@hydra-acp/cli 0.1.182 → 0.1.183

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/daemon.js CHANGED
@@ -1,45 +1,45 @@
1
1
  #!/usr/bin/env node
2
- var Pu=Object.defineProperty;var Hn=(s,e)=>()=>(s&&(e=s(s=0)),e);var Mu=(s,e)=>{for(var t in e)Pu(s,t,{get:e[t],enumerable:!0})};import*as U from"path";import*as nr from"os";function F(s){let e=nr.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 _u(){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 $u(s,e){ni||U.isAbsolute(s)||(ni=!0,process.stderr.write(`hydra-acp: ${si} 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
- `))}function B(){let s=process.env[si];if(s&&s.length>0){let t=U.resolve(s);return $u(s,t),t}let e=_u();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 U.join(nr.homedir(),".hydra-acp")}var si,ni,x,G=Hn(()=>{"use strict";si="HYDRA_ACP_HOME";ni=!1;x={home:B,config:()=>U.join(B(),"config.json"),authToken:()=>U.join(B(),"auth-token"),remotes:()=>U.join(B(),"remotes.json"),peers:()=>U.join(B(),"peers.json"),pidFile:()=>U.join(B(),"daemon.pid"),logFile:()=>U.join(B(),"daemon.log"),daemonBootLog:()=>U.join(B(),"daemon-boot.log"),currentLogFile:()=>U.join(B(),"current.log"),registryCache:()=>U.join(B(),"registry.json"),themesDir:()=>U.join(B(),"themes"),ttySessionDir:()=>U.join(B(),"tty"),ttySessionFile:s=>U.join(B(),"tty",s),agentsDir:()=>U.join(B(),"agents"),agentLogFile:s=>U.join(B(),"agents","logs",`${s}.log`),agentInstallDir:(s,e,t)=>U.join(B(),"agents",e,s,t),agentNpmInstallDir:(s,e,t)=>U.join(B(),"agents",e,s,t,`node${process.versions.modules}`),sessionsDir:()=>U.join(B(),"sessions"),sessionDir:s=>U.join(B(),"sessions",s),sessionFile:s=>U.join(B(),"sessions",s,"meta.json"),historyFile:s=>U.join(B(),"sessions",s,"history.jsonl"),historyArchiveFile:(s,e)=>U.join(B(),"sessions",s,`history.jsonl.${e}`),toolsDir:s=>U.join(B(),"sessions",s,"tools"),toolBlobFile:(s,e)=>U.join(B(),"sessions",s,"tools",e),queueFile:s=>U.join(B(),"sessions",s,"queue.ndjson"),tombstonesDir:()=>U.join(B(),"sessions",".tombstones"),tombstoneAgentDir:s=>U.join(B(),"sessions",".tombstones",encodeURIComponent(s)),tombstoneFile:(s,e)=>U.join(B(),"sessions",".tombstones",encodeURIComponent(s),encodeURIComponent(e)),extensionsDir:()=>U.join(B(),"extensions"),extensionLogDir:s=>U.join(B(),"extensions",s),extensionLogFile:s=>U.join(B(),"extensions",s,"current.log"),extensionPidFile:s=>U.join(B(),"extensions",s,"extension.pid"),transformersDir:()=>U.join(B(),"transformers"),transformerLogDir:s=>U.join(B(),"transformers",s),transformerLogFile:s=>U.join(B(),"transformers",s,"current.log"),transformerPidFile:s=>U.join(B(),"transformers",s,"transformer.pid"),transformerState:(s,e)=>U.join(B(),"sessions",s,"transformer-state",e),tuiHistoryFile:s=>U.join(B(),"sessions",s,"prompt-history"),globalTuiHistoryFile:()=>U.join(B(),"prompt-history"),tuiLogFile:()=>U.join(B(),"tui.log"),shimWireLogFile:()=>U.join(B(),"shim-wire.log")}});import*as ue from"fs/promises";import*as oi from"fs";import*as xe from"path";import{randomBytes as Ou}from"crypto";async function le(s,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
4
- `;await Lu(s,r,t)}async function ju(s,e,t={}){let n=t.rename??ue.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"&&Nu.has(d)&&i<Du-1))throw a;await o(10*(i+1))}}async function Lu(s,e,t={}){let n=await Hu(s),r=xe.dirname(n);await ue.mkdir(r,{recursive:!0});let o=`${n}.tmp-${process.pid}-${Uu()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await ue.writeFile(o,e,i),await ju(o,n)}catch(i){throw await ue.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{oi.chmodSync(n,t.mode)}catch{}}async function Hu(s){let e;try{e=await ue.lstat(s)}catch(r){if(r.code==="ENOENT")return s;throw r}if(!e.isSymbolicLink())return s;let t=await ue.readlink(s),n=xe.isAbsolute(t)?t:xe.resolve(xe.dirname(s),t);try{let r=await ue.realpath(xe.dirname(n));return xe.join(r,xe.basename(n))}catch(r){if(r.code==="ENOENT")return n;throw r}}async function ie(s){let e;try{e=await ue.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 Uu(){return Ou(4).toString("hex")}var Nu,Du,Ne=Hn(()=>{"use strict";Nu=new Set(["EPERM","EACCES","EBUSY"]),Du=10});function Js(s,e){return`${s}:${e}`}var zc=Hn(()=>{"use strict";G();Ne()});var Xc={};Mu(Xc,{_resetForTests:()=>jh,clearPin:()=>Ho,fetchPeerFingerprint:()=>Nh,formatFingerprint:()=>Vc,getPin:()=>Fh,installGlobalTlsTrust:()=>Wo,loadPinsFromPeerStore:()=>Uo,loadPinsFromStore:()=>Oh,setPin:()=>On,sha256Hex:()=>Bo,wsTlsOptions:()=>qo});import{createHash as Eh}from"crypto";import*as Jc from"tls";import{Agent as Th,Dispatcher as Ph,buildConnector as Mh,getGlobalDispatcher as _h,setGlobalDispatcher as $h}from"undici";function On(s,e,t){St.set(Js(s,e),Gc(t))}function Ho(s,e){St.delete(Js(s,e))}function Fh(s,e){return St.get(Js(s,e))}function Oh(s){St.clear();for(let e of s.list())e.entry.pinnedFingerprint&&On(e.host,e.port,e.entry.pinnedFingerprint)}function Uo(s){for(let e of s.list())e.pinnedFingerprint&&On(e.host,e.port,e.pinnedFingerprint)}async function Nh(s,e,t={}){let n=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=Jc.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,Bo(u.raw))}),i.once("error",u=>d(u))})}function Bo(s){return Eh("sha256").update(s).digest("hex")}function Vc(s){let e=Gc(s),t=e.match(/.{2}/g);return t?t.join(":"):e}function Gc(s){return s.replace(/:/g,"").toLowerCase()}function Wo(){if(Lo)return;Lo=!0;let s=_h(),e=new Th({connect:Mh({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(n,r)=>Qc(n,r)})}),t=new Ph;t.dispatch=(n,r)=>{let o=Dh(n.origin);return(o&&Kc(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(()=>{})),$h(t)}function Dh(s){if(!s)return null;try{return new URL(String(s)).hostname}catch{return null}}function Kc(s){for(let e of St.keys())if(Yc(e)?.host===s)return!0;return!1}function Qc(s,e){if(!e||!e.raw)return new Error(`TLS peer ${s} did not present a certificate`);let t=Bo(e.raw);for(let[n,r]of St.entries()){let o=Yc(n);if(o&&o.host===s&&r===t)return}return new Error(`TLS pin mismatch for ${s} (cert sha256 ${Vc(t)})`)}function Yc(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 qo(s){return Kc(s)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>Qc(e,t)}:{autoSelectFamily:!0}}function jh(){St.clear(),Lo=!1}var St,Lo,Nn=Hn(()=>{"use strict";zc();St=new Map,Lo=!1});G();import*as et from"fs/promises";import{homedir as lr}from"os";import{z as I}from"zod";G();import*as At from"fs/promises";function sr(){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 Fu(){try{let e=(await At.readFile(x.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(s){if(s.code==="ENOENT")return;throw s}}async function rr(s){await At.mkdir(x.home(),{recursive:!0}),await At.writeFile(x.authToken(),s+`
2
+ var Pu=Object.defineProperty;var Ln=(s,e)=>()=>(s&&(e=s(s=0)),e);var Mu=(s,e)=>{for(var t in e)Pu(s,t,{get:e[t],enumerable:!0})};import*as U from"path";import*as nr from"os";function F(s){let e=nr.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 _u(){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 $u(s,e){ni||U.isAbsolute(s)||(ni=!0,process.stderr.write(`hydra-acp: ${si} 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
+ `))}function B(){let s=process.env[si];if(s&&s.length>0){let t=U.resolve(s);return $u(s,t),t}let e=_u();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 U.join(nr.homedir(),".hydra-acp")}var si,ni,x,G=Ln(()=>{"use strict";si="HYDRA_ACP_HOME";ni=!1;x={home:B,config:()=>U.join(B(),"config.json"),authToken:()=>U.join(B(),"auth-token"),remotes:()=>U.join(B(),"remotes.json"),peers:()=>U.join(B(),"peers.json"),pidFile:()=>U.join(B(),"daemon.pid"),logFile:()=>U.join(B(),"daemon.log"),daemonBootLog:()=>U.join(B(),"daemon-boot.log"),currentLogFile:()=>U.join(B(),"current.log"),registryCache:()=>U.join(B(),"registry.json"),themesDir:()=>U.join(B(),"themes"),ttySessionDir:()=>U.join(B(),"tty"),ttySessionFile:s=>U.join(B(),"tty",s),agentsDir:()=>U.join(B(),"agents"),agentLogFile:s=>U.join(B(),"agents","logs",`${s}.log`),agentInstallDir:(s,e,t)=>U.join(B(),"agents",e,s,t),agentNpmInstallDir:(s,e,t)=>U.join(B(),"agents",e,s,t,`node${process.versions.modules}`),sessionsDir:()=>U.join(B(),"sessions"),sessionDir:s=>U.join(B(),"sessions",s),sessionFile:s=>U.join(B(),"sessions",s,"meta.json"),historyFile:s=>U.join(B(),"sessions",s,"history.jsonl"),historyArchiveFile:(s,e)=>U.join(B(),"sessions",s,`history.jsonl.${e}`),toolsDir:s=>U.join(B(),"sessions",s,"tools"),toolBlobFile:(s,e)=>U.join(B(),"sessions",s,"tools",e),queueFile:s=>U.join(B(),"sessions",s,"queue.ndjson"),tombstonesDir:()=>U.join(B(),"sessions",".tombstones"),tombstoneAgentDir:s=>U.join(B(),"sessions",".tombstones",encodeURIComponent(s)),tombstoneFile:(s,e)=>U.join(B(),"sessions",".tombstones",encodeURIComponent(s),encodeURIComponent(e)),extensionsDir:()=>U.join(B(),"extensions"),extensionLogDir:s=>U.join(B(),"extensions",s),extensionLogFile:s=>U.join(B(),"extensions",s,"current.log"),extensionPidFile:s=>U.join(B(),"extensions",s,"extension.pid"),transformersDir:()=>U.join(B(),"transformers"),transformerLogDir:s=>U.join(B(),"transformers",s),transformerLogFile:s=>U.join(B(),"transformers",s,"current.log"),transformerPidFile:s=>U.join(B(),"transformers",s,"transformer.pid"),transformerState:(s,e)=>U.join(B(),"sessions",s,"transformer-state",e),tuiHistoryFile:s=>U.join(B(),"sessions",s,"prompt-history"),globalTuiHistoryFile:()=>U.join(B(),"prompt-history"),tuiLogFile:()=>U.join(B(),"tui.log"),shimWireLogFile:()=>U.join(B(),"shim-wire.log")}});import*as ue from"fs/promises";import*as oi from"fs";import*as xe from"path";import{randomBytes as Ou}from"crypto";async function le(s,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
4
+ `;await Hu(s,r,t)}async function ju(s,e,t={}){let n=t.rename??ue.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"&&Nu.has(d)&&i<Du-1))throw a;await o(10*(i+1))}}async function Hu(s,e,t={}){let n=await Lu(s),r=xe.dirname(n);await ue.mkdir(r,{recursive:!0});let o=`${n}.tmp-${process.pid}-${Uu()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await ue.writeFile(o,e,i),await ju(o,n)}catch(i){throw await ue.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{oi.chmodSync(n,t.mode)}catch{}}async function Lu(s){let e;try{e=await ue.lstat(s)}catch(r){if(r.code==="ENOENT")return s;throw r}if(!e.isSymbolicLink())return s;let t=await ue.readlink(s),n=xe.isAbsolute(t)?t:xe.resolve(xe.dirname(s),t);try{let r=await ue.realpath(xe.dirname(n));return xe.join(r,xe.basename(n))}catch(r){if(r.code==="ENOENT")return n;throw r}}async function ie(s){let e;try{e=await ue.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 Uu(){return Ou(4).toString("hex")}var Nu,Du,Ne=Ln(()=>{"use strict";Nu=new Set(["EPERM","EACCES","EBUSY"]),Du=10});function Js(s,e){return`${s}:${e}`}var zc=Ln(()=>{"use strict";G();Ne()});var Xc={};Mu(Xc,{_resetForTests:()=>jh,clearPin:()=>Lo,fetchPeerFingerprint:()=>Nh,formatFingerprint:()=>Vc,getPin:()=>Fh,installGlobalTlsTrust:()=>Wo,loadPinsFromPeerStore:()=>Uo,loadPinsFromStore:()=>Oh,setPin:()=>On,sha256Hex:()=>Bo,wsTlsOptions:()=>qo});import{createHash as Eh}from"crypto";import*as Jc from"tls";import{Agent as Th,Dispatcher as Ph,buildConnector as Mh,getGlobalDispatcher as _h,setGlobalDispatcher as $h}from"undici";function On(s,e,t){St.set(Js(s,e),Gc(t))}function Lo(s,e){St.delete(Js(s,e))}function Fh(s,e){return St.get(Js(s,e))}function Oh(s){St.clear();for(let e of s.list())e.entry.pinnedFingerprint&&On(e.host,e.port,e.entry.pinnedFingerprint)}function Uo(s){for(let e of s.list())e.pinnedFingerprint&&On(e.host,e.port,e.pinnedFingerprint)}async function Nh(s,e,t={}){let n=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=Jc.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,Bo(u.raw))}),i.once("error",u=>d(u))})}function Bo(s){return Eh("sha256").update(s).digest("hex")}function Vc(s){let e=Gc(s),t=e.match(/.{2}/g);return t?t.join(":"):e}function Gc(s){return s.replace(/:/g,"").toLowerCase()}function Wo(){if(Ho)return;Ho=!0;let s=_h(),e=new Th({connect:Mh({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(n,r)=>Qc(n,r)})}),t=new Ph;t.dispatch=(n,r)=>{let o=Dh(n.origin);return(o&&Kc(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(()=>{})),$h(t)}function Dh(s){if(!s)return null;try{return new URL(String(s)).hostname}catch{return null}}function Kc(s){for(let e of St.keys())if(Yc(e)?.host===s)return!0;return!1}function Qc(s,e){if(!e||!e.raw)return new Error(`TLS peer ${s} did not present a certificate`);let t=Bo(e.raw);for(let[n,r]of St.entries()){let o=Yc(n);if(o&&o.host===s&&r===t)return}return new Error(`TLS pin mismatch for ${s} (cert sha256 ${Vc(t)})`)}function Yc(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 qo(s){return Kc(s)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>Qc(e,t)}:{autoSelectFamily:!0}}function jh(){St.clear(),Ho=!1}var St,Ho,Nn=Ln(()=>{"use strict";zc();St=new Map,Ho=!1});G();import*as et from"fs/promises";import{homedir as lr}from"os";import{z as I}from"zod";G();import*as At from"fs/promises";function sr(){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 Fu(){try{let e=(await At.readFile(x.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(s){if(s.code==="ENOENT")return;throw s}}async function rr(s){await At.mkdir(x.home(),{recursive:!0}),await At.writeFile(x.authToken(),s+`
5
5
  `,{encoding:"utf8",mode:384})}async function ri(){let s=await Fu();if(s)return s;let e=sr();return await rr(e),process.stderr.write(`hydra-acp: initialized ${x.authToken()} with a fresh service token.
6
6
  `),e}Ne();import*as ai from"fs/promises";import*as en from"os";import*as De from"path";var ee="read by the daemon, which loads config.json at startup",ii={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:ee},agentOverrides:{reload:"live",overlay:"inert",overlayNote:ee},registry:{reload:"live",overlay:"inert",overlayNote:ee},npmRegistry:{reload:"live",overlay:"inert",overlayNote:ee},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:ee},synopsisModel:{reload:"warn",overlay:"inert",overlayNote:ee},compaction:{reload:"warn",overlay:"inert",overlayNote:ee},defaultTransformers:{reload:"warn",overlay:"inert",overlayNote:ee},disableWorkspaceSnapshots:{reload:"warn",overlay:"inert",overlayNote:ee},compressToolContent:{reload:"warn",overlay:"inert",overlayNote:ee},extensions:{reload:"warn",overlay:"inert",overlayNote:ee},transformers:{reload:"warn",overlay:"inert",overlayNote:ee},tui:{reload:"client",overlay:"effective"},sessionListColdLimit:{reload:"client",overlay:"effective"}},Bu={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:ee},logLevel:{reload:"warn",overlay:"inert",overlayNote:ee},sessionIdleTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ee},nonInteractiveOrphanTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ee},sessionHistoryMaxEntries:{reload:"warn",overlay:"inert",overlayNote:ee},sessionHistoryArchiveMaxBytes:{reload:"warn",overlay:"inert",overlayNote:ee},sessionHistoryArchiveTiers:{reload:"warn",overlay:"inert",overlayNote:ee},agentStderrTailBytes:{reload:"warn",overlay:"inert",overlayNote:ee},agentSyncIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ee},sessionGcIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ee},sessionGcMaxAgeDays:{reload:"warn",overlay:"inert",overlayNote:ee}};function or(s){return ii[s]??{reload:"restart",overlay:"inert"}}function ir(s){return Bu[s]??{reload:"restart",overlay:"inert"}}function ar(){let s=[];for(let[e,t]of Object.entries(ii))t.overlay!=="effective"&&s.push({key:e,effect:t.overlay,note:t.overlayNote??ee});return s}var Wu=".hydra-acp.json",dr="home",qu=64,Xy=ar().map(s=>s.key);function zu(s){return s==="~"?en.homedir():s.startsWith("~/")?De.join(en.homedir(),s.slice(2)):s.startsWith("$HOME/")?De.join(en.homedir(),s.slice(6)):s}function cr(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function ur(s,e){let t={...s};for(let[n,r]of Object.entries(e)){let o=t[n];t[n]=cr(o)&&cr(r)?ur(o,r):r}return t}async function Ju(s,e=en.homedir()){let t=[],n=[],r=De.resolve(e),o=De.resolve(s);for(let i=0;i<qu;i+=1){let a=De.join(o,Wu),d;try{d=await ai.readFile(a,"utf8")}catch{d=void 0}if(d!==void 0)try{let u=JSON.parse(d);cr(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=De.dirname(o);if(c===o)break;o=c}return t.reverse(),{layers:t,notices:n}}function Vu(s){let e=new Map(ar().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 Gu(s=process.cwd()){let{layers:e,notices:t}=await Ju(s);t.push(...Vu(e));let n={};for(let i of e)n=ur(n,i.data);let r,o=n[dr];return typeof o=="string"&&o.length>0?r=De.resolve(zu(o)):o!==void 0&&t.push({file:e[e.length-1].file,key:dr,message:"`home` must be a non-empty string; ignoring it"}),delete n[dr],{layers:e,notices:t,merged:n,...r!==void 0?{homeRequest:r}:{}}}function Ku(s,e){let t=s[e];return typeof t=="string"&&t.length>0?t:void 0}function Qu(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 tn(s){let e={};try{e=(await Gu(s)).merged}catch{return{}}let t=Ku(e,"defaultAgent"),n=Qu(e,"sessionDefaults");return{...t!==void 0?{agentId:t}:{},...n!==void 0?{configDefaults:n}:{}}}var ui="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",Yu=I.object({cert:I.string(),key:I.string()}),Ct=55514,Xu=I.object({host:I.string().default("127.0.0.1"),port:I.number().int().positive().default(Ct),logLevel:I.enum(["debug","info","warn","error"]).default("info"),tls:Yu.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)}),Zu=I.object({url:I.string().url().default(ui),ttlHours:I.number().positive().default(24),pinned:I.boolean().default(!1)}),el=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()}),tl=I.object({packageSpec:I.string().optional(),extraArgs:I.array(I.string()).optional(),env:I.record(I.string()).optional()}),nl=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"]),sl=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()]),rl=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(),ol=I.union([I.string(),rl]),di=I.array(sl);function fr(s,e){return I.object({left:di.default(s),right:di.default(e)}).default({})}var il=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],al=["usage"],dl=[],cl=["helpHint"],ul=["cwd","title"],ll=["agentModel"],fl=I.object({composer:I.object({top:fr(il,al),bottom:fr(dl,cl),hintTurns:I.number().int().nonnegative().nullable().default(3)}).default({}),sessionbar:fr(ul,ll),scriptRefreshMs:I.number().int().positive().default(5e3),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),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(!1),width:I.number().int().positive().optional(),border:I.enum(["none","rule","frame"]).default("frame"),gadgets:I.array(ol).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(),hotkeys:I.record(nl,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()}),ci=I.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),pl=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)}),gl=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)}),ml=I.object({daemon:Xu.default({}),registry:Zu.default({url:ui,ttlHours:24,pinned:!1}),agents:I.record(I.string(),el).default({}),agentOverrides:I.record(I.string(),tl).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(ci,pl).default({}),transformers:I.record(ci,gl).default({}),defaultTransformers:I.array(I.string()).default([]),npmRegistry:I.string().url().optional(),tui:fl.default({})});function li(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 pr(){return await hl(),await ie(x.config())??{}}async function hl(){let s;try{s=await et.lstat(x.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(s.isSymbolicLink())try{await et.stat(x.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await et.readlink(x.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${x.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 yl(){let s=await pr(),e=s.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let n=!1;try{await et.access(x.authToken()),n=!0}catch(r){if(r.code!=="ENOENT")throw r}if(n)throw new Error(`Auth token present in both ${x.authToken()} and ${x.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await rr(t),delete e.authToken,Object.keys(e).length===0&&delete s.daemon,await le(x.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${x.config()} to ${x.authToken()}.
7
7
  `)}async function wl(){let s=await pr(),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 le(x.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated defaultModels to sessionDefaults in ${x.config()}.
8
8
  `)}async function nn(){return await yl(),await wl(),ml.parse(await pr())}function fe(s){return s==="~"||s==="$HOME"?lr():s.startsWith("~/")?lr()+s.slice(1):s.startsWith("$HOME/")?lr()+s.slice(5):s}G();import*as Ke from"fs/promises";import*as pi from"path";var vl=64*1024;async function gi(s){let e=x.daemonBootLog(),t=`[${new Date().toISOString()}] pid=${process.pid} ${s}
9
- `;if(await Ke.mkdir(pi.dirname(e),{recursive:!0}),await Ke.stat(e).then(r=>r.size).catch(()=>0)>vl){await Ke.writeFile(e,t,{encoding:"utf8",mode:384});return}await Ke.appendFile(e,t,{encoding:"utf8",mode:384})}import*as Iu from"fs";import*as Ge from"fs/promises";import*as Au from"net";import*as Yt from"path";import*as Cu from"tls";import Oy from"fastify";import Ny from"@fastify/websocket";var mi="acp.v1";function hi(s,e){return s.has(mi)?mi:!1}import bu from"pino";import Dy from"pino-roll";var kl={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"]},yi="HYDRA_ACP_SESSION",bl=[yi],Sl=[...Object.values(kl).flat(),...bl];function Un(s,e){return s?{...e??{},[yi]:s}:e}var wi=[];function gr(s){wi=s?[...s]:[]}function Il(s,e){return e.endsWith("*")?s.startsWith(e.slice(0,-1)):s===e}function Al(){return[...Sl,...wi]}function Bn(s=process.env){let e=Al(),t={};for(let[n,r]of Object.entries(s))r!==void 0&&(e.some(o=>Il(n,o))||(t[n]=r));return t}G();import*as pe from"fs/promises";import{createHash as Cl}from"crypto";import{gzip as Rl,gunzip as xl}from"zlib";import{promisify as vi}from"util";var ki=vi(Rl),El=vi(xl),bi=/^[A-Za-z0-9_-]+$/,Tl=/^[a-f0-9]{64}$/,mr=!0;function Si(s){mr=s}function Wn(s,e){return bi.test(s)?e===void 0||Tl.test(e):!1}function qn(s,e){return`${x.toolBlobFile(s,e)}.gz`}async function hr(s,e){if(!Wn(s))return null;let t=Cl("sha256").update(e,"utf8").digest("hex"),n=qn(s,t),r=x.toolBlobFile(s,t);for(let a of[n,r])try{return await pe.access(a),t}catch{}await pe.mkdir(x.toolsDir(s),{recursive:!0});let o=mr?n:r,i=mr?await ki(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await pe.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function sn(s,e){if(!Wn(s,e))return null;try{let t=await pe.readFile(qn(s,e));return(await El(t)).toString("utf8")}catch{}try{return await pe.readFile(x.toolBlobFile(s,e),"utf8")}catch{return null}}async function Ii(s,e){if(!Wn(s,e))return null;try{return await pe.readFile(qn(s,e))}catch{}try{let t=await pe.readFile(x.toolBlobFile(s,e));return await ki(t)}catch{return null}}async function Ai(s,e,t){if(!Wn(s,e))return;let n=qn(s,e);try{await pe.access(n);return}catch{}await pe.mkdir(x.toolsDir(s),{recursive:!0}),await pe.writeFile(n,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function Ci(s){bi.test(s)&&await pe.rm(x.toolsDir(s),{recursive:!0,force:!0}).catch(()=>{})}G();import*as Li from"fs/promises";import*as Jn from"path";import{z as H}from"zod";Ne();G();import*as xi from"fs";import*as he from"fs/promises";import*as tt from"path";import{spawn as Ei}from"child_process";import{Readable as Pl}from"stream";function je(){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 vr(s,e=je()){if(e)return s[e]}var Rt=s=>{process.stderr.write(s+`
9
+ `;if(await Ke.mkdir(pi.dirname(e),{recursive:!0}),await Ke.stat(e).then(r=>r.size).catch(()=>0)>vl){await Ke.writeFile(e,t,{encoding:"utf8",mode:384});return}await Ke.appendFile(e,t,{encoding:"utf8",mode:384})}import*as Iu from"fs";import*as Ge from"fs/promises";import*as Au from"net";import*as Yt from"path";import*as Cu from"tls";import Oy from"fastify";import Ny from"@fastify/websocket";var mi="acp.v1";function hi(s,e){return s.has(mi)?mi:!1}import bu from"pino";import Dy from"pino-roll";var kl={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"]},yi="HYDRA_ACP_SESSION",bl=[yi],Sl=[...Object.values(kl).flat(),...bl];function Un(s,e){return s?{...e??{},[yi]:s}:e}var wi=[];function gr(s){wi=s?[...s]:[]}function Il(s,e){return e.endsWith("*")?s.startsWith(e.slice(0,-1)):s===e}function Al(){return[...Sl,...wi]}function Bn(s=process.env){let e=Al(),t={};for(let[n,r]of Object.entries(s))r!==void 0&&(e.some(o=>Il(n,o))||(t[n]=r));return t}G();import*as pe from"fs/promises";import{createHash as Cl}from"crypto";import{gzip as Rl,gunzip as xl}from"zlib";import{promisify as vi}from"util";var ki=vi(Rl),El=vi(xl),bi=/^[A-Za-z0-9_-]+$/,Tl=/^[a-f0-9]{64}$/,mr=!0;function Si(s){mr=s}function Wn(s,e){return bi.test(s)?e===void 0||Tl.test(e):!1}function qn(s,e){return`${x.toolBlobFile(s,e)}.gz`}async function hr(s,e){if(!Wn(s))return null;let t=Cl("sha256").update(e,"utf8").digest("hex"),n=qn(s,t),r=x.toolBlobFile(s,t);for(let a of[n,r])try{return await pe.access(a),t}catch{}await pe.mkdir(x.toolsDir(s),{recursive:!0});let o=mr?n:r,i=mr?await ki(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await pe.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function sn(s,e){if(!Wn(s,e))return null;try{let t=await pe.readFile(qn(s,e));return(await El(t)).toString("utf8")}catch{}try{return await pe.readFile(x.toolBlobFile(s,e),"utf8")}catch{return null}}async function Ii(s,e){if(!Wn(s,e))return null;try{return await pe.readFile(qn(s,e))}catch{}try{let t=await pe.readFile(x.toolBlobFile(s,e));return await ki(t)}catch{return null}}async function Ai(s,e,t){if(!Wn(s,e))return;let n=qn(s,e);try{await pe.access(n);return}catch{}await pe.mkdir(x.toolsDir(s),{recursive:!0}),await pe.writeFile(n,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function Ci(s){bi.test(s)&&await pe.rm(x.toolsDir(s),{recursive:!0,force:!0}).catch(()=>{})}G();import*as Hi from"fs/promises";import*as Jn from"path";import{z as L}from"zod";Ne();G();import*as xi from"fs";import*as he from"fs/promises";import*as tt from"path";import{spawn as Ei}from"child_process";import{Readable as Pl}from"stream";function je(){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 vr(s,e=je()){if(e)return s[e]}var Rt=s=>{process.stderr.write(s+`
10
10
  `)};function kr(s){Rt=s??(e=>process.stderr.write(e+`
11
- `))}async function Ti(s){if(!s.target.archive)throw new Error(`Agent ${s.agentId} has no archive URL for ${je()??"this platform"}`);if(!s.target.cmd)throw new Error(`Agent ${s.agentId} has no cmd in its binary target`);let e=je();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=x.agentInstallDir(s.agentId,e,s.version),n=tt.resolve(t,s.target.cmd);if(await wr(n))return n;if(await Ml({agentId:s.agentId,version:s.version,archiveUrl:s.target.archive,installDir:t,onProgress:s.onProgress}),!await wr(n))throw new Error(`Agent ${s.agentId}: extracted archive did not contain ${s.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await he.chmod(n,493).catch(()=>{}),n}async function Ml(s){await he.mkdir(tt.dirname(s.installDir),{recursive:!0});let e=await he.mkdtemp(`${s.installDir}.partial-`);try{Rt(`hydra-acp: downloading ${s.agentId} from ${s.archiveUrl}`);let t=await _l({url:s.archiveUrl,dir:e,agentId:s.agentId,version:s.version,onProgress:s.onProgress});Rt(`hydra-acp: extracting ${s.agentId}`),xt(s.onProgress,{phase:"extract",agentId:s.agentId,version:s.version}),await Fl(t,e),await he.unlink(t).catch(()=>{});try{await he.rename(e,s.installDir)}catch(n){let r=n;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await wr(s.installDir)){await he.rm(e,{recursive:!0,force:!0}).catch(()=>{}),xt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw n}Rt(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),xt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await he.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function xt(s,e){if(s)try{s(e)}catch{}}async function _l(s){let e=$l(s.url),t=tt.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=xi.createWriteStream(t),i=Pl.fromWeb(n.body);xt(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 m=Date.now();m-c>=l&&(c=m,xt(s.onProgress,{phase:"download_progress",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r})),m-d>=u&&(d=m,Rt(Ri(s.agentId,a,r)))}),await new Promise((p,m)=>{i.on("error",m),o.on("error",m),o.on("finish",()=>p()),i.pipe(o)}),Rt(Ri(s.agentId,a,r,!0)),xt(s.onProgress,{phase:"download_done",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r}),t}function Ri(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 $l(s){let e=new URL(s);return tt.posix.basename(e.pathname)||"archive"}async function Fl(s,e){let t=s.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await yr("tar",["-xf",s,"-C",e]);return}if(t.endsWith(".zip")){if(await Ol("unzip")){await yr("unzip",["-q",s,"-d",e]);return}await yr("tar",["-xf",s,"-C",e]);return}throw new Error(`Unsupported archive format: ${s}`)}function yr(s,e){return new Promise((t,n)=>{let r=Ei(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 Ol(s){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",n=Ei(t,[s],{stdio:"ignore"});n.on("error",()=>e(!1)),n.on("exit",r=>e(r===0))})}async function wr(s){try{return await he.access(s),!0}catch{return!1}}G();import*as Ie from"fs/promises";import*as Le from"path";import{delimiter as ql}from"path";import{spawn as zl}from"child_process";import{statSync as Nl}from"fs";import{delimiter as Dl,join as jl}from"path";var Ll=".COM;.EXE;.BAT;.CMD";function Pi(s){try{return Nl(s).isFile()}catch{return!1}}function Hl(s){let e=(s.PATHEXT??Ll).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 Ul(s,e){let t=s.toLowerCase();return e.some(n=>t.endsWith(n.toLowerCase()))}function Bl(s,e={}){if((e.platform??process.platform)!=="win32")return s;let n=e.env??process.env,r=Hl(n);if(Ul(s,r))return s;if(/[\\/]/.test(s)){for(let i of r){let a=s+i;if(Pi(a))return a}return s}let o=n.PATH??n.Path??"";for(let i of o.split(Dl).filter(a=>a.length>0))for(let a of r){let d=jl(i,s+a);if(Pi(d))return d}return s}var Wl=/["%\r\n]/;function Mi(s){if(Wl.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 Et(s,e,t={}){let n=t.platform??process.platform,r=Bl(s,t);return n!=="win32"||!/\.(cmd|bat)$/i.test(r)?{command:r,args:[...e],shell:!1}:{command:Mi(r),args:e.map(Mi),shell:!0}}var Sr=s=>{process.stderr.write(s+`
11
+ `))}async function Ti(s){if(!s.target.archive)throw new Error(`Agent ${s.agentId} has no archive URL for ${je()??"this platform"}`);if(!s.target.cmd)throw new Error(`Agent ${s.agentId} has no cmd in its binary target`);let e=je();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=x.agentInstallDir(s.agentId,e,s.version),n=tt.resolve(t,s.target.cmd);if(await wr(n))return n;if(await Ml({agentId:s.agentId,version:s.version,archiveUrl:s.target.archive,installDir:t,onProgress:s.onProgress}),!await wr(n))throw new Error(`Agent ${s.agentId}: extracted archive did not contain ${s.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await he.chmod(n,493).catch(()=>{}),n}async function Ml(s){await he.mkdir(tt.dirname(s.installDir),{recursive:!0});let e=await he.mkdtemp(`${s.installDir}.partial-`);try{Rt(`hydra-acp: downloading ${s.agentId} from ${s.archiveUrl}`);let t=await _l({url:s.archiveUrl,dir:e,agentId:s.agentId,version:s.version,onProgress:s.onProgress});Rt(`hydra-acp: extracting ${s.agentId}`),xt(s.onProgress,{phase:"extract",agentId:s.agentId,version:s.version}),await Fl(t,e),await he.unlink(t).catch(()=>{});try{await he.rename(e,s.installDir)}catch(n){let r=n;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await wr(s.installDir)){await he.rm(e,{recursive:!0,force:!0}).catch(()=>{}),xt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw n}Rt(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),xt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await he.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function xt(s,e){if(s)try{s(e)}catch{}}async function _l(s){let e=$l(s.url),t=tt.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=xi.createWriteStream(t),i=Pl.fromWeb(n.body);xt(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 m=Date.now();m-c>=l&&(c=m,xt(s.onProgress,{phase:"download_progress",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r})),m-d>=u&&(d=m,Rt(Ri(s.agentId,a,r)))}),await new Promise((p,m)=>{i.on("error",m),o.on("error",m),o.on("finish",()=>p()),i.pipe(o)}),Rt(Ri(s.agentId,a,r,!0)),xt(s.onProgress,{phase:"download_done",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r}),t}function Ri(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 $l(s){let e=new URL(s);return tt.posix.basename(e.pathname)||"archive"}async function Fl(s,e){let t=s.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await yr("tar",["-xf",s,"-C",e]);return}if(t.endsWith(".zip")){if(await Ol("unzip")){await yr("unzip",["-q",s,"-d",e]);return}await yr("tar",["-xf",s,"-C",e]);return}throw new Error(`Unsupported archive format: ${s}`)}function yr(s,e){return new Promise((t,n)=>{let r=Ei(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 Ol(s){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",n=Ei(t,[s],{stdio:"ignore"});n.on("error",()=>e(!1)),n.on("exit",r=>e(r===0))})}async function wr(s){try{return await he.access(s),!0}catch{return!1}}G();import*as Ie from"fs/promises";import*as He from"path";import{delimiter as ql}from"path";import{spawn as zl}from"child_process";import{statSync as Nl}from"fs";import{delimiter as Dl,join as jl}from"path";var Hl=".COM;.EXE;.BAT;.CMD";function Pi(s){try{return Nl(s).isFile()}catch{return!1}}function Ll(s){let e=(s.PATHEXT??Hl).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 Ul(s,e){let t=s.toLowerCase();return e.some(n=>t.endsWith(n.toLowerCase()))}function Bl(s,e={}){if((e.platform??process.platform)!=="win32")return s;let n=e.env??process.env,r=Ll(n);if(Ul(s,r))return s;if(/[\\/]/.test(s)){for(let i of r){let a=s+i;if(Pi(a))return a}return s}let o=n.PATH??n.Path??"";for(let i of o.split(Dl).filter(a=>a.length>0))for(let a of r){let d=jl(i,s+a);if(Pi(d))return d}return s}var Wl=/["%\r\n]/;function Mi(s){if(Wl.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 Et(s,e,t={}){let n=t.platform??process.platform,r=Bl(s,t);return n!=="win32"||!/\.(cmd|bat)$/i.test(r)?{command:r,args:[...e],shell:!1}:{command:Mi(r),args:e.map(Mi),shell:!0}}var Sr=s=>{process.stderr.write(s+`
12
12
  `)};function Ir(s){Sr=s??(e=>process.stderr.write(e+`
13
- `))}async function $i(s){let e=je();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=x.agentNpmInstallDir(s.agentId,e,s.version),n=Ql(s.packageSpec),r=Yl(n),o={installDir:t,packageName:n,hint:s.bin,basename:r},i=Le.join(t,"node_modules",".bin",s.bin);if(await ft(i))return i;if(await ft(t)){let l=await _i(o);if(l)return l.binPath}await Jl({agentId:s.agentId,version:s.version,packageSpec:s.packageSpec,installDir:t,registry:s.registry,onProgress:s.onProgress});let a=await _i(o);if(a)return a.binPath;let d=await Oi(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 Jl(s){await Ie.mkdir(Le.dirname(s.installDir),{recursive:!0});let e=await Ie.mkdtemp(`${s.installDir}.partial-`);try{Sr(`hydra-acp: installing ${s.packageSpec} for ${s.agentId} into ${e}`),br(s.onProgress,{phase:"install_start",agentId:s.agentId,version:s.version,packageSpec:s.packageSpec}),await Kl({packageSpec:s.packageSpec,cwd:e,registry:s.registry});try{await Ie.rename(e,s.installDir)}catch(t){let n=t;if((n.code==="EEXIST"||n.code==="ENOTEMPTY")&&await ft(s.installDir)){await Ie.rm(e,{recursive:!0,force:!0}).catch(()=>{}),br(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw t}Sr(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),br(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await Ie.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function br(s,e){if(s)try{s(e)}catch{}}var Vl=5,Gl=25;function Kl(s){return Fi(s,0)}async function Fi(s,e){try{await new Promise((t,n)=>{let r=s.registry?["--registry",s.registry]:[],o=Et("npm",["install","--no-audit","--no-fund","--silent",...r,s.packageSpec]),i;try{i=zl(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(ql).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<Vl)return await new Promise(r=>setTimeout(r,Gl*(e+1))),Fi(s,e+1);throw t}}function Ql(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 Yl(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}async function Oi(s,e){let t=Le.join(s,"node_modules",e,"package.json");try{let n=await Ie.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 _i(s){let e=Le.join(s.installDir,"node_modules",".bin"),t=Le.join(e,s.hint);if(await ft(t))return{binName:s.hint,binPath:t};let n=await Oi(s.installDir,s.packageName);if(typeof n=="object"&&n!==null){let r=Object.keys(n);if(r.length===1){let o=r[0],i=Le.join(e,o);if(await ft(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=Le.join(e,o);if(await ft(i))return{binName:o,binPath:i}}}}if(s.basename!==s.hint){let r=Le.join(e,s.basename);if(await ft(r))return{binName:s.basename,binPath:r}}}async function ft(s){try{return await Ie.access(s),!0}catch{return!1}}var Xl=H.object({package:H.string(),bin:H.string().optional(),args:H.array(H.string()).optional(),env:H.record(H.string()).optional()}),Tt=H.object({archive:H.string().url().optional(),cmd:H.string().optional(),args:H.array(H.string()).optional(),env:H.record(H.string()).optional()}),Zl=H.object({"darwin-aarch64":Tt.optional(),"darwin-x86_64":Tt.optional(),"linux-aarch64":Tt.optional(),"linux-x86_64":Tt.optional(),"windows-x86_64":Tt.optional(),"windows-aarch64":Tt.optional()}),ef=H.object({package:H.string(),args:H.array(H.string()).optional(),env:H.record(H.string()).optional()}),tf=H.object({command:H.string(),args:H.array(H.string()).optional(),env:H.record(H.string()).optional()}),nf=H.object({command:H.string().optional(),url:H.string().optional(),description:H.string().optional()}),sf=H.object({npx:Xl.optional(),binary:Zl.optional(),uvx:ef.optional(),exec:tf.optional()}),rf=H.object({id:H.string(),name:H.string(),version:H.string().optional(),description:H.string().optional(),authors:H.array(H.string()).optional(),license:H.string().optional(),icon:H.string().optional(),repository:H.string().optional(),website:H.string().optional(),distribution:sf,onboarding:nf.optional(),requiredEnv:H.array(H.string().min(1)).optional()}),Ni=8;function Hi(s){return s.installId??s.id}function Cr(s){let e=s.extendsChain;return e&&e.length>0?e[e.length-1]:s.id}function rn(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}}}var Di=H.object({version:H.string(),agents:H.array(rf),extensions:H.array(H.unknown()).optional()}),zn=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{...Ar(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>=Ni)throw new Error(`agent ${n.id}: extends chain deeper than ${Ni} (${[...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(af(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=>Rr(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])=>Ar(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=df(n.packageSpec),i=t.id,r={...r,npx:{...r.npx,package:n.packageSpec}}),n.extraArgs?.length&&(r=of(r,n.extraArgs)),n.env&&Object.keys(n.env).length>0&&(r=Ui(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=Di.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 ie(x.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=Di.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await le(x.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function Ar(s,e){return{id:s,name:e.name??s,description:e.description,version:"local",distribution:{exec:{command:fe(e.command??s),args:e.args?.map(fe),env:e.env}}}}function Ui(s,e){let t=e.args?.map(fe),n=r=>({...r,...t?{args:t}:{},...e.env?{env:{...r.env,...e.env}}:{}});return{...s.npx?{npx:n(s.npx)}:{},...s.uvx?{uvx:n(s.uvx)}:{},...s.exec?{exec:n(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([r,o])=>[r,o&&n(o)]))}:{}}}function of(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 af(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?Ar(s,e).distribution:Ui(t.distribution,e),installId:n?s:t.installId??t.id,extendsChain:[s,...t.extendsChain??[t.id]]}}function df(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 Rr(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 Pt(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 xr(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 xr(s){let e=je();if(!e)return"no";let t=s.version??"current",n=Hi(s);if(s.distribution.exec)return"yes";if(s.distribution.binary){let r=vr(s.distribution.binary,e);if(r?.cmd){let o=Jn.resolve(x.agentInstallDir(n,e,t),r.cmd);if(await ji(o))return"yes"}}if(s.distribution.npx){let r=s.distribution.npx,o=r.bin??Rr(s)??r.package,i=x.agentNpmInstallDir(n,e,t),a=Jn.join(i,"node_modules",".bin",o);if(await ji(a))return"yes"}return!s.distribution.npx&&!s.distribution.binary&&s.distribution.uvx?"lazy":"no"}async function ji(s){try{return await Li.access(s),!0}catch{return!1}}async function Ee(s,e=[],t={}){let n=s.version??"current",r=Hi(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??Rr(s)??o.package,d=t.onInstallProgress;return{command:await $i({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=vr(s.distribution.binary);if(!o)throw new Error(`Agent ${s.id} has no binary distribution for ${je()??"this platform"}.`);let i=t.onInstallProgress,a=await Ti({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 pf,spawnSync as gf}from"child_process";import*as Kn from"fs";import*as ra from"path";var E={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 K}from"zod";var Bi=K.object({protocolVersion:K.number().optional(),clientCapabilities:K.record(K.unknown()).optional(),clientInfo:K.object({name:K.string(),version:K.string().optional()}).optional()}),cf=K.enum(["full","pending_only","none","after_message"]),Wi=K.object({cwd:K.string(),mcpServers:K.array(K.unknown()).optional(),_meta:K.record(K.unknown()).optional()}),qi=K.object({upstreamSessionId:K.string(),agentId:K.string(),cwd:K.string(),title:K.string().optional(),agentArgs:K.array(K.string()).optional()}),zi=K.object({sessionId:K.string(),historyPolicy:cf.default("full"),afterMessageId:K.string().optional(),afterSeq:K.number().optional(),clientId:K.string().optional(),clientInfo:K.object({name:K.string(),version:K.string().optional()}).optional(),_meta:K.record(K.unknown()).optional()});import{z as D}from"zod";var Ji=D.object({sessionId:D.string()}),Vi=D.object({cwd:D.string().optional(),cursor:D.string().optional()}),Er=D.object({used:D.number().optional(),size:D.number().optional(),costAmount:D.number().optional(),costCurrency:D.string().optional()}),Bw=D.object({sessionId:D.string(),upstreamSessionId:D.string().optional(),cwd:D.string(),workspace:D.object({path:D.string(),sourceCwd:D.string(),label:D.string(),provider:D.string(),snapshot:D.string().optional(),vcs:D.record(D.string(),D.string()).optional()}).optional(),workspaceError:D.string().optional(),title:D.string().optional(),agentId:D.string().optional(),currentModel:D.string().optional(),currentUsage:Er.optional(),importedFromMachine:D.string().optional(),importedFromUpstreamSessionId:D.string().optional(),parentSessionId:D.string().optional(),forkedFromSessionId:D.string().optional(),forkedFromMessageId:D.string().optional(),originatingClient:D.object({name:D.string(),version:D.string().optional()}).optional(),interactive:D.boolean().optional(),priority:D.number().int().nonnegative().optional(),updatedAt:D.string(),attachedClients:D.number().int().nonnegative(),status:D.enum(["warm","cold"]).default("warm"),busy:D.boolean().default(!1),awaitingInput:D.boolean().default(!1),armedTasks:D.number().int().nonnegative().optional(),armedSince:D.number().int().positive().optional(),compactionState:D.any().optional(),agentPid:D.number().int().positive().optional(),forkSynthesisState:D.enum(["running","failed"]).optional(),_meta:D.record(D.unknown()).optional()}),uf=D.object({sessionId:D.string(),cwd:D.string(),title:D.string().optional(),updatedAt:D.string().optional(),_meta:D.record(D.unknown()).optional()}),Ww=D.object({sessions:D.array(uf),nextCursor:D.string().optional()});function Vn(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.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.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.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 Gi(s){let e={sessionId:s.sessionId,cwd:s.cwd,updatedAt:s.updatedAt,_meta:on(s._meta,Vn(s))};return s.title!==void 0&&(e.title=s.title),e}var de="hydra-acp";function lf(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 pt(s){if(!s)return{};let e=s[de];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 r=t.workspace,o={};typeof r.label=="string"&&(o.label=r.label),typeof r.from=="string"&&(o.from=r.from),r.required===!0&&(o.required=!0),typeof r.provider=="string"&&(o.provider=r.provider),n.workspace=o}if(t.workspaceInfo!==null&&typeof t.workspaceInfo=="object"&&!Array.isArray(t.workspaceInfo)){let r=t.workspaceInfo;if(typeof r.path=="string"&&typeof r.sourceCwd=="string"&&typeof r.label=="string"&&typeof r.provider=="string"){let o={path:r.path,sourceCwd:r.sourceCwd,label:r.label,provider:r.provider};if(typeof r.snapshot=="string"&&(o.snapshot=r.snapshot),r.vcs!==null&&typeof r.vcs=="object"&&!Array.isArray(r.vcs)){let i={};for(let[a,d]of Object.entries(r.vcs))typeof d=="string"&&(i[a]=d);o.vcs=i}n.workspaceInfo=o}}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(r=>typeof r=="string")&&(n.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(r=>typeof r=="string")&&(n.transformers=t.transformers),t.resume){let r=qi.safeParse(t.resume);r.success&&(n.resume=r.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 r=Er.safeParse(t.currentUsage);r.success&&(n.currentUsage=r.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 r=[];for(let o of t.armedTaskList){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;typeof i.label!="string"||typeof i.since!="number"||r.push({label:i.label,since:i.since,...typeof i.taskId=="string"?{taskId:i.taskId}:{},...typeof i.taskType=="string"?{taskType:i.taskType}:{},...typeof i.toolCallId=="string"?{toolCallId:i.toolCallId}:{}})}n.armedTaskList=r}if(Array.isArray(t.availableCommands)){let r=[];for(let o of t.availableCommands){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.name!="string")continue;let a={name:i.name};typeof i.description=="string"&&(a.description=i.description),r.push(a)}r.length>0&&(n.availableCommands=r)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let r=t.prompt,o={};typeof r.queueing=="boolean"&&(o.queueing=r.queueing),typeof r.cancelling=="boolean"&&(o.cancelling=r.cancelling),typeof r.updating=="boolean"&&(o.updating=r.updating),typeof r.amending=="boolean"&&(o.amending=r.amending),typeof r.pipelining=="boolean"&&(o.pipelining=r.pipelining),n.prompt=o}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let r=t.agents,o={};typeof r.list=="boolean"&&(o.list=r.list),typeof r.installProgress=="boolean"&&(o.installProgress=r.installProgress),n.agents=o}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 r=t.salvaged;typeof r.reason=="string"&&typeof r.supersededMessageId=="string"&&(n.salvaged={reason:r.reason,supersededMessageId:r.supersededMessageId})}if(Array.isArray(t.queue)){let r=[];for(let o of t.queue){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o,a=i.originator;if(typeof i.messageId!="string"||!a||typeof a.clientId!="string"||!Array.isArray(i.prompt)||typeof i.position!="number"||typeof i.enqueuedAt!="number")continue;let d={clientId:a.clientId};typeof a.name=="string"&&(d.name=a.name),typeof a.version=="string"&&(d.version=a.version),r.push({messageId:i.messageId,originator:d,prompt:i.prompt,position:i.position,enqueuedAt:i.enqueuedAt})}r.length>0&&(n.queue=r)}if(Array.isArray(t.availableModes)){let r=[];for(let o of t.availableModes){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.id!="string")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)}r.length>0&&(n.availableModes=r)}if(Array.isArray(t.availableModels)){let r=[];for(let o of t.availableModels){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.modelId!="string")continue;let a={modelId:i.modelId};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}r.length>0&&(n.availableModels=r)}if((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),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let r=t.originatingClient;n.originatingClient={name:r.name,...typeof r.version=="string"?{version:r.version}:{}}}if(t.agentCapabilities!==void 0&&(n.agentCapabilities=t.agentCapabilities),t.env!==void 0){let r=lf(t.env);r!==void 0&&(n.env=r)}return n}function He(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[de],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?s:{...t,_meta:{...n,[de]:{...o,recordedAt:e}}}}function Ue(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[de],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.seq=="number"?s:{...t,_meta:{...n,[de]:{...o,seq:e}}}}function on(s,e){return{...s??{},[de]:e}}import{z as _}from"zod";var Ki=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.record(_.unknown()).optional()}),Gn=_.object({sessionId:_.string()}),Qi=_.object({clientId:_.string(),name:_.string().optional(),version:_.string().optional()}),Kw=_.object({sessionId:_.string(),messageId:_.string(),originator:Qi,prompt:_.array(_.unknown()),position:_.number().int().nonnegative(),queueDepth:_.number().int().positive(),enqueuedAt:_.number()}),Qw=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),Yw=_.object({sessionId:_.string(),messageId:_.string(),reason:_.enum(["started","cancelled","abandoned"])}),Yi=_.object({sessionId:_.string(),messageId:_.string()}),Xw=_.object({cancelled:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Xi=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),Zw=_.object({updated:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Zi=_.object({sessionId:_.string(),targetMessageId:_.string(),prompt:_.array(_.unknown()),replaceQueue:_.boolean().optional(),onTargetCompleted:_.enum(["reject","send_anyway"]).optional()}),ev=_.object({amended:_.boolean(),reason:_.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:_.string().optional()}),ea=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.object({steering:_.object({idleBehavior:_.literal("promptRequired").optional()}).optional()}).optional()}),tv=_.object({outcome:_.enum(["injected","startedNewTurn","promptRequired","failed"]),reason:_.literal("noRunningTurn").optional(),detached:_.boolean().optional()}),nv=_.object({sessionId:_.string(),cancelledMessageId:_.string(),newMessageId:_.string(),prompt:_.array(_.unknown()),originator:Qi,amendedAt:_.number()});import{z as nt}from"zod";var ov=nt.object({agentId:nt.string(),version:nt.string(),source:nt.enum(["binary","npm"]),phase:nt.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:nt.number().optional(),totalBytes:nt.number().optional(),packageSpec:nt.string().optional()}),ta="hydra-acp/agents/install_progress",Mt={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function na(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 $i(s){let e=je();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=x.agentNpmInstallDir(s.agentId,e,s.version),n=Ql(s.packageSpec),r=Yl(n),o={installDir:t,packageName:n,hint:s.bin,basename:r},i=He.join(t,"node_modules",".bin",s.bin);if(await ft(i))return i;if(await ft(t)){let l=await _i(o);if(l)return l.binPath}await Jl({agentId:s.agentId,version:s.version,packageSpec:s.packageSpec,installDir:t,registry:s.registry,onProgress:s.onProgress});let a=await _i(o);if(a)return a.binPath;let d=await Oi(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 Jl(s){await Ie.mkdir(He.dirname(s.installDir),{recursive:!0});let e=await Ie.mkdtemp(`${s.installDir}.partial-`);try{Sr(`hydra-acp: installing ${s.packageSpec} for ${s.agentId} into ${e}`),br(s.onProgress,{phase:"install_start",agentId:s.agentId,version:s.version,packageSpec:s.packageSpec}),await Kl({packageSpec:s.packageSpec,cwd:e,registry:s.registry});try{await Ie.rename(e,s.installDir)}catch(t){let n=t;if((n.code==="EEXIST"||n.code==="ENOTEMPTY")&&await ft(s.installDir)){await Ie.rm(e,{recursive:!0,force:!0}).catch(()=>{}),br(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw t}Sr(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),br(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await Ie.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function br(s,e){if(s)try{s(e)}catch{}}var Vl=5,Gl=25;function Kl(s){return Fi(s,0)}async function Fi(s,e){try{await new Promise((t,n)=>{let r=s.registry?["--registry",s.registry]:[],o=Et("npm",["install","--no-audit","--no-fund","--silent",...r,s.packageSpec]),i;try{i=zl(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(ql).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<Vl)return await new Promise(r=>setTimeout(r,Gl*(e+1))),Fi(s,e+1);throw t}}function Ql(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 Yl(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}async function Oi(s,e){let t=He.join(s,"node_modules",e,"package.json");try{let n=await Ie.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 _i(s){let e=He.join(s.installDir,"node_modules",".bin"),t=He.join(e,s.hint);if(await ft(t))return{binName:s.hint,binPath:t};let n=await Oi(s.installDir,s.packageName);if(typeof n=="object"&&n!==null){let r=Object.keys(n);if(r.length===1){let o=r[0],i=He.join(e,o);if(await ft(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=He.join(e,o);if(await ft(i))return{binName:o,binPath:i}}}}if(s.basename!==s.hint){let r=He.join(e,s.basename);if(await ft(r))return{binName:s.basename,binPath:r}}}async function ft(s){try{return await Ie.access(s),!0}catch{return!1}}var Xl=L.object({package:L.string(),bin:L.string().optional(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Tt=L.object({archive:L.string().url().optional(),cmd:L.string().optional(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),Zl=L.object({"darwin-aarch64":Tt.optional(),"darwin-x86_64":Tt.optional(),"linux-aarch64":Tt.optional(),"linux-x86_64":Tt.optional(),"windows-x86_64":Tt.optional(),"windows-aarch64":Tt.optional()}),ef=L.object({package:L.string(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),tf=L.object({command:L.string(),args:L.array(L.string()).optional(),env:L.record(L.string()).optional()}),nf=L.object({command:L.string().optional(),url:L.string().optional(),description:L.string().optional()}),sf=L.object({npx:Xl.optional(),binary:Zl.optional(),uvx:ef.optional(),exec:tf.optional()}),rf=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:sf,onboarding:nf.optional(),requiredEnv:L.array(L.string().min(1)).optional()}),Ni=8;function Li(s){return s.installId??s.id}function Cr(s){let e=s.extendsChain;return e&&e.length>0?e[e.length-1]:s.id}function rn(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}}}var Di=L.object({version:L.string(),agents:L.array(rf),extensions:L.array(L.unknown()).optional()}),zn=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{...Ar(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>=Ni)throw new Error(`agent ${n.id}: extends chain deeper than ${Ni} (${[...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(af(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=>Rr(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])=>Ar(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=df(n.packageSpec),i=t.id,r={...r,npx:{...r.npx,package:n.packageSpec}}),n.extraArgs?.length&&(r=of(r,n.extraArgs)),n.env&&Object.keys(n.env).length>0&&(r=Ui(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=Di.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 ie(x.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=Di.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await le(x.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function Ar(s,e){return{id:s,name:e.name??s,description:e.description,version:"local",distribution:{exec:{command:fe(e.command??s),args:e.args?.map(fe),env:e.env}}}}function Ui(s,e){let t=e.args?.map(fe),n=r=>({...r,...t?{args:t}:{},...e.env?{env:{...r.env,...e.env}}:{}});return{...s.npx?{npx:n(s.npx)}:{},...s.uvx?{uvx:n(s.uvx)}:{},...s.exec?{exec:n(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([r,o])=>[r,o&&n(o)]))}:{}}}function of(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 af(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?Ar(s,e).distribution:Ui(t.distribution,e),installId:n?s:t.installId??t.id,extendsChain:[s,...t.extendsChain??[t.id]]}}function df(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 Rr(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 Pt(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 xr(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 xr(s){let e=je();if(!e)return"no";let t=s.version??"current",n=Li(s);if(s.distribution.exec)return"yes";if(s.distribution.binary){let r=vr(s.distribution.binary,e);if(r?.cmd){let o=Jn.resolve(x.agentInstallDir(n,e,t),r.cmd);if(await ji(o))return"yes"}}if(s.distribution.npx){let r=s.distribution.npx,o=r.bin??Rr(s)??r.package,i=x.agentNpmInstallDir(n,e,t),a=Jn.join(i,"node_modules",".bin",o);if(await ji(a))return"yes"}return!s.distribution.npx&&!s.distribution.binary&&s.distribution.uvx?"lazy":"no"}async function ji(s){try{return await Hi.access(s),!0}catch{return!1}}async function Ee(s,e=[],t={}){let n=s.version??"current",r=Li(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??Rr(s)??o.package,d=t.onInstallProgress;return{command:await $i({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=vr(s.distribution.binary);if(!o)throw new Error(`Agent ${s.id} has no binary distribution for ${je()??"this platform"}.`);let i=t.onInstallProgress,a=await Ti({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 pf,spawnSync as gf}from"child_process";import*as Kn from"fs";import*as ra from"path";var E={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 K}from"zod";var Bi=K.object({protocolVersion:K.number().optional(),clientCapabilities:K.record(K.unknown()).optional(),clientInfo:K.object({name:K.string(),version:K.string().optional()}).optional()}),cf=K.enum(["full","pending_only","none","after_message"]),Wi=K.object({cwd:K.string(),mcpServers:K.array(K.unknown()).optional(),_meta:K.record(K.unknown()).optional()}),qi=K.object({upstreamSessionId:K.string(),agentId:K.string(),cwd:K.string(),title:K.string().optional(),agentArgs:K.array(K.string()).optional()}),zi=K.object({sessionId:K.string(),historyPolicy:cf.default("full"),afterMessageId:K.string().optional(),afterSeq:K.number().optional(),clientId:K.string().optional(),clientInfo:K.object({name:K.string(),version:K.string().optional()}).optional(),_meta:K.record(K.unknown()).optional()});import{z as D}from"zod";var Ji=D.object({sessionId:D.string()}),Vi=D.object({cwd:D.string().optional(),cursor:D.string().optional()}),Er=D.object({used:D.number().optional(),size:D.number().optional(),costAmount:D.number().optional(),costCurrency:D.string().optional()}),Bw=D.object({sessionId:D.string(),upstreamSessionId:D.string().optional(),cwd:D.string(),workspace:D.object({path:D.string(),sourceCwd:D.string(),label:D.string(),provider:D.string(),snapshot:D.string().optional(),vcs:D.record(D.string(),D.string()).optional()}).optional(),workspaceError:D.string().optional(),title:D.string().optional(),agentId:D.string().optional(),currentModel:D.string().optional(),currentUsage:Er.optional(),importedFromMachine:D.string().optional(),importedFromUpstreamSessionId:D.string().optional(),parentSessionId:D.string().optional(),forkedFromSessionId:D.string().optional(),forkedFromMessageId:D.string().optional(),originatingClient:D.object({name:D.string(),version:D.string().optional()}).optional(),interactive:D.boolean().optional(),priority:D.number().int().nonnegative().optional(),updatedAt:D.string(),attachedClients:D.number().int().nonnegative(),status:D.enum(["warm","cold"]).default("warm"),busy:D.boolean().default(!1),awaitingInput:D.boolean().default(!1),armedTasks:D.number().int().nonnegative().optional(),armedSince:D.number().int().positive().optional(),compactionState:D.any().optional(),agentPid:D.number().int().positive().optional(),forkSynthesisState:D.enum(["running","failed"]).optional(),_meta:D.record(D.unknown()).optional()}),uf=D.object({sessionId:D.string(),cwd:D.string(),title:D.string().optional(),updatedAt:D.string().optional(),_meta:D.record(D.unknown()).optional()}),Ww=D.object({sessions:D.array(uf),nextCursor:D.string().optional()});function Vn(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.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.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.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 Gi(s){let e={sessionId:s.sessionId,cwd:s.cwd,updatedAt:s.updatedAt,_meta:on(s._meta,Vn(s))};return s.title!==void 0&&(e.title=s.title),e}var de="hydra-acp";function lf(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 pt(s){if(!s)return{};let e=s[de];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 r=t.workspace,o={};typeof r.label=="string"&&(o.label=r.label),typeof r.from=="string"&&(o.from=r.from),r.required===!0&&(o.required=!0),typeof r.provider=="string"&&(o.provider=r.provider),n.workspace=o}if(t.workspaceInfo!==null&&typeof t.workspaceInfo=="object"&&!Array.isArray(t.workspaceInfo)){let r=t.workspaceInfo;if(typeof r.path=="string"&&typeof r.sourceCwd=="string"&&typeof r.label=="string"&&typeof r.provider=="string"){let o={path:r.path,sourceCwd:r.sourceCwd,label:r.label,provider:r.provider};if(typeof r.snapshot=="string"&&(o.snapshot=r.snapshot),r.vcs!==null&&typeof r.vcs=="object"&&!Array.isArray(r.vcs)){let i={};for(let[a,d]of Object.entries(r.vcs))typeof d=="string"&&(i[a]=d);o.vcs=i}n.workspaceInfo=o}}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(r=>typeof r=="string")&&(n.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(r=>typeof r=="string")&&(n.transformers=t.transformers),t.resume){let r=qi.safeParse(t.resume);r.success&&(n.resume=r.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 r=Er.safeParse(t.currentUsage);r.success&&(n.currentUsage=r.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 r=[];for(let o of t.armedTaskList){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;typeof i.label!="string"||typeof i.since!="number"||r.push({label:i.label,since:i.since,...typeof i.taskId=="string"?{taskId:i.taskId}:{},...typeof i.taskType=="string"?{taskType:i.taskType}:{},...typeof i.toolCallId=="string"?{toolCallId:i.toolCallId}:{}})}n.armedTaskList=r}if(Array.isArray(t.availableCommands)){let r=[];for(let o of t.availableCommands){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.name!="string")continue;let a={name:i.name};typeof i.description=="string"&&(a.description=i.description),r.push(a)}r.length>0&&(n.availableCommands=r)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let r=t.prompt,o={};typeof r.queueing=="boolean"&&(o.queueing=r.queueing),typeof r.cancelling=="boolean"&&(o.cancelling=r.cancelling),typeof r.updating=="boolean"&&(o.updating=r.updating),typeof r.amending=="boolean"&&(o.amending=r.amending),typeof r.pipelining=="boolean"&&(o.pipelining=r.pipelining),n.prompt=o}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let r=t.agents,o={};typeof r.list=="boolean"&&(o.list=r.list),typeof r.installProgress=="boolean"&&(o.installProgress=r.installProgress),n.agents=o}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 r=t.salvaged;typeof r.reason=="string"&&typeof r.supersededMessageId=="string"&&(n.salvaged={reason:r.reason,supersededMessageId:r.supersededMessageId})}if(Array.isArray(t.queue)){let r=[];for(let o of t.queue){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o,a=i.originator;if(typeof i.messageId!="string"||!a||typeof a.clientId!="string"||!Array.isArray(i.prompt)||typeof i.position!="number"||typeof i.enqueuedAt!="number")continue;let d={clientId:a.clientId};typeof a.name=="string"&&(d.name=a.name),typeof a.version=="string"&&(d.version=a.version),r.push({messageId:i.messageId,originator:d,prompt:i.prompt,position:i.position,enqueuedAt:i.enqueuedAt})}r.length>0&&(n.queue=r)}if(Array.isArray(t.availableModes)){let r=[];for(let o of t.availableModes){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.id!="string")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)}r.length>0&&(n.availableModes=r)}if(Array.isArray(t.availableModels)){let r=[];for(let o of t.availableModels){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.modelId!="string")continue;let a={modelId:i.modelId};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}r.length>0&&(n.availableModels=r)}if((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),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let r=t.originatingClient;n.originatingClient={name:r.name,...typeof r.version=="string"?{version:r.version}:{}}}if(t.agentCapabilities!==void 0&&(n.agentCapabilities=t.agentCapabilities),t.env!==void 0){let r=lf(t.env);r!==void 0&&(n.env=r)}return n}function Le(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[de],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?s:{...t,_meta:{...n,[de]:{...o,recordedAt:e}}}}function Ue(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[de],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.seq=="number"?s:{...t,_meta:{...n,[de]:{...o,seq:e}}}}function on(s,e){return{...s??{},[de]:e}}import{z as _}from"zod";var Ki=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.record(_.unknown()).optional()}),Gn=_.object({sessionId:_.string()}),Qi=_.object({clientId:_.string(),name:_.string().optional(),version:_.string().optional()}),Kw=_.object({sessionId:_.string(),messageId:_.string(),originator:Qi,prompt:_.array(_.unknown()),position:_.number().int().nonnegative(),queueDepth:_.number().int().positive(),enqueuedAt:_.number()}),Qw=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),Yw=_.object({sessionId:_.string(),messageId:_.string(),reason:_.enum(["started","cancelled","abandoned"])}),Yi=_.object({sessionId:_.string(),messageId:_.string()}),Xw=_.object({cancelled:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Xi=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),Zw=_.object({updated:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Zi=_.object({sessionId:_.string(),targetMessageId:_.string(),prompt:_.array(_.unknown()),replaceQueue:_.boolean().optional(),onTargetCompleted:_.enum(["reject","send_anyway"]).optional()}),ev=_.object({amended:_.boolean(),reason:_.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:_.string().optional()}),ea=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.object({steering:_.object({idleBehavior:_.literal("promptRequired").optional()}).optional()}).optional()}),tv=_.object({outcome:_.enum(["injected","startedNewTurn","promptRequired","failed"]),reason:_.literal("noRunningTurn").optional(),detached:_.boolean().optional()}),nv=_.object({sessionId:_.string(),cancelledMessageId:_.string(),newMessageId:_.string(),prompt:_.array(_.unknown()),originator:Qi,amendedAt:_.number()});import{z as nt}from"zod";var ov=nt.object({agentId:nt.string(),version:nt.string(),source:nt.enum(["binary","npm"]),phase:nt.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:nt.number().optional(),totalBytes:nt.number().optional(),packageSpec:nt.string().optional()}),ta="hydra-acp/agents/install_progress",Mt={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function na(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:E.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
- `;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 ff}from"nanoid";var Tr=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},st=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;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}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}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 Tr;let n=ff(),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?"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:E.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??E.InternalError,message:r.message,data:r.data}).catch(()=>{})}}handleNotification(e){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)}}};G();var mf=4096,rt=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??mf,this.killEscalationMs=e.killEscalationMs??hf,this.logger=e.logger,this.fileLog=yf(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()} ---
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 ff}from"nanoid";var Tr=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},st=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;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}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}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 Tr;let n=ff(),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?"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:E.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??E.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)}}};G();var mf=4096,rt=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??mf,this.killEscalationMs=e.killEscalationMs??hf,this.logger=e.logger,this.fileLog=yf(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()} ---
18
18
  `),!t.stdout||!t.stdin)throw new Error("agent subprocess missing stdio");let n=na(t.stdout,t.stdin);this.connection=new st(n),t.stderr?.setEncoding("utf8"),t.stderr?.on("data",r=>{if(this.stderrTail=(this.stderrTail+r).slice(-this.stderrTailBytes),this.writeLog(r),this.logger)for(let o of r.split(/\r?\n/))o.length>0&&this.logger.info(`[${e.agentId}] ${o}`);else process.stderr.write(`[${e.agentId}] ${r}`)}),t.on("error",r=>{let o=this.formatFailure(r.message);this.writeLog(`--- spawn error: ${r.message} time=${new Date().toISOString()} ---
19
19
  `),this.connection.fail(new Error(o))}),t.on("exit",(r,o)=>{if(this.exited=!0,this.writeLog(`--- exit code=${r} signal=${o} ${this.killed?"(after kill) ":""}time=${new Date().toISOString()} ---
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={...Bn(),...e.plan.env,...e.extraEnv??{}},n=Et(e.plan.command,e.plan.args),r=pf(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(sa),this.exited||this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} still has not exited ${sa}ms after SIGKILL; giving up on the reap`)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0){if(process.platform==="win32"){try{gf("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)})}},hf=2e3,sa=5e3;function yf(s){try{let e=x.agentLogFile(s);Kn.mkdirSync(ra.dirname(e),{recursive:!0});let t=Kn.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}import*as kt from"fs/promises";import*as $d from"os";import*as oa from"os";function an(){return oa.hostname()}import*as Rn from"path";import{customAlphabet as Pg}from"nanoid";var Be="session/set_model",Mr="session/set_config_option",da="model";function Pr(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.availableModels)}function ca(s){return Array.isArray(s)&&s.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===da)}function _t(s){if(!s)return;if(Pr(s)||Pr(s.models))return Be;let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,n]of Object.entries(e))if(t!=="hydra-acp"&&Pr(n))return Be}if(ca(s.configOptions))return Mr}function ua(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.sessionUpdate;if(e==="_hydra_current_model_update")return Be;if(e==="config_option_update"&&ca(s.configOptions))return Mr}function ia(s){return typeof s=="object"&&s!==null&&s.code===E.MethodNotFound}function aa(s,e,t,n){let r={...n??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,s===Be?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:da,value:t}}function wf(s){return s===Be?Mr:Be}async function ot(s){let{request:e,sessionId:t,modelId:n,extraParams:r,logger:o}=s,i=s.verb??Be;try{let a=await e(i,aa(i,t,n,r));return{verb:i,result:a}}catch(a){if(!ia(a))throw a;let d=wf(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(n)}`);try{let c=await e(d,aa(d,t,n,r));return{verb:d,result:c}}catch(c){throw ia(c)?a:c}}}async function gt(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 mt(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 ot({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}}}import{customAlphabet as Da}from"nanoid";function it(s){return`${s.name}:${s.localId}`}function ht(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 vf}from"crypto";function kf(s,e){return vf("sha256",s).update(e).digest("hex")}function _r(s,e){let t=JSON.stringify(e),n=kf(s.secret,t);fetch(s.callbackUrl,{method:"POST",headers:{"Content-Type":"application/json","X-Hydra-Turn-Notify-Signature":n},body:t}).catch(()=>{})}var la="edit",Qn=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 fa(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}import*as ga from"fs/promises";var bf=64*1024*1024,Sf=1*1024*1024,$t=64*1024,If=6e4,Af=100,Cf=1e3,Rf=64*1024,xf=256*1024,pa=20;function Ef(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Yn=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??bf,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Sf,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,$t));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,$t)),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,$t)),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,If));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(Ef(e.pattern),d),u=e.invert??!1,l=Math.max(1,Math.min(e.maxMatches??Af,Cf)),p=Math.max(1,Math.min(e.maxBytes??Rf,xf)),m=Math.max(0,Math.min(e.contextBefore??0,pa)),h=Math.max(0,Math.min(e.contextAfter??0,pa)),f=[],g=[],w=[],y=0,v=!1,b=0,S=0,k=(R,T)=>{for(let $ of w)$.remaining>0&&($.match.after===void 0&&($.match.after=[]),$.match.after.push({cursor:R,line:T}),$.remaining--,y+=T.length);for(;w.length>0&&w[0].remaining===0;)w.shift();if(c.test(T)!==u&&f.length<l){let $={cursor:R,line:T};if(m>0&&g.length>0){$.before=g.slice();for(let W of $.before)y+=W.line.length}y+=T.length,f.push($),h>0&&w.push({match:$,remaining:h})}if(m>0)for(g.push({cursor:R,line:T});g.length>m;)g.shift();let L=f.length>=l&&w.length===0,J=y>=p;return L||J};for(let R=0;R<i.length;R++){if(i[R]!==10)continue;let T=i.subarray(b,R).toString("utf8"),M=r+b;if(b=R+1,S=b,k(M,T)){v=!0;break}}if(!v&&b<i.length&&this.closed){let R=i.subarray(b).toString("utf8"),T=r+b;k(T,R)&&(v=!0),S=i.length}let C=Math.min(r+S,this.writeCursor),A={matches:f,truncated:v,nextCursor:C,scannedBytes:S};return o>0&&(A.gap=o),this.closed&&C>=this.writeCursor&&(A.eof=!0),A}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(()=>ga.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var Ft=[{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:"fork",name:"hydra fork",argsHint:"[verbatim]",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)"},{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."}],Nv=new Map(Ft.map(s=>[s.verb,s]));function ma(s){let e=s.lastIndexOf("/");return(e===-1?s:s.slice(e+1)).toLowerCase()}function Ot(s,e){return dn(s,e.map(t=>t.modelId))}function dn(s,e){if(e.length===0)return{kind:"none",requested:s};if(e.includes(s))return{kind:"exact",modelId:s};let t=ma(s),n=e.filter(o=>ma(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}}function ya(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=$r(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 $f){if(!ha(c[l]))continue;let p=n.get(u);p===void 0?n.set(u,new Map([[l,c[l]]])):p.set(l,c[l])}if(Array.isArray(c.content)&&c.content.length>0){let l=t.get(u);l?l.push(...c.content):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=$r(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?(Mf(r,o.outIndex,Tf(c.content)),Pf(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)?_f(d,t.get(l)??[]):d,m=l===void 0?void 0:n.get(l);if(m!==void 0)for(let[h,f]of m)ha($r(p)?.[h])||(p=Ff(p,h,f));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 $r(s){if(s.method!=="session/update")return;let t=s.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Tf(s){if(!s||typeof s!="object")return"";let e=s;return typeof e.text=="string"?e.text:""}function Pf(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 Mf(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 _f(s,e){let t=s.params??{},n=t.update??{};return{...s,params:{...t,update:{...n,content:e}}}}var $f=["rawInput","locations"];function ha(s){return s==null||typeof s!="object"?!1:Array.isArray(s)?s.length>0:Object.keys(s).length>0}function Ff(s,e,t){let n=s.params??{},r=n.update??{};return{...s,params:{...n,update:{...r,[e]:t}}}}var wa=`[older history truncated]
24
- `,va=["file_path","filePath","path","command","pattern","query"];function Nt(s,e={}){let t=e.maxChars??4e5,n=Fr(s),r=[],o="",i=e.toolOutput?.maxTotal??0,a=()=>{o.length!==0&&(r.push(`Assistant: ${o}`),o="")};for(let d of s){if(d.method!=="session/update")continue;let u=d.params?.update;if(!u||typeof u.sessionUpdate!="string")continue;let l=u.sessionUpdate;if(l==="prompt_received"){a();let p=jr(u.prompt).trim();p.length>0&&r.push(`User: ${p}`)}else if(l==="agent_message_chunk"){let p=Lr(u.content);p.length>0&&(o+=p)}else if(l==="tool_call"){if(a(),r.push(Dr(u,n)),e.toolOutput!==void 0){let p=Nr(u),m=p!==void 0?n.get(p)?.output:void 0;if(m!==void 0&&i>0){let h=Math.min(e.toolOutput.maxPerCall,i),f=m.length<=h?m:`${m.slice(0,h)}\u2026[${m.length-h} more chars]`;r.push(`Output: ${f}`),i-=Math.min(f.length,h)}}}else l==="turn_complete"&&a()}return a(),Uf(r.join(`
23
+ `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(sa),this.exited||this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} still has not exited ${sa}ms after SIGKILL; giving up on the reap`)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0){if(process.platform==="win32"){try{gf("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)})}},hf=2e3,sa=5e3;function yf(s){try{let e=x.agentLogFile(s);Kn.mkdirSync(ra.dirname(e),{recursive:!0});let t=Kn.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}import*as kt from"fs/promises";import*as $d from"os";import*as oa from"os";function an(){return oa.hostname()}import*as Rn from"path";import{customAlphabet as Pg}from"nanoid";var Be="session/set_model",Mr="session/set_config_option",da="model";function Pr(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.availableModels)}function ca(s){return Array.isArray(s)&&s.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===da)}function _t(s){if(!s)return;if(Pr(s)||Pr(s.models))return Be;let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,n]of Object.entries(e))if(t!=="hydra-acp"&&Pr(n))return Be}if(ca(s.configOptions))return Mr}function ua(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.sessionUpdate;if(e==="_hydra_current_model_update")return Be;if(e==="config_option_update"&&ca(s.configOptions))return Mr}function ia(s){return typeof s=="object"&&s!==null&&s.code===E.MethodNotFound}function aa(s,e,t,n){let r={...n??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,s===Be?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:da,value:t}}function wf(s){return s===Be?Mr:Be}async function ot(s){let{request:e,sessionId:t,modelId:n,extraParams:r,logger:o}=s,i=s.verb??Be;try{let a=await e(i,aa(i,t,n,r));return{verb:i,result:a}}catch(a){if(!ia(a))throw a;let d=wf(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(n)}`);try{let c=await e(d,aa(d,t,n,r));return{verb:d,result:c}}catch(c){throw ia(c)?a:c}}}async function gt(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 mt(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 ot({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}}}import{customAlphabet as Da}from"nanoid";function it(s){return`${s.name}:${s.localId}`}function ht(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 vf}from"crypto";function kf(s,e){return vf("sha256",s).update(e).digest("hex")}function _r(s,e){let t=JSON.stringify(e),n=kf(s.secret,t);fetch(s.callbackUrl,{method:"POST",headers:{"Content-Type":"application/json","X-Hydra-Turn-Notify-Signature":n},body:t}).catch(()=>{})}var la="edit",Qn=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 fa(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}import*as ga from"fs/promises";var bf=64*1024*1024,Sf=1*1024*1024,$t=64*1024,If=6e4,Af=100,Cf=1e3,Rf=64*1024,xf=256*1024,pa=20;function Ef(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Yn=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??bf,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Sf,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,$t));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,$t)),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,$t)),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,If));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(Ef(e.pattern),d),u=e.invert??!1,l=Math.max(1,Math.min(e.maxMatches??Af,Cf)),p=Math.max(1,Math.min(e.maxBytes??Rf,xf)),m=Math.max(0,Math.min(e.contextBefore??0,pa)),h=Math.max(0,Math.min(e.contextAfter??0,pa)),f=[],g=[],w=[],y=0,v=!1,b=0,S=0,k=(R,T)=>{for(let $ of w)$.remaining>0&&($.match.after===void 0&&($.match.after=[]),$.match.after.push({cursor:R,line:T}),$.remaining--,y+=T.length);for(;w.length>0&&w[0].remaining===0;)w.shift();if(c.test(T)!==u&&f.length<l){let $={cursor:R,line:T};if(m>0&&g.length>0){$.before=g.slice();for(let W of $.before)y+=W.line.length}y+=T.length,f.push($),h>0&&w.push({match:$,remaining:h})}if(m>0)for(g.push({cursor:R,line:T});g.length>m;)g.shift();let H=f.length>=l&&w.length===0,J=y>=p;return H||J};for(let R=0;R<i.length;R++){if(i[R]!==10)continue;let T=i.subarray(b,R).toString("utf8"),M=r+b;if(b=R+1,S=b,k(M,T)){v=!0;break}}if(!v&&b<i.length&&this.closed){let R=i.subarray(b).toString("utf8"),T=r+b;k(T,R)&&(v=!0),S=i.length}let C=Math.min(r+S,this.writeCursor),A={matches:f,truncated:v,nextCursor:C,scannedBytes:S};return o>0&&(A.gap=o),this.closed&&C>=this.writeCursor&&(A.eof=!0),A}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(()=>ga.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var Ft=[{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:"fork",name:"hydra fork",argsHint:"[verbatim]",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)"},{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."}],Nv=new Map(Ft.map(s=>[s.verb,s]));function ma(s){let e=s.lastIndexOf("/");return(e===-1?s:s.slice(e+1)).toLowerCase()}function Ot(s,e){return dn(s,e.map(t=>t.modelId))}function dn(s,e){if(e.length===0)return{kind:"none",requested:s};if(e.includes(s))return{kind:"exact",modelId:s};let t=ma(s),n=e.filter(o=>ma(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}}function ya(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=$r(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 $f){if(!ha(c[l]))continue;let p=n.get(u);p===void 0?n.set(u,new Map([[l,c[l]]])):p.set(l,c[l])}if(Array.isArray(c.content)&&c.content.length>0){let l=t.get(u);l?l.push(...c.content):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=$r(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?(Mf(r,o.outIndex,Tf(c.content)),Pf(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)?_f(d,t.get(l)??[]):d,m=l===void 0?void 0:n.get(l);if(m!==void 0)for(let[h,f]of m)ha($r(p)?.[h])||(p=Ff(p,h,f));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 $r(s){if(s.method!=="session/update")return;let t=s.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Tf(s){if(!s||typeof s!="object")return"";let e=s;return typeof e.text=="string"?e.text:""}function Pf(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 Mf(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 _f(s,e){let t=s.params??{},n=t.update??{};return{...s,params:{...t,update:{...n,content:e}}}}var $f=["rawInput","locations"];function ha(s){return s==null||typeof s!="object"?!1:Array.isArray(s)?s.length>0:Object.keys(s).length>0}function Ff(s,e,t){let n=s.params??{},r=n.update??{};return{...s,params:{...n,update:{...r,[e]:t}}}}var wa=`[older history truncated]
24
+ `,va=["file_path","filePath","path","command","pattern","query"];function Nt(s,e={}){let t=e.maxChars??4e5,n=Fr(s),r=[],o="",i=e.toolOutput?.maxTotal??0,a=()=>{o.length!==0&&(r.push(`Assistant: ${o}`),o="")};for(let d of s){if(d.method!=="session/update")continue;let u=d.params?.update;if(!u||typeof u.sessionUpdate!="string")continue;let l=u.sessionUpdate;if(l==="prompt_received"){a();let p=jr(u.prompt).trim();p.length>0&&r.push(`User: ${p}`)}else if(l==="agent_message_chunk"){let p=Hr(u.content);p.length>0&&(o+=p)}else if(l==="tool_call"){if(a(),r.push(Dr(u,n)),e.toolOutput!==void 0){let p=Nr(u),m=p!==void 0?n.get(p)?.output:void 0;if(m!==void 0&&i>0){let h=Math.min(e.toolOutput.maxPerCall,i),f=m.length<=h?m:`${m.slice(0,h)}\u2026[${m.length-h} more chars]`;r.push(`Output: ${f}`),i-=Math.min(f.length,h)}}}else l==="turn_complete"&&a()}return a(),Uf(r.join(`
25
25
  `),t)}function Fr(s){let e=new Map;for(let t of s){if(t.method!=="session/update")continue;let r=t.params?.update;if(!r)continue;let o=r.sessionUpdate;if(o!=="tool_call"&&o!=="tool_call_update")continue;let i=Nr(r);if(i===void 0)continue;let a=e.get(i);if(a===void 0&&(a={name:"(unnamed)",rawInput:{}},e.set(i,a)),a.name==="(unnamed)"){let c=Nf(r,o);c!==void 0&&(a.name=c)}if(a.kind===void 0&&typeof r.kind=="string"&&r.kind.length>0&&(a.kind=r.kind),a.output===void 0){let c=Xn(r);c!==void 0&&(a.output=c)}let d=r.rawInput;d&&typeof d=="object"&&!Array.isArray(d)&&Object.assign(a.rawInput,d)}for(let t of e.values())t.name=Or(t);return e}function Or(s){return Of(s)?s.kind??"(unnamed)":s.name}function Of(s){for(let e of va){let t=s.rawInput[e];if(!(typeof t!="string"||t.length===0)&&(t===s.name||s.name.length>=12&&t.startsWith(s.name)))return!0}return!1}function Nf(s,e){let t=cn(s);if(t!==void 0)return t;if(typeof s.name=="string"&&s.name.length>0)return s.name;if(e==="tool_call"&&typeof s.title=="string"&&s.title.length>0)return s.title}function Nr(s){let e=s.toolCallId;if(typeof e=="string"&&e.length>0)return e}function Xn(s){let e=Df(s);if(e!==void 0)return e;let t=s.rawOutput;if(typeof t=="string")return t.length>0?t:void 0;if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t.output;if(typeof n=="string")return n.length>0?n:void 0}}function Df(s){let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.toolResponse;if(typeof n=="string")return n.length>0?n:void 0;if(!n||typeof n!="object")return;let{stdout:r,stderr:o}=n,i=[];if(typeof r=="string"&&r.length>0&&i.push(r),typeof o=="string"&&o.length>0&&i.push(`[stderr] ${o}`),i.length!==0)return i.join(`
26
- `)}function cn(s){let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.toolName;if(typeof n=="string"&&n.length>0)return n}function Dr(s,e){let t=Nr(s),n=t!==void 0?e?.get(t):void 0,r=n?.name??jf(s),o=Lf(n?.rawInput??s.rawInput);return o.length===0?`Tool: ${r}`:`Tool: ${r}(${o.join(", ")})`}function jf(s){let e=cn(s);return e!==void 0?e:typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function Lf(s){if(!s||typeof s!="object"||Array.isArray(s))return[];let e=s,t=[];for(let n of va){let r=e[n];typeof r=="string"&&r.length>0&&t.push(`${n}=${Hf(r,600)}`)}return t}function jr(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>{if(e&&typeof e=="object"){let t=e.text;if(typeof t=="string")return t}return""}).join(""):""}function Lr(s){if(!s||typeof s!="object")return"";let e=s.text;return typeof e=="string"?e:""}function Hf(s,e){return s.length<=e?s:s.slice(0,e-1)+"\u2026"}function Uf(s,e){if(s.length<=e)return s;let t=s.split(`
26
+ `)}function cn(s){let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.toolName;if(typeof n=="string"&&n.length>0)return n}function Dr(s,e){let t=Nr(s),n=t!==void 0?e?.get(t):void 0,r=n?.name??jf(s),o=Hf(n?.rawInput??s.rawInput);return o.length===0?`Tool: ${r}`:`Tool: ${r}(${o.join(", ")})`}function jf(s){let e=cn(s);return e!==void 0?e:typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function Hf(s){if(!s||typeof s!="object"||Array.isArray(s))return[];let e=s,t=[];for(let n of va){let r=e[n];typeof r=="string"&&r.length>0&&t.push(`${n}=${Lf(r,600)}`)}return t}function jr(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>{if(e&&typeof e=="object"){let t=e.text;if(typeof t=="string")return t}return""}).join(""):""}function Hr(s){if(!s||typeof s!="object")return"";let e=s.text;return typeof e=="string"?e:""}function Lf(s,e){return s.length<=e?s:s.slice(0,e-1)+"\u2026"}function Uf(s,e){if(s.length<=e)return s;let t=s.split(`
27
27
  `);for(;t.length>0;){let n=wa+t.join(`
28
- `);if(n.length<=e)return n;t.shift()}return wa}var ka="(untitled)";function Hr(s){let e=[],t=s.synopsis;if(t!==void 0){e.push("--- begin prior session compaction ---"),e.push(`[Title] ${s.title??ka}`),t.goal!==void 0&&t.goal.trim().length>0&&e.push(`[Goal] ${t.goal}`),t.outcome!==void 0&&t.outcome.trim().length>0&&e.push(`[Outcome] ${t.outcome}`);let d=un("Open threads",t.open_threads);d.length>0&&e.push(d);let c=un("Decisions",t.decisions);c.length>0&&e.push(c);let u=un("File edit intentions",t.file_edit_intentions);u.length>0&&e.push(u);let l=un("Unresolved errors",t.unresolved_errors);l.length>0&&e.push(l);let p=un("Tool state",t.tool_state);p.length>0&&e.push(p);let m=ba(t.files_touched);m.length>0&&e.push(`[Files previously touched] ${m}`);let h=ba(t.tools_used);h.length>0&&e.push(`[Tools previously used] ${h}`),e.push("--- end prior session compaction ---")}else e.push(`[Title] ${s.title??ka}`);s.note!==void 0&&s.note.trim().length>0&&e.push(`[Situation] ${s.note.trim()}`);let{closedText:n,openText:r,keptCount:o}=Bf(s.tail,s.tailK,s.watermark??0,s.tailFloor??0);e.push("--- begin recent turns (verbatim, last "+o+") ---"),n.length>0&&e.push(n),e.push("--- end recent turns ---"),r.length>0&&(e.push("--- begin current in-flight turn (no completion yet) ---"),e.push(r),e.push("--- end current in-flight turn ---"));let i=s.recallArmed??!0;e.push("");let a=s.framing??(t!==void 0?"compaction":"fork");return a==="swap"?e.push(i?"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)":"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):a==="compaction"&&i?e.push("(Hydra has compacted earlier conversation. Do NOT call any tools yet. Do NOT read any files, run any commands, or invoke hydra-recall. Reply with the single word 'OK' and wait for the next user message \u2014 at that point you can use the hydra-recall tools to look up specifics on demand if needed.)"):a==="compaction"?e.push("(Hydra has compacted earlier conversation; the turns above are what survives. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):i?e.push("(This is a side conversation forked from another session. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):e.push("(This is a side conversation forked from another session. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"),e.join(`
28
+ `);if(n.length<=e)return n;t.shift()}return wa}var ka="(untitled)";function Lr(s){let e=[],t=s.synopsis;if(t!==void 0){e.push("--- begin prior session compaction ---"),e.push(`[Title] ${s.title??ka}`),t.goal!==void 0&&t.goal.trim().length>0&&e.push(`[Goal] ${t.goal}`),t.outcome!==void 0&&t.outcome.trim().length>0&&e.push(`[Outcome] ${t.outcome}`);let d=un("Open threads",t.open_threads);d.length>0&&e.push(d);let c=un("Decisions",t.decisions);c.length>0&&e.push(c);let u=un("File edit intentions",t.file_edit_intentions);u.length>0&&e.push(u);let l=un("Unresolved errors",t.unresolved_errors);l.length>0&&e.push(l);let p=un("Tool state",t.tool_state);p.length>0&&e.push(p);let m=ba(t.files_touched);m.length>0&&e.push(`[Files previously touched] ${m}`);let h=ba(t.tools_used);h.length>0&&e.push(`[Tools previously used] ${h}`),e.push("--- end prior session compaction ---")}else e.push(`[Title] ${s.title??ka}`);s.note!==void 0&&s.note.trim().length>0&&e.push(`[Situation] ${s.note.trim()}`);let{closedText:n,openText:r,keptCount:o}=Bf(s.tail,s.tailK,s.watermark??0,s.tailFloor??0);e.push("--- begin recent turns (verbatim, last "+o+") ---"),n.length>0&&e.push(n),e.push("--- end recent turns ---"),r.length>0&&(e.push("--- begin current in-flight turn (no completion yet) ---"),e.push(r),e.push("--- end current in-flight turn ---"));let i=s.recallArmed??!0;e.push("");let a=s.framing??(t!==void 0?"compaction":"fork");return a==="swap"?e.push(i?"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)":"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):a==="compaction"&&i?e.push("(Hydra has compacted earlier conversation. Do NOT call any tools yet. Do NOT read any files, run any commands, or invoke hydra-recall. Reply with the single word 'OK' and wait for the next user message \u2014 at that point you can use the hydra-recall tools to look up specifics on demand if needed.)"):a==="compaction"?e.push("(Hydra has compacted earlier conversation; the turns above are what survives. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):i?e.push("(This is a side conversation forked from another session. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):e.push("(This is a side conversation forked from another session. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"),e.join(`
29
29
  `)}function un(s,e){if(!e||!Array.isArray(e))return"";let t=e.filter(r=>typeof r=="string"&&r.trim().length>0);if(t.length===0)return"";let n=t.map(r=>"- "+r.trim());return`[${s}] ${n.join(`
30
30
  `)}`}function ba(s){if(!s||!Array.isArray(s))return"";let e=s.filter(t=>typeof t=="string"&&t.trim().length>0);return e.length===0?"":e.map(t=>t.trim()).join(", ")}function Bf(s,e,t,n){if(s.length===0)return{closedText:"",openText:"",keptCount:0};let{closed:r,open:o}=Wf(s),i=0,a=[];if(e>0&&r.length>0){let u=r.filter(m=>m.startEntryIndex>=t).length,l=Math.max(u,n),p=Math.min(l,e,r.length);i=p,a=p>0?r.slice(-p):[]}let d=a.length>0?Sa(a):"",c=o?Sa([o]):"";return{closedText:d,openText:c,keptCount:i}}function Sa(s){let e=[];for(let t of s){t.user.length>0&&e.push("User: "+t.user),t.agent.length>0&&e.push("Assistant: "+t.agent);for(let n of t.tools)e.push(n)}return e.join(`
31
- `)}function Wf(s){let e=[],t=null,n=Fr(s);for(let o=0;o<s.length;o++){let i=s[o];if(i.method!=="session/update")continue;let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate;if(c==="prompt_received")t!==null&&t.user.length>0&&e.push(t),t={user:jr(d.prompt).trim(),agent:"",tools:[],startEntryIndex:o};else if(c==="agent_message_chunk"&&t!==null){let u=Lr(d.content);u.length>0&&(t.agent+=u)}else c==="tool_call"&&t!==null?t.tools.push(Dr(d,n)):c==="turn_complete"&&t!==null&&(e.push(t),t=null)}let r=t!==null&&t.user.length>0?t:null;return{closed:e,open:r}}function Aa(s,e){let t=s??[],n=(e??0)>0,r=[],o=new Set,i=t[0];i&&o.add(i.upstreamSessionId);for(let d=1;d<t.length;d++){let c=t[d],u=t[d-1],l={upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,...c.startedAt!==void 0?{at:c.startedAt}:{},...c.endedAt!==void 0?{endedAt:c.endedAt}:{},...c.cost!==void 0?{cost:c.cost}:{},...c.usedAtStart!==void 0?{usedAfter:c.usedAtStart}:{},...u.usedAtEnd!==void 0?{usedBefore:u.usedAtEnd}:{},...c.reason!==void 0?{reason:c.reason}:{},...c.runId!==void 0?{runId:c.runId}:{}};c.reason===void 0&&(c.agentId!==u.agentId?l.inferredReason="agent-swap":o.has(c.upstreamSessionId)?l.inferredReason="rollback":n||(l.notCompaction=!0)),o.add(c.upstreamSessionId),r.push(l)}let a=r.filter(d=>d.reason==="compaction");return{rotations:r,compactions:a,runs:qf(a),unknownCount:r.filter(d=>d.reason===void 0&&d.inferredReason===void 0&&!d.notCompaction).length}}function qf(s){let e=[],t;for(let n of s){let r=e[e.length-1];if(r!==void 0&&n.runId!==void 0&&n.runId===t){r.swaps++,r.upstreamSessionId=n.upstreamSessionId,r.current=n.endedAt===void 0,n.cost!==void 0&&(r.cost=(r.cost??0)+n.cost),n.usedAfter!==void 0&&(r.usedAfter=n.usedAfter);continue}e.push({...n.at!==void 0?{at:n.at}:{},upstreamSessionId:n.upstreamSessionId,swaps:1,...n.cost!==void 0?{cost:n.cost}:{},...n.usedBefore!==void 0?{usedBefore:n.usedBefore}:{},...n.usedAfter!==void 0?{usedAfter:n.usedAfter}:{},current:n.endedAt===void 0}),t=n.runId}return e}function zf(s){if(!s)return"unknown time";let e=Date.parse(s);return Number.isNaN(e)?"unknown time":`${new Date(e).toISOString().slice(0,16)}Z`}function Ia(s){if(s<1e3)return String(s);let e=s/1e3;return e<100?`${e.toFixed(1)}k`:`${Math.round(e)}k`}function Jf(s){return s.usedBefore===void 0||s.usedAfter===void 0?"":` ${Ia(s.usedBefore)} \u2192 ${Ia(s.usedAfter)}`}function Ca(s){let{runs:e,unknownCount:t}=s,n=[];if(e.length>0){n.push(e.length===1?"Compacted 1 time:":`Compacted ${e.length} times:`);for(let r of e){let o=Jf(r),i=r.cost!==void 0?` $${r.cost.toFixed(2)}`:"",a=r.current?" (current)":"",d=r.swaps>1?` (${r.swaps} swaps)`:"";n.push(` ${zf(r.at)} ${r.upstreamSessionId}${o}${i}${d}${a}`)}}if(t>0){let r=t===1?"rotation":"rotations";n.push(e.length>0?`${t} earlier ${r}, cause not recorded; the count above is a lower bound.`:`No compactions on record. ${t} ${r} predate reason tracking, and any of them may have been a compaction.`)}return n}import*as at from"path";function Vf(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ur(s,e,t){if(e.length===0||e===t)return{text:s,rewritten:[]};let n=e.endsWith("/")?e.slice(0,-1):e,r=t.endsWith("/")?t.slice(0,-1):t,o=[],i=new RegExp(`${Vf(n)}/(?![/\\s])`,"g");return{text:s.replace(i,(d,c)=>{let u=s.slice(c+d.length),l=u.search(/[\s"'`,;:)\]}]|$/);return o.push(`${n}/${u.slice(0,l<0?void 0:l)}`),`${r}/`}),rewritten:o}}function Br(s,e){if(e.length===0)return!1;let t=e.endsWith("/")?e.slice(0,-1):e;return s.includes(t)}function Ra(s){let e=[];return e.push("[workspace] You have LEFT the isolated workspace."),e.push(`- Your working directory is now ${s.sourceCwd}`),e.push(s.removed?`- The workspace at ${s.formerWorkspacePath} has been removed. Paths under it from earlier in this conversation no longer exist.`:`- The workspace at ${s.formerWorkspacePath} still exists but is NO LONGER YOURS. Editing anything under it is wasted: that work will not reach ${s.sourceCwd}.`),e.push("- Earlier turns refer to files by their workspace paths. Treat those as referring to the same files under your current working directory, and prefer repo-relative paths from here on."),e.join(`
31
+ `)}function Wf(s){let e=[],t=null,n=Fr(s);for(let o=0;o<s.length;o++){let i=s[o];if(i.method!=="session/update")continue;let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate;if(c==="prompt_received")t!==null&&t.user.length>0&&e.push(t),t={user:jr(d.prompt).trim(),agent:"",tools:[],startEntryIndex:o};else if(c==="agent_message_chunk"&&t!==null){let u=Hr(d.content);u.length>0&&(t.agent+=u)}else c==="tool_call"&&t!==null?t.tools.push(Dr(d,n)):c==="turn_complete"&&t!==null&&(e.push(t),t=null)}let r=t!==null&&t.user.length>0?t:null;return{closed:e,open:r}}function Aa(s,e){let t=s??[],n=(e??0)>0,r=[],o=new Set,i=t[0];i&&o.add(i.upstreamSessionId);for(let d=1;d<t.length;d++){let c=t[d],u=t[d-1],l={upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,...c.startedAt!==void 0?{at:c.startedAt}:{},...c.endedAt!==void 0?{endedAt:c.endedAt}:{},...c.cost!==void 0?{cost:c.cost}:{},...c.usedAtStart!==void 0?{usedAfter:c.usedAtStart}:{},...u.usedAtEnd!==void 0?{usedBefore:u.usedAtEnd}:{},...c.reason!==void 0?{reason:c.reason}:{},...c.runId!==void 0?{runId:c.runId}:{}};c.reason===void 0&&(c.agentId!==u.agentId?l.inferredReason="agent-swap":o.has(c.upstreamSessionId)?l.inferredReason="rollback":n||(l.notCompaction=!0)),o.add(c.upstreamSessionId),r.push(l)}let a=r.filter(d=>d.reason==="compaction");return{rotations:r,compactions:a,runs:qf(a),unknownCount:r.filter(d=>d.reason===void 0&&d.inferredReason===void 0&&!d.notCompaction).length}}function qf(s){let e=[],t;for(let n of s){let r=e[e.length-1];if(r!==void 0&&n.runId!==void 0&&n.runId===t){r.swaps++,r.upstreamSessionId=n.upstreamSessionId,r.current=n.endedAt===void 0,n.cost!==void 0&&(r.cost=(r.cost??0)+n.cost),n.usedAfter!==void 0&&(r.usedAfter=n.usedAfter);continue}e.push({...n.at!==void 0?{at:n.at}:{},upstreamSessionId:n.upstreamSessionId,swaps:1,...n.cost!==void 0?{cost:n.cost}:{},...n.usedBefore!==void 0?{usedBefore:n.usedBefore}:{},...n.usedAfter!==void 0?{usedAfter:n.usedAfter}:{},current:n.endedAt===void 0}),t=n.runId}return e}function zf(s){if(!s)return"unknown time";let e=Date.parse(s);return Number.isNaN(e)?"unknown time":`${new Date(e).toISOString().slice(0,16)}Z`}function Ia(s){if(s<1e3)return String(s);let e=s/1e3;return e<100?`${e.toFixed(1)}k`:`${Math.round(e)}k`}function Jf(s){return s.usedBefore===void 0||s.usedAfter===void 0?"":` ${Ia(s.usedBefore)} \u2192 ${Ia(s.usedAfter)}`}function Ca(s){let{runs:e,unknownCount:t}=s,n=[];if(e.length>0){n.push(e.length===1?"Compacted 1 time:":`Compacted ${e.length} times:`);for(let r of e){let o=Jf(r),i=r.cost!==void 0?` $${r.cost.toFixed(2)}`:"",a=r.current?" (current)":"",d=r.swaps>1?` (${r.swaps} swaps)`:"";n.push(` ${zf(r.at)} ${r.upstreamSessionId}${o}${i}${d}${a}`)}}if(t>0){let r=t===1?"rotation":"rotations";n.push(e.length>0?`${t} earlier ${r}, cause not recorded; the count above is a lower bound.`:`No compactions on record. ${t} ${r} predate reason tracking, and any of them may have been a compaction.`)}return n}import*as at from"path";function Vf(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ur(s,e,t){if(e.length===0||e===t)return{text:s,rewritten:[]};let n=e.endsWith("/")?e.slice(0,-1):e,r=t.endsWith("/")?t.slice(0,-1):t,o=[],i=new RegExp(`${Vf(n)}/(?![/\\s])`,"g");return{text:s.replace(i,(d,c)=>{let u=s.slice(c+d.length),l=u.search(/[\s"'`,;:)\]}]|$/);return o.push(`${n}/${u.slice(0,l<0?void 0:l)}`),`${r}/`}),rewritten:o}}function Br(s,e){if(e.length===0)return!1;let t=e.endsWith("/")?e.slice(0,-1):e;return s.includes(t)}function Ra(s){let e=[];return e.push("[workspace] You have LEFT the isolated workspace."),e.push(`- Your working directory is now ${s.sourceCwd}`),e.push(s.removed?`- The workspace at ${s.formerWorkspacePath} has been removed. Paths under it from earlier in this conversation no longer exist.`:`- The workspace at ${s.formerWorkspacePath} still exists but is NO LONGER YOURS. Editing anything under it is wasted: that work will not reach ${s.sourceCwd}.`),e.push("- Earlier turns refer to files by their workspace paths. Treat those as referring to the same files under your current working directory, and prefer repo-relative paths from here on."),e.join(`
32
32
  `)}function xa(s){let e=[];e.push(s.reassert===!0?"[workspace] Reminder: you are NOT working in the directory that path names.":"[workspace] Before anything else, note where you are working:"),e.push(`- Your working directory is ${s.workspacePath}`),e.push(`- It is an isolated copy of ${s.sourceCwd}`),e.push(`- Any absolute path under ${s.sourceCwd} refers to the matching file under your working directory. Do not read or write ${s.sourceCwd} directly.`),e.push("- Prefer repo-relative paths (`src/foo.ts`). They are identical in both trees, so they cannot be misread.");for(let t of s.notes)e.push(`- ${t}`);return e.join(`
33
33
  `)}function Ea(s,e,t){return s.length===0||!at.isAbsolute(s)||Zn(s,t)?!1:Zn(s,e)}function Zn(s,e){let t=at.relative(at.resolve(e),at.resolve(s));return!(t.length===0||t.startsWith("..")||at.isAbsolute(t))}G();import*as We from"fs/promises";async function ln(s,e){let t=x.queueFile(s);if(e.length===0){await We.unlink(t).catch(()=>{});return}await We.mkdir(x.sessionDir(s),{recursive:!0});let n=e.map(r=>JSON.stringify(r)).join(`
34
34
  `)+`
35
35
  `;await We.writeFile(t,n,"utf8")}async function Ta(s){let e=x.queueFile(s),t;try{t=await We.readFile(e,"utf8")}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t.split(`
36
- `))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 Pa(s){let e=x.queueFile(s);await We.unlink(e).catch(()=>{})}import*as Ha from"fs/promises";var ja="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",La=Da(ja,16),Wr=Da(ja,16),Gf=20,Kf=20,Qf=5,Yf=32,Ae="hydra_session_";function qe(){return`m_${La()}`}function Qe(s){let e=ht(s)?.localId??s;return e.startsWith(Ae)?e.slice(Ae.length):e}var Ma=["start","merge","apply","sync","stop","detach","discard","clean","status"],Xf=1e3,es=300*1e3,Zf=64,ep=new Set(["task-notification","peer","coordinator","observer","observer-activity"]);function tp(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"&&ep.has(r)}function _a(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="usage_update"}function np(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 $a=120,sp=128,rp=new Set(["local_bash"]),op=1e3,Dt=class s{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=Be;modelVerbConfirmed=!1;agentArgs;parentSessionId;forkedFromSessionId;forkedFromMessageId;forkSynthesisState;originatingClient;_interactive;get interactive(){return this._interactive}_priority;get priority(){return this._priority}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;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;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}_titleSeedPending=!0;_upstreamRespawned=!1;promptStartedAt;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;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 Qn;filesEditedSeen=new Set;openToolCalls=new Set;agentChangeHandlers=[];retiringGenerationCost;retiringGenerationUsed;rotationLifetimeCost;agentAdvertisedCommands=[];agentAdvertisedModes=[];agentAdvertisedModels=[];agentAdvertisedConfigOptions=[];agentCommandsHandlers=[];agentModesHandlers=[];agentModelsHandlers=[];availableAgentsFn;modelHandlers=[];modeHandlers=[];interactiveHandlers=[];priorityHandlers=[];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??`${Ae}${La()}`,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.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),this._interactive=e.interactive,this._priority=e.priority,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??Xf,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){hp(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=Fa(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 u=n;u<this.transformChain.length;u++){let l=this.transformChain[u];if(t.has(l.name)||!l.intercepts.has(a))continue;let p=`t_${Wr()}`,m;try{m=await l.connection.request("hydra-acp/transformer/message",{token:p,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(f){this.logger?.warn(`transformer ${l.name} error on ${a}: ${f.message}`);continue}let h=m?.action??"continue";if(h==="stop")return;if(h==="processing"){let f=u,g=i,w=new Set(t),y=r;await new Promise(v=>{let b=setTimeout(()=>{this.pendingClaims.delete(p)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:p,transformerName:l.name}),this.runResponseChain(g,new Set([...w,l.name]),f+1,y).then(()=>v()).catch(()=>v()))},es);typeof b.unref=="function"&&b.unref(),this.pendingClaims.set(p,{resolve:()=>v(),timer:b,transformerName:l.name,method:y,envelope:g,chainIdx:f,originatedBy:w,side:"response"})});return}m?.payload&&typeof m.payload=="object"&&(i=m.payload),t.add(l.name)}if(r!=="session/update")return;this.noteAgentActivity(i);let d=yp(i);if(d!==null){this.setAgentAdvertisedCommands(d);return}let c=mp(i);if(c!==null){this.setAgentAdvertisedModes(c);return}if(this.noteModelVerbHint(ua(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",i)}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??[],m=await l({agentId:n,cwd:i,agentArgs:a,...d?{forwardedEnv:d}:{},mcpServers:p});if(this.accumulateAndResetCost(),this.cwd=i,this.wireAgent(m.agent,{respawn:!0}),!r){let M=await mt({agent:m.agent,upstreamSessionId:m.upstreamSessionId,persistedModel:c,agentReportedModel:m.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(M.result,"model"),await gt({agent:m.agent,upstreamSessionId:m.upstreamSessionId,persistedMode:u,agentReportedMode:m.initialMode,logger:this.logger})}m.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 f=Hr({...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 g,w;try{await m.agent.connection.request("session/prompt",{sessionId:m.upstreamSessionId,prompt:[{type:"text",text:f}]});let M=this.internalPromptCapture;g=M.lastUsed,w=M.lastSize,this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${f.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}g!==void 0&&(this.maybeApplyAgentUsage({update:{sessionUpdate:"usage_update",used:g,...w!==void 0?{size:w}:{}}}),this.broadcastCurrentUsage());let y=this.upstreamSessionId,v=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let b=this.agent;if(this.agent=m.agent,this.upstreamSessionId=m.upstreamSessionId,this.agentMeta=m.agentMeta,this.agentCapabilities=m.agentCapabilities,this.resetModelVerb(m.modelVerb),r&&(this.agentId=n,this.agentAdvertisedCommands=[],this.currentModel=m.initialModel,this.currentMode=m.initialMode,this.setAgentAdvertisedModels(m.initialModels??[]),this.setAgentAdvertisedModes(m.initialModes??[]),this.agentAdvertisedConfigOptions=m.initialConfigOptions??[]),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream",o,e.runId,g),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,...v!==void 0?{previousSummarizedThroughEntry:v}:{},...e.runId!==void 0?{runId:e.runId}:{}})}catch(M){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${M.message}`)}let S=await this.retireAgent(b,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 k=S.length>0?`
36
+ `))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 Pa(s){let e=x.queueFile(s);await We.unlink(e).catch(()=>{})}import*as La from"fs/promises";var ja="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ha=Da(ja,16),Wr=Da(ja,16),Gf=20,Kf=20,Qf=5,Yf=32,Ae="hydra_session_";function qe(){return`m_${Ha()}`}function Qe(s){let e=ht(s)?.localId??s;return e.startsWith(Ae)?e.slice(Ae.length):e}var Ma=["start","merge","apply","sync","stop","detach","discard","clean","status"],Xf=1e3,es=300*1e3,Zf=64,ep=new Set(["task-notification","peer","coordinator","observer","observer-activity"]);function tp(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"&&ep.has(r)}function _a(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="usage_update"}function np(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 $a=120,sp=128,rp=new Set(["local_bash"]),op=1e3,Dt=class s{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=Be;modelVerbConfirmed=!1;agentArgs;parentSessionId;forkedFromSessionId;forkedFromMessageId;forkSynthesisState;originatingClient;_interactive;get interactive(){return this._interactive}_priority;get priority(){return this._priority}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;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;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}_titleSeedPending=!0;_upstreamRespawned=!1;promptStartedAt;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;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 Qn;filesEditedSeen=new Set;openToolCalls=new Set;agentChangeHandlers=[];retiringGenerationCost;retiringGenerationUsed;rotationLifetimeCost;agentAdvertisedCommands=[];agentAdvertisedModes=[];agentAdvertisedModels=[];agentAdvertisedConfigOptions=[];agentCommandsHandlers=[];agentModesHandlers=[];agentModelsHandlers=[];availableAgentsFn;modelHandlers=[];modeHandlers=[];interactiveHandlers=[];priorityHandlers=[];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??`${Ae}${Ha()}`,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.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),this._interactive=e.interactive,this._priority=e.priority,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??Xf,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){hp(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=Fa(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 u=n;u<this.transformChain.length;u++){let l=this.transformChain[u];if(t.has(l.name)||!l.intercepts.has(a))continue;let p=`t_${Wr()}`,m;try{m=await l.connection.request("hydra-acp/transformer/message",{token:p,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(f){this.logger?.warn(`transformer ${l.name} error on ${a}: ${f.message}`);continue}let h=m?.action??"continue";if(h==="stop")return;if(h==="processing"){let f=u,g=i,w=new Set(t),y=r;await new Promise(v=>{let b=setTimeout(()=>{this.pendingClaims.delete(p)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:p,transformerName:l.name}),this.runResponseChain(g,new Set([...w,l.name]),f+1,y).then(()=>v()).catch(()=>v()))},es);typeof b.unref=="function"&&b.unref(),this.pendingClaims.set(p,{resolve:()=>v(),timer:b,transformerName:l.name,method:y,envelope:g,chainIdx:f,originatedBy:w,side:"response"})});return}m?.payload&&typeof m.payload=="object"&&(i=m.payload),t.add(l.name)}if(r!=="session/update")return;this.noteAgentActivity(i);let d=yp(i);if(d!==null){this.setAgentAdvertisedCommands(d);return}let c=mp(i);if(c!==null){this.setAgentAdvertisedModes(c);return}if(this.noteModelVerbHint(ua(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",i)}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??[],m=await l({agentId:n,cwd:i,agentArgs:a,...d?{forwardedEnv:d}:{},mcpServers:p});if(this.accumulateAndResetCost(),this.cwd=i,this.wireAgent(m.agent,{respawn:!0}),!r){let M=await mt({agent:m.agent,upstreamSessionId:m.upstreamSessionId,persistedModel:c,agentReportedModel:m.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(M.result,"model"),await gt({agent:m.agent,upstreamSessionId:m.upstreamSessionId,persistedMode:u,agentReportedMode:m.initialMode,logger:this.logger})}m.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 f=Lr({...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 g,w;try{await m.agent.connection.request("session/prompt",{sessionId:m.upstreamSessionId,prompt:[{type:"text",text:f}]});let M=this.internalPromptCapture;g=M.lastUsed,w=M.lastSize,this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${f.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}g!==void 0&&(this.maybeApplyAgentUsage({update:{sessionUpdate:"usage_update",used:g,...w!==void 0?{size:w}:{}}}),this.broadcastCurrentUsage());let y=this.upstreamSessionId,v=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let b=this.agent;if(this.agent=m.agent,this.upstreamSessionId=m.upstreamSessionId,this.agentMeta=m.agentMeta,this.agentCapabilities=m.agentCapabilities,this.resetModelVerb(m.modelVerb),r&&(this.agentId=n,this.agentAdvertisedCommands=[],this.currentModel=m.initialModel,this.currentMode=m.initialMode,this.setAgentAdvertisedModels(m.initialModels??[]),this.setAgentAdvertisedModes(m.initialModes??[]),this.agentAdvertisedConfigOptions=m.initialConfigOptions??[]),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream",o,e.runId,g),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,...v!==void 0?{previousSummarizedThroughEntry:v}:{},...e.runId!==void 0?{runId:e.runId}:{}})}catch(M){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${M.message}`)}let S=await this.retireAgent(b,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 k=S.length>0?`
37
37
  Stopped ${S.length} background task(s) with the previous agent: ${S.join(", ")}. Re-arm anything still needed.
38
38
  `:"",R=(e.reason==="workspace-enter"||e.reason==="workspace-leave"?"":r?`
39
39
  Switched to ${n}.
40
40
  `:`
41
41
  Compaction completed.
42
- `)+k,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 L of this.clients.values())L.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 mt({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedModel:d,agentReportedModel:u.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(l.result,"model"),await gt({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 mt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:t,agentReportedModel:r.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(o.result,"model"),await gt({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=Gf){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){if(c==="tool_call")r.add(u);else if(c==="tool_call_update"){let l=d.status;(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 be(new Error("session is closed"),E.SessionNotFound);if(this.clients.has(e.clientId))throw be(new Error(`client ${e.clientId} is already attached`),E.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=d=>t.raw?d:ya(d),r=t.historyLimit===0?1/0:t.historyLimit??this.historyMaxEntries,o=await this.getHistorySnapshot(t.toolContent??"inline",r===1/0?1/0:r*2),i=vp(o.filter(d=>!qr(d.method,d.params)),r),a=this.buildStateSnapshotReplay();if(e==="after_message"){let d=t.afterSeq!==void 0?kp(i,t.afterSeq):t.afterMessageId?ns(i,t.afterMessageId):-1;return d<0?{entries:[...a,...n(i)],appliedPolicy:"full"}:{entries:[...a,...n(i.slice(d+1))],appliedPolicy:"after_message"}}return{entries:[...a,...n(i)],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&&Zn(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}Ea(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=Oa(e,o=>Br(o,t.path)?(n=!0,Ur(o,t.path,t.sourceCwd).text):o);if(!this.departureNoteSent||n){let o=Ra({sourceCwd:t.sourceCwd,formerWorkspacePath:t.path,removed:t.removed});r=zr(r,`${o}
42
+ `)+k,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 mt({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedModel:d,agentReportedModel:u.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(l.result,"model"),await gt({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 mt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:t,agentReportedModel:r.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(o.result,"model"),await gt({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=Gf){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){if(c==="tool_call")r.add(u);else if(c==="tool_call_update"){let l=d.status;(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 be(new Error("session is closed"),E.SessionNotFound);if(this.clients.has(e.clientId))throw be(new Error(`client ${e.clientId} is already attached`),E.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=d=>t.raw?d:ya(d),r=t.historyLimit===0?1/0:t.historyLimit??this.historyMaxEntries,o=await this.getHistorySnapshot(t.toolContent??"inline",r===1/0?1/0:r*2),i=vp(o.filter(d=>!qr(d.method,d.params)),r),a=this.buildStateSnapshotReplay();if(e==="after_message"){let d=t.afterSeq!==void 0?kp(i,t.afterSeq):t.afterMessageId?ns(i,t.afterMessageId):-1;return d<0?{entries:[...a,...n(i)],appliedPolicy:"full"}:{entries:[...a,...n(i.slice(d+1))],appliedPolicy:"after_message"}}return{entries:[...a,...n(i)],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&&Zn(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}Ea(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=Oa(e,o=>Br(o,t.path)?(n=!0,Ur(o,t.path,t.sourceCwd).text):o);if(!this.departureNoteSent||n){let o=Ra({sourceCwd:t.sourceCwd,formerWorkspacePath:t.path,removed:t.removed});r=zr(r,`${o}
43
43
 
44
44
  `),this.departureNoteSent=!0}return r}applyWorkspacePromptRewrite(e){let t=this.workspace;if(t===void 0)return this.applyDepartedPromptRewrite(e);let n=!1,r=Oa(e,i=>Br(i,t.sourceCwd)?(n=!0,Ur(i,t.sourceCwd,t.path).text):i);if(!this.workspacePreambleSent||n){let i=xa({workspacePath:t.path,sourceCwd:t.sourceCwd,notes:this.workspaceNotes,...this.workspacePreambleSent?{reassert:!0}:{}});r=zr(r,`${i}
45
45
 
@@ -84,7 +84,7 @@ ${f}:
84
84
  `)}
85
85
  `},_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 be(new Error("/hydra agent requires an agent id"),E.InvalidParams);let r=(this.resolveAgentIdHook?await this.resolveAgentIdHook(t):void 0)??t;if(r===this.agentId)throw be(new Error(`already on agent ${r}`),E.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 be(new Error("agent restart not configured for this session"),E.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=Aa(n,t),o=Ca(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(`
86
86
  `)),{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(!Ma.includes(t))return this.emitExtensionReply(`Unknown workspace verb "${t}". Use one of: ${Ma.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;if(n==="verbatim")r="verbatim";else if(n==="synthesis"||n==="")r=void 0;else return this.emitExtensionReply(`Unknown fork argument: \`${n}\`. Use \`/hydra fork\` or \`/hydra fork verbatim\`.`),{stopReason:"end_turn"};try{let o={};if(r&&(o.mode=r),t&&this.historyStore){let d=await this.findMessageIdBefore(t).catch(()=>{});d&&(o.forkAt=d)}let a=(await this.forkHook(Object.keys(o).length>0?o:void 0)).sessionId.replace(/^hydra_session_/,"");this.emitExtensionReply(`Forked to [\`${a}\`](hydra://sessions/${a}).`)}catch(o){this.emitExtensionReply(`Fork failed: ${o instanceof Error?o.message:String(o)}`)}return{stopReason:"end_turn"}}async forceCancel(){if(this.closed||this.closing)throw be(new Error("session is closing"),E.SessionClosing);return this.lastCancelAt=0,this.forceCancelling=!0,await this.close({deleteRecord:!1,by:"force-cancel"}),{stopReason:"cancelled"}}async respawnAgent(){let e=this.spawnReplacementAgent,t=this.agentId,n=await this.buildSwitchTranscript(t),r=await e({agentId:t,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{}});this.accumulateAndResetCost(),this.wireAgent(r.agent,{respawn:!0});let o=this.agent;this.agent=r.agent,this.upstreamSessionId=r.upstreamSessionId,this.agentMeta=r.agentMeta,this.agentCapabilities=r.agentCapabilities,this.resetModelVerb(r.modelVerb),this.agentAdvertisedCommands=[],this.broadcastMergedCommands(),this.currentModel=r.initialModel,this.currentMode=r.initialMode,this.setAgentAdvertisedModels(r.initialModels??[]),this.setAgentAdvertisedModes(r.initialModes??[]),this.agentAdvertisedConfigOptions=r.initialConfigOptions??[],await this.retireAgent(o,"agent restart"),n&&await this.runInternalPrompt(n).catch(()=>{}),this.broadcastAgentSwitch(t,t),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 m=l.sessionUpdate;if(m==="prompt_received"){let h=yt(l.prompt);h&&n.push({speaker:"user",text:h})}else if(m==="agent_message_chunk"){let f=l.content?.text;f&&n.push({speaker:`agent: ${e}`,text:f})}else if(m==="tool_call"||m==="tool_call_update"){let h=l.status,f=l.title;(h==="completed"||h==="failed")&&n.push({speaker:"tool",text:`${f??"?"} ${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(`
87
- `)}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=Hr({synopsis:e,title:t,tail:n,tailK:Kf,tailFloor:Qf,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 Yn(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??$t,$t)),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=E.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),_r(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(()=>Pa(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(()=>Ha.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){if(n.sessionUpdate==="tool_call"){this.openToolCalls.add(r);return}n.sessionUpdate==="tool_call_update"&&(n.status==="completed"||n.status==="failed")&&this.openToolCalls.delete(r)}}closeOpenToolCalls(e){if(this.openToolCalls.size===0||this.closed)return;let t=[...this.openToolCalls];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:{[de]:{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===la&&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,m={path:l,toolCallId:o};typeof p=="number"&&(m.line=p),this.notifyChain("file.edited",m),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=!qr(e,r),i=o?wp(e,r):r,a=Date.now(),d=o?this.lastSeq=Math.max(this.lastSeq+1,a):void 0,c=o?Ue(He(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 be(new Error("no clients attached to handle permission request"),E.PermissionDenied);let n=this.rewriteForClient(e),r=Fa(n),o=qe(),{toolCall:i,options:a}=n??{};return new Promise((d,c)=>{let u=!1,l=[],p=0,m,h=this.sessionId,f=y=>{u||(u=!0,this.clearAttentionFlag("daemon",`permission:${o}`),this.permissionCallbacks.delete(o),y())},g=y=>y?.code===E.MethodNotFound;function w(y){if(u)return;let v=y.connection.request("session/request_permission",n);l.push({client:y}),p++,v.then(b=>{p--,f(()=>{let S=bp({toolCallId:r,result:b,resolver:y});for(let k of l)k.client.clientId!==y.clientId&&k.client.connection.notify("session/update",{sessionId:h,update:S}).catch(()=>{});d(b)})}).catch(b=>{if(p--,g(b)||(m=b),p===0&&!u){let S=m??be(new Error("no client handled permission request"),E.PermissionDenied);f(()=>c(S))}})}this.setAttentionFlag("daemon",`permission:${o}`,{kind:"permission",toolCall:i??null,options:a??null}),this.permissionCallbacks.set(o,w);for(let y of t)w(y)})}async enqueuePrompt(e,t){return new Promise((n,r)=>{let o={kind:"internal",messageId:qe(),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[de];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(()=>ln(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=yt(e.prompt).replace(/\s+$/,""),n=!t.includes(`
87
+ `)}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=Lr({synopsis:e,title:t,tail:n,tailK:Kf,tailFloor:Qf,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 Yn(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??$t,$t)),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=E.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),_r(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(()=>Pa(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(()=>La.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){if(n.sessionUpdate==="tool_call"){this.openToolCalls.add(r);return}n.sessionUpdate==="tool_call_update"&&(n.status==="completed"||n.status==="failed")&&this.openToolCalls.delete(r)}}closeOpenToolCalls(e){if(this.openToolCalls.size===0||this.closed)return;let t=[...this.openToolCalls];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:{[de]:{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===la&&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,m={path:l,toolCallId:o};typeof p=="number"&&(m.line=p),this.notifyChain("file.edited",m),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=!qr(e,r),i=o?wp(e,r):r,a=Date.now(),d=o?this.lastSeq=Math.max(this.lastSeq+1,a):void 0,c=o?Ue(Le(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 be(new Error("no clients attached to handle permission request"),E.PermissionDenied);let n=this.rewriteForClient(e),r=Fa(n),o=qe(),{toolCall:i,options:a}=n??{};return new Promise((d,c)=>{let u=!1,l=[],p=0,m,h=this.sessionId,f=y=>{u||(u=!0,this.clearAttentionFlag("daemon",`permission:${o}`),this.permissionCallbacks.delete(o),y())},g=y=>y?.code===E.MethodNotFound;function w(y){if(u)return;let v=y.connection.request("session/request_permission",n);l.push({client:y}),p++,v.then(b=>{p--,f(()=>{let S=bp({toolCallId:r,result:b,resolver:y});for(let k of l)k.client.clientId!==y.clientId&&k.client.connection.notify("session/update",{sessionId:h,update:S}).catch(()=>{});d(b)})}).catch(b=>{if(p--,g(b)||(m=b),p===0&&!u){let S=m??be(new Error("no client handled permission request"),E.PermissionDenied);f(()=>c(S))}})}this.setAttentionFlag("daemon",`permission:${o}`,{kind:"permission",toolCall:i??null,options:a??null}),this.permissionCallbacks.set(o,w);for(let y of t)w(y)})}async enqueuePrompt(e,t){return new Promise((n,r)=>{let o={kind:"internal",messageId:qe(),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[de];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(()=>ln(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=yt(e.prompt).replace(/\s+$/,""),n=!t.includes(`
88
88
  `)&&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;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);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=zr(e.prompt,Ap));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||!ap(r))throw 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()}}clearAmendIfMatches(e){this.amendInProgress?.cancelledMessageId===e&&(this.amendInProgress=void 0)}},ip=["session not found","the claude agent session has ended"];function ap(s){let e=s;if(e?.code!==E.InternalError)return!1;let t=e.data?.details,n=`${typeof e.message=="string"?e.message:""} ${typeof t=="string"?t:""}`.toLowerCase();return ip.some(r=>n.includes(r))}function be(s,e){return s.code=e,s}var dp=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 cp(s,e,t){return t?.run_in_background===!0?!1:e?.toolName==="Monitor"||s==="Monitor"||typeof e?.toolResponse?.taskId=="string"}function up(s){return typeof s!="string"?void 0:/Command running in background with ID: ([A-Za-z0-9_-]+)/.exec(s)?.[1]}function lp(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 qr(s,e){if(s!=="session/update")return!1;let n=(e??{}).update?.sessionUpdate;return typeof n=="string"&&dp.has(n)}function fp(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 pp(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 gp(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 fn(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 ts(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 Vr(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 mp(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 hp(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 yp(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 wp(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:qe()}}}function vp(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 kp(s,e){for(let t=s.length-1;t>=0;t--)if(s[t]?.seq===e)return t;return-1}function ns(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 Fa(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 bp(s){let e=Sp(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=Ip(s.resolver),t}function Sp(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 Ip(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 yt(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var Ap="\u200B";function Oa(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 zr(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 Jr(s){return s==="session/prompt"?{stopReason:"stopped"}:{}}function Cp(s){return s==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function Na(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}
89
89
  ${n.join(`
90
90
  `)}`}function Gr(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}}G();Ne();import*as Te from"fs/promises";import*as gk from"path";import{customAlphabet as Ep}from"nanoid";import{z as P}from"zod";import{z as jt}from"zod";var Rp=jt.object({source:jt.string(),reason:jt.string(),raisedAt:jt.number(),payload:jt.unknown()}),Ua=jt.array(Rp);import{z as Q}from"zod";var Ba=Q.object({status:Q.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:Q.number(),runId:Q.string().optional(),iter:Q.number().int().nonnegative().optional(),attempts:Q.number().int().nonnegative().optional(),lastError:Q.string().optional(),worker:Q.object({upstreamSessionId:Q.string(),pid:Q.number().int().nonnegative()}).optional()}),pn=Q.object({goal:Q.string().optional(),outcome:Q.string().optional(),files_touched:Q.array(Q.string()).optional(),tools_used:Q.array(Q.string()).optional(),rejected_approaches:Q.array(Q.string()).optional(),open_threads:Q.array(Q.string()).optional(),decisions:Q.array(Q.string()).optional(),file_edit_intentions:Q.array(Q.string()).optional(),unresolved_errors:Q.array(Q.string()).optional(),tool_state:Q.array(Q.string()).optional()}),Wa=200,Kr=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
@@ -97,7 +97,7 @@ ${n.join(`
97
97
  "open_threads": ["work started but not finished"]
98
98
  }
99
99
  }
100
- Use empty arrays/strings where a field doesn't apply.`;function qa(s){let e=s.trim();if(e.length===0)return;let t=Lt(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=Lt(e.slice(o,i+1)))}if(t===void 0){let o=Ja(e);o!==void 0&&(t=Lt(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,Wa))}if(n.synopsis!==void 0&&n.synopsis!==null){let o=pn.safeParse(n.synopsis);o.success&&xp(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var Qr=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
100
+ Use empty arrays/strings where a field doesn't apply.`;function qa(s){let e=s.trim();if(e.length===0)return;let t=Ht(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=Ht(e.slice(o,i+1)))}if(t===void 0){let o=Ja(e);o!==void 0&&(t=Ht(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,Wa))}if(n.synopsis!==void 0&&n.synopsis!==null){let o=pn.safeParse(n.synopsis);o.success&&xp(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var Qr=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
101
101
  {
102
102
  "title": "short summary, max 80 chars",
103
103
  "goal": "the user's original ask",
@@ -109,10 +109,10 @@ Use empty arrays/strings where a field doesn't apply.`;function qa(s){let e=s.tr
109
109
  "unresolved_errors": ["errors left open at session end"],
110
110
  "tool_state": ["runtime state relevant for recall"]
111
111
  }
112
- Use empty arrays/strings where a field doesn't apply.`;function za(s){let e=s.trim();if(e.length===0)return;let t=Lt(e);if(t===void 0){let c=e.indexOf("{"),u=e.lastIndexOf("}");c>=0&&u>c&&(t=Lt(e.slice(c,u+1)))}if(t===void 0){let c=Ja(e);c!==void 0&&(t=Lt(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,Wa))}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=Q.array(Q.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 Lt(s){try{return JSON.parse(s)}catch{return}}function Ja(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 xp(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 Tp="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Pp=Ep(Tp,16),Mp="hydra_lineage_";function mn(){return`${Mp}${Pp()}`}var Yr=P.object({name:P.string(),description:P.string().optional()}),Xr=P.object({id:P.string(),name:P.string().optional(),description:P.string().optional()}),_p=P.object({modelId:P.string(),name:P.string().optional(),description:P.string().optional()}),Zr=P.object({used:P.number().optional(),size:P.number().optional(),costAmount:P.number().optional(),costCurrency:P.string().optional(),cumulativeCost:P.number().optional()}),eo=P.object({name:P.string(),version:P.string().optional()}),$p=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()}),Fp=P.object({previousUpstreamSessionId:P.string(),previousSummarizedThroughEntry:P.number().int().nonnegative().optional(),runId:P.string().optional()}),Op=P.enum(["compaction","agent-swap","workspace-enter","workspace-leave","rollback","restart"]),Np=P.object({upstreamSessionId:P.string(),agentId:P.string(),reason:Op.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()}),Dp=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:pn.optional(),compactionState:Ba.optional(),rollbackBreadcrumb:Fp.optional(),upstreamGenerations:P.array(Np).optional(),summarizedThroughEntry:P.number().int().nonnegative().optional(),agentArgs:P.array(P.string()).optional(),currentModel:P.string().optional(),currentMode:P.string().optional(),currentUsage:Zr.optional(),agentCommands:P.array(Yr).optional(),agentModes:P.array(Xr).optional(),agentModels:P.array(_p).optional(),pendingHistorySync:P.boolean().optional(),pendingAgentSwap:P.string().optional(),parentSessionId:P.string().optional(),forkedFromSessionId:P.string().optional(),forkedFromMessageId:P.string().optional(),forkSynthesisState:P.enum(["running","failed"]).optional(),originatingClient:eo.optional(),interactive:P.boolean().optional(),priority:P.number().int().nonnegative().optional(),forwardedEnv:P.record(P.string(),P.string()).optional(),workspace:$p.optional(),attentionFlags:Ua.default([]).optional(),extensionState:P.record(P.string(),P.record(P.string(),P.unknown())).default({}).optional(),createdAt:P.string(),updatedAt:P.string()}),gn=/^[A-Za-z0-9_-]+$/;function jp(s){if(!gn.test(s))throw new Error(`unsafe session id: ${s}`)}var ss=class{index;indexSeed;async write(e){jp(e.sessionId);let t={version:1,...e};await le(x.sessionFile(e.sessionId),t,{mode:384}),await this.reindex(e.sessionId)}async touch(e){if(!gn.test(e))return;let t=new Date;try{await Te.utimes(x.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 Te.readdir(x.sessionsDir())}catch(n){if(n.code!=="ENOENT")throw n}await Promise.all(t.map(async n=>{if(gn.test(n))try{let r=await Te.stat(x.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 Te.stat(x.sessionFile(e));this.index.set(e,{mtimeMs:t.mtimeMs,deleted:!1})}catch{}}}async read(e){if(!gn.test(e))return;let t=await ie(x.sessionFile(e));if(t!==void 0)try{return Dp.parse(t)}catch{return}}async delete(e){if(gn.test(e)){this.indexSeed&&(await this.indexSeed,this.index.set(e,{mtimeMs:Date.now(),deleted:!0}));try{await Te.unlink(x.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await Te.rmdir(x.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 Te.readdir(x.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 to(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,pendingHistorySync:s.pendingHistorySync,pendingAgentSwap:s.pendingAgentSwap,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,priority:s.priority,forwardedEnv:s.forwardedEnv,workspace:s.workspace,attentionFlags:s.attentionFlags??[],extensionState:s.extensionState??{},createdAt:t,updatedAt:s.updatedAt??e}}Ne();G();import*as oe from"fs/promises";import*as ye from"path";G();import*as rs from"path";import{createHash as Lp}from"crypto";var _e=class extends Error{constructor(e,t){super(`provider "${e}" does not support ${t}; check capabilities().supports before calling`),this.name="WorkspaceUnsupportedError"}};function Ht(s){let e=Lp("sha256").update(rs.resolve(s)).digest("hex").slice(0,12);return rs.join(B(),"workspaces",e)}async function os(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 wt(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 no(s){return s.changedPaths.length>0||s.recorded!==void 0&&s.recorded!==s.actual}function Hp(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 so(s,e){let t=new Set(e.map(r=>r.relPath));return[...s.filter(r=>!t.has(r.replace(/\/$/,""))),...Hp(e.filter(no))]}function is(s){let e=s.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e.slice(0,64):"workspace"}var ro="copy",Ga=new Set([".git"]);function hn(s){return`${s}.manifest.json`}async function Va(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 oe.readdir(n,{withFileTypes:!0})}catch{continue}for(let o of r){let i=ye.join(n,o.name);if(!(n===s&&Ga.has(o.name))){if(o.isDirectory()){t.push(i);continue}if(o.isFile())try{let a=await oe.stat(i);e.set(ye.relative(s,i),{size:a.size,mtimeMs:a.mtimeMs})}catch{continue}}}}return e}var as=class{kind=ro;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=ye.resolve(e.sourceCwd),n=e.contentFrom!==void 0?ye.resolve(e.contentFrom):t;try{n=await oe.realpath(n)}catch{}try{if(!(await oe.stat(n)).isDirectory())return{ok:!1,reason:`${n} is not a directory`}}catch{return{ok:!1,reason:`${n} does not exist`}}let r=Ht(t);try{await oe.mkdir(r,{recursive:!0})}catch(u){return{ok:!1,reason:`could not create workspace root: ${String(u)}`}}let o=await os(is(e.label),async u=>oe.access(ye.join(r,u)).then(()=>!1).catch(()=>!0));if(o===void 0)return{ok:!1,reason:`no free name available for "${e.label}"`};let i=ye.join(r,o),a;try{a=await oe.readdir(n)}catch(u){return{ok:!1,reason:`copy failed: ${String(u)}`}}try{await oe.mkdir(i,{recursive:!0});for(let u of a)Ga.has(u)||await oe.cp(ye.join(n,u),ye.join(i,u),{recursive:!0,errorOnExist:!1,force:!0})}catch(u){return await oe.rm(i,{recursive:!0,force:!0}).catch(()=>{}),{ok:!1,reason:`copy failed: ${String(u)}`}}let d=await Va(i),c={sourceCwd:t,label:o,createdAt:new Date().toISOString(),entries:Object.fromEntries(d)};return await le(hn(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 oe.rm(e.path,{recursive:!0,force:!0}),await oe.rm(hn(e.path),{force:!0})}async listWorkspaces(e){let t=Ht(ye.resolve(e)),n;try{n=await oe.readdir(t)}catch{return[]}let r=[];for(let o of n){if(o.endsWith(".manifest.json"))continue;let i=ye.join(t,o),a=await ie(hn(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 ie(hn(e.path)),n=await Va(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:`,...wt(t.map(r=>` ${r}`))];return n.push(`Not tracking ${F(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 _e(this.kind,"captureWorkingState")}async record(){throw new _e(this.kind,"record")}async attributeOrphan(e){let t=await ie(hn(e));if(t?.sourceCwd!==void 0)return{path:e,sourceCwd:t.sourceCwd,label:t.label??ye.basename(e),provider:this.kind}}async discardLine(){return{ok:!0,dropped:0}}ownsLine(){return!1}async pruneStale(){}async changedPaths(){throw new _e(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 _e(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 _e(this.kind,"lock")}async unlock(){throw new _e(this.kind,"unlock")}};G();import{execFile as Za}from"child_process";import{randomBytes as qp}from"crypto";import*as $e from"fs/promises";import*as ed from"os";import*as Y from"path";function Up(s){let e=s.indexOf(" ");return e===-1?{key:s,value:""}:{key:s.slice(0,e),value:s.slice(e+1)}}function Ka(s){let e=[],t,n=()=>{t!==void 0&&(e.push(t),t=void 0)};for(let r of s.split(`
112
+ Use empty arrays/strings where a field doesn't apply.`;function za(s){let e=s.trim();if(e.length===0)return;let t=Ht(e);if(t===void 0){let c=e.indexOf("{"),u=e.lastIndexOf("}");c>=0&&u>c&&(t=Ht(e.slice(c,u+1)))}if(t===void 0){let c=Ja(e);c!==void 0&&(t=Ht(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,Wa))}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=Q.array(Q.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 Ht(s){try{return JSON.parse(s)}catch{return}}function Ja(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 xp(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 Tp="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Pp=Ep(Tp,16),Mp="hydra_lineage_";function mn(){return`${Mp}${Pp()}`}var Yr=P.object({name:P.string(),description:P.string().optional()}),Xr=P.object({id:P.string(),name:P.string().optional(),description:P.string().optional()}),_p=P.object({modelId:P.string(),name:P.string().optional(),description:P.string().optional()}),Zr=P.object({used:P.number().optional(),size:P.number().optional(),costAmount:P.number().optional(),costCurrency:P.string().optional(),cumulativeCost:P.number().optional()}),eo=P.object({name:P.string(),version:P.string().optional()}),$p=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()}),Fp=P.object({previousUpstreamSessionId:P.string(),previousSummarizedThroughEntry:P.number().int().nonnegative().optional(),runId:P.string().optional()}),Op=P.enum(["compaction","agent-swap","workspace-enter","workspace-leave","rollback","restart"]),Np=P.object({upstreamSessionId:P.string(),agentId:P.string(),reason:Op.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()}),Dp=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:pn.optional(),compactionState:Ba.optional(),rollbackBreadcrumb:Fp.optional(),upstreamGenerations:P.array(Np).optional(),summarizedThroughEntry:P.number().int().nonnegative().optional(),agentArgs:P.array(P.string()).optional(),currentModel:P.string().optional(),currentMode:P.string().optional(),currentUsage:Zr.optional(),agentCommands:P.array(Yr).optional(),agentModes:P.array(Xr).optional(),agentModels:P.array(_p).optional(),pendingHistorySync:P.boolean().optional(),pendingAgentSwap:P.string().optional(),parentSessionId:P.string().optional(),forkedFromSessionId:P.string().optional(),forkedFromMessageId:P.string().optional(),forkSynthesisState:P.enum(["running","failed"]).optional(),originatingClient:eo.optional(),interactive:P.boolean().optional(),priority:P.number().int().nonnegative().optional(),forwardedEnv:P.record(P.string(),P.string()).optional(),workspace:$p.optional(),attentionFlags:Ua.default([]).optional(),extensionState:P.record(P.string(),P.record(P.string(),P.unknown())).default({}).optional(),createdAt:P.string(),updatedAt:P.string()}),gn=/^[A-Za-z0-9_-]+$/;function jp(s){if(!gn.test(s))throw new Error(`unsafe session id: ${s}`)}var ss=class{index;indexSeed;async write(e){jp(e.sessionId);let t={version:1,...e};await le(x.sessionFile(e.sessionId),t,{mode:384}),await this.reindex(e.sessionId)}async touch(e){if(!gn.test(e))return;let t=new Date;try{await Te.utimes(x.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 Te.readdir(x.sessionsDir())}catch(n){if(n.code!=="ENOENT")throw n}await Promise.all(t.map(async n=>{if(gn.test(n))try{let r=await Te.stat(x.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 Te.stat(x.sessionFile(e));this.index.set(e,{mtimeMs:t.mtimeMs,deleted:!1})}catch{}}}async read(e){if(!gn.test(e))return;let t=await ie(x.sessionFile(e));if(t!==void 0)try{return Dp.parse(t)}catch{return}}async delete(e){if(gn.test(e)){this.indexSeed&&(await this.indexSeed,this.index.set(e,{mtimeMs:Date.now(),deleted:!0}));try{await Te.unlink(x.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await Te.rmdir(x.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 Te.readdir(x.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 to(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,pendingHistorySync:s.pendingHistorySync,pendingAgentSwap:s.pendingAgentSwap,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,priority:s.priority,forwardedEnv:s.forwardedEnv,workspace:s.workspace,attentionFlags:s.attentionFlags??[],extensionState:s.extensionState??{},createdAt:t,updatedAt:s.updatedAt??e}}Ne();G();import*as oe from"fs/promises";import*as ye from"path";G();import*as rs from"path";import{createHash as Hp}from"crypto";var _e=class extends Error{constructor(e,t){super(`provider "${e}" does not support ${t}; check capabilities().supports before calling`),this.name="WorkspaceUnsupportedError"}};function Lt(s){let e=Hp("sha256").update(rs.resolve(s)).digest("hex").slice(0,12);return rs.join(B(),"workspaces",e)}async function os(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 wt(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 no(s){return s.changedPaths.length>0||s.recorded!==void 0&&s.recorded!==s.actual}function Lp(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 so(s,e){let t=new Set(e.map(r=>r.relPath));return[...s.filter(r=>!t.has(r.replace(/\/$/,""))),...Lp(e.filter(no))]}function is(s){let e=s.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e.slice(0,64):"workspace"}var ro="copy",Ga=new Set([".git"]);function hn(s){return`${s}.manifest.json`}async function Va(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 oe.readdir(n,{withFileTypes:!0})}catch{continue}for(let o of r){let i=ye.join(n,o.name);if(!(n===s&&Ga.has(o.name))){if(o.isDirectory()){t.push(i);continue}if(o.isFile())try{let a=await oe.stat(i);e.set(ye.relative(s,i),{size:a.size,mtimeMs:a.mtimeMs})}catch{continue}}}}return e}var as=class{kind=ro;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=ye.resolve(e.sourceCwd),n=e.contentFrom!==void 0?ye.resolve(e.contentFrom):t;try{n=await oe.realpath(n)}catch{}try{if(!(await oe.stat(n)).isDirectory())return{ok:!1,reason:`${n} is not a directory`}}catch{return{ok:!1,reason:`${n} does not exist`}}let r=Lt(t);try{await oe.mkdir(r,{recursive:!0})}catch(u){return{ok:!1,reason:`could not create workspace root: ${String(u)}`}}let o=await os(is(e.label),async u=>oe.access(ye.join(r,u)).then(()=>!1).catch(()=>!0));if(o===void 0)return{ok:!1,reason:`no free name available for "${e.label}"`};let i=ye.join(r,o),a;try{a=await oe.readdir(n)}catch(u){return{ok:!1,reason:`copy failed: ${String(u)}`}}try{await oe.mkdir(i,{recursive:!0});for(let u of a)Ga.has(u)||await oe.cp(ye.join(n,u),ye.join(i,u),{recursive:!0,errorOnExist:!1,force:!0})}catch(u){return await oe.rm(i,{recursive:!0,force:!0}).catch(()=>{}),{ok:!1,reason:`copy failed: ${String(u)}`}}let d=await Va(i),c={sourceCwd:t,label:o,createdAt:new Date().toISOString(),entries:Object.fromEntries(d)};return await le(hn(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 oe.rm(e.path,{recursive:!0,force:!0}),await oe.rm(hn(e.path),{force:!0})}async listWorkspaces(e){let t=Lt(ye.resolve(e)),n;try{n=await oe.readdir(t)}catch{return[]}let r=[];for(let o of n){if(o.endsWith(".manifest.json"))continue;let i=ye.join(t,o),a=await ie(hn(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 ie(hn(e.path)),n=await Va(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:`,...wt(t.map(r=>` ${r}`))];return n.push(`Not tracking ${F(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 _e(this.kind,"captureWorkingState")}async record(){throw new _e(this.kind,"record")}async attributeOrphan(e){let t=await ie(hn(e));if(t?.sourceCwd!==void 0)return{path:e,sourceCwd:t.sourceCwd,label:t.label??ye.basename(e),provider:this.kind}}async discardLine(){return{ok:!0,dropped:0}}ownsLine(){return!1}async pruneStale(){}async changedPaths(){throw new _e(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 _e(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 _e(this.kind,"lock")}async unlock(){throw new _e(this.kind,"unlock")}};G();import{execFile as Za}from"child_process";import{randomBytes as qp}from"crypto";import*as $e from"fs/promises";import*as ed from"os";import*as Y from"path";function Up(s){let e=s.indexOf(" ");return e===-1?{key:s,value:""}:{key:s.slice(0,e),value:s.slice(e+1)}}function Ka(s){let e=[],t,n=()=>{t!==void 0&&(e.push(t),t=void 0)};for(let r of s.split(`
113
113
  `)){let o=r.replace(/\r$/,"");if(o.length===0){n();continue}let{key:i,value:a}=Up(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 Qa(s){if(s===void 0)return;let e="refs/heads/";return s.startsWith(e)?s.slice(e.length):s}var us="git",Ya="hydra-acp:",oo="hydra",z=5e3,ce=12e4,ds=9e5;function Xa(s){return $e.access(s).then(()=>!0).catch(()=>!1)}function yn(s){return s.length===0?s:Y.normalize(s)}function zp(s){return $e.realpath(s).catch(()=>s)}function j(s,e,t,n){return new Promise(r=>{Za("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 io(s,e,t,n=ce){return new Promise(r=>{let o=Za("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 ao(s){let e=[];for(let t of s.split(`
114
114
  `)){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 cs=class{kind=us;refRoot(e){return e.vcs?.repoRoot??e.sourceCwd}ownsLine(e){return e.startsWith(`${oo}/`)}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 Xa(Y.join(e.path,".gitmodules")))return{ok:!0,count:0};let r=await j(["submodule","update","--init","--recursive",...t?.discardLocal===!0?["--force"]:[]],e.path,ds);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,ds);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,ds);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,z);return{ok:!0,count:o.ok?o.stdout.split(`
115
- `).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 Xa(n))return{ok:!1,reason:`source repository ${n} no longer exists`};let r=await j(["rev-parse","--verify","--quiet",`refs/heads/${t}`],n,z);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,z),await j(["worktree","prune"],n,z);let o=await j(["worktree","add",e.path,t],n,ce);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=Y.resolve(e.sourceCwd),n=await j(["rev-parse","--show-toplevel"],t,z);if(!n.ok)return{ok:!1,reason:`${t} is not a git repository (or git is unavailable)`};let r=yn(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,z);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=Ht(t);try{await $e.mkdir(d,{recursive:!0})}catch(m){return{ok:!1,reason:`could not create workspace root: ${String(m)}`}}let c=await os(a,async m=>await $e.access(Y.join(d,m)).then(()=>!0).catch(()=>!1)?!1:!(await j(["rev-parse","--verify","--quiet",`refs/heads/${oo}/${m}`],r,z)).ok);if(c===void 0)return{ok:!1,reason:`no free name available for "${a}"`};let u=Y.join(d,c),l=`${oo}/${c}`,p=await j(["worktree","add","--no-track","-b",l,u,i],r,ce);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,ce);t.discardLine===!0&&e.vcs?.branch!==void 0&&await j(["branch","-D",e.vcs.branch],n,z),r.ok||(await $e.rm(e.path,{recursive:!0,force:!0}),await j(["worktree","prune"],n,z))}async listWorkspaces(e){let t=Y.resolve(e),n=await j(["rev-parse","--show-toplevel"],t,z);if(!n.ok)return[];let r=yn(n.stdout.trim()),o=await j(["worktree","list","--porcelain"],r,z);if(!o.ok)return[];let i=Ht(t),a=await zp(i),d=[];for(let c of Ka(o.stdout)){let u=yn(c.path),l=Y.dirname(u);if(l!==i&&l!==a)continue;let p=Y.join(i,Y.basename(u)),m={kind:"git",repoRoot:r},h=Qa(c.branch);h!==void 0&&(m.branch=h),c.head!==void 0&&(m.head=c.head),c.lockedReason!==void 0&&(m.locked=c.lockedReason);let f=c.lockedReason?.startsWith(Ya)===!0;d.push({path:p,sourceCwd:t,label:Y.basename(p),...f?{heldByUs:!0}:{},provider:this.kind,...h!==void 0?{line:h}:{},vcs:m})}return d}async status(e){let t=await j(["status","--porcelain","--untracked-files=all"],e.path,z);if(!t.ok)return{clean:!1,changedPaths:[],hasRecordedWork:!1};let n=ao(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,z);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",`${Ya}${t}`,e.path],n,z)}async unlock(e){let t=this.refRoot(e);await j(["worktree","unlock",e.path],t,z)}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 $e.access(Y.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,z);if(n.ok){let r=ao(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(...wt(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,z),j(["rev-parse","HEAD"],e.path,z)]),r=t.stdout.trim(),o=n.stdout.trim();if(!t.ok||!n.ok||r.length===0||o.length===0)return[];let i=F(e.sourceCwd);if(r===o)return[`in sync with ${i}`];let a=await j(["rev-list","--left-right","--count",`${r}...${o}`],e.path,z),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=Y.join(ed.tmpdir(),`hydra-index-${process.pid}-${qp(6).toString("hex")}`),r={GIT_INDEX_FILE:n};try{let o=await j(["rev-parse","--verify","HEAD"],e,z),i=o.ok&&o.stdout.trim().length>0;if(i){let l=await j(["read-tree","HEAD"],e,ce,r);if(!l.ok)throw new Error(`could not seed the snapshot index: ${l.stderr.trim()}`)}let a=await j(["add","-A"],e,ce,r);if(!a.ok)throw new Error(`could not stage working state: ${a.stderr.trim()}`);let d=await j(["write-tree"],e,ce,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,ce,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 $e.rm(n,{force:!0}).catch(()=>{})}}async retainSnapshot(e,t,n){let r=this.refRoot(e);await j(["update-ref","--create-reflog",t,n],r,z)}async dropSnapshotRef(e,t){let n=this.refRoot(e);await j(["update-ref","-d",t],n,z)}async currentState(e){let t=await j(["rev-parse","HEAD"],e,z),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,z),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,z),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,z),n=yn(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),z),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,z)).ok}async divergence(e,t,n){let r=await j(["rev-list","--left-right","--count",`${t}...${n}`],e,z);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,z);return r.ok?r.stdout.split(`
115
+ `).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 Xa(n))return{ok:!1,reason:`source repository ${n} no longer exists`};let r=await j(["rev-parse","--verify","--quiet",`refs/heads/${t}`],n,z);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,z),await j(["worktree","prune"],n,z);let o=await j(["worktree","add",e.path,t],n,ce);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=Y.resolve(e.sourceCwd),n=await j(["rev-parse","--show-toplevel"],t,z);if(!n.ok)return{ok:!1,reason:`${t} is not a git repository (or git is unavailable)`};let r=yn(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,z);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=Lt(t);try{await $e.mkdir(d,{recursive:!0})}catch(m){return{ok:!1,reason:`could not create workspace root: ${String(m)}`}}let c=await os(a,async m=>await $e.access(Y.join(d,m)).then(()=>!0).catch(()=>!1)?!1:!(await j(["rev-parse","--verify","--quiet",`refs/heads/${oo}/${m}`],r,z)).ok);if(c===void 0)return{ok:!1,reason:`no free name available for "${a}"`};let u=Y.join(d,c),l=`${oo}/${c}`,p=await j(["worktree","add","--no-track","-b",l,u,i],r,ce);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,ce);t.discardLine===!0&&e.vcs?.branch!==void 0&&await j(["branch","-D",e.vcs.branch],n,z),r.ok||(await $e.rm(e.path,{recursive:!0,force:!0}),await j(["worktree","prune"],n,z))}async listWorkspaces(e){let t=Y.resolve(e),n=await j(["rev-parse","--show-toplevel"],t,z);if(!n.ok)return[];let r=yn(n.stdout.trim()),o=await j(["worktree","list","--porcelain"],r,z);if(!o.ok)return[];let i=Lt(t),a=await zp(i),d=[];for(let c of Ka(o.stdout)){let u=yn(c.path),l=Y.dirname(u);if(l!==i&&l!==a)continue;let p=Y.join(i,Y.basename(u)),m={kind:"git",repoRoot:r},h=Qa(c.branch);h!==void 0&&(m.branch=h),c.head!==void 0&&(m.head=c.head),c.lockedReason!==void 0&&(m.locked=c.lockedReason);let f=c.lockedReason?.startsWith(Ya)===!0;d.push({path:p,sourceCwd:t,label:Y.basename(p),...f?{heldByUs:!0}:{},provider:this.kind,...h!==void 0?{line:h}:{},vcs:m})}return d}async status(e){let t=await j(["status","--porcelain","--untracked-files=all"],e.path,z);if(!t.ok)return{clean:!1,changedPaths:[],hasRecordedWork:!1};let n=ao(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,z);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",`${Ya}${t}`,e.path],n,z)}async unlock(e){let t=this.refRoot(e);await j(["worktree","unlock",e.path],t,z)}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 $e.access(Y.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,z);if(n.ok){let r=ao(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(...wt(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,z),j(["rev-parse","HEAD"],e.path,z)]),r=t.stdout.trim(),o=n.stdout.trim();if(!t.ok||!n.ok||r.length===0||o.length===0)return[];let i=F(e.sourceCwd);if(r===o)return[`in sync with ${i}`];let a=await j(["rev-list","--left-right","--count",`${r}...${o}`],e.path,z),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=Y.join(ed.tmpdir(),`hydra-index-${process.pid}-${qp(6).toString("hex")}`),r={GIT_INDEX_FILE:n};try{let o=await j(["rev-parse","--verify","HEAD"],e,z),i=o.ok&&o.stdout.trim().length>0;if(i){let l=await j(["read-tree","HEAD"],e,ce,r);if(!l.ok)throw new Error(`could not seed the snapshot index: ${l.stderr.trim()}`)}let a=await j(["add","-A"],e,ce,r);if(!a.ok)throw new Error(`could not stage working state: ${a.stderr.trim()}`);let d=await j(["write-tree"],e,ce,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,ce,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 $e.rm(n,{force:!0}).catch(()=>{})}}async retainSnapshot(e,t,n){let r=this.refRoot(e);await j(["update-ref","--create-reflog",t,n],r,z)}async dropSnapshotRef(e,t){let n=this.refRoot(e);await j(["update-ref","-d",t],n,z)}async currentState(e){let t=await j(["rev-parse","HEAD"],e,z),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,z),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,z),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,z),n=yn(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),z),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,z)).ok}async divergence(e,t,n){let r=await j(["rev-list","--left-right","--count",`${t}...${n}`],e,z);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,z);return r.ok?r.stdout.split(`
116
116
  `).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,ce);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 io(["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 io(["apply","--reverse","--check"],e,t)).ok)return{ok:!0,alreadyPresent:!0};let a=await io(["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,ce);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,ce);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,z)).ok}async abortIntegration(e){await j(["merge","--abort"],e,ce)}async conflictedPaths(e){let t=await j(["diff","--name-only","--diff-filter=U"],e,z);return t.ok?t.stdout.split(`
117
117
  `).map(n=>n.replace(/\r$/,"").trim()).filter(n=>n.length>0):[]}async record(e,t){let n=await j(["add","-A"],e.path,ce);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,ce);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,z),n=yn(t.stdout.trim());if(!t.ok||n.length===0)return;let r=Y.dirname(n),o=await this.currentLineName(e);return{path:e,sourceCwd:r,label:Y.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,z);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),z)}async changedPaths(){throw new _e(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,ce);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,ce);if(!t.ok)return[];let n=[];for(let r of t.stdout.split(`
118
118
  `)){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||!Jp(e,c))continue;let u=Y.join(e,c),[l,p,m]=await Promise.all([this.currentState(u),j(["rev-parse",`HEAD:${c}`],e,z),j(["status","--porcelain","--untracked-files=all"],u,z)]);if(l===void 0)continue;let h=p.ok?p.stdout.trim():"";n.push({relPath:c,actual:l,...h.length>0?{recorded:h}:{},changedPaths:m.ok?ao(m.stdout).map(f=>f.path):[]})}return n}async captureNested(e,t){let n=[];for(let r of t){if(!no(r))continue;if(r.changedPaths.length===0){n.push(r);continue}let o=Y.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=Y.join(e,i.relPath),d=Y.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(g=>g.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,m=l?.delta!==void 0;if(!p&&!m)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=Y.join(e,c),f=Y.join(t,c);if(p&&u.recorded!==void 0){let g=await this.alignNested(h,f,u.recorded);if(g!==void 0){o.push({path:c,reason:g});continue}}if(l?.delta!==void 0){let g=await this.applyDelta(h,l.delta);if(!g.ok){o.push({path:c,reason:g.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,z)).ok&&!(await j(["fetch","--no-tags",t,n],e,ds)).ok)return`could not transfer ${n.slice(0,8)} from the other copy`;if(!(await j(["checkout","--detach",n],e,ce)).ok)return`could not move to ${n.slice(0,8)}`}};function Jp(s,e){if(Y.isAbsolute(e))return!1;let t=Y.resolve(s),n=Y.resolve(t,e);return n!==t&&n.startsWith(t+Y.sep)}var Vp=us,Gp=new Map([[us,new cs],[ro,new as]]);function ne(s){return Gp.get(s??Vp)}var ls="refs/hydra";function wn(s){let e=`${ls}/workspaces/${s}`;return{autosave:`${e}/autosave`,start:`${e}/start`,baseline:`${e}/baseline`}}function co(s){return`${ls}/landing/${s}`}function td(s){return`${ls}/sync/${s}`}function nd(s,e){return`${ls}/retired/${s}-${e.slice(0,12)}`}function sd(s){let e=wn(s);return[e.autosave,e.start,e.baseline]}async function uo(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 vt(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 vn(s){s.capture.retainedRef===void 0||s.provider===void 0||await s.provider.dropSnapshotRef({...s.ws,path:s.source},s.capture.retainedRef).catch(()=>{})}Ne();import{exec as Kp}from"child_process";import*as ze from"fs/promises";import*as Ce from"path";var Qp=".hydra/worktree.json",Yp=".worktreeinclude",Xp=120;async function fs(s){let e=await ie(Ce.join(s,Qp))??{},t=new Set(Array.isArray(e.carry)?e.carry:[]),n=await ze.readFile(Ce.join(s,Yp),"utf8").catch(()=>{});if(n!==void 0)for(let o of n.split(`
@@ -128,7 +128,7 @@ ${e}
128
128
 
129
129
  ${Qr}`:`${t}
130
130
 
131
- ${Qr}`;return id(s,n,za)}function sg(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 rg(s){let e=new Set;od(e,s.availableModels);let t=s.models;return t&&typeof t=="object"&&!Array.isArray(t)&&od(e,t.availableModels),e}function od(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)}}}function og(s){let e=new Map;for(let t of pd(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 ud(s){return og(s).map(e=>e.name)}function ig(s){let e=new Map;for(let t of pd(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 ld(s){return ig(s).map(e=>e.path)}function fd(s){let e=0;for(let t of s)t.params?.update?.sessionUpdate==="prompt_received"&&(e+=1);return e}function pd(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:`__synth_${t++}`,c=e.get(d);c===void 0?(c={toolName:dd(o),paths:new Set},e.set(d,c)):c.toolName=dd(o);for(let u of cd(o.rawInput,o.locations))c.paths.add(u);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 cd(o.rawInput,o.locations))a.paths.add(d)}return e}function dd(s){return typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function cd(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 fa(e))t.add(n);return t}G();var dg=ag("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",12),cg=2,ws=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??cg}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 Ee(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,m=x.sessionDir(e);if(await yd.mkdir(m,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(p??"(default)")} cwd=${m}`),n==="compaction"){let h=this.opts.compactionMaxIterations??3,f=0,g=a??0,w,y=0,v,b=Date.now(),S=dg(),k={targetAgentId:r},C=R=>this.opts.onCompactionStateChange?.(e,{runId:S,...R},k)??Promise.resolve(),A=R=>{this.opts.broadcastHydraCompaction?.(e,R,k)};await C({status:"requested",requestedAt:b}),A({sessionUpdate:"_hydra_compaction",phase:"started",requestedAt:b});try{do{f++,this.opts.logger?.info(`synopsis: compaction iteration ${f} sessionId=${e} historyLen=${i.length} watermark=${g}`);let R=await this.opts.histories.load(e,{maxEntries:1/0});if(R.length===g)break;let T=await ad({agentId:d,cwd:m,plan:u,history:R,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:(L,J)=>{C({status:"running",requestedAt:b,iter:f,worker:{upstreamSessionId:L,pid:J??0}})},onFailure:L=>{v=L}});if(T){let L=gd(T.synopsis,R);L&&md(L)&&(await this.opts.persistSynopsis(e,L,R.length),w=L,y=R.length,v=void 0,await C({status:"running",requestedAt:b,iter:f}),A({sessionUpdate:"_hydra_compaction",phase:"iteration",iter:f,historyLen:R.length}),await this.opts.onSynthesisArtifact?.(e,L,y,r,S),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${f} fields=${hd(L)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${f} returned no result`);if(g=R.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===g)break}while(f<h);if(w)this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} runId=${S} watermark=${y} iterations=${f}`+(f>=h?` (hit maxIterations=${h})`:"")),A({sessionUpdate:"_hydra_compaction",phase:"converged",iter:f,summarizedThroughEntry:y});else{f>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${h} without producing artifact sessionId=${e}: ${v??"no reason captured"}`);let R=v??(f===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${f} iteration(s)`);await C({status:"failed",requestedAt:b,iter:f,lastError:R}),A({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 C({status:"failed",requestedAt:b,iter:f,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 ys({agentId:d,cwd:m,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 f=gd(h.synopsis,i);f&&md(f)?(await this.opts.persistSynopsis(e,f,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=${hd(f)}`)):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 gd(s,e){let t=ld(e),n=ud(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 md(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 hd(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(",")}]`}G();import*as X from"fs/promises";import{createReadStream as hg}from"fs";import{createGunzip as yg,gzip as wg,gunzip as vg}from"zlib";import{createInterface as kg}from"readline";import{promisify as Id}from"util";function wd(s){return s==="summary"?"summary":"inline"}var fo=256,ug=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],lg=["content","stdout","stderr"];function vd(s,e){return e!=="summary"?s:s.map(fg)}function fg(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(kd));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=vs(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let c of ug)a[c]!==void 0&&(d[c]=a[c]);for(let c of lg)typeof a[c]=="string"&&(d[c]=vs(a[c]));o.rawOutput=d}return{...s,params:{...t,update:o}}}function pg(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&s.type==="diff"}function kd(s){if(pg(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=vs(e.text)),typeof e.content=="string"?t.content=vs(e.content):e.content&&typeof e.content=="object"&&(t.content=kd(e.content)),t}function vs(s){if(typeof s=="string"&&s.length>fo){let e=s.length-fo;return`${s.slice(0,fo)}\u2026[+${e} chars omitted from summary export]`}return s}var gg=2048;function bd(s){let e=new Set,t=n=>{if(Sd(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 Sd(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.__hydraBlob=="string"}function mg(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 mo(s,e){if(!mg(s))return s;let t=s.params,n=t.update,r=await po(n,e);return{...s,params:{...t,update:r}}}async function po(s,e){if(typeof s=="string"){if(s.length<=gg)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 po(n,e));return t}if(s&&typeof s=="object"){let t={};for(let[n,r]of Object.entries(s))t[n]=await po(r,e);return t}return s}async function ho(s,e){let t=s.params;if(!t||typeof t!="object"||Array.isArray(t))return s;let n=await go(t,e);return n===t?s:{...s,params:n}}async function go(s,e){if(Sd(s))return await e(s.__hydraBlob)??"";if(Array.isArray(s)){let t=!1,n=[];for(let r of s){let o=await go(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 go(o,e);i!==o&&(t=!0),n[r]=i}return t?n:s}return s}var bg=Id(wg),Sg=Id(vg),Ig=/^history\.jsonl\.(\d+)(\.gz)?$/,Oe=/^[A-Za-z0-9_-]+$/,Ag=1e3,Cg=1e7,Rg=10,ks=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??Ag,this.archiveMaxBytes=e.archiveMaxBytes??Cg,this.archiveTiers=e.archiveTiers??Rg}async append(e,t){if(Oe.test(e))return this.enqueue(e,async()=>{await X.mkdir(x.sessionDir(e),{recursive:!0});let n=await mo(t,o=>hr(e,o)),r=JSON.stringify(n)+`
131
+ ${Qr}`;return id(s,n,za)}function sg(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 rg(s){let e=new Set;od(e,s.availableModels);let t=s.models;return t&&typeof t=="object"&&!Array.isArray(t)&&od(e,t.availableModels),e}function od(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)}}}function og(s){let e=new Map;for(let t of pd(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 ud(s){return og(s).map(e=>e.name)}function ig(s){let e=new Map;for(let t of pd(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 ld(s){return ig(s).map(e=>e.path)}function fd(s){let e=0;for(let t of s)t.params?.update?.sessionUpdate==="prompt_received"&&(e+=1);return e}function pd(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:`__synth_${t++}`,c=e.get(d);c===void 0?(c={toolName:dd(o),paths:new Set},e.set(d,c)):c.toolName=dd(o);for(let u of cd(o.rawInput,o.locations))c.paths.add(u);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 cd(o.rawInput,o.locations))a.paths.add(d)}return e}function dd(s){return typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function cd(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 fa(e))t.add(n);return t}G();var dg=ag("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",12),cg=2,ws=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??cg}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 Ee(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,m=x.sessionDir(e);if(await yd.mkdir(m,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(p??"(default)")} cwd=${m}`),n==="compaction"){let h=this.opts.compactionMaxIterations??3,f=0,g=a??0,w,y=0,v,b=Date.now(),S=dg(),k={targetAgentId:r},C=R=>this.opts.onCompactionStateChange?.(e,{runId:S,...R},k)??Promise.resolve(),A=R=>{this.opts.broadcastHydraCompaction?.(e,R,k)};await C({status:"requested",requestedAt:b}),A({sessionUpdate:"_hydra_compaction",phase:"started",requestedAt:b});try{do{f++,this.opts.logger?.info(`synopsis: compaction iteration ${f} sessionId=${e} historyLen=${i.length} watermark=${g}`);let R=await this.opts.histories.load(e,{maxEntries:1/0});if(R.length===g)break;let T=await ad({agentId:d,cwd:m,plan:u,history:R,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:(H,J)=>{C({status:"running",requestedAt:b,iter:f,worker:{upstreamSessionId:H,pid:J??0}})},onFailure:H=>{v=H}});if(T){let H=gd(T.synopsis,R);H&&md(H)&&(await this.opts.persistSynopsis(e,H,R.length),w=H,y=R.length,v=void 0,await C({status:"running",requestedAt:b,iter:f}),A({sessionUpdate:"_hydra_compaction",phase:"iteration",iter:f,historyLen:R.length}),await this.opts.onSynthesisArtifact?.(e,H,y,r,S),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${f} fields=${hd(H)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${f} returned no result`);if(g=R.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===g)break}while(f<h);if(w)this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} runId=${S} watermark=${y} iterations=${f}`+(f>=h?` (hit maxIterations=${h})`:"")),A({sessionUpdate:"_hydra_compaction",phase:"converged",iter:f,summarizedThroughEntry:y});else{f>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${h} without producing artifact sessionId=${e}: ${v??"no reason captured"}`);let R=v??(f===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${f} iteration(s)`);await C({status:"failed",requestedAt:b,iter:f,lastError:R}),A({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 C({status:"failed",requestedAt:b,iter:f,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 ys({agentId:d,cwd:m,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 f=gd(h.synopsis,i);f&&md(f)?(await this.opts.persistSynopsis(e,f,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=${hd(f)}`)):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 gd(s,e){let t=ld(e),n=ud(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 md(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 hd(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(",")}]`}G();import*as X from"fs/promises";import{createReadStream as hg}from"fs";import{createGunzip as yg,gzip as wg,gunzip as vg}from"zlib";import{createInterface as kg}from"readline";import{promisify as Id}from"util";function wd(s){return s==="summary"?"summary":"inline"}var fo=256,ug=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],lg=["content","stdout","stderr"];function vd(s,e){return e!=="summary"?s:s.map(fg)}function fg(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(kd));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=vs(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let c of ug)a[c]!==void 0&&(d[c]=a[c]);for(let c of lg)typeof a[c]=="string"&&(d[c]=vs(a[c]));o.rawOutput=d}return{...s,params:{...t,update:o}}}function pg(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&s.type==="diff"}function kd(s){if(pg(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=vs(e.text)),typeof e.content=="string"?t.content=vs(e.content):e.content&&typeof e.content=="object"&&(t.content=kd(e.content)),t}function vs(s){if(typeof s=="string"&&s.length>fo){let e=s.length-fo;return`${s.slice(0,fo)}\u2026[+${e} chars omitted from summary export]`}return s}var gg=2048;function bd(s){let e=new Set,t=n=>{if(Sd(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 Sd(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.__hydraBlob=="string"}function mg(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 mo(s,e){if(!mg(s))return s;let t=s.params,n=t.update,r=await po(n,e);return{...s,params:{...t,update:r}}}async function po(s,e){if(typeof s=="string"){if(s.length<=gg)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 po(n,e));return t}if(s&&typeof s=="object"){let t={};for(let[n,r]of Object.entries(s))t[n]=await po(r,e);return t}return s}async function ho(s,e){let t=s.params;if(!t||typeof t!="object"||Array.isArray(t))return s;let n=await go(t,e);return n===t?s:{...s,params:n}}async function go(s,e){if(Sd(s))return await e(s.__hydraBlob)??"";if(Array.isArray(s)){let t=!1,n=[];for(let r of s){let o=await go(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 go(o,e);i!==o&&(t=!0),n[r]=i}return t?n:s}return s}var bg=Id(wg),Sg=Id(vg),Ig=/^history\.jsonl\.(\d+)(\.gz)?$/,Oe=/^[A-Za-z0-9_-]+$/,Ag=1e3,Cg=1e7,Rg=10,ks=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??Ag,this.archiveMaxBytes=e.archiveMaxBytes??Cg,this.archiveTiers=e.archiveTiers??Rg}async append(e,t){if(Oe.test(e))return this.enqueue(e,async()=>{await X.mkdir(x.sessionDir(e),{recursive:!0});let n=await mo(t,o=>hr(e,o)),r=JSON.stringify(n)+`
132
132
  `;await X.appendFile(x.historyFile(e),r,{encoding:"utf8",mode:384})})}async rewrite(e,t){if(Oe.test(e))return this.enqueue(e,async()=>{await X.mkdir(x.sessionDir(e),{recursive:!0});let n=[];for(let o of t)n.push(await mo(o,i=>hr(e,i)));let r=n.length===0?"":n.map(o=>JSON.stringify(o)).join(`
133
133
  `)+`
134
134
  `;await X.writeFile(x.historyFile(e),r,{encoding:"utf8",mode:384})})}async compact(e,t){if(Oe.test(e))return this.enqueue(e,async()=>{let n;try{n=await X.readFile(x.historyFile(e),"utf8")}catch(a){if(a.code==="ENOENT")return;throw a}let r=n.split(`
@@ -168,11 +168,11 @@ A sync was attempted first but was refused: ${A instanceof Error?A.message:Strin
168
168
  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=ne(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 ${F(t)} with ${F(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`${F(t)} and ${F(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=ne(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(`${F(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=>Qe(u.sessionId)),c=[`Joined workspace ${F(n.path)}`,` source: ${F(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(`
169
169
  `)})}async startWorkspace(e,t,n){if(e.workspace!==void 0)throw new Error(`already isolated in ${F(e.workspace.path)}. Use \`/hydra workspace stop\` to merge and return first, or \`detach\` to leave it behind.`);let r=e.cwd,o=ne();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 k=this.liveSessionsWithLabel(r,t)[0];if(k!==void 0&&k.workspace!==void 0)return await this.joinWorkspace(e,k,k.workspace,r)}let d,c=[],u=!1,l=!1,p=[],m=[],h=n?.clean===!0;if(a.supports.captureWorkingState){let k=await o.status({path:r,sourceCwd:r,label:"source",provider:o.kind}).catch(()=>{});l=k!==void 0;let C=a.supports.nestedTrees&&k!==void 0&&k.changedPaths.length>0?await o.listNested(r).catch(()=>[]):[];if(k!==void 0&&k.changedPaths.length>0&&h)p=so(k.changedPaths,C);else if(k!==void 0&&k.changedPaths.length>0&&(c=so(k.changedPaths,C),m=await o.captureNested(r,C).catch(()=>[]),u=k.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 f=await o.createWorkspace({sourceCwd:r,label:t??`s-${e.sessionId.slice(-8)}`});if(!f.ok)throw e.broadcastWorkspacePhase({phase:"failed",error:f.reason}),new Error(f.reason);let g=f.workspace,w=this.startRefFor(g.label),y,v=!1,b=[];try{a.locking&&await o.lock(g,`session ${e.sessionId}`).catch(()=>{});let k=d??g.snapshot;if(k===void 0)throw new Error(`provider "${g.provider}" gave the workspace no base to anchor landing against`);await o.retainSnapshot(g,w,k),e.broadcastWorkspacePhase({phase:"setup"}),v=d!==void 0?await this.copyCarriedWork(g,d,r):!0;let C=await this.materializeNestedTrees(g);if(m.length>0){let R=await o.reproduceNested(g.path,r,m).catch(T=>({applied:[],failed:m.map(M=>({path:M.relPath,reason:T instanceof Error?T.message:String(T)}))}));R.failed.length>0&&(v=!1,b=R.failed)}y=await this.applyWorkspaceSetup(g,e.sessionId),C!==void 0&&(y=y===void 0?C:`${C}; ${y}`),e.broadcastWorkspacePhase({phase:"swapping"});let A=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:g.path,workspace:{path:g.path,sourceCwd:g.sourceCwd,label:g.label,...t!==void 0&&t!==g.label?{requestedLabel:t}:{},provider:g.provider,...g.snapshot!==void 0?{snapshot:g.snapshot}:{},...g.line!==void 0?{line:g.line}:{},...g.vcs!==void 0?{vcs:{...g.vcs}}:{},...d===void 0?{clean:!0}:{}},historyLength:A.length,note:`Continuing in an isolated workspace at ${g.path}, derived from ${r}.`,...await this.recordSynopsisFor(e.sessionId)})}catch(k){let C=await this.unwindStartWorkspace({provider:o,ws:g,startRef:w,carried:d}),A=k instanceof Error?k.message:String(k);throw e.broadcastWorkspacePhase({phase:"failed",error:A}),new Error(C===void 0?A:`${A}
170
170
  ${C}`)}await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:g.sourceCwd,label:g.label,...g.line!==void 0?{branch:g.line}:{}});let S=[`Moved into workspace ${F(g.path)}`,` source: ${F(r)}`];if(g.line!==void 0&&S.push(` branch: ${g.line}`),t!==void 0&&t!==g.label&&S.push(` note: "${t}" was already taken by a surviving branch, so this is "${g.label}"`),d!==void 0){S.push(v?` 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 k of wt(c))S.push(` ${k}`);v&&u&&S.push(" staging did not come along; everything above is unstaged here");for(let k of b)S.push(` nested tree ${k.path}: ${k.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 k of wt(p))S.push(` ${k}`)}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(`
171
- `)}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=ne(e.provider);return o===void 0?!1:(await o.applyDelta(e.path,r)).ok}async patchFromSnapshot(e,t,n){let r=ne(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=ne(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 fs(e.sourceCwd).catch(()=>({})),r=[];if(n.carry!==void 0&&n.carry.length>0){let o=await lo(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=ne(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=ne(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=ne(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 f=new Error(`agent ${e} not found in registry`);throw f.code=E.AgentNotInstalled,f}let n=await Ee(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:$d.homedir(),plan:n}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:Mt,clientInfo:{name:"hydra",version:ge}})}catch(f){throw await r.kill().catch(()=>{}),dt(f,r)}if(r.authMethods=An(o.authMethods),r.steeringSupported=In(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(f){throw await r.kill().catch(()=>{}),f}await r.kill().catch(()=>{});let d=new Map,c=Cr(t);d.set(e,c);let u=new Set;for(let f of this.sessions.values()){let g=await this.agentStoreKey(f.agentId,d);u.add(`${g}::${f.upstreamSessionId}`)}let l=await this.store.list().catch(()=>[]);for(let f of l){u.add(`${await this.agentStoreKey(f.agentId,d)}::${f.upstreamSessionId}`);for(let g of f.upstreamGenerations??[])u.add(`${await this.agentStoreKey(g.agentId,d)}::${g.upstreamSessionId}`)}let p=x.sessionsDir(),m=[],h=0;for(let f of a){let g=`${c}::${f.sessionId}`;if(u.has(g)){h+=1;continue}if($g(f.cwd,p)){h+=1;continue}let w=c,y=await this.tombstones.read(w,f.sessionId).catch(()=>{});if(!y&&c!==e&&(w=e,y=await this.tombstones.read(w,f.sessionId).catch(()=>{})),y){if(!rd(y,f.updatedAt)){h+=1;continue}await this.tombstones.remove(w,f.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${f.sessionId} (upstream updatedAt advanced past ${y.upstreamUpdatedAt??"<unset>"})`)}u.add(g);let v=`${Ae}${Ut()}`,b=new Date().toISOString(),S=f.updatedAt??b,k={sessionId:v,lineageId:mn(),upstreamSessionId:f.sessionId,agentId:e,cwd:f.cwd,pendingHistorySync:!0,interactive:!0,createdAt:S,updatedAt:S};f.title!==void 0&&(k.title=f.title);let C=to(k);await this.store.write(C),m.push({version:1,...C})}return{synced:m,skipped:h}}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 ot({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 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=E.AgentNotInstalled,i}let n=await Ee(t,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),r=Un(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:Mt,clientInfo:{name:"hydra",version:ge}}),a=i.agentCapabilities;o.authMethods=An(i.authMethods),o.steeringSupported=In(i);let d=vo(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=ko(c),p=bo(c),m=_t(c),h=rn(this.sessionDefaults,t),f=h?.value,g=e.configDefaults,w=h?.from??e.agentId,y=e.model??g?.model??f?.model,v;if(y&&y!==l){let R=Ot(y,p),T=e.model!==void 0?`model=${JSON.stringify(y)}`:g?.model!==void 0?`configDefaults.model=${JSON.stringify(y)}`:`sessionDefaults[${w}].model=${JSON.stringify(y)}`;if(R.kind==="exact"||R.kind==="none"){let M=await this.applySeedModel(o,u,y,T,m);M.accepted&&(l=y,v=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)}`,m);M.accepted&&(l=R.modelId,v=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(L=>L.modelId).join(", ");this.logger?.warn(`${T} not in agent's availableModels ([${M}]); skipping session/set_model, session will use ${JSON.stringify(l)}`)}}let b=So(c),S=Io(c),k=g?.mode??f?.mode;if(k&&k!==S){let R=g?.mode!==void 0?`configDefaults.mode=${JSON.stringify(k)}`:`sessionDefaults[${w}].mode=${JSON.stringify(k)}`;if(b.length>0&&!b.some(T=>T.id===k)){let T=b.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,k,R);T.accepted&&(S=k,Bt(T.result)&&(v=T.result))}}let C={...f??{},...g??{}};if(delete C.model,delete C.mode,Object.keys(C).length>0){let R=Wt(Bt(v)?v:c);for(let[T,M]of Object.entries(C)){let L=`sessionDefaults[${w}].${T}=${JSON.stringify(M)}`,J=R.find(q=>q.id===T);if(!J){this.logger?.warn(`${L}: agent does not currently advertise configId=${T}; skipping session/set_config_option`);continue}let $=dn(M,J.options.map(q=>q.value));if($.kind!=="exact"&&$.kind!=="resolved"){this.logger?.warn(`${L} ${$.kind}; skipping session/set_config_option`);continue}let W=$.kind==="resolved"?$.modelId:M;if(W!==J.currentValue)try{let q=await o.connection.request("session/set_config_option",{sessionId:u,configId:T,value:W});this.logger?.info(`${L}: session/set_config_option accepted`),Bt(q)&&(R=Wt(q),v=q)}catch(q){this.logger?.warn(`${L}: session/set_config_option rejected by agent (${q.message})`)}}}let A=Wt(Bt(v)?v:c);return{agent:o,upstreamSessionId:u,agentMeta:c._meta,agentCapabilities:a,initialModel:l,initialModels:p.length>0?p:void 0,initialModes:b.length>0?b:void 0,initialMode:S,initialConfigOptions:A.length>0?A:void 0,modelVerb:m}}catch(i){throw await o.kill().catch(()=>{}),dt(Md(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=E.AgentNotInstalled,a}let r=await Ee(n,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=Un(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:Mt,clientInfo:{name:"hydra",version:ge}}),d=a.agentCapabilities;i.authMethods=An(a.authMethods),i.steeringSupported=In(a);let c=vo(n),u=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...c&&{_meta:c}}),l=ko(u),p=qt(bo(u)),m=So(u),h=Io(u),f=qt(Wt(u));return{agent:i,upstreamSessionId:e,agentMeta:u._meta,agentCapabilities:d,initialModel:l,initialModels:p,initialModes:m.length>0?m:void 0,initialMode:h,initialConfigOptions:f,modelVerb:_t(u)}}catch(a){throw await i.kill().catch(()=>{}),dt(Md(a,i,t.agentId,{command:r.command,args:r.args,cwd:t.cwd}),i)}}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=E.AgentNotInstalled,d}let o=await Ee(r,[],{npmRegistry:this.npmRegistry}),i=t??fe(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:Mt,clientInfo:{name:"hydra",version:ge}});a.authMethods=An(d.authMethods),a.steeringSupported=In(d)}catch(d){throw await a.kill().catch(()=>{}),dt(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=E.AgentNotInstalled,n}return Ee(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=zt({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.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:Fd(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.onAttentionFlagsChange(t=>{this.mutateRecord(e.sessionId,{attentionFlags:t}).catch(()=>{})}),this.sessions.set(e.sessionId,e),this.invalidateListCache(),await this.enqueueMetaWrite(e.sessionId,async()=>{let t=await this.store.read(e.sessionId),n=Fg(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 loadHistory(e,t={}){return this.histories.load(e,t)}async loadToolBlob(e,t){return sn(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:Og(t.currentUsage),agentCommands:t.agentCommands,agentModes:t.agentModes,agentModels:t.agentModels,createdAt:t.createdAt,pendingHistorySync:t.pendingHistorySync,originatingClient:t.originatingClient,interactive:t.interactive,priority:t.priority,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,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=yt(r.update.prompt),a=Gr(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(Ae))return;let t=Ae+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=E.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,forkSynthesisState:e.forkSynthesisState,originatingClient:e.originatingClient,interactive:e.interactive,updatedAt:new Date(e.updatedAt).toISOString(),attachedClients:e.attachedCount,status:"warm",busy:e.turnStartedAt!==void 0,armedTasks:e.armedBackgroundTasks.length,...e.armedSince!==void 0?{armedSince:e.armedSince}:{},awaitingInput:e.awaitingInput,agentPid:e.agentPid}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Cn(t.sessionId),d=zt({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,forkSynthesisState:t.forkSynthesisState,originatingClient:t.originatingClient,interactive:d,priority:t.priority,updatedAt:c,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,armedTasks:t.armedBackgroundTasks.length,...t.armedSince!==void 0?{armedSince:t.armedSince}:{},awaitingInput:t.awaitingInput}}let n=await this.store.read(e).catch(()=>{});if(!n)return;let r=await Cn(n.sessionId),o=zt(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:Sn(n.currentUsage),importedFromMachine:n.importedFromMachine,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:o,priority:n.priority,updatedAt:i,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1}}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=>Td(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=>Cn(i.sessionId)));for(let i=0;i<o.length;i+=1){let a=r[i],d=o[i];n.add(a.sessionId);let c=zt({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,originatingClient:a.originatingClient,interactive:c,priority:a.priority,updatedAt:u,attachedClients:a.attachedCount,status:"warm",agentPid:a.agentPid,busy:a.turnStartedAt!==void 0,armedTasks:a.armedBackgroundTasks.length,...a.armedSince!==void 0?{armedSince:a.armedSince}:{},awaitingInput:a.awaitingInput,compactionState:a.compactionState,forkSynthesisState:a.forkSynthesisState})}return{entries:t,liveIds:n}}async coldRows(e,t,n){let r=[],o=e.filter(a=>!t.has(a.sessionId)&&Td(n.cwd,a)),i=await Promise.all(o.map(a=>Cn(a.sessionId)));for(let a=0;a<o.length;a+=1){let d=o[a],c=i[a],u=zt(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:Sn(d.currentUsage),importedFromMachine:d.importedFromMachine,importedFromUpstreamSessionId:d.importedFromUpstreamSessionId,parentSessionId:d.parentSessionId,forkedFromSessionId:d.forkedFromSessionId,forkedFromMessageId:d.forkedFromMessageId,originatingClient:d.originatingClient,interactive:u,priority:d.priority,updatedAt:l,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,compactionState:d.compactionState,forkSynthesisState:d.forkSynthesisState})}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=mn(),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=await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await _d(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let c of bd(i)){let u=await Ii(e,c);u&&(d[c]=u.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}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=E.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=`${Ae}${Ut()}`;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 S=new Error(`source session not found: ${e}`);throw S.code=E.SessionNotFound,S}let r=t.agentId??n.agentId,o=r!==n.agentId;if(o&&!await this.registry.getAgent(r)){let k=new Error(`agent ${r} not found in registry`);throw k.code=E.AgentNotInstalled,k}let i=await this.histories.load(e).catch(()=>[]),a=i,d,c=t.mode??"synthesis",u,l,p,m=12e4;if(c==="verbatim")if(t.forkAt!==void 0){let S=ns(i,t.forkAt);if(S<0){let k=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw k.code=E.InvalidParams,k}d=t.forkAt,a=i.slice(0,S+1)}else{let S=Lg(i);S?(d=S.messageId,a=i.slice(0,S.index+1)):(d="",a=i.slice(0,0))}else{if(t.forkAt!==void 0&&t.forkAt!==""){let k=ns(i,t.forkAt);if(k<0){let C=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw C.code=E.InvalidParams,C}d=t.forkAt,a=i.slice(0,k+1)}else d="",a=i;let S=await this.registry.getAgent(r);if(!S){let k=new Error(`agent ${r} not found in registry`);throw k.code=E.AgentNotInstalled,k}p=S,l=n.currentModel,u="running"}let h=await _d(e),f=c==="synthesis",g={...n,lineageId:mn(),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}:{}},w=bn({record:g,history:a,promptHistory:h.length>0?h:void 0,hydraVersion:ge,machine:an()}),y=`${Ae}${Ut()}`,v=t.cwd,b;if(t.cwd===void 0&&n.workspace!==void 0){let S=await this.deriveForkWorkspace(n.workspace,`${n.workspace.label}-fork-${y.slice(-6)}`);S!==void 0?(b=S,v=S.path):(v=n.workspace.sourceCwd,this.logger?.warn?.(`fork ${y}: could not derive an isolated workspace from ${n.workspace.path}; running unisolated in ${v}`))}return await this.writeImportedRecord({sessionId:y,bundle:w,cwd:v,...b!==void 0?{workspace:b}:{},forkedFromSessionId:e,forkedFromMessageId:d,...u!==void 0?{forkSynthesisState:u}:{}}),f&&(async()=>{try{let S=await Ee(p,[],{npmRegistry:this.npmRegistry}),k=await ys({agentId:r,cwd:t.cwd??x.sessionDir(e),plan:S,history:a,modelId:l,sessionId:e,logger:this.logger,timeoutMs:m});k&&k.synopsis?await this.mutateRecord(y,{synopsis:k.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(y,{},["forkSynthesisState"]))}catch(S){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${S.message}`);try{await this.mutateRecord(y,{},["forkSynthesisState"])}catch(k){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${k.message}`)}}})(),{sessionId:y,forkedFromSessionId:e,forkedAt:d}}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 Ai(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await kt.utimes(x.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await Rd(x.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}:{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=Cr(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 Cn(e),o=zt(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:Od(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.interactive!==void 0&&(n.interactive=t.interactive),t.cwd!==void 0&&(n.cwd=t.cwd),await this.mutateRecord(e,n)}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(fd(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 Ta(t.sessionId).catch(()=>[]);if(n.length===0)continue;let r=Date.now(),o=n.filter(d=>r-d.enqueuedAt<Ed),i=n.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${Ed/1e3}s)`),await ln(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 ln(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 $g(s,e){if(typeof s!="string"||s.length===0)return!1;let t=Rn.resolve(s),n=Rn.resolve(e);return t===n||t.startsWith(n+Rn.sep)}function Td(s,e){if(s===void 0||s.length===0)return!0;let t=wo(s);if(wo(e.cwd)===t)return!0;let n=e.workspace?.sourceCwd;return n!==void 0&&wo(n)===t}function wo(s){return s.length>1&&s.endsWith("/")?s.replace(/\/+$/,""):s}function Fg(s,e){let n=(s.mergedAvailableCommands().length>0?s.agentOnlyAdvertisedCommands().map(u=>u.description!==void 0?{name:u.name,description:u.description}:{name:u.name}):void 0)??e?.agentCommands,r=s.availableModes(),i=(r.length>0?r.map(u=>{let l={id:u.id};return u.name!==void 0&&(l.name=u.name),u.description!==void 0&&(l.description=u.description),l}):void 0)??e?.agentModes,a=s.availableModels(),c=(a.length>0?a.map(u=>{let l={modelId:u.modelId};return u.name!==void 0&&(l.name=u.name),u.description!==void 0&&(l.description=u.description),l}):void 0)??e?.agentModels;return to({sessionId:s.sessionId,lineageId:e?.lineageId??mn(),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:Fd(s.persistableUsage)??e?.currentUsage,agentCommands:n,agentModes:i,agentModels:c,parentSessionId:s.parentSessionId??e?.parentSessionId,forkedFromSessionId:s.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId??e?.forkedFromMessageId,originatingClient:s.originatingClient??e?.originatingClient,interactive:s.interactive??e?.interactive,priority:s.priority??e?.priority,forwardedEnv:s.forwardedEnv??e?.forwardedEnv,workspace:s.workspace,attentionFlags:s.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?Od(e,s.agentId,s.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(s.createdAt).toISOString()})}function Fd(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 Og(s){return s?{...s}:void 0}function Ng(s){return(s.extendsChain??[s.id]).some(t=>t==="claude-acp"||t.startsWith("claude-acp-"))}var Dg=[{type:"system",subtype:"background_tasks_changed"}];function vo(s,e={}){if(!Ng(s))return;let t={extraArgs:{"thinking-display":"summarized"}};return e.model&&(t.model=e.model),{claudeCode:{options:t,emitRawSDKMessages:Dg}}}function Ss(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=jg(s,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function ko(s){return Ss(s,{nestedKey:"models",configId:"model",fromObject:e=>we(e.currentModelId)??we(e.currentModel)??we(e.modelId)??we(e.model),fromConfig:e=>we(e.currentValue)})}function dt(s,e){if(!s||typeof s!="object")return s;let t=s;if(t.code!==E.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=E.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function Pd(s){return/^[A-Za-z0-9_\-./=:@]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function Md(s,e,t,n){if(s&&typeof s=="object"&&s.code===E.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 ${Pd(n.cwd)} && ${[n.command,...n.args].map(Pd).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(`
172
- `));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 In(s){return s._meta?.steering?.supported===!0}function An(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 we(s){if(typeof s!="string")return;let e=s.trim();return e.length>0?e:void 0}function jg(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 Bt(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.configOptions)}function Wt(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=we(r.id);if(!o||o==="model"||o==="mode"||o==="agent")continue;let i=Vr(r.options);if(i.length===0)continue;let a=we(r.description);t.push({id:o,name:we(r.name)??o,...a?{description:a}:{},category:we(r.category)??"other",type:"select",currentValue:we(r.currentValue)??i[0].value,options:i})}return t}function qt(s){return s.length>0?s:void 0}function bo(s){return Ss(s,{nestedKey:"models",configId:"model",fromObject:e=>{let t=fn(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=fn(e.options);return t.length>0?t:void 0}})??[]}function So(s){return Ss(s,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=ts(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=ts(e.options);return t.length>0?t:void 0}})??[]}function Io(s){return Ss(s,{nestedKey:"modes",configId:"mode",fromObject:e=>we(e.currentModeId)??we(e.currentMode)??we(e.modeId)??we(e.mode),fromConfig:e=>we(e.currentValue)})}function Lg(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 _d(s){try{let e=await kt.readFile(x.tuiHistoryFile(s),"utf8"),t=[];for(let n of e.split(`
173
- `))if(n.length!==0)try{let r=JSON.parse(n);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function Od(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}]:[],m=p[p.length-1];if(m&&m.upstreamSessionId===t){if(p.length>=2){let h=p[p.length-2];if(h){let f=l(h);p[p.length-2]={...h,...f!==void 0&&h.cost===void 0?{cost:f}:{},...i!==void 0&&h.usedAtEnd===void 0?{usedAtEnd:i}:{}}}}return(c!==void 0&&m.reason===void 0||a!==void 0&&m.usedAtStart===void 0||d!==void 0&&m.lifetimeCostAtStart===void 0)&&(p[p.length-1]={...m,...c!==void 0&&m.reason===void 0?{reason:c,...u!==void 0?{runId:u}:{}}:{},...a!==void 0&&m.usedAtStart===void 0?{usedAtStart:a}:{},...d!==void 0&&m.lifetimeCostAtStart===void 0?{lifetimeCostAtStart:d}:{}}),p}return m&&m.endedAt===void 0&&(p[p.length-1]={...m,endedAt:n,...(()=>{let h=l(m);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 Cn(s){try{let e=await kt.stat(x.historyFile(s));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function zt(s,e){return s.interactive!==void 0?s.interactive:s.originatingClient?.name===hs?!1:e?!0:void 0}import{spawn as Hg}from"child_process";import*as Cs from"fs";import*as Ze from"fs/promises";import*as Rs from"path";import Ug from"pino-roll";var Is=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 Nd from"fs/promises";import*as Ao from"path";var As=process.platform!=="win32";var Bg=1e3,Wg=6e4,Co=3e3,Jt=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??Bg,this.restartCapMs=r.restartCapMs??Wg;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 Ze.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()},Co);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 xn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw xn(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 xn(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 xn(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 xn(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{}},Co);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 Is(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await Ze.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 Ze.readFile(n,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&Ro(r)){try{process.kill(r,"SIGTERM")}catch{}let o=Date.now()+Co;for(;Date.now()<o&&Ro(r);)await new Promise(i=>setTimeout(i,50));if(Ro(r))try{process.kill(r,"SIGKILL")}catch{}}await Ze.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=Rs.dirname(this.adapter.paths.logFile(r.name)),a;try{await Ze.mkdir(i,{recursive:!0}),a=await Ug({file:Rs.join(i,`${r.name}.log`),size:"5m",mkdir:!0,symlink:As,limit:{count:5}}),a.on("error",g=>{e.failureReason=`log stream: ${g.message}`})}catch(g){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${g.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})
171
+ `)}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=ne(e.provider);return o===void 0?!1:(await o.applyDelta(e.path,r)).ok}async patchFromSnapshot(e,t,n){let r=ne(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=ne(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 fs(e.sourceCwd).catch(()=>({})),r=[];if(n.carry!==void 0&&n.carry.length>0){let o=await lo(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=ne(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=ne(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=ne(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 f=new Error(`agent ${e} not found in registry`);throw f.code=E.AgentNotInstalled,f}let n=await Ee(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:$d.homedir(),plan:n}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:Mt,clientInfo:{name:"hydra",version:ge}})}catch(f){throw await r.kill().catch(()=>{}),dt(f,r)}if(r.authMethods=An(o.authMethods),r.steeringSupported=In(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(f){throw await r.kill().catch(()=>{}),f}await r.kill().catch(()=>{});let d=new Map,c=Cr(t);d.set(e,c);let u=new Set;for(let f of this.sessions.values()){let g=await this.agentStoreKey(f.agentId,d);u.add(`${g}::${f.upstreamSessionId}`)}let l=await this.store.list().catch(()=>[]);for(let f of l){u.add(`${await this.agentStoreKey(f.agentId,d)}::${f.upstreamSessionId}`);for(let g of f.upstreamGenerations??[])u.add(`${await this.agentStoreKey(g.agentId,d)}::${g.upstreamSessionId}`)}let p=x.sessionsDir(),m=[],h=0;for(let f of a){let g=`${c}::${f.sessionId}`;if(u.has(g)){h+=1;continue}if($g(f.cwd,p)){h+=1;continue}let w=c,y=await this.tombstones.read(w,f.sessionId).catch(()=>{});if(!y&&c!==e&&(w=e,y=await this.tombstones.read(w,f.sessionId).catch(()=>{})),y){if(!rd(y,f.updatedAt)){h+=1;continue}await this.tombstones.remove(w,f.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${f.sessionId} (upstream updatedAt advanced past ${y.upstreamUpdatedAt??"<unset>"})`)}u.add(g);let v=`${Ae}${Ut()}`,b=new Date().toISOString(),S=f.updatedAt??b,k={sessionId:v,lineageId:mn(),upstreamSessionId:f.sessionId,agentId:e,cwd:f.cwd,pendingHistorySync:!0,interactive:!0,createdAt:S,updatedAt:S};f.title!==void 0&&(k.title=f.title);let C=to(k);await this.store.write(C),m.push({version:1,...C})}return{synced:m,skipped:h}}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 ot({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 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=E.AgentNotInstalled,i}let n=await Ee(t,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),r=Un(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:Mt,clientInfo:{name:"hydra",version:ge}}),a=i.agentCapabilities;o.authMethods=An(i.authMethods),o.steeringSupported=In(i);let d=vo(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=ko(c),p=bo(c),m=_t(c),h=rn(this.sessionDefaults,t),f=h?.value,g=e.configDefaults,w=h?.from??e.agentId,y=e.model??g?.model??f?.model,v;if(y&&y!==l){let R=Ot(y,p),T=e.model!==void 0?`model=${JSON.stringify(y)}`:g?.model!==void 0?`configDefaults.model=${JSON.stringify(y)}`:`sessionDefaults[${w}].model=${JSON.stringify(y)}`;if(R.kind==="exact"||R.kind==="none"){let M=await this.applySeedModel(o,u,y,T,m);M.accepted&&(l=y,v=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)}`,m);M.accepted&&(l=R.modelId,v=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 b=So(c),S=Io(c),k=g?.mode??f?.mode;if(k&&k!==S){let R=g?.mode!==void 0?`configDefaults.mode=${JSON.stringify(k)}`:`sessionDefaults[${w}].mode=${JSON.stringify(k)}`;if(b.length>0&&!b.some(T=>T.id===k)){let T=b.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,k,R);T.accepted&&(S=k,Bt(T.result)&&(v=T.result))}}let C={...f??{},...g??{}};if(delete C.model,delete C.mode,Object.keys(C).length>0){let R=Wt(Bt(v)?v:c);for(let[T,M]of Object.entries(C)){let H=`sessionDefaults[${w}].${T}=${JSON.stringify(M)}`,J=R.find(q=>q.id===T);if(!J){this.logger?.warn(`${H}: agent does not currently advertise configId=${T}; skipping session/set_config_option`);continue}let $=dn(M,J.options.map(q=>q.value));if($.kind!=="exact"&&$.kind!=="resolved"){this.logger?.warn(`${H} ${$.kind}; skipping session/set_config_option`);continue}let W=$.kind==="resolved"?$.modelId:M;if(W!==J.currentValue)try{let q=await o.connection.request("session/set_config_option",{sessionId:u,configId:T,value:W});this.logger?.info(`${H}: session/set_config_option accepted`),Bt(q)&&(R=Wt(q),v=q)}catch(q){this.logger?.warn(`${H}: session/set_config_option rejected by agent (${q.message})`)}}}let A=Wt(Bt(v)?v:c);return{agent:o,upstreamSessionId:u,agentMeta:c._meta,agentCapabilities:a,initialModel:l,initialModels:p.length>0?p:void 0,initialModes:b.length>0?b:void 0,initialMode:S,initialConfigOptions:A.length>0?A:void 0,modelVerb:m}}catch(i){throw await o.kill().catch(()=>{}),dt(Md(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=E.AgentNotInstalled,a}let r=await Ee(n,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=Un(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:Mt,clientInfo:{name:"hydra",version:ge}}),d=a.agentCapabilities;i.authMethods=An(a.authMethods),i.steeringSupported=In(a);let c=vo(n),u=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...c&&{_meta:c}}),l=ko(u),p=qt(bo(u)),m=So(u),h=Io(u),f=qt(Wt(u));return{agent:i,upstreamSessionId:e,agentMeta:u._meta,agentCapabilities:d,initialModel:l,initialModels:p,initialModes:m.length>0?m:void 0,initialMode:h,initialConfigOptions:f,modelVerb:_t(u)}}catch(a){throw await i.kill().catch(()=>{}),dt(Md(a,i,t.agentId,{command:r.command,args:r.args,cwd:t.cwd}),i)}}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=E.AgentNotInstalled,d}let o=await Ee(r,[],{npmRegistry:this.npmRegistry}),i=t??fe(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:Mt,clientInfo:{name:"hydra",version:ge}});a.authMethods=An(d.authMethods),a.steeringSupported=In(d)}catch(d){throw await a.kill().catch(()=>{}),dt(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=E.AgentNotInstalled,n}return Ee(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=zt({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.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:Fd(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.onAttentionFlagsChange(t=>{this.mutateRecord(e.sessionId,{attentionFlags:t}).catch(()=>{})}),this.sessions.set(e.sessionId,e),this.invalidateListCache(),await this.enqueueMetaWrite(e.sessionId,async()=>{let t=await this.store.read(e.sessionId),n=Fg(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 loadHistory(e,t={}){return this.histories.load(e,t)}async loadToolBlob(e,t){return sn(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:Og(t.currentUsage),agentCommands:t.agentCommands,agentModes:t.agentModes,agentModels:t.agentModels,createdAt:t.createdAt,pendingHistorySync:t.pendingHistorySync,originatingClient:t.originatingClient,interactive:t.interactive,priority:t.priority,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,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=yt(r.update.prompt),a=Gr(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(Ae))return;let t=Ae+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=E.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,forkSynthesisState:e.forkSynthesisState,originatingClient:e.originatingClient,interactive:e.interactive,updatedAt:new Date(e.updatedAt).toISOString(),attachedClients:e.attachedCount,status:"warm",busy:e.turnStartedAt!==void 0,armedTasks:e.armedBackgroundTasks.length,...e.armedSince!==void 0?{armedSince:e.armedSince}:{},awaitingInput:e.awaitingInput,agentPid:e.agentPid}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Cn(t.sessionId),d=zt({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,forkSynthesisState:t.forkSynthesisState,originatingClient:t.originatingClient,interactive:d,priority:t.priority,updatedAt:c,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,armedTasks:t.armedBackgroundTasks.length,...t.armedSince!==void 0?{armedSince:t.armedSince}:{},awaitingInput:t.awaitingInput}}let n=await this.store.read(e).catch(()=>{});if(!n)return;let r=await Cn(n.sessionId),o=zt(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:Sn(n.currentUsage),importedFromMachine:n.importedFromMachine,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:o,priority:n.priority,updatedAt:i,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1}}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=>Td(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=>Cn(i.sessionId)));for(let i=0;i<o.length;i+=1){let a=r[i],d=o[i];n.add(a.sessionId);let c=zt({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,originatingClient:a.originatingClient,interactive:c,priority:a.priority,updatedAt:u,attachedClients:a.attachedCount,status:"warm",agentPid:a.agentPid,busy:a.turnStartedAt!==void 0,armedTasks:a.armedBackgroundTasks.length,...a.armedSince!==void 0?{armedSince:a.armedSince}:{},awaitingInput:a.awaitingInput,compactionState:a.compactionState,forkSynthesisState:a.forkSynthesisState})}return{entries:t,liveIds:n}}async coldRows(e,t,n){let r=[],o=e.filter(a=>!t.has(a.sessionId)&&Td(n.cwd,a)),i=await Promise.all(o.map(a=>Cn(a.sessionId)));for(let a=0;a<o.length;a+=1){let d=o[a],c=i[a],u=zt(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:Sn(d.currentUsage),importedFromMachine:d.importedFromMachine,importedFromUpstreamSessionId:d.importedFromUpstreamSessionId,parentSessionId:d.parentSessionId,forkedFromSessionId:d.forkedFromSessionId,forkedFromMessageId:d.forkedFromMessageId,originatingClient:d.originatingClient,interactive:u,priority:d.priority,updatedAt:l,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,compactionState:d.compactionState,forkSynthesisState:d.forkSynthesisState})}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=mn(),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=await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await _d(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let c of bd(i)){let u=await Ii(e,c);u&&(d[c]=u.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}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=E.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=`${Ae}${Ut()}`;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 S=new Error(`source session not found: ${e}`);throw S.code=E.SessionNotFound,S}let r=t.agentId??n.agentId,o=r!==n.agentId;if(o&&!await this.registry.getAgent(r)){let k=new Error(`agent ${r} not found in registry`);throw k.code=E.AgentNotInstalled,k}let i=await this.histories.load(e).catch(()=>[]),a=i,d,c=t.mode??"synthesis",u,l,p,m=12e4;if(c==="verbatim")if(t.forkAt!==void 0){let S=ns(i,t.forkAt);if(S<0){let k=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw k.code=E.InvalidParams,k}d=t.forkAt,a=i.slice(0,S+1)}else{let S=Hg(i);S?(d=S.messageId,a=i.slice(0,S.index+1)):(d="",a=i.slice(0,0))}else{if(t.forkAt!==void 0&&t.forkAt!==""){let k=ns(i,t.forkAt);if(k<0){let C=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw C.code=E.InvalidParams,C}d=t.forkAt,a=i.slice(0,k+1)}else d="",a=i;let S=await this.registry.getAgent(r);if(!S){let k=new Error(`agent ${r} not found in registry`);throw k.code=E.AgentNotInstalled,k}p=S,l=n.currentModel,u="running"}let h=await _d(e),f=c==="synthesis",g={...n,lineageId:mn(),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}:{}},w=bn({record:g,history:a,promptHistory:h.length>0?h:void 0,hydraVersion:ge,machine:an()}),y=`${Ae}${Ut()}`,v=t.cwd,b;if(t.cwd===void 0&&n.workspace!==void 0){let S=await this.deriveForkWorkspace(n.workspace,`${n.workspace.label}-fork-${y.slice(-6)}`);S!==void 0?(b=S,v=S.path):(v=n.workspace.sourceCwd,this.logger?.warn?.(`fork ${y}: could not derive an isolated workspace from ${n.workspace.path}; running unisolated in ${v}`))}return await this.writeImportedRecord({sessionId:y,bundle:w,cwd:v,...b!==void 0?{workspace:b}:{},forkedFromSessionId:e,forkedFromMessageId:d,...u!==void 0?{forkSynthesisState:u}:{}}),f&&(async()=>{try{let S=await Ee(p,[],{npmRegistry:this.npmRegistry}),k=await ys({agentId:r,cwd:t.cwd??x.sessionDir(e),plan:S,history:a,modelId:l,sessionId:e,logger:this.logger,timeoutMs:m});k&&k.synopsis?await this.mutateRecord(y,{synopsis:k.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(y,{},["forkSynthesisState"]))}catch(S){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${S.message}`);try{await this.mutateRecord(y,{},["forkSynthesisState"])}catch(k){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${k.message}`)}}})(),{sessionId:y,forkedFromSessionId:e,forkedAt:d}}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 Ai(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await kt.utimes(x.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await Rd(x.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}:{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=Cr(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 Cn(e),o=zt(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:Od(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.interactive!==void 0&&(n.interactive=t.interactive),t.cwd!==void 0&&(n.cwd=t.cwd),await this.mutateRecord(e,n)}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(fd(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 Ta(t.sessionId).catch(()=>[]);if(n.length===0)continue;let r=Date.now(),o=n.filter(d=>r-d.enqueuedAt<Ed),i=n.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${Ed/1e3}s)`),await ln(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 ln(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 $g(s,e){if(typeof s!="string"||s.length===0)return!1;let t=Rn.resolve(s),n=Rn.resolve(e);return t===n||t.startsWith(n+Rn.sep)}function Td(s,e){if(s===void 0||s.length===0)return!0;let t=wo(s);if(wo(e.cwd)===t)return!0;let n=e.workspace?.sourceCwd;return n!==void 0&&wo(n)===t}function wo(s){return s.length>1&&s.endsWith("/")?s.replace(/\/+$/,""):s}function Fg(s,e){let n=(s.mergedAvailableCommands().length>0?s.agentOnlyAdvertisedCommands().map(u=>u.description!==void 0?{name:u.name,description:u.description}:{name:u.name}):void 0)??e?.agentCommands,r=s.availableModes(),i=(r.length>0?r.map(u=>{let l={id:u.id};return u.name!==void 0&&(l.name=u.name),u.description!==void 0&&(l.description=u.description),l}):void 0)??e?.agentModes,a=s.availableModels(),c=(a.length>0?a.map(u=>{let l={modelId:u.modelId};return u.name!==void 0&&(l.name=u.name),u.description!==void 0&&(l.description=u.description),l}):void 0)??e?.agentModels;return to({sessionId:s.sessionId,lineageId:e?.lineageId??mn(),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:Fd(s.persistableUsage)??e?.currentUsage,agentCommands:n,agentModes:i,agentModels:c,parentSessionId:s.parentSessionId??e?.parentSessionId,forkedFromSessionId:s.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId??e?.forkedFromMessageId,originatingClient:s.originatingClient??e?.originatingClient,interactive:s.interactive??e?.interactive,priority:s.priority??e?.priority,forwardedEnv:s.forwardedEnv??e?.forwardedEnv,workspace:s.workspace,attentionFlags:s.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?Od(e,s.agentId,s.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(s.createdAt).toISOString()})}function Fd(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 Og(s){return s?{...s}:void 0}function Ng(s){return(s.extendsChain??[s.id]).some(t=>t==="claude-acp"||t.startsWith("claude-acp-"))}var Dg=[{type:"system",subtype:"background_tasks_changed"}];function vo(s,e={}){if(!Ng(s))return;let t={extraArgs:{"thinking-display":"summarized"}};return e.model&&(t.model=e.model),{claudeCode:{options:t,emitRawSDKMessages:Dg}}}function Ss(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=jg(s,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function ko(s){return Ss(s,{nestedKey:"models",configId:"model",fromObject:e=>we(e.currentModelId)??we(e.currentModel)??we(e.modelId)??we(e.model),fromConfig:e=>we(e.currentValue)})}function dt(s,e){if(!s||typeof s!="object")return s;let t=s;if(t.code!==E.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=E.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function Pd(s){return/^[A-Za-z0-9_\-./=:@]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function Md(s,e,t,n){if(s&&typeof s=="object"&&s.code===E.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 ${Pd(n.cwd)} && ${[n.command,...n.args].map(Pd).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(`
172
+ `));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 In(s){return s._meta?.steering?.supported===!0}function An(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 we(s){if(typeof s!="string")return;let e=s.trim();return e.length>0?e:void 0}function jg(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 Bt(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.configOptions)}function Wt(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=we(r.id);if(!o||o==="model"||o==="mode"||o==="agent")continue;let i=Vr(r.options);if(i.length===0)continue;let a=we(r.description);t.push({id:o,name:we(r.name)??o,...a?{description:a}:{},category:we(r.category)??"other",type:"select",currentValue:we(r.currentValue)??i[0].value,options:i})}return t}function qt(s){return s.length>0?s:void 0}function bo(s){return Ss(s,{nestedKey:"models",configId:"model",fromObject:e=>{let t=fn(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=fn(e.options);return t.length>0?t:void 0}})??[]}function So(s){return Ss(s,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=ts(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=ts(e.options);return t.length>0?t:void 0}})??[]}function Io(s){return Ss(s,{nestedKey:"modes",configId:"mode",fromObject:e=>we(e.currentModeId)??we(e.currentMode)??we(e.modeId)??we(e.mode),fromConfig:e=>we(e.currentValue)})}function Hg(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 _d(s){try{let e=await kt.readFile(x.tuiHistoryFile(s),"utf8"),t=[];for(let n of e.split(`
173
+ `))if(n.length!==0)try{let r=JSON.parse(n);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function Od(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}]:[],m=p[p.length-1];if(m&&m.upstreamSessionId===t){if(p.length>=2){let h=p[p.length-2];if(h){let f=l(h);p[p.length-2]={...h,...f!==void 0&&h.cost===void 0?{cost:f}:{},...i!==void 0&&h.usedAtEnd===void 0?{usedAtEnd:i}:{}}}}return(c!==void 0&&m.reason===void 0||a!==void 0&&m.usedAtStart===void 0||d!==void 0&&m.lifetimeCostAtStart===void 0)&&(p[p.length-1]={...m,...c!==void 0&&m.reason===void 0?{reason:c,...u!==void 0?{runId:u}:{}}:{},...a!==void 0&&m.usedAtStart===void 0?{usedAtStart:a}:{},...d!==void 0&&m.lifetimeCostAtStart===void 0?{lifetimeCostAtStart:d}:{}}),p}return m&&m.endedAt===void 0&&(p[p.length-1]={...m,endedAt:n,...(()=>{let h=l(m);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 Cn(s){try{let e=await kt.stat(x.historyFile(s));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function zt(s,e){return s.interactive!==void 0?s.interactive:s.originatingClient?.name===hs?!1:e?!0:void 0}import{spawn as Lg}from"child_process";import*as Cs from"fs";import*as Ze from"fs/promises";import*as Rs from"path";import Ug from"pino-roll";var Is=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 Nd from"fs/promises";import*as Ao from"path";var As=process.platform!=="win32";var Bg=1e3,Wg=6e4,Co=3e3,Jt=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??Bg,this.restartCapMs=r.restartCapMs??Wg;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 Ze.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()},Co);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 xn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw xn(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 xn(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 xn(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 xn(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{}},Co);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 Is(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await Ze.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 Ze.readFile(n,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&Ro(r)){try{process.kill(r,"SIGTERM")}catch{}let o=Date.now()+Co;for(;Date.now()<o&&Ro(r);)await new Promise(i=>setTimeout(i,50));if(Ro(r))try{process.kill(r,"SIGKILL")}catch{}}await Ze.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=Rs.dirname(this.adapter.paths.logFile(r.name)),a;try{await Ze.mkdir(i,{recursive:!0}),a=await Ug({file:Rs.join(i,`${r.name}.log`),size:"5m",mkdir:!0,symlink:As,limit:{count:5}}),a.on("error",g=>{e.failureReason=`log stream: ${g.message}`})}catch(g){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${g.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})
174
174
  `);let d=this.tokenRegistry?.mint(r.name,this.adapter.tokenRole)??n.serviceToken;e.processToken=d,e.version=void 0;let c={...Bn(),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
175
- `),a.end();return}let p=fe(u),m=[...l,...r.args].map(fe),h;try{let g=Et(p,m);h=Hg(g.command,g.args,{env:c,stdio:["ignore","pipe","pipe"],detached:!1,shell:g.shell,windowsHide:!0})}catch(g){a.write(`[hydra-acp] failed to spawn ${r.name}: ${g.message}
175
+ `),a.end();return}let p=fe(u),m=[...l,...r.args].map(fe),h;try{let g=Et(p,m);h=Lg(g.command,g.args,{env:c,stdio:["ignore","pipe","pipe"],detached:!1,shell:g.shell,windowsHide:!0})}catch(g){a.write(`[hydra-acp] failed to spawn ${r.name}: ${g.message}
176
176
  `),a.end(),this.scheduleRestart(e,t);return}let f=g=>{try{a.write(typeof g=="string"?g:g.toString())}catch{}};if(h.stdout?.on("data",f),h.stderr?.on("data",f),typeof h.pid=="number")try{Cs.writeFileSync(this.adapter.paths.pidFile(r.name),`${h.pid}
177
177
  `,{encoding:"utf8",mode:384})}catch(g){a.write(`[hydra-acp] failed to write pid file for ${r.name}: ${g.message}
178
178
  `)}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",g=>{a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} error: ${g.message}
@@ -181,19 +181,19 @@ ${C}`)}await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),th
181
181
  `);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 Ro(s){try{return process.kill(s,0),!0}catch{return!1}}function xn(s,e){return s.code=e,s}G();var qg={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:x.extensionsDir,logFile:x.extensionLogFile,pidFile:x.extensionPidFile}},xs=class extends Jt{constructor(e,t,n={}){super(e,qg,t,n)}};G();var zg={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:x.transformersDir,logFile:x.transformerLogFile,pidFile:x.transformerPidFile}},Es=class extends Jt{connected=new Map;constructor(e,t,n={}){super(e,zg,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 Ts=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{}}};G();G();import*as xo from"fs/promises";async function Dd(s){await xo.writeFile(x.pidFile(),JSON.stringify(s)+`
182
182
  `,{encoding:"utf8",mode:384})}G();import*as Tn from"fs/promises";import*as Ps from"path";var En=s=>{process.stderr.write(s+`
183
183
  `)};function Eo(s){En=s??(e=>process.stderr.write(e+`
184
- `))}async function jd(s,e){let t=je();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=Ps.join(x.agentsDir(),t),a;try{a=await Tn.readdir(i,{withFileTypes:!0})}catch(d){let c=d;if(c.code==="ENOENT")return;En(`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=Ps.join(i,c),m;try{m=await Tn.readdir(p,{withFileTypes:!0})}catch(h){En(`hydra-acp: prune: failed to read ${p}: ${h.message}`);continue}for(let h of m){if(!h.isDirectory())continue;let f=h.name;if(f===u||l.has(f)||f.includes(".partial-"))continue;let g=Ps.join(p,f);try{await Tn.rm(g,{recursive:!0,force:!0}),En(`hydra-acp: pruned stale ${c} ${f} (${g})`)}catch(w){En(`hydra-acp: prune: failed to remove ${g}: ${w.message}`)}}}}function Ld(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 xr(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 To(s){let e=s.maxDeletions??200,t=(m,h)=>{s.logger&&s.logger[m](`session-gc: ${h}`)},n=Date.now(),r=s.maxAgeMs>0?n-s.maxAgeMs:Number.POSITIVE_INFINITY,o=await s.manager.list({includeNonInteractive:!0}).catch(m=>(t("warn",`manager.list failed: ${m.message}`),[])),i=[];for(let m of o){if(m.status!=="cold")continue;if((s.selection??"explicit")==="explicit"){if(m.interactive!==!1)continue}else if(m.interactive===!0)continue;let f=Date.parse(m.updatedAt);Number.isFinite(f)&&(s.maxAgeMs>0&&f>r||i.push({sessionId:m.sessionId,lastUsedMs:f}))}if(i.length===0)return s.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((m,h)=>m.lastUsedMs-h.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,c=0,u=0;for(let{sessionId:m}of a)try{await s.manager.deleteRecord(m,"expired")&&(c+=1)}catch(h){u+=1,t("warn",`delete ${m} failed: ${h.message}`)}let l=i.length-a.length;if(s.verbose||c>0||u>0){let m=(s.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${c} ${m} session(s) older than ${Jg(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 Hd(s){let e,t=!1,n=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!n){n=!0;try{await To({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 Jg(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 Vg}from"crypto";function Pn(s){if(Array.isArray(s))return s.map(Pn);if(s!==null&&typeof s=="object"){let e={};for(let t of Object.keys(s).sort())e[t]=Pn(s[t]);return e}return s}function Ud(s){let e={};for(let[n,r]of Object.entries(s)){let o=or(n);if(o.nested){let i={};for(let[a,d]of Object.entries(r??{}))ir(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(Pn(e));return Vg("sha256").update(t).digest("hex").slice(0,16)}function Bd(s,e){let t=[],n=(r,o)=>JSON.stringify(Pn(r))!==JSON.stringify(Pn(o));for(let r of Object.keys(e)){let o=or(r),i=e[r],a=s[r];if(o.nested){for(let d of Object.keys(i??{})){if(ir(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 qd from"fs/promises";G();var Gg=3e3;async function Wd(){try{return(await qd.stat(x.config())).mtimeMs}catch{return}}function zd(s){let e=s.intervalMs??Gg,t=!1,n,r,o=Wd().then(d=>{r=d}),i=async()=>{await o;let d=await Wd();if(d===r)return;r=d;let c;try{c=await nn()}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=Bd(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)}}G();Ne();import*as Gd from"path";import{createHash as Kg,randomBytes as Qg,timingSafeEqual as Yg}from"crypto";var Kd="hydra_session_",Xg=3600*24*30,Jd=12,Zg=32,em=50;function tm(){return Gd.join(x.home(),"session-tokens.json")}function Vd(s){return Kg("sha256").update(s).digest("hex")}function Qd(s){return Qg(s).toString("hex")}function nm(){return Qd(Jd).slice(0,Jd*2)}function sm(){return`${Kd}${Qd(Zg)}`}var Ms=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=tm(),n=await ie(t);n&&Array.isArray(n.records)&&(e=n.records.filter(rm));let r=new s(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=sm(),n=Vd(t),r=nm(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:Xg,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(Kd))return;let t=Vd(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||!Yg(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(()=>{})},em))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>le(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 rm(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 Yd="Bearer ",_s=class{constructor(e){this.token=e}token;async validate(e){return im(e,this.token)?"service":void 0}rotate(e){this.token=e}},$s=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},Fs=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 Xd(s){return async function(t,n){let r=t.headers.authorization;if(!r||!r.startsWith(Yd)){n.code(401).send({error:"Missing bearer token"});return}let o=r.slice(Yd.length).trim(),i=await s.validator.validate(o);if(!i){n.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function Zd(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 Os=class{tokens=new Map;mint(e,t){let n=sr();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}`}},om=new Set(["GET /v1/sessions","GET /v1/sessions/:id","GET /v1/config"]);function ec(s,e){return e?om.has(`${s} ${e}`):!1}function im(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 Ns=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 No from"fs";import*as Tc from"os";import*as Ws from"path";import*as Do from"readline";G();function Po(s){return Math.floor(s/4)}function tc(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+=bt(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=am(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 am(s){let e=0;return typeof s.title=="string"&&(e+=s.title.length),e+=Ds(s.rawInput),e+=bt(s.content),e+=Ds(s.rawOutput),e}function Ds(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+=Ds(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+=Ds(n);return t}return 0}function bt(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+=bt(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?bt(e.text):e.type==="diff"?bt(e.oldText)+bt(e.newText):e.content!==void 0?bt(e.content):0}function nc(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=Po(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}G();import{posix as dm}from"path";import cm from"strip-ansi";function Mn(s){if(!s||typeof s!="object")return;let e=s;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}function Mo(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 um=/[\x00-\x08\x0b-\x1f\x7f]/g;function Pe(s){return cm(s).replace(um,"")}function re(s){return Pe(s).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function ic(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 ym(t);case"agent_thought_chunk":case"agent_thought":return wm(t);case"user_message_chunk":return vm(t);case"prompt_received":return km(t);case"tool_call":return bm(t,e);case"tool_call_update":return Rm(t,e);case"plan":return Pm(t);case"current_mode_update":return Mm(t);case"_hydra_current_model_update":return _m(t);case"turn_complete":return $m(t);case"_hydra_turn_started":return oc(t,"turn-started");case"_hydra_turn_ended":return oc(t,"turn-ended");case"usage_update":return hm(t);case"available_commands_update":return gm(t);case"_hydra_available_modes_update":return mm(t);case"session_info_update":return fm(t);case"config_option_update":return lm(t);default:return{kind:"unknown",sessionUpdate:n,raw:s}}}function lm(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 fm(s){let e=se(s,"title"),t=e!==void 0?re(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 pm(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:re(r)};typeof n.description=="string"&&(o.description=re(n.description)),e.push(o)}return e}function gm(s){let e=s.availableCommands??s.commands;return Array.isArray(e)?{kind:"available-commands",commands:pm(e)}:null}function mm(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:re(r.id)};typeof r.name=="string"&&(o.name=re(r.name)),typeof r.description=="string"&&(o.description=re(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function hm(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 ym(s){let e=_n(s.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:Mn(s)}}function wm(s){let e=typeof s.text=="string"?Pe(s.text):_n(s.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:Mn(s)}}function vm(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=_n(s.content);return t===null?null:{kind:"user-text",text:t}}function km(s){let e=Fm(s.prompt);return e===null?null:{kind:"user-text",text:e}}function ac(s){return s?s.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function sc(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 js(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(r.type!=="diff")continue;let o=sc(r.oldText),i=sc(r.newText);if(o===void 0&&i===void 0)continue;let a=typeof r.path=="string"?r.path:void 0;return{...a!==void 0?{path:a}:{},oldText:o?.text??"",newText:i?.text??"",...o?.ref?{oldRef:o.ref}:{},...i?.ref?{newRef:i.ref}:{}}}let t=s.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t,r=typeof n.file_path=="string"?n.file_path:typeof n.path=="string"?n.path:void 0;if(typeof n.old_string=="string"&&typeof n.new_string=="string")return{...r!==void 0?{path:r}:{},oldText:n.old_string,newText:n.new_string};if(typeof n.content=="string")return{...r!==void 0?{path:r}:{},oldText:"",newText:n.content}}return null}function dc(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:Pe(t)}function bm(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(ac(r)){let f=dc(s);if(f!==null){let g=se(s,"status"),w={kind:"exit-plan-mode",toolCallId:t,plan:f};return g!==void 0&&(w.status=g),w}}let o=lc(re(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=js(s);c!==null&&(d.editDiff=c);let u=uc(s);u!==void 0&&(d.detail=u);let l=_o(s);l!==void 0&&(d.detailFull=l);let p=cc(s);p!==void 0&&(d.locations=p);let m=Mn(s);m!==void 0&&(d.workerTaskId=m);let h=Mo(s);return h!==void 0&&(d.parentToolUseId=h),d}function cc(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 rc=64;function uc(s){let e=_o(s);if(e===void 0)return;let t=re(e),n=s.rawInput;return n&&typeof n.command=="string"?Am(t,rc):Cm(t,rc)}function _o(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 Pe(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 F(re(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 F(re(n))}}}var Sm=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function Im(s){for(let e of Sm)if(s.startsWith(e))return!0;return!1}function lc(s,e,t={}){if(s.length===0)return s;if(s.startsWith("/"))return F(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 F(i)}return Im(s)?F(`/${s}`):t.cwd&&t.cwd.length>0?F(dm.resolve(t.cwd,s)):s}function Am(s,e){return s.length>e?`${s.slice(0,e-1)}\u2026`:s}function Cm(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 Rm(s,e={}){let t=se(s,"toolCallId")??se(s,"id");if(!t)return null;let n=se(s,"title"),r=n!==void 0?lc(re(n),s,e):void 0,o=se(s,"status"),i=js(s),a=uc(s),d=xm(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(ac(u)){let g={kind:"exit-plan-mode",toolCallId:t},w=dc(s);return w!==null&&(g.plan=w),o!==void 0&&(g.status=o),g}let l={kind:"tool-call-update",toolCallId:t};r!==void 0&&(l.title=r),a!==void 0&&(l.detail=a);let p=_o(s);p!==void 0&&(l.detailFull=p);let m=cc(s);if(m!==void 0&&(l.locations=m),d!==void 0&&(l.resultSummary=d),o!==void 0&&(l.status=o),i!==null&&(l.editDiff=i),o==="failed"){let g=Em(s);g!==null&&(l.errorText=g),Tm(s,g)&&(l.upstreamInterrupted=!0)}let h=Mn(s);h!==void 0&&(l.workerTaskId=h);let f=Mo(s);return f!==void 0&&(l.parentToolUseId=f),l}function xm(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 Em(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=_n(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 Pe(n)}return null}function Tm(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 Pm(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"?re(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 Mm(s){let e=se(s,"currentModeId")??se(s,"currentMode")??se(s,"mode");return e?{kind:"mode-changed",mode:re(e)}:null}function _m(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:re(e),...n&&n.length>0?{availableModels:n}:{}}}function $m(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 oc(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 _n(s){if(typeof s=="string")return Pe(s);if(!s||typeof s!="object")return null;let e=s;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?Pe(e.text):null}function Fm(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){let n=_n(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 fc(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=Nm(i);if(c.length===0)continue;let u=c;if(d!==void 0){let l=e.get(d)??[],p=[];for(let m of c)l.some(h=>h.path===m.path&&h.oldText===m.oldText&&h.newText===m.newText)||p.push(m);if(p.length===0)continue;e.set(d,[...l,...p]),u=p}for(let l of u)Om(t,l)}let n=[];for(let[r,o]of t)n.push({path:r,hunks:o.hunks,created:o.created});return n}function pc(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 Om(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 Nm(s){let e=[],t=s.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let o=t,i=typeof o.file_path=="string"?o.file_path:typeof o.path=="string"?o.path:void 0,a=o.edits;if(i!==void 0&&Array.isArray(a)){for(let d of a){if(!d||typeof d!="object")continue;let c=d,u=typeof c.old_string=="string"?c.old_string:void 0,l=typeof c.new_string=="string"?c.new_string:void 0;u===void 0||l===void 0||e.push({path:i,oldText:u,newText:l})}if(e.length>0)return e}}let n=s.content;if(Array.isArray(n)){for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(i.type!=="diff")continue;let a=typeof i.path=="string"?i.path:void 0;if(a===void 0)continue;let d=typeof i.oldText=="string"?i.oldText:"",c=typeof i.newText=="string"?i.newText:"";e.push({path:a,oldText:d,newText:c})}if(e.length>0)return e}let r=js(s);return r&&r.path&&e.push({path:r.path,oldText:r.oldText,newText:r.newText}),e}function mc(s,e={}){let t=jm(s),{events:n,window:r}=Dm(t,e),o=Lm(n),i=[];Hm(i,s),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),Um(i,n,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
184
+ `))}async function jd(s,e){let t=je();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=Ps.join(x.agentsDir(),t),a;try{a=await Tn.readdir(i,{withFileTypes:!0})}catch(d){let c=d;if(c.code==="ENOENT")return;En(`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=Ps.join(i,c),m;try{m=await Tn.readdir(p,{withFileTypes:!0})}catch(h){En(`hydra-acp: prune: failed to read ${p}: ${h.message}`);continue}for(let h of m){if(!h.isDirectory())continue;let f=h.name;if(f===u||l.has(f)||f.includes(".partial-"))continue;let g=Ps.join(p,f);try{await Tn.rm(g,{recursive:!0,force:!0}),En(`hydra-acp: pruned stale ${c} ${f} (${g})`)}catch(w){En(`hydra-acp: prune: failed to remove ${g}: ${w.message}`)}}}}function Hd(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 xr(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 To(s){let e=s.maxDeletions??200,t=(m,h)=>{s.logger&&s.logger[m](`session-gc: ${h}`)},n=Date.now(),r=s.maxAgeMs>0?n-s.maxAgeMs:Number.POSITIVE_INFINITY,o=await s.manager.list({includeNonInteractive:!0}).catch(m=>(t("warn",`manager.list failed: ${m.message}`),[])),i=[];for(let m of o){if(m.status!=="cold")continue;if((s.selection??"explicit")==="explicit"){if(m.interactive!==!1)continue}else if(m.interactive===!0)continue;let f=Date.parse(m.updatedAt);Number.isFinite(f)&&(s.maxAgeMs>0&&f>r||i.push({sessionId:m.sessionId,lastUsedMs:f}))}if(i.length===0)return s.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((m,h)=>m.lastUsedMs-h.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,c=0,u=0;for(let{sessionId:m}of a)try{await s.manager.deleteRecord(m,"expired")&&(c+=1)}catch(h){u+=1,t("warn",`delete ${m} failed: ${h.message}`)}let l=i.length-a.length;if(s.verbose||c>0||u>0){let m=(s.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${c} ${m} session(s) older than ${Jg(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 Ld(s){let e,t=!1,n=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!n){n=!0;try{await To({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 Jg(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 Vg}from"crypto";function Pn(s){if(Array.isArray(s))return s.map(Pn);if(s!==null&&typeof s=="object"){let e={};for(let t of Object.keys(s).sort())e[t]=Pn(s[t]);return e}return s}function Ud(s){let e={};for(let[n,r]of Object.entries(s)){let o=or(n);if(o.nested){let i={};for(let[a,d]of Object.entries(r??{}))ir(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(Pn(e));return Vg("sha256").update(t).digest("hex").slice(0,16)}function Bd(s,e){let t=[],n=(r,o)=>JSON.stringify(Pn(r))!==JSON.stringify(Pn(o));for(let r of Object.keys(e)){let o=or(r),i=e[r],a=s[r];if(o.nested){for(let d of Object.keys(i??{})){if(ir(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 qd from"fs/promises";G();var Gg=3e3;async function Wd(){try{return(await qd.stat(x.config())).mtimeMs}catch{return}}function zd(s){let e=s.intervalMs??Gg,t=!1,n,r,o=Wd().then(d=>{r=d}),i=async()=>{await o;let d=await Wd();if(d===r)return;r=d;let c;try{c=await nn()}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=Bd(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)}}G();Ne();import*as Gd from"path";import{createHash as Kg,randomBytes as Qg,timingSafeEqual as Yg}from"crypto";var Kd="hydra_session_",Xg=3600*24*30,Jd=12,Zg=32,em=50;function tm(){return Gd.join(x.home(),"session-tokens.json")}function Vd(s){return Kg("sha256").update(s).digest("hex")}function Qd(s){return Qg(s).toString("hex")}function nm(){return Qd(Jd).slice(0,Jd*2)}function sm(){return`${Kd}${Qd(Zg)}`}var Ms=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=tm(),n=await ie(t);n&&Array.isArray(n.records)&&(e=n.records.filter(rm));let r=new s(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=sm(),n=Vd(t),r=nm(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:Xg,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(Kd))return;let t=Vd(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||!Yg(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(()=>{})},em))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>le(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 rm(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 Yd="Bearer ",_s=class{constructor(e){this.token=e}token;async validate(e){return im(e,this.token)?"service":void 0}rotate(e){this.token=e}},$s=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},Fs=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 Xd(s){return async function(t,n){let r=t.headers.authorization;if(!r||!r.startsWith(Yd)){n.code(401).send({error:"Missing bearer token"});return}let o=r.slice(Yd.length).trim(),i=await s.validator.validate(o);if(!i){n.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function Zd(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 Os=class{tokens=new Map;mint(e,t){let n=sr();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}`}},om=new Set(["GET /v1/sessions","GET /v1/sessions/:id","GET /v1/config"]);function ec(s,e){return e?om.has(`${s} ${e}`):!1}function im(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 Ns=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 No from"fs";import*as Tc from"os";import*as Ws from"path";import*as Do from"readline";G();function Po(s){return Math.floor(s/4)}function tc(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+=bt(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=am(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 am(s){let e=0;return typeof s.title=="string"&&(e+=s.title.length),e+=Ds(s.rawInput),e+=bt(s.content),e+=Ds(s.rawOutput),e}function Ds(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+=Ds(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+=Ds(n);return t}return 0}function bt(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+=bt(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?bt(e.text):e.type==="diff"?bt(e.oldText)+bt(e.newText):e.content!==void 0?bt(e.content):0}function nc(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=Po(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}G();import{posix as dm}from"path";import cm from"strip-ansi";function Mn(s){if(!s||typeof s!="object")return;let e=s;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}function Mo(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 um=/[\x00-\x08\x0b-\x1f\x7f]/g;function Pe(s){return cm(s).replace(um,"")}function re(s){return Pe(s).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function ic(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 ym(t);case"agent_thought_chunk":case"agent_thought":return wm(t);case"user_message_chunk":return vm(t);case"prompt_received":return km(t);case"tool_call":return bm(t,e);case"tool_call_update":return Rm(t,e);case"plan":return Pm(t);case"current_mode_update":return Mm(t);case"_hydra_current_model_update":return _m(t);case"turn_complete":return $m(t);case"_hydra_turn_started":return oc(t,"turn-started");case"_hydra_turn_ended":return oc(t,"turn-ended");case"usage_update":return hm(t);case"available_commands_update":return gm(t);case"_hydra_available_modes_update":return mm(t);case"session_info_update":return fm(t);case"config_option_update":return lm(t);default:return{kind:"unknown",sessionUpdate:n,raw:s}}}function lm(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 fm(s){let e=se(s,"title"),t=e!==void 0?re(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 pm(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:re(r)};typeof n.description=="string"&&(o.description=re(n.description)),e.push(o)}return e}function gm(s){let e=s.availableCommands??s.commands;return Array.isArray(e)?{kind:"available-commands",commands:pm(e)}:null}function mm(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:re(r.id)};typeof r.name=="string"&&(o.name=re(r.name)),typeof r.description=="string"&&(o.description=re(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function hm(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 ym(s){let e=_n(s.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:Mn(s)}}function wm(s){let e=typeof s.text=="string"?Pe(s.text):_n(s.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:Mn(s)}}function vm(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=_n(s.content);return t===null?null:{kind:"user-text",text:t}}function km(s){let e=Fm(s.prompt);return e===null?null:{kind:"user-text",text:e}}function ac(s){return s?s.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function sc(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 js(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(r.type!=="diff")continue;let o=sc(r.oldText),i=sc(r.newText);if(o===void 0&&i===void 0)continue;let a=typeof r.path=="string"?r.path:void 0;return{...a!==void 0?{path:a}:{},oldText:o?.text??"",newText:i?.text??"",...o?.ref?{oldRef:o.ref}:{},...i?.ref?{newRef:i.ref}:{}}}let t=s.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t,r=typeof n.file_path=="string"?n.file_path:typeof n.path=="string"?n.path:void 0;if(typeof n.old_string=="string"&&typeof n.new_string=="string")return{...r!==void 0?{path:r}:{},oldText:n.old_string,newText:n.new_string};if(typeof n.content=="string")return{...r!==void 0?{path:r}:{},oldText:"",newText:n.content}}return null}function dc(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:Pe(t)}function bm(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(ac(r)){let f=dc(s);if(f!==null){let g=se(s,"status"),w={kind:"exit-plan-mode",toolCallId:t,plan:f};return g!==void 0&&(w.status=g),w}}let o=lc(re(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=js(s);c!==null&&(d.editDiff=c);let u=uc(s);u!==void 0&&(d.detail=u);let l=_o(s);l!==void 0&&(d.detailFull=l);let p=cc(s);p!==void 0&&(d.locations=p);let m=Mn(s);m!==void 0&&(d.workerTaskId=m);let h=Mo(s);return h!==void 0&&(d.parentToolUseId=h),d}function cc(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 rc=64;function uc(s){let e=_o(s);if(e===void 0)return;let t=re(e),n=s.rawInput;return n&&typeof n.command=="string"?Am(t,rc):Cm(t,rc)}function _o(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 Pe(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 F(re(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 F(re(n))}}}var Sm=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function Im(s){for(let e of Sm)if(s.startsWith(e))return!0;return!1}function lc(s,e,t={}){if(s.length===0)return s;if(s.startsWith("/"))return F(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 F(i)}return Im(s)?F(`/${s}`):t.cwd&&t.cwd.length>0?F(dm.resolve(t.cwd,s)):s}function Am(s,e){return s.length>e?`${s.slice(0,e-1)}\u2026`:s}function Cm(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 Rm(s,e={}){let t=se(s,"toolCallId")??se(s,"id");if(!t)return null;let n=se(s,"title"),r=n!==void 0?lc(re(n),s,e):void 0,o=se(s,"status"),i=js(s),a=uc(s),d=xm(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(ac(u)){let g={kind:"exit-plan-mode",toolCallId:t},w=dc(s);return w!==null&&(g.plan=w),o!==void 0&&(g.status=o),g}let l={kind:"tool-call-update",toolCallId:t};r!==void 0&&(l.title=r),a!==void 0&&(l.detail=a);let p=_o(s);p!==void 0&&(l.detailFull=p);let m=cc(s);if(m!==void 0&&(l.locations=m),d!==void 0&&(l.resultSummary=d),o!==void 0&&(l.status=o),i!==null&&(l.editDiff=i),o==="failed"){let g=Em(s);g!==null&&(l.errorText=g),Tm(s,g)&&(l.upstreamInterrupted=!0)}let h=Mn(s);h!==void 0&&(l.workerTaskId=h);let f=Mo(s);return f!==void 0&&(l.parentToolUseId=f),l}function xm(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 Em(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=_n(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 Pe(n)}return null}function Tm(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 Pm(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"?re(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 Mm(s){let e=se(s,"currentModeId")??se(s,"currentMode")??se(s,"mode");return e?{kind:"mode-changed",mode:re(e)}:null}function _m(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:re(e),...n&&n.length>0?{availableModels:n}:{}}}function $m(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 oc(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 _n(s){if(typeof s=="string")return Pe(s);if(!s||typeof s!="object")return null;let e=s;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?Pe(e.text):null}function Fm(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){let n=_n(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 fc(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=Nm(i);if(c.length===0)continue;let u=c;if(d!==void 0){let l=e.get(d)??[],p=[];for(let m of c)l.some(h=>h.path===m.path&&h.oldText===m.oldText&&h.newText===m.newText)||p.push(m);if(p.length===0)continue;e.set(d,[...l,...p]),u=p}for(let l of u)Om(t,l)}let n=[];for(let[r,o]of t)n.push({path:r,hunks:o.hunks,created:o.created});return n}function pc(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 Om(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 Nm(s){let e=[],t=s.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let o=t,i=typeof o.file_path=="string"?o.file_path:typeof o.path=="string"?o.path:void 0,a=o.edits;if(i!==void 0&&Array.isArray(a)){for(let d of a){if(!d||typeof d!="object")continue;let c=d,u=typeof c.old_string=="string"?c.old_string:void 0,l=typeof c.new_string=="string"?c.new_string:void 0;u===void 0||l===void 0||e.push({path:i,oldText:u,newText:l})}if(e.length>0)return e}}let n=s.content;if(Array.isArray(n)){for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(i.type!=="diff")continue;let a=typeof i.path=="string"?i.path:void 0;if(a===void 0)continue;let d=typeof i.oldText=="string"?i.oldText:"",c=typeof i.newText=="string"?i.newText:"";e.push({path:a,oldText:d,newText:c})}if(e.length>0)return e}let r=js(s);return r&&r.path&&e.push({path:r.path,oldText:r.oldText,newText:r.newText}),e}function mc(s,e={}){let t=jm(s),{events:n,window:r}=Dm(t,e),o=Hm(n),i=[];Lm(i,s),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),Um(i,n,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
185
185
  `);return a.endsWith(`
186
186
  `)||(a+=`
187
- `),a}function $o(s,e){let t=s<0?e+s+1:s;return t<1?1:t>e?e:t}function Dm(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:m}of s)m.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=$o(o-e.last+1,o):(e.from!==void 0&&(i=$o(e.from,o)),e.to!==void 0&&(a=$o(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((m,h)=>{m.recordedAt>=d&&c.add(n[h])});let u=[],l,p;return s.forEach((m,h)=>{let f=n[h];f<i||f>a||d!==void 0&&!c.has(f)||(u.push(m),l??=f,p=f)}),{events:u,window:{from:l??i,to:p??a,total:o}}}function jm(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=ic(n.update,{cwd:s.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function Lm(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 Hm(s,e){let t=e.session,n=Qe(t.sessionId),r=t.title?.trim()||`Hydra session ${n}`;s.push(`# ${$n(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?`${Fo(a.size)}`:void 0;d.push(u?`${Fo(a.used)} / ${u} tokens`:`${Fo(a.used)} tokens`)}let c=yo(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(`
187
+ `),a}function $o(s,e){let t=s<0?e+s+1:s;return t<1?1:t>e?e:t}function Dm(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:m}of s)m.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=$o(o-e.last+1,o):(e.from!==void 0&&(i=$o(e.from,o)),e.to!==void 0&&(a=$o(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((m,h)=>{m.recordedAt>=d&&c.add(n[h])});let u=[],l,p;return s.forEach((m,h)=>{let f=n[h];f<i||f>a||d!==void 0&&!c.has(f)||(u.push(m),l??=f,p=f)}),{events:u,window:{from:l??i,to:p??a,total:o}}}function jm(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=ic(n.update,{cwd:s.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function Hm(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 Lm(s,e){let t=e.session,n=Qe(t.sessionId),r=t.title?.trim()||`Hydra session ${n}`;s.push(`# ${$n(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?`${Fo(a.size)}`:void 0;d.push(u?`${Fo(a.used)} / ${u} tokens`:`${Fo(a.used)} tokens`)}let c=yo(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(`
188
188
  `)),s.push("")}function Um(s,e,t,n){let{includeTools:r,includeThoughts:o}=n;if(!e.some(f=>Bm(f.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 f of c)s.push(f);s.push(""),c=[]}},m=()=>{p(),d.length>0&&(gc(s,d.trimEnd(),"*"),s.push(""),d=""),a.length!==0&&(s.push(a.trimEnd()),s.push(""),a="")},h=()=>{l||(l=!0)};for(let{event:f}of e)switch(f.kind){case"user-text":{m(),s.push("---"),s.push(""),i+=1,gc(s,f.text,"**"),s.push(""),l=!0;break}case"agent-text":h(),a+=f.text;break;case"agent-thought":{if(!o)break;h(),a.length>0&&(s.push(a.trimEnd()),s.push(""),a=""),d+=f.text;break}case"tool-call":{if(!r||(h(),(a.length>0||d.length>0)&&m(),u.has(f.toolCallId)))break;u.add(f.toolCallId);let g=t.get(f.toolCallId)??{title:f.title,status:f.status??"pending"};c.push(`- ${qm(g.status)} ${Wm(g)}`);break}case"tool-call-update":break;case"plan":{h(),m(),s.push("**Plan:**"),s.push("");for(let g of f.entries){let w=g.status==="completed"?"[x]":"[ ]";s.push(`- ${w} ${$n(g.content)}`)}s.push("");break}case"mode-changed":h(),m(),s.push(`_mode: ${$n(f.mode)}_`),s.push("");break;case"model-changed":h(),m(),s.push(`_model: ${$n(f.model)}_`),s.push("");break;case"turn-complete":m();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}m()}function Bm(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 Wm(s){let e=s.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${$n(s.title)}${t}`}function qm(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 hc=String.raw`<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s[^<>]*)?\/?>`,zm=new RegExp(hc);function gc(s,e,t){if(zm.test(e)){Jm(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(`
189
189
  `);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 Jm(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(`
190
- `))s.push(o);s.push(r)}function $n(s){return s.replace(new RegExp(hc,"g"),e=>e.replace(/</g,"&lt;").replace(/>/g,"&gt;"))}function Fo(s){return s.toLocaleString("en-US")}function Me(s){return s==="127.0.0.1"||s==="::1"||s==="localhost"||s==="[::1]"}function Vm(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=>Gm(u)).filter(u=>u.term.length>0);return{operator:o,terms:c}}function Gm(s){let e=/^(\w+):"([^"]*)"$/.exec(s);if(e)return{scope:yc(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:yc(n[1]),term:n[2].trim()}:{scope:"all",term:s.trim()}}function yc(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 Km(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 Qm=5,Ym=200,Hs=72,Xm=24,Zm=512;function Sc(s){return Number.isFinite(s)?Math.max(Xm,Math.min(Zm,Math.floor(s))):Hs}async function Ic(s,e,t={}){let n=Vm(e);if(n.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??Qm,o=t.maxSessions??Ym,i=Sc(t.snippetWidth??Hs),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 m=await s.loadHistory(p.sessionId,{tools:"references"}).catch(()=>[]),h=th(m,n,r,i,eh(p));if(h.snippets.length===0)continue;let f={sessionId:p.sessionId,cwd:p.cwd,status:p.status,updatedAt:p.updatedAt,totalMatches:h.totalMatches,snippets:h.snippets};p.title!==void 0&&(f.title=p.title),u.push(f)}return{query:e,truncated:l,results:u}}function eh(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 th(s,e,t,n=Hs,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=nh(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 nh(s,e,t,n,r,o){let i=e.toLowerCase(),a=0,d=[],c=new Set;for(let u of s){let l=sh(u).filter(p=>Km(t,p.kind));for(let p of l){let m=p.text.toLowerCase();if(p.kind==="edit"){let g=o?.(p.text);if(!(wc(p.text,e)||(g!==void 0&&g!==p.text?wc(g,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=m.indexOf(i);if(h===-1)continue;let f=0;for(;h!==-1;)f++,h=m.indexOf(i,h+i.length);if(a+=f,d.length<n){let g=m.indexOf(i),w={kind:p.kind,text:uh(p.text,g,i.length,r),recordedAt:u.recordedAt};p.toolName!==void 0&&(w.toolName=p.toolName),d.push(w)}}}return{totalMatches:a,snippets:d}}function sh(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=Ls(n.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof n.text=="string"?Pe(n.text):Ls(n.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if(dh(n))return[];let o=Ls(n.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=ch(n.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return rh(n);default:return[]}}function rh(s){let e=kc(s,"name"),t=kc(s,"title"),n=[];if(t!==void 0){let a=re(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=re(e);a.length>0&&n.push({kind:"tool",toolName:e,text:a})}let r=s.rawInput;if(r&&typeof r=="object"){let a=bc(r);if(a.length>0){let d={kind:"tool-input",text:re(a)};e!==void 0&&(d.toolName=e),n.push(d)}}for(let a of oh(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=bc(o);if(a.length>0){let d={kind:"tool-input",text:re(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let i=ih(s);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),n.push(a)}return n}function oh(s){let e=[],t=new Set,n=i=>{typeof i!="string"||i.length===0||t.has(i)||(t.add(i),e.push(i))},r=s.content;if(Array.isArray(r))for(let i of r){if(!i||typeof i!="object")continue;let a=i;a.type==="diff"&&n(a.path)}let o=s.rawInput;if(o&&typeof o=="object"&&!Array.isArray(o)){let i=o;(i.old_string!==void 0||i.new_string!==void 0||i.content!==void 0||Array.isArray(i.edits))&&n(typeof i.file_path=="string"?i.file_path:i.path)}return e}function wc(s,e){let t=vc(s.toLowerCase()),n=vc(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 vc(s){return s.length>1&&s.endsWith("/")?s.slice(0,-1):s}function ih(s){if(!ah(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=re(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=re(n);if(r.length>0)return r}}return null}function ah(s){return s==="failed"||s==="rejected"||s==="cancelled"}function dh(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 Ls(s){if(typeof s=="string")return Pe(s);if(!s||typeof s!="object"||Array.isArray(s))return"";let e=s;return typeof e.text=="string"?Pe(e.text):""}function ch(s){if(!Array.isArray(s))return"";let e=[];for(let t of s){let n=Ls(t);n.length>0&&e.push(n)}return e.join("")}function kc(s,e){let t=s[e];return typeof t=="string"?t:void 0}function bc(s){try{return JSON.stringify(s)}catch{return""}}function uh(s,e,t,n=Hs){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=Sc(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)),m=Math.max(0,a-(c-p)),h=Math.min(r.length,a+i.length+p),f=m>0?"\u2026":"",g=h<r.length?"\u2026":"";return`${f}${r.slice(m,h)}${g}`}import{randomBytes as Cc}from"crypto";function Ac(s){let e=Cc(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 Oo(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(Ac({name:"hydra-acp-stdin",session:n,tokenRegistry:e,getOrigin:t})),r.push(Ac({name:"hydra-acp-recall",session:n,tokenRegistry:e,getOrigin:t}));let o=Vt(s.deps);return o!==void 0&&(o.bindToSession(n),r=[...r,...o.descriptors]),r}}function Vt(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=Cc(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 lh=new Set(["/v1/sessions/:id/history","/v1/sessions/:id/events"]);function Rc(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=ht(a);if(!d){if(!e.localMiss||await e.localMiss.resolvesLocally(a))return;let w=e.localMiss.cache.findByLocalId(a);if(w.length===0)return;if(w.length>1){r.code(404).send({error:`Session "${a}" exists on more than one remote (${w.map(y=>y.name).join(", ")}). Address it as "<remote>:${a}".`});return}d=w[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(lh.has(o)&&ph(u?.follow)){let w=c.port===Ct?"":`:${c.port}`;r.code(501).send({error:`Streaming a federated session isn't supported yet. Attach directly with hydra://${c.host}${w}/${d.localId} instead.`});return}let l=gh(o,i,d.localId,n.url),m=`${Me(c.host)?"http":"https"}://${c.host}:${c.port}${l}`,h;try{h=await t(m,{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(w){r.code(502).send({error:`Could not reach remote "${d.name}" (${c.host}:${c.port}): ${w.message}`});return}if(h.status===204){r.code(204).send();return}let f=await h.text(),g=h.headers.get("content-type");g&&r.header("content-type",g),r.code(h.status).send(f)})}var fh=5e3,Us=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??fh),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=Me(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[m,h]of[...p])h.status!=="cold"&&p.delete(m);for(let m of l.removed??[])p.delete(it({name:n.name,localId:m}))}else p.clear();for(let m of l.sessions??[]){let h=it({name:n.name,localId:String(m.sessionId)});p.set(h,{...m,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))}findByLocalId(e){let t=e.startsWith(Ae)?[e]:[e,Ae+e],n=[];for(let[r,o]of this.perPeer)for(let i of t)if(o.sessions.has(it({name:r,localId:i}))){n.push({name:r,localId:i});break}return n}};async function xc(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=`${Me(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:it({name:e,localId:u.sessionId})}}:{status:a.status,body:c}}function ph(s){return s==="1"||s==="true"||s===!0}function gh(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 Bs=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function Ec(s){if(s.publicHost&&s.publicHost.length>0)return s.publicHost;if(s.host&&!Me(s.host))return s.port!==void 0?`${s.host}:${s.port}`:s.host}function Pc(s,e,t,n={},r,o){s.get("/v1/sessions",async(l,p)=>{let m=l.query,h=m?.includeNonInteractive==="1"||m?.includeNonInteractive==="true",f;if(m?.since!==void 0&&(f=Number(m.since),!Number.isFinite(f)||f<0))return p.code(400).send({error:`since must be a non-negative number, got ${JSON.stringify(m.since)}`});let g=m?.status==="warm"||m?.status==="cold"?m.status:void 0,w={cwd:m?.cwd,includeNonInteractive:h,...g?{status:g}:{}},y=o&&!w.cwd?o.list({includeNonInteractive:h,...g?{status:g}:{}}):[];if(f!==void 0){let b=await e.listSince(w,f);return{sessions:[...b.entries,...y],removed:b.removed,cursor:b.cursor}}let v=await e.listing(w);return{sessions:[...v.entries,...y],removed:[],cursor:v.cursor}}),s.get("/v1/sessions/:id",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=await e.getOne(h);return f||(p.code(404).send({error:"session not found"}),p)}),s.post("/v1/sessions/search",async(l,p)=>{let m=l.body??{},h=typeof m.q=="string"?m.q:"";if(h.trim().length===0)return p.code(400).send({error:"q is required"}),p;let g={sessionIds:Array.isArray(m.sessionIds)?m.sessionIds.filter(y=>typeof y=="string"&&y.length>0):void 0};return typeof m.snippetWidth=="number"&&(g.snippetWidth=m.snippetWidth),await Ic(e,h,g)}),s.post("/v1/sessions",async(l,p)=>{let m=l.body??{};if(m.remote){if(!r)return p.code(404).send({error:`No remote named "${m.remote}". Run \`hydra remote add\` first.`});let v=await xc(r,m.remote,{cwd:m.cwd,agentId:m.agentId,mcpServers:m.mcpServers,workspace:m.workspace});return p.code(v.status).send(v.body)}let h=fe(m.cwd??t.cwd),f=await tn(h),g=m.agentId??f.agentId??t.agentId,w=Vt(n),y=w!==void 0?[...m.mcpServers??[],...w.descriptors]:m.mcpServers;try{let v=await e.create({cwd:h,agentId:g,mcpServers:y,...m.workspace!==void 0?{workspace:m.workspace}:{}});w!==void 0&&w.bindToSession(v),p.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){w!==void 0&&w.abandon(v instanceof Error?v:void 0),p.code(500).send({error:v.message})}}),s.post("/v1/sessions/collect",async(l,p)=>{let m=l.body??{},h=typeof m.maxAgeDays=="number"&&m.maxAgeDays>0?m.maxAgeDays*24*60*60*1e3:0,f=typeof m.limit=="number"&&m.limit>0?m.limit:1e3,g=m.selection==="explicit"||m.selection==="unpromoted"?m.selection:"unpromoted";try{let w=await To({manager:e,maxAgeMs:h,maxDeletions:f,selection:g,verbose:!1});p.code(200).send(w)}catch(w){p.code(500).send({error:w.message})}}),s.post("/v1/sessions/:id/kill",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(f){f.close({deleteRecord:!1,by:"REST POST /kill"}).catch(()=>{}),p.code(202).send();return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}p.code(204).send()}),s.post("/v1/sessions/:id/stdin/open",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(!f)return p.code(404).send({error:"session not found"}),p;let g=l.body??{},w={};(g.mode==="memory"||g.mode==="file")&&(w.mode=g.mode),typeof g.capacityBytes=="number"&&(w.capacityBytes=g.capacityBytes),typeof g.fileCapBytes=="number"&&(w.fileCapBytes=g.fileCapBytes),(w.mode??"memory")==="file"&&(w.filePathFor=y=>Ws.join(Tc.tmpdir(),`hydra-acp-stdin-${y}.log`));try{return f.openStream(w)}catch(y){return p.code(409).send({error:y.message}),p}}),s.post("/v1/sessions/:id/stdin",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(!f)return p.code(404).send({error:"session not found"}),p;let g=l.body??{},w=typeof g.chunk=="string"?g.chunk:"",y=g.eof===!0;try{return f.streamWrite(w,y)}catch(v){return p.code(409).send({error:v.message}),p}}),s.patch("/v1/sessions/:id",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.body??{};if(f.cwd!==void 0){if(typeof f.cwd!="string"||!Ws.isAbsolute(f.cwd)){p.code(400).send({error:"cwd must be an absolute path"});return}let w=await e.setCwd(h,f.cwd);if(w==="missing"){p.code(404).send({error:"session not found"});return}if(w==="not-a-directory"){p.code(400).send({error:`${f.cwd} is not a directory`});return}if(w==="live"){p.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(w==="bound"){p.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}p.code(204).send();return}if("workspace"in f){if(f.workspace!==null){p.code(400).send({error:"workspace may only be set to null (clear the binding)"});return}let w=await e.clearWorkspaceBinding(h);if(w==="missing"){p.code(404).send({error:"session not found"});return}if(w==="live"){p.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}p.code(204).send();return}if(f.priority!==void 0){let w=f.priority,y;if(w===null||w===0)y=void 0;else if(typeof w=="number"&&Number.isInteger(w)&&w>0)y=w;else{p.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(h,y)){p.code(404).send({error:"session not found"});return}p.code(204).send();return}if(f.regen===!0){if(!(e.get(h)!==void 0||await e.hasRecord(h))){p.code(404).send({error:"session not found"});return}e.scheduleSynopsis(h),p.code(202).send();return}if(typeof f.title!="string"||f.title.trim().length===0){p.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(h,f.title)){p.code(404).send({error:"session not found"});return}p.code(204).send()}),s.delete("/v1/sessions/:id",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(f){await f.close({deleteRecord:!0,by:"REST DELETE /v1/sessions"}),await e.waitForDeletion(h),await e.hasRecord(h)&&await e.deleteRecord(h),p.code(204).send();return}if(!await e.deleteRecord(h)){p.code(404).send({error:"session not found"});return}p.code(204).send()}),s.get("/v1/sessions/:id/export",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.query?.tools,g=f==="references"?"references":wd(f),w=await e.exportBundle(h,g==="references"?{tools:"references"}:{});if(!w){p.code(404).send({error:"session not found"});return}let y=bn({record:w.record,history:g==="summary"?vd(w.history,"summary"):w.history,promptHistory:w.promptHistory.length>0?w.promptHistory:void 0,...w.toolBlobs!==void 0?{toolBlobs:w.toolBlobs}:{},hydraVersion:ge,machine:an(),hydraHost:Ec(t)}),v=new Date().toISOString().replace(/[:.]/g,"-");p.header("Content-Disposition",`attachment; filename="${h}-${v}.hydra"`),p.code(200).send(y)}),s.get("/v1/sessions/:id/diff",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=await e.exportBundle(h);if(!f){p.code(404).send({error:"session not found"});return}let g=l.query??{},w=g.fold==="true"||g.fold==="1",y=typeof g.paths=="string"&&g.paths.length>0?new Set(g.paths.split(",").map(b=>b.trim()).filter(b=>b.length>0)):void 0,v=fc(f.history);y&&(v=v.filter(b=>y.has(b.path))),w&&(v=v.map(b=>({...b,hunks:pc(b.hunks)}))),p.code(200).send(v)}),s.get("/v1/sessions/:id/tools/:hash",async(l,p)=>{let m=l.params,h=await e.resolveCanonicalId(m.id)??m.id,f=await e.loadToolBlob(h,m.hash);if(f===null){p.code(404).send({error:"tool blob not found"});return}p.header("Content-Type","text/plain; charset=utf-8"),p.code(200).send(f)}),s.get("/v1/sessions/:id/transcript",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=await e.exportBundle(h);if(!f){p.code(404).send({error:"session not found"});return}let g=bn({record:f.record,history:f.history,promptHistory:f.promptHistory.length>0?f.promptHistory:void 0,hydraVersion:ge,machine:an(),hydraHost:Ec(t)}),w=l.query,y=S=>S==="1"||S==="true"||S==="yes",v=S=>{let k=w?.[S];if(k===void 0||k==="")return;let C=Number(k);return Number.isFinite(C)?C:"bad"},b={};for(let S of["from","to","last","since"]){let k=v(S);if(k==="bad"){p.code(400).send({error:`${S} must be a number`});return}k!==void 0&&(b[S==="since"?"sinceMs":S]=k)}p.header("Content-Type","text/markdown; charset=utf-8"),p.code(200).send(mc(g,{includeTools:y(w?.tools),includeThoughts:y(w?.thoughts),...b}))}),s.post("/v1/sessions/:id/fork",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.body??{},g={};if(f.forkAt!==void 0){if(typeof f.forkAt!="string"||f.forkAt.length===0){p.code(400).send({error:"forkAt must be a non-empty string"});return}g.forkAt=f.forkAt}if(f.cwd!==void 0){if(typeof f.cwd!="string"||f.cwd.length===0){p.code(400).send({error:"cwd must be a non-empty string"});return}g.cwd=fe(f.cwd)}if(f.agentId!==void 0){if(typeof f.agentId!="string"||f.agentId.length===0){p.code(400).send({error:"agentId must be a non-empty string"});return}g.agentId=f.agentId}if(f.title!==void 0){if(typeof f.title!="string"){p.code(400).send({error:"title must be a string"});return}g.title=f.title}if(f.mode!==void 0){if(f.mode!=="verbatim"&&f.mode!=="synthesis"){p.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}g.mode=f.mode}if(f.model!==void 0){if(typeof f.model!="string"||f.model.length===0){p.code(400).send({error:"model must be a non-empty string"});return}g.model=f.model}try{let w=await e.forkSession(h,g);p.code(201).send(w)}catch(w){let y=w;if(y.code===E.SessionNotFound){p.code(404).send({error:y.message});return}if(y.code===E.InvalidParams||y.code===E.AgentNotInstalled){p.code(400).send({error:y.message});return}p.code(500).send({error:y.message})}}),s.post("/v1/sessions/import",async(l,p)=>{let m=l.body??{};if(m.bundle===void 0){p.code(400).send({error:"missing bundle"});return}let h;if(m.cwd!==void 0){if(typeof m.cwd!="string"||m.cwd.length===0){p.code(400).send({error:"cwd must be a non-empty string"});return}h=m.cwd}let f;try{f=xd(m.bundle)}catch(g){p.code(400).send({error:"invalid bundle",details:g.message});return}try{let g=await e.importBundle(f,{replace:m.replace===!0,...h!==void 0?{cwd:h}:{}});p.code(201).send(g)}catch(g){let w=g;if(w.code===E.BundleAlreadyImported){p.code(409).send({error:"bundle already imported",existingSessionId:w.existingSessionId});return}p.code(500).send({error:w.message})}}),s.get("/v1/sessions/:id/compact/status",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h),g;if(f?g=f.summarizedThroughEntry:g=await e.getSummarizedThroughEntry(h),g===void 0&&!await e.hasRecord(h))return p.code(404).send({error:"session not found"}),p;let w=await e.getCompactionState(h),y=await e.getRollbackBreadcrumb(h),v=await e.getPendingAgentSwap(h),b=!1,S,k=f?.currentUsage,C=typeof k?.used=="number"&&typeof k?.size=="number"&&k.size>0?{used:k.used,size:k.size}:void 0,A=await e.loadHistory(h,{tools:"references",maxEntries:1/0}).catch(()=>[]);if(A.length>0&&t.compaction){let R=g??0,T=A.length,M=R<=A.length?R:0,L=A.slice(M),J=tc(L);S=Po(J);let $=f?.currentModel,W=A.at(-1).recordedAt;b=nc({summarizedThroughEntry:R,totalEntries:T,unsummarizedChars:J,compactionInFlight:e.getCompactionInFlight(),currentModel:$,lastActivityMs:W,nowMs:Date.now(),config:t.compaction,...typeof k?.used=="number"?{agentReportedUsed:k.used}:{},...typeof k?.size=="number"?{agentReportedSize:k.size}:{}})}return{summarizedThroughEntry:g??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:b,...S!=null?{approxTokens:S}:{},...C!=null?{currentUsage:C}:{},...w!=null?{compactionState:w}:{},...y!=null?{rollbackBreadcrumb:y}:{},...v!=null?{pendingAgentSwap:v}:{}}}),s.post("/v1/sessions/:id/compact",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m;if(e.get(h)){e.scheduleCompaction(h),p.code(202).send({scheduled:!0});return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}e.scheduleCompaction(h),p.code(202).send({scheduled:!0})}),s.post("/v1/sessions/:id/compact/rollback",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m;if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}try{await e.performUncompact(h),p.code(202).send({rolledBack:!0})}catch(f){let g=f instanceof Error?f.message:String(f);p.code(409).send({error:g})}}),s.post("/v1/sessions/:id/workspace/clean",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.body??{};if(f.deep!==void 0&&typeof f.deep!="boolean"){p.code(400).send({error:"deep must be a boolean"});return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}if(e.get(h)===void 0){p.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(h,"clean",void 0,{deep:f.deep===!0});p.code(202).send({report:g})}catch(g){p.code(409).send({error:g instanceof Error?g.message:String(g)})}}),s.get("/v1/sessions/:id/history",async(l,p)=>{let m=l.params.id,h=l.query,f=h?.follow==="1"||h?.follow==="true",g=await e.resolveCanonicalId(m)??m,w=e.get(g),y,v,b=!1,S=1e4,k=[];if(w){f&&(v=w.onBroadcast(A=>{p.raw.writableEnded||(b?p.raw.write(JSON.stringify(A)+`
190
+ `))s.push(o);s.push(r)}function $n(s){return s.replace(new RegExp(hc,"g"),e=>e.replace(/</g,"&lt;").replace(/>/g,"&gt;"))}function Fo(s){return s.toLocaleString("en-US")}function Me(s){return s==="127.0.0.1"||s==="::1"||s==="localhost"||s==="[::1]"}function Vm(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=>Gm(u)).filter(u=>u.term.length>0);return{operator:o,terms:c}}function Gm(s){let e=/^(\w+):"([^"]*)"$/.exec(s);if(e)return{scope:yc(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:yc(n[1]),term:n[2].trim()}:{scope:"all",term:s.trim()}}function yc(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 Km(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 Qm=5,Ym=200,Ls=72,Xm=24,Zm=512;function Sc(s){return Number.isFinite(s)?Math.max(Xm,Math.min(Zm,Math.floor(s))):Ls}async function Ic(s,e,t={}){let n=Vm(e);if(n.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??Qm,o=t.maxSessions??Ym,i=Sc(t.snippetWidth??Ls),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 m=await s.loadHistory(p.sessionId,{tools:"references"}).catch(()=>[]),h=th(m,n,r,i,eh(p));if(h.snippets.length===0)continue;let f={sessionId:p.sessionId,cwd:p.cwd,status:p.status,updatedAt:p.updatedAt,totalMatches:h.totalMatches,snippets:h.snippets};p.title!==void 0&&(f.title=p.title),u.push(f)}return{query:e,truncated:l,results:u}}function eh(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 th(s,e,t,n=Ls,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=nh(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 nh(s,e,t,n,r,o){let i=e.toLowerCase(),a=0,d=[],c=new Set;for(let u of s){let l=sh(u).filter(p=>Km(t,p.kind));for(let p of l){let m=p.text.toLowerCase();if(p.kind==="edit"){let g=o?.(p.text);if(!(wc(p.text,e)||(g!==void 0&&g!==p.text?wc(g,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=m.indexOf(i);if(h===-1)continue;let f=0;for(;h!==-1;)f++,h=m.indexOf(i,h+i.length);if(a+=f,d.length<n){let g=m.indexOf(i),w={kind:p.kind,text:uh(p.text,g,i.length,r),recordedAt:u.recordedAt};p.toolName!==void 0&&(w.toolName=p.toolName),d.push(w)}}}return{totalMatches:a,snippets:d}}function sh(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=Hs(n.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof n.text=="string"?Pe(n.text):Hs(n.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if(dh(n))return[];let o=Hs(n.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=ch(n.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return rh(n);default:return[]}}function rh(s){let e=kc(s,"name"),t=kc(s,"title"),n=[];if(t!==void 0){let a=re(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=re(e);a.length>0&&n.push({kind:"tool",toolName:e,text:a})}let r=s.rawInput;if(r&&typeof r=="object"){let a=bc(r);if(a.length>0){let d={kind:"tool-input",text:re(a)};e!==void 0&&(d.toolName=e),n.push(d)}}for(let a of oh(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=bc(o);if(a.length>0){let d={kind:"tool-input",text:re(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let i=ih(s);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),n.push(a)}return n}function oh(s){let e=[],t=new Set,n=i=>{typeof i!="string"||i.length===0||t.has(i)||(t.add(i),e.push(i))},r=s.content;if(Array.isArray(r))for(let i of r){if(!i||typeof i!="object")continue;let a=i;a.type==="diff"&&n(a.path)}let o=s.rawInput;if(o&&typeof o=="object"&&!Array.isArray(o)){let i=o;(i.old_string!==void 0||i.new_string!==void 0||i.content!==void 0||Array.isArray(i.edits))&&n(typeof i.file_path=="string"?i.file_path:i.path)}return e}function wc(s,e){let t=vc(s.toLowerCase()),n=vc(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 vc(s){return s.length>1&&s.endsWith("/")?s.slice(0,-1):s}function ih(s){if(!ah(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=re(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=re(n);if(r.length>0)return r}}return null}function ah(s){return s==="failed"||s==="rejected"||s==="cancelled"}function dh(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 Hs(s){if(typeof s=="string")return Pe(s);if(!s||typeof s!="object"||Array.isArray(s))return"";let e=s;return typeof e.text=="string"?Pe(e.text):""}function ch(s){if(!Array.isArray(s))return"";let e=[];for(let t of s){let n=Hs(t);n.length>0&&e.push(n)}return e.join("")}function kc(s,e){let t=s[e];return typeof t=="string"?t:void 0}function bc(s){try{return JSON.stringify(s)}catch{return""}}function uh(s,e,t,n=Ls){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=Sc(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)),m=Math.max(0,a-(c-p)),h=Math.min(r.length,a+i.length+p),f=m>0?"\u2026":"",g=h<r.length?"\u2026":"";return`${f}${r.slice(m,h)}${g}`}import{randomBytes as Cc}from"crypto";function Ac(s){let e=Cc(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 Oo(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(Ac({name:"hydra-acp-stdin",session:n,tokenRegistry:e,getOrigin:t})),r.push(Ac({name:"hydra-acp-recall",session:n,tokenRegistry:e,getOrigin:t}));let o=Vt(s.deps);return o!==void 0&&(o.bindToSession(n),r=[...r,...o.descriptors]),r}}function Vt(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=Cc(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 lh=new Set(["/v1/sessions/:id/history","/v1/sessions/:id/events"]);function Rc(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=ht(a);if(!d){if(!e.localMiss||await e.localMiss.resolvesLocally(a))return;let w=e.localMiss.cache.findByLocalId(a);if(w.length===0)return;if(w.length>1){r.code(404).send({error:`Session "${a}" exists on more than one remote (${w.map(y=>y.name).join(", ")}). Address it as "<remote>:${a}".`});return}d=w[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(lh.has(o)&&ph(u?.follow)){let w=c.port===Ct?"":`:${c.port}`;r.code(501).send({error:`Streaming a federated session isn't supported yet. Attach directly with hydra://${c.host}${w}/${d.localId} instead.`});return}let l=gh(o,i,d.localId,n.url),m=`${Me(c.host)?"http":"https"}://${c.host}:${c.port}${l}`,h;try{h=await t(m,{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(w){r.code(502).send({error:`Could not reach remote "${d.name}" (${c.host}:${c.port}): ${w.message}`});return}if(h.status===204){r.code(204).send();return}let f=await h.text(),g=h.headers.get("content-type");g&&r.header("content-type",g),r.code(h.status).send(f)})}var fh=5e3,Us=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??fh),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=Me(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[m,h]of[...p])h.status!=="cold"&&p.delete(m);for(let m of l.removed??[])p.delete(it({name:n.name,localId:m}))}else p.clear();for(let m of l.sessions??[]){let h=it({name:n.name,localId:String(m.sessionId)});p.set(h,{...m,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))}findByLocalId(e){let t=e.startsWith(Ae)?[e]:[e,Ae+e],n=[];for(let[r,o]of this.perPeer)for(let i of t)if(o.sessions.has(it({name:r,localId:i}))){n.push({name:r,localId:i});break}return n}};async function xc(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=`${Me(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:it({name:e,localId:u.sessionId})}}:{status:a.status,body:c}}function ph(s){return s==="1"||s==="true"||s===!0}function gh(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 Bs=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function Ec(s){if(s.publicHost&&s.publicHost.length>0)return s.publicHost;if(s.host&&!Me(s.host))return s.port!==void 0?`${s.host}:${s.port}`:s.host}function Pc(s,e,t,n={},r,o){s.get("/v1/sessions",async(l,p)=>{let m=l.query,h=m?.includeNonInteractive==="1"||m?.includeNonInteractive==="true",f;if(m?.since!==void 0&&(f=Number(m.since),!Number.isFinite(f)||f<0))return p.code(400).send({error:`since must be a non-negative number, got ${JSON.stringify(m.since)}`});let g=m?.status==="warm"||m?.status==="cold"?m.status:void 0,w={cwd:m?.cwd,includeNonInteractive:h,...g?{status:g}:{}},y=o&&!w.cwd?o.list({includeNonInteractive:h,...g?{status:g}:{}}):[];if(f!==void 0){let b=await e.listSince(w,f);return{sessions:[...b.entries,...y],removed:b.removed,cursor:b.cursor}}let v=await e.listing(w);return{sessions:[...v.entries,...y],removed:[],cursor:v.cursor}}),s.get("/v1/sessions/:id",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=await e.getOne(h);return f||(p.code(404).send({error:"session not found"}),p)}),s.post("/v1/sessions/search",async(l,p)=>{let m=l.body??{},h=typeof m.q=="string"?m.q:"";if(h.trim().length===0)return p.code(400).send({error:"q is required"}),p;let g={sessionIds:Array.isArray(m.sessionIds)?m.sessionIds.filter(y=>typeof y=="string"&&y.length>0):void 0};return typeof m.snippetWidth=="number"&&(g.snippetWidth=m.snippetWidth),await Ic(e,h,g)}),s.post("/v1/sessions",async(l,p)=>{let m=l.body??{};if(m.remote){if(!r)return p.code(404).send({error:`No remote named "${m.remote}". Run \`hydra remote add\` first.`});let v=await xc(r,m.remote,{cwd:m.cwd,agentId:m.agentId,mcpServers:m.mcpServers,workspace:m.workspace});return p.code(v.status).send(v.body)}let h=fe(m.cwd??t.cwd),f=await tn(h),g=m.agentId??f.agentId??t.agentId,w=Vt(n),y=w!==void 0?[...m.mcpServers??[],...w.descriptors]:m.mcpServers;try{let v=await e.create({cwd:h,agentId:g,mcpServers:y,...m.workspace!==void 0?{workspace:m.workspace}:{}});w!==void 0&&w.bindToSession(v),p.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){w!==void 0&&w.abandon(v instanceof Error?v:void 0),p.code(500).send({error:v.message})}}),s.post("/v1/sessions/collect",async(l,p)=>{let m=l.body??{},h=typeof m.maxAgeDays=="number"&&m.maxAgeDays>0?m.maxAgeDays*24*60*60*1e3:0,f=typeof m.limit=="number"&&m.limit>0?m.limit:1e3,g=m.selection==="explicit"||m.selection==="unpromoted"?m.selection:"unpromoted";try{let w=await To({manager:e,maxAgeMs:h,maxDeletions:f,selection:g,verbose:!1});p.code(200).send(w)}catch(w){p.code(500).send({error:w.message})}}),s.post("/v1/sessions/:id/kill",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(f){f.close({deleteRecord:!1,by:"REST POST /kill"}).catch(()=>{}),p.code(202).send();return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}p.code(204).send()}),s.post("/v1/sessions/:id/stdin/open",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(!f)return p.code(404).send({error:"session not found"}),p;let g=l.body??{},w={};(g.mode==="memory"||g.mode==="file")&&(w.mode=g.mode),typeof g.capacityBytes=="number"&&(w.capacityBytes=g.capacityBytes),typeof g.fileCapBytes=="number"&&(w.fileCapBytes=g.fileCapBytes),(w.mode??"memory")==="file"&&(w.filePathFor=y=>Ws.join(Tc.tmpdir(),`hydra-acp-stdin-${y}.log`));try{return f.openStream(w)}catch(y){return p.code(409).send({error:y.message}),p}}),s.post("/v1/sessions/:id/stdin",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(!f)return p.code(404).send({error:"session not found"}),p;let g=l.body??{},w=typeof g.chunk=="string"?g.chunk:"",y=g.eof===!0;try{return f.streamWrite(w,y)}catch(v){return p.code(409).send({error:v.message}),p}}),s.patch("/v1/sessions/:id",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.body??{};if(f.cwd!==void 0){if(typeof f.cwd!="string"||!Ws.isAbsolute(f.cwd)){p.code(400).send({error:"cwd must be an absolute path"});return}let w=await e.setCwd(h,f.cwd);if(w==="missing"){p.code(404).send({error:"session not found"});return}if(w==="not-a-directory"){p.code(400).send({error:`${f.cwd} is not a directory`});return}if(w==="live"){p.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(w==="bound"){p.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}p.code(204).send();return}if("workspace"in f){if(f.workspace!==null){p.code(400).send({error:"workspace may only be set to null (clear the binding)"});return}let w=await e.clearWorkspaceBinding(h);if(w==="missing"){p.code(404).send({error:"session not found"});return}if(w==="live"){p.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}p.code(204).send();return}if(f.priority!==void 0){let w=f.priority,y;if(w===null||w===0)y=void 0;else if(typeof w=="number"&&Number.isInteger(w)&&w>0)y=w;else{p.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(h,y)){p.code(404).send({error:"session not found"});return}p.code(204).send();return}if(f.regen===!0){if(!(e.get(h)!==void 0||await e.hasRecord(h))){p.code(404).send({error:"session not found"});return}e.scheduleSynopsis(h),p.code(202).send();return}if(typeof f.title!="string"||f.title.trim().length===0){p.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(h,f.title)){p.code(404).send({error:"session not found"});return}p.code(204).send()}),s.delete("/v1/sessions/:id",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);if(f){await f.close({deleteRecord:!0,by:"REST DELETE /v1/sessions"}),await e.waitForDeletion(h),await e.hasRecord(h)&&await e.deleteRecord(h),p.code(204).send();return}if(!await e.deleteRecord(h)){p.code(404).send({error:"session not found"});return}p.code(204).send()}),s.get("/v1/sessions/:id/export",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.query?.tools,g=f==="references"?"references":wd(f),w=await e.exportBundle(h,g==="references"?{tools:"references"}:{});if(!w){p.code(404).send({error:"session not found"});return}let y=bn({record:w.record,history:g==="summary"?vd(w.history,"summary"):w.history,promptHistory:w.promptHistory.length>0?w.promptHistory:void 0,...w.toolBlobs!==void 0?{toolBlobs:w.toolBlobs}:{},hydraVersion:ge,machine:an(),hydraHost:Ec(t)}),v=new Date().toISOString().replace(/[:.]/g,"-");p.header("Content-Disposition",`attachment; filename="${h}-${v}.hydra"`),p.code(200).send(y)}),s.get("/v1/sessions/:id/diff",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=await e.exportBundle(h);if(!f){p.code(404).send({error:"session not found"});return}let g=l.query??{},w=g.fold==="true"||g.fold==="1",y=typeof g.paths=="string"&&g.paths.length>0?new Set(g.paths.split(",").map(b=>b.trim()).filter(b=>b.length>0)):void 0,v=fc(f.history);y&&(v=v.filter(b=>y.has(b.path))),w&&(v=v.map(b=>({...b,hunks:pc(b.hunks)}))),p.code(200).send(v)}),s.get("/v1/sessions/:id/tools/:hash",async(l,p)=>{let m=l.params,h=await e.resolveCanonicalId(m.id)??m.id,f=await e.loadToolBlob(h,m.hash);if(f===null){p.code(404).send({error:"tool blob not found"});return}p.header("Content-Type","text/plain; charset=utf-8"),p.code(200).send(f)}),s.get("/v1/sessions/:id/transcript",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=await e.exportBundle(h);if(!f){p.code(404).send({error:"session not found"});return}let g=bn({record:f.record,history:f.history,promptHistory:f.promptHistory.length>0?f.promptHistory:void 0,hydraVersion:ge,machine:an(),hydraHost:Ec(t)}),w=l.query,y=S=>S==="1"||S==="true"||S==="yes",v=S=>{let k=w?.[S];if(k===void 0||k==="")return;let C=Number(k);return Number.isFinite(C)?C:"bad"},b={};for(let S of["from","to","last","since"]){let k=v(S);if(k==="bad"){p.code(400).send({error:`${S} must be a number`});return}k!==void 0&&(b[S==="since"?"sinceMs":S]=k)}p.header("Content-Type","text/markdown; charset=utf-8"),p.code(200).send(mc(g,{includeTools:y(w?.tools),includeThoughts:y(w?.thoughts),...b}))}),s.post("/v1/sessions/:id/fork",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.body??{},g={};if(f.forkAt!==void 0){if(typeof f.forkAt!="string"||f.forkAt.length===0){p.code(400).send({error:"forkAt must be a non-empty string"});return}g.forkAt=f.forkAt}if(f.cwd!==void 0){if(typeof f.cwd!="string"||f.cwd.length===0){p.code(400).send({error:"cwd must be a non-empty string"});return}g.cwd=fe(f.cwd)}if(f.agentId!==void 0){if(typeof f.agentId!="string"||f.agentId.length===0){p.code(400).send({error:"agentId must be a non-empty string"});return}g.agentId=f.agentId}if(f.title!==void 0){if(typeof f.title!="string"){p.code(400).send({error:"title must be a string"});return}g.title=f.title}if(f.mode!==void 0){if(f.mode!=="verbatim"&&f.mode!=="synthesis"){p.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}g.mode=f.mode}if(f.model!==void 0){if(typeof f.model!="string"||f.model.length===0){p.code(400).send({error:"model must be a non-empty string"});return}g.model=f.model}try{let w=await e.forkSession(h,g);p.code(201).send(w)}catch(w){let y=w;if(y.code===E.SessionNotFound){p.code(404).send({error:y.message});return}if(y.code===E.InvalidParams||y.code===E.AgentNotInstalled){p.code(400).send({error:y.message});return}p.code(500).send({error:y.message})}}),s.post("/v1/sessions/import",async(l,p)=>{let m=l.body??{};if(m.bundle===void 0){p.code(400).send({error:"missing bundle"});return}let h;if(m.cwd!==void 0){if(typeof m.cwd!="string"||m.cwd.length===0){p.code(400).send({error:"cwd must be a non-empty string"});return}h=m.cwd}let f;try{f=xd(m.bundle)}catch(g){p.code(400).send({error:"invalid bundle",details:g.message});return}try{let g=await e.importBundle(f,{replace:m.replace===!0,...h!==void 0?{cwd:h}:{}});p.code(201).send(g)}catch(g){let w=g;if(w.code===E.BundleAlreadyImported){p.code(409).send({error:"bundle already imported",existingSessionId:w.existingSessionId});return}p.code(500).send({error:w.message})}}),s.get("/v1/sessions/:id/compact/status",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h),g;if(f?g=f.summarizedThroughEntry:g=await e.getSummarizedThroughEntry(h),g===void 0&&!await e.hasRecord(h))return p.code(404).send({error:"session not found"}),p;let w=await e.getCompactionState(h),y=await e.getRollbackBreadcrumb(h),v=await e.getPendingAgentSwap(h),b=!1,S,k=f?.currentUsage,C=typeof k?.used=="number"&&typeof k?.size=="number"&&k.size>0?{used:k.used,size:k.size}:void 0,A=await e.loadHistory(h,{tools:"references",maxEntries:1/0}).catch(()=>[]);if(A.length>0&&t.compaction){let R=g??0,T=A.length,M=R<=A.length?R:0,H=A.slice(M),J=tc(H);S=Po(J);let $=f?.currentModel,W=A.at(-1).recordedAt;b=nc({summarizedThroughEntry:R,totalEntries:T,unsummarizedChars:J,compactionInFlight:e.getCompactionInFlight(),currentModel:$,lastActivityMs:W,nowMs:Date.now(),config:t.compaction,...typeof k?.used=="number"?{agentReportedUsed:k.used}:{},...typeof k?.size=="number"?{agentReportedSize:k.size}:{}})}return{summarizedThroughEntry:g??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:b,...S!=null?{approxTokens:S}:{},...C!=null?{currentUsage:C}:{},...w!=null?{compactionState:w}:{},...y!=null?{rollbackBreadcrumb:y}:{},...v!=null?{pendingAgentSwap:v}:{}}}),s.post("/v1/sessions/:id/compact",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m;if(e.get(h)){e.scheduleCompaction(h),p.code(202).send({scheduled:!0});return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}e.scheduleCompaction(h),p.code(202).send({scheduled:!0})}),s.post("/v1/sessions/:id/compact/rollback",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m;if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}try{await e.performUncompact(h),p.code(202).send({rolledBack:!0})}catch(f){let g=f instanceof Error?f.message:String(f);p.code(409).send({error:g})}}),s.post("/v1/sessions/:id/workspace/clean",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=l.body??{};if(f.deep!==void 0&&typeof f.deep!="boolean"){p.code(400).send({error:"deep must be a boolean"});return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}if(e.get(h)===void 0){p.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(h,"clean",void 0,{deep:f.deep===!0});p.code(202).send({report:g})}catch(g){p.code(409).send({error:g instanceof Error?g.message:String(g)})}}),s.get("/v1/sessions/:id/history",async(l,p)=>{let m=l.params.id,h=l.query,f=h?.follow==="1"||h?.follow==="true",g=await e.resolveCanonicalId(m)??m,w=e.get(g),y,v,b=!1,S=1e4,k=[];if(w){f&&(v=w.onBroadcast(A=>{p.raw.writableEnded||(b?p.raw.write(JSON.stringify(A)+`
191
191
  `):(k.push(A),k.length>S&&k.shift()))})),l.raw.on("close",()=>{v?.(),p.raw.writableEnded||p.raw.end()});try{y=await w.getHistorySnapshot()}catch(A){throw v?.(),A}}else{let A=await e.getHistory(g);if(A===void 0)return p.code(404).send({error:"session not found"}),p;y=A}p.raw.setHeader("Content-Type","application/x-ndjson"),p.raw.setHeader("Cache-Control","no-cache"),p.raw.statusCode=200;let C=new Set;for(let A of y??[]){p.raw.write(JSON.stringify(A)+`
192
192
  `);let R=A;typeof R.recordedAt=="number"&&C.add(String(R.recordedAt))}for(;k.length>0;){let A=k.splice(0,k.length);for(let R of A){let T=R,M=typeof T.recordedAt=="number"?String(T.recordedAt):"";M&&C.has(M)||p.raw.write(JSON.stringify(R)+`
193
193
  `)}}return b=!0,v||p.raw.end(),p});function i(l,p,m){let h=typeof l=="string"?l.trim():"";if(h.length===0)return null;let f;try{f=JSON.parse(h)}catch{return console.debug("events endpoint: skipping malformed JSONL line"),null}if(!f||typeof f!="object"||Array.isArray(f))return console.debug("events endpoint: skipping non-object JSONL line"),null;let g=f;if(typeof g.recordedAt!="number"||m!==void 0&&g.recordedAt<m||typeof g.params!="object"||g.params===null||Array.isArray(g.params))return null;let w=g.params;if(typeof w.update!="object"||w.update===null||Array.isArray(w.update))return null;let v=w.update.sessionUpdate;return typeof v!="string"||!p.has(v)?null:{recordedAt:g.recordedAt,entry:f}}function a(l,p,m){let f=p.params.update,g={sessionId:l,ts:new Date(p.recordedAt).toISOString(),kind:m,update:f};return f.messageId!==void 0&&f.messageId!==null&&(g.messageId=f.messageId),g}async function*d(l,p,m,h){for await(let f of p){let g=i(f,m,h);if(g){let w=g.entry.params.update.sessionUpdate;yield{ts:g.recordedAt,row:a(l,g.entry,w)}}}}async function c(l,p,m,h){let f=Do.createInterface({input:No.createReadStream(p),crlfDelay:1/0}),g=d(l,f,m,h),w=await g.next(),y=w.done?null:w.value;return{sessionId:l,rl:f,gen:g,current:y,exhausted:y===null}}async function u(l){let p=await l.gen.next();p.done?(l.exhausted=!0,l.current=null):l.current=p.value}s.get("/v1/sessions/events",async(l,p)=>{let m=l.query,h=m.kinds;if(!h||h.trim().length===0)return p.code(400).send({error:"kinds parameter is required"}),p;let f=h.split(",").map(S=>S.trim());if(f.length===0)return p.code(400).send({error:"kinds parameter is required"}),p;for(let S of f)if(!Bs.has(S))return p.code(400).send({error:`kind "${S}" is not queryable; allowed kinds: ${[...Bs].join(", ")}`}),p;let g=new Set(f),w;if(m.since!==void 0&&m.since.trim().length>0){let S=new Date(m.since);if(isNaN(S.getTime()))return p.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),p;w=S.getTime()}let y=await e.list({includeNonInteractive:!0}),v=w!==void 0?y.filter(S=>new Date(S.updatedAt).getTime()>=w):y;p.raw.setHeader("content-type","application/x-ndjson"),p.raw.statusCode=200;let b=[];for(let S of v)try{let k=x.historyFile(S.sessionId),C=await c(S.sessionId,k,g,w);C.exhausted||b.push(C)}catch(k){if(k.code==="ENOENT")continue;throw k}l.raw.on("close",()=>{for(let S of b)try{S.rl.close()}catch{}p.raw.writableEnded||p.raw.end()});try{for(;b.length>0;){let S=-1,k=1/0;for(let A=0;A<b.length;A++){let R=b[A];R.current!==null&&R.current.ts<k&&(k=R.current.ts,S=A)}if(S===-1)break;let C=b[S];if(p.raw.write(JSON.stringify(C.current.row)+`
194
- `),await u(C),C.exhausted){try{C.rl.close()}catch{}b.splice(S,1)}}}catch(S){for(let k of b)try{k.rl.close()}catch{}throw S}return p.raw.end(),p}),s.get("/v1/sessions/:id/events",async(l,p)=>{let m=l.params.id,h=l.query,f=await e.resolveCanonicalId(m)??m;if(!e.get(f)&&!await e.hasRecord(f))return p.code(404).send({error:"session not found"}),p;let w=h.kinds;if(!w||w.trim().length===0)return p.code(400).send({error:"kinds parameter is required"}),p;let y=w.split(",").map(A=>A.trim());if(y.length===0)return p.code(400).send({error:"kinds parameter is required"}),p;for(let A of y)if(!Bs.has(A))return p.code(400).send({error:`kind "${A}" is not queryable; allowed kinds: ${[...Bs].join(", ")}`}),p;let v=new Set(y),b;if(h.since!==void 0&&h.since.trim().length>0){let A=new Date(h.since);if(isNaN(A.getTime()))return p.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),p;b=A.getTime()}let S=x.historyFile(f),k=No.createReadStream(S),C=Do.createInterface({input:k,crlfDelay:1/0});p.raw.setHeader("content-type","application/x-ndjson"),p.raw.statusCode=200;try{for await(let A of C){let R=typeof A=="string"?A.trim():"";if(R.length===0)continue;let T;try{T=JSON.parse(R)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",S);continue}if(!T||typeof T!="object"||Array.isArray(T)){console.debug("events endpoint: skipping non-object JSONL line in %s",S);continue}let M=T;if(typeof M.recordedAt!="number"||typeof M.params!="object"||M.params===null||Array.isArray(M.params))continue;let L=M.params;if(typeof L.update!="object"||L.update===null||Array.isArray(L.update))continue;let J=L.update,$=J.sessionUpdate;if(typeof $!="string"||!v.has($)||b!==void 0&&M.recordedAt<b)continue;let W={ts:new Date(M.recordedAt).toISOString(),kind:$,update:J};J.messageId!==void 0&&J.messageId!==null&&(W.messageId=J.messageId),p.raw.write(JSON.stringify(W)+`
195
- `)}}catch(A){if(A.code==="ENOENT")return p.raw.end(),p;throw A}return p.raw.end(),p}),s.post("/v1/sessions/:id/prompt/:messageId/notify",async(l,p)=>{let m=l.params,h=m.id,f=await e.resolveCanonicalId(h)??h,g=m.messageId,w=l.body,y=typeof w?.callbackUrl=="string"?w.callbackUrl:"",v=typeof w?.secret=="string"?w.secret:"";if(!g||!y||!v){p.code(400).send({error:"messageId, callbackUrl, and secret are all required"});return}let b;try{b=new URL(y)}catch{p.code(400).send({error:"callbackUrl must be a valid absolute URL"});return}if(b.protocol!=="https:"&&b.protocol!=="http:"){p.code(400).send({error:"callbackUrl must be http or https"});return}let S=e.get(f);if(!S){p.code(404).send({error:"session not found or not warm"});return}let k=S.registerTurnNotify(g,y,v);if(k.alreadyTerminal){p.code(200).send({status:"already_terminal",stopReason:k.stopReason});return}p.code(202).send({status:"registered"})}),s.get("/v1/sessions/:id/attention",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);return!f&&!await e.hasRecord(h)?(p.code(404).send({error:"session not found"}),p):f?{flags:f.listAttentionFlags()}:{flags:(await e.store.read(h))?.attentionFlags??[]}}),s.get("/v1/sessions/attention",async(l,p)=>{let m=l.query;if(!m.source||m.source.trim().length===0)return p.code(400).send({error:"source query parameter is required"}),p;let h=await e.list({includeNonInteractive:!0}),f=[];for(let g of h){let w=e.get(g.sessionId),y;w?y=w.listAttentionFlags():y=(await e.store.read(g.sessionId))?.attentionFlags??[];for(let v of y)v.source===m.source&&f.push({...v,sessionId:g.sessionId})}return{flags:f}}),s.post("/v1/sessions/:id/attention/clear",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,g=l.body??{},w=typeof g.source=="string"?g.source:"",y=typeof g.reason=="string"?g.reason:"";if((w.length>0||y.length>0)&&!(w.length>0&&y.length>0)){p.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}w.length===0&&y.length;let v=e.get(h);if(v){if(w.length>0&&y.length>0)v.clearAttentionFlag(w,y);else{let A=Array.from(v.listAttentionFlags()).map(R=>`${R.source}::${R.reason}`);for(let R of A)v.clearAttentionFlag(R.split("::")[0],R.split("::").slice(1).join("::"))}p.code(204).send();return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}let b=e.store,S=await b.read(h);if(!S){p.code(404).send({error:"session not found"});return}let k=S.attentionFlags??[],C;if(w.length>0&&y.length>0){let A=`${w}::${y}`;C=k.filter(R=>`${R.source}::${R.reason}`!==A)}else C=[];if(C.length===k.length&&C.every((A,R)=>A.source===k[R].source&&A.reason===k[R].reason)){p.code(204).send();return}await b.write({...S,attentionFlags:C}),p.code(204).send()})}function Mc(s,e,t,n={}){s.get("/v1/agents",async()=>Pt(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 Ee(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===E.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}G();function _c(s,e,t,n=()=>[]){s.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t,home:x.home(),driftedKeys:n()}))}var mh=/^[A-Za-z0-9._-]+$/;function qs(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=hh(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){Fn(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){Fn(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){Fn(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){Fn(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){Fn(i,d)}})}function Fn(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 hh(s){let e=s.name;if(typeof e!="string"||!mh.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 $c(s,e){qs(s,"extension",e)}function Fc(s,e){qs(s,"transformer",e)}function Oc(s,e){s.get("/v1/config",async()=>e())}import{z as ct}from"zod";G();import*as Gt from"fs/promises";import*as Nc from"path";import{randomBytes as JI,scrypt as yh,timingSafeEqual as wh}from"crypto";import{promisify as vh}from"util";var kh=vh(yh);function Dc(){return Nc.join(x.home(),"password-hash")}var bh=128*1024*1024;async function jc(){try{return(await Gt.readFile(Dc(),"utf8")).trim().length>0}catch(s){if(s.code==="ENOENT")return!1;throw s}}async function Lc(s){if(typeof s!="string"||s.length===0)return!1;let e;try{e=(await Gt.readFile(Dc(),"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 kh(s,i,a.length,{N:n,r,p:o,maxmem:bh});return d.length!==a.length?!1:wh(d,a)}var Sh=ct.object({password:ct.string().min(1),label:ct.string().min(1).max(256).optional(),ttlSec:ct.number().int().positive().optional()}),Ih=ct.object({id:ct.string().optional()}).optional(),Ah=ct.object({token:ct.string().min(32)});function Hc(s,e){s.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,n)=>{let r=Ch(t);if(e.rateLimiter.isBlocked(r))return n.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=Sh.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}if(!await jc())return n.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await Lc(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=Ih.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=Ah.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 Ch(s){return s.ip||"unknown"}import{z as ut}from"zod";G();Ne();var jo=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,zs=class s{data;constructor(e){this.data=e}static async load(){let e=await ie(x.peers());return new s(Rh(e))}get(e){return this.data.entries[e]}async set(e){this.data.entries[e.name]=e,await Uc(this.data)}async delete(e){return e in this.data.entries?(delete this.data.entries[e],await Uc(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 Rh(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 Uc(s){await le(x.peers(),s,{mode:384})}var xh=3600*24*365,Je=class extends Error{status;constructor(e,t){super(e),this.name="PeerLoginError",this.status=t}};function Bc(s,e){return`${Me(s)?"http":"https"}://${s}:${e}`}async function Wc(s){let e=s.fetchImpl??fetch,t=`${s.host}:${s.port}`,n=Bc(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??xh})})}catch(i){throw new Je(`Could not reach ${t}: ${i.message}`,502)}if(r.status===401)throw new Je(`Wrong password for ${t}.`,401);if(r.status===403)throw new Je(`No password is configured on ${t}. Run \`hydra-acp auth password\` on that daemon first.`,502);if(r.status===429)throw new Je(`Too many failed login attempts on ${t}; try again later.`,429);if(!r.ok)throw new Je(`Login to ${t} failed: HTTP ${r.status}`,502);let o=await r.json();if(!o.session_token||!o.expires_at)throw new Je(`Login to ${t} returned a malformed response.`,502);return{token:o.session_token,expiresAt:o.expires_at}}async function qc(s){let e=s.fetchImpl??fetch,t=Bc(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{}}Nn();var Lh=ut.object({name:ut.string().min(1).max(64).regex(jo),host:ut.string().min(1),port:ut.number().int().positive().optional(),password:ut.string().min(1),label:ut.string().min(1).max(256).optional(),ttlSec:ut.number().int().positive().optional(),pinnedFingerprint:ut.string().min(1).optional()});function Zc(s,e){s.post("/v1/remotes",async(t,n)=>{let r;try{r=Lh.parse(t.body)}catch{return n.code(400).send({error:`Invalid request body (name must match ${jo} and the rest is a normal login request)`})}let o=r.port??Ct;r.pinnedFingerprint&&On(r.host,o,r.pinnedFingerprint);let i;try{i=await Wc({host:r.host,port:o,password:r.password,label:r.label,ttlSec:r.ttlSec})}catch(c){if(c instanceof Je)return n.code(c.status).send({error:c.message});throw c}let a=new Date().toISOString(),d={name:r.name,host:r.host,port:o,token:i.token,expiresAt:i.expiresAt,addedAt:a,...r.label!==void 0?{label:r.label}:{},...r.pinnedFingerprint!==void 0?{pinnedFingerprint:r.pinnedFingerprint,pinnedAt:a}:{}};return await e.store.set(d),e.health?.markOk(d.name),n.code(201).send({name:d.name,host:d.host,port:d.port,expiresAt:d.expiresAt,label:d.label,addedAt:d.addedAt,pinnedFingerprint:d.pinnedFingerprint,status:e.health?.get(d.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}:{}}});return n.code(200).send({remotes:r})}),s.delete("/v1/remotes/:name",async(t,n)=>{let r=t.params.name,o=e.store.get(r);return o?(await qc({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)||Ho(o.host,o.port),n.code(204).send()):n.code(404).send({error:"Not found"})})}function Vs(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:E.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())}}}Nn();import{WebSocket as Hh}from"ws";var Uh=1e4,zo=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 eu(s,e,t=Uh){let n={};try{let r=new URL(s);if(r.protocol==="wss:"){let o=qo(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 Hh(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 zo(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 Bh=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 Wh(s){return Bh.has(s)}function nu(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&&Wh(a.method)){let d=a.params,c=typeof d?.sessionId=="string"?d.sessionId:void 0;if(c){if(ht(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(Dn(a.id,E.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 Gs=class{constructor(e,t=zh,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:it(t[0])}}async handleLocalMessage(e,t,n){let r="id"in e,o=r?e.id:void 0,i=ht(t);if(!i)return r?Dn(o,E.SessionNotFound,`not a federated session id: ${t}`):void 0;let a=tu(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?Dn(o,E.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(g){return r?Dn(o,E.InternalError,`Could not reach remote "${i.name}": ${g.message}`):void 0}let m;try{m=await p.request("session/attach",d)}catch(g){return p.close().catch(()=>{}),r?Jo(o,g):void 0}let h={peerConnection:p,localId:i.localId,target:n};this.wireAttachment(i.name,h),this.attachments.set(a,h);let f=m&&typeof m.sessionId=="string"?{...m,sessionId:t}:m;return r?{jsonrpc:"2.0",id:o,result:f}:void 0}let c=this.attachments.get(a);if(!c)return r?Dn(o,E.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?Jo(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 Jo(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=it({name:e,localId:r}),a=()=>{this.attachments.delete(tu(o.clientId,i))};n.onNotification("session/update",d=>{let c=d;!c||c.sessionId!==r||o.connection.notify("session/update",{...c,sessionId:i}).catch(()=>{})}),n.onNotification("hydra-acp/session/closed",d=>{let c=d;!c||c.sessionId!==r||(a(),o.connection.notify("hydra-acp/session/closed",{sessionId:i}).catch(()=>{}))}),n.onRequest("hydra-acp/session/request_permission",async d=>{let c=d;if(!c||c.sessionId!==r)throw{code:E.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 tu(s,e){return`${s} ${e}`}function Dn(s,e,t){return{jsonrpc:"2.0",id:s,error:{code:e,message:t}}}function Jo(s,e){let t=e,n=typeof t?.code=="number"?t.code:E.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 qh=1e4;async function zh(s){let t=`${Me(s.host)?"ws":"wss"}://${s.host}:${s.port}/acp`,n=await eu(t,["acp.v1",`hydra-acp-token.${s.token}`],qh);return new st(Vs(n))}var Jh=3e4,Vh=5e3,Ks=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??Jh),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}get(e){return this.snapshots.get(e)}markOk(e){this.snapshots.set(e,{status:"ok",checkedAt:new Date().toISOString()})}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 o=`${Me(n.host)?"http":"https"}://${n.host}:${n.port}/v1/auth/verify`,i=new AbortController,a=setTimeout(()=>i.abort(),Vh);try{let d=await e(o,{headers:{Authorization:`Bearer ${n.token}`},signal:i.signal});this.snapshots.set(t.name,{status:d.ok?"ok":"unauthorized",checkedAt:new Date().toISOString()})}catch(d){this.snapshots.set(t.name,{status:"unreachable",checkedAt:new Date().toISOString(),error:d.message})}finally{clearTimeout(a)}}))}};Nn();import{z as su}from"zod";var Gh=su.object({sessionLabel:su.string().min(1).max(256)});function ru(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=Gh.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 Vo}from"nanoid";import{randomBytes as cu}from"crypto";import*as uu from"os";import*as lu from"path";var Kh=200;function Qh(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[de];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,Kh)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function ou(s,e,t){let n=Qh(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 jn=new Map;function iu(s,e){let t=jn.get(s);t||(t=new Set,jn.set(s,t)),t.add(e);let n=!1;return()=>{if(n)return;n=!0;let r=jn.get(s);r&&(r.delete(e),r.size===0&&jn.delete(s))}}function au(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=jn.get(r);if(o){if(o.has(s))return!0;for(let i of o)n.push(i)}}return!1}function N(s,e,t){let n=new Error(e);return n.code=s,t!==void 0&&(n.data=t),n}function ty(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 Re(s,e,t){let n=s.get(e);if(!n)throw N(E.SessionNotFound,t??`session ${e} not found`);return n}async function It(s,e){let t=Vt(s),n,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&s.mcpTokenRegistry!==void 0&&s.getDaemonOrigin!==void 0&&(n=cu(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=Oo({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 ly(c,s),pu(c.sessionId,s),c}function fu(s,e){s.get("/acp",{websocket:!0},async(t,n)=>{let r=Zd({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_${Vo(12)}`,a=Vs(t),d={},c=e.foreignSessions?nu(a,e.foreignSessions,d,i):a,u=new st(c);d.connection=u;let l={clientId:i,processIdentity:o,attached:new Map};u.onClose(()=>{for(let h of l.attached.values())e.manager.get(h.sessionId)?.detach(h.clientId);l.attached.clear(),e.foreignSessions?.detachClient(i)});let p=(h,f)=>{if(l.attached.get(h)?.readonly)throw N(E.PermissionDenied,`${f} not permitted on a read-only attachment`)};if(u.onRequest("initialize",async h=>{let f=Bi.parse(h??{});f.clientInfo?.name&&(l.clientInfo={name:f.clientInfo.name,...f.clientInfo.version!==void 0?{version:f.clientInfo.version}:{}});let g=f.clientInfo?.version;return g&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,g):e.onTransformerVersion?.(o.name,g)),uy()}),o&&e.extensionCommands){let h=e.extensionCommands;u.onRequest("hydra-acp/commands/register",async f=>{let g=f??{},w=Array.isArray(g.commands)?g.commands.map(y=>{if(!y||typeof y!="object")return;let v=y;if(typeof v.verb!="string")return;let b={verb:v.verb};return typeof v.argsHint=="string"&&(b.argsHint=v.argsHint),typeof v.description=="string"&&(b.description=v.description),b}).filter(y=>y!==void 0):[];return h.register(o.name,u,w),{ok:!0,registered:w.length}}),u.onClose(()=>{h.clear(o.name)})}if(o&&e.extensionMcp){let h=e.extensionMcp;u.onRequest("hydra-acp/mcp_tools/register",async g=>{let w=g??{},y=typeof w.instructions=="string"?w.instructions:void 0,v=Array.isArray(w.tools)?w.tools.map(b=>{if(!b||typeof b!="object")return;let S=b;if(typeof S.name!="string"||S.name.length===0||typeof S.description!="string"||S.inputSchema===null||typeof S.inputSchema!="object")return;let k={name:S.name,description:S.description,inputSchema:S.inputSchema};return S.outputSchema!==null&&typeof S.outputSchema=="object"&&(k.outputSchema=S.outputSchema),k}).filter(b=>b!==void 0):[];if(v.length===0)throw new Error("register_mcp_tools requires at least one tool");return h.register(o.name,u,y,v),{ok:!0,registered:v.length}});let f=g=>{let w=g??{};if(typeof w.sessionId!="string"||w.sessionId.length===0)throw N(E.InvalidParams,"sessionId is required");return w.sessionId};if(u.onRequest("hydra-acp/session/extension_state/get",async g=>{let w=f(g),y=g??{};if(typeof y.key!="string"||y.key.length===0)throw N(E.InvalidParams,"key is required");if(!e.manager)throw N(E.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(w,o.name,y.key)??null}}),u.onRequest("hydra-acp/session/extension_state/list",async g=>{let w=f(g);if(!e.manager)throw N(E.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(w,o.name)}}),u.onRequest("hydra-acp/session/extension_state/set",async g=>{let w=f(g),y=g??{};if(typeof y.key!="string"||y.key.length===0)throw N(E.InvalidParams,"key is required");if(y.value===void 0)throw N(E.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw N(E.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(w,o.name,y.key,y.value)}catch(v){throw N(E.InvalidParams,v.message)}return{ok:!0}}),u.onRequest("hydra-acp/session/extension_state/delete",async g=>{let w=f(g),y=g??{};if(typeof y.key!="string"||y.key.length===0)throw N(E.InvalidParams,"key is required");if(!e.manager)throw N(E.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(w,o.name,y.key),{ok:!0}}),e.extensionMcpControls){let g=e.extensionMcpControls;u.onRequest("hydra-acp/mcp_tools/refresh_session",async w=>{let y=w??{};if(typeof y.sessionId!="string"||y.sessionId.length===0)throw N(E.InvalidParams,"refresh_session requires sessionId");return await g.notifyToolListChanged(y.sessionId,o.name),{ok:!0}})}u.onClose(()=>{h.clear(o.name)})}if(o?.kind==="transformer"){u.onRequest("hydra-acp/transformer/initialize",async f=>{let g=f??{},w=Array.isArray(g.intercepts)?g.intercepts.filter(y=>typeof y=="string"):[];if(e.transformers&&(e.transformers.registerConnection(o.name,u,w),e.manager?.defaultTransformers.includes(o.name))){let y=e.transformers.resolveChain([o.name])[0];if(y)for(let v of e.manager.liveSessions())v.addTransformer(y)}return{ack:!0}}),u.onClose(()=>{e.transformers?.deregisterConnection(o.name)}),u.onRequest("hydra-acp/message/emit",async f=>{let g=f??{},w=typeof g.sessionId=="string"?g.sessionId:void 0,y=typeof g.method=="string"?g.method:void 0,v=g.envelope,b=g.route;if(!w)throw N(-32602,"emit_message requires sessionId");if(!y&&b!=="client_broadcast")throw N(-32602,"emit_message requires method");let S=Re(e.manager,w),k=typeof g.respondsTo=="string"?g.respondsTo:void 0;if(k)return S.dischargeClaim(k,v),{ok:!0};if(b==="chain")return{ok:!0,response:await S.emitToChain(o.name,y,v)};if(b==="queue"){if(y!=="session/prompt")throw N(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await S.emitToQueue(o.name,v)}}if(b==="daemon")return{ok:!0,response:await S.emitToChain(o.name,y,v)};if(b==="client_broadcast"){if(!v||typeof v!="object")throw N(-32602,"client_broadcast requires an envelope object");return S.broadcastClientUpdate(v),{ok:!0}}throw N(-32602,`unsupported route: ${JSON.stringify(b)}`)}),u.onRequest("hydra-acp/session/request_permission",async f=>{let g=f??{},w=typeof g.sessionId=="string"?g.sessionId:void 0;if(!w)throw N(-32602,"hydra-acp/session/request_permission requires sessionId");return Re(e.manager,w).requestPermissionFromClients(g)}),u.onRequest("hydra-acp/transformer/attach",async f=>iy(f,o.name,e)),u.onRequest("hydra-acp/child_session/spawn",async f=>{let g=f??{},w=typeof g.agentId=="string"?g.agentId:void 0,y=typeof g.cwd=="string"?g.cwd:void 0,v=typeof g.parentSessionId=="string"?g.parentSessionId:void 0,b=g._meta&&typeof g._meta=="object"?g._meta:void 0,S=b&&b["hydra-acp"]&&typeof b["hydra-acp"]=="object"?b["hydra-acp"]:void 0,k=S&&typeof S.title=="string"?S.title:void 0,C=S&&typeof S.model=="string"?S.model:void 0;if(!y&&v){let W=e.manager.get(v);W&&(y=W.cwd)}if(!y)throw N(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let A=await tn(y),R=w??A.agentId??e.defaultAgent,T=await e.registry?.getAgent(R),M=rn(A.configDefaults,T??{id:R})?.value,L=C??M?.model,J=typeof g.interactive=="boolean"?g.interactive:!1;return{childSessionId:(await e.manager.create({agentId:R,cwd:y,parentSessionId:v,interactive:J,transformChain:[],title:k,model:L,configDefaults:M})).sessionId}}),u.onRequest("hydra-acp/session/fork",async f=>{let g=f??{};if(typeof g.sessionId!="string")throw N(E.InvalidParams,"fork_session requires sessionId");let w=typeof g.forkAt=="string"?g.forkAt:void 0,y=typeof g.cwd=="string"?g.cwd:void 0,v=typeof g.agentId=="string"?g.agentId:void 0,b=typeof g.mode=="string"&&(g.mode==="verbatim"||g.mode==="synthesis")?g.mode:void 0,S=typeof g.model=="string"&&g.model.length>0?g.model:void 0,k=await e.manager.forkSession(g.sessionId,{...w!==void 0?{forkAt:w}:{},...y!==void 0?{cwd:y}:{},...v!==void 0?{agentId:v}:{},...b!==void 0?{mode:b}:{},...S!==void 0?{model:S}:{}}),C=e.manager.get(k.sessionId);if(!C){let T=await e.manager.loadFromDisk(k.sessionId);if(!T)throw N(E.InternalError,`fork ${k.sessionId} vanished before it could be attached`);C=await It(e,{...T,onInstallProgress:Qs(u)})}Kt(l,C,C.sessionId);let A=lt(u,C,l),{entries:R}=await C.attach(A,"full");l.attached.set(C.sessionId,{sessionId:C.sessionId,clientId:A.clientId,readonly:!1});for(let T of R){if(u.isClosed())break;await u.notify(T.method,Ue(He(T.params,T.recordedAt),T.seq)).catch(()=>{})}return{...k,sessionId:C.sessionId}}),u.onRequest("session/fork",async f=>{let g=f??{};if(typeof g.sessionId!="string")throw N(E.InvalidParams,"session/fork requires sessionId");let w=typeof g.cwd=="string"?g.cwd:void 0,y=await e.manager.forkSession(g.sessionId,{...w!==void 0?{cwd:w}:{},mode:"verbatim"}),v=e.manager.get(y.sessionId);if(!v){let k=await e.manager.loadFromDisk(y.sessionId);if(!k)throw N(E.InternalError,`fork ${y.sessionId} vanished before it could be attached`);v=await It(e,{...k,onInstallProgress:Qs(u)})}Kt(l,v,v.sessionId);let b=lt(u,v,l),{entries:S}=await v.attach(b,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:b.clientId,readonly:!1});for(let k of S){if(u.isClosed())break;await u.notify(k.method,Ue(He(k.params,k.recordedAt),k.seq)).catch(()=>{})}return{sessionId:v.sessionId}});let h=async(f,g)=>{let w=f??{};if(typeof w.sessionId!="string")throw N(E.InvalidParams,`${g} requires sessionId`);let y=await e.manager.resolveCanonicalId(w.sessionId)??w.sessionId,v=e.manager.get(y);if(v)return await v.close({deleteRecord:!0,by:`session/delete ${l.clientId}`}),await e.manager.waitForDeletion(y),await e.manager.hasRecord(y)&&await e.manager.deleteRecord(y),{id:y,existed:!0};let b=await e.manager.deleteRecord(y);return{id:y,existed:b}};u.onRequest("session/delete",async f=>(await h(f,"session/delete"),{})),u.onRequest("session/close",async f=>{let g=f??{};if(typeof g.sessionId!="string")throw N(E.InvalidParams,"session/close requires sessionId");p(g.sessionId,"session/close");let w=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,y=e.manager.get(w);if(y)return await y.close({deleteRecord:!1,by:`session/close ${l.clientId}`+(l.processIdentity?` (${l.processIdentity.name})`:"")}),{};if(await e.manager.hasRecord(w))return{};throw N(E.SessionNotFound,`session ${w} not found`)}),u.onRequest("hydra-acp/session/delete",async f=>{let{id:g,existed:w}=await h(f,"hydra-acp/session/delete");if(!w)throw N(E.SessionNotFound,`session ${g} not found`);return{deleted:!0,sessionId:g}}),u.onRequest("hydra-acp/child_session/await",async f=>{let g=f??{},w=typeof g.childSessionId=="string"?g.childSessionId:void 0,y=g.until==="idle"?"idle":"turn_complete",v=typeof g.timeoutMs=="number"?Math.min(g.timeoutMs,18e5):3e5;if(!w)throw N(-32602,"await_child requires childSessionId");let b=Re(e.manager,w,`child session ${w} not found`);return new Promise(S=>{let A=[],R=[],T=0,M=!1,L,J,$=!1,W=()=>{$||($=!0,clearTimeout(q),L?.(),J?.(),S(M?{entries:A,truncated:!0}:{entries:A}))};L=b.onBroadcast(te=>{let ae=ty(te);for(A.push(te),R.push(ae),T+=ae;A.length>0&&(A.length>1e3||T>1048576);)A.shift(),T-=R.shift()??0,M=!0;y==="turn_complete"&&te.params?.update?.sessionUpdate==="turn_complete"&&W()});let q=setTimeout(W,v);typeof q.unref=="function"&&q.unref(),J=b.onClose(()=>W())})}),u.onRequest("hydra-acp/child_session/close",async f=>{let g=f??{},w=typeof g.childSessionId=="string"?g.childSessionId:void 0;if(!w)throw N(-32602,"close_child_session requires childSessionId");let y=e.manager.get(w);return y&&await y.close({deleteRecord:!1,by:`child_session/close ${l.clientId}`}),{ok:!0}}),u.onRequest("hydra-acp/attention/set",async f=>ay(f,o.name,e)),u.onRequest("hydra-acp/attention/clear",async f=>dy(f,o.name,e)),u.onRequest("hydra-acp/connection/keep_alive",async f=>{let g=f??{},w=typeof g.token=="string"?g.token:void 0,y=typeof g.sessionId=="string"?g.sessionId:void 0,v=typeof g.estimatedRemainingMs=="number"?g.estimatedRemainingMs:void 0;return w&&y&&e.manager.get(y)?.keepAliveClaim(w,v),{ok:!0}})}u.onRequest("hydra-acp/session/tool_content",async h=>{let f=h??{};if(typeof f.sessionId!="string"||typeof f.hash!="string")throw N(E.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let g=await e.manager.resolveCanonicalId(f.sessionId)??f.sessionId,w=await e.manager.loadToolBlob(g,f.hash);if(w===null)throw N(E.SessionNotFound,"tool content not found");return{content:w}}),u.onRequest("authenticate",async h=>ny(h,e)),u.onRequest("logout",async h=>sy(h,e)),u.onRequest("session/new",async h=>{let f=Wi.parse(h),g=pt(h?._meta),w=Array.isArray(g.transformers)&&g.transformers.every(Z=>typeof Z=="string")?g.transformers:e.manager.defaultTransformers??[],y=e.transformers?.resolveChain(w)??[],v=await tn(f.cwd),b=g.agentId??v.agentId??e.defaultAgent,S=await e.registry?.getAgent(b),k=rn(v.configDefaults,S??{id:b})?.value,C,A,R=f.mcpServers;if(g.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){C=cu(32).toString("hex"),A=e.mcpTokenRegistry.reserve(C);let ve={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${C}`}]};R=[...f.mcpServers??[],ve]}let T,M,L=Vt(e);L!==void 0&&(R=[...R??[],...L.descriptors]);let J=Oo({baselineMcpServers:f.mcpServers,stdinEnabled:g.mcpStdin===!0,deps:e}),$;try{$=await e.manager.create({cwd:f.cwd,agentId:b,mcpServers:R,title:g.title,agentArgs:g.agentArgs,model:g.model??k?.model,configDefaults:k,onInstallProgress:Qs(u),transformChain:y,originatingClient:l.clientInfo,...g.interactive!==void 0?{interactive:g.interactive}:{},...g.env!==void 0?{forwardedEnv:g.env}:{},...g.workspace!==void 0?{workspace:g.workspace}:{},...J?{mintMcpServersForSwap:J}:{}})}catch(Z){throw A!==void 0&&A.abandon(Z instanceof Error?Z:void 0),M!==void 0&&M.abandon(Z instanceof Error?Z:void 0),L!==void 0&&L.abandon(Z instanceof Error?Z:void 0),Z}if(C!==void 0&&A!==void 0&&e.mcpTokenRegistry!==void 0){let Z=C,ve=e.mcpTokenRegistry;A.complete($),$.onClose(()=>{ve.unbind(Z)})}if(T!==void 0&&M!==void 0&&e.mcpTokenRegistry!==void 0){let Z=T,ve=e.mcpTokenRegistry;M.complete($),$.onClose(()=>{ve.unbind(Z)})}L!==void 0&&L.bindToSession($),pu($.sessionId,e);let W,q;try{Kt(l,$,$.sessionId),W=lt(u,$,l),{entries:q}=await $.attach(W,"full")}catch(Z){throw await $.close({deleteRecord:!1,by:"session/new attach-failed"}).catch(()=>{}),Z}l.attached.set($.sessionId,{sessionId:$.sessionId,clientId:W.clientId,readonly:!1}),setImmediate(()=>{(async()=>{for(let Z of q){if(u.isClosed())break;await u.notify(Z.method,Ue(He(Z.params,Z.recordedAt),Z.seq)).catch(()=>{})}})()});let te=Ys($),ae=Xs($);return{sessionId:$.sessionId,...te?{modes:te}:{},...ae?{models:ae}:{},configOptions:$.buildConfigOptions(),_meta:Zs(e.manager,$,{clientId:W.clientId})}}),u.onRequest("session/attach",async h=>{let f=zi.parse(h),g=f.clientInfo?.version;g&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,g):e.onTransformerVersion?.(o.name,g));let w=pt(f._meta),y=w.resume,v=w.readonly===!0,b=w.env;s.log.info(`session/attach sessionId=${f.sessionId} hasResumeHints=${!!y} readonly=${v}`);let S=y?f.sessionId:await e.manager.resolveCanonicalId(f.sessionId)??f.sessionId,k=e.manager.get(S);if(!k&&v){let $=await e.manager.loadFromDisk(S);if(!$)throw N(E.SessionNotFound,`session ${f.sessionId} not found`);let W=await e.manager.loadHistory(S),q=f.clientId??`cli_${Vo(8)}`;l.attached.set($.hydraSessionId,{sessionId:$.hydraSessionId,clientId:q,readonly:!0}),s.log.info(`session/attach OK (viewer) sessionId=${$.hydraSessionId} clientId=${q} attachedCount=${l.attached.size} replayed=${W.length}`);for(let te of W)await u.notify(te.method,Ue(He(te.params,te.recordedAt),te.seq)).catch(()=>{});return{sessionId:$.hydraSessionId,clientId:q,connectedClients:[q],historyPolicy:"full",replayed:W.length,_meta:cy($)}}let C=!k;if(!k){let $=await e.manager.loadFromDisk(S),W=await ry(S,y,$?.upstreamSessionId,e.manager);W.kind==="ignore"&&s.log.warn(W.logMessage);let q=$;if(y&&W.kind==="honor"&&(q={...$,hydraSessionId:f.sessionId,upstreamSessionId:y.upstreamSessionId,agentId:y.agentId,cwd:$?.workspace?.path??y.cwd,...y.title!==void 0?{title:y.title}:{},...y.agentArgs!==void 0?{agentArgs:y.agentArgs}:{}}),!q)throw N(E.SessionNotFound,`session ${f.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(q.agentId,q.upstreamSessionId))throw N(E.SessionNotFound,`session ${f.sessionId} was deleted`);let te=q.originatingClient?q:{...q,originatingClient:l.clientInfo},ae=b!==void 0?{...te,forwardedEnv:b}:te;k=await It(e,{...ae,onInstallProgress:Qs(u)})}Kt(l,k,k.sessionId);let A=lt(u,k,l,f.clientInfo,f.clientId),R=w.replayMode==="drip",{entries:T,appliedPolicy:M}=await k.attach(A,f.historyPolicy,{afterMessageId:f.afterMessageId,afterSeq:f.afterSeq,raw:R,...w.historyLimit!==void 0?{historyLimit:w.historyLimit}:{},...w.toolContent!==void 0?{toolContent:w.toolContent}:{}});if(l.attached.set(k.sessionId,{sessionId:k.sessionId,clientId:A.clientId,readonly:v}),b!==void 0&&await e.manager.setForwardedEnv(k.sessionId,b).catch(()=>{}),s.log.info(`session/attach OK sessionId=${k.sessionId} clientId=${A.clientId} attachedCount=${l.attached.size} requestedPolicy=${f.historyPolicy} appliedPolicy=${M} replayed=${T.length} readonly=${v}${R?" replayMode=drip":""}`),R){let $=w.dripSpeed&&w.dripSpeed>0?w.dripSpeed:1,W=750;(async()=>{let q=null;for(let te of T){let ae=typeof te.recordedAt=="number"?te.recordedAt:null;if(q!==null&&ae!==null){let Z=Math.min(W,Math.max(0,(ae-q)/$));Z>0&&await new Promise(ve=>setTimeout(ve,Z))}ae!==null&&(q=ae);try{await u.notify(te.method,Ue(He(te.params,ae??void 0),te.seq))}catch{return}}})()}else for(let $=0;$<T.length&&!u.isClosed();$++){let W=T[$],q=u.notify(W.method,Ue(He(W.params,W.recordedAt),W.seq)).catch(()=>{});($+1)%200===0&&await q}k.replayPendingPermissions(A);let L=Ys(k),J=Xs(k);return{sessionId:k.sessionId,clientId:A.clientId,connectedClients:k.connectedClients(A.clientId),historyPolicy:M,replayed:T.length,...L?{modes:L}:{},...J?{models:J}:{},configOptions:k.buildConfigOptions(),_meta:Zs(e.manager,k,{resurrected:C})}}),u.onRequest("session/detach",async h=>{let f=Ji.parse(h),g=l.attached.get(f.sessionId);if(!g)throw N(E.SessionNotFound,"client not attached to that session");let w=e.manager.get(f.sessionId);return w?.detach(g.clientId),l.attached.delete(f.sessionId),w&&e.manager.reapIfOrphanedNonInteractive(f.sessionId),{sessionId:f.sessionId,_meta:{[de]:{detachStatus:"detached"}}}}),u.onRequest("session/list",async h=>{let f=Vi.parse(h??{});return{sessions:(await e.manager.list({cwd:f.cwd})).filter(v=>v.originatingClient?.name!==hs).map(Gi)}}),u.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw N(E.InternalError,"agent registry unavailable");return Pt(e.registry)}),u.onRequest("hydra-acp/agents/auth_methods",async h=>{let f=h??{};if(typeof f.agentId!="string"||f.agentId.length===0)throw N(E.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(f.agentId)).authMethods??[]}}),u.onRequest("session/prompt",async h=>{let f=Ki.parse(h);p(f.sessionId,"session/prompt");let g=await ou(f,e.manager,b=>{s.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${b} sessionId=${f.sessionId}`)});if(g?.fromSession!==void 0){if((g.depth??0)>3)throw s.log.warn(`session/prompt: refusing depth ${g.depth} chain from ${g.fromSession} to ${f.sessionId}`),N(E.InvalidRequest,`message chain too deep (${g.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(g.awaiting===!0&&au(g.fromSession,f.sessionId))throw s.log.warn(`session/prompt: refusing deadlock ${g.fromSession} -> ${f.sessionId}`),N(E.InvalidRequest,`would deadlock: ${f.sessionId} is already blocked waiting on ${g.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let w=l.attached.get(f.sessionId);if(!w)throw s.log.warn(`session/prompt rejected: not attached sessionId=${f.sessionId} attachedKeys=[${[...l.attached.keys()].join(",")}]`),N(E.SessionNotFound,"not attached to session");let y=e.manager.get(f.sessionId);if(!y){let b=await e.manager.loadFromDisk(f.sessionId);if(!b)throw N(E.SessionNotFound,`session ${f.sessionId} not found`);s.log.info(`session/prompt auto-resurrecting cold sessionId=${f.sessionId}`),y=await It(e,b);let S=lt(u,y,l,void 0,w.clientId);await y.attach(S,"none")}let v=g?.awaiting===!0&&g.fromSession!==void 0?iu(g.fromSession,f.sessionId):void 0;try{return await y.prompt(w.clientId,f,g)}finally{v?.()}});let m=h=>{let f;try{f=Gn.parse(h)}catch(y){s.log.warn(`session/cancel: invalid params: ${y.message}`);return}let g=l.attached.get(f.sessionId);if(!g)return;if(g.readonly){s.log.warn(`session/cancel dropped (readonly attachment) sessionId=${f.sessionId}`);return}let w=e.manager.get(f.sessionId);w&&w.cancel(g.clientId).catch(y=>{s.log.warn(`session/cancel for ${f.sessionId}: ${y.message}`)})};u.onNotification("session/cancel",m),u.onRequest("session/cancel",async h=>{let f=Gn.parse(h);return p(f.sessionId,"session/cancel"),m(h),null}),u.onRequest("hydra-acp/prompt/cancel",async h=>{let f=Yi.parse(h);return p(f.sessionId,"hydra-acp/prompt/cancel"),Re(e.manager,f.sessionId).cancelQueuedPrompt(f.messageId)}),u.onRequest("hydra-acp/session/force_cancel",async h=>{let f=Gn.parse(h);return p(f.sessionId,"hydra-acp/session/force_cancel"),Re(e.manager,f.sessionId).forceCancel()}),u.onRequest("hydra-acp/prompt/update",async h=>{let f=Xi.parse(h);return p(f.sessionId,"hydra-acp/prompt/update"),Re(e.manager,f.sessionId).updateQueuedPrompt(f.messageId,f.prompt)}),u.onRequest("hydra-acp/prompt/amend",async h=>{let f=Zi.parse(h);p(f.sessionId,"hydra-acp/prompt/amend");let g=l.attached.get(f.sessionId);if(!g)throw N(E.SessionNotFound,"not attached to session");return Re(e.manager,f.sessionId).amendPrompt(g.clientId,f)}),u.onRequest("_session/steering",async h=>{let f=ea.parse(h);p(f.sessionId,"_session/steering");let g=l.attached.get(f.sessionId);if(!g)throw N(E.SessionNotFound,"not attached to session");let w=e.manager.get(f.sessionId);if(!w){let y=await e.manager.loadFromDisk(f.sessionId);if(!y)throw N(E.SessionNotFound,`session ${f.sessionId} not found`);w=await It(e,y);let v=lt(u,w,l,void 0,g.clientId);await w.attach(v,"none")}return w.steer(g.clientId,f)}),u.onRequest("session/resume",async h=>{let f=h??{},g=typeof f.sessionId=="string"?f.sessionId:void 0;if(!g)throw N(E.InvalidParams,"session/resume requires sessionId");let w=await e.manager.resolveCanonicalId(g)??g,y=e.manager.get(w);if(!y){let k=await e.manager.loadFromDisk(w);if(!k)throw N(E.SessionNotFound,`session ${g} not found in memory or on disk`);y=await It(e,k)}Kt(l,y,y.sessionId);let v=lt(u,y,l);await y.attach(v,"pending_only"),l.attached.set(y.sessionId,{sessionId:y.sessionId,clientId:v.clientId,readonly:!1}),y.replayPendingPermissions(v);let b=Ys(y),S=Xs(y);return{sessionId:y.sessionId,...b?{modes:b}:{},...S?{models:S}:{},configOptions:y.buildConfigOptions(),_meta:Zs(e.manager,y,{clientId:v.clientId})}}),u.onRequest("session/load",async h=>{let f=h??{},g=typeof f.sessionId=="string"?f.sessionId:void 0;if(!g)throw N(E.InvalidParams,"session/load requires sessionId");let w=await e.manager.resolveCanonicalId(g)??g,y=e.manager.get(w);if(!y){let C=await e.manager.loadFromDisk(w);if(!C)throw N(E.SessionNotFound,`session ${g} not found in memory or on disk`);y=await It(e,C)}Kt(l,y,y.sessionId);let v=lt(u,y,l),{entries:b}=await y.attach(v,"full");l.attached.set(y.sessionId,{sessionId:y.sessionId,clientId:v.clientId,readonly:!1});for(let C of b){if(u.isClosed())break;await u.notify(C.method,Ue(He(C.params,C.recordedAt),C.seq)).catch(()=>{})}y.replayPendingPermissions(v);let S=Ys(y),k=Xs(y);return{sessionId:y.sessionId,...S?{modes:S}:{},...k?{models:k}:{},configOptions:y.buildConfigOptions(),_meta:Zs(e.manager,y,{clientId:v.clientId})}}),u.onRequest("session/set_model",async h=>{let f=h?.sessionId;typeof f=="string"&&p(f,"session/set_model");let g=oy(h,e.manager);if(g.kind==="error")throw s.log.warn(g.logMessage),N(g.code,g.message);if(g.kind==="no_op")return s.log.warn(g.logMessage),await u.notify("session/update",{sessionId:g.sessionId,update:{sessionUpdate:"_hydra_current_model_update",currentModel:g.currentModel}}).catch(()=>{}),null;s.log.info(g.logMessage);let{modelId:w}=g,y=await g.session.forwardModelChange(w,h);return g.session.applyAgentConfigOptionResponse(y,"model"),g.session.applyModelChange(w),y}),u.onRequest("session/set_mode",async h=>{let f=h,g=f?.sessionId;if(typeof g=="string"&&p(g,"session/set_mode"),!f||typeof f.sessionId!="string")throw N(E.InvalidParams,"session/set_mode requires string sessionId");if(typeof f.modeId!="string")throw N(E.InvalidParams,"session/set_mode requires string modeId");let w=Re(e.manager,f.sessionId),y=await w.forwardRequest("session/set_mode",h);return w.applyModeChange(f.modeId),y}),u.onRequest("session/set_config_option",async h=>{let f=h,g=b=>N(E.InvalidParams,b),w=f?.sessionId;if(typeof w=="string"&&p(w,"session/set_config_option"),!f||typeof f.sessionId!="string")throw g("session/set_config_option requires string sessionId");if(typeof f.configId!="string")throw g("session/set_config_option requires string configId");if(typeof f.value!="string")throw g("session/set_config_option requires string value");let y=Re(e.manager,f.sessionId),v=y.buildConfigOptions().find(b=>b.id===f.configId);if(!v)throw g(`unknown configId ${JSON.stringify(f.configId)} for this session`);if(!v.options.some(b=>b.value===f.value))throw g(`value ${JSON.stringify(f.value)} is not valid for configId ${JSON.stringify(f.configId)}`);switch(f.configId){case"model":{if(f.value!==y.currentModel){let b=await y.forwardModelChange(f.value);y.applyAgentConfigOptionResponse(b,"model")}y.applyModelChange(f.value);break}case"mode":{f.value!==y.currentMode&&await y.forwardRequest("session/set_mode",{sessionId:f.sessionId,modeId:f.value}),y.applyModeChange(f.value);break}case"agent":{f.value!==y.agentId&&await y.setAgent(f.value);break}default:{let b=await y.forwardRequest("session/set_config_option",{sessionId:f.sessionId,configId:f.configId,value:f.value});y.applyAgentConfigOptionResponse(b,f.configId)&&y.broadcastConfigOptions()}}return{configOptions:y.buildConfigOptions()}}),u.setDefaultHandler(async(h,f)=>{let g=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),w=f.startsWith("session/"),y=f.startsWith("hydra-acp/");if(!w&&!y||h===null||typeof h!="object"||g.has(f))throw N(E.MethodNotFound,`Method not found: ${f}`);let v=h.sessionId;if(typeof v!="string")throw N(E.MethodNotFound,`Method not found: ${f}`);return p(v,f),Re(e.manager,v).forwardRequest(f,h)})})}async function ny(s,e){let t=s??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw N(E.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 m=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(m)}let d=a.authMethods??[],c=d.find(m=>m.id===n);if(!c){let m=d.map(h=>h.id);throw N(E.InvalidParams,`authenticate: methodId ${JSON.stringify(n)} is not advertised by agent ${a.agentId}; valid: [${m.map(h=>JSON.stringify(h)).join(", ")}]`)}let u=c._meta?.type,l=(()=>{let m=c._meta?.["terminal-auth"];if(m&&typeof m=="object"&&!Array.isArray(m))return m})();if((c.type??(u==="agent"||u==="terminal"?u:l!==void 0?"terminal":"agent"))==="terminal"){let m=(v,b)=>{if(!Array.isArray(v))throw N(E.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${b} must be a string[]; got ${v===null?"null":typeof v}`);for(let S of v)if(typeof S!="string")throw N(E.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${b} must be string[]; got non-string entry ${JSON.stringify(S)}`);return v},h=await e.manager.planSpawnForAgent(a.agentId),f,g;if(l?.args!==void 0){let v=typeof l.command=="string"?l.command:void 0;f=v!==void 0&&lu.isAbsolute(v)?v:h.command,g=m(l.args,'_meta["terminal-auth"].args')}else{let v=c.args!==void 0?{raw:c.args,label:"args"}:c._meta?.args!==void 0?{raw:c._meta.args,label:"_meta.args"}:void 0,b=v!==void 0?m(v.raw,v.label):[];f=h.command,g=[...h.args,...b]}let w={};for(let[v,b]of Object.entries(process.env))typeof b=="string"&&(w[v]=b);Object.assign(w,h.env);let y=uu.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${n}`),{kind:"terminal",command:f,args:g,env:w,cwd:y}}try{return await a.connection.request("authenticate",{methodId:n})}catch(m){throw dt(m,a)}}async function sy(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 Qs(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(ta,t).catch(()=>{})}}function Ys(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 Xs(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 ry(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 oy(s,e){if(!s||typeof s!="object")return{kind:"error",code:E.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:E.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:E.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:E.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=n.availableModels(),o=Ot(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:E.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 iy(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0;if(!r)throw N(E.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw N(E.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw N(E.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return Re(t.manager,r).addTransformer(o),{ok:!0}}async function ay(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 N(E.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw N(E.InvalidParams,"hydra-acp/attention/set requires string reason");return Re(t.manager,r).setAttentionFlag(e,o,n.payload),{ok:!0}}async function dy(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 N(E.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw N(E.InvalidParams,"hydra-acp/attention/clear requires string reason");return Re(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function cy(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:Sn(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{[de]:Vn(e,t)}}function Zs(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 on(e.agentMeta,Vn(n,r))}function uy(){return{protocolVersion:1,agentInfo:{name:"hydra",version:ge},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:{...on(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}}}),steering:{supported:!0}}}}function ly(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 pu(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 lt(s,e,t,n,r){return{clientId:r??`cli_${Vo(8)}`,connection:s,clientInfo:n}}function Kt(s,e,t){let n=s.attached.get(t);n&&(e.detach(n.clientId),s.attached.delete(t))}var er=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 fy}from"crypto";import{McpServer as py}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as gy}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as me}from"zod";function Go(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 Se(s){return{content:[{type:"text",text:JSON.stringify(s)}],structuredContent:s}}var gu="Bearer ";function Qt(s){let e=s.headers.authorization;if(typeof e!="string"||!e.startsWith(gu))return;let t=e.slice(gu.length).trim();return t.length>0?t:void 0}function my(s){let e=new py({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:me.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let n=s.streamTail(t);return Se(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:me.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let n=s.streamHead(t);return Se(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:me.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:me.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:me.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 Se(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:me.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:me.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 Se({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:me.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:me.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:me.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:me.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:me.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:me.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:me.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:me.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:me.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 Se(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 Se(t)}),e}var hy=1e4;function mu(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=my(a),u=new gy({sessionIdGenerator:()=>fy()});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=Qt(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,m=new Promise(f=>{p=setTimeout(()=>f(void 0),hy)}),h=await Promise.race([c.sessionReady.catch(()=>{}),m]);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 yy}from"crypto";import{McpServer as wy}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as vy}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as Ve}from"zod";function ky(s){switch(s){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}var hu=2e3,yu=2e4;function by(s,e,t){if(e!=="tool_call"&&e!=="tool_call_update")return Nt([s]);let n=[],r=cn(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=Xn(t);return i!==void 0&&n.push(i),n.join(`
196
- `)}function Sy(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 Iy(s){let e=new wy({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:Ve.string().min(1).describe("Case-insensitive substring to search for."),limit:Ve.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:Ve.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 Se({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=Go(u);if(!l)continue;let{kind:p,update:m}=l;if((p==="tool_call"||p==="tool_call_update")&&!r)continue;let h=by(u,p,m),f=h.toLowerCase().indexOf(a);if(f<0)continue;let g=ky(p),w=Sy(h,f),y=typeof u.recordedAt=="number"?String(u.recordedAt):void 0;if(i.push({entryId:c,speaker:g,snippet:w,timestamp:y}),i.length>=n)break}i.sort((c,u)=>c.entryId-u.entryId);let d=i.length>=n;return Se({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:Ve.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:Ve.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 Se({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 Se({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=Nt(u,{toolOutput:{maxPerCall:hu,maxTotal:yu}});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:Ve.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:Ve.string().optional().describe("ACP tool kind: execute (shell), read, edit, think, other. Agent-independent, unlike tool_name."),file_path:Ve.string().optional(),limit:Ve.number().int().min(1).max(100).optional(),include_output:Ve.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 Se({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:v}of a.iterRecallNewestFirst()){let b=Go(v);if(!b)continue;let{kind:S,update:k}=b;if(S!=="tool_call"&&S!=="tool_call_update")continue;let C=typeof k.toolCallId=="string"&&k.toolCallId.length>0?k.toolCallId:`__noid_${y}`,A=l.get(C);if(A||(A={entryId:y,toolName:"(unnamed)",nameAuthoritative:!1,rawInput:{},locations:[],status:"in_progress"},l.set(C,A)),y<A.entryId&&(A.entryId=y),!A.nameAuthoritative){let T=cn(k);T!==void 0?(A.toolName=T,A.nameAuthoritative=!0):typeof k.name=="string"&&k.name.length>0?(A.toolName=k.name,A.nameAuthoritative=!0):S==="tool_call"&&typeof k.title=="string"&&k.title.length>0&&(A.toolName=k.title,A.nameAuthoritative=!0)}if(A.kind===void 0&&typeof k.kind=="string"&&k.kind.length>0&&(A.kind=k.kind),A.output===void 0){let T=Xn(k);T!==void 0&&(A.output=T)}let R=k.rawInput;if(R&&typeof R=="object"&&!Array.isArray(R)&&Object.keys(R).length>0)for(let[T,M]of Object.entries(R))A.rawInput[T]===void 0&&(A.rawInput[T]=M);if(Array.isArray(k.locations))for(let T of k.locations){let M=T?.path;typeof M=="string"&&M.length>0&&!A.locations.includes(M)&&A.locations.push(M)}if(typeof k.status=="string"&&A.status==="in_progress"&&(A.status=k.status),v.recordedAt!==void 0&&A.timestamp===void 0&&(A.timestamp=String(v.recordedAt)),l.size>=p)break}let m=[...l.keys()].sort((y,v)=>l.get(y).entryId-l.get(v).entryId),h=[],f=yu,g=!1;for(let y of m){let v=l.get(y);if(v.toolName=Or({name:v.toolName,rawInput:v.rawInput,...v.kind!==void 0?{kind:v.kind}:{}}),d&&!v.toolName.toLowerCase().includes(t.toLowerCase())||c&&(v.kind??"").toLowerCase()!==n.toLowerCase())continue;if(u){let k=r.toLowerCase(),C=["file_path","filePath","path"],A=!1;for(let R of C){let T=v.rawInput[R];if(typeof T=="string"&&T.toLowerCase().includes(k)){A=!0;break}}if(!A){for(let R of v.locations)if(R.toLowerCase().includes(k)){A=!0;break}}if(!A)continue}let b={};for(let[k,C]of Object.entries(v.rawInput))typeof C=="string"?b[k]=C.length>500?C.slice(0,497)+"\u2026":C:(typeof C=="number"||typeof C=="boolean")&&(b[k]=C);v.locations.length>0&&b.locations===void 0&&(b.locations=v.locations);let S={entryId:v.entryId,tool:v.toolName,args:b,status:v.status,timestamp:v.timestamp};if(v.kind!==void 0&&(S.kind=v.kind),i&&v.output!==void 0){let k=v.output,C=Math.min(hu,f);if(C<=0)g=!0;else{let A=k.length<=C?k:k.slice(0,C-1)+"\u2026";S.output=A,S.outputBytes=k.length,S.outputTruncated=A.length<k.length,f-=A.length}}if(h.push(S),h.length>=o)break}let w=h.length>=o;return Se({calls:h,truncated:w,...g?{outputBudgetExhausted:g}:{}})}),e}var Ay=1e4;function wu(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=Iy(a),u=new vy({sessionIdGenerator:()=>yy()});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=Qt(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,m=new Promise(f=>{p=setTimeout(()=>f(void 0),Ay)}),h=await Promise.race([c.sessionReady.catch(()=>{}),m]);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 tr=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 _y}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as $y}from"crypto";import{Server as Cy}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as Ry,ListToolsRequestSchema as xy}from"@modelcontextprotocol/sdk/types.js";function vu(s,e,t,n){let r=typeof t=="function"?async()=>t():async()=>t,o=new Cy({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(xy,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(Ry,async(a,d)=>{let c=a.params.name,u=d._meta?.progressToken??d.requestId,l=Ty(u,d.sendNotification);try{let p=await r(),m=await Py(e.connection,s,c,a.params.arguments??{},p);return My(m,c)}catch(p){return Ko(p instanceof Error?p.message:String(p))}finally{l()}}),o}var Ey=15e3;function Ty(s,e,t=Ey){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 Py(s,e,t,n,r){return await s.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:n,sessionId:r})}function My(s,e){if(s===null||typeof s!="object")return Ko(`extension ${e} returned non-object`);let t=s;return Array.isArray(t.content)?t:Ko(`extension ${e} omitted content array`)}function Ko(s){return{content:[{type:"text",text:s}],isError:!0}}var Fy=1e4;function ku(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,m]of n){if(e.lookup(p)?.session?.sessionId!==u)continue;let f=m.get(l);if(f!==void 0)try{await f.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 b=n.get(u);if(b!==void 0){n.delete(u);for(let S of b.values())await r(S)}}));let m=p.get(l);if(m!==void 0)return m.transport;let h=t.lookup(l);if(h===void 0)return;let y=vu(l,h,async()=>{let b=e.lookup(u);if(b===void 0)throw new Error("mcp token no longer bound");if(b.session!==void 0)return b.session.sessionId;let S,k=new Promise(A=>{S=setTimeout(()=>A(void 0),Fy)}),C=await Promise.race([b.sessionReady.catch(()=>{}),k]);if(S!==void 0&&clearTimeout(S),C===void 0)throw new Error("session not ready");return C.sessionId},{peekSessionId:()=>e.lookup(u)?.session?.sessionId,fetchSessionTools:async b=>{let S=await h.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:b});if(!S||typeof S!="object")return;let k=S.tools;if(!Array.isArray(k))return;let C=[];for(let A of k){if(!A||typeof A!="object")continue;let R=A;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),C.push(T)}return C}}),v=new _y({sessionIdGenerator:()=>$y()});return await y.connect(v),p.set(l,{server:y,transport:v}),v}async function d(u,l){let p=Qt(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,f=await a(p,h);if(f===void 0){l.code(404).send({error:`unknown mcp server: ${h}`});return}l.hijack(),await f.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 Ru(s,e){Uy(s),gr(s.daemon.scrubEnv);let t=s,n=s.daemon.tls?await Ge.readFile(fe(s.daemon.tls.key)):void 0,r=s.daemon.tls?await Ge.readFile(fe(s.daemon.tls.cert)):void 0;await Ge.mkdir(x.home(),{recursive:!0});let{stream:o,fileStream:i}=await Ly(s.daemon.logLevel),a=Oy({logger:{level:s.daemon.logLevel,stream:o},bodyLimit:256*1024*1024});await a.register(Ny,{options:{handleProtocols:hi}}),kr(O=>{a.log.info(O)}),Ir(O=>{a.log.info(O)});let d=await Ms.load(),c=await zs.load();Wo(),Uo(c);let u=new Ks(c);u.start();let l=new Us(c);l.start();let p=new Ns,m=new Os,h=new _s(e),f=new Fs([h,new $s(d),m]),g=Xd({validator:f});a.addHook("onRequest",async(O,ke)=>{O.routeOptions.config?.skipAuth||O.url==="/acp"||O.url?.startsWith("/acp?")||(await g(O,ke),!ke.sent&&O.authIdentity?.startsWith("script:")&&!ec(O.method,O.routeOptions.url)&&ke.code(403).send({error:"script tokens may only access read-only session data"}))});let w=setInterval(()=>{d.sweepExpired()},300*1e3);w.unref();let y=setInterval(()=>{p.sweepExpired()},300*1e3);y.unref();let v=new zn(s,{onFetched:()=>{jd(v,C)},onStaleFallback:(O,ke)=>{let Xt=Math.round(ke/36e5),Zt=Xt>=48?`${Math.round(Xt/24)}d`:`${Xt}h`;a.log.warn(`registry fetch failed (${O.message}); serving stale cache last synced ${Zt} ago; agent versions may be outdated ('hydra registry refresh' to retry)`)}});Eo(O=>a.log.info(O));let b={info:O=>a.log.info(O),warn:O=>a.log.warn(O)},S=O=>rt.spawn({...O,stderrTailBytes:s.daemon.agentStderrTailBytes,logger:b});Si(s.compressToolContent);let k=new Ts,C=new bs(v,S,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:b,npmRegistry:s.npmRegistry,extensionCommands:k,defaultCwd:s.defaultCwd,disableWorkspaceSnapshots:s.disableWorkspaceSnapshots}),A=new Gs(c,void 0,{resolvesLocally:async O=>await C.resolveCanonicalId(O)!==void 0,cache:l}),R=new xs(li(s),void 0,{tokenRegistry:m}),T=new Es(fi(s),void 0,{tokenRegistry:m}),M=[];_c(a,ge,Ud(s),()=>M);let L=new er,J=new tr,$,W=()=>{if($!==void 0)return $;let O=a.server.address();return $=`http://127.0.0.1:${O&&typeof O=="object"?O.port:s.daemon.port}`,$},q={agentId:s.defaultAgent,cwd:s.defaultCwd,publicHost:s.daemon.publicHost,host:s.daemon.host,port:s.daemon.port,compaction:s.compaction};Pc(a,C,q,{extensionMcp:J,mcpTokenRegistry:L,getDaemonOrigin:W},c,l),Rc(a,{store:c,localMiss:{resolvesLocally:async O=>await C.resolveCanonicalId(O)!==void 0,cache:l}}),Mc(a,v,C,{npmRegistry:s.npmRegistry}),$c(a,R),Fc(a,T),Oc(a,()=>({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]})),Hc(a,{store:d,rateLimiter:p,staticTokenValidator:h}),Zc(a,{store:c,health:u}),ru(a,{processRegistry:m}),mu(a,L),wu(a,L);let te=ku(a,L,J);fu(a,{validator:f,manager:C,defaultAgent:s.defaultAgent,processRegistry:m,onExtensionVersion:(O,ke)=>R.reportVersion(O,ke),onTransformerVersion:(O,ke)=>T.reportVersion(O,ke),transformers:T,extensionCommands:k,mcpTokenRegistry:L,extensionMcp:J,extensionMcpControls:te,getDaemonOrigin:W,registry:v,foreignSessions:A});let ae=!!s.daemon.tls;await a.listen({host:ae?"127.0.0.1":s.daemon.host,port:ae?0:s.daemon.port});let Z=a.server.address(),ve=Z&&typeof Z=="object"?Z.port:s.daemon.port,Ln,xu=s.daemon.host,Qo=ve;if(ae&&n&&r){Ln=Hy({listenHost:s.daemon.host,listenPort:s.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:ve,tlsOptions:{key:n,cert:r},logger:a.log});let O=Ln.address();O&&typeof O=="object"&&(Qo=O.port)}await Ge.mkdir(x.home(),{recursive:!0}),await Dd({pid:process.pid,host:xu,port:Qo,loopbackPort:ve,startedAt:new Date().toISOString()});let Yo={daemonUrl:`http://127.0.0.1:${ve}`,daemonHost:"127.0.0.1",daemonPort:ve,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${ve}/acp`,hydraHome:x.home()};R.setContext(Yo),T.setContext(Yo),await R.start(),await T.start();try{await C.reconcilePermissionFlags()}catch(O){a.log.warn(`permission flag reconcile failed: ${O.message}`)}try{await C.seedSessionIndex()}catch(O){a.log.warn(`session index seed failed: ${O.message}`)}C.resurrectPendingQueues().catch(O=>{a.log.warn(`queue replay scan failed: ${O.message}`)}),C.resumePendingCompactions().catch(O=>{a.log.warn(`compaction resume scan failed: ${O.message}`)}),C.resumePendingAgentSwaps().catch(O=>{a.log.warn(`agent-swap resume scan failed: ${O.message}`)});let Xo=s.daemon.agentSyncIntervalMinutes*60*1e3,Zo=Xo>0?Ld({registry:v,manager:C,intervalMs:Xo,logger:b}):void 0,ei=s.daemon.sessionGcIntervalMinutes*60*1e3,Eu=s.daemon.sessionGcMaxAgeDays*24*60*60*1e3,ti=ei>0?Hd({manager:C,intervalMs:ei,maxAgeMs:Eu,logger:b}):void 0,Tu=zd({bootConfig:s,apply:O=>{t=O,v.setConfig(O),C.setLiveConfig({sessionDefaults:O.sessionDefaults}),q.agentId=O.defaultAgent,q.cwd=O.defaultCwd,gr(O.daemon.scrubEnv)},onDrift:O=>{M=O},logger:b});return{app:a,manager:C,registry:v,extensions:R,transformers:T,mcpTokenRegistry:L,extensionMcp:J,processRegistry:m,shutdown:async()=>{u.stop(),l.stop(),Tu(),ti&&ti(),Zo&&Zo(),clearInterval(w),clearInterval(y);let O=async(ke,Xt)=>{try{await Xt()}catch(Zt){a.log.warn(`shutdown step ${ke} failed: ${Zt instanceof Error?Zt.message:String(Zt)}`)}};await O("sessionTokenStore.flush",()=>d.flush()),await O("extensions.stop",()=>R.stop()),await O("transformers.stop",()=>T.stop()),await O("manager.closeAll",()=>C.closeAll()),await O("manager.flushSynopsis",()=>C.flushSynopsis(3e4)),await O("manager.shutdownSynopsis",()=>C.shutdownSynopsis()),await O("manager.flushMetaWrites",()=>C.flushMetaWrites()),await O("manager.flushHistoryWrites",()=>C.flushHistoryWrites()),kr(null),Ir(null),Eo(null),Ln&&await O("tlsTerminator.close",()=>new Promise(ke=>Ln.close(()=>ke()))),await O("app.close",()=>a.close());try{Iu.unlinkSync(x.pidFile())}catch{}await O("fileStream.flushSync",()=>i.flushSync())}}}var Su=20;async function jy(s,e){let t=Yt.dirname(s),n=Yt.basename(s,".log"),r=new RegExp(`^${n}\\.(\\d+)\\.log$`),o;try{o=await Ge.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=>Ge.unlink(Yt.join(t,d.name))))}async function Ly(s){await jy(x.logFile(),Su);let e=await Dy({file:x.logFile(),size:"10m",mkdir:!0,symlink:As,limit:{count:Su,removeOtherLogFiles:!0}}),t=bu.destination(2);return{stream:bu.multistream([{stream:e,level:s},{stream:t,level:s}]),fileStream:e}}function Hy(s){let e=Cu.createServer(s.tlsOptions,t=>{let n=Au.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}`)}),e.listen({host:s.listenHost,port:s.listenPort}),e}function Uy(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 By(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:s}=await Promise.resolve().then(()=>(Nn(),Xc));s();let e=await nn(),t=await ri(),n=await Ru(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
194
+ `),await u(C),C.exhausted){try{C.rl.close()}catch{}b.splice(S,1)}}}catch(S){for(let k of b)try{k.rl.close()}catch{}throw S}return p.raw.end(),p}),s.get("/v1/sessions/:id/events",async(l,p)=>{let m=l.params.id,h=l.query,f=await e.resolveCanonicalId(m)??m;if(!e.get(f)&&!await e.hasRecord(f))return p.code(404).send({error:"session not found"}),p;let w=h.kinds;if(!w||w.trim().length===0)return p.code(400).send({error:"kinds parameter is required"}),p;let y=w.split(",").map(A=>A.trim());if(y.length===0)return p.code(400).send({error:"kinds parameter is required"}),p;for(let A of y)if(!Bs.has(A))return p.code(400).send({error:`kind "${A}" is not queryable; allowed kinds: ${[...Bs].join(", ")}`}),p;let v=new Set(y),b;if(h.since!==void 0&&h.since.trim().length>0){let A=new Date(h.since);if(isNaN(A.getTime()))return p.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),p;b=A.getTime()}let S=x.historyFile(f),k=No.createReadStream(S),C=Do.createInterface({input:k,crlfDelay:1/0});p.raw.setHeader("content-type","application/x-ndjson"),p.raw.statusCode=200;try{for await(let A of C){let R=typeof A=="string"?A.trim():"";if(R.length===0)continue;let T;try{T=JSON.parse(R)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",S);continue}if(!T||typeof T!="object"||Array.isArray(T)){console.debug("events endpoint: skipping non-object JSONL line in %s",S);continue}let M=T;if(typeof M.recordedAt!="number"||typeof M.params!="object"||M.params===null||Array.isArray(M.params))continue;let H=M.params;if(typeof H.update!="object"||H.update===null||Array.isArray(H.update))continue;let J=H.update,$=J.sessionUpdate;if(typeof $!="string"||!v.has($)||b!==void 0&&M.recordedAt<b)continue;let W={ts:new Date(M.recordedAt).toISOString(),kind:$,update:J};J.messageId!==void 0&&J.messageId!==null&&(W.messageId=J.messageId),p.raw.write(JSON.stringify(W)+`
195
+ `)}}catch(A){if(A.code==="ENOENT")return p.raw.end(),p;throw A}return p.raw.end(),p}),s.post("/v1/sessions/:id/prompt/:messageId/notify",async(l,p)=>{let m=l.params,h=m.id,f=await e.resolveCanonicalId(h)??h,g=m.messageId,w=l.body,y=typeof w?.callbackUrl=="string"?w.callbackUrl:"",v=typeof w?.secret=="string"?w.secret:"";if(!g||!y||!v){p.code(400).send({error:"messageId, callbackUrl, and secret are all required"});return}let b;try{b=new URL(y)}catch{p.code(400).send({error:"callbackUrl must be a valid absolute URL"});return}if(b.protocol!=="https:"&&b.protocol!=="http:"){p.code(400).send({error:"callbackUrl must be http or https"});return}let S=e.get(f);if(!S){p.code(404).send({error:"session not found or not warm"});return}let k=S.registerTurnNotify(g,y,v);if(k.alreadyTerminal){p.code(200).send({status:"already_terminal",stopReason:k.stopReason});return}p.code(202).send({status:"registered"})}),s.get("/v1/sessions/:id/attention",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,f=e.get(h);return!f&&!await e.hasRecord(h)?(p.code(404).send({error:"session not found"}),p):f?{flags:f.listAttentionFlags()}:{flags:(await e.store.read(h))?.attentionFlags??[]}}),s.get("/v1/sessions/attention",async(l,p)=>{let m=l.query;if(!m.source||m.source.trim().length===0)return p.code(400).send({error:"source query parameter is required"}),p;let h=await e.list({includeNonInteractive:!0}),f=[];for(let g of h){let w=e.get(g.sessionId),y;w?y=w.listAttentionFlags():y=(await e.store.read(g.sessionId))?.attentionFlags??[];for(let v of y)v.source===m.source&&f.push({...v,sessionId:g.sessionId})}return{flags:f}}),s.post("/v1/sessions/:id/attention/clear",async(l,p)=>{let m=l.params.id,h=await e.resolveCanonicalId(m)??m,g=l.body??{},w=typeof g.source=="string"?g.source:"",y=typeof g.reason=="string"?g.reason:"";if((w.length>0||y.length>0)&&!(w.length>0&&y.length>0)){p.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}w.length===0&&y.length;let v=e.get(h);if(v){if(w.length>0&&y.length>0)v.clearAttentionFlag(w,y);else{let A=Array.from(v.listAttentionFlags()).map(R=>`${R.source}::${R.reason}`);for(let R of A)v.clearAttentionFlag(R.split("::")[0],R.split("::").slice(1).join("::"))}p.code(204).send();return}if(!await e.hasRecord(h)){p.code(404).send({error:"session not found"});return}let b=e.store,S=await b.read(h);if(!S){p.code(404).send({error:"session not found"});return}let k=S.attentionFlags??[],C;if(w.length>0&&y.length>0){let A=`${w}::${y}`;C=k.filter(R=>`${R.source}::${R.reason}`!==A)}else C=[];if(C.length===k.length&&C.every((A,R)=>A.source===k[R].source&&A.reason===k[R].reason)){p.code(204).send();return}await b.write({...S,attentionFlags:C}),p.code(204).send()})}function Mc(s,e,t,n={}){s.get("/v1/agents",async()=>Pt(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 Ee(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===E.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}G();function _c(s,e,t,n=()=>[]){s.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t,home:x.home(),driftedKeys:n()}))}var mh=/^[A-Za-z0-9._-]+$/;function qs(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=hh(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){Fn(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){Fn(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){Fn(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){Fn(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){Fn(i,d)}})}function Fn(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 hh(s){let e=s.name;if(typeof e!="string"||!mh.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 $c(s,e){qs(s,"extension",e)}function Fc(s,e){qs(s,"transformer",e)}function Oc(s,e){s.get("/v1/config",async()=>e())}import{z as ct}from"zod";G();import*as Gt from"fs/promises";import*as Nc from"path";import{randomBytes as JI,scrypt as yh,timingSafeEqual as wh}from"crypto";import{promisify as vh}from"util";var kh=vh(yh);function Dc(){return Nc.join(x.home(),"password-hash")}var bh=128*1024*1024;async function jc(){try{return(await Gt.readFile(Dc(),"utf8")).trim().length>0}catch(s){if(s.code==="ENOENT")return!1;throw s}}async function Hc(s){if(typeof s!="string"||s.length===0)return!1;let e;try{e=(await Gt.readFile(Dc(),"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 kh(s,i,a.length,{N:n,r,p:o,maxmem:bh});return d.length!==a.length?!1:wh(d,a)}var Sh=ct.object({password:ct.string().min(1),label:ct.string().min(1).max(256).optional(),ttlSec:ct.number().int().positive().optional()}),Ih=ct.object({id:ct.string().optional()}).optional(),Ah=ct.object({token:ct.string().min(32)});function Lc(s,e){s.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,n)=>{let r=Ch(t);if(e.rateLimiter.isBlocked(r))return n.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=Sh.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}if(!await jc())return n.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await Hc(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=Ih.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=Ah.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 Ch(s){return s.ip||"unknown"}import{z as ut}from"zod";G();Ne();var jo=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,zs=class s{data;constructor(e){this.data=e}static async load(){let e=await ie(x.peers());return new s(Rh(e))}get(e){return this.data.entries[e]}async set(e){this.data.entries[e.name]=e,await Uc(this.data)}async delete(e){return e in this.data.entries?(delete this.data.entries[e],await Uc(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 Rh(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 Uc(s){await le(x.peers(),s,{mode:384})}var xh=3600*24*365,Je=class extends Error{status;constructor(e,t){super(e),this.name="PeerLoginError",this.status=t}};function Bc(s,e){return`${Me(s)?"http":"https"}://${s}:${e}`}async function Wc(s){let e=s.fetchImpl??fetch,t=`${s.host}:${s.port}`,n=Bc(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??xh})})}catch(i){throw new Je(`Could not reach ${t}: ${i.message}`,502)}if(r.status===401)throw new Je(`Wrong password for ${t}.`,401);if(r.status===403)throw new Je(`No password is configured on ${t}. Run \`hydra-acp auth password\` on that daemon first.`,502);if(r.status===429)throw new Je(`Too many failed login attempts on ${t}; try again later.`,429);if(!r.ok)throw new Je(`Login to ${t} failed: HTTP ${r.status}`,502);let o=await r.json();if(!o.session_token||!o.expires_at)throw new Je(`Login to ${t} returned a malformed response.`,502);return{token:o.session_token,expiresAt:o.expires_at}}async function qc(s){let e=s.fetchImpl??fetch,t=Bc(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{}}Nn();var Hh=ut.object({name:ut.string().min(1).max(64).regex(jo),host:ut.string().min(1),port:ut.number().int().positive().optional(),password:ut.string().min(1),label:ut.string().min(1).max(256).optional(),ttlSec:ut.number().int().positive().optional(),pinnedFingerprint:ut.string().min(1).optional()});function Zc(s,e){s.post("/v1/remotes",async(t,n)=>{let r;try{r=Hh.parse(t.body)}catch{return n.code(400).send({error:`Invalid request body (name must match ${jo} and the rest is a normal login request)`})}let o=r.port??Ct;r.pinnedFingerprint&&On(r.host,o,r.pinnedFingerprint);let i;try{i=await Wc({host:r.host,port:o,password:r.password,label:r.label,ttlSec:r.ttlSec})}catch(c){if(c instanceof Je)return n.code(c.status).send({error:c.message});throw c}let a=new Date().toISOString(),d={name:r.name,host:r.host,port:o,token:i.token,expiresAt:i.expiresAt,addedAt:a,...r.label!==void 0?{label:r.label}:{},...r.pinnedFingerprint!==void 0?{pinnedFingerprint:r.pinnedFingerprint,pinnedAt:a}:{}};return await e.store.set(d),e.health?.markOk(d.name),n.code(201).send({name:d.name,host:d.host,port:d.port,expiresAt:d.expiresAt,label:d.label,addedAt:d.addedAt,pinnedFingerprint:d.pinnedFingerprint,status:e.health?.get(d.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}:{}}});return n.code(200).send({remotes:r})}),s.delete("/v1/remotes/:name",async(t,n)=>{let r=t.params.name,o=e.store.get(r);return o?(await qc({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)||Lo(o.host,o.port),n.code(204).send()):n.code(404).send({error:"Not found"})})}function Vs(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:E.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())}}}Nn();import{WebSocket as Lh}from"ws";var Uh=1e4,zo=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 eu(s,e,t=Uh){let n={};try{let r=new URL(s);if(r.protocol==="wss:"){let o=qo(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 Lh(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 zo(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 Bh=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 Wh(s){return Bh.has(s)}function nu(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&&Wh(a.method)){let d=a.params,c=typeof d?.sessionId=="string"?d.sessionId:void 0;if(c){if(ht(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(Dn(a.id,E.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 Gs=class{constructor(e,t=zh,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:it(t[0])}}async handleLocalMessage(e,t,n){let r="id"in e,o=r?e.id:void 0,i=ht(t);if(!i)return r?Dn(o,E.SessionNotFound,`not a federated session id: ${t}`):void 0;let a=tu(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?Dn(o,E.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(g){return r?Dn(o,E.InternalError,`Could not reach remote "${i.name}": ${g.message}`):void 0}let m={peerConnection:p,localId:i.localId,target:n};this.wireAttachment(i.name,m);let h;try{h=await p.request("session/attach",d)}catch(g){return p.close().catch(()=>{}),r?Jo(o,g):void 0}this.attachments.set(a,m);let f=h&&typeof h.sessionId=="string"?{...h,sessionId:t}:h;return r?{jsonrpc:"2.0",id:o,result:f}:void 0}let c=this.attachments.get(a);if(!c)return r?Dn(o,E.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?Jo(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 Jo(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=it({name:e,localId:r}),a=()=>{this.attachments.delete(tu(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:E.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 tu(s,e){return`${s} ${e}`}function Dn(s,e,t){return{jsonrpc:"2.0",id:s,error:{code:e,message:t}}}function Jo(s,e){let t=e,n=typeof t?.code=="number"?t.code:E.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 qh=1e4;async function zh(s){let t=`${Me(s.host)?"ws":"wss"}://${s.host}:${s.port}/acp`,n=await eu(t,["acp.v1",`hydra-acp-token.${s.token}`],qh);return new st(Vs(n))}var Jh=3e4,Vh=5e3,Ks=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??Jh),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}get(e){return this.snapshots.get(e)}markOk(e){this.snapshots.set(e,{status:"ok",checkedAt:new Date().toISOString()})}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 o=`${Me(n.host)?"http":"https"}://${n.host}:${n.port}/v1/auth/verify`,i=new AbortController,a=setTimeout(()=>i.abort(),Vh);try{let d=await e(o,{headers:{Authorization:`Bearer ${n.token}`},signal:i.signal});this.snapshots.set(t.name,{status:d.ok?"ok":"unauthorized",checkedAt:new Date().toISOString()})}catch(d){this.snapshots.set(t.name,{status:"unreachable",checkedAt:new Date().toISOString(),error:d.message})}finally{clearTimeout(a)}}))}};Nn();import{z as su}from"zod";var Gh=su.object({sessionLabel:su.string().min(1).max(256)});function ru(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=Gh.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 Vo}from"nanoid";import{randomBytes as cu}from"crypto";import*as uu from"os";import*as lu from"path";var Kh=200;function Qh(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[de];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,Kh)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function ou(s,e,t){let n=Qh(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 jn=new Map;function iu(s,e){let t=jn.get(s);t||(t=new Set,jn.set(s,t)),t.add(e);let n=!1;return()=>{if(n)return;n=!0;let r=jn.get(s);r&&(r.delete(e),r.size===0&&jn.delete(s))}}function au(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=jn.get(r);if(o){if(o.has(s))return!0;for(let i of o)n.push(i)}}return!1}function N(s,e,t){let n=new Error(e);return n.code=s,t!==void 0&&(n.data=t),n}function ty(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 Re(s,e,t){let n=s.get(e);if(!n)throw N(E.SessionNotFound,t??`session ${e} not found`);return n}async function It(s,e){let t=Vt(s),n,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&s.mcpTokenRegistry!==void 0&&s.getDaemonOrigin!==void 0&&(n=cu(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=Oo({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 ly(c,s),pu(c.sessionId,s),c}function fu(s,e){s.get("/acp",{websocket:!0},async(t,n)=>{let r=Zd({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_${Vo(12)}`,a=Vs(t),d={},c=e.foreignSessions?nu(a,e.foreignSessions,d,i):a,u=new st(c);d.connection=u;let l={clientId:i,processIdentity:o,attached:new Map};u.onClose(()=>{for(let h of l.attached.values())e.manager.get(h.sessionId)?.detach(h.clientId);l.attached.clear(),e.foreignSessions?.detachClient(i)});let p=(h,f)=>{if(l.attached.get(h)?.readonly)throw N(E.PermissionDenied,`${f} not permitted on a read-only attachment`)};if(u.onRequest("initialize",async h=>{let f=Bi.parse(h??{});f.clientInfo?.name&&(l.clientInfo={name:f.clientInfo.name,...f.clientInfo.version!==void 0?{version:f.clientInfo.version}:{}});let g=f.clientInfo?.version;return g&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,g):e.onTransformerVersion?.(o.name,g)),uy()}),o&&e.extensionCommands){let h=e.extensionCommands;u.onRequest("hydra-acp/commands/register",async f=>{let g=f??{},w=Array.isArray(g.commands)?g.commands.map(y=>{if(!y||typeof y!="object")return;let v=y;if(typeof v.verb!="string")return;let b={verb:v.verb};return typeof v.argsHint=="string"&&(b.argsHint=v.argsHint),typeof v.description=="string"&&(b.description=v.description),b}).filter(y=>y!==void 0):[];return h.register(o.name,u,w),{ok:!0,registered:w.length}}),u.onClose(()=>{h.clear(o.name)})}if(o&&e.extensionMcp){let h=e.extensionMcp;u.onRequest("hydra-acp/mcp_tools/register",async g=>{let w=g??{},y=typeof w.instructions=="string"?w.instructions:void 0,v=Array.isArray(w.tools)?w.tools.map(b=>{if(!b||typeof b!="object")return;let S=b;if(typeof S.name!="string"||S.name.length===0||typeof S.description!="string"||S.inputSchema===null||typeof S.inputSchema!="object")return;let k={name:S.name,description:S.description,inputSchema:S.inputSchema};return S.outputSchema!==null&&typeof S.outputSchema=="object"&&(k.outputSchema=S.outputSchema),k}).filter(b=>b!==void 0):[];if(v.length===0)throw new Error("register_mcp_tools requires at least one tool");return h.register(o.name,u,y,v),{ok:!0,registered:v.length}});let f=g=>{let w=g??{};if(typeof w.sessionId!="string"||w.sessionId.length===0)throw N(E.InvalidParams,"sessionId is required");return w.sessionId};if(u.onRequest("hydra-acp/session/extension_state/get",async g=>{let w=f(g),y=g??{};if(typeof y.key!="string"||y.key.length===0)throw N(E.InvalidParams,"key is required");if(!e.manager)throw N(E.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(w,o.name,y.key)??null}}),u.onRequest("hydra-acp/session/extension_state/list",async g=>{let w=f(g);if(!e.manager)throw N(E.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(w,o.name)}}),u.onRequest("hydra-acp/session/extension_state/set",async g=>{let w=f(g),y=g??{};if(typeof y.key!="string"||y.key.length===0)throw N(E.InvalidParams,"key is required");if(y.value===void 0)throw N(E.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw N(E.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(w,o.name,y.key,y.value)}catch(v){throw N(E.InvalidParams,v.message)}return{ok:!0}}),u.onRequest("hydra-acp/session/extension_state/delete",async g=>{let w=f(g),y=g??{};if(typeof y.key!="string"||y.key.length===0)throw N(E.InvalidParams,"key is required");if(!e.manager)throw N(E.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(w,o.name,y.key),{ok:!0}}),e.extensionMcpControls){let g=e.extensionMcpControls;u.onRequest("hydra-acp/mcp_tools/refresh_session",async w=>{let y=w??{};if(typeof y.sessionId!="string"||y.sessionId.length===0)throw N(E.InvalidParams,"refresh_session requires sessionId");return await g.notifyToolListChanged(y.sessionId,o.name),{ok:!0}})}u.onClose(()=>{h.clear(o.name)})}if(o?.kind==="transformer"){u.onRequest("hydra-acp/transformer/initialize",async f=>{let g=f??{},w=Array.isArray(g.intercepts)?g.intercepts.filter(y=>typeof y=="string"):[];if(e.transformers&&(e.transformers.registerConnection(o.name,u,w),e.manager?.defaultTransformers.includes(o.name))){let y=e.transformers.resolveChain([o.name])[0];if(y)for(let v of e.manager.liveSessions())v.addTransformer(y)}return{ack:!0}}),u.onClose(()=>{e.transformers?.deregisterConnection(o.name)}),u.onRequest("hydra-acp/message/emit",async f=>{let g=f??{},w=typeof g.sessionId=="string"?g.sessionId:void 0,y=typeof g.method=="string"?g.method:void 0,v=g.envelope,b=g.route;if(!w)throw N(-32602,"emit_message requires sessionId");if(!y&&b!=="client_broadcast")throw N(-32602,"emit_message requires method");let S=Re(e.manager,w),k=typeof g.respondsTo=="string"?g.respondsTo:void 0;if(k)return S.dischargeClaim(k,v),{ok:!0};if(b==="chain")return{ok:!0,response:await S.emitToChain(o.name,y,v)};if(b==="queue"){if(y!=="session/prompt")throw N(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await S.emitToQueue(o.name,v)}}if(b==="daemon")return{ok:!0,response:await S.emitToChain(o.name,y,v)};if(b==="client_broadcast"){if(!v||typeof v!="object")throw N(-32602,"client_broadcast requires an envelope object");return S.broadcastClientUpdate(v),{ok:!0}}throw N(-32602,`unsupported route: ${JSON.stringify(b)}`)}),u.onRequest("hydra-acp/session/request_permission",async f=>{let g=f??{},w=typeof g.sessionId=="string"?g.sessionId:void 0;if(!w)throw N(-32602,"hydra-acp/session/request_permission requires sessionId");return Re(e.manager,w).requestPermissionFromClients(g)}),u.onRequest("hydra-acp/transformer/attach",async f=>iy(f,o.name,e)),u.onRequest("hydra-acp/child_session/spawn",async f=>{let g=f??{},w=typeof g.agentId=="string"?g.agentId:void 0,y=typeof g.cwd=="string"?g.cwd:void 0,v=typeof g.parentSessionId=="string"?g.parentSessionId:void 0,b=g._meta&&typeof g._meta=="object"?g._meta:void 0,S=b&&b["hydra-acp"]&&typeof b["hydra-acp"]=="object"?b["hydra-acp"]:void 0,k=S&&typeof S.title=="string"?S.title:void 0,C=S&&typeof S.model=="string"?S.model:void 0;if(!y&&v){let W=e.manager.get(v);W&&(y=W.cwd)}if(!y)throw N(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let A=await tn(y),R=w??A.agentId??e.defaultAgent,T=await e.registry?.getAgent(R),M=rn(A.configDefaults,T??{id:R})?.value,H=C??M?.model,J=typeof g.interactive=="boolean"?g.interactive:!1;return{childSessionId:(await e.manager.create({agentId:R,cwd:y,parentSessionId:v,interactive:J,transformChain:[],title:k,model:H,configDefaults:M})).sessionId}}),u.onRequest("hydra-acp/session/fork",async f=>{let g=f??{};if(typeof g.sessionId!="string")throw N(E.InvalidParams,"fork_session requires sessionId");let w=typeof g.forkAt=="string"?g.forkAt:void 0,y=typeof g.cwd=="string"?g.cwd:void 0,v=typeof g.agentId=="string"?g.agentId:void 0,b=typeof g.mode=="string"&&(g.mode==="verbatim"||g.mode==="synthesis")?g.mode:void 0,S=typeof g.model=="string"&&g.model.length>0?g.model:void 0,k=await e.manager.forkSession(g.sessionId,{...w!==void 0?{forkAt:w}:{},...y!==void 0?{cwd:y}:{},...v!==void 0?{agentId:v}:{},...b!==void 0?{mode:b}:{},...S!==void 0?{model:S}:{}}),C=e.manager.get(k.sessionId);if(!C){let T=await e.manager.loadFromDisk(k.sessionId);if(!T)throw N(E.InternalError,`fork ${k.sessionId} vanished before it could be attached`);C=await It(e,{...T,onInstallProgress:Qs(u)})}Kt(l,C,C.sessionId);let A=lt(u,C,l),{entries:R}=await C.attach(A,"full");l.attached.set(C.sessionId,{sessionId:C.sessionId,clientId:A.clientId,readonly:!1});for(let T of R){if(u.isClosed())break;await u.notify(T.method,Ue(Le(T.params,T.recordedAt),T.seq)).catch(()=>{})}return{...k,sessionId:C.sessionId}}),u.onRequest("session/fork",async f=>{let g=f??{};if(typeof g.sessionId!="string")throw N(E.InvalidParams,"session/fork requires sessionId");let w=typeof g.cwd=="string"?g.cwd:void 0,y=await e.manager.forkSession(g.sessionId,{...w!==void 0?{cwd:w}:{},mode:"verbatim"}),v=e.manager.get(y.sessionId);if(!v){let k=await e.manager.loadFromDisk(y.sessionId);if(!k)throw N(E.InternalError,`fork ${y.sessionId} vanished before it could be attached`);v=await It(e,{...k,onInstallProgress:Qs(u)})}Kt(l,v,v.sessionId);let b=lt(u,v,l),{entries:S}=await v.attach(b,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:b.clientId,readonly:!1});for(let k of S){if(u.isClosed())break;await u.notify(k.method,Ue(Le(k.params,k.recordedAt),k.seq)).catch(()=>{})}return{sessionId:v.sessionId}});let h=async(f,g)=>{let w=f??{};if(typeof w.sessionId!="string")throw N(E.InvalidParams,`${g} requires sessionId`);let y=await e.manager.resolveCanonicalId(w.sessionId)??w.sessionId,v=e.manager.get(y);if(v)return await v.close({deleteRecord:!0,by:`session/delete ${l.clientId}`}),await e.manager.waitForDeletion(y),await e.manager.hasRecord(y)&&await e.manager.deleteRecord(y),{id:y,existed:!0};let b=await e.manager.deleteRecord(y);return{id:y,existed:b}};u.onRequest("session/delete",async f=>(await h(f,"session/delete"),{})),u.onRequest("session/close",async f=>{let g=f??{};if(typeof g.sessionId!="string")throw N(E.InvalidParams,"session/close requires sessionId");p(g.sessionId,"session/close");let w=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,y=e.manager.get(w);if(y)return await y.close({deleteRecord:!1,by:`session/close ${l.clientId}`+(l.processIdentity?` (${l.processIdentity.name})`:"")}),{};if(await e.manager.hasRecord(w))return{};throw N(E.SessionNotFound,`session ${w} not found`)}),u.onRequest("hydra-acp/session/delete",async f=>{let{id:g,existed:w}=await h(f,"hydra-acp/session/delete");if(!w)throw N(E.SessionNotFound,`session ${g} not found`);return{deleted:!0,sessionId:g}}),u.onRequest("hydra-acp/child_session/await",async f=>{let g=f??{},w=typeof g.childSessionId=="string"?g.childSessionId:void 0,y=g.until==="idle"?"idle":"turn_complete",v=typeof g.timeoutMs=="number"?Math.min(g.timeoutMs,18e5):3e5;if(!w)throw N(-32602,"await_child requires childSessionId");let b=Re(e.manager,w,`child session ${w} not found`);return new Promise(S=>{let A=[],R=[],T=0,M=!1,H,J,$=!1,W=()=>{$||($=!0,clearTimeout(q),H?.(),J?.(),S(M?{entries:A,truncated:!0}:{entries:A}))};H=b.onBroadcast(te=>{let ae=ty(te);for(A.push(te),R.push(ae),T+=ae;A.length>0&&(A.length>1e3||T>1048576);)A.shift(),T-=R.shift()??0,M=!0;y==="turn_complete"&&te.params?.update?.sessionUpdate==="turn_complete"&&W()});let q=setTimeout(W,v);typeof q.unref=="function"&&q.unref(),J=b.onClose(()=>W())})}),u.onRequest("hydra-acp/child_session/close",async f=>{let g=f??{},w=typeof g.childSessionId=="string"?g.childSessionId:void 0;if(!w)throw N(-32602,"close_child_session requires childSessionId");let y=e.manager.get(w);return y&&await y.close({deleteRecord:!1,by:`child_session/close ${l.clientId}`}),{ok:!0}}),u.onRequest("hydra-acp/attention/set",async f=>ay(f,o.name,e)),u.onRequest("hydra-acp/attention/clear",async f=>dy(f,o.name,e)),u.onRequest("hydra-acp/connection/keep_alive",async f=>{let g=f??{},w=typeof g.token=="string"?g.token:void 0,y=typeof g.sessionId=="string"?g.sessionId:void 0,v=typeof g.estimatedRemainingMs=="number"?g.estimatedRemainingMs:void 0;return w&&y&&e.manager.get(y)?.keepAliveClaim(w,v),{ok:!0}})}u.onRequest("hydra-acp/session/tool_content",async h=>{let f=h??{};if(typeof f.sessionId!="string"||typeof f.hash!="string")throw N(E.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let g=await e.manager.resolveCanonicalId(f.sessionId)??f.sessionId,w=await e.manager.loadToolBlob(g,f.hash);if(w===null)throw N(E.SessionNotFound,"tool content not found");return{content:w}}),u.onRequest("authenticate",async h=>ny(h,e)),u.onRequest("logout",async h=>sy(h,e)),u.onRequest("session/new",async h=>{let f=Wi.parse(h),g=pt(h?._meta),w=Array.isArray(g.transformers)&&g.transformers.every(Z=>typeof Z=="string")?g.transformers:e.manager.defaultTransformers??[],y=e.transformers?.resolveChain(w)??[],v=await tn(f.cwd),b=g.agentId??v.agentId??e.defaultAgent,S=await e.registry?.getAgent(b),k=rn(v.configDefaults,S??{id:b})?.value,C,A,R=f.mcpServers;if(g.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){C=cu(32).toString("hex"),A=e.mcpTokenRegistry.reserve(C);let ve={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${C}`}]};R=[...f.mcpServers??[],ve]}let T,M,H=Vt(e);H!==void 0&&(R=[...R??[],...H.descriptors]);let J=Oo({baselineMcpServers:f.mcpServers,stdinEnabled:g.mcpStdin===!0,deps:e}),$;try{$=await e.manager.create({cwd:f.cwd,agentId:b,mcpServers:R,title:g.title,agentArgs:g.agentArgs,model:g.model??k?.model,configDefaults:k,onInstallProgress:Qs(u),transformChain:y,originatingClient:l.clientInfo,...g.interactive!==void 0?{interactive:g.interactive}:{},...g.env!==void 0?{forwardedEnv:g.env}:{},...g.workspace!==void 0?{workspace:g.workspace}:{},...J?{mintMcpServersForSwap:J}:{}})}catch(Z){throw A!==void 0&&A.abandon(Z instanceof Error?Z:void 0),M!==void 0&&M.abandon(Z instanceof Error?Z:void 0),H!==void 0&&H.abandon(Z instanceof Error?Z:void 0),Z}if(C!==void 0&&A!==void 0&&e.mcpTokenRegistry!==void 0){let Z=C,ve=e.mcpTokenRegistry;A.complete($),$.onClose(()=>{ve.unbind(Z)})}if(T!==void 0&&M!==void 0&&e.mcpTokenRegistry!==void 0){let Z=T,ve=e.mcpTokenRegistry;M.complete($),$.onClose(()=>{ve.unbind(Z)})}H!==void 0&&H.bindToSession($),pu($.sessionId,e);let W,q;try{Kt(l,$,$.sessionId),W=lt(u,$,l),{entries:q}=await $.attach(W,"full")}catch(Z){throw await $.close({deleteRecord:!1,by:"session/new attach-failed"}).catch(()=>{}),Z}l.attached.set($.sessionId,{sessionId:$.sessionId,clientId:W.clientId,readonly:!1}),setImmediate(()=>{(async()=>{for(let Z of q){if(u.isClosed())break;await u.notify(Z.method,Ue(Le(Z.params,Z.recordedAt),Z.seq)).catch(()=>{})}})()});let te=Ys($),ae=Xs($);return{sessionId:$.sessionId,...te?{modes:te}:{},...ae?{models:ae}:{},configOptions:$.buildConfigOptions(),_meta:Zs(e.manager,$,{clientId:W.clientId})}}),u.onRequest("session/attach",async h=>{let f=zi.parse(h),g=f.clientInfo?.version;g&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,g):e.onTransformerVersion?.(o.name,g));let w=pt(f._meta),y=w.resume,v=w.readonly===!0,b=w.env;s.log.info(`session/attach sessionId=${f.sessionId} hasResumeHints=${!!y} readonly=${v}`);let S=y?f.sessionId:await e.manager.resolveCanonicalId(f.sessionId)??f.sessionId,k=e.manager.get(S);if(!k&&v){let $=await e.manager.loadFromDisk(S);if(!$)throw N(E.SessionNotFound,`session ${f.sessionId} not found`);let W=await e.manager.loadHistory(S),q=f.clientId??`cli_${Vo(8)}`;l.attached.set($.hydraSessionId,{sessionId:$.hydraSessionId,clientId:q,readonly:!0}),s.log.info(`session/attach OK (viewer) sessionId=${$.hydraSessionId} clientId=${q} attachedCount=${l.attached.size} replayed=${W.length}`);for(let te of W)await u.notify(te.method,Ue(Le(te.params,te.recordedAt),te.seq)).catch(()=>{});return{sessionId:$.hydraSessionId,clientId:q,connectedClients:[q],historyPolicy:"full",replayed:W.length,_meta:cy($)}}let C=!k;if(!k){let $=await e.manager.loadFromDisk(S),W=await ry(S,y,$?.upstreamSessionId,e.manager);W.kind==="ignore"&&s.log.warn(W.logMessage);let q=$;if(y&&W.kind==="honor"&&(q={...$,hydraSessionId:f.sessionId,upstreamSessionId:y.upstreamSessionId,agentId:y.agentId,cwd:$?.workspace?.path??y.cwd,...y.title!==void 0?{title:y.title}:{},...y.agentArgs!==void 0?{agentArgs:y.agentArgs}:{}}),!q)throw N(E.SessionNotFound,`session ${f.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(q.agentId,q.upstreamSessionId))throw N(E.SessionNotFound,`session ${f.sessionId} was deleted`);let te=q.originatingClient?q:{...q,originatingClient:l.clientInfo},ae=b!==void 0?{...te,forwardedEnv:b}:te;k=await It(e,{...ae,onInstallProgress:Qs(u)})}Kt(l,k,k.sessionId);let A=lt(u,k,l,f.clientInfo,f.clientId),R=w.replayMode==="drip",{entries:T,appliedPolicy:M}=await k.attach(A,f.historyPolicy,{afterMessageId:f.afterMessageId,afterSeq:f.afterSeq,raw:R,...w.historyLimit!==void 0?{historyLimit:w.historyLimit}:{},...w.toolContent!==void 0?{toolContent:w.toolContent}:{}});if(l.attached.set(k.sessionId,{sessionId:k.sessionId,clientId:A.clientId,readonly:v}),b!==void 0&&await e.manager.setForwardedEnv(k.sessionId,b).catch(()=>{}),s.log.info(`session/attach OK sessionId=${k.sessionId} clientId=${A.clientId} attachedCount=${l.attached.size} requestedPolicy=${f.historyPolicy} appliedPolicy=${M} replayed=${T.length} readonly=${v}${R?" replayMode=drip":""}`),R){let $=w.dripSpeed&&w.dripSpeed>0?w.dripSpeed:1,W=750;(async()=>{let q=null;for(let te of T){let ae=typeof te.recordedAt=="number"?te.recordedAt:null;if(q!==null&&ae!==null){let Z=Math.min(W,Math.max(0,(ae-q)/$));Z>0&&await new Promise(ve=>setTimeout(ve,Z))}ae!==null&&(q=ae);try{await u.notify(te.method,Ue(Le(te.params,ae??void 0),te.seq))}catch{return}}})()}else for(let $=0;$<T.length&&!u.isClosed();$++){let W=T[$],q=u.notify(W.method,Ue(Le(W.params,W.recordedAt),W.seq)).catch(()=>{});($+1)%200===0&&await q}k.replayPendingPermissions(A);let H=Ys(k),J=Xs(k);return{sessionId:k.sessionId,clientId:A.clientId,connectedClients:k.connectedClients(A.clientId),historyPolicy:M,replayed:T.length,...H?{modes:H}:{},...J?{models:J}:{},configOptions:k.buildConfigOptions(),_meta:Zs(e.manager,k,{resurrected:C})}}),u.onRequest("session/detach",async h=>{let f=Ji.parse(h),g=l.attached.get(f.sessionId);if(!g)throw N(E.SessionNotFound,"client not attached to that session");let w=e.manager.get(f.sessionId);return w?.detach(g.clientId),l.attached.delete(f.sessionId),w&&e.manager.reapIfOrphanedNonInteractive(f.sessionId),{sessionId:f.sessionId,_meta:{[de]:{detachStatus:"detached"}}}}),u.onRequest("session/list",async h=>{let f=Vi.parse(h??{});return{sessions:(await e.manager.list({cwd:f.cwd})).filter(v=>v.originatingClient?.name!==hs).map(Gi)}}),u.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw N(E.InternalError,"agent registry unavailable");return Pt(e.registry)}),u.onRequest("hydra-acp/agents/auth_methods",async h=>{let f=h??{};if(typeof f.agentId!="string"||f.agentId.length===0)throw N(E.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(f.agentId)).authMethods??[]}}),u.onRequest("session/prompt",async h=>{let f=Ki.parse(h);p(f.sessionId,"session/prompt");let g=await ou(f,e.manager,b=>{s.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${b} sessionId=${f.sessionId}`)});if(g?.fromSession!==void 0){if((g.depth??0)>3)throw s.log.warn(`session/prompt: refusing depth ${g.depth} chain from ${g.fromSession} to ${f.sessionId}`),N(E.InvalidRequest,`message chain too deep (${g.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(g.awaiting===!0&&au(g.fromSession,f.sessionId))throw s.log.warn(`session/prompt: refusing deadlock ${g.fromSession} -> ${f.sessionId}`),N(E.InvalidRequest,`would deadlock: ${f.sessionId} is already blocked waiting on ${g.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let w=l.attached.get(f.sessionId);if(!w)throw s.log.warn(`session/prompt rejected: not attached sessionId=${f.sessionId} attachedKeys=[${[...l.attached.keys()].join(",")}]`),N(E.SessionNotFound,"not attached to session");let y=e.manager.get(f.sessionId);if(!y){let b=await e.manager.loadFromDisk(f.sessionId);if(!b)throw N(E.SessionNotFound,`session ${f.sessionId} not found`);s.log.info(`session/prompt auto-resurrecting cold sessionId=${f.sessionId}`),y=await It(e,b);let S=lt(u,y,l,void 0,w.clientId);await y.attach(S,"none")}let v=g?.awaiting===!0&&g.fromSession!==void 0?iu(g.fromSession,f.sessionId):void 0;try{return await y.prompt(w.clientId,f,g)}finally{v?.()}});let m=h=>{let f;try{f=Gn.parse(h)}catch(y){s.log.warn(`session/cancel: invalid params: ${y.message}`);return}let g=l.attached.get(f.sessionId);if(!g)return;if(g.readonly){s.log.warn(`session/cancel dropped (readonly attachment) sessionId=${f.sessionId}`);return}let w=e.manager.get(f.sessionId);w&&w.cancel(g.clientId).catch(y=>{s.log.warn(`session/cancel for ${f.sessionId}: ${y.message}`)})};u.onNotification("session/cancel",m),u.onRequest("session/cancel",async h=>{let f=Gn.parse(h);return p(f.sessionId,"session/cancel"),m(h),null}),u.onRequest("hydra-acp/prompt/cancel",async h=>{let f=Yi.parse(h);return p(f.sessionId,"hydra-acp/prompt/cancel"),Re(e.manager,f.sessionId).cancelQueuedPrompt(f.messageId)}),u.onRequest("hydra-acp/session/force_cancel",async h=>{let f=Gn.parse(h);return p(f.sessionId,"hydra-acp/session/force_cancel"),Re(e.manager,f.sessionId).forceCancel()}),u.onRequest("hydra-acp/prompt/update",async h=>{let f=Xi.parse(h);return p(f.sessionId,"hydra-acp/prompt/update"),Re(e.manager,f.sessionId).updateQueuedPrompt(f.messageId,f.prompt)}),u.onRequest("hydra-acp/prompt/amend",async h=>{let f=Zi.parse(h);p(f.sessionId,"hydra-acp/prompt/amend");let g=l.attached.get(f.sessionId);if(!g)throw N(E.SessionNotFound,"not attached to session");return Re(e.manager,f.sessionId).amendPrompt(g.clientId,f)}),u.onRequest("_session/steering",async h=>{let f=ea.parse(h);p(f.sessionId,"_session/steering");let g=l.attached.get(f.sessionId);if(!g)throw N(E.SessionNotFound,"not attached to session");let w=e.manager.get(f.sessionId);if(!w){let y=await e.manager.loadFromDisk(f.sessionId);if(!y)throw N(E.SessionNotFound,`session ${f.sessionId} not found`);w=await It(e,y);let v=lt(u,w,l,void 0,g.clientId);await w.attach(v,"none")}return w.steer(g.clientId,f)}),u.onRequest("session/resume",async h=>{let f=h??{},g=typeof f.sessionId=="string"?f.sessionId:void 0;if(!g)throw N(E.InvalidParams,"session/resume requires sessionId");let w=await e.manager.resolveCanonicalId(g)??g,y=e.manager.get(w);if(!y){let k=await e.manager.loadFromDisk(w);if(!k)throw N(E.SessionNotFound,`session ${g} not found in memory or on disk`);y=await It(e,k)}Kt(l,y,y.sessionId);let v=lt(u,y,l);await y.attach(v,"pending_only"),l.attached.set(y.sessionId,{sessionId:y.sessionId,clientId:v.clientId,readonly:!1}),y.replayPendingPermissions(v);let b=Ys(y),S=Xs(y);return{sessionId:y.sessionId,...b?{modes:b}:{},...S?{models:S}:{},configOptions:y.buildConfigOptions(),_meta:Zs(e.manager,y,{clientId:v.clientId})}}),u.onRequest("session/load",async h=>{let f=h??{},g=typeof f.sessionId=="string"?f.sessionId:void 0;if(!g)throw N(E.InvalidParams,"session/load requires sessionId");let w=await e.manager.resolveCanonicalId(g)??g,y=e.manager.get(w);if(!y){let C=await e.manager.loadFromDisk(w);if(!C)throw N(E.SessionNotFound,`session ${g} not found in memory or on disk`);y=await It(e,C)}Kt(l,y,y.sessionId);let v=lt(u,y,l),{entries:b}=await y.attach(v,"full");l.attached.set(y.sessionId,{sessionId:y.sessionId,clientId:v.clientId,readonly:!1});for(let C of b){if(u.isClosed())break;await u.notify(C.method,Ue(Le(C.params,C.recordedAt),C.seq)).catch(()=>{})}y.replayPendingPermissions(v);let S=Ys(y),k=Xs(y);return{sessionId:y.sessionId,...S?{modes:S}:{},...k?{models:k}:{},configOptions:y.buildConfigOptions(),_meta:Zs(e.manager,y,{clientId:v.clientId})}}),u.onRequest("session/set_model",async h=>{let f=h?.sessionId;typeof f=="string"&&p(f,"session/set_model");let g=oy(h,e.manager);if(g.kind==="error")throw s.log.warn(g.logMessage),N(g.code,g.message);if(g.kind==="no_op")return s.log.warn(g.logMessage),await u.notify("session/update",{sessionId:g.sessionId,update:{sessionUpdate:"_hydra_current_model_update",currentModel:g.currentModel}}).catch(()=>{}),null;s.log.info(g.logMessage);let{modelId:w}=g,y=await g.session.forwardModelChange(w,h);return g.session.applyAgentConfigOptionResponse(y,"model"),g.session.applyModelChange(w),y}),u.onRequest("session/set_mode",async h=>{let f=h,g=f?.sessionId;if(typeof g=="string"&&p(g,"session/set_mode"),!f||typeof f.sessionId!="string")throw N(E.InvalidParams,"session/set_mode requires string sessionId");if(typeof f.modeId!="string")throw N(E.InvalidParams,"session/set_mode requires string modeId");let w=Re(e.manager,f.sessionId),y=await w.forwardRequest("session/set_mode",h);return w.applyModeChange(f.modeId),y}),u.onRequest("session/set_config_option",async h=>{let f=h,g=b=>N(E.InvalidParams,b),w=f?.sessionId;if(typeof w=="string"&&p(w,"session/set_config_option"),!f||typeof f.sessionId!="string")throw g("session/set_config_option requires string sessionId");if(typeof f.configId!="string")throw g("session/set_config_option requires string configId");if(typeof f.value!="string")throw g("session/set_config_option requires string value");let y=Re(e.manager,f.sessionId),v=y.buildConfigOptions().find(b=>b.id===f.configId);if(!v)throw g(`unknown configId ${JSON.stringify(f.configId)} for this session`);if(!v.options.some(b=>b.value===f.value))throw g(`value ${JSON.stringify(f.value)} is not valid for configId ${JSON.stringify(f.configId)}`);switch(f.configId){case"model":{if(f.value!==y.currentModel){let b=await y.forwardModelChange(f.value);y.applyAgentConfigOptionResponse(b,"model")}y.applyModelChange(f.value);break}case"mode":{f.value!==y.currentMode&&await y.forwardRequest("session/set_mode",{sessionId:f.sessionId,modeId:f.value}),y.applyModeChange(f.value);break}case"agent":{f.value!==y.agentId&&await y.setAgent(f.value);break}default:{let b=await y.forwardRequest("session/set_config_option",{sessionId:f.sessionId,configId:f.configId,value:f.value});y.applyAgentConfigOptionResponse(b,f.configId)&&y.broadcastConfigOptions()}}return{configOptions:y.buildConfigOptions()}}),u.setDefaultHandler(async(h,f)=>{let g=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),w=f.startsWith("session/"),y=f.startsWith("hydra-acp/");if(!w&&!y||h===null||typeof h!="object"||g.has(f))throw N(E.MethodNotFound,`Method not found: ${f}`);let v=h.sessionId;if(typeof v!="string")throw N(E.MethodNotFound,`Method not found: ${f}`);return p(v,f),Re(e.manager,v).forwardRequest(f,h)})})}async function ny(s,e){let t=s??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw N(E.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 m=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(m)}let d=a.authMethods??[],c=d.find(m=>m.id===n);if(!c){let m=d.map(h=>h.id);throw N(E.InvalidParams,`authenticate: methodId ${JSON.stringify(n)} is not advertised by agent ${a.agentId}; valid: [${m.map(h=>JSON.stringify(h)).join(", ")}]`)}let u=c._meta?.type,l=(()=>{let m=c._meta?.["terminal-auth"];if(m&&typeof m=="object"&&!Array.isArray(m))return m})();if((c.type??(u==="agent"||u==="terminal"?u:l!==void 0?"terminal":"agent"))==="terminal"){let m=(v,b)=>{if(!Array.isArray(v))throw N(E.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${b} must be a string[]; got ${v===null?"null":typeof v}`);for(let S of v)if(typeof S!="string")throw N(E.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${b} must be string[]; got non-string entry ${JSON.stringify(S)}`);return v},h=await e.manager.planSpawnForAgent(a.agentId),f,g;if(l?.args!==void 0){let v=typeof l.command=="string"?l.command:void 0;f=v!==void 0&&lu.isAbsolute(v)?v:h.command,g=m(l.args,'_meta["terminal-auth"].args')}else{let v=c.args!==void 0?{raw:c.args,label:"args"}:c._meta?.args!==void 0?{raw:c._meta.args,label:"_meta.args"}:void 0,b=v!==void 0?m(v.raw,v.label):[];f=h.command,g=[...h.args,...b]}let w={};for(let[v,b]of Object.entries(process.env))typeof b=="string"&&(w[v]=b);Object.assign(w,h.env);let y=uu.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${n}`),{kind:"terminal",command:f,args:g,env:w,cwd:y}}try{return await a.connection.request("authenticate",{methodId:n})}catch(m){throw dt(m,a)}}async function sy(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 Qs(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(ta,t).catch(()=>{})}}function Ys(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 Xs(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 ry(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 oy(s,e){if(!s||typeof s!="object")return{kind:"error",code:E.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:E.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:E.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:E.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=n.availableModels(),o=Ot(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:E.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 iy(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0;if(!r)throw N(E.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw N(E.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw N(E.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return Re(t.manager,r).addTransformer(o),{ok:!0}}async function ay(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 N(E.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw N(E.InvalidParams,"hydra-acp/attention/set requires string reason");return Re(t.manager,r).setAttentionFlag(e,o,n.payload),{ok:!0}}async function dy(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 N(E.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw N(E.InvalidParams,"hydra-acp/attention/clear requires string reason");return Re(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function cy(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:Sn(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{[de]:Vn(e,t)}}function Zs(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 on(e.agentMeta,Vn(n,r))}function uy(){return{protocolVersion:1,agentInfo:{name:"hydra",version:ge},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:{...on(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}}}),steering:{supported:!0}}}}function ly(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 pu(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 lt(s,e,t,n,r){return{clientId:r??`cli_${Vo(8)}`,connection:s,clientInfo:n}}function Kt(s,e,t){let n=s.attached.get(t);n&&(e.detach(n.clientId),s.attached.delete(t))}var er=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 fy}from"crypto";import{McpServer as py}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as gy}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as me}from"zod";function Go(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 Se(s){return{content:[{type:"text",text:JSON.stringify(s)}],structuredContent:s}}var gu="Bearer ";function Qt(s){let e=s.headers.authorization;if(typeof e!="string"||!e.startsWith(gu))return;let t=e.slice(gu.length).trim();return t.length>0?t:void 0}function my(s){let e=new py({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:me.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let n=s.streamTail(t);return Se(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:me.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let n=s.streamHead(t);return Se(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:me.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:me.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:me.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 Se(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:me.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:me.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 Se({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:me.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:me.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:me.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:me.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:me.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:me.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:me.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:me.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:me.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 Se(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 Se(t)}),e}var hy=1e4;function mu(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=my(a),u=new gy({sessionIdGenerator:()=>fy()});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=Qt(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,m=new Promise(f=>{p=setTimeout(()=>f(void 0),hy)}),h=await Promise.race([c.sessionReady.catch(()=>{}),m]);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 yy}from"crypto";import{McpServer as wy}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as vy}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as Ve}from"zod";function ky(s){switch(s){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}var hu=2e3,yu=2e4;function by(s,e,t){if(e!=="tool_call"&&e!=="tool_call_update")return Nt([s]);let n=[],r=cn(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=Xn(t);return i!==void 0&&n.push(i),n.join(`
196
+ `)}function Sy(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 Iy(s){let e=new wy({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:Ve.string().min(1).describe("Case-insensitive substring to search for."),limit:Ve.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:Ve.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 Se({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=Go(u);if(!l)continue;let{kind:p,update:m}=l;if((p==="tool_call"||p==="tool_call_update")&&!r)continue;let h=by(u,p,m),f=h.toLowerCase().indexOf(a);if(f<0)continue;let g=ky(p),w=Sy(h,f),y=typeof u.recordedAt=="number"?String(u.recordedAt):void 0;if(i.push({entryId:c,speaker:g,snippet:w,timestamp:y}),i.length>=n)break}i.sort((c,u)=>c.entryId-u.entryId);let d=i.length>=n;return Se({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:Ve.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:Ve.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 Se({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 Se({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=Nt(u,{toolOutput:{maxPerCall:hu,maxTotal:yu}});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:Ve.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:Ve.string().optional().describe("ACP tool kind: execute (shell), read, edit, think, other. Agent-independent, unlike tool_name."),file_path:Ve.string().optional(),limit:Ve.number().int().min(1).max(100).optional(),include_output:Ve.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 Se({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:v}of a.iterRecallNewestFirst()){let b=Go(v);if(!b)continue;let{kind:S,update:k}=b;if(S!=="tool_call"&&S!=="tool_call_update")continue;let C=typeof k.toolCallId=="string"&&k.toolCallId.length>0?k.toolCallId:`__noid_${y}`,A=l.get(C);if(A||(A={entryId:y,toolName:"(unnamed)",nameAuthoritative:!1,rawInput:{},locations:[],status:"in_progress"},l.set(C,A)),y<A.entryId&&(A.entryId=y),!A.nameAuthoritative){let T=cn(k);T!==void 0?(A.toolName=T,A.nameAuthoritative=!0):typeof k.name=="string"&&k.name.length>0?(A.toolName=k.name,A.nameAuthoritative=!0):S==="tool_call"&&typeof k.title=="string"&&k.title.length>0&&(A.toolName=k.title,A.nameAuthoritative=!0)}if(A.kind===void 0&&typeof k.kind=="string"&&k.kind.length>0&&(A.kind=k.kind),A.output===void 0){let T=Xn(k);T!==void 0&&(A.output=T)}let R=k.rawInput;if(R&&typeof R=="object"&&!Array.isArray(R)&&Object.keys(R).length>0)for(let[T,M]of Object.entries(R))A.rawInput[T]===void 0&&(A.rawInput[T]=M);if(Array.isArray(k.locations))for(let T of k.locations){let M=T?.path;typeof M=="string"&&M.length>0&&!A.locations.includes(M)&&A.locations.push(M)}if(typeof k.status=="string"&&A.status==="in_progress"&&(A.status=k.status),v.recordedAt!==void 0&&A.timestamp===void 0&&(A.timestamp=String(v.recordedAt)),l.size>=p)break}let m=[...l.keys()].sort((y,v)=>l.get(y).entryId-l.get(v).entryId),h=[],f=yu,g=!1;for(let y of m){let v=l.get(y);if(v.toolName=Or({name:v.toolName,rawInput:v.rawInput,...v.kind!==void 0?{kind:v.kind}:{}}),d&&!v.toolName.toLowerCase().includes(t.toLowerCase())||c&&(v.kind??"").toLowerCase()!==n.toLowerCase())continue;if(u){let k=r.toLowerCase(),C=["file_path","filePath","path"],A=!1;for(let R of C){let T=v.rawInput[R];if(typeof T=="string"&&T.toLowerCase().includes(k)){A=!0;break}}if(!A){for(let R of v.locations)if(R.toLowerCase().includes(k)){A=!0;break}}if(!A)continue}let b={};for(let[k,C]of Object.entries(v.rawInput))typeof C=="string"?b[k]=C.length>500?C.slice(0,497)+"\u2026":C:(typeof C=="number"||typeof C=="boolean")&&(b[k]=C);v.locations.length>0&&b.locations===void 0&&(b.locations=v.locations);let S={entryId:v.entryId,tool:v.toolName,args:b,status:v.status,timestamp:v.timestamp};if(v.kind!==void 0&&(S.kind=v.kind),i&&v.output!==void 0){let k=v.output,C=Math.min(hu,f);if(C<=0)g=!0;else{let A=k.length<=C?k:k.slice(0,C-1)+"\u2026";S.output=A,S.outputBytes=k.length,S.outputTruncated=A.length<k.length,f-=A.length}}if(h.push(S),h.length>=o)break}let w=h.length>=o;return Se({calls:h,truncated:w,...g?{outputBudgetExhausted:g}:{}})}),e}var Ay=1e4;function wu(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=Iy(a),u=new vy({sessionIdGenerator:()=>yy()});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=Qt(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,m=new Promise(f=>{p=setTimeout(()=>f(void 0),Ay)}),h=await Promise.race([c.sessionReady.catch(()=>{}),m]);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 tr=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 _y}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as $y}from"crypto";import{Server as Cy}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as Ry,ListToolsRequestSchema as xy}from"@modelcontextprotocol/sdk/types.js";function vu(s,e,t,n){let r=typeof t=="function"?async()=>t():async()=>t,o=new Cy({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(xy,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(Ry,async(a,d)=>{let c=a.params.name,u=d._meta?.progressToken??d.requestId,l=Ty(u,d.sendNotification);try{let p=await r(),m=await Py(e.connection,s,c,a.params.arguments??{},p);return My(m,c)}catch(p){return Ko(p instanceof Error?p.message:String(p))}finally{l()}}),o}var Ey=15e3;function Ty(s,e,t=Ey){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 Py(s,e,t,n,r){return await s.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:n,sessionId:r})}function My(s,e){if(s===null||typeof s!="object")return Ko(`extension ${e} returned non-object`);let t=s;return Array.isArray(t.content)?t:Ko(`extension ${e} omitted content array`)}function Ko(s){return{content:[{type:"text",text:s}],isError:!0}}var Fy=1e4;function ku(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,m]of n){if(e.lookup(p)?.session?.sessionId!==u)continue;let f=m.get(l);if(f!==void 0)try{await f.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 b=n.get(u);if(b!==void 0){n.delete(u);for(let S of b.values())await r(S)}}));let m=p.get(l);if(m!==void 0)return m.transport;let h=t.lookup(l);if(h===void 0)return;let y=vu(l,h,async()=>{let b=e.lookup(u);if(b===void 0)throw new Error("mcp token no longer bound");if(b.session!==void 0)return b.session.sessionId;let S,k=new Promise(A=>{S=setTimeout(()=>A(void 0),Fy)}),C=await Promise.race([b.sessionReady.catch(()=>{}),k]);if(S!==void 0&&clearTimeout(S),C===void 0)throw new Error("session not ready");return C.sessionId},{peekSessionId:()=>e.lookup(u)?.session?.sessionId,fetchSessionTools:async b=>{let S=await h.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:b});if(!S||typeof S!="object")return;let k=S.tools;if(!Array.isArray(k))return;let C=[];for(let A of k){if(!A||typeof A!="object")continue;let R=A;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),C.push(T)}return C}}),v=new _y({sessionIdGenerator:()=>$y()});return await y.connect(v),p.set(l,{server:y,transport:v}),v}async function d(u,l){let p=Qt(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,f=await a(p,h);if(f===void 0){l.code(404).send({error:`unknown mcp server: ${h}`});return}l.hijack(),await f.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 Ru(s,e){Uy(s),gr(s.daemon.scrubEnv);let t=s,n=s.daemon.tls?await Ge.readFile(fe(s.daemon.tls.key)):void 0,r=s.daemon.tls?await Ge.readFile(fe(s.daemon.tls.cert)):void 0;await Ge.mkdir(x.home(),{recursive:!0});let{stream:o,fileStream:i}=await Hy(s.daemon.logLevel),a=Oy({logger:{level:s.daemon.logLevel,stream:o},bodyLimit:256*1024*1024});await a.register(Ny,{options:{handleProtocols:hi}}),kr(O=>{a.log.info(O)}),Ir(O=>{a.log.info(O)});let d=await Ms.load(),c=await zs.load();Wo(),Uo(c);let u=new Ks(c);u.start();let l=new Us(c);l.start();let p=new Ns,m=new Os,h=new _s(e),f=new Fs([h,new $s(d),m]),g=Xd({validator:f});a.addHook("onRequest",async(O,ke)=>{O.routeOptions.config?.skipAuth||O.url==="/acp"||O.url?.startsWith("/acp?")||(await g(O,ke),!ke.sent&&O.authIdentity?.startsWith("script:")&&!ec(O.method,O.routeOptions.url)&&ke.code(403).send({error:"script tokens may only access read-only session data"}))});let w=setInterval(()=>{d.sweepExpired()},300*1e3);w.unref();let y=setInterval(()=>{p.sweepExpired()},300*1e3);y.unref();let v=new zn(s,{onFetched:()=>{jd(v,C)},onStaleFallback:(O,ke)=>{let Xt=Math.round(ke/36e5),Zt=Xt>=48?`${Math.round(Xt/24)}d`:`${Xt}h`;a.log.warn(`registry fetch failed (${O.message}); serving stale cache last synced ${Zt} ago; agent versions may be outdated ('hydra registry refresh' to retry)`)}});Eo(O=>a.log.info(O));let b={info:O=>a.log.info(O),warn:O=>a.log.warn(O)},S=O=>rt.spawn({...O,stderrTailBytes:s.daemon.agentStderrTailBytes,logger:b});Si(s.compressToolContent);let k=new Ts,C=new bs(v,S,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:b,npmRegistry:s.npmRegistry,extensionCommands:k,defaultCwd:s.defaultCwd,disableWorkspaceSnapshots:s.disableWorkspaceSnapshots}),A=new Gs(c,void 0,{resolvesLocally:async O=>await C.resolveCanonicalId(O)!==void 0,cache:l}),R=new xs(li(s),void 0,{tokenRegistry:m}),T=new Es(fi(s),void 0,{tokenRegistry:m}),M=[];_c(a,ge,Ud(s),()=>M);let H=new er,J=new tr,$,W=()=>{if($!==void 0)return $;let O=a.server.address();return $=`http://127.0.0.1:${O&&typeof O=="object"?O.port:s.daemon.port}`,$},q={agentId:s.defaultAgent,cwd:s.defaultCwd,publicHost:s.daemon.publicHost,host:s.daemon.host,port:s.daemon.port,compaction:s.compaction};Pc(a,C,q,{extensionMcp:J,mcpTokenRegistry:H,getDaemonOrigin:W},c,l),Rc(a,{store:c,localMiss:{resolvesLocally:async O=>await C.resolveCanonicalId(O)!==void 0,cache:l}}),Mc(a,v,C,{npmRegistry:s.npmRegistry}),$c(a,R),Fc(a,T),Oc(a,()=>({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]})),Lc(a,{store:d,rateLimiter:p,staticTokenValidator:h}),Zc(a,{store:c,health:u}),ru(a,{processRegistry:m}),mu(a,H),wu(a,H);let te=ku(a,H,J);fu(a,{validator:f,manager:C,defaultAgent:s.defaultAgent,processRegistry:m,onExtensionVersion:(O,ke)=>R.reportVersion(O,ke),onTransformerVersion:(O,ke)=>T.reportVersion(O,ke),transformers:T,extensionCommands:k,mcpTokenRegistry:H,extensionMcp:J,extensionMcpControls:te,getDaemonOrigin:W,registry:v,foreignSessions:A});let ae=!!s.daemon.tls;await a.listen({host:ae?"127.0.0.1":s.daemon.host,port:ae?0:s.daemon.port});let Z=a.server.address(),ve=Z&&typeof Z=="object"?Z.port:s.daemon.port,Hn,xu=s.daemon.host,Qo=ve;if(ae&&n&&r){Hn=Ly({listenHost:s.daemon.host,listenPort:s.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:ve,tlsOptions:{key:n,cert:r},logger:a.log});let O=Hn.address();O&&typeof O=="object"&&(Qo=O.port)}await Ge.mkdir(x.home(),{recursive:!0}),await Dd({pid:process.pid,host:xu,port:Qo,loopbackPort:ve,startedAt:new Date().toISOString()});let Yo={daemonUrl:`http://127.0.0.1:${ve}`,daemonHost:"127.0.0.1",daemonPort:ve,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${ve}/acp`,hydraHome:x.home()};R.setContext(Yo),T.setContext(Yo),await R.start(),await T.start();try{await C.reconcilePermissionFlags()}catch(O){a.log.warn(`permission flag reconcile failed: ${O.message}`)}try{await C.seedSessionIndex()}catch(O){a.log.warn(`session index seed failed: ${O.message}`)}C.resurrectPendingQueues().catch(O=>{a.log.warn(`queue replay scan failed: ${O.message}`)}),C.resumePendingCompactions().catch(O=>{a.log.warn(`compaction resume scan failed: ${O.message}`)}),C.resumePendingAgentSwaps().catch(O=>{a.log.warn(`agent-swap resume scan failed: ${O.message}`)});let Xo=s.daemon.agentSyncIntervalMinutes*60*1e3,Zo=Xo>0?Hd({registry:v,manager:C,intervalMs:Xo,logger:b}):void 0,ei=s.daemon.sessionGcIntervalMinutes*60*1e3,Eu=s.daemon.sessionGcMaxAgeDays*24*60*60*1e3,ti=ei>0?Ld({manager:C,intervalMs:ei,maxAgeMs:Eu,logger:b}):void 0,Tu=zd({bootConfig:s,apply:O=>{t=O,v.setConfig(O),C.setLiveConfig({sessionDefaults:O.sessionDefaults}),q.agentId=O.defaultAgent,q.cwd=O.defaultCwd,gr(O.daemon.scrubEnv)},onDrift:O=>{M=O},logger:b});return{app:a,manager:C,registry:v,extensions:R,transformers:T,mcpTokenRegistry:H,extensionMcp:J,processRegistry:m,shutdown:async()=>{u.stop(),l.stop(),Tu(),ti&&ti(),Zo&&Zo(),clearInterval(w),clearInterval(y);let O=async(ke,Xt)=>{try{await Xt()}catch(Zt){a.log.warn(`shutdown step ${ke} failed: ${Zt instanceof Error?Zt.message:String(Zt)}`)}};await O("sessionTokenStore.flush",()=>d.flush()),await O("extensions.stop",()=>R.stop()),await O("transformers.stop",()=>T.stop()),await O("manager.closeAll",()=>C.closeAll()),await O("manager.flushSynopsis",()=>C.flushSynopsis(3e4)),await O("manager.shutdownSynopsis",()=>C.shutdownSynopsis()),await O("manager.flushMetaWrites",()=>C.flushMetaWrites()),await O("manager.flushHistoryWrites",()=>C.flushHistoryWrites()),kr(null),Ir(null),Eo(null),Hn&&await O("tlsTerminator.close",()=>new Promise(ke=>Hn.close(()=>ke()))),await O("app.close",()=>a.close());try{Iu.unlinkSync(x.pidFile())}catch{}await O("fileStream.flushSync",()=>i.flushSync())}}}var Su=20;async function jy(s,e){let t=Yt.dirname(s),n=Yt.basename(s,".log"),r=new RegExp(`^${n}\\.(\\d+)\\.log$`),o;try{o=await Ge.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=>Ge.unlink(Yt.join(t,d.name))))}async function Hy(s){await jy(x.logFile(),Su);let e=await Dy({file:x.logFile(),size:"10m",mkdir:!0,symlink:As,limit:{count:Su,removeOtherLogFiles:!0}}),t=bu.destination(2);return{stream:bu.multistream([{stream:e,level:s},{stream:t,level:s}]),fileStream:e}}function Ly(s){let e=Cu.createServer(s.tlsOptions,t=>{let n=Au.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}`)}),e.listen({host:s.listenHost,port:s.listenPort}),e}function Uy(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 By(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:s}=await Promise.resolve().then(()=>(Nn(),Xc));s();let e=await nn(),t=await ri(),n=await Ru(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
197
197
  `);let r=1e4,o=!1,i=async()=>{o&&(process.stderr.write(`Second signal received; exiting immediately.
198
198
  `),process.exit(1)),o=!0,process.stdout.write(`Shutting down...
199
199
  `);let a=setTimeout(()=>{process.stderr.write(`Graceful shutdown did not complete within ${r}ms; forcing exit.