blade-code 0.10.101 → 0.10.103
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/blade.js +2 -2
- package/dist/chunk-03qymy9e.js +1 -0
- package/dist/{chunk-2191220r.js → chunk-07w0qapm.js} +1 -1
- package/dist/{chunk-qjv5kz7q.js → chunk-0aa40zbs.js} +15 -15
- package/dist/{chunk-9sx3vsyj.js → chunk-0hr050ck.js} +1 -1
- package/dist/chunk-0kdrgmyy.js +1 -0
- package/dist/{chunk-8z9d0zd0.js → chunk-14bs89sm.js} +2 -2
- package/dist/{chunk-b4d43ap3.js → chunk-181ef74x.js} +1 -1
- package/dist/{chunk-c6tq09mt.js → chunk-41cg66y0.js} +1 -1
- package/dist/{chunk-p0rvgzpx.js → chunk-41ympwz1.js} +1 -1
- package/dist/chunk-42bcht8b.js +169 -0
- package/dist/{chunk-39qzk9nm.js → chunk-47e6tdbb.js} +1 -1
- package/dist/{chunk-cjgpas7y.js → chunk-4qfke0gd.js} +5 -5
- package/dist/chunk-5sk7q6pw.js +1 -0
- package/dist/chunk-6v10cs0h.js +1 -0
- package/dist/{chunk-4fmtv329.js → chunk-6wsvgk20.js} +1 -1
- package/dist/chunk-7ab7jcvn.js +1 -0
- package/dist/{chunk-j00px1es.js → chunk-7fz3w4rk.js} +1 -1
- package/dist/chunk-8zjn51fr.js +1 -0
- package/dist/{chunk-ykkqywtq.js → chunk-946wkbmw.js} +1 -1
- package/dist/{chunk-k7vv9vne.js → chunk-9p20hhs0.js} +1 -1
- package/dist/{chunk-j22d84s7.js → chunk-a7ejfmtc.js} +1 -1
- package/dist/chunk-a8x3xygs.js +1 -0
- package/dist/{chunk-dcjh1cj6.js → chunk-aa5zmwd9.js} +3 -3
- package/dist/{chunk-0zhdjaen.js → chunk-abd57h72.js} +1 -1
- package/dist/{chunk-fqbc1ppx.js → chunk-afa35v3f.js} +1 -1
- package/dist/{chunk-2f5kkhan.js → chunk-b0j9v359.js} +407 -403
- package/dist/{chunk-qjeadpj2.js → chunk-bt18xsc6.js} +1 -1
- package/dist/chunk-bx82y5ce.js +1 -0
- package/dist/chunk-c475tfqf.js +2 -0
- package/dist/{chunk-9ajkzcqj.js → chunk-c479s9v2.js} +1 -1
- package/dist/{chunk-jvxskq6a.js → chunk-cpex23zk.js} +1 -1
- package/dist/{chunk-wbf4qcws.js → chunk-e1tt6b1w.js} +2 -2
- package/dist/{chunk-czcxx8tb.js → chunk-f3426b1c.js} +1 -1
- package/dist/{chunk-z5a8ay9s.js → chunk-f945dzj6.js} +2 -2
- package/dist/{chunk-w9xfks7f.js → chunk-fhfzdyba.js} +1 -1
- package/dist/{chunk-qcy79mva.js → chunk-fva7jnjy.js} +1 -1
- package/dist/chunk-fw2x9p4c.js +6 -0
- package/dist/{chunk-8yt4nmyb.js → chunk-gr80w0vh.js} +1 -1
- package/dist/{chunk-3c01jje5.js → chunk-gxgq70gm.js} +1 -1
- package/dist/{chunk-10taec1j.js → chunk-j2dyprdy.js} +1 -1
- package/dist/{chunk-f8z5v101.js → chunk-jaswqpe7.js} +1 -1
- package/dist/{chunk-kdatgrjy.js → chunk-k9fveqq6.js} +1 -1
- package/dist/chunk-kdjtxpxw.js +1 -0
- package/dist/chunk-kf7whgr7.js +2 -0
- package/dist/{chunk-tp5bep1y.js → chunk-khtxprbv.js} +1 -1
- package/dist/{chunk-ykf4cqpg.js → chunk-mgsvn9v4.js} +4 -4
- package/dist/{chunk-d8wzc602.js → chunk-n7mzxa8h.js} +2 -2
- package/dist/chunk-nz7kjzc0.js +1 -0
- package/dist/{chunk-70hwyc2w.js → chunk-q69fzq4y.js} +1 -1
- package/dist/{chunk-z0dmm227.js → chunk-q6eb20fz.js} +1 -1
- package/dist/{chunk-3an3vxzt.js → chunk-rahch228.js} +1 -1
- package/dist/{chunk-3awjdsef.js → chunk-rchz6j90.js} +1 -1
- package/dist/{chunk-2va6ex5v.js → chunk-rvk9r2cm.js} +1 -1
- package/dist/{chunk-425p4nwx.js → chunk-s10pmnrd.js} +2 -2
- package/dist/{chunk-twhf09qs.js → chunk-s66fwx1p.js} +1 -1
- package/dist/chunk-s6vzjear.js +10 -0
- package/dist/{chunk-f9asjkfz.js → chunk-sdbbyagy.js} +1 -1
- package/dist/{chunk-9hsbjy6a.js → chunk-szxajr6e.js} +1 -1
- package/dist/{chunk-q3vza5gt.js → chunk-tgdhsm5t.js} +2 -2
- package/dist/chunk-v4w5b2cq.js +1 -0
- package/dist/chunk-vk4xbek0.js +1 -0
- package/dist/{chunk-53xtssbf.js → chunk-w7hy5wh1.js} +1 -1
- package/dist/{chunk-cp7xsjj2.js → chunk-wyhyw9rq.js} +2 -2
- package/dist/{chunk-zydvg30x.js → chunk-wzmqkam9.js} +1 -1
- package/dist/{chunk-hpjnk87v.js → chunk-x3cxmwnz.js} +1 -1
- package/dist/chunk-xm8nyj5z.js +2 -0
- package/dist/{chunk-2cg8f38t.js → chunk-xtb84adp.js} +1 -1
- package/dist/chunk-yr56ttgw.js +1 -0
- package/dist/{chunk-nh4jy5cs.js → chunk-ywarj5j9.js} +1 -1
- package/dist/{chunk-rej5bbbs.js → chunk-z9gd9spf.js} +1 -1
- package/dist/web/assets/ChatView-_4ut_-Jh.js +58 -0
- package/dist/web/assets/{CodeBlockHighlighter-DZcVFtJE.js → CodeBlockHighlighter-DkDr6wE9.js} +1 -1
- package/dist/web/assets/{FilePreview-CzNS6kfM.js → FilePreview-DCI-oqhJ.js} +1 -1
- package/dist/web/assets/{KanbanBoard-cdh2g0r0.js → KanbanBoard-CB5C4tJC.js} +1 -1
- package/dist/web/assets/{MarkdownRenderer-BqBOUlXa.js → MarkdownRenderer-ychfmIQK.js} +3 -3
- package/dist/web/assets/{SettingsModal-meSWhCOP.js → SettingsModal-SSdk0Bjr.js} +1 -1
- package/dist/web/assets/{TaskSwitcher-CiQi64Yl.js → TaskSwitcher-EnaUhn3o.js} +1 -1
- package/dist/web/assets/{TerminalPanel-Bze9t5mz.js → TerminalPanel-BcWxLSV3.js} +1 -1
- package/dist/web/assets/{arrow-left-DpTnLOBT.js → arrow-left-Ob5r20g7.js} +1 -1
- package/dist/web/assets/{calendar-clock-DlAXXpl_.js → calendar-clock-eOALT8DB.js} +1 -1
- package/dist/web/assets/{chevrons-up-down-CmAktdaR.js → chevrons-up-down-BkZBwmbt.js} +1 -1
- package/dist/web/assets/{clock-3-_w8nIuEK.js → clock-3-DQp9SzYc.js} +1 -1
- package/dist/web/assets/{external-link-AlymrIfc.js → external-link-BuGUowPD.js} +1 -1
- package/dist/web/assets/{folder-CrxO-9Rc.js → folder-c92kw1oI.js} +1 -1
- package/dist/web/assets/index-CS8jtO_A.js +275 -0
- package/dist/web/assets/{pause-GQZaG_P3.js → pause-DP_CXoH7.js} +1 -1
- package/dist/web/assets/{play-BPhmPVpi.js → play-DcRwtohz.js} +1 -1
- package/dist/web/assets/{session-events-CO2pRY9U.js → session-events-CrAgnaj2.js} +19 -19
- package/dist/web/assets/{teamService-BqS4iOx0.js → teamService-JyVbGQhi.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/chunk-2r0f3b4t.js +0 -1
- package/dist/chunk-as2ezx8p.js +0 -1
- package/dist/chunk-bswjne5v.js +0 -1
- package/dist/chunk-c663rajb.js +0 -1
- package/dist/chunk-fvfc95g3.js +0 -2
- package/dist/chunk-hz5rsfxv.js +0 -2
- package/dist/chunk-kfcs62nw.js +0 -1
- package/dist/chunk-kvdk0pfk.js +0 -1
- package/dist/chunk-maebpz1j.js +0 -2
- package/dist/chunk-mzab7qak.js +0 -1
- package/dist/chunk-n4cw6vt1.js +0 -1
- package/dist/chunk-n5jfmzp2.js +0 -1
- package/dist/chunk-p7t010gq.js +0 -1
- package/dist/chunk-qgjgjzbx.js +0 -10
- package/dist/chunk-sa7t9kht.js +0 -6
- package/dist/chunk-tazb5tze.js +0 -1
- package/dist/chunk-tc9rq0st.js +0 -160
- package/dist/chunk-vc7gh3wc.js +0 -1
- package/dist/chunk-zjpph3ys.js +0 -1
- package/dist/web/assets/ChatView-Cc4bXZ6x.js +0 -58
- package/dist/web/assets/index-JJH0FKfo.js +0 -275
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{e as u4,f as p4}from"./chunk-
|
|
1
|
+
import{e as u4,f as p4}from"./chunk-7fz3w4rk.js";import{g as wx}from"./chunk-47e6tdbb.js";import{s as N0,t as K4}from"./chunk-afa35v3f.js";import{u as rO}from"./chunk-khtxprbv.js";import{A as J1,v as W4,w as w1,x as Q1,y as Z1,z as Z0}from"./chunk-k9fveqq6.js";import{$ as Y4,D as O4,E as C1,F as r4,I as x4,J as V0,K as Px,L as r0,M as j1,N as jx,O as w4,P as fO,Q as Q4,R as Z4,S as J4,T as Mx,U as gO,V as sO,Y as m0,Z as h0,_ as G$,aa as N4,ba as j4,ca as M4,da as T4,ea as R4,fa as q4,ga as C4,ha as I4,ia as E4,ja as k4,ma as g4,pa as H$,ua as e4}from"./chunk-b0j9v359.js";import{Ba as _1,Ha as KO}from"./chunk-xtb84adp.js";import{$a as V4,La as Xx,Oa as x$,Pa as yx,Qa as X4,Ra as z4,Sa as $$,Ta as w$,Ua as mx,Va as Q$,Wa as x0,Xa as v4,Ya as l4,Za as i4,_a as G4,ab as B4,bb as U4,cb as O1,db as vx}from"./chunk-xm8nyj5z.js";import{Db as Sx,Mb as eO,ob as pO,pb as m,rb as q,sb as $4}from"./chunk-0aa40zbs.js";import{Xb as d1}from"./chunk-8hprmrd5.js";import{Ac as C0,Bc as c1,Cd as s1,Dd as r1,Ec as Ux,Fd as X0,Id as Hx,Nd as e1,Od as bx,Pd as Ax,Qd as C,Rc as a1,ad as o1,kd as n1,ld as e0,qc as v1,sd as P0,td as qx,ud as y0,wd as t1,xc as l1,yc as Dx,zc as i1}from"./chunk-wzmqkam9.js";import{$e as AO,Me as X$,Qe as YO,Ue as H1}from"./chunk-q6eb20fz.js";import{af as Lx}from"./chunk-dg0d3303.js";import{rf as u1}from"./chunk-2hb222re.js";import{tf as s0}from"./chunk-07w0qapm.js";import{Bf as z$,Df as o4,Gf as S4,Kf as T0,Lf as R0,Pf as R$,Sf as TO,Tf as q0,Wf as q$}from"./chunk-ywarj5j9.js";import{kg as b1,lg as p1}from"./chunk-fva7jnjy.js";import{pg as V1,qg as Y0}from"./chunk-aa5zmwd9.js";import{Ig as K1,ah as m1,dh as h1,fh as g1,sh as B1,xh as M0}from"./chunk-f945dzj6.js";import{Ah as _x}from"./chunk-sdbbyagy.js";import{Bh as f,Dh as W,Eh as RO,Gh as e}from"./chunk-f3426b1c.js";import{Ih as xx,Lh as Fx}from"./chunk-c475tfqf.js";import{Ph as o}from"./chunk-0hr050ck.js";import{pi as t}from"./chunk-n7mzxa8h.js";import{vi as nO}from"./chunk-s10pmnrd.js";import{Ai as D1,Bi as y1,xi as L1,yi as P1}from"./chunk-9p20hhs0.js";import{Di as J0}from"./chunk-14bs89sm.js";import{Ki as dx}from"./chunk-wyhyw9rq.js";import{Qi as o0,Ui as N1,Vi as Ox}from"./chunk-tgdhsm5t.js";import{Xi as gx}from"./chunk-fhfzdyba.js";var u2={port:{type:"number",describe:"Port to listen on (0 for auto)",default:0},hostname:{type:"string",describe:"Hostname to listen on",default:"127.0.0.1"},cors:{type:"array",describe:"Additional domains to allow for CORS",default:[]}};function p2(O){return{port:O.port??0,hostname:O.hostname??"127.0.0.1",cors:O.cors??[]}}import{existsSync as lx,readFileSync as p0}from"node:fs";import{createServer as _2}from"node:http";import{networkInterfaces as F2}from"node:os";import{dirname as L2,extname as D2,join as cO}from"node:path";import{fileURLToPath as H2}from"node:url";import{brotliCompressSync as b2,gzipSync as A2,constants as S2}from"node:zlib";import{Hono as j2}from"hono";import{cors as M2}from"hono/cors";import{WebSocketServer as T2}from"ws";var Q0=t("Service"),E$=30000,k$=new Set(["completed","failed","cancelled","interrupted"]);class zx{dispatch;store;tickMs;timer;unsubscribeBus;ticking=!1;inFlight=new Set;constructor(O){this.dispatch=O.dispatch,this.store=O.store??O1.getInstance(),this.tickMs=O.tickMs??E$}start(){if(this.timer)return;Q0.info("[TaskScheduler] Starting scheduler tick loop"),this.timer=setInterval(()=>{this.tick()},this.tickMs),this.timer.unref?.(),this.unsubscribeBus=q.subscribe((O)=>{if(O.type!=="task.status")return;let x=O.properties.taskStatus;if(typeof x!=="string"||!k$.has(x))return;this.recordTerminalStatus(O.sessionId,x,typeof O.properties.taskStatusReason==="string"?O.properties.taskStatusReason:void 0)}),this.tick()}stop(){if(this.timer)clearInterval(this.timer),this.timer=void 0,this.unsubscribeBus?.(),this.unsubscribeBus=void 0,Q0.info("[TaskScheduler] Stopped scheduler tick loop")}async tick(O=new Date){if(this.ticking)return;this.ticking=!0;try{let x=await this.store.list();for(let $ of x)await this.evaluate($,O)}catch(x){Q0.warn("[TaskScheduler] Tick failed:",x)}finally{this.ticking=!1}}async evaluate(O,x){if(!O.enabled)return;if(this.inFlight.has(O.id))return;if(O.expiresAt&&new Date(O.expiresAt).getTime()<=x.getTime()){await this.store.update(O.id,{enabled:!1,nextRunAt:null}),Q0.info(`[TaskScheduler] Schedule ${O.id} expired; disabled`);return}if(!O.nextRunAt)return;if(!(new Date(O.nextRunAt).getTime()<=x.getTime()))return;await this.fire(O,x)}async fire(O,x=new Date,$={}){if(this.inFlight.has(O.id))throw Error(`Schedule ${O.id} is already dispatching`);this.inFlight.add(O.id);let w=x.toISOString();try{let Q=await this.dispatch({prompt:O.prompt,title:O.title??f$(O),sourceProjectPath:O.projectPath,isolation:O.dispatch.isolation??"worktree",permissionMode:O.dispatch.permissionMode??"default",modelId:O.dispatch.modelId,reasoningEffort:O.dispatch.reasoningEffort,serviceTier:O.dispatch.serviceTier,responseVerbosity:O.dispatch.responseVerbosity,communicationStyle:O.dispatch.communicationStyle}),Y=O.trigger.kind==="once"?null:$.manual?O.nextRunAt?new Date(O.nextRunAt):null:Xx(O.trigger,x,x);await this.store.update(O.id,{lastRunAt:w,lastRunSessionId:Q.session.sessionId,lastStatus:Q.status,lastError:void 0,runCount:O.runCount+1,nextRunAt:Y?Y.toISOString():null,enabled:O.trigger.kind==="once"?!1:O.enabled}),q.publish({sessionId:Q.session.sessionId,projectPath:O.projectPath},"schedule.fired",{scheduleId:O.id,firedAt:w,sessionId:Q.session.sessionId,runId:Q.runId,status:Q.status}),Q0.info(`[TaskScheduler] Fired schedule ${O.id} -> session ${Q.session.sessionId} (${Q.status})`)}catch(Q){let Y=Q instanceof Error?Q.message:String(Q);Q0.warn(`[TaskScheduler] Schedule ${O.id} dispatch failed:`,Q);let J=O.trigger.kind==="once"?null:$.manual?O.nextRunAt?new Date(O.nextRunAt):null:Xx(O.trigger,x,x);await this.store.update(O.id,{lastRunAt:w,lastStatus:"error",lastError:Y,nextRunAt:J?J.toISOString():null,enabled:O.trigger.kind==="once"?!1:O.enabled})}finally{this.inFlight.delete(O.id)}}async recordTerminalStatus(O,x,$){let Q=(await this.store.list()).find((Y)=>Y.lastRunSessionId===O);if(!Q)return;await this.store.update(Q.id,{lastStatus:x,...$?{lastError:$}:{lastError:void 0}})}}function f$(O){return`Scheduled: ${O.prompt.trim().replace(/\s+/g," ").slice(0,60)}`}class r extends Error{code;statusCode;details;constructor(O,x,$=500,w){super(x);this.code=O;this.statusCode=$;this.details=w;this.name="BladeServerError"}toObject(){return{error:{code:this.code,message:this.message,...this.details?{details:this.details}:{}}}}}class y extends r{constructor(O,x){super("NOT_FOUND",x?`${O} not found: ${x}`:`${O} not found`,404)}}class _ extends r{constructor(O){super("BAD_REQUEST",O,400)}}class k extends r{constructor(O){super("CONFLICT",O,409)}}class PO extends r{constructor(O,x){super("TOO_MANY_REQUESTS",O,429,x)}}class yO extends r{constructor(O="Server is shutting down"){super("SERVICE_UNAVAILABLE",O,503)}}class c0 extends r{constructor(O){super("SESSION_WORKSPACE_UNAVAILABLE","This session workspace is no longer available",409,{reason:O})}}class bO extends r{constructor(){super("AMBIGUOUS_SESSION","Multiple workspaces contain this session ID; projectPath is required",409)}}class s extends r{constructor(O="Internal server error"){super("INTERNAL_ERROR",O,500)}}var n2=W.Object({error:W.Object({code:W.String(),message:W.String(),details:W.Optional(W.Record(W.String(),W.Unknown()))})});import{Hono as P$}from"hono";var Gx=t("Service"),y$=W.Object({updates:W.Record(W.String(),W.Any()),options:W.Optional(W.Object({scope:W.Optional(e(["local","project","global"])),immediate:W.Optional(W.Boolean())}))});function m$(O){return{currentModelId:O.currentModelId,permissionMode:O.permissionMode,language:O.language,codeTheme:O.codeTheme,uiTheme:O.uiTheme,autoSaveSessions:O.autoSaveSessions,notifyBuild:O.notifyBuild,notifyErrors:O.notifyErrors,notifySounds:O.notifySounds,privacyTelemetry:O.privacyTelemetry,privacyCrash:O.privacyCrash,agentTeamsEnabled:O.agentTeamsEnabled===!0,communicationStyle:O.communicationStyle,maxConcurrentTasks:O.maxConcurrentTasks,maxQueuedTasks:O.maxQueuedTasks,maxQueuedTaskBytes:O.maxQueuedTaskBytes,maxResidentSessionRuntimes:O.maxResidentSessionRuntimes,sessionRuntimeIdleMs:O.sessionRuntimeIdleMs}}var x1=()=>{let O=new P$;return O.get("/",async(x)=>{try{let $=YO();return x.json($?m$($):{})}catch($){return Gx.error("[ConfigRoutes] Failed to get config:",$),x.json({})}}),O.put("/",async(x)=>{try{let $=await x.req.json(),w=f(y$,$);if(!w.success)throw new _("Invalid config update format");let{updates:Q,options:Y}=w.data;return await AO().updateConfig(Q,Y),x.json({success:!0,updates:Q})}catch($){throw Gx.error("[ConfigRoutes] Failed to update config:",$),$}}),O.get("/permissions",async(x)=>{try{let $=YO();return x.json($?.permissions||{})}catch($){return Gx.error("[ConfigRoutes] Failed to get permissions:",$),x.json({})}}),O};import{Hono as h$}from"hono";import{streamSSE as g$}from"hono/streaming";function $1(O){let x="";if(O.id!==void 0)x+=`id: ${O.id}
|
|
2
2
|
`;if(O.event!==void 0)x+=`event: ${O.event}
|
|
3
3
|
`;for(let $ of O.data.split(/\r\n|\r|\n/))x+=`data: ${$}
|
|
4
4
|
`;if(O.retry!==void 0)x+=`retry: ${O.retry}
|
|
5
5
|
`;return x+=`
|
|
6
|
-
`,Buffer.byteLength(x)}class S0{serial;buffered=[];bufferedBytes=0;nextOrder=0;phase="buffering";highestDeliveredSequence=0;highestReplaySequence=0;failure;maxPendingItems;maxPendingBytes;constructor(O){this.maxPendingItems=O.maxPendingItems??w1,this.maxPendingBytes=O.maxPendingBytes??Q1,this.serial=new J1({maxPendingItems:this.maxPendingItems,maxPendingBytes:this.maxPendingBytes,writeTimeoutMs:O.writeTimeoutMs??Z1,sizeOf:$1,write:O.write,onFailure:(x)=>{this.failure=x,this.phase="closed",this.buffered.length=0,this.bufferedBytes=0,O.onFailure?.(x)}})}async writeInitial(O){await this.offerDirect(O)}observe(O,x){if(this.phase==="closed")return;if(this.phase==="buffering"){this.buffer(O,x);return}this.offerLive(O,x)}async writeReplay(O,x){if(!Number.isSafeInteger(x)||x<=0)throw this.fail(new Z0("invalid_size","SSE committed sequence must be a positive safe integer")),this.currentFailure();if(x<=this.highestReplaySequence)return;await this.offerDirect(O),this.highestReplaySequence=x,this.highestDeliveredSequence=x}finishInitialization(O){if(this.phase!=="buffering")return;let x=this.buffered.splice(0);this.bufferedBytes=0,this.phase="live";let $=O.replayed?x.filter((Q)=>Q.sequence!==void 0&&Q.sequence>this.highestReplaySequence).sort((Q,Y)=>Q.sequence-Y.sequence||Q.order-Y.order):x.sort((Q,Y)=>Q.order-Y.order),w;for(let Q of $){if(O.replayed&&Q.sequence!==void 0&&Q.sequence===w)continue;if(this.offerLive(Q.message,Q.sequence),this.serial.stats().closed)return;w=Q.sequence}}offerHeartbeat(O){if(this.phase!=="live"||this.buffered.length>0||this.serial.stats().pendingItems>0)return!1;return this.offerLive(O),!this.serial.stats().closed}async flush(){await this.serial.flush()}close(O){if(this.phase==="closed")return;this.phase="closed",this.buffered.length=0,this.bufferedBytes=0,this.serial.close(O)}stats(){let O=this.serial.stats();return{closed:this.phase==="closed",pendingItems:O.pendingItems+this.buffered.length,pendingBytes:O.pendingBytes+this.bufferedBytes,bufferedItems:this.buffered.length,bufferedBytes:this.bufferedBytes}}buffer(O,x){let $=$1(O),w=this.serial.stats();if($>this.maxPendingBytes){this.fail(new Z0("oversized",`SSE frame requires ${$} bytes; limit is ${this.maxPendingBytes}`,{pendingItems:w.pendingItems+this.buffered.length,pendingBytes:w.pendingBytes+this.bufferedBytes}));return}if(w.pendingItems+this.buffered.length>=this.maxPendingItems||w.pendingBytes+this.bufferedBytes+$>this.maxPendingBytes){this.fail(new Z0("overflow","SSE initialization buffer limit exceeded",{pendingItems:w.pendingItems+this.buffered.length,pendingBytes:w.pendingBytes+this.bufferedBytes}));return}this.nextOrder+=1,this.buffered.push({message:O,bytes:$,sequence:x,order:this.nextOrder}),this.bufferedBytes+=$}offerLive(O,x){if(x!==void 0){if(x<=this.highestReplaySequence)return;if(x<=this.highestDeliveredSequence){this.fail(new Z0("write_failed","SSE committed sequence regressed"));return}this.highestDeliveredSequence=x}if(!this.serial.offer(O).accepted)this.phase="closed"}async offerDirect(O){if(this.phase==="closed")throw this.currentFailure();let x=this.serial.offer(O);if(!x.accepted)throw this.phase="closed",x.error;await x.completion}fail(O){this.serial.close(O)}currentFailure(){return this.failure??new Z0("closed","SSE egress is closed")}}var u$=15000,p$=t("Service"),d$=new Set(["task.status","task.delivery","session.created","session.updated","session.deleted","schedule.fired","permission.asked","question.required","elicitation.required","interaction.resolved"]),v$=new Set(["queued","running","completed","failed","cancelled","interrupted"]),l$=new Set(["high","medium","low"]),i$=new Set(["feature","bug","maintenance","research"]);function c$(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let x=O,$=["changedFiles","additions","deletions","commits"];if($.some((w)=>typeof x[w]!=="number"||!Number.isInteger(x[w])||x[w]<0))return;return Object.fromEntries($.map((w)=>[w,x[w]]))}function j0(O,x){return typeof O==="number"&&Number.isInteger(O)&&O>=x?O:void 0}function a$(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let x=O;if(!["applied","discarded","conflicted"].includes(String(x.status))||typeof x.updatedAt!=="string")return;return{status:x.status,updatedAt:x.updatedAt,...typeof x.sourceCommit==="string"?{sourceCommit:x.sourceCommit}:{},...j0(x.changedFiles,0)!==void 0?{changedFiles:x.changedFiles}:{},...typeof x.message==="string"?{message:x.message}:{}}}var Y1=()=>{let O=new h$;return O.get("/",(x)=>g$(x,async($)=>{let w,Q,Y=!1,J,K,S=new Promise((U)=>{K=U}),B=()=>{if(Q!==void 0)clearInterval(Q),Q=void 0;w?.(),w=void 0},A=(U)=>{if(Y)return;Y=!0,B(),J?.close(U),K()};$.onAbort(A),J=new S0({write:async(U)=>{await $.writeSSE(U)},onFailure:(U)=>{p$.warn(`[EventRoutes] SSE egress closed: kind=${U.kind} pendingItems=${U.pendingItems??0} pendingBytes=${U.pendingBytes??0}`),A(U)}});let H=(U,T)=>{J?.observe({data:JSON.stringify({type:U,properties:T})})};w=q.subscribe((U)=>{if(!d$.has(U.type))return;if(U.type==="permission.asked"||U.type==="question.required"||U.type==="elicitation.required"){let v=U.properties.requestId;if(typeof v!=="string"||!v)return;H("interaction.pending",{sessionId:U.sessionId,projectPath:U.projectPath,interactionType:U.type==="question.required"?"question":U.type==="elicitation.required"?"elicitation":"permission",requestId:v});return}if(U.type==="interaction.resolved"){let v=U.properties.requestId;if(typeof v!=="string"||!v)return;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,requestId:v});return}if(U.type==="session.created"||U.type==="session.deleted"){H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath});return}if(U.type==="session.updated"){let v=U.properties.title,ZO=U.properties.taskPriority,wO=U.properties.taskKind,IO=U.properties.taskDueAt,xO=typeof v==="string"&&Boolean(v.trim()),aO=l$.has(String(ZO)),LO=i$.has(String(wO)),z=IO===null||typeof IO==="string"&&Number.isFinite(Date.parse(IO));if(!xO&&!aO&&!LO&&!z)return;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,...xO?{title:v}:{},...aO?{taskPriority:ZO}:{},...LO?{taskKind:wO}:{},...z?{taskDueAt:IO}:{}});return}if(U.type==="task.delivery"){let v=a$(U.properties.taskDelivery);if(!v)return;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,taskDelivery:v,...U.properties.taskWorktreeRemoved===!0?{taskWorktreeRemoved:!0}:{},...typeof U.properties.updatedAt==="string"?{updatedAt:U.properties.updatedAt}:{}});return}if(U.type==="schedule.fired"){let v=U.properties.scheduleId,ZO=U.properties.firedAt;if(typeof v!=="string"||typeof ZO!=="string")return;H(U.type,{scheduleId:v,firedAt:ZO,sessionId:U.sessionId,projectPath:U.projectPath,...typeof U.properties.runId==="string"?{runId:U.properties.runId}:{},...typeof U.properties.status==="string"?{status:U.properties.status}:{}});return}let T=U.properties.taskStatus;if(typeof T!=="string"||!v$.has(T))return;let c=c$(U.properties.taskDiffStat),l=j0(U.properties.taskQueuePosition,1),JO=j0(U.properties.taskQueueDepth,0),R=j0(U.properties.taskConcurrencyLimit,1),NO=j0(U.properties.taskInFlight,0),p=typeof U.properties.taskAdmissionPaused==="boolean"?U.properties.taskAdmissionPaused:void 0;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,taskStatus:T,...typeof U.properties.taskStatusReason==="string"?{taskStatusReason:U.properties.taskStatusReason}:{},...U.properties.taskFailure&&typeof U.properties.taskFailure==="object"?{taskFailure:U.properties.taskFailure}:{},...typeof U.properties.taskStartedAt==="string"?{taskStartedAt:U.properties.taskStartedAt}:{},...typeof U.properties.taskCompletedAt==="string"?{taskCompletedAt:U.properties.taskCompletedAt}:{},...typeof U.properties.updatedAt==="string"?{updatedAt:U.properties.updatedAt}:{},...c?{taskDiffStat:c}:{},...l!==void 0?{taskQueuePosition:l}:{},...JO!==void 0?{taskQueueDepth:JO}:{},...R!==void 0?{taskConcurrencyLimit:R}:{},...NO!==void 0?{taskInFlight:NO}:{},...p!==void 0?{taskAdmissionPaused:p}:{}})});try{if($.aborted||Y)return;if(await J.writeInitial({data:JSON.stringify({type:"connected",properties:{timestamp:Date.now()}})}),$.aborted||Y)return;if(J.finishInitialization({replayed:!1}),$.aborted||Y)return;Q=setInterval(()=>{if($.aborted||Y)return;J?.offerHeartbeat({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})})},u$),await S}finally{A()}})),O};import{Hono as o$}from"hono";var n$=W.Object({paused:W.Boolean()}),W1=()=>{let O=new o$;return O.get("/health",(x)=>{return x.json({healthy:!0,version:J0()})}),O.get("/info",(x)=>{let $=o(),w=YO();if(w)gO.configure(w.maxConcurrentTasks,w.maxQueuedTasks,w.maxQueuedTaskBytes);let Q=gO.getStats();return x.json({version:J0(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:$,gitBranch:N1($),taskAdmission:{inFlight:Q.inFlight,queued:Q.queued,maxConcurrent:Q.maxConcurrent,maxQueued:Q.maxQueued,paused:Q.paused}})}),O.put("/task-admission",async(x)=>{let $;try{$=await x.req.json()}catch{throw new _("Invalid request body")}let w=f(n$,$);if(!w.success)throw new _("Invalid task admission control request");gO.setPaused(w.data.paused);let Q=gO.getStats();return x.json({inFlight:Q.inFlight,queued:Q.queued,maxConcurrent:Q.maxConcurrent,maxQueued:Q.maxQueued,paused:Q.paused})}),O};import X1 from"node:path";import{Hono as t$}from"hono";var s$=W.Object({projectPath:W.String({minLength:1}),action:e(["trust","revoke"]),expectedDigest:W.Optional(W.String())}),r$=W.Object({projectPath:W.String({minLength:1}),sessionId:W.String({minLength:1}),enabled:W.Boolean()});function Vx(O){if(!O||!X1.isAbsolute(O))throw new _("projectPath must be absolute");return X1.resolve(O)}function z1(O){if(!O)throw new _("sessionId is required");try{o0(O)}catch(x){throw new _(x instanceof Error?x.message:"sessionId is invalid")}return O}async function a0(O){let x=Vx(O),$=YO()?.hooks??B1.hooks,w=await M0.getInstance().loadWorkspaceHooks(x,$,{includeBaseForCurrentWorkspace:!1});return q0(x,async()=>{R0(x);let Q=Y0.getInstance();return Q.loadConfig(w,x),await T0(x),Q.getConfig(x)})}function G1(O,x){let $=Y0.getInstance(),w=$.getConfig(x).enabled,Q=$.isSessionPaused(O,x);return{sessionId:O,projectPath:x,enabled:$.isSessionEnabled(O,x),paused:Q,configEnabled:w}}var U1=()=>{let O=new t$;return O.get("/trust",async(x)=>{let $=x.req.query("projectPath");if(!$)throw new _("projectPath query parameter is required");return await a0($),x.json(await Y0.getInstance().getTrustStatus($))}),O.post("/trust",async(x)=>{let $=f(s$,await x.req.json());if(!$.success)throw new _("Invalid hook trust request");let{projectPath:w,action:Q,expectedDigest:Y}=$.data;await a0(w);let J=Y0.getInstance(),K;try{K=Q==="trust"?await J.trustProject(w,Y):await J.revokeProjectTrust(w)}catch(S){if(S instanceof V1)throw new k(S.message);throw S}return x.json(K)}),O.get("/session",async(x)=>{let $=Vx(x.req.query("projectPath")),w=z1(x.req.query("sessionId"));return await a0($),x.json(G1(w,$))}),O.post("/session",async(x)=>{let $=f(r$,await x.req.json());if(!$.success)throw new _("Invalid hook session request");let w=Vx($.data.projectPath),Q=z1($.data.sessionId);await a0(w);let Y=Y0.getInstance();if($.data.enabled)Y.enableSession(Q,w);else Y.disableSession(Q,w);return x.json(G1(Q,w))}),O};import{Hono as e$}from"hono";var kO=t("Service");function Ow(O){try{return _1(O)}catch{return[]}}function xw(O){if(!n0(O)||!n0(O.reference)||!n0(O.argument))throw Error("Invalid MCP completion request");let x=O.reference.type,$=x==="prompt"&&typeof O.reference.name==="string"?{type:"prompt",name:O.reference.name}:x==="resource"&&typeof O.reference.uri==="string"?{type:"resource",uri:O.reference.uri}:void 0;if(!$||typeof O.argument.name!=="string"||typeof O.argument.value!=="string")throw Error("Invalid MCP completion request");let w;if(O.context!==void 0){if(!n0(O.context))throw Error("Invalid MCP completion context");w=Object.create(null);for(let[Q,Y]of Object.entries(O.context)){if(typeof Y!=="string")throw Error("Invalid MCP completion context");w[Q]=Y}}return{reference:$,argument:{name:O.argument.name,value:O.argument.value},...w?{context:w}:{}}}function n0(O){return O!==null&&typeof O==="object"&&!Array.isArray(O)}async function uO(O,x){let $=YO()?.mcpServers??{};for(let[w,Q]of Object.entries($)){if(x&&w!==x)continue;if(!O.getServerStatus(w))await O.registerServer(w,Q,{connect:!1})}}var F1=()=>{let O=new e$;return O.get("/",async(x)=>{try{let $=KO.getInstance();await uO($);let w=$.getAllServers(),Q=await Promise.all(Array.from(w.entries()).map(async([Y,J])=>({id:Y,name:Y,status:J.status==="connected"?"connected":J.status==="reconnecting"?"reconnecting":J.status==="connecting"?"connecting":J.lastError?"error":"offline",endpoint:J.config.command?`${J.config.command} ${(J.config.args||[]).join(" ")}`.trim():J.config.url||"Unknown",description:`MCP server: ${Y}`,tools:J.tools.map((K)=>K.name),completionSupported:J.client.completionSupported,tasks:J.client.tasks,resources:J.contentCatalog.resources,resourceTemplates:J.contentCatalog.resourceTemplates.map((K)=>({...K,variables:Ow(K.uriTemplate)})),prompts:J.contentCatalog.prompts,connectedAt:J.connectedAt?.toISOString(),error:J.lastError?.message,recovery:J.recovery,logging:J.logging,instructions:J.instructions,oauthEnabled:J.client.oauthEnabled,oauthStatus:await J.client.getOAuthStatus()})));return x.json(Q)}catch($){return kO.error("[McpRoutes] Failed to get MCP servers:",$),x.json({error:$ instanceof Error?$.message:"Failed to get MCP servers"},500)}}),O.post("/:name/connect",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();return await uO(w,$),await w.connectServer($),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to connect MCP server:",$),x.json({success:!1,error:$.message},500)}}),O.post("/:name/disconnect",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();return await uO(w,$),await w.disconnectServer($),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to disconnect MCP server:",$),x.json({success:!1,error:$.message},500)}}),O.get("/:name/logs",async(x)=>{try{let $=x.req.param("name"),w=Number(x.req.query("limit")??20),Q=Number(x.req.query("afterRevision")??0);if(!Number.isSafeInteger(w)||w<1||w>100||!Number.isSafeInteger(Q)||Q<0)return x.json({error:"Invalid MCP log pagination"},400);let Y=KO.getInstance();return await uO(Y,$),x.json(Y.getLogSnapshot($,{limit:w,afterRevision:Q}))}catch($){return kO.error("[McpRoutes] Failed to get MCP logs:",$),x.json({error:$.message},500)}}),O.post("/:name/logging-level",async(x)=>{try{let $=x.req.param("name"),w=await x.req.json();if(!K1(w.level))return x.json({success:!1,error:"Invalid MCP logging level"},400);let Q=KO.getInstance();return await uO(Q,$),await Q.setServerLoggingLevel($,w.level),x.json({success:!0,level:w.level})}catch($){return kO.error("[McpRoutes] Failed to set MCP logging level:",$),x.json({success:!1,error:$.message},400)}}),O.post("/:name/complete",async(x)=>{try{let $=x.req.param("name"),w=xw(await x.req.json()),Q=KO.getInstance();await uO(Q,$);let Y=await Q.complete($,w);return x.json(Y)}catch($){return kO.error("[McpRoutes] Failed to complete MCP argument:",$),x.json({error:$.message},400)}}),O.post("/:name/oauth/login",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();await uO(w,$);let Q=await w.beginOAuthLogin($);return x.json({success:!0,flowId:Q.flowId,authorizationUrl:Q.authorizationUrl},202)}catch($){return kO.error("[McpRoutes] Failed to start MCP OAuth login:",$),x.json({success:!1,error:$.message},400)}}),O.post("/:name/oauth/logout",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();return await uO(w,$),await w.logoutOAuth($),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to log out MCP OAuth:",$),x.json({success:!1,error:$.message},400)}}),O.delete("/:name",async(x)=>{try{let $=x.req.param("name");await KO.getInstance().unregisterServer($);let Q=YO();if(Q?.mcpServers){let{[$]:Y,...J}=Q.mcpServers;await AO().updateConfig({mcpServers:J})}return x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to delete MCP server:",$),x.json({success:!1,error:$.message},500)}}),O.post("/",async(x)=>{try{let $=await x.req.json(),{name:w,config:Q}=$;if(!w||!Q)return x.json({success:!1,error:"Missing name or config"},400);await KO.getInstance().registerServer(w,Q);let J=YO();return await AO().updateConfig({mcpServers:{...J?.mcpServers,[w]:Q}}),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to add MCP server:",$),x.json({success:!1,error:$.message},500)}}),O};import{getSupportedThinkingLevels as $w}from"@earendil-works/pi-ai";import{Hono as ww}from"hono";var t0=t("Service");function Qw(O,x,$=b1.list()){return{id:O.id,displayName:O.displayName,provider:O.provider,model:O.model,overrides:O.overrides,fallbackModels:O.fallbackModels,contextWindow:x.contextWindow,maxTokens:x.maxTokens,reasoning:x.reasoning,supportedReasoningEfforts:$w(x),supportedServiceTiers:D1(x),supportedResponseVerbosities:L1(x),communicationStyles:$,input:x.input}}function Zw(O){A1(O.overrides);let x={displayName:O.displayName||void 0,overrides:O.overrides||void 0};if(O.model)x.model=O.model;return x}function A1(O){let x=O?.streamIdleTimeout;if(x!==void 0&&(!Number.isFinite(x)||x<1000))throw new _("streamIdleTimeout must be at least 1000ms")}var S1=()=>{let O=new ww;return O.get("/",async(x)=>{try{let $=YO();if(!$)throw Error("Config not initialized");let w=x.get("directory")||o(),[Q,Y]=await Promise.all([s0(w,$),TO(w)]),J=Q.config.models,K=J.find((H)=>H.id===Q.config.currentModelId)??J[0],S=Q.catalog,B=Y.communicationStyles.list(),A=(H)=>Qw(H,S.resolveConfig(H),B);return x.json({configured:J.map(A),current:K?A(K):null})}catch($){t0.error("[ModelsRoutes] Failed to get models:",$);let w=new s("Failed to get models");return x.json(w.toObject(),500)}}),O.post("/",async(x)=>{let $=nO(),w,Q;try{let Y=await x.req.json(),{provider:J,displayName:K,model:S,overrides:B,apiKey:A,modelProvider:H}=Y;if(!J||!S)throw new _("provider and model are required");A1(B);let U;if(H){if(H.id!==J)throw new _("modelProvider.id must match the model provider");if(YO()?.modelProviders[J])throw new _(`model provider already exists: ${J}`);U={name:H.name,baseUrl:H.baseUrl,wireApi:H.wireApi,...H.apiKeyEnv?{apiKeyEnv:H.apiKeyEnv}:{}};try{$.registerModelProvider(J,U,[S]),Q=J}catch(l){throw new _(l instanceof Error?l.message:"Invalid model provider")}}else $.getModel(J,S);if(A?.trim()){if(await $.setApiKey(J,A.trim()),U)w=J}let T={provider:J,displayName:K||void 0,model:S,overrides:B||void 0},c=U?await AO().addModelWithProvider(T,U):await AO().addModel(T);return x.json({success:!0,model:c})}catch(Y){if(w)await $.credentials.delete(w);if(Q){let J=YO();$.configureModelProviders(J?.modelProviders??{},J?.models??[])}throw t0.error("[ModelsRoutes] Failed to add model:",Y),Y}}),O.put("/:modelId",async(x)=>{try{let $=x.req.param("modelId"),w=await x.req.json(),{displayName:Q,overrides:Y,model:J}=w,K=H1($);if(!K)throw new _("model config not found");if(J)nO().getModel(K.provider,J);return await AO().updateModel($,Zw({displayName:Q,overrides:Y,model:J})),x.json({success:!0})}catch($){throw t0.error("[ModelsRoutes] Failed to update model:",$),$}}),O.delete("/:modelId",async(x)=>{try{let $=x.req.param("modelId");return await AO().removeModel($),x.json({success:!0})}catch($){throw t0.error("[ModelsRoutes] Failed to delete model:",$),$}}),O};import{Hono as Tw}from"hono";import E1 from"node:path";import{Hono as Xw}from"hono";import{streamSSE as zw}from"hono/streaming";import{LRUCache as Gw}from"lru-cache";import{nanoid as W0}from"nanoid";class Bx{runtimes=new Map;createRuntime;constructor(O={}){this.createRuntime=O.createRuntime??((x)=>new j1(x.projectPath,`web-browser:${x.sessionId}`,{exposeArtifactPaths:!1}))}get(O){let x=m(O),$=this.runtimes.get(x);if(!$)$=this.createRuntime(O),this.runtimes.set(x,$);return $}async reset(O){let x=this.runtimes.get(m(O));if(x)await x.page({action:{kind:"reset"}})}async dispose(O){let x=m(O),$=this.runtimes.get(x);if(!$)return;this.runtimes.delete(x),await $.dispose()}async disposeAll(){let O=[...this.runtimes.values()];this.runtimes.clear();let $=(await Promise.allSettled(O.map((w)=>w.dispose()))).find((w)=>w.status==="rejected");if($)throw $.reason}stats(){return{sessions:this.runtimes.size}}}import{Hono as Yw}from"hono";var M1=W.Object({action:e(["accept","dismiss"])},{additionalProperties:!1}),Jw=RO(W.Union([W.Object({kind:W.Literal("click"),dialog:W.Optional(M1)},{additionalProperties:!1}),W.Object({kind:W.Literal("click_at"),screenshotId:W.String({minLength:1,maxLength:C0}),x:W.Integer({minimum:0,maximum:Ux}),y:W.Integer({minimum:0,maximum:Ux}),dialog:W.Optional(M1)},{additionalProperties:!1}),W.Object({kind:W.Literal("hover")},{additionalProperties:!1}),W.Object({kind:W.Literal("fill"),value:W.String()},{additionalProperties:!1}),W.Object({kind:W.Literal("type"),value:W.String()},{additionalProperties:!1}),W.Object({kind:W.Literal("press"),key:e(["Enter","Tab","Escape","Backspace","Delete","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown","Space"])},{additionalProperties:!1}),W.Object({kind:W.Literal("select"),values:W.Array(W.String())},{additionalProperties:!1}),W.Object({kind:W.Literal("check")},{additionalProperties:!1}),W.Object({kind:W.Literal("uncheck")},{additionalProperties:!1}),W.Object({kind:W.Literal("scroll"),direction:e(["up","down","left","right"]),amount:W.Integer()},{additionalProperties:!1})])),T1=RO(W.Object({action:W.Optional(e(["goto","back","forward","reload"])),url:W.Optional(W.String()),pageId:W.Optional(W.String()),expectedOrigin:W.Optional(W.String()),waitUntil:W.Optional(e(["commit","domcontentloaded","load"])),timeoutMs:W.Optional(W.Integer())},{additionalProperties:!1})),R1=RO(W.Object({pageId:W.String(),snapshotId:W.String(),ref:W.Optional(W.String()),expectedOrigin:W.String(),action:Jw,timeoutMs:W.Optional(W.Integer())},{additionalProperties:!1}));function q1(O,x){if(O===void 0)return;let $=Number(O);if(!Number.isSafeInteger($))throw new _(`${x} must be an integer`);return $}function Nw(O,x){if(O===void 0)return;if(O==="true")return!0;if(O==="false")return!1;throw new _(`${x} must be true or false`)}function Ww(O){let x=O.code==="browser_not_installed"||O.code==="browser_disconnected"||O.code==="browser_disposed"?503:O.code==="browser_capacity"?429:O.code==="browser_unsupported"?400:409;return new r(O.code.toUpperCase(),O.message,x,O.details)}function I1(O){let x=new Yw;x.use("*",(w,Q)=>O.withAdmission(Q)),x.onError((w,Q)=>{let Y=w instanceof C1?Ww(w):w instanceof r?w:new s;return Q.json(Y.toObject(),Y.statusCode)});let $=(w,Q)=>O.resolveSessionRef(w,Q);return x.post("/:sessionId/browser/navigate",async(w)=>{let Q=await w.req.json().catch(()=>{return}),Y=f(T1,Q);if(!Y.success)throw new _("Invalid browser navigation request");let J=await $(w.req.param("sessionId"),w.req.query("projectPath"));return w.json(await O.getRuntime(J).navigate(Y.data))}),x.post("/:sessionId/browser/interact",async(w)=>{let Q=await w.req.json().catch(()=>{return}),Y=f(R1,Q);if(!Y.success)throw new _("Invalid browser interaction request");let J=await $(w.req.param("sessionId"),w.req.query("projectPath"));return w.json(await O.getRuntime(J).interact(Y.data))}),x.get("/:sessionId/browser/snapshot",async(w)=>{let Q=await $(w.req.param("sessionId"),w.req.query("projectPath")),Y=q1(w.req.query("depth"),"depth"),J=Nw(w.req.query("includeBoxes"),"includeBoxes");return w.json(await O.getRuntime(Q).snapshot({...w.req.query("pageId")?{pageId:w.req.query("pageId")}:{},...Y===void 0?{}:{depth:Y},...J===void 0?{}:{includeBoxes:J}}))}),x.get("/:sessionId/browser/inspect",async(w)=>{let Q=await $(w.req.param("sessionId"),w.req.query("projectPath")),Y=w.req.query("target"),J=w.req.query("pageId"),K=w.req.query("expectedOrigin");if(Y==="screenshot"){let A=w.req.query("source")??"user";if(A!=="user"&&A!=="agent")throw new _("Unsupported browser screenshot source");if(A==="agent"&&(!J||!K))throw new _("Agent browser screenshots require pageId and expectedOrigin");let H={...J?{pageId:J}:{},...K?{expectedOrigin:K}:{}},U=A==="agent"?await O.captureAgentScreenshot(Q,H):await O.getRuntime(Q).screenshot(H);return new Response(new Uint8Array(U),{headers:{"Content-Type":"image/png","Content-Length":String(U.length),"Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}})}let S=q1(w.req.query("limit"),"limit"),B={...J?{pageId:J}:{},...K?{expectedOrigin:K}:{}};if(Y==="find"){let A=w.req.query("text");if(!A)throw new _("text is required for browser find");return w.json(await O.getRuntime(Q).inspect({...B,target:{kind:"find",text:A,...S===void 0?{}:{limit:S}}}))}if(Y!=="console"&&Y!=="page-errors"&&Y!=="network")throw new _("Unsupported browser inspection target");return w.json(await O.getRuntime(Q).inspect({...B,target:{kind:Y,...S===void 0?{}:{limit:S}}}))}),x.post("/:sessionId/browser/reset",async(w)=>{let Q=await $(w.req.param("sessionId"),w.req.query("projectPath"));return await O.resetRuntime(Q),w.json({success:!0})}),x}var g=t("Service"),Vw=W.Object({title:W.Optional(W.String()),projectPath:W.Optional(W.String())}),Bw=G4,Uw=W.Object({title:W.Optional(W.String()),projectPath:W.Optional(W.String())}),Kw=W.Object({projectPath:W.String()}),_w=W.Object({objective:W.String({minLength:1}),tokenBudget:W.Optional(W.Integer({minimum:1})),permissionMode:W.Optional(e(["default","autoEdit","plan","yolo"]))}),Fw=W.Union([W.Object({action:W.Literal("pause")}),W.Object({action:W.Literal("resume")}),W.Object({action:W.Literal("edit"),objective:W.String({minLength:1})})]),OO=new Map,z0,CO=new Map,mO=new Map,qO=new Map,$x=new Gw({max:100,ttl:1800000});function k1(O){return{sessionId:O.sessionId,projectPath:O.projectPath}}function FO(O){if(!O)return;return CO.get(O)??$x.get(O)}function Lw(O){if(CO.get(O.id)!==O)return;CO.delete(O.id),$x.set(O.id,O)}function Dw(O){CO.delete(O),$x.delete(O)}function _O(O){return O?.status==="queued"||O?.status==="running"||O?.status==="waiting_permission"}function k0(O,x="user-cancel"){if(O.status==="cancelled"||O.status==="completed"||O.status==="failed"||O.status==="attention_required")return!1;let $=O.pendingPermission;if(O.pendingPermission=void 0,$?.resolve({approved:!1,reason:d1}),$)q.publish(k1(O),"interaction.resolved",{requestId:$.permissionId});return O.abortController.abort(x),O.status="cancelled",q.publish(k1(O),"run.cancelled",{runId:O.id}),!0}function _4(O,x=!1){let{permissionId:$,details:w}=O;if(w.type==="askUserQuestion"&&w.questions)return{type:"question.required",properties:{requestId:$,toolCallId:w.toolCallId??$,questions:w.questions,details:w,...x?{replayed:!0}:{}}};if(w.type==="mcpElicitation"&&w.mcpElicitation)return{type:"elicitation.required",properties:{requestId:$,toolCallId:w.toolCallId??$,elicitation:w.mcpElicitation,...x?{replayed:!0}:{}}};return{type:"permission.asked",properties:{requestId:$,toolName:w.toolName,description:w.message,args:w.args,details:w,...x?{replayed:!0}:{}}}}function Hw(O){return{...typeof O.seq==="number"?{id:String(O.seq)}:{},data:JSON.stringify({type:O.type,...typeof O.seq==="number"?{seq:O.seq}:{},properties:{...O.properties,sessionId:O.sessionId,projectPath:O.projectPath}})}}function bw(){for(let O of CO.values())k0(O,"route-reset");CO.clear();for(let O of mO.values())O.controller.abort("route-reset");mO.clear(),$x.clear(),z0=void 0,OO.clear()}function Aw(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let x=O,$=x.code,w=x.reason,Q=x.scope,Y=x.kind,J=x.limit;if($!=="tool_busy"&&$!=="tool_batch_full"||w!=="queue_full"&&w!=="wait_timeout"&&w!=="turn_limit"||Q!=="global"&&Q!=="session"||typeof x.retryable!=="boolean"||!Number.isSafeInteger(J)||J<=0||Y!==void 0&&Y!=="readonly"&&Y!=="write"&&Y!=="execute")return;return{code:$,reason:w,scope:Q,retryable:x.retryable,...Y===void 0?{}:{kind:Y},limit:J}}var f0=(O,x)=>{if(!x||typeof x!=="object")return x;let $={...x},w=Aw($.tool_admission);if(w)$.tool_admission=w;else delete $.tool_admission;if(O4(O)){let J=$.browser&&typeof $.browser==="object"&&!Array.isArray($.browser)?$.browser:{},K={},S=(B,A,H)=>{let U=J[B];if(typeof U==="string"&&Buffer.byteLength(U)<=A&&(!H||H.test(U)))K[B]=U};if(S("action",64),S("status",16,/^(?:ok|warning|error)$/),S("pageId",C0,/^browser_page_[a-f0-9-]+$/),S("snapshotId",C0,/^browser_snapshot_[a-f0-9-]+$/),S("origin",Dx),S("candidateOrigin",Dx),S("url",l1),S("title",i1),S("errorCode",64,/^browser_[a-z_]+$/),typeof J.truncated==="boolean")K.truncated=J.truncated;if(typeof J.actionApplied==="boolean"||J.actionApplied==="unknown")K.actionApplied=J.actionApplied;if(typeof J.sideEffectsUncertain==="boolean")K.sideEffectsUncertain=J.sideEffectsUncertain;if(typeof J.diagnosticCount==="number"&&Number.isSafeInteger(J.diagnosticCount)&&J.diagnosticCount>=0&&J.diagnosticCount<=v1)K.diagnosticCount=J.diagnosticCount;if(J.interaction&&typeof J.interaction==="object"&&!Array.isArray(J.interaction)){let B=J.interaction,A=new Set(["click","hover","fill","type","press","select","check","uncheck","scroll"]);if(typeof B.action==="string"&&A.has(B.action)){let H={action:B.action};if(typeof B.ref==="string"&&Buffer.byteLength(B.ref)<=c1&&/^[a-z][a-z0-9]*$/.test(B.ref))H.ref=B.ref;let U=(T,c,l)=>typeof T==="number"&&Number.isFinite(T)&&T>=c&&T<=l;if(B.viewport&&typeof B.viewport==="object"&&!Array.isArray(B.viewport)){let T=B.viewport;if(U(T.width,1,16384)&&U(T.height,1,16384))H.viewport={width:T.width,height:T.height}}if(B.targetBox&&typeof B.targetBox==="object"&&!Array.isArray(B.targetBox)){let T=B.targetBox;if(U(T.x,-16384,32768)&&U(T.y,-16384,32768)&&U(T.width,0,16384)&&U(T.height,0,16384))H.targetBox={x:T.x,y:T.y,width:T.width,height:T.height}}K.interaction=H}}if(J.artifact&&typeof J.artifact==="object"&&!Array.isArray(J.artifact)){let B=J.artifact;if(typeof B.id==="string"&&/^[a-f0-9]{64}$/.test(B.id)&&B.sha256===B.id&&B.kind==="image"&&B.mimeType==="image/png"&&typeof B.size==="number"&&Number.isSafeInteger(B.size)&&B.size>=0&&B.size<=a1&&B.persisted===!0)K.artifact={id:B.id,sha256:B.sha256,kind:B.kind,mimeType:B.mimeType,size:B.size,persisted:!0,...typeof B.path==="string"&&Buffer.byteLength(B.path)<=8192?{path:B.path}:{}}}return{...typeof $.summary==="string"?{summary:$.summary.slice(0,512)}:{},browser:K,...w?{tool_admission:w}:{}}}if(O==="Bash"){let J={},K=["message","signal","status","summary"],S=["aborted","acp_mode","admission_failed","auto_backgrounded","background","capture_truncated","finalization_failed","has_stderr","output_accounting_complete","output_truncated","projection_truncated","sandbox_required","sandboxed","stderr_projection_truncated","stdout_projection_truncated","terminal_output_merged","timeout"],B=["execution_time","foreground_budget_ms","pid","raw_output_bytes","stderr_length","stderr_omitted_bytes","stderr_retained_bytes","stderr_total_bytes","stdout_length","stdout_omitted_bytes","stdout_retained_bytes","stdout_total_bytes"];for(let H of K){let U=$[H];if(typeof U==="string")J[H]=U.slice(0,8192)}for(let H of S){let U=$[H];if(typeof U==="boolean")J[H]=U}for(let H of B){let U=$[H];if(typeof U==="number"&&Number.isSafeInteger(U)&&U>=0)J[H]=U}if($.exit_code===null||typeof $.exit_code==="number"&&Number.isSafeInteger($.exit_code))J.exit_code=$.exit_code;if($.terminal_transport==="local"||$.terminal_transport==="acp"||$.terminal_transport==="local_fallback")J.terminal_transport=$.terminal_transport;if($.background_reason==="explicit"||$.background_reason==="foreground_budget")J.background_reason=$.background_reason;for(let H of["bash_id","shell_id"]){let U=$[H];if(typeof U==="string"&&U.length<=128&&/^bash_[A-Za-z0-9-]+$/.test(U))J[H]=U}if(w)J.tool_admission=w;let A=$.background_shell_admission;if(A&&typeof A==="object"&&!Array.isArray(A)){let H=A;if(H.code==="background_shell_busy"&&(H.scope==="session"||H.scope==="global")&&H.retryable===!0&&Number.isSafeInteger(H.limit)&&H.limit>0)J.background_shell_admission={code:H.code,scope:H.scope,retryable:H.retryable,limit:H.limit}}return J}let Q=200000,Y=(J,K)=>typeof J==="number"&&Number.isSafeInteger(J)&&J>=0&&J<=K?J:0;if(typeof $.oldContent==="string"&&$.oldContent.length>Q)delete $.oldContent;if(typeof $.newContent==="string"&&$.newContent.length>Q)delete $.newContent;if($.mcpResult&&typeof $.mcpResult==="object"&&!Array.isArray($.mcpResult)){let J=$.mcpResult,K=Array.isArray(J.artifacts)?J.artifacts.slice(0,64).flatMap((S)=>{if(!S||typeof S!=="object"||Array.isArray(S))return[];let B=S,A=new Set(["text","image","audio","resource"]);if(typeof B.id!=="string"||!/^[a-f0-9]{64}$/.test(B.id)||typeof B.sha256!=="string"||B.sha256!==B.id||typeof B.kind!=="string"||!A.has(B.kind)||Y(B.size,67108864)!==B.size||typeof B.persisted!=="boolean")return[];return[{id:B.id.slice(0,128),sha256:B.sha256.slice(0,128),kind:B.kind,size:B.size,persisted:B.persisted,...typeof B.mimeType==="string"?{mimeType:B.mimeType.slice(0,256)}:{},...typeof B.sourceUri==="string"?{sourceUri:B.sourceUri.slice(0,8192)}:{},...typeof B.path==="string"?{path:B.path.slice(0,8192)}:{}}]}):[];$.mcpResult={isError:J.isError===!0,contentCount:Y(J.contentCount,64),textBytes:Y(J.textBytes,4194304),structuredBytes:Y(J.structuredBytes,4194304),artifactCount:Y(J.artifactCount,64),truncated:J.truncated===!0,binaryOmitted:J.binaryOmitted===!0,artifacts:K}}else delete $.mcpResult;return $};function Sw(O){let x=typeof O.seq==="number"?{seq:O.seq}:{};if(O.type==="part_created"&&O.data.partType==="tool_call"){let $=O.data.payload;return{type:"tool.start",...x,properties:{messageId:O.data.messageId,toolCallId:$.toolCallId??O.data.partId,toolName:$.toolName??"unknown",arguments:JSON.stringify($.input??{})}}}if(O.type==="part_created"&&O.data.partType==="tool_result"){let $=O.data.payload,w=$.toolName??"unknown",Q=qx($),Y=y0(m0(w,Q),P0);return{type:"tool.result",...x,properties:{messageId:O.data.messageId,toolCallId:$.toolCallId??O.data.partId,toolName:w,success:Q.success,status:Q.success?"completed":"failed",summary:Q.metadata?.summary,output:h0(Y),metadata:f0(w,Q.metadata)}}}return{type:`committed.${O.type}`,...x,properties:{event:O}}}function jw(O,x,$){switch($.kind){case"tool_start":if("function"in $.toolCall)q.publish(O,"subagent.update",{subagentSessionId:x,toolName:$.toolCall.function.name}),q.publish(O,"subagent.tool.start",{subagentSessionId:x,toolCallId:$.toolCall.id,toolName:$.toolCall.function.name,arguments:$.toolCall.function.arguments,toolKind:$.toolKind});break;case"tool_result":if("function"in $.toolCall)q.publish(O,"subagent.tool.result",{subagentSessionId:x,toolCallId:$.toolCall.id,toolName:$.toolCall.function.name,success:$.result.success,summary:$.result.metadata?.summary,output:h0(y0(m0($.toolCall.function.name,$.result),P0)),metadata:f0($.toolCall.function.name,$.result.metadata)});break;case"tool_progress":if("function"in $.toolCall)q.publish(O,"subagent.tool.progress",{subagentSessionId:x,toolCallId:$.toolCall.id,toolName:$.toolCall.function.name,...$.update});break;case"content_delta":q.publish(O,"subagent.delta",{subagentSessionId:x,delta:$.delta});break;case"thinking_delta":q.publish(O,"subagent.thinking.delta",{subagentSessionId:x,delta:$.delta});break;case"stream_end":q.publish(O,"subagent.stream.end",{subagentSessionId:x});break;case"provider_admission":q.publish(O,"subagent.provider.admission",{subagentSessionId:x,phase:$.phase,requestClass:$.requestClass,resource:$.resource,scope:$.scope,reason:$.reason,queuePosition:$.queuePosition,queueDepth:$.queueDepth,inFlight:$.inFlight,limit:$.limit,waitMs:$.waitMs,maxWaitMs:$.maxWaitMs,recoveryRemainingMs:$.recoveryRemainingMs});break;case"provider_circuit":q.publish(O,"subagent.provider.circuit",{subagentSessionId:x,phase:$.phase,reason:$.reason,statusCode:$.statusCode,retryAfterMs:$.retryAfterMs,nextProbeAt:$.nextProbeAt,openDurationMs:$.openDurationMs,sampleCount:$.sampleCount,failureCount:$.failureCount,recoveryRemainingMs:$.recoveryRemainingMs});break;case"provider_retry":q.publish(O,"subagent.provider.retry",{subagentSessionId:x,phase:$.phase,attempt:$.attempt,maxRetries:$.maxRetries,reason:$.reason,statusCode:$.statusCode,delayMs:$.delayMs,nextRetryAt:$.nextRetryAt,mode:$.mode,recoveryBudgetMs:$.recoveryBudgetMs,recoveryElapsedMs:$.recoveryElapsedMs,recoveryRemainingMs:$.recoveryRemainingMs,exhaustedBy:$.exhaustedBy});break;case"provider_stall":q.publish(O,"subagent.provider.stall",{subagentSessionId:x,phase:$.phase,stallCount:$.stallCount,durationMs:$.durationMs,warningAfterMs:$.warningAfterMs,timeoutMs:$.timeoutMs,outputStarted:$.outputStarted});break;case"action_stationarity":q.publish(O,"subagent.action.stationarity",{subagentSessionId:x,phase:$.phase,toolName:$.toolName,runLength:$.runLength,nudgeThreshold:$.nudgeThreshold,haltThreshold:$.haltThreshold,progressAware:$.progressAware});break;case"mcp_catalog_changed":q.publish(O,"subagent.mcp.catalog.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,added:$.added,removed:$.removed,updated:$.updated});break;case"mcp_content_changed":q.publish(O,"subagent.mcp.content.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,contentKind:$.contentKind,added:$.added,removed:$.removed,updated:$.updated});break;case"mcp_resource_updated":q.publish(O,"subagent.mcp.resource.updated",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,uri:$.uri});break;case"mcp_connection_changed":q.publish(O,"subagent.mcp.connection.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,phase:$.phase,reason:$.reason,attempt:$.attempt,maxAttempts:$.maxAttempts,nextRetryAt:$.nextRetryAt,error:$.error});break;case"mcp_log":q.publish(O,"subagent.mcp.log",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,level:$.level,logger:$.logger,message:$.message,projectedBytes:$.projectedBytes,dataSha256:$.dataSha256,truncated:$.truncated,detailsOmitted:$.detailsOmitted,timestamp:$.timestamp,synthetic:$.synthetic});break;case"mcp_instructions_changed":q.publish(O,"subagent.mcp.instructions.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,action:$.action,reason:$.reason,text:$.text,sourceBytes:$.sourceBytes,projectedBytes:$.projectedBytes,sha256:$.sha256,truncated:$.truncated,detailsOmitted:$.detailsOmitted});break;case"mcp_task_changed":q.publish(O,"subagent.mcp.task.changed",{subagentSessionId:x,revision:$.revision,taskId:$.taskId,serverName:$.serverName,toolName:$.toolName,status:$.status,statusMessage:$.statusMessage,createdAt:$.createdAt,updatedAt:$.updatedAt,completedAt:$.completedAt,hasResult:$.hasResult,error:$.error});break;case"project_rules_loaded":q.publish(O,"subagent.project.rules.loaded",{subagentSessionId:x,files:$.files,triggerPaths:$.triggerPaths,blockedWrite:$.blockedWrite});break;default:break}}function I0(O,x="projectPath"){if(!E1.isAbsolute(O))throw new _(`${x} must be absolute`);return E1.resolve(O)}function Tx(O){try{o0(O)}catch(x){throw new _(x instanceof Error?x.message:`Invalid session ID: ${O}`)}}function XO(O){return{sessionId:O.id,projectPath:O.projectPath}}function E0(O,x,$){return{id:O.sessionId,projectPath:O.projectPath,title:O.title??`Session ${O.sessionId.slice(0,6)}`,createdAt:new Date(O.firstMessageTime),updatedAt:new Date(O.lastMessageTime),rootId:O.rootId,parentId:O.parentId,relationType:O.relationType,taskStatus:O.taskStatus,taskStatusReason:O.taskStatusReason,taskFailure:O.taskFailure,taskStartedAt:O.taskStartedAt,taskCompletedAt:O.taskCompletedAt,taskPromptSummary:O.taskPromptSummary,taskPriority:O.taskPriority,taskKind:O.taskKind,taskDueAt:O.taskDueAt,taskModelId:O.taskModelId,selectedModelId:O.selectedModelId,permissionMode:O.permissionMode,reasoningEffort:O.reasoningEffort,serviceTier:O.serviceTier,responseVerbosity:O.responseVerbosity,communicationStyle:O.communicationStyle,communicationStyleDigest:O.communicationStyleDigest,projectInstructionsDigest:O.projectInstructionsDigest,pendingInteraction:O.pendingInteraction,taskRetryAvailable:O.taskRetryAvailable,taskRetriedFrom:O.taskRetriedFrom,taskDelivery:O.taskDelivery,taskIsolation:O.taskIsolation,taskSourceProjectPath:O.taskSourceProjectPath,taskWorktreePath:O.taskWorktreePath,taskWorktreeBranch:O.taskWorktreeBranch,taskBaseCommit:O.taskBaseCommit,taskDiffStat:O.taskDiffStat,taskQueuePosition:O.taskQueuePosition,taskQueueDepth:O.taskQueueDepth,taskConcurrencyLimit:O.taskConcurrencyLimit,archivedAt:O.archivedAt,archivedBySessionId:O.archivedBySessionId,taskWorktree:$,messages:x}}function Kx(O){return O.flatMap((x)=>{if(!t1(x)||x.role==="system"||x.role==="tool"&&x.name===X0)return[];let $=x.tool_calls?.filter((J)=>!("function"in J)||J.function.name!==X0),w=typeof x.content==="string"?x.content.trim():"";if(x.role==="assistant"&&x.tool_calls?.length&&!$?.length&&!w&&!x.reasoningContent&&!x.metadata)return[];let Q={...x,...x.tool_calls?{tool_calls:$&&$.length>0?$:void 0}:{}};if(x.role==="tool"){let J=x.metadata&&typeof x.metadata==="object"&&!Array.isArray(x.metadata)?x.metadata:void 0,K=x.name??(typeof J?.toolName==="string"?J.toolName:"unknown");if(J!==void 0&&(Object.hasOwn(J,"output")||Object.hasOwn(J,"error"))){let B=qx(J),A=y0(m0(K,B),P0);return[{...Q,name:K,content:h0(A),metadata:f0(K,{...B.metadata,status:B.success?"completed":"failed"})}]}return[{...Q,name:K,metadata:f0(K,J)}]}let Y=r1(x.metadata);return[Y?{...Q,content:s1(Y)}:Q]})}function O0(O,x){O.title=x.title??O.title,O.taskStatus=x.taskStatus,O.taskStatusReason=x.taskStatusReason,O.taskFailure=x.taskFailure,O.taskStartedAt=x.taskStartedAt,O.taskCompletedAt=x.taskCompletedAt,O.taskPromptSummary=x.taskPromptSummary,O.taskPriority=x.taskPriority,O.taskKind=x.taskKind,O.taskDueAt=x.taskDueAt,O.taskModelId=x.taskModelId,O.selectedModelId=x.selectedModelId,O.permissionMode=x.permissionMode,O.reasoningEffort=x.reasoningEffort,O.serviceTier=x.serviceTier,O.responseVerbosity=x.responseVerbosity,O.communicationStyle=x.communicationStyle,O.communicationStyleDigest=x.communicationStyleDigest,O.projectInstructionsDigest=x.projectInstructionsDigest,O.pendingInteraction=x.pendingInteraction,O.taskRetryAvailable=x.taskRetryAvailable,O.taskRetriedFrom=x.taskRetriedFrom,O.taskDelivery=x.taskDelivery,O.taskIsolation=x.taskIsolation,O.taskSourceProjectPath=x.taskSourceProjectPath,O.taskWorktreePath=x.taskWorktreePath,O.taskWorktreeBranch=x.taskWorktreeBranch,O.taskBaseCommit=x.taskBaseCommit,O.taskDiffStat=x.taskDiffStat,O.taskQueuePosition=x.taskQueuePosition,O.taskQueueDepth=x.taskQueueDepth,O.taskConcurrencyLimit=x.taskConcurrencyLimit,O.archivedAt=x.archivedAt,O.archivedBySessionId=x.archivedBySessionId,O.updatedAt=new Date(x.lastMessageTime)}async function dO(O){let x=await C.findSessionMetadata(O.id,O.projectPath);if(x)O0(O,x)}function tO(O){let x=FO(O.currentRunId),$=x?.status==="waiting_permission"?"running":x?.status==="attention_required"?"interrupted":x?.status??O.taskStatus;return{sessionId:O.id,projectPath:O.projectPath,title:O.title,rootId:O.rootId,parentId:O.parentId,relationType:O.relationType,status:void 0,taskStatus:$,taskStatusReason:O.taskStatusReason,taskFailure:O.taskFailure,taskStartedAt:O.taskStartedAt,taskCompletedAt:O.taskCompletedAt,taskPromptSummary:O.taskPromptSummary,taskPriority:O.taskPriority,taskKind:O.taskKind,taskDueAt:O.taskDueAt,taskModelId:O.taskModelId,selectedModelId:O.selectedModelId,permissionMode:O.permissionMode,reasoningEffort:O.reasoningEffort,serviceTier:O.serviceTier,responseVerbosity:O.responseVerbosity,communicationStyle:O.communicationStyle,communicationStyleDigest:O.communicationStyleDigest,projectInstructionsDigest:O.projectInstructionsDigest,taskRetryAvailable:O.taskRetryAvailable,taskRetriedFrom:O.taskRetriedFrom,taskDelivery:O.taskDelivery,taskIsolation:O.taskIsolation,taskSourceProjectPath:O.taskSourceProjectPath,taskWorktreePath:O.taskWorktreePath,taskWorktreeBranch:O.taskWorktreeBranch,taskBaseCommit:O.taskBaseCommit,taskDiffStat:O.taskDiffStat,taskQueuePosition:$==="queued"?O.taskQueuePosition:void 0,taskQueueDepth:$==="queued"?O.taskQueueDepth:void 0,taskConcurrencyLimit:O.taskConcurrencyLimit,archivedAt:O.archivedAt,archivedBySessionId:O.archivedBySessionId,pendingInteraction:x?.pendingPermission?{type:x.pendingPermission.details.type==="askUserQuestion"?"question":x.pendingPermission.details.type==="mcpElicitation"?"elicitation":"permission",requestId:x.pendingPermission.permissionId}:O.pendingInteraction,agentType:void 0,model:void 0,messageCount:O.messages.length,firstMessageTime:O.createdAt.toISOString(),lastMessageTime:O.updatedAt.toISOString(),hasErrors:!1,isActive:!0}}async function VO(O,x){if(Tx(O),x!==void 0){let w=pO({sessionId:O,projectPath:I0(x)});if(OO.has(m(w)))return w;let Q=await C.findSessionMetadata(w.sessionId,w.projectPath);if(!Q)throw new y("Session",O);return pO({sessionId:Q.sessionId,projectPath:Q.projectPath})}let $=new Map;for(let w of OO.values()){if(w.id!==O)continue;let Q=XO(w);$.set(m(Q),Q)}for(let w of await C.listSessions()){if(w.sessionId!==O)continue;let Q=pO({sessionId:w.sessionId,projectPath:w.projectPath});$.set(m(Q),Q)}if($.size===0)try{let w=await C.findSessionMetadata(O);if(!w)throw new y("Session",O);return pO({sessionId:w.sessionId,projectPath:w.projectPath})}catch(w){if(w instanceof y)throw w;if(w instanceof Error&&w.message.startsWith("Ambiguous session ID:"))throw new bO;throw w}if($.size>1)throw new bO;return $.values().next().value}function Rx(O){if(typeof O==="string")return O;return O.filter((x)=>x.type==="text").map((x)=>x.text).join(`
|
|
7
|
-
`)}function f1(O,x){let $=(x??[]).filter((Q)=>Q.type==="image"&&typeof Q.content==="string").map((Q)=>({type:"image_url",image_url:{url:Q.content}}));if($.length===0)return O;let w=[];if(O.trim())w.push({type:"text",text:O});return w.push(...$),w}var F4=()=>{bw();let O=new Xw;O.onError((Z,G)=>{if(Z instanceof N0){let N=new PO("Session runtime capacity is full",{resource:Z.resource,limit:Z.limit});return G.json(N.toObject(),429)}if(Z instanceof r)return G.json(Z.toObject(),Z.statusCode);return g.error("[SessionRoutes] Unhandled route error:",Z),G.json({error:{code:"INTERNAL_ERROR",message:"Internal server error"}},500)});let x=new Map,$=new Bx,w=new Map,Q=new Map,Y=new Map,J=new _x,K=new _x,S=YO(),B=new K4({maxResident:S?.maxResidentSessionRuntimes??m1,idleMs:S?.sessionRuntimeIdleMs??h1}),A=new J4,H=setInterval(()=>{B.sweepIdle().catch((Z)=>{g.warn("[SessionRoutes] Session Runtime idle sweep failed:",Z)})},g1);H.unref?.();let U,T=async(Z)=>{let G;try{G=A.enter()}catch{throw new yO}try{return await Z()}finally{G.release()}};O.use("*",async(Z,G)=>{if(Z.req.method==="GET"||Z.req.method==="HEAD")return G();return T(G)});let c=(Z,G)=>J.runExclusive(m(Z),G),l=(Z,G)=>K.runExclusive(m(Z),G),JO=(Z)=>[...CO.values()].some((G)=>G.sessionId===Z.sessionId&&G.projectPath===Z.projectPath&&_O(G)),R=async(Z,G,N)=>{let X=Q.get(G);if(!X)X=(async()=>{if(x.get(G)===N)x.delete(G);for(let[L,F]of x)if(F===N)x.delete(L);let V=XO(Z);if(OO.get(G)===Z&&!JO(V)&&!mO.has(G)&&!qO.has(G))OO.delete(G);if(await N.dispose(),x.size===0)await KO.getInstance().disconnectAll()})().finally(()=>{if(Q.get(G)===X)Q.delete(G)}),Q.set(G,X);await X},NO=async(Z,G={})=>{let N=XO(Z),X=m(N);await Q.get(X);let V=B.acquire(X);if(V){if(x.get(X)!==V.value)throw V.release(),Error("Session Runtime residency identity is inconsistent");return V}if(B.owns(X))throw new N0(B.getStats().maxResident);let L=w.get(X);if(!L){let F=G.communicationStyle??Z.communicationStyle;L=(async()=>{let D=await B.reserve(X,{surface:"web",allowEviction:!0});try{let b=await sO.create({sessionId:Z.id,workspaceRoot:Z.projectPath,permissionMode:G.permissionMode??Z.permissionMode??"default",...Z.reasoningEffort?{reasoningEffort:Z.reasoningEffort}:{},...Z.serviceTier?{serviceTier:Z.serviceTier}:{},...Z.responseVerbosity?{responseVerbosity:Z.responseVerbosity}:{},...F?{communicationStyle:F}:{},...F===Z.communicationStyle&&Z.communicationStyleDigest?{communicationStyleDigest:Z.communicationStyleDigest}:{},...Z.projectInstructionsDigest?{projectInstructionsDigest:Z.projectInstructionsDigest}:{},...Z.taskWorktree?{taskWorktree:Z.taskWorktree}:{},...Z.taskIsolation?{taskIsolation:Z.taskIsolation}:{},...Z.messages.length>0?{sessionStart:{isResume:!0,resumeSessionId:Z.id}}:{}}),j=b.getCurrentModelId();if(j&&(Z.selectedModelId||Z.taskModelId)&&j!==Z.selectedModelId){let I=await C.updateSessionMetadata(Z.id,Z.projectPath,{selectedModelId:j}).catch((QO)=>{g.warn(`[SessionRoutes] Failed to migrate restored model for ${Z.id}:`,QO);return});if(I)Z.selectedModelId=I.selectedModelId,Z.updatedAt=new Date(I.lastMessageTime)}let M=D.commit({key:X,surface:"web",value:b,canEvict:()=>!JO(N)&&!mO.has(X)&&!qO.has(X)&&!w.has(X)&&!Q.has(X)&&b.isIdleForResidency(),dispose:()=>R(Z,X,b)});return x.set(X,b),{runtime:b,claimLease:()=>{if(M){let QO=M;return M=void 0,QO}let I=B.acquire(X);if(!I||I.value!==b)throw Error("Initialized Session Runtime lost residency");return I}}}catch(b){if(D.cancel(),b instanceof w4)throw new c0(b.reason);throw b}})(),w.set(X,L)}try{return(await L).claimLease()}finally{if(w.get(X)===L)w.delete(X)}},p=async(Z,G,N={})=>{let X=await NO(Z,N);try{return await G(X.value)}finally{X.release()}},v=async(Z,G)=>{let N=m(XO(Z)),X=w.get(N);if(X)await X.catch(()=>{return});w.delete(N);let V=G??x.get(N);if(!V)return;if(!await B.remove(N,V))throw Error(`Session Runtime is pinned and cannot be disposed: ${N}`)},ZO=async(Z)=>{let G=m(Z),N=OO.get(G);if(N)return N;let X=Y.get(G);if(!X)X=(async()=>{let V=await C.findSessionMetadata(Z.sessionId,Z.projectPath);if(!V)throw new y("Session",Z.sessionId);let[L,F]=await Promise.all([C.loadSession(Z.sessionId,Z.projectPath),C.findSessionTaskWorktree(Z.sessionId,Z.projectPath)]),D=E0(V,L,F);return OO.set(G,D),D})(),Y.set(G,X);try{return await X}finally{if(Y.get(G)===X)Y.delete(G)}},wO=async(Z,G)=>{let N=await VO(Z,G);try{await C.assertSessionWritable(N.sessionId,N.projectPath)}catch(X){if(X instanceof bx)throw new k(X.message);throw X}return ZO(N)},IO=async(Z,G)=>{if(Z.permissionMode===G)return;let N=await C.setSessionPermissionMode(Z.id,Z.projectPath,G);Z.permissionMode=N.permissionMode,Z.updatedAt=new Date(N.lastMessageTime),q.publish(XO(Z),"session.updated",{permissionMode:G})},xO=(Z,G,N,X={})=>{if(!A.stats().accepting)throw new yO;let V=W0(12),L={id:V,sessionId:Z.id,projectPath:Z.projectPath,status:"running",abortController:new AbortController,disposeRuntimeOnSettle:Z.taskIsolation!==void 0&&X.runtimeLease!==void 0,createdAt:new Date};if(Z.taskIsolation&&X.runtimeLease){let F=X.runtimeLease.value,D=gO.admit({key:`${Z.projectPath}\x00${Z.id}`,...F.getTaskAdmissionLimits(),pendingBytes:Y4({content:G,outputSchema:X.outputSchema,pendingMessages:F.getPendingSteeringMessages()}),signal:L.abortController.signal,onUpdate:(j)=>{L.status=j.state,Z.taskStatus=j.state,Z.taskQueuePosition=j.queuePosition,Z.taskQueueDepth=j.queueDepth,Z.taskConcurrencyLimit=j.maxConcurrent,L.taskAdmissionUpdate=(L.taskAdmissionUpdate??Promise.resolve()).then(async()=>{await F.setTaskAdmission(j)}).catch((M)=>{g.warn(`[SessionRoutes] Failed to persist admission for ${Z.id}:`,M)})}});L.taskAdmission=D;let b=D.getSnapshot();L.status=b.state,Z.taskStatus=b.state,Z.taskQueuePosition=b.queuePosition,Z.taskQueueDepth=b.queueDepth,Z.taskConcurrencyLimit=b.maxConcurrent}return CO.set(V,L),Z.currentRunId=V,L.completion=Mw(L,Z,G,N,NO,{pendingInputOnly:X.pendingInputOnly,preparedInputTurn:X.preparedInputTurn,goalContinuationOnly:X.goalContinuationOnly,outputSchema:X.outputSchema,taskAdmission:L.taskAdmission,runtimeLease:X.runtimeLease,disposeRuntime:v}).catch((F)=>{g.error(`[SessionRoutes] Run ${V} failed:`,F)}),L},aO=async(Z)=>{let G;if(Z.outputSchema)try{G=Hx(Z.outputSchema).schema}catch(u){throw new _(u instanceof Error?u.message:"Invalid output schema")}let N=Lx("task",12),X=I0(Z.sourceProjectPath),V=Z.modelId?.trim(),L=YO();if(!L)throw new _("Config not initialized");let[F,D]=await Promise.all([s0(X,L),TO(X)]);if(V&&!F.config.models.some((u)=>u.id===V))throw new _(`Task model not found: ${V}`);let b=V||F.config.models.find((u)=>u.id===F.config.currentModelId)?.id||F.config.models[0]?.id;if(!b)throw new _("No model is configured. Add or select a model before dispatching a task.");let j=F.config.models.find((u)=>u.id===b);if(!j)throw new _(`Task model not found: ${b}`);let M=Z.reasoningEffort??"off",I=Z.serviceTier??"auto",QO=Z.responseVerbosity??"auto",HO=Z.communicationStyle??"auto",MO,zO=D.projectRules?.staticRules(X),$O=zO&&zO.files.length>0?zO.provenanceSha256:void 0;try{let u=F.catalog.resolveConfig(j);u1(u,M),y1(u,I),P1(u,QO);let i=p1(HO,D.communicationStyles);MO=i.source==="built-in"?void 0:i.contentSha256}catch(u){throw new _(u instanceof Error?u.message:"Invalid reasoning effort")}let w0={version:1,prompt:Z.prompt,...Z.title?{title:Z.title}:{},...Z.taskPriority?{taskPriority:Z.taskPriority}:{},...Z.taskKind?{taskKind:Z.taskKind}:{},...Z.taskDueAt?{taskDueAt:Z.taskDueAt}:{},sourceProjectPath:X,isolation:Z.isolation,permissionMode:Z.permissionMode,modelId:b,reasoningEffort:M,serviceTier:I,responseVerbosity:QO,communicationStyle:HO,...MO?{communicationStyleDigest:MO}:{},...$O?{projectInstructionsDigest:$O}:{},...Z.attachments?{attachments:Z.attachments.map((u)=>({...u}))}:{},...G?{outputSchema:G}:{}},E,h,P;try{let u=await W4.createSessionTask({sessionId:N,prompt:Z.prompt,title:Z.title,taskPriority:Z.taskPriority,taskKind:Z.taskKind,taskDueAt:Z.taskDueAt,sourceProjectPath:X,isolation:Z.isolation,dispatch:w0,retriedFrom:Z.retriedFrom}),{metadata:i}=u;E=u.taskWorktree,h=E0(i,[],E);let d=XO(h);OO.set(m(d),h),q.publish(d,"task.status",{taskStatus:i.taskStatus,updatedAt:i.lastMessageTime});let a=f1(Z.prompt,Z.attachments);P=await NO(h);let hO=P.value,n=G?await hO.prepareInputTurn(a,{outputSchema:G}):await hO.prepareInputTurn(a);if(!n.accepted)throw new k(`Task prompt was not accepted: ${n.reason}`);let WO=xO(h,a,Z.permissionMode,{preparedInputTurn:n,runtimeLease:P,outputSchema:G});return P=void 0,await WO.taskAdmissionUpdate,{session:tO(h),runId:WO.id,messageId:n.messageId,status:WO.status==="queued"?"queued":"running",queuePosition:h.taskQueuePosition,queueDepth:h.taskQueueDepth,maxConcurrentTasks:h.taskConcurrencyLimit}}catch(u){if(P?.release(),P=void 0,(u instanceof Mx||u instanceof N0)&&h){let i=XO(h),d=m(i);if(E)await fO.exit({sessionId:h.id,action:"remove",discardChanges:!0}).catch(()=>{return});throw await v(h).catch(()=>{return}),await C.deleteSession(h.id,h.projectPath).catch(()=>{return}),OO.delete(d),new PO(u instanceof N0?"Session runtime capacity is full":"Task admission capacity is full",{resource:u.resource,limit:u.limit})}if(h){let i=await C.findSessionMetadata(h.id,h.projectPath).catch(()=>{return});if(!i||i.taskStatus==="queued"){let d=e0(u),a=await C.updateSessionMetadata(h.id,h.projectPath,{taskStatus:"failed",taskStatusReason:d.message,taskFailure:d,taskCompletedAt:new Date().toISOString(),taskOwnerPid:null}).catch(()=>{return});h.taskStatus=a?.taskStatus??"failed",h.taskStatusReason=a?.taskStatusReason??d.message,h.taskFailure=a?.taskFailure??d,h.taskCompletedAt=a?.taskCompletedAt}else h.taskStatus=i.taskStatus,h.taskStatusReason=i.taskStatusReason,h.taskFailure=i.taskFailure,h.taskCompletedAt=i.taskCompletedAt}throw u}},LO=(Z)=>T(()=>aO(Z)),z=async(Z,G)=>{let N=await VO(Z,G),X=await C.findSessionMetadata(N.sessionId,N.projectPath);if(!X)throw new y("Session",N.sessionId);if(!["failed","interrupted","cancelled"].includes(X.taskStatus))throw new k(`Task cannot be retried while status is ${X.taskStatus}`);let V=await C.findSessionTaskDispatch(N.sessionId,N.projectPath);if(!V)throw new k("Task retry payload is unavailable");return LO({prompt:V.prompt,title:X.title??V.title,taskPriority:X.taskPriority??V.taskPriority,taskKind:X.taskKind??V.taskKind,taskDueAt:X.taskDueAt,sourceProjectPath:V.sourceProjectPath,isolation:V.isolation,permissionMode:V.permissionMode,modelId:V.modelId,reasoningEffort:V.reasoningEffort,serviceTier:V.serviceTier,responseVerbosity:V.responseVerbosity,communicationStyle:V.communicationStyle,attachments:V.attachments,outputSchema:V.outputSchema,retriedFrom:N})},UO=(Z,G)=>T(()=>z(Z,G)),cx=(Z,G,N)=>T(async()=>{let X=await VO(Z,N);if(!await C.findSessionMetadata(X.sessionId,X.projectPath))throw new y("Session",X.sessionId);let L=await C.updateSessionMetadata(X.sessionId,X.projectPath,G),F=OO.get(m(X));if(F)O0(F,L);return q.publish(X,"session.updated",{...L.title?{title:L.title}:{},...L.taskPriority?{taskPriority:L.taskPriority}:{},...L.taskKind?{taskKind:L.taskKind}:{},taskDueAt:L.taskDueAt??null}),F?tO(F):{...L,isActive:!1}}),Jx=async(Z,G)=>{let N=await wO(Z,G);if(!N.taskWorktree)throw new _("Session does not have a task worktree");try{await fO.restoreSession(N.taskWorktree);let X=await fO.getDiffArtifact(N.id);if(!X)throw new k("Task diff artifact is unavailable");return{sessionId:N.id,projectPath:N.projectPath,...X}}catch(X){if(X instanceof k)throw X;throw g.error("[SessionRoutes] Failed to load task diff artifact:",X),new k("Task diff artifact is unavailable")}},H0=async(Z,G,N)=>{let X=await VO(Z,N);return l(X,async()=>{let V=await wO(X.sessionId,X.projectPath);if(["queued","running"].includes(V.taskStatus))throw new k(`Task artifacts cannot be delivered while status is ${V.taskStatus}`);if(V.taskDelivery?.status==="applied")throw new k("Task changes have already been applied");if(V.taskDelivery?.status==="discarded")throw new k("Task changes have already been discarded");if(!V.taskWorktree)throw new k("Task worktree is unavailable");let L=async(F,D=!1)=>{let b=await C.updateSessionMetadata(V.id,V.projectPath,{taskDelivery:F,...D?{taskWorktree:null}:{}});if(O0(V,b),D)V.taskWorktree=void 0;return q.publish(X,"task.delivery",{taskDelivery:F,...D?{taskWorktreeRemoved:!0}:{},updatedAt:b.lastMessageTime}),tO(V)};try{if(G==="discard"){try{await fO.restoreSession(V.taskWorktree)}catch(b){return g.warn(`[SessionRoutes] Abandoning unavailable task worktree for ${V.id}:`,b),L({status:"discarded",updatedAt:new Date().toISOString(),changedFiles:V.taskDiffStat?.changedFiles??0,message:"Task artifact discarded; worktree was unavailable"},!0)}let D=await fO.exit({sessionId:V.id,action:"remove",discardChanges:!0});return L({status:"discarded",updatedAt:new Date().toISOString(),changedFiles:D.discardedFiles??0,message:"Task worktree removed"},!0)}try{await fO.restoreSession(V.taskWorktree)}catch(D){throw g.warn(`[SessionRoutes] Task worktree is unavailable for ${V.id}:`,D),new jx("artifact_unavailable","Task worktree is unavailable")}let F=await fO.apply(V.id);return L({status:"applied",updatedAt:new Date().toISOString(),sourceCommit:F.sourceCommit,changedFiles:F.changedFiles,message:"Task changes applied to the source workspace"})}catch(F){if(F instanceof jx)throw await L({status:"conflicted",updatedAt:new Date().toISOString(),message:F.message}),new k(F.message);throw F}})},d0=(Z,G,N)=>T(()=>H0(Z,G,N)),v0=async(Z)=>{let G=FO(Z.currentRunId);if(_O(G))return;let N=Z.taskIsolation&&Z.taskStatus!=="queued"&&Z.taskStatus!=="running",X=N?await sO.hasRecoverableTurn(Z.projectPath,Z.id):!1;if(N&&!X)return;let V=await sO.hasPendingInbox(Z.projectPath,Z.id),L=!V&&await sO.hasActiveGoal(Z.projectPath,Z.id);if(!V&&!L&&!X)X=await sO.hasRecoverableTurn(Z.projectPath,Z.id);if(!V&&!L&&!X)return;let F=await NO(Z),D=!1;try{let b=F.value,j=FO(Z.currentRunId);if(_O(j))return;if(V&&b.getPendingSteeringCount()===0)await b.reloadPendingInbox();let M=b.getPendingSteeringCount()>0,I=M?null:await b.getGoal(),QO=I?.status==="active"||I?.status==="verifying",HO=b.getTurnRecoveryAssessment();if(HO.state!=="none"&&(HO.state==="requires_attention"||!M&&!QO))q.publish({sessionId:Z.id,projectPath:Z.projectPath},"turn.recovery",{assessment:HO});if(HO.state==="requires_attention"||N||!M&&!QO||b.hasTurnOwner())return;xO(Z,"",Z.permissionMode??"default",{pendingInputOnly:M,goalContinuationOnly:QO,runtimeLease:F}),D=!0}finally{if(!D)F.release()}},EO=async(Z)=>{let G;try{G=A.enter()}catch{return}try{await v0(Z)}finally{G.release()}};z0=EO;let Yx=async()=>{let Z={scheduled:0,failed:0,deferred:0};if(!A.stats().accepting)return Z;let G=(await C.listSessions({taskStatus:"queued"})).filter((N)=>N.taskIsolation!==void 0).sort((N,X)=>N.firstMessageTime.localeCompare(X.firstMessageTime)||N.projectPath.localeCompare(X.projectPath)||N.sessionId.localeCompare(X.sessionId));for(let[N,X]of G.entries()){let V={sessionId:X.sessionId,projectPath:X.projectPath};try{if(!await sO.hasPendingInbox(X.projectPath,X.sessionId)){let F=e0("Queued task input is missing");await C.updateSessionMetadata(X.sessionId,X.projectPath,{taskStatus:"failed",taskStatusReason:F.message,taskFailure:F,taskCompletedAt:new Date().toISOString(),taskOwnerPid:null,taskQueuePosition:null,taskQueueDepth:null}),Z.failed++;continue}let L=await ZO(V);if(await EO(L),L.currentRunId)Z.scheduled++}catch(L){if(L instanceof Mx||L instanceof N0){Z.deferred+=G.length-N;break}g.warn(`[SessionRoutes] Failed to recover queued task ${X.sessionId}:`,L),Z.deferred++}}return Z};return O.route("/",I1({withAdmission:T,resolveSessionRef:async(Z,G)=>{let N=await VO(Z,G);return await ZO(N),N},getRuntime:(Z)=>$.get(Z),captureAgentScreenshot:async(Z,G)=>{let N=await ZO(Z);return p(N,(X)=>X.captureBrowserScreenshot(G))},resetRuntime:(Z)=>$.reset(Z)})),O.get("/",async(Z)=>{try{let G=await C.listSessions(),N=new Set(G.filter((j)=>j.relationType==="subagent").map((j)=>m({sessionId:j.sessionId,projectPath:j.projectPath}))),X=Array.from(OO.values()).filter((j)=>!N.has(m(XO(j)))&&j.relationType!=="subagent").map((j)=>tO(j)),V=new Set(X.map((j)=>m({sessionId:j.sessionId,projectPath:j.projectPath}))),L=G.filter((j)=>{if(j.relationType==="subagent")return!1;return!V.has(m({sessionId:j.sessionId,projectPath:j.projectPath}))}),F=new Set(V),D=L.filter((j)=>{let M=m({sessionId:j.sessionId,projectPath:j.projectPath});if(F.has(M))return!1;return F.add(M),!0}),b=[...X,...D];return Z.json(b)}catch(G){throw g.error("[SessionRoutes] Failed to list sessions:",G),new s("Failed to list sessions")}}),O.get("/catalog",async(Z)=>{try{let G=Z.req.query("limit"),N=G===void 0?void 0:Number(G),X=Z.req.query("cursor"),V=Z.req.query("projectPath"),L=Z.req.query("archived");if(L!==void 0&&L!=="true"&&L!=="false")throw new _("archived must be true or false");let F=L==="true",D=await C.listSessionPage({...V?{cwd:I0(V)}:{},...X?{cursor:X}:{},...N===void 0?{}:{limit:N},includeSubagents:!1,archived:F}),b=new Map((F?[]:Array.from(OO.values())).filter((j)=>j.relationType!=="subagent").map((j)=>[m(XO(j)),tO(j)]));return Z.json({sessions:D.sessions.map((j)=>b.get(m({sessionId:j.sessionId,projectPath:j.projectPath}))??j),...D.nextCursor?{nextCursor:D.nextCursor}:{}})}catch(G){if(G instanceof _)throw G;if(G instanceof Error&&(G.message.startsWith("Invalid session cursor")||G.message.startsWith("Session cursor scope")||G.message.startsWith("Session catalog")))throw new _(G.message);throw g.error("[SessionRoutes] Failed to list session catalog:",G),new s("Failed to list session catalog")}}),O.post("/",async(Z)=>{try{let G=await Z.req.json(),N=f(Vw,G);if(!N.success)throw new _("Invalid request body");let{title:X,projectPath:V}=N.data,L=Lx("web",12),F=I0(V||Z.get("directory")||o(),V?"projectPath":"directory"),D=await C.createSessionMetadata(L,F,{title:X,taskStatus:"completed"}),b=E0(D,[]),j=XO(b);return OO.set(m(j),b),q.publish(j,"session.created",{}),Z.json({...tO(b),status:void 0,agentType:void 0,model:void 0})}catch(G){if(g.error("[SessionRoutes] Failed to create session:",G),G instanceof _)throw G;throw new s("Failed to create session")}}),O.get("/:sessionId/export",async(Z)=>{let G=Z.req.param("sessionId");try{let N=Z.req.query("includeReasoning");if(N!==void 0&&N!=="true"&&N!=="false")throw new _("includeReasoning must be true or false");let X=await VO(G,Z.req.query("projectPath")),V=await C.exportSessionMarkdown(X.sessionId,X.projectPath,{includeReasoning:N==="true"});return Z.body(V.markdown,200,{"Cache-Control":"no-store","Content-Disposition":`attachment; filename="${V.filename}"`,"Content-Length":String(Buffer.byteLength(V.markdown,"utf8")),"Content-Type":"text/markdown; charset=utf-8","X-Blade-Content-Sha256":V.contentSha256,"X-Blade-Export-Activities":String(V.activityCount),"X-Blade-Export-Messages":String(V.messageCount),"X-Blade-Export-Redactions":String(V.redactionCount)})}catch(N){if(N instanceof _||N instanceof y||N instanceof bO)throw N;if(N instanceof Error&&N.message==="No conversation content to export")throw new k(N.message);throw g.error("[SessionRoutes] Failed to export session:",N),new s("Failed to export session")}}),O.post("/:sessionId/fork",async(Z)=>{let G=Z.req.param("sessionId");try{Tx(G);let N=await Z.req.json(),X=f(Kw,N);if(!X.success)throw new _("Invalid request body");let V=I0(X.data.projectPath),L=await C.findSessionMetadata(G,V);if(!L)throw new y("Session",G);let F=await C.forkSession(G,{sourceProjectPath:L.projectPath,targetProjectPath:L.projectPath}),D=E0(F.metadata,F.messages),b=XO(D);return OO.set(m(b),D),q.publish(b,"task.status",{taskStatus:F.metadata.taskStatus,...F.metadata.taskCompletedAt?{taskCompletedAt:F.metadata.taskCompletedAt}:{},updatedAt:F.metadata.lastMessageTime}),Z.json({session:F.metadata,messages:Kx(F.messages)},201)}catch(N){if(N instanceof _||N instanceof y||N instanceof k)throw N;if(N instanceof e1)throw new k("Session has no durable creation record");throw g.error("[SessionRoutes] Failed to fork session:",N),new s("Failed to fork session")}}),O.get("/:sessionId",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N));if(X)return Z.json(tO(X));let V=await C.findSessionMetadata(N.sessionId,N.projectPath);if(!V)throw new y("Session",G);return Z.json(V)}catch(N){if(N instanceof _||N instanceof y||N instanceof bO)throw N;throw g.error("[SessionRoutes] Failed to get session:",N),new s("Failed to get session")}}),O.patch("/:sessionId",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await Z.req.json(),X=f(Uw,N);if(!X.success)throw new _("Invalid request body");if(X.data.title===void 0)throw new _("title is required");let V=await VO(G,X.data.projectPath),L=await C.updateSessionMetadata(V.sessionId,V.projectPath,{title:X.data.title}),F=OO.get(m(V));if(F)F.title=L.title??F.title,F.updatedAt=new Date(L.lastMessageTime);if(L.title)q.publish(V,"session.updated",{title:L.title});return Z.json({success:!0,title:L.title})}catch(N){if(g.error("[SessionRoutes] Failed to update session:",N),N instanceof _||N instanceof y||N instanceof bO)throw N;throw new s("Failed to update session")}}),O.get("/:sessionId/rewind",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath"));return p(G,async(N)=>Z.json({checkpoints:await N.listRewindCheckpoints()}))}),O.post("/:sessionId/rewind",async(Z)=>{let G=f(X4,await Z.req.json());if(!G.success)throw new _("Invalid rewind request");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=FO(N.currentRunId);if(_O(V))throw new k("Cannot rewind while a run is active");return p(N,async(L)=>{let F;try{F=await L.rewindSession(G.data)}catch(b){if(b instanceof Error&&b.message.startsWith("Cannot rewind while"))throw new k(b.message);throw b}N.messages=[...F.messages],N.updatedAt=new Date;let D=Kx(F.messages);return q.publish(X,"session.rewound",{targetMessageId:F.checkpoint.messageId,mode:F.mode,removedTurns:F.removedTurns,restoredFiles:F.restoredFiles,messages:D}),Z.json({...F,messages:D})})})}),O.get("/:sessionId/review",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath")),X=await rO.list(N.projectPath,N.sessionId);return Z.json({reviews:X.map((V)=>({...V,content:V.completion?o1(V.start,V.completion):void 0}))})}),O.post("/:sessionId/review",async(Z)=>{let G=Z.req.param("sessionId"),N=f(U4,await Z.req.json());if(!N.success)throw new _("Invalid code review request");let X=await wO(G,N.data.projectPath),V=XO(X),L=m(V);return c(V,async()=>{if(_O(FO(X.currentRunId)))throw new k("Cannot start a review during an active turn");if(qO.has(L))throw new k("Session already has an active review");return p(X,async(F)=>{if(await rO.recoverInterrupted(V.projectPath,V.sessionId,F),N.data.modelId&&!F.getModelById(N.data.modelId))throw new _(`Model not found: ${N.data.modelId}`);if(N.data.modelId&&F.getCurrentModelId()!==N.data.modelId)await F.refresh({modelId:N.data.modelId});if(N.data.modelId&&X.selectedModelId!==N.data.modelId){let M=await C.updateSessionMetadata(X.id,X.projectPath,{selectedModelId:N.data.modelId});O0(X,M)}let D=new AbortController,b;try{b=await rO.start({sessionId:V.sessionId,projectPath:V.projectPath,runtime:F,request:{kind:N.data.kind,...N.data.ref?{ref:N.data.ref}:{},...N.data.instructions?{instructions:N.data.instructions}:{}},signal:D.signal,onEvent:(M)=>{if(M.kind==="tool_start")q.publish(V,"review.tool.started",{reviewId:b?.reviewId,toolCallId:M.toolCall.id,toolName:M.toolCall.function.name});else if(M.kind==="tool_progress")q.publish(V,"review.tool.progress",{reviewId:b?.reviewId,toolCallId:M.toolCall.id,message:M.update.message.slice(0,1000)});else if(M.kind==="tool_result")q.publish(V,"review.tool.completed",{reviewId:b?.reviewId,toolCallId:M.toolCall.id,success:M.result.success})}})}catch(M){if(M instanceof Error&&(M.message.includes("active review")||M.message.includes("interrupted review")||M.message.includes("active turn")))throw new k(M.message);if(M instanceof Error&&(M.message.includes("review")||M.message.includes("Git")||M.message.includes("changes")||M.message.includes("ref")))throw new _(M.message);throw M}if(!b)throw new s("Code review failed to start");await dO(X),q.publish(V,"review.started",{reviewId:b.reviewId,kind:N.data.kind}),q.publish(V,"task.status",{taskStatus:X.taskStatus,...X.taskStatusReason?{taskStatusReason:X.taskStatusReason}:{},...X.taskStartedAt?{taskStartedAt:X.taskStartedAt}:{},...X.taskPromptSummary?{taskPromptSummary:X.taskPromptSummary}:{},updatedAt:new Date().toISOString()});let j=b.completion.then(async(M)=>{X.messages=await C.loadSession(V.sessionId,V.projectPath),await dO(X),q.publish(V,"task.status",{taskStatus:X.taskStatus,...X.taskStatusReason?{taskStatusReason:X.taskStatusReason}:{},...X.taskFailure?{taskFailure:X.taskFailure}:{},...X.taskStartedAt?{taskStartedAt:X.taskStartedAt}:{},...X.taskCompletedAt?{taskCompletedAt:X.taskCompletedAt}:{},...X.taskPromptSummary?{taskPromptSummary:X.taskPromptSummary}:{},updatedAt:new Date().toISOString()}),q.publish(V,"review.completed",{reviewId:b.reviewId,status:M.status,findings:M.findings.length})}).catch((M)=>{g.error(`[SessionRoutes] Code review ${b.reviewId} failed:`,M)}).finally(()=>{if(qO.get(L)?.reviewId===b.reviewId)qO.delete(L)});return qO.set(L,{reviewId:b.reviewId,controller:D,completion:j}),Z.json({reviewId:b.reviewId,status:"running"},202)})})}),O.get("/:sessionId/subagents",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath"));return p(G,(N)=>Z.json({subagents:N.listSubagents().map(r0)}))}),O.post("/:sessionId/subagents/:agentId/resume",async(Z)=>{Tx(Z.req.param("agentId"));let G=z4.safeParse(await Z.req.json());if(!G.success)throw new _("Invalid subagent resume request");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=FO(N.currentRunId);if(_O(V))throw new k("Cannot resume a subagent while a parent run is active");return p(N,async(L)=>{let F=!1,D,b=(M)=>{q.publish(X,"subagent.complete",{subagentSessionId:M.id,success:M.status==="completed",status:M.status,summary:M.result?.message?.slice(0,500),type:M.subagentType,verificationVerdict:M.result?.verificationVerdict,resumedFrom:M.resumedFrom,rootAgentId:M.rootAgentId,resumeDepth:M.resumeDepth})},j;try{j=L.resumeSubagent({agentId:Z.req.param("agentId"),prompt:G.data.prompt,onEvent:(M,I)=>{jw(X,I,M)},onCompleted:(M)=>{if(F)b(M);else D=M}})}catch(M){if(M instanceof Error&&(M.message.startsWith("Cannot resume")||M.message.startsWith("Subagent cannot")))throw new k(M.message);if(M instanceof Error&&M.message.startsWith("Subagent not found"))throw new y(M.message);throw M}if(q.publish(X,"subagent.start",{subagentSessionId:j.session.id,type:j.session.subagentType,description:j.session.description,resumedFrom:j.source.id,rootAgentId:j.session.rootAgentId,resumeDepth:j.session.resumeDepth}),F=!0,D)b(D);return Z.json({source:r0(j.source),session:r0(j.session)})})})}),O.get("/:sessionId/goal",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath"));return Z.json({goal:await new x4(G.projectPath,G.id).get()})}),O.put("/:sessionId/goal",async(Z)=>{let G=f(_w,await Z.req.json());if(!G.success)throw new _("Invalid goal request");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=FO(N.currentRunId);if(_O(V))return Z.json({status:"rejected",reason:"run_active"},409);let F=G.data.permissionMode??N.permissionMode??"default";if(N.permissionMode!==F)await IO(N,F);let D=await NO(N),b=!1;try{let j=await D.value.createGoal(G.data);q.publish(X,"goal.updated",{goal:j});let M=xO(N,"",F,{goalContinuationOnly:!0,runtimeLease:D});return b=!0,await M.taskAdmissionUpdate,Z.json({status:M.status==="queued"?"queued":"running",runId:M.id,goal:j,queuePosition:N.taskQueuePosition,queueDepth:N.taskQueueDepth,maxConcurrentTasks:N.taskConcurrencyLimit},202)}finally{if(!b)D.release()}})}),O.patch("/:sessionId/goal",async(Z)=>{let G=f(Fw,await Z.req.json());if(!G.success)throw new _("Invalid goal update");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=await NO(N),L=!1;try{let F=V.value,D;if(G.data.action==="pause")D=await F.pauseGoal();else if(G.data.action==="edit")D=await F.editGoal(G.data.objective);else D=await F.resumeGoal();if(q.publish(X,"goal.updated",{goal:D}),D.status==="active"&&!_O(FO(N.currentRunId))){let b=xO(N,"","default",{goalContinuationOnly:!0,runtimeLease:V});return L=!0,await b.taskAdmissionUpdate,Z.json({status:b.status==="queued"?"queued":"running",runId:b.id,goal:D,queuePosition:N.taskQueuePosition,queueDepth:N.taskQueueDepth,maxConcurrentTasks:N.taskConcurrencyLimit},202)}return Z.json({status:D.status,goal:D})}finally{if(!L)V.release()}})}),O.delete("/:sessionId/goal",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),N=XO(G);return p(G,async(X)=>{let V=await X.clearGoal();if(V)q.publish(N,"goal.cleared",{});return Z.json({cleared:V})})}),O.post("/:sessionId/archive",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=await C.listSessionArchiveMembers(N.sessionId,N.projectPath);for(let L of X){let F=pO({sessionId:L.sessionId,projectPath:L.projectPath}),D=OO.get(m(F));if(_O(FO(D?.currentRunId)))throw new k(`Stop session ${L.sessionId} before archiving this session tree`)}for(let L of X){let F=pO({sessionId:L.sessionId,projectPath:L.projectPath}),D=OO.get(m(F));if(D)await v(D)}let V=await C.archiveSession(N.sessionId,N.projectPath);for(let L of X){let F=pO({sessionId:L.sessionId,projectPath:L.projectPath}),D=m(F);OO.delete(D),Y.delete(D),w.delete(D),q.publish(F,"session.archived",{archiveRootId:N.sessionId,archivedAt:V.archivedAt})}if(x.size===0)await KO.getInstance().disconnectAll();return Z.json({session:V,archivedSessionIds:X.map((L)=>L.sessionId)})}catch(N){if(N instanceof _||N instanceof y||N instanceof bO||N instanceof k)throw N;if(N instanceof Ax)throw new k(N.message);throw g.error("[SessionRoutes] Failed to archive session:",N),new s("Failed to archive session")}}),O.post("/:sessionId/unarchive",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=await C.listSessionArchiveMembers(N.sessionId,N.projectPath),V=await C.unarchiveSession(N.sessionId,N.projectPath),L=X.filter((F)=>F.sessionId===N.sessionId||F.archivedBySessionId===N.sessionId).map((F)=>F.sessionId);for(let F of L)q.publish({sessionId:F,projectPath:N.projectPath},"session.unarchived",{archiveRootId:N.sessionId});return Z.json({session:V,restoredSessionIds:L})}catch(N){if(N instanceof _||N instanceof y||N instanceof bO)throw N;if(N instanceof Ax)throw new k(N.message);throw g.error("[SessionRoutes] Failed to unarchive session:",N),new s("Failed to unarchive session")}}),O.delete("/:sessionId",async(Z)=>{let G=Z.req.param("sessionId"),N=Z.req.query("projectPath");try{let X=await VO(G,N),V=m(X),L=OO.get(V),F=x.get(V),D=L?.taskWorktree??await C.findSessionTaskWorktree(X.sessionId,X.projectPath),b;if(L?.currentRunId){let I=FO(L.currentRunId);if(I)k0(I),await I.completion,b=I.id}let j=qO.get(V);if(j)j.controller.abort("session-delete"),await j.completion;if(F)await F.clearGoal().catch((I)=>{g.warn("[SessionRoutes] Failed to clear session goal:",I)});if(await $.dispose(X),await C.deleteSession(X.sessionId,X.projectPath),q.publish(X,"session.deleted",{}),b)Dw(b);OO.delete(V),Y.delete(V),w.delete(V);let M=x.get(V);if(M){if(!await B.remove(V,M))throw new k("Session Runtime is still active and cannot be deleted")}if(D)try{await fO.restoreSession(D),await fO.exit({sessionId:X.sessionId,action:"remove",discardChanges:!0})}catch(I){g.warn(`[SessionRoutes] Failed to remove deleted task worktree ${X.sessionId}:`,I)}return Z.json({success:!0})}catch(X){if(g.error("[SessionRoutes] Failed to delete session:",X),X instanceof _||X instanceof y||X instanceof bO)throw X;throw new s("Failed to delete session")}}),O.get("/:sessionId/message",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N)),V=X?.messages?X.messages:await C.loadSession(N.sessionId,N.projectPath);return Z.json(Kx(V))}catch(N){if(g.error("[SessionRoutes] Failed to get messages:",N),N instanceof _||N instanceof y||N instanceof bO)throw N;throw new s("Failed to get messages")}}),O.get("/:sessionId/events",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath"));try{await C.assertSessionWritable(N.sessionId,N.projectPath)}catch(D){if(D instanceof bx)throw new k(D.message);throw D}let X=await ZO(N),V=Z.req.header("Last-Event-ID")??Z.req.query("lastEventId"),L=V?Number.parseInt(V,10):Number.NaN,F=Number.isInteger(L)?L+1:void 0;return zw(Z,async(D)=>{let j,M,I=!1,QO,HO,MO=new Promise((E)=>{HO=E}),zO=()=>{if(M!==void 0)clearInterval(M),M=void 0;j?.(),j=void 0},$O=(E)=>{if(I)return;I=!0,zO(),QO?.close(E),HO()},w0=new Set;D.onAbort($O),QO=new S0({write:async(E)=>{await D.writeSSE(E)},onFailure:(E)=>{g.warn(`[SessionRoutes] SSE egress closed for ${N.sessionId}: kind=${E.kind} pendingItems=${E.pendingItems??0} pendingBytes=${E.pendingBytes??0}`),$O(E)}}),j=q.subscribe((E)=>{if(E.sessionId!==N.sessionId||E.projectPath!==N.projectPath)return;let h=E.properties.requestId;if((E.type==="permission.asked"||E.type==="question.required"||E.type==="elicitation.required")&&typeof h==="string"){if(w0.has(h))return;w0.add(h)}if(E.type==="subagent.completion.queued")c(N,()=>EO(X)).catch((P)=>{g.error(`[SessionRoutes] Failed to wake background completion for ${X.id}:`,P)});if(E.type==="team.message.received"&&typeof E.properties.teamName==="string"&&typeof E.properties.messageId==="string"&&typeof E.properties.content==="string"&&Z4(E.properties.metadata,{messageId:E.properties.messageId,teamName:E.properties.teamName})){let P=E.properties.teamName,u=E.properties.messageId,i=E.properties.content,d=E.properties.metadata;c(N,async()=>{let a=await NO(X),hO=!1;try{let n=await a.value.enqueueSteering(i,{allowBeforeTurn:!0,messageId:u,origin:"team_message",metadata:d});if(!n.accepted)return;await new Q4(P,Ox()).markDelivered([u]),hO=n.delivery==="next_turn"}finally{a.release()}if(hO)await EO(X)}).catch((a)=>{g.error(`[SessionRoutes] Failed to deliver teammate message for ${X.id}:`,a)})}QO?.observe(Hw(E),E.seq)});try{if(D.aborted||I)return;let E=FO(X.currentRunId),h=_O(E)?await NO(X):void 0;try{let i=h?.value,d=i?.getPendingSteeringCount()??0;await QO.writeInitial({data:JSON.stringify({type:"connected",properties:{sessionId:N.sessionId,projectPath:N.projectPath,timestamp:Date.now(),status:_O(E)?E.status:"idle",runId:_O(E)?E.id:void 0,queued:d,pendingInputDelivery:d>0?i?.hasActiveTurn()?"current_turn":"next_turn":null,recovered:i?.getRecoveredSteeringCount()??0}})})}finally{h?.release()}if(D.aborted||I)return;if(F!==void 0){if(await $4.for(N.sessionId,N.projectPath).replay({onCommitted:async(d)=>{if(D.aborted||I)return;let a=Sw(d);if(a.seq===void 0)return;await QO.writeReplay({...typeof d.seq==="number"?{id:String(d.seq)}:{},data:JSON.stringify({type:a.type,...a.seq!==void 0?{seq:a.seq}:{},properties:{...a.properties,sessionId:N.sessionId,projectPath:N.projectPath}})},a.seq)}},F),D.aborted||I)return}if(QO.finishInitialization({replayed:F!==void 0}),D.aborted||I)return;if(!E&&!qO.has(m(N))){let d=(await rO.list(N.projectPath,N.sessionId)).some((a)=>a.completion===void 0)?await p(X,(a)=>rO.recoverInterrupted(N.projectPath,N.sessionId,a)):void 0;if(d)X.messages=await C.loadSession(N.sessionId,N.projectPath),await dO(X),q.publish(N,"review.completed",{reviewId:d.reviewId,status:d.status,findings:0,recovered:!0})}if(D.aborted||I)return;if(!E)await eO.recoverResponded(N.projectPath,N.sessionId);if(D.aborted||I)return;let P=E?void 0:await eO.findPending(N.projectPath,N.sessionId),u=E?.pendingPermission??(P?{permissionId:P.request.requestId,details:eO.confirmationDetails(P),resolve:()=>{return}}:void 0);if(u){w0.add(u.permissionId);let i=_4(u,!0);QO.observe({data:JSON.stringify({type:i.type,properties:{...i.properties,sessionId:N.sessionId,projectPath:N.projectPath}})})}if(D.aborted||I)return;if(EO(X).catch(async(i)=>{if(i instanceof c0){await dO(X).catch(()=>{return});let d=X.taskFailure?.code==="workspace_unavailable"?X.taskFailure:n1("workspace_unavailable");X.taskStatus="failed",X.taskStatusReason=d.message,X.taskFailure=d,q.publish(N,"session.error",{error:d.message,taskFailure:d}),q.publish(N,"session.status",{status:"error"})}g.error(`[SessionRoutes] Failed to resume pending input for ${G}:`,i)}),D.aborted||I)return;M=setInterval(()=>{if(D.aborted||I)return;QO?.offerHeartbeat({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})})},15000),await MO}finally{$O()}})}),O.post("/:sessionId/message",async(Z)=>{let G=Z.req.param("sessionId"),N=await Z.req.json(),X=f(Bw,N);if(!X.success)throw new _("Invalid message format");let{content:V,attachments:L,modelId:F,reasoningEffort:D,serviceTier:b,responseVerbosity:j,communicationStyle:M,permissionMode:I,projectPath:QO,outputSchema:HO}=X.data,MO;if(HO)try{MO=Hx(HO).schema}catch(d){throw new _(d instanceof Error?d.message:"Invalid output schema")}let zO=M;if(Buffer.byteLength(V,"utf8")>Fx)throw new _(`Message text exceeds the ${Fx}-byte limit`);let $O=F?.trim();if((L??[]).reduce((d,a)=>d+(typeof a.content==="string"?Buffer.byteLength(a.content):0),0)>xx)throw new _("Message attachments exceed the 5 MiB limit");let E=I,h=f1(V,L),P=await wO(G,QO??Z.req.query("projectPath")),u=E??P.permissionMode??"default",i=XO(P);return c(i,async()=>{let d=FO(P.currentRunId);if(_O(d)){if(MO)throw new k("Wait for the active turn to finish before setting an output schema");return p(P,async(n)=>{if($O&&!n.getModelById($O))throw new _(`Model not found: ${$O}`);if($O&&n.getCurrentModelId()!==$O)throw new k("Wait for the active turn to finish before switching models");if(D&&n.getReasoningConfiguration().selection!==D)throw new k("Wait for the active turn to finish before switching reasoning effort");if(b&&n.getServiceTierConfiguration().selection!==b)throw new k("Wait for the active turn to finish before switching service tier");if(j&&n.getResponseVerbosityConfiguration().selection!==j)throw new k("Wait for the active turn to finish before switching response verbosity");if(zO&&n.getCommunicationStyleConfiguration().selection!==zO)throw new k("Wait for the active turn to finish before switching communication style");if(E&&P.permissionMode!==E)throw new k("Wait for the active turn to finish before switching permission mode");let WO=await n.enqueueSteering(h,{allowBeforeTurn:!0});if(!WO.accepted)return Z.json({status:"rejected",reason:WO.reason??"turn_unavailable"},409);let oO=WO.messageId??W0(12),b0=WO.queued;q.publish(i,"message.created",{messageId:oO,role:"user",content:Rx(h)});let l0=WO.delivery==="next_turn"?"follow_up.queued":"steering.queued";if(q.publish(i,l0,{runId:d.id,messageId:oO,queued:b0}),WO.delivery==="next_turn"&&d.status!=="running"&&d.status!=="waiting_permission")EO(P).catch((i0)=>{g.error(`[SessionRoutes] Failed to wake queued follow-up for ${G}:`,i0)});if(WO.delivery==="next_turn")d.pendingFollowUpRequested=!0;return Z.json({runId:d.id,messageId:oO,status:WO.delivery==="next_turn"?"follow_up_queued":"steering_queued",queued:b0},202)})}if(P.permissionMode!==u)await IO(P,u);let a=await NO(P,{permissionMode:u,...zO&&!zO.includes(":")?{communicationStyle:zO}:{}}),hO=!1;try{let n=a.value;if($O&&!n.getModelById($O))throw new _(`Model not found: ${$O}`);if(D)try{n.resolveReasoningConfiguration(D,$O)}catch(GO){throw new _(GO instanceof Error?GO.message:"Invalid reasoning effort")}if(b)try{n.resolveServiceTierConfiguration(b,$O)}catch(GO){throw new _(GO instanceof Error?GO.message:"Invalid service tier")}if(j)try{n.resolveResponseVerbosityConfiguration(j,$O)}catch(GO){throw new _(GO instanceof Error?GO.message:"Invalid response verbosity")}let WO=zO?n.resolveCommunicationStyleConfiguration(zO):void 0;if(WO?.source!==void 0&&WO.source!=="built-in"&&!WO.contentSha256)throw new _("Custom communication style has no provenance");let oO=n.getCurrentModelId(),b0=n.getReasoningConfiguration(),l0=n.getServiceTierConfiguration(),i0=n.getResponseVerbosityConfiguration(),ox=n.getCommunicationStyleConfiguration(),nx=Boolean($O)&&oO!==$O,tx=Boolean(D)&&b0.selection!==D,sx=Boolean(b)&&l0.selection!==b,rx=Boolean(j)&&i0.selection!==j,ex=Boolean(zO)&&ox.selection!==zO;if(nx||tx||sx||rx||ex)await n.refresh({...$O?{modelId:$O}:{},...D?{reasoningEffort:D}:{},...b?{serviceTier:b}:{},...j?{responseVerbosity:j}:{},...zO?{communicationStyle:zO}:{}});let Nx={...$O&&P.selectedModelId!==$O?{selectedModelId:$O}:{},...D&&P.reasoningEffort!==D?{reasoningEffort:D}:{},...b&&P.serviceTier!==b?{serviceTier:b}:{},...j&&P.responseVerbosity!==j?{responseVerbosity:j}:{},...WO&&(P.communicationStyle!==zO||P.communicationStyleDigest!==WO.contentSha256)?{communicationStyle:zO,communicationStyleDigest:WO.source==="built-in"?null:WO.contentSha256}:{}};if(Object.keys(Nx).length>0)try{let GO=await C.updateSessionMetadata(P.id,P.projectPath,Nx);P.permissionMode=GO.permissionMode,P.selectedModelId=GO.selectedModelId,P.reasoningEffort=GO.reasoningEffort,P.serviceTier=GO.serviceTier,P.responseVerbosity=GO.responseVerbosity,P.communicationStyle=GO.communicationStyle,P.communicationStyleDigest=GO.communicationStyleDigest,P.updatedAt=new Date(GO.lastMessageTime),q.publish(i,"session.updated",Nx)}catch(GO){if(nx||tx||sx||rx||ex)await n.refresh({...oO?{modelId:oO}:{},reasoningEffort:b0.selection,serviceTier:l0.selection,responseVerbosity:i0.selection,communicationStyle:ox.selection}).catch((I$)=>g.error("[SessionRoutes] Failed to roll back non-durable model settings:",I$));throw GO}let A0=MO?await n.prepareInputTurn(h,{outputSchema:MO}):await n.prepareInputTurn(h);if(!A0.accepted)return Z.json({status:"rejected",reason:A0.reason},A0.reason==="queue_full"?429:409);let Wx=xO(P,h,u,{preparedInputTurn:A0,outputSchema:MO,runtimeLease:a});return hO=!0,await Wx.taskAdmissionUpdate,Z.json({runId:Wx.id,messageId:A0.messageId,status:Wx.status==="queued"?"queued":"running",queuePosition:P.taskQueuePosition,queueDepth:P.taskQueueDepth,maxConcurrentTasks:P.taskConcurrencyLimit},202)}finally{if(!hO)a.release()}})}),O.post("/:sessionId/side-question",async(Z)=>{let G=Z.req.param("sessionId"),N=f(B4,await Z.req.json());if(!N.success)throw new _("Invalid side conversation request");let X=await wO(G,N.data.projectPath??Z.req.query("projectPath"));return p(X,async(V)=>{let L=await V.askSideQuestion(N.data.question,{signal:Z.req.raw.signal});return Z.json({...L,...V.getCurrentModelId()?{modelId:V.getCurrentModelId()}:{}})})}),O.post("/:sessionId/shell",async(Z)=>{let G=Z.req.param("sessionId"),N=f(V4,await Z.req.json());if(!N.success)throw new _("Invalid user shell command");let X=await wO(G,N.data.projectPath??Z.req.query("projectPath")),V=XO(X),L=m(V);return c(V,async()=>{if(mO.has(L))throw new k("A user shell command is already running in this Session");let F=await NO(X),D=F.value,b=new AbortController,j,M=new Promise((I)=>{j=I});mO.set(L,{controller:b,completion:M});try{let I=await D.executeUserShellCommand(N.data.command,{signal:b.signal});X.messages=await C.loadSession(X.id,X.projectPath),X.updatedAt=new Date;let QO=FO(X.currentRunId);if(I.delivery==="next_turn"&&_O(QO))QO.pendingFollowUpRequested=!0;return Z.json({executionId:I.executionId,messageId:I.messageId,record:I.record,auxiliary:I.auxiliary,...I.delivery?{delivery:I.delivery}:{},...I.queued!==void 0?{queued:I.queued}:{}})}finally{mO.delete(L),j(),F.release()}})}),O.post("/:sessionId/abort",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N));if(X?.currentRunId){let F=FO(X.currentRunId);if(F)k0(F),await F.completion}let V=mO.get(m(N));if(V)V.controller.abort("user-cancel"),await V.completion;let L=qO.get(m(N));if(L)L.controller.abort("user-cancel"),await L.completion;return Z.json({success:!0})}),O.get("/:sessionId/status",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N)),V=qO.get(m(N));if(V)return Z.json({sessionId:G,projectPath:N.projectPath,reviewId:V.reviewId,status:"reviewing"});if(!X?.currentRunId)return Z.json({sessionId:G,projectPath:N.projectPath,status:"idle"});let L=FO(X.currentRunId);return Z.json({sessionId:G,projectPath:N.projectPath,runId:X.currentRunId,status:L?.status==="attention_required"?"idle":L?.status??"idle"})}),{app:O,dispatchTask:LO,retryTask:UO,updateTask:cx,getTaskDiff:Jx,deliverTask:d0,recoverQueuedTasks:Yx,getRuntimeResidencyStats:()=>B.getStats(),getCoordinationStats:()=>({messageSubmissions:J.getStats(),taskDeliveries:K.getStats()}),shutdown:(Z="server-shutdown")=>{if(U)return U;return A.close(Z),clearInterval(H),U=(async()=>{let G,N=async(D)=>{let b=await Promise.allSettled(D);for(let j of b)if(j.status==="rejected")G??=j.reason},X=new Set,V=()=>{for(let D of CO.values()){if(D.completion)X.add(D.completion);if(_O(D))k0(D,Z)}for(let D of mO.values())D.controller.abort(Z),X.add(D.completion);for(let D of qO.values())D.controller.abort(Z),X.add(D.completion)},L=A.waitForIdle(),F=!1;L.then(()=>{F=!0});while(!F)V(),await Promise.race([L,new Promise((D)=>setImmediate(D))]);if(await L,V(),await N([...X]),await N([...w.values()]),V(),await N([...X]),await N([B.disposeAll()]),x.clear(),await N([...Q.values()]),await N([$.disposeAll()]),await N([KO.getInstance().disconnectAll()]),w.clear(),Q.clear(),Y.clear(),OO.clear(),z0===EO)z0=void 0;if(G!==void 0)throw G})(),U}}};async function Mw(O,x,$,w,Q,Y={}){let{abortController:J,sessionId:K,id:S}=O,B=Y.preparedInputTurn?.messageId??W0(12),H=Y.pendingInputOnly===!0||Y.preparedInputTurn?.mode==="pending"||Y.goalContinuationOnly===!0?void 0:W0(12),U=Y.runtimeLease,T,c,l=XO(x),JO=async(p)=>{let v=p.metadata?.recoveryAttention;if(!v||!T)return!1;if(Y.preparedInputTurn)await T.finishTurn(Y.preparedInputTurn.handle,{preserveStartupRecovery:!0,outcome:{status:"aborted",cause:"failed",turnsCount:0,toolCallsCount:0,durationMs:0}}).catch(()=>{return});let ZO=`Turn recovery requires attention: ${v.reason}`,wO=await T.setTaskStatus("interrupted",ZO).catch(()=>{return});if(wO)O0(x,wO);else x.taskStatus="interrupted",x.taskStatusReason=ZO,x.taskCompletedAt=void 0;return O.status="attention_required",R("session.status",{status:"idle"}),!0},R=(p,v)=>{q.publish(l,p,v)},NO=async()=>{let p=String(J.signal.reason||"Task run cancelled");if(x.taskIsolation){if(!U)U=await Q(x).catch(()=>{return});let v=T??U?.value;if(p==="user-cancel")await v?.discardPendingInput().catch((wO)=>{g.warn(`[SessionRoutes] Failed to discard cancelled input for ${x.id}:`,wO)});let ZO=await v?.setTaskStatus("cancelled",p).catch(()=>{return});if(ZO)O0(x,ZO);else await dO(x).catch(()=>{return})}x.taskStatus="cancelled",x.taskStatusReason=p,x.taskCompletedAt??=new Date().toISOString()};try{if(Y.taskAdmission){if(await Y.taskAdmission.ready,await O.taskAdmissionUpdate,J.signal.aborted)throw Error(String(J.signal.reason||"Task run cancelled"))}if(x.taskStatus="running",x.taskStatusReason=void 0,x.taskStartedAt=new Date().toISOString(),x.taskCompletedAt=void 0,!Y.pendingInputOnly&&!Y.goalContinuationOnly)R("message.created",{messageId:B,role:"user",content:Rx($)});if(R("session.status",{status:"running"}),H)R("message.created",{messageId:H,role:"assistant",content:""});U??=await Q(x),T=U.value;let p=T,v=Boolean(Y.outputSchema??p.getPendingSteeringMessages().find((z)=>z.outputSchema)?.outputSchema);c=await N4.createWithRuntime(p,{sessionId:K,...x.taskWorktree?{toolBlacklist:["EnterWorktree","ExitWorktree"]}:{}});let ZO=async(z)=>{let UO=z.interactionRequestId??W0(12),cx=300000;O.status="waiting_permission";let Jx=new Promise((EO)=>{let Yx=setTimeout(()=>{g.warn(`[SessionRoutes] Permission ${UO} timed out after 300000ms`),R("permission.timeout",{requestId:UO}),EO({approved:!1,reason:"timeout"})},300000);O.pendingPermission={permissionId:UO,resolve:(ax)=>{clearTimeout(Yx),EO(ax)},details:z}}),H0=O.pendingPermission;if(!H0)throw Error("Permission request was not registered");let d0=_4(H0);R(d0.type,d0.properties),g.info(`[SessionRoutes] Permission request created: ${UO}, runId: ${S}`);let v0=await Jx;if(g.info(`[SessionRoutes] Permission response received: ${UO}, approved: ${v0.approved}`),!J.signal.aborted)O.status="running";if(O.pendingPermission===H0)O.pendingPermission=void 0;return R("interaction.resolved",{requestId:UO}),v0},IO={messages:await C.loadSessionModelContext(x.id,x.projectPath),userId:"web-user",sessionId:K,workspaceRoot:x.projectPath,signal:J.signal,permissionMode:w,onPermissionModeChange:async(z)=>{x.permissionMode=z,x.updatedAt=new Date,R("session.updated",{permissionMode:z})},...x.taskWorktree?{worktreeActive:!0}:{},confirmationHandler:{requestConfirmation:ZO}},xO=()=>{if(!H)H=W0(12),R("message.created",{messageId:H,role:"assistant",content:""});return H},aO=async(z)=>{switch(z.kind){case"content_delta":if(v)break;R("message.delta",{messageId:xO(),delta:z.delta});break;case"structured_output":R("structured.output",{messageId:xO(),output:z.output,schemaDigest:z.schemaDigest});break;case"thinking_delta":R("thinking.delta",{messageId:xO(),delta:z.delta});break;case"tool_start":if("function"in z.toolCall){if(z.toolCall.function.name===X0)break;R("tool.start",{messageId:xO(),toolName:z.toolCall.function.name,toolCallId:z.toolCall.id,arguments:z.toolCall.function.arguments,toolKind:z.toolKind})}break;case"tool_result":if("function"in z.toolCall){if(z.toolCall.function.name===X0)break;R("tool.result",{messageId:xO(),toolName:z.toolCall.function.name,toolCallId:z.toolCall.id,success:z.result.success,summary:z.result.metadata?.summary,output:h0(y0(m0(z.toolCall.function.name,z.result),P0)),metadata:f0(z.toolCall.function.name,z.result.metadata)})}break;case"tool_progress":if("function"in z.toolCall){if(z.toolCall.function.name===X0)break;R("tool.progress",{messageId:xO(),toolName:z.toolCall.function.name,toolCallId:z.toolCall.id,...z.update})}break;case"token_usage":R("token.usage",{...z.usage});break;case"turn_start":R("turn.started",{turn:z.turn,maxTurns:z.maxTurns});break;case"turn_recovery":R("turn.recovery",{assessment:z.assessment});break;case"provider_admission":R("provider.admission",{phase:z.phase,requestClass:z.requestClass,resource:z.resource,scope:z.scope,reason:z.reason,queuePosition:z.queuePosition,queueDepth:z.queueDepth,inFlight:z.inFlight,limit:z.limit,waitMs:z.waitMs,maxWaitMs:z.maxWaitMs,recoveryRemainingMs:z.recoveryRemainingMs});break;case"provider_circuit":R("provider.circuit",{phase:z.phase,reason:z.reason,statusCode:z.statusCode,retryAfterMs:z.retryAfterMs,nextProbeAt:z.nextProbeAt,openDurationMs:z.openDurationMs,sampleCount:z.sampleCount,failureCount:z.failureCount,recoveryRemainingMs:z.recoveryRemainingMs});break;case"provider_retry":R("provider.retry",{phase:z.phase,attempt:z.attempt,maxRetries:z.maxRetries,reason:z.reason,statusCode:z.statusCode,delayMs:z.delayMs,nextRetryAt:z.nextRetryAt,mode:z.mode,recoveryBudgetMs:z.recoveryBudgetMs,recoveryElapsedMs:z.recoveryElapsedMs,recoveryRemainingMs:z.recoveryRemainingMs,exhaustedBy:z.exhaustedBy});break;case"provider_stall":R("provider.stall",{phase:z.phase,stallCount:z.stallCount,durationMs:z.durationMs,warningAfterMs:z.warningAfterMs,timeoutMs:z.timeoutMs,outputStarted:z.outputStarted});break;case"action_stationarity":R("action.stationarity",{phase:z.phase,toolName:z.toolName,runLength:z.runLength,nudgeThreshold:z.nudgeThreshold,haltThreshold:z.haltThreshold,progressAware:z.progressAware});break;case"mcp_catalog_changed":R("mcp.catalog.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,added:z.added,removed:z.removed,updated:z.updated});break;case"mcp_content_changed":R("mcp.content.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,contentKind:z.contentKind,added:z.added,removed:z.removed,updated:z.updated});break;case"mcp_resource_updated":R("mcp.resource.updated",{messageId:xO(),revision:z.revision,serverName:z.serverName,uri:z.uri});break;case"mcp_connection_changed":R("mcp.connection.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,phase:z.phase,reason:z.reason,attempt:z.attempt,maxAttempts:z.maxAttempts,nextRetryAt:z.nextRetryAt,error:z.error});break;case"mcp_log":R("mcp.log",{messageId:xO(),revision:z.revision,serverName:z.serverName,level:z.level,logger:z.logger,message:z.message,projectedBytes:z.projectedBytes,dataSha256:z.dataSha256,truncated:z.truncated,detailsOmitted:z.detailsOmitted,timestamp:z.timestamp,synthetic:z.synthetic});break;case"mcp_instructions_changed":R("mcp.instructions.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,action:z.action,reason:z.reason,text:z.text,sourceBytes:z.sourceBytes,projectedBytes:z.projectedBytes,sha256:z.sha256,truncated:z.truncated,detailsOmitted:z.detailsOmitted});break;case"mcp_task_changed":R("mcp.task.changed",{messageId:xO(),revision:z.revision,taskId:z.taskId,serverName:z.serverName,toolName:z.toolName,status:z.status,statusMessage:z.statusMessage,createdAt:z.createdAt,updatedAt:z.updatedAt,completedAt:z.completedAt,hasResult:z.hasResult,error:z.error});break;case"project_rules_loaded":R("project.rules.loaded",{messageId:xO(),files:z.files,triggerPaths:z.triggerPaths,blockedWrite:z.blockedWrite});break;case"steering_applied":R("steering.applied",{runId:S,messageIds:z.messageIds,count:z.count,recovered:z.recovered,delivery:z.delivery,queued:p.getPendingSteeringCount()});break;case"follow_up_started":{if(H)R("message.complete",{messageId:H}),H=void 0;for(let UO of z.messages){if(!UO.recovered||UO.persisted)continue;R("message.created",{messageId:UO.id,role:"user",content:Rx(UO.content),recovered:!0})}R("follow_up.started",{runId:S,queued:z.queued,recovered:z.recovered}),xO();break}case"goal_updated":R("goal.updated",{goal:z.goal});break;case"goal_continuation_started":R("goal.continuation.started",{goal:z.goal,continuation:z.continuation,...z.prematureStopPattern?{prematureStopPattern:z.prematureStopPattern}:{},...z.prematureStopCount!==void 0?{prematureStopCount:z.prematureStopCount}:{}}),xO();break;case"compaction":R(z.phase==="start"?"compaction.started":"compaction.completed",{...z.reason?{reason:z.reason}:{},...z.strategy?{strategy:z.strategy}:{},...z.outcome?{outcome:z.outcome}:{},...z.preTokens!==void 0?{preTokens:z.preTokens}:{},...z.preTokenSource?{preTokenSource:z.preTokenSource}:{},...z.estimatedPendingTokens!==void 0?{estimatedPendingTokens:z.estimatedPendingTokens}:{},...z.postTokens!==void 0?{postTokens:z.postTokens}:{},...z.sampleAttempts!==void 0?{sampleAttempts:z.sampleAttempts}:{},...z.inputReductions!==void 0?{inputReductions:z.inputReductions}:{},...z.messagesOmitted!==void 0?{messagesOmitted:z.messagesOmitted}:{},...z.filesOmitted!==void 0?{filesOmitted:z.filesOmitted}:{},...z.imagesOmitted!==void 0?{imagesOmitted:z.imagesOmitted}:{},...z.fallbackTargetTokens!==void 0?{fallbackTargetTokens:z.fallbackTargetTokens}:{},...z.fallbackMessagesOmitted!==void 0?{fallbackMessagesOmitted:z.fallbackMessagesOmitted}:{},...z.fallbackMessagesTruncated!==void 0?{fallbackMessagesTruncated:z.fallbackMessagesTruncated}:{},...z.failureReason?{failureReason:z.failureReason}:{}});break;case"model_fallback":R("model.fallback",{});break;case"task_update":R("task.updated",{tasks:z.tasks});break;default:break}},LO=await Sx(c.chatStream($,IO,{stream:!0,pendingInputOnly:Y.pendingInputOnly,preparedInputTurn:Y.preparedInputTurn,goalContinuationOnly:Y.goalContinuationOnly,outputSchema:Y.outputSchema,taskAdmission:Y.taskAdmission}),aO);if(await JO(LO))return;if(!LO.success)throw Error(LO.error?.message??"Agent run failed");for(let z=0;z<20;z++){let UO=O.pendingFollowUpRequested===!0;if(O.pendingFollowUpRequested=!1,p.getPendingSteeringCount()===0){if(!UO)break;continue}if(J.signal.aborted)break;if(LO=await Sx(c.chatStream("",IO,{stream:!0,pendingInputOnly:!0,taskAdmission:Y.taskAdmission}),aO),await JO(LO))return;if(!LO.success)throw Error(LO.error?.message??"Agent follow-up failed")}if(x.messages=await C.loadSession(x.id,x.projectPath),x.updatedAt=new Date,await dO(x),J.signal.aborted||O.status==="cancelled"){await NO(),R("session.status",{status:"idle"});return}if(H)R("message.complete",{messageId:H});R("thinking.completed",{}),O.status="completed",x.taskStatus="completed",x.taskCompletedAt??=new Date().toISOString(),R("session.completed",{runId:S,outputTruncated:LO.metadata?.outputTruncated??!1}),R("session.status",{status:"idle"})}catch(p){if(T&&Y.preparedInputTurn)await(T.getTurnRecoveryAssessment().state==="requires_attention"?T.finishTurn(Y.preparedInputTurn.handle,{preserveStartupRecovery:!0}):T.finishTurn(Y.preparedInputTurn.handle)).catch(()=>{return});if(J.signal.aborted||O.status==="cancelled"){k0(O,"runtime-abort"),await NO(),R("session.status",{status:"idle"});return}await dO(x).catch(()=>{return}),g.error("[SessionRoutes] Agent execution error:",p),O.status="failed",x.taskStatus="failed",x.taskCompletedAt??=new Date().toISOString();let v=e0(p);if(!x.taskFailure){let ZO=T?await T.setTaskStatus("failed",p).catch(()=>{return}):await C.updateSessionMetadata(x.id,x.projectPath,{taskStatus:"failed",taskStatusReason:v.message,taskFailure:v,taskCompletedAt:x.taskCompletedAt,taskOwnerPid:null,taskQueuePosition:null,taskQueueDepth:null}).catch(()=>{return});if(ZO)O0(x,ZO)}x.taskStatusReason??=v.message,x.taskFailure??=v,R("session.error",{error:x.taskFailure.message,taskFailure:x.taskFailure}),R("session.status",{status:"error"})}finally{if(Y.taskAdmission?.release(),Y.taskAdmission){let p=gO.getStats();R("task.status",{taskStatus:x.taskStatus,...x.taskStatusReason?{taskStatusReason:x.taskStatusReason}:{},...x.taskFailure?{taskFailure:x.taskFailure}:{},...x.taskStartedAt?{taskStartedAt:x.taskStartedAt}:{},...x.taskCompletedAt?{taskCompletedAt:x.taskCompletedAt}:{},...x.taskDiffStat?{taskDiffStat:x.taskDiffStat}:{},taskQueueDepth:p.queued,taskConcurrencyLimit:p.maxConcurrent,taskInFlight:p.inFlight,taskAdmissionPaused:p.paused,updatedAt:new Date().toISOString()})}if(await c?.destroy().catch(()=>{return}),U?.release(),O.disposeRuntimeOnSettle&&Y.disposeRuntime)await Y.disposeRuntime(x,T).catch((p)=>{g.warn(`[SessionRoutes] Failed to dispose terminal task runtime ${x.id}:`,p)});Lw(O)}}async function L4(O,x,$){g.info(`[SessionRoutes] Looking for permission ${x} in session ${O.sessionId}`),g.info(`[SessionRoutes] Active runs: ${CO.size}`);for(let[Y,J]of CO.entries())if(g.info(`[SessionRoutes] Checking run ${Y}: sessionId=${J.sessionId}, projectPath=${J.projectPath}, pendingPermission=${J.pendingPermission?.permissionId}`),J.sessionId===O.sessionId&&J.projectPath===O.projectPath&&J.pendingPermission?.permissionId===x){if(J.pendingPermission.details.interactionRequestId)await eO.respond(O.projectPath,O.sessionId,x,$);return J.pendingPermission.resolve($),g.info(`[SessionRoutes] Permission ${x} responded, runId: ${J.id}`),!0}let w=await eO.findPending(O.projectPath,O.sessionId);if(!w||w.request.requestId!==x)return g.error(`[SessionRoutes] Permission not found: ${x}`),!1;await eO.respondAndRecover(O.projectPath,O.sessionId,x,$);let Q=OO.get(m(O));if(!Q){let Y=await C.findSessionMetadata(O.sessionId,O.projectPath);if(!Y)return!1;let[J,K]=await Promise.all([C.loadSession(O.sessionId,O.projectPath),C.findSessionTaskWorktree(O.sessionId,O.projectPath)]);Q=E0(Y,J,K),OO.set(m(O),Q)}else await dO(Q);if(q.publish(O,"interaction.resolved",{requestId:x}),z0)z0(Q).catch((Y)=>{g.error(`[SessionRoutes] Failed to resume recovered interaction ${x}:`,Y)});return!0}var Cx=t("Service"),Rw=W.Object({approved:W.Boolean(),remember:W.Optional(W.Boolean()),scope:W.Optional(e(["once","session","project"])),targetMode:W.Optional(e(["default","autoEdit","plan","yolo"])),feedback:W.Optional(W.String({maxLength:4000})),answers:W.Optional(W.Record(W.String({maxLength:80}),W.Union([W.String({maxLength:4000}),W.Array(W.String({maxLength:1000}),{maxItems:4})]),{maxProperties:4})),elicitation:W.Optional(W.Object({action:e(["accept","decline","cancel"]),content:W.Optional(W.Record(W.String(),W.Union([W.String({maxLength:4000}),W.Number(),W.Boolean(),W.Array(W.String({maxLength:1000}),{maxItems:100})]),{maxProperties:32}))}))}),D4=()=>{let O=new Tw;return O.post("/:permissionId",async(x)=>{let $=x.req.param("permissionId"),w=x.req.query("sessionId"),Q=x.req.query("projectPath");Cx.info(`[PermissionRoutes] Received permission response: permissionId=${$}, sessionId=${w}`);try{let Y=await x.req.json(),J=f(Rw,Y);if(!J.success)throw new _("Invalid permission response format");let{approved:K,remember:S,scope:B,targetMode:A,feedback:H,answers:U,elicitation:T}=J.data;if(!w)throw new _("sessionId query parameter is required");let c=await VO(w,Q);if(!await L4(c,$,{approved:K,reason:H,scope:B,targetMode:A,feedback:H,answers:U,elicitation:T}))throw new y("Permission request",$);return Cx.info(`[PermissionRoutes] Permission ${$} ${K?"approved":"denied"}`),x.json({success:!0,approved:K,remember:S})}catch(Y){if(Cx.error("[PermissionRoutes] Failed to respond to permission:",Y),Y instanceof _||Y instanceof bO||Y instanceof y||Y instanceof r)throw Y;throw Y}}),O};import H4 from"node:path";import{Hono as qw}from"hono";var Cw=W.Object({projectPath:W.String({minLength:1}),enabled:W.Boolean(),scope:W.Optional(e(["local","project","global"]))}),Iw=W.Object({projectPath:W.String({minLength:1})}),Ew=W.Object({projectPath:W.String({minLength:1}),source:W.String({minLength:1}),trust:W.Literal(!0),ref:W.Optional(W.String({minLength:1}))}),kw=W.Object({projectPath:W.String({minLength:1}),trust:W.Literal(!0)}),fw=W.Object({projectPath:W.String({minLength:1}),confirm:W.Literal(!0)}),Pw=W.Object({projectPath:W.String({minLength:1}),source:W.String({minLength:1}),ref:W.Optional(W.String({minLength:1}))}),b4=W.Object({projectPath:W.String({minLength:1}),confirm:W.Optional(W.Literal(!0))}),yw=W.Object({projectPath:W.String({minLength:1}),scope:W.Optional(e(["local","project","global"])),policy:W.Object({restrictToAllowedSources:W.Boolean(),requireGitCommitSha:W.Boolean(),allowedGitHosts:W.Array(W.String()),allowedMarketplaces:W.Array(W.String()),allowedLocalRoots:W.Array(W.String())})});function SO(O){if(!O||!H4.isAbsolute(O))throw new _("projectPath must be absolute");return H4.resolve(O)}async function A4(O){let[x,$]=await Promise.all([TO(O),M0.getInstance().loadWorkspacePluginSettingsResolution(O)]);return x.plugins.getAll().map((w)=>({name:w.manifest.name,description:w.manifest.description,version:w.manifest.version,source:w.source,enabled:w.status==="active",status:w.status,commands:w.commands.length,skills:w.skills.length,agents:w.agents.length,hooks:w.hooks?Object.values(w.hooks).reduce((Q,Y)=>Q+(Array.isArray(Y)?Y.length:0),0):0,mcpServers:Object.keys(w.mcpServers??{}).length,configurable:w.source!=="cli",managed:w.installation!==void 0,marketplace:w.installation?.source.type==="marketplace"?w.installation.source.marketplace:void 0,revision:w.installation?.revision,installedAt:w.installation?.installedAt,updatedAt:w.installation?.updatedAt,compatibilityIssues:w.compatibilityIssues??[],effectiveScope:w.source==="cli"?"invocation":$.settings[w.manifest.name]?.effectiveScope??"default",settingLayers:w.source==="cli"?{invocation:!0}:$.settings[w.manifest.name]?.layers??{}}))}async function mw(){let O=S4(),[x,$]=await Promise.all([O.listCatalogs(),O.listInstallationRecords()]),w=new Map($.map((Q)=>[Q.name,Q]));return x.map(({marketplace:Q,manifest:Y})=>({name:Q.name,description:Y.description??Y.metadata?.description??"",sourceType:Q.source.type,revision:Q.revision,updatedAt:Q.updatedAt,plugins:Y.plugins.map((J)=>{let K=w.get(J.name);return{name:J.name,description:J.description??"",version:J.version,category:J.category,tags:J.tags??[],installed:K!==void 0,installedVersion:K?.version}})}))}function G0(O,x){if(!O.success)throw new _(O.error??x)}var f4=()=>{let O=new qw;return O.get("/",async(x)=>{let $=SO(x.req.query("projectPath"));return x.json(await A4($))}),O.post("/refresh",async(x)=>{let $=f(Iw,await x.req.json());if(!$.success)throw new _("Invalid plugin refresh request");let w=SO($.data.projectPath),Q=await M4(w);return x.json({plugins:await A4(w),errors:Q.discovery.errors.map((Y)=>({code:Y.code??"LOAD_ERROR",error:Y.error}))})}),O.get("/catalog",async(x)=>{return SO(x.req.query("projectPath")),x.json(await mw())}),O.get("/policy",async(x)=>{let $=SO(x.req.query("projectPath")),w=await M0.getInstance().loadWorkspacePluginSourcePolicy($);return x.json({policy:w,environmentRequiresSha:process.env.BLADE_PLUGIN_REQUIRE_SHA==="1"||process.env.BLADE_PLUGIN_REQUIRE_SHA==="true"})}),O.post("/policy",async(x)=>{let $=f(yw,await x.req.json());if(!$.success)throw new _("Invalid plugin source policy request");let w=SO($.data.projectPath),Q=await T4(w,$.data.policy,$.data.scope??"global");return x.json({policy:Q})}),O.post("/install",async(x)=>{let $=f(Ew,await x.req.json());if(!$.success)throw new _("Invalid plugin install request; explicit source trust is required");let w=SO($.data.projectPath),{result:Q}=await R4(w,$.data.source,{trusted:$.data.trust,ref:$.data.ref});return G0(Q,"Plugin installation failed"),x.json({name:Q.pluginName,version:Q.manifest?.version,revision:Q.installation?.revision,changed:Q.changed,installedDependencies:Q.installedDependencies??[]})}),O.post("/marketplaces",async(x)=>{let $=f(Pw,await x.req.json());if(!$.success)throw new _("Invalid marketplace add request");let w=SO($.data.projectPath),Q=await I4(w,$.data.source,$.data.ref);return G0(Q,"Marketplace installation failed"),x.json({name:Q.marketplace?.name,plugins:Q.manifest?.plugins.length??0,revision:Q.marketplace?.revision,changed:Q.changed})}),O.post("/marketplaces/:name/refresh",async(x)=>{let $=f(b4,await x.req.json());if(!$.success)throw new _("Invalid marketplace refresh request");let w=await E4(SO($.data.projectPath),x.req.param("name"));return G0(w,"Marketplace refresh failed"),x.json({name:w.marketplace?.name,plugins:w.manifest?.plugins.length??0,revision:w.marketplace?.revision,changed:w.changed})}),O.post("/marketplaces/:name/remove",async(x)=>{let $=f(b4,await x.req.json());if(!$.success||$.data.confirm!==!0)throw new _("Invalid marketplace removal request; explicit confirmation is required");SO($.data.projectPath);let w=await k4(x.req.param("name"),!0);return G0(w,"Marketplace removal failed"),x.json({name:w.marketplace?.name,removed:!0})}),O.post("/:name/update",async(x)=>{let $=f(kw,await x.req.json());if(!$.success)throw new _("Invalid plugin update request; explicit source trust is required");let w=SO($.data.projectPath),{result:Q}=await q4(w,x.req.param("name"),{trusted:$.data.trust});return G0(Q,"Plugin update failed"),x.json({name:Q.pluginName,version:Q.manifest?.version,revision:Q.installation?.revision,changed:Q.changed,updatedDependencies:Q.updatedDependencies??[]})}),O.post("/:name/uninstall",async(x)=>{let $=f(fw,await x.req.json());if(!$.success)throw new _("Invalid plugin uninstall request; explicit confirmation is required");let w=SO($.data.projectPath),{result:Q}=await C4(w,x.req.param("name"),$.data.confirm);return G0(Q,"Plugin uninstall failed"),x.json({name:Q.pluginName,removed:!0})}),O.post("/:name/state",async(x)=>{let $=f(Cw,await x.req.json());if(!$.success)throw new _("Invalid plugin state request");let w=SO($.data.projectPath),Q=x.req.param("name"),J=(await TO(w)).plugins.get(Q);if(!J)throw new y("Plugin",Q);if(J.source==="cli")throw new _(`Plugin "${Q}" was loaded with --plugin-dir and is invocation-scoped`);let K=await j4(w,Q,$.data.enabled,$.data.scope??"local");return x.json(K)}),O};import{Hono as dw}from"hono";import{execFile as hw}from"node:child_process";import gw from"node:path";var kx="__BLADE_DIRECTORY_PICKER_CANCELLED__",uw=900000;function pw(O,x){return new Promise(($)=>{hw(O,[...x],{timeout:uw,maxBuffer:65536,windowsHide:!0},(w,Q,Y)=>{let J=w?.code;$({stdout:Q,stderr:Y,exitCode:typeof J==="number"?J:w?1:0,...typeof J==="string"?{errorCode:J}:{}})})})}function Ix(O){let x=O.replace(/[\r\n]+$/,"");if(!x||x===kx)return{cancelled:!0};if(!gw.isAbsolute(x))throw Error("The folder picker returned an invalid path");return{cancelled:!1,path:x}}function Ex(O){return O.exitCode!==0||Boolean(O.errorCode)}class P4{platform;runCommand;activeSelection=null;constructor(O={}){this.platform=O.platform??process.platform,this.runCommand=O.runCommand??pw}pick(){if(this.activeSelection)return this.activeSelection;let O=this.pickForPlatform().finally(()=>{this.activeSelection=null});return this.activeSelection=O,O}async pickForPlatform(){switch(this.platform){case"darwin":return this.pickOnMac();case"win32":return this.pickOnWindows();case"linux":return this.pickOnLinux();default:throw Error("Native folder selection is unavailable on this system")}}async pickOnMac(){let O=["try",'set selectedFolder to choose folder with prompt "Choose a project folder"',"return POSIX path of selectedFolder","on error number -128",`return "${kx}"`,"end try"].join(`
|
|
8
|
-
`),x=await this.runCommand("osascript",["-e",O]);if(Ex(x))throw Error("Unable to open the macOS folder picker");return Ix(x.stdout)}async pickOnWindows(){let O=["Add-Type -AssemblyName System.Windows.Forms","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog",'$dialog.Description = "Choose a project folder"',"$dialog.ShowNewFolderButton = $true","if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {"," [Console]::Out.Write($dialog.SelectedPath)","} else {",` [Console]::Out.Write("${kx}")`,"}"].join("; "),x=await this.runCommand("powershell.exe",["-NoProfile","-STA","-Command",O]);if(Ex(x))throw Error("Unable to open the Windows folder picker");return Ix(x.stdout)}async pickOnLinux(){let O=[{command:"zenity",args:["--file-selection","--directory","--title=Choose a project folder"]},{command:"kdialog",args:["--getexistingdirectory",".","--title","Choose a project folder"]}];for(let x of O){let $=await this.runCommand(x.command,x.args);if($.errorCode==="ENOENT")continue;if($.exitCode===1&&!$.stdout.trim()&&!$.stderr.trim())return{cancelled:!0};if(Ex($))throw Error("Unable to open the Linux folder picker");return Ix($.stdout)}throw Error("Install zenity or kdialog to use native folder selection")}}var y4=new P4;var vw=W.Object({path:W.String({minLength:1})});function lw(O){if(!O)return!1;if(O==="tauri://localhost"||O==="http://tauri.localhost")return!0;try{let x=new URL(O).hostname;return x==="localhost"||x==="127.0.0.1"||x==="::1"||x==="[::1]"}catch{return!1}}var m4=(O={})=>{let x=new dw,$=O.pickDirectory??(()=>y4.pick()),w=O.allowDirectoryPickerRequest??lw;return x.get("/",async(Q)=>{return Q.json(await wx.list(o()))}),x.post("/",async(Q)=>{let Y;try{Y=await Q.req.json()}catch{throw new _("A valid JSON body is required")}let J=f(vw,Y);if(!J.success)throw new _("A project path is required");try{let K=await wx.bind(J.data.path,o());return Q.json(K,201)}catch(K){throw new _(K instanceof Error?K.message:"Failed to bind project")}}),x.post("/pick",async(Q)=>{if(!w(Q.req.header("Origin")))throw new r("LOCAL_ACCESS_REQUIRED","Folder selection is only available from this machine",403);try{return Q.json(await $())}catch(Y){throw new _(Y instanceof Error?Y.message:"Failed to select a folder")}}),x.delete("/",async(Q)=>{let Y=Q.req.query("path");if(!Y)throw new _("A project path is required");try{let J=await wx.unbind(Y);return Q.json({success:!0,removed:J})}catch(J){throw new _(J instanceof Error?J.message:"Failed to unbind project")}}),x};import{Hono as iw}from"hono";var h4=t("Service"),d4=()=>{let O=new iw;return O.get("/",async(x)=>{try{let $=await u4();return x.json($)}catch($){return h4.error("[ProviderRoutes] Failed to list providers:",$),x.json([])}}),O.get("/:provider/models",async(x)=>{let $=x.req.param("provider");try{let w=await p4($);return x.json(w)}catch(w){return h4.error("[ProviderRoutes] Failed to list models:",w),x.json([])}}),O.put("/:provider/credential",async(x)=>{let $=x.req.param("provider"),w=await x.req.json();if(!w.apiKey?.trim())throw new _("apiKey is required");return await nO().setApiKey($,w.apiKey.trim()),x.json({success:!0})}),O.delete("/:provider/credential",async(x)=>{return await nO().clearCredential(x.req.param("provider")),x.json({success:!0})}),O.put("/:provider",async(x)=>{let $=x.req.param("provider"),w=YO(),Q=w?.modelProviders[$];if(!w||!Q)throw new y("Model provider",$);let Y=await x.req.json();if(!Y.name||!Y.baseUrl||!Y.wireApi)throw new _("name, baseUrl and wireApi are required");let J="apiKeyEnv"in Y?Y.apiKeyEnv?.trim():Q.apiKeyEnv,K={name:Y.name,baseUrl:Y.baseUrl,wireApi:Y.wireApi,...J?{apiKeyEnv:J}:{}},S=nO(),B=Y.apiKey?.trim()?await S.credentials.read($):void 0;if(Y.apiKey?.trim())await S.setApiKey($,Y.apiKey.trim());try{return await AO().updateModelProvider($,K),x.json({success:!0})}catch(A){if(Y.apiKey?.trim())if(B)await S.credentials.modify($,async()=>B);else await S.credentials.delete($);if(A instanceof Error&&(A.message.includes("modelProviders.")||A.message.includes("built-in provider")))throw new _(A.message);throw A}}),O.delete("/:provider",async(x)=>{let $=x.req.param("provider");if(!YO()?.modelProviders[$])throw new y("Model provider",$);let Q=x.req.query("removeModels");if(Q!==void 0&&Q!=="true"&&Q!=="false")throw new _("removeModels must be true or false");try{let Y=await AO().removeModelProvider($,{removeModels:Q==="true"});return x.json({success:!0,...Y})}catch(Y){if(Y instanceof Error&&(Y.message.includes("still referenced")||Y.message.includes("owns the only model")))throw new k(Y.message);throw Y}}),O.post("/:provider/probe",async(x)=>{let $=x.req.param("provider"),w=YO();if(!w?.modelProviders[$])throw new y("Model provider",$);let Q=await x.req.json().catch(()=>({})),Y=w.models.filter((K)=>K.provider===$),J=Q.modelId?Y.find((K)=>K.id===Q.modelId):Y[0];if(!J)throw new _(Q.modelId?"modelId does not reference this provider":"Model provider has no configured model to probe");return x.json(await g4(J,w))}),O};import{Hono as cw}from"hono";var aw=t("Service"),c4=(O,x)=>{let $=new cw;return $.onError((w,Q)=>{if(w instanceof r)return Q.json(w.toObject(),w.statusCode);return aw.error("[ScheduleRoutes] Unhandled route error:",w),Q.json(new s("Schedule request failed").toObject(),500)}),$.get("/",async(w)=>{let Q=await O.list();return w.json(i4.parse({schedules:Q}))}),$.post("/",async(w)=>{let Q;try{Q=await w.req.json()}catch{throw new _("Invalid request body")}let Y=f(v4,Q);if(!Y.success)throw new _("Invalid schedule request");let J=Y.data.projectPath||w.get("directory")||o();try{let K=await O.create({...Y.data,projectPath:J});return w.json(x0.parse(K),201)}catch(K){throw new _(K instanceof Error?K.message:"Failed to create schedule")}}),$.get("/:id",async(w)=>{let Q=await O.get(w.req.param("id"));if(!Q)throw new y("Schedule not found");return w.json(x0.parse(Q))}),$.patch("/:id",async(w)=>{let Q;try{Q=await w.req.json()}catch{throw new _("Invalid request body")}let Y=f(l4,Q);if(!Y.success)throw new _("Invalid schedule update");let{modelId:J,reasoningEffort:K,serviceTier:S,responseVerbosity:B,communicationStyle:A,isolation:H,permissionMode:U,...T}=Y.data,c={...J!==void 0?{modelId:J}:{},...K!==void 0?{reasoningEffort:K}:{},...S!==void 0?{serviceTier:S}:{},...B!==void 0?{responseVerbosity:B}:{},...A!==void 0?{communicationStyle:A}:{},...H!==void 0?{isolation:H}:{},...U!==void 0?{permissionMode:U}:{}};try{let l=await O.update(w.req.param("id"),{...T,...Object.keys(c).length>0?{dispatch:c}:{}});if(!l)throw new y("Schedule not found");return w.json(x0.parse(l))}catch(l){if(l instanceof r)throw l;throw new _(l instanceof Error?l.message:"Failed to update schedule")}}),$.delete("/:id",async(w)=>{if(!await O.remove(w.req.param("id")))throw new y("Schedule not found");return w.json({ok:!0})}),$.post("/:id/enable",async(w)=>{let Q=await O.setEnabled(w.req.param("id"),!0);if(!Q)throw new y("Schedule not found");return w.json(x0.parse(Q))}),$.post("/:id/disable",async(w)=>{let Q=await O.setEnabled(w.req.param("id"),!1);if(!Q)throw new y("Schedule not found");return w.json(x0.parse(Q))}),$.post("/:id/run",async(w)=>{let Q=await O.get(w.req.param("id"));if(!Q)throw new y("Schedule not found");if(!x)throw new s("Scheduler is not running in this process");await x.fire(Q,new Date,{manual:!0});let Y=await O.get(Q.id);return w.json(x0.parse(Y??Q),202)}),$};import*as lO from"node:fs/promises";import{homedir as n4}from"node:os";import*as jO from"node:path";import{Hono as ow}from"hono";var $0=t("Service"),a4=jO.join(n4(),".blade","skills"),fx=jO.join(n4(),".blade","skills-config.json");async function t4(){try{let O=await lO.readFile(fx,"utf-8");return JSON.parse(O)}catch{return{disabled:[]}}}async function nw(O){await lO.mkdir(jO.dirname(fx),{recursive:!0}),await lO.writeFile(fx,JSON.stringify(O,null,2))}async function tw(O,x){let $=await t4();if(x)$.disabled=$.disabled.filter((w)=>w!==O);else if(!$.disabled.includes(O))$.disabled.push(O);await nw($)}var vO=null,sw=300000,rw=6;async function ew(){if(vO&&Date.now()-vO.timestamp<sw)return vO.data;try{let O=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!O.ok){if($0.warn(`GitHub API returned ${O.status}`),vO)return vO.data;throw Error(`GitHub skills catalog returned ${O.status}`)}let $=(await O.json()).filter((J)=>J.type==="dir"),w=Array($.length),Q=0,Y=Math.min(rw,$.length);return await Promise.all(Array.from({length:Y},async()=>{while(Q<$.length){let J=Q++,K=$[J];if(!K)continue;let S=`Official ${K.name} skill`;try{let B=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${K.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(B.ok){let H=(await B.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(H)S=H[1].trim().slice(0,100)}}catch{}w[J]={name:K.name,description:S,tag:"Official",author:"Anthropic"}}})),vO={data:w,timestamp:Date.now()},w}catch(O){if($0.warn("Failed to fetch skills catalog from GitHub:",O),vO)return vO.data;throw O}}var s4=()=>{let O=new ow;return O.get("/",async(x)=>{try{let $=x.get("directory")||o(),Q=(await TO($)).skills.getAll(),Y=await t4(),J=Q.map((K)=>({id:K.name,name:K.name,enabled:!Y.disabled.includes(K.name),description:K.description||"",version:K.version||"1.0.0",provider:"Local",location:K.source==="builtin"?"Built-in":K.basePath,removable:K.source==="user"&&jO.dirname(jO.resolve(K.basePath))===jO.resolve(a4),capabilities:["prompts"],allowedTools:K.allowedTools||[]}));return x.json(J)}catch($){return $0.error("[SkillsRoutes] Failed to get skills:",$),x.json({error:$ instanceof Error?$.message:"Failed to get skills"},500)}}),O.post("/:name/toggle",async(x)=>{try{let $=x.req.param("name"),w=await x.req.json();return await tw($,w.enabled),x.json({success:!0,enabled:w.enabled})}catch($){return $0.error("[SkillsRoutes] Failed to toggle skill:",$),x.json({success:!1,error:$.message},500)}}),O.delete("/:name",async(x)=>{try{let $=x.req.param("name"),w=x.get("directory")||o();return q0(w,async(Q)=>{let Y=Q.skills,J=Y.get($);if(!J)return x.json({success:!1,error:"Skill not found"},404);let K=jO.resolve(J.basePath),S=jO.resolve(a4);if(J.source!=="user"||jO.dirname(K)!==S)return x.json({success:!1,error:"Only Blade user skills can be uninstalled"},400);return await lO.rm(K,{recursive:!0,force:!0}),await Y.refresh(),R0(w),await T0(w),x.json({success:!0})})}catch($){return $0.error("[SkillsRoutes] Failed to uninstall skill:",$),x.json({success:!1,error:$.message},500)}}),O.post("/install",async(x)=>{try{let $=await x.req.json(),w=o4(),Q=x.get("directory")||o();return q0(Q,async(Y)=>{let J=Y.skills,K=!1;if($.source==="catalog"&&$.name){if(K=await w.installOfficialSkill($.name),!K)return x.json({success:!1,error:"Failed to install skill from catalog"},500)}else if($.source==="repo"&&$.url){if(K=await w.installFromRepo($.url,$.name),!K)return x.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if($.source==="local"&&$.path){if(K=await w.installFromLocal($.path,$.name),!K)return x.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return x.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await J.refresh(),R0(Q),await T0(Q),x.json({success:!0})})}catch($){return $0.error("[SkillsRoutes] Failed to install skill:",$),x.json({success:!1,error:$.message},500)}}),O.get("/catalog",async(x)=>{try{let $=await ew();return x.json($)}catch($){return $0.error("[SkillsRoutes] Failed to get catalog:",$),x.json({error:$ instanceof Error?$.message:"Failed to get skills catalog"},502)}}),O};import{execSync as O2}from"node:child_process";import{readdir as x2}from"node:fs/promises";import Qx from"node:path";import $2 from"fast-glob";import{Hono as w2}from"hono";var g0=t("Service"),Q2=(O)=>{try{return O2("git rev-parse --abbrev-ref HEAD",{cwd:O,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},Z2=[...V0.map((O)=>`${O}/**`),...V0,...V0.map((O)=>`**/${O}/**`),...V0.map((O)=>`**/${O}`),...Px.map((O)=>`**/${O}`)],J2=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),O$=()=>{let O=new w2;return O.get("/commands",async(x)=>{try{let $=x.req.query("q")||"",w=x.get("directory")||o(),Q=await TO(w),Y=e4($,w,Q).filter((J)=>!J2.has(J.command));return x.json(Y)}catch($){return g0.error("[SuggestionsRoutes] Failed to get command suggestions:",$),x.json([])}}),O.get("/files",async(x)=>{try{let $=x.req.query("q")||"",w=x.get("directory")||o(),Q=Math.min(Number(x.req.query("limit"))||100,1000),Y=x.req.query("type")==="file",K=(await $2("**/*",{cwd:w,dot:!1,followSymbolicLinks:!1,onlyFiles:Y,markDirectories:!0,unique:!0,ignore:Z2})).map((A)=>A.replace(/\\/g,"/"));if(!$)return x.json(K.slice(0,Q));let S=$.toLowerCase(),B=K.filter((A)=>A.toLowerCase().includes(S)).slice(0,Q);return x.json(B)}catch($){return g0.error("[SuggestionsRoutes] Failed to get file suggestions:",$),x.json([])}}),O.get("/files/tree",async(x)=>{try{let $=x.get("directory")||o(),w=x.req.query("path")||"",Q=w?Qx.join($,w):$,J=(await x2(Q,{withFileTypes:!0})).map((B)=>({name:B.name,path:w?`${w}/${B.name}`:B.name,type:B.isDirectory()?"dir":"file"}));J.sort((B,A)=>{if(B.type!==A.type)return B.type==="dir"?-1:1;return B.name.localeCompare(A.name)});let K=new Set(V0),S=J.filter((B)=>{let A=B.name;if(A.startsWith("."))return!1;if(K.has(A))return!1;for(let H of Px)if(A.match(new RegExp(H.replace("*",".*"))))return!1;return!0});return x.json(S)}catch($){return g0.error("[SuggestionsRoutes] Failed to get file tree:",$),x.json([])}}),O.get("/files/content",async(x)=>{try{let $=x.req.query("path");if(!$)return x.json({error:"Missing file path"},400);let w=x.get("directory")||o(),Q=Qx.resolve(w,$),Y=Qx.relative(w,Q);if(Y.startsWith("..")||Qx.isAbsolute(Y))return x.json({error:"Invalid file path"},400);let J=r4(),K=await J.stat(Q);if(!K?.isFile)return x.json({error:"File not found"},404);let S=200000,B=await J.readTextFile(Q),A=B.length>S;return x.json({path:$,content:A?B.slice(0,S):B,truncated:A,size:K.size})}catch($){return g0.error("[SuggestionsRoutes] Failed to get file content:",$),x.json({error:"Failed to read file"},500)}}),O.get("/git-info",async(x)=>{try{let $=x.get("directory")||o(),w=Q2($);return x.json({branch:w})}catch($){return g0.error("[SuggestionsRoutes] Failed to get git info:",$),x.json({branch:null})}}),O};import{Hono as Y2}from"hono";var B0=t("Service"),Z$=(O)=>{let x=new Y2;return x.onError(($,w)=>{if($ instanceof r)return w.json($.toObject(),$.statusCode);return B0.error("[TaskRoutes] Unhandled route error:",$),w.json(new s("Failed to dispatch task").toObject(),500)}),x.post("/",async($)=>{let w;try{w=await $.req.json()}catch{throw new _("Invalid request body")}let Q=f($$,w);if(!Q.success)throw new _("Invalid task request");if((Q.data.attachments??[]).reduce((J,K)=>J+(typeof K.content==="string"?Buffer.byteLength(K.content):0),0)>xx)throw new _("Task attachments exceed the 5 MiB limit");if(Q.data.taskDueAt&&!Number.isFinite(Date.parse(Q.data.taskDueAt)))throw new _("Invalid task due date");try{let J=await O.dispatchTask({prompt:Q.data.prompt,title:Q.data.title,taskPriority:Q.data.taskPriority,taskKind:Q.data.taskKind,taskDueAt:Q.data.taskDueAt?new Date(Q.data.taskDueAt).toISOString():void 0,sourceProjectPath:Q.data.projectPath||$.get("directory")||o(),isolation:Q.data.isolation,permissionMode:Q.data.permissionMode,modelId:Q.data.modelId,reasoningEffort:Q.data.reasoningEffort,serviceTier:Q.data.serviceTier,responseVerbosity:Q.data.responseVerbosity,communicationStyle:Q.data.communicationStyle,attachments:Q.data.attachments,outputSchema:Q.data.outputSchema});return $.json(mx.parse(J),202)}catch(J){if(J instanceof _||J instanceof k||J instanceof yO||J instanceof PO)throw J;throw B0.error("[TaskRoutes] Failed to dispatch task:",J),new s("Failed to dispatch task")}}),x.patch("/:sessionId",async($)=>{let w;try{w=await $.req.json()}catch{throw new _("Invalid request body")}let Q=f(w$,w);if(!Q.success)throw new _("Invalid task update");if(Q.data.title===void 0&&Q.data.taskPriority===void 0&&Q.data.taskKind===void 0&&Q.data.taskDueAt===void 0)throw new _("Task update must include at least one field");if(typeof Q.data.taskDueAt==="string"&&!Number.isFinite(Date.parse(Q.data.taskDueAt)))throw new _("Invalid task due date");try{let Y=await O.updateTask($.req.param("sessionId"),{...Q.data,...typeof Q.data.taskDueAt==="string"?{taskDueAt:new Date(Q.data.taskDueAt).toISOString()}:{}},$.req.query("projectPath"));return $.json(yx.parse(Y))}catch(Y){if(Y instanceof _||Y instanceof y||Y instanceof k)throw Y;throw B0.error("[TaskRoutes] Failed to update task:",Y),new s("Failed to update task")}}),x.post("/:sessionId/retry",async($)=>{try{let w=await O.retryTask($.req.param("sessionId"),$.req.query("projectPath"));return $.json(mx.parse(w),202)}catch(w){if(w instanceof _||w instanceof y||w instanceof k||w instanceof yO||w instanceof PO)throw w;throw B0.error("[TaskRoutes] Failed to retry task:",w),new s("Failed to retry task")}}),x.get("/:sessionId/diff",async($)=>{try{let w=await O.getTaskDiff($.req.param("sessionId"),$.req.query("projectPath"));return $.json(x$.parse(w))}catch(w){if(w instanceof _||w instanceof y||w instanceof k)throw w;throw B0.error("[TaskRoutes] Failed to load task diff:",w),new s("Failed to load task diff")}}),x.post("/:sessionId/delivery",async($)=>{let w;try{w=await $.req.json()}catch{throw new _("Invalid request body")}let Q=f(Q$,w);if(!Q.success)throw new _("Invalid task delivery request");try{let Y=await O.deliverTask($.req.param("sessionId"),Q.data.action,$.req.query("projectPath"));return $.json(yx.parse(Y))}catch(Y){if(Y instanceof _||Y instanceof y||Y instanceof k)throw Y;throw B0.error("[TaskRoutes] Failed to deliver task:",Y),new s("Failed to deliver task")}}),x};import W$ from"node:path";import{Hono as X2}from"hono";var N2=RO(W.Object({id:W.String(),name:W.String(),subagentType:W.String(),description:W.String(),agentId:W.Optional(W.String()),status:e(["leader","running","completed","failed","cancelled","unknown"]),result:W.Optional(W.Unknown()),stats:W.Optional(W.Unknown()),worktreePath:W.Optional(W.String())})),W2=RO(W.Object({id:W.String(),subject:W.String(),description:W.String(),status:e(["pending","blocked","running","completed"]),owner:W.Optional(W.String()),priority:e(["high","medium","low"]),dependsOn:W.Array(W.String()),blocks:W.Array(W.String()),result:W.Optional(W.String()),createdAt:W.String(),startedAt:W.Optional(W.String()),completedAt:W.Optional(W.String())})),C6=RO(W.Object({name:W.String(),description:W.Optional(W.String()),status:e(["idle","running","completed","failed","deleted"]),leadAgentId:W.String(),leadSessionId:W.Optional(W.String()),workspaceRoot:W.Optional(W.String()),peerMessagingEnabled:W.Boolean(),createdAt:W.Number(),updatedAt:W.Number(),deletedAt:W.Optional(W.Number()),members:W.Array(N2),tasks:W.Array(W2)})),J$=RO(W.Object({sessionId:W.String({minLength:1}),projectPath:W.String({minLength:1}),name:W.String({minLength:1}),description:W.Optional(W.String()),leadAgentType:W.Optional(W.String()),peerMessagingEnabled:W.Optional(W.Boolean()),members:W.Array(W.Object({name:W.String({minLength:1}),subagentType:W.String({minLength:1}),description:W.Optional(W.String()),prompt:W.String({minLength:10,maxLength:32768})}),{maxItems:32}),tasks:W.Optional(W.Array(W.Object({subject:W.String({minLength:1}),description:W.String({minLength:1}),dependsOn:W.Optional(W.Array(W.String())),assignedTo:W.Optional(W.String()),priority:W.Optional(e(["high","medium","low"]))}),{maxItems:256}))})),Y$=RO(W.Object({sessionId:W.String({minLength:1}),projectPath:W.String({minLength:1}),to:W.String({minLength:1}),message:W.String({minLength:1,maxLength:32768})})),N$=RO(W.Object({sessionId:W.String({minLength:1}),projectPath:W.String({minLength:1}),memberId:W.String({minLength:1})}));var z2=t("Service"),V$=()=>{let O=new X2;return O.onError((x,$)=>{if(x instanceof r)return $.json(x.toObject(),x.statusCode);return z2.error("[TeamRoutes] Unhandled route error:",x),$.json(new s("Team operation failed").toObject(),500)}),O.get("/",async(x)=>{K0();let $=await _0(x.req.query("sessionId"),x.req.query("projectPath"));return x.json(await U0($.projectPath).list($))}),O.post("/",async(x)=>{K0();let $=f(J$,await hx(x.req));if(!$.success)throw new _("Invalid team request");let w=await _0($.data.sessionId,$.data.projectPath),Q=await C.findSessionMetadata(w.sessionId,w.projectPath);return x.json(await U0(w.projectPath).create({name:$.data.name,description:$.data.description,leadAgentType:$.data.leadAgentType,owner:w,modelId:Q?.selectedModelId,peerMessagingEnabled:$.data.peerMessagingEnabled,members:$.data.members,tasks:$.data.tasks}),201)}),O.get("/:teamName",async(x)=>{K0();let $=await _0(x.req.query("sessionId"),x.req.query("projectPath"));return x.json(await U0($.projectPath).getSnapshot(x.req.param("teamName"),$))}),O.post("/:teamName/messages",async(x)=>{K0();let $=f(Y$,await hx(x.req));if(!$.success)throw new _("Invalid team message");let w=await _0($.data.sessionId,$.data.projectPath),Q=await U0(w.projectPath).sendMessage({name:x.req.param("teamName"),to:$.data.to,body:$.data.message,owner:w});return x.json({messages:Q})}),O.post("/:teamName/tasks/claim",async(x)=>{K0();let $=f(N$,await hx(x.req));if(!$.success)throw new _("Invalid team task claim");let w=await _0($.data.sessionId,$.data.projectPath);return x.json({task:await U0(w.projectPath).claimTask(x.req.param("teamName"),$.data.memberId,w)})}),O.delete("/:teamName",async(x)=>{K0();let $=await _0(x.req.query("sessionId"),x.req.query("projectPath"));return x.json(await U0($.projectPath).delete(x.req.param("teamName"),{owner:$,killRunning:!0}))}),O};function U0(O){return new G$({configDir:Ox(),subagentRegistry:z$(O)})}function K0(){if(X$().config.config?.agentTeamsEnabled!==!0)throw new yO("Agent Teams are disabled")}async function _0(O,x){if(!O||!x||!W$.isAbsolute(x))throw new _("sessionId and absolute projectPath are required");let $=W$.resolve(x);if(!await C.findSessionMetadata(O,$))throw new y(`Session not found: ${O}`);return{sessionId:O,projectPath:$}}async function hx(O){try{return await O.json()}catch{throw new _("Invalid request body")}}import{Hono as G2}from"hono";var iO=t("Service"),F0=new Map,B$=2097152,U$=65536;function K$(){return typeof globalThis.Bun<"u"}async function V2(O,x,$){if(K$()){let{spawn:Y}=await import("bun-pty"),J=Y(O,x,{name:"xterm-256color",cwd:$.cwd,env:$.env});return{pid:J.pid,write:(K)=>J.write(K),resize:(K,S)=>J.resize(K,S),kill:()=>J.kill(),onData:(K)=>J.onData(K),onExit:(K)=>J.onExit(K)}}let Q=(await import("node-pty")).spawn(O,x,{name:"xterm-256color",cwd:$.cwd,env:$.env,cols:80,rows:24});return{pid:Q.pid,write:(Y)=>Q.write(Y),resize:(Y,J)=>Q.resize(Y,J),kill:()=>Q.kill(),onData:(Y)=>{Q.onData(Y)},onExit:(Y)=>{Q.onExit(Y)}}}var px=void 0,ux;if(K$())try{let{createBunWebSocket:O}=await import("hono/bun"),x=O();ux=x.upgradeWebSocket,px=x.websocket}catch(O){iO.warn("[Terminal] Failed to initialize Bun WebSocket support:",O)}async function _$(O,x){let $=`term-${Date.now()}`;iO.info(`[Terminal] New connection: ${$}, cwd: ${O}`);let w=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",Q=w.endsWith("sh")?["-l"]:[],Y=await V2(w,Q,{cwd:O,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),J={id:$,process:Y,cwd:O,buffer:"",subscribers:new Set};if(F0.set($,J),J.subscribers.add(x),Y.onData((K)=>{let S=!1;for(let B of J.subscribers)try{B.send(K),S=!0}catch{J.subscribers.delete(B)}if(S)return;if(J.buffer+=K,J.buffer.length>B$)J.buffer=J.buffer.slice(-B$)}),Y.onExit(({exitCode:K})=>{iO.info(`[Terminal] Process exited: ${$}, code: ${K}`);for(let S of J.subscribers)try{S.close()}catch{}F0.delete($)}),J.buffer){let K=J.buffer;J.buffer="";for(let S=0;S<K.length;S+=U$)x.send(K.slice(S,S+U$))}return{session:J,cleanup:()=>{if(iO.info(`[Terminal] Connection closed: ${$}`),J.subscribers.delete(x),J.subscribers.size===0){try{J.process.kill()}catch{}F0.delete($)}}}}function F$(O,x){O.on("connection",async($,w)=>{let Q=new URL(w.url||"/",`http://${w.headers.host}`);if(!Q.pathname.endsWith("/terminal/ws")){$.close();return}let Y=Q.searchParams.get("cwd")||x()||o();try{let{session:J,cleanup:K}=await _$(Y,{send:(S)=>$.send(S),close:()=>$.close()});$.on("message",(S)=>{try{J.process.write(String(S))}catch(B){iO.error("[Terminal] Failed to write to PTY:",B)}}),$.on("close",K),$.on("error",K)}catch(J){iO.error("[Terminal] Failed to spawn PTY:",J),$.close()}})}var L$=()=>{let O=new G2;if(O.get("/status",(x)=>{let $=Array.from(F0.values()).map((w)=>({id:w.id,cwd:w.cwd}));return x.json({active:$.length,terminals:$})}),O.post("/kill/:terminalId",(x)=>{let $=x.req.param("terminalId"),w=F0.get($);if(w){try{w.process.kill()}catch{}for(let Q of w.subscribers)Q.close();return F0.delete($),x.json({success:!0})}return x.json({success:!1,error:"Terminal not found"},404)}),ux)O.get("/ws",ux((x)=>{let $=x.req.query("cwd")||x.get("directory")||o(),w;return{async onOpen(Q,Y){try{w=await _$($,{send:(J)=>Y.send(J),close:()=>Y.close()})}catch(J){iO.error("[Terminal] Failed to spawn PTY:",J),Y.close()}},onMessage(Q){if(!w)return;try{w.session.process.write(String(Q.data))}catch(Y){iO.error("[Terminal] Failed to write to PTY:",Y)}},onClose(){w?.cleanup()}}}));else O.get("/ws",(x)=>{return x.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return O};import B2 from"node:path";import{Hono as U2}from"hono";var K2=W.Object({projectPath:W.String({minLength:1}),action:e(["trust","revoke"])});function D$(O){if(!B2.isAbsolute(O))throw new _("projectPath must be absolute")}var b$=()=>{let O=new U2;return O.get("/",async(x)=>{let $=x.req.query("projectPath");if(!$)throw new _("projectPath query parameter is required");return D$($),x.json(await dx.getInstance().getStatus($))}),O.post("/",async(x)=>{let $=f(K2,await x.req.json());if(!$.success)throw new _("Invalid workspace trust request");let{projectPath:w,action:Q}=$.data;D$(w);let Y=dx.getInstance(),J=Q==="trust"?await Y.trust(w):await Y.revoke(w);return await H$(),x.json({...J,reloadRequired:J.sensitiveSources>0})}),O};var BO=t("Service"),ix=[],Zx,L0,D0,u0,A$=new Map,S$=new Map,R2=new Set([".css",".html",".js",".json",".svg"]),q2=1024,C2=3600000;function I2(O,x){if(!O)return 0;let $=O.split(",").map((w)=>{let[Q,...Y]=w.trim().toLowerCase().split(";"),J=Y.find((S)=>S.trim().startsWith("q=")),K=J?Number(J.trim().slice(2)):1;return{name:Q,quality:Number.isFinite(K)?Math.max(0,Math.min(1,K)):0}});return $.find((w)=>w.name===x)?.quality??$.find((w)=>w.name==="*")?.quality??0}function j$(){if(D0)return;let O=()=>{C.collectStaleEmptySessions().then((x)=>{if(x>0)BO.info(`[SessionGC] removed ${x} stale empty session(s)`)}).catch((x)=>{BO.warn("[SessionGC] failed to collect stale empty sessions:",x)})};O(),D0=setInterval(O,C2),D0.unref?.()}function E2(){if(!D0)return;clearInterval(D0),D0=void 0}function k2(O){return["br","gzip"].map(($)=>({encoding:$,quality:I2(O,$)})).filter(($)=>$.quality>0).sort(($,w)=>w.quality-$.quality||($.encoding==="br"?-1:1))[0]?.encoding}function f2(O){let x=A$.get(O);if(x)return x;let $=p0(O);return A$.set(O,$),$}function P2(O,x,$){let w=`${$}:${O}`,Q=S$.get(w);if(Q)return Q;let Y=$==="br"?b2(x,{params:{[S2.BROTLI_PARAM_QUALITY]:5}}):A2(x,{level:6});return S$.set(w,Y),Y}function y2(){let O=L2(H2(import.meta.url)),x=[cO(O,"web"),cO(o(),"dist/web"),cO(o(),"packages/cli/dist/web")];for(let $ of x){let w=cO($,"index.html");if(lx(w)){if(p0(w,"utf-8").includes("/assets/"))return BO.debug(`[Server] Found web dist at: ${$}`),$}}return null}function m2(){let O=new j2;O.onError((w,Q)=>{if(BO.error("[Server] Request error:",w),w instanceof R$){let J=new PO(w.message,{resource:"workspace_agent_resources",limit:w.capacity});return Q.json(J.toObject(),429)}if(w instanceof r)return Q.json(w.toObject(),w.statusCode);let Y=w instanceof Error?w.message:String(w);return Q.json({error:{code:"INTERNAL_ERROR",message:Y}},500)}),O.use(async(w,Q)=>{let Y=process.env.BLADE_SERVER_PASSWORD;if(!Y)return Q();let J=w.req.path;if(J==="/"||J==="/favicon.svg"||J.startsWith("/assets/")||J.endsWith(".html")||J.endsWith(".js")||J.endsWith(".css"))return Q();let K=w.req.header("Authorization");if(!K?.startsWith("Basic "))return w.header("WWW-Authenticate",'Basic realm="Blade Server"'),w.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let S=Buffer.from(K.slice(6),"base64").toString(),[B,A]=S.split(":"),H=process.env.BLADE_SERVER_USERNAME??"blade";if(B!==H||A!==Y)return w.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return Q()}),O.use(async(w,Q)=>{let Y=w.req.path==="/health"||w.req.path==="/global/health"||w.req.path.startsWith("/assets/");if(!Y)BO.debug(`[Server] ${w.req.method} ${w.req.path}`);let J=Date.now();if(await Q(),!Y){let K=Date.now()-J;BO.debug(`[Server] ${w.req.method} ${w.req.path} - ${w.res.status} (${K}ms)`)}}),O.use(M2({origin(w){if(!w)return;if(w.startsWith("http://localhost:"))return w;if(w.startsWith("http://127.0.0.1:"))return w;if(w==="tauri://localhost"||w==="http://tauri.localhost")return w;if(ix.includes(w))return w;return}})),O.use(async(w,Q)=>{let Y=w.req.query("directory")||w.req.header("x-blade-directory")||o();try{Y=decodeURIComponent(Y)}catch{}return w.set("directory",Y),Q()});let x=F4();u0=x,Zx=x.recoverQueuedTasks,L0=new zx({dispatch:(w)=>x.dispatchTask(w),store:vx}),O.route("/global",W1()),O.route("/events",Y1()),O.route("/sessions",x.app),O.route("/tasks",Z$(x)),O.route("/teams",V$()),O.route("/schedules",c4(vx,L0)),O.route("/configs",x1()),O.route("/permissions",D4()),O.route("/plugins",f4()),O.route("/hooks",U1()),O.route("/workspace-trust",b$()),O.route("/providers",d4()),O.route("/models",S1()),O.route("/projects",m4()),O.route("/suggestions",O$()),O.route("/terminal",L$()),O.route("/mcp",F1()),O.route("/skills",s4()),O.get("/health",(w)=>{return w.json({healthy:!0,version:J0()})});let $=y2();if($)BO.info(`[Server] Serving static files from ${$}`),O.get("/favicon.svg",()=>{let w=cO($,"favicon.svg");if(!lx(w))return new Response(null,{status:404});return new Response(p0(w),{headers:{"Content-Type":"image/svg+xml","Cache-Control":"public, max-age=86400"}})}),O.get("/assets/*",(w)=>{let Q=cO($,w.req.path);if(!lx(Q))return w.json({error:{code:"NOT_FOUND",message:`File not found: ${w.req.path}`}},404);let Y=f2(Q),J=D2(Q).toLowerCase(),S={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[J]||"application/octet-stream",B=R2.has(J)&&Y.byteLength>=q2?k2(w.req.header("Accept-Encoding")):void 0,A=B?P2(Q,Y,B):Y;return new Response(new Uint8Array(A),{headers:{"Content-Type":S,"Content-Length":String(A.byteLength),"Cache-Control":"public, max-age=31536000, immutable",Vary:"Accept-Encoding",...B?{"Content-Encoding":B}:{}}})}),O.get("/",(w)=>{let Q=cO($,"index.html"),Y=p0(Q,"utf-8");return w.html(Y,200,{"Cache-Control":"no-cache"})}),O.get("*",(w)=>{let Q=w.req.path;if(Q.includes("."))return w.json({error:{code:"NOT_FOUND",message:`File not found: ${Q}`}},404);let Y=cO($,"index.html"),J=p0(Y,"utf-8");return w.html(J,200,{"Cache-Control":"no-cache"})});else BO.warn('[Server] Web UI not found. Run "cd packages/cli/web && bun run build" to enable web interface.'),O.get("/",(w)=>{return w.json({message:"Blade API Server",version:J0(),webUI:!1,hint:'Web UI not built. Run "cd packages/cli/web && bun run build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),O.all("*",(w)=>{return w.json({error:{code:"NOT_FOUND",message:`Route not found: ${w.req.path}`}},404)});return O}function h2(){let O=F2(),x=[];for(let $ of Object.keys(O)){let w=O[$];if(!w)continue;for(let Q of w){if(Q.internal||Q.family!=="IPv4")continue;if(Q.address.startsWith("172."))continue;x.push(Q.address)}}return x}function M$(){return typeof globalThis.Bun<"u"}function T$(O,x){let $=globalThis.Bun,w=(Y)=>{try{return $.serve({hostname:x.hostname,port:Y,fetch:O.fetch,idleTimeout:0,websocket:px})}catch(J){BO.error("Failed to start Bun server:",J);return}},Q=x.port===0?w(4096)??w(0):w(x.port);if(!Q)throw Error(`Failed to start Bun server on port ${x.port}`);return{url:Q.url,port:Q.port,hostname:Q.hostname,stop:async()=>{Q.stop(!0)}}}function g2(O,x){return new Promise(($,w)=>{let Q=_2(async(B,A)=>{let H=new URL(B.url||"/",`http://${B.headers.host}`),U=new Headers;for(let[l,JO]of Object.entries(B.headers))if(JO)if(Array.isArray(JO))for(let R of JO)U.append(l,R);else U.set(l,JO);let T;if(B.method!=="GET"&&B.method!=="HEAD")T=(await new Promise((JO)=>{let R=[];B.on("data",(NO)=>R.push(NO)),B.on("end",()=>JO(Buffer.concat(R)))})).toString();let c=new Request(H.toString(),{method:B.method,headers:U,body:T});try{let l=await O.fetch(c);if(A.statusCode=l.status,l.headers.forEach((JO,R)=>{A.setHeader(R,JO)}),l.body){let JO=l.body.getReader(),R=async()=>{let{done:NO,value:p}=await JO.read();if(NO){A.end();return}return A.write(p),R()};await R()}else{let JO=await l.text();A.end(JO)}}catch(l){BO.error("[Server] Node request error:",l),A.statusCode=500,A.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),Y=new T2({noServer:!0}),J=o();F$(Y,()=>J),Q.on("upgrade",(B,A,H)=>{if(new URL(B.url||"/",`http://${B.headers.host}`).pathname==="/terminal/ws")Y.handleUpgrade(B,A,H,(T)=>{Y.emit("connection",T,B)});else A.destroy()});let K=(B)=>{return new Promise((A,H)=>{Q.once("error",(U)=>{if(U.code==="EADDRINUSE")H(U);else H(U)}),Q.listen(B,x.hostname,()=>{let U=Q.address();if(U&&typeof U==="object")A(U.port);else A(B)})})};(async()=>{let B;if(x.port===0)try{B=await K(4096)}catch{B=await K(0)}else B=await K(x.port);let A=new URL(`http://${x.hostname==="0.0.0.0"?"localhost":x.hostname}:${B}`);$({url:A,port:B,hostname:x.hostname,stop:async()=>{return new Promise((H)=>{Y.close(()=>{Q.close(()=>H())})})}})})().catch(w)})}var C$;((y8)=>{let O,x,$,w=(B,A)=>{if(O!==B)return Promise.resolve();if($)return $;let H=A?.shutdown("server-shutdown");return L0?.stop(),E2(),$=(async()=>{let U,T=async(c)=>{if(!c)return;try{await c()}catch(l){U??=l}};if(await T(()=>B.stop()),await T(H?()=>H:void 0),q$(),O===B)O=void 0,x=void 0,u0=void 0,Zx=void 0,L0=void 0;if(BO.info("[Server] Blade server stopped"),U!==void 0)throw U})(),$};function Q(){if(!x)x=m2();return x}y8.getApp=Q;function Y(B){ix=B.cors??[];let A=Q();if(M$())O=T$(A,B),$=void 0,BO.info(`[Server] Blade server listening on ${O.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let H=O,U=u0;return Zx?.().catch((T)=>{BO.warn("[Server] Failed to recover queued tasks:",T)}),L0?.start(),j$(),{url:H.url,port:H.port,hostname:H.hostname,stop:()=>w(H,U)}}y8.listen=Y;async function J(B){ix=B.cors??[];let A=Q();if(M$())O=T$(A,B),BO.info(`[Server] Blade server listening on ${O.url} (Bun runtime)`);else O=await g2(A,B),BO.info(`[Server] Blade server listening on ${O.url} (Node.js runtime)`);$=void 0;let H=O,U=u0;try{await Zx?.()}catch(T){BO.warn("[Server] Failed to recover queued tasks:",T)}return L0?.start(),j$(),{url:H.url,port:H.port,hostname:H.hostname,stop:()=>w(H,U)}}y8.listenAsync=J;function K(){return O!==void 0}y8.isRunning=K;function S(){return u0?.getCoordinationStats()}y8.getSessionCoordinationStatsForTests=S})(C$||={});export{u2 as a,p2 as b,h2 as c,C$ as d};
|
|
6
|
+
`,Buffer.byteLength(x)}class S0{serial;buffered=[];bufferedBytes=0;nextOrder=0;phase="buffering";highestDeliveredSequence=0;highestReplaySequence=0;failure;maxPendingItems;maxPendingBytes;constructor(O){this.maxPendingItems=O.maxPendingItems??w1,this.maxPendingBytes=O.maxPendingBytes??Q1,this.serial=new J1({maxPendingItems:this.maxPendingItems,maxPendingBytes:this.maxPendingBytes,writeTimeoutMs:O.writeTimeoutMs??Z1,sizeOf:$1,write:O.write,onFailure:(x)=>{this.failure=x,this.phase="closed",this.buffered.length=0,this.bufferedBytes=0,O.onFailure?.(x)}})}async writeInitial(O){await this.offerDirect(O)}observe(O,x){if(this.phase==="closed")return;if(this.phase==="buffering"){this.buffer(O,x);return}this.offerLive(O,x)}async writeReplay(O,x){if(!Number.isSafeInteger(x)||x<=0)throw this.fail(new Z0("invalid_size","SSE committed sequence must be a positive safe integer")),this.currentFailure();if(x<=this.highestReplaySequence)return;await this.offerDirect(O),this.highestReplaySequence=x,this.highestDeliveredSequence=x}finishInitialization(O){if(this.phase!=="buffering")return;let x=this.buffered.splice(0);this.bufferedBytes=0,this.phase="live";let $=O.replayed?x.filter((Q)=>Q.sequence!==void 0&&Q.sequence>this.highestReplaySequence).sort((Q,Y)=>Q.sequence-Y.sequence||Q.order-Y.order):x.sort((Q,Y)=>Q.order-Y.order),w;for(let Q of $){if(O.replayed&&Q.sequence!==void 0&&Q.sequence===w)continue;if(this.offerLive(Q.message,Q.sequence),this.serial.stats().closed)return;w=Q.sequence}}offerHeartbeat(O){if(this.phase!=="live"||this.buffered.length>0||this.serial.stats().pendingItems>0)return!1;return this.offerLive(O),!this.serial.stats().closed}async flush(){await this.serial.flush()}close(O){if(this.phase==="closed")return;this.phase="closed",this.buffered.length=0,this.bufferedBytes=0,this.serial.close(O)}stats(){let O=this.serial.stats();return{closed:this.phase==="closed",pendingItems:O.pendingItems+this.buffered.length,pendingBytes:O.pendingBytes+this.bufferedBytes,bufferedItems:this.buffered.length,bufferedBytes:this.bufferedBytes}}buffer(O,x){let $=$1(O),w=this.serial.stats();if($>this.maxPendingBytes){this.fail(new Z0("oversized",`SSE frame requires ${$} bytes; limit is ${this.maxPendingBytes}`,{pendingItems:w.pendingItems+this.buffered.length,pendingBytes:w.pendingBytes+this.bufferedBytes}));return}if(w.pendingItems+this.buffered.length>=this.maxPendingItems||w.pendingBytes+this.bufferedBytes+$>this.maxPendingBytes){this.fail(new Z0("overflow","SSE initialization buffer limit exceeded",{pendingItems:w.pendingItems+this.buffered.length,pendingBytes:w.pendingBytes+this.bufferedBytes}));return}this.nextOrder+=1,this.buffered.push({message:O,bytes:$,sequence:x,order:this.nextOrder}),this.bufferedBytes+=$}offerLive(O,x){if(x!==void 0){if(x<=this.highestReplaySequence)return;if(x<=this.highestDeliveredSequence){this.fail(new Z0("write_failed","SSE committed sequence regressed"));return}this.highestDeliveredSequence=x}if(!this.serial.offer(O).accepted)this.phase="closed"}async offerDirect(O){if(this.phase==="closed")throw this.currentFailure();let x=this.serial.offer(O);if(!x.accepted)throw this.phase="closed",x.error;await x.completion}fail(O){this.serial.close(O)}currentFailure(){return this.failure??new Z0("closed","SSE egress is closed")}}var u$=15000,p$=t("Service"),d$=new Set(["task.status","task.delivery","session.created","session.updated","session.deleted","schedule.fired","permission.asked","question.required","elicitation.required","interaction.resolved"]),v$=new Set(["queued","running","completed","failed","cancelled","interrupted"]),l$=new Set(["high","medium","low"]),i$=new Set(["feature","bug","maintenance","research"]);function c$(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let x=O,$=["changedFiles","additions","deletions","commits"];if($.some((w)=>typeof x[w]!=="number"||!Number.isInteger(x[w])||x[w]<0))return;return Object.fromEntries($.map((w)=>[w,x[w]]))}function j0(O,x){return typeof O==="number"&&Number.isInteger(O)&&O>=x?O:void 0}function a$(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let x=O;if(!["applied","discarded","conflicted"].includes(String(x.status))||typeof x.updatedAt!=="string")return;return{status:x.status,updatedAt:x.updatedAt,...typeof x.sourceCommit==="string"?{sourceCommit:x.sourceCommit}:{},...j0(x.changedFiles,0)!==void 0?{changedFiles:x.changedFiles}:{},...typeof x.message==="string"?{message:x.message}:{}}}var Y1=()=>{let O=new h$;return O.get("/",(x)=>g$(x,async($)=>{let w,Q,Y=!1,J,K,S=new Promise((U)=>{K=U}),B=()=>{if(Q!==void 0)clearInterval(Q),Q=void 0;w?.(),w=void 0},A=(U)=>{if(Y)return;Y=!0,B(),J?.close(U),K()};$.onAbort(A),J=new S0({write:async(U)=>{await $.writeSSE(U)},onFailure:(U)=>{p$.warn(`[EventRoutes] SSE egress closed: kind=${U.kind} pendingItems=${U.pendingItems??0} pendingBytes=${U.pendingBytes??0}`),A(U)}});let H=(U,R)=>{J?.observe({data:JSON.stringify({type:U,properties:R})})};w=q.subscribe((U)=>{if(!d$.has(U.type))return;if(U.type==="permission.asked"||U.type==="question.required"||U.type==="elicitation.required"){let v=U.properties.requestId;if(typeof v!=="string"||!v)return;H("interaction.pending",{sessionId:U.sessionId,projectPath:U.projectPath,interactionType:U.type==="question.required"?"question":U.type==="elicitation.required"?"elicitation":"permission",requestId:v});return}if(U.type==="interaction.resolved"){let v=U.properties.requestId;if(typeof v!=="string"||!v)return;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,requestId:v});return}if(U.type==="session.created"||U.type==="session.deleted"){H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath});return}if(U.type==="session.updated"){let v=U.properties.title,ZO=U.properties.taskPriority,wO=U.properties.taskKind,IO=U.properties.taskDueAt,xO=typeof v==="string"&&Boolean(v.trim()),aO=l$.has(String(ZO)),LO=i$.has(String(wO)),z=IO===null||typeof IO==="string"&&Number.isFinite(Date.parse(IO));if(!xO&&!aO&&!LO&&!z)return;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,...xO?{title:v}:{},...aO?{taskPriority:ZO}:{},...LO?{taskKind:wO}:{},...z?{taskDueAt:IO}:{}});return}if(U.type==="task.delivery"){let v=a$(U.properties.taskDelivery);if(!v)return;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,taskDelivery:v,...U.properties.taskWorktreeRemoved===!0?{taskWorktreeRemoved:!0}:{},...typeof U.properties.updatedAt==="string"?{updatedAt:U.properties.updatedAt}:{}});return}if(U.type==="schedule.fired"){let v=U.properties.scheduleId,ZO=U.properties.firedAt;if(typeof v!=="string"||typeof ZO!=="string")return;H(U.type,{scheduleId:v,firedAt:ZO,sessionId:U.sessionId,projectPath:U.projectPath,...typeof U.properties.runId==="string"?{runId:U.properties.runId}:{},...typeof U.properties.status==="string"?{status:U.properties.status}:{}});return}let R=U.properties.taskStatus;if(typeof R!=="string"||!v$.has(R))return;let c=c$(U.properties.taskDiffStat),l=j0(U.properties.taskQueuePosition,1),JO=j0(U.properties.taskQueueDepth,0),T=j0(U.properties.taskConcurrencyLimit,1),NO=j0(U.properties.taskInFlight,0),p=typeof U.properties.taskAdmissionPaused==="boolean"?U.properties.taskAdmissionPaused:void 0;H(U.type,{sessionId:U.sessionId,projectPath:U.projectPath,taskStatus:R,...typeof U.properties.taskStatusReason==="string"?{taskStatusReason:U.properties.taskStatusReason}:{},...U.properties.taskFailure&&typeof U.properties.taskFailure==="object"?{taskFailure:U.properties.taskFailure}:{},...typeof U.properties.taskStartedAt==="string"?{taskStartedAt:U.properties.taskStartedAt}:{},...typeof U.properties.taskCompletedAt==="string"?{taskCompletedAt:U.properties.taskCompletedAt}:{},...typeof U.properties.updatedAt==="string"?{updatedAt:U.properties.updatedAt}:{},...c?{taskDiffStat:c}:{},...l!==void 0?{taskQueuePosition:l}:{},...JO!==void 0?{taskQueueDepth:JO}:{},...T!==void 0?{taskConcurrencyLimit:T}:{},...NO!==void 0?{taskInFlight:NO}:{},...p!==void 0?{taskAdmissionPaused:p}:{}})});try{if($.aborted||Y)return;if(await J.writeInitial({data:JSON.stringify({type:"connected",properties:{timestamp:Date.now()}})}),$.aborted||Y)return;if(J.finishInitialization({replayed:!1}),$.aborted||Y)return;Q=setInterval(()=>{if($.aborted||Y)return;J?.offerHeartbeat({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})})},u$),await S}finally{A()}})),O};import{Hono as o$}from"hono";var n$=W.Object({paused:W.Boolean()}),W1=()=>{let O=new o$;return O.get("/health",(x)=>{return x.json({healthy:!0,version:J0()})}),O.get("/info",(x)=>{let $=o(),w=YO();if(w)gO.configure(w.maxConcurrentTasks,w.maxQueuedTasks,w.maxQueuedTaskBytes);let Q=gO.getStats();return x.json({version:J0(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:$,gitBranch:N1($),taskAdmission:{inFlight:Q.inFlight,queued:Q.queued,maxConcurrent:Q.maxConcurrent,maxQueued:Q.maxQueued,paused:Q.paused}})}),O.put("/task-admission",async(x)=>{let $;try{$=await x.req.json()}catch{throw new _("Invalid request body")}let w=f(n$,$);if(!w.success)throw new _("Invalid task admission control request");gO.setPaused(w.data.paused);let Q=gO.getStats();return x.json({inFlight:Q.inFlight,queued:Q.queued,maxConcurrent:Q.maxConcurrent,maxQueued:Q.maxQueued,paused:Q.paused})}),O};import X1 from"node:path";import{Hono as t$}from"hono";var s$=W.Object({projectPath:W.String({minLength:1}),action:e(["trust","revoke"]),expectedDigest:W.Optional(W.String())}),r$=W.Object({projectPath:W.String({minLength:1}),sessionId:W.String({minLength:1}),enabled:W.Boolean()});function Vx(O){if(!O||!X1.isAbsolute(O))throw new _("projectPath must be absolute");return X1.resolve(O)}function z1(O){if(!O)throw new _("sessionId is required");try{o0(O)}catch(x){throw new _(x instanceof Error?x.message:"sessionId is invalid")}return O}async function a0(O){let x=Vx(O),$=YO()?.hooks??B1.hooks,w=await M0.getInstance().loadWorkspaceHooks(x,$,{includeBaseForCurrentWorkspace:!1});return q0(x,async()=>{R0(x);let Q=Y0.getInstance();return Q.loadConfig(w,x),await T0(x),Q.getConfig(x)})}function G1(O,x){let $=Y0.getInstance(),w=$.getConfig(x).enabled,Q=$.isSessionPaused(O,x);return{sessionId:O,projectPath:x,enabled:$.isSessionEnabled(O,x),paused:Q,configEnabled:w}}var U1=()=>{let O=new t$;return O.get("/trust",async(x)=>{let $=x.req.query("projectPath");if(!$)throw new _("projectPath query parameter is required");return await a0($),x.json(await Y0.getInstance().getTrustStatus($))}),O.post("/trust",async(x)=>{let $=f(s$,await x.req.json());if(!$.success)throw new _("Invalid hook trust request");let{projectPath:w,action:Q,expectedDigest:Y}=$.data;await a0(w);let J=Y0.getInstance(),K;try{K=Q==="trust"?await J.trustProject(w,Y):await J.revokeProjectTrust(w)}catch(S){if(S instanceof V1)throw new k(S.message);throw S}return x.json(K)}),O.get("/session",async(x)=>{let $=Vx(x.req.query("projectPath")),w=z1(x.req.query("sessionId"));return await a0($),x.json(G1(w,$))}),O.post("/session",async(x)=>{let $=f(r$,await x.req.json());if(!$.success)throw new _("Invalid hook session request");let w=Vx($.data.projectPath),Q=z1($.data.sessionId);await a0(w);let Y=Y0.getInstance();if($.data.enabled)Y.enableSession(Q,w);else Y.disableSession(Q,w);return x.json(G1(Q,w))}),O};import{Hono as e$}from"hono";var kO=t("Service");function Ow(O){try{return _1(O)}catch{return[]}}function xw(O){if(!n0(O)||!n0(O.reference)||!n0(O.argument))throw Error("Invalid MCP completion request");let x=O.reference.type,$=x==="prompt"&&typeof O.reference.name==="string"?{type:"prompt",name:O.reference.name}:x==="resource"&&typeof O.reference.uri==="string"?{type:"resource",uri:O.reference.uri}:void 0;if(!$||typeof O.argument.name!=="string"||typeof O.argument.value!=="string")throw Error("Invalid MCP completion request");let w;if(O.context!==void 0){if(!n0(O.context))throw Error("Invalid MCP completion context");w=Object.create(null);for(let[Q,Y]of Object.entries(O.context)){if(typeof Y!=="string")throw Error("Invalid MCP completion context");w[Q]=Y}}return{reference:$,argument:{name:O.argument.name,value:O.argument.value},...w?{context:w}:{}}}function n0(O){return O!==null&&typeof O==="object"&&!Array.isArray(O)}async function uO(O,x){let $=YO()?.mcpServers??{};for(let[w,Q]of Object.entries($)){if(x&&w!==x)continue;if(!O.getServerStatus(w))await O.registerServer(w,Q,{connect:!1})}}var F1=()=>{let O=new e$;return O.get("/",async(x)=>{try{let $=KO.getInstance();await uO($);let w=$.getAllServers(),Q=await Promise.all(Array.from(w.entries()).map(async([Y,J])=>({id:Y,name:Y,status:J.status==="connected"?"connected":J.status==="reconnecting"?"reconnecting":J.status==="connecting"?"connecting":J.lastError?"error":"offline",endpoint:J.config.command?`${J.config.command} ${(J.config.args||[]).join(" ")}`.trim():J.config.url||"Unknown",description:`MCP server: ${Y}`,tools:J.tools.map((K)=>K.name),completionSupported:J.client.completionSupported,tasks:J.client.tasks,resources:J.contentCatalog.resources,resourceTemplates:J.contentCatalog.resourceTemplates.map((K)=>({...K,variables:Ow(K.uriTemplate)})),prompts:J.contentCatalog.prompts,connectedAt:J.connectedAt?.toISOString(),error:J.lastError?.message,recovery:J.recovery,logging:J.logging,instructions:J.instructions,oauthEnabled:J.client.oauthEnabled,oauthStatus:await J.client.getOAuthStatus()})));return x.json(Q)}catch($){return kO.error("[McpRoutes] Failed to get MCP servers:",$),x.json({error:$ instanceof Error?$.message:"Failed to get MCP servers"},500)}}),O.post("/:name/connect",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();return await uO(w,$),await w.connectServer($),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to connect MCP server:",$),x.json({success:!1,error:$.message},500)}}),O.post("/:name/disconnect",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();return await uO(w,$),await w.disconnectServer($),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to disconnect MCP server:",$),x.json({success:!1,error:$.message},500)}}),O.get("/:name/logs",async(x)=>{try{let $=x.req.param("name"),w=Number(x.req.query("limit")??20),Q=Number(x.req.query("afterRevision")??0);if(!Number.isSafeInteger(w)||w<1||w>100||!Number.isSafeInteger(Q)||Q<0)return x.json({error:"Invalid MCP log pagination"},400);let Y=KO.getInstance();return await uO(Y,$),x.json(Y.getLogSnapshot($,{limit:w,afterRevision:Q}))}catch($){return kO.error("[McpRoutes] Failed to get MCP logs:",$),x.json({error:$.message},500)}}),O.post("/:name/logging-level",async(x)=>{try{let $=x.req.param("name"),w=await x.req.json();if(!K1(w.level))return x.json({success:!1,error:"Invalid MCP logging level"},400);let Q=KO.getInstance();return await uO(Q,$),await Q.setServerLoggingLevel($,w.level),x.json({success:!0,level:w.level})}catch($){return kO.error("[McpRoutes] Failed to set MCP logging level:",$),x.json({success:!1,error:$.message},400)}}),O.post("/:name/complete",async(x)=>{try{let $=x.req.param("name"),w=xw(await x.req.json()),Q=KO.getInstance();await uO(Q,$);let Y=await Q.complete($,w);return x.json(Y)}catch($){return kO.error("[McpRoutes] Failed to complete MCP argument:",$),x.json({error:$.message},400)}}),O.post("/:name/oauth/login",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();await uO(w,$);let Q=await w.beginOAuthLogin($);return x.json({success:!0,flowId:Q.flowId,authorizationUrl:Q.authorizationUrl},202)}catch($){return kO.error("[McpRoutes] Failed to start MCP OAuth login:",$),x.json({success:!1,error:$.message},400)}}),O.post("/:name/oauth/logout",async(x)=>{try{let $=x.req.param("name"),w=KO.getInstance();return await uO(w,$),await w.logoutOAuth($),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to log out MCP OAuth:",$),x.json({success:!1,error:$.message},400)}}),O.delete("/:name",async(x)=>{try{let $=x.req.param("name");await KO.getInstance().unregisterServer($);let Q=YO();if(Q?.mcpServers){let{[$]:Y,...J}=Q.mcpServers;await AO().updateConfig({mcpServers:J})}return x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to delete MCP server:",$),x.json({success:!1,error:$.message},500)}}),O.post("/",async(x)=>{try{let $=await x.req.json(),{name:w,config:Q}=$;if(!w||!Q)return x.json({success:!1,error:"Missing name or config"},400);await KO.getInstance().registerServer(w,Q);let J=YO();return await AO().updateConfig({mcpServers:{...J?.mcpServers,[w]:Q}}),x.json({success:!0})}catch($){return kO.error("[McpRoutes] Failed to add MCP server:",$),x.json({success:!1,error:$.message},500)}}),O};import{getSupportedThinkingLevels as $w}from"@earendil-works/pi-ai";import{Hono as ww}from"hono";var t0=t("Service");function Qw(O,x,$=b1.list()){return{id:O.id,displayName:O.displayName,provider:O.provider,model:O.model,overrides:O.overrides,fallbackModels:O.fallbackModels,contextWindow:x.contextWindow,maxTokens:x.maxTokens,reasoning:x.reasoning,supportedReasoningEfforts:$w(x),supportedServiceTiers:D1(x),supportedResponseVerbosities:L1(x),communicationStyles:$,input:x.input}}function Zw(O){A1(O.overrides);let x={displayName:O.displayName||void 0,overrides:O.overrides||void 0};if(O.model)x.model=O.model;return x}function A1(O){let x=O?.streamIdleTimeout;if(x!==void 0&&(!Number.isFinite(x)||x<1000))throw new _("streamIdleTimeout must be at least 1000ms")}var S1=()=>{let O=new ww;return O.get("/",async(x)=>{try{let $=YO();if(!$)throw Error("Config not initialized");let w=x.get("directory")||o(),[Q,Y]=await Promise.all([s0(w,$),TO(w)]),J=Q.config.models,K=J.find((H)=>H.id===Q.config.currentModelId)??J[0],S=Q.catalog,B=Y.communicationStyles.list(),A=(H)=>Qw(H,S.resolveConfig(H),B);return x.json({configured:J.map(A),current:K?A(K):null})}catch($){t0.error("[ModelsRoutes] Failed to get models:",$);let w=new s("Failed to get models");return x.json(w.toObject(),500)}}),O.post("/",async(x)=>{let $=nO(),w,Q;try{let Y=await x.req.json(),{provider:J,displayName:K,model:S,overrides:B,apiKey:A,modelProvider:H}=Y;if(!J||!S)throw new _("provider and model are required");A1(B);let U;if(H){if(H.id!==J)throw new _("modelProvider.id must match the model provider");if(YO()?.modelProviders[J])throw new _(`model provider already exists: ${J}`);U={name:H.name,baseUrl:H.baseUrl,wireApi:H.wireApi,...H.apiKeyEnv?{apiKeyEnv:H.apiKeyEnv}:{}};try{$.registerModelProvider(J,U,[S]),Q=J}catch(l){throw new _(l instanceof Error?l.message:"Invalid model provider")}}else $.getModel(J,S);if(A?.trim()){if(await $.setApiKey(J,A.trim()),U)w=J}let R={provider:J,displayName:K||void 0,model:S,overrides:B||void 0},c=U?await AO().addModelWithProvider(R,U):await AO().addModel(R);return x.json({success:!0,model:c})}catch(Y){if(w)await $.credentials.delete(w);if(Q){let J=YO();$.configureModelProviders(J?.modelProviders??{},J?.models??[])}throw t0.error("[ModelsRoutes] Failed to add model:",Y),Y}}),O.put("/:modelId",async(x)=>{try{let $=x.req.param("modelId"),w=await x.req.json(),{displayName:Q,overrides:Y,model:J}=w,K=H1($);if(!K)throw new _("model config not found");if(J)nO().getModel(K.provider,J);return await AO().updateModel($,Zw({displayName:Q,overrides:Y,model:J})),x.json({success:!0})}catch($){throw t0.error("[ModelsRoutes] Failed to update model:",$),$}}),O.delete("/:modelId",async(x)=>{try{let $=x.req.param("modelId");return await AO().removeModel($),x.json({success:!0})}catch($){throw t0.error("[ModelsRoutes] Failed to delete model:",$),$}}),O};import{Hono as Tw}from"hono";import E1 from"node:path";import{Hono as Xw}from"hono";import{streamSSE as zw}from"hono/streaming";import{LRUCache as Gw}from"lru-cache";import{nanoid as W0}from"nanoid";class Bx{runtimes=new Map;createRuntime;constructor(O={}){this.createRuntime=O.createRuntime??((x)=>new j1(x.projectPath,`web-browser:${x.sessionId}`,{exposeArtifactPaths:!1}))}get(O){let x=m(O),$=this.runtimes.get(x);if(!$)$=this.createRuntime(O),this.runtimes.set(x,$);return $}async reset(O){let x=this.runtimes.get(m(O));if(x)await x.page({action:{kind:"reset"}})}async dispose(O){let x=m(O),$=this.runtimes.get(x);if(!$)return;this.runtimes.delete(x),await $.dispose()}async disposeAll(){let O=[...this.runtimes.values()];this.runtimes.clear();let $=(await Promise.allSettled(O.map((w)=>w.dispose()))).find((w)=>w.status==="rejected");if($)throw $.reason}stats(){return{sessions:this.runtimes.size}}}import{Hono as Yw}from"hono";var M1=W.Object({action:e(["accept","dismiss"])},{additionalProperties:!1}),Jw=RO(W.Union([W.Object({kind:W.Literal("click"),dialog:W.Optional(M1)},{additionalProperties:!1}),W.Object({kind:W.Literal("click_at"),screenshotId:W.String({minLength:1,maxLength:C0}),x:W.Integer({minimum:0,maximum:Ux}),y:W.Integer({minimum:0,maximum:Ux}),dialog:W.Optional(M1)},{additionalProperties:!1}),W.Object({kind:W.Literal("hover")},{additionalProperties:!1}),W.Object({kind:W.Literal("fill"),value:W.String()},{additionalProperties:!1}),W.Object({kind:W.Literal("type"),value:W.String()},{additionalProperties:!1}),W.Object({kind:W.Literal("press"),key:e(["Enter","Tab","Escape","Backspace","Delete","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown","Space"])},{additionalProperties:!1}),W.Object({kind:W.Literal("select"),values:W.Array(W.String())},{additionalProperties:!1}),W.Object({kind:W.Literal("check")},{additionalProperties:!1}),W.Object({kind:W.Literal("uncheck")},{additionalProperties:!1}),W.Object({kind:W.Literal("scroll"),direction:e(["up","down","left","right"]),amount:W.Integer()},{additionalProperties:!1})])),T1=RO(W.Object({action:W.Optional(e(["goto","back","forward","reload"])),url:W.Optional(W.String()),pageId:W.Optional(W.String()),expectedOrigin:W.Optional(W.String()),waitUntil:W.Optional(e(["commit","domcontentloaded","load"])),timeoutMs:W.Optional(W.Integer())},{additionalProperties:!1})),R1=RO(W.Object({pageId:W.String(),snapshotId:W.String(),ref:W.Optional(W.String()),expectedOrigin:W.String(),action:Jw,timeoutMs:W.Optional(W.Integer())},{additionalProperties:!1}));function q1(O,x){if(O===void 0)return;let $=Number(O);if(!Number.isSafeInteger($))throw new _(`${x} must be an integer`);return $}function Nw(O,x){if(O===void 0)return;if(O==="true")return!0;if(O==="false")return!1;throw new _(`${x} must be true or false`)}function Ww(O){let x=O.code==="browser_not_installed"||O.code==="browser_disconnected"||O.code==="browser_disposed"?503:O.code==="browser_capacity"?429:O.code==="browser_unsupported"?400:409;return new r(O.code.toUpperCase(),O.message,x,O.details)}function I1(O){let x=new Yw;x.use("*",(w,Q)=>O.withAdmission(Q)),x.onError((w,Q)=>{let Y=w instanceof C1?Ww(w):w instanceof r?w:new s;return Q.json(Y.toObject(),Y.statusCode)});let $=(w,Q)=>O.resolveSessionRef(w,Q);return x.post("/:sessionId/browser/navigate",async(w)=>{let Q=await w.req.json().catch(()=>{return}),Y=f(T1,Q);if(!Y.success)throw new _("Invalid browser navigation request");let J=await $(w.req.param("sessionId"),w.req.query("projectPath"));return w.json(await O.getRuntime(J).navigate(Y.data))}),x.post("/:sessionId/browser/interact",async(w)=>{let Q=await w.req.json().catch(()=>{return}),Y=f(R1,Q);if(!Y.success)throw new _("Invalid browser interaction request");let J=await $(w.req.param("sessionId"),w.req.query("projectPath"));return w.json(await O.getRuntime(J).interact(Y.data))}),x.get("/:sessionId/browser/snapshot",async(w)=>{let Q=await $(w.req.param("sessionId"),w.req.query("projectPath")),Y=q1(w.req.query("depth"),"depth"),J=Nw(w.req.query("includeBoxes"),"includeBoxes");return w.json(await O.getRuntime(Q).snapshot({...w.req.query("pageId")?{pageId:w.req.query("pageId")}:{},...Y===void 0?{}:{depth:Y},...J===void 0?{}:{includeBoxes:J}}))}),x.get("/:sessionId/browser/inspect",async(w)=>{let Q=await $(w.req.param("sessionId"),w.req.query("projectPath")),Y=w.req.query("target"),J=w.req.query("pageId"),K=w.req.query("expectedOrigin");if(Y==="screenshot"){let A=w.req.query("source")??"user";if(A!=="user"&&A!=="agent")throw new _("Unsupported browser screenshot source");if(A==="agent"&&(!J||!K))throw new _("Agent browser screenshots require pageId and expectedOrigin");let H={...J?{pageId:J}:{},...K?{expectedOrigin:K}:{}},U=A==="agent"?await O.captureAgentScreenshot(Q,H):await O.getRuntime(Q).screenshot(H);return new Response(new Uint8Array(U),{headers:{"Content-Type":"image/png","Content-Length":String(U.length),"Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}})}let S=q1(w.req.query("limit"),"limit"),B={...J?{pageId:J}:{},...K?{expectedOrigin:K}:{}};if(Y==="find"){let A=w.req.query("text");if(!A)throw new _("text is required for browser find");return w.json(await O.getRuntime(Q).inspect({...B,target:{kind:"find",text:A,...S===void 0?{}:{limit:S}}}))}if(Y!=="console"&&Y!=="page-errors"&&Y!=="network")throw new _("Unsupported browser inspection target");return w.json(await O.getRuntime(Q).inspect({...B,target:{kind:Y,...S===void 0?{}:{limit:S}}}))}),x.post("/:sessionId/browser/reset",async(w)=>{let Q=await $(w.req.param("sessionId"),w.req.query("projectPath"));return await O.resetRuntime(Q),w.json({success:!0})}),x}var g=t("Service"),Vw=W.Object({title:W.Optional(W.String()),projectPath:W.Optional(W.String())}),Bw=G4,Uw=W.Object({title:W.Optional(W.String()),projectPath:W.Optional(W.String())}),Kw=W.Object({projectPath:W.String()}),_w=W.Object({objective:W.String({minLength:1}),tokenBudget:W.Optional(W.Integer({minimum:1})),permissionMode:W.Optional(e(["default","autoEdit","plan","yolo"]))}),Fw=W.Union([W.Object({action:W.Literal("pause")}),W.Object({action:W.Literal("resume")}),W.Object({action:W.Literal("edit"),objective:W.String({minLength:1})})]),OO=new Map,z0,CO=new Map,mO=new Map,qO=new Map,$x=new Gw({max:100,ttl:1800000});function k1(O){return{sessionId:O.sessionId,projectPath:O.projectPath}}function FO(O){if(!O)return;return CO.get(O)??$x.get(O)}function Lw(O){if(CO.get(O.id)!==O)return;CO.delete(O.id),$x.set(O.id,O)}function Dw(O){CO.delete(O),$x.delete(O)}function _O(O){return O?.status==="queued"||O?.status==="running"||O?.status==="waiting_permission"}function k0(O,x="user-cancel"){if(O.status==="cancelled"||O.status==="completed"||O.status==="failed"||O.status==="attention_required")return!1;let $=O.pendingPermission;if(O.pendingPermission=void 0,$?.resolve({approved:!1,reason:d1}),$)q.publish(k1(O),"interaction.resolved",{requestId:$.permissionId});return O.abortController.abort(x),O.status="cancelled",q.publish(k1(O),"run.cancelled",{runId:O.id}),!0}function _4(O,x=!1){let{permissionId:$,details:w}=O;if(w.type==="askUserQuestion"&&w.questions)return{type:"question.required",properties:{requestId:$,toolCallId:w.toolCallId??$,questions:w.questions,details:w,...x?{replayed:!0}:{}}};if(w.type==="mcpElicitation"&&w.mcpElicitation)return{type:"elicitation.required",properties:{requestId:$,toolCallId:w.toolCallId??$,elicitation:w.mcpElicitation,...x?{replayed:!0}:{}}};return{type:"permission.asked",properties:{requestId:$,toolName:w.toolName,description:w.message,args:w.args,details:w,...x?{replayed:!0}:{}}}}function Hw(O){return{...typeof O.seq==="number"?{id:String(O.seq)}:{},data:JSON.stringify({type:O.type,...typeof O.seq==="number"?{seq:O.seq}:{},properties:{...O.properties,sessionId:O.sessionId,projectPath:O.projectPath}})}}function bw(){for(let O of CO.values())k0(O,"route-reset");CO.clear();for(let O of mO.values())O.controller.abort("route-reset");mO.clear(),$x.clear(),z0=void 0,OO.clear()}function Aw(O){if(!O||typeof O!=="object"||Array.isArray(O))return;let x=O,$=x.code,w=x.reason,Q=x.scope,Y=x.kind,J=x.limit;if($!=="tool_busy"&&$!=="tool_batch_full"||w!=="queue_full"&&w!=="wait_timeout"&&w!=="turn_limit"||Q!=="global"&&Q!=="session"||typeof x.retryable!=="boolean"||!Number.isSafeInteger(J)||J<=0||Y!==void 0&&Y!=="readonly"&&Y!=="write"&&Y!=="execute")return;return{code:$,reason:w,scope:Q,retryable:x.retryable,...Y===void 0?{}:{kind:Y},limit:J}}var f0=(O,x)=>{if(!x||typeof x!=="object")return x;let $={...x},w=Aw($.tool_admission);if(w)$.tool_admission=w;else delete $.tool_admission;if(O4(O)){let J=$.browser&&typeof $.browser==="object"&&!Array.isArray($.browser)?$.browser:{},K={},S=(B,A,H)=>{let U=J[B];if(typeof U==="string"&&Buffer.byteLength(U)<=A&&(!H||H.test(U)))K[B]=U};if(S("action",64),S("status",16,/^(?:ok|warning|error)$/),S("pageId",C0,/^browser_page_[a-f0-9-]+$/),S("snapshotId",C0,/^browser_snapshot_[a-f0-9-]+$/),S("origin",Dx),S("candidateOrigin",Dx),S("url",l1),S("title",i1),S("errorCode",64,/^browser_[a-z_]+$/),typeof J.truncated==="boolean")K.truncated=J.truncated;if(typeof J.actionApplied==="boolean"||J.actionApplied==="unknown")K.actionApplied=J.actionApplied;if(typeof J.sideEffectsUncertain==="boolean")K.sideEffectsUncertain=J.sideEffectsUncertain;if(typeof J.diagnosticCount==="number"&&Number.isSafeInteger(J.diagnosticCount)&&J.diagnosticCount>=0&&J.diagnosticCount<=v1)K.diagnosticCount=J.diagnosticCount;if(J.interaction&&typeof J.interaction==="object"&&!Array.isArray(J.interaction)){let B=J.interaction,A=new Set(["click","hover","fill","type","press","select","check","uncheck","scroll"]);if(typeof B.action==="string"&&A.has(B.action)){let H={action:B.action};if(typeof B.ref==="string"&&Buffer.byteLength(B.ref)<=c1&&/^[a-z][a-z0-9]*$/.test(B.ref))H.ref=B.ref;let U=(R,c,l)=>typeof R==="number"&&Number.isFinite(R)&&R>=c&&R<=l;if(B.viewport&&typeof B.viewport==="object"&&!Array.isArray(B.viewport)){let R=B.viewport;if(U(R.width,1,16384)&&U(R.height,1,16384))H.viewport={width:R.width,height:R.height}}if(B.targetBox&&typeof B.targetBox==="object"&&!Array.isArray(B.targetBox)){let R=B.targetBox;if(U(R.x,-16384,32768)&&U(R.y,-16384,32768)&&U(R.width,0,16384)&&U(R.height,0,16384))H.targetBox={x:R.x,y:R.y,width:R.width,height:R.height}}K.interaction=H}}if(J.artifact&&typeof J.artifact==="object"&&!Array.isArray(J.artifact)){let B=J.artifact;if(typeof B.id==="string"&&/^[a-f0-9]{64}$/.test(B.id)&&B.sha256===B.id&&B.kind==="image"&&B.mimeType==="image/png"&&typeof B.size==="number"&&Number.isSafeInteger(B.size)&&B.size>=0&&B.size<=a1&&B.persisted===!0)K.artifact={id:B.id,sha256:B.sha256,kind:B.kind,mimeType:B.mimeType,size:B.size,persisted:!0,...typeof B.path==="string"&&Buffer.byteLength(B.path)<=8192?{path:B.path}:{}}}return{...typeof $.summary==="string"?{summary:$.summary.slice(0,512)}:{},browser:K,...w?{tool_admission:w}:{}}}if(O==="Bash"){let J={},K=["message","signal","status","summary"],S=["aborted","acp_mode","admission_failed","auto_backgrounded","background","capture_truncated","finalization_failed","has_stderr","output_accounting_complete","output_truncated","projection_truncated","sandbox_required","sandboxed","stderr_projection_truncated","stdout_projection_truncated","terminal_output_merged","timeout"],B=["execution_time","foreground_budget_ms","pid","raw_output_bytes","stderr_length","stderr_omitted_bytes","stderr_retained_bytes","stderr_total_bytes","stdout_length","stdout_omitted_bytes","stdout_retained_bytes","stdout_total_bytes"];for(let H of K){let U=$[H];if(typeof U==="string")J[H]=U.slice(0,8192)}for(let H of S){let U=$[H];if(typeof U==="boolean")J[H]=U}for(let H of B){let U=$[H];if(typeof U==="number"&&Number.isSafeInteger(U)&&U>=0)J[H]=U}if($.exit_code===null||typeof $.exit_code==="number"&&Number.isSafeInteger($.exit_code))J.exit_code=$.exit_code;if($.terminal_transport==="local"||$.terminal_transport==="acp"||$.terminal_transport==="local_fallback")J.terminal_transport=$.terminal_transport;if($.background_reason==="explicit"||$.background_reason==="foreground_budget")J.background_reason=$.background_reason;for(let H of["bash_id","shell_id"]){let U=$[H];if(typeof U==="string"&&U.length<=128&&/^bash_[A-Za-z0-9-]+$/.test(U))J[H]=U}if(w)J.tool_admission=w;let A=$.background_shell_admission;if(A&&typeof A==="object"&&!Array.isArray(A)){let H=A;if(H.code==="background_shell_busy"&&(H.scope==="session"||H.scope==="global")&&H.retryable===!0&&Number.isSafeInteger(H.limit)&&H.limit>0)J.background_shell_admission={code:H.code,scope:H.scope,retryable:H.retryable,limit:H.limit}}return J}let Q=200000,Y=(J,K)=>typeof J==="number"&&Number.isSafeInteger(J)&&J>=0&&J<=K?J:0;if(typeof $.oldContent==="string"&&$.oldContent.length>Q)delete $.oldContent;if(typeof $.newContent==="string"&&$.newContent.length>Q)delete $.newContent;if($.mcpResult&&typeof $.mcpResult==="object"&&!Array.isArray($.mcpResult)){let J=$.mcpResult,K=Array.isArray(J.artifacts)?J.artifacts.slice(0,64).flatMap((S)=>{if(!S||typeof S!=="object"||Array.isArray(S))return[];let B=S,A=new Set(["text","image","audio","resource"]);if(typeof B.id!=="string"||!/^[a-f0-9]{64}$/.test(B.id)||typeof B.sha256!=="string"||B.sha256!==B.id||typeof B.kind!=="string"||!A.has(B.kind)||Y(B.size,67108864)!==B.size||typeof B.persisted!=="boolean")return[];return[{id:B.id.slice(0,128),sha256:B.sha256.slice(0,128),kind:B.kind,size:B.size,persisted:B.persisted,...typeof B.mimeType==="string"?{mimeType:B.mimeType.slice(0,256)}:{},...typeof B.sourceUri==="string"?{sourceUri:B.sourceUri.slice(0,8192)}:{},...typeof B.path==="string"?{path:B.path.slice(0,8192)}:{}}]}):[];$.mcpResult={isError:J.isError===!0,contentCount:Y(J.contentCount,64),textBytes:Y(J.textBytes,4194304),structuredBytes:Y(J.structuredBytes,4194304),artifactCount:Y(J.artifactCount,64),truncated:J.truncated===!0,binaryOmitted:J.binaryOmitted===!0,artifacts:K}}else delete $.mcpResult;return $};function Sw(O){let x=typeof O.seq==="number"?{seq:O.seq}:{};if(O.type==="part_created"&&O.data.partType==="tool_call"){let $=O.data.payload;return{type:"tool.start",...x,properties:{messageId:O.data.messageId,toolCallId:$.toolCallId??O.data.partId,toolName:$.toolName??"unknown",arguments:JSON.stringify($.input??{})}}}if(O.type==="part_created"&&O.data.partType==="tool_result"){let $=O.data.payload,w=$.toolName??"unknown",Q=qx($),Y=y0(m0(w,Q),P0);return{type:"tool.result",...x,properties:{messageId:O.data.messageId,toolCallId:$.toolCallId??O.data.partId,toolName:w,success:Q.success,status:Q.success?"completed":"failed",summary:Q.metadata?.summary,output:h0(Y),metadata:f0(w,Q.metadata)}}}return{type:`committed.${O.type}`,...x,properties:{event:O}}}function jw(O,x,$){switch($.kind){case"tool_start":if("function"in $.toolCall)q.publish(O,"subagent.update",{subagentSessionId:x,toolName:$.toolCall.function.name}),q.publish(O,"subagent.tool.start",{subagentSessionId:x,toolCallId:$.toolCall.id,toolName:$.toolCall.function.name,arguments:$.toolCall.function.arguments,toolKind:$.toolKind});break;case"tool_result":if("function"in $.toolCall)q.publish(O,"subagent.tool.result",{subagentSessionId:x,toolCallId:$.toolCall.id,toolName:$.toolCall.function.name,success:$.result.success,summary:$.result.metadata?.summary,output:h0(y0(m0($.toolCall.function.name,$.result),P0)),metadata:f0($.toolCall.function.name,$.result.metadata)});break;case"tool_progress":if("function"in $.toolCall)q.publish(O,"subagent.tool.progress",{subagentSessionId:x,toolCallId:$.toolCall.id,toolName:$.toolCall.function.name,...$.update});break;case"content_delta":q.publish(O,"subagent.delta",{subagentSessionId:x,delta:$.delta});break;case"thinking_delta":q.publish(O,"subagent.thinking.delta",{subagentSessionId:x,delta:$.delta});break;case"stream_end":q.publish(O,"subagent.stream.end",{subagentSessionId:x});break;case"provider_admission":q.publish(O,"subagent.provider.admission",{subagentSessionId:x,phase:$.phase,requestClass:$.requestClass,resource:$.resource,scope:$.scope,reason:$.reason,queuePosition:$.queuePosition,queueDepth:$.queueDepth,inFlight:$.inFlight,limit:$.limit,waitMs:$.waitMs,maxWaitMs:$.maxWaitMs,recoveryRemainingMs:$.recoveryRemainingMs});break;case"provider_circuit":q.publish(O,"subagent.provider.circuit",{subagentSessionId:x,phase:$.phase,reason:$.reason,statusCode:$.statusCode,retryAfterMs:$.retryAfterMs,nextProbeAt:$.nextProbeAt,openDurationMs:$.openDurationMs,sampleCount:$.sampleCount,failureCount:$.failureCount,recoveryRemainingMs:$.recoveryRemainingMs});break;case"provider_retry":q.publish(O,"subagent.provider.retry",{subagentSessionId:x,phase:$.phase,attempt:$.attempt,maxRetries:$.maxRetries,reason:$.reason,statusCode:$.statusCode,delayMs:$.delayMs,nextRetryAt:$.nextRetryAt,mode:$.mode,recoveryBudgetMs:$.recoveryBudgetMs,recoveryElapsedMs:$.recoveryElapsedMs,recoveryRemainingMs:$.recoveryRemainingMs,exhaustedBy:$.exhaustedBy});break;case"provider_stall":q.publish(O,"subagent.provider.stall",{subagentSessionId:x,phase:$.phase,stallCount:$.stallCount,durationMs:$.durationMs,warningAfterMs:$.warningAfterMs,timeoutMs:$.timeoutMs,outputStarted:$.outputStarted});break;case"action_stationarity":q.publish(O,"subagent.action.stationarity",{subagentSessionId:x,phase:$.phase,toolName:$.toolName,runLength:$.runLength,nudgeThreshold:$.nudgeThreshold,haltThreshold:$.haltThreshold,progressAware:$.progressAware});break;case"mcp_catalog_changed":q.publish(O,"subagent.mcp.catalog.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,added:$.added,removed:$.removed,updated:$.updated});break;case"mcp_content_changed":q.publish(O,"subagent.mcp.content.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,contentKind:$.contentKind,added:$.added,removed:$.removed,updated:$.updated});break;case"mcp_resource_updated":q.publish(O,"subagent.mcp.resource.updated",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,uri:$.uri});break;case"mcp_connection_changed":q.publish(O,"subagent.mcp.connection.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,phase:$.phase,reason:$.reason,attempt:$.attempt,maxAttempts:$.maxAttempts,nextRetryAt:$.nextRetryAt,error:$.error});break;case"mcp_log":q.publish(O,"subagent.mcp.log",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,level:$.level,logger:$.logger,message:$.message,projectedBytes:$.projectedBytes,dataSha256:$.dataSha256,truncated:$.truncated,detailsOmitted:$.detailsOmitted,timestamp:$.timestamp,synthetic:$.synthetic});break;case"mcp_instructions_changed":q.publish(O,"subagent.mcp.instructions.changed",{subagentSessionId:x,revision:$.revision,serverName:$.serverName,action:$.action,reason:$.reason,text:$.text,sourceBytes:$.sourceBytes,projectedBytes:$.projectedBytes,sha256:$.sha256,truncated:$.truncated,detailsOmitted:$.detailsOmitted});break;case"mcp_task_changed":q.publish(O,"subagent.mcp.task.changed",{subagentSessionId:x,revision:$.revision,taskId:$.taskId,serverName:$.serverName,toolName:$.toolName,status:$.status,statusMessage:$.statusMessage,createdAt:$.createdAt,updatedAt:$.updatedAt,completedAt:$.completedAt,hasResult:$.hasResult,error:$.error});break;case"project_rules_loaded":q.publish(O,"subagent.project.rules.loaded",{subagentSessionId:x,files:$.files,triggerPaths:$.triggerPaths,blockedWrite:$.blockedWrite});break;default:break}}function I0(O,x="projectPath"){if(!E1.isAbsolute(O))throw new _(`${x} must be absolute`);return E1.resolve(O)}function Tx(O){try{o0(O)}catch(x){throw new _(x instanceof Error?x.message:`Invalid session ID: ${O}`)}}function XO(O){return{sessionId:O.id,projectPath:O.projectPath}}function E0(O,x,$){return{id:O.sessionId,projectPath:O.projectPath,title:O.title??`Session ${O.sessionId.slice(0,6)}`,createdAt:new Date(O.firstMessageTime),updatedAt:new Date(O.lastMessageTime),rootId:O.rootId,parentId:O.parentId,relationType:O.relationType,taskStatus:O.taskStatus,taskStatusReason:O.taskStatusReason,taskFailure:O.taskFailure,taskStartedAt:O.taskStartedAt,taskCompletedAt:O.taskCompletedAt,taskPromptSummary:O.taskPromptSummary,taskPriority:O.taskPriority,taskKind:O.taskKind,taskDueAt:O.taskDueAt,taskModelId:O.taskModelId,selectedModelId:O.selectedModelId,permissionMode:O.permissionMode,reasoningEffort:O.reasoningEffort,serviceTier:O.serviceTier,responseVerbosity:O.responseVerbosity,communicationStyle:O.communicationStyle,communicationStyleDigest:O.communicationStyleDigest,projectInstructionsDigest:O.projectInstructionsDigest,pendingInteraction:O.pendingInteraction,taskRetryAvailable:O.taskRetryAvailable,taskRetriedFrom:O.taskRetriedFrom,taskDelivery:O.taskDelivery,taskIsolation:O.taskIsolation,taskSourceProjectPath:O.taskSourceProjectPath,taskWorktreePath:O.taskWorktreePath,taskWorktreeBranch:O.taskWorktreeBranch,taskBaseCommit:O.taskBaseCommit,taskDiffStat:O.taskDiffStat,taskQueuePosition:O.taskQueuePosition,taskQueueDepth:O.taskQueueDepth,taskConcurrencyLimit:O.taskConcurrencyLimit,archivedAt:O.archivedAt,archivedBySessionId:O.archivedBySessionId,taskWorktree:$,messages:x}}function Kx(O){return O.flatMap((x)=>{if(!t1(x)||x.role==="system"||x.role==="tool"&&x.name===X0)return[];let $=x.tool_calls?.filter((J)=>!("function"in J)||J.function.name!==X0),w=typeof x.content==="string"?x.content.trim():"";if(x.role==="assistant"&&x.tool_calls?.length&&!$?.length&&!w&&!x.reasoningContent&&!x.metadata)return[];let Q={...x,...x.tool_calls?{tool_calls:$&&$.length>0?$:void 0}:{}};if(x.role==="tool"){let J=x.metadata&&typeof x.metadata==="object"&&!Array.isArray(x.metadata)?x.metadata:void 0,K=x.name??(typeof J?.toolName==="string"?J.toolName:"unknown");if(J!==void 0&&(Object.hasOwn(J,"output")||Object.hasOwn(J,"error"))){let B=qx(J),A=y0(m0(K,B),P0);return[{...Q,name:K,content:h0(A),metadata:f0(K,{...B.metadata,status:B.success?"completed":"failed"})}]}return[{...Q,name:K,metadata:f0(K,J)}]}let Y=r1(x.metadata);return[Y?{...Q,content:s1(Y)}:Q]})}function O0(O,x){O.title=x.title??O.title,O.taskStatus=x.taskStatus,O.taskStatusReason=x.taskStatusReason,O.taskFailure=x.taskFailure,O.taskStartedAt=x.taskStartedAt,O.taskCompletedAt=x.taskCompletedAt,O.taskPromptSummary=x.taskPromptSummary,O.taskPriority=x.taskPriority,O.taskKind=x.taskKind,O.taskDueAt=x.taskDueAt,O.taskModelId=x.taskModelId,O.selectedModelId=x.selectedModelId,O.permissionMode=x.permissionMode,O.reasoningEffort=x.reasoningEffort,O.serviceTier=x.serviceTier,O.responseVerbosity=x.responseVerbosity,O.communicationStyle=x.communicationStyle,O.communicationStyleDigest=x.communicationStyleDigest,O.projectInstructionsDigest=x.projectInstructionsDigest,O.pendingInteraction=x.pendingInteraction,O.taskRetryAvailable=x.taskRetryAvailable,O.taskRetriedFrom=x.taskRetriedFrom,O.taskDelivery=x.taskDelivery,O.taskIsolation=x.taskIsolation,O.taskSourceProjectPath=x.taskSourceProjectPath,O.taskWorktreePath=x.taskWorktreePath,O.taskWorktreeBranch=x.taskWorktreeBranch,O.taskBaseCommit=x.taskBaseCommit,O.taskDiffStat=x.taskDiffStat,O.taskQueuePosition=x.taskQueuePosition,O.taskQueueDepth=x.taskQueueDepth,O.taskConcurrencyLimit=x.taskConcurrencyLimit,O.archivedAt=x.archivedAt,O.archivedBySessionId=x.archivedBySessionId,O.updatedAt=new Date(x.lastMessageTime)}async function dO(O){let x=await C.findSessionMetadata(O.id,O.projectPath);if(x)O0(O,x)}function tO(O){let x=FO(O.currentRunId),$=x?.status==="waiting_permission"?"running":x?.status==="attention_required"?"interrupted":x?.status??O.taskStatus;return{sessionId:O.id,projectPath:O.projectPath,title:O.title,rootId:O.rootId,parentId:O.parentId,relationType:O.relationType,status:void 0,taskStatus:$,taskStatusReason:O.taskStatusReason,taskFailure:O.taskFailure,taskStartedAt:O.taskStartedAt,taskCompletedAt:O.taskCompletedAt,taskPromptSummary:O.taskPromptSummary,taskPriority:O.taskPriority,taskKind:O.taskKind,taskDueAt:O.taskDueAt,taskModelId:O.taskModelId,selectedModelId:O.selectedModelId,permissionMode:O.permissionMode,reasoningEffort:O.reasoningEffort,serviceTier:O.serviceTier,responseVerbosity:O.responseVerbosity,communicationStyle:O.communicationStyle,communicationStyleDigest:O.communicationStyleDigest,projectInstructionsDigest:O.projectInstructionsDigest,taskRetryAvailable:O.taskRetryAvailable,taskRetriedFrom:O.taskRetriedFrom,taskDelivery:O.taskDelivery,taskIsolation:O.taskIsolation,taskSourceProjectPath:O.taskSourceProjectPath,taskWorktreePath:O.taskWorktreePath,taskWorktreeBranch:O.taskWorktreeBranch,taskBaseCommit:O.taskBaseCommit,taskDiffStat:O.taskDiffStat,taskQueuePosition:$==="queued"?O.taskQueuePosition:void 0,taskQueueDepth:$==="queued"?O.taskQueueDepth:void 0,taskConcurrencyLimit:O.taskConcurrencyLimit,archivedAt:O.archivedAt,archivedBySessionId:O.archivedBySessionId,pendingInteraction:x?.pendingPermission?{type:x.pendingPermission.details.type==="askUserQuestion"?"question":x.pendingPermission.details.type==="mcpElicitation"?"elicitation":"permission",requestId:x.pendingPermission.permissionId}:O.pendingInteraction,agentType:void 0,model:void 0,messageCount:O.messages.length,firstMessageTime:O.createdAt.toISOString(),lastMessageTime:O.updatedAt.toISOString(),hasErrors:!1,isActive:!0}}async function VO(O,x){if(Tx(O),x!==void 0){let w=pO({sessionId:O,projectPath:I0(x)});if(OO.has(m(w)))return w;let Q=await C.findSessionMetadata(w.sessionId,w.projectPath);if(!Q)throw new y("Session",O);return pO({sessionId:Q.sessionId,projectPath:Q.projectPath})}let $=new Map;for(let w of OO.values()){if(w.id!==O)continue;let Q=XO(w);$.set(m(Q),Q)}for(let w of await C.listSessions()){if(w.sessionId!==O)continue;let Q=pO({sessionId:w.sessionId,projectPath:w.projectPath});$.set(m(Q),Q)}if($.size===0)try{let w=await C.findSessionMetadata(O);if(!w)throw new y("Session",O);return pO({sessionId:w.sessionId,projectPath:w.projectPath})}catch(w){if(w instanceof y)throw w;if(w instanceof Error&&w.message.startsWith("Ambiguous session ID:"))throw new bO;throw w}if($.size>1)throw new bO;return $.values().next().value}function Rx(O){if(typeof O==="string")return O;return O.filter((x)=>x.type==="text").map((x)=>x.text).join(`
|
|
7
|
+
`)}function f1(O,x){let $=(x??[]).filter((Q)=>Q.type==="image"&&typeof Q.content==="string").map((Q)=>({type:"image_url",image_url:{url:Q.content}}));if($.length===0)return O;let w=[];if(O.trim())w.push({type:"text",text:O});return w.push(...$),w}var F4=()=>{bw();let O=new Xw;O.onError((Z,G)=>{if(Z instanceof N0){let N=new PO("Session runtime capacity is full",{resource:Z.resource,limit:Z.limit});return G.json(N.toObject(),429)}if(Z instanceof r)return G.json(Z.toObject(),Z.statusCode);return g.error("[SessionRoutes] Unhandled route error:",Z),G.json({error:{code:"INTERNAL_ERROR",message:"Internal server error"}},500)});let x=new Map,$=new Bx,w=new Map,Q=new Map,Y=new Map,J=new _x,K=new _x,S=YO(),B=new K4({maxResident:S?.maxResidentSessionRuntimes??m1,idleMs:S?.sessionRuntimeIdleMs??h1}),A=new J4,H=setInterval(()=>{B.sweepIdle().catch((Z)=>{g.warn("[SessionRoutes] Session Runtime idle sweep failed:",Z)})},g1);H.unref?.();let U,R=async(Z)=>{let G;try{G=A.enter()}catch{throw new yO}try{return await Z()}finally{G.release()}};O.use("*",async(Z,G)=>{if(Z.req.method==="GET"||Z.req.method==="HEAD")return G();return R(G)});let c=(Z,G)=>J.runExclusive(m(Z),G),l=(Z,G)=>K.runExclusive(m(Z),G),JO=(Z)=>[...CO.values()].some((G)=>G.sessionId===Z.sessionId&&G.projectPath===Z.projectPath&&_O(G)),T=async(Z,G,N)=>{let X=Q.get(G);if(!X)X=(async()=>{if(x.get(G)===N)x.delete(G);for(let[L,F]of x)if(F===N)x.delete(L);let V=XO(Z);if(OO.get(G)===Z&&!JO(V)&&!mO.has(G)&&!qO.has(G))OO.delete(G);if(await N.dispose(),x.size===0)await KO.getInstance().disconnectAll()})().finally(()=>{if(Q.get(G)===X)Q.delete(G)}),Q.set(G,X);await X},NO=async(Z,G={})=>{let N=XO(Z),X=m(N);await Q.get(X);let V=B.acquire(X);if(V){if(x.get(X)!==V.value)throw V.release(),Error("Session Runtime residency identity is inconsistent");return V}if(B.owns(X))throw new N0(B.getStats().maxResident);let L=w.get(X);if(!L){let F=G.communicationStyle??Z.communicationStyle;L=(async()=>{let D=await B.reserve(X,{surface:"web",allowEviction:!0});try{let b=await sO.create({sessionId:Z.id,workspaceRoot:Z.projectPath,permissionMode:G.permissionMode??Z.permissionMode??"default",...Z.reasoningEffort?{reasoningEffort:Z.reasoningEffort}:{},...Z.serviceTier?{serviceTier:Z.serviceTier}:{},...Z.responseVerbosity?{responseVerbosity:Z.responseVerbosity}:{},...F?{communicationStyle:F}:{},...F===Z.communicationStyle&&Z.communicationStyleDigest?{communicationStyleDigest:Z.communicationStyleDigest}:{},...Z.projectInstructionsDigest?{projectInstructionsDigest:Z.projectInstructionsDigest}:{},...Z.taskWorktree?{taskWorktree:Z.taskWorktree}:{},...Z.taskIsolation?{taskIsolation:Z.taskIsolation}:{},...Z.messages.length>0?{sessionStart:{isResume:!0,resumeSessionId:Z.id}}:{}}),j=b.getCurrentModelId();if(j&&(Z.selectedModelId||Z.taskModelId)&&j!==Z.selectedModelId){let I=await C.updateSessionMetadata(Z.id,Z.projectPath,{selectedModelId:j}).catch((QO)=>{g.warn(`[SessionRoutes] Failed to migrate restored model for ${Z.id}:`,QO);return});if(I)Z.selectedModelId=I.selectedModelId,Z.updatedAt=new Date(I.lastMessageTime)}let M=D.commit({key:X,surface:"web",value:b,canEvict:()=>!JO(N)&&!mO.has(X)&&!qO.has(X)&&!w.has(X)&&!Q.has(X)&&b.isIdleForResidency(),dispose:()=>T(Z,X,b)});return x.set(X,b),{runtime:b,claimLease:()=>{if(M){let QO=M;return M=void 0,QO}let I=B.acquire(X);if(!I||I.value!==b)throw Error("Initialized Session Runtime lost residency");return I}}}catch(b){if(D.cancel(),b instanceof w4)throw new c0(b.reason);throw b}})(),w.set(X,L)}try{return(await L).claimLease()}finally{if(w.get(X)===L)w.delete(X)}},p=async(Z,G,N={})=>{let X=await NO(Z,N);try{return await G(X.value)}finally{X.release()}},v=async(Z,G)=>{let N=m(XO(Z)),X=w.get(N);if(X)await X.catch(()=>{return});w.delete(N);let V=G??x.get(N);if(!V)return;if(!await B.remove(N,V))throw Error(`Session Runtime is pinned and cannot be disposed: ${N}`)},ZO=async(Z)=>{let G=m(Z),N=OO.get(G);if(N)return N;let X=Y.get(G);if(!X)X=(async()=>{let V=await C.findSessionMetadata(Z.sessionId,Z.projectPath);if(!V)throw new y("Session",Z.sessionId);let[L,F]=await Promise.all([C.loadSession(Z.sessionId,Z.projectPath),C.findSessionTaskWorktree(Z.sessionId,Z.projectPath)]),D=E0(V,L,F);return OO.set(G,D),D})(),Y.set(G,X);try{return await X}finally{if(Y.get(G)===X)Y.delete(G)}},wO=async(Z,G)=>{let N=await VO(Z,G);try{await C.assertSessionWritable(N.sessionId,N.projectPath)}catch(X){if(X instanceof bx)throw new k(X.message);throw X}return ZO(N)},IO=async(Z,G)=>{if(Z.permissionMode===G)return;let N=await C.setSessionPermissionMode(Z.id,Z.projectPath,G);Z.permissionMode=N.permissionMode,Z.updatedAt=new Date(N.lastMessageTime),q.publish(XO(Z),"session.updated",{permissionMode:G})},xO=(Z,G,N,X={})=>{if(!A.stats().accepting)throw new yO;let V=W0(12),L={id:V,sessionId:Z.id,projectPath:Z.projectPath,status:"running",abortController:new AbortController,disposeRuntimeOnSettle:Z.taskIsolation!==void 0&&X.runtimeLease!==void 0,createdAt:new Date};if(Z.taskIsolation&&X.runtimeLease){let F=X.runtimeLease.value,D=gO.admit({key:`${Z.projectPath}\x00${Z.id}`,...F.getTaskAdmissionLimits(),pendingBytes:Y4({content:G,outputSchema:X.outputSchema,pendingMessages:F.getPendingSteeringMessages()}),signal:L.abortController.signal,onUpdate:(j)=>{L.status=j.state,Z.taskStatus=j.state,Z.taskQueuePosition=j.queuePosition,Z.taskQueueDepth=j.queueDepth,Z.taskConcurrencyLimit=j.maxConcurrent,L.taskAdmissionUpdate=(L.taskAdmissionUpdate??Promise.resolve()).then(async()=>{await F.setTaskAdmission(j)}).catch((M)=>{g.warn(`[SessionRoutes] Failed to persist admission for ${Z.id}:`,M)})}});L.taskAdmission=D;let b=D.getSnapshot();L.status=b.state,Z.taskStatus=b.state,Z.taskQueuePosition=b.queuePosition,Z.taskQueueDepth=b.queueDepth,Z.taskConcurrencyLimit=b.maxConcurrent}return CO.set(V,L),Z.currentRunId=V,L.completion=Mw(L,Z,G,N,NO,{pendingInputOnly:X.pendingInputOnly,preparedInputTurn:X.preparedInputTurn,goalContinuationOnly:X.goalContinuationOnly,outputSchema:X.outputSchema,taskAdmission:L.taskAdmission,runtimeLease:X.runtimeLease,disposeRuntime:v}).catch((F)=>{g.error(`[SessionRoutes] Run ${V} failed:`,F)}),L},aO=async(Z)=>{let G;if(Z.outputSchema)try{G=Hx(Z.outputSchema).schema}catch(u){throw new _(u instanceof Error?u.message:"Invalid output schema")}let N=Lx("task",12),X=I0(Z.sourceProjectPath),V=Z.modelId?.trim(),L=YO();if(!L)throw new _("Config not initialized");let[F,D]=await Promise.all([s0(X,L),TO(X)]);if(V&&!F.config.models.some((u)=>u.id===V))throw new _(`Task model not found: ${V}`);let b=V||F.config.models.find((u)=>u.id===F.config.currentModelId)?.id||F.config.models[0]?.id;if(!b)throw new _("No model is configured. Add or select a model before dispatching a task.");let j=F.config.models.find((u)=>u.id===b);if(!j)throw new _(`Task model not found: ${b}`);let M=Z.reasoningEffort??"off",I=Z.serviceTier??"auto",QO=Z.responseVerbosity??"auto",HO=Z.communicationStyle??"auto",MO,zO=D.projectRules?.staticRules(X),$O=zO&&zO.files.length>0?zO.provenanceSha256:void 0;try{let u=F.catalog.resolveConfig(j);u1(u,M),y1(u,I),P1(u,QO);let i=p1(HO,D.communicationStyles);MO=i.source==="built-in"?void 0:i.contentSha256}catch(u){throw new _(u instanceof Error?u.message:"Invalid reasoning effort")}let w0={version:1,prompt:Z.prompt,...Z.title?{title:Z.title}:{},...Z.taskPriority?{taskPriority:Z.taskPriority}:{},...Z.taskKind?{taskKind:Z.taskKind}:{},...Z.taskDueAt?{taskDueAt:Z.taskDueAt}:{},sourceProjectPath:X,isolation:Z.isolation,permissionMode:Z.permissionMode,modelId:b,reasoningEffort:M,serviceTier:I,responseVerbosity:QO,communicationStyle:HO,...MO?{communicationStyleDigest:MO}:{},...$O?{projectInstructionsDigest:$O}:{},...Z.attachments?{attachments:Z.attachments.map((u)=>({...u}))}:{},...G?{outputSchema:G}:{}},E,h,P;try{let u=await W4.createSessionTask({sessionId:N,prompt:Z.prompt,title:Z.title,taskPriority:Z.taskPriority,taskKind:Z.taskKind,taskDueAt:Z.taskDueAt,sourceProjectPath:X,isolation:Z.isolation,dispatch:w0,retriedFrom:Z.retriedFrom}),{metadata:i}=u;E=u.taskWorktree,h=E0(i,[],E);let d=XO(h);OO.set(m(d),h),q.publish(d,"task.status",{taskStatus:i.taskStatus,updatedAt:i.lastMessageTime});let a=f1(Z.prompt,Z.attachments);P=await NO(h);let hO=P.value,n=G?await hO.prepareInputTurn(a,{outputSchema:G}):await hO.prepareInputTurn(a);if(!n.accepted)throw new k(`Task prompt was not accepted: ${n.reason}`);let WO=xO(h,a,Z.permissionMode,{preparedInputTurn:n,runtimeLease:P,outputSchema:G});return P=void 0,await WO.taskAdmissionUpdate,{session:tO(h),runId:WO.id,messageId:n.messageId,status:WO.status==="queued"?"queued":"running",queuePosition:h.taskQueuePosition,queueDepth:h.taskQueueDepth,maxConcurrentTasks:h.taskConcurrencyLimit}}catch(u){if(P?.release(),P=void 0,(u instanceof Mx||u instanceof N0)&&h){let i=XO(h),d=m(i);if(E)await fO.exit({sessionId:h.id,action:"remove",discardChanges:!0}).catch(()=>{return});throw await v(h).catch(()=>{return}),await C.deleteSession(h.id,h.projectPath).catch(()=>{return}),OO.delete(d),new PO(u instanceof N0?"Session runtime capacity is full":"Task admission capacity is full",{resource:u.resource,limit:u.limit})}if(h){let i=await C.findSessionMetadata(h.id,h.projectPath).catch(()=>{return});if(!i||i.taskStatus==="queued"){let d=e0(u),a=await C.updateSessionMetadata(h.id,h.projectPath,{taskStatus:"failed",taskStatusReason:d.message,taskFailure:d,taskCompletedAt:new Date().toISOString(),taskOwnerPid:null}).catch(()=>{return});h.taskStatus=a?.taskStatus??"failed",h.taskStatusReason=a?.taskStatusReason??d.message,h.taskFailure=a?.taskFailure??d,h.taskCompletedAt=a?.taskCompletedAt}else h.taskStatus=i.taskStatus,h.taskStatusReason=i.taskStatusReason,h.taskFailure=i.taskFailure,h.taskCompletedAt=i.taskCompletedAt}throw u}},LO=(Z)=>R(()=>aO(Z)),z=async(Z,G)=>{let N=await VO(Z,G),X=await C.findSessionMetadata(N.sessionId,N.projectPath);if(!X)throw new y("Session",N.sessionId);if(!["failed","interrupted","cancelled"].includes(X.taskStatus))throw new k(`Task cannot be retried while status is ${X.taskStatus}`);let V=await C.findSessionTaskDispatch(N.sessionId,N.projectPath);if(!V)throw new k("Task retry payload is unavailable");return LO({prompt:V.prompt,title:X.title??V.title,taskPriority:X.taskPriority??V.taskPriority,taskKind:X.taskKind??V.taskKind,taskDueAt:X.taskDueAt,sourceProjectPath:V.sourceProjectPath,isolation:V.isolation,permissionMode:V.permissionMode,modelId:V.modelId,reasoningEffort:V.reasoningEffort,serviceTier:V.serviceTier,responseVerbosity:V.responseVerbosity,communicationStyle:V.communicationStyle,attachments:V.attachments,outputSchema:V.outputSchema,retriedFrom:N})},UO=(Z,G)=>R(()=>z(Z,G)),cx=(Z,G,N)=>R(async()=>{let X=await VO(Z,N);if(!await C.findSessionMetadata(X.sessionId,X.projectPath))throw new y("Session",X.sessionId);let L=await C.updateSessionMetadata(X.sessionId,X.projectPath,G),F=OO.get(m(X));if(F)O0(F,L);return q.publish(X,"session.updated",{...L.title?{title:L.title}:{},...L.taskPriority?{taskPriority:L.taskPriority}:{},...L.taskKind?{taskKind:L.taskKind}:{},taskDueAt:L.taskDueAt??null}),F?tO(F):{...L,isActive:!1}}),Jx=async(Z,G)=>{let N=await wO(Z,G);if(!N.taskWorktree)throw new _("Session does not have a task worktree");try{await fO.restoreSession(N.taskWorktree);let X=await fO.getDiffArtifact(N.id);if(!X)throw new k("Task diff artifact is unavailable");return{sessionId:N.id,projectPath:N.projectPath,...X}}catch(X){if(X instanceof k)throw X;throw g.error("[SessionRoutes] Failed to load task diff artifact:",X),new k("Task diff artifact is unavailable")}},H0=async(Z,G,N)=>{let X=await VO(Z,N);return l(X,async()=>{let V=await wO(X.sessionId,X.projectPath);if(["queued","running"].includes(V.taskStatus))throw new k(`Task artifacts cannot be delivered while status is ${V.taskStatus}`);if(V.taskDelivery?.status==="applied")throw new k("Task changes have already been applied");if(V.taskDelivery?.status==="discarded")throw new k("Task changes have already been discarded");if(!V.taskWorktree)throw new k("Task worktree is unavailable");let L=async(F,D=!1)=>{let b=await C.updateSessionMetadata(V.id,V.projectPath,{taskDelivery:F,...D?{taskWorktree:null}:{}});if(O0(V,b),D)V.taskWorktree=void 0;return q.publish(X,"task.delivery",{taskDelivery:F,...D?{taskWorktreeRemoved:!0}:{},updatedAt:b.lastMessageTime}),tO(V)};try{if(G==="discard"){try{await fO.restoreSession(V.taskWorktree)}catch(b){return g.warn(`[SessionRoutes] Abandoning unavailable task worktree for ${V.id}:`,b),L({status:"discarded",updatedAt:new Date().toISOString(),changedFiles:V.taskDiffStat?.changedFiles??0,message:"Task artifact discarded; worktree was unavailable"},!0)}let D=await fO.exit({sessionId:V.id,action:"remove",discardChanges:!0});return L({status:"discarded",updatedAt:new Date().toISOString(),changedFiles:D.discardedFiles??0,message:"Task worktree removed"},!0)}try{await fO.restoreSession(V.taskWorktree)}catch(D){throw g.warn(`[SessionRoutes] Task worktree is unavailable for ${V.id}:`,D),new jx("artifact_unavailable","Task worktree is unavailable")}let F=await fO.apply(V.id);return L({status:"applied",updatedAt:new Date().toISOString(),sourceCommit:F.sourceCommit,changedFiles:F.changedFiles,message:"Task changes applied to the source workspace"})}catch(F){if(F instanceof jx)throw await L({status:"conflicted",updatedAt:new Date().toISOString(),message:F.message}),new k(F.message);throw F}})},d0=(Z,G,N)=>R(()=>H0(Z,G,N)),v0=async(Z)=>{let G=FO(Z.currentRunId);if(_O(G))return;let N=Z.taskIsolation&&Z.taskStatus!=="queued"&&Z.taskStatus!=="running",X=N?await sO.hasRecoverableTurn(Z.projectPath,Z.id):!1;if(N&&!X)return;let V=await sO.hasPendingInbox(Z.projectPath,Z.id),L=!V&&await sO.hasActiveGoal(Z.projectPath,Z.id);if(!V&&!L&&!X)X=await sO.hasRecoverableTurn(Z.projectPath,Z.id);if(!V&&!L&&!X)return;let F=await NO(Z),D=!1;try{let b=F.value,j=FO(Z.currentRunId);if(_O(j))return;if(V&&b.getPendingSteeringCount()===0)await b.reloadPendingInbox();let M=b.getPendingSteeringCount()>0,I=M?null:await b.getGoal(),QO=I?.status==="active"||I?.status==="verifying",HO=b.getTurnRecoveryAssessment();if(HO.state!=="none"&&(HO.state==="requires_attention"||!M&&!QO))q.publish({sessionId:Z.id,projectPath:Z.projectPath},"turn.recovery",{assessment:HO});if(HO.state==="requires_attention"||N||!M&&!QO||b.hasTurnOwner())return;xO(Z,"",Z.permissionMode??"default",{pendingInputOnly:M,goalContinuationOnly:QO,runtimeLease:F}),D=!0}finally{if(!D)F.release()}},EO=async(Z)=>{let G;try{G=A.enter()}catch{return}try{await v0(Z)}finally{G.release()}};z0=EO;let Yx=async()=>{let Z={scheduled:0,failed:0,deferred:0};if(!A.stats().accepting)return Z;let G=(await C.listSessions({taskStatus:"queued"})).filter((N)=>N.taskIsolation!==void 0).sort((N,X)=>N.firstMessageTime.localeCompare(X.firstMessageTime)||N.projectPath.localeCompare(X.projectPath)||N.sessionId.localeCompare(X.sessionId));for(let[N,X]of G.entries()){let V={sessionId:X.sessionId,projectPath:X.projectPath};try{if(!await sO.hasPendingInbox(X.projectPath,X.sessionId)){let F=e0("Queued task input is missing");await C.updateSessionMetadata(X.sessionId,X.projectPath,{taskStatus:"failed",taskStatusReason:F.message,taskFailure:F,taskCompletedAt:new Date().toISOString(),taskOwnerPid:null,taskQueuePosition:null,taskQueueDepth:null}),Z.failed++;continue}let L=await ZO(V);if(await EO(L),L.currentRunId)Z.scheduled++}catch(L){if(L instanceof Mx||L instanceof N0){Z.deferred+=G.length-N;break}g.warn(`[SessionRoutes] Failed to recover queued task ${X.sessionId}:`,L),Z.deferred++}}return Z};return O.route("/",I1({withAdmission:R,resolveSessionRef:async(Z,G)=>{let N=await VO(Z,G);return await ZO(N),N},getRuntime:(Z)=>$.get(Z),captureAgentScreenshot:async(Z,G)=>{let N=await ZO(Z);return p(N,(X)=>X.captureBrowserScreenshot(G))},resetRuntime:(Z)=>$.reset(Z)})),O.get("/",async(Z)=>{try{let G=await C.listSessions(),N=new Set(G.filter((j)=>j.relationType==="subagent").map((j)=>m({sessionId:j.sessionId,projectPath:j.projectPath}))),X=Array.from(OO.values()).filter((j)=>!N.has(m(XO(j)))&&j.relationType!=="subagent").map((j)=>tO(j)),V=new Set(X.map((j)=>m({sessionId:j.sessionId,projectPath:j.projectPath}))),L=G.filter((j)=>{if(j.relationType==="subagent")return!1;return!V.has(m({sessionId:j.sessionId,projectPath:j.projectPath}))}),F=new Set(V),D=L.filter((j)=>{let M=m({sessionId:j.sessionId,projectPath:j.projectPath});if(F.has(M))return!1;return F.add(M),!0}),b=[...X,...D];return Z.json(b)}catch(G){throw g.error("[SessionRoutes] Failed to list sessions:",G),new s("Failed to list sessions")}}),O.get("/catalog",async(Z)=>{try{let G=Z.req.query("limit"),N=G===void 0?void 0:Number(G),X=Z.req.query("cursor"),V=Z.req.query("projectPath"),L=Z.req.query("archived");if(L!==void 0&&L!=="true"&&L!=="false")throw new _("archived must be true or false");let F=L==="true",D=await C.listSessionPage({...V?{cwd:I0(V)}:{},...X?{cursor:X}:{},...N===void 0?{}:{limit:N},includeSubagents:!1,archived:F}),b=new Map((F?[]:Array.from(OO.values())).filter((j)=>j.relationType!=="subagent").map((j)=>[m(XO(j)),tO(j)]));return Z.json({sessions:D.sessions.map((j)=>b.get(m({sessionId:j.sessionId,projectPath:j.projectPath}))??j),...D.nextCursor?{nextCursor:D.nextCursor}:{}})}catch(G){if(G instanceof _)throw G;if(G instanceof Error&&(G.message.startsWith("Invalid session cursor")||G.message.startsWith("Session cursor scope")||G.message.startsWith("Session catalog")))throw new _(G.message);throw g.error("[SessionRoutes] Failed to list session catalog:",G),new s("Failed to list session catalog")}}),O.post("/",async(Z)=>{try{let G=await Z.req.json(),N=f(Vw,G);if(!N.success)throw new _("Invalid request body");let{title:X,projectPath:V}=N.data,L=Lx("web",12),F=I0(V||Z.get("directory")||o(),V?"projectPath":"directory"),D=await C.createSessionMetadata(L,F,{title:X,taskStatus:"completed"}),b=E0(D,[]),j=XO(b);return OO.set(m(j),b),q.publish(j,"session.created",{}),Z.json({...tO(b),status:void 0,agentType:void 0,model:void 0})}catch(G){if(g.error("[SessionRoutes] Failed to create session:",G),G instanceof _)throw G;throw new s("Failed to create session")}}),O.get("/:sessionId/export",async(Z)=>{let G=Z.req.param("sessionId");try{let N=Z.req.query("includeReasoning");if(N!==void 0&&N!=="true"&&N!=="false")throw new _("includeReasoning must be true or false");let X=await VO(G,Z.req.query("projectPath")),V=await C.exportSessionMarkdown(X.sessionId,X.projectPath,{includeReasoning:N==="true"});return Z.body(V.markdown,200,{"Cache-Control":"no-store","Content-Disposition":`attachment; filename="${V.filename}"`,"Content-Length":String(Buffer.byteLength(V.markdown,"utf8")),"Content-Type":"text/markdown; charset=utf-8","X-Blade-Content-Sha256":V.contentSha256,"X-Blade-Export-Activities":String(V.activityCount),"X-Blade-Export-Messages":String(V.messageCount),"X-Blade-Export-Redactions":String(V.redactionCount)})}catch(N){if(N instanceof _||N instanceof y||N instanceof bO)throw N;if(N instanceof Error&&N.message==="No conversation content to export")throw new k(N.message);throw g.error("[SessionRoutes] Failed to export session:",N),new s("Failed to export session")}}),O.post("/:sessionId/fork",async(Z)=>{let G=Z.req.param("sessionId");try{Tx(G);let N=await Z.req.json(),X=f(Kw,N);if(!X.success)throw new _("Invalid request body");let V=I0(X.data.projectPath),L=await C.findSessionMetadata(G,V);if(!L)throw new y("Session",G);let F=await C.forkSession(G,{sourceProjectPath:L.projectPath,targetProjectPath:L.projectPath}),D=E0(F.metadata,F.messages),b=XO(D);return OO.set(m(b),D),q.publish(b,"task.status",{taskStatus:F.metadata.taskStatus,...F.metadata.taskCompletedAt?{taskCompletedAt:F.metadata.taskCompletedAt}:{},updatedAt:F.metadata.lastMessageTime}),Z.json({session:F.metadata,messages:Kx(F.messages)},201)}catch(N){if(N instanceof _||N instanceof y||N instanceof k)throw N;if(N instanceof e1)throw new k("Session has no durable creation record");throw g.error("[SessionRoutes] Failed to fork session:",N),new s("Failed to fork session")}}),O.get("/:sessionId",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N));if(X)return Z.json(tO(X));let V=await C.findSessionMetadata(N.sessionId,N.projectPath);if(!V)throw new y("Session",G);return Z.json(V)}catch(N){if(N instanceof _||N instanceof y||N instanceof bO)throw N;throw g.error("[SessionRoutes] Failed to get session:",N),new s("Failed to get session")}}),O.patch("/:sessionId",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await Z.req.json(),X=f(Uw,N);if(!X.success)throw new _("Invalid request body");if(X.data.title===void 0)throw new _("title is required");let V=await VO(G,X.data.projectPath),L=await C.updateSessionMetadata(V.sessionId,V.projectPath,{title:X.data.title}),F=OO.get(m(V));if(F)F.title=L.title??F.title,F.updatedAt=new Date(L.lastMessageTime);if(L.title)q.publish(V,"session.updated",{title:L.title});return Z.json({success:!0,title:L.title})}catch(N){if(g.error("[SessionRoutes] Failed to update session:",N),N instanceof _||N instanceof y||N instanceof bO)throw N;throw new s("Failed to update session")}}),O.get("/:sessionId/rewind",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath"));return p(G,async(N)=>Z.json({checkpoints:await N.listRewindCheckpoints()}))}),O.post("/:sessionId/rewind",async(Z)=>{let G=f(X4,await Z.req.json());if(!G.success)throw new _("Invalid rewind request");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=FO(N.currentRunId);if(_O(V))throw new k("Cannot rewind while a run is active");return p(N,async(L)=>{let F;try{F=await L.rewindSession(G.data)}catch(b){if(b instanceof Error&&b.message.startsWith("Cannot rewind while"))throw new k(b.message);throw b}N.messages=[...F.messages],N.updatedAt=new Date;let D=Kx(F.messages);return q.publish(X,"session.rewound",{targetMessageId:F.checkpoint.messageId,mode:F.mode,removedTurns:F.removedTurns,restoredFiles:F.restoredFiles,messages:D}),Z.json({...F,messages:D})})})}),O.get("/:sessionId/review",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath")),X=await rO.list(N.projectPath,N.sessionId);return Z.json({reviews:X.map((V)=>({...V,content:V.completion?o1(V.start,V.completion):void 0}))})}),O.post("/:sessionId/review",async(Z)=>{let G=Z.req.param("sessionId"),N=f(U4,await Z.req.json());if(!N.success)throw new _("Invalid code review request");let X=await wO(G,N.data.projectPath),V=XO(X),L=m(V);return c(V,async()=>{if(_O(FO(X.currentRunId)))throw new k("Cannot start a review during an active turn");if(qO.has(L))throw new k("Session already has an active review");return p(X,async(F)=>{if(await rO.recoverInterrupted(V.projectPath,V.sessionId,F),N.data.modelId&&!F.getModelById(N.data.modelId))throw new _(`Model not found: ${N.data.modelId}`);if(N.data.modelId&&F.getCurrentModelId()!==N.data.modelId)await F.refresh({modelId:N.data.modelId});if(N.data.modelId&&X.selectedModelId!==N.data.modelId){let M=await C.updateSessionMetadata(X.id,X.projectPath,{selectedModelId:N.data.modelId});O0(X,M)}let D=new AbortController,b;try{b=await rO.start({sessionId:V.sessionId,projectPath:V.projectPath,runtime:F,request:{kind:N.data.kind,...N.data.ref?{ref:N.data.ref}:{},...N.data.instructions?{instructions:N.data.instructions}:{}},signal:D.signal,onEvent:(M)=>{if(M.kind==="tool_start")q.publish(V,"review.tool.started",{reviewId:b?.reviewId,toolCallId:M.toolCall.id,toolName:M.toolCall.function.name});else if(M.kind==="tool_progress")q.publish(V,"review.tool.progress",{reviewId:b?.reviewId,toolCallId:M.toolCall.id,message:M.update.message.slice(0,1000)});else if(M.kind==="tool_result")q.publish(V,"review.tool.completed",{reviewId:b?.reviewId,toolCallId:M.toolCall.id,success:M.result.success})}})}catch(M){if(M instanceof Error&&(M.message.includes("active review")||M.message.includes("interrupted review")||M.message.includes("active turn")))throw new k(M.message);if(M instanceof Error&&(M.message.includes("review")||M.message.includes("Git")||M.message.includes("changes")||M.message.includes("ref")))throw new _(M.message);throw M}if(!b)throw new s("Code review failed to start");await dO(X),q.publish(V,"review.started",{reviewId:b.reviewId,kind:N.data.kind}),q.publish(V,"task.status",{taskStatus:X.taskStatus,...X.taskStatusReason?{taskStatusReason:X.taskStatusReason}:{},...X.taskStartedAt?{taskStartedAt:X.taskStartedAt}:{},...X.taskPromptSummary?{taskPromptSummary:X.taskPromptSummary}:{},updatedAt:new Date().toISOString()});let j=b.completion.then(async(M)=>{X.messages=await C.loadSession(V.sessionId,V.projectPath),await dO(X),q.publish(V,"task.status",{taskStatus:X.taskStatus,...X.taskStatusReason?{taskStatusReason:X.taskStatusReason}:{},...X.taskFailure?{taskFailure:X.taskFailure}:{},...X.taskStartedAt?{taskStartedAt:X.taskStartedAt}:{},...X.taskCompletedAt?{taskCompletedAt:X.taskCompletedAt}:{},...X.taskPromptSummary?{taskPromptSummary:X.taskPromptSummary}:{},updatedAt:new Date().toISOString()}),q.publish(V,"review.completed",{reviewId:b.reviewId,status:M.status,findings:M.findings.length})}).catch((M)=>{g.error(`[SessionRoutes] Code review ${b.reviewId} failed:`,M)}).finally(()=>{if(qO.get(L)?.reviewId===b.reviewId)qO.delete(L)});return qO.set(L,{reviewId:b.reviewId,controller:D,completion:j}),Z.json({reviewId:b.reviewId,status:"running"},202)})})}),O.get("/:sessionId/subagents",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath"));return p(G,(N)=>Z.json({subagents:N.listSubagents().map(r0)}))}),O.post("/:sessionId/subagents/:agentId/resume",async(Z)=>{Tx(Z.req.param("agentId"));let G=z4.safeParse(await Z.req.json());if(!G.success)throw new _("Invalid subagent resume request");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=FO(N.currentRunId);if(_O(V))throw new k("Cannot resume a subagent while a parent run is active");return p(N,async(L)=>{let F=!1,D,b=(M)=>{q.publish(X,"subagent.complete",{subagentSessionId:M.id,success:M.status==="completed",status:M.status,summary:M.result?.message?.slice(0,500),type:M.subagentType,verificationVerdict:M.result?.verificationVerdict,resumedFrom:M.resumedFrom,rootAgentId:M.rootAgentId,resumeDepth:M.resumeDepth})},j;try{j=L.resumeSubagent({agentId:Z.req.param("agentId"),prompt:G.data.prompt,onEvent:(M,I)=>{jw(X,I,M)},onCompleted:(M)=>{if(F)b(M);else D=M}})}catch(M){if(M instanceof Error&&(M.message.startsWith("Cannot resume")||M.message.startsWith("Subagent cannot")))throw new k(M.message);if(M instanceof Error&&M.message.startsWith("Subagent not found"))throw new y(M.message);throw M}if(q.publish(X,"subagent.start",{subagentSessionId:j.session.id,type:j.session.subagentType,description:j.session.description,resumedFrom:j.source.id,rootAgentId:j.session.rootAgentId,resumeDepth:j.session.resumeDepth}),F=!0,D)b(D);return Z.json({source:r0(j.source),session:r0(j.session)})})})}),O.get("/:sessionId/goal",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath"));return Z.json({goal:await new x4(G.projectPath,G.id).get()})}),O.put("/:sessionId/goal",async(Z)=>{let G=f(_w,await Z.req.json());if(!G.success)throw new _("Invalid goal request");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=FO(N.currentRunId);if(_O(V))return Z.json({status:"rejected",reason:"run_active"},409);let F=G.data.permissionMode??N.permissionMode??"default";if(N.permissionMode!==F)await IO(N,F);let D=await NO(N),b=!1;try{let j=await D.value.createGoal(G.data);q.publish(X,"goal.updated",{goal:j});let M=xO(N,"",F,{goalContinuationOnly:!0,runtimeLease:D});return b=!0,await M.taskAdmissionUpdate,Z.json({status:M.status==="queued"?"queued":"running",runId:M.id,goal:j,queuePosition:N.taskQueuePosition,queueDepth:N.taskQueueDepth,maxConcurrentTasks:N.taskConcurrencyLimit},202)}finally{if(!b)D.release()}})}),O.patch("/:sessionId/goal",async(Z)=>{let G=f(Fw,await Z.req.json());if(!G.success)throw new _("Invalid goal update");let N=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),X=XO(N);return c(X,async()=>{let V=await NO(N),L=!1;try{let F=V.value,D;if(G.data.action==="pause")D=await F.pauseGoal();else if(G.data.action==="edit")D=await F.editGoal(G.data.objective);else D=await F.resumeGoal();if(q.publish(X,"goal.updated",{goal:D}),D.status==="active"&&!_O(FO(N.currentRunId))){let b=xO(N,"","default",{goalContinuationOnly:!0,runtimeLease:V});return L=!0,await b.taskAdmissionUpdate,Z.json({status:b.status==="queued"?"queued":"running",runId:b.id,goal:D,queuePosition:N.taskQueuePosition,queueDepth:N.taskQueueDepth,maxConcurrentTasks:N.taskConcurrencyLimit},202)}return Z.json({status:D.status,goal:D})}finally{if(!L)V.release()}})}),O.delete("/:sessionId/goal",async(Z)=>{let G=await wO(Z.req.param("sessionId"),Z.req.query("projectPath")),N=XO(G);return p(G,async(X)=>{let V=await X.clearGoal();if(V)q.publish(N,"goal.cleared",{});return Z.json({cleared:V})})}),O.post("/:sessionId/archive",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=await C.listSessionArchiveMembers(N.sessionId,N.projectPath);for(let L of X){let F=pO({sessionId:L.sessionId,projectPath:L.projectPath}),D=OO.get(m(F));if(_O(FO(D?.currentRunId)))throw new k(`Stop session ${L.sessionId} before archiving this session tree`)}for(let L of X){let F=pO({sessionId:L.sessionId,projectPath:L.projectPath}),D=OO.get(m(F));if(D)await v(D)}let V=await C.archiveSession(N.sessionId,N.projectPath);for(let L of X){let F=pO({sessionId:L.sessionId,projectPath:L.projectPath}),D=m(F);OO.delete(D),Y.delete(D),w.delete(D),q.publish(F,"session.archived",{archiveRootId:N.sessionId,archivedAt:V.archivedAt})}if(x.size===0)await KO.getInstance().disconnectAll();return Z.json({session:V,archivedSessionIds:X.map((L)=>L.sessionId)})}catch(N){if(N instanceof _||N instanceof y||N instanceof bO||N instanceof k)throw N;if(N instanceof Ax)throw new k(N.message);throw g.error("[SessionRoutes] Failed to archive session:",N),new s("Failed to archive session")}}),O.post("/:sessionId/unarchive",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=await C.listSessionArchiveMembers(N.sessionId,N.projectPath),V=await C.unarchiveSession(N.sessionId,N.projectPath),L=X.filter((F)=>F.sessionId===N.sessionId||F.archivedBySessionId===N.sessionId).map((F)=>F.sessionId);for(let F of L)q.publish({sessionId:F,projectPath:N.projectPath},"session.unarchived",{archiveRootId:N.sessionId});return Z.json({session:V,restoredSessionIds:L})}catch(N){if(N instanceof _||N instanceof y||N instanceof bO)throw N;if(N instanceof Ax)throw new k(N.message);throw g.error("[SessionRoutes] Failed to unarchive session:",N),new s("Failed to unarchive session")}}),O.delete("/:sessionId",async(Z)=>{let G=Z.req.param("sessionId"),N=Z.req.query("projectPath");try{let X=await VO(G,N),V=m(X),L=OO.get(V),F=x.get(V),D=L?.taskWorktree??await C.findSessionTaskWorktree(X.sessionId,X.projectPath),b;if(L?.currentRunId){let I=FO(L.currentRunId);if(I)k0(I),await I.completion,b=I.id}let j=qO.get(V);if(j)j.controller.abort("session-delete"),await j.completion;if(F)await F.clearGoal().catch((I)=>{g.warn("[SessionRoutes] Failed to clear session goal:",I)});if(await $.dispose(X),await C.deleteSession(X.sessionId,X.projectPath),q.publish(X,"session.deleted",{}),b)Dw(b);OO.delete(V),Y.delete(V),w.delete(V);let M=x.get(V);if(M){if(!await B.remove(V,M))throw new k("Session Runtime is still active and cannot be deleted")}if(D)try{await fO.restoreSession(D),await fO.exit({sessionId:X.sessionId,action:"remove",discardChanges:!0})}catch(I){g.warn(`[SessionRoutes] Failed to remove deleted task worktree ${X.sessionId}:`,I)}return Z.json({success:!0})}catch(X){if(g.error("[SessionRoutes] Failed to delete session:",X),X instanceof _||X instanceof y||X instanceof bO)throw X;throw new s("Failed to delete session")}}),O.get("/:sessionId/message",async(Z)=>{let G=Z.req.param("sessionId");try{let N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N)),V=X?.messages?X.messages:await C.loadSession(N.sessionId,N.projectPath);return Z.json(Kx(V))}catch(N){if(g.error("[SessionRoutes] Failed to get messages:",N),N instanceof _||N instanceof y||N instanceof bO)throw N;throw new s("Failed to get messages")}}),O.get("/:sessionId/events",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath"));try{await C.assertSessionWritable(N.sessionId,N.projectPath)}catch(D){if(D instanceof bx)throw new k(D.message);throw D}let X=await ZO(N),V=Z.req.header("Last-Event-ID")??Z.req.query("lastEventId"),L=V?Number.parseInt(V,10):Number.NaN,F=Number.isInteger(L)?L+1:void 0;return zw(Z,async(D)=>{let j,M,I=!1,QO,HO,MO=new Promise((E)=>{HO=E}),zO=()=>{if(M!==void 0)clearInterval(M),M=void 0;j?.(),j=void 0},$O=(E)=>{if(I)return;I=!0,zO(),QO?.close(E),HO()},w0=new Set;D.onAbort($O),QO=new S0({write:async(E)=>{await D.writeSSE(E)},onFailure:(E)=>{g.warn(`[SessionRoutes] SSE egress closed for ${N.sessionId}: kind=${E.kind} pendingItems=${E.pendingItems??0} pendingBytes=${E.pendingBytes??0}`),$O(E)}}),j=q.subscribe((E)=>{if(E.sessionId!==N.sessionId||E.projectPath!==N.projectPath)return;let h=E.properties.requestId;if((E.type==="permission.asked"||E.type==="question.required"||E.type==="elicitation.required")&&typeof h==="string"){if(w0.has(h))return;w0.add(h)}if(E.type==="subagent.completion.queued")c(N,()=>EO(X)).catch((P)=>{g.error(`[SessionRoutes] Failed to wake background completion for ${X.id}:`,P)});if(E.type==="team.message.received"&&typeof E.properties.teamName==="string"&&typeof E.properties.messageId==="string"&&typeof E.properties.content==="string"&&Z4(E.properties.metadata,{messageId:E.properties.messageId,teamName:E.properties.teamName})){let P=E.properties.teamName,u=E.properties.messageId,i=E.properties.content,d=E.properties.metadata;c(N,async()=>{let a=await NO(X),hO=!1;try{let n=await a.value.enqueueSteering(i,{allowBeforeTurn:!0,messageId:u,origin:"team_message",metadata:d});if(!n.accepted)return;await new Q4(P,Ox()).markDelivered([u]),hO=n.delivery==="next_turn"}finally{a.release()}if(hO)await EO(X)}).catch((a)=>{g.error(`[SessionRoutes] Failed to deliver teammate message for ${X.id}:`,a)})}QO?.observe(Hw(E),E.seq)});try{if(D.aborted||I)return;let E=FO(X.currentRunId),h=_O(E)?await NO(X):void 0;try{let i=h?.value,d=i?.getPendingSteeringCount()??0;await QO.writeInitial({data:JSON.stringify({type:"connected",properties:{sessionId:N.sessionId,projectPath:N.projectPath,timestamp:Date.now(),status:_O(E)?E.status:"idle",runId:_O(E)?E.id:void 0,queued:d,pendingInputDelivery:d>0?i?.hasActiveTurn()?"current_turn":"next_turn":null,recovered:i?.getRecoveredSteeringCount()??0}})})}finally{h?.release()}if(D.aborted||I)return;if(F!==void 0){if(await $4.for(N.sessionId,N.projectPath).replay({onCommitted:async(d)=>{if(D.aborted||I)return;let a=Sw(d);if(a.seq===void 0)return;await QO.writeReplay({...typeof d.seq==="number"?{id:String(d.seq)}:{},data:JSON.stringify({type:a.type,...a.seq!==void 0?{seq:a.seq}:{},properties:{...a.properties,sessionId:N.sessionId,projectPath:N.projectPath}})},a.seq)}},F),D.aborted||I)return}if(QO.finishInitialization({replayed:F!==void 0}),D.aborted||I)return;if(!E&&!qO.has(m(N))){let d=(await rO.list(N.projectPath,N.sessionId)).some((a)=>a.completion===void 0)?await p(X,(a)=>rO.recoverInterrupted(N.projectPath,N.sessionId,a)):void 0;if(d)X.messages=await C.loadSession(N.sessionId,N.projectPath),await dO(X),q.publish(N,"review.completed",{reviewId:d.reviewId,status:d.status,findings:0,recovered:!0})}if(D.aborted||I)return;if(!E)await eO.recoverResponded(N.projectPath,N.sessionId);if(D.aborted||I)return;let P=E?void 0:await eO.findPending(N.projectPath,N.sessionId),u=E?.pendingPermission??(P?{permissionId:P.request.requestId,details:eO.confirmationDetails(P),resolve:()=>{return}}:void 0);if(u){w0.add(u.permissionId);let i=_4(u,!0);QO.observe({data:JSON.stringify({type:i.type,properties:{...i.properties,sessionId:N.sessionId,projectPath:N.projectPath}})})}if(D.aborted||I)return;if(EO(X).catch(async(i)=>{if(i instanceof c0){await dO(X).catch(()=>{return});let d=X.taskFailure?.code==="workspace_unavailable"?X.taskFailure:n1("workspace_unavailable");X.taskStatus="failed",X.taskStatusReason=d.message,X.taskFailure=d,q.publish(N,"session.error",{error:d.message,taskFailure:d}),q.publish(N,"session.status",{status:"error"})}g.error(`[SessionRoutes] Failed to resume pending input for ${G}:`,i)}),D.aborted||I)return;M=setInterval(()=>{if(D.aborted||I)return;QO?.offerHeartbeat({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})})},15000),await MO}finally{$O()}})}),O.post("/:sessionId/message",async(Z)=>{let G=Z.req.param("sessionId"),N=await Z.req.json(),X=f(Bw,N);if(!X.success)throw new _("Invalid message format");let{content:V,attachments:L,modelId:F,reasoningEffort:D,serviceTier:b,responseVerbosity:j,communicationStyle:M,permissionMode:I,projectPath:QO,outputSchema:HO}=X.data,MO;if(HO)try{MO=Hx(HO).schema}catch(d){throw new _(d instanceof Error?d.message:"Invalid output schema")}let zO=M;if(Buffer.byteLength(V,"utf8")>Fx)throw new _(`Message text exceeds the ${Fx}-byte limit`);let $O=F?.trim();if((L??[]).reduce((d,a)=>d+(typeof a.content==="string"?Buffer.byteLength(a.content):0),0)>xx)throw new _("Message attachments exceed the 5 MiB limit");let E=I,h=f1(V,L),P=await wO(G,QO??Z.req.query("projectPath")),u=E??P.permissionMode??"default",i=XO(P);return c(i,async()=>{let d=FO(P.currentRunId);if(_O(d)){if(MO)throw new k("Wait for the active turn to finish before setting an output schema");return p(P,async(n)=>{if($O&&!n.getModelById($O))throw new _(`Model not found: ${$O}`);if($O&&n.getCurrentModelId()!==$O)throw new k("Wait for the active turn to finish before switching models");if(D&&n.getReasoningConfiguration().selection!==D)throw new k("Wait for the active turn to finish before switching reasoning effort");if(b&&n.getServiceTierConfiguration().selection!==b)throw new k("Wait for the active turn to finish before switching service tier");if(j&&n.getResponseVerbosityConfiguration().selection!==j)throw new k("Wait for the active turn to finish before switching response verbosity");if(zO&&n.getCommunicationStyleConfiguration().selection!==zO)throw new k("Wait for the active turn to finish before switching communication style");if(E&&P.permissionMode!==E)throw new k("Wait for the active turn to finish before switching permission mode");let WO=await n.enqueueSteering(h,{allowBeforeTurn:!0});if(!WO.accepted)return Z.json({status:"rejected",reason:WO.reason??"turn_unavailable"},409);let oO=WO.messageId??W0(12),b0=WO.queued;q.publish(i,"message.created",{messageId:oO,role:"user",content:Rx(h)});let l0=WO.delivery==="next_turn"?"follow_up.queued":"steering.queued";if(q.publish(i,l0,{runId:d.id,messageId:oO,queued:b0}),WO.delivery==="next_turn"&&d.status!=="running"&&d.status!=="waiting_permission")EO(P).catch((i0)=>{g.error(`[SessionRoutes] Failed to wake queued follow-up for ${G}:`,i0)});if(WO.delivery==="next_turn")d.pendingFollowUpRequested=!0;return Z.json({runId:d.id,messageId:oO,status:WO.delivery==="next_turn"?"follow_up_queued":"steering_queued",queued:b0},202)})}if(P.permissionMode!==u)await IO(P,u);let a=await NO(P,{permissionMode:u,...zO&&!zO.includes(":")?{communicationStyle:zO}:{}}),hO=!1;try{let n=a.value;if($O&&!n.getModelById($O))throw new _(`Model not found: ${$O}`);if(D)try{n.resolveReasoningConfiguration(D,$O)}catch(GO){throw new _(GO instanceof Error?GO.message:"Invalid reasoning effort")}if(b)try{n.resolveServiceTierConfiguration(b,$O)}catch(GO){throw new _(GO instanceof Error?GO.message:"Invalid service tier")}if(j)try{n.resolveResponseVerbosityConfiguration(j,$O)}catch(GO){throw new _(GO instanceof Error?GO.message:"Invalid response verbosity")}let WO=zO?n.resolveCommunicationStyleConfiguration(zO):void 0;if(WO?.source!==void 0&&WO.source!=="built-in"&&!WO.contentSha256)throw new _("Custom communication style has no provenance");let oO=n.getCurrentModelId(),b0=n.getReasoningConfiguration(),l0=n.getServiceTierConfiguration(),i0=n.getResponseVerbosityConfiguration(),ox=n.getCommunicationStyleConfiguration(),nx=Boolean($O)&&oO!==$O,tx=Boolean(D)&&b0.selection!==D,sx=Boolean(b)&&l0.selection!==b,rx=Boolean(j)&&i0.selection!==j,ex=Boolean(zO)&&ox.selection!==zO;if(nx||tx||sx||rx||ex)await n.refresh({...$O?{modelId:$O}:{},...D?{reasoningEffort:D}:{},...b?{serviceTier:b}:{},...j?{responseVerbosity:j}:{},...zO?{communicationStyle:zO}:{}});let Nx={...$O&&P.selectedModelId!==$O?{selectedModelId:$O}:{},...D&&P.reasoningEffort!==D?{reasoningEffort:D}:{},...b&&P.serviceTier!==b?{serviceTier:b}:{},...j&&P.responseVerbosity!==j?{responseVerbosity:j}:{},...WO&&(P.communicationStyle!==zO||P.communicationStyleDigest!==WO.contentSha256)?{communicationStyle:zO,communicationStyleDigest:WO.source==="built-in"?null:WO.contentSha256}:{}};if(Object.keys(Nx).length>0)try{let GO=await C.updateSessionMetadata(P.id,P.projectPath,Nx);P.permissionMode=GO.permissionMode,P.selectedModelId=GO.selectedModelId,P.reasoningEffort=GO.reasoningEffort,P.serviceTier=GO.serviceTier,P.responseVerbosity=GO.responseVerbosity,P.communicationStyle=GO.communicationStyle,P.communicationStyleDigest=GO.communicationStyleDigest,P.updatedAt=new Date(GO.lastMessageTime),q.publish(i,"session.updated",Nx)}catch(GO){if(nx||tx||sx||rx||ex)await n.refresh({...oO?{modelId:oO}:{},reasoningEffort:b0.selection,serviceTier:l0.selection,responseVerbosity:i0.selection,communicationStyle:ox.selection}).catch((I$)=>g.error("[SessionRoutes] Failed to roll back non-durable model settings:",I$));throw GO}let A0=MO?await n.prepareInputTurn(h,{outputSchema:MO}):await n.prepareInputTurn(h);if(!A0.accepted)return Z.json({status:"rejected",reason:A0.reason},A0.reason==="queue_full"?429:409);let Wx=xO(P,h,u,{preparedInputTurn:A0,outputSchema:MO,runtimeLease:a});return hO=!0,await Wx.taskAdmissionUpdate,Z.json({runId:Wx.id,messageId:A0.messageId,status:Wx.status==="queued"?"queued":"running",queuePosition:P.taskQueuePosition,queueDepth:P.taskQueueDepth,maxConcurrentTasks:P.taskConcurrencyLimit},202)}finally{if(!hO)a.release()}})}),O.post("/:sessionId/side-question",async(Z)=>{let G=Z.req.param("sessionId"),N=f(B4,await Z.req.json());if(!N.success)throw new _("Invalid side conversation request");let X=await wO(G,N.data.projectPath??Z.req.query("projectPath"));return p(X,async(V)=>{let L=await V.askSideQuestion(N.data.question,{signal:Z.req.raw.signal});return Z.json({...L,...V.getCurrentModelId()?{modelId:V.getCurrentModelId()}:{}})})}),O.post("/:sessionId/shell",async(Z)=>{let G=Z.req.param("sessionId"),N=f(V4,await Z.req.json());if(!N.success)throw new _("Invalid user shell command");let X=await wO(G,N.data.projectPath??Z.req.query("projectPath")),V=XO(X),L=m(V);return c(V,async()=>{if(mO.has(L))throw new k("A user shell command is already running in this Session");let F=await NO(X),D=F.value,b=new AbortController,j,M=new Promise((I)=>{j=I});mO.set(L,{controller:b,completion:M});try{let I=await D.executeUserShellCommand(N.data.command,{signal:b.signal});X.messages=await C.loadSession(X.id,X.projectPath),X.updatedAt=new Date;let QO=FO(X.currentRunId);if(I.delivery==="next_turn"&&_O(QO))QO.pendingFollowUpRequested=!0;return Z.json({executionId:I.executionId,messageId:I.messageId,record:I.record,auxiliary:I.auxiliary,...I.delivery?{delivery:I.delivery}:{},...I.queued!==void 0?{queued:I.queued}:{}})}finally{mO.delete(L),j(),F.release()}})}),O.post("/:sessionId/abort",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N));if(X?.currentRunId){let F=FO(X.currentRunId);if(F)k0(F),await F.completion}let V=mO.get(m(N));if(V)V.controller.abort("user-cancel"),await V.completion;let L=qO.get(m(N));if(L)L.controller.abort("user-cancel"),await L.completion;return Z.json({success:!0})}),O.get("/:sessionId/status",async(Z)=>{let G=Z.req.param("sessionId"),N=await VO(G,Z.req.query("projectPath")),X=OO.get(m(N)),V=qO.get(m(N));if(V)return Z.json({sessionId:G,projectPath:N.projectPath,reviewId:V.reviewId,status:"reviewing"});if(!X?.currentRunId)return Z.json({sessionId:G,projectPath:N.projectPath,status:"idle"});let L=FO(X.currentRunId);return Z.json({sessionId:G,projectPath:N.projectPath,runId:X.currentRunId,status:L?.status==="attention_required"?"idle":L?.status??"idle"})}),{app:O,dispatchTask:LO,retryTask:UO,updateTask:cx,getTaskDiff:Jx,deliverTask:d0,recoverQueuedTasks:Yx,getRuntimeResidencyStats:()=>B.getStats(),getCoordinationStats:()=>({messageSubmissions:J.getStats(),taskDeliveries:K.getStats()}),shutdown:(Z="server-shutdown")=>{if(U)return U;return A.close(Z),clearInterval(H),U=(async()=>{let G,N=async(D)=>{let b=await Promise.allSettled(D);for(let j of b)if(j.status==="rejected")G??=j.reason},X=new Set,V=()=>{for(let D of CO.values()){if(D.completion)X.add(D.completion);if(_O(D))k0(D,Z)}for(let D of mO.values())D.controller.abort(Z),X.add(D.completion);for(let D of qO.values())D.controller.abort(Z),X.add(D.completion)},L=A.waitForIdle(),F=!1;L.then(()=>{F=!0});while(!F)V(),await Promise.race([L,new Promise((D)=>setImmediate(D))]);if(await L,V(),await N([...X]),await N([...w.values()]),V(),await N([...X]),await N([B.disposeAll()]),x.clear(),await N([...Q.values()]),await N([$.disposeAll()]),await N([KO.getInstance().disconnectAll()]),w.clear(),Q.clear(),Y.clear(),OO.clear(),z0===EO)z0=void 0;if(G!==void 0)throw G})(),U}}};async function Mw(O,x,$,w,Q,Y={}){let{abortController:J,sessionId:K,id:S}=O,B=Y.preparedInputTurn?.messageId??W0(12),H=Y.pendingInputOnly===!0||Y.preparedInputTurn?.mode==="pending"||Y.goalContinuationOnly===!0?void 0:W0(12),U=Y.runtimeLease,R,c,l=XO(x),JO=async(p)=>{let v=p.metadata?.recoveryAttention;if(!v||!R)return!1;if(Y.preparedInputTurn)await R.finishTurn(Y.preparedInputTurn.handle,{preserveStartupRecovery:!0,outcome:{status:"aborted",cause:"failed",turnsCount:0,toolCallsCount:0,durationMs:0}}).catch(()=>{return});let ZO=`Turn recovery requires attention: ${v.reason}`,wO=await R.setTaskStatus("interrupted",ZO).catch(()=>{return});if(wO)O0(x,wO);else x.taskStatus="interrupted",x.taskStatusReason=ZO,x.taskCompletedAt=void 0;return O.status="attention_required",T("session.status",{status:"idle"}),!0},T=(p,v)=>{q.publish(l,p,v)},NO=async()=>{let p=String(J.signal.reason||"Task run cancelled");if(x.taskIsolation){if(!U)U=await Q(x).catch(()=>{return});let v=R??U?.value;if(p==="user-cancel")await v?.discardPendingInput().catch((wO)=>{g.warn(`[SessionRoutes] Failed to discard cancelled input for ${x.id}:`,wO)});let ZO=await v?.setTaskStatus("cancelled",p).catch(()=>{return});if(ZO)O0(x,ZO);else await dO(x).catch(()=>{return})}x.taskStatus="cancelled",x.taskStatusReason=p,x.taskCompletedAt??=new Date().toISOString()};try{if(Y.taskAdmission){if(await Y.taskAdmission.ready,await O.taskAdmissionUpdate,J.signal.aborted)throw Error(String(J.signal.reason||"Task run cancelled"))}if(x.taskStatus="running",x.taskStatusReason=void 0,x.taskStartedAt=new Date().toISOString(),x.taskCompletedAt=void 0,!Y.pendingInputOnly&&!Y.goalContinuationOnly)T("message.created",{messageId:B,role:"user",content:Rx($)});if(T("session.status",{status:"running"}),H)T("message.created",{messageId:H,role:"assistant",content:""});U??=await Q(x),R=U.value;let p=R,v=Boolean(Y.outputSchema??p.getPendingSteeringMessages().find((z)=>z.outputSchema)?.outputSchema);c=await N4.createWithRuntime(p,{sessionId:K,...x.taskWorktree?{toolBlacklist:["EnterWorktree","ExitWorktree"]}:{}});let ZO=async(z)=>{let UO=z.interactionRequestId??W0(12),cx=300000;O.status="waiting_permission";let Jx=new Promise((EO)=>{let Yx=setTimeout(()=>{g.warn(`[SessionRoutes] Permission ${UO} timed out after 300000ms`),T("permission.timeout",{requestId:UO}),EO({approved:!1,reason:"timeout"})},300000);O.pendingPermission={permissionId:UO,resolve:(ax)=>{clearTimeout(Yx),EO(ax)},details:z}}),H0=O.pendingPermission;if(!H0)throw Error("Permission request was not registered");let d0=_4(H0);T(d0.type,d0.properties),g.info(`[SessionRoutes] Permission request created: ${UO}, runId: ${S}`);let v0=await Jx;if(g.info(`[SessionRoutes] Permission response received: ${UO}, approved: ${v0.approved}`),!J.signal.aborted)O.status="running";if(O.pendingPermission===H0)O.pendingPermission=void 0;return T("interaction.resolved",{requestId:UO}),v0},IO={messages:await C.loadSessionModelContext(x.id,x.projectPath),userId:"web-user",sessionId:K,workspaceRoot:x.projectPath,signal:J.signal,permissionMode:w,onPermissionModeChange:async(z)=>{x.permissionMode=z,x.updatedAt=new Date,T("session.updated",{permissionMode:z})},...x.taskWorktree?{worktreeActive:!0}:{},confirmationHandler:{requestConfirmation:ZO}},xO=()=>{if(!H)H=W0(12),T("message.created",{messageId:H,role:"assistant",content:""});return H},aO=async(z)=>{switch(z.kind){case"content_delta":if(v)break;T("message.delta",{messageId:xO(),delta:z.delta});break;case"structured_output":T("structured.output",{messageId:xO(),output:z.output,schemaDigest:z.schemaDigest});break;case"thinking_delta":T("thinking.delta",{messageId:xO(),delta:z.delta});break;case"tool_start":if("function"in z.toolCall){if(z.toolCall.function.name===X0)break;T("tool.start",{messageId:xO(),toolName:z.toolCall.function.name,toolCallId:z.toolCall.id,arguments:z.toolCall.function.arguments,toolKind:z.toolKind})}break;case"tool_result":if("function"in z.toolCall){if(z.toolCall.function.name===X0)break;T("tool.result",{messageId:xO(),toolName:z.toolCall.function.name,toolCallId:z.toolCall.id,success:z.result.success,summary:z.result.metadata?.summary,output:h0(y0(m0(z.toolCall.function.name,z.result),P0)),metadata:f0(z.toolCall.function.name,z.result.metadata)})}break;case"tool_progress":if("function"in z.toolCall){if(z.toolCall.function.name===X0)break;T("tool.progress",{messageId:xO(),toolName:z.toolCall.function.name,toolCallId:z.toolCall.id,...z.update})}break;case"token_usage":T("token.usage",{...z.usage});break;case"turn_start":T("turn.started",{turn:z.turn,maxTurns:z.maxTurns});break;case"turn_recovery":T("turn.recovery",{assessment:z.assessment});break;case"provider_admission":T("provider.admission",{phase:z.phase,requestClass:z.requestClass,resource:z.resource,scope:z.scope,reason:z.reason,queuePosition:z.queuePosition,queueDepth:z.queueDepth,inFlight:z.inFlight,limit:z.limit,waitMs:z.waitMs,maxWaitMs:z.maxWaitMs,recoveryRemainingMs:z.recoveryRemainingMs});break;case"provider_circuit":T("provider.circuit",{phase:z.phase,reason:z.reason,statusCode:z.statusCode,retryAfterMs:z.retryAfterMs,nextProbeAt:z.nextProbeAt,openDurationMs:z.openDurationMs,sampleCount:z.sampleCount,failureCount:z.failureCount,recoveryRemainingMs:z.recoveryRemainingMs});break;case"provider_retry":T("provider.retry",{phase:z.phase,attempt:z.attempt,maxRetries:z.maxRetries,reason:z.reason,statusCode:z.statusCode,delayMs:z.delayMs,nextRetryAt:z.nextRetryAt,mode:z.mode,recoveryBudgetMs:z.recoveryBudgetMs,recoveryElapsedMs:z.recoveryElapsedMs,recoveryRemainingMs:z.recoveryRemainingMs,exhaustedBy:z.exhaustedBy});break;case"provider_stall":T("provider.stall",{phase:z.phase,stallCount:z.stallCount,durationMs:z.durationMs,warningAfterMs:z.warningAfterMs,timeoutMs:z.timeoutMs,outputStarted:z.outputStarted});break;case"action_stationarity":T("action.stationarity",{phase:z.phase,toolName:z.toolName,runLength:z.runLength,nudgeThreshold:z.nudgeThreshold,haltThreshold:z.haltThreshold,progressAware:z.progressAware});break;case"mcp_catalog_changed":T("mcp.catalog.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,added:z.added,removed:z.removed,updated:z.updated});break;case"mcp_content_changed":T("mcp.content.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,contentKind:z.contentKind,added:z.added,removed:z.removed,updated:z.updated});break;case"mcp_resource_updated":T("mcp.resource.updated",{messageId:xO(),revision:z.revision,serverName:z.serverName,uri:z.uri});break;case"mcp_connection_changed":T("mcp.connection.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,phase:z.phase,reason:z.reason,attempt:z.attempt,maxAttempts:z.maxAttempts,nextRetryAt:z.nextRetryAt,error:z.error});break;case"mcp_log":T("mcp.log",{messageId:xO(),revision:z.revision,serverName:z.serverName,level:z.level,logger:z.logger,message:z.message,projectedBytes:z.projectedBytes,dataSha256:z.dataSha256,truncated:z.truncated,detailsOmitted:z.detailsOmitted,timestamp:z.timestamp,synthetic:z.synthetic});break;case"mcp_instructions_changed":T("mcp.instructions.changed",{messageId:xO(),revision:z.revision,serverName:z.serverName,action:z.action,reason:z.reason,text:z.text,sourceBytes:z.sourceBytes,projectedBytes:z.projectedBytes,sha256:z.sha256,truncated:z.truncated,detailsOmitted:z.detailsOmitted});break;case"mcp_task_changed":T("mcp.task.changed",{messageId:xO(),revision:z.revision,taskId:z.taskId,serverName:z.serverName,toolName:z.toolName,status:z.status,statusMessage:z.statusMessage,createdAt:z.createdAt,updatedAt:z.updatedAt,completedAt:z.completedAt,hasResult:z.hasResult,error:z.error});break;case"project_rules_loaded":T("project.rules.loaded",{messageId:xO(),files:z.files,triggerPaths:z.triggerPaths,blockedWrite:z.blockedWrite});break;case"steering_applied":T("steering.applied",{runId:S,messageIds:z.messageIds,count:z.count,recovered:z.recovered,delivery:z.delivery,queued:p.getPendingSteeringCount()});break;case"follow_up_started":{if(H)T("message.complete",{messageId:H}),H=void 0;for(let UO of z.messages){if(!UO.recovered||UO.persisted)continue;T("message.created",{messageId:UO.id,role:"user",content:Rx(UO.content),recovered:!0})}T("follow_up.started",{runId:S,queued:z.queued,recovered:z.recovered}),xO();break}case"goal_updated":T("goal.updated",{goal:z.goal});break;case"goal_continuation_started":T("goal.continuation.started",{goal:z.goal,continuation:z.continuation,...z.prematureStopPattern?{prematureStopPattern:z.prematureStopPattern}:{},...z.prematureStopCount!==void 0?{prematureStopCount:z.prematureStopCount}:{}}),xO();break;case"compaction":T(z.phase==="start"?"compaction.started":"compaction.completed",{...z.reason?{reason:z.reason}:{},...z.strategy?{strategy:z.strategy}:{},...z.outcome?{outcome:z.outcome}:{},...z.preTokens!==void 0?{preTokens:z.preTokens}:{},...z.preTokenSource?{preTokenSource:z.preTokenSource}:{},...z.estimatedPendingTokens!==void 0?{estimatedPendingTokens:z.estimatedPendingTokens}:{},...z.postTokens!==void 0?{postTokens:z.postTokens}:{},...z.sampleAttempts!==void 0?{sampleAttempts:z.sampleAttempts}:{},...z.inputReductions!==void 0?{inputReductions:z.inputReductions}:{},...z.messagesOmitted!==void 0?{messagesOmitted:z.messagesOmitted}:{},...z.filesOmitted!==void 0?{filesOmitted:z.filesOmitted}:{},...z.imagesOmitted!==void 0?{imagesOmitted:z.imagesOmitted}:{},...z.fallbackTargetTokens!==void 0?{fallbackTargetTokens:z.fallbackTargetTokens}:{},...z.fallbackMessagesOmitted!==void 0?{fallbackMessagesOmitted:z.fallbackMessagesOmitted}:{},...z.fallbackMessagesTruncated!==void 0?{fallbackMessagesTruncated:z.fallbackMessagesTruncated}:{},...z.failureReason?{failureReason:z.failureReason}:{}});break;case"model_fallback":T("model.fallback",{});break;case"task_update":T("task.updated",{tasks:z.tasks});break;case"goal_frontier_updated":T("goal.frontier.updated",{goalId:z.goal.goalId,goalStatus:z.goal.status,frontier:z.frontier,stall:z.goal.frontierStall});break;default:break}},LO=await Sx(c.chatStream($,IO,{stream:!0,pendingInputOnly:Y.pendingInputOnly,preparedInputTurn:Y.preparedInputTurn,goalContinuationOnly:Y.goalContinuationOnly,outputSchema:Y.outputSchema,taskAdmission:Y.taskAdmission}),aO);if(await JO(LO))return;if(!LO.success)throw Error(LO.error?.message??"Agent run failed");for(let z=0;z<20;z++){let UO=O.pendingFollowUpRequested===!0;if(O.pendingFollowUpRequested=!1,p.getPendingSteeringCount()===0){if(!UO)break;continue}if(J.signal.aborted)break;if(LO=await Sx(c.chatStream("",IO,{stream:!0,pendingInputOnly:!0,taskAdmission:Y.taskAdmission}),aO),await JO(LO))return;if(!LO.success)throw Error(LO.error?.message??"Agent follow-up failed")}if(x.messages=await C.loadSession(x.id,x.projectPath),x.updatedAt=new Date,await dO(x),J.signal.aborted||O.status==="cancelled"){await NO(),T("session.status",{status:"idle"});return}if(H)T("message.complete",{messageId:H});T("thinking.completed",{}),O.status="completed",x.taskStatus="completed",x.taskCompletedAt??=new Date().toISOString(),T("session.completed",{runId:S,outputTruncated:LO.metadata?.outputTruncated??!1}),T("session.status",{status:"idle"})}catch(p){if(R&&Y.preparedInputTurn)await(R.getTurnRecoveryAssessment().state==="requires_attention"?R.finishTurn(Y.preparedInputTurn.handle,{preserveStartupRecovery:!0}):R.finishTurn(Y.preparedInputTurn.handle)).catch(()=>{return});if(J.signal.aborted||O.status==="cancelled"){k0(O,"runtime-abort"),await NO(),T("session.status",{status:"idle"});return}await dO(x).catch(()=>{return}),g.error("[SessionRoutes] Agent execution error:",p),O.status="failed",x.taskStatus="failed",x.taskCompletedAt??=new Date().toISOString();let v=e0(p);if(!x.taskFailure){let ZO=R?await R.setTaskStatus("failed",p).catch(()=>{return}):await C.updateSessionMetadata(x.id,x.projectPath,{taskStatus:"failed",taskStatusReason:v.message,taskFailure:v,taskCompletedAt:x.taskCompletedAt,taskOwnerPid:null,taskQueuePosition:null,taskQueueDepth:null}).catch(()=>{return});if(ZO)O0(x,ZO)}x.taskStatusReason??=v.message,x.taskFailure??=v,T("session.error",{error:x.taskFailure.message,taskFailure:x.taskFailure}),T("session.status",{status:"error"})}finally{if(Y.taskAdmission?.release(),Y.taskAdmission){let p=gO.getStats();T("task.status",{taskStatus:x.taskStatus,...x.taskStatusReason?{taskStatusReason:x.taskStatusReason}:{},...x.taskFailure?{taskFailure:x.taskFailure}:{},...x.taskStartedAt?{taskStartedAt:x.taskStartedAt}:{},...x.taskCompletedAt?{taskCompletedAt:x.taskCompletedAt}:{},...x.taskDiffStat?{taskDiffStat:x.taskDiffStat}:{},taskQueueDepth:p.queued,taskConcurrencyLimit:p.maxConcurrent,taskInFlight:p.inFlight,taskAdmissionPaused:p.paused,updatedAt:new Date().toISOString()})}if(await c?.destroy().catch(()=>{return}),U?.release(),O.disposeRuntimeOnSettle&&Y.disposeRuntime)await Y.disposeRuntime(x,R).catch((p)=>{g.warn(`[SessionRoutes] Failed to dispose terminal task runtime ${x.id}:`,p)});Lw(O)}}async function L4(O,x,$){g.info(`[SessionRoutes] Looking for permission ${x} in session ${O.sessionId}`),g.info(`[SessionRoutes] Active runs: ${CO.size}`);for(let[Y,J]of CO.entries())if(g.info(`[SessionRoutes] Checking run ${Y}: sessionId=${J.sessionId}, projectPath=${J.projectPath}, pendingPermission=${J.pendingPermission?.permissionId}`),J.sessionId===O.sessionId&&J.projectPath===O.projectPath&&J.pendingPermission?.permissionId===x){if(J.pendingPermission.details.interactionRequestId)await eO.respond(O.projectPath,O.sessionId,x,$);return J.pendingPermission.resolve($),g.info(`[SessionRoutes] Permission ${x} responded, runId: ${J.id}`),!0}let w=await eO.findPending(O.projectPath,O.sessionId);if(!w||w.request.requestId!==x)return g.error(`[SessionRoutes] Permission not found: ${x}`),!1;await eO.respondAndRecover(O.projectPath,O.sessionId,x,$);let Q=OO.get(m(O));if(!Q){let Y=await C.findSessionMetadata(O.sessionId,O.projectPath);if(!Y)return!1;let[J,K]=await Promise.all([C.loadSession(O.sessionId,O.projectPath),C.findSessionTaskWorktree(O.sessionId,O.projectPath)]);Q=E0(Y,J,K),OO.set(m(O),Q)}else await dO(Q);if(q.publish(O,"interaction.resolved",{requestId:x}),z0)z0(Q).catch((Y)=>{g.error(`[SessionRoutes] Failed to resume recovered interaction ${x}:`,Y)});return!0}var Cx=t("Service"),Rw=W.Object({approved:W.Boolean(),remember:W.Optional(W.Boolean()),scope:W.Optional(e(["once","session","project"])),targetMode:W.Optional(e(["default","autoEdit","plan","yolo"])),feedback:W.Optional(W.String({maxLength:4000})),answers:W.Optional(W.Record(W.String({maxLength:80}),W.Union([W.String({maxLength:4000}),W.Array(W.String({maxLength:1000}),{maxItems:4})]),{maxProperties:4})),elicitation:W.Optional(W.Object({action:e(["accept","decline","cancel"]),content:W.Optional(W.Record(W.String(),W.Union([W.String({maxLength:4000}),W.Number(),W.Boolean(),W.Array(W.String({maxLength:1000}),{maxItems:100})]),{maxProperties:32}))}))}),D4=()=>{let O=new Tw;return O.post("/:permissionId",async(x)=>{let $=x.req.param("permissionId"),w=x.req.query("sessionId"),Q=x.req.query("projectPath");Cx.info(`[PermissionRoutes] Received permission response: permissionId=${$}, sessionId=${w}`);try{let Y=await x.req.json(),J=f(Rw,Y);if(!J.success)throw new _("Invalid permission response format");let{approved:K,remember:S,scope:B,targetMode:A,feedback:H,answers:U,elicitation:R}=J.data;if(!w)throw new _("sessionId query parameter is required");let c=await VO(w,Q);if(!await L4(c,$,{approved:K,reason:H,scope:B,targetMode:A,feedback:H,answers:U,elicitation:R}))throw new y("Permission request",$);return Cx.info(`[PermissionRoutes] Permission ${$} ${K?"approved":"denied"}`),x.json({success:!0,approved:K,remember:S})}catch(Y){if(Cx.error("[PermissionRoutes] Failed to respond to permission:",Y),Y instanceof _||Y instanceof bO||Y instanceof y||Y instanceof r)throw Y;throw Y}}),O};import H4 from"node:path";import{Hono as qw}from"hono";var Cw=W.Object({projectPath:W.String({minLength:1}),enabled:W.Boolean(),scope:W.Optional(e(["local","project","global"]))}),Iw=W.Object({projectPath:W.String({minLength:1})}),Ew=W.Object({projectPath:W.String({minLength:1}),source:W.String({minLength:1}),trust:W.Literal(!0),ref:W.Optional(W.String({minLength:1}))}),kw=W.Object({projectPath:W.String({minLength:1}),trust:W.Literal(!0)}),fw=W.Object({projectPath:W.String({minLength:1}),confirm:W.Literal(!0)}),Pw=W.Object({projectPath:W.String({minLength:1}),source:W.String({minLength:1}),ref:W.Optional(W.String({minLength:1}))}),b4=W.Object({projectPath:W.String({minLength:1}),confirm:W.Optional(W.Literal(!0))}),yw=W.Object({projectPath:W.String({minLength:1}),scope:W.Optional(e(["local","project","global"])),policy:W.Object({restrictToAllowedSources:W.Boolean(),requireGitCommitSha:W.Boolean(),allowedGitHosts:W.Array(W.String()),allowedMarketplaces:W.Array(W.String()),allowedLocalRoots:W.Array(W.String())})});function SO(O){if(!O||!H4.isAbsolute(O))throw new _("projectPath must be absolute");return H4.resolve(O)}async function A4(O){let[x,$]=await Promise.all([TO(O),M0.getInstance().loadWorkspacePluginSettingsResolution(O)]);return x.plugins.getAll().map((w)=>({name:w.manifest.name,description:w.manifest.description,version:w.manifest.version,source:w.source,enabled:w.status==="active",status:w.status,commands:w.commands.length,skills:w.skills.length,agents:w.agents.length,hooks:w.hooks?Object.values(w.hooks).reduce((Q,Y)=>Q+(Array.isArray(Y)?Y.length:0),0):0,mcpServers:Object.keys(w.mcpServers??{}).length,configurable:w.source!=="cli",managed:w.installation!==void 0,marketplace:w.installation?.source.type==="marketplace"?w.installation.source.marketplace:void 0,revision:w.installation?.revision,installedAt:w.installation?.installedAt,updatedAt:w.installation?.updatedAt,compatibilityIssues:w.compatibilityIssues??[],effectiveScope:w.source==="cli"?"invocation":$.settings[w.manifest.name]?.effectiveScope??"default",settingLayers:w.source==="cli"?{invocation:!0}:$.settings[w.manifest.name]?.layers??{}}))}async function mw(){let O=S4(),[x,$]=await Promise.all([O.listCatalogs(),O.listInstallationRecords()]),w=new Map($.map((Q)=>[Q.name,Q]));return x.map(({marketplace:Q,manifest:Y})=>({name:Q.name,description:Y.description??Y.metadata?.description??"",sourceType:Q.source.type,revision:Q.revision,updatedAt:Q.updatedAt,plugins:Y.plugins.map((J)=>{let K=w.get(J.name);return{name:J.name,description:J.description??"",version:J.version,category:J.category,tags:J.tags??[],installed:K!==void 0,installedVersion:K?.version}})}))}function G0(O,x){if(!O.success)throw new _(O.error??x)}var f4=()=>{let O=new qw;return O.get("/",async(x)=>{let $=SO(x.req.query("projectPath"));return x.json(await A4($))}),O.post("/refresh",async(x)=>{let $=f(Iw,await x.req.json());if(!$.success)throw new _("Invalid plugin refresh request");let w=SO($.data.projectPath),Q=await M4(w);return x.json({plugins:await A4(w),errors:Q.discovery.errors.map((Y)=>({code:Y.code??"LOAD_ERROR",error:Y.error}))})}),O.get("/catalog",async(x)=>{return SO(x.req.query("projectPath")),x.json(await mw())}),O.get("/policy",async(x)=>{let $=SO(x.req.query("projectPath")),w=await M0.getInstance().loadWorkspacePluginSourcePolicy($);return x.json({policy:w,environmentRequiresSha:process.env.BLADE_PLUGIN_REQUIRE_SHA==="1"||process.env.BLADE_PLUGIN_REQUIRE_SHA==="true"})}),O.post("/policy",async(x)=>{let $=f(yw,await x.req.json());if(!$.success)throw new _("Invalid plugin source policy request");let w=SO($.data.projectPath),Q=await T4(w,$.data.policy,$.data.scope??"global");return x.json({policy:Q})}),O.post("/install",async(x)=>{let $=f(Ew,await x.req.json());if(!$.success)throw new _("Invalid plugin install request; explicit source trust is required");let w=SO($.data.projectPath),{result:Q}=await R4(w,$.data.source,{trusted:$.data.trust,ref:$.data.ref});return G0(Q,"Plugin installation failed"),x.json({name:Q.pluginName,version:Q.manifest?.version,revision:Q.installation?.revision,changed:Q.changed,installedDependencies:Q.installedDependencies??[]})}),O.post("/marketplaces",async(x)=>{let $=f(Pw,await x.req.json());if(!$.success)throw new _("Invalid marketplace add request");let w=SO($.data.projectPath),Q=await I4(w,$.data.source,$.data.ref);return G0(Q,"Marketplace installation failed"),x.json({name:Q.marketplace?.name,plugins:Q.manifest?.plugins.length??0,revision:Q.marketplace?.revision,changed:Q.changed})}),O.post("/marketplaces/:name/refresh",async(x)=>{let $=f(b4,await x.req.json());if(!$.success)throw new _("Invalid marketplace refresh request");let w=await E4(SO($.data.projectPath),x.req.param("name"));return G0(w,"Marketplace refresh failed"),x.json({name:w.marketplace?.name,plugins:w.manifest?.plugins.length??0,revision:w.marketplace?.revision,changed:w.changed})}),O.post("/marketplaces/:name/remove",async(x)=>{let $=f(b4,await x.req.json());if(!$.success||$.data.confirm!==!0)throw new _("Invalid marketplace removal request; explicit confirmation is required");SO($.data.projectPath);let w=await k4(x.req.param("name"),!0);return G0(w,"Marketplace removal failed"),x.json({name:w.marketplace?.name,removed:!0})}),O.post("/:name/update",async(x)=>{let $=f(kw,await x.req.json());if(!$.success)throw new _("Invalid plugin update request; explicit source trust is required");let w=SO($.data.projectPath),{result:Q}=await q4(w,x.req.param("name"),{trusted:$.data.trust});return G0(Q,"Plugin update failed"),x.json({name:Q.pluginName,version:Q.manifest?.version,revision:Q.installation?.revision,changed:Q.changed,updatedDependencies:Q.updatedDependencies??[]})}),O.post("/:name/uninstall",async(x)=>{let $=f(fw,await x.req.json());if(!$.success)throw new _("Invalid plugin uninstall request; explicit confirmation is required");let w=SO($.data.projectPath),{result:Q}=await C4(w,x.req.param("name"),$.data.confirm);return G0(Q,"Plugin uninstall failed"),x.json({name:Q.pluginName,removed:!0})}),O.post("/:name/state",async(x)=>{let $=f(Cw,await x.req.json());if(!$.success)throw new _("Invalid plugin state request");let w=SO($.data.projectPath),Q=x.req.param("name"),J=(await TO(w)).plugins.get(Q);if(!J)throw new y("Plugin",Q);if(J.source==="cli")throw new _(`Plugin "${Q}" was loaded with --plugin-dir and is invocation-scoped`);let K=await j4(w,Q,$.data.enabled,$.data.scope??"local");return x.json(K)}),O};import{Hono as dw}from"hono";import{execFile as hw}from"node:child_process";import gw from"node:path";var kx="__BLADE_DIRECTORY_PICKER_CANCELLED__",uw=900000;function pw(O,x){return new Promise(($)=>{hw(O,[...x],{timeout:uw,maxBuffer:65536,windowsHide:!0},(w,Q,Y)=>{let J=w?.code;$({stdout:Q,stderr:Y,exitCode:typeof J==="number"?J:w?1:0,...typeof J==="string"?{errorCode:J}:{}})})})}function Ix(O){let x=O.replace(/[\r\n]+$/,"");if(!x||x===kx)return{cancelled:!0};if(!gw.isAbsolute(x))throw Error("The folder picker returned an invalid path");return{cancelled:!1,path:x}}function Ex(O){return O.exitCode!==0||Boolean(O.errorCode)}class P4{platform;runCommand;activeSelection=null;constructor(O={}){this.platform=O.platform??process.platform,this.runCommand=O.runCommand??pw}pick(){if(this.activeSelection)return this.activeSelection;let O=this.pickForPlatform().finally(()=>{this.activeSelection=null});return this.activeSelection=O,O}async pickForPlatform(){switch(this.platform){case"darwin":return this.pickOnMac();case"win32":return this.pickOnWindows();case"linux":return this.pickOnLinux();default:throw Error("Native folder selection is unavailable on this system")}}async pickOnMac(){let O=["try",'set selectedFolder to choose folder with prompt "Choose a project folder"',"return POSIX path of selectedFolder","on error number -128",`return "${kx}"`,"end try"].join(`
|
|
8
|
+
`),x=await this.runCommand("osascript",["-e",O]);if(Ex(x))throw Error("Unable to open the macOS folder picker");return Ix(x.stdout)}async pickOnWindows(){let O=["Add-Type -AssemblyName System.Windows.Forms","$dialog = New-Object System.Windows.Forms.FolderBrowserDialog",'$dialog.Description = "Choose a project folder"',"$dialog.ShowNewFolderButton = $true","if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {"," [Console]::Out.Write($dialog.SelectedPath)","} else {",` [Console]::Out.Write("${kx}")`,"}"].join("; "),x=await this.runCommand("powershell.exe",["-NoProfile","-STA","-Command",O]);if(Ex(x))throw Error("Unable to open the Windows folder picker");return Ix(x.stdout)}async pickOnLinux(){let O=[{command:"zenity",args:["--file-selection","--directory","--title=Choose a project folder"]},{command:"kdialog",args:["--getexistingdirectory",".","--title","Choose a project folder"]}];for(let x of O){let $=await this.runCommand(x.command,x.args);if($.errorCode==="ENOENT")continue;if($.exitCode===1&&!$.stdout.trim()&&!$.stderr.trim())return{cancelled:!0};if(Ex($))throw Error("Unable to open the Linux folder picker");return Ix($.stdout)}throw Error("Install zenity or kdialog to use native folder selection")}}var y4=new P4;var vw=W.Object({path:W.String({minLength:1})});function lw(O){if(!O)return!1;if(O==="tauri://localhost"||O==="http://tauri.localhost")return!0;try{let x=new URL(O).hostname;return x==="localhost"||x==="127.0.0.1"||x==="::1"||x==="[::1]"}catch{return!1}}var m4=(O={})=>{let x=new dw,$=O.pickDirectory??(()=>y4.pick()),w=O.allowDirectoryPickerRequest??lw;return x.get("/",async(Q)=>{return Q.json(await wx.list(o()))}),x.post("/",async(Q)=>{let Y;try{Y=await Q.req.json()}catch{throw new _("A valid JSON body is required")}let J=f(vw,Y);if(!J.success)throw new _("A project path is required");try{let K=await wx.bind(J.data.path,o());return Q.json(K,201)}catch(K){throw new _(K instanceof Error?K.message:"Failed to bind project")}}),x.post("/pick",async(Q)=>{if(!w(Q.req.header("Origin")))throw new r("LOCAL_ACCESS_REQUIRED","Folder selection is only available from this machine",403);try{return Q.json(await $())}catch(Y){throw new _(Y instanceof Error?Y.message:"Failed to select a folder")}}),x.delete("/",async(Q)=>{let Y=Q.req.query("path");if(!Y)throw new _("A project path is required");try{let J=await wx.unbind(Y);return Q.json({success:!0,removed:J})}catch(J){throw new _(J instanceof Error?J.message:"Failed to unbind project")}}),x};import{Hono as iw}from"hono";var h4=t("Service"),d4=()=>{let O=new iw;return O.get("/",async(x)=>{try{let $=await u4();return x.json($)}catch($){return h4.error("[ProviderRoutes] Failed to list providers:",$),x.json([])}}),O.get("/:provider/models",async(x)=>{let $=x.req.param("provider");try{let w=await p4($);return x.json(w)}catch(w){return h4.error("[ProviderRoutes] Failed to list models:",w),x.json([])}}),O.put("/:provider/credential",async(x)=>{let $=x.req.param("provider"),w=await x.req.json();if(!w.apiKey?.trim())throw new _("apiKey is required");return await nO().setApiKey($,w.apiKey.trim()),x.json({success:!0})}),O.delete("/:provider/credential",async(x)=>{return await nO().clearCredential(x.req.param("provider")),x.json({success:!0})}),O.put("/:provider",async(x)=>{let $=x.req.param("provider"),w=YO(),Q=w?.modelProviders[$];if(!w||!Q)throw new y("Model provider",$);let Y=await x.req.json();if(!Y.name||!Y.baseUrl||!Y.wireApi)throw new _("name, baseUrl and wireApi are required");let J="apiKeyEnv"in Y?Y.apiKeyEnv?.trim():Q.apiKeyEnv,K={name:Y.name,baseUrl:Y.baseUrl,wireApi:Y.wireApi,...J?{apiKeyEnv:J}:{}},S=nO(),B=Y.apiKey?.trim()?await S.credentials.read($):void 0;if(Y.apiKey?.trim())await S.setApiKey($,Y.apiKey.trim());try{return await AO().updateModelProvider($,K),x.json({success:!0})}catch(A){if(Y.apiKey?.trim())if(B)await S.credentials.modify($,async()=>B);else await S.credentials.delete($);if(A instanceof Error&&(A.message.includes("modelProviders.")||A.message.includes("built-in provider")))throw new _(A.message);throw A}}),O.delete("/:provider",async(x)=>{let $=x.req.param("provider");if(!YO()?.modelProviders[$])throw new y("Model provider",$);let Q=x.req.query("removeModels");if(Q!==void 0&&Q!=="true"&&Q!=="false")throw new _("removeModels must be true or false");try{let Y=await AO().removeModelProvider($,{removeModels:Q==="true"});return x.json({success:!0,...Y})}catch(Y){if(Y instanceof Error&&(Y.message.includes("still referenced")||Y.message.includes("owns the only model")))throw new k(Y.message);throw Y}}),O.post("/:provider/probe",async(x)=>{let $=x.req.param("provider"),w=YO();if(!w?.modelProviders[$])throw new y("Model provider",$);let Q=await x.req.json().catch(()=>({})),Y=w.models.filter((K)=>K.provider===$),J=Q.modelId?Y.find((K)=>K.id===Q.modelId):Y[0];if(!J)throw new _(Q.modelId?"modelId does not reference this provider":"Model provider has no configured model to probe");return x.json(await g4(J,w))}),O};import{Hono as cw}from"hono";var aw=t("Service"),c4=(O,x)=>{let $=new cw;return $.onError((w,Q)=>{if(w instanceof r)return Q.json(w.toObject(),w.statusCode);return aw.error("[ScheduleRoutes] Unhandled route error:",w),Q.json(new s("Schedule request failed").toObject(),500)}),$.get("/",async(w)=>{let Q=await O.list();return w.json(i4.parse({schedules:Q}))}),$.post("/",async(w)=>{let Q;try{Q=await w.req.json()}catch{throw new _("Invalid request body")}let Y=f(v4,Q);if(!Y.success)throw new _("Invalid schedule request");let J=Y.data.projectPath||w.get("directory")||o();try{let K=await O.create({...Y.data,projectPath:J});return w.json(x0.parse(K),201)}catch(K){throw new _(K instanceof Error?K.message:"Failed to create schedule")}}),$.get("/:id",async(w)=>{let Q=await O.get(w.req.param("id"));if(!Q)throw new y("Schedule not found");return w.json(x0.parse(Q))}),$.patch("/:id",async(w)=>{let Q;try{Q=await w.req.json()}catch{throw new _("Invalid request body")}let Y=f(l4,Q);if(!Y.success)throw new _("Invalid schedule update");let{modelId:J,reasoningEffort:K,serviceTier:S,responseVerbosity:B,communicationStyle:A,isolation:H,permissionMode:U,...R}=Y.data,c={...J!==void 0?{modelId:J}:{},...K!==void 0?{reasoningEffort:K}:{},...S!==void 0?{serviceTier:S}:{},...B!==void 0?{responseVerbosity:B}:{},...A!==void 0?{communicationStyle:A}:{},...H!==void 0?{isolation:H}:{},...U!==void 0?{permissionMode:U}:{}};try{let l=await O.update(w.req.param("id"),{...R,...Object.keys(c).length>0?{dispatch:c}:{}});if(!l)throw new y("Schedule not found");return w.json(x0.parse(l))}catch(l){if(l instanceof r)throw l;throw new _(l instanceof Error?l.message:"Failed to update schedule")}}),$.delete("/:id",async(w)=>{if(!await O.remove(w.req.param("id")))throw new y("Schedule not found");return w.json({ok:!0})}),$.post("/:id/enable",async(w)=>{let Q=await O.setEnabled(w.req.param("id"),!0);if(!Q)throw new y("Schedule not found");return w.json(x0.parse(Q))}),$.post("/:id/disable",async(w)=>{let Q=await O.setEnabled(w.req.param("id"),!1);if(!Q)throw new y("Schedule not found");return w.json(x0.parse(Q))}),$.post("/:id/run",async(w)=>{let Q=await O.get(w.req.param("id"));if(!Q)throw new y("Schedule not found");if(!x)throw new s("Scheduler is not running in this process");await x.fire(Q,new Date,{manual:!0});let Y=await O.get(Q.id);return w.json(x0.parse(Y??Q),202)}),$};import*as lO from"node:fs/promises";import{homedir as n4}from"node:os";import*as jO from"node:path";import{Hono as ow}from"hono";var $0=t("Service"),a4=jO.join(n4(),".blade","skills"),fx=jO.join(n4(),".blade","skills-config.json");async function t4(){try{let O=await lO.readFile(fx,"utf-8");return JSON.parse(O)}catch{return{disabled:[]}}}async function nw(O){await lO.mkdir(jO.dirname(fx),{recursive:!0}),await lO.writeFile(fx,JSON.stringify(O,null,2))}async function tw(O,x){let $=await t4();if(x)$.disabled=$.disabled.filter((w)=>w!==O);else if(!$.disabled.includes(O))$.disabled.push(O);await nw($)}var vO=null,sw=300000,rw=6;async function ew(){if(vO&&Date.now()-vO.timestamp<sw)return vO.data;try{let O=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!O.ok){if($0.warn(`GitHub API returned ${O.status}`),vO)return vO.data;throw Error(`GitHub skills catalog returned ${O.status}`)}let $=(await O.json()).filter((J)=>J.type==="dir"),w=Array($.length),Q=0,Y=Math.min(rw,$.length);return await Promise.all(Array.from({length:Y},async()=>{while(Q<$.length){let J=Q++,K=$[J];if(!K)continue;let S=`Official ${K.name} skill`;try{let B=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${K.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(B.ok){let H=(await B.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(H)S=H[1].trim().slice(0,100)}}catch{}w[J]={name:K.name,description:S,tag:"Official",author:"Anthropic"}}})),vO={data:w,timestamp:Date.now()},w}catch(O){if($0.warn("Failed to fetch skills catalog from GitHub:",O),vO)return vO.data;throw O}}var s4=()=>{let O=new ow;return O.get("/",async(x)=>{try{let $=x.get("directory")||o(),Q=(await TO($)).skills.getAll(),Y=await t4(),J=Q.map((K)=>({id:K.name,name:K.name,enabled:!Y.disabled.includes(K.name),description:K.description||"",version:K.version||"1.0.0",provider:"Local",location:K.source==="builtin"?"Built-in":K.basePath,removable:K.source==="user"&&jO.dirname(jO.resolve(K.basePath))===jO.resolve(a4),capabilities:["prompts"],allowedTools:K.allowedTools||[]}));return x.json(J)}catch($){return $0.error("[SkillsRoutes] Failed to get skills:",$),x.json({error:$ instanceof Error?$.message:"Failed to get skills"},500)}}),O.post("/:name/toggle",async(x)=>{try{let $=x.req.param("name"),w=await x.req.json();return await tw($,w.enabled),x.json({success:!0,enabled:w.enabled})}catch($){return $0.error("[SkillsRoutes] Failed to toggle skill:",$),x.json({success:!1,error:$.message},500)}}),O.delete("/:name",async(x)=>{try{let $=x.req.param("name"),w=x.get("directory")||o();return q0(w,async(Q)=>{let Y=Q.skills,J=Y.get($);if(!J)return x.json({success:!1,error:"Skill not found"},404);let K=jO.resolve(J.basePath),S=jO.resolve(a4);if(J.source!=="user"||jO.dirname(K)!==S)return x.json({success:!1,error:"Only Blade user skills can be uninstalled"},400);return await lO.rm(K,{recursive:!0,force:!0}),await Y.refresh(),R0(w),await T0(w),x.json({success:!0})})}catch($){return $0.error("[SkillsRoutes] Failed to uninstall skill:",$),x.json({success:!1,error:$.message},500)}}),O.post("/install",async(x)=>{try{let $=await x.req.json(),w=o4(),Q=x.get("directory")||o();return q0(Q,async(Y)=>{let J=Y.skills,K=!1;if($.source==="catalog"&&$.name){if(K=await w.installOfficialSkill($.name),!K)return x.json({success:!1,error:"Failed to install skill from catalog"},500)}else if($.source==="repo"&&$.url){if(K=await w.installFromRepo($.url,$.name),!K)return x.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if($.source==="local"&&$.path){if(K=await w.installFromLocal($.path,$.name),!K)return x.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return x.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await J.refresh(),R0(Q),await T0(Q),x.json({success:!0})})}catch($){return $0.error("[SkillsRoutes] Failed to install skill:",$),x.json({success:!1,error:$.message},500)}}),O.get("/catalog",async(x)=>{try{let $=await ew();return x.json($)}catch($){return $0.error("[SkillsRoutes] Failed to get catalog:",$),x.json({error:$ instanceof Error?$.message:"Failed to get skills catalog"},502)}}),O};import{execSync as O2}from"node:child_process";import{readdir as x2}from"node:fs/promises";import Qx from"node:path";import $2 from"fast-glob";import{Hono as w2}from"hono";var g0=t("Service"),Q2=(O)=>{try{return O2("git rev-parse --abbrev-ref HEAD",{cwd:O,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},Z2=[...V0.map((O)=>`${O}/**`),...V0,...V0.map((O)=>`**/${O}/**`),...V0.map((O)=>`**/${O}`),...Px.map((O)=>`**/${O}`)],J2=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),O$=()=>{let O=new w2;return O.get("/commands",async(x)=>{try{let $=x.req.query("q")||"",w=x.get("directory")||o(),Q=await TO(w),Y=e4($,w,Q).filter((J)=>!J2.has(J.command));return x.json(Y)}catch($){return g0.error("[SuggestionsRoutes] Failed to get command suggestions:",$),x.json([])}}),O.get("/files",async(x)=>{try{let $=x.req.query("q")||"",w=x.get("directory")||o(),Q=Math.min(Number(x.req.query("limit"))||100,1000),Y=x.req.query("type")==="file",K=(await $2("**/*",{cwd:w,dot:!1,followSymbolicLinks:!1,onlyFiles:Y,markDirectories:!0,unique:!0,ignore:Z2})).map((A)=>A.replace(/\\/g,"/"));if(!$)return x.json(K.slice(0,Q));let S=$.toLowerCase(),B=K.filter((A)=>A.toLowerCase().includes(S)).slice(0,Q);return x.json(B)}catch($){return g0.error("[SuggestionsRoutes] Failed to get file suggestions:",$),x.json([])}}),O.get("/files/tree",async(x)=>{try{let $=x.get("directory")||o(),w=x.req.query("path")||"",Q=w?Qx.join($,w):$,J=(await x2(Q,{withFileTypes:!0})).map((B)=>({name:B.name,path:w?`${w}/${B.name}`:B.name,type:B.isDirectory()?"dir":"file"}));J.sort((B,A)=>{if(B.type!==A.type)return B.type==="dir"?-1:1;return B.name.localeCompare(A.name)});let K=new Set(V0),S=J.filter((B)=>{let A=B.name;if(A.startsWith("."))return!1;if(K.has(A))return!1;for(let H of Px)if(A.match(new RegExp(H.replace("*",".*"))))return!1;return!0});return x.json(S)}catch($){return g0.error("[SuggestionsRoutes] Failed to get file tree:",$),x.json([])}}),O.get("/files/content",async(x)=>{try{let $=x.req.query("path");if(!$)return x.json({error:"Missing file path"},400);let w=x.get("directory")||o(),Q=Qx.resolve(w,$),Y=Qx.relative(w,Q);if(Y.startsWith("..")||Qx.isAbsolute(Y))return x.json({error:"Invalid file path"},400);let J=r4(),K=await J.stat(Q);if(!K?.isFile)return x.json({error:"File not found"},404);let S=200000,B=await J.readTextFile(Q),A=B.length>S;return x.json({path:$,content:A?B.slice(0,S):B,truncated:A,size:K.size})}catch($){return g0.error("[SuggestionsRoutes] Failed to get file content:",$),x.json({error:"Failed to read file"},500)}}),O.get("/git-info",async(x)=>{try{let $=x.get("directory")||o(),w=Q2($);return x.json({branch:w})}catch($){return g0.error("[SuggestionsRoutes] Failed to get git info:",$),x.json({branch:null})}}),O};import{Hono as Y2}from"hono";var B0=t("Service"),Z$=(O)=>{let x=new Y2;return x.onError(($,w)=>{if($ instanceof r)return w.json($.toObject(),$.statusCode);return B0.error("[TaskRoutes] Unhandled route error:",$),w.json(new s("Failed to dispatch task").toObject(),500)}),x.post("/",async($)=>{let w;try{w=await $.req.json()}catch{throw new _("Invalid request body")}let Q=f($$,w);if(!Q.success)throw new _("Invalid task request");if((Q.data.attachments??[]).reduce((J,K)=>J+(typeof K.content==="string"?Buffer.byteLength(K.content):0),0)>xx)throw new _("Task attachments exceed the 5 MiB limit");if(Q.data.taskDueAt&&!Number.isFinite(Date.parse(Q.data.taskDueAt)))throw new _("Invalid task due date");try{let J=await O.dispatchTask({prompt:Q.data.prompt,title:Q.data.title,taskPriority:Q.data.taskPriority,taskKind:Q.data.taskKind,taskDueAt:Q.data.taskDueAt?new Date(Q.data.taskDueAt).toISOString():void 0,sourceProjectPath:Q.data.projectPath||$.get("directory")||o(),isolation:Q.data.isolation,permissionMode:Q.data.permissionMode,modelId:Q.data.modelId,reasoningEffort:Q.data.reasoningEffort,serviceTier:Q.data.serviceTier,responseVerbosity:Q.data.responseVerbosity,communicationStyle:Q.data.communicationStyle,attachments:Q.data.attachments,outputSchema:Q.data.outputSchema});return $.json(mx.parse(J),202)}catch(J){if(J instanceof _||J instanceof k||J instanceof yO||J instanceof PO)throw J;throw B0.error("[TaskRoutes] Failed to dispatch task:",J),new s("Failed to dispatch task")}}),x.patch("/:sessionId",async($)=>{let w;try{w=await $.req.json()}catch{throw new _("Invalid request body")}let Q=f(w$,w);if(!Q.success)throw new _("Invalid task update");if(Q.data.title===void 0&&Q.data.taskPriority===void 0&&Q.data.taskKind===void 0&&Q.data.taskDueAt===void 0)throw new _("Task update must include at least one field");if(typeof Q.data.taskDueAt==="string"&&!Number.isFinite(Date.parse(Q.data.taskDueAt)))throw new _("Invalid task due date");try{let Y=await O.updateTask($.req.param("sessionId"),{...Q.data,...typeof Q.data.taskDueAt==="string"?{taskDueAt:new Date(Q.data.taskDueAt).toISOString()}:{}},$.req.query("projectPath"));return $.json(yx.parse(Y))}catch(Y){if(Y instanceof _||Y instanceof y||Y instanceof k)throw Y;throw B0.error("[TaskRoutes] Failed to update task:",Y),new s("Failed to update task")}}),x.post("/:sessionId/retry",async($)=>{try{let w=await O.retryTask($.req.param("sessionId"),$.req.query("projectPath"));return $.json(mx.parse(w),202)}catch(w){if(w instanceof _||w instanceof y||w instanceof k||w instanceof yO||w instanceof PO)throw w;throw B0.error("[TaskRoutes] Failed to retry task:",w),new s("Failed to retry task")}}),x.get("/:sessionId/diff",async($)=>{try{let w=await O.getTaskDiff($.req.param("sessionId"),$.req.query("projectPath"));return $.json(x$.parse(w))}catch(w){if(w instanceof _||w instanceof y||w instanceof k)throw w;throw B0.error("[TaskRoutes] Failed to load task diff:",w),new s("Failed to load task diff")}}),x.post("/:sessionId/delivery",async($)=>{let w;try{w=await $.req.json()}catch{throw new _("Invalid request body")}let Q=f(Q$,w);if(!Q.success)throw new _("Invalid task delivery request");try{let Y=await O.deliverTask($.req.param("sessionId"),Q.data.action,$.req.query("projectPath"));return $.json(yx.parse(Y))}catch(Y){if(Y instanceof _||Y instanceof y||Y instanceof k)throw Y;throw B0.error("[TaskRoutes] Failed to deliver task:",Y),new s("Failed to deliver task")}}),x};import W$ from"node:path";import{Hono as X2}from"hono";var N2=RO(W.Object({id:W.String(),name:W.String(),subagentType:W.String(),description:W.String(),agentId:W.Optional(W.String()),status:e(["leader","running","completed","failed","cancelled","unknown"]),result:W.Optional(W.Unknown()),stats:W.Optional(W.Unknown()),worktreePath:W.Optional(W.String())})),W2=RO(W.Object({id:W.String(),subject:W.String(),description:W.String(),status:e(["pending","blocked","running","completed"]),owner:W.Optional(W.String()),priority:e(["high","medium","low"]),dependsOn:W.Array(W.String()),blocks:W.Array(W.String()),result:W.Optional(W.String()),createdAt:W.String(),startedAt:W.Optional(W.String()),completedAt:W.Optional(W.String())})),C6=RO(W.Object({name:W.String(),description:W.Optional(W.String()),status:e(["idle","running","completed","failed","deleted"]),leadAgentId:W.String(),leadSessionId:W.Optional(W.String()),workspaceRoot:W.Optional(W.String()),peerMessagingEnabled:W.Boolean(),createdAt:W.Number(),updatedAt:W.Number(),deletedAt:W.Optional(W.Number()),members:W.Array(N2),tasks:W.Array(W2)})),J$=RO(W.Object({sessionId:W.String({minLength:1}),projectPath:W.String({minLength:1}),name:W.String({minLength:1}),description:W.Optional(W.String()),leadAgentType:W.Optional(W.String()),peerMessagingEnabled:W.Optional(W.Boolean()),members:W.Array(W.Object({name:W.String({minLength:1}),subagentType:W.String({minLength:1}),description:W.Optional(W.String()),prompt:W.String({minLength:10,maxLength:32768})}),{maxItems:32}),tasks:W.Optional(W.Array(W.Object({subject:W.String({minLength:1}),description:W.String({minLength:1}),dependsOn:W.Optional(W.Array(W.String())),assignedTo:W.Optional(W.String()),priority:W.Optional(e(["high","medium","low"]))}),{maxItems:256}))})),Y$=RO(W.Object({sessionId:W.String({minLength:1}),projectPath:W.String({minLength:1}),to:W.String({minLength:1}),message:W.String({minLength:1,maxLength:32768})})),N$=RO(W.Object({sessionId:W.String({minLength:1}),projectPath:W.String({minLength:1}),memberId:W.String({minLength:1})}));var z2=t("Service"),V$=()=>{let O=new X2;return O.onError((x,$)=>{if(x instanceof r)return $.json(x.toObject(),x.statusCode);return z2.error("[TeamRoutes] Unhandled route error:",x),$.json(new s("Team operation failed").toObject(),500)}),O.get("/",async(x)=>{K0();let $=await _0(x.req.query("sessionId"),x.req.query("projectPath"));return x.json(await U0($.projectPath).list($))}),O.post("/",async(x)=>{K0();let $=f(J$,await hx(x.req));if(!$.success)throw new _("Invalid team request");let w=await _0($.data.sessionId,$.data.projectPath),Q=await C.findSessionMetadata(w.sessionId,w.projectPath);return x.json(await U0(w.projectPath).create({name:$.data.name,description:$.data.description,leadAgentType:$.data.leadAgentType,owner:w,modelId:Q?.selectedModelId,peerMessagingEnabled:$.data.peerMessagingEnabled,members:$.data.members,tasks:$.data.tasks}),201)}),O.get("/:teamName",async(x)=>{K0();let $=await _0(x.req.query("sessionId"),x.req.query("projectPath"));return x.json(await U0($.projectPath).getSnapshot(x.req.param("teamName"),$))}),O.post("/:teamName/messages",async(x)=>{K0();let $=f(Y$,await hx(x.req));if(!$.success)throw new _("Invalid team message");let w=await _0($.data.sessionId,$.data.projectPath),Q=await U0(w.projectPath).sendMessage({name:x.req.param("teamName"),to:$.data.to,body:$.data.message,owner:w});return x.json({messages:Q})}),O.post("/:teamName/tasks/claim",async(x)=>{K0();let $=f(N$,await hx(x.req));if(!$.success)throw new _("Invalid team task claim");let w=await _0($.data.sessionId,$.data.projectPath);return x.json({task:await U0(w.projectPath).claimTask(x.req.param("teamName"),$.data.memberId,w)})}),O.delete("/:teamName",async(x)=>{K0();let $=await _0(x.req.query("sessionId"),x.req.query("projectPath"));return x.json(await U0($.projectPath).delete(x.req.param("teamName"),{owner:$,killRunning:!0}))}),O};function U0(O){return new G$({configDir:Ox(),subagentRegistry:z$(O)})}function K0(){if(X$().config.config?.agentTeamsEnabled!==!0)throw new yO("Agent Teams are disabled")}async function _0(O,x){if(!O||!x||!W$.isAbsolute(x))throw new _("sessionId and absolute projectPath are required");let $=W$.resolve(x);if(!await C.findSessionMetadata(O,$))throw new y(`Session not found: ${O}`);return{sessionId:O,projectPath:$}}async function hx(O){try{return await O.json()}catch{throw new _("Invalid request body")}}import{Hono as G2}from"hono";var iO=t("Service"),F0=new Map,B$=2097152,U$=65536;function K$(){return typeof globalThis.Bun<"u"}async function V2(O,x,$){if(K$()){let{spawn:Y}=await import("bun-pty"),J=Y(O,x,{name:"xterm-256color",cwd:$.cwd,env:$.env});return{pid:J.pid,write:(K)=>J.write(K),resize:(K,S)=>J.resize(K,S),kill:()=>J.kill(),onData:(K)=>J.onData(K),onExit:(K)=>J.onExit(K)}}let Q=(await import("node-pty")).spawn(O,x,{name:"xterm-256color",cwd:$.cwd,env:$.env,cols:80,rows:24});return{pid:Q.pid,write:(Y)=>Q.write(Y),resize:(Y,J)=>Q.resize(Y,J),kill:()=>Q.kill(),onData:(Y)=>{Q.onData(Y)},onExit:(Y)=>{Q.onExit(Y)}}}var px=void 0,ux;if(K$())try{let{createBunWebSocket:O}=await import("hono/bun"),x=O();ux=x.upgradeWebSocket,px=x.websocket}catch(O){iO.warn("[Terminal] Failed to initialize Bun WebSocket support:",O)}async function _$(O,x){let $=`term-${Date.now()}`;iO.info(`[Terminal] New connection: ${$}, cwd: ${O}`);let w=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",Q=w.endsWith("sh")?["-l"]:[],Y=await V2(w,Q,{cwd:O,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),J={id:$,process:Y,cwd:O,buffer:"",subscribers:new Set};if(F0.set($,J),J.subscribers.add(x),Y.onData((K)=>{let S=!1;for(let B of J.subscribers)try{B.send(K),S=!0}catch{J.subscribers.delete(B)}if(S)return;if(J.buffer+=K,J.buffer.length>B$)J.buffer=J.buffer.slice(-B$)}),Y.onExit(({exitCode:K})=>{iO.info(`[Terminal] Process exited: ${$}, code: ${K}`);for(let S of J.subscribers)try{S.close()}catch{}F0.delete($)}),J.buffer){let K=J.buffer;J.buffer="";for(let S=0;S<K.length;S+=U$)x.send(K.slice(S,S+U$))}return{session:J,cleanup:()=>{if(iO.info(`[Terminal] Connection closed: ${$}`),J.subscribers.delete(x),J.subscribers.size===0){try{J.process.kill()}catch{}F0.delete($)}}}}function F$(O,x){O.on("connection",async($,w)=>{let Q=new URL(w.url||"/",`http://${w.headers.host}`);if(!Q.pathname.endsWith("/terminal/ws")){$.close();return}let Y=Q.searchParams.get("cwd")||x()||o();try{let{session:J,cleanup:K}=await _$(Y,{send:(S)=>$.send(S),close:()=>$.close()});$.on("message",(S)=>{try{J.process.write(String(S))}catch(B){iO.error("[Terminal] Failed to write to PTY:",B)}}),$.on("close",K),$.on("error",K)}catch(J){iO.error("[Terminal] Failed to spawn PTY:",J),$.close()}})}var L$=()=>{let O=new G2;if(O.get("/status",(x)=>{let $=Array.from(F0.values()).map((w)=>({id:w.id,cwd:w.cwd}));return x.json({active:$.length,terminals:$})}),O.post("/kill/:terminalId",(x)=>{let $=x.req.param("terminalId"),w=F0.get($);if(w){try{w.process.kill()}catch{}for(let Q of w.subscribers)Q.close();return F0.delete($),x.json({success:!0})}return x.json({success:!1,error:"Terminal not found"},404)}),ux)O.get("/ws",ux((x)=>{let $=x.req.query("cwd")||x.get("directory")||o(),w;return{async onOpen(Q,Y){try{w=await _$($,{send:(J)=>Y.send(J),close:()=>Y.close()})}catch(J){iO.error("[Terminal] Failed to spawn PTY:",J),Y.close()}},onMessage(Q){if(!w)return;try{w.session.process.write(String(Q.data))}catch(Y){iO.error("[Terminal] Failed to write to PTY:",Y)}},onClose(){w?.cleanup()}}}));else O.get("/ws",(x)=>{return x.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return O};import B2 from"node:path";import{Hono as U2}from"hono";var K2=W.Object({projectPath:W.String({minLength:1}),action:e(["trust","revoke"])});function D$(O){if(!B2.isAbsolute(O))throw new _("projectPath must be absolute")}var b$=()=>{let O=new U2;return O.get("/",async(x)=>{let $=x.req.query("projectPath");if(!$)throw new _("projectPath query parameter is required");return D$($),x.json(await dx.getInstance().getStatus($))}),O.post("/",async(x)=>{let $=f(K2,await x.req.json());if(!$.success)throw new _("Invalid workspace trust request");let{projectPath:w,action:Q}=$.data;D$(w);let Y=dx.getInstance(),J=Q==="trust"?await Y.trust(w):await Y.revoke(w);return await H$(),x.json({...J,reloadRequired:J.sensitiveSources>0})}),O};var BO=t("Service"),ix=[],Zx,L0,D0,u0,A$=new Map,S$=new Map,R2=new Set([".css",".html",".js",".json",".svg"]),q2=1024,C2=3600000;function I2(O,x){if(!O)return 0;let $=O.split(",").map((w)=>{let[Q,...Y]=w.trim().toLowerCase().split(";"),J=Y.find((S)=>S.trim().startsWith("q=")),K=J?Number(J.trim().slice(2)):1;return{name:Q,quality:Number.isFinite(K)?Math.max(0,Math.min(1,K)):0}});return $.find((w)=>w.name===x)?.quality??$.find((w)=>w.name==="*")?.quality??0}function j$(){if(D0)return;let O=()=>{C.collectStaleEmptySessions().then((x)=>{if(x>0)BO.info(`[SessionGC] removed ${x} stale empty session(s)`)}).catch((x)=>{BO.warn("[SessionGC] failed to collect stale empty sessions:",x)})};O(),D0=setInterval(O,C2),D0.unref?.()}function E2(){if(!D0)return;clearInterval(D0),D0=void 0}function k2(O){return["br","gzip"].map(($)=>({encoding:$,quality:I2(O,$)})).filter(($)=>$.quality>0).sort(($,w)=>w.quality-$.quality||($.encoding==="br"?-1:1))[0]?.encoding}function f2(O){let x=A$.get(O);if(x)return x;let $=p0(O);return A$.set(O,$),$}function P2(O,x,$){let w=`${$}:${O}`,Q=S$.get(w);if(Q)return Q;let Y=$==="br"?b2(x,{params:{[S2.BROTLI_PARAM_QUALITY]:5}}):A2(x,{level:6});return S$.set(w,Y),Y}function y2(){let O=L2(H2(import.meta.url)),x=[cO(O,"web"),cO(o(),"dist/web"),cO(o(),"packages/cli/dist/web")];for(let $ of x){let w=cO($,"index.html");if(lx(w)){if(p0(w,"utf-8").includes("/assets/"))return BO.debug(`[Server] Found web dist at: ${$}`),$}}return null}function m2(){let O=new j2;O.onError((w,Q)=>{if(BO.error("[Server] Request error:",w),w instanceof R$){let J=new PO(w.message,{resource:"workspace_agent_resources",limit:w.capacity});return Q.json(J.toObject(),429)}if(w instanceof r)return Q.json(w.toObject(),w.statusCode);let Y=w instanceof Error?w.message:String(w);return Q.json({error:{code:"INTERNAL_ERROR",message:Y}},500)}),O.use(async(w,Q)=>{let Y=process.env.BLADE_SERVER_PASSWORD;if(!Y)return Q();let J=w.req.path;if(J==="/"||J==="/favicon.svg"||J.startsWith("/assets/")||J.endsWith(".html")||J.endsWith(".js")||J.endsWith(".css"))return Q();let K=w.req.header("Authorization");if(!K?.startsWith("Basic "))return w.header("WWW-Authenticate",'Basic realm="Blade Server"'),w.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let S=Buffer.from(K.slice(6),"base64").toString(),[B,A]=S.split(":"),H=process.env.BLADE_SERVER_USERNAME??"blade";if(B!==H||A!==Y)return w.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return Q()}),O.use(async(w,Q)=>{let Y=w.req.path==="/health"||w.req.path==="/global/health"||w.req.path.startsWith("/assets/");if(!Y)BO.debug(`[Server] ${w.req.method} ${w.req.path}`);let J=Date.now();if(await Q(),!Y){let K=Date.now()-J;BO.debug(`[Server] ${w.req.method} ${w.req.path} - ${w.res.status} (${K}ms)`)}}),O.use(M2({origin(w){if(!w)return;if(w.startsWith("http://localhost:"))return w;if(w.startsWith("http://127.0.0.1:"))return w;if(w==="tauri://localhost"||w==="http://tauri.localhost")return w;if(ix.includes(w))return w;return}})),O.use(async(w,Q)=>{let Y=w.req.query("directory")||w.req.header("x-blade-directory")||o();try{Y=decodeURIComponent(Y)}catch{}return w.set("directory",Y),Q()});let x=F4();u0=x,Zx=x.recoverQueuedTasks,L0=new zx({dispatch:(w)=>x.dispatchTask(w),store:vx}),O.route("/global",W1()),O.route("/events",Y1()),O.route("/sessions",x.app),O.route("/tasks",Z$(x)),O.route("/teams",V$()),O.route("/schedules",c4(vx,L0)),O.route("/configs",x1()),O.route("/permissions",D4()),O.route("/plugins",f4()),O.route("/hooks",U1()),O.route("/workspace-trust",b$()),O.route("/providers",d4()),O.route("/models",S1()),O.route("/projects",m4()),O.route("/suggestions",O$()),O.route("/terminal",L$()),O.route("/mcp",F1()),O.route("/skills",s4()),O.get("/health",(w)=>{return w.json({healthy:!0,version:J0()})});let $=y2();if($)BO.info(`[Server] Serving static files from ${$}`),O.get("/favicon.svg",()=>{let w=cO($,"favicon.svg");if(!lx(w))return new Response(null,{status:404});return new Response(p0(w),{headers:{"Content-Type":"image/svg+xml","Cache-Control":"public, max-age=86400"}})}),O.get("/assets/*",(w)=>{let Q=cO($,w.req.path);if(!lx(Q))return w.json({error:{code:"NOT_FOUND",message:`File not found: ${w.req.path}`}},404);let Y=f2(Q),J=D2(Q).toLowerCase(),S={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[J]||"application/octet-stream",B=R2.has(J)&&Y.byteLength>=q2?k2(w.req.header("Accept-Encoding")):void 0,A=B?P2(Q,Y,B):Y;return new Response(new Uint8Array(A),{headers:{"Content-Type":S,"Content-Length":String(A.byteLength),"Cache-Control":"public, max-age=31536000, immutable",Vary:"Accept-Encoding",...B?{"Content-Encoding":B}:{}}})}),O.get("/",(w)=>{let Q=cO($,"index.html"),Y=p0(Q,"utf-8");return w.html(Y,200,{"Cache-Control":"no-cache"})}),O.get("*",(w)=>{let Q=w.req.path;if(Q.includes("."))return w.json({error:{code:"NOT_FOUND",message:`File not found: ${Q}`}},404);let Y=cO($,"index.html"),J=p0(Y,"utf-8");return w.html(J,200,{"Cache-Control":"no-cache"})});else BO.warn('[Server] Web UI not found. Run "cd packages/cli/web && bun run build" to enable web interface.'),O.get("/",(w)=>{return w.json({message:"Blade API Server",version:J0(),webUI:!1,hint:'Web UI not built. Run "cd packages/cli/web && bun run build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),O.all("*",(w)=>{return w.json({error:{code:"NOT_FOUND",message:`Route not found: ${w.req.path}`}},404)});return O}function h2(){let O=F2(),x=[];for(let $ of Object.keys(O)){let w=O[$];if(!w)continue;for(let Q of w){if(Q.internal||Q.family!=="IPv4")continue;if(Q.address.startsWith("172."))continue;x.push(Q.address)}}return x}function M$(){return typeof globalThis.Bun<"u"}function T$(O,x){let $=globalThis.Bun,w=(Y)=>{try{return $.serve({hostname:x.hostname,port:Y,fetch:O.fetch,idleTimeout:0,websocket:px})}catch(J){BO.error("Failed to start Bun server:",J);return}},Q=x.port===0?w(4096)??w(0):w(x.port);if(!Q)throw Error(`Failed to start Bun server on port ${x.port}`);return{url:Q.url,port:Q.port,hostname:Q.hostname,stop:async()=>{Q.stop(!0)}}}function g2(O,x){return new Promise(($,w)=>{let Q=_2(async(B,A)=>{let H=new URL(B.url||"/",`http://${B.headers.host}`),U=new Headers;for(let[l,JO]of Object.entries(B.headers))if(JO)if(Array.isArray(JO))for(let T of JO)U.append(l,T);else U.set(l,JO);let R;if(B.method!=="GET"&&B.method!=="HEAD")R=(await new Promise((JO)=>{let T=[];B.on("data",(NO)=>T.push(NO)),B.on("end",()=>JO(Buffer.concat(T)))})).toString();let c=new Request(H.toString(),{method:B.method,headers:U,body:R});try{let l=await O.fetch(c);if(A.statusCode=l.status,l.headers.forEach((JO,T)=>{A.setHeader(T,JO)}),l.body){let JO=l.body.getReader(),T=async()=>{let{done:NO,value:p}=await JO.read();if(NO){A.end();return}return A.write(p),T()};await T()}else{let JO=await l.text();A.end(JO)}}catch(l){BO.error("[Server] Node request error:",l),A.statusCode=500,A.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),Y=new T2({noServer:!0}),J=o();F$(Y,()=>J),Q.on("upgrade",(B,A,H)=>{if(new URL(B.url||"/",`http://${B.headers.host}`).pathname==="/terminal/ws")Y.handleUpgrade(B,A,H,(R)=>{Y.emit("connection",R,B)});else A.destroy()});let K=(B)=>{return new Promise((A,H)=>{Q.once("error",(U)=>{if(U.code==="EADDRINUSE")H(U);else H(U)}),Q.listen(B,x.hostname,()=>{let U=Q.address();if(U&&typeof U==="object")A(U.port);else A(B)})})};(async()=>{let B;if(x.port===0)try{B=await K(4096)}catch{B=await K(0)}else B=await K(x.port);let A=new URL(`http://${x.hostname==="0.0.0.0"?"localhost":x.hostname}:${B}`);$({url:A,port:B,hostname:x.hostname,stop:async()=>{return new Promise((H)=>{Y.close(()=>{Q.close(()=>H())})})}})})().catch(w)})}var C$;((y8)=>{let O,x,$,w=(B,A)=>{if(O!==B)return Promise.resolve();if($)return $;let H=A?.shutdown("server-shutdown");return L0?.stop(),E2(),$=(async()=>{let U,R=async(c)=>{if(!c)return;try{await c()}catch(l){U??=l}};if(await R(()=>B.stop()),await R(H?()=>H:void 0),q$(),O===B)O=void 0,x=void 0,u0=void 0,Zx=void 0,L0=void 0;if(BO.info("[Server] Blade server stopped"),U!==void 0)throw U})(),$};function Q(){if(!x)x=m2();return x}y8.getApp=Q;function Y(B){ix=B.cors??[];let A=Q();if(M$())O=T$(A,B),$=void 0,BO.info(`[Server] Blade server listening on ${O.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let H=O,U=u0;return Zx?.().catch((R)=>{BO.warn("[Server] Failed to recover queued tasks:",R)}),L0?.start(),j$(),{url:H.url,port:H.port,hostname:H.hostname,stop:()=>w(H,U)}}y8.listen=Y;async function J(B){ix=B.cors??[];let A=Q();if(M$())O=T$(A,B),BO.info(`[Server] Blade server listening on ${O.url} (Bun runtime)`);else O=await g2(A,B),BO.info(`[Server] Blade server listening on ${O.url} (Node.js runtime)`);$=void 0;let H=O,U=u0;try{await Zx?.()}catch(R){BO.warn("[Server] Failed to recover queued tasks:",R)}return L0?.start(),j$(),{url:H.url,port:H.port,hostname:H.hostname,stop:()=>w(H,U)}}y8.listenAsync=J;function K(){return O!==void 0}y8.isRunning=K;function S(){return u0?.getCoordinationStats()}y8.getSessionCoordinationStatsForTests=S})(C$||={});export{u2 as a,p2 as b,h2 as c,C$ as d};
|