@maincode-ai/matilda-code 0.21.2 → 0.21.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +7 -0
  2. package/chunks/{agent-B4THN25M.js → agent-WBKEN3MM.js} +1 -1
  3. package/chunks/{agent-headless-CR55Q5QA.js → agent-headless-OJM6RWIA.js} +1 -1
  4. package/chunks/{anthropicContentGenerator-GW3P6NLQ.js → anthropicContentGenerator-EFVV6ZTA.js} +1 -1
  5. package/chunks/{chunk-CFBZKYFB.js → chunk-6QP5C76Y.js} +52 -52
  6. package/chunks/{chunk-MAQJCFZU.js → chunk-7LNKXNEZ.js} +526 -517
  7. package/chunks/{chunk-GIIMOLLN.js → chunk-C2ZWB2NT.js} +1 -1
  8. package/chunks/{chunk-NUJ63BIE.js → chunk-DBSJNFFU.js} +1 -1
  9. package/chunks/{chunk-SS5WUOSJ.js → chunk-FT76AZPN.js} +1 -1
  10. package/chunks/chunk-FU2PKCG5.js +108 -0
  11. package/chunks/{chunk-QEUJHX22.js → chunk-IZ6YBZWM.js} +13 -13
  12. package/chunks/{chunk-M3G4PG2T.js → chunk-JDXISO3F.js} +4 -4
  13. package/chunks/chunk-MJEXA2MA.js +8 -0
  14. package/chunks/chunk-MTMU7JYZ.js +11 -0
  15. package/chunks/chunk-SDTWBD62.js +8 -0
  16. package/chunks/{chunk-JEDNTIM3.js → chunk-ZYW5GLYY.js} +1 -1
  17. package/chunks/{computer-use-STZBQBFP.js → computer-use-MCXFHFTP.js} +1 -1
  18. package/chunks/{contextCommand-LB5MHXJY.js → contextCommand-G4LS5GW6.js} +1 -1
  19. package/chunks/edit-KNZAPSGJ.js +39 -0
  20. package/chunks/{enter-worktree-V6TA7IPP.js → enter-worktree-LJ66TFYR.js} +1 -1
  21. package/chunks/{enterPlanMode-KQCLOC2K.js → enterPlanMode-P6EIGU3Y.js} +1 -1
  22. package/chunks/{exit-worktree-B3SWF6PM.js → exit-worktree-QVQ3TLW5.js} +1 -1
  23. package/chunks/{exitPlanMode-7OHF37SX.js → exitPlanMode-I7SGPSG4.js} +1 -1
  24. package/chunks/{geminiContentGenerator-6VRAJ3BI.js → geminiContentGenerator-SBVCQ423.js} +1 -1
  25. package/chunks/{glob-ZAZPTZD5.js → glob-F5YOX6YA.js} +1 -1
  26. package/chunks/{grep-DNYRXQWA.js → grep-UOIHSM5U.js} +1 -1
  27. package/chunks/{matildaAgentContentGenerator-S26H4H3W.js → matildaAgentContentGenerator-EIQI4YCP.js} +10 -10
  28. package/chunks/{matildaContentGenerator-UFATU4UK.js → matildaContentGenerator-QMMGDPIK.js} +1 -1
  29. package/chunks/{monitor-HQXCJQ3M.js → monitor-GDKHPTET.js} +1 -1
  30. package/chunks/notebook-edit-LWH7H4WX.js +17 -0
  31. package/chunks/{openaiContentGenerator-XAPZXISY.js → openaiContentGenerator-TNZ6SB7H.js} +1 -1
  32. package/chunks/{read-file-HEVXSNSO.js → read-file-URGJTANM.js} +1 -1
  33. package/chunks/{ripGrep-BNBRX7HQ.js → ripGrep-SL4ICAX6.js} +1 -1
  34. package/chunks/{scheduler-3K7OROFK.js → scheduler-EX674HYK.js} +1 -1
  35. package/chunks/{serve-MBVRWSOA.js → serve-FZ4FTA5D.js} +7 -7
  36. package/chunks/{shell-3YF6VEDO.js → shell-LLU55LCI.js} +1 -1
  37. package/chunks/{skill-4GKPLUND.js → skill-KSYY6BM6.js} +1 -1
  38. package/chunks/src-UXJDJ3RJ.js +3 -0
  39. package/chunks/{symbol-search-WVNUJRET.js → symbol-search-3A66G4MP.js} +1 -1
  40. package/chunks/{team-create-2LLJKRSY.js → team-create-7PFAVYVV.js} +1 -1
  41. package/chunks/{tool-search-47TA6SG4.js → tool-search-7D46IF5G.js} +1 -1
  42. package/chunks/{update-goal-6WDBMJ2I.js → update-goal-EUJYH23K.js} +1 -1
  43. package/chunks/{web-fetch-QP42GV23.js → web-fetch-UGTFUOQN.js} +1 -1
  44. package/chunks/{workflow-EIZTKOPX.js → workflow-2TGFLD2R.js} +2 -2
  45. package/chunks/write-file-DQ6NYEJ7.js +15 -0
  46. package/cli.js +443 -444
  47. package/package.json +2 -2
  48. package/sandbox-macos-restrictive-open.sb +22 -2
  49. package/chunks/chunk-I55PXD4N.js +0 -10
  50. package/chunks/chunk-KFULPF66.js +0 -107
  51. package/chunks/chunk-OCXGNAAT.js +0 -8
  52. package/chunks/chunk-RBG4ERTN.js +0 -11
  53. package/chunks/chunk-XJDC3ZQZ.js +0 -8
  54. package/chunks/edit-EP7HIW5W.js +0 -39
  55. package/chunks/notebook-edit-S63FQCCF.js +0 -17
  56. package/chunks/src-4XJIGVTS.js +0 -3
  57. package/chunks/write-file-YT7UT6TX.js +0 -15
@@ -1,6 +1,6 @@
1
1
  // Force strict mode and setup for ESM
2
2
  "use strict";
3
- import{a as Ru}from"./chunk-PA6532AY.js";import{a as wv}from"./chunk-XMZIY7XX.js";import{$a as Ev,Aa as Gi,B as ns,Ba as or,Ca as an,D as Iu,Da as ar,Ea as Mr,Fa as mt,Ga as cr,Ha as Or,Ia as Dr,Ja as cn,Ka as dn,La as un,Ma as ot,Na as bv,Oa as Ki,Pa as ss,Qa as Mu,Ra as ke,Sa as fe,Ta as Sv,Ua as ln,V as xu,Va as pn,Wa as Ou,X as Tt,Xa as Ji,Ya as Xi,Za as Yi,_a as Qi,ab as Zi,bb as Mt,cb as Du,db as Fu,ga as _u,ha as Cu,hb as Lu,ia as Pt,ib as Nu,ja as Tu,ka as zi,la as Ye,ma as wt,oa as Pu,pa as ie,qa as nn,ra as sn,sa as sr,ta as Cr,ua as on,va as Tr,wa as bt,x as Ui,xa as St,ya as ir,za as Pr}from"./chunk-M3G4PG2T.js";import{a as Su,b as D,d as Eu}from"./chunk-NUJ63BIE.js";import{a as ku,b as rn,d as Au,e as Vi}from"./chunk-JSFA3NEP.js";import{Ck as es,Dk as ts,Ek as rs,Fh as fu,Ma as kr,Oe as du,Pe as uu,Pj as mu,Qe as lu,Sj as gu,Tj as vu,Uj as yu,_h as yv,ce as iu,ef as Ar,ff as Ve,fk as Hi,hh as pu,hk as wu,ij as tt,je as ou,jj as Zn,lk as bu,oe as Wi,pe as au,qe as cu,yf as Qn,zl as Rr}from"./chunk-MAQJCFZU.js";import"./chunk-TZIDSCTF.js";import"./chunk-FUNLOUYI.js";import"./chunk-R3H6IWFK.js";import"./chunk-OMZ5SGMK.js";import"./chunk-GIIMOLLN.js";import{e as hu}from"./chunk-RBG4ERTN.js";import"./chunk-TXMXCR7D.js";import"./chunk-YULUB745.js";import"./chunk-LQWORCPO.js";import"./chunk-TISQNFB5.js";import"./chunk-SS5WUOSJ.js";import"./chunk-47XR7IMP.js";import"./chunk-QEI3OETI.js";import"./chunk-QKYGQLWC.js";import"./chunk-MNGFXISD.js";import"./chunk-4R2OFVPK.js";import"./chunk-RNKDFE2S.js";import"./chunk-EMWHQSMS.js";import{b as Yd,e as Qd}from"./chunk-S4K76QPI.js";import{C as Bd,D as qd,E as jd,F as Wd,G as Hd,H as Ud,I as Vd,J as zd,K as Gd,L as Kd,U as Jd,V as Xd,n as Fd,o as $i,p as Bi,q as Yn,s as Ld,u as Nd,v as $d,w as qi,x as _r}from"./chunk-KFULPF66.js";import"./chunk-4F4DA5UI.js";import"./chunk-DC7LAFZZ.js";import"./chunk-QLEJOI4X.js";import"./chunk-4J6DC24J.js";import{b as Rd}from"./chunk-LJR4RZZ2.js";import"./chunk-U347OO7S.js";import"./chunk-XJDC3ZQZ.js";import{Cb as Md,Eb as Od,Fb as Dd,Y as Td,da as xr,ea as Pd,j as He,t as Cd}from"./chunk-CFBZKYFB.js";import"./chunk-WVY2P6WH.js";import"./chunk-UIRBHC5X.js";import"./chunk-UY2R3ZQ4.js";import"./chunk-NDR7ZFUA.js";import"./chunk-5U3A6KMU.js";import{f as Zd,h as ji,i as eu,j as tu,k as ru,m as nu,r as su}from"./chunk-IMYUVCF7.js";import"./chunk-XKDGRW3K.js";import"./chunk-ESSYHTAZ.js";import"./chunk-3YLXGE6T.js";import"./chunk-IOCF4XSR.js";import{L as Xn,M as Ad}from"./chunk-QWBNNEV2.js";import{a as ht}from"./chunk-G7R2XEEF.js";import{a as vv}from"./chunk-OA56BXPD.js";import"./chunk-FWDMPRKU.js";import{b as w}from"./chunk-GZPNIYVZ.js";import{a as se,d as L,f as gv}from"./chunk-OWGSC52X.js";var fn=L((k_,ju)=>{w();var Iv=se("path").relative;ju.exports=Rv;var xv=process.cwd();function Bu(t,e){for(var r=t.split(/[ ,]+/),n=String(e).toLowerCase(),s=0;s<r.length;s++){var i=r[s];if(i&&(i==="*"||i.toLowerCase()===n))return!0}return!1}function _v(t,e,r){var n=Object.getOwnPropertyDescriptor(t,e),s=n.value;return n.get=function(){return s},n.writable&&(n.set=function(o){return s=o}),delete n.value,delete n.writable,Object.defineProperty(t,e,n),n}function kv(t){for(var e="",r=0;r<t;r++)e+=", arg"+r;return e.substr(2)}function Av(t){var e=this.name+": "+this.namespace;this.message&&(e+=" deprecated "+this.message);for(var r=0;r<t.length;r++)e+=`
3
+ import{a as Ru}from"./chunk-PA6532AY.js";import{a as wv}from"./chunk-XMZIY7XX.js";import{$a as Qi,Aa as Pr,B as ns,Ba as Gi,Ca as or,D as Iu,Da as an,Ea as ar,Fa as Mr,Ga as mt,Ha as cr,Ia as Or,Ja as Dr,Ka as cn,La as dn,Ma as un,Na as ot,Oa as bv,Pa as Ki,Qa as ss,Ra as Mu,Sa as ke,Ta as fe,Ua as Sv,Va as ln,W as xu,Wa as pn,Xa as Ou,Y as Tt,Ya as Ji,Za as Xi,_a as Yi,ab as Ev,bb as Zi,cb as Mt,db as Du,eb as Fu,ha as _u,ia as Cu,ib as Lu,ja as Pt,jb as Nu,ka as Tu,la as zi,ma as Ye,na as wt,pa as Pu,qa as ie,ra as nn,sa as sn,ta as sr,ua as Cr,va as on,wa as Tr,x as Ui,xa as bt,ya as St,za as ir}from"./chunk-JDXISO3F.js";import{a as Su,b as D,d as Eu}from"./chunk-DBSJNFFU.js";import{a as ku,b as rn,d as Au,e as Vi}from"./chunk-JSFA3NEP.js";import{$a as au,Hl as Rr,Ii as yv,Ke as lu,Kk as es,Lk as ts,Ma as kr,Mk as rs,Nf as Ar,Of as Ve,Re as pu,Rh as yu,Sj as tt,Tj as Zn,We as Hi,Xa as iu,Xe as fu,Ye as hu,_a as ou,ab as cu,fg as Qn,nb as Wi,ni as wu,pb as du,tb as uu,vf as mu,wf as gu,xf as vu}from"./chunk-7LNKXNEZ.js";import"./chunk-TZIDSCTF.js";import"./chunk-FUNLOUYI.js";import"./chunk-R3H6IWFK.js";import"./chunk-OMZ5SGMK.js";import"./chunk-C2ZWB2NT.js";import{e as bu}from"./chunk-MTMU7JYZ.js";import"./chunk-TXMXCR7D.js";import"./chunk-YULUB745.js";import"./chunk-LQWORCPO.js";import"./chunk-TISQNFB5.js";import"./chunk-FT76AZPN.js";import"./chunk-47XR7IMP.js";import"./chunk-QEI3OETI.js";import"./chunk-QKYGQLWC.js";import"./chunk-MNGFXISD.js";import"./chunk-4R2OFVPK.js";import"./chunk-RNKDFE2S.js";import"./chunk-EMWHQSMS.js";import{b as Yd,e as Qd}from"./chunk-S4K76QPI.js";import{C as Bd,D as qd,E as jd,F as Wd,G as Hd,H as Ud,I as Vd,J as zd,K as Gd,L as Kd,U as Jd,V as Xd,n as Fd,o as $i,p as Bi,q as Yn,s as Ld,u as Nd,v as $d,w as qi,x as _r}from"./chunk-FU2PKCG5.js";import"./chunk-4F4DA5UI.js";import"./chunk-DC7LAFZZ.js";import"./chunk-QLEJOI4X.js";import"./chunk-4J6DC24J.js";import{b as Rd}from"./chunk-LJR4RZZ2.js";import"./chunk-U347OO7S.js";import"./chunk-SDTWBD62.js";import{Cb as Md,Eb as Od,Fb as Dd,Y as Td,da as xr,ea as Pd,j as He,t as Cd}from"./chunk-6QP5C76Y.js";import"./chunk-WVY2P6WH.js";import"./chunk-UIRBHC5X.js";import"./chunk-UY2R3ZQ4.js";import"./chunk-NDR7ZFUA.js";import"./chunk-5U3A6KMU.js";import{f as Zd,h as ji,i as eu,j as tu,k as ru,m as nu,r as su}from"./chunk-IMYUVCF7.js";import"./chunk-XKDGRW3K.js";import"./chunk-ESSYHTAZ.js";import"./chunk-3YLXGE6T.js";import"./chunk-IOCF4XSR.js";import{L as Xn,M as Ad}from"./chunk-QWBNNEV2.js";import{a as ht}from"./chunk-G7R2XEEF.js";import{a as vv}from"./chunk-OA56BXPD.js";import"./chunk-FWDMPRKU.js";import{b as w}from"./chunk-GZPNIYVZ.js";import{a as se,d as L,f as gv}from"./chunk-OWGSC52X.js";var fn=L((k_,ju)=>{w();var Iv=se("path").relative;ju.exports=Rv;var xv=process.cwd();function Bu(t,e){for(var r=t.split(/[ ,]+/),n=String(e).toLowerCase(),s=0;s<r.length;s++){var i=r[s];if(i&&(i==="*"||i.toLowerCase()===n))return!0}return!1}function _v(t,e,r){var n=Object.getOwnPropertyDescriptor(t,e),s=n.value;return n.get=function(){return s},n.writable&&(n.set=function(o){return s=o}),delete n.value,delete n.writable,Object.defineProperty(t,e,n),n}function kv(t){for(var e="",r=0;r<t;r++)e+=", arg"+r;return e.substr(2)}function Av(t){var e=this.name+": "+this.namespace;this.message&&(e+=" deprecated "+this.message);for(var r=0;r<t.length;r++)e+=`
4
4
  at `+t[r].toString();return e}function Rv(t){if(!t)throw new TypeError("argument namespace is required");var e=os(),r=Fr(e[1]),n=r[0];function s(i){is.call(s,i)}return s._file=n,s._ignored=Tv(t),s._namespace=t,s._traced=Pv(t),s._warned=Object.create(null),s.function=Fv,s.property=Lv,s}function Cv(t,e){var r=typeof t.listenerCount!="function"?t.listeners(e).length:t.listenerCount(e);return r>0}function Tv(t){if(process.noDeprecation)return!0;var e=process.env.NO_DEPRECATION||"";return Bu(e,t)}function Pv(t){if(process.traceDeprecation)return!0;var e=process.env.TRACE_DEPRECATION||"";return Bu(e,t)}function is(t,e){var r=Cv(process,"deprecation");if(!(!r&&this._ignored)){var n,s,i,o,a=0,c=!1,d=os(),u=this._file;for(e?(o=e,i=Fr(d[1]),i.name=o.name,u=i[0]):(a=2,o=Fr(d[a]),i=o);a<d.length;a++)if(n=Fr(d[a]),s=n[0],s===u)c=!0;else if(s===this._file)u=this._file;else if(c)break;var l=n?o.join(":")+"__"+n.join(":"):void 0;if(!(l!==void 0&&l in this._warned)){this._warned[l]=!0;var p=t;if(p||(p=i===o||!i.name?$u(o):$u(i)),r){var f=qu(this._namespace,p,d.slice(a));process.emit("deprecation",f);return}var g=process.stderr.isTTY?Ov:Mv,v=g.call(this,p,n,d.slice(a));process.stderr.write(v+`
5
5
  `,"utf8")}}}function Fr(t){var e=t.getFileName()||"<anonymous>",r=t.getLineNumber(),n=t.getColumnNumber();t.isEval()&&(e=t.getEvalOrigin()+", "+e);var s=[e,r,n];return s.callSite=t,s.name=t.getFunctionName(),s}function $u(t){var e=t.callSite,r=t.name;r||(r="<anonymous@"+eo(t)+">");var n=e.getThis(),s=n&&e.getTypeName();return s==="Object"&&(s=void 0),s==="Function"&&(s=n.name||s),s&&e.getMethodName()?s+"."+r:r}function Mv(t,e,r){var n=new Date().toUTCString(),s=n+" "+this._namespace+" deprecated "+t;if(this._traced){for(var i=0;i<r.length;i++)s+=`
6
6
  at `+r[i].toString();return s}return e&&(s+=" at "+eo(e)),s}function Ov(t,e,r){var n="\x1B[36;1m"+this._namespace+"\x1B[22;39m \x1B[33;1mdeprecated\x1B[22;39m \x1B[0m"+t+"\x1B[39m";if(this._traced){for(var s=0;s<r.length;s++)n+=`
@@ -64,9 +64,9 @@ return fn.apply(this, arguments)
64
64
  `)?t:`${t}
65
65
  `)}function K4(t){return t instanceof Error&&t.name==="FsError"&&typeof t.kind=="string"}function Zm(t){throw K4(t)?new Vi(-32603,t.message,{errorKind:t.kind,...t.hint!==void 0?{hint:t.hint}:{},...t.status!==void 0?{status:t.status}:{}}):t}function J4(t){return t.kind==="option"?{outcome:{outcome:"selected",optionId:t.optionId},...t.metadata??{}}:{outcome:{outcome:"cancelled"}}}var eg=64,tg=32,X4=500,rg=6e4,Tn=new Set(["plan","default","auto-edit","auto","bogan"]);function Y4(t){return t.isDirectory()?"directory":t.isSymbolicLink()?"symlink":t.isCharacterDevice()?"character device":t.isBlockDevice()?"block device":t.isFIFO()?"named pipe (FIFO)":t.isSocket()?"socket":"non-regular file"}function Q4(t,e,r){let n=0;for(let o=0;o<e;o++){let a=t.indexOf(`
66
66
  `,n);if(a===-1)return"";n=a+1}if(r===void 0)return t.slice(n);let s=n,i=r-e;for(let o=0;o<i;o++){let a=t.indexOf(`
67
- `,s);if(a===-1)return t.slice(n);s=a+1}return t.slice(n,s>n?s-1:s)}var Z4="mid_turn_message_injected",Cn=class{constructor(e,r,n,s,i,o,a,c){this.resolveEntry=e;this.resolvePendingRestoreEvents=r;this.mediator=n;this.permissionTimeoutMs=s;this.maxPendingPerSession=i;this.fileSystem=o;this.onModelPromoted=a;this.onModePromoted=c}async requestPermission(e){let r=this.resolveEntry(e.sessionId);if(!r)return{outcome:{outcome:"cancelled"}};if(r.pendingPermissionIds.size>=this.maxPendingPerSession)return G(`matilda serve: session ${r.sessionId} exceeded maxPendingPermissionsPerSession (${this.maxPendingPerSession}) \u2014 resolving new permission as cancelled.`),{outcome:{outcome:"cancelled"}};let n=new Set(e.options.map(o=>String(o.optionId??"")));n.delete("");let s=Qm();if(n.has(lt))throw new or(s,lt);if(!r.events.publish({type:"permission_request",data:{requestId:s,sessionId:r.sessionId,toolCall:e.toolCall,options:e.options},...r.activePromptOriginatorClientId?{originatorClientId:r.activePromptOriginatorClientId}:{}}))return{outcome:{outcome:"cancelled"}};r.pendingPermissionIds.add(s);try{let o={requestId:s,sessionId:r.sessionId,originatorClientId:r.activePromptOriginatorClientId,allowedOptionIds:n,issuedAtMs:Date.now()},a=await this.mediator.request(o,this.permissionTimeoutMs);return J4(a)}finally{r.pendingPermissionIds.delete(s)}}async sessionUpdate(e){let r=this.resolveEntry(e.sessionId),n=r?.events??this.resolvePendingRestoreEvents(e.sessionId);if(!n)return;let s=r?.activePromptOriginatorClientId?{originatorClientId:r.activePromptOriginatorClientId}:{},i=sE(e);if(i){for(let d of i.surfaces)n.publish({type:"session_update",data:{sessionId:e.sessionId,update:{sessionUpdate:"a2ui",a2ui:{surfaceId:d.surfaceId,callId:i.callId,commands:d.commands},_meta:{serverTimestamp:Date.now(),source:"a2ui-bridge"}}},...s});e=i.sanitizedParams}let o=e.update._meta,a=o?.serverTimestamp??o?.timestamp,c=typeof a=="number"&&Number.isFinite(a)?a:void 0;n.publish({type:"session_update",data:e,...s,...c!==void 0?{_meta:{serverTimestamp:c}}:{}})}earlyEvents=new Map;tombstonedSessionIds=new Map;inFlightRestoreIds=new Set;async extMethod(e,r){if(e!==Du)throw Vi.methodNotFound(e);let n=typeof r.sessionId=="string"?r.sessionId:void 0;if(!n)return{messages:[]};let s=this.resolveEntry(n);if(!s)return{messages:[]};let i=s.midTurnMessageQueue.splice(0),o=i.map(a=>a.text);if(i.length>0){let a=new Map;for(let c of i){let d=a.get(c.originatorClientId);d?d.push(c.text):a.set(c.originatorClientId,[c.text])}for(let[c,d]of a){let u=s.events.publish({type:Z4,data:{sessionId:s.sessionId,messages:d},...c?{originatorClientId:c}:{}});G(u?`[mid-turn] session=${s.sessionId} drained=${d.length}${c?` originator=${c}`:""} injected into running turn`:`[mid-turn] session=${s.sessionId} drained=${d.length} echo frame dropped (bus closed); browser may resend next turn`)}}return{messages:o}}async extNotification(e,r){if(e==="matilda/notify/session/model-update"){this.handleInSessionModelUpdate(r);return}if(e==="matilda/notify/session/mode-update"){this.handleInSessionModeUpdate(r);return}if(e==="matilda/notify/session/title-update"){let u=r.sessionId,l=r.title;if(typeof u!="string"||typeof l!="string"||!l)return;let p=this.resolveEntry(u);if(!p)return;try{p.events.publish({type:"session_metadata_updated",data:{sessionId:u,displayName:l,...typeof r.titleSource=="string"?{titleSource:r.titleSource}:{}}})}catch{}return}if(e==="matilda/notify/session/prompt-suggestion"){let u=r.sessionId,l=r.suggestion,p=r.promptId;if(typeof u!="string"||typeof l!="string"||l.length===0||l.length>X4||typeof p!="string"){G(`[demux] session=${typeof u=="string"?u:"<missing>"} type=prompt_suggestion action=dropped reason=malformed`);return}let f=this.resolveEntry(u);if(!f)return;f.events.publish({type:"followup_suggestion",data:{sessionId:u,suggestion:l,promptId:p}});return}if(e==="matilda/notify/session/terminal-sequence"){let u=r.sessionId;if(typeof u!="string")return;let{v:l,sessionId:p,...f}=r;this.publishExtNotification(u,"terminal_sequence",f);return}if(e!=="matilda/notify/session/mcp-budget-event")return;let n=r.sessionId;if(typeof n!="string")return;let s=r.kind,i;if(s==="budget_warning")i="mcp_budget_warning";else if(s==="refused_batch")i="mcp_child_refused_batch";else return;let{v:o,sessionId:a,kind:c,...d}=r;this.publishExtNotification(n,i,d)}publishExtNotification(e,r,n){let s=this.resolveEntry(e),i={type:r,data:n,...s?.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}};if(s){s.events.publish(i);return}this.bufferEarlyEvent(e,i)}handleInSessionModelUpdate(e){let r=e.sessionId,n=e.currentModelId;if(typeof r!="string"||typeof n!="string")return;let s=this.resolveEntry(r);if(!s){G(`[demux] session=${r} type=current_model_update action=dropped reason=no_entry`);return}if(s.modelRoundtripInFlight){G(`[demux] session=${r} type=current_model_update action=suppressed reason=bridge_roundtrip_in_flight`);return}this.onModelPromoted?this.onModelPromoted(s,n,s.activePromptOriginatorClientId):s.events.publish({type:"model_switched",data:{sessionId:r,modelId:n},...s.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}}),G(`[demux] session=${r} type=current_model_update action=promoted model=${n}`)}handleInSessionModeUpdate(e){let r=e.sessionId,n=e.currentModeId;if(typeof r!="string"||typeof n!="string")return;if(!Tn.has(n)){G(`[demux] session=${r} type=current_mode_update action=dropped reason=unknown_mode mode=${n}`);return}let s=this.resolveEntry(r);if(!s){G(`[demux] session=${r} type=current_mode_update action=dropped reason=no_entry`);return}if(s.approvalModeRoundtripInFlight){G(`[demux] session=${r} type=current_mode_update action=suppressed reason=bridge_roundtrip_in_flight`);return}if(this.onModePromoted?this.onModePromoted(s,n,s.activePromptOriginatorClientId):s.events.publish({type:"approval_mode_changed",data:{sessionId:r,previous:"default",next:n,persisted:!1},...s.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}}),e.legacyFrameSent===!0){G(`[demux] session=${r} type=current_mode_update action=promoted mode=${n} legacy_frame=skipped`);return}s.events.publish({type:"session_update",data:{sessionId:r,update:{sessionUpdate:"current_mode_update",currentModeId:n}},...s.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}}),G(`[demux] session=${r} type=current_mode_update action=promoted mode=${n}`)}bufferEarlyEvent(e,r){let n=Date.now();if(this.sweepExpiredTombstones(n),this.tombstonedSessionIds.has(e)&&!this.inFlightRestoreIds.has(e)){G(`matilda serve: dropping mcp guardrail extNotification for tombstoned session ${JSON.stringify(e)} (post-close stale event)`);return}this.sweepExpiredEarlyEvents(n);let s=this.earlyEvents.get(e);if(!s){if(this.earlyEvents.size>=eg){G(`matilda serve: dropping mcp guardrail extNotification \u2014 early-event buffer at MAX_EARLY_EVENT_SESSIONS (${eg}); possible session-id fanout abuse`);return}s={frames:[],expiresAt:n+rg},this.earlyEvents.set(e,s)}if(s.frames.length>=tg){G(`matilda serve: dropping mcp guardrail extNotification for session ${JSON.stringify(e)} \u2014 per-session cap (${tg}) reached`);return}s.frames.push(r)}sweepExpiredEarlyEvents(e){for(let[r,n]of this.earlyEvents)n.expiresAt<=e&&this.earlyEvents.delete(r)}sweepExpiredTombstones(e){for(let[r,n]of this.tombstonedSessionIds)n<=e&&this.tombstonedSessionIds.delete(r)}markSessionClosed(e){let r=Date.now();this.sweepExpiredTombstones(r),this.tombstonedSessionIds.set(e,r+rg),this.earlyEvents.delete(e)}markRestoreInFlight(e){this.inFlightRestoreIds.add(e)}clearRestoreInFlight(e){this.inFlightRestoreIds.delete(e)}drainEarlyEvents(e,r){this.tombstonedSessionIds.delete(e);let n=this.earlyEvents.get(e);if(n){for(let s of n.frames)r.events.publish(s);this.earlyEvents.delete(e)}}async writeTextFile(e){if(this.fileSystem)try{return await this.fileSystem.writeText(e)}catch(i){Zm(i)}let r=e.path;try{r=await kt.realpath(e.path)}catch(i){if((i&&typeof i=="object"&&"code"in i?i.code:void 0)!=="ENOENT")throw i;try{let a=await kt.readlink(e.path);r=ai.resolve(ai.dirname(e.path),a)}catch{}}let n=`${r}.${process.pid}.${Date.now()}.${Qm()}.tmp`,s;try{let i=await kt.stat(r);s={mode:i.mode&4095,uid:i.uid,gid:i.gid}}catch(i){if((i&&typeof i=="object"&&"code"in i?i.code:void 0)!=="ENOENT")throw i}try{await kt.writeFile(n,e.content,{encoding:"utf8",flag:"wx",mode:s?.mode??384}),s&&(await kt.chmod(n,s.mode).catch(()=>{}),await kt.chown(n,s.uid,s.gid).catch(()=>{})),await kt.rename(n,r)}catch(i){throw await kt.unlink(n).catch(()=>{}),i}return{}}async readTextFile(e){if(this.fileSystem)try{return await this.fileSystem.readText(e)}catch(i){Zm(i)}if(typeof e.limit=="number"&&e.limit<=0)return{content:""};let r=100*1024*1024,n=await kt.stat(e.path);if(!n.isFile())throw new Error(`readTextFile: ${e.path} is not a regular file (reported as ${Y4(n)}). Pipe / device / proc-like inputs can produce unbounded data and aren't supported by the bridge fs proxy.`);if(n.size>r)throw new Error(`readTextFile: ${e.path} is ${n.size} bytes, exceeds the ${r}-byte daemon cap. Tail/grep externally and feed the relevant slice instead.`);let s=await kt.readFile(e.path,"utf8");if(typeof e.line=="number"||typeof e.limit=="number"){let i=e.line??1,o=i>0?i-1:0,a=e.limit!=null?o+e.limit:void 0;return{content:Q4(s,o,a)}}return{content:s}}},eE=/(^|__)(present_ui|present_choices|a2ui_action)$/;function tE(t){return t?typeof t.serverId=="string"&&t.serverId.toLowerCase().includes("a2ui")?!0:typeof t.toolName=="string"&&eE.test(t.toolName):!1}function rE(t){let e=t.replace(/^\s+/,"");if(e[0]!=="[")return null;let r=0,n=!1,s=!1,i=-1;for(let o=0;o<e.length;o++){let a=e[o];if(n){s?s=!1:a==="\\"?s=!0:a==='"'&&(n=!1);continue}if(a==='"')n=!0;else if(a==="[")r++;else if(a==="]"&&(r--,r===0)){i=o+1;break}}if(i<0)return null;try{let o=JSON.parse(e.slice(0,i));return!Array.isArray(o)||o.length===0?null:[o,e.slice(i).trim()]}catch{return null}}function nE(t){let e=t;return e?.createSurface?.surfaceId??e?.updateComponents?.surfaceId??e?.updateDataModel?.surfaceId??e?.deleteSurface?.surfaceId}function sE(t){let e=t.update;if(!e||e.sessionUpdate!=="tool_call_update")return null;let r=e._meta;if(!tE(r))return null;let n=e.content;if(!Array.isArray(n))return null;let s=null,i=-1;for(let g=0;g<n.length;g++){let v=n[g]?.content;if(typeof v?.text=="string"&&(s=rE(v.text),s)){i=g;break}}if(!s)return null;let[o,a]=s,c=[],d=new Map;for(let g of o){let v=nE(g);if(!v){let x=g&&typeof g=="object"?Object.keys(g).join(",")||"empty object":typeof g;G(`a2ui: dropping command with unrecognized shape (${x})`);continue}d.has(v)||(d.set(v,[]),c.push(v)),d.get(v).push(g)}let u=c.map(g=>({surfaceId:g,commands:d.get(g)})),l=a||"[A2UI surface rendered]",p=n.map((g,v)=>v===i?{...g,content:{...g.content??{},text:l}}:g),f={...e,content:p};return typeof e.rawOutput=="string"&&(f.rawOutput=l),{surfaces:u,callId:typeof e.toolCallId=="string"?e.toolCallId:void 0,sanitizedParams:{...t,update:f}}}w();import{randomUUID as sg}from"node:crypto";import*as di from"node:path";w();var iE=new Set(["turn_complete","turn_error"]),oE=new Set(["slow_client_warning","client_evicted","replay_complete","stream_error"]),aE=new Set(["available_commands_update","current_mode_update"]),ci=class{compactedTurns=[];liveJournal=[];lastEventId=0;closed=!1;slots=[];toolSlotIndex=new Map;textSlotIndex=new Map;ingest(e){if(!this.closed&&(e.id!==void 0&&(this.lastEventId=e.id),!oE.has(e.type))){if(this.liveJournal.push(e),iE.has(e.type)){this.compactCurrentTurn(e);return}if(e.type==="session_update"){this.classifySessionUpdate(e);return}this.slots.push({kind:"misc",event:e})}}snapshot(){return{compactedTurns:this.compactedTurns.slice(),liveJournal:this.liveJournal.slice(),lastEventId:this.lastEventId}}seed(e){this.closed||(this.compactedTurns=e.compactedTurns.slice(),this.lastEventId=e.lastEventId,this.liveJournal=[],this.slots=[],this.toolSlotIndex.clear(),this.textSlotIndex.clear())}close(){this.closed||(this.closed=!0,this.compactedTurns=[],this.liveJournal=[],this.slots=[],this.toolSlotIndex.clear(),this.textSlotIndex.clear())}classifySessionUpdate(e){let r=e.data,n=r?.update?.sessionUpdate;if(!n){this.slots.push({kind:"misc",event:e});return}switch(n){case"agent_message_chunk":{this.mergeTextSlot("text",e,r);break}case"agent_thought_chunk":{this.mergeTextSlot("thought",e,r);break}case"tool_call":case"tool_call_update":{let s=r?.update?.toolCallId;if(!s){this.slots.push({kind:"misc",event:e});break}let i=this.toolSlotIndex.get(s);if(i!==void 0){let o=this.slots[i];o.event=uE(o.event,e)}else{let o=dE(e);this.toolSlotIndex.set(s,this.slots.length),this.slots.push({kind:"tool",toolCallId:s,event:o});let a=ng(r?.update?._meta);a&&(this.textSlotIndex.delete(`text::${a}`),this.textSlotIndex.delete(`thought::${a}`))}break}default:{if(aE.has(n)){let s=this.slots.findIndex(i=>i.kind==="latestWins"&&i.key===n);s!==-1?this.slots[s].event=e:this.slots.push({kind:"latestWins",key:n,event:e})}else this.slots.push({kind:"misc",event:e});break}}}mergeTextSlot(e,r,n){let s=n?.update?.content?.text??"",i=n?.update?._meta,o=ng(i);if(o!=null){let a=`${e}::${o}`,c=this.textSlotIndex.get(a);if(c!==void 0){let d=this.slots[c];d.chunks.push(s),r.id!==void 0&&(d.lastEventId=r.id),d.lastMeta=i??d.lastMeta,d.lastEnvelopeMeta=r._meta??d.lastEnvelopeMeta}else this.textSlotIndex.set(a,this.slots.length),this.slots.push({kind:e,parentToolCallId:o,chunks:[s],lastEventId:r.id??0,lastMeta:i,lastEnvelopeMeta:r._meta})}else{let a=this.slots[this.slots.length-1];a&&a.kind===e&&a.parentToolCallId==null?(a.chunks.push(s),r.id!==void 0&&(a.lastEventId=r.id),a.lastMeta=i??a.lastMeta,a.lastEnvelopeMeta=r._meta??a.lastEnvelopeMeta):this.slots.push({kind:e,parentToolCallId:void 0,chunks:[s],lastEventId:r.id??0,lastMeta:i,lastEnvelopeMeta:r._meta})}}compactCurrentTurn(e){let r=[];for(let n of this.slots)switch(n.kind){case"text":case"thought":r.push(cE(n.kind==="text"?"agent_message_chunk":"agent_thought_chunk",n.chunks.join(""),n.lastEventId,n.lastMeta,n.lastEnvelopeMeta));break;case"tool":case"misc":case"latestWins":r.push(n.event);break;default:break}r.push(e),this.compactedTurns.push(...r),this.liveJournal=[],this.slots=[],this.toolSlotIndex.clear(),this.textSlotIndex.clear()}};function cE(t,e,r,n,s){return{id:r||void 0,v:1,type:"session_update",...s!==void 0?{_meta:s}:{},data:{update:{sessionUpdate:t,content:{type:"text",text:e},...n!=null?{_meta:n}:{}}}}}function dE(t){let e=t.data;return e?.update?.sessionUpdate==="tool_call_update"?{...t,data:{...e,update:{...e.update,sessionUpdate:"tool_call"}}}:t}function ng(t){if(typeof t=="object"&&t!==null){let e=t.parentToolCallId;return typeof e=="string"&&e.length>0?e:void 0}}function uE(t,e){let r=t.data,n=e.data,s=r?.update??{},i=n?.update??{},o={...s};for(let[c,d]of Object.entries(i))d!=null&&(o[c]=d);o.sessionUpdate="tool_call";let a=t._meta||e._meta?{...t._meta??{},...e._meta??{}}:void 0;return{id:e.id??t.id,v:1,type:"session_update",...a?{_meta:a}:{},data:{...r,...n,update:o}}}w();var pE={captureContext:()=>{},runWithContext(t,e){return e()},withSpan(t,e,r){return r()},event(){},injectPromptContext(t){let e=t._meta;if(!e||typeof e!="object"||Array.isArray(e))return t;let r=e;if(!($i in r)&&!(Bi in r))return t;let n={...r};return delete n[$i],delete n[Bi],{...t,_meta:n}}};function pg(){let t=process.env.MATILDA_SERVE_DEBUG;return t?!["0","false","off","no"].includes(t.trim().toLowerCase()):!1}function _c(t){pg()&&G(`matilda serve debug: ${t}`)}var ig=256,fE=256;function hE(t){if(t===null||typeof t!="object")return;let e=t.answers;if(e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.entries(e).every(([,n])=>typeof n=="string"))return{answers:e}}function mE(t,e,r){let n=e.prompt;if(!Array.isArray(n)||n.length===0)return;let s=Date.now(),i=Math.min(n.length,fE);for(let o=0;o<i;o+=1){let a=n[o];if(!(!a||typeof a!="object"||Array.isArray(a)))try{t.events.publish({type:"session_update",data:{sessionId:e.sessionId,update:{sessionUpdate:"user_message_chunk",content:a,_meta:{serverTimestamp:s,source:"bridge-echo"}}},...r?{originatorClientId:r}:{}})}catch{}}}function gE(t,e,r,n){try{t.events.publish({type:"prompt_cancelled",data:{sessionId:e,...n?{reason:n}:{}},...r?{originatorClientId:r}:{}})}catch{}}function kc(t,e,r,n){if(t.cancelBroadcast){G(`broadcastPromptCancelledOnce: suppressed duplicate cancel for session ${e} (latch already set)`);return}t.cancelBroadcast=!0,gE(t,e,r,n)}function vE(t,e,r,n,s){t.events.publish({type:"turn_complete",data:{sessionId:e,stopReason:r.stopReason??"end_turn",...n?{promptId:n}:{}},...s?{originatorClientId:s}:{}})}function fg(t){if(t instanceof Error){let e=t.data;return og(e)??t.message}if(typeof t=="object"&&t!==null){let e=t,r=og(e.data);if(r)return r;let n=e.message;if(typeof n=="string")return n}return String(t)}function og(t){if(typeof t=="string"&&t.length>0)return t;if(typeof t=="object"&&t!==null){let e=t.details;if(typeof e=="string"&&e.length>0)return e;let r=t.message;if(typeof r=="string"&&r.length>0)return r}}function yE(t){if(typeof t!="object"||t===null||!("code"in t))return;let e=t.code;if(typeof e=="string")return e;if(typeof e=="number")return String(e)}function wE(t,e,r,n,s){let i=fg(r),o=yE(r);t.retryAllowed=!0,t.events.publish({type:"turn_error",data:{sessionId:e,message:i,...o?{code:o}:{},...n?{promptId:n}:{}},...s?{originatorClientId:s}:{}})}function bE(t){for(let e=0;e<t.length;e+=1){let r=t.charCodeAt(e);if(r<=31||r===127)return!0}return!1}var SE=1e4,EE=5e3,ag=3e5,IE=6e5,cg="matilda.daemon.retry",xE=6e4,_E=6e4,kE=12e4,dg=1e4,ug=20,AE=20,RE=5,lg=1e6,CE=5*60*1e3,TE=64,PE=6e4,ME=30*6e4;function gr(t){let e=t.sessionScope??"single",r;if(t.maxSessions===void 0)r=AE;else{if(Number.isNaN(t.maxSessions))throw new TypeError("Invalid maxSessions: NaN. Must be a number >= 0 (0 / Infinity = unlimited).");if(t.maxSessions<0)throw new TypeError(`Invalid maxSessions: ${t.maxSessions}. Must be >= 0 (0 / Infinity = unlimited).`);t.maxSessions===0||t.maxSessions===1/0?r=1/0:r=t.maxSessions}if(e!=="single"&&e!=="thread")throw new TypeError(`Invalid sessionScope: ${JSON.stringify(e)}. Expected 'single' or 'thread'.`);let n=t.eventRingSize??8e3;if(!Number.isInteger(n)||n<1||n>lg)throw new TypeError(`Invalid eventRingSize: ${t.eventRingSize}. Must be a positive integer in [1, ${lg}].`);let s=t.channelFactory??oi,i=t.childEnvOverrides?Object.freeze({...t.childEnvOverrides}):Object.freeze({}),o=t.initializeTimeoutMs??SE;if(o<=0)throw new TypeError(`Invalid initializeTimeoutMs: ${o}. Must be > 0.`);let a=t.permissionResponseTimeoutMs??CE,c=a>0&&Number.isFinite(a)?a:0,d=t.maxPendingPermissionsPerSession??TE,u=d>0&&Number.isFinite(d)?d:1/0,l=t.maxPendingPromptsPerSession??RE,p;if(l===0||l===Number.POSITIVE_INFINITY)p=1/0;else{if(!Number.isInteger(l)||l<0)throw new TypeError(`Invalid maxPendingPromptsPerSession: ${l}. Must be a non-negative integer (0 / Infinity = unlimited).`);p=l}if(!di.isAbsolute(t.boundWorkspace))throw new TypeError(`Invalid boundWorkspace: "${t.boundWorkspace}". Must be an absolute path.`);let f=t.boundWorkspace,g=t.persistApprovalMode,v=t.telemetry??pE,x,O,P,q=le(t.sessionReapIntervalMs,PE),U=le(t.sessionIdleTimeoutMs,ME),ae;function le(m,E){return m===void 0?E:m>0&&Number.isFinite(m)?Math.min(m,2147483647):0}function V(){P!==void 0&&(clearTimeout(P),P=void 0)}async function Se(m,E){m.isDying=!0,await m.channel.kill().catch(_=>{G(`matilda serve: channel kill failed${E?` (${E})`:""}: ${String(_)}`)})}function Te(){let m=t.channelIdleTimeoutMs;return m!==void 0&&Number.isFinite(m)&&m>0?Math.min(m,2147483647):0}async function Ze(m,E){let _=Te();if(_<=0){await Se(m,E);return}V(),P=setTimeout(()=>{P=void 0,m.sessionIds.size===0&&m.pendingRestoreIds.size===0&&(G(`matilda serve: idle timeout (${_}ms) expired, killing channel`),Se(m,"idle timeout"))},_),P.unref()}function Me(){if(q<=0||U<=0){G("matilda serve: session reaper disabled");return}G(`matilda serve: session reaper started (interval ${q}ms, idle threshold ${U}ms)`),ae=setInterval(()=>{if(S)return;let m=Date.now();for(let[E,_]of h){if(_.promptActive||_.events.subscriberCount>0)continue;let I=_.sessionLastSeenAt??Date.parse(_.createdAt),C=m-I;C<U||(G(`matilda serve: reaping idle session ${JSON.stringify(E)} (idle for ${Math.round(C/1e3)}s, threshold ${Math.round(U/1e3)}s)`),zn(E,void 0,{reason:"idle_timeout"}).catch(T=>{G(`matilda serve: session reaper failed to close ${JSON.stringify(E)}: ${T instanceof Error?T.stack??T.message:String(T)}`)}))}},q),ae.unref()}function Ue(){ae!==void 0&&(clearInterval(ae),ae=void 0)}let be=new Set,b,h=new Map,y=t.permissionConsensusQuorum;if(y!==void 0&&(!Number.isInteger(y)||y<1))throw new Error(`BridgeOptions.permissionConsensusQuorum must be a positive integer; got ${String(y)}`);let A=t.permissionAudit??Jm(),k=new si(t.permissionPolicy??"first-responder",{emit:(m,E)=>{h.get(m)?.events.publish(E)},audit:A,...y!==void 0?{consensusQuorum:y}:{},now:()=>Date.now(),votersForSession:m=>{let E=h.get(m);return E?new Set(E.clientIds.keys()):new Set}}),S=!1,R=m=>{_c(m),t.onDiagnosticLine&&pg()&&t.onDiagnosticLine(`matilda serve debug: ${m}`,"info")},F=new Map,H=new Map,Z=new Map,X=()=>`client_${sg()}`,pe=(m,E)=>{if(E&&m.clientIds.has(E))return m.clientIds.set(E,(m.clientIds.get(E)??0)+1),E;let _=X();return m.clientIds.set(_,1),_},de=(m,E)=>{if(E===void 0)return;let _=m.clientIds.get(E);_!==void 0&&(_<=1?(m.clientIds.delete(E),m.clientLastSeenAt.delete(E)):m.clientIds.set(E,_-1))},re=(m,E)=>{if(E!==void 0){if(!m.clientIds.has(E))throw new Tr(m.sessionId,E);return E}};async function xe(){if(V(),O&&!O.isDying)return O;if(b)return await b;let m=(async()=>{let E=await v.withSpan("channel.spawn",{"matilda-code.daemon.bridge.operation":"channel.spawn","matilda-code.daemon.channel.reused":!1},async()=>await s(f,i)),_=new Cn(T=>{if(T)return h.get(T);if(O&&O.sessionIds.size>1)throw new Error("BridgeClient: ACP call without sessionId on a multi-session channel cannot be routed \u2014 workspace="+f)},T=>T?Z.get(T):void 0,k,c,u,t.fileSystem,(T,M,N)=>Un(T,M,N),(T,M,N)=>{let z=T;Fi(z,{previous:z.currentApprovalMode??"default",next:M,persisted:!1},N)}),I=new Au(()=>_,E.stream),C={channel:E,connection:I,client:_,sessionIds:new Set,pendingRestoreIds:new Set,isDying:!1,handshakeComplete:!1};be.add(C),be.size>2&&G(`matilda serve: WARNING aliveChannels.size=${be.size} (expected 1, max 2 during killSession-then-spawnOrAttach overlap) \u2014 possible channel leak; check that prior channels' channel.exited fired and the handler ran cleanup.`),E.exited.then(T=>{O===C&&V(),be.delete(C),O===C&&(O=void 0);let M=Array.from(C.sessionIds);C.sessionIds.clear();let N=S||C.isDying;C.handshakeComplete&&v.metrics?.channelLifecycle("exit",N),S||(v.event("channel.exited",{"matilda-code.daemon.channel.exit_code":T?.exitCode??-1,"matilda-code.daemon.channel.session_count":M.length,...T?.signalCode?{"matilda-code.daemon.channel.signal":T.signalCode}:{}}),G(`matilda serve: channel exited (code=${T?.exitCode??"none"}, signal=${T?.signalCode??"none"}, ${M.length} session(s) torn down)`));for(let z of M){let J=h.get(z);if(J){Y(z);try{J.events.publish({type:"session_died",data:{sessionId:z,reason:"channel_closed",exitCode:T?.exitCode??null,signalCode:T?.signalCode??null}})}catch{}h.delete(z),v.metrics?.sessionLifecycle("die"),C.client.markSessionClosed(z),x===J&&(x=void 0),J.events.close()}}});try{await v.withSpan("channel.initialize",{"matilda-code.daemon.bridge.operation":"channel.initialize"},async()=>await Ce(I.initialize({protocolVersion:ku,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}},clientInfo:{name:"matilda-serve-bridge",version:"0"}}),o,"initialize"))}catch(T){throw C.isDying=!0,await E.kill().catch(()=>{}),T}if(S)throw C.isDying=!0,await E.kill().catch(()=>{}),new Error("AcpSessionBridge is shutting down");return O=C,C.handshakeComplete=!0,v.metrics?.channelLifecycle("spawn"),C})();b=m;try{return await m}finally{b=void 0}}async function he(m,E,_){let I=await xe(),C;try{C=await v.withSpan("session.new",{"matilda-code.daemon.bridge.operation":"session.new","matilda-code.daemon.session_scope":E},async()=>await Ce(I.connection.newSession({cwd:f,mcpServers:[]}),o,"newSession"))}catch(N){throw I.sessionIds.size===0&&(I.isDying=!0,await I.channel.kill().catch(()=>{})),N}if(S)throw new Error("AcpSessionBridge is shutting down");let T=_d(I,C.sessionId,f);kd(T,C);let M=pe(T,_);if(E==="single"&&!x&&(x=T),m&&await K(T,m,o,M).catch(()=>{}),!h.has(T.sessionId))throw new Error(`Session ${T.sessionId} died during model-switch initialization`);return{sessionId:T.sessionId,workspaceCwd:T.workspaceCwd,attached:!1,clientId:M,createdAt:T.createdAt}}async function K(m,E,_,I){let C=m.connection,T=Ee(m),M=m.modelChangeQueue.then(async()=>{m.modelRoundtripInFlight=!0;let N=!1;try{await Promise.race([Ce(C.unstable_setSessionModel({sessionId:m.sessionId,modelId:E}),_,"setSessionModel"),T]),Un(m,E,I),N=!0}catch(z){throw m.events.publish({type:"model_switch_failed",data:{sessionId:m.sessionId,requestedModelId:E,error:z instanceof Error?z.message:String(z)},...I?{originatorClientId:I}:{}}),z}finally{m.modelRoundtripInFlight=!1,N?Vn(m,"model"):G(`[reconcile] session=${m.sessionId} target=model action=skipped reason=roundtrip_failed`)}});return m.modelChangeQueue=M.then(()=>{},()=>{}),M}let Y=m=>{k.forgetSession(m),h.get(m)?.pendingPermissionIds.clear()},Ee=m=>(m.transportClosedReject||(m.transportClosedReject=m.channel.exited.then(()=>{throw new ss(`mid-request (session ${m.sessionId})`)})),m.transportClosedReject),et=m=>{if(!di.isAbsolute(m))throw new Error(`workspaceCwd must be an absolute path; got "${m}"`);let E=m===f?f:Ye(m);if(E!==f)throw new on(f,E);return E},Oe=()=>{if(!(!O||O.isDying))return O},Fe=m=>{if(O?.channel===m.channel)return O;for(let E of be)if(E.channel===m.channel)return E},Le=m=>(m.statusClosedReject||(m.statusClosedReject=m.channel.exited.then(()=>{throw new ss("mid-request (workspace status)")})),m.statusClosedReject),ne=async(m,E,_={})=>{let I=Oe();return I?await Ce(Promise.race([I.connection.extMethod(m,{..._,cwd:f}),Le(I)]),o,m):E()},ye=async(m,E,_={})=>{let I=h.get(m);if(!I)throw new ie(m);let C=Fe(I);if(!C||C.isDying)throw new ie(m);return await Promise.race([Ce(I.connection.extMethod(E,{..._,sessionId:m}),o,E),Ee(I)])},tn=async(m,E,_)=>{if(!(!E||E.channel!==m.channel))try{await Promise.race([Ce(m.connection.extMethod(fe.sessionClose,{sessionId:m.sessionId}),o,fe.sessionClose),Ee(m)])}catch(I){G(`matilda serve: ${_} ACP session close notification failed for session ${JSON.stringify(m.sessionId)}: ${String(I instanceof Error?I.message:I)}`)}},nr=(m,E)=>{let _=Array.from(h.values()),I=0,C=0,T=0;for(let N of _){if(E!==void 0&&N.sessionId===E){T+=1;continue}try{N.events.publish(m)===void 0?(C+=1,R(`broadcastWorkspaceEvent: publish on session ${N.sessionId} no-op (bus closed)`)):I+=1}catch(z){C+=1;let J=`broadcastWorkspaceEvent: bus publish failed for session ${JSON.stringify(N.sessionId)} (type=${m.type}): ${z instanceof Error?z.message:String(z)}`;S?R(J):G(`matilda serve: ${J}`)}}_.length-T>0&&I===0&&!S&&G(`matilda serve: broadcastWorkspaceEvent type=${m.type} dropped on ALL ${C} session bus(es); SSE subscribers will miss this event (GET fallback still authoritative)`)},xd=()=>new zi(n,void 0,new ci),Un=(m,E,_)=>{m.currentModelId=E,m.modelPublishGeneration++,m.events.publish({type:"model_switched",data:{sessionId:m.sessionId,modelId:E},..._?{originatorClientId:_}:{}})},Fi=(m,E,_)=>{m.currentApprovalMode=E.next,m.approvalModePublishGeneration++,m.events.publish({type:"approval_mode_changed",data:{sessionId:m.sessionId,previous:E.previous,next:E.next,persisted:E.persisted},..._?{originatorClientId:_}:{}})},Vn=async(m,E)=>{let _=E==="model"?"modelReconciliationInFlight":"approvalModeReconciliationInFlight",I=()=>E==="model"?m.modelPublishGeneration:m.approvalModePublishGeneration;if(m[_])return;m[_]=!0;let C=I(),T=!1;try{let M=await ye(m.sessionId,ke.sessionContext);if(I()!==C){T=!0,G(`[reconcile] session=${m.sessionId} target=${E} action=skipped reason=generation_changed genBefore=${C} genAfter=${I()}`);return}if(E==="model"){let N=M?.state?.models?.currentModelId;typeof N=="string"&&N&&N!==m.currentModelId&&(G(`[reconcile] session=${m.sessionId} target=model action=corrected cached=${m.currentModelId??"<unset>"} actual=${N}`),Un(m,N,void 0))}else{let N=M?.state?.modes?.currentModeId;N&&!Tn.has(N)?G(`[reconcile] session=${m.sessionId} target=approvalMode action=dropped reason=unknown_mode mode=${N}`):N&&N!==m.currentApprovalMode&&(G(`[reconcile] session=${m.sessionId} target=approvalMode action=corrected cached=${m.currentApprovalMode??"<unset>"} actual=${N}`),Fi(m,{previous:m.currentApprovalMode??"default",next:N,persisted:!1},void 0))}}catch(M){G(`[reconcile] session=${m.sessionId} target=${E} action=failed error=${M instanceof Error?M.message:String(M)}`)}finally{m[_]=!1,T&&Vn(m,E)}},_d=(m,E,_,I=xd())=>{let C={sessionId:E,workspaceCwd:_,createdAt:new Date().toISOString(),channel:m.channel,connection:m.connection,events:I,promptQueue:Promise.resolve(),pendingPromptCount:0,midTurnMessageQueue:[],modelChangeQueue:Promise.resolve(),approvalModeQueue:Promise.resolve(),modelPublishGeneration:0,approvalModePublishGeneration:0,pendingPermissionIds:new Set,clientIds:new Map,clientLastSeenAt:new Map,attachCount:0,spawnOwnerWantedKill:!1,promptActive:!1,retryAllowed:!1};return m.sessionIds.add(C.sessionId),h.set(C.sessionId,C),v.metrics?.sessionLifecycle("spawn"),m.client.drainEarlyEvents(C.sessionId,C),C},kd=(m,E)=>{let _=E.models?.currentModelId;typeof _=="string"&&_.length>0?m.currentModelId=_:_!=null&&G(`[seed] session=${m.sessionId} target=model action=dropped value=${JSON.stringify(_)} reason=invalid_type`);let I=E.modes?.currentModeId;typeof I=="string"&&Tn.has(I)?m.currentApprovalMode=I:I!=null&&G(`[seed] session=${m.sessionId} target=approvalMode action=dropped value=${JSON.stringify(I)} reason=${typeof I!="string"?"invalid_type":"unknown_mode"}`)},mv=(m,E)=>{if(!m||typeof m!="object")return!1;let _=m;if(_.code!==-32002)return!1;let I=`session:${E}`;return _.data&&typeof _.data=="object"&&_.data.uri===I?!0:typeof _.message=="string"&&_.message===`Resource not found: ${I}`},Li=(m,E)=>{let _=m.events.snapshotReplay();return _?E==="load"?{compactedReplay:_.compactedTurns,liveJournal:_.liveJournal,lastEventId:_.lastEventId}:{lastEventId:_.lastEventId}:{lastEventId:m.events.lastEventId}};async function Ni(m,E){if(S)throw new Error("AcpSessionBridge is shutting down");let _=et(E.workspaceCwd),I=h.get(E.sessionId);if(I){I.attachCount++;let Q=pe(I,E.clientId);return{sessionId:I.sessionId,workspaceCwd:I.workspaceCwd,attached:!0,clientId:Q,createdAt:I.createdAt,state:I.restoreState??{},...Li(I,m)}}let C=H.get(E.sessionId);if(C){if(m!==C.action)throw new nn(E.sessionId,C.action,m);C.coalesceState.count++;let Q;try{Q=await C.promise}catch(ue){throw C.coalesceState.count--,ue}let oe=h.get(Q.sessionId);if(!oe)throw C.coalesceState.count--,new ie(Q.sessionId,"the agent child likely crashed during session restore \u2014 retry to restore the session");return{...Q,attached:!0,clientId:pe(oe,E.clientId),createdAt:oe.createdAt}}if(h.size+F.size+H.size>=r)throw new sr(r);let T=xd(),M,N,z={count:0},J=(async()=>{Z.set(E.sessionId,T),N=await xe(),N.pendingRestoreIds.add(E.sessionId),N.client.markRestoreInFlight(E.sessionId);let Q=N.channel.exited.then(()=>{throw new ss(`during session/${m}`)});Q.catch(()=>{});let oe;try{m==="load"?oe=await Promise.race([Ce(N.connection.loadSession({sessionId:E.sessionId,cwd:_,mcpServers:[]}),o,"loadSession"),Q]):oe=await Promise.race([Ce(N.connection.unstable_resumeSession({sessionId:E.sessionId,cwd:_,mcpServers:[]}),o,"resumeSession"),Q])}catch(yt){throw T.close(),mv(yt,E.sessionId)?new ie(E.sessionId):(N.sessionIds.size===0&&N.pendingRestoreIds.size===1&&N.pendingRestoreIds.has(E.sessionId)&&(N.isDying=!0,await N.channel.kill().catch(()=>{})),yt)}if(S)throw T.close(),new Error("AcpSessionBridge is shutting down");if(N.isDying||!be.has(N))throw T.close(),new Error(`Session ${E.sessionId} restored on a closed agent channel`);let ue=h.get(E.sessionId);if(ue){T.close(),ue.attachCount+=1+z.count;let yt=pe(ue,E.clientId);return{sessionId:ue.sessionId,workspaceCwd:ue.workspaceCwd,attached:!0,clientId:yt,createdAt:ue.createdAt,state:ue.restoreState??{},...Li(ue,m)}}let _e=_d(N,E.sessionId,_,T);_e.restoreState=oe,kd(_e,oe);let Sr=pe(_e,E.clientId);return _e.attachCount=z.count,M=_e,{sessionId:_e.sessionId,workspaceCwd:_e.workspaceCwd,attached:!1,clientId:Sr,createdAt:_e.createdAt,state:oe,...Li(_e,m)}})().finally(()=>{N?.pendingRestoreIds.delete(E.sessionId),N?.client.clearRestoreInFlight(E.sessionId),Z.delete(E.sessionId),M||(T.close(),N?.client.markSessionClosed(E.sessionId))});H.set(E.sessionId,{action:m,promise:J,coalesceState:z});try{return await J}finally{H.delete(E.sessionId)}}async function zn(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C;E?.clientId!==void 0&&(C=re(I,E.clientId));let T=_?.reason??"client_close";G(`matilda serve: closing session ${JSON.stringify(m)} (reason: ${T})`+(C?` by client ${JSON.stringify(C)}`:"")),v.event("session.close",{"matilda-code.daemon.bridge.operation":"session.close","session.id":m,"session.close.reason":T}),x===I&&(x=void 0);let M=Fe(I);M||G(`matilda serve: closeSession channelInfoForEntry returned undefined for session ${JSON.stringify(m)} \u2014 channel cleanup skipped (entry's channel already torn down)`),M&&M.channel===I.channel&&M.sessionIds.delete(m),k.forgetSession(m),I.pendingPermissionIds.clear(),h.delete(m),v.metrics?.sessionLifecycle("close"),M?.client.markSessionClosed(m);try{I.events.publish({type:"session_closed",data:{sessionId:m,reason:T,...C?{closedBy:C}:{}},...C?{originatorClientId:C}:{}})}catch{}I.events.close(),await tn(I,M,"closeSession");try{await v.withSpan("session.close.cancel_active_prompt",{"matilda-code.daemon.bridge.operation":"session.close.cancel_active_prompt","session.id":m},async()=>await I.connection.cancel({sessionId:m}))}catch{}M&&M.sessionIds.size===0&&M.pendingRestoreIds.size===0&&await Ze(M,`closeSession "${m}"`)}return Me(),{getDaemonStatusSnapshot(){return{limits:{maxSessions:r===1/0?null:r,maxPendingPromptsPerSession:p===1/0?null:p,eventRingSize:n,channelIdleTimeoutMs:Te(),sessionIdleTimeoutMs:U},sessionCount:h.size,pendingPermissionCount:k.pendingCount,channelLive:!!Oe(),permissionPolicy:k.policy,sessions:[...h.values()].map(m=>({sessionId:m.sessionId,workspaceCwd:m.workspaceCwd,createdAt:m.createdAt,...m.displayName?{displayName:m.displayName}:{},clientCount:m.clientIds.size,subscriberCount:m.events.subscriberCount,attachCount:m.attachCount,pendingPromptCount:m.pendingPromptCount,pendingPermissionCount:m.pendingPermissionIds.size,hasActivePrompt:m.promptActive,lastEventId:m.events.lastEventId,...m.sessionLastSeenAt!==void 0?{lastSeenAt:m.sessionLastSeenAt}:{},...m.currentModelId?{currentModelId:m.currentModelId}:{},...m.currentApprovalMode?{currentApprovalMode:m.currentApprovalMode}:{}}))}},get sessionCount(){return h.size},isChannelLive(){return!!Oe()},get pendingPermissionCount(){return k.pendingCount},get permissionPolicy(){return k.policy},async loadSession(m){return Ni("load",m)},async resumeSession(m){return Ni("resume",m)},async spawnOrAttach(m){if(S)throw new Error("AcpSessionBridge is shutting down");let E=et(m.workspaceCwd);if(m.sessionScope!==void 0&&m.sessionScope!=="single"&&m.sessionScope!=="thread")throw new sn(m.sessionScope);let _=m.sessionScope??e;if(_==="single"){let T=x;if(T){T.attachCount++;let N=pe(T,m.clientId);return m.modelServiceId&&await K(T,m.modelServiceId,o,N).catch(()=>{}),{sessionId:T.sessionId,workspaceCwd:T.workspaceCwd,attached:!0,clientId:N,createdAt:T.createdAt}}let M=F.get(E);if(M){let N=await M,z=h.get(N.sessionId);if(z&&z.attachCount++,!z)throw new ie(N.sessionId,"the agent child likely crashed during initialization \u2014 retry to spawn a new session");let J=pe(z,m.clientId);return m.modelServiceId&&await K(z,m.modelServiceId,o,J).catch(()=>{}),{...N,attached:!0,clientId:J}}}if(h.size+F.size+H.size>=r)throw new sr(r);let I=he(m.modelServiceId,_,m.clientId),C=_==="single"?E:`${E}#${sg()}`;F.set(C,I);try{return await I}finally{F.delete(C)}},sendPrompt(m,E,_,I){t.onDiagnosticLine?.(`matilda serve: bridge sendPrompt for session=${m}`,"info");let C=v.captureContext(),T=Date.now(),M=h.get(m);if(!M)return Promise.reject(new ie(m));let N;try{N=re(M,I?.clientId)}catch(ue){return Promise.reject(ue)}if(_?.aborted)throw new DOMException("Prompt aborted","AbortError");if(M.pendingPromptCount>=p)throw new Cr(p,M.pendingPromptCount,m);M.pendingPromptCount+=1;let z=!1,J=()=>{z||(z=!0,M.pendingPromptCount=Math.max(0,M.pendingPromptCount-1))},Q=M.promptQueue.then(()=>v.runWithContext(C,async()=>{let ue=Date.now()-T;v.metrics?.promptQueueWait(ue);let _e=Date.now();try{return await v.withSpan("prompt.dispatch",{"matilda-code.daemon.bridge.operation":"prompt.dispatch","session.id":m,"matilda-code.daemon.prompt.queue_wait_ms":ue,...I?.clientId?{"matilda-code.client_id":I.clientId}:{}},async()=>{let Sr=v.injectPromptContext({...E,sessionId:m});if(_?.aborted)throw new DOMException("Prompt aborted","AbortError");let Gn=E.retry===!0&&M.retryAllowed;M.retryAllowed=!1;let ft=(()=>{let We={...Sr};delete We.retry;let Jn=We._meta&&typeof We._meta=="object"?{...We._meta}:{};return delete Jn[cg],Gn&&(Jn[cg]=!0),Object.keys(Jn).length>0?We._meta=Jn:delete We._meta,We})();M.promptActive=!0,M.sessionLastSeenAt=Date.now(),N===void 0?delete M.activePromptOriginatorClientId:M.activePromptOriginatorClientId=N;try{M.cancelBroadcast=!1,Gn||mE(M,ft,N)}catch(We){throw M.promptActive=!1,delete M.activePromptOriginatorClientId,We}let Kn=M.connection.prompt(ft).finally(()=>{M.promptActive=!1,M.sessionLastSeenAt=Date.now(),delete M.activePromptOriginatorClientId,M.clientIds.size===0&&M.events.subscriberCount===0&&h.has(m)&&zn(m,void 0,{reason:"last_client_detached"}).catch(We=>{G(`matilda serve: deferred close-on-prompt-complete failed for ${JSON.stringify(m)}: ${We instanceof Error?We.stack??We.message:String(We)}`)})}),Er=Promise.race([Kn,Ee(M)]);if(Er.then(()=>{},We=>{G(`sendPrompt: forward failed for session ${m}: ${fg(We)}`),kc(M,m,N,"forward_failed"),Y(m),M.connection.cancel({sessionId:m}).catch(()=>{})}).catch(()=>{}),!_)return Er;let Ir=()=>{kc(M,m,N),Y(m),M.connection.cancel({sessionId:m}).catch(()=>{})};return _.aborted?Ir():(_.addEventListener("abort",Ir,{once:!0}),_.aborted&&Ir(),Er.finally(()=>_.removeEventListener("abort",Ir)).catch(()=>{})),Er})}finally{v.metrics?.promptDuration(Date.now()-_e)}})),oe=I?.promptId;return Q.then(ue=>{vE(M,m,ue,oe,N)},ue=>{ue instanceof DOMException&&ue.name==="AbortError"||wE(M,m,ue,oe,N)}),M.promptQueue=Q.then(()=>{},()=>{}),Q.finally(()=>{J(),M.pendingPromptCount===0&&M.midTurnMessageQueue.length>0&&(G(`[mid-turn] session=${M.sessionId} dropped ${M.midTurnMessageQueue.length} undrained message(s) at idle; browser resends next turn`),M.midTurnMessageQueue.length=0)}).catch(()=>{}),Q},async cancelSession(m,E,_){t.onDiagnosticLine?.(`matilda serve: bridge cancelSession for session=${m}`,"info");let I=h.get(m);if(!I)throw new ie(m);let C=re(I,_?.clientId);kc(I,m,C),Y(m);let T=E?{...E,sessionId:m}:{sessionId:m};v.metrics?.cancelled(),await v.withSpan("session.cancel",{"matilda-code.daemon.bridge.operation":"session.cancel","session.id":m},async()=>{try{await I.connection.cancel(T)}catch(M){if(Pu(M))return;throw M}})},subscribeEvents(m,E){let _=h.get(m);if(!_)throw new ie(m);let I=_.events.subscribe(E);if(!E?.snapshot)return I;let C=()=>({v:1,type:"session_snapshot",data:{sessionId:_.sessionId,currentModelId:_.currentModelId??null,currentApprovalMode:_.currentApprovalMode??null}});async function*T(){let M=!1;E?.lastEventId===void 0&&(yield C(),M=!0);for await(let N of I)yield N,!M&&N.type==="replay_complete"&&(yield C(),M=!0)}return T()},getSessionLastEventId(m){let E=h.get(m);if(!E)throw new ie(m);return E.events.lastEventId},respondToPermission(m,E,_){let I=k.peekSessionFor(m);return I===void 0||!h.has(I)?(G(`matilda serve: legacy permission vote ${JSON.stringify(m)} has no live session (peek returned ${JSON.stringify(I)}); returning 404.`),!1):this.respondToSessionPermission(I,m,E,_)},respondToSessionPermission(m,E,_,I){let C=h.get(m);if(!C)throw new ie(m);let T=k.peekSessionFor(E);if(T!==void 0&&T!==m)return R(`rejected permission vote ${JSON.stringify(E)} for session ${JSON.stringify(m)}; request belongs to session ${JSON.stringify(T)}.`),!1;if(T===void 0)return G(`matilda serve: rejected permission vote ${JSON.stringify(E)} for session ${JSON.stringify(m)}; mediator has no pending or resolved record (unknown / timed out / LRU-evicted).`),!1;let M=re(C,I?.clientId);if(_.outcome.outcome==="selected"&&_.outcome.optionId===lt)throw new ir(E,lt);let N=_.outcome.outcome==="selected"?_.outcome.optionId:lt,z=hE(_),J=k.vote({requestId:E,sessionId:m,clientId:M,optionId:N,receivedAtMs:Date.now(),fromLoopback:I?.fromLoopback??!1,...z?{metadata:z}:{}});switch(J.kind){case"resolved":case"recorded":return!0;case"already_resolved":return!1;case"unknown_request":return R(`rejected permission vote ${JSON.stringify(E)} for session ${JSON.stringify(m)}; mediator has no pending or resolved record.`),!1;case"forbidden":throw new an(E,m,J.reason);default:{let Q=J;throw new Error(`unreachable PermissionVoteOutcome: ${JSON.stringify(Q)}`)}}},async branchSession(m,E,_){if(S)throw new Error("AcpSessionBridge is shutting down");let I=h.get(m);if(!I)throw new ie(m);let C;_?.clientId!==void 0&&(C=re(I,_.clientId));let T=I.promptQueue.then(async()=>{if(I.promptActive)throw new un(m);if(h.size+F.size+H.size>=r)throw new sr(r);let M=await xe(),N=await Ce(M.connection.extMethod(fe.sessionBranch,{sessionId:m,cwd:f,name:E.name}),o,"branchSession");if(!N||typeof N.newSessionId!="string"||typeof N.title!="string")throw new Error(`branchSession: agent returned invalid response: ${JSON.stringify(N)}`);let z;try{z=await Ni("resume",{sessionId:N.newSessionId,workspaceCwd:f,clientId:_?.clientId})}catch(ue){G(`matilda serve: branchSession resume failed for ${N.newSessionId}, attempting cleanup...`);try{await M.connection.extMethod(fe.sessionClose,{sessionId:N.newSessionId,cwd:f})}catch(_e){G(`matilda serve: branchSession cleanup of ${N.newSessionId} failed: ${_e instanceof Error?_e.message:_e}`)}throw ue}let J=h.get(N.newSessionId);J&&(J.displayName=N.title);let oe={type:"session_branched",data:{sourceSessionId:m,newSessionId:N.newSessionId,displayName:N.title},...C?{originatorClientId:C}:{}};return I.events.publish(oe),nr(oe,m),{...z,title:N.title,forkedFrom:{sessionId:m,title:I.displayName??m.slice(0,8)}}});return I.promptQueue=T.then(()=>{},()=>{}),T},async closeSession(m,E,_){return zn(m,E,_)},updateSessionMetadata(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=_?.clientId!==void 0?re(I,_.clientId):void 0;if(E.displayName!==void 0){if(typeof E.displayName!="string"||E.displayName.length>ig)throw new Pr("displayName",`must be a string of at most ${ig} characters`);if(bE(E.displayName))throw new Pr("displayName","must not contain control characters");let T=E.displayName||void 0;if(I.displayName!==T){I.displayName=T,G(`matilda serve: updated session metadata ${JSON.stringify(m)} displayName=${I.displayName===void 0?"cleared":"set"}`+(_?.clientId?` by client ${JSON.stringify(_.clientId)}`:""));try{I.events.publish({type:"session_metadata_updated",data:{sessionId:m,displayName:I.displayName},...C?{originatorClientId:C}:{}})}catch{}}}return{displayName:I.displayName}},listWorkspaceSessions(m){if(!di.isAbsolute(m))return[];let E=m===f?f:Ye(m);if(E!==f)return[];let _=[];for(let I of h.values())I.workspaceCwd===E&&_.push({sessionId:I.sessionId,workspaceCwd:I.workspaceCwd,createdAt:I.createdAt,displayName:I.displayName,clientCount:I.clientIds.size,hasActivePrompt:I.promptActive});return _},recordHeartbeat(m,E){let _=h.get(m);if(!_)throw new ie(m);let I=re(_,E?.clientId),C=Date.now();return _.sessionLastSeenAt=C,I!==void 0&&_.clientLastSeenAt.set(I,C),{sessionId:_.sessionId,...I!==void 0?{clientId:I}:{},lastSeenAt:C}},getHeartbeatState(m){let E=h.get(m);if(E)return{...E.sessionLastSeenAt!==void 0?{sessionLastSeenAt:E.sessionLastSeenAt}:{},clientLastSeenAt:new Map(E.clientLastSeenAt)}},publishWorkspaceEvent(m){let E=Array.from(h.values()),_=0,I=0;for(let C of E)try{C.events.publish(m)===void 0?(I+=1,R(`publishWorkspaceEvent: publish on session ${C.sessionId} no-op (bus closed)`)):_+=1}catch(T){I+=1;let M=`publishWorkspaceEvent: bus publish failed for session ${JSON.stringify(C.sessionId)} (type=${m.type}): ${T instanceof Error?T.message:String(T)}`;S?R(M):G(`matilda serve: ${M}`)}E.length>0&&_===0&&!S&&G(`matilda serve: publishWorkspaceEvent type=${m.type} dropped on ALL ${I} session bus(es); SSE subscribers will miss this event (GET fallback still authoritative)`)},knownClientIds(){let m=new Set;for(let E of h.values())for(let _ of E.clientIds.keys())m.add(_);return m},async queryWorkspaceStatus(m,E){return ne(m,E)},async invokeWorkspaceCommand(m,E,_){let I=Oe();if(!I)throw new ie(`workspace-command:${m}`);let C=_?.timeoutMs??o;return await Ce(Promise.race([I.connection.extMethod(m,E??{}),Le(I)]),C,m)},async getWorkspaceMcpToolsStatus(m){return ne(ke.workspaceMcpTools,()=>({v:ot,workspaceCwd:f,serverName:m,initialized:!1,acpChannelLive:!1,tools:[],errors:[{kind:"mcp_tools",status:"not_started",hint:"spawn a session to populate"}]}),{serverName:m})},async getWorkspaceToolsStatus(){return ne(ke.workspaceTools,()=>({v:ot,workspaceCwd:f,initialized:!0,acpChannelLive:!1,tools:[],errors:[{kind:"tools",status:"not_started",hint:"spawn a session to populate"}]}))},async getSessionContextStatus(m){return ye(m,ke.sessionContext)},async getSessionContextUsageStatus(m,E){return ye(m,ke.sessionContextUsage,{detail:E?.detail===!0})},async getSessionSupportedCommandsStatus(m){return ye(m,ke.sessionSupportedCommands)},async getSessionTasksStatus(m){return ye(m,ke.sessionTasks)},async cancelSessionTask(m,E,_){return ye(m,fe.sessionTaskCancel,{taskId:E,taskKind:_})},async clearSessionGoal(m){return ye(m,fe.sessionGoalClear)},async getSessionStatsStatus(m){return ye(m,ke.sessionStats)},async getWorkspaceHooksStatus(){return ne(ke.workspaceHooks,()=>pn(f))},async getSessionHooksStatus(m){return ye(m,ke.sessionHooks)},async getWorkspaceExtensionsStatus(){return ne(ke.workspaceExtensions,()=>ln(f))},async setSessionModel(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=re(I,_?.clientId),T={...E,sessionId:m},M=I.connection,N=Ee(I),z=I.modelChangeQueue.then(async()=>{I.modelRoundtripInFlight=!0;let Q=!1;try{let oe=await Promise.race([Ce(M.unstable_setSessionModel(T),o,"setSessionModel"),N]);return Un(I,E.modelId,C),Q=!0,oe}finally{I.modelRoundtripInFlight=!1,Q?Vn(I,"model"):G(`[reconcile] session=${I.sessionId} target=model action=skipped reason=roundtrip_failed`)}});I.modelChangeQueue=z.then(()=>{},()=>{});let J;try{J=await z}catch(Q){throw I.events.publish({type:"model_switch_failed",data:{sessionId:I.sessionId,requestedModelId:E.modelId,error:Q instanceof Error?Q.message:String(Q)},...C?{originatorClientId:C}:{}}),Q}return J},async setSessionLanguage(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=Fe(I);if(!C||C.isDying)throw new ie(m);let T=re(I,_?.clientId),M=await Promise.race([Ce(I.connection.extMethod(fe.sessionLanguage,{sessionId:m,language:E.language,syncOutputLanguage:E.syncOutputLanguage}),o,fe.sessionLanguage),Ee(I)]);try{I.events.publish({type:"language_changed",data:{sessionId:I.sessionId,language:M.language,outputLanguage:M.outputLanguage??null,refreshed:M.refreshed??!1},...T?{originatorClientId:T}:{}})}catch(N){_c(`language_changed event publish failed: ${N instanceof Error?N.message:String(N)}`)}return{language:M.language,outputLanguage:M.outputLanguage??null,refreshed:M.refreshed??!1}},async setSessionApprovalMode(m,E,_,I){let C=h.get(m);if(!C)throw new ie(m);let T=Fe(C);if(!T||T.isDying)throw new ie(m);let M=re(C,I?.clientId);if(_.persist&&!g)throw new Error("setSessionApprovalMode called with `persist: true` but no `persistApprovalMode` callback wired in BridgeOptions. runMatildaServe wires the production callback; direct embeds and tests must opt in or omit `persist`.");let N=C.approvalModeQueue.then(async()=>{C.approvalModeRoundtripInFlight=!0;let z=!1;try{let J=await Promise.race([Ce(C.connection.extMethod(fe.sessionApprovalMode,{sessionId:m,mode:E}),o,fe.sessionApprovalMode),Ee(C)]);if(typeof J.current!="string"||!Tn.has(J.current))throw new Error(`Agent returned unknown approval mode: ${JSON.stringify(J.current)}`);let Q=!1;if(_.persist)try{await Ce(g?.(f,E)??Promise.resolve(),EE,"persistApprovalMode"),Q=g!==void 0}catch(oe){G(`setSessionApprovalMode: persist failed: ${oe instanceof Error?oe.message:String(oe)}`)}if(Fi(C,{previous:J.previous,next:J.current,persisted:Q},M),Q){nr({type:"approval_mode_changed",data:{sessionId:C.sessionId,previous:J.previous,next:J.current,persisted:Q},...M?{originatorClientId:M}:{}},C.sessionId);for(let oe of h.values())oe.sessionId!==C.sessionId&&(oe.currentApprovalMode=J.current)}return z=!0,{sessionId:C.sessionId,mode:J.current,previous:J.previous,persisted:Q}}finally{C.approvalModeRoundtripInFlight=!1,z?Vn(C,"approvalMode"):G(`[reconcile] session=${C.sessionId} target=approvalMode action=skipped reason=roundtrip_failed`)}});C.approvalModeQueue=N.then(()=>{},()=>{});try{return await N}catch(z){let J=z?.data;if(J&&typeof J=="object"&&"errorKind"in J&&J.errorKind==="trust_gate"){let Q=z?.message,oe=typeof Q=="string"?Q:"Trust-gate rejection from ACP child";throw new Zn(oe)}throw z}},async generateSessionRecap(m,E){let _=h.get(m);if(!_)throw new ie(m);let I=Fe(_);if(!I||I.isDying)throw new ie(m);t.onDiagnosticLine?.(`matilda serve: bridge generateSessionRecap dispatching ext-method for session=${m}`,"info");let C=await Promise.race([Ce(_.connection.extMethod(fe.sessionRecap,{sessionId:m}),xE,fe.sessionRecap),Ee(_)]);return t.onDiagnosticLine?.(`matilda serve: bridge generateSessionRecap completed for session=${m} recap=${C.recap?`len=${C.recap.length}`:"null"}`,"info"),{sessionId:_.sessionId,recap:C.recap??null}},enqueueMidTurnMessage(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=re(I,_?.clientId),T=E.trim();return T.length===0||I.pendingPromptCount===0?(G(`[mid-turn] session=${I.sessionId} rejected: ${T.length===0?"empty message":"session idle"}; browser keeps it for next turn`),{accepted:!1}):I.midTurnMessageQueue.length>=ug?(G(`[mid-turn] session=${I.sessionId} rejected: queue full (depth ${I.midTurnMessageQueue.length} >= ${ug}); browser keeps it for next turn`),{accepted:!1}):(I.midTurnMessageQueue.push({text:T,originatorClientId:C}),{accepted:!0})},async generateSessionBtw(m,E,_,I){let C=h.get(m);if(!C)throw new ie(m);let T=Fe(C);if(!T||T.isDying)throw new ie(m);if(_?.aborted)return{sessionId:m,answer:null};let M=[Ce(C.connection.extMethod(fe.sessionBtw,{sessionId:m,question:E}),_E,fe.sessionBtw),Ee(C)],N;_&&M.push(new Promise((J,Q)=>{let oe=()=>Q(new DOMException("Aborted","AbortError"));_.addEventListener("abort",oe,{once:!0}),N=()=>_.removeEventListener("abort",oe)}));let z;try{z=await Promise.race(M)}finally{N?.()}return{sessionId:C.sessionId,answer:z.answer??null}},async executeShellCommand(m,E,_,I){if(t.onDiagnosticLine?.(`matilda serve: bridge executeShellCommand for session=${m}`,"info"),t.sessionShellCommandEnabled!==!0)throw new bt;if(I?.clientId===void 0)throw new St;let C=h.get(m);if(!C)throw new ie(m);let T=re(C,I.clientId);if(_?.aborted)return{exitCode:null,output:"",aborted:!0};let M=C.workspaceCwd;C.events.publish({type:"user_shell_command",data:{sessionId:m,command:E,cwd:M},...T?{originatorClientId:T}:{}});let N=[],z=new AbortController,J=()=>z.abort();_?.addEventListener("abort",J,{once:!0});try{let Q=await iu.execute(E,M,ft=>{if(ft.type==="data"){let Kn=typeof ft.chunk=="string"?ft.chunk:ft.chunk.map(Er=>Er.map(Ir=>Ir.text).join("")).join(`
67
+ `,s);if(a===-1)return t.slice(n);s=a+1}return t.slice(n,s>n?s-1:s)}var Z4="mid_turn_message_injected",Cn=class{constructor(e,r,n,s,i,o,a,c){this.resolveEntry=e;this.resolvePendingRestoreEvents=r;this.mediator=n;this.permissionTimeoutMs=s;this.maxPendingPerSession=i;this.fileSystem=o;this.onModelPromoted=a;this.onModePromoted=c}async requestPermission(e){let r=this.resolveEntry(e.sessionId);if(!r)return{outcome:{outcome:"cancelled"}};if(r.pendingPermissionIds.size>=this.maxPendingPerSession)return G(`matilda serve: session ${r.sessionId} exceeded maxPendingPermissionsPerSession (${this.maxPendingPerSession}) \u2014 resolving new permission as cancelled.`),{outcome:{outcome:"cancelled"}};let n=new Set(e.options.map(o=>String(o.optionId??"")));n.delete("");let s=Qm();if(n.has(lt))throw new or(s,lt);if(!r.events.publish({type:"permission_request",data:{requestId:s,sessionId:r.sessionId,toolCall:e.toolCall,options:e.options},...r.activePromptOriginatorClientId?{originatorClientId:r.activePromptOriginatorClientId}:{}}))return{outcome:{outcome:"cancelled"}};r.pendingPermissionIds.add(s);try{let o={requestId:s,sessionId:r.sessionId,originatorClientId:r.activePromptOriginatorClientId,allowedOptionIds:n,issuedAtMs:Date.now()},a=await this.mediator.request(o,this.permissionTimeoutMs);return J4(a)}finally{r.pendingPermissionIds.delete(s)}}async sessionUpdate(e){let r=this.resolveEntry(e.sessionId),n=r?.events??this.resolvePendingRestoreEvents(e.sessionId);if(!n)return;let s=r?.activePromptOriginatorClientId?{originatorClientId:r.activePromptOriginatorClientId}:{},i=sE(e);if(i){for(let d of i.surfaces)n.publish({type:"session_update",data:{sessionId:e.sessionId,update:{sessionUpdate:"a2ui",a2ui:{surfaceId:d.surfaceId,callId:i.callId,commands:d.commands},_meta:{serverTimestamp:Date.now(),source:"a2ui-bridge"}}},...s});e=i.sanitizedParams}let o=e.update._meta,a=o?.serverTimestamp??o?.timestamp,c=typeof a=="number"&&Number.isFinite(a)?a:void 0;n.publish({type:"session_update",data:e,...s,...c!==void 0?{_meta:{serverTimestamp:c}}:{}})}earlyEvents=new Map;tombstonedSessionIds=new Map;inFlightRestoreIds=new Set;async extMethod(e,r){if(e!==Du)throw Vi.methodNotFound(e);let n=typeof r.sessionId=="string"?r.sessionId:void 0;if(!n)return{messages:[]};let s=this.resolveEntry(n);if(!s)return{messages:[]};let i=s.midTurnMessageQueue.splice(0),o=i.map(a=>a.text);if(i.length>0){let a=new Map;for(let c of i){let d=a.get(c.originatorClientId);d?d.push(c.text):a.set(c.originatorClientId,[c.text])}for(let[c,d]of a){let u=s.events.publish({type:Z4,data:{sessionId:s.sessionId,messages:d},...c?{originatorClientId:c}:{}});G(u?`[mid-turn] session=${s.sessionId} drained=${d.length}${c?` originator=${c}`:""} injected into running turn`:`[mid-turn] session=${s.sessionId} drained=${d.length} echo frame dropped (bus closed); browser may resend next turn`)}}return{messages:o}}async extNotification(e,r){if(e==="matilda/notify/session/model-update"){this.handleInSessionModelUpdate(r);return}if(e==="matilda/notify/session/mode-update"){this.handleInSessionModeUpdate(r);return}if(e==="matilda/notify/session/title-update"){let u=r.sessionId,l=r.title;if(typeof u!="string"||typeof l!="string"||!l)return;let p=this.resolveEntry(u);if(!p)return;try{p.events.publish({type:"session_metadata_updated",data:{sessionId:u,displayName:l,...typeof r.titleSource=="string"?{titleSource:r.titleSource}:{}}})}catch{}return}if(e==="matilda/notify/session/prompt-suggestion"){let u=r.sessionId,l=r.suggestion,p=r.promptId;if(typeof u!="string"||typeof l!="string"||l.length===0||l.length>X4||typeof p!="string"){G(`[demux] session=${typeof u=="string"?u:"<missing>"} type=prompt_suggestion action=dropped reason=malformed`);return}let f=this.resolveEntry(u);if(!f)return;f.events.publish({type:"followup_suggestion",data:{sessionId:u,suggestion:l,promptId:p}});return}if(e==="matilda/notify/session/terminal-sequence"){let u=r.sessionId;if(typeof u!="string")return;let{v:l,sessionId:p,...f}=r;this.publishExtNotification(u,"terminal_sequence",f);return}if(e!=="matilda/notify/session/mcp-budget-event")return;let n=r.sessionId;if(typeof n!="string")return;let s=r.kind,i;if(s==="budget_warning")i="mcp_budget_warning";else if(s==="refused_batch")i="mcp_child_refused_batch";else return;let{v:o,sessionId:a,kind:c,...d}=r;this.publishExtNotification(n,i,d)}publishExtNotification(e,r,n){let s=this.resolveEntry(e),i={type:r,data:n,...s?.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}};if(s){s.events.publish(i);return}this.bufferEarlyEvent(e,i)}handleInSessionModelUpdate(e){let r=e.sessionId,n=e.currentModelId;if(typeof r!="string"||typeof n!="string")return;let s=this.resolveEntry(r);if(!s){G(`[demux] session=${r} type=current_model_update action=dropped reason=no_entry`);return}if(s.modelRoundtripInFlight){G(`[demux] session=${r} type=current_model_update action=suppressed reason=bridge_roundtrip_in_flight`);return}this.onModelPromoted?this.onModelPromoted(s,n,s.activePromptOriginatorClientId):s.events.publish({type:"model_switched",data:{sessionId:r,modelId:n},...s.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}}),G(`[demux] session=${r} type=current_model_update action=promoted model=${n}`)}handleInSessionModeUpdate(e){let r=e.sessionId,n=e.currentModeId;if(typeof r!="string"||typeof n!="string")return;if(!Tn.has(n)){G(`[demux] session=${r} type=current_mode_update action=dropped reason=unknown_mode mode=${n}`);return}let s=this.resolveEntry(r);if(!s){G(`[demux] session=${r} type=current_mode_update action=dropped reason=no_entry`);return}if(s.approvalModeRoundtripInFlight){G(`[demux] session=${r} type=current_mode_update action=suppressed reason=bridge_roundtrip_in_flight`);return}if(this.onModePromoted?this.onModePromoted(s,n,s.activePromptOriginatorClientId):s.events.publish({type:"approval_mode_changed",data:{sessionId:r,previous:"default",next:n,persisted:!1},...s.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}}),e.legacyFrameSent===!0){G(`[demux] session=${r} type=current_mode_update action=promoted mode=${n} legacy_frame=skipped`);return}s.events.publish({type:"session_update",data:{sessionId:r,update:{sessionUpdate:"current_mode_update",currentModeId:n}},...s.activePromptOriginatorClientId?{originatorClientId:s.activePromptOriginatorClientId}:{}}),G(`[demux] session=${r} type=current_mode_update action=promoted mode=${n}`)}bufferEarlyEvent(e,r){let n=Date.now();if(this.sweepExpiredTombstones(n),this.tombstonedSessionIds.has(e)&&!this.inFlightRestoreIds.has(e)){G(`matilda serve: dropping mcp guardrail extNotification for tombstoned session ${JSON.stringify(e)} (post-close stale event)`);return}this.sweepExpiredEarlyEvents(n);let s=this.earlyEvents.get(e);if(!s){if(this.earlyEvents.size>=eg){G(`matilda serve: dropping mcp guardrail extNotification \u2014 early-event buffer at MAX_EARLY_EVENT_SESSIONS (${eg}); possible session-id fanout abuse`);return}s={frames:[],expiresAt:n+rg},this.earlyEvents.set(e,s)}if(s.frames.length>=tg){G(`matilda serve: dropping mcp guardrail extNotification for session ${JSON.stringify(e)} \u2014 per-session cap (${tg}) reached`);return}s.frames.push(r)}sweepExpiredEarlyEvents(e){for(let[r,n]of this.earlyEvents)n.expiresAt<=e&&this.earlyEvents.delete(r)}sweepExpiredTombstones(e){for(let[r,n]of this.tombstonedSessionIds)n<=e&&this.tombstonedSessionIds.delete(r)}markSessionClosed(e){let r=Date.now();this.sweepExpiredTombstones(r),this.tombstonedSessionIds.set(e,r+rg),this.earlyEvents.delete(e)}markRestoreInFlight(e){this.inFlightRestoreIds.add(e)}clearRestoreInFlight(e){this.inFlightRestoreIds.delete(e)}drainEarlyEvents(e,r){this.tombstonedSessionIds.delete(e);let n=this.earlyEvents.get(e);if(n){for(let s of n.frames)r.events.publish(s);this.earlyEvents.delete(e)}}async writeTextFile(e){if(this.fileSystem)try{return await this.fileSystem.writeText(e)}catch(i){Zm(i)}let r=e.path;try{r=await kt.realpath(e.path)}catch(i){if((i&&typeof i=="object"&&"code"in i?i.code:void 0)!=="ENOENT")throw i;try{let a=await kt.readlink(e.path);r=ai.resolve(ai.dirname(e.path),a)}catch{}}let n=`${r}.${process.pid}.${Date.now()}.${Qm()}.tmp`,s;try{let i=await kt.stat(r);s={mode:i.mode&4095,uid:i.uid,gid:i.gid}}catch(i){if((i&&typeof i=="object"&&"code"in i?i.code:void 0)!=="ENOENT")throw i}try{await kt.writeFile(n,e.content,{encoding:"utf8",flag:"wx",mode:s?.mode??384}),s&&(await kt.chmod(n,s.mode).catch(()=>{}),await kt.chown(n,s.uid,s.gid).catch(()=>{})),await kt.rename(n,r)}catch(i){throw await kt.unlink(n).catch(()=>{}),i}return{}}async readTextFile(e){if(this.fileSystem)try{return await this.fileSystem.readText(e)}catch(i){Zm(i)}if(typeof e.limit=="number"&&e.limit<=0)return{content:""};let r=100*1024*1024,n=await kt.stat(e.path);if(!n.isFile())throw new Error(`readTextFile: ${e.path} is not a regular file (reported as ${Y4(n)}). Pipe / device / proc-like inputs can produce unbounded data and aren't supported by the bridge fs proxy.`);if(n.size>r)throw new Error(`readTextFile: ${e.path} is ${n.size} bytes, exceeds the ${r}-byte daemon cap. Tail/grep externally and feed the relevant slice instead.`);let s=await kt.readFile(e.path,"utf8");if(typeof e.line=="number"||typeof e.limit=="number"){let i=e.line??1,o=i>0?i-1:0,a=e.limit!=null?o+e.limit:void 0;return{content:Q4(s,o,a)}}return{content:s}}},eE=/(^|__)(present_ui|present_choices|a2ui_action)$/;function tE(t){return t?typeof t.serverId=="string"&&t.serverId.toLowerCase().includes("a2ui")?!0:typeof t.toolName=="string"&&eE.test(t.toolName):!1}function rE(t){let e=t.replace(/^\s+/,"");if(e[0]!=="[")return null;let r=0,n=!1,s=!1,i=-1;for(let o=0;o<e.length;o++){let a=e[o];if(n){s?s=!1:a==="\\"?s=!0:a==='"'&&(n=!1);continue}if(a==='"')n=!0;else if(a==="[")r++;else if(a==="]"&&(r--,r===0)){i=o+1;break}}if(i<0)return null;try{let o=JSON.parse(e.slice(0,i));return!Array.isArray(o)||o.length===0?null:[o,e.slice(i).trim()]}catch{return null}}function nE(t){let e=t;return e?.createSurface?.surfaceId??e?.updateComponents?.surfaceId??e?.updateDataModel?.surfaceId??e?.deleteSurface?.surfaceId}function sE(t){let e=t.update;if(!e||e.sessionUpdate!=="tool_call_update")return null;let r=e._meta;if(!tE(r))return null;let n=e.content;if(!Array.isArray(n))return null;let s=null,i=-1;for(let g=0;g<n.length;g++){let v=n[g]?.content;if(typeof v?.text=="string"&&(s=rE(v.text),s)){i=g;break}}if(!s)return null;let[o,a]=s,c=[],d=new Map;for(let g of o){let v=nE(g);if(!v){let x=g&&typeof g=="object"?Object.keys(g).join(",")||"empty object":typeof g;G(`a2ui: dropping command with unrecognized shape (${x})`);continue}d.has(v)||(d.set(v,[]),c.push(v)),d.get(v).push(g)}let u=c.map(g=>({surfaceId:g,commands:d.get(g)})),l=a||"[A2UI surface rendered]",p=n.map((g,v)=>v===i?{...g,content:{...g.content??{},text:l}}:g),f={...e,content:p};return typeof e.rawOutput=="string"&&(f.rawOutput=l),{surfaces:u,callId:typeof e.toolCallId=="string"?e.toolCallId:void 0,sanitizedParams:{...t,update:f}}}w();import{randomUUID as sg}from"node:crypto";import*as di from"node:path";w();var iE=new Set(["turn_complete","turn_error"]),oE=new Set(["slow_client_warning","client_evicted","replay_complete","stream_error"]),aE=new Set(["available_commands_update","current_mode_update"]),ci=class{compactedTurns=[];liveJournal=[];lastEventId=0;closed=!1;slots=[];toolSlotIndex=new Map;textSlotIndex=new Map;ingest(e){if(!this.closed&&(e.id!==void 0&&(this.lastEventId=e.id),!oE.has(e.type))){if(this.liveJournal.push(e),iE.has(e.type)){this.compactCurrentTurn(e);return}if(e.type==="session_update"){this.classifySessionUpdate(e);return}this.slots.push({kind:"misc",event:e})}}snapshot(){return{compactedTurns:this.compactedTurns.slice(),liveJournal:this.liveJournal.slice(),lastEventId:this.lastEventId}}seed(e){this.closed||(this.compactedTurns=e.compactedTurns.slice(),this.lastEventId=e.lastEventId,this.liveJournal=[],this.slots=[],this.toolSlotIndex.clear(),this.textSlotIndex.clear())}close(){this.closed||(this.closed=!0,this.compactedTurns=[],this.liveJournal=[],this.slots=[],this.toolSlotIndex.clear(),this.textSlotIndex.clear())}classifySessionUpdate(e){let r=e.data,n=r?.update?.sessionUpdate;if(!n){this.slots.push({kind:"misc",event:e});return}switch(n){case"agent_message_chunk":{this.mergeTextSlot("text",e,r);break}case"agent_thought_chunk":{this.mergeTextSlot("thought",e,r);break}case"tool_call":case"tool_call_update":{let s=r?.update?.toolCallId;if(!s){this.slots.push({kind:"misc",event:e});break}let i=this.toolSlotIndex.get(s);if(i!==void 0){let o=this.slots[i];o.event=uE(o.event,e)}else{let o=dE(e);this.toolSlotIndex.set(s,this.slots.length),this.slots.push({kind:"tool",toolCallId:s,event:o});let a=ng(r?.update?._meta);a&&(this.textSlotIndex.delete(`text::${a}`),this.textSlotIndex.delete(`thought::${a}`))}break}default:{if(aE.has(n)){let s=this.slots.findIndex(i=>i.kind==="latestWins"&&i.key===n);s!==-1?this.slots[s].event=e:this.slots.push({kind:"latestWins",key:n,event:e})}else this.slots.push({kind:"misc",event:e});break}}}mergeTextSlot(e,r,n){let s=n?.update?.content?.text??"",i=n?.update?._meta,o=ng(i);if(o!=null){let a=`${e}::${o}`,c=this.textSlotIndex.get(a);if(c!==void 0){let d=this.slots[c];d.chunks.push(s),r.id!==void 0&&(d.lastEventId=r.id),d.lastMeta=i??d.lastMeta,d.lastEnvelopeMeta=r._meta??d.lastEnvelopeMeta}else this.textSlotIndex.set(a,this.slots.length),this.slots.push({kind:e,parentToolCallId:o,chunks:[s],lastEventId:r.id??0,lastMeta:i,lastEnvelopeMeta:r._meta})}else{let a=this.slots[this.slots.length-1];a&&a.kind===e&&a.parentToolCallId==null?(a.chunks.push(s),r.id!==void 0&&(a.lastEventId=r.id),a.lastMeta=i??a.lastMeta,a.lastEnvelopeMeta=r._meta??a.lastEnvelopeMeta):this.slots.push({kind:e,parentToolCallId:void 0,chunks:[s],lastEventId:r.id??0,lastMeta:i,lastEnvelopeMeta:r._meta})}}compactCurrentTurn(e){let r=[];for(let n of this.slots)switch(n.kind){case"text":case"thought":r.push(cE(n.kind==="text"?"agent_message_chunk":"agent_thought_chunk",n.chunks.join(""),n.lastEventId,n.lastMeta,n.lastEnvelopeMeta));break;case"tool":case"misc":case"latestWins":r.push(n.event);break;default:break}r.push(e),this.compactedTurns.push(...r),this.liveJournal=[],this.slots=[],this.toolSlotIndex.clear(),this.textSlotIndex.clear()}};function cE(t,e,r,n,s){return{id:r||void 0,v:1,type:"session_update",...s!==void 0?{_meta:s}:{},data:{update:{sessionUpdate:t,content:{type:"text",text:e},...n!=null?{_meta:n}:{}}}}}function dE(t){let e=t.data;return e?.update?.sessionUpdate==="tool_call_update"?{...t,data:{...e,update:{...e.update,sessionUpdate:"tool_call"}}}:t}function ng(t){if(typeof t=="object"&&t!==null){let e=t.parentToolCallId;return typeof e=="string"&&e.length>0?e:void 0}}function uE(t,e){let r=t.data,n=e.data,s=r?.update??{},i=n?.update??{},o={...s};for(let[c,d]of Object.entries(i))d!=null&&(o[c]=d);o.sessionUpdate="tool_call";let a=t._meta||e._meta?{...t._meta??{},...e._meta??{}}:void 0;return{id:e.id??t.id,v:1,type:"session_update",...a?{_meta:a}:{},data:{...r,...n,update:o}}}w();var pE={captureContext:()=>{},runWithContext(t,e){return e()},withSpan(t,e,r){return r()},event(){},injectPromptContext(t){let e=t._meta;if(!e||typeof e!="object"||Array.isArray(e))return t;let r=e;if(!($i in r)&&!(Bi in r))return t;let n={...r};return delete n[$i],delete n[Bi],{...t,_meta:n}}};function pg(){let t=process.env.MATILDA_SERVE_DEBUG;return t?!["0","false","off","no"].includes(t.trim().toLowerCase()):!1}function _c(t){pg()&&G(`matilda serve debug: ${t}`)}var ig=256,fE=256;function hE(t){if(t===null||typeof t!="object")return;let e=t.answers;if(e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.entries(e).every(([,n])=>typeof n=="string"))return{answers:e}}function mE(t,e,r){let n=e.prompt;if(!Array.isArray(n)||n.length===0)return;let s=Date.now(),i=Math.min(n.length,fE);for(let o=0;o<i;o+=1){let a=n[o];if(!(!a||typeof a!="object"||Array.isArray(a)))try{t.events.publish({type:"session_update",data:{sessionId:e.sessionId,update:{sessionUpdate:"user_message_chunk",content:a,_meta:{serverTimestamp:s,source:"bridge-echo"}}},...r?{originatorClientId:r}:{}})}catch{}}}function gE(t,e,r,n){try{t.events.publish({type:"prompt_cancelled",data:{sessionId:e,...n?{reason:n}:{}},...r?{originatorClientId:r}:{}})}catch{}}function kc(t,e,r,n){if(t.cancelBroadcast){G(`broadcastPromptCancelledOnce: suppressed duplicate cancel for session ${e} (latch already set)`);return}t.cancelBroadcast=!0,gE(t,e,r,n)}function vE(t,e,r,n,s){t.events.publish({type:"turn_complete",data:{sessionId:e,stopReason:r.stopReason??"end_turn",...n?{promptId:n}:{}},...s?{originatorClientId:s}:{}})}function fg(t){if(t instanceof Error){let e=t.data;return og(e)??t.message}if(typeof t=="object"&&t!==null){let e=t,r=og(e.data);if(r)return r;let n=e.message;if(typeof n=="string")return n}return String(t)}function og(t){if(typeof t=="string"&&t.length>0)return t;if(typeof t=="object"&&t!==null){let e=t.details;if(typeof e=="string"&&e.length>0)return e;let r=t.message;if(typeof r=="string"&&r.length>0)return r}}function yE(t){if(typeof t!="object"||t===null||!("code"in t))return;let e=t.code;if(typeof e=="string")return e;if(typeof e=="number")return String(e)}function wE(t,e,r,n,s){let i=fg(r),o=yE(r);t.retryAllowed=!0,t.events.publish({type:"turn_error",data:{sessionId:e,message:i,...o?{code:o}:{},...n?{promptId:n}:{}},...s?{originatorClientId:s}:{}})}function bE(t){for(let e=0;e<t.length;e+=1){let r=t.charCodeAt(e);if(r<=31||r===127)return!0}return!1}var SE=1e4,EE=5e3,ag=3e5,IE=6e5,cg="matilda.daemon.retry",xE=6e4,_E=6e4,kE=12e4,dg=1e4,ug=20,AE=20,RE=5,lg=1e6,CE=5*60*1e3,TE=64,PE=6e4,ME=30*6e4;function gr(t){let e=t.sessionScope??"single",r;if(t.maxSessions===void 0)r=AE;else{if(Number.isNaN(t.maxSessions))throw new TypeError("Invalid maxSessions: NaN. Must be a number >= 0 (0 / Infinity = unlimited).");if(t.maxSessions<0)throw new TypeError(`Invalid maxSessions: ${t.maxSessions}. Must be >= 0 (0 / Infinity = unlimited).`);t.maxSessions===0||t.maxSessions===1/0?r=1/0:r=t.maxSessions}if(e!=="single"&&e!=="thread")throw new TypeError(`Invalid sessionScope: ${JSON.stringify(e)}. Expected 'single' or 'thread'.`);let n=t.eventRingSize??8e3;if(!Number.isInteger(n)||n<1||n>lg)throw new TypeError(`Invalid eventRingSize: ${t.eventRingSize}. Must be a positive integer in [1, ${lg}].`);let s=t.channelFactory??oi,i=t.childEnvOverrides?Object.freeze({...t.childEnvOverrides}):Object.freeze({}),o=t.initializeTimeoutMs??SE;if(o<=0)throw new TypeError(`Invalid initializeTimeoutMs: ${o}. Must be > 0.`);let a=t.permissionResponseTimeoutMs??CE,c=a>0&&Number.isFinite(a)?a:0,d=t.maxPendingPermissionsPerSession??TE,u=d>0&&Number.isFinite(d)?d:1/0,l=t.maxPendingPromptsPerSession??RE,p;if(l===0||l===Number.POSITIVE_INFINITY)p=1/0;else{if(!Number.isInteger(l)||l<0)throw new TypeError(`Invalid maxPendingPromptsPerSession: ${l}. Must be a non-negative integer (0 / Infinity = unlimited).`);p=l}if(!di.isAbsolute(t.boundWorkspace))throw new TypeError(`Invalid boundWorkspace: "${t.boundWorkspace}". Must be an absolute path.`);let f=t.boundWorkspace,g=t.persistApprovalMode,v=t.telemetry??pE,x,O,P,q=le(t.sessionReapIntervalMs,PE),U=le(t.sessionIdleTimeoutMs,ME),ae;function le(m,E){return m===void 0?E:m>0&&Number.isFinite(m)?Math.min(m,2147483647):0}function V(){P!==void 0&&(clearTimeout(P),P=void 0)}async function Se(m,E){m.isDying=!0,await m.channel.kill().catch(_=>{G(`matilda serve: channel kill failed${E?` (${E})`:""}: ${String(_)}`)})}function Te(){let m=t.channelIdleTimeoutMs;return m!==void 0&&Number.isFinite(m)&&m>0?Math.min(m,2147483647):0}async function Ze(m,E){let _=Te();if(_<=0){await Se(m,E);return}V(),P=setTimeout(()=>{P=void 0,m.sessionIds.size===0&&m.pendingRestoreIds.size===0&&(G(`matilda serve: idle timeout (${_}ms) expired, killing channel`),Se(m,"idle timeout"))},_),P.unref()}function Me(){if(q<=0||U<=0){G("matilda serve: session reaper disabled");return}G(`matilda serve: session reaper started (interval ${q}ms, idle threshold ${U}ms)`),ae=setInterval(()=>{if(S)return;let m=Date.now();for(let[E,_]of h){if(_.promptActive||_.events.subscriberCount>0)continue;let I=_.sessionLastSeenAt??Date.parse(_.createdAt),C=m-I;C<U||(G(`matilda serve: reaping idle session ${JSON.stringify(E)} (idle for ${Math.round(C/1e3)}s, threshold ${Math.round(U/1e3)}s)`),zn(E,void 0,{reason:"idle_timeout"}).catch(T=>{G(`matilda serve: session reaper failed to close ${JSON.stringify(E)}: ${T instanceof Error?T.stack??T.message:String(T)}`)}))}},q),ae.unref()}function Ue(){ae!==void 0&&(clearInterval(ae),ae=void 0)}let be=new Set,b,h=new Map,y=t.permissionConsensusQuorum;if(y!==void 0&&(!Number.isInteger(y)||y<1))throw new Error(`BridgeOptions.permissionConsensusQuorum must be a positive integer; got ${String(y)}`);let A=t.permissionAudit??Jm(),k=new si(t.permissionPolicy??"first-responder",{emit:(m,E)=>{h.get(m)?.events.publish(E)},audit:A,...y!==void 0?{consensusQuorum:y}:{},now:()=>Date.now(),votersForSession:m=>{let E=h.get(m);return E?new Set(E.clientIds.keys()):new Set}}),S=!1,R=m=>{_c(m),t.onDiagnosticLine&&pg()&&t.onDiagnosticLine(`matilda serve debug: ${m}`,"info")},F=new Map,H=new Map,Z=new Map,X=()=>`client_${sg()}`,pe=(m,E)=>{if(E&&m.clientIds.has(E))return m.clientIds.set(E,(m.clientIds.get(E)??0)+1),E;let _=X();return m.clientIds.set(_,1),_},de=(m,E)=>{if(E===void 0)return;let _=m.clientIds.get(E);_!==void 0&&(_<=1?(m.clientIds.delete(E),m.clientLastSeenAt.delete(E)):m.clientIds.set(E,_-1))},re=(m,E)=>{if(E!==void 0){if(!m.clientIds.has(E))throw new Tr(m.sessionId,E);return E}};async function xe(){if(V(),O&&!O.isDying)return O;if(b)return await b;let m=(async()=>{let E=await v.withSpan("channel.spawn",{"matilda-code.daemon.bridge.operation":"channel.spawn","matilda-code.daemon.channel.reused":!1},async()=>await s(f,i)),_=new Cn(T=>{if(T)return h.get(T);if(O&&O.sessionIds.size>1)throw new Error("BridgeClient: ACP call without sessionId on a multi-session channel cannot be routed \u2014 workspace="+f)},T=>T?Z.get(T):void 0,k,c,u,t.fileSystem,(T,M,N)=>Un(T,M,N),(T,M,N)=>{let z=T;Fi(z,{previous:z.currentApprovalMode??"default",next:M,persisted:!1},N)}),I=new Au(()=>_,E.stream),C={channel:E,connection:I,client:_,sessionIds:new Set,pendingRestoreIds:new Set,isDying:!1,handshakeComplete:!1};be.add(C),be.size>2&&G(`matilda serve: WARNING aliveChannels.size=${be.size} (expected 1, max 2 during killSession-then-spawnOrAttach overlap) \u2014 possible channel leak; check that prior channels' channel.exited fired and the handler ran cleanup.`),E.exited.then(T=>{O===C&&V(),be.delete(C),O===C&&(O=void 0);let M=Array.from(C.sessionIds);C.sessionIds.clear();let N=S||C.isDying;C.handshakeComplete&&v.metrics?.channelLifecycle("exit",N),S||(v.event("channel.exited",{"matilda-code.daemon.channel.exit_code":T?.exitCode??-1,"matilda-code.daemon.channel.session_count":M.length,...T?.signalCode?{"matilda-code.daemon.channel.signal":T.signalCode}:{}}),G(`matilda serve: channel exited (code=${T?.exitCode??"none"}, signal=${T?.signalCode??"none"}, ${M.length} session(s) torn down)`));for(let z of M){let J=h.get(z);if(J){Y(z);try{J.events.publish({type:"session_died",data:{sessionId:z,reason:"channel_closed",exitCode:T?.exitCode??null,signalCode:T?.signalCode??null}})}catch{}h.delete(z),v.metrics?.sessionLifecycle("die"),C.client.markSessionClosed(z),x===J&&(x=void 0),J.events.close()}}});try{await v.withSpan("channel.initialize",{"matilda-code.daemon.bridge.operation":"channel.initialize"},async()=>await Ce(I.initialize({protocolVersion:ku,clientCapabilities:{fs:{readTextFile:!0,writeTextFile:!0}},clientInfo:{name:"matilda-serve-bridge",version:"0"}}),o,"initialize"))}catch(T){throw C.isDying=!0,await E.kill().catch(()=>{}),T}if(S)throw C.isDying=!0,await E.kill().catch(()=>{}),new Error("AcpSessionBridge is shutting down");return O=C,C.handshakeComplete=!0,v.metrics?.channelLifecycle("spawn"),C})();b=m;try{return await m}finally{b=void 0}}async function he(m,E,_){let I=await xe(),C;try{C=await v.withSpan("session.new",{"matilda-code.daemon.bridge.operation":"session.new","matilda-code.daemon.session_scope":E},async()=>await Ce(I.connection.newSession({cwd:f,mcpServers:[]}),o,"newSession"))}catch(N){throw I.sessionIds.size===0&&(I.isDying=!0,await I.channel.kill().catch(()=>{})),N}if(S)throw new Error("AcpSessionBridge is shutting down");let T=_d(I,C.sessionId,f);kd(T,C);let M=pe(T,_);if(E==="single"&&!x&&(x=T),m&&await K(T,m,o,M).catch(()=>{}),!h.has(T.sessionId))throw new Error(`Session ${T.sessionId} died during model-switch initialization`);return{sessionId:T.sessionId,workspaceCwd:T.workspaceCwd,attached:!1,clientId:M,createdAt:T.createdAt}}async function K(m,E,_,I){let C=m.connection,T=Ee(m),M=m.modelChangeQueue.then(async()=>{m.modelRoundtripInFlight=!0;let N=!1;try{await Promise.race([Ce(C.unstable_setSessionModel({sessionId:m.sessionId,modelId:E}),_,"setSessionModel"),T]),Un(m,E,I),N=!0}catch(z){throw m.events.publish({type:"model_switch_failed",data:{sessionId:m.sessionId,requestedModelId:E,error:z instanceof Error?z.message:String(z)},...I?{originatorClientId:I}:{}}),z}finally{m.modelRoundtripInFlight=!1,N?Vn(m,"model"):G(`[reconcile] session=${m.sessionId} target=model action=skipped reason=roundtrip_failed`)}});return m.modelChangeQueue=M.then(()=>{},()=>{}),M}let Y=m=>{k.forgetSession(m),h.get(m)?.pendingPermissionIds.clear()},Ee=m=>(m.transportClosedReject||(m.transportClosedReject=m.channel.exited.then(()=>{throw new ss(`mid-request (session ${m.sessionId})`)})),m.transportClosedReject),et=m=>{if(!di.isAbsolute(m))throw new Error(`workspaceCwd must be an absolute path; got "${m}"`);let E=m===f?f:Ye(m);if(E!==f)throw new on(f,E);return E},Oe=()=>{if(!(!O||O.isDying))return O},Fe=m=>{if(O?.channel===m.channel)return O;for(let E of be)if(E.channel===m.channel)return E},Le=m=>(m.statusClosedReject||(m.statusClosedReject=m.channel.exited.then(()=>{throw new ss("mid-request (workspace status)")})),m.statusClosedReject),ne=async(m,E,_={})=>{let I=Oe();return I?await Ce(Promise.race([I.connection.extMethod(m,{..._,cwd:f}),Le(I)]),o,m):E()},ye=async(m,E,_={})=>{let I=h.get(m);if(!I)throw new ie(m);let C=Fe(I);if(!C||C.isDying)throw new ie(m);return await Promise.race([Ce(I.connection.extMethod(E,{..._,sessionId:m}),o,E),Ee(I)])},tn=async(m,E,_)=>{if(!(!E||E.channel!==m.channel))try{await Promise.race([Ce(m.connection.extMethod(fe.sessionClose,{sessionId:m.sessionId}),o,fe.sessionClose),Ee(m)])}catch(I){G(`matilda serve: ${_} ACP session close notification failed for session ${JSON.stringify(m.sessionId)}: ${String(I instanceof Error?I.message:I)}`)}},nr=(m,E)=>{let _=Array.from(h.values()),I=0,C=0,T=0;for(let N of _){if(E!==void 0&&N.sessionId===E){T+=1;continue}try{N.events.publish(m)===void 0?(C+=1,R(`broadcastWorkspaceEvent: publish on session ${N.sessionId} no-op (bus closed)`)):I+=1}catch(z){C+=1;let J=`broadcastWorkspaceEvent: bus publish failed for session ${JSON.stringify(N.sessionId)} (type=${m.type}): ${z instanceof Error?z.message:String(z)}`;S?R(J):G(`matilda serve: ${J}`)}}_.length-T>0&&I===0&&!S&&G(`matilda serve: broadcastWorkspaceEvent type=${m.type} dropped on ALL ${C} session bus(es); SSE subscribers will miss this event (GET fallback still authoritative)`)},xd=()=>new zi(n,void 0,new ci),Un=(m,E,_)=>{m.currentModelId=E,m.modelPublishGeneration++,m.events.publish({type:"model_switched",data:{sessionId:m.sessionId,modelId:E},..._?{originatorClientId:_}:{}})},Fi=(m,E,_)=>{m.currentApprovalMode=E.next,m.approvalModePublishGeneration++,m.events.publish({type:"approval_mode_changed",data:{sessionId:m.sessionId,previous:E.previous,next:E.next,persisted:E.persisted},..._?{originatorClientId:_}:{}})},Vn=async(m,E)=>{let _=E==="model"?"modelReconciliationInFlight":"approvalModeReconciliationInFlight",I=()=>E==="model"?m.modelPublishGeneration:m.approvalModePublishGeneration;if(m[_])return;m[_]=!0;let C=I(),T=!1;try{let M=await ye(m.sessionId,ke.sessionContext);if(I()!==C){T=!0,G(`[reconcile] session=${m.sessionId} target=${E} action=skipped reason=generation_changed genBefore=${C} genAfter=${I()}`);return}if(E==="model"){let N=M?.state?.models?.currentModelId;typeof N=="string"&&N&&N!==m.currentModelId&&(G(`[reconcile] session=${m.sessionId} target=model action=corrected cached=${m.currentModelId??"<unset>"} actual=${N}`),Un(m,N,void 0))}else{let N=M?.state?.modes?.currentModeId;N&&!Tn.has(N)?G(`[reconcile] session=${m.sessionId} target=approvalMode action=dropped reason=unknown_mode mode=${N}`):N&&N!==m.currentApprovalMode&&(G(`[reconcile] session=${m.sessionId} target=approvalMode action=corrected cached=${m.currentApprovalMode??"<unset>"} actual=${N}`),Fi(m,{previous:m.currentApprovalMode??"default",next:N,persisted:!1},void 0))}}catch(M){G(`[reconcile] session=${m.sessionId} target=${E} action=failed error=${M instanceof Error?M.message:String(M)}`)}finally{m[_]=!1,T&&Vn(m,E)}},_d=(m,E,_,I=xd())=>{let C={sessionId:E,workspaceCwd:_,createdAt:new Date().toISOString(),channel:m.channel,connection:m.connection,events:I,promptQueue:Promise.resolve(),pendingPromptCount:0,midTurnMessageQueue:[],modelChangeQueue:Promise.resolve(),approvalModeQueue:Promise.resolve(),modelPublishGeneration:0,approvalModePublishGeneration:0,pendingPermissionIds:new Set,clientIds:new Map,clientLastSeenAt:new Map,attachCount:0,spawnOwnerWantedKill:!1,promptActive:!1,retryAllowed:!1};return m.sessionIds.add(C.sessionId),h.set(C.sessionId,C),v.metrics?.sessionLifecycle("spawn"),m.client.drainEarlyEvents(C.sessionId,C),C},kd=(m,E)=>{let _=E.models?.currentModelId;typeof _=="string"&&_.length>0?m.currentModelId=_:_!=null&&G(`[seed] session=${m.sessionId} target=model action=dropped value=${JSON.stringify(_)} reason=invalid_type`);let I=E.modes?.currentModeId;typeof I=="string"&&Tn.has(I)?m.currentApprovalMode=I:I!=null&&G(`[seed] session=${m.sessionId} target=approvalMode action=dropped value=${JSON.stringify(I)} reason=${typeof I!="string"?"invalid_type":"unknown_mode"}`)},mv=(m,E)=>{if(!m||typeof m!="object")return!1;let _=m;if(_.code!==-32002)return!1;let I=`session:${E}`;return _.data&&typeof _.data=="object"&&_.data.uri===I?!0:typeof _.message=="string"&&_.message===`Resource not found: ${I}`},Li=(m,E)=>{let _=m.events.snapshotReplay();return _?E==="load"?{compactedReplay:_.compactedTurns,liveJournal:_.liveJournal,lastEventId:_.lastEventId}:{lastEventId:_.lastEventId}:{lastEventId:m.events.lastEventId}};async function Ni(m,E){if(S)throw new Error("AcpSessionBridge is shutting down");let _=et(E.workspaceCwd),I=h.get(E.sessionId);if(I){I.attachCount++;let Q=pe(I,E.clientId);return{sessionId:I.sessionId,workspaceCwd:I.workspaceCwd,attached:!0,clientId:Q,createdAt:I.createdAt,state:I.restoreState??{},...Li(I,m)}}let C=H.get(E.sessionId);if(C){if(m!==C.action)throw new nn(E.sessionId,C.action,m);C.coalesceState.count++;let Q;try{Q=await C.promise}catch(ue){throw C.coalesceState.count--,ue}let oe=h.get(Q.sessionId);if(!oe)throw C.coalesceState.count--,new ie(Q.sessionId,"the agent child likely crashed during session restore \u2014 retry to restore the session");return{...Q,attached:!0,clientId:pe(oe,E.clientId),createdAt:oe.createdAt}}if(h.size+F.size+H.size>=r)throw new sr(r);let T=xd(),M,N,z={count:0},J=(async()=>{Z.set(E.sessionId,T),N=await xe(),N.pendingRestoreIds.add(E.sessionId),N.client.markRestoreInFlight(E.sessionId);let Q=N.channel.exited.then(()=>{throw new ss(`during session/${m}`)});Q.catch(()=>{});let oe;try{m==="load"?oe=await Promise.race([Ce(N.connection.loadSession({sessionId:E.sessionId,cwd:_,mcpServers:[]}),o,"loadSession"),Q]):oe=await Promise.race([Ce(N.connection.unstable_resumeSession({sessionId:E.sessionId,cwd:_,mcpServers:[]}),o,"resumeSession"),Q])}catch(yt){throw T.close(),mv(yt,E.sessionId)?new ie(E.sessionId):(N.sessionIds.size===0&&N.pendingRestoreIds.size===1&&N.pendingRestoreIds.has(E.sessionId)&&(N.isDying=!0,await N.channel.kill().catch(()=>{})),yt)}if(S)throw T.close(),new Error("AcpSessionBridge is shutting down");if(N.isDying||!be.has(N))throw T.close(),new Error(`Session ${E.sessionId} restored on a closed agent channel`);let ue=h.get(E.sessionId);if(ue){T.close(),ue.attachCount+=1+z.count;let yt=pe(ue,E.clientId);return{sessionId:ue.sessionId,workspaceCwd:ue.workspaceCwd,attached:!0,clientId:yt,createdAt:ue.createdAt,state:ue.restoreState??{},...Li(ue,m)}}let _e=_d(N,E.sessionId,_,T);_e.restoreState=oe,kd(_e,oe);let Sr=pe(_e,E.clientId);return _e.attachCount=z.count,M=_e,{sessionId:_e.sessionId,workspaceCwd:_e.workspaceCwd,attached:!1,clientId:Sr,createdAt:_e.createdAt,state:oe,...Li(_e,m)}})().finally(()=>{N?.pendingRestoreIds.delete(E.sessionId),N?.client.clearRestoreInFlight(E.sessionId),Z.delete(E.sessionId),M||(T.close(),N?.client.markSessionClosed(E.sessionId))});H.set(E.sessionId,{action:m,promise:J,coalesceState:z});try{return await J}finally{H.delete(E.sessionId)}}async function zn(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C;E?.clientId!==void 0&&(C=re(I,E.clientId));let T=_?.reason??"client_close";G(`matilda serve: closing session ${JSON.stringify(m)} (reason: ${T})`+(C?` by client ${JSON.stringify(C)}`:"")),v.event("session.close",{"matilda-code.daemon.bridge.operation":"session.close","session.id":m,"session.close.reason":T}),x===I&&(x=void 0);let M=Fe(I);M||G(`matilda serve: closeSession channelInfoForEntry returned undefined for session ${JSON.stringify(m)} \u2014 channel cleanup skipped (entry's channel already torn down)`),M&&M.channel===I.channel&&M.sessionIds.delete(m),k.forgetSession(m),I.pendingPermissionIds.clear(),h.delete(m),v.metrics?.sessionLifecycle("close"),M?.client.markSessionClosed(m);try{I.events.publish({type:"session_closed",data:{sessionId:m,reason:T,...C?{closedBy:C}:{}},...C?{originatorClientId:C}:{}})}catch{}I.events.close(),await tn(I,M,"closeSession");try{await v.withSpan("session.close.cancel_active_prompt",{"matilda-code.daemon.bridge.operation":"session.close.cancel_active_prompt","session.id":m},async()=>await I.connection.cancel({sessionId:m}))}catch{}M&&M.sessionIds.size===0&&M.pendingRestoreIds.size===0&&await Ze(M,`closeSession "${m}"`)}return Me(),{getDaemonStatusSnapshot(){return{limits:{maxSessions:r===1/0?null:r,maxPendingPromptsPerSession:p===1/0?null:p,eventRingSize:n,channelIdleTimeoutMs:Te(),sessionIdleTimeoutMs:U},sessionCount:h.size,pendingPermissionCount:k.pendingCount,channelLive:!!Oe(),permissionPolicy:k.policy,sessions:[...h.values()].map(m=>({sessionId:m.sessionId,workspaceCwd:m.workspaceCwd,createdAt:m.createdAt,...m.displayName?{displayName:m.displayName}:{},clientCount:m.clientIds.size,subscriberCount:m.events.subscriberCount,attachCount:m.attachCount,pendingPromptCount:m.pendingPromptCount,pendingPermissionCount:m.pendingPermissionIds.size,hasActivePrompt:m.promptActive,lastEventId:m.events.lastEventId,...m.sessionLastSeenAt!==void 0?{lastSeenAt:m.sessionLastSeenAt}:{},...m.currentModelId?{currentModelId:m.currentModelId}:{},...m.currentApprovalMode?{currentApprovalMode:m.currentApprovalMode}:{}}))}},get sessionCount(){return h.size},isChannelLive(){return!!Oe()},get pendingPermissionCount(){return k.pendingCount},get permissionPolicy(){return k.policy},async loadSession(m){return Ni("load",m)},async resumeSession(m){return Ni("resume",m)},async spawnOrAttach(m){if(S)throw new Error("AcpSessionBridge is shutting down");let E=et(m.workspaceCwd);if(m.sessionScope!==void 0&&m.sessionScope!=="single"&&m.sessionScope!=="thread")throw new sn(m.sessionScope);let _=m.sessionScope??e;if(_==="single"){let T=x;if(T){T.attachCount++;let N=pe(T,m.clientId);return m.modelServiceId&&await K(T,m.modelServiceId,o,N).catch(()=>{}),{sessionId:T.sessionId,workspaceCwd:T.workspaceCwd,attached:!0,clientId:N,createdAt:T.createdAt}}let M=F.get(E);if(M){let N=await M,z=h.get(N.sessionId);if(z&&z.attachCount++,!z)throw new ie(N.sessionId,"the agent child likely crashed during initialization \u2014 retry to spawn a new session");let J=pe(z,m.clientId);return m.modelServiceId&&await K(z,m.modelServiceId,o,J).catch(()=>{}),{...N,attached:!0,clientId:J}}}if(h.size+F.size+H.size>=r)throw new sr(r);let I=he(m.modelServiceId,_,m.clientId),C=_==="single"?E:`${E}#${sg()}`;F.set(C,I);try{return await I}finally{F.delete(C)}},sendPrompt(m,E,_,I){t.onDiagnosticLine?.(`matilda serve: bridge sendPrompt for session=${m}`,"info");let C=v.captureContext(),T=Date.now(),M=h.get(m);if(!M)return Promise.reject(new ie(m));let N;try{N=re(M,I?.clientId)}catch(ue){return Promise.reject(ue)}if(_?.aborted)throw new DOMException("Prompt aborted","AbortError");if(M.pendingPromptCount>=p)throw new Cr(p,M.pendingPromptCount,m);M.pendingPromptCount+=1;let z=!1,J=()=>{z||(z=!0,M.pendingPromptCount=Math.max(0,M.pendingPromptCount-1))},Q=M.promptQueue.then(()=>v.runWithContext(C,async()=>{let ue=Date.now()-T;v.metrics?.promptQueueWait(ue);let _e=Date.now();try{return await v.withSpan("prompt.dispatch",{"matilda-code.daemon.bridge.operation":"prompt.dispatch","session.id":m,"matilda-code.daemon.prompt.queue_wait_ms":ue,...I?.clientId?{"matilda-code.client_id":I.clientId}:{}},async()=>{let Sr=v.injectPromptContext({...E,sessionId:m});if(_?.aborted)throw new DOMException("Prompt aborted","AbortError");let Gn=E.retry===!0&&M.retryAllowed;M.retryAllowed=!1;let ft=(()=>{let We={...Sr};delete We.retry;let Jn=We._meta&&typeof We._meta=="object"?{...We._meta}:{};return delete Jn[cg],Gn&&(Jn[cg]=!0),Object.keys(Jn).length>0?We._meta=Jn:delete We._meta,We})();M.promptActive=!0,M.sessionLastSeenAt=Date.now(),N===void 0?delete M.activePromptOriginatorClientId:M.activePromptOriginatorClientId=N;try{M.cancelBroadcast=!1,Gn||mE(M,ft,N)}catch(We){throw M.promptActive=!1,delete M.activePromptOriginatorClientId,We}let Kn=M.connection.prompt(ft).finally(()=>{M.promptActive=!1,M.sessionLastSeenAt=Date.now(),delete M.activePromptOriginatorClientId,M.clientIds.size===0&&M.events.subscriberCount===0&&h.has(m)&&zn(m,void 0,{reason:"last_client_detached"}).catch(We=>{G(`matilda serve: deferred close-on-prompt-complete failed for ${JSON.stringify(m)}: ${We instanceof Error?We.stack??We.message:String(We)}`)})}),Er=Promise.race([Kn,Ee(M)]);if(Er.then(()=>{},We=>{G(`sendPrompt: forward failed for session ${m}: ${fg(We)}`),kc(M,m,N,"forward_failed"),Y(m),M.connection.cancel({sessionId:m}).catch(()=>{})}).catch(()=>{}),!_)return Er;let Ir=()=>{kc(M,m,N),Y(m),M.connection.cancel({sessionId:m}).catch(()=>{})};return _.aborted?Ir():(_.addEventListener("abort",Ir,{once:!0}),_.aborted&&Ir(),Er.finally(()=>_.removeEventListener("abort",Ir)).catch(()=>{})),Er})}finally{v.metrics?.promptDuration(Date.now()-_e)}})),oe=I?.promptId;return Q.then(ue=>{vE(M,m,ue,oe,N)},ue=>{ue instanceof DOMException&&ue.name==="AbortError"||wE(M,m,ue,oe,N)}),M.promptQueue=Q.then(()=>{},()=>{}),Q.finally(()=>{J(),M.pendingPromptCount===0&&M.midTurnMessageQueue.length>0&&(G(`[mid-turn] session=${M.sessionId} dropped ${M.midTurnMessageQueue.length} undrained message(s) at idle; browser resends next turn`),M.midTurnMessageQueue.length=0)}).catch(()=>{}),Q},async cancelSession(m,E,_){t.onDiagnosticLine?.(`matilda serve: bridge cancelSession for session=${m}`,"info");let I=h.get(m);if(!I)throw new ie(m);let C=re(I,_?.clientId);kc(I,m,C),Y(m);let T=E?{...E,sessionId:m}:{sessionId:m};v.metrics?.cancelled(),await v.withSpan("session.cancel",{"matilda-code.daemon.bridge.operation":"session.cancel","session.id":m},async()=>{try{await I.connection.cancel(T)}catch(M){if(Pu(M))return;throw M}})},subscribeEvents(m,E){let _=h.get(m);if(!_)throw new ie(m);let I=_.events.subscribe(E);if(!E?.snapshot)return I;let C=()=>({v:1,type:"session_snapshot",data:{sessionId:_.sessionId,currentModelId:_.currentModelId??null,currentApprovalMode:_.currentApprovalMode??null}});async function*T(){let M=!1;E?.lastEventId===void 0&&(yield C(),M=!0);for await(let N of I)yield N,!M&&N.type==="replay_complete"&&(yield C(),M=!0)}return T()},getSessionLastEventId(m){let E=h.get(m);if(!E)throw new ie(m);return E.events.lastEventId},respondToPermission(m,E,_){let I=k.peekSessionFor(m);return I===void 0||!h.has(I)?(G(`matilda serve: legacy permission vote ${JSON.stringify(m)} has no live session (peek returned ${JSON.stringify(I)}); returning 404.`),!1):this.respondToSessionPermission(I,m,E,_)},respondToSessionPermission(m,E,_,I){let C=h.get(m);if(!C)throw new ie(m);let T=k.peekSessionFor(E);if(T!==void 0&&T!==m)return R(`rejected permission vote ${JSON.stringify(E)} for session ${JSON.stringify(m)}; request belongs to session ${JSON.stringify(T)}.`),!1;if(T===void 0)return G(`matilda serve: rejected permission vote ${JSON.stringify(E)} for session ${JSON.stringify(m)}; mediator has no pending or resolved record (unknown / timed out / LRU-evicted).`),!1;let M=re(C,I?.clientId);if(_.outcome.outcome==="selected"&&_.outcome.optionId===lt)throw new ir(E,lt);let N=_.outcome.outcome==="selected"?_.outcome.optionId:lt,z=hE(_),J=k.vote({requestId:E,sessionId:m,clientId:M,optionId:N,receivedAtMs:Date.now(),fromLoopback:I?.fromLoopback??!1,...z?{metadata:z}:{}});switch(J.kind){case"resolved":case"recorded":return!0;case"already_resolved":return!1;case"unknown_request":return R(`rejected permission vote ${JSON.stringify(E)} for session ${JSON.stringify(m)}; mediator has no pending or resolved record.`),!1;case"forbidden":throw new an(E,m,J.reason);default:{let Q=J;throw new Error(`unreachable PermissionVoteOutcome: ${JSON.stringify(Q)}`)}}},async branchSession(m,E,_){if(S)throw new Error("AcpSessionBridge is shutting down");let I=h.get(m);if(!I)throw new ie(m);let C;_?.clientId!==void 0&&(C=re(I,_.clientId));let T=I.promptQueue.then(async()=>{if(I.promptActive)throw new un(m);if(h.size+F.size+H.size>=r)throw new sr(r);let M=await xe(),N=await Ce(M.connection.extMethod(fe.sessionBranch,{sessionId:m,cwd:f,name:E.name}),o,"branchSession");if(!N||typeof N.newSessionId!="string"||typeof N.title!="string")throw new Error(`branchSession: agent returned invalid response: ${JSON.stringify(N)}`);let z;try{z=await Ni("resume",{sessionId:N.newSessionId,workspaceCwd:f,clientId:_?.clientId})}catch(ue){G(`matilda serve: branchSession resume failed for ${N.newSessionId}, attempting cleanup...`);try{await M.connection.extMethod(fe.sessionClose,{sessionId:N.newSessionId,cwd:f})}catch(_e){G(`matilda serve: branchSession cleanup of ${N.newSessionId} failed: ${_e instanceof Error?_e.message:_e}`)}throw ue}let J=h.get(N.newSessionId);J&&(J.displayName=N.title);let oe={type:"session_branched",data:{sourceSessionId:m,newSessionId:N.newSessionId,displayName:N.title},...C?{originatorClientId:C}:{}};return I.events.publish(oe),nr(oe,m),{...z,title:N.title,forkedFrom:{sessionId:m,title:I.displayName??m.slice(0,8)}}});return I.promptQueue=T.then(()=>{},()=>{}),T},async closeSession(m,E,_){return zn(m,E,_)},updateSessionMetadata(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=_?.clientId!==void 0?re(I,_.clientId):void 0;if(E.displayName!==void 0){if(typeof E.displayName!="string"||E.displayName.length>ig)throw new Pr("displayName",`must be a string of at most ${ig} characters`);if(bE(E.displayName))throw new Pr("displayName","must not contain control characters");let T=E.displayName||void 0;if(I.displayName!==T){I.displayName=T,G(`matilda serve: updated session metadata ${JSON.stringify(m)} displayName=${I.displayName===void 0?"cleared":"set"}`+(_?.clientId?` by client ${JSON.stringify(_.clientId)}`:""));try{I.events.publish({type:"session_metadata_updated",data:{sessionId:m,displayName:I.displayName},...C?{originatorClientId:C}:{}})}catch{}}}return{displayName:I.displayName}},listWorkspaceSessions(m){if(!di.isAbsolute(m))return[];let E=m===f?f:Ye(m);if(E!==f)return[];let _=[];for(let I of h.values())I.workspaceCwd===E&&_.push({sessionId:I.sessionId,workspaceCwd:I.workspaceCwd,createdAt:I.createdAt,displayName:I.displayName,clientCount:I.clientIds.size,hasActivePrompt:I.promptActive});return _},recordHeartbeat(m,E){let _=h.get(m);if(!_)throw new ie(m);let I=re(_,E?.clientId),C=Date.now();return _.sessionLastSeenAt=C,I!==void 0&&_.clientLastSeenAt.set(I,C),{sessionId:_.sessionId,...I!==void 0?{clientId:I}:{},lastSeenAt:C}},getHeartbeatState(m){let E=h.get(m);if(E)return{...E.sessionLastSeenAt!==void 0?{sessionLastSeenAt:E.sessionLastSeenAt}:{},clientLastSeenAt:new Map(E.clientLastSeenAt)}},publishWorkspaceEvent(m){let E=Array.from(h.values()),_=0,I=0;for(let C of E)try{C.events.publish(m)===void 0?(I+=1,R(`publishWorkspaceEvent: publish on session ${C.sessionId} no-op (bus closed)`)):_+=1}catch(T){I+=1;let M=`publishWorkspaceEvent: bus publish failed for session ${JSON.stringify(C.sessionId)} (type=${m.type}): ${T instanceof Error?T.message:String(T)}`;S?R(M):G(`matilda serve: ${M}`)}E.length>0&&_===0&&!S&&G(`matilda serve: publishWorkspaceEvent type=${m.type} dropped on ALL ${I} session bus(es); SSE subscribers will miss this event (GET fallback still authoritative)`)},knownClientIds(){let m=new Set;for(let E of h.values())for(let _ of E.clientIds.keys())m.add(_);return m},async queryWorkspaceStatus(m,E){return ne(m,E)},async invokeWorkspaceCommand(m,E,_){let I=Oe();if(!I)throw new ie(`workspace-command:${m}`);let C=_?.timeoutMs??o;return await Ce(Promise.race([I.connection.extMethod(m,E??{}),Le(I)]),C,m)},async getWorkspaceMcpToolsStatus(m){return ne(ke.workspaceMcpTools,()=>({v:ot,workspaceCwd:f,serverName:m,initialized:!1,acpChannelLive:!1,tools:[],errors:[{kind:"mcp_tools",status:"not_started",hint:"spawn a session to populate"}]}),{serverName:m})},async getWorkspaceToolsStatus(){return ne(ke.workspaceTools,()=>({v:ot,workspaceCwd:f,initialized:!0,acpChannelLive:!1,tools:[],errors:[{kind:"tools",status:"not_started",hint:"spawn a session to populate"}]}))},async getSessionContextStatus(m){return ye(m,ke.sessionContext)},async getSessionContextUsageStatus(m,E){return ye(m,ke.sessionContextUsage,{detail:E?.detail===!0})},async getSessionSupportedCommandsStatus(m){return ye(m,ke.sessionSupportedCommands)},async getSessionTasksStatus(m){return ye(m,ke.sessionTasks)},async cancelSessionTask(m,E,_){return ye(m,fe.sessionTaskCancel,{taskId:E,taskKind:_})},async clearSessionGoal(m){return ye(m,fe.sessionGoalClear)},async getSessionStatsStatus(m){return ye(m,ke.sessionStats)},async getWorkspaceHooksStatus(){return ne(ke.workspaceHooks,()=>pn(f))},async getSessionHooksStatus(m){return ye(m,ke.sessionHooks)},async getWorkspaceExtensionsStatus(){return ne(ke.workspaceExtensions,()=>ln(f))},async setSessionModel(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=re(I,_?.clientId),T={...E,sessionId:m},M=I.connection,N=Ee(I),z=I.modelChangeQueue.then(async()=>{I.modelRoundtripInFlight=!0;let Q=!1;try{let oe=await Promise.race([Ce(M.unstable_setSessionModel(T),o,"setSessionModel"),N]);return Un(I,E.modelId,C),Q=!0,oe}finally{I.modelRoundtripInFlight=!1,Q?Vn(I,"model"):G(`[reconcile] session=${I.sessionId} target=model action=skipped reason=roundtrip_failed`)}});I.modelChangeQueue=z.then(()=>{},()=>{});let J;try{J=await z}catch(Q){throw I.events.publish({type:"model_switch_failed",data:{sessionId:I.sessionId,requestedModelId:E.modelId,error:Q instanceof Error?Q.message:String(Q)},...C?{originatorClientId:C}:{}}),Q}return J},async setSessionLanguage(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=Fe(I);if(!C||C.isDying)throw new ie(m);let T=re(I,_?.clientId),M=await Promise.race([Ce(I.connection.extMethod(fe.sessionLanguage,{sessionId:m,language:E.language,syncOutputLanguage:E.syncOutputLanguage}),o,fe.sessionLanguage),Ee(I)]);try{I.events.publish({type:"language_changed",data:{sessionId:I.sessionId,language:M.language,outputLanguage:M.outputLanguage??null,refreshed:M.refreshed??!1},...T?{originatorClientId:T}:{}})}catch(N){_c(`language_changed event publish failed: ${N instanceof Error?N.message:String(N)}`)}return{language:M.language,outputLanguage:M.outputLanguage??null,refreshed:M.refreshed??!1}},async setSessionApprovalMode(m,E,_,I){let C=h.get(m);if(!C)throw new ie(m);let T=Fe(C);if(!T||T.isDying)throw new ie(m);let M=re(C,I?.clientId);if(_.persist&&!g)throw new Error("setSessionApprovalMode called with `persist: true` but no `persistApprovalMode` callback wired in BridgeOptions. runMatildaServe wires the production callback; direct embeds and tests must opt in or omit `persist`.");let N=C.approvalModeQueue.then(async()=>{C.approvalModeRoundtripInFlight=!0;let z=!1;try{let J=await Promise.race([Ce(C.connection.extMethod(fe.sessionApprovalMode,{sessionId:m,mode:E}),o,fe.sessionApprovalMode),Ee(C)]);if(typeof J.current!="string"||!Tn.has(J.current))throw new Error(`Agent returned unknown approval mode: ${JSON.stringify(J.current)}`);let Q=!1;if(_.persist)try{await Ce(g?.(f,E)??Promise.resolve(),EE,"persistApprovalMode"),Q=g!==void 0}catch(oe){G(`setSessionApprovalMode: persist failed: ${oe instanceof Error?oe.message:String(oe)}`)}if(Fi(C,{previous:J.previous,next:J.current,persisted:Q},M),Q){nr({type:"approval_mode_changed",data:{sessionId:C.sessionId,previous:J.previous,next:J.current,persisted:Q},...M?{originatorClientId:M}:{}},C.sessionId);for(let oe of h.values())oe.sessionId!==C.sessionId&&(oe.currentApprovalMode=J.current)}return z=!0,{sessionId:C.sessionId,mode:J.current,previous:J.previous,persisted:Q}}finally{C.approvalModeRoundtripInFlight=!1,z?Vn(C,"approvalMode"):G(`[reconcile] session=${C.sessionId} target=approvalMode action=skipped reason=roundtrip_failed`)}});C.approvalModeQueue=N.then(()=>{},()=>{});try{return await N}catch(z){let J=z?.data;if(J&&typeof J=="object"&&"errorKind"in J&&J.errorKind==="trust_gate"){let Q=z?.message,oe=typeof Q=="string"?Q:"Trust-gate rejection from ACP child";throw new Zn(oe)}throw z}},async generateSessionRecap(m,E){let _=h.get(m);if(!_)throw new ie(m);let I=Fe(_);if(!I||I.isDying)throw new ie(m);t.onDiagnosticLine?.(`matilda serve: bridge generateSessionRecap dispatching ext-method for session=${m}`,"info");let C=await Promise.race([Ce(_.connection.extMethod(fe.sessionRecap,{sessionId:m}),xE,fe.sessionRecap),Ee(_)]);return t.onDiagnosticLine?.(`matilda serve: bridge generateSessionRecap completed for session=${m} recap=${C.recap?`len=${C.recap.length}`:"null"}`,"info"),{sessionId:_.sessionId,recap:C.recap??null}},enqueueMidTurnMessage(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=re(I,_?.clientId),T=E.trim();return T.length===0||I.pendingPromptCount===0?(G(`[mid-turn] session=${I.sessionId} rejected: ${T.length===0?"empty message":"session idle"}; browser keeps it for next turn`),{accepted:!1}):I.midTurnMessageQueue.length>=ug?(G(`[mid-turn] session=${I.sessionId} rejected: queue full (depth ${I.midTurnMessageQueue.length} >= ${ug}); browser keeps it for next turn`),{accepted:!1}):(I.midTurnMessageQueue.push({text:T,originatorClientId:C}),{accepted:!0})},async generateSessionBtw(m,E,_,I){let C=h.get(m);if(!C)throw new ie(m);let T=Fe(C);if(!T||T.isDying)throw new ie(m);if(_?.aborted)return{sessionId:m,answer:null};let M=[Ce(C.connection.extMethod(fe.sessionBtw,{sessionId:m,question:E}),_E,fe.sessionBtw),Ee(C)],N;_&&M.push(new Promise((J,Q)=>{let oe=()=>Q(new DOMException("Aborted","AbortError"));_.addEventListener("abort",oe,{once:!0}),N=()=>_.removeEventListener("abort",oe)}));let z;try{z=await Promise.race(M)}finally{N?.()}return{sessionId:C.sessionId,answer:z.answer??null}},async executeShellCommand(m,E,_,I){if(t.onDiagnosticLine?.(`matilda serve: bridge executeShellCommand for session=${m}`,"info"),t.sessionShellCommandEnabled!==!0)throw new bt;if(I?.clientId===void 0)throw new St;let C=h.get(m);if(!C)throw new ie(m);let T=re(C,I.clientId);if(_?.aborted)return{exitCode:null,output:"",aborted:!0};let M=C.workspaceCwd;C.events.publish({type:"user_shell_command",data:{sessionId:m,command:E,cwd:M},...T?{originatorClientId:T}:{}});let N=[],z=new AbortController,J=()=>z.abort();_?.addEventListener("abort",J,{once:!0});try{let Q=await lu.execute(E,M,ft=>{if(ft.type==="data"){let Kn=typeof ft.chunk=="string"?ft.chunk:ft.chunk.map(Er=>Er.map(Ir=>Ir.text).join("")).join(`
68
68
  `);N.push(Kn),C.events.publish({type:"session_update",data:{sessionId:m,update:{sessionUpdate:"shell_output",output:Kn,_meta:{serverTimestamp:Date.now(),source:"user-shell"}}},...T?{originatorClientId:T}:{}})}},z.signal,!1,{terminalWidth:120,terminalHeight:40},{streamStdout:!0}),oe=setTimeout(()=>z.abort(),kE);oe.unref();let ue=await Q.result;clearTimeout(oe);let _e=ue.exitCode,Sr=ue.aborted,yt=N.join("")||ue.output;C.events.publish({type:"user_shell_result",data:{sessionId:m,exitCode:_e,signal:ue.signal,aborted:Sr,_meta:{serverTimestamp:Date.now()}},...T?{originatorClientId:T}:{}});let Gn=yt.length>dg?yt.substring(0,dg)+`
69
- ... (truncated)`:yt;try{await C.connection.extMethod(fe.sessionShellHistory,{sessionId:m,command:E,output:Gn,exitCode:_e})}catch(ft){_c(`shell history injection failed for session ${m}: ${ft instanceof Error?ft.message:String(ft)}`)}return{exitCode:_e,output:yt,aborted:Sr}}catch(Q){throw C.events.publish({type:"user_shell_result",data:{sessionId:m,exitCode:null,signal:null,aborted:!1,error:Q instanceof Error?Q.message:String(Q),_meta:{serverTimestamp:Date.now()}},...T?{originatorClientId:T}:{}}),Q}finally{_?.removeEventListener("abort",J)}},async getRewindSnapshots(m){return ye(m,ke.sessionRewindSnapshots)},async rewindSession(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=Fe(I);if(!C||C.isDying)throw new ie(m);let T=re(I,_?.clientId),M;try{M=await Promise.race([Ce(I.connection.extMethod(fe.sessionRewind,{sessionId:m,promptId:E.promptId,rewindFiles:!0}),o,fe.sessionRewind),Ee(I)])}catch(Q){let oe=Q?.data;if(oe&&typeof oe=="object"&&"errorKind"in oe){let ue=oe.errorKind,_e=Q?.message??"Rewind failed";if(ue==="session_busy")throw new cn(m,_e);if(ue==="invalid_rewind_target")throw new dn(m,_e)}throw Q}let N=M.targetTurnIndex??0,z=M.filesChanged??[],J=M.filesFailed??[];try{I.events.publish({type:"session_rewound",data:{sessionId:m,promptId:E.promptId,targetTurnIndex:N,filesChanged:z,filesFailed:J},...T?{originatorClientId:T}:{}})}catch{}return{rewound:J.length===0,targetTurnIndex:N,filesChanged:z,filesFailed:J}},async manageMcpServer(m,E,_){let I=Oe();if(!I)throw new ie(`mcp:${m}`);let C=E==="authenticate"?IE:ag,T=await Promise.race([Ce(I.connection.extMethod(fe.workspaceMcpManage,{serverName:m,action:E,originatorClientId:_}),C,fe.workspaceMcpManage),Le(I)]);return nr({type:"mcp_server_changed",data:{serverName:T.serverName,action:T.action,originatorClientId:_},..._?{originatorClientId:_}:{}}),T},async generateWorkspaceAgent(m,E){let _=Oe();if(!_)throw new ie("agents:generate");return await Promise.race([Ce(_.connection.extMethod(fe.workspaceAgentGenerate,{description:m}),ag,fe.workspaceAgentGenerate),Le(_)])},async addRuntimeMcpServer(m,E,_){let I=Oe();if(!I)throw Object.assign(new Error(`No live ACP channel for runtime MCP add: ${m}`),{data:{errorKind:"acp_channel_unavailable"}});let C=await Promise.race([Ce(I.connection.extMethod(fe.workspaceMcpRuntimeAdd,{name:m,config:E,originatorClientId:_}),3e5,fe.workspaceMcpRuntimeAdd),Le(I)]);if(!(C.skipped===!0)){let M=C;nr({type:"mcp_server_added",data:{name:M.name,transport:M.transport,replaced:M.replaced,shadowedSettings:M.shadowedSettings,toolCount:M.toolCount,originatorClientId:M.originatorClientId},..._?{originatorClientId:_}:{}})}return C},async removeRuntimeMcpServer(m,E){let _=Oe();if(!_)throw Object.assign(new Error(`No live ACP channel for runtime MCP remove: ${m}`),{data:{errorKind:"acp_channel_unavailable"}});let I=await Promise.race([Ce(_.connection.extMethod(fe.workspaceMcpRuntimeRemove,{name:m,originatorClientId:E}),3e5,fe.workspaceMcpRuntimeRemove),Le(_)]);if(!(I.skipped===!0)){let T=I;nr({type:"mcp_server_removed",data:{name:T.name,wasShadowingSettings:T.wasShadowingSettings,originatorClientId:T.originatorClientId},...E?{originatorClientId:E}:{}})}return I},async killSession(m,E){let _=h.get(m);if(!_)return;if(E?.requireZeroAttaches&&_.attachCount>0){_.spawnOwnerWantedKill=!0;return}k.forgetSession(m),_.pendingPermissionIds.clear(),x===_&&(x=void 0),h.delete(m),v.metrics?.sessionLifecycle("die");let I=Fe(_);I||G(`matilda serve: killSession channelInfoForEntry returned undefined for session ${JSON.stringify(m)} \u2014 channel cleanup skipped (entry's channel already torn down)`),I&&I.channel===_.channel&&I.sessionIds.delete(m),await tn(_,I,"killSession"),I?.client.markSessionClosed(m);try{_.events.publish({type:"session_died",data:{sessionId:m,reason:"killed"}})}catch{}_.events.close(),I&&I.sessionIds.size===0&&I.pendingRestoreIds.size===0&&await Ze(I,`killSession "${m}"`)},async detachClient(m,E){let _=h.get(m);_&&(_.attachCount>0&&_.attachCount--,de(_,E),_.spawnOwnerWantedKill&&_.attachCount===0&&_.events.subscriberCount===0?await this.killSession(m).catch(()=>{}):_.clientIds.size===0&&_.events.subscriberCount===0&&!_.promptActive&&await zn(m,void 0,{reason:"last_client_detached"}).catch(I=>{G(`matilda serve: close-on-last-detach failed for ${JSON.stringify(m)}: ${I instanceof Error?I.stack??I.message:String(I)}`)}))},killAllSync(){S=!0,V(),Ue();let m=Array.from(be);x=void 0,h.clear();for(let E of m)try{E.channel.killSync()}catch{}},async shutdown(){S=!0,V(),Ue();let m=Array.from(h.values()),E=Array.from(be);for(let T of E)T.isDying=!0;for(let T of m)k.forgetSession(T.sessionId),T.pendingPermissionIds.clear();x=void 0,h.clear();for(let T of m){v.metrics?.sessionLifecycle("die");try{T.events.publish({type:"session_died",data:{sessionId:T.sessionId,reason:"daemon_shutdown"}})}catch{}T.events.close()}let _=Array.from(F.values()).map(T=>T.then(()=>{},()=>{})),I=Array.from(H.values()).map(T=>T.promise.then(()=>{},()=>{})),C=b?b.then(()=>{},()=>{}):Promise.resolve();await Promise.all([...E.map(T=>T.channel.kill().catch(()=>{})),..._,...I,C])},async preheat(){if(S)return;let m=await xe();Te()>0&&m.sessionIds.size===0&&m.pendingRestoreIds.size===0&&await Ze(m)}}}async function Ce(t,e,r){let n,s=new Promise((i,o)=>{n=setTimeout(()=>o(new Ki(r,e)),e)});try{return await Promise.race([t,s])}finally{n&&clearTimeout(n)}}var hg=gr;w();w();var OE="openid profile email model.completion",Ac=2048;function Rc(t){if(t.length<=Ac)return t;let e=t.length-Ac;return`${t.slice(0,Ac)}\u2026[+${e} bytes truncated]`}var li=class{providerId="matilda-oauth";client;constructor(e){this.client=e??new nu}async start(e){let{code_verifier:r,code_challenge:n}=Zd(),s;try{s=await this.client.requestDeviceAuthorization({scope:OE,code_challenge:n,code_challenge_method:"S256"},{signal:e.signal})}catch(i){let o=i instanceof Error?i.message:String(i);throw D(`[serve] matilda device-flow start failed (raw): ${Rc(o)}`),new vt("Matilda IdP device authorization request failed")}if(e.signal.aborted)throw new vt("device-flow start aborted");if(!eu(s)){let i=s;throw D(Rc(`[serve] matilda device-flow start error envelope (raw): error=${i?.error??"unknown"} description=${i?.error_description??"(none)"}`)),new vt("Matilda IdP rejected the device authorization request")}return{deviceCode:Ec(s.device_code),pkceVerifier:Ec(r),userCode:s.user_code,verificationUri:s.verification_uri,verificationUriComplete:s.verification_uri_complete,expiresIn:s.expires_in}}async poll(e,r){if(!e.pkceVerifier)return{kind:"error",errorKind:"invalid_grant",hint:"Matilda device-flow requires a PKCE verifier"};if(r.signal.aborted)return{kind:"pending"};let n;try{n=await this.client.pollDeviceToken({device_code:Ic(e.deviceCode),code_verifier:Ic(e.pkceVerifier)},{signal:r.signal})}catch(s){let i=s instanceof ji?DE(s.oauthError):"upstream_error";if(!r.signal.aborted){let a;if(s instanceof ji){let c=s.oauthError??"(missing)";a=`oauthError=${Gr(c)}`}else s instanceof Error?a=`${Gr(s.name)} (message ${s.message.length} bytes; raw suppressed to avoid echoing device_code/PKCE)`:a=`<non-Error throw: ${typeof s}>`;D(`[serve] matilda device-flow poll failed (errorKind=${i}): ${Rc(a)}`)}return{kind:"error",errorKind:i,hint:i==="upstream_error"?"unexpected response from identity provider":`Matilda IdP returned ${i}`}}if(tu(n)){let s=n,i={access_token:s.access_token,refresh_token:s.refresh_token??void 0,token_type:s.token_type,resource_url:s.resource_url,expiry_date:s.expires_in?Date.now()+s.expires_in*1e3:void 0},o=i.expiry_date,a=this.client;return{kind:"success",async persist(c){await su(i,{signal:c.signal});try{a.setCredentials(i)}catch{}return{expiresAt:o}}}}return ru(n)?n.slowDown?{kind:"slow_down"}:{kind:"pending"}:{kind:"error",errorKind:"upstream_error",hint:"unexpected response from identity provider"}}};function DE(t){switch(t){case"expired_token":return"expired_token";case"access_denied":return"access_denied";case"invalid_grant":return"invalid_grant";default:return"upstream_error"}}w();var FE="ACP writeTextFile",LE="ACP readTextFile";function mg(t,e){return{route:e,...t.sessionId?{sessionId:t.sessionId}:{}}}function pi(t){return{async writeText(e){let r=t.forRequest(mg(e,FE)),n=await r.resolve(e.path,"write");return await r.writeTextOverwrite(n,e.content),{}},async readText(e){let r=t.forRequest(mg(e,LE)),n=await r.resolve(e.path,"read"),s={};typeof e.line=="number"&&e.line>0&&(s.line=e.line),typeof e.limit=="number"&&e.limit>0&&(s.limit=e.limit);let{content:i}=await r.readText(n,s);return{content:i}}}}w();import{promises as HE}from"node:fs";w();import NE from"node:os";var gg=["OPENAI_API_KEY","ANTHROPIC_API_KEY","GEMINI_API_KEY","GOOGLE_API_KEY","MATILDA_API_KEY","OPENROUTER_API_KEY","MATILDA_SERVER_TOKEN"],vg=["OPENAI_BASE_URL","ANTHROPIC_BASE_URL","OPENAI_API_BASE","NODE_EXTRA_CA_CERTS","TZ","LANG","LC_ALL","TERM","MATILDA_CLI_ENTRY"],yg=["HTTP_PROXY","HTTPS_PROXY","NO_PROXY","ALL_PROXY"];function $E(t,e){return t[e]??t[e.toLowerCase()]}function BE(t,e){if(t==="NO_PROXY")return Qd(e);try{let n=new URL(e).host;if(n)return n}catch{}try{let n=new URL(`http://${e}`).host;if(n)return n}catch{}return(e.replace(/^[^@/?#]*@/,"").split(/[/?#]/)[0]??"")||"<unparseable>"}function Cc(t,e){let r={...process.env},n=[],s=Yd(),i=s==="bun"?process.versions.bun??process.versions.node:process.versions.node;n.push({kind:"runtime",name:s,status:"ok",value:i}),n.push({kind:"platform",name:process.platform,status:"ok",value:`${process.arch} (${NE.release()})`}),n.push({kind:"memory",name:"rss",status:"ok",value:Fu(process.memoryUsage().rss)});let o=r.SANDBOX;n.push({kind:"sandbox",name:"SANDBOX",status:o?"ok":"disabled",present:!!o,...o?{value:o}:{}});let a=r.SEATBELT_PROFILE;a&&n.push({kind:"sandbox",name:"SEATBELT_PROFILE",status:"ok",present:!0,value:a});for(let c of yg){let d=$E(r,c);d?n.push({kind:"proxy",name:c,status:"ok",present:!0,value:BE(c,d)}):n.push({kind:"proxy",name:c,status:"disabled",present:!1})}for(let c of[...gg,...vg]){let d=!!r[c];n.push({kind:"env_var",name:c,status:d?"ok":"disabled",present:d})}return{v:ot,workspaceCwd:t,initialized:!0,acpChannelLive:e,cells:n}}var qE=gg,jE=vg,WE=yg;var Pn=22;function Mn(){return{async getEnvStatus(t,e){return Cc(t,e)},async getDaemonPreflightCells(t){return UE(t)}}}async function UE(t){let s=[{kind:"node_version",run:()=>{try{let o=process.versions.node,a=Number.parseInt(o.split(".")[0]??"0",10);return Number.isFinite(a)&&a>=Pn?{kind:"node_version",status:"ok",locality:"daemon",detail:{version:o,required:`>=${Pn}`}}:{kind:"node_version",status:"error",errorKind:"missing_binary",error:`Node ${o} is below the required >=${Pn}.`,hint:`Upgrade Node to v${Pn} or newer.`,locality:"daemon",detail:{version:o,required:`>=${Pn}`}}}catch(o){return{kind:"node_version",status:"error",error:o instanceof Error?o.message:String(o),locality:"daemon"}}}},{kind:"cli_entry",run:()=>{let o=process.env.MATILDA_CLI_ENTRY||process.argv[1]||"";return o?{kind:"cli_entry",status:"ok",locality:"daemon",detail:{path:o,source:process.env.MATILDA_CLI_ENTRY?"MATILDA_CLI_ENTRY":"process.argv[1]"}}:{kind:"cli_entry",status:"error",errorKind:"missing_binary",error:"Cannot determine CLI entry path for spawning the ACP child.",hint:"Set MATILDA_CLI_ENTRY to the absolute path of the matilda entry script.",locality:"daemon"}}},{kind:"workspace_dir",run:async()=>{try{return(await HE.stat(t)).isDirectory()?{kind:"workspace_dir",status:"ok",locality:"daemon",detail:{path:t}}:{kind:"workspace_dir",status:"error",errorKind:"missing_file",error:`Bound workspace path is not a directory: ${t}`,locality:"daemon",detail:{path:t}}}catch(o){let a=Mt(o);return{kind:"workspace_dir",status:"error",error:o instanceof Error?o.message:String(o),...a?{errorKind:a}:{},locality:"daemon",detail:{path:t}}}}},{kind:"ripgrep",run:()=>Tc("ripgrep",async()=>await pu(!0)?{status:"ok"}:{status:"warning",hint:"Install ripgrep for faster grep tool execution."})},{kind:"git",run:()=>Tc("git",async()=>{let o=await Nu();return o&&o!=="unknown"?{status:"ok",detail:{version:o}}:{status:"warning",hint:"git not found on PATH."}})},{kind:"npm",run:()=>Tc("npm",async()=>{let o=await Lu();return o&&o!=="unknown"?{status:"ok",detail:{version:o}}:{status:"warning",hint:"npm not found on PATH."}})}];return(await Promise.allSettled(s.map(o=>Promise.resolve().then(o.run)))).map((o,a)=>{if(o.status==="fulfilled")return o.value;let c=o.reason,d=Mt(c);return{kind:s[a].kind,status:"error",locality:"daemon",error:c instanceof Error?c.message:String(c),...d?{errorKind:d}:{}}})}async function Tc(t,e){try{let r=await e();return{kind:t,status:r.status,locality:"daemon",...r.detail?{detail:r.detail}:{},...r.hint?{hint:r.hint}:{}}}catch(r){let n=Mt(r);return{kind:t,status:"error",error:r instanceof Error?r.message:String(r),locality:"daemon",...n?{errorKind:n}:{}}}}w();function qt(){let t=process.env.MATILDA_SERVE_DEBUG;return t?!["0","false","off","no"].includes(t.trim().toLowerCase()):!1}w();import{createHash as Ug,timingSafeEqual as oI}from"node:crypto";w();import eI from"node:path";w();var VE={path_outside_workspace:400,symlink_escape:400,path_not_found:404,binary_file:422,file_too_large:413,hash_mismatch:409,file_already_exists:409,text_not_found:422,ambiguous_text_match:422,untrusted_workspace:403,permission_denied:403,io_error:503,internal_error:500,parse_error:400},B=class extends Error{kind;status;hint;constructor(e,r,n){super(r,n?.cause===void 0?void 0:{cause:n.cause}),this.name="FsError",this.kind=e,this.status=n?.status??VE[e],this.hint=n?.hint}};function Pc(t){return t instanceof B}function wg(t,e="internal_error"){if(t instanceof B)return t;let r=t?.code,n=t instanceof Error?t.message:"unknown filesystem error";switch(r){case"ENOENT":return new B("path_not_found",n,{cause:t});case"EACCES":case"EPERM":return new B("permission_denied",n,{cause:t});case"ELOOP":return new B("symlink_escape",n,{cause:t,hint:"symlink chain forms a cycle or exceeds SYMLOOP_MAX"});case"EISDIR":return new B("parse_error",n,{cause:t,hint:"EISDIR \u2014 path is a directory but a regular file was expected"});case"ENOTDIR":return new B("parse_error",n,{cause:t,hint:"ENOTDIR \u2014 a path component is a regular file but a directory was expected"});case"ENOSPC":return new B("io_error",n,{cause:t,hint:"filesystem is full (df -h reporting 100%)"});case"EIO":return new B("io_error",n,{cause:t,hint:"underlying I/O error (failing disk or kernel-level fault)"});case"EBUSY":case"ETXTBSY":return new B("io_error",n,{cause:t,hint:"file is busy; another process holds an exclusive handle"});case"ENAMETOOLONG":return new B("io_error",n,{cause:t,hint:"path exceeds the OS PATH_MAX"});case"EMFILE":case"ENFILE":return new B("io_error",n,{cause:t,hint:"too many open files; daemon is at file-descriptor limit"});default:return new B(e,n,{cause:t})}}w();import{promises as Kr}from"node:fs";import*as Ke from"node:path";var zE=new Set(["write","stat"]);function Eg(t){if(process.platform==="win32"&&t.indexOf(":",2)!==-1||process.platform==="win32"&&/~\d+/.test(t)||t.startsWith("\\\\?\\")||t.startsWith("\\\\.\\")||t.startsWith("//?/")||t.startsWith("//./")||t.startsWith("\\\\")&&t.length>2&&t[2]!=="\\"||t.startsWith("//")&&t.length>2&&t[2]!=="/"||/(^|\/|\\)\.{3,}(\/|\\|$)/.test(t))return!0;for(let e of t.split(/[\\/]/))if(!(e===""||e==="."||e==="..")&&(/[.\s]+$/.test(e)||/(^|\.)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|$)/i.test(e)))return!0;return!1}var fi=40,bg=new Map;function GE(t){let e=bg.get(t);if(e!==void 0)return e;let r=Ye(t);return bg.set(t,r),r}async function Sg(t){let e=t,r=[];for(let n=0;n<fi;n++){let s=null;try{s=await Kr.stat(e)}catch(o){let a=o?.code;if(!(a==="ENOENT"||a==="ENOTDIR"))throw o}if(s){if(r.length>0&&!s.isDirectory())throw new B("parse_error",`path component is not a directory: ${t}`,{hint:"a non-directory file occupies a path segment"});return{ancestor:e,tail:r.join(Ke.sep)}}let i=Ke.dirname(e);if(i===e)throw new B("path_not_found",`no existing ancestor for ${t}`);r.unshift(Ke.basename(e)),e=i}throw new B("path_not_found",`path traversal exceeded ${fi} hops while finding ancestor`,{hint:"path is too deeply nested or filesystem is responding unexpectedly"})}async function Mc(t,e,r){if(typeof t!="string"||t.length===0)throw new B("parse_error","path must be a non-empty string");if(Eg(t))throw new B("path_outside_workspace",`path contains suspicious pattern: ${t}`,{hint:"paths with NTFS ADS, 8.3 short names, UNC prefixes, or trailing dots are rejected outright"});let n=GE(e),s=Ke.resolve(n,t);if(!xr(s,n))throw new B("path_outside_workspace",`path escapes workspace: ${t}`);let i;try{i=await Kr.realpath(s)}catch(o){let a=o?.code;if(a==="ENOENT"&&zE.has(r)){let c=null;try{let d=s,u=new Set,l=null,p=!1;for(let f=0;f<fi;f++){let g;try{g=await Kr.lstat(d)}catch(P){let q=P?.code;if(q==="ENOENT"||q==="ENOTDIR"){p=!0;break}throw P}if(!g.isSymbolicLink()){p=!0;break}let v=typeof g.ino=="bigint"?g.ino:BigInt(g.ino);if(v!==0n&&u.has(v))throw new B("symlink_escape",`symlink cycle detected at ${d}`,{hint:"symlink loops back onto a previously visited inode"});v!==0n&&u.add(v);let x=await Kr.readlink(d),O=Ke.isAbsolute(x)?x:Ke.resolve(Ke.dirname(d),x);l===null&&(l=x),d=O}if(!p)throw new B("symlink_escape",`symlink chain exceeded ${fi} hops for ${t}`,{hint:"symlink chain is too long or contains a cycle"});if(l!==null){let{ancestor:f,tail:g}=await Sg(d),v=await Kr.realpath(f),x=g?Ke.join(v,g):v;if(!xr(x,n))throw new B("symlink_escape",`dangling symlink target escapes workspace: ${t}`,{hint:"symlink chain leaves the workspace; enable MATILDA_AUDIT_RAW_PATHS for the resolved target"});c=x}}catch(d){if(d instanceof B||d?.code!=="ENOENT")throw d}if(c!==null)i=c;else{let{ancestor:d,tail:u}=await Sg(s),l=await Kr.realpath(d);i=u?Ke.join(l,u):l}}else throw a==="ENOENT"?new B("path_not_found",`path does not exist: ${t}`,{cause:o}):a==="ELOOP"?new B("symlink_escape",`symlink loop or chain too long for ${t}`,{cause:o,hint:"a symlink in the path forms a cycle or exceeds SYMLOOP_MAX"}):a==="EACCES"?new B("permission_denied",`permission denied resolving ${t}`,{cause:o}):o}if(!xr(i,n)){let o=i!==s?"symlink_escape":"path_outside_workspace";throw new B(o,o==="symlink_escape"?`symlink resolves outside workspace: ${t}`:`path escapes workspace: ${t}`)}return i}w();import{promises as xg}from"node:fs";import*as Oc from"node:path";var Ig=1024*1024;function _g(t,e){t.get("/workspace/memory",async(r,n)=>{try{let s=await Dc(e.boundWorkspace);n.status(200).json(s)}catch(s){D(`matilda serve: GET /workspace/memory failed: ${s instanceof Error?s.stack??s.message:String(s)}`),n.status(500).json({error:"Failed to discover workspace memory",code:"memory_discovery_failed"})}}),t.post("/workspace/memory",e.mutate({strict:!0}),async(r,n)=>{let s=e.safeBody(r),i=s.scope;if(i!=="workspace"&&i!=="global"){n.status(400).json({error:'`scope` must be "workspace" or "global"',code:"invalid_scope"});return}let o=s.mode;if(o!==void 0&&o!=="append"&&o!=="replace"){n.status(400).json({error:'`mode` must be "append", "replace", or omitted',code:"invalid_mode"});return}let a=o==="replace"?"replace":"append",c=s.content;if(typeof c!="string"){n.status(400).json({error:"`content` must be a string",code:"invalid_content"});return}if(Buffer.byteLength(c,"utf8")>Ig){n.status(400).json({error:`\`content\` exceeds the ${Ig}-byte limit`,code:"content_too_large"});return}let d=e.parseClientId(r,n);if(d===null)return;let u;if(d!==void 0){if(!e.bridge.knownClientIds().has(d)){n.status(400).json({error:`Client id "${d}" is not registered for this workspace`,code:"invalid_client_id",clientId:d});return}u=d}try{let l=await ts({scope:i,mode:a,content:c,projectRoot:e.boundWorkspace}),p={ok:!0,filePath:l.filePath,bytesWritten:l.bytesWritten,mode:a,changed:l.changed};l.changed&&e.bridge.publishWorkspaceEvent({type:"memory_changed",data:{scope:i,filePath:l.filePath,mode:a,bytesWritten:l.bytesWritten},...u?{originatorClientId:u}:{}}),n.status(200).json(p)}catch(l){if(l instanceof es){D(`matilda serve: POST /workspace/memory timeout \u2014 file lock at ${l.filePath} did not acquire within ${l.timeoutMs}ms (stalled FS / OneDrive / NFS)`);let g=qt();n.status(500).json({error:g?l.message:"Workspace memory write timed out waiting for the per-file lock. Retry or restart the daemon.",code:"memory_write_timeout",scope:i,mode:a,timeoutMs:l.timeoutMs,...g?{filePath:l.filePath}:{}});return}if(l instanceof rs){D(`matilda serve: POST /workspace/memory refused \u2014 existing file ${l.filePath} is ${l.bytes} bytes (cap ${l.limit})`);let g=qt();n.status(413).json({error:g?l.message:"Existing memory file exceeds the safe-append cap. Trim the file or POST with mode=replace.",code:"memory_file_too_large",scope:i,mode:a,...g?{filePath:l.filePath}:{},bytes:l.bytes,limit:l.limit});return}D(`matilda serve: POST /workspace/memory failed (scope=${i} mode=${a}): ${l instanceof Error?l.stack??l.message:String(l)}`);let p=l&&typeof l=="object"&&"code"in l?l.code:void 0,f=qt();n.status(500).json({error:"Failed to write workspace memory",code:"file_error",scope:i,mode:a,...typeof p=="string"?{osCode:p}:{},...f?{errorMessage:l instanceof Error?l.message:String(l)}:{}})}})}async function Dc(t){let e=new Set(Cd()),r=[],n=[],s=await KE(t,e,n);r.push(...s);let i=Xn.getGlobalMatildaDir();for(let c of e){let d=Oc.join(i,c);try{let u=await xg.stat(d);u.isFile()&&r.push({absolutePath:d,scope:"global",bytes:u.size})}catch(u){kg(u)||n.push({kind:"memory_file",status:"error",error:u instanceof Error?u.message:String(u),errorKind:"stat_failed",hint:d})}}if(r.length===0&&n.length===0)return Ou(t);let o=r.reduce((c,d)=>c+d.bytes,0),a={v:ot,workspaceCwd:t,initialized:!0,files:r.map(c=>({kind:"memory_file",path:c.absolutePath,scope:c.scope,bytes:c.bytes})),totalBytes:o,fileCount:r.length,ruleCount:0};return n.length>0&&(a.errors=n),a}async function KE(t,e,r){let n=[];for(let s of e){let i=Oc.join(t,s);try{let o=await xg.stat(i);o.isFile()&&n.push({absolutePath:i,scope:"workspace",bytes:o.size})}catch(o){kg(o)||r.push({kind:"memory_file",status:"error",error:o instanceof Error?o.message:String(o),errorKind:"stat_failed",hint:i})}}return n}function kg(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}w();import{promises as JE}from"node:fs";w();var Og=/^[\p{L}\p{N}_-]+$/u,Lc=64,Ag=2,mi=256*1024,gi=256*1024,Rg=256,Cg=256;function Dg(t,e){let r=Nc(e.boundWorkspace);t.get("/workspace/agents",async(n,s)=>{try{let i=await r.listSubagents({force:!0}),o={v:ot,workspaceCwd:e.boundWorkspace,agents:i.map(yi)};s.status(200).json(o)}catch(i){D(`matilda serve: GET /workspace/agents failed: ${i instanceof Error?i.stack??i.message:String(i)}`),s.status(500).json({error:"Failed to list workspace agents",code:"agent_list_failed"})}}),t.post("/workspace/agents",e.mutate({strict:!0}),async(n,s)=>{let i=e.safeBody(n),o=hi(e,n,s);if(o===null)return;let a=o,c=i.scope;if(c!=="workspace"&&c!=="global"){s.status(400).json({error:'`scope` must be "workspace" or "global"',code:"invalid_scope"});return}let d=c==="workspace"?"project":"user",u=XE(i,d,s);if(!u)return;if(await r.loadSubagent(u.name,d)){s.status(409).json({error:`Subagent "${u.name}" already exists at ${d} level`,code:"agent_already_exists",name:u.name,level:d});return}try{await r.createSubagent(u,{level:d})}catch(f){if(f instanceof Ar){if(f.code===Ve.ALREADY_EXISTS){s.status(409).json({error:f.message,code:"agent_already_exists",name:f.subagentName??u.name});return}if(f.code===Ve.VALIDATION_ERROR||f.code===Ve.INVALID_CONFIG||f.code===Ve.INVALID_NAME||f.code===Ve.TOOL_NOT_FOUND){s.status(422).json({error:f.message,code:"invalid_config",name:f.subagentName??u.name});return}if(f.code===Ve.FILE_ERROR){let g=qt();s.status(500).json({error:g?f.message:"Failed to write workspace agent file",code:"file_error",name:f.subagentName??u.name});return}}D(`matilda serve: POST /workspace/agents failed: ${f instanceof Error?f.stack??f.message:String(f)}`),s.status(500).json({error:"Failed to create workspace agent",code:"agent_create_failed"});return}let p=await r.loadSubagent(u.name,d);if(!p){D(`matilda serve: agent_create_reload_failed (name=${vr(u.name)} level=${d}) \u2014 file likely persisted on disk; check \`GET /workspace/agents\` for a phantom entry`),s.status(500).json({error:"Agent creation succeeded but reload failed",code:"agent_create_reload_failed",name:u.name,level:d});return}e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:u.name,level:d},...a?{originatorClientId:a}:{}}),s.status(201).json({ok:!0,agent:Gt(p)})}),t.post("/workspace/agents/generate",e.mutate({strict:!0}),async(n,s)=>{let i=e.safeBody(n),o=hi(e,n,s);if(o===null)return;let a=o,c=i.description;if(typeof c!="string"||c.trim().length===0){s.status(400).json({error:"`description` must be a non-empty string",code:"invalid_description"});return}if(Buffer.byteLength(c,"utf8")>4096){s.status(400).json({error:"`description` exceeds the 4096-byte limit",code:"invalid_description"});return}try{let d=await e.bridge.generateWorkspaceAgent(c.trim(),a);s.status(200).json(d)}catch(d){D(`matilda serve: POST /workspace/agents/generate failed: ${d instanceof Error?d.stack??d.message:String(d)}`),s.status(500).json({error:"Failed to generate workspace agent",code:"agent_generate_failed"})}}),t.get("/workspace/agents/:agentType",async(n,s)=>{let i=Fc(n,s);if(i!==null)try{let o=await r.loadSubagent(i);if(!o){s.status(404).json({error:`Subagent "${i}" not found`,code:"agent_not_found",name:i});return}s.status(200).json(Gt(o))}catch(o){D(`matilda serve: GET /workspace/agents/${vr(i)} failed: ${o instanceof Error?o.stack??o.message:String(o)}`),s.status(500).json({error:"Failed to read workspace agent",code:"agent_read_failed"})}}),t.post("/workspace/agents/:agentType",e.mutate({strict:!0}),async(n,s)=>{let i=Fc(n,s);if(i===null)return;let o=hi(e,n,s);if(o===null)return;let a=o,c=e.safeBody(n),d=YE(c,s);if(!d)return;let u=Tg(n,s);if(u===null)return;let l=await r.loadSubagent(i,u);if(!l){s.status(404).json({error:`Subagent "${i}" not found`,code:"agent_not_found",name:i});return}if(Pg(l,i,s))return;if(Object.keys(d).length===0){s.status(400).json({error:"`POST /workspace/agents/:agentType` requires at least one updatable field in the body",code:"invalid_config",name:i});return}if(QE(l,d)){s.status(200).json({ok:!0,agent:Gt(l),changed:!1});return}try{await r.updateSubagent(i,d,l.level)}catch(g){if(g instanceof Ar){if(g.code===Ve.NOT_FOUND){s.status(404).json({error:g.message,code:"agent_not_found",name:g.subagentName??i});return}if(g.code===Ve.INVALID_CONFIG){s.status(403).json({error:g.message,code:"agent_readonly",name:g.subagentName??i});return}if(g.code===Ve.VALIDATION_ERROR||g.code===Ve.INVALID_NAME||g.code===Ve.TOOL_NOT_FOUND){s.status(422).json({error:g.message,code:"invalid_config",name:g.subagentName??i});return}if(g.code===Ve.FILE_ERROR){let v=qt();s.status(500).json({error:v?g.message:"Failed to write workspace agent file",code:"file_error",name:g.subagentName??i});return}}D(`matilda serve: POST /workspace/agents/${vr(i)} failed: ${g instanceof Error?g.stack??g.message:String(g)}`),s.status(500).json({error:"Failed to update workspace agent",code:"agent_update_failed"});return}let p=await r.loadSubagent(i,l.level);if(!p){D(`matilda serve: agent_update_reload_failed (name=${vr(i)} level=${l.level}) \u2014 disk write completed; check \`GET /workspace/agents/${vr(i)}\` for the new state`),s.status(500).json({error:"Agent update succeeded but reload failed",code:"agent_update_reload_failed",name:i,level:l.level});return}let f=l.level==="project"?"project":"user";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:l.name,level:f},...a?{originatorClientId:a}:{}}),s.status(200).json({ok:!0,agent:Gt(p),changed:!0})}),t.delete("/workspace/agents/:agentType",e.mutate({strict:!0}),async(n,s)=>{let i=Fc(n,s);if(i===null)return;let o=hi(e,n,s);if(o===null)return;let a=o,c=Tg(n,s);if(c===null)return;let d=c?[c]:["project","user"],u=[];for(let f of d){let g=await r.loadSubagent(i,f);g&&u.push(g)}for(let f of u)if(Pg(f,i,s))return;try{await r.deleteSubagent(i,c)}catch(f){if(f instanceof Ar){if(f.code===Ve.NOT_FOUND){s.status(404).json({error:f.message,code:"agent_not_found",name:f.subagentName??i});return}if(f.code===Ve.INVALID_CONFIG){s.status(403).json({error:f.message,code:"agent_readonly",name:f.subagentName??i});return}}D(`matilda serve: DELETE /workspace/agents/${vr(i)} failed: ${f instanceof Error?f.stack??f.message:String(f)}`),s.status(500).json({error:"Failed to delete workspace agent",code:"agent_delete_failed"});return}let l=[],p=[];for(let f of u){if(!f.filePath){l.push(f);continue}try{await JE.access(f.filePath),p.push(f)}catch{l.push(f)}}if(p.length>0){D(`matilda serve: DELETE /workspace/agents/${vr(i)} partial \u2014 removed=${l.map(f=>f.level).join(",")||"none"} remaining=${p.map(f=>`${f.level}:${f.filePath}`).join(",")}`);for(let f of l){let g=f.level==="project"?"project":"user";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:f.name,level:g},...a?{originatorClientId:a}:{}})}s.status(500).json({error:`Failed to delete every level of subagent "${i}" \u2014 ${p.length} level(s) still have their file on disk`,code:"agent_delete_partial",name:i,removedLevels:l.map(f=>f.level),remainingLevels:p.map(f=>f.level)});return}if(u.length===0){let f=c==="user"?"user":"project";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:i,level:f},...a?{originatorClientId:a}:{}})}else for(let f of l){let g=f.level==="project"?"project":"user";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:f.name,level:g},...a?{originatorClientId:a}:{}})}s.status(204).end()})}function vr(t){return JSON.stringify(String(t)).slice(0,82)}function Fc(t,e){let r=t.params.agentType;return!r||r.length===0?(e.status(400).json({error:"`agentType` path parameter is required",code:"invalid_agent_type"}),null):r.length>Lc||!Og.test(r)?(e.status(400).json({error:"`agentType` must contain only letters, numbers, hyphens, or underscores (max 64 chars)",code:"invalid_agent_type",agentType:r}),null):r}function Tg(t,e){let r=t.query.scope;if(r!==void 0)return typeof r!="string"?(e.status(400).json({error:'`scope` query must be a single "workspace" or "global" value',code:"invalid_scope"}),null):r!=="workspace"&&r!=="global"?(e.status(400).json({error:'`scope` query must be "workspace" or "global"',code:"invalid_scope"}),null):r==="workspace"?"project":"user"}function Pg(t,e,r){return t.isBuiltin||t.level==="builtin"||t.level==="extension"||t.level==="session"?(r.status(403).json({error:`Cannot modify ${t.level}-level subagent "${e}"`,code:"agent_readonly",name:t.name,level:t.level}),!0):!1}function hi(t,e,r){let n=t.parseClientId(e,r);if(n===null)return null;if(n!==void 0)return t.bridge.knownClientIds().has(n)?n:(r.status(400).json({error:`Client id "${n}" is not registered for this workspace`,code:"invalid_client_id",clientId:n}),null)}function XE(t,e,r){let n=t.name;if(typeof n!="string"||n.trim().length===0){r.status(422).json({error:"`name` is required and must be a non-empty string",code:"invalid_config"});return}let s=n.trim();if(s.length<Ag||s.length>Lc||!Og.test(s)){r.status(422).json({error:`\`name\` must be ${Ag}-${Lc} characters of letters, numbers, hyphens, or underscores`,code:"invalid_config",name:s});return}if(Qn.isBuiltinAgent(s)){r.status(422).json({error:`"${s}" shadows a built-in subagent and cannot be used as a project- or user-level agent name. Choose a different name.`,code:"invalid_config",name:s});return}let i=t.description;if(typeof i!="string"||i.trim().length===0){r.status(422).json({error:"`description` is required and must be a non-empty string",code:"invalid_config"});return}if(Buffer.byteLength(i,"utf8")>mi){r.status(422).json({error:`\`description\` exceeds the ${mi}-byte limit`,code:"invalid_config"});return}let o=t.systemPrompt;if(typeof o!="string"||o.trim().length===0){r.status(422).json({error:"`systemPrompt` is required and must be a non-empty string (whitespace only is rejected)",code:"invalid_config"});return}if(Buffer.byteLength(o,"utf8")>gi){r.status(422).json({error:`\`systemPrompt\` exceeds the ${gi}-byte limit`,code:"invalid_config"});return}let a=vi(t.tools,"tools",r);if(a===null)return;let c=vi(t.disallowedTools,"disallowedTools",r);if(c===null)return;let d={name:s,description:i,systemPrompt:o,level:e};if(a!==void 0&&(d.tools=a),c!==void 0&&(d.disallowedTools=c),zt(t,"model","string",r)||(typeof t.model=="string"&&(d.model=t.model),zt(t,"color","string",r))||(typeof t.color=="string"&&(d.color=t.color),zt(t,"approvalMode","string",r)))return;if(typeof t.approvalMode=="string"){if(!tt.includes(t.approvalMode)){r.status(422).json({error:`\`approvalMode\` must be one of ${JSON.stringify(tt)}`,code:"invalid_config"});return}d.approvalMode=t.approvalMode}if(zt(t,"background","boolean",r))return;typeof t.background=="boolean"&&(d.background=t.background);let u=t.runConfig;if(u!==void 0){let l=Fg(u,r);if(l===null)return;d.runConfig=l}return d}function YE(t,e){let r={};if("description"in t){let n=t.description;if(typeof n!="string"||n.trim().length===0){e.status(422).json({error:"`description` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return}if(Buffer.byteLength(n,"utf8")>mi){e.status(422).json({error:`\`description\` exceeds the ${mi}-byte limit`,code:"invalid_config"});return}r.description=n}if("systemPrompt"in t){let n=t.systemPrompt;if(typeof n!="string"||n.trim().length===0){e.status(422).json({error:"`systemPrompt` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return}if(Buffer.byteLength(n,"utf8")>gi){e.status(422).json({error:`\`systemPrompt\` exceeds the ${gi}-byte limit`,code:"invalid_config"});return}r.systemPrompt=n}if("tools"in t){let n=vi(t.tools,"tools",e);if(n===null)return;n!==void 0&&(r.tools=n)}if("disallowedTools"in t){let n=vi(t.disallowedTools,"disallowedTools",e);if(n===null)return;n!==void 0&&(r.disallowedTools=n)}if(!zt(t,"model","string",e)&&(typeof t.model=="string"&&(r.model=t.model),!zt(t,"color","string",e)&&(typeof t.color=="string"&&(r.color=t.color),!zt(t,"approvalMode","string",e)))){if(typeof t.approvalMode=="string"){if(!tt.includes(t.approvalMode)){e.status(422).json({error:`\`approvalMode\` must be one of ${JSON.stringify(tt)}`,code:"invalid_config"});return}r.approvalMode=t.approvalMode}if(!zt(t,"background","boolean",e)){if(typeof t.background=="boolean"&&(r.background=t.background),"runConfig"in t){let n=Fg(t.runConfig,e);if(n===null)return;r.runConfig=n}return r}}}function vi(t,e,r){if(t!==void 0)return!Array.isArray(t)||t.some(n=>typeof n!="string")?(r.status(422).json({error:`\`${e}\` must be an array of strings when provided`,code:"invalid_config"}),null):t.length>Rg?(r.status(422).json({error:`\`${e}\` exceeds the ${Rg}-entry limit`,code:"invalid_config"}),null):t.some(n=>n.length>Cg)?(r.status(422).json({error:`\`${e}\` entries must be at most ${Cg} characters`,code:"invalid_config"}),null):t}function zt(t,e,r,n){return!(e in t)||typeof t[e]===r?!1:(n.status(422).json({error:`\`${e}\` must be a ${r} when provided`,code:"invalid_config"}),!0)}function QE(t,e){if(e.description!==void 0&&e.description!==t.description||e.systemPrompt!==void 0&&e.systemPrompt!==t.systemPrompt||e.tools!==void 0&&!Mg(e.tools,t.tools)||e.disallowedTools!==void 0&&!Mg(e.disallowedTools,t.disallowedTools)||e.model!==void 0&&e.model!==t.model||e.color!==void 0&&e.color!==t.color||e.approvalMode!==void 0&&e.approvalMode!==t.approvalMode||e.background!==void 0&&e.background!==t.background)return!1;if(e.runConfig!==void 0){let r=t.runConfig??{},n=e.runConfig;if("max_time_minutes"in n&&n.max_time_minutes!==r.max_time_minutes||"max_turns"in n&&n.max_turns!==r.max_turns)return!1}return!0}function Mg(t,e){if(t===e)return!0;if(!t||!e||t.length!==e.length)return!1;for(let r=0;r<t.length;r++)if(t[r]!==e[r])return!1;return!0}function Fg(t,e){if(typeof t!="object"||t===null||Array.isArray(t))return e.status(422).json({error:"`runConfig` must be an object when provided",code:"invalid_config"}),null;let r=t,n={};if("max_time_minutes"in r){let s=r.max_time_minutes;if(typeof s!="number"||!Number.isFinite(s)||s<=0)return e.status(422).json({error:"`runConfig.max_time_minutes` must be a positive finite number when provided",code:"invalid_config"}),null;n.max_time_minutes=s}if("max_turns"in r){let s=r.max_turns;if(typeof s!="number"||!Number.isFinite(s)||s<=0||!Number.isInteger(s))return e.status(422).json({error:"`runConfig.max_turns` must be a positive integer when provided",code:"invalid_config"}),null;n.max_turns=s}return n}function yi(t){let e={kind:"agent",name:t.name,description:t.description,level:t.level,isBuiltin:t.isBuiltin===!0||t.level==="builtin",hasTools:Array.isArray(t.tools)&&t.tools.length>0};return t.model&&(e.model=t.model),t.color&&(e.color=t.color),t.background!==void 0&&(e.background=t.background),t.approvalMode&&(e.approvalMode=t.approvalMode),t.extensionName&&(e.extensionName=t.extensionName),t.filePath&&(e.filePath=t.filePath),e}function Gt(t){let e={...yi(t),systemPrompt:t.systemPrompt};if(t.tools&&(e.tools=[...t.tools]),t.disallowedTools&&(e.disallowedTools=[...t.disallowedTools]),t.runConfig){let r={};typeof t.runConfig.max_time_minutes=="number"&&(r.max_time_minutes=t.runConfig.max_time_minutes),typeof t.runConfig.max_turns=="number"&&(r.max_turns=t.runConfig.max_turns),e.runConfig=r}return e}function Nc(t){let e={getSdkMode:()=>!1,getProjectRoot:()=>t,getActiveExtensions:()=>[]},r=new Proxy(e,{get(n,s){if(s in n)return n[s];if(s!=="then")throw new Error(`matilda serve workspace agents: SubagentManager touched Config.${String(s)} which the daemon stub does not implement. Add it to createDaemonSubagentManager and audit safety.`)},has(n,s){if(s in n)return!0;if(s==="then")return!1;throw new Error(`matilda serve workspace agents: SubagentManager probed Config.${String(s)} via 'in' check; the daemon stub does not implement it. Add it to createDaemonSubagentManager and audit safety.`)}});return new fu(r)}w();var j="_matilda/",$c="matilda",$={PARSE_ERROR:-32700,INVALID_REQUEST:-32600,METHOD_NOT_FOUND:-32601,INVALID_PARAMS:-32602,INTERNAL_ERROR:-32603};function yr(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Qe(t){return yr(t)&&t.jsonrpc==="2.0"&&typeof t.method=="string"&&"id"in t&&t.id!==null&&(typeof t.id=="number"||typeof t.id=="string")}function Bc(t){return yr(t)&&t.jsonrpc==="2.0"&&typeof t.method=="string"&&!("id"in t)}function qc(t){return yr(t)&&t.jsonrpc==="2.0"&&!("method"in t)&&"id"in t&&"result"in t!="error"in t}var ZE=new RegExp(String.raw`[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]`,"g");function ce(t){return t.replace(ZE," ")}function jc(t,e){return{jsonrpc:"2.0",id:t,result:e}}function W(t,e,r,n){return{jsonrpc:"2.0",id:t,error:{code:e,message:r,...n!==void 0?{data:n}:{}}}}function On(t,e){return{jsonrpc:"2.0",method:t,params:e}}function Lg(t,e,r){return{jsonrpc:"2.0",id:t,method:e,params:r}}function Wc(t){return Array.isArray(t)?{ok:!1,error:W(null,$.INVALID_REQUEST,"JSON-RPC batch not supported")}:Qe(t)||Bc(t)||qc(t)?{ok:!0,message:t}:{ok:!1,error:W(null,$.INVALID_REQUEST,"Malformed JSON-RPC message")}}function je(t){return t instanceof Error?t.message:String(t)}var qg=`${j}session/shell`,jg=[`${j}session/heartbeat`,`${j}session/context`,`${j}session/supported_commands`,`${j}session/update_metadata`,`${j}workspace/mcp`,`${j}workspace/skills`,`${j}workspace/providers`,`${j}workspace/env`,`${j}workspace/preflight`,`${j}workspace/init`,`${j}workspace/set_tool_enabled`,`${j}workspace/restart_mcp_server`,`${j}session/recap`,`${j}session/btw`,qg,`${j}session/detach`,`${j}session/context_usage`,`${j}session/tasks`,`${j}workspace/memory`,`${j}workspace/memory/write`,`${j}file/read`,`${j}file/read_bytes`,`${j}file/stat`,`${j}file/list`,`${j}file/glob`,`${j}file/write`,`${j}file/edit`,`${j}workspace/auth/status`,`${j}workspace/auth/device_flow/start`,`${j}workspace/auth/device_flow/get`,`${j}workspace/auth/device_flow/cancel`,`${j}workspace/tools`,`${j}workspace/mcp/tools`,`${j}workspace/mcp/servers/add`,`${j}workspace/mcp/servers/remove`,`${j}sessions/delete`,`${j}workspace/agents/list`,`${j}workspace/agents/get`,`${j}workspace/agents/create`,`${j}workspace/agents/update`,`${j}workspace/agents/delete`];function tI(t){return jg.filter(e=>t||e!==qg)}var rI=new Set(["authenticate","session/new","session/load","session/resume","session/list","session/close","session/fork",...jg]),Kt=256,Jt=class extends Error{};function Ng(t,e){if(!("cwd"in t)||t.cwd===void 0)return e;let r=t.cwd;if(typeof r!="string")throw new Jt("`cwd` must be a string absolute path when provided");if(r.length>wt)throw new Jt(`\`cwd\` exceeds the ${wt}-character limit`);if(!eI.isAbsolute(r))throw new Jt("`cwd` must be an absolute path when provided");return r}function nI(t){let e=t.prompt;if(!Array.isArray(e)||e.length===0)throw new Jt("`prompt` is required and must be a non-empty array of content blocks");if(!e.every(r=>typeof r=="object"&&r!==null&&!Array.isArray(r)))throw new Jt("each `prompt` element must be an object")}function Hc(t){if(t instanceof Jt||t instanceof Jr)return{code:$.INVALID_PARAMS,message:t.message};if(t instanceof Ar)return{code:$.INVALID_PARAMS,message:t.message};if(t instanceof B)return{code:$.INVALID_PARAMS,message:t.message,data:{errorKind:t.kind,hint:t.hint}};if(t instanceof rs)return{code:$.INVALID_PARAMS,message:t.message,data:{errorKind:"memory_file_too_large"}};if(t instanceof es)return{code:$.INTERNAL_ERROR,message:t.message,data:{errorKind:"memory_write_timeout"}};if(t instanceof mr)return{code:$.INTERNAL_ERROR,message:t.message,data:{errorKind:"too_many_active_flows"}};if(t instanceof hr)return{code:$.INVALID_PARAMS,message:t.message,data:{errorKind:"unsupported_provider"}};if(t instanceof vt)return{code:$.INTERNAL_ERROR,message:t.message,data:{errorKind:"upstream_error"}};if(t instanceof bt)return{code:$.INVALID_PARAMS,message:je(t),data:{errorKind:"session_shell_disabled"}};if(t instanceof St)return{code:$.INVALID_PARAMS,message:je(t),data:{errorKind:"client_id_required"}};switch(t instanceof Error?t.name:""){case"SessionNotFoundError":case"InvalidSessionScopeError":case"WorkspaceMismatchError":case"InvalidClientIdError":return{code:$.INVALID_PARAMS,message:je(t)};case"SessionLimitExceededError":return{code:$.INTERNAL_ERROR,message:je(t)};case"PromptQueueFullError":{let r=t;return{code:$.INTERNAL_ERROR,message:je(t),data:{errorKind:"prompt_queue_full",sessionId:r.sessionId,limit:r.limit,pendingCount:r.pendingCount}}}default:return{code:$.INTERNAL_ERROR,message:"Internal error",data:{errorKind:"internal"}}}}function $g(t,e){let{code:r,message:n,data:s}=Hc(e);return W(t,r,n,s)}var Bg=1,wi=class{constructor(e,r,n,s,i,o=!1){this.bridge=e;this.boundWorkspace=r;this.workspace=n;this.fsFactory=s;this.deviceFlowRegistry=i;this.sessionShellCommandEnabled=o;this.agentManager=Nc(r)}agentManager;killOrphanSession(e){this.bridge.killSession(e,{requireZeroAttaches:!0}).catch(r=>D(`matilda serve: /acp orphan killSession(${ce(e)}) failed: ${ce(je(r))}`))}wsCtx(e,r){return{originatorClientId:e.clientId,route:`ACP ${r}`,workspaceCwd:this.boundWorkspace}}sessionCtx(e,r,n){let s=e.sessions.get(r)?.clientId;if(!s)throw new Error(`no bridge-stamped clientId for session ${r} (ownership invariant violated)`);return{clientId:s,fromLoopback:n}}async configOptionsFor(e){try{let n=(await this.bridge.getSessionContextStatus(e))?.state?.configOptions;return Array.isArray(n)?n:void 0}catch(r){D(`matilda serve: /acp configOptionsFor(${ce(e)}) failed: ${ce(je(r))}`);return}}extractModelState(e){if(!e)return;let r=e.find(i=>typeof i=="object"&&i!==null&&i.category==="model");if(!r)return;let n=String(r.currentValue??""),s=Array.isArray(r.options)?r.options:[];return{currentModelId:n,availableModels:s.map(i=>{let o=i;return{id:String(o.value??o.id??"")}})}}extractModeState(e){if(!e)return;let r=e.find(i=>typeof i=="object"&&i!==null&&i.category==="mode");if(!r)return;let n=String(r.currentValue??""),s=Array.isArray(r.options)?r.options:[];return{currentModeId:n,availableModes:s.map(i=>{let o=i;return{id:String(o.value??o.id??"")}})}}cancelAbandonedPermission(e,r){try{return this.bridge.respondToSessionPermission(e.sessionId,e.bridgeRequestId,{outcome:{outcome:"cancelled"}},r!==void 0?{clientId:r}:void 0),!0}catch(n){let s=je(n);return/not found|unknown session/i.test(s)?!0:(D(`matilda serve: /acp cancelAbandonedPermission(${ce(e.sessionId)}) failed: ${ce(s)}`),!1)}}buildInitializeResult(e,r){let n=typeof r=="number"&&Number.isFinite(r)?r:Bg;return{protocolVersion:Math.max(1,Math.min(n,Bg)),agentCapabilities:{loadSession:!0,promptCapabilities:{image:!0,audio:!0,embeddedContext:!0},configOptions:!0,_meta:{[$c]:{connectionId:e,workspaceCwd:this.boundWorkspace,methods:tI(this.sessionShellCommandEnabled)}}}}}requireOwned(e,r,n){return e.ownsSession(r)?!0:n===void 0?(D(`matilda serve: /acp notification for unowned session ${ce(r)} (dropped)`),!1):(e.sendConn(W(n,$.INVALID_PARAMS,`Session ${r} is not owned by this connection`)),!1)}async handle(e,r,n,s){let i=s??e.fromLoopback;if(qc(r)){try{this.resolveClientResponse(e,r,i)}catch(d){D(`matilda serve: /acp response handling error: ${ce(je(d))}`)}return}if(!Qe(r)&&!Bc(r))return;let o=r.method,a=yr(r.params)?r.params:{},c=Qe(r)?r.id:void 0;if(n&&typeof a.sessionId=="string"&&a.sessionId!==n){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"Acp-Session-Id header does not match params.sessionId"));return}try{switch(o){case"authenticate":this.replyConn(e,c,{});return;case"session/new":{let d=Ng(a,this.boundWorkspace),u=await this.bridge.spawnOrAttach({workspaceCwd:d,clientId:e.clientId,sessionScope:"thread"});if(e.destroyed){this.killOrphanSession(u.sessionId);return}e.getOrCreateSession(u.sessionId).clientId=u.clientId,e.ownSession(u.sessionId);let l=await this.configOptionsFor(u.sessionId);if(e.destroyed){this.killOrphanSession(u.sessionId);return}let p=this.extractModelState(l),f=this.extractModeState(l);this.replyConn(e,c,{sessionId:u.sessionId,...l?{configOptions:l}:{},...p?{models:p}:{},...f?{modes:f}:{}});return}case"session/load":case"session/resume":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(e.closingSessions.has(d)){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,`session ${d} is being closed; retry`));return}let u=Ng(a,this.boundWorkspace),l=o==="session/load"?await this.bridge.loadSession({sessionId:d,workspaceCwd:u,clientId:e.clientId}):await this.bridge.resumeSession({sessionId:d,workspaceCwd:u,clientId:e.clientId}),p=e.closingSessions.has(d);if(e.destroyed||p){(l.attached?this.bridge.detachClient(d,l.clientId):this.bridge.killSession(d,{requireZeroAttaches:!0})).catch(O=>D(`matilda serve: /acp orphan ${l.attached?"detach":"kill"}(${ce(d)}) teardown-race: ${ce(je(O))}`)),p&&!e.destroyed&&c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,`session ${d} was closed during load; retry`));return}e.getOrCreateSession(d).clientId=l.clientId,e.ownSession(d);let f=await this.configOptionsFor(d),g=this.extractModelState(f),v=this.extractModeState(f);this.replyConn(e,c,{...l.state??{},...f?{configOptions:f}:{},...g?{models:g}:{},...v?{modes:v}:{}});return}case"session/list":{let d=typeof a.cursor=="string"?a.cursor:void 0,u=yr(a._meta)?a._meta:void 0,l=typeof u?.size=="number"?u.size:void 0,p=await Uc(this.bridge,this.boundWorkspace,{cursor:d,size:l});this.replyConn(e,c,{sessions:p.sessions.map(f=>({sessionId:f.sessionId,cwd:f.workspaceCwd,title:f.title,updatedAt:f.updatedAt})),...p.nextCursor!=null?{nextCursor:p.nextCursor}:{}});return}case"session/close":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;e.ownedSessions.delete(d),e.closingSessions.add(d);try{await this.bridge.closeSession(d,this.sessionCtx(e,d,i))}finally{try{e.closeSessionStream(d)}catch(u){D(`matilda serve: /acp session/close local teardown failed (${ce(d)}): ${ce(je(u))}`)}e.closingSessions.delete(d)}this.replyConn(e,c,{});return}case"session/fork":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(!this.requireOwned(e,d,c))return;let u=this.sessionCtx(e,d,i),l=await this.bridge.branchSession(d,{name:typeof a.name=="string"?a.name:void 0},u);if(e.destroyed){this.killOrphanSession(l.sessionId);return}e.getOrCreateSession(l.sessionId).clientId=l.clientId,e.ownSession(l.sessionId);let p=await this.configOptionsFor(l.sessionId),f=this.extractModelState(p),g=this.extractModeState(p);this.replyConn(e,c,{sessionId:l.sessionId,...p?{configOptions:p}:{},...f?{models:f}:{},...g?{modes:g}:{}});return}case"session/cancel":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;e.sessions.get(d)?.promptAbort?.abort(),await this.bridge.cancelSession(d,{...a,sessionId:d},this.sessionCtx(e,d,i)),c!==void 0&&this.replySession(e,d,c,{});return}case"session/prompt":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;nI(a),await this.handlePrompt(e,d,c,a,i);return}case"session/set_config_option":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=String(a.configId??""),l=a.value,p=this.sessionCtx(e,d,i);if(typeof l!="string"||l.length===0){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,"`value` must be a non-empty string"));return}if(u==="model")await this.bridge.setSessionModel(d,{modelId:l},p);else if(u==="mode"){let g=l==="yolo"?"bogan":l;if(!tt.includes(g)){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,`invalid mode "${l}" (expected one of: ${tt.join(", ")})`));return}await this.bridge.setSessionApprovalMode(d,g,{persist:a.persist===!0},p)}else{c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,`Unknown configId: ${u}`));return}let f=await this.configOptionsFor(d);this.replySession(e,d,c,{configOptions:f});return}case"session/set_mode":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(!this.requireOwned(e,d,c))return;let u=String(a.modeId??""),l=u==="yolo"?"bogan":u;if(!l||!tt.includes(l)){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,`invalid modeId "${u}" (expected one of: ${tt.join(", ")})`));return}let p=this.sessionCtx(e,d,i);await this.bridge.setSessionApprovalMode(d,l,{persist:!1},p),this.replySession(e,d,c,{});return}case"session/set_model":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(!this.requireOwned(e,d,c))return;let u=String(a.modelId??"");if(!u){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,"`modelId` is required"));return}let l=this.sessionCtx(e,d,i);await this.bridge.setSessionModel(d,{modelId:u,sessionId:d},l),this.replySession(e,d,c,{});return}case`${j}session/heartbeat`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=this.bridge.recordHeartbeat(d,this.sessionCtx(e,d,i));this.replyConn(e,c,u);return}case`${j}session/context`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;this.replyConn(e,c,await this.bridge.getSessionContextStatus(d));return}case`${j}session/supported_commands`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;this.replyConn(e,c,await this.bridge.getSessionSupportedCommandsStatus(d));return}case`${j}session/update_metadata`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=yr(a.metadata)?a.metadata:{},l=this.bridge.updateSessionMetadata(d,u,this.sessionCtx(e,d,i));this.replyConn(e,c,l);return}case`${j}workspace/mcp`:this.replyConn(e,c,await this.workspace.getWorkspaceMcpStatus(this.wsCtx(e,o)));return;case`${j}workspace/skills`:this.replyConn(e,c,await this.workspace.getWorkspaceSkillsStatus(this.wsCtx(e,o)));return;case`${j}workspace/providers`:this.replyConn(e,c,await this.workspace.getWorkspaceProvidersStatus(this.wsCtx(e,o)));return;case`${j}workspace/env`:this.replyConn(e,c,await this.workspace.getWorkspaceEnvStatus(this.wsCtx(e,o)));return;case`${j}workspace/preflight`:this.replyConn(e,c,await this.workspace.getWorkspacePreflightStatus(this.wsCtx(e,o)));return;case`${j}workspace/init`:{let d=a.force;if(d!==void 0&&typeof d!="boolean"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`force` must be a boolean when provided"));return}let u=d===!0,l=await this.workspace.initWorkspace(this.wsCtx(e,o),{force:u});this.replyConn(e,c,l);return}case`${j}workspace/set_tool_enabled`:{let d=String(a.toolName??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`toolName\` is required and must be \u2264 ${Kt} chars`));return}let u=await this.workspace.setWorkspaceToolEnabled(this.wsCtx(e,o),d,a.enabled===!0);this.replyConn(e,c,u);return}case`${j}workspace/restart_mcp_server`:{let d=String(a.serverName??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`serverName\` is required and must be \u2264 ${Kt} chars`));return}let u=a.entryIndex;if(u!==void 0&&(typeof u!="number"||!Number.isInteger(u)||u<0)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`entryIndex` must be a non-negative integer"));return}let l=await this.workspace.restartMcpServer(this.wsCtx(e,o),d,u!==void 0?{entryIndex:u}:void 0);this.replyConn(e,c,l);return}case`${j}session/recap`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=await this.bridge.generateSessionRecap(d,this.sessionCtx(e,d,i));this.replyConn(e,c,u);return}case`${j}session/btw`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=a.question;if(typeof u!="string"||u.trim().length===0||u.length>Rr){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`question\` required, non-empty, max ${Rr} chars`));return}let l=await this.bridge.generateSessionBtw(d,u.trim(),void 0,this.sessionCtx(e,d,i));this.replyConn(e,c,l);return}case`${j}session/shell`:{let d=String(a.sessionId??"");if(!this.sessionShellCommandEnabled){c!==void 0&&e.sendConn($g(c,new bt));return}if(!this.requireOwned(e,d,c))return;let u=e.sessions.get(d);if(!u?.clientId){c!==void 0&&e.sendConn($g(c,new St));return}let p=a.command;if(typeof p!="string"||p.trim().length===0){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`command` required and must be non-empty"));return}let f=ce(d.slice(0,8)),g=ce(String(e.clientId?.slice(0,8))),v=ce(p.slice(0,120));D(`matilda serve: /acp session/shell session=${f} client=${g} cmd=${v}`);let x=await this.bridge.executeShellCommand(d,p,u.abort.signal,this.sessionCtx(e,d,i));this.replyConn(e,c,x);return}case`${j}session/detach`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=this.sessionCtx(e,d,i);await this.bridge.detachClient(d,u.clientId),this.replyConn(e,c,{ok:!0});return}case`${j}session/context_usage`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=await this.bridge.getSessionContextUsageStatus(d,{detail:a.detail===!0});this.replyConn(e,c,u);return}case`${j}session/tasks`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=await this.bridge.getSessionTasksStatus(d);this.replyConn(e,c,u);return}case`${j}workspace/memory`:{let d=await Dc(this.boundWorkspace);this.replyConn(e,c,d);return}case`${j}workspace/memory/write`:{let d=a.content;if(typeof d!="string"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`content` required, must be string"));return}if(Buffer.byteLength(d,"utf8")>1024*1024){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`content` exceeds 1MB limit"));return}let u=a.scope;if(u!==void 0&&u!=="workspace"&&u!=="global"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,'`scope` must be "workspace" or "global"'));return}let l=u??"workspace",p=a.mode;if(p!==void 0&&p!=="append"&&p!=="replace"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,'`mode` must be "append" or "replace"'));return}let f=p??"append";D(`matilda serve: /acp workspace/memory/write scope=${l} mode=${f} client=${e.clientId?.slice(0,8)} bytes=${Buffer.byteLength(d,"utf8")}`);let g=await ts({scope:l,mode:f,content:d,projectRoot:this.boundWorkspace});if(this.replyConn(e,c,{ok:!0,filePath:g.filePath,bytesWritten:g.bytesWritten,changed:g.changed}),g.changed)try{this.bridge.publishWorkspaceEvent({type:"memory_changed",data:{scope:l,filePath:g.filePath,mode:f,bytesWritten:g.bytesWritten},originatorClientId:e.clientId})}catch{}return}case`${j}file/read`:{let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=await u.readText(l,{maxBytes:typeof a.maxBytes=="number"?a.maxBytes:void 0,line:typeof a.line=="number"?a.line:void 0,limit:typeof a.limit=="number"?a.limit:void 0});this.replyConn(e,c,{path:d,content:p.content,...p.meta});return}case`${j}file/read_bytes`:{if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=await u.readBytesWindow(l,{offset:typeof a.offset=="number"?a.offset:void 0,maxBytes:typeof a.maxBytes=="number"?a.maxBytes:void 0});this.replyConn(e,c,{path:d,...p});return}case`${j}file/stat`:{if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=await u.stat(l);this.replyConn(e,c,{path:d,...p});return}case`${j}file/list`:{if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=2e3,f=await u.list(l,{maxEntries:p+1}),g=f.length>p;this.replyConn(e,c,{path:d,entries:g?f.slice(0,p):f,truncated:g});return}case`${j}file/glob`:{let d=String(a.pattern??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`pattern` required"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),p=typeof a.maxResults=="number"?Math.max(1,Math.min(Number(a.maxResults)||5e3,5e4)):5e3,f=await u.glob(d,{maxResults:p+1}),g=f.length>p;this.replyConn(e,c,{pattern:d,matches:g?f.slice(0,p):f,truncated:g});return}case`${j}file/write`:{let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}if(typeof a.content!="string"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`content` must be string"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"write");if(Buffer.byteLength(a.content,"utf8")>10*1024*1024){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"content exceeds 10MB limit"));return}await u.writeTextOverwrite(l,a.content),this.replyConn(e,c,{ok:!0,path:d});return}case`${j}file/edit`:{let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}if(typeof a.oldText!="string"||typeof a.newText!="string"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`oldText` and `newText` must be strings"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"write"),p=await u.edit(l,a.oldText,a.newText);this.replyConn(e,c,{ok:!0,path:d,...p});return}case`${j}workspace/auth/status`:{if(!this.deviceFlowRegistry){this.replyConn(e,c,{pendingDeviceFlows:[]});return}let u=this.deviceFlowRegistry.listPending().map(l=>({deviceFlowId:l.deviceFlowId,providerId:l.providerId,expiresAt:l.expiresAt}));this.replyConn(e,c,{pendingDeviceFlows:u});return}case`${j}workspace/auth/device_flow/start`:{if(!this.deviceFlowRegistry){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"Device flow not configured"));return}let d=String(a.providerId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`providerId` required"));return}let u=await this.deviceFlowRegistry.start({providerId:d,initiatorClientId:e.clientId}),{view:l,attached:p}=u,f=l.initiatorClientId===e.clientId?l:{deviceFlowId:l.deviceFlowId,providerId:l.providerId,status:l.status,expiresAt:l.expiresAt};this.replyConn(e,c,{view:f,attached:p});return}case`${j}workspace/auth/device_flow/get`:{if(!this.deviceFlowRegistry){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"Device flow not configured"));return}let d=String(a.id??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`id` required"));return}let u=this.deviceFlowRegistry.get(d);if(!u){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Device flow "${d}" not found`));return}let l=u.initiatorClientId===e.clientId?u:{deviceFlowId:u.deviceFlowId,providerId:u.providerId,status:u.status,expiresAt:u.expiresAt};this.replyConn(e,c,l);return}case`${j}workspace/auth/device_flow/cancel`:{if(!this.deviceFlowRegistry){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"Device flow not configured"));return}let d=String(a.id??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`id` required"));return}let u=this.deviceFlowRegistry.get(d);if(u&&u.initiatorClientId&&u.initiatorClientId!==e.clientId){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"Only the flow initiator can cancel"));return}let l=this.deviceFlowRegistry.cancel(d,e.clientId);if(!l){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Device flow "${d}" not found`));return}this.replyConn(e,c,{ok:!0,alreadyTerminal:l.alreadyTerminal});return}case`${j}workspace/tools`:{let d=await this.bridge.getWorkspaceToolsStatus();this.replyConn(e,c,d);return}case`${j}workspace/mcp/tools`:{let d=String(a.serverName??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`serverName` required"));return}let u=await this.bridge.getWorkspaceMcpToolsStatus(d);this.replyConn(e,c,u);return}case`${j}workspace/mcp/servers/add`:{let d=String(a.name??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`name\` required, max ${Kt} chars`));return}let u=a.config;if(!u||typeof u!="object"||Array.isArray(u)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`config` required, must be object"));return}let l=await this.bridge.addRuntimeMcpServer(d,u,e.clientId);this.replyConn(e,c,l);return}case`${j}workspace/mcp/servers/remove`:{let d=String(a.name??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`name\` required, max ${Kt} chars`));return}let u=await this.bridge.removeRuntimeMcpServer(d,e.clientId);this.replyConn(e,c,u);return}case`${j}sessions/delete`:{let d=a.sessionIds;if(!Array.isArray(d)||d.length===0||d.length>100||!d.every(v=>typeof v=="string")){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionIds` must be non-empty string array (max 100)"));return}let u=[...new Set(d)],l=[],p=[];await Promise.allSettled(u.map(async v=>{try{await this.bridge.closeSession(v),p.push(v)}catch(x){let O=x instanceof Error?x.message:String(x);if(x instanceof Error&&x.name==="SessionNotFoundError")p.push(v);else{let P=ce(v.slice(0,8)),q=ce(O);D(`matilda serve: /acp sessions/delete closeSession(${P}) failed: ${q}`),l.push({sessionId:v,error:O})}}}));let g=await new kr(this.boundWorkspace).removeSessions(p);for(let v of g.errors){let x=ce(v.sessionId.slice(0,8)),O=ce(je(v.error));D(`matilda serve: /acp sessions/delete removeSessions(${x}) failed: ${O}`)}this.replyConn(e,c,{removed:g.removed,notFound:g.notFound,errors:[...l,...g.errors.map(v=>({sessionId:v.sessionId,error:je(v.error)}))]});return}case`${j}workspace/agents/list`:{let d=await this.agentManager.listSubagents({force:!0});this.replyConn(e,c,{v:1,workspaceCwd:this.boundWorkspace,agents:d.map(yi)});return}case`${j}workspace/agents/get`:{let d=String(a.agentType??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`agentType` required"));return}let u=await this.agentManager.loadSubagent(d);if(!u){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${d}" not found`));return}this.replyConn(e,c,Gt(u));return}case`${j}workspace/agents/create`:{let d=a.scope;if(d!=="workspace"&&d!=="global"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,'`scope` must be "workspace" or "global"'));return}let u=a.name;if(typeof u!="string"||!u.trim()){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`name` required"));return}let l=d==="workspace"?"project":"user";if(Qn.isBuiltinAgent(u)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Cannot shadow built-in agent "${u}"`));return}if(await this.agentManager.loadSubagent(u,l)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${u}" already exists`));return}await this.agentManager.createSubagent({name:u,level:l,description:typeof a.description=="string"?a.description:"",systemPrompt:typeof a.systemPrompt=="string"?a.systemPrompt:"",tools:Array.isArray(a.tools)?a.tools:void 0,model:typeof a.model=="string"?a.model:void 0},{level:l});let f=await this.agentManager.loadSubagent(u,l);this.replyConn(e,c,{ok:!0,agent:f?Gt(f):null});try{this.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:u,level:l},originatorClientId:e.clientId})}catch{}return}case`${j}workspace/agents/update`:{let d=String(a.agentType??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`agentType` required"));return}let u=await this.agentManager.loadSubagent(d);if(!u){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${d}" not found`));return}let l=256*1024,p={};if(typeof a.description=="string"){if(Buffer.byteLength(a.description,"utf8")>l){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`description` exceeds 256KB limit"));return}p.description=a.description}if(typeof a.systemPrompt=="string"){if(Buffer.byteLength(a.systemPrompt,"utf8")>l){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`systemPrompt` exceeds 256KB limit"));return}p.systemPrompt=a.systemPrompt}if(Array.isArray(a.tools)){if(a.tools.length>256){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`tools` exceeds 256-entry limit"));return}if(!a.tools.every(g=>typeof g=="string"&&g.length<=256)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`tools` elements must be strings \u2264256 chars"));return}p.tools=a.tools}if(typeof a.model=="string"&&(p.model=a.model),Object.keys(p).length===0){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"at least one updatable field required"));return}await this.agentManager.updateSubagent(d,p,u.level);let f=await this.agentManager.loadSubagent(d,u.level);this.replyConn(e,c,{ok:!0,agent:f?Gt(f):null});try{this.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:d,level:u.level},originatorClientId:e.clientId})}catch{}return}case`${j}workspace/agents/delete`:{let d=String(a.agentType??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`agentType` required"));return}let u=typeof a.scope=="string"?a.scope:void 0,l=u==="workspace"?"project":u==="global"?"user":void 0,p=await this.agentManager.loadSubagent(d,l);if(!p){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${d}" not found`));return}await this.agentManager.deleteSubagent(d,p.level),this.replyConn(e,c,{ok:!0});try{this.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:d,level:p.level},originatorClientId:e.clientId})}catch{}return}default:c!==void 0&&e.sendConn(W(c,$.METHOD_NOT_FOUND,`Unknown method: ${o}`));return}}catch(d){if(D(`matilda serve: /acp dispatch error (${ce(o)}): ${ce(je(d))}`),c!==void 0){let{code:u,message:l,data:p}=Hc(d),f=W(c,u,l,p),g=typeof a.sessionId=="string"?a.sessionId:void 0;g&&!rI.has(o)?this.replySession(e,g,c,void 0,f):e.sendConn(f)}}}async pumpSessionEvents(e,r,n){try{let s=this.bridge.subscribeEvents(r,{signal:n});for await(let i of s){if(n.aborted)break;e.touch(),this.translateEvent(e,r,i)}}catch(s){throw n.aborted||e.sendSession(r,On(`${j}notify`,{kind:"stream_error",error:je(s)})),s}}translateEvent(e,r,n){switch(n.type){case"session_update":{e.sendSession(r,On("session/update",n.data));return}case"permission_request":{let s=n.data,i=e.sessions.get(r);if(!i?.stream||i.stream.isClosed){this.cancelAbandonedPermission({sessionId:r,bridgeRequestId:s.requestId},i?.clientId)||D(`matilda serve: /acp permission cancel FAILED for ${ce(r)} (mediator stuck; no automatic recovery)`);return}let o=e.nextId();e.pending.set(o,{sessionId:r,bridgeRequestId:s.requestId,kind:"permission"}),i.stream.send(Lg(o,"session/request_permission",{sessionId:s.sessionId,toolCall:s.toolCall,options:s.options,_meta:{[$c]:{requestId:s.requestId}}}));return}case"stream_error":{e.sendSession(r,On(`${j}notify`,{...n.data,kind:"stream_error"}));return}default:e.sendSession(r,On(`${j}notify`,{kind:n.type,data:n.data}))}}resolveClientResponse(e,r,n){let s=r.id;if(typeof s!="string")return;let i=e.pending.get(s);if(!i)return;let o="error"in r?{outcome:{outcome:"cancelled"}}:r.result;try{this.bridge.respondToSessionPermission(i.sessionId,i.bridgeRequestId,o,this.sessionCtx(e,i.sessionId,n)),e.pending.delete(s)}catch(a){D(`matilda serve: /acp permission vote failed (${ce(i.sessionId)}): ${ce(je(a))}`),this.cancelAbandonedPermission(i,e.sessions.get(i.sessionId)?.clientId)&&e.pending.delete(s)}}async handlePrompt(e,r,n,s,i){let o=e.getOrCreateSession(r);o.promptAbort?.abort();let a=new AbortController;o.promptAbort=a;try{let c=await this.bridge.sendPrompt(r,s,a.signal,this.sessionCtx(e,r,i));n!==void 0&&this.replySession(e,r,n,c)}catch(c){let{code:d,message:u,data:l}=Hc(c);n!==void 0?this.replySession(e,r,n,void 0,W(n,d,u,l)):D(`matilda serve: /acp prompt error (${ce(r)}, notification): ${ce(je(c))}`)}finally{o.promptAbort===a&&(o.promptAbort=void 0)}}replyConn(e,r,n){r!==void 0&&e.sendConn(jc(r,n))}replySession(e,r,n,s,i){if(n===void 0)return;let o=i??jc(n,s);e.sessions.has(r)?e.sendSession(r,o):(D(`matilda serve: /acp replySession(${ce(r)}) binding gone mid-flight, reply routed to connection stream ${e.connectionId.slice(0,8)}`),e.sendConn(o))}};w();import{randomUUID as Wg}from"node:crypto";var sI=256,iI=64,Vc=class{constructor(e,r,n,s){this.onAbandonPending=n;this.onDetachSession=s;this.connectionId=e??Wg(),this.clientId=Wg(),this.fromLoopback=r}connectionId;connStream;connBuffer=[];sessions=new Map;ownedSessions=new Set;closingSessions=new Set;pending=new Map;clientId;fromLoopback;destroyed=!1;connGraceTimer;lastActiveMs=Date.now();idCounter=0;nextId(){return this.idCounter+=1,`_matilda_perm_${this.idCounter}`}touch(){this.lastActiveMs=Date.now()}ownSession(e){this.ownedSessions.add(e)}ownsSession(e){return this.ownedSessions.has(e)}getOrCreateSession(e){let r=this.sessions.get(e);return r||(r={sessionId:e,abort:new AbortController,buffer:[]},this.sessions.set(e,r)),r}getDiagnostic(){let e=new Set;this.connStream&&!this.connStream.isClosed&&e.add(this.connStream);let r=0,n=0;for(let o of this.sessions.values())n+=o.buffer.length,o.stream&&!o.stream.isClosed&&(r+=1,e.add(o.stream));let s=0,i=0;for(let o of e)o.kind==="sse"&&(s+=1),o.kind==="ws"&&(i+=1);return{connectionIdPrefix:this.connectionId.slice(0,8),fromLoopback:this.fromLoopback,destroyed:this.destroyed,lastActiveMs:this.lastActiveMs,ownedSessionCount:this.ownedSessions.size,sessionBindingCount:this.sessions.size,closingSessionCount:this.closingSessions.size,pendingClientRequests:this.pending.size,connectionStreamOpen:this.connStream!==void 0&&!this.connStream.isClosed,sessionStreams:r,sseStreams:s,wsStreams:i,bufferedConnectionFrames:this.connBuffer.length,bufferedSessionFrames:n}}sendConn(e){this.connStream&&!this.connStream.isClosed?this.connStream.send(e):Hg(this.connBuffer,e,`conn ${this.connectionId}`)}hasLiveSessionStream(){for(let e of this.sessions.values())if(e.stream&&!e.stream.isClosed)return!0;return!1}clearGraceTimer(){this.connGraceTimer&&(clearTimeout(this.connGraceTimer),this.connGraceTimer=void 0)}attachConnStream(e){this.clearGraceTimer(),this.connStream&&this.connStream!==e&&this.connStream.close(),this.connStream=e;for(let r of this.connBuffer.splice(0))e.send(r)}sendSession(e,r){let n=this.sessions.get(e);n&&(n.stream&&!n.stream.isClosed?n.stream.send(r):Hg(n.buffer,r,`session ${e}`))}attachSessionStream(e,r,n){let s=this.getOrCreateSession(e),i=s.stream;s.abort.abort(),s.abort=n,s.stream=r,i&&i!==r&&i!==this.connStream&&i.close();for(let o of s.buffer.splice(0))r.send(o);return s}closeSessionStream(e){let r=this.sessions.get(e);r&&(this.teardownBinding(r),this.sessions.delete(e),this.ownedSessions.delete(e))}destroy(){this.destroyed=!0,this.clearGraceTimer();for(let e of this.sessions.values())try{this.teardownBinding(e)}catch(r){D(`matilda serve: /acp teardownBinding(${ce(e.sessionId)}) failed during destroy: ${r instanceof Error?r.message:String(r)}`)}this.sessions.clear(),this.ownedSessions.clear(),this.pending.clear(),this.connStream?.close()}teardownBinding(e){e.abort.abort(),e.promptAbort?.abort(),e.stream&&e.stream!==this.connStream&&e.stream.close(),this.abandonPendingForSession(e.sessionId,e.clientId),this.onDetachSession?.(e.sessionId,e.clientId)}abandonPendingForSession(e,r){for(let[n,s]of this.pending){if(s.sessionId!==e)continue;this.pending.delete(n),(this.onAbandonPending?.(s,r)??!0)||D(`matilda serve: /acp MEDIATOR STUCK: abandonPendingForSession(${ce(e)}) cancel failed for ${ce(s.bridgeRequestId)}`)}}};function Hg(t,e,r="stream"){t.length>=sI&&(t.shift(),D(`matilda serve: /acp pre-attach buffer full (${r}), dropped oldest frame`)),t.push(e)}var Si=class{constructor(e,r,n=iI,s=30*6e4){this.onAbandonPending=e;this.onDetachSession=r;this.maxConnections=n;this.idleTtlMs=s;this.sweepTimer=setInterval(()=>this.sweep(),6e4),this.sweepTimer.unref()}byId=new Map;sweepTimer;create(e){if(this.maxConnections>0&&this.byId.size>=this.maxConnections)return;let r=new Vc(void 0,e,this.onAbandonPending,this.onDetachSession);return this.byId.set(r.connectionId,r),r}get(e){if(!e)return;let r=this.byId.get(e);return r?.touch(),r}delete(e){let r=this.byId.get(e);return r?(r.destroy(),this.byId.delete(e)):!1}get size(){return this.byId.size}get connectionCap(){return this.maxConnections}getSnapshot(){let e=[...this.byId.values()].map(r=>r.getDiagnostic());return{connectionCount:this.byId.size,connectionCap:this.maxConnections>0&&Number.isFinite(this.maxConnections)?this.maxConnections:null,connectionStreams:e.filter(r=>r.connectionStreamOpen).length,sessionStreams:bi(e,r=>r.sessionStreams),sseStreams:bi(e,r=>r.sseStreams),wsStreams:bi(e,r=>r.wsStreams),pendingClientRequests:bi(e,r=>r.pendingClientRequests),connections:e}}dispose(){clearInterval(this.sweepTimer);for(let e of[...this.byId.keys()])this.delete(e)}sweep(){let e=Date.now()-this.idleTtlMs;for(let[r,n]of this.byId)n.lastActiveMs>=e||(D(`matilda serve: /acp reaping idle connection ${r} (idle > ${Math.round(this.idleTtlMs/6e4)}m, ${n.sessions.size} session(s))`),this.delete(r))}};function bi(t,e){let r=0;for(let n of t)r+=e(n);return r}w();var Dn=class{constructor(e,r,n){this.res=e;this.onClose=r;this.onHeartbeat=n}kind="sse";writeChain=Promise.resolve();heartbeat;closed=!1;cleanupFn;open(){this.res.status(200),this.res.setHeader("Content-Type","text/event-stream"),this.res.setHeader("Cache-Control","no-cache, no-transform"),this.res.setHeader("Connection","keep-alive"),this.res.setHeader("X-Accel-Buffering","no"),this.res.flushHeaders(),this.writeRaw(`retry: 3000
69
+ ... (truncated)`:yt;try{await C.connection.extMethod(fe.sessionShellHistory,{sessionId:m,command:E,output:Gn,exitCode:_e})}catch(ft){_c(`shell history injection failed for session ${m}: ${ft instanceof Error?ft.message:String(ft)}`)}return{exitCode:_e,output:yt,aborted:Sr}}catch(Q){throw C.events.publish({type:"user_shell_result",data:{sessionId:m,exitCode:null,signal:null,aborted:!1,error:Q instanceof Error?Q.message:String(Q),_meta:{serverTimestamp:Date.now()}},...T?{originatorClientId:T}:{}}),Q}finally{_?.removeEventListener("abort",J)}},async getRewindSnapshots(m){return ye(m,ke.sessionRewindSnapshots)},async rewindSession(m,E,_){let I=h.get(m);if(!I)throw new ie(m);let C=Fe(I);if(!C||C.isDying)throw new ie(m);let T=re(I,_?.clientId),M;try{M=await Promise.race([Ce(I.connection.extMethod(fe.sessionRewind,{sessionId:m,promptId:E.promptId,rewindFiles:!0}),o,fe.sessionRewind),Ee(I)])}catch(Q){let oe=Q?.data;if(oe&&typeof oe=="object"&&"errorKind"in oe){let ue=oe.errorKind,_e=Q?.message??"Rewind failed";if(ue==="session_busy")throw new cn(m,_e);if(ue==="invalid_rewind_target")throw new dn(m,_e)}throw Q}let N=M.targetTurnIndex??0,z=M.filesChanged??[],J=M.filesFailed??[];try{I.events.publish({type:"session_rewound",data:{sessionId:m,promptId:E.promptId,targetTurnIndex:N,filesChanged:z,filesFailed:J},...T?{originatorClientId:T}:{}})}catch{}return{rewound:J.length===0,targetTurnIndex:N,filesChanged:z,filesFailed:J}},async manageMcpServer(m,E,_){let I=Oe();if(!I)throw new ie(`mcp:${m}`);let C=E==="authenticate"?IE:ag,T=await Promise.race([Ce(I.connection.extMethod(fe.workspaceMcpManage,{serverName:m,action:E,originatorClientId:_}),C,fe.workspaceMcpManage),Le(I)]);return nr({type:"mcp_server_changed",data:{serverName:T.serverName,action:T.action,originatorClientId:_},..._?{originatorClientId:_}:{}}),T},async generateWorkspaceAgent(m,E){let _=Oe();if(!_)throw new ie("agents:generate");return await Promise.race([Ce(_.connection.extMethod(fe.workspaceAgentGenerate,{description:m}),ag,fe.workspaceAgentGenerate),Le(_)])},async addRuntimeMcpServer(m,E,_){let I=Oe();if(!I)throw Object.assign(new Error(`No live ACP channel for runtime MCP add: ${m}`),{data:{errorKind:"acp_channel_unavailable"}});let C=await Promise.race([Ce(I.connection.extMethod(fe.workspaceMcpRuntimeAdd,{name:m,config:E,originatorClientId:_}),3e5,fe.workspaceMcpRuntimeAdd),Le(I)]);if(!(C.skipped===!0)){let M=C;nr({type:"mcp_server_added",data:{name:M.name,transport:M.transport,replaced:M.replaced,shadowedSettings:M.shadowedSettings,toolCount:M.toolCount,originatorClientId:M.originatorClientId},..._?{originatorClientId:_}:{}})}return C},async removeRuntimeMcpServer(m,E){let _=Oe();if(!_)throw Object.assign(new Error(`No live ACP channel for runtime MCP remove: ${m}`),{data:{errorKind:"acp_channel_unavailable"}});let I=await Promise.race([Ce(_.connection.extMethod(fe.workspaceMcpRuntimeRemove,{name:m,originatorClientId:E}),3e5,fe.workspaceMcpRuntimeRemove),Le(_)]);if(!(I.skipped===!0)){let T=I;nr({type:"mcp_server_removed",data:{name:T.name,wasShadowingSettings:T.wasShadowingSettings,originatorClientId:T.originatorClientId},...E?{originatorClientId:E}:{}})}return I},async killSession(m,E){let _=h.get(m);if(!_)return;if(E?.requireZeroAttaches&&_.attachCount>0){_.spawnOwnerWantedKill=!0;return}k.forgetSession(m),_.pendingPermissionIds.clear(),x===_&&(x=void 0),h.delete(m),v.metrics?.sessionLifecycle("die");let I=Fe(_);I||G(`matilda serve: killSession channelInfoForEntry returned undefined for session ${JSON.stringify(m)} \u2014 channel cleanup skipped (entry's channel already torn down)`),I&&I.channel===_.channel&&I.sessionIds.delete(m),await tn(_,I,"killSession"),I?.client.markSessionClosed(m);try{_.events.publish({type:"session_died",data:{sessionId:m,reason:"killed"}})}catch{}_.events.close(),I&&I.sessionIds.size===0&&I.pendingRestoreIds.size===0&&await Ze(I,`killSession "${m}"`)},async detachClient(m,E){let _=h.get(m);_&&(_.attachCount>0&&_.attachCount--,de(_,E),_.spawnOwnerWantedKill&&_.attachCount===0&&_.events.subscriberCount===0?await this.killSession(m).catch(()=>{}):_.clientIds.size===0&&_.events.subscriberCount===0&&!_.promptActive&&await zn(m,void 0,{reason:"last_client_detached"}).catch(I=>{G(`matilda serve: close-on-last-detach failed for ${JSON.stringify(m)}: ${I instanceof Error?I.stack??I.message:String(I)}`)}))},killAllSync(){S=!0,V(),Ue();let m=Array.from(be);x=void 0,h.clear();for(let E of m)try{E.channel.killSync()}catch{}},async shutdown(){S=!0,V(),Ue();let m=Array.from(h.values()),E=Array.from(be);for(let T of E)T.isDying=!0;for(let T of m)k.forgetSession(T.sessionId),T.pendingPermissionIds.clear();x=void 0,h.clear();for(let T of m){v.metrics?.sessionLifecycle("die");try{T.events.publish({type:"session_died",data:{sessionId:T.sessionId,reason:"daemon_shutdown"}})}catch{}T.events.close()}let _=Array.from(F.values()).map(T=>T.then(()=>{},()=>{})),I=Array.from(H.values()).map(T=>T.promise.then(()=>{},()=>{})),C=b?b.then(()=>{},()=>{}):Promise.resolve();await Promise.all([...E.map(T=>T.channel.kill().catch(()=>{})),..._,...I,C])},async preheat(){if(S)return;let m=await xe();Te()>0&&m.sessionIds.size===0&&m.pendingRestoreIds.size===0&&await Ze(m)}}}async function Ce(t,e,r){let n,s=new Promise((i,o)=>{n=setTimeout(()=>o(new Ki(r,e)),e)});try{return await Promise.race([t,s])}finally{n&&clearTimeout(n)}}var hg=gr;w();w();var OE="openid profile email model.completion",Ac=2048;function Rc(t){if(t.length<=Ac)return t;let e=t.length-Ac;return`${t.slice(0,Ac)}\u2026[+${e} bytes truncated]`}var li=class{providerId="matilda-oauth";client;constructor(e){this.client=e??new nu}async start(e){let{code_verifier:r,code_challenge:n}=Zd(),s;try{s=await this.client.requestDeviceAuthorization({scope:OE,code_challenge:n,code_challenge_method:"S256"},{signal:e.signal})}catch(i){let o=i instanceof Error?i.message:String(i);throw D(`[serve] matilda device-flow start failed (raw): ${Rc(o)}`),new vt("Matilda IdP device authorization request failed")}if(e.signal.aborted)throw new vt("device-flow start aborted");if(!eu(s)){let i=s;throw D(Rc(`[serve] matilda device-flow start error envelope (raw): error=${i?.error??"unknown"} description=${i?.error_description??"(none)"}`)),new vt("Matilda IdP rejected the device authorization request")}return{deviceCode:Ec(s.device_code),pkceVerifier:Ec(r),userCode:s.user_code,verificationUri:s.verification_uri,verificationUriComplete:s.verification_uri_complete,expiresIn:s.expires_in}}async poll(e,r){if(!e.pkceVerifier)return{kind:"error",errorKind:"invalid_grant",hint:"Matilda device-flow requires a PKCE verifier"};if(r.signal.aborted)return{kind:"pending"};let n;try{n=await this.client.pollDeviceToken({device_code:Ic(e.deviceCode),code_verifier:Ic(e.pkceVerifier)},{signal:r.signal})}catch(s){let i=s instanceof ji?DE(s.oauthError):"upstream_error";if(!r.signal.aborted){let a;if(s instanceof ji){let c=s.oauthError??"(missing)";a=`oauthError=${Gr(c)}`}else s instanceof Error?a=`${Gr(s.name)} (message ${s.message.length} bytes; raw suppressed to avoid echoing device_code/PKCE)`:a=`<non-Error throw: ${typeof s}>`;D(`[serve] matilda device-flow poll failed (errorKind=${i}): ${Rc(a)}`)}return{kind:"error",errorKind:i,hint:i==="upstream_error"?"unexpected response from identity provider":`Matilda IdP returned ${i}`}}if(tu(n)){let s=n,i={access_token:s.access_token,refresh_token:s.refresh_token??void 0,token_type:s.token_type,resource_url:s.resource_url,expiry_date:s.expires_in?Date.now()+s.expires_in*1e3:void 0},o=i.expiry_date,a=this.client;return{kind:"success",async persist(c){await su(i,{signal:c.signal});try{a.setCredentials(i)}catch{}return{expiresAt:o}}}}return ru(n)?n.slowDown?{kind:"slow_down"}:{kind:"pending"}:{kind:"error",errorKind:"upstream_error",hint:"unexpected response from identity provider"}}};function DE(t){switch(t){case"expired_token":return"expired_token";case"access_denied":return"access_denied";case"invalid_grant":return"invalid_grant";default:return"upstream_error"}}w();var FE="ACP writeTextFile",LE="ACP readTextFile";function mg(t,e){return{route:e,...t.sessionId?{sessionId:t.sessionId}:{}}}function pi(t){return{async writeText(e){let r=t.forRequest(mg(e,FE)),n=await r.resolve(e.path,"write");return await r.writeTextOverwrite(n,e.content),{}},async readText(e){let r=t.forRequest(mg(e,LE)),n=await r.resolve(e.path,"read"),s={};typeof e.line=="number"&&e.line>0&&(s.line=e.line),typeof e.limit=="number"&&e.limit>0&&(s.limit=e.limit);let{content:i}=await r.readText(n,s);return{content:i}}}}w();import{promises as HE}from"node:fs";w();import NE from"node:os";var gg=["OPENAI_API_KEY","ANTHROPIC_API_KEY","GEMINI_API_KEY","GOOGLE_API_KEY","MATILDA_API_KEY","OPENROUTER_API_KEY","MATILDA_SERVER_TOKEN"],vg=["OPENAI_BASE_URL","ANTHROPIC_BASE_URL","OPENAI_API_BASE","NODE_EXTRA_CA_CERTS","TZ","LANG","LC_ALL","TERM","MATILDA_CLI_ENTRY"],yg=["HTTP_PROXY","HTTPS_PROXY","NO_PROXY","ALL_PROXY"];function $E(t,e){return t[e]??t[e.toLowerCase()]}function BE(t,e){if(t==="NO_PROXY")return Qd(e);try{let n=new URL(e).host;if(n)return n}catch{}try{let n=new URL(`http://${e}`).host;if(n)return n}catch{}return(e.replace(/^[^@/?#]*@/,"").split(/[/?#]/)[0]??"")||"<unparseable>"}function Cc(t,e){let r={...process.env},n=[],s=Yd(),i=s==="bun"?process.versions.bun??process.versions.node:process.versions.node;n.push({kind:"runtime",name:s,status:"ok",value:i}),n.push({kind:"platform",name:process.platform,status:"ok",value:`${process.arch} (${NE.release()})`}),n.push({kind:"memory",name:"rss",status:"ok",value:Fu(process.memoryUsage().rss)});let o=r.SANDBOX;n.push({kind:"sandbox",name:"SANDBOX",status:o?"ok":"disabled",present:!!o,...o?{value:o}:{}});let a=r.SEATBELT_PROFILE;a&&n.push({kind:"sandbox",name:"SEATBELT_PROFILE",status:"ok",present:!0,value:a});for(let c of yg){let d=$E(r,c);d?n.push({kind:"proxy",name:c,status:"ok",present:!0,value:BE(c,d)}):n.push({kind:"proxy",name:c,status:"disabled",present:!1})}for(let c of[...gg,...vg]){let d=!!r[c];n.push({kind:"env_var",name:c,status:d?"ok":"disabled",present:d})}return{v:ot,workspaceCwd:t,initialized:!0,acpChannelLive:e,cells:n}}var qE=gg,jE=vg,WE=yg;var Pn=22;function Mn(){return{async getEnvStatus(t,e){return Cc(t,e)},async getDaemonPreflightCells(t){return UE(t)}}}async function UE(t){let s=[{kind:"node_version",run:()=>{try{let o=process.versions.node,a=Number.parseInt(o.split(".")[0]??"0",10);return Number.isFinite(a)&&a>=Pn?{kind:"node_version",status:"ok",locality:"daemon",detail:{version:o,required:`>=${Pn}`}}:{kind:"node_version",status:"error",errorKind:"missing_binary",error:`Node ${o} is below the required >=${Pn}.`,hint:`Upgrade Node to v${Pn} or newer.`,locality:"daemon",detail:{version:o,required:`>=${Pn}`}}}catch(o){return{kind:"node_version",status:"error",error:o instanceof Error?o.message:String(o),locality:"daemon"}}}},{kind:"cli_entry",run:()=>{let o=process.env.MATILDA_CLI_ENTRY||process.argv[1]||"";return o?{kind:"cli_entry",status:"ok",locality:"daemon",detail:{path:o,source:process.env.MATILDA_CLI_ENTRY?"MATILDA_CLI_ENTRY":"process.argv[1]"}}:{kind:"cli_entry",status:"error",errorKind:"missing_binary",error:"Cannot determine CLI entry path for spawning the ACP child.",hint:"Set MATILDA_CLI_ENTRY to the absolute path of the matilda entry script.",locality:"daemon"}}},{kind:"workspace_dir",run:async()=>{try{return(await HE.stat(t)).isDirectory()?{kind:"workspace_dir",status:"ok",locality:"daemon",detail:{path:t}}:{kind:"workspace_dir",status:"error",errorKind:"missing_file",error:`Bound workspace path is not a directory: ${t}`,locality:"daemon",detail:{path:t}}}catch(o){let a=Mt(o);return{kind:"workspace_dir",status:"error",error:o instanceof Error?o.message:String(o),...a?{errorKind:a}:{},locality:"daemon",detail:{path:t}}}}},{kind:"ripgrep",run:()=>Tc("ripgrep",async()=>await yu(!0)?{status:"ok"}:{status:"warning",hint:"Install ripgrep for faster grep tool execution."})},{kind:"git",run:()=>Tc("git",async()=>{let o=await Nu();return o&&o!=="unknown"?{status:"ok",detail:{version:o}}:{status:"warning",hint:"git not found on PATH."}})},{kind:"npm",run:()=>Tc("npm",async()=>{let o=await Lu();return o&&o!=="unknown"?{status:"ok",detail:{version:o}}:{status:"warning",hint:"npm not found on PATH."}})}];return(await Promise.allSettled(s.map(o=>Promise.resolve().then(o.run)))).map((o,a)=>{if(o.status==="fulfilled")return o.value;let c=o.reason,d=Mt(c);return{kind:s[a].kind,status:"error",locality:"daemon",error:c instanceof Error?c.message:String(c),...d?{errorKind:d}:{}}})}async function Tc(t,e){try{let r=await e();return{kind:t,status:r.status,locality:"daemon",...r.detail?{detail:r.detail}:{},...r.hint?{hint:r.hint}:{}}}catch(r){let n=Mt(r);return{kind:t,status:"error",error:r instanceof Error?r.message:String(r),locality:"daemon",...n?{errorKind:n}:{}}}}w();function qt(){let t=process.env.MATILDA_SERVE_DEBUG;return t?!["0","false","off","no"].includes(t.trim().toLowerCase()):!1}w();import{createHash as Ug,timingSafeEqual as oI}from"node:crypto";w();import eI from"node:path";w();var VE={path_outside_workspace:400,symlink_escape:400,path_not_found:404,binary_file:422,file_too_large:413,hash_mismatch:409,file_already_exists:409,text_not_found:422,ambiguous_text_match:422,untrusted_workspace:403,permission_denied:403,io_error:503,internal_error:500,parse_error:400},B=class extends Error{kind;status;hint;constructor(e,r,n){super(r,n?.cause===void 0?void 0:{cause:n.cause}),this.name="FsError",this.kind=e,this.status=n?.status??VE[e],this.hint=n?.hint}};function Pc(t){return t instanceof B}function wg(t,e="internal_error"){if(t instanceof B)return t;let r=t?.code,n=t instanceof Error?t.message:"unknown filesystem error";switch(r){case"ENOENT":return new B("path_not_found",n,{cause:t});case"EACCES":case"EPERM":return new B("permission_denied",n,{cause:t});case"ELOOP":return new B("symlink_escape",n,{cause:t,hint:"symlink chain forms a cycle or exceeds SYMLOOP_MAX"});case"EISDIR":return new B("parse_error",n,{cause:t,hint:"EISDIR \u2014 path is a directory but a regular file was expected"});case"ENOTDIR":return new B("parse_error",n,{cause:t,hint:"ENOTDIR \u2014 a path component is a regular file but a directory was expected"});case"ENOSPC":return new B("io_error",n,{cause:t,hint:"filesystem is full (df -h reporting 100%)"});case"EIO":return new B("io_error",n,{cause:t,hint:"underlying I/O error (failing disk or kernel-level fault)"});case"EBUSY":case"ETXTBSY":return new B("io_error",n,{cause:t,hint:"file is busy; another process holds an exclusive handle"});case"ENAMETOOLONG":return new B("io_error",n,{cause:t,hint:"path exceeds the OS PATH_MAX"});case"EMFILE":case"ENFILE":return new B("io_error",n,{cause:t,hint:"too many open files; daemon is at file-descriptor limit"});default:return new B(e,n,{cause:t})}}w();import{promises as Kr}from"node:fs";import*as Ke from"node:path";var zE=new Set(["write","stat"]);function Eg(t){if(process.platform==="win32"&&t.indexOf(":",2)!==-1||process.platform==="win32"&&/~\d+/.test(t)||t.startsWith("\\\\?\\")||t.startsWith("\\\\.\\")||t.startsWith("//?/")||t.startsWith("//./")||t.startsWith("\\\\")&&t.length>2&&t[2]!=="\\"||t.startsWith("//")&&t.length>2&&t[2]!=="/"||/(^|\/|\\)\.{3,}(\/|\\|$)/.test(t))return!0;for(let e of t.split(/[\\/]/))if(!(e===""||e==="."||e==="..")&&(/[.\s]+$/.test(e)||/(^|\.)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|$)/i.test(e)))return!0;return!1}var fi=40,bg=new Map;function GE(t){let e=bg.get(t);if(e!==void 0)return e;let r=Ye(t);return bg.set(t,r),r}async function Sg(t){let e=t,r=[];for(let n=0;n<fi;n++){let s=null;try{s=await Kr.stat(e)}catch(o){let a=o?.code;if(!(a==="ENOENT"||a==="ENOTDIR"))throw o}if(s){if(r.length>0&&!s.isDirectory())throw new B("parse_error",`path component is not a directory: ${t}`,{hint:"a non-directory file occupies a path segment"});return{ancestor:e,tail:r.join(Ke.sep)}}let i=Ke.dirname(e);if(i===e)throw new B("path_not_found",`no existing ancestor for ${t}`);r.unshift(Ke.basename(e)),e=i}throw new B("path_not_found",`path traversal exceeded ${fi} hops while finding ancestor`,{hint:"path is too deeply nested or filesystem is responding unexpectedly"})}async function Mc(t,e,r){if(typeof t!="string"||t.length===0)throw new B("parse_error","path must be a non-empty string");if(Eg(t))throw new B("path_outside_workspace",`path contains suspicious pattern: ${t}`,{hint:"paths with NTFS ADS, 8.3 short names, UNC prefixes, or trailing dots are rejected outright"});let n=GE(e),s=Ke.resolve(n,t);if(!xr(s,n))throw new B("path_outside_workspace",`path escapes workspace: ${t}`);let i;try{i=await Kr.realpath(s)}catch(o){let a=o?.code;if(a==="ENOENT"&&zE.has(r)){let c=null;try{let d=s,u=new Set,l=null,p=!1;for(let f=0;f<fi;f++){let g;try{g=await Kr.lstat(d)}catch(P){let q=P?.code;if(q==="ENOENT"||q==="ENOTDIR"){p=!0;break}throw P}if(!g.isSymbolicLink()){p=!0;break}let v=typeof g.ino=="bigint"?g.ino:BigInt(g.ino);if(v!==0n&&u.has(v))throw new B("symlink_escape",`symlink cycle detected at ${d}`,{hint:"symlink loops back onto a previously visited inode"});v!==0n&&u.add(v);let x=await Kr.readlink(d),O=Ke.isAbsolute(x)?x:Ke.resolve(Ke.dirname(d),x);l===null&&(l=x),d=O}if(!p)throw new B("symlink_escape",`symlink chain exceeded ${fi} hops for ${t}`,{hint:"symlink chain is too long or contains a cycle"});if(l!==null){let{ancestor:f,tail:g}=await Sg(d),v=await Kr.realpath(f),x=g?Ke.join(v,g):v;if(!xr(x,n))throw new B("symlink_escape",`dangling symlink target escapes workspace: ${t}`,{hint:"symlink chain leaves the workspace; enable MATILDA_AUDIT_RAW_PATHS for the resolved target"});c=x}}catch(d){if(d instanceof B||d?.code!=="ENOENT")throw d}if(c!==null)i=c;else{let{ancestor:d,tail:u}=await Sg(s),l=await Kr.realpath(d);i=u?Ke.join(l,u):l}}else throw a==="ENOENT"?new B("path_not_found",`path does not exist: ${t}`,{cause:o}):a==="ELOOP"?new B("symlink_escape",`symlink loop or chain too long for ${t}`,{cause:o,hint:"a symlink in the path forms a cycle or exceeds SYMLOOP_MAX"}):a==="EACCES"?new B("permission_denied",`permission denied resolving ${t}`,{cause:o}):o}if(!xr(i,n)){let o=i!==s?"symlink_escape":"path_outside_workspace";throw new B(o,o==="symlink_escape"?`symlink resolves outside workspace: ${t}`:`path escapes workspace: ${t}`)}return i}w();import{promises as xg}from"node:fs";import*as Oc from"node:path";var Ig=1024*1024;function _g(t,e){t.get("/workspace/memory",async(r,n)=>{try{let s=await Dc(e.boundWorkspace);n.status(200).json(s)}catch(s){D(`matilda serve: GET /workspace/memory failed: ${s instanceof Error?s.stack??s.message:String(s)}`),n.status(500).json({error:"Failed to discover workspace memory",code:"memory_discovery_failed"})}}),t.post("/workspace/memory",e.mutate({strict:!0}),async(r,n)=>{let s=e.safeBody(r),i=s.scope;if(i!=="workspace"&&i!=="global"){n.status(400).json({error:'`scope` must be "workspace" or "global"',code:"invalid_scope"});return}let o=s.mode;if(o!==void 0&&o!=="append"&&o!=="replace"){n.status(400).json({error:'`mode` must be "append", "replace", or omitted',code:"invalid_mode"});return}let a=o==="replace"?"replace":"append",c=s.content;if(typeof c!="string"){n.status(400).json({error:"`content` must be a string",code:"invalid_content"});return}if(Buffer.byteLength(c,"utf8")>Ig){n.status(400).json({error:`\`content\` exceeds the ${Ig}-byte limit`,code:"content_too_large"});return}let d=e.parseClientId(r,n);if(d===null)return;let u;if(d!==void 0){if(!e.bridge.knownClientIds().has(d)){n.status(400).json({error:`Client id "${d}" is not registered for this workspace`,code:"invalid_client_id",clientId:d});return}u=d}try{let l=await ts({scope:i,mode:a,content:c,projectRoot:e.boundWorkspace}),p={ok:!0,filePath:l.filePath,bytesWritten:l.bytesWritten,mode:a,changed:l.changed};l.changed&&e.bridge.publishWorkspaceEvent({type:"memory_changed",data:{scope:i,filePath:l.filePath,mode:a,bytesWritten:l.bytesWritten},...u?{originatorClientId:u}:{}}),n.status(200).json(p)}catch(l){if(l instanceof es){D(`matilda serve: POST /workspace/memory timeout \u2014 file lock at ${l.filePath} did not acquire within ${l.timeoutMs}ms (stalled FS / OneDrive / NFS)`);let g=qt();n.status(500).json({error:g?l.message:"Workspace memory write timed out waiting for the per-file lock. Retry or restart the daemon.",code:"memory_write_timeout",scope:i,mode:a,timeoutMs:l.timeoutMs,...g?{filePath:l.filePath}:{}});return}if(l instanceof rs){D(`matilda serve: POST /workspace/memory refused \u2014 existing file ${l.filePath} is ${l.bytes} bytes (cap ${l.limit})`);let g=qt();n.status(413).json({error:g?l.message:"Existing memory file exceeds the safe-append cap. Trim the file or POST with mode=replace.",code:"memory_file_too_large",scope:i,mode:a,...g?{filePath:l.filePath}:{},bytes:l.bytes,limit:l.limit});return}D(`matilda serve: POST /workspace/memory failed (scope=${i} mode=${a}): ${l instanceof Error?l.stack??l.message:String(l)}`);let p=l&&typeof l=="object"&&"code"in l?l.code:void 0,f=qt();n.status(500).json({error:"Failed to write workspace memory",code:"file_error",scope:i,mode:a,...typeof p=="string"?{osCode:p}:{},...f?{errorMessage:l instanceof Error?l.message:String(l)}:{}})}})}async function Dc(t){let e=new Set(Cd()),r=[],n=[],s=await KE(t,e,n);r.push(...s);let i=Xn.getGlobalMatildaDir();for(let c of e){let d=Oc.join(i,c);try{let u=await xg.stat(d);u.isFile()&&r.push({absolutePath:d,scope:"global",bytes:u.size})}catch(u){kg(u)||n.push({kind:"memory_file",status:"error",error:u instanceof Error?u.message:String(u),errorKind:"stat_failed",hint:d})}}if(r.length===0&&n.length===0)return Ou(t);let o=r.reduce((c,d)=>c+d.bytes,0),a={v:ot,workspaceCwd:t,initialized:!0,files:r.map(c=>({kind:"memory_file",path:c.absolutePath,scope:c.scope,bytes:c.bytes})),totalBytes:o,fileCount:r.length,ruleCount:0};return n.length>0&&(a.errors=n),a}async function KE(t,e,r){let n=[];for(let s of e){let i=Oc.join(t,s);try{let o=await xg.stat(i);o.isFile()&&n.push({absolutePath:i,scope:"workspace",bytes:o.size})}catch(o){kg(o)||r.push({kind:"memory_file",status:"error",error:o instanceof Error?o.message:String(o),errorKind:"stat_failed",hint:i})}}return n}function kg(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}w();import{promises as JE}from"node:fs";w();var Og=/^[\p{L}\p{N}_-]+$/u,Lc=64,Ag=2,mi=256*1024,gi=256*1024,Rg=256,Cg=256;function Dg(t,e){let r=Nc(e.boundWorkspace);t.get("/workspace/agents",async(n,s)=>{try{let i=await r.listSubagents({force:!0}),o={v:ot,workspaceCwd:e.boundWorkspace,agents:i.map(yi)};s.status(200).json(o)}catch(i){D(`matilda serve: GET /workspace/agents failed: ${i instanceof Error?i.stack??i.message:String(i)}`),s.status(500).json({error:"Failed to list workspace agents",code:"agent_list_failed"})}}),t.post("/workspace/agents",e.mutate({strict:!0}),async(n,s)=>{let i=e.safeBody(n),o=hi(e,n,s);if(o===null)return;let a=o,c=i.scope;if(c!=="workspace"&&c!=="global"){s.status(400).json({error:'`scope` must be "workspace" or "global"',code:"invalid_scope"});return}let d=c==="workspace"?"project":"user",u=XE(i,d,s);if(!u)return;if(await r.loadSubagent(u.name,d)){s.status(409).json({error:`Subagent "${u.name}" already exists at ${d} level`,code:"agent_already_exists",name:u.name,level:d});return}try{await r.createSubagent(u,{level:d})}catch(f){if(f instanceof Ar){if(f.code===Ve.ALREADY_EXISTS){s.status(409).json({error:f.message,code:"agent_already_exists",name:f.subagentName??u.name});return}if(f.code===Ve.VALIDATION_ERROR||f.code===Ve.INVALID_CONFIG||f.code===Ve.INVALID_NAME||f.code===Ve.TOOL_NOT_FOUND){s.status(422).json({error:f.message,code:"invalid_config",name:f.subagentName??u.name});return}if(f.code===Ve.FILE_ERROR){let g=qt();s.status(500).json({error:g?f.message:"Failed to write workspace agent file",code:"file_error",name:f.subagentName??u.name});return}}D(`matilda serve: POST /workspace/agents failed: ${f instanceof Error?f.stack??f.message:String(f)}`),s.status(500).json({error:"Failed to create workspace agent",code:"agent_create_failed"});return}let p=await r.loadSubagent(u.name,d);if(!p){D(`matilda serve: agent_create_reload_failed (name=${vr(u.name)} level=${d}) \u2014 file likely persisted on disk; check \`GET /workspace/agents\` for a phantom entry`),s.status(500).json({error:"Agent creation succeeded but reload failed",code:"agent_create_reload_failed",name:u.name,level:d});return}e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:u.name,level:d},...a?{originatorClientId:a}:{}}),s.status(201).json({ok:!0,agent:Gt(p)})}),t.post("/workspace/agents/generate",e.mutate({strict:!0}),async(n,s)=>{let i=e.safeBody(n),o=hi(e,n,s);if(o===null)return;let a=o,c=i.description;if(typeof c!="string"||c.trim().length===0){s.status(400).json({error:"`description` must be a non-empty string",code:"invalid_description"});return}if(Buffer.byteLength(c,"utf8")>4096){s.status(400).json({error:"`description` exceeds the 4096-byte limit",code:"invalid_description"});return}try{let d=await e.bridge.generateWorkspaceAgent(c.trim(),a);s.status(200).json(d)}catch(d){D(`matilda serve: POST /workspace/agents/generate failed: ${d instanceof Error?d.stack??d.message:String(d)}`),s.status(500).json({error:"Failed to generate workspace agent",code:"agent_generate_failed"})}}),t.get("/workspace/agents/:agentType",async(n,s)=>{let i=Fc(n,s);if(i!==null)try{let o=await r.loadSubagent(i);if(!o){s.status(404).json({error:`Subagent "${i}" not found`,code:"agent_not_found",name:i});return}s.status(200).json(Gt(o))}catch(o){D(`matilda serve: GET /workspace/agents/${vr(i)} failed: ${o instanceof Error?o.stack??o.message:String(o)}`),s.status(500).json({error:"Failed to read workspace agent",code:"agent_read_failed"})}}),t.post("/workspace/agents/:agentType",e.mutate({strict:!0}),async(n,s)=>{let i=Fc(n,s);if(i===null)return;let o=hi(e,n,s);if(o===null)return;let a=o,c=e.safeBody(n),d=YE(c,s);if(!d)return;let u=Tg(n,s);if(u===null)return;let l=await r.loadSubagent(i,u);if(!l){s.status(404).json({error:`Subagent "${i}" not found`,code:"agent_not_found",name:i});return}if(Pg(l,i,s))return;if(Object.keys(d).length===0){s.status(400).json({error:"`POST /workspace/agents/:agentType` requires at least one updatable field in the body",code:"invalid_config",name:i});return}if(QE(l,d)){s.status(200).json({ok:!0,agent:Gt(l),changed:!1});return}try{await r.updateSubagent(i,d,l.level)}catch(g){if(g instanceof Ar){if(g.code===Ve.NOT_FOUND){s.status(404).json({error:g.message,code:"agent_not_found",name:g.subagentName??i});return}if(g.code===Ve.INVALID_CONFIG){s.status(403).json({error:g.message,code:"agent_readonly",name:g.subagentName??i});return}if(g.code===Ve.VALIDATION_ERROR||g.code===Ve.INVALID_NAME||g.code===Ve.TOOL_NOT_FOUND){s.status(422).json({error:g.message,code:"invalid_config",name:g.subagentName??i});return}if(g.code===Ve.FILE_ERROR){let v=qt();s.status(500).json({error:v?g.message:"Failed to write workspace agent file",code:"file_error",name:g.subagentName??i});return}}D(`matilda serve: POST /workspace/agents/${vr(i)} failed: ${g instanceof Error?g.stack??g.message:String(g)}`),s.status(500).json({error:"Failed to update workspace agent",code:"agent_update_failed"});return}let p=await r.loadSubagent(i,l.level);if(!p){D(`matilda serve: agent_update_reload_failed (name=${vr(i)} level=${l.level}) \u2014 disk write completed; check \`GET /workspace/agents/${vr(i)}\` for the new state`),s.status(500).json({error:"Agent update succeeded but reload failed",code:"agent_update_reload_failed",name:i,level:l.level});return}let f=l.level==="project"?"project":"user";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:l.name,level:f},...a?{originatorClientId:a}:{}}),s.status(200).json({ok:!0,agent:Gt(p),changed:!0})}),t.delete("/workspace/agents/:agentType",e.mutate({strict:!0}),async(n,s)=>{let i=Fc(n,s);if(i===null)return;let o=hi(e,n,s);if(o===null)return;let a=o,c=Tg(n,s);if(c===null)return;let d=c?[c]:["project","user"],u=[];for(let f of d){let g=await r.loadSubagent(i,f);g&&u.push(g)}for(let f of u)if(Pg(f,i,s))return;try{await r.deleteSubagent(i,c)}catch(f){if(f instanceof Ar){if(f.code===Ve.NOT_FOUND){s.status(404).json({error:f.message,code:"agent_not_found",name:f.subagentName??i});return}if(f.code===Ve.INVALID_CONFIG){s.status(403).json({error:f.message,code:"agent_readonly",name:f.subagentName??i});return}}D(`matilda serve: DELETE /workspace/agents/${vr(i)} failed: ${f instanceof Error?f.stack??f.message:String(f)}`),s.status(500).json({error:"Failed to delete workspace agent",code:"agent_delete_failed"});return}let l=[],p=[];for(let f of u){if(!f.filePath){l.push(f);continue}try{await JE.access(f.filePath),p.push(f)}catch{l.push(f)}}if(p.length>0){D(`matilda serve: DELETE /workspace/agents/${vr(i)} partial \u2014 removed=${l.map(f=>f.level).join(",")||"none"} remaining=${p.map(f=>`${f.level}:${f.filePath}`).join(",")}`);for(let f of l){let g=f.level==="project"?"project":"user";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:f.name,level:g},...a?{originatorClientId:a}:{}})}s.status(500).json({error:`Failed to delete every level of subagent "${i}" \u2014 ${p.length} level(s) still have their file on disk`,code:"agent_delete_partial",name:i,removedLevels:l.map(f=>f.level),remainingLevels:p.map(f=>f.level)});return}if(u.length===0){let f=c==="user"?"user":"project";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:i,level:f},...a?{originatorClientId:a}:{}})}else for(let f of l){let g=f.level==="project"?"project":"user";e.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:f.name,level:g},...a?{originatorClientId:a}:{}})}s.status(204).end()})}function vr(t){return JSON.stringify(String(t)).slice(0,82)}function Fc(t,e){let r=t.params.agentType;return!r||r.length===0?(e.status(400).json({error:"`agentType` path parameter is required",code:"invalid_agent_type"}),null):r.length>Lc||!Og.test(r)?(e.status(400).json({error:"`agentType` must contain only letters, numbers, hyphens, or underscores (max 64 chars)",code:"invalid_agent_type",agentType:r}),null):r}function Tg(t,e){let r=t.query.scope;if(r!==void 0)return typeof r!="string"?(e.status(400).json({error:'`scope` query must be a single "workspace" or "global" value',code:"invalid_scope"}),null):r!=="workspace"&&r!=="global"?(e.status(400).json({error:'`scope` query must be "workspace" or "global"',code:"invalid_scope"}),null):r==="workspace"?"project":"user"}function Pg(t,e,r){return t.isBuiltin||t.level==="builtin"||t.level==="extension"||t.level==="session"?(r.status(403).json({error:`Cannot modify ${t.level}-level subagent "${e}"`,code:"agent_readonly",name:t.name,level:t.level}),!0):!1}function hi(t,e,r){let n=t.parseClientId(e,r);if(n===null)return null;if(n!==void 0)return t.bridge.knownClientIds().has(n)?n:(r.status(400).json({error:`Client id "${n}" is not registered for this workspace`,code:"invalid_client_id",clientId:n}),null)}function XE(t,e,r){let n=t.name;if(typeof n!="string"||n.trim().length===0){r.status(422).json({error:"`name` is required and must be a non-empty string",code:"invalid_config"});return}let s=n.trim();if(s.length<Ag||s.length>Lc||!Og.test(s)){r.status(422).json({error:`\`name\` must be ${Ag}-${Lc} characters of letters, numbers, hyphens, or underscores`,code:"invalid_config",name:s});return}if(Qn.isBuiltinAgent(s)){r.status(422).json({error:`"${s}" shadows a built-in subagent and cannot be used as a project- or user-level agent name. Choose a different name.`,code:"invalid_config",name:s});return}let i=t.description;if(typeof i!="string"||i.trim().length===0){r.status(422).json({error:"`description` is required and must be a non-empty string",code:"invalid_config"});return}if(Buffer.byteLength(i,"utf8")>mi){r.status(422).json({error:`\`description\` exceeds the ${mi}-byte limit`,code:"invalid_config"});return}let o=t.systemPrompt;if(typeof o!="string"||o.trim().length===0){r.status(422).json({error:"`systemPrompt` is required and must be a non-empty string (whitespace only is rejected)",code:"invalid_config"});return}if(Buffer.byteLength(o,"utf8")>gi){r.status(422).json({error:`\`systemPrompt\` exceeds the ${gi}-byte limit`,code:"invalid_config"});return}let a=vi(t.tools,"tools",r);if(a===null)return;let c=vi(t.disallowedTools,"disallowedTools",r);if(c===null)return;let d={name:s,description:i,systemPrompt:o,level:e};if(a!==void 0&&(d.tools=a),c!==void 0&&(d.disallowedTools=c),zt(t,"model","string",r)||(typeof t.model=="string"&&(d.model=t.model),zt(t,"color","string",r))||(typeof t.color=="string"&&(d.color=t.color),zt(t,"approvalMode","string",r)))return;if(typeof t.approvalMode=="string"){if(!tt.includes(t.approvalMode)){r.status(422).json({error:`\`approvalMode\` must be one of ${JSON.stringify(tt)}`,code:"invalid_config"});return}d.approvalMode=t.approvalMode}if(zt(t,"background","boolean",r))return;typeof t.background=="boolean"&&(d.background=t.background);let u=t.runConfig;if(u!==void 0){let l=Fg(u,r);if(l===null)return;d.runConfig=l}return d}function YE(t,e){let r={};if("description"in t){let n=t.description;if(typeof n!="string"||n.trim().length===0){e.status(422).json({error:"`description` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return}if(Buffer.byteLength(n,"utf8")>mi){e.status(422).json({error:`\`description\` exceeds the ${mi}-byte limit`,code:"invalid_config"});return}r.description=n}if("systemPrompt"in t){let n=t.systemPrompt;if(typeof n!="string"||n.trim().length===0){e.status(422).json({error:"`systemPrompt` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return}if(Buffer.byteLength(n,"utf8")>gi){e.status(422).json({error:`\`systemPrompt\` exceeds the ${gi}-byte limit`,code:"invalid_config"});return}r.systemPrompt=n}if("tools"in t){let n=vi(t.tools,"tools",e);if(n===null)return;n!==void 0&&(r.tools=n)}if("disallowedTools"in t){let n=vi(t.disallowedTools,"disallowedTools",e);if(n===null)return;n!==void 0&&(r.disallowedTools=n)}if(!zt(t,"model","string",e)&&(typeof t.model=="string"&&(r.model=t.model),!zt(t,"color","string",e)&&(typeof t.color=="string"&&(r.color=t.color),!zt(t,"approvalMode","string",e)))){if(typeof t.approvalMode=="string"){if(!tt.includes(t.approvalMode)){e.status(422).json({error:`\`approvalMode\` must be one of ${JSON.stringify(tt)}`,code:"invalid_config"});return}r.approvalMode=t.approvalMode}if(!zt(t,"background","boolean",e)){if(typeof t.background=="boolean"&&(r.background=t.background),"runConfig"in t){let n=Fg(t.runConfig,e);if(n===null)return;r.runConfig=n}return r}}}function vi(t,e,r){if(t!==void 0)return!Array.isArray(t)||t.some(n=>typeof n!="string")?(r.status(422).json({error:`\`${e}\` must be an array of strings when provided`,code:"invalid_config"}),null):t.length>Rg?(r.status(422).json({error:`\`${e}\` exceeds the ${Rg}-entry limit`,code:"invalid_config"}),null):t.some(n=>n.length>Cg)?(r.status(422).json({error:`\`${e}\` entries must be at most ${Cg} characters`,code:"invalid_config"}),null):t}function zt(t,e,r,n){return!(e in t)||typeof t[e]===r?!1:(n.status(422).json({error:`\`${e}\` must be a ${r} when provided`,code:"invalid_config"}),!0)}function QE(t,e){if(e.description!==void 0&&e.description!==t.description||e.systemPrompt!==void 0&&e.systemPrompt!==t.systemPrompt||e.tools!==void 0&&!Mg(e.tools,t.tools)||e.disallowedTools!==void 0&&!Mg(e.disallowedTools,t.disallowedTools)||e.model!==void 0&&e.model!==t.model||e.color!==void 0&&e.color!==t.color||e.approvalMode!==void 0&&e.approvalMode!==t.approvalMode||e.background!==void 0&&e.background!==t.background)return!1;if(e.runConfig!==void 0){let r=t.runConfig??{},n=e.runConfig;if("max_time_minutes"in n&&n.max_time_minutes!==r.max_time_minutes||"max_turns"in n&&n.max_turns!==r.max_turns)return!1}return!0}function Mg(t,e){if(t===e)return!0;if(!t||!e||t.length!==e.length)return!1;for(let r=0;r<t.length;r++)if(t[r]!==e[r])return!1;return!0}function Fg(t,e){if(typeof t!="object"||t===null||Array.isArray(t))return e.status(422).json({error:"`runConfig` must be an object when provided",code:"invalid_config"}),null;let r=t,n={};if("max_time_minutes"in r){let s=r.max_time_minutes;if(typeof s!="number"||!Number.isFinite(s)||s<=0)return e.status(422).json({error:"`runConfig.max_time_minutes` must be a positive finite number when provided",code:"invalid_config"}),null;n.max_time_minutes=s}if("max_turns"in r){let s=r.max_turns;if(typeof s!="number"||!Number.isFinite(s)||s<=0||!Number.isInteger(s))return e.status(422).json({error:"`runConfig.max_turns` must be a positive integer when provided",code:"invalid_config"}),null;n.max_turns=s}return n}function yi(t){let e={kind:"agent",name:t.name,description:t.description,level:t.level,isBuiltin:t.isBuiltin===!0||t.level==="builtin",hasTools:Array.isArray(t.tools)&&t.tools.length>0};return t.model&&(e.model=t.model),t.color&&(e.color=t.color),t.background!==void 0&&(e.background=t.background),t.approvalMode&&(e.approvalMode=t.approvalMode),t.extensionName&&(e.extensionName=t.extensionName),t.filePath&&(e.filePath=t.filePath),e}function Gt(t){let e={...yi(t),systemPrompt:t.systemPrompt};if(t.tools&&(e.tools=[...t.tools]),t.disallowedTools&&(e.disallowedTools=[...t.disallowedTools]),t.runConfig){let r={};typeof t.runConfig.max_time_minutes=="number"&&(r.max_time_minutes=t.runConfig.max_time_minutes),typeof t.runConfig.max_turns=="number"&&(r.max_turns=t.runConfig.max_turns),e.runConfig=r}return e}function Nc(t){let e={getSdkMode:()=>!1,getProjectRoot:()=>t,getActiveExtensions:()=>[]},r=new Proxy(e,{get(n,s){if(s in n)return n[s];if(s!=="then")throw new Error(`matilda serve workspace agents: SubagentManager touched Config.${String(s)} which the daemon stub does not implement. Add it to createDaemonSubagentManager and audit safety.`)},has(n,s){if(s in n)return!0;if(s==="then")return!1;throw new Error(`matilda serve workspace agents: SubagentManager probed Config.${String(s)} via 'in' check; the daemon stub does not implement it. Add it to createDaemonSubagentManager and audit safety.`)}});return new wu(r)}w();var j="_matilda/",$c="matilda",$={PARSE_ERROR:-32700,INVALID_REQUEST:-32600,METHOD_NOT_FOUND:-32601,INVALID_PARAMS:-32602,INTERNAL_ERROR:-32603};function yr(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function Qe(t){return yr(t)&&t.jsonrpc==="2.0"&&typeof t.method=="string"&&"id"in t&&t.id!==null&&(typeof t.id=="number"||typeof t.id=="string")}function Bc(t){return yr(t)&&t.jsonrpc==="2.0"&&typeof t.method=="string"&&!("id"in t)}function qc(t){return yr(t)&&t.jsonrpc==="2.0"&&!("method"in t)&&"id"in t&&"result"in t!="error"in t}var ZE=new RegExp(String.raw`[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]`,"g");function ce(t){return t.replace(ZE," ")}function jc(t,e){return{jsonrpc:"2.0",id:t,result:e}}function W(t,e,r,n){return{jsonrpc:"2.0",id:t,error:{code:e,message:r,...n!==void 0?{data:n}:{}}}}function On(t,e){return{jsonrpc:"2.0",method:t,params:e}}function Lg(t,e,r){return{jsonrpc:"2.0",id:t,method:e,params:r}}function Wc(t){return Array.isArray(t)?{ok:!1,error:W(null,$.INVALID_REQUEST,"JSON-RPC batch not supported")}:Qe(t)||Bc(t)||qc(t)?{ok:!0,message:t}:{ok:!1,error:W(null,$.INVALID_REQUEST,"Malformed JSON-RPC message")}}function je(t){return t instanceof Error?t.message:String(t)}var qg=`${j}session/shell`,jg=[`${j}session/heartbeat`,`${j}session/context`,`${j}session/supported_commands`,`${j}session/update_metadata`,`${j}workspace/mcp`,`${j}workspace/skills`,`${j}workspace/providers`,`${j}workspace/env`,`${j}workspace/preflight`,`${j}workspace/init`,`${j}workspace/set_tool_enabled`,`${j}workspace/restart_mcp_server`,`${j}session/recap`,`${j}session/btw`,qg,`${j}session/detach`,`${j}session/context_usage`,`${j}session/tasks`,`${j}workspace/memory`,`${j}workspace/memory/write`,`${j}file/read`,`${j}file/read_bytes`,`${j}file/stat`,`${j}file/list`,`${j}file/glob`,`${j}file/write`,`${j}file/edit`,`${j}workspace/auth/status`,`${j}workspace/auth/device_flow/start`,`${j}workspace/auth/device_flow/get`,`${j}workspace/auth/device_flow/cancel`,`${j}workspace/tools`,`${j}workspace/mcp/tools`,`${j}workspace/mcp/servers/add`,`${j}workspace/mcp/servers/remove`,`${j}sessions/delete`,`${j}workspace/agents/list`,`${j}workspace/agents/get`,`${j}workspace/agents/create`,`${j}workspace/agents/update`,`${j}workspace/agents/delete`];function tI(t){return jg.filter(e=>t||e!==qg)}var rI=new Set(["authenticate","session/new","session/load","session/resume","session/list","session/close","session/fork",...jg]),Kt=256,Jt=class extends Error{};function Ng(t,e){if(!("cwd"in t)||t.cwd===void 0)return e;let r=t.cwd;if(typeof r!="string")throw new Jt("`cwd` must be a string absolute path when provided");if(r.length>wt)throw new Jt(`\`cwd\` exceeds the ${wt}-character limit`);if(!eI.isAbsolute(r))throw new Jt("`cwd` must be an absolute path when provided");return r}function nI(t){let e=t.prompt;if(!Array.isArray(e)||e.length===0)throw new Jt("`prompt` is required and must be a non-empty array of content blocks");if(!e.every(r=>typeof r=="object"&&r!==null&&!Array.isArray(r)))throw new Jt("each `prompt` element must be an object")}function Hc(t){if(t instanceof Jt||t instanceof Jr)return{code:$.INVALID_PARAMS,message:t.message};if(t instanceof Ar)return{code:$.INVALID_PARAMS,message:t.message};if(t instanceof B)return{code:$.INVALID_PARAMS,message:t.message,data:{errorKind:t.kind,hint:t.hint}};if(t instanceof rs)return{code:$.INVALID_PARAMS,message:t.message,data:{errorKind:"memory_file_too_large"}};if(t instanceof es)return{code:$.INTERNAL_ERROR,message:t.message,data:{errorKind:"memory_write_timeout"}};if(t instanceof mr)return{code:$.INTERNAL_ERROR,message:t.message,data:{errorKind:"too_many_active_flows"}};if(t instanceof hr)return{code:$.INVALID_PARAMS,message:t.message,data:{errorKind:"unsupported_provider"}};if(t instanceof vt)return{code:$.INTERNAL_ERROR,message:t.message,data:{errorKind:"upstream_error"}};if(t instanceof bt)return{code:$.INVALID_PARAMS,message:je(t),data:{errorKind:"session_shell_disabled"}};if(t instanceof St)return{code:$.INVALID_PARAMS,message:je(t),data:{errorKind:"client_id_required"}};switch(t instanceof Error?t.name:""){case"SessionNotFoundError":case"InvalidSessionScopeError":case"WorkspaceMismatchError":case"InvalidClientIdError":return{code:$.INVALID_PARAMS,message:je(t)};case"SessionLimitExceededError":return{code:$.INTERNAL_ERROR,message:je(t)};case"PromptQueueFullError":{let r=t;return{code:$.INTERNAL_ERROR,message:je(t),data:{errorKind:"prompt_queue_full",sessionId:r.sessionId,limit:r.limit,pendingCount:r.pendingCount}}}default:return{code:$.INTERNAL_ERROR,message:"Internal error",data:{errorKind:"internal"}}}}function $g(t,e){let{code:r,message:n,data:s}=Hc(e);return W(t,r,n,s)}var Bg=1,wi=class{constructor(e,r,n,s,i,o=!1){this.bridge=e;this.boundWorkspace=r;this.workspace=n;this.fsFactory=s;this.deviceFlowRegistry=i;this.sessionShellCommandEnabled=o;this.agentManager=Nc(r)}agentManager;killOrphanSession(e){this.bridge.killSession(e,{requireZeroAttaches:!0}).catch(r=>D(`matilda serve: /acp orphan killSession(${ce(e)}) failed: ${ce(je(r))}`))}wsCtx(e,r){return{originatorClientId:e.clientId,route:`ACP ${r}`,workspaceCwd:this.boundWorkspace}}sessionCtx(e,r,n){let s=e.sessions.get(r)?.clientId;if(!s)throw new Error(`no bridge-stamped clientId for session ${r} (ownership invariant violated)`);return{clientId:s,fromLoopback:n}}async configOptionsFor(e){try{let n=(await this.bridge.getSessionContextStatus(e))?.state?.configOptions;return Array.isArray(n)?n:void 0}catch(r){D(`matilda serve: /acp configOptionsFor(${ce(e)}) failed: ${ce(je(r))}`);return}}extractModelState(e){if(!e)return;let r=e.find(i=>typeof i=="object"&&i!==null&&i.category==="model");if(!r)return;let n=String(r.currentValue??""),s=Array.isArray(r.options)?r.options:[];return{currentModelId:n,availableModels:s.map(i=>{let o=i;return{id:String(o.value??o.id??"")}})}}extractModeState(e){if(!e)return;let r=e.find(i=>typeof i=="object"&&i!==null&&i.category==="mode");if(!r)return;let n=String(r.currentValue??""),s=Array.isArray(r.options)?r.options:[];return{currentModeId:n,availableModes:s.map(i=>{let o=i;return{id:String(o.value??o.id??"")}})}}cancelAbandonedPermission(e,r){try{return this.bridge.respondToSessionPermission(e.sessionId,e.bridgeRequestId,{outcome:{outcome:"cancelled"}},r!==void 0?{clientId:r}:void 0),!0}catch(n){let s=je(n);return/not found|unknown session/i.test(s)?!0:(D(`matilda serve: /acp cancelAbandonedPermission(${ce(e.sessionId)}) failed: ${ce(s)}`),!1)}}buildInitializeResult(e,r){let n=typeof r=="number"&&Number.isFinite(r)?r:Bg;return{protocolVersion:Math.max(1,Math.min(n,Bg)),agentCapabilities:{loadSession:!0,promptCapabilities:{image:!0,audio:!0,embeddedContext:!0},configOptions:!0,_meta:{[$c]:{connectionId:e,workspaceCwd:this.boundWorkspace,methods:tI(this.sessionShellCommandEnabled)}}}}}requireOwned(e,r,n){return e.ownsSession(r)?!0:n===void 0?(D(`matilda serve: /acp notification for unowned session ${ce(r)} (dropped)`),!1):(e.sendConn(W(n,$.INVALID_PARAMS,`Session ${r} is not owned by this connection`)),!1)}async handle(e,r,n,s){let i=s??e.fromLoopback;if(qc(r)){try{this.resolveClientResponse(e,r,i)}catch(d){D(`matilda serve: /acp response handling error: ${ce(je(d))}`)}return}if(!Qe(r)&&!Bc(r))return;let o=r.method,a=yr(r.params)?r.params:{},c=Qe(r)?r.id:void 0;if(n&&typeof a.sessionId=="string"&&a.sessionId!==n){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"Acp-Session-Id header does not match params.sessionId"));return}try{switch(o){case"authenticate":this.replyConn(e,c,{});return;case"session/new":{let d=Ng(a,this.boundWorkspace),u=await this.bridge.spawnOrAttach({workspaceCwd:d,clientId:e.clientId,sessionScope:"thread"});if(e.destroyed){this.killOrphanSession(u.sessionId);return}e.getOrCreateSession(u.sessionId).clientId=u.clientId,e.ownSession(u.sessionId);let l=await this.configOptionsFor(u.sessionId);if(e.destroyed){this.killOrphanSession(u.sessionId);return}let p=this.extractModelState(l),f=this.extractModeState(l);this.replyConn(e,c,{sessionId:u.sessionId,...l?{configOptions:l}:{},...p?{models:p}:{},...f?{modes:f}:{}});return}case"session/load":case"session/resume":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(e.closingSessions.has(d)){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,`session ${d} is being closed; retry`));return}let u=Ng(a,this.boundWorkspace),l=o==="session/load"?await this.bridge.loadSession({sessionId:d,workspaceCwd:u,clientId:e.clientId}):await this.bridge.resumeSession({sessionId:d,workspaceCwd:u,clientId:e.clientId}),p=e.closingSessions.has(d);if(e.destroyed||p){(l.attached?this.bridge.detachClient(d,l.clientId):this.bridge.killSession(d,{requireZeroAttaches:!0})).catch(O=>D(`matilda serve: /acp orphan ${l.attached?"detach":"kill"}(${ce(d)}) teardown-race: ${ce(je(O))}`)),p&&!e.destroyed&&c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,`session ${d} was closed during load; retry`));return}e.getOrCreateSession(d).clientId=l.clientId,e.ownSession(d);let f=await this.configOptionsFor(d),g=this.extractModelState(f),v=this.extractModeState(f);this.replyConn(e,c,{...l.state??{},...f?{configOptions:f}:{},...g?{models:g}:{},...v?{modes:v}:{}});return}case"session/list":{let d=typeof a.cursor=="string"?a.cursor:void 0,u=yr(a._meta)?a._meta:void 0,l=typeof u?.size=="number"?u.size:void 0,p=await Uc(this.bridge,this.boundWorkspace,{cursor:d,size:l});this.replyConn(e,c,{sessions:p.sessions.map(f=>({sessionId:f.sessionId,cwd:f.workspaceCwd,title:f.title,updatedAt:f.updatedAt})),...p.nextCursor!=null?{nextCursor:p.nextCursor}:{}});return}case"session/close":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;e.ownedSessions.delete(d),e.closingSessions.add(d);try{await this.bridge.closeSession(d,this.sessionCtx(e,d,i))}finally{try{e.closeSessionStream(d)}catch(u){D(`matilda serve: /acp session/close local teardown failed (${ce(d)}): ${ce(je(u))}`)}e.closingSessions.delete(d)}this.replyConn(e,c,{});return}case"session/fork":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(!this.requireOwned(e,d,c))return;let u=this.sessionCtx(e,d,i),l=await this.bridge.branchSession(d,{name:typeof a.name=="string"?a.name:void 0},u);if(e.destroyed){this.killOrphanSession(l.sessionId);return}e.getOrCreateSession(l.sessionId).clientId=l.clientId,e.ownSession(l.sessionId);let p=await this.configOptionsFor(l.sessionId),f=this.extractModelState(p),g=this.extractModeState(p);this.replyConn(e,c,{sessionId:l.sessionId,...p?{configOptions:p}:{},...f?{models:f}:{},...g?{modes:g}:{}});return}case"session/cancel":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;e.sessions.get(d)?.promptAbort?.abort(),await this.bridge.cancelSession(d,{...a,sessionId:d},this.sessionCtx(e,d,i)),c!==void 0&&this.replySession(e,d,c,{});return}case"session/prompt":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;nI(a),await this.handlePrompt(e,d,c,a,i);return}case"session/set_config_option":{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=String(a.configId??""),l=a.value,p=this.sessionCtx(e,d,i);if(typeof l!="string"||l.length===0){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,"`value` must be a non-empty string"));return}if(u==="model")await this.bridge.setSessionModel(d,{modelId:l},p);else if(u==="mode"){let g=l==="yolo"?"bogan":l;if(!tt.includes(g)){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,`invalid mode "${l}" (expected one of: ${tt.join(", ")})`));return}await this.bridge.setSessionApprovalMode(d,g,{persist:a.persist===!0},p)}else{c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,`Unknown configId: ${u}`));return}let f=await this.configOptionsFor(d);this.replySession(e,d,c,{configOptions:f});return}case"session/set_mode":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(!this.requireOwned(e,d,c))return;let u=String(a.modeId??""),l=u==="yolo"?"bogan":u;if(!l||!tt.includes(l)){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,`invalid modeId "${u}" (expected one of: ${tt.join(", ")})`));return}let p=this.sessionCtx(e,d,i);await this.bridge.setSessionApprovalMode(d,l,{persist:!1},p),this.replySession(e,d,c,{});return}case"session/set_model":{let d=String(a.sessionId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionId` is required"));return}if(!this.requireOwned(e,d,c))return;let u=String(a.modelId??"");if(!u){c!==void 0&&this.replySession(e,d,c,void 0,W(c,$.INVALID_PARAMS,"`modelId` is required"));return}let l=this.sessionCtx(e,d,i);await this.bridge.setSessionModel(d,{modelId:u,sessionId:d},l),this.replySession(e,d,c,{});return}case`${j}session/heartbeat`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=this.bridge.recordHeartbeat(d,this.sessionCtx(e,d,i));this.replyConn(e,c,u);return}case`${j}session/context`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;this.replyConn(e,c,await this.bridge.getSessionContextStatus(d));return}case`${j}session/supported_commands`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;this.replyConn(e,c,await this.bridge.getSessionSupportedCommandsStatus(d));return}case`${j}session/update_metadata`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=yr(a.metadata)?a.metadata:{},l=this.bridge.updateSessionMetadata(d,u,this.sessionCtx(e,d,i));this.replyConn(e,c,l);return}case`${j}workspace/mcp`:this.replyConn(e,c,await this.workspace.getWorkspaceMcpStatus(this.wsCtx(e,o)));return;case`${j}workspace/skills`:this.replyConn(e,c,await this.workspace.getWorkspaceSkillsStatus(this.wsCtx(e,o)));return;case`${j}workspace/providers`:this.replyConn(e,c,await this.workspace.getWorkspaceProvidersStatus(this.wsCtx(e,o)));return;case`${j}workspace/env`:this.replyConn(e,c,await this.workspace.getWorkspaceEnvStatus(this.wsCtx(e,o)));return;case`${j}workspace/preflight`:this.replyConn(e,c,await this.workspace.getWorkspacePreflightStatus(this.wsCtx(e,o)));return;case`${j}workspace/init`:{let d=a.force;if(d!==void 0&&typeof d!="boolean"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`force` must be a boolean when provided"));return}let u=d===!0,l=await this.workspace.initWorkspace(this.wsCtx(e,o),{force:u});this.replyConn(e,c,l);return}case`${j}workspace/set_tool_enabled`:{let d=String(a.toolName??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`toolName\` is required and must be \u2264 ${Kt} chars`));return}let u=await this.workspace.setWorkspaceToolEnabled(this.wsCtx(e,o),d,a.enabled===!0);this.replyConn(e,c,u);return}case`${j}workspace/restart_mcp_server`:{let d=String(a.serverName??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`serverName\` is required and must be \u2264 ${Kt} chars`));return}let u=a.entryIndex;if(u!==void 0&&(typeof u!="number"||!Number.isInteger(u)||u<0)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`entryIndex` must be a non-negative integer"));return}let l=await this.workspace.restartMcpServer(this.wsCtx(e,o),d,u!==void 0?{entryIndex:u}:void 0);this.replyConn(e,c,l);return}case`${j}session/recap`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=await this.bridge.generateSessionRecap(d,this.sessionCtx(e,d,i));this.replyConn(e,c,u);return}case`${j}session/btw`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=a.question;if(typeof u!="string"||u.trim().length===0||u.length>Rr){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`question\` required, non-empty, max ${Rr} chars`));return}let l=await this.bridge.generateSessionBtw(d,u.trim(),void 0,this.sessionCtx(e,d,i));this.replyConn(e,c,l);return}case`${j}session/shell`:{let d=String(a.sessionId??"");if(!this.sessionShellCommandEnabled){c!==void 0&&e.sendConn($g(c,new bt));return}if(!this.requireOwned(e,d,c))return;let u=e.sessions.get(d);if(!u?.clientId){c!==void 0&&e.sendConn($g(c,new St));return}let p=a.command;if(typeof p!="string"||p.trim().length===0){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`command` required and must be non-empty"));return}let f=ce(d.slice(0,8)),g=ce(String(e.clientId?.slice(0,8))),v=ce(p.slice(0,120));D(`matilda serve: /acp session/shell session=${f} client=${g} cmd=${v}`);let x=await this.bridge.executeShellCommand(d,p,u.abort.signal,this.sessionCtx(e,d,i));this.replyConn(e,c,x);return}case`${j}session/detach`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=this.sessionCtx(e,d,i);await this.bridge.detachClient(d,u.clientId),this.replyConn(e,c,{ok:!0});return}case`${j}session/context_usage`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=await this.bridge.getSessionContextUsageStatus(d,{detail:a.detail===!0});this.replyConn(e,c,u);return}case`${j}session/tasks`:{let d=String(a.sessionId??"");if(!this.requireOwned(e,d,c))return;let u=await this.bridge.getSessionTasksStatus(d);this.replyConn(e,c,u);return}case`${j}workspace/memory`:{let d=await Dc(this.boundWorkspace);this.replyConn(e,c,d);return}case`${j}workspace/memory/write`:{let d=a.content;if(typeof d!="string"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`content` required, must be string"));return}if(Buffer.byteLength(d,"utf8")>1024*1024){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`content` exceeds 1MB limit"));return}let u=a.scope;if(u!==void 0&&u!=="workspace"&&u!=="global"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,'`scope` must be "workspace" or "global"'));return}let l=u??"workspace",p=a.mode;if(p!==void 0&&p!=="append"&&p!=="replace"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,'`mode` must be "append" or "replace"'));return}let f=p??"append";D(`matilda serve: /acp workspace/memory/write scope=${l} mode=${f} client=${e.clientId?.slice(0,8)} bytes=${Buffer.byteLength(d,"utf8")}`);let g=await ts({scope:l,mode:f,content:d,projectRoot:this.boundWorkspace});if(this.replyConn(e,c,{ok:!0,filePath:g.filePath,bytesWritten:g.bytesWritten,changed:g.changed}),g.changed)try{this.bridge.publishWorkspaceEvent({type:"memory_changed",data:{scope:l,filePath:g.filePath,mode:f,bytesWritten:g.bytesWritten},originatorClientId:e.clientId})}catch{}return}case`${j}file/read`:{let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=await u.readText(l,{maxBytes:typeof a.maxBytes=="number"?a.maxBytes:void 0,line:typeof a.line=="number"?a.line:void 0,limit:typeof a.limit=="number"?a.limit:void 0});this.replyConn(e,c,{path:d,content:p.content,...p.meta});return}case`${j}file/read_bytes`:{if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=await u.readBytesWindow(l,{offset:typeof a.offset=="number"?a.offset:void 0,maxBytes:typeof a.maxBytes=="number"?a.maxBytes:void 0});this.replyConn(e,c,{path:d,...p});return}case`${j}file/stat`:{if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=await u.stat(l);this.replyConn(e,c,{path:d,...p});return}case`${j}file/list`:{if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"read"),p=2e3,f=await u.list(l,{maxEntries:p+1}),g=f.length>p;this.replyConn(e,c,{path:d,entries:g?f.slice(0,p):f,truncated:g});return}case`${j}file/glob`:{let d=String(a.pattern??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`pattern` required"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),p=typeof a.maxResults=="number"?Math.max(1,Math.min(Number(a.maxResults)||5e3,5e4)):5e3,f=await u.glob(d,{maxResults:p+1}),g=f.length>p;this.replyConn(e,c,{pattern:d,matches:g?f.slice(0,p):f,truncated:g});return}case`${j}file/write`:{let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}if(typeof a.content!="string"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`content` must be string"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"write");if(Buffer.byteLength(a.content,"utf8")>10*1024*1024){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"content exceeds 10MB limit"));return}await u.writeTextOverwrite(l,a.content),this.replyConn(e,c,{ok:!0,path:d});return}case`${j}file/edit`:{let d=String(a.path??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`path` required"));return}if(typeof a.oldText!="string"||typeof a.newText!="string"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`oldText` and `newText` must be strings"));return}if(!this.fsFactory){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"File system not configured"));return}let u=this.fsFactory.forRequest({originatorClientId:e.clientId,route:`ACP ${o}`}),l=await u.resolve(d,"write"),p=await u.edit(l,a.oldText,a.newText);this.replyConn(e,c,{ok:!0,path:d,...p});return}case`${j}workspace/auth/status`:{if(!this.deviceFlowRegistry){this.replyConn(e,c,{pendingDeviceFlows:[]});return}let u=this.deviceFlowRegistry.listPending().map(l=>({deviceFlowId:l.deviceFlowId,providerId:l.providerId,expiresAt:l.expiresAt}));this.replyConn(e,c,{pendingDeviceFlows:u});return}case`${j}workspace/auth/device_flow/start`:{if(!this.deviceFlowRegistry){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"Device flow not configured"));return}let d=String(a.providerId??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`providerId` required"));return}let u=await this.deviceFlowRegistry.start({providerId:d,initiatorClientId:e.clientId}),{view:l,attached:p}=u,f=l.initiatorClientId===e.clientId?l:{deviceFlowId:l.deviceFlowId,providerId:l.providerId,status:l.status,expiresAt:l.expiresAt};this.replyConn(e,c,{view:f,attached:p});return}case`${j}workspace/auth/device_flow/get`:{if(!this.deviceFlowRegistry){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"Device flow not configured"));return}let d=String(a.id??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`id` required"));return}let u=this.deviceFlowRegistry.get(d);if(!u){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Device flow "${d}" not found`));return}let l=u.initiatorClientId===e.clientId?u:{deviceFlowId:u.deviceFlowId,providerId:u.providerId,status:u.status,expiresAt:u.expiresAt};this.replyConn(e,c,l);return}case`${j}workspace/auth/device_flow/cancel`:{if(!this.deviceFlowRegistry){c!==void 0&&e.sendConn(W(c,$.INTERNAL_ERROR,"Device flow not configured"));return}let d=String(a.id??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`id` required"));return}let u=this.deviceFlowRegistry.get(d);if(u&&u.initiatorClientId&&u.initiatorClientId!==e.clientId){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"Only the flow initiator can cancel"));return}let l=this.deviceFlowRegistry.cancel(d,e.clientId);if(!l){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Device flow "${d}" not found`));return}this.replyConn(e,c,{ok:!0,alreadyTerminal:l.alreadyTerminal});return}case`${j}workspace/tools`:{let d=await this.bridge.getWorkspaceToolsStatus();this.replyConn(e,c,d);return}case`${j}workspace/mcp/tools`:{let d=String(a.serverName??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`serverName` required"));return}let u=await this.bridge.getWorkspaceMcpToolsStatus(d);this.replyConn(e,c,u);return}case`${j}workspace/mcp/servers/add`:{let d=String(a.name??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`name\` required, max ${Kt} chars`));return}let u=a.config;if(!u||typeof u!="object"||Array.isArray(u)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`config` required, must be object"));return}let l=await this.bridge.addRuntimeMcpServer(d,u,e.clientId);this.replyConn(e,c,l);return}case`${j}workspace/mcp/servers/remove`:{let d=String(a.name??"");if(!d||d.length>Kt){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`\`name\` required, max ${Kt} chars`));return}let u=await this.bridge.removeRuntimeMcpServer(d,e.clientId);this.replyConn(e,c,u);return}case`${j}sessions/delete`:{let d=a.sessionIds;if(!Array.isArray(d)||d.length===0||d.length>100||!d.every(v=>typeof v=="string")){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`sessionIds` must be non-empty string array (max 100)"));return}let u=[...new Set(d)],l=[],p=[];await Promise.allSettled(u.map(async v=>{try{await this.bridge.closeSession(v),p.push(v)}catch(x){let O=x instanceof Error?x.message:String(x);if(x instanceof Error&&x.name==="SessionNotFoundError")p.push(v);else{let P=ce(v.slice(0,8)),q=ce(O);D(`matilda serve: /acp sessions/delete closeSession(${P}) failed: ${q}`),l.push({sessionId:v,error:O})}}}));let g=await new kr(this.boundWorkspace).removeSessions(p);for(let v of g.errors){let x=ce(v.sessionId.slice(0,8)),O=ce(je(v.error));D(`matilda serve: /acp sessions/delete removeSessions(${x}) failed: ${O}`)}this.replyConn(e,c,{removed:g.removed,notFound:g.notFound,errors:[...l,...g.errors.map(v=>({sessionId:v.sessionId,error:je(v.error)}))]});return}case`${j}workspace/agents/list`:{let d=await this.agentManager.listSubagents({force:!0});this.replyConn(e,c,{v:1,workspaceCwd:this.boundWorkspace,agents:d.map(yi)});return}case`${j}workspace/agents/get`:{let d=String(a.agentType??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`agentType` required"));return}let u=await this.agentManager.loadSubagent(d);if(!u){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${d}" not found`));return}this.replyConn(e,c,Gt(u));return}case`${j}workspace/agents/create`:{let d=a.scope;if(d!=="workspace"&&d!=="global"){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,'`scope` must be "workspace" or "global"'));return}let u=a.name;if(typeof u!="string"||!u.trim()){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`name` required"));return}let l=d==="workspace"?"project":"user";if(Qn.isBuiltinAgent(u)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Cannot shadow built-in agent "${u}"`));return}if(await this.agentManager.loadSubagent(u,l)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${u}" already exists`));return}await this.agentManager.createSubagent({name:u,level:l,description:typeof a.description=="string"?a.description:"",systemPrompt:typeof a.systemPrompt=="string"?a.systemPrompt:"",tools:Array.isArray(a.tools)?a.tools:void 0,model:typeof a.model=="string"?a.model:void 0},{level:l});let f=await this.agentManager.loadSubagent(u,l);this.replyConn(e,c,{ok:!0,agent:f?Gt(f):null});try{this.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:u,level:l},originatorClientId:e.clientId})}catch{}return}case`${j}workspace/agents/update`:{let d=String(a.agentType??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`agentType` required"));return}let u=await this.agentManager.loadSubagent(d);if(!u){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${d}" not found`));return}let l=256*1024,p={};if(typeof a.description=="string"){if(Buffer.byteLength(a.description,"utf8")>l){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`description` exceeds 256KB limit"));return}p.description=a.description}if(typeof a.systemPrompt=="string"){if(Buffer.byteLength(a.systemPrompt,"utf8")>l){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`systemPrompt` exceeds 256KB limit"));return}p.systemPrompt=a.systemPrompt}if(Array.isArray(a.tools)){if(a.tools.length>256){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`tools` exceeds 256-entry limit"));return}if(!a.tools.every(g=>typeof g=="string"&&g.length<=256)){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`tools` elements must be strings \u2264256 chars"));return}p.tools=a.tools}if(typeof a.model=="string"&&(p.model=a.model),Object.keys(p).length===0){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"at least one updatable field required"));return}await this.agentManager.updateSubagent(d,p,u.level);let f=await this.agentManager.loadSubagent(d,u.level);this.replyConn(e,c,{ok:!0,agent:f?Gt(f):null});try{this.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:d,level:u.level},originatorClientId:e.clientId})}catch{}return}case`${j}workspace/agents/delete`:{let d=String(a.agentType??"");if(!d){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,"`agentType` required"));return}let u=typeof a.scope=="string"?a.scope:void 0,l=u==="workspace"?"project":u==="global"?"user":void 0,p=await this.agentManager.loadSubagent(d,l);if(!p){c!==void 0&&e.sendConn(W(c,$.INVALID_PARAMS,`Agent "${d}" not found`));return}await this.agentManager.deleteSubagent(d,p.level),this.replyConn(e,c,{ok:!0});try{this.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:d,level:p.level},originatorClientId:e.clientId})}catch{}return}default:c!==void 0&&e.sendConn(W(c,$.METHOD_NOT_FOUND,`Unknown method: ${o}`));return}}catch(d){if(D(`matilda serve: /acp dispatch error (${ce(o)}): ${ce(je(d))}`),c!==void 0){let{code:u,message:l,data:p}=Hc(d),f=W(c,u,l,p),g=typeof a.sessionId=="string"?a.sessionId:void 0;g&&!rI.has(o)?this.replySession(e,g,c,void 0,f):e.sendConn(f)}}}async pumpSessionEvents(e,r,n){try{let s=this.bridge.subscribeEvents(r,{signal:n});for await(let i of s){if(n.aborted)break;e.touch(),this.translateEvent(e,r,i)}}catch(s){throw n.aborted||e.sendSession(r,On(`${j}notify`,{kind:"stream_error",error:je(s)})),s}}translateEvent(e,r,n){switch(n.type){case"session_update":{e.sendSession(r,On("session/update",n.data));return}case"permission_request":{let s=n.data,i=e.sessions.get(r);if(!i?.stream||i.stream.isClosed){this.cancelAbandonedPermission({sessionId:r,bridgeRequestId:s.requestId},i?.clientId)||D(`matilda serve: /acp permission cancel FAILED for ${ce(r)} (mediator stuck; no automatic recovery)`);return}let o=e.nextId();e.pending.set(o,{sessionId:r,bridgeRequestId:s.requestId,kind:"permission"}),i.stream.send(Lg(o,"session/request_permission",{sessionId:s.sessionId,toolCall:s.toolCall,options:s.options,_meta:{[$c]:{requestId:s.requestId}}}));return}case"stream_error":{e.sendSession(r,On(`${j}notify`,{...n.data,kind:"stream_error"}));return}default:e.sendSession(r,On(`${j}notify`,{kind:n.type,data:n.data}))}}resolveClientResponse(e,r,n){let s=r.id;if(typeof s!="string")return;let i=e.pending.get(s);if(!i)return;let o="error"in r?{outcome:{outcome:"cancelled"}}:r.result;try{this.bridge.respondToSessionPermission(i.sessionId,i.bridgeRequestId,o,this.sessionCtx(e,i.sessionId,n)),e.pending.delete(s)}catch(a){D(`matilda serve: /acp permission vote failed (${ce(i.sessionId)}): ${ce(je(a))}`),this.cancelAbandonedPermission(i,e.sessions.get(i.sessionId)?.clientId)&&e.pending.delete(s)}}async handlePrompt(e,r,n,s,i){let o=e.getOrCreateSession(r);o.promptAbort?.abort();let a=new AbortController;o.promptAbort=a;try{let c=await this.bridge.sendPrompt(r,s,a.signal,this.sessionCtx(e,r,i));n!==void 0&&this.replySession(e,r,n,c)}catch(c){let{code:d,message:u,data:l}=Hc(c);n!==void 0?this.replySession(e,r,n,void 0,W(n,d,u,l)):D(`matilda serve: /acp prompt error (${ce(r)}, notification): ${ce(je(c))}`)}finally{o.promptAbort===a&&(o.promptAbort=void 0)}}replyConn(e,r,n){r!==void 0&&e.sendConn(jc(r,n))}replySession(e,r,n,s,i){if(n===void 0)return;let o=i??jc(n,s);e.sessions.has(r)?e.sendSession(r,o):(D(`matilda serve: /acp replySession(${ce(r)}) binding gone mid-flight, reply routed to connection stream ${e.connectionId.slice(0,8)}`),e.sendConn(o))}};w();import{randomUUID as Wg}from"node:crypto";var sI=256,iI=64,Vc=class{constructor(e,r,n,s){this.onAbandonPending=n;this.onDetachSession=s;this.connectionId=e??Wg(),this.clientId=Wg(),this.fromLoopback=r}connectionId;connStream;connBuffer=[];sessions=new Map;ownedSessions=new Set;closingSessions=new Set;pending=new Map;clientId;fromLoopback;destroyed=!1;connGraceTimer;lastActiveMs=Date.now();idCounter=0;nextId(){return this.idCounter+=1,`_matilda_perm_${this.idCounter}`}touch(){this.lastActiveMs=Date.now()}ownSession(e){this.ownedSessions.add(e)}ownsSession(e){return this.ownedSessions.has(e)}getOrCreateSession(e){let r=this.sessions.get(e);return r||(r={sessionId:e,abort:new AbortController,buffer:[]},this.sessions.set(e,r)),r}getDiagnostic(){let e=new Set;this.connStream&&!this.connStream.isClosed&&e.add(this.connStream);let r=0,n=0;for(let o of this.sessions.values())n+=o.buffer.length,o.stream&&!o.stream.isClosed&&(r+=1,e.add(o.stream));let s=0,i=0;for(let o of e)o.kind==="sse"&&(s+=1),o.kind==="ws"&&(i+=1);return{connectionIdPrefix:this.connectionId.slice(0,8),fromLoopback:this.fromLoopback,destroyed:this.destroyed,lastActiveMs:this.lastActiveMs,ownedSessionCount:this.ownedSessions.size,sessionBindingCount:this.sessions.size,closingSessionCount:this.closingSessions.size,pendingClientRequests:this.pending.size,connectionStreamOpen:this.connStream!==void 0&&!this.connStream.isClosed,sessionStreams:r,sseStreams:s,wsStreams:i,bufferedConnectionFrames:this.connBuffer.length,bufferedSessionFrames:n}}sendConn(e){this.connStream&&!this.connStream.isClosed?this.connStream.send(e):Hg(this.connBuffer,e,`conn ${this.connectionId}`)}hasLiveSessionStream(){for(let e of this.sessions.values())if(e.stream&&!e.stream.isClosed)return!0;return!1}clearGraceTimer(){this.connGraceTimer&&(clearTimeout(this.connGraceTimer),this.connGraceTimer=void 0)}attachConnStream(e){this.clearGraceTimer(),this.connStream&&this.connStream!==e&&this.connStream.close(),this.connStream=e;for(let r of this.connBuffer.splice(0))e.send(r)}sendSession(e,r){let n=this.sessions.get(e);n&&(n.stream&&!n.stream.isClosed?n.stream.send(r):Hg(n.buffer,r,`session ${e}`))}attachSessionStream(e,r,n){let s=this.getOrCreateSession(e),i=s.stream;s.abort.abort(),s.abort=n,s.stream=r,i&&i!==r&&i!==this.connStream&&i.close();for(let o of s.buffer.splice(0))r.send(o);return s}closeSessionStream(e){let r=this.sessions.get(e);r&&(this.teardownBinding(r),this.sessions.delete(e),this.ownedSessions.delete(e))}destroy(){this.destroyed=!0,this.clearGraceTimer();for(let e of this.sessions.values())try{this.teardownBinding(e)}catch(r){D(`matilda serve: /acp teardownBinding(${ce(e.sessionId)}) failed during destroy: ${r instanceof Error?r.message:String(r)}`)}this.sessions.clear(),this.ownedSessions.clear(),this.pending.clear(),this.connStream?.close()}teardownBinding(e){e.abort.abort(),e.promptAbort?.abort(),e.stream&&e.stream!==this.connStream&&e.stream.close(),this.abandonPendingForSession(e.sessionId,e.clientId),this.onDetachSession?.(e.sessionId,e.clientId)}abandonPendingForSession(e,r){for(let[n,s]of this.pending){if(s.sessionId!==e)continue;this.pending.delete(n),(this.onAbandonPending?.(s,r)??!0)||D(`matilda serve: /acp MEDIATOR STUCK: abandonPendingForSession(${ce(e)}) cancel failed for ${ce(s.bridgeRequestId)}`)}}};function Hg(t,e,r="stream"){t.length>=sI&&(t.shift(),D(`matilda serve: /acp pre-attach buffer full (${r}), dropped oldest frame`)),t.push(e)}var Si=class{constructor(e,r,n=iI,s=30*6e4){this.onAbandonPending=e;this.onDetachSession=r;this.maxConnections=n;this.idleTtlMs=s;this.sweepTimer=setInterval(()=>this.sweep(),6e4),this.sweepTimer.unref()}byId=new Map;sweepTimer;create(e){if(this.maxConnections>0&&this.byId.size>=this.maxConnections)return;let r=new Vc(void 0,e,this.onAbandonPending,this.onDetachSession);return this.byId.set(r.connectionId,r),r}get(e){if(!e)return;let r=this.byId.get(e);return r?.touch(),r}delete(e){let r=this.byId.get(e);return r?(r.destroy(),this.byId.delete(e)):!1}get size(){return this.byId.size}get connectionCap(){return this.maxConnections}getSnapshot(){let e=[...this.byId.values()].map(r=>r.getDiagnostic());return{connectionCount:this.byId.size,connectionCap:this.maxConnections>0&&Number.isFinite(this.maxConnections)?this.maxConnections:null,connectionStreams:e.filter(r=>r.connectionStreamOpen).length,sessionStreams:bi(e,r=>r.sessionStreams),sseStreams:bi(e,r=>r.sseStreams),wsStreams:bi(e,r=>r.wsStreams),pendingClientRequests:bi(e,r=>r.pendingClientRequests),connections:e}}dispose(){clearInterval(this.sweepTimer);for(let e of[...this.byId.keys()])this.delete(e)}sweep(){let e=Date.now()-this.idleTtlMs;for(let[r,n]of this.byId)n.lastActiveMs>=e||(D(`matilda serve: /acp reaping idle connection ${r} (idle > ${Math.round(this.idleTtlMs/6e4)}m, ${n.sessions.size} session(s))`),this.delete(r))}};function bi(t,e){let r=0;for(let n of t)r+=e(n);return r}w();var Dn=class{constructor(e,r,n){this.res=e;this.onClose=r;this.onHeartbeat=n}kind="sse";writeChain=Promise.resolve();heartbeat;closed=!1;cleanupFn;open(){this.res.status(200),this.res.setHeader("Content-Type","text/event-stream"),this.res.setHeader("Cache-Control","no-cache, no-transform"),this.res.setHeader("Connection","keep-alive"),this.res.setHeader("X-Accel-Buffering","no"),this.res.flushHeaders(),this.writeRaw(`retry: 3000
70
70
 
71
71
  `),this.heartbeat=setInterval(()=>{this.closed||(this.onHeartbeat?.(),this.writeRaw(`: hb
72
72
 
@@ -710,10 +710,10 @@ return fn.apply(this, arguments)
710
710
  })();
711
711
  </script>
712
712
  </body>
713
- </html>`}w();w();import*as c0 from"node:path";var Je=256*1024,d0=5*1024*1024;function At(t,e,r,n="file"){let s=c0.relative(e,t);if(s===""||s.startsWith(".."))return{ignored:!1};let i=r.getFileFilter(),o=r.getDirectoryFilter();if(n==="directory"){let a=s.endsWith("/")?s:`${s}/`;return o(a)?{ignored:!0,category:"directory"}:i(s)?{ignored:!0,category:"file"}:{ignored:!1}}return i(s)?{ignored:!0,category:"file"}:o(s)?{ignored:!0,category:"directory"}:{ignored:!1}}function pt(t,e){if(!t)switch(e){case"read":case"list":case"glob":case"stat":return;case"write":case"edit":throw new B("untrusted_workspace",`workspace is not trusted; ${e} operations are forbidden`,{hint:"mark the folder as trusted in the daemon configuration to allow writes"});default:{let r=e;throw new B("untrusted_workspace",`workspace is not trusted; intent "${String(r)}" is not classified`,{hint:"unknown intent reached the trust gate; classify it in policy.ts"})}}}function Yc(t,e=Je){return t<=e?{bytesToRead:t,truncated:!1}:{bytesToRead:e,truncated:!0}}function Yt(t,e=d0){if(t>e)throw new B("file_too_large",`payload of ${t} bytes exceeds write limit of ${e} bytes`,{hint:"split the write into smaller chunks or raise the daemon limit"})}async function Qc(t){return Pd(t)}w();import{createHash as RI}from"node:crypto";import*as Qt from"node:path";var Zc="fs.access",ed="fs.denied";function u0(t){return RI("sha256").update(t).digest("hex").slice(0,16)}var CI="<cross-drive>";function l0(t,e){let r=Qt.isAbsolute(t)?Qt.relative(e,t):t;return Qt.isAbsolute(r)?CI:r}function TI(){return process.env.MATILDA_AUDIT_RAW_PATHS==="1"}function td(t){let e=t.includeRawPaths??TI(),{emit:r,boundWorkspace:n}=t;return{recordAccess(s,i){let o=String(i.absolute),a={kind:Zc,intent:i.intent,route:s.route,pathHash:u0(o),durationMs:i.durationMs};s.sessionId&&(a.sessionId=s.sessionId),i.sizeBytes!==void 0&&(a.sizeBytes=i.sizeBytes),i.truncated&&(a.truncated=!0),i.matchedIgnore&&(a.matchedIgnore=i.matchedIgnore),i.pattern!==void 0&&e&&(a.pattern=i.pattern),e&&(a.relPath=l0(o,n)),r({v:1,type:Zc,data:a,originatorClientId:s.originatorClientId})},recordDenied(s,i){let o=Qt.isAbsolute(i.input)?i.input:Qt.resolve(n,i.input),a={kind:ed,intent:i.intent,route:s.route,pathHash:u0(o),errorKind:i.errorKind};s.sessionId&&(a.sessionId=s.sessionId),i.hint&&(a.hint=i.hint),i.message&&e&&(a.message=i.message),i.pattern!==void 0&&e&&(a.pattern=i.pattern),e&&(a.relPath=l0(i.input,n)),r({v:1,type:ed,data:a,originatorClientId:s.originatorClientId})}}}w();import{createHash as v0,randomBytes as PI}from"node:crypto";import{promises as ve}from"node:fs";import*as Xe from"node:path";function ad(t){let e=Ye(t.boundWorkspace),r=t.ignore??hu({projectRoot:e,useGitignore:!0,useMatildaignore:!0,ignoreDirs:[]});Object.freeze(r);let n=td({emit:t.emit,boundWorkspace:e,includeRawPaths:t.includeRawPaths}),s=new cu,i=new id;return{forRequest(o){return new sd({boundWorkspace:e,trusted:t.trusted,ignore:r,audit:n,ctx:o,lowFs:s,pathLocks:i})}}}var sd=class{constructor(e){this.deps=e}async resolve(e,r){try{return await Mc(e,this.deps.boundWorkspace,r)}catch(n){throw this.recordAndWrap(n,r,e)}}async stat(e){let r=performance.now();try{pt(this.deps.trusted,"stat");let n=await ve.lstat(e),s={kind:g0(n),sizeBytes:n.size,modifiedMs:n.mtimeMs};return this.deps.audit.recordAccess(this.deps.ctx,{intent:"stat",absolute:e,durationMs:performance.now()-r,sizeBytes:n.size}),s}catch(n){throw this.recordAndWrap(n,"stat",e)}}async readText(e,r={}){let n=performance.now();try{if(pt(this.deps.trusted,"read"),r.line!==void 0&&(!Number.isSafeInteger(r.line)||r.line<1))throw new B("parse_error",`line must be a positive integer, got ${r.line}`);let s=await od(e,r),i=At(e,this.deps.boundWorkspace,this.deps.ignore,"file"),o=s.meta;return i.ignored&&(o.matchedIgnore=i.category),this.deps.audit.recordAccess(this.deps.ctx,{intent:"read",absolute:e,durationMs:performance.now()-n,sizeBytes:o.sizeBytes,truncated:o.truncated,matchedIgnore:o.matchedIgnore}),{content:s.content,meta:o}}catch(s){throw this.recordAndWrap(s,"read",e)}}async readBytes(e,r={}){return(await this.readBytesWindow(e,r)).buffer}async readBytesWindow(e,r={}){let n=performance.now();try{pt(this.deps.trusted,"read");let s=r.offset??0,i=r.maxBytes??Je;if(!Number.isSafeInteger(s)||s<0)throw new B("parse_error",`offset must be a non-negative integer, got ${s}`);if(!Number.isSafeInteger(i)||i<1||i>Je)throw new B("parse_error",`maxBytes must be a positive integer in [1, ${Je}], got ${i}`);let o=await ve.lstat(e);if(!o.isFile())throw new B("parse_error",`path is not a regular file: ${e}`);let a=await ve.open(e,"r"),c,d;try{c=await a.stat(),jt(o,c,e,"read");let p=Math.max(0,c.size-s),f=Math.min(i,p);if(d=Buffer.allocUnsafe(f),f>0){let v=await a.read(d,0,f,s);d=v.bytesRead===f?d:d.subarray(0,v.bytesRead)}let g=await a.stat();if(jt(c,g,e,"read"),g.size!==c.size||g.mtimeMs!==c.mtimeMs)throw new B("hash_mismatch",`file changed during read: ${e}`,{hint:"retry after re-reading the latest file hash"})}finally{await a.close()}await h0(e,c.ino);let u=s===0&&d.length===c.size,l={buffer:d,sizeBytes:c.size,returnedBytes:d.length,offset:s,truncated:!u,...u?{hash:cd(d)}:{}};return this.deps.audit.recordAccess(this.deps.ctx,{intent:"read",absolute:e,durationMs:performance.now()-n,sizeBytes:d.length,truncated:l.truncated}),l}catch(s){throw this.recordAndWrap(s,"read",e)}}async list(e,r={}){let n=performance.now();try{pt(this.deps.trusted,"list");let s=[],i=await ve.opendir(e);for await(let o of i){let a=Xe.join(e,o.name),c=g0(o),d=At(a,this.deps.boundWorkspace,this.deps.ignore,c==="directory"?"directory":"file");if(!(d.ignored&&!r.includeIgnored)&&(s.push({name:o.name,kind:c,ignored:d.ignored}),r.maxEntries!==void 0&&s.length>=r.maxEntries))break}return this.deps.audit.recordAccess(this.deps.ctx,{intent:"list",absolute:e,durationMs:performance.now()-n,sizeBytes:s.length,truncated:r.maxEntries!==void 0&&s.length>=r.maxEntries}),s}catch(s){throw this.recordAndWrap(s,"list",e)}}async glob(e,r={}){let n=performance.now();try{if(pt(this.deps.trusted,"glob"),e.split(/[\\/]/).some(p=>p===".."))throw new B("parse_error",`glob pattern may not contain '..' segments: ${e}`);if(Xe.isAbsolute(e)||/^[A-Za-z]:[\\/]/.test(e)||e.startsWith("\\\\")||e.startsWith("//"))throw new B("parse_error",`glob pattern must be workspace-relative: ${e}`,{hint:'pass a relative pattern such as "src/**/*.ts"'});let s=r.cwd??this.deps.boundWorkspace,i;if(s===this.deps.boundWorkspace)i=s;else try{i=await ve.realpath(Xe.resolve(s))}catch(p){throw p?.code==="ENOENT"?new B("path_not_found",`glob cwd does not exist: ${s}`,{cause:p}):p}if(!xr(i,this.deps.boundWorkspace))throw new B("path_outside_workspace",`glob cwd is outside workspace: ${s}`,{hint:"opts.cwd must be a path obtained from fs.resolve()"});let o=await ou(e,{cwd:i,nodir:!1,absolute:!0,dot:!0,ignore:["**/node_modules/**","**/.git/**"]}),a=[],c=r.maxResults??Number.POSITIVE_INFINITY,d=0,u=0,l=0;for(let p of o){if(a.length>=c)break;let f=Xe.resolve(p),g;try{g=await ve.realpath(f)}catch(q){let U=q?.code;U==="ENOENT"||U==="ELOOP"?d+=1:U==="EACCES"||U==="EPERM"?u+=1:l+=1;continue}let v=Xe.relative(this.deps.boundWorkspace,g);if(v.startsWith("..")||Xe.isAbsolute(v)){d+=1;continue}let x=null;try{x=await ve.lstat(g)}catch{x=null}let O=x?.isDirectory()?"directory":"file";At(g,this.deps.boundWorkspace,this.deps.ignore,O).ignored&&!r.includeIgnored||a.push(g)}return d>0&&this.deps.audit.recordDenied(this.deps.ctx,{intent:"glob",input:e,errorKind:"symlink_escape",hint:`glob filtered ${d} hit(s) that resolved outside workspace`,pattern:e}),u>0&&this.deps.audit.recordDenied(this.deps.ctx,{intent:"glob",input:e,errorKind:"permission_denied",hint:`glob skipped ${u} hit(s) due to EACCES/EPERM`,pattern:e}),l>0&&this.deps.audit.recordDenied(this.deps.ctx,{intent:"glob",input:e,errorKind:"io_error",hint:`glob skipped ${l} hit(s) due to transient I/O errors (EIO/EBUSY/ENAMETOOLONG/EMFILE)`,pattern:e}),this.deps.audit.recordAccess(this.deps.ctx,{intent:"glob",absolute:this.deps.boundWorkspace,durationMs:performance.now()-n,sizeBytes:a.length,pattern:e}),a}catch(s){throw this.recordAndWrap(s,"glob",e)}}async writeTextAtomic(e,r,n){let s=performance.now();try{pt(this.deps.trusted,"write"),OI(n);let i=Buffer.byteLength(r,"utf-8");return Yt(i),await this.deps.pathLocks.runExclusive(e,async()=>{let a=n.mode==="replace"?await p0(e,n.expectedHash):void 0;n.mode==="create"&&await y0(e);let c=rd(a,n),d=await nd({target:e,content:r,mode:n.mode,expectedHash:n.expectedHash,meta:c}),u=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return u.ignored&&(c.matchedIgnore=u.category),c.sizeBytes=d.sizeBytes,c.hash=d.hash,this.deps.audit.recordAccess(this.deps.ctx,{intent:"write",absolute:e,durationMs:performance.now()-s,sizeBytes:d.sizeBytes,matchedIgnore:c.matchedIgnore}),{created:n.mode==="create",sizeBytes:d.sizeBytes,hash:d.hash,meta:c}})}catch(i){throw this.recordAndWrap(i,"write",e)}}async writeTextOverwrite(e,r,n={}){let s=performance.now();try{pt(this.deps.trusted,"write");let i=Buffer.byteLength(r,"utf-8");return Yt(i),await this.deps.pathLocks.runExclusive(e,async()=>{let a=!1;try{await ve.lstat(e),a=!0}catch(p){if(p?.code!=="ENOENT")throw p}let c;try{c=await p0(e)}catch(p){let f=p?.code,g=p?.kind;if(f!=="ENOENT"&&f!=="EACCES"&&f!=="EPERM"&&g!=="file_too_large"&&g!=="binary_file")throw p}let d=rd(c,n),u=await nd({target:e,content:r,mode:"overwrite",meta:d}),l=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return l.ignored&&(d.matchedIgnore=l.category),d.sizeBytes=u.sizeBytes,d.hash=u.hash,this.deps.audit.recordAccess(this.deps.ctx,{intent:"write",absolute:e,durationMs:performance.now()-s,sizeBytes:u.sizeBytes,matchedIgnore:d.matchedIgnore}),{created:!a,sizeBytes:u.sizeBytes,hash:u.hash,meta:d}})}catch(i){throw this.recordAndWrap(i,"write",e)}}async writeText(e,r,n){let s=performance.now();try{pt(this.deps.trusted,"write");let i=Buffer.byteLength(r,"utf-8");Yt(i),await m0(e),await this.deps.lowFs.writeTextFile({path:e,content:r,_meta:n?w0(n):void 0});let o=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");this.deps.audit.recordAccess(this.deps.ctx,{intent:"write",absolute:e,durationMs:performance.now()-s,sizeBytes:i,matchedIgnore:o.ignored?o.category:void 0})}catch(i){throw this.recordAndWrap(i,"write",e)}}async editAtomic(e,r,n,s){let i=performance.now();try{if(pt(this.deps.trusted,"edit"),!wr(s.expectedHash))throw new B("parse_error","expectedHash must match sha256:<64 lowercase hex chars>");if(typeof r!="string"||r.length===0)throw new B("parse_error",`oldText must be a non-empty string for edit on ${e}`);if(typeof n!="string")throw new B("parse_error","newText must be a string");return await this.deps.pathLocks.runExclusive(e,async()=>{let a=await od(e);if(a.meta.hash!==s.expectedHash)throw new B("hash_mismatch",`expected ${s.expectedHash}, found ${a.meta.hash}`,{hint:"re-read the file and retry with the latest hash"});let c=a.content,d=zI(c,r);if(d===0){let v=r.length>80?r.slice(0,80)+"...":r;throw new B("text_not_found",`oldText not found in ${e}`,{hint:`searched for: ${JSON.stringify(v)}`})}if(d>1)throw new B("ambiguous_text_match",`oldText appears ${d} times in ${e}`,{hint:"pass a larger oldText span that occurs exactly once"});let u=c.indexOf(r),l=c.slice(0,u)+n+c.slice(u+r.length);Yt(Buffer.byteLength(l,"utf-8"));let p=rd(a.meta,{}),f=await nd({target:e,content:l,mode:"replace",expectedHash:s.expectedHash,meta:p}),g=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return g.ignored&&(p.matchedIgnore=g.category),p.sizeBytes=f.sizeBytes,p.hash=f.hash,this.deps.audit.recordAccess(this.deps.ctx,{intent:"edit",absolute:e,durationMs:performance.now()-i,sizeBytes:f.sizeBytes,matchedIgnore:p.matchedIgnore}),{writtenBytes:f.sizeBytes,hash:f.hash,meta:p}})}catch(o){throw this.recordAndWrap(o,"edit",e)}}async edit(e,r,n,s){if(s?.expectedHash!==void 0)return this.editAtomic(e,r,n,{expectedHash:s.expectedHash});let i=performance.now();try{pt(this.deps.trusted,"edit");let o=await ve.stat(e);if(o.size>Je)throw new B("file_too_large",`file of ${o.size} bytes exceeds edit cap of ${Je} bytes`,{hint:"split large edits into bounded readBytes/writeText sequences"});if(await Qc(e))throw new B("binary_file",`cannot edit binary file: ${e}`,{hint:"edit() works on text files only"});if(r.length===0)throw new B("parse_error",`oldText must be a non-empty string for edit on ${e}`,{hint:"empty oldText would match at position 0 and silently prepend newText"});let a=await this.deps.lowFs.readTextFile({path:e,limit:Number.POSITIVE_INFINITY,line:0}),c=a.content;await h0(e,o.ino);let d=c.indexOf(r);if(d===-1){let f=r.length>80?r.slice(0,80)+"\u2026":r;throw new B("parse_error",`oldText not found in ${e}`,{hint:`edit() expects oldText to appear verbatim; searched for: ${JSON.stringify(f)}`})}let u=c.slice(0,d)+n+c.slice(d+r.length),l=Buffer.byteLength(u,"utf-8");Yt(l),await m0(e),await this.deps.lowFs.writeTextFile({path:e,content:u,_meta:a._meta});let p=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return this.deps.audit.recordAccess(this.deps.ctx,{intent:"edit",absolute:e,durationMs:performance.now()-i,sizeBytes:l,matchedIgnore:p.ignored?p.category:void 0}),{writtenBytes:l}}catch(o){throw this.recordAndWrap(o,"edit",e)}}recordAndWrap(e,r,n){let s=wg(e);return this.deps.audit.recordDenied(this.deps.ctx,{intent:r,input:n,errorKind:s.kind,hint:s.hint,message:s.message,pattern:r==="glob"?n:void 0}),s}},MI=/^sha256:[0-9a-f]{64}$/;function wr(t){return typeof t=="string"&&MI.test(t)}var id=class{tails=new Map;async runExclusive(e,r){let n=this.tails.get(e)??Promise.resolve(),s,i=new Promise(a=>{s=a}),o=n.catch(()=>{}).then(()=>i);this.tails.set(e,o),await n.catch(()=>{});try{return await r()}finally{s(),this.tails.get(e)===o&&this.tails.delete(e)}}};function OI(t){if(t.mode!=="create"&&t.mode!=="replace")throw new B("parse_error",'mode must be either "create" or "replace" (use writeTextOverwrite() for unconditional overwrites)');if(t.expectedHash!==void 0&&!wr(t.expectedHash))throw new B("parse_error","expectedHash must match sha256:<64 lowercase hex chars>");if(t.mode==="replace"&&t.expectedHash===void 0)throw new B("parse_error",'expectedHash is required when mode is "replace"');if(t.lineEnding!==void 0&&t.lineEnding!=="lf"&&t.lineEnding!=="crlf")throw new B("parse_error",'lineEnding must be "lf" or "crlf"')}async function od(t,e={}){let r=await ve.lstat(t);if(r.isSymbolicLink())throw new B("symlink_escape",`path is a symlink: ${t}`,{hint:"re-resolve the target file instead of reading through a link"});if(!r.isFile())throw new B("parse_error",`path is not a regular file: ${t}`);if(r.size>Je)throw new B("file_too_large",`file of ${r.size} bytes exceeds read cap of ${Je} bytes`,{hint:"use readBytes for explicit byte-windowed access on large files"});let n=await DI(t,r);if(LI(n))throw new B("binary_file",`binary file: ${t}`,{hint:"use readBytes for binary content"});let s=Td(n),i=e.line!==void 0?e.line-1:0,o=FI(s.content,i,e.limit??Number.POSITIVE_INFINITY),a=Yc(n.length,e.maxBytes),c=o.content,d={encoding:s.encoding,bom:s.bom,lineEnding:Wi(c),sizeBytes:n.length,originalLineCount:o.originalLineCount,hash:cd(n)};if(a.truncated){let u=Buffer.from(c,"utf-8");u.length>a.bytesToRead&&(c=GI(u,a.bytesToRead).toString("utf-8"),d.lineEnding=Wi(c)),d.truncated=!0}return e.limit!==void 0&&Number.isFinite(e.limit)&&o.originalLineCount>e.limit+i&&(d.truncated=!0),{content:c,meta:d}}async function DI(t,e){let r=await ve.open(t,"r"),n;try{if(n=await r.stat(),jt(e,n,t,"read"),n.size>Je)throw new B("file_too_large",`file of ${n.size} bytes exceeds read cap of ${Je} bytes`,{hint:"use readBytes for explicit byte-windowed access on large files"});let s=Buffer.alloc(n.size),i=0;for(;i<n.size;){let c=await r.read(s,i,n.size-i,i);if(c.bytesRead===0)break;i+=c.bytesRead}let o=await r.stat();if(jt(n,o,t,"read"),o.size!==n.size||o.mtimeMs!==n.mtimeMs)throw new B("hash_mismatch",`file changed during read: ${t}`,{hint:"retry after re-reading the latest file hash"});let a=await ve.lstat(t);if(jt(e,a,t,"read"),a.size!==n.size||a.mtimeMs!==n.mtimeMs)throw new B("hash_mismatch",`file changed during read: ${t}`,{hint:"retry after re-reading the latest file hash"});return i===s.length?s:s.subarray(0,i)}finally{await r.close()}}function FI(t,e,r){let n=t.split(`
713
+ </html>`}w();w();import*as c0 from"node:path";var Je=256*1024,d0=5*1024*1024;function At(t,e,r,n="file"){let s=c0.relative(e,t);if(s===""||s.startsWith(".."))return{ignored:!1};let i=r.getFileFilter(),o=r.getDirectoryFilter();if(n==="directory"){let a=s.endsWith("/")?s:`${s}/`;return o(a)?{ignored:!0,category:"directory"}:i(s)?{ignored:!0,category:"file"}:{ignored:!1}}return i(s)?{ignored:!0,category:"file"}:o(s)?{ignored:!0,category:"directory"}:{ignored:!1}}function pt(t,e){if(!t)switch(e){case"read":case"list":case"glob":case"stat":return;case"write":case"edit":throw new B("untrusted_workspace",`workspace is not trusted; ${e} operations are forbidden`,{hint:"mark the folder as trusted in the daemon configuration to allow writes"});default:{let r=e;throw new B("untrusted_workspace",`workspace is not trusted; intent "${String(r)}" is not classified`,{hint:"unknown intent reached the trust gate; classify it in policy.ts"})}}}function Yc(t,e=Je){return t<=e?{bytesToRead:t,truncated:!1}:{bytesToRead:e,truncated:!0}}function Yt(t,e=d0){if(t>e)throw new B("file_too_large",`payload of ${t} bytes exceeds write limit of ${e} bytes`,{hint:"split the write into smaller chunks or raise the daemon limit"})}async function Qc(t){return Pd(t)}w();import{createHash as RI}from"node:crypto";import*as Qt from"node:path";var Zc="fs.access",ed="fs.denied";function u0(t){return RI("sha256").update(t).digest("hex").slice(0,16)}var CI="<cross-drive>";function l0(t,e){let r=Qt.isAbsolute(t)?Qt.relative(e,t):t;return Qt.isAbsolute(r)?CI:r}function TI(){return process.env.MATILDA_AUDIT_RAW_PATHS==="1"}function td(t){let e=t.includeRawPaths??TI(),{emit:r,boundWorkspace:n}=t;return{recordAccess(s,i){let o=String(i.absolute),a={kind:Zc,intent:i.intent,route:s.route,pathHash:u0(o),durationMs:i.durationMs};s.sessionId&&(a.sessionId=s.sessionId),i.sizeBytes!==void 0&&(a.sizeBytes=i.sizeBytes),i.truncated&&(a.truncated=!0),i.matchedIgnore&&(a.matchedIgnore=i.matchedIgnore),i.pattern!==void 0&&e&&(a.pattern=i.pattern),e&&(a.relPath=l0(o,n)),r({v:1,type:Zc,data:a,originatorClientId:s.originatorClientId})},recordDenied(s,i){let o=Qt.isAbsolute(i.input)?i.input:Qt.resolve(n,i.input),a={kind:ed,intent:i.intent,route:s.route,pathHash:u0(o),errorKind:i.errorKind};s.sessionId&&(a.sessionId=s.sessionId),i.hint&&(a.hint=i.hint),i.message&&e&&(a.message=i.message),i.pattern!==void 0&&e&&(a.pattern=i.pattern),e&&(a.relPath=l0(i.input,n)),r({v:1,type:ed,data:a,originatorClientId:s.originatorClientId})}}}w();import{createHash as v0,randomBytes as PI}from"node:crypto";import{promises as ve}from"node:fs";import*as Xe from"node:path";function ad(t){let e=Ye(t.boundWorkspace),r=t.ignore??bu({projectRoot:e,useGitignore:!0,useMatildaignore:!0,ignoreDirs:[]});Object.freeze(r);let n=td({emit:t.emit,boundWorkspace:e,includeRawPaths:t.includeRawPaths}),s=new hu,i=new id;return{forRequest(o){return new sd({boundWorkspace:e,trusted:t.trusted,ignore:r,audit:n,ctx:o,lowFs:s,pathLocks:i})}}}var sd=class{constructor(e){this.deps=e}async resolve(e,r){try{return await Mc(e,this.deps.boundWorkspace,r)}catch(n){throw this.recordAndWrap(n,r,e)}}async stat(e){let r=performance.now();try{pt(this.deps.trusted,"stat");let n=await ve.lstat(e),s={kind:g0(n),sizeBytes:n.size,modifiedMs:n.mtimeMs};return this.deps.audit.recordAccess(this.deps.ctx,{intent:"stat",absolute:e,durationMs:performance.now()-r,sizeBytes:n.size}),s}catch(n){throw this.recordAndWrap(n,"stat",e)}}async readText(e,r={}){let n=performance.now();try{if(pt(this.deps.trusted,"read"),r.line!==void 0&&(!Number.isSafeInteger(r.line)||r.line<1))throw new B("parse_error",`line must be a positive integer, got ${r.line}`);let s=await od(e,r),i=At(e,this.deps.boundWorkspace,this.deps.ignore,"file"),o=s.meta;return i.ignored&&(o.matchedIgnore=i.category),this.deps.audit.recordAccess(this.deps.ctx,{intent:"read",absolute:e,durationMs:performance.now()-n,sizeBytes:o.sizeBytes,truncated:o.truncated,matchedIgnore:o.matchedIgnore}),{content:s.content,meta:o}}catch(s){throw this.recordAndWrap(s,"read",e)}}async readBytes(e,r={}){return(await this.readBytesWindow(e,r)).buffer}async readBytesWindow(e,r={}){let n=performance.now();try{pt(this.deps.trusted,"read");let s=r.offset??0,i=r.maxBytes??Je;if(!Number.isSafeInteger(s)||s<0)throw new B("parse_error",`offset must be a non-negative integer, got ${s}`);if(!Number.isSafeInteger(i)||i<1||i>Je)throw new B("parse_error",`maxBytes must be a positive integer in [1, ${Je}], got ${i}`);let o=await ve.lstat(e);if(!o.isFile())throw new B("parse_error",`path is not a regular file: ${e}`);let a=await ve.open(e,"r"),c,d;try{c=await a.stat(),jt(o,c,e,"read");let p=Math.max(0,c.size-s),f=Math.min(i,p);if(d=Buffer.allocUnsafe(f),f>0){let v=await a.read(d,0,f,s);d=v.bytesRead===f?d:d.subarray(0,v.bytesRead)}let g=await a.stat();if(jt(c,g,e,"read"),g.size!==c.size||g.mtimeMs!==c.mtimeMs)throw new B("hash_mismatch",`file changed during read: ${e}`,{hint:"retry after re-reading the latest file hash"})}finally{await a.close()}await h0(e,c.ino);let u=s===0&&d.length===c.size,l={buffer:d,sizeBytes:c.size,returnedBytes:d.length,offset:s,truncated:!u,...u?{hash:cd(d)}:{}};return this.deps.audit.recordAccess(this.deps.ctx,{intent:"read",absolute:e,durationMs:performance.now()-n,sizeBytes:d.length,truncated:l.truncated}),l}catch(s){throw this.recordAndWrap(s,"read",e)}}async list(e,r={}){let n=performance.now();try{pt(this.deps.trusted,"list");let s=[],i=await ve.opendir(e);for await(let o of i){let a=Xe.join(e,o.name),c=g0(o),d=At(a,this.deps.boundWorkspace,this.deps.ignore,c==="directory"?"directory":"file");if(!(d.ignored&&!r.includeIgnored)&&(s.push({name:o.name,kind:c,ignored:d.ignored}),r.maxEntries!==void 0&&s.length>=r.maxEntries))break}return this.deps.audit.recordAccess(this.deps.ctx,{intent:"list",absolute:e,durationMs:performance.now()-n,sizeBytes:s.length,truncated:r.maxEntries!==void 0&&s.length>=r.maxEntries}),s}catch(s){throw this.recordAndWrap(s,"list",e)}}async glob(e,r={}){let n=performance.now();try{if(pt(this.deps.trusted,"glob"),e.split(/[\\/]/).some(p=>p===".."))throw new B("parse_error",`glob pattern may not contain '..' segments: ${e}`);if(Xe.isAbsolute(e)||/^[A-Za-z]:[\\/]/.test(e)||e.startsWith("\\\\")||e.startsWith("//"))throw new B("parse_error",`glob pattern must be workspace-relative: ${e}`,{hint:'pass a relative pattern such as "src/**/*.ts"'});let s=r.cwd??this.deps.boundWorkspace,i;if(s===this.deps.boundWorkspace)i=s;else try{i=await ve.realpath(Xe.resolve(s))}catch(p){throw p?.code==="ENOENT"?new B("path_not_found",`glob cwd does not exist: ${s}`,{cause:p}):p}if(!xr(i,this.deps.boundWorkspace))throw new B("path_outside_workspace",`glob cwd is outside workspace: ${s}`,{hint:"opts.cwd must be a path obtained from fs.resolve()"});let o=await pu(e,{cwd:i,nodir:!1,absolute:!0,dot:!0,ignore:["**/node_modules/**","**/.git/**"]}),a=[],c=r.maxResults??Number.POSITIVE_INFINITY,d=0,u=0,l=0;for(let p of o){if(a.length>=c)break;let f=Xe.resolve(p),g;try{g=await ve.realpath(f)}catch(q){let U=q?.code;U==="ENOENT"||U==="ELOOP"?d+=1:U==="EACCES"||U==="EPERM"?u+=1:l+=1;continue}let v=Xe.relative(this.deps.boundWorkspace,g);if(v.startsWith("..")||Xe.isAbsolute(v)){d+=1;continue}let x=null;try{x=await ve.lstat(g)}catch{x=null}let O=x?.isDirectory()?"directory":"file";At(g,this.deps.boundWorkspace,this.deps.ignore,O).ignored&&!r.includeIgnored||a.push(g)}return d>0&&this.deps.audit.recordDenied(this.deps.ctx,{intent:"glob",input:e,errorKind:"symlink_escape",hint:`glob filtered ${d} hit(s) that resolved outside workspace`,pattern:e}),u>0&&this.deps.audit.recordDenied(this.deps.ctx,{intent:"glob",input:e,errorKind:"permission_denied",hint:`glob skipped ${u} hit(s) due to EACCES/EPERM`,pattern:e}),l>0&&this.deps.audit.recordDenied(this.deps.ctx,{intent:"glob",input:e,errorKind:"io_error",hint:`glob skipped ${l} hit(s) due to transient I/O errors (EIO/EBUSY/ENAMETOOLONG/EMFILE)`,pattern:e}),this.deps.audit.recordAccess(this.deps.ctx,{intent:"glob",absolute:this.deps.boundWorkspace,durationMs:performance.now()-n,sizeBytes:a.length,pattern:e}),a}catch(s){throw this.recordAndWrap(s,"glob",e)}}async writeTextAtomic(e,r,n){let s=performance.now();try{pt(this.deps.trusted,"write"),OI(n);let i=Buffer.byteLength(r,"utf-8");return Yt(i),await this.deps.pathLocks.runExclusive(e,async()=>{let a=n.mode==="replace"?await p0(e,n.expectedHash):void 0;n.mode==="create"&&await y0(e);let c=rd(a,n),d=await nd({target:e,content:r,mode:n.mode,expectedHash:n.expectedHash,meta:c}),u=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return u.ignored&&(c.matchedIgnore=u.category),c.sizeBytes=d.sizeBytes,c.hash=d.hash,this.deps.audit.recordAccess(this.deps.ctx,{intent:"write",absolute:e,durationMs:performance.now()-s,sizeBytes:d.sizeBytes,matchedIgnore:c.matchedIgnore}),{created:n.mode==="create",sizeBytes:d.sizeBytes,hash:d.hash,meta:c}})}catch(i){throw this.recordAndWrap(i,"write",e)}}async writeTextOverwrite(e,r,n={}){let s=performance.now();try{pt(this.deps.trusted,"write");let i=Buffer.byteLength(r,"utf-8");return Yt(i),await this.deps.pathLocks.runExclusive(e,async()=>{let a=!1;try{await ve.lstat(e),a=!0}catch(p){if(p?.code!=="ENOENT")throw p}let c;try{c=await p0(e)}catch(p){let f=p?.code,g=p?.kind;if(f!=="ENOENT"&&f!=="EACCES"&&f!=="EPERM"&&g!=="file_too_large"&&g!=="binary_file")throw p}let d=rd(c,n),u=await nd({target:e,content:r,mode:"overwrite",meta:d}),l=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return l.ignored&&(d.matchedIgnore=l.category),d.sizeBytes=u.sizeBytes,d.hash=u.hash,this.deps.audit.recordAccess(this.deps.ctx,{intent:"write",absolute:e,durationMs:performance.now()-s,sizeBytes:u.sizeBytes,matchedIgnore:d.matchedIgnore}),{created:!a,sizeBytes:u.sizeBytes,hash:u.hash,meta:d}})}catch(i){throw this.recordAndWrap(i,"write",e)}}async writeText(e,r,n){let s=performance.now();try{pt(this.deps.trusted,"write");let i=Buffer.byteLength(r,"utf-8");Yt(i),await m0(e),await this.deps.lowFs.writeTextFile({path:e,content:r,_meta:n?w0(n):void 0});let o=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");this.deps.audit.recordAccess(this.deps.ctx,{intent:"write",absolute:e,durationMs:performance.now()-s,sizeBytes:i,matchedIgnore:o.ignored?o.category:void 0})}catch(i){throw this.recordAndWrap(i,"write",e)}}async editAtomic(e,r,n,s){let i=performance.now();try{if(pt(this.deps.trusted,"edit"),!wr(s.expectedHash))throw new B("parse_error","expectedHash must match sha256:<64 lowercase hex chars>");if(typeof r!="string"||r.length===0)throw new B("parse_error",`oldText must be a non-empty string for edit on ${e}`);if(typeof n!="string")throw new B("parse_error","newText must be a string");return await this.deps.pathLocks.runExclusive(e,async()=>{let a=await od(e);if(a.meta.hash!==s.expectedHash)throw new B("hash_mismatch",`expected ${s.expectedHash}, found ${a.meta.hash}`,{hint:"re-read the file and retry with the latest hash"});let c=a.content,d=zI(c,r);if(d===0){let v=r.length>80?r.slice(0,80)+"...":r;throw new B("text_not_found",`oldText not found in ${e}`,{hint:`searched for: ${JSON.stringify(v)}`})}if(d>1)throw new B("ambiguous_text_match",`oldText appears ${d} times in ${e}`,{hint:"pass a larger oldText span that occurs exactly once"});let u=c.indexOf(r),l=c.slice(0,u)+n+c.slice(u+r.length);Yt(Buffer.byteLength(l,"utf-8"));let p=rd(a.meta,{}),f=await nd({target:e,content:l,mode:"replace",expectedHash:s.expectedHash,meta:p}),g=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return g.ignored&&(p.matchedIgnore=g.category),p.sizeBytes=f.sizeBytes,p.hash=f.hash,this.deps.audit.recordAccess(this.deps.ctx,{intent:"edit",absolute:e,durationMs:performance.now()-i,sizeBytes:f.sizeBytes,matchedIgnore:p.matchedIgnore}),{writtenBytes:f.sizeBytes,hash:f.hash,meta:p}})}catch(o){throw this.recordAndWrap(o,"edit",e)}}async edit(e,r,n,s){if(s?.expectedHash!==void 0)return this.editAtomic(e,r,n,{expectedHash:s.expectedHash});let i=performance.now();try{pt(this.deps.trusted,"edit");let o=await ve.stat(e);if(o.size>Je)throw new B("file_too_large",`file of ${o.size} bytes exceeds edit cap of ${Je} bytes`,{hint:"split large edits into bounded readBytes/writeText sequences"});if(await Qc(e))throw new B("binary_file",`cannot edit binary file: ${e}`,{hint:"edit() works on text files only"});if(r.length===0)throw new B("parse_error",`oldText must be a non-empty string for edit on ${e}`,{hint:"empty oldText would match at position 0 and silently prepend newText"});let a=await this.deps.lowFs.readTextFile({path:e,limit:Number.POSITIVE_INFINITY,line:0}),c=a.content;await h0(e,o.ino);let d=c.indexOf(r);if(d===-1){let f=r.length>80?r.slice(0,80)+"\u2026":r;throw new B("parse_error",`oldText not found in ${e}`,{hint:`edit() expects oldText to appear verbatim; searched for: ${JSON.stringify(f)}`})}let u=c.slice(0,d)+n+c.slice(d+r.length),l=Buffer.byteLength(u,"utf-8");Yt(l),await m0(e),await this.deps.lowFs.writeTextFile({path:e,content:u,_meta:a._meta});let p=At(e,this.deps.boundWorkspace,this.deps.ignore,"file");return this.deps.audit.recordAccess(this.deps.ctx,{intent:"edit",absolute:e,durationMs:performance.now()-i,sizeBytes:l,matchedIgnore:p.ignored?p.category:void 0}),{writtenBytes:l}}catch(o){throw this.recordAndWrap(o,"edit",e)}}recordAndWrap(e,r,n){let s=wg(e);return this.deps.audit.recordDenied(this.deps.ctx,{intent:r,input:n,errorKind:s.kind,hint:s.hint,message:s.message,pattern:r==="glob"?n:void 0}),s}},MI=/^sha256:[0-9a-f]{64}$/;function wr(t){return typeof t=="string"&&MI.test(t)}var id=class{tails=new Map;async runExclusive(e,r){let n=this.tails.get(e)??Promise.resolve(),s,i=new Promise(a=>{s=a}),o=n.catch(()=>{}).then(()=>i);this.tails.set(e,o),await n.catch(()=>{});try{return await r()}finally{s(),this.tails.get(e)===o&&this.tails.delete(e)}}};function OI(t){if(t.mode!=="create"&&t.mode!=="replace")throw new B("parse_error",'mode must be either "create" or "replace" (use writeTextOverwrite() for unconditional overwrites)');if(t.expectedHash!==void 0&&!wr(t.expectedHash))throw new B("parse_error","expectedHash must match sha256:<64 lowercase hex chars>");if(t.mode==="replace"&&t.expectedHash===void 0)throw new B("parse_error",'expectedHash is required when mode is "replace"');if(t.lineEnding!==void 0&&t.lineEnding!=="lf"&&t.lineEnding!=="crlf")throw new B("parse_error",'lineEnding must be "lf" or "crlf"')}async function od(t,e={}){let r=await ve.lstat(t);if(r.isSymbolicLink())throw new B("symlink_escape",`path is a symlink: ${t}`,{hint:"re-resolve the target file instead of reading through a link"});if(!r.isFile())throw new B("parse_error",`path is not a regular file: ${t}`);if(r.size>Je)throw new B("file_too_large",`file of ${r.size} bytes exceeds read cap of ${Je} bytes`,{hint:"use readBytes for explicit byte-windowed access on large files"});let n=await DI(t,r);if(LI(n))throw new B("binary_file",`binary file: ${t}`,{hint:"use readBytes for binary content"});let s=Td(n),i=e.line!==void 0?e.line-1:0,o=FI(s.content,i,e.limit??Number.POSITIVE_INFINITY),a=Yc(n.length,e.maxBytes),c=o.content,d={encoding:s.encoding,bom:s.bom,lineEnding:Hi(c),sizeBytes:n.length,originalLineCount:o.originalLineCount,hash:cd(n)};if(a.truncated){let u=Buffer.from(c,"utf-8");u.length>a.bytesToRead&&(c=GI(u,a.bytesToRead).toString("utf-8"),d.lineEnding=Hi(c)),d.truncated=!0}return e.limit!==void 0&&Number.isFinite(e.limit)&&o.originalLineCount>e.limit+i&&(d.truncated=!0),{content:c,meta:d}}async function DI(t,e){let r=await ve.open(t,"r"),n;try{if(n=await r.stat(),jt(e,n,t,"read"),n.size>Je)throw new B("file_too_large",`file of ${n.size} bytes exceeds read cap of ${Je} bytes`,{hint:"use readBytes for explicit byte-windowed access on large files"});let s=Buffer.alloc(n.size),i=0;for(;i<n.size;){let c=await r.read(s,i,n.size-i,i);if(c.bytesRead===0)break;i+=c.bytesRead}let o=await r.stat();if(jt(n,o,t,"read"),o.size!==n.size||o.mtimeMs!==n.mtimeMs)throw new B("hash_mismatch",`file changed during read: ${t}`,{hint:"retry after re-reading the latest file hash"});let a=await ve.lstat(t);if(jt(e,a,t,"read"),a.size!==n.size||a.mtimeMs!==n.mtimeMs)throw new B("hash_mismatch",`file changed during read: ${t}`,{hint:"retry after re-reading the latest file hash"});return i===s.length?s:s.subarray(0,i)}finally{await r.close()}}function FI(t,e,r){let n=t.split(`
714
714
  `),s=n.length,i=Math.min(e+r,s),o=Math.min(e,s);return{content:n.slice(o,i).join(`
715
- `),originalLineCount:s}}function LI(t){if(t.length===0)return!1;let e=t.subarray(0,Math.min(4,t.length));if(e.length>=4&&(e[0]===255&&e[1]===254&&e[2]===0&&e[3]===0||e[0]===0&&e[1]===0&&e[2]===254&&e[3]===255)||e.length>=3&&e[0]===239&&e[1]===187&&e[2]===191||e.length>=2&&(e[0]===255&&e[1]===254||e[0]===254&&e[1]===255))return!1;let n=Math.min(4096,t.length),s=0;for(let i=0;i<n;i++){if(t[i]===0)return!0;(t[i]<9||t[i]>13&&t[i]<32)&&s++}return s/n>.3}async function p0(t,e){let r=await od(t);if(e!==void 0&&r.meta.hash!==e)throw new B("hash_mismatch",`expected ${e}, found ${r.meta.hash}`,{hint:"re-read the file and retry with the latest hash"});return r.meta}function rd(t,e){return{encoding:e.encoding??t?.encoding??"utf-8",bom:e.bom??t?.bom??!1,lineEnding:e.lineEnding??t?.lineEnding??"lf"}}async function nd(t){let e=t.target,r=Xe.dirname(e),n=await ve.lstat(r);if(n.isSymbolicLink())throw new B("symlink_escape",`parent path is a symlink: ${r}`,{hint:"re-resolve the target after detecting parent-symlink swaps"});if(!n.isDirectory())throw new B("parse_error",`parent path is not a directory: ${r}`);let s=Xe.join(r,`.${Xe.basename(e)}.${process.pid}.${PI(6).toString("hex")}.tmp`),i=!1,o,a;try{o=await NI(s),i=!0;let c=await $I({targetPath:e,tmpPath:s,content:t.content,meta:t.meta,handle:o});a=c.stat;let d=await BI({target:e,mode:t.mode,expectedHash:t.expectedHash});return await HI(o,d.mode??384),await f0(s,a),await o.close(),o=void 0,await f0(s,a),t.mode==="create"?await UI(s,e):await VI(s,e,3,50),i=!1,await WI(r),c}catch(c){if(await o?.close().catch(()=>{}),i)try{await ve.unlink(s)}catch{}throw c}}async function NI(t){return ve.open(t,"wx",384)}async function $I(t){let e=au(t.targetPath,t.content,w0(t.meta));Yt(e.length),await t.handle.writeFile(e),await jI(t.handle);let r=await ve.lstat(t.tmpPath),n=await t.handle.stat();if(jt(n,r,t.tmpPath,"write"),r.isSymbolicLink())throw new B("symlink_escape",`temporary path became a symlink: ${t.tmpPath}`,{hint:"temp-file race detected before final rename"});if(!r.isFile())throw new B("parse_error",`temporary path is not a regular file: ${t.tmpPath}`);return{sizeBytes:e.length,hash:cd(e),stat:r}}async function y0(t){try{throw(await ve.lstat(t)).isSymbolicLink()?new B("symlink_escape",`path is a symlink and cannot be created over: ${t}`,{hint:"remove the symlink or resolve the target explicitly"}):new B("file_already_exists",`file already exists: ${t}`)}catch(e){if(e?.code==="ENOENT")return;throw e}}async function BI(t){if(t.mode==="create")return await y0(t.target),{};if(t.mode==="overwrite"){let n;try{n=await ve.lstat(t.target)}catch(s){if(s?.code==="ENOENT")return{};throw s}if(n.isSymbolicLink())throw new B("symlink_escape",`path is a symlink and cannot be overwritten atomically: ${t.target}`,{hint:"re-resolve the target file instead of writing through a link"});if(!n.isFile())throw new B("parse_error",`path is not a regular file: ${t.target}`);return{mode:n.mode&4095}}if(!wr(t.expectedHash))throw new B("parse_error",'expectedHash is required when mode is "replace"');let e=await ve.lstat(t.target);if(e.isSymbolicLink())throw new B("symlink_escape",`path is a symlink and cannot be replaced atomically: ${t.target}`,{hint:"re-resolve the target file instead of writing through a link"});if(!e.isFile())throw new B("parse_error",`path is not a regular file: ${t.target}`);let r=await qI(t.target,e);if(r!==t.expectedHash)throw new B("hash_mismatch",`expected ${t.expectedHash}, found ${r}`,{hint:"re-read the file and retry with the latest hash"});return{mode:e.mode&4095}}async function qI(t,e){let r=await ve.open(t,"r"),n=v0("sha256"),s;try{s=await r.stat(),jt(e,s,t,"read");let o=Buffer.allocUnsafe(64*1024),a=0;for(;a<s.size;){let c=await r.read(o,0,Math.min(o.length,s.size-a),a);if(c.bytesRead===0)break;n.update(o.subarray(0,c.bytesRead)),a+=c.bytesRead}}finally{await r.close()}if(s===void 0)throw new B("internal_error",`failed to stat opened file: ${t}`);let i=await ve.lstat(t);if(jt(e,i,t,"read"),i.size!==s.size||i.mtimeMs!==s.mtimeMs)throw new B("hash_mismatch",`file changed during hash: ${t}`,{hint:"retry after re-reading the latest file hash"});return`sha256:${n.digest("hex")}`}function cd(t){return`sha256:${v0("sha256").update(t).digest("hex")}`}function jt(t,e,r,n){let s=Xr(t.dev),i=Xr(e.dev),o=Xr(t.ino),a=Xr(e.ino);if(s!==0n&&i!==0n&&o!==0n&&a!==0n&&(s!==i||o!==a))throw new B("symlink_escape",`path changed during ${n}: ${r}`,{hint:"TOCTOU swap detected via device/inode comparison"})}function Xr(t){return typeof t=="bigint"?t:BigInt(t)}async function jI(t){try{await t.sync()}catch{}}async function WI(t){let e;try{e=await ve.open(t,"r"),await e.sync()}catch{}finally{await e?.close().catch(()=>{})}}async function HI(t,e){try{await t.chmod(e)}catch{}}async function f0(t,e){let r=await ve.lstat(t);if(r.isSymbolicLink())throw new B("symlink_escape",`temporary path is a symlink: ${t}`,{hint:"temp-file race detected before final rename"});if(!r.isFile())throw new B("parse_error",`temporary path is not a regular file: ${t}`);jt(e,r,t,"write")}async function UI(t,e){try{await ve.link(t,e)}catch(r){throw r?.code==="EEXIST"?new B("file_already_exists",`file already exists: ${e}`):r}await ve.unlink(t).catch(()=>{})}async function VI(t,e,r,n){for(let s=0;s<=r;s++)try{await ve.rename(t,e);return}catch(i){let o=i?.code;if(!(o==="EPERM"||o==="EACCES")||s===r)throw i;await new Promise(c=>setTimeout(c,n*2**s))}}function zI(t,e){let r=0,n=0;for(;;){let s=t.indexOf(e,n);if(s===-1)return r;r+=1,n=s+e.length}}function GI(t,e){if(t.length<=e)return t;let r=e;for(;r>0&&(t[r]&192)===128;)r--;return t.subarray(0,r)}async function h0(t,e){let r=await ve.lstat(t);if(r.isSymbolicLink())throw new B("symlink_escape",`path was replaced with a symlink during read: ${t}`,{hint:"TOCTOU swap detected via post-read lstat"});let n=Xr(e),s=Xr(r.ino);if(n!==0n&&s!==0n&&n!==s)throw new B("symlink_escape",`path inode changed during read: ${t}`,{hint:"TOCTOU swap detected via inode comparison"})}async function m0(t){let e;try{e=await ve.lstat(t)}catch(r){if(r?.code==="ENOENT")return;throw r}if(e.isSymbolicLink())throw new B("symlink_escape",`path was replaced with a symlink before write: ${t}`,{hint:"TOCTOU swap detected via pre-write lstat \u2014 re-resolve before retrying"})}function g0(t){return t.isSymbolicLink()?"symlink":t.isDirectory()?"directory":t.isFile()?"file":"other"}function w0(t){let e={};return t.bom!==void 0&&(e.bom=t.bom),t.encoding&&(e.encoding=t.encoding),t.lineEnding&&(e.lineEnding=t.lineEnding),Object.keys(e).length>0?e:void 0}w();import*as $n from"node:path";var dd=2e3,b0=2e3,KI=64*1024,JI=5e3,S0=5e4;function Pe(t){t.set("Cache-Control","no-store"),t.set("X-Content-Type-Options","nosniff")}function Zt(t,e,r){if(Pe(t),Pc(e)){let n=e;t.status(n.status).json({errorKind:n.kind,error:n.message,hint:n.hint,status:n.status});return}D(`matilda serve: ${r} unexpected error: ${e instanceof Error?e.message:String(e)}`),t.status(500).json({errorKind:"internal_error",error:e instanceof Error?e.message:String(e),status:500})}function Yr(t,e,r){if(t===void 0)return;if(typeof t!="string"||!/^\d+$/.test(t))return null;let n=Number.parseInt(t,10);return!Number.isSafeInteger(n)||n<e||n>r?null:n}function E0(t){return t==="1"||t==="true"}function Bn(t,e,r,n){return typeof e!="string"||e.length===0?(Pe(t),t.status(400).json({errorKind:"parse_error",error:`${r} query parameter is required`,status:400}),D(`matilda serve: ${n} rejected request missing required ?${r}`),null):e}function qn(t,e){let r=t.app.locals.fsFactory;return r||(Pe(e),e.status(500).json({errorKind:"internal_error",error:"workspace filesystem factory is not configured",status:500}),null)}async function XI(t,e,r){let n="GET /file",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=Yr(t.query.maxBytes,1,256*1024);if(a===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:"`maxBytes` must be a positive integer in [1, 262144]",status:400});return}let c=Yr(t.query.line,1,Number.MAX_SAFE_INTEGER);if(c===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:"`line` must be a positive integer",status:400});return}let d=Yr(t.query.limit,1,b0);if(d===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:`\`limit\` must be a positive integer in [1, ${b0}]`,status:400});return}let u=s.forRequest({originatorClientId:i??void 0,route:n});try{let l=await u.resolve(o,"read"),p=await u.readText(l,{maxBytes:a,line:c,limit:d}),f=Buffer.byteLength(p.content,"utf-8");Pe(e),e.status(200).json({kind:"file",path:er(t,l),content:p.content,encoding:p.meta.encoding??"utf-8",bom:p.meta.bom===!0,lineEnding:p.meta.lineEnding,sizeBytes:p.meta.sizeBytes??f,returnedBytes:f,truncated:p.meta.truncated===!0,hash:p.meta.hash,matchedIgnore:p.meta.matchedIgnore??null,originalLineCount:p.meta.originalLineCount??null})}catch(l){Zt(e,l,n)}}async function YI(t,e,r){let n="GET /file/bytes",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=Yr(t.query.offset,0,Number.MAX_SAFE_INTEGER);if(a===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:"`offset` must be a non-negative safe integer",status:400});return}let c=Yr(t.query.maxBytes,1,Je);if(c===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:`\`maxBytes\` must be a positive integer in [1, ${Je}]`,status:400});return}let d=s.forRequest({originatorClientId:i??void 0,route:n});try{let u=await d.resolve(o,"read"),l=await d.readBytesWindow(u,{offset:a??0,maxBytes:c??KI});Pe(e),e.status(200).json({kind:"file_bytes",path:er(t,u),offset:l.offset,sizeBytes:l.sizeBytes,returnedBytes:l.returnedBytes,truncated:l.truncated,contentBase64:l.buffer.toString("base64"),...l.hash?{hash:l.hash}:{}})}catch(u){Zt(e,u,n)}}async function QI(t,e,r){let n="GET /stat",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=s.forRequest({originatorClientId:i??void 0,route:n});try{let c=await a.resolve(o,"stat"),d=await a.stat(c);Pe(e),e.status(200).json({kind:"stat",path:er(t,c),type:d.kind,sizeBytes:d.sizeBytes,modifiedMs:d.modifiedMs})}catch(c){Zt(e,c,n)}}async function ZI(t,e,r){let n="GET /list",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=E0(t.query.includeIgnored),c=s.forRequest({originatorClientId:i??void 0,route:n});try{let d=await c.resolve(o,"list"),u=await c.list(d,{includeIgnored:a,maxEntries:dd+1}),l=!1,p=u;p.length>dd&&(p=p.slice(0,dd),l=!0),Pe(e),e.status(200).json({kind:"list",path:er(t,d),entries:p,truncated:l,matchedIgnore:null})}catch(d){Zt(e,d,n)}}async function ex(t,e,r){let n="GET /glob",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.pattern,"pattern",n);if(o===null)return;let a=E0(t.query.includeIgnored),c=Yr(t.query.maxResults,1,S0);if(c===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:`\`maxResults\` must be a positive integer in [1, ${S0}]`,status:400});return}let d=t.query.cwd,u=typeof d=="string"&&d.length>0?d:void 0,l=s.forRequest({originatorClientId:i??void 0,route:n}),p=performance.now();try{let f=u?await l.resolve(u,"list"):void 0,g=c??JI,v=await l.glob(o,{cwd:f,includeIgnored:a,maxResults:g+1}),x=v.length>g,P=(x?v.slice(0,g):v).map(q=>er(t,q));Pe(e),e.status(200).json({kind:"glob",pattern:o,cwd:u??"",matches:P,count:P.length,truncated:x,durationMs:Math.round(performance.now()-p)})}catch(f){Zt(e,f,n)}}function er(t,e){let r=t.app.locals.boundWorkspace;if(!r)throw new Error("bound workspace is not configured");let n=$n.relative(r,e);return n===""?".":$n.sep==="/"?n:n.split($n.sep).join("/")}function I0(t,e){t.get("/file",(r,n)=>XI(r,n,e)),t.get("/file/bytes",(r,n)=>YI(r,n,e)),t.get("/stat",(r,n)=>QI(r,n,e)),t.get("/list",(r,n)=>ZI(r,n,e)),t.get("/glob",(r,n)=>ex(r,n,e))}w();function x0(t,e){let r=t.app.locals.fsFactory;return r||(Pe(e),e.status(500).json({errorKind:"internal_error",error:"workspace filesystem factory is not configured",status:500}),null)}function Rt(t,e,r){return Pe(t),t.status(400).json({errorKind:"parse_error",error:r,status:400}),null}function _0(t,e,r,n){let s=t[e];return typeof s!="string"||s.length===0?Rt(r,n,`\`${e}\` must be a non-empty string`):s}function tx(t,e,r,n){let s=t[e];if(s!==void 0)return typeof s!="boolean"?Rt(r,n,`\`${e}\` must be a boolean`):s}function rx(t,e,r,n){let s=t[e];if(s!==void 0)return typeof s!="string"||s.length===0?Rt(r,n,`\`${e}\` must be a non-empty string`):s}function nx(t,e,r){let n=t.lineEnding;if(n!==void 0)return n!=="crlf"&&n!=="lf"?Rt(e,r,'`lineEnding` must be "lf" or "crlf"'):n}function k0(t,e,r){let n=t.expectedHash;return wr(n)?n:Rt(e,r,"`expectedHash` must match sha256:<64 lowercase hex chars>")}function sx(t,e,r){let n=t.expectedHash;if(n!==void 0)return wr(n)?n:Rt(e,r,"`expectedHash` must match sha256:<64 lowercase hex chars>")}function A0(t,e,r){if(t!==void 0)return e.bridge.knownClientIds().has(t)?t:(Pe(r),r.status(400).json({error:`Client id "${t}" is not registered for this workspace`,code:"invalid_client_id",clientId:t}),null)}async function ix(t,e,r){let n="POST /file/write",s=x0(t,e);if(!s)return;let i=r.safeBody(t),o=_0(i,"path",e,n);if(o===null)return;let a=i.content;if(typeof a!="string"){Rt(e,n,"`content` must be a string");return}let c=i.mode;if(c!=="create"&&c!=="replace"){Rt(e,n,'`mode` must be "create" or "replace"');return}let d=c,u=d==="replace"?k0(i,e,n):sx(i,e,n);if(u===null)return;let l=tx(i,"bom",e,n);if(l===null)return;let p=rx(i,"encoding",e,n);if(p===null)return;let f=nx(i,e,n);if(f===null)return;let g=r.parseClientId(t,e);if(g===null)return;let v=A0(g,r,e);if(v===null)return;let x=s.forRequest({originatorClientId:v,route:n});try{let O=await x.resolve(o,"write"),P=await x.writeTextAtomic(O,a,{mode:d,...u?{expectedHash:u}:{},...l!==void 0?{bom:l}:{},...p!==void 0?{encoding:p}:{},...f!==void 0?{lineEnding:f}:{}});Pe(e),e.status(P.created?201:200).json({kind:"file_write",path:er(t,O),mode:d,created:P.created,sizeBytes:P.sizeBytes,hash:P.hash,encoding:P.meta.encoding??"utf-8",bom:P.meta.bom===!0,lineEnding:P.meta.lineEnding,matchedIgnore:P.meta.matchedIgnore??null})}catch(O){Zt(e,O,n)}}async function ox(t,e,r){let n="POST /file/edit",s=x0(t,e);if(!s)return;let i=r.safeBody(t),o=_0(i,"path",e,n);if(o===null)return;let a=i.oldText;if(typeof a!="string"){Rt(e,n,"`oldText` must be a string");return}let c=i.newText;if(typeof c!="string"){Rt(e,n,"`newText` must be a string");return}let d=k0(i,e,n);if(d===null)return;let u=r.parseClientId(t,e);if(u===null)return;let l=A0(u,r,e);if(l===null)return;let p=s.forRequest({originatorClientId:l,route:n});try{let f=await p.resolve(o,"edit"),g=await p.editAtomic(f,a,c,{expectedHash:d});Pe(e),e.status(200).json({kind:"file_edit",path:er(t,f),replacements:1,sizeBytes:g.writtenBytes,hash:g.hash,encoding:g.meta?.encoding??"utf-8",bom:g.meta?.bom===!0,lineEnding:g.meta?.lineEnding??"lf",matchedIgnore:g.meta?.matchedIgnore??null})}catch(f){Zt(e,f,n)}}function R0(t,e){t.post("/file/write",e.mutate({strict:!0}),(r,n)=>ix(r,n,e)),t.post("/file/edit",e.mutate({strict:!0}),(r,n)=>ox(r,n,e))}w();import{promises as Qr,constants as C0}from"node:fs";import*as Ct from"node:path";async function P0(t){let e=t;for(;;)try{return await Qr.realpath(e)}catch(r){let n=r?.code;if(n!=="ENOENT"&&n!=="ENOTDIR"&&n!=="ELOOP")throw r;let s=Ct.dirname(e);if(s===e)throw r;e=s}}async function T0(t,e,r){let n=await P0(Ct.dirname(t));if(!(n===e||n.startsWith(e+Ct.sep)))throw new mt(t,"parent",`Workspace context file ${JSON.stringify(t)}'s parent moved outside the workspace between the pre-open canonicalize and the post-open verify (parent canonicalizes to ${JSON.stringify(n)}, workspace canonicalizes to ${JSON.stringify(e)}). Refusing to write \u2014 investigate the concurrent writer or the parent-directory permissions.`)}function Ri(t){let{boundWorkspace:e,contextFilename:r,statusProvider:n,isChannelLive:s,persistDisabledTools:i,queryWorkspaceStatus:o,invokeWorkspaceCommand:a,publishWorkspaceEvent:c}=t;return{async getWorkspaceMcpStatus(d){return o(ke.workspaceMcp,()=>Ji(e))},async getWorkspaceSkillsStatus(d){return o(ke.workspaceSkills,()=>Xi(e))},async getWorkspaceProvidersStatus(d){return o(ke.workspaceProviders,()=>Yi(e))},async getWorkspaceEnvStatus(d){let u=s?.()??!1;if(!n)return Qi(e,u);try{return await n.getEnvStatus(e,u)}catch(l){return D(`matilda serve: getEnvStatus failed: ${l instanceof Error?l.message:String(l)}`),Qi(e,u)}},async getWorkspacePreflightStatus(d){let u=s?.()??!1,l=Zi(),p=[];if(n)try{p=await n.getDaemonPreflightCells(e)}catch(v){D(`matilda serve: getDaemonPreflightCells failed: ${v instanceof Error?v.message:String(v)}`)}let f=l,g;if(u)try{let v=await o(ke.workspacePreflight,()=>({cells:l}));if(v&&"cells"in v){let x=v;f=x.cells.filter(O=>O.locality!=="daemon"),g=x.errors}}catch(v){f=l;let x=Mt(v);g=[{kind:"preflight",status:"error",error:v instanceof Error?v.message:String(v),...x?{errorKind:x}:{}}]}return{v:ot,workspaceCwd:e,initialized:!0,acpChannelLive:u,cells:[...p,...f],...g&&g.length>0?{errors:g}:{}}},async getWorkspaceHooksStatus(d){return o(ke.workspaceHooks,()=>pn(e))},async getWorkspaceExtensionsStatus(d){return o(ke.workspaceExtensions,()=>ln(e))},async setWorkspaceToolEnabled(d,u,l){return await i(e,u,l),c({type:"tool_toggled",data:{toolName:u,enabled:l},originatorClientId:d.originatorClientId}),{toolName:u,enabled:l}},async initWorkspace(d,u){let l=r,p=Ct.resolve(e,l);if(!(p===e||p.startsWith(e+Ct.sep)))throw new Mr(l,e);let g=await Qr.realpath(e),v=await P0(Ct.dirname(p));if(!(v===g||v.startsWith(g+Ct.sep)))throw new mt(p,"parent",`Configured workspace context filename ${JSON.stringify(l)} has a parent path that resolves outside the bound workspace (parent canonicalizes to ${JSON.stringify(v)}, workspace canonicalizes to ${JSON.stringify(g)}). Refusing to write \u2014 replace any symlinked parent directory with a real directory before re-running init.`);try{let P=await Qr.lstat(p);if(P.isSymbolicLink())throw new mt(p,"target",`Workspace context file ${JSON.stringify(p)} is a symlink. Refusing to follow it for write \u2014 replace the symlink with a regular file (or remove it) before re-running init.`);if(!P.isFile())throw new mt(p,"target",`Workspace context file ${JSON.stringify(p)} is not a regular file (mode=${P.mode.toString(8)}). Refusing to proceed \u2014 FIFOs, sockets, and device nodes can block or misbehave on read/write.`)}catch(P){if(P instanceof mt||P?.code!=="ENOENT")throw P}let O="created";try{let P=await Qr.readFile(p,"utf8");if(P.trim().length>0){let q=Buffer.byteLength(P,"utf8");if(u.force!==!0)throw new ar(p,q);O="overwrote"}else O="noop"}catch(P){if(P instanceof ar||P?.code!=="ENOENT")throw P}if(O==="created"){let P;try{P=await Qr.open(p,"wx")}catch(q){throw q?.code==="EEXIST"?new cr(p,"eexist",`Workspace context file ${JSON.stringify(p)} appeared between our absence check and the create \u2014 refusing to proceed (a regular file or symlink was just placed at the target path, and following it could escape the workspace).`):q}try{await T0(p,g,P),await P.writeFile("","utf8")}finally{await P.close()}}else if(O==="overwrote"){let P;try{P=await Qr.open(p,C0.O_WRONLY|(C0.O_NOFOLLOW??0))}catch(q){let U=q?.code;throw U==="ELOOP"?new mt(p,"target",`Workspace context file ${JSON.stringify(p)} could not be opened with O_NOFOLLOW (ELOOP); the path may have been swapped to a symlink between the content check and the overwrite. Refusing to follow it.`):U==="ENOENT"?new cr(p,"enoent",`Workspace context file ${JSON.stringify(p)} was deleted between the content check and the overwrite (likely a concurrent writer). Refusing to recreate blindly; rerun init.`):q}try{await T0(p,g,P),await P.truncate(0)}finally{await P.close()}}return c({type:"workspace_initialized",data:{path:p,action:O},originatorClientId:d.originatorClientId}),{path:p,action:O}},async restartMcpServer(d,u,l){let p={serverName:u};l?.entryIndex!==void 0&&(p.entryIndex=l.entryIndex);let f;try{f=await a(fe.workspaceMcpRestart,p,{timeoutMs:3e5})}catch(g){let v=g?.data;if(v&&typeof v=="object"){let x=v.errorKind,O=v.serverName;if(x==="mcp_server_not_found"&&typeof O=="string")throw new Or(O);if(x==="mcp_restart_failed"&&typeof O=="string"){let P=v.mcpStatus;throw new Dr(O,typeof P=="string"?P:"unknown")}}throw g}if("entries"in f){let g=Array.isArray(f.entries)?f.entries:[];Array.isArray(f.entries)||D(`matilda serve: pool restart response carried 'entries' field but it is not an array (server=${u}); treating as empty.`);for(let v of g){if(typeof v!="object"||v===null||typeof v.entryIndex!="number"){D(`matilda serve: skipping malformed pool restart entry (server=${u}): ${JSON.stringify(v)}`);continue}v.restarted?c({type:"mcp_server_restarted",data:{serverName:f.serverName,durationMs:v.durationMs??0,entryIndex:v.entryIndex},originatorClientId:d.originatorClientId}):c({type:"mcp_server_restart_refused",data:{serverName:f.serverName,reason:"restart_failed",entryIndex:v.entryIndex,...v.reason?{details:v.reason}:{}},originatorClientId:d.originatorClientId})}}else f.restarted===!0?c({type:"mcp_server_restarted",data:{serverName:f.serverName,durationMs:f.durationMs},originatorClientId:d.originatorClientId}):c({type:"mcp_server_restart_refused",data:{serverName:f.serverName,reason:f.reason},originatorClientId:d.originatorClientId});return f},async reload(d){if(t.reloadDaemonEnv)try{await t.reloadDaemonEnv(e)}catch(x){D(`matilda serve: daemon reload failed: ${x instanceof Error?x.message:String(x)}`)}let u=!1,l={updatedKeys:[],removedKeys:[]},p=[],f,g,v;try{let x=await a(fe.workspaceReload,{cwd:e},{timeoutMs:3e4});u=!0,l=x.env,p=x.changedKeys,f=x.sessionsRefreshed,g=x.sessionsSkipped}catch(x){x instanceof ie?v="ACP child not running":(v=x instanceof Error?x.message:String(x),D(`matilda serve: reload failed: ${v}`))}return c({type:"settings_reloaded",data:{env:l,changedKeys:p,childReloaded:u,sessionsRefreshed:f,sessionsSkipped:g,childError:v},originatorClientId:d.originatorClientId}),{env:l,changedKeys:p,childReloaded:u,sessionsRefreshed:f,sessionsSkipped:g,childError:v}}}}w();var cx=new Set(["general.vimMode","general.terminalBell","general.preferredEditor","general.outputLanguage","ide.enabled","ui.showLineNumbers","ui.renderMode","ui.useTerminalBuffer","ui.hideBanner","ui.accessibility.enableLoadingPhrases","ui.enableWelcomeBack"]),dx=new Set(["ui.compactMode"]),ud=new Set(["workspace"]),M0=1024,ux=new Set(["tools.approvalMode"]);function lx(){let t=new Set(Iu().filter(e=>!cx.has(e)&&!ux.has(e)));for(let e of dx)t.add(e);return t}function px(t,e){let r=Tt(t),n=[];for(let i of e){let o=Ui(i);if(!o)continue;let a=ns(r.merged,i),c=ns(r.user.settings,i),d=ns(r.workspace.settings,i),u={effective:a!==void 0?a:o.default};c!==void 0&&(u.user=c),d!==void 0&&(u.workspace=d),n.push({key:i,type:o.type,label:o.label,category:o.category,...o.description?{description:o.description}:{},requiresRestart:o.requiresRestart,default:o.default,...o.options?.length?{options:o.options}:{},values:u})}let s=[];return r.corruptedPath&&s.push({type:"corrupted",recovered:r.wasRecovered}),{v:1,...s.length?{warnings:s}:{},settings:n}}function fx(t,e){switch(t.type){case"boolean":if(typeof e!="boolean")return"Value must be a boolean";break;case"number":if(typeof e!="number"||!Number.isFinite(e))return"Value must be a finite number";break;case"string":if(typeof e!="string")return"Value must be a string";if(e.length>M0)return`Value exceeds ${M0}-character limit`;break;case"enum":if(!t.options?.some(r=>r.value===e))return`Value must be one of: ${t.options?.map(n=>n.value).join(", ")??""}`;break;default:return`Settings of type '${t.type}' cannot be modified via this API`}}var hx={workspace:"Workspace"};function O0(t,e){let{boundWorkspace:r,mutate:n,safeBody:s,persistSetting:i,broadcastSettingsChanged:o,parseAndValidateClientId:a}=e,c=lx();t.get("/workspace/settings",(d,u)=>{try{let l=px(r,c);u.status(200).json(l)}catch(l){D(`matilda serve: GET /workspace/settings error: ${l instanceof Error?l.message:String(l)}`),u.status(500).json({error:"Failed to load settings",code:"internal_error"})}}),t.post("/workspace/settings",n({strict:!0}),async(d,u)=>{let l=s(d),p=l.scope,f=l.key,g=l.value;if(typeof p!="string"||!ud.has(p)){u.status(400).json({error:`scope must be one of: ${[...ud].join(", ")}`,code:"invalid_scope"});return}if(typeof f!="string"||!f){u.status(400).json({error:"key is required and must be a string",code:"invalid_key"});return}if(!c.has(f)){u.status(400).json({error:`Setting "${f}" is not modifiable via this API`,code:"disallowed_key"});return}if(g==null){u.status(400).json({error:"value is required",code:"missing_value"});return}let v=Ui(f);if(!v){u.status(400).json({error:`Unknown setting: ${f}`,code:"unknown_key"});return}let x=fx(v,g);if(x){u.status(400).json({error:x,code:"invalid_value"});return}let O=a(d,u);if(O!==null){try{let P=hx[p];if(!P){u.status(400).json({error:`scope must be one of: ${[...ud].join(", ")}`,code:"invalid_scope"});return}await i(r,P,f,g)}catch(P){D(`matilda serve: POST /workspace/settings persist error (key=${f}, scope=${p}, workspace=${r}): ${P instanceof Error?P.message:String(P)}`),u.status(500).json({error:"Failed to persist setting",code:"persist_error"});return}try{o(f,g,p,O)}catch(P){D(`matilda serve: POST /workspace/settings broadcast error (key=${f}, scope=${p}): ${P instanceof Error?P.message:String(P)}`)}u.status(200).json({key:f,scope:p,value:g,requiresRestart:v.requiresRestart})}})}w();import*as F0 from"node:fs/promises";import*as L0 from"node:path";var mx="application/a2ui+json",gx="action",D0=15e3;function N0(t){return!!t&&(typeof t.command=="string"||typeof t.httpUrl=="string")}async function vx(t){try{let e=await F0.readFile(L0.join(t,".matilda","settings.json"),"utf8"),r=JSON.parse(e);for(let[n,s]of Object.entries(r.mcpServers??{}))if(n.toLowerCase().includes("a2ui")&&N0(s))return s}catch{}return null}function yx(t){return typeof t.httpUrl=="string"?new uu(new URL(t.httpUrl)):new lu({command:t.command,args:t.args??[],...t.env?{env:{...process.env,...t.env}}:{},cwd:t.cwd})}function wx(t){if(t.isError){let n=(t.content??[]).filter(s=>s.type==="text"&&typeof s.text=="string").map(s=>s.text).join("");throw new Error(`a2ui action tool returned error: ${n||"unknown error"}`)}let e=null,r="";for(let n of t.content??[])if(e===null&&n.type==="resource"&&n.resource?.mimeType===mx&&typeof n.resource.text=="string")try{let s=JSON.parse(n.resource.text);Array.isArray(s)&&(e=s)}catch{}else n.type==="text"&&typeof n.text=="string"&&(r+=n.text);return{commands:e,fallback:r}}async function bx(t,e){let r=yx(t),n=new du({name:"matilda-serve-a2ui",version:"0.0.1"});try{await n.connect(r,{timeout:D0});let s=await n.callTool({name:gx,arguments:{...e}},void 0,{timeout:D0});return wx(s)}finally{await r.close().catch(()=>{}),await n.close().catch(()=>{})}}function $0(t,e){let{boundWorkspace:r,mutate:n,safeBody:s,getMcpServers:i}=e,o=e.callAction??bx;t.post("/session/:id/a2ui-action",n(),async(a,c)=>{let d=s(a),u=d.name;if(typeof u!="string"||u.trim().length===0){c.status(400).json({error:"`name` is required"});return}let l=typeof d.surfaceId=="string"?d.surfaceId:void 0,p=d.context&&typeof d.context=="object"&&!Array.isArray(d.context)?d.context:void 0,f=null;try{let g=(await i(a)).filter(x=>x.name.toLowerCase().includes("a2ui")&&N0(x.config));f=(g.find(x=>x.mcpStatus==="connected")??g[0])?.config??null}catch{}if(f||(f=await vx(r)),!f){c.status(503).json({error:"no a2ui MCP server found (neither runtime-registered nor in workspace settings mcpServers)"});return}try{let{commands:g,fallback:v}=await o(f,{name:u.trim(),surfaceId:l,context:p});c.status(200).json({commands:g,fallback:v})}catch(g){D(`a2ui-action proxy failed: ${g instanceof Error?g.message:String(g)}`),c.status(502).json({error:"a2ui action call failed"})}})}w();var Sx=1e4,Ex=1e3,Ix=5*60*1e3;function xx(t,e){let r=e.endsWith("/")&&e.length>1?e.slice(0,-1):e;return t==="OPTIONS"||(t==="GET"||t==="HEAD")&&(r==="/health"||r==="/demo")||t==="POST"&&r.startsWith("/session/")&&r.endsWith("/heartbeat")||t==="GET"&&r.startsWith("/session/")&&r.endsWith("/events")||r==="/acp"||r.startsWith("/acp/")?null:t==="POST"&&r.startsWith("/session/")&&r.endsWith("/prompt")?"prompt":t!=="GET"&&t!=="HEAD"?"mutation":"read"}var _x=128,kx=/^[A-Za-z0-9._:-]+$/;function Ax(t){return t.startsWith("::ffff:")?t.slice(7):t}function Rx(t){let e=_t(t);return r=>{let n=r.get("x-matilda-client-id"),s=n&&n.length<=_x&&kx.test(n)?n:void 0;if(e)return s?`cid:${s}`:"anonymous";let i=Ax(r.socket?.remoteAddress??"unknown");return s?`${i}:${s}`:i}}var Cx=100;function Tx(t){let e=new Map;return{log(r,n){let s=`${r}:${n}`,i=e.get(s);i||(i={count:0,suppressed:0},e.set(s,i)),i.count++,i.count===1||i.count%Cx===0?(t(r,n,i.suppressed),i.suppressed=0):i.suppressed++},clear(){e.clear()}}}function B0(t){for(let[p,f]of Object.entries(t.tiers)){if(!Number.isFinite(f.max)||f.max<=0)throw new Error(`rate limit: ${p}.max must be a positive number, got ${f.max}`);if(!Number.isFinite(f.windowMs)||f.windowMs<=0)throw new Error(`rate limit: ${p}.windowMs must be a positive number, got ${f.windowMs}`)}let e=new Map,r=Rx(t.hostname),n={prompt:0,mutation:0,read:0},s={prompt:t.tiers.prompt.max/t.tiers.prompt.windowMs,mutation:t.tiers.mutation.max/t.tiers.mutation.windowMs,read:t.tiers.read.max/t.tiers.read.windowMs},i=!1,o=0,a=t.onLimitReached?Tx(t.onLimitReached):void 0;function c(){let p=Date.now();for(let[f,g]of e){let v=!0;for(let[x,O]of g)if(p-O.lastRefill<t.tiers[x].windowMs*2){v=!1;break}v&&e.delete(f)}}let d=setInterval(c,Ix);d.unref();let u=(p,f,g)=>{try{if(i){g();return}let v=xx(p.method,p.path);if(v===null){g();return}o++,o%Ex===0&&c();let x=r(p);if(l(x,v))g();else{let O=t.tiers[v],P=s[v],q=e.get(x)?.get(v),U=Math.ceil((1-(q?.tokens??0))/P),ae=Math.ceil(U/1e3);f.setHeader("Retry-After",String(ae)),f.setHeader("X-RateLimit-Limit",String(O.max)),f.setHeader("X-RateLimit-Remaining","0"),f.setHeader("X-RateLimit-Reset",String(Math.ceil((Date.now()+U)/1e3))),f.status(429).json({error:"Rate limit exceeded",code:"rate_limit_exceeded",tier:v,retryAfterMs:U})}}catch(v){t.onError?.(v,p.path),g()}};function l(p,f){if(i)return!0;let g=t.tiers[f],v=s[f],x=Date.now(),O=e.get(p);if(!O){if(e.size>=Sx)return t.onError?.(new Error(`rate limit bucket overflow: ${e.size} keys`),`tryConsume:${f}`),!0;O=new Map,e.set(p,O)}let P=O.get(f);P||(P={tokens:g.max,lastRefill:x},O.set(f,P));let q=Math.max(0,x-P.lastRefill);return P.tokens=Math.min(g.max,P.tokens+q*v),P.lastRefill=x,P.tokens>=1?(P.tokens-=1,!0):(n[f]++,a&&a.log(f,p),!1)}return{middleware:u,checkRate:l,reset(){e.clear(),n.prompt=0,n.mutation=0,n.read=0,o=0,a?.clear()},setDraining(p){i=p},dispose(){clearInterval(d),e.clear(),a?.clear()},getHitCounts(){return{...n}}}}var q0="_rateLimiter";function j0(t,e){t.locals[q0]=e}function W0(t){return t.locals[q0]}var vd=0;function wd(){return vd}var Px="MATILDA_CODE_BENCHMARK_API",Mx=1e3,H0=2e5;function Ox(){let e=0;return r=>{if(e+=1,e===1||e%100===0){let n=r.data,s=[];n?.errorKind&&s.push(`errorKind=${n.errorKind}`),n?.intent&&s.push(`intent=${n.intent}`),n?.pathHash&&s.push(`pathHash=${n.pathHash}`);let i=s.length>0?` (${s.join(" ")})`:"";D(`matilda serve: fs audit emit is the default no-op \u2014 ${e} event(s) dropped so far. Latest type=${r.type}${i}. Inject deps.fsFactory in createServeApp to wire audit into the EventBus.`)}}}var U0=!1;function bd(t){return t.injected?t.injected:ad({boundWorkspace:t.boundWorkspace,trusted:t.trusted,emit:t.emit??Ox()})}var Dx=20,Fx=100,Jr=class extends Error{constructor(e){super(`Invalid cursor: "${e}" is not a valid numeric cursor`),this.name="InvalidCursorError"}};async function Uc(t,e,r){let n=Math.min(Math.max(r?.size??Dx,1),Fx),s;if(r?.cursor){let p=Number(r.cursor);if(!Number.isFinite(p))throw new Jr(r.cursor);s=p}let i=s===void 0,o=new kr(e),a=await o.listSessions({cursor:s,size:n}),c=new Map;for(let p of a.items)c.set(p.sessionId,{sessionId:p.sessionId,workspaceCwd:p.cwd,createdAt:p.startTime,updatedAt:new Date(p.mtime).toISOString(),title:p.customTitle??p.prompt,clientCount:0,hasActivePrompt:!1});let d=t.listWorkspaceSessions(e);for(let p of d){let f=c.get(p.sessionId);f?c.set(p.sessionId,{...f,...p,createdAt:f.createdAt,title:p.title??f.title,updatedAt:p.updatedAt??f.updatedAt,clientCount:p.clientCount,hasActivePrompt:p.hasActivePrompt}):i&&!await o.sessionExists(p.sessionId)&&c.set(p.sessionId,{...p,createdAt:p.createdAt,clientCount:p.clientCount,hasActivePrompt:p.hasActivePrompt})}let u=[...c.values()].sort((p,f)=>{let g=Date.parse(p.updatedAt??p.createdAt);return Date.parse(f.updatedAt??f.createdAt)-g}),l=a.nextCursor!=null?String(a.nextCursor):void 0;return{sessions:u,nextCursor:l}}var Lx=["protocol","baseUrl","apiKey","models","advancedConfig"];function Nx(t){let e=Lx.filter(r=>yu(t,r));return{id:t.id,label:t.label,description:t.description,...t.uiGroup?{uiGroup:t.uiGroup}:{},protocol:t.protocol,...t.protocolOptions?{protocolOptions:[...t.protocolOptions]}:{},...t.baseUrl!==void 0?{baseUrl:t.baseUrl}:{},...typeof t.envKey=="string"?{envKey:t.envKey}:{},...t.models?{models:t.models.map(r=>({id:r.id,...r.contextWindowSize!==void 0?{contextWindowSize:r.contextWindowSize}:{},...r.enableThinking!==void 0?{enableThinking:r.enableThinking}:{},...r.modalities?{modalities:r.modalities}:{},...r.description?{description:r.description}:{}}))}:{},...t.modelsEditable!==void 0?{modelsEditable:t.modelsEditable}:{},...t.apiKeyPlaceholder?{apiKeyPlaceholder:t.apiKeyPlaceholder}:{},...typeof t.documentationUrl=="string"?{documentationUrl:t.documentationUrl}:{},...t.showAdvancedConfig!==void 0?{showAdvancedConfig:t.showAdvancedConfig}:{},...t.uiLabels?{uiLabels:t.uiLabels}:{},steps:e}}function $x(t){let e=Hi.map(Nx),r=n=>e.filter(s=>s.uiGroup===n).map(s=>s.id);return{v:1,workspaceCwd:t,providers:e,groups:[{id:"third-party",label:"Third-party Providers",description:"Choose a built-in provider and connect with an API key",providerIds:r("third-party")},{id:"custom",label:"Custom Provider",description:"Manually connect a local server, proxy, or unsupported provider",providerIds:r("custom")}]}}function Bx(t){if(!Array.isArray(t))return;let e=t.map(r=>typeof r=="string"?r.trim():"").filter(r=>r.length>0);return e.length>0?[...new Set(e)]:void 0}function V0(t,e){if(!(typeof t!="number"||!Number.isInteger(t)||!Number.isFinite(t)||t<=0||t>e))return t}function qx(t){let e=t.split(":");if(e.length!==2)return;let[r,n]=e;if(!/^[0-9a-f]{1,4}$/i.test(r)||!/^[0-9a-f]{1,4}$/i.test(n))return;let s=Number.parseInt(r,16),i=Number.parseInt(n,16);return`${s>>8&255}.${s&255}.${i>>8&255}.${i&255}`}function jx(t){let e=t.split(":",1)[0];if(!(!e||!/^[0-9a-f]{1,4}$/i.test(e)))return Number.parseInt(e,16)}function yd(t){let r=(t.endsWith(".")?t.slice(0,-1):t).toLowerCase();if(r==="localhost"||r.endsWith(".localhost"))return!0;let n=r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,s=md.isIP(n);if(s===4){let i=n.split(".").map(c=>Number(c)),[o,a]=i;return o===0||o===10||o===127||o===100&&a!==void 0&&a>=64&&a<=127||o===169&&a===254||o===172&&a!==void 0&&a>=16&&a<=31||o===192&&a===168}if(s===6){if(n==="::"||n==="::1")return!0;let i=jx(n);if(i!==void 0&&(i>=65152&&i<=65215||(i&65024)===64512))return!0;if(n.startsWith("::ffff:")){let o=n.slice(7);if(md.isIP(o)===4)return yd(o);let a=qx(o);return a?yd(a):!0}}return!1}function Wx(t,e){if(t==null)return;if(typeof t!="string")return null;let r=t.trim();if(!r)return;let n;try{n=new URL(r)}catch{return null}return n.protocol!=="http:"&&n.protocol!=="https:"||n.username||n.password||!e&&yd(n.hostname)?null:n.toString().replace(/\/$/,"")}function Hx(t,e){let r=t.providerId,n=t.apiKey;if(typeof r!="string"||r.trim().length===0||typeof n!="string"||n.trim().length===0)return{ok:!1,code:"invalid_request",error:"`providerId` and `apiKey` are required"};let s=t.protocol,i=Wx(t.baseUrl,e?.allowPrivateBaseUrl===!0);if(i===null)return{ok:!1,code:"invalid_base_url",error:"`baseUrl` must be an http(s) URL without credentials or blocked private-network host"};let o=Bx(t.modelIds),a=t.advancedConfig&&typeof t.advancedConfig=="object"?t.advancedConfig:void 0,c=a?.multimodal&&typeof a.multimodal=="object"?a.multimodal:void 0,d=V0(a?.contextWindowSize,1e7),u=V0(a?.maxTokens,1e7),l=a?{...typeof a.enableThinking=="boolean"?{enableThinking:a.enableThinking}:{},...c?{multimodal:{...typeof c.image=="boolean"?{image:c.image}:{},...typeof c.pdf=="boolean"?{pdf:c.pdf}:{},...typeof c.audio=="boolean"?{audio:c.audio}:{},...typeof c.video=="boolean"?{video:c.video}:{}}}:{},...d!==void 0?{contextWindowSize:d}:{},...u!==void 0?{maxTokens:u}:{}}:void 0;return{ok:!0,value:{providerId:r.trim(),...typeof s=="string"&&s.trim()?{protocol:s.trim()}:{},...i?{baseUrl:i}:{},apiKey:n,...o?{modelIds:o}:{},...l?{advancedConfig:l}:{}}}}function Ux(t){let e=t.path.replace(/\/$/,"")||"/";if(t.method==="POST"&&e==="/session")return{route:"POST /session"};if(t.method==="POST"&&e==="/sessions/delete")return{route:"POST /sessions/delete"};if(t.method==="GET"&&e==="/daemon/status")return{route:"GET /daemon/status"};let r=e.match(/^\/session\/([^/]+)\/(load|resume|prompt|cancel|recap|btw|mid-turn-message|model|shell|detach|rewind|approval-mode|language|a2ui-action)$/),n=r?.[1],s=r?.[2];if(n&&s&&t.method==="POST")return{route:`POST /session/:id/${s}`,sessionId:n};let i=e.match(/^\/session\/([^/]+)\/metadata$/);if(i?.[1]&&t.method==="PATCH")return{route:"PATCH /session/:id/metadata",sessionId:i[1]};let o=e.match(/^\/session\/([^/]+)\/permission\/([^/]+)$/);if(o?.[1]&&o?.[2]&&t.method==="POST"){let g=o[2];return{route:"POST /session/:id/permission/:requestId",sessionId:o[1],...g.length<=Pi&&Mi.test(g)?{permissionRequestId:g}:{}}}let a=e.match(/^\/permission\/([^/]+)$/);if(a?.[1]&&t.method==="POST"){let g=a[1];return{route:"POST /permission/:requestId",...g.length<=Pi&&Mi.test(g)?{permissionRequestId:g}:{}}}let d=e.match(/^\/session\/([^/]+)$/)?.[1];if(d&&t.method==="DELETE")return{route:"DELETE /session/:id",sessionId:d};if(t.method==="GET"&&/^\/workspace\/[^/]+\/sessions$/.test(e))return{route:"GET /workspace/:id/sessions"};if(t.method==="POST"&&e==="/workspace/init")return{route:"POST /workspace/init"};if(t.method==="POST"&&e==="/workspace/reload")return{route:"POST /workspace/reload"};if(e.match(/^\/workspace\/mcp\/([^/]+)\/restart$/)?.[1]&&t.method==="POST")return{route:"POST /workspace/mcp/:server/restart"};if(t.method==="POST"&&e==="/workspace/mcp/servers")return{route:"POST /workspace/mcp/servers"};if(e.match(/^\/workspace\/mcp\/servers\/([^/]+)$/)?.[1]&&t.method==="DELETE")return{route:"DELETE /workspace/mcp/servers/:name"};if(t.method==="POST"&&e==="/workspace/auth/device-flow")return{route:"POST /workspace/auth/device-flow"};if(e.match(/^\/workspace\/auth\/device-flow\/([^/]+)$/)?.[1]&&t.method==="DELETE")return{route:"DELETE /workspace/auth/device-flow/:id"};if(e.match(/^\/workspace\/tools\/([^/]+)\/enable$/)?.[1]&&t.method==="POST")return{route:"POST /workspace/tools/:name/enable"};if(e==="/workspace/settings"){if(t.method==="GET")return{route:"GET /workspace/settings"};if(t.method==="POST")return{route:"POST /workspace/settings"}}}function Vx(t){let e=Yn(t);return(r,n,s)=>{let i=Ux(r);if(!i){s();return}let o=r.get(Q0),a=o!==void 0&&o!==""&&o.length<=Pi&&Mi.test(o)?o:void 0,c=Date.now();Ld({method:r.method,route:i.route,workspaceHash:e,...i.sessionId?{sessionId:i.sessionId}:{},...i.permissionRequestId?{permissionRequestId:i.permissionRequestId}:{},...a?{clientId:a}:{}},async d=>await new Promise((u,l)=>{let p=!1,f=()=>{p||(p=!0,Nd(d,n.statusCode),Wd(Date.now()-c,i.route,n.statusCode),u())};n.once("finish",f),n.once("close",f);try{s()}catch(g){qi(d,g),l(g)}})).catch(s)}}var Ti=class extends Error{deadlineMs;constructor(e){super(`prompt exceeded the ${e}ms deadline`),this.name="PromptDeadlineExceededError",this.deadlineMs=e}};function z0(t,e){if(!(t===void 0||!Number.isFinite(t)||t<=0))return e===void 0||!Number.isFinite(e)||e<=0?t:Math.min(t,e)}var zx=5;function Gx(t){return t===void 0?zx:t===0||t===Number.POSITIVE_INFINITY?null:t}function Sd(t,e=()=>t.port,r={}){let n=(0,gd.default)(),s=r.boundWorkspace??Ye(t.workspace??process.cwd());!r.fsFactory&&!r.bridge&&!U0&&(U0=!0,process.stderr.write(`matilda serve: createServeApp default fsFactory uses trusted=false \u2014 agent ACP writeTextFile calls will reject with untrusted_workspace. Inject deps.fsFactory (with explicit trust) or deps.bridge to override.
716
- `));let i=bd({boundWorkspace:s,injected:r.fsFactory,trusted:!1}),o=typeof t.token=="string"&&t.token.length>0,a=t.enableSessionShell===!0&&o,c=r.bridge??gr({maxSessions:t.maxSessions,maxPendingPromptsPerSession:t.maxPendingPromptsPerSession,eventRingSize:t.eventRingSize,boundWorkspace:s,sessionShellCommandEnabled:a,statusProvider:Mn(),fileSystem:pi(i)}),d=-1,u=new Set;n.use((b,h,y)=>{let A=b.headers.origin;if(A){let k=e();k!==d&&(d=k,u=new Set([`http://127.0.0.1:${k}`,`http://localhost:${k}`,`http://[::1]:${k}`,`http://host.docker.internal:${k}`])),u.has(A)&&delete b.headers.origin}y()}),n.locals.fsFactory=i,n.locals.boundWorkspace=s;let l=new Map;for(let b of r.deviceFlowProviders??[])l.set(b.providerId,b);l.has("matilda-oauth")||l.set("matilda-oauth",new li);let p={publish(b,h){c.publishWorkspaceEvent({type:`auth_device_flow_${b.type}`,data:b.data,...h?{originatorClientId:h}:{}})}},f=r.deviceFlowRegistry??new ni({events:p,audit:{record(b){let h=b.deviceFlowId.slice(0,8),y=["[serve] auth.device-flow:",`provider=${b.providerId}`,`deviceFlowId=${h}...`,b.clientId?`clientId=${b.clientId}`:"clientId=-",`status=${b.status}`];if(b.errorKind&&y.push(`errorKind=${b.errorKind}`),b.expiresInMs!==void 0&&y.push(`expiresInMs=${Math.max(0,b.expiresInMs)}`),b.hint){let k=b.hint.length>1024?`${b.hint.slice(0,1024)}\u2026[+${b.hint.length-1024} bytes truncated]`:b.hint;y.push(`hint=${JSON.stringify(k)}`)}D(y.join(" "))}},resolveProvider:b=>l.get(b)});zm(n,f);let{daemonLog:g}=r,v=(b,h,y)=>Z0(b,h,y,g),x=(b,h,y)=>a_(b,h,y,g),O=r.workspace??Ri({boundWorkspace:s,contextFilename:r.contextFilename??"MATILDA.md",statusProvider:Mn(),isChannelLive:()=>c.isChannelLive(),persistDisabledTools:r.persistDisabledTools??(async()=>{throw new Error("setWorkspaceToolEnabled requires persistDisabledTools in ServeAppDeps")}),queryWorkspaceStatus:(b,h)=>c.queryWorkspaceStatus(b,h),invokeWorkspaceCommand:(b,h,y)=>c.invokeWorkspaceCommand(b,h,y),publishWorkspaceEvent:b=>c.publishWorkspaceEvent(b)});if(t.allowOrigins&&t.allowOrigins.length>0){let b=ti(t.allowOrigins);if(b.allowAny&&!t.token)throw new Error("Refusing to start with --allow-origin '*' but no bearer token configured. '*' admits any cross-origin browser to the API; without a token, any local page can drive the daemon. Set a token or list specific origins instead of '*'.");n.use(Wm(b))}else n.use(yc);n.use(wc(t.hostname,e));let P=(b,h)=>{try{h.type("html").set("X-Frame-Options","DENY").set("Content-Security-Policy","default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'").send(a0(e()))}catch(y){D(`matilda serve: /demo render failed: ${y instanceof Error?y.message:String(y)}`),h.status(500).json({error:"Failed to render demo page"})}},q=(b,h)=>{let y=b.query.deep;if(!(y==="1"||y==="true"||y==="")){h.status(200).json({status:"ok"});return}try{h.status(200).json({status:"ok",sessions:c.sessionCount,pendingPermissions:c.pendingPermissionCount,...le?{rateLimitHits:le.getHitCounts()}:{}})}catch(k){D(`matilda serve: /health deep probe failed: ${k instanceof Error?k.message:String(k)}`),h.status(503).json({status:"degraded"})}},ae=_t(t.hostname)&&!t.requireAuth;if(ae&&(n.get("/health",q),n.get("/demo",P)),g){let b=/\/session\/([^/]+)/;n.use((h,y,A)=>{let{method:k,path:S}=h;if(k==="GET"&&S==="/health"||k==="POST"&&S.endsWith("/heartbeat"))return A();let R=Date.now();y.on("finish",()=>{try{let F=y.statusCode;if(k==="GET"&&S.endsWith("/events")&&F===200)return;let H=Date.now()-R,X=S.match(b)?.[1],pe=h.headers["x-matilda-client-id"],de={route:`${k} ${S}`,...X?{sessionId:X}:{},...pe?{clientId:pe}:{},status:F,durationMs:H};F>=400?g.warn("request completed",de):g.info("request completed",de)}catch{}}),A()})}n.use(bc(t.token));let le;if(t.rateLimit){let b=t.rateLimitWindowMs??6e4;le=B0({tiers:{prompt:{windowMs:b,max:t.rateLimitPrompt??10},mutation:{windowMs:b,max:t.rateLimitMutation??30},read:{windowMs:b,max:t.rateLimitRead??120}},hostname:t.hostname,onLimitReached:g?(h,y,A)=>{g.warn(`rate limit hit${A>0?` (${A} suppressed)`:""}`,{tier:h,key:y.slice(0,64)})}:void 0,onError:g?(h,y)=>{g.warn(`rate limiter error (fail-open): ${h instanceof Error?h.message:String(h)}`,{path:y})}:void 0}),n.use(le.middleware)}n.use(gd.default.json({limit:"10mb"})),n.use((b,h,y,A)=>{G0(y,b)||A(b)}),ae||(n.get("/health",q),n.get("/demo",P));let V=Sc({tokenConfigured:o,requireAuth:t.requireAuth===!0});n.use(Vx(s));function Se(b,h,y){return{originatorClientId:y,route:h,workspaceCwd:s}}let Te=[...Eu.map(b=>b.code),"auto"],Ze=()=>ki(void 0,{requireAuth:t.requireAuth===!0,mcpPoolActive:t.mcpPoolActive!==!1,allowOriginActive:t.allowOrigins!==void 0&&t.allowOrigins.length>0,...t.promptDeadlineMs!==void 0?{promptDeadlineMs:t.promptDeadlineMs}:{},...t.writerIdleTimeoutMs!==void 0?{writerIdleTimeoutMs:t.writerIdleTimeoutMs}:{},persistSettingAvailable:r.persistSetting!==void 0,sessionShellCommandEnabled:a,rateLimit:t.rateLimit===!0,reloadAvailable:r.workspace!==void 0}),Me={};if(n.get("/daemon/status",async(b,h)=>{let y=r0(b.query.detail);if(!y.ok||!y.detail){h.status(400).json({error:"detail must be one of: summary, full",code:"invalid_detail"});return}try{h.status(200).json(await n0(y.detail,{opts:t,boundWorkspace:s,bridge:c,workspace:O,daemonLog:g,matildaCodeVersion:r.matildaCodeVersion,acpHandle:Me.current,rateLimiter:le,getRestSseActive:wd,features:Ze(),protocolVersions:Ai(),supportedDeviceFlowProviders:Array.from(l.keys()),deviceFlowRegistry:f,sessionShellCommandEnabled:a}))}catch(A){D(`matilda serve: /daemon/status failed: ${A instanceof Error?A.message:String(A)}`),h.status(500).json({error:"Failed to build daemon status",code:"daemon_status_failed"})}}),n.get("/capabilities",(b,h)=>{let y={v:Xc,protocolVersions:Ai(),...r.matildaCodeVersion?{matildaCodeVersion:r.matildaCodeVersion}:{},mode:t.mode,features:Ze(),modelServices:[],workspaceCwd:s,transports:["rest"],policy:{permission:c.permissionPolicy},limits:{maxPendingPromptsPerSession:Gx(t.maxPendingPromptsPerSession)},supportedLanguages:Te};h.status(200).json(y)}),n.get("/workspace/mcp",async(b,h)=>{try{let y=Se(b,"GET /workspace/mcp");h.status(200).json(await O.getWorkspaceMcpStatus(y))}catch(y){v(h,y,{route:"GET /workspace/mcp"})}}),n.get("/workspace/mcp/:server/tools",async(b,h)=>{let y=b.params.server;if(!y||typeof y!="string"){h.status(400).json({error:"Server name path parameter is required",code:"invalid_server_name"});return}if(y.length>rr){h.status(400).json({error:`Server name exceeds ${rr}-character limit`,code:"invalid_server_name"});return}try{h.status(200).json(await c.getWorkspaceMcpToolsStatus(y))}catch(A){v(h,A,{route:"GET /workspace/mcp/:server/tools"})}}),n.get("/workspace/skills",async(b,h)=>{try{let y=Se(b,"GET /workspace/skills");h.status(200).json(await O.getWorkspaceSkillsStatus(y))}catch(y){v(h,y,{route:"GET /workspace/skills"})}}),n.get("/workspace/tools",async(b,h)=>{try{h.status(200).json(await c.getWorkspaceToolsStatus())}catch(y){v(h,y,{route:"GET /workspace/tools"})}}),n.get("/workspace/providers",async(b,h)=>{try{let y=Se(b,"GET /workspace/providers");h.status(200).json(await O.getWorkspaceProvidersStatus(y))}catch(y){v(h,y,{route:"GET /workspace/providers"})}}),_g(n,{bridge:c,boundWorkspace:s,mutate:V,parseClientId:me,safeBody:we}),Dg(n,{bridge:c,boundWorkspace:s,mutate:V,parseClientId:me,safeBody:we}),n.get("/workspace/env",async(b,h)=>{try{let y=Se(b,"GET /workspace/env");h.status(200).json(await O.getWorkspaceEnvStatus(y))}catch(y){v(h,y,{route:"GET /workspace/env"})}}),n.get("/workspace/preflight",async(b,h)=>{try{let y=Se(b,"GET /workspace/preflight");h.status(200).json(await O.getWorkspacePreflightStatus(y))}catch(y){v(h,y,{route:"GET /workspace/preflight"})}}),n.get("/workspace/hooks",async(b,h)=>{try{let y=Se(b,"GET /workspace/hooks");h.status(200).json(await O.getWorkspaceHooksStatus(y))}catch(y){v(h,y,{route:"GET /workspace/hooks"})}}),n.get("/workspace/extensions",async(b,h)=>{try{let y=Se(b,"GET /workspace/extensions");h.status(200).json(await O.getWorkspaceExtensionsStatus(y))}catch(y){v(h,y,{route:"GET /workspace/extensions"})}}),I0(n,{parseClientId:me}),R0(n,{bridge:c,mutate:V,parseClientId:me,safeBody:we}),r.persistSetting){let b=r.persistSetting;O0(n,{boundWorkspace:s,mutate:V,safeBody:we,persistSetting:b,broadcastSettingsChanged:(h,y,A,k)=>{c.publishWorkspaceEvent({type:"settings_changed",data:{key:h,value:y,scope:A},...k?{originatorClientId:k}:{}})},parseAndValidateClientId:(h,y)=>tr(h,y,c)})}$0(n,{boundWorkspace:s,mutate:V,safeBody:we,getMcpServers:async b=>{let h=Se(b,"POST /session/:id/a2ui-action");return(await O.getWorkspaceMcpStatus(h)).servers??[]}}),n.post("/workspace/auth/device-flow",V({strict:!0}),async(b,h)=>{let A=we(b).providerId;if(typeof A!="string"||A.length===0){h.status(400).json({error:"`providerId` must be a non-empty string",code:"invalid_request"});return}if(!l.has(A)){h.status(400).json({error:`Unsupported device-flow provider: ${A}`,code:"unsupported_provider",supportedProviders:Array.from(l.keys())});return}let k=A,S=me(b,h);if(S!==null)try{let{view:R,attached:F}=await f.start({providerId:k,...S!==void 0?{initiatorClientId:S}:{}});h.status(F?200:201).json(r_(R,F,S))}catch(R){if(R instanceof hr){h.status(400).json({error:R.message,code:"unsupported_provider"});return}if(R instanceof mr){h.status(409).json({error:R.message,code:"too_many_active_flows"});return}if(R instanceof vt){h.status(502).json({error:R.message,code:"upstream_error"});return}v(h,R,{route:"POST /workspace/auth/device-flow"})}}),n.get("/workspace/auth/device-flow/:id",V({strict:!0}),async(b,h)=>{let y=b.params.id;if(!y){h.status(404).json({error:"Device-flow id required",code:"device_flow_not_found"});return}let A=f.get(y);if(!A){h.status(404).json({error:`Device-flow ${y} not found`,code:"device_flow_not_found"});return}let k=me(b,h);k!==null&&(!Ed(A,k)&&qt()&&D(`matilda serve debug: GET /workspace/auth/device-flow/${y} redacted verification fields \u2014 caller-clientId mismatch (initiator=${A.initiatorClientId??"anonymous"}, caller=${k??"anonymous"})`),h.status(200).json(n_(A,k)))}),n.delete("/workspace/auth/device-flow/:id",V({strict:!0}),(b,h)=>{let y=b.params.id;if(!y){h.status(404).json({error:"Device-flow id required",code:"device_flow_not_found"});return}let A=me(b,h);if(A===null)return;if(f.cancel(y,A)===void 0){h.status(404).json({error:`Device-flow ${y} not found`,code:"device_flow_not_found"});return}h.status(204).end()}),n.get("/workspace/auth/status",(b,h)=>{let y=f.listPending();h.status(200).json({v:1,workspaceCwd:s,providers:[],pendingDeviceFlows:y.map(A=>({deviceFlowId:A.deviceFlowId,providerId:A.providerId,...A.expiresAt!==void 0?{expiresAt:A.expiresAt}:{}})),supportedDeviceFlowProviders:Array.from(l.keys())})}),n.get("/workspace/auth/providers",(b,h)=>{h.status(200).json($x(s))}),process.env[Px]==="true"&&n.post("/benchmark/prompt",V({strict:!0}),async(b,h)=>{let y=we(b),A=Xx(y.prompt,h);if(A===void 0)return;let k=y.sessionId,S=typeof k=="string"&&k.length>0?k:void 0;if(k!==void 0&&S===void 0){h.status(400).json({error:"`sessionId` must be a non-empty string when provided",code:"invalid_session_id"});return}let R=y.deadlineMs,F;if(R!=null){if(typeof R!="number"||!Number.isFinite(R)||!Number.isInteger(R)||R<=0){h.status(400).json({error:"`deadlineMs` must be a positive integer (milliseconds)",code:"invalid_deadline_ms"});return}F=R}let H=me(b,h);if(H===null)return;let Z=H,X,pe,de=hd.randomUUID(),re=new AbortController,xe=z0(t.promptDeadlineMs,F),he;xe!==void 0&&(he=setTimeout(()=>{re.signal.aborted||re.abort(new Ti(xe))},xe),he.unref());let K=Date.now();try{let Y=!1;if(S===void 0){let ne=typeof y.modelServiceId=="string"?y.modelServiceId:void 0,ye=await c.spawnOrAttach({workspaceCwd:s,sessionScope:"thread",...ne!==void 0?{modelServiceId:ne}:{},...H!==void 0?{clientId:H}:{}});S=ye.sessionId,Z=ye.clientId,Y=!0,y.keepSession!==!0&&(X=ye.sessionId,pe=ye.clientId)}let Ee=c.getSessionLastEventId(S),et={text:"",eventCount:0},Oe=new AbortController,Fe=Zx(c,S,de,Ee,Oe.signal,et).catch(ne=>{if(!(ne instanceof DOMException&&(ne.name==="AbortError"||ne.name==="TimeoutError")))throw ne}),Le=await c.sendPrompt(S,{sessionId:S,prompt:A},re.signal,{...Z!==void 0?{clientId:Z}:{},promptId:de});await Promise.race([Fe,e_(Mx)]),Oe.abort(),h.status(200).json({v:1,sessionId:S,promptId:de,createdSession:Y,keptSession:X===void 0,latencyMs:Date.now()-K,text:et.text,stopReason:Le.stopReason,usage:Le.usage??null,eventCount:et.eventCount,terminalType:et.terminalType??null})}catch(Y){v(h,Y,{route:"POST /benchmark/prompt"})}finally{he!==void 0&&clearTimeout(he),re.abort(),X!==void 0&&c.closeSession(X,pe!==void 0?{clientId:pe}:void 0).catch(Y=>{D(`matilda serve: benchmark session cleanup failed for ${it(X)}: ${it(Y instanceof Error?Y.message:String(Y))}`)})}}),n.post("/workspace/auth/provider",V({strict:!0}),async(b,h)=>{if(!r.installAuthProvider){h.status(501).json({error:"Auth provider installation is not implemented by this daemon",code:"not_implemented"});return}let y=Hx(we(b),{allowPrivateBaseUrl:t.allowPrivateAuthBaseUrl===!0});if(!y.ok){h.status(400).json({error:y.error,code:y.code});return}let A=y.value,k=Hi.find(S=>S.id===A.providerId);if(!k){h.status(400).json({error:`Unsupported auth provider: ${A.providerId}`,code:"unsupported_provider"});return}if(A.protocol){let S=k.protocolOptions&&k.protocolOptions.length?k.protocolOptions:[k.protocol];if(!S.includes(A.protocol)){h.status(400).json({error:`protocol must be one of: ${S.join(", ")}`,code:"unsupported_protocol"});return}}try{h.status(200).json(await r.installAuthProvider(A))}catch(S){v(h,S,{route:"POST /workspace/auth/provider",providerId:A.providerId})}}),n.post("/session",V(),async(b,h)=>{let y=we(b),A="cwd"in y;if(A&&typeof y.cwd!="string"){h.status(400).json({error:"`cwd` must be a string absolute path when provided"});return}if(A&&y.cwd.length>wt){h.status(400).json({error:`\`cwd\` exceeds the ${wt}-character limit`});return}let k=A?y.cwd:s;if(!Ci.isAbsolute(k)){h.status(400).json({error:"`cwd` must be an absolute path when provided"});return}let S=typeof y.modelServiceId=="string"?y.modelServiceId:void 0,R=y.sessionScope,F;if(R!==void 0){if(R!=="single"&&R!=="thread"){h.status(400).json({error:'`sessionScope` must be "single" or "thread" when provided',code:"invalid_session_scope"});return}F=R}let H=me(b,h);if(H!==null)try{let Z=await c.spawnOrAttach({workspaceCwd:k,modelServiceId:S,...H!==void 0?{clientId:H}:{},...F!==void 0?{sessionScope:F}:{}});if(g&&g.info(Z.attached?"session attached":"session spawned",{sessionId:Z.sessionId,clientId:Z.clientId}),!h.writable){g&&g.warn("session reaped (client disconnected before response)",{sessionId:Z.sessionId,attached:Z.attached}),Z.attached?c.detachClient(Z.sessionId,Z.clientId).catch(()=>{}):c.killSession(Z.sessionId,{requireZeroAttaches:!0}).catch(()=>{});return}h.status(200).json(Z)}catch(Z){v(h,Z,{route:"POST /session"})}});let Ue=b=>async(h,y)=>{let A=st(h,y);if(!A)return;let k=we(h),S=t_(k,s,y);if(S===void 0)return;let R=me(h,y);if(R!==null)try{let F=b==="load"?await c.loadSession({sessionId:A,workspaceCwd:S,...R!==void 0?{clientId:R}:{}}):await c.resumeSession({sessionId:A,workspaceCwd:S,...R!==void 0?{clientId:R}:{}});if(g&&g.info(`session ${b}${F.attached?" (attached)":""}`,{sessionId:F.sessionId,clientId:F.clientId}),!y.writable){F.attached?c.detachClient(F.sessionId,F.clientId).catch(()=>{}):c.killSession(F.sessionId,{requireZeroAttaches:!0}).catch(()=>{});return}y.status(200).json(F)}catch(F){v(y,F,{route:`POST /session/:id/${b}`,sessionId:A})}};n.post("/session/:id/load",V(),Ue("load")),n.post("/session/:id/resume",V(),Ue("resume")),n.post("/session/:id/branch",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let A=we(b),k=typeof A?.name=="string"?A.name:void 0;k&&(k=k.replace(/[\x00-\x1F\x7F-\x9F]/g,""),k.length>200&&(k=k.slice(0,200)));let S=me(b,h);if(S!==null)try{let R=await c.branchSession(y,{name:k},{clientId:S});if(!h.writable){R.attached?c.detachClient(R.sessionId,R.clientId).catch(()=>{}):c.killSession(R.sessionId,{requireZeroAttaches:!0}).catch(()=>{});return}h.status(201).json(R)}catch(R){v(h,R,{route:"POST /session/:id/branch",sessionId:y})}}),n.get("/session/:id/context",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionContextStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/context",sessionId:y})}}),n.get("/session/:id/context-usage",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionContextUsageStatus(y,{detail:b.query.detail==="true"}))}catch(A){v(h,A,{route:"GET /session/:id/context-usage",sessionId:y})}}),n.get("/session/:id/stats",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionStatsStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/stats",sessionId:y})}}),n.get("/session/:id/supported-commands",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionSupportedCommandsStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/supported-commands",sessionId:y})}}),n.get("/session/:id/tasks",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionTasksStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/tasks",sessionId:y})}}),n.get("/session/:id/hooks",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionHooksStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/hooks",sessionId:y})}}),n.post("/session/:id/tasks/:taskId/cancel",V({strict:!0}),async(b,h)=>{let y=b.params.id,A=b.params.taskId;if(!y||!A){h.status(400).json({error:"`sessionId` and `taskId` route parameters are required"});return}let S=we(b).kind;if(S!=="agent"&&S!=="shell"&&S!=="monitor"){h.status(400).json({error:'`kind` must be "agent", "shell", or "monitor"'});return}try{h.status(200).json(await c.cancelSessionTask(y,A,S))}catch(R){v(h,R,{route:"POST /session/:id/tasks/:taskId/cancel",sessionId:y})}}),n.post("/session/:id/goal/clear",V({strict:!0}),async(b,h)=>{let y=b.params.id;if(!y){h.status(400).json({error:"`sessionId` route parameter is required"});return}try{h.status(200).json(await c.clearSessionGoal(y))}catch(A){v(h,A,{route:"POST /session/:id/goal/clear",sessionId:y})}}),n.post("/session/:id/prompt",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=A.prompt;if(!Array.isArray(k)||k.length===0){h.status(400).json({error:"`prompt` is required and must be a non-empty array of content blocks"});return}if(!k.every(he=>typeof he=="object"&&he!==null&&!Array.isArray(he))){h.status(400).json({error:"each `prompt` element must be an object (content block)"});return}let S=A.deadlineMs,R;if(S!=null){if(typeof S!="number"||!Number.isFinite(S)||!Number.isInteger(S)||S<=0){h.status(400).json({error:"`deadlineMs` must be a positive integer (milliseconds)",code:"invalid_deadline_ms"});return}R=S}let F=me(b,h);if(F===null)return;let H=hd.randomUUID(),Z={...A};delete Z.deadlineMs;let X;try{X=c.getSessionLastEventId(y)}catch(he){v(h,he,{route:"POST /session/:id/prompt",sessionId:y});return}$d("matilda-code.prompt_id",H);let pe=new AbortController,de=z0(t.promptDeadlineMs,R),re;de!==void 0&&(re=setTimeout(()=>{pe.signal.aborted||pe.abort(new Ti(de))},de),re.unref());let xe;try{xe=c.sendPrompt(y,{...Z,sessionId:y,prompt:k},pe.signal,{...F!==void 0?{clientId:F}:{},promptId:H})}catch(he){re!==void 0&&clearTimeout(re),g&&he instanceof Cr&&g.warn("prompt admission rejected: queue full",{sessionId:y,promptId:H,...F!==void 0?{clientId:F}:{},limit:he.limit,pendingCount:he.pendingCount}),v(h,he,{route:"POST /session/:id/prompt",sessionId:y});return}xe.then(()=>{g&&g.info("prompt turn completed",{sessionId:y,promptId:H,clientId:F})},he=>{if(g){let K=he instanceof Error?he.name:void 0;g.warn(`prompt turn failed: ${K?`[${K}] `:""}${he instanceof Error?he.message:String(he)}`,{sessionId:y,promptId:H,clientId:F})}}).finally(()=>{re!==void 0&&clearTimeout(re)}).catch(()=>{}),g&&g.info("prompt enqueued",{sessionId:y,promptId:H,clientId:F}),h.status(202).json({promptId:H,lastEventId:X})}),n.post("/session/:id/heartbeat",V(),(b,h)=>{let y=st(b,h);if(y===null)return;let A=me(b,h);if(A!==null)try{let k=c.recordHeartbeat(y,A!==void 0?{clientId:A}:void 0);h.status(200).json(k)}catch(k){v(h,k,{route:"POST /session/:id/heartbeat",sessionId:y})}}),n.post("/session/:id/detach",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let A=me(b,h);if(A!==null)try{await c.detachClient(y,A),h.status(204).end()}catch(k){v(h,k,{route:"POST /session/:id/detach",sessionId:y})}}),n.post("/session/:id/cancel",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=me(b,h);if(k!==null)try{await c.cancelSession(y,{...A,sessionId:y},k!==void 0?{clientId:k}:void 0),g&&g.info("cancel sent",{sessionId:y,clientId:k}),h.status(204).end()}catch(S){v(h,S,{route:"POST /session/:id/cancel",sessionId:y})}}),n.delete("/session/:id",async(b,h)=>{let y=b.params.id,A=me(b,h);if(A!==null)try{await c.closeSession(y,A!==void 0?{clientId:A}:void 0),h.status(204).end()}catch(k){v(h,k,{route:"DELETE /session/:id",sessionId:y})}}),n.post("/sessions/delete",V(),async(b,h)=>{if(me(b,h)===null)return;let k=we(b).sessionIds;if(!Array.isArray(k)||k.length===0||k.length>100||!k.every(S=>typeof S=="string")){h.status(400).json({error:"`sessionIds` must be a non-empty string array (max 100)",code:"invalid_request"});return}try{let S=[...new Set(k)],R=await Promise.allSettled(S.map(async X=>(await c.closeSession(X),X))),F=[],H=[];for(let X=0;X<R.length;X++){let pe=R[X],de=S[X];if(pe.status==="fulfilled")H.push(de);else{let re=pe.reason;if(re instanceof ie)H.push(de);else{let xe=re instanceof Error?re.message:String(re);D(`matilda serve: closeSession failed for ${it(de)}: ${it(xe)}`),F.push({sessionId:de,error:xe})}}}let Z=await new kr(s).removeSessions(H);for(let X of Z.errors){let pe=X.error instanceof Error?X.error.message:String(X.error);D(`matilda serve: removeSession failed for ${it(X.sessionId)}: ${it(pe)}`)}h.status(200).json({removed:Z.removed,notFound:Z.notFound,errors:[...F,...Z.errors.map(X=>({sessionId:X.sessionId,error:X.error instanceof Error?X.error.message:String(X.error)}))]})}catch(S){let R=S instanceof Error?S.message:String(S);D(`matilda serve: failed to batch delete sessions: ${it(R)}`),h.status(500).json({error:"Failed to delete sessions",code:"sessions_delete_failed"})}}),n.patch("/session/:id/metadata",async(b,h)=>{let y=b.params.id,A=we(b),k=me(b,h);if(k===null)return;let S=A.displayName;if(S!==void 0&&typeof S!="string"){h.status(400).json({error:"`displayName` must be a string",code:"invalid_metadata",field:"displayName"});return}let R=typeof S=="string"?S.slice(0,256):void 0;try{let F=c.updateSessionMetadata(y,{displayName:R},k!==void 0?{clientId:k}:void 0);if(R!==void 0)try{await new kr(s).renameSession(y,R)}catch{}h.status(200).json({sessionId:y,...F})}catch(F){v(h,F,{route:"PATCH /session/:id/metadata",sessionId:y})}}),n.get("/workspace/:id/sessions",async(b,h)=>{let y=b.params.id??"";if(!Ci.isAbsolute(y)){h.status(400).json({error:"`:id` must decode to an absolute workspace path"});return}let A=Ye(y);if(A!==s){h.status(400).json({error:`Workspace mismatch: daemon is bound to "${s}"`,code:"workspace_mismatch",boundWorkspace:s,requestedWorkspace:A});return}try{let k=typeof b.query.cursor=="string"?b.query.cursor:void 0,S=b.query.size,R=typeof S=="string"?parseInt(S,10):void 0,F=await Uc(c,A,{cursor:k,size:Number.isFinite(R)?R:void 0});h.status(200).json({sessions:F.sessions,...F.nextCursor!=null?{nextCursor:F.nextCursor}:{}})}catch(k){if(k instanceof Jr){h.status(400).json({error:k.message,code:"invalid_cursor"});return}D(`matilda serve: failed to list sessions for workspace ${it(A)}: ${it(k instanceof Error?k.message:String(k))}`),h.status(500).json({error:"Failed to list sessions",code:"session_list_failed"})}}),n.post("/session/:id/model",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=A.modelId;if(typeof k!="string"||!k){h.status(400).json({error:"`modelId` is required and must be a non-empty string"});return}let S=me(b,h);if(S!==null)try{let R=await c.setSessionModel(y,{...A,sessionId:y,modelId:k},S!==void 0?{clientId:S}:void 0);h.status(200).json(R)}catch(R){v(h,R,{route:"POST /session/:id/model",sessionId:y})}}),n.post("/session/:id/recap",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let A=me(b,h);if(A!==null)try{let k=await c.generateSessionRecap(y,A!==void 0?{clientId:A}:void 0);if(g){let S=k.recap;g.info(S?`recap generated len=${S.length}`:"recap returned null",{sessionId:y,clientId:A})}h.status(200).json(k)}catch(k){v(h,k,{route:"POST /session/:id/recap",sessionId:y})}}),n.post("/session/:id/btw",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let k=we(b).question;if(typeof k!="string"||k.trim().length===0||k.length>Rr){h.status(400).json({error:`\`question\` is required, must be a non-empty string, and at most ${Rr} characters`});return}let S=new AbortController,R=()=>{h.writableEnded||S.abort()};h.once("close",R);let F=me(b,h);if(F===null){h.off("close",R);return}try{let H=await c.generateSessionBtw(y,k.trim(),S.signal,F!==void 0?{clientId:F}:void 0);h.status(200).json(H)}catch(H){if(H instanceof DOMException&&H.name==="AbortError"&&S.signal.aborted)return;v(h,H,{route:"POST /session/:id/btw",sessionId:y})}finally{h.off("close",R)}});let be=16*1024;n.post("/session/:id/mid-turn-message",V(),(b,h)=>{let y=st(b,h);if(y===null)return;let k=we(b).message,S=typeof k=="string"?k.trim():"";if(S.length===0){h.status(400).json({error:"`message` is required and must be a non-empty string"});return}if(S.length>be){h.status(400).json({error:`\`message\` must be at most ${be} characters`});return}let R=me(b,h);if(R!==null)try{let F=c.enqueueMidTurnMessage(y,S,R!==void 0?{clientId:R}:void 0);h.status(200).json(F)}catch(F){v(h,F,{route:"POST /session/:id/mid-turn-message",sessionId:y})}}),n.post("/session/:id/shell",V({strict:!0}),async(b,h)=>{let y=b.params.id;if(!a){v(h,new bt,{route:"POST /session/:id/shell",sessionId:y});return}let A=me(b,h);if(A===null)return;if(A===void 0){v(h,new St,{route:"POST /session/:id/shell",sessionId:y});return}let S=we(b).command;if(typeof S!="string"||S.trim().length===0){h.status(400).json({error:"`command` is required and must be a non-empty string"});return}let R=new AbortController,F=()=>{h.writableEnded||R.abort()};h.once("close",F);try{let H=await c.executeShellCommand(y,S.trim(),R.signal,{clientId:A});g&&g.info("shell command completed",{sessionId:y,clientId:A,exitCode:H.exitCode}),h.status(200).json(H)}catch(H){if(H instanceof DOMException&&H.name==="AbortError"&&R.signal.aborted)return;v(h,H,{route:"POST /session/:id/shell",sessionId:y})}finally{h.off("close",F)}}),n.get("/session/:id/rewind/snapshots",async(b,h)=>{let y=b.params.id;if(!y){h.status(400).json({error:"`sessionId` route parameter is required"});return}try{h.status(200).json(await c.getRewindSnapshots(y))}catch(A){v(h,A,{route:"GET /session/:id/rewind/snapshots",sessionId:y})}}),n.post("/session/:id/rewind",V({strict:!0}),async(b,h)=>{let y=b.params.id,k=we(b).promptId;if(typeof k!="string"||k.length===0){h.status(400).json({error:"`promptId` is required and must be a non-empty string",code:"missing_prompt_id"});return}let S=me(b,h);if(S!==null)try{let R=await c.rewindSession(y,{promptId:k},S!==void 0?{clientId:S}:void 0);h.status(200).json(R)}catch(R){v(h,R,{route:"POST /session/:id/rewind",sessionId:y})}}),n.post("/session/:id/approval-mode",V({strict:!0}),async(b,h)=>{let y=b.params.id,A=we(b),k=A.mode,S=A.persist;if(typeof k!="string"||!tt.includes(k)){h.status(400).json({error:"`mode` is required and must be one of the allowed values",code:"invalid_approval_mode",allowed:tt});return}if(S!==void 0&&typeof S!="boolean"){h.status(400).json({error:"`persist` must be a boolean when provided",code:"invalid_persist_flag"});return}let R=me(b,h);if(R!==null)try{let F=await c.setSessionApprovalMode(y,k,{persist:S===!0},R!==void 0?{clientId:R}:void 0);h.status(200).json(F)}catch(F){v(h,F,{route:"POST /session/:id/approval-mode",sessionId:y})}}),n.post("/session/:id/language",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=A.language,S=A.syncOutputLanguage;if(typeof k!="string"||!Te.includes(k)){h.status(400).json({error:"`language` is required and must be one of: "+Te.join(", "),code:"invalid_language",allowed:Te});return}if(S!==void 0&&typeof S!="boolean"){h.status(400).json({error:"`syncOutputLanguage` must be a boolean when provided",code:"invalid_sync_flag"});return}let R=me(b,h);if(R!==null)try{let F=await c.setSessionLanguage(y,{language:k,syncOutputLanguage:S===!0},R!==void 0?{clientId:R}:void 0);h.status(200).json(F)}catch(F){v(h,F,{route:"POST /session/:id/language",sessionId:y})}}),n.post("/workspace/mcp/:server/restart",V({strict:!0}),async(b,h)=>{let y=b.params.server;if(!y||typeof y!="string"){h.status(400).json({error:"Server name path parameter is required",code:"invalid_server_name"});return}if(y.length>rr){h.status(400).json({error:`Server name exceeds ${rr}-character limit`,code:"invalid_server_name"});return}let A=tr(b,h,c);if(A===null)return;let k,S=b.query.entryIndex;if(S!==void 0&&S!=="*"){let R=typeof S=="string"?S:void 0,F=R!==void 0?Number.parseInt(R,10):NaN;if(!Number.isInteger(F)||F<0||String(F)!==R){h.status(400).json({error:'`entryIndex` query parameter must be a non-negative integer or "*"',code:"invalid_entry_index"});return}k=F}try{let R=Se(b,"POST /workspace/mcp/:server/restart",A),F=await O.restartMcpServer(R,y,k!==void 0?{entryIndex:k}:void 0);h.status(200).json(F)}catch(R){v(h,R,{route:"POST /workspace/mcp/:server/restart"})}});for(let[b,h]of[["enable","enable"],["disable","disable"],["authenticate","authenticate"],["clear-auth","clear-auth"]])n.post(`/workspace/mcp/:server/${b}`,V({strict:!0}),async(y,A)=>{let k=y.params.server;if(!k||typeof k!="string"){A.status(400).json({error:"Server name path parameter is required",code:"invalid_server_name"});return}if(k.length>rr){A.status(400).json({error:`Server name exceeds ${rr}-character limit`,code:"invalid_server_name"});return}let S=tr(y,A,c);if(S!==null)try{let R=await c.manageMcpServer(k,h,S);A.status(200).json(R)}catch(R){v(A,R,{route:`POST /workspace/mcp/:server/${b}`})}});return n.post("/workspace/mcp/servers",V({strict:!0}),async(b,h)=>{let y=we(b),A=y.name;if(!X0(A,h))return;let k=y.config;if(typeof k!="object"||k===null||Array.isArray(k)){h.status(400).json({error:"`config` must be a non-null object",code:"missing_required_field",field:"config"});return}let S=tr(b,h,c);if(S!==null){if(!S){h.status(400).json({error:"`X-Matilda-Client-Id` header is required for runtime MCP mutation",code:"missing_client_id"});return}try{let R=await c.addRuntimeMcpServer(A,k,S);h.status(200).json(R)}catch(R){v(h,R,{route:"POST /workspace/mcp/servers"})}}}),n.delete("/workspace/mcp/servers/:name",V({strict:!0}),async(b,h)=>{let y=b.params.name??"";if(!X0(y,h))return;let A=tr(b,h,c);if(A!==null){if(!A){h.status(400).json({error:"`X-Matilda-Client-Id` header is required for runtime MCP mutation",code:"missing_client_id"});return}try{let k=await c.removeRuntimeMcpServer(y,A);h.status(200).json(k)}catch(k){v(h,k,{route:"DELETE /workspace/mcp/servers/:name"})}}}),n.post("/workspace/init",V({strict:!0}),async(b,h)=>{let A=we(b).force;if(A!==void 0&&typeof A!="boolean"){h.status(400).json({error:"`force` must be a boolean when provided",code:"invalid_force_flag"});return}let k=tr(b,h,c);if(k!==null)try{let S=Se(b,"POST /workspace/init",k),R=await O.initWorkspace(S,{force:A===!0});h.status(200).json(R)}catch(S){v(h,S,{route:"POST /workspace/init"})}}),n.post("/workspace/reload",V({strict:!0}),async(b,h)=>{let y=tr(b,h,c);if(y!==null)try{let A=Se(b,"POST /workspace/reload",y),k=await O.reload(A);h.status(200).json(k)}catch(A){v(h,A,{route:"POST /workspace/reload"})}}),n.post("/workspace/tools/:name/enable",V({strict:!0}),async(b,h)=>{let y=b.params.name;if(!y||typeof y!="string"){h.status(400).json({error:"Tool name path parameter is required",code:"invalid_tool_name"});return}let A=y.trim();if(A.length===0){h.status(400).json({error:"Tool name path parameter is required",code:"invalid_tool_name"});return}if(A.length>K0){h.status(400).json({error:`Tool name exceeds ${K0}-character limit`,code:"invalid_tool_name"});return}let S=we(b).enabled;if(typeof S!="boolean"){h.status(400).json({error:"`enabled` is required and must be a boolean",code:"invalid_enabled_flag"});return}let R=tr(b,h,c);if(R!==null)try{let F=Se(b,"POST /workspace/tools/:name/enable",R),H=await O.setWorkspaceToolEnabled(F,A,S);h.status(200).json(H)}catch(F){v(h,F,{route:"POST /workspace/tools/:name/enable"})}}),n.post("/session/:id/permission/:requestId",V(),(b,h)=>{let y=b.params.id,A=b.params.requestId,k=Y0(b,h);if(k===void 0)return;let S=me(b,h);if(S===null)return;let R=J0(b),F={...S!==void 0?{clientId:S}:{},fromLoopback:R},H;try{H=c.respondToSessionPermission(y,A,k,F)}catch(Z){x(h,Z,{route:"POST /session/:id/permission/:requestId",sessionId:y});return}if(!H){h.status(404).json({error:"No pending permission request for session",sessionId:y,requestId:A});return}h.status(200).json({})}),n.post("/permission/:requestId",V(),(b,h)=>{let y=b.params.requestId,A=Y0(b,h);if(A===void 0)return;let k=me(b,h);if(k===null)return;let S=J0(b),R={...k!==void 0?{clientId:k}:{},fromLoopback:S},F;try{F=c.respondToPermission(y,A,R)}catch(H){x(h,H,{route:"POST /permission/:requestId"});return}if(!F){h.status(404).json({error:"No pending permission request",requestId:y});return}h.status(200).json({})}),n.get("/session/:id/events",(b,h)=>{let y=b.params.id,A=o_(b.headers["last-event-id"]),k=i_(b.query.maxQueued,h);if(k===null)return;let S,R=new AbortController;try{let K=b.query.snapshot==="1";S=c.subscribeEvents(y,{signal:R.signal,lastEventId:A,...k!==void 0?{maxQueued:k}:{},...K?{snapshot:!0}:{}})[Symbol.asyncIterator]()}catch(K){if(K instanceof Tu){D(`matilda serve: subscriber limit reached for session ${y} (limit=${K.limit}); rejecting new SSE client with 429`),h.setHeader("Retry-After","5"),h.status(429).json({error:K.message,code:"subscriber_limit_exceeded",limit:K.limit});return}v(h,K,{route:"GET /session/:id/events",sessionId:y});return}if(g){let K=Date.now(),Y=b.headers["x-matilda-client-id"];g.info("SSE stream opened",{sessionId:y,clientId:Y}),h.on("close",()=>{try{g.info("SSE stream closed",{sessionId:y,clientId:Y,durationMs:Date.now()-K})}catch{}})}h.status(200),h.setHeader("Content-Type","text/event-stream"),h.setHeader("Cache-Control","no-cache, no-transform"),h.setHeader("Connection","keep-alive"),h.setHeader("X-Accel-Buffering","no"),h.flushHeaders(),vd++;let F=!0;h.on("close",()=>{F&&(F=!1,vd--)});let H=Promise.resolve(),Z=t.writerIdleTimeoutMs!==void 0&&t.writerIdleTimeoutMs>0,X=Z?Date.now():0,pe=K=>new Promise((Y,Ee)=>{if(h.writableEnded){Y();return}let et;try{et=h.write(K)}catch(ne){Ee(ne);return}if(et){Z&&(X=Date.now()),Y();return}let Oe=()=>{h.off("close",Fe),h.off("error",Le),Z&&(X=Date.now()),Y()},Fe=()=>{h.off("drain",Oe),h.off("error",Le),Y()},Le=ne=>{h.off("drain",Oe),h.off("close",Fe),Ee(ne)};h.once("drain",Oe),h.once("close",Fe),h.once("error",Le)}),de=K=>{let Y=H.then(()=>pe(K));return H=Y.catch(()=>{}),Y};de(`retry: 3000
715
+ `),originalLineCount:s}}function LI(t){if(t.length===0)return!1;let e=t.subarray(0,Math.min(4,t.length));if(e.length>=4&&(e[0]===255&&e[1]===254&&e[2]===0&&e[3]===0||e[0]===0&&e[1]===0&&e[2]===254&&e[3]===255)||e.length>=3&&e[0]===239&&e[1]===187&&e[2]===191||e.length>=2&&(e[0]===255&&e[1]===254||e[0]===254&&e[1]===255))return!1;let n=Math.min(4096,t.length),s=0;for(let i=0;i<n;i++){if(t[i]===0)return!0;(t[i]<9||t[i]>13&&t[i]<32)&&s++}return s/n>.3}async function p0(t,e){let r=await od(t);if(e!==void 0&&r.meta.hash!==e)throw new B("hash_mismatch",`expected ${e}, found ${r.meta.hash}`,{hint:"re-read the file and retry with the latest hash"});return r.meta}function rd(t,e){return{encoding:e.encoding??t?.encoding??"utf-8",bom:e.bom??t?.bom??!1,lineEnding:e.lineEnding??t?.lineEnding??"lf"}}async function nd(t){let e=t.target,r=Xe.dirname(e),n=await ve.lstat(r);if(n.isSymbolicLink())throw new B("symlink_escape",`parent path is a symlink: ${r}`,{hint:"re-resolve the target after detecting parent-symlink swaps"});if(!n.isDirectory())throw new B("parse_error",`parent path is not a directory: ${r}`);let s=Xe.join(r,`.${Xe.basename(e)}.${process.pid}.${PI(6).toString("hex")}.tmp`),i=!1,o,a;try{o=await NI(s),i=!0;let c=await $I({targetPath:e,tmpPath:s,content:t.content,meta:t.meta,handle:o});a=c.stat;let d=await BI({target:e,mode:t.mode,expectedHash:t.expectedHash});return await HI(o,d.mode??384),await f0(s,a),await o.close(),o=void 0,await f0(s,a),t.mode==="create"?await UI(s,e):await VI(s,e,3,50),i=!1,await WI(r),c}catch(c){if(await o?.close().catch(()=>{}),i)try{await ve.unlink(s)}catch{}throw c}}async function NI(t){return ve.open(t,"wx",384)}async function $I(t){let e=fu(t.targetPath,t.content,w0(t.meta));Yt(e.length),await t.handle.writeFile(e),await jI(t.handle);let r=await ve.lstat(t.tmpPath),n=await t.handle.stat();if(jt(n,r,t.tmpPath,"write"),r.isSymbolicLink())throw new B("symlink_escape",`temporary path became a symlink: ${t.tmpPath}`,{hint:"temp-file race detected before final rename"});if(!r.isFile())throw new B("parse_error",`temporary path is not a regular file: ${t.tmpPath}`);return{sizeBytes:e.length,hash:cd(e),stat:r}}async function y0(t){try{throw(await ve.lstat(t)).isSymbolicLink()?new B("symlink_escape",`path is a symlink and cannot be created over: ${t}`,{hint:"remove the symlink or resolve the target explicitly"}):new B("file_already_exists",`file already exists: ${t}`)}catch(e){if(e?.code==="ENOENT")return;throw e}}async function BI(t){if(t.mode==="create")return await y0(t.target),{};if(t.mode==="overwrite"){let n;try{n=await ve.lstat(t.target)}catch(s){if(s?.code==="ENOENT")return{};throw s}if(n.isSymbolicLink())throw new B("symlink_escape",`path is a symlink and cannot be overwritten atomically: ${t.target}`,{hint:"re-resolve the target file instead of writing through a link"});if(!n.isFile())throw new B("parse_error",`path is not a regular file: ${t.target}`);return{mode:n.mode&4095}}if(!wr(t.expectedHash))throw new B("parse_error",'expectedHash is required when mode is "replace"');let e=await ve.lstat(t.target);if(e.isSymbolicLink())throw new B("symlink_escape",`path is a symlink and cannot be replaced atomically: ${t.target}`,{hint:"re-resolve the target file instead of writing through a link"});if(!e.isFile())throw new B("parse_error",`path is not a regular file: ${t.target}`);let r=await qI(t.target,e);if(r!==t.expectedHash)throw new B("hash_mismatch",`expected ${t.expectedHash}, found ${r}`,{hint:"re-read the file and retry with the latest hash"});return{mode:e.mode&4095}}async function qI(t,e){let r=await ve.open(t,"r"),n=v0("sha256"),s;try{s=await r.stat(),jt(e,s,t,"read");let o=Buffer.allocUnsafe(64*1024),a=0;for(;a<s.size;){let c=await r.read(o,0,Math.min(o.length,s.size-a),a);if(c.bytesRead===0)break;n.update(o.subarray(0,c.bytesRead)),a+=c.bytesRead}}finally{await r.close()}if(s===void 0)throw new B("internal_error",`failed to stat opened file: ${t}`);let i=await ve.lstat(t);if(jt(e,i,t,"read"),i.size!==s.size||i.mtimeMs!==s.mtimeMs)throw new B("hash_mismatch",`file changed during hash: ${t}`,{hint:"retry after re-reading the latest file hash"});return`sha256:${n.digest("hex")}`}function cd(t){return`sha256:${v0("sha256").update(t).digest("hex")}`}function jt(t,e,r,n){let s=Xr(t.dev),i=Xr(e.dev),o=Xr(t.ino),a=Xr(e.ino);if(s!==0n&&i!==0n&&o!==0n&&a!==0n&&(s!==i||o!==a))throw new B("symlink_escape",`path changed during ${n}: ${r}`,{hint:"TOCTOU swap detected via device/inode comparison"})}function Xr(t){return typeof t=="bigint"?t:BigInt(t)}async function jI(t){try{await t.sync()}catch{}}async function WI(t){let e;try{e=await ve.open(t,"r"),await e.sync()}catch{}finally{await e?.close().catch(()=>{})}}async function HI(t,e){try{await t.chmod(e)}catch{}}async function f0(t,e){let r=await ve.lstat(t);if(r.isSymbolicLink())throw new B("symlink_escape",`temporary path is a symlink: ${t}`,{hint:"temp-file race detected before final rename"});if(!r.isFile())throw new B("parse_error",`temporary path is not a regular file: ${t}`);jt(e,r,t,"write")}async function UI(t,e){try{await ve.link(t,e)}catch(r){throw r?.code==="EEXIST"?new B("file_already_exists",`file already exists: ${e}`):r}await ve.unlink(t).catch(()=>{})}async function VI(t,e,r,n){for(let s=0;s<=r;s++)try{await ve.rename(t,e);return}catch(i){let o=i?.code;if(!(o==="EPERM"||o==="EACCES")||s===r)throw i;await new Promise(c=>setTimeout(c,n*2**s))}}function zI(t,e){let r=0,n=0;for(;;){let s=t.indexOf(e,n);if(s===-1)return r;r+=1,n=s+e.length}}function GI(t,e){if(t.length<=e)return t;let r=e;for(;r>0&&(t[r]&192)===128;)r--;return t.subarray(0,r)}async function h0(t,e){let r=await ve.lstat(t);if(r.isSymbolicLink())throw new B("symlink_escape",`path was replaced with a symlink during read: ${t}`,{hint:"TOCTOU swap detected via post-read lstat"});let n=Xr(e),s=Xr(r.ino);if(n!==0n&&s!==0n&&n!==s)throw new B("symlink_escape",`path inode changed during read: ${t}`,{hint:"TOCTOU swap detected via inode comparison"})}async function m0(t){let e;try{e=await ve.lstat(t)}catch(r){if(r?.code==="ENOENT")return;throw r}if(e.isSymbolicLink())throw new B("symlink_escape",`path was replaced with a symlink before write: ${t}`,{hint:"TOCTOU swap detected via pre-write lstat \u2014 re-resolve before retrying"})}function g0(t){return t.isSymbolicLink()?"symlink":t.isDirectory()?"directory":t.isFile()?"file":"other"}function w0(t){let e={};return t.bom!==void 0&&(e.bom=t.bom),t.encoding&&(e.encoding=t.encoding),t.lineEnding&&(e.lineEnding=t.lineEnding),Object.keys(e).length>0?e:void 0}w();import*as $n from"node:path";var dd=2e3,b0=2e3,KI=64*1024,JI=5e3,S0=5e4;function Pe(t){t.set("Cache-Control","no-store"),t.set("X-Content-Type-Options","nosniff")}function Zt(t,e,r){if(Pe(t),Pc(e)){let n=e;t.status(n.status).json({errorKind:n.kind,error:n.message,hint:n.hint,status:n.status});return}D(`matilda serve: ${r} unexpected error: ${e instanceof Error?e.message:String(e)}`),t.status(500).json({errorKind:"internal_error",error:e instanceof Error?e.message:String(e),status:500})}function Yr(t,e,r){if(t===void 0)return;if(typeof t!="string"||!/^\d+$/.test(t))return null;let n=Number.parseInt(t,10);return!Number.isSafeInteger(n)||n<e||n>r?null:n}function E0(t){return t==="1"||t==="true"}function Bn(t,e,r,n){return typeof e!="string"||e.length===0?(Pe(t),t.status(400).json({errorKind:"parse_error",error:`${r} query parameter is required`,status:400}),D(`matilda serve: ${n} rejected request missing required ?${r}`),null):e}function qn(t,e){let r=t.app.locals.fsFactory;return r||(Pe(e),e.status(500).json({errorKind:"internal_error",error:"workspace filesystem factory is not configured",status:500}),null)}async function XI(t,e,r){let n="GET /file",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=Yr(t.query.maxBytes,1,256*1024);if(a===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:"`maxBytes` must be a positive integer in [1, 262144]",status:400});return}let c=Yr(t.query.line,1,Number.MAX_SAFE_INTEGER);if(c===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:"`line` must be a positive integer",status:400});return}let d=Yr(t.query.limit,1,b0);if(d===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:`\`limit\` must be a positive integer in [1, ${b0}]`,status:400});return}let u=s.forRequest({originatorClientId:i??void 0,route:n});try{let l=await u.resolve(o,"read"),p=await u.readText(l,{maxBytes:a,line:c,limit:d}),f=Buffer.byteLength(p.content,"utf-8");Pe(e),e.status(200).json({kind:"file",path:er(t,l),content:p.content,encoding:p.meta.encoding??"utf-8",bom:p.meta.bom===!0,lineEnding:p.meta.lineEnding,sizeBytes:p.meta.sizeBytes??f,returnedBytes:f,truncated:p.meta.truncated===!0,hash:p.meta.hash,matchedIgnore:p.meta.matchedIgnore??null,originalLineCount:p.meta.originalLineCount??null})}catch(l){Zt(e,l,n)}}async function YI(t,e,r){let n="GET /file/bytes",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=Yr(t.query.offset,0,Number.MAX_SAFE_INTEGER);if(a===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:"`offset` must be a non-negative safe integer",status:400});return}let c=Yr(t.query.maxBytes,1,Je);if(c===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:`\`maxBytes\` must be a positive integer in [1, ${Je}]`,status:400});return}let d=s.forRequest({originatorClientId:i??void 0,route:n});try{let u=await d.resolve(o,"read"),l=await d.readBytesWindow(u,{offset:a??0,maxBytes:c??KI});Pe(e),e.status(200).json({kind:"file_bytes",path:er(t,u),offset:l.offset,sizeBytes:l.sizeBytes,returnedBytes:l.returnedBytes,truncated:l.truncated,contentBase64:l.buffer.toString("base64"),...l.hash?{hash:l.hash}:{}})}catch(u){Zt(e,u,n)}}async function QI(t,e,r){let n="GET /stat",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=s.forRequest({originatorClientId:i??void 0,route:n});try{let c=await a.resolve(o,"stat"),d=await a.stat(c);Pe(e),e.status(200).json({kind:"stat",path:er(t,c),type:d.kind,sizeBytes:d.sizeBytes,modifiedMs:d.modifiedMs})}catch(c){Zt(e,c,n)}}async function ZI(t,e,r){let n="GET /list",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.path,"path",n);if(o===null)return;let a=E0(t.query.includeIgnored),c=s.forRequest({originatorClientId:i??void 0,route:n});try{let d=await c.resolve(o,"list"),u=await c.list(d,{includeIgnored:a,maxEntries:dd+1}),l=!1,p=u;p.length>dd&&(p=p.slice(0,dd),l=!0),Pe(e),e.status(200).json({kind:"list",path:er(t,d),entries:p,truncated:l,matchedIgnore:null})}catch(d){Zt(e,d,n)}}async function ex(t,e,r){let n="GET /glob",s=qn(t,e);if(!s)return;let i=r.parseClientId(t,e);if(i===null)return;let o=Bn(e,t.query.pattern,"pattern",n);if(o===null)return;let a=E0(t.query.includeIgnored),c=Yr(t.query.maxResults,1,S0);if(c===null){Pe(e),e.status(400).json({errorKind:"parse_error",error:`\`maxResults\` must be a positive integer in [1, ${S0}]`,status:400});return}let d=t.query.cwd,u=typeof d=="string"&&d.length>0?d:void 0,l=s.forRequest({originatorClientId:i??void 0,route:n}),p=performance.now();try{let f=u?await l.resolve(u,"list"):void 0,g=c??JI,v=await l.glob(o,{cwd:f,includeIgnored:a,maxResults:g+1}),x=v.length>g,P=(x?v.slice(0,g):v).map(q=>er(t,q));Pe(e),e.status(200).json({kind:"glob",pattern:o,cwd:u??"",matches:P,count:P.length,truncated:x,durationMs:Math.round(performance.now()-p)})}catch(f){Zt(e,f,n)}}function er(t,e){let r=t.app.locals.boundWorkspace;if(!r)throw new Error("bound workspace is not configured");let n=$n.relative(r,e);return n===""?".":$n.sep==="/"?n:n.split($n.sep).join("/")}function I0(t,e){t.get("/file",(r,n)=>XI(r,n,e)),t.get("/file/bytes",(r,n)=>YI(r,n,e)),t.get("/stat",(r,n)=>QI(r,n,e)),t.get("/list",(r,n)=>ZI(r,n,e)),t.get("/glob",(r,n)=>ex(r,n,e))}w();function x0(t,e){let r=t.app.locals.fsFactory;return r||(Pe(e),e.status(500).json({errorKind:"internal_error",error:"workspace filesystem factory is not configured",status:500}),null)}function Rt(t,e,r){return Pe(t),t.status(400).json({errorKind:"parse_error",error:r,status:400}),null}function _0(t,e,r,n){let s=t[e];return typeof s!="string"||s.length===0?Rt(r,n,`\`${e}\` must be a non-empty string`):s}function tx(t,e,r,n){let s=t[e];if(s!==void 0)return typeof s!="boolean"?Rt(r,n,`\`${e}\` must be a boolean`):s}function rx(t,e,r,n){let s=t[e];if(s!==void 0)return typeof s!="string"||s.length===0?Rt(r,n,`\`${e}\` must be a non-empty string`):s}function nx(t,e,r){let n=t.lineEnding;if(n!==void 0)return n!=="crlf"&&n!=="lf"?Rt(e,r,'`lineEnding` must be "lf" or "crlf"'):n}function k0(t,e,r){let n=t.expectedHash;return wr(n)?n:Rt(e,r,"`expectedHash` must match sha256:<64 lowercase hex chars>")}function sx(t,e,r){let n=t.expectedHash;if(n!==void 0)return wr(n)?n:Rt(e,r,"`expectedHash` must match sha256:<64 lowercase hex chars>")}function A0(t,e,r){if(t!==void 0)return e.bridge.knownClientIds().has(t)?t:(Pe(r),r.status(400).json({error:`Client id "${t}" is not registered for this workspace`,code:"invalid_client_id",clientId:t}),null)}async function ix(t,e,r){let n="POST /file/write",s=x0(t,e);if(!s)return;let i=r.safeBody(t),o=_0(i,"path",e,n);if(o===null)return;let a=i.content;if(typeof a!="string"){Rt(e,n,"`content` must be a string");return}let c=i.mode;if(c!=="create"&&c!=="replace"){Rt(e,n,'`mode` must be "create" or "replace"');return}let d=c,u=d==="replace"?k0(i,e,n):sx(i,e,n);if(u===null)return;let l=tx(i,"bom",e,n);if(l===null)return;let p=rx(i,"encoding",e,n);if(p===null)return;let f=nx(i,e,n);if(f===null)return;let g=r.parseClientId(t,e);if(g===null)return;let v=A0(g,r,e);if(v===null)return;let x=s.forRequest({originatorClientId:v,route:n});try{let O=await x.resolve(o,"write"),P=await x.writeTextAtomic(O,a,{mode:d,...u?{expectedHash:u}:{},...l!==void 0?{bom:l}:{},...p!==void 0?{encoding:p}:{},...f!==void 0?{lineEnding:f}:{}});Pe(e),e.status(P.created?201:200).json({kind:"file_write",path:er(t,O),mode:d,created:P.created,sizeBytes:P.sizeBytes,hash:P.hash,encoding:P.meta.encoding??"utf-8",bom:P.meta.bom===!0,lineEnding:P.meta.lineEnding,matchedIgnore:P.meta.matchedIgnore??null})}catch(O){Zt(e,O,n)}}async function ox(t,e,r){let n="POST /file/edit",s=x0(t,e);if(!s)return;let i=r.safeBody(t),o=_0(i,"path",e,n);if(o===null)return;let a=i.oldText;if(typeof a!="string"){Rt(e,n,"`oldText` must be a string");return}let c=i.newText;if(typeof c!="string"){Rt(e,n,"`newText` must be a string");return}let d=k0(i,e,n);if(d===null)return;let u=r.parseClientId(t,e);if(u===null)return;let l=A0(u,r,e);if(l===null)return;let p=s.forRequest({originatorClientId:l,route:n});try{let f=await p.resolve(o,"edit"),g=await p.editAtomic(f,a,c,{expectedHash:d});Pe(e),e.status(200).json({kind:"file_edit",path:er(t,f),replacements:1,sizeBytes:g.writtenBytes,hash:g.hash,encoding:g.meta?.encoding??"utf-8",bom:g.meta?.bom===!0,lineEnding:g.meta?.lineEnding??"lf",matchedIgnore:g.meta?.matchedIgnore??null})}catch(f){Zt(e,f,n)}}function R0(t,e){t.post("/file/write",e.mutate({strict:!0}),(r,n)=>ix(r,n,e)),t.post("/file/edit",e.mutate({strict:!0}),(r,n)=>ox(r,n,e))}w();import{promises as Qr,constants as C0}from"node:fs";import*as Ct from"node:path";async function P0(t){let e=t;for(;;)try{return await Qr.realpath(e)}catch(r){let n=r?.code;if(n!=="ENOENT"&&n!=="ENOTDIR"&&n!=="ELOOP")throw r;let s=Ct.dirname(e);if(s===e)throw r;e=s}}async function T0(t,e,r){let n=await P0(Ct.dirname(t));if(!(n===e||n.startsWith(e+Ct.sep)))throw new mt(t,"parent",`Workspace context file ${JSON.stringify(t)}'s parent moved outside the workspace between the pre-open canonicalize and the post-open verify (parent canonicalizes to ${JSON.stringify(n)}, workspace canonicalizes to ${JSON.stringify(e)}). Refusing to write \u2014 investigate the concurrent writer or the parent-directory permissions.`)}function Ri(t){let{boundWorkspace:e,contextFilename:r,statusProvider:n,isChannelLive:s,persistDisabledTools:i,queryWorkspaceStatus:o,invokeWorkspaceCommand:a,publishWorkspaceEvent:c}=t;return{async getWorkspaceMcpStatus(d){return o(ke.workspaceMcp,()=>Ji(e))},async getWorkspaceSkillsStatus(d){return o(ke.workspaceSkills,()=>Xi(e))},async getWorkspaceProvidersStatus(d){return o(ke.workspaceProviders,()=>Yi(e))},async getWorkspaceEnvStatus(d){let u=s?.()??!1;if(!n)return Qi(e,u);try{return await n.getEnvStatus(e,u)}catch(l){return D(`matilda serve: getEnvStatus failed: ${l instanceof Error?l.message:String(l)}`),Qi(e,u)}},async getWorkspacePreflightStatus(d){let u=s?.()??!1,l=Zi(),p=[];if(n)try{p=await n.getDaemonPreflightCells(e)}catch(v){D(`matilda serve: getDaemonPreflightCells failed: ${v instanceof Error?v.message:String(v)}`)}let f=l,g;if(u)try{let v=await o(ke.workspacePreflight,()=>({cells:l}));if(v&&"cells"in v){let x=v;f=x.cells.filter(O=>O.locality!=="daemon"),g=x.errors}}catch(v){f=l;let x=Mt(v);g=[{kind:"preflight",status:"error",error:v instanceof Error?v.message:String(v),...x?{errorKind:x}:{}}]}return{v:ot,workspaceCwd:e,initialized:!0,acpChannelLive:u,cells:[...p,...f],...g&&g.length>0?{errors:g}:{}}},async getWorkspaceHooksStatus(d){return o(ke.workspaceHooks,()=>pn(e))},async getWorkspaceExtensionsStatus(d){return o(ke.workspaceExtensions,()=>ln(e))},async setWorkspaceToolEnabled(d,u,l){return await i(e,u,l),c({type:"tool_toggled",data:{toolName:u,enabled:l},originatorClientId:d.originatorClientId}),{toolName:u,enabled:l}},async initWorkspace(d,u){let l=r,p=Ct.resolve(e,l);if(!(p===e||p.startsWith(e+Ct.sep)))throw new Mr(l,e);let g=await Qr.realpath(e),v=await P0(Ct.dirname(p));if(!(v===g||v.startsWith(g+Ct.sep)))throw new mt(p,"parent",`Configured workspace context filename ${JSON.stringify(l)} has a parent path that resolves outside the bound workspace (parent canonicalizes to ${JSON.stringify(v)}, workspace canonicalizes to ${JSON.stringify(g)}). Refusing to write \u2014 replace any symlinked parent directory with a real directory before re-running init.`);try{let P=await Qr.lstat(p);if(P.isSymbolicLink())throw new mt(p,"target",`Workspace context file ${JSON.stringify(p)} is a symlink. Refusing to follow it for write \u2014 replace the symlink with a regular file (or remove it) before re-running init.`);if(!P.isFile())throw new mt(p,"target",`Workspace context file ${JSON.stringify(p)} is not a regular file (mode=${P.mode.toString(8)}). Refusing to proceed \u2014 FIFOs, sockets, and device nodes can block or misbehave on read/write.`)}catch(P){if(P instanceof mt||P?.code!=="ENOENT")throw P}let O="created";try{let P=await Qr.readFile(p,"utf8");if(P.trim().length>0){let q=Buffer.byteLength(P,"utf8");if(u.force!==!0)throw new ar(p,q);O="overwrote"}else O="noop"}catch(P){if(P instanceof ar||P?.code!=="ENOENT")throw P}if(O==="created"){let P;try{P=await Qr.open(p,"wx")}catch(q){throw q?.code==="EEXIST"?new cr(p,"eexist",`Workspace context file ${JSON.stringify(p)} appeared between our absence check and the create \u2014 refusing to proceed (a regular file or symlink was just placed at the target path, and following it could escape the workspace).`):q}try{await T0(p,g,P),await P.writeFile("","utf8")}finally{await P.close()}}else if(O==="overwrote"){let P;try{P=await Qr.open(p,C0.O_WRONLY|(C0.O_NOFOLLOW??0))}catch(q){let U=q?.code;throw U==="ELOOP"?new mt(p,"target",`Workspace context file ${JSON.stringify(p)} could not be opened with O_NOFOLLOW (ELOOP); the path may have been swapped to a symlink between the content check and the overwrite. Refusing to follow it.`):U==="ENOENT"?new cr(p,"enoent",`Workspace context file ${JSON.stringify(p)} was deleted between the content check and the overwrite (likely a concurrent writer). Refusing to recreate blindly; rerun init.`):q}try{await T0(p,g,P),await P.truncate(0)}finally{await P.close()}}return c({type:"workspace_initialized",data:{path:p,action:O},originatorClientId:d.originatorClientId}),{path:p,action:O}},async restartMcpServer(d,u,l){let p={serverName:u};l?.entryIndex!==void 0&&(p.entryIndex=l.entryIndex);let f;try{f=await a(fe.workspaceMcpRestart,p,{timeoutMs:3e5})}catch(g){let v=g?.data;if(v&&typeof v=="object"){let x=v.errorKind,O=v.serverName;if(x==="mcp_server_not_found"&&typeof O=="string")throw new Or(O);if(x==="mcp_restart_failed"&&typeof O=="string"){let P=v.mcpStatus;throw new Dr(O,typeof P=="string"?P:"unknown")}}throw g}if("entries"in f){let g=Array.isArray(f.entries)?f.entries:[];Array.isArray(f.entries)||D(`matilda serve: pool restart response carried 'entries' field but it is not an array (server=${u}); treating as empty.`);for(let v of g){if(typeof v!="object"||v===null||typeof v.entryIndex!="number"){D(`matilda serve: skipping malformed pool restart entry (server=${u}): ${JSON.stringify(v)}`);continue}v.restarted?c({type:"mcp_server_restarted",data:{serverName:f.serverName,durationMs:v.durationMs??0,entryIndex:v.entryIndex},originatorClientId:d.originatorClientId}):c({type:"mcp_server_restart_refused",data:{serverName:f.serverName,reason:"restart_failed",entryIndex:v.entryIndex,...v.reason?{details:v.reason}:{}},originatorClientId:d.originatorClientId})}}else f.restarted===!0?c({type:"mcp_server_restarted",data:{serverName:f.serverName,durationMs:f.durationMs},originatorClientId:d.originatorClientId}):c({type:"mcp_server_restart_refused",data:{serverName:f.serverName,reason:f.reason},originatorClientId:d.originatorClientId});return f},async reload(d){if(t.reloadDaemonEnv)try{await t.reloadDaemonEnv(e)}catch(x){D(`matilda serve: daemon reload failed: ${x instanceof Error?x.message:String(x)}`)}let u=!1,l={updatedKeys:[],removedKeys:[]},p=[],f,g,v;try{let x=await a(fe.workspaceReload,{cwd:e},{timeoutMs:3e4});u=!0,l=x.env,p=x.changedKeys,f=x.sessionsRefreshed,g=x.sessionsSkipped}catch(x){x instanceof ie?v="ACP child not running":(v=x instanceof Error?x.message:String(x),D(`matilda serve: reload failed: ${v}`))}return c({type:"settings_reloaded",data:{env:l,changedKeys:p,childReloaded:u,sessionsRefreshed:f,sessionsSkipped:g,childError:v},originatorClientId:d.originatorClientId}),{env:l,changedKeys:p,childReloaded:u,sessionsRefreshed:f,sessionsSkipped:g,childError:v}}}}w();var cx=new Set(["general.vimMode","general.terminalBell","general.preferredEditor","general.outputLanguage","ide.enabled","ui.showLineNumbers","ui.renderMode","ui.useTerminalBuffer","ui.hideBanner","ui.accessibility.enableLoadingPhrases","ui.enableWelcomeBack"]),dx=new Set(["ui.compactMode"]),ud=new Set(["workspace"]),M0=1024,ux=new Set(["tools.approvalMode"]);function lx(){let t=new Set(Iu().filter(e=>!cx.has(e)&&!ux.has(e)));for(let e of dx)t.add(e);return t}function px(t,e){let r=Tt(t),n=[];for(let i of e){let o=Ui(i);if(!o)continue;let a=ns(r.merged,i),c=ns(r.user.settings,i),d=ns(r.workspace.settings,i),u={effective:a!==void 0?a:o.default};c!==void 0&&(u.user=c),d!==void 0&&(u.workspace=d),n.push({key:i,type:o.type,label:o.label,category:o.category,...o.description?{description:o.description}:{},requiresRestart:o.requiresRestart,default:o.default,...o.options?.length?{options:o.options}:{},values:u})}let s=[];return r.corruptedPath&&s.push({type:"corrupted",recovered:r.wasRecovered}),{v:1,...s.length?{warnings:s}:{},settings:n}}function fx(t,e){switch(t.type){case"boolean":if(typeof e!="boolean")return"Value must be a boolean";break;case"number":if(typeof e!="number"||!Number.isFinite(e))return"Value must be a finite number";break;case"string":if(typeof e!="string")return"Value must be a string";if(e.length>M0)return`Value exceeds ${M0}-character limit`;break;case"enum":if(!t.options?.some(r=>r.value===e))return`Value must be one of: ${t.options?.map(n=>n.value).join(", ")??""}`;break;default:return`Settings of type '${t.type}' cannot be modified via this API`}}var hx={workspace:"Workspace"};function O0(t,e){let{boundWorkspace:r,mutate:n,safeBody:s,persistSetting:i,broadcastSettingsChanged:o,parseAndValidateClientId:a}=e,c=lx();t.get("/workspace/settings",(d,u)=>{try{let l=px(r,c);u.status(200).json(l)}catch(l){D(`matilda serve: GET /workspace/settings error: ${l instanceof Error?l.message:String(l)}`),u.status(500).json({error:"Failed to load settings",code:"internal_error"})}}),t.post("/workspace/settings",n({strict:!0}),async(d,u)=>{let l=s(d),p=l.scope,f=l.key,g=l.value;if(typeof p!="string"||!ud.has(p)){u.status(400).json({error:`scope must be one of: ${[...ud].join(", ")}`,code:"invalid_scope"});return}if(typeof f!="string"||!f){u.status(400).json({error:"key is required and must be a string",code:"invalid_key"});return}if(!c.has(f)){u.status(400).json({error:`Setting "${f}" is not modifiable via this API`,code:"disallowed_key"});return}if(g==null){u.status(400).json({error:"value is required",code:"missing_value"});return}let v=Ui(f);if(!v){u.status(400).json({error:`Unknown setting: ${f}`,code:"unknown_key"});return}let x=fx(v,g);if(x){u.status(400).json({error:x,code:"invalid_value"});return}let O=a(d,u);if(O!==null){try{let P=hx[p];if(!P){u.status(400).json({error:`scope must be one of: ${[...ud].join(", ")}`,code:"invalid_scope"});return}await i(r,P,f,g)}catch(P){D(`matilda serve: POST /workspace/settings persist error (key=${f}, scope=${p}, workspace=${r}): ${P instanceof Error?P.message:String(P)}`),u.status(500).json({error:"Failed to persist setting",code:"persist_error"});return}try{o(f,g,p,O)}catch(P){D(`matilda serve: POST /workspace/settings broadcast error (key=${f}, scope=${p}): ${P instanceof Error?P.message:String(P)}`)}u.status(200).json({key:f,scope:p,value:g,requiresRestart:v.requiresRestart})}})}w();import*as F0 from"node:fs/promises";import*as L0 from"node:path";var mx="application/a2ui+json",gx="action",D0=15e3;function N0(t){return!!t&&(typeof t.command=="string"||typeof t.httpUrl=="string")}async function vx(t){try{let e=await F0.readFile(L0.join(t,".matilda","settings.json"),"utf8"),r=JSON.parse(e);for(let[n,s]of Object.entries(r.mcpServers??{}))if(n.toLowerCase().includes("a2ui")&&N0(s))return s}catch{}return null}function yx(t){return typeof t.httpUrl=="string"?new gu(new URL(t.httpUrl)):new vu({command:t.command,args:t.args??[],...t.env?{env:{...process.env,...t.env}}:{},cwd:t.cwd})}function wx(t){if(t.isError){let n=(t.content??[]).filter(s=>s.type==="text"&&typeof s.text=="string").map(s=>s.text).join("");throw new Error(`a2ui action tool returned error: ${n||"unknown error"}`)}let e=null,r="";for(let n of t.content??[])if(e===null&&n.type==="resource"&&n.resource?.mimeType===mx&&typeof n.resource.text=="string")try{let s=JSON.parse(n.resource.text);Array.isArray(s)&&(e=s)}catch{}else n.type==="text"&&typeof n.text=="string"&&(r+=n.text);return{commands:e,fallback:r}}async function bx(t,e){let r=yx(t),n=new mu({name:"matilda-serve-a2ui",version:"0.0.1"});try{await n.connect(r,{timeout:D0});let s=await n.callTool({name:gx,arguments:{...e}},void 0,{timeout:D0});return wx(s)}finally{await r.close().catch(()=>{}),await n.close().catch(()=>{})}}function $0(t,e){let{boundWorkspace:r,mutate:n,safeBody:s,getMcpServers:i}=e,o=e.callAction??bx;t.post("/session/:id/a2ui-action",n(),async(a,c)=>{let d=s(a),u=d.name;if(typeof u!="string"||u.trim().length===0){c.status(400).json({error:"`name` is required"});return}let l=typeof d.surfaceId=="string"?d.surfaceId:void 0,p=d.context&&typeof d.context=="object"&&!Array.isArray(d.context)?d.context:void 0,f=null;try{let g=(await i(a)).filter(x=>x.name.toLowerCase().includes("a2ui")&&N0(x.config));f=(g.find(x=>x.mcpStatus==="connected")??g[0])?.config??null}catch{}if(f||(f=await vx(r)),!f){c.status(503).json({error:"no a2ui MCP server found (neither runtime-registered nor in workspace settings mcpServers)"});return}try{let{commands:g,fallback:v}=await o(f,{name:u.trim(),surfaceId:l,context:p});c.status(200).json({commands:g,fallback:v})}catch(g){D(`a2ui-action proxy failed: ${g instanceof Error?g.message:String(g)}`),c.status(502).json({error:"a2ui action call failed"})}})}w();var Sx=1e4,Ex=1e3,Ix=5*60*1e3;function xx(t,e){let r=e.endsWith("/")&&e.length>1?e.slice(0,-1):e;return t==="OPTIONS"||(t==="GET"||t==="HEAD")&&(r==="/health"||r==="/demo")||t==="POST"&&r.startsWith("/session/")&&r.endsWith("/heartbeat")||t==="GET"&&r.startsWith("/session/")&&r.endsWith("/events")||r==="/acp"||r.startsWith("/acp/")?null:t==="POST"&&r.startsWith("/session/")&&r.endsWith("/prompt")?"prompt":t!=="GET"&&t!=="HEAD"?"mutation":"read"}var _x=128,kx=/^[A-Za-z0-9._:-]+$/;function Ax(t){return t.startsWith("::ffff:")?t.slice(7):t}function Rx(t){let e=_t(t);return r=>{let n=r.get("x-matilda-client-id"),s=n&&n.length<=_x&&kx.test(n)?n:void 0;if(e)return s?`cid:${s}`:"anonymous";let i=Ax(r.socket?.remoteAddress??"unknown");return s?`${i}:${s}`:i}}var Cx=100;function Tx(t){let e=new Map;return{log(r,n){let s=`${r}:${n}`,i=e.get(s);i||(i={count:0,suppressed:0},e.set(s,i)),i.count++,i.count===1||i.count%Cx===0?(t(r,n,i.suppressed),i.suppressed=0):i.suppressed++},clear(){e.clear()}}}function B0(t){for(let[p,f]of Object.entries(t.tiers)){if(!Number.isFinite(f.max)||f.max<=0)throw new Error(`rate limit: ${p}.max must be a positive number, got ${f.max}`);if(!Number.isFinite(f.windowMs)||f.windowMs<=0)throw new Error(`rate limit: ${p}.windowMs must be a positive number, got ${f.windowMs}`)}let e=new Map,r=Rx(t.hostname),n={prompt:0,mutation:0,read:0},s={prompt:t.tiers.prompt.max/t.tiers.prompt.windowMs,mutation:t.tiers.mutation.max/t.tiers.mutation.windowMs,read:t.tiers.read.max/t.tiers.read.windowMs},i=!1,o=0,a=t.onLimitReached?Tx(t.onLimitReached):void 0;function c(){let p=Date.now();for(let[f,g]of e){let v=!0;for(let[x,O]of g)if(p-O.lastRefill<t.tiers[x].windowMs*2){v=!1;break}v&&e.delete(f)}}let d=setInterval(c,Ix);d.unref();let u=(p,f,g)=>{try{if(i){g();return}let v=xx(p.method,p.path);if(v===null){g();return}o++,o%Ex===0&&c();let x=r(p);if(l(x,v))g();else{let O=t.tiers[v],P=s[v],q=e.get(x)?.get(v),U=Math.ceil((1-(q?.tokens??0))/P),ae=Math.ceil(U/1e3);f.setHeader("Retry-After",String(ae)),f.setHeader("X-RateLimit-Limit",String(O.max)),f.setHeader("X-RateLimit-Remaining","0"),f.setHeader("X-RateLimit-Reset",String(Math.ceil((Date.now()+U)/1e3))),f.status(429).json({error:"Rate limit exceeded",code:"rate_limit_exceeded",tier:v,retryAfterMs:U})}}catch(v){t.onError?.(v,p.path),g()}};function l(p,f){if(i)return!0;let g=t.tiers[f],v=s[f],x=Date.now(),O=e.get(p);if(!O){if(e.size>=Sx)return t.onError?.(new Error(`rate limit bucket overflow: ${e.size} keys`),`tryConsume:${f}`),!0;O=new Map,e.set(p,O)}let P=O.get(f);P||(P={tokens:g.max,lastRefill:x},O.set(f,P));let q=Math.max(0,x-P.lastRefill);return P.tokens=Math.min(g.max,P.tokens+q*v),P.lastRefill=x,P.tokens>=1?(P.tokens-=1,!0):(n[f]++,a&&a.log(f,p),!1)}return{middleware:u,checkRate:l,reset(){e.clear(),n.prompt=0,n.mutation=0,n.read=0,o=0,a?.clear()},setDraining(p){i=p},dispose(){clearInterval(d),e.clear(),a?.clear()},getHitCounts(){return{...n}}}}var q0="_rateLimiter";function j0(t,e){t.locals[q0]=e}function W0(t){return t.locals[q0]}var vd=0;function wd(){return vd}var Px="MATILDA_CODE_BENCHMARK_API",Mx=1e3,H0=2e5;function Ox(){let e=0;return r=>{if(e+=1,e===1||e%100===0){let n=r.data,s=[];n?.errorKind&&s.push(`errorKind=${n.errorKind}`),n?.intent&&s.push(`intent=${n.intent}`),n?.pathHash&&s.push(`pathHash=${n.pathHash}`);let i=s.length>0?` (${s.join(" ")})`:"";D(`matilda serve: fs audit emit is the default no-op \u2014 ${e} event(s) dropped so far. Latest type=${r.type}${i}. Inject deps.fsFactory in createServeApp to wire audit into the EventBus.`)}}}var U0=!1;function bd(t){return t.injected?t.injected:ad({boundWorkspace:t.boundWorkspace,trusted:t.trusted,emit:t.emit??Ox()})}var Dx=20,Fx=100,Jr=class extends Error{constructor(e){super(`Invalid cursor: "${e}" is not a valid numeric cursor`),this.name="InvalidCursorError"}};async function Uc(t,e,r){let n=Math.min(Math.max(r?.size??Dx,1),Fx),s;if(r?.cursor){let p=Number(r.cursor);if(!Number.isFinite(p))throw new Jr(r.cursor);s=p}let i=s===void 0,o=new kr(e),a=await o.listSessions({cursor:s,size:n}),c=new Map;for(let p of a.items)c.set(p.sessionId,{sessionId:p.sessionId,workspaceCwd:p.cwd,createdAt:p.startTime,updatedAt:new Date(p.mtime).toISOString(),title:p.customTitle??p.prompt,clientCount:0,hasActivePrompt:!1});let d=t.listWorkspaceSessions(e);for(let p of d){let f=c.get(p.sessionId);f?c.set(p.sessionId,{...f,...p,createdAt:f.createdAt,title:p.title??f.title,updatedAt:p.updatedAt??f.updatedAt,clientCount:p.clientCount,hasActivePrompt:p.hasActivePrompt}):i&&!await o.sessionExists(p.sessionId)&&c.set(p.sessionId,{...p,createdAt:p.createdAt,clientCount:p.clientCount,hasActivePrompt:p.hasActivePrompt})}let u=[...c.values()].sort((p,f)=>{let g=Date.parse(p.updatedAt??p.createdAt);return Date.parse(f.updatedAt??f.createdAt)-g}),l=a.nextCursor!=null?String(a.nextCursor):void 0;return{sessions:u,nextCursor:l}}var Lx=["protocol","baseUrl","apiKey","models","advancedConfig"];function Nx(t){let e=Lx.filter(r=>cu(t,r));return{id:t.id,label:t.label,description:t.description,...t.uiGroup?{uiGroup:t.uiGroup}:{},protocol:t.protocol,...t.protocolOptions?{protocolOptions:[...t.protocolOptions]}:{},...t.baseUrl!==void 0?{baseUrl:t.baseUrl}:{},...typeof t.envKey=="string"?{envKey:t.envKey}:{},...t.models?{models:t.models.map(r=>({id:r.id,...r.contextWindowSize!==void 0?{contextWindowSize:r.contextWindowSize}:{},...r.enableThinking!==void 0?{enableThinking:r.enableThinking}:{},...r.modalities?{modalities:r.modalities}:{},...r.description?{description:r.description}:{}}))}:{},...t.modelsEditable!==void 0?{modelsEditable:t.modelsEditable}:{},...t.apiKeyPlaceholder?{apiKeyPlaceholder:t.apiKeyPlaceholder}:{},...typeof t.documentationUrl=="string"?{documentationUrl:t.documentationUrl}:{},...t.showAdvancedConfig!==void 0?{showAdvancedConfig:t.showAdvancedConfig}:{},...t.uiLabels?{uiLabels:t.uiLabels}:{},steps:e}}function $x(t){let e=Wi.map(Nx),r=n=>e.filter(s=>s.uiGroup===n).map(s=>s.id);return{v:1,workspaceCwd:t,providers:e,groups:[{id:"third-party",label:"Third-party Providers",description:"Choose a built-in provider and connect with an API key",providerIds:r("third-party")},{id:"custom",label:"Custom Provider",description:"Manually connect a local server, proxy, or unsupported provider",providerIds:r("custom")}]}}function Bx(t){if(!Array.isArray(t))return;let e=t.map(r=>typeof r=="string"?r.trim():"").filter(r=>r.length>0);return e.length>0?[...new Set(e)]:void 0}function V0(t,e){if(!(typeof t!="number"||!Number.isInteger(t)||!Number.isFinite(t)||t<=0||t>e))return t}function qx(t){let e=t.split(":");if(e.length!==2)return;let[r,n]=e;if(!/^[0-9a-f]{1,4}$/i.test(r)||!/^[0-9a-f]{1,4}$/i.test(n))return;let s=Number.parseInt(r,16),i=Number.parseInt(n,16);return`${s>>8&255}.${s&255}.${i>>8&255}.${i&255}`}function jx(t){let e=t.split(":",1)[0];if(!(!e||!/^[0-9a-f]{1,4}$/i.test(e)))return Number.parseInt(e,16)}function yd(t){let r=(t.endsWith(".")?t.slice(0,-1):t).toLowerCase();if(r==="localhost"||r.endsWith(".localhost"))return!0;let n=r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,s=md.isIP(n);if(s===4){let i=n.split(".").map(c=>Number(c)),[o,a]=i;return o===0||o===10||o===127||o===100&&a!==void 0&&a>=64&&a<=127||o===169&&a===254||o===172&&a!==void 0&&a>=16&&a<=31||o===192&&a===168}if(s===6){if(n==="::"||n==="::1")return!0;let i=jx(n);if(i!==void 0&&(i>=65152&&i<=65215||(i&65024)===64512))return!0;if(n.startsWith("::ffff:")){let o=n.slice(7);if(md.isIP(o)===4)return yd(o);let a=qx(o);return a?yd(a):!0}}return!1}function Wx(t,e){if(t==null)return;if(typeof t!="string")return null;let r=t.trim();if(!r)return;let n;try{n=new URL(r)}catch{return null}return n.protocol!=="http:"&&n.protocol!=="https:"||n.username||n.password||!e&&yd(n.hostname)?null:n.toString().replace(/\/$/,"")}function Hx(t,e){let r=t.providerId,n=t.apiKey;if(typeof r!="string"||r.trim().length===0||typeof n!="string"||n.trim().length===0)return{ok:!1,code:"invalid_request",error:"`providerId` and `apiKey` are required"};let s=t.protocol,i=Wx(t.baseUrl,e?.allowPrivateBaseUrl===!0);if(i===null)return{ok:!1,code:"invalid_base_url",error:"`baseUrl` must be an http(s) URL without credentials or blocked private-network host"};let o=Bx(t.modelIds),a=t.advancedConfig&&typeof t.advancedConfig=="object"?t.advancedConfig:void 0,c=a?.multimodal&&typeof a.multimodal=="object"?a.multimodal:void 0,d=V0(a?.contextWindowSize,1e7),u=V0(a?.maxTokens,1e7),l=a?{...typeof a.enableThinking=="boolean"?{enableThinking:a.enableThinking}:{},...c?{multimodal:{...typeof c.image=="boolean"?{image:c.image}:{},...typeof c.pdf=="boolean"?{pdf:c.pdf}:{},...typeof c.audio=="boolean"?{audio:c.audio}:{},...typeof c.video=="boolean"?{video:c.video}:{}}}:{},...d!==void 0?{contextWindowSize:d}:{},...u!==void 0?{maxTokens:u}:{}}:void 0;return{ok:!0,value:{providerId:r.trim(),...typeof s=="string"&&s.trim()?{protocol:s.trim()}:{},...i?{baseUrl:i}:{},apiKey:n,...o?{modelIds:o}:{},...l?{advancedConfig:l}:{}}}}function Ux(t){let e=t.path.replace(/\/$/,"")||"/";if(t.method==="POST"&&e==="/session")return{route:"POST /session"};if(t.method==="POST"&&e==="/sessions/delete")return{route:"POST /sessions/delete"};if(t.method==="GET"&&e==="/daemon/status")return{route:"GET /daemon/status"};let r=e.match(/^\/session\/([^/]+)\/(load|resume|prompt|cancel|recap|btw|mid-turn-message|model|shell|detach|rewind|approval-mode|language|a2ui-action)$/),n=r?.[1],s=r?.[2];if(n&&s&&t.method==="POST")return{route:`POST /session/:id/${s}`,sessionId:n};let i=e.match(/^\/session\/([^/]+)\/metadata$/);if(i?.[1]&&t.method==="PATCH")return{route:"PATCH /session/:id/metadata",sessionId:i[1]};let o=e.match(/^\/session\/([^/]+)\/permission\/([^/]+)$/);if(o?.[1]&&o?.[2]&&t.method==="POST"){let g=o[2];return{route:"POST /session/:id/permission/:requestId",sessionId:o[1],...g.length<=Pi&&Mi.test(g)?{permissionRequestId:g}:{}}}let a=e.match(/^\/permission\/([^/]+)$/);if(a?.[1]&&t.method==="POST"){let g=a[1];return{route:"POST /permission/:requestId",...g.length<=Pi&&Mi.test(g)?{permissionRequestId:g}:{}}}let d=e.match(/^\/session\/([^/]+)$/)?.[1];if(d&&t.method==="DELETE")return{route:"DELETE /session/:id",sessionId:d};if(t.method==="GET"&&/^\/workspace\/[^/]+\/sessions$/.test(e))return{route:"GET /workspace/:id/sessions"};if(t.method==="POST"&&e==="/workspace/init")return{route:"POST /workspace/init"};if(t.method==="POST"&&e==="/workspace/reload")return{route:"POST /workspace/reload"};if(e.match(/^\/workspace\/mcp\/([^/]+)\/restart$/)?.[1]&&t.method==="POST")return{route:"POST /workspace/mcp/:server/restart"};if(t.method==="POST"&&e==="/workspace/mcp/servers")return{route:"POST /workspace/mcp/servers"};if(e.match(/^\/workspace\/mcp\/servers\/([^/]+)$/)?.[1]&&t.method==="DELETE")return{route:"DELETE /workspace/mcp/servers/:name"};if(t.method==="POST"&&e==="/workspace/auth/device-flow")return{route:"POST /workspace/auth/device-flow"};if(e.match(/^\/workspace\/auth\/device-flow\/([^/]+)$/)?.[1]&&t.method==="DELETE")return{route:"DELETE /workspace/auth/device-flow/:id"};if(e.match(/^\/workspace\/tools\/([^/]+)\/enable$/)?.[1]&&t.method==="POST")return{route:"POST /workspace/tools/:name/enable"};if(e==="/workspace/settings"){if(t.method==="GET")return{route:"GET /workspace/settings"};if(t.method==="POST")return{route:"POST /workspace/settings"}}}function Vx(t){let e=Yn(t);return(r,n,s)=>{let i=Ux(r);if(!i){s();return}let o=r.get(Q0),a=o!==void 0&&o!==""&&o.length<=Pi&&Mi.test(o)?o:void 0,c=Date.now();Ld({method:r.method,route:i.route,workspaceHash:e,...i.sessionId?{sessionId:i.sessionId}:{},...i.permissionRequestId?{permissionRequestId:i.permissionRequestId}:{},...a?{clientId:a}:{}},async d=>await new Promise((u,l)=>{let p=!1,f=()=>{p||(p=!0,Nd(d,n.statusCode),Wd(Date.now()-c,i.route,n.statusCode),u())};n.once("finish",f),n.once("close",f);try{s()}catch(g){qi(d,g),l(g)}})).catch(s)}}var Ti=class extends Error{deadlineMs;constructor(e){super(`prompt exceeded the ${e}ms deadline`),this.name="PromptDeadlineExceededError",this.deadlineMs=e}};function z0(t,e){if(!(t===void 0||!Number.isFinite(t)||t<=0))return e===void 0||!Number.isFinite(e)||e<=0?t:Math.min(t,e)}var zx=5;function Gx(t){return t===void 0?zx:t===0||t===Number.POSITIVE_INFINITY?null:t}function Sd(t,e=()=>t.port,r={}){let n=(0,gd.default)(),s=r.boundWorkspace??Ye(t.workspace??process.cwd());!r.fsFactory&&!r.bridge&&!U0&&(U0=!0,process.stderr.write(`matilda serve: createServeApp default fsFactory uses trusted=false \u2014 agent ACP writeTextFile calls will reject with untrusted_workspace. Inject deps.fsFactory (with explicit trust) or deps.bridge to override.
716
+ `));let i=bd({boundWorkspace:s,injected:r.fsFactory,trusted:!1}),o=typeof t.token=="string"&&t.token.length>0,a=t.enableSessionShell===!0&&o,c=r.bridge??gr({maxSessions:t.maxSessions,maxPendingPromptsPerSession:t.maxPendingPromptsPerSession,eventRingSize:t.eventRingSize,boundWorkspace:s,sessionShellCommandEnabled:a,statusProvider:Mn(),fileSystem:pi(i)}),d=-1,u=new Set;n.use((b,h,y)=>{let A=b.headers.origin;if(A){let k=e();k!==d&&(d=k,u=new Set([`http://127.0.0.1:${k}`,`http://localhost:${k}`,`http://[::1]:${k}`,`http://host.docker.internal:${k}`])),u.has(A)&&delete b.headers.origin}y()}),n.locals.fsFactory=i,n.locals.boundWorkspace=s;let l=new Map;for(let b of r.deviceFlowProviders??[])l.set(b.providerId,b);l.has("matilda-oauth")||l.set("matilda-oauth",new li);let p={publish(b,h){c.publishWorkspaceEvent({type:`auth_device_flow_${b.type}`,data:b.data,...h?{originatorClientId:h}:{}})}},f=r.deviceFlowRegistry??new ni({events:p,audit:{record(b){let h=b.deviceFlowId.slice(0,8),y=["[serve] auth.device-flow:",`provider=${b.providerId}`,`deviceFlowId=${h}...`,b.clientId?`clientId=${b.clientId}`:"clientId=-",`status=${b.status}`];if(b.errorKind&&y.push(`errorKind=${b.errorKind}`),b.expiresInMs!==void 0&&y.push(`expiresInMs=${Math.max(0,b.expiresInMs)}`),b.hint){let k=b.hint.length>1024?`${b.hint.slice(0,1024)}\u2026[+${b.hint.length-1024} bytes truncated]`:b.hint;y.push(`hint=${JSON.stringify(k)}`)}D(y.join(" "))}},resolveProvider:b=>l.get(b)});zm(n,f);let{daemonLog:g}=r,v=(b,h,y)=>Z0(b,h,y,g),x=(b,h,y)=>a_(b,h,y,g),O=r.workspace??Ri({boundWorkspace:s,contextFilename:r.contextFilename??"MATILDA.md",statusProvider:Mn(),isChannelLive:()=>c.isChannelLive(),persistDisabledTools:r.persistDisabledTools??(async()=>{throw new Error("setWorkspaceToolEnabled requires persistDisabledTools in ServeAppDeps")}),queryWorkspaceStatus:(b,h)=>c.queryWorkspaceStatus(b,h),invokeWorkspaceCommand:(b,h,y)=>c.invokeWorkspaceCommand(b,h,y),publishWorkspaceEvent:b=>c.publishWorkspaceEvent(b)});if(t.allowOrigins&&t.allowOrigins.length>0){let b=ti(t.allowOrigins);if(b.allowAny&&!t.token)throw new Error("Refusing to start with --allow-origin '*' but no bearer token configured. '*' admits any cross-origin browser to the API; without a token, any local page can drive the daemon. Set a token or list specific origins instead of '*'.");n.use(Wm(b))}else n.use(yc);n.use(wc(t.hostname,e));let P=(b,h)=>{try{h.type("html").set("X-Frame-Options","DENY").set("Content-Security-Policy","default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'").send(a0(e()))}catch(y){D(`matilda serve: /demo render failed: ${y instanceof Error?y.message:String(y)}`),h.status(500).json({error:"Failed to render demo page"})}},q=(b,h)=>{let y=b.query.deep;if(!(y==="1"||y==="true"||y==="")){h.status(200).json({status:"ok"});return}try{h.status(200).json({status:"ok",sessions:c.sessionCount,pendingPermissions:c.pendingPermissionCount,...le?{rateLimitHits:le.getHitCounts()}:{}})}catch(k){D(`matilda serve: /health deep probe failed: ${k instanceof Error?k.message:String(k)}`),h.status(503).json({status:"degraded"})}},ae=_t(t.hostname)&&!t.requireAuth;if(ae&&(n.get("/health",q),n.get("/demo",P)),g){let b=/\/session\/([^/]+)/;n.use((h,y,A)=>{let{method:k,path:S}=h;if(k==="GET"&&S==="/health"||k==="POST"&&S.endsWith("/heartbeat"))return A();let R=Date.now();y.on("finish",()=>{try{let F=y.statusCode;if(k==="GET"&&S.endsWith("/events")&&F===200)return;let H=Date.now()-R,X=S.match(b)?.[1],pe=h.headers["x-matilda-client-id"],de={route:`${k} ${S}`,...X?{sessionId:X}:{},...pe?{clientId:pe}:{},status:F,durationMs:H};F>=400?g.warn("request completed",de):g.info("request completed",de)}catch{}}),A()})}n.use(bc(t.token));let le;if(t.rateLimit){let b=t.rateLimitWindowMs??6e4;le=B0({tiers:{prompt:{windowMs:b,max:t.rateLimitPrompt??10},mutation:{windowMs:b,max:t.rateLimitMutation??30},read:{windowMs:b,max:t.rateLimitRead??120}},hostname:t.hostname,onLimitReached:g?(h,y,A)=>{g.warn(`rate limit hit${A>0?` (${A} suppressed)`:""}`,{tier:h,key:y.slice(0,64)})}:void 0,onError:g?(h,y)=>{g.warn(`rate limiter error (fail-open): ${h instanceof Error?h.message:String(h)}`,{path:y})}:void 0}),n.use(le.middleware)}n.use(gd.default.json({limit:"10mb"})),n.use((b,h,y,A)=>{G0(y,b)||A(b)}),ae||(n.get("/health",q),n.get("/demo",P));let V=Sc({tokenConfigured:o,requireAuth:t.requireAuth===!0});n.use(Vx(s));function Se(b,h,y){return{originatorClientId:y,route:h,workspaceCwd:s}}let Te=[...Eu.map(b=>b.code),"auto"],Ze=()=>ki(void 0,{requireAuth:t.requireAuth===!0,mcpPoolActive:t.mcpPoolActive!==!1,allowOriginActive:t.allowOrigins!==void 0&&t.allowOrigins.length>0,...t.promptDeadlineMs!==void 0?{promptDeadlineMs:t.promptDeadlineMs}:{},...t.writerIdleTimeoutMs!==void 0?{writerIdleTimeoutMs:t.writerIdleTimeoutMs}:{},persistSettingAvailable:r.persistSetting!==void 0,sessionShellCommandEnabled:a,rateLimit:t.rateLimit===!0,reloadAvailable:r.workspace!==void 0}),Me={};if(n.get("/daemon/status",async(b,h)=>{let y=r0(b.query.detail);if(!y.ok||!y.detail){h.status(400).json({error:"detail must be one of: summary, full",code:"invalid_detail"});return}try{h.status(200).json(await n0(y.detail,{opts:t,boundWorkspace:s,bridge:c,workspace:O,daemonLog:g,matildaCodeVersion:r.matildaCodeVersion,acpHandle:Me.current,rateLimiter:le,getRestSseActive:wd,features:Ze(),protocolVersions:Ai(),supportedDeviceFlowProviders:Array.from(l.keys()),deviceFlowRegistry:f,sessionShellCommandEnabled:a}))}catch(A){D(`matilda serve: /daemon/status failed: ${A instanceof Error?A.message:String(A)}`),h.status(500).json({error:"Failed to build daemon status",code:"daemon_status_failed"})}}),n.get("/capabilities",(b,h)=>{let y={v:Xc,protocolVersions:Ai(),...r.matildaCodeVersion?{matildaCodeVersion:r.matildaCodeVersion}:{},mode:t.mode,features:Ze(),modelServices:[],workspaceCwd:s,transports:["rest"],policy:{permission:c.permissionPolicy},limits:{maxPendingPromptsPerSession:Gx(t.maxPendingPromptsPerSession)},supportedLanguages:Te};h.status(200).json(y)}),n.get("/workspace/mcp",async(b,h)=>{try{let y=Se(b,"GET /workspace/mcp");h.status(200).json(await O.getWorkspaceMcpStatus(y))}catch(y){v(h,y,{route:"GET /workspace/mcp"})}}),n.get("/workspace/mcp/:server/tools",async(b,h)=>{let y=b.params.server;if(!y||typeof y!="string"){h.status(400).json({error:"Server name path parameter is required",code:"invalid_server_name"});return}if(y.length>rr){h.status(400).json({error:`Server name exceeds ${rr}-character limit`,code:"invalid_server_name"});return}try{h.status(200).json(await c.getWorkspaceMcpToolsStatus(y))}catch(A){v(h,A,{route:"GET /workspace/mcp/:server/tools"})}}),n.get("/workspace/skills",async(b,h)=>{try{let y=Se(b,"GET /workspace/skills");h.status(200).json(await O.getWorkspaceSkillsStatus(y))}catch(y){v(h,y,{route:"GET /workspace/skills"})}}),n.get("/workspace/tools",async(b,h)=>{try{h.status(200).json(await c.getWorkspaceToolsStatus())}catch(y){v(h,y,{route:"GET /workspace/tools"})}}),n.get("/workspace/providers",async(b,h)=>{try{let y=Se(b,"GET /workspace/providers");h.status(200).json(await O.getWorkspaceProvidersStatus(y))}catch(y){v(h,y,{route:"GET /workspace/providers"})}}),_g(n,{bridge:c,boundWorkspace:s,mutate:V,parseClientId:me,safeBody:we}),Dg(n,{bridge:c,boundWorkspace:s,mutate:V,parseClientId:me,safeBody:we}),n.get("/workspace/env",async(b,h)=>{try{let y=Se(b,"GET /workspace/env");h.status(200).json(await O.getWorkspaceEnvStatus(y))}catch(y){v(h,y,{route:"GET /workspace/env"})}}),n.get("/workspace/preflight",async(b,h)=>{try{let y=Se(b,"GET /workspace/preflight");h.status(200).json(await O.getWorkspacePreflightStatus(y))}catch(y){v(h,y,{route:"GET /workspace/preflight"})}}),n.get("/workspace/hooks",async(b,h)=>{try{let y=Se(b,"GET /workspace/hooks");h.status(200).json(await O.getWorkspaceHooksStatus(y))}catch(y){v(h,y,{route:"GET /workspace/hooks"})}}),n.get("/workspace/extensions",async(b,h)=>{try{let y=Se(b,"GET /workspace/extensions");h.status(200).json(await O.getWorkspaceExtensionsStatus(y))}catch(y){v(h,y,{route:"GET /workspace/extensions"})}}),I0(n,{parseClientId:me}),R0(n,{bridge:c,mutate:V,parseClientId:me,safeBody:we}),r.persistSetting){let b=r.persistSetting;O0(n,{boundWorkspace:s,mutate:V,safeBody:we,persistSetting:b,broadcastSettingsChanged:(h,y,A,k)=>{c.publishWorkspaceEvent({type:"settings_changed",data:{key:h,value:y,scope:A},...k?{originatorClientId:k}:{}})},parseAndValidateClientId:(h,y)=>tr(h,y,c)})}$0(n,{boundWorkspace:s,mutate:V,safeBody:we,getMcpServers:async b=>{let h=Se(b,"POST /session/:id/a2ui-action");return(await O.getWorkspaceMcpStatus(h)).servers??[]}}),n.post("/workspace/auth/device-flow",V({strict:!0}),async(b,h)=>{let A=we(b).providerId;if(typeof A!="string"||A.length===0){h.status(400).json({error:"`providerId` must be a non-empty string",code:"invalid_request"});return}if(!l.has(A)){h.status(400).json({error:`Unsupported device-flow provider: ${A}`,code:"unsupported_provider",supportedProviders:Array.from(l.keys())});return}let k=A,S=me(b,h);if(S!==null)try{let{view:R,attached:F}=await f.start({providerId:k,...S!==void 0?{initiatorClientId:S}:{}});h.status(F?200:201).json(r_(R,F,S))}catch(R){if(R instanceof hr){h.status(400).json({error:R.message,code:"unsupported_provider"});return}if(R instanceof mr){h.status(409).json({error:R.message,code:"too_many_active_flows"});return}if(R instanceof vt){h.status(502).json({error:R.message,code:"upstream_error"});return}v(h,R,{route:"POST /workspace/auth/device-flow"})}}),n.get("/workspace/auth/device-flow/:id",V({strict:!0}),async(b,h)=>{let y=b.params.id;if(!y){h.status(404).json({error:"Device-flow id required",code:"device_flow_not_found"});return}let A=f.get(y);if(!A){h.status(404).json({error:`Device-flow ${y} not found`,code:"device_flow_not_found"});return}let k=me(b,h);k!==null&&(!Ed(A,k)&&qt()&&D(`matilda serve debug: GET /workspace/auth/device-flow/${y} redacted verification fields \u2014 caller-clientId mismatch (initiator=${A.initiatorClientId??"anonymous"}, caller=${k??"anonymous"})`),h.status(200).json(n_(A,k)))}),n.delete("/workspace/auth/device-flow/:id",V({strict:!0}),(b,h)=>{let y=b.params.id;if(!y){h.status(404).json({error:"Device-flow id required",code:"device_flow_not_found"});return}let A=me(b,h);if(A===null)return;if(f.cancel(y,A)===void 0){h.status(404).json({error:`Device-flow ${y} not found`,code:"device_flow_not_found"});return}h.status(204).end()}),n.get("/workspace/auth/status",(b,h)=>{let y=f.listPending();h.status(200).json({v:1,workspaceCwd:s,providers:[],pendingDeviceFlows:y.map(A=>({deviceFlowId:A.deviceFlowId,providerId:A.providerId,...A.expiresAt!==void 0?{expiresAt:A.expiresAt}:{}})),supportedDeviceFlowProviders:Array.from(l.keys())})}),n.get("/workspace/auth/providers",(b,h)=>{h.status(200).json($x(s))}),process.env[Px]==="true"&&n.post("/benchmark/prompt",V({strict:!0}),async(b,h)=>{let y=we(b),A=Xx(y.prompt,h);if(A===void 0)return;let k=y.sessionId,S=typeof k=="string"&&k.length>0?k:void 0;if(k!==void 0&&S===void 0){h.status(400).json({error:"`sessionId` must be a non-empty string when provided",code:"invalid_session_id"});return}let R=y.deadlineMs,F;if(R!=null){if(typeof R!="number"||!Number.isFinite(R)||!Number.isInteger(R)||R<=0){h.status(400).json({error:"`deadlineMs` must be a positive integer (milliseconds)",code:"invalid_deadline_ms"});return}F=R}let H=me(b,h);if(H===null)return;let Z=H,X,pe,de=hd.randomUUID(),re=new AbortController,xe=z0(t.promptDeadlineMs,F),he;xe!==void 0&&(he=setTimeout(()=>{re.signal.aborted||re.abort(new Ti(xe))},xe),he.unref());let K=Date.now();try{let Y=!1;if(S===void 0){let ne=typeof y.modelServiceId=="string"?y.modelServiceId:void 0,ye=await c.spawnOrAttach({workspaceCwd:s,sessionScope:"thread",...ne!==void 0?{modelServiceId:ne}:{},...H!==void 0?{clientId:H}:{}});S=ye.sessionId,Z=ye.clientId,Y=!0,y.keepSession!==!0&&(X=ye.sessionId,pe=ye.clientId)}let Ee=c.getSessionLastEventId(S),et={text:"",eventCount:0},Oe=new AbortController,Fe=Zx(c,S,de,Ee,Oe.signal,et).catch(ne=>{if(!(ne instanceof DOMException&&(ne.name==="AbortError"||ne.name==="TimeoutError")))throw ne}),Le=await c.sendPrompt(S,{sessionId:S,prompt:A},re.signal,{...Z!==void 0?{clientId:Z}:{},promptId:de});await Promise.race([Fe,e_(Mx)]),Oe.abort(),h.status(200).json({v:1,sessionId:S,promptId:de,createdSession:Y,keptSession:X===void 0,latencyMs:Date.now()-K,text:et.text,stopReason:Le.stopReason,usage:Le.usage??null,eventCount:et.eventCount,terminalType:et.terminalType??null})}catch(Y){v(h,Y,{route:"POST /benchmark/prompt"})}finally{he!==void 0&&clearTimeout(he),re.abort(),X!==void 0&&c.closeSession(X,pe!==void 0?{clientId:pe}:void 0).catch(Y=>{D(`matilda serve: benchmark session cleanup failed for ${it(X)}: ${it(Y instanceof Error?Y.message:String(Y))}`)})}}),n.post("/workspace/auth/provider",V({strict:!0}),async(b,h)=>{if(!r.installAuthProvider){h.status(501).json({error:"Auth provider installation is not implemented by this daemon",code:"not_implemented"});return}let y=Hx(we(b),{allowPrivateBaseUrl:t.allowPrivateAuthBaseUrl===!0});if(!y.ok){h.status(400).json({error:y.error,code:y.code});return}let A=y.value,k=Wi.find(S=>S.id===A.providerId);if(!k){h.status(400).json({error:`Unsupported auth provider: ${A.providerId}`,code:"unsupported_provider"});return}if(A.protocol){let S=k.protocolOptions&&k.protocolOptions.length?k.protocolOptions:[k.protocol];if(!S.includes(A.protocol)){h.status(400).json({error:`protocol must be one of: ${S.join(", ")}`,code:"unsupported_protocol"});return}}try{h.status(200).json(await r.installAuthProvider(A))}catch(S){v(h,S,{route:"POST /workspace/auth/provider",providerId:A.providerId})}}),n.post("/session",V(),async(b,h)=>{let y=we(b),A="cwd"in y;if(A&&typeof y.cwd!="string"){h.status(400).json({error:"`cwd` must be a string absolute path when provided"});return}if(A&&y.cwd.length>wt){h.status(400).json({error:`\`cwd\` exceeds the ${wt}-character limit`});return}let k=A?y.cwd:s;if(!Ci.isAbsolute(k)){h.status(400).json({error:"`cwd` must be an absolute path when provided"});return}let S=typeof y.modelServiceId=="string"?y.modelServiceId:void 0,R=y.sessionScope,F;if(R!==void 0){if(R!=="single"&&R!=="thread"){h.status(400).json({error:'`sessionScope` must be "single" or "thread" when provided',code:"invalid_session_scope"});return}F=R}let H=me(b,h);if(H!==null)try{let Z=await c.spawnOrAttach({workspaceCwd:k,modelServiceId:S,...H!==void 0?{clientId:H}:{},...F!==void 0?{sessionScope:F}:{}});if(g&&g.info(Z.attached?"session attached":"session spawned",{sessionId:Z.sessionId,clientId:Z.clientId}),!h.writable){g&&g.warn("session reaped (client disconnected before response)",{sessionId:Z.sessionId,attached:Z.attached}),Z.attached?c.detachClient(Z.sessionId,Z.clientId).catch(()=>{}):c.killSession(Z.sessionId,{requireZeroAttaches:!0}).catch(()=>{});return}h.status(200).json(Z)}catch(Z){v(h,Z,{route:"POST /session"})}});let Ue=b=>async(h,y)=>{let A=st(h,y);if(!A)return;let k=we(h),S=t_(k,s,y);if(S===void 0)return;let R=me(h,y);if(R!==null)try{let F=b==="load"?await c.loadSession({sessionId:A,workspaceCwd:S,...R!==void 0?{clientId:R}:{}}):await c.resumeSession({sessionId:A,workspaceCwd:S,...R!==void 0?{clientId:R}:{}});if(g&&g.info(`session ${b}${F.attached?" (attached)":""}`,{sessionId:F.sessionId,clientId:F.clientId}),!y.writable){F.attached?c.detachClient(F.sessionId,F.clientId).catch(()=>{}):c.killSession(F.sessionId,{requireZeroAttaches:!0}).catch(()=>{});return}y.status(200).json(F)}catch(F){v(y,F,{route:`POST /session/:id/${b}`,sessionId:A})}};n.post("/session/:id/load",V(),Ue("load")),n.post("/session/:id/resume",V(),Ue("resume")),n.post("/session/:id/branch",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let A=we(b),k=typeof A?.name=="string"?A.name:void 0;k&&(k=k.replace(/[\x00-\x1F\x7F-\x9F]/g,""),k.length>200&&(k=k.slice(0,200)));let S=me(b,h);if(S!==null)try{let R=await c.branchSession(y,{name:k},{clientId:S});if(!h.writable){R.attached?c.detachClient(R.sessionId,R.clientId).catch(()=>{}):c.killSession(R.sessionId,{requireZeroAttaches:!0}).catch(()=>{});return}h.status(201).json(R)}catch(R){v(h,R,{route:"POST /session/:id/branch",sessionId:y})}}),n.get("/session/:id/context",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionContextStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/context",sessionId:y})}}),n.get("/session/:id/context-usage",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionContextUsageStatus(y,{detail:b.query.detail==="true"}))}catch(A){v(h,A,{route:"GET /session/:id/context-usage",sessionId:y})}}),n.get("/session/:id/stats",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionStatsStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/stats",sessionId:y})}}),n.get("/session/:id/supported-commands",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionSupportedCommandsStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/supported-commands",sessionId:y})}}),n.get("/session/:id/tasks",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionTasksStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/tasks",sessionId:y})}}),n.get("/session/:id/hooks",async(b,h)=>{let y=st(b,h);if(y!==null)try{h.status(200).json(await c.getSessionHooksStatus(y))}catch(A){v(h,A,{route:"GET /session/:id/hooks",sessionId:y})}}),n.post("/session/:id/tasks/:taskId/cancel",V({strict:!0}),async(b,h)=>{let y=b.params.id,A=b.params.taskId;if(!y||!A){h.status(400).json({error:"`sessionId` and `taskId` route parameters are required"});return}let S=we(b).kind;if(S!=="agent"&&S!=="shell"&&S!=="monitor"){h.status(400).json({error:'`kind` must be "agent", "shell", or "monitor"'});return}try{h.status(200).json(await c.cancelSessionTask(y,A,S))}catch(R){v(h,R,{route:"POST /session/:id/tasks/:taskId/cancel",sessionId:y})}}),n.post("/session/:id/goal/clear",V({strict:!0}),async(b,h)=>{let y=b.params.id;if(!y){h.status(400).json({error:"`sessionId` route parameter is required"});return}try{h.status(200).json(await c.clearSessionGoal(y))}catch(A){v(h,A,{route:"POST /session/:id/goal/clear",sessionId:y})}}),n.post("/session/:id/prompt",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=A.prompt;if(!Array.isArray(k)||k.length===0){h.status(400).json({error:"`prompt` is required and must be a non-empty array of content blocks"});return}if(!k.every(he=>typeof he=="object"&&he!==null&&!Array.isArray(he))){h.status(400).json({error:"each `prompt` element must be an object (content block)"});return}let S=A.deadlineMs,R;if(S!=null){if(typeof S!="number"||!Number.isFinite(S)||!Number.isInteger(S)||S<=0){h.status(400).json({error:"`deadlineMs` must be a positive integer (milliseconds)",code:"invalid_deadline_ms"});return}R=S}let F=me(b,h);if(F===null)return;let H=hd.randomUUID(),Z={...A};delete Z.deadlineMs;let X;try{X=c.getSessionLastEventId(y)}catch(he){v(h,he,{route:"POST /session/:id/prompt",sessionId:y});return}$d("matilda-code.prompt_id",H);let pe=new AbortController,de=z0(t.promptDeadlineMs,R),re;de!==void 0&&(re=setTimeout(()=>{pe.signal.aborted||pe.abort(new Ti(de))},de),re.unref());let xe;try{xe=c.sendPrompt(y,{...Z,sessionId:y,prompt:k},pe.signal,{...F!==void 0?{clientId:F}:{},promptId:H})}catch(he){re!==void 0&&clearTimeout(re),g&&he instanceof Cr&&g.warn("prompt admission rejected: queue full",{sessionId:y,promptId:H,...F!==void 0?{clientId:F}:{},limit:he.limit,pendingCount:he.pendingCount}),v(h,he,{route:"POST /session/:id/prompt",sessionId:y});return}xe.then(()=>{g&&g.info("prompt turn completed",{sessionId:y,promptId:H,clientId:F})},he=>{if(g){let K=he instanceof Error?he.name:void 0;g.warn(`prompt turn failed: ${K?`[${K}] `:""}${he instanceof Error?he.message:String(he)}`,{sessionId:y,promptId:H,clientId:F})}}).finally(()=>{re!==void 0&&clearTimeout(re)}).catch(()=>{}),g&&g.info("prompt enqueued",{sessionId:y,promptId:H,clientId:F}),h.status(202).json({promptId:H,lastEventId:X})}),n.post("/session/:id/heartbeat",V(),(b,h)=>{let y=st(b,h);if(y===null)return;let A=me(b,h);if(A!==null)try{let k=c.recordHeartbeat(y,A!==void 0?{clientId:A}:void 0);h.status(200).json(k)}catch(k){v(h,k,{route:"POST /session/:id/heartbeat",sessionId:y})}}),n.post("/session/:id/detach",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let A=me(b,h);if(A!==null)try{await c.detachClient(y,A),h.status(204).end()}catch(k){v(h,k,{route:"POST /session/:id/detach",sessionId:y})}}),n.post("/session/:id/cancel",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=me(b,h);if(k!==null)try{await c.cancelSession(y,{...A,sessionId:y},k!==void 0?{clientId:k}:void 0),g&&g.info("cancel sent",{sessionId:y,clientId:k}),h.status(204).end()}catch(S){v(h,S,{route:"POST /session/:id/cancel",sessionId:y})}}),n.delete("/session/:id",async(b,h)=>{let y=b.params.id,A=me(b,h);if(A!==null)try{await c.closeSession(y,A!==void 0?{clientId:A}:void 0),h.status(204).end()}catch(k){v(h,k,{route:"DELETE /session/:id",sessionId:y})}}),n.post("/sessions/delete",V(),async(b,h)=>{if(me(b,h)===null)return;let k=we(b).sessionIds;if(!Array.isArray(k)||k.length===0||k.length>100||!k.every(S=>typeof S=="string")){h.status(400).json({error:"`sessionIds` must be a non-empty string array (max 100)",code:"invalid_request"});return}try{let S=[...new Set(k)],R=await Promise.allSettled(S.map(async X=>(await c.closeSession(X),X))),F=[],H=[];for(let X=0;X<R.length;X++){let pe=R[X],de=S[X];if(pe.status==="fulfilled")H.push(de);else{let re=pe.reason;if(re instanceof ie)H.push(de);else{let xe=re instanceof Error?re.message:String(re);D(`matilda serve: closeSession failed for ${it(de)}: ${it(xe)}`),F.push({sessionId:de,error:xe})}}}let Z=await new kr(s).removeSessions(H);for(let X of Z.errors){let pe=X.error instanceof Error?X.error.message:String(X.error);D(`matilda serve: removeSession failed for ${it(X.sessionId)}: ${it(pe)}`)}h.status(200).json({removed:Z.removed,notFound:Z.notFound,errors:[...F,...Z.errors.map(X=>({sessionId:X.sessionId,error:X.error instanceof Error?X.error.message:String(X.error)}))]})}catch(S){let R=S instanceof Error?S.message:String(S);D(`matilda serve: failed to batch delete sessions: ${it(R)}`),h.status(500).json({error:"Failed to delete sessions",code:"sessions_delete_failed"})}}),n.patch("/session/:id/metadata",async(b,h)=>{let y=b.params.id,A=we(b),k=me(b,h);if(k===null)return;let S=A.displayName;if(S!==void 0&&typeof S!="string"){h.status(400).json({error:"`displayName` must be a string",code:"invalid_metadata",field:"displayName"});return}let R=typeof S=="string"?S.slice(0,256):void 0;try{let F=c.updateSessionMetadata(y,{displayName:R},k!==void 0?{clientId:k}:void 0);if(R!==void 0)try{await new kr(s).renameSession(y,R)}catch{}h.status(200).json({sessionId:y,...F})}catch(F){v(h,F,{route:"PATCH /session/:id/metadata",sessionId:y})}}),n.get("/workspace/:id/sessions",async(b,h)=>{let y=b.params.id??"";if(!Ci.isAbsolute(y)){h.status(400).json({error:"`:id` must decode to an absolute workspace path"});return}let A=Ye(y);if(A!==s){h.status(400).json({error:`Workspace mismatch: daemon is bound to "${s}"`,code:"workspace_mismatch",boundWorkspace:s,requestedWorkspace:A});return}try{let k=typeof b.query.cursor=="string"?b.query.cursor:void 0,S=b.query.size,R=typeof S=="string"?parseInt(S,10):void 0,F=await Uc(c,A,{cursor:k,size:Number.isFinite(R)?R:void 0});h.status(200).json({sessions:F.sessions,...F.nextCursor!=null?{nextCursor:F.nextCursor}:{}})}catch(k){if(k instanceof Jr){h.status(400).json({error:k.message,code:"invalid_cursor"});return}D(`matilda serve: failed to list sessions for workspace ${it(A)}: ${it(k instanceof Error?k.message:String(k))}`),h.status(500).json({error:"Failed to list sessions",code:"session_list_failed"})}}),n.post("/session/:id/model",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=A.modelId;if(typeof k!="string"||!k){h.status(400).json({error:"`modelId` is required and must be a non-empty string"});return}let S=me(b,h);if(S!==null)try{let R=await c.setSessionModel(y,{...A,sessionId:y,modelId:k},S!==void 0?{clientId:S}:void 0);h.status(200).json(R)}catch(R){v(h,R,{route:"POST /session/:id/model",sessionId:y})}}),n.post("/session/:id/recap",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let A=me(b,h);if(A!==null)try{let k=await c.generateSessionRecap(y,A!==void 0?{clientId:A}:void 0);if(g){let S=k.recap;g.info(S?`recap generated len=${S.length}`:"recap returned null",{sessionId:y,clientId:A})}h.status(200).json(k)}catch(k){v(h,k,{route:"POST /session/:id/recap",sessionId:y})}}),n.post("/session/:id/btw",V(),async(b,h)=>{let y=st(b,h);if(y===null)return;let k=we(b).question;if(typeof k!="string"||k.trim().length===0||k.length>Rr){h.status(400).json({error:`\`question\` is required, must be a non-empty string, and at most ${Rr} characters`});return}let S=new AbortController,R=()=>{h.writableEnded||S.abort()};h.once("close",R);let F=me(b,h);if(F===null){h.off("close",R);return}try{let H=await c.generateSessionBtw(y,k.trim(),S.signal,F!==void 0?{clientId:F}:void 0);h.status(200).json(H)}catch(H){if(H instanceof DOMException&&H.name==="AbortError"&&S.signal.aborted)return;v(h,H,{route:"POST /session/:id/btw",sessionId:y})}finally{h.off("close",R)}});let be=16*1024;n.post("/session/:id/mid-turn-message",V(),(b,h)=>{let y=st(b,h);if(y===null)return;let k=we(b).message,S=typeof k=="string"?k.trim():"";if(S.length===0){h.status(400).json({error:"`message` is required and must be a non-empty string"});return}if(S.length>be){h.status(400).json({error:`\`message\` must be at most ${be} characters`});return}let R=me(b,h);if(R!==null)try{let F=c.enqueueMidTurnMessage(y,S,R!==void 0?{clientId:R}:void 0);h.status(200).json(F)}catch(F){v(h,F,{route:"POST /session/:id/mid-turn-message",sessionId:y})}}),n.post("/session/:id/shell",V({strict:!0}),async(b,h)=>{let y=b.params.id;if(!a){v(h,new bt,{route:"POST /session/:id/shell",sessionId:y});return}let A=me(b,h);if(A===null)return;if(A===void 0){v(h,new St,{route:"POST /session/:id/shell",sessionId:y});return}let S=we(b).command;if(typeof S!="string"||S.trim().length===0){h.status(400).json({error:"`command` is required and must be a non-empty string"});return}let R=new AbortController,F=()=>{h.writableEnded||R.abort()};h.once("close",F);try{let H=await c.executeShellCommand(y,S.trim(),R.signal,{clientId:A});g&&g.info("shell command completed",{sessionId:y,clientId:A,exitCode:H.exitCode}),h.status(200).json(H)}catch(H){if(H instanceof DOMException&&H.name==="AbortError"&&R.signal.aborted)return;v(h,H,{route:"POST /session/:id/shell",sessionId:y})}finally{h.off("close",F)}}),n.get("/session/:id/rewind/snapshots",async(b,h)=>{let y=b.params.id;if(!y){h.status(400).json({error:"`sessionId` route parameter is required"});return}try{h.status(200).json(await c.getRewindSnapshots(y))}catch(A){v(h,A,{route:"GET /session/:id/rewind/snapshots",sessionId:y})}}),n.post("/session/:id/rewind",V({strict:!0}),async(b,h)=>{let y=b.params.id,k=we(b).promptId;if(typeof k!="string"||k.length===0){h.status(400).json({error:"`promptId` is required and must be a non-empty string",code:"missing_prompt_id"});return}let S=me(b,h);if(S!==null)try{let R=await c.rewindSession(y,{promptId:k},S!==void 0?{clientId:S}:void 0);h.status(200).json(R)}catch(R){v(h,R,{route:"POST /session/:id/rewind",sessionId:y})}}),n.post("/session/:id/approval-mode",V({strict:!0}),async(b,h)=>{let y=b.params.id,A=we(b),k=A.mode,S=A.persist;if(typeof k!="string"||!tt.includes(k)){h.status(400).json({error:"`mode` is required and must be one of the allowed values",code:"invalid_approval_mode",allowed:tt});return}if(S!==void 0&&typeof S!="boolean"){h.status(400).json({error:"`persist` must be a boolean when provided",code:"invalid_persist_flag"});return}let R=me(b,h);if(R!==null)try{let F=await c.setSessionApprovalMode(y,k,{persist:S===!0},R!==void 0?{clientId:R}:void 0);h.status(200).json(F)}catch(F){v(h,F,{route:"POST /session/:id/approval-mode",sessionId:y})}}),n.post("/session/:id/language",V(),async(b,h)=>{let y=b.params.id,A=we(b),k=A.language,S=A.syncOutputLanguage;if(typeof k!="string"||!Te.includes(k)){h.status(400).json({error:"`language` is required and must be one of: "+Te.join(", "),code:"invalid_language",allowed:Te});return}if(S!==void 0&&typeof S!="boolean"){h.status(400).json({error:"`syncOutputLanguage` must be a boolean when provided",code:"invalid_sync_flag"});return}let R=me(b,h);if(R!==null)try{let F=await c.setSessionLanguage(y,{language:k,syncOutputLanguage:S===!0},R!==void 0?{clientId:R}:void 0);h.status(200).json(F)}catch(F){v(h,F,{route:"POST /session/:id/language",sessionId:y})}}),n.post("/workspace/mcp/:server/restart",V({strict:!0}),async(b,h)=>{let y=b.params.server;if(!y||typeof y!="string"){h.status(400).json({error:"Server name path parameter is required",code:"invalid_server_name"});return}if(y.length>rr){h.status(400).json({error:`Server name exceeds ${rr}-character limit`,code:"invalid_server_name"});return}let A=tr(b,h,c);if(A===null)return;let k,S=b.query.entryIndex;if(S!==void 0&&S!=="*"){let R=typeof S=="string"?S:void 0,F=R!==void 0?Number.parseInt(R,10):NaN;if(!Number.isInteger(F)||F<0||String(F)!==R){h.status(400).json({error:'`entryIndex` query parameter must be a non-negative integer or "*"',code:"invalid_entry_index"});return}k=F}try{let R=Se(b,"POST /workspace/mcp/:server/restart",A),F=await O.restartMcpServer(R,y,k!==void 0?{entryIndex:k}:void 0);h.status(200).json(F)}catch(R){v(h,R,{route:"POST /workspace/mcp/:server/restart"})}});for(let[b,h]of[["enable","enable"],["disable","disable"],["authenticate","authenticate"],["clear-auth","clear-auth"]])n.post(`/workspace/mcp/:server/${b}`,V({strict:!0}),async(y,A)=>{let k=y.params.server;if(!k||typeof k!="string"){A.status(400).json({error:"Server name path parameter is required",code:"invalid_server_name"});return}if(k.length>rr){A.status(400).json({error:`Server name exceeds ${rr}-character limit`,code:"invalid_server_name"});return}let S=tr(y,A,c);if(S!==null)try{let R=await c.manageMcpServer(k,h,S);A.status(200).json(R)}catch(R){v(A,R,{route:`POST /workspace/mcp/:server/${b}`})}});return n.post("/workspace/mcp/servers",V({strict:!0}),async(b,h)=>{let y=we(b),A=y.name;if(!X0(A,h))return;let k=y.config;if(typeof k!="object"||k===null||Array.isArray(k)){h.status(400).json({error:"`config` must be a non-null object",code:"missing_required_field",field:"config"});return}let S=tr(b,h,c);if(S!==null){if(!S){h.status(400).json({error:"`X-Matilda-Client-Id` header is required for runtime MCP mutation",code:"missing_client_id"});return}try{let R=await c.addRuntimeMcpServer(A,k,S);h.status(200).json(R)}catch(R){v(h,R,{route:"POST /workspace/mcp/servers"})}}}),n.delete("/workspace/mcp/servers/:name",V({strict:!0}),async(b,h)=>{let y=b.params.name??"";if(!X0(y,h))return;let A=tr(b,h,c);if(A!==null){if(!A){h.status(400).json({error:"`X-Matilda-Client-Id` header is required for runtime MCP mutation",code:"missing_client_id"});return}try{let k=await c.removeRuntimeMcpServer(y,A);h.status(200).json(k)}catch(k){v(h,k,{route:"DELETE /workspace/mcp/servers/:name"})}}}),n.post("/workspace/init",V({strict:!0}),async(b,h)=>{let A=we(b).force;if(A!==void 0&&typeof A!="boolean"){h.status(400).json({error:"`force` must be a boolean when provided",code:"invalid_force_flag"});return}let k=tr(b,h,c);if(k!==null)try{let S=Se(b,"POST /workspace/init",k),R=await O.initWorkspace(S,{force:A===!0});h.status(200).json(R)}catch(S){v(h,S,{route:"POST /workspace/init"})}}),n.post("/workspace/reload",V({strict:!0}),async(b,h)=>{let y=tr(b,h,c);if(y!==null)try{let A=Se(b,"POST /workspace/reload",y),k=await O.reload(A);h.status(200).json(k)}catch(A){v(h,A,{route:"POST /workspace/reload"})}}),n.post("/workspace/tools/:name/enable",V({strict:!0}),async(b,h)=>{let y=b.params.name;if(!y||typeof y!="string"){h.status(400).json({error:"Tool name path parameter is required",code:"invalid_tool_name"});return}let A=y.trim();if(A.length===0){h.status(400).json({error:"Tool name path parameter is required",code:"invalid_tool_name"});return}if(A.length>K0){h.status(400).json({error:`Tool name exceeds ${K0}-character limit`,code:"invalid_tool_name"});return}let S=we(b).enabled;if(typeof S!="boolean"){h.status(400).json({error:"`enabled` is required and must be a boolean",code:"invalid_enabled_flag"});return}let R=tr(b,h,c);if(R!==null)try{let F=Se(b,"POST /workspace/tools/:name/enable",R),H=await O.setWorkspaceToolEnabled(F,A,S);h.status(200).json(H)}catch(F){v(h,F,{route:"POST /workspace/tools/:name/enable"})}}),n.post("/session/:id/permission/:requestId",V(),(b,h)=>{let y=b.params.id,A=b.params.requestId,k=Y0(b,h);if(k===void 0)return;let S=me(b,h);if(S===null)return;let R=J0(b),F={...S!==void 0?{clientId:S}:{},fromLoopback:R},H;try{H=c.respondToSessionPermission(y,A,k,F)}catch(Z){x(h,Z,{route:"POST /session/:id/permission/:requestId",sessionId:y});return}if(!H){h.status(404).json({error:"No pending permission request for session",sessionId:y,requestId:A});return}h.status(200).json({})}),n.post("/permission/:requestId",V(),(b,h)=>{let y=b.params.requestId,A=Y0(b,h);if(A===void 0)return;let k=me(b,h);if(k===null)return;let S=J0(b),R={...k!==void 0?{clientId:k}:{},fromLoopback:S},F;try{F=c.respondToPermission(y,A,R)}catch(H){x(h,H,{route:"POST /permission/:requestId"});return}if(!F){h.status(404).json({error:"No pending permission request",requestId:y});return}h.status(200).json({})}),n.get("/session/:id/events",(b,h)=>{let y=b.params.id,A=o_(b.headers["last-event-id"]),k=i_(b.query.maxQueued,h);if(k===null)return;let S,R=new AbortController;try{let K=b.query.snapshot==="1";S=c.subscribeEvents(y,{signal:R.signal,lastEventId:A,...k!==void 0?{maxQueued:k}:{},...K?{snapshot:!0}:{}})[Symbol.asyncIterator]()}catch(K){if(K instanceof Tu){D(`matilda serve: subscriber limit reached for session ${y} (limit=${K.limit}); rejecting new SSE client with 429`),h.setHeader("Retry-After","5"),h.status(429).json({error:K.message,code:"subscriber_limit_exceeded",limit:K.limit});return}v(h,K,{route:"GET /session/:id/events",sessionId:y});return}if(g){let K=Date.now(),Y=b.headers["x-matilda-client-id"];g.info("SSE stream opened",{sessionId:y,clientId:Y}),h.on("close",()=>{try{g.info("SSE stream closed",{sessionId:y,clientId:Y,durationMs:Date.now()-K})}catch{}})}h.status(200),h.setHeader("Content-Type","text/event-stream"),h.setHeader("Cache-Control","no-cache, no-transform"),h.setHeader("Connection","keep-alive"),h.setHeader("X-Accel-Buffering","no"),h.flushHeaders(),vd++;let F=!0;h.on("close",()=>{F&&(F=!1,vd--)});let H=Promise.resolve(),Z=t.writerIdleTimeoutMs!==void 0&&t.writerIdleTimeoutMs>0,X=Z?Date.now():0,pe=K=>new Promise((Y,Ee)=>{if(h.writableEnded){Y();return}let et;try{et=h.write(K)}catch(ne){Ee(ne);return}if(et){Z&&(X=Date.now()),Y();return}let Oe=()=>{h.off("close",Fe),h.off("error",Le),Z&&(X=Date.now()),Y()},Fe=()=>{h.off("drain",Oe),h.off("error",Le),Y()},Le=ne=>{h.off("drain",Oe),h.off("close",Fe),Ee(ne)};h.once("drain",Oe),h.once("close",Fe),h.once("error",Le)}),de=K=>{let Y=H.then(()=>pe(K));return H=Y.catch(()=>{}),Y};de(`retry: 3000
717
717
 
718
718
  `).catch(()=>{});let re=setInterval(()=>{h.writableEnded||de(`: heartbeat
719
719
 
@@ -726,7 +726,7 @@ data: ${i}
726
726
  `)+`
727
727
  `:""}function rv(t){let e=t.now.toISOString(),r=p_(t.ctx);return`${e} [${t.level}] [DAEMON] ${r}${t.message}
728
728
  ${f_(t.err)}`}var nv={info:()=>{},warn:()=>{},error:()=>{},raw:()=>{},getLogPath:()=>"",getDaemonId:()=>"",flush:()=>Promise.resolve()};function h_(){let t=process.env.MATILDA_DAEMON_LOG_FILE;return t?["0","false","off","no"].includes(t.trim().toLowerCase()):!1}function m_(t,e){let r=sv.createHash("sha256").update(e).digest("hex").slice(0,8);return`serve-${t}-${r}`}function ov(t){if(h_())return nv;let e=t.pid??process.pid,r=t.now??(()=>new Date),n=t.stderr??D,s=t.baseDir??Xn.getGlobalDebugDir(),i=m_(e,t.boundWorkspace),o=Di.join(s,"daemon"),a=Di.join(o,`${i}.log`);try{Zr.mkdirSync(o,{recursive:!0});let p=rv({level:"INFO",message:`daemon started pid=${e} workspace=${t.boundWorkspace}`,now:r()});Zr.appendFileSync(a,p)}catch(p){return n(`matilda serve: daemon log disabled \u2014 init failed: ${p instanceof Error?p.message:String(p)}`),nv}try{let p=Di.join(o,"latest");Ad(p,a,{fallbackCopy:!1}).catch(()=>{})}catch{}let c=Promise.resolve(),d=!1,u=p=>{c=c.then(()=>Zr.promises.appendFile(a,p).catch(f=>{d||(d=!0,n(`matilda serve: daemon log write failed \u2014 entering degraded mode: ${f instanceof Error?f.message:String(f)}`))}))},l=(p,f,g,v)=>{let x=rv({level:p,message:f,now:r(),ctx:g,err:v});n(x.trimEnd()),u(x)};return{info:(p,f)=>l("INFO",p,f),warn:(p,f)=>l("WARN",p,f),error:(p,f,g)=>l("ERROR",p,g,f??void 0),raw:(p,f="info")=>{let g=f.toUpperCase(),v=`${r().toISOString()} [${g}] [DAEMON] ${p}
729
- `;u(v)},getLogPath:()=>a,getDaemonId:()=>i,flush:()=>c}}var en="MATILDA_SERVER_TOKEN",av="MATILDA_SERVE_PROMPT_DEADLINE_MS",cv="MATILDA_SERVE_WRITER_IDLE_TIMEOUT_MS",dv=5e3;function Id(t){return Number.isFinite(t)&&Number.isInteger(t)&&t>0}function g_(t){return t===Number.POSITIVE_INFINITY||Number.isFinite(t)&&Number.isInteger(t)&&t>=0}var uv=2147483647;function v_(t,e){if(e>uv)throw new TypeError(`Invalid ${t}: ${e}. Exceeds maximum JS timer delay of ${uv} ms (~24.8 days); Node would silently compress longer delays to 1ms.`)}function lv(t,e){if(e===void 0)return;let r=e.trim(),n=Number(r);if(!Id(n))throw new Error(`Invalid ${t}="${e}": must be a positive integer (milliseconds).`);return n}function y_(t,e,r){return{getTelemetryEnabled:()=>t.enabled??!1,getTelemetryOtlpEndpoint:()=>t.otlpEndpoint??Xd,getTelemetryOtlpProtocol:()=>t.otlpProtocol??"grpc",getTelemetryOtlpTracesEndpoint:()=>t.otlpTracesEndpoint,getTelemetryOtlpLogsEndpoint:()=>t.otlpLogsEndpoint,getTelemetryOtlpMetricsEndpoint:()=>t.otlpMetricsEndpoint,getTelemetryTarget:()=>t.target??Jd,getTelemetryOutfile:()=>t.outfile,getTelemetryIncludeSensitiveSpanAttributes:()=>t.includeSensitiveSpanAttributes??!1,getTelemetryResourceAttributes:()=>({"service.instance.id":r,...t.resourceAttributes??{}}),getTelemetryMetricsIncludeSessionId:()=>t.metrics?.includeSessionId??!1,getTelemetryResourceAttributeWarnings:()=>t.resourceAttributeWarnings??[],getCliVersion:()=>e,getSessionId:()=>r,isInteractive:()=>!1,getOutboundCorrelationPropagateTraceContext:()=>!1}}var Hn=class extends Error{name="InvalidPolicyConfigError";constructor(e){super(e)}};function w_(t={},e=D){let r=new Set(Ln.permission_mediation.modes);if(t.permissionStrategy!==void 0&&!r.has(t.permissionStrategy))throw new Hn(`matilda serve: invalid policy.permissionStrategy "${String(t.permissionStrategy)}"; must be one of ${Array.from(r).join(", ")}`);if(t.consensusQuorum!==void 0&&(!Number.isInteger(t.consensusQuorum)||t.consensusQuorum<1))throw new Hn(`matilda serve: invalid policy.consensusQuorum ${String(t.consensusQuorum)}; must be a positive integer`);let n=t.consensusQuorum!==void 0&&t.permissionStrategy==="consensus";return t.consensusQuorum!==void 0&&t.permissionStrategy!=="consensus"&&e('matilda serve: policy.consensusQuorum is set but policy.permissionStrategy is not "consensus"; the override will be ignored.'),{permissionPolicy:t.permissionStrategy,permissionConsensusQuorum:n?t.consensusQuorum:void 0}}function b_(t){return t.startsWith("[")?t:t.includes(":")?`[${t.includes("%")?t.replace(/%/g,"%25"):t}]`:t}function S_(t){if(typeof t=="string"){let e=t.trim();return e===""?void 0:e}if(Array.isArray(t)){for(let e of t)if(typeof e=="string"){let r=e.trim();if(r!=="")return r}return}}var pv=new Map;function Wn(t,e){let n=(pv.get(t)??Promise.resolve()).then(e,e);return pv.set(t,n),n}function E_(t,e){let r=t.modelIds?.map(s=>s.trim()).filter(s=>s.length>0),n=r&&r.length>0?r:vu(e);return[...new Set(n)]}function I_(t,e){let r=t.protocol??e.protocol,n=gu(e,t.baseUrl);return{...e.protocolOptions?{protocol:r}:{},baseUrl:n,apiKey:t.apiKey.trim(),modelIds:E_(t,e),...t.advancedConfig?{advancedConfig:t.advancedConfig}:{}}}function x_(t){return t.preheatBridge!==void 0?t.preheatBridge:process.env.VITEST_WORKER_ID===void 0}async function __(t,e={}){let r=t.token??process.env[en],n=typeof r=="string"&&r.trim().length>0?r.trim():void 0,s=t.enableSessionShell===!0&&n!==void 0;t.enableSessionShell===!0&&n===void 0&&D(`matilda serve: --enable-session-shell ignored because no bearer token is configured. Set ${en} or pass --token to enable direct session shell.`);let i=t.promptDeadlineMs??lv(av,process.env[av]),o=t.writerIdleTimeoutMs??lv(cv,process.env[cv]),a={...t,token:n,promptDeadlineMs:i,writerIdleTimeoutMs:o};if(!a.hostname.startsWith("[")&&a.hostname.split(":").length===2){let[S,R]=a.hostname.split(":");throw new Error(`Invalid --hostname "${a.hostname}": looks like a "host:port" combination. Use --port for the port, e.g. "--hostname ${S} --port ${R}".`)}if(!_t(a.hostname)&&!n)throw new Error(`Refusing to bind ${a.hostname}:${a.port} without a bearer token. Set ${en} or pass --token, or rebind to loopback (127.0.0.1, localhost, ::1, or [::1]).`);if(a.requireAuth&&!n)throw new Error(`Refusing to start with --require-auth set but no bearer token configured. Set ${en} or pass --token, or omit --require-auth to keep the loopback developer default.`);if(a.allowOrigins&&a.allowOrigins.length>0){let S=ti(a.allowOrigins);if(S.allowAny&&!n)throw new Error(`Refusing to start with --allow-origin '*' but no bearer token configured. '*' admits any cross-origin browser to the API; without a token, any local page can drive the daemon. Set ${en} or pass --token, or list specific origins instead of '*'.`);D(`matilda serve: --allow-origin: ${a.allowOrigins.join(", ")}`+(S.allowAny?" (WARNING: `*` admits any cross-origin browser \u2014 bearer token gates API routes; /health and /demo remain pre-auth on loopback unless --require-auth is set)":""))}a.allowPrivateAuthBaseUrl&&D("matilda serve: --allow-private-auth-base-url enabled; /workspace/auth/provider may install localhost/private-network model endpoints. Use only for local development with trusted clients.");let c=a.workspace??process.cwd();if(!hv.isAbsolute(c))throw new Error(`Invalid --workspace "${c}": must be an absolute path.`);try{if(!fv.statSync(c).isDirectory())throw new Error(`Invalid --workspace "${c}": exists but is not a directory.`)}catch(S){if(S&&typeof S=="object"&&"code"in S){let R=S.code;if(R==="ENOENT")throw new Error(`Invalid --workspace "${c}": directory does not exist.`);if(R==="EACCES"||R==="EPERM")throw new Error(`Invalid --workspace "${c}": permission denied (${String(R)}). The path exists but cannot be stat'd by the current user.`)}throw S}let d=Ye(c),u=ov({boundWorkspace:d});if(D(`matilda serve: daemon log \u2192 ${u.getLogPath()||"(disabled)"}`),a.mcpClientBudget!==void 0&&(!Number.isFinite(a.mcpClientBudget)||!Number.isInteger(a.mcpClientBudget)||a.mcpClientBudget<=0))throw new TypeError(`Invalid mcpClientBudget: ${a.mcpClientBudget}. Must be a positive integer.`);if(a.mcpBudgetMode==="enforce"&&a.mcpClientBudget===void 0)throw new Error('mcpBudgetMode="enforce" requires a positive mcpClientBudget. Pass mcpClientBudget=N, or set mcpBudgetMode to "warn" or "off".');if(a.promptDeadlineMs!==void 0){if(!Id(a.promptDeadlineMs))throw new TypeError(`Invalid promptDeadlineMs: ${a.promptDeadlineMs}. Must be a positive integer (milliseconds).`);v_("promptDeadlineMs",a.promptDeadlineMs)}if(a.maxPendingPromptsPerSession!==void 0&&!g_(a.maxPendingPromptsPerSession))throw new TypeError(`Invalid maxPendingPromptsPerSession: ${a.maxPendingPromptsPerSession}. Must be a non-negative integer (0 / Infinity = unlimited).`);if(a.writerIdleTimeoutMs!==void 0&&!Id(a.writerIdleTimeoutMs))throw new TypeError(`Invalid writerIdleTimeoutMs: ${a.writerIdleTimeoutMs}. Must be a positive integer (milliseconds).`);if(a.channelIdleTimeoutMs!==void 0&&(!Number.isFinite(a.channelIdleTimeoutMs)||!Number.isInteger(a.channelIdleTimeoutMs)||a.channelIdleTimeoutMs<0))throw new TypeError(`Invalid channelIdleTimeoutMs: ${a.channelIdleTimeoutMs}. Must be a non-negative integer (milliseconds, 0 = immediate kill).`);let l=process.env.MATILDA_SERVE_NO_MCP_POOL==="1";a.mcpPoolActive===void 0&&l&&(a.mcpPoolActive=!1);let p={MATILDA_SERVE_MCP_CLIENT_BUDGET:a.mcpClientBudget!==void 0?String(a.mcpClientBudget):void 0,MATILDA_SERVE_MCP_BUDGET_MODE:a.mcpBudgetMode},f,g,v,x;try{x=Tt(d),f=S_(x.merged.context?.fileName);let S=x.merged.policy??{},R=w_(S);g=R.permissionPolicy,v=R.permissionConsensusQuorum}catch(S){if(S instanceof Hn)throw S;D(`matilda serve: could not read settings for context.fileName / policy.* (${S instanceof Error?S.message:String(S)}); falling back to defaults. Restart with a valid settings.json to apply context.fileName / policy.* overrides.`)}let O=Yn(d),P=await Fd({env:process.env,settings:x?.merged.telemetry}),q=await _u();Md(y_(P,q,`daemon:${O}:${process.pid}`)),qd();let U=Bd();U.metrics={sessionLifecycle(S){Hd(S),_r(`Session ${S}.`,{"matilda-code.workspace.hash":O},{eventName:`matilda-code.daemon.session.${S}`})},channelLifecycle(S,R){Ud(S,R),_r(S==="spawn"?"ACP channel spawned.":`ACP channel exited (expected=${R??!0}).`,{...S==="exit"?{"matilda-code.daemon.channel.expected":R??!0}:{}},{eventName:`matilda-code.daemon.channel.${S}`,...R===!1&&S==="exit"?{severityNumber:13}:{}})},promptQueueWait:Vd,promptDuration:zd,cancelled:Kd};let ae=new Oi,le=tv({ring:ae}),V=e.trustedWorkspace??!0,Se=bd({boundWorkspace:d,injected:e.fsFactory,trusted:V,emit:e.fsAuditEmit}),Te=(S,R)=>u.raw(S,R),Ze=xc({onDiagnosticLine:Te}),Me=(S,R,F)=>Wn(S,async()=>{let H=Tt(S),X=H.forScope("Workspace").settings.tools?.disabled,pe=Array.isArray(X)?X.filter(re=>typeof re=="string"):[],de=new Set(pe);F?de.delete(R):de.add(R),H.setValue("Workspace","tools.disabled",[...de].sort())}),Ue=Mn(),be=e.bridge??gr({maxSessions:a.maxSessions,...a.maxPendingPromptsPerSession!==void 0?{maxPendingPromptsPerSession:a.maxPendingPromptsPerSession}:{},...a.eventRingSize!==void 0?{eventRingSize:a.eventRingSize}:{},...a.channelIdleTimeoutMs!==void 0?{channelIdleTimeoutMs:a.channelIdleTimeoutMs}:{},...a.sessionReapIntervalMs!==void 0?{sessionReapIntervalMs:a.sessionReapIntervalMs}:{},...a.sessionIdleTimeoutMs!==void 0?{sessionIdleTimeoutMs:a.sessionIdleTimeoutMs}:{},boundWorkspace:d,sessionShellCommandEnabled:s,childEnvOverrides:p,channelFactory:Ze,onDiagnosticLine:Te,telemetry:U,...g!==void 0?{permissionPolicy:g}:{},...v!==void 0?{permissionConsensusQuorum:v}:{},permissionAudit:le,statusProvider:Ue,fileSystem:pi(Se),persistApprovalMode:(S,R)=>Wn(S,async()=>{Tt(S).setValue("Workspace","tools.approvalMode",R)})}),b=Ri({boundWorkspace:d,contextFilename:f??"MATILDA.md",statusProvider:Ue,isChannelLive:()=>be.isChannelLive(),persistDisabledTools:Me,reloadDaemonEnv:S=>Wn(S,async()=>{let R=Tt(S,{skipLoadEnvironment:!0});return xu(R.merged,S)}),queryWorkspaceStatus:(S,R)=>be.queryWorkspaceStatus(S,R),invokeWorkspaceCommand:(S,R,F)=>be.invokeWorkspaceCommand(S,R,F),publishWorkspaceEvent:S=>be.publishWorkspaceEvent(S)});jd({sessionCount:()=>be.sessionCount,sseCount:()=>wd(),heapUsed:()=>process.memoryUsage().heapUsed});let h=a.port,y=Sd(a,()=>h,{bridge:be,boundWorkspace:d,matildaCodeVersion:q,fsFactory:Se,daemonLog:u,workspace:b,persistDisabledTools:Me,persistSetting:(S,R,F,H)=>Wn(S,async()=>{Tt(S).setValue(R,F,H)}),installAuthProvider:S=>Wn(d,async()=>{let R=wu(S.providerId);if(!R)throw new Error(`Unsupported auth provider: ${S.providerId}`);let F=I_(S,R),H=mu(R,F),Z=Tt(d);return await bu(H,{settings:Cu(Z),doRefreshAuth:!1}),_r("Auth provider installed.",{"matilda-code.daemon.auth.provider_id":R.id,"matilda-code.daemon.auth.auth_type":H.authType}),{v:1,providerId:R.id,providerLabel:R.label,authType:H.authType,...H.modelSelection?.modelId?{modelId:H.modelSelection.modelId}:{},...F.baseUrl?{baseUrl:F.baseUrl}:{},message:`Successfully configured ${R.label}.`}})}),A=Gm(y),k=a.hostname;if(a.hostname.startsWith("[")){let S=a.hostname.slice(1,-1);if(!a.hostname.endsWith("]")||S.length===0||S.includes("]"))throw new Error(`Invalid --hostname "${a.hostname}": brackets indicate an IPv6 literal but the value isn't a clean [addr] form. Pass the address without a trailing :port (use --port for that), e.g. "--hostname [::1] --port 4170".`);k=S}if(a.maxConnections!==void 0&&(Number.isNaN(a.maxConnections)||a.maxConnections<0))throw new TypeError(`Invalid maxConnections: ${a.maxConnections}. Must be >= 0 (0 / Infinity = unlimited).`);return await new Promise((S,R)=>{let F=y.listen(a.port,k,()=>{let H=a.maxConnections??256;H>0&&Number.isFinite(H)&&(F.maxConnections=H);let Z=F.address();h=typeof Z=="object"&&Z?Z.port:a.port;let X=`http://${b_(a.hostname)}:${h}`;Su(`matilda serve listening on ${X} (mode=${a.mode}, workspace=${d})`),D(`matilda serve: bound to workspace ${JSON.stringify(d)}`),n?a.requireAuth&&D("matilda serve: --require-auth enabled (bearer token mandatory on every route, including loopback /health)."):D(`matilda serve: bearer auth disabled (loopback default). Set ${en} to enable.`);let pe=!1,de,re=async K=>{if(pe){u.warn(`received ${K} during drain \u2014 forcing exit`);try{be.killAllSync()}catch(Y){u.error("force-kill error",Y instanceof Error?Y:null)}await u.flush().catch(()=>{}),process.exit(1);return}u.warn(`received ${K}, draining`);try{await xe.close(),await u.flush(),process.exit(0)}catch(Y){u.error("shutdown error",Y instanceof Error?Y:null),await u.flush().catch(()=>{}),process.exit(1)}},xe={server:F,url:X,bridge:be,close:()=>de||(de=new Promise((K,Y)=>{pe=!0;let Ee=!1,et,Oe=ne=>{Ee||(Ee=!0,process.removeListener("SIGINT",re),process.removeListener("SIGTERM",re),Od().catch(ye=>{D(`matilda serve: telemetry shutdown error: ${ye instanceof Error?ye.message:String(ye)}`)}).finally(()=>{let ye=ne??et;ye?Y(ye):K()}))};if(A)try{A.dispose()}catch(ne){u.warn(`device-flow registry dispose error: ${ne instanceof Error?ne.message:String(ne)}`)}let Fe=y.locals?.acpHandle;if(Fe?.dispose)try{Fe.dispose()}catch(ne){u.warn(`ACP handle dispose error: ${ne instanceof Error?ne.message:String(ne)}`)}let Le=W0(y);Le&&(Le.setDraining(!0),Le.dispose()),Dd().catch(ne=>{u.warn(`pre-shutdown metrics flush failed: ${ne instanceof Error?ne.message:String(ne)}`)}).then(()=>{be.shutdown().catch(ne=>{u.error("bridge shutdown error",ne instanceof Error?ne:null),et=ne instanceof Error?ne:new Error(String(ne))}).finally(()=>{let ye,tn=setTimeout(()=>{u.warn(`${dv}ms listener-drain timeout reached; force-closing remaining connections`),F.closeAllConnections(),ye=setTimeout(()=>{u.warn("server.close did not fire 2000ms after force-close; resolving anyway"),Oe()},2e3),ye.unref()},dv);tn.unref(),F.close(nr=>{clearTimeout(tn),ye&&clearTimeout(ye),Oe(nr)})})})}),de)};process.on("SIGINT",re),process.on("SIGTERM",re),F.removeAllListeners("error"),F.on("error",K=>{u.error("server error",K instanceof Error?K:null)}),!e.bridge&&x_(e)&&be.preheat().catch(K=>{D(`matilda serve: ACP preheat failed, will retry on first session: ${K instanceof Error?K.message:String(K)}`)}),y.locals?.acpHandle?.attachServer?.(F),S(xe)});F.once("error",R)})}w();export{Ev as ACP_PREFLIGHT_KINDS,Ki as BridgeTimeoutError,Xc as CAPABILITIES_SCHEMA_VERSION,o0 as CONDITIONAL_SERVE_FEATURES,jE as ENV_NONSECRET_VARS,WE as ENV_PROXY_VARS,qE as ENV_SECRET_VARS,Pt as EVENT_SCHEMA_VERSION,zi as EventBus,Sv as IDLE_HOOK_EVENTS,Or as McpServerNotFoundError,Dr as McpServerRestartFailedError,Ln as SERVE_CAPABILITY_REGISTRY,fe as SERVE_CONTROL_EXT_METHODS,bv as SERVE_ERROR_KINDS,Nn as SERVE_FEATURES,_i as SERVE_PROTOCOL_VERSION,ke as SERVE_STATUS_EXT_METHODS,AI as STAGE1_FEATURES,ot as STATUS_SCHEMA_VERSION,Jc as SUPPORTED_SERVE_PROTOCOL_VERSIONS,ie as SessionNotFoundError,St as SessionShellClientRequiredError,bt as SessionShellDisabledError,ar as WorkspaceInitConflictError,Mr as WorkspaceInitPathEscapeError,cr as WorkspaceInitRaceError,mt as WorkspaceInitSymlinkError,bc as bearerAuth,Cc as buildEnvStatusFromProcess,gr as createAcpSessionBridge,hg as createHttpAcpBridge,Zi as createIdleAcpPreflightCells,ln as createIdleWorkspaceExtensionsStatus,pn as createIdleWorkspaceHooksStatus,Ji as createIdleWorkspaceMcpStatus,Yi as createIdleWorkspaceProvidersStatus,Xi as createIdleWorkspaceSkillsStatus,N4 as createInMemoryChannel,Sc as createMutationGate,Sd as createServeApp,oi as defaultSpawnChannelFactory,yc as denyBrowserOriginCors,ki as getAdvertisedServeFeatures,_I as getRegisteredServeFeatures,kI as getServeFeatures,Ai as getServeProtocolVersions,wc as hostAllowlist,Mt as mapDomainErrorToErrorKind,__ as runMatildaServe};
729
+ `;u(v)},getLogPath:()=>a,getDaemonId:()=>i,flush:()=>c}}var en="MATILDA_SERVER_TOKEN",av="MATILDA_SERVE_PROMPT_DEADLINE_MS",cv="MATILDA_SERVE_WRITER_IDLE_TIMEOUT_MS",dv=5e3;function Id(t){return Number.isFinite(t)&&Number.isInteger(t)&&t>0}function g_(t){return t===Number.POSITIVE_INFINITY||Number.isFinite(t)&&Number.isInteger(t)&&t>=0}var uv=2147483647;function v_(t,e){if(e>uv)throw new TypeError(`Invalid ${t}: ${e}. Exceeds maximum JS timer delay of ${uv} ms (~24.8 days); Node would silently compress longer delays to 1ms.`)}function lv(t,e){if(e===void 0)return;let r=e.trim(),n=Number(r);if(!Id(n))throw new Error(`Invalid ${t}="${e}": must be a positive integer (milliseconds).`);return n}function y_(t,e,r){return{getTelemetryEnabled:()=>t.enabled??!1,getTelemetryOtlpEndpoint:()=>t.otlpEndpoint??Xd,getTelemetryOtlpProtocol:()=>t.otlpProtocol??"grpc",getTelemetryOtlpTracesEndpoint:()=>t.otlpTracesEndpoint,getTelemetryOtlpLogsEndpoint:()=>t.otlpLogsEndpoint,getTelemetryOtlpMetricsEndpoint:()=>t.otlpMetricsEndpoint,getTelemetryTarget:()=>t.target??Jd,getTelemetryOutfile:()=>t.outfile,getTelemetryIncludeSensitiveSpanAttributes:()=>t.includeSensitiveSpanAttributes??!1,getTelemetryResourceAttributes:()=>({"service.instance.id":r,...t.resourceAttributes??{}}),getTelemetryMetricsIncludeSessionId:()=>t.metrics?.includeSessionId??!1,getTelemetryResourceAttributeWarnings:()=>t.resourceAttributeWarnings??[],getCliVersion:()=>e,getSessionId:()=>r,isInteractive:()=>!1,getOutboundCorrelationPropagateTraceContext:()=>!1}}var Hn=class extends Error{name="InvalidPolicyConfigError";constructor(e){super(e)}};function w_(t={},e=D){let r=new Set(Ln.permission_mediation.modes);if(t.permissionStrategy!==void 0&&!r.has(t.permissionStrategy))throw new Hn(`matilda serve: invalid policy.permissionStrategy "${String(t.permissionStrategy)}"; must be one of ${Array.from(r).join(", ")}`);if(t.consensusQuorum!==void 0&&(!Number.isInteger(t.consensusQuorum)||t.consensusQuorum<1))throw new Hn(`matilda serve: invalid policy.consensusQuorum ${String(t.consensusQuorum)}; must be a positive integer`);let n=t.consensusQuorum!==void 0&&t.permissionStrategy==="consensus";return t.consensusQuorum!==void 0&&t.permissionStrategy!=="consensus"&&e('matilda serve: policy.consensusQuorum is set but policy.permissionStrategy is not "consensus"; the override will be ignored.'),{permissionPolicy:t.permissionStrategy,permissionConsensusQuorum:n?t.consensusQuorum:void 0}}function b_(t){return t.startsWith("[")?t:t.includes(":")?`[${t.includes("%")?t.replace(/%/g,"%25"):t}]`:t}function S_(t){if(typeof t=="string"){let e=t.trim();return e===""?void 0:e}if(Array.isArray(t)){for(let e of t)if(typeof e=="string"){let r=e.trim();if(r!=="")return r}return}}var pv=new Map;function Wn(t,e){let n=(pv.get(t)??Promise.resolve()).then(e,e);return pv.set(t,n),n}function E_(t,e){let r=t.modelIds?.map(s=>s.trim()).filter(s=>s.length>0),n=r&&r.length>0?r:au(e);return[...new Set(n)]}function I_(t,e){let r=t.protocol??e.protocol,n=ou(e,t.baseUrl);return{...e.protocolOptions?{protocol:r}:{},baseUrl:n,apiKey:t.apiKey.trim(),modelIds:E_(t,e),...t.advancedConfig?{advancedConfig:t.advancedConfig}:{}}}function x_(t){return t.preheatBridge!==void 0?t.preheatBridge:process.env.VITEST_WORKER_ID===void 0}async function __(t,e={}){let r=t.token??process.env[en],n=typeof r=="string"&&r.trim().length>0?r.trim():void 0,s=t.enableSessionShell===!0&&n!==void 0;t.enableSessionShell===!0&&n===void 0&&D(`matilda serve: --enable-session-shell ignored because no bearer token is configured. Set ${en} or pass --token to enable direct session shell.`);let i=t.promptDeadlineMs??lv(av,process.env[av]),o=t.writerIdleTimeoutMs??lv(cv,process.env[cv]),a={...t,token:n,promptDeadlineMs:i,writerIdleTimeoutMs:o};if(!a.hostname.startsWith("[")&&a.hostname.split(":").length===2){let[S,R]=a.hostname.split(":");throw new Error(`Invalid --hostname "${a.hostname}": looks like a "host:port" combination. Use --port for the port, e.g. "--hostname ${S} --port ${R}".`)}if(!_t(a.hostname)&&!n)throw new Error(`Refusing to bind ${a.hostname}:${a.port} without a bearer token. Set ${en} or pass --token, or rebind to loopback (127.0.0.1, localhost, ::1, or [::1]).`);if(a.requireAuth&&!n)throw new Error(`Refusing to start with --require-auth set but no bearer token configured. Set ${en} or pass --token, or omit --require-auth to keep the loopback developer default.`);if(a.allowOrigins&&a.allowOrigins.length>0){let S=ti(a.allowOrigins);if(S.allowAny&&!n)throw new Error(`Refusing to start with --allow-origin '*' but no bearer token configured. '*' admits any cross-origin browser to the API; without a token, any local page can drive the daemon. Set ${en} or pass --token, or list specific origins instead of '*'.`);D(`matilda serve: --allow-origin: ${a.allowOrigins.join(", ")}`+(S.allowAny?" (WARNING: `*` admits any cross-origin browser \u2014 bearer token gates API routes; /health and /demo remain pre-auth on loopback unless --require-auth is set)":""))}a.allowPrivateAuthBaseUrl&&D("matilda serve: --allow-private-auth-base-url enabled; /workspace/auth/provider may install localhost/private-network model endpoints. Use only for local development with trusted clients.");let c=a.workspace??process.cwd();if(!hv.isAbsolute(c))throw new Error(`Invalid --workspace "${c}": must be an absolute path.`);try{if(!fv.statSync(c).isDirectory())throw new Error(`Invalid --workspace "${c}": exists but is not a directory.`)}catch(S){if(S&&typeof S=="object"&&"code"in S){let R=S.code;if(R==="ENOENT")throw new Error(`Invalid --workspace "${c}": directory does not exist.`);if(R==="EACCES"||R==="EPERM")throw new Error(`Invalid --workspace "${c}": permission denied (${String(R)}). The path exists but cannot be stat'd by the current user.`)}throw S}let d=Ye(c),u=ov({boundWorkspace:d});if(D(`matilda serve: daemon log \u2192 ${u.getLogPath()||"(disabled)"}`),a.mcpClientBudget!==void 0&&(!Number.isFinite(a.mcpClientBudget)||!Number.isInteger(a.mcpClientBudget)||a.mcpClientBudget<=0))throw new TypeError(`Invalid mcpClientBudget: ${a.mcpClientBudget}. Must be a positive integer.`);if(a.mcpBudgetMode==="enforce"&&a.mcpClientBudget===void 0)throw new Error('mcpBudgetMode="enforce" requires a positive mcpClientBudget. Pass mcpClientBudget=N, or set mcpBudgetMode to "warn" or "off".');if(a.promptDeadlineMs!==void 0){if(!Id(a.promptDeadlineMs))throw new TypeError(`Invalid promptDeadlineMs: ${a.promptDeadlineMs}. Must be a positive integer (milliseconds).`);v_("promptDeadlineMs",a.promptDeadlineMs)}if(a.maxPendingPromptsPerSession!==void 0&&!g_(a.maxPendingPromptsPerSession))throw new TypeError(`Invalid maxPendingPromptsPerSession: ${a.maxPendingPromptsPerSession}. Must be a non-negative integer (0 / Infinity = unlimited).`);if(a.writerIdleTimeoutMs!==void 0&&!Id(a.writerIdleTimeoutMs))throw new TypeError(`Invalid writerIdleTimeoutMs: ${a.writerIdleTimeoutMs}. Must be a positive integer (milliseconds).`);if(a.channelIdleTimeoutMs!==void 0&&(!Number.isFinite(a.channelIdleTimeoutMs)||!Number.isInteger(a.channelIdleTimeoutMs)||a.channelIdleTimeoutMs<0))throw new TypeError(`Invalid channelIdleTimeoutMs: ${a.channelIdleTimeoutMs}. Must be a non-negative integer (milliseconds, 0 = immediate kill).`);let l=process.env.MATILDA_SERVE_NO_MCP_POOL==="1";a.mcpPoolActive===void 0&&l&&(a.mcpPoolActive=!1);let p={MATILDA_SERVE_MCP_CLIENT_BUDGET:a.mcpClientBudget!==void 0?String(a.mcpClientBudget):void 0,MATILDA_SERVE_MCP_BUDGET_MODE:a.mcpBudgetMode},f,g,v,x;try{x=Tt(d),f=S_(x.merged.context?.fileName);let S=x.merged.policy??{},R=w_(S);g=R.permissionPolicy,v=R.permissionConsensusQuorum}catch(S){if(S instanceof Hn)throw S;D(`matilda serve: could not read settings for context.fileName / policy.* (${S instanceof Error?S.message:String(S)}); falling back to defaults. Restart with a valid settings.json to apply context.fileName / policy.* overrides.`)}let O=Yn(d),P=await Fd({env:process.env,settings:x?.merged.telemetry}),q=await _u();Md(y_(P,q,`daemon:${O}:${process.pid}`)),qd();let U=Bd();U.metrics={sessionLifecycle(S){Hd(S),_r(`Session ${S}.`,{"matilda-code.workspace.hash":O},{eventName:`matilda-code.daemon.session.${S}`})},channelLifecycle(S,R){Ud(S,R),_r(S==="spawn"?"ACP channel spawned.":`ACP channel exited (expected=${R??!0}).`,{...S==="exit"?{"matilda-code.daemon.channel.expected":R??!0}:{}},{eventName:`matilda-code.daemon.channel.${S}`,...R===!1&&S==="exit"?{severityNumber:13}:{}})},promptQueueWait:Vd,promptDuration:zd,cancelled:Kd};let ae=new Oi,le=tv({ring:ae}),V=e.trustedWorkspace??!0,Se=bd({boundWorkspace:d,injected:e.fsFactory,trusted:V,emit:e.fsAuditEmit}),Te=(S,R)=>u.raw(S,R),Ze=xc({onDiagnosticLine:Te}),Me=(S,R,F)=>Wn(S,async()=>{let H=Tt(S),X=H.forScope("Workspace").settings.tools?.disabled,pe=Array.isArray(X)?X.filter(re=>typeof re=="string"):[],de=new Set(pe);F?de.delete(R):de.add(R),H.setValue("Workspace","tools.disabled",[...de].sort())}),Ue=Mn(),be=e.bridge??gr({maxSessions:a.maxSessions,...a.maxPendingPromptsPerSession!==void 0?{maxPendingPromptsPerSession:a.maxPendingPromptsPerSession}:{},...a.eventRingSize!==void 0?{eventRingSize:a.eventRingSize}:{},...a.channelIdleTimeoutMs!==void 0?{channelIdleTimeoutMs:a.channelIdleTimeoutMs}:{},...a.sessionReapIntervalMs!==void 0?{sessionReapIntervalMs:a.sessionReapIntervalMs}:{},...a.sessionIdleTimeoutMs!==void 0?{sessionIdleTimeoutMs:a.sessionIdleTimeoutMs}:{},boundWorkspace:d,sessionShellCommandEnabled:s,childEnvOverrides:p,channelFactory:Ze,onDiagnosticLine:Te,telemetry:U,...g!==void 0?{permissionPolicy:g}:{},...v!==void 0?{permissionConsensusQuorum:v}:{},permissionAudit:le,statusProvider:Ue,fileSystem:pi(Se),persistApprovalMode:(S,R)=>Wn(S,async()=>{Tt(S).setValue("Workspace","tools.approvalMode",R)})}),b=Ri({boundWorkspace:d,contextFilename:f??"MATILDA.md",statusProvider:Ue,isChannelLive:()=>be.isChannelLive(),persistDisabledTools:Me,reloadDaemonEnv:S=>Wn(S,async()=>{let R=Tt(S,{skipLoadEnvironment:!0});return xu(R.merged,S)}),queryWorkspaceStatus:(S,R)=>be.queryWorkspaceStatus(S,R),invokeWorkspaceCommand:(S,R,F)=>be.invokeWorkspaceCommand(S,R,F),publishWorkspaceEvent:S=>be.publishWorkspaceEvent(S)});jd({sessionCount:()=>be.sessionCount,sseCount:()=>wd(),heapUsed:()=>process.memoryUsage().heapUsed});let h=a.port,y=Sd(a,()=>h,{bridge:be,boundWorkspace:d,matildaCodeVersion:q,fsFactory:Se,daemonLog:u,workspace:b,persistDisabledTools:Me,persistSetting:(S,R,F,H)=>Wn(S,async()=>{Tt(S).setValue(R,F,H)}),installAuthProvider:S=>Wn(d,async()=>{let R=du(S.providerId);if(!R)throw new Error(`Unsupported auth provider: ${S.providerId}`);let F=I_(S,R),H=iu(R,F),Z=Tt(d);return await uu(H,{settings:Cu(Z),doRefreshAuth:!1}),_r("Auth provider installed.",{"matilda-code.daemon.auth.provider_id":R.id,"matilda-code.daemon.auth.auth_type":H.authType}),{v:1,providerId:R.id,providerLabel:R.label,authType:H.authType,...H.modelSelection?.modelId?{modelId:H.modelSelection.modelId}:{},...F.baseUrl?{baseUrl:F.baseUrl}:{},message:`Successfully configured ${R.label}.`}})}),A=Gm(y),k=a.hostname;if(a.hostname.startsWith("[")){let S=a.hostname.slice(1,-1);if(!a.hostname.endsWith("]")||S.length===0||S.includes("]"))throw new Error(`Invalid --hostname "${a.hostname}": brackets indicate an IPv6 literal but the value isn't a clean [addr] form. Pass the address without a trailing :port (use --port for that), e.g. "--hostname [::1] --port 4170".`);k=S}if(a.maxConnections!==void 0&&(Number.isNaN(a.maxConnections)||a.maxConnections<0))throw new TypeError(`Invalid maxConnections: ${a.maxConnections}. Must be >= 0 (0 / Infinity = unlimited).`);return await new Promise((S,R)=>{let F=y.listen(a.port,k,()=>{let H=a.maxConnections??256;H>0&&Number.isFinite(H)&&(F.maxConnections=H);let Z=F.address();h=typeof Z=="object"&&Z?Z.port:a.port;let X=`http://${b_(a.hostname)}:${h}`;Su(`matilda serve listening on ${X} (mode=${a.mode}, workspace=${d})`),D(`matilda serve: bound to workspace ${JSON.stringify(d)}`),n?a.requireAuth&&D("matilda serve: --require-auth enabled (bearer token mandatory on every route, including loopback /health)."):D(`matilda serve: bearer auth disabled (loopback default). Set ${en} to enable.`);let pe=!1,de,re=async K=>{if(pe){u.warn(`received ${K} during drain \u2014 forcing exit`);try{be.killAllSync()}catch(Y){u.error("force-kill error",Y instanceof Error?Y:null)}await u.flush().catch(()=>{}),process.exit(1);return}u.warn(`received ${K}, draining`);try{await xe.close(),await u.flush(),process.exit(0)}catch(Y){u.error("shutdown error",Y instanceof Error?Y:null),await u.flush().catch(()=>{}),process.exit(1)}},xe={server:F,url:X,bridge:be,close:()=>de||(de=new Promise((K,Y)=>{pe=!0;let Ee=!1,et,Oe=ne=>{Ee||(Ee=!0,process.removeListener("SIGINT",re),process.removeListener("SIGTERM",re),Od().catch(ye=>{D(`matilda serve: telemetry shutdown error: ${ye instanceof Error?ye.message:String(ye)}`)}).finally(()=>{let ye=ne??et;ye?Y(ye):K()}))};if(A)try{A.dispose()}catch(ne){u.warn(`device-flow registry dispose error: ${ne instanceof Error?ne.message:String(ne)}`)}let Fe=y.locals?.acpHandle;if(Fe?.dispose)try{Fe.dispose()}catch(ne){u.warn(`ACP handle dispose error: ${ne instanceof Error?ne.message:String(ne)}`)}let Le=W0(y);Le&&(Le.setDraining(!0),Le.dispose()),Dd().catch(ne=>{u.warn(`pre-shutdown metrics flush failed: ${ne instanceof Error?ne.message:String(ne)}`)}).then(()=>{be.shutdown().catch(ne=>{u.error("bridge shutdown error",ne instanceof Error?ne:null),et=ne instanceof Error?ne:new Error(String(ne))}).finally(()=>{let ye,tn=setTimeout(()=>{u.warn(`${dv}ms listener-drain timeout reached; force-closing remaining connections`),F.closeAllConnections(),ye=setTimeout(()=>{u.warn("server.close did not fire 2000ms after force-close; resolving anyway"),Oe()},2e3),ye.unref()},dv);tn.unref(),F.close(nr=>{clearTimeout(tn),ye&&clearTimeout(ye),Oe(nr)})})})}),de)};process.on("SIGINT",re),process.on("SIGTERM",re),F.removeAllListeners("error"),F.on("error",K=>{u.error("server error",K instanceof Error?K:null)}),!e.bridge&&x_(e)&&be.preheat().catch(K=>{D(`matilda serve: ACP preheat failed, will retry on first session: ${K instanceof Error?K.message:String(K)}`)}),y.locals?.acpHandle?.attachServer?.(F),S(xe)});F.once("error",R)})}w();export{Ev as ACP_PREFLIGHT_KINDS,Ki as BridgeTimeoutError,Xc as CAPABILITIES_SCHEMA_VERSION,o0 as CONDITIONAL_SERVE_FEATURES,jE as ENV_NONSECRET_VARS,WE as ENV_PROXY_VARS,qE as ENV_SECRET_VARS,Pt as EVENT_SCHEMA_VERSION,zi as EventBus,Sv as IDLE_HOOK_EVENTS,Or as McpServerNotFoundError,Dr as McpServerRestartFailedError,Ln as SERVE_CAPABILITY_REGISTRY,fe as SERVE_CONTROL_EXT_METHODS,bv as SERVE_ERROR_KINDS,Nn as SERVE_FEATURES,_i as SERVE_PROTOCOL_VERSION,ke as SERVE_STATUS_EXT_METHODS,AI as STAGE1_FEATURES,ot as STATUS_SCHEMA_VERSION,Jc as SUPPORTED_SERVE_PROTOCOL_VERSIONS,ie as SessionNotFoundError,St as SessionShellClientRequiredError,bt as SessionShellDisabledError,ar as WorkspaceInitConflictError,Mr as WorkspaceInitPathEscapeError,cr as WorkspaceInitRaceError,mt as WorkspaceInitSymlinkError,bc as bearerAuth,Cc as buildEnvStatusFromProcess,gr as createAcpSessionBridge,hg as createHttpAcpBridge,Zi as createIdleAcpPreflightCells,ln as createIdleWorkspaceExtensionsStatus,pn as createIdleWorkspaceHooksStatus,Ji as createIdleWorkspaceMcpStatus,Yi as createIdleWorkspaceProvidersStatus,Xi as createIdleWorkspaceSkillsStatus,N4 as createInMemoryChannel,Sc as createMutationGate,Sd as createServeApp,oi as defaultSpawnChannelFactory,yc as denyBrowserOriginCors,ki as getAdvertisedServeFeatures,_I as getRegisteredServeFeatures,kI as getServeFeatures,Ai as getServeProtocolVersions,wc as hostAllowlist,Mt as mapDomainErrorToErrorKind,__ as runMatildaServe};
730
730
  /**
731
731
  * @license
732
732
  * Copyright 2025 Matilda Team