@hydra-acp/cli 0.1.204 → 0.1.205

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 (3) hide show
  1. package/dist/cli.js +172 -172
  2. package/dist/daemon.js +45 -45
  3. package/package.json +1 -1
package/dist/daemon.js CHANGED
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  var vl=Object.defineProperty;var Xn=(s,e)=>()=>(s&&(e=s(s=0)),e);var bl=(s,e)=>{for(var t in e)vl(s,t,{get:e[t],enumerable:!0})};import*as B from"path";import*as vr from"os";function $(s){let e=vr.homedir();if(!e)return s;let t=o=>process.platform==="win32"?o.replace(/\\/g,"/").toLowerCase():o,n=t(e),r=t(s);return r===n?"~":r.startsWith(n+"/")?"~"+s.slice(e.length):s}function Sl(){if(process.env.VITEST)return"vitest";if(process.versions.bun||typeof globalThis.Bun<"u")return"bun";if(process.env.JEST_WORKER_ID!==void 0)return"jest";if(process.env.NODE_TEST_CONTEXT!==void 0)return"node:test"}function Il(s,e){Ci||B.isAbsolute(s)||(Ci=!0,process.stderr.write(`hydra-acp: ${Ri} is relative (${JSON.stringify(s)}); resolved against the current directory to ${e}. Processes started from elsewhere will use a different home and will not see each other's daemon. Set an absolute path.
3
3
  `))}function q(){let s=process.env[Ri];if(s&&s.length>0){let t=B.resolve(s);return Il(s,t),t}let e=Sl();if(e)throw new Error(`HYDRA_ACP_HOME is unset under a test runner (${e}); refusing to fall back to ~/.hydra-acp. The harness must set HYDRA_ACP_HOME \u2014 vitest.setup.ts does this, but \`bun test\` bypasses the vitest config and does not. Run the suite with \`npx vitest run\`, not \`bun test\`.`);return B.join(vr.homedir(),".hydra-acp")}var Ri,Ci,E,K=Xn(()=>{"use strict";Ri="HYDRA_ACP_HOME";Ci=!1;E={home:q,config:()=>B.join(q(),"config.json"),authToken:()=>B.join(q(),"auth-token"),remotes:()=>B.join(q(),"remotes.json"),peers:()=>B.join(q(),"peers.json"),tlsDir:()=>B.join(q(),"tls"),pidFile:()=>B.join(q(),"daemon.pid"),logFile:()=>B.join(q(),"daemon.log"),daemonBootLog:()=>B.join(q(),"daemon-boot.log"),currentLogFile:()=>B.join(q(),"current.log"),registryCache:()=>B.join(q(),"registry.json"),themesDir:()=>B.join(q(),"themes"),ttySessionDir:()=>B.join(q(),"tty"),ttySessionFile:s=>B.join(q(),"tty",s),agentsDir:()=>B.join(q(),"agents"),agentLogFile:s=>B.join(q(),"agents","logs",`${s}.log`),agentInstallDir:(s,e,t)=>B.join(q(),"agents",e,s,t),agentNpmInstallDir:(s,e,t)=>B.join(q(),"agents",e,s,t,`node${process.versions.modules}`),sessionsDir:()=>B.join(q(),"sessions"),sessionDir:s=>B.join(q(),"sessions",s),sessionFile:s=>B.join(q(),"sessions",s,"meta.json"),historyFile:s=>B.join(q(),"sessions",s,"history.jsonl"),historyArchiveFile:(s,e)=>B.join(q(),"sessions",s,`history.jsonl.${e}`),toolsDir:s=>B.join(q(),"sessions",s,"tools"),toolBlobFile:(s,e)=>B.join(q(),"sessions",s,"tools",e),queueFile:s=>B.join(q(),"sessions",s,"queue.ndjson"),tombstonesDir:()=>B.join(q(),"sessions",".tombstones"),tombstoneAgentDir:s=>B.join(q(),"sessions",".tombstones",encodeURIComponent(s)),tombstoneFile:(s,e)=>B.join(q(),"sessions",".tombstones",encodeURIComponent(s),encodeURIComponent(e)),extensionsDir:()=>B.join(q(),"extensions"),extensionLogDir:s=>B.join(q(),"extensions",s),extensionLogFile:s=>B.join(q(),"extensions",s,"current.log"),extensionPidFile:s=>B.join(q(),"extensions",s,"extension.pid"),transformersDir:()=>B.join(q(),"transformers"),transformerLogDir:s=>B.join(q(),"transformers",s),transformerLogFile:s=>B.join(q(),"transformers",s,"current.log"),transformerPidFile:s=>B.join(q(),"transformers",s,"transformer.pid"),transformerState:(s,e)=>B.join(q(),"sessions",s,"transformer-state",e),tuiHistoryFile:s=>B.join(q(),"sessions",s,"prompt-history"),globalTuiHistoryFile:()=>B.join(q(),"prompt-history"),tuiLogFile:()=>B.join(q(),"tui.log"),shimWireLogFile:()=>B.join(q(),"shim-wire.log")}});import*as ge from"fs/promises";import*as Ei from"fs";import*as Pe from"path";import{randomBytes as Cl}from"crypto";async function he(s,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
4
- `;await Tl(s,r,t)}async function El(s,e,t={}){let n=t.rename??ge.rename,r=t.platform??process.platform,o=t.sleep??(i=>new Promise(a=>setTimeout(a,i)));for(let i=0;;i++)try{await n(s,e);return}catch(a){let d=a.code??"";if(!(r==="win32"&&Rl.has(d)&&i<xl-1))throw a;await o(10*(i+1))}}async function Tl(s,e,t={}){let n=await Pl(s),r=Pe.dirname(n);await ge.mkdir(r,{recursive:!0});let o=`${n}.tmp-${process.pid}-${Ml()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await ge.writeFile(o,e,i),await El(o,n)}catch(i){throw await ge.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{Ei.chmodSync(n,t.mode)}catch{}}async function Pl(s){let e;try{e=await ge.lstat(s)}catch(r){if(r.code==="ENOENT")return s;throw r}if(!e.isSymbolicLink())return s;let t=await ge.readlink(s),n=Pe.isAbsolute(t)?t:Pe.resolve(Pe.dirname(s),t);try{let r=await ge.realpath(Pe.dirname(n));return Pe.join(r,Pe.basename(n))}catch(r){if(r.code==="ENOENT")return n;throw r}}async function de(s){let e;try{e=await ge.readFile(s,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}if(e.trim().length!==0)try{return JSON.parse(e)}catch{return}}function Ml(){return Cl(4).toString("hex")}var Rl,xl,He=Xn(()=>{"use strict";Rl=new Set(["EPERM","EACCES","EBUSY"]),xl=10});function ur(s,e){return`${s}:${e}`}var Fu=Xn(()=>{"use strict";K();He()});var Bu={};bl(Bu,{_resetForTests:()=>Yy,clearPin:()=>ci,fetchPeerFingerprint:()=>Ky,formatFingerprint:()=>Du,getPin:()=>Vy,installGlobalTlsTrust:()=>fi,loadPinsFromPeerStore:()=>ui,loadPinsFromStore:()=>Gy,setPin:()=>Vn,sha256Hex:()=>li,wsTlsOptions:()=>pi});import{createHash as Uy}from"crypto";import*as Nu from"tls";import{Agent as By,Dispatcher as Wy,buildConnector as qy,getGlobalDispatcher as zy,setGlobalDispatcher as Jy}from"undici";function Vn(s,e,t){Et.set(ur(s,e),Hu(t))}function ci(s,e){Et.delete(ur(s,e))}function Vy(s,e){return Et.get(ur(s,e))}function Gy(s){Et.clear();for(let e of s.list())e.entry.pinnedFingerprint&&Vn(e.host,e.port,e.entry.pinnedFingerprint)}function ui(s){for(let e of s.list())e.pinnedFingerprint&&Vn(e.host,e.port,e.pinnedFingerprint)}async function Ky(s,e,t={}){let n=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=Nu.connect({host:s,port:e,servername:s,rejectUnauthorized:!1,autoSelectFamily:!0}),a=!1,d=(u,l)=>{if(!a){a=!0,clearTimeout(c);try{i.destroy()}catch{}u?o(u):l&&r(l)}},c=setTimeout(()=>{d(new Error(`TLS connect to ${s}:${e} timed out`))},n);i.once("secureConnect",()=>{let u=i.getPeerCertificate(!1);if(!u||!u.raw){d(new Error(`${s}:${e} did not present a TLS certificate`));return}d(null,li(u.raw))}),i.once("error",u=>d(u))})}function li(s){return Uy("sha256").update(s).digest("hex")}function Du(s){let e=Hu(s),t=e.match(/.{2}/g);return t?t.join(":"):e}function Hu(s){return s.replace(/:/g,"").toLowerCase()}function fi(){if(di)return;di=!0;let s=zy(),e=new By({connect:qy({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(n,r)=>Lu(n,r)})}),t=new Wy;t.dispatch=(n,r)=>{let o=Qy(n.origin);return(o&&ju(o)?e:s).dispatch(n,r)},t.close=(()=>Promise.all([e.close(),s.close()]).then(()=>{})),t.destroy=(n=>Promise.all([e.destroy(n??null),s.destroy(n??null)]).then(()=>{})),Jy(t)}function Qy(s){if(!s)return null;try{return new URL(String(s)).hostname}catch{return null}}function ju(s){for(let e of Et.keys())if(Uu(e)?.host===s)return!0;return!1}function Lu(s,e){if(!e||!e.raw)return new Error(`TLS peer ${s} did not present a certificate`);let t=li(e.raw);for(let[n,r]of Et.entries()){let o=Uu(n);if(o&&o.host===s&&r===t)return}return new Error(`TLS pin mismatch for ${s} (cert sha256 ${Du(t)})`)}function Uu(s){let e=s.lastIndexOf(":");if(e<0)return null;let t=s.slice(0,e),n=Number(s.slice(e+1));return Number.isInteger(n)?{host:t,port:n}:null}function pi(s){return ju(s)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>Lu(e,t)}:{autoSelectFamily:!0}}function Yy(){Et.clear(),di=!1}var Et,di,Gn=Xn(()=>{"use strict";Fu();Et=new Map,di=!1});K();import*as rt from"fs/promises";import{homedir as Tr}from"os";import{z as I}from"zod";K();import*as Mt from"fs/promises";function br(){let s=new Uint8Array(32);crypto.getRandomValues(s);let e="";for(let t of s)e+=t.toString(16).padStart(2,"0");return`hydra_token_${e}`}async function Al(){try{let e=(await Mt.readFile(E.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(s){if(s.code==="ENOENT")return;throw s}}async function Sr(s){await Mt.mkdir(E.home(),{recursive:!0}),await Mt.writeFile(E.authToken(),s+`
4
+ `;await Tl(s,r,t)}async function El(s,e,t={}){let n=t.rename??ge.rename,r=t.platform??process.platform,o=t.sleep??(i=>new Promise(a=>setTimeout(a,i)));for(let i=0;;i++)try{await n(s,e);return}catch(a){let d=a.code??"";if(!(r==="win32"&&Rl.has(d)&&i<xl-1))throw a;await o(10*(i+1))}}async function Tl(s,e,t={}){let n=await Pl(s),r=Pe.dirname(n);await ge.mkdir(r,{recursive:!0});let o=`${n}.tmp-${process.pid}-${Ml()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await ge.writeFile(o,e,i),await El(o,n)}catch(i){throw await ge.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{Ei.chmodSync(n,t.mode)}catch{}}async function Pl(s){let e;try{e=await ge.lstat(s)}catch(r){if(r.code==="ENOENT")return s;throw r}if(!e.isSymbolicLink())return s;let t=await ge.readlink(s),n=Pe.isAbsolute(t)?t:Pe.resolve(Pe.dirname(s),t);try{let r=await ge.realpath(Pe.dirname(n));return Pe.join(r,Pe.basename(n))}catch(r){if(r.code==="ENOENT")return n;throw r}}async function de(s){let e;try{e=await ge.readFile(s,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}if(e.trim().length!==0)try{return JSON.parse(e)}catch{return}}function Ml(){return Cl(4).toString("hex")}var Rl,xl,je=Xn(()=>{"use strict";Rl=new Set(["EPERM","EACCES","EBUSY"]),xl=10});function ur(s,e){return`${s}:${e}`}var Fu=Xn(()=>{"use strict";K();je()});var Bu={};bl(Bu,{_resetForTests:()=>Xy,clearPin:()=>ci,fetchPeerFingerprint:()=>Qy,formatFingerprint:()=>Du,getPin:()=>Gy,installGlobalTlsTrust:()=>fi,loadPinsFromPeerStore:()=>ui,loadPinsFromStore:()=>Ky,setPin:()=>Vn,sha256Hex:()=>li,wsTlsOptions:()=>pi});import{createHash as By}from"crypto";import*as Nu from"tls";import{Agent as Wy,Dispatcher as qy,buildConnector as zy,getGlobalDispatcher as Jy,setGlobalDispatcher as Vy}from"undici";function Vn(s,e,t){Et.set(ur(s,e),ju(t))}function ci(s,e){Et.delete(ur(s,e))}function Gy(s,e){return Et.get(ur(s,e))}function Ky(s){Et.clear();for(let e of s.list())e.entry.pinnedFingerprint&&Vn(e.host,e.port,e.entry.pinnedFingerprint)}function ui(s){for(let e of s.list())e.pinnedFingerprint&&Vn(e.host,e.port,e.pinnedFingerprint)}async function Qy(s,e,t={}){let n=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=Nu.connect({host:s,port:e,servername:s,rejectUnauthorized:!1,autoSelectFamily:!0}),a=!1,d=(u,l)=>{if(!a){a=!0,clearTimeout(c);try{i.destroy()}catch{}u?o(u):l&&r(l)}},c=setTimeout(()=>{d(new Error(`TLS connect to ${s}:${e} timed out`))},n);i.once("secureConnect",()=>{let u=i.getPeerCertificate(!1);if(!u||!u.raw){d(new Error(`${s}:${e} did not present a TLS certificate`));return}d(null,li(u.raw))}),i.once("error",u=>d(u))})}function li(s){return By("sha256").update(s).digest("hex")}function Du(s){let e=ju(s),t=e.match(/.{2}/g);return t?t.join(":"):e}function ju(s){return s.replace(/:/g,"").toLowerCase()}function fi(){if(di)return;di=!0;let s=Jy(),e=new Wy({connect:zy({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(n,r)=>Lu(n,r)})}),t=new qy;t.dispatch=(n,r)=>{let o=Yy(n.origin);return(o&&Hu(o)?e:s).dispatch(n,r)},t.close=(()=>Promise.all([e.close(),s.close()]).then(()=>{})),t.destroy=(n=>Promise.all([e.destroy(n??null),s.destroy(n??null)]).then(()=>{})),Vy(t)}function Yy(s){if(!s)return null;try{return new URL(String(s)).hostname}catch{return null}}function Hu(s){for(let e of Et.keys())if(Uu(e)?.host===s)return!0;return!1}function Lu(s,e){if(!e||!e.raw)return new Error(`TLS peer ${s} did not present a certificate`);let t=li(e.raw);for(let[n,r]of Et.entries()){let o=Uu(n);if(o&&o.host===s&&r===t)return}return new Error(`TLS pin mismatch for ${s} (cert sha256 ${Du(t)})`)}function Uu(s){let e=s.lastIndexOf(":");if(e<0)return null;let t=s.slice(0,e),n=Number(s.slice(e+1));return Number.isInteger(n)?{host:t,port:n}:null}function pi(s){return Hu(s)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>Lu(e,t)}:{autoSelectFamily:!0}}function Xy(){Et.clear(),di=!1}var Et,di,Gn=Xn(()=>{"use strict";Fu();Et=new Map,di=!1});K();import*as rt from"fs/promises";import{homedir as Tr}from"os";import{z as I}from"zod";K();import*as Mt from"fs/promises";function br(){let s=new Uint8Array(32);crypto.getRandomValues(s);let e="";for(let t of s)e+=t.toString(16).padStart(2,"0");return`hydra_token_${e}`}async function Al(){try{let e=(await Mt.readFile(E.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(s){if(s.code==="ENOENT")return;throw s}}async function Sr(s){await Mt.mkdir(E.home(),{recursive:!0}),await Mt.writeFile(E.authToken(),s+`
5
5
  `,{encoding:"utf8",mode:384})}async function xi(){let s=await Al();if(s)return s;let e=br();return await Sr(e),process.stderr.write(`hydra-acp: initialized ${E.authToken()} with a fresh service token.
6
- `),e}He();import*as Pi from"fs/promises";import*as ln from"os";import*as je from"path";var ne="read by the daemon, which loads config.json at startup",Ti={daemon:{reload:"restart",overlay:"partial",overlayNote:"only changes which daemon this client dials; a daemon started from here still binds config.json's host/port. Use `home` for a separate daemon",nested:!0},agents:{reload:"live",overlay:"inert",overlayNote:ne},agentOverrides:{reload:"live",overlay:"inert",overlayNote:ne},registry:{reload:"live",overlay:"inert",overlayNote:ne},npmRegistry:{reload:"live",overlay:"inert",overlayNote:ne},defaultAgent:{reload:"live",overlay:"effective"},defaultCwd:{reload:"live",overlay:"effective"},sessionDefaults:{reload:"live",overlay:"partial",overlayNote:"applies to WS session/new and child_session/spawn; POST /v1/sessions has no model/mode/effort field to apply any of it to"},synopsisAgent:{reload:"warn",overlay:"inert",overlayNote:ne},synopsisModel:{reload:"warn",overlay:"inert",overlayNote:ne},compaction:{reload:"warn",overlay:"inert",overlayNote:ne},defaultTransformers:{reload:"warn",overlay:"inert",overlayNote:ne},disableWorkspaceSnapshots:{reload:"warn",overlay:"inert",overlayNote:ne},compressToolContent:{reload:"warn",overlay:"inert",overlayNote:ne},extensions:{reload:"warn",overlay:"inert",overlayNote:ne},transformers:{reload:"warn",overlay:"inert",overlayNote:ne},tui:{reload:"client",overlay:"effective"},sessionListColdLimit:{reload:"client",overlay:"effective"}},_l={host:{reload:"restart",overlay:"inert"},port:{reload:"restart",overlay:"inert"},publicHost:{reload:"restart",overlay:"inert"},tls:{reload:"restart",overlay:"inert"},scrubEnv:{reload:"live",overlay:"inert",overlayNote:ne},logLevel:{reload:"warn",overlay:"inert",overlayNote:ne},sessionIdleTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},nonInteractiveOrphanTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryMaxEntries:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveMaxBytes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveTiers:{reload:"warn",overlay:"inert",overlayNote:ne},agentStderrTailBytes:{reload:"warn",overlay:"inert",overlayNote:ne},agentSyncIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcMaxAgeDays:{reload:"warn",overlay:"inert",overlayNote:ne}};function Ir(s){return Ti[s]??{reload:"restart",overlay:"inert"}}function Ar(s){return _l[s]??{reload:"restart",overlay:"inert"}}function Cr(){let s=[];for(let[e,t]of Object.entries(Ti))t.overlay!=="effective"&&s.push({key:e,effect:t.overlay,note:t.overlayNote??ne});return s}var $l=".hydra-acp.json",Rr="home",Ol=64,lk=Cr().map(s=>s.key);function Fl(s){return s==="~"?ln.homedir():s.startsWith("~/")?je.join(ln.homedir(),s.slice(2)):s.startsWith("$HOME/")?je.join(ln.homedir(),s.slice(6)):s}function xr(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function Er(s,e){let t={...s};for(let[n,r]of Object.entries(e)){let o=t[n];t[n]=xr(o)&&xr(r)?Er(o,r):r}return t}async function Nl(s,e=ln.homedir()){let t=[],n=[],r=je.resolve(e),o=je.resolve(s);for(let i=0;i<Ol;i+=1){let a=je.join(o,$l),d;try{d=await Pi.readFile(a,"utf8")}catch{d=void 0}if(d!==void 0)try{let u=JSON.parse(d);xr(u)?t.push({file:a,data:u}):n.push({file:a,key:"",message:"expected a JSON object; ignoring this file"})}catch(u){n.push({file:a,key:"",message:`is not valid JSON (${u.message}); ignoring this file`})}if(o===r)break;let c=je.dirname(o);if(c===o)break;o=c}return t.reverse(),{layers:t,notices:n}}function Dl(s){let e=new Map(Cr().map(n=>[n.key,n])),t=[];for(let n of s)for(let r of Object.keys(n.data)){let o=e.get(r);if(!o)continue;let i=o.effect==="partial"?`\`${r}\` ${o.note}`:`\`${r}\` is ${o.note}, so it has no effect in a directory config`;t.push({file:n.file,key:r,message:i})}return t}async function Hl(s=process.cwd()){let{layers:e,notices:t}=await Nl(s);t.push(...Dl(e));let n={};for(let i of e)n=Er(n,i.data);let r,o=n[Rr];return typeof o=="string"&&o.length>0?r=je.resolve(Fl(o)):o!==void 0&&t.push({file:e[e.length-1].file,key:Rr,message:"`home` must be a non-empty string; ignoring it"}),delete n[Rr],{layers:e,notices:t,merged:n,...r!==void 0?{homeRequest:r}:{}}}function jl(s,e){let t=s[e];return typeof t=="string"&&t.length>0?t:void 0}function Ll(s,e){let t=s[e];if(t===null||typeof t!="object"||Array.isArray(t))return;let n={};for(let[r,o]of Object.entries(t)){if(o===null||typeof o!="object"||Array.isArray(o))continue;let i={};for(let[a,d]of Object.entries(o))typeof d=="string"&&(i[a]=d);Object.keys(i).length>0&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}async function fn(s){let e={};try{e=(await Hl(s)).merged}catch{return{}}let t=jl(e,"defaultAgent"),n=Ll(e,"sessionDefaults");return{...t!==void 0?{agentId:t}:{},...n!==void 0?{configDefaults:n}:{}}}var $i="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",Ul=I.object({cert:I.string(),key:I.string()}),_t=55514,Bl=I.object({host:I.string().default("127.0.0.1"),port:I.number().int().positive().default(_t),logLevel:I.enum(["debug","info","warn","error"]).default("info"),tls:Ul.optional(),sessionIdleTimeoutSeconds:I.number().int().nonnegative().default(3600),nonInteractiveOrphanTimeoutSeconds:I.number().int().nonnegative().default(180),sessionHistoryMaxEntries:I.number().int().positive().default(1e4),sessionHistoryArchiveMaxBytes:I.number().int().nonnegative().default(1e7),sessionHistoryArchiveTiers:I.number().int().positive().default(10),agentStderrTailBytes:I.number().int().positive().default(4096),publicHost:I.string().optional(),agentSyncIntervalMinutes:I.number().nonnegative().default(60),scrubEnv:I.array(I.string()).default([]),sessionGcIntervalMinutes:I.number().nonnegative().default(60),sessionGcMaxAgeDays:I.number().positive().default(2)}),Wl=I.object({url:I.string().url().default($i),ttlHours:I.number().positive().default(24),pinned:I.boolean().default(!1)}),ql=I.object({extends:I.string().optional(),name:I.string().optional(),description:I.string().optional(),command:I.string().optional(),args:I.array(I.string()).optional(),env:I.record(I.string()).optional()}),zl=I.object({packageSpec:I.string().optional(),extraArgs:I.array(I.string()).optional(),env:I.record(I.string()).optional()}),Jl=I.enum(["enter","alt-enter","shift-enter","ctrl-enter","alt-b","alt-f","alt-n","alt-tab","shift-tab","tab","up","down","left","right","home","end","backspace","alt-backspace","delete","ctrl-a","ctrl-b","ctrl-c","ctrl-d","ctrl-e","ctrl-f","ctrl-g","ctrl-k","ctrl-l","ctrl-n","ctrl-o","ctrl-p","ctrl-q","ctrl-r","ctrl-s","ctrl-u","ctrl-v","ctrl-t","ctrl-w","ctrl-x","ctrl-x-ctrl-e","ctrl-y","ctrl-underscore","alt-underscore","escape"]),Vl=I.union([I.string(),I.object({field:I.string().optional(),text:I.string().optional(),script:I.string().optional(),refreshMs:I.number().int().positive().optional(),maxWidth:I.number().int().positive().optional(),minWidth:I.number().int().nonnegative().optional(),truncate:I.boolean().optional(),priority:I.number().optional(),prefix:I.string().optional(),suffix:I.string().optional(),separator:I.string().optional(),style:I.string().optional(),onClick:I.string().optional(),onDoubleClick:I.string().optional()}).strict()]),Gl=I.object({id:I.string().min(1),script:I.string().min(1),refreshMs:I.number().int().positive().optional(),title:I.string().optional(),cap:I.number().int().positive().optional()}).strict(),Kl=I.union([I.string(),Gl]),Mi=I.array(Vl);function Pr(s,e){return I.object({left:Mi.default(s),right:Mi.default(e)}).default({})}var Ql=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],Yl=["usage"],Xl=[],Zl=["helpHint"],ef=["cwd","title"],tf=["agentModel"],nf=I.object({composer:I.object({top:Pr(Ql,Yl),bottom:Pr(Xl,Zl),hintTurns:I.number().int().nonnegative().nullable().default(3)}).default({}),sessionbar:Pr(ef,tf),scriptRefreshMs:I.number().int().positive().default(5e3),readIdleSeconds:I.number().int().nonnegative().default(180),repaintThrottleMs:I.number().int().nonnegative().default(1e3),maxScrollbackLines:I.number().int().positive().default(1e4),mouse:I.boolean().default(!0),inAppSelection:I.boolean().optional(),selectionClipboard:I.enum(["primary","clipboard","both"]).default("both"),openFileCommand:I.union([I.string(),I.array(I.string())]).optional(),openFileInTerminal:I.boolean().optional(),logMaxBytes:I.number().int().positive().default(5*1024*1024),keyTrace:I.boolean().optional(),cwdColumnMaxWidth:I.number().int().positive().default(32),progressIndicator:I.boolean().default(!0),terminalHost:I.union([I.boolean(),I.enum(["auto","paseo","herdr","tmux"])]).default(!0),launcherModeWhenHosted:I.boolean().default(!1),skipPermissions:I.boolean().default(!1),defaultEnterAction:I.enum(["enqueue","amend"]).default("amend"),showThoughts:I.boolean().default(!0),ambiguousWidth:I.enum(["auto","narrow","wide"]).default("auto"),toolContent:I.enum(["inline","references"]).default("references"),diffContextLines:I.number().int().min(0).default(3),promptHistoryMaxEntries:I.number().int().positive().default(2e3),maxToolItems:I.number().int().nonnegative().default(5),maxPlanItems:I.number().int().nonnegative().default(5),sidebar:I.object({enabled:I.boolean().default(!0),width:I.number().int().positive().optional(),border:I.enum(["none","rule","frame"]).default("frame"),gadgets:I.array(Kl).default(["activity","sessions","tasks","context","queue","todo","files","git","resources","info","tools"])}).default({}),showFileUpdates:I.enum(["none","edit","diff"]).default("edit"),sessionColumns:I.array(I.enum(["session","upstream","host","state","agent","model","age","cwd","title","cost"])).nonempty().optional(),defaultHost:I.string().min(1).default("remote:all"),hotkeys:I.record(Jl,I.object({command:I.union([I.string(),I.array(I.string())])})).default({}),theme:I.union([I.string(),I.record(I.string(),I.unknown())]).optional(),themeBackground:I.string().optional()}),_i=I.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),sf=I.object({command:I.array(I.string()).default([]),args:I.array(I.string()).default([]),env:I.record(I.string()).default({}),enabled:I.boolean().default(!0)}),rf=I.object({command:I.array(I.string()).default([]),args:I.array(I.string()).default([]),env:I.record(I.string()).default({}),enabled:I.boolean().default(!0)}),of=I.object({daemon:Bl.default({}),registry:Wl.default({url:$i,ttlHours:24,pinned:!1}),agents:I.record(I.string(),ql).default({}),agentOverrides:I.record(I.string(),zl).default({}),defaultAgent:I.string().default("opencode"),sessionDefaults:I.record(I.string(),I.record(I.string(),I.string())).default({}),synopsisAgent:I.string().optional(),synopsisModel:I.string().optional(),compaction:I.object({agent:I.string().optional(),model:I.string().optional(),tailK:I.number().int().nonnegative().default(20),maxIterations:I.number().int().positive().default(3),contextFraction:I.number().min(0).max(1).default(.5),hardCeilingFraction:I.number().min(0).max(1).default(.85),absoluteFallback:I.number().int().positive().default(2e5),idleBeforePromptMs:I.number().int().nonnegative().default(3e5),modelContextWindows:I.record(I.string(),I.number().int().positive()).default({})}).default({}),defaultCwd:I.string().default("~"),disableWorkspaceSnapshots:I.boolean().optional(),compressToolContent:I.boolean().default(!0),sessionListColdLimit:I.number().int().nonnegative().default(20),extensions:I.record(_i,sf).default({}),transformers:I.record(_i,rf).default({}),defaultTransformers:I.array(I.string()).default([]),npmRegistry:I.string().url().optional(),tui:nf.default({})});function Oi(s){return Object.entries(s.extensions).map(([e,t])=>({name:e,...t}))}function Fi(s){return Object.entries(s.transformers).map(([e,t])=>({name:e,...t}))}async function Mr(){return await af(),await de(E.config())??{}}async function af(){let s;try{s=await rt.lstat(E.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(s.isSymbolicLink())try{await rt.stat(E.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await rt.readlink(E.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${E.config()} is a broken symlink (-> ${t}); its target is missing. Refusing to treat this as "no config" and overwrite it. Restore the target (e.g. decrypt/check out your dotfiles) or remove the dangling link.`)}}async function df(){let s=await Mr(),e=s.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let n=!1;try{await rt.access(E.authToken()),n=!0}catch(r){if(r.code!=="ENOENT")throw r}if(n)throw new Error(`Auth token present in both ${E.authToken()} and ${E.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await Sr(t),delete e.authToken,Object.keys(e).length===0&&delete s.daemon,await he(E.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${E.config()} to ${E.authToken()}.
6
+ `),e}je();import*as Pi from"fs/promises";import*as ln from"os";import*as He from"path";var ne="read by the daemon, which loads config.json at startup",Ti={daemon:{reload:"restart",overlay:"partial",overlayNote:"only changes which daemon this client dials; a daemon started from here still binds config.json's host/port. Use `home` for a separate daemon",nested:!0},agents:{reload:"live",overlay:"inert",overlayNote:ne},agentOverrides:{reload:"live",overlay:"inert",overlayNote:ne},registry:{reload:"live",overlay:"inert",overlayNote:ne},npmRegistry:{reload:"live",overlay:"inert",overlayNote:ne},defaultAgent:{reload:"live",overlay:"effective"},defaultCwd:{reload:"live",overlay:"effective"},sessionDefaults:{reload:"live",overlay:"partial",overlayNote:"applies to WS session/new and child_session/spawn; POST /v1/sessions has no model/mode/effort field to apply any of it to"},synopsisAgent:{reload:"warn",overlay:"inert",overlayNote:ne},synopsisModel:{reload:"warn",overlay:"inert",overlayNote:ne},compaction:{reload:"warn",overlay:"inert",overlayNote:ne},defaultTransformers:{reload:"warn",overlay:"inert",overlayNote:ne},disableWorkspaceSnapshots:{reload:"warn",overlay:"inert",overlayNote:ne},compressToolContent:{reload:"warn",overlay:"inert",overlayNote:ne},extensions:{reload:"warn",overlay:"inert",overlayNote:ne},transformers:{reload:"warn",overlay:"inert",overlayNote:ne},tui:{reload:"client",overlay:"effective"},sessionListColdLimit:{reload:"client",overlay:"effective"}},_l={host:{reload:"restart",overlay:"inert"},port:{reload:"restart",overlay:"inert"},publicHost:{reload:"restart",overlay:"inert"},tls:{reload:"restart",overlay:"inert"},scrubEnv:{reload:"live",overlay:"inert",overlayNote:ne},logLevel:{reload:"warn",overlay:"inert",overlayNote:ne},sessionIdleTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},nonInteractiveOrphanTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryMaxEntries:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveMaxBytes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveTiers:{reload:"warn",overlay:"inert",overlayNote:ne},agentStderrTailBytes:{reload:"warn",overlay:"inert",overlayNote:ne},agentSyncIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcMaxAgeDays:{reload:"warn",overlay:"inert",overlayNote:ne}};function Ir(s){return Ti[s]??{reload:"restart",overlay:"inert"}}function Ar(s){return _l[s]??{reload:"restart",overlay:"inert"}}function Cr(){let s=[];for(let[e,t]of Object.entries(Ti))t.overlay!=="effective"&&s.push({key:e,effect:t.overlay,note:t.overlayNote??ne});return s}var $l=".hydra-acp.json",Rr="home",Ol=64,fk=Cr().map(s=>s.key);function Fl(s){return s==="~"?ln.homedir():s.startsWith("~/")?He.join(ln.homedir(),s.slice(2)):s.startsWith("$HOME/")?He.join(ln.homedir(),s.slice(6)):s}function xr(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function Er(s,e){let t={...s};for(let[n,r]of Object.entries(e)){let o=t[n];t[n]=xr(o)&&xr(r)?Er(o,r):r}return t}async function Nl(s,e=ln.homedir()){let t=[],n=[],r=He.resolve(e),o=He.resolve(s);for(let i=0;i<Ol;i+=1){let a=He.join(o,$l),d;try{d=await Pi.readFile(a,"utf8")}catch{d=void 0}if(d!==void 0)try{let u=JSON.parse(d);xr(u)?t.push({file:a,data:u}):n.push({file:a,key:"",message:"expected a JSON object; ignoring this file"})}catch(u){n.push({file:a,key:"",message:`is not valid JSON (${u.message}); ignoring this file`})}if(o===r)break;let c=He.dirname(o);if(c===o)break;o=c}return t.reverse(),{layers:t,notices:n}}function Dl(s){let e=new Map(Cr().map(n=>[n.key,n])),t=[];for(let n of s)for(let r of Object.keys(n.data)){let o=e.get(r);if(!o)continue;let i=o.effect==="partial"?`\`${r}\` ${o.note}`:`\`${r}\` is ${o.note}, so it has no effect in a directory config`;t.push({file:n.file,key:r,message:i})}return t}async function jl(s=process.cwd()){let{layers:e,notices:t}=await Nl(s);t.push(...Dl(e));let n={};for(let i of e)n=Er(n,i.data);let r,o=n[Rr];return typeof o=="string"&&o.length>0?r=He.resolve(Fl(o)):o!==void 0&&t.push({file:e[e.length-1].file,key:Rr,message:"`home` must be a non-empty string; ignoring it"}),delete n[Rr],{layers:e,notices:t,merged:n,...r!==void 0?{homeRequest:r}:{}}}function Hl(s,e){let t=s[e];return typeof t=="string"&&t.length>0?t:void 0}function Ll(s,e){let t=s[e];if(t===null||typeof t!="object"||Array.isArray(t))return;let n={};for(let[r,o]of Object.entries(t)){if(o===null||typeof o!="object"||Array.isArray(o))continue;let i={};for(let[a,d]of Object.entries(o))typeof d=="string"&&(i[a]=d);Object.keys(i).length>0&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}async function fn(s){let e={};try{e=(await jl(s)).merged}catch{return{}}let t=Hl(e,"defaultAgent"),n=Ll(e,"sessionDefaults");return{...t!==void 0?{agentId:t}:{},...n!==void 0?{configDefaults:n}:{}}}var $i="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",Ul=I.object({cert:I.string(),key:I.string()}),_t=55514,Bl=I.object({host:I.string().default("127.0.0.1"),port:I.number().int().positive().default(_t),logLevel:I.enum(["debug","info","warn","error"]).default("info"),tls:Ul.optional(),sessionIdleTimeoutSeconds:I.number().int().nonnegative().default(3600),nonInteractiveOrphanTimeoutSeconds:I.number().int().nonnegative().default(180),sessionHistoryMaxEntries:I.number().int().positive().default(1e4),sessionHistoryArchiveMaxBytes:I.number().int().nonnegative().default(1e7),sessionHistoryArchiveTiers:I.number().int().positive().default(10),agentStderrTailBytes:I.number().int().positive().default(4096),publicHost:I.string().optional(),agentSyncIntervalMinutes:I.number().nonnegative().default(60),scrubEnv:I.array(I.string()).default([]),sessionGcIntervalMinutes:I.number().nonnegative().default(60),sessionGcMaxAgeDays:I.number().positive().default(2)}),Wl=I.object({url:I.string().url().default($i),ttlHours:I.number().positive().default(24),pinned:I.boolean().default(!1)}),ql=I.object({extends:I.string().optional(),name:I.string().optional(),description:I.string().optional(),command:I.string().optional(),args:I.array(I.string()).optional(),env:I.record(I.string()).optional()}),zl=I.object({packageSpec:I.string().optional(),extraArgs:I.array(I.string()).optional(),env:I.record(I.string()).optional()}),Jl=I.enum(["enter","alt-enter","shift-enter","ctrl-enter","alt-b","alt-f","alt-n","alt-tab","shift-tab","tab","up","down","left","right","home","end","backspace","alt-backspace","delete","ctrl-a","ctrl-b","ctrl-c","ctrl-d","ctrl-e","ctrl-f","ctrl-g","ctrl-k","ctrl-l","ctrl-n","ctrl-o","ctrl-p","ctrl-q","ctrl-r","ctrl-s","ctrl-u","ctrl-v","ctrl-t","ctrl-w","ctrl-x","ctrl-x-ctrl-e","ctrl-y","ctrl-underscore","alt-underscore","escape"]),Vl=I.union([I.string(),I.object({field:I.string().optional(),text:I.string().optional(),script:I.string().optional(),refreshMs:I.number().int().positive().optional(),maxWidth:I.number().int().positive().optional(),minWidth:I.number().int().nonnegative().optional(),truncate:I.boolean().optional(),priority:I.number().optional(),prefix:I.string().optional(),suffix:I.string().optional(),separator:I.string().optional(),style:I.string().optional(),onClick:I.string().optional(),onDoubleClick:I.string().optional()}).strict()]),Gl=I.object({id:I.string().min(1),script:I.string().min(1),refreshMs:I.number().int().positive().optional(),title:I.string().optional(),cap:I.number().int().positive().optional()}).strict(),Kl=I.union([I.string(),Gl]),Mi=I.array(Vl);function Pr(s,e){return I.object({left:Mi.default(s),right:Mi.default(e)}).default({})}var Ql=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],Yl=["usage"],Xl=[],Zl=["helpHint"],ef=["cwd","title"],tf=["agentModel"],nf=I.object({composer:I.object({top:Pr(Ql,Yl),bottom:Pr(Xl,Zl),hintTurns:I.number().int().nonnegative().nullable().default(3)}).default({}),sessionbar:Pr(ef,tf),scriptRefreshMs:I.number().int().positive().default(5e3),readIdleSeconds:I.number().int().nonnegative().default(180),repaintThrottleMs:I.number().int().nonnegative().default(1e3),maxScrollbackLines:I.number().int().positive().default(1e4),mouse:I.boolean().default(!0),inAppSelection:I.boolean().optional(),selectionClipboard:I.enum(["primary","clipboard","both"]).default("both"),openFileCommand:I.union([I.string(),I.array(I.string())]).optional(),openFileInTerminal:I.boolean().optional(),logMaxBytes:I.number().int().positive().default(5*1024*1024),keyTrace:I.boolean().optional(),cwdColumnMaxWidth:I.number().int().positive().default(32),progressIndicator:I.boolean().default(!0),terminalHost:I.union([I.boolean(),I.enum(["auto","paseo","herdr","tmux"])]).default(!0),launcherModeWhenHosted:I.boolean().default(!1),skipPermissions:I.boolean().default(!1),defaultEnterAction:I.enum(["enqueue","amend"]).default("amend"),showThoughts:I.boolean().default(!0),ambiguousWidth:I.enum(["auto","narrow","wide"]).default("auto"),toolContent:I.enum(["inline","references"]).default("references"),diffContextLines:I.number().int().min(0).default(3),promptHistoryMaxEntries:I.number().int().positive().default(2e3),maxToolItems:I.number().int().nonnegative().default(5),maxPlanItems:I.number().int().nonnegative().default(5),sidebar:I.object({enabled:I.boolean().default(!0),width:I.number().int().positive().optional(),border:I.enum(["none","rule","frame"]).default("frame"),gadgets:I.array(Kl).default(["activity","sessions","tasks","context","queue","todo","files","git","resources","info","tools"])}).default({}),showFileUpdates:I.enum(["none","edit","diff"]).default("edit"),sessionColumns:I.array(I.enum(["session","upstream","host","state","agent","model","age","cwd","title","cost"])).nonempty().optional(),defaultHost:I.string().min(1).default("remote:all"),hotkeys:I.record(Jl,I.object({command:I.union([I.string(),I.array(I.string())])})).default({}),theme:I.union([I.string(),I.record(I.string(),I.unknown())]).optional(),themeBackground:I.string().optional()}),_i=I.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),sf=I.object({command:I.array(I.string()).default([]),args:I.array(I.string()).default([]),env:I.record(I.string()).default({}),enabled:I.boolean().default(!0)}),rf=I.object({command:I.array(I.string()).default([]),args:I.array(I.string()).default([]),env:I.record(I.string()).default({}),enabled:I.boolean().default(!0)}),of=I.object({daemon:Bl.default({}),registry:Wl.default({url:$i,ttlHours:24,pinned:!1}),agents:I.record(I.string(),ql).default({}),agentOverrides:I.record(I.string(),zl).default({}),defaultAgent:I.string().default("opencode"),sessionDefaults:I.record(I.string(),I.record(I.string(),I.string())).default({}),synopsisAgent:I.string().optional(),synopsisModel:I.string().optional(),compaction:I.object({agent:I.string().optional(),model:I.string().optional(),tailK:I.number().int().nonnegative().default(20),maxIterations:I.number().int().positive().default(3),contextFraction:I.number().min(0).max(1).default(.5),hardCeilingFraction:I.number().min(0).max(1).default(.85),absoluteFallback:I.number().int().positive().default(2e5),idleBeforePromptMs:I.number().int().nonnegative().default(3e5),modelContextWindows:I.record(I.string(),I.number().int().positive()).default({})}).default({}),defaultCwd:I.string().default("~"),disableWorkspaceSnapshots:I.boolean().optional(),compressToolContent:I.boolean().default(!0),sessionListColdLimit:I.number().int().nonnegative().default(20),extensions:I.record(_i,sf).default({}),transformers:I.record(_i,rf).default({}),defaultTransformers:I.array(I.string()).default([]),npmRegistry:I.string().url().optional(),tui:nf.default({})});function Oi(s){return Object.entries(s.extensions).map(([e,t])=>({name:e,...t}))}function Fi(s){return Object.entries(s.transformers).map(([e,t])=>({name:e,...t}))}async function Mr(){return await af(),await de(E.config())??{}}async function af(){let s;try{s=await rt.lstat(E.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(s.isSymbolicLink())try{await rt.stat(E.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await rt.readlink(E.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${E.config()} is a broken symlink (-> ${t}); its target is missing. Refusing to treat this as "no config" and overwrite it. Restore the target (e.g. decrypt/check out your dotfiles) or remove the dangling link.`)}}async function df(){let s=await Mr(),e=s.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let n=!1;try{await rt.access(E.authToken()),n=!0}catch(r){if(r.code!=="ENOENT")throw r}if(n)throw new Error(`Auth token present in both ${E.authToken()} and ${E.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await Sr(t),delete e.authToken,Object.keys(e).length===0&&delete s.daemon,await he(E.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${E.config()} to ${E.authToken()}.
7
7
  `)}async function cf(){let s=await Mr(),e=s.defaultModels&&typeof s.defaultModels=="object"&&!Array.isArray(s.defaultModels)?s.defaultModels:void 0;if(!e)return;let t=s.sessionDefaults&&typeof s.sessionDefaults=="object"&&!Array.isArray(s.sessionDefaults)?s.sessionDefaults:{};for(let[n,r]of Object.entries(e)){if(typeof r!="string")continue;let o=t[n]&&typeof t[n]=="object"&&!Array.isArray(t[n])?t[n]:{};o.model===void 0&&(o.model=r),t[n]=o}s.sessionDefaults=t,delete s.defaultModels,await he(E.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated defaultModels to sessionDefaults in ${E.config()}.
8
8
  `)}async function pn(){return await df(),await cf(),of.parse(await Mr())}function ce(s){return s==="~"||s==="$HOME"?Tr():s.startsWith("~/")?Tr()+s.slice(1):s.startsWith("$HOME/")?Tr()+s.slice(5):s}K();import*as Ze from"fs/promises";import*as Ni from"path";var uf=64*1024;async function Di(s){let e=E.daemonBootLog(),t=`[${new Date().toISOString()}] pid=${process.pid} ${s}
9
- `;if(await Ze.mkdir(Ni.dirname(e),{recursive:!0}),await Ze.stat(e).then(r=>r.size).catch(()=>0)>uf){await Ze.writeFile(e,t,{encoding:"utf8",mode:384});return}await Ze.appendFile(e,t,{encoding:"utf8",mode:384})}import*as pl from"fs";import*as Xe from"fs/promises";import*as gl from"net";import*as dn from"path";import*as hl from"tls";import Gw from"fastify";import Kw from"@fastify/websocket";var Hi="acp.v1";function ji(s,e){return s.has(Hi)?Hi:!1}import ll from"pino";import Qw from"pino-roll";var lf={herdr:["HERDR_PANE_ID","HERDR_TAB_ID","HERDR_WORKSPACE_ID","HERDR_STARTUP_CWD"],tmux:["TMUX_PANE"],zellij:["ZELLIJ_PANE_ID","ZELLIJ_SESSION_NAME"],wezterm:["WEZTERM_PANE"],kitty:["KITTY_WINDOW_ID"],screen:["STY"],iterm2:["ITERM_SESSION_ID"],paseo:["PASEO_TERMINAL_ID","PASEO_ACTIVITY_TOKEN"],hydra:["HYDRA_TAB_LABEL"]},Li="HYDRA_ACP_SESSION",ff=[Li],pf=[...Object.values(lf).flat(),...ff];function Zn(s,e){return s?{...e??{},[Li]:s}:e}var Ui=[];function _r(s){Ui=s?[...s]:[]}function gf(s,e){return e.endsWith("*")?s.startsWith(e.slice(0,-1)):s===e}function hf(){return[...pf,...Ui]}function es(s=process.env){let e=hf(),t={};for(let[n,r]of Object.entries(s))r!==void 0&&(e.some(o=>gf(n,o))||(t[n]=r));return t}K();import*as me from"fs/promises";import{createHash as mf}from"crypto";import{gzip as yf,gunzip as wf}from"zlib";import{promisify as Bi}from"util";var Wi=Bi(yf),kf=Bi(wf),qi=/^[A-Za-z0-9_-]+$/,vf=/^[a-f0-9]{64}$/,$r=!0;function zi(s){$r=s}function ts(s,e){return qi.test(s)?e===void 0||vf.test(e):!1}function ns(s,e){return`${E.toolBlobFile(s,e)}.gz`}async function Or(s,e){if(!ts(s))return null;let t=mf("sha256").update(e,"utf8").digest("hex"),n=ns(s,t),r=E.toolBlobFile(s,t);for(let a of[n,r])try{return await me.access(a),t}catch{}await me.mkdir(E.toolsDir(s),{recursive:!0});let o=$r?n:r,i=$r?await Wi(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await me.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function gn(s,e){if(!ts(s,e))return null;try{let t=await me.readFile(ns(s,e));return(await kf(t)).toString("utf8")}catch{}try{return await me.readFile(E.toolBlobFile(s,e),"utf8")}catch{return null}}async function Ji(s,e){if(!ts(s,e))return null;try{return await me.readFile(ns(s,e))}catch{}try{let t=await me.readFile(E.toolBlobFile(s,e));return await Wi(t)}catch{return null}}async function Vi(s,e,t){if(!ts(s,e))return;let n=ns(s,e);try{await me.access(n);return}catch{}await me.mkdir(E.toolsDir(s),{recursive:!0}),await me.writeFile(n,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function Gi(s){qi.test(s)&&await me.rm(E.toolsDir(s),{recursive:!0,force:!0}).catch(()=>{})}K();import*as da from"fs/promises";import*as rs from"path";import{z as L}from"zod";He();K();import*as Qi from"fs";import*as ke from"fs/promises";import*as ot from"path";import{spawn as Yi}from"child_process";import{Readable as bf}from"stream";function Le(){let s=process.platform==="darwin"?"darwin":process.platform==="linux"?"linux":process.platform==="win32"?"windows":void 0,e=process.arch==="arm64"?"aarch64":process.arch==="x64"?"x86_64":void 0;if(!(!s||!e))return`${s}-${e}`}function Dr(s,e=Le()){if(e)return s[e]}var $t=s=>{process.stderr.write(s+`
10
- `)};function Hr(s){$t=s??(e=>process.stderr.write(e+`
9
+ `;if(await Ze.mkdir(Ni.dirname(e),{recursive:!0}),await Ze.stat(e).then(r=>r.size).catch(()=>0)>uf){await Ze.writeFile(e,t,{encoding:"utf8",mode:384});return}await Ze.appendFile(e,t,{encoding:"utf8",mode:384})}import*as pl from"fs";import*as Xe from"fs/promises";import*as gl from"net";import*as dn from"path";import*as hl from"tls";import Kw from"fastify";import Qw from"@fastify/websocket";var ji="acp.v1";function Hi(s,e){return s.has(ji)?ji:!1}import ll from"pino";import Yw from"pino-roll";var lf={herdr:["HERDR_PANE_ID","HERDR_TAB_ID","HERDR_WORKSPACE_ID","HERDR_STARTUP_CWD"],tmux:["TMUX_PANE"],zellij:["ZELLIJ_PANE_ID","ZELLIJ_SESSION_NAME"],wezterm:["WEZTERM_PANE"],kitty:["KITTY_WINDOW_ID"],screen:["STY"],iterm2:["ITERM_SESSION_ID"],paseo:["PASEO_TERMINAL_ID","PASEO_ACTIVITY_TOKEN"],hydra:["HYDRA_TAB_LABEL"]},Li="HYDRA_ACP_SESSION",ff=[Li],pf=[...Object.values(lf).flat(),...ff];function Zn(s,e){return s?{...e??{},[Li]:s}:e}var Ui=[];function _r(s){Ui=s?[...s]:[]}function gf(s,e){return e.endsWith("*")?s.startsWith(e.slice(0,-1)):s===e}function hf(){return[...pf,...Ui]}function es(s=process.env){let e=hf(),t={};for(let[n,r]of Object.entries(s))r!==void 0&&(e.some(o=>gf(n,o))||(t[n]=r));return t}K();import*as me from"fs/promises";import{createHash as mf}from"crypto";import{gzip as yf,gunzip as wf}from"zlib";import{promisify as Bi}from"util";var Wi=Bi(yf),kf=Bi(wf),qi=/^[A-Za-z0-9_-]+$/,vf=/^[a-f0-9]{64}$/,$r=!0;function zi(s){$r=s}function ts(s,e){return qi.test(s)?e===void 0||vf.test(e):!1}function ns(s,e){return`${E.toolBlobFile(s,e)}.gz`}async function Or(s,e){if(!ts(s))return null;let t=mf("sha256").update(e,"utf8").digest("hex"),n=ns(s,t),r=E.toolBlobFile(s,t);for(let a of[n,r])try{return await me.access(a),t}catch{}await me.mkdir(E.toolsDir(s),{recursive:!0});let o=$r?n:r,i=$r?await Wi(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await me.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function gn(s,e){if(!ts(s,e))return null;try{let t=await me.readFile(ns(s,e));return(await kf(t)).toString("utf8")}catch{}try{return await me.readFile(E.toolBlobFile(s,e),"utf8")}catch{return null}}async function Ji(s,e){if(!ts(s,e))return null;try{return await me.readFile(ns(s,e))}catch{}try{let t=await me.readFile(E.toolBlobFile(s,e));return await Wi(t)}catch{return null}}async function Vi(s,e,t){if(!ts(s,e))return;let n=ns(s,e);try{await me.access(n);return}catch{}await me.mkdir(E.toolsDir(s),{recursive:!0}),await me.writeFile(n,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function Gi(s){qi.test(s)&&await me.rm(E.toolsDir(s),{recursive:!0,force:!0}).catch(()=>{})}K();import*as da from"fs/promises";import*as rs from"path";import{z as L}from"zod";je();K();import*as Qi from"fs";import*as ke from"fs/promises";import*as ot from"path";import{spawn as Yi}from"child_process";import{Readable as bf}from"stream";function Le(){let s=process.platform==="darwin"?"darwin":process.platform==="linux"?"linux":process.platform==="win32"?"windows":void 0,e=process.arch==="arm64"?"aarch64":process.arch==="x64"?"x86_64":void 0;if(!(!s||!e))return`${s}-${e}`}function Dr(s,e=Le()){if(e)return s[e]}var $t=s=>{process.stderr.write(s+`
10
+ `)};function jr(s){$t=s??(e=>process.stderr.write(e+`
11
11
  `))}async function Xi(s){if(!s.target.archive)throw new Error(`Agent ${s.agentId} has no archive URL for ${Le()??"this platform"}`);if(!s.target.cmd)throw new Error(`Agent ${s.agentId} has no cmd in its binary target`);let e=Le();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=E.agentInstallDir(s.agentId,e,s.version),n=ot.resolve(t,s.target.cmd);if(await Nr(n))return n;if(await Sf({agentId:s.agentId,version:s.version,archiveUrl:s.target.archive,installDir:t,onProgress:s.onProgress}),!await Nr(n))throw new Error(`Agent ${s.agentId}: extracted archive did not contain ${s.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await ke.chmod(n,493).catch(()=>{}),n}async function Sf(s){await ke.mkdir(ot.dirname(s.installDir),{recursive:!0});let e=await ke.mkdtemp(`${s.installDir}.partial-`);try{$t(`hydra-acp: downloading ${s.agentId} from ${s.archiveUrl}`);let t=await If({url:s.archiveUrl,dir:e,agentId:s.agentId,version:s.version,onProgress:s.onProgress});$t(`hydra-acp: extracting ${s.agentId}`),Ot(s.onProgress,{phase:"extract",agentId:s.agentId,version:s.version}),await Cf(t,e),await ke.unlink(t).catch(()=>{});try{await ke.rename(e,s.installDir)}catch(n){let r=n;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await Nr(s.installDir)){await ke.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Ot(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw n}$t(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),Ot(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await ke.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Ot(s,e){if(s)try{s(e)}catch{}}async function If(s){let e=Af(s.url),t=ot.join(s.dir,e),n=await fetch(s.url,{redirect:"follow"});if(!n.ok||!n.body)throw new Error(`Failed to download ${s.url}: HTTP ${n.status} ${n.statusText}`);let r=Number(n.headers.get("content-length")??"0"),o=Qi.createWriteStream(t),i=bf.fromWeb(n.body);Ot(s.onProgress,{phase:"download_start",agentId:s.agentId,version:s.version,totalBytes:r});let a=0,d=Date.now(),c=0,u=2e3,l=150;return i.on("data",p=>{a+=p.length;let f=Date.now();f-c>=l&&(c=f,Ot(s.onProgress,{phase:"download_progress",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r})),f-d>=u&&(d=f,$t(Ki(s.agentId,a,r)))}),await new Promise((p,f)=>{i.on("error",f),o.on("error",f),o.on("finish",()=>p()),i.pipe(o)}),$t(Ki(s.agentId,a,r,!0)),Ot(s.onProgress,{phase:"download_done",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r}),t}function Ki(s,e,t,n=!1){let r=(e/1e6).toFixed(1);if(t>0){let i=(t/1e6).toFixed(1),a=Math.min(100,Math.floor(e/t*100));return`hydra-acp: ${n?"downloaded":"downloading"} ${s} ${r}/${i} MB (${a}%)`}return`hydra-acp: ${n?"downloaded":"downloading"} ${s} ${r} MB`}function Af(s){let e=new URL(s);return ot.posix.basename(e.pathname)||"archive"}async function Cf(s,e){let t=s.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await Fr("tar",["-xf",s,"-C",e]);return}if(t.endsWith(".zip")){if(await Rf("unzip")){await Fr("unzip",["-q",s,"-d",e]);return}await Fr("tar",["-xf",s,"-C",e]);return}throw new Error(`Unsupported archive format: ${s}`)}function Fr(s,e){return new Promise((t,n)=>{let r=Yi(s,e,{stdio:["ignore","ignore","inherit"]});r.on("error",n),r.on("exit",(o,i)=>{if(o===0){t();return}n(new Error(`${s} ${e.join(" ")} exited with ${o!==null?`code ${o}`:`signal ${i}`}`))})})}async function Rf(s){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",n=Yi(t,[s],{stdio:"ignore"});n.on("error",()=>e(!1)),n.on("exit",r=>e(r===0))})}async function Nr(s){try{return await ke.access(s),!0}catch{return!1}}K();import*as xe from"fs/promises";import*as Ue from"path";import{delimiter as Ff}from"path";import{spawn as Nf}from"child_process";import{statSync as xf}from"fs";import{delimiter as Ef,join as Tf}from"path";var Pf=".COM;.EXE;.BAT;.CMD";function Zi(s){try{return xf(s).isFile()}catch{return!1}}function Mf(s){let e=(s.PATHEXT??Pf).split(";").map(n=>n.trim()).filter(n=>n.length>0),t=[];for(let n of e)for(let r of[n,n.toLowerCase(),n.toUpperCase()])t.includes(r)||t.push(r);return t}function _f(s,e){let t=s.toLowerCase();return e.some(n=>t.endsWith(n.toLowerCase()))}function $f(s,e={}){if((e.platform??process.platform)!=="win32")return s;let n=e.env??process.env,r=Mf(n);if(_f(s,r))return s;if(/[\\/]/.test(s)){for(let i of r){let a=s+i;if(Zi(a))return a}return s}let o=n.PATH??n.Path??"";for(let i of o.split(Ef).filter(a=>a.length>0))for(let a of r){let d=Tf(i,s+a);if(Zi(d))return d}return s}var Of=/["%\r\n]/;function ea(s){if(Of.test(s))throw new Error(`cannot pass ${JSON.stringify(s)} through cmd.exe: it contains a quote, a percent sign, or a newline, none of which can be escaped unambiguously`);return/[\s&|<>^()]/.test(s)?`"${s}"`:s}function Ft(s,e,t={}){let n=t.platform??process.platform,r=$f(s,t);return n!=="win32"||!/\.(cmd|bat)$/i.test(r)?{command:r,args:[...e],shell:!1}:{command:ea(r),args:e.map(ea),shell:!0}}var Lr=s=>{process.stderr.write(s+`
12
12
  `)};function Ur(s){Lr=s??(e=>process.stderr.write(e+`
13
- `))}async function na(s){let e=Le();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=E.agentNpmInstallDir(s.agentId,e,s.version),n=Uf(s.packageSpec),r=Bf(n),o={installDir:t,packageName:n,hint:s.bin,basename:r},i=Ue.join(t,"node_modules",".bin",s.bin);if(await kt(i))return i;if(await kt(t)){let l=await ta(o);if(l)return l.binPath}await Df({agentId:s.agentId,version:s.version,packageSpec:s.packageSpec,installDir:t,registry:s.registry,onProgress:s.onProgress});let a=await ta(o);if(a)return a.binPath;let d=await ra(t,n),c=typeof d=="object"&&d!==null?Object.keys(d):typeof d=="string"?[r]:[],u=c.length>0?` (package declares bins: ${c.join(", ")})`:"";throw new Error(`Agent ${s.agentId}: npm install of ${s.packageSpec} did not produce bin ${s.bin} (looked in ${t}/node_modules/.bin/)${u}`)}async function Df(s){await xe.mkdir(Ue.dirname(s.installDir),{recursive:!0});let e=await xe.mkdtemp(`${s.installDir}.partial-`);try{Lr(`hydra-acp: installing ${s.packageSpec} for ${s.agentId} into ${e}`),jr(s.onProgress,{phase:"install_start",agentId:s.agentId,version:s.version,packageSpec:s.packageSpec}),await Lf({packageSpec:s.packageSpec,cwd:e,registry:s.registry});try{await xe.rename(e,s.installDir)}catch(t){let n=t;if((n.code==="EEXIST"||n.code==="ENOTEMPTY")&&await kt(s.installDir)){await xe.rm(e,{recursive:!0,force:!0}).catch(()=>{}),jr(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw t}Lr(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),jr(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await xe.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function jr(s,e){if(s)try{s(e)}catch{}}var Hf=5,jf=25;function Lf(s){return sa(s,0)}async function sa(s,e){try{await new Promise((t,n)=>{let r=s.registry?["--registry",s.registry]:[],o=Ft("npm",["install","--no-audit","--no-fund","--silent",...r,s.packageSpec]),i;try{i=Nf(o.command,o.args,{cwd:s.cwd,stdio:["ignore","pipe","pipe"],shell:o.shell,windowsHide:!0})}catch(d){n(d);return}let a="";i.stdout?.on("data",d=>{}),i.stderr?.setEncoding("utf8"),i.stderr?.on("data",d=>{a=(a+d).slice(-4096)}),i.on("error",d=>{if(d.code==="ENOENT"){let u=(process.env.PATH??process.env.Path??"").split(Ff).filter(l=>l.length>0);n(new Error(`npm not found on PATH: tried to run ${JSON.stringify(o.command)}${o.shell?" through a shell":""} against ${u.length} PATH entries. Install Node.js / npm, or use a binary-distributed agent.`));return}n(d)}),i.on("exit",(d,c)=>{if(d===0){t();return}let u=d!==null?`exit code ${d}`:`signal ${c??"unknown"}`,l=a.trim();n(new Error(l?`npm install ${s.packageSpec} failed (${u})
14
- stderr: ${l}`:`npm install ${s.packageSpec} failed (${u})`))})})}catch(t){if(t.code==="ETXTBSY"&&e<Hf)return await new Promise(r=>setTimeout(r,jf*(e+1))),sa(s,e+1);throw t}}function Uf(s){if(s.startsWith("@")){let t=s.indexOf("/");if(t===-1)return s;let r=s.slice(t+1).indexOf("@");return r===-1?s:s.slice(0,t+1+r)}let e=s.indexOf("@");return e<=0?s:s.slice(0,e)}function Bf(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}async function ra(s,e){let t=Ue.join(s,"node_modules",e,"package.json");try{let n=await xe.readFile(t,"utf8"),r=JSON.parse(n);return typeof r.bin=="string"||typeof r.bin=="object"&&r.bin!==null&&!Array.isArray(r.bin)?r.bin:void 0}catch{return}}async function ta(s){let e=Ue.join(s.installDir,"node_modules",".bin"),t=Ue.join(e,s.hint);if(await kt(t))return{binName:s.hint,binPath:t};let n=await ra(s.installDir,s.packageName);if(typeof n=="object"&&n!==null){let r=Object.keys(n);if(r.length===1){let o=r[0],i=Ue.join(e,o);if(await kt(i))return{binName:o,binPath:i}}else if(r.length>1){for(let o of[s.hint,s.basename])if(r.includes(o)){let i=Ue.join(e,o);if(await kt(i))return{binName:o,binPath:i}}}}if(s.basename!==s.hint){let r=Ue.join(e,s.basename);if(await kt(r))return{binName:s.basename,binPath:r}}}async function kt(s){try{return await xe.access(s),!0}catch{return!1}}var Wf=L.object({package:L.string(),bin:L.string().optional(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Nt=L.object({archive:L.string().url().optional(),cmd:L.string().optional(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),qf=L.object({"darwin-aarch64":Nt.optional(),"darwin-x86_64":Nt.optional(),"linux-aarch64":Nt.optional(),"linux-x86_64":Nt.optional(),"windows-x86_64":Nt.optional(),"windows-aarch64":Nt.optional()}),zf=L.object({package:L.string(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Jf=L.object({command:L.string(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Vf=L.object({command:L.string().optional(),url:L.string().optional(),description:L.string().optional()}),Gf=L.object({npx:Wf.optional(),binary:qf.optional(),uvx:zf.optional(),exec:Jf.optional()}),Kf=L.object({id:L.string(),name:L.string(),version:L.string().optional(),description:L.string().optional(),authors:L.array(L.string()).optional(),license:L.string().optional(),icon:L.string().optional(),repository:L.string().optional(),website:L.string().optional(),distribution:Gf,onboarding:Vf.optional(),requiredEnv:L.array(L.string().min(1)).optional()}),oa=8;function ca(s){return s.installId??s.id}function Wr(s){let e=s.extendsChain;return e&&e.length>0?e[e.length-1]:s.id}function qr(s,e){if(s)for(let t of e.extendsChain??[e.id]){let n=s[t];if(n!==void 0)return{value:n,from:t}}}function ua(s,e){if(!s)return;let t,n;for(let r of[...e.extendsChain??[e.id]].reverse()){let o=s[r];o!==void 0&&(t={...t,...o},n=r)}return t!==void 0&&n!==void 0?{value:t,from:n}:void 0}var ia=L.object({version:L.string(),agents:L.array(Kf),extensions:L.array(L.unknown()).optional()}),ss=class{constructor(e,t={}){this.config=e;this.options=t}config;options;cache;async load(){if(this.cache&&(this.isPinned()||this.isFresh(this.cache.fetchedAt)))return this.cache.data;let e=await this.readDiskCache();if(e&&(this.isPinned()||this.isFresh(e.fetchedAt)))return this.cache=e,e.data;try{let t=await this.fetchFromNetwork();return this.cache=t,await this.writeDiskCache(t),t.data}catch(t){if(e){let n=this.options.onStaleFallback;if(n)try{n(t,Date.now()-e.fetchedAt)}catch{}return this.cache=e,e.data}throw t}}async refresh(){let e=await this.fetchFromNetwork();return this.cache=e,await this.writeDiskCache(e),e.data}lastFetchedAt(){return this.cache?.fetchedAt}setConfig(e){this.config=e}async getAgent(e){return this.resolveAgent(e,[])}async resolveAgent(e,t){let n=this.findLocalDef(e);if(n){if(n.def.extends===void 0)return{...Br(n.id,n.def),extendsChain:[n.id]};if(t.includes(n.id))throw new Error(`agent ${n.id}: extends cycle (${[...t,n.id].join(" -> ")})`);if(t.length+1>=oa)throw new Error(`agent ${n.id}: extends chain deeper than ${oa} (${[...t,n.id].join(" -> ")})`);let c=await this.resolveAgent(n.def.extends,[...t,n.id]);if(!c)throw new Error(`agent ${n.id}: extends ${JSON.stringify(n.def.extends)}, which is not a known agent`);return this.applyOverride(Yf(n.id,n.def,c))}let r=await this.load(),o=r.agents.find(c=>c.id===e);if(o)return this.applyOverride(o);let i=r.agents.find(c=>zr(c)===e);if(i)return this.applyOverride(i);let a=e.toLowerCase(),d=r.agents.find(c=>c.id.toLowerCase()===`${a}-acp`);if(d)return this.applyOverride(d);if(a.length>0){let c=r.agents.filter(u=>u.id.toLowerCase().startsWith(a));if(c.length===1)return this.applyOverride(c[0])}}findLocalDef(e){let t=this.config.agents??{},n=t[e];if(n)return{id:e,def:n};let r=e.toLowerCase();for(let[o,i]of Object.entries(t))if(o.toLowerCase()===`${r}-acp`)return{id:o,def:i}}localAgents(){return Object.entries(this.config.agents??{}).filter(([,e])=>e.extends===void 0).map(([e,t])=>Br(e,t))}async resolvedLocalAgents(){let e=[];for(let t of Object.keys(this.config.agents??{}))try{let n=await this.resolveAgent(t,[]);n&&e.push(n)}catch(n){this.options.onResolveError?.(t,n)}return e}applyOverride(e){let t=e.extendsChain?e:{...e,extendsChain:[e.id]},n=this.config.agentOverrides?.[t.id];if(!n)return t;let r=t.distribution,o=t.version,i=t.installId;return n.packageSpec&&r.npx&&(o=Xf(n.packageSpec),i=t.id,r={...r,npx:{...r.npx,package:n.packageSpec}}),n.extraArgs?.length&&(r=Qf(r,n.extraArgs)),n.env&&Object.keys(n.env).length>0&&(r=fa(r,{env:n.env})),r===t.distribution?t:{...t,version:o,installId:i,distribution:r}}isPinned(){return this.config.registry?.pinned===!0}isFresh(e){let t=Date.now()-e,n=this.config.registry.ttlHours*60*60*1e3;return t<n}async fetchFromNetwork(){let e=await fetch(this.config.registry.url);if(!e.ok)throw new Error(`Registry fetch failed: HTTP ${e.status}`);let t=await e.json(),n=ia.parse(t),r={fetchedAt:Date.now(),raw:t,data:n},o=this.options.onFetched;return o&&Promise.resolve().then(()=>o(n)).catch(()=>{}),r}async readDiskCache(){let e=await de(E.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=ia.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await he(E.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function la(s){return s&&Object.fromEntries(Object.entries(s).map(([e,t])=>[e,ce(t)]))}function Br(s,e){return{id:s,name:e.name??s,description:e.description,version:"local",distribution:{exec:{command:ce(e.command??s),args:e.args?.map(ce),env:la(e.env)}}}}function fa(s,e){let t=e.args?.map(ce),n=la(e.env),r=o=>({...o,...t?{args:t}:{},...n?{env:{...o.env,...n}}:{}});return{...s.npx?{npx:r(s.npx)}:{},...s.uvx?{uvx:r(s.uvx)}:{},...s.exec?{exec:r(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([o,i])=>[o,i&&r(i)]))}:{}}}function Qf(s,e){let t=n=>({...n,args:[...n.args??[],...e]});return{...s.npx?{npx:t(s.npx)}:{},...s.uvx?{uvx:t(s.uvx)}:{},...s.exec?{exec:t(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([n,r])=>[n,r&&t(r)]))}:{}}}function Yf(s,e,t){let n=e.command!==void 0;return{...t,id:s,name:e.name??t.name,description:e.description??t.description,version:n?"local":t.version,distribution:n?Br(s,e).distribution:fa(t.distribution,e),installId:n?s:t.installId??t.id,extendsChain:[s,...t.extendsChain??[t.id]]}}function Xf(s){let e=s.lastIndexOf("@"),n=(e>0?s.slice(e+1):"").replace(/[^a-zA-Z0-9._-]/g,"_");return n.length>0?`pin-${n}`:"pinned"}function zr(s){let e=s.distribution.npx?.package;if(!e)return;let t=e.lastIndexOf("/"),n=t===-1?e:e.slice(t+1),r=n.lastIndexOf("@");return r<=0?n:n.slice(0,r)}async function Dt(s){let e=typeof s.resolvedLocalAgents=="function"?await s.resolvedLocalAgents():typeof s.localAgents=="function"?s.localAgents():[],t;try{t=await s.load()}catch(i){if(e.length===0)throw i;t={version:"local-only",agents:[]}}let n=new Set(e.map(i=>i.id)),r=[...e,...t.agents.filter(i=>!n.has(i.id))],o=await Promise.all(r.map(async i=>({id:i.id,name:i.name,version:i.version,description:i.description,distributions:Object.keys(i.distribution),installed:await Jr(i),...i.extendsChain?{extendsChain:i.extendsChain}:{},source:n.has(i.id)?"local":"registry",...i.onboarding?{onboarding:i.onboarding}:{}})));return{version:t.version,fetchedAt:s.lastFetchedAt(),agents:o}}async function Jr(s){let e=Le();if(!e)return"no";let t=s.version??"current",n=ca(s);if(s.distribution.exec)return"yes";if(s.distribution.binary){let r=Dr(s.distribution.binary,e);if(r?.cmd){let o=rs.resolve(E.agentInstallDir(n,e,t),r.cmd);if(await aa(o))return"yes"}}if(s.distribution.npx){let r=s.distribution.npx,o=r.bin??zr(s)??r.package,i=E.agentNpmInstallDir(n,e,t),a=rs.join(i,"node_modules",".bin",o);if(await aa(a))return"yes"}return!s.distribution.npx&&!s.distribution.binary&&s.distribution.uvx?"lazy":"no"}async function aa(s){try{return await da.access(s),!0}catch{return!1}}async function Me(s,e=[],t={}){let n=s.version??"current",r=ca(s);if(s.distribution.npx){let o=s.distribution.npx,i=e.length>0?e:o.args??[];if(process.env.HYDRA_ACP_SKIP_NPM_PREFETCH)return{command:"npx",args:["-y",o.package,...i],env:o.env??{},version:n,installId:r};let a=o.bin??zr(s)??o.package,d=t.onInstallProgress;return{command:await na({agentId:r,version:n,packageSpec:o.package,bin:a,registry:t.npmRegistry,onProgress:d?u=>d({source:"npm",...u}):void 0}),args:i,env:o.env??{},version:n,installId:r}}if(s.distribution.binary){let o=Dr(s.distribution.binary);if(!o)throw new Error(`Agent ${s.id} has no binary distribution for ${Le()??"this platform"}.`);let i=t.onInstallProgress,a=await Xi({agentId:r,version:n,target:o,onProgress:i?c=>i({source:"binary",...c}):void 0}),d=e.length>0?e:o.args??[];return{command:a,args:d,env:o.env??{},version:n,installId:r}}if(s.distribution.uvx){let o=s.distribution.uvx,i=e.length>0?e:o.args??[];return{command:"uvx",args:[o.package,...i],env:o.env??{},version:n,installId:r}}if(s.distribution.exec){let o=s.distribution.exec,i=e.length>0?e:o.args??[];return{command:o.command,args:i,env:o.env??{},version:n,installId:r}}throw new Error(`Agent ${s.id} has no usable distribution method.`)}import{spawn as sp,spawnSync as rp}from"child_process";import*as as from"fs";import*as Ta from"path";var x={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,AuthRequired:-32e3,SessionNotFound:-32001,NotAuthorisedToAttach:-32002,MultiClientNotSupported:-32003,AgentNotInstalled:-32005,BundleAlreadyImported:-32010,PermissionDenied:-32011,AlreadyAttached:-32012,StreamNotEnabled:-32013,SessionClosing:-32014};import{z as Q}from"zod";var pa=Q.object({protocolVersion:Q.number().optional(),clientCapabilities:Q.record(Q.unknown()).optional(),clientInfo:Q.object({name:Q.string(),version:Q.string().optional()}).optional()}),Zf=Q.enum(["full","pending_only","none","after_message"]),ga=Q.object({cwd:Q.string(),mcpServers:Q.array(Q.unknown()).optional(),_meta:Q.record(Q.unknown()).optional()}),ha=Q.object({upstreamSessionId:Q.string(),agentId:Q.string(),cwd:Q.string(),title:Q.string().optional(),agentArgs:Q.array(Q.string()).optional()}),ma=Q.object({sessionId:Q.string(),historyPolicy:Zf.default("full"),afterMessageId:Q.string().optional(),afterSeq:Q.number().optional(),clientId:Q.string().optional(),clientInfo:Q.object({name:Q.string(),version:Q.string().optional()}).optional(),_meta:Q.record(Q.unknown()).optional()});import{z as hn}from"zod";var Ht=hn.object({selection:hn.object({text:hn.string().min(1),responsePartId:hn.string().optional()}).optional(),contextThroughSeq:hn.number().optional()});import{z as N}from"zod";var ya=N.object({sessionId:N.string()}),wa=N.object({cwd:N.string().optional(),cursor:N.string().optional()}),Vr=N.object({used:N.number().optional(),size:N.number().optional(),costAmount:N.number().optional(),costCurrency:N.string().optional()}),rv=N.object({sessionId:N.string(),upstreamSessionId:N.string().optional(),cwd:N.string(),workspace:N.object({path:N.string(),sourceCwd:N.string(),label:N.string(),provider:N.string(),snapshot:N.string().optional(),vcs:N.record(N.string(),N.string()).optional()}).optional(),workspaceError:N.string().optional(),title:N.string().optional(),agentId:N.string().optional(),currentModel:N.string().optional(),currentUsage:Vr.optional(),importedFromMachine:N.string().optional(),importedFromUpstreamSessionId:N.string().optional(),parentSessionId:N.string().optional(),forkedFromSessionId:N.string().optional(),forkedFromMessageId:N.string().optional(),side:Ht.optional(),originatingClient:N.object({name:N.string(),version:N.string().optional()}).optional(),interactive:N.boolean().optional(),priority:N.number().int().nonnegative().optional(),lastTurnEndedAt:N.number().optional(),readAt:N.number().optional(),unread:N.boolean().optional(),createdAt:N.string().optional(),updatedAt:N.string(),attachedClients:N.number().int().nonnegative(),status:N.enum(["warm","cold"]).default("warm"),busy:N.boolean().default(!1),awaitingInput:N.boolean().default(!1),turnStartedAt:N.number().optional(),armedTasks:N.number().int().nonnegative().optional(),armedSince:N.number().int().positive().optional(),compactionState:N.any().optional(),agentPid:N.number().int().positive().optional(),forkSynthesisState:N.enum(["running","failed"]).optional(),_meta:N.record(N.unknown()).optional()}),ep=N.object({sessionId:N.string(),cwd:N.string(),title:N.string().optional(),updatedAt:N.string().optional(),_meta:N.record(N.unknown()).optional()}),ov=N.object({sessions:N.array(ep),nextCursor:N.string().optional()});function os(s,e){let t={attachedClients:s.attachedClients,status:s.status,busy:s.busy,awaitingInput:s.awaitingInput};return s.cwd!==void 0&&(t.cwd=s.cwd),s.workspace!==void 0&&(t.workspaceInfo=s.workspace),s.workspaceError!==void 0&&(t.workspaceError=s.workspaceError),s.title!==void 0&&(t.title=s.title),s.agentId!==void 0&&(t.agentId=s.agentId),s.upstreamSessionId!==void 0&&(t.upstreamSessionId=s.upstreamSessionId),s.createdAt!==void 0&&(t.createdAt=s.createdAt),s.currentModel!==void 0&&(t.currentModel=s.currentModel),s.currentUsage!==void 0&&(t.currentUsage=s.currentUsage),s.importedFromMachine!==void 0&&(t.importedFromMachine=s.importedFromMachine),s.importedFromUpstreamSessionId!==void 0&&(t.importedFromUpstreamSessionId=s.importedFromUpstreamSessionId),s.parentSessionId!==void 0&&(t.parentSessionId=s.parentSessionId),s.forkedFromSessionId!==void 0&&(t.forkedFromSessionId=s.forkedFromSessionId),s.forkedFromMessageId!==void 0&&(t.forkedFromMessageId=s.forkedFromMessageId),s.side!==void 0&&(t.side=s.side),s.originatingClient!==void 0&&(t.originatingClient=s.originatingClient),s.interactive!==void 0&&(t.interactive=s.interactive),s.priority!==void 0&&s.priority>0&&(t.priority=s.priority),s.lastTurnEndedAt!==void 0&&(t.lastTurnEndedAt=s.lastTurnEndedAt),s.readAt!==void 0&&(t.readAt=s.readAt),s.unread&&(t.unread=!0),s.armedTasks!==void 0&&(t.armedTasks=s.armedTasks),s.armedSince!==void 0&&(t.armedSince=s.armedSince),s.compactionState!==void 0&&(t.compactionState=s.compactionState),s.forkSynthesisState!==void 0&&(t.forkSynthesisState=s.forkSynthesisState),e&&(e.clientId!==void 0&&(t.clientId=e.clientId),e.currentMode!==void 0&&(t.currentMode=e.currentMode),e.agentArgs!==void 0&&e.agentArgs.length>0&&(t.agentArgs=e.agentArgs),e.availableCommands!==void 0&&e.availableCommands.length>0&&(t.availableCommands=e.availableCommands),e.availableModes!==void 0&&e.availableModes.length>0&&(t.availableModes=e.availableModes),e.availableModels!==void 0&&e.availableModels.length>0&&(t.availableModels=e.availableModels),e.turnStartedAt!==void 0&&(t.turnStartedAt=e.turnStartedAt),e.agentCapabilities!==void 0&&(t.agentCapabilities=e.agentCapabilities),e.queue!==void 0&&e.queue.length>0&&(t.queue=e.queue),e.resurrected===!0&&(t.resurrected=!0),e.armedTaskList!==void 0&&(t.armedTaskList=e.armedTaskList)),t}function ka(s){let e={sessionId:s.sessionId,cwd:s.cwd,updatedAt:s.updatedAt,_meta:mn(s._meta,os(s))};return s.title!==void 0&&(e.title=s.title),e}var le="hydra-acp";function tp(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e={};for(let[t,n]of Object.entries(s)){if(typeof t!="string"||t.length===0||typeof n!="string")return;e[t]=n}return e}function it(s){if(!s)return{};let e=s[le];if(!e||typeof e!="object"||Array.isArray(e))return{};let t=e,n={};if(typeof t.upstreamSessionId=="string"&&(n.upstreamSessionId=t.upstreamSessionId),typeof t.agentId=="string"&&(n.agentId=t.agentId),typeof t.cwd=="string"&&(n.cwd=t.cwd),t.workspace!==null&&typeof t.workspace=="object"&&!Array.isArray(t.workspace)){let o=t.workspace,i={};typeof o.label=="string"&&(i.label=o.label),typeof o.from=="string"&&(i.from=o.from),o.required===!0&&(i.required=!0),o.adopt===!0&&(i.adopt=!0),typeof o.provider=="string"&&(i.provider=o.provider),n.workspace=i}if(t.workspaceInfo!==null&&typeof t.workspaceInfo=="object"&&!Array.isArray(t.workspaceInfo)){let o=t.workspaceInfo;if(typeof o.path=="string"&&typeof o.sourceCwd=="string"&&typeof o.label=="string"&&typeof o.provider=="string"){let i={path:o.path,sourceCwd:o.sourceCwd,label:o.label,provider:o.provider};if(typeof o.snapshot=="string"&&(i.snapshot=o.snapshot),o.vcs!==null&&typeof o.vcs=="object"&&!Array.isArray(o.vcs)){let a={};for(let[d,c]of Object.entries(o.vcs))typeof c=="string"&&(a[d]=c);i.vcs=a}n.workspaceInfo=i}}if(typeof t.workspaceError=="string"&&(n.workspaceError=t.workspaceError),typeof t.clientId=="string"&&(n.clientId=t.clientId),typeof t.readonly=="boolean"&&(n.readonly=t.readonly),(t.replayMode==="instant"||t.replayMode==="drip")&&(n.replayMode=t.replayMode),typeof t.dripSpeed=="number"&&t.dripSpeed>0&&(n.dripSpeed=t.dripSpeed),typeof t.historyLimit=="number"&&Number.isFinite(t.historyLimit)&&t.historyLimit>=0&&(n.historyLimit=t.historyLimit),(t.toolContent==="inline"||t.toolContent==="references")&&(n.toolContent=t.toolContent),t.detachStatus==="detached"&&(n.detachStatus=t.detachStatus),typeof t.title=="string"&&(n.title=t.title),Array.isArray(t.agentArgs)&&t.agentArgs.every(o=>typeof o=="string")&&(n.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(o=>typeof o=="string")&&(n.transformers=t.transformers),t.resume){let o=ha.safeParse(t.resume);o.success&&(n.resume=o.data)}if(typeof t.model=="string"&&(n.model=t.model),typeof t.currentModel=="string"&&(n.currentModel=t.currentModel),typeof t.currentMode=="string"&&(n.currentMode=t.currentMode),t.currentUsage){let o=Vr.safeParse(t.currentUsage);o.success&&(n.currentUsage=o.data)}if(typeof t.turnStartedAt=="number"&&t.turnStartedAt>0&&(n.turnStartedAt=t.turnStartedAt),typeof t.armedTasks=="number"&&t.armedTasks>=0&&(n.armedTasks=t.armedTasks),typeof t.armedSince=="number"&&t.armedSince>0&&(n.armedSince=t.armedSince),Array.isArray(t.armedTaskList)){let o=[];for(let i of t.armedTaskList){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;typeof a.label!="string"||typeof a.since!="number"||o.push({label:a.label,since:a.since,...typeof a.taskId=="string"?{taskId:a.taskId}:{},...typeof a.taskType=="string"?{taskType:a.taskType}:{},...typeof a.toolCallId=="string"?{toolCallId:a.toolCallId}:{}})}n.armedTaskList=o}if(Array.isArray(t.availableCommands)){let o=[];for(let i of t.availableCommands){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.name!="string")continue;let d={name:a.name};typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableCommands=o)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let o=t.prompt,i={};typeof o.queueing=="boolean"&&(i.queueing=o.queueing),typeof o.cancelling=="boolean"&&(i.cancelling=o.cancelling),typeof o.updating=="boolean"&&(i.updating=o.updating),typeof o.amending=="boolean"&&(i.amending=o.amending),typeof o.pipelining=="boolean"&&(i.pipelining=o.pipelining),n.prompt=i}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let o=t.agents,i={};typeof o.list=="boolean"&&(i.list=o.list),typeof o.installProgress=="boolean"&&(i.installProgress=o.installProgress),n.agents=i}if(typeof t.mcpStdin=="boolean"&&(n.mcpStdin=t.mcpStdin),typeof t.interactive=="boolean"&&(n.interactive=t.interactive),typeof t.ancillary=="boolean"&&(n.ancillary=t.ancillary),t.salvaged&&typeof t.salvaged=="object"&&!Array.isArray(t.salvaged)){let o=t.salvaged;typeof o.reason=="string"&&typeof o.supersededMessageId=="string"&&(n.salvaged={reason:o.reason,supersededMessageId:o.supersededMessageId})}if(Array.isArray(t.queue)){let o=[];for(let i of t.queue){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i,d=a.originator;if(typeof a.messageId!="string"||!d||typeof d.clientId!="string"||!Array.isArray(a.prompt)||typeof a.position!="number"||typeof a.enqueuedAt!="number")continue;let c={clientId:d.clientId};typeof d.name=="string"&&(c.name=d.name),typeof d.version=="string"&&(c.version=d.version),o.push({messageId:a.messageId,originator:c,prompt:a.prompt,position:a.position,enqueuedAt:a.enqueuedAt})}o.length>0&&(n.queue=o)}if(Array.isArray(t.availableModes)){let o=[];for(let i of t.availableModes){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.id!="string")continue;let d={id:a.id};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModes=o)}if(Array.isArray(t.availableModels)){let o=[];for(let i of t.availableModels){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.modelId!="string")continue;let d={modelId:a.modelId};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModels=o)}(t.status==="warm"||t.status==="cold")&&(n.status=t.status),typeof t.busy=="boolean"&&(n.busy=t.busy),typeof t.awaitingInput=="boolean"&&(n.awaitingInput=t.awaitingInput),typeof t.attachedClients=="number"&&(n.attachedClients=t.attachedClients),typeof t.resurrected=="boolean"&&(n.resurrected=t.resurrected),typeof t.importedFromMachine=="string"&&(n.importedFromMachine=t.importedFromMachine),typeof t.importedFromUpstreamSessionId=="string"&&(n.importedFromUpstreamSessionId=t.importedFromUpstreamSessionId),typeof t.parentSessionId=="string"&&(n.parentSessionId=t.parentSessionId),typeof t.forkedFromSessionId=="string"&&(n.forkedFromSessionId=t.forkedFromSessionId),typeof t.forkedFromMessageId=="string"&&(n.forkedFromMessageId=t.forkedFromMessageId);let r=Ht.safeParse(t.side);if(r.success&&(n.side=r.data),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let o=t.originatingClient;n.originatingClient={name:o.name,...typeof o.version=="string"?{version:o.version}:{}}}if(t.agentCapabilities!==void 0&&(n.agentCapabilities=t.agentCapabilities),t.env!==void 0){let o=tp(t.env);o!==void 0&&(n.env=o)}return n}function Be(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?s:{...t,_meta:{...n,[le]:{...o,recordedAt:e}}}}function We(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.seq=="number"?s:{...t,_meta:{...n,[le]:{...o,seq:e}}}}function mn(s,e){return{...s??{},[le]:e}}import{z as _}from"zod";var va=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.record(_.unknown()).optional()}),is=_.object({sessionId:_.string()}),ba=_.object({clientId:_.string(),name:_.string().optional(),version:_.string().optional()}),fv=_.object({sessionId:_.string(),messageId:_.string(),originator:ba,prompt:_.array(_.unknown()),position:_.number().int().nonnegative(),queueDepth:_.number().int().positive(),enqueuedAt:_.number()}),pv=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),gv=_.object({sessionId:_.string(),messageId:_.string(),reason:_.enum(["started","cancelled","abandoned"])}),Sa=_.object({sessionId:_.string(),messageId:_.string()}),hv=_.object({cancelled:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Ia=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),mv=_.object({updated:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Aa=_.object({sessionId:_.string(),targetMessageId:_.string(),prompt:_.array(_.unknown()),replaceQueue:_.boolean().optional(),onTargetCompleted:_.enum(["reject","send_anyway"]).optional()}),yv=_.object({amended:_.boolean(),reason:_.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:_.string().optional()}),Ca=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.object({steering:_.object({idleBehavior:_.literal("promptRequired").optional()}).optional()}).optional()}),wv=_.object({outcome:_.enum(["injected","startedNewTurn","promptRequired","failed"]),reason:_.literal("noRunningTurn").optional(),detached:_.boolean().optional()}),kv=_.object({sessionId:_.string(),cancelledMessageId:_.string(),newMessageId:_.string(),prompt:_.array(_.unknown()),originator:ba,amendedAt:_.number()});import{z as at}from"zod";var Sv=at.object({agentId:at.string(),version:at.string(),source:at.enum(["binary","npm"]),phase:at.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:at.number().optional(),totalBytes:at.number().optional(),packageSpec:at.string().optional()}),Ra="hydra-acp/agents/install_progress",jt={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function xa(s,e){let t="",n=[],r=[],o=!1,i=a=>{if(!o){o=!0;for(let d of r)d(a)}};return s.setEncoding("utf8"),s.on("data",a=>{t+=a;let d=t.indexOf(`
13
+ `))}async function na(s){let e=Le();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=E.agentNpmInstallDir(s.agentId,e,s.version),n=Uf(s.packageSpec),r=Bf(n),o={installDir:t,packageName:n,hint:s.bin,basename:r},i=Ue.join(t,"node_modules",".bin",s.bin);if(await kt(i))return i;if(await kt(t)){let l=await ta(o);if(l)return l.binPath}await Df({agentId:s.agentId,version:s.version,packageSpec:s.packageSpec,installDir:t,registry:s.registry,onProgress:s.onProgress});let a=await ta(o);if(a)return a.binPath;let d=await ra(t,n),c=typeof d=="object"&&d!==null?Object.keys(d):typeof d=="string"?[r]:[],u=c.length>0?` (package declares bins: ${c.join(", ")})`:"";throw new Error(`Agent ${s.agentId}: npm install of ${s.packageSpec} did not produce bin ${s.bin} (looked in ${t}/node_modules/.bin/)${u}`)}async function Df(s){await xe.mkdir(Ue.dirname(s.installDir),{recursive:!0});let e=await xe.mkdtemp(`${s.installDir}.partial-`);try{Lr(`hydra-acp: installing ${s.packageSpec} for ${s.agentId} into ${e}`),Hr(s.onProgress,{phase:"install_start",agentId:s.agentId,version:s.version,packageSpec:s.packageSpec}),await Lf({packageSpec:s.packageSpec,cwd:e,registry:s.registry});try{await xe.rename(e,s.installDir)}catch(t){let n=t;if((n.code==="EEXIST"||n.code==="ENOTEMPTY")&&await kt(s.installDir)){await xe.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Hr(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw t}Lr(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),Hr(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await xe.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Hr(s,e){if(s)try{s(e)}catch{}}var jf=5,Hf=25;function Lf(s){return sa(s,0)}async function sa(s,e){try{await new Promise((t,n)=>{let r=s.registry?["--registry",s.registry]:[],o=Ft("npm",["install","--no-audit","--no-fund","--silent",...r,s.packageSpec]),i;try{i=Nf(o.command,o.args,{cwd:s.cwd,stdio:["ignore","pipe","pipe"],shell:o.shell,windowsHide:!0})}catch(d){n(d);return}let a="";i.stdout?.on("data",d=>{}),i.stderr?.setEncoding("utf8"),i.stderr?.on("data",d=>{a=(a+d).slice(-4096)}),i.on("error",d=>{if(d.code==="ENOENT"){let u=(process.env.PATH??process.env.Path??"").split(Ff).filter(l=>l.length>0);n(new Error(`npm not found on PATH: tried to run ${JSON.stringify(o.command)}${o.shell?" through a shell":""} against ${u.length} PATH entries. Install Node.js / npm, or use a binary-distributed agent.`));return}n(d)}),i.on("exit",(d,c)=>{if(d===0){t();return}let u=d!==null?`exit code ${d}`:`signal ${c??"unknown"}`,l=a.trim();n(new Error(l?`npm install ${s.packageSpec} failed (${u})
14
+ stderr: ${l}`:`npm install ${s.packageSpec} failed (${u})`))})})}catch(t){if(t.code==="ETXTBSY"&&e<jf)return await new Promise(r=>setTimeout(r,Hf*(e+1))),sa(s,e+1);throw t}}function Uf(s){if(s.startsWith("@")){let t=s.indexOf("/");if(t===-1)return s;let r=s.slice(t+1).indexOf("@");return r===-1?s:s.slice(0,t+1+r)}let e=s.indexOf("@");return e<=0?s:s.slice(0,e)}function Bf(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}async function ra(s,e){let t=Ue.join(s,"node_modules",e,"package.json");try{let n=await xe.readFile(t,"utf8"),r=JSON.parse(n);return typeof r.bin=="string"||typeof r.bin=="object"&&r.bin!==null&&!Array.isArray(r.bin)?r.bin:void 0}catch{return}}async function ta(s){let e=Ue.join(s.installDir,"node_modules",".bin"),t=Ue.join(e,s.hint);if(await kt(t))return{binName:s.hint,binPath:t};let n=await ra(s.installDir,s.packageName);if(typeof n=="object"&&n!==null){let r=Object.keys(n);if(r.length===1){let o=r[0],i=Ue.join(e,o);if(await kt(i))return{binName:o,binPath:i}}else if(r.length>1){for(let o of[s.hint,s.basename])if(r.includes(o)){let i=Ue.join(e,o);if(await kt(i))return{binName:o,binPath:i}}}}if(s.basename!==s.hint){let r=Ue.join(e,s.basename);if(await kt(r))return{binName:s.basename,binPath:r}}}async function kt(s){try{return await xe.access(s),!0}catch{return!1}}var Wf=L.object({package:L.string(),bin:L.string().optional(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Nt=L.object({archive:L.string().url().optional(),cmd:L.string().optional(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),qf=L.object({"darwin-aarch64":Nt.optional(),"darwin-x86_64":Nt.optional(),"linux-aarch64":Nt.optional(),"linux-x86_64":Nt.optional(),"windows-x86_64":Nt.optional(),"windows-aarch64":Nt.optional()}),zf=L.object({package:L.string(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Jf=L.object({command:L.string(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Vf=L.object({command:L.string().optional(),url:L.string().optional(),description:L.string().optional()}),Gf=L.object({npx:Wf.optional(),binary:qf.optional(),uvx:zf.optional(),exec:Jf.optional()}),Kf=L.object({id:L.string(),name:L.string(),version:L.string().optional(),description:L.string().optional(),authors:L.array(L.string()).optional(),license:L.string().optional(),icon:L.string().optional(),repository:L.string().optional(),website:L.string().optional(),distribution:Gf,onboarding:Vf.optional(),requiredEnv:L.array(L.string().min(1)).optional()}),oa=8;function ca(s){return s.installId??s.id}function Wr(s){let e=s.extendsChain;return e&&e.length>0?e[e.length-1]:s.id}function qr(s,e){if(s)for(let t of e.extendsChain??[e.id]){let n=s[t];if(n!==void 0)return{value:n,from:t}}}function ua(s,e){if(!s)return;let t,n;for(let r of[...e.extendsChain??[e.id]].reverse()){let o=s[r];o!==void 0&&(t={...t,...o},n=r)}return t!==void 0&&n!==void 0?{value:t,from:n}:void 0}var ia=L.object({version:L.string(),agents:L.array(Kf),extensions:L.array(L.unknown()).optional()}),ss=class{constructor(e,t={}){this.config=e;this.options=t}config;options;cache;async load(){if(this.cache&&(this.isPinned()||this.isFresh(this.cache.fetchedAt)))return this.cache.data;let e=await this.readDiskCache();if(e&&(this.isPinned()||this.isFresh(e.fetchedAt)))return this.cache=e,e.data;try{let t=await this.fetchFromNetwork();return this.cache=t,await this.writeDiskCache(t),t.data}catch(t){if(e){let n=this.options.onStaleFallback;if(n)try{n(t,Date.now()-e.fetchedAt)}catch{}return this.cache=e,e.data}throw t}}async refresh(){let e=await this.fetchFromNetwork();return this.cache=e,await this.writeDiskCache(e),e.data}lastFetchedAt(){return this.cache?.fetchedAt}setConfig(e){this.config=e}async getAgent(e){return this.resolveAgent(e,[])}async resolveAgent(e,t){let n=this.findLocalDef(e);if(n){if(n.def.extends===void 0)return{...Br(n.id,n.def),extendsChain:[n.id]};if(t.includes(n.id))throw new Error(`agent ${n.id}: extends cycle (${[...t,n.id].join(" -> ")})`);if(t.length+1>=oa)throw new Error(`agent ${n.id}: extends chain deeper than ${oa} (${[...t,n.id].join(" -> ")})`);let c=await this.resolveAgent(n.def.extends,[...t,n.id]);if(!c)throw new Error(`agent ${n.id}: extends ${JSON.stringify(n.def.extends)}, which is not a known agent`);return this.applyOverride(Yf(n.id,n.def,c))}let r=await this.load(),o=r.agents.find(c=>c.id===e);if(o)return this.applyOverride(o);let i=r.agents.find(c=>zr(c)===e);if(i)return this.applyOverride(i);let a=e.toLowerCase(),d=r.agents.find(c=>c.id.toLowerCase()===`${a}-acp`);if(d)return this.applyOverride(d);if(a.length>0){let c=r.agents.filter(u=>u.id.toLowerCase().startsWith(a));if(c.length===1)return this.applyOverride(c[0])}}findLocalDef(e){let t=this.config.agents??{},n=t[e];if(n)return{id:e,def:n};let r=e.toLowerCase();for(let[o,i]of Object.entries(t))if(o.toLowerCase()===`${r}-acp`)return{id:o,def:i}}localAgents(){return Object.entries(this.config.agents??{}).filter(([,e])=>e.extends===void 0).map(([e,t])=>Br(e,t))}async resolvedLocalAgents(){let e=[];for(let t of Object.keys(this.config.agents??{}))try{let n=await this.resolveAgent(t,[]);n&&e.push(n)}catch(n){this.options.onResolveError?.(t,n)}return e}applyOverride(e){let t=e.extendsChain?e:{...e,extendsChain:[e.id]},n=this.config.agentOverrides?.[t.id];if(!n)return t;let r=t.distribution,o=t.version,i=t.installId;return n.packageSpec&&r.npx&&(o=Xf(n.packageSpec),i=t.id,r={...r,npx:{...r.npx,package:n.packageSpec}}),n.extraArgs?.length&&(r=Qf(r,n.extraArgs)),n.env&&Object.keys(n.env).length>0&&(r=fa(r,{env:n.env})),r===t.distribution?t:{...t,version:o,installId:i,distribution:r}}isPinned(){return this.config.registry?.pinned===!0}isFresh(e){let t=Date.now()-e,n=this.config.registry.ttlHours*60*60*1e3;return t<n}async fetchFromNetwork(){let e=await fetch(this.config.registry.url);if(!e.ok)throw new Error(`Registry fetch failed: HTTP ${e.status}`);let t=await e.json(),n=ia.parse(t),r={fetchedAt:Date.now(),raw:t,data:n},o=this.options.onFetched;return o&&Promise.resolve().then(()=>o(n)).catch(()=>{}),r}async readDiskCache(){let e=await de(E.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=ia.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await he(E.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function la(s){return s&&Object.fromEntries(Object.entries(s).map(([e,t])=>[e,ce(t)]))}function Br(s,e){return{id:s,name:e.name??s,description:e.description,version:"local",distribution:{exec:{command:ce(e.command??s),args:e.args?.map(ce),env:la(e.env)}}}}function fa(s,e){let t=e.args?.map(ce),n=la(e.env),r=o=>({...o,...t?{args:t}:{},...n?{env:{...o.env,...n}}:{}});return{...s.npx?{npx:r(s.npx)}:{},...s.uvx?{uvx:r(s.uvx)}:{},...s.exec?{exec:r(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([o,i])=>[o,i&&r(i)]))}:{}}}function Qf(s,e){let t=n=>({...n,args:[...n.args??[],...e]});return{...s.npx?{npx:t(s.npx)}:{},...s.uvx?{uvx:t(s.uvx)}:{},...s.exec?{exec:t(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([n,r])=>[n,r&&t(r)]))}:{}}}function Yf(s,e,t){let n=e.command!==void 0;return{...t,id:s,name:e.name??t.name,description:e.description??t.description,version:n?"local":t.version,distribution:n?Br(s,e).distribution:fa(t.distribution,e),installId:n?s:t.installId??t.id,extendsChain:[s,...t.extendsChain??[t.id]]}}function Xf(s){let e=s.lastIndexOf("@"),n=(e>0?s.slice(e+1):"").replace(/[^a-zA-Z0-9._-]/g,"_");return n.length>0?`pin-${n}`:"pinned"}function zr(s){let e=s.distribution.npx?.package;if(!e)return;let t=e.lastIndexOf("/"),n=t===-1?e:e.slice(t+1),r=n.lastIndexOf("@");return r<=0?n:n.slice(0,r)}async function Dt(s){let e=typeof s.resolvedLocalAgents=="function"?await s.resolvedLocalAgents():typeof s.localAgents=="function"?s.localAgents():[],t;try{t=await s.load()}catch(i){if(e.length===0)throw i;t={version:"local-only",agents:[]}}let n=new Set(e.map(i=>i.id)),r=[...e,...t.agents.filter(i=>!n.has(i.id))],o=await Promise.all(r.map(async i=>({id:i.id,name:i.name,version:i.version,description:i.description,distributions:Object.keys(i.distribution),installed:await Jr(i),...i.extendsChain?{extendsChain:i.extendsChain}:{},source:n.has(i.id)?"local":"registry",...i.onboarding?{onboarding:i.onboarding}:{}})));return{version:t.version,fetchedAt:s.lastFetchedAt(),agents:o}}async function Jr(s){let e=Le();if(!e)return"no";let t=s.version??"current",n=ca(s);if(s.distribution.exec)return"yes";if(s.distribution.binary){let r=Dr(s.distribution.binary,e);if(r?.cmd){let o=rs.resolve(E.agentInstallDir(n,e,t),r.cmd);if(await aa(o))return"yes"}}if(s.distribution.npx){let r=s.distribution.npx,o=r.bin??zr(s)??r.package,i=E.agentNpmInstallDir(n,e,t),a=rs.join(i,"node_modules",".bin",o);if(await aa(a))return"yes"}return!s.distribution.npx&&!s.distribution.binary&&s.distribution.uvx?"lazy":"no"}async function aa(s){try{return await da.access(s),!0}catch{return!1}}async function Me(s,e=[],t={}){let n=s.version??"current",r=ca(s);if(s.distribution.npx){let o=s.distribution.npx,i=e.length>0?e:o.args??[];if(process.env.HYDRA_ACP_SKIP_NPM_PREFETCH)return{command:"npx",args:["-y",o.package,...i],env:o.env??{},version:n,installId:r};let a=o.bin??zr(s)??o.package,d=t.onInstallProgress;return{command:await na({agentId:r,version:n,packageSpec:o.package,bin:a,registry:t.npmRegistry,onProgress:d?u=>d({source:"npm",...u}):void 0}),args:i,env:o.env??{},version:n,installId:r}}if(s.distribution.binary){let o=Dr(s.distribution.binary);if(!o)throw new Error(`Agent ${s.id} has no binary distribution for ${Le()??"this platform"}.`);let i=t.onInstallProgress,a=await Xi({agentId:r,version:n,target:o,onProgress:i?c=>i({source:"binary",...c}):void 0}),d=e.length>0?e:o.args??[];return{command:a,args:d,env:o.env??{},version:n,installId:r}}if(s.distribution.uvx){let o=s.distribution.uvx,i=e.length>0?e:o.args??[];return{command:"uvx",args:[o.package,...i],env:o.env??{},version:n,installId:r}}if(s.distribution.exec){let o=s.distribution.exec,i=e.length>0?e:o.args??[];return{command:o.command,args:i,env:o.env??{},version:n,installId:r}}throw new Error(`Agent ${s.id} has no usable distribution method.`)}import{spawn as sp,spawnSync as rp}from"child_process";import*as as from"fs";import*as Ta from"path";var x={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,AuthRequired:-32e3,SessionNotFound:-32001,NotAuthorisedToAttach:-32002,MultiClientNotSupported:-32003,AgentNotInstalled:-32005,BundleAlreadyImported:-32010,PermissionDenied:-32011,AlreadyAttached:-32012,StreamNotEnabled:-32013,SessionClosing:-32014};import{z as Q}from"zod";var pa=Q.object({protocolVersion:Q.number().optional(),clientCapabilities:Q.record(Q.unknown()).optional(),clientInfo:Q.object({name:Q.string(),version:Q.string().optional()}).optional()}),Zf=Q.enum(["full","pending_only","none","after_message"]),ga=Q.object({cwd:Q.string(),mcpServers:Q.array(Q.unknown()).optional(),_meta:Q.record(Q.unknown()).optional()}),ha=Q.object({upstreamSessionId:Q.string(),agentId:Q.string(),cwd:Q.string(),title:Q.string().optional(),agentArgs:Q.array(Q.string()).optional()}),ma=Q.object({sessionId:Q.string(),historyPolicy:Zf.default("full"),afterMessageId:Q.string().optional(),afterSeq:Q.number().optional(),clientId:Q.string().optional(),clientInfo:Q.object({name:Q.string(),version:Q.string().optional()}).optional(),_meta:Q.record(Q.unknown()).optional()});import{z as hn}from"zod";var jt=hn.object({selection:hn.object({text:hn.string().min(1),responsePartId:hn.string().optional()}).optional(),contextThroughSeq:hn.number().optional()});import{z as N}from"zod";var ya=N.object({sessionId:N.string()}),wa=N.object({cwd:N.string().optional(),cursor:N.string().optional()}),Vr=N.object({used:N.number().optional(),size:N.number().optional(),costAmount:N.number().optional(),costCurrency:N.string().optional()}),ov=N.object({sessionId:N.string(),upstreamSessionId:N.string().optional(),cwd:N.string(),workspace:N.object({path:N.string(),sourceCwd:N.string(),label:N.string(),provider:N.string(),snapshot:N.string().optional(),vcs:N.record(N.string(),N.string()).optional()}).optional(),workspaceError:N.string().optional(),title:N.string().optional(),agentId:N.string().optional(),currentModel:N.string().optional(),currentUsage:Vr.optional(),importedFromMachine:N.string().optional(),importedFromUpstreamSessionId:N.string().optional(),parentSessionId:N.string().optional(),forkedFromSessionId:N.string().optional(),forkedFromMessageId:N.string().optional(),side:jt.optional(),originatingClient:N.object({name:N.string(),version:N.string().optional()}).optional(),interactive:N.boolean().optional(),priority:N.number().int().nonnegative().optional(),lastTurnEndedAt:N.number().optional(),readAt:N.number().optional(),unread:N.boolean().optional(),createdAt:N.string().optional(),updatedAt:N.string(),attachedClients:N.number().int().nonnegative(),status:N.enum(["warm","cold"]).default("warm"),busy:N.boolean().default(!1),awaitingInput:N.boolean().default(!1),turnStartedAt:N.number().optional(),armedTasks:N.number().int().nonnegative().optional(),armedSince:N.number().int().positive().optional(),compactionState:N.any().optional(),agentPid:N.number().int().positive().optional(),forkSynthesisState:N.enum(["running","failed"]).optional(),_meta:N.record(N.unknown()).optional()}),ep=N.object({sessionId:N.string(),cwd:N.string(),title:N.string().optional(),updatedAt:N.string().optional(),_meta:N.record(N.unknown()).optional()}),iv=N.object({sessions:N.array(ep),nextCursor:N.string().optional()});function os(s,e){let t={attachedClients:s.attachedClients,status:s.status,busy:s.busy,awaitingInput:s.awaitingInput};return s.cwd!==void 0&&(t.cwd=s.cwd),s.workspace!==void 0&&(t.workspaceInfo=s.workspace),s.workspaceError!==void 0&&(t.workspaceError=s.workspaceError),s.title!==void 0&&(t.title=s.title),s.agentId!==void 0&&(t.agentId=s.agentId),s.upstreamSessionId!==void 0&&(t.upstreamSessionId=s.upstreamSessionId),s.createdAt!==void 0&&(t.createdAt=s.createdAt),s.currentModel!==void 0&&(t.currentModel=s.currentModel),s.currentUsage!==void 0&&(t.currentUsage=s.currentUsage),s.importedFromMachine!==void 0&&(t.importedFromMachine=s.importedFromMachine),s.importedFromUpstreamSessionId!==void 0&&(t.importedFromUpstreamSessionId=s.importedFromUpstreamSessionId),s.parentSessionId!==void 0&&(t.parentSessionId=s.parentSessionId),s.forkedFromSessionId!==void 0&&(t.forkedFromSessionId=s.forkedFromSessionId),s.forkedFromMessageId!==void 0&&(t.forkedFromMessageId=s.forkedFromMessageId),s.side!==void 0&&(t.side=s.side),s.originatingClient!==void 0&&(t.originatingClient=s.originatingClient),s.interactive!==void 0&&(t.interactive=s.interactive),s.priority!==void 0&&s.priority>0&&(t.priority=s.priority),s.lastTurnEndedAt!==void 0&&(t.lastTurnEndedAt=s.lastTurnEndedAt),s.readAt!==void 0&&(t.readAt=s.readAt),s.unread&&(t.unread=!0),s.armedTasks!==void 0&&(t.armedTasks=s.armedTasks),s.armedSince!==void 0&&(t.armedSince=s.armedSince),s.compactionState!==void 0&&(t.compactionState=s.compactionState),s.forkSynthesisState!==void 0&&(t.forkSynthesisState=s.forkSynthesisState),e&&(e.clientId!==void 0&&(t.clientId=e.clientId),e.currentMode!==void 0&&(t.currentMode=e.currentMode),e.agentArgs!==void 0&&e.agentArgs.length>0&&(t.agentArgs=e.agentArgs),e.availableCommands!==void 0&&e.availableCommands.length>0&&(t.availableCommands=e.availableCommands),e.availableModes!==void 0&&e.availableModes.length>0&&(t.availableModes=e.availableModes),e.availableModels!==void 0&&e.availableModels.length>0&&(t.availableModels=e.availableModels),e.turnStartedAt!==void 0&&(t.turnStartedAt=e.turnStartedAt),e.agentCapabilities!==void 0&&(t.agentCapabilities=e.agentCapabilities),e.queue!==void 0&&e.queue.length>0&&(t.queue=e.queue),e.resurrected===!0&&(t.resurrected=!0),e.armedTaskList!==void 0&&(t.armedTaskList=e.armedTaskList)),t}function ka(s){let e={sessionId:s.sessionId,cwd:s.cwd,updatedAt:s.updatedAt,_meta:mn(s._meta,os(s))};return s.title!==void 0&&(e.title=s.title),e}var le="hydra-acp";function tp(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e={};for(let[t,n]of Object.entries(s)){if(typeof t!="string"||t.length===0||typeof n!="string")return;e[t]=n}return e}function it(s){if(!s)return{};let e=s[le];if(!e||typeof e!="object"||Array.isArray(e))return{};let t=e,n={};if(typeof t.upstreamSessionId=="string"&&(n.upstreamSessionId=t.upstreamSessionId),typeof t.agentId=="string"&&(n.agentId=t.agentId),typeof t.cwd=="string"&&(n.cwd=t.cwd),t.workspace!==null&&typeof t.workspace=="object"&&!Array.isArray(t.workspace)){let o=t.workspace,i={};typeof o.label=="string"&&(i.label=o.label),typeof o.from=="string"&&(i.from=o.from),o.required===!0&&(i.required=!0),o.adopt===!0&&(i.adopt=!0),typeof o.provider=="string"&&(i.provider=o.provider),n.workspace=i}if(t.workspaceInfo!==null&&typeof t.workspaceInfo=="object"&&!Array.isArray(t.workspaceInfo)){let o=t.workspaceInfo;if(typeof o.path=="string"&&typeof o.sourceCwd=="string"&&typeof o.label=="string"&&typeof o.provider=="string"){let i={path:o.path,sourceCwd:o.sourceCwd,label:o.label,provider:o.provider};if(typeof o.snapshot=="string"&&(i.snapshot=o.snapshot),o.vcs!==null&&typeof o.vcs=="object"&&!Array.isArray(o.vcs)){let a={};for(let[d,c]of Object.entries(o.vcs))typeof c=="string"&&(a[d]=c);i.vcs=a}n.workspaceInfo=i}}if(typeof t.workspaceError=="string"&&(n.workspaceError=t.workspaceError),typeof t.clientId=="string"&&(n.clientId=t.clientId),typeof t.readonly=="boolean"&&(n.readonly=t.readonly),(t.replayMode==="instant"||t.replayMode==="drip")&&(n.replayMode=t.replayMode),typeof t.dripSpeed=="number"&&t.dripSpeed>0&&(n.dripSpeed=t.dripSpeed),typeof t.historyLimit=="number"&&Number.isFinite(t.historyLimit)&&t.historyLimit>=0&&(n.historyLimit=t.historyLimit),(t.toolContent==="inline"||t.toolContent==="references")&&(n.toolContent=t.toolContent),t.detachStatus==="detached"&&(n.detachStatus=t.detachStatus),typeof t.title=="string"&&(n.title=t.title),Array.isArray(t.agentArgs)&&t.agentArgs.every(o=>typeof o=="string")&&(n.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(o=>typeof o=="string")&&(n.transformers=t.transformers),t.resume){let o=ha.safeParse(t.resume);o.success&&(n.resume=o.data)}if(typeof t.model=="string"&&(n.model=t.model),typeof t.currentModel=="string"&&(n.currentModel=t.currentModel),typeof t.currentMode=="string"&&(n.currentMode=t.currentMode),t.currentUsage){let o=Vr.safeParse(t.currentUsage);o.success&&(n.currentUsage=o.data)}if(typeof t.turnStartedAt=="number"&&t.turnStartedAt>0&&(n.turnStartedAt=t.turnStartedAt),typeof t.armedTasks=="number"&&t.armedTasks>=0&&(n.armedTasks=t.armedTasks),typeof t.armedSince=="number"&&t.armedSince>0&&(n.armedSince=t.armedSince),Array.isArray(t.armedTaskList)){let o=[];for(let i of t.armedTaskList){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;typeof a.label!="string"||typeof a.since!="number"||o.push({label:a.label,since:a.since,...typeof a.taskId=="string"?{taskId:a.taskId}:{},...typeof a.taskType=="string"?{taskType:a.taskType}:{},...typeof a.toolCallId=="string"?{toolCallId:a.toolCallId}:{}})}n.armedTaskList=o}if(Array.isArray(t.availableCommands)){let o=[];for(let i of t.availableCommands){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.name!="string")continue;let d={name:a.name};typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableCommands=o)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let o=t.prompt,i={};typeof o.queueing=="boolean"&&(i.queueing=o.queueing),typeof o.cancelling=="boolean"&&(i.cancelling=o.cancelling),typeof o.updating=="boolean"&&(i.updating=o.updating),typeof o.amending=="boolean"&&(i.amending=o.amending),typeof o.pipelining=="boolean"&&(i.pipelining=o.pipelining),n.prompt=i}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let o=t.agents,i={};typeof o.list=="boolean"&&(i.list=o.list),typeof o.installProgress=="boolean"&&(i.installProgress=o.installProgress),n.agents=i}if(typeof t.mcpStdin=="boolean"&&(n.mcpStdin=t.mcpStdin),typeof t.interactive=="boolean"&&(n.interactive=t.interactive),typeof t.ancillary=="boolean"&&(n.ancillary=t.ancillary),t.salvaged&&typeof t.salvaged=="object"&&!Array.isArray(t.salvaged)){let o=t.salvaged;typeof o.reason=="string"&&typeof o.supersededMessageId=="string"&&(n.salvaged={reason:o.reason,supersededMessageId:o.supersededMessageId})}if(Array.isArray(t.queue)){let o=[];for(let i of t.queue){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i,d=a.originator;if(typeof a.messageId!="string"||!d||typeof d.clientId!="string"||!Array.isArray(a.prompt)||typeof a.position!="number"||typeof a.enqueuedAt!="number")continue;let c={clientId:d.clientId};typeof d.name=="string"&&(c.name=d.name),typeof d.version=="string"&&(c.version=d.version),o.push({messageId:a.messageId,originator:c,prompt:a.prompt,position:a.position,enqueuedAt:a.enqueuedAt})}o.length>0&&(n.queue=o)}if(Array.isArray(t.availableModes)){let o=[];for(let i of t.availableModes){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.id!="string")continue;let d={id:a.id};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModes=o)}if(Array.isArray(t.availableModels)){let o=[];for(let i of t.availableModels){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.modelId!="string")continue;let d={modelId:a.modelId};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModels=o)}(t.status==="warm"||t.status==="cold")&&(n.status=t.status),typeof t.busy=="boolean"&&(n.busy=t.busy),typeof t.awaitingInput=="boolean"&&(n.awaitingInput=t.awaitingInput),typeof t.attachedClients=="number"&&(n.attachedClients=t.attachedClients),typeof t.resurrected=="boolean"&&(n.resurrected=t.resurrected),typeof t.importedFromMachine=="string"&&(n.importedFromMachine=t.importedFromMachine),typeof t.importedFromUpstreamSessionId=="string"&&(n.importedFromUpstreamSessionId=t.importedFromUpstreamSessionId),typeof t.parentSessionId=="string"&&(n.parentSessionId=t.parentSessionId),typeof t.forkedFromSessionId=="string"&&(n.forkedFromSessionId=t.forkedFromSessionId),typeof t.forkedFromMessageId=="string"&&(n.forkedFromMessageId=t.forkedFromMessageId);let r=jt.safeParse(t.side);if(r.success&&(n.side=r.data),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let o=t.originatingClient;n.originatingClient={name:o.name,...typeof o.version=="string"?{version:o.version}:{}}}if(t.agentCapabilities!==void 0&&(n.agentCapabilities=t.agentCapabilities),t.env!==void 0){let o=tp(t.env);o!==void 0&&(n.env=o)}return n}function Be(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?s:{...t,_meta:{...n,[le]:{...o,recordedAt:e}}}}function We(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.seq=="number"?s:{...t,_meta:{...n,[le]:{...o,seq:e}}}}function mn(s,e){return{...s??{},[le]:e}}import{z as _}from"zod";var va=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.record(_.unknown()).optional()}),is=_.object({sessionId:_.string()}),ba=_.object({clientId:_.string(),name:_.string().optional(),version:_.string().optional()}),pv=_.object({sessionId:_.string(),messageId:_.string(),originator:ba,prompt:_.array(_.unknown()),position:_.number().int().nonnegative(),queueDepth:_.number().int().positive(),enqueuedAt:_.number()}),gv=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),hv=_.object({sessionId:_.string(),messageId:_.string(),reason:_.enum(["started","cancelled","abandoned"])}),Sa=_.object({sessionId:_.string(),messageId:_.string()}),mv=_.object({cancelled:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Ia=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),yv=_.object({updated:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Aa=_.object({sessionId:_.string(),targetMessageId:_.string(),prompt:_.array(_.unknown()),replaceQueue:_.boolean().optional(),onTargetCompleted:_.enum(["reject","send_anyway"]).optional()}),wv=_.object({amended:_.boolean(),reason:_.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:_.string().optional()}),Ca=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.object({steering:_.object({idleBehavior:_.literal("promptRequired").optional()}).optional()}).optional()}),kv=_.object({outcome:_.enum(["injected","startedNewTurn","promptRequired","failed"]),reason:_.literal("noRunningTurn").optional(),detached:_.boolean().optional()}),vv=_.object({sessionId:_.string(),cancelledMessageId:_.string(),newMessageId:_.string(),prompt:_.array(_.unknown()),originator:ba,amendedAt:_.number()});import{z as at}from"zod";var Iv=at.object({agentId:at.string(),version:at.string(),source:at.enum(["binary","npm"]),phase:at.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:at.number().optional(),totalBytes:at.number().optional(),packageSpec:at.string().optional()}),Ra="hydra-acp/agents/install_progress",Ht={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function xa(s,e){let t="",n=[],r=[],o=!1,i=a=>{if(!o){o=!0;for(let d of r)d(a)}};return s.setEncoding("utf8"),s.on("data",a=>{t+=a;let d=t.indexOf(`
15
15
  `);for(;d!==-1;){let c=t.slice(0,d).trim();if(t=t.slice(d+1),c.length>0)try{let u=JSON.parse(c);for(let l of n)l(u)}catch(u){for(let l of n)l({jsonrpc:"2.0",id:null,error:{code:x.ParseError,message:`Failed to parse ndjson line: ${u.message}`}})}d=t.indexOf(`
16
16
  `)}}),s.on("end",()=>i()),s.on("error",a=>i(a)),e.on("error",a=>i(a)),{async send(a){if(o)throw new Error("stream is closed");let d=JSON.stringify(a)+`
17
17
  `;await new Promise((c,u)=>{e.write(d,l=>{if(l){u(l);return}c()})})},onMessage(a){n.push(a)},onClose(a){r.push(a)},async close(){e.end(),i()}}}import{nanoid as np}from"nanoid";var Gr=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},qe=class s{constructor(e){this.stream=e;this.stream.onMessage(t=>this.handleIncoming(t)),this.stream.onClose(t=>this.handleClose(t))}stream;requestHandlers=new Map;defaultRequestHandler;notificationHandlers=new Map;paramsRewriter;anyNotificationHandlers=[];bufferedNotifications=new Map;static MAX_BUFFERED_PER_METHOD=64;static MAX_BUFFERED_METHODS=256;pending=new Map;closed=!1;closeHandlers=[];orphanErrorHandlers=[];onRequest(e,t){this.requestHandlers.set(e,t)}setDefaultHandler(e){this.defaultRequestHandler=e}setParamsRewriter(e){this.paramsRewriter=e}onNotification(e,t){this.notificationHandlers.set(e,t);let n=this.bufferedNotifications.get(e);if(n){this.bufferedNotifications.delete(e);for(let r of n)try{t(r.params,r.method)}catch{}}}drainBuffered(e){let n=this.bufferedNotifications.get(e)?.length??0;return this.bufferedNotifications.delete(e),n}dropBufferedWhere(e,t){let n=this.bufferedNotifications.get(e);if(!n)return 0;let r=n.filter(o=>!t(o.params));return r.length>0?this.bufferedNotifications.set(e,r):this.bufferedNotifications.delete(e),n.length-r.length}onAnyNotification(e){this.anyNotificationHandlers.push(e)}onClose(e){this.closeHandlers.push(e)}isClosed(){return this.closed}onOrphanError(e){this.orphanErrorHandlers.push(e)}async request(e,t){return this.requestWithId(e,t).response}requestWithId(e,t){if(this.closed)throw new Gr;let n=np(),r={jsonrpc:"2.0",id:n,method:e,params:t},o=new Promise((i,a)=>{this.pending.set(n,{resolve:d=>i(d),reject:a}),this.stream.send(r).catch(d=>{this.pending.delete(n),a(d)})});return{id:n,response:o}}notify(e,t){if(this.closed)return Promise.resolve();let n={jsonrpc:"2.0",method:e,params:t};return this.stream.send(n)}async close(){this.closed||await this.stream.close()}fail(e){this.handleClose(e)}handleIncoming(e){"method"in e?(this.paramsRewriter&&(e={...e,params:this.paramsRewriter(e.params,e.method)}),"id"in e&&e.id!==void 0?this.handleRequest(e).catch(()=>{}):this.handleNotification(e)):"id"in e?this.handleResponse(e):"error"in e&&this.handleResponse(e)}async handleRequest(e){let t=this.requestHandlers.get(e.method)??this.defaultRequestHandler;if(!t){await this.sendError(e.id,{code:x.MethodNotFound,message:`Method not found: ${e.method}`}).catch(()=>{});return}try{let n=await t(e.params,e.method),r={jsonrpc:"2.0",id:e.id,result:n};await this.stream.send(r).catch(()=>{})}catch(n){let r=n;await this.sendError(e.id,{code:r.code??x.InternalError,message:r.message,data:r.data}).catch(()=>{})}}handleNotification(e){for(let r of this.anyNotificationHandlers)try{r(e.params,e.method)}catch{}let t=this.notificationHandlers.get(e.method);if(t){t(e.params,e.method);return}let n=this.bufferedNotifications.get(e.method);if(!n){if(this.bufferedNotifications.size>=s.MAX_BUFFERED_METHODS){let r=this.bufferedNotifications.keys().next().value;r!==void 0&&this.bufferedNotifications.delete(r)}n=[],this.bufferedNotifications.set(e.method,n)}n.push(e),n.length>s.MAX_BUFFERED_PER_METHOD&&n.shift()}handleResponse(e){let t=e.id===null?void 0:this.pending.get(e.id);if(!t){if(e.error)for(let n of this.orphanErrorHandlers)try{n({code:e.error.code,message:e.error.message,data:e.error.data})}catch{}return}if(this.pending.delete(e.id),e.error){let n=new Error(e.error.message);n.code=e.error.code,n.data=e.error.data,t.reject(n)}else t.resolve(e.result)}async sendError(e,t){let n={jsonrpc:"2.0",id:e,error:t};await this.stream.send(n)}handleClose(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e??new Error("connection closed"));this.pending.clear();for(let t of this.closeHandlers)t(e)}}};K();var op=4096,dt=class s{agentId;version;installId;cwd;connection;authMethods;steeringSupported;child;get pid(){return this.child.pid}exited=!1;killed=!1;stderrTail="";stderrTailBytes;killEscalationMs;logger;fileLog;exitHandlers=[];constructor(e,t){if(this.agentId=e.agentId,this.version=e.plan.version,this.installId=e.plan.installId??e.agentId,this.cwd=e.cwd,this.child=t,this.stderrTailBytes=e.stderrTailBytes??op,this.killEscalationMs=e.killEscalationMs??ip,this.logger=e.logger,this.fileLog=ap(e.agentId),this.writeLog(`--- spawn pid=${t.pid} version=${e.plan.version} cwd=${e.cwd} cmd=${e.plan.command} args=${JSON.stringify(e.plan.args)} time=${new Date().toISOString()} ---
@@ -20,15 +20,15 @@ stderr: ${l}`:`npm install ${s.packageSpec} failed (${u})`))})})}catch(t){if(t.c
20
20
  `),this.fileLog?.end(),this.fileLog=void 0,this.killed)this.logger?.info(`agent ${e.agentId} pid=${t.pid} exited after kill code=${r} signal=${o}`);else{let i=`agent ${e.agentId} exited before responding (code=${r} signal=${o})`;this.connection.fail(new Error(this.formatFailure(i))),this.logger?.warn(`agent ${e.agentId} pid=${t.pid} exited unexpectedly code=${r} signal=${o}`)}for(let i of this.exitHandlers)i(r,o)})}writeLog(e){if(this.fileLog)try{this.fileLog.write(e)}catch{}}formatFailure(e){let t=this.stderrTail.trim();return t?`${e}
21
21
  stderr: ${t}`:e}stderrTailText(){return this.stderrTail.trim()}static spawn(e){let t={...es(),...e.plan.env,...e.extraEnv??{}},n=Ft(e.plan.command,e.plan.args),r=sp(n.command,n.args,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],shell:n.shell,windowsHide:!0,detached:!0});return r.unref(),new s(e,r)}onExit(e){this.exitHandlers.push(e)}isAlive(){return!this.exited}async kill(e="SIGTERM"){this.exited||(this.killed=!0,this.writeLog(`--- kill requested signal=${e} time=${new Date().toISOString()} ---
22
22
  `),this.logger?.info(`agent ${this.agentId} pid=${this.child.pid} kill requested signal=${e}`),await this.connection.close().catch(()=>{}),this.signalProcessGroup(e),await this.waitForExit(this.killEscalationMs),!this.exited&&(this.writeLog(`--- kill escalating signal=SIGKILL time=${new Date().toISOString()} ---
23
- `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(Ea),this.exited||this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} still has not exited ${Ea}ms after SIGKILL; giving up on the reap`)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0){if(process.platform==="win32"){try{rp("taskkill",["/pid",String(t),"/T","/F"],{stdio:"ignore",windowsHide:!0})}catch{try{this.child.kill()}catch{}}return}try{process.kill(-t,e)}catch{try{this.child.kill(e)}catch{}}}}waitForExit(e){return this.exited?Promise.resolve():new Promise(t=>{let n=setTimeout(()=>{this.child.off("exit",r),t()},e),r=()=>{clearTimeout(n),t()};this.child.once("exit",r)})}},ip=2e3,Ea=5e3;function ap(s){try{let e=E.agentLogFile(s);as.mkdirSync(Ta.dirname(e),{recursive:!0});let t=as.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}function ds(s){if(s.length===0)return s;let e=new Map,t=new Map,n=new Map;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=Kr(d);if(c?.sessionUpdate!=="tool_call_update")continue;let u=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(u!==void 0){e.set(u,a);for(let l of fp){if(!Pa(c[l]))continue;let p=n.get(u);p===void 0?n.set(u,new Map([[l,c[l]]])):p.set(l,c[l])}Array.isArray(c.content)&&c.content.length>0&&t.set(u,c.content)}}let r=[],o=null,i=null;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=Kr(d);if(!c||typeof c.sessionUpdate!="string"){r.push(d),o=null;continue}let u=c.sessionUpdate;if(u==="agent_message_chunk"||u==="agent_thought_chunk"||u==="user_message_chunk"){o&&o.kind===u?(up(r,o.outIndex,dp(c.content)),cp(r,o.outIndex,d.seq)):(r.push(d),o={outIndex:r.length-1,kind:u});continue}if(o=null,u==="tool_call_update"){let l=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(l!==void 0&&e.get(l)!==a)continue;let p=l!==void 0&&t.has(l)?lp(d,t.get(l)??[]):d,f=l===void 0?void 0:n.get(l);if(f!==void 0)for(let[h,w]of f)Pa(Kr(p)?.[h])||(p=pp(p,h,w));r.push(p);continue}if(u==="plan"){i!==null?r[i]=d:(r.push(d),i=r.length-1);continue}(u==="prompt_received"||u==="turn_complete")&&(i=null),r.push(d)}return r}function Kr(s){if(s.method!=="session/update")return;let t=s.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function dp(s){if(!s||typeof s!="object")return"";let e=s;return typeof e.text=="string"?e.text:""}function cp(s,e,t){let n=s[e];n===void 0||typeof t!="number"||n.seq!==void 0&&n.seq>=t||(s[e]={...n,seq:t})}function up(s,e,t){if(t.length===0)return;let n=s[e];if(n===void 0)return;let r=n.params??{},o=r.update??{},i=o.content??{},a=typeof i.text=="string"?i.text:"";s[e]={...n,params:{...r,update:{...o,content:{...i,text:a+t}}}}}function lp(s,e){let t=s.params??{},n=t.update??{};return{...s,params:{...t,update:{...n,content:e}}}}var fp=["rawInput","locations"];function Pa(s){return s==null||typeof s!="object"?!1:Array.isArray(s)?s.length>0:Object.keys(s).length>0}function pp(s,e,t){let n=s.params??{},r=n.update??{};return{...s,params:{...n,update:{...r,[e]:t}}}}function Lt(s,e){let t=e?.contextThroughSeq;return t===void 0?[...s]:s.filter(n=>n.seq===void 0||n.seq>t)}function Ma(s){let e;for(let t of s)t.seq!==void 0&&(e===void 0||t.seq>e)&&(e=t.seq);return e===void 0?{}:{contextThroughSeq:e}}import*as Rt from"fs/promises";import*as Ec from"os";import*as _a from"os";function vt(){return _a.hostname()}import*as Hn from"path";import{customAlphabet as hm}from"nanoid";var ze="session/set_model",Yr="session/set_config_option",Fa="model";function Qr(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.availableModels)}function Na(s){return Array.isArray(s)&&s.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===Fa)}function Ut(s){if(!s)return;if(Qr(s)||Qr(s.models))return ze;let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,n]of Object.entries(e))if(t!=="hydra-acp"&&Qr(n))return ze}if(Na(s.configOptions))return Yr}function Da(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.sessionUpdate;if(e==="_hydra_current_model_update")return ze;if(e==="config_option_update"&&Na(s.configOptions))return Yr}function $a(s){return typeof s=="object"&&s!==null&&s.code===x.MethodNotFound}function Oa(s,e,t,n){let r={...n??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,s===ze?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:Fa,value:t}}function gp(s){return s===ze?Yr:ze}async function ct(s){let{request:e,sessionId:t,modelId:n,extraParams:r,logger:o}=s,i=s.verb??ze;try{let a=await e(i,Oa(i,t,n,r));return{verb:i,result:a}}catch(a){if(!$a(a))throw a;let d=gp(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(n)}`);try{let c=await e(d,Oa(d,t,n,r));return{verb:d,result:c}}catch(c){throw $a(c)?a:c}}}async function ut(s){let{agent:e,upstreamSessionId:t,persistedMode:n,agentReportedMode:r,advertisedModes:o,logger:i}=s;if(!n)return r;if(n===r)return n;if(o&&o.length>0&&!o.some(a=>a.id===n)){let a=o.map(d=>d.id).join(", ");return i?.warn(`resurrect: persisted currentMode=${JSON.stringify(n)} not in agent's availableModes ([${a}]); skipping session/set_mode, session will use ${JSON.stringify(r)}`),r}try{return i?.info(`resurrect: pushing persisted modeId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`),await e.connection.request("session/set_mode",{sessionId:t,modeId:n}),i?.info(`resurrect: session/set_mode accepted, effectiveMode=${JSON.stringify(n)}`),n}catch(a){return i?.warn(`resurrect: session/set_mode rejected by agent for modeId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),r}}async function lt(s){let{agent:e,upstreamSessionId:t,persistedModel:n,agentReportedModel:r,modelVerb:o,logger:i}=s;if(!n)return{modelId:r};if(n===r)return{modelId:n};try{i?.info(`resurrect: pushing persisted modelId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`);let{verb:a,result:d}=await ct({request:(c,u)=>e.connection.request(c,u),sessionId:t,modelId:n,...o?{verb:o}:{},logger:i});return i?.info(`resurrect: ${a} accepted, effectiveModel=${JSON.stringify(n)}`),{modelId:n,result:d}}catch(a){return i?.warn(`resurrect: session/set_model rejected by agent for modelId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),{modelId:r}}}var Ha="edit",cs=class{kinds=new Map;note(e,t){t!==void 0&&t.length>0&&!this.kinds.has(e)&&this.kinds.set(e,t)}get(e){return this.kinds.get(e)}effective(e,t){return t!==void 0&&t.length>0?t:this.kinds.get(e)}clear(){this.kinds.clear()}get size(){return this.kinds.size}};function ja(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(t===null||typeof t!="object")continue;let n=t.path;typeof n=="string"&&n.length>0&&e.push(n)}return e}function Xr(s){let e=[],t=[],n=!1;for(let r of s.split(`
23
+ `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(Ea),this.exited||this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} still has not exited ${Ea}ms after SIGKILL; giving up on the reap`)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0){if(process.platform==="win32"){try{rp("taskkill",["/pid",String(t),"/T","/F"],{stdio:"ignore",windowsHide:!0})}catch{try{this.child.kill()}catch{}}return}try{process.kill(-t,e)}catch{try{this.child.kill(e)}catch{}}}}waitForExit(e){return this.exited?Promise.resolve():new Promise(t=>{let n=setTimeout(()=>{this.child.off("exit",r),t()},e),r=()=>{clearTimeout(n),t()};this.child.once("exit",r)})}},ip=2e3,Ea=5e3;function ap(s){try{let e=E.agentLogFile(s);as.mkdirSync(Ta.dirname(e),{recursive:!0});let t=as.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}function ds(s){if(s.length===0)return s;let e=new Map,t=new Map,n=new Map;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=Kr(d);if(c?.sessionUpdate!=="tool_call_update")continue;let u=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(u!==void 0){e.set(u,a);for(let l of fp){if(!Pa(c[l]))continue;let p=n.get(u);p===void 0?n.set(u,new Map([[l,c[l]]])):p.set(l,c[l])}Array.isArray(c.content)&&c.content.length>0&&t.set(u,c.content)}}let r=[],o=null,i=null;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=Kr(d);if(!c||typeof c.sessionUpdate!="string"){r.push(d),o=null;continue}let u=c.sessionUpdate;if(u==="agent_message_chunk"||u==="agent_thought_chunk"||u==="user_message_chunk"){o&&o.kind===u?(up(r,o.outIndex,dp(c.content)),cp(r,o.outIndex,d.seq)):(r.push(d),o={outIndex:r.length-1,kind:u});continue}if(o=null,u==="tool_call_update"){let l=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(l!==void 0&&e.get(l)!==a)continue;let p=l!==void 0&&t.has(l)?lp(d,t.get(l)??[]):d,f=l===void 0?void 0:n.get(l);if(f!==void 0)for(let[h,w]of f)Pa(Kr(p)?.[h])||(p=pp(p,h,w));r.push(p);continue}if(u==="plan"){i!==null?r[i]=d:(r.push(d),i=r.length-1);continue}(u==="prompt_received"||u==="turn_complete")&&(i=null),r.push(d)}return r}function Kr(s){if(s.method!=="session/update")return;let t=s.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function dp(s){if(!s||typeof s!="object")return"";let e=s;return typeof e.text=="string"?e.text:""}function cp(s,e,t){let n=s[e];n===void 0||typeof t!="number"||n.seq!==void 0&&n.seq>=t||(s[e]={...n,seq:t})}function up(s,e,t){if(t.length===0)return;let n=s[e];if(n===void 0)return;let r=n.params??{},o=r.update??{},i=o.content??{},a=typeof i.text=="string"?i.text:"";s[e]={...n,params:{...r,update:{...o,content:{...i,text:a+t}}}}}function lp(s,e){let t=s.params??{},n=t.update??{};return{...s,params:{...t,update:{...n,content:e}}}}var fp=["rawInput","locations"];function Pa(s){return s==null||typeof s!="object"?!1:Array.isArray(s)?s.length>0:Object.keys(s).length>0}function pp(s,e,t){let n=s.params??{},r=n.update??{};return{...s,params:{...n,update:{...r,[e]:t}}}}function Lt(s,e){let t=e?.contextThroughSeq;return t===void 0?[...s]:s.filter(n=>n.seq===void 0||n.seq>t)}function Ma(s){let e;for(let t of s)t.seq!==void 0&&(e===void 0||t.seq>e)&&(e=t.seq);return e===void 0?{}:{contextThroughSeq:e}}import*as Rt from"fs/promises";import*as Ec from"os";import*as _a from"os";function vt(){return _a.hostname()}import*as jn from"path";import{customAlphabet as mm}from"nanoid";var ze="session/set_model",Yr="session/set_config_option",Fa="model";function Qr(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.availableModels)}function Na(s){return Array.isArray(s)&&s.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===Fa)}function Ut(s){if(!s)return;if(Qr(s)||Qr(s.models))return ze;let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,n]of Object.entries(e))if(t!=="hydra-acp"&&Qr(n))return ze}if(Na(s.configOptions))return Yr}function Da(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.sessionUpdate;if(e==="_hydra_current_model_update")return ze;if(e==="config_option_update"&&Na(s.configOptions))return Yr}function $a(s){return typeof s=="object"&&s!==null&&s.code===x.MethodNotFound}function Oa(s,e,t,n){let r={...n??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,s===ze?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:Fa,value:t}}function gp(s){return s===ze?Yr:ze}async function ct(s){let{request:e,sessionId:t,modelId:n,extraParams:r,logger:o}=s,i=s.verb??ze;try{let a=await e(i,Oa(i,t,n,r));return{verb:i,result:a}}catch(a){if(!$a(a))throw a;let d=gp(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(n)}`);try{let c=await e(d,Oa(d,t,n,r));return{verb:d,result:c}}catch(c){throw $a(c)?a:c}}}async function ut(s){let{agent:e,upstreamSessionId:t,persistedMode:n,agentReportedMode:r,advertisedModes:o,logger:i}=s;if(!n)return r;if(n===r)return n;if(o&&o.length>0&&!o.some(a=>a.id===n)){let a=o.map(d=>d.id).join(", ");return i?.warn(`resurrect: persisted currentMode=${JSON.stringify(n)} not in agent's availableModes ([${a}]); skipping session/set_mode, session will use ${JSON.stringify(r)}`),r}try{return i?.info(`resurrect: pushing persisted modeId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`),await e.connection.request("session/set_mode",{sessionId:t,modeId:n}),i?.info(`resurrect: session/set_mode accepted, effectiveMode=${JSON.stringify(n)}`),n}catch(a){return i?.warn(`resurrect: session/set_mode rejected by agent for modeId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),r}}async function lt(s){let{agent:e,upstreamSessionId:t,persistedModel:n,agentReportedModel:r,modelVerb:o,logger:i}=s;if(!n)return{modelId:r};if(n===r)return{modelId:n};try{i?.info(`resurrect: pushing persisted modelId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`);let{verb:a,result:d}=await ct({request:(c,u)=>e.connection.request(c,u),sessionId:t,modelId:n,...o?{verb:o}:{},logger:i});return i?.info(`resurrect: ${a} accepted, effectiveModel=${JSON.stringify(n)}`),{modelId:n,result:d}}catch(a){return i?.warn(`resurrect: session/set_model rejected by agent for modelId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),{modelId:r}}}var ja="edit",cs=class{kinds=new Map;note(e,t){t!==void 0&&t.length>0&&!this.kinds.has(e)&&this.kinds.set(e,t)}get(e){return this.kinds.get(e)}effective(e,t){return t!==void 0&&t.length>0?t:this.kinds.get(e)}clear(){this.kinds.clear()}get size(){return this.kinds.size}};function Ha(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(t===null||typeof t!="object")continue;let n=t.path;typeof n=="string"&&n.length>0&&e.push(n)}return e}function Xr(s){let e=[],t=[],n=!1;for(let r of s.split(`
24
24
  `)){if(r.startsWith("@@")){n=!0;continue}if(!n||r.startsWith("\\"))continue;let o=r.slice(1);r.startsWith("-")?e.push(o):r.startsWith("+")?t.push(o):r.startsWith(" ")&&(e.push(o),t.push(o))}return{oldText:e.length>0?e.join(`
25
25
  `)+`
26
26
  `:"",newText:t.length>0?t.join(`
27
27
  `)+`
28
- `:""}}function La(s){if(s===null||typeof s!="object")return[];let e=s.rawOutput;if(e===null||typeof e!="object")return[];let t=e.metadata;if(t===null||typeof t!="object")return[];let n=t.files;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(o===null||typeof o!="object")continue;let i=o;if(typeof i.filePath!="string"||i.filePath.length===0)continue;let a=i.patch,d=a!==null&&typeof a=="object"?a:void 0;r.push({path:i.filePath,...typeof i.additions=="number"?{added:i.additions}:{},...typeof i.deletions=="number"?{removed:i.deletions}:{},...typeof a=="string"?{patch:a}:{},...typeof d?.__hydraBlob=="string"?{patchRef:{hash:d.__hydraBlob,bytes:typeof d.bytes=="number"?d.bytes:0}}:{}})}return r}function bt(s){if(typeof s=="string")return{text:s};if(s&&typeof s=="object"&&!Array.isArray(s)){let e=s;if(typeof e.__hydraBlob=="string")return{ref:{hash:e.__hydraBlob,bytes:typeof e.bytes=="number"?e.bytes:0}}}}function Zr(s){let e=s.rawInput;return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function eo(s){return typeof s.file_path=="string"?s.file_path:typeof s.path=="string"?s.path:void 0}function us(s){let e=s.content;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(r.type!=="diff")continue;let o=bt(r.oldText),i=bt(r.newText);o===void 0&&i===void 0||t.push({...typeof r.path=="string"?{path:r.path}:{},...o?{old:o}:{},...i?{new:i}:{}})}return t}function ls(s){let e=Zr(s);if(!e)return;let t=eo(e);if(e.old_string!==void 0||e.new_string!==void 0){let n=bt(e.old_string),r=bt(e.new_string);return{...t!==void 0?{path:t}:{},...n?{old:n}:{},...r?{new:r}:{}}}if(e.content!==void 0){let n=bt(e.content);return{...t!==void 0?{path:t}:{},old:{text:""},...n?{new:n}:{}}}}function hp(s){let e=Zr(s),t=e?eo(e):void 0;if(!e||t===void 0||!Array.isArray(e.edits))return[];let n=[];for(let r of e.edits){if(!r||typeof r!="object")continue;let o=r,i=bt(o.old_string),a=bt(o.new_string);i===void 0||a===void 0||n.push({path:t,old:i,new:a})}return n}function Ua(s){return La(s).map(e=>({path:e.path,...e.patch!==void 0?{patch:{text:e.patch}}:{},...e.patchRef!==void 0?{patch:{ref:e.patchRef}}:{}}))}function fs(s){let e=hp(s);if(e.length>0)return e;let t=us(s).filter(r=>r.path!==void 0);if(t.length>0)return t;let n=ls(s);return n?.path!==void 0?[n]:Ua(s)}function Ba(s){let e=new Set,t=Zr(s),n=[...us(s).map(r=>r.path),ls(s)?.path,t&&Array.isArray(t.edits)?eo(t):void 0,...Ua(s).map(r=>r.path)];for(let r of n)typeof r=="string"&&r.length>0&&e.add(r);return[...e]}function Wa(s){return s.patch!==void 0?s.patch.text!==void 0?Xr(s.patch.text):{oldText:"",newText:""}:{oldText:s.old?.text??"",newText:s.new?.text??""}}K();import{posix as mp}from"path";import yp from"strip-ansi";function yn(s){if(!s||typeof s!="object")return;let e=s;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}function to(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.parentToolUseId;return typeof n=="string"?n:void 0}var wp=/[\x00-\x08\x0b-\x1f\x7f]/g;function ve(s){return yp(s).replace(wp,"")}function ie(s){return ve(s).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function Va(s,e={}){if(!s||typeof s!="object")return null;let t=s,n=t.sessionUpdate??t.kind;if(typeof n!="string")return null;switch(n){case"agent_message_chunk":return Cp(t);case"agent_thought_chunk":case"agent_thought":return Rp(t);case"user_message_chunk":return xp(t);case"prompt_received":return Ep(t);case"tool_call":return Tp(t,e);case"tool_call_update":return Op(t,e);case"plan":return Hp(t);case"current_mode_update":return jp(t);case"_hydra_current_model_update":return Lp(t);case"turn_complete":return Up(t);case"_hydra_turn_started":return Ja(t,"turn-started");case"_hydra_turn_ended":return Ja(t,"turn-ended");case"usage_update":return Ap(t);case"available_commands_update":return Sp(t);case"_hydra_available_modes_update":return Ip(t);case"session_info_update":return vp(t);case"config_option_update":return kp(t);default:return{kind:"unknown",sessionUpdate:n,raw:s}}}function kp(s){let e=s.configOptions;if(!Array.isArray(e))return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.id!="string"||typeof r.currentValue!="string"||!Array.isArray(r.options))continue;let o=[];for(let i of r.options){if(!i||typeof i!="object")continue;let a=i;typeof a.value=="string"&&o.push({value:a.value,name:typeof a.name=="string"?a.name:a.value,...typeof a.description=="string"?{description:a.description}:{}})}t.push({id:r.id,name:typeof r.name=="string"?r.name:r.id,type:"select",currentValue:r.currentValue,options:o,...typeof r.category=="string"?{category:r.category}:{}})}return{kind:"config-options",options:t}}function vp(s){let e=se(s,"title"),t=e!==void 0?ie(e):void 0,n=s._meta,r,o;if(n&&typeof n=="object"&&!Array.isArray(n)){let a=n["hydra-acp"];if(a&&typeof a=="object"&&!Array.isArray(a)){let d=a.agentId;if(typeof d=="string"&&(r=d),"pendingAgentSwap"in a){let c=a.pendingAgentSwap;typeof c=="string"?o=c:c===null&&(o=null)}}}if(t===void 0&&r===void 0&&o===void 0)return null;let i={kind:"session-info"};return t!==void 0&&(i.title=t),r!==void 0&&(i.agentId=r),o!==void 0&&(i.pendingAgentSwap=o),i}function bp(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object")continue;let n=t;if(typeof n.name!="string"||n.name.length===0)continue;let r=n.name.startsWith("/")?n.name:`/${n.name}`,o={name:ie(r)};typeof n.description=="string"&&(o.description=ie(n.description)),e.push(o)}return e}function Sp(s){let e=s.availableCommands??s.commands;return Array.isArray(e)?{kind:"available-commands",commands:bp(e)}:null}function Ip(s){let e=s.availableModes;if(!Array.isArray(e))return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.id!="string"||r.id.length===0)continue;let o={id:ie(r.id)};typeof r.name=="string"&&(o.name=ie(r.name)),typeof r.description=="string"&&(o.description=ie(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function Ap(s){let e={kind:"usage-update"};if(typeof s.used=="number"&&(e.used=s.used),typeof s.size=="number"&&(e.size=s.size),s.cost&&typeof s.cost=="object"){let t=s.cost;typeof t.amount=="number"&&(e.costAmount=t.amount),typeof t.currency=="string"&&(e.costCurrency=t.currency)}return e}function Cp(s){let e=wn(s.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:yn(s)}}function Rp(s){let e=typeof s.text=="string"?ve(s.text):wn(s.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:yn(s)}}function xp(s){let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){let n=e["hydra-acp"];if(n&&typeof n=="object"&&!Array.isArray(n)&&n.compatFor==="prompt_received")return null}let t=wn(s.content);return t===null?null:{kind:"user-text",text:t}}function Ep(s){let e=Bp(s.prompt);return e===null?null:{kind:"user-text",text:e}}function Ga(s){return s?s.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function Ka(s){let e=us(s)[0];if(e)return qa(e);let t=ls(s);return t?.old?.text!==void 0&&t.new?.text!==void 0?qa(t):null}function qa(s){return{...s.path!==void 0?{path:s.path}:{},oldText:s.old?.text??"",newText:s.new?.text??"",...s.old?.ref?{oldRef:s.old.ref}:{},...s.new?.ref?{newRef:s.new.ref}:{}}}function Qa(s){let e=s.rawInput;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e.plan;return typeof t!="string"||t.length===0?null:ve(t)}function Tp(s,e={}){let t=se(s,"toolCallId")??se(s,"id");if(!t)return null;let n=se(s,"title")??se(s,"name")??se(s,"label")??"tool call",r=se(s,"name")??se(s,"title");if(Ga(r)){let w=Qa(s);if(w!==null){let m=se(s,"status"),g={kind:"exit-plan-mode",toolCallId:t,plan:w};return m!==void 0&&(g.status=m),g}}let o=Za(ie(n),s,e),i=se(s,"status"),a=se(s,"kind"),d={kind:"tool-call",toolCallId:t,title:o};i!==void 0&&(d.status=i),a!==void 0&&(d.rawKind=a);let c=Ka(s);c!==null&&(d.editDiff=c);let u=Xa(s);u!==void 0&&(d.detail=u);let l=no(s);l!==void 0&&(d.detailFull=l);let p=Ya(s);p!==void 0&&(d.locations=p);let f=yn(s);f!==void 0&&(d.workerTaskId=f);let h=to(s);return h!==void 0&&(d.parentToolUseId=h),d}function Ya(s){let e=s.locations;if(!Array.isArray(e))return;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.path!="string"||r.path.length===0)continue;let o={path:r.path};typeof r.line=="number"&&Number.isFinite(r.line)&&r.line>=1&&(o.line=Math.floor(r.line)),t.push(o)}return t.length>0?t:void 0}var za=64;function Xa(s){let e=no(s);if(e===void 0)return;let t=ie(e),n=s.rawInput;return n&&typeof n.command=="string"?_p(t,za):$p(t,za)}function no(s){let e=s.rawInput;if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.command=="string"&&t.command.trim().length>0)return ve(t.command).trim().replace(/^cd\s+\S+\s+&&\s+/,"");let n=typeof t.file_path=="string"?t.file_path:typeof t.filePath=="string"?t.filePath:typeof t.path=="string"?t.path:void 0;if(n!==void 0&&n.length>0)return $(ie(n))}if(Array.isArray(s.locations)){for(let t of s.locations)if(t&&typeof t=="object"){let n=t.path;if(typeof n=="string"&&n.length>0)return $(ie(n))}}}var Pp=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function Mp(s){for(let e of Pp)if(s.startsWith(e))return!0;return!1}function Za(s,e,t={}){if(s.length===0)return s;if(s.startsWith("/"))return $(s);if(s.startsWith("~")||!s.includes("/")||/\s/.test(s))return s;let n=e.rawInput;if(n&&typeof n=="object"&&!Array.isArray(n)){let r=n,o=[r.file_path,r.filePath,r.path];for(let i of o)if(!(typeof i!="string"||i.length===0)&&(i===`/${s}`||i.endsWith(`/${s}`)||i===s))return $(i)}return Mp(s)?$(`/${s}`):t.cwd&&t.cwd.length>0?$(mp.resolve(t.cwd,s)):s}function _p(s,e){return s.length>e?`${s.slice(0,e-1)}\u2026`:s}function $p(s,e){if(s.length<=e)return s;let t=s.slice(-(e-1)),n=t.indexOf("/");return n>=0&&n<e/2?`\u2026${t.slice(n)}`:`\u2026${t}`}function Op(s,e={}){let t=se(s,"toolCallId")??se(s,"id");if(!t)return null;let n=se(s,"title"),r=n!==void 0?Za(ie(n),s,e):void 0,o=se(s,"status"),i=Ka(s),a=Xa(s),d=Fp(s);if(!(r!==void 0||i!==null||a!==void 0||d!==void 0||o==="completed"||o==="failed"||o==="rejected"||o==="cancelled"))return null;let u=se(s,"name")??n;if(Ga(u)){let m={kind:"exit-plan-mode",toolCallId:t},g=Qa(s);return g!==null&&(m.plan=g),o!==void 0&&(m.status=o),m}let l={kind:"tool-call-update",toolCallId:t};r!==void 0&&(l.title=r),a!==void 0&&(l.detail=a);let p=no(s);p!==void 0&&(l.detailFull=p);let f=Ya(s);if(f!==void 0&&(l.locations=f),d!==void 0&&(l.resultSummary=d),o!==void 0&&(l.status=o),i!==null&&(l.editDiff=i),o==="failed"){let m=Np(s);m!==null&&(l.errorText=m),Dp(s,m)&&(l.upstreamInterrupted=!0)}let h=yn(s);h!==void 0&&(l.workerTaskId=h);let w=to(s);return w!==void 0&&(l.parentToolUseId=w),l}function Fp(s){if(!s||typeof s!="object")return;let e=s.rawOutput;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=u=>{let l=t[u];return typeof l=="number"&&Number.isFinite(l)?l:void 0},r=(u,l,p=`${l}s`)=>`${u} ${u===1?l:p}`,o=[],i=n("totalMatches");i!==void 0&&o.push(r(i,"match","matches"));let a=n("totalFiles");a!==void 0&&o.push(r(a,"file"));let d=n("referenceCount");d!==void 0&&o.push(r(d,"reference")),o.length>0&&t.truncated===!0&&o.push("truncated");let c=n("exitCode");return c!==void 0&&c!==0&&o.push(`exit ${c}`),o.length>0?o.join(", "):void 0}function Np(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=wn(n.content);if(o!==null&&o.length>0)return o}let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.error;if(typeof n=="string"&&n.length>0)return ve(n)}return null}function Dp(s,e){let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.metadata;if(n&&typeof n=="object"&&n.interrupted===!0)return!0}return!!(e!==null&&e.toLowerCase().includes("tool execution aborted"))}function Hp(s){let e=s.entries;if(!Array.isArray(e)||e.length===0)return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n,o=typeof r.content=="string"?ie(r.content):void 0;if(!o)continue;let i={content:o};typeof r.status=="string"&&(i.status=r.status),typeof r.priority=="string"&&(i.priority=r.priority),t.push(i)}return{kind:"plan",entries:t}}function jp(s){let e=se(s,"currentModeId")??se(s,"currentMode")??se(s,"mode");return e?{kind:"mode-changed",mode:ie(e)}:null}function Lp(s){let e=se(s,"currentModel")??se(s,"model");if(!e)return null;let t=s.availableModels,n=Array.isArray(t)?t.map(r=>typeof r=="object"&&r!==null?r.modelId:typeof r=="string"?r:void 0).filter(r=>typeof r=="string"&&r.length>0):void 0;return{kind:"model-changed",model:ie(e),...n&&n.length>0?{availableModels:n}:{}}}function Up(s){let e=se(s,"stopReason"),t=s._meta,n=t?.["hydra-acp"]?.amended!==void 0&&t["hydra-acp"].amended!==null,r={kind:"turn-complete"};return e!==void 0&&(r.stopReason=e),n&&(r.amended=!0),r}function Ja(s,e){let n=s._meta?.["hydra-acp"],r=n?.unsolicited===!0;if(e==="turn-started"){let i=n?.cause?.label,a={kind:e,unsolicited:r};return typeof i=="string"&&i.length>0&&(a.cause=i),a}let o={kind:e,unsolicited:r};return typeof n?.reason=="string"&&(o.reason=n.reason),o}function wn(s){if(typeof s=="string")return ve(s);if(!s||typeof s!="object")return null;let e=s;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?ve(e.text):null}function Bp(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){let n=wn(t);n!==null&&e.push(n)}return e.length===0?null:e.join("")}function se(s,e){let t=s[e];return typeof t=="string"?t:void 0}function Wp(s,e){let t=ve(s).split(`
28
+ `:""}}function La(s){if(s===null||typeof s!="object")return[];let e=s.rawOutput;if(e===null||typeof e!="object")return[];let t=e.metadata;if(t===null||typeof t!="object")return[];let n=t.files;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(o===null||typeof o!="object")continue;let i=o;if(typeof i.filePath!="string"||i.filePath.length===0)continue;let a=i.patch,d=a!==null&&typeof a=="object"?a:void 0;r.push({path:i.filePath,...typeof i.additions=="number"?{added:i.additions}:{},...typeof i.deletions=="number"?{removed:i.deletions}:{},...typeof a=="string"?{patch:a}:{},...typeof d?.__hydraBlob=="string"?{patchRef:{hash:d.__hydraBlob,bytes:typeof d.bytes=="number"?d.bytes:0}}:{}})}return r}function bt(s){if(typeof s=="string")return{text:s};if(s&&typeof s=="object"&&!Array.isArray(s)){let e=s;if(typeof e.__hydraBlob=="string")return{ref:{hash:e.__hydraBlob,bytes:typeof e.bytes=="number"?e.bytes:0}}}}function Zr(s){let e=s.rawInput;return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function eo(s){return typeof s.file_path=="string"?s.file_path:typeof s.path=="string"?s.path:void 0}function us(s){let e=s.content;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(r.type!=="diff")continue;let o=bt(r.oldText),i=bt(r.newText);o===void 0&&i===void 0||t.push({...typeof r.path=="string"?{path:r.path}:{},...o?{old:o}:{},...i?{new:i}:{}})}return t}function ls(s){let e=Zr(s);if(!e)return;let t=eo(e);if(e.old_string!==void 0||e.new_string!==void 0){let n=bt(e.old_string),r=bt(e.new_string);return{...t!==void 0?{path:t}:{},...n?{old:n}:{},...r?{new:r}:{}}}if(e.content!==void 0){let n=bt(e.content);return{...t!==void 0?{path:t}:{},old:{text:""},...n?{new:n}:{}}}}function hp(s){let e=Zr(s),t=e?eo(e):void 0;if(!e||t===void 0||!Array.isArray(e.edits))return[];let n=[];for(let r of e.edits){if(!r||typeof r!="object")continue;let o=r,i=bt(o.old_string),a=bt(o.new_string);i===void 0||a===void 0||n.push({path:t,old:i,new:a})}return n}function Ua(s){return La(s).map(e=>({path:e.path,...e.patch!==void 0?{patch:{text:e.patch}}:{},...e.patchRef!==void 0?{patch:{ref:e.patchRef}}:{}}))}function fs(s){let e=hp(s);if(e.length>0)return e;let t=us(s).filter(r=>r.path!==void 0);if(t.length>0)return t;let n=ls(s);return n?.path!==void 0?[n]:Ua(s)}function Ba(s){let e=new Set,t=Zr(s),n=[...us(s).map(r=>r.path),ls(s)?.path,t&&Array.isArray(t.edits)?eo(t):void 0,...Ua(s).map(r=>r.path)];for(let r of n)typeof r=="string"&&r.length>0&&e.add(r);return[...e]}function Wa(s){return s.patch!==void 0?s.patch.text!==void 0?Xr(s.patch.text):{oldText:"",newText:""}:{oldText:s.old?.text??"",newText:s.new?.text??""}}K();import{posix as mp}from"path";import yp from"strip-ansi";function yn(s){if(!s||typeof s!="object")return;let e=s;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}function to(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.parentToolUseId;return typeof n=="string"?n:void 0}var wp=/[\x00-\x08\x0b-\x1f\x7f]/g;function ve(s){return yp(s).replace(wp,"")}function ie(s){return ve(s).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function Va(s,e={}){if(!s||typeof s!="object")return null;let t=s,n=t.sessionUpdate??t.kind;if(typeof n!="string")return null;switch(n){case"agent_message_chunk":return Cp(t);case"agent_thought_chunk":case"agent_thought":return Rp(t);case"user_message_chunk":return xp(t);case"prompt_received":return Ep(t);case"tool_call":return Tp(t,e);case"tool_call_update":return Op(t,e);case"plan":return jp(t);case"current_mode_update":return Hp(t);case"_hydra_current_model_update":return Lp(t);case"turn_complete":return Up(t);case"_hydra_turn_started":return Ja(t,"turn-started");case"_hydra_turn_ended":return Ja(t,"turn-ended");case"usage_update":return Ap(t);case"available_commands_update":return Sp(t);case"_hydra_available_modes_update":return Ip(t);case"session_info_update":return vp(t);case"config_option_update":return kp(t);default:return{kind:"unknown",sessionUpdate:n,raw:s}}}function kp(s){let e=s.configOptions;if(!Array.isArray(e))return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.id!="string"||typeof r.currentValue!="string"||!Array.isArray(r.options))continue;let o=[];for(let i of r.options){if(!i||typeof i!="object")continue;let a=i;typeof a.value=="string"&&o.push({value:a.value,name:typeof a.name=="string"?a.name:a.value,...typeof a.description=="string"?{description:a.description}:{}})}t.push({id:r.id,name:typeof r.name=="string"?r.name:r.id,type:"select",currentValue:r.currentValue,options:o,...typeof r.category=="string"?{category:r.category}:{}})}return{kind:"config-options",options:t}}function vp(s){let e=se(s,"title"),t=e!==void 0?ie(e):void 0,n=s._meta,r,o;if(n&&typeof n=="object"&&!Array.isArray(n)){let a=n["hydra-acp"];if(a&&typeof a=="object"&&!Array.isArray(a)){let d=a.agentId;if(typeof d=="string"&&(r=d),"pendingAgentSwap"in a){let c=a.pendingAgentSwap;typeof c=="string"?o=c:c===null&&(o=null)}}}if(t===void 0&&r===void 0&&o===void 0)return null;let i={kind:"session-info"};return t!==void 0&&(i.title=t),r!==void 0&&(i.agentId=r),o!==void 0&&(i.pendingAgentSwap=o),i}function bp(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object")continue;let n=t;if(typeof n.name!="string"||n.name.length===0)continue;let r=n.name.startsWith("/")?n.name:`/${n.name}`,o={name:ie(r)};typeof n.description=="string"&&(o.description=ie(n.description)),e.push(o)}return e}function Sp(s){let e=s.availableCommands??s.commands;return Array.isArray(e)?{kind:"available-commands",commands:bp(e)}:null}function Ip(s){let e=s.availableModes;if(!Array.isArray(e))return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.id!="string"||r.id.length===0)continue;let o={id:ie(r.id)};typeof r.name=="string"&&(o.name=ie(r.name)),typeof r.description=="string"&&(o.description=ie(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function Ap(s){let e={kind:"usage-update"};if(typeof s.used=="number"&&(e.used=s.used),typeof s.size=="number"&&(e.size=s.size),s.cost&&typeof s.cost=="object"){let t=s.cost;typeof t.amount=="number"&&(e.costAmount=t.amount),typeof t.currency=="string"&&(e.costCurrency=t.currency)}return e}function Cp(s){let e=wn(s.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:yn(s)}}function Rp(s){let e=typeof s.text=="string"?ve(s.text):wn(s.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:yn(s)}}function xp(s){let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){let n=e["hydra-acp"];if(n&&typeof n=="object"&&!Array.isArray(n)&&n.compatFor==="prompt_received")return null}let t=wn(s.content);return t===null?null:{kind:"user-text",text:t}}function Ep(s){let e=Bp(s.prompt);return e===null?null:{kind:"user-text",text:e}}function Ga(s){return s?s.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function Ka(s){let e=us(s)[0];if(e)return qa(e);let t=ls(s);return t?.old?.text!==void 0&&t.new?.text!==void 0?qa(t):null}function qa(s){return{...s.path!==void 0?{path:s.path}:{},oldText:s.old?.text??"",newText:s.new?.text??"",...s.old?.ref?{oldRef:s.old.ref}:{},...s.new?.ref?{newRef:s.new.ref}:{}}}function Qa(s){let e=s.rawInput;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e.plan;return typeof t!="string"||t.length===0?null:ve(t)}function Tp(s,e={}){let t=se(s,"toolCallId")??se(s,"id");if(!t)return null;let n=se(s,"title")??se(s,"name")??se(s,"label")??"tool call",r=se(s,"name")??se(s,"title");if(Ga(r)){let w=Qa(s);if(w!==null){let m=se(s,"status"),g={kind:"exit-plan-mode",toolCallId:t,plan:w};return m!==void 0&&(g.status=m),g}}let o=Za(ie(n),s,e),i=se(s,"status"),a=se(s,"kind"),d={kind:"tool-call",toolCallId:t,title:o};i!==void 0&&(d.status=i),a!==void 0&&(d.rawKind=a);let c=Ka(s);c!==null&&(d.editDiff=c);let u=Xa(s);u!==void 0&&(d.detail=u);let l=no(s);l!==void 0&&(d.detailFull=l);let p=Ya(s);p!==void 0&&(d.locations=p);let f=yn(s);f!==void 0&&(d.workerTaskId=f);let h=to(s);return h!==void 0&&(d.parentToolUseId=h),d}function Ya(s){let e=s.locations;if(!Array.isArray(e))return;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.path!="string"||r.path.length===0)continue;let o={path:r.path};typeof r.line=="number"&&Number.isFinite(r.line)&&r.line>=1&&(o.line=Math.floor(r.line)),t.push(o)}return t.length>0?t:void 0}var za=64;function Xa(s){let e=no(s);if(e===void 0)return;let t=ie(e),n=s.rawInput;return n&&typeof n.command=="string"?_p(t,za):$p(t,za)}function no(s){let e=s.rawInput;if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.command=="string"&&t.command.trim().length>0)return ve(t.command).trim().replace(/^cd\s+\S+\s+&&\s+/,"");let n=typeof t.file_path=="string"?t.file_path:typeof t.filePath=="string"?t.filePath:typeof t.path=="string"?t.path:void 0;if(n!==void 0&&n.length>0)return $(ie(n))}if(Array.isArray(s.locations)){for(let t of s.locations)if(t&&typeof t=="object"){let n=t.path;if(typeof n=="string"&&n.length>0)return $(ie(n))}}}var Pp=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function Mp(s){for(let e of Pp)if(s.startsWith(e))return!0;return!1}function Za(s,e,t={}){if(s.length===0)return s;if(s.startsWith("/"))return $(s);if(s.startsWith("~")||!s.includes("/")||/\s/.test(s))return s;let n=e.rawInput;if(n&&typeof n=="object"&&!Array.isArray(n)){let r=n,o=[r.file_path,r.filePath,r.path];for(let i of o)if(!(typeof i!="string"||i.length===0)&&(i===`/${s}`||i.endsWith(`/${s}`)||i===s))return $(i)}return Mp(s)?$(`/${s}`):t.cwd&&t.cwd.length>0?$(mp.resolve(t.cwd,s)):s}function _p(s,e){return s.length>e?`${s.slice(0,e-1)}\u2026`:s}function $p(s,e){if(s.length<=e)return s;let t=s.slice(-(e-1)),n=t.indexOf("/");return n>=0&&n<e/2?`\u2026${t.slice(n)}`:`\u2026${t}`}function Op(s,e={}){let t=se(s,"toolCallId")??se(s,"id");if(!t)return null;let n=se(s,"title"),r=n!==void 0?Za(ie(n),s,e):void 0,o=se(s,"status"),i=Ka(s),a=Xa(s),d=Fp(s);if(!(r!==void 0||i!==null||a!==void 0||d!==void 0||o==="completed"||o==="failed"||o==="rejected"||o==="cancelled"))return null;let u=se(s,"name")??n;if(Ga(u)){let m={kind:"exit-plan-mode",toolCallId:t},g=Qa(s);return g!==null&&(m.plan=g),o!==void 0&&(m.status=o),m}let l={kind:"tool-call-update",toolCallId:t};r!==void 0&&(l.title=r),a!==void 0&&(l.detail=a);let p=no(s);p!==void 0&&(l.detailFull=p);let f=Ya(s);if(f!==void 0&&(l.locations=f),d!==void 0&&(l.resultSummary=d),o!==void 0&&(l.status=o),i!==null&&(l.editDiff=i),o==="failed"){let m=Np(s);m!==null&&(l.errorText=m),Dp(s,m)&&(l.upstreamInterrupted=!0)}let h=yn(s);h!==void 0&&(l.workerTaskId=h);let w=to(s);return w!==void 0&&(l.parentToolUseId=w),l}function Fp(s){if(!s||typeof s!="object")return;let e=s.rawOutput;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=u=>{let l=t[u];return typeof l=="number"&&Number.isFinite(l)?l:void 0},r=(u,l,p=`${l}s`)=>`${u} ${u===1?l:p}`,o=[],i=n("totalMatches");i!==void 0&&o.push(r(i,"match","matches"));let a=n("totalFiles");a!==void 0&&o.push(r(a,"file"));let d=n("referenceCount");d!==void 0&&o.push(r(d,"reference")),o.length>0&&t.truncated===!0&&o.push("truncated");let c=n("exitCode");return c!==void 0&&c!==0&&o.push(`exit ${c}`),o.length>0?o.join(", "):void 0}function Np(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=wn(n.content);if(o!==null&&o.length>0)return o}let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.error;if(typeof n=="string"&&n.length>0)return ve(n)}return null}function Dp(s,e){let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.metadata;if(n&&typeof n=="object"&&n.interrupted===!0)return!0}return!!(e!==null&&e.toLowerCase().includes("tool execution aborted"))}function jp(s){let e=s.entries;if(!Array.isArray(e)||e.length===0)return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n,o=typeof r.content=="string"?ie(r.content):void 0;if(!o)continue;let i={content:o};typeof r.status=="string"&&(i.status=r.status),typeof r.priority=="string"&&(i.priority=r.priority),t.push(i)}return{kind:"plan",entries:t}}function Hp(s){let e=se(s,"currentModeId")??se(s,"currentMode")??se(s,"mode");return e?{kind:"mode-changed",mode:ie(e)}:null}function Lp(s){let e=se(s,"currentModel")??se(s,"model");if(!e)return null;let t=s.availableModels,n=Array.isArray(t)?t.map(r=>typeof r=="object"&&r!==null?r.modelId:typeof r=="string"?r:void 0).filter(r=>typeof r=="string"&&r.length>0):void 0;return{kind:"model-changed",model:ie(e),...n&&n.length>0?{availableModels:n}:{}}}function Up(s){let e=se(s,"stopReason"),t=s._meta,n=t?.["hydra-acp"]?.amended!==void 0&&t["hydra-acp"].amended!==null,r={kind:"turn-complete"};return e!==void 0&&(r.stopReason=e),n&&(r.amended=!0),r}function Ja(s,e){let n=s._meta?.["hydra-acp"],r=n?.unsolicited===!0;if(e==="turn-started"){let i=n?.cause?.label,a={kind:e,unsolicited:r};return typeof i=="string"&&i.length>0&&(a.cause=i),a}let o={kind:e,unsolicited:r};return typeof n?.reason=="string"&&(o.reason=n.reason),o}function wn(s){if(typeof s=="string")return ve(s);if(!s||typeof s!="object")return null;let e=s;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?ve(e.text):null}function Bp(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){let n=wn(t);n!==null&&e.push(n)}return e.length===0?null:e.join("")}function se(s,e){let t=s[e];return typeof t=="string"?t:void 0}function Wp(s,e){let t=ve(s).split(`
29
29
  `),n=ve(e).split(`
30
30
  `);return t.length>0&&t[t.length-1]===""&&t.pop(),n.length>0&&n[n.length-1]===""&&n.pop(),{oldLines:t,newLines:n}}function ed(s,e){let{oldLines:t,newLines:n}=Wp(s,e),r=0,o=0;for(let i of qp(t,n))i.op==="+"?r++:i.op==="-"&&o++;return{added:r,removed:o}}function qp(s,e){let t=0,n=Math.min(s.length,e.length);for(;t<n&&s[t]===e[t];)t++;let r=s.length,o=e.length;for(;r>t&&o>t&&s[r-1]===e[o-1];)r--,o--;let i=[];for(let a=0;a<t;a++)i.push({op:"=",text:s[a]});i.push(...zp(s.slice(t,r),e.slice(t,o)));for(let a=r;a<s.length;a++)i.push({op:"=",text:s[a]});return i}function zp(s,e){let t=s.length,n=e.length;if(t===0||n===0){let d=[];for(let c of s)d.push({op:"-",text:c});for(let c of e)d.push({op:"+",text:c});return d}let r=Array.from({length:t+1},()=>new Array(n+1).fill(0));for(let d=t-1;d>=0;d--)for(let c=n-1;c>=0;c--)s[d]===e[c]?r[d][c]=r[d+1][c+1]+1:r[d][c]=Math.max(r[d+1][c],r[d][c+1]);let o=[],i=0,a=0;for(;i<t&&a<n;)s[i]===e[a]?(o.push({op:"=",text:s[i]}),i++,a++):r[i+1][a]>=r[i][a+1]?(o.push({op:"-",text:s[i]}),i++):(o.push({op:"+",text:e[a]}),a++);for(;i<t;)o.push({op:"-",text:s[i]}),i++;for(;a<n;)o.push({op:"+",text:e[a]}),a++;return o}var td="hydra-acp";function Jp(s){let e=0,t=0,n=!1;for(let r of s.split(`
31
- `)){if(r.startsWith("@@")){n=!0;continue}n&&(r.startsWith("+")?e++:r.startsWith("-")&&t++)}return{added:e,removed:t}}function Vp(s){let e=[];for(let t of fs(s))if(t.path!==void 0){if(t.patch!==void 0){t.patch.text!==void 0&&e.push({path:t.path,...Jp(t.patch.text)});continue}t.old!==void 0&&t.old.text===void 0||t.new!==void 0&&t.new.text===void 0||e.push({path:t.path,...ed(t.old?.text??"",t.new?.text??"")})}return e}function nd(s){let e=s.update;if(!e||e.sessionUpdate!=="tool_call"&&e.sessionUpdate!=="tool_call_update")return s;let t=Vp(e);if(t.length===0)return s;let n=e._meta??{},r=n[td]??{};return{...s,update:{...e,_meta:{...n,[td]:{...r,editStats:t}}}}}var sd=["hydra-acp-","hydra-"];function so(s){for(let e of sd)if(s.startsWith(e)&&s.length>e.length)return s.slice(e.length)}function rd(s){return sd.map(e=>`${e}${s}`)}import{customAlphabet as Pd}from"nanoid";function Je(s){return`${s.name}:${s.localId}`}function ft(s){let e=s.indexOf(":");if(e===-1)return;let t=s.slice(0,e),n=s.slice(e+1);if(!(t.length===0||n.length===0))return{name:t,localId:n}}import{createHmac as Gp}from"crypto";function Kp(s,e){return Gp("sha256",s).update(e).digest("hex")}function ro(s,e){let t=JSON.stringify(e),n=Kp(s.secret,t);fetch(s.callbackUrl,{method:"POST",headers:{"Content-Type":"application/json","X-Hydra-Turn-Notify-Signature":n},body:t}).catch(()=>{})}function kn(s,e){return s!==void 0&&e!==void 0&&s>e}function Bt(s){return{...s.lastTurnEndedAt!==void 0?{lastTurnEndedAt:s.lastTurnEndedAt}:{},...s.readAt!==void 0?{readAt:s.readAt}:{},unread:kn(s.lastTurnEndedAt,s.readAt)}}function ps(s,e,t=Date.now()){let n;if(e){if(s.readAt!==void 0&&!kn(s.lastTurnEndedAt,s.readAt))return;n=Math.max(t,s.lastTurnEndedAt??0)}else s.lastTurnEndedAt!==void 0&&!kn(s.lastTurnEndedAt,s.readAt)&&(n=s.lastTurnEndedAt-1);return n===s.readAt?void 0:n}import*as id from"fs/promises";var Qp=64*1024*1024,Yp=1*1024*1024,Wt=64*1024,Xp=6e4,Zp=100,eg=1e3,tg=64*1024,ng=256*1024,od=20;function sg(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var gs=class{storage;maxCapacityBytes;currentCapacityBytes;writeCursor=0;closed=!1;waiters=[];filePath;fileCapBytes;fileBytesWritten=0;fileCapReached=!1;onFileCapReached;logWriteError;fileWriteChain=Promise.resolve();constructor(e={}){if(this.maxCapacityBytes=e.capacityBytes??Qp,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Yp,this.maxCapacityBytes),this.storage=Buffer.alloc(this.currentCapacityBytes),this.filePath=e.filePath,this.fileCapBytes=e.fileCapBytes??Number.POSITIVE_INFINITY,this.onFileCapReached=e.onFileCapReached,this.logWriteError=e.logWriteError}get capacity(){return this.maxCapacityBytes}get allocatedBytes(){return this.currentCapacityBytes}get writeCursorPos(){return this.writeCursor}get oldestAvailable(){return Math.max(0,this.writeCursor-this.currentCapacityBytes)}get isClosed(){return this.closed}append(e){this.closed||e.length===0||(this.writeRing(e),this.writeCursor+=e.length,this.filePath!==void 0&&this.scheduleFileWrite(e),this.wakeWaiters("data"))}close(){this.closed||(this.closed=!0,this.wakeWaiters("eof"))}read(e,t){let n=Math.max(0,Math.min(t,Wt));if(n===0){let l={bytes:Buffer.alloc(0),nextCursor:e};return this.closed&&e>=this.writeCursor&&(l.eof=!0),l}let r=e,o=0,i=this.oldestAvailable;r<i&&(o=i-r,r=i);let a=this.writeCursor-r;if(a<=0){let l={bytes:Buffer.alloc(0),nextCursor:r};return o>0&&(l.gap=o),this.closed&&(l.eof=!0),l}let d=Math.min(a,n),u={bytes:this.sliceFromRing(r,d),nextCursor:r+d};return o>0&&(u.gap=o),this.closed&&r+d>=this.writeCursor&&(u.eof=!0),u}tail(e){let t=Math.max(0,Math.min(e,Wt)),n=this.oldestAvailable,r=this.writeCursor-t,o=Math.max(n,r),i=r<n;return{bytes:this.sliceFromRing(o,this.writeCursor-o),startCursor:o,endCursor:this.writeCursor,truncated:i}}head(e){let t=Math.max(0,Math.min(e,Wt)),n=this.oldestAvailable,r=n>0,o=n,i=Math.min(this.writeCursor,o+t);return{bytes:this.sliceFromRing(o,i-o),startCursor:o,endCursor:i,truncated:r}}waitForData(e,t){if(e<this.writeCursor)return Promise.resolve("data");if(this.closed)return Promise.resolve("eof");let n=Math.max(0,Math.min(t,Xp));return n===0?Promise.resolve("timeout"):new Promise(r=>{let o={resolve:i=>{o.timer!==void 0&&(clearTimeout(o.timer),o.timer=void 0),r(i)},timer:setTimeout(()=>{let i=this.waiters.indexOf(o);i>=0&&this.waiters.splice(i,1),o.timer=void 0,r("timeout")},n)};this.waiters.push(o)})}grep(e){let t=this.oldestAvailable,n=e.cursor,r=n??t,o=0;n!==void 0&&n<t&&(o=t-n,r=t),r>this.writeCursor&&(r=this.writeCursor);let i=this.sliceFromRing(r,this.writeCursor-r),a=e.regex??!0,d=e.caseInsensitive===!0?"i":"",c=a?new RegExp(e.pattern,d):new RegExp(sg(e.pattern),d),u=e.invert??!1,l=Math.max(1,Math.min(e.maxMatches??Zp,eg)),p=Math.max(1,Math.min(e.maxBytes??tg,ng)),f=Math.max(0,Math.min(e.contextBefore??0,od)),h=Math.max(0,Math.min(e.contextAfter??0,od)),w=[],m=[],g=[],y=0,k=!1,v=0,S=0,b=(R,T)=>{for(let W of g)W.remaining>0&&(W.match.after===void 0&&(W.match.after=[]),W.match.after.push({cursor:R,line:T}),W.remaining--,y+=T.length);for(;g.length>0&&g[0].remaining===0;)g.shift();if(c.test(T)!==u&&w.length<l){let W={cursor:R,line:T};if(f>0&&m.length>0){W.before=m.slice();for(let z of W.before)y+=z.line.length}y+=T.length,w.push(W),h>0&&g.push({match:W,remaining:h})}if(f>0)for(m.push({cursor:R,line:T});m.length>f;)m.shift();let j=w.length>=l&&g.length===0,U=y>=p;return j||U};for(let R=0;R<i.length;R++){if(i[R]!==10)continue;let T=i.subarray(v,R).toString("utf8"),M=r+v;if(v=R+1,S=v,b(M,T)){k=!0;break}}if(!k&&v<i.length&&this.closed){let R=i.subarray(v).toString("utf8"),T=r+v;b(T,R)&&(k=!0),S=i.length}let A=Math.min(r+S,this.writeCursor),C={matches:w,truncated:k,nextCursor:A,scannedBytes:S};return o>0&&(C.gap=o),this.closed&&A>=this.writeCursor&&(C.eof=!0),C}wakeWaiters(e){if(this.waiters.length===0)return;let t=this.waiters;this.waiters=[];for(let n of t)n.resolve(e)}growIfNeeded(e){if(this.currentCapacityBytes>=this.maxCapacityBytes)return;let t=this.writeCursor+e;if(t<=this.currentCapacityBytes)return;let n=this.currentCapacityBytes;for(;n<t&&n<this.maxCapacityBytes;)n=Math.min(this.maxCapacityBytes,n*2);if(n===this.currentCapacityBytes)return;let r=Buffer.alloc(n);this.storage.copy(r,0,0,this.writeCursor),this.storage=r,this.currentCapacityBytes=n}writeRing(e){let t=e.length;if(this.growIfNeeded(t),t>=this.currentCapacityBytes){let o=t-this.currentCapacityBytes;e.copy(this.storage,0,o,t);return}let n=this.writeCursor%this.currentCapacityBytes,r=this.currentCapacityBytes-n;t<=r?e.copy(this.storage,n,0,t):(e.copy(this.storage,n,0,r),e.copy(this.storage,0,r,t))}sliceFromRing(e,t){if(t<=0)return Buffer.alloc(0);let n=Buffer.alloc(t),r=e%this.currentCapacityBytes,o=Math.min(t,this.currentCapacityBytes-r);return this.storage.copy(n,0,r,r+o),o<t&&this.storage.copy(n,o,0,t-o),n}scheduleFileWrite(e){let t=this.filePath;if(t===void 0||this.fileCapReached)return;let n=this.fileCapBytes-this.fileBytesWritten;if(n<=0){this.fileCapReached=!0,this.onFileCapReached?.();return}let r=e.length<=n?e:e.subarray(0,n);this.fileBytesWritten+=r.length;let o=this.fileBytesWritten>=this.fileCapBytes;this.fileWriteChain=this.fileWriteChain.then(()=>id.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var qt=[{verb:"title",name:"hydra title",description:"Regenerate the session title + synopsis via the agent (or set title manually with an arg)"},{verb:"agent",name:"hydra agent",argsHint:"<agent | status>",description:"Schedule a swap to a different agent (synthesizes a brief in the target's idiom, rotates on idle); `status` reports any pending swap"},{verb:"workspace",name:"hydra workspace",argsHint:"<start [name] [--clean] | sync | merge | apply | stop | detach | clean [--deep] | discard | status>",description:"Move this session into an isolated workspace so its edits cannot collide with other work, then land or discard them. `start` copies your uncommitted changes in and leaves the real tree untouched; `start --clean` leaves them behind so the workspace begins at the last commit. `stop` merges and returns; `discard` throws the work away and returns; `detach` returns without merging, leaving the workspace and its branch intact; `merge` lands the work without leaving; `apply` also stays, but delivers the work as ONE staged, uncommitted changeset instead of as the agent's commits, so you review and commit it yourself, with no fast-forward needed, which is what makes it work once the source has moved on; `clean` throws away everything done in the workspace and stays there, putting it back exactly as `start --clean` would have made it (add `--deep` to rebuild dependencies and carried config files too, rather than keeping them); `sync` pulls the source's committed history INTO the workspace, so you can test against what you will land onto, and because landing is fast-forward-only, syncing is also how you recover once the source has moved on. `start <name>` naming a workspace another live session is already in JOINS it instead of making a second one, so two sessions can share a checkout deliberately: edits interleave, `stop` behaves as `detach` while anyone else is still there, and the work lands when the last of them leaves."},{verb:"kill",name:"hydra kill",description:"Close this session (kills the agent; record is kept so it can be resumed later)"},{verb:"restart",name:"hydra restart",description:"Restart the agent with a fresh session/new while preserving conversation history (useful when the proxy has changed available models)"},{verb:"compact",name:"hydra compact",description:"Compact this session's history. Use '/hydra compact status' to inspect current compaction state without triggering."},{verb:"uncompact",name:"hydra uncompact",description:"Roll back the most recent compaction swap (only available immediately after a swap, before any new turns)"},{verb:"clear",name:"hydra clear",description:"Drop every turn of this conversation, this command included, and restart the agent with no context"},{verb:"fork",name:"hydra fork",argsHint:"[--verbatim] [prompt]",description:"Fork this conversation into a new session (default: synthesis mode with a synopsis brief; pass --verbatim to slice at the last completed turn instead). A prompt is sent to the fork as its first turn once it's ready."},{verb:"config",name:"hydra config",argsHint:"[<id> [<value>]]",description:"List or set an agent-advertised configOption (model, mode, effort, etc.). With no args, lists all options; with <id>, shows its choices; with <id> <value>, applies it."}],wb=new Map(qt.map(s=>[s.verb,s]));function ad(s){let e=s.lastIndexOf("/");return(e===-1?s:s.slice(e+1)).toLowerCase()}function zt(s,e){return Jt(s,e.map(t=>t.modelId))}function Jt(s,e){if(e.length===0)return{kind:"none",requested:s};if(e.includes(s))return{kind:"exact",modelId:s};let t=ad(s),n=e.filter(o=>ad(o)===t);if(n.length===1)return{kind:"resolved",modelId:n[0],requested:s};if(n.length>1)return{kind:"ambiguous",requested:s,candidates:n};let r=s.toLowerCase();if(r.length>0){let o=e.filter(i=>i.toLowerCase().includes(r));if(o.length===1)return{kind:"resolved",modelId:o[0],requested:s};if(o.length>1)return{kind:"ambiguous",requested:s,candidates:o}}return{kind:"unknown",requested:s}}var rg="Compact conversation",og="contextCompaction",ig=`
31
+ `)){if(r.startsWith("@@")){n=!0;continue}n&&(r.startsWith("+")?e++:r.startsWith("-")&&t++)}return{added:e,removed:t}}function Vp(s){let e=[];for(let t of fs(s))if(t.path!==void 0){if(t.patch!==void 0){t.patch.text!==void 0&&e.push({path:t.path,...Jp(t.patch.text)});continue}t.old!==void 0&&t.old.text===void 0||t.new!==void 0&&t.new.text===void 0||e.push({path:t.path,...ed(t.old?.text??"",t.new?.text??"")})}return e}function nd(s){let e=s.update;if(!e||e.sessionUpdate!=="tool_call"&&e.sessionUpdate!=="tool_call_update")return s;let t=Vp(e);if(t.length===0)return s;let n=e._meta??{},r=n[td]??{};return{...s,update:{...e,_meta:{...n,[td]:{...r,editStats:t}}}}}var sd=["hydra-acp-","hydra-"];function so(s){for(let e of sd)if(s.startsWith(e)&&s.length>e.length)return s.slice(e.length)}function rd(s){return sd.map(e=>`${e}${s}`)}import{customAlphabet as Pd}from"nanoid";function Je(s){return`${s.name}:${s.localId}`}function ft(s){let e=s.indexOf(":");if(e===-1)return;let t=s.slice(0,e),n=s.slice(e+1);if(!(t.length===0||n.length===0))return{name:t,localId:n}}import{createHmac as Gp}from"crypto";function Kp(s,e){return Gp("sha256",s).update(e).digest("hex")}function ro(s,e){let t=JSON.stringify(e),n=Kp(s.secret,t);fetch(s.callbackUrl,{method:"POST",headers:{"Content-Type":"application/json","X-Hydra-Turn-Notify-Signature":n},body:t}).catch(()=>{})}function kn(s,e){return s!==void 0&&e!==void 0&&s>e}function Bt(s){return{...s.lastTurnEndedAt!==void 0?{lastTurnEndedAt:s.lastTurnEndedAt}:{},...s.readAt!==void 0?{readAt:s.readAt}:{},unread:kn(s.lastTurnEndedAt,s.readAt)}}function ps(s,e,t=Date.now()){let n;if(e){if(s.readAt!==void 0&&!kn(s.lastTurnEndedAt,s.readAt))return;n=Math.max(t,s.lastTurnEndedAt??0)}else s.lastTurnEndedAt!==void 0&&!kn(s.lastTurnEndedAt,s.readAt)&&(n=s.lastTurnEndedAt-1);return n===s.readAt?void 0:n}import*as id from"fs/promises";var Qp=64*1024*1024,Yp=1*1024*1024,Wt=64*1024,Xp=6e4,Zp=100,eg=1e3,tg=64*1024,ng=256*1024,od=20;function sg(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var gs=class{storage;maxCapacityBytes;currentCapacityBytes;writeCursor=0;closed=!1;waiters=[];filePath;fileCapBytes;fileBytesWritten=0;fileCapReached=!1;onFileCapReached;logWriteError;fileWriteChain=Promise.resolve();constructor(e={}){if(this.maxCapacityBytes=e.capacityBytes??Qp,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Yp,this.maxCapacityBytes),this.storage=Buffer.alloc(this.currentCapacityBytes),this.filePath=e.filePath,this.fileCapBytes=e.fileCapBytes??Number.POSITIVE_INFINITY,this.onFileCapReached=e.onFileCapReached,this.logWriteError=e.logWriteError}get capacity(){return this.maxCapacityBytes}get allocatedBytes(){return this.currentCapacityBytes}get writeCursorPos(){return this.writeCursor}get oldestAvailable(){return Math.max(0,this.writeCursor-this.currentCapacityBytes)}get isClosed(){return this.closed}append(e){this.closed||e.length===0||(this.writeRing(e),this.writeCursor+=e.length,this.filePath!==void 0&&this.scheduleFileWrite(e),this.wakeWaiters("data"))}close(){this.closed||(this.closed=!0,this.wakeWaiters("eof"))}read(e,t){let n=Math.max(0,Math.min(t,Wt));if(n===0){let l={bytes:Buffer.alloc(0),nextCursor:e};return this.closed&&e>=this.writeCursor&&(l.eof=!0),l}let r=e,o=0,i=this.oldestAvailable;r<i&&(o=i-r,r=i);let a=this.writeCursor-r;if(a<=0){let l={bytes:Buffer.alloc(0),nextCursor:r};return o>0&&(l.gap=o),this.closed&&(l.eof=!0),l}let d=Math.min(a,n),u={bytes:this.sliceFromRing(r,d),nextCursor:r+d};return o>0&&(u.gap=o),this.closed&&r+d>=this.writeCursor&&(u.eof=!0),u}tail(e){let t=Math.max(0,Math.min(e,Wt)),n=this.oldestAvailable,r=this.writeCursor-t,o=Math.max(n,r),i=r<n;return{bytes:this.sliceFromRing(o,this.writeCursor-o),startCursor:o,endCursor:this.writeCursor,truncated:i}}head(e){let t=Math.max(0,Math.min(e,Wt)),n=this.oldestAvailable,r=n>0,o=n,i=Math.min(this.writeCursor,o+t);return{bytes:this.sliceFromRing(o,i-o),startCursor:o,endCursor:i,truncated:r}}waitForData(e,t){if(e<this.writeCursor)return Promise.resolve("data");if(this.closed)return Promise.resolve("eof");let n=Math.max(0,Math.min(t,Xp));return n===0?Promise.resolve("timeout"):new Promise(r=>{let o={resolve:i=>{o.timer!==void 0&&(clearTimeout(o.timer),o.timer=void 0),r(i)},timer:setTimeout(()=>{let i=this.waiters.indexOf(o);i>=0&&this.waiters.splice(i,1),o.timer=void 0,r("timeout")},n)};this.waiters.push(o)})}grep(e){let t=this.oldestAvailable,n=e.cursor,r=n??t,o=0;n!==void 0&&n<t&&(o=t-n,r=t),r>this.writeCursor&&(r=this.writeCursor);let i=this.sliceFromRing(r,this.writeCursor-r),a=e.regex??!0,d=e.caseInsensitive===!0?"i":"",c=a?new RegExp(e.pattern,d):new RegExp(sg(e.pattern),d),u=e.invert??!1,l=Math.max(1,Math.min(e.maxMatches??Zp,eg)),p=Math.max(1,Math.min(e.maxBytes??tg,ng)),f=Math.max(0,Math.min(e.contextBefore??0,od)),h=Math.max(0,Math.min(e.contextAfter??0,od)),w=[],m=[],g=[],y=0,k=!1,v=0,S=0,b=(R,T)=>{for(let W of g)W.remaining>0&&(W.match.after===void 0&&(W.match.after=[]),W.match.after.push({cursor:R,line:T}),W.remaining--,y+=T.length);for(;g.length>0&&g[0].remaining===0;)g.shift();if(c.test(T)!==u&&w.length<l){let W={cursor:R,line:T};if(f>0&&m.length>0){W.before=m.slice();for(let z of W.before)y+=z.line.length}y+=T.length,w.push(W),h>0&&g.push({match:W,remaining:h})}if(f>0)for(m.push({cursor:R,line:T});m.length>f;)m.shift();let H=w.length>=l&&g.length===0,U=y>=p;return H||U};for(let R=0;R<i.length;R++){if(i[R]!==10)continue;let T=i.subarray(v,R).toString("utf8"),M=r+v;if(v=R+1,S=v,b(M,T)){k=!0;break}}if(!k&&v<i.length&&this.closed){let R=i.subarray(v).toString("utf8"),T=r+v;b(T,R)&&(k=!0),S=i.length}let A=Math.min(r+S,this.writeCursor),C={matches:w,truncated:k,nextCursor:A,scannedBytes:S};return o>0&&(C.gap=o),this.closed&&A>=this.writeCursor&&(C.eof=!0),C}wakeWaiters(e){if(this.waiters.length===0)return;let t=this.waiters;this.waiters=[];for(let n of t)n.resolve(e)}growIfNeeded(e){if(this.currentCapacityBytes>=this.maxCapacityBytes)return;let t=this.writeCursor+e;if(t<=this.currentCapacityBytes)return;let n=this.currentCapacityBytes;for(;n<t&&n<this.maxCapacityBytes;)n=Math.min(this.maxCapacityBytes,n*2);if(n===this.currentCapacityBytes)return;let r=Buffer.alloc(n);this.storage.copy(r,0,0,this.writeCursor),this.storage=r,this.currentCapacityBytes=n}writeRing(e){let t=e.length;if(this.growIfNeeded(t),t>=this.currentCapacityBytes){let o=t-this.currentCapacityBytes;e.copy(this.storage,0,o,t);return}let n=this.writeCursor%this.currentCapacityBytes,r=this.currentCapacityBytes-n;t<=r?e.copy(this.storage,n,0,t):(e.copy(this.storage,n,0,r),e.copy(this.storage,0,r,t))}sliceFromRing(e,t){if(t<=0)return Buffer.alloc(0);let n=Buffer.alloc(t),r=e%this.currentCapacityBytes,o=Math.min(t,this.currentCapacityBytes-r);return this.storage.copy(n,0,r,r+o),o<t&&this.storage.copy(n,o,0,t-o),n}scheduleFileWrite(e){let t=this.filePath;if(t===void 0||this.fileCapReached)return;let n=this.fileCapBytes-this.fileBytesWritten;if(n<=0){this.fileCapReached=!0,this.onFileCapReached?.();return}let r=e.length<=n?e:e.subarray(0,n);this.fileBytesWritten+=r.length;let o=this.fileBytesWritten>=this.fileCapBytes;this.fileWriteChain=this.fileWriteChain.then(()=>id.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var qt=[{verb:"title",name:"hydra title",description:"Regenerate the session title + synopsis via the agent (or set title manually with an arg)"},{verb:"agent",name:"hydra agent",argsHint:"<agent | status>",description:"Schedule a swap to a different agent (synthesizes a brief in the target's idiom, rotates on idle); `status` reports any pending swap"},{verb:"workspace",name:"hydra workspace",argsHint:"<start [name] [--clean] | sync | merge | apply | stop | detach | clean [--deep] | discard | status>",description:"Move this session into an isolated workspace so its edits cannot collide with other work, then land or discard them. `start` copies your uncommitted changes in and leaves the real tree untouched; `start --clean` leaves them behind so the workspace begins at the last commit. `stop` merges and returns; `discard` throws the work away and returns; `detach` returns without merging, leaving the workspace and its branch intact; `merge` lands the work without leaving; `apply` also stays, but delivers the work as ONE staged, uncommitted changeset instead of as the agent's commits, so you review and commit it yourself, with no fast-forward needed, which is what makes it work once the source has moved on; `clean` throws away everything done in the workspace and stays there, putting it back exactly as `start --clean` would have made it (add `--deep` to rebuild dependencies and carried config files too, rather than keeping them); `sync` pulls the source's committed history INTO the workspace, so you can test against what you will land onto, and because landing is fast-forward-only, syncing is also how you recover once the source has moved on. `start <name>` naming a workspace another live session is already in JOINS it instead of making a second one, so two sessions can share a checkout deliberately: edits interleave, `stop` behaves as `detach` while anyone else is still there, and the work lands when the last of them leaves."},{verb:"kill",name:"hydra kill",description:"Close this session (kills the agent; record is kept so it can be resumed later)"},{verb:"restart",name:"hydra restart",description:"Restart the agent with a fresh session/new while preserving conversation history (useful when the proxy has changed available models)"},{verb:"compact",name:"hydra compact",description:"Compact this session's history. Use '/hydra compact status' to inspect current compaction state without triggering."},{verb:"uncompact",name:"hydra uncompact",description:"Roll back the most recent compaction swap (only available immediately after a swap, before any new turns)"},{verb:"clear",name:"hydra clear",description:"Drop every turn of this conversation, this command included, and restart the agent with no context"},{verb:"fork",name:"hydra fork",argsHint:"[--verbatim] [prompt]",description:"Fork this conversation into a new session (default: synthesis mode with a synopsis brief; pass --verbatim to slice at the last completed turn instead). A prompt is sent to the fork as its first turn once it's ready."},{verb:"config",name:"hydra config",argsHint:"[<id> [<value>]]",description:"List or set an agent-advertised configOption (model, mode, effort, etc.). With no args, lists all options; with <id>, shows its choices; with <id> <value>, applies it."}],kb=new Map(qt.map(s=>[s.verb,s]));function ad(s){let e=s.lastIndexOf("/");return(e===-1?s:s.slice(e+1)).toLowerCase()}function zt(s,e){return Jt(s,e.map(t=>t.modelId))}function Jt(s,e){if(e.length===0)return{kind:"none",requested:s};if(e.includes(s))return{kind:"exact",modelId:s};let t=ad(s),n=e.filter(o=>ad(o)===t);if(n.length===1)return{kind:"resolved",modelId:n[0],requested:s};if(n.length>1)return{kind:"ambiguous",requested:s,candidates:n};let r=s.toLowerCase();if(r.length>0){let o=e.filter(i=>i.toLowerCase().includes(r));if(o.length===1)return{kind:"resolved",modelId:o[0],requested:s};if(o.length>1)return{kind:"ambiguous",requested:s,candidates:o}}return{kind:"unknown",requested:s}}var rg="Compact conversation",og="contextCompaction",ig=`
32
32
 
33
33
  Compacting completed.`;function ag(s){if(!s||s.status!=="completed"||s.sessionUpdate!=="tool_call"&&s.sessionUpdate!=="tool_call_update")return!1;let e=s._meta,t=e!==null&&typeof e=="object"&&og in e;return s.title===rg||t}function dg(s){if(!s||s.sessionUpdate!=="agent_message_chunk")return!1;let e=s.content;return!e||typeof e!="object"||Array.isArray(e)?!1:e.text===ig}function cd(s){return ag(s)||dg(s)}var dd=[`## Objective
34
34
  `,`## Important Details
@@ -46,17 +46,17 @@ Compacting completed.`;function ag(s){if(!s||s.status!=="completed"||s.sessionUp
46
46
  `)+`
47
47
  `;await Ve.writeFile(t,n,"utf8")}async function Sd(s){let e=E.queueFile(s),t;try{t=await Ve.readFile(e,"utf8")}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t.split(`
48
48
  `))if(r.trim())try{let o=JSON.parse(r);o&&typeof o.messageId=="string"&&Array.isArray(o.prompt)&&typeof o.enqueuedAt=="number"&&n.push(o)}catch{}return n}async function Id(s){let e=E.queueFile(s);await Ve.unlink(e).catch(()=>{})}import*as $d from"fs/promises";var Md="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",_d=Pd(Md,16),ho=Pd(Md,16),Cg=20,Rg=20,xg=5,Eg=32,ye="hydra_session_";function Ge(){return`m_${_d()}`}function et(s){let e=ft(s)?.localId??s;return e.startsWith(ye)?e.slice(ye.length):e}var Ad=["start","merge","apply","sync","stop","detach","discard","clean","status"],Tg=1e3,ws=300*1e3,Pg=64,Mg=new Set(["task-notification","peer","coordinator","observer","observer-activity"]);function _g(s){let e=s?.update;if(!e||typeof e!="object"||e.sessionUpdate!=="usage_update")return!1;let t=e._meta;if(!t||typeof t!="object")return!1;let n=t["_claude/origin"];if(!n||typeof n!="object")return!1;let r=n.kind;return typeof r=="string"&&Mg.has(r)}function Cd(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="usage_update"}function $g(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="tool_call_update"}function Og(s,e){return e===void 0?!1:s.some(t=>{if(!t||typeof t!="object")return!1;let n=t.id;return typeof n=="string"&&n.trim()!==""&&n.trim()!==e})}var mo=120;function Fg(s){let e=s.split(`
49
- `).map(t=>t.trim()).filter(t=>t!=="");return e.length===0?"":e[e.length-1]}var Ng=128,Dg=new Set(["local_bash"]),Hg=1e3,Gt=class s{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=ze;modelVerbConfirmed=!1;agentArgs;parentSessionId;forkedFromSessionId;forkedFromMessageId;side;forkSynthesisState;originatingClient;_interactive;get interactive(){return this._interactive}_priority;get priority(){return this._priority}_lastTurnEndedAt;get lastTurnEndedAt(){return this._lastTurnEndedAt}_readAt;get readAt(){return this._readAt}title;_summarizedThroughEntry;get summarizedThroughEntry(){return this._summarizedThroughEntry}set summarizedThroughEntry(e){this._summarizedThroughEntry=e}currentModel;currentMode;compactionState;_currentUsage;updatedAt;createdAt;clients=new Map;historyStore;promptQueue=[];currentEntry;promptInFlight=!1;agentTurnInFlight=!1;swapInFlight=!1;opencodeSummary=new hs;modeChangeInFlight=!1;modelChangeInFlight=!1;queueWriteChain=Promise.resolve();closed=!1;closing=!1;closeInFlight;deleteRecordIntent=!1;closeHandlers=[];titleHandlers=[];scheduleSynopsisHook;scheduleWorkspaceSnapshotHook;scheduleCompactionHook;resolveAgentIdHook;getCompactionStateHook;getUpstreamGenerationsHook;getPendingAgentSwapHook;_liveCompactionPhase;broadcastHandlers=[];lastCancelAt=0;static CANCEL_ERROR_WINDOW_MS=2e3;lastUnsolicitedCancelAt=0;cancelReopenStreak=0;static UNSOLICITED_REOPEN_WINDOW_MS=1e4;static UNSOLICITED_REOPEN_LIMIT=3;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}_titleSeedPending=!0;_upstreamRespawned=!1;promptStartedAt;turnRanTool=!1;unsolicitedTurn;pendingSteerDetach;supersededAutonomousTurn;autonomousSalvage;lastBackgroundTask;toolLabels=new Map;armedTasks=new Map;lastArmedBroadcast;liveBackgroundTasks=new Map;sawBackgroundTaskLevel=!1;sawTurnComplete=!1;appendCount=0;historyMaxEntries;compactEvery;permissionCallbacks=new Map;attentionFlags=new Map;get hasPermissionFlag(){for(let e of this.attentionFlags.values())if(e.source==="daemon"&&e.reason.startsWith("permission:"))return!0;return!1}attentionFlagsChangeHandlers=[];internalPromptCapture;idleTimeoutMs;idleTimer;orphanTimeoutMs;orphanTimer;idleEventTimeoutMs;idleHandlers=[];lastRecordedAt;lastSeq=0;spawnReplacementAgent;mintMcpServersForSwap;loadExistingAgentSession;clearRollbackBreadcrumbHook;onCompactionSwapHook;persistWatermarkHook;uncompactHook;rewindHook;forkHook;mcpServersConfig;forwardedEnv;workspace;workspaceError;workspaceNotes=[];workspaceHook;workspacePreambleSent=!1;formerWorkspace;departureNoteSent=!1;listSessions;logger;transformChain;extensionCommands;extensionCommandsUnsub;pendingClaims=new Map;toolCompletionSeen=new Map;toolCallKind=new cs;filesEditedSeen=new Set;openToolCalls=new Map;agentChangeHandlers=[];retiringGenerationCost;retiringGenerationUsed;rotationLifetimeCost;agentAdvertisedCommands=[];agentAdvertisedModes=[];agentAdvertisedModels=[];agentAdvertisedConfigOptions=[];agentCommandsHandlers=[];agentModesHandlers=[];agentModelsHandlers=[];configOptionsHandlers=[];availableAgentsFn;modelHandlers=[];modeHandlers=[];interactiveHandlers=[];priorityHandlers=[];readStateHandlers=[];usageHandlers=[];cumulativeCost=0;costLedgerProbe;get persistableUsage(){if(!(!this._currentUsage&&!this.cumulativeCost))return{...this._currentUsage??{},...this.cumulativeCost?{cumulativeCost:this.cumulativeCost}:{cumulativeCost:void 0}}}get currentUsage(){if(!this._currentUsage&&!this.cumulativeCost)return;let e=this._currentUsage??{},t=this.cumulativeCost+(e.costAmount??0);return{...e,costAmount:t||void 0,cumulativeCost:void 0}}amendInProgress;inFlightExtensionDispatches=new Map;recentlyTerminal=new Map;pendingTurnNotifiers=new Map;streamBuffer;streamFilePath;constructor(e){if(this.sessionId=e.sessionId??`${ye}${_d()}`,this.cwd=e.cwd,this.workspace=e.workspace,this.workspaceError=e.workspaceError,this.workspaceHook=e.workspaceHook,this.agentId=e.agentId,this.agent=e.agent,this.upstreamSessionId=e.upstreamSessionId,this.agentMeta=e.agentMeta,this.agentCapabilities=e.agentCapabilities,this.agentArgs=e.agentArgs,this.parentSessionId=e.parentSessionId,this.forkedFromSessionId=e.forkedFromSessionId,this.forkedFromMessageId=e.forkedFromMessageId,this.side=e.side,this.forkSynthesisState=e.forkSynthesisState,this.originatingClient=e.originatingClient,this.title=e.title,this.scheduleSynopsisHook=e.scheduleSynopsis,this.scheduleWorkspaceSnapshotHook=e.scheduleWorkspaceSnapshot,this.scheduleCompactionHook=e.scheduleCompaction,this.resolveAgentIdHook=e.resolveAgentId,this.getCompactionStateHook=e.getCompactionState,this.getUpstreamGenerationsHook=e.getUpstreamGenerations,this.getPendingAgentSwapHook=e.getPendingAgentSwap,this.currentModel=e.currentModel,this.currentMode=e.currentMode,this._currentUsage=e.currentUsage,this.cumulativeCost=e.currentUsage?.cumulativeCost??0,e.reloadsUpstreamLedger&&this.armCostLedgerProbe(),e.agentCommands&&e.agentCommands.length>0&&(this.agentAdvertisedCommands=[...e.agentCommands]),e.agentModes&&e.agentModes.length>0&&(this.agentAdvertisedModes=[...e.agentModes]),e.agentModels&&e.agentModels.length>0&&(this.agentAdvertisedModels=[...e.agentModels]),e.agentConfigOptions&&e.agentConfigOptions.length>0&&(this.agentAdvertisedConfigOptions=[...e.agentConfigOptions]),this.idleTimeoutMs=e.idleTimeoutMs??0,this.orphanTimeoutMs=e.orphanTimeoutMs??0,this.idleEventTimeoutMs=e.idleEventTimeoutMs??3e4,this.idleEventTimeoutMs>0&&this.onIdle(t=>t.notifyChain("session.idle",{}),{debounceMs:this.idleEventTimeoutMs}),this.spawnReplacementAgent=e.spawnReplacementAgent,this.mintMcpServersForSwap=e.mintMcpServersForSwap,this.loadExistingAgentSession=e.loadExistingAgentSession,this.clearRollbackBreadcrumbHook=e.clearRollbackBreadcrumbHook,this.onCompactionSwapHook=e.onCompactionSwapHook,this.persistWatermarkHook=e.persistWatermarkHook,this.uncompactHook=e.uncompactHook,this.forkHook=e.forkHook,this.mcpServersConfig=e.mcpServers,this.forwardedEnv=e.forwardedEnv,this.availableAgentsFn=e.availableAgents,this.listSessions=e.listSessions,this.logger=e.logger,this.transformChain=e.transformChain??[],this.extensionCommands=e.extensionCommands,this.extensionCommands&&(this.extensionCommandsUnsub=this.extensionCommands.onChange(()=>{this.closed||this.broadcastMergedCommands()})),e.firstPromptSeeded&&(this._firstPromptSeeded=!0,this._titleSeedPending=!1),e.upstreamRespawned&&(this._upstreamRespawned=!0),this._interactive=e.interactive,this._priority=e.priority,this._lastTurnEndedAt=e.lastTurnEndedAt,this._readAt=e.readAt,this._summarizedThroughEntry=e.summarizedThroughEntry,this.compactionState=e.compactionState,e.compactionState){let t=e.compactionState;(t.status==="requested"||t.status==="running"||t.status==="swap_pending"||t.status==="swap_deferred")&&(t.status==="swap_deferred"?this._liveCompactionPhase={phase:"deferred",attempts:t.attempts}:this._liveCompactionPhase={phase:t.status==="requested"?"started":"iteration",iter:t.iter})}if(e.attentionFlags&&e.attentionFlags.length>0)for(let t of e.attentionFlags)this.attentionFlags.set(`${t.source}::${t.reason}`,t);this.historyStore=e.historyStore,this.historyMaxEntries=e.historyMaxEntries??Tg,this.compactEvery=Math.max(1,Math.floor(this.historyMaxEntries*.2)),this.updatedAt=Date.now(),this.createdAt=e.createdAt??this.updatedAt,this.lastRecordedAt=this.updatedAt,this.resetModelVerb(e.modelVerb),this.wireAgent(this.agent),this.scheduleIdleCheck(),this.notifyChain("session.opened",{})}broadcastMergedCommands(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"available_commands_update",availableCommands:this.mergedAvailableCommands()}})}broadcastAvailableModes(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:this.agentAdvertisedModes}})}broadcastAvailableModels(){let e={sessionUpdate:"_hydra_current_model_update",availableModels:[...this.agentAdvertisedModels]};this.currentModel!==void 0&&this.currentModel.length>0&&(e.currentModel=this.currentModel),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:e})}wireAgent(e,t){this.resetBackgroundTaskLevel(),t?.respawn&&(this._upstreamRespawned=!0),e.connection.onNotification("session/update",n=>{if(this.internalPromptCapture){Yg(this.internalPromptCapture,n);return}this.maybeEmitToolEdges(n),this.runResponseChain(n)}),e.connection.onNotification("_claude/sdkMessage",n=>{this.applyBackgroundTaskLevel(n)}),e.connection.onRequest("session/request_permission",async n=>{let r=await this.runAgentRequestChain("session/request_permission",n),o=xd(r.shortCircuit?n:r.envelope);if(r.shortCircuit)return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:r.payload,sourceWasTransformer:!0}),r.payload;let i=await this.handlePermissionRequest(r.envelope);return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:i,sourceWasTransformer:!1}),i}),typeof e.connection.onOrphanError=="function"&&e.connection.onOrphanError(n=>{this.handleOrphanError(n)}),e.onExit(()=>{this.agent===e&&this.markClosed({deleteRecord:!1})})}handleOrphanError(e){let t=Date.now()-this.lastCancelAt;if(this.lastCancelAt===0||t>s.CANCEL_ERROR_WINDOW_MS){this.logger?.warn(`agent ${this.agentId} sent uncorrelated error frame code=${e.code} message=${e.message}`);return}this.lastCancelAt=0,this.logger?.warn(`agent ${this.agentId} rejected session/cancel code=${e.code} message=${e.message}`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,code:e.code,message:e.message})}async runResponseChain(e,t=new Set,n=0,r="session/update"){let o=e,i=r==="session/update"?this.injectCumulativeCost(e):e,a=`response:${r}`;for(let l=n;l<this.transformChain.length;l++){let p=this.transformChain[l];if(t.has(p.name)||!p.intercepts.has(a))continue;let f=`t_${ho()}`,h;try{h=await p.connection.request("hydra-acp/transformer/message",{token:f,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(m){this.logger?.warn(`transformer ${p.name} error on ${a}: ${m.message}`);continue}let w=h?.action??"continue";if(w==="stop")return;if(w==="processing"){let m=l,g=i,y=new Set(t),k=r;await new Promise(v=>{let S=setTimeout(()=>{this.pendingClaims.delete(f)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:f,transformerName:p.name}),this.runResponseChain(g,new Set([...y,p.name]),m+1,k).then(()=>v()).catch(()=>v()))},ws);typeof S.unref=="function"&&S.unref(),this.pendingClaims.set(f,{resolve:()=>v(),timer:S,transformerName:p.name,method:k,envelope:g,chainIdx:m,originatedBy:y,side:"response"})});return}h?.payload&&typeof h.payload=="object"&&(i=h.payload),t.add(p.name)}if(r!=="session/update")return;this.noteAgentActivity(i);let d=i.update;(cd(d)||this.agentId==="opencode"&&this.opencodeSummary.feed(d))&&this.armRecallFromSelfCompaction();let c=Xg(i);if(c!==null){this.setAgentAdvertisedCommands(c);return}let u=Qg(i);if(u!==null){this.setAgentAdvertisedModes(u);return}if(this.noteModelVerbHint(Da(i.update),"session/update"),this.maybeApplyAgentModel(i)){this.recordAndBroadcast("session/update",i);return}if(this.maybeApplyAgentMode(i)){this.recordAndBroadcast("session/update",i);return}if(this.maybeApplyAgentConfigOption(i)){this.recordAndBroadcast("session/update",this.mergeAgentOptionIntoEnvelope(i));return}if(this.maybeApplyAgentUsage(o)){this.recordAndBroadcast("session/update",i);return}this.maybeApplyAgentSessionInfo(i),this.recordAndBroadcast("session/update",nd(i))}armRecallFromSelfCompaction(){this.armRecallInPlace().catch(e=>{this.logger?.warn(`armRecallInPlace failed: ${e.message}`)})}async armRecallInPlace(){if(!this.historyStore)return;let e=await this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0);if(!(e<=(this._summarizedThroughEntry??0))){if(this._summarizedThroughEntry=e,this.persistWatermarkHook)try{this.persistWatermarkHook(e)}catch(t){this.logger?.warn(`armRecallInPlace: persistWatermarkHook failed: ${t.message}`)}this.broadcastQueueNotification("hydra-acp/context_self_compacted",{sessionId:this.sessionId})}}onAgentChange(e){this.agentChangeHandlers.push(e)}get attachedCount(){return this.clients.size}connectedClients(e){let t=[];for(let n of this.clients.values()){if(e&&n.clientId===e)continue;let r={clientId:n.clientId};n.clientInfo?.name&&(r.name=n.clientInfo.name),n.clientInfo?.version&&(r.version=n.clientInfo.version),t.push(r)}return t}get turnStartedAt(){return this.promptStartedAt}get inUnsolicitedTurn(){return this.unsolicitedTurn!==void 0}get agentPid(){return this.agent.pid}get awaitingInput(){return this.attentionFlags.size>0}async isQuiescedForSwap(){return await this.quiesceBlocker()===void 0}async quiesceBlocker(){if(this.agentTurnInFlight)return"the agent is still working; wait for the current turn to finish, then try again";if(this.unsolicitedTurn!==void 0)return"the agent is part-way through a turn it started by itself; wait for it to finish or interrupt it (^C), then try again";if(this.internalPromptCapture!==void 0)return"hydra is driving the agent right now (compaction seed or transcript injection); this clears by itself, so try again in a moment";if(this.modelChangeInFlight)return"a model change is still settling; try again in a moment";if(this.modeChangeInFlight)return"a mode change is still settling; try again in a moment";let e=this.pendingOneShotBackgroundTasks();if(e.length>0)return`${e.length} background task(s) still running (${e.join(", ")}); a swap would kill the agent process and abandon them. Wait for them to finish, or cancel them, then try again`;let t=await this.openToolCallIdsInHistory();if(t.length>0)return`${t.length} tool call(s) from an earlier turn never reported a result, so the session still reads as busy. ^C closes an abandoned chain; failing that it clears as new history accumulates`}isQuiescedSync(){return!(this.promptInFlight||this.unsolicitedTurn!==void 0||this.modeChangeInFlight||this.modelChangeInFlight)}async swapIntoWorkspace(e){await this.swapUpstream({...e.synopsis!==void 0?{artifact:e.synopsis}:{},note:e.note,framing:"swap",...e.title!==void 0?{title:e.title}:{},tailK:8,tailFloor:4,summarizedThroughEntry:e.historyLength,newCwd:e.cwd,reason:e.workspace!==void 0?"workspace-enter":"workspace-leave"}),this.workspace=e.workspace,e.left!==void 0?(this.formerWorkspace={path:e.left.path,sourceCwd:e.cwd,removed:e.left.removed},this.departureNoteSent=!1):this.formerWorkspace=void 0}async swapUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for swap: ${t}`);if(this.swapInFlight)throw new Error("a swap is already in progress for this session");this.swapInFlight=!0;try{await this.doSwapUpstream(e)}finally{this.swapInFlight=!1}}async doSwapUpstream(e){this.notifyChain("agent.swap",{phase:"pre",previousUpstreamSessionId:this.upstreamSessionId,agentId:this.agentId});let t=this.agentId,n=e.newAgentId??this.agentId,r=n!==this.agentId,o=e.reason!==void 0&&e.reason!=="compaction"?e.reason:r?"agent-swap":"compaction",i=e.newCwd??this.cwd,a=this.agentArgs,d=this.forwardedEnv,c=this.currentModel,u=this.currentMode,l=this.spawnReplacementAgent;if(!l)throw new Error("agent spawning not configured for this session");let p=this.mintMcpServersForSwap?await this.mintMcpServersForSwap(this):this.mcpServersConfig??[],f=await l({agentId:n,cwd:i,agentArgs:a,...d?{forwardedEnv:d}:{},mcpServers:p});if(this.accumulateAndResetCost(),this.cwd=i,this.wireAgent(f.agent,{respawn:!0}),!r){let M=await lt({agent:f.agent,upstreamSessionId:f.upstreamSessionId,persistedModel:c,agentReportedModel:f.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(M.result,"model"),await ut({agent:f.agent,upstreamSessionId:f.upstreamSessionId,persistedMode:u,agentReportedMode:f.initialMode,logger:this.logger})}f.agent.connection.drainBuffered("session/update");let h=[];if(this.historyStore)try{h=await this.historyStore.load(this.sessionId)}catch(M){this.logger?.warn(`swapUpstream: historyStore.load failed: ${M.message}`)}let w=fo({...e.artifact!==void 0?{synopsis:e.artifact}:{},...e.note!==void 0?{note:e.note}:{},...e.framing!==void 0?{framing:e.framing}:{},title:e.title,tail:h,tailK:e.tailK,tailFloor:e.tailFloor,...e.summarizedThroughEntry!==void 0?{watermark:e.summarizedThroughEntry}:{},recallArmed:(e.summarizedThroughEntry??this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("swapUpstream: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};let m,g;try{await f.agent.connection.request("session/prompt",{sessionId:f.upstreamSessionId,prompt:[{type:"text",text:w}]});let M=this.internalPromptCapture;m=M.lastUsed,g=M.lastSize,this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${w.length} toolCalls=${M.toolCalls} thinkingChars=${M.thinkingChars} messageChars=${M.messageChars} used=${M.lastUsed??"?"} size=${M.lastSize??"?"} reply=${JSON.stringify(M.chunks.join("").slice(0,200))}`)}finally{this.internalPromptCapture=void 0}m!==void 0&&(this.maybeApplyAgentUsage({update:{sessionUpdate:"usage_update",used:m,...g!==void 0?{size:g}:{}}}),this.broadcastCurrentUsage());let y=this.upstreamSessionId,k=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let v=this.agent;if(this.agent=f.agent,this.upstreamSessionId=f.upstreamSessionId,this.agentMeta=f.agentMeta,this.agentCapabilities=f.agentCapabilities,this.resetModelVerb(f.modelVerb),r&&(this.agentId=n,this.agentAdvertisedCommands=[],this.currentModel=f.initialModel,this.currentMode=f.initialMode,this.setAgentAdvertisedModels(f.initialModels??[]),this.setAgentAdvertisedModes(f.initialModes??[]),this.agentAdvertisedConfigOptions=f.initialConfigOptions??[]),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream",o,e.runId,m),e.summarizedThroughEntry!==void 0&&this.persistWatermarkHook)try{this.persistWatermarkHook(e.summarizedThroughEntry)}catch(M){this.logger?.warn(`swapUpstream: persistWatermarkHook failed: ${M.message}`)}if(!r&&this.onCompactionSwapHook)try{this.onCompactionSwapHook({previousUpstreamSessionId:y,...k!==void 0?{previousSummarizedThroughEntry:k}:{},...e.runId!==void 0?{runId:e.runId}:{}})}catch(M){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${M.message}`)}let S=await this.retireAgent(v,r?"agent switch":e.reason==="workspace-enter"||e.reason==="workspace-leave"?"workspace move":"compaction swap");this.notifyChain("agent.swap",{phase:"post",previousUpstreamSessionId:y,upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}),r||this.broadcastCompactionPhase({phase:"swapped",...this.title!==void 0?{title:this.title}:{},summarizedThroughEntry:e.summarizedThroughEntry??this._summarizedThroughEntry??0}),r&&this.broadcastAgentSwitch(t,n);let b=S.length>0?`
49
+ `).map(t=>t.trim()).filter(t=>t!=="");return e.length===0?"":e[e.length-1]}var Ng=128,Dg=new Set(["local_bash"]),jg=1e3,Gt=class s{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=ze;modelVerbConfirmed=!1;agentArgs;parentSessionId;forkedFromSessionId;forkedFromMessageId;side;forkSynthesisState;originatingClient;_interactive;get interactive(){return this._interactive}_priority;get priority(){return this._priority}_lastTurnEndedAt;get lastTurnEndedAt(){return this._lastTurnEndedAt}_readAt;get readAt(){return this._readAt}title;_summarizedThroughEntry;get summarizedThroughEntry(){return this._summarizedThroughEntry}set summarizedThroughEntry(e){this._summarizedThroughEntry=e}currentModel;currentMode;compactionState;_currentUsage;updatedAt;createdAt;clients=new Map;historyStore;promptQueue=[];currentEntry;promptInFlight=!1;agentTurnInFlight=!1;swapInFlight=!1;opencodeSummary=new hs;modeChangeInFlight=!1;modelChangeInFlight=!1;queueWriteChain=Promise.resolve();closed=!1;closing=!1;closeInFlight;deleteRecordIntent=!1;closeHandlers=[];titleHandlers=[];scheduleSynopsisHook;scheduleWorkspaceSnapshotHook;scheduleCompactionHook;resolveAgentIdHook;getCompactionStateHook;getUpstreamGenerationsHook;getPendingAgentSwapHook;_liveCompactionPhase;broadcastHandlers=[];lastCancelAt=0;static CANCEL_ERROR_WINDOW_MS=2e3;lastUnsolicitedCancelAt=0;cancelReopenStreak=0;static UNSOLICITED_REOPEN_WINDOW_MS=1e4;static UNSOLICITED_REOPEN_LIMIT=3;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}_titleSeedPending=!0;_upstreamRespawned=!1;promptStartedAt;turnRanTool=!1;unsolicitedTurn;pendingSteerDetach;supersededAutonomousTurn;autonomousSalvage;lastBackgroundTask;toolLabels=new Map;armedTasks=new Map;lastArmedBroadcast;liveBackgroundTasks=new Map;sawBackgroundTaskLevel=!1;sawTurnComplete=!1;appendCount=0;historyMaxEntries;compactEvery;permissionCallbacks=new Map;attentionFlags=new Map;get hasPermissionFlag(){for(let e of this.attentionFlags.values())if(e.source==="daemon"&&e.reason.startsWith("permission:"))return!0;return!1}attentionFlagsChangeHandlers=[];internalPromptCapture;idleTimeoutMs;idleTimer;orphanTimeoutMs;orphanTimer;idleEventTimeoutMs;idleHandlers=[];lastRecordedAt;lastSeq=0;spawnReplacementAgent;mintMcpServersForSwap;loadExistingAgentSession;clearRollbackBreadcrumbHook;onCompactionSwapHook;persistWatermarkHook;uncompactHook;rewindHook;forkHook;mcpServersConfig;forwardedEnv;workspace;workspaceError;workspaceNotes=[];workspaceHook;workspacePreambleSent=!1;formerWorkspace;departureNoteSent=!1;listSessions;logger;transformChain;extensionCommands;extensionCommandsUnsub;pendingClaims=new Map;toolCompletionSeen=new Map;toolCallKind=new cs;filesEditedSeen=new Set;openToolCalls=new Map;agentChangeHandlers=[];retiringGenerationCost;retiringGenerationUsed;rotationLifetimeCost;agentAdvertisedCommands=[];agentAdvertisedModes=[];agentAdvertisedModels=[];agentAdvertisedConfigOptions=[];agentCommandsHandlers=[];agentModesHandlers=[];agentModelsHandlers=[];configOptionsHandlers=[];availableAgentsFn;modelHandlers=[];modeHandlers=[];interactiveHandlers=[];priorityHandlers=[];readStateHandlers=[];usageHandlers=[];cumulativeCost=0;costLedgerProbe;get persistableUsage(){if(!(!this._currentUsage&&!this.cumulativeCost))return{...this._currentUsage??{},...this.cumulativeCost?{cumulativeCost:this.cumulativeCost}:{cumulativeCost:void 0}}}get currentUsage(){if(!this._currentUsage&&!this.cumulativeCost)return;let e=this._currentUsage??{},t=this.cumulativeCost+(e.costAmount??0);return{...e,costAmount:t||void 0,cumulativeCost:void 0}}amendInProgress;inFlightExtensionDispatches=new Map;recentlyTerminal=new Map;pendingTurnNotifiers=new Map;streamBuffer;streamFilePath;constructor(e){if(this.sessionId=e.sessionId??`${ye}${_d()}`,this.cwd=e.cwd,this.workspace=e.workspace,this.workspaceError=e.workspaceError,this.workspaceHook=e.workspaceHook,this.agentId=e.agentId,this.agent=e.agent,this.upstreamSessionId=e.upstreamSessionId,this.agentMeta=e.agentMeta,this.agentCapabilities=e.agentCapabilities,this.agentArgs=e.agentArgs,this.parentSessionId=e.parentSessionId,this.forkedFromSessionId=e.forkedFromSessionId,this.forkedFromMessageId=e.forkedFromMessageId,this.side=e.side,this.forkSynthesisState=e.forkSynthesisState,this.originatingClient=e.originatingClient,this.title=e.title,this.scheduleSynopsisHook=e.scheduleSynopsis,this.scheduleWorkspaceSnapshotHook=e.scheduleWorkspaceSnapshot,this.scheduleCompactionHook=e.scheduleCompaction,this.resolveAgentIdHook=e.resolveAgentId,this.getCompactionStateHook=e.getCompactionState,this.getUpstreamGenerationsHook=e.getUpstreamGenerations,this.getPendingAgentSwapHook=e.getPendingAgentSwap,this.currentModel=e.currentModel,this.currentMode=e.currentMode,this._currentUsage=e.currentUsage,this.cumulativeCost=e.currentUsage?.cumulativeCost??0,e.reloadsUpstreamLedger&&this.armCostLedgerProbe(),e.agentCommands&&e.agentCommands.length>0&&(this.agentAdvertisedCommands=[...e.agentCommands]),e.agentModes&&e.agentModes.length>0&&(this.agentAdvertisedModes=[...e.agentModes]),e.agentModels&&e.agentModels.length>0&&(this.agentAdvertisedModels=[...e.agentModels]),e.agentConfigOptions&&e.agentConfigOptions.length>0&&(this.agentAdvertisedConfigOptions=[...e.agentConfigOptions]),this.idleTimeoutMs=e.idleTimeoutMs??0,this.orphanTimeoutMs=e.orphanTimeoutMs??0,this.idleEventTimeoutMs=e.idleEventTimeoutMs??3e4,this.idleEventTimeoutMs>0&&this.onIdle(t=>t.notifyChain("session.idle",{}),{debounceMs:this.idleEventTimeoutMs}),this.spawnReplacementAgent=e.spawnReplacementAgent,this.mintMcpServersForSwap=e.mintMcpServersForSwap,this.loadExistingAgentSession=e.loadExistingAgentSession,this.clearRollbackBreadcrumbHook=e.clearRollbackBreadcrumbHook,this.onCompactionSwapHook=e.onCompactionSwapHook,this.persistWatermarkHook=e.persistWatermarkHook,this.uncompactHook=e.uncompactHook,this.forkHook=e.forkHook,this.mcpServersConfig=e.mcpServers,this.forwardedEnv=e.forwardedEnv,this.availableAgentsFn=e.availableAgents,this.listSessions=e.listSessions,this.logger=e.logger,this.transformChain=e.transformChain??[],this.extensionCommands=e.extensionCommands,this.extensionCommands&&(this.extensionCommandsUnsub=this.extensionCommands.onChange(()=>{this.closed||this.broadcastMergedCommands()})),e.firstPromptSeeded&&(this._firstPromptSeeded=!0,this._titleSeedPending=!1),e.upstreamRespawned&&(this._upstreamRespawned=!0),this._interactive=e.interactive,this._priority=e.priority,this._lastTurnEndedAt=e.lastTurnEndedAt,this._readAt=e.readAt,this._summarizedThroughEntry=e.summarizedThroughEntry,this.compactionState=e.compactionState,e.compactionState){let t=e.compactionState;(t.status==="requested"||t.status==="running"||t.status==="swap_pending"||t.status==="swap_deferred")&&(t.status==="swap_deferred"?this._liveCompactionPhase={phase:"deferred",attempts:t.attempts}:this._liveCompactionPhase={phase:t.status==="requested"?"started":"iteration",iter:t.iter})}if(e.attentionFlags&&e.attentionFlags.length>0)for(let t of e.attentionFlags)this.attentionFlags.set(`${t.source}::${t.reason}`,t);this.historyStore=e.historyStore,this.historyMaxEntries=e.historyMaxEntries??Tg,this.compactEvery=Math.max(1,Math.floor(this.historyMaxEntries*.2)),this.updatedAt=Date.now(),this.createdAt=e.createdAt??this.updatedAt,this.lastRecordedAt=this.updatedAt,this.resetModelVerb(e.modelVerb),this.wireAgent(this.agent),this.scheduleIdleCheck(),this.notifyChain("session.opened",{})}broadcastMergedCommands(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"available_commands_update",availableCommands:this.mergedAvailableCommands()}})}broadcastAvailableModes(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:this.agentAdvertisedModes}})}broadcastAvailableModels(){let e={sessionUpdate:"_hydra_current_model_update",availableModels:[...this.agentAdvertisedModels]};this.currentModel!==void 0&&this.currentModel.length>0&&(e.currentModel=this.currentModel),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:e})}wireAgent(e,t){this.resetBackgroundTaskLevel(),t?.respawn&&(this._upstreamRespawned=!0),e.connection.onNotification("session/update",n=>{if(this.internalPromptCapture){Xg(this.internalPromptCapture,n);return}this.maybeEmitToolEdges(n),this.runResponseChain(n)}),e.connection.onNotification("_claude/sdkMessage",n=>{this.applyBackgroundTaskLevel(n)}),e.connection.onRequest("session/request_permission",async n=>{let r=await this.runAgentRequestChain("session/request_permission",n),o=xd(r.shortCircuit?n:r.envelope);if(r.shortCircuit)return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:r.payload,sourceWasTransformer:!0}),r.payload;let i=await this.handlePermissionRequest(r.envelope);return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:i,sourceWasTransformer:!1}),i}),typeof e.connection.onOrphanError=="function"&&e.connection.onOrphanError(n=>{this.handleOrphanError(n)}),e.onExit(()=>{this.agent===e&&this.markClosed({deleteRecord:!1})})}handleOrphanError(e){let t=Date.now()-this.lastCancelAt;if(this.lastCancelAt===0||t>s.CANCEL_ERROR_WINDOW_MS){this.logger?.warn(`agent ${this.agentId} sent uncorrelated error frame code=${e.code} message=${e.message}`);return}this.lastCancelAt=0,this.logger?.warn(`agent ${this.agentId} rejected session/cancel code=${e.code} message=${e.message}`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,code:e.code,message:e.message})}async runResponseChain(e,t=new Set,n=0,r="session/update"){let o=e,i=r==="session/update"?this.injectCumulativeCost(e):e,a=`response:${r}`;for(let l=n;l<this.transformChain.length;l++){let p=this.transformChain[l];if(t.has(p.name)||!p.intercepts.has(a))continue;let f=`t_${ho()}`,h;try{h=await p.connection.request("hydra-acp/transformer/message",{token:f,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(m){this.logger?.warn(`transformer ${p.name} error on ${a}: ${m.message}`);continue}let w=h?.action??"continue";if(w==="stop")return;if(w==="processing"){let m=l,g=i,y=new Set(t),k=r;await new Promise(v=>{let S=setTimeout(()=>{this.pendingClaims.delete(f)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:f,transformerName:p.name}),this.runResponseChain(g,new Set([...y,p.name]),m+1,k).then(()=>v()).catch(()=>v()))},ws);typeof S.unref=="function"&&S.unref(),this.pendingClaims.set(f,{resolve:()=>v(),timer:S,transformerName:p.name,method:k,envelope:g,chainIdx:m,originatedBy:y,side:"response"})});return}h?.payload&&typeof h.payload=="object"&&(i=h.payload),t.add(p.name)}if(r!=="session/update")return;this.noteAgentActivity(i);let d=i.update;(cd(d)||this.agentId==="opencode"&&this.opencodeSummary.feed(d))&&this.armRecallFromSelfCompaction();let c=Zg(i);if(c!==null){this.setAgentAdvertisedCommands(c);return}let u=Yg(i);if(u!==null){this.setAgentAdvertisedModes(u);return}if(this.noteModelVerbHint(Da(i.update),"session/update"),this.maybeApplyAgentModel(i)){this.recordAndBroadcast("session/update",i);return}if(this.maybeApplyAgentMode(i)){this.recordAndBroadcast("session/update",i);return}if(this.maybeApplyAgentConfigOption(i)){this.recordAndBroadcast("session/update",this.mergeAgentOptionIntoEnvelope(i));return}if(this.maybeApplyAgentUsage(o)){this.recordAndBroadcast("session/update",i);return}this.maybeApplyAgentSessionInfo(i),this.recordAndBroadcast("session/update",nd(i))}armRecallFromSelfCompaction(){this.armRecallInPlace().catch(e=>{this.logger?.warn(`armRecallInPlace failed: ${e.message}`)})}async armRecallInPlace(){if(!this.historyStore)return;let e=await this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0);if(!(e<=(this._summarizedThroughEntry??0))){if(this._summarizedThroughEntry=e,this.persistWatermarkHook)try{this.persistWatermarkHook(e)}catch(t){this.logger?.warn(`armRecallInPlace: persistWatermarkHook failed: ${t.message}`)}this.broadcastQueueNotification("hydra-acp/context_self_compacted",{sessionId:this.sessionId})}}onAgentChange(e){this.agentChangeHandlers.push(e)}get attachedCount(){return this.clients.size}connectedClients(e){let t=[];for(let n of this.clients.values()){if(e&&n.clientId===e)continue;let r={clientId:n.clientId};n.clientInfo?.name&&(r.name=n.clientInfo.name),n.clientInfo?.version&&(r.version=n.clientInfo.version),t.push(r)}return t}get turnStartedAt(){return this.promptStartedAt}get inUnsolicitedTurn(){return this.unsolicitedTurn!==void 0}get agentPid(){return this.agent.pid}get awaitingInput(){return this.attentionFlags.size>0}async isQuiescedForSwap(){return await this.quiesceBlocker()===void 0}async quiesceBlocker(){if(this.agentTurnInFlight)return"the agent is still working; wait for the current turn to finish, then try again";if(this.unsolicitedTurn!==void 0)return"the agent is part-way through a turn it started by itself; wait for it to finish or interrupt it (^C), then try again";if(this.internalPromptCapture!==void 0)return"hydra is driving the agent right now (compaction seed or transcript injection); this clears by itself, so try again in a moment";if(this.modelChangeInFlight)return"a model change is still settling; try again in a moment";if(this.modeChangeInFlight)return"a mode change is still settling; try again in a moment";let e=this.pendingOneShotBackgroundTasks();if(e.length>0)return`${e.length} background task(s) still running (${e.join(", ")}); a swap would kill the agent process and abandon them. Wait for them to finish, or cancel them, then try again`;let t=await this.openToolCallIdsInHistory();if(t.length>0)return`${t.length} tool call(s) from an earlier turn never reported a result, so the session still reads as busy. ^C closes an abandoned chain; failing that it clears as new history accumulates`}isQuiescedSync(){return!(this.promptInFlight||this.unsolicitedTurn!==void 0||this.modeChangeInFlight||this.modelChangeInFlight)}async swapIntoWorkspace(e){await this.swapUpstream({...e.synopsis!==void 0?{artifact:e.synopsis}:{},note:e.note,framing:"swap",...e.title!==void 0?{title:e.title}:{},tailK:8,tailFloor:4,summarizedThroughEntry:e.historyLength,newCwd:e.cwd,reason:e.workspace!==void 0?"workspace-enter":"workspace-leave"}),this.workspace=e.workspace,e.left!==void 0?(this.formerWorkspace={path:e.left.path,sourceCwd:e.cwd,removed:e.left.removed},this.departureNoteSent=!1):this.formerWorkspace=void 0}async swapUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for swap: ${t}`);if(this.swapInFlight)throw new Error("a swap is already in progress for this session");this.swapInFlight=!0;try{await this.doSwapUpstream(e)}finally{this.swapInFlight=!1}}async doSwapUpstream(e){this.notifyChain("agent.swap",{phase:"pre",previousUpstreamSessionId:this.upstreamSessionId,agentId:this.agentId});let t=this.agentId,n=e.newAgentId??this.agentId,r=n!==this.agentId,o=e.reason!==void 0&&e.reason!=="compaction"?e.reason:r?"agent-swap":"compaction",i=e.newCwd??this.cwd,a=this.agentArgs,d=this.forwardedEnv,c=this.currentModel,u=this.currentMode,l=this.spawnReplacementAgent;if(!l)throw new Error("agent spawning not configured for this session");let p=this.mintMcpServersForSwap?await this.mintMcpServersForSwap(this):this.mcpServersConfig??[],f=await l({agentId:n,cwd:i,agentArgs:a,...d?{forwardedEnv:d}:{},mcpServers:p});if(this.accumulateAndResetCost(),this.cwd=i,this.wireAgent(f.agent,{respawn:!0}),!r){let M=await lt({agent:f.agent,upstreamSessionId:f.upstreamSessionId,persistedModel:c,agentReportedModel:f.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(M.result,"model"),await ut({agent:f.agent,upstreamSessionId:f.upstreamSessionId,persistedMode:u,agentReportedMode:f.initialMode,logger:this.logger})}f.agent.connection.drainBuffered("session/update");let h=[];if(this.historyStore)try{h=await this.historyStore.load(this.sessionId)}catch(M){this.logger?.warn(`swapUpstream: historyStore.load failed: ${M.message}`)}let w=fo({...e.artifact!==void 0?{synopsis:e.artifact}:{},...e.note!==void 0?{note:e.note}:{},...e.framing!==void 0?{framing:e.framing}:{},title:e.title,tail:h,tailK:e.tailK,tailFloor:e.tailFloor,...e.summarizedThroughEntry!==void 0?{watermark:e.summarizedThroughEntry}:{},recallArmed:(e.summarizedThroughEntry??this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("swapUpstream: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};let m,g;try{await f.agent.connection.request("session/prompt",{sessionId:f.upstreamSessionId,prompt:[{type:"text",text:w}]});let M=this.internalPromptCapture;m=M.lastUsed,g=M.lastSize,this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${w.length} toolCalls=${M.toolCalls} thinkingChars=${M.thinkingChars} messageChars=${M.messageChars} used=${M.lastUsed??"?"} size=${M.lastSize??"?"} reply=${JSON.stringify(M.chunks.join("").slice(0,200))}`)}finally{this.internalPromptCapture=void 0}m!==void 0&&(this.maybeApplyAgentUsage({update:{sessionUpdate:"usage_update",used:m,...g!==void 0?{size:g}:{}}}),this.broadcastCurrentUsage());let y=this.upstreamSessionId,k=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let v=this.agent;if(this.agent=f.agent,this.upstreamSessionId=f.upstreamSessionId,this.agentMeta=f.agentMeta,this.agentCapabilities=f.agentCapabilities,this.resetModelVerb(f.modelVerb),r&&(this.agentId=n,this.agentAdvertisedCommands=[],this.currentModel=f.initialModel,this.currentMode=f.initialMode,this.setAgentAdvertisedModels(f.initialModels??[]),this.setAgentAdvertisedModes(f.initialModes??[]),this.agentAdvertisedConfigOptions=f.initialConfigOptions??[]),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream",o,e.runId,m),e.summarizedThroughEntry!==void 0&&this.persistWatermarkHook)try{this.persistWatermarkHook(e.summarizedThroughEntry)}catch(M){this.logger?.warn(`swapUpstream: persistWatermarkHook failed: ${M.message}`)}if(!r&&this.onCompactionSwapHook)try{this.onCompactionSwapHook({previousUpstreamSessionId:y,...k!==void 0?{previousSummarizedThroughEntry:k}:{},...e.runId!==void 0?{runId:e.runId}:{}})}catch(M){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${M.message}`)}let S=await this.retireAgent(v,r?"agent switch":e.reason==="workspace-enter"||e.reason==="workspace-leave"?"workspace move":"compaction swap");this.notifyChain("agent.swap",{phase:"post",previousUpstreamSessionId:y,upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}),r||this.broadcastCompactionPhase({phase:"swapped",...this.title!==void 0?{title:this.title}:{},summarizedThroughEntry:e.summarizedThroughEntry??this._summarizedThroughEntry??0}),r&&this.broadcastAgentSwitch(t,n);let b=S.length>0?`
50
50
  Stopped ${S.length} background task(s) with the previous agent: ${S.join(", ")}. Re-arm anything still needed.
51
51
  `:"",R=(e.reason==="workspace-enter"||e.reason==="workspace-leave"?"":r?`
52
52
  Switched to ${n}.
53
53
  `:`
54
54
  Compaction completed.
55
- `)+b,T=R===""?void 0:R;if(T!==void 0){let M=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:T},_meta:{"hydra-acp":{synthetic:!0}}}});for(let j of this.clients.values())j.connection.notify("session/update",M).catch(()=>{})}this.updatedAt=Date.now()}async rollbackToUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for rollback: ${t}`);let n=this.loadExistingAgentSession;if(!n)throw new Error("loadExistingAgentSession not configured for this session");let r=this.agentId,o=this.cwd,i=this.agentArgs,a=this.forwardedEnv,d=this.currentModel,c=this.currentMode,u=await n(e.previousUpstreamSessionId,{agentId:r,cwd:o,agentArgs:i,...a?{forwardedEnv:a}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(u.agent,{respawn:!0});let l=await lt({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedModel:d,agentReportedModel:u.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(l.result,"model"),await ut({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedMode:c,agentReportedMode:u.initialMode,logger:this.logger}),u.agent.connection.drainBuffered("session/update");let p=this.agent;this.agent=u.agent,this.upstreamSessionId=u.upstreamSessionId,this.agentMeta=u.agentMeta,this.agentCapabilities=u.agentCapabilities,this.resetModelVerb(u.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(p,"rollback"),this._summarizedThroughEntry=e.previousSummarizedThroughEntry,this.broadcastCompactionPhase({phase:"rolled_back",summarizedThroughEntry:e.previousSummarizedThroughEntry??0}),this.notifyAgentChange("rollbackToUpstream","rollback"),this.updatedAt=Date.now()}async reloadUpstreamAfterAgentLoss(){let e=this.loadExistingAgentSession;if(!e)throw new Error("loadExistingAgentSession not configured for this session");let t=this.currentModel,n=this.currentMode,r=await e(this.upstreamSessionId,{agentId:this.agentId,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(r.agent,{respawn:!0});let o=await lt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:t,agentReportedModel:r.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(o.result,"model"),await ut({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:n,agentReportedMode:r.initialMode,logger:this.logger}),r.agent.connection.drainBuffered("session/update");let i=this.agent;this.agent=r.agent,this.upstreamSessionId=r.upstreamSessionId,this.agentMeta=r.agentMeta,this.agentCapabilities=r.agentCapabilities,this.resetModelVerb(r.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(i,"upstream-lost"),this.notifyAgentChange("reloadUpstreamAfterAgentLoss"),this.updatedAt=Date.now()}async openToolCallIdsInHistory(e=Cg){if(!this.historyStore)return[];let t=await this.historyStore.load(this.sessionId),n=t.length>e?t.slice(-e):t,r=new Set,o=new Set;for(let i of n){let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate,u=typeof d.toolCallId=="string"?d.toolCallId:void 0;if(!u)continue;let l=d.status;c==="tool_call"&&r.add(u),(c==="tool_call"||c==="tool_call_update")&&(l==="completed"||l==="failed")&&o.add(u)}return[...r].filter(i=>!o.has(i))}async getHistorySnapshot(e="inline",t){return this.historyStore?this.historyStore.load(this.sessionId,{tools:e,...t!==void 0?{maxEntries:t}:{}}).catch(()=>[]):[]}async*iterRecallNewestFirst(){this.historyStore&&(yield*this.historyStore.iterRecallNewestFirst(this.sessionId))}async getRecallTotalCount(){return this.historyStore?this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0):0}async sliceRecallHistory(e,t){return this.historyStore?(await this.historyStore.rangeSlice(this.sessionId,e,t).catch(()=>[])).map(r=>r.entry):[]}onBroadcast(e){return this.broadcastHandlers.push(e),()=>{let t=this.broadcastHandlers.indexOf(e);t>=0&&this.broadcastHandlers.splice(t,1)}}broadcastClientUpdate(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:e});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}broadcastCompactionPhase(e){let t=e.phase;t==="swapped"||t==="failed"||t==="rolled_back"?this._liveCompactionPhase=void 0:this._liveCompactionPhase=e;let n=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_compaction",...e}});for(let r of this.broadcastHandlers)try{r({method:"session/update",params:n,recordedAt:Date.now()})}catch{}for(let r of this.clients.values())r.connection.notify("session/update",n).catch(()=>{});this.notifyChain("compaction",{...e})}broadcastWorkspacePhase(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_workspace",...e}});for(let n of this.broadcastHandlers)try{n({method:"session/update",params:t,recordedAt:Date.now()})}catch{}for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{});this.notifyChain("workspace",{...e})}broadcastSyntheticText(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:e},_meta:{"hydra-acp":{synthetic:!0}}}});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}attach(e,t,n={}){if(this.closed)throw fe(new Error("session is closed"),x.SessionNotFound);if(this.clients.has(e.clientId))throw fe(new Error(`client ${e.clientId} is already attached`),x.AlreadyAttached);return this.clients.set(e.clientId,e),this.cancelOrphanTimer(),this.updatedAt=Date.now(),t==="none"?Promise.resolve({entries:[],appliedPolicy:t}):t==="pending_only"?Promise.resolve({entries:this.buildStateSnapshotReplay(),appliedPolicy:t}):this.loadReplay(t,n)}async loadReplay(e,t){let n=t.toolContent??"inline",r=n==="inline"&&!t.raw&&this.historyStore!==void 0,o=async u=>{if(t.raw)return u;let l=ds(u);return r&&this.historyStore?this.historyStore.hydrate(this.sessionId,l):l},i=t.historyLimit===0?1/0:t.historyLimit??this.historyMaxEntries,a=Lt(await this.getHistorySnapshot(r?"references":n,i===1/0?1/0:i*2),this.side),d=eh(a.filter(u=>!In(u.method,u.params)),i),c=this.buildStateSnapshotReplay();if(e==="after_message"){let u=t.afterSeq!==void 0?th(d,t.afterSeq):t.afterMessageId?nh(d,t.afterMessageId):-1;return u<0?{entries:[...c,...await o(d)],appliedPolicy:"full"}:{entries:[...c,...await o(d.slice(u+1))],appliedPolicy:"after_message"}}return{entries:[...c,...await o(d)],appliedPolicy:"full"}}buildStateSnapshotReplay(){let e=[],t=this.sessionId,n=Date.now();if(this.title!==void 0&&this.title.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"session_info_update",title:this.title}},recordedAt:n}),this.currentModel!==void 0&&this.currentModel.length>0||this.agentAdvertisedModels.length>0){let o={sessionUpdate:"_hydra_current_model_update"};this.currentModel!==void 0&&this.currentModel.length>0&&(o.currentModel=this.currentModel),this.agentAdvertisedModels.length>0&&(o.availableModels=[...this.agentAdvertisedModels]),e.push({method:"session/update",params:{sessionId:t,update:o},recordedAt:n})}this.currentMode!==void 0&&this.currentMode.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"current_mode_update",currentModeId:this.currentMode}},recordedAt:n});let r=this.mergedAvailableCommands();if(r.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_commands_update",availableCommands:r}},recordedAt:n}),this.agentAdvertisedModes.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:[...this.agentAdvertisedModes]}},recordedAt:n}),this.currentUsage!==void 0){let o=this.currentUsage,i={sessionUpdate:"usage_update"};if(typeof o.used=="number"&&(i.used=o.used),typeof o.size=="number"&&(i.size=o.size),typeof o.costAmount=="number"||typeof o.costCurrency=="string"){let a={};typeof o.costAmount=="number"&&(a.amount=o.costAmount),typeof o.costCurrency=="string"&&(a.currency=o.costCurrency),i.cost=a}Object.keys(i).length>1&&e.push({method:"session/update",params:{sessionId:t,update:i},recordedAt:n})}return this._liveCompactionPhase!==void 0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_compaction",...this._liveCompactionPhase}},recordedAt:n}),e}replayPendingPermissions(e){for(let t of this.attentionFlags.values()){if(t.source!=="daemon"||!t.reason.startsWith("permission:"))continue;let n=t.reason.slice(11),r=this.permissionCallbacks.get(n);r&&r(e)}}detach(e){let t=this.clients.get(e);t&&(this.clients.delete(e),this.updatedAt=Date.now(),this.scheduleOrphanCheck(),this.broadcastClientDisconnected(t))}broadcastClientDisconnected(e){let t={clientId:e.clientId};e.clientInfo?.name&&(t.name=e.clientInfo.name),e.clientInfo?.version&&(t.version=e.clientInfo.version);let n={sessionUpdate:"client_disconnected",client:t,timestamp:new Date().toISOString()};for(let r of this.clients.values())r.connection.notify("session/update",{sessionId:this.sessionId,update:n}).catch(()=>{})}reportIsolationBreach(e,t){let n=this.workspace;if(n===void 0){let r=this.formerWorkspace;r!==void 0&&ys(e,r.path)&&(this.logger?.warn?.(`STALE WORKSPACE WRITE on session ${this.sessionId}: the agent wrote ${e}, which is inside the workspace this session already left. That work will not reach ${r.sourceCwd}.`),this.notifyChain("workspace.staleWrite",{path:e,formerWorkspacePath:r.path,sourceCwd:r.sourceCwd,toolCallId:t}));return}bd(e,n.sourceCwd,n.path)&&(this.logger?.warn?.(`ISOLATION BREACH on session ${this.sessionId}: the agent wrote ${e}, which is in the source tree ${n.sourceCwd}, not its workspace ${n.path}. The user's checkout has been modified.`),this.notifyChain("workspace.breach",{path:e,sourceCwd:n.sourceCwd,workspacePath:n.path,toolCallId:t}))}applyDepartedPromptRewrite(e){let t=this.formerWorkspace;if(t===void 0)return e;let n=!1,r=Ed(e,o=>go(o,t.path)?(n=!0,po(o,t.path,t.sourceCwd).text):o);if(!this.departureNoteSent||n){let o=kd({sourceCwd:t.sourceCwd,formerWorkspacePath:t.path,removed:t.removed});r=yo(r,`${o}
55
+ `)+b,T=R===""?void 0:R;if(T!==void 0){let M=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:T},_meta:{"hydra-acp":{synthetic:!0}}}});for(let H of this.clients.values())H.connection.notify("session/update",M).catch(()=>{})}this.updatedAt=Date.now()}async rollbackToUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for rollback: ${t}`);let n=this.loadExistingAgentSession;if(!n)throw new Error("loadExistingAgentSession not configured for this session");let r=this.agentId,o=this.cwd,i=this.agentArgs,a=this.forwardedEnv,d=this.currentModel,c=this.currentMode,u=await n(e.previousUpstreamSessionId,{agentId:r,cwd:o,agentArgs:i,...a?{forwardedEnv:a}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(u.agent,{respawn:!0});let l=await lt({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedModel:d,agentReportedModel:u.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(l.result,"model"),await ut({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedMode:c,agentReportedMode:u.initialMode,logger:this.logger}),u.agent.connection.drainBuffered("session/update");let p=this.agent;this.agent=u.agent,this.upstreamSessionId=u.upstreamSessionId,this.agentMeta=u.agentMeta,this.agentCapabilities=u.agentCapabilities,this.resetModelVerb(u.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(p,"rollback"),this._summarizedThroughEntry=e.previousSummarizedThroughEntry,this.broadcastCompactionPhase({phase:"rolled_back",summarizedThroughEntry:e.previousSummarizedThroughEntry??0}),this.notifyAgentChange("rollbackToUpstream","rollback"),this.updatedAt=Date.now()}async reloadUpstreamAfterAgentLoss(){let e=this.loadExistingAgentSession;if(!e)throw new Error("loadExistingAgentSession not configured for this session");let t=this.currentModel,n=this.currentMode,r=await e(this.upstreamSessionId,{agentId:this.agentId,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(r.agent,{respawn:!0});let o=await lt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:t,agentReportedModel:r.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(o.result,"model"),await ut({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:n,agentReportedMode:r.initialMode,logger:this.logger}),r.agent.connection.drainBuffered("session/update");let i=this.agent;this.agent=r.agent,this.upstreamSessionId=r.upstreamSessionId,this.agentMeta=r.agentMeta,this.agentCapabilities=r.agentCapabilities,this.resetModelVerb(r.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(i,"upstream-lost"),this.notifyAgentChange("reloadUpstreamAfterAgentLoss"),this.updatedAt=Date.now()}async openToolCallIdsInHistory(e=Cg){if(!this.historyStore)return[];let t=await this.historyStore.load(this.sessionId),n=t.length>e?t.slice(-e):t,r=new Set,o=new Set;for(let i of n){let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate,u=typeof d.toolCallId=="string"?d.toolCallId:void 0;if(!u)continue;let l=d.status;c==="tool_call"&&r.add(u),(c==="tool_call"||c==="tool_call_update")&&(l==="completed"||l==="failed")&&o.add(u)}return[...r].filter(i=>!o.has(i))}async getHistorySnapshot(e="inline",t){return this.historyStore?this.historyStore.load(this.sessionId,{tools:e,...t!==void 0?{maxEntries:t}:{}}).catch(()=>[]):[]}async*iterRecallNewestFirst(){this.historyStore&&(yield*this.historyStore.iterRecallNewestFirst(this.sessionId))}async getRecallTotalCount(){return this.historyStore?this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0):0}async sliceRecallHistory(e,t){return this.historyStore?(await this.historyStore.rangeSlice(this.sessionId,e,t).catch(()=>[])).map(r=>r.entry):[]}onBroadcast(e){return this.broadcastHandlers.push(e),()=>{let t=this.broadcastHandlers.indexOf(e);t>=0&&this.broadcastHandlers.splice(t,1)}}broadcastClientUpdate(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:e});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}broadcastCompactionPhase(e){let t=e.phase;t==="swapped"||t==="failed"||t==="rolled_back"?this._liveCompactionPhase=void 0:this._liveCompactionPhase=e;let n=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_compaction",...e}});for(let r of this.broadcastHandlers)try{r({method:"session/update",params:n,recordedAt:Date.now()})}catch{}for(let r of this.clients.values())r.connection.notify("session/update",n).catch(()=>{});this.notifyChain("compaction",{...e})}broadcastWorkspacePhase(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_workspace",...e}});for(let n of this.broadcastHandlers)try{n({method:"session/update",params:t,recordedAt:Date.now()})}catch{}for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{});this.notifyChain("workspace",{...e})}broadcastSyntheticText(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:e},_meta:{"hydra-acp":{synthetic:!0}}}});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}attach(e,t,n={}){if(this.closed)throw fe(new Error("session is closed"),x.SessionNotFound);if(this.clients.has(e.clientId))throw fe(new Error(`client ${e.clientId} is already attached`),x.AlreadyAttached);return this.clients.set(e.clientId,e),this.cancelOrphanTimer(),this.updatedAt=Date.now(),t==="none"?Promise.resolve({entries:[],appliedPolicy:t}):t==="pending_only"?Promise.resolve({entries:this.buildStateSnapshotReplay(),appliedPolicy:t}):this.loadReplay(t,n)}async loadReplay(e,t){let n=t.toolContent??"inline",r=n==="inline"&&!t.raw&&this.historyStore!==void 0,o=async u=>{if(t.raw)return u;let l=ds(u);return r&&this.historyStore?this.historyStore.hydrate(this.sessionId,l):l},i=t.historyLimit===0?1/0:t.historyLimit??this.historyMaxEntries,a=Lt(await this.getHistorySnapshot(r?"references":n,i===1/0?1/0:i*2),this.side),d=th(a.filter(u=>!In(u.method,u.params)),i),c=this.buildStateSnapshotReplay();if(e==="after_message"){let u=t.afterSeq!==void 0?nh(d,t.afterSeq):t.afterMessageId?sh(d,t.afterMessageId):-1;return u<0?{entries:[...c,...await o(d)],appliedPolicy:"full"}:{entries:[...c,...await o(d.slice(u+1))],appliedPolicy:"after_message"}}return{entries:[...c,...await o(d)],appliedPolicy:"full"}}buildStateSnapshotReplay(){let e=[],t=this.sessionId,n=Date.now();if(this.title!==void 0&&this.title.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"session_info_update",title:this.title}},recordedAt:n}),this.currentModel!==void 0&&this.currentModel.length>0||this.agentAdvertisedModels.length>0){let o={sessionUpdate:"_hydra_current_model_update"};this.currentModel!==void 0&&this.currentModel.length>0&&(o.currentModel=this.currentModel),this.agentAdvertisedModels.length>0&&(o.availableModels=[...this.agentAdvertisedModels]),e.push({method:"session/update",params:{sessionId:t,update:o},recordedAt:n})}this.currentMode!==void 0&&this.currentMode.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"current_mode_update",currentModeId:this.currentMode}},recordedAt:n});let r=this.mergedAvailableCommands();if(r.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_commands_update",availableCommands:r}},recordedAt:n}),this.agentAdvertisedModes.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:[...this.agentAdvertisedModes]}},recordedAt:n}),this.currentUsage!==void 0){let o=this.currentUsage,i={sessionUpdate:"usage_update"};if(typeof o.used=="number"&&(i.used=o.used),typeof o.size=="number"&&(i.size=o.size),typeof o.costAmount=="number"||typeof o.costCurrency=="string"){let a={};typeof o.costAmount=="number"&&(a.amount=o.costAmount),typeof o.costCurrency=="string"&&(a.currency=o.costCurrency),i.cost=a}Object.keys(i).length>1&&e.push({method:"session/update",params:{sessionId:t,update:i},recordedAt:n})}return this._liveCompactionPhase!==void 0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_compaction",...this._liveCompactionPhase}},recordedAt:n}),e}replayPendingPermissions(e){for(let t of this.attentionFlags.values()){if(t.source!=="daemon"||!t.reason.startsWith("permission:"))continue;let n=t.reason.slice(11),r=this.permissionCallbacks.get(n);r&&r(e)}}detach(e){let t=this.clients.get(e);t&&(this.clients.delete(e),this.updatedAt=Date.now(),this.scheduleOrphanCheck(),this.broadcastClientDisconnected(t))}broadcastClientDisconnected(e){let t={clientId:e.clientId};e.clientInfo?.name&&(t.name=e.clientInfo.name),e.clientInfo?.version&&(t.version=e.clientInfo.version);let n={sessionUpdate:"client_disconnected",client:t,timestamp:new Date().toISOString()};for(let r of this.clients.values())r.connection.notify("session/update",{sessionId:this.sessionId,update:n}).catch(()=>{})}reportIsolationBreach(e,t){let n=this.workspace;if(n===void 0){let r=this.formerWorkspace;r!==void 0&&ys(e,r.path)&&(this.logger?.warn?.(`STALE WORKSPACE WRITE on session ${this.sessionId}: the agent wrote ${e}, which is inside the workspace this session already left. That work will not reach ${r.sourceCwd}.`),this.notifyChain("workspace.staleWrite",{path:e,formerWorkspacePath:r.path,sourceCwd:r.sourceCwd,toolCallId:t}));return}bd(e,n.sourceCwd,n.path)&&(this.logger?.warn?.(`ISOLATION BREACH on session ${this.sessionId}: the agent wrote ${e}, which is in the source tree ${n.sourceCwd}, not its workspace ${n.path}. The user's checkout has been modified.`),this.notifyChain("workspace.breach",{path:e,sourceCwd:n.sourceCwd,workspacePath:n.path,toolCallId:t}))}applyDepartedPromptRewrite(e){let t=this.formerWorkspace;if(t===void 0)return e;let n=!1,r=Ed(e,o=>go(o,t.path)?(n=!0,po(o,t.path,t.sourceCwd).text):o);if(!this.departureNoteSent||n){let o=kd({sourceCwd:t.sourceCwd,formerWorkspacePath:t.path,removed:t.removed});r=yo(r,`${o}
56
56
 
57
57
  `),this.departureNoteSent=!0}return r}applyWorkspacePromptRewrite(e){let t=this.workspace;if(t===void 0)return this.applyDepartedPromptRewrite(e);let n=!1,r=Ed(e,i=>go(i,t.sourceCwd)?(n=!0,po(i,t.sourceCwd,t.path).text):i);if(!this.workspacePreambleSent||n){let i=vd({workspacePath:t.path,sourceCwd:t.sourceCwd,notes:this.workspaceNotes,...this.workspacePreambleSent?{reassert:!0}:{}});r=yo(r,`${i}
58
58
 
59
- `),this.workspacePreambleSent=!0}return r}async prompt(e,t,n,r){let o=this.clients.get(e);if(!o)throw fe(new Error("client not attached"),x.SessionNotFound);if(this.closing)throw fe(new Error("session is closing; new prompts cannot be accepted"),x.SessionClosing);let i=Ge();if(this.maybeSeedTitleFromPrompt(t),this._firstPromptSeeded=!0,!(it((t??{})._meta).ancillary===!0)&&this._interactive!==!0){this._interactive=!0,this.cancelOrphanTimer();for(let d of this.interactiveHandlers)try{d(!0)}catch{}}return this.enqueueUserPrompt(o,t,i,n,r)}broadcastPromptReceived(e){this.closeUnsolicitedTurn("superseded",`prompt:${e.messageId}`);let t={clientId:e.originator.clientId};e.originator.name&&(t.name=e.originator.name),e.originator.version&&(t.version=e.originator.version),e.originator.fromSession&&(t.fromSession=e.originator.fromSession),e.originator.fromSessionTitle&&(t.fromSessionTitle=e.originator.fromSessionTitle),e.originator.fromLabel&&(t.fromLabel=e.originator.fromLabel),e.originator.depth!==void 0&&(t.depth=e.originator.depth),this.promptStartedAt=Date.now(),this.turnRanTool=!1,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"prompt_received",messageId:e.messageId,prompt:e.prompt,sentBy:t}},e.clientId);let n=St(e.prompt);n.length>0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{compatFor:"prompt_received"}}}},e.clientId)}recordCurrentUsageSnapshot(){if(this.historyStore===void 0)return;let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let r={};typeof e.costAmount=="number"&&(r.amount=e.costAmount),typeof e.costCurrency=="string"&&(r.currency=e.costCurrency),t.cost=r}if(Object.keys(t).length<=1)return;t._meta={"hydra-acp":{upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}};let n={sessionId:this.sessionId,update:t};this.historyStore.append(this.sessionId,{method:"session/update",params:n,recordedAt:Date.now()}).catch(()=>{})}originatorNeedsTurnComplete(e){return e.wasAmend===!0||e.wasSteer===!0}broadcastTurnComplete(e,t,n,r){let o=t&&typeof t=="object"&&"stopReason"in t&&typeof t.stopReason=="string"?t.stopReason:void 0,i={sessionUpdate:"turn_complete",messageId:Ge()};o!==void 0&&(i.stopReason=o);let a=it(t?._meta).salvaged;a!==void 0&&(i._meta={[le]:{salvaged:a}}),this.supersededAutonomousTurn=void 0;let d=this.amendInProgress;if(d&&n!==void 0&&d.cancelledMessageId===n&&(i._meta={[le]:{...a!==void 0?{salvaged:a}:{},amended:{cancelledMessageId:d.cancelledMessageId,newMessageId:d.newMessageId}}}),this.promptStartedAt=void 0,this.noteTurnEnded(),this.sawTurnComplete=!0,this.scheduleWorkspaceSnapshotHook?.(),n!==void 0&&o!==void 0){this.recordTerminal(n,o);let c=this.pendingTurnNotifiers.get(n);c&&(this.pendingTurnNotifiers.delete(n),ro(c,{sessionId:this.sessionId,messageId:c.originalMessageId,stopReason:o,deliveredAt:Date.now(),...n!==c.originalMessageId?{amendedTo:n}:{}}))}o==="cancelled"||o==="error"||o==="refusal"?this.closeOpenToolCalls(o):this.armOpenToolCalls(),this.recordCurrentUsageSnapshot(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:i},r?void 0:e),d&&n!==void 0&&d.cancelledMessageId===n&&this.broadcastPromptAmended(d)}noteAgentActivity(e){if(!(this.closing||this.closed)){if(_g(e)||this.steerCausedTurnTerminal(e)){if(this.unsolicitedTurn!==void 0){this.closeUnsolicitedTurn("completed");return}this.salvageSupersededTerminal();return}this.pendingSteerDetach!==void 0&&this.currentEntry?.messageId===this.pendingSteerDetach.messageId&&Cd(e)&&(this.pendingSteerDetach=void 0),!In("session/update",e)&&(this.noteBackgroundTaskArming(e),this.unsolicitedTurn===void 0&&(this.promptInFlight||!this.sawTurnComplete||$g(e)||this.openUnsolicitedTurn()))}}steerCausedTurnTerminal(e){return this.unsolicitedTurn?.steerCaused!==!0?!1:Cd(e)}noteBackgroundTaskArming(e){let t=e?.update;if(!t||typeof t!="object")return;let n=typeof t.toolCallId=="string"?t.toolCallId:void 0;if(n===void 0)return;let r=t.rawInput,o=Jg(t._meta);this.rememberToolLabel(n,t,r,o),this.noteBackgroundTaskStopped(t,r,o);let i=typeof o?.toolResponse?.taskId=="string"?o.toolResponse.taskId:zg(t.rawOutput);if(!(i!==void 0||r!==void 0&&r.run_in_background===!0))return;let d=this.toolLabels.get(n)?.label??"background task";this.lastBackgroundTask={toolCallId:n,label:d};let c=Date.now(),u=this.armedTasks.get(n),l=i??u?.taskId,p=qg(t.title,o,r)||u?.repeating===!0;this.armedTasks.set(n,{label:d,...l!==void 0?{taskId:l}:{},repeating:p,armedAt:u?.armedAt??c}),this.onArmedTasksChanged()}applyBackgroundTaskLevel(e){let t=e?.message;if(!t||t.subtype!=="background_tasks_changed")return;let n=t.tasks;if(!Array.isArray(n))return;let r=Date.now(),o=new Map;for(let a of n){let d=a,c=typeof d?.task_id=="string"?d.task_id:void 0;c!==void 0&&o.set(c,{taskType:typeof d?.task_type=="string"?d.task_type:"unknown",description:typeof d?.description=="string"?d.description:"",firstSeen:this.liveBackgroundTasks.get(c)?.firstSeen??r})}let i=[...this.liveBackgroundTasks.keys()].filter(a=>!o.has(a));this.liveBackgroundTasks=o,this.sawBackgroundTaskLevel=!0,this.logger?.info(`session ${this.sessionId} background level: ${o.size} live`+(i.length>0?` (ended: ${i.join(", ")})`:"")),this.onArmedTasksChanged()}get armedBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.entries()].map(([e,t])=>({taskId:e,label:t.description||t.taskType,taskType:t.taskType,since:t.firstSeen})):[...this.armedTasks.entries()].map(([e,t])=>({toolCallId:e,label:t.label,...t.taskId!==void 0?{taskId:t.taskId}:{},since:t.armedAt}))}pendingOneShotBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.values()].filter(e=>Dg.has(e.taskType)).map(e=>e.description||e.taskType):[...this.armedTasks.values()].filter(e=>!e.repeating).map(e=>e.label)}get armedSince(){let e;if(this.sawBackgroundTaskLevel){for(let t of this.liveBackgroundTasks.values())(e===void 0||t.firstSeen<e)&&(e=t.firstSeen);return e}for(let t of this.armedTasks.values())(e===void 0||t.armedAt<e)&&(e=t.armedAt);return e}onArmedTasksChanged(){let e=this.armedBackgroundTasks,t=e.length,n=this.armedSince,r=e.map(o=>o.taskId??o.toolCallId??o.label).sort().join("\0");r===this.lastArmedBroadcast?.key&&n===this.lastArmedBroadcast?.since||this.closed||(this.lastArmedBroadcast={key:r,since:n},this.broadcastQueueNotification("hydra-acp/session/armed_tasks_updated",{sessionId:this.sessionId,count:t,...n!==void 0?{since:n}:{},tasks:e}),this.dispatchIdle())}async retireAgent(e,t){return await e.kill().catch(()=>{}),this.resetBackgroundTaskLevel(),this.discardArmedTasks(t)}resetBackgroundTaskLevel(){this.liveBackgroundTasks.clear(),this.sawBackgroundTaskLevel=!1}discardArmedTasks(e){if(this.armedTasks.size===0)return[];let t=[...this.armedTasks.values()].map(n=>n.label);for(let[n,r]of this.armedTasks)r.openToolCall===!0&&this.openToolCalls.delete(n);return this.armedTasks.clear(),this.logger?.info(`session ${this.sessionId} discarded ${t.length} armed task(s) on ${e}: ${t.join(", ")}`),this.onArmedTasksChanged(),t}noteBackgroundTaskStopped(e,t,n){if(!(n?.toolName==="TaskStop"||e.title==="TaskStop"))return;let o=t?.task_id;if(typeof o!="string"||o.length===0)return;let i=!1;for(let[a,d]of this.armedTasks)d.taskId===o&&(this.armedTasks.delete(a),i=!0);i&&this.onArmedTasksChanged()}rememberToolLabel(e,t,n,r){let o=n!==void 0&&typeof n.description=="string"&&n.description?n.description:void 0;if(o!==void 0)this.toolLabels.set(e,{label:o.slice(0,mo),fromDescription:!0});else if(this.toolLabels.get(e)?.fromDescription!==!0){let i=typeof t.title=="string"&&t.title?t.title:typeof r?.toolName=="string"&&r.toolName?r.toolName:void 0;i!==void 0&&this.toolLabels.set(e,{label:i.slice(0,mo),fromDescription:!1})}for(;this.toolLabels.size>Ng;){let i=this.toolLabels.keys().next().value;if(i===void 0)break;this.toolLabels.delete(i)}}openUnsolicitedTurn(){let e=Date.now();if(this.lastUnsolicitedCancelAt!==0&&e-this.lastUnsolicitedCancelAt<=s.UNSOLICITED_REOPEN_WINDOW_MS?this.cancelReopenStreak+=1:this.cancelReopenStreak=0,this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak>=s.UNSOLICITED_REOPEN_LIMIT){this.escalateUnresponsiveCancel();return}let t=this.lastBackgroundTask,n=!1;for(let[i,a]of this.armedTasks)a.repeating||a.openToolCall===!0||(this.armedTasks.delete(i),n=!0);n&&this.onArmedTasksChanged();let r={messageId:Ge(),startedAt:e,cause:t,steerCaused:this.pendingSteerDetach!==void 0};this.pendingSteerDetach=void 0,this.unsolicitedTurn=r,this.promptStartedAt=e,this.logger?.info(`session ${this.sessionId} agent resumed with no prompt in flight`+(t?` (after ${t.label})`:""));let o={unsolicited:!0};t&&(o.cause=t),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_started",messageId:r.messageId,_meta:{"hydra-acp":o}}})}async holdForUnsolicitedTurn(e){if(this.unsolicitedTurn===void 0){this.logger?.info(`session ${this.sessionId} queue hold skipped for ${e.messageId} (no unsolicited turn open)`);return}let t=Date.now(),n=this.unsolicitedTurn.cause;this.logger?.info(`session ${this.sessionId} holding ${e.messageId} behind unsolicited turn ${this.unsolicitedTurn.messageId}`+(n?` cause=${JSON.stringify(n.label)}`:"")),this.broadcastQueueNotification("hydra-acp/prompt_queue/held",{sessionId:this.sessionId,messageId:e.messageId,reason:"agent_resumed",...n?{cause:n}:{}});let r="turn_ended";for(;;){if(this.closing||this.closed){r="closing";break}if(e.cancelled){r="cancelled";break}if(this.unsolicitedTurn===void 0){r="turn_ended";break}await new Promise(i=>{let a=setTimeout(i,Hg);typeof a.unref=="function"&&a.unref()})}let o=Date.now()-t;this.logger?.info(`session ${this.sessionId} released ${e.messageId} reason=${r} heldMs=${o}`),this.broadcastQueueNotification("hydra-acp/prompt_queue/released",{sessionId:this.sessionId,messageId:e.messageId,reason:r,heldMs:o})}closeUnsolicitedTurn(e,t){let n=this.unsolicitedTurn;if(n===void 0)return;let r=Date.now()-n.startedAt;this.unsolicitedTurn=void 0,this.promptStartedAt=void 0,this.noteTurnEnded(),e==="cancelled"?this.lastUnsolicitedCancelAt=Date.now():(this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak=0),this.logger?.info(`session ${this.sessionId} unsolicited turn ${n.messageId} closed reason=${e} durationMs=${r}`+(t?` by=${t}`:"")+(n.cause?` cause=${JSON.stringify(n.cause.label)}`:"")),e==="superseded"&&(this.supersededAutonomousTurn={turnMessageId:n.messageId,cause:n.cause,supersededAt:Date.now()}),this.recordCurrentUsageSnapshot(),!this.closed&&(e==="cancelled"?this.closeOpenToolCalls("cancelled"):e==="completed"&&this.armOpenToolCalls(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_ended",messageId:Ge(),startedMessageId:n.messageId,durationMs:r,_meta:{"hydra-acp":{unsolicited:!0,reason:e}}}}))}salvageSupersededTerminal(){let e=this.supersededAutonomousTurn;if(e===void 0)return;this.supersededAutonomousTurn=void 0;let t=this.autonomousSalvage;t!==void 0&&(this.autonomousSalvage=void 0,this.logger?.warn(`session ${this.sessionId} salvaged session/prompt from autonomous terminal (superseded turn ${e.turnMessageId}, ${Date.now()-e.supersededAt}ms earlier)`+(e.cause?` cause=${JSON.stringify(e.cause.label)}`:"")),t({stopReason:"end_turn",_meta:{[le]:{salvaged:{reason:"autonomous_terminal",supersededMessageId:e.turnMessageId}}}}))}async awaitPromptResponse(e){if(this.supersededAutonomousTurn===void 0)return e;try{return await new Promise((t,n)=>{this.autonomousSalvage=t,e.then(t,n)})}finally{this.autonomousSalvage=void 0}}recordTerminal(e,t){for(this.recentlyTerminal.set(e,{stopReason:t,terminatedAt:Date.now()});this.recentlyTerminal.size>Pg;){let n=this.recentlyTerminal.keys().next().value;if(n===void 0)break;this.recentlyTerminal.delete(n)}}registerTurnNotify(e,t,n){let r=this.recentlyTerminal.get(e);if(r)return{alreadyTerminal:!0,stopReason:r.stopReason};for(this.pendingTurnNotifiers.set(e,{callbackUrl:t,secret:n,registeredAt:Date.now(),originalMessageId:e});this.pendingTurnNotifiers.size>Eg;){let o=this.pendingTurnNotifiers.keys().next().value;if(o===void 0)break;this.pendingTurnNotifiers.delete(o)}return{alreadyTerminal:!1}}broadcastPromptAmended(e){let t=this.findUserEntry(e.newMessageId);if(!t)return;let n={sessionId:this.sessionId,cancelledMessageId:e.cancelledMessageId,newMessageId:e.newMessageId,prompt:t.prompt,originator:t.originator,amendedAt:Date.now()};this.broadcastQueueNotification("hydra-acp/prompt/amended",n)}findUserEntry(e){if(this.currentEntry?.messageId===e&&this.currentEntry.kind==="user")return this.currentEntry;let t=this.promptQueue.find(n=>n.messageId===e&&n.kind==="user");return t?.kind==="user"?t:void 0}visibleQueueDepth(){let e=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;for(let t of this.promptQueue)t.kind==="user"&&!t.cancelled&&(e+=1);return e}broadcastQueueAdded(e,t){let n=this.visibleQueueDepth(),r=t?.position??Math.max(0,n-1),o={sessionId:this.sessionId,messageId:e.messageId,originator:e.originator,prompt:e.prompt,position:r,queueDepth:n,enqueuedAt:e.enqueuedAt};t?.amending!==void 0&&(o._meta={"hydra-acp":{amending:t.amending}}),this.broadcastQueueNotification("hydra-acp/prompt_queue/added",o)}broadcastQueueUpdated(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/updated",{sessionId:this.sessionId,messageId:e,prompt:t})}broadcastQueueRemoved(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/removed",{sessionId:this.sessionId,messageId:e,reason:t})}broadcastQueueNotification(e,t){for(let n of this.clients.values())n.connection.notify(e,t).catch(()=>{})}queueSnapshot(){let e=[],t=0;this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled&&e.push({messageId:this.currentEntry.messageId,originator:this.currentEntry.originator,prompt:this.currentEntry.prompt,position:t++,enqueuedAt:this.currentEntry.enqueuedAt});for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push({messageId:n.messageId,originator:n.originator,prompt:n.prompt,position:t++,enqueuedAt:n.enqueuedAt});return e}async flushPersistWrites(){await this.queueWriteChain.catch(()=>{})}replayPersistedQueue(e){for(let t of e){let n={clientId:`hydra-resurrected_${t.messageId}`};t.originator.clientInfo.name!==void 0&&(n.name=t.originator.clientInfo.name),t.originator.clientInfo.version!==void 0&&(n.version=t.originator.clientInfo.version);let r={kind:"user",messageId:t.messageId,originator:n,clientId:n.clientId,prompt:t.prompt,enqueuedAt:t.enqueuedAt,cancelled:!1,resolve:()=>{},reject:()=>{}};this.promptQueue.push(r),this.broadcastQueueAdded(r)}this.drainQueue()}cancelQueuedPrompt(e){if(this.currentEntry?.messageId===e)return{cancelled:!1,reason:"already_running"};let t=this.promptQueue.findIndex(r=>r.messageId===e);if(t<0)return{cancelled:!1,reason:"not_found"};let n=this.promptQueue[t];return n.cancelled=!0,this.promptQueue.splice(t,1),n.kind==="user"&&(this.broadcastQueueRemoved(e,"cancelled"),this.persistRewrite()),this.amendInProgress?.newMessageId===e&&(this.amendInProgress=void 0),n.resolve({stopReason:"cancelled"}),{cancelled:!0,reason:"ok"}}updateQueuedPrompt(e,t){if(this.currentEntry?.messageId===e)return{updated:!1,reason:"already_running"};let n=this.promptQueue.find(r=>r.messageId===e);return!n||n.kind!=="user"?{updated:!1,reason:"not_found"}:(n.prompt=t,this.broadcastQueueUpdated(e,t),this.persistRewrite(),{updated:!0,reason:"ok"})}amendPrompt(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let{targetMessageId:r,prompt:o,replaceQueue:i,onTargetCompleted:a}=t;if(this.currentEntry?.messageId===r&&this.currentEntry.kind==="user"&&!this.currentEntry.cancelled&&this.amendInProgress===void 0)return this.amendOnHead(n,o,r,i);let d=this.promptQueue.find(u=>u.messageId===r&&u.kind==="user");if(d&&d.kind==="user"&&!d.cancelled)return d.prompt=o,this.broadcastQueueUpdated(r,o),this.persistRewrite(),{amended:!0,reason:"ok",messageId:r};let c=this.recentlyTerminal.get(r);return c?c.stopReason==="cancelled"?{amended:!1,reason:"target_cancelled"}:a==="send_anyway"?{amended:!1,reason:"target_completed",messageId:this.enqueueAmendmentAsFollowUp(n,o)}:{amended:!1,reason:"target_completed"}:{amended:!1,reason:"target_not_found"}}amendOnHead(e,t,n,r){let o=Ge(),i={clientId:e.clientId};if(e.clientInfo?.name&&(i.name=e.clientInfo.name),e.clientInfo?.version&&(i.version=e.clientInfo.version),r){let c=[];for(let u of this.promptQueue){if(u.kind==="user"&&!u.cancelled){u.cancelled=!0,this.broadcastQueueRemoved(u.messageId,"cancelled"),u.resolve({stopReason:"cancelled"});continue}c.push(u)}this.promptQueue=c}let a={kind:"user",messageId:o,originator:i,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,wasAmend:!0,resolve:()=>{},reject:()=>{}};this.promptQueue.unshift(a),this.persistRewrite(),this.broadcastQueueAdded(a,{amending:n,position:1}),this.amendInProgress={cancelledMessageId:n,newMessageId:o};let d=this.pendingTurnNotifiers.get(n);return d&&(this.pendingTurnNotifiers.delete(n),this.pendingTurnNotifiers.set(o,d)),this.cancelExtensionDispatch(n,"amended"),this.agent.connection.notify("session/cancel",{sessionId:this.upstreamSessionId}).catch(()=>{}),{amended:!0,reason:"ok",messageId:o}}async steer(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let r=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled;if(r&&this.agent.steeringSupported){this.pendingSteerDetach={messageId:this.currentEntry.messageId};let o;try{o=await this.forwardRequest("_session/steering",t)}catch(d){throw this.pendingSteerDetach=void 0,d}let i=o?.outcome,a=i==="injected"||i==="startedNewTurn"||i==="promptRequired"||i==="failed"?o:{outcome:"failed"};return a.outcome!=="startedNewTurn"&&(this.pendingSteerDetach=void 0),a.outcome==="injected"&&this.recordSteerAsUserMessageChunk(t.prompt,e),a.outcome==="startedNewTurn"?{...a,detached:!0}:a}return r?(this.amendOnHead(n,t.prompt,this.currentEntry.messageId,!1),{outcome:"startedNewTurn"}):t._meta?.steering?.idleBehavior==="promptRequired"?{outcome:"promptRequired",reason:"noRunningTurn"}:(this.prompt(e,{sessionId:t.sessionId,prompt:t.prompt},void 0,{steerOriginated:!0}).catch(o=>{this.logger?.warn(`steer-originated prompt failed to enqueue: ${o.message}`)}),{outcome:"startedNewTurn"})}recordSteerAsUserMessageChunk(e,t){let n=St(e);n.length!==0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{steered:!0}}}},t)}enqueueAmendmentAsFollowUp(e,t){let n=Ge(),r={clientId:e.clientId};e.clientInfo?.name&&(r.name=e.clientInfo.name),e.clientInfo?.version&&(r.version=e.clientInfo.version);let o={kind:"user",messageId:n,originator:r,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,resolve:()=>{},reject:()=>{}};return this.promptQueue.push(o),this.persistRewrite(),this.broadcastQueueAdded(o),this.drainQueue(),n}async cancel(e){if(!this.clients.get(e))throw fe(new Error("client not attached"),x.SessionNotFound);this.logger?.info(`session ${this.sessionId} session/cancel from ${e} promptInFlight=${this.promptInFlight} agentTurnInFlight=${this.agentTurnInFlight} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length}`),this.lastCancelAt=Date.now(),this.currentEntry?.kind==="user"&&this.currentEntry.messageId!==void 0&&this.cancelExtensionDispatch(this.currentEntry.messageId,"cancelled"),this.closeUnsolicitedTurn("cancelled"),this.agentTurnInFlight||this.closeOpenToolCalls("cancelled"),await this.forwardRequest("session/cancel",{sessionId:this.sessionId},new Set,0,"notification")}addTransformer(e){let t=this.transformChain.findIndex(n=>n.name===e.name);t>=0?this.transformChain[t]=e:this.transformChain.push(e),e.intercepts.has("lifecycle:session.opened")&&e.connection.notify("hydra-acp/transformer/session_event",{event:"session.opened",sessionId:this.sessionId}).catch(()=>{})}async forwardRequest(e,t,n=new Set,r=0,o="request"){let i=this.rewriteForAgent(t);for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name))continue;let c=`request:${e}`;if(!d.intercepts.has(c))continue;let u=`t_${ho()}`,l;try{l=await d.connection.request("hydra-acp/transformer/message",{token:u,phase:"request",method:e,direction:"client\u2192agent",sessionId:this.sessionId,envelope:i})}catch(f){this.logger?.warn(`transformer ${d.name} error on ${c}: ${f.message}`);continue}let p=l?.action??"continue";if(p==="stop")return o==="notification"?void 0:l?.payload??wo(e);if(p==="continue"){l?.payload&&typeof l.payload=="object"&&(i=l.payload),n.add(d.name);continue}if(p==="processing"){let f=a,h=i,w=new Set(n);return new Promise(m=>{let g=setTimeout(()=>{this.pendingClaims.delete(u)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:u,transformerName:d.name}),this.forwardRequest(e,h,new Set([...w,d.name]),f+1,o).then(m).catch(()=>m(o==="notification"?void 0:wo(e))))},ws);typeof g.unref=="function"&&g.unref(),this.pendingClaims.set(u,{resolve:m,timer:g,transformerName:d.name,method:e,envelope:h,chainIdx:f,originatedBy:w,side:"request",tailKind:o})})}n.add(d.name)}if(o==="notification"){await this.agent.connection.notify(e,i);return}return this.agent.connection.request(e,i)}async forwardModelChange(e,t){let n=await ct({request:(r,o)=>this.forwardRequest(r,o),sessionId:this.sessionId,modelId:e,verb:this.modelVerb,extraParams:t,logger:this.logger});return this.modelVerb=n.verb,this.modelVerbConfirmed=!0,n.result}noteModelVerbHint(e,t){e===void 0||this.modelVerbConfirmed||e===this.modelVerb||(this.logger?.info(`model verb for agent ${this.agentId} inferred as ${e} from ${t} (was ${this.modelVerb})`),this.modelVerb=e)}resetModelVerb(e){this.modelVerb=e??ze,this.modelVerbConfirmed=!1}async runAgentRequestChain(e,t,n=new Set,r=0){let o=t,i=`request:${e}`;for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name)||!d.intercepts.has(i))continue;let c=`t_${ho()}`,u;try{u=await d.connection.request("hydra-acp/transformer/message",{token:c,phase:"request",method:e,direction:"agent\u2192client",sessionId:this.sessionId,envelope:o})}catch(p){this.logger?.warn(`transformer ${d.name} error on ${i}: ${p.message}`);continue}let l=u?.action??"continue";if(l==="stop")return{shortCircuit:!0,payload:u?.payload??ah(e)};if(l==="continue"){u?.payload&&typeof u.payload=="object"&&(o=u.payload),n.add(d.name);continue}if(l==="processing"){let p=a,f=o,h=new Set(n),w=e;return new Promise(m=>{let g=setTimeout(()=>{this.pendingClaims.delete(c)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:c,transformerName:d.name}),this.runAgentRequestChain(w,f,new Set([...h,d.name]),p+1).then(m).catch(()=>m({shortCircuit:!1,envelope:f})))},ws);typeof g.unref=="function"&&g.unref(),this.pendingClaims.set(c,{resolve:y=>m({shortCircuit:!0,payload:y}),timer:g,transformerName:d.name,method:w,envelope:f,chainIdx:p,originatedBy:h,side:"agent-request"})})}n.add(d.name)}return{shortCircuit:!1,envelope:o}}dischargeClaim(e,t){let n=this.pendingClaims.get(e);return n?(clearTimeout(n.timer),this.pendingClaims.delete(e),n.resolve(t),!0):!1}keepAliveClaim(e,t){let n=this.pendingClaims.get(e);if(!n)return!1;clearTimeout(n.timer);let r=typeof t=="number"&&t>0?Math.min(t*1.5,1800*1e3):ws,o=setTimeout(()=>{if(this.pendingClaims.delete(e))if(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:e,transformerName:n.transformerName}),n.side==="response")this.runResponseChain(n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1).then(()=>n.resolve(void 0)).catch(()=>n.resolve(void 0));else if(n.side==="agent-request")this.runAgentRequestChain(n.method,n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1).then(n.resolve).catch(()=>n.resolve({shortCircuit:!1,envelope:n.envelope}));else{let i=n.tailKind??"request";this.forwardRequest(n.method,n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1,i).then(n.resolve).catch(()=>n.resolve(i==="notification"?void 0:wo(n.method)))}},r);return typeof o.unref=="function"&&o.unref(),n.timer=o,!0}async emitToChain(e,t,n){let r=this.transformChain.findIndex(a=>a.name===e),o=r>=0?r+1:0,i=new Set([e]);if(t==="session/update"){await this.runResponseChain(n,i,o);return}return this.forwardRequest(t,n,i,o)}async emitToQueue(e,t){let n=this.transformChain.findIndex(c=>c.name===e),r=n>=0?n+1:0,o=(t??{}).prompt??[],i=Ge(),a=`transformer:${e}`,d={clientId:a,name:e};return new Promise((c,u)=>{let l={kind:"user",messageId:i,originator:d,clientId:a,prompt:o,enqueuedAt:Date.now(),cancelled:!1,emitterName:e,chainStartIdx:r,resolve:c,reject:u},p=this.insertEntryAt(l,"tail");this.persistRewrite(),this.broadcastQueueAdded(l,{position:p}),this.drainQueue()})}rewriteForAgent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.sessionId===this.sessionId)return{...t,sessionId:this.upstreamSessionId}}return e}async close(e={}){if(e.deleteRecord&&(this.deleteRecordIntent=!0),!this.closed)return this.closeInFlight?this.closeInFlight:(this.closing=!0,this.closeInFlight=this.doClose(e),this.closeInFlight)}async doClose(e){let t=this.turnStartedAt!==void 0;this.logger?.info(`session ${this.sessionId} closing deleteRecord=${e.deleteRecord??!1} by=${e.by??"unknown"} midTurn=${t} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length} awaitingPermission=${this.hasPermissionFlag}`),t&&this.logger?.warn(`session ${this.sessionId} closed mid-turn by=${e.by??"unknown"}; the in-flight turn will not settle and the agent is being killed`),this.cancelIdleTimer(),this.cancelOrphanTimer();for(let n of this.pendingClaims.values())clearTimeout(n.timer);this.pendingClaims.clear(),await this.agent.kill().catch(()=>{}),this.markClosed({deleteRecord:e.deleteRecord??!1})}onClose(e){return this.closeHandlers.push(e),()=>{let t=this.closeHandlers.indexOf(e);t>=0&&this.closeHandlers.splice(t,1)}}onTitleChange(e){this.titleHandlers.push(e)}retitle(e){return this.runTitleCommand(e)}retitleFromAgent(){return this.runTitleCommand("")}setTitle(e){let t=e.trim();if(!(!t||t===this.title)){this._titleSeedPending=!1,this.title=t,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",title:t,updatedAt:new Date().toISOString()}});for(let n of this.titleHandlers)try{n(t)}catch{}}}maybeSeedTitleFromPrompt(e){if(!this._titleSeedPending||it((e??{})._meta).ancillary===!0||this.promptCarriesSentBy(e))return;let r=St((e??{}).prompt),o=vo(r,200);!o||o.startsWith("/")||(this._titleSeedPending=!1,this.setTitle(o))}maybeApplyAgentModel(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="_hydra_current_model_update")return!1;let r=An(n.availableModels);r.length>0&&this.setAgentAdvertisedModels(r);let o=typeof n.currentModel=="string"?n.currentModel:typeof n.model=="string"?n.model:void 0;if(o===void 0)return!0;let i=o.trim();if(!i||i===this.currentModel)return!0;this.logger?.info(`live current_model_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(i)}`),this.currentModel=i;for(let a of this.modelHandlers)try{a(i)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentConfigOption(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="config_option_update")return!1;let r=n.configOptions;if(!Array.isArray(r))return!0;for(let i of r)this.applyOneConfigOptionEntry(i);let o=new Set(r.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i&&i!=="model"&&i!=="mode"&&i!=="agent"));return this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id)),this.fireConfigOptionsHandlers(),!0}applyAgentConfigOptionResponse(e,t){let n=e?.configOptions;if(!Array.isArray(n))return!1;let r=JSON.stringify(this.agentAdvertisedConfigOptions);for(let o of n){let i=o?.id;i==="model"||i==="mode"||i==="agent"||this.applyOneConfigOptionEntry(o)}if(Og(n,t)){let o=new Set(n.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i));this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id))}return JSON.stringify(this.agentAdvertisedConfigOptions)!==r}applyOneConfigOptionEntry(e){if(!e||typeof e!="object")return;let t=e;if(t.id==="model"){let w=An(t.options);w.length>0&&this.setAgentAdvertisedModels(w);let m=t.currentValue;if(typeof m=="string"){let g=m.trim();g&&g!==this.currentModel&&(this.logger?.info(`live config_option_update(model): sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(g)}`),this.applyModelChange(g))}return}if(t.id==="mode"){let w=ks(t.options);w.length>0&&this.setAgentAdvertisedModes(w);let m=t.currentValue;if(typeof m=="string"){let g=m.trim();g&&g!==this.currentMode&&(this.logger?.info(`live config_option_update(mode): sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(g)}`),this.applyModeChange(g))}return}if(typeof t.id!="string"||!t.id.trim())return;let n=t.id.trim(),r=ko(t.options);if(r.length===0)return;let o=t.name,i=typeof o=="string"&&o.trim()?o.trim():n,a=t.category,d=typeof a=="string"&&a.trim()?a.trim():"other",c=t.description,u=typeof c=="string"&&c.trim()?c.trim():void 0,l=t.currentValue,p=typeof l=="string"&&l.trim()?l.trim():r[0].value,f={id:n,name:i,category:d,type:"select",currentValue:p,options:r,...u?{description:u}:{}},h=this.agentAdvertisedConfigOptions.findIndex(w=>w.id===n);h>=0?this.agentAdvertisedConfigOptions[h]=f:this.agentAdvertisedConfigOptions.push(f)}maybeApplyAgentMode(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="current_mode_update")return!1;let r=typeof n.currentModeId=="string"?n.currentModeId:typeof n.currentMode=="string"?n.currentMode:typeof n.mode=="string"?n.mode:void 0;if(r===void 0)return!0;let o=r.trim();if(!o||o===this.currentMode)return!0;this.logger?.info(`current_mode_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(o)}`),this.currentMode=o;for(let i of this.modeHandlers)try{i(o)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentUsage(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="usage_update")return!1;let r={...this._currentUsage??{}},o=!1;if(typeof n.used=="number"&&!this.swapInFlight&&ud(r.used,n.used)&&this.armRecallFromSelfCompaction(),typeof n.used=="number"&&r.used!==n.used&&(r.used=n.used,o=!0),typeof n.size=="number"&&r.size!==n.size&&(r.size=n.size,o=!0),n.cost&&typeof n.cost=="object"){let a=n.cost;typeof a.amount=="number"&&(this.reconcileCostLedger(a.amount)&&(o=!0),r.costAmount!==a.amount&&(r.costAmount=a.amount,o=!0)),typeof a.currency=="string"&&r.costCurrency!==a.currency&&(r.costCurrency=a.currency,o=!0)}if(!o)return!0;this._currentUsage=r;let i=this.persistableUsage??r;for(let a of this.usageHandlers)try{a(i)}catch{}return!0}armCostLedgerProbe(){let e=this._currentUsage?.costAmount;typeof e=="number"&&e>0&&(this.costLedgerProbe=e)}reconcileCostLedger(e){let t=this.costLedgerProbe;return t===void 0||(this.costLedgerProbe=void 0,e>=t-1e-6)?!1:(this.cumulativeCost+=t,!0)}notifyAgentChange(e,t,n,r){let o=this.retiringGenerationCost;this.retiringGenerationCost=void 0;let i=this.retiringGenerationUsed;this.retiringGenerationUsed=void 0;let a=this.rotationLifetimeCost;this.rotationLifetimeCost=void 0;for(let d of this.agentChangeHandlers)try{d({agentId:this.agentId,upstreamSessionId:this.upstreamSessionId,...o!==void 0?{retiredCost:o}:{},...a!==void 0?{lifetimeCost:a}:{},...i!==void 0?{retiredUsed:i}:{},...r!==void 0?{startedUsed:r}:{},...t!==void 0?{reason:t}:{},...n!==void 0?{runId:n}:{}})}catch(c){this.logger?.warn(`${e}: agentChange handler failed: ${c.message}`)}}accumulateAndResetCost(){let e=this._currentUsage?.costAmount;e&&(this.cumulativeCost+=e,this.retiringGenerationCost=e);let t=this._currentUsage?.used;typeof t=="number"&&t>0&&(this.retiringGenerationUsed=t),this.rotationLifetimeCost=this.cumulativeCost;let n={used:0,cumulativeCost:this.cumulativeCost,...typeof this._currentUsage?.size=="number"?{size:this._currentUsage.size}:{},...this._currentUsage?.costCurrency?{costCurrency:this._currentUsage.costCurrency}:{}};this._currentUsage=n;for(let r of this.usageHandlers)try{r(n)}catch{}this.broadcastCurrentUsage()}broadcastCurrentUsage(){let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let n={};typeof e.costAmount=="number"&&(n.amount=e.costAmount),typeof e.costCurrency=="string"&&(n.currency=e.costCurrency),t.cost=n}this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:t})}injectCumulativeCost(e){if(!this.cumulativeCost||!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update;if(n.sessionUpdate!=="usage_update"||!n.cost||typeof n.cost!="object")return e;let r=n.cost;return typeof r.amount!="number"?e:{...t,update:{...n,cost:{...r,amount:this.cumulativeCost+r.amount}}}}get totalUsage(){return this.currentUsage}setAgentAdvertisedCommands(e){if(Vg(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(Gg(this.agentAdvertisedModes,e)){this.broadcastAvailableModes();return}this.agentAdvertisedModes=e;for(let t of this.agentModesHandlers)try{t(e)}catch{}this.broadcastAvailableModes()}setAgentAdvertisedModels(e){if(this.logger?.info(`setAgentAdvertisedModels: sessionId=${this.sessionId} currentModel=${JSON.stringify(this.currentModel)} newList=[${e.map(t=>t.modelId).join(",")}]`),Kg(this.agentAdvertisedModels,e)){this.broadcastAvailableModels();return}this.agentAdvertisedModels=e;for(let t of this.agentModelsHandlers)try{t(e)}catch{}this.broadcastAvailableModels()}onAgentCommandsChange(e){this.agentCommandsHandlers.push(e)}onAgentModesChange(e){this.agentModesHandlers.push(e)}onAgentModelsChange(e){this.agentModelsHandlers.push(e)}onConfigOptionsChange(e){this.configOptionsHandlers.push(e)}extraConfigOptionValues(){return Object.fromEntries(this.agentAdvertisedConfigOptions.map(e=>[e.id,e.currentValue]))}onModelChange(e){this.modelHandlers.push(e)}onModeChange(e){this.modeHandlers.push(e)}onInteractiveChange(e){this.interactiveHandlers.push(e)}onPriorityChange(e){this.priorityHandlers.push(e)}onReadStateChange(e){this.readStateHandlers.push(e)}get unread(){return kn(this._lastTurnEndedAt,this._readAt)}setRead(e,t=Date.now()){let n=ps({lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt},e,t);n!==void 0&&(this._readAt=n,this.fireReadState())}noteTurnEnded(e=Date.now()){this._readAt===void 0&&(this._readAt=Math.min(this._lastTurnEndedAt??this.createdAt,e-1)),this._lastTurnEndedAt=e,this.fireReadState()}fireReadState(){let e={lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt};for(let t of this.readStateHandlers)try{t(e)}catch{}}setPriority(e){let t=e===void 0||e<=0?void 0:Math.floor(e);if(t!==this._priority){this._priority=t,this.updatedAt=Date.now();for(let n of this.priorityHandlers)try{n(t)}catch{}}}applyModelChange(e){let t=e.trim();if(t){this.modelChangeInFlight=!0;try{if(t!==this.currentModel){this.logger?.info(`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(t)}`),this.currentModel=t;for(let r of this.modelHandlers)try{r(t)}catch{}}let n={sessionUpdate:"_hydra_current_model_update",currentModel:t};this.agentAdvertisedModels.length>0&&(n.availableModels=[...this.agentAdvertisedModels]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modelChangeInFlight=!1}}}applyModeChange(e){let t=e.trim();if(t){this.modeChangeInFlight=!0;try{if(t!==this.currentMode){this.logger?.info(`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(t)}`),this.currentMode=t;for(let r of this.modeHandlers)try{r(t)}catch{}}let n={sessionUpdate:"current_mode_update",currentModeId:t};this.agentAdvertisedModes.length>0&&(n.availableModes=[...this.agentAdvertisedModes]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modeChangeInFlight=!1}}}buildConfigOptions(){let e=[];if(this.agentAdvertisedModels.length>0){let r=this.agentAdvertisedModels.map(i=>({value:i.modelId,name:i.name??i.modelId,...i.description!==void 0?{description:i.description}:{}}));this.currentModel&&!r.some(i=>i.value===this.currentModel)&&r.unshift({value:this.currentModel,name:this.currentModel});let o=this.currentModel||r[0].value;e.push({id:"model",name:"Model",category:"model",type:"select",currentValue:o,options:r})}if(this.agentAdvertisedModes.length>0){let r=this.agentAdvertisedModes.map(i=>({value:i.id,name:i.name??i.id,...i.description!==void 0?{description:i.description}:{}}));this.currentMode&&!r.some(i=>i.value===this.currentMode)&&r.unshift({value:this.currentMode,name:this.currentMode});let o=this.currentMode||r[0].value;e.push({id:"mode",name:"Session Mode",category:"mode",type:"select",currentValue:o,options:r})}let n=(this.availableAgentsFn?.()??[]).map(r=>({value:r.id,name:r.name??r.id,...r.description!==void 0?{description:r.description}:{}}));return n.some(r=>r.value===this.agentId)||n.unshift({value:this.agentId,name:this.agentId}),e.push({id:"agent",name:"Agent",category:"_hydra_agent",type:"select",currentValue:this.agentId,options:n}),e.push(...this.agentAdvertisedConfigOptions),e}broadcastConfigOptions(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"config_option_update",configOptions:this.buildConfigOptions()}}),this.fireConfigOptionsHandlers()}fireConfigOptionsHandlers(){for(let e of this.configOptionsHandlers)try{e(this.agentAdvertisedConfigOptions)}catch{}}mergeAgentOptionIntoEnvelope(e){if(!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update,r=Array.isArray(n.configOptions)?[...n.configOptions]:[];if(r.some(a=>a&&typeof a=="object"&&a.id==="agent"))return e;let i=this.buildConfigOptions().find(a=>a.id==="agent");return i?{...t,update:{...n,configOptions:[...r,i]}}:e}onUsageChange(e){this.usageHandlers.push(e)}mergedAvailableCommands(){let e=this.daemonTopLevelCommands(),t=this.aliasableBareVerbs();for(let n of qt){if(t.get(n.verb)!=="__hydra__")continue;let r=n.argsHint?`${n.verb} ${n.argsHint}`:n.verb;e.push({name:r,description:`Alias for '/hydra ${n.verb}': ${n.description}`})}if(this.extensionCommands)for(let{name:n,command:r}of this.extensionCommands.list()){let o=r.verb?`hydra ${n} ${r.verb}`:`hydra ${n}`,a={name:r.argsHint?`${o} ${r.argsHint}`:o};r.description&&(a.description=r.description),e.push(a);let d=so(n),c=d??n;if(d!==void 0){let u=r.verb?`hydra ${c} ${r.verb}`:`hydra ${c}`,p={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(p.description=r.description),e.push(p)}if(c.length>0&&t.get(c)===n){let u=r.verb?`${c} ${r.verb}`:c,p={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(p.description=r.description),e.push(p)}}return e.push(...this.agentAdvertisedCommands),e}daemonTopLevelCommands(){return[{name:"hydra",description:"Hydra session command (kill, restart, title, agent <agent>)"},{name:"model",description:"Switch model; omit arg to list available models"},{name:"mode",description:"Switch mode; omit arg to list available modes"},{name:"sessions",description:"List all sessions"},{name:"help",description:"Show available commands"}]}aliasableBareVerbs(){let e=new Set,t=i=>i.split(/\s+/)[0]??"";for(let i of this.daemonTopLevelCommands()){let a=t(i.name);a&&e.add(a)}for(let i of this.agentAdvertisedCommands){let a=t(i.name),d=a.startsWith("/")?a.slice(1):a;d&&e.add(d)}let n=new Map;for(let i of qt)e.has(i.verb)||n.set(i.verb,"__hydra__");if(!this.extensionCommands)return n;let r=new Map,o=new Set;for(let{name:i}of this.extensionCommands.list()){if(o.has(i))continue;o.add(i);let a=so(i)??i;if(!a||e.has(a)||n.has(a))continue;let d=r.get(a);d===void 0?r.set(a,i):d!==i&&r.set(a,"__conflict__")}for(let[i,a]of r)a!=="__conflict__"&&n.set(i,a);return n}agentOnlyAdvertisedCommands(){return[...this.agentAdvertisedCommands]}agentKnowsSlashCommand(e){let t=r=>r.startsWith("/")?r.slice(1):r,n=t(e);if(!n)return!1;for(let r of this.agentAdvertisedCommands)if(t(r.name.split(/\s+/)[0]??"")===n)return!0;return!1}availableModes(){return[...this.agentAdvertisedModes]}availableModels(){return[...this.agentAdvertisedModels]}maybeApplyAgentSessionInfo(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="session_info_update"||typeof n.title!="string"||this._upstreamRespawned)return;let r=n.title.trim();if(!(!r||r===this.title)){this.title=r,this._firstPromptSeeded=!0,this._titleSeedPending=!1;for(let o of this.titleHandlers)try{o(r)}catch{}}}async handleSlashCommand(e,t){let r=e.slice(6).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),o=r?.[1]??"",i=(r?.[2]??"").trim();if(o==="")return{stopReason:"end_turn"};let a=t!==void 0;if(qt.some(l=>l.verb===o))switch(o){case"title":return a?this.runTitleCommandInline(i):this.runTitleCommand(i);case"agent":return this.runAgentCommandInline(i);case"config":return this.handleConfigCommand(`/config ${i}`);case"kill":return this.runKillCommand();case"workspace":return this.runWorkspaceCommand(i);case"restart":return a?this.runRestartCommandInline():this.runRestartCommand();case"clear":return this.runClearCommand();case"compact":return a?this.runCompactCommandInline(i):this.runCompactCommand(i);case"uncompact":return a?this.runUncompactCommandInline():this.runUncompactCommand();case"fork":return a?this.runForkCommandInline(i,t):this.runForkCommand(i);default:{let l=new Error(`no dispatcher for /hydra verb ${o}`);throw l.code=x.InternalError,l}}if(this.extensionCommands?.has(o))return a?this.runExtensionCommandInline(o,i,t):this.runExtensionCommand(o,i);let d=rd(o).find(l=>this.extensionCommands?.has(l));if(d!==void 0)return a?this.runExtensionCommandInline(d,i,t):this.runExtensionCommand(d,i);let c=qt.map(l=>l.verb);if(this.extensionCommands){let l=new Set;for(let{name:p}of this.extensionCommands.list())l.has(p)||(c.push(p),l.add(p))}let u=new Error(`unknown /hydra verb: ${o} (known: ${c.join(", ")})`);throw u.code=x.InvalidParams,u}runExtensionCommand(e,t){return this.enqueuePrompt(`extension:${e}`,()=>this.runExtensionCommandInline(e,t,void 0))}async runExtensionCommandInline(e,t,n){let r=this.extensionCommands?.get(e);if(!r)return this.emitExtensionReply(`extension "${e}" is no longer connected`);let o=t.match(/^(\S+)(?:\s+([\s\S]*))?$/),i=o?.[1]??"",a=(o?.[2]??"").trim();if(!r.commands.some(h=>h.verb===i)){let h=r.commands.map(w=>w.verb).join(", ");return this.emitExtensionReply(`/hydra ${e}${i?` ${i}`:""}: unknown verb (known: ${h||"(none)"})`)}let d={sessionId:this.sessionId,verb:i,args:a};n!==void 0&&(d.messageId=n);let c=()=>{},u=new Promise(h=>{c=h});n!==void 0&&this.inFlightExtensionDispatches.set(n,{extensionName:e,connection:r.connection,cancel:h=>c({stopReason:"cancelled",reason:h})});let l,p=!1;try{let h=r.connection.request("hydra-acp/commands/invoke",d),w=await Promise.race([h,u]);if(w&&typeof w=="object"&&w.stopReason==="cancelled"&&"reason"in w)return p=!0,this.logger?.info(`extension ${e} ${i} cancelled (cancelExtensionDispatch); abandoning in-flight commands/invoke`),{stopReason:"cancelled"};l=w}catch(h){return this.emitExtensionReply(`${e} ${i}: ${h.message}`)}finally{n!==void 0&&!p&&this.inFlightExtensionDispatches.delete(n)}let f=l&&typeof l=="object"&&typeof l.text=="string"?l.text:"";return f.length>0?this.emitExtensionReply(f):{stopReason:"end_turn"}}cancelExtensionDispatch(e,t){let n=this.inFlightExtensionDispatches.get(e);if(!n)return!1;this.inFlightExtensionDispatches.delete(e);try{n.connection.notify("hydra-acp/commands/cancel",{sessionId:this.sessionId,messageId:e,reason:t})}catch(r){this.logger?.warn(`notify commands/cancel to ${n.extensionName} failed: ${r.message}`)}return n.cancel(t),!0}emitExtensionReply(e){return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
59
+ `),this.workspacePreambleSent=!0}return r}async prompt(e,t,n,r){let o=this.clients.get(e);if(!o)throw fe(new Error("client not attached"),x.SessionNotFound);if(this.closing)throw fe(new Error("session is closing; new prompts cannot be accepted"),x.SessionClosing);let i=Ge();if(this.maybeSeedTitleFromPrompt(t),this._firstPromptSeeded=!0,!(it((t??{})._meta).ancillary===!0)&&this._interactive!==!0){this._interactive=!0,this.cancelOrphanTimer();for(let d of this.interactiveHandlers)try{d(!0)}catch{}}return this.enqueueUserPrompt(o,t,i,n,r)}broadcastPromptReceived(e){this.closeUnsolicitedTurn("superseded",`prompt:${e.messageId}`);let t={clientId:e.originator.clientId};e.originator.name&&(t.name=e.originator.name),e.originator.version&&(t.version=e.originator.version),e.originator.fromSession&&(t.fromSession=e.originator.fromSession),e.originator.fromSessionTitle&&(t.fromSessionTitle=e.originator.fromSessionTitle),e.originator.fromLabel&&(t.fromLabel=e.originator.fromLabel),e.originator.depth!==void 0&&(t.depth=e.originator.depth),this.promptStartedAt=Date.now(),this.turnRanTool=!1,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"prompt_received",messageId:e.messageId,prompt:e.prompt,sentBy:t}},e.clientId);let n=St(e.prompt);n.length>0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{compatFor:"prompt_received"}}}},e.clientId)}recordCurrentUsageSnapshot(){if(this.historyStore===void 0)return;let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let r={};typeof e.costAmount=="number"&&(r.amount=e.costAmount),typeof e.costCurrency=="string"&&(r.currency=e.costCurrency),t.cost=r}if(Object.keys(t).length<=1)return;t._meta={"hydra-acp":{upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}};let n={sessionId:this.sessionId,update:t};this.historyStore.append(this.sessionId,{method:"session/update",params:n,recordedAt:Date.now()}).catch(()=>{})}originatorNeedsTurnComplete(e){return e.wasAmend===!0||e.wasSteer===!0}broadcastTurnComplete(e,t,n,r){let o=t&&typeof t=="object"&&"stopReason"in t&&typeof t.stopReason=="string"?t.stopReason:void 0,i={sessionUpdate:"turn_complete",messageId:Ge()};o!==void 0&&(i.stopReason=o);let a=it(t?._meta).salvaged;a!==void 0&&(i._meta={[le]:{salvaged:a}}),this.supersededAutonomousTurn=void 0;let d=this.amendInProgress;if(d&&n!==void 0&&d.cancelledMessageId===n&&(i._meta={[le]:{...a!==void 0?{salvaged:a}:{},amended:{cancelledMessageId:d.cancelledMessageId,newMessageId:d.newMessageId}}}),this.promptStartedAt=void 0,this.noteTurnEnded(),this.sawTurnComplete=!0,this.scheduleWorkspaceSnapshotHook?.(),n!==void 0&&o!==void 0){this.recordTerminal(n,o);let c=this.pendingTurnNotifiers.get(n);c&&(this.pendingTurnNotifiers.delete(n),ro(c,{sessionId:this.sessionId,messageId:c.originalMessageId,stopReason:o,deliveredAt:Date.now(),...n!==c.originalMessageId?{amendedTo:n}:{}}))}o==="cancelled"||o==="error"||o==="refusal"?this.closeOpenToolCalls(o):this.armOpenToolCalls(),this.recordCurrentUsageSnapshot(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:i},r?void 0:e),d&&n!==void 0&&d.cancelledMessageId===n&&this.broadcastPromptAmended(d)}noteAgentActivity(e){if(!(this.closing||this.closed)){if(_g(e)||this.steerCausedTurnTerminal(e)){if(this.unsolicitedTurn!==void 0){this.closeUnsolicitedTurn("completed");return}this.salvageSupersededTerminal();return}this.pendingSteerDetach!==void 0&&this.currentEntry?.messageId===this.pendingSteerDetach.messageId&&Cd(e)&&(this.pendingSteerDetach=void 0),!In("session/update",e)&&(this.noteBackgroundTaskArming(e),this.unsolicitedTurn===void 0&&(this.promptInFlight||!this.sawTurnComplete||$g(e)||this.openUnsolicitedTurn()))}}steerCausedTurnTerminal(e){return this.unsolicitedTurn?.steerCaused!==!0?!1:Cd(e)}noteBackgroundTaskArming(e){let t=e?.update;if(!t||typeof t!="object")return;let n=typeof t.toolCallId=="string"?t.toolCallId:void 0;if(n===void 0)return;let r=t.rawInput,o=Vg(t._meta);this.rememberToolLabel(n,t,r,o),this.noteBackgroundTaskStopped(t,r,o);let i=Jg(t.rawOutput),a=typeof o?.toolResponse?.taskId=="string"?o.toolResponse.taskId:i??zg(t.rawOutput),d=i!==void 0||r?.background===!0;if(!(a!==void 0||d||r!==void 0&&r.run_in_background===!0))return;let u=this.toolLabels.get(n)?.label??"background task";this.lastBackgroundTask={toolCallId:n,label:u};let l=Date.now(),p=this.armedTasks.get(n),f=a??p?.taskId,h=qg(t.title,o,r)||p?.repeating===!0;this.armedTasks.set(n,{label:u,...f!==void 0?{taskId:f}:{},repeating:h,armedAt:p?.armedAt??l,...d||p?.endUnobservable===!0?{endUnobservable:!0}:{}}),this.onArmedTasksChanged()}applyBackgroundTaskLevel(e){let t=e?.message;if(!t||t.subtype!=="background_tasks_changed")return;let n=t.tasks;if(!Array.isArray(n))return;let r=Date.now(),o=new Map;for(let a of n){let d=a,c=typeof d?.task_id=="string"?d.task_id:void 0;c!==void 0&&o.set(c,{taskType:typeof d?.task_type=="string"?d.task_type:"unknown",description:typeof d?.description=="string"?d.description:"",firstSeen:this.liveBackgroundTasks.get(c)?.firstSeen??r})}let i=[...this.liveBackgroundTasks.keys()].filter(a=>!o.has(a));this.liveBackgroundTasks=o,this.sawBackgroundTaskLevel=!0,this.logger?.info(`session ${this.sessionId} background level: ${o.size} live`+(i.length>0?` (ended: ${i.join(", ")})`:"")),this.onArmedTasksChanged()}get armedBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.entries()].map(([e,t])=>({taskId:e,label:t.description||t.taskType,taskType:t.taskType,since:t.firstSeen})):[...this.armedTasks.entries()].map(([e,t])=>({toolCallId:e,label:t.label,...t.taskId!==void 0?{taskId:t.taskId}:{},since:t.armedAt}))}pendingOneShotBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.values()].filter(e=>Dg.has(e.taskType)).map(e=>e.description||e.taskType):[...this.armedTasks.values()].filter(e=>!e.repeating&&e.endUnobservable!==!0).map(e=>e.label)}get armedSince(){let e;if(this.sawBackgroundTaskLevel){for(let t of this.liveBackgroundTasks.values())(e===void 0||t.firstSeen<e)&&(e=t.firstSeen);return e}for(let t of this.armedTasks.values())(e===void 0||t.armedAt<e)&&(e=t.armedAt);return e}onArmedTasksChanged(){let e=this.armedBackgroundTasks,t=e.length,n=this.armedSince,r=e.map(o=>o.taskId??o.toolCallId??o.label).sort().join("\0");r===this.lastArmedBroadcast?.key&&n===this.lastArmedBroadcast?.since||this.closed||(this.lastArmedBroadcast={key:r,since:n},this.broadcastQueueNotification("hydra-acp/session/armed_tasks_updated",{sessionId:this.sessionId,count:t,...n!==void 0?{since:n}:{},tasks:e}),this.dispatchIdle())}async retireAgent(e,t){return await e.kill().catch(()=>{}),this.resetBackgroundTaskLevel(),this.discardArmedTasks(t)}resetBackgroundTaskLevel(){this.liveBackgroundTasks.clear(),this.sawBackgroundTaskLevel=!1}discardArmedTasks(e){if(this.armedTasks.size===0)return[];let t=[...this.armedTasks.values()].map(n=>n.label);for(let[n,r]of this.armedTasks)r.openToolCall===!0&&this.openToolCalls.delete(n);return this.armedTasks.clear(),this.logger?.info(`session ${this.sessionId} discarded ${t.length} armed task(s) on ${e}: ${t.join(", ")}`),this.onArmedTasksChanged(),t}noteBackgroundTaskStopped(e,t,n){if(!(n?.toolName==="TaskStop"||e.title==="TaskStop"))return;let o=t?.task_id;if(typeof o!="string"||o.length===0)return;let i=!1;for(let[a,d]of this.armedTasks)d.taskId===o&&(this.armedTasks.delete(a),i=!0);i&&this.onArmedTasksChanged()}rememberToolLabel(e,t,n,r){let o=n!==void 0&&typeof n.description=="string"&&n.description?n.description:void 0;if(o!==void 0)this.toolLabels.set(e,{label:o.slice(0,mo),fromDescription:!0});else if(this.toolLabels.get(e)?.fromDescription!==!0){let i=typeof t.title=="string"&&t.title?t.title:typeof r?.toolName=="string"&&r.toolName?r.toolName:void 0;i!==void 0&&this.toolLabels.set(e,{label:i.slice(0,mo),fromDescription:!1})}for(;this.toolLabels.size>Ng;){let i=this.toolLabels.keys().next().value;if(i===void 0)break;this.toolLabels.delete(i)}}openUnsolicitedTurn(){let e=Date.now();if(this.lastUnsolicitedCancelAt!==0&&e-this.lastUnsolicitedCancelAt<=s.UNSOLICITED_REOPEN_WINDOW_MS?this.cancelReopenStreak+=1:this.cancelReopenStreak=0,this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak>=s.UNSOLICITED_REOPEN_LIMIT){this.escalateUnresponsiveCancel();return}let t=this.lastBackgroundTask,n=!1;for(let[i,a]of this.armedTasks)a.repeating||a.openToolCall===!0||(this.armedTasks.delete(i),n=!0);n&&this.onArmedTasksChanged();let r={messageId:Ge(),startedAt:e,cause:t,steerCaused:this.pendingSteerDetach!==void 0};this.pendingSteerDetach=void 0,this.unsolicitedTurn=r,this.promptStartedAt=e,this.logger?.info(`session ${this.sessionId} agent resumed with no prompt in flight`+(t?` (after ${t.label})`:""));let o={unsolicited:!0};t&&(o.cause=t),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_started",messageId:r.messageId,_meta:{"hydra-acp":o}}})}async holdForUnsolicitedTurn(e){if(this.unsolicitedTurn===void 0){this.logger?.info(`session ${this.sessionId} queue hold skipped for ${e.messageId} (no unsolicited turn open)`);return}let t=Date.now(),n=this.unsolicitedTurn.cause;this.logger?.info(`session ${this.sessionId} holding ${e.messageId} behind unsolicited turn ${this.unsolicitedTurn.messageId}`+(n?` cause=${JSON.stringify(n.label)}`:"")),this.broadcastQueueNotification("hydra-acp/prompt_queue/held",{sessionId:this.sessionId,messageId:e.messageId,reason:"agent_resumed",...n?{cause:n}:{}});let r="turn_ended";for(;;){if(this.closing||this.closed){r="closing";break}if(e.cancelled){r="cancelled";break}if(this.unsolicitedTurn===void 0){r="turn_ended";break}await new Promise(i=>{let a=setTimeout(i,jg);typeof a.unref=="function"&&a.unref()})}let o=Date.now()-t;this.logger?.info(`session ${this.sessionId} released ${e.messageId} reason=${r} heldMs=${o}`),this.broadcastQueueNotification("hydra-acp/prompt_queue/released",{sessionId:this.sessionId,messageId:e.messageId,reason:r,heldMs:o})}closeUnsolicitedTurn(e,t){let n=this.unsolicitedTurn;if(n===void 0)return;let r=Date.now()-n.startedAt;this.unsolicitedTurn=void 0,this.promptStartedAt=void 0,this.noteTurnEnded(),e==="cancelled"?this.lastUnsolicitedCancelAt=Date.now():(this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak=0),this.logger?.info(`session ${this.sessionId} unsolicited turn ${n.messageId} closed reason=${e} durationMs=${r}`+(t?` by=${t}`:"")+(n.cause?` cause=${JSON.stringify(n.cause.label)}`:"")),e==="superseded"&&(this.supersededAutonomousTurn={turnMessageId:n.messageId,cause:n.cause,supersededAt:Date.now()}),this.recordCurrentUsageSnapshot(),!this.closed&&(e==="cancelled"?this.closeOpenToolCalls("cancelled"):e==="completed"&&this.armOpenToolCalls(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_ended",messageId:Ge(),startedMessageId:n.messageId,durationMs:r,_meta:{"hydra-acp":{unsolicited:!0,reason:e}}}}))}salvageSupersededTerminal(){let e=this.supersededAutonomousTurn;if(e===void 0)return;this.supersededAutonomousTurn=void 0;let t=this.autonomousSalvage;t!==void 0&&(this.autonomousSalvage=void 0,this.logger?.warn(`session ${this.sessionId} salvaged session/prompt from autonomous terminal (superseded turn ${e.turnMessageId}, ${Date.now()-e.supersededAt}ms earlier)`+(e.cause?` cause=${JSON.stringify(e.cause.label)}`:"")),t({stopReason:"end_turn",_meta:{[le]:{salvaged:{reason:"autonomous_terminal",supersededMessageId:e.turnMessageId}}}}))}async awaitPromptResponse(e){if(this.supersededAutonomousTurn===void 0)return e;try{return await new Promise((t,n)=>{this.autonomousSalvage=t,e.then(t,n)})}finally{this.autonomousSalvage=void 0}}recordTerminal(e,t){for(this.recentlyTerminal.set(e,{stopReason:t,terminatedAt:Date.now()});this.recentlyTerminal.size>Pg;){let n=this.recentlyTerminal.keys().next().value;if(n===void 0)break;this.recentlyTerminal.delete(n)}}registerTurnNotify(e,t,n){let r=this.recentlyTerminal.get(e);if(r)return{alreadyTerminal:!0,stopReason:r.stopReason};for(this.pendingTurnNotifiers.set(e,{callbackUrl:t,secret:n,registeredAt:Date.now(),originalMessageId:e});this.pendingTurnNotifiers.size>Eg;){let o=this.pendingTurnNotifiers.keys().next().value;if(o===void 0)break;this.pendingTurnNotifiers.delete(o)}return{alreadyTerminal:!1}}broadcastPromptAmended(e){let t=this.findUserEntry(e.newMessageId);if(!t)return;let n={sessionId:this.sessionId,cancelledMessageId:e.cancelledMessageId,newMessageId:e.newMessageId,prompt:t.prompt,originator:t.originator,amendedAt:Date.now()};this.broadcastQueueNotification("hydra-acp/prompt/amended",n)}findUserEntry(e){if(this.currentEntry?.messageId===e&&this.currentEntry.kind==="user")return this.currentEntry;let t=this.promptQueue.find(n=>n.messageId===e&&n.kind==="user");return t?.kind==="user"?t:void 0}visibleQueueDepth(){let e=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;for(let t of this.promptQueue)t.kind==="user"&&!t.cancelled&&(e+=1);return e}broadcastQueueAdded(e,t){let n=this.visibleQueueDepth(),r=t?.position??Math.max(0,n-1),o={sessionId:this.sessionId,messageId:e.messageId,originator:e.originator,prompt:e.prompt,position:r,queueDepth:n,enqueuedAt:e.enqueuedAt};t?.amending!==void 0&&(o._meta={"hydra-acp":{amending:t.amending}}),this.broadcastQueueNotification("hydra-acp/prompt_queue/added",o)}broadcastQueueUpdated(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/updated",{sessionId:this.sessionId,messageId:e,prompt:t})}broadcastQueueRemoved(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/removed",{sessionId:this.sessionId,messageId:e,reason:t})}broadcastQueueNotification(e,t){for(let n of this.clients.values())n.connection.notify(e,t).catch(()=>{})}queueSnapshot(){let e=[],t=0;this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled&&e.push({messageId:this.currentEntry.messageId,originator:this.currentEntry.originator,prompt:this.currentEntry.prompt,position:t++,enqueuedAt:this.currentEntry.enqueuedAt});for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push({messageId:n.messageId,originator:n.originator,prompt:n.prompt,position:t++,enqueuedAt:n.enqueuedAt});return e}async flushPersistWrites(){await this.queueWriteChain.catch(()=>{})}replayPersistedQueue(e){for(let t of e){let n={clientId:`hydra-resurrected_${t.messageId}`};t.originator.clientInfo.name!==void 0&&(n.name=t.originator.clientInfo.name),t.originator.clientInfo.version!==void 0&&(n.version=t.originator.clientInfo.version);let r={kind:"user",messageId:t.messageId,originator:n,clientId:n.clientId,prompt:t.prompt,enqueuedAt:t.enqueuedAt,cancelled:!1,resolve:()=>{},reject:()=>{}};this.promptQueue.push(r),this.broadcastQueueAdded(r)}this.drainQueue()}cancelQueuedPrompt(e){if(this.currentEntry?.messageId===e)return{cancelled:!1,reason:"already_running"};let t=this.promptQueue.findIndex(r=>r.messageId===e);if(t<0)return{cancelled:!1,reason:"not_found"};let n=this.promptQueue[t];return n.cancelled=!0,this.promptQueue.splice(t,1),n.kind==="user"&&(this.broadcastQueueRemoved(e,"cancelled"),this.persistRewrite()),this.amendInProgress?.newMessageId===e&&(this.amendInProgress=void 0),n.resolve({stopReason:"cancelled"}),{cancelled:!0,reason:"ok"}}updateQueuedPrompt(e,t){if(this.currentEntry?.messageId===e)return{updated:!1,reason:"already_running"};let n=this.promptQueue.find(r=>r.messageId===e);return!n||n.kind!=="user"?{updated:!1,reason:"not_found"}:(n.prompt=t,this.broadcastQueueUpdated(e,t),this.persistRewrite(),{updated:!0,reason:"ok"})}amendPrompt(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let{targetMessageId:r,prompt:o,replaceQueue:i,onTargetCompleted:a}=t;if(this.currentEntry?.messageId===r&&this.currentEntry.kind==="user"&&!this.currentEntry.cancelled&&this.amendInProgress===void 0)return this.amendOnHead(n,o,r,i);let d=this.promptQueue.find(u=>u.messageId===r&&u.kind==="user");if(d&&d.kind==="user"&&!d.cancelled)return d.prompt=o,this.broadcastQueueUpdated(r,o),this.persistRewrite(),{amended:!0,reason:"ok",messageId:r};let c=this.recentlyTerminal.get(r);return c?c.stopReason==="cancelled"?{amended:!1,reason:"target_cancelled"}:a==="send_anyway"?{amended:!1,reason:"target_completed",messageId:this.enqueueAmendmentAsFollowUp(n,o)}:{amended:!1,reason:"target_completed"}:{amended:!1,reason:"target_not_found"}}amendOnHead(e,t,n,r){let o=Ge(),i={clientId:e.clientId};if(e.clientInfo?.name&&(i.name=e.clientInfo.name),e.clientInfo?.version&&(i.version=e.clientInfo.version),r){let c=[];for(let u of this.promptQueue){if(u.kind==="user"&&!u.cancelled){u.cancelled=!0,this.broadcastQueueRemoved(u.messageId,"cancelled"),u.resolve({stopReason:"cancelled"});continue}c.push(u)}this.promptQueue=c}let a={kind:"user",messageId:o,originator:i,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,wasAmend:!0,resolve:()=>{},reject:()=>{}};this.promptQueue.unshift(a),this.persistRewrite(),this.broadcastQueueAdded(a,{amending:n,position:1}),this.amendInProgress={cancelledMessageId:n,newMessageId:o};let d=this.pendingTurnNotifiers.get(n);return d&&(this.pendingTurnNotifiers.delete(n),this.pendingTurnNotifiers.set(o,d)),this.cancelExtensionDispatch(n,"amended"),this.agent.connection.notify("session/cancel",{sessionId:this.upstreamSessionId}).catch(()=>{}),{amended:!0,reason:"ok",messageId:o}}async steer(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let r=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled;if(r&&this.agent.steeringSupported){this.pendingSteerDetach={messageId:this.currentEntry.messageId};let o;try{o=await this.forwardRequest("_session/steering",t)}catch(d){throw this.pendingSteerDetach=void 0,d}let i=o?.outcome,a=i==="injected"||i==="startedNewTurn"||i==="promptRequired"||i==="failed"?o:{outcome:"failed"};return a.outcome!=="startedNewTurn"&&(this.pendingSteerDetach=void 0),a.outcome==="injected"&&this.recordSteerAsUserMessageChunk(t.prompt,e),a.outcome==="startedNewTurn"?{...a,detached:!0}:a}return r?(this.amendOnHead(n,t.prompt,this.currentEntry.messageId,!1),{outcome:"startedNewTurn"}):t._meta?.steering?.idleBehavior==="promptRequired"?{outcome:"promptRequired",reason:"noRunningTurn"}:(this.prompt(e,{sessionId:t.sessionId,prompt:t.prompt},void 0,{steerOriginated:!0}).catch(o=>{this.logger?.warn(`steer-originated prompt failed to enqueue: ${o.message}`)}),{outcome:"startedNewTurn"})}recordSteerAsUserMessageChunk(e,t){let n=St(e);n.length!==0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{steered:!0}}}},t)}enqueueAmendmentAsFollowUp(e,t){let n=Ge(),r={clientId:e.clientId};e.clientInfo?.name&&(r.name=e.clientInfo.name),e.clientInfo?.version&&(r.version=e.clientInfo.version);let o={kind:"user",messageId:n,originator:r,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,resolve:()=>{},reject:()=>{}};return this.promptQueue.push(o),this.persistRewrite(),this.broadcastQueueAdded(o),this.drainQueue(),n}async cancel(e){if(!this.clients.get(e))throw fe(new Error("client not attached"),x.SessionNotFound);this.logger?.info(`session ${this.sessionId} session/cancel from ${e} promptInFlight=${this.promptInFlight} agentTurnInFlight=${this.agentTurnInFlight} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length}`),this.lastCancelAt=Date.now(),this.currentEntry?.kind==="user"&&this.currentEntry.messageId!==void 0&&this.cancelExtensionDispatch(this.currentEntry.messageId,"cancelled"),this.closeUnsolicitedTurn("cancelled"),this.agentTurnInFlight||this.closeOpenToolCalls("cancelled"),await this.forwardRequest("session/cancel",{sessionId:this.sessionId},new Set,0,"notification")}addTransformer(e){let t=this.transformChain.findIndex(n=>n.name===e.name);t>=0?this.transformChain[t]=e:this.transformChain.push(e),e.intercepts.has("lifecycle:session.opened")&&e.connection.notify("hydra-acp/transformer/session_event",{event:"session.opened",sessionId:this.sessionId}).catch(()=>{})}async forwardRequest(e,t,n=new Set,r=0,o="request"){let i=this.rewriteForAgent(t);for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name))continue;let c=`request:${e}`;if(!d.intercepts.has(c))continue;let u=`t_${ho()}`,l;try{l=await d.connection.request("hydra-acp/transformer/message",{token:u,phase:"request",method:e,direction:"client\u2192agent",sessionId:this.sessionId,envelope:i})}catch(f){this.logger?.warn(`transformer ${d.name} error on ${c}: ${f.message}`);continue}let p=l?.action??"continue";if(p==="stop")return o==="notification"?void 0:l?.payload??wo(e);if(p==="continue"){l?.payload&&typeof l.payload=="object"&&(i=l.payload),n.add(d.name);continue}if(p==="processing"){let f=a,h=i,w=new Set(n);return new Promise(m=>{let g=setTimeout(()=>{this.pendingClaims.delete(u)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:u,transformerName:d.name}),this.forwardRequest(e,h,new Set([...w,d.name]),f+1,o).then(m).catch(()=>m(o==="notification"?void 0:wo(e))))},ws);typeof g.unref=="function"&&g.unref(),this.pendingClaims.set(u,{resolve:m,timer:g,transformerName:d.name,method:e,envelope:h,chainIdx:f,originatedBy:w,side:"request",tailKind:o})})}n.add(d.name)}if(o==="notification"){await this.agent.connection.notify(e,i);return}return this.agent.connection.request(e,i)}async forwardModelChange(e,t){let n=await ct({request:(r,o)=>this.forwardRequest(r,o),sessionId:this.sessionId,modelId:e,verb:this.modelVerb,extraParams:t,logger:this.logger});return this.modelVerb=n.verb,this.modelVerbConfirmed=!0,n.result}noteModelVerbHint(e,t){e===void 0||this.modelVerbConfirmed||e===this.modelVerb||(this.logger?.info(`model verb for agent ${this.agentId} inferred as ${e} from ${t} (was ${this.modelVerb})`),this.modelVerb=e)}resetModelVerb(e){this.modelVerb=e??ze,this.modelVerbConfirmed=!1}async runAgentRequestChain(e,t,n=new Set,r=0){let o=t,i=`request:${e}`;for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name)||!d.intercepts.has(i))continue;let c=`t_${ho()}`,u;try{u=await d.connection.request("hydra-acp/transformer/message",{token:c,phase:"request",method:e,direction:"agent\u2192client",sessionId:this.sessionId,envelope:o})}catch(p){this.logger?.warn(`transformer ${d.name} error on ${i}: ${p.message}`);continue}let l=u?.action??"continue";if(l==="stop")return{shortCircuit:!0,payload:u?.payload??dh(e)};if(l==="continue"){u?.payload&&typeof u.payload=="object"&&(o=u.payload),n.add(d.name);continue}if(l==="processing"){let p=a,f=o,h=new Set(n),w=e;return new Promise(m=>{let g=setTimeout(()=>{this.pendingClaims.delete(c)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:c,transformerName:d.name}),this.runAgentRequestChain(w,f,new Set([...h,d.name]),p+1).then(m).catch(()=>m({shortCircuit:!1,envelope:f})))},ws);typeof g.unref=="function"&&g.unref(),this.pendingClaims.set(c,{resolve:y=>m({shortCircuit:!0,payload:y}),timer:g,transformerName:d.name,method:w,envelope:f,chainIdx:p,originatedBy:h,side:"agent-request"})})}n.add(d.name)}return{shortCircuit:!1,envelope:o}}dischargeClaim(e,t){let n=this.pendingClaims.get(e);return n?(clearTimeout(n.timer),this.pendingClaims.delete(e),n.resolve(t),!0):!1}keepAliveClaim(e,t){let n=this.pendingClaims.get(e);if(!n)return!1;clearTimeout(n.timer);let r=typeof t=="number"&&t>0?Math.min(t*1.5,1800*1e3):ws,o=setTimeout(()=>{if(this.pendingClaims.delete(e))if(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:e,transformerName:n.transformerName}),n.side==="response")this.runResponseChain(n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1).then(()=>n.resolve(void 0)).catch(()=>n.resolve(void 0));else if(n.side==="agent-request")this.runAgentRequestChain(n.method,n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1).then(n.resolve).catch(()=>n.resolve({shortCircuit:!1,envelope:n.envelope}));else{let i=n.tailKind??"request";this.forwardRequest(n.method,n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1,i).then(n.resolve).catch(()=>n.resolve(i==="notification"?void 0:wo(n.method)))}},r);return typeof o.unref=="function"&&o.unref(),n.timer=o,!0}async emitToChain(e,t,n){let r=this.transformChain.findIndex(a=>a.name===e),o=r>=0?r+1:0,i=new Set([e]);if(t==="session/update"){await this.runResponseChain(n,i,o);return}return this.forwardRequest(t,n,i,o)}async emitToQueue(e,t){let n=this.transformChain.findIndex(c=>c.name===e),r=n>=0?n+1:0,o=(t??{}).prompt??[],i=Ge(),a=`transformer:${e}`,d={clientId:a,name:e};return new Promise((c,u)=>{let l={kind:"user",messageId:i,originator:d,clientId:a,prompt:o,enqueuedAt:Date.now(),cancelled:!1,emitterName:e,chainStartIdx:r,resolve:c,reject:u},p=this.insertEntryAt(l,"tail");this.persistRewrite(),this.broadcastQueueAdded(l,{position:p}),this.drainQueue()})}rewriteForAgent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.sessionId===this.sessionId)return{...t,sessionId:this.upstreamSessionId}}return e}async close(e={}){if(e.deleteRecord&&(this.deleteRecordIntent=!0),!this.closed)return this.closeInFlight?this.closeInFlight:(this.closing=!0,this.closeInFlight=this.doClose(e),this.closeInFlight)}async doClose(e){let t=this.turnStartedAt!==void 0;this.logger?.info(`session ${this.sessionId} closing deleteRecord=${e.deleteRecord??!1} by=${e.by??"unknown"} midTurn=${t} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length} awaitingPermission=${this.hasPermissionFlag}`),t&&this.logger?.warn(`session ${this.sessionId} closed mid-turn by=${e.by??"unknown"}; the in-flight turn will not settle and the agent is being killed`),this.cancelIdleTimer(),this.cancelOrphanTimer();for(let n of this.pendingClaims.values())clearTimeout(n.timer);this.pendingClaims.clear(),await this.agent.kill().catch(()=>{}),this.markClosed({deleteRecord:e.deleteRecord??!1})}onClose(e){return this.closeHandlers.push(e),()=>{let t=this.closeHandlers.indexOf(e);t>=0&&this.closeHandlers.splice(t,1)}}onTitleChange(e){this.titleHandlers.push(e)}retitle(e){return this.runTitleCommand(e)}retitleFromAgent(){return this.runTitleCommand("")}setTitle(e){let t=e.trim();if(!(!t||t===this.title)){this._titleSeedPending=!1,this.title=t,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",title:t,updatedAt:new Date().toISOString()}});for(let n of this.titleHandlers)try{n(t)}catch{}}}maybeSeedTitleFromPrompt(e){if(!this._titleSeedPending||it((e??{})._meta).ancillary===!0||this.promptCarriesSentBy(e))return;let r=St((e??{}).prompt),o=vo(r,200);!o||o.startsWith("/")||(this._titleSeedPending=!1,this.setTitle(o))}maybeApplyAgentModel(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="_hydra_current_model_update")return!1;let r=An(n.availableModels);r.length>0&&this.setAgentAdvertisedModels(r);let o=typeof n.currentModel=="string"?n.currentModel:typeof n.model=="string"?n.model:void 0;if(o===void 0)return!0;let i=o.trim();if(!i||i===this.currentModel)return!0;this.logger?.info(`live current_model_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(i)}`),this.currentModel=i;for(let a of this.modelHandlers)try{a(i)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentConfigOption(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="config_option_update")return!1;let r=n.configOptions;if(!Array.isArray(r))return!0;for(let i of r)this.applyOneConfigOptionEntry(i);let o=new Set(r.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i&&i!=="model"&&i!=="mode"&&i!=="agent"));return this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id)),this.fireConfigOptionsHandlers(),!0}applyAgentConfigOptionResponse(e,t){let n=e?.configOptions;if(!Array.isArray(n))return!1;let r=JSON.stringify(this.agentAdvertisedConfigOptions);for(let o of n){let i=o?.id;i==="model"||i==="mode"||i==="agent"||this.applyOneConfigOptionEntry(o)}if(Og(n,t)){let o=new Set(n.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i));this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id))}return JSON.stringify(this.agentAdvertisedConfigOptions)!==r}applyOneConfigOptionEntry(e){if(!e||typeof e!="object")return;let t=e;if(t.id==="model"){let w=An(t.options);w.length>0&&this.setAgentAdvertisedModels(w);let m=t.currentValue;if(typeof m=="string"){let g=m.trim();g&&g!==this.currentModel&&(this.logger?.info(`live config_option_update(model): sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(g)}`),this.applyModelChange(g))}return}if(t.id==="mode"){let w=ks(t.options);w.length>0&&this.setAgentAdvertisedModes(w);let m=t.currentValue;if(typeof m=="string"){let g=m.trim();g&&g!==this.currentMode&&(this.logger?.info(`live config_option_update(mode): sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(g)}`),this.applyModeChange(g))}return}if(typeof t.id!="string"||!t.id.trim())return;let n=t.id.trim(),r=ko(t.options);if(r.length===0)return;let o=t.name,i=typeof o=="string"&&o.trim()?o.trim():n,a=t.category,d=typeof a=="string"&&a.trim()?a.trim():"other",c=t.description,u=typeof c=="string"&&c.trim()?c.trim():void 0,l=t.currentValue,p=typeof l=="string"&&l.trim()?l.trim():r[0].value,f={id:n,name:i,category:d,type:"select",currentValue:p,options:r,...u?{description:u}:{}},h=this.agentAdvertisedConfigOptions.findIndex(w=>w.id===n);h>=0?this.agentAdvertisedConfigOptions[h]=f:this.agentAdvertisedConfigOptions.push(f)}maybeApplyAgentMode(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="current_mode_update")return!1;let r=typeof n.currentModeId=="string"?n.currentModeId:typeof n.currentMode=="string"?n.currentMode:typeof n.mode=="string"?n.mode:void 0;if(r===void 0)return!0;let o=r.trim();if(!o||o===this.currentMode)return!0;this.logger?.info(`current_mode_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(o)}`),this.currentMode=o;for(let i of this.modeHandlers)try{i(o)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentUsage(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="usage_update")return!1;let r={...this._currentUsage??{}},o=!1;if(typeof n.used=="number"&&!this.swapInFlight&&ud(r.used,n.used)&&this.armRecallFromSelfCompaction(),typeof n.used=="number"&&r.used!==n.used&&(r.used=n.used,o=!0),typeof n.size=="number"&&r.size!==n.size&&(r.size=n.size,o=!0),n.cost&&typeof n.cost=="object"){let a=n.cost;typeof a.amount=="number"&&(this.reconcileCostLedger(a.amount)&&(o=!0),r.costAmount!==a.amount&&(r.costAmount=a.amount,o=!0)),typeof a.currency=="string"&&r.costCurrency!==a.currency&&(r.costCurrency=a.currency,o=!0)}if(!o)return!0;this._currentUsage=r;let i=this.persistableUsage??r;for(let a of this.usageHandlers)try{a(i)}catch{}return!0}armCostLedgerProbe(){let e=this._currentUsage?.costAmount;typeof e=="number"&&e>0&&(this.costLedgerProbe=e)}reconcileCostLedger(e){let t=this.costLedgerProbe;return t===void 0||(this.costLedgerProbe=void 0,e>=t-1e-6)?!1:(this.cumulativeCost+=t,!0)}notifyAgentChange(e,t,n,r){let o=this.retiringGenerationCost;this.retiringGenerationCost=void 0;let i=this.retiringGenerationUsed;this.retiringGenerationUsed=void 0;let a=this.rotationLifetimeCost;this.rotationLifetimeCost=void 0;for(let d of this.agentChangeHandlers)try{d({agentId:this.agentId,upstreamSessionId:this.upstreamSessionId,...o!==void 0?{retiredCost:o}:{},...a!==void 0?{lifetimeCost:a}:{},...i!==void 0?{retiredUsed:i}:{},...r!==void 0?{startedUsed:r}:{},...t!==void 0?{reason:t}:{},...n!==void 0?{runId:n}:{}})}catch(c){this.logger?.warn(`${e}: agentChange handler failed: ${c.message}`)}}accumulateAndResetCost(){let e=this._currentUsage?.costAmount;e&&(this.cumulativeCost+=e,this.retiringGenerationCost=e);let t=this._currentUsage?.used;typeof t=="number"&&t>0&&(this.retiringGenerationUsed=t),this.rotationLifetimeCost=this.cumulativeCost;let n={used:0,cumulativeCost:this.cumulativeCost,...typeof this._currentUsage?.size=="number"?{size:this._currentUsage.size}:{},...this._currentUsage?.costCurrency?{costCurrency:this._currentUsage.costCurrency}:{}};this._currentUsage=n;for(let r of this.usageHandlers)try{r(n)}catch{}this.broadcastCurrentUsage()}broadcastCurrentUsage(){let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let n={};typeof e.costAmount=="number"&&(n.amount=e.costAmount),typeof e.costCurrency=="string"&&(n.currency=e.costCurrency),t.cost=n}this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:t})}injectCumulativeCost(e){if(!this.cumulativeCost||!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update;if(n.sessionUpdate!=="usage_update"||!n.cost||typeof n.cost!="object")return e;let r=n.cost;return typeof r.amount!="number"?e:{...t,update:{...n,cost:{...r,amount:this.cumulativeCost+r.amount}}}}get totalUsage(){return this.currentUsage}setAgentAdvertisedCommands(e){if(Gg(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(Kg(this.agentAdvertisedModes,e)){this.broadcastAvailableModes();return}this.agentAdvertisedModes=e;for(let t of this.agentModesHandlers)try{t(e)}catch{}this.broadcastAvailableModes()}setAgentAdvertisedModels(e){if(this.logger?.info(`setAgentAdvertisedModels: sessionId=${this.sessionId} currentModel=${JSON.stringify(this.currentModel)} newList=[${e.map(t=>t.modelId).join(",")}]`),Qg(this.agentAdvertisedModels,e)){this.broadcastAvailableModels();return}this.agentAdvertisedModels=e;for(let t of this.agentModelsHandlers)try{t(e)}catch{}this.broadcastAvailableModels()}onAgentCommandsChange(e){this.agentCommandsHandlers.push(e)}onAgentModesChange(e){this.agentModesHandlers.push(e)}onAgentModelsChange(e){this.agentModelsHandlers.push(e)}onConfigOptionsChange(e){this.configOptionsHandlers.push(e)}extraConfigOptionValues(){return Object.fromEntries(this.agentAdvertisedConfigOptions.map(e=>[e.id,e.currentValue]))}onModelChange(e){this.modelHandlers.push(e)}onModeChange(e){this.modeHandlers.push(e)}onInteractiveChange(e){this.interactiveHandlers.push(e)}onPriorityChange(e){this.priorityHandlers.push(e)}onReadStateChange(e){this.readStateHandlers.push(e)}get unread(){return kn(this._lastTurnEndedAt,this._readAt)}setRead(e,t=Date.now()){let n=ps({lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt},e,t);n!==void 0&&(this._readAt=n,this.fireReadState())}noteTurnEnded(e=Date.now()){this._readAt===void 0&&(this._readAt=Math.min(this._lastTurnEndedAt??this.createdAt,e-1)),this._lastTurnEndedAt=e,this.fireReadState()}fireReadState(){let e={lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt};for(let t of this.readStateHandlers)try{t(e)}catch{}}setPriority(e){let t=e===void 0||e<=0?void 0:Math.floor(e);if(t!==this._priority){this._priority=t,this.updatedAt=Date.now();for(let n of this.priorityHandlers)try{n(t)}catch{}}}applyModelChange(e){let t=e.trim();if(t){this.modelChangeInFlight=!0;try{if(t!==this.currentModel){this.logger?.info(`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(t)}`),this.currentModel=t;for(let r of this.modelHandlers)try{r(t)}catch{}}let n={sessionUpdate:"_hydra_current_model_update",currentModel:t};this.agentAdvertisedModels.length>0&&(n.availableModels=[...this.agentAdvertisedModels]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modelChangeInFlight=!1}}}applyModeChange(e){let t=e.trim();if(t){this.modeChangeInFlight=!0;try{if(t!==this.currentMode){this.logger?.info(`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(t)}`),this.currentMode=t;for(let r of this.modeHandlers)try{r(t)}catch{}}let n={sessionUpdate:"current_mode_update",currentModeId:t};this.agentAdvertisedModes.length>0&&(n.availableModes=[...this.agentAdvertisedModes]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modeChangeInFlight=!1}}}buildConfigOptions(){let e=[];if(this.agentAdvertisedModels.length>0){let r=this.agentAdvertisedModels.map(i=>({value:i.modelId,name:i.name??i.modelId,...i.description!==void 0?{description:i.description}:{}}));this.currentModel&&!r.some(i=>i.value===this.currentModel)&&r.unshift({value:this.currentModel,name:this.currentModel});let o=this.currentModel||r[0].value;e.push({id:"model",name:"Model",category:"model",type:"select",currentValue:o,options:r})}if(this.agentAdvertisedModes.length>0){let r=this.agentAdvertisedModes.map(i=>({value:i.id,name:i.name??i.id,...i.description!==void 0?{description:i.description}:{}}));this.currentMode&&!r.some(i=>i.value===this.currentMode)&&r.unshift({value:this.currentMode,name:this.currentMode});let o=this.currentMode||r[0].value;e.push({id:"mode",name:"Session Mode",category:"mode",type:"select",currentValue:o,options:r})}let n=(this.availableAgentsFn?.()??[]).map(r=>({value:r.id,name:r.name??r.id,...r.description!==void 0?{description:r.description}:{}}));return n.some(r=>r.value===this.agentId)||n.unshift({value:this.agentId,name:this.agentId}),e.push({id:"agent",name:"Agent",category:"_hydra_agent",type:"select",currentValue:this.agentId,options:n}),e.push(...this.agentAdvertisedConfigOptions),e}broadcastConfigOptions(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"config_option_update",configOptions:this.buildConfigOptions()}}),this.fireConfigOptionsHandlers()}fireConfigOptionsHandlers(){for(let e of this.configOptionsHandlers)try{e(this.agentAdvertisedConfigOptions)}catch{}}mergeAgentOptionIntoEnvelope(e){if(!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update,r=Array.isArray(n.configOptions)?[...n.configOptions]:[];if(r.some(a=>a&&typeof a=="object"&&a.id==="agent"))return e;let i=this.buildConfigOptions().find(a=>a.id==="agent");return i?{...t,update:{...n,configOptions:[...r,i]}}:e}onUsageChange(e){this.usageHandlers.push(e)}mergedAvailableCommands(){let e=this.daemonTopLevelCommands(),t=this.aliasableBareVerbs();for(let n of qt){if(t.get(n.verb)!=="__hydra__")continue;let r=n.argsHint?`${n.verb} ${n.argsHint}`:n.verb;e.push({name:r,description:`Alias for '/hydra ${n.verb}': ${n.description}`})}if(this.extensionCommands)for(let{name:n,command:r}of this.extensionCommands.list()){let o=r.verb?`hydra ${n} ${r.verb}`:`hydra ${n}`,a={name:r.argsHint?`${o} ${r.argsHint}`:o};r.description&&(a.description=r.description),e.push(a);let d=so(n),c=d??n;if(d!==void 0){let u=r.verb?`hydra ${c} ${r.verb}`:`hydra ${c}`,p={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(p.description=r.description),e.push(p)}if(c.length>0&&t.get(c)===n){let u=r.verb?`${c} ${r.verb}`:c,p={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(p.description=r.description),e.push(p)}}return e.push(...this.agentAdvertisedCommands),e}daemonTopLevelCommands(){return[{name:"hydra",description:"Hydra session command (kill, restart, title, agent <agent>)"},{name:"model",description:"Switch model; omit arg to list available models"},{name:"mode",description:"Switch mode; omit arg to list available modes"},{name:"sessions",description:"List all sessions"},{name:"help",description:"Show available commands"}]}aliasableBareVerbs(){let e=new Set,t=i=>i.split(/\s+/)[0]??"";for(let i of this.daemonTopLevelCommands()){let a=t(i.name);a&&e.add(a)}for(let i of this.agentAdvertisedCommands){let a=t(i.name),d=a.startsWith("/")?a.slice(1):a;d&&e.add(d)}let n=new Map;for(let i of qt)e.has(i.verb)||n.set(i.verb,"__hydra__");if(!this.extensionCommands)return n;let r=new Map,o=new Set;for(let{name:i}of this.extensionCommands.list()){if(o.has(i))continue;o.add(i);let a=so(i)??i;if(!a||e.has(a)||n.has(a))continue;let d=r.get(a);d===void 0?r.set(a,i):d!==i&&r.set(a,"__conflict__")}for(let[i,a]of r)a!=="__conflict__"&&n.set(i,a);return n}agentOnlyAdvertisedCommands(){return[...this.agentAdvertisedCommands]}agentKnowsSlashCommand(e){let t=r=>r.startsWith("/")?r.slice(1):r,n=t(e);if(!n)return!1;for(let r of this.agentAdvertisedCommands)if(t(r.name.split(/\s+/)[0]??"")===n)return!0;return!1}availableModes(){return[...this.agentAdvertisedModes]}availableModels(){return[...this.agentAdvertisedModels]}maybeApplyAgentSessionInfo(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="session_info_update"||typeof n.title!="string"||this._upstreamRespawned)return;let r=n.title.trim();if(!(!r||r===this.title)){this.title=r,this._firstPromptSeeded=!0,this._titleSeedPending=!1;for(let o of this.titleHandlers)try{o(r)}catch{}}}async handleSlashCommand(e,t){let r=e.slice(6).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),o=r?.[1]??"",i=(r?.[2]??"").trim();if(o==="")return{stopReason:"end_turn"};let a=t!==void 0;if(qt.some(l=>l.verb===o))switch(o){case"title":return a?this.runTitleCommandInline(i):this.runTitleCommand(i);case"agent":return this.runAgentCommandInline(i);case"config":return this.handleConfigCommand(`/config ${i}`);case"kill":return this.runKillCommand();case"workspace":return this.runWorkspaceCommand(i);case"restart":return a?this.runRestartCommandInline():this.runRestartCommand();case"clear":return this.runClearCommand();case"compact":return a?this.runCompactCommandInline(i):this.runCompactCommand(i);case"uncompact":return a?this.runUncompactCommandInline():this.runUncompactCommand();case"fork":return a?this.runForkCommandInline(i,t):this.runForkCommand(i);default:{let l=new Error(`no dispatcher for /hydra verb ${o}`);throw l.code=x.InternalError,l}}if(this.extensionCommands?.has(o))return a?this.runExtensionCommandInline(o,i,t):this.runExtensionCommand(o,i);let d=rd(o).find(l=>this.extensionCommands?.has(l));if(d!==void 0)return a?this.runExtensionCommandInline(d,i,t):this.runExtensionCommand(d,i);let c=qt.map(l=>l.verb);if(this.extensionCommands){let l=new Set;for(let{name:p}of this.extensionCommands.list())l.has(p)||(c.push(p),l.add(p))}let u=new Error(`unknown /hydra verb: ${o} (known: ${c.join(", ")})`);throw u.code=x.InvalidParams,u}runExtensionCommand(e,t){return this.enqueuePrompt(`extension:${e}`,()=>this.runExtensionCommandInline(e,t,void 0))}async runExtensionCommandInline(e,t,n){let r=this.extensionCommands?.get(e);if(!r)return this.emitExtensionReply(`extension "${e}" is no longer connected`);let o=t.match(/^(\S+)(?:\s+([\s\S]*))?$/),i=o?.[1]??"",a=(o?.[2]??"").trim();if(!r.commands.some(h=>h.verb===i)){let h=r.commands.map(w=>w.verb).join(", ");return this.emitExtensionReply(`/hydra ${e}${i?` ${i}`:""}: unknown verb (known: ${h||"(none)"})`)}let d={sessionId:this.sessionId,verb:i,args:a};n!==void 0&&(d.messageId=n);let c=()=>{},u=new Promise(h=>{c=h});n!==void 0&&this.inFlightExtensionDispatches.set(n,{extensionName:e,connection:r.connection,cancel:h=>c({stopReason:"cancelled",reason:h})});let l,p=!1;try{let h=r.connection.request("hydra-acp/commands/invoke",d),w=await Promise.race([h,u]);if(w&&typeof w=="object"&&w.stopReason==="cancelled"&&"reason"in w)return p=!0,this.logger?.info(`extension ${e} ${i} cancelled (cancelExtensionDispatch); abandoning in-flight commands/invoke`),{stopReason:"cancelled"};l=w}catch(h){return this.emitExtensionReply(`${e} ${i}: ${h.message}`)}finally{n!==void 0&&!p&&this.inFlightExtensionDispatches.delete(n)}let f=l&&typeof l=="object"&&typeof l.text=="string"?l.text:"";return f.length>0?this.emitExtensionReply(f):{stopReason:"end_turn"}}cancelExtensionDispatch(e,t){let n=this.inFlightExtensionDispatches.get(e);if(!n)return!1;this.inFlightExtensionDispatches.delete(e);try{n.connection.notify("hydra-acp/commands/cancel",{sessionId:this.sessionId,messageId:e,reason:t})}catch(r){this.logger?.warn(`notify commands/cancel to ${n.extensionName} failed: ${r.message}`)}return n.cancel(t),!0}emitExtensionReply(e){return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
60
60
  ${e}
61
61
  `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}async handleSessionsCommand(){let e;if(!this.listSessions)e="_(session listing not available)_";else{let t=await this.listSessions();if(t.length===0)e="_(no sessions)_";else{let n=t.map(r=>{let o=r.sessionId.replace(/^hydra_session_/,"").slice(0,12),i=r.currentModel?` \xB7 ${r.currentModel}`:"",a=r.sessionId===this.sessionId?" \u25C0":"",d=r.title?` ${r.title}`:"";return`\`${o}\` ${r.cwd}${i}${a}${d}`});e=`Sessions (${t.length}):
62
62
  ${n.join(`
@@ -97,10 +97,10 @@ ${w}:
97
97
  `)}
98
98
  `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}if(n==="model"){if(c!==this.currentModel){let l=await this.forwardModelChange(c);this.applyAgentConfigOptionResponse(l,"model")}return this.applyModelChange(c),{stopReason:"end_turn"}}if(n==="mode")return c!==this.currentMode&&await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:c}),this.applyModeChange(c),{stopReason:"end_turn"};if(n==="agent")return c!==this.agentId&&await this.runAgentCommandInline(c),{stopReason:"end_turn"};let u=await this.forwardRequest("session/set_config_option",{sessionId:this.sessionId,configId:n,value:c});return this.applyAgentConfigOptionResponse(u,n)&&this.broadcastConfigOptions(),{stopReason:"end_turn"}}runTitleCommand(e){return this.enqueuePrompt("title",()=>this.runTitleCommandInline(e))}async runTitleCommandInline(e){return e?(this.setTitle(e),{stopReason:"end_turn"}):(this.scheduleSynopsisHook?.(),{stopReason:"end_turn"})}async runInternalPrompt(e){if(this.internalPromptCapture)throw new Error("internal prompt already in flight");let t={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};this.internalPromptCapture=t;try{return await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:e}]}),t.chunks.join("")}finally{this.internalPromptCapture=void 0}}setAgent(e){return this.runAgentCommandInline(e)}async runAgentCommandInline(e){if(e==="status")return this.runAgentStatusCommandInline();let t=e;if(!t)throw fe(new Error("/hydra agent requires an agent id"),x.InvalidParams);let r=(this.resolveAgentIdHook?await this.resolveAgentIdHook(t):void 0)??t;if(r===this.agentId)throw fe(new Error(`already on agent ${r}`),x.InvalidParams);if(!this.scheduleCompactionHook)return this.emitExtensionReply("agent switching not configured for this session"),{stopReason:"end_turn"};this.scheduleCompactionHook({targetAgentId:r});let o=this.promptInFlight||this.unsolicitedTurn!==void 0;return this.emitExtensionReply(o?`Agent switch to ${r} scheduled. A turn is still in flight \u2014 the rotation lands on the next idle edge; cancel the turn to make that happen now.`:`Agent switch to ${r} scheduled. The session will rotate to ${r} once synthesis completes.`),{stopReason:"end_turn"}}async runAgentStatusCommandInline(){let e=await this.getPendingAgentSwapHook?.();return e?(this.emitExtensionReply(`Agent switch to ${e} pending \u2014 will rotate on the next idle edge.`),{stopReason:"end_turn"}):(this.emitExtensionReply("No agent switch pending."),{stopReason:"end_turn"})}async runKillCommand(){return await this.close({deleteRecord:!1,by:"/hydra kill"}),{stopReason:"end_turn"}}runRestartCommand(){return this.enqueuePrompt("restart",()=>this.runRestartCommandInline())}async runRestartCommandInline(){if(!this.spawnReplacementAgent)throw fe(new Error("agent restart not configured for this session"),x.InternalError);return await this.respawnAgent(),{stopReason:"end_turn"}}runCompactCommand(e){return this.enqueuePrompt("compact",()=>this.runCompactCommandInline(e))}async runCompactCommandInline(e){return e==="status"?this.runCompactStatusCommandInline():this.scheduleCompactionHook?(this.scheduleCompactionHook(),this.emitExtensionReply("Compaction scheduled. The session will rotate to a fresh upstream once summarization completes."),{stopReason:"end_turn"}):(this.emitExtensionReply("compaction scheduling not configured for this session"),{stopReason:"end_turn"})}async runCompactStatusCommandInline(){let e=await this.getCompactionStateHook?.(),t=this._summarizedThroughEntry,n=await this.getUpstreamGenerationsHook?.()??[],r=yd(n,t),o=wd(r);if(e==null&&t==null&&o.length===0)return this.emitExtensionReply("This session has never been compacted."),{stopReason:"end_turn"};let i=[];return e==null?i.push(`No compaction in progress. Last summarized through entry: ${t??0}`):(i.push(`Compaction state: ${e.status}${e.iter!=null?` (iteration ${e.iter})`:""}`,`Summarized through entry: ${t??0}`,`Pending attempts: ${e.attempts??0}`),e.lastError!==void 0&&i.push(`Last error: ${e.lastError}`)),i.push(`Current upstream: ${this.upstreamSessionId}`),o.length>0&&i.push("",...o),this.emitExtensionReply(i.join(`
99
99
  `)),{stopReason:"end_turn"}}runUncompactCommand(){return this.enqueuePrompt("uncompact",()=>this.runUncompactCommandInline())}async runWorkspaceCommand(e){if(!this.workspaceHook)return this.emitExtensionReply("Workspaces are not available on this session (no workspace hook configured)."),{stopReason:"end_turn"};let[t="status",...n]=e.split(/\s+/).filter(d=>d.length>0);if(!Ad.includes(t))return this.emitExtensionReply(`Unknown workspace verb "${t}". Use one of: ${Ad.join(", ")}.`),{stopReason:"end_turn"};let r=n.filter(d=>d.startsWith("--")),o=r.filter(d=>d!=="--clean"&&d!=="--deep");if(o.length>0)return this.emitExtensionReply(`Unknown workspace flag(s) ${o.join(", ")}. Supported: --clean (start), --deep (clean).`),{stopReason:"end_turn"};let i={clean:r.includes("--clean"),deep:r.includes("--deep")};if(i.clean&&t!=="start")return this.emitExtensionReply(`--clean applies to \`start\`, not to \`${t}\`.`),{stopReason:"end_turn"};if(i.deep&&t!=="clean")return this.emitExtensionReply(`--deep applies to \`clean\`, not to \`${t}\`.`),{stopReason:"end_turn"};let a=n.filter(d=>!d.startsWith("--")).join(" ").trim();try{let d=await this.workspaceHook(t,a.length>0?a:void 0,i);this.emitExtensionReply(d)}catch(d){this.emitExtensionReply(`Workspace ${t} failed: ${d instanceof Error?d.message:String(d)}`)}return{stopReason:"end_turn"}}async runUncompactCommandInline(){if(!this.uncompactHook)return this.emitExtensionReply("Rollback not available: uncompact hook not configured for this session."),{stopReason:"end_turn"};try{await this.uncompactHook(),this.emitExtensionReply("Rolled back to pre-compaction upstream. The session is now using the previous agent context.")}catch(e){this.emitExtensionReply(`Rollback failed: ${e instanceof Error?e.message:String(e)}`)}return{stopReason:"end_turn"}}runForkCommand(e){return this.enqueuePrompt("fork",()=>this.runForkCommandInline(e,void 0))}async findMessageIdBefore(e){if(!this.historyStore)return;let t=await this.historyStore.load(this.sessionId),n;for(let r of t){if(r.method!=="session/update")continue;let i=r.params?.update?.messageId;if(typeof i=="string"){if(i===e)return n;n=i}}}async runForkCommandInline(e,t){if(!this.forkHook)return this.emitExtensionReply("Fork not configured for this session."),{stopReason:"end_turn"};let n=(e??"").trim(),r=n.match(/^--verbatim(?:\s+([\s\S]*))?$/),o=r?"verbatim":void 0,i=(r?r[1]??"":n).trim();try{let a={};if(o&&(a.mode=o),i!==""&&(a.prompt=i),t&&this.historyStore){let u=await this.findMessageIdBefore(t).catch(()=>{});u&&(a.forkAt=u)}let c=(await this.forkHook(Object.keys(a).length>0?a:void 0)).sessionId.replace(/^hydra_session_/,"");this.emitExtensionReply(i!==""?`Forked to [\`${c}\`](hydra://sessions/${c}) and sent the prompt.`:`Forked to [\`${c}\`](hydra://sessions/${c}).`)}catch(a){this.emitExtensionReply(`Fork failed: ${a instanceof Error?a.message:String(a)}`)}return{stopReason:"end_turn"}}escalateUnresponsiveCancel(){this.cancelReopenStreak=0,this.logger?.warn(`session ${this.sessionId} agent ${this.agentId} reopened an unsolicited turn right after cancel ${s.UNSOLICITED_REOPEN_LIMIT} times in a row; forcing a restart`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,reason:"unresponsive",message:`${this.agentId} kept resuming after repeated cancels; restarting the agent`}),this.forceCancel().catch(e=>{this.logger?.warn(`session ${this.sessionId} forceCancel after unresponsive-cancel escalation failed: ${e instanceof Error?e.message:String(e)}`)})}async forceCancel(){if(this.closed||this.closing)throw fe(new Error("session is closing"),x.SessionClosing);return this.lastCancelAt=0,this.forceCancelling=!0,await this.close({deleteRecord:!1,by:"force-cancel"}),{stopReason:"cancelled"}}async rewind(e,t,n={}){let r=()=>this.promptInFlight&&!n.afterCurrentTurn||this.promptQueue.length>0?"the session is busy; wait for the current turn and queued prompts to finish, then try again":this.swapInFlight?"the session's agent is being replaced; try again in a moment":void 0,o=r()??await this.quiesceBlocker()??r();if(o!==void 0)throw fe(new Error(o),x.InvalidRequest);if(!this.spawnReplacementAgent)throw fe(new Error("agent restart not configured for this session"),x.InternalError);await this.enqueuePrompt("rewind",async()=>{this.swapInFlight=!0;try{if(!await t())return;await this.respawnAgent({rewind:!0})}finally{this.swapInFlight=!1}this.broadcastClientUpdate({sessionUpdate:"_hydra_history_truncated",keepThrough:e})})}runClearCommand(){if(!this.rewindHook)throw fe(new Error("clear not configured for this session"),x.InternalError);return this.rewindHook(null).catch(e=>{this.broadcastSyntheticText(`/hydra clear failed: ${e.message}`)}),Promise.resolve({stopReason:"end_turn"})}async respawnAgent(e={}){let t=this.spawnReplacementAgent,n=this.agentId,r=await this.buildSwitchTranscript(n,e.rewind?{intro:"You are continuing a conversation whose later turns were withdrawn by the user. Below is the transcript of what remains.",followup:"Each line is prefixed with its speaker. Treat this as context for the next user message; do not re-respond to earlier turns."}:void 0),o=this.currentModel,i=this.currentMode,a=await t({agentId:n,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{}});if(this.accumulateAndResetCost(),this.wireAgent(a.agent,{respawn:!0}),e.rewind){let c=await lt({agent:a.agent,upstreamSessionId:a.upstreamSessionId,persistedModel:o,agentReportedModel:a.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(c.result,"model"),await ut({agent:a.agent,upstreamSessionId:a.upstreamSessionId,persistedMode:i,agentReportedMode:a.initialMode,logger:this.logger}),a.agent.connection.drainBuffered("session/update")}let d=this.agent;this.agent=a.agent,this.upstreamSessionId=a.upstreamSessionId,this.agentMeta=a.agentMeta,this.agentCapabilities=a.agentCapabilities,this.resetModelVerb(a.modelVerb),this.agentAdvertisedCommands=[],this.broadcastMergedCommands(),e.rewind||(this.currentModel=a.initialModel,this.currentMode=a.initialMode),this.setAgentAdvertisedModels(a.initialModels??[]),this.setAgentAdvertisedModes(a.initialModes??[]),this.agentAdvertisedConfigOptions=a.initialConfigOptions??[],await this.retireAgent(d,"agent restart"),r&&await this.runInternalPrompt(r).catch(()=>{}),e.rewind||this.broadcastAgentSwitch(n,n),this.notifyAgentChange("respawnAgent","restart")}async buildSwitchTranscript(e,t){let n=[],r=await this.getHistorySnapshot();for(let c of r){if(c.method!=="session/update")continue;let l=(c.params??{}).update;if(!l||l._meta?.["hydra-acp"]?.synthetic)continue;let f=l.sessionUpdate;if(f==="prompt_received"){let h=St(l.prompt);h&&n.push({speaker:"user",text:h})}else if(f==="agent_message_chunk"){let w=l.content?.text;w&&n.push({speaker:`agent: ${e}`,text:w})}else if(f==="tool_call"||f==="tool_call_update"){let h=l.status,w=l.title;(h==="completed"||h==="failed")&&n.push({speaker:"tool",text:`${w??"?"} ${h}`})}}if(n.length===0)return"";let o=[],i;for(let c of n)i&&i.speaker===c.speaker?i.text+=c.text:(i&&o.push(`<${i.speaker}>: ${i.text.trim()}`),i={speaker:c.speaker,text:c.text});i&&o.push(`<${i.speaker}>: ${i.text.trim()}`);let a=t?.intro??`You are taking over this conversation from ${e}. Below is the transcript so far.`,d=t?.followup??`Each line is prefixed with its speaker. Continue from where ${e} left off, responding to the user's most recent message.`;return[a,d,"","--- begin transcript ---",...o,"--- end transcript ---"].join(`
100
- `)}async seedFromImport(){await this.enqueuePrompt("seed:import",async()=>{let e=await this.buildSwitchTranscript(this.agentId,{intro:"You are continuing a conversation that was imported from another hydra. Below is the transcript so far.",followup:"Each line is prefixed with its speaker. Treat this as context for the next user message; do not re-respond to earlier turns."});e&&await this.runInternalPrompt(e).catch(()=>{})})}async seedFromFork(e){await this.enqueuePrompt("seed:fork",async()=>{let t=this.title??"(untitled)",n=[];if(this.historyStore)try{n=await this.historyStore.load(this.sessionId)}catch(o){this.logger?.warn(`seedFromFork: historyStore.load failed: ${o.message}`)}let r=fo({synopsis:e,title:t,tail:n,tailK:Rg,tailFloor:xg,watermark:this._summarizedThroughEntry,recallArmed:(this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("seedFromFork: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:r}]});let o=this.internalPromptCapture;this.logger?.info(`seedFromFork: seed processed sessionId=${this.sessionId} seedChars=${r.length} toolCalls=${o.toolCalls} thinkingChars=${o.thinkingChars} messageChars=${o.messageChars}`)}finally{this.internalPromptCapture=void 0}})}broadcastAgentSwitch(e,t){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,agentId:t,pendingAgentSwap:null}}}}),this.broadcastConfigOptions()}broadcastPendingAgentSwap(e){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,pendingAgentSwap:e}}}})}hasStreamBuffer(){return this.streamBuffer!==void 0}get streamPath(){return this.streamFilePath}openStream(e){if(this.streamBuffer!==void 0)throw new Error(`stream buffer already open for session ${this.sessionId}`);let n=(e.mode??"memory")==="file"&&e.filePathFor!==void 0?e.filePathFor(this.sessionId):void 0,r={};e.capacityBytes!==void 0&&(r.capacityBytes=e.capacityBytes),n!==void 0&&(r.filePath=n),e.fileCapBytes!==void 0&&(r.fileCapBytes=e.fileCapBytes),r.onFileCapReached=()=>{this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_stream_truncated",...n!==void 0?{filePath:n}:{},fileCapBytes:e.fileCapBytes}})};let o=new gs(r);this.streamBuffer=o,this.streamFilePath=n;let i={capacityBytes:o.capacity};return n!==void 0&&(i.filePath=n),e.fileCapBytes!==void 0&&(i.fileCapBytes=e.fileCapBytes),i}streamWrite(e,t){let n=this.requireStreamBuffer();if(e.length>0){let r=Buffer.from(e,"base64");n.append(r)}return t===!0&&n.close(),{writeCursor:n.writeCursorPos}}async streamRead(e,t,n){let r=this.requireStreamBuffer(),o=Math.max(0,Math.min(t??Wt,Wt)),i=r.read(e,o);if(i.bytes.length===0&&i.eof!==!0&&n!==void 0&&n>0){let d=await r.waitForData(i.nextCursor,n);(d==="data"||d==="eof")&&(i=r.read(i.nextCursor,o))}let a={bytes:i.bytes.toString("base64"),nextCursor:i.nextCursor};return i.gap!==void 0&&(a.gap=i.gap),i.eof===!0&&(a.eof=!0),a}streamTail(e){let n=this.requireStreamBuffer().tail(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}streamHead(e){let n=this.requireStreamBuffer().head(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}async streamWaitFor(e,t){return this.requireStreamBuffer().waitForData(e,t)}streamGrep(e){return this.requireStreamBuffer().grep(e)}streamInfo(){let e=this.requireStreamBuffer();return{writeCursor:e.writeCursorPos,oldestAvailable:e.oldestAvailable,capacity:e.capacity,closed:e.isClosed}}requireStreamBuffer(){if(this.streamBuffer===void 0){let e=new Error(`session ${this.sessionId} has no stream buffer; POST /v1/sessions/:id/stdin/open first`);throw e.code=x.StreamNotEnabled,e}return this.streamBuffer}markClosed(e){if(this.closed)return;this.closeUnsolicitedTurn("closed"),e={deleteRecord:e.deleteRecord||this.deleteRecordIntent},this.closing=!0,this.closed=!0,this.cancelIdleTimer(),this.cancelOrphanTimer(),this.extensionCommandsUnsub&&(this.extensionCommandsUnsub(),this.extensionCommandsUnsub=void 0);for(let o of[...this.inFlightExtensionDispatches.keys()])this.cancelExtensionDispatch(o,"abandoned");this.currentEntry?.kind==="user"&&!this.recentlyTerminal.has(this.currentEntry.messageId)&&this.broadcastTurnComplete(this.currentEntry.clientId,{stopReason:"interrupted"},this.currentEntry.messageId,this.originatorNeedsTurnComplete(this.currentEntry)),this.currentEntry=void 0;let n=this.promptQueue;this.promptQueue=[];for(let o of n){o.cancelled=!0,o.kind==="user"&&this.broadcastQueueRemoved(o.messageId,"abandoned");let i=this.pendingTurnNotifiers.get(o.messageId);i&&(this.pendingTurnNotifiers.delete(o.messageId),ro(i,{sessionId:this.sessionId,messageId:i.originalMessageId,stopReason:"cancelled",deliveredAt:Date.now(),...o.messageId!==i.originalMessageId?{amendedTo:o.messageId}:{}}));try{o.resolve({stopReason:"cancelled"})}catch{}}this.notifyChain("session.closed",{}),this.toolCompletionSeen.clear(),this.toolCallKind.clear(),this.filesEditedSeen.clear(),this.openToolCalls.clear();let r=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Id(r).catch(()=>{}));for(let o of this.clients.values())o.connection.notify("hydra-acp/session/closed",{sessionId:this.sessionId}).catch(()=>{});if(this.clients.clear(),this.streamBuffer!==void 0){let o=this.streamBuffer,i=this.streamFilePath;this.streamBuffer=void 0,this.streamFilePath=void 0,o.close(),i!==void 0&&o.drainFileWrites().then(()=>$d.unlink(i).catch(()=>{}))}for(let o of this.closeHandlers)o(e)}get lastActivityAt(){return this.lastRecordedAt}setAttentionFlag(e,t,n){this._setAttentionFlag(e,t,n,!0)}_setAttentionFlag(e,t,n,r){let o=`${e}::${t}`,i=this.attentionFlags.get(o);if(i){if(JSON.stringify(i.payload)===JSON.stringify(n))return;this.attentionFlags.set(o,{...i,payload:n,raisedAt:i.raisedAt})}else this.attentionFlags.set(o,{source:e,reason:t,raisedAt:Date.now(),payload:n});r&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}clearAttentionFlag(e,t){this._clearAttentionFlag(e,t,!0)}_clearAttentionFlag(e,t,n){let r=`${e}::${t}`;this.attentionFlags.delete(r)&&n&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}listAttentionFlags(){return Array.from(this.attentionFlags.values()).sort((e,t)=>e.raisedAt-t.raisedAt)}listAttentionFlagsBySource(e){return this.listAttentionFlags().filter(t=>t.source===e)}onAttentionFlagsChange(e){this.attentionFlagsChangeHandlers.push(e)}fireAttentionFlagsChange(){let e=this.listAttentionFlags();for(let t of this.attentionFlagsChangeHandlers)try{t(e)}catch{}}broadcastAttentionUpdated(){for(let e of this.clients.values())e.connection.notify("hydra-acp/session/attention_updated",{sessionId:this.sessionId,flags:this.listAttentionFlags()}).catch(()=>{})}scheduleIdleCheck(){if(this.closed||this.idleTimeoutMs<=0)return;let e=this.lastActivityAt+this.idleTimeoutMs;this.armIdleTimer(Math.max(0,e-Date.now()))}armIdleTimer(e){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{this.idleTimer=void 0,this.checkIdle()},e),typeof this.idleTimer.unref=="function"&&this.idleTimer.unref()}checkIdle(){if(this.closed||this.idleTimeoutMs<=0)return;if(this.hasWorkInFlight){this.armIdleTimer(this.idleTimeoutMs);return}let e=Date.now()-this.lastActivityAt;if(e<this.idleTimeoutMs){this.armIdleTimer(this.idleTimeoutMs-e);return}let t=this.firstPromptSeeded?{deleteRecord:!1}:{deleteRecord:!0},n=Math.round(e/1e3);this.logger?.info(`session ${this.sessionId} idle timeout fired after ${n}s (window=${Math.round(this.idleTimeoutMs/1e3)}s) \u2014 closing`),this.close(t).catch(()=>{})}cancelIdleTimer(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=void 0),this.disposeIdleHandlers()}scheduleOrphanCheck(){this.closed||this.orphanTimeoutMs<=0||this.clients.size>0||this._interactive===!0||this.armOrphanTimer(this.orphanTimeoutMs)}armOrphanTimer(e){this.orphanTimer&&clearTimeout(this.orphanTimer),this.orphanTimer=setTimeout(()=>{this.orphanTimer=void 0,this.checkOrphan()},e),typeof this.orphanTimer.unref=="function"&&this.orphanTimer.unref()}checkOrphan(){if(!this.closed&&!(this.clients.size>0||this._interactive===!0)){if(this.hasWorkInFlight){this.armOrphanTimer(this.orphanTimeoutMs);return}this.logger?.info(`session ${this.sessionId} orphan timeout fired after ${Math.round(this.orphanTimeoutMs/1e3)}s with no attached client and no prompt ever received \u2014 closing`),this.close({deleteRecord:!1,by:"reap-orphaned"}).catch(()=>{})}}cancelOrphanTimer(){this.orphanTimer&&(clearTimeout(this.orphanTimer),this.orphanTimer=void 0)}get currentPromptDepth(){if(this.currentEntry?.kind==="user")return this.currentEntry.originator.depth??0}get hasWorkInFlight(){return this.turnStartedAt!==void 0||this.hasPermissionFlag||this.promptQueue.length>0||this.armedBackgroundTasks.length>0}onIdle(e,t){let n={fn:e,once:!!t?.once,debounceMs:t?.debounceMs??0};return this.idleHandlers.push(n),()=>{let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1),n.timer&&(clearTimeout(n.timer),n.timer=void 0)}}onceIdle(e){return this.onIdle(e,{once:!0})}dispatchIdle(){if(this.closed)return;if(!this.isQuiescedSync()){for(let n of this.idleHandlers)n.timer&&(clearTimeout(n.timer),n.timer=void 0);return}let t=[...this.idleHandlers];for(let n of t){if(n.debounceMs===0){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}continue}n.timer&&(clearTimeout(n.timer),n.timer=void 0),n.timer=setTimeout(()=>{if(n.timer=void 0,!this.closed&&this.isQuiescedSync()){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}}},n.debounceMs),typeof n.timer.unref=="function"&&n.timer.unref()}}disposeIdleHandlers(){for(let e of this.idleHandlers)e.timer&&(clearTimeout(e.timer),e.timer=void 0);this.idleHandlers.length=0}noteRecordedToolCall(e,t){if(e!=="session/update")return;let n=t?.update;if(n===void 0)return;let r=typeof n.toolCallId=="string"?n.toolCallId:"";if(r.length===0)return;let o=typeof n.title=="string"&&n.title!==""?n.title:void 0;if(n.sessionUpdate==="tool_call"){this.turnRanTool=!0,n.status!=="completed"&&n.status!=="failed"&&this.openToolCalls.set(r,{startedAt:Date.now(),...o!==void 0?{title:o}:{}});return}if(n.sessionUpdate!=="tool_call_update")return;if(n.status==="completed"||n.status==="failed"){this.openToolCalls.delete(r),this.disarmOpenToolCall(r);return}let i=this.openToolCalls.get(r);i!==void 0&&o!==void 0&&(i.title=o)}armOpenToolCalls(){let e=!1;for(let[t,n]of this.openToolCalls){if(this.armedTasks.has(t))continue;let r=this.toolLabels.get(t),o=r?.fromDescription===!0?r.label:Fg(n.title??r?.label??"").slice(0,mo);this.armedTasks.set(t,{label:o===""?"running tool":o,repeating:!1,armedAt:n.startedAt,openToolCall:!0}),e=!0}e&&this.onArmedTasksChanged()}disarmOpenToolCall(e){this.armedTasks.get(e)?.openToolCall===!0&&(this.armedTasks.delete(e),this.onArmedTasksChanged())}closeOpenToolCalls(e){if(this.openToolCalls.size===0||this.closed)return;let t=[...this.openToolCalls.keys()];this.openToolCalls.clear();for(let n of t)this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"tool_call_update",toolCallId:n,status:"failed",_meta:{[le]:{synthetic:!0,closedBy:e}}}});this.logger?.info(`session ${this.sessionId} closed ${t.length} open tool call(s) on ${e}`)}maybeEmitToolEdges(e){if(!e||typeof e!="object")return;let t=e.update;if(!t||typeof t!="object")return;let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:"";if(r!=="tool_call"&&r!=="tool_call_update")return;let o=typeof n.toolCallId=="string"&&n.toolCallId.length>0?n.toolCallId:void 0;if(!o)return;let i=typeof n.kind=="string"?n.kind:void 0;this.toolCallKind.note(o,i);let a=this.toolCallKind.effective(o,i);if(a===Ha&&Array.isArray(n.locations))for(let u of n.locations){if(!u||typeof u!="object")continue;let l=u.path;if(typeof l!="string"||l.length===0||this.filesEditedSeen.has(l))continue;this.filesEditedSeen.add(l);let p=u.line,f={path:l,toolCallId:o};typeof p=="number"&&(f.line=p),this.notifyChain("file.edited",f),this.reportIsolationBreach(l,o)}if(r!=="tool_call_update")return;let d=typeof n.status=="string"?n.status:void 0;if(d!=="completed"&&d!=="failed"||this.toolCompletionSeen.has(o))return;this.toolCompletionSeen.set(o,d);let c={toolCallId:o,status:d};a&&(c.kind=a),n.content!==void 0&&(c.content=n.content),Array.isArray(n.locations)&&(c.locations=n.locations),this.notifyChain("tool.completed",c)}notifyChain(e,t){let n=`lifecycle:${e}`;for(let r of this.transformChain)r.intercepts.has(n)&&r.connection.notify("hydra-acp/transformer/session_event",{event:e,sessionId:this.sessionId,payload:t}).catch(()=>{})}rewriteForClient(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.sessionId=="string"&&t.sessionId!==this.sessionId)return{...t,sessionId:this.sessionId}}return e}recordAndBroadcast(e,t,n){let r=this.rewriteForClient(t),o=!In(e,r),i=o?Zg(e,r):r,a=Date.now(),d=o?this.lastSeq=Math.max(this.lastSeq+1,a):void 0,c=o?We(Be(i,a),d):i;if(o){this.noteRecordedToolCall(e,i);let u={method:e,params:i,recordedAt:a,seq:d};if(this.lastRecordedAt=u.recordedAt,this.appendCount+=1,this.historyStore){let l=this.historyStore;l.append(this.sessionId,u).catch(()=>{}),this.appendCount>=this.compactEvery&&(this.appendCount=0,l.compact(this.sessionId,this.historyMaxEntries).catch(()=>{}))}for(let l of this.broadcastHandlers)try{l(u)}catch{}this.scheduleIdleCheck(),this.dispatchIdle()}this.updatedAt=Date.now();for(let u of this.clients.values())n&&u.clientId===n||u.connection.notify(e,c).catch(()=>{})}async requestPermissionFromClients(e){return this.handlePermissionRequest(e)}async handlePermissionRequest(e){let t=[...this.clients.values()];if(t.length===0)throw fe(new Error("no clients attached to handle permission request"),x.PermissionDenied);let n=this.rewriteForClient(e),r=xd(n),o=Ge(),{toolCall:i,options:a}=n??{};return new Promise((d,c)=>{let u=!1,l=[],p=0,f,h=this.sessionId,w=y=>{u||(u=!0,this.clearAttentionFlag("daemon",`permission:${o}`),this.permissionCallbacks.delete(o),y())},m=y=>y?.code===x.MethodNotFound;function g(y){if(u)return;let k=y.connection.request("session/request_permission",n);l.push({client:y}),p++,k.then(v=>{p--,w(()=>{let S=sh({toolCallId:r,result:v,resolver:y});for(let b of l)b.client.clientId!==y.clientId&&b.client.connection.notify("session/update",{sessionId:h,update:S}).catch(()=>{});d(v)})}).catch(v=>{if(p--,m(v)||(f=v),p===0&&!u){let S=f??fe(new Error("no client handled permission request"),x.PermissionDenied);w(()=>c(S))}})}this.setAttentionFlag("daemon",`permission:${o}`,{kind:"permission",toolCall:i??null,options:a??null}),this.permissionCallbacks.set(o,g);for(let y of t)g(y)})}async enqueuePrompt(e,t){return new Promise((n,r)=>{let o={kind:"internal",messageId:Ge(),label:e,enqueuedAt:Date.now(),cancelled:!1,task:t,resolve:n,reject:r};this.promptQueue.push(o),this.drainQueue()})}async enqueueUserPrompt(e,t,n,r,o){let i=(t??{}).prompt??[],a={clientId:e.clientId};e.clientInfo?.name&&(a.name=e.clientInfo.name),e.clientInfo?.version&&(a.version=e.clientInfo.version),r?.fromSession&&(a.fromSession=r.fromSession),r?.fromSessionTitle&&(a.fromSessionTitle=r.fromSessionTitle),r?.fromLabel&&(a.fromLabel=r.fromLabel),r?.depth!==void 0&&(a.depth=r.depth);let d=this.parseQueuePosition(t);return new Promise((c,u)=>{let l={kind:"user",messageId:n,originator:a,clientId:e.clientId,prompt:i,enqueuedAt:Date.now(),cancelled:!1,resolve:c,reject:u};o?.steerOriginated===!0&&(l.wasSteer=!0);let p=this.insertEntryAt(l,d);this.persistRewrite(),this.broadcastQueueAdded(l,{position:p}),this.drainQueue()})}promptCarriesSentBy(e){if(!e||typeof e!="object")return!1;let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t[le];if(!n||typeof n!="object"||Array.isArray(n))return!1;let r=n.sentBy;return!!r&&typeof r=="object"}parseQueuePosition(e){if(!e||typeof e!="object")return"tail";let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return"tail";let n=t["hydra-acp"];if(!n||typeof n!="object"||Array.isArray(n))return"tail";let r=n.queuePosition;if(r==="head"||r==="tail")return r;if(r&&typeof r=="object"&&!Array.isArray(r)){let o=r.afterMessageId;if(typeof o=="string"&&o.length>0)return{afterMessageId:o}}return"tail"}insertEntryAt(e,t){let n=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;if(t==="head")return this.promptQueue.unshift(e),n;if(typeof t=="object"){let r=t.afterMessageId,o=this.promptQueue.findIndex(i=>i.messageId===r);if(o>=0)return this.promptQueue.splice(o+1,0,e),n+o+1}return this.promptQueue.push(e),n+this.promptQueue.length-1}persistRewrite(){let e=[];for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push(this.persistedFromEntry(n));let t=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Sn(t,e).catch(()=>{}))}persistedFromEntry(e){return{messageId:e.messageId,originator:{clientInfo:{...e.originator.name!==void 0?{name:e.originator.name}:{},...e.originator.version!==void 0?{version:e.originator.version}:{}}},prompt:e.prompt,enqueuedAt:e.enqueuedAt}}async drainQueue(){if(!this.promptInFlight){this.promptInFlight=!0,await new Promise(e=>setImmediate(e));try{for(;this.promptQueue.length>0&&!this.closing;){let e=this.promptQueue[0];if(e?.kind==="user"&&(await this.holdForUnsolicitedTurn(e),this.closing))break;let t=this.promptQueue.shift();if(!t)break;if(!t.cancelled){this.currentEntry=t,t.kind==="user"&&this.persistRewrite(),t.kind==="user"&&this.broadcastQueueRemoved(t.messageId,"started");try{let n=await this.runQueueEntry(t);t.resolve(n),await new Promise(r=>setImmediate(r))}catch(n){t.reject(n)}finally{this.currentEntry=void 0}}}}finally{this.promptInFlight=!1,this.supersededAutonomousTurn=void 0,this.dispatchIdle()}}}async runQueueEntry(e){if(e.kind==="internal")return this.closeUnsolicitedTurn("superseded",`internal:${e.label}`),e.task();this.broadcastPromptReceived(e);let t=St(e.prompt).replace(/\s+$/,""),n=!t.includes(`
101
- `)&&t.startsWith("/")?t.split(/\s+/)[0]??"":"",r=n.startsWith("/")?n.slice(1):"",o=r.length>0&&this.aliasableBareVerbs().has(r);if(n==="/model"||n==="/mode"||n==="/sessions"||n==="/help"||n==="/hydra"||o){let d;try{if(n==="/sessions")d=await this.handleSessionsCommand();else if(n==="/help")d=await this.handleHelpCommand();else if(n==="/mode")d=await this.handleModeCommand(t);else if(n==="/model")d=await this.handleModelCommand(t);else if(o){let c=t.slice(n.length).trim(),u=c?`/hydra ${r} ${c}`:`/hydra ${r}`;d=await this.handleSlashCommand(u,e.messageId)}else d=await this.handleSlashCommand(t,e.messageId)}catch(c){throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),c}return this.closed||this.broadcastTurnComplete(e.clientId,d,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),d}if(this.clearRollbackBreadcrumbHook)try{this.clearRollbackBreadcrumbHook()}catch{}let i=e.prompt;n&&this.agentAdvertisedCommands.length>0&&!this.agentKnowsSlashCommand(n)&&(i=yo(e.prompt,ih));let a;this.agentTurnInFlight=!0;try{i=this.applyWorkspacePromptRewrite(i),a=await this.dispatchPrompt(e,i)}catch(d){if(this.forceCancelling)return this.clearAmendIfMatches(e.messageId),{stopReason:"cancelled"};throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),d}finally{this.agentTurnInFlight=!1}return this.closed||this.broadcastTurnComplete(e.clientId,a,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),a}async dispatchPrompt(e,t){let n=()=>this.awaitPromptResponse(this.forwardRequest("session/prompt",{sessionId:this.sessionId,prompt:t},e.emitterName?new Set([e.emitterName]):new Set,e.chainStartIdx??0));try{return await n()}catch(r){if(this.loadExistingAgentSession&&Lg(r))return this.logger?.warn(`agent ${this.agentId} no longer knows upstream session ${this.upstreamSessionId} for ${this.sessionId}; reloading it onto a fresh process and retrying the prompt once`),await this.reloadUpstreamAfterAgentLoss(),await n();if(!Bg(r)||this.turnRanTool||(this.logger?.warn(`agent ${this.agentId} hit a transient auth failure for ${this.sessionId}; retrying the prompt once in ${Rd}ms`),await new Promise(o=>setTimeout(o,Rd)),e.cancelled))throw r;return await n()}}clearAmendIfMatches(e){this.amendInProgress?.cancelledMessageId===e&&(this.amendInProgress=void 0)}},jg=["session not found","the claude agent session has ended"];function Od(s){let e=s;if(e?.code!==x.InternalError)return;let t=e.data?.details;return`${typeof e.message=="string"?e.message:""} ${typeof t=="string"?t:""}`.toLowerCase()}function Lg(s){let e=Od(s);return e!==void 0&&jg.some(t=>e.includes(t))}var Ug=["failed to refresh oauth token"],Rd=6e4;function Bg(s){let e=Od(s);return e!==void 0&&Ug.some(t=>e.includes(t))}function fe(s,e){return s.code=e,s}var Wg=new Set(["session_info_update","_hydra_current_model_update","current_mode_update","available_commands_update","_hydra_available_modes_update","usage_update","config_option_update","_hydra_compaction"]);function qg(s,e,t){return t?.run_in_background===!0?!1:e?.toolName==="Monitor"||s==="Monitor"||typeof e?.toolResponse?.taskId=="string"}function zg(s){return typeof s!="string"?void 0:/Command running in background with ID: ([A-Za-z0-9_-]+)/.exec(s)?.[1]}function Jg(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.claudeCode;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n={};return t.toolName!==void 0&&(n.toolName=t.toolName),t.toolResponse&&typeof t.toolResponse=="object"&&(n.toolResponse=t.toolResponse),n}function In(s,e){if(s!=="session/update")return!1;let n=(e??{}).update?.sessionUpdate;return typeof n=="string"&&Wg.has(n)}function Vg(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function Gg(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.id!==e[t]?.id||s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function Kg(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.modelId!==e[t]?.modelId||s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function An(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.modelId=="string"&&n.modelId.trim()||typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o={modelId:r};typeof n.name=="string"&&n.name.length>0&&(o.name=n.name),typeof n.description=="string"&&n.description.length>0&&(o.description=n.description),e.push(o)}return e}function ks(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o={id:r};typeof n.name=="string"&&n.name.length>0&&(o.name=n.name),typeof n.description=="string"&&n.description.length>0&&(o.description=n.description),e.push(o)}return e}function ko(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o=typeof n.name=="string"&&n.name.trim()?n.name.trim():r,i={value:r,name:o};typeof n.description=="string"&&n.description.length>0&&(i.description=n.description),e.push(i)}return e}function Qg(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="_hydra_available_modes_update")return null;let n=t.availableModes;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.id!="string"||i.id.length===0)continue;let a={id:i.id};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function Yg(s,e){let n=(e??{}).update??{},r=n.sessionUpdate;if(r==="agent_message_chunk"){let o=n.content??{};typeof o.text=="string"&&(s.chunks.push(o.text),s.messageChars+=o.text.length);return}if(r==="agent_thought_chunk"){let o=n.content??{};typeof o.text=="string"&&(s.thinkingChars+=o.text.length);return}if(r==="tool_call"){s.toolCalls++;return}if(r==="usage_update"){typeof n.used=="number"&&(s.lastUsed=n.used),typeof n.size=="number"&&(s.lastSize=n.size);return}}function Xg(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="available_commands_update")return null;let n=t.availableCommands??t.commands;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.name!="string"||i.name.length===0)continue;let a={name:i.name};typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function Zg(s,e){if(s!=="session/update"||!e||typeof e!="object")return e;let t=e;return!t.update||typeof t.update!="object"||Array.isArray(t.update)||typeof t.update.messageId=="string"?e:{...e,update:{...t.update,messageId:Ge()}}}function eh(s,e){if(s.length<=e)return s;let t=s.length-e;for(let n=t;n>=0;n--)if(s[n]?.params?.update?.sessionUpdate==="prompt_received")return s.slice(n);return s.slice(t)}function th(s,e){for(let t=s.length-1;t>=0;t--)if(s[t]?.seq===e)return t;return-1}function nh(s,e){for(let t=s.length-1;t>=0;t--){let n=s[t];if(!n||n.method!=="session/update")continue;if(n.params?.update?.messageId===e)return t}return-1}function xd(s){if(!s||typeof s!="object")return;let e=s.toolCall;if(!e||typeof e!="object")return;let t=e.toolCallId;return typeof t=="string"?t:void 0}function sh(s){let e=rh(s.result),t={sessionUpdate:"permission_resolved"};return s.toolCallId!==void 0&&(t.toolCallId=s.toolCallId),e&&(t.outcome=e,e.kind==="selected"&&typeof e.optionId=="string"&&(t.chosenOptionId=e.optionId)),t.resolvedBy=oh(s.resolver),t}function rh(s){if(!s||typeof s!="object")return;let e=s.outcome;if(!e||typeof e!="object")return;let t=e.kind;if(typeof t!="string")return;let n={kind:t},r=e.optionId;typeof r=="string"&&(n.optionId=r);let o=e.reason;return typeof o=="string"&&(n.reason=o),n}function oh(s){let e={clientId:s.clientId};return s.clientInfo?.name&&(e.name=s.clientInfo.name),s.clientInfo?.version&&(e.version=s.clientInfo.version),e}function St(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var ih="\u200B";function Ed(s,e){return s.map(t=>{if(t&&typeof t=="object"&&typeof t.text=="string"){let n=t;return{...n,text:e(n.text)}}return t})}function yo(s,e){let t=s.findIndex(o=>o&&typeof o=="object"&&typeof o.text=="string");if(t<0)return s;let n=s[t],r=[...s];return r[t]={...n,text:`${e}${n.text}`},r}function wo(s){return s==="session/prompt"?{stopReason:"stopped"}:{}}function ah(s){return s==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function Td(s){let e=s.name&&s.name!==s.id?`${s.id} (${s.name}) \u2014 \u25B6 ${s.currentValue}`:`${s.id} \u2014 \u25B6 ${s.currentValue}`;if(s.options.length===0)return e;let t=Math.max(...s.options.map(r=>r.value.length)),n=s.options.map(r=>{let o=r.value===s.currentValue?"\u25B6":"\xB7",i=r.name&&r.name!==r.value,a=i?r.value.padEnd(t):r.value;return i?` ${o} ${a} ${r.name}`:` ${o} ${a}`});return`${e}
100
+ `)}async seedFromImport(){await this.enqueuePrompt("seed:import",async()=>{let e=await this.buildSwitchTranscript(this.agentId,{intro:"You are continuing a conversation that was imported from another hydra. Below is the transcript so far.",followup:"Each line is prefixed with its speaker. Treat this as context for the next user message; do not re-respond to earlier turns."});e&&await this.runInternalPrompt(e).catch(()=>{})})}async seedFromFork(e){await this.enqueuePrompt("seed:fork",async()=>{let t=this.title??"(untitled)",n=[];if(this.historyStore)try{n=await this.historyStore.load(this.sessionId)}catch(o){this.logger?.warn(`seedFromFork: historyStore.load failed: ${o.message}`)}let r=fo({synopsis:e,title:t,tail:n,tailK:Rg,tailFloor:xg,watermark:this._summarizedThroughEntry,recallArmed:(this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("seedFromFork: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:r}]});let o=this.internalPromptCapture;this.logger?.info(`seedFromFork: seed processed sessionId=${this.sessionId} seedChars=${r.length} toolCalls=${o.toolCalls} thinkingChars=${o.thinkingChars} messageChars=${o.messageChars}`)}finally{this.internalPromptCapture=void 0}})}broadcastAgentSwitch(e,t){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,agentId:t,pendingAgentSwap:null}}}}),this.broadcastConfigOptions()}broadcastPendingAgentSwap(e){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,pendingAgentSwap:e}}}})}hasStreamBuffer(){return this.streamBuffer!==void 0}get streamPath(){return this.streamFilePath}openStream(e){if(this.streamBuffer!==void 0)throw new Error(`stream buffer already open for session ${this.sessionId}`);let n=(e.mode??"memory")==="file"&&e.filePathFor!==void 0?e.filePathFor(this.sessionId):void 0,r={};e.capacityBytes!==void 0&&(r.capacityBytes=e.capacityBytes),n!==void 0&&(r.filePath=n),e.fileCapBytes!==void 0&&(r.fileCapBytes=e.fileCapBytes),r.onFileCapReached=()=>{this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_stream_truncated",...n!==void 0?{filePath:n}:{},fileCapBytes:e.fileCapBytes}})};let o=new gs(r);this.streamBuffer=o,this.streamFilePath=n;let i={capacityBytes:o.capacity};return n!==void 0&&(i.filePath=n),e.fileCapBytes!==void 0&&(i.fileCapBytes=e.fileCapBytes),i}streamWrite(e,t){let n=this.requireStreamBuffer();if(e.length>0){let r=Buffer.from(e,"base64");n.append(r)}return t===!0&&n.close(),{writeCursor:n.writeCursorPos}}async streamRead(e,t,n){let r=this.requireStreamBuffer(),o=Math.max(0,Math.min(t??Wt,Wt)),i=r.read(e,o);if(i.bytes.length===0&&i.eof!==!0&&n!==void 0&&n>0){let d=await r.waitForData(i.nextCursor,n);(d==="data"||d==="eof")&&(i=r.read(i.nextCursor,o))}let a={bytes:i.bytes.toString("base64"),nextCursor:i.nextCursor};return i.gap!==void 0&&(a.gap=i.gap),i.eof===!0&&(a.eof=!0),a}streamTail(e){let n=this.requireStreamBuffer().tail(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}streamHead(e){let n=this.requireStreamBuffer().head(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}async streamWaitFor(e,t){return this.requireStreamBuffer().waitForData(e,t)}streamGrep(e){return this.requireStreamBuffer().grep(e)}streamInfo(){let e=this.requireStreamBuffer();return{writeCursor:e.writeCursorPos,oldestAvailable:e.oldestAvailable,capacity:e.capacity,closed:e.isClosed}}requireStreamBuffer(){if(this.streamBuffer===void 0){let e=new Error(`session ${this.sessionId} has no stream buffer; POST /v1/sessions/:id/stdin/open first`);throw e.code=x.StreamNotEnabled,e}return this.streamBuffer}markClosed(e){if(this.closed)return;this.closeUnsolicitedTurn("closed"),e={deleteRecord:e.deleteRecord||this.deleteRecordIntent},this.closing=!0,this.closed=!0,this.cancelIdleTimer(),this.cancelOrphanTimer(),this.extensionCommandsUnsub&&(this.extensionCommandsUnsub(),this.extensionCommandsUnsub=void 0);for(let o of[...this.inFlightExtensionDispatches.keys()])this.cancelExtensionDispatch(o,"abandoned");this.currentEntry?.kind==="user"&&!this.recentlyTerminal.has(this.currentEntry.messageId)&&this.broadcastTurnComplete(this.currentEntry.clientId,{stopReason:"interrupted"},this.currentEntry.messageId,this.originatorNeedsTurnComplete(this.currentEntry)),this.currentEntry=void 0;let n=this.promptQueue;this.promptQueue=[];for(let o of n){o.cancelled=!0,o.kind==="user"&&this.broadcastQueueRemoved(o.messageId,"abandoned");let i=this.pendingTurnNotifiers.get(o.messageId);i&&(this.pendingTurnNotifiers.delete(o.messageId),ro(i,{sessionId:this.sessionId,messageId:i.originalMessageId,stopReason:"cancelled",deliveredAt:Date.now(),...o.messageId!==i.originalMessageId?{amendedTo:o.messageId}:{}}));try{o.resolve({stopReason:"cancelled"})}catch{}}this.notifyChain("session.closed",{}),this.toolCompletionSeen.clear(),this.toolCallKind.clear(),this.filesEditedSeen.clear(),this.openToolCalls.clear();let r=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Id(r).catch(()=>{}));for(let o of this.clients.values())o.connection.notify("hydra-acp/session/closed",{sessionId:this.sessionId}).catch(()=>{});if(this.clients.clear(),this.streamBuffer!==void 0){let o=this.streamBuffer,i=this.streamFilePath;this.streamBuffer=void 0,this.streamFilePath=void 0,o.close(),i!==void 0&&o.drainFileWrites().then(()=>$d.unlink(i).catch(()=>{}))}for(let o of this.closeHandlers)o(e)}get lastActivityAt(){return this.lastRecordedAt}setAttentionFlag(e,t,n){this._setAttentionFlag(e,t,n,!0)}_setAttentionFlag(e,t,n,r){let o=`${e}::${t}`,i=this.attentionFlags.get(o);if(i){if(JSON.stringify(i.payload)===JSON.stringify(n))return;this.attentionFlags.set(o,{...i,payload:n,raisedAt:i.raisedAt})}else this.attentionFlags.set(o,{source:e,reason:t,raisedAt:Date.now(),payload:n});r&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}clearAttentionFlag(e,t){this._clearAttentionFlag(e,t,!0)}_clearAttentionFlag(e,t,n){let r=`${e}::${t}`;this.attentionFlags.delete(r)&&n&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}listAttentionFlags(){return Array.from(this.attentionFlags.values()).sort((e,t)=>e.raisedAt-t.raisedAt)}listAttentionFlagsBySource(e){return this.listAttentionFlags().filter(t=>t.source===e)}onAttentionFlagsChange(e){this.attentionFlagsChangeHandlers.push(e)}fireAttentionFlagsChange(){let e=this.listAttentionFlags();for(let t of this.attentionFlagsChangeHandlers)try{t(e)}catch{}}broadcastAttentionUpdated(){for(let e of this.clients.values())e.connection.notify("hydra-acp/session/attention_updated",{sessionId:this.sessionId,flags:this.listAttentionFlags()}).catch(()=>{})}scheduleIdleCheck(){if(this.closed||this.idleTimeoutMs<=0)return;let e=this.lastActivityAt+this.idleTimeoutMs;this.armIdleTimer(Math.max(0,e-Date.now()))}armIdleTimer(e){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{this.idleTimer=void 0,this.checkIdle()},e),typeof this.idleTimer.unref=="function"&&this.idleTimer.unref()}checkIdle(){if(this.closed||this.idleTimeoutMs<=0)return;if(this.hasWorkInFlight){this.armIdleTimer(this.idleTimeoutMs);return}let e=Date.now()-this.lastActivityAt;if(e<this.idleTimeoutMs){this.armIdleTimer(this.idleTimeoutMs-e);return}let t=this.firstPromptSeeded?{deleteRecord:!1}:{deleteRecord:!0},n=Math.round(e/1e3);this.logger?.info(`session ${this.sessionId} idle timeout fired after ${n}s (window=${Math.round(this.idleTimeoutMs/1e3)}s) \u2014 closing`),this.close(t).catch(()=>{})}cancelIdleTimer(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=void 0),this.disposeIdleHandlers()}scheduleOrphanCheck(){this.closed||this.orphanTimeoutMs<=0||this.clients.size>0||this._interactive===!0||this.armOrphanTimer(this.orphanTimeoutMs)}armOrphanTimer(e){this.orphanTimer&&clearTimeout(this.orphanTimer),this.orphanTimer=setTimeout(()=>{this.orphanTimer=void 0,this.checkOrphan()},e),typeof this.orphanTimer.unref=="function"&&this.orphanTimer.unref()}checkOrphan(){if(!this.closed&&!(this.clients.size>0||this._interactive===!0)){if(this.hasWorkInFlight){this.armOrphanTimer(this.orphanTimeoutMs);return}this.logger?.info(`session ${this.sessionId} orphan timeout fired after ${Math.round(this.orphanTimeoutMs/1e3)}s with no attached client and no prompt ever received \u2014 closing`),this.close({deleteRecord:!1,by:"reap-orphaned"}).catch(()=>{})}}cancelOrphanTimer(){this.orphanTimer&&(clearTimeout(this.orphanTimer),this.orphanTimer=void 0)}get currentPromptDepth(){if(this.currentEntry?.kind==="user")return this.currentEntry.originator.depth??0}get hasWorkInFlight(){return this.turnStartedAt!==void 0||this.hasPermissionFlag||this.promptQueue.length>0||this.armedBackgroundTasks.length>0}onIdle(e,t){let n={fn:e,once:!!t?.once,debounceMs:t?.debounceMs??0};return this.idleHandlers.push(n),()=>{let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1),n.timer&&(clearTimeout(n.timer),n.timer=void 0)}}onceIdle(e){return this.onIdle(e,{once:!0})}dispatchIdle(){if(this.closed)return;if(!this.isQuiescedSync()){for(let n of this.idleHandlers)n.timer&&(clearTimeout(n.timer),n.timer=void 0);return}let t=[...this.idleHandlers];for(let n of t){if(n.debounceMs===0){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}continue}n.timer&&(clearTimeout(n.timer),n.timer=void 0),n.timer=setTimeout(()=>{if(n.timer=void 0,!this.closed&&this.isQuiescedSync()){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}}},n.debounceMs),typeof n.timer.unref=="function"&&n.timer.unref()}}disposeIdleHandlers(){for(let e of this.idleHandlers)e.timer&&(clearTimeout(e.timer),e.timer=void 0);this.idleHandlers.length=0}noteRecordedToolCall(e,t){if(e!=="session/update")return;let n=t?.update;if(n===void 0)return;let r=typeof n.toolCallId=="string"?n.toolCallId:"";if(r.length===0)return;let o=typeof n.title=="string"&&n.title!==""?n.title:void 0;if(n.sessionUpdate==="tool_call"){this.turnRanTool=!0,n.status!=="completed"&&n.status!=="failed"&&this.openToolCalls.set(r,{startedAt:Date.now(),...o!==void 0?{title:o}:{}});return}if(n.sessionUpdate!=="tool_call_update")return;if(n.status==="completed"||n.status==="failed"){this.openToolCalls.delete(r),this.disarmOpenToolCall(r);return}let i=this.openToolCalls.get(r);i!==void 0&&o!==void 0&&(i.title=o)}armOpenToolCalls(){let e=!1;for(let[t,n]of this.openToolCalls){if(this.armedTasks.has(t))continue;let r=this.toolLabels.get(t),o=r?.fromDescription===!0?r.label:Fg(n.title??r?.label??"").slice(0,mo);this.armedTasks.set(t,{label:o===""?"running tool":o,repeating:!1,armedAt:n.startedAt,openToolCall:!0}),e=!0}e&&this.onArmedTasksChanged()}disarmOpenToolCall(e){this.armedTasks.get(e)?.openToolCall===!0&&(this.armedTasks.delete(e),this.onArmedTasksChanged())}closeOpenToolCalls(e){if(this.openToolCalls.size===0||this.closed)return;let t=[...this.openToolCalls.keys()];this.openToolCalls.clear();for(let n of t)this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"tool_call_update",toolCallId:n,status:"failed",_meta:{[le]:{synthetic:!0,closedBy:e}}}});this.logger?.info(`session ${this.sessionId} closed ${t.length} open tool call(s) on ${e}`)}maybeEmitToolEdges(e){if(!e||typeof e!="object")return;let t=e.update;if(!t||typeof t!="object")return;let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:"";if(r!=="tool_call"&&r!=="tool_call_update")return;let o=typeof n.toolCallId=="string"&&n.toolCallId.length>0?n.toolCallId:void 0;if(!o)return;let i=typeof n.kind=="string"?n.kind:void 0;this.toolCallKind.note(o,i);let a=this.toolCallKind.effective(o,i);if(a===ja&&Array.isArray(n.locations))for(let u of n.locations){if(!u||typeof u!="object")continue;let l=u.path;if(typeof l!="string"||l.length===0||this.filesEditedSeen.has(l))continue;this.filesEditedSeen.add(l);let p=u.line,f={path:l,toolCallId:o};typeof p=="number"&&(f.line=p),this.notifyChain("file.edited",f),this.reportIsolationBreach(l,o)}if(r!=="tool_call_update")return;let d=typeof n.status=="string"?n.status:void 0;if(d!=="completed"&&d!=="failed"||this.toolCompletionSeen.has(o))return;this.toolCompletionSeen.set(o,d);let c={toolCallId:o,status:d};a&&(c.kind=a),n.content!==void 0&&(c.content=n.content),Array.isArray(n.locations)&&(c.locations=n.locations),this.notifyChain("tool.completed",c)}notifyChain(e,t){let n=`lifecycle:${e}`;for(let r of this.transformChain)r.intercepts.has(n)&&r.connection.notify("hydra-acp/transformer/session_event",{event:e,sessionId:this.sessionId,payload:t}).catch(()=>{})}rewriteForClient(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.sessionId=="string"&&t.sessionId!==this.sessionId)return{...t,sessionId:this.sessionId}}return e}recordAndBroadcast(e,t,n){let r=this.rewriteForClient(t),o=!In(e,r),i=o?eh(e,r):r,a=Date.now(),d=o?this.lastSeq=Math.max(this.lastSeq+1,a):void 0,c=o?We(Be(i,a),d):i;if(o){this.noteRecordedToolCall(e,i);let u={method:e,params:i,recordedAt:a,seq:d};if(this.lastRecordedAt=u.recordedAt,this.appendCount+=1,this.historyStore){let l=this.historyStore;l.append(this.sessionId,u).catch(()=>{}),this.appendCount>=this.compactEvery&&(this.appendCount=0,l.compact(this.sessionId,this.historyMaxEntries).catch(()=>{}))}for(let l of this.broadcastHandlers)try{l(u)}catch{}this.scheduleIdleCheck(),this.dispatchIdle()}this.updatedAt=Date.now();for(let u of this.clients.values())n&&u.clientId===n||u.connection.notify(e,c).catch(()=>{})}async requestPermissionFromClients(e){return this.handlePermissionRequest(e)}async handlePermissionRequest(e){let t=[...this.clients.values()];if(t.length===0)throw fe(new Error("no clients attached to handle permission request"),x.PermissionDenied);let n=this.rewriteForClient(e),r=xd(n),o=Ge(),{toolCall:i,options:a}=n??{};return new Promise((d,c)=>{let u=!1,l=[],p=0,f,h=this.sessionId,w=y=>{u||(u=!0,this.clearAttentionFlag("daemon",`permission:${o}`),this.permissionCallbacks.delete(o),y())},m=y=>y?.code===x.MethodNotFound;function g(y){if(u)return;let k=y.connection.request("session/request_permission",n);l.push({client:y}),p++,k.then(v=>{p--,w(()=>{let S=rh({toolCallId:r,result:v,resolver:y});for(let b of l)b.client.clientId!==y.clientId&&b.client.connection.notify("session/update",{sessionId:h,update:S}).catch(()=>{});d(v)})}).catch(v=>{if(p--,m(v)||(f=v),p===0&&!u){let S=f??fe(new Error("no client handled permission request"),x.PermissionDenied);w(()=>c(S))}})}this.setAttentionFlag("daemon",`permission:${o}`,{kind:"permission",toolCall:i??null,options:a??null}),this.permissionCallbacks.set(o,g);for(let y of t)g(y)})}async enqueuePrompt(e,t){return new Promise((n,r)=>{let o={kind:"internal",messageId:Ge(),label:e,enqueuedAt:Date.now(),cancelled:!1,task:t,resolve:n,reject:r};this.promptQueue.push(o),this.drainQueue()})}async enqueueUserPrompt(e,t,n,r,o){let i=(t??{}).prompt??[],a={clientId:e.clientId};e.clientInfo?.name&&(a.name=e.clientInfo.name),e.clientInfo?.version&&(a.version=e.clientInfo.version),r?.fromSession&&(a.fromSession=r.fromSession),r?.fromSessionTitle&&(a.fromSessionTitle=r.fromSessionTitle),r?.fromLabel&&(a.fromLabel=r.fromLabel),r?.depth!==void 0&&(a.depth=r.depth);let d=this.parseQueuePosition(t);return new Promise((c,u)=>{let l={kind:"user",messageId:n,originator:a,clientId:e.clientId,prompt:i,enqueuedAt:Date.now(),cancelled:!1,resolve:c,reject:u};o?.steerOriginated===!0&&(l.wasSteer=!0);let p=this.insertEntryAt(l,d);this.persistRewrite(),this.broadcastQueueAdded(l,{position:p}),this.drainQueue()})}promptCarriesSentBy(e){if(!e||typeof e!="object")return!1;let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t[le];if(!n||typeof n!="object"||Array.isArray(n))return!1;let r=n.sentBy;return!!r&&typeof r=="object"}parseQueuePosition(e){if(!e||typeof e!="object")return"tail";let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return"tail";let n=t["hydra-acp"];if(!n||typeof n!="object"||Array.isArray(n))return"tail";let r=n.queuePosition;if(r==="head"||r==="tail")return r;if(r&&typeof r=="object"&&!Array.isArray(r)){let o=r.afterMessageId;if(typeof o=="string"&&o.length>0)return{afterMessageId:o}}return"tail"}insertEntryAt(e,t){let n=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;if(t==="head")return this.promptQueue.unshift(e),n;if(typeof t=="object"){let r=t.afterMessageId,o=this.promptQueue.findIndex(i=>i.messageId===r);if(o>=0)return this.promptQueue.splice(o+1,0,e),n+o+1}return this.promptQueue.push(e),n+this.promptQueue.length-1}persistRewrite(){let e=[];for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push(this.persistedFromEntry(n));let t=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Sn(t,e).catch(()=>{}))}persistedFromEntry(e){return{messageId:e.messageId,originator:{clientInfo:{...e.originator.name!==void 0?{name:e.originator.name}:{},...e.originator.version!==void 0?{version:e.originator.version}:{}}},prompt:e.prompt,enqueuedAt:e.enqueuedAt}}async drainQueue(){if(!this.promptInFlight){this.promptInFlight=!0,await new Promise(e=>setImmediate(e));try{for(;this.promptQueue.length>0&&!this.closing;){let e=this.promptQueue[0];if(e?.kind==="user"&&(await this.holdForUnsolicitedTurn(e),this.closing))break;let t=this.promptQueue.shift();if(!t)break;if(!t.cancelled){this.currentEntry=t,t.kind==="user"&&this.persistRewrite(),t.kind==="user"&&this.broadcastQueueRemoved(t.messageId,"started");try{let n=await this.runQueueEntry(t);t.resolve(n),await new Promise(r=>setImmediate(r))}catch(n){t.reject(n)}finally{this.currentEntry=void 0}}}}finally{this.promptInFlight=!1,this.supersededAutonomousTurn=void 0,this.dispatchIdle()}}}async runQueueEntry(e){if(e.kind==="internal")return this.closeUnsolicitedTurn("superseded",`internal:${e.label}`),e.task();this.broadcastPromptReceived(e);let t=St(e.prompt).replace(/\s+$/,""),n=!t.includes(`
101
+ `)&&t.startsWith("/")?t.split(/\s+/)[0]??"":"",r=n.startsWith("/")?n.slice(1):"",o=r.length>0&&this.aliasableBareVerbs().has(r);if(n==="/model"||n==="/mode"||n==="/sessions"||n==="/help"||n==="/hydra"||o){let d;try{if(n==="/sessions")d=await this.handleSessionsCommand();else if(n==="/help")d=await this.handleHelpCommand();else if(n==="/mode")d=await this.handleModeCommand(t);else if(n==="/model")d=await this.handleModelCommand(t);else if(o){let c=t.slice(n.length).trim(),u=c?`/hydra ${r} ${c}`:`/hydra ${r}`;d=await this.handleSlashCommand(u,e.messageId)}else d=await this.handleSlashCommand(t,e.messageId)}catch(c){throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),c}return this.closed||this.broadcastTurnComplete(e.clientId,d,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),d}if(this.clearRollbackBreadcrumbHook)try{this.clearRollbackBreadcrumbHook()}catch{}let i=e.prompt;n&&this.agentAdvertisedCommands.length>0&&!this.agentKnowsSlashCommand(n)&&(i=yo(e.prompt,ah));let a;this.agentTurnInFlight=!0;try{i=this.applyWorkspacePromptRewrite(i),a=await this.dispatchPrompt(e,i)}catch(d){if(this.forceCancelling)return this.clearAmendIfMatches(e.messageId),{stopReason:"cancelled"};throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),d}finally{this.agentTurnInFlight=!1}return this.closed||this.broadcastTurnComplete(e.clientId,a,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),a}async dispatchPrompt(e,t){let n=()=>this.awaitPromptResponse(this.forwardRequest("session/prompt",{sessionId:this.sessionId,prompt:t},e.emitterName?new Set([e.emitterName]):new Set,e.chainStartIdx??0));try{return await n()}catch(r){if(this.loadExistingAgentSession&&Lg(r))return this.logger?.warn(`agent ${this.agentId} no longer knows upstream session ${this.upstreamSessionId} for ${this.sessionId}; reloading it onto a fresh process and retrying the prompt once`),await this.reloadUpstreamAfterAgentLoss(),await n();if(!Bg(r)||this.turnRanTool||(this.logger?.warn(`agent ${this.agentId} hit a transient auth failure for ${this.sessionId}; retrying the prompt once in ${Rd}ms`),await new Promise(o=>setTimeout(o,Rd)),e.cancelled))throw r;return await n()}}clearAmendIfMatches(e){this.amendInProgress?.cancelledMessageId===e&&(this.amendInProgress=void 0)}},Hg=["session not found","the claude agent session has ended"];function Od(s){let e=s;if(e?.code!==x.InternalError)return;let t=e.data?.details;return`${typeof e.message=="string"?e.message:""} ${typeof t=="string"?t:""}`.toLowerCase()}function Lg(s){let e=Od(s);return e!==void 0&&Hg.some(t=>e.includes(t))}var Ug=["failed to refresh oauth token"],Rd=6e4;function Bg(s){let e=Od(s);return e!==void 0&&Ug.some(t=>e.includes(t))}function fe(s,e){return s.code=e,s}var Wg=new Set(["session_info_update","_hydra_current_model_update","current_mode_update","available_commands_update","_hydra_available_modes_update","usage_update","config_option_update","_hydra_compaction"]);function qg(s,e,t){return t?.run_in_background===!0||t?.background===!0?!1:e?.toolName==="Monitor"||s==="Monitor"||typeof e?.toolResponse?.taskId=="string"}function zg(s){return typeof s!="string"?void 0:/Command running in background with ID: ([A-Za-z0-9_-]+)/.exec(s)?.[1]}function Jg(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.metadata;if(!e||typeof e!="object")return;let{status:t,shellID:n}=e;return t==="running"&&typeof n=="string"&&n!==""?n:void 0}function Vg(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.claudeCode;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n={};return t.toolName!==void 0&&(n.toolName=t.toolName),t.toolResponse&&typeof t.toolResponse=="object"&&(n.toolResponse=t.toolResponse),n}function In(s,e){if(s!=="session/update")return!1;let n=(e??{}).update?.sessionUpdate;return typeof n=="string"&&Wg.has(n)}function Gg(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function Kg(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.id!==e[t]?.id||s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function Qg(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.modelId!==e[t]?.modelId||s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function An(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.modelId=="string"&&n.modelId.trim()||typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o={modelId:r};typeof n.name=="string"&&n.name.length>0&&(o.name=n.name),typeof n.description=="string"&&n.description.length>0&&(o.description=n.description),e.push(o)}return e}function ks(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o={id:r};typeof n.name=="string"&&n.name.length>0&&(o.name=n.name),typeof n.description=="string"&&n.description.length>0&&(o.description=n.description),e.push(o)}return e}function ko(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o=typeof n.name=="string"&&n.name.trim()?n.name.trim():r,i={value:r,name:o};typeof n.description=="string"&&n.description.length>0&&(i.description=n.description),e.push(i)}return e}function Yg(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="_hydra_available_modes_update")return null;let n=t.availableModes;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.id!="string"||i.id.length===0)continue;let a={id:i.id};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function Xg(s,e){let n=(e??{}).update??{},r=n.sessionUpdate;if(r==="agent_message_chunk"){let o=n.content??{};typeof o.text=="string"&&(s.chunks.push(o.text),s.messageChars+=o.text.length);return}if(r==="agent_thought_chunk"){let o=n.content??{};typeof o.text=="string"&&(s.thinkingChars+=o.text.length);return}if(r==="tool_call"){s.toolCalls++;return}if(r==="usage_update"){typeof n.used=="number"&&(s.lastUsed=n.used),typeof n.size=="number"&&(s.lastSize=n.size);return}}function Zg(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="available_commands_update")return null;let n=t.availableCommands??t.commands;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.name!="string"||i.name.length===0)continue;let a={name:i.name};typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function eh(s,e){if(s!=="session/update"||!e||typeof e!="object")return e;let t=e;return!t.update||typeof t.update!="object"||Array.isArray(t.update)||typeof t.update.messageId=="string"?e:{...e,update:{...t.update,messageId:Ge()}}}function th(s,e){if(s.length<=e)return s;let t=s.length-e;for(let n=t;n>=0;n--)if(s[n]?.params?.update?.sessionUpdate==="prompt_received")return s.slice(n);return s.slice(t)}function nh(s,e){for(let t=s.length-1;t>=0;t--)if(s[t]?.seq===e)return t;return-1}function sh(s,e){for(let t=s.length-1;t>=0;t--){let n=s[t];if(!n||n.method!=="session/update")continue;if(n.params?.update?.messageId===e)return t}return-1}function xd(s){if(!s||typeof s!="object")return;let e=s.toolCall;if(!e||typeof e!="object")return;let t=e.toolCallId;return typeof t=="string"?t:void 0}function rh(s){let e=oh(s.result),t={sessionUpdate:"permission_resolved"};return s.toolCallId!==void 0&&(t.toolCallId=s.toolCallId),e&&(t.outcome=e,e.kind==="selected"&&typeof e.optionId=="string"&&(t.chosenOptionId=e.optionId)),t.resolvedBy=ih(s.resolver),t}function oh(s){if(!s||typeof s!="object")return;let e=s.outcome;if(!e||typeof e!="object")return;let t=e.kind;if(typeof t!="string")return;let n={kind:t},r=e.optionId;typeof r=="string"&&(n.optionId=r);let o=e.reason;return typeof o=="string"&&(n.reason=o),n}function ih(s){let e={clientId:s.clientId};return s.clientInfo?.name&&(e.name=s.clientInfo.name),s.clientInfo?.version&&(e.version=s.clientInfo.version),e}function St(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var ah="\u200B";function Ed(s,e){return s.map(t=>{if(t&&typeof t=="object"&&typeof t.text=="string"){let n=t;return{...n,text:e(n.text)}}return t})}function yo(s,e){let t=s.findIndex(o=>o&&typeof o=="object"&&typeof o.text=="string");if(t<0)return s;let n=s[t],r=[...s];return r[t]={...n,text:`${e}${n.text}`},r}function wo(s){return s==="session/prompt"?{stopReason:"stopped"}:{}}function dh(s){return s==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function Td(s){let e=s.name&&s.name!==s.id?`${s.id} (${s.name}) \u2014 \u25B6 ${s.currentValue}`:`${s.id} \u2014 \u25B6 ${s.currentValue}`;if(s.options.length===0)return e;let t=Math.max(...s.options.map(r=>r.value.length)),n=s.options.map(r=>{let o=r.value===s.currentValue?"\u25B6":"\xB7",i=r.name&&r.name!==r.value,a=i?r.value.padEnd(t):r.value;return i?` ${o} ${a} ${r.name}`:` ${o} ${a}`});return`${e}
102
102
  ${n.join(`
103
- `)}`}function vo(s,e){for(let t of s.split(/\r?\n/)){let n=t.trim();if(n)return n.length>e?`${n.slice(0,e)}\u2026`:n}}K();He();import*as _e from"fs/promises";import*as nS from"path";import{customAlphabet as uh}from"nanoid";import{z as P}from"zod";import{z as Kt}from"zod";var dh=Kt.object({source:Kt.string(),reason:Kt.string(),raisedAt:Kt.number(),payload:Kt.unknown()}),Fd=Kt.array(dh);import{z as Y}from"zod";var Nd=Y.object({status:Y.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:Y.number(),runId:Y.string().optional(),iter:Y.number().int().nonnegative().optional(),attempts:Y.number().int().nonnegative().optional(),lastError:Y.string().optional(),worker:Y.object({upstreamSessionId:Y.string(),pid:Y.number().int().nonnegative()}).optional()}),Cn=Y.object({goal:Y.string().optional(),outcome:Y.string().optional(),files_touched:Y.array(Y.string()).optional(),tools_used:Y.array(Y.string()).optional(),rejected_approaches:Y.array(Y.string()).optional(),open_threads:Y.array(Y.string()).optional(),decisions:Y.array(Y.string()).optional(),file_edit_intentions:Y.array(Y.string()).optional(),unresolved_errors:Y.array(Y.string()).optional(),tool_state:Y.array(Y.string()).optional()}),Dd=200,bo=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
103
+ `)}`}function vo(s,e){for(let t of s.split(/\r?\n/)){let n=t.trim();if(n)return n.length>e?`${n.slice(0,e)}\u2026`:n}}K();je();import*as _e from"fs/promises";import*as sS from"path";import{customAlphabet as lh}from"nanoid";import{z as P}from"zod";import{z as Kt}from"zod";var ch=Kt.object({source:Kt.string(),reason:Kt.string(),raisedAt:Kt.number(),payload:Kt.unknown()}),Fd=Kt.array(ch);import{z as Y}from"zod";var Nd=Y.object({status:Y.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:Y.number(),runId:Y.string().optional(),iter:Y.number().int().nonnegative().optional(),attempts:Y.number().int().nonnegative().optional(),lastError:Y.string().optional(),worker:Y.object({upstreamSessionId:Y.string(),pid:Y.number().int().nonnegative()}).optional()}),Cn=Y.object({goal:Y.string().optional(),outcome:Y.string().optional(),files_touched:Y.array(Y.string()).optional(),tools_used:Y.array(Y.string()).optional(),rejected_approaches:Y.array(Y.string()).optional(),open_threads:Y.array(Y.string()).optional(),decisions:Y.array(Y.string()).optional(),file_edit_intentions:Y.array(Y.string()).optional(),unresolved_errors:Y.array(Y.string()).optional(),tool_state:Y.array(Y.string()).optional()}),Dd=200,bo=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
104
104
  {
105
105
  "title": "short summary, max 80 chars",
106
106
  "synopsis": {
@@ -110,7 +110,7 @@ ${n.join(`
110
110
  "open_threads": ["work started but not finished"]
111
111
  }
112
112
  }
113
- Use empty arrays/strings where a field doesn't apply.`;function Hd(s){let e=s.trim();if(e.length===0)return;let t=Qt(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=Qt(e.slice(o,i+1)))}if(t===void 0){let o=Ld(e);o!==void 0&&(t=Qt(o))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let o=n.title.trim();o.length>0&&(r.title=o.slice(0,Dd))}if(n.synopsis!==void 0&&n.synopsis!==null){let o=Cn.safeParse(n.synopsis);o.success&&ch(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var So=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
113
+ Use empty arrays/strings where a field doesn't apply.`;function jd(s){let e=s.trim();if(e.length===0)return;let t=Qt(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=Qt(e.slice(o,i+1)))}if(t===void 0){let o=Ld(e);o!==void 0&&(t=Qt(o))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let o=n.title.trim();o.length>0&&(r.title=o.slice(0,Dd))}if(n.synopsis!==void 0&&n.synopsis!==null){let o=Cn.safeParse(n.synopsis);o.success&&uh(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var So=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
114
114
  {
115
115
  "title": "short summary, max 80 chars",
116
116
  "goal": "the user's original ask",
@@ -122,41 +122,41 @@ Use empty arrays/strings where a field doesn't apply.`;function Hd(s){let e=s.tr
122
122
  "unresolved_errors": ["errors left open at session end"],
123
123
  "tool_state": ["runtime state relevant for recall"]
124
124
  }
125
- Use empty arrays/strings where a field doesn't apply.`;function jd(s){let e=s.trim();if(e.length===0)return;let t=Qt(e);if(t===void 0){let c=e.indexOf("{"),u=e.lastIndexOf("}");c>=0&&u>c&&(t=Qt(e.slice(c,u+1)))}if(t===void 0){let c=Ld(e);c!==void 0&&(t=Qt(c))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let c=n.title.trim();c.length>0&&(r.title=c.slice(0,Dd))}let o={},i=!1,a=["goal","outcome"];for(let c of a)if(typeof n[c]=="string"){let u=n[c].trim();u.length>0&&(o[c]=u,i=!0)}let d=["files_touched","tools_used","rejected_approaches","open_threads","decisions","file_edit_intentions","unresolved_errors","tool_state"];for(let c of d)if(Array.isArray(n[c])){let u=n[c],l=Y.array(Y.string()).safeParse(u);l.success&&u.length>0&&(o[c]=l.data,i=!0)}if(i&&(r.synopsis=o),!(r.title===void 0&&r.synopsis===void 0))return r}function Qt(s){try{return JSON.parse(s)}catch{return}}function Ld(s){let e=s.indexOf("{");if(e<0)return;let t=0,n=!1,r=!1;for(let o=e;o<s.length;o++){let i=s[o];if(n){r?r=!1:i==="\\"?r=!0:i==='"'&&(n=!1);continue}if(i==='"'){n=!0;continue}if(i==="{")t++;else if(i==="}"&&(t--,t===0))return s.slice(e,o+1)}}function ch(s){return s.goal!==void 0&&s.goal.trim().length>0||s.outcome!==void 0&&s.outcome.trim().length>0||s.files_touched!==void 0&&s.files_touched.length>0||s.tools_used!==void 0&&s.tools_used.length>0||s.rejected_approaches!==void 0&&s.rejected_approaches.length>0||s.open_threads!==void 0&&s.open_threads.length>0||s.decisions!==void 0&&s.decisions.length>0||s.file_edit_intentions!==void 0&&s.file_edit_intentions.length>0||s.unresolved_errors!==void 0&&s.unresolved_errors.length>0||s.tool_state!==void 0&&s.tool_state.length>0}var lh="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",fh=uh(lh,16),ph="hydra_lineage_";function xn(){return`${ph}${fh()}`}var Io=P.object({name:P.string(),description:P.string().optional()}),Ao=P.object({id:P.string(),name:P.string().optional(),description:P.string().optional()}),gh=P.object({modelId:P.string(),name:P.string().optional(),description:P.string().optional()}),Co=P.object({used:P.number().optional(),size:P.number().optional(),costAmount:P.number().optional(),costCurrency:P.string().optional(),cumulativeCost:P.number().optional()}),Ro=P.object({name:P.string(),version:P.string().optional()}),hh=P.object({path:P.string(),sourceCwd:P.string(),label:P.string(),requestedLabel:P.string().optional(),provider:P.string(),snapshot:P.string().optional(),line:P.string().optional(),vcs:P.record(P.string(),P.string()).optional(),clean:P.boolean().optional()}),mh=P.object({previousUpstreamSessionId:P.string(),previousSummarizedThroughEntry:P.number().int().nonnegative().optional(),runId:P.string().optional()}),yh=P.enum(["compaction","agent-swap","workspace-enter","workspace-leave","rollback","restart"]),wh=P.object({upstreamSessionId:P.string(),agentId:P.string(),reason:yh.optional(),runId:P.string().optional(),startedAt:P.string().optional(),endedAt:P.string().optional(),cost:P.number().nonnegative().optional(),lifetimeCostAtStart:P.number().nonnegative().optional(),usedAtStart:P.number().nonnegative().optional(),usedAtEnd:P.number().nonnegative().optional(),inferred:P.boolean().optional()}),kh=P.object({version:P.literal(1),sessionId:P.string(),lineageId:P.string().optional(),upstreamSessionId:P.string(),importedFromSessionId:P.string().optional(),importedFromUpstreamSessionId:P.string().optional(),importedFromMachine:P.string().optional(),agentId:P.string(),cwd:P.string(),title:P.string().optional(),synopsis:Cn.optional(),compactionState:Nd.optional(),rollbackBreadcrumb:mh.optional(),upstreamGenerations:P.array(wh).optional(),summarizedThroughEntry:P.number().int().nonnegative().optional(),agentArgs:P.array(P.string()).optional(),currentModel:P.string().optional(),currentMode:P.string().optional(),currentUsage:Co.optional(),agentCommands:P.array(Io).optional(),agentModes:P.array(Ao).optional(),agentModels:P.array(gh).optional(),configOptionValues:P.record(P.string(),P.string()).optional(),pendingHistorySync:P.boolean().optional(),pendingAgentSwap:P.string().optional(),parentSessionId:P.string().optional(),forkedFromSessionId:P.string().optional(),forkedFromMessageId:P.string().optional(),side:Ht.optional(),forkSynthesisState:P.enum(["running","failed"]).optional(),originatingClient:Ro.optional(),interactive:P.boolean().optional(),priority:P.number().int().nonnegative().optional(),lastTurnEndedAt:P.number().int().nonnegative().optional(),readAt:P.number().int().nonnegative().optional(),forwardedEnv:P.record(P.string(),P.string()).optional(),workspace:hh.optional(),attentionFlags:Fd.default([]).optional(),extensionState:P.record(P.string(),P.record(P.string(),P.unknown())).default({}).optional(),createdAt:P.string(),updatedAt:P.string()}),Rn=/^[A-Za-z0-9_-]+$/;function vh(s){if(!Rn.test(s))throw new Error(`unsafe session id: ${s}`)}var vs=class{index;indexSeed;async write(e){vh(e.sessionId);let t={version:1,...e};await he(E.sessionFile(e.sessionId),t,{mode:384}),await this.reindex(e.sessionId)}async touch(e){if(!Rn.test(e))return;let t=new Date;try{await _e.utimes(E.sessionFile(e),t,t)}catch(n){if(n.code!=="ENOENT")throw n;return}await this.reindex(e)}async markDeleted(e,t){await this.ensureIndex();let n=this.index.get(e);n&&!n.deleted||n&&n.mtimeMs>=t||this.index.set(e,{mtimeMs:t,deleted:!0})}async cursor(){await this.ensureIndex();let e=0;for(let t of this.index.values())t.mtimeMs>e&&(e=t.mtimeMs);return e}async listChangedSince(e){let t=await this.cursor(),n=[],r=[];for(let[a,d]of this.index)d.mtimeMs<e||(d.deleted?r.push(a):n.push(a));let o=await Promise.all(n.map(a=>this.read(a).catch(()=>{}))),i=[];for(let a of o)a&&i.push(a);return{records:i,removed:r,cursor:t}}async ensureIndex(){this.index||(this.indexSeed||(this.indexSeed=this.seedIndex()),await this.indexSeed)}async seedIndex(){let e=new Map,t=[];try{t=await _e.readdir(E.sessionsDir())}catch(n){if(n.code!=="ENOENT")throw n}await Promise.all(t.map(async n=>{if(Rn.test(n))try{let r=await _e.stat(E.sessionFile(n));e.set(n,{mtimeMs:r.mtimeMs,deleted:!1})}catch{}})),this.index=e}async reindex(e){if(this.indexSeed){await this.indexSeed;try{let t=await _e.stat(E.sessionFile(e));this.index.set(e,{mtimeMs:t.mtimeMs,deleted:!1})}catch{}}}async read(e){if(!Rn.test(e))return;let t=await de(E.sessionFile(e));if(t!==void 0)try{return kh.parse(t)}catch{return}}async delete(e){if(Rn.test(e)){this.indexSeed&&(await this.indexSeed,this.index.set(e,{mtimeMs:Date.now(),deleted:!0}));try{await _e.unlink(E.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await _e.rmdir(E.sessionDir(e))}catch(t){let n=t;if(n.code!=="ENOENT"&&n.code!=="ENOTEMPTY")throw t}}}async findByLineageId(e){if(e.length===0)return;let t=await this.list().catch(()=>[]);for(let n of t)if(n.lineageId===e)return n}async list(){let e;try{e=await _e.readdir(E.sessionsDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let t=await Promise.all(e.map(r=>this.read(r).catch(()=>{}))),n=[];for(let r of t)r&&n.push(r);return n}};function xo(s){let e=new Date().toISOString(),t=s.createdAt??e,n=(s.currentUsage?.cumulativeCost??0)+(s.currentUsage?.costAmount??0),r=s.upstreamGenerations??(s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId,startedAt:t,...n===0?{lifetimeCostAtStart:0}:{}}]:[]);return{sessionId:s.sessionId,lineageId:s.lineageId,upstreamSessionId:s.upstreamSessionId,importedFromSessionId:s.importedFromSessionId,importedFromUpstreamSessionId:s.importedFromUpstreamSessionId,importedFromMachine:s.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:s.synopsis,summarizedThroughEntry:s.summarizedThroughEntry,compactionState:s.compactionState,rollbackBreadcrumb:s.rollbackBreadcrumb,upstreamGenerations:r,agentArgs:s.agentArgs,currentModel:s.currentModel,currentMode:s.currentMode,currentUsage:s.currentUsage,agentCommands:s.agentCommands,agentModes:s.agentModes,agentModels:s.agentModels,configOptionValues:s.configOptionValues,pendingHistorySync:s.pendingHistorySync,pendingAgentSwap:s.pendingAgentSwap,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,side:s.side,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,priority:s.priority,lastTurnEndedAt:s.lastTurnEndedAt,readAt:s.readAt,forwardedEnv:s.forwardedEnv,workspace:s.workspace,attentionFlags:s.attentionFlags??[],extensionState:s.extensionState??{},createdAt:t,updatedAt:s.updatedAt??e}}He();K();import*as ae from"fs/promises";import*as be from"path";K();import*as bs from"path";import{createHash as bh}from"crypto";var Fe=class extends Error{constructor(e,t){super(`provider "${e}" does not support ${t}; check capabilities().supports before calling`),this.name="WorkspaceUnsupportedError"}};function Yt(s){let e=bh("sha256").update(bs.resolve(s)).digest("hex").slice(0,12);return bs.join(q(),"workspaces",e)}async function Ss(s,e,t=100){if(await e(s))return s;for(let n=2;n<=t;n+=1){let r=`${s}-${n}`;if(await e(r))return r}}function It(s,e=10){if(s.length<=e)return[...s];let t=s.slice(0,e),n=s.length-e;return[...t,`... and ${n} more`]}function Eo(s){return s.changedPaths.length>0||s.recorded!==void 0&&s.recorded!==s.actual}function Sh(s){let e=[];for(let t of s){if(t.changedPaths.length===0){e.push(`${t.relPath} (nested tree advanced to ${t.actual.slice(0,8)})`);continue}for(let n of t.changedPaths)e.push(`${t.relPath}/${n}`)}return e}function To(s,e){let t=new Set(e.map(r=>r.relPath));return[...s.filter(r=>!t.has(r.replace(/\/$/,""))),...Sh(e.filter(Eo))]}function Is(s){let e=s.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e.slice(0,64):"workspace"}var Po="copy",Bd=new Set([".git"]);function En(s){return`${s}.manifest.json`}async function Ud(s){let e=new Map,t=[s];for(;t.length>0;){let n=t.pop();if(n===void 0)break;let r;try{r=await ae.readdir(n,{withFileTypes:!0})}catch{continue}for(let o of r){let i=be.join(n,o.name);if(!(n===s&&Bd.has(o.name))){if(o.isDirectory()){t.push(i);continue}if(o.isFile())try{let a=await ae.stat(i);e.set(be.relative(s,i),{size:a.size,mtimeMs:a.mtimeMs})}catch{continue}}}}return e}var As=class{kind=Po;capabilities(){return{cheapWorkspaces:!1,sharedHistory:!1,nonMutatingCapture:!0,conflictReporting:!1,locking:!1,requiresServer:!1,supports:{record:!1,integrate:!1,captureWorkingState:!1,changedPaths:!1,environmentNotes:!0,rematerialize:!1,nestedTrees:!1}}}async materializeNested(){return{ok:!0,count:0}}async retainSnapshot(){}async dropSnapshotRef(){}async rematerialize(e){return{ok:!1,reason:`copy provider retains nothing outside ${e.path}; it cannot be rebuilt`}}async createWorkspace(e){if(e.from!==void 0)return{ok:!1,reason:"copy provider cannot create from a snapshot; it records none"};let t=be.resolve(e.sourceCwd),n=e.contentFrom!==void 0?be.resolve(e.contentFrom):t;try{n=await ae.realpath(n)}catch{}try{if(!(await ae.stat(n)).isDirectory())return{ok:!1,reason:`${n} is not a directory`}}catch{return{ok:!1,reason:`${n} does not exist`}}let r=Yt(t);try{await ae.mkdir(r,{recursive:!0})}catch(u){return{ok:!1,reason:`could not create workspace root: ${String(u)}`}}let o=await Ss(Is(e.label),async u=>ae.access(be.join(r,u)).then(()=>!1).catch(()=>!0));if(o===void 0)return{ok:!1,reason:`no free name available for "${e.label}"`};let i=be.join(r,o),a;try{a=await ae.readdir(n)}catch(u){return{ok:!1,reason:`copy failed: ${String(u)}`}}try{await ae.mkdir(i,{recursive:!0});for(let u of a)Bd.has(u)||await ae.cp(be.join(n,u),be.join(i,u),{recursive:!0,errorOnExist:!1,force:!0})}catch(u){return await ae.rm(i,{recursive:!0,force:!0}).catch(()=>{}),{ok:!1,reason:`copy failed: ${String(u)}`}}let d=await Ud(i),c={sourceCwd:t,label:o,createdAt:new Date().toISOString(),entries:Object.fromEntries(d)};return await he(En(i),c,{pretty:!1}),{ok:!0,workspace:{path:i,sourceCwd:t,label:o,provider:this.kind}}}async removeWorkspace(e,t){if(!t.force){let n=await this.status(e);if(!n.clean)throw new Error(`workspace ${e.path} has ${n.changedPaths.length} changed path(s); pass force to remove`)}await ae.rm(e.path,{recursive:!0,force:!0}),await ae.rm(En(e.path),{force:!0})}async listWorkspaces(e){let t=Yt(be.resolve(e)),n;try{n=await ae.readdir(t)}catch{return[]}let r=[];for(let o of n){if(o.endsWith(".manifest.json"))continue;let i=be.join(t,o),a=await de(En(i));a!==void 0&&r.push({path:i,sourceCwd:a.sourceCwd,label:a.label,provider:this.kind})}return r}async status(e){let t=await de(En(e.path)),n=await Ud(e.path);if(t===void 0)return{clean:!1,changedPaths:[...n.keys()].sort(),hasRecordedWork:!1};let r=[];for(let[o,i]of n){let a=t.entries[o];(a===void 0||a.size!==i.size||a.mtimeMs!==i.mtimeMs)&&r.push(o)}for(let o of Object.keys(t.entries))n.has(o)||r.push(o);return r.sort(),{clean:r.length===0,changedPaths:r,hasRecordedWork:!1}}async statusReport(e){let{changedPaths:t}=await this.status(e),n=t.length===0?["no changes since this copy was made"]:[`${t.length} changed file(s) since this copy was made:`,...It(t.map(r=>` ${r}`))];return n.push(`Not tracking ${$(e.sourceCwd)}: a copied directory has no shared history, so there is nothing to be in or out of sync with.`),n}async environmentNotes(e){return[`This directory is an isolated copy of ${e.sourceCwd}. It is not under version control: there is no history, no branches, and version-control commands will not behave as they would in the original.`,"Changes here are not automatically returned to the original directory."]}async captureWorkingState(){throw new Fe(this.kind,"captureWorkingState")}async record(){throw new Fe(this.kind,"record")}async attributeOrphan(e){let t=await de(En(e));if(t?.sourceCwd!==void 0)return{path:e,sourceCwd:t.sourceCwd,label:t.label??be.basename(e),provider:this.kind}}async discardLine(){return{ok:!0,dropped:0}}ownsLine(){return!1}async pruneStale(){}async changedPaths(){throw new Fe(this.kind,"changedPaths")}async integrate(){return{ok:!1,conflicts:[],declined:!0,reason:`the "${this.kind}" provider keeps no history, so there is nothing to integrate from`}}async currentState(){}async contentId(){}async currentLineName(){}async resolveRoot(e){return e}async resolveRetained(){}async contains(){return!1}async divergence(){}async changedPathsBetween(){return[]}async captureDelta(){throw new Fe(this.kind,"captureDelta")}async applyDelta(){return{ok:!1,reason:`the "${this.kind}" provider cannot reproduce a captured change`}}async resetTo(){return{ok:!1,reason:`the "${this.kind}" provider records no state to return to`}}async integrationInProgress(){return!1}async abortIntegration(){}async conflictedPaths(){return[]}async listNested(){return[]}async captureNested(){return[]}async reproduceNested(){return{applied:[],failed:[]}}async integrateNested(){return{applied:[],failed:[]}}async lock(){throw new Fe(this.kind,"lock")}async unlock(){throw new Fe(this.kind,"unlock")}};K();import{execFile as Vd}from"child_process";import{randomBytes as Rh}from"crypto";import*as Ne from"fs/promises";import*as Gd from"os";import*as X from"path";function Ih(s){let e=s.indexOf(" ");return e===-1?{key:s,value:""}:{key:s.slice(0,e),value:s.slice(e+1)}}function Wd(s){let e=[],t,n=()=>{t!==void 0&&(e.push(t),t=void 0)};for(let r of s.split(`
126
- `)){let o=r.replace(/\r$/,"");if(o.length===0){n();continue}let{key:i,value:a}=Ih(o);if(i==="worktree"){n(),t={path:a,bare:!1,detached:!1};continue}if(t!==void 0)switch(i){case"HEAD":t.head=a;break;case"branch":t.branch=a;break;case"bare":t.bare=!0;break;case"detached":t.detached=!0;break;case"locked":t.lockedReason=a;break;case"prunable":t.prunableReason=a;break;default:break}}return n(),e}function qd(s){if(s===void 0)return;let e="refs/heads/";return s.startsWith(e)?s.slice(e.length):s}var xs="git",zd="hydra-acp:",Mo="hydra",J=5e3,pe=12e4,Cs=9e5;function Jd(s){return Ne.access(s).then(()=>!0).catch(()=>!1)}function Tn(s){return s.length===0?s:X.normalize(s)}function xh(s){return Ne.realpath(s).catch(()=>s)}function H(s,e,t,n){return new Promise(r=>{Vd("git",s,{cwd:e,timeout:t,maxBuffer:8*1024*1024,...n?{env:{...process.env,...n}}:{}},(o,i,a)=>{r({ok:!o,stdout:i??"",stderr:a??""})})})}function _o(s,e,t,n=pe){return new Promise(r=>{let o=Vd("git",s,{cwd:e,timeout:n,maxBuffer:67108864},(i,a,d)=>{r({ok:!i,stdout:a??"",stderr:d??""})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}function $o(s){let e=[];for(let t of s.split(`
127
- `)){let n=t.replace(/\r$/,"");if(n.length<4)continue;let r=n.slice(3),o=r.indexOf(" -> ");e.push({code:n.slice(0,2),path:o===-1?r:r.slice(o+4)})}return e}var Rs=class{kind=xs;refRoot(e){return e.vcs?.repoRoot??e.sourceCwd}ownsLine(e){return e.startsWith(`${Mo}/`)}capabilities(){return{cheapWorkspaces:!0,sharedHistory:!0,nonMutatingCapture:!0,conflictReporting:!0,locking:!0,requiresServer:!1,supports:{record:!0,integrate:!0,captureWorkingState:!0,changedPaths:!1,environmentNotes:!0,rematerialize:!0,nestedTrees:!0}}}async materializeNested(e,t){if(!await Jd(X.join(e.path,".gitmodules")))return{ok:!0,count:0};let r=await H(["submodule","update","--init","--recursive",...t?.discardLocal===!0?["--force"]:[]],e.path,Cs);if(!r.ok)return{ok:!1,count:0,reason:r.stderr.trim()||"git submodule update --init failed"};if(t?.discardLocal===!0){let a=await H(["submodule","foreach","--recursive","git","reset","--hard"],e.path,Cs);if(!a.ok)return{ok:!1,count:0,reason:a.stderr.trim()||"could not reset submodules"};let d=t.purgeIgnored===!0?"-ffdx":"-fd",c=await H(["submodule","foreach","--recursive","git","clean",d],e.path,Cs);if(!c.ok)return{ok:!1,count:0,reason:c.stderr.trim()||"could not clean submodules"}}let o=await H(["submodule","status","--recursive"],e.path,J);return{ok:!0,count:o.ok?o.stdout.split(`
128
- `).filter(a=>a.trim().length>0).length:0}}async rematerialize(e){let t=e.vcs?.branch;if(t===void 0)return{ok:!1,reason:"workspace has no recorded branch to restore from"};let n=this.refRoot(e);if(!await Jd(n))return{ok:!1,reason:`source repository ${n} no longer exists`};let r=await H(["rev-parse","--verify","--quiet",`refs/heads/${t}`],n,J);if(!r.ok||r.stdout.trim().length===0)return{ok:!1,reason:`branch ${t} no longer exists in ${n}`};await H(["worktree","unlock",e.path],n,J),await H(["worktree","prune"],n,J);let o=await H(["worktree","add",e.path,t],n,pe);return o.ok?{ok:!0,workspace:{...e,line:t,vcs:{...e.vcs??{},kind:"git",branch:t,repoRoot:n}}}:{ok:!1,reason:`could not restore worktree: ${o.stderr.trim()||"unknown error"}`}}async createWorkspace(e){let t=X.resolve(e.sourceCwd),n=await H(["rev-parse","--show-toplevel"],t,J);if(!n.ok)return{ok:!1,reason:`${t} is not a git repository (or git is unavailable)`};let r=Tn(n.stdout.trim());if(r.length===0)return{ok:!1,reason:`could not resolve the repository root for ${t}`};let o=await H(["rev-parse","HEAD"],r,J);if(!o.ok)return{ok:!1,reason:`${r} has no commits yet, so there is nothing to branch from`};let i=e.from??o.stdout.trim(),a=Is(e.label),d=Yt(t);try{await Ne.mkdir(d,{recursive:!0})}catch(f){return{ok:!1,reason:`could not create workspace root: ${String(f)}`}}let c=await Ss(a,async f=>await Ne.access(X.join(d,f)).then(()=>!0).catch(()=>!1)?!1:!(await H(["rev-parse","--verify","--quiet",`refs/heads/${Mo}/${f}`],r,J)).ok);if(c===void 0)return{ok:!1,reason:`no free name available for "${a}"`};let u=X.join(d,c),l=`${Mo}/${c}`,p=await H(["worktree","add","--no-track","-b",l,u,i],r,pe);return p.ok?{ok:!0,workspace:{path:u,sourceCwd:t,label:c,provider:this.kind,snapshot:i,line:l,vcs:{kind:"git",branch:l,base:i,repoRoot:r}}}:{ok:!1,reason:`git worktree add failed: ${p.stderr.trim()||"unknown error"}`}}async removeWorkspace(e,t){if(!t.force){let o=await this.status(e);if(!o.clean)throw new Error(`workspace ${e.path} has ${o.changedPaths.length} changed path(s)${o.hasRecordedWork?" and unintegrated recorded work":""}; pass force to remove`)}let n=this.refRoot(e);await this.unlock(e).catch(()=>{});let r=await H(["worktree","remove","--force",e.path],n,pe);t.discardLine===!0&&e.vcs?.branch!==void 0&&await H(["branch","-D",e.vcs.branch],n,J),r.ok||(await Ne.rm(e.path,{recursive:!0,force:!0}),await H(["worktree","prune"],n,J))}async listWorkspaces(e){let t=X.resolve(e),n=await H(["rev-parse","--show-toplevel"],t,J);if(!n.ok)return[];let r=Tn(n.stdout.trim()),o=await H(["worktree","list","--porcelain"],r,J);if(!o.ok)return[];let i=Yt(t),a=await xh(i),d=[];for(let c of Wd(o.stdout)){let u=Tn(c.path),l=X.dirname(u);if(l!==i&&l!==a)continue;let p=X.join(i,X.basename(u)),f={kind:"git",repoRoot:r},h=qd(c.branch);h!==void 0&&(f.branch=h),c.head!==void 0&&(f.head=c.head),c.lockedReason!==void 0&&(f.locked=c.lockedReason);let w=c.lockedReason?.startsWith(zd)===!0;d.push({path:p,sourceCwd:t,label:X.basename(p),...w?{heldByUs:!0}:{},provider:this.kind,...h!==void 0?{line:h}:{},vcs:f})}return d}async status(e){let t=await H(["status","--porcelain","--untracked-files=all"],e.path,J);if(!t.ok)return{clean:!1,changedPaths:[],hasRecordedWork:!1};let n=$o(t.stdout),r=n.map(a=>a.path),o=n.some(({code:a})=>a!=="??"&&a[0]!==" "&&a[0]!=="?"),i=!1;if(e.snapshot!==void 0){let a=await H(["rev-list","--count",`${e.snapshot}..HEAD`],e.path,J);a.ok&&(i=Number.parseInt(a.stdout.trim(),10)>0)}return{clean:r.length===0&&!i,changedPaths:r,hasRecordedWork:i,hasStagedWork:o}}async lock(e,t){let n=this.refRoot(e);await H(["worktree","lock","--reason",`${zd}${t}`,e.path],n,J)}async unlock(e){let t=this.refRoot(e);await H(["worktree","unlock",e.path],t,J)}async environmentNotes(e){let t=[],n=e.vcs?.branch;return t.push(`This directory is a git worktree of ${e.sourceCwd}${n!==void 0?`, on branch ${n}`:""}. Do not read or write ${e.sourceCwd} directly; paths under it refer to the corresponding file here. Prefer repo-relative paths, which are identical in both.`),t.push("`.git` here is a file, not a directory. That is normal for a worktree and does not need repairing."),await Ne.access(X.join(e.path,".gitmodules")).then(()=>!0).catch(()=>!1)&&t.push("Submodules here are initialized and checked out at the commits this tree records, which means each sits on a detached HEAD. That is normal and does not need repairing. Never re-add a submodule's contents as ordinary tracked files in the superproject: that silently corrupts the integration back to the source branch."),t}async statusReport(e){let t=[],n=await H(["status","--porcelain","--untracked-files=all"],e.path,J);if(n.ok){let r=$o(n.stdout);if(r.length===0)t.push("no uncommitted changes");else{let o=0,i=0,a=0;for(let{code:c}of r){if(c==="??"){a+=1;continue}c[0]!==" "&&c[0]!=="?"&&(o+=1),c[1]!==" "&&c[1]!=="?"&&(i+=1)}let d=[];o>0&&d.push(`${o} staged`),i>0&&d.push(`${i} unstaged`),a>0&&d.push(`${a} untracked`),t.push(`${d.join(", ")}:`),t.push(...It(r.map(c=>` ${c.code} ${c.path}`)))}}return t.push(...await this.syncLines(e)),t}async syncLines(e){if(e.vcs?.branch===void 0)return[];let[t,n]=await Promise.all([H(["rev-parse","HEAD"],e.sourceCwd,J),H(["rev-parse","HEAD"],e.path,J)]),r=t.stdout.trim(),o=n.stdout.trim();if(!t.ok||!n.ok||r.length===0||o.length===0)return[];let i=$(e.sourceCwd);if(r===o)return[`in sync with ${i}`];let a=await H(["rev-list","--left-right","--count",`${r}...${o}`],e.path,J),d=a.stdout.trim().split(/\s+/).map(p=>Number.parseInt(p,10)),c=d[0],u=d[1];if(!a.ok||c===void 0||u===void 0||!Number.isFinite(c)||!Number.isFinite(u))return[];let l=[];return c>0&&l.push(`${c} commit(s) behind ${i}. \`/hydra workspace sync\` brings them in; landing is fast-forward-only, so this also unblocks \`stop\`.`),u>0&&l.push(`${u} commit(s) recorded here and not landed yet.`),l}async captureWorkingState(e,t){let n=X.join(Gd.tmpdir(),`hydra-index-${process.pid}-${Rh(6).toString("hex")}`),r={GIT_INDEX_FILE:n};try{let o=await H(["rev-parse","--verify","HEAD"],e,J),i=o.ok&&o.stdout.trim().length>0;if(i){let l=await H(["read-tree","HEAD"],e,pe,r);if(!l.ok)throw new Error(`could not seed the snapshot index: ${l.stderr.trim()}`)}let a=await H(["add","-A"],e,pe,r);if(!a.ok)throw new Error(`could not stage working state: ${a.stderr.trim()}`);let d=await H(["write-tree"],e,pe,r);if(!d.ok||d.stdout.trim().length===0)throw new Error(`could not write tree: ${d.stderr.trim()}`);let c=["commit-tree",d.stdout.trim(),"-m",t];i&&c.push("-p",o.stdout.trim());let u=await H(c,e,pe,r);if(!u.ok||u.stdout.trim().length===0)throw new Error(`could not create snapshot commit: ${u.stderr.trim()}`);return u.stdout.trim()}finally{await Ne.rm(n,{force:!0}).catch(()=>{})}}async retainSnapshot(e,t,n){let r=this.refRoot(e);await H(["update-ref","--create-reflog",t,n],r,J)}async dropSnapshotRef(e,t){let n=this.refRoot(e);await H(["update-ref","-d",t],n,J)}async currentState(e){let t=await H(["rev-parse","HEAD"],e,J),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async contentId(e,t){let n=await H(["rev-parse",`${t}^{tree}`],e,J),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async currentLineName(e){let t=await H(["rev-parse","--abbrev-ref","HEAD"],e,J),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async resolveRoot(e){let t=await H(["rev-parse","--show-toplevel"],e,J),n=Tn(t.stdout.trim());return t.ok&&n.length>0?n:void 0}async resolveRetained(e,t){let n=await H(["rev-parse","--verify","--quiet",`${t}^{commit}`],this.refRoot(e),J),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async contains(e,t){return(await H(["merge-base","--is-ancestor",t.state,t.within],e,J)).ok}async divergence(e,t,n){let r=await H(["rev-list","--left-right","--count",`${t}...${n}`],e,J);if(!r.ok)return;let o=r.stdout.trim().split(/\s+/).map(d=>Number.parseInt(d,10)),i=o[0],a=o[1];if(!(i===void 0||a===void 0||!Number.isFinite(i)||!Number.isFinite(a)))return{ahead:i,behind:a}}async changedPathsBetween(e,t,n){let r=await H(["diff","--name-only",t,n],e,J);return r.ok?r.stdout.split(`
129
- `).map(o=>o.replace(/\r$/,"").trim()).filter(o=>o.length>0):[]}async captureDelta(e,t,n){let r=await H(["diff","--binary","--ignore-submodules=all",t,n],e,pe);if(r.ok)return r.stdout}async applyDelta(e,t,n){if(t.trim().length===0)return{ok:!0,alreadyPresent:!0};let r=n?.stage===!0?["--index"]:[],o=await _o(["apply",...r],e,t);if(o.ok)return{ok:!0};if(n?.tolerant!==!0)return{ok:!1,reason:o.stderr.trim()||"the change did not apply"};if((await _o(["apply","--reverse","--check"],e,t)).ok)return{ok:!0,alreadyPresent:!0};let a=await _o(["apply","--3way"],e,t);return a.ok?{ok:!0}:{ok:!1,reason:a.stderr.trim()||"the change overlaps what is already there"}}async resetTo(e,t,n){let r=await H(["reset","--hard",t],e,pe);if(!r.ok)return{ok:!1,reason:r.stderr.trim()||"could not return to that state"};let o=await H(["clean",n?.purgeIgnored===!0?"-ffdx":"-fd"],e,pe);if(!o.ok)return{ok:!1,reason:o.stderr.trim()||"returned to that state but could not remove extra files"};let i=await this.materializeNested({path:e,sourceCwd:e,label:"",provider:this.kind},{discardLocal:!0,...n?.purgeIgnored===!0?{purgeIgnored:!0}:{}});return i.ok?{ok:!0}:{ok:!1,reason:i.reason??"could not reset nested trees"}}async integrationInProgress(e){return(await H(["rev-parse","-q","--verify","MERGE_HEAD"],e,J)).ok}async abortIntegration(e){await H(["merge","--abort"],e,pe)}async conflictedPaths(e){let t=await H(["diff","--name-only","--diff-filter=U"],e,J);return t.ok?t.stdout.split(`
130
- `).map(n=>n.replace(/\r$/,"").trim()).filter(n=>n.length>0):[]}async record(e,t){let n=await H(["add","-A"],e.path,pe);if(!n.ok)throw new Error(`could not stage ${e.path}: ${n.stderr.trim()||"unknown error"}`);let r=await this.status(e),o=await this.currentState(e.path);if(r.changedPaths.length===0){if(o===void 0)throw new Error(`could not read the state of ${e.path}`);return o}let i=await H(["commit","-m",t],e.path,pe);if(!i.ok)throw new Error(`could not record ${e.path}: ${i.stderr.trim()||i.stdout.trim()||"unknown error"}`);let a=await this.currentState(e.path);if(a===void 0)throw new Error(`recorded ${e.path} but could not read the resulting state`);return a}async attributeOrphan(e){let t=await H(["rev-parse","--path-format=absolute","--git-common-dir"],e,J),n=Tn(t.stdout.trim());if(!t.ok||n.length===0)return;let r=X.dirname(n),o=await this.currentLineName(e);return{path:e,sourceCwd:r,label:X.basename(e),provider:this.kind,...o!==void 0?{line:o}:{},vcs:{repoRoot:r,...o!==void 0?{branch:o}:{}}}}async discardLine(e,t){let n=this.refRoot(e),o=(await this.divergence(n,"HEAD",t))?.behind??0,i=await H(["branch","-D",t],n,J);return i.ok?{ok:!0,dropped:o}:{ok:!1,dropped:o,reason:i.stderr.trim()||"could not discard the line"}}async pruneStale(e){await H(["worktree","prune"],this.refRoot(e),J)}async changedPaths(){throw new Fe(this.kind,"changedPaths")}async integrate(e){let{into:t,from:n}=e,r=await this.currentState(t);if(r===void 0)return{ok:!1,conflicts:[],declined:!0,reason:`cannot read the state of ${t}`};if(await this.contains(t,{state:n,within:r}))return{ok:!0,snapshot:r,alreadyUpToDate:!0};if(e.fastForwardOnly===!0&&!await this.contains(t,{state:r,within:n}))return{ok:!1,conflicts:[],declined:!0,reason:`${t} cannot simply advance to that state; it has moved on independently`};let o=e.fastForwardOnly===!0?["merge","--ff-only",n]:["merge","--no-edit","-m",e.message??"hydra: integrate",n],i=await H(o,t,pe);if(i.ok){let c=await this.currentState(t);return c===void 0?{ok:!1,conflicts:[],reason:"integrated but could not read the resulting state"}:{ok:!0,snapshot:c}}let a=await this.conflictedPaths(t),d=await this.integrationInProgress(t);return a.length===0&&!d?{ok:!1,conflicts:[],declined:!0,reason:i.stderr.trim()||"the integration was refused"}:(e.onConflict==="abort"&&await this.abortIntegration(t),{ok:!1,conflicts:a})}async listNested(e){let t=await H(["submodule","status","--recursive"],e,pe);if(!t.ok)return[];let n=[];for(let r of t.stdout.split(`
131
- `)){let o=r.replace(/\r$/,"");if(o.trim().length===0||(o[0]??" ")==="-")continue;let a=o.slice(1),d=a.indexOf(" ");if(d<=0)continue;let c=a.slice(d+1).replace(/\s+\(.*\)\s*$/,"").trim();if(c.length===0||!Eh(e,c))continue;let u=X.join(e,c),[l,p,f]=await Promise.all([this.currentState(u),H(["rev-parse",`HEAD:${c}`],e,J),H(["status","--porcelain","--untracked-files=all"],u,J)]);if(l===void 0)continue;let h=p.ok?p.stdout.trim():"";n.push({relPath:c,actual:l,...h.length>0?{recorded:h}:{},changedPaths:f.ok?$o(f.stdout).map(w=>w.path):[]})}return n}async captureNested(e,t){let n=[];for(let r of t){if(!Eo(r))continue;if(r.changedPaths.length===0){n.push(r);continue}let o=X.join(e,r.relPath),i=await this.captureWorkingState(o,"hydra: nested work carried into workspace").catch(()=>{});if(i===void 0){n.push(r);continue}let a=await this.captureDelta(o,r.actual,i);n.push(a===void 0?r:{...r,delta:a})}return n}async reproduceNested(e,t,n){let r=[],o=[];for(let i of n){let a=X.join(e,i.relPath),d=X.join(t,i.relPath),c=await this.alignNested(a,d,i.actual);if(c!==void 0){o.push({path:i.relPath,reason:c});continue}if(i.delta!==void 0){let u=await this.applyDelta(a,i.delta);if(!u.ok){o.push({path:i.relPath,reason:u.reason??"changes did not apply"});continue}}r.push(i.relPath)}return{applied:r,failed:o}}async integrateNested(e,t,n){let r=[],o=[],i=new Map(n.map(c=>[c.relPath,c])),a=await this.listNested(e),d=new Set([...a.map(c=>c.relPath),...i.keys()]);for(let c of[...d].sort()){let u=a.find(m=>m.relPath===c),l=i.get(c);if(u===void 0){o.push({path:c,reason:"not populated in the receiving tree"});continue}let p=u.recorded!==void 0&&u.recorded!==u.actual,f=l?.delta!==void 0;if(!p&&!f)continue;if(u.changedPaths.length>0){o.push({path:c,reason:`it has ${u.changedPaths.length} uncommitted change(s) of its own, and nothing can tell those apart from what was integrated`});continue}let h=X.join(e,c),w=X.join(t,c);if(p&&u.recorded!==void 0){let m=await this.alignNested(h,w,u.recorded);if(m!==void 0){o.push({path:c,reason:m});continue}}if(l?.delta!==void 0){let m=await this.applyDelta(h,l.delta);if(!m.ok){o.push({path:c,reason:m.reason??"the uncommitted changes there did not apply"});continue}}r.push(c)}return{applied:r,failed:o}}async alignNested(e,t,n){let r=await this.currentState(e);if(r===void 0)return"not populated here";if(r===n)return;if(!(await H(["cat-file","-e",`${n}^{commit}`],e,J)).ok&&!(await H(["fetch","--no-tags",t,n],e,Cs)).ok)return`could not transfer ${n.slice(0,8)} from the other copy`;if(!(await H(["checkout","--detach",n],e,pe)).ok)return`could not move to ${n.slice(0,8)}`}};function Eh(s,e){if(X.isAbsolute(e))return!1;let t=X.resolve(s),n=X.resolve(t,e);return n!==t&&n.startsWith(t+X.sep)}var Th=xs,Ph=new Map([[xs,new Rs],[Po,new As]]);function re(s){return Ph.get(s??Th)}var Es="refs/hydra";function Xt(s){let e=`${Es}/workspaces/${s}`;return{autosave:`${e}/autosave`,start:`${e}/start`,baseline:`${e}/baseline`}}function Oo(s){return`${Es}/landing/${s}`}function Kd(s){return`${Es}/sync/${s}`}function Qd(s,e){return`${Es}/retired/${s}-${e.slice(0,12)}`}function Yd(s){let e=Xt(s);return[e.autosave,e.start,e.baseline]}async function Fo(s){let{source:e,ws:t,startSnapshotRef:n,baselineRef:r,retainRef:o,provider:i}=s;if(i===void 0)throw new Error("no provider available to inspect the source tree");let a=await i.status({...t,path:e}).catch(()=>{}),d="";for(let l of[r,n]){if(l===void 0)continue;let p=await i.resolveRetained(t,l).catch(()=>{});if(p!==void 0){d=p;break}}let c=a===void 0||a.changedPaths.length>0;if(d.length===0){if(c)throw new Error(`${e} has uncommitted changes but this workspace has no start anchor, so its copy of your work cannot be told apart from edits you made since. Refusing rather than reporting a conflict that is not yours. Commit or stash the source, then retry.`);d=await i.currentState(e).catch(()=>{})??""}if(!c)return{clean:!0,base:d};if(i.capabilities().supports.captureWorkingState!==!0)throw new Error(`${e} has uncommitted changes and this provider cannot snapshot them, so they cannot be preserved across the landing. Commit or stash them first.`);let u=await i.captureWorkingState(e,"hydra: source state before landing").catch(()=>{});if(u===void 0)throw new Error(`could not snapshot the uncommitted changes in ${e}, so refusing to touch them`);return await i.retainSnapshot({...t,path:e},o,u),{clean:!1,snapshot:u,base:d,retainedRef:o}}async function At(s){let{source:e,capture:t,provider:n}=s;if(t.clean||t.snapshot===void 0||n===void 0)return!0;let r=await n.captureDelta(e,t.base,t.snapshot).catch(()=>{});return r===void 0?!1:(await n.applyDelta(e,r,{tolerant:!0})).ok}async function Pn(s){s.capture.retainedRef===void 0||s.provider===void 0||await s.provider.dropSnapshotRef({...s.ws,path:s.source},s.capture.retainedRef).catch(()=>{})}He();import{exec as Mh}from"child_process";import*as Ke from"fs/promises";import*as Ee from"path";var _h=".hydra/worktree.json",$h=".worktreeinclude",Oh=120;async function Ts(s){let e=await de(Ee.join(s,_h))??{},t=new Set(Array.isArray(e.carry)?e.carry:[]),n=await Ke.readFile(Ee.join(s,$h),"utf8").catch(()=>{});if(n!==void 0)for(let o of n.split(`
132
- `)){let i=o.trim();i.length===0||i.startsWith("#")||i.startsWith("!")||i.includes("*")||i.includes("?")||t.add(i)}let r={};return t.size>0&&(r.carry=[...t]),typeof e.postCreate=="string"&&(r.postCreate=e.postCreate),typeof e.preRemove=="string"&&(r.preRemove=e.preRemove),typeof e.hookTimeoutSeconds=="number"&&(r.hookTimeoutSeconds=e.hookTimeoutSeconds),r}async function No(s,e,t){let n=[],r=[],o=Ee.resolve(s),i=Ee.resolve(e);for(let a of t){let d=Ee.resolve(o,a),c=Ee.resolve(i,a);if(!d.startsWith(o+Ee.sep)||!c.startsWith(i+Ee.sep)){r.push(a);continue}if(await Ke.access(c).then(()=>!0).catch(()=>!1)){r.push(a);continue}let l=await Ke.stat(d).catch(()=>{});if(l===void 0){r.push(a);continue}try{await Ke.mkdir(Ee.dirname(c),{recursive:!0}),await Ke.cp(d,c,{recursive:l.isDirectory(),dereference:!0}),n.push(a)}catch{r.push(a)}}return{copied:n,skipped:r}}async function Ps(s,e){let t=JSON.stringify({path:e.workspacePath,sourceCwd:e.sourceCwd,label:e.label,...e.sessionId!==void 0?{sessionId:e.sessionId}:{}}),n=(e.timeoutSeconds??Oh)*1e3;return new Promise(r=>{let o=Mh(s,{cwd:e.workspacePath,timeout:n,maxBuffer:8388608,windowsHide:!0,env:{...process.env,HYDRA_WORKSPACE_PATH:e.workspacePath,HYDRA_SOURCE_CWD:e.sourceCwd,HYDRA_WORKSPACE_LABEL:e.label,...e.sessionId!==void 0?{HYDRA_SESSION_ID:e.sessionId}:{}}},(i,a,d)=>{if(i){let c=(d||i.message||"").trim().slice(0,500);r({ok:!1,reason:c.length>0?c:"hook failed"});return}r({ok:!0})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}K();He();import*as tt from"fs/promises";import{z as De}from"zod";var Fh=De.object({version:De.literal(1),agentId:De.string(),upstreamSessionId:De.string(),sessionId:De.string().optional(),deletedAt:De.string(),upstreamUpdatedAt:De.string().optional(),cwd:De.string().optional(),title:De.string().optional(),reason:De.enum(["user","expired"]).optional(),interactive:De.boolean().optional()}),Ms=class{async add(e){let t={version:1,...e};await he(E.tombstoneFile(e.agentId,e.upstreamSessionId),t,{mode:384})}async has(e,t){try{return await tt.access(E.tombstoneFile(e,t)),!0}catch{return!1}}async read(e,t){let n=E.tombstoneFile(e,t),r=await de(n);if(r===void 0)return await this.has(e,t)?{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}:void 0;try{return Fh.parse(r)}catch{return{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}}}async remove(e,t){try{await tt.unlink(E.tombstoneFile(e,t))}catch(n){if(n.code!=="ENOENT")throw n}try{await tt.rmdir(E.tombstoneAgentDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}}async list(e){if(e!==void 0)return this.listForAgent(e);let t;try{t=await tt.readdir(E.tombstonesDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}n.push(...await this.listForAgent(o))}return n}async listForAgent(e){let t;try{t=await tt.readdir(E.tombstoneAgentDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}let i=await this.read(e,o);i&&n.push(i)}return n}};function Xd(s,e){return s.reason==="user"||e===void 0?!1:s.upstreamUpdatedAt===void 0?!0:e>s.upstreamUpdatedAt}import*as fc from"fs/promises";import{customAlphabet as zh}from"nanoid";import{fileURLToPath as Nh}from"url";import*as Mn from"path";import*as _s from"fs";function Dh(){try{let s=Mn.dirname(Nh(import.meta.url));for(let e=0;e<8;e+=1){let t=Mn.join(s,"package.json");if(_s.existsSync(t)){let r=JSON.parse(_s.readFileSync(t,"utf8"));if(typeof r.version=="string"&&r.version.length>0&&(typeof r.name!="string"||r.name.includes("hydra-acp")))return r.version}let n=Mn.dirname(s);if(n===s)break;s=n}}catch{}return"0.0.0"}var ue=Dh(),$s="hydra-acp-cat";var Hh=12e4;async function ec(s,e,t){let n=s.timeoutMs??Hh,r,o,i=!1;try{let a=(async()=>{r=dt.spawn({agentId:s.agentId,cwd:s.cwd,plan:s.plan,logger:s.logger});let d=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:{name:"hydra-synopsis",version:ue}}),c=await r.connection.request("session/new",{cwd:s.cwd,mcpServers:[]}),u=c.sessionId;if(typeof u!="string"){s.logger?.warn(`synopsis: agent ${s.agentId} returned non-string sessionId from session/new`),s.onFailure?.(`agent ${s.agentId} did not return a sessionId from session/new`);return}if(s.onWorkerSpawned?.(u,r.pid),s.modelId){let h=Lh(c);if(h.size===0||h.has(s.modelId)){let w=r.connection;try{await ct({request:(m,g)=>w.request(m,g),sessionId:u,modelId:s.modelId,verb:Ut(c),logger:s.logger})}catch(m){s.logger?.warn(`synopsis: agent ${s.agentId} rejected model change to ${JSON.stringify(s.modelId)}: ${m.message}; continuing on default`)}}else s.logger?.warn(`synopsis: model ${JSON.stringify(s.modelId)} not advertised by agent ${s.agentId} (have [${[...h].join(", ")}]); continuing on default`)}let l=[];r.connection.onNotification("session/update",h=>{let w=jh(h);w.length>0&&l.push(w)}),await r.connection.request("session/prompt",{sessionId:u,prompt:[{type:"text",text:e}]});let p=l.join(""),f=t(p);if(!f){let h=JSON.stringify(p.slice(0,200));s.logger?.warn(`synopsis: agent ${s.agentId} reply did not parse (replyLen=${p.length} preview=${h})`);let w=p.slice(0,120).replace(/\s+/g," ").trim();s.onFailure?.(`agent ${s.agentId} returned unparseable JSON (${p.length} chars): ${w}${p.length>120?"\u2026":""}`)}return f})();return await new Promise((d,c)=>{o=setTimeout(()=>{i=!0,s.logger?.warn(`synopsis: agent ${s.agentId} timed out after ${n}ms`),s.onFailure?.(`agent ${s.agentId} timed out after ${n}ms`),d(void 0)},n),o.unref?.(),a.then(u=>{o&&clearTimeout(o),i||d(u)},u=>{o&&clearTimeout(o),i||c(u)})})}catch(a){let d=a.message;s.logger?.warn(`synopsis: agent ${s.agentId} failed: ${d}`),s.onFailure?.(`agent ${s.agentId} failed: ${d}`);return}finally{o&&clearTimeout(o),r&&await r.kill().catch(()=>{})}}async function Os(s){let e=Vt(s.history,{maxChars:s.maxTranscriptChars}),t=s.sessionId!==void 0?`[hydra-acp title-regen worker for session ${s.sessionId}]`:"[hydra-acp title-regen worker]",n=e.length>0?`${t}
125
+ Use empty arrays/strings where a field doesn't apply.`;function Hd(s){let e=s.trim();if(e.length===0)return;let t=Qt(e);if(t===void 0){let c=e.indexOf("{"),u=e.lastIndexOf("}");c>=0&&u>c&&(t=Qt(e.slice(c,u+1)))}if(t===void 0){let c=Ld(e);c!==void 0&&(t=Qt(c))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let c=n.title.trim();c.length>0&&(r.title=c.slice(0,Dd))}let o={},i=!1,a=["goal","outcome"];for(let c of a)if(typeof n[c]=="string"){let u=n[c].trim();u.length>0&&(o[c]=u,i=!0)}let d=["files_touched","tools_used","rejected_approaches","open_threads","decisions","file_edit_intentions","unresolved_errors","tool_state"];for(let c of d)if(Array.isArray(n[c])){let u=n[c],l=Y.array(Y.string()).safeParse(u);l.success&&u.length>0&&(o[c]=l.data,i=!0)}if(i&&(r.synopsis=o),!(r.title===void 0&&r.synopsis===void 0))return r}function Qt(s){try{return JSON.parse(s)}catch{return}}function Ld(s){let e=s.indexOf("{");if(e<0)return;let t=0,n=!1,r=!1;for(let o=e;o<s.length;o++){let i=s[o];if(n){r?r=!1:i==="\\"?r=!0:i==='"'&&(n=!1);continue}if(i==='"'){n=!0;continue}if(i==="{")t++;else if(i==="}"&&(t--,t===0))return s.slice(e,o+1)}}function uh(s){return s.goal!==void 0&&s.goal.trim().length>0||s.outcome!==void 0&&s.outcome.trim().length>0||s.files_touched!==void 0&&s.files_touched.length>0||s.tools_used!==void 0&&s.tools_used.length>0||s.rejected_approaches!==void 0&&s.rejected_approaches.length>0||s.open_threads!==void 0&&s.open_threads.length>0||s.decisions!==void 0&&s.decisions.length>0||s.file_edit_intentions!==void 0&&s.file_edit_intentions.length>0||s.unresolved_errors!==void 0&&s.unresolved_errors.length>0||s.tool_state!==void 0&&s.tool_state.length>0}var fh="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",ph=lh(fh,16),gh="hydra_lineage_";function xn(){return`${gh}${ph()}`}var Io=P.object({name:P.string(),description:P.string().optional()}),Ao=P.object({id:P.string(),name:P.string().optional(),description:P.string().optional()}),hh=P.object({modelId:P.string(),name:P.string().optional(),description:P.string().optional()}),Co=P.object({used:P.number().optional(),size:P.number().optional(),costAmount:P.number().optional(),costCurrency:P.string().optional(),cumulativeCost:P.number().optional()}),Ro=P.object({name:P.string(),version:P.string().optional()}),mh=P.object({path:P.string(),sourceCwd:P.string(),label:P.string(),requestedLabel:P.string().optional(),provider:P.string(),snapshot:P.string().optional(),line:P.string().optional(),vcs:P.record(P.string(),P.string()).optional(),clean:P.boolean().optional()}),yh=P.object({previousUpstreamSessionId:P.string(),previousSummarizedThroughEntry:P.number().int().nonnegative().optional(),runId:P.string().optional()}),wh=P.enum(["compaction","agent-swap","workspace-enter","workspace-leave","rollback","restart"]),kh=P.object({upstreamSessionId:P.string(),agentId:P.string(),reason:wh.optional(),runId:P.string().optional(),startedAt:P.string().optional(),endedAt:P.string().optional(),cost:P.number().nonnegative().optional(),lifetimeCostAtStart:P.number().nonnegative().optional(),usedAtStart:P.number().nonnegative().optional(),usedAtEnd:P.number().nonnegative().optional(),inferred:P.boolean().optional()}),vh=P.object({version:P.literal(1),sessionId:P.string(),lineageId:P.string().optional(),upstreamSessionId:P.string(),importedFromSessionId:P.string().optional(),importedFromUpstreamSessionId:P.string().optional(),importedFromMachine:P.string().optional(),agentId:P.string(),cwd:P.string(),title:P.string().optional(),synopsis:Cn.optional(),compactionState:Nd.optional(),rollbackBreadcrumb:yh.optional(),upstreamGenerations:P.array(kh).optional(),summarizedThroughEntry:P.number().int().nonnegative().optional(),agentArgs:P.array(P.string()).optional(),currentModel:P.string().optional(),currentMode:P.string().optional(),currentUsage:Co.optional(),agentCommands:P.array(Io).optional(),agentModes:P.array(Ao).optional(),agentModels:P.array(hh).optional(),configOptionValues:P.record(P.string(),P.string()).optional(),pendingHistorySync:P.boolean().optional(),pendingAgentSwap:P.string().optional(),parentSessionId:P.string().optional(),forkedFromSessionId:P.string().optional(),forkedFromMessageId:P.string().optional(),side:jt.optional(),forkSynthesisState:P.enum(["running","failed"]).optional(),originatingClient:Ro.optional(),interactive:P.boolean().optional(),priority:P.number().int().nonnegative().optional(),lastTurnEndedAt:P.number().int().nonnegative().optional(),readAt:P.number().int().nonnegative().optional(),forwardedEnv:P.record(P.string(),P.string()).optional(),workspace:mh.optional(),attentionFlags:Fd.default([]).optional(),extensionState:P.record(P.string(),P.record(P.string(),P.unknown())).default({}).optional(),createdAt:P.string(),updatedAt:P.string()}),Rn=/^[A-Za-z0-9_-]+$/;function bh(s){if(!Rn.test(s))throw new Error(`unsafe session id: ${s}`)}var vs=class{index;indexSeed;async write(e){bh(e.sessionId);let t={version:1,...e};await he(E.sessionFile(e.sessionId),t,{mode:384}),await this.reindex(e.sessionId)}async touch(e){if(!Rn.test(e))return;let t=new Date;try{await _e.utimes(E.sessionFile(e),t,t)}catch(n){if(n.code!=="ENOENT")throw n;return}await this.reindex(e)}async markDeleted(e,t){await this.ensureIndex();let n=this.index.get(e);n&&!n.deleted||n&&n.mtimeMs>=t||this.index.set(e,{mtimeMs:t,deleted:!0})}async cursor(){await this.ensureIndex();let e=0;for(let t of this.index.values())t.mtimeMs>e&&(e=t.mtimeMs);return e}async listChangedSince(e){let t=await this.cursor(),n=[],r=[];for(let[a,d]of this.index)d.mtimeMs<e||(d.deleted?r.push(a):n.push(a));let o=await Promise.all(n.map(a=>this.read(a).catch(()=>{}))),i=[];for(let a of o)a&&i.push(a);return{records:i,removed:r,cursor:t}}async ensureIndex(){this.index||(this.indexSeed||(this.indexSeed=this.seedIndex()),await this.indexSeed)}async seedIndex(){let e=new Map,t=[];try{t=await _e.readdir(E.sessionsDir())}catch(n){if(n.code!=="ENOENT")throw n}await Promise.all(t.map(async n=>{if(Rn.test(n))try{let r=await _e.stat(E.sessionFile(n));e.set(n,{mtimeMs:r.mtimeMs,deleted:!1})}catch{}})),this.index=e}async reindex(e){if(this.indexSeed){await this.indexSeed;try{let t=await _e.stat(E.sessionFile(e));this.index.set(e,{mtimeMs:t.mtimeMs,deleted:!1})}catch{}}}async read(e){if(!Rn.test(e))return;let t=await de(E.sessionFile(e));if(t!==void 0)try{return vh.parse(t)}catch{return}}async delete(e){if(Rn.test(e)){this.indexSeed&&(await this.indexSeed,this.index.set(e,{mtimeMs:Date.now(),deleted:!0}));try{await _e.unlink(E.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await _e.rmdir(E.sessionDir(e))}catch(t){let n=t;if(n.code!=="ENOENT"&&n.code!=="ENOTEMPTY")throw t}}}async findByLineageId(e){if(e.length===0)return;let t=await this.list().catch(()=>[]);for(let n of t)if(n.lineageId===e)return n}async list(){let e;try{e=await _e.readdir(E.sessionsDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let t=await Promise.all(e.map(r=>this.read(r).catch(()=>{}))),n=[];for(let r of t)r&&n.push(r);return n}};function xo(s){let e=new Date().toISOString(),t=s.createdAt??e,n=(s.currentUsage?.cumulativeCost??0)+(s.currentUsage?.costAmount??0),r=s.upstreamGenerations??(s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId,startedAt:t,...n===0?{lifetimeCostAtStart:0}:{}}]:[]);return{sessionId:s.sessionId,lineageId:s.lineageId,upstreamSessionId:s.upstreamSessionId,importedFromSessionId:s.importedFromSessionId,importedFromUpstreamSessionId:s.importedFromUpstreamSessionId,importedFromMachine:s.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:s.synopsis,summarizedThroughEntry:s.summarizedThroughEntry,compactionState:s.compactionState,rollbackBreadcrumb:s.rollbackBreadcrumb,upstreamGenerations:r,agentArgs:s.agentArgs,currentModel:s.currentModel,currentMode:s.currentMode,currentUsage:s.currentUsage,agentCommands:s.agentCommands,agentModes:s.agentModes,agentModels:s.agentModels,configOptionValues:s.configOptionValues,pendingHistorySync:s.pendingHistorySync,pendingAgentSwap:s.pendingAgentSwap,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,side:s.side,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,priority:s.priority,lastTurnEndedAt:s.lastTurnEndedAt,readAt:s.readAt,forwardedEnv:s.forwardedEnv,workspace:s.workspace,attentionFlags:s.attentionFlags??[],extensionState:s.extensionState??{},createdAt:t,updatedAt:s.updatedAt??e}}je();K();import*as ae from"fs/promises";import*as be from"path";K();import*as bs from"path";import{createHash as Sh}from"crypto";var Fe=class extends Error{constructor(e,t){super(`provider "${e}" does not support ${t}; check capabilities().supports before calling`),this.name="WorkspaceUnsupportedError"}};function Yt(s){let e=Sh("sha256").update(bs.resolve(s)).digest("hex").slice(0,12);return bs.join(q(),"workspaces",e)}async function Ss(s,e,t=100){if(await e(s))return s;for(let n=2;n<=t;n+=1){let r=`${s}-${n}`;if(await e(r))return r}}function It(s,e=10){if(s.length<=e)return[...s];let t=s.slice(0,e),n=s.length-e;return[...t,`... and ${n} more`]}function Eo(s){return s.changedPaths.length>0||s.recorded!==void 0&&s.recorded!==s.actual}function Ih(s){let e=[];for(let t of s){if(t.changedPaths.length===0){e.push(`${t.relPath} (nested tree advanced to ${t.actual.slice(0,8)})`);continue}for(let n of t.changedPaths)e.push(`${t.relPath}/${n}`)}return e}function To(s,e){let t=new Set(e.map(r=>r.relPath));return[...s.filter(r=>!t.has(r.replace(/\/$/,""))),...Ih(e.filter(Eo))]}function Is(s){let e=s.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e.slice(0,64):"workspace"}var Po="copy",Bd=new Set([".git"]);function En(s){return`${s}.manifest.json`}async function Ud(s){let e=new Map,t=[s];for(;t.length>0;){let n=t.pop();if(n===void 0)break;let r;try{r=await ae.readdir(n,{withFileTypes:!0})}catch{continue}for(let o of r){let i=be.join(n,o.name);if(!(n===s&&Bd.has(o.name))){if(o.isDirectory()){t.push(i);continue}if(o.isFile())try{let a=await ae.stat(i);e.set(be.relative(s,i),{size:a.size,mtimeMs:a.mtimeMs})}catch{continue}}}}return e}var As=class{kind=Po;capabilities(){return{cheapWorkspaces:!1,sharedHistory:!1,nonMutatingCapture:!0,conflictReporting:!1,locking:!1,requiresServer:!1,supports:{record:!1,integrate:!1,captureWorkingState:!1,changedPaths:!1,environmentNotes:!0,rematerialize:!1,nestedTrees:!1}}}async materializeNested(){return{ok:!0,count:0}}async retainSnapshot(){}async dropSnapshotRef(){}async rematerialize(e){return{ok:!1,reason:`copy provider retains nothing outside ${e.path}; it cannot be rebuilt`}}async createWorkspace(e){if(e.from!==void 0)return{ok:!1,reason:"copy provider cannot create from a snapshot; it records none"};let t=be.resolve(e.sourceCwd),n=e.contentFrom!==void 0?be.resolve(e.contentFrom):t;try{n=await ae.realpath(n)}catch{}try{if(!(await ae.stat(n)).isDirectory())return{ok:!1,reason:`${n} is not a directory`}}catch{return{ok:!1,reason:`${n} does not exist`}}let r=Yt(t);try{await ae.mkdir(r,{recursive:!0})}catch(u){return{ok:!1,reason:`could not create workspace root: ${String(u)}`}}let o=await Ss(Is(e.label),async u=>ae.access(be.join(r,u)).then(()=>!1).catch(()=>!0));if(o===void 0)return{ok:!1,reason:`no free name available for "${e.label}"`};let i=be.join(r,o),a;try{a=await ae.readdir(n)}catch(u){return{ok:!1,reason:`copy failed: ${String(u)}`}}try{await ae.mkdir(i,{recursive:!0});for(let u of a)Bd.has(u)||await ae.cp(be.join(n,u),be.join(i,u),{recursive:!0,errorOnExist:!1,force:!0})}catch(u){return await ae.rm(i,{recursive:!0,force:!0}).catch(()=>{}),{ok:!1,reason:`copy failed: ${String(u)}`}}let d=await Ud(i),c={sourceCwd:t,label:o,createdAt:new Date().toISOString(),entries:Object.fromEntries(d)};return await he(En(i),c,{pretty:!1}),{ok:!0,workspace:{path:i,sourceCwd:t,label:o,provider:this.kind}}}async removeWorkspace(e,t){if(!t.force){let n=await this.status(e);if(!n.clean)throw new Error(`workspace ${e.path} has ${n.changedPaths.length} changed path(s); pass force to remove`)}await ae.rm(e.path,{recursive:!0,force:!0}),await ae.rm(En(e.path),{force:!0})}async listWorkspaces(e){let t=Yt(be.resolve(e)),n;try{n=await ae.readdir(t)}catch{return[]}let r=[];for(let o of n){if(o.endsWith(".manifest.json"))continue;let i=be.join(t,o),a=await de(En(i));a!==void 0&&r.push({path:i,sourceCwd:a.sourceCwd,label:a.label,provider:this.kind})}return r}async status(e){let t=await de(En(e.path)),n=await Ud(e.path);if(t===void 0)return{clean:!1,changedPaths:[...n.keys()].sort(),hasRecordedWork:!1};let r=[];for(let[o,i]of n){let a=t.entries[o];(a===void 0||a.size!==i.size||a.mtimeMs!==i.mtimeMs)&&r.push(o)}for(let o of Object.keys(t.entries))n.has(o)||r.push(o);return r.sort(),{clean:r.length===0,changedPaths:r,hasRecordedWork:!1}}async statusReport(e){let{changedPaths:t}=await this.status(e),n=t.length===0?["no changes since this copy was made"]:[`${t.length} changed file(s) since this copy was made:`,...It(t.map(r=>` ${r}`))];return n.push(`Not tracking ${$(e.sourceCwd)}: a copied directory has no shared history, so there is nothing to be in or out of sync with.`),n}async environmentNotes(e){return[`This directory is an isolated copy of ${e.sourceCwd}. It is not under version control: there is no history, no branches, and version-control commands will not behave as they would in the original.`,"Changes here are not automatically returned to the original directory."]}async captureWorkingState(){throw new Fe(this.kind,"captureWorkingState")}async record(){throw new Fe(this.kind,"record")}async attributeOrphan(e){let t=await de(En(e));if(t?.sourceCwd!==void 0)return{path:e,sourceCwd:t.sourceCwd,label:t.label??be.basename(e),provider:this.kind}}async discardLine(){return{ok:!0,dropped:0}}ownsLine(){return!1}async pruneStale(){}async changedPaths(){throw new Fe(this.kind,"changedPaths")}async integrate(){return{ok:!1,conflicts:[],declined:!0,reason:`the "${this.kind}" provider keeps no history, so there is nothing to integrate from`}}async currentState(){}async contentId(){}async currentLineName(){}async resolveRoot(e){return e}async resolveRetained(){}async contains(){return!1}async divergence(){}async changedPathsBetween(){return[]}async captureDelta(){throw new Fe(this.kind,"captureDelta")}async applyDelta(){return{ok:!1,reason:`the "${this.kind}" provider cannot reproduce a captured change`}}async resetTo(){return{ok:!1,reason:`the "${this.kind}" provider records no state to return to`}}async integrationInProgress(){return!1}async abortIntegration(){}async conflictedPaths(){return[]}async listNested(){return[]}async captureNested(){return[]}async reproduceNested(){return{applied:[],failed:[]}}async integrateNested(){return{applied:[],failed:[]}}async lock(){throw new Fe(this.kind,"lock")}async unlock(){throw new Fe(this.kind,"unlock")}};K();import{execFile as Vd}from"child_process";import{randomBytes as xh}from"crypto";import*as Ne from"fs/promises";import*as Gd from"os";import*as X from"path";function Ah(s){let e=s.indexOf(" ");return e===-1?{key:s,value:""}:{key:s.slice(0,e),value:s.slice(e+1)}}function Wd(s){let e=[],t,n=()=>{t!==void 0&&(e.push(t),t=void 0)};for(let r of s.split(`
126
+ `)){let o=r.replace(/\r$/,"");if(o.length===0){n();continue}let{key:i,value:a}=Ah(o);if(i==="worktree"){n(),t={path:a,bare:!1,detached:!1};continue}if(t!==void 0)switch(i){case"HEAD":t.head=a;break;case"branch":t.branch=a;break;case"bare":t.bare=!0;break;case"detached":t.detached=!0;break;case"locked":t.lockedReason=a;break;case"prunable":t.prunableReason=a;break;default:break}}return n(),e}function qd(s){if(s===void 0)return;let e="refs/heads/";return s.startsWith(e)?s.slice(e.length):s}var xs="git",zd="hydra-acp:",Mo="hydra",J=5e3,pe=12e4,Cs=9e5;function Jd(s){return Ne.access(s).then(()=>!0).catch(()=>!1)}function Tn(s){return s.length===0?s:X.normalize(s)}function Eh(s){return Ne.realpath(s).catch(()=>s)}function j(s,e,t,n){return new Promise(r=>{Vd("git",s,{cwd:e,timeout:t,maxBuffer:8*1024*1024,...n?{env:{...process.env,...n}}:{}},(o,i,a)=>{r({ok:!o,stdout:i??"",stderr:a??""})})})}function _o(s,e,t,n=pe){return new Promise(r=>{let o=Vd("git",s,{cwd:e,timeout:n,maxBuffer:67108864},(i,a,d)=>{r({ok:!i,stdout:a??"",stderr:d??""})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}function $o(s){let e=[];for(let t of s.split(`
127
+ `)){let n=t.replace(/\r$/,"");if(n.length<4)continue;let r=n.slice(3),o=r.indexOf(" -> ");e.push({code:n.slice(0,2),path:o===-1?r:r.slice(o+4)})}return e}var Rs=class{kind=xs;refRoot(e){return e.vcs?.repoRoot??e.sourceCwd}ownsLine(e){return e.startsWith(`${Mo}/`)}capabilities(){return{cheapWorkspaces:!0,sharedHistory:!0,nonMutatingCapture:!0,conflictReporting:!0,locking:!0,requiresServer:!1,supports:{record:!0,integrate:!0,captureWorkingState:!0,changedPaths:!1,environmentNotes:!0,rematerialize:!0,nestedTrees:!0}}}async materializeNested(e,t){if(!await Jd(X.join(e.path,".gitmodules")))return{ok:!0,count:0};let r=await j(["submodule","update","--init","--recursive",...t?.discardLocal===!0?["--force"]:[]],e.path,Cs);if(!r.ok)return{ok:!1,count:0,reason:r.stderr.trim()||"git submodule update --init failed"};if(t?.discardLocal===!0){let a=await j(["submodule","foreach","--recursive","git","reset","--hard"],e.path,Cs);if(!a.ok)return{ok:!1,count:0,reason:a.stderr.trim()||"could not reset submodules"};let d=t.purgeIgnored===!0?"-ffdx":"-fd",c=await j(["submodule","foreach","--recursive","git","clean",d],e.path,Cs);if(!c.ok)return{ok:!1,count:0,reason:c.stderr.trim()||"could not clean submodules"}}let o=await j(["submodule","status","--recursive"],e.path,J);return{ok:!0,count:o.ok?o.stdout.split(`
128
+ `).filter(a=>a.trim().length>0).length:0}}async rematerialize(e){let t=e.vcs?.branch;if(t===void 0)return{ok:!1,reason:"workspace has no recorded branch to restore from"};let n=this.refRoot(e);if(!await Jd(n))return{ok:!1,reason:`source repository ${n} no longer exists`};let r=await j(["rev-parse","--verify","--quiet",`refs/heads/${t}`],n,J);if(!r.ok||r.stdout.trim().length===0)return{ok:!1,reason:`branch ${t} no longer exists in ${n}`};await j(["worktree","unlock",e.path],n,J),await j(["worktree","prune"],n,J);let o=await j(["worktree","add",e.path,t],n,pe);return o.ok?{ok:!0,workspace:{...e,line:t,vcs:{...e.vcs??{},kind:"git",branch:t,repoRoot:n}}}:{ok:!1,reason:`could not restore worktree: ${o.stderr.trim()||"unknown error"}`}}async createWorkspace(e){let t=X.resolve(e.sourceCwd),n=await j(["rev-parse","--show-toplevel"],t,J);if(!n.ok)return{ok:!1,reason:`${t} is not a git repository (or git is unavailable)`};let r=Tn(n.stdout.trim());if(r.length===0)return{ok:!1,reason:`could not resolve the repository root for ${t}`};let o=await j(["rev-parse","HEAD"],r,J);if(!o.ok)return{ok:!1,reason:`${r} has no commits yet, so there is nothing to branch from`};let i=e.from??o.stdout.trim(),a=Is(e.label),d=Yt(t);try{await Ne.mkdir(d,{recursive:!0})}catch(f){return{ok:!1,reason:`could not create workspace root: ${String(f)}`}}let c=await Ss(a,async f=>await Ne.access(X.join(d,f)).then(()=>!0).catch(()=>!1)?!1:!(await j(["rev-parse","--verify","--quiet",`refs/heads/${Mo}/${f}`],r,J)).ok);if(c===void 0)return{ok:!1,reason:`no free name available for "${a}"`};let u=X.join(d,c),l=`${Mo}/${c}`,p=await j(["worktree","add","--no-track","-b",l,u,i],r,pe);return p.ok?{ok:!0,workspace:{path:u,sourceCwd:t,label:c,provider:this.kind,snapshot:i,line:l,vcs:{kind:"git",branch:l,base:i,repoRoot:r}}}:{ok:!1,reason:`git worktree add failed: ${p.stderr.trim()||"unknown error"}`}}async removeWorkspace(e,t){if(!t.force){let o=await this.status(e);if(!o.clean)throw new Error(`workspace ${e.path} has ${o.changedPaths.length} changed path(s)${o.hasRecordedWork?" and unintegrated recorded work":""}; pass force to remove`)}let n=this.refRoot(e);await this.unlock(e).catch(()=>{});let r=await j(["worktree","remove","--force",e.path],n,pe);t.discardLine===!0&&e.vcs?.branch!==void 0&&await j(["branch","-D",e.vcs.branch],n,J),r.ok||(await Ne.rm(e.path,{recursive:!0,force:!0}),await j(["worktree","prune"],n,J))}async listWorkspaces(e){let t=X.resolve(e),n=await j(["rev-parse","--show-toplevel"],t,J);if(!n.ok)return[];let r=Tn(n.stdout.trim()),o=await j(["worktree","list","--porcelain"],r,J);if(!o.ok)return[];let i=Yt(t),a=await Eh(i),d=[];for(let c of Wd(o.stdout)){let u=Tn(c.path),l=X.dirname(u);if(l!==i&&l!==a)continue;let p=X.join(i,X.basename(u)),f={kind:"git",repoRoot:r},h=qd(c.branch);h!==void 0&&(f.branch=h),c.head!==void 0&&(f.head=c.head),c.lockedReason!==void 0&&(f.locked=c.lockedReason);let w=c.lockedReason?.startsWith(zd)===!0;d.push({path:p,sourceCwd:t,label:X.basename(p),...w?{heldByUs:!0}:{},provider:this.kind,...h!==void 0?{line:h}:{},vcs:f})}return d}async status(e){let t=await j(["status","--porcelain","--untracked-files=all"],e.path,J);if(!t.ok)return{clean:!1,changedPaths:[],hasRecordedWork:!1};let n=$o(t.stdout),r=n.map(a=>a.path),o=n.some(({code:a})=>a!=="??"&&a[0]!==" "&&a[0]!=="?"),i=!1;if(e.snapshot!==void 0){let a=await j(["rev-list","--count",`${e.snapshot}..HEAD`],e.path,J);a.ok&&(i=Number.parseInt(a.stdout.trim(),10)>0)}return{clean:r.length===0&&!i,changedPaths:r,hasRecordedWork:i,hasStagedWork:o}}async lock(e,t){let n=this.refRoot(e);await j(["worktree","lock","--reason",`${zd}${t}`,e.path],n,J)}async unlock(e){let t=this.refRoot(e);await j(["worktree","unlock",e.path],t,J)}async environmentNotes(e){let t=[],n=e.vcs?.branch;return t.push(`This directory is a git worktree of ${e.sourceCwd}${n!==void 0?`, on branch ${n}`:""}. Do not read or write ${e.sourceCwd} directly; paths under it refer to the corresponding file here. Prefer repo-relative paths, which are identical in both.`),t.push("`.git` here is a file, not a directory. That is normal for a worktree and does not need repairing."),await Ne.access(X.join(e.path,".gitmodules")).then(()=>!0).catch(()=>!1)&&t.push("Submodules here are initialized and checked out at the commits this tree records, which means each sits on a detached HEAD. That is normal and does not need repairing. Never re-add a submodule's contents as ordinary tracked files in the superproject: that silently corrupts the integration back to the source branch."),t}async statusReport(e){let t=[],n=await j(["status","--porcelain","--untracked-files=all"],e.path,J);if(n.ok){let r=$o(n.stdout);if(r.length===0)t.push("no uncommitted changes");else{let o=0,i=0,a=0;for(let{code:c}of r){if(c==="??"){a+=1;continue}c[0]!==" "&&c[0]!=="?"&&(o+=1),c[1]!==" "&&c[1]!=="?"&&(i+=1)}let d=[];o>0&&d.push(`${o} staged`),i>0&&d.push(`${i} unstaged`),a>0&&d.push(`${a} untracked`),t.push(`${d.join(", ")}:`),t.push(...It(r.map(c=>` ${c.code} ${c.path}`)))}}return t.push(...await this.syncLines(e)),t}async syncLines(e){if(e.vcs?.branch===void 0)return[];let[t,n]=await Promise.all([j(["rev-parse","HEAD"],e.sourceCwd,J),j(["rev-parse","HEAD"],e.path,J)]),r=t.stdout.trim(),o=n.stdout.trim();if(!t.ok||!n.ok||r.length===0||o.length===0)return[];let i=$(e.sourceCwd);if(r===o)return[`in sync with ${i}`];let a=await j(["rev-list","--left-right","--count",`${r}...${o}`],e.path,J),d=a.stdout.trim().split(/\s+/).map(p=>Number.parseInt(p,10)),c=d[0],u=d[1];if(!a.ok||c===void 0||u===void 0||!Number.isFinite(c)||!Number.isFinite(u))return[];let l=[];return c>0&&l.push(`${c} commit(s) behind ${i}. \`/hydra workspace sync\` brings them in; landing is fast-forward-only, so this also unblocks \`stop\`.`),u>0&&l.push(`${u} commit(s) recorded here and not landed yet.`),l}async captureWorkingState(e,t){let n=X.join(Gd.tmpdir(),`hydra-index-${process.pid}-${xh(6).toString("hex")}`),r={GIT_INDEX_FILE:n};try{let o=await j(["rev-parse","--verify","HEAD"],e,J),i=o.ok&&o.stdout.trim().length>0;if(i){let l=await j(["read-tree","HEAD"],e,pe,r);if(!l.ok)throw new Error(`could not seed the snapshot index: ${l.stderr.trim()}`)}let a=await j(["add","-A"],e,pe,r);if(!a.ok)throw new Error(`could not stage working state: ${a.stderr.trim()}`);let d=await j(["write-tree"],e,pe,r);if(!d.ok||d.stdout.trim().length===0)throw new Error(`could not write tree: ${d.stderr.trim()}`);let c=["commit-tree",d.stdout.trim(),"-m",t];i&&c.push("-p",o.stdout.trim());let u=await j(c,e,pe,r);if(!u.ok||u.stdout.trim().length===0)throw new Error(`could not create snapshot commit: ${u.stderr.trim()}`);return u.stdout.trim()}finally{await Ne.rm(n,{force:!0}).catch(()=>{})}}async retainSnapshot(e,t,n){let r=this.refRoot(e);await j(["update-ref","--create-reflog",t,n],r,J)}async dropSnapshotRef(e,t){let n=this.refRoot(e);await j(["update-ref","-d",t],n,J)}async currentState(e){let t=await j(["rev-parse","HEAD"],e,J),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async contentId(e,t){let n=await j(["rev-parse",`${t}^{tree}`],e,J),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async currentLineName(e){let t=await j(["rev-parse","--abbrev-ref","HEAD"],e,J),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async resolveRoot(e){let t=await j(["rev-parse","--show-toplevel"],e,J),n=Tn(t.stdout.trim());return t.ok&&n.length>0?n:void 0}async resolveRetained(e,t){let n=await j(["rev-parse","--verify","--quiet",`${t}^{commit}`],this.refRoot(e),J),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async contains(e,t){return(await j(["merge-base","--is-ancestor",t.state,t.within],e,J)).ok}async divergence(e,t,n){let r=await j(["rev-list","--left-right","--count",`${t}...${n}`],e,J);if(!r.ok)return;let o=r.stdout.trim().split(/\s+/).map(d=>Number.parseInt(d,10)),i=o[0],a=o[1];if(!(i===void 0||a===void 0||!Number.isFinite(i)||!Number.isFinite(a)))return{ahead:i,behind:a}}async changedPathsBetween(e,t,n){let r=await j(["diff","--name-only",t,n],e,J);return r.ok?r.stdout.split(`
129
+ `).map(o=>o.replace(/\r$/,"").trim()).filter(o=>o.length>0):[]}async captureDelta(e,t,n){let r=await j(["diff","--binary","--ignore-submodules=all",t,n],e,pe);if(r.ok)return r.stdout}async applyDelta(e,t,n){if(t.trim().length===0)return{ok:!0,alreadyPresent:!0};let r=n?.stage===!0?["--index"]:[],o=await _o(["apply",...r],e,t);if(o.ok)return{ok:!0};if(n?.tolerant!==!0)return{ok:!1,reason:o.stderr.trim()||"the change did not apply"};if((await _o(["apply","--reverse","--check"],e,t)).ok)return{ok:!0,alreadyPresent:!0};let a=await _o(["apply","--3way"],e,t);return a.ok?{ok:!0}:{ok:!1,reason:a.stderr.trim()||"the change overlaps what is already there"}}async resetTo(e,t,n){let r=await j(["reset","--hard",t],e,pe);if(!r.ok)return{ok:!1,reason:r.stderr.trim()||"could not return to that state"};let o=await j(["clean",n?.purgeIgnored===!0?"-ffdx":"-fd"],e,pe);if(!o.ok)return{ok:!1,reason:o.stderr.trim()||"returned to that state but could not remove extra files"};let i=await this.materializeNested({path:e,sourceCwd:e,label:"",provider:this.kind},{discardLocal:!0,...n?.purgeIgnored===!0?{purgeIgnored:!0}:{}});return i.ok?{ok:!0}:{ok:!1,reason:i.reason??"could not reset nested trees"}}async integrationInProgress(e){return(await j(["rev-parse","-q","--verify","MERGE_HEAD"],e,J)).ok}async abortIntegration(e){await j(["merge","--abort"],e,pe)}async conflictedPaths(e){let t=await j(["diff","--name-only","--diff-filter=U"],e,J);return t.ok?t.stdout.split(`
130
+ `).map(n=>n.replace(/\r$/,"").trim()).filter(n=>n.length>0):[]}async record(e,t){let n=await j(["add","-A"],e.path,pe);if(!n.ok)throw new Error(`could not stage ${e.path}: ${n.stderr.trim()||"unknown error"}`);let r=await this.status(e),o=await this.currentState(e.path);if(r.changedPaths.length===0){if(o===void 0)throw new Error(`could not read the state of ${e.path}`);return o}let i=await j(["commit","-m",t],e.path,pe);if(!i.ok)throw new Error(`could not record ${e.path}: ${i.stderr.trim()||i.stdout.trim()||"unknown error"}`);let a=await this.currentState(e.path);if(a===void 0)throw new Error(`recorded ${e.path} but could not read the resulting state`);return a}async attributeOrphan(e){let t=await j(["rev-parse","--path-format=absolute","--git-common-dir"],e,J),n=Tn(t.stdout.trim());if(!t.ok||n.length===0)return;let r=X.dirname(n),o=await this.currentLineName(e);return{path:e,sourceCwd:r,label:X.basename(e),provider:this.kind,...o!==void 0?{line:o}:{},vcs:{repoRoot:r,...o!==void 0?{branch:o}:{}}}}async discardLine(e,t){let n=this.refRoot(e),o=(await this.divergence(n,"HEAD",t))?.behind??0,i=await j(["branch","-D",t],n,J);return i.ok?{ok:!0,dropped:o}:{ok:!1,dropped:o,reason:i.stderr.trim()||"could not discard the line"}}async pruneStale(e){await j(["worktree","prune"],this.refRoot(e),J)}async changedPaths(){throw new Fe(this.kind,"changedPaths")}async integrate(e){let{into:t,from:n}=e,r=await this.currentState(t);if(r===void 0)return{ok:!1,conflicts:[],declined:!0,reason:`cannot read the state of ${t}`};if(await this.contains(t,{state:n,within:r}))return{ok:!0,snapshot:r,alreadyUpToDate:!0};if(e.fastForwardOnly===!0&&!await this.contains(t,{state:r,within:n}))return{ok:!1,conflicts:[],declined:!0,reason:`${t} cannot simply advance to that state; it has moved on independently`};let o=e.fastForwardOnly===!0?["merge","--ff-only",n]:["merge","--no-edit","-m",e.message??"hydra: integrate",n],i=await j(o,t,pe);if(i.ok){let c=await this.currentState(t);return c===void 0?{ok:!1,conflicts:[],reason:"integrated but could not read the resulting state"}:{ok:!0,snapshot:c}}let a=await this.conflictedPaths(t),d=await this.integrationInProgress(t);return a.length===0&&!d?{ok:!1,conflicts:[],declined:!0,reason:i.stderr.trim()||"the integration was refused"}:(e.onConflict==="abort"&&await this.abortIntegration(t),{ok:!1,conflicts:a})}async listNested(e){let t=await j(["submodule","status","--recursive"],e,pe);if(!t.ok)return[];let n=[];for(let r of t.stdout.split(`
131
+ `)){let o=r.replace(/\r$/,"");if(o.trim().length===0||(o[0]??" ")==="-")continue;let a=o.slice(1),d=a.indexOf(" ");if(d<=0)continue;let c=a.slice(d+1).replace(/\s+\(.*\)\s*$/,"").trim();if(c.length===0||!Th(e,c))continue;let u=X.join(e,c),[l,p,f]=await Promise.all([this.currentState(u),j(["rev-parse",`HEAD:${c}`],e,J),j(["status","--porcelain","--untracked-files=all"],u,J)]);if(l===void 0)continue;let h=p.ok?p.stdout.trim():"";n.push({relPath:c,actual:l,...h.length>0?{recorded:h}:{},changedPaths:f.ok?$o(f.stdout).map(w=>w.path):[]})}return n}async captureNested(e,t){let n=[];for(let r of t){if(!Eo(r))continue;if(r.changedPaths.length===0){n.push(r);continue}let o=X.join(e,r.relPath),i=await this.captureWorkingState(o,"hydra: nested work carried into workspace").catch(()=>{});if(i===void 0){n.push(r);continue}let a=await this.captureDelta(o,r.actual,i);n.push(a===void 0?r:{...r,delta:a})}return n}async reproduceNested(e,t,n){let r=[],o=[];for(let i of n){let a=X.join(e,i.relPath),d=X.join(t,i.relPath),c=await this.alignNested(a,d,i.actual);if(c!==void 0){o.push({path:i.relPath,reason:c});continue}if(i.delta!==void 0){let u=await this.applyDelta(a,i.delta);if(!u.ok){o.push({path:i.relPath,reason:u.reason??"changes did not apply"});continue}}r.push(i.relPath)}return{applied:r,failed:o}}async integrateNested(e,t,n){let r=[],o=[],i=new Map(n.map(c=>[c.relPath,c])),a=await this.listNested(e),d=new Set([...a.map(c=>c.relPath),...i.keys()]);for(let c of[...d].sort()){let u=a.find(m=>m.relPath===c),l=i.get(c);if(u===void 0){o.push({path:c,reason:"not populated in the receiving tree"});continue}let p=u.recorded!==void 0&&u.recorded!==u.actual,f=l?.delta!==void 0;if(!p&&!f)continue;if(u.changedPaths.length>0){o.push({path:c,reason:`it has ${u.changedPaths.length} uncommitted change(s) of its own, and nothing can tell those apart from what was integrated`});continue}let h=X.join(e,c),w=X.join(t,c);if(p&&u.recorded!==void 0){let m=await this.alignNested(h,w,u.recorded);if(m!==void 0){o.push({path:c,reason:m});continue}}if(l?.delta!==void 0){let m=await this.applyDelta(h,l.delta);if(!m.ok){o.push({path:c,reason:m.reason??"the uncommitted changes there did not apply"});continue}}r.push(c)}return{applied:r,failed:o}}async alignNested(e,t,n){let r=await this.currentState(e);if(r===void 0)return"not populated here";if(r===n)return;if(!(await j(["cat-file","-e",`${n}^{commit}`],e,J)).ok&&!(await j(["fetch","--no-tags",t,n],e,Cs)).ok)return`could not transfer ${n.slice(0,8)} from the other copy`;if(!(await j(["checkout","--detach",n],e,pe)).ok)return`could not move to ${n.slice(0,8)}`}};function Th(s,e){if(X.isAbsolute(e))return!1;let t=X.resolve(s),n=X.resolve(t,e);return n!==t&&n.startsWith(t+X.sep)}var Ph=xs,Mh=new Map([[xs,new Rs],[Po,new As]]);function re(s){return Mh.get(s??Ph)}var Es="refs/hydra";function Xt(s){let e=`${Es}/workspaces/${s}`;return{autosave:`${e}/autosave`,start:`${e}/start`,baseline:`${e}/baseline`}}function Oo(s){return`${Es}/landing/${s}`}function Kd(s){return`${Es}/sync/${s}`}function Qd(s,e){return`${Es}/retired/${s}-${e.slice(0,12)}`}function Yd(s){let e=Xt(s);return[e.autosave,e.start,e.baseline]}async function Fo(s){let{source:e,ws:t,startSnapshotRef:n,baselineRef:r,retainRef:o,provider:i}=s;if(i===void 0)throw new Error("no provider available to inspect the source tree");let a=await i.status({...t,path:e}).catch(()=>{}),d="";for(let l of[r,n]){if(l===void 0)continue;let p=await i.resolveRetained(t,l).catch(()=>{});if(p!==void 0){d=p;break}}let c=a===void 0||a.changedPaths.length>0;if(d.length===0){if(c)throw new Error(`${e} has uncommitted changes but this workspace has no start anchor, so its copy of your work cannot be told apart from edits you made since. Refusing rather than reporting a conflict that is not yours. Commit or stash the source, then retry.`);d=await i.currentState(e).catch(()=>{})??""}if(!c)return{clean:!0,base:d};if(i.capabilities().supports.captureWorkingState!==!0)throw new Error(`${e} has uncommitted changes and this provider cannot snapshot them, so they cannot be preserved across the landing. Commit or stash them first.`);let u=await i.captureWorkingState(e,"hydra: source state before landing").catch(()=>{});if(u===void 0)throw new Error(`could not snapshot the uncommitted changes in ${e}, so refusing to touch them`);return await i.retainSnapshot({...t,path:e},o,u),{clean:!1,snapshot:u,base:d,retainedRef:o}}async function At(s){let{source:e,capture:t,provider:n}=s;if(t.clean||t.snapshot===void 0||n===void 0)return!0;let r=await n.captureDelta(e,t.base,t.snapshot).catch(()=>{});return r===void 0?!1:(await n.applyDelta(e,r,{tolerant:!0})).ok}async function Pn(s){s.capture.retainedRef===void 0||s.provider===void 0||await s.provider.dropSnapshotRef({...s.ws,path:s.source},s.capture.retainedRef).catch(()=>{})}je();import{exec as _h}from"child_process";import*as Ke from"fs/promises";import*as Ee from"path";var $h=".hydra/worktree.json",Oh=".worktreeinclude",Fh=120;async function Ts(s){let e=await de(Ee.join(s,$h))??{},t=new Set(Array.isArray(e.carry)?e.carry:[]),n=await Ke.readFile(Ee.join(s,Oh),"utf8").catch(()=>{});if(n!==void 0)for(let o of n.split(`
132
+ `)){let i=o.trim();i.length===0||i.startsWith("#")||i.startsWith("!")||i.includes("*")||i.includes("?")||t.add(i)}let r={};return t.size>0&&(r.carry=[...t]),typeof e.postCreate=="string"&&(r.postCreate=e.postCreate),typeof e.preRemove=="string"&&(r.preRemove=e.preRemove),typeof e.hookTimeoutSeconds=="number"&&(r.hookTimeoutSeconds=e.hookTimeoutSeconds),r}async function No(s,e,t){let n=[],r=[],o=Ee.resolve(s),i=Ee.resolve(e);for(let a of t){let d=Ee.resolve(o,a),c=Ee.resolve(i,a);if(!d.startsWith(o+Ee.sep)||!c.startsWith(i+Ee.sep)){r.push(a);continue}if(await Ke.access(c).then(()=>!0).catch(()=>!1)){r.push(a);continue}let l=await Ke.stat(d).catch(()=>{});if(l===void 0){r.push(a);continue}try{await Ke.mkdir(Ee.dirname(c),{recursive:!0}),await Ke.cp(d,c,{recursive:l.isDirectory(),dereference:!0}),n.push(a)}catch{r.push(a)}}return{copied:n,skipped:r}}async function Ps(s,e){let t=JSON.stringify({path:e.workspacePath,sourceCwd:e.sourceCwd,label:e.label,...e.sessionId!==void 0?{sessionId:e.sessionId}:{}}),n=(e.timeoutSeconds??Fh)*1e3;return new Promise(r=>{let o=_h(s,{cwd:e.workspacePath,timeout:n,maxBuffer:8388608,windowsHide:!0,env:{...process.env,HYDRA_WORKSPACE_PATH:e.workspacePath,HYDRA_SOURCE_CWD:e.sourceCwd,HYDRA_WORKSPACE_LABEL:e.label,...e.sessionId!==void 0?{HYDRA_SESSION_ID:e.sessionId}:{}}},(i,a,d)=>{if(i){let c=(d||i.message||"").trim().slice(0,500);r({ok:!1,reason:c.length>0?c:"hook failed"});return}r({ok:!0})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}K();je();import*as tt from"fs/promises";import{z as De}from"zod";var Nh=De.object({version:De.literal(1),agentId:De.string(),upstreamSessionId:De.string(),sessionId:De.string().optional(),deletedAt:De.string(),upstreamUpdatedAt:De.string().optional(),cwd:De.string().optional(),title:De.string().optional(),reason:De.enum(["user","expired"]).optional(),interactive:De.boolean().optional()}),Ms=class{async add(e){let t={version:1,...e};await he(E.tombstoneFile(e.agentId,e.upstreamSessionId),t,{mode:384})}async has(e,t){try{return await tt.access(E.tombstoneFile(e,t)),!0}catch{return!1}}async read(e,t){let n=E.tombstoneFile(e,t),r=await de(n);if(r===void 0)return await this.has(e,t)?{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}:void 0;try{return Nh.parse(r)}catch{return{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}}}async remove(e,t){try{await tt.unlink(E.tombstoneFile(e,t))}catch(n){if(n.code!=="ENOENT")throw n}try{await tt.rmdir(E.tombstoneAgentDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}}async list(e){if(e!==void 0)return this.listForAgent(e);let t;try{t=await tt.readdir(E.tombstonesDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}n.push(...await this.listForAgent(o))}return n}async listForAgent(e){let t;try{t=await tt.readdir(E.tombstoneAgentDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}let i=await this.read(e,o);i&&n.push(i)}return n}};function Xd(s,e){return s.reason==="user"||e===void 0?!1:s.upstreamUpdatedAt===void 0?!0:e>s.upstreamUpdatedAt}import*as fc from"fs/promises";import{customAlphabet as Jh}from"nanoid";import{fileURLToPath as Dh}from"url";import*as Mn from"path";import*as _s from"fs";function jh(){try{let s=Mn.dirname(Dh(import.meta.url));for(let e=0;e<8;e+=1){let t=Mn.join(s,"package.json");if(_s.existsSync(t)){let r=JSON.parse(_s.readFileSync(t,"utf8"));if(typeof r.version=="string"&&r.version.length>0&&(typeof r.name!="string"||r.name.includes("hydra-acp")))return r.version}let n=Mn.dirname(s);if(n===s)break;s=n}}catch{}return"0.0.0"}var ue=jh(),$s="hydra-acp-cat";var Hh=12e4;async function ec(s,e,t){let n=s.timeoutMs??Hh,r,o,i=!1;try{let a=(async()=>{r=dt.spawn({agentId:s.agentId,cwd:s.cwd,plan:s.plan,logger:s.logger});let d=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:{name:"hydra-synopsis",version:ue}}),c=await r.connection.request("session/new",{cwd:s.cwd,mcpServers:[]}),u=c.sessionId;if(typeof u!="string"){s.logger?.warn(`synopsis: agent ${s.agentId} returned non-string sessionId from session/new`),s.onFailure?.(`agent ${s.agentId} did not return a sessionId from session/new`);return}if(s.onWorkerSpawned?.(u,r.pid),s.modelId){let h=Uh(c);if(h.size===0||h.has(s.modelId)){let w=r.connection;try{await ct({request:(m,g)=>w.request(m,g),sessionId:u,modelId:s.modelId,verb:Ut(c),logger:s.logger})}catch(m){s.logger?.warn(`synopsis: agent ${s.agentId} rejected model change to ${JSON.stringify(s.modelId)}: ${m.message}; continuing on default`)}}else s.logger?.warn(`synopsis: model ${JSON.stringify(s.modelId)} not advertised by agent ${s.agentId} (have [${[...h].join(", ")}]); continuing on default`)}let l=[];r.connection.onNotification("session/update",h=>{let w=Lh(h);w.length>0&&l.push(w)}),await r.connection.request("session/prompt",{sessionId:u,prompt:[{type:"text",text:e}]});let p=l.join(""),f=t(p);if(!f){let h=JSON.stringify(p.slice(0,200));s.logger?.warn(`synopsis: agent ${s.agentId} reply did not parse (replyLen=${p.length} preview=${h})`);let w=p.slice(0,120).replace(/\s+/g," ").trim();s.onFailure?.(`agent ${s.agentId} returned unparseable JSON (${p.length} chars): ${w}${p.length>120?"\u2026":""}`)}return f})();return await new Promise((d,c)=>{o=setTimeout(()=>{i=!0,s.logger?.warn(`synopsis: agent ${s.agentId} timed out after ${n}ms`),s.onFailure?.(`agent ${s.agentId} timed out after ${n}ms`),d(void 0)},n),o.unref?.(),a.then(u=>{o&&clearTimeout(o),i||d(u)},u=>{o&&clearTimeout(o),i||c(u)})})}catch(a){let d=a.message;s.logger?.warn(`synopsis: agent ${s.agentId} failed: ${d}`),s.onFailure?.(`agent ${s.agentId} failed: ${d}`);return}finally{o&&clearTimeout(o),r&&await r.kill().catch(()=>{})}}async function Os(s){let e=Vt(s.history,{maxChars:s.maxTranscriptChars}),t=s.sessionId!==void 0?`[hydra-acp title-regen worker for session ${s.sessionId}]`:"[hydra-acp title-regen worker]",n=e.length>0?`${t}
133
133
 
134
134
  ${e}
135
135
 
136
136
  ${bo}`:`${t}
137
137
 
138
- ${bo}`;return ec(s,n,Hd)}async function tc(s){let e=Vt(s.history,{maxChars:s.maxTranscriptChars}),t=s.sessionId!==void 0?`[hydra-acp compaction worker for session ${s.sessionId}]`:"[hydra-acp compaction worker]",n=e.length>0?`${t}
138
+ ${bo}`;return ec(s,n,jd)}async function tc(s){let e=Vt(s.history,{maxChars:s.maxTranscriptChars}),t=s.sessionId!==void 0?`[hydra-acp compaction worker for session ${s.sessionId}]`:"[hydra-acp compaction worker]",n=e.length>0?`${t}
139
139
 
140
140
  ${e}
141
141
 
142
142
  ${So}`:`${t}
143
143
 
144
- ${So}`;return ec(s,n,jd)}function jh(s){if(!s||typeof s!="object")return"";let e=s.update;if(!e||typeof e!="object")return"";let t=e;if(t.sessionUpdate!=="agent_message_chunk")return"";let n=t.content;return n&&typeof n.text=="string"?n.text:""}function Lh(s){let e=new Set;Zd(e,s.availableModels);let t=s.models;return t&&typeof t=="object"&&!Array.isArray(t)&&Zd(e,t.availableModels),e}function Zd(s,e){if(Array.isArray(e)){for(let t of e)if(t&&typeof t=="object"){let n=t.modelId??t.value??t.id;typeof n=="string"&&n.length>0&&s.add(n)}}}var Uh="guardian_assessment:",Bh="Guardian Review";function nc(s,e){return s!==void 0&&s.startsWith(Uh)||e===Bh}function Wh(s){let e=new Map;for(let t of dc(s).values())e.set(t.toolName,(e.get(t.toolName)??0)+1);return[...e.entries()].map(([t,n])=>({name:t,count:n})).sort((t,n)=>n.count-t.count||t.name.localeCompare(n.name))}function oc(s){return Wh(s).map(e=>e.name)}function qh(s){let e=new Map;for(let t of dc(s).values())for(let n of t.paths){let r=e.get(n);r===void 0&&(r=new Map,e.set(n,r)),r.set(t.toolName,(r.get(t.toolName)??0)+1)}return[...e.entries()].map(([t,n])=>{let r=[...n.entries()].map(([i,a])=>({name:i,count:a})).sort((i,a)=>a.count-i.count||i.name.localeCompare(a.name)),o=r.reduce((i,a)=>i+a.count,0);return{path:t,count:o,byTool:r}}).sort((t,n)=>n.count-t.count||t.path.localeCompare(n.path))}function ic(s){return qh(s).map(e=>e.path)}function ac(s){let e=0;for(let t of s)t.params?.update?.sessionUpdate==="prompt_received"&&(e+=1);return e}function dc(s){let e=new Map,t=0;for(let n of s){let o=n.params?.update;if(!o)continue;let i=o.sessionUpdate;if(i!=="tool_call"&&i!=="tool_call_update")continue;if(i==="tool_call"){let d=typeof o.toolCallId=="string"&&o.toolCallId.length>0?o.toolCallId:void 0,c=typeof o.title=="string"?o.title:void 0;if(nc(d,c))continue;let u=d??`__synth_${t++}`,l=e.get(u);l===void 0?(l={toolName:sc(o),paths:new Set},e.set(u,l)):l.toolName=sc(o);for(let p of rc(o.rawInput,o.locations))l.paths.add(p);continue}if(typeof o.toolCallId!="string"||o.toolCallId.length===0)continue;let a=e.get(o.toolCallId);if(a!==void 0)for(let d of rc(o.rawInput,o.locations))a.paths.add(d)}return e}function sc(s){return typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function rc(s,e){let t=new Set;if(s&&typeof s=="object"&&!Array.isArray(s)){let n=s;typeof n.file_path=="string"?t.add(n.file_path):typeof n.path=="string"&&t.add(n.path);let r=n.edits;if(Array.isArray(r)){for(let o of r)if(o&&typeof o=="object"){let i=o.file_path;typeof i=="string"&&t.add(i)}}}for(let n of ja(e))t.add(n);return t}K();var Jh=zh("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",12),Vh=2,Fs=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??Vh}opts;queued={};inflight=new Map;stopped=!1;maxConcurrent;schedule(e){this.stopped||this.inflight.has(e)||e in this.queued||(this.queued[e]={kind:"title"},this.drain())}scheduleCompaction(e,t){if(this.stopped)return;let n=t?.targetAgentId;if(this.inflight.has(e))return;let r=this.queued[e];if(r&&r.kind==="title"){this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}};return}this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}},this.drain()}size(){return{queued:Object.keys(this.queued).length,inflight:this.inflight.size}}async flush(e){let t=Date.now()+e;for(;Object.keys(this.queued).length>0||this.inflight.size>0;){let n=t-Date.now();if(n<=0)return;let r=[...this.inflight.values()];if(r.length===0){await new Promise(o=>{setTimeout(o,25).unref?.()});continue}await Promise.race([Promise.race(r),new Promise(o=>{setTimeout(o,n).unref?.()})])}}async shutdown(){this.stopped=!0,this.queued={},await Promise.allSettled([...this.inflight.values()])}drain(){if(!this.stopped)for(;this.inflight.size<this.maxConcurrent&&Object.keys(this.queued).length>0;){let t=Object.keys(this.queued)[0];if(!t)return;let n=this.queued[t];delete this.queued[t];let r=this.runOne(t,n).finally(()=>{this.inflight.delete(t),this.drain()});this.inflight.set(t,r)}}async runOne(e,t){let n=t.kind,r=t.targetAgentId;try{let o=await this.opts.store.read(e);if(!o){this.opts.logger?.info(`synopsis: session ${e} record missing; skipping`);return}let i=await this.opts.histories.load(e,{maxEntries:1/0}),a=o.summarizedThroughEntry;if(a!==void 0&&i.length===a){this.opts.logger?.info(`synopsis: skip ${e} (history unchanged at ${i.length})`);return}a!==void 0&&i.length<a&&this.opts.logger?.warn(`synopsis: watermark ahead of history (last=${a} history=${i.length}) for ${e} \u2014 re-baselining`);let d=n==="compaction"?r??this.opts.compactionAgent??o.agentId:this.opts.synopsisAgent??o.agentId,c=await this.opts.registry.getAgent(d);if(!c){this.opts.logger?.warn(`synopsis: agent ${d} not in registry for session ${e}; skipping`);return}let u=await Me(c,[],{npmRegistry:this.opts.npmRegistry}),l=this.opts.compactionAgent===void 0&&r===void 0,p=n==="compaction"?this.opts.compactionModel??(l?o.currentModel:void 0):this.opts.synopsisModel,f=E.sessionDir(e);if(await fc.mkdir(f,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(p??"(default)")} cwd=${f}`),n==="compaction"){let h=this.opts.compactionMaxIterations??3,w=0,m=a??0,g,y=0,k,v=Date.now(),S=Jh(),b={targetAgentId:r},A=R=>this.opts.onCompactionStateChange?.(e,{runId:S,...R},b)??Promise.resolve(),C=R=>{this.opts.broadcastHydraCompaction?.(e,R,b)};await A({status:"requested",requestedAt:v}),C({sessionUpdate:"_hydra_compaction",phase:"started",requestedAt:v});try{do{w++,this.opts.logger?.info(`synopsis: compaction iteration ${w} sessionId=${e} historyLen=${i.length} watermark=${m}`);let R=await this.opts.histories.load(e,{maxEntries:1/0});if(R.length===m)break;let T=await tc({agentId:d,cwd:f,plan:u,history:R,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:(j,U)=>{A({status:"running",requestedAt:v,iter:w,worker:{upstreamSessionId:j,pid:U??0}})},onFailure:j=>{k=j}});if(T){let j=cc(T.synopsis,R);j&&uc(j)&&(await this.opts.persistSynopsis(e,j,R.length),g=j,y=R.length,k=void 0,await A({status:"running",requestedAt:v,iter:w}),C({sessionUpdate:"_hydra_compaction",phase:"iteration",iter:w,historyLen:R.length}),await this.opts.onSynthesisArtifact?.(e,j,y,r,S),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${w} fields=${lc(j)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${w} returned no result`);if(m=R.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===m)break}while(w<h);if(g)this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} runId=${S} watermark=${y} iterations=${w}`+(w>=h?` (hit maxIterations=${h})`:"")),C({sessionUpdate:"_hydra_compaction",phase:"converged",iter:w,summarizedThroughEntry:y});else{w>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${h} without producing artifact sessionId=${e}: ${k??"no reason captured"}`);let R=k??(w===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${w} iteration(s)`);await A({status:"failed",requestedAt:v,iter:w,lastError:R}),C({sessionUpdate:"_hydra_compaction",phase:"failed",error:R}),r&&await this.opts.onSynthesisUnavailable?.(e,r,R)}}catch(R){let T=R instanceof Error?R.message:String(R);if(this.opts.logger?.warn(`synopsis: compaction threw for sessionId=${e}: ${T}`),await A({status:"failed",requestedAt:v,iter:w,lastError:T}),this.opts.broadcastHydraCompaction?.(e,{sessionUpdate:"_hydra_compaction",phase:"failed",error:T},{targetAgentId:r}),r)try{await this.opts.onSynthesisUnavailable?.(e,r,T)}catch{}}}else{let h=await Os({agentId:d,cwd:f,plan:u,history:i,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs});if(!h){this.opts.logger?.warn(`synopsis: sessionId=${e} no parseable result; not persisting`);return}let w=cc(h.synopsis,i);w&&uc(w)?(await this.opts.persistSynopsis(e,w,i.length),h.title&&await this.opts.persistTitle(e,h.title),this.opts.logger?.info(`synopsis: persisted sessionId=${e} title=${JSON.stringify(!!h.title)} fields=${lc(w)}`)):h.title&&(await this.opts.persistTitle(e,h.title),this.opts.logger?.info(`synopsis: persisted title only sessionId=${e}`))}}catch(o){this.opts.logger?.warn(`synopsis: sessionId=${e} failed: ${o.message}`)}}};function cc(s,e){let t=ic(e),n=oc(e);return s?{...s,files_touched:t.length>0?t:s.files_touched,tools_used:n.length>0?n:s.tools_used}:t.length===0&&n.length===0?void 0:{files_touched:t.length>0?t:void 0,tools_used:n.length>0?n:void 0}}function uc(s){return!!(s.goal&&s.goal.trim().length>0||s.outcome&&s.outcome.trim().length>0||s.files_touched&&s.files_touched.length>0||s.tools_used&&s.tools_used.length>0||s.rejected_approaches&&s.rejected_approaches.length>0||s.open_threads&&s.open_threads.length>0)}function lc(s){let e=[];return s.goal&&e.push("goal"),s.outcome&&e.push("outcome"),s.files_touched&&s.files_touched.length>0&&e.push(`files=${s.files_touched.length}`),s.tools_used&&s.tools_used.length>0&&e.push(`tools=${s.tools_used.length}`),s.rejected_approaches&&s.rejected_approaches.length>0&&e.push(`rejected=${s.rejected_approaches.length}`),s.open_threads&&s.open_threads.length>0&&e.push(`open=${s.open_threads.length}`),`[${e.join(",")}]`}K();import*as V from"fs/promises";import{createReadStream as em}from"fs";import{createGunzip as tm,gzip as nm,gunzip as sm}from"zlib";import{createInterface as rm}from"readline";import{promisify as wc}from"util";function pc(s){return s==="summary"?"summary":"inline"}var Do=256,Gh=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],Kh=["content","stdout","stderr"];function gc(s,e){return e!=="summary"?s:s.map(Qh)}function Qh(s){if(s.method!=="session/update")return s;let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return s;let t=e,n=t.update;if(!n||typeof n!="object"||Array.isArray(n))return s;let r=n;if(r.sessionUpdate!=="tool_call"&&r.sessionUpdate!=="tool_call_update")return s;let o={...r};Array.isArray(r.content)&&(o.content=r.content.map(hc));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=Ns(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let c of Gh)a[c]!==void 0&&(d[c]=a[c]);for(let c of Kh)typeof a[c]=="string"&&(d[c]=Ns(a[c]));o.rawOutput=d}return{...s,params:{...t,update:o}}}function Yh(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&s.type==="diff"}function hc(s){if(Yh(s)){let n=s,r={type:"diff",oldText:"",newText:""};return typeof n.path=="string"&&(r.path=n.path),r}if(!s||typeof s!="object"||Array.isArray(s))return s;let e=s,t={...e};return typeof e.text=="string"&&(t.text=Ns(e.text)),typeof e.content=="string"?t.content=Ns(e.content):e.content&&typeof e.content=="object"&&(t.content=hc(e.content)),t}function Ns(s){if(typeof s=="string"&&s.length>Do){let e=s.length-Do;return`${s.slice(0,Do)}\u2026[+${e} chars omitted from summary export]`}return s}var Xh=2048;function mc(s){let e=new Set,t=n=>{if(yc(n)){e.add(n.__hydraBlob);return}if(Array.isArray(n)){for(let r of n)t(r);return}if(n&&typeof n=="object")for(let r of Object.values(n))t(r)};for(let n of s)t(n.params);return e}function yc(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.__hydraBlob=="string"}function Zh(s){if(s.method!=="session/update")return!1;let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t.sessionUpdate;return n==="tool_call"||n==="tool_call_update"}async function Lo(s,e){if(!Zh(s))return s;let t=s.params,n=t.update,r=await Ho(n,e);return{...s,params:{...t,update:r}}}async function Ho(s,e){if(typeof s=="string"){if(s.length<=Xh)return s;let t=await e(s);return t===null?s:{__hydraBlob:t,bytes:s.length}}if(Array.isArray(s)){let t=[];for(let n of s)t.push(await Ho(n,e));return t}if(s&&typeof s=="object"){let t={};for(let[n,r]of Object.entries(s))t[n]=await Ho(r,e);return t}return s}async function Uo(s,e){let t=s.params;if(!t||typeof t!="object"||Array.isArray(t))return s;let n=await jo(t,e);return n===t?s:{...s,params:n}}async function jo(s,e){if(yc(s))return await e(s.__hydraBlob)??"";if(Array.isArray(s)){let t=!1,n=[];for(let r of s){let o=await jo(r,e);o!==r&&(t=!0),n.push(o)}return t?n:s}if(s&&typeof s=="object"){let t=!1,n={};for(let[r,o]of Object.entries(s)){let i=await jo(o,e);i!==o&&(t=!0),n[r]=i}return t?n:s}return s}function _n(s,e){let t=-1;for(let n=s.length-1;n>=0;n--)if(s[n]?.messageId===e){t=n;break}if(t<0)return-1;for(let n=t;n<s.length;n++){let r=s[n]?.sessionUpdate;if(r==="turn_complete"||r==="_hydra_turn_ended")return n;if(n>t&&(r==="prompt_received"||r==="_hydra_turn_started"))return n-1}return s.length-1}function Bo(s){return s.map(e=>e.method==="session/update"?e.params?.update:void 0)}var om=wc(nm),im=wc(sm),am=/^history\.jsonl\.(\d+)(\.gz)?$/,$e=/^[A-Za-z0-9_-]+$/;function dm(s){try{let e=JSON.parse(s);return e.method==="session/update"?e.params?.update:void 0}catch{return}}var cm=1e3,um=1e7,lm=10,Ds=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??cm,this.archiveMaxBytes=e.archiveMaxBytes??um,this.archiveTiers=e.archiveTiers??lm}async append(e,t){if($e.test(e))return this.enqueue(e,async()=>{await V.mkdir(E.sessionDir(e),{recursive:!0});let n=await Lo(t,o=>Or(e,o)),r=JSON.stringify(n)+`
144
+ ${So}`;return ec(s,n,Hd)}function Lh(s){if(!s||typeof s!="object")return"";let e=s.update;if(!e||typeof e!="object")return"";let t=e;if(t.sessionUpdate!=="agent_message_chunk")return"";let n=t.content;return n&&typeof n.text=="string"?n.text:""}function Uh(s){let e=new Set;Zd(e,s.availableModels);let t=s.models;return t&&typeof t=="object"&&!Array.isArray(t)&&Zd(e,t.availableModels),e}function Zd(s,e){if(Array.isArray(e)){for(let t of e)if(t&&typeof t=="object"){let n=t.modelId??t.value??t.id;typeof n=="string"&&n.length>0&&s.add(n)}}}var Bh="guardian_assessment:",Wh="Guardian Review";function nc(s,e){return s!==void 0&&s.startsWith(Bh)||e===Wh}function qh(s){let e=new Map;for(let t of dc(s).values())e.set(t.toolName,(e.get(t.toolName)??0)+1);return[...e.entries()].map(([t,n])=>({name:t,count:n})).sort((t,n)=>n.count-t.count||t.name.localeCompare(n.name))}function oc(s){return qh(s).map(e=>e.name)}function zh(s){let e=new Map;for(let t of dc(s).values())for(let n of t.paths){let r=e.get(n);r===void 0&&(r=new Map,e.set(n,r)),r.set(t.toolName,(r.get(t.toolName)??0)+1)}return[...e.entries()].map(([t,n])=>{let r=[...n.entries()].map(([i,a])=>({name:i,count:a})).sort((i,a)=>a.count-i.count||i.name.localeCompare(a.name)),o=r.reduce((i,a)=>i+a.count,0);return{path:t,count:o,byTool:r}}).sort((t,n)=>n.count-t.count||t.path.localeCompare(n.path))}function ic(s){return zh(s).map(e=>e.path)}function ac(s){let e=0;for(let t of s)t.params?.update?.sessionUpdate==="prompt_received"&&(e+=1);return e}function dc(s){let e=new Map,t=0;for(let n of s){let o=n.params?.update;if(!o)continue;let i=o.sessionUpdate;if(i!=="tool_call"&&i!=="tool_call_update")continue;if(i==="tool_call"){let d=typeof o.toolCallId=="string"&&o.toolCallId.length>0?o.toolCallId:void 0,c=typeof o.title=="string"?o.title:void 0;if(nc(d,c))continue;let u=d??`__synth_${t++}`,l=e.get(u);l===void 0?(l={toolName:sc(o),paths:new Set},e.set(u,l)):l.toolName=sc(o);for(let p of rc(o.rawInput,o.locations))l.paths.add(p);continue}if(typeof o.toolCallId!="string"||o.toolCallId.length===0)continue;let a=e.get(o.toolCallId);if(a!==void 0)for(let d of rc(o.rawInput,o.locations))a.paths.add(d)}return e}function sc(s){return typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function rc(s,e){let t=new Set;if(s&&typeof s=="object"&&!Array.isArray(s)){let n=s;typeof n.file_path=="string"?t.add(n.file_path):typeof n.path=="string"&&t.add(n.path);let r=n.edits;if(Array.isArray(r)){for(let o of r)if(o&&typeof o=="object"){let i=o.file_path;typeof i=="string"&&t.add(i)}}}for(let n of Ha(e))t.add(n);return t}K();var Vh=Jh("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",12),Gh=2,Fs=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??Gh}opts;queued={};inflight=new Map;stopped=!1;maxConcurrent;schedule(e){this.stopped||this.inflight.has(e)||e in this.queued||(this.queued[e]={kind:"title"},this.drain())}scheduleCompaction(e,t){if(this.stopped)return;let n=t?.targetAgentId;if(this.inflight.has(e))return;let r=this.queued[e];if(r&&r.kind==="title"){this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}};return}this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}},this.drain()}size(){return{queued:Object.keys(this.queued).length,inflight:this.inflight.size}}async flush(e){let t=Date.now()+e;for(;Object.keys(this.queued).length>0||this.inflight.size>0;){let n=t-Date.now();if(n<=0)return;let r=[...this.inflight.values()];if(r.length===0){await new Promise(o=>{setTimeout(o,25).unref?.()});continue}await Promise.race([Promise.race(r),new Promise(o=>{setTimeout(o,n).unref?.()})])}}async shutdown(){this.stopped=!0,this.queued={},await Promise.allSettled([...this.inflight.values()])}drain(){if(!this.stopped)for(;this.inflight.size<this.maxConcurrent&&Object.keys(this.queued).length>0;){let t=Object.keys(this.queued)[0];if(!t)return;let n=this.queued[t];delete this.queued[t];let r=this.runOne(t,n).finally(()=>{this.inflight.delete(t),this.drain()});this.inflight.set(t,r)}}async runOne(e,t){let n=t.kind,r=t.targetAgentId;try{let o=await this.opts.store.read(e);if(!o){this.opts.logger?.info(`synopsis: session ${e} record missing; skipping`);return}let i=await this.opts.histories.load(e,{maxEntries:1/0}),a=o.summarizedThroughEntry;if(a!==void 0&&i.length===a){this.opts.logger?.info(`synopsis: skip ${e} (history unchanged at ${i.length})`);return}a!==void 0&&i.length<a&&this.opts.logger?.warn(`synopsis: watermark ahead of history (last=${a} history=${i.length}) for ${e} \u2014 re-baselining`);let d=n==="compaction"?r??this.opts.compactionAgent??o.agentId:this.opts.synopsisAgent??o.agentId,c=await this.opts.registry.getAgent(d);if(!c){this.opts.logger?.warn(`synopsis: agent ${d} not in registry for session ${e}; skipping`);return}let u=await Me(c,[],{npmRegistry:this.opts.npmRegistry}),l=this.opts.compactionAgent===void 0&&r===void 0,p=n==="compaction"?this.opts.compactionModel??(l?o.currentModel:void 0):this.opts.synopsisModel,f=E.sessionDir(e);if(await fc.mkdir(f,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(p??"(default)")} cwd=${f}`),n==="compaction"){let h=this.opts.compactionMaxIterations??3,w=0,m=a??0,g,y=0,k,v=Date.now(),S=Vh(),b={targetAgentId:r},A=R=>this.opts.onCompactionStateChange?.(e,{runId:S,...R},b)??Promise.resolve(),C=R=>{this.opts.broadcastHydraCompaction?.(e,R,b)};await A({status:"requested",requestedAt:v}),C({sessionUpdate:"_hydra_compaction",phase:"started",requestedAt:v});try{do{w++,this.opts.logger?.info(`synopsis: compaction iteration ${w} sessionId=${e} historyLen=${i.length} watermark=${m}`);let R=await this.opts.histories.load(e,{maxEntries:1/0});if(R.length===m)break;let T=await tc({agentId:d,cwd:f,plan:u,history:R,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:(H,U)=>{A({status:"running",requestedAt:v,iter:w,worker:{upstreamSessionId:H,pid:U??0}})},onFailure:H=>{k=H}});if(T){let H=cc(T.synopsis,R);H&&uc(H)&&(await this.opts.persistSynopsis(e,H,R.length),g=H,y=R.length,k=void 0,await A({status:"running",requestedAt:v,iter:w}),C({sessionUpdate:"_hydra_compaction",phase:"iteration",iter:w,historyLen:R.length}),await this.opts.onSynthesisArtifact?.(e,H,y,r,S),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${w} fields=${lc(H)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${w} returned no result`);if(m=R.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===m)break}while(w<h);if(g)this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} runId=${S} watermark=${y} iterations=${w}`+(w>=h?` (hit maxIterations=${h})`:"")),C({sessionUpdate:"_hydra_compaction",phase:"converged",iter:w,summarizedThroughEntry:y});else{w>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${h} without producing artifact sessionId=${e}: ${k??"no reason captured"}`);let R=k??(w===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${w} iteration(s)`);await A({status:"failed",requestedAt:v,iter:w,lastError:R}),C({sessionUpdate:"_hydra_compaction",phase:"failed",error:R}),r&&await this.opts.onSynthesisUnavailable?.(e,r,R)}}catch(R){let T=R instanceof Error?R.message:String(R);if(this.opts.logger?.warn(`synopsis: compaction threw for sessionId=${e}: ${T}`),await A({status:"failed",requestedAt:v,iter:w,lastError:T}),this.opts.broadcastHydraCompaction?.(e,{sessionUpdate:"_hydra_compaction",phase:"failed",error:T},{targetAgentId:r}),r)try{await this.opts.onSynthesisUnavailable?.(e,r,T)}catch{}}}else{let h=await Os({agentId:d,cwd:f,plan:u,history:i,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs});if(!h){this.opts.logger?.warn(`synopsis: sessionId=${e} no parseable result; not persisting`);return}let w=cc(h.synopsis,i);w&&uc(w)?(await this.opts.persistSynopsis(e,w,i.length),h.title&&await this.opts.persistTitle(e,h.title),this.opts.logger?.info(`synopsis: persisted sessionId=${e} title=${JSON.stringify(!!h.title)} fields=${lc(w)}`)):h.title&&(await this.opts.persistTitle(e,h.title),this.opts.logger?.info(`synopsis: persisted title only sessionId=${e}`))}}catch(o){this.opts.logger?.warn(`synopsis: sessionId=${e} failed: ${o.message}`)}}};function cc(s,e){let t=ic(e),n=oc(e);return s?{...s,files_touched:t.length>0?t:s.files_touched,tools_used:n.length>0?n:s.tools_used}:t.length===0&&n.length===0?void 0:{files_touched:t.length>0?t:void 0,tools_used:n.length>0?n:void 0}}function uc(s){return!!(s.goal&&s.goal.trim().length>0||s.outcome&&s.outcome.trim().length>0||s.files_touched&&s.files_touched.length>0||s.tools_used&&s.tools_used.length>0||s.rejected_approaches&&s.rejected_approaches.length>0||s.open_threads&&s.open_threads.length>0)}function lc(s){let e=[];return s.goal&&e.push("goal"),s.outcome&&e.push("outcome"),s.files_touched&&s.files_touched.length>0&&e.push(`files=${s.files_touched.length}`),s.tools_used&&s.tools_used.length>0&&e.push(`tools=${s.tools_used.length}`),s.rejected_approaches&&s.rejected_approaches.length>0&&e.push(`rejected=${s.rejected_approaches.length}`),s.open_threads&&s.open_threads.length>0&&e.push(`open=${s.open_threads.length}`),`[${e.join(",")}]`}K();import*as V from"fs/promises";import{createReadStream as tm}from"fs";import{createGunzip as nm,gzip as sm,gunzip as rm}from"zlib";import{createInterface as om}from"readline";import{promisify as wc}from"util";function pc(s){return s==="summary"?"summary":"inline"}var Do=256,Kh=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],Qh=["content","stdout","stderr"];function gc(s,e){return e!=="summary"?s:s.map(Yh)}function Yh(s){if(s.method!=="session/update")return s;let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return s;let t=e,n=t.update;if(!n||typeof n!="object"||Array.isArray(n))return s;let r=n;if(r.sessionUpdate!=="tool_call"&&r.sessionUpdate!=="tool_call_update")return s;let o={...r};Array.isArray(r.content)&&(o.content=r.content.map(hc));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=Ns(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let c of Kh)a[c]!==void 0&&(d[c]=a[c]);for(let c of Qh)typeof a[c]=="string"&&(d[c]=Ns(a[c]));o.rawOutput=d}return{...s,params:{...t,update:o}}}function Xh(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&s.type==="diff"}function hc(s){if(Xh(s)){let n=s,r={type:"diff",oldText:"",newText:""};return typeof n.path=="string"&&(r.path=n.path),r}if(!s||typeof s!="object"||Array.isArray(s))return s;let e=s,t={...e};return typeof e.text=="string"&&(t.text=Ns(e.text)),typeof e.content=="string"?t.content=Ns(e.content):e.content&&typeof e.content=="object"&&(t.content=hc(e.content)),t}function Ns(s){if(typeof s=="string"&&s.length>Do){let e=s.length-Do;return`${s.slice(0,Do)}\u2026[+${e} chars omitted from summary export]`}return s}var Zh=2048;function mc(s){let e=new Set,t=n=>{if(yc(n)){e.add(n.__hydraBlob);return}if(Array.isArray(n)){for(let r of n)t(r);return}if(n&&typeof n=="object")for(let r of Object.values(n))t(r)};for(let n of s)t(n.params);return e}function yc(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.__hydraBlob=="string"}function em(s){if(s.method!=="session/update")return!1;let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t.sessionUpdate;return n==="tool_call"||n==="tool_call_update"}async function Lo(s,e){if(!em(s))return s;let t=s.params,n=t.update,r=await jo(n,e);return{...s,params:{...t,update:r}}}async function jo(s,e){if(typeof s=="string"){if(s.length<=Zh)return s;let t=await e(s);return t===null?s:{__hydraBlob:t,bytes:s.length}}if(Array.isArray(s)){let t=[];for(let n of s)t.push(await jo(n,e));return t}if(s&&typeof s=="object"){let t={};for(let[n,r]of Object.entries(s))t[n]=await jo(r,e);return t}return s}async function Uo(s,e){let t=s.params;if(!t||typeof t!="object"||Array.isArray(t))return s;let n=await Ho(t,e);return n===t?s:{...s,params:n}}async function Ho(s,e){if(yc(s))return await e(s.__hydraBlob)??"";if(Array.isArray(s)){let t=!1,n=[];for(let r of s){let o=await Ho(r,e);o!==r&&(t=!0),n.push(o)}return t?n:s}if(s&&typeof s=="object"){let t=!1,n={};for(let[r,o]of Object.entries(s)){let i=await Ho(o,e);i!==o&&(t=!0),n[r]=i}return t?n:s}return s}function _n(s,e){let t=-1;for(let n=s.length-1;n>=0;n--)if(s[n]?.messageId===e){t=n;break}if(t<0)return-1;for(let n=t;n<s.length;n++){let r=s[n]?.sessionUpdate;if(r==="turn_complete"||r==="_hydra_turn_ended")return n;if(n>t&&(r==="prompt_received"||r==="_hydra_turn_started"))return n-1}return s.length-1}function Bo(s){return s.map(e=>e.method==="session/update"?e.params?.update:void 0)}var im=wc(sm),am=wc(rm),dm=/^history\.jsonl\.(\d+)(\.gz)?$/,$e=/^[A-Za-z0-9_-]+$/;function cm(s){try{let e=JSON.parse(s);return e.method==="session/update"?e.params?.update:void 0}catch{return}}var um=1e3,lm=1e7,fm=10,Ds=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??um,this.archiveMaxBytes=e.archiveMaxBytes??lm,this.archiveTiers=e.archiveTiers??fm}async append(e,t){if($e.test(e))return this.enqueue(e,async()=>{await V.mkdir(E.sessionDir(e),{recursive:!0});let n=await Lo(t,o=>Or(e,o)),r=JSON.stringify(n)+`
145
145
  `;await V.appendFile(E.historyFile(e),r,{encoding:"utf8",mode:384})})}async rewrite(e,t){if($e.test(e))return this.enqueue(e,async()=>{await V.mkdir(E.sessionDir(e),{recursive:!0});let n=[];for(let o of t)n.push(await Lo(o,i=>Or(e,i)));let r=n.length===0?"":n.map(o=>JSON.stringify(o)).join(`
146
146
  `)+`
147
147
  `;await V.writeFile(E.historyFile(e),r,{encoding:"utf8",mode:384})})}async truncateAfterTurn(e,t){if(!$e.test(e))return;let n;return await this.enqueue(e,async()=>{let r="";try{r=await V.readFile(E.historyFile(e),"utf8")}catch(d){if(d.code!=="ENOENT")throw d}let o=r.split(`
148
- `).filter(d=>d.length>0),i=0;if(t!==null){let d=_n(o.map(dm),t);if(d<0)return;i=d+1}let a=o.slice(0,i);if(await V.writeFile(E.historyFile(e),a.length===0?"":a.join(`
148
+ `).filter(d=>d.length>0),i=0;if(t!==null){let d=_n(o.map(cm),t);if(d<0)return;i=d+1}let a=o.slice(0,i);if(await V.writeFile(E.historyFile(e),a.length===0?"":a.join(`
149
149
  `)+`
150
150
  `,{encoding:"utf8",mode:384}),t===null){for(let d of await this.listArchiveIndices(e))await this.unlinkArchive(e,d);this.nextArchiveIndex.delete(e)}this.archiveLineCounts.delete(e),n={kept:a.length,removed:o.length-a.length}}),n}async compact(e,t){if($e.test(e))return this.enqueue(e,async()=>{let n;try{n=await V.readFile(E.historyFile(e),"utf8")}catch(a){if(a.code==="ENOENT")return;throw a}let r=n.split(`
151
151
  `).filter(a=>a.length>0);if(r.length<=t)return;let o=r.slice(0,r.length-t),i=r.slice(-t);this.archiveMaxBytes>0&&o.length>0&&await this.spillToArchive(e,o),await V.writeFile(E.historyFile(e),i.join(`
152
152
  `)+`
153
153
  `,{encoding:"utf8",mode:384})})}async spillToArchive(e,t){let n=t.join(`
154
154
  `)+`
155
- `,r=await this.resolveNextArchiveIndex(e);await this.enforceArchiveTierCap(e,r);let o=E.historyArchiveFile(e,r);await V.mkdir(E.sessionDir(e),{recursive:!0}),await V.appendFile(o,n,{encoding:"utf8",mode:384});let i=0;try{i=(await V.stat(o)).size}catch{i=0}i>=this.archiveMaxBytes?(await this.sealArchive(e,r),this.nextArchiveIndex.set(e,r+1)):this.nextArchiveIndex.set(e,r),this.archiveLineCounts.delete(e)}async sealArchive(e,t){let n=E.historyArchiveFile(e,t),r;try{r=await V.readFile(n)}catch(i){if(i.code==="ENOENT")return;throw i}let o=await om(r);await V.writeFile(n+".gz",o,{mode:384});try{await V.unlink(n)}catch(i){if(i.code!=="ENOENT")throw i}}async resolveNextArchiveIndex(e){let t=this.nextArchiveIndex.get(e);if(t!==void 0)return t;let n=await this.listArchiveIndices(e),r=n.length===0?0:n[n.length-1],o=r===0?1:r;if(r>0){let i=E.historyArchiveFile(e,r),a=i+".gz",d=!1;try{await V.access(a),d=!0}catch{d=!1}if(d)o=r+1;else try{(await V.stat(i)).size>=this.archiveMaxBytes&&(o=r+1)}catch{o=r}}return this.nextArchiveIndex.set(e,o),o}async enforceArchiveTierCap(e,t){if(this.archiveTiers<=0)return;let n=await this.listArchiveIndices(e),o=(n.includes(t)?n.length:n.length+1)-this.archiveTiers,i=0;for(;o>0&&i<n.length;){let a=n[i];a!==t&&(await this.unlinkArchive(e,a),o-=1),i+=1}}async unlinkArchive(e,t){let n=E.historyArchiveFile(e,t);for(let r of[n,n+".gz"])try{await V.unlink(r)}catch(o){if(o.code!=="ENOENT")throw o}this.archiveLineCounts.delete(e)}async listArchiveIndices(e){let t;try{t=await V.readdir(E.sessionDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=new Set;for(let r of t){let o=am.exec(r);if(!o)continue;let i=Number.parseInt(o[1],10);Number.isFinite(i)&&i>0&&n.add(i)}return[...n].sort((r,o)=>r-o)}async listArchives(e){if(!$e.test(e))return[];let t=await this.listArchiveIndices(e),n=[];for(let r of t){let o=E.historyArchiveFile(e,r),i=o+".gz",a=o;try{await V.access(i),a=i}catch{a=o}n.push({index:r,path:a})}return n}async loadArchives(e){if(!$e.test(e))return[];let t=this.writeQueues.get(e);t&&await t;let n=await this.listArchives(e),r=[];for(let{path:o}of n){let i;try{if(o.endsWith(".gz")){let a=await V.readFile(o);i=(await im(a)).toString("utf8")}else i=await V.readFile(o,"utf8")}catch(a){if(a.code==="ENOENT")continue;throw a}for(let a of i.split(`
156
- `)){if(a.length===0)continue;let d;try{d=JSON.parse(a)}catch{continue}if(!d||typeof d!="object"||Array.isArray(d))continue;let c=d;typeof c.method=="string"&&typeof c.recordedAt=="number"&&r.push({method:c.method,params:c.params,recordedAt:c.recordedAt,...typeof c.seq=="number"?{seq:c.seq}:{}})}}return r}async*streamFile(e){let t;try{t=em(e)}catch(i){if(i.code==="ENOENT")return;throw i}if(await new Promise(i=>{let a=!1,d=c=>{a||(a=!0,i(c))};t.once("error",c=>{c.code==="ENOENT"?d(!0):(t.destroy(),d(!1))}),t.once("readable",()=>d(!1)),t.once("end",()=>d(!1))}))return;let r=e.endsWith(".gz")?t.pipe(tm()):t,o=rm({input:r,crlfDelay:1/0});try{for await(let i of o){if(i.length===0)continue;let a;try{a=JSON.parse(i)}catch{continue}if(!a||typeof a!="object"||Array.isArray(a))continue;let d=a;typeof d.method=="string"&&typeof d.recordedAt=="number"&&(yield{method:d.method,params:d.params,recordedAt:d.recordedAt,...typeof d.seq=="number"?{seq:d.seq}:{}})}}finally{o.close(),t.destroy()}}async getArchiveLineCounts(e){if(!$e.test(e))return[];let t=this.archiveLineCounts.get(e),n=await this.listArchives(e);if(t&&t.length===n.length&&t.every((o,i)=>o.index===n[i].index&&o.path===n[i].path))return t;let r=[];for(let{index:o,path:i}of n){let a=t?.find(c=>c.index===o&&c.path===i);if(a){r.push(a);continue}let d=0;for await(let c of this.streamFile(i))d+=1;r.push({index:o,path:i,lineCount:d})}return this.archiveLineCounts.set(e,r),r}async hydrate(e,t){let n=new Map,r=[];for(let o of t)r.push(await this.hydrateEntry(e,o,n));return r}async hydrateEntry(e,t,n){return Uo(t,async r=>{let o=n.get(r);if(o!==void 0)return o;let i=await gn(e,r);return n.set(r,i),i})}async*iterRecallNewestFirst(e,t={}){if(!$e.test(e))return;let n=this.writeQueues.get(e);n&&await n;let r=await this.getArchiveLineCounts(e),o=0;for(let l of r)o+=l.lineCount;let i=new Map,a=[];for await(let l of this.streamFile(E.historyFile(e)))a.push(l);let d=t.hydrate!==!1;for(let l=a.length-1;l>=0;l--){let p=d?await this.hydrateEntry(e,a[l],i):a[l];yield{entryId:o+l,entry:p}}let c=new Array(r.length),u=0;for(let l=0;l<r.length;l++)c[l]=u,u+=r[l].lineCount;for(let l=r.length-1;l>=0;l--){let p=r[l],f=[];for await(let w of this.streamFile(p.path))f.push(w);let h=c[l];for(let w=f.length-1;w>=0;w--){let m=d?await this.hydrateEntry(e,f[w],i):f[w];yield{entryId:h+w,entry:m}}}}async pageBefore(e,t){let n=[],r=0,o=!1,i=!1;for await(let{entry:a}of this.iterRecallNewestFirst(e,{hydrate:t.hydrate})){if(!o){if(a.seq===void 0||a.seq>=t.beforeSeq)continue;o=!0}if(t.skip?.(a))continue;if(r>=t.turns){i=!0;break}let d=a.params?.update;n.push(a),d?.sessionUpdate==="prompt_received"&&(r+=1)}return n.reverse(),{entries:n,hasMore:i}}async rangeSlice(e,t,n){if(!$e.test(e))return[];if(n<t)return[];let r=this.writeQueues.get(e);r&&await r;let o=await this.getArchiveLineCounts(e),i=0;for(let u of o)i+=u.lineCount;let a=[],d=new Map,c=0;for(let u of o){let l=c,p=c+u.lineCount;if(c=p,p<=t)continue;if(l>n)break;let f=0;for await(let h of this.streamFile(u.path)){let w=l+f;if(f+=1,w<t)continue;if(w>n)break;let m=await this.hydrateEntry(e,h,d);a.push({entryId:w,entry:m})}}if(n>=i){let u=Math.max(t-i,0),l=n-i,p=0;for await(let f of this.streamFile(E.historyFile(e))){if(p>l)break;if(p>=u){let h=await this.hydrateEntry(e,f,d);a.push({entryId:i+p,entry:h})}p+=1}}return a}async getRecallTotalCount(e){if(!$e.test(e))return 0;let t=await this.getArchiveLineCounts(e),n=0;for(let o of t)n+=o.lineCount;let r=0;for await(let o of this.streamFile(E.historyFile(e)))r+=1;return n+r}async load(e,t={}){if(!$e.test(e))return[];let n=(t.tools??"inline")==="inline",r=this.writeQueues.get(e);r&&await r;let o;try{o=await V.readFile(E.historyFile(e),"utf8")}catch(p){if(p.code==="ENOENT")return[];throw p}let i=[];for(let p of o.split(`
155
+ `,r=await this.resolveNextArchiveIndex(e);await this.enforceArchiveTierCap(e,r);let o=E.historyArchiveFile(e,r);await V.mkdir(E.sessionDir(e),{recursive:!0}),await V.appendFile(o,n,{encoding:"utf8",mode:384});let i=0;try{i=(await V.stat(o)).size}catch{i=0}i>=this.archiveMaxBytes?(await this.sealArchive(e,r),this.nextArchiveIndex.set(e,r+1)):this.nextArchiveIndex.set(e,r),this.archiveLineCounts.delete(e)}async sealArchive(e,t){let n=E.historyArchiveFile(e,t),r;try{r=await V.readFile(n)}catch(i){if(i.code==="ENOENT")return;throw i}let o=await im(r);await V.writeFile(n+".gz",o,{mode:384});try{await V.unlink(n)}catch(i){if(i.code!=="ENOENT")throw i}}async resolveNextArchiveIndex(e){let t=this.nextArchiveIndex.get(e);if(t!==void 0)return t;let n=await this.listArchiveIndices(e),r=n.length===0?0:n[n.length-1],o=r===0?1:r;if(r>0){let i=E.historyArchiveFile(e,r),a=i+".gz",d=!1;try{await V.access(a),d=!0}catch{d=!1}if(d)o=r+1;else try{(await V.stat(i)).size>=this.archiveMaxBytes&&(o=r+1)}catch{o=r}}return this.nextArchiveIndex.set(e,o),o}async enforceArchiveTierCap(e,t){if(this.archiveTiers<=0)return;let n=await this.listArchiveIndices(e),o=(n.includes(t)?n.length:n.length+1)-this.archiveTiers,i=0;for(;o>0&&i<n.length;){let a=n[i];a!==t&&(await this.unlinkArchive(e,a),o-=1),i+=1}}async unlinkArchive(e,t){let n=E.historyArchiveFile(e,t);for(let r of[n,n+".gz"])try{await V.unlink(r)}catch(o){if(o.code!=="ENOENT")throw o}this.archiveLineCounts.delete(e)}async listArchiveIndices(e){let t;try{t=await V.readdir(E.sessionDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=new Set;for(let r of t){let o=dm.exec(r);if(!o)continue;let i=Number.parseInt(o[1],10);Number.isFinite(i)&&i>0&&n.add(i)}return[...n].sort((r,o)=>r-o)}async listArchives(e){if(!$e.test(e))return[];let t=await this.listArchiveIndices(e),n=[];for(let r of t){let o=E.historyArchiveFile(e,r),i=o+".gz",a=o;try{await V.access(i),a=i}catch{a=o}n.push({index:r,path:a})}return n}async loadArchives(e){if(!$e.test(e))return[];let t=this.writeQueues.get(e);t&&await t;let n=await this.listArchives(e),r=[];for(let{path:o}of n){let i;try{if(o.endsWith(".gz")){let a=await V.readFile(o);i=(await am(a)).toString("utf8")}else i=await V.readFile(o,"utf8")}catch(a){if(a.code==="ENOENT")continue;throw a}for(let a of i.split(`
156
+ `)){if(a.length===0)continue;let d;try{d=JSON.parse(a)}catch{continue}if(!d||typeof d!="object"||Array.isArray(d))continue;let c=d;typeof c.method=="string"&&typeof c.recordedAt=="number"&&r.push({method:c.method,params:c.params,recordedAt:c.recordedAt,...typeof c.seq=="number"?{seq:c.seq}:{}})}}return r}async*streamFile(e){let t;try{t=tm(e)}catch(i){if(i.code==="ENOENT")return;throw i}if(await new Promise(i=>{let a=!1,d=c=>{a||(a=!0,i(c))};t.once("error",c=>{c.code==="ENOENT"?d(!0):(t.destroy(),d(!1))}),t.once("readable",()=>d(!1)),t.once("end",()=>d(!1))}))return;let r=e.endsWith(".gz")?t.pipe(nm()):t,o=om({input:r,crlfDelay:1/0});try{for await(let i of o){if(i.length===0)continue;let a;try{a=JSON.parse(i)}catch{continue}if(!a||typeof a!="object"||Array.isArray(a))continue;let d=a;typeof d.method=="string"&&typeof d.recordedAt=="number"&&(yield{method:d.method,params:d.params,recordedAt:d.recordedAt,...typeof d.seq=="number"?{seq:d.seq}:{}})}}finally{o.close(),t.destroy()}}async getArchiveLineCounts(e){if(!$e.test(e))return[];let t=this.archiveLineCounts.get(e),n=await this.listArchives(e);if(t&&t.length===n.length&&t.every((o,i)=>o.index===n[i].index&&o.path===n[i].path))return t;let r=[];for(let{index:o,path:i}of n){let a=t?.find(c=>c.index===o&&c.path===i);if(a){r.push(a);continue}let d=0;for await(let c of this.streamFile(i))d+=1;r.push({index:o,path:i,lineCount:d})}return this.archiveLineCounts.set(e,r),r}async hydrate(e,t){let n=new Map,r=[];for(let o of t)r.push(await this.hydrateEntry(e,o,n));return r}async hydrateEntry(e,t,n){return Uo(t,async r=>{let o=n.get(r);if(o!==void 0)return o;let i=await gn(e,r);return n.set(r,i),i})}async*iterRecallNewestFirst(e,t={}){if(!$e.test(e))return;let n=this.writeQueues.get(e);n&&await n;let r=await this.getArchiveLineCounts(e),o=0;for(let l of r)o+=l.lineCount;let i=new Map,a=[];for await(let l of this.streamFile(E.historyFile(e)))a.push(l);let d=t.hydrate!==!1;for(let l=a.length-1;l>=0;l--){let p=d?await this.hydrateEntry(e,a[l],i):a[l];yield{entryId:o+l,entry:p}}let c=new Array(r.length),u=0;for(let l=0;l<r.length;l++)c[l]=u,u+=r[l].lineCount;for(let l=r.length-1;l>=0;l--){let p=r[l],f=[];for await(let w of this.streamFile(p.path))f.push(w);let h=c[l];for(let w=f.length-1;w>=0;w--){let m=d?await this.hydrateEntry(e,f[w],i):f[w];yield{entryId:h+w,entry:m}}}}async pageBefore(e,t){let n=[],r=0,o=!1,i=!1;for await(let{entry:a}of this.iterRecallNewestFirst(e,{hydrate:t.hydrate})){if(!o){if(a.seq===void 0||a.seq>=t.beforeSeq)continue;o=!0}if(t.skip?.(a))continue;if(r>=t.turns){i=!0;break}let d=a.params?.update;n.push(a),d?.sessionUpdate==="prompt_received"&&(r+=1)}return n.reverse(),{entries:n,hasMore:i}}async rangeSlice(e,t,n){if(!$e.test(e))return[];if(n<t)return[];let r=this.writeQueues.get(e);r&&await r;let o=await this.getArchiveLineCounts(e),i=0;for(let u of o)i+=u.lineCount;let a=[],d=new Map,c=0;for(let u of o){let l=c,p=c+u.lineCount;if(c=p,p<=t)continue;if(l>n)break;let f=0;for await(let h of this.streamFile(u.path)){let w=l+f;if(f+=1,w<t)continue;if(w>n)break;let m=await this.hydrateEntry(e,h,d);a.push({entryId:w,entry:m})}}if(n>=i){let u=Math.max(t-i,0),l=n-i,p=0;for await(let f of this.streamFile(E.historyFile(e))){if(p>l)break;if(p>=u){let h=await this.hydrateEntry(e,f,d);a.push({entryId:i+p,entry:h})}p+=1}}return a}async getRecallTotalCount(e){if(!$e.test(e))return 0;let t=await this.getArchiveLineCounts(e),n=0;for(let o of t)n+=o.lineCount;let r=0;for await(let o of this.streamFile(E.historyFile(e)))r+=1;return n+r}async load(e,t={}){if(!$e.test(e))return[];let n=(t.tools??"inline")==="inline",r=this.writeQueues.get(e);r&&await r;let o;try{o=await V.readFile(E.historyFile(e),"utf8")}catch(p){if(p.code==="ENOENT")return[];throw p}let i=[];for(let p of o.split(`
157
157
  `)){if(p.length===0)continue;let f;try{f=JSON.parse(p)}catch{continue}if(!f||typeof f!="object"||Array.isArray(f))continue;let h=f;typeof h.method=="string"&&typeof h.recordedAt=="number"&&i.push({method:h.method,params:h.params,recordedAt:h.recordedAt,...typeof h.seq=="number"?{seq:h.seq}:{}})}let a=t.maxEntries??this.maxEntries,d=i.length>a?i.slice(-a):i;if(!n)return d;let c=new Map,u=async p=>{let f=c.get(p);if(f!==void 0)return f;let h=await gn(e,p);return c.set(p,h),h},l=[];for(let p of d)l.push(await Uo(p,u));return l}async flushAll(){let e=[...this.writeQueues.values()];e.length!==0&&await Promise.allSettled(e)}async delete(e){if($e.test(e))return this.enqueue(e,async()=>{try{await V.unlink(E.historyFile(e))}catch(n){if(n.code!=="ENOENT")throw n}let t=await this.listArchiveIndices(e);for(let n of t)await this.unlinkArchive(e,n);this.nextArchiveIndex.delete(e),this.archiveLineCounts.delete(e),await Gi(e);try{await V.rmdir(E.sessionDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}})}enqueue(e,t){let r=(this.writeQueues.get(e)??Promise.resolve()).then(t,t),o=r.catch(()=>{});return this.writeQueues.set(e,o),o.finally(()=>{this.writeQueues.get(e)===o&&this.writeQueues.delete(e)}),r}};K();import{promises as kc}from"fs";import*as vc from"path";async function bc(s,e){await kc.mkdir(vc.dirname(s),{recursive:!0});let t=e.map(n=>JSON.stringify(n));await kc.writeFile(s,t.length>0?t.join(`
158
158
  `)+`
159
- `:"")}import{z as G}from"zod";var fm=G.object({method:G.string(),params:G.unknown(),recordedAt:G.number()}),pm=G.object({sessionId:G.string(),lineageId:G.string(),upstreamSessionId:G.string().optional(),agentId:G.string(),cwd:G.string(),title:G.string().optional(),synopsis:Cn.optional(),summarizedThroughEntry:G.number().int().nonnegative().optional(),currentModel:G.string().optional(),currentMode:G.string().optional(),currentUsage:Co.optional(),agentCommands:G.array(Io).optional(),agentModes:G.array(Ao).optional(),interactive:G.boolean().optional(),originatingClient:Ro.optional(),priority:G.number().int().nonnegative().optional(),createdAt:G.string(),updatedAt:G.string()}),gm=G.object({version:G.literal(1),exportedAt:G.string(),exportedFrom:G.object({hydraVersion:G.string(),machine:G.string(),hydraHost:G.string().optional()}),session:pm,history:G.array(fm),promptHistory:G.array(G.string()).optional(),toolBlobs:G.record(G.string()).optional()});function $n(s){let e={version:1,exportedAt:new Date().toISOString(),exportedFrom:{hydraVersion:s.hydraVersion,machine:s.machine,...s.hydraHost!==void 0&&s.hydraHost.length>0?{hydraHost:s.hydraHost}:{}},session:{sessionId:s.record.sessionId,lineageId:s.record.lineageId,...s.record.upstreamSessionId?{upstreamSessionId:s.record.upstreamSessionId}:{},agentId:s.record.agentId,cwd:s.record.cwd,...s.record.title!==void 0?{title:s.record.title}:{},...s.record.synopsis!==void 0?{synopsis:s.record.synopsis}:{},...s.record.summarizedThroughEntry!==void 0?{summarizedThroughEntry:s.record.summarizedThroughEntry}:{},...s.record.currentModel!==void 0?{currentModel:s.record.currentModel}:{},...s.record.currentMode!==void 0?{currentMode:s.record.currentMode}:{},...s.record.currentUsage!==void 0?{currentUsage:s.record.currentUsage}:{},...s.record.agentCommands!==void 0?{agentCommands:s.record.agentCommands}:{},...s.record.agentModes!==void 0?{agentModes:s.record.agentModes}:{},...s.record.interactive!==void 0?{interactive:s.record.interactive}:{},...s.record.originatingClient!==void 0?{originatingClient:s.record.originatingClient}:{},...s.record.priority!==void 0&&s.record.priority>0?{priority:s.record.priority}:{},createdAt:s.record.createdAt,updatedAt:s.record.updatedAt},history:s.history};return s.promptHistory!==void 0&&(e.promptHistory=s.promptHistory),s.toolBlobs!==void 0&&Object.keys(s.toolBlobs).length>0&&(e.toolBlobs=s.toolBlobs),e}function Sc(s){return gm.parse(s)}function Wo(s){if(s&&!(s.costAmount===void 0&&s.cumulativeCost===void 0))return(s.cumulativeCost??0)+(s.costAmount??0)}function On(s){if(!s)return;let e={};s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size);let t=Wo(s);return t&&(e.costAmount=t),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),e}var Ic=900*1e3,mm=12,ym="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ct=hm(ym,16);function wm(){let s,e,t=!1;return{send(n){if(t)return Promise.resolve();if("method"in n&&"id"in n){let r={jsonrpc:"2.0",id:n.id,error:{code:x.MethodNotFound,message:`no handler for ${n.method} (headless fork-prompt client)`}};queueMicrotask(()=>s?.(r))}return Promise.resolve()},onMessage(n){s=n},onClose(n){e=n},close(){return t||(t=!0,e?.()),Promise.resolve()}}}var Hs=class s{constructor(e,t,n,r={}){this.registry=e;this.spawner=t??(a=>dt.spawn(a)),this.store=n??new vs,this.tombstones=r.tombstones??new Ms,this.sessionHistoryMaxEntries=r.sessionHistoryMaxEntries??1e3,this.histories=new Ds({maxEntries:this.sessionHistoryMaxEntries,archiveMaxBytes:r.sessionHistoryArchiveMaxBytes,archiveTiers:r.sessionHistoryArchiveTiers}),this.workspaceSnapshotsDisabled=r.disableWorkspaceSnapshots===!0,this.idleTimeoutMs=r.idleTimeoutMs??0,this.orphanTimeoutMs=r.orphanTimeoutMs??0,this.idleEventTimeoutMs=r.idleEventTimeoutMs??3e4,this.sessionDefaults=r.sessionDefaults??{},this.synopsisAgent=r.synopsisAgent,this.synopsisModel=r.synopsisModel,this.compactionAgent=r.compactionAgent,this.compactionModel=r.compactionModel,this.defaultTransformers=r.defaultTransformers??[],this.logger=r.logger,this.npmRegistry=r.npmRegistry,this.extensionCommands=r.extensionCommands,this.defaultCwd=r.defaultCwd??"~";let o=r.compaction??{},i=o.tailK??20;this.compactionTailK=i,this.synopsisCoordinator=new Fs({registry:this.registry,store:this.store,histories:this.histories,synopsisAgent:this.synopsisAgent,synopsisModel:this.synopsisModel,compactionAgent:this.compactionAgent,compactionModel:this.compactionModel,compactionMaxIterations:o.maxIterations,persistTitle:async(a,d)=>{let c=this.get(a);if(c){await c.retitle(d);return}await this.persistTitle(a,d)},persistSynopsis:(a,d,c)=>this.persistSynopsis(a,d,c),logger:this.logger,npmRegistry:this.npmRegistry,onCompactionStateChange:async(a,d,c)=>{if(c.targetAgentId)return;let u=this.get(a);u&&(u.compactionState=d),await this.mutateRecord(a,{compactionState:d})},broadcastHydraCompaction:(a,d,c)=>{this.emitSwapPhase(a,c.targetAgentId,d)},onSynthesisArtifact:async(a,d,c,u,l)=>{await this.dispatchSynthesisSwap(a,d,c,u,l)},onSynthesisUnavailable:async(a,d,c)=>{let u=await this.store.read(a).catch(()=>{});if(u?.synopsis&&u.summarizedThroughEntry!==void 0){this.logger?.info(`agent switch: synthesis produced no new artifact for sessionId=${a} (${c}); swapping to ${d} on the persisted synopsis`),await this.dispatchSynthesisSwap(a,u.synopsis,u.summarizedThroughEntry,d);return}let l=(await this.histories.load(a).catch(()=>[])).length;this.logger?.warn(`agent switch: synthesis unavailable for sessionId=${a} (${c}); swapping to ${d} on verbatim tail`),await this.dispatchSynthesisSwap(a,void 0,l,d)}}),this.refreshAgentCatalog()}registry;sessions=new Map;resurrectionInflight=new Map;snapshotInFlight=new Set;snapshotPending=new Set;workspaceSnapshotsDisabled=!1;driftNoticed=new Map;pendingAuthAgents=new Map;spawner;store;tombstones;histories;idleTimeoutMs;orphanTimeoutMs;sessionDefaults;synopsisAgent;synopsisModel;compactionAgent;compactionModel;defaultTransformers;idleEventTimeoutMs;sessionHistoryMaxEntries;metaWriteQueues=new Map;workspaceQueues=new Map;listCache=new Map;static LIST_CACHE_TTL_MS=500;logger;npmRegistry;extensionCommands;defaultCwd;synopsisCoordinator;pendingDeletions=new Map;pendingSwapDisposers=new Map;rollbackLocks=new Set;compactionTailK=20;agentCatalog=[];async dispatchSynthesisSwap(e,t,n,r,o){let i=this.get(e);if(t===void 0&&r===void 0)return;if(!i){if(this.logger?.info(`compaction: persisted artifact for cold session sessionId=${e}`),t===void 0)return;await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:n});return}let a=this.compactionTailK;try{if(await i.isQuiescedForSwap()){this.pendingSwapDisposers.get(e)?.(),this.pendingSwapDisposers.delete(e),await this.performSynthesisSwap(i,t,a,n,r,o);return}this.pendingSwapDisposers.get(e)?.(),this.logger?.info(`compaction: session not quiesced, parking onceIdle swap sessionId=${e}`),this.emitSwapPhase(e,r,{phase:"deferred"});let c=i.onceIdle(()=>{this.pendingSwapDisposers.delete(e),this.onIdleAttemptSwap(e)});this.pendingSwapDisposers.set(e,c)}catch(d){this.logger?.warn(`compaction: dispatch failed for sessionId=${e}: ${d instanceof Error?d.message:String(d)}, leaving session as-is`)}}async onIdleAttemptSwap(e){let t=this.get(e);if(!t)return;let n=this.compactionTailK;try{if(!await t.isQuiescedForSwap()){let d=await this.store.read(e).catch(()=>{});d?.synopsis&&d.summarizedThroughEntry!==void 0?this.dispatchSynthesisSwap(e,d.synopsis,d.summarizedThroughEntry,d.pendingAgentSwap):d?.pendingAgentSwap&&this.dispatchSynthesisSwap(e,void 0,(await this.histories.load(e).catch(()=>[])).length,d.pendingAgentSwap);return}let o=await this.store.read(e).catch(()=>{});if(!o?.synopsis||o.summarizedThroughEntry===void 0){if(o?.pendingAgentSwap){let d=(await this.histories.load(e).catch(()=>[])).length;this.logger?.info(`compaction: no artifact for sessionId=${e}, swapping to ${o.pendingAgentSwap} on verbatim tail`),await this.performSynthesisSwap(t,void 0,n,d,o.pendingAgentSwap);return}this.logger?.warn(`compaction: persisted artifact missing for sessionId=${e}, abandoning swap`),t.compactionState=void 0,await this.mutateRecord(e,{},["compactionState"]);return}let i=o.pendingAgentSwap,a=await this.histories.load(e).catch(()=>[]);if(a.length>o.summarizedThroughEntry){this.logger?.info(`compaction: history grew during deferral (have=${a.length} artifact=${o.summarizedThroughEntry}), rescheduling synopsis sessionId=${e}`),i?this.synopsisCoordinator.scheduleCompaction(e,{targetAgentId:i}):this.synopsisCoordinator.scheduleCompaction(e);return}await this.performSynthesisSwap(t,o.synopsis,n,o.summarizedThroughEntry,i,o.compactionState?.runId)}catch(r){this.logger?.warn(`compaction: onIdleAttemptSwap failed for sessionId=${e}: ${r instanceof Error?r.message:String(r)}`)}}async recordSynopsisFor(e){let t=await this.store.read(e).catch(()=>{});return t?.synopsis?{synopsis:t.synopsis}:{}}async performSynthesisSwap(e,t,n,r,o,i){try{let a=o?Math.min(t===void 0?mm:5,n):0;await e.swapUpstream({...t!==void 0?{artifact:t}:{},tailK:n,tailFloor:a,summarizedThroughEntry:r,...o?{newAgentId:o}:{},...i!==void 0?{runId:i}:{}}),o?await this.mutateRecord(e.sessionId,{},["pendingAgentSwap"]):(e.compactionState=void 0,await this.mutateRecord(e.sessionId,{},["compactionState"]))}catch(a){this.logger?.warn(`compaction: swap failed for sessionId=${e.sessionId}: ${a instanceof Error?a.message:String(a)}, leaving session as-is`)}finally{this.invalidateListCache()}}async refreshAgentCatalog(){try{let{agents:e}=await Dt(this.registry);this.agentCatalog=e.map(t=>({id:t.id,name:t.name,...t.description!==void 0?{description:t.description}:{}}))}catch{}}async adoptWorkspace(e,t,n){let r=t.label;if(r===void 0)throw new Error("workspace.adopt requires workspace.label");let o=this.liveSessionsWithLabel(n.cwd,r)[0]?.workspace,i=o!==void 0?this.asWorkspace(o):(await e.listWorkspaces(n.cwd).catch(()=>[])).find(a=>a.label===r);if(i===void 0)throw new Error(`cannot adopt workspace "${r}": no workspace by that name derived from ${$(n.cwd)}`);return await this.enqueueKeyed(this.workspaceQueues,i.path,async()=>(e.capabilities().locking&&await e.lock(i,`session ${n.title??"live"}`).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},...o?.clean!==void 0?{clean:o.clean}:{}}}))}async resolveWorkspace(e){let t=e.workspace;if(t===void 0)return{cwd:e.cwd};let n=re(t.provider);if(n===void 0){let u=`unknown workspace provider "${t.provider}"`;if(t.required===!0)throw new Error(`isolation required but unavailable: ${u}`);return this.logger?.warn?.(`session workspace: ${u}; running in ${e.cwd}`),{cwd:e.cwd,isolationError:u}}if(t.adopt===!0)return await this.adoptWorkspace(n,t,e);let r=t.label??`s-${Ct().slice(0,8)}`,o=await n.createWorkspace({sourceCwd:e.cwd,label:r,...t.from!==void 0?{from:t.from}:{}}).catch(u=>({ok:!1,reason:String(u)}));if(!o.ok){if(t.required===!0)throw new Error(`isolation required but unavailable: ${o.reason}`);return this.logger?.warn?.(`session workspace: ${o.reason}; falling back to ${e.cwd} (unisolated)`),{cwd:e.cwd,isolationError:o.reason}}let i=o.workspace;n.capabilities().locking&&await n.lock(i,`session ${e.title??"live"}`).catch(()=>{});let a=await Ts(i.sourceCwd).catch(()=>({})),d,c=await this.materializeNestedTrees(i);if(c!==void 0&&this.logger?.info?.(`session workspace: ${c} in ${i.path}`),a.carry!==void 0&&a.carry.length>0){let u=await No(i.sourceCwd,i.path,a.carry).catch(()=>{});u!==void 0&&u.copied.length>0&&this.logger?.info?.(`session workspace: carried ${u.copied.length} file(s) into ${i.path}`)}if(a.postCreate!==void 0){let u=await Ps(a.postCreate,{workspacePath:i.path,sourceCwd:i.sourceCwd,label:i.label,...a.hookTimeoutSeconds!==void 0?{timeoutSeconds:a.hookTimeoutSeconds}:{}});u.ok||(d=`postCreate failed: ${u.reason??"unknown"}`,this.logger?.warn?.(`session workspace: ${d} (${i.path})`))}return i.snapshot!==void 0&&await n.retainSnapshot(i,this.startRefFor(i.label),i.snapshot).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},clean:!0},...d!==void 0?{isolationError:d}:{}}}async create(e){let t=await this.registry.getAgent(e.agentId);t&&t.id!==e.agentId&&(e={...e,agentId:t.id});let n=`${ye}${Ct()}`,r=await this.resolveWorkspace(e),o=r.cwd,i=await this.bootstrapAgent({agentId:e.agentId,cwd:o,agentArgs:e.agentArgs,mcpServers:e.mcpServers,model:e.model,configDefaults:e.configDefaults,onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,selfSessionId:n});if(e.transformChain&&e.transformChain.length>0){let d={...i.agentCapabilities??{}};for(let c of e.transformChain)if(c.intercepts.has("agent:initialize"))try{let u=await c.connection.request("hydra-acp/transformer/message",{token:`t_${Ct()}`,phase:"response",method:"initialize",direction:"agent\u2192daemon",sessionId:"(pre-session)",envelope:d});u.action==="stop"&&u.payload&&(d=u.payload)}catch{}i.agentCapabilities=d}let a=new Gt({sessionId:n,cwd:o,...r.workspace!==void 0?{workspace:r.workspace}:{},...r.isolationError!==void 0?{workspaceError:r.isolationError}:{},agentId:e.agentId,agent:i.agent,upstreamSessionId:i.upstreamSessionId,agentMeta:i.agentMeta,agentCapabilities:i.agentCapabilities,...i.modelVerb?{modelVerb:i.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,orphanTimeoutMs:this.orphanTimeoutMs,idleEventTimeoutMs:this.idleEventTimeoutMs,logger:this.logger,spawnReplacementAgent:d=>this.bootstrapAgent({...d,mcpServers:d.mcpServers??[],selfSessionId:n}),loadExistingAgentSession:(d,c)=>this.bootstrapAgentLoad(d,{...c,mcpServers:c.mcpServers??[],selfSessionId:n}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:i.initialModel,currentMode:i.initialMode,agentModes:i.initialModes,agentModels:i.initialModels,agentConfigOptions:i.initialConfigOptions,transformChain:e.transformChain,parentSessionId:e.parentSessionId,originatingClient:e.originatingClient,interactive:e.interactive,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(a.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(a),scheduleCompaction:d=>this.scheduleCompaction(a.sessionId,d),resolveAgentId:async d=>(await this.registry.getAgent(d))?.id,getCompactionState:()=>this.getCompactionState(a.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(a.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(a.sessionId),uncompactHook:()=>this.performUncompact(a.sessionId),forkHook:d=>this.forkSession(a.sessionId,d??{}),workspaceHook:(d,c,u)=>this.runWorkspaceAction(a.sessionId,d,c,u),onCompactionSwapHook:d=>{this.persistRollbackBreadcrumb(a.sessionId,d).catch(()=>{})},persistWatermarkHook:d=>{this.mutateRecord(a.sessionId,{summarizedThroughEntry:d}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(a.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});if(r.workspace!==void 0){let d=re(r.workspace.provider);d!==void 0&&d.capabilities().supports.environmentNotes&&(a.workspaceNotes=await d.environmentNotes({path:r.workspace.path,sourceCwd:r.workspace.sourceCwd,label:r.workspace.label,provider:r.workspace.provider,...r.workspace.snapshot!==void 0?{snapshot:r.workspace.snapshot}:{},...r.workspace.vcs!==void 0?{vcs:r.workspace.vcs}:{}}).catch(()=>[]))}return await this.attachManagerHooks(a),a}async resurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t){if(t.upstreamSessionId!==e.upstreamSessionId){let o=new Error(`session ${e.hydraSessionId} already exists with a different upstream id`);throw o.code=x.AlreadyAttached,o}return t}let n=this.resurrectionInflight.get(e.hydraSessionId);if(n)return n;let r=this.doResurrect(e);this.resurrectionInflight.set(e.hydraSessionId,r);try{return await r}finally{this.resurrectionInflight.delete(e.hydraSessionId)}}async doResurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t)return t;let n=await this.registry.getAgent(e.agentId);if(!n){let k=new Error(`agent ${e.agentId} not found in registry; cannot resurrect`);throw k.code=x.AgentNotInstalled,k}if(e.upstreamSessionId==="")return this.doResurrectFromImport(e);if(!await this.dirExists(e.cwd))return this.doResurrectFromImport(e);let r=await Me(n,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),o=Zn(e.hydraSessionId,e.forwardedEnv),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...o?{extraEnv:o}:{}}),a;try{let k=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:jt,clientInfo:{name:"hydra",version:ue}});a=k.agentCapabilities,i.authMethods=Nn(k.authMethods),i.steeringSupported=Fn(k)}catch(k){throw await i.kill().catch(()=>{}),ht(k,i)}let d;try{let k=zo(n,{model:e.currentModel});d=await i.connection.request("session/load",{sessionId:e.upstreamSessionId,cwd:e.cwd,mcpServers:e.mcpServers??[],...k&&{_meta:k}})}catch(k){if(k&&typeof k=="object"&&k.code===x.AuthRequired)throw await i.kill().catch(()=>{}),ht(k,i);return process.stderr.write(`session/load failed for upstream ${e.upstreamSessionId} on ${e.agentId} (${k.message}); recovering via import-reseed
159
+ `:"")}import{z as G}from"zod";var pm=G.object({method:G.string(),params:G.unknown(),recordedAt:G.number()}),gm=G.object({sessionId:G.string(),lineageId:G.string(),upstreamSessionId:G.string().optional(),agentId:G.string(),cwd:G.string(),title:G.string().optional(),synopsis:Cn.optional(),summarizedThroughEntry:G.number().int().nonnegative().optional(),currentModel:G.string().optional(),currentMode:G.string().optional(),currentUsage:Co.optional(),agentCommands:G.array(Io).optional(),agentModes:G.array(Ao).optional(),interactive:G.boolean().optional(),originatingClient:Ro.optional(),priority:G.number().int().nonnegative().optional(),createdAt:G.string(),updatedAt:G.string()}),hm=G.object({version:G.literal(1),exportedAt:G.string(),exportedFrom:G.object({hydraVersion:G.string(),machine:G.string(),hydraHost:G.string().optional()}),session:gm,history:G.array(pm),promptHistory:G.array(G.string()).optional(),toolBlobs:G.record(G.string()).optional()});function $n(s){let e={version:1,exportedAt:new Date().toISOString(),exportedFrom:{hydraVersion:s.hydraVersion,machine:s.machine,...s.hydraHost!==void 0&&s.hydraHost.length>0?{hydraHost:s.hydraHost}:{}},session:{sessionId:s.record.sessionId,lineageId:s.record.lineageId,...s.record.upstreamSessionId?{upstreamSessionId:s.record.upstreamSessionId}:{},agentId:s.record.agentId,cwd:s.record.cwd,...s.record.title!==void 0?{title:s.record.title}:{},...s.record.synopsis!==void 0?{synopsis:s.record.synopsis}:{},...s.record.summarizedThroughEntry!==void 0?{summarizedThroughEntry:s.record.summarizedThroughEntry}:{},...s.record.currentModel!==void 0?{currentModel:s.record.currentModel}:{},...s.record.currentMode!==void 0?{currentMode:s.record.currentMode}:{},...s.record.currentUsage!==void 0?{currentUsage:s.record.currentUsage}:{},...s.record.agentCommands!==void 0?{agentCommands:s.record.agentCommands}:{},...s.record.agentModes!==void 0?{agentModes:s.record.agentModes}:{},...s.record.interactive!==void 0?{interactive:s.record.interactive}:{},...s.record.originatingClient!==void 0?{originatingClient:s.record.originatingClient}:{},...s.record.priority!==void 0&&s.record.priority>0?{priority:s.record.priority}:{},createdAt:s.record.createdAt,updatedAt:s.record.updatedAt},history:s.history};return s.promptHistory!==void 0&&(e.promptHistory=s.promptHistory),s.toolBlobs!==void 0&&Object.keys(s.toolBlobs).length>0&&(e.toolBlobs=s.toolBlobs),e}function Sc(s){return hm.parse(s)}function Wo(s){if(s&&!(s.costAmount===void 0&&s.cumulativeCost===void 0))return(s.cumulativeCost??0)+(s.costAmount??0)}function On(s){if(!s)return;let e={};s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size);let t=Wo(s);return t&&(e.costAmount=t),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),e}var Ic=900*1e3,ym=12,wm="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ct=mm(wm,16);function km(){let s,e,t=!1;return{send(n){if(t)return Promise.resolve();if("method"in n&&"id"in n){let r={jsonrpc:"2.0",id:n.id,error:{code:x.MethodNotFound,message:`no handler for ${n.method} (headless fork-prompt client)`}};queueMicrotask(()=>s?.(r))}return Promise.resolve()},onMessage(n){s=n},onClose(n){e=n},close(){return t||(t=!0,e?.()),Promise.resolve()}}}var js=class s{constructor(e,t,n,r={}){this.registry=e;this.spawner=t??(a=>dt.spawn(a)),this.store=n??new vs,this.tombstones=r.tombstones??new Ms,this.sessionHistoryMaxEntries=r.sessionHistoryMaxEntries??1e3,this.histories=new Ds({maxEntries:this.sessionHistoryMaxEntries,archiveMaxBytes:r.sessionHistoryArchiveMaxBytes,archiveTiers:r.sessionHistoryArchiveTiers}),this.workspaceSnapshotsDisabled=r.disableWorkspaceSnapshots===!0,this.idleTimeoutMs=r.idleTimeoutMs??0,this.orphanTimeoutMs=r.orphanTimeoutMs??0,this.idleEventTimeoutMs=r.idleEventTimeoutMs??3e4,this.sessionDefaults=r.sessionDefaults??{},this.synopsisAgent=r.synopsisAgent,this.synopsisModel=r.synopsisModel,this.compactionAgent=r.compactionAgent,this.compactionModel=r.compactionModel,this.defaultTransformers=r.defaultTransformers??[],this.logger=r.logger,this.npmRegistry=r.npmRegistry,this.extensionCommands=r.extensionCommands,this.defaultCwd=r.defaultCwd??"~";let o=r.compaction??{},i=o.tailK??20;this.compactionTailK=i,this.synopsisCoordinator=new Fs({registry:this.registry,store:this.store,histories:this.histories,synopsisAgent:this.synopsisAgent,synopsisModel:this.synopsisModel,compactionAgent:this.compactionAgent,compactionModel:this.compactionModel,compactionMaxIterations:o.maxIterations,persistTitle:async(a,d)=>{let c=this.get(a);if(c){await c.retitle(d);return}await this.persistTitle(a,d)},persistSynopsis:(a,d,c)=>this.persistSynopsis(a,d,c),logger:this.logger,npmRegistry:this.npmRegistry,onCompactionStateChange:async(a,d,c)=>{if(c.targetAgentId)return;let u=this.get(a);u&&(u.compactionState=d),await this.mutateRecord(a,{compactionState:d})},broadcastHydraCompaction:(a,d,c)=>{this.emitSwapPhase(a,c.targetAgentId,d)},onSynthesisArtifact:async(a,d,c,u,l)=>{await this.dispatchSynthesisSwap(a,d,c,u,l)},onSynthesisUnavailable:async(a,d,c)=>{let u=await this.store.read(a).catch(()=>{});if(u?.synopsis&&u.summarizedThroughEntry!==void 0){this.logger?.info(`agent switch: synthesis produced no new artifact for sessionId=${a} (${c}); swapping to ${d} on the persisted synopsis`),await this.dispatchSynthesisSwap(a,u.synopsis,u.summarizedThroughEntry,d);return}let l=(await this.histories.load(a).catch(()=>[])).length;this.logger?.warn(`agent switch: synthesis unavailable for sessionId=${a} (${c}); swapping to ${d} on verbatim tail`),await this.dispatchSynthesisSwap(a,void 0,l,d)}}),this.refreshAgentCatalog()}registry;sessions=new Map;resurrectionInflight=new Map;snapshotInFlight=new Set;snapshotPending=new Set;workspaceSnapshotsDisabled=!1;driftNoticed=new Map;pendingAuthAgents=new Map;spawner;store;tombstones;histories;idleTimeoutMs;orphanTimeoutMs;sessionDefaults;synopsisAgent;synopsisModel;compactionAgent;compactionModel;defaultTransformers;idleEventTimeoutMs;sessionHistoryMaxEntries;metaWriteQueues=new Map;workspaceQueues=new Map;listCache=new Map;static LIST_CACHE_TTL_MS=500;logger;npmRegistry;extensionCommands;defaultCwd;synopsisCoordinator;pendingDeletions=new Map;pendingSwapDisposers=new Map;rollbackLocks=new Set;compactionTailK=20;agentCatalog=[];async dispatchSynthesisSwap(e,t,n,r,o){let i=this.get(e);if(t===void 0&&r===void 0)return;if(!i){if(this.logger?.info(`compaction: persisted artifact for cold session sessionId=${e}`),t===void 0)return;await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:n});return}let a=this.compactionTailK;try{if(await i.isQuiescedForSwap()){this.pendingSwapDisposers.get(e)?.(),this.pendingSwapDisposers.delete(e),await this.performSynthesisSwap(i,t,a,n,r,o);return}this.pendingSwapDisposers.get(e)?.(),this.logger?.info(`compaction: session not quiesced, parking onceIdle swap sessionId=${e}`),this.emitSwapPhase(e,r,{phase:"deferred"});let c=i.onceIdle(()=>{this.pendingSwapDisposers.delete(e),this.onIdleAttemptSwap(e)});this.pendingSwapDisposers.set(e,c)}catch(d){this.logger?.warn(`compaction: dispatch failed for sessionId=${e}: ${d instanceof Error?d.message:String(d)}, leaving session as-is`)}}async onIdleAttemptSwap(e){let t=this.get(e);if(!t)return;let n=this.compactionTailK;try{if(!await t.isQuiescedForSwap()){let d=await this.store.read(e).catch(()=>{});d?.synopsis&&d.summarizedThroughEntry!==void 0?this.dispatchSynthesisSwap(e,d.synopsis,d.summarizedThroughEntry,d.pendingAgentSwap):d?.pendingAgentSwap&&this.dispatchSynthesisSwap(e,void 0,(await this.histories.load(e).catch(()=>[])).length,d.pendingAgentSwap);return}let o=await this.store.read(e).catch(()=>{});if(!o?.synopsis||o.summarizedThroughEntry===void 0){if(o?.pendingAgentSwap){let d=(await this.histories.load(e).catch(()=>[])).length;this.logger?.info(`compaction: no artifact for sessionId=${e}, swapping to ${o.pendingAgentSwap} on verbatim tail`),await this.performSynthesisSwap(t,void 0,n,d,o.pendingAgentSwap);return}this.logger?.warn(`compaction: persisted artifact missing for sessionId=${e}, abandoning swap`),t.compactionState=void 0,await this.mutateRecord(e,{},["compactionState"]);return}let i=o.pendingAgentSwap,a=await this.histories.load(e).catch(()=>[]);if(a.length>o.summarizedThroughEntry){this.logger?.info(`compaction: history grew during deferral (have=${a.length} artifact=${o.summarizedThroughEntry}), rescheduling synopsis sessionId=${e}`),i?this.synopsisCoordinator.scheduleCompaction(e,{targetAgentId:i}):this.synopsisCoordinator.scheduleCompaction(e);return}await this.performSynthesisSwap(t,o.synopsis,n,o.summarizedThroughEntry,i,o.compactionState?.runId)}catch(r){this.logger?.warn(`compaction: onIdleAttemptSwap failed for sessionId=${e}: ${r instanceof Error?r.message:String(r)}`)}}async recordSynopsisFor(e){let t=await this.store.read(e).catch(()=>{});return t?.synopsis?{synopsis:t.synopsis}:{}}async performSynthesisSwap(e,t,n,r,o,i){try{let a=o?Math.min(t===void 0?ym:5,n):0;await e.swapUpstream({...t!==void 0?{artifact:t}:{},tailK:n,tailFloor:a,summarizedThroughEntry:r,...o?{newAgentId:o}:{},...i!==void 0?{runId:i}:{}}),o?await this.mutateRecord(e.sessionId,{},["pendingAgentSwap"]):(e.compactionState=void 0,await this.mutateRecord(e.sessionId,{},["compactionState"]))}catch(a){this.logger?.warn(`compaction: swap failed for sessionId=${e.sessionId}: ${a instanceof Error?a.message:String(a)}, leaving session as-is`)}finally{this.invalidateListCache()}}async refreshAgentCatalog(){try{let{agents:e}=await Dt(this.registry);this.agentCatalog=e.map(t=>({id:t.id,name:t.name,...t.description!==void 0?{description:t.description}:{}}))}catch{}}async adoptWorkspace(e,t,n){let r=t.label;if(r===void 0)throw new Error("workspace.adopt requires workspace.label");let o=this.liveSessionsWithLabel(n.cwd,r)[0]?.workspace,i=o!==void 0?this.asWorkspace(o):(await e.listWorkspaces(n.cwd).catch(()=>[])).find(a=>a.label===r);if(i===void 0)throw new Error(`cannot adopt workspace "${r}": no workspace by that name derived from ${$(n.cwd)}`);return await this.enqueueKeyed(this.workspaceQueues,i.path,async()=>(e.capabilities().locking&&await e.lock(i,`session ${n.title??"live"}`).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},...o?.clean!==void 0?{clean:o.clean}:{}}}))}async resolveWorkspace(e){let t=e.workspace;if(t===void 0)return{cwd:e.cwd};let n=re(t.provider);if(n===void 0){let u=`unknown workspace provider "${t.provider}"`;if(t.required===!0)throw new Error(`isolation required but unavailable: ${u}`);return this.logger?.warn?.(`session workspace: ${u}; running in ${e.cwd}`),{cwd:e.cwd,isolationError:u}}if(t.adopt===!0)return await this.adoptWorkspace(n,t,e);let r=t.label??`s-${Ct().slice(0,8)}`,o=await n.createWorkspace({sourceCwd:e.cwd,label:r,...t.from!==void 0?{from:t.from}:{}}).catch(u=>({ok:!1,reason:String(u)}));if(!o.ok){if(t.required===!0)throw new Error(`isolation required but unavailable: ${o.reason}`);return this.logger?.warn?.(`session workspace: ${o.reason}; falling back to ${e.cwd} (unisolated)`),{cwd:e.cwd,isolationError:o.reason}}let i=o.workspace;n.capabilities().locking&&await n.lock(i,`session ${e.title??"live"}`).catch(()=>{});let a=await Ts(i.sourceCwd).catch(()=>({})),d,c=await this.materializeNestedTrees(i);if(c!==void 0&&this.logger?.info?.(`session workspace: ${c} in ${i.path}`),a.carry!==void 0&&a.carry.length>0){let u=await No(i.sourceCwd,i.path,a.carry).catch(()=>{});u!==void 0&&u.copied.length>0&&this.logger?.info?.(`session workspace: carried ${u.copied.length} file(s) into ${i.path}`)}if(a.postCreate!==void 0){let u=await Ps(a.postCreate,{workspacePath:i.path,sourceCwd:i.sourceCwd,label:i.label,...a.hookTimeoutSeconds!==void 0?{timeoutSeconds:a.hookTimeoutSeconds}:{}});u.ok||(d=`postCreate failed: ${u.reason??"unknown"}`,this.logger?.warn?.(`session workspace: ${d} (${i.path})`))}return i.snapshot!==void 0&&await n.retainSnapshot(i,this.startRefFor(i.label),i.snapshot).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},clean:!0},...d!==void 0?{isolationError:d}:{}}}async create(e){let t=await this.registry.getAgent(e.agentId);t&&t.id!==e.agentId&&(e={...e,agentId:t.id});let n=`${ye}${Ct()}`,r=await this.resolveWorkspace(e),o=r.cwd,i=await this.bootstrapAgent({agentId:e.agentId,cwd:o,agentArgs:e.agentArgs,mcpServers:e.mcpServers,model:e.model,configDefaults:e.configDefaults,onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,selfSessionId:n});if(e.transformChain&&e.transformChain.length>0){let d={...i.agentCapabilities??{}};for(let c of e.transformChain)if(c.intercepts.has("agent:initialize"))try{let u=await c.connection.request("hydra-acp/transformer/message",{token:`t_${Ct()}`,phase:"response",method:"initialize",direction:"agent\u2192daemon",sessionId:"(pre-session)",envelope:d});u.action==="stop"&&u.payload&&(d=u.payload)}catch{}i.agentCapabilities=d}let a=new Gt({sessionId:n,cwd:o,...r.workspace!==void 0?{workspace:r.workspace}:{},...r.isolationError!==void 0?{workspaceError:r.isolationError}:{},agentId:e.agentId,agent:i.agent,upstreamSessionId:i.upstreamSessionId,agentMeta:i.agentMeta,agentCapabilities:i.agentCapabilities,...i.modelVerb?{modelVerb:i.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,orphanTimeoutMs:this.orphanTimeoutMs,idleEventTimeoutMs:this.idleEventTimeoutMs,logger:this.logger,spawnReplacementAgent:d=>this.bootstrapAgent({...d,mcpServers:d.mcpServers??[],selfSessionId:n}),loadExistingAgentSession:(d,c)=>this.bootstrapAgentLoad(d,{...c,mcpServers:c.mcpServers??[],selfSessionId:n}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:i.initialModel,currentMode:i.initialMode,agentModes:i.initialModes,agentModels:i.initialModels,agentConfigOptions:i.initialConfigOptions,transformChain:e.transformChain,parentSessionId:e.parentSessionId,originatingClient:e.originatingClient,interactive:e.interactive,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(a.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(a),scheduleCompaction:d=>this.scheduleCompaction(a.sessionId,d),resolveAgentId:async d=>(await this.registry.getAgent(d))?.id,getCompactionState:()=>this.getCompactionState(a.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(a.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(a.sessionId),uncompactHook:()=>this.performUncompact(a.sessionId),forkHook:d=>this.forkSession(a.sessionId,d??{}),workspaceHook:(d,c,u)=>this.runWorkspaceAction(a.sessionId,d,c,u),onCompactionSwapHook:d=>{this.persistRollbackBreadcrumb(a.sessionId,d).catch(()=>{})},persistWatermarkHook:d=>{this.mutateRecord(a.sessionId,{summarizedThroughEntry:d}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(a.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});if(r.workspace!==void 0){let d=re(r.workspace.provider);d!==void 0&&d.capabilities().supports.environmentNotes&&(a.workspaceNotes=await d.environmentNotes({path:r.workspace.path,sourceCwd:r.workspace.sourceCwd,label:r.workspace.label,provider:r.workspace.provider,...r.workspace.snapshot!==void 0?{snapshot:r.workspace.snapshot}:{},...r.workspace.vcs!==void 0?{vcs:r.workspace.vcs}:{}}).catch(()=>[]))}return await this.attachManagerHooks(a),a}async resurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t){if(t.upstreamSessionId!==e.upstreamSessionId){let o=new Error(`session ${e.hydraSessionId} already exists with a different upstream id`);throw o.code=x.AlreadyAttached,o}return t}let n=this.resurrectionInflight.get(e.hydraSessionId);if(n)return n;let r=this.doResurrect(e);this.resurrectionInflight.set(e.hydraSessionId,r);try{return await r}finally{this.resurrectionInflight.delete(e.hydraSessionId)}}async doResurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t)return t;let n=await this.registry.getAgent(e.agentId);if(!n){let k=new Error(`agent ${e.agentId} not found in registry; cannot resurrect`);throw k.code=x.AgentNotInstalled,k}if(e.upstreamSessionId==="")return this.doResurrectFromImport(e);if(!await this.dirExists(e.cwd))return this.doResurrectFromImport(e);let r=await Me(n,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),o=Zn(e.hydraSessionId,e.forwardedEnv),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...o?{extraEnv:o}:{}}),a;try{let k=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:Ht,clientInfo:{name:"hydra",version:ue}});a=k.agentCapabilities,i.authMethods=Nn(k.authMethods),i.steeringSupported=Fn(k)}catch(k){throw await i.kill().catch(()=>{}),ht(k,i)}let d;try{let k=zo(n,{model:e.currentModel});d=await i.connection.request("session/load",{sessionId:e.upstreamSessionId,cwd:e.cwd,mcpServers:e.mcpServers??[],...k&&{_meta:k}})}catch(k){if(k&&typeof k=="object"&&k.code===x.AuthRequired)throw await i.kill().catch(()=>{}),ht(k,i);return process.stderr.write(`session/load failed for upstream ${e.upstreamSessionId} on ${e.agentId} (${k.message}); recovering via import-reseed
160
160
  `),await i.kill().catch(()=>{}),this.doResurrectFromImport(e)}if(e.pendingHistorySync===!0)this.clearPendingHistorySync(e.hydraSessionId).catch(()=>{});else{let k=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain1 dropped ${k} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let c=Ko(d??{}),u=e.agentModes??gt(Go(d??{}));this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedMode=${JSON.stringify(e.currentMode)} agentReportedMode=${JSON.stringify(c)} advertisedModes=${JSON.stringify(u?.map(k=>k.id))}`);let l=await ut({agent:i,upstreamSessionId:e.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:c,advertisedModes:u,logger:this.logger});this.logger?.info(`resurrect: effectiveMode=${JSON.stringify(l)} for sessionId=${e.hydraSessionId}`);let p=Jo(d??{}),f=gt(Vo(d??{}))??e.agentModels;if(this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedModel=${JSON.stringify(e.currentModel)} agentReportedModel=${JSON.stringify(p)} advertisedModels=${JSON.stringify(f?.map(k=>k.modelId))}`),e.pendingHistorySync!==!0){let k=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain2 (post-mode-restore) dropped ${k} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let h=Ut(d),w=await lt({agent:i,upstreamSessionId:e.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:p,...h?{modelVerb:h}:{},logger:this.logger}),m=w.modelId,g=gt(en(Zt(w.result)?w.result:d??{}));if(g=gt(await this.restoreConfigOptionValues(i,e.upstreamSessionId,e.configOptionValues,g??[])),e.pendingHistorySync!==!0){let k=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain3 (post-model-restore) dropped ${k} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let y=new Gt({sessionId:e.hydraSessionId,cwd:e.cwd,...e.workspace!==void 0?{workspace:e.workspace}:{},agentId:e.agentId,agent:i,upstreamSessionId:e.upstreamSessionId,agentMeta:d?._meta,agentCapabilities:a,...h?{modelVerb:h}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,orphanTimeoutMs:this.orphanTimeoutMs,logger:this.logger,spawnReplacementAgent:k=>this.bootstrapAgent({...k,mcpServers:k.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(k,v)=>this.bootstrapAgentLoad(k,{...v,mcpServers:v.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:m,currentMode:l,currentUsage:e.currentUsage,reloadsUpstreamLedger:!0,agentCommands:e.agentCommands,agentModes:u,agentModels:f,agentConfigOptions:g,summarizedThroughEntry:e.summarizedThroughEntry,compactionState:e.compactionState,firstPromptSeeded:!!e.title,upstreamRespawned:!0,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,lastTurnEndedAt:e.lastTurnEndedAt,readAt:e.readAt,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(y.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(y),scheduleCompaction:k=>this.scheduleCompaction(y.sessionId,k),resolveAgentId:async k=>(await this.registry.getAgent(k))?.id,getCompactionState:()=>this.getCompactionState(y.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(y.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(y.sessionId),uncompactHook:()=>this.performUncompact(y.sessionId),forkHook:k=>this.forkSession(y.sessionId,k??{}),workspaceHook:(k,v,S)=>this.runWorkspaceAction(y.sessionId,k,v,S),onCompactionSwapHook:k=>{this.persistRollbackBreadcrumb(y.sessionId,k).catch(()=>{})},persistWatermarkHook:k=>{this.mutateRecord(y.sessionId,{summarizedThroughEntry:k}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(y.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(y),y}async doResurrectFromImport(e){let t=await this.resolveResurrectTarget(e.cwd,e.workspace),n=t.cwd,r=await this.bootstrapAgent({agentId:e.agentId,cwd:n,agentArgs:e.agentArgs,mcpServers:e.mcpServers??[],onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,model:e.currentModel}),o=e.agentModes??r.initialModes,i=await ut({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:r.initialMode,advertisedModes:o,logger:this.logger}),a=e.agentModels??r.initialModels,d=await lt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:r.initialModel,...r.modelVerb?{modelVerb:r.modelVerb}:{},logger:this.logger}),c=d.modelId,u=Zt(d.result)?gt(en(d.result)):void 0;u=gt(await this.restoreConfigOptionValues(r.agent,r.upstreamSessionId,e.configOptionValues,u??r.initialConfigOptions??[])),r.agent.connection.drainBuffered("session/update");let l=new Gt({sessionId:e.hydraSessionId,cwd:n,...t.workspace!==void 0?{workspace:t.workspace}:{},agentId:e.agentId,agent:r.agent,upstreamSessionId:r.upstreamSessionId,agentMeta:r.agentMeta,agentCapabilities:r.agentCapabilities,...r.modelVerb?{modelVerb:r.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,orphanTimeoutMs:this.orphanTimeoutMs,logger:this.logger,spawnReplacementAgent:p=>this.bootstrapAgent({...p,mcpServers:p.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(p,f)=>this.bootstrapAgentLoad(p,{...f,mcpServers:f.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:c,currentMode:i,currentUsage:e.currentUsage,agentCommands:e.agentCommands,agentModes:o,agentModels:a,agentConfigOptions:u??r.initialConfigOptions,summarizedThroughEntry:e.summarizedThroughEntry,firstPromptSeeded:!!e.title,upstreamRespawned:!0,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,lastTurnEndedAt:e.lastTurnEndedAt,readAt:e.readAt,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(l.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(l),scheduleCompaction:p=>this.scheduleCompaction(l.sessionId,p),resolveAgentId:async p=>(await this.registry.getAgent(p))?.id,getCompactionState:()=>this.getCompactionState(l.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(l.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(l.sessionId),uncompactHook:()=>this.performUncompact(l.sessionId),forkHook:p=>this.forkSession(l.sessionId,p??{}),workspaceHook:(p,f,h)=>this.runWorkspaceAction(l.sessionId,p,f,h),onCompactionSwapHook:p=>{this.persistRollbackBreadcrumb(l.sessionId,p).catch(()=>{})},persistWatermarkHook:p=>{this.mutateRecord(l.sessionId,{summarizedThroughEntry:p}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(l.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(l),e.forkedFromSessionId&&e.forkSynthesisState==="running"?this.logger?.info(`fork ${l.sessionId}: synthesis in flight \u2014 skipping seed, recall available`):e.forkedFromSessionId&&(e.synopsis||(e.summarizedThroughEntry??0)>0)?l.seedFromFork(e.synopsis).catch(()=>{}):l.seedFromImport().catch(()=>{}),l}async dirExists(e){try{return(await Rt.stat(e)).isDirectory()}catch{return!1}}async reapIfOrphanedNonInteractive(e){let t=this.sessions.get(e);if(!(!t||t.attachedCount>0)&&t.interactive!==!0){if(t.hasWorkInFlight){this.logger?.info(`deferring reap of ${e}: work still in flight after detach`),t.onceIdle(n=>{this.reapIfOrphanedNonInteractive(n.sessionId).catch(()=>{})});return}this.logger?.info(`reaping orphaned non-interactive session ${e} (agent killed, cold record kept)`),await t.close({deleteRecord:!1,by:"reap-orphaned"}).catch(()=>{})}}async resolveResurrectTarget(e,t){if(await this.dirExists(e))return t!==void 0?{cwd:e,workspace:t}:{cwd:e};if(t!==void 0){let n=await this.recoverWorkspace(t);if(n!==void 0)return{cwd:n.path,workspace:n}}return{cwd:ce(this.defaultCwd)}}async releaseWorkspace(e,t){let n=re(e.provider);if(n===void 0){this.logger?.warn?.(`session workspace: no provider "${e.provider}" to release ${e.path}; leaving it in place`);return}return this.enqueueKeyed(this.workspaceQueues,e.path,async()=>{let r=this.liveSessionsIn(e.path,t);if(r.length>0){this.logger?.info?.(`session workspace: keeping ${e.path} \u2014 ${r.length} live session(s) still in it`);return}await this.tearDownWorkspace(n,e,t)})}async syncWorkspaceFromSource(e,t,n){let r=this.liveSessionsIn(t.path,e.sessionId);if(r.length>0)throw new Error(`${$(t.path)} is shared with ${r.map(f=>et(f.sessionId)).join(", ")}, and a sync would move files under them. Sync it from a session that has it to itself.`);let o=await e.quiesceBlocker();if(o!==void 0)throw new Error(o);let i=re(t.provider);if(t.line===void 0||i?.capabilities().sharedHistory!==!0)throw new Error(`workspace ${t.label} uses the "${t.provider}" provider, which has no history to merge from \u2014 a sync needs a common base, and a copied directory has none. Land its work with \`/hydra workspace merge\` instead, or start a git-backed workspace if you need to track the source.`);let[a,d]=await Promise.all([i.currentState(t.sourceCwd),i.currentState(t.path)]);if(a===void 0||d===void 0)throw new Error("could not read the state of the source or the workspace");if(await i.contains(t.path,{state:a,within:d}))return{ok:!0,message:`Already up to date with ${$(t.sourceCwd)} (${a.slice(0,8)}).`};let c=await i.divergence(t.path,d,a),u=String(c?.behind??0),l=await i.integrate({into:t.path,from:a,message:`hydra: sync ${t.label} with the source`});if(!l.ok){let f=l.conflicts,h=await i.integrationInProgress(t.path);if(f.length===0&&!h){let m=await this.syncOverDirtyTree(t,{provider:i,before:d,sourceHead:a,incoming:u});if(m!==void 0)return m}let w=f.length>0?`
161
161
  ${f.map(m=>` ${m}`).join(`
162
162
  `)}`:` (${l.reason??"the integration failed"})`;return f.length===0?{ok:!1,message:`the source could not be merged into ${$(t.path)}; nothing changed.${w}
@@ -184,35 +184,35 @@ A sync was attempted first but was refused: ${C instanceof Error?C.message:Strin
184
184
  Nothing was committed: review it with \`git -C ${n} diff --cached\` and commit it however you like. The workspace and its history are untouched.`,warnings:y}}async leaveWorkspace(e,t,n){let r=n.exit!=="detached",o=re(t.provider),i={path:t.path,sourceCwd:t.sourceCwd,label:t.label,provider:t.provider,...t.snapshot!==void 0?{snapshot:t.snapshot}:{},...t.vcs!==void 0?{vcs:t.vcs}:{}},a=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:t.sourceCwd,workspace:void 0,historyLength:a.length,note:`Returned to the source tree at ${t.sourceCwd}`+(n.exit==="landed"?" after merging the workspace.":n.exit==="discarded"?" after discarding the workspace and its work.":" without merging."),...await this.recordSynopsisFor(e.sessionId),left:{path:t.path,removed:r}}),await this.mutateRecord(e.sessionId,{cwd:e.cwd},["workspace"]),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"left",cwd:e.cwd,sourceCwd:t.sourceCwd,integrated:n.exit==="landed"}),o!==void 0&&await this.enqueueKeyed(this.workspaceQueues,t.path,async()=>{let d=this.liveSessionsIn(t.path,e.sessionId);if(d.length>0){this.logger?.info?.(`session workspace: ${e.sessionId} left ${t.path}; ${d.length} live session(s) remain, so it stays`);return}await this.reclaimAfterLastLeaver(o,i,t,e.sessionId,n)})}async reclaimAfterLastLeaver(e,t,n,r,o){await e.unlock(t).catch(()=>{});for(let i of[this.startRefFor(n.label),this.baselineRefFor(n.label)])await e.dropSnapshotRef(t,i).catch(()=>{});o.exit!=="detached"&&(o.exit==="landed"&&await e.dropSnapshotRef(t,this.snapshotRefFor(n.label)).catch(()=>{}),await e.removeWorkspace(t,{force:!0,discardLine:!0}).catch(()=>{}))}async joinDivergence(e,t,n){let[r,o]=await Promise.all([e.captureWorkingState(t,"hydra: source state at join").catch(()=>{}),e.captureWorkingState(n.path,"hydra: workspace state at join").catch(()=>{})]);if(r===void 0||o===void 0)return`could not compare ${$(t)} with ${$(n.path)}, so refusing to join a workspace that may not match your tree`;let i=await Promise.all([r,o].map(a=>e.contentId(t,a).catch(()=>{})));if(!(i[0]!==void 0&&i[0]===i[1]))return`${$(t)} and ${$(n.path)} have diverged, and joining does not carry work across \u2014 whichever side you are not in would be left behind. Land or stash one of them first: \`git -C ${t} stash\` if the difference is yours, or \`/hydra workspace merge\` from the session already in there if it is theirs.`}liveSessionsWithLabel(e,t){let n=[];for(let r of this.sessions.values()){let o=r.workspace;o===void 0||o.sourceCwd!==e||(o.label===t||o.requestedLabel===t)&&n.push(r)}return n}async joinWorkspace(e,t,n,r){let o=re(n.provider);if(o===void 0)throw new Error(`no provider "${n.provider}" to join that workspace with`);if(o.capabilities().supports.captureWorkingState){let i=await this.joinDivergence(o,r,n);if(i!==void 0)throw new Error(i)}return await this.enqueueKeyed(this.workspaceQueues,n.path,async()=>{if(this.sessions.get(t.sessionId)?.workspace?.path!==n.path)throw new Error(`${$(n.path)} was released while joining it; run the command again`);e.broadcastWorkspacePhase({phase:"swapping"});let i=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:n.path,workspace:{path:n.path,sourceCwd:n.sourceCwd,label:n.label,...n.requestedLabel!==void 0?{requestedLabel:n.requestedLabel}:{},provider:n.provider,...n.snapshot!==void 0?{snapshot:n.snapshot}:{},...n.line!==void 0?{line:n.line}:{},...n.vcs!==void 0?{vcs:{...n.vcs}}:{}},historyLength:i.length,note:`Continuing in an isolated workspace at ${n.path}, derived from ${r}, shared with another session.`,...await this.recordSynopsisFor(e.sessionId)}),await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache();let a=n.line;e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:n.sourceCwd,label:n.label,...a!==void 0?{branch:a}:{}});let d=this.liveSessionsIn(n.path,e.sessionId).map(u=>et(u.sessionId)),c=[`Joined workspace ${$(n.path)}`,` source: ${$(n.sourceCwd)}`];return a!==void 0&&c.push(` branch: ${a}`),c.push(` shared with: ${d.join(", ")}`),c.push(" your edits will interleave with that session's"),c.push("Use `/hydra workspace stop` to leave; the work lands when the last session leaves."),c.join(`
185
185
  `)})}async startWorkspace(e,t,n){if(e.workspace!==void 0)throw new Error(`already isolated in ${$(e.workspace.path)}. Use \`/hydra workspace stop\` to merge and return first, or \`detach\` to leave it behind.`);let r=e.cwd,o=re();if(o===void 0)throw new Error("no workspace provider available");let i=await e.quiesceBlocker();if(i!==void 0)throw new Error(i);let a=o.capabilities();if(t!==void 0){let b=this.liveSessionsWithLabel(r,t)[0];if(b!==void 0&&b.workspace!==void 0)return await this.joinWorkspace(e,b,b.workspace,r)}let d,c=[],u=!1,l=!1,p=[],f=[],h=n?.clean===!0;if(a.supports.captureWorkingState){let b=await o.status({path:r,sourceCwd:r,label:"source",provider:o.kind}).catch(()=>{});l=b!==void 0;let A=a.supports.nestedTrees&&b!==void 0&&b.changedPaths.length>0?await o.listNested(r).catch(()=>[]):[];if(b!==void 0&&b.changedPaths.length>0&&h)p=To(b.changedPaths,A);else if(b!==void 0&&b.changedPaths.length>0&&(c=To(b.changedPaths,A),f=await o.captureNested(r,A).catch(()=>[]),u=b.hasStagedWork===!0,d=await o.captureWorkingState(r,"hydra: work carried into workspace").catch(()=>{}),d===void 0))throw new Error("could not snapshot your uncommitted work, so refusing to move it. Commit or stash first.")}e.broadcastWorkspacePhase({phase:"provisioning"});let w=await o.createWorkspace({sourceCwd:r,label:t??`s-${e.sessionId.slice(-8)}`});if(!w.ok)throw e.broadcastWorkspacePhase({phase:"failed",error:w.reason}),new Error(w.reason);let m=w.workspace,g=this.startRefFor(m.label),y,k=!1,v=[];try{a.locking&&await o.lock(m,`session ${e.sessionId}`).catch(()=>{});let b=d??m.snapshot;if(b===void 0)throw new Error(`provider "${m.provider}" gave the workspace no base to anchor landing against`);await o.retainSnapshot(m,g,b),e.broadcastWorkspacePhase({phase:"setup"}),k=d!==void 0?await this.copyCarriedWork(m,d,r):!0;let A=await this.materializeNestedTrees(m);if(f.length>0){let R=await o.reproduceNested(m.path,r,f).catch(T=>({applied:[],failed:f.map(M=>({path:M.relPath,reason:T instanceof Error?T.message:String(T)}))}));R.failed.length>0&&(k=!1,v=R.failed)}y=await this.applyWorkspaceSetup(m,e.sessionId),A!==void 0&&(y=y===void 0?A:`${A}; ${y}`),e.broadcastWorkspacePhase({phase:"swapping"});let C=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:m.path,workspace:{path:m.path,sourceCwd:m.sourceCwd,label:m.label,...t!==void 0&&t!==m.label?{requestedLabel:t}:{},provider:m.provider,...m.snapshot!==void 0?{snapshot:m.snapshot}:{},...m.line!==void 0?{line:m.line}:{},...m.vcs!==void 0?{vcs:{...m.vcs}}:{},...d===void 0?{clean:!0}:{}},historyLength:C.length,note:`Continuing in an isolated workspace at ${m.path}, derived from ${r}.`,...await this.recordSynopsisFor(e.sessionId)})}catch(b){let A=await this.unwindStartWorkspace({provider:o,ws:m,startRef:g,carried:d}),C=b instanceof Error?b.message:String(b);throw e.broadcastWorkspacePhase({phase:"failed",error:C}),new Error(A===void 0?C:`${C}
186
186
  ${A}`)}await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:m.sourceCwd,label:m.label,...m.line!==void 0?{branch:m.line}:{}});let S=[`Moved into workspace ${$(m.path)}`,` source: ${$(r)}`];if(m.line!==void 0&&S.push(` branch: ${m.line}`),t!==void 0&&t!==m.label&&S.push(` note: "${t}" was already taken by a surviving branch, so this is "${m.label}"`),d!==void 0){S.push(k?` carried ${c.length} uncommitted file(s) in; the source tree is untouched:`:` WARNING: could not copy ${c.length} uncommitted file(s); the workspace starts from HEAD. They are untouched in the source tree:`);for(let b of It(c))S.push(` ${b}`);k&&u&&S.push(" staging did not come along; everything above is unstaged here");for(let b of v)S.push(` nested tree ${b.path}: ${b.reason}`)}else if(p.length>0){S.push(` started clean: ${p.length} uncommitted file(s) stayed in the source and did NOT come along:`);for(let b of It(p))S.push(` ${b}`)}else l&&S.push(" source tree was clean; nothing carried in");return y!==void 0&&S.push(` ${y}`),S.push("Use `/hydra workspace stop` to merge back and return."),S.join(`
187
- `)}async copyCarriedWork(e,t,n){let r=await this.patchFromSnapshot(n,t,e.provider);if(r===void 0)return!1;if(r.length===0)return!0;let o=re(e.provider);return o===void 0?!1:(await o.applyDelta(e.path,r)).ok}async patchFromSnapshot(e,t,n){let r=re(n);if(r===void 0)return;let o=await r.currentState(e);if(o!==void 0)return await r.captureDelta(e,o,t).catch(()=>{})}async unwindStartWorkspace(e){let{provider:t,ws:n,startRef:r,carried:o}=e;await t.unlock(n).catch(()=>{}),o!==void 0&&await t.dropSnapshotRef(n,r).catch(()=>{}),await t.removeWorkspace(n,{force:!0}).catch(()=>{})}async materializeNestedTrees(e,t){let n=re(e.provider);if(n?.capabilities().supports.nestedTrees!==!0)return;let r=await n.materializeNested({path:e.path,sourceCwd:e.sourceCwd,label:e.label,provider:n.kind},t).catch(o=>({ok:!1,count:0,reason:o instanceof Error?o.message:String(o)}));return r.ok?r.count>0?`populated ${r.count} nested tree(s)`:void 0:`nested trees FAILED: ${r.reason??"unknown"}`}async applyWorkspaceSetup(e,t){let n=await Ts(e.sourceCwd).catch(()=>({})),r=[];if(n.carry!==void 0&&n.carry.length>0){let o=await No(e.sourceCwd,e.path,n.carry).catch(()=>{});o!==void 0&&o.copied.length>0&&r.push(`carried ${o.copied.length} config file(s)`)}if(n.postCreate!==void 0){let o=await Ps(n.postCreate,{workspacePath:e.path,sourceCwd:e.sourceCwd,label:e.label,sessionId:t,...n.hookTimeoutSeconds!==void 0?{timeoutSeconds:n.hookTimeoutSeconds}:{}});r.push(o.ok?"ran postCreate":`postCreate FAILED: ${o.reason??"unknown"}`)}return r.length>0?r.join("; "):void 0}async deriveForkWorkspace(e,t){let n=re(e.provider);if(n===void 0)return;let r=n.capabilities(),o=r.sharedHistory?await n.currentState(e.path)??"":"",i=await n.createWorkspace({sourceCwd:e.sourceCwd,label:t,...o.length>0?{from:o}:{contentFrom:e.path}}).catch(d=>({ok:!1,reason:String(d)}));if(!i.ok){this.logger?.warn?.(`fork workspace: could not derive from ${e.path}: ${i.reason}`);return}let a=i.workspace;if(o.length>0&&r.supports.captureWorkingState){let d=await n.captureWorkingState(e.path,`hydra: fork carry from ${e.label}`).catch(()=>{});d!==void 0&&d!==o&&await this.copyUncommittedInto(e.path,a.path,o,d,a.provider).catch(()=>{})}return{path:a.path,sourceCwd:a.sourceCwd,label:a.label,provider:a.provider,...a.snapshot!==void 0?{snapshot:a.snapshot}:{},...a.line!==void 0?{line:a.line}:{},...a.vcs!==void 0?{vcs:{...a.vcs}}:{}}}async copyUncommittedInto(e,t,n,r,o){let i=re(o);if(i===void 0)return!1;let a=await i.captureDelta(e,n,r).catch(()=>{});return a===void 0||a.trim().length===0?!1:(await i.applyDelta(t,a,{stage:!0})).ok}async recoverWorkspace(e){let t=re(e.provider);if(t===void 0)return;let n={path:e.path,sourceCwd:e.sourceCwd,label:e.label,provider:e.provider,...e.snapshot!==void 0?{snapshot:e.snapshot}:{},...e.vcs!==void 0?{vcs:e.vcs}:{}};if(t.capabilities().supports.rematerialize){let o=await t.rematerialize(n).catch(i=>({ok:!1,reason:String(i)}));if(o.ok)return this.logger?.info?.(`session workspace: restored ${o.workspace.path} from retained state`),{...e,path:o.workspace.path};this.logger?.warn?.(`session workspace: could not restore: ${o.reason}`)}if(!await this.dirExists(e.sourceCwd))return;let r=await t.createWorkspace({sourceCwd:e.sourceCwd,label:`${e.label}-r`}).catch(o=>({ok:!1,reason:String(o)}));if(r.ok)return this.logger?.warn?.(`session workspace: ${e.path} is gone and could not be restored; resurrecting in a fresh workspace ${r.workspace.path} from ${e.sourceCwd}. Uncommitted work from the old workspace is not recoverable.`),{path:r.workspace.path,sourceCwd:r.workspace.sourceCwd,label:r.workspace.label,provider:r.workspace.provider,...r.workspace.snapshot!==void 0?{snapshot:r.workspace.snapshot}:{},...r.workspace.vcs!==void 0?{vcs:{...r.workspace.vcs}}:{}}}async syncFromAgent(e){let t=await this.registry.getAgent(e);if(!t){let w=new Error(`agent ${e} not found in registry`);throw w.code=x.AgentNotInstalled,w}let n=await Me(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:Ec.homedir(),plan:n}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:jt,clientInfo:{name:"hydra",version:ue}})}catch(w){throw await r.kill().catch(()=>{}),ht(w,r)}if(r.authMethods=Nn(o.authMethods),r.steeringSupported=Fn(o),(o.agentCapabilities??{}).sessionCapabilities?.list===void 0)throw await r.kill().catch(()=>{}),new Error(`agent ${e} does not advertise sessionCapabilities.list; cannot sync`);let a;try{a=await this.collectAgentSessions(r)}catch(w){throw await r.kill().catch(()=>{}),w}await r.kill().catch(()=>{});let d=new Map,c=Wr(t);d.set(e,c);let u=new Set;for(let w of this.sessions.values()){let m=await this.agentStoreKey(w.agentId,d);u.add(`${m}::${w.upstreamSessionId}`)}let l=await this.store.list().catch(()=>[]);for(let w of l){u.add(`${await this.agentStoreKey(w.agentId,d)}::${w.upstreamSessionId}`);for(let m of w.upstreamGenerations??[])u.add(`${await this.agentStoreKey(m.agentId,d)}::${m.upstreamSessionId}`)}let p=E.sessionsDir(),f=[],h=0;for(let w of a){let m=`${c}::${w.sessionId}`;if(u.has(m)){h+=1;continue}if(km(w.cwd,p)){h+=1;continue}let g=c,y=await this.tombstones.read(g,w.sessionId).catch(()=>{});if(!y&&c!==e&&(g=e,y=await this.tombstones.read(g,w.sessionId).catch(()=>{})),y){if(!Xd(y,w.updatedAt)){h+=1;continue}await this.tombstones.remove(g,w.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${w.sessionId} (upstream updatedAt advanced past ${y.upstreamUpdatedAt??"<unset>"})`)}u.add(m);let k=`${ye}${Ct()}`,v=new Date().toISOString(),S=w.updatedAt??v,b={sessionId:k,lineageId:xn(),upstreamSessionId:w.sessionId,agentId:e,cwd:w.cwd,pendingHistorySync:!0,interactive:!vm(w.title),createdAt:S,updatedAt:S};w.title!==void 0&&(b.title=w.title);let A=xo(b);await this.store.write(A),f.push({version:1,...A})}return{synced:f,skipped:h}}async listTombstones(e={}){let t=e.grep?.toLowerCase();return(await this.tombstones.list(e.agentId)).filter(r=>e.since===void 0||r.deletedAt>=e.since).filter(r=>t===void 0||[r.title,r.cwd,r.sessionId,r.upstreamSessionId].some(o=>o?.toLowerCase().includes(t))).sort((r,o)=>r.deletedAt<o.deletedAt?1:-1)}async undeleteSessions(e){let t=await this.tombstones.list(),n=[],r=[],o=[];for(let a of e){let d=t.filter(u=>u.upstreamSessionId===a),c=d.length>0?d:t.filter(u=>u.sessionId===a||u.sessionId===`${ye}${a}`);if(c.length===0){r.push({id:a,reason:"no tombstone found"});continue}if(c.length>1){r.push({id:a,reason:"ambiguous: several tombstones match; pass an upstream id",candidates:c.map(u=>u.upstreamSessionId)});continue}o.push({id:a,tombstone:c[0]})}let i=new Map;for(let a of o){let d=i.get(a.tombstone.agentId)??[];d.push(a),i.set(a.tombstone.agentId,d)}for(let[a,d]of i){let c=l=>{let{version:p,...f}=l;return this.tombstones.add(f).catch(()=>{})};for(let l of d)await this.tombstones.remove(a,l.tombstone.upstreamSessionId);let u;try{u=(await this.syncFromAgent(a)).synced}catch(l){for(let p of d)await c(p.tombstone),r.push({id:p.id,reason:`agent sync failed: ${l.message}`});continue}for(let l of d){let p=u.find(f=>f.upstreamSessionId===l.tombstone.upstreamSessionId);if(!p){await c(l.tombstone),r.push({id:l.id,reason:`agent ${a} no longer lists this session`});continue}n.push({id:l.id,sessionId:p.sessionId,upstreamSessionId:l.tombstone.upstreamSessionId})}}return{restored:n,failed:r}}async collectAgentSessions(e){let t=[],n,r=new Set;for(let o=0;o<100;o+=1){let i={};n!==void 0&&(i.cursor=n);let a=await e.connection.request("session/list",i),d=Array.isArray(a.sessions)?a.sessions:[];for(let c of d){if(typeof c.sessionId!="string"||typeof c.cwd!="string")continue;let u={sessionId:c.sessionId,cwd:c.cwd};typeof c.title=="string"&&(u.title=c.title),typeof c.updatedAt=="string"&&(u.updatedAt=c.updatedAt),t.push(u)}if(typeof a.nextCursor!="string"||a.nextCursor.length===0||r.has(a.nextCursor))break;r.add(a.nextCursor),n=a.nextCursor}return t}async applySeedModel(e,t,n,r,o){try{let{verb:i,result:a}=await ct({request:(d,c)=>e.connection.request(d,c),sessionId:t,modelId:n,...o?{verb:o}:{},logger:this.logger});return this.logger?.info(`${r}: ${i} accepted`),{accepted:!0,result:a}}catch(i){return this.logger?.warn(`${r} rejected by agent (${i.message}); session will use the agent's own default`),{accepted:!1}}}async applySeedMode(e,t,n,r){try{let o=await e.connection.request("session/set_mode",{sessionId:t,modeId:n});return this.logger?.info(`${r}: session/set_mode accepted`),{accepted:!0,result:o}}catch(o){return this.logger?.warn(`${r} rejected by agent (${o.message}); session will use the agent's own default mode`),{accepted:!1}}}async restoreConfigOptionValues(e,t,n,r){if(!n||Object.keys(n).length===0)return this.logger?.info(`resurrect: no persisted configOptionValues; agent reports ${JSON.stringify(Object.fromEntries(r.map(i=>[i.id,i.currentValue])))}`),r;let o=r;for(let[i,a]of Object.entries(n)){let d=`resurrect: persisted configOptionValues.${i}=${JSON.stringify(a)}`,c=o.find(p=>p.id===i);if(!c){this.logger?.warn(`${d}: agent does not currently advertise configId=${i}; skipping session/set_config_option`);continue}if(a===c.currentValue){this.logger?.info(`${d}: agent already reports ${JSON.stringify(c.currentValue)}; nothing to restore`);continue}this.logger?.info(`${d}: agent reports ${JSON.stringify(c.currentValue)}; restoring`);let u=Jt(a,c.options.map(p=>p.value));if(u.kind!=="exact"&&u.kind!=="resolved"){this.logger?.warn(`${d} ${u.kind}; skipping session/set_config_option`);continue}let l=u.kind==="resolved"?u.modelId:a;try{let p=await e.connection.request("session/set_config_option",{sessionId:t,configId:i,value:l});this.logger?.info(`${d}: session/set_config_option accepted`),o=Zt(p)?en(p):o.map(f=>f.id===i?{...f,currentValue:l}:f)}catch(p){this.logger?.warn(`${d}: session/set_config_option rejected by agent (${p.message})`)}}return o}async bootstrapAgent(e){let t=await this.registry.getAgent(e.agentId);if(!t){let i=new Error(`agent ${e.agentId} not found in registry`);throw i.code=x.AgentNotInstalled,i}let n=await Me(t,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),r=Zn(e.selfSessionId,e.forwardedEnv),o=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:n,...r?{extraEnv:r}:{}});try{let i=await o.connection.request("initialize",{protocolVersion:1,clientCapabilities:jt,clientInfo:{name:"hydra",version:ue}}),a=i.agentCapabilities;o.authMethods=Nn(i.authMethods),o.steeringSupported=Fn(i);let d=zo(t),c=await o.connection.request("session/new",{cwd:e.cwd,mcpServers:e.mcpServers??[],...d&&{_meta:d}}),u=c.sessionId;if(typeof u!="string")throw new Error(`agent ${e.agentId} returned a non-string sessionId from session/new`);let l=Jo(c),p=Vo(c),f=Ut(c),h=ua(this.sessionDefaults,t),w=h?.value,m=e.configDefaults,g=h?.from??e.agentId,y=e.model??m?.model??w?.model,k;if(y&&y!==l){let R=zt(y,p),T=e.model!==void 0?`model=${JSON.stringify(y)}`:m?.model!==void 0?`configDefaults.model=${JSON.stringify(y)}`:`sessionDefaults[${g}].model=${JSON.stringify(y)}`;if(R.kind==="exact"||R.kind==="none"){let M=await this.applySeedModel(o,u,y,T,f);M.accepted&&(l=y,k=M.result)}else if(R.kind==="resolved")if(R.modelId===l)l=R.modelId;else{let M=await this.applySeedModel(o,u,R.modelId,`${T} resolved to ${JSON.stringify(R.modelId)}`,f);M.accepted&&(l=R.modelId,k=M.result)}else if(R.kind==="ambiguous")this.logger?.warn(`${T} is ambiguous (trailing-segment matches [${R.candidates.join(", ")}]); skipping session/set_model, session will use ${JSON.stringify(l)}`);else{let M=p.map(j=>j.modelId).join(", ");this.logger?.warn(`${T} not in agent's availableModels ([${M}]); skipping session/set_model, session will use ${JSON.stringify(l)}`)}}let v=Go(c),S=Ko(c),b=m?.mode??w?.mode;if(b&&b!==S){let R=m?.mode!==void 0?`configDefaults.mode=${JSON.stringify(b)}`:`sessionDefaults[${g}].mode=${JSON.stringify(b)}`;if(v.length>0&&!v.some(T=>T.id===b)){let T=v.map(M=>M.id).join(", ");this.logger?.warn(`${R} not in agent's availableModes ([${T}]); skipping session/set_mode, session will use ${JSON.stringify(S)}`)}else{let T=await this.applySeedMode(o,u,b,R);T.accepted&&(S=b,Zt(T.result)&&(k=T.result))}}let A={...w??{},...m??{}};delete A.model,delete A.mode;let C=en(Zt(k)?k:c);if(Object.keys(A).length>0)for(let[R,T]of Object.entries(A)){let M=`sessionDefaults[${g}].${R}=${JSON.stringify(T)}`,j=C.find(z=>z.id===R);if(!j){this.logger?.warn(`${M}: agent does not currently advertise configId=${R}; skipping session/set_config_option`);continue}let U=Jt(T,j.options.map(z=>z.value));if(U.kind!=="exact"&&U.kind!=="resolved"){this.logger?.warn(`${M} ${U.kind}; skipping session/set_config_option`);continue}let W=U.kind==="resolved"?U.modelId:T;if(W!==j.currentValue)try{let z=await o.connection.request("session/set_config_option",{sessionId:u,configId:R,value:W});this.logger?.info(`${M}: session/set_config_option accepted`),Zt(z)?(C=en(z),k=z):C=C.map(D=>D.id===R?{...D,currentValue:W}:D)}catch(z){this.logger?.warn(`${M}: session/set_config_option rejected by agent (${z.message})`)}}return o.connection.dropBufferedWhere("session/update",R=>R?.update?.sessionUpdate==="config_option_update"),{agent:o,upstreamSessionId:u,agentMeta:c._meta,agentCapabilities:a,initialModel:l,initialModels:p.length>0?p:void 0,initialModes:v.length>0?v:void 0,initialMode:S,initialConfigOptions:C.length>0?C:void 0,modelVerb:f}}catch(i){throw await o.kill().catch(()=>{}),ht(Rc(i,o,e.agentId,{command:n.command,args:n.args,cwd:e.cwd}),o)}}async bootstrapAgentLoad(e,t){let n=await this.registry.getAgent(t.agentId);if(!n){let a=new Error(`agent ${t.agentId} not found in registry`);throw a.code=x.AgentNotInstalled,a}let r=await Me(n,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=Zn(t.selfSessionId,t.forwardedEnv),i=this.spawner({agentId:t.agentId,cwd:t.cwd,plan:r,...o?{extraEnv:o}:{}});try{let a=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:jt,clientInfo:{name:"hydra",version:ue}}),d=a.agentCapabilities;i.authMethods=Nn(a.authMethods),i.steeringSupported=Fn(a);let c=zo(n),u=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...c&&{_meta:c}}),l=Jo(u),p=gt(Vo(u)),f=Go(u),h=Ko(u),w=gt(en(u));return{agent:i,upstreamSessionId:e,agentMeta:u._meta,agentCapabilities:d,initialModel:l,initialModels:p,initialModes:f.length>0?f:void 0,initialMode:h,initialConfigOptions:w,modelVerb:Ut(u)}}catch(a){throw await i.kill().catch(()=>{}),ht(Rc(a,i,t.agentId,{command:r.command,args:r.args,cwd:t.cwd}),i)}}async rewindSession(e,t,n={}){let r=await this.store.read(e);if(!r){let a=new Error(`session not found: ${e}`);throw a.code=x.SessionNotFound,a}if(this.rollbackLocks.has(e)||r.compactionState!=null){let a=new Error("the session is being compacted or rolled back; try again when that finishes");throw a.code=x.InvalidRequest,a}let o=0,i=async()=>{let a=await this.histories.truncateAfterTurn(e,t);if(!a){let u=new Error(`keepThrough messageId not found in the session's recent history: ${t}`);throw u.code=x.InvalidParams,u}if(o=a.removed,o===0)return!1;let d=r.summarizedThroughEntry,c=d!==void 0&&a.kept<d;if(c){let u=this.get(e);u&&(u.summarizedThroughEntry=void 0)}return await this.mutateRecord(e,{},c?["rollbackBreadcrumb","synopsis","summarizedThroughEntry"]:["rollbackBreadcrumb"]),!0};this.rollbackLocks.add(e);try{let a=this.get(e);a?await a.rewind(t,i,n):await i()&&await this.mutateRecord(e,{upstreamSessionId:""})}finally{this.rollbackLocks.delete(e)}return{sessionId:e,removed:o}}async performUncompact(e){if(this.rollbackLocks.has(e))throw new Error("a rollback is already in progress for this session");let t=this.get(e);if(!t)throw new Error("session is not live \u2014 cannot roll back a cold session");let n=await this.store.read(e);if(!n)throw new Error("session record not found");let r=n.rollbackBreadcrumb;if(!r)throw new Error("no rollback breadcrumb found \u2014 either the session has not been compacted, the rollback window has closed (a new turn was dispatched), or a previous rollback already consumed the breadcrumb");let o=n.compactionState;if(o!=null)throw new Error(`compaction is in progress (status: ${o.status}) \u2014 wait for it to complete before rolling back`);if(!await t.isQuiescedForSwap())throw new Error("session is not quiesced for rollback \u2014 wait for in-flight work to complete");this.rollbackLocks.add(e);try{await t.rollbackToUpstream({previousUpstreamSessionId:r.previousUpstreamSessionId,previousSummarizedThroughEntry:r.previousSummarizedThroughEntry}),await this.mutateRecord(e,{summarizedThroughEntry:r.previousSummarizedThroughEntry},["synopsis","rollbackBreadcrumb"])}finally{this.rollbackLocks.delete(e)}}async bootstrapAgentForAuth(e,t){let n=this.pendingAuthAgents.get(e);if(n&&n.isAlive())return n;let r=await this.registry.getAgent(e);if(!r){let d=new Error(`agent ${e} not found in registry`);throw d.code=x.AgentNotInstalled,d}let o=await Me(r,[],{npmRegistry:this.npmRegistry}),i=t??ce(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:jt,clientInfo:{name:"hydra",version:ue}});a.authMethods=Nn(d.authMethods),a.steeringSupported=Fn(d)}catch(d){throw await a.kill().catch(()=>{}),ht(d,a)}return this.pendingAuthAgents.set(e,a),a.onExit(()=>{this.pendingAuthAgents.get(e)===a&&this.pendingAuthAgents.delete(e)}),a}async planSpawnForAgent(e){let t=await this.registry.getAgent(e);if(!t){let n=new Error(`agent ${e} not found in registry`);throw n.code=x.AgentNotInstalled,n}return Me(t,[],{npmRegistry:this.npmRegistry})}consumePendingAuthAgent(e){let t=this.pendingAuthAgents.get(e);if(t&&(this.pendingAuthAgents.delete(e),!!t.isAlive()))return t}getAgentForSession(e){return this.sessions.get(e)?.agent}async attachManagerHooks(e){e.onClose(({deleteRecord:t})=>{if(this.sessions.delete(e.sessionId),this.driftNoticed.delete(e.sessionId),this.invalidateListCache(),t||this.store.touch(e.sessionId).catch(()=>{}),t&&e.workspace!==void 0&&this.releaseWorkspace(e.workspace,e.sessionId).catch(()=>{}),t){if(e.upstreamSessionId){let r=tn({interactive:e.interactive,...e.originatingClient?{originatingClient:e.originatingClient}:{}},!0),o=this.tombstoneAllGenerations(e.sessionId,{agentId:e.agentId,upstreamSessionId:e.upstreamSessionId,upstreamUpdatedAt:new Date(e.updatedAt).toISOString(),cwd:e.cwd,...e.title!==void 0?{title:e.title}:{},...r!==void 0?{interactive:r}:{}},"user").catch(()=>{}).then(()=>this.store.delete(e.sessionId).catch(()=>{})).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===o&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,o);return}let n=this.store.delete(e.sessionId).catch(()=>{}).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===n&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,n);return}}),e.rewindHook=t=>this.rewindSession(e.sessionId,t,{afterCurrentTurn:!0}),e.onTitleChange(t=>{this.persistTitle(e.sessionId,t).catch(()=>{})}),e.onPriorityChange(t=>{this.persistPriority(e.sessionId,t).catch(()=>{})}),e.onAgentChange(({agentId:t,upstreamSessionId:n,...r})=>{this.persistAgentChange(e.sessionId,t,n,r).catch(()=>{})}),e.onModelChange(t=>{this.persistSnapshot(e.sessionId,{currentModel:t}).catch(()=>{})}),e.onModeChange(t=>{this.persistSnapshot(e.sessionId,{currentMode:t}).catch(()=>{})}),e.onInteractiveChange(t=>{this.persistSnapshot(e.sessionId,{interactive:t}).catch(()=>{})}),e.onUsageChange(t=>{this.persistSnapshot(e.sessionId,{currentUsage:Tc(t)}).catch(()=>{})}),e.onAgentCommandsChange(t=>{this.persistSnapshot(e.sessionId,{agentCommands:t.map(n=>({name:n.name,...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModesChange(t=>{this.persistSnapshot(e.sessionId,{agentModes:t.map(n=>({id:n.id,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModelsChange(t=>{this.persistSnapshot(e.sessionId,{agentModels:t.map(n=>({modelId:n.modelId,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onConfigOptionsChange(t=>{this.persistSnapshot(e.sessionId,{configOptionValues:Object.fromEntries(t.map(n=>[n.id,n.currentValue]))}).catch(()=>{})}),e.onAttentionFlagsChange(t=>{this.mutateRecord(e.sessionId,{attentionFlags:t}).catch(()=>{})}),e.onReadStateChange(t=>{this.invalidateListCache(),this.persistReadState(e.sessionId,t).then(()=>this.invalidateListCache()).catch(()=>{})}),this.sessions.set(e.sessionId,e),this.invalidateListCache(),await this.enqueueMetaWrite(e.sessionId,async()=>{let t=await this.store.read(e.sessionId),n=bm(e,t);await this.store.write(n)}).catch(t=>{this.logger?.warn(`failed to persist session record for ${e.sessionId}: ${t instanceof Error?t.message:String(t)}`)})}async getHistory(e){if(this.sessions.has(e))return this.histories.load(e).catch(()=>[]);if(await this.store.read(e))return this.histories.load(e).catch(()=>[])}async pageHistory(e,t){let n=await this.store.read(e);if(!this.sessions.has(e)&&!n)return;let r=this.sessions.get(e)?.side??n?.side,o=await this.histories.pageBefore(e,{...t,skip:a=>In(a.method,a.params),hydrate:!1}),i=Lt(o.entries,r);return{entries:await this.histories.hydrate(e,ds(i)),hasMore:o.hasMore&&i.length===o.entries.length}}async loadHistory(e,t={}){return this.histories.load(e,t)}async loadToolBlob(e,t){return gn(e,t)}async loadFromDisk(e){let t=await this.store.read(e);if(!t)return;let n=t.title;return n||(n=await this.deriveTitleFromHistory(e)),{hydraSessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,agentId:t.agentId,cwd:t.cwd,title:n,synopsis:t.synopsis,summarizedThroughEntry:t.summarizedThroughEntry,agentArgs:t.agentArgs,currentModel:t.currentModel,currentMode:t.currentMode,currentUsage:Sm(t.currentUsage),agentCommands:t.agentCommands,agentModes:t.agentModes,agentModels:t.agentModels,configOptionValues:t.configOptionValues,createdAt:t.createdAt,pendingHistorySync:t.pendingHistorySync,originatingClient:t.originatingClient,interactive:t.interactive,priority:t.priority,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,forwardedEnv:t.forwardedEnv,workspace:t.workspace,compactionState:t.compactionState,attentionFlags:t.attentionFlags?.filter(r=>!(r.source==="daemon"&&r.reason.startsWith("permission:")))}}async setForwardedEnv(e,t){if(t===void 0)return;let n=this.sessions.get(e);n&&(n.forwardedEnv=t),await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r)return;let o={...r,forwardedEnv:t};await this.store.write(o)})}async clearPendingHistorySync(e){await this.enqueueMetaWrite(e,async()=>{let t=await this.store.read(e);if(!t||t.pendingHistorySync!==!0)return;let n={...t};delete n.pendingHistorySync,await this.store.write(n)})}async deriveTitleFromHistory(e){let t=await this.histories.load(e).catch(()=>[]);for(let n of t){let r=n.params;if(r?.update?.sessionUpdate!=="prompt_received")continue;let o=r.update.sentBy;if(typeof o?.fromSession=="string"||typeof o?.clientId=="string"&&o.clientId.startsWith("transformer:"))continue;let i=St(r.update.prompt),a=vo(i,200);if(a&&!a.startsWith("/"))return a}}get(e){return this.sessions.get(e)}liveSessions(){return this.sessions.values()}setLiveConfig(e){e.sessionDefaults&&(this.sessionDefaults=e.sessionDefaults)}activeAgentVersions(){let e=new Map;for(let t of this.sessions.values()){let n=t.agent.installId,r=t.agent.version,o=e.get(n);o||(o=new Set,e.set(n,o)),o.add(r)}return e}async resolveCanonicalId(e){if(this.sessions.has(e)||await this.store.read(e))return e;if(e.startsWith(ye))return;let t=ye+e;if(this.sessions.has(t)||await this.store.read(t))return t}require(e){let t=this.sessions.get(e);if(!t){let n=new Error(`session ${e} not found`);throw n.code=x.SessionNotFound,n}return t}liveListEntry(e){return{sessionId:e.sessionId,upstreamSessionId:e.upstreamSessionId,cwd:e.cwd,workspace:e.workspace,workspaceError:e.workspaceError,title:e.title,agentId:e.agentId,currentModel:e.currentModel,currentUsage:e.currentUsage,parentSessionId:e.parentSessionId,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forkSynthesisState:e.forkSynthesisState,originatingClient:e.originatingClient,interactive:e.interactive,createdAt:new Date(e.createdAt).toISOString(),updatedAt:new Date(e.updatedAt).toISOString(),attachedClients:e.attachedCount,status:"warm",busy:e.turnStartedAt!==void 0,turnStartedAt:e.turnStartedAt,armedTasks:e.armedBackgroundTasks.length,...e.armedSince!==void 0?{armedSince:e.armedSince}:{},awaitingInput:e.awaitingInput,agentPid:e.agentPid,...Bt(e)}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Dn(t.sessionId),d=tn({interactive:t.interactive,...t.originatingClient?{originatingClient:t.originatingClient}:{}},a.hasContent),c=a.mtime??new Date(t.updatedAt).toISOString();return{sessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,cwd:t.cwd,title:t.title,agentId:t.agentId,currentModel:t.currentModel,currentUsage:t.currentUsage,parentSessionId:t.parentSessionId,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,originatingClient:t.originatingClient,interactive:d,priority:t.priority,createdAt:new Date(t.createdAt).toISOString(),updatedAt:c,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,turnStartedAt:t.turnStartedAt,armedTasks:t.armedBackgroundTasks.length,...t.armedSince!==void 0?{armedSince:t.armedSince}:{},awaitingInput:t.awaitingInput,...Bt(t)}}let n=await this.store.read(e).catch(()=>{});if(!n)return;let r=await Dn(n.sessionId),o=tn(n,r.hasContent),i=r.mtime??n.updatedAt;return{sessionId:n.sessionId,upstreamSessionId:n.upstreamSessionId,cwd:n.cwd,title:n.title,agentId:n.agentId,currentModel:n.currentModel,currentUsage:On(n.currentUsage),importedFromMachine:n.importedFromMachine,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,side:n.side,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:o,priority:n.priority,createdAt:n.createdAt,updatedAt:i,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,...Bt(n)}}async list(e={}){return(await this.listing(e)).entries}async listing(e={}){let t=`${e.cwd??""}|${e.includeNonInteractive?"1":"0"}|${e.status??""}`,n=Date.now(),r=this.listCache.get(t);if(r&&r.expiresAt>n)return r.promise;let o=this.listUncached(e);return this.listCache.set(t,{expiresAt:n+s.LIST_CACHE_TTL_MS,promise:o}),o.catch(()=>{let i=this.listCache.get(t);i&&i.promise===o&&this.listCache.delete(t)}),o}invalidateListCache(){this.listCache.clear()}async listUncached(e={}){let t=await this.store.cursor(),{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,cursor:t};let o=await this.store.list().catch(i=>{throw this.logger?.warn(`session list: store.list() failed: ${i?.message??String(i)}`),i});return n.push(...await this.coldRows(o,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,cursor:t}}async listSince(e,t){let{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,removed:[],cursor:await this.store.cursor()};let o=await this.store.listChangedSince(t);return n.push(...await this.coldRows(o.records,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,removed:o.removed,cursor:o.cursor}}async seedSessionIndex(){await this.store.ensureIndex();let e=await this.tombstones.list().catch(()=>[]);for(let t of e){if(t.sessionId===void 0)continue;let n=Date.parse(t.deletedAt);Number.isNaN(n)||await this.store.markDeleted(t.sessionId,n)}}static includeRow(e,t){return e.includeNonInteractive?!0:t===!0}async warmRows(e){let t=[],n=new Set,r=[...this.sessions.values()].filter(i=>Ac(e.cwd,i));if(e.status==="cold"){for(let i of r)n.add(i.sessionId);return{entries:t,liveIds:n}}let o=await Promise.all(r.map(i=>Dn(i.sessionId)));for(let i=0;i<o.length;i+=1){let a=r[i],d=o[i];n.add(a.sessionId);let c=tn({interactive:a.interactive,...a.originatingClient?{originatingClient:a.originatingClient}:{}},d.hasContent);if(!s.includeRow(e,c))continue;let u=d.mtime??new Date(a.updatedAt).toISOString();t.push({sessionId:a.sessionId,upstreamSessionId:a.upstreamSessionId,cwd:a.cwd,workspace:a.workspace,workspaceError:a.workspaceError,title:a.title,agentId:a.agentId,currentModel:a.currentModel,currentUsage:a.currentUsage,parentSessionId:a.parentSessionId,forkedFromSessionId:a.forkedFromSessionId,forkedFromMessageId:a.forkedFromMessageId,side:a.side,originatingClient:a.originatingClient,interactive:c,priority:a.priority,createdAt:new Date(a.createdAt).toISOString(),updatedAt:u,attachedClients:a.attachedCount,status:"warm",agentPid:a.agentPid,busy:a.turnStartedAt!==void 0,turnStartedAt:a.turnStartedAt,armedTasks:a.armedBackgroundTasks.length,...a.armedSince!==void 0?{armedSince:a.armedSince}:{},awaitingInput:a.awaitingInput,compactionState:a.compactionState,forkSynthesisState:a.forkSynthesisState,...Bt(a)})}return{entries:t,liveIds:n}}async coldRows(e,t,n){let r=[],o=e.filter(a=>!t.has(a.sessionId)&&Ac(n.cwd,a)),i=await Promise.all(o.map(a=>Dn(a.sessionId)));for(let a=0;a<o.length;a+=1){let d=o[a],c=i[a],u=tn(d,c.hasContent);if(!s.includeRow(n,u))continue;let l=c.mtime??d.updatedAt;r.push({sessionId:d.sessionId,upstreamSessionId:d.upstreamSessionId,cwd:d.cwd,workspace:d.workspace,title:d.title,agentId:d.agentId,currentModel:d.currentModel,currentUsage:On(d.currentUsage),importedFromMachine:d.importedFromMachine,importedFromUpstreamSessionId:d.importedFromUpstreamSessionId,parentSessionId:d.parentSessionId,forkedFromSessionId:d.forkedFromSessionId,forkedFromMessageId:d.forkedFromMessageId,side:d.side,originatingClient:d.originatingClient,interactive:u,priority:d.priority,createdAt:d.createdAt,updatedAt:l,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,compactionState:d.compactionState,forkSynthesisState:d.forkSynthesisState,...Bt(d)})}return r}async exportBundle(e,t={}){let n=await this.store.read(e);if(!n)return;let r;if(n.lineageId)r=n;else{let c=xn(),u={...n,lineageId:c};await this.enqueueMetaWrite(e,async()=>{let l=await this.store.read(e);l&&(l.lineageId||await this.store.write({...l,lineageId:c}))}).catch(()=>{}),r=u}let o=t.tools??"inline",i=t.includeArchivedHistory?await this.loadArchivedHistory(e,o):await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await xc(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let c of mc(i)){let u=await Ji(e,c);u&&(d[c]=u.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}async loadArchivedHistory(e,t){let n=await this.histories.loadArchives(e),r=await this.histories.load(e,{tools:"references",maxEntries:1/0}),o=[...n,...r];return t==="references"?o:this.histories.hydrate(e,o)}async importBundle(e,t={}){let n=await this.store.findByLineageId(e.session.lineageId);if(n){if(!t.replace){let i=new Error(`bundle already imported as ${n.sessionId}`);throw i.code=x.BundleAlreadyImported,i.existingSessionId=n.sessionId,i}let o=this.sessions.get(n.sessionId);return o&&await o.close({deleteRecord:!1,by:"bundle-import-overwrite"}).catch(()=>{}),await this.writeImportedRecord({sessionId:n.sessionId,bundle:e,preservedCreatedAt:n.createdAt,cwd:t.cwd}),{sessionId:n.sessionId,importedFromSessionId:e.session.sessionId,replaced:!0}}let r=`${ye}${Ct()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let n=await this.store.read(e);if(!n){let b=new Error(`source session not found: ${e}`);throw b.code=x.SessionNotFound,b}let r=t.agentId??n.agentId,o=r!==n.agentId;if(o&&!await this.registry.getAgent(r)){let A=new Error(`agent ${r} not found in registry`);throw A.code=x.AgentNotInstalled,A}let i=await this.histories.load(e).catch(()=>[]),a=i,d,c=t.mode??(t.side?"verbatim":"synthesis"),u,l,p,f=12e4;if(c==="verbatim")if(t.forkAt!==void 0){let b=_n(Bo(i),t.forkAt);if(b<0){let A=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw A.code=x.InvalidParams,A}d=t.forkAt,a=i.slice(0,b+1)}else{let b=Rm(i);b?(d=b.messageId,a=i.slice(0,b.index+1)):(d="",a=i.slice(0,0))}else{if(t.forkAt!==void 0&&t.forkAt!==""){let A=_n(Bo(i),t.forkAt);if(A<0){let C=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw C.code=x.InvalidParams,C}d=t.forkAt,a=i.slice(0,A+1)}else d="",a=i;let b=await this.registry.getAgent(r);if(!b){let A=new Error(`agent ${r} not found in registry`);throw A.code=x.AgentNotInstalled,A}p=b,l=n.currentModel,u="running"}let h=await xc(e),w=c==="synthesis",m={...n,lineageId:xn(),agentId:r,interactive:!1,...u!==void 0?{forkSynthesisState:u}:{},summarizedThroughEntry:a.length,...t.title!==void 0?{title:t.title}:{},currentUsage:void 0,...o?{currentModel:void 0,currentMode:void 0,agentCommands:void 0,agentModes:void 0,agentModels:void 0}:{},...t.model!==void 0?{currentModel:t.model}:{}},g=$n({record:m,history:a,promptHistory:h.length>0?h:void 0,hydraVersion:ue,machine:vt()}),y=`${ye}${Ct()}`,k=t.cwd,v;if(t.cwd===void 0&&n.workspace!==void 0){let b=await this.deriveForkWorkspace(n.workspace,`${n.workspace.label}-fork-${y.slice(-6)}`);b!==void 0?(v=b,k=b.path):(k=n.workspace.sourceCwd,this.logger?.warn?.(`fork ${y}: could not derive an isolated workspace from ${n.workspace.path}; running unisolated in ${k}`))}await this.writeImportedRecord({sessionId:y,bundle:g,cwd:k,...v!==void 0?{workspace:v}:{},forkedFromSessionId:e,forkedFromMessageId:d,...t.side!==void 0?{side:{...t.side.selection!==void 0?{selection:t.side.selection}:{},...Ma(a)}}:{},...u!==void 0?{forkSynthesisState:u}:{}});let S=w?(async()=>{try{let b=await Me(p,[],{npmRegistry:this.npmRegistry}),A=await Os({agentId:r,cwd:t.cwd??E.sessionDir(e),plan:b,history:a,modelId:l,sessionId:e,logger:this.logger,timeoutMs:f});A&&A.synopsis?await this.mutateRecord(y,{synopsis:A.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(y,{},["forkSynthesisState"]))}catch(b){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${b.message}`);try{await this.mutateRecord(y,{},["forkSynthesisState"])}catch(A){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${A.message}`)}}})():Promise.resolve();if(t.prompt!==void 0&&t.prompt.trim()!==""){let b=t.prompt;S.catch(()=>{}).then(()=>this.deliverHeadlessPrompt(y,b)).catch(A=>{this.logger?.warn(`forkSession(${e}): headless prompt delivery to ${y} failed: ${A.message}`)})}return{sessionId:y,forkedFromSessionId:e,forkedAt:d}}async deliverHeadlessPrompt(e,t){let n=await this.loadFromDisk(e);if(!n){this.logger?.warn(`deliverHeadlessPrompt: ${e} vanished before its prompt could be sent`);return}let r=this.sessions.get(e)??await this.resurrect(n),o=wm(),i={clientId:`fork-prompt-${Ct().slice(0,8)}`,connection:new qe(o),clientInfo:{name:"hydra-acp-fork",version:ue}};await r.attach(i,"none");try{await r.prompt(i.clientId,{sessionId:e,prompt:[{type:"text",text:t}]})}finally{r.detach(i.clientId),o.close()}}async writeImportedRecord(e){if(await this.histories.rewrite(e.sessionId,e.bundle.history),e.bundle.toolBlobs)for(let[o,i]of Object.entries(e.bundle.toolBlobs))await Vi(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await Rt.utimes(E.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await bc(E.tuiHistoryFile(e.sessionId),e.bundle.promptHistory).catch(()=>{});let n=new Date().toISOString(),r=e.forkedFromSessionId!==void 0;await this.enqueueMetaWrite(e.sessionId,async()=>{await this.store.write({sessionId:e.sessionId,lineageId:e.bundle.session.lineageId,upstreamSessionId:"",...r?{forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,...e.side!==void 0?{side:e.side}:{}}:{importedFromSessionId:e.bundle.session.sessionId,importedFromUpstreamSessionId:e.bundle.session.upstreamSessionId,importedFromMachine:e.bundle.exportedFrom.machine},agentId:e.bundle.session.agentId,cwd:e.cwd??e.bundle.session.cwd,workspace:e.workspace,title:e.bundle.session.title,synopsis:e.bundle.session.synopsis,summarizedThroughEntry:e.bundle.session.summarizedThroughEntry,...e.forkSynthesisState!==void 0?{forkSynthesisState:e.forkSynthesisState}:{},currentModel:e.bundle.session.currentModel,currentMode:e.bundle.session.currentMode,currentUsage:e.bundle.session.currentUsage,agentCommands:e.bundle.session.agentCommands,agentModes:e.bundle.session.agentModes,interactive:e.bundle.session.interactive,originatingClient:e.bundle.session.originatingClient,priority:e.bundle.session.priority,attentionFlags:[],createdAt:e.preservedCreatedAt??n,updatedAt:e.bundle.session.updatedAt})})}async agentStoreKey(e,t){let n=t.get(e);if(n!==void 0)return n;let r=e;try{let o=await this.registry.getAgent(e);o&&(r=Wr(o))}catch{}return t.set(e,r),r}async tombstoneAllGenerations(e,t,n){let r=await this.store.read(e).catch(()=>{}),o=new Map;for(let d of r?.upstreamGenerations??[])d.upstreamSessionId&&o.set(`${d.agentId}::${d.upstreamSessionId}`,{agentId:d.agentId,upstreamSessionId:d.upstreamSessionId});o.set(`${t.agentId}::${t.upstreamSessionId}`,{agentId:t.agentId,upstreamSessionId:t.upstreamSessionId});let i=new Date().toISOString(),a=new Map;for(let d of o.values())await this.tombstones.add({agentId:await this.agentStoreKey(d.agentId,a),upstreamSessionId:d.upstreamSessionId,sessionId:e,deletedAt:i,upstreamUpdatedAt:t.upstreamUpdatedAt,cwd:t.cwd,...t.title!==void 0?{title:t.title}:{},reason:n,...t.interactive!==void 0?{interactive:t.interactive}:{}}).catch(()=>{})}async deleteRecord(e,t="user"){let n=await this.store.read(e);if(!n)return!1;if(n.upstreamSessionId){let r=await Dn(e),o=tn(n,r.hasContent);await this.tombstoneAllGenerations(e,{agentId:n.agentId,upstreamSessionId:n.upstreamSessionId,upstreamUpdatedAt:n.updatedAt,cwd:n.cwd,...n.title!==void 0?{title:n.title}:{},...o!==void 0?{interactive:o}:{}},t)}return n.workspace!==void 0&&await this.releaseWorkspace(n.workspace,e).catch(()=>{}),await this.store.delete(e).catch(()=>{}),await this.histories.delete(e).catch(()=>{}),this.invalidateListCache(),!0}async waitForDeletion(e){let t=this.pendingDeletions.get(e);t&&await t}async isTombstoned(e,t){let n=await this.agentStoreKey(e,new Map);return(await this.tombstones.read(n,t).catch(()=>{})??(n!==e?await this.tombstones.read(e,t).catch(()=>{}):void 0))?.reason==="user"}async hasRecord(e){return await this.store.read(e).catch(()=>{})!==void 0}async isRetiredGeneration(e,t){let n=await this.store.read(e).catch(()=>{});return!n||n.upstreamSessionId===t?!1:(n.upstreamGenerations??[]).some(r=>r.upstreamSessionId===t)}async clearWorkspaceBinding(e){if(this.get(e)!==void 0)return"live";let t=await this.store.read(e).catch(()=>{});if(!t)return"missing";let n=t.workspace?.sourceCwd;return await this.mutateRecord(e,n!==void 0?{cwd:n}:{},["workspace"]),"cleared"}async setCwd(e,t){if(this.get(e)!==void 0)return"live";let n=await this.store.read(e).catch(()=>{});return n?n.workspace!==void 0?"bound":await this.dirExists(t)?(await this.mutateRecord(e,{cwd:t}),this.invalidateListCache(),"set"):"not-a-directory":"missing"}async setPriority(e,t){let n=this.get(e);if(n)return n.setPriority(t),!0;if(!await this.hasRecord(e))return!1;let r=t===void 0||t<=0?void 0:Math.floor(t);return await this.persistPriority(e,r),!0}async persistPriority(e,t){t===void 0?await this.mutateRecord(e,{},["priority"]):await this.mutateRecord(e,{priority:t}),this.invalidateListCache()}async setTitle(e,t){let n=this.get(e);return n?(await n.retitle(t),!0):await this.hasRecord(e)?(await this.persistTitle(e,t),!0):!1}async persistTitle(e,t){await this.mutateRecord(e,{title:t})}async persistSynopsis(e,t,n){await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:n})}async persistAgentChange(e,t,n,r={}){await this.mutateRecord(e,{agentId:t,upstreamSessionId:n},void 0,o=>({upstreamGenerations:Pc(o,t,n,void 0,r)}))}async persistSnapshot(e,t){let n={};t.currentModel!==void 0&&(n.currentModel=t.currentModel),t.currentMode!==void 0&&(n.currentMode=t.currentMode),t.currentUsage!==void 0&&(n.currentUsage=t.currentUsage),t.agentCommands!==void 0&&(n.agentCommands=t.agentCommands),t.agentModes!==void 0&&(n.agentModes=t.agentModes),t.agentModels!==void 0&&(n.agentModels=t.agentModels),t.configOptionValues!==void 0&&(n.configOptionValues=t.configOptionValues),t.interactive!==void 0&&(n.interactive=t.interactive),t.cwd!==void 0&&(n.cwd=t.cwd),await this.mutateRecord(e,n)}async setRead(e,t){let n=this.sessions.get(e);if(n)return n.setRead(t),!0;let r=!1;return await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;r=!0;let i=ps(o,t);i!==void 0&&await this.store.write({...o,readAt:i})}),this.invalidateListCache(),r}async persistReadState(e,t){await this.enqueueMetaWrite(e,async()=>{let n=await this.store.read(e);n&&await this.store.write({...n,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt})})}async mutateRecord(e,t,n=[],r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o,...t,...r?r(o):{},updatedAt:new Date().toISOString()};for(let a of n)delete i[a];await this.store.write(i)})}static EXTENSION_STATE_CAP_BYTES=64*1024;async getExtensionState(e,t){return(await this.store.read(e))?.extensionState?.[t]??{}}async getExtensionStateKey(e,t,n){return(await this.getExtensionState(e,t))[n]}async setExtensionStateKey(e,t,n,r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o.extensionState??{}},a={...i[t]??{},[n]:r},d=Buffer.byteLength(JSON.stringify(a),"utf8");if(d>s.EXTENSION_STATE_CAP_BYTES)throw new Error(`extension_state: bucket for ${t} would be ${d} bytes; cap is ${s.EXTENSION_STATE_CAP_BYTES}`);i[t]=a;let c={...o,extensionState:i,updatedAt:new Date().toISOString()};await this.store.write(c)})}async deleteExtensionStateKey(e,t,n){await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r?.extensionState?.[t])return;let o={...r.extensionState},i={...o[t]};if(!(n in i))return;delete i[n],Object.keys(i).length===0?delete o[t]:o[t]=i;let a={...r,extensionState:o,updatedAt:new Date().toISOString()};await this.store.write(a)})}enqueueMetaWrite(e,t){return this.enqueueKeyed(this.metaWriteQueues,e,t)}enqueueKeyed(e,t,n){let o=(e.get(t)??Promise.resolve()).catch(()=>{}).then(n),i=o.catch(()=>{});return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)}),o}liveSessionsIn(e,t){let n=[];for(let r of this.sessions.values())r.sessionId!==t&&r.workspace?.path===e&&n.push(r);return n}async closeAll(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(t=>t.close({deleteRecord:!1,by:"daemon-shutdown"}))),this.sessions.clear()}async flushSynopsis(e){await this.synopsisCoordinator.flush(e)}async shutdownSynopsis(){await this.synopsisCoordinator.shutdown()}scheduleSynopsis(e){this.synopsisCoordinator.schedule(e)}scheduleCompaction(e,t){if(t?.targetAgentId){this.mutateRecord(e,{pendingAgentSwap:t.targetAgentId}).catch(r=>{this.logger?.warn(`scheduleCompaction: failed to stamp pendingAgentSwap for ${e}: ${r instanceof Error?r.message:String(r)}`)});let n=t.targetAgentId;(async()=>{try{let r=await this.store.read(e),o=await this.histories.load(e,{maxEntries:1/0});if(ac(o)===0){this.logger?.info(`compaction: zero-turn fast-path swap sessionId=${e} target=${n}`),await this.dispatchSynthesisSwap(e,void 0,o.length,n);return}if(!r?.synopsis||r.summarizedThroughEntry===void 0){this.synopsisCoordinator.scheduleCompaction(e,t);return}if(o.length!==r.summarizedThroughEntry){this.synopsisCoordinator.scheduleCompaction(e,t);return}this.logger?.info(`compaction: fast-path swap sessionId=${e} target=${n} (reusing artifact @${r.summarizedThroughEntry})`),await this.dispatchSynthesisSwap(e,r.synopsis,r.summarizedThroughEntry,n)}catch(r){this.logger?.warn(`scheduleCompaction: fast-path check failed for ${e}: ${r instanceof Error?r.message:String(r)} \u2014 falling back to synthesis`),this.synopsisCoordinator.scheduleCompaction(e,t)}})();return}this.synopsisCoordinator.scheduleCompaction(e,t)}getCompactionInFlight(){let e=this.synopsisCoordinator.size();return e.inflight>0||e.queued>0}async getPendingAgentSwap(e){return(await this.store.read(e).catch(()=>{}))?.pendingAgentSwap}async getCompactionState(e){return(await this.store.read(e).catch(()=>{}))?.compactionState}async persistRollbackBreadcrumb(e,t){await this.mutateRecord(e,{},void 0,n=>{let r=n.rollbackBreadcrumb;return r!==void 0&&t.runId!==void 0&&r.runId===t.runId?(this.logger?.info(`compaction: keeping rollback breadcrumb pinned at ${r.previousUpstreamSessionId} for runId=${t.runId} sessionId=${e} (later swap of the same run)`),{}):{rollbackBreadcrumb:t}})}async getUpstreamGenerations(e){return(await this.store.read(e).catch(()=>{}))?.upstreamGenerations??[]}async getRollbackBreadcrumb(e){return(await this.store.read(e).catch(()=>{}))?.rollbackBreadcrumb}emitSwapPhase(e,t,n){let r=this.get(e);if(r){if(t){let o=n.phase==="failed";r.broadcastPendingAgentSwap(o?null:t);return}r.broadcastCompactionPhase(n)}}async getSummarizedThroughEntry(e){let t=this.sessions.get(e);return t?t.summarizedThroughEntry:(await this.store.read(e).catch(()=>{}))?.summarizedThroughEntry}async flushMetaWrites(){let e=[...this.metaWriteQueues.values()];e.length!==0&&await Promise.allSettled(e)}async flushHistoryWrites(){await this.histories.flushAll()}async reconcilePermissionFlags(){let e=await this.store.list().catch(()=>[]),t=0;for(let n of e){let r=n.attentionFlags??[],o=r.filter(i=>!(i.source==="daemon"&&i.reason.startsWith("permission:")));if(o.length!==r.length){let i=r.length-o.length;t+=i,await this.mutateRecord(n.sessionId,{attentionFlags:o}).catch(()=>{})}}t>0&&this.logger?.info(`cleared ${t} stale permission attention flags on startup`)}async resumePendingCompactions(){let e=new Set(["requested","running","swap_pending","swap_deferred"]),t=await this.store.list().catch(()=>[]);for(let n of t){let r=n.compactionState;if(r!=null){if(!e.has(r.status)){this.logger?.info(`compaction: not resuming sessionId=${n.sessionId} status=${r.status} (terminal \u2014 user must re-trigger explicitly)`);continue}this.logger?.info(`compaction: resuming sessionId=${n.sessionId} status=${r.status} from prior daemon`);try{this.scheduleCompaction(n.sessionId)}catch(o){this.logger?.warn(`compaction: resume failed for sessionId=${n.sessionId}: ${o instanceof Error?o.message:String(o)}`)}}}}async resumePendingAgentSwaps(){let e=await this.store.list().catch(()=>[]);for(let t of e){let n=t.pendingAgentSwap;if(n)try{let r=await this.histories.load(t.sessionId).catch(()=>[]);t.synopsis!==void 0&&t.summarizedThroughEntry!==void 0&&t.summarizedThroughEntry>=r.length&&t.synopsis?(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${n} with persisted synopsis (history=${r.length})`),await this.dispatchSynthesisSwap(t.sessionId,t.synopsis,t.summarizedThroughEntry??r.length,n)):(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${n} via fresh synthesis (history=${r.length} watermark=${t.summarizedThroughEntry??"(none)"})`),this.scheduleCompaction(t.sessionId,{targetAgentId:n}))}catch(r){this.logger?.warn(`agent-swap: resume failed for sessionId=${t.sessionId}: ${r instanceof Error?r.message:String(r)}`)}}}async resurrectPendingQueues(){let e=await this.store.list().catch(()=>[]);for(let t of e){let n=await Sd(t.sessionId).catch(()=>[]);if(n.length===0)continue;let r=Date.now(),o=n.filter(d=>r-d.enqueuedAt<Ic),i=n.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${Ic/1e3}s)`),await Sn(t.sessionId,o).catch(()=>{})),o.length===0)continue;let a=await this.loadFromDisk(t.sessionId).catch(()=>{});if(!a){this.logger?.warn(`queue replay: no meta for ${t.sessionId}; discarding ${o.length} entr${o.length===1?"y":"ies"}`),await Sn(t.sessionId,[]).catch(()=>{});continue}try{let d=await this.resurrect(a);this.logger?.info(`queue replay: resurrected ${t.sessionId} and replaying ${o.length} prompt(s)`),d.replayPersistedQueue(o)}catch(d){this.logger?.warn(`queue replay: failed to resurrect ${t.sessionId}: ${d.message}`)}}}};function km(s,e){if(typeof s!="string"||s.length===0)return!1;let t=Hn.resolve(s),n=Hn.resolve(e);return t===n||t.startsWith(n+Hn.sep)}function vm(s){return s!==void 0&&/^\{\s*"session_id"\s*:\s*"[^"]*"\s*,\s*"(?:transcript_path|cwd|permission_mode|hook_event_name)"\s*:/.test(s)}function Ac(s,e){if(s===void 0||s.length===0)return!0;let t=qo(s);if(qo(e.cwd)===t)return!0;let n=e.workspace?.sourceCwd;return n!==void 0&&qo(n)===t}function qo(s){return s.length>1&&s.endsWith("/")?s.replace(/\/+$/,""):s}function bm(s,e){let n=(s.mergedAvailableCommands().length>0?s.agentOnlyAdvertisedCommands().map(p=>p.description!==void 0?{name:p.name,description:p.description}:{name:p.name}):void 0)??e?.agentCommands,r=s.availableModes(),i=(r.length>0?r.map(p=>{let f={id:p.id};return p.name!==void 0&&(f.name=p.name),p.description!==void 0&&(f.description=p.description),f}):void 0)??e?.agentModes,a=s.availableModels(),c=(a.length>0?a.map(p=>{let f={modelId:p.modelId};return p.name!==void 0&&(f.name=p.name),p.description!==void 0&&(f.description=p.description),f}):void 0)??e?.agentModels,u=s.extraConfigOptionValues(),l=Object.keys(u).length>0?u:e?.configOptionValues;return xo({sessionId:s.sessionId,lineageId:e?.lineageId??xn(),upstreamSessionId:s.upstreamSessionId,importedFromSessionId:e?.importedFromSessionId,importedFromUpstreamSessionId:e?.importedFromUpstreamSessionId,importedFromMachine:e?.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:e?.synopsis,summarizedThroughEntry:e?.summarizedThroughEntry,agentArgs:s.agentArgs,currentModel:s.currentModel??e?.currentModel,currentMode:s.currentMode??e?.currentMode,currentUsage:Tc(s.persistableUsage)??e?.currentUsage,agentCommands:n,agentModes:i,agentModels:c,configOptionValues:l,parentSessionId:s.parentSessionId??e?.parentSessionId,forkedFromSessionId:s.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId??e?.forkedFromMessageId,side:s.side??e?.side,originatingClient:s.originatingClient??e?.originatingClient,interactive:s.interactive??e?.interactive,priority:s.priority??e?.priority,lastTurnEndedAt:s.lastTurnEndedAt??e?.lastTurnEndedAt,readAt:s.readAt??e?.readAt,forwardedEnv:s.forwardedEnv??e?.forwardedEnv,workspace:s.workspace,attentionFlags:s.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?Pc(e,s.agentId,s.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(s.createdAt).toISOString()})}function Tc(s){if(!s)return;let e={};return s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size),s.costAmount!==void 0&&(e.costAmount=s.costAmount),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),s.cumulativeCost!==void 0&&(e.cumulativeCost=s.cumulativeCost),Object.keys(e).length>0?e:void 0}function Sm(s){return s?{...s}:void 0}function Im(s){return(s.extendsChain??[s.id]).some(t=>t==="claude-acp"||t.startsWith("claude-acp-"))}var Am=[{type:"system",subtype:"background_tasks_changed"}];function zo(s,e={}){if(!Im(s))return;let t={extraArgs:{"thinking-display":"summarized"}};return e.model&&(t.model=e.model),{claudeCode:{options:t,emitRawSDKMessages:Am}}}function js(s,e){let t=e.fromObject(s);if(t!==void 0)return t;let n=s[e.nestedKey];if(n&&typeof n=="object"&&!Array.isArray(n)){let i=e.fromObject(n);if(i!==void 0)return i}let r=s._meta;if(r&&typeof r=="object"&&!Array.isArray(r)){for(let[i,a]of Object.entries(r))if(i!=="hydra-acp"&&a&&typeof a=="object"&&!Array.isArray(a)){let d=e.fromObject(a);if(d!==void 0)return d}}let o=Cm(s,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function Jo(s){return js(s,{nestedKey:"models",configId:"model",fromObject:e=>Se(e.currentModelId)??Se(e.currentModel)??Se(e.modelId)??Se(e.model),fromConfig:e=>Se(e.currentValue)})}function ht(s,e){if(!s||typeof s!="object")return s;let t=s;if(t.code!==x.AuthRequired)return s;let n=c=>!!c&&typeof c=="object"&&!Array.isArray(c),r=n(t.data)?t.data:{},o=n(r._meta)?r._meta:{},i=n(o["hydra-acp"])?o["hydra-acp"]:{},a=typeof t.message=="string"?t.message:"authentication required",d=new Error(a);return d.code=x.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function Cc(s){return/^[A-Za-z0-9_\-./=:@]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function Rc(s,e,t,n){if(s&&typeof s=="object"&&s.code===x.AuthRequired)return s;let r=s instanceof Error?s.message:String(s),o=r.includes("stderr:"),i=o?"":e.stderrTailText(),a=n?`to reproduce: (cd ${Cc(n.cwd)} && ${[n.command,...n.args].map(Cc).join(" ")})`:"";if(!i&&!a)return s;let d=[o?r:`agent ${t} failed to start: ${r}`];i&&d.push(`stderr: ${i}`),a&&d.push(a);let c=new Error(d.join(`
188
- `));if(s&&typeof s=="object"){let u=s;typeof u.code=="number"&&(c.code=u.code),u.data!==void 0&&(c.data=u.data)}return c}function Fn(s){return s._meta?.steering?.supported===!0}function Nn(s){if(!Array.isArray(s))return;let e=[];for(let t of s){if(!t||typeof t!="object")continue;let n=t;if(typeof n.id!="string")continue;let r=typeof n.description=="string"?n.description:"",o=n.type==="agent"||n.type==="terminal"?n.type:void 0,i=typeof n.name=="string"?n.name:void 0,a=n._meta,d=a!==null&&typeof a=="object"&&!Array.isArray(a)?a:void 0;e.push({id:n.id,description:r,...o&&{type:o},...i!==void 0&&{name:i},...d&&{_meta:d}})}return e.length>0?e:void 0}function Se(s){if(typeof s!="string")return;let e=s.trim();return e.length>0?e:void 0}function Cm(s,e){let t=s.configOptions;if(Array.isArray(t))for(let n of t){if(!n||typeof n!="object"||Array.isArray(n))continue;let r=n;if(r.id===e)return r}}function Zt(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.configOptions)}function en(s){let e=s.configOptions;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object"||Array.isArray(n))continue;let r=n,o=Se(r.id);if(!o||o==="model"||o==="mode"||o==="agent")continue;let i=ko(r.options);if(i.length===0)continue;let a=Se(r.description);t.push({id:o,name:Se(r.name)??o,...a?{description:a}:{},category:Se(r.category)??"other",type:"select",currentValue:Se(r.currentValue)??i[0].value,options:i})}return t}function gt(s){return s.length>0?s:void 0}function Vo(s){return js(s,{nestedKey:"models",configId:"model",fromObject:e=>{let t=An(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=An(e.options);return t.length>0?t:void 0}})??[]}function Go(s){return js(s,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=ks(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=ks(e.options);return t.length>0?t:void 0}})??[]}function Ko(s){return js(s,{nestedKey:"modes",configId:"mode",fromObject:e=>Se(e.currentModeId)??Se(e.currentMode)??Se(e.modeId)??Se(e.mode),fromConfig:e=>Se(e.currentValue)})}function Rm(s){for(let e=s.length-1;e>=0;e--){let t=s[e];if(!t||t.method!=="session/update")continue;let n=t.params?.update;if(n?.sessionUpdate==="turn_complete"&&!(typeof n.messageId!="string"||n.messageId.length===0))return{index:e,messageId:n.messageId}}}async function xc(s){try{let e=await Rt.readFile(E.tuiHistoryFile(s),"utf8"),t=[];for(let n of e.split(`
189
- `))if(n.length!==0)try{let r=JSON.parse(n);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function Pc(s,e,t,n=new Date().toISOString(),r={}){let{retiredCost:o,retiredUsed:i,startedUsed:a,lifetimeCost:d,reason:c,runId:u}=r,l=h=>d!==void 0&&h.lifetimeCostAtStart!==void 0?Math.max(0,d-h.lifetimeCostAtStart):o,p=s.upstreamGenerations&&s.upstreamGenerations.length>0?[...s.upstreamGenerations]:s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId}]:[],f=p[p.length-1];if(f&&f.upstreamSessionId===t){if(p.length>=2){let h=p[p.length-2];if(h){let w=l(h);p[p.length-2]={...h,...w!==void 0&&h.cost===void 0?{cost:w}:{},...i!==void 0&&h.usedAtEnd===void 0?{usedAtEnd:i}:{}}}}return(c!==void 0&&f.reason===void 0||a!==void 0&&f.usedAtStart===void 0||d!==void 0&&f.lifetimeCostAtStart===void 0)&&(p[p.length-1]={...f,...c!==void 0&&f.reason===void 0?{reason:c,...u!==void 0?{runId:u}:{}}:{},...a!==void 0&&f.usedAtStart===void 0?{usedAtStart:a}:{},...d!==void 0&&f.lifetimeCostAtStart===void 0?{lifetimeCostAtStart:d}:{}}),p}return f&&f.endedAt===void 0&&(p[p.length-1]={...f,endedAt:n,...(()=>{let h=l(f);return h!==void 0?{cost:h}:{}})(),...i!==void 0?{usedAtEnd:i}:{}}),p.push({upstreamSessionId:t,agentId:e,startedAt:n,...c!==void 0?{reason:c}:{},...u!==void 0?{runId:u}:{},...a!==void 0?{usedAtStart:a}:{},...d!==void 0?{lifetimeCostAtStart:d}:{}}),p}async function Dn(s){try{let e=await Rt.stat(E.historyFile(s));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function tn(s,e){return s.interactive!==void 0?s.interactive:s.originatingClient?.name===$s?!1:e?!0:void 0}import{spawn as xm}from"child_process";import*as Bs from"fs";import*as st from"fs/promises";import*as Ws from"path";import Em from"pino-roll";var Ls=class{windowMs;maxFailures;now;recentExits=[];tripped_;constructor(e={}){this.windowMs=e.windowMs??3e5,this.maxFailures=e.maxFailuresInWindow??10,this.now=e.now??Date.now}recordExit(e,t,n){if(e===78){let i=`exited with code 78 (unrecoverable); fix and run \`${n}s start ${t}\``;return this.tripped_=i,{tripped:i}}let r=this.now();this.recentExits.push(r);let o=r-this.windowMs;for(;this.recentExits.length>0&&this.recentExits[0]<o;)this.recentExits.shift();if(this.recentExits.length>this.maxFailures){let i=Math.round(this.windowMs/6e4),a=`${this.recentExits.length} exits in ${i}m (crash loop); fix and run \`${n}s start ${t}\``;return this.tripped_=a,{tripped:a}}return"restart"}reset(){this.recentExits=[],this.tripped_=void 0}get tripped(){return this.tripped_}};import*as Mc from"fs/promises";import*as Qo from"path";var Us=process.platform!=="win32";var Tm=1e3,Pm=6e4,Yo=3e3,nn=class{entries=new Map;stopping=!1;context;tokenRegistry;breakerOptions;restartBaseMs;restartCapMs;adapter;constructor(e,t,n,r={}){this.adapter=t,this.context=n,this.tokenRegistry=r.tokenRegistry,this.breakerOptions=r.breakerOptions,this.restartBaseMs=r.restartBaseMs??Tm,this.restartCapMs=r.restartCapMs??Pm;for(let o of e)this.entries.set(o.name,this.makeEntry(o))}setContext(e){this.context=e}reportVersion(e,t){let n=this.entries.get(e);n&&(n.version=t)}async start(){if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before start`);await st.mkdir(this.adapter.paths.dir(),{recursive:!0}),await this.reapOrphans();let e=[];for(let t of this.entries.values())t.config.enabled&&e.push(this.spawn(t,0));await Promise.all(e)}async stop(){this.stopping=!0;let e=[];for(let t of this.entries.values()){t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;if(n){try{n.kill("SIGTERM")}catch{}e.push(new Promise(r=>{if(n.exitCode!==null||n.signalCode!==null){r();return}let o=setTimeout(()=>{try{n.kill("SIGKILL")}catch{}r()},Yo);n.on("exit",()=>{clearTimeout(o),r()})}))}}await Promise.allSettled(e);for(let t of this.entries.values()){try{t.logStream?.end()}catch{}t.child=void 0,t.logStream=void 0,t.pid=void 0}}list(){return[...this.entries.values()].map(e=>this.infoFor(e))}get(e){let t=this.entries.get(e);return t?this.infoFor(t):void 0}has(e){return this.entries.has(e)}async startByName(e){let t=this.entries.get(e);if(!t)throw jn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw jn(new Error(`${this.adapter.kind} ${e} already running`),"CONFLICT");return t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0),t.manuallyStopped=!1,t.restartCount=0,t.breaker.reset(),t.failureReason=void 0,await this.spawn(t,0),this.infoFor(t)}async stopByName(e){let t=this.entries.get(e);if(!t)throw jn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;return n?(await this.terminate(t,n),this.infoFor(t)):this.infoFor(t)}async restartByName(e){return await this.stopByName(e),this.startByName(e)}register(e){if(this.entries.has(e.name))throw jn(new Error(`${this.adapter.kind} ${e.name} already exists`),"CONFLICT");if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before register`);let t=this.makeEntry(e);return this.entries.set(e.name,t),e.enabled&&this.spawn(t,0).catch(n=>{t.failureReason=`spawn: ${n.message}`}),this.infoFor(t)}async unregister(e){let t=this.entries.get(e);if(!t)throw jn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;n&&await this.terminate(t,n);try{t.logStream?.end()}catch{}this.entries.delete(e)}async terminate(e,t){if(t.exitCode!==null||t.signalCode!==null)return;let n=new Promise(o=>{e.exitWaiters.push(o)});try{t.kill("SIGTERM")}catch{}let r=setTimeout(()=>{try{t.kill("SIGKILL")}catch{}},Yo);typeof r.unref=="function"&&r.unref();try{await n}finally{clearTimeout(r)}}infoFor(e){let t;return e.failureReason!==void 0?t="failed":e.child?t="running":e.restartTimer?t="restarting":e.config.enabled?t="stopped":t="disabled",{name:e.config.name,status:t,pid:e.pid,enabled:e.config.enabled,restartCount:e.restartCount,startedAt:e.startedAt,lastExitCode:e.lastExitCode,logPath:this.adapter.paths.logFile(e.config.name),version:e.version,failureReason:e.failureReason}}makeEntry(e){return{config:e,child:void 0,logStream:void 0,restartTimer:void 0,pid:void 0,startedAt:void 0,restartCount:0,lastExitCode:void 0,manuallyStopped:!1,exitWaiters:[],version:void 0,processToken:void 0,breaker:new Ls(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await st.readdir(this.adapter.paths.dir(),{withFileTypes:!0})}catch(t){if(t.code==="ENOENT")return;throw t}for(let t of e){if(!t.isDirectory())continue;let n=this.adapter.paths.pidFile(t.name),r;try{let o=await st.readFile(n,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&Xo(r)){try{process.kill(r,"SIGTERM")}catch{}let o=Date.now()+Yo;for(;Date.now()<o&&Xo(r);)await new Promise(i=>setTimeout(i,50));if(Xo(r))try{process.kill(r,"SIGKILL")}catch{}}await st.unlink(n).catch(()=>{})}}async spawn(e,t){if(this.stopping||e.manuallyStopped)return;let n=this.context;if(!n)throw new Error(`${this.managerName()}.spawn called before setContext`);let r=e.config,o=r.command.length>0?r.command:[r.name],i=Ws.dirname(this.adapter.paths.logFile(r.name)),a;try{await st.mkdir(i,{recursive:!0}),a=await Em({file:Ws.join(i,`${r.name}.log`),size:"5m",mkdir:!0,symlink:Us,limit:{count:5}}),a.on("error",m=>{e.failureReason=`log stream: ${m.message}`})}catch(m){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${m.message}`,this.scheduleRestart(e,t+1);return}if(this.stopping||e.manuallyStopped){try{a.end()}catch{}return}a.write(`[hydra-acp] ${new Date().toISOString()} starting ${this.adapter.kind} ${r.name} (attempt ${t+1})
187
+ `)}async copyCarriedWork(e,t,n){let r=await this.patchFromSnapshot(n,t,e.provider);if(r===void 0)return!1;if(r.length===0)return!0;let o=re(e.provider);return o===void 0?!1:(await o.applyDelta(e.path,r)).ok}async patchFromSnapshot(e,t,n){let r=re(n);if(r===void 0)return;let o=await r.currentState(e);if(o!==void 0)return await r.captureDelta(e,o,t).catch(()=>{})}async unwindStartWorkspace(e){let{provider:t,ws:n,startRef:r,carried:o}=e;await t.unlock(n).catch(()=>{}),o!==void 0&&await t.dropSnapshotRef(n,r).catch(()=>{}),await t.removeWorkspace(n,{force:!0}).catch(()=>{})}async materializeNestedTrees(e,t){let n=re(e.provider);if(n?.capabilities().supports.nestedTrees!==!0)return;let r=await n.materializeNested({path:e.path,sourceCwd:e.sourceCwd,label:e.label,provider:n.kind},t).catch(o=>({ok:!1,count:0,reason:o instanceof Error?o.message:String(o)}));return r.ok?r.count>0?`populated ${r.count} nested tree(s)`:void 0:`nested trees FAILED: ${r.reason??"unknown"}`}async applyWorkspaceSetup(e,t){let n=await Ts(e.sourceCwd).catch(()=>({})),r=[];if(n.carry!==void 0&&n.carry.length>0){let o=await No(e.sourceCwd,e.path,n.carry).catch(()=>{});o!==void 0&&o.copied.length>0&&r.push(`carried ${o.copied.length} config file(s)`)}if(n.postCreate!==void 0){let o=await Ps(n.postCreate,{workspacePath:e.path,sourceCwd:e.sourceCwd,label:e.label,sessionId:t,...n.hookTimeoutSeconds!==void 0?{timeoutSeconds:n.hookTimeoutSeconds}:{}});r.push(o.ok?"ran postCreate":`postCreate FAILED: ${o.reason??"unknown"}`)}return r.length>0?r.join("; "):void 0}async deriveForkWorkspace(e,t){let n=re(e.provider);if(n===void 0)return;let r=n.capabilities(),o=r.sharedHistory?await n.currentState(e.path)??"":"",i=await n.createWorkspace({sourceCwd:e.sourceCwd,label:t,...o.length>0?{from:o}:{contentFrom:e.path}}).catch(d=>({ok:!1,reason:String(d)}));if(!i.ok){this.logger?.warn?.(`fork workspace: could not derive from ${e.path}: ${i.reason}`);return}let a=i.workspace;if(o.length>0&&r.supports.captureWorkingState){let d=await n.captureWorkingState(e.path,`hydra: fork carry from ${e.label}`).catch(()=>{});d!==void 0&&d!==o&&await this.copyUncommittedInto(e.path,a.path,o,d,a.provider).catch(()=>{})}return{path:a.path,sourceCwd:a.sourceCwd,label:a.label,provider:a.provider,...a.snapshot!==void 0?{snapshot:a.snapshot}:{},...a.line!==void 0?{line:a.line}:{},...a.vcs!==void 0?{vcs:{...a.vcs}}:{}}}async copyUncommittedInto(e,t,n,r,o){let i=re(o);if(i===void 0)return!1;let a=await i.captureDelta(e,n,r).catch(()=>{});return a===void 0||a.trim().length===0?!1:(await i.applyDelta(t,a,{stage:!0})).ok}async recoverWorkspace(e){let t=re(e.provider);if(t===void 0)return;let n={path:e.path,sourceCwd:e.sourceCwd,label:e.label,provider:e.provider,...e.snapshot!==void 0?{snapshot:e.snapshot}:{},...e.vcs!==void 0?{vcs:e.vcs}:{}};if(t.capabilities().supports.rematerialize){let o=await t.rematerialize(n).catch(i=>({ok:!1,reason:String(i)}));if(o.ok)return this.logger?.info?.(`session workspace: restored ${o.workspace.path} from retained state`),{...e,path:o.workspace.path};this.logger?.warn?.(`session workspace: could not restore: ${o.reason}`)}if(!await this.dirExists(e.sourceCwd))return;let r=await t.createWorkspace({sourceCwd:e.sourceCwd,label:`${e.label}-r`}).catch(o=>({ok:!1,reason:String(o)}));if(r.ok)return this.logger?.warn?.(`session workspace: ${e.path} is gone and could not be restored; resurrecting in a fresh workspace ${r.workspace.path} from ${e.sourceCwd}. Uncommitted work from the old workspace is not recoverable.`),{path:r.workspace.path,sourceCwd:r.workspace.sourceCwd,label:r.workspace.label,provider:r.workspace.provider,...r.workspace.snapshot!==void 0?{snapshot:r.workspace.snapshot}:{},...r.workspace.vcs!==void 0?{vcs:{...r.workspace.vcs}}:{}}}async syncFromAgent(e){let t=await this.registry.getAgent(e);if(!t){let w=new Error(`agent ${e} not found in registry`);throw w.code=x.AgentNotInstalled,w}let n=await Me(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:Ec.homedir(),plan:n}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:Ht,clientInfo:{name:"hydra",version:ue}})}catch(w){throw await r.kill().catch(()=>{}),ht(w,r)}if(r.authMethods=Nn(o.authMethods),r.steeringSupported=Fn(o),(o.agentCapabilities??{}).sessionCapabilities?.list===void 0)throw await r.kill().catch(()=>{}),new Error(`agent ${e} does not advertise sessionCapabilities.list; cannot sync`);let a;try{a=await this.collectAgentSessions(r)}catch(w){throw await r.kill().catch(()=>{}),w}await r.kill().catch(()=>{});let d=new Map,c=Wr(t);d.set(e,c);let u=new Set;for(let w of this.sessions.values()){let m=await this.agentStoreKey(w.agentId,d);u.add(`${m}::${w.upstreamSessionId}`)}let l=await this.store.list().catch(()=>[]);for(let w of l){u.add(`${await this.agentStoreKey(w.agentId,d)}::${w.upstreamSessionId}`);for(let m of w.upstreamGenerations??[])u.add(`${await this.agentStoreKey(m.agentId,d)}::${m.upstreamSessionId}`)}let p=E.sessionsDir(),f=[],h=0;for(let w of a){let m=`${c}::${w.sessionId}`;if(u.has(m)){h+=1;continue}if(vm(w.cwd,p)){h+=1;continue}let g=c,y=await this.tombstones.read(g,w.sessionId).catch(()=>{});if(!y&&c!==e&&(g=e,y=await this.tombstones.read(g,w.sessionId).catch(()=>{})),y){if(!Xd(y,w.updatedAt)){h+=1;continue}await this.tombstones.remove(g,w.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${w.sessionId} (upstream updatedAt advanced past ${y.upstreamUpdatedAt??"<unset>"})`)}u.add(m);let k=`${ye}${Ct()}`,v=new Date().toISOString(),S=w.updatedAt??v,b={sessionId:k,lineageId:xn(),upstreamSessionId:w.sessionId,agentId:e,cwd:w.cwd,pendingHistorySync:!0,interactive:!bm(w.title),createdAt:S,updatedAt:S};w.title!==void 0&&(b.title=w.title);let A=xo(b);await this.store.write(A),f.push({version:1,...A})}return{synced:f,skipped:h}}async listTombstones(e={}){let t=e.grep?.toLowerCase();return(await this.tombstones.list(e.agentId)).filter(r=>e.since===void 0||r.deletedAt>=e.since).filter(r=>t===void 0||[r.title,r.cwd,r.sessionId,r.upstreamSessionId].some(o=>o?.toLowerCase().includes(t))).sort((r,o)=>r.deletedAt<o.deletedAt?1:-1)}async undeleteSessions(e){let t=await this.tombstones.list(),n=[],r=[],o=[];for(let a of e){let d=t.filter(u=>u.upstreamSessionId===a),c=d.length>0?d:t.filter(u=>u.sessionId===a||u.sessionId===`${ye}${a}`);if(c.length===0){r.push({id:a,reason:"no tombstone found"});continue}if(c.length>1){r.push({id:a,reason:"ambiguous: several tombstones match; pass an upstream id",candidates:c.map(u=>u.upstreamSessionId)});continue}o.push({id:a,tombstone:c[0]})}let i=new Map;for(let a of o){let d=i.get(a.tombstone.agentId)??[];d.push(a),i.set(a.tombstone.agentId,d)}for(let[a,d]of i){let c=l=>{let{version:p,...f}=l;return this.tombstones.add(f).catch(()=>{})};for(let l of d)await this.tombstones.remove(a,l.tombstone.upstreamSessionId);let u;try{u=(await this.syncFromAgent(a)).synced}catch(l){for(let p of d)await c(p.tombstone),r.push({id:p.id,reason:`agent sync failed: ${l.message}`});continue}for(let l of d){let p=u.find(f=>f.upstreamSessionId===l.tombstone.upstreamSessionId);if(!p){await c(l.tombstone),r.push({id:l.id,reason:`agent ${a} no longer lists this session`});continue}n.push({id:l.id,sessionId:p.sessionId,upstreamSessionId:l.tombstone.upstreamSessionId})}}return{restored:n,failed:r}}async collectAgentSessions(e){let t=[],n,r=new Set;for(let o=0;o<100;o+=1){let i={};n!==void 0&&(i.cursor=n);let a=await e.connection.request("session/list",i),d=Array.isArray(a.sessions)?a.sessions:[];for(let c of d){if(typeof c.sessionId!="string"||typeof c.cwd!="string")continue;let u={sessionId:c.sessionId,cwd:c.cwd};typeof c.title=="string"&&(u.title=c.title),typeof c.updatedAt=="string"&&(u.updatedAt=c.updatedAt),t.push(u)}if(typeof a.nextCursor!="string"||a.nextCursor.length===0||r.has(a.nextCursor))break;r.add(a.nextCursor),n=a.nextCursor}return t}async applySeedModel(e,t,n,r,o){try{let{verb:i,result:a}=await ct({request:(d,c)=>e.connection.request(d,c),sessionId:t,modelId:n,...o?{verb:o}:{},logger:this.logger});return this.logger?.info(`${r}: ${i} accepted`),{accepted:!0,result:a}}catch(i){return this.logger?.warn(`${r} rejected by agent (${i.message}); session will use the agent's own default`),{accepted:!1}}}async applySeedMode(e,t,n,r){try{let o=await e.connection.request("session/set_mode",{sessionId:t,modeId:n});return this.logger?.info(`${r}: session/set_mode accepted`),{accepted:!0,result:o}}catch(o){return this.logger?.warn(`${r} rejected by agent (${o.message}); session will use the agent's own default mode`),{accepted:!1}}}async restoreConfigOptionValues(e,t,n,r){if(!n||Object.keys(n).length===0)return this.logger?.info(`resurrect: no persisted configOptionValues; agent reports ${JSON.stringify(Object.fromEntries(r.map(i=>[i.id,i.currentValue])))}`),r;let o=r;for(let[i,a]of Object.entries(n)){let d=`resurrect: persisted configOptionValues.${i}=${JSON.stringify(a)}`,c=o.find(p=>p.id===i);if(!c){this.logger?.warn(`${d}: agent does not currently advertise configId=${i}; skipping session/set_config_option`);continue}if(a===c.currentValue){this.logger?.info(`${d}: agent already reports ${JSON.stringify(c.currentValue)}; nothing to restore`);continue}this.logger?.info(`${d}: agent reports ${JSON.stringify(c.currentValue)}; restoring`);let u=Jt(a,c.options.map(p=>p.value));if(u.kind!=="exact"&&u.kind!=="resolved"){this.logger?.warn(`${d} ${u.kind}; skipping session/set_config_option`);continue}let l=u.kind==="resolved"?u.modelId:a;try{let p=await e.connection.request("session/set_config_option",{sessionId:t,configId:i,value:l});this.logger?.info(`${d}: session/set_config_option accepted`),o=Zt(p)?en(p):o.map(f=>f.id===i?{...f,currentValue:l}:f)}catch(p){this.logger?.warn(`${d}: session/set_config_option rejected by agent (${p.message})`)}}return o}async bootstrapAgent(e){let t=await this.registry.getAgent(e.agentId);if(!t){let i=new Error(`agent ${e.agentId} not found in registry`);throw i.code=x.AgentNotInstalled,i}let n=await Me(t,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),r=Zn(e.selfSessionId,e.forwardedEnv),o=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:n,...r?{extraEnv:r}:{}});try{let i=await o.connection.request("initialize",{protocolVersion:1,clientCapabilities:Ht,clientInfo:{name:"hydra",version:ue}}),a=i.agentCapabilities;o.authMethods=Nn(i.authMethods),o.steeringSupported=Fn(i);let d=zo(t),c=await o.connection.request("session/new",{cwd:e.cwd,mcpServers:e.mcpServers??[],...d&&{_meta:d}}),u=c.sessionId;if(typeof u!="string")throw new Error(`agent ${e.agentId} returned a non-string sessionId from session/new`);let l=Jo(c),p=Vo(c),f=Ut(c),h=ua(this.sessionDefaults,t),w=h?.value,m=e.configDefaults,g=h?.from??e.agentId,y=e.model??m?.model??w?.model,k;if(y&&y!==l){let R=zt(y,p),T=e.model!==void 0?`model=${JSON.stringify(y)}`:m?.model!==void 0?`configDefaults.model=${JSON.stringify(y)}`:`sessionDefaults[${g}].model=${JSON.stringify(y)}`;if(R.kind==="exact"||R.kind==="none"){let M=await this.applySeedModel(o,u,y,T,f);M.accepted&&(l=y,k=M.result)}else if(R.kind==="resolved")if(R.modelId===l)l=R.modelId;else{let M=await this.applySeedModel(o,u,R.modelId,`${T} resolved to ${JSON.stringify(R.modelId)}`,f);M.accepted&&(l=R.modelId,k=M.result)}else if(R.kind==="ambiguous")this.logger?.warn(`${T} is ambiguous (trailing-segment matches [${R.candidates.join(", ")}]); skipping session/set_model, session will use ${JSON.stringify(l)}`);else{let M=p.map(H=>H.modelId).join(", ");this.logger?.warn(`${T} not in agent's availableModels ([${M}]); skipping session/set_model, session will use ${JSON.stringify(l)}`)}}let v=Go(c),S=Ko(c),b=m?.mode??w?.mode;if(b&&b!==S){let R=m?.mode!==void 0?`configDefaults.mode=${JSON.stringify(b)}`:`sessionDefaults[${g}].mode=${JSON.stringify(b)}`;if(v.length>0&&!v.some(T=>T.id===b)){let T=v.map(M=>M.id).join(", ");this.logger?.warn(`${R} not in agent's availableModes ([${T}]); skipping session/set_mode, session will use ${JSON.stringify(S)}`)}else{let T=await this.applySeedMode(o,u,b,R);T.accepted&&(S=b,Zt(T.result)&&(k=T.result))}}let A={...w??{},...m??{}};delete A.model,delete A.mode;let C=en(Zt(k)?k:c);if(Object.keys(A).length>0)for(let[R,T]of Object.entries(A)){let M=`sessionDefaults[${g}].${R}=${JSON.stringify(T)}`,H=C.find(z=>z.id===R);if(!H){this.logger?.warn(`${M}: agent does not currently advertise configId=${R}; skipping session/set_config_option`);continue}let U=Jt(T,H.options.map(z=>z.value));if(U.kind!=="exact"&&U.kind!=="resolved"){this.logger?.warn(`${M} ${U.kind}; skipping session/set_config_option`);continue}let W=U.kind==="resolved"?U.modelId:T;if(W!==H.currentValue)try{let z=await o.connection.request("session/set_config_option",{sessionId:u,configId:R,value:W});this.logger?.info(`${M}: session/set_config_option accepted`),Zt(z)?(C=en(z),k=z):C=C.map(D=>D.id===R?{...D,currentValue:W}:D)}catch(z){this.logger?.warn(`${M}: session/set_config_option rejected by agent (${z.message})`)}}return o.connection.dropBufferedWhere("session/update",R=>R?.update?.sessionUpdate==="config_option_update"),{agent:o,upstreamSessionId:u,agentMeta:c._meta,agentCapabilities:a,initialModel:l,initialModels:p.length>0?p:void 0,initialModes:v.length>0?v:void 0,initialMode:S,initialConfigOptions:C.length>0?C:void 0,modelVerb:f}}catch(i){throw await o.kill().catch(()=>{}),ht(Rc(i,o,e.agentId,{command:n.command,args:n.args,cwd:e.cwd}),o)}}async bootstrapAgentLoad(e,t){let n=await this.registry.getAgent(t.agentId);if(!n){let a=new Error(`agent ${t.agentId} not found in registry`);throw a.code=x.AgentNotInstalled,a}let r=await Me(n,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=Zn(t.selfSessionId,t.forwardedEnv),i=this.spawner({agentId:t.agentId,cwd:t.cwd,plan:r,...o?{extraEnv:o}:{}});try{let a=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:Ht,clientInfo:{name:"hydra",version:ue}}),d=a.agentCapabilities;i.authMethods=Nn(a.authMethods),i.steeringSupported=Fn(a);let c=zo(n),u=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...c&&{_meta:c}}),l=Jo(u),p=gt(Vo(u)),f=Go(u),h=Ko(u),w=gt(en(u));return{agent:i,upstreamSessionId:e,agentMeta:u._meta,agentCapabilities:d,initialModel:l,initialModels:p,initialModes:f.length>0?f:void 0,initialMode:h,initialConfigOptions:w,modelVerb:Ut(u)}}catch(a){throw await i.kill().catch(()=>{}),ht(Rc(a,i,t.agentId,{command:r.command,args:r.args,cwd:t.cwd}),i)}}async rewindSession(e,t,n={}){let r=await this.store.read(e);if(!r){let a=new Error(`session not found: ${e}`);throw a.code=x.SessionNotFound,a}if(this.rollbackLocks.has(e)||r.compactionState!=null){let a=new Error("the session is being compacted or rolled back; try again when that finishes");throw a.code=x.InvalidRequest,a}let o=0,i=async()=>{let a=await this.histories.truncateAfterTurn(e,t);if(!a){let u=new Error(`keepThrough messageId not found in the session's recent history: ${t}`);throw u.code=x.InvalidParams,u}if(o=a.removed,o===0)return!1;let d=r.summarizedThroughEntry,c=d!==void 0&&a.kept<d;if(c){let u=this.get(e);u&&(u.summarizedThroughEntry=void 0)}return await this.mutateRecord(e,{},c?["rollbackBreadcrumb","synopsis","summarizedThroughEntry"]:["rollbackBreadcrumb"]),!0};this.rollbackLocks.add(e);try{let a=this.get(e);a?await a.rewind(t,i,n):await i()&&await this.mutateRecord(e,{upstreamSessionId:""})}finally{this.rollbackLocks.delete(e)}return{sessionId:e,removed:o}}async performUncompact(e){if(this.rollbackLocks.has(e))throw new Error("a rollback is already in progress for this session");let t=this.get(e);if(!t)throw new Error("session is not live \u2014 cannot roll back a cold session");let n=await this.store.read(e);if(!n)throw new Error("session record not found");let r=n.rollbackBreadcrumb;if(!r)throw new Error("no rollback breadcrumb found \u2014 either the session has not been compacted, the rollback window has closed (a new turn was dispatched), or a previous rollback already consumed the breadcrumb");let o=n.compactionState;if(o!=null)throw new Error(`compaction is in progress (status: ${o.status}) \u2014 wait for it to complete before rolling back`);if(!await t.isQuiescedForSwap())throw new Error("session is not quiesced for rollback \u2014 wait for in-flight work to complete");this.rollbackLocks.add(e);try{await t.rollbackToUpstream({previousUpstreamSessionId:r.previousUpstreamSessionId,previousSummarizedThroughEntry:r.previousSummarizedThroughEntry}),await this.mutateRecord(e,{summarizedThroughEntry:r.previousSummarizedThroughEntry},["synopsis","rollbackBreadcrumb"])}finally{this.rollbackLocks.delete(e)}}async bootstrapAgentForAuth(e,t){let n=this.pendingAuthAgents.get(e);if(n&&n.isAlive())return n;let r=await this.registry.getAgent(e);if(!r){let d=new Error(`agent ${e} not found in registry`);throw d.code=x.AgentNotInstalled,d}let o=await Me(r,[],{npmRegistry:this.npmRegistry}),i=t??ce(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:Ht,clientInfo:{name:"hydra",version:ue}});a.authMethods=Nn(d.authMethods),a.steeringSupported=Fn(d)}catch(d){throw await a.kill().catch(()=>{}),ht(d,a)}return this.pendingAuthAgents.set(e,a),a.onExit(()=>{this.pendingAuthAgents.get(e)===a&&this.pendingAuthAgents.delete(e)}),a}async planSpawnForAgent(e){let t=await this.registry.getAgent(e);if(!t){let n=new Error(`agent ${e} not found in registry`);throw n.code=x.AgentNotInstalled,n}return Me(t,[],{npmRegistry:this.npmRegistry})}consumePendingAuthAgent(e){let t=this.pendingAuthAgents.get(e);if(t&&(this.pendingAuthAgents.delete(e),!!t.isAlive()))return t}getAgentForSession(e){return this.sessions.get(e)?.agent}async attachManagerHooks(e){e.onClose(({deleteRecord:t})=>{if(this.sessions.delete(e.sessionId),this.driftNoticed.delete(e.sessionId),this.invalidateListCache(),t||this.store.touch(e.sessionId).catch(()=>{}),t&&e.workspace!==void 0&&this.releaseWorkspace(e.workspace,e.sessionId).catch(()=>{}),t){if(e.upstreamSessionId){let r=tn({interactive:e.interactive,...e.originatingClient?{originatingClient:e.originatingClient}:{}},!0),o=this.tombstoneAllGenerations(e.sessionId,{agentId:e.agentId,upstreamSessionId:e.upstreamSessionId,upstreamUpdatedAt:new Date(e.updatedAt).toISOString(),cwd:e.cwd,...e.title!==void 0?{title:e.title}:{},...r!==void 0?{interactive:r}:{}},"user").catch(()=>{}).then(()=>this.store.delete(e.sessionId).catch(()=>{})).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===o&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,o);return}let n=this.store.delete(e.sessionId).catch(()=>{}).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===n&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,n);return}}),e.rewindHook=t=>this.rewindSession(e.sessionId,t,{afterCurrentTurn:!0}),e.onTitleChange(t=>{this.persistTitle(e.sessionId,t).catch(()=>{})}),e.onPriorityChange(t=>{this.persistPriority(e.sessionId,t).catch(()=>{})}),e.onAgentChange(({agentId:t,upstreamSessionId:n,...r})=>{this.persistAgentChange(e.sessionId,t,n,r).catch(()=>{})}),e.onModelChange(t=>{this.persistSnapshot(e.sessionId,{currentModel:t}).catch(()=>{})}),e.onModeChange(t=>{this.persistSnapshot(e.sessionId,{currentMode:t}).catch(()=>{})}),e.onInteractiveChange(t=>{this.persistSnapshot(e.sessionId,{interactive:t}).catch(()=>{})}),e.onUsageChange(t=>{this.persistSnapshot(e.sessionId,{currentUsage:Tc(t)}).catch(()=>{})}),e.onAgentCommandsChange(t=>{this.persistSnapshot(e.sessionId,{agentCommands:t.map(n=>({name:n.name,...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModesChange(t=>{this.persistSnapshot(e.sessionId,{agentModes:t.map(n=>({id:n.id,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModelsChange(t=>{this.persistSnapshot(e.sessionId,{agentModels:t.map(n=>({modelId:n.modelId,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onConfigOptionsChange(t=>{this.persistSnapshot(e.sessionId,{configOptionValues:Object.fromEntries(t.map(n=>[n.id,n.currentValue]))}).catch(()=>{})}),e.onAttentionFlagsChange(t=>{this.mutateRecord(e.sessionId,{attentionFlags:t}).catch(()=>{})}),e.onReadStateChange(t=>{this.invalidateListCache(),this.persistReadState(e.sessionId,t).then(()=>this.invalidateListCache()).catch(()=>{})}),this.sessions.set(e.sessionId,e),this.invalidateListCache(),await this.enqueueMetaWrite(e.sessionId,async()=>{let t=await this.store.read(e.sessionId),n=Sm(e,t);await this.store.write(n)}).catch(t=>{this.logger?.warn(`failed to persist session record for ${e.sessionId}: ${t instanceof Error?t.message:String(t)}`)})}async getHistory(e){if(this.sessions.has(e))return this.histories.load(e).catch(()=>[]);if(await this.store.read(e))return this.histories.load(e).catch(()=>[])}async pageHistory(e,t){let n=await this.store.read(e);if(!this.sessions.has(e)&&!n)return;let r=this.sessions.get(e)?.side??n?.side,o=await this.histories.pageBefore(e,{...t,skip:a=>In(a.method,a.params),hydrate:!1}),i=Lt(o.entries,r);return{entries:await this.histories.hydrate(e,ds(i)),hasMore:o.hasMore&&i.length===o.entries.length}}async loadHistory(e,t={}){return this.histories.load(e,t)}async loadToolBlob(e,t){return gn(e,t)}async loadFromDisk(e){let t=await this.store.read(e);if(!t)return;let n=t.title;return n||(n=await this.deriveTitleFromHistory(e)),{hydraSessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,agentId:t.agentId,cwd:t.cwd,title:n,synopsis:t.synopsis,summarizedThroughEntry:t.summarizedThroughEntry,agentArgs:t.agentArgs,currentModel:t.currentModel,currentMode:t.currentMode,currentUsage:Im(t.currentUsage),agentCommands:t.agentCommands,agentModes:t.agentModes,agentModels:t.agentModels,configOptionValues:t.configOptionValues,createdAt:t.createdAt,pendingHistorySync:t.pendingHistorySync,originatingClient:t.originatingClient,interactive:t.interactive,priority:t.priority,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,forwardedEnv:t.forwardedEnv,workspace:t.workspace,compactionState:t.compactionState,attentionFlags:t.attentionFlags?.filter(r=>!(r.source==="daemon"&&r.reason.startsWith("permission:")))}}async setForwardedEnv(e,t){if(t===void 0)return;let n=this.sessions.get(e);n&&(n.forwardedEnv=t),await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r)return;let o={...r,forwardedEnv:t};await this.store.write(o)})}async clearPendingHistorySync(e){await this.enqueueMetaWrite(e,async()=>{let t=await this.store.read(e);if(!t||t.pendingHistorySync!==!0)return;let n={...t};delete n.pendingHistorySync,await this.store.write(n)})}async deriveTitleFromHistory(e){let t=await this.histories.load(e).catch(()=>[]);for(let n of t){let r=n.params;if(r?.update?.sessionUpdate!=="prompt_received")continue;let o=r.update.sentBy;if(typeof o?.fromSession=="string"||typeof o?.clientId=="string"&&o.clientId.startsWith("transformer:"))continue;let i=St(r.update.prompt),a=vo(i,200);if(a&&!a.startsWith("/"))return a}}get(e){return this.sessions.get(e)}liveSessions(){return this.sessions.values()}setLiveConfig(e){e.sessionDefaults&&(this.sessionDefaults=e.sessionDefaults)}activeAgentVersions(){let e=new Map;for(let t of this.sessions.values()){let n=t.agent.installId,r=t.agent.version,o=e.get(n);o||(o=new Set,e.set(n,o)),o.add(r)}return e}async resolveCanonicalId(e){if(this.sessions.has(e)||await this.store.read(e))return e;if(e.startsWith(ye))return;let t=ye+e;if(this.sessions.has(t)||await this.store.read(t))return t}require(e){let t=this.sessions.get(e);if(!t){let n=new Error(`session ${e} not found`);throw n.code=x.SessionNotFound,n}return t}liveListEntry(e){return{sessionId:e.sessionId,upstreamSessionId:e.upstreamSessionId,cwd:e.cwd,workspace:e.workspace,workspaceError:e.workspaceError,title:e.title,agentId:e.agentId,currentModel:e.currentModel,currentUsage:e.currentUsage,parentSessionId:e.parentSessionId,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forkSynthesisState:e.forkSynthesisState,originatingClient:e.originatingClient,interactive:e.interactive,createdAt:new Date(e.createdAt).toISOString(),updatedAt:new Date(e.updatedAt).toISOString(),attachedClients:e.attachedCount,status:"warm",busy:e.turnStartedAt!==void 0,turnStartedAt:e.turnStartedAt,armedTasks:e.armedBackgroundTasks.length,...e.armedSince!==void 0?{armedSince:e.armedSince}:{},awaitingInput:e.awaitingInput,agentPid:e.agentPid,...Bt(e)}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Dn(t.sessionId),d=tn({interactive:t.interactive,...t.originatingClient?{originatingClient:t.originatingClient}:{}},a.hasContent),c=a.mtime??new Date(t.updatedAt).toISOString();return{sessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,cwd:t.cwd,title:t.title,agentId:t.agentId,currentModel:t.currentModel,currentUsage:t.currentUsage,parentSessionId:t.parentSessionId,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,originatingClient:t.originatingClient,interactive:d,priority:t.priority,createdAt:new Date(t.createdAt).toISOString(),updatedAt:c,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,turnStartedAt:t.turnStartedAt,armedTasks:t.armedBackgroundTasks.length,...t.armedSince!==void 0?{armedSince:t.armedSince}:{},awaitingInput:t.awaitingInput,...Bt(t)}}let n=await this.store.read(e).catch(()=>{});if(!n)return;let r=await Dn(n.sessionId),o=tn(n,r.hasContent),i=r.mtime??n.updatedAt;return{sessionId:n.sessionId,upstreamSessionId:n.upstreamSessionId,cwd:n.cwd,title:n.title,agentId:n.agentId,currentModel:n.currentModel,currentUsage:On(n.currentUsage),importedFromMachine:n.importedFromMachine,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,side:n.side,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:o,priority:n.priority,createdAt:n.createdAt,updatedAt:i,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,...Bt(n)}}async list(e={}){return(await this.listing(e)).entries}async listing(e={}){let t=`${e.cwd??""}|${e.includeNonInteractive?"1":"0"}|${e.status??""}`,n=Date.now(),r=this.listCache.get(t);if(r&&r.expiresAt>n)return r.promise;let o=this.listUncached(e);return this.listCache.set(t,{expiresAt:n+s.LIST_CACHE_TTL_MS,promise:o}),o.catch(()=>{let i=this.listCache.get(t);i&&i.promise===o&&this.listCache.delete(t)}),o}invalidateListCache(){this.listCache.clear()}async listUncached(e={}){let t=await this.store.cursor(),{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,cursor:t};let o=await this.store.list().catch(i=>{throw this.logger?.warn(`session list: store.list() failed: ${i?.message??String(i)}`),i});return n.push(...await this.coldRows(o,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,cursor:t}}async listSince(e,t){let{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,removed:[],cursor:await this.store.cursor()};let o=await this.store.listChangedSince(t);return n.push(...await this.coldRows(o.records,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,removed:o.removed,cursor:o.cursor}}async seedSessionIndex(){await this.store.ensureIndex();let e=await this.tombstones.list().catch(()=>[]);for(let t of e){if(t.sessionId===void 0)continue;let n=Date.parse(t.deletedAt);Number.isNaN(n)||await this.store.markDeleted(t.sessionId,n)}}static includeRow(e,t){return e.includeNonInteractive?!0:t===!0}async warmRows(e){let t=[],n=new Set,r=[...this.sessions.values()].filter(i=>Ac(e.cwd,i));if(e.status==="cold"){for(let i of r)n.add(i.sessionId);return{entries:t,liveIds:n}}let o=await Promise.all(r.map(i=>Dn(i.sessionId)));for(let i=0;i<o.length;i+=1){let a=r[i],d=o[i];n.add(a.sessionId);let c=tn({interactive:a.interactive,...a.originatingClient?{originatingClient:a.originatingClient}:{}},d.hasContent);if(!s.includeRow(e,c))continue;let u=d.mtime??new Date(a.updatedAt).toISOString();t.push({sessionId:a.sessionId,upstreamSessionId:a.upstreamSessionId,cwd:a.cwd,workspace:a.workspace,workspaceError:a.workspaceError,title:a.title,agentId:a.agentId,currentModel:a.currentModel,currentUsage:a.currentUsage,parentSessionId:a.parentSessionId,forkedFromSessionId:a.forkedFromSessionId,forkedFromMessageId:a.forkedFromMessageId,side:a.side,originatingClient:a.originatingClient,interactive:c,priority:a.priority,createdAt:new Date(a.createdAt).toISOString(),updatedAt:u,attachedClients:a.attachedCount,status:"warm",agentPid:a.agentPid,busy:a.turnStartedAt!==void 0,turnStartedAt:a.turnStartedAt,armedTasks:a.armedBackgroundTasks.length,...a.armedSince!==void 0?{armedSince:a.armedSince}:{},awaitingInput:a.awaitingInput,compactionState:a.compactionState,forkSynthesisState:a.forkSynthesisState,...Bt(a)})}return{entries:t,liveIds:n}}async coldRows(e,t,n){let r=[],o=e.filter(a=>!t.has(a.sessionId)&&Ac(n.cwd,a)),i=await Promise.all(o.map(a=>Dn(a.sessionId)));for(let a=0;a<o.length;a+=1){let d=o[a],c=i[a],u=tn(d,c.hasContent);if(!s.includeRow(n,u))continue;let l=c.mtime??d.updatedAt;r.push({sessionId:d.sessionId,upstreamSessionId:d.upstreamSessionId,cwd:d.cwd,workspace:d.workspace,title:d.title,agentId:d.agentId,currentModel:d.currentModel,currentUsage:On(d.currentUsage),importedFromMachine:d.importedFromMachine,importedFromUpstreamSessionId:d.importedFromUpstreamSessionId,parentSessionId:d.parentSessionId,forkedFromSessionId:d.forkedFromSessionId,forkedFromMessageId:d.forkedFromMessageId,side:d.side,originatingClient:d.originatingClient,interactive:u,priority:d.priority,createdAt:d.createdAt,updatedAt:l,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,compactionState:d.compactionState,forkSynthesisState:d.forkSynthesisState,...Bt(d)})}return r}async exportBundle(e,t={}){let n=await this.store.read(e);if(!n)return;let r;if(n.lineageId)r=n;else{let c=xn(),u={...n,lineageId:c};await this.enqueueMetaWrite(e,async()=>{let l=await this.store.read(e);l&&(l.lineageId||await this.store.write({...l,lineageId:c}))}).catch(()=>{}),r=u}let o=t.tools??"inline",i=t.includeArchivedHistory?await this.loadArchivedHistory(e,o):await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await xc(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let c of mc(i)){let u=await Ji(e,c);u&&(d[c]=u.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}async loadArchivedHistory(e,t){let n=await this.histories.loadArchives(e),r=await this.histories.load(e,{tools:"references",maxEntries:1/0}),o=[...n,...r];return t==="references"?o:this.histories.hydrate(e,o)}async importBundle(e,t={}){let n=await this.store.findByLineageId(e.session.lineageId);if(n){if(!t.replace){let i=new Error(`bundle already imported as ${n.sessionId}`);throw i.code=x.BundleAlreadyImported,i.existingSessionId=n.sessionId,i}let o=this.sessions.get(n.sessionId);return o&&await o.close({deleteRecord:!1,by:"bundle-import-overwrite"}).catch(()=>{}),await this.writeImportedRecord({sessionId:n.sessionId,bundle:e,preservedCreatedAt:n.createdAt,cwd:t.cwd}),{sessionId:n.sessionId,importedFromSessionId:e.session.sessionId,replaced:!0}}let r=`${ye}${Ct()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let n=await this.store.read(e);if(!n){let b=new Error(`source session not found: ${e}`);throw b.code=x.SessionNotFound,b}let r=t.agentId??n.agentId,o=r!==n.agentId;if(o&&!await this.registry.getAgent(r)){let A=new Error(`agent ${r} not found in registry`);throw A.code=x.AgentNotInstalled,A}let i=await this.histories.load(e).catch(()=>[]),a=i,d,c=t.mode??(t.side?"verbatim":"synthesis"),u,l,p,f=12e4;if(c==="verbatim")if(t.forkAt!==void 0){let b=_n(Bo(i),t.forkAt);if(b<0){let A=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw A.code=x.InvalidParams,A}d=t.forkAt,a=i.slice(0,b+1)}else{let b=xm(i);b?(d=b.messageId,a=i.slice(0,b.index+1)):(d="",a=i.slice(0,0))}else{if(t.forkAt!==void 0&&t.forkAt!==""){let A=_n(Bo(i),t.forkAt);if(A<0){let C=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw C.code=x.InvalidParams,C}d=t.forkAt,a=i.slice(0,A+1)}else d="",a=i;let b=await this.registry.getAgent(r);if(!b){let A=new Error(`agent ${r} not found in registry`);throw A.code=x.AgentNotInstalled,A}p=b,l=n.currentModel,u="running"}let h=await xc(e),w=c==="synthesis",m={...n,lineageId:xn(),agentId:r,interactive:!1,...u!==void 0?{forkSynthesisState:u}:{},summarizedThroughEntry:a.length,...t.title!==void 0?{title:t.title}:{},currentUsage:void 0,...o?{currentModel:void 0,currentMode:void 0,agentCommands:void 0,agentModes:void 0,agentModels:void 0}:{},...t.model!==void 0?{currentModel:t.model}:{}},g=$n({record:m,history:a,promptHistory:h.length>0?h:void 0,hydraVersion:ue,machine:vt()}),y=`${ye}${Ct()}`,k=t.cwd,v;if(t.cwd===void 0&&n.workspace!==void 0){let b=await this.deriveForkWorkspace(n.workspace,`${n.workspace.label}-fork-${y.slice(-6)}`);b!==void 0?(v=b,k=b.path):(k=n.workspace.sourceCwd,this.logger?.warn?.(`fork ${y}: could not derive an isolated workspace from ${n.workspace.path}; running unisolated in ${k}`))}await this.writeImportedRecord({sessionId:y,bundle:g,cwd:k,...v!==void 0?{workspace:v}:{},forkedFromSessionId:e,forkedFromMessageId:d,...t.side!==void 0?{side:{...t.side.selection!==void 0?{selection:t.side.selection}:{},...Ma(a)}}:{},...u!==void 0?{forkSynthesisState:u}:{}});let S=w?(async()=>{try{let b=await Me(p,[],{npmRegistry:this.npmRegistry}),A=await Os({agentId:r,cwd:t.cwd??E.sessionDir(e),plan:b,history:a,modelId:l,sessionId:e,logger:this.logger,timeoutMs:f});A&&A.synopsis?await this.mutateRecord(y,{synopsis:A.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(y,{},["forkSynthesisState"]))}catch(b){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${b.message}`);try{await this.mutateRecord(y,{},["forkSynthesisState"])}catch(A){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${A.message}`)}}})():Promise.resolve();if(t.prompt!==void 0&&t.prompt.trim()!==""){let b=t.prompt;S.catch(()=>{}).then(()=>this.deliverHeadlessPrompt(y,b)).catch(A=>{this.logger?.warn(`forkSession(${e}): headless prompt delivery to ${y} failed: ${A.message}`)})}return{sessionId:y,forkedFromSessionId:e,forkedAt:d}}async deliverHeadlessPrompt(e,t){let n=await this.loadFromDisk(e);if(!n){this.logger?.warn(`deliverHeadlessPrompt: ${e} vanished before its prompt could be sent`);return}let r=this.sessions.get(e)??await this.resurrect(n),o=km(),i={clientId:`fork-prompt-${Ct().slice(0,8)}`,connection:new qe(o),clientInfo:{name:"hydra-acp-fork",version:ue}};await r.attach(i,"none");try{await r.prompt(i.clientId,{sessionId:e,prompt:[{type:"text",text:t}]})}finally{r.detach(i.clientId),o.close()}}async writeImportedRecord(e){if(await this.histories.rewrite(e.sessionId,e.bundle.history),e.bundle.toolBlobs)for(let[o,i]of Object.entries(e.bundle.toolBlobs))await Vi(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await Rt.utimes(E.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await bc(E.tuiHistoryFile(e.sessionId),e.bundle.promptHistory).catch(()=>{});let n=new Date().toISOString(),r=e.forkedFromSessionId!==void 0;await this.enqueueMetaWrite(e.sessionId,async()=>{await this.store.write({sessionId:e.sessionId,lineageId:e.bundle.session.lineageId,upstreamSessionId:"",...r?{forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,...e.side!==void 0?{side:e.side}:{}}:{importedFromSessionId:e.bundle.session.sessionId,importedFromUpstreamSessionId:e.bundle.session.upstreamSessionId,importedFromMachine:e.bundle.exportedFrom.machine},agentId:e.bundle.session.agentId,cwd:e.cwd??e.bundle.session.cwd,workspace:e.workspace,title:e.bundle.session.title,synopsis:e.bundle.session.synopsis,summarizedThroughEntry:e.bundle.session.summarizedThroughEntry,...e.forkSynthesisState!==void 0?{forkSynthesisState:e.forkSynthesisState}:{},currentModel:e.bundle.session.currentModel,currentMode:e.bundle.session.currentMode,currentUsage:e.bundle.session.currentUsage,agentCommands:e.bundle.session.agentCommands,agentModes:e.bundle.session.agentModes,interactive:e.bundle.session.interactive,originatingClient:e.bundle.session.originatingClient,priority:e.bundle.session.priority,attentionFlags:[],createdAt:e.preservedCreatedAt??n,updatedAt:e.bundle.session.updatedAt})})}async agentStoreKey(e,t){let n=t.get(e);if(n!==void 0)return n;let r=e;try{let o=await this.registry.getAgent(e);o&&(r=Wr(o))}catch{}return t.set(e,r),r}async tombstoneAllGenerations(e,t,n){let r=await this.store.read(e).catch(()=>{}),o=new Map;for(let d of r?.upstreamGenerations??[])d.upstreamSessionId&&o.set(`${d.agentId}::${d.upstreamSessionId}`,{agentId:d.agentId,upstreamSessionId:d.upstreamSessionId});o.set(`${t.agentId}::${t.upstreamSessionId}`,{agentId:t.agentId,upstreamSessionId:t.upstreamSessionId});let i=new Date().toISOString(),a=new Map;for(let d of o.values())await this.tombstones.add({agentId:await this.agentStoreKey(d.agentId,a),upstreamSessionId:d.upstreamSessionId,sessionId:e,deletedAt:i,upstreamUpdatedAt:t.upstreamUpdatedAt,cwd:t.cwd,...t.title!==void 0?{title:t.title}:{},reason:n,...t.interactive!==void 0?{interactive:t.interactive}:{}}).catch(()=>{})}async deleteRecord(e,t="user"){let n=await this.store.read(e);if(!n)return!1;if(n.upstreamSessionId){let r=await Dn(e),o=tn(n,r.hasContent);await this.tombstoneAllGenerations(e,{agentId:n.agentId,upstreamSessionId:n.upstreamSessionId,upstreamUpdatedAt:n.updatedAt,cwd:n.cwd,...n.title!==void 0?{title:n.title}:{},...o!==void 0?{interactive:o}:{}},t)}return n.workspace!==void 0&&await this.releaseWorkspace(n.workspace,e).catch(()=>{}),await this.store.delete(e).catch(()=>{}),await this.histories.delete(e).catch(()=>{}),this.invalidateListCache(),!0}async waitForDeletion(e){let t=this.pendingDeletions.get(e);t&&await t}async isTombstoned(e,t){let n=await this.agentStoreKey(e,new Map);return(await this.tombstones.read(n,t).catch(()=>{})??(n!==e?await this.tombstones.read(e,t).catch(()=>{}):void 0))?.reason==="user"}async hasRecord(e){return await this.store.read(e).catch(()=>{})!==void 0}async isRetiredGeneration(e,t){let n=await this.store.read(e).catch(()=>{});return!n||n.upstreamSessionId===t?!1:(n.upstreamGenerations??[]).some(r=>r.upstreamSessionId===t)}async clearWorkspaceBinding(e){if(this.get(e)!==void 0)return"live";let t=await this.store.read(e).catch(()=>{});if(!t)return"missing";let n=t.workspace?.sourceCwd;return await this.mutateRecord(e,n!==void 0?{cwd:n}:{},["workspace"]),"cleared"}async setCwd(e,t){if(this.get(e)!==void 0)return"live";let n=await this.store.read(e).catch(()=>{});return n?n.workspace!==void 0?"bound":await this.dirExists(t)?(await this.mutateRecord(e,{cwd:t}),this.invalidateListCache(),"set"):"not-a-directory":"missing"}async setPriority(e,t){let n=this.get(e);if(n)return n.setPriority(t),!0;if(!await this.hasRecord(e))return!1;let r=t===void 0||t<=0?void 0:Math.floor(t);return await this.persistPriority(e,r),!0}async persistPriority(e,t){t===void 0?await this.mutateRecord(e,{},["priority"]):await this.mutateRecord(e,{priority:t}),this.invalidateListCache()}async setTitle(e,t){let n=this.get(e);return n?(await n.retitle(t),!0):await this.hasRecord(e)?(await this.persistTitle(e,t),!0):!1}async persistTitle(e,t){await this.mutateRecord(e,{title:t})}async persistSynopsis(e,t,n){await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:n})}async persistAgentChange(e,t,n,r={}){await this.mutateRecord(e,{agentId:t,upstreamSessionId:n},void 0,o=>({upstreamGenerations:Pc(o,t,n,void 0,r)}))}async persistSnapshot(e,t){let n={};t.currentModel!==void 0&&(n.currentModel=t.currentModel),t.currentMode!==void 0&&(n.currentMode=t.currentMode),t.currentUsage!==void 0&&(n.currentUsage=t.currentUsage),t.agentCommands!==void 0&&(n.agentCommands=t.agentCommands),t.agentModes!==void 0&&(n.agentModes=t.agentModes),t.agentModels!==void 0&&(n.agentModels=t.agentModels),t.configOptionValues!==void 0&&(n.configOptionValues=t.configOptionValues),t.interactive!==void 0&&(n.interactive=t.interactive),t.cwd!==void 0&&(n.cwd=t.cwd),await this.mutateRecord(e,n)}async setRead(e,t){let n=this.sessions.get(e);if(n)return n.setRead(t),!0;let r=!1;return await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;r=!0;let i=ps(o,t);i!==void 0&&await this.store.write({...o,readAt:i})}),this.invalidateListCache(),r}async persistReadState(e,t){await this.enqueueMetaWrite(e,async()=>{let n=await this.store.read(e);n&&await this.store.write({...n,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt})})}async mutateRecord(e,t,n=[],r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o,...t,...r?r(o):{},updatedAt:new Date().toISOString()};for(let a of n)delete i[a];await this.store.write(i)})}static EXTENSION_STATE_CAP_BYTES=64*1024;async getExtensionState(e,t){return(await this.store.read(e))?.extensionState?.[t]??{}}async getExtensionStateKey(e,t,n){return(await this.getExtensionState(e,t))[n]}async setExtensionStateKey(e,t,n,r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o.extensionState??{}},a={...i[t]??{},[n]:r},d=Buffer.byteLength(JSON.stringify(a),"utf8");if(d>s.EXTENSION_STATE_CAP_BYTES)throw new Error(`extension_state: bucket for ${t} would be ${d} bytes; cap is ${s.EXTENSION_STATE_CAP_BYTES}`);i[t]=a;let c={...o,extensionState:i,updatedAt:new Date().toISOString()};await this.store.write(c)})}async deleteExtensionStateKey(e,t,n){await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r?.extensionState?.[t])return;let o={...r.extensionState},i={...o[t]};if(!(n in i))return;delete i[n],Object.keys(i).length===0?delete o[t]:o[t]=i;let a={...r,extensionState:o,updatedAt:new Date().toISOString()};await this.store.write(a)})}enqueueMetaWrite(e,t){return this.enqueueKeyed(this.metaWriteQueues,e,t)}enqueueKeyed(e,t,n){let o=(e.get(t)??Promise.resolve()).catch(()=>{}).then(n),i=o.catch(()=>{});return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)}),o}liveSessionsIn(e,t){let n=[];for(let r of this.sessions.values())r.sessionId!==t&&r.workspace?.path===e&&n.push(r);return n}async closeAll(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(t=>t.close({deleteRecord:!1,by:"daemon-shutdown"}))),this.sessions.clear()}async flushSynopsis(e){await this.synopsisCoordinator.flush(e)}async shutdownSynopsis(){await this.synopsisCoordinator.shutdown()}scheduleSynopsis(e){this.synopsisCoordinator.schedule(e)}scheduleCompaction(e,t){if(t?.targetAgentId){this.mutateRecord(e,{pendingAgentSwap:t.targetAgentId}).catch(r=>{this.logger?.warn(`scheduleCompaction: failed to stamp pendingAgentSwap for ${e}: ${r instanceof Error?r.message:String(r)}`)});let n=t.targetAgentId;(async()=>{try{let r=await this.store.read(e),o=await this.histories.load(e,{maxEntries:1/0});if(ac(o)===0){this.logger?.info(`compaction: zero-turn fast-path swap sessionId=${e} target=${n}`),await this.dispatchSynthesisSwap(e,void 0,o.length,n);return}if(!r?.synopsis||r.summarizedThroughEntry===void 0){this.synopsisCoordinator.scheduleCompaction(e,t);return}if(o.length!==r.summarizedThroughEntry){this.synopsisCoordinator.scheduleCompaction(e,t);return}this.logger?.info(`compaction: fast-path swap sessionId=${e} target=${n} (reusing artifact @${r.summarizedThroughEntry})`),await this.dispatchSynthesisSwap(e,r.synopsis,r.summarizedThroughEntry,n)}catch(r){this.logger?.warn(`scheduleCompaction: fast-path check failed for ${e}: ${r instanceof Error?r.message:String(r)} \u2014 falling back to synthesis`),this.synopsisCoordinator.scheduleCompaction(e,t)}})();return}this.synopsisCoordinator.scheduleCompaction(e,t)}getCompactionInFlight(){let e=this.synopsisCoordinator.size();return e.inflight>0||e.queued>0}async getPendingAgentSwap(e){return(await this.store.read(e).catch(()=>{}))?.pendingAgentSwap}async getCompactionState(e){return(await this.store.read(e).catch(()=>{}))?.compactionState}async persistRollbackBreadcrumb(e,t){await this.mutateRecord(e,{},void 0,n=>{let r=n.rollbackBreadcrumb;return r!==void 0&&t.runId!==void 0&&r.runId===t.runId?(this.logger?.info(`compaction: keeping rollback breadcrumb pinned at ${r.previousUpstreamSessionId} for runId=${t.runId} sessionId=${e} (later swap of the same run)`),{}):{rollbackBreadcrumb:t}})}async getUpstreamGenerations(e){return(await this.store.read(e).catch(()=>{}))?.upstreamGenerations??[]}async getRollbackBreadcrumb(e){return(await this.store.read(e).catch(()=>{}))?.rollbackBreadcrumb}emitSwapPhase(e,t,n){let r=this.get(e);if(r){if(t){let o=n.phase==="failed";r.broadcastPendingAgentSwap(o?null:t);return}r.broadcastCompactionPhase(n)}}async getSummarizedThroughEntry(e){let t=this.sessions.get(e);return t?t.summarizedThroughEntry:(await this.store.read(e).catch(()=>{}))?.summarizedThroughEntry}async flushMetaWrites(){let e=[...this.metaWriteQueues.values()];e.length!==0&&await Promise.allSettled(e)}async flushHistoryWrites(){await this.histories.flushAll()}async reconcilePermissionFlags(){let e=await this.store.list().catch(()=>[]),t=0;for(let n of e){let r=n.attentionFlags??[],o=r.filter(i=>!(i.source==="daemon"&&i.reason.startsWith("permission:")));if(o.length!==r.length){let i=r.length-o.length;t+=i,await this.mutateRecord(n.sessionId,{attentionFlags:o}).catch(()=>{})}}t>0&&this.logger?.info(`cleared ${t} stale permission attention flags on startup`)}async resumePendingCompactions(){let e=new Set(["requested","running","swap_pending","swap_deferred"]),t=await this.store.list().catch(()=>[]);for(let n of t){let r=n.compactionState;if(r!=null){if(!e.has(r.status)){this.logger?.info(`compaction: not resuming sessionId=${n.sessionId} status=${r.status} (terminal \u2014 user must re-trigger explicitly)`);continue}this.logger?.info(`compaction: resuming sessionId=${n.sessionId} status=${r.status} from prior daemon`);try{this.scheduleCompaction(n.sessionId)}catch(o){this.logger?.warn(`compaction: resume failed for sessionId=${n.sessionId}: ${o instanceof Error?o.message:String(o)}`)}}}}async resumePendingAgentSwaps(){let e=await this.store.list().catch(()=>[]);for(let t of e){let n=t.pendingAgentSwap;if(n)try{let r=await this.histories.load(t.sessionId).catch(()=>[]);t.synopsis!==void 0&&t.summarizedThroughEntry!==void 0&&t.summarizedThroughEntry>=r.length&&t.synopsis?(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${n} with persisted synopsis (history=${r.length})`),await this.dispatchSynthesisSwap(t.sessionId,t.synopsis,t.summarizedThroughEntry??r.length,n)):(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${n} via fresh synthesis (history=${r.length} watermark=${t.summarizedThroughEntry??"(none)"})`),this.scheduleCompaction(t.sessionId,{targetAgentId:n}))}catch(r){this.logger?.warn(`agent-swap: resume failed for sessionId=${t.sessionId}: ${r instanceof Error?r.message:String(r)}`)}}}async resurrectPendingQueues(){let e=await this.store.list().catch(()=>[]);for(let t of e){let n=await Sd(t.sessionId).catch(()=>[]);if(n.length===0)continue;let r=Date.now(),o=n.filter(d=>r-d.enqueuedAt<Ic),i=n.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${Ic/1e3}s)`),await Sn(t.sessionId,o).catch(()=>{})),o.length===0)continue;let a=await this.loadFromDisk(t.sessionId).catch(()=>{});if(!a){this.logger?.warn(`queue replay: no meta for ${t.sessionId}; discarding ${o.length} entr${o.length===1?"y":"ies"}`),await Sn(t.sessionId,[]).catch(()=>{});continue}try{let d=await this.resurrect(a);this.logger?.info(`queue replay: resurrected ${t.sessionId} and replaying ${o.length} prompt(s)`),d.replayPersistedQueue(o)}catch(d){this.logger?.warn(`queue replay: failed to resurrect ${t.sessionId}: ${d.message}`)}}}};function vm(s,e){if(typeof s!="string"||s.length===0)return!1;let t=jn.resolve(s),n=jn.resolve(e);return t===n||t.startsWith(n+jn.sep)}function bm(s){return s!==void 0&&/^\{\s*"session_id"\s*:\s*"[^"]*"\s*,\s*"(?:transcript_path|cwd|permission_mode|hook_event_name)"\s*:/.test(s)}function Ac(s,e){if(s===void 0||s.length===0)return!0;let t=qo(s);if(qo(e.cwd)===t)return!0;let n=e.workspace?.sourceCwd;return n!==void 0&&qo(n)===t}function qo(s){return s.length>1&&s.endsWith("/")?s.replace(/\/+$/,""):s}function Sm(s,e){let n=(s.mergedAvailableCommands().length>0?s.agentOnlyAdvertisedCommands().map(p=>p.description!==void 0?{name:p.name,description:p.description}:{name:p.name}):void 0)??e?.agentCommands,r=s.availableModes(),i=(r.length>0?r.map(p=>{let f={id:p.id};return p.name!==void 0&&(f.name=p.name),p.description!==void 0&&(f.description=p.description),f}):void 0)??e?.agentModes,a=s.availableModels(),c=(a.length>0?a.map(p=>{let f={modelId:p.modelId};return p.name!==void 0&&(f.name=p.name),p.description!==void 0&&(f.description=p.description),f}):void 0)??e?.agentModels,u=s.extraConfigOptionValues(),l=Object.keys(u).length>0?u:e?.configOptionValues;return xo({sessionId:s.sessionId,lineageId:e?.lineageId??xn(),upstreamSessionId:s.upstreamSessionId,importedFromSessionId:e?.importedFromSessionId,importedFromUpstreamSessionId:e?.importedFromUpstreamSessionId,importedFromMachine:e?.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:e?.synopsis,summarizedThroughEntry:e?.summarizedThroughEntry,agentArgs:s.agentArgs,currentModel:s.currentModel??e?.currentModel,currentMode:s.currentMode??e?.currentMode,currentUsage:Tc(s.persistableUsage)??e?.currentUsage,agentCommands:n,agentModes:i,agentModels:c,configOptionValues:l,parentSessionId:s.parentSessionId??e?.parentSessionId,forkedFromSessionId:s.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId??e?.forkedFromMessageId,side:s.side??e?.side,originatingClient:s.originatingClient??e?.originatingClient,interactive:s.interactive??e?.interactive,priority:s.priority??e?.priority,lastTurnEndedAt:s.lastTurnEndedAt??e?.lastTurnEndedAt,readAt:s.readAt??e?.readAt,forwardedEnv:s.forwardedEnv??e?.forwardedEnv,workspace:s.workspace,attentionFlags:s.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?Pc(e,s.agentId,s.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(s.createdAt).toISOString()})}function Tc(s){if(!s)return;let e={};return s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size),s.costAmount!==void 0&&(e.costAmount=s.costAmount),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),s.cumulativeCost!==void 0&&(e.cumulativeCost=s.cumulativeCost),Object.keys(e).length>0?e:void 0}function Im(s){return s?{...s}:void 0}function Am(s){return(s.extendsChain??[s.id]).some(t=>t==="claude-acp"||t.startsWith("claude-acp-"))}var Cm=[{type:"system",subtype:"background_tasks_changed"}];function zo(s,e={}){if(!Am(s))return;let t={extraArgs:{"thinking-display":"summarized"}};return e.model&&(t.model=e.model),{claudeCode:{options:t,emitRawSDKMessages:Cm}}}function Hs(s,e){let t=e.fromObject(s);if(t!==void 0)return t;let n=s[e.nestedKey];if(n&&typeof n=="object"&&!Array.isArray(n)){let i=e.fromObject(n);if(i!==void 0)return i}let r=s._meta;if(r&&typeof r=="object"&&!Array.isArray(r)){for(let[i,a]of Object.entries(r))if(i!=="hydra-acp"&&a&&typeof a=="object"&&!Array.isArray(a)){let d=e.fromObject(a);if(d!==void 0)return d}}let o=Rm(s,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function Jo(s){return Hs(s,{nestedKey:"models",configId:"model",fromObject:e=>Se(e.currentModelId)??Se(e.currentModel)??Se(e.modelId)??Se(e.model),fromConfig:e=>Se(e.currentValue)})}function ht(s,e){if(!s||typeof s!="object")return s;let t=s;if(t.code!==x.AuthRequired)return s;let n=c=>!!c&&typeof c=="object"&&!Array.isArray(c),r=n(t.data)?t.data:{},o=n(r._meta)?r._meta:{},i=n(o["hydra-acp"])?o["hydra-acp"]:{},a=typeof t.message=="string"?t.message:"authentication required",d=new Error(a);return d.code=x.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function Cc(s){return/^[A-Za-z0-9_\-./=:@]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function Rc(s,e,t,n){if(s&&typeof s=="object"&&s.code===x.AuthRequired)return s;let r=s instanceof Error?s.message:String(s),o=r.includes("stderr:"),i=o?"":e.stderrTailText(),a=n?`to reproduce: (cd ${Cc(n.cwd)} && ${[n.command,...n.args].map(Cc).join(" ")})`:"";if(!i&&!a)return s;let d=[o?r:`agent ${t} failed to start: ${r}`];i&&d.push(`stderr: ${i}`),a&&d.push(a);let c=new Error(d.join(`
188
+ `));if(s&&typeof s=="object"){let u=s;typeof u.code=="number"&&(c.code=u.code),u.data!==void 0&&(c.data=u.data)}return c}function Fn(s){return s._meta?.steering?.supported===!0}function Nn(s){if(!Array.isArray(s))return;let e=[];for(let t of s){if(!t||typeof t!="object")continue;let n=t;if(typeof n.id!="string")continue;let r=typeof n.description=="string"?n.description:"",o=n.type==="agent"||n.type==="terminal"?n.type:void 0,i=typeof n.name=="string"?n.name:void 0,a=n._meta,d=a!==null&&typeof a=="object"&&!Array.isArray(a)?a:void 0;e.push({id:n.id,description:r,...o&&{type:o},...i!==void 0&&{name:i},...d&&{_meta:d}})}return e.length>0?e:void 0}function Se(s){if(typeof s!="string")return;let e=s.trim();return e.length>0?e:void 0}function Rm(s,e){let t=s.configOptions;if(Array.isArray(t))for(let n of t){if(!n||typeof n!="object"||Array.isArray(n))continue;let r=n;if(r.id===e)return r}}function Zt(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.configOptions)}function en(s){let e=s.configOptions;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object"||Array.isArray(n))continue;let r=n,o=Se(r.id);if(!o||o==="model"||o==="mode"||o==="agent")continue;let i=ko(r.options);if(i.length===0)continue;let a=Se(r.description);t.push({id:o,name:Se(r.name)??o,...a?{description:a}:{},category:Se(r.category)??"other",type:"select",currentValue:Se(r.currentValue)??i[0].value,options:i})}return t}function gt(s){return s.length>0?s:void 0}function Vo(s){return Hs(s,{nestedKey:"models",configId:"model",fromObject:e=>{let t=An(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=An(e.options);return t.length>0?t:void 0}})??[]}function Go(s){return Hs(s,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=ks(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=ks(e.options);return t.length>0?t:void 0}})??[]}function Ko(s){return Hs(s,{nestedKey:"modes",configId:"mode",fromObject:e=>Se(e.currentModeId)??Se(e.currentMode)??Se(e.modeId)??Se(e.mode),fromConfig:e=>Se(e.currentValue)})}function xm(s){for(let e=s.length-1;e>=0;e--){let t=s[e];if(!t||t.method!=="session/update")continue;let n=t.params?.update;if(n?.sessionUpdate==="turn_complete"&&!(typeof n.messageId!="string"||n.messageId.length===0))return{index:e,messageId:n.messageId}}}async function xc(s){try{let e=await Rt.readFile(E.tuiHistoryFile(s),"utf8"),t=[];for(let n of e.split(`
189
+ `))if(n.length!==0)try{let r=JSON.parse(n);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function Pc(s,e,t,n=new Date().toISOString(),r={}){let{retiredCost:o,retiredUsed:i,startedUsed:a,lifetimeCost:d,reason:c,runId:u}=r,l=h=>d!==void 0&&h.lifetimeCostAtStart!==void 0?Math.max(0,d-h.lifetimeCostAtStart):o,p=s.upstreamGenerations&&s.upstreamGenerations.length>0?[...s.upstreamGenerations]:s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId}]:[],f=p[p.length-1];if(f&&f.upstreamSessionId===t){if(p.length>=2){let h=p[p.length-2];if(h){let w=l(h);p[p.length-2]={...h,...w!==void 0&&h.cost===void 0?{cost:w}:{},...i!==void 0&&h.usedAtEnd===void 0?{usedAtEnd:i}:{}}}}return(c!==void 0&&f.reason===void 0||a!==void 0&&f.usedAtStart===void 0||d!==void 0&&f.lifetimeCostAtStart===void 0)&&(p[p.length-1]={...f,...c!==void 0&&f.reason===void 0?{reason:c,...u!==void 0?{runId:u}:{}}:{},...a!==void 0&&f.usedAtStart===void 0?{usedAtStart:a}:{},...d!==void 0&&f.lifetimeCostAtStart===void 0?{lifetimeCostAtStart:d}:{}}),p}return f&&f.endedAt===void 0&&(p[p.length-1]={...f,endedAt:n,...(()=>{let h=l(f);return h!==void 0?{cost:h}:{}})(),...i!==void 0?{usedAtEnd:i}:{}}),p.push({upstreamSessionId:t,agentId:e,startedAt:n,...c!==void 0?{reason:c}:{},...u!==void 0?{runId:u}:{},...a!==void 0?{usedAtStart:a}:{},...d!==void 0?{lifetimeCostAtStart:d}:{}}),p}async function Dn(s){try{let e=await Rt.stat(E.historyFile(s));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function tn(s,e){return s.interactive!==void 0?s.interactive:s.originatingClient?.name===$s?!1:e?!0:void 0}import{spawn as Em}from"child_process";import*as Bs from"fs";import*as st from"fs/promises";import*as Ws from"path";import Tm from"pino-roll";var Ls=class{windowMs;maxFailures;now;recentExits=[];tripped_;constructor(e={}){this.windowMs=e.windowMs??3e5,this.maxFailures=e.maxFailuresInWindow??10,this.now=e.now??Date.now}recordExit(e,t,n){if(e===78){let i=`exited with code 78 (unrecoverable); fix and run \`${n}s start ${t}\``;return this.tripped_=i,{tripped:i}}let r=this.now();this.recentExits.push(r);let o=r-this.windowMs;for(;this.recentExits.length>0&&this.recentExits[0]<o;)this.recentExits.shift();if(this.recentExits.length>this.maxFailures){let i=Math.round(this.windowMs/6e4),a=`${this.recentExits.length} exits in ${i}m (crash loop); fix and run \`${n}s start ${t}\``;return this.tripped_=a,{tripped:a}}return"restart"}reset(){this.recentExits=[],this.tripped_=void 0}get tripped(){return this.tripped_}};import*as Mc from"fs/promises";import*as Qo from"path";var Us=process.platform!=="win32";var Pm=1e3,Mm=6e4,Yo=3e3,nn=class{entries=new Map;stopping=!1;context;tokenRegistry;breakerOptions;restartBaseMs;restartCapMs;adapter;constructor(e,t,n,r={}){this.adapter=t,this.context=n,this.tokenRegistry=r.tokenRegistry,this.breakerOptions=r.breakerOptions,this.restartBaseMs=r.restartBaseMs??Pm,this.restartCapMs=r.restartCapMs??Mm;for(let o of e)this.entries.set(o.name,this.makeEntry(o))}setContext(e){this.context=e}reportVersion(e,t){let n=this.entries.get(e);n&&(n.version=t)}async start(){if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before start`);await st.mkdir(this.adapter.paths.dir(),{recursive:!0}),await this.reapOrphans();let e=[];for(let t of this.entries.values())t.config.enabled&&e.push(this.spawn(t,0));await Promise.all(e)}async stop(){this.stopping=!0;let e=[];for(let t of this.entries.values()){t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;if(n){try{n.kill("SIGTERM")}catch{}e.push(new Promise(r=>{if(n.exitCode!==null||n.signalCode!==null){r();return}let o=setTimeout(()=>{try{n.kill("SIGKILL")}catch{}r()},Yo);n.on("exit",()=>{clearTimeout(o),r()})}))}}await Promise.allSettled(e);for(let t of this.entries.values()){try{t.logStream?.end()}catch{}t.child=void 0,t.logStream=void 0,t.pid=void 0}}list(){return[...this.entries.values()].map(e=>this.infoFor(e))}get(e){let t=this.entries.get(e);return t?this.infoFor(t):void 0}has(e){return this.entries.has(e)}async startByName(e){let t=this.entries.get(e);if(!t)throw Hn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw Hn(new Error(`${this.adapter.kind} ${e} already running`),"CONFLICT");return t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0),t.manuallyStopped=!1,t.restartCount=0,t.breaker.reset(),t.failureReason=void 0,await this.spawn(t,0),this.infoFor(t)}async stopByName(e){let t=this.entries.get(e);if(!t)throw Hn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;return n?(await this.terminate(t,n),this.infoFor(t)):this.infoFor(t)}async restartByName(e){return await this.stopByName(e),this.startByName(e)}register(e){if(this.entries.has(e.name))throw Hn(new Error(`${this.adapter.kind} ${e.name} already exists`),"CONFLICT");if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before register`);let t=this.makeEntry(e);return this.entries.set(e.name,t),e.enabled&&this.spawn(t,0).catch(n=>{t.failureReason=`spawn: ${n.message}`}),this.infoFor(t)}async unregister(e){let t=this.entries.get(e);if(!t)throw Hn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;n&&await this.terminate(t,n);try{t.logStream?.end()}catch{}this.entries.delete(e)}async terminate(e,t){if(t.exitCode!==null||t.signalCode!==null)return;let n=new Promise(o=>{e.exitWaiters.push(o)});try{t.kill("SIGTERM")}catch{}let r=setTimeout(()=>{try{t.kill("SIGKILL")}catch{}},Yo);typeof r.unref=="function"&&r.unref();try{await n}finally{clearTimeout(r)}}infoFor(e){let t;return e.failureReason!==void 0?t="failed":e.child?t="running":e.restartTimer?t="restarting":e.config.enabled?t="stopped":t="disabled",{name:e.config.name,status:t,pid:e.pid,enabled:e.config.enabled,restartCount:e.restartCount,startedAt:e.startedAt,lastExitCode:e.lastExitCode,logPath:this.adapter.paths.logFile(e.config.name),version:e.version,failureReason:e.failureReason}}makeEntry(e){return{config:e,child:void 0,logStream:void 0,restartTimer:void 0,pid:void 0,startedAt:void 0,restartCount:0,lastExitCode:void 0,manuallyStopped:!1,exitWaiters:[],version:void 0,processToken:void 0,breaker:new Ls(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await st.readdir(this.adapter.paths.dir(),{withFileTypes:!0})}catch(t){if(t.code==="ENOENT")return;throw t}for(let t of e){if(!t.isDirectory())continue;let n=this.adapter.paths.pidFile(t.name),r;try{let o=await st.readFile(n,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&Xo(r)){try{process.kill(r,"SIGTERM")}catch{}let o=Date.now()+Yo;for(;Date.now()<o&&Xo(r);)await new Promise(i=>setTimeout(i,50));if(Xo(r))try{process.kill(r,"SIGKILL")}catch{}}await st.unlink(n).catch(()=>{})}}async spawn(e,t){if(this.stopping||e.manuallyStopped)return;let n=this.context;if(!n)throw new Error(`${this.managerName()}.spawn called before setContext`);let r=e.config,o=r.command.length>0?r.command:[r.name],i=Ws.dirname(this.adapter.paths.logFile(r.name)),a;try{await st.mkdir(i,{recursive:!0}),a=await Tm({file:Ws.join(i,`${r.name}.log`),size:"5m",mkdir:!0,symlink:Us,limit:{count:5}}),a.on("error",m=>{e.failureReason=`log stream: ${m.message}`})}catch(m){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${m.message}`,this.scheduleRestart(e,t+1);return}if(this.stopping||e.manuallyStopped){try{a.end()}catch{}return}a.write(`[hydra-acp] ${new Date().toISOString()} starting ${this.adapter.kind} ${r.name} (attempt ${t+1})
190
190
  `);let d=this.tokenRegistry?.mint(r.name,this.adapter.tokenRole)??n.serviceToken;e.processToken=d,e.version=void 0;let c={...es(),HYDRA_ACP_DAEMON_URL:n.daemonUrl,HYDRA_ACP_DAEMON_HOST:n.daemonHost,HYDRA_ACP_DAEMON_PORT:String(n.daemonPort),HYDRA_ACP_TOKEN:d,HYDRA_ACP_WS_URL:n.daemonWsUrl,HYDRA_ACP_HOME:n.hydraHome,[this.adapter.nameEnvVar]:r.name,...r.env},[u,...l]=o;if(u===void 0){a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} has empty command
191
- `),a.end();return}let p=ce(u),f=[...l,...r.args].map(ce),h;try{let m=Ft(p,f);h=xm(m.command,m.args,{env:c,stdio:["ignore","pipe","pipe"],detached:!1,shell:m.shell,windowsHide:!0})}catch(m){a.write(`[hydra-acp] failed to spawn ${r.name}: ${m.message}
191
+ `),a.end();return}let p=ce(u),f=[...l,...r.args].map(ce),h;try{let m=Ft(p,f);h=Em(m.command,m.args,{env:c,stdio:["ignore","pipe","pipe"],detached:!1,shell:m.shell,windowsHide:!0})}catch(m){a.write(`[hydra-acp] failed to spawn ${r.name}: ${m.message}
192
192
  `),a.end(),this.scheduleRestart(e,t);return}let w=m=>{try{a.write(typeof m=="string"?m:m.toString())}catch{}};if(h.stdout?.on("data",w),h.stderr?.on("data",w),typeof h.pid=="number")try{Bs.writeFileSync(this.adapter.paths.pidFile(r.name),`${h.pid}
193
193
  `,{encoding:"utf8",mode:384})}catch(m){a.write(`[hydra-acp] failed to write pid file for ${r.name}: ${m.message}
194
194
  `)}e.child=h,e.logStream=a,e.pid=typeof h.pid=="number"?h.pid:void 0,e.startedAt=Date.now(),e.lastExitCode=void 0,h.on("error",m=>{a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} error: ${m.message}
195
195
  `)}),h.on("exit",(m,g)=>{try{Bs.unlinkSync(this.adapter.paths.pidFile(r.name))}catch{}a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} exited code=${m??"null"} signal=${g??"null"}
196
196
  `),e.child=void 0,e.pid=void 0,e.lastExitCode=typeof m=="number"?m:void 0,e.processToken&&(this.tokenRegistry?.revoke(r.name),e.processToken=void 0);let y=e.exitWaiters.splice(0);for(let v of y)v();if(this.stopping||e.manuallyStopped){try{a.end()}catch{}e.logStream=void 0;return}e.restartCount+=1;let k=e.breaker.recordExit(m,r.name,this.adapter.kind);if(typeof k=="object"){e.failureReason=k.tripped,a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} circuit breaker tripped: ${k.tripped}
197
- `);try{a.end()}catch{}e.logStream=void 0;return}this.scheduleRestart(e,t+1)})}scheduleRestart(e,t){if(this.stopping||e.manuallyStopped)return;let n=Math.min(this.restartBaseMs*2**Math.min(t,10),this.restartCapMs);e.restartTimer=setTimeout(()=>{e.restartTimer=void 0,this.spawn(e,t).catch(r=>{e.failureReason=`spawn: ${r.message}`})},n),typeof e.restartTimer.unref=="function"&&e.restartTimer.unref()}managerName(){return this.adapter.kind==="extension"?"ExtensionManager":"TransformerManager"}};function Xo(s){try{return process.kill(s,0),!0}catch{return!1}}function jn(s,e){return s.code=e,s}K();var Mm={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:E.extensionsDir,logFile:E.extensionLogFile,pidFile:E.extensionPidFile}},qs=class extends nn{constructor(e,t,n={}){super(e,Mm,t,n)}};K();var _m={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:E.transformersDir,logFile:E.transformerLogFile,pidFile:E.transformerPidFile}},zs=class extends nn{connected=new Map;constructor(e,t,n={}){super(e,_m,t,n)}registerConnection(e,t,n){this.connected.set(e,{name:e,connection:t,intercepts:new Set(n)})}deregisterConnection(e){this.connected.delete(e)}resolveChain(e){let t=[];for(let n of e){let r=this.connected.get(n);r&&t.push(r)}return t}interestedIn(e){let t=[];for(let n of this.connected.values())n.intercepts.has(e)&&t.push(n);return t}};var Js=class{entries=new Map;changeHandlers=[];register(e,t,n){this.entries.set(e,{connection:t,commands:[...n]}),this.fireChanged()}clear(e){this.entries.delete(e)&&this.fireChanged()}get(e){return this.entries.get(e)}has(e){return this.entries.has(e)}list(){let e=[];for(let[t,n]of this.entries)for(let r of n.commands)e.push({name:t,command:r});return e}onChange(e){return this.changeHandlers.push(e),()=>{let t=this.changeHandlers.indexOf(e);t>=0&&this.changeHandlers.splice(t,1)}}fireChanged(){for(let e of this.changeHandlers)try{e()}catch{}}};K();K();import*as Ln from"fs/promises";async function _c(s){let e=E.pidFile(),t=`${e}.${process.pid}.tmp`;await Ln.writeFile(t,JSON.stringify(s)+`
197
+ `);try{a.end()}catch{}e.logStream=void 0;return}this.scheduleRestart(e,t+1)})}scheduleRestart(e,t){if(this.stopping||e.manuallyStopped)return;let n=Math.min(this.restartBaseMs*2**Math.min(t,10),this.restartCapMs);e.restartTimer=setTimeout(()=>{e.restartTimer=void 0,this.spawn(e,t).catch(r=>{e.failureReason=`spawn: ${r.message}`})},n),typeof e.restartTimer.unref=="function"&&e.restartTimer.unref()}managerName(){return this.adapter.kind==="extension"?"ExtensionManager":"TransformerManager"}};function Xo(s){try{return process.kill(s,0),!0}catch{return!1}}function Hn(s,e){return s.code=e,s}K();var _m={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:E.extensionsDir,logFile:E.extensionLogFile,pidFile:E.extensionPidFile}},qs=class extends nn{constructor(e,t,n={}){super(e,_m,t,n)}};K();var $m={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:E.transformersDir,logFile:E.transformerLogFile,pidFile:E.transformerPidFile}},zs=class extends nn{connected=new Map;constructor(e,t,n={}){super(e,$m,t,n)}registerConnection(e,t,n){this.connected.set(e,{name:e,connection:t,intercepts:new Set(n)})}deregisterConnection(e){this.connected.delete(e)}resolveChain(e){let t=[];for(let n of e){let r=this.connected.get(n);r&&t.push(r)}return t}interestedIn(e){let t=[];for(let n of this.connected.values())n.intercepts.has(e)&&t.push(n);return t}};var Js=class{entries=new Map;changeHandlers=[];register(e,t,n){this.entries.set(e,{connection:t,commands:[...n]}),this.fireChanged()}clear(e){this.entries.delete(e)&&this.fireChanged()}get(e){return this.entries.get(e)}has(e){return this.entries.has(e)}list(){let e=[];for(let[t,n]of this.entries)for(let r of n.commands)e.push({name:t,command:r});return e}onChange(e){return this.changeHandlers.push(e),()=>{let t=this.changeHandlers.indexOf(e);t>=0&&this.changeHandlers.splice(t,1)}}fireChanged(){for(let e of this.changeHandlers)try{e()}catch{}}};K();K();import*as Ln from"fs/promises";async function _c(s){let e=E.pidFile(),t=`${e}.${process.pid}.tmp`;await Ln.writeFile(t,JSON.stringify(s)+`
198
198
  `,{encoding:"utf8",mode:384}),await Ln.rename(t,e)}K();import*as Bn from"fs/promises";import*as Vs from"path";var Un=s=>{process.stderr.write(s+`
199
199
  `)};function Zo(s){Un=s??(e=>process.stderr.write(e+`
200
- `))}async function $c(s,e){let t=Le();if(!t)return;let n=await s.load(),r=new Map;for(let d of n.agents)r.set(d.id,d.version??"current");let o=e.activeAgentVersions(),i=Vs.join(E.agentsDir(),t),a;try{a=await Bn.readdir(i,{withFileTypes:!0})}catch(d){let c=d;if(c.code==="ENOENT")return;Un(`hydra-acp: prune: failed to read ${i}: ${c.message}`);return}for(let d of a){if(!d.isDirectory())continue;let c=d.name,u=r.get(c);if(u===void 0)continue;let l=o.get(c)??new Set,p=Vs.join(i,c),f;try{f=await Bn.readdir(p,{withFileTypes:!0})}catch(h){Un(`hydra-acp: prune: failed to read ${p}: ${h.message}`);continue}for(let h of f){if(!h.isDirectory())continue;let w=h.name;if(w===u||l.has(w)||w.includes(".partial-"))continue;let m=Vs.join(p,w);try{await Bn.rm(m,{recursive:!0,force:!0}),Un(`hydra-acp: pruned stale ${c} ${w} (${m})`)}catch(g){Un(`hydra-acp: prune: failed to remove ${m}: ${g.message}`)}}}}function Oc(s){let e,t=!1,n=0,r=(a,d)=>{s.logger&&s.logger[a](`agent-sync: ${d}`)},o=async()=>{let a=[];try{let u=await s.registry.load();for(let l of u.agents)await Jr(l)==="yes"&&a.push(l.id)}catch(u){return r("warn",`registry load failed: ${u.message}`),s.intervalMs}if(a.length===0)return s.intervalMs;let d=n%a.length;n=(n+1)%a.length;let c=a[d];try{let{synced:u,skipped:l}=await s.manager.syncFromAgent(c);r("info",`${c}: synced ${u.length}, skipped ${l}`)}catch(u){r("warn",`${c}: ${u.message}`)}return Math.max(1,Math.floor(s.intervalMs/a.length))},i=a=>{t||(e=setTimeout(()=>{o().then(d=>{i(d)}).catch(d=>{r("warn",`tick crashed: ${d.message}`),i(s.intervalMs)})},a),e.unref())};return i(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}async function ei(s){let e=s.maxDeletions??200,t=(f,h)=>{s.logger&&s.logger[f](`session-gc: ${h}`)},n=Date.now(),r=s.maxAgeMs>0?n-s.maxAgeMs:Number.POSITIVE_INFINITY,o=await s.manager.list({includeNonInteractive:!0}).catch(f=>(t("warn",`manager.list failed: ${f.message}`),[])),i=[];for(let f of o){if(f.status!=="cold")continue;if((s.selection??"explicit")==="explicit"){if(f.interactive!==!1)continue}else if(f.interactive===!0)continue;let w=Date.parse(f.updatedAt);Number.isFinite(w)&&(s.maxAgeMs>0&&w>r||i.push({sessionId:f.sessionId,lastUsedMs:w}))}if(i.length===0)return s.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((f,h)=>f.lastUsedMs-h.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,c=0,u=0;for(let{sessionId:f}of a)try{await s.manager.deleteRecord(f,"expired")&&(c+=1)}catch(h){u+=1,t("warn",`delete ${f} failed: ${h.message}`)}let l=i.length-a.length;if(s.verbose||c>0||u>0){let f=(s.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${c} ${f} session(s) older than ${$m(s.maxAgeMs)}`+(u>0?`; ${u} failed`:"")+(l>0?`; ${l} deferred to next sweep`:""))}let p={considered:i.length,deleted:c,failed:u,deferred:l};return d!==void 0&&(p.oldestLastUsedMs=d),p}function Fc(s){let e,t=!1,n=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!n){n=!0;try{await ei({manager:s.manager,maxAgeMs:s.maxAgeMs,selection:"unpromoted",...s.maxDeletionsPerSweep!==void 0?{maxDeletions:s.maxDeletionsPerSweep}:{},...s.logger?{logger:s.logger}:{}})}finally{n=!1}}})().catch(a=>{s.logger?.warn(`session-gc: sweep crashed: ${a.message}`)}).finally(()=>{r(s.intervalMs)})},o),e.unref())};return r(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}function $m(s){if(s<=0)return"any age";let e=s/(1440*60*1e3);if(e>=1)return`${e.toFixed(e>=10?0:1)}d`;let t=s/(3600*1e3);return`${t.toFixed(t>=10?0:1)}h`}import{createHash as Om}from"crypto";function Wn(s){if(Array.isArray(s))return s.map(Wn);if(s!==null&&typeof s=="object"){let e={};for(let t of Object.keys(s).sort())e[t]=Wn(s[t]);return e}return s}function Nc(s){let e={};for(let[n,r]of Object.entries(s)){let o=Ir(n);if(o.nested){let i={};for(let[a,d]of Object.entries(r??{}))Ar(a).reload==="restart"&&(i[a]=d);Object.keys(i).length>0&&(e[n]=i);continue}o.reload==="restart"&&(e[n]=r)}let t=JSON.stringify(Wn(e));return Om("sha256").update(t).digest("hex").slice(0,16)}function Dc(s,e){let t=[],n=(r,o)=>JSON.stringify(Wn(r))!==JSON.stringify(Wn(o));for(let r of Object.keys(e)){let o=Ir(r),i=e[r],a=s[r];if(o.nested){for(let d of Object.keys(i??{})){if(Ar(d).reload!=="warn")continue;let c=i[d],u=(a??{})[d];n(u,c)&&t.push(`${r}.${d}`)}continue}o.reload==="warn"&&n(a,i)&&t.push(r)}return t}import*as jc from"fs/promises";K();var Fm=3e3;async function Hc(){try{return(await jc.stat(E.config())).mtimeMs}catch{return}}function Lc(s){let e=s.intervalMs??Fm,t=!1,n,r,o=Hc().then(d=>{r=d}),i=async()=>{await o;let d=await Hc();if(d===r)return;r=d;let c;try{c=await pn()}catch(l){s.logger?.warn(`config-reload: config.json changed but did not parse (${l.message}); keeping the loaded config`);return}try{s.apply(c)}catch(l){s.logger?.warn(`config-reload: applying live config failed: ${l.message}`)}let u=Dc(s.bootConfig,c);s.onDrift?.(u),s.logger?.info(u.length>0?`config-reload: applied live config; restart-only keys differing from boot: ${u.join(", ")}`:"config-reload: applied live config")},a=()=>{t||(n=setTimeout(()=>{i().finally(a)},e),n.unref?.())};return a(),()=>{t=!0,n&&clearTimeout(n)}}K();He();import*as Wc from"path";import{createHash as Nm,randomBytes as Dm,timingSafeEqual as Hm}from"crypto";var qc="hydra_session_",jm=3600*24*30,Uc=12,Lm=32,Um=50;function Bm(){return Wc.join(E.home(),"session-tokens.json")}function Bc(s){return Nm("sha256").update(s).digest("hex")}function zc(s){return Dm(s).toString("hex")}function Wm(){return zc(Uc).slice(0,Uc*2)}function qm(){return`${qc}${zc(Lm)}`}var Gs=class s{records=new Map;writeTimer=null;writeInflight=null;filePath;constructor(e,t){this.filePath=t;for(let n of e)this.records.set(n.hash,n)}static async load(){let e=[],t=Bm(),n=await de(t);n&&Array.isArray(n.records)&&(e=n.records.filter(zm));let r=new s(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=qm(),n=Bc(t),r=Wm(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:jm,a=new Date(o.getTime()+i*1e3),d={id:r,hash:n,label:e.label,createdAt:o.toISOString(),expiresAt:a.toISOString(),lastUsedAt:o.toISOString()};return this.records.set(n,d),this.scheduleWrite(),{id:r,token:t,expiresAt:d.expiresAt}}async verify(e){if(typeof e!="string"||!e.startsWith(qc))return;let t=Bc(e),n=this.records.get(t);if(!n)return;let r=Buffer.from(n.hash,"hex"),o=Buffer.from(t,"hex");if(r.length!==o.length||!Hm(r,o))return;let i=new Date;if(new Date(n.expiresAt).getTime()<=i.getTime()){this.records.delete(t),this.scheduleWrite();return}return n.lastUsedAt=i.toISOString(),this.scheduleWrite(),n.id}async revoke(e){for(let[t,n]of this.records)if(n.id===e)return this.records.delete(t),this.scheduleWrite(),!0;return!1}async revokeAll(){let e=this.records.size;return this.records.clear(),this.scheduleWrite(),e}list(){return Array.from(this.records.values()).map(({id:e,label:t,createdAt:n,expiresAt:r,lastUsedAt:o})=>({id:e,label:t,createdAt:n,expiresAt:r,lastUsedAt:o})).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}sweepExpired(e=new Date){let t=0;for(let[n,r]of this.records)new Date(r.expiresAt).getTime()<=e.getTime()&&(this.records.delete(n),t+=1);return t>0&&this.scheduleWrite(),t}async flush(){this.writeTimer&&(clearTimeout(this.writeTimer),this.writeTimer=null),await this.persist()}scheduleWrite(){this.writeTimer||(this.writeTimer=setTimeout(()=>{this.writeTimer=null,this.persist().catch(()=>{})},Um))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>he(this.filePath,{records:Array.from(this.records.values())},{mode:384}));return this.writeInflight=e,e.catch(()=>{}).finally(()=>{this.writeInflight===e&&(this.writeInflight=null)}),e}};function zm(s){if(!s||typeof s!="object")return!1;let e=s;return typeof e.id=="string"&&typeof e.hash=="string"&&typeof e.createdAt=="string"&&typeof e.expiresAt=="string"&&typeof e.lastUsedAt=="string"&&(e.label===void 0||typeof e.label=="string")}var Jc="Bearer ",Ks=class{constructor(e){this.token=e}token;async validate(e){return Vm(e,this.token)?"service":void 0}rotate(e){this.token=e}},Qs=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},Ys=class{constructor(e){this.validators=e}validators;async validate(e){for(let t of this.validators){let n=await t.validate(e);if(n!==void 0)return n}}};function Vc(s){return async function(t,n){let r=t.headers.authorization;if(!r||!r.startsWith(Jc)){n.code(401).send({error:"Missing bearer token"});return}let o=r.slice(Jc.length).trim(),i=await s.validator.validate(o);if(!i){n.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function Gc(s){let e=s.headers["sec-websocket-protocol"],t=Array.isArray(e)?e.join(","):e;if(t)for(let n of t.split(",")){let r=n.trim(),o="hydra-acp-token.";if(r.startsWith(o))return r.slice(o.length)}if(s.url)try{let r=new URL(s.url,"http://localhost").searchParams.get("token");if(r)return r}catch{return}}var Xs=class{tokens=new Map;mint(e,t){let n=br();return this.tokens.set(n,{name:e,kind:t}),n}revoke(e){for(let[t,n]of this.tokens)n.name===e&&this.tokens.delete(t)}resolve(e){return this.tokens.get(e)}async validate(e){let t=this.tokens.get(e);if(t)return`${t.kind}:${t.name}`}},Jm=new Set(["GET /v1/sessions","GET /v1/sessions/:id","GET /v1/config","GET /v1/system"]);function Kc(s,e){return e?Jm.has(`${s} ${e}`):!1}function Vm(s,e){if(s.length!==e.length)return!1;let t=0;for(let n=0;n<s.length;n+=1)t|=s.charCodeAt(n)^e.charCodeAt(n);return t===0}var Zs=class{entries=new Map;maxFails;windowMs;constructor(e=10,t=900*1e3){this.maxFails=e,this.windowMs=t}isBlocked(e){let t=this.entries.get(e);return t?Date.now()-t.windowStart>this.windowMs?(this.entries.delete(e),!1):t.fails>=this.maxFails:!1}recordFailure(e){let t=Date.now(),n=this.entries.get(e);if(!n||t-n.windowStart>this.windowMs){this.entries.set(e,{fails:1,windowStart:t});return}n.fails+=1}recordSuccess(e){this.entries.delete(e)}sweepExpired(){let e=Date.now();for(let[t,n]of this.entries)e-n.windowStart>this.windowMs&&this.entries.delete(t)}};import*as oi from"fs";import*as mu from"os";import*as or from"path";import*as ii from"readline";K();function ti(s){return Math.floor(s/4)}function Qc(s){let e=0,t=new Map;for(let n of s){let r=n.params;if(!r||typeof r!="object")continue;let o=r.update;if(!o||typeof o!="object")continue;let i=o;switch(i.sessionUpdate){case"user_message_chunk":case"agent_message_chunk":case"agent_thought_chunk":e+=xt(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=Gm(i),c=t.get(a)??0;d>c&&t.set(a,d);break}default:break}}for(let n of t.values())e+=n;return e}function Gm(s){let e=0;return typeof s.title=="string"&&(e+=s.title.length),e+=er(s.rawInput),e+=xt(s.content),e+=er(s.rawOutput),e}function er(s){if(s==null)return 0;if(typeof s=="string")return s.length;if(typeof s=="number"||typeof s=="boolean")return String(s).length;if(Array.isArray(s)){let e=0;for(let t of s)e+=er(t);return e}if(typeof s=="object"){let e=s.bytes;if(typeof s.__hydraBlob=="string"&&typeof e=="number")return e;let t=0;for(let n of Object.values(s))t+=er(n);return t}return 0}function xt(s){if(s==null)return 0;if(typeof s=="string")return s.length;if(Array.isArray(s)){let t=0;for(let n of s)t+=xt(n);return t}if(typeof s!="object")return 0;let e=s;return typeof e.__hydraBlob=="string"&&typeof e.bytes=="number"?e.bytes:e.text!==void 0?xt(e.text):e.type==="diff"?xt(e.oldText)+xt(e.newText):e.content!==void 0?xt(e.content):0}function Yc(s){if(s.compactionInFlight||s.totalEntries===0)return!1;let e,t;if(typeof s.agentReportedUsed=="number"&&typeof s.agentReportedSize=="number"&&s.agentReportedSize>0)e=s.agentReportedUsed/s.agentReportedSize,t=!0;else{let r=ti(s.unsummarizedChars),o=s.currentModel!==void 0?s.config.modelContextWindows[s.currentModel]??s.config.absoluteFallback:s.config.absoluteFallback;e=r/o,t=!1}if(t&&e>=s.config.hardCeilingFraction)return!0;let n=s.nowMs-s.lastActivityMs;return e>=s.config.contextFraction&&n>=s.config.idleBeforePromptMs}function Xc(s){let e=new Map,t=new Map;for(let r of s){let i=r.params?.update;if(!i||typeof i!="object")continue;let a=i.sessionUpdate;if(a!=="tool_call"&&a!=="tool_call_update")continue;let d=typeof i.toolCallId=="string"&&i.toolCallId.length>0?i.toolCallId:void 0,c=Qm(i);if(c.length===0)continue;let u=c;if(d!==void 0){let l=e.get(d)??[],p=[];for(let f of c)l.some(h=>h.path===f.path&&h.oldText===f.oldText&&h.newText===f.newText)||p.push(f);if(p.length===0)continue;e.set(d,[...l,...p]),u=p}for(let l of u)Km(t,l)}let n=[];for(let[r,o]of t)n.push({path:r,hunks:o.hunks,created:o.created});return n}function Zc(s){let e=[];for(let t of s){let n=-1;for(let o=e.length-1;o>=0;o--)if(e[o].newText===t.oldText){n=o;break}if(n===-1){e.push(t);continue}let r=e[n];e.splice(n,1,{oldText:r.oldText,newText:t.newText})}return e}function Km(s,e){let t={oldText:e.oldText,newText:e.newText},n=s.get(e.path);if(n===void 0){s.set(e.path,{hunks:[t],created:e.oldText.length===0});return}n.hunks.push(t)}function Qm(s){let e=[];for(let t of fs(s))t.path!==void 0&&e.push({path:t.path,...Wa(t)});return e}function tu(s,e={}){let t=Xm(s),{events:n,window:r}=Ym(t,e),o=Zm(n),i=[];ey(i,s),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),ty(i,n,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
200
+ `))}async function $c(s,e){let t=Le();if(!t)return;let n=await s.load(),r=new Map;for(let d of n.agents)r.set(d.id,d.version??"current");let o=e.activeAgentVersions(),i=Vs.join(E.agentsDir(),t),a;try{a=await Bn.readdir(i,{withFileTypes:!0})}catch(d){let c=d;if(c.code==="ENOENT")return;Un(`hydra-acp: prune: failed to read ${i}: ${c.message}`);return}for(let d of a){if(!d.isDirectory())continue;let c=d.name,u=r.get(c);if(u===void 0)continue;let l=o.get(c)??new Set,p=Vs.join(i,c),f;try{f=await Bn.readdir(p,{withFileTypes:!0})}catch(h){Un(`hydra-acp: prune: failed to read ${p}: ${h.message}`);continue}for(let h of f){if(!h.isDirectory())continue;let w=h.name;if(w===u||l.has(w)||w.includes(".partial-"))continue;let m=Vs.join(p,w);try{await Bn.rm(m,{recursive:!0,force:!0}),Un(`hydra-acp: pruned stale ${c} ${w} (${m})`)}catch(g){Un(`hydra-acp: prune: failed to remove ${m}: ${g.message}`)}}}}function Oc(s){let e,t=!1,n=0,r=(a,d)=>{s.logger&&s.logger[a](`agent-sync: ${d}`)},o=async()=>{let a=[];try{let u=await s.registry.load();for(let l of u.agents)await Jr(l)==="yes"&&a.push(l.id)}catch(u){return r("warn",`registry load failed: ${u.message}`),s.intervalMs}if(a.length===0)return s.intervalMs;let d=n%a.length;n=(n+1)%a.length;let c=a[d];try{let{synced:u,skipped:l}=await s.manager.syncFromAgent(c);r("info",`${c}: synced ${u.length}, skipped ${l}`)}catch(u){r("warn",`${c}: ${u.message}`)}return Math.max(1,Math.floor(s.intervalMs/a.length))},i=a=>{t||(e=setTimeout(()=>{o().then(d=>{i(d)}).catch(d=>{r("warn",`tick crashed: ${d.message}`),i(s.intervalMs)})},a),e.unref())};return i(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}async function ei(s){let e=s.maxDeletions??200,t=(f,h)=>{s.logger&&s.logger[f](`session-gc: ${h}`)},n=Date.now(),r=s.maxAgeMs>0?n-s.maxAgeMs:Number.POSITIVE_INFINITY,o=await s.manager.list({includeNonInteractive:!0}).catch(f=>(t("warn",`manager.list failed: ${f.message}`),[])),i=[];for(let f of o){if(f.status!=="cold")continue;if((s.selection??"explicit")==="explicit"){if(f.interactive!==!1)continue}else if(f.interactive===!0)continue;let w=Date.parse(f.updatedAt);Number.isFinite(w)&&(s.maxAgeMs>0&&w>r||i.push({sessionId:f.sessionId,lastUsedMs:w}))}if(i.length===0)return s.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((f,h)=>f.lastUsedMs-h.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,c=0,u=0;for(let{sessionId:f}of a)try{await s.manager.deleteRecord(f,"expired")&&(c+=1)}catch(h){u+=1,t("warn",`delete ${f} failed: ${h.message}`)}let l=i.length-a.length;if(s.verbose||c>0||u>0){let f=(s.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${c} ${f} session(s) older than ${Om(s.maxAgeMs)}`+(u>0?`; ${u} failed`:"")+(l>0?`; ${l} deferred to next sweep`:""))}let p={considered:i.length,deleted:c,failed:u,deferred:l};return d!==void 0&&(p.oldestLastUsedMs=d),p}function Fc(s){let e,t=!1,n=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!n){n=!0;try{await ei({manager:s.manager,maxAgeMs:s.maxAgeMs,selection:"unpromoted",...s.maxDeletionsPerSweep!==void 0?{maxDeletions:s.maxDeletionsPerSweep}:{},...s.logger?{logger:s.logger}:{}})}finally{n=!1}}})().catch(a=>{s.logger?.warn(`session-gc: sweep crashed: ${a.message}`)}).finally(()=>{r(s.intervalMs)})},o),e.unref())};return r(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}function Om(s){if(s<=0)return"any age";let e=s/(1440*60*1e3);if(e>=1)return`${e.toFixed(e>=10?0:1)}d`;let t=s/(3600*1e3);return`${t.toFixed(t>=10?0:1)}h`}import{createHash as Fm}from"crypto";function Wn(s){if(Array.isArray(s))return s.map(Wn);if(s!==null&&typeof s=="object"){let e={};for(let t of Object.keys(s).sort())e[t]=Wn(s[t]);return e}return s}function Nc(s){let e={};for(let[n,r]of Object.entries(s)){let o=Ir(n);if(o.nested){let i={};for(let[a,d]of Object.entries(r??{}))Ar(a).reload==="restart"&&(i[a]=d);Object.keys(i).length>0&&(e[n]=i);continue}o.reload==="restart"&&(e[n]=r)}let t=JSON.stringify(Wn(e));return Fm("sha256").update(t).digest("hex").slice(0,16)}function Dc(s,e){let t=[],n=(r,o)=>JSON.stringify(Wn(r))!==JSON.stringify(Wn(o));for(let r of Object.keys(e)){let o=Ir(r),i=e[r],a=s[r];if(o.nested){for(let d of Object.keys(i??{})){if(Ar(d).reload!=="warn")continue;let c=i[d],u=(a??{})[d];n(u,c)&&t.push(`${r}.${d}`)}continue}o.reload==="warn"&&n(a,i)&&t.push(r)}return t}import*as Hc from"fs/promises";K();var Nm=3e3;async function jc(){try{return(await Hc.stat(E.config())).mtimeMs}catch{return}}function Lc(s){let e=s.intervalMs??Nm,t=!1,n,r,o=jc().then(d=>{r=d}),i=async()=>{await o;let d=await jc();if(d===r)return;r=d;let c;try{c=await pn()}catch(l){s.logger?.warn(`config-reload: config.json changed but did not parse (${l.message}); keeping the loaded config`);return}try{s.apply(c)}catch(l){s.logger?.warn(`config-reload: applying live config failed: ${l.message}`)}let u=Dc(s.bootConfig,c);s.onDrift?.(u),s.logger?.info(u.length>0?`config-reload: applied live config; restart-only keys differing from boot: ${u.join(", ")}`:"config-reload: applied live config")},a=()=>{t||(n=setTimeout(()=>{i().finally(a)},e),n.unref?.())};return a(),()=>{t=!0,n&&clearTimeout(n)}}K();je();import*as Wc from"path";import{createHash as Dm,randomBytes as jm,timingSafeEqual as Hm}from"crypto";var qc="hydra_session_",Lm=3600*24*30,Uc=12,Um=32,Bm=50;function Wm(){return Wc.join(E.home(),"session-tokens.json")}function Bc(s){return Dm("sha256").update(s).digest("hex")}function zc(s){return jm(s).toString("hex")}function qm(){return zc(Uc).slice(0,Uc*2)}function zm(){return`${qc}${zc(Um)}`}var Gs=class s{records=new Map;writeTimer=null;writeInflight=null;filePath;constructor(e,t){this.filePath=t;for(let n of e)this.records.set(n.hash,n)}static async load(){let e=[],t=Wm(),n=await de(t);n&&Array.isArray(n.records)&&(e=n.records.filter(Jm));let r=new s(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=zm(),n=Bc(t),r=qm(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:Lm,a=new Date(o.getTime()+i*1e3),d={id:r,hash:n,label:e.label,createdAt:o.toISOString(),expiresAt:a.toISOString(),lastUsedAt:o.toISOString()};return this.records.set(n,d),this.scheduleWrite(),{id:r,token:t,expiresAt:d.expiresAt}}async verify(e){if(typeof e!="string"||!e.startsWith(qc))return;let t=Bc(e),n=this.records.get(t);if(!n)return;let r=Buffer.from(n.hash,"hex"),o=Buffer.from(t,"hex");if(r.length!==o.length||!Hm(r,o))return;let i=new Date;if(new Date(n.expiresAt).getTime()<=i.getTime()){this.records.delete(t),this.scheduleWrite();return}return n.lastUsedAt=i.toISOString(),this.scheduleWrite(),n.id}async revoke(e){for(let[t,n]of this.records)if(n.id===e)return this.records.delete(t),this.scheduleWrite(),!0;return!1}async revokeAll(){let e=this.records.size;return this.records.clear(),this.scheduleWrite(),e}list(){return Array.from(this.records.values()).map(({id:e,label:t,createdAt:n,expiresAt:r,lastUsedAt:o})=>({id:e,label:t,createdAt:n,expiresAt:r,lastUsedAt:o})).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}sweepExpired(e=new Date){let t=0;for(let[n,r]of this.records)new Date(r.expiresAt).getTime()<=e.getTime()&&(this.records.delete(n),t+=1);return t>0&&this.scheduleWrite(),t}async flush(){this.writeTimer&&(clearTimeout(this.writeTimer),this.writeTimer=null),await this.persist()}scheduleWrite(){this.writeTimer||(this.writeTimer=setTimeout(()=>{this.writeTimer=null,this.persist().catch(()=>{})},Bm))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>he(this.filePath,{records:Array.from(this.records.values())},{mode:384}));return this.writeInflight=e,e.catch(()=>{}).finally(()=>{this.writeInflight===e&&(this.writeInflight=null)}),e}};function Jm(s){if(!s||typeof s!="object")return!1;let e=s;return typeof e.id=="string"&&typeof e.hash=="string"&&typeof e.createdAt=="string"&&typeof e.expiresAt=="string"&&typeof e.lastUsedAt=="string"&&(e.label===void 0||typeof e.label=="string")}var Jc="Bearer ",Ks=class{constructor(e){this.token=e}token;async validate(e){return Gm(e,this.token)?"service":void 0}rotate(e){this.token=e}},Qs=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},Ys=class{constructor(e){this.validators=e}validators;async validate(e){for(let t of this.validators){let n=await t.validate(e);if(n!==void 0)return n}}};function Vc(s){return async function(t,n){let r=t.headers.authorization;if(!r||!r.startsWith(Jc)){n.code(401).send({error:"Missing bearer token"});return}let o=r.slice(Jc.length).trim(),i=await s.validator.validate(o);if(!i){n.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function Gc(s){let e=s.headers["sec-websocket-protocol"],t=Array.isArray(e)?e.join(","):e;if(t)for(let n of t.split(",")){let r=n.trim(),o="hydra-acp-token.";if(r.startsWith(o))return r.slice(o.length)}if(s.url)try{let r=new URL(s.url,"http://localhost").searchParams.get("token");if(r)return r}catch{return}}var Xs=class{tokens=new Map;mint(e,t){let n=br();return this.tokens.set(n,{name:e,kind:t}),n}revoke(e){for(let[t,n]of this.tokens)n.name===e&&this.tokens.delete(t)}resolve(e){return this.tokens.get(e)}async validate(e){let t=this.tokens.get(e);if(t)return`${t.kind}:${t.name}`}},Vm=new Set(["GET /v1/sessions","GET /v1/sessions/:id","GET /v1/config","GET /v1/system"]);function Kc(s,e){return e?Vm.has(`${s} ${e}`):!1}function Gm(s,e){if(s.length!==e.length)return!1;let t=0;for(let n=0;n<s.length;n+=1)t|=s.charCodeAt(n)^e.charCodeAt(n);return t===0}var Zs=class{entries=new Map;maxFails;windowMs;constructor(e=10,t=900*1e3){this.maxFails=e,this.windowMs=t}isBlocked(e){let t=this.entries.get(e);return t?Date.now()-t.windowStart>this.windowMs?(this.entries.delete(e),!1):t.fails>=this.maxFails:!1}recordFailure(e){let t=Date.now(),n=this.entries.get(e);if(!n||t-n.windowStart>this.windowMs){this.entries.set(e,{fails:1,windowStart:t});return}n.fails+=1}recordSuccess(e){this.entries.delete(e)}sweepExpired(){let e=Date.now();for(let[t,n]of this.entries)e-n.windowStart>this.windowMs&&this.entries.delete(t)}};import*as oi from"fs";import*as mu from"os";import*as or from"path";import*as ii from"readline";K();function ti(s){return Math.floor(s/4)}function Qc(s){let e=0,t=new Map;for(let n of s){let r=n.params;if(!r||typeof r!="object")continue;let o=r.update;if(!o||typeof o!="object")continue;let i=o;switch(i.sessionUpdate){case"user_message_chunk":case"agent_message_chunk":case"agent_thought_chunk":e+=xt(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=Km(i),c=t.get(a)??0;d>c&&t.set(a,d);break}default:break}}for(let n of t.values())e+=n;return e}function Km(s){let e=0;return typeof s.title=="string"&&(e+=s.title.length),e+=er(s.rawInput),e+=xt(s.content),e+=er(s.rawOutput),e}function er(s){if(s==null)return 0;if(typeof s=="string")return s.length;if(typeof s=="number"||typeof s=="boolean")return String(s).length;if(Array.isArray(s)){let e=0;for(let t of s)e+=er(t);return e}if(typeof s=="object"){let e=s.bytes;if(typeof s.__hydraBlob=="string"&&typeof e=="number")return e;let t=0;for(let n of Object.values(s))t+=er(n);return t}return 0}function xt(s){if(s==null)return 0;if(typeof s=="string")return s.length;if(Array.isArray(s)){let t=0;for(let n of s)t+=xt(n);return t}if(typeof s!="object")return 0;let e=s;return typeof e.__hydraBlob=="string"&&typeof e.bytes=="number"?e.bytes:e.text!==void 0?xt(e.text):e.type==="diff"?xt(e.oldText)+xt(e.newText):e.content!==void 0?xt(e.content):0}function Yc(s){if(s.compactionInFlight||s.totalEntries===0)return!1;let e,t;if(typeof s.agentReportedUsed=="number"&&typeof s.agentReportedSize=="number"&&s.agentReportedSize>0)e=s.agentReportedUsed/s.agentReportedSize,t=!0;else{let r=ti(s.unsummarizedChars),o=s.currentModel!==void 0?s.config.modelContextWindows[s.currentModel]??s.config.absoluteFallback:s.config.absoluteFallback;e=r/o,t=!1}if(t&&e>=s.config.hardCeilingFraction)return!0;let n=s.nowMs-s.lastActivityMs;return e>=s.config.contextFraction&&n>=s.config.idleBeforePromptMs}function Xc(s){let e=new Map,t=new Map;for(let r of s){let i=r.params?.update;if(!i||typeof i!="object")continue;let a=i.sessionUpdate;if(a!=="tool_call"&&a!=="tool_call_update")continue;let d=typeof i.toolCallId=="string"&&i.toolCallId.length>0?i.toolCallId:void 0,c=Ym(i);if(c.length===0)continue;let u=c;if(d!==void 0){let l=e.get(d)??[],p=[];for(let f of c)l.some(h=>h.path===f.path&&h.oldText===f.oldText&&h.newText===f.newText)||p.push(f);if(p.length===0)continue;e.set(d,[...l,...p]),u=p}for(let l of u)Qm(t,l)}let n=[];for(let[r,o]of t)n.push({path:r,hunks:o.hunks,created:o.created});return n}function Zc(s){let e=[];for(let t of s){let n=-1;for(let o=e.length-1;o>=0;o--)if(e[o].newText===t.oldText){n=o;break}if(n===-1){e.push(t);continue}let r=e[n];e.splice(n,1,{oldText:r.oldText,newText:t.newText})}return e}function Qm(s,e){let t={oldText:e.oldText,newText:e.newText},n=s.get(e.path);if(n===void 0){s.set(e.path,{hunks:[t],created:e.oldText.length===0});return}n.hunks.push(t)}function Ym(s){let e=[];for(let t of fs(s))t.path!==void 0&&e.push({path:t.path,...Wa(t)});return e}function tu(s,e={}){let t=Zm(s),{events:n,window:r}=Xm(t,e),o=ey(n),i=[];ty(i,s),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),ny(i,n,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
201
201
  `);return a.endsWith(`
202
202
  `)||(a+=`
203
- `),a}function ni(s,e){let t=s<0?e+s+1:s;return t<1?1:t>e?e:t}function Ym(s,e){if(!(e.from!==void 0||e.to!==void 0||e.last!==void 0)&&e.sinceMs===void 0)return{events:s};let n=[],r=0;for(let{event:f}of s)f.kind==="user-text"&&(r+=1),n.push(r===0?1:r);let o=Math.max(r,1),i=1,a=o;if(e.last!==void 0&&e.last>0?i=ni(o-e.last+1,o):(e.from!==void 0&&(i=ni(e.from,o)),e.to!==void 0&&(a=ni(e.to,o))),i>a)return{events:[],window:{from:i,to:a,total:o}};let d=e.sinceMs,c=new Set;d!==void 0&&s.forEach((f,h)=>{f.recordedAt>=d&&c.add(n[h])});let u=[],l,p;return s.forEach((f,h)=>{let w=n[h];w<i||w>a||d!==void 0&&!c.has(w)||(u.push(f),l??=w,p=w)}),{events:u,window:{from:l??i,to:p??a,total:o}}}function Xm(s){let e=[];for(let t of s.history){if(t.method!=="session/update")continue;let n=t.params;if(!n||typeof n!="object")continue;let r=Va(n.update,{cwd:s.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function Zm(s){let e=new Map;for(let{event:t}of s){if(t.kind==="tool-call"){let n=e.get(t.toolCallId);e.set(t.toolCallId,{title:t.title,status:t.status??n?.status??"pending"});continue}if(t.kind==="tool-call-update"){let n=e.get(t.toolCallId)??{title:"tool call",status:"pending"};e.set(t.toolCallId,{title:t.title??n.title,status:t.status??n.status})}}return e}function ey(s,e){let t=e.session,n=et(t.sessionId),r=t.title?.trim()||`Hydra session ${n}`;s.push(`# ${qn(r)}`),s.push("");let o=[];o.push(`- **Session:** \`${n}\` (lineage \`${t.lineageId}\`)`);let i=[t.agentId];t.currentModel&&i.push(`model: ${t.currentModel}`),t.currentMode&&i.push(`mode: ${t.currentMode}`),o.push(`- **Agent:** ${i.filter(Boolean).join(" \xB7 ")}`),o.push(`- **Cwd:** ${t.cwd}`),o.push(`- **Exported:** ${e.exportedAt} from ${e.exportedFrom.machine} (hydra ${e.exportedFrom.hydraVersion})`);let a=t.currentUsage;if(a&&(a.used!==void 0||a.costAmount!==void 0||a.cumulativeCost!==void 0)){let d=[];if(a.used!==void 0){let u=a.size!==void 0?`${si(a.size)}`:void 0;d.push(u?`${si(a.used)} / ${u} tokens`:`${si(a.used)} tokens`)}let c=Wo(a);if(c!==void 0){let u=a.costCurrency??"USD";d.push(`$${c.toFixed(2)} ${u}`)}o.push(`- **Usage:** ${d.join(" \xB7 ")}`)}s.push(o.join(`
204
- `)),s.push("")}function ty(s,e,t,n){let{includeTools:r,includeThoughts:o}=n;if(!e.some(w=>ny(w.event,o))){s.push("_No conversation history recorded._"),s.push("");return}let i=0,a="",d="",c=[],u=new Set,l=!1,p=()=>{if(c.length!==0){for(let w of c)s.push(w);s.push(""),c=[]}},f=()=>{p(),d.length>0&&(eu(s,d.trimEnd(),"*"),s.push(""),d=""),a.length!==0&&(s.push(a.trimEnd()),s.push(""),a="")},h=()=>{l||(l=!0)};for(let{event:w}of e)switch(w.kind){case"user-text":{f(),s.push("---"),s.push(""),i+=1,eu(s,w.text,"**"),s.push(""),l=!0;break}case"agent-text":h(),a+=w.text;break;case"agent-thought":{if(!o)break;h(),a.length>0&&(s.push(a.trimEnd()),s.push(""),a=""),d+=w.text;break}case"tool-call":{if(!r||(h(),(a.length>0||d.length>0)&&f(),u.has(w.toolCallId)))break;u.add(w.toolCallId);let m=t.get(w.toolCallId)??{title:w.title,status:w.status??"pending"};c.push(`- ${ry(m.status)} ${sy(m)}`);break}case"tool-call-update":break;case"plan":{h(),f(),s.push("**Plan:**"),s.push("");for(let m of w.entries){let g=m.status==="completed"?"[x]":"[ ]";s.push(`- ${g} ${qn(m.content)}`)}s.push("");break}case"mode-changed":h(),f(),s.push(`_mode: ${qn(w.mode)}_`),s.push("");break;case"model-changed":h(),f(),s.push(`_model: ${qn(w.model)}_`),s.push("");break;case"turn-complete":f();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}f()}function ny(s,e){switch(s.kind){case"agent-thought":return e;case"usage-update":case"available-commands":case"session-info":case"unknown":case"turn-complete":return!1;default:return!0}}function sy(s){let e=s.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${qn(s.title)}${t}`}function ry(s){switch(s){case"completed":return"\u2713";case"failed":return"\u2717";case"cancelled":case"rejected":return"\u2298";case"in_progress":return"\u21BB";default:return"\xB7"}}var nu=String.raw`<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s[^<>]*)?\/?>`,oy=new RegExp(nu);function eu(s,e,t){if(oy.test(e)){iy(s,e);return}let n=e.split(/\n\s*\n/);for(let r=0;r<n.length;r++){let o=n[r];if(o.trim().length===0)continue;let i=o.split(`
205
- `);for(let a=0;a<i.length;a++){let d=i[a];s.push(a===0&&a===i.length-1?`${t}${d}${t}`:a===0?`${t}${d}`:a===i.length-1?`${d}${t}`:d)}r<n.length-1&&s.push("")}}function iy(s,e){let t=e.replace(/\s+$/,"");if(t.length===0)return;let n=0;for(let o of t.match(/`+/g)??[])n=Math.max(n,o.length);let r="`".repeat(Math.max(3,n+1));s.push(r);for(let o of t.split(`
206
- `))s.push(o);s.push(r)}function qn(s){return s.replace(new RegExp(nu,"g"),e=>e.replace(/</g,"&lt;").replace(/>/g,"&gt;"))}function si(s){return s.toLocaleString("en-US")}function Ie(s){return s==="127.0.0.1"||s==="::1"||s==="localhost"||s==="[::1]"}function ay(s){let e=s.trim();if(e.length===0)return{operator:"OR",terms:[]};let t=/\w+:"[^"]*"|"[^"]*"|\S+/g,n=[],r;for(;(r=t.exec(e))!==null;)n.push(r[0]);let o="OR",i=!1,a=!1,d=[];for(let u of n){let l=u.toUpperCase();l==="AND"?i=!0:l==="OR"?a=!0:d.push(u)}i?o="AND":a&&(o="OR");let c=d.map(u=>dy(u)).filter(u=>u.term.length>0);return{operator:o,terms:c}}function dy(s){let e=/^(\w+):"([^"]*)"$/.exec(s);if(e)return{scope:su(e[1]),term:e[2]};let t=/^"([^"]*)"$/.exec(s);if(t)return{scope:"all",term:t[1]};let n=/^(prompt|response|tool|edit|edited):([\s\S]*)$/i.exec(s);return n?{scope:su(n[1]),term:n[2].trim()}:{scope:"all",term:s.trim()}}function su(s){switch(s.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";case"edit":case"edited":return"edit";default:return"all"}}function cy(s,e){return e==="edit"?s==="edit":s==="edit"?!1:s==="all"?!0:s==="user"?e==="user":s==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var uy=5,ly=200,nr=72,fy=24,py=512;function du(s){return Number.isFinite(s)?Math.max(fy,Math.min(py,Math.floor(s))):nr}async function cu(s,e,t={}){let n=ay(e);if(n.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??uy,o=t.maxSessions??ly,i=du(t.snippetWidth??nr),a=t.sessionIds?new Set(t.sessionIds):null,d=await s.list(),c=a?d.filter(p=>a.has(p.sessionId)):d,u=[],l=!1;for(let p of c){if(u.length>=o){l=!0;break}let f=await s.loadHistory(p.sessionId,{tools:"references"}).catch(()=>[]),h=hy(f,n,r,i,gy(p));if(h.snippets.length===0)continue;let w={sessionId:p.sessionId,cwd:p.cwd,status:p.status,updatedAt:p.updatedAt,totalMatches:h.totalMatches,snippets:h.snippets};p.title!==void 0&&(w.title=p.title),u.push(w)}return{query:e,truncated:l,results:u}}function gy(s){let e=s.workspace?.sourceCwd;if(e===void 0||e.length===0||s.cwd.length===0)return;let t=s.cwd.endsWith("/")?s.cwd:s.cwd+"/";return n=>n.startsWith(t)?e.replace(/\/+$/,"")+"/"+n.slice(t.length):n}function hy(s,e,t,n=nr,r){if(e.terms.length===0)return{totalMatches:0,snippets:[]};let o=0,i=[],a=Math.max(1,Math.floor(t/e.terms.length)),d=[];for(let{scope:c,term:u}of e.terms){let l=my(s,u,c,t,n,r);if(e.operator==="AND"&&l.totalMatches===0)return{totalMatches:0,snippets:[]};o+=l.totalMatches,i.push(...l.snippets.slice(0,a)),d.push(...l.snippets.slice(a))}for(let c of d){if(i.length>=t)break;i.push(c)}return{totalMatches:o,snippets:i.slice(0,t)}}function my(s,e,t,n,r,o){let i=e.toLowerCase(),a=0,d=[],c=new Set;for(let u of s){let l=yy(u).filter(p=>cy(t,p.kind));for(let p of l){let f=p.text.toLowerCase();if(p.kind==="edit"){let m=o?.(p.text);if(!(ru(p.text,e)||(m!==void 0&&m!==p.text?ru(m,e):!1))||c.has(p.text))continue;if(c.add(p.text),a+=1,d.length<n){let y={kind:"edit",text:p.text,recordedAt:u.recordedAt};p.toolName!==void 0&&(y.toolName=p.toolName),d.push(y)}continue}let h=f.indexOf(i);if(h===-1)continue;let w=0;for(;h!==-1;)w++,h=f.indexOf(i,h+i.length);if(a+=w,d.length<n){let m=f.indexOf(i),g={kind:p.kind,text:Iy(p.text,m,i.length,r),recordedAt:u.recordedAt};p.toolName!==void 0&&(g.toolName=p.toolName),d.push(g)}}}return{totalMatches:a,snippets:d}}function yy(s){if(s.method!=="session/update")return[];let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return[];let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:n.kind;if(typeof r!="string")return[];switch(r){case"agent_message_chunk":{let o=tr(n.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof n.text=="string"?ve(n.text):tr(n.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if(by(n))return[];let o=tr(n.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=Sy(n.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return wy(n);default:return[]}}function wy(s){let e=iu(s,"name"),t=iu(s,"title"),n=[];if(t!==void 0){let a=ie(t);if(a.length>0){let d={kind:"tool",text:a};e!==void 0&&(d.toolName=e),n.push(d)}}if(e!==void 0&&e!==t){let a=ie(e);a.length>0&&n.push({kind:"tool",toolName:e,text:a})}let r=s.rawInput;if(r&&typeof r=="object"){let a=au(r);if(a.length>0){let d={kind:"tool-input",text:ie(a)};e!==void 0&&(d.toolName=e),n.push(d)}}for(let a of Ba(s)){let d={kind:"edit",text:a};e!==void 0&&(d.toolName=e),n.push(d)}let o=s.locations;if(Array.isArray(o)&&o.length>0){let a=au(o);if(a.length>0){let d={kind:"tool-input",text:ie(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let i=ky(s);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),n.push(a)}return n}function ru(s,e){let t=ou(s.toLowerCase()),n=ou(e.toLowerCase());if(n.length===0)return!1;if(n.startsWith("/"))return t===n||t.startsWith(n+"/");let r="/"+n,o=t.indexOf(r);for(;o!==-1;){let i=o+r.length;if(i===t.length||t[i]==="/")return!0;o=t.indexOf(r,o+1)}return t===n||t.startsWith(n+"/")}function ou(s){return s.length>1&&s.endsWith("/")?s.slice(0,-1):s}function ky(s){if(!vy(s.status))return null;let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=n.content;if(!o||typeof o!="object")continue;let i=o;if(i.type==="text"&&typeof i.text=="string"){let a=ie(i.text);if(a.length>0)return a}}let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.error;if(typeof n=="string"){let r=ie(n);if(r.length>0)return r}}return null}function vy(s){return s==="failed"||s==="rejected"||s==="cancelled"}function by(s){let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e["hydra-acp"];return!t||typeof t!="object"||Array.isArray(t)?!1:t.compatFor==="prompt_received"}function tr(s){if(typeof s=="string")return ve(s);if(!s||typeof s!="object"||Array.isArray(s))return"";let e=s;return typeof e.text=="string"?ve(e.text):""}function Sy(s){if(!Array.isArray(s))return"";let e=[];for(let t of s){let n=tr(t);n.length>0&&e.push(n)}return e.join("")}function iu(s,e){let t=s[e];return typeof t=="string"?t:void 0}function au(s){try{return JSON.stringify(s)}catch{return""}}function Iy(s,e,t,n=nr){let r=s.replace(/\s+/g," ").trim();if(r.length===0)return"";let o=r.toLowerCase(),i=s.slice(e,e+t).toLowerCase().replace(/\s+/g," ").trim(),a=i.length>0?o.indexOf(i):0;a===-1&&(a=0);let d=du(n),c=Math.max(0,d-i.length),u=Math.floor(c/2),l=Math.min(u,a),p=Math.min(c-l,r.length-(a+i.length)),f=Math.max(0,a-(c-p)),h=Math.min(r.length,a+i.length+p),w=f>0?"\u2026":"",m=h<r.length?"\u2026":"";return`${w}${r.slice(f,h)}${m}`}import{randomBytes as lu}from"crypto";function uu(s){let e=lu(32).toString("hex");return s.tokenRegistry.reserve(e).complete(s.session),s.session.onClose(()=>{s.tokenRegistry.unbind(e)}),{name:s.name,type:"http",url:`${s.getOrigin()}/mcp/${s.name}`,headers:[{name:"Authorization",value:`Bearer ${e}`}]}}function ri(s){if(s.deps.mcpTokenRegistry===void 0||s.deps.getDaemonOrigin===void 0)return;let e=s.deps.mcpTokenRegistry,t=s.deps.getDaemonOrigin;return async n=>{let r=[...s.baselineMcpServers??[]];s.stdinEnabled&&r.push(uu({name:"hydra-acp-stdin",session:n,tokenRegistry:e,getOrigin:t})),r.push(uu({name:"hydra-acp-recall",session:n,tokenRegistry:e,getOrigin:t}));let o=sn(s.deps);return o!==void 0&&(o.bindToSession(n),r=[...r,...o.descriptors]),r}}function sn(s){if(s.extensionMcp===void 0||s.mcpTokenRegistry===void 0||s.getDaemonOrigin===void 0)return;let e=s.extensionMcp.list();if(e.length===0)return;let t=lu(32).toString("hex"),n=s.mcpTokenRegistry.reserve(t),r=s.getDaemonOrigin(),o=e.map(a=>({name:a,type:"http",url:`${r}/mcp/${a}`,headers:[{name:"Authorization",value:`Bearer ${t}`}]})),i=s.mcpTokenRegistry;return{descriptors:o,bindToSession:a=>{n.complete(a),a.onClose(()=>{i.unbind(t)})},abandon:a=>n.abandon(a)}}var Ay=new Set(["/v1/sessions/:id/history","/v1/sessions/:id/events"]);function fu(s,e){let t=e.fetchImpl??fetch;s.addHook("preHandler",async(n,r)=>{let o=n.routeOptions.url;if(!o||!o.startsWith("/v1/sessions/:id"))return;let i=n.params,a=i.id;if(typeof a!="string")return;let d=ft(a);if(!d){if(!e.localMiss||await e.localMiss.resolvesLocally(a))return;let g=e.localMiss.cache.findByLocalId(a);if(g.length===0)return;if(g.length>1){r.code(404).send({error:`Session "${a}" exists on more than one remote (${g.map(y=>y.name).join(", ")}). Address it as "<remote>:${a}".`});return}d=g[0]}let c=e.store.get(d.name);if(!c){r.code(404).send({error:`No remote named "${d.name}". Run \`hydra remote add\` first.`});return}let u=n.query;if(Ay.has(o)&&Ry(u?.follow)){let g=c.port===_t?"":`:${c.port}`;r.code(501).send({error:`Streaming a federated session isn't supported yet. Attach directly with hydra://${c.host}${g}/${d.localId} instead.`});return}let l=xy(o,i,d.localId,n.url),f=`${Ie(c.host)?"http":"https"}://${c.host}:${c.port}${l}`,h;try{h=await t(f,{method:n.method,headers:{Authorization:`Bearer ${c.token}`,...n.body!==void 0?{"Content-Type":"application/json"}:{}},...n.body!==void 0&&n.method!=="GET"?{body:JSON.stringify(n.body)}:{}})}catch(g){r.code(502).send({error:`Could not reach remote "${d.name}" (${c.host}:${c.port}): ${g.message}`});return}if(n.method==="DELETE"&&o==="/v1/sessions/:id"&&(h.ok||h.status===404)&&e.localMiss?.cache.evict(d.name,d.localId),h.status===204){r.code(204).send();return}let w=await h.text(),m=h.headers.get("content-type");m&&r.header("content-type",m),r.code(h.status).send(w)})}var Cy=5e3,sr=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;perPeer=new Map;timer;start(){this.timer||(this.refreshNow(),this.timer=setInterval(()=>{this.refreshNow()},this.opts.intervalMs??Cy),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}async refreshNow(){let e=this.opts.fetchImpl??fetch,t=new Set(this.store.list().map(n=>n.name));for(let n of[...this.perPeer.keys()])t.has(n)||this.perPeer.delete(n);await Promise.allSettled(this.store.list().map(async n=>{let r=this.store.get(n.name);if(!r)return;let o=this.perPeer.get(n.name),i=Ie(r.host)?"http":"https",a=new URLSearchParams({includeNonInteractive:"1"}),d=o?.cursor!==void 0;d&&a.set("since",String(o.cursor));let c=`${i}://${r.host}:${r.port}/v1/sessions?${a.toString()}`,u;try{u=await e(c,{headers:{Authorization:`Bearer ${r.token}`}})}catch{return}if(!u.ok)return;let l=await u.json(),p=o?.sessions??new Map;if(d){for(let[f,h]of[...p])h.status!=="cold"&&p.delete(f);for(let f of l.removed??[])p.delete(Je({name:n.name,localId:f}))}else p.clear();for(let f of l.sessions??[]){let h=Je({name:n.name,localId:String(f.sessionId)});p.set(h,{...f,sessionId:h,remote:n.name})}this.perPeer.set(n.name,{cursor:l.cursor,sessions:p})}))}list(e){let t=[];for(let n of this.perPeer.values())t.push(...n.sessions.values());return t.filter(n=>!(e.status&&n.status!==e.status||!e.includeNonInteractive&&n.interactive!==!0))}evict(e,t){this.perPeer.get(e)?.sessions.delete(Je({name:e,localId:t}))}findByLocalId(e){let t=e.startsWith(ye)?[e]:[e,ye+e],n=[];for(let[r,o]of this.perPeer)for(let i of t)if(o.sessions.has(Je({name:r,localId:i}))){n.push({name:r,localId:i});break}return n}};async function pu(s,e,t,n=fetch){let r=s.get(e);if(!r)return{status:404,body:{error:`No remote named "${e}". Run \`hydra remote add\` first.`}};let i=`${Ie(r.host)?"http":"https"}://${r.host}:${r.port}/v1/sessions`,a;try{a=await n(i,{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(l){return{status:502,body:{error:`Could not reach remote "${e}" (${r.host}:${r.port}): ${l.message}`}}}let d=await a.text(),c=null;try{c=d.length>0?JSON.parse(d):null}catch{c=null}if(!a.ok)return{status:a.status,body:c};let u=c;return u&&typeof u.sessionId=="string"?{status:a.status,body:{...u,sessionId:Je({name:e,localId:u.sessionId})}}:{status:a.status,body:c}}async function gu(s,e,t=fetch){let n;if(e.sessionIds===void 0)n=s.list().map(a=>({name:a.name}));else{let a=new Map;for(let d of e.sessionIds){let c=ft(d);if(!c)continue;let u=a.get(c.name)??[];u.push(c.localId),a.set(c.name,u)}n=[...a.entries()].map(([d,c])=>({name:d,sessionIds:c}))}if(n.length===0)return{query:e.q,truncated:!1,results:[]};let r=await Promise.all(n.map(async a=>{let d=s.get(a.name);if(!d)return null;let u=`${Ie(d.host)?"http":"https"}://${d.host}:${d.port}/v1/sessions/search`,l;try{l=await t(u,{method:"POST",headers:{Authorization:`Bearer ${d.token}`,"Content-Type":"application/json"},body:JSON.stringify({q:e.q,...a.sessionIds?{sessionIds:a.sessionIds}:{},...e.snippetWidth!==void 0?{snippetWidth:e.snippetWidth}:{}})})}catch{return null}if(!l.ok)return null;let p;try{p=await l.json()}catch{return null}let f=p;if(!f||!Array.isArray(f.results))return null;let h=f.results.map(w=>({...w,sessionId:Je({name:a.name,localId:w.sessionId})}));return{query:e.q,truncated:f.truncated===!0,results:h}})),o=[],i=!1;for(let a of r)a!==null&&(o.push(...a.results),i=i||a.truncated);return{query:e.q,truncated:i,results:o}}function Ry(s){return s==="1"||s==="true"||s===!0}function xy(s,e,t,n){let r=s.replace(/:([A-Za-z_]+)/g,(i,a)=>encodeURIComponent(a==="id"?t:e[a]??"")),o=n.indexOf("?");return o===-1?r:r+n.slice(o)}var rr=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function hu(s){if(s.publicHost&&s.publicHost.length>0)return s.publicHost;if(s.host&&!Ie(s.host))return s.port!==void 0?`${s.host}:${s.port}`:s.host}function yu(s,e,t,n={},r,o){s.get("/v1/sessions",async(p,f)=>{let h=p.query,w=h?.includeNonInteractive==="1"||h?.includeNonInteractive==="true",m;if(h?.since!==void 0&&(m=Number(h.since),!Number.isFinite(m)||m<0))return f.code(400).send({error:`since must be a non-negative number, got ${JSON.stringify(h.since)}`});let g=h?.status==="warm"||h?.status==="cold"?h.status:void 0,y={cwd:h?.cwd,includeNonInteractive:w,...g?{status:g}:{}},k=o&&!y.cwd?o.list({includeNonInteractive:w,...g?{status:g}:{}}):[];if(m!==void 0){let S=await e.listSince(y,m);return{sessions:[...S.entries,...k],removed:S.removed,cursor:S.cursor}}let v=await e.listing(y);return{sessions:[...v.entries,...k],removed:[],cursor:v.cursor}}),s.get("/v1/sessions/:id",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=await e.getOne(w);return m||(f.code(404).send({error:"session not found"}),f)}),s.post("/v1/sessions/search",async(p,f)=>{let h=p.body??{},w=typeof h.q=="string"?h.q:"";if(w.trim().length===0)return f.code(400).send({error:"q is required"}),f;let m=Array.isArray(h.sessionIds)?h.sessionIds.filter(v=>typeof v=="string"&&v.length>0):void 0,g={sessionIds:m};typeof h.snippetWidth=="number"&&(g.snippetWidth=h.snippetWidth);let y=await cu(e,w,g);if(!r)return y;let k=await gu(r,{q:w,...m?{sessionIds:m}:{},...g.snippetWidth!==void 0?{snippetWidth:g.snippetWidth}:{}});return{query:w,truncated:y.truncated||k.truncated,results:[...y.results,...k.results]}}),s.post("/v1/sessions",async(p,f)=>{let h=p.body??{};if(h.remote){if(!r)return f.code(404).send({error:`No remote named "${h.remote}". Run \`hydra remote add\` first.`});let v=await pu(r,h.remote,{cwd:h.cwd,agentId:h.agentId,mcpServers:h.mcpServers,workspace:h.workspace});return f.code(v.status).send(v.body)}let w=ce(h.cwd??t.cwd),m=await fn(w),g=h.agentId??m.agentId??t.agentId,y=sn(n),k=y!==void 0?[...h.mcpServers??[],...y.descriptors]:h.mcpServers;try{let v=await e.create({cwd:w,agentId:g,mcpServers:k,...h.workspace!==void 0?{workspace:h.workspace}:{}});y!==void 0&&y.bindToSession(v),f.code(201).send({sessionId:v.sessionId,agentId:v.agentId,cwd:v.cwd,...v.workspace!==void 0?{workspace:v.workspace}:{},...v.workspaceError!==void 0?{workspaceError:v.workspaceError}:{}})}catch(v){y!==void 0&&y.abandon(v instanceof Error?v:void 0),f.code(500).send({error:v.message})}}),s.post("/v1/sessions/collect",async(p,f)=>{let h=p.body??{},w=typeof h.maxAgeDays=="number"&&h.maxAgeDays>0?h.maxAgeDays*24*60*60*1e3:0,m=typeof h.limit=="number"&&h.limit>0?h.limit:1e3,g=h.selection==="explicit"||h.selection==="unpromoted"?h.selection:"unpromoted";try{let y=await ei({manager:e,maxAgeMs:w,maxDeletions:m,selection:g,verbose:!1});f.code(200).send(y)}catch(y){f.code(500).send({error:y.message})}}),s.get("/v1/sessions/tombstones",async(p,f)=>{let h=p.query;if(h.since!==void 0&&Number.isNaN(Date.parse(h.since))){f.code(400).send({error:"since must be an ISO timestamp"});return}let w=await e.listTombstones({...h.agent?{agentId:h.agent}:{},...h.since?{since:h.since}:{},...h.grep?{grep:h.grep}:{}});f.code(200).send({tombstones:w})}),s.post("/v1/sessions/undelete",async(p,f)=>{let h=p.body??{};if(!Array.isArray(h.ids)||h.ids.length===0||!h.ids.every(w=>typeof w=="string"&&w.length>0)){f.code(400).send({error:"ids must be a non-empty array of strings"});return}try{f.code(200).send(await e.undeleteSessions(h.ids))}catch(w){f.code(500).send({error:w.message})}}),s.post("/v1/sessions/:id/kill",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(m){m.close({deleteRecord:!1,by:"REST POST /kill"}).catch(()=>{}),f.code(202).send();return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.post("/v1/sessions/:id/stdin/open",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(!m)return f.code(404).send({error:"session not found"}),f;let g=p.body??{},y={};(g.mode==="memory"||g.mode==="file")&&(y.mode=g.mode),typeof g.capacityBytes=="number"&&(y.capacityBytes=g.capacityBytes),typeof g.fileCapBytes=="number"&&(y.fileCapBytes=g.fileCapBytes),(y.mode??"memory")==="file"&&(y.filePathFor=k=>or.join(mu.tmpdir(),`hydra-acp-stdin-${k}.log`));try{return m.openStream(y)}catch(k){return f.code(409).send({error:k.message}),f}}),s.post("/v1/sessions/:id/stdin",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(!m)return f.code(404).send({error:"session not found"}),f;let g=p.body??{},y=typeof g.chunk=="string"?g.chunk:"",k=g.eof===!0;try{return m.streamWrite(y,k)}catch(v){return f.code(409).send({error:v.message}),f}}),s.patch("/v1/sessions/:id",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=p.body??{};if(m.cwd!==void 0){if(typeof m.cwd!="string"||!or.isAbsolute(m.cwd)){f.code(400).send({error:"cwd must be an absolute path"});return}let y=await e.setCwd(w,m.cwd);if(y==="missing"){f.code(404).send({error:"session not found"});return}if(y==="not-a-directory"){f.code(400).send({error:`${m.cwd} is not a directory`});return}if(y==="live"){f.code(409).send({error:"session is live; its agent was spawned in its cwd and cannot change directory. Moving a live session is a swap \u2014 use `workspace start` in it."});return}if(y==="bound"){f.code(409).send({error:"session is isolated, so its cwd IS its workspace. Clear the binding first (PATCH { workspace: null }) or leave the workspace from inside the session."});return}f.code(204).send();return}if("workspace"in m){if(m.workspace!==null){f.code(400).send({error:"workspace may only be set to null (clear the binding)"});return}let y=await e.clearWorkspaceBinding(w);if(y==="missing"){f.code(404).send({error:"session not found"});return}if(y==="live"){f.code(409).send({error:"session is live; its cwd is the workspace. Use `workspace stop` or `workspace detach` in the session so the agent moves with the binding."});return}f.code(204).send();return}if(m.priority!==void 0){let y=m.priority,k;if(y===null||y===0)k=void 0;else if(typeof y=="number"&&Number.isInteger(y)&&y>0)k=y;else{f.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(w,k)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(m.read!==void 0){if(typeof m.read!="boolean"){f.code(400).send({error:"read must be a boolean"});return}if(!await e.setRead(w,m.read)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(m.regen===!0){if(!(e.get(w)!==void 0||await e.hasRecord(w))){f.code(404).send({error:"session not found"});return}e.scheduleSynopsis(w),f.code(202).send();return}if(typeof m.title!="string"||m.title.trim().length===0){f.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(w,m.title)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.delete("/v1/sessions/:id",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(m){await m.close({deleteRecord:!0,by:"REST DELETE /v1/sessions"}),await e.waitForDeletion(w),await e.hasRecord(w)&&await e.deleteRecord(w),f.code(204).send();return}if(!await e.deleteRecord(w)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.get("/v1/sessions/:id/export",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=p.query?.tools,g=m==="references"?"references":pc(m),y=await e.exportBundle(w,g==="references"?{tools:"references"}:{});if(!y){f.code(404).send({error:"session not found"});return}let k=$n({record:y.record,history:g==="summary"?gc(y.history,"summary"):y.history,promptHistory:y.promptHistory.length>0?y.promptHistory:void 0,...y.toolBlobs!==void 0?{toolBlobs:y.toolBlobs}:{},hydraVersion:ue,machine:vt(),hydraHost:hu(t)}),v=new Date().toISOString().replace(/[:.]/g,"-");f.header("Content-Disposition",`attachment; filename="${w}-${v}.hydra"`),f.code(200).send(k)}),s.get("/v1/sessions/:id/diff",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=await e.exportBundle(w,{includeArchivedHistory:!0});if(!m){f.code(404).send({error:"session not found"});return}let g=p.query??{},y=g.fold==="true"||g.fold==="1",k=typeof g.paths=="string"&&g.paths.length>0?new Set(g.paths.split(",").map(S=>S.trim()).filter(S=>S.length>0)):void 0,v=Xc(m.history);k&&(v=v.filter(S=>k.has(S.path))),y&&(v=v.map(S=>({...S,hunks:Zc(S.hunks)}))),f.code(200).send(v)}),s.get("/v1/sessions/:id/tools/:hash",async(p,f)=>{let h=p.params,w=await e.resolveCanonicalId(h.id)??h.id,m=await e.loadToolBlob(w,h.hash);if(m===null){f.code(404).send({error:"tool blob not found"});return}f.header("Content-Type","text/plain; charset=utf-8"),f.code(200).send(m)}),s.get("/v1/sessions/:id/transcript",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=await e.exportBundle(w);if(!m){f.code(404).send({error:"session not found"});return}let g=$n({record:m.record,history:m.history,promptHistory:m.promptHistory.length>0?m.promptHistory:void 0,hydraVersion:ue,machine:vt(),hydraHost:hu(t)}),y=p.query,k=b=>b==="1"||b==="true"||b==="yes",v=b=>{let A=y?.[b];if(A===void 0||A==="")return;let C=Number(A);return Number.isFinite(C)?C:"bad"},S={};for(let b of["from","to","last","since"]){let A=v(b);if(A==="bad"){f.code(400).send({error:`${b} must be a number`});return}A!==void 0&&(S[b==="since"?"sinceMs":b]=A)}f.header("Content-Type","text/markdown; charset=utf-8"),f.code(200).send(tu(g,{includeTools:k(y?.tools),includeThoughts:k(y?.thoughts),...S}))});let i=p=>async(f,h)=>{let w=f.params.id,m=await e.resolveCanonicalId(w)??w,g=f.body??{},y={};if(g.forkAt!==void 0){if(typeof g.forkAt!="string"||g.forkAt.length===0){h.code(400).send({error:"forkAt must be a non-empty string"});return}y.forkAt=g.forkAt}if(g.cwd!==void 0){if(typeof g.cwd!="string"||g.cwd.length===0){h.code(400).send({error:"cwd must be a non-empty string"});return}y.cwd=ce(g.cwd)}if(g.agentId!==void 0){if(typeof g.agentId!="string"||g.agentId.length===0){h.code(400).send({error:"agentId must be a non-empty string"});return}y.agentId=g.agentId}if(g.title!==void 0){if(typeof g.title!="string"){h.code(400).send({error:"title must be a string"});return}y.title=g.title}if(p){let k=g.selection;if(k!==void 0){if(typeof k.text!="string"||k.text.length===0){h.code(400).send({error:"selection.text must be a non-empty string"});return}y.side={selection:{text:k.text,...typeof k.responsePartId=="string"?{responsePartId:k.responsePartId}:{}}}}else y.side={}}if(g.mode!==void 0&&!p){if(g.mode!=="verbatim"&&g.mode!=="synthesis"){h.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}y.mode=g.mode}if(g.model!==void 0){if(typeof g.model!="string"||g.model.length===0){h.code(400).send({error:"model must be a non-empty string"});return}y.model=g.model}try{let k=await e.forkSession(m,y);h.code(201).send(k)}catch(k){let v=k;if(v.code===x.SessionNotFound){h.code(404).send({error:v.message});return}if(v.code===x.InvalidParams||v.code===x.AgentNotInstalled){h.code(400).send({error:v.message});return}h.code(500).send({error:v.message})}};s.post("/v1/sessions/:id/fork",i(!1)),s.post("/v1/sessions/:id/side",i(!0)),s.post("/v1/sessions/:id/rewind",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=(p.body??{}).keepThrough;if(m!==null&&(typeof m!="string"||m.length===0)){f.code(400).send({error:"keepThrough must be a non-empty messageId, or null to drop every turn"});return}try{f.code(200).send(await e.rewindSession(w,m))}catch(g){let y=g;if(y.code===x.SessionNotFound){f.code(404).send({error:y.message});return}if(y.code===x.InvalidParams){f.code(400).send({error:y.message});return}if(y.code===x.InvalidRequest){f.code(409).send({error:y.message});return}f.code(500).send({error:y.message})}}),s.post("/v1/sessions/import",async(p,f)=>{let h=p.body??{};if(h.bundle===void 0){f.code(400).send({error:"missing bundle"});return}let w;if(h.cwd!==void 0){if(typeof h.cwd!="string"||h.cwd.length===0){f.code(400).send({error:"cwd must be a non-empty string"});return}w=h.cwd}let m;try{m=Sc(h.bundle)}catch(g){f.code(400).send({error:"invalid bundle",details:g.message});return}try{let g=await e.importBundle(m,{replace:h.replace===!0,...w!==void 0?{cwd:w}:{}});f.code(201).send(g)}catch(g){let y=g;if(y.code===x.BundleAlreadyImported){f.code(409).send({error:"bundle already imported",existingSessionId:y.existingSessionId});return}f.code(500).send({error:y.message})}}),s.get("/v1/sessions/:id/compact/status",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w),g;if(m?g=m.summarizedThroughEntry:g=await e.getSummarizedThroughEntry(w),g===void 0&&!await e.hasRecord(w))return f.code(404).send({error:"session not found"}),f;let y=await e.getCompactionState(w),k=await e.getRollbackBreadcrumb(w),v=await e.getPendingAgentSwap(w),S=!1,b,A=m?.currentUsage,C=typeof A?.used=="number"&&typeof A?.size=="number"&&A.size>0?{used:A.used,size:A.size}:void 0,R=await e.loadHistory(w,{tools:"references",maxEntries:1/0}).catch(()=>[]);if(R.length>0&&t.compaction){let T=g??0,M=R.length,j=T<=R.length?T:0,U=R.slice(j),W=Qc(U);b=ti(W);let z=m?.currentModel,D=R.at(-1).recordedAt;S=Yc({summarizedThroughEntry:T,totalEntries:M,unsummarizedChars:W,compactionInFlight:e.getCompactionInFlight(),currentModel:z,lastActivityMs:D,nowMs:Date.now(),config:t.compaction,...typeof A?.used=="number"?{agentReportedUsed:A.used}:{},...typeof A?.size=="number"?{agentReportedSize:A.size}:{}})}return{summarizedThroughEntry:g??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:S,...b!=null?{approxTokens:b}:{},...C!=null?{currentUsage:C}:{},...y!=null?{compactionState:y}:{},...k!=null?{rollbackBreadcrumb:k}:{},...v!=null?{pendingAgentSwap:v}:{}}}),s.post("/v1/sessions/:id/compact",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h;if(e.get(w)){e.scheduleCompaction(w),f.code(202).send({scheduled:!0});return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}e.scheduleCompaction(w),f.code(202).send({scheduled:!0})}),s.post("/v1/sessions/:id/compact/rollback",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h;if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}try{await e.performUncompact(w),f.code(202).send({rolledBack:!0})}catch(m){let g=m instanceof Error?m.message:String(m);f.code(409).send({error:g})}}),s.post("/v1/sessions/:id/workspace/clean",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=p.body??{};if(m.deep!==void 0&&typeof m.deep!="boolean"){f.code(400).send({error:"deep must be a boolean"});return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}if(e.get(w)===void 0){f.code(409).send({error:"session is not live. Cleaning rewrites the workspace under a running agent, so it is only available inside a live session (`/hydra workspace clean`). For a cold workspace use `hydra workspace remove` instead."});return}try{let g=await e.runWorkspaceAction(w,"clean",void 0,{deep:m.deep===!0});f.code(202).send({report:g})}catch(g){f.code(409).send({error:g instanceof Error?g.message:String(g)})}}),s.get("/v1/sessions/:id/history/page",async(p,f)=>{let h=p.params.id,w=p.query,m=Number(w?.beforeSeq);if(w?.beforeSeq===void 0||w.beforeSeq===""||!Number.isFinite(m)){f.code(400).send({error:"beforeSeq must be a number"});return}let g=w.turns===void 0||w.turns===""?10:Number(w.turns);if(!Number.isInteger(g)||g<1){f.code(400).send({error:"turns must be a positive integer"});return}let y=await e.resolveCanonicalId(h)??h,k=await e.pageHistory(y,{beforeSeq:m,turns:Math.min(g,100)});if(!k){f.code(404).send({error:"session not found"});return}f.code(200).send({entries:k.entries,hasMore:k.hasMore})}),s.get("/v1/sessions/:id/history",async(p,f)=>{let h=p.params.id,w=p.query,m=w?.follow==="1"||w?.follow==="true",g=await e.resolveCanonicalId(h)??h,y=e.get(g),k,v,S=!1,b=1e4,A=[];if(y){m&&(v=y.onBroadcast(R=>{f.raw.writableEnded||(S?f.raw.write(JSON.stringify(R)+`
203
+ `),a}function ni(s,e){let t=s<0?e+s+1:s;return t<1?1:t>e?e:t}function Xm(s,e){if(!(e.from!==void 0||e.to!==void 0||e.last!==void 0)&&e.sinceMs===void 0)return{events:s};let n=[],r=0;for(let{event:f}of s)f.kind==="user-text"&&(r+=1),n.push(r===0?1:r);let o=Math.max(r,1),i=1,a=o;if(e.last!==void 0&&e.last>0?i=ni(o-e.last+1,o):(e.from!==void 0&&(i=ni(e.from,o)),e.to!==void 0&&(a=ni(e.to,o))),i>a)return{events:[],window:{from:i,to:a,total:o}};let d=e.sinceMs,c=new Set;d!==void 0&&s.forEach((f,h)=>{f.recordedAt>=d&&c.add(n[h])});let u=[],l,p;return s.forEach((f,h)=>{let w=n[h];w<i||w>a||d!==void 0&&!c.has(w)||(u.push(f),l??=w,p=w)}),{events:u,window:{from:l??i,to:p??a,total:o}}}function Zm(s){let e=[];for(let t of s.history){if(t.method!=="session/update")continue;let n=t.params;if(!n||typeof n!="object")continue;let r=Va(n.update,{cwd:s.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function ey(s){let e=new Map;for(let{event:t}of s){if(t.kind==="tool-call"){let n=e.get(t.toolCallId);e.set(t.toolCallId,{title:t.title,status:t.status??n?.status??"pending"});continue}if(t.kind==="tool-call-update"){let n=e.get(t.toolCallId)??{title:"tool call",status:"pending"};e.set(t.toolCallId,{title:t.title??n.title,status:t.status??n.status})}}return e}function ty(s,e){let t=e.session,n=et(t.sessionId),r=t.title?.trim()||`Hydra session ${n}`;s.push(`# ${qn(r)}`),s.push("");let o=[];o.push(`- **Session:** \`${n}\` (lineage \`${t.lineageId}\`)`);let i=[t.agentId];t.currentModel&&i.push(`model: ${t.currentModel}`),t.currentMode&&i.push(`mode: ${t.currentMode}`),o.push(`- **Agent:** ${i.filter(Boolean).join(" \xB7 ")}`),o.push(`- **Cwd:** ${t.cwd}`),o.push(`- **Exported:** ${e.exportedAt} from ${e.exportedFrom.machine} (hydra ${e.exportedFrom.hydraVersion})`);let a=t.currentUsage;if(a&&(a.used!==void 0||a.costAmount!==void 0||a.cumulativeCost!==void 0)){let d=[];if(a.used!==void 0){let u=a.size!==void 0?`${si(a.size)}`:void 0;d.push(u?`${si(a.used)} / ${u} tokens`:`${si(a.used)} tokens`)}let c=Wo(a);if(c!==void 0){let u=a.costCurrency??"USD";d.push(`$${c.toFixed(2)} ${u}`)}o.push(`- **Usage:** ${d.join(" \xB7 ")}`)}s.push(o.join(`
204
+ `)),s.push("")}function ny(s,e,t,n){let{includeTools:r,includeThoughts:o}=n;if(!e.some(w=>sy(w.event,o))){s.push("_No conversation history recorded._"),s.push("");return}let i=0,a="",d="",c=[],u=new Set,l=!1,p=()=>{if(c.length!==0){for(let w of c)s.push(w);s.push(""),c=[]}},f=()=>{p(),d.length>0&&(eu(s,d.trimEnd(),"*"),s.push(""),d=""),a.length!==0&&(s.push(a.trimEnd()),s.push(""),a="")},h=()=>{l||(l=!0)};for(let{event:w}of e)switch(w.kind){case"user-text":{f(),s.push("---"),s.push(""),i+=1,eu(s,w.text,"**"),s.push(""),l=!0;break}case"agent-text":h(),a+=w.text;break;case"agent-thought":{if(!o)break;h(),a.length>0&&(s.push(a.trimEnd()),s.push(""),a=""),d+=w.text;break}case"tool-call":{if(!r||(h(),(a.length>0||d.length>0)&&f(),u.has(w.toolCallId)))break;u.add(w.toolCallId);let m=t.get(w.toolCallId)??{title:w.title,status:w.status??"pending"};c.push(`- ${oy(m.status)} ${ry(m)}`);break}case"tool-call-update":break;case"plan":{h(),f(),s.push("**Plan:**"),s.push("");for(let m of w.entries){let g=m.status==="completed"?"[x]":"[ ]";s.push(`- ${g} ${qn(m.content)}`)}s.push("");break}case"mode-changed":h(),f(),s.push(`_mode: ${qn(w.mode)}_`),s.push("");break;case"model-changed":h(),f(),s.push(`_model: ${qn(w.model)}_`),s.push("");break;case"turn-complete":f();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}f()}function sy(s,e){switch(s.kind){case"agent-thought":return e;case"usage-update":case"available-commands":case"session-info":case"unknown":case"turn-complete":return!1;default:return!0}}function ry(s){let e=s.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${qn(s.title)}${t}`}function oy(s){switch(s){case"completed":return"\u2713";case"failed":return"\u2717";case"cancelled":case"rejected":return"\u2298";case"in_progress":return"\u21BB";default:return"\xB7"}}var nu=String.raw`<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s[^<>]*)?\/?>`,iy=new RegExp(nu);function eu(s,e,t){if(iy.test(e)){ay(s,e);return}let n=e.split(/\n\s*\n/);for(let r=0;r<n.length;r++){let o=n[r];if(o.trim().length===0)continue;let i=o.split(`
205
+ `);for(let a=0;a<i.length;a++){let d=i[a];s.push(a===0&&a===i.length-1?`${t}${d}${t}`:a===0?`${t}${d}`:a===i.length-1?`${d}${t}`:d)}r<n.length-1&&s.push("")}}function ay(s,e){let t=e.replace(/\s+$/,"");if(t.length===0)return;let n=0;for(let o of t.match(/`+/g)??[])n=Math.max(n,o.length);let r="`".repeat(Math.max(3,n+1));s.push(r);for(let o of t.split(`
206
+ `))s.push(o);s.push(r)}function qn(s){return s.replace(new RegExp(nu,"g"),e=>e.replace(/</g,"&lt;").replace(/>/g,"&gt;"))}function si(s){return s.toLocaleString("en-US")}function Ie(s){return s==="127.0.0.1"||s==="::1"||s==="localhost"||s==="[::1]"}function dy(s){let e=s.trim();if(e.length===0)return{operator:"OR",terms:[]};let t=/\w+:"[^"]*"|"[^"]*"|\S+/g,n=[],r;for(;(r=t.exec(e))!==null;)n.push(r[0]);let o="OR",i=!1,a=!1,d=[];for(let u of n){let l=u.toUpperCase();l==="AND"?i=!0:l==="OR"?a=!0:d.push(u)}i?o="AND":a&&(o="OR");let c=d.map(u=>cy(u)).filter(u=>u.term.length>0);return{operator:o,terms:c}}function cy(s){let e=/^(\w+):"([^"]*)"$/.exec(s);if(e)return{scope:su(e[1]),term:e[2]};let t=/^"([^"]*)"$/.exec(s);if(t)return{scope:"all",term:t[1]};let n=/^(prompt|response|tool|edit|edited):([\s\S]*)$/i.exec(s);return n?{scope:su(n[1]),term:n[2].trim()}:{scope:"all",term:s.trim()}}function su(s){switch(s.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";case"edit":case"edited":return"edit";default:return"all"}}function uy(s,e){return e==="edit"?s==="edit":s==="edit"?!1:s==="all"?!0:s==="user"?e==="user":s==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var ly=5,fy=200,nr=72,py=24,gy=512;function du(s){return Number.isFinite(s)?Math.max(py,Math.min(gy,Math.floor(s))):nr}async function cu(s,e,t={}){let n=dy(e);if(n.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??ly,o=t.maxSessions??fy,i=du(t.snippetWidth??nr),a=t.sessionIds?new Set(t.sessionIds):null,d=await s.list(),c=a?d.filter(p=>a.has(p.sessionId)):d,u=[],l=!1;for(let p of c){if(u.length>=o){l=!0;break}let f=await s.loadHistory(p.sessionId,{tools:"references"}).catch(()=>[]),h=my(f,n,r,i,hy(p));if(h.snippets.length===0)continue;let w={sessionId:p.sessionId,cwd:p.cwd,status:p.status,updatedAt:p.updatedAt,totalMatches:h.totalMatches,snippets:h.snippets};p.title!==void 0&&(w.title=p.title),u.push(w)}return{query:e,truncated:l,results:u}}function hy(s){let e=s.workspace?.sourceCwd;if(e===void 0||e.length===0||s.cwd.length===0)return;let t=s.cwd.endsWith("/")?s.cwd:s.cwd+"/";return n=>n.startsWith(t)?e.replace(/\/+$/,"")+"/"+n.slice(t.length):n}function my(s,e,t,n=nr,r){if(e.terms.length===0)return{totalMatches:0,snippets:[]};let o=0,i=[],a=Math.max(1,Math.floor(t/e.terms.length)),d=[];for(let{scope:c,term:u}of e.terms){let l=yy(s,u,c,t,n,r);if(e.operator==="AND"&&l.totalMatches===0)return{totalMatches:0,snippets:[]};o+=l.totalMatches,i.push(...l.snippets.slice(0,a)),d.push(...l.snippets.slice(a))}for(let c of d){if(i.length>=t)break;i.push(c)}return{totalMatches:o,snippets:i.slice(0,t)}}function yy(s,e,t,n,r,o){let i=e.toLowerCase(),a=0,d=[],c=new Set;for(let u of s){let l=wy(u).filter(p=>uy(t,p.kind));for(let p of l){let f=p.text.toLowerCase();if(p.kind==="edit"){let m=o?.(p.text);if(!(ru(p.text,e)||(m!==void 0&&m!==p.text?ru(m,e):!1))||c.has(p.text))continue;if(c.add(p.text),a+=1,d.length<n){let y={kind:"edit",text:p.text,recordedAt:u.recordedAt};p.toolName!==void 0&&(y.toolName=p.toolName),d.push(y)}continue}let h=f.indexOf(i);if(h===-1)continue;let w=0;for(;h!==-1;)w++,h=f.indexOf(i,h+i.length);if(a+=w,d.length<n){let m=f.indexOf(i),g={kind:p.kind,text:Ay(p.text,m,i.length,r),recordedAt:u.recordedAt};p.toolName!==void 0&&(g.toolName=p.toolName),d.push(g)}}}return{totalMatches:a,snippets:d}}function wy(s){if(s.method!=="session/update")return[];let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return[];let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:n.kind;if(typeof r!="string")return[];switch(r){case"agent_message_chunk":{let o=tr(n.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof n.text=="string"?ve(n.text):tr(n.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if(Sy(n))return[];let o=tr(n.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=Iy(n.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return ky(n);default:return[]}}function ky(s){let e=iu(s,"name"),t=iu(s,"title"),n=[];if(t!==void 0){let a=ie(t);if(a.length>0){let d={kind:"tool",text:a};e!==void 0&&(d.toolName=e),n.push(d)}}if(e!==void 0&&e!==t){let a=ie(e);a.length>0&&n.push({kind:"tool",toolName:e,text:a})}let r=s.rawInput;if(r&&typeof r=="object"){let a=au(r);if(a.length>0){let d={kind:"tool-input",text:ie(a)};e!==void 0&&(d.toolName=e),n.push(d)}}for(let a of Ba(s)){let d={kind:"edit",text:a};e!==void 0&&(d.toolName=e),n.push(d)}let o=s.locations;if(Array.isArray(o)&&o.length>0){let a=au(o);if(a.length>0){let d={kind:"tool-input",text:ie(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let i=vy(s);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),n.push(a)}return n}function ru(s,e){let t=ou(s.toLowerCase()),n=ou(e.toLowerCase());if(n.length===0)return!1;if(n.startsWith("/"))return t===n||t.startsWith(n+"/");let r="/"+n,o=t.indexOf(r);for(;o!==-1;){let i=o+r.length;if(i===t.length||t[i]==="/")return!0;o=t.indexOf(r,o+1)}return t===n||t.startsWith(n+"/")}function ou(s){return s.length>1&&s.endsWith("/")?s.slice(0,-1):s}function vy(s){if(!by(s.status))return null;let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=n.content;if(!o||typeof o!="object")continue;let i=o;if(i.type==="text"&&typeof i.text=="string"){let a=ie(i.text);if(a.length>0)return a}}let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.error;if(typeof n=="string"){let r=ie(n);if(r.length>0)return r}}return null}function by(s){return s==="failed"||s==="rejected"||s==="cancelled"}function Sy(s){let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e["hydra-acp"];return!t||typeof t!="object"||Array.isArray(t)?!1:t.compatFor==="prompt_received"}function tr(s){if(typeof s=="string")return ve(s);if(!s||typeof s!="object"||Array.isArray(s))return"";let e=s;return typeof e.text=="string"?ve(e.text):""}function Iy(s){if(!Array.isArray(s))return"";let e=[];for(let t of s){let n=tr(t);n.length>0&&e.push(n)}return e.join("")}function iu(s,e){let t=s[e];return typeof t=="string"?t:void 0}function au(s){try{return JSON.stringify(s)}catch{return""}}function Ay(s,e,t,n=nr){let r=s.replace(/\s+/g," ").trim();if(r.length===0)return"";let o=r.toLowerCase(),i=s.slice(e,e+t).toLowerCase().replace(/\s+/g," ").trim(),a=i.length>0?o.indexOf(i):0;a===-1&&(a=0);let d=du(n),c=Math.max(0,d-i.length),u=Math.floor(c/2),l=Math.min(u,a),p=Math.min(c-l,r.length-(a+i.length)),f=Math.max(0,a-(c-p)),h=Math.min(r.length,a+i.length+p),w=f>0?"\u2026":"",m=h<r.length?"\u2026":"";return`${w}${r.slice(f,h)}${m}`}import{randomBytes as lu}from"crypto";function uu(s){let e=lu(32).toString("hex");return s.tokenRegistry.reserve(e).complete(s.session),s.session.onClose(()=>{s.tokenRegistry.unbind(e)}),{name:s.name,type:"http",url:`${s.getOrigin()}/mcp/${s.name}`,headers:[{name:"Authorization",value:`Bearer ${e}`}]}}function ri(s){if(s.deps.mcpTokenRegistry===void 0||s.deps.getDaemonOrigin===void 0)return;let e=s.deps.mcpTokenRegistry,t=s.deps.getDaemonOrigin;return async n=>{let r=[...s.baselineMcpServers??[]];s.stdinEnabled&&r.push(uu({name:"hydra-acp-stdin",session:n,tokenRegistry:e,getOrigin:t})),r.push(uu({name:"hydra-acp-recall",session:n,tokenRegistry:e,getOrigin:t}));let o=sn(s.deps);return o!==void 0&&(o.bindToSession(n),r=[...r,...o.descriptors]),r}}function sn(s){if(s.extensionMcp===void 0||s.mcpTokenRegistry===void 0||s.getDaemonOrigin===void 0)return;let e=s.extensionMcp.list();if(e.length===0)return;let t=lu(32).toString("hex"),n=s.mcpTokenRegistry.reserve(t),r=s.getDaemonOrigin(),o=e.map(a=>({name:a,type:"http",url:`${r}/mcp/${a}`,headers:[{name:"Authorization",value:`Bearer ${t}`}]})),i=s.mcpTokenRegistry;return{descriptors:o,bindToSession:a=>{n.complete(a),a.onClose(()=>{i.unbind(t)})},abandon:a=>n.abandon(a)}}var Cy=new Set(["/v1/sessions/:id/history","/v1/sessions/:id/events"]);function fu(s,e){let t=e.fetchImpl??fetch;s.addHook("preHandler",async(n,r)=>{let o=n.routeOptions.url;if(!o||!o.startsWith("/v1/sessions/:id"))return;let i=n.params,a=i.id;if(typeof a!="string")return;let d=ft(a);if(!d){if(!e.localMiss||await e.localMiss.resolvesLocally(a))return;let g=e.localMiss.cache.findByLocalId(a);if(g.length===0)return;if(g.length>1){r.code(404).send({error:`Session "${a}" exists on more than one remote (${g.map(y=>y.name).join(", ")}). Address it as "<remote>:${a}".`});return}d=g[0]}let c=e.store.get(d.name);if(!c){r.code(404).send({error:`No remote named "${d.name}". Run \`hydra remote add\` first.`});return}let u=n.query;if(Cy.has(o)&&xy(u?.follow)){let g=c.port===_t?"":`:${c.port}`;r.code(501).send({error:`Streaming a federated session isn't supported yet. Attach directly with hydra://${c.host}${g}/${d.localId} instead.`});return}let l=Ey(o,i,d.localId,n.url),f=`${Ie(c.host)?"http":"https"}://${c.host}:${c.port}${l}`,h;try{h=await t(f,{method:n.method,headers:{Authorization:`Bearer ${c.token}`,...n.body!==void 0?{"Content-Type":"application/json"}:{}},...n.body!==void 0&&n.method!=="GET"?{body:JSON.stringify(n.body)}:{}})}catch(g){r.code(502).send({error:`Could not reach remote "${d.name}" (${c.host}:${c.port}): ${g.message}`});return}if(n.method==="DELETE"&&o==="/v1/sessions/:id"&&(h.ok||h.status===404)&&e.localMiss?.cache.evict(d.name,d.localId),h.status===204){r.code(204).send();return}let w=await h.text(),m=h.headers.get("content-type");m&&r.header("content-type",m),r.code(h.status).send(w)})}var Ry=5e3,sr=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;perPeer=new Map;timer;start(){this.timer||(this.refreshNow(),this.timer=setInterval(()=>{this.refreshNow()},this.opts.intervalMs??Ry),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}async refreshNow(){let e=this.opts.fetchImpl??fetch,t=new Set(this.store.list().map(n=>n.name));for(let n of[...this.perPeer.keys()])t.has(n)||this.perPeer.delete(n);await Promise.allSettled(this.store.list().map(async n=>{let r=this.store.get(n.name);if(!r)return;let o=this.perPeer.get(n.name),i=Ie(r.host)?"http":"https",a=new URLSearchParams({includeNonInteractive:"1"}),d=o?.cursor!==void 0;d&&a.set("since",String(o.cursor));let c=`${i}://${r.host}:${r.port}/v1/sessions?${a.toString()}`,u;try{u=await e(c,{headers:{Authorization:`Bearer ${r.token}`}})}catch{return}if(!u.ok)return;let l=await u.json(),p=o?.sessions??new Map;if(d){for(let[f,h]of[...p])h.status!=="cold"&&p.delete(f);for(let f of l.removed??[])p.delete(Je({name:n.name,localId:f}))}else p.clear();for(let f of l.sessions??[]){let h=Je({name:n.name,localId:String(f.sessionId)});p.set(h,{...f,sessionId:h,remote:n.name})}this.perPeer.set(n.name,{cursor:l.cursor,sessions:p})}))}list(e){let t=[];for(let n of this.perPeer.values())t.push(...n.sessions.values());return t.filter(n=>!(e.status&&n.status!==e.status||!e.includeNonInteractive&&n.interactive!==!0))}evict(e,t){this.perPeer.get(e)?.sessions.delete(Je({name:e,localId:t}))}findByLocalId(e){let t=e.startsWith(ye)?[e]:[e,ye+e],n=[];for(let[r,o]of this.perPeer)for(let i of t)if(o.sessions.has(Je({name:r,localId:i}))){n.push({name:r,localId:i});break}return n}};async function pu(s,e,t,n=fetch){let r=s.get(e);if(!r)return{status:404,body:{error:`No remote named "${e}". Run \`hydra remote add\` first.`}};let i=`${Ie(r.host)?"http":"https"}://${r.host}:${r.port}/v1/sessions`,a;try{a=await n(i,{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(l){return{status:502,body:{error:`Could not reach remote "${e}" (${r.host}:${r.port}): ${l.message}`}}}let d=await a.text(),c=null;try{c=d.length>0?JSON.parse(d):null}catch{c=null}if(!a.ok)return{status:a.status,body:c};let u=c;return u&&typeof u.sessionId=="string"?{status:a.status,body:{...u,sessionId:Je({name:e,localId:u.sessionId})}}:{status:a.status,body:c}}async function gu(s,e,t=fetch){let n;if(e.sessionIds===void 0)n=s.list().map(a=>({name:a.name}));else{let a=new Map;for(let d of e.sessionIds){let c=ft(d);if(!c)continue;let u=a.get(c.name)??[];u.push(c.localId),a.set(c.name,u)}n=[...a.entries()].map(([d,c])=>({name:d,sessionIds:c}))}if(n.length===0)return{query:e.q,truncated:!1,results:[]};let r=await Promise.all(n.map(async a=>{let d=s.get(a.name);if(!d)return null;let u=`${Ie(d.host)?"http":"https"}://${d.host}:${d.port}/v1/sessions/search`,l;try{l=await t(u,{method:"POST",headers:{Authorization:`Bearer ${d.token}`,"Content-Type":"application/json"},body:JSON.stringify({q:e.q,...a.sessionIds?{sessionIds:a.sessionIds}:{},...e.snippetWidth!==void 0?{snippetWidth:e.snippetWidth}:{}})})}catch{return null}if(!l.ok)return null;let p;try{p=await l.json()}catch{return null}let f=p;if(!f||!Array.isArray(f.results))return null;let h=f.results.map(w=>({...w,sessionId:Je({name:a.name,localId:w.sessionId})}));return{query:e.q,truncated:f.truncated===!0,results:h}})),o=[],i=!1;for(let a of r)a!==null&&(o.push(...a.results),i=i||a.truncated);return{query:e.q,truncated:i,results:o}}function xy(s){return s==="1"||s==="true"||s===!0}function Ey(s,e,t,n){let r=s.replace(/:([A-Za-z_]+)/g,(i,a)=>encodeURIComponent(a==="id"?t:e[a]??"")),o=n.indexOf("?");return o===-1?r:r+n.slice(o)}var rr=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function hu(s){if(s.publicHost&&s.publicHost.length>0)return s.publicHost;if(s.host&&!Ie(s.host))return s.port!==void 0?`${s.host}:${s.port}`:s.host}function yu(s,e,t,n={},r,o){s.get("/v1/sessions",async(p,f)=>{let h=p.query,w=h?.includeNonInteractive==="1"||h?.includeNonInteractive==="true",m;if(h?.since!==void 0&&(m=Number(h.since),!Number.isFinite(m)||m<0))return f.code(400).send({error:`since must be a non-negative number, got ${JSON.stringify(h.since)}`});let g=h?.status==="warm"||h?.status==="cold"?h.status:void 0,y={cwd:h?.cwd,includeNonInteractive:w,...g?{status:g}:{}},k=o&&!y.cwd?o.list({includeNonInteractive:w,...g?{status:g}:{}}):[];if(m!==void 0){let S=await e.listSince(y,m);return{sessions:[...S.entries,...k],removed:S.removed,cursor:S.cursor}}let v=await e.listing(y);return{sessions:[...v.entries,...k],removed:[],cursor:v.cursor}}),s.get("/v1/sessions/:id",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=await e.getOne(w);return m||(f.code(404).send({error:"session not found"}),f)}),s.post("/v1/sessions/search",async(p,f)=>{let h=p.body??{},w=typeof h.q=="string"?h.q:"";if(w.trim().length===0)return f.code(400).send({error:"q is required"}),f;let m=Array.isArray(h.sessionIds)?h.sessionIds.filter(v=>typeof v=="string"&&v.length>0):void 0,g={sessionIds:m};typeof h.snippetWidth=="number"&&(g.snippetWidth=h.snippetWidth);let y=await cu(e,w,g);if(!r)return y;let k=await gu(r,{q:w,...m?{sessionIds:m}:{},...g.snippetWidth!==void 0?{snippetWidth:g.snippetWidth}:{}});return{query:w,truncated:y.truncated||k.truncated,results:[...y.results,...k.results]}}),s.post("/v1/sessions",async(p,f)=>{let h=p.body??{};if(h.remote){if(!r)return f.code(404).send({error:`No remote named "${h.remote}". Run \`hydra remote add\` first.`});let v=await pu(r,h.remote,{cwd:h.cwd,agentId:h.agentId,mcpServers:h.mcpServers,workspace:h.workspace});return f.code(v.status).send(v.body)}let w=ce(h.cwd??t.cwd),m=await fn(w),g=h.agentId??m.agentId??t.agentId,y=sn(n),k=y!==void 0?[...h.mcpServers??[],...y.descriptors]:h.mcpServers;try{let v=await e.create({cwd:w,agentId:g,mcpServers:k,...h.workspace!==void 0?{workspace:h.workspace}:{}});y!==void 0&&y.bindToSession(v),f.code(201).send({sessionId:v.sessionId,agentId:v.agentId,cwd:v.cwd,...v.workspace!==void 0?{workspace:v.workspace}:{},...v.workspaceError!==void 0?{workspaceError:v.workspaceError}:{}})}catch(v){y!==void 0&&y.abandon(v instanceof Error?v:void 0),f.code(500).send({error:v.message})}}),s.post("/v1/sessions/collect",async(p,f)=>{let h=p.body??{},w=typeof h.maxAgeDays=="number"&&h.maxAgeDays>0?h.maxAgeDays*24*60*60*1e3:0,m=typeof h.limit=="number"&&h.limit>0?h.limit:1e3,g=h.selection==="explicit"||h.selection==="unpromoted"?h.selection:"unpromoted";try{let y=await ei({manager:e,maxAgeMs:w,maxDeletions:m,selection:g,verbose:!1});f.code(200).send(y)}catch(y){f.code(500).send({error:y.message})}}),s.get("/v1/sessions/tombstones",async(p,f)=>{let h=p.query;if(h.since!==void 0&&Number.isNaN(Date.parse(h.since))){f.code(400).send({error:"since must be an ISO timestamp"});return}let w=await e.listTombstones({...h.agent?{agentId:h.agent}:{},...h.since?{since:h.since}:{},...h.grep?{grep:h.grep}:{}});f.code(200).send({tombstones:w})}),s.post("/v1/sessions/undelete",async(p,f)=>{let h=p.body??{};if(!Array.isArray(h.ids)||h.ids.length===0||!h.ids.every(w=>typeof w=="string"&&w.length>0)){f.code(400).send({error:"ids must be a non-empty array of strings"});return}try{f.code(200).send(await e.undeleteSessions(h.ids))}catch(w){f.code(500).send({error:w.message})}}),s.post("/v1/sessions/:id/kill",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(m){m.close({deleteRecord:!1,by:"REST POST /kill"}).catch(()=>{}),f.code(202).send();return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.post("/v1/sessions/:id/stdin/open",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(!m)return f.code(404).send({error:"session not found"}),f;let g=p.body??{},y={};(g.mode==="memory"||g.mode==="file")&&(y.mode=g.mode),typeof g.capacityBytes=="number"&&(y.capacityBytes=g.capacityBytes),typeof g.fileCapBytes=="number"&&(y.fileCapBytes=g.fileCapBytes),(y.mode??"memory")==="file"&&(y.filePathFor=k=>or.join(mu.tmpdir(),`hydra-acp-stdin-${k}.log`));try{return m.openStream(y)}catch(k){return f.code(409).send({error:k.message}),f}}),s.post("/v1/sessions/:id/stdin",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(!m)return f.code(404).send({error:"session not found"}),f;let g=p.body??{},y=typeof g.chunk=="string"?g.chunk:"",k=g.eof===!0;try{return m.streamWrite(y,k)}catch(v){return f.code(409).send({error:v.message}),f}}),s.patch("/v1/sessions/:id",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=p.body??{};if(m.cwd!==void 0){if(typeof m.cwd!="string"||!or.isAbsolute(m.cwd)){f.code(400).send({error:"cwd must be an absolute path"});return}let y=await e.setCwd(w,m.cwd);if(y==="missing"){f.code(404).send({error:"session not found"});return}if(y==="not-a-directory"){f.code(400).send({error:`${m.cwd} is not a directory`});return}if(y==="live"){f.code(409).send({error:"session is live; its agent was spawned in its cwd and cannot change directory. Moving a live session is a swap \u2014 use `workspace start` in it."});return}if(y==="bound"){f.code(409).send({error:"session is isolated, so its cwd IS its workspace. Clear the binding first (PATCH { workspace: null }) or leave the workspace from inside the session."});return}f.code(204).send();return}if("workspace"in m){if(m.workspace!==null){f.code(400).send({error:"workspace may only be set to null (clear the binding)"});return}let y=await e.clearWorkspaceBinding(w);if(y==="missing"){f.code(404).send({error:"session not found"});return}if(y==="live"){f.code(409).send({error:"session is live; its cwd is the workspace. Use `workspace stop` or `workspace detach` in the session so the agent moves with the binding."});return}f.code(204).send();return}if(m.priority!==void 0){let y=m.priority,k;if(y===null||y===0)k=void 0;else if(typeof y=="number"&&Number.isInteger(y)&&y>0)k=y;else{f.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(w,k)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(m.read!==void 0){if(typeof m.read!="boolean"){f.code(400).send({error:"read must be a boolean"});return}if(!await e.setRead(w,m.read)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(m.regen===!0){if(!(e.get(w)!==void 0||await e.hasRecord(w))){f.code(404).send({error:"session not found"});return}e.scheduleSynopsis(w),f.code(202).send();return}if(typeof m.title!="string"||m.title.trim().length===0){f.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(w,m.title)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.delete("/v1/sessions/:id",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);if(m){await m.close({deleteRecord:!0,by:"REST DELETE /v1/sessions"}),await e.waitForDeletion(w),await e.hasRecord(w)&&await e.deleteRecord(w),f.code(204).send();return}if(!await e.deleteRecord(w)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.get("/v1/sessions/:id/export",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=p.query?.tools,g=m==="references"?"references":pc(m),y=await e.exportBundle(w,g==="references"?{tools:"references"}:{});if(!y){f.code(404).send({error:"session not found"});return}let k=$n({record:y.record,history:g==="summary"?gc(y.history,"summary"):y.history,promptHistory:y.promptHistory.length>0?y.promptHistory:void 0,...y.toolBlobs!==void 0?{toolBlobs:y.toolBlobs}:{},hydraVersion:ue,machine:vt(),hydraHost:hu(t)}),v=new Date().toISOString().replace(/[:.]/g,"-");f.header("Content-Disposition",`attachment; filename="${w}-${v}.hydra"`),f.code(200).send(k)}),s.get("/v1/sessions/:id/diff",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=await e.exportBundle(w,{includeArchivedHistory:!0});if(!m){f.code(404).send({error:"session not found"});return}let g=p.query??{},y=g.fold==="true"||g.fold==="1",k=typeof g.paths=="string"&&g.paths.length>0?new Set(g.paths.split(",").map(S=>S.trim()).filter(S=>S.length>0)):void 0,v=Xc(m.history);k&&(v=v.filter(S=>k.has(S.path))),y&&(v=v.map(S=>({...S,hunks:Zc(S.hunks)}))),f.code(200).send(v)}),s.get("/v1/sessions/:id/tools/:hash",async(p,f)=>{let h=p.params,w=await e.resolveCanonicalId(h.id)??h.id,m=await e.loadToolBlob(w,h.hash);if(m===null){f.code(404).send({error:"tool blob not found"});return}f.header("Content-Type","text/plain; charset=utf-8"),f.code(200).send(m)}),s.get("/v1/sessions/:id/transcript",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=await e.exportBundle(w);if(!m){f.code(404).send({error:"session not found"});return}let g=$n({record:m.record,history:m.history,promptHistory:m.promptHistory.length>0?m.promptHistory:void 0,hydraVersion:ue,machine:vt(),hydraHost:hu(t)}),y=p.query,k=b=>b==="1"||b==="true"||b==="yes",v=b=>{let A=y?.[b];if(A===void 0||A==="")return;let C=Number(A);return Number.isFinite(C)?C:"bad"},S={};for(let b of["from","to","last","since"]){let A=v(b);if(A==="bad"){f.code(400).send({error:`${b} must be a number`});return}A!==void 0&&(S[b==="since"?"sinceMs":b]=A)}f.header("Content-Type","text/markdown; charset=utf-8"),f.code(200).send(tu(g,{includeTools:k(y?.tools),includeThoughts:k(y?.thoughts),...S}))});let i=p=>async(f,h)=>{let w=f.params.id,m=await e.resolveCanonicalId(w)??w,g=f.body??{},y={};if(g.forkAt!==void 0){if(typeof g.forkAt!="string"||g.forkAt.length===0){h.code(400).send({error:"forkAt must be a non-empty string"});return}y.forkAt=g.forkAt}if(g.cwd!==void 0){if(typeof g.cwd!="string"||g.cwd.length===0){h.code(400).send({error:"cwd must be a non-empty string"});return}y.cwd=ce(g.cwd)}if(g.agentId!==void 0){if(typeof g.agentId!="string"||g.agentId.length===0){h.code(400).send({error:"agentId must be a non-empty string"});return}y.agentId=g.agentId}if(g.title!==void 0){if(typeof g.title!="string"){h.code(400).send({error:"title must be a string"});return}y.title=g.title}if(p){let k=g.selection;if(k!==void 0){if(typeof k.text!="string"||k.text.length===0){h.code(400).send({error:"selection.text must be a non-empty string"});return}y.side={selection:{text:k.text,...typeof k.responsePartId=="string"?{responsePartId:k.responsePartId}:{}}}}else y.side={}}if(g.mode!==void 0&&!p){if(g.mode!=="verbatim"&&g.mode!=="synthesis"){h.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}y.mode=g.mode}if(g.model!==void 0){if(typeof g.model!="string"||g.model.length===0){h.code(400).send({error:"model must be a non-empty string"});return}y.model=g.model}try{let k=await e.forkSession(m,y);h.code(201).send(k)}catch(k){let v=k;if(v.code===x.SessionNotFound){h.code(404).send({error:v.message});return}if(v.code===x.InvalidParams||v.code===x.AgentNotInstalled){h.code(400).send({error:v.message});return}h.code(500).send({error:v.message})}};s.post("/v1/sessions/:id/fork",i(!1)),s.post("/v1/sessions/:id/side",i(!0)),s.post("/v1/sessions/:id/rewind",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=(p.body??{}).keepThrough;if(m!==null&&(typeof m!="string"||m.length===0)){f.code(400).send({error:"keepThrough must be a non-empty messageId, or null to drop every turn"});return}try{f.code(200).send(await e.rewindSession(w,m))}catch(g){let y=g;if(y.code===x.SessionNotFound){f.code(404).send({error:y.message});return}if(y.code===x.InvalidParams){f.code(400).send({error:y.message});return}if(y.code===x.InvalidRequest){f.code(409).send({error:y.message});return}f.code(500).send({error:y.message})}}),s.post("/v1/sessions/import",async(p,f)=>{let h=p.body??{};if(h.bundle===void 0){f.code(400).send({error:"missing bundle"});return}let w;if(h.cwd!==void 0){if(typeof h.cwd!="string"||h.cwd.length===0){f.code(400).send({error:"cwd must be a non-empty string"});return}w=h.cwd}let m;try{m=Sc(h.bundle)}catch(g){f.code(400).send({error:"invalid bundle",details:g.message});return}try{let g=await e.importBundle(m,{replace:h.replace===!0,...w!==void 0?{cwd:w}:{}});f.code(201).send(g)}catch(g){let y=g;if(y.code===x.BundleAlreadyImported){f.code(409).send({error:"bundle already imported",existingSessionId:y.existingSessionId});return}f.code(500).send({error:y.message})}}),s.get("/v1/sessions/:id/compact/status",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w),g;if(m?g=m.summarizedThroughEntry:g=await e.getSummarizedThroughEntry(w),g===void 0&&!await e.hasRecord(w))return f.code(404).send({error:"session not found"}),f;let y=await e.getCompactionState(w),k=await e.getRollbackBreadcrumb(w),v=await e.getPendingAgentSwap(w),S=!1,b,A=m?.currentUsage,C=typeof A?.used=="number"&&typeof A?.size=="number"&&A.size>0?{used:A.used,size:A.size}:void 0,R=await e.loadHistory(w,{tools:"references",maxEntries:1/0}).catch(()=>[]);if(R.length>0&&t.compaction){let T=g??0,M=R.length,H=T<=R.length?T:0,U=R.slice(H),W=Qc(U);b=ti(W);let z=m?.currentModel,D=R.at(-1).recordedAt;S=Yc({summarizedThroughEntry:T,totalEntries:M,unsummarizedChars:W,compactionInFlight:e.getCompactionInFlight(),currentModel:z,lastActivityMs:D,nowMs:Date.now(),config:t.compaction,...typeof A?.used=="number"?{agentReportedUsed:A.used}:{},...typeof A?.size=="number"?{agentReportedSize:A.size}:{}})}return{summarizedThroughEntry:g??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:S,...b!=null?{approxTokens:b}:{},...C!=null?{currentUsage:C}:{},...y!=null?{compactionState:y}:{},...k!=null?{rollbackBreadcrumb:k}:{},...v!=null?{pendingAgentSwap:v}:{}}}),s.post("/v1/sessions/:id/compact",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h;if(e.get(w)){e.scheduleCompaction(w),f.code(202).send({scheduled:!0});return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}e.scheduleCompaction(w),f.code(202).send({scheduled:!0})}),s.post("/v1/sessions/:id/compact/rollback",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h;if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}try{await e.performUncompact(w),f.code(202).send({rolledBack:!0})}catch(m){let g=m instanceof Error?m.message:String(m);f.code(409).send({error:g})}}),s.post("/v1/sessions/:id/workspace/clean",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=p.body??{};if(m.deep!==void 0&&typeof m.deep!="boolean"){f.code(400).send({error:"deep must be a boolean"});return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}if(e.get(w)===void 0){f.code(409).send({error:"session is not live. Cleaning rewrites the workspace under a running agent, so it is only available inside a live session (`/hydra workspace clean`). For a cold workspace use `hydra workspace remove` instead."});return}try{let g=await e.runWorkspaceAction(w,"clean",void 0,{deep:m.deep===!0});f.code(202).send({report:g})}catch(g){f.code(409).send({error:g instanceof Error?g.message:String(g)})}}),s.get("/v1/sessions/:id/history/page",async(p,f)=>{let h=p.params.id,w=p.query,m=Number(w?.beforeSeq);if(w?.beforeSeq===void 0||w.beforeSeq===""||!Number.isFinite(m)){f.code(400).send({error:"beforeSeq must be a number"});return}let g=w.turns===void 0||w.turns===""?10:Number(w.turns);if(!Number.isInteger(g)||g<1){f.code(400).send({error:"turns must be a positive integer"});return}let y=await e.resolveCanonicalId(h)??h,k=await e.pageHistory(y,{beforeSeq:m,turns:Math.min(g,100)});if(!k){f.code(404).send({error:"session not found"});return}f.code(200).send({entries:k.entries,hasMore:k.hasMore})}),s.get("/v1/sessions/:id/history",async(p,f)=>{let h=p.params.id,w=p.query,m=w?.follow==="1"||w?.follow==="true",g=await e.resolveCanonicalId(h)??h,y=e.get(g),k,v,S=!1,b=1e4,A=[];if(y){m&&(v=y.onBroadcast(R=>{f.raw.writableEnded||(S?f.raw.write(JSON.stringify(R)+`
207
207
  `):(A.push(R),A.length>b&&A.shift()))})),p.raw.on("close",()=>{v?.(),f.raw.writableEnded||f.raw.end()});try{k=await y.getHistorySnapshot()}catch(R){throw v?.(),R}}else{let R=await e.getHistory(g);if(R===void 0)return f.code(404).send({error:"session not found"}),f;k=R}f.raw.setHeader("Content-Type","application/x-ndjson"),f.raw.setHeader("Cache-Control","no-cache"),f.raw.statusCode=200;let C=new Set;for(let R of k??[]){f.raw.write(JSON.stringify(R)+`
208
- `);let T=R;typeof T.recordedAt=="number"&&C.add(String(T.recordedAt))}for(;A.length>0;){let R=A.splice(0,A.length);for(let T of R){let M=T,j=typeof M.recordedAt=="number"?String(M.recordedAt):"";j&&C.has(j)||f.raw.write(JSON.stringify(T)+`
208
+ `);let T=R;typeof T.recordedAt=="number"&&C.add(String(T.recordedAt))}for(;A.length>0;){let R=A.splice(0,A.length);for(let T of R){let M=T,H=typeof M.recordedAt=="number"?String(M.recordedAt):"";H&&C.has(H)||f.raw.write(JSON.stringify(T)+`
209
209
  `)}}return S=!0,v||f.raw.end(),f});function a(p,f,h){let w=typeof p=="string"?p.trim():"";if(w.length===0)return null;let m;try{m=JSON.parse(w)}catch{return console.debug("events endpoint: skipping malformed JSONL line"),null}if(!m||typeof m!="object"||Array.isArray(m))return console.debug("events endpoint: skipping non-object JSONL line"),null;let g=m;if(typeof g.recordedAt!="number"||h!==void 0&&g.recordedAt<h||typeof g.params!="object"||g.params===null||Array.isArray(g.params))return null;let y=g.params;if(typeof y.update!="object"||y.update===null||Array.isArray(y.update))return null;let v=y.update.sessionUpdate;return typeof v!="string"||!f.has(v)?null:{recordedAt:g.recordedAt,entry:m}}function d(p,f,h){let m=f.params.update,g={sessionId:p,ts:new Date(f.recordedAt).toISOString(),kind:h,update:m};return m.messageId!==void 0&&m.messageId!==null&&(g.messageId=m.messageId),g}async function*c(p,f,h,w){for await(let m of f){let g=a(m,h,w);if(g){let y=g.entry.params.update.sessionUpdate;yield{ts:g.recordedAt,row:d(p,g.entry,y)}}}}async function u(p,f,h,w){let m=ii.createInterface({input:oi.createReadStream(f),crlfDelay:1/0}),g=c(p,m,h,w),y=await g.next(),k=y.done?null:y.value;return{sessionId:p,rl:m,gen:g,current:k,exhausted:k===null}}async function l(p){let f=await p.gen.next();f.done?(p.exhausted=!0,p.current=null):p.current=f.value}s.get("/v1/sessions/events",async(p,f)=>{let h=p.query,w=h.kinds;if(!w||w.trim().length===0)return f.code(400).send({error:"kinds parameter is required"}),f;let m=w.split(",").map(b=>b.trim());if(m.length===0)return f.code(400).send({error:"kinds parameter is required"}),f;for(let b of m)if(!rr.has(b))return f.code(400).send({error:`kind "${b}" is not queryable; allowed kinds: ${[...rr].join(", ")}`}),f;let g=new Set(m),y;if(h.since!==void 0&&h.since.trim().length>0){let b=new Date(h.since);if(isNaN(b.getTime()))return f.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),f;y=b.getTime()}let k=await e.list({includeNonInteractive:!0}),v=y!==void 0?k.filter(b=>new Date(b.updatedAt).getTime()>=y):k;f.raw.setHeader("content-type","application/x-ndjson"),f.raw.statusCode=200;let S=[];for(let b of v)try{let A=E.historyFile(b.sessionId),C=await u(b.sessionId,A,g,y);C.exhausted||S.push(C)}catch(A){if(A.code==="ENOENT")continue;throw A}p.raw.on("close",()=>{for(let b of S)try{b.rl.close()}catch{}f.raw.writableEnded||f.raw.end()});try{for(;S.length>0;){let b=-1,A=1/0;for(let R=0;R<S.length;R++){let T=S[R];T.current!==null&&T.current.ts<A&&(A=T.current.ts,b=R)}if(b===-1)break;let C=S[b];if(f.raw.write(JSON.stringify(C.current.row)+`
210
- `),await l(C),C.exhausted){try{C.rl.close()}catch{}S.splice(b,1)}}}catch(b){for(let A of S)try{A.rl.close()}catch{}throw b}return f.raw.end(),f}),s.get("/v1/sessions/:id/events",async(p,f)=>{let h=p.params.id,w=p.query,m=await e.resolveCanonicalId(h)??h;if(!e.get(m)&&!await e.hasRecord(m))return f.code(404).send({error:"session not found"}),f;let y=w.kinds;if(!y||y.trim().length===0)return f.code(400).send({error:"kinds parameter is required"}),f;let k=y.split(",").map(R=>R.trim());if(k.length===0)return f.code(400).send({error:"kinds parameter is required"}),f;for(let R of k)if(!rr.has(R))return f.code(400).send({error:`kind "${R}" is not queryable; allowed kinds: ${[...rr].join(", ")}`}),f;let v=new Set(k),S;if(w.since!==void 0&&w.since.trim().length>0){let R=new Date(w.since);if(isNaN(R.getTime()))return f.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),f;S=R.getTime()}let b=E.historyFile(m),A=oi.createReadStream(b),C=ii.createInterface({input:A,crlfDelay:1/0});f.raw.setHeader("content-type","application/x-ndjson"),f.raw.statusCode=200;try{for await(let R of C){let T=typeof R=="string"?R.trim():"";if(T.length===0)continue;let M;try{M=JSON.parse(T)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",b);continue}if(!M||typeof M!="object"||Array.isArray(M)){console.debug("events endpoint: skipping non-object JSONL line in %s",b);continue}let j=M;if(typeof j.recordedAt!="number"||typeof j.params!="object"||j.params===null||Array.isArray(j.params))continue;let U=j.params;if(typeof U.update!="object"||U.update===null||Array.isArray(U.update))continue;let W=U.update,z=W.sessionUpdate;if(typeof z!="string"||!v.has(z)||S!==void 0&&j.recordedAt<S)continue;let D={ts:new Date(j.recordedAt).toISOString(),kind:z,update:W};W.messageId!==void 0&&W.messageId!==null&&(D.messageId=W.messageId),f.raw.write(JSON.stringify(D)+`
211
- `)}}catch(R){if(R.code==="ENOENT")return f.raw.end(),f;throw R}return f.raw.end(),f}),s.post("/v1/sessions/:id/prompt/:messageId/notify",async(p,f)=>{let h=p.params,w=h.id,m=await e.resolveCanonicalId(w)??w,g=h.messageId,y=p.body,k=typeof y?.callbackUrl=="string"?y.callbackUrl:"",v=typeof y?.secret=="string"?y.secret:"";if(!g||!k||!v){f.code(400).send({error:"messageId, callbackUrl, and secret are all required"});return}let S;try{S=new URL(k)}catch{f.code(400).send({error:"callbackUrl must be a valid absolute URL"});return}if(S.protocol!=="https:"&&S.protocol!=="http:"){f.code(400).send({error:"callbackUrl must be http or https"});return}let b=e.get(m);if(!b){f.code(404).send({error:"session not found or not warm"});return}let A=b.registerTurnNotify(g,k,v);if(A.alreadyTerminal){f.code(200).send({status:"already_terminal",stopReason:A.stopReason});return}f.code(202).send({status:"registered"})}),s.get("/v1/sessions/:id/attention",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);return!m&&!await e.hasRecord(w)?(f.code(404).send({error:"session not found"}),f):m?{flags:m.listAttentionFlags()}:{flags:(await e.store.read(w))?.attentionFlags??[]}}),s.get("/v1/sessions/attention",async(p,f)=>{let h=p.query;if(!h.source||h.source.trim().length===0)return f.code(400).send({error:"source query parameter is required"}),f;let w=await e.list({includeNonInteractive:!0}),m=[];for(let g of w){let y=e.get(g.sessionId),k;y?k=y.listAttentionFlags():k=(await e.store.read(g.sessionId))?.attentionFlags??[];for(let v of k)v.source===h.source&&m.push({...v,sessionId:g.sessionId})}return{flags:m}}),s.post("/v1/sessions/:id/attention/clear",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,g=p.body??{},y=typeof g.source=="string"?g.source:"",k=typeof g.reason=="string"?g.reason:"";if((y.length>0||k.length>0)&&!(y.length>0&&k.length>0)){f.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}y.length===0&&k.length;let v=e.get(w);if(v){if(y.length>0&&k.length>0)v.clearAttentionFlag(y,k);else{let R=Array.from(v.listAttentionFlags()).map(T=>`${T.source}::${T.reason}`);for(let T of R)v.clearAttentionFlag(T.split("::")[0],T.split("::").slice(1).join("::"))}f.code(204).send();return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}let S=e.store,b=await S.read(w);if(!b){f.code(404).send({error:"session not found"});return}let A=b.attentionFlags??[],C;if(y.length>0&&k.length>0){let R=`${y}::${k}`;C=A.filter(T=>`${T.source}::${T.reason}`!==R)}else C=[];if(C.length===A.length&&C.every((R,T)=>R.source===A[T].source&&R.reason===A[T].reason)){f.code(204).send();return}await S.write({...b,attentionFlags:C}),f.code(204).send()})}function wu(s,e,t,n={}){s.get("/v1/agents",async()=>Dt(e)),s.get("/v1/registry",async()=>e.load()),s.post("/v1/registry/refresh",async()=>{let r=await e.refresh();return{version:r.version,agentCount:r.agents.length}}),s.post("/v1/agents/:id/install",async(r,o)=>{let i=r.params.id,a=await e.getAgent(i);if(!a){o.code(404).send({error:`agent ${i} not found in registry`});return}if(a.distribution.uvx&&!a.distribution.npx&&!a.distribution.binary){o.send({agentId:a.id,version:a.version??"current",distribution:"uvx",installed:!1,message:"uvx agents resolve on first run; nothing to pre-install."});return}try{let d=await Me(a,[],{npmRegistry:n.npmRegistry}),c=a.distribution.npx?"npx":a.distribution.binary?"binary":"unknown";o.send({agentId:a.id,version:d.version,distribution:c,installed:!0,command:d.command})}catch(d){o.code(500).send({error:d.message})}}),s.post("/v1/agents/:id/sync",async(r,o)=>{let i=r.params.id;try{let{synced:a,skipped:d}=await t.syncFromAgent(i);return{synced:a.map(c=>({sessionId:c.sessionId,upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,cwd:c.cwd,title:c.title,updatedAt:c.updatedAt})),skipped:d}}catch(a){let d=a;if(d.code===x.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}K();function ku(s,e,t,n=()=>[]){s.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t,home:E.home(),driftedKeys:n()}))}import*as Iu from"os";K();He();var zn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,ir=class s{data;constructor(e){this.data=e}static async load(){let e=await de(E.peers());return new s(Ey(e))}get(e){return this.data.entries[e]}async set(e){this.data.entries[e.name]=e,await vu(this.data)}async delete(e){return e in this.data.entries?(delete this.data.entries[e],await vu(this.data),!0):!1}list(){return Object.values(this.data.entries).map(({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})=>({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})).sort((e,t)=>e.addedAt.localeCompare(t.addedAt))}};function Ey(s){if(!s||typeof s!="object")return{version:1,entries:{}};let e=s,t=e.entries&&typeof e.entries=="object"?e.entries:{},n={};for(let[r,o]of Object.entries(t)){if(!o||typeof o!="object")continue;let i=o;if(typeof i.name!="string"||typeof i.host!="string"||typeof i.port!="number"||typeof i.token!="string"||typeof i.expiresAt!="string"||typeof i.addedAt!="string")continue;let a={name:i.name,host:i.host,port:i.port,token:i.token,expiresAt:i.expiresAt,addedAt:i.addedAt};typeof i.label=="string"&&(a.label=i.label),typeof i.pinnedFingerprint=="string"&&(a.pinnedFingerprint=i.pinnedFingerprint),typeof i.pinnedAt=="string"&&(a.pinnedAt=i.pinnedAt),n[r]=a}return{version:1,entries:n}}async function vu(s){await he(E.peers(),s,{mode:384})}var Ty=3600*24*365,Qe=class extends Error{status;constructor(e,t){super(e),this.name="PeerLoginError",this.status=t}};function ar(s,e){return`${Ie(s)?"http":"https"}://${s}:${e}`}async function bu(s){let e=s.fetchImpl??fetch,t=`${s.host}:${s.port}`,n=ar(s.host,s.port),r;try{r=await e(`${n}/v1/auth/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:s.password,label:s.label,ttlSec:s.ttlSec??Ty})})}catch(i){throw new Qe(`Could not reach ${t}: ${i.message}`,502)}if(r.status===401)throw new Qe(`Wrong password for ${t}.`,401);if(r.status===403)throw new Qe(`No password is configured on ${t}. Run \`hydra-acp auth password\` on that daemon first.`,502);if(r.status===429)throw new Qe(`Too many failed login attempts on ${t}; try again later.`,429);if(!r.ok)throw new Qe(`Login to ${t} failed: HTTP ${r.status}`,502);let o=await r.json();if(!o.session_token||!o.expires_at)throw new Qe(`Login to ${t} returned a malformed response.`,502);return{token:o.session_token,expiresAt:o.expires_at}}async function ai(s){let e=s.fetchImpl??fetch,t=ar(s.host,s.port);try{await e(`${t}/v1/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json"},body:JSON.stringify({})})}catch{}}function Au(s){return{machine:vt(),hydraVersion:ue,startedAt:s,os:{platform:process.platform,release:Iu.release(),arch:process.arch},node:process.version}}async function dr(s){let e=s.fetchImpl??fetch,t;try{t=await e(`${ar(s.host,s.port)}/v1/system`,{headers:{Authorization:`Bearer ${s.token}`},signal:s.signal})}catch(n){return{kind:"error",message:n.message}}if(t.status===401||t.status===403)return{kind:"unauthorized"};if(t.status===404)return{kind:"unsupported"};if(!t.ok)return{kind:"error",message:`HTTP ${t.status}`};try{let n=await t.json();return typeof n?.machine=="string"?{kind:"ok",system:n}:{kind:"ok"}}catch{return{kind:"ok"}}}function Su(s){return s!==void 0&&s.length<=64&&zn.test(s)}function Cu(s,e){if(Su(s))return s;if(/^[\d.]+$/.test(e)||e.includes(":"))return;let t=e.split(".")[0];return Su(t)?t:void 0}function Ru(s,e){s.get("/v1/system",async()=>Au(e))}var Py=/^[A-Za-z0-9._-]+$/;function cr(s,e,t){let n=e==="extension"?"extensions":"transformers",r=`/v1/${n}`;s.get(r,async()=>({[n]:t.list()})),s.get(`${r}/:name`,async(o,i)=>{let a=o.params.name,d=t.get(a);if(!d){i.code(404).send({error:`unknown ${e}: ${a}`});return}return d}),s.post(r,async(o,i)=>{let a=o.body??{},d=My(a);if("error"in d){i.code(400).send({error:d.error});return}try{let c=t.register(d.config);i.code(201).send(c)}catch(c){Jn(i,c)}}),s.delete(`${r}/:name`,async(o,i)=>{let a=o.params.name;try{await t.unregister(a),i.code(204).send()}catch(d){Jn(i,d)}}),s.post(`${r}/:name/start`,async(o,i)=>{let a=o.params.name;try{let d=await t.startByName(a);i.code(200).send(d)}catch(d){Jn(i,d)}}),s.post(`${r}/:name/stop`,async(o,i)=>{let a=o.params.name;try{let d=await t.stopByName(a);i.code(200).send(d)}catch(d){Jn(i,d)}}),s.post(`${r}/:name/restart`,async(o,i)=>{let a=o.params.name;try{let d=await t.restartByName(a);i.code(200).send(d)}catch(d){Jn(i,d)}})}function Jn(s,e){let t=e.code,n=e.message??"unknown error";if(t==="NOT_FOUND"){s.code(404).send({error:n});return}if(t==="CONFLICT"){s.code(409).send({error:n});return}s.code(500).send({error:n})}function My(s){let e=s.name;if(typeof e!="string"||!Py.test(e))return{error:"name must match [A-Za-z0-9._-]+"};let t=s.command;if(t!==void 0&&(!Array.isArray(t)||t.some(i=>typeof i!="string")))return{error:"command must be string[]"};let n=s.args;if(n!==void 0&&(!Array.isArray(n)||n.some(i=>typeof i!="string")))return{error:"args must be string[]"};let r=s.env;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))return{error:"env must be an object of string\u2192string"};if(r&&Object.values(r).some(i=>typeof i!="string"))return{error:"env values must be strings"};let o=s.enabled;return o!==void 0&&typeof o!="boolean"?{error:"enabled must be a boolean"}:{config:{name:e,command:t??[],args:n??[],env:r??{},enabled:o===void 0?!0:o}}}function xu(s,e){cr(s,"extension",e)}function Eu(s,e){cr(s,"transformer",e)}function Tu(s,e){s.get("/v1/config",async()=>e())}import{z as mt}from"zod";K();import*as rn from"fs/promises";import*as Pu from"path";import{randomBytes as QC,scrypt as _y,timingSafeEqual as $y}from"crypto";import{promisify as Oy}from"util";var Fy=Oy(_y);function Mu(){return Pu.join(E.home(),"password-hash")}var Ny=128*1024*1024;async function _u(){try{return(await rn.readFile(Mu(),"utf8")).trim().length>0}catch(s){if(s.code==="ENOENT")return!1;throw s}}async function $u(s){if(typeof s!="string"||s.length===0)return!1;let e;try{e=(await rn.readFile(Mu(),"utf8")).trim()}catch(c){if(c.code==="ENOENT")return!1;throw c}let t=e.split("$");if(t.length!==6||t[0]!=="scrypt")return!1;let n=parseInt(t[1],10),r=parseInt(t[2],10),o=parseInt(t[3],10);if(!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o))return!1;let i=Buffer.from(t[4],"hex"),a=Buffer.from(t[5],"hex");if(i.length===0||a.length===0)return!1;let d=await Fy(s,i,a.length,{N:n,r,p:o,maxmem:Ny});return d.length!==a.length?!1:$y(d,a)}var Dy=mt.object({password:mt.string().min(1),label:mt.string().min(1).max(256).optional(),ttlSec:mt.number().int().positive().optional()}),Hy=mt.object({id:mt.string().optional()}).optional(),jy=mt.object({token:mt.string().min(32)});function Ou(s,e){s.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,n)=>{let r=Ly(t);if(e.rateLimiter.isBlocked(r))return n.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=Dy.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}if(!await _u())return n.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await $u(o.password))return e.rateLimiter.recordFailure(r),n.code(401).send({error:"Invalid password"});e.rateLimiter.recordSuccess(r);let a=await e.store.issue({label:o.label,ttlSec:o.ttlSec});return n.code(200).send({session_token:a.token,id:a.id,expires_at:a.expiresAt})}),s.post("/v1/auth/logout",async(t,n)=>{let r;try{r=Hy.parse(t.body??void 0)}catch{return n.code(400).send({error:"Invalid request body"})}let o=r?.id??t.authIdentity;if(!o||o==="service")return n.code(200).send({revoked:!1});let i=await e.store.revoke(o);return n.code(200).send({revoked:i})}),s.get("/v1/auth/verify",async(t,n)=>n.code(200).send({ok:!0})),s.get("/v1/auth/sessions",async(t,n)=>n.code(200).send({sessions:e.store.list()})),s.delete("/v1/auth/sessions",async(t,n)=>{let r=await e.store.revokeAll();return n.code(200).send({revoked:r})}),s.delete("/v1/auth/sessions/:id",async(t,n)=>{let r=t.params.id;return await e.store.revoke(r)?n.code(204).send():n.code(404).send({error:"Not found"})}),s.post("/v1/auth/rotate-token",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=jy.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}return e.staticTokenValidator.rotate(r.token),n.code(200).send({rotated:!0})})}function Ly(s){return s.ip||"unknown"}import{z as yt}from"zod";Gn();var Xy=yt.object({name:yt.string().min(1).max(64).regex(zn).optional(),host:yt.string().min(1),port:yt.number().int().positive().optional(),password:yt.string().min(1),label:yt.string().min(1).max(256).optional(),ttlSec:yt.number().int().positive().optional(),pinnedFingerprint:yt.string().min(1).optional()});function Wu(s,e){s.post("/v1/remotes",async(t,n)=>{let r;try{r=Xy.parse(t.body)}catch{return n.code(400).send({error:`Invalid request body (name must match ${zn} and the rest is a normal login request)`})}let o=r.port??_t;r.pinnedFingerprint&&Vn(r.host,o,r.pinnedFingerprint);let i;try{i=await bu({host:r.host,port:o,password:r.password,label:r.label,ttlSec:r.ttlSec})}catch(p){if(p instanceof Qe)return n.code(p.status).send({error:p.message});throw p}let a=await dr({host:r.host,port:o,token:i.token}),d=a.kind==="ok"?a.system:void 0,c=r.name;if(c===void 0){c=Cu(d?.machine,r.host);let p=c!==void 0?e.store.get(c):void 0,f=p!==void 0&&(p.host!==r.host||p.port!==o);if(c===void 0||f){await ai({host:r.host,port:o,token:i.token});let h=c===void 0?`Couldn't derive a remote name for ${r.host}`:`A remote named ${c} already points at ${p.host}:${p.port}`;return n.code(c===void 0?400:409).send({error:`${h}. Pass a name: hydra-acp remote add <name> ${r.host}`})}}let u=new Date().toISOString(),l={name:c,host:r.host,port:o,token:i.token,expiresAt:i.expiresAt,addedAt:u,...r.label!==void 0?{label:r.label}:{},...r.pinnedFingerprint!==void 0?{pinnedFingerprint:r.pinnedFingerprint,pinnedAt:u}:{}};return await e.store.set(l),e.health?.markOk(l.name,d),n.code(201).send({name:l.name,host:l.host,port:l.port,expiresAt:l.expiresAt,label:l.label,addedAt:l.addedAt,pinnedFingerprint:l.pinnedFingerprint,status:e.health?.get(l.name)?.status??"unknown"})}),s.get("/v1/remotes",async(t,n)=>{let r=e.store.list().map(o=>{let i=e.health?.get(o.name);return{...o,status:i?.status??"unknown",...i?.checkedAt?{lastCheckedAt:i.checkedAt}:{},...i?.system?{system:i.system}:{}}});return n.code(200).send({remotes:r})}),s.get("/v1/remotes/:name/agents",async(t,n)=>{let r=e.store.get(t.params.name);if(!r)return n.code(404).send({error:"Not found"});let i=`${Ie(r.host)?"http":"https"}://${r.host}:${r.port}`,a={Authorization:`Bearer ${r.token}`};try{let[d,c]=await Promise.all([fetch(`${i}/v1/agents`,{headers:a}),fetch(`${i}/v1/config`,{headers:a}).catch(()=>null)]);if(!d.ok)return n.code(d.status).header("content-type","application/json").send(await d.text());let u=await d.json(),l={};if(c?.ok){let p=await c.json();l={defaultAgent:p.defaultAgent,sessionDefaults:p.sessionDefaults}}return n.code(200).send({...u,...l})}catch(d){return n.code(502).send({error:`Could not reach remote "${r.name}": ${d.message}`})}}),s.delete("/v1/remotes/:name",async(t,n)=>{let r=t.params.name,o=e.store.get(r);return o?(await ai({host:o.host,port:o.port,token:o.token}),await e.store.delete(r),e.health?.forget(r),e.store.list().some(a=>a.host===o.host&&a.port===o.port)||ci(o.host,o.port),n.code(204).send()):n.code(404).send({error:"Not found"})})}function lr(s){let e=[],t=[],n=!1,r=o=>{if(!n){n=!0;for(let i of t)i(o)}};return s.on("message",(o,i)=>{if(i)return;let a=o.toString("utf8");try{let d=JSON.parse(a);for(let c of e)c(d)}catch(d){for(let c of e)c({jsonrpc:"2.0",id:null,error:{code:x.ParseError,message:`Failed to parse WS frame: ${d.message}`}})}}),s.on("close",()=>r()),s.on("error",o=>r(o)),{async send(o){if(n)throw new Error("ws is closed");let i=JSON.stringify(o);await new Promise((a,d)=>{s.send(i,c=>{if(c){d(c);return}a()})})},onMessage(o){e.push(o)},onClose(o){t.push(o)},async close(){n||(await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,clearTimeout(d),o())},d=setTimeout(a,5e3);s.once("close",a);try{s.close()}catch{a()}}),r())}}}Gn();import{WebSocket as Zy}from"ws";var ew=1e4,gi=class extends Error{url;elapsedMs;constructor(e,t){super(`hydra-acp: websocket connect to ${e} timed out after ${t}ms`),this.name="WsConnectTimeoutError",this.url=e,this.elapsedMs=t}};async function qu(s,e,t=ew){let n={};try{let r=new URL(s);if(r.protocol==="wss:"){let o=pi(r.hostname);o.rejectUnauthorized!==void 0&&(n.rejectUnauthorized=o.rejectUnauthorized),o.autoSelectFamily!==void 0&&(n.autoSelectFamily=o.autoSelectFamily),o.checkServerIdentity!==void 0&&(n.checkServerIdentity=o.checkServerIdentity)}}catch{}return new Promise((r,o)=>{let i=new Zy(s,e,n),a=Date.now(),d=setTimeout(()=>{i.off("open",c),i.off("error",u),i.on("error",()=>{});try{i.terminate()}catch{}o(new gi(s,Date.now()-a))},t),c=()=>{clearTimeout(d),i.off("error",u),r(i)},u=l=>{clearTimeout(d),i.off("open",c),o(l)};i.once("open",c),i.once("error",u)})}var tw=new Set(["session/attach","session/detach","session/prompt","session/cancel","session/close","session/delete","hydra-acp/session/delete","session/set_model","session/set_mode","session/set_config_option","_session/steering","hydra-acp/prompt/cancel","hydra-acp/prompt/update","hydra-acp/prompt/amend","hydra-acp/session/tool_content","hydra-acp/session/force_cancel"]);function nw(s){return tw.has(s)}function Ju(s,e,t,n){let r=[],o=a=>{for(let d of r)d(a)},i=(a,d)=>{e.handleLocalMessage(a,d,{connection:t.connection,clientId:n}).then(c=>c?s.send(c):void 0).catch(()=>{})};return s.onMessage(a=>{if("method"in a&&nw(a.method)){let d=a.params,c=typeof d?.sessionId=="string"?d.sessionId:void 0;if(c){if(ft(c)){i(a,c);return}if(a.method==="session/attach"){let u="id"in a;e.resolveLocalMiss(c).then(l=>{if(l.ok){i(a,l.foreignId);return}if(l.ambiguous&&u){s.send(Kn(a.id,x.SessionNotFound,`Session "${c}" exists on more than one remote (${l.ambiguous.join(", ")}). Address it as "<remote>:${c}".`));return}o(a)});return}}}o(a)}),{send:a=>s.send(a),onMessage:a=>r.push(a),onClose:a=>s.onClose(a),close:()=>s.close()}}var fr=class{constructor(e,t=rw,n){this.store=e;this.dial=t;this.localMiss=n}store;dial;localMiss;attachments=new Map;async resolveLocalMiss(e){if(!this.localMiss)return{ok:!1};if(await this.localMiss.resolvesLocally(e))return{ok:!1};let t=this.localMiss.cache.findByLocalId(e);return t.length===0?{ok:!1}:t.length>1?{ok:!1,ambiguous:t.map(n=>n.name)}:{ok:!0,foreignId:Je(t[0])}}async handleLocalMessage(e,t,n){let r="id"in e,o=r?e.id:void 0,i=ft(t);if(!i)return r?Kn(o,x.SessionNotFound,`not a federated session id: ${t}`):void 0;let a=zu(n.clientId,t),d={...e.params,sessionId:i.localId};if(e.method==="session/attach"){let u=this.store.get(i.name);if(!u)return r?Kn(o,x.SessionNotFound,`No remote named "${i.name}". Run \`hydra remote add\` first.`):void 0;let l=this.attachments.get(a);l&&(this.attachments.delete(a),l.peerConnection.close().catch(()=>{}));let p;try{p=await this.dial(u)}catch(m){return r?Kn(o,x.InternalError,`Could not reach remote "${i.name}": ${m.message}`):void 0}let f={peerConnection:p,localId:i.localId,target:n};this.wireAttachment(i.name,f);let h;try{h=await p.request("session/attach",d)}catch(m){return p.close().catch(()=>{}),r?hi(o,m):void 0}this.attachments.set(a,f);let w=h&&typeof h.sessionId=="string"?{...h,sessionId:t}:h;return r?{jsonrpc:"2.0",id:o,result:w}:void 0}let c=this.attachments.get(a);if(!c)return r?Kn(o,x.SessionNotFound,`"${t}" is not attached through this daemon.`):void 0;if(e.method==="session/detach"){let u,l;try{u=await c.peerConnection.request("session/detach",d)}catch(p){l=p}return this.attachments.delete(a),c.peerConnection.close().catch(()=>{}),l?r?hi(o,l):void 0:r?{jsonrpc:"2.0",id:o,result:u??{}}:void 0}if(r)try{let u=await c.peerConnection.request(e.method,d);return{jsonrpc:"2.0",id:o,result:u}}catch(u){return hi(o,u)}await c.peerConnection.notify(e.method,d).catch(()=>{})}detachClient(e){for(let[t,n]of[...this.attachments.entries()])n.target.clientId===e&&(this.attachments.delete(t),n.peerConnection.request("session/detach",{sessionId:n.localId}).catch(()=>{}),n.peerConnection.close().catch(()=>{}))}wireAttachment(e,t){let{peerConnection:n,localId:r,target:o}=t,i=Je({name:e,localId:r}),a=()=>{this.attachments.delete(zu(o.clientId,i))};n.onAnyNotification((d,c)=>{let u=d;!u||u.sessionId!==r||(c==="hydra-acp/session/closed"&&a(),o.connection.notify(c,{...u,sessionId:i}).catch(()=>{}))}),n.onRequest("hydra-acp/session/request_permission",async d=>{let c=d;if(!c||c.sessionId!==r)throw{code:x.MethodNotFound,message:"unexpected sessionId"};return o.connection.request("hydra-acp/session/request_permission",{...c,sessionId:i})}),n.onClose(()=>{a(),o.connection.notify("hydra-acp/session/closed",{sessionId:i}).catch(()=>{})})}};function zu(s,e){return`${s} ${e}`}function Kn(s,e,t){return{jsonrpc:"2.0",id:s,error:{code:e,message:t}}}function hi(s,e){let t=e,n=typeof t?.code=="number"?t.code:x.InternalError,r=typeof t?.message=="string"?t.message:String(e??"forward failed");return{jsonrpc:"2.0",id:s,error:{code:n,message:r,...t?.data!==void 0?{data:t.data}:{}}}}var sw=1e4;async function rw(s){let t=`${Ie(s.host)?"ws":"wss"}://${s.host}:${s.port}/acp`,n=await qu(t,["acp.v1",`hydra-acp-token.${s.token}`],sw);return new qe(lr(n))}var ow=3e4,iw=5e3,pr=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;snapshots=new Map;timer;start(){this.timer||(this.checkAll(),this.timer=setInterval(()=>{this.checkAll()},this.opts.intervalMs??ow),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}get(e){return this.snapshots.get(e)}markOk(e,t){this.snapshots.set(e,{status:"ok",checkedAt:new Date().toISOString(),...t?{system:t}:{}})}forget(e){this.snapshots.delete(e)}async checkAll(){let e=this.opts.fetchImpl??fetch;await Promise.allSettled(this.store.list().map(async t=>{let n=this.store.get(t.name);if(!n)return;let r=new AbortController,o=setTimeout(()=>r.abort(),iw);try{let i=await dr({host:n.host,port:n.port,token:n.token,fetchImpl:e,signal:r.signal});if(i.kind==="ok"){this.snapshots.set(t.name,{status:"ok",checkedAt:new Date().toISOString(),...i.system?{system:i.system}:{}});return}if(i.kind==="unauthorized"){this.snapshots.set(t.name,{status:"unauthorized",checkedAt:new Date().toISOString()});return}if(i.kind==="error")throw new Error(i.message);let d=`${Ie(n.host)?"http":"https"}://${n.host}:${n.port}/v1/auth/verify`,c=await e(d,{headers:{Authorization:`Bearer ${n.token}`},signal:r.signal});this.snapshots.set(t.name,{status:c.ok?"ok":"unauthorized",checkedAt:new Date().toISOString()})}catch(i){this.snapshots.set(t.name,{status:"unreachable",checkedAt:new Date().toISOString(),error:i.message})}finally{clearTimeout(o)}}))}};Gn();import{z as Vu}from"zod";var aw=Vu.object({sessionLabel:Vu.string().min(1).max(256)});function Gu(s,e){s.post("/v1/process-tokens",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=aw.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}let o=e.processRegistry.mint(r.sessionLabel,"script");return n.code(201).send({token:o})}),s.delete("/v1/process-tokens/:sessionLabel",async(t,n)=>t.authIdentity!=="service"?n.code(403).send({error:"Requires the service token"}):(e.processRegistry.revoke(t.params.sessionLabel),n.code(204).send()))}import{nanoid as mi}from"nanoid";import{randomBytes as Zu}from"crypto";import*as el from"os";import*as tl from"path";var dw=200;function cw(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[le];if(!t||typeof t!="object"||Array.isArray(t))return;let n=t.sentBy;if(!n||typeof n!="object"||Array.isArray(n))return;let r=n,o={};if(typeof r.sessionId=="string"&&r.sessionId.length>0&&(o.sessionId=r.sessionId),typeof r.label=="string"&&r.label.length>0&&(o.label=r.label.slice(0,dw)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function Ku(s,e,t){let n=cw(s);if(!n)return;let r={};if(n.label!==void 0&&(r.fromLabel=n.label),n.awaiting===!0&&(r.awaiting=!0),n.sessionId!==void 0){let o=await e.resolveCanonicalId(n.sessionId)??n.sessionId,i=await e.getOne(o);if(i){r.fromSession=o,i.title&&(r.fromSessionTitle=i.title);let a=e.get(o)?.currentPromptDepth;r.depth=(a??0)+1}else t?.(n.sessionId)}if(!(r.fromSession===void 0&&r.fromLabel===void 0))return r}var Qn=new Map;function Qu(s,e){let t=Qn.get(s);t||(t=new Set,Qn.set(s,t)),t.add(e);let n=!1;return()=>{if(n)return;n=!0;let r=Qn.get(s);r&&(r.delete(e),r.size===0&&Qn.delete(s))}}function Yu(s,e){if(s===e)return!0;let t=new Set,n=[e];for(;n.length>0;){let r=n.pop();if(t.has(r))continue;t.add(r);let o=Qn.get(r);if(o){if(o.has(s))return!0;for(let i of o)n.push(i)}}return!1}function O(s,e,t){let n=new Error(e);return n.code=s,t!==void 0&&(n.data=t),n}function gw(s){if(!s||typeof s!="object")return 512;let n=s.params?.update;if(!n)return 512;let r=512,o=n.content;if(typeof o=="string")r+=o.length;else if(o&&typeof o=="object"){let a=o;typeof a.text=="string"&&(r+=a.text.length),typeof a.data=="string"&&(r+=a.data.length)}let i=n.toolCall;if(i&&(typeof i.rawInput=="string"?r+=i.rawInput.length:i.rawInput&&typeof i.rawInput=="object"&&(r+=256),typeof i.rawOutput=="string"?r+=i.rawOutput.length:i.rawOutput&&typeof i.rawOutput=="object"&&(r+=256),Array.isArray(i.content)))for(let a of i.content){if(!a||typeof a!="object")continue;let d=a;if(typeof d.text=="string"&&(r+=d.text.length),d.content&&typeof d.content=="object"){let c=d.content;typeof c.text=="string"&&(r+=c.text.length)}}return r}function Te(s,e,t){let n=s.get(e);if(!n)throw O(x.SessionNotFound,t??`session ${e} not found`);return n}async function Tt(s,e){let t=sn(s),n,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&s.mcpTokenRegistry!==void 0&&s.getDaemonOrigin!==void 0&&(n=Zu(32).toString("hex"),r=s.mcpTokenRegistry.reserve(n),o={name:"hydra-acp-recall",type:"http",url:`${s.getDaemonOrigin()}/mcp/hydra-acp-recall`,headers:[{name:"Authorization",value:`Bearer ${n}`}]});let a=[...t?.descriptors??[],...o!==void 0?[o]:[]],d=ri({baselineMcpServers:void 0,stdinEnabled:!1,deps:s}),c;try{c=await s.manager.resurrect({...e,mcpServers:a,...d?{mintMcpServersForSwap:d}:{}})}catch(u){throw t!==void 0&&t.abandon(u instanceof Error?u:void 0),r!==void 0&&r.abandon(u instanceof Error?u:void 0),u}if(t!==void 0&&t.bindToSession(c),n!==void 0&&r!==void 0&&s.mcpTokenRegistry!==void 0){let u=n,l=s.mcpTokenRegistry;r.complete(c),c.onClose(()=>{l.unbind(u)})}return Aw(c,s),sl(c.sessionId,s),c}function nl(s,e){s.get("/acp",{websocket:!0},async(t,n)=>{let r=Gc({headers:n.headers,url:n.url});if(!r||!await e.validator.validate(r)){t.close(4401,"Unauthorized");return}let o=e.processRegistry?.resolve(r),i=`hydra_client_${mi(12)}`,a=lr(t),d={},c=e.foreignSessions?Ju(a,e.foreignSessions,d,i):a,u=new qe(c);d.connection=u;let l={clientId:i,processIdentity:o,attached:new Map};u.setParamsRewriter(m=>{if(m===null||typeof m!="object")return m;let g=m.sessionId;if(typeof g!="string"||l.attached.has(g))return m;let y=ye+g;return l.attached.has(y)?{...m,sessionId:y}:m}),u.onClose(()=>{for(let m of l.attached.values())e.manager.get(m.sessionId)?.detach(m.clientId);l.attached.clear(),e.foreignSessions?.detachClient(i)});let p=(m,g)=>{if(l.attached.get(m)?.readonly)throw O(x.PermissionDenied,`${g} not permitted on a read-only attachment`)};if(u.onRequest("initialize",async m=>{let g=pa.parse(m??{});g.clientInfo?.name&&(l.clientInfo={name:g.clientInfo.name,...g.clientInfo.version!==void 0?{version:g.clientInfo.version}:{}});let y=g.clientInfo?.version;return y&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,y):e.onTransformerVersion?.(o.name,y)),Iw()}),o&&e.extensionCommands){let m=e.extensionCommands;u.onRequest("hydra-acp/commands/register",async g=>{let y=g??{},k=Array.isArray(y.commands)?y.commands.map(v=>{if(!v||typeof v!="object")return;let S=v;if(typeof S.verb!="string")return;let b={verb:S.verb};return typeof S.argsHint=="string"&&(b.argsHint=S.argsHint),typeof S.description=="string"&&(b.description=S.description),b}).filter(v=>v!==void 0):[];return m.register(o.name,u,k),{ok:!0,registered:k.length}}),u.onClose(()=>{m.clear(o.name)})}if(o&&e.extensionMcp){let m=e.extensionMcp;u.onRequest("hydra-acp/mcp_tools/register",async y=>{let k=y??{},v=typeof k.instructions=="string"?k.instructions:void 0,S=Array.isArray(k.tools)?k.tools.map(b=>{if(!b||typeof b!="object")return;let A=b;if(typeof A.name!="string"||A.name.length===0||typeof A.description!="string"||A.inputSchema===null||typeof A.inputSchema!="object")return;let C={name:A.name,description:A.description,inputSchema:A.inputSchema};return A.outputSchema!==null&&typeof A.outputSchema=="object"&&(C.outputSchema=A.outputSchema),C}).filter(b=>b!==void 0):[];if(S.length===0)throw new Error("register_mcp_tools requires at least one tool");return m.register(o.name,u,v,S),{ok:!0,registered:S.length}});let g=y=>{let k=y??{};if(typeof k.sessionId!="string"||k.sessionId.length===0)throw O(x.InvalidParams,"sessionId is required");return k.sessionId};if(u.onRequest("hydra-acp/session/extension_state/get",async y=>{let k=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(!e.manager)throw O(x.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(k,o.name,v.key)??null}}),u.onRequest("hydra-acp/session/extension_state/list",async y=>{let k=g(y);if(!e.manager)throw O(x.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(k,o.name)}}),u.onRequest("hydra-acp/session/extension_state/set",async y=>{let k=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(v.value===void 0)throw O(x.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw O(x.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(k,o.name,v.key,v.value)}catch(S){throw O(x.InvalidParams,S.message)}return{ok:!0}}),u.onRequest("hydra-acp/session/extension_state/delete",async y=>{let k=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(!e.manager)throw O(x.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(k,o.name,v.key),{ok:!0}}),e.extensionMcpControls){let y=e.extensionMcpControls;u.onRequest("hydra-acp/mcp_tools/refresh_session",async k=>{let v=k??{};if(typeof v.sessionId!="string"||v.sessionId.length===0)throw O(x.InvalidParams,"refresh_session requires sessionId");return await y.notifyToolListChanged(v.sessionId,o.name),{ok:!0}})}u.onClose(()=>{m.clear(o.name)})}o?.kind==="transformer"&&(u.onRequest("hydra-acp/transformer/initialize",async m=>{let g=m??{},y=Array.isArray(g.intercepts)?g.intercepts.filter(k=>typeof k=="string"):[];if(e.transformers&&(e.transformers.registerConnection(o.name,u,y),e.manager?.defaultTransformers.includes(o.name))){let k=e.transformers.resolveChain([o.name])[0];if(k)for(let v of e.manager.liveSessions())v.addTransformer(k)}return{ack:!0}}),u.onClose(()=>{e.transformers?.deregisterConnection(o.name)}),u.onRequest("hydra-acp/message/emit",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0,k=typeof g.method=="string"?g.method:void 0,v=g.envelope,S=g.route;if(!y)throw O(-32602,"emit_message requires sessionId");if(!k&&S!=="client_broadcast")throw O(-32602,"emit_message requires method");let b=Te(e.manager,y),A=typeof g.respondsTo=="string"?g.respondsTo:void 0;if(A)return b.dischargeClaim(A,v),{ok:!0};if(S==="chain")return{ok:!0,response:await b.emitToChain(o.name,k,v)};if(S==="queue"){if(k!=="session/prompt")throw O(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await b.emitToQueue(o.name,v)}}if(S==="daemon")return{ok:!0,response:await b.emitToChain(o.name,k,v)};if(S==="client_broadcast"){if(!v||typeof v!="object")throw O(-32602,"client_broadcast requires an envelope object");return b.broadcastClientUpdate(v),{ok:!0}}throw O(-32602,`unsupported route: ${JSON.stringify(S)}`)}),u.onRequest("hydra-acp/session/request_permission",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw O(-32602,"hydra-acp/session/request_permission requires sessionId");return Te(e.manager,y).requestPermissionFromClients(g)}),u.onRequest("hydra-acp/transformer/attach",async m=>kw(m,o.name,e)),u.onRequest("hydra-acp/child_session/spawn",async m=>{let g=m??{},y=typeof g.agentId=="string"?g.agentId:void 0,k=typeof g.cwd=="string"?g.cwd:void 0,v=typeof g.parentSessionId=="string"?g.parentSessionId:void 0,S=it(g._meta??void 0),b=S.title,A=S.model,C=S.workspace;if(!k&&v){let D=e.manager.get(v);D&&(k=D.cwd)}if(!k)throw O(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let R=await fn(k),T=y??R.agentId??e.defaultAgent,M=await e.registry?.getAgent(T),j=qr(R.configDefaults,M??{id:T})?.value,U=A??j?.model,W=typeof g.interactive=="boolean"?g.interactive:!1,z=await e.manager.create({agentId:T,cwd:k,parentSessionId:v,interactive:W,transformChain:[],title:b,model:U,configDefaults:j,...C!==void 0?{workspace:C}:{}});return{childSessionId:z.sessionId,...z.workspace!==void 0||z.workspaceError!==void 0?{_meta:{[le]:{...z.workspace!==void 0?{workspaceInfo:z.workspace}:{},...z.workspaceError!==void 0?{workspaceError:z.workspaceError}:{}}}}:{}}}));let f=async(m,g)=>{let y=m??{};if(typeof y.sessionId!="string")throw O(x.InvalidParams,"fork_session requires sessionId");let k=typeof y.forkAt=="string"?y.forkAt:void 0,v=typeof y.cwd=="string"?y.cwd:void 0,S=typeof y.agentId=="string"?y.agentId:void 0,b=g?void 0:typeof y.mode=="string"&&(y.mode==="verbatim"||y.mode==="synthesis")?y.mode:void 0,A=typeof y.model=="string"&&y.model.length>0?y.model:void 0,C;if(g){let U=y.selection;if(U!==void 0&&(typeof U.text!="string"||U.text.length===0))throw O(x.InvalidParams,"selection.text must be a non-empty string");C={...U!==void 0?{selection:{text:U.text,...typeof U.responsePartId=="string"?{responsePartId:U.responsePartId}:{}}}:{}}}let R=await e.manager.forkSession(y.sessionId,{...C!==void 0?{side:C}:{},...k!==void 0?{forkAt:k}:{},...v!==void 0?{cwd:v}:{},...S!==void 0?{agentId:S}:{},...b!==void 0?{mode:b}:{},...A!==void 0?{model:A}:{}}),T=e.manager.get(R.sessionId);if(!T){let U=await e.manager.loadFromDisk(R.sessionId);if(!U)throw O(x.InternalError,`fork ${R.sessionId} vanished before it could be attached`);T=await Tt(e,{...U,onInstallProgress:gr(u)})}on(l,T,T.sessionId);let M=wt(u,T,l),{entries:j}=await T.attach(M,"full");l.attached.set(T.sessionId,{sessionId:T.sessionId,clientId:M.clientId,readonly:!1});for(let U of j){if(u.isClosed())break;await u.notify(U.method,We(Be(U.params,U.recordedAt),U.seq)).catch(()=>{})}return{...R,sessionId:T.sessionId}};u.onRequest("hydra-acp/session/fork",m=>f(m,!1)),u.onRequest("hydra-acp/session/side",m=>f(m,!0)),u.onRequest("hydra-acp/session/rewind",async m=>{let g=m??{};if(typeof g.sessionId!="string")throw O(x.InvalidParams,"hydra-acp/session/rewind requires sessionId");let y=g.keepThrough;if(y!==null&&(typeof y!="string"||y.length===0))throw O(x.InvalidParams,"keepThrough must be a non-empty messageId, or null to drop every turn");let k=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId;try{return await e.manager.rewindSession(k,y)}catch(v){let S=v;throw O(S.code??x.InternalError,S.message)}}),u.onRequest("session/fork",async m=>{let g=m??{};if(typeof g.sessionId!="string")throw O(x.InvalidParams,"session/fork requires sessionId");let y=typeof g.cwd=="string"?g.cwd:void 0,k=await e.manager.forkSession(g.sessionId,{...y!==void 0?{cwd:y}:{},mode:"verbatim"}),v=e.manager.get(k.sessionId);if(!v){let A=await e.manager.loadFromDisk(k.sessionId);if(!A)throw O(x.InternalError,`fork ${k.sessionId} vanished before it could be attached`);v=await Tt(e,{...A,onInstallProgress:gr(u)})}on(l,v,v.sessionId);let S=wt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let A of b){if(u.isClosed())break;await u.notify(A.method,We(Be(A.params,A.recordedAt),A.seq)).catch(()=>{})}return{sessionId:v.sessionId}});let h=async(m,g)=>{let y=m??{};if(typeof y.sessionId!="string")throw O(x.InvalidParams,`${g} requires sessionId`);let k=await e.manager.resolveCanonicalId(y.sessionId)??y.sessionId,v=e.manager.get(k);if(v)return await v.close({deleteRecord:!0,by:`session/delete ${l.clientId}`}),await e.manager.waitForDeletion(k),await e.manager.hasRecord(k)&&await e.manager.deleteRecord(k),{id:k,existed:!0};let S=await e.manager.deleteRecord(k);return{id:k,existed:S}};u.onRequest("session/delete",async m=>(await h(m,"session/delete"),{})),u.onRequest("session/close",async m=>{let g=m??{};if(typeof g.sessionId!="string")throw O(x.InvalidParams,"session/close requires sessionId");p(g.sessionId,"session/close");let y=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,k=e.manager.get(y);if(k)return await k.close({deleteRecord:!1,by:`session/close ${l.clientId}`+(l.processIdentity?` (${l.processIdentity.name})`:"")}),{};if(await e.manager.hasRecord(y))return{};throw O(x.SessionNotFound,`session ${y} not found`)}),u.onRequest("hydra-acp/session/delete",async m=>{let{id:g,existed:y}=await h(m,"hydra-acp/session/delete");if(!y)throw O(x.SessionNotFound,`session ${g} not found`);return{deleted:!0,sessionId:g}}),o?.kind==="transformer"&&(u.onRequest("hydra-acp/child_session/await",async m=>{let g=m??{},y=typeof g.childSessionId=="string"?g.childSessionId:void 0,k=g.until==="idle"?"idle":"turn_complete",v=typeof g.timeoutMs=="number"?Math.min(g.timeoutMs,18e5):3e5;if(!y)throw O(-32602,"await_child requires childSessionId");let S=Te(e.manager,y,`child session ${y} not found`);return new Promise(b=>{let R=[],T=[],M=0,j=!1,U,W,z=!1,D=()=>{z||(z=!0,clearTimeout(te),U?.(),W?.(),b(j?{entries:R,truncated:!0}:{entries:R}))};U=S.onBroadcast(Z=>{let oe=gw(Z);for(R.push(Z),T.push(oe),M+=oe;R.length>0&&(R.length>1e3||M>1048576);)R.shift(),M-=T.shift()??0,j=!0;k==="turn_complete"&&Z.params?.update?.sessionUpdate==="turn_complete"&&D()});let te=setTimeout(D,v);typeof te.unref=="function"&&te.unref(),W=S.onClose(()=>D())})}),u.onRequest("hydra-acp/child_session/close",async m=>{let g=m??{},y=typeof g.childSessionId=="string"?g.childSessionId:void 0;if(!y)throw O(-32602,"close_child_session requires childSessionId");let k=e.manager.get(y);return k&&await k.close({deleteRecord:!1,by:`child_session/close ${l.clientId}`}),{ok:!0}}),u.onRequest("hydra-acp/attention/set",async m=>vw(m,o.name,e)),u.onRequest("hydra-acp/attention/clear",async m=>bw(m,o.name,e)),u.onRequest("hydra-acp/connection/keep_alive",async m=>{let g=m??{},y=typeof g.token=="string"?g.token:void 0,k=typeof g.sessionId=="string"?g.sessionId:void 0,v=typeof g.estimatedRemainingMs=="number"?g.estimatedRemainingMs:void 0;return y&&k&&e.manager.get(k)?.keepAliveClaim(y,v),{ok:!0}})),u.onRequest("hydra-acp/session/tool_content",async m=>{let g=m??{};if(typeof g.sessionId!="string"||typeof g.hash!="string")throw O(x.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let y=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,k=await e.manager.loadToolBlob(y,g.hash);if(k===null)throw O(x.SessionNotFound,"tool content not found");return{content:k}}),u.onRequest("authenticate",async m=>hw(m,e)),u.onRequest("logout",async m=>mw(m,e)),u.onRequest("session/new",async m=>{let g=ga.parse(m),y=it(m?._meta),k=Array.isArray(y.transformers)&&y.transformers.every(ee=>typeof ee=="string")?y.transformers:e.manager.defaultTransformers??[],v=e.transformers?.resolveChain(k)??[],S=await fn(g.cwd),b=y.agentId??S.agentId??e.defaultAgent,A=await e.registry?.getAgent(b),C=qr(S.configDefaults,A??{id:b})?.value,R,T,M=g.mcpServers;if(y.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){R=Zu(32).toString("hex"),T=e.mcpTokenRegistry.reserve(R);let Oe={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${R}`}]};M=[...g.mcpServers??[],Oe]}let j,U,W=sn(e);W!==void 0&&(M=[...M??[],...W.descriptors]);let z=ri({baselineMcpServers:g.mcpServers,stdinEnabled:y.mcpStdin===!0,deps:e}),D;try{D=await e.manager.create({cwd:g.cwd,agentId:b,mcpServers:M,title:y.title,agentArgs:y.agentArgs,model:y.model??C?.model,configDefaults:C,onInstallProgress:gr(u),transformChain:v,originatingClient:l.clientInfo,...y.interactive!==void 0?{interactive:y.interactive}:{},...y.env!==void 0?{forwardedEnv:y.env}:{},...y.workspace!==void 0?{workspace:y.workspace}:{},...z?{mintMcpServersForSwap:z}:{}})}catch(ee){throw T!==void 0&&T.abandon(ee instanceof Error?ee:void 0),U!==void 0&&U.abandon(ee instanceof Error?ee:void 0),W!==void 0&&W.abandon(ee instanceof Error?ee:void 0),ee}if(R!==void 0&&T!==void 0&&e.mcpTokenRegistry!==void 0){let ee=R,Oe=e.mcpTokenRegistry;T.complete(D),D.onClose(()=>{Oe.unbind(ee)})}if(j!==void 0&&U!==void 0&&e.mcpTokenRegistry!==void 0){let ee=j,Oe=e.mcpTokenRegistry;U.complete(D),D.onClose(()=>{Oe.unbind(ee)})}W!==void 0&&W.bindToSession(D),sl(D.sessionId,e);let te,Z;try{on(l,D,D.sessionId),te=wt(u,D,l),{entries:Z}=await D.attach(te,"full")}catch(ee){throw await D.close({deleteRecord:!1,by:"session/new attach-failed"}).catch(()=>{}),ee}l.attached.set(D.sessionId,{sessionId:D.sessionId,clientId:te.clientId,readonly:!1}),setImmediate(()=>{(async()=>{for(let ee of Z){if(u.isClosed())break;await u.notify(ee.method,We(Be(ee.params,ee.recordedAt),ee.seq)).catch(()=>{})}})()});let oe=hr(D),Re=mr(D);return{sessionId:D.sessionId,...oe?{modes:oe}:{},...Re?{models:Re}:{},configOptions:D.buildConfigOptions(),_meta:yr(e.manager,D,{clientId:te.clientId})}}),u.onRequest("session/attach",async m=>{let g=ma.parse(m),y=g.clientInfo?.version;y&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,y):e.onTransformerVersion?.(o.name,y));let k=it(g._meta),v=k.resume,S=k.readonly===!0,b=k.env;s.log.info(`session/attach sessionId=${g.sessionId} hasResumeHints=${!!v} readonly=${S}`);let A=v?g.sessionId:await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,C=e.manager.get(A);if(!C&&S){let D=await e.manager.loadFromDisk(A);if(!D)throw O(x.SessionNotFound,`session ${g.sessionId} not found`);let te=Lt(await e.manager.loadHistory(A,{...k.historyLimit!==void 0?{maxEntries:k.historyLimit}:{}}),D.side),Z=g.clientId??`cli_${mi(8)}`;l.attached.set(D.hydraSessionId,{sessionId:D.hydraSessionId,clientId:Z,readonly:!0}),s.log.info(`session/attach OK (viewer) sessionId=${D.hydraSessionId} clientId=${Z} attachedCount=${l.attached.size} replayed=${te.length}`);for(let oe of te)await u.notify(oe.method,We(Be(oe.params,oe.recordedAt),oe.seq)).catch(()=>{});return{sessionId:D.hydraSessionId,clientId:Z,connectedClients:[Z],historyPolicy:"full",replayed:te.length,_meta:Sw(D)}}let R=!C;if(!C){let D=await e.manager.loadFromDisk(A),te=await yw(A,v,D?.upstreamSessionId,e.manager);te.kind==="ignore"&&s.log.warn(te.logMessage);let Z=D;if(v&&te.kind==="honor"&&(Z={...D,hydraSessionId:g.sessionId,upstreamSessionId:v.upstreamSessionId,agentId:v.agentId,cwd:D?.workspace?.path??v.cwd,...v.title!==void 0?{title:v.title}:{},...v.agentArgs!==void 0?{agentArgs:v.agentArgs}:{}}),!Z)throw O(x.SessionNotFound,`session ${g.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(Z.agentId,Z.upstreamSessionId))throw O(x.SessionNotFound,`session ${g.sessionId} was deleted`);let oe=Z.originatingClient?Z:{...Z,originatingClient:l.clientInfo},Re=b!==void 0?{...oe,forwardedEnv:b}:oe;C=await Tt(e,{...Re,onInstallProgress:gr(u)})}on(l,C,C.sessionId);let T=wt(u,C,l,g.clientInfo,g.clientId),M=k.replayMode==="drip",{entries:j,appliedPolicy:U}=await C.attach(T,g.historyPolicy,{afterMessageId:g.afterMessageId,afterSeq:g.afterSeq,raw:M,...k.historyLimit!==void 0?{historyLimit:k.historyLimit}:{},...k.toolContent!==void 0?{toolContent:k.toolContent}:{}});if(l.attached.set(C.sessionId,{sessionId:C.sessionId,clientId:T.clientId,readonly:S}),b!==void 0&&await e.manager.setForwardedEnv(C.sessionId,b).catch(()=>{}),s.log.info(`session/attach OK sessionId=${C.sessionId} clientId=${T.clientId} attachedCount=${l.attached.size} requestedPolicy=${g.historyPolicy} appliedPolicy=${U} replayed=${j.length} readonly=${S}${M?" replayMode=drip":""}`),M){let D=k.dripSpeed&&k.dripSpeed>0?k.dripSpeed:1,te=750;(async()=>{let Z=null;for(let oe of j){let Re=typeof oe.recordedAt=="number"?oe.recordedAt:null;if(Z!==null&&Re!==null){let ee=Math.min(te,Math.max(0,(Re-Z)/D));ee>0&&await new Promise(Oe=>setTimeout(Oe,ee))}Re!==null&&(Z=Re);try{await u.notify(oe.method,We(Be(oe.params,Re??void 0),oe.seq))}catch{return}}})()}else for(let D=0;D<j.length&&!u.isClosed();D++){let te=j[D],Z=u.notify(te.method,We(Be(te.params,te.recordedAt),te.seq)).catch(()=>{});(D+1)%200===0&&await Z}C.replayPendingPermissions(T);let W=hr(C),z=mr(C);return{sessionId:C.sessionId,clientId:T.clientId,connectedClients:C.connectedClients(T.clientId),historyPolicy:U,replayed:j.length,...W?{modes:W}:{},...z?{models:z}:{},configOptions:C.buildConfigOptions(),_meta:yr(e.manager,C,{resurrected:R})}}),u.onRequest("session/detach",async m=>{let g=ya.parse(m),y=l.attached.get(g.sessionId);if(!y)throw O(x.SessionNotFound,"client not attached to that session");let k=e.manager.get(g.sessionId);return k?.detach(y.clientId),l.attached.delete(g.sessionId),k&&e.manager.reapIfOrphanedNonInteractive(g.sessionId),{sessionId:g.sessionId,_meta:{[le]:{detachStatus:"detached"}}}}),u.onRequest("session/list",async m=>{let g=wa.parse(m??{});return{sessions:(await e.manager.list({cwd:g.cwd})).filter(S=>S.originatingClient?.name!==$s).map(ka)}}),u.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw O(x.InternalError,"agent registry unavailable");return Dt(e.registry)}),u.onRequest("hydra-acp/agents/auth_methods",async m=>{let g=m??{};if(typeof g.agentId!="string"||g.agentId.length===0)throw O(x.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(g.agentId)).authMethods??[]}}),u.onRequest("session/prompt",async m=>{let g=va.parse(m);p(g.sessionId,"session/prompt");let y=await Ku(g,e.manager,b=>{s.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${b} sessionId=${g.sessionId}`)});if(y?.fromSession!==void 0){if((y.depth??0)>3)throw s.log.warn(`session/prompt: refusing depth ${y.depth} chain from ${y.fromSession} to ${g.sessionId}`),O(x.InvalidRequest,`message chain too deep (${y.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(y.awaiting===!0&&Yu(y.fromSession,g.sessionId))throw s.log.warn(`session/prompt: refusing deadlock ${y.fromSession} -> ${g.sessionId}`),O(x.InvalidRequest,`would deadlock: ${g.sessionId} is already blocked waiting on ${y.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let k=l.attached.get(g.sessionId);if(!k)throw s.log.warn(`session/prompt rejected: not attached sessionId=${g.sessionId} attachedKeys=[${[...l.attached.keys()].join(",")}]`),O(x.SessionNotFound,"not attached to session");let v=e.manager.get(g.sessionId);if(!v){let b=await e.manager.loadFromDisk(g.sessionId);if(!b)throw O(x.SessionNotFound,`session ${g.sessionId} not found`);s.log.info(`session/prompt auto-resurrecting cold sessionId=${g.sessionId}`),v=await Tt(e,b);let A=wt(u,v,l,void 0,k.clientId);await v.attach(A,"none")}let S=y?.awaiting===!0&&y.fromSession!==void 0?Qu(y.fromSession,g.sessionId):void 0;try{return await v.prompt(k.clientId,g,y)}finally{S?.()}});let w=m=>{let g;try{g=is.parse(m)}catch(v){s.log.warn(`session/cancel: invalid params: ${v.message}`);return}let y=l.attached.get(g.sessionId);if(!y)return;if(y.readonly){s.log.warn(`session/cancel dropped (readonly attachment) sessionId=${g.sessionId}`);return}let k=e.manager.get(g.sessionId);k&&k.cancel(y.clientId).catch(v=>{s.log.warn(`session/cancel for ${g.sessionId}: ${v.message}`)})};u.onNotification("session/cancel",w),u.onRequest("session/cancel",async m=>{let g=is.parse(m);return p(g.sessionId,"session/cancel"),w(m),null}),u.onRequest("hydra-acp/prompt/cancel",async m=>{let g=Sa.parse(m);return p(g.sessionId,"hydra-acp/prompt/cancel"),Te(e.manager,g.sessionId).cancelQueuedPrompt(g.messageId)}),u.onRequest("hydra-acp/session/force_cancel",async m=>{let g=is.parse(m);return p(g.sessionId,"hydra-acp/session/force_cancel"),Te(e.manager,g.sessionId).forceCancel()}),u.onRequest("hydra-acp/prompt/update",async m=>{let g=Ia.parse(m);return p(g.sessionId,"hydra-acp/prompt/update"),Te(e.manager,g.sessionId).updateQueuedPrompt(g.messageId,g.prompt)}),u.onRequest("hydra-acp/prompt/amend",async m=>{let g=Aa.parse(m);p(g.sessionId,"hydra-acp/prompt/amend");let y=l.attached.get(g.sessionId);if(!y)throw O(x.SessionNotFound,"not attached to session");return Te(e.manager,g.sessionId).amendPrompt(y.clientId,g)}),u.onRequest("_session/steering",async m=>{let g=Ca.parse(m);p(g.sessionId,"_session/steering");let y=l.attached.get(g.sessionId);if(!y)throw O(x.SessionNotFound,"not attached to session");let k=e.manager.get(g.sessionId);if(!k){let v=await e.manager.loadFromDisk(g.sessionId);if(!v)throw O(x.SessionNotFound,`session ${g.sessionId} not found`);k=await Tt(e,v);let S=wt(u,k,l,void 0,y.clientId);await k.attach(S,"none")}return k.steer(y.clientId,g)}),u.onRequest("session/resume",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw O(x.InvalidParams,"session/resume requires sessionId");let k=await e.manager.resolveCanonicalId(y)??y,v=e.manager.get(k);if(!v){let C=await e.manager.loadFromDisk(k);if(!C)throw O(x.SessionNotFound,`session ${y} not found in memory or on disk`);v=await Tt(e,C)}on(l,v,v.sessionId);let S=wt(u,v,l);await v.attach(S,"pending_only"),l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1}),v.replayPendingPermissions(S);let b=hr(v),A=mr(v);return{sessionId:v.sessionId,...b?{modes:b}:{},...A?{models:A}:{},configOptions:v.buildConfigOptions(),_meta:yr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/load",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw O(x.InvalidParams,"session/load requires sessionId");let k=await e.manager.resolveCanonicalId(y)??y,v=e.manager.get(k);if(!v){let R=await e.manager.loadFromDisk(k);if(!R)throw O(x.SessionNotFound,`session ${y} not found in memory or on disk`);v=await Tt(e,R)}on(l,v,v.sessionId);let S=wt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let R of b){if(u.isClosed())break;await u.notify(R.method,We(Be(R.params,R.recordedAt),R.seq)).catch(()=>{})}v.replayPendingPermissions(S);let A=hr(v),C=mr(v);return{sessionId:v.sessionId,...A?{modes:A}:{},...C?{models:C}:{},configOptions:v.buildConfigOptions(),_meta:yr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/set_model",async m=>{let g=m?.sessionId;typeof g=="string"&&p(g,"session/set_model");let y=ww(m,e.manager);if(y.kind==="error")throw s.log.warn(y.logMessage),O(y.code,y.message);if(y.kind==="no_op")return s.log.warn(y.logMessage),await u.notify("session/update",{sessionId:y.sessionId,update:{sessionUpdate:"_hydra_current_model_update",currentModel:y.currentModel}}).catch(()=>{}),null;s.log.info(y.logMessage);let{modelId:k}=y,v=await y.session.forwardModelChange(k,m);return y.session.applyAgentConfigOptionResponse(v,"model"),y.session.applyModelChange(k),v}),u.onRequest("session/set_mode",async m=>{let g=m,y=g?.sessionId;if(typeof y=="string"&&p(y,"session/set_mode"),!g||typeof g.sessionId!="string")throw O(x.InvalidParams,"session/set_mode requires string sessionId");if(typeof g.modeId!="string")throw O(x.InvalidParams,"session/set_mode requires string modeId");let k=Te(e.manager,g.sessionId),v=await k.forwardRequest("session/set_mode",m);return k.applyModeChange(g.modeId),v}),u.onRequest("session/set_config_option",async m=>{let g=m,y=b=>O(x.InvalidParams,b),k=g?.sessionId;if(typeof k=="string"&&p(k,"session/set_config_option"),!g||typeof g.sessionId!="string")throw y("session/set_config_option requires string sessionId");if(typeof g.configId!="string")throw y("session/set_config_option requires string configId");if(typeof g.value!="string")throw y("session/set_config_option requires string value");let v=Te(e.manager,g.sessionId),S=v.buildConfigOptions().find(b=>b.id===g.configId);if(!S)throw y(`unknown configId ${JSON.stringify(g.configId)} for this session`);if(!S.options.some(b=>b.value===g.value))throw y(`value ${JSON.stringify(g.value)} is not valid for configId ${JSON.stringify(g.configId)}`);switch(g.configId){case"model":{if(g.value!==v.currentModel){let b=await v.forwardModelChange(g.value);v.applyAgentConfigOptionResponse(b,"model")}v.applyModelChange(g.value);break}case"mode":{g.value!==v.currentMode&&await v.forwardRequest("session/set_mode",{sessionId:g.sessionId,modeId:g.value}),v.applyModeChange(g.value);break}case"agent":{g.value!==v.agentId&&await v.setAgent(g.value);break}default:{let b=await v.forwardRequest("session/set_config_option",{sessionId:g.sessionId,configId:g.configId,value:g.value});v.applyAgentConfigOptionResponse(b,g.configId)&&v.broadcastConfigOptions()}}return{configOptions:v.buildConfigOptions()}}),u.setDefaultHandler(async(m,g)=>{let y=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),k=g.startsWith("session/"),v=g.startsWith("hydra-acp/");if(!k&&!v||m===null||typeof m!="object"||y.has(g))throw O(x.MethodNotFound,`Method not found: ${g}`);let S=m.sessionId;if(typeof S!="string")throw O(x.MethodNotFound,`Method not found: ${g}`);return p(S,g),Te(e.manager,S).forwardRequest(g,m)})})}async function hw(s,e){let t=s??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw O(x.InvalidParams,"authenticate requires a non-empty methodId string");let n=t.methodId,r=t._meta?.["hydra-acp"],o=typeof r?.sessionId=="string"?r.sessionId:void 0,i=typeof r?.agentId=="string"?r.agentId:void 0,a=o!==void 0?e.manager.getAgentForSession(o):void 0;if(!a||!a.isAlive()){let f=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(f)}let d=a.authMethods??[],c=d.find(f=>f.id===n);if(!c){let f=d.map(h=>h.id);throw O(x.InvalidParams,`authenticate: methodId ${JSON.stringify(n)} is not advertised by agent ${a.agentId}; valid: [${f.map(h=>JSON.stringify(h)).join(", ")}]`)}let u=c._meta?.type,l=(()=>{let f=c._meta?.["terminal-auth"];if(f&&typeof f=="object"&&!Array.isArray(f))return f})();if((c.type??(u==="agent"||u==="terminal"?u:l!==void 0?"terminal":"agent"))==="terminal"){let f=(k,v)=>{if(!Array.isArray(k))throw O(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be a string[]; got ${k===null?"null":typeof k}`);for(let S of k)if(typeof S!="string")throw O(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be string[]; got non-string entry ${JSON.stringify(S)}`);return k},h=await e.manager.planSpawnForAgent(a.agentId),w,m;if(l?.args!==void 0){let k=typeof l.command=="string"?l.command:void 0;w=k!==void 0&&tl.isAbsolute(k)?k:h.command,m=f(l.args,'_meta["terminal-auth"].args')}else{let k=c.args!==void 0?{raw:c.args,label:"args"}:c._meta?.args!==void 0?{raw:c._meta.args,label:"_meta.args"}:void 0,v=k!==void 0?f(k.raw,k.label):[];w=h.command,m=[...h.args,...v]}let g={};for(let[k,v]of Object.entries(process.env))typeof v=="string"&&(g[k]=v);Object.assign(g,h.env);let y=el.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${n}`),{kind:"terminal",command:w,args:m,env:g,cwd:y}}try{return await a.connection.request("authenticate",{methodId:n})}catch(f){throw ht(f,a)}}async function mw(s,e){let n=(s??{})._meta?.["hydra-acp"],r=typeof n?.sessionId=="string"?n.sessionId:void 0,o=typeof n?.agentId=="string"?n.agentId:void 0,i=r!==void 0?e.manager.getAgentForSession(r):void 0;if(!i||!i.isAlive()){let a=o??e.defaultAgent;i=await e.manager.bootstrapAgentForAuth(a)}return await i.connection.request("logout",{})}function gr(s){return e=>{let t={agentId:e.agentId,version:e.version,source:e.source,phase:e.phase};"receivedBytes"in e&&(t.receivedBytes=e.receivedBytes),"totalBytes"in e&&(t.totalBytes=e.totalBytes),"packageSpec"in e&&(t.packageSpec=e.packageSpec),s.notify(Ra,t).catch(()=>{})}}function hr(s){let e=s.availableModes();if(e.length===0)return;let t=e.map(r=>{let o={id:r.id,name:r.name??r.id};return r.description!==void 0&&(o.description=r.description),o});return{currentModeId:s.currentMode??e[0].id,availableModes:t}}function mr(s){let e=s.availableModels();if(e.length===0)return;let t=e.map(r=>{let o={modelId:r.modelId};return r.name!==void 0&&(o.name=r.name),r.description!==void 0&&(o.description=r.description),o});return{currentModelId:s.currentModel??e[0].modelId,availableModels:t}}async function yw(s,e,t,n){return e?await n.isRetiredGeneration(s,e.upstreamSessionId)?{kind:"ignore",logMessage:`session/attach ignoring stale resume hint sessionId=${s} hintUpstream=${e.upstreamSessionId} recordUpstream=${t} (retired generation)`}:{kind:"honor"}:{kind:"none"}}function ww(s,e){if(!s||typeof s!="object")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires params",logMessage:"session/set_model rejected: params not an object"};let t=s;if(typeof t.sessionId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string sessionId",logMessage:"session/set_model rejected: missing/non-string sessionId"};if(typeof t.modelId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string modelId",logMessage:`session/set_model rejected: missing/non-string modelId sessionId=${t.sessionId}`};let n=e.get(t.sessionId);if(!n)return{kind:"error",code:x.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=n.availableModels(),o=zt(t.modelId,r);if(o.kind==="none")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model passthrough (no availableModels) sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="exact")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model accepted sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="resolved")return{kind:"ok",session:n,modelId:o.modelId,logMessage:`session/set_model resolved sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} \u2192 ${JSON.stringify(o.modelId)}`};let i=r.map(d=>d.modelId).join(", "),a=o.kind==="ambiguous"?`ambiguous (trailing-segment matches [${o.candidates.join(", ")}])`:"not in availableModels";return n.currentModel!==void 0&&n.currentModel.length>0?{kind:"no_op",session:n,sessionId:t.sessionId,currentModel:n.currentModel,logMessage:`session/set_model no_op (resyncing client) sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} ${a} actual=${JSON.stringify(n.currentModel)} agentId=${n.agentId} known=[${i}]`}:{kind:"error",code:x.InvalidParams,message:`model "${t.modelId}" is ${a==="not in availableModels"?"not in this session's availableModels":a} (agent ${n.agentId}); known models: ${i}`,logMessage:`session/set_model rejected sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)} ${a} agentId=${n.agentId} known=[${i}] (no current model to fall back to)`}}async function kw(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0;if(!r)throw O(x.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw O(x.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw O(x.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return Te(t.manager,r).addTransformer(o),{ok:!0}}async function vw(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw O(x.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw O(x.InvalidParams,"hydra-acp/attention/set requires string reason");return Te(t.manager,r).setAttentionFlag(e,o,n.payload),{ok:!0}}async function bw(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw O(x.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw O(x.InvalidParams,"hydra-acp/attention/clear requires string reason");return Te(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function Sw(s){let e={sessionId:s.hydraSessionId,upstreamSessionId:s.upstreamSessionId,cwd:s.cwd,workspace:s.workspace,title:s.title,agentId:s.agentId,currentModel:s.currentModel,currentUsage:On(s.currentUsage),forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,updatedAt:s.createdAt??new Date().toISOString(),attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1},t={currentMode:s.currentMode,agentArgs:s.agentArgs,availableCommands:s.agentCommands,availableModes:s.agentModes,availableModels:s.agentModels,armedTaskList:[]};return{[le]:os(e,t)}}function yr(s,e,t={}){let n=s.liveListEntry(e),r={clientId:t.clientId,currentMode:e.currentMode,agentArgs:e.agentArgs,availableCommands:e.mergedAvailableCommands(),availableModes:e.availableModes(),availableModels:e.availableModels(),turnStartedAt:e.turnStartedAt,agentCapabilities:e.agentCapabilities,queue:e.queueSnapshot(),armedTaskList:e.armedBackgroundTasks,...t.resurrected===!0?{resurrected:!0}:{}};return mn(e.agentMeta,os(n,r))}function Iw(){return{protocolVersion:1,agentInfo:{name:"hydra",version:ue},agentCapabilities:{promptCapabilities:{image:!0,audio:!0,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0},loadSession:!0,auth:{logout:{}},sessionCapabilities:{attach:{},list:{},resume:{},delete:{},close:{},fork:{}}},authMethods:[{id:"proxy",name:"Hydra proxy",type:"agent",description:"Hydra proxies authentication to the downstream agent selected per session"}],_meta:{...mn(void 0,{prompt:{queueing:!0,cancelling:!0,updating:!0,amending:!0,pipelining:!1},agents:{list:!0,installProgress:!0},session:{fork:{forkAt:!0,agentSwap:!0,synthesis:!0,model:!0},side:{selection:!0},rewind:{}}}),steering:{supported:!0}}}}function Aw(s,e){if(!(!e.transformers||!e.manager))for(let t of e.manager.defaultTransformers){let n=e.transformers.resolveChain([t])[0];n&&s.addTransformer(n)}}function sl(s,e){if(!e.transformers)return;let t=e.transformers.interestedIn("lifecycle:session.starting");for(let n of t)n.connection.notify("hydra-acp/transformer/session_event",{event:"session.starting",sessionId:s}).catch(()=>{})}function wt(s,e,t,n,r){return{clientId:r??`cli_${mi(8)}`,connection:s,clientInfo:n}}function on(s,e,t){let n=s.attached.get(t);n&&(e.detach(n.clientId),s.attached.delete(t))}var wr=class{byToken=new Map;reserve(e){if(this.byToken.has(e))throw new Error("mcp token already bound");let t,n,r=new Promise((i,a)=>{t=i,n=a});r.catch(()=>{});let o={session:void 0,sessionReady:r,disposers:[]};return this.byToken.set(e,o),{complete:i=>{o.session=i,t(i)},abandon:i=>{this.byToken.delete(e),n(i??new Error("mcp token reservation abandoned"))}}}bind(e,t){let{complete:n}=this.reserve(e);n(t)}lookup(e){return this.byToken.get(e)}addDisposer(e,t){let n=this.byToken.get(e);n!==void 0&&n.disposers.push(t)}async unbind(e){let t=this.byToken.get(e);if(t!==void 0){this.byToken.delete(e);for(let n of t.disposers)try{await n()}catch{}}}size(){return this.byToken.size}};import{randomUUID as Cw}from"crypto";import{McpServer as Rw}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as xw}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as we}from"zod";function yi(s){if(s.method!=="session/update")return null;let t=s.params?.update;return!t||typeof t.sessionUpdate!="string"?null:{kind:t.sessionUpdate,update:t}}function Ce(s){return{content:[{type:"text",text:JSON.stringify(s)}],structuredContent:s}}var rl="Bearer ";function an(s){let e=s.headers.authorization;if(typeof e!="string"||!e.startsWith(rl))return;let t=e.slice(rl.length).trim();return t.length>0?t:void 0}function Ew(s){let e=new Rw({name:"hydra-acp-stdin",version:"1.0.0"},{instructions:"Piped input from `hydra cat --stream` is exposed here as a byte stream. Use `tail` for the latest N bytes (good for finding the end of a log), `head` for the first N bytes (good for headers/preamble), `read` for windowed reads against an absolute byte cursor, `wait_for_more` to block until new bytes arrive past a cursor, and `info` for the current cursors/capacity/closed status. Byte payloads come back base64-encoded."});return e.registerTool("tail",{description:"Return the most recent `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means older bytes existed but have been evicted from the ring.",inputSchema:{bytes:we.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let n=s.streamTail(t);return Ce(n)}),e.registerTool("head",{description:"Return the first `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means the head has already been evicted from the ring and the returned bytes start at the oldest still-resident cursor.",inputSchema:{bytes:we.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let n=s.streamHead(t);return Ce(n)}),e.registerTool("read",{description:"Read up to `max_bytes` bytes starting at absolute byte `cursor`. Returns `{bytes, nextCursor, gap?, eof?}` \u2014 `gap` is the number of bytes silently skipped because the ring had evicted them; `eof:true` means the producer closed and there is nothing left to read.",inputSchema:{cursor:we.number().int().min(0).describe("Absolute byte offset to start reading from. Use 0 to read from the very beginning (may produce a gap if old bytes have been evicted)."),max_bytes:we.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:we.number().int().min(0).optional().describe("If no bytes are available, block up to this many ms for more (capped server-side at 60_000).")}},async({cursor:t,max_bytes:n,wait_ms:r})=>{let o=await s.streamRead(t,n,r);return Ce(o)}),e.registerTool("wait_for_more",{description:"Block until bytes are available past `cursor`, the stream closes, or `timeout_ms` elapses. Returns one of {data, eof, timeout} plus the current `writeCursor`. Use this when you've consumed everything up to a cursor and want to wait for more without busy-polling.",inputSchema:{cursor:we.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:we.number().int().min(0).describe("Maximum ms to block (server caps at 60_000).")}},async({cursor:t,timeout_ms:n})=>{let r=await s.streamWaitFor(t,n),o=s.streamInfo();return Ce({outcome:r,writeCursor:o.writeCursor,closed:o.closed})}),e.registerTool("grep",{description:"Scan piped stdin line-by-line and return lines matching `pattern`. Prefer this over `read` when the question is 'find lines that mention X' \u2014 it filters server-side so you don't pull and decode 64 KiB base64 windows. Returns `{matches: [{cursor, line, before?, after?}], truncated, nextCursor, gap?, scannedBytes, eof?}`. Lines come back as decoded UTF-8 strings (not base64). When `truncated:true`, re-call with `cursor: nextCursor` to resume.",inputSchema:{pattern:we.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:we.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:we.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:we.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:we.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:we.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:we.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:we.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:we.number().int().min(0).optional().describe("Optional absolute byte offset to start scanning from. Omit to scan from the oldest still-resident byte. Pass the `nextCursor` from a previous truncated call to resume.")}},async t=>{let n={pattern:t.pattern};t.regex!==void 0&&(n.regex=t.regex),t.case_insensitive!==void 0&&(n.caseInsensitive=t.case_insensitive),t.invert!==void 0&&(n.invert=t.invert),t.max_matches!==void 0&&(n.maxMatches=t.max_matches),t.max_bytes!==void 0&&(n.maxBytes=t.max_bytes),t.context_before!==void 0&&(n.contextBefore=t.context_before),t.context_after!==void 0&&(n.contextAfter=t.context_after),t.cursor!==void 0&&(n.cursor=t.cursor);let r=s.streamGrep(n);return Ce(r)}),e.registerTool("info",{description:"Report cursor / capacity / closed state of the stdin ring. Cheap; safe to call repeatedly.",inputSchema:{}},async()=>{let t=s.streamInfo();return Ce(t)}),e}var Tw=1e4;function ol(s,e){let t=new Map;async function n(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let c=Ew(a),u=new xw({sessionIdGenerator:()=>Cw()});await c.connect(u);let l={server:c,transport:u};return t.set(i,l),e.addDisposer(i,async()=>{t.delete(i);try{await u.close()}catch{}try{await c.close()}catch{}}),u}async function r(i,a){let d=an(i);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let c=e.lookup(d);if(c===void 0){a.code(404).send({error:"unknown stdin token"});return}let u;if(c.session!==void 0)u=c.session;else{let p,f=new Promise(w=>{p=setTimeout(()=>w(void 0),Tw)}),h=await Promise.race([c.sessionReady.catch(()=>{}),f]);if(p!==void 0&&clearTimeout(p),h===void 0){a.code(503).send({error:"session not ready"});return}u=h}let l=await n(d,u);a.hijack(),await l.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),s.get("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),s.delete("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)})}import{randomUUID as Pw}from"crypto";import{McpServer as Mw}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as _w}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as Ye}from"zod";function $w(s){switch(s){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}var il=2e3,al=2e4;function Ow(s,e,t){if(e!=="tool_call"&&e!=="tool_call_update")return Vt([s]);let n=[],r=vn(t);r!==void 0?n.push(`Tool: ${r}`):typeof t.title=="string"&&t.title.length>0&&n.push(`Tool: ${t.title}`);let o=t.rawInput;if(o&&typeof o=="object"&&!Array.isArray(o))for(let[a,d]of Object.entries(o))typeof d=="string"&&d.length>0&&n.push(`${a}=${d}`);if(Array.isArray(t.locations))for(let a of t.locations)typeof a?.path=="string"&&a.path.length>0&&n.push(a.path);let i=ms(t);return i!==void 0&&n.push(i),n.join(`
212
- `)}function Fw(s,e){if(s.length<=148)return s;let r=Math.floor(148/2),o=e-r;o<0&&(o=0);let i=o+148;i>s.length&&(o=s.length-148,o<0&&(o=0));let a=s.slice(o,i);return o>0&&(a="\u2026"+a),i<s.length&&(a=a+"\u2026"),a}function Nw(s){let e=new Mw({name:"hydra-acp-recall",version:"1.0.0"},{instructions:"Search and retrieve detail from this session's pre-compaction history. After a compaction summary replaces earlier conversation in working memory, these tools let you page back specifics on demand. Use `search` to find entries by keyword, `range` to pull a contiguous slice verbatim, and `tool_calls` to enumerate prior tool invocations. These tools only return results once the session has been compacted at least once."});return e.registerTool("search",{description:"Search this session's prior conversation history (the part that was compacted out of your working memory) by keyword. Covers assistant and user messages, the arguments of every tool call including full shell commands, and what those calls printed. Returns matching entry ids with short snippets so you can decide which to pull in full via `range`. Use this when the compaction summary mentions something but you need the verbatim detail.",inputSchema:{query:Ye.string().min(1).describe("Case-insensitive substring to search for."),limit:Ye.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:Ye.boolean().optional().describe("Whether to include tool_call entries in the search (default true).")}},async({query:t,limit:n=10,include_tool_calls:r=!0})=>{let o=await s();if(!o.summarizedThroughEntry||o.summarizedThroughEntry===0)return Ce({matches:[],total_matched:0,truncated:!1,note:"This session has no compacted history. `search` retrieves detail from entries that were summarized out of the working conversation; nothing has been summarized yet."});let i=[],a=t.toLowerCase();for await(let{entryId:c,entry:u}of o.iterRecallNewestFirst()){let l=yi(u);if(!l)continue;let{kind:p,update:f}=l;if((p==="tool_call"||p==="tool_call_update")&&!r)continue;let h=Ow(u,p,f),w=h.toLowerCase().indexOf(a);if(w<0)continue;let m=$w(p),g=Fw(h,w),y=typeof u.recordedAt=="number"?String(u.recordedAt):void 0;if(i.push({entryId:c,speaker:m,snippet:g,timestamp:y}),i.length>=n)break}i.sort((c,u)=>c.entryId-u.entryId);let d=i.length>=n;return Ce({matches:i,total_matched:i.length,truncated:d})}),e.registerTool("range",{description:"Pull a contiguous range of prior conversation entries verbatim from this session's pre-compaction history, including each tool call's arguments and what it printed. Use after `search` narrows in on what you need. Capped at 50 entries per call.",inputSchema:{from_entry:Ye.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:Ye.number().int().min(0).describe("Zero-based index of the last entry to include (inclusive).")}},async({from_entry:t,to_entry:n})=>{let r=await s();if(!r.summarizedThroughEntry||r.summarizedThroughEntry===0)return Ce({text:"",entry_count:0,truncated:!1,note:"This session has no compacted history. `range` retrieves verbatim entries from the pre-compaction transcript; nothing has been compacted yet."});if(n<t)throw new Error(`range: to_entry (${n}) must be >= from_entry (${t})`);let o=n-t+1;if(o>50)throw new Error(`range: range size (${o}) exceeds maximum of 50 entries`);let i=await r.getRecallTotalCount();if(i===0)return Ce({text:"",entry_count:0,truncated:!1});let a=Math.min(t,i-1),d=Math.min(n,i-1),c=a>t||d<n;if(a>d)return{content:[{type:"text",text:""}],structuredContent:{text:"",entry_count:0,truncated:c}};let u=await r.sliceRecallHistory(a,d),l=Vt(u,{toolOutput:{maxPerCall:il,maxTotal:al}});return{content:[{type:"text",text:l}],structuredContent:{text:l,entry_count:u.length,truncated:c}}}),e.registerTool("tool_calls",{description:"Search this session's prior tool invocations by tool name, ACP kind, and/or file path. Returns when each tool was called, its arguments (including the full shell command), the result status, and what the call printed. Use this to recall which files were read/edited, what shell commands ran, and what they output.",inputSchema:{tool_name:Ye.string().optional().describe("Case-insensitive substring of the tool name. Names vary by agent for the same tool (Bash, Terminal, bash), so prefer `kind` when you want every shell invocation."),kind:Ye.string().optional().describe("ACP tool kind: execute (shell), read, edit, think, other. Agent-independent, unlike tool_name."),file_path:Ye.string().optional(),limit:Ye.number().int().min(1).max(100).optional(),include_output:Ye.boolean().optional().describe("Include what each call printed (default true). Set false when you only need the commands and not their results.")}},async({tool_name:t,kind:n,file_path:r,limit:o=20,include_output:i=!0})=>{let a=await s();if(!a.summarizedThroughEntry||a.summarizedThroughEntry===0)return Ce({calls:[],truncated:!1,note:"This session has no compacted history. `tool_calls` retrieves tool invocations from the pre-compaction transcript; nothing has been compacted yet."});let d=typeof t=="string"&&t.length>0,c=typeof n=="string"&&n.length>0,u=typeof r=="string"&&r.length>0;if(!d&&!c&&!u)throw new Error("tool_calls: at least one of tool_name, kind, or file_path must be provided");let l=new Map,p=Math.max(o*4,200);for await(let{entryId:y,entry:k}of a.iterRecallNewestFirst()){let v=yi(k);if(!v)continue;let{kind:S,update:b}=v;if(S!=="tool_call"&&S!=="tool_call_update")continue;let A=typeof b.toolCallId=="string"&&b.toolCallId.length>0?b.toolCallId:`__noid_${y}`,C=l.get(A);if(C||(C={entryId:y,toolName:"(unnamed)",nameAuthoritative:!1,rawInput:{},locations:[],status:"in_progress"},l.set(A,C)),y<C.entryId&&(C.entryId=y),!C.nameAuthoritative){let T=vn(b);T!==void 0?(C.toolName=T,C.nameAuthoritative=!0):typeof b.name=="string"&&b.name.length>0?(C.toolName=b.name,C.nameAuthoritative=!0):S==="tool_call"&&typeof b.title=="string"&&b.title.length>0&&(C.toolName=b.title,C.nameAuthoritative=!0)}if(C.kind===void 0&&typeof b.kind=="string"&&b.kind.length>0&&(C.kind=b.kind),C.output===void 0){let T=ms(b);T!==void 0&&(C.output=T)}let R=b.rawInput;if(R&&typeof R=="object"&&!Array.isArray(R)&&Object.keys(R).length>0)for(let[T,M]of Object.entries(R))C.rawInput[T]===void 0&&(C.rawInput[T]=M);if(Array.isArray(b.locations))for(let T of b.locations){let M=T?.path;typeof M=="string"&&M.length>0&&!C.locations.includes(M)&&C.locations.push(M)}if(typeof b.status=="string"&&C.status==="in_progress"&&(C.status=b.status),k.recordedAt!==void 0&&C.timestamp===void 0&&(C.timestamp=String(k.recordedAt)),l.size>=p)break}let f=[...l.keys()].sort((y,k)=>l.get(y).entryId-l.get(k).entryId),h=[],w=al,m=!1;for(let y of f){let k=l.get(y);if(k.toolName=io({name:k.toolName,rawInput:k.rawInput,...k.kind!==void 0?{kind:k.kind}:{}}),d&&!k.toolName.toLowerCase().includes(t.toLowerCase())||c&&(k.kind??"").toLowerCase()!==n.toLowerCase())continue;if(u){let b=r.toLowerCase(),A=["file_path","filePath","path"],C=!1;for(let R of A){let T=k.rawInput[R];if(typeof T=="string"&&T.toLowerCase().includes(b)){C=!0;break}}if(!C){for(let R of k.locations)if(R.toLowerCase().includes(b)){C=!0;break}}if(!C)continue}let v={};for(let[b,A]of Object.entries(k.rawInput))typeof A=="string"?v[b]=A.length>500?A.slice(0,497)+"\u2026":A:(typeof A=="number"||typeof A=="boolean")&&(v[b]=A);k.locations.length>0&&v.locations===void 0&&(v.locations=k.locations);let S={entryId:k.entryId,tool:k.toolName,args:v,status:k.status,timestamp:k.timestamp};if(k.kind!==void 0&&(S.kind=k.kind),i&&k.output!==void 0){let b=k.output,A=Math.min(il,w);if(A<=0)m=!0;else{let C=b.length<=A?b:b.slice(0,A-1)+"\u2026";S.output=C,S.outputBytes=b.length,S.outputTruncated=C.length<b.length,w-=C.length}}if(h.push(S),h.length>=o)break}let g=h.length>=o;return Ce({calls:h,truncated:g,...m?{outputBudgetExhausted:m}:{}})}),e}var Dw=1e4;function dl(s,e){let t=new Map;async function n(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let c=Nw(a),u=new _w({sessionIdGenerator:()=>Pw()});await c.connect(u);let l={server:c,transport:u};return t.set(i,l),e.addDisposer(i,async()=>{t.delete(i);try{await u.close()}catch{}try{await c.close()}catch{}}),u}async function r(i,a){let d=an(i);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let c=e.lookup(d);if(c===void 0){a.code(404).send({error:"unknown recall token"});return}let l=await n(d,async()=>{if(c.session!==void 0)return c.session;let p,f=new Promise(w=>{p=setTimeout(()=>w(void 0),Dw)}),h=await Promise.race([c.sessionReady.catch(()=>{}),f]);if(p!==void 0&&clearTimeout(p),h===void 0)throw new Error("recall: session not ready");return h});a.hijack(),await l.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),s.get("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),s.delete("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)})}var kr=class{byName=new Map;changeHandlers=[];register(e,t,n,r){this.byName.set(e,{connection:t,instructions:n,tools:[...r]}),this.fireChanged(e,"register")}clear(e){this.byName.delete(e)&&this.fireChanged(e,"clear")}lookup(e){return this.byName.get(e)}list(){return Array.from(this.byName.keys())}onChange(e){return this.changeHandlers.push(e),()=>{let t=this.changeHandlers.indexOf(e);t>=0&&this.changeHandlers.splice(t,1)}}fireChanged(e,t){for(let n of this.changeHandlers)try{n(e,t)}catch{}}};import{StreamableHTTPServerTransport as zw}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as Jw}from"crypto";import{Server as Hw}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as jw,ListToolsRequestSchema as Lw}from"@modelcontextprotocol/sdk/types.js";function cl(s,e,t,n){let r=typeof t=="function"?async()=>t():async()=>t,o=new Hw({name:s,version:"1.0.0"},{capabilities:{tools:{listChanged:!0}},...e.instructions!==void 0?{instructions:e.instructions}:{}}),i=a=>({name:a.name,description:a.description,inputSchema:a.inputSchema,...a.outputSchema!==void 0?{outputSchema:a.outputSchema}:{}});return o.setRequestHandler(Lw,async()=>{let a=n?.peekSessionId?.();if(a!==void 0&&n?.fetchSessionTools!==void 0)try{let d=await n.fetchSessionTools(a);if(d!==void 0)return{tools:d.map(i)}}catch{}return{tools:e.tools.map(i)}}),o.setRequestHandler(jw,async(a,d)=>{let c=a.params.name,u=d._meta?.progressToken??d.requestId,l=Bw(u,d.sendNotification);try{let p=await r(),f=await Ww(e.connection,s,c,a.params.arguments??{},p);return qw(f,c)}catch(p){return wi(p instanceof Error?p.message:String(p))}finally{l()}}),o}var Uw=15e3;function Bw(s,e,t=Uw){if(s===void 0)return()=>{};let n=0,r=setInterval(()=>{n+=1,e({method:"notifications/progress",params:{progressToken:s,progress:n}}).catch(()=>{})},t);return r.unref?.(),()=>clearInterval(r)}async function Ww(s,e,t,n,r){return await s.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:n,sessionId:r})}function qw(s,e){if(s===null||typeof s!="object")return wi(`extension ${e} returned non-object`);let t=s;return Array.isArray(t.content)?t:wi(`extension ${e} omitted content array`)}function wi(s){return{content:[{type:"text",text:s}],isError:!0}}var Vw=1e4;function ul(s,e,t){let n=new Map;async function r(u){try{await u.transport.close()}catch{}try{await u.server.close()}catch{}}function o(u){for(let l of n.values()){let p=l.get(u);p!==void 0&&(l.delete(u),r(p))}}async function i(u,l){for(let[p,f]of n){if(e.lookup(p)?.session?.sessionId!==u)continue;let w=f.get(l);if(w!==void 0)try{await w.server.sendToolListChanged()}catch{}}}t.onChange(u=>{o(u)});async function a(u,l){let p=n.get(u);p===void 0&&(p=new Map,n.set(u,p),e.addDisposer(u,async()=>{let v=n.get(u);if(v!==void 0){n.delete(u);for(let S of v.values())await r(S)}}));let f=p.get(l);if(f!==void 0)return f.transport;let h=t.lookup(l);if(h===void 0)return;let y=cl(l,h,async()=>{let v=e.lookup(u);if(v===void 0)throw new Error("mcp token no longer bound");if(v.session!==void 0)return v.session.sessionId;let S,b=new Promise(C=>{S=setTimeout(()=>C(void 0),Vw)}),A=await Promise.race([v.sessionReady.catch(()=>{}),b]);if(S!==void 0&&clearTimeout(S),A===void 0)throw new Error("session not ready");return A.sessionId},{peekSessionId:()=>e.lookup(u)?.session?.sessionId,fetchSessionTools:async v=>{let S=await h.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:v});if(!S||typeof S!="object")return;let b=S.tools;if(!Array.isArray(b))return;let A=[];for(let C of b){if(!C||typeof C!="object")continue;let R=C;if(typeof R.name!="string"||R.name.length===0||typeof R.description!="string"||R.inputSchema===null||typeof R.inputSchema!="object")continue;let T={name:R.name,description:R.description,inputSchema:R.inputSchema};R.outputSchema!==null&&typeof R.outputSchema=="object"&&(T.outputSchema=R.outputSchema),A.push(T)}return A}}),k=new zw({sessionIdGenerator:()=>Jw()});return await y.connect(k),p.set(l,{server:y,transport:k}),k}async function d(u,l){let p=an(u);if(p===void 0){l.code(401).send({error:"missing bearer token"});return}if(e.lookup(p)===void 0){l.code(404).send({error:"unknown mcp token"});return}let h=u.params.name,w=await a(p,h);if(w===void 0){l.code(404).send({error:`unknown mcp server: ${h}`});return}l.hijack(),await w.handleRequest(u.raw,l.raw,u.body)}let c={config:{skipAuth:!0}};return s.post("/mcp/:name",c,async(u,l)=>{await d(u,l)}),s.get("/mcp/:name",c,async(u,l)=>{await d(u,l)}),s.delete("/mcp/:name",c,async(u,l)=>{await d(u,l)}),{notifyToolListChanged:i}}async function ml(s,e){ek(s),_r(s.daemon.scrubEnv);let t=s,n=s.daemon.tls?await Xe.readFile(ce(s.daemon.tls.key)):void 0,r=s.daemon.tls?await Xe.readFile(ce(s.daemon.tls.cert)):void 0;await Xe.mkdir(E.home(),{recursive:!0});let{stream:o,fileStream:i,closeFile:a}=await Xw(s.daemon.logLevel),d=Gw({logger:{level:s.daemon.logLevel,stream:o},bodyLimit:256*1024*1024});await d.register(Kw,{options:{handleProtocols:ji}}),Hr(F=>{d.log.info(F)}),Ur(F=>{d.log.info(F)});let c=await Gs.load(),u=await ir.load();fi(),ui(u);let l=new pr(u);l.start();let p=new sr(u);p.start();let f=new Zs,h=new Xs,w=new Ks(e),m=new Ys([w,new Qs(c),h]),g=Vc({validator:m});d.addHook("onRequest",async(F,Ae)=>{F.routeOptions.config?.skipAuth||F.url==="/acp"||F.url?.startsWith("/acp?")||(await g(F,Ae),!Ae.sent&&F.authIdentity?.startsWith("script:")&&!Kc(F.method,F.routeOptions.url)&&Ae.code(403).send({error:"script tokens may only access read-only session data"}))});let y=setInterval(()=>{c.sweepExpired()},300*1e3);y.unref();let k=setInterval(()=>{f.sweepExpired()},300*1e3);k.unref();let v=new ss(s,{onFetched:()=>{$c(v,C)},onStaleFallback:(F,Ae)=>{let cn=Math.round(Ae/36e5),un=cn>=48?`${Math.round(cn/24)}d`:`${cn}h`;d.log.warn(`registry fetch failed (${F.message}); serving stale cache last synced ${un} ago; agent versions may be outdated ('hydra registry refresh' to retry)`)}});Zo(F=>d.log.info(F));let S={info:F=>d.log.info(F),warn:F=>d.log.warn(F)},b=F=>dt.spawn({...F,stderrTailBytes:s.daemon.agentStderrTailBytes,logger:S});zi(s.compressToolContent);let A=new Js,C=new Hs(v,b,void 0,{idleTimeoutMs:s.daemon.sessionIdleTimeoutSeconds*1e3,orphanTimeoutMs:s.daemon.nonInteractiveOrphanTimeoutSeconds*1e3,sessionDefaults:s.sessionDefaults,synopsisAgent:s.synopsisAgent,synopsisModel:s.synopsisModel,compactionAgent:s.compaction?.agent,compactionModel:s.compaction?.model,defaultTransformers:s.defaultTransformers,sessionHistoryMaxEntries:s.daemon.sessionHistoryMaxEntries,sessionHistoryArchiveMaxBytes:s.daemon.sessionHistoryArchiveMaxBytes,sessionHistoryArchiveTiers:s.daemon.sessionHistoryArchiveTiers,logger:S,npmRegistry:s.npmRegistry,extensionCommands:A,defaultCwd:s.defaultCwd,disableWorkspaceSnapshots:s.disableWorkspaceSnapshots}),R=new fr(u,void 0,{resolvesLocally:async F=>await C.resolveCanonicalId(F)!==void 0,cache:p}),T=new qs(Oi(s),void 0,{tokenRegistry:h}),M=new zs(Fi(s),void 0,{tokenRegistry:h}),j=[];ku(d,ue,Nc(s),()=>j);let U=new Date().toISOString();Ru(d,U);let W=new wr,z=new kr,D,te=()=>{if(D!==void 0)return D;let F=d.server.address();return D=`http://127.0.0.1:${F&&typeof F=="object"?F.port:s.daemon.port}`,D},Z={agentId:s.defaultAgent,cwd:s.defaultCwd,publicHost:s.daemon.publicHost,host:s.daemon.host,port:s.daemon.port,compaction:s.compaction};yu(d,C,Z,{extensionMcp:z,mcpTokenRegistry:W,getDaemonOrigin:te},u,p),fu(d,{store:u,localMiss:{resolvesLocally:async F=>await C.resolveCanonicalId(F)!==void 0,cache:p}}),wu(d,v,C,{npmRegistry:s.npmRegistry}),xu(d,T),Eu(d,M);let oe={host:s.daemon.host,port:s.daemon.port,...s.daemon.publicHost!==void 0?{publicHost:s.daemon.publicHost}:{},...s.daemon.tls?{tls:{cert:ce(s.daemon.tls.cert),key:ce(s.daemon.tls.key)}}:{}};Tu(d,()=>({defaultAgent:t.defaultAgent,defaultCwd:t.defaultCwd,sessionDefaults:{...t.sessionDefaults},...t.synopsisAgent!==void 0?{synopsisAgent:t.synopsisAgent}:{},...t.synopsisModel!==void 0?{synopsisModel:t.synopsisModel}:{},defaultTransformers:[...t.defaultTransformers],listen:oe})),Ou(d,{store:c,rateLimiter:f,staticTokenValidator:w}),Wu(d,{store:u,health:l}),Gu(d,{processRegistry:h}),ol(d,W),dl(d,W);let Re=ul(d,W,z);nl(d,{validator:m,manager:C,defaultAgent:s.defaultAgent,processRegistry:h,onExtensionVersion:(F,Ae)=>T.reportVersion(F,Ae),onTransformerVersion:(F,Ae)=>M.reportVersion(F,Ae),transformers:M,extensionCommands:A,mcpTokenRegistry:W,extensionMcp:z,extensionMcpControls:Re,getDaemonOrigin:te,registry:v,foreignSessions:R});let ee=!!s.daemon.tls;await d.listen({host:ee?"127.0.0.1":s.daemon.host,port:ee?0:s.daemon.port});let Oe=d.server.address(),Pt=Oe&&typeof Oe=="object"?Oe.port:s.daemon.port,Yn,yl=s.daemon.host,ki=Pt;if(ee&&n&&r){Yn=await Zw({listenHost:s.daemon.host,listenPort:s.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:Pt,tlsOptions:{key:n,cert:r},logger:d.log});let F=Yn.address();F&&typeof F=="object"&&(ki=F.port)}await Xe.mkdir(E.home(),{recursive:!0}),await _c({pid:process.pid,host:yl,port:ki,loopbackPort:Pt,startedAt:U});let vi={daemonUrl:`http://127.0.0.1:${Pt}`,daemonHost:"127.0.0.1",daemonPort:Pt,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${Pt}/acp`,hydraHome:E.home()};T.setContext(vi),M.setContext(vi),await T.start(),await M.start();try{await C.reconcilePermissionFlags()}catch(F){d.log.warn(`permission flag reconcile failed: ${F.message}`)}try{await C.seedSessionIndex()}catch(F){d.log.warn(`session index seed failed: ${F.message}`)}C.resurrectPendingQueues().catch(F=>{d.log.warn(`queue replay scan failed: ${F.message}`)}),C.resumePendingCompactions().catch(F=>{d.log.warn(`compaction resume scan failed: ${F.message}`)}),C.resumePendingAgentSwaps().catch(F=>{d.log.warn(`agent-swap resume scan failed: ${F.message}`)});let bi=s.daemon.agentSyncIntervalMinutes*60*1e3,Si=bi>0?Oc({registry:v,manager:C,intervalMs:bi,logger:S}):void 0,Ii=s.daemon.sessionGcIntervalMinutes*60*1e3,wl=s.daemon.sessionGcMaxAgeDays*24*60*60*1e3,Ai=Ii>0?Fc({manager:C,intervalMs:Ii,maxAgeMs:wl,logger:S}):void 0,kl=Lc({bootConfig:s,apply:F=>{t=F,v.setConfig(F),C.setLiveConfig({sessionDefaults:F.sessionDefaults}),Z.agentId=F.defaultAgent,Z.cwd=F.defaultCwd,_r(F.daemon.scrubEnv)},onDrift:F=>{j=F},logger:S});return{app:d,manager:C,registry:v,extensions:T,transformers:M,mcpTokenRegistry:W,extensionMcp:z,processRegistry:h,shutdown:async()=>{l.stop(),p.stop(),kl(),Ai&&Ai(),Si&&Si(),clearInterval(y),clearInterval(k);let F=async(Ae,cn)=>{try{await cn()}catch(un){d.log.warn(`shutdown step ${Ae} failed: ${un instanceof Error?un.message:String(un)}`)}};await F("sessionTokenStore.flush",()=>c.flush()),await F("extensions.stop",()=>T.stop()),await F("transformers.stop",()=>M.stop()),await F("manager.closeAll",()=>C.closeAll()),await F("manager.flushSynopsis",()=>C.flushSynopsis(3e4)),await F("manager.shutdownSynopsis",()=>C.shutdownSynopsis()),await F("manager.flushMetaWrites",()=>C.flushMetaWrites()),await F("manager.flushHistoryWrites",()=>C.flushHistoryWrites()),Hr(null),Ur(null),Zo(null),Yn&&await F("tlsTerminator.close",()=>new Promise(Ae=>Yn.close(()=>Ae()))),await F("app.close",()=>d.close());try{pl.unlinkSync(E.pidFile())}catch{}await F("fileStream.flushSync",()=>i.flushSync()),await F("fileStream.close",a)}}}var fl=20;async function Yw(s,e){let t=dn.dirname(s),n=dn.basename(s,".log"),r=new RegExp(`^${n}\\.(\\d+)\\.log$`),o;try{o=await Xe.readdir(t)}catch{return}let i=[];for(let d of o){let c=d.match(r);c&&i.push({name:d,n:Number(c[1])})}if(i.length<=e)return;i.sort((d,c)=>d.n-c.n);let a=i.slice(0,i.length-e);await Promise.allSettled(a.map(d=>Xe.unlink(dn.join(t,d.name))))}async function Xw(s){await Yw(E.logFile(),fl);let e=await Qw({file:E.logFile(),size:"10m",mkdir:!0,symlink:Us,limit:{count:fl,removeOtherLogFiles:!0}}),t=ll.destination(2),n=!1,r={write:a=>{n||e.write(a)}};return{stream:ll.multistream([{stream:r,level:s},{stream:t,level:s}]),fileStream:e,closeFile:()=>new Promise(a=>{n=!0,e.once("close",()=>a()),e.end()})}}async function Zw(s){let e=hl.createServer(s.tlsOptions,t=>{let n=gl.connect({host:s.upstreamHost,port:s.upstreamPort}),r=!1,o=i=>{if(!r){r=!0,i&&s.logger.warn(`tls terminator forwarder error: ${i.message??String(i)}`);try{t.destroy()}catch{}try{n.destroy()}catch{}}};t.on("error",o),n.on("error",o),t.on("close",()=>o()),n.on("close",()=>o()),t.pipe(n),n.pipe(t)});return e.on("tlsClientError",t=>{s.logger.warn(`tls handshake error: ${t.message}`)}),await new Promise((t,n)=>{let r=o=>{n(new Error(`TLS listener could not bind ${s.listenHost}:${s.listenPort}: ${o.message}`))};e.once("error",r),e.listen({host:s.listenHost,port:s.listenPort},()=>{e.off("error",r),t()})}),e.on("error",t=>{s.logger.warn(`tls terminator error: ${t.message}`)}),e}function ek(s){let e=s.daemon.host;if(!(e==="127.0.0.1"||e==="::1"||e==="localhost"||e==="[::1]")&&!s.daemon.tls)throw new Error(`Refusing to bind to non-loopback host ${e} without TLS configured.`)}async function tk(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:s}=await Promise.resolve().then(()=>(Gn(),Bu));s();let e=await pn(),t=await xi(),n=await ml(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
210
+ `),await l(C),C.exhausted){try{C.rl.close()}catch{}S.splice(b,1)}}}catch(b){for(let A of S)try{A.rl.close()}catch{}throw b}return f.raw.end(),f}),s.get("/v1/sessions/:id/events",async(p,f)=>{let h=p.params.id,w=p.query,m=await e.resolveCanonicalId(h)??h;if(!e.get(m)&&!await e.hasRecord(m))return f.code(404).send({error:"session not found"}),f;let y=w.kinds;if(!y||y.trim().length===0)return f.code(400).send({error:"kinds parameter is required"}),f;let k=y.split(",").map(R=>R.trim());if(k.length===0)return f.code(400).send({error:"kinds parameter is required"}),f;for(let R of k)if(!rr.has(R))return f.code(400).send({error:`kind "${R}" is not queryable; allowed kinds: ${[...rr].join(", ")}`}),f;let v=new Set(k),S;if(w.since!==void 0&&w.since.trim().length>0){let R=new Date(w.since);if(isNaN(R.getTime()))return f.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),f;S=R.getTime()}let b=E.historyFile(m),A=oi.createReadStream(b),C=ii.createInterface({input:A,crlfDelay:1/0});f.raw.setHeader("content-type","application/x-ndjson"),f.raw.statusCode=200;try{for await(let R of C){let T=typeof R=="string"?R.trim():"";if(T.length===0)continue;let M;try{M=JSON.parse(T)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",b);continue}if(!M||typeof M!="object"||Array.isArray(M)){console.debug("events endpoint: skipping non-object JSONL line in %s",b);continue}let H=M;if(typeof H.recordedAt!="number"||typeof H.params!="object"||H.params===null||Array.isArray(H.params))continue;let U=H.params;if(typeof U.update!="object"||U.update===null||Array.isArray(U.update))continue;let W=U.update,z=W.sessionUpdate;if(typeof z!="string"||!v.has(z)||S!==void 0&&H.recordedAt<S)continue;let D={ts:new Date(H.recordedAt).toISOString(),kind:z,update:W};W.messageId!==void 0&&W.messageId!==null&&(D.messageId=W.messageId),f.raw.write(JSON.stringify(D)+`
211
+ `)}}catch(R){if(R.code==="ENOENT")return f.raw.end(),f;throw R}return f.raw.end(),f}),s.post("/v1/sessions/:id/prompt/:messageId/notify",async(p,f)=>{let h=p.params,w=h.id,m=await e.resolveCanonicalId(w)??w,g=h.messageId,y=p.body,k=typeof y?.callbackUrl=="string"?y.callbackUrl:"",v=typeof y?.secret=="string"?y.secret:"";if(!g||!k||!v){f.code(400).send({error:"messageId, callbackUrl, and secret are all required"});return}let S;try{S=new URL(k)}catch{f.code(400).send({error:"callbackUrl must be a valid absolute URL"});return}if(S.protocol!=="https:"&&S.protocol!=="http:"){f.code(400).send({error:"callbackUrl must be http or https"});return}let b=e.get(m);if(!b){f.code(404).send({error:"session not found or not warm"});return}let A=b.registerTurnNotify(g,k,v);if(A.alreadyTerminal){f.code(200).send({status:"already_terminal",stopReason:A.stopReason});return}f.code(202).send({status:"registered"})}),s.get("/v1/sessions/:id/attention",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,m=e.get(w);return!m&&!await e.hasRecord(w)?(f.code(404).send({error:"session not found"}),f):m?{flags:m.listAttentionFlags()}:{flags:(await e.store.read(w))?.attentionFlags??[]}}),s.get("/v1/sessions/attention",async(p,f)=>{let h=p.query;if(!h.source||h.source.trim().length===0)return f.code(400).send({error:"source query parameter is required"}),f;let w=await e.list({includeNonInteractive:!0}),m=[];for(let g of w){let y=e.get(g.sessionId),k;y?k=y.listAttentionFlags():k=(await e.store.read(g.sessionId))?.attentionFlags??[];for(let v of k)v.source===h.source&&m.push({...v,sessionId:g.sessionId})}return{flags:m}}),s.post("/v1/sessions/:id/attention/clear",async(p,f)=>{let h=p.params.id,w=await e.resolveCanonicalId(h)??h,g=p.body??{},y=typeof g.source=="string"?g.source:"",k=typeof g.reason=="string"?g.reason:"";if((y.length>0||k.length>0)&&!(y.length>0&&k.length>0)){f.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}y.length===0&&k.length;let v=e.get(w);if(v){if(y.length>0&&k.length>0)v.clearAttentionFlag(y,k);else{let R=Array.from(v.listAttentionFlags()).map(T=>`${T.source}::${T.reason}`);for(let T of R)v.clearAttentionFlag(T.split("::")[0],T.split("::").slice(1).join("::"))}f.code(204).send();return}if(!await e.hasRecord(w)){f.code(404).send({error:"session not found"});return}let S=e.store,b=await S.read(w);if(!b){f.code(404).send({error:"session not found"});return}let A=b.attentionFlags??[],C;if(y.length>0&&k.length>0){let R=`${y}::${k}`;C=A.filter(T=>`${T.source}::${T.reason}`!==R)}else C=[];if(C.length===A.length&&C.every((R,T)=>R.source===A[T].source&&R.reason===A[T].reason)){f.code(204).send();return}await S.write({...b,attentionFlags:C}),f.code(204).send()})}function wu(s,e,t,n={}){s.get("/v1/agents",async()=>Dt(e)),s.get("/v1/registry",async()=>e.load()),s.post("/v1/registry/refresh",async()=>{let r=await e.refresh();return{version:r.version,agentCount:r.agents.length}}),s.post("/v1/agents/:id/install",async(r,o)=>{let i=r.params.id,a=await e.getAgent(i);if(!a){o.code(404).send({error:`agent ${i} not found in registry`});return}if(a.distribution.uvx&&!a.distribution.npx&&!a.distribution.binary){o.send({agentId:a.id,version:a.version??"current",distribution:"uvx",installed:!1,message:"uvx agents resolve on first run; nothing to pre-install."});return}try{let d=await Me(a,[],{npmRegistry:n.npmRegistry}),c=a.distribution.npx?"npx":a.distribution.binary?"binary":"unknown";o.send({agentId:a.id,version:d.version,distribution:c,installed:!0,command:d.command})}catch(d){o.code(500).send({error:d.message})}}),s.post("/v1/agents/:id/sync",async(r,o)=>{let i=r.params.id;try{let{synced:a,skipped:d}=await t.syncFromAgent(i);return{synced:a.map(c=>({sessionId:c.sessionId,upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,cwd:c.cwd,title:c.title,updatedAt:c.updatedAt})),skipped:d}}catch(a){let d=a;if(d.code===x.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}K();function ku(s,e,t,n=()=>[]){s.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t,home:E.home(),driftedKeys:n()}))}import*as Iu from"os";K();je();var zn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,ir=class s{data;constructor(e){this.data=e}static async load(){let e=await de(E.peers());return new s(Ty(e))}get(e){return this.data.entries[e]}async set(e){this.data.entries[e.name]=e,await vu(this.data)}async delete(e){return e in this.data.entries?(delete this.data.entries[e],await vu(this.data),!0):!1}list(){return Object.values(this.data.entries).map(({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})=>({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})).sort((e,t)=>e.addedAt.localeCompare(t.addedAt))}};function Ty(s){if(!s||typeof s!="object")return{version:1,entries:{}};let e=s,t=e.entries&&typeof e.entries=="object"?e.entries:{},n={};for(let[r,o]of Object.entries(t)){if(!o||typeof o!="object")continue;let i=o;if(typeof i.name!="string"||typeof i.host!="string"||typeof i.port!="number"||typeof i.token!="string"||typeof i.expiresAt!="string"||typeof i.addedAt!="string")continue;let a={name:i.name,host:i.host,port:i.port,token:i.token,expiresAt:i.expiresAt,addedAt:i.addedAt};typeof i.label=="string"&&(a.label=i.label),typeof i.pinnedFingerprint=="string"&&(a.pinnedFingerprint=i.pinnedFingerprint),typeof i.pinnedAt=="string"&&(a.pinnedAt=i.pinnedAt),n[r]=a}return{version:1,entries:n}}async function vu(s){await he(E.peers(),s,{mode:384})}var Py=3600*24*365,Qe=class extends Error{status;constructor(e,t){super(e),this.name="PeerLoginError",this.status=t}};function ar(s,e){return`${Ie(s)?"http":"https"}://${s}:${e}`}async function bu(s){let e=s.fetchImpl??fetch,t=`${s.host}:${s.port}`,n=ar(s.host,s.port),r;try{r=await e(`${n}/v1/auth/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:s.password,label:s.label,ttlSec:s.ttlSec??Py})})}catch(i){throw new Qe(`Could not reach ${t}: ${i.message}`,502)}if(r.status===401)throw new Qe(`Wrong password for ${t}.`,401);if(r.status===403)throw new Qe(`No password is configured on ${t}. Run \`hydra-acp auth password\` on that daemon first.`,502);if(r.status===429)throw new Qe(`Too many failed login attempts on ${t}; try again later.`,429);if(!r.ok)throw new Qe(`Login to ${t} failed: HTTP ${r.status}`,502);let o=await r.json();if(!o.session_token||!o.expires_at)throw new Qe(`Login to ${t} returned a malformed response.`,502);return{token:o.session_token,expiresAt:o.expires_at}}async function ai(s){let e=s.fetchImpl??fetch,t=ar(s.host,s.port);try{await e(`${t}/v1/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json"},body:JSON.stringify({})})}catch{}}function Au(s){return{machine:vt(),hydraVersion:ue,startedAt:s,os:{platform:process.platform,release:Iu.release(),arch:process.arch},node:process.version}}async function dr(s){let e=s.fetchImpl??fetch,t;try{t=await e(`${ar(s.host,s.port)}/v1/system`,{headers:{Authorization:`Bearer ${s.token}`},signal:s.signal})}catch(n){return{kind:"error",message:n.message}}if(t.status===401||t.status===403)return{kind:"unauthorized"};if(t.status===404)return{kind:"unsupported"};if(!t.ok)return{kind:"error",message:`HTTP ${t.status}`};try{let n=await t.json();return typeof n?.machine=="string"?{kind:"ok",system:n}:{kind:"ok"}}catch{return{kind:"ok"}}}function Su(s){return s!==void 0&&s.length<=64&&zn.test(s)}function Cu(s,e){if(Su(s))return s;if(/^[\d.]+$/.test(e)||e.includes(":"))return;let t=e.split(".")[0];return Su(t)?t:void 0}function Ru(s,e){s.get("/v1/system",async()=>Au(e))}var My=/^[A-Za-z0-9._-]+$/;function cr(s,e,t){let n=e==="extension"?"extensions":"transformers",r=`/v1/${n}`;s.get(r,async()=>({[n]:t.list()})),s.get(`${r}/:name`,async(o,i)=>{let a=o.params.name,d=t.get(a);if(!d){i.code(404).send({error:`unknown ${e}: ${a}`});return}return d}),s.post(r,async(o,i)=>{let a=o.body??{},d=_y(a);if("error"in d){i.code(400).send({error:d.error});return}try{let c=t.register(d.config);i.code(201).send(c)}catch(c){Jn(i,c)}}),s.delete(`${r}/:name`,async(o,i)=>{let a=o.params.name;try{await t.unregister(a),i.code(204).send()}catch(d){Jn(i,d)}}),s.post(`${r}/:name/start`,async(o,i)=>{let a=o.params.name;try{let d=await t.startByName(a);i.code(200).send(d)}catch(d){Jn(i,d)}}),s.post(`${r}/:name/stop`,async(o,i)=>{let a=o.params.name;try{let d=await t.stopByName(a);i.code(200).send(d)}catch(d){Jn(i,d)}}),s.post(`${r}/:name/restart`,async(o,i)=>{let a=o.params.name;try{let d=await t.restartByName(a);i.code(200).send(d)}catch(d){Jn(i,d)}})}function Jn(s,e){let t=e.code,n=e.message??"unknown error";if(t==="NOT_FOUND"){s.code(404).send({error:n});return}if(t==="CONFLICT"){s.code(409).send({error:n});return}s.code(500).send({error:n})}function _y(s){let e=s.name;if(typeof e!="string"||!My.test(e))return{error:"name must match [A-Za-z0-9._-]+"};let t=s.command;if(t!==void 0&&(!Array.isArray(t)||t.some(i=>typeof i!="string")))return{error:"command must be string[]"};let n=s.args;if(n!==void 0&&(!Array.isArray(n)||n.some(i=>typeof i!="string")))return{error:"args must be string[]"};let r=s.env;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))return{error:"env must be an object of string\u2192string"};if(r&&Object.values(r).some(i=>typeof i!="string"))return{error:"env values must be strings"};let o=s.enabled;return o!==void 0&&typeof o!="boolean"?{error:"enabled must be a boolean"}:{config:{name:e,command:t??[],args:n??[],env:r??{},enabled:o===void 0?!0:o}}}function xu(s,e){cr(s,"extension",e)}function Eu(s,e){cr(s,"transformer",e)}function Tu(s,e){s.get("/v1/config",async()=>e())}import{z as mt}from"zod";K();import*as rn from"fs/promises";import*as Pu from"path";import{randomBytes as YC,scrypt as $y,timingSafeEqual as Oy}from"crypto";import{promisify as Fy}from"util";var Ny=Fy($y);function Mu(){return Pu.join(E.home(),"password-hash")}var Dy=128*1024*1024;async function _u(){try{return(await rn.readFile(Mu(),"utf8")).trim().length>0}catch(s){if(s.code==="ENOENT")return!1;throw s}}async function $u(s){if(typeof s!="string"||s.length===0)return!1;let e;try{e=(await rn.readFile(Mu(),"utf8")).trim()}catch(c){if(c.code==="ENOENT")return!1;throw c}let t=e.split("$");if(t.length!==6||t[0]!=="scrypt")return!1;let n=parseInt(t[1],10),r=parseInt(t[2],10),o=parseInt(t[3],10);if(!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o))return!1;let i=Buffer.from(t[4],"hex"),a=Buffer.from(t[5],"hex");if(i.length===0||a.length===0)return!1;let d=await Ny(s,i,a.length,{N:n,r,p:o,maxmem:Dy});return d.length!==a.length?!1:Oy(d,a)}var jy=mt.object({password:mt.string().min(1),label:mt.string().min(1).max(256).optional(),ttlSec:mt.number().int().positive().optional()}),Hy=mt.object({id:mt.string().optional()}).optional(),Ly=mt.object({token:mt.string().min(32)});function Ou(s,e){s.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,n)=>{let r=Uy(t);if(e.rateLimiter.isBlocked(r))return n.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=jy.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}if(!await _u())return n.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await $u(o.password))return e.rateLimiter.recordFailure(r),n.code(401).send({error:"Invalid password"});e.rateLimiter.recordSuccess(r);let a=await e.store.issue({label:o.label,ttlSec:o.ttlSec});return n.code(200).send({session_token:a.token,id:a.id,expires_at:a.expiresAt})}),s.post("/v1/auth/logout",async(t,n)=>{let r;try{r=Hy.parse(t.body??void 0)}catch{return n.code(400).send({error:"Invalid request body"})}let o=r?.id??t.authIdentity;if(!o||o==="service")return n.code(200).send({revoked:!1});let i=await e.store.revoke(o);return n.code(200).send({revoked:i})}),s.get("/v1/auth/verify",async(t,n)=>n.code(200).send({ok:!0})),s.get("/v1/auth/sessions",async(t,n)=>n.code(200).send({sessions:e.store.list()})),s.delete("/v1/auth/sessions",async(t,n)=>{let r=await e.store.revokeAll();return n.code(200).send({revoked:r})}),s.delete("/v1/auth/sessions/:id",async(t,n)=>{let r=t.params.id;return await e.store.revoke(r)?n.code(204).send():n.code(404).send({error:"Not found"})}),s.post("/v1/auth/rotate-token",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=Ly.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}return e.staticTokenValidator.rotate(r.token),n.code(200).send({rotated:!0})})}function Uy(s){return s.ip||"unknown"}import{z as yt}from"zod";Gn();var Zy=yt.object({name:yt.string().min(1).max(64).regex(zn).optional(),host:yt.string().min(1),port:yt.number().int().positive().optional(),password:yt.string().min(1),label:yt.string().min(1).max(256).optional(),ttlSec:yt.number().int().positive().optional(),pinnedFingerprint:yt.string().min(1).optional()});function Wu(s,e){s.post("/v1/remotes",async(t,n)=>{let r;try{r=Zy.parse(t.body)}catch{return n.code(400).send({error:`Invalid request body (name must match ${zn} and the rest is a normal login request)`})}let o=r.port??_t;r.pinnedFingerprint&&Vn(r.host,o,r.pinnedFingerprint);let i;try{i=await bu({host:r.host,port:o,password:r.password,label:r.label,ttlSec:r.ttlSec})}catch(p){if(p instanceof Qe)return n.code(p.status).send({error:p.message});throw p}let a=await dr({host:r.host,port:o,token:i.token}),d=a.kind==="ok"?a.system:void 0,c=r.name;if(c===void 0){c=Cu(d?.machine,r.host);let p=c!==void 0?e.store.get(c):void 0,f=p!==void 0&&(p.host!==r.host||p.port!==o);if(c===void 0||f){await ai({host:r.host,port:o,token:i.token});let h=c===void 0?`Couldn't derive a remote name for ${r.host}`:`A remote named ${c} already points at ${p.host}:${p.port}`;return n.code(c===void 0?400:409).send({error:`${h}. Pass a name: hydra-acp remote add <name> ${r.host}`})}}let u=new Date().toISOString(),l={name:c,host:r.host,port:o,token:i.token,expiresAt:i.expiresAt,addedAt:u,...r.label!==void 0?{label:r.label}:{},...r.pinnedFingerprint!==void 0?{pinnedFingerprint:r.pinnedFingerprint,pinnedAt:u}:{}};return await e.store.set(l),e.health?.markOk(l.name,d),n.code(201).send({name:l.name,host:l.host,port:l.port,expiresAt:l.expiresAt,label:l.label,addedAt:l.addedAt,pinnedFingerprint:l.pinnedFingerprint,status:e.health?.get(l.name)?.status??"unknown"})}),s.get("/v1/remotes",async(t,n)=>{let r=e.store.list().map(o=>{let i=e.health?.get(o.name);return{...o,status:i?.status??"unknown",...i?.checkedAt?{lastCheckedAt:i.checkedAt}:{},...i?.system?{system:i.system}:{}}});return n.code(200).send({remotes:r})}),s.get("/v1/remotes/:name/agents",async(t,n)=>{let r=e.store.get(t.params.name);if(!r)return n.code(404).send({error:"Not found"});let i=`${Ie(r.host)?"http":"https"}://${r.host}:${r.port}`,a={Authorization:`Bearer ${r.token}`};try{let[d,c]=await Promise.all([fetch(`${i}/v1/agents`,{headers:a}),fetch(`${i}/v1/config`,{headers:a}).catch(()=>null)]);if(!d.ok)return n.code(d.status).header("content-type","application/json").send(await d.text());let u=await d.json(),l={};if(c?.ok){let p=await c.json();l={defaultAgent:p.defaultAgent,sessionDefaults:p.sessionDefaults}}return n.code(200).send({...u,...l})}catch(d){return n.code(502).send({error:`Could not reach remote "${r.name}": ${d.message}`})}}),s.delete("/v1/remotes/:name",async(t,n)=>{let r=t.params.name,o=e.store.get(r);return o?(await ai({host:o.host,port:o.port,token:o.token}),await e.store.delete(r),e.health?.forget(r),e.store.list().some(a=>a.host===o.host&&a.port===o.port)||ci(o.host,o.port),n.code(204).send()):n.code(404).send({error:"Not found"})})}function lr(s){let e=[],t=[],n=!1,r=o=>{if(!n){n=!0;for(let i of t)i(o)}};return s.on("message",(o,i)=>{if(i)return;let a=o.toString("utf8");try{let d=JSON.parse(a);for(let c of e)c(d)}catch(d){for(let c of e)c({jsonrpc:"2.0",id:null,error:{code:x.ParseError,message:`Failed to parse WS frame: ${d.message}`}})}}),s.on("close",()=>r()),s.on("error",o=>r(o)),{async send(o){if(n)throw new Error("ws is closed");let i=JSON.stringify(o);await new Promise((a,d)=>{s.send(i,c=>{if(c){d(c);return}a()})})},onMessage(o){e.push(o)},onClose(o){t.push(o)},async close(){n||(await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,clearTimeout(d),o())},d=setTimeout(a,5e3);s.once("close",a);try{s.close()}catch{a()}}),r())}}}Gn();import{WebSocket as ew}from"ws";var tw=1e4,gi=class extends Error{url;elapsedMs;constructor(e,t){super(`hydra-acp: websocket connect to ${e} timed out after ${t}ms`),this.name="WsConnectTimeoutError",this.url=e,this.elapsedMs=t}};async function qu(s,e,t=tw){let n={};try{let r=new URL(s);if(r.protocol==="wss:"){let o=pi(r.hostname);o.rejectUnauthorized!==void 0&&(n.rejectUnauthorized=o.rejectUnauthorized),o.autoSelectFamily!==void 0&&(n.autoSelectFamily=o.autoSelectFamily),o.checkServerIdentity!==void 0&&(n.checkServerIdentity=o.checkServerIdentity)}}catch{}return new Promise((r,o)=>{let i=new ew(s,e,n),a=Date.now(),d=setTimeout(()=>{i.off("open",c),i.off("error",u),i.on("error",()=>{});try{i.terminate()}catch{}o(new gi(s,Date.now()-a))},t),c=()=>{clearTimeout(d),i.off("error",u),r(i)},u=l=>{clearTimeout(d),i.off("open",c),o(l)};i.once("open",c),i.once("error",u)})}var nw=new Set(["session/attach","session/detach","session/prompt","session/cancel","session/close","session/delete","hydra-acp/session/delete","session/set_model","session/set_mode","session/set_config_option","_session/steering","hydra-acp/prompt/cancel","hydra-acp/prompt/update","hydra-acp/prompt/amend","hydra-acp/session/tool_content","hydra-acp/session/force_cancel"]);function sw(s){return nw.has(s)}function Ju(s,e,t,n){let r=[],o=a=>{for(let d of r)d(a)},i=(a,d)=>{e.handleLocalMessage(a,d,{connection:t.connection,clientId:n}).then(c=>c?s.send(c):void 0).catch(()=>{})};return s.onMessage(a=>{if("method"in a&&sw(a.method)){let d=a.params,c=typeof d?.sessionId=="string"?d.sessionId:void 0;if(c){if(ft(c)){i(a,c);return}if(a.method==="session/attach"){let u="id"in a;e.resolveLocalMiss(c).then(l=>{if(l.ok){i(a,l.foreignId);return}if(l.ambiguous&&u){s.send(Kn(a.id,x.SessionNotFound,`Session "${c}" exists on more than one remote (${l.ambiguous.join(", ")}). Address it as "<remote>:${c}".`));return}o(a)});return}}}o(a)}),{send:a=>s.send(a),onMessage:a=>r.push(a),onClose:a=>s.onClose(a),close:()=>s.close()}}var fr=class{constructor(e,t=ow,n){this.store=e;this.dial=t;this.localMiss=n}store;dial;localMiss;attachments=new Map;async resolveLocalMiss(e){if(!this.localMiss)return{ok:!1};if(await this.localMiss.resolvesLocally(e))return{ok:!1};let t=this.localMiss.cache.findByLocalId(e);return t.length===0?{ok:!1}:t.length>1?{ok:!1,ambiguous:t.map(n=>n.name)}:{ok:!0,foreignId:Je(t[0])}}async handleLocalMessage(e,t,n){let r="id"in e,o=r?e.id:void 0,i=ft(t);if(!i)return r?Kn(o,x.SessionNotFound,`not a federated session id: ${t}`):void 0;let a=zu(n.clientId,t),d={...e.params,sessionId:i.localId};if(e.method==="session/attach"){let u=this.store.get(i.name);if(!u)return r?Kn(o,x.SessionNotFound,`No remote named "${i.name}". Run \`hydra remote add\` first.`):void 0;let l=this.attachments.get(a);l&&(this.attachments.delete(a),l.peerConnection.close().catch(()=>{}));let p;try{p=await this.dial(u)}catch(m){return r?Kn(o,x.InternalError,`Could not reach remote "${i.name}": ${m.message}`):void 0}let f={peerConnection:p,localId:i.localId,target:n};this.wireAttachment(i.name,f);let h;try{h=await p.request("session/attach",d)}catch(m){return p.close().catch(()=>{}),r?hi(o,m):void 0}this.attachments.set(a,f);let w=h&&typeof h.sessionId=="string"?{...h,sessionId:t}:h;return r?{jsonrpc:"2.0",id:o,result:w}:void 0}let c=this.attachments.get(a);if(!c)return r?Kn(o,x.SessionNotFound,`"${t}" is not attached through this daemon.`):void 0;if(e.method==="session/detach"){let u,l;try{u=await c.peerConnection.request("session/detach",d)}catch(p){l=p}return this.attachments.delete(a),c.peerConnection.close().catch(()=>{}),l?r?hi(o,l):void 0:r?{jsonrpc:"2.0",id:o,result:u??{}}:void 0}if(r)try{let u=await c.peerConnection.request(e.method,d);return{jsonrpc:"2.0",id:o,result:u}}catch(u){return hi(o,u)}await c.peerConnection.notify(e.method,d).catch(()=>{})}detachClient(e){for(let[t,n]of[...this.attachments.entries()])n.target.clientId===e&&(this.attachments.delete(t),n.peerConnection.request("session/detach",{sessionId:n.localId}).catch(()=>{}),n.peerConnection.close().catch(()=>{}))}wireAttachment(e,t){let{peerConnection:n,localId:r,target:o}=t,i=Je({name:e,localId:r}),a=()=>{this.attachments.delete(zu(o.clientId,i))};n.onAnyNotification((d,c)=>{let u=d;!u||u.sessionId!==r||(c==="hydra-acp/session/closed"&&a(),o.connection.notify(c,{...u,sessionId:i}).catch(()=>{}))}),n.onRequest("hydra-acp/session/request_permission",async d=>{let c=d;if(!c||c.sessionId!==r)throw{code:x.MethodNotFound,message:"unexpected sessionId"};return o.connection.request("hydra-acp/session/request_permission",{...c,sessionId:i})}),n.onClose(()=>{a(),o.connection.notify("hydra-acp/session/closed",{sessionId:i}).catch(()=>{})})}};function zu(s,e){return`${s} ${e}`}function Kn(s,e,t){return{jsonrpc:"2.0",id:s,error:{code:e,message:t}}}function hi(s,e){let t=e,n=typeof t?.code=="number"?t.code:x.InternalError,r=typeof t?.message=="string"?t.message:String(e??"forward failed");return{jsonrpc:"2.0",id:s,error:{code:n,message:r,...t?.data!==void 0?{data:t.data}:{}}}}var rw=1e4;async function ow(s){let t=`${Ie(s.host)?"ws":"wss"}://${s.host}:${s.port}/acp`,n=await qu(t,["acp.v1",`hydra-acp-token.${s.token}`],rw);return new qe(lr(n))}var iw=3e4,aw=5e3,pr=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;snapshots=new Map;timer;start(){this.timer||(this.checkAll(),this.timer=setInterval(()=>{this.checkAll()},this.opts.intervalMs??iw),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}get(e){return this.snapshots.get(e)}markOk(e,t){this.snapshots.set(e,{status:"ok",checkedAt:new Date().toISOString(),...t?{system:t}:{}})}forget(e){this.snapshots.delete(e)}async checkAll(){let e=this.opts.fetchImpl??fetch;await Promise.allSettled(this.store.list().map(async t=>{let n=this.store.get(t.name);if(!n)return;let r=new AbortController,o=setTimeout(()=>r.abort(),aw);try{let i=await dr({host:n.host,port:n.port,token:n.token,fetchImpl:e,signal:r.signal});if(i.kind==="ok"){this.snapshots.set(t.name,{status:"ok",checkedAt:new Date().toISOString(),...i.system?{system:i.system}:{}});return}if(i.kind==="unauthorized"){this.snapshots.set(t.name,{status:"unauthorized",checkedAt:new Date().toISOString()});return}if(i.kind==="error")throw new Error(i.message);let d=`${Ie(n.host)?"http":"https"}://${n.host}:${n.port}/v1/auth/verify`,c=await e(d,{headers:{Authorization:`Bearer ${n.token}`},signal:r.signal});this.snapshots.set(t.name,{status:c.ok?"ok":"unauthorized",checkedAt:new Date().toISOString()})}catch(i){this.snapshots.set(t.name,{status:"unreachable",checkedAt:new Date().toISOString(),error:i.message})}finally{clearTimeout(o)}}))}};Gn();import{z as Vu}from"zod";var dw=Vu.object({sessionLabel:Vu.string().min(1).max(256)});function Gu(s,e){s.post("/v1/process-tokens",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=dw.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}let o=e.processRegistry.mint(r.sessionLabel,"script");return n.code(201).send({token:o})}),s.delete("/v1/process-tokens/:sessionLabel",async(t,n)=>t.authIdentity!=="service"?n.code(403).send({error:"Requires the service token"}):(e.processRegistry.revoke(t.params.sessionLabel),n.code(204).send()))}import{nanoid as mi}from"nanoid";import{randomBytes as Zu}from"crypto";import*as el from"os";import*as tl from"path";var cw=200;function uw(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[le];if(!t||typeof t!="object"||Array.isArray(t))return;let n=t.sentBy;if(!n||typeof n!="object"||Array.isArray(n))return;let r=n,o={};if(typeof r.sessionId=="string"&&r.sessionId.length>0&&(o.sessionId=r.sessionId),typeof r.label=="string"&&r.label.length>0&&(o.label=r.label.slice(0,cw)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function Ku(s,e,t){let n=uw(s);if(!n)return;let r={};if(n.label!==void 0&&(r.fromLabel=n.label),n.awaiting===!0&&(r.awaiting=!0),n.sessionId!==void 0){let o=await e.resolveCanonicalId(n.sessionId)??n.sessionId,i=await e.getOne(o);if(i){r.fromSession=o,i.title&&(r.fromSessionTitle=i.title);let a=e.get(o)?.currentPromptDepth;r.depth=(a??0)+1}else t?.(n.sessionId)}if(!(r.fromSession===void 0&&r.fromLabel===void 0))return r}var Qn=new Map;function Qu(s,e){let t=Qn.get(s);t||(t=new Set,Qn.set(s,t)),t.add(e);let n=!1;return()=>{if(n)return;n=!0;let r=Qn.get(s);r&&(r.delete(e),r.size===0&&Qn.delete(s))}}function Yu(s,e){if(s===e)return!0;let t=new Set,n=[e];for(;n.length>0;){let r=n.pop();if(t.has(r))continue;t.add(r);let o=Qn.get(r);if(o){if(o.has(s))return!0;for(let i of o)n.push(i)}}return!1}function O(s,e,t){let n=new Error(e);return n.code=s,t!==void 0&&(n.data=t),n}function hw(s){if(!s||typeof s!="object")return 512;let n=s.params?.update;if(!n)return 512;let r=512,o=n.content;if(typeof o=="string")r+=o.length;else if(o&&typeof o=="object"){let a=o;typeof a.text=="string"&&(r+=a.text.length),typeof a.data=="string"&&(r+=a.data.length)}let i=n.toolCall;if(i&&(typeof i.rawInput=="string"?r+=i.rawInput.length:i.rawInput&&typeof i.rawInput=="object"&&(r+=256),typeof i.rawOutput=="string"?r+=i.rawOutput.length:i.rawOutput&&typeof i.rawOutput=="object"&&(r+=256),Array.isArray(i.content)))for(let a of i.content){if(!a||typeof a!="object")continue;let d=a;if(typeof d.text=="string"&&(r+=d.text.length),d.content&&typeof d.content=="object"){let c=d.content;typeof c.text=="string"&&(r+=c.text.length)}}return r}function Te(s,e,t){let n=s.get(e);if(!n)throw O(x.SessionNotFound,t??`session ${e} not found`);return n}async function Tt(s,e){let t=sn(s),n,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&s.mcpTokenRegistry!==void 0&&s.getDaemonOrigin!==void 0&&(n=Zu(32).toString("hex"),r=s.mcpTokenRegistry.reserve(n),o={name:"hydra-acp-recall",type:"http",url:`${s.getDaemonOrigin()}/mcp/hydra-acp-recall`,headers:[{name:"Authorization",value:`Bearer ${n}`}]});let a=[...t?.descriptors??[],...o!==void 0?[o]:[]],d=ri({baselineMcpServers:void 0,stdinEnabled:!1,deps:s}),c;try{c=await s.manager.resurrect({...e,mcpServers:a,...d?{mintMcpServersForSwap:d}:{}})}catch(u){throw t!==void 0&&t.abandon(u instanceof Error?u:void 0),r!==void 0&&r.abandon(u instanceof Error?u:void 0),u}if(t!==void 0&&t.bindToSession(c),n!==void 0&&r!==void 0&&s.mcpTokenRegistry!==void 0){let u=n,l=s.mcpTokenRegistry;r.complete(c),c.onClose(()=>{l.unbind(u)})}return Cw(c,s),sl(c.sessionId,s),c}function nl(s,e){s.get("/acp",{websocket:!0},async(t,n)=>{let r=Gc({headers:n.headers,url:n.url});if(!r||!await e.validator.validate(r)){t.close(4401,"Unauthorized");return}let o=e.processRegistry?.resolve(r),i=`hydra_client_${mi(12)}`,a=lr(t),d={},c=e.foreignSessions?Ju(a,e.foreignSessions,d,i):a,u=new qe(c);d.connection=u;let l={clientId:i,processIdentity:o,attached:new Map};u.setParamsRewriter(m=>{if(m===null||typeof m!="object")return m;let g=m.sessionId;if(typeof g!="string"||l.attached.has(g))return m;let y=ye+g;return l.attached.has(y)?{...m,sessionId:y}:m}),u.onClose(()=>{for(let m of l.attached.values())e.manager.get(m.sessionId)?.detach(m.clientId);l.attached.clear(),e.foreignSessions?.detachClient(i)});let p=(m,g)=>{if(l.attached.get(m)?.readonly)throw O(x.PermissionDenied,`${g} not permitted on a read-only attachment`)};if(u.onRequest("initialize",async m=>{let g=pa.parse(m??{});g.clientInfo?.name&&(l.clientInfo={name:g.clientInfo.name,...g.clientInfo.version!==void 0?{version:g.clientInfo.version}:{}});let y=g.clientInfo?.version;return y&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,y):e.onTransformerVersion?.(o.name,y)),Aw()}),o&&e.extensionCommands){let m=e.extensionCommands;u.onRequest("hydra-acp/commands/register",async g=>{let y=g??{},k=Array.isArray(y.commands)?y.commands.map(v=>{if(!v||typeof v!="object")return;let S=v;if(typeof S.verb!="string")return;let b={verb:S.verb};return typeof S.argsHint=="string"&&(b.argsHint=S.argsHint),typeof S.description=="string"&&(b.description=S.description),b}).filter(v=>v!==void 0):[];return m.register(o.name,u,k),{ok:!0,registered:k.length}}),u.onClose(()=>{m.clear(o.name)})}if(o&&e.extensionMcp){let m=e.extensionMcp;u.onRequest("hydra-acp/mcp_tools/register",async y=>{let k=y??{},v=typeof k.instructions=="string"?k.instructions:void 0,S=Array.isArray(k.tools)?k.tools.map(b=>{if(!b||typeof b!="object")return;let A=b;if(typeof A.name!="string"||A.name.length===0||typeof A.description!="string"||A.inputSchema===null||typeof A.inputSchema!="object")return;let C={name:A.name,description:A.description,inputSchema:A.inputSchema};return A.outputSchema!==null&&typeof A.outputSchema=="object"&&(C.outputSchema=A.outputSchema),C}).filter(b=>b!==void 0):[];if(S.length===0)throw new Error("register_mcp_tools requires at least one tool");return m.register(o.name,u,v,S),{ok:!0,registered:S.length}});let g=y=>{let k=y??{};if(typeof k.sessionId!="string"||k.sessionId.length===0)throw O(x.InvalidParams,"sessionId is required");return k.sessionId};if(u.onRequest("hydra-acp/session/extension_state/get",async y=>{let k=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(!e.manager)throw O(x.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(k,o.name,v.key)??null}}),u.onRequest("hydra-acp/session/extension_state/list",async y=>{let k=g(y);if(!e.manager)throw O(x.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(k,o.name)}}),u.onRequest("hydra-acp/session/extension_state/set",async y=>{let k=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(v.value===void 0)throw O(x.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw O(x.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(k,o.name,v.key,v.value)}catch(S){throw O(x.InvalidParams,S.message)}return{ok:!0}}),u.onRequest("hydra-acp/session/extension_state/delete",async y=>{let k=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(!e.manager)throw O(x.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(k,o.name,v.key),{ok:!0}}),e.extensionMcpControls){let y=e.extensionMcpControls;u.onRequest("hydra-acp/mcp_tools/refresh_session",async k=>{let v=k??{};if(typeof v.sessionId!="string"||v.sessionId.length===0)throw O(x.InvalidParams,"refresh_session requires sessionId");return await y.notifyToolListChanged(v.sessionId,o.name),{ok:!0}})}u.onClose(()=>{m.clear(o.name)})}o?.kind==="transformer"&&(u.onRequest("hydra-acp/transformer/initialize",async m=>{let g=m??{},y=Array.isArray(g.intercepts)?g.intercepts.filter(k=>typeof k=="string"):[];if(e.transformers&&(e.transformers.registerConnection(o.name,u,y),e.manager?.defaultTransformers.includes(o.name))){let k=e.transformers.resolveChain([o.name])[0];if(k)for(let v of e.manager.liveSessions())v.addTransformer(k)}return{ack:!0}}),u.onClose(()=>{e.transformers?.deregisterConnection(o.name)}),u.onRequest("hydra-acp/message/emit",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0,k=typeof g.method=="string"?g.method:void 0,v=g.envelope,S=g.route;if(!y)throw O(-32602,"emit_message requires sessionId");if(!k&&S!=="client_broadcast")throw O(-32602,"emit_message requires method");let b=Te(e.manager,y),A=typeof g.respondsTo=="string"?g.respondsTo:void 0;if(A)return b.dischargeClaim(A,v),{ok:!0};if(S==="chain")return{ok:!0,response:await b.emitToChain(o.name,k,v)};if(S==="queue"){if(k!=="session/prompt")throw O(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await b.emitToQueue(o.name,v)}}if(S==="daemon")return{ok:!0,response:await b.emitToChain(o.name,k,v)};if(S==="client_broadcast"){if(!v||typeof v!="object")throw O(-32602,"client_broadcast requires an envelope object");return b.broadcastClientUpdate(v),{ok:!0}}throw O(-32602,`unsupported route: ${JSON.stringify(S)}`)}),u.onRequest("hydra-acp/session/request_permission",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw O(-32602,"hydra-acp/session/request_permission requires sessionId");return Te(e.manager,y).requestPermissionFromClients(g)}),u.onRequest("hydra-acp/transformer/attach",async m=>vw(m,o.name,e)),u.onRequest("hydra-acp/child_session/spawn",async m=>{let g=m??{},y=typeof g.agentId=="string"?g.agentId:void 0,k=typeof g.cwd=="string"?g.cwd:void 0,v=typeof g.parentSessionId=="string"?g.parentSessionId:void 0,S=it(g._meta??void 0),b=S.title,A=S.model,C=S.workspace;if(!k&&v){let D=e.manager.get(v);D&&(k=D.cwd)}if(!k)throw O(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let R=await fn(k),T=y??R.agentId??e.defaultAgent,M=await e.registry?.getAgent(T),H=qr(R.configDefaults,M??{id:T})?.value,U=A??H?.model,W=typeof g.interactive=="boolean"?g.interactive:!1,z=await e.manager.create({agentId:T,cwd:k,parentSessionId:v,interactive:W,transformChain:[],title:b,model:U,configDefaults:H,...C!==void 0?{workspace:C}:{}});return{childSessionId:z.sessionId,...z.workspace!==void 0||z.workspaceError!==void 0?{_meta:{[le]:{...z.workspace!==void 0?{workspaceInfo:z.workspace}:{},...z.workspaceError!==void 0?{workspaceError:z.workspaceError}:{}}}}:{}}}));let f=async(m,g)=>{let y=m??{};if(typeof y.sessionId!="string")throw O(x.InvalidParams,"fork_session requires sessionId");let k=typeof y.forkAt=="string"?y.forkAt:void 0,v=typeof y.cwd=="string"?y.cwd:void 0,S=typeof y.agentId=="string"?y.agentId:void 0,b=g?void 0:typeof y.mode=="string"&&(y.mode==="verbatim"||y.mode==="synthesis")?y.mode:void 0,A=typeof y.model=="string"&&y.model.length>0?y.model:void 0,C;if(g){let U=y.selection;if(U!==void 0&&(typeof U.text!="string"||U.text.length===0))throw O(x.InvalidParams,"selection.text must be a non-empty string");C={...U!==void 0?{selection:{text:U.text,...typeof U.responsePartId=="string"?{responsePartId:U.responsePartId}:{}}}:{}}}let R=await e.manager.forkSession(y.sessionId,{...C!==void 0?{side:C}:{},...k!==void 0?{forkAt:k}:{},...v!==void 0?{cwd:v}:{},...S!==void 0?{agentId:S}:{},...b!==void 0?{mode:b}:{},...A!==void 0?{model:A}:{}}),T=e.manager.get(R.sessionId);if(!T){let U=await e.manager.loadFromDisk(R.sessionId);if(!U)throw O(x.InternalError,`fork ${R.sessionId} vanished before it could be attached`);T=await Tt(e,{...U,onInstallProgress:gr(u)})}on(l,T,T.sessionId);let M=wt(u,T,l),{entries:H}=await T.attach(M,"full");l.attached.set(T.sessionId,{sessionId:T.sessionId,clientId:M.clientId,readonly:!1});for(let U of H){if(u.isClosed())break;await u.notify(U.method,We(Be(U.params,U.recordedAt),U.seq)).catch(()=>{})}return{...R,sessionId:T.sessionId}};u.onRequest("hydra-acp/session/fork",m=>f(m,!1)),u.onRequest("hydra-acp/session/side",m=>f(m,!0)),u.onRequest("hydra-acp/session/rewind",async m=>{let g=m??{};if(typeof g.sessionId!="string")throw O(x.InvalidParams,"hydra-acp/session/rewind requires sessionId");let y=g.keepThrough;if(y!==null&&(typeof y!="string"||y.length===0))throw O(x.InvalidParams,"keepThrough must be a non-empty messageId, or null to drop every turn");let k=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId;try{return await e.manager.rewindSession(k,y)}catch(v){let S=v;throw O(S.code??x.InternalError,S.message)}}),u.onRequest("session/fork",async m=>{let g=m??{};if(typeof g.sessionId!="string")throw O(x.InvalidParams,"session/fork requires sessionId");let y=typeof g.cwd=="string"?g.cwd:void 0,k=await e.manager.forkSession(g.sessionId,{...y!==void 0?{cwd:y}:{},mode:"verbatim"}),v=e.manager.get(k.sessionId);if(!v){let A=await e.manager.loadFromDisk(k.sessionId);if(!A)throw O(x.InternalError,`fork ${k.sessionId} vanished before it could be attached`);v=await Tt(e,{...A,onInstallProgress:gr(u)})}on(l,v,v.sessionId);let S=wt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let A of b){if(u.isClosed())break;await u.notify(A.method,We(Be(A.params,A.recordedAt),A.seq)).catch(()=>{})}return{sessionId:v.sessionId}});let h=async(m,g)=>{let y=m??{};if(typeof y.sessionId!="string")throw O(x.InvalidParams,`${g} requires sessionId`);let k=await e.manager.resolveCanonicalId(y.sessionId)??y.sessionId,v=e.manager.get(k);if(v)return await v.close({deleteRecord:!0,by:`session/delete ${l.clientId}`}),await e.manager.waitForDeletion(k),await e.manager.hasRecord(k)&&await e.manager.deleteRecord(k),{id:k,existed:!0};let S=await e.manager.deleteRecord(k);return{id:k,existed:S}};u.onRequest("session/delete",async m=>(await h(m,"session/delete"),{})),u.onRequest("session/close",async m=>{let g=m??{};if(typeof g.sessionId!="string")throw O(x.InvalidParams,"session/close requires sessionId");p(g.sessionId,"session/close");let y=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,k=e.manager.get(y);if(k)return await k.close({deleteRecord:!1,by:`session/close ${l.clientId}`+(l.processIdentity?` (${l.processIdentity.name})`:"")}),{};if(await e.manager.hasRecord(y))return{};throw O(x.SessionNotFound,`session ${y} not found`)}),u.onRequest("hydra-acp/session/delete",async m=>{let{id:g,existed:y}=await h(m,"hydra-acp/session/delete");if(!y)throw O(x.SessionNotFound,`session ${g} not found`);return{deleted:!0,sessionId:g}}),o?.kind==="transformer"&&(u.onRequest("hydra-acp/child_session/await",async m=>{let g=m??{},y=typeof g.childSessionId=="string"?g.childSessionId:void 0,k=g.until==="idle"?"idle":"turn_complete",v=typeof g.timeoutMs=="number"?Math.min(g.timeoutMs,18e5):3e5;if(!y)throw O(-32602,"await_child requires childSessionId");let S=Te(e.manager,y,`child session ${y} not found`);return new Promise(b=>{let R=[],T=[],M=0,H=!1,U,W,z=!1,D=()=>{z||(z=!0,clearTimeout(te),U?.(),W?.(),b(H?{entries:R,truncated:!0}:{entries:R}))};U=S.onBroadcast(Z=>{let oe=hw(Z);for(R.push(Z),T.push(oe),M+=oe;R.length>0&&(R.length>1e3||M>1048576);)R.shift(),M-=T.shift()??0,H=!0;k==="turn_complete"&&Z.params?.update?.sessionUpdate==="turn_complete"&&D()});let te=setTimeout(D,v);typeof te.unref=="function"&&te.unref(),W=S.onClose(()=>D())})}),u.onRequest("hydra-acp/child_session/close",async m=>{let g=m??{},y=typeof g.childSessionId=="string"?g.childSessionId:void 0;if(!y)throw O(-32602,"close_child_session requires childSessionId");let k=e.manager.get(y);return k&&await k.close({deleteRecord:!1,by:`child_session/close ${l.clientId}`}),{ok:!0}}),u.onRequest("hydra-acp/attention/set",async m=>bw(m,o.name,e)),u.onRequest("hydra-acp/attention/clear",async m=>Sw(m,o.name,e)),u.onRequest("hydra-acp/connection/keep_alive",async m=>{let g=m??{},y=typeof g.token=="string"?g.token:void 0,k=typeof g.sessionId=="string"?g.sessionId:void 0,v=typeof g.estimatedRemainingMs=="number"?g.estimatedRemainingMs:void 0;return y&&k&&e.manager.get(k)?.keepAliveClaim(y,v),{ok:!0}})),u.onRequest("hydra-acp/session/tool_content",async m=>{let g=m??{};if(typeof g.sessionId!="string"||typeof g.hash!="string")throw O(x.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let y=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,k=await e.manager.loadToolBlob(y,g.hash);if(k===null)throw O(x.SessionNotFound,"tool content not found");return{content:k}}),u.onRequest("authenticate",async m=>mw(m,e)),u.onRequest("logout",async m=>yw(m,e)),u.onRequest("session/new",async m=>{let g=ga.parse(m),y=it(m?._meta),k=Array.isArray(y.transformers)&&y.transformers.every(ee=>typeof ee=="string")?y.transformers:e.manager.defaultTransformers??[],v=e.transformers?.resolveChain(k)??[],S=await fn(g.cwd),b=y.agentId??S.agentId??e.defaultAgent,A=await e.registry?.getAgent(b),C=qr(S.configDefaults,A??{id:b})?.value,R,T,M=g.mcpServers;if(y.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){R=Zu(32).toString("hex"),T=e.mcpTokenRegistry.reserve(R);let Oe={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${R}`}]};M=[...g.mcpServers??[],Oe]}let H,U,W=sn(e);W!==void 0&&(M=[...M??[],...W.descriptors]);let z=ri({baselineMcpServers:g.mcpServers,stdinEnabled:y.mcpStdin===!0,deps:e}),D;try{D=await e.manager.create({cwd:g.cwd,agentId:b,mcpServers:M,title:y.title,agentArgs:y.agentArgs,model:y.model??C?.model,configDefaults:C,onInstallProgress:gr(u),transformChain:v,originatingClient:l.clientInfo,...y.interactive!==void 0?{interactive:y.interactive}:{},...y.env!==void 0?{forwardedEnv:y.env}:{},...y.workspace!==void 0?{workspace:y.workspace}:{},...z?{mintMcpServersForSwap:z}:{}})}catch(ee){throw T!==void 0&&T.abandon(ee instanceof Error?ee:void 0),U!==void 0&&U.abandon(ee instanceof Error?ee:void 0),W!==void 0&&W.abandon(ee instanceof Error?ee:void 0),ee}if(R!==void 0&&T!==void 0&&e.mcpTokenRegistry!==void 0){let ee=R,Oe=e.mcpTokenRegistry;T.complete(D),D.onClose(()=>{Oe.unbind(ee)})}if(H!==void 0&&U!==void 0&&e.mcpTokenRegistry!==void 0){let ee=H,Oe=e.mcpTokenRegistry;U.complete(D),D.onClose(()=>{Oe.unbind(ee)})}W!==void 0&&W.bindToSession(D),sl(D.sessionId,e);let te,Z;try{on(l,D,D.sessionId),te=wt(u,D,l),{entries:Z}=await D.attach(te,"full")}catch(ee){throw await D.close({deleteRecord:!1,by:"session/new attach-failed"}).catch(()=>{}),ee}l.attached.set(D.sessionId,{sessionId:D.sessionId,clientId:te.clientId,readonly:!1}),setImmediate(()=>{(async()=>{for(let ee of Z){if(u.isClosed())break;await u.notify(ee.method,We(Be(ee.params,ee.recordedAt),ee.seq)).catch(()=>{})}})()});let oe=hr(D),Re=mr(D);return{sessionId:D.sessionId,...oe?{modes:oe}:{},...Re?{models:Re}:{},configOptions:D.buildConfigOptions(),_meta:yr(e.manager,D,{clientId:te.clientId})}}),u.onRequest("session/attach",async m=>{let g=ma.parse(m),y=g.clientInfo?.version;y&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,y):e.onTransformerVersion?.(o.name,y));let k=it(g._meta),v=k.resume,S=k.readonly===!0,b=k.env;s.log.info(`session/attach sessionId=${g.sessionId} hasResumeHints=${!!v} readonly=${S}`);let A=v?g.sessionId:await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,C=e.manager.get(A);if(!C&&S){let D=await e.manager.loadFromDisk(A);if(!D)throw O(x.SessionNotFound,`session ${g.sessionId} not found`);let te=Lt(await e.manager.loadHistory(A,{...k.historyLimit!==void 0?{maxEntries:k.historyLimit}:{}}),D.side),Z=g.clientId??`cli_${mi(8)}`;l.attached.set(D.hydraSessionId,{sessionId:D.hydraSessionId,clientId:Z,readonly:!0}),s.log.info(`session/attach OK (viewer) sessionId=${D.hydraSessionId} clientId=${Z} attachedCount=${l.attached.size} replayed=${te.length}`);for(let oe of te)await u.notify(oe.method,We(Be(oe.params,oe.recordedAt),oe.seq)).catch(()=>{});return{sessionId:D.hydraSessionId,clientId:Z,connectedClients:[Z],historyPolicy:"full",replayed:te.length,_meta:Iw(D)}}let R=!C;if(!C){let D=await e.manager.loadFromDisk(A),te=await ww(A,v,D?.upstreamSessionId,e.manager);te.kind==="ignore"&&s.log.warn(te.logMessage);let Z=D;if(v&&te.kind==="honor"&&(Z={...D,hydraSessionId:g.sessionId,upstreamSessionId:v.upstreamSessionId,agentId:v.agentId,cwd:D?.workspace?.path??v.cwd,...v.title!==void 0?{title:v.title}:{},...v.agentArgs!==void 0?{agentArgs:v.agentArgs}:{}}),!Z)throw O(x.SessionNotFound,`session ${g.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(Z.agentId,Z.upstreamSessionId))throw O(x.SessionNotFound,`session ${g.sessionId} was deleted`);let oe=Z.originatingClient?Z:{...Z,originatingClient:l.clientInfo},Re=b!==void 0?{...oe,forwardedEnv:b}:oe;C=await Tt(e,{...Re,onInstallProgress:gr(u)})}on(l,C,C.sessionId);let T=wt(u,C,l,g.clientInfo,g.clientId),M=k.replayMode==="drip",{entries:H,appliedPolicy:U}=await C.attach(T,g.historyPolicy,{afterMessageId:g.afterMessageId,afterSeq:g.afterSeq,raw:M,...k.historyLimit!==void 0?{historyLimit:k.historyLimit}:{},...k.toolContent!==void 0?{toolContent:k.toolContent}:{}});if(l.attached.set(C.sessionId,{sessionId:C.sessionId,clientId:T.clientId,readonly:S}),b!==void 0&&await e.manager.setForwardedEnv(C.sessionId,b).catch(()=>{}),s.log.info(`session/attach OK sessionId=${C.sessionId} clientId=${T.clientId} attachedCount=${l.attached.size} requestedPolicy=${g.historyPolicy} appliedPolicy=${U} replayed=${H.length} readonly=${S}${M?" replayMode=drip":""}`),M){let D=k.dripSpeed&&k.dripSpeed>0?k.dripSpeed:1,te=750;(async()=>{let Z=null;for(let oe of H){let Re=typeof oe.recordedAt=="number"?oe.recordedAt:null;if(Z!==null&&Re!==null){let ee=Math.min(te,Math.max(0,(Re-Z)/D));ee>0&&await new Promise(Oe=>setTimeout(Oe,ee))}Re!==null&&(Z=Re);try{await u.notify(oe.method,We(Be(oe.params,Re??void 0),oe.seq))}catch{return}}})()}else for(let D=0;D<H.length&&!u.isClosed();D++){let te=H[D],Z=u.notify(te.method,We(Be(te.params,te.recordedAt),te.seq)).catch(()=>{});(D+1)%200===0&&await Z}C.replayPendingPermissions(T);let W=hr(C),z=mr(C);return{sessionId:C.sessionId,clientId:T.clientId,connectedClients:C.connectedClients(T.clientId),historyPolicy:U,replayed:H.length,...W?{modes:W}:{},...z?{models:z}:{},configOptions:C.buildConfigOptions(),_meta:yr(e.manager,C,{resurrected:R})}}),u.onRequest("session/detach",async m=>{let g=ya.parse(m),y=l.attached.get(g.sessionId);if(!y)throw O(x.SessionNotFound,"client not attached to that session");let k=e.manager.get(g.sessionId);return k?.detach(y.clientId),l.attached.delete(g.sessionId),k&&e.manager.reapIfOrphanedNonInteractive(g.sessionId),{sessionId:g.sessionId,_meta:{[le]:{detachStatus:"detached"}}}}),u.onRequest("session/list",async m=>{let g=wa.parse(m??{});return{sessions:(await e.manager.list({cwd:g.cwd})).filter(S=>S.originatingClient?.name!==$s).map(ka)}}),u.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw O(x.InternalError,"agent registry unavailable");return Dt(e.registry)}),u.onRequest("hydra-acp/agents/auth_methods",async m=>{let g=m??{};if(typeof g.agentId!="string"||g.agentId.length===0)throw O(x.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(g.agentId)).authMethods??[]}}),u.onRequest("session/prompt",async m=>{let g=va.parse(m);p(g.sessionId,"session/prompt");let y=await Ku(g,e.manager,b=>{s.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${b} sessionId=${g.sessionId}`)});if(y?.fromSession!==void 0){if((y.depth??0)>3)throw s.log.warn(`session/prompt: refusing depth ${y.depth} chain from ${y.fromSession} to ${g.sessionId}`),O(x.InvalidRequest,`message chain too deep (${y.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(y.awaiting===!0&&Yu(y.fromSession,g.sessionId))throw s.log.warn(`session/prompt: refusing deadlock ${y.fromSession} -> ${g.sessionId}`),O(x.InvalidRequest,`would deadlock: ${g.sessionId} is already blocked waiting on ${y.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let k=l.attached.get(g.sessionId);if(!k)throw s.log.warn(`session/prompt rejected: not attached sessionId=${g.sessionId} attachedKeys=[${[...l.attached.keys()].join(",")}]`),O(x.SessionNotFound,"not attached to session");let v=e.manager.get(g.sessionId);if(!v){let b=await e.manager.loadFromDisk(g.sessionId);if(!b)throw O(x.SessionNotFound,`session ${g.sessionId} not found`);s.log.info(`session/prompt auto-resurrecting cold sessionId=${g.sessionId}`),v=await Tt(e,b);let A=wt(u,v,l,void 0,k.clientId);await v.attach(A,"none")}let S=y?.awaiting===!0&&y.fromSession!==void 0?Qu(y.fromSession,g.sessionId):void 0;try{return await v.prompt(k.clientId,g,y)}finally{S?.()}});let w=m=>{let g;try{g=is.parse(m)}catch(v){s.log.warn(`session/cancel: invalid params: ${v.message}`);return}let y=l.attached.get(g.sessionId);if(!y)return;if(y.readonly){s.log.warn(`session/cancel dropped (readonly attachment) sessionId=${g.sessionId}`);return}let k=e.manager.get(g.sessionId);k&&k.cancel(y.clientId).catch(v=>{s.log.warn(`session/cancel for ${g.sessionId}: ${v.message}`)})};u.onNotification("session/cancel",w),u.onRequest("session/cancel",async m=>{let g=is.parse(m);return p(g.sessionId,"session/cancel"),w(m),null}),u.onRequest("hydra-acp/prompt/cancel",async m=>{let g=Sa.parse(m);return p(g.sessionId,"hydra-acp/prompt/cancel"),Te(e.manager,g.sessionId).cancelQueuedPrompt(g.messageId)}),u.onRequest("hydra-acp/session/force_cancel",async m=>{let g=is.parse(m);return p(g.sessionId,"hydra-acp/session/force_cancel"),Te(e.manager,g.sessionId).forceCancel()}),u.onRequest("hydra-acp/prompt/update",async m=>{let g=Ia.parse(m);return p(g.sessionId,"hydra-acp/prompt/update"),Te(e.manager,g.sessionId).updateQueuedPrompt(g.messageId,g.prompt)}),u.onRequest("hydra-acp/prompt/amend",async m=>{let g=Aa.parse(m);p(g.sessionId,"hydra-acp/prompt/amend");let y=l.attached.get(g.sessionId);if(!y)throw O(x.SessionNotFound,"not attached to session");return Te(e.manager,g.sessionId).amendPrompt(y.clientId,g)}),u.onRequest("_session/steering",async m=>{let g=Ca.parse(m);p(g.sessionId,"_session/steering");let y=l.attached.get(g.sessionId);if(!y)throw O(x.SessionNotFound,"not attached to session");let k=e.manager.get(g.sessionId);if(!k){let v=await e.manager.loadFromDisk(g.sessionId);if(!v)throw O(x.SessionNotFound,`session ${g.sessionId} not found`);k=await Tt(e,v);let S=wt(u,k,l,void 0,y.clientId);await k.attach(S,"none")}return k.steer(y.clientId,g)}),u.onRequest("session/resume",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw O(x.InvalidParams,"session/resume requires sessionId");let k=await e.manager.resolveCanonicalId(y)??y,v=e.manager.get(k);if(!v){let C=await e.manager.loadFromDisk(k);if(!C)throw O(x.SessionNotFound,`session ${y} not found in memory or on disk`);v=await Tt(e,C)}on(l,v,v.sessionId);let S=wt(u,v,l);await v.attach(S,"pending_only"),l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1}),v.replayPendingPermissions(S);let b=hr(v),A=mr(v);return{sessionId:v.sessionId,...b?{modes:b}:{},...A?{models:A}:{},configOptions:v.buildConfigOptions(),_meta:yr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/load",async m=>{let g=m??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw O(x.InvalidParams,"session/load requires sessionId");let k=await e.manager.resolveCanonicalId(y)??y,v=e.manager.get(k);if(!v){let R=await e.manager.loadFromDisk(k);if(!R)throw O(x.SessionNotFound,`session ${y} not found in memory or on disk`);v=await Tt(e,R)}on(l,v,v.sessionId);let S=wt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let R of b){if(u.isClosed())break;await u.notify(R.method,We(Be(R.params,R.recordedAt),R.seq)).catch(()=>{})}v.replayPendingPermissions(S);let A=hr(v),C=mr(v);return{sessionId:v.sessionId,...A?{modes:A}:{},...C?{models:C}:{},configOptions:v.buildConfigOptions(),_meta:yr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/set_model",async m=>{let g=m?.sessionId;typeof g=="string"&&p(g,"session/set_model");let y=kw(m,e.manager);if(y.kind==="error")throw s.log.warn(y.logMessage),O(y.code,y.message);if(y.kind==="no_op")return s.log.warn(y.logMessage),await u.notify("session/update",{sessionId:y.sessionId,update:{sessionUpdate:"_hydra_current_model_update",currentModel:y.currentModel}}).catch(()=>{}),null;s.log.info(y.logMessage);let{modelId:k}=y,v=await y.session.forwardModelChange(k,m);return y.session.applyAgentConfigOptionResponse(v,"model"),y.session.applyModelChange(k),v}),u.onRequest("session/set_mode",async m=>{let g=m,y=g?.sessionId;if(typeof y=="string"&&p(y,"session/set_mode"),!g||typeof g.sessionId!="string")throw O(x.InvalidParams,"session/set_mode requires string sessionId");if(typeof g.modeId!="string")throw O(x.InvalidParams,"session/set_mode requires string modeId");let k=Te(e.manager,g.sessionId),v=await k.forwardRequest("session/set_mode",m);return k.applyModeChange(g.modeId),v}),u.onRequest("session/set_config_option",async m=>{let g=m,y=b=>O(x.InvalidParams,b),k=g?.sessionId;if(typeof k=="string"&&p(k,"session/set_config_option"),!g||typeof g.sessionId!="string")throw y("session/set_config_option requires string sessionId");if(typeof g.configId!="string")throw y("session/set_config_option requires string configId");if(typeof g.value!="string")throw y("session/set_config_option requires string value");let v=Te(e.manager,g.sessionId),S=v.buildConfigOptions().find(b=>b.id===g.configId);if(!S)throw y(`unknown configId ${JSON.stringify(g.configId)} for this session`);if(!S.options.some(b=>b.value===g.value))throw y(`value ${JSON.stringify(g.value)} is not valid for configId ${JSON.stringify(g.configId)}`);switch(g.configId){case"model":{if(g.value!==v.currentModel){let b=await v.forwardModelChange(g.value);v.applyAgentConfigOptionResponse(b,"model")}v.applyModelChange(g.value);break}case"mode":{g.value!==v.currentMode&&await v.forwardRequest("session/set_mode",{sessionId:g.sessionId,modeId:g.value}),v.applyModeChange(g.value);break}case"agent":{g.value!==v.agentId&&await v.setAgent(g.value);break}default:{let b=await v.forwardRequest("session/set_config_option",{sessionId:g.sessionId,configId:g.configId,value:g.value});v.applyAgentConfigOptionResponse(b,g.configId)&&v.broadcastConfigOptions()}}return{configOptions:v.buildConfigOptions()}}),u.setDefaultHandler(async(m,g)=>{let y=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),k=g.startsWith("session/"),v=g.startsWith("hydra-acp/");if(!k&&!v||m===null||typeof m!="object"||y.has(g))throw O(x.MethodNotFound,`Method not found: ${g}`);let S=m.sessionId;if(typeof S!="string")throw O(x.MethodNotFound,`Method not found: ${g}`);return p(S,g),Te(e.manager,S).forwardRequest(g,m)})})}async function mw(s,e){let t=s??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw O(x.InvalidParams,"authenticate requires a non-empty methodId string");let n=t.methodId,r=t._meta?.["hydra-acp"],o=typeof r?.sessionId=="string"?r.sessionId:void 0,i=typeof r?.agentId=="string"?r.agentId:void 0,a=o!==void 0?e.manager.getAgentForSession(o):void 0;if(!a||!a.isAlive()){let f=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(f)}let d=a.authMethods??[],c=d.find(f=>f.id===n);if(!c){let f=d.map(h=>h.id);throw O(x.InvalidParams,`authenticate: methodId ${JSON.stringify(n)} is not advertised by agent ${a.agentId}; valid: [${f.map(h=>JSON.stringify(h)).join(", ")}]`)}let u=c._meta?.type,l=(()=>{let f=c._meta?.["terminal-auth"];if(f&&typeof f=="object"&&!Array.isArray(f))return f})();if((c.type??(u==="agent"||u==="terminal"?u:l!==void 0?"terminal":"agent"))==="terminal"){let f=(k,v)=>{if(!Array.isArray(k))throw O(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be a string[]; got ${k===null?"null":typeof k}`);for(let S of k)if(typeof S!="string")throw O(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be string[]; got non-string entry ${JSON.stringify(S)}`);return k},h=await e.manager.planSpawnForAgent(a.agentId),w,m;if(l?.args!==void 0){let k=typeof l.command=="string"?l.command:void 0;w=k!==void 0&&tl.isAbsolute(k)?k:h.command,m=f(l.args,'_meta["terminal-auth"].args')}else{let k=c.args!==void 0?{raw:c.args,label:"args"}:c._meta?.args!==void 0?{raw:c._meta.args,label:"_meta.args"}:void 0,v=k!==void 0?f(k.raw,k.label):[];w=h.command,m=[...h.args,...v]}let g={};for(let[k,v]of Object.entries(process.env))typeof v=="string"&&(g[k]=v);Object.assign(g,h.env);let y=el.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${n}`),{kind:"terminal",command:w,args:m,env:g,cwd:y}}try{return await a.connection.request("authenticate",{methodId:n})}catch(f){throw ht(f,a)}}async function yw(s,e){let n=(s??{})._meta?.["hydra-acp"],r=typeof n?.sessionId=="string"?n.sessionId:void 0,o=typeof n?.agentId=="string"?n.agentId:void 0,i=r!==void 0?e.manager.getAgentForSession(r):void 0;if(!i||!i.isAlive()){let a=o??e.defaultAgent;i=await e.manager.bootstrapAgentForAuth(a)}return await i.connection.request("logout",{})}function gr(s){return e=>{let t={agentId:e.agentId,version:e.version,source:e.source,phase:e.phase};"receivedBytes"in e&&(t.receivedBytes=e.receivedBytes),"totalBytes"in e&&(t.totalBytes=e.totalBytes),"packageSpec"in e&&(t.packageSpec=e.packageSpec),s.notify(Ra,t).catch(()=>{})}}function hr(s){let e=s.availableModes();if(e.length===0)return;let t=e.map(r=>{let o={id:r.id,name:r.name??r.id};return r.description!==void 0&&(o.description=r.description),o});return{currentModeId:s.currentMode??e[0].id,availableModes:t}}function mr(s){let e=s.availableModels();if(e.length===0)return;let t=e.map(r=>{let o={modelId:r.modelId};return r.name!==void 0&&(o.name=r.name),r.description!==void 0&&(o.description=r.description),o});return{currentModelId:s.currentModel??e[0].modelId,availableModels:t}}async function ww(s,e,t,n){return e?await n.isRetiredGeneration(s,e.upstreamSessionId)?{kind:"ignore",logMessage:`session/attach ignoring stale resume hint sessionId=${s} hintUpstream=${e.upstreamSessionId} recordUpstream=${t} (retired generation)`}:{kind:"honor"}:{kind:"none"}}function kw(s,e){if(!s||typeof s!="object")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires params",logMessage:"session/set_model rejected: params not an object"};let t=s;if(typeof t.sessionId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string sessionId",logMessage:"session/set_model rejected: missing/non-string sessionId"};if(typeof t.modelId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string modelId",logMessage:`session/set_model rejected: missing/non-string modelId sessionId=${t.sessionId}`};let n=e.get(t.sessionId);if(!n)return{kind:"error",code:x.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=n.availableModels(),o=zt(t.modelId,r);if(o.kind==="none")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model passthrough (no availableModels) sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="exact")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model accepted sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="resolved")return{kind:"ok",session:n,modelId:o.modelId,logMessage:`session/set_model resolved sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} \u2192 ${JSON.stringify(o.modelId)}`};let i=r.map(d=>d.modelId).join(", "),a=o.kind==="ambiguous"?`ambiguous (trailing-segment matches [${o.candidates.join(", ")}])`:"not in availableModels";return n.currentModel!==void 0&&n.currentModel.length>0?{kind:"no_op",session:n,sessionId:t.sessionId,currentModel:n.currentModel,logMessage:`session/set_model no_op (resyncing client) sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} ${a} actual=${JSON.stringify(n.currentModel)} agentId=${n.agentId} known=[${i}]`}:{kind:"error",code:x.InvalidParams,message:`model "${t.modelId}" is ${a==="not in availableModels"?"not in this session's availableModels":a} (agent ${n.agentId}); known models: ${i}`,logMessage:`session/set_model rejected sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)} ${a} agentId=${n.agentId} known=[${i}] (no current model to fall back to)`}}async function vw(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0;if(!r)throw O(x.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw O(x.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw O(x.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return Te(t.manager,r).addTransformer(o),{ok:!0}}async function bw(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw O(x.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw O(x.InvalidParams,"hydra-acp/attention/set requires string reason");return Te(t.manager,r).setAttentionFlag(e,o,n.payload),{ok:!0}}async function Sw(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw O(x.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw O(x.InvalidParams,"hydra-acp/attention/clear requires string reason");return Te(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function Iw(s){let e={sessionId:s.hydraSessionId,upstreamSessionId:s.upstreamSessionId,cwd:s.cwd,workspace:s.workspace,title:s.title,agentId:s.agentId,currentModel:s.currentModel,currentUsage:On(s.currentUsage),forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,updatedAt:s.createdAt??new Date().toISOString(),attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1},t={currentMode:s.currentMode,agentArgs:s.agentArgs,availableCommands:s.agentCommands,availableModes:s.agentModes,availableModels:s.agentModels,armedTaskList:[]};return{[le]:os(e,t)}}function yr(s,e,t={}){let n=s.liveListEntry(e),r={clientId:t.clientId,currentMode:e.currentMode,agentArgs:e.agentArgs,availableCommands:e.mergedAvailableCommands(),availableModes:e.availableModes(),availableModels:e.availableModels(),turnStartedAt:e.turnStartedAt,agentCapabilities:e.agentCapabilities,queue:e.queueSnapshot(),armedTaskList:e.armedBackgroundTasks,...t.resurrected===!0?{resurrected:!0}:{}};return mn(e.agentMeta,os(n,r))}function Aw(){return{protocolVersion:1,agentInfo:{name:"hydra",version:ue},agentCapabilities:{promptCapabilities:{image:!0,audio:!0,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0},loadSession:!0,auth:{logout:{}},sessionCapabilities:{attach:{},list:{},resume:{},delete:{},close:{},fork:{}}},authMethods:[{id:"proxy",name:"Hydra proxy",type:"agent",description:"Hydra proxies authentication to the downstream agent selected per session"}],_meta:{...mn(void 0,{prompt:{queueing:!0,cancelling:!0,updating:!0,amending:!0,pipelining:!1},agents:{list:!0,installProgress:!0},session:{fork:{forkAt:!0,agentSwap:!0,synthesis:!0,model:!0},side:{selection:!0},rewind:{}}}),steering:{supported:!0}}}}function Cw(s,e){if(!(!e.transformers||!e.manager))for(let t of e.manager.defaultTransformers){let n=e.transformers.resolveChain([t])[0];n&&s.addTransformer(n)}}function sl(s,e){if(!e.transformers)return;let t=e.transformers.interestedIn("lifecycle:session.starting");for(let n of t)n.connection.notify("hydra-acp/transformer/session_event",{event:"session.starting",sessionId:s}).catch(()=>{})}function wt(s,e,t,n,r){return{clientId:r??`cli_${mi(8)}`,connection:s,clientInfo:n}}function on(s,e,t){let n=s.attached.get(t);n&&(e.detach(n.clientId),s.attached.delete(t))}var wr=class{byToken=new Map;reserve(e){if(this.byToken.has(e))throw new Error("mcp token already bound");let t,n,r=new Promise((i,a)=>{t=i,n=a});r.catch(()=>{});let o={session:void 0,sessionReady:r,disposers:[]};return this.byToken.set(e,o),{complete:i=>{o.session=i,t(i)},abandon:i=>{this.byToken.delete(e),n(i??new Error("mcp token reservation abandoned"))}}}bind(e,t){let{complete:n}=this.reserve(e);n(t)}lookup(e){return this.byToken.get(e)}addDisposer(e,t){let n=this.byToken.get(e);n!==void 0&&n.disposers.push(t)}async unbind(e){let t=this.byToken.get(e);if(t!==void 0){this.byToken.delete(e);for(let n of t.disposers)try{await n()}catch{}}}size(){return this.byToken.size}};import{randomUUID as Rw}from"crypto";import{McpServer as xw}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Ew}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as we}from"zod";function yi(s){if(s.method!=="session/update")return null;let t=s.params?.update;return!t||typeof t.sessionUpdate!="string"?null:{kind:t.sessionUpdate,update:t}}function Ce(s){return{content:[{type:"text",text:JSON.stringify(s)}],structuredContent:s}}var rl="Bearer ";function an(s){let e=s.headers.authorization;if(typeof e!="string"||!e.startsWith(rl))return;let t=e.slice(rl.length).trim();return t.length>0?t:void 0}function Tw(s){let e=new xw({name:"hydra-acp-stdin",version:"1.0.0"},{instructions:"Piped input from `hydra cat --stream` is exposed here as a byte stream. Use `tail` for the latest N bytes (good for finding the end of a log), `head` for the first N bytes (good for headers/preamble), `read` for windowed reads against an absolute byte cursor, `wait_for_more` to block until new bytes arrive past a cursor, and `info` for the current cursors/capacity/closed status. Byte payloads come back base64-encoded."});return e.registerTool("tail",{description:"Return the most recent `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means older bytes existed but have been evicted from the ring.",inputSchema:{bytes:we.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let n=s.streamTail(t);return Ce(n)}),e.registerTool("head",{description:"Return the first `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means the head has already been evicted from the ring and the returned bytes start at the oldest still-resident cursor.",inputSchema:{bytes:we.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let n=s.streamHead(t);return Ce(n)}),e.registerTool("read",{description:"Read up to `max_bytes` bytes starting at absolute byte `cursor`. Returns `{bytes, nextCursor, gap?, eof?}` \u2014 `gap` is the number of bytes silently skipped because the ring had evicted them; `eof:true` means the producer closed and there is nothing left to read.",inputSchema:{cursor:we.number().int().min(0).describe("Absolute byte offset to start reading from. Use 0 to read from the very beginning (may produce a gap if old bytes have been evicted)."),max_bytes:we.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:we.number().int().min(0).optional().describe("If no bytes are available, block up to this many ms for more (capped server-side at 60_000).")}},async({cursor:t,max_bytes:n,wait_ms:r})=>{let o=await s.streamRead(t,n,r);return Ce(o)}),e.registerTool("wait_for_more",{description:"Block until bytes are available past `cursor`, the stream closes, or `timeout_ms` elapses. Returns one of {data, eof, timeout} plus the current `writeCursor`. Use this when you've consumed everything up to a cursor and want to wait for more without busy-polling.",inputSchema:{cursor:we.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:we.number().int().min(0).describe("Maximum ms to block (server caps at 60_000).")}},async({cursor:t,timeout_ms:n})=>{let r=await s.streamWaitFor(t,n),o=s.streamInfo();return Ce({outcome:r,writeCursor:o.writeCursor,closed:o.closed})}),e.registerTool("grep",{description:"Scan piped stdin line-by-line and return lines matching `pattern`. Prefer this over `read` when the question is 'find lines that mention X' \u2014 it filters server-side so you don't pull and decode 64 KiB base64 windows. Returns `{matches: [{cursor, line, before?, after?}], truncated, nextCursor, gap?, scannedBytes, eof?}`. Lines come back as decoded UTF-8 strings (not base64). When `truncated:true`, re-call with `cursor: nextCursor` to resume.",inputSchema:{pattern:we.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:we.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:we.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:we.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:we.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:we.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:we.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:we.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:we.number().int().min(0).optional().describe("Optional absolute byte offset to start scanning from. Omit to scan from the oldest still-resident byte. Pass the `nextCursor` from a previous truncated call to resume.")}},async t=>{let n={pattern:t.pattern};t.regex!==void 0&&(n.regex=t.regex),t.case_insensitive!==void 0&&(n.caseInsensitive=t.case_insensitive),t.invert!==void 0&&(n.invert=t.invert),t.max_matches!==void 0&&(n.maxMatches=t.max_matches),t.max_bytes!==void 0&&(n.maxBytes=t.max_bytes),t.context_before!==void 0&&(n.contextBefore=t.context_before),t.context_after!==void 0&&(n.contextAfter=t.context_after),t.cursor!==void 0&&(n.cursor=t.cursor);let r=s.streamGrep(n);return Ce(r)}),e.registerTool("info",{description:"Report cursor / capacity / closed state of the stdin ring. Cheap; safe to call repeatedly.",inputSchema:{}},async()=>{let t=s.streamInfo();return Ce(t)}),e}var Pw=1e4;function ol(s,e){let t=new Map;async function n(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let c=Tw(a),u=new Ew({sessionIdGenerator:()=>Rw()});await c.connect(u);let l={server:c,transport:u};return t.set(i,l),e.addDisposer(i,async()=>{t.delete(i);try{await u.close()}catch{}try{await c.close()}catch{}}),u}async function r(i,a){let d=an(i);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let c=e.lookup(d);if(c===void 0){a.code(404).send({error:"unknown stdin token"});return}let u;if(c.session!==void 0)u=c.session;else{let p,f=new Promise(w=>{p=setTimeout(()=>w(void 0),Pw)}),h=await Promise.race([c.sessionReady.catch(()=>{}),f]);if(p!==void 0&&clearTimeout(p),h===void 0){a.code(503).send({error:"session not ready"});return}u=h}let l=await n(d,u);a.hijack(),await l.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),s.get("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),s.delete("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)})}import{randomUUID as Mw}from"crypto";import{McpServer as _w}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as $w}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as Ye}from"zod";function Ow(s){switch(s){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}var il=2e3,al=2e4;function Fw(s,e,t){if(e!=="tool_call"&&e!=="tool_call_update")return Vt([s]);let n=[],r=vn(t);r!==void 0?n.push(`Tool: ${r}`):typeof t.title=="string"&&t.title.length>0&&n.push(`Tool: ${t.title}`);let o=t.rawInput;if(o&&typeof o=="object"&&!Array.isArray(o))for(let[a,d]of Object.entries(o))typeof d=="string"&&d.length>0&&n.push(`${a}=${d}`);if(Array.isArray(t.locations))for(let a of t.locations)typeof a?.path=="string"&&a.path.length>0&&n.push(a.path);let i=ms(t);return i!==void 0&&n.push(i),n.join(`
212
+ `)}function Nw(s,e){if(s.length<=148)return s;let r=Math.floor(148/2),o=e-r;o<0&&(o=0);let i=o+148;i>s.length&&(o=s.length-148,o<0&&(o=0));let a=s.slice(o,i);return o>0&&(a="\u2026"+a),i<s.length&&(a=a+"\u2026"),a}function Dw(s){let e=new _w({name:"hydra-acp-recall",version:"1.0.0"},{instructions:"Search and retrieve detail from this session's pre-compaction history. After a compaction summary replaces earlier conversation in working memory, these tools let you page back specifics on demand. Use `search` to find entries by keyword, `range` to pull a contiguous slice verbatim, and `tool_calls` to enumerate prior tool invocations. These tools only return results once the session has been compacted at least once."});return e.registerTool("search",{description:"Search this session's prior conversation history (the part that was compacted out of your working memory) by keyword. Covers assistant and user messages, the arguments of every tool call including full shell commands, and what those calls printed. Returns matching entry ids with short snippets so you can decide which to pull in full via `range`. Use this when the compaction summary mentions something but you need the verbatim detail.",inputSchema:{query:Ye.string().min(1).describe("Case-insensitive substring to search for."),limit:Ye.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:Ye.boolean().optional().describe("Whether to include tool_call entries in the search (default true).")}},async({query:t,limit:n=10,include_tool_calls:r=!0})=>{let o=await s();if(!o.summarizedThroughEntry||o.summarizedThroughEntry===0)return Ce({matches:[],total_matched:0,truncated:!1,note:"This session has no compacted history. `search` retrieves detail from entries that were summarized out of the working conversation; nothing has been summarized yet."});let i=[],a=t.toLowerCase();for await(let{entryId:c,entry:u}of o.iterRecallNewestFirst()){let l=yi(u);if(!l)continue;let{kind:p,update:f}=l;if((p==="tool_call"||p==="tool_call_update")&&!r)continue;let h=Fw(u,p,f),w=h.toLowerCase().indexOf(a);if(w<0)continue;let m=Ow(p),g=Nw(h,w),y=typeof u.recordedAt=="number"?String(u.recordedAt):void 0;if(i.push({entryId:c,speaker:m,snippet:g,timestamp:y}),i.length>=n)break}i.sort((c,u)=>c.entryId-u.entryId);let d=i.length>=n;return Ce({matches:i,total_matched:i.length,truncated:d})}),e.registerTool("range",{description:"Pull a contiguous range of prior conversation entries verbatim from this session's pre-compaction history, including each tool call's arguments and what it printed. Use after `search` narrows in on what you need. Capped at 50 entries per call.",inputSchema:{from_entry:Ye.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:Ye.number().int().min(0).describe("Zero-based index of the last entry to include (inclusive).")}},async({from_entry:t,to_entry:n})=>{let r=await s();if(!r.summarizedThroughEntry||r.summarizedThroughEntry===0)return Ce({text:"",entry_count:0,truncated:!1,note:"This session has no compacted history. `range` retrieves verbatim entries from the pre-compaction transcript; nothing has been compacted yet."});if(n<t)throw new Error(`range: to_entry (${n}) must be >= from_entry (${t})`);let o=n-t+1;if(o>50)throw new Error(`range: range size (${o}) exceeds maximum of 50 entries`);let i=await r.getRecallTotalCount();if(i===0)return Ce({text:"",entry_count:0,truncated:!1});let a=Math.min(t,i-1),d=Math.min(n,i-1),c=a>t||d<n;if(a>d)return{content:[{type:"text",text:""}],structuredContent:{text:"",entry_count:0,truncated:c}};let u=await r.sliceRecallHistory(a,d),l=Vt(u,{toolOutput:{maxPerCall:il,maxTotal:al}});return{content:[{type:"text",text:l}],structuredContent:{text:l,entry_count:u.length,truncated:c}}}),e.registerTool("tool_calls",{description:"Search this session's prior tool invocations by tool name, ACP kind, and/or file path. Returns when each tool was called, its arguments (including the full shell command), the result status, and what the call printed. Use this to recall which files were read/edited, what shell commands ran, and what they output.",inputSchema:{tool_name:Ye.string().optional().describe("Case-insensitive substring of the tool name. Names vary by agent for the same tool (Bash, Terminal, bash), so prefer `kind` when you want every shell invocation."),kind:Ye.string().optional().describe("ACP tool kind: execute (shell), read, edit, think, other. Agent-independent, unlike tool_name."),file_path:Ye.string().optional(),limit:Ye.number().int().min(1).max(100).optional(),include_output:Ye.boolean().optional().describe("Include what each call printed (default true). Set false when you only need the commands and not their results.")}},async({tool_name:t,kind:n,file_path:r,limit:o=20,include_output:i=!0})=>{let a=await s();if(!a.summarizedThroughEntry||a.summarizedThroughEntry===0)return Ce({calls:[],truncated:!1,note:"This session has no compacted history. `tool_calls` retrieves tool invocations from the pre-compaction transcript; nothing has been compacted yet."});let d=typeof t=="string"&&t.length>0,c=typeof n=="string"&&n.length>0,u=typeof r=="string"&&r.length>0;if(!d&&!c&&!u)throw new Error("tool_calls: at least one of tool_name, kind, or file_path must be provided");let l=new Map,p=Math.max(o*4,200);for await(let{entryId:y,entry:k}of a.iterRecallNewestFirst()){let v=yi(k);if(!v)continue;let{kind:S,update:b}=v;if(S!=="tool_call"&&S!=="tool_call_update")continue;let A=typeof b.toolCallId=="string"&&b.toolCallId.length>0?b.toolCallId:`__noid_${y}`,C=l.get(A);if(C||(C={entryId:y,toolName:"(unnamed)",nameAuthoritative:!1,rawInput:{},locations:[],status:"in_progress"},l.set(A,C)),y<C.entryId&&(C.entryId=y),!C.nameAuthoritative){let T=vn(b);T!==void 0?(C.toolName=T,C.nameAuthoritative=!0):typeof b.name=="string"&&b.name.length>0?(C.toolName=b.name,C.nameAuthoritative=!0):S==="tool_call"&&typeof b.title=="string"&&b.title.length>0&&(C.toolName=b.title,C.nameAuthoritative=!0)}if(C.kind===void 0&&typeof b.kind=="string"&&b.kind.length>0&&(C.kind=b.kind),C.output===void 0){let T=ms(b);T!==void 0&&(C.output=T)}let R=b.rawInput;if(R&&typeof R=="object"&&!Array.isArray(R)&&Object.keys(R).length>0)for(let[T,M]of Object.entries(R))C.rawInput[T]===void 0&&(C.rawInput[T]=M);if(Array.isArray(b.locations))for(let T of b.locations){let M=T?.path;typeof M=="string"&&M.length>0&&!C.locations.includes(M)&&C.locations.push(M)}if(typeof b.status=="string"&&C.status==="in_progress"&&(C.status=b.status),k.recordedAt!==void 0&&C.timestamp===void 0&&(C.timestamp=String(k.recordedAt)),l.size>=p)break}let f=[...l.keys()].sort((y,k)=>l.get(y).entryId-l.get(k).entryId),h=[],w=al,m=!1;for(let y of f){let k=l.get(y);if(k.toolName=io({name:k.toolName,rawInput:k.rawInput,...k.kind!==void 0?{kind:k.kind}:{}}),d&&!k.toolName.toLowerCase().includes(t.toLowerCase())||c&&(k.kind??"").toLowerCase()!==n.toLowerCase())continue;if(u){let b=r.toLowerCase(),A=["file_path","filePath","path"],C=!1;for(let R of A){let T=k.rawInput[R];if(typeof T=="string"&&T.toLowerCase().includes(b)){C=!0;break}}if(!C){for(let R of k.locations)if(R.toLowerCase().includes(b)){C=!0;break}}if(!C)continue}let v={};for(let[b,A]of Object.entries(k.rawInput))typeof A=="string"?v[b]=A.length>500?A.slice(0,497)+"\u2026":A:(typeof A=="number"||typeof A=="boolean")&&(v[b]=A);k.locations.length>0&&v.locations===void 0&&(v.locations=k.locations);let S={entryId:k.entryId,tool:k.toolName,args:v,status:k.status,timestamp:k.timestamp};if(k.kind!==void 0&&(S.kind=k.kind),i&&k.output!==void 0){let b=k.output,A=Math.min(il,w);if(A<=0)m=!0;else{let C=b.length<=A?b:b.slice(0,A-1)+"\u2026";S.output=C,S.outputBytes=b.length,S.outputTruncated=C.length<b.length,w-=C.length}}if(h.push(S),h.length>=o)break}let g=h.length>=o;return Ce({calls:h,truncated:g,...m?{outputBudgetExhausted:m}:{}})}),e}var jw=1e4;function dl(s,e){let t=new Map;async function n(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let c=Dw(a),u=new $w({sessionIdGenerator:()=>Mw()});await c.connect(u);let l={server:c,transport:u};return t.set(i,l),e.addDisposer(i,async()=>{t.delete(i);try{await u.close()}catch{}try{await c.close()}catch{}}),u}async function r(i,a){let d=an(i);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let c=e.lookup(d);if(c===void 0){a.code(404).send({error:"unknown recall token"});return}let l=await n(d,async()=>{if(c.session!==void 0)return c.session;let p,f=new Promise(w=>{p=setTimeout(()=>w(void 0),jw)}),h=await Promise.race([c.sessionReady.catch(()=>{}),f]);if(p!==void 0&&clearTimeout(p),h===void 0)throw new Error("recall: session not ready");return h});a.hijack(),await l.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),s.get("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),s.delete("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)})}var kr=class{byName=new Map;changeHandlers=[];register(e,t,n,r){this.byName.set(e,{connection:t,instructions:n,tools:[...r]}),this.fireChanged(e,"register")}clear(e){this.byName.delete(e)&&this.fireChanged(e,"clear")}lookup(e){return this.byName.get(e)}list(){return Array.from(this.byName.keys())}onChange(e){return this.changeHandlers.push(e),()=>{let t=this.changeHandlers.indexOf(e);t>=0&&this.changeHandlers.splice(t,1)}}fireChanged(e,t){for(let n of this.changeHandlers)try{n(e,t)}catch{}}};import{StreamableHTTPServerTransport as Jw}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as Vw}from"crypto";import{Server as Hw}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as Lw,ListToolsRequestSchema as Uw}from"@modelcontextprotocol/sdk/types.js";function cl(s,e,t,n){let r=typeof t=="function"?async()=>t():async()=>t,o=new Hw({name:s,version:"1.0.0"},{capabilities:{tools:{listChanged:!0}},...e.instructions!==void 0?{instructions:e.instructions}:{}}),i=a=>({name:a.name,description:a.description,inputSchema:a.inputSchema,...a.outputSchema!==void 0?{outputSchema:a.outputSchema}:{}});return o.setRequestHandler(Uw,async()=>{let a=n?.peekSessionId?.();if(a!==void 0&&n?.fetchSessionTools!==void 0)try{let d=await n.fetchSessionTools(a);if(d!==void 0)return{tools:d.map(i)}}catch{}return{tools:e.tools.map(i)}}),o.setRequestHandler(Lw,async(a,d)=>{let c=a.params.name,u=d._meta?.progressToken??d.requestId,l=Ww(u,d.sendNotification);try{let p=await r(),f=await qw(e.connection,s,c,a.params.arguments??{},p);return zw(f,c)}catch(p){return wi(p instanceof Error?p.message:String(p))}finally{l()}}),o}var Bw=15e3;function Ww(s,e,t=Bw){if(s===void 0)return()=>{};let n=0,r=setInterval(()=>{n+=1,e({method:"notifications/progress",params:{progressToken:s,progress:n}}).catch(()=>{})},t);return r.unref?.(),()=>clearInterval(r)}async function qw(s,e,t,n,r){return await s.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:n,sessionId:r})}function zw(s,e){if(s===null||typeof s!="object")return wi(`extension ${e} returned non-object`);let t=s;return Array.isArray(t.content)?t:wi(`extension ${e} omitted content array`)}function wi(s){return{content:[{type:"text",text:s}],isError:!0}}var Gw=1e4;function ul(s,e,t){let n=new Map;async function r(u){try{await u.transport.close()}catch{}try{await u.server.close()}catch{}}function o(u){for(let l of n.values()){let p=l.get(u);p!==void 0&&(l.delete(u),r(p))}}async function i(u,l){for(let[p,f]of n){if(e.lookup(p)?.session?.sessionId!==u)continue;let w=f.get(l);if(w!==void 0)try{await w.server.sendToolListChanged()}catch{}}}t.onChange(u=>{o(u)});async function a(u,l){let p=n.get(u);p===void 0&&(p=new Map,n.set(u,p),e.addDisposer(u,async()=>{let v=n.get(u);if(v!==void 0){n.delete(u);for(let S of v.values())await r(S)}}));let f=p.get(l);if(f!==void 0)return f.transport;let h=t.lookup(l);if(h===void 0)return;let y=cl(l,h,async()=>{let v=e.lookup(u);if(v===void 0)throw new Error("mcp token no longer bound");if(v.session!==void 0)return v.session.sessionId;let S,b=new Promise(C=>{S=setTimeout(()=>C(void 0),Gw)}),A=await Promise.race([v.sessionReady.catch(()=>{}),b]);if(S!==void 0&&clearTimeout(S),A===void 0)throw new Error("session not ready");return A.sessionId},{peekSessionId:()=>e.lookup(u)?.session?.sessionId,fetchSessionTools:async v=>{let S=await h.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:v});if(!S||typeof S!="object")return;let b=S.tools;if(!Array.isArray(b))return;let A=[];for(let C of b){if(!C||typeof C!="object")continue;let R=C;if(typeof R.name!="string"||R.name.length===0||typeof R.description!="string"||R.inputSchema===null||typeof R.inputSchema!="object")continue;let T={name:R.name,description:R.description,inputSchema:R.inputSchema};R.outputSchema!==null&&typeof R.outputSchema=="object"&&(T.outputSchema=R.outputSchema),A.push(T)}return A}}),k=new Jw({sessionIdGenerator:()=>Vw()});return await y.connect(k),p.set(l,{server:y,transport:k}),k}async function d(u,l){let p=an(u);if(p===void 0){l.code(401).send({error:"missing bearer token"});return}if(e.lookup(p)===void 0){l.code(404).send({error:"unknown mcp token"});return}let h=u.params.name,w=await a(p,h);if(w===void 0){l.code(404).send({error:`unknown mcp server: ${h}`});return}l.hijack(),await w.handleRequest(u.raw,l.raw,u.body)}let c={config:{skipAuth:!0}};return s.post("/mcp/:name",c,async(u,l)=>{await d(u,l)}),s.get("/mcp/:name",c,async(u,l)=>{await d(u,l)}),s.delete("/mcp/:name",c,async(u,l)=>{await d(u,l)}),{notifyToolListChanged:i}}async function ml(s,e){tk(s),_r(s.daemon.scrubEnv);let t=s,n=s.daemon.tls?await Xe.readFile(ce(s.daemon.tls.key)):void 0,r=s.daemon.tls?await Xe.readFile(ce(s.daemon.tls.cert)):void 0;await Xe.mkdir(E.home(),{recursive:!0});let{stream:o,fileStream:i,closeFile:a}=await Zw(s.daemon.logLevel),d=Kw({logger:{level:s.daemon.logLevel,stream:o},bodyLimit:256*1024*1024});await d.register(Qw,{options:{handleProtocols:Hi}}),jr(F=>{d.log.info(F)}),Ur(F=>{d.log.info(F)});let c=await Gs.load(),u=await ir.load();fi(),ui(u);let l=new pr(u);l.start();let p=new sr(u);p.start();let f=new Zs,h=new Xs,w=new Ks(e),m=new Ys([w,new Qs(c),h]),g=Vc({validator:m});d.addHook("onRequest",async(F,Ae)=>{F.routeOptions.config?.skipAuth||F.url==="/acp"||F.url?.startsWith("/acp?")||(await g(F,Ae),!Ae.sent&&F.authIdentity?.startsWith("script:")&&!Kc(F.method,F.routeOptions.url)&&Ae.code(403).send({error:"script tokens may only access read-only session data"}))});let y=setInterval(()=>{c.sweepExpired()},300*1e3);y.unref();let k=setInterval(()=>{f.sweepExpired()},300*1e3);k.unref();let v=new ss(s,{onFetched:()=>{$c(v,C)},onStaleFallback:(F,Ae)=>{let cn=Math.round(Ae/36e5),un=cn>=48?`${Math.round(cn/24)}d`:`${cn}h`;d.log.warn(`registry fetch failed (${F.message}); serving stale cache last synced ${un} ago; agent versions may be outdated ('hydra registry refresh' to retry)`)}});Zo(F=>d.log.info(F));let S={info:F=>d.log.info(F),warn:F=>d.log.warn(F)},b=F=>dt.spawn({...F,stderrTailBytes:s.daemon.agentStderrTailBytes,logger:S});zi(s.compressToolContent);let A=new Js,C=new js(v,b,void 0,{idleTimeoutMs:s.daemon.sessionIdleTimeoutSeconds*1e3,orphanTimeoutMs:s.daemon.nonInteractiveOrphanTimeoutSeconds*1e3,sessionDefaults:s.sessionDefaults,synopsisAgent:s.synopsisAgent,synopsisModel:s.synopsisModel,compactionAgent:s.compaction?.agent,compactionModel:s.compaction?.model,defaultTransformers:s.defaultTransformers,sessionHistoryMaxEntries:s.daemon.sessionHistoryMaxEntries,sessionHistoryArchiveMaxBytes:s.daemon.sessionHistoryArchiveMaxBytes,sessionHistoryArchiveTiers:s.daemon.sessionHistoryArchiveTiers,logger:S,npmRegistry:s.npmRegistry,extensionCommands:A,defaultCwd:s.defaultCwd,disableWorkspaceSnapshots:s.disableWorkspaceSnapshots}),R=new fr(u,void 0,{resolvesLocally:async F=>await C.resolveCanonicalId(F)!==void 0,cache:p}),T=new qs(Oi(s),void 0,{tokenRegistry:h}),M=new zs(Fi(s),void 0,{tokenRegistry:h}),H=[];ku(d,ue,Nc(s),()=>H);let U=new Date().toISOString();Ru(d,U);let W=new wr,z=new kr,D,te=()=>{if(D!==void 0)return D;let F=d.server.address();return D=`http://127.0.0.1:${F&&typeof F=="object"?F.port:s.daemon.port}`,D},Z={agentId:s.defaultAgent,cwd:s.defaultCwd,publicHost:s.daemon.publicHost,host:s.daemon.host,port:s.daemon.port,compaction:s.compaction};yu(d,C,Z,{extensionMcp:z,mcpTokenRegistry:W,getDaemonOrigin:te},u,p),fu(d,{store:u,localMiss:{resolvesLocally:async F=>await C.resolveCanonicalId(F)!==void 0,cache:p}}),wu(d,v,C,{npmRegistry:s.npmRegistry}),xu(d,T),Eu(d,M);let oe={host:s.daemon.host,port:s.daemon.port,...s.daemon.publicHost!==void 0?{publicHost:s.daemon.publicHost}:{},...s.daemon.tls?{tls:{cert:ce(s.daemon.tls.cert),key:ce(s.daemon.tls.key)}}:{}};Tu(d,()=>({defaultAgent:t.defaultAgent,defaultCwd:t.defaultCwd,sessionDefaults:{...t.sessionDefaults},...t.synopsisAgent!==void 0?{synopsisAgent:t.synopsisAgent}:{},...t.synopsisModel!==void 0?{synopsisModel:t.synopsisModel}:{},defaultTransformers:[...t.defaultTransformers],listen:oe})),Ou(d,{store:c,rateLimiter:f,staticTokenValidator:w}),Wu(d,{store:u,health:l}),Gu(d,{processRegistry:h}),ol(d,W),dl(d,W);let Re=ul(d,W,z);nl(d,{validator:m,manager:C,defaultAgent:s.defaultAgent,processRegistry:h,onExtensionVersion:(F,Ae)=>T.reportVersion(F,Ae),onTransformerVersion:(F,Ae)=>M.reportVersion(F,Ae),transformers:M,extensionCommands:A,mcpTokenRegistry:W,extensionMcp:z,extensionMcpControls:Re,getDaemonOrigin:te,registry:v,foreignSessions:R});let ee=!!s.daemon.tls;await d.listen({host:ee?"127.0.0.1":s.daemon.host,port:ee?0:s.daemon.port});let Oe=d.server.address(),Pt=Oe&&typeof Oe=="object"?Oe.port:s.daemon.port,Yn,yl=s.daemon.host,ki=Pt;if(ee&&n&&r){Yn=await ek({listenHost:s.daemon.host,listenPort:s.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:Pt,tlsOptions:{key:n,cert:r},logger:d.log});let F=Yn.address();F&&typeof F=="object"&&(ki=F.port)}await Xe.mkdir(E.home(),{recursive:!0}),await _c({pid:process.pid,host:yl,port:ki,loopbackPort:Pt,startedAt:U});let vi={daemonUrl:`http://127.0.0.1:${Pt}`,daemonHost:"127.0.0.1",daemonPort:Pt,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${Pt}/acp`,hydraHome:E.home()};T.setContext(vi),M.setContext(vi),await T.start(),await M.start();try{await C.reconcilePermissionFlags()}catch(F){d.log.warn(`permission flag reconcile failed: ${F.message}`)}try{await C.seedSessionIndex()}catch(F){d.log.warn(`session index seed failed: ${F.message}`)}C.resurrectPendingQueues().catch(F=>{d.log.warn(`queue replay scan failed: ${F.message}`)}),C.resumePendingCompactions().catch(F=>{d.log.warn(`compaction resume scan failed: ${F.message}`)}),C.resumePendingAgentSwaps().catch(F=>{d.log.warn(`agent-swap resume scan failed: ${F.message}`)});let bi=s.daemon.agentSyncIntervalMinutes*60*1e3,Si=bi>0?Oc({registry:v,manager:C,intervalMs:bi,logger:S}):void 0,Ii=s.daemon.sessionGcIntervalMinutes*60*1e3,wl=s.daemon.sessionGcMaxAgeDays*24*60*60*1e3,Ai=Ii>0?Fc({manager:C,intervalMs:Ii,maxAgeMs:wl,logger:S}):void 0,kl=Lc({bootConfig:s,apply:F=>{t=F,v.setConfig(F),C.setLiveConfig({sessionDefaults:F.sessionDefaults}),Z.agentId=F.defaultAgent,Z.cwd=F.defaultCwd,_r(F.daemon.scrubEnv)},onDrift:F=>{H=F},logger:S});return{app:d,manager:C,registry:v,extensions:T,transformers:M,mcpTokenRegistry:W,extensionMcp:z,processRegistry:h,shutdown:async()=>{l.stop(),p.stop(),kl(),Ai&&Ai(),Si&&Si(),clearInterval(y),clearInterval(k);let F=async(Ae,cn)=>{try{await cn()}catch(un){d.log.warn(`shutdown step ${Ae} failed: ${un instanceof Error?un.message:String(un)}`)}};await F("sessionTokenStore.flush",()=>c.flush()),await F("extensions.stop",()=>T.stop()),await F("transformers.stop",()=>M.stop()),await F("manager.closeAll",()=>C.closeAll()),await F("manager.flushSynopsis",()=>C.flushSynopsis(3e4)),await F("manager.shutdownSynopsis",()=>C.shutdownSynopsis()),await F("manager.flushMetaWrites",()=>C.flushMetaWrites()),await F("manager.flushHistoryWrites",()=>C.flushHistoryWrites()),jr(null),Ur(null),Zo(null),Yn&&await F("tlsTerminator.close",()=>new Promise(Ae=>Yn.close(()=>Ae()))),await F("app.close",()=>d.close());try{pl.unlinkSync(E.pidFile())}catch{}await F("fileStream.flushSync",()=>i.flushSync()),await F("fileStream.close",a)}}}var fl=20;async function Xw(s,e){let t=dn.dirname(s),n=dn.basename(s,".log"),r=new RegExp(`^${n}\\.(\\d+)\\.log$`),o;try{o=await Xe.readdir(t)}catch{return}let i=[];for(let d of o){let c=d.match(r);c&&i.push({name:d,n:Number(c[1])})}if(i.length<=e)return;i.sort((d,c)=>d.n-c.n);let a=i.slice(0,i.length-e);await Promise.allSettled(a.map(d=>Xe.unlink(dn.join(t,d.name))))}async function Zw(s){await Xw(E.logFile(),fl);let e=await Yw({file:E.logFile(),size:"10m",mkdir:!0,symlink:Us,limit:{count:fl,removeOtherLogFiles:!0}}),t=ll.destination(2),n=!1,r={write:a=>{n||e.write(a)}};return{stream:ll.multistream([{stream:r,level:s},{stream:t,level:s}]),fileStream:e,closeFile:()=>new Promise(a=>{n=!0,e.once("close",()=>a()),e.end()})}}async function ek(s){let e=hl.createServer(s.tlsOptions,t=>{let n=gl.connect({host:s.upstreamHost,port:s.upstreamPort}),r=!1,o=i=>{if(!r){r=!0,i&&s.logger.warn(`tls terminator forwarder error: ${i.message??String(i)}`);try{t.destroy()}catch{}try{n.destroy()}catch{}}};t.on("error",o),n.on("error",o),t.on("close",()=>o()),n.on("close",()=>o()),t.pipe(n),n.pipe(t)});return e.on("tlsClientError",t=>{s.logger.warn(`tls handshake error: ${t.message}`)}),await new Promise((t,n)=>{let r=o=>{n(new Error(`TLS listener could not bind ${s.listenHost}:${s.listenPort}: ${o.message}`))};e.once("error",r),e.listen({host:s.listenHost,port:s.listenPort},()=>{e.off("error",r),t()})}),e.on("error",t=>{s.logger.warn(`tls terminator error: ${t.message}`)}),e}function tk(s){let e=s.daemon.host;if(!(e==="127.0.0.1"||e==="::1"||e==="localhost"||e==="[::1]")&&!s.daemon.tls)throw new Error(`Refusing to bind to non-loopback host ${e} without TLS configured.`)}async function nk(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:s}=await Promise.resolve().then(()=>(Gn(),Bu));s();let e=await pn(),t=await xi(),n=await ml(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
213
213
  `);let r=1e4,o=!1,i=async()=>{o&&(process.stderr.write(`Second signal received; exiting immediately.
214
214
  `),process.exit(1)),o=!0,process.stdout.write(`Shutting down...
215
215
  `);let a=setTimeout(()=>{process.stderr.write(`Graceful shutdown did not complete within ${r}ms; forcing exit.
216
216
  `),process.exit(1)},r);a.unref();try{await n.shutdown()}catch(d){process.stderr.write(`shutdown failed: ${d instanceof Error?d.message:String(d)}
217
- `)}clearTimeout(a),process.exit(0)};process.on("SIGINT",()=>{i()}),process.on("SIGTERM",()=>{i()}),process.on("SIGHUP",()=>{})}tk().catch(s=>{let e=s instanceof Error?s.stack??s.message:String(s);process.stderr.write(`hydra-acp-daemon: ${e}
217
+ `)}clearTimeout(a),process.exit(0)};process.on("SIGINT",()=>{i()}),process.on("SIGTERM",()=>{i()}),process.on("SIGHUP",()=>{})}nk().catch(s=>{let e=s instanceof Error?s.stack??s.message:String(s);process.stderr.write(`hydra-acp-daemon: ${e}
218
218
  `),Di(e).catch(()=>{}).finally(()=>process.exit(1))});