@hydra-acp/cli 0.1.144 → 0.1.146

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +507 -334
  2. package/dist/cli.js +331 -324
  3. package/dist/daemon.js +83 -83
  4. package/package.json +1 -1
package/dist/daemon.js CHANGED
@@ -1,81 +1,81 @@
1
1
  #!/usr/bin/env node
2
- var ha=Object.defineProperty;var Ot=(n,e)=>()=>(n&&(e=n(n=0)),e);var ya=(n,e)=>{for(var t in e)ha(n,t,{get:e[t],enumerable:!0})};import*as H from"path";import*as $n from"os";function Te(n){let e=$n.homedir();return e?n===e?"~":n.startsWith(e+"/")?"~"+n.slice(e.length):n:n}function va(){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 j(){let n=process.env[wa];if(n&&n.length>0)return H.resolve(n);let e=va();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 H.join($n.homedir(),".hydra-acp")}var wa,I,W=Ot(()=>{"use strict";wa="HYDRA_ACP_HOME";I={home:j,config:()=>H.join(j(),"config.json"),authToken:()=>H.join(j(),"auth-token"),remotes:()=>H.join(j(),"remotes.json"),pidFile:()=>H.join(j(),"daemon.pid"),logFile:()=>H.join(j(),"daemon.log"),currentLogFile:()=>H.join(j(),"current.log"),registryCache:()=>H.join(j(),"registry.json"),themesDir:()=>H.join(j(),"themes"),ttySessionDir:()=>H.join(j(),"tty"),ttySessionFile:n=>H.join(j(),"tty",n),agentsDir:()=>H.join(j(),"agents"),agentLogFile:n=>H.join(j(),"agents","logs",`${n}.log`),agentInstallDir:(n,e,t)=>H.join(j(),"agents",e,n,t),agentNpmInstallDir:(n,e,t)=>H.join(j(),"agents",e,n,t,`node${process.versions.modules}`),sessionsDir:()=>H.join(j(),"sessions"),sessionDir:n=>H.join(j(),"sessions",n),sessionFile:n=>H.join(j(),"sessions",n,"meta.json"),historyFile:n=>H.join(j(),"sessions",n,"history.jsonl"),historyArchiveFile:(n,e)=>H.join(j(),"sessions",n,`history.jsonl.${e}`),toolsDir:n=>H.join(j(),"sessions",n,"tools"),toolBlobFile:(n,e)=>H.join(j(),"sessions",n,"tools",e),queueFile:n=>H.join(j(),"sessions",n,"queue.ndjson"),tombstonesDir:()=>H.join(j(),"sessions",".tombstones"),tombstoneAgentDir:n=>H.join(j(),"sessions",".tombstones",encodeURIComponent(n)),tombstoneFile:(n,e)=>H.join(j(),"sessions",".tombstones",encodeURIComponent(n),encodeURIComponent(e)),extensionsDir:()=>H.join(j(),"extensions"),extensionLogDir:n=>H.join(j(),"extensions",n),extensionLogFile:n=>H.join(j(),"extensions",n,"current.log"),extensionPidFile:n=>H.join(j(),"extensions",n,"extension.pid"),transformersDir:()=>H.join(j(),"transformers"),transformerLogDir:n=>H.join(j(),"transformers",n),transformerLogFile:n=>H.join(j(),"transformers",n,"current.log"),transformerPidFile:n=>H.join(j(),"transformers",n,"transformer.pid"),transformerState:(n,e)=>H.join(j(),"sessions",n,"transformer-state",e),tuiHistoryFile:n=>H.join(j(),"sessions",n,"prompt-history"),globalTuiHistoryFile:()=>H.join(j(),"prompt-history"),tuiLogFile:()=>H.join(j(),"tui.log"),shimWireLogFile:()=>H.join(j(),"shim-wire.log")}});import*as K from"fs/promises";import*as Gs from"fs";import*as de from"path";import{randomBytes as Sa}from"crypto";async function ce(n,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
3
- `;await Ia(n,r,t)}async function Ia(n,e,t={}){let s=await ka(n),r=Aa(s);await K.mkdir(r,{recursive:!0});let i=`${s}.tmp-${process.pid}-${Ca()}`;try{let o={encoding:"utf8"};t.mode!==void 0&&(o.mode=t.mode),await K.writeFile(i,e,o),await K.rename(i,s)}catch(o){throw await K.unlink(i).catch(()=>{}),o}if(t.mode!==void 0)try{Gs.chmodSync(s,t.mode)}catch{}}async function ka(n){let e;try{e=await K.lstat(n)}catch(r){if(r.code==="ENOENT")return n;throw r}if(!e.isSymbolicLink())return n;let t=await K.readlink(n),s=de.isAbsolute(t)?t:de.resolve(de.dirname(n),t);try{let r=await K.realpath(de.dirname(s));return de.join(r,de.basename(s))}catch(r){if(r.code==="ENOENT")return s;throw r}}async function ue(n){let e;try{e=await K.readFile(n,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}if(e.trim().length!==0)try{return JSON.parse(e)}catch{return}}function Aa(n){let e=n.lastIndexOf("/");return e<=0?".":n.slice(0,e)}function Ca(){return Sa(4).toString("hex")}var _e=Ot(()=>{"use strict"});function _n(n,e){return`${n}:${e}`}var ra=Ot(()=>{"use strict";W();_e()});var fa={};ya(fa,{_resetForTests:()=>jf,clearPin:()=>Tf,fetchPeerFingerprint:()=>$f,formatFingerprint:()=>aa,getPin:()=>_f,installGlobalTlsTrust:()=>Of,loadPinsFromStore:()=>Ff,setPin:()=>oa,sha256Hex:()=>qs,wsTlsOptions:()=>Hf});import{createHash as Cf}from"crypto";import*as ia from"tls";import{Agent as xf,Dispatcher as Rf,buildConnector as Ef,getGlobalDispatcher as Mf,setGlobalDispatcher as Pf}from"undici";function oa(n,e,t){He.set(_n(n,e),da(t))}function Tf(n,e){He.delete(_n(n,e))}function _f(n,e){return He.get(_n(n,e))}function Ff(n){He.clear();for(let e of n.list())e.entry.pinnedFingerprint&&oa(e.host,e.port,e.entry.pinnedFingerprint)}async function $f(n,e,t={}){let s=t.timeoutMs??1e4;return new Promise((r,i)=>{let o=ia.connect({host:n,port:e,servername:n,rejectUnauthorized:!1,autoSelectFamily:!0}),a=!1,d=(c,f)=>{if(!a){a=!0,clearTimeout(u);try{o.destroy()}catch{}c?i(c):f&&r(f)}},u=setTimeout(()=>{d(new Error(`TLS connect to ${n}:${e} timed out`))},s);o.once("secureConnect",()=>{let c=o.getPeerCertificate(!1);if(!c||!c.raw){d(new Error(`${n}:${e} did not present a TLS certificate`));return}d(null,qs(c.raw))}),o.once("error",c=>d(c))})}function qs(n){return Cf("sha256").update(n).digest("hex")}function aa(n){let e=da(n),t=e.match(/.{2}/g);return t?t.join(":"):e}function da(n){return n.replace(/:/g,"").toLowerCase()}function Of(){if(Ls)return;Ls=!0;let n=Mf(),e=new xf({connect:Ef({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(s,r)=>ua(s,r)})}),t=new Rf;t.dispatch=(s,r)=>{let i=Nf(s.origin);return(i&&ca(i)?e:n).dispatch(s,r)},t.close=(()=>Promise.all([e.close(),n.close()]).then(()=>{})),t.destroy=(s=>Promise.all([e.destroy(s??null),n.destroy(s??null)]).then(()=>{})),Pf(t)}function Nf(n){if(!n)return null;try{return new URL(String(n)).hostname}catch{return null}}function ca(n){for(let e of He.keys())if(la(e)?.host===n)return!0;return!1}function ua(n,e){if(!e||!e.raw)return new Error(`TLS peer ${n} did not present a certificate`);let t=qs(e.raw);for(let[s,r]of He.entries()){let i=la(s);if(i&&i.host===n&&r===t)return}return new Error(`TLS pin mismatch for ${n} (cert sha256 ${aa(t)})`)}function la(n){let e=n.lastIndexOf(":");if(e<0)return null;let t=n.slice(0,e),s=Number(n.slice(e+1));return Number.isInteger(s)?{host:t,port:s}:null}function Hf(n){return ca(n)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>ua(e,t)}:{autoSelectFamily:!0}}function jf(){He.clear(),Ls=!1}var He,Ls,pa=Ot(()=>{"use strict";ra();He=new Map,Ls=!1});W();import*as ke from"fs/promises";import{homedir as Hn}from"os";import{z as b}from"zod";W();import*as Be from"fs/promises";function On(){let n=new Uint8Array(32);crypto.getRandomValues(n);let e="";for(let t of n)e+=t.toString(16).padStart(2,"0");return`hydra_token_${e}`}async function ba(){try{let e=(await Be.readFile(I.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(n){if(n.code==="ENOENT")return;throw n}}async function Nn(n){await Be.mkdir(I.home(),{recursive:!0}),await Be.writeFile(I.authToken(),n+`
4
- `,{encoding:"utf8",mode:384})}async function Qs(){let n=await ba();if(n)return n;let e=On();return await Nn(e),process.stderr.write(`hydra-acp: initialized ${I.authToken()} with a fresh service token.
5
- `),e}_e();var Ys="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",xa=b.object({cert:b.string(),key:b.string()}),Xs=55514,Ra=b.object({host:b.string().default("127.0.0.1"),port:b.number().int().positive().default(Xs),logLevel:b.enum(["debug","info","warn","error"]).default("info"),tls:xa.optional(),sessionIdleTimeoutSeconds:b.number().int().nonnegative().default(3600),sessionHistoryMaxEntries:b.number().int().positive().default(1e4),sessionHistoryArchiveMaxBytes:b.number().int().nonnegative().default(1e7),sessionHistoryArchiveTiers:b.number().int().positive().default(10),agentStderrTailBytes:b.number().int().positive().default(4096),publicHost:b.string().optional(),agentSyncIntervalMinutes:b.number().nonnegative().default(60),scrubEnv:b.array(b.string()).default([]),sessionGcIntervalMinutes:b.number().nonnegative().default(60),sessionGcMaxAgeDays:b.number().positive().default(2)}),Ea=b.object({url:b.string().url().default(Ys),ttlHours:b.number().positive().default(24),pinned:b.boolean().default(!1)}),Ma=b.object({name:b.string().optional(),description:b.string().optional(),command:b.string().optional(),args:b.array(b.string()).optional(),env:b.record(b.string()).optional()}),Pa=b.object({packageSpec:b.string().optional()}),Ta=b.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-y","ctrl-underscore","alt-underscore","escape"]),_a=b.union([b.string(),b.object({field:b.string().optional(),text:b.string().optional(),maxWidth:b.number().int().positive().optional(),minWidth:b.number().int().nonnegative().optional(),priority:b.number().optional(),prefix:b.string().optional(),suffix:b.string().optional(),separator:b.string().optional(),style:b.string().optional(),onClick:b.string().optional(),onDoubleClick:b.string().optional()}).strict()]),Ks=b.array(_a);function jn(n,e){return b.object({left:Ks.default(n),right:Ks.default(e)}).default({})}var Fa=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],$a=["usage"],Oa=[],Na=["helpHint"],Ha=["cwd","title"],ja=["agentModel"],Ba=b.object({composer:b.object({top:jn(Fa,$a),bottom:jn(Oa,Na)}).default({}),sessionbar:jn(Ha,ja),repaintThrottleMs:b.number().int().nonnegative().default(1e3),maxScrollbackLines:b.number().int().positive().default(1e4),mouse:b.boolean().default(!0),inAppSelection:b.boolean().optional(),selectionClipboard:b.enum(["primary","clipboard","both"]).default("both"),openFileCommand:b.union([b.string(),b.array(b.string())]).optional(),logMaxBytes:b.number().int().positive().default(5*1024*1024),cwdColumnMaxWidth:b.number().int().positive().default(32),progressIndicator:b.boolean().default(!0),defaultEnterAction:b.enum(["enqueue","amend"]).default("amend"),showThoughts:b.boolean().default(!0),ambiguousWidth:b.enum(["auto","narrow","wide"]).default("auto"),toolContent:b.enum(["inline","references"]).default("references"),diffContextLines:b.number().int().min(0).default(3),promptHistoryMaxEntries:b.number().int().positive().default(2e3),maxToolItems:b.number().int().nonnegative().default(5),maxPlanItems:b.number().int().nonnegative().default(5),sidebar:b.object({enabled:b.boolean().default(!1),width:b.number().int().positive().optional(),border:b.enum(["none","rule","frame"]).default("frame"),gadgets:b.array(b.string()).default(["activity","sessions","context","queue","todo","files","git","resources","info","tools"])}).default({}),showFileUpdates:b.enum(["none","edit","diff"]).default("edit"),sessionColumns:b.array(b.enum(["session","upstream","host","state","agent","model","age","cwd","title","cost"])).nonempty().optional(),hotkeys:b.record(Ta,b.object({command:b.union([b.string(),b.array(b.string())])})).default({}),theme:b.union([b.string(),b.record(b.string(),b.unknown())]).optional(),themeBackground:b.string().optional()}),Vs=b.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),Ua=b.object({command:b.array(b.string()).default([]),args:b.array(b.string()).default([]),env:b.record(b.string()).default({}),enabled:b.boolean().default(!0)}),Da=b.object({command:b.array(b.string()).default([]),args:b.array(b.string()).default([]),env:b.record(b.string()).default({}),enabled:b.boolean().default(!0)}),La=b.object({daemon:Ra.default({}),registry:Ea.default({url:Ys,ttlHours:24,pinned:!1}),agents:b.record(b.string(),Ma).default({}),agentOverrides:b.record(b.string(),Pa).default({}),defaultAgent:b.string().default("opencode"),defaultModels:b.record(b.string(),b.string()).default({}),synopsisAgent:b.string().optional(),synopsisModel:b.string().optional(),compaction:b.object({agent:b.string().optional(),model:b.string().optional(),tailK:b.number().int().nonnegative().default(20),maxIterations:b.number().int().positive().default(3),contextFraction:b.number().min(0).max(1).default(.5),hardCeilingFraction:b.number().min(0).max(1).default(.85),absoluteFallback:b.number().int().positive().default(2e5),idleBeforePromptMs:b.number().int().nonnegative().default(3e5),modelContextWindows:b.record(b.string(),b.number().int().positive()).default({})}).default({}),defaultCwd:b.string().default("~"),compressToolContent:b.boolean().default(!0),sessionListColdLimit:b.number().int().nonnegative().default(20),extensions:b.record(Vs,Ua).default({}),transformers:b.record(Vs,Da).default({}),defaultTransformers:b.array(b.string()).default([]),npmRegistry:b.string().url().optional(),tui:Ba.default({})});function Zs(n){return Object.entries(n.extensions).map(([e,t])=>({name:e,...t}))}function er(n){return Object.entries(n.transformers).map(([e,t])=>({name:e,...t}))}async function tr(){return await qa(),await ue(I.config())??{}}async function qa(){let n;try{n=await ke.lstat(I.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(n.isSymbolicLink())try{await ke.stat(I.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await ke.readlink(I.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${I.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 za(){let n=await tr(),e=n.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let s=!1;try{await ke.access(I.authToken()),s=!0}catch(r){if(r.code!=="ENOENT")throw r}if(s)throw new Error(`Auth token present in both ${I.authToken()} and ${I.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await Nn(t),delete e.authToken,Object.keys(e).length===0&&delete n.daemon,await ce(I.config(),n,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${I.config()} to ${I.authToken()}.
6
- `)}async function Bn(){return await za(),La.parse(await tr())}function Z(n){return n==="~"||n==="$HOME"?Hn():n.startsWith("~/")?Hn()+n.slice(1):n.startsWith("$HOME/")?Hn()+n.slice(5):n}import*as ea from"fs";import*as we from"fs/promises";import*as ta from"net";import*as lt from"path";import*as na from"tls";import wf from"fastify";import vf from"@fastify/websocket";var nr="acp.v1";function sr(n,e){return n.has(nr)?nr:!1}import Xo from"pino";import bf from"pino-roll";var Ja={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"],hydra:["HYDRA_TAB_LABEL"]},Wa=Object.values(Ja).flat(),rr=[];function ir(n){rr=n?[...n]:[]}function Qa(n,e){return e.endsWith("*")?n.startsWith(e.slice(0,-1)):n===e}function Ga(){return[...Wa,...rr]}function Nt(n=process.env){let e=Ga(),t={};for(let[s,r]of Object.entries(n))r!==void 0&&(e.some(i=>Qa(s,i))||(t[s]=r));return t}W();import*as V from"fs/promises";import{createHash as Ka}from"crypto";import{gzip as Va,gunzip as Ya}from"zlib";import{promisify as or}from"util";var ar=or(Va),Xa=or(Ya),dr=/^[A-Za-z0-9_-]+$/,Za=/^[a-f0-9]{64}$/,Un=!0;function cr(n){Un=n}function Ht(n,e){return dr.test(n)?e===void 0||Za.test(e):!1}function jt(n,e){return`${I.toolBlobFile(n,e)}.gz`}async function Dn(n,e){if(!Ht(n))return null;let t=Ka("sha256").update(e,"utf8").digest("hex"),s=jt(n,t),r=I.toolBlobFile(n,t);for(let a of[s,r])try{return await V.access(a),t}catch{}await V.mkdir(I.toolsDir(n),{recursive:!0});let i=Un?s:r,o=Un?await ar(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await V.writeFile(i,o,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function ft(n,e){if(!Ht(n,e))return null;try{let t=await V.readFile(jt(n,e));return(await Xa(t)).toString("utf8")}catch{}try{return await V.readFile(I.toolBlobFile(n,e),"utf8")}catch{return null}}async function ur(n,e){if(!Ht(n,e))return null;try{return await V.readFile(jt(n,e))}catch{}try{let t=await V.readFile(I.toolBlobFile(n,e));return await ar(t)}catch{return null}}async function lr(n,e,t){if(!Ht(n,e))return;let s=jt(n,e);try{await V.access(s);return}catch{}await V.mkdir(I.toolsDir(n),{recursive:!0}),await V.writeFile(s,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function fr(n){dr.test(n)&&await V.rm(I.toolsDir(n),{recursive:!0,force:!0}).catch(()=>{})}W();import*as kr from"fs/promises";import*as Ut from"path";import{z as $}from"zod";_e();W();import*as mr from"fs";import*as ee from"fs/promises";import*as Ae from"path";import{spawn as gr}from"child_process";import{Readable as ed}from"stream";function pe(){let n=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(!(!n||!e))return`${n}-${e}`}function zn(n,e=pe()){if(e)return n[e]}var Ue=n=>{process.stderr.write(n+`
7
- `)};function Jn(n){Ue=n??(e=>process.stderr.write(e+`
8
- `))}async function hr(n){if(!n.target.archive)throw new Error(`Agent ${n.agentId} has no archive URL for ${pe()??"this platform"}`);if(!n.target.cmd)throw new Error(`Agent ${n.agentId} has no cmd in its binary target`);let e=pe();if(!e)throw new Error(`Agent ${n.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=I.agentInstallDir(n.agentId,e,n.version),s=Ae.resolve(t,n.target.cmd);if(await qn(s))return s;if(await td({agentId:n.agentId,version:n.version,archiveUrl:n.target.archive,installDir:t,onProgress:n.onProgress}),!await qn(s))throw new Error(`Agent ${n.agentId}: extracted archive did not contain ${n.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await ee.chmod(s,493).catch(()=>{}),s}async function td(n){await ee.mkdir(Ae.dirname(n.installDir),{recursive:!0});let e=await ee.mkdtemp(`${n.installDir}.partial-`);try{Ue(`hydra-acp: downloading ${n.agentId} from ${n.archiveUrl}`);let t=await nd({url:n.archiveUrl,dir:e,agentId:n.agentId,version:n.version,onProgress:n.onProgress});Ue(`hydra-acp: extracting ${n.agentId}`),De(n.onProgress,{phase:"extract",agentId:n.agentId,version:n.version}),await rd(t,e),await ee.unlink(t).catch(()=>{});try{await ee.rename(e,n.installDir)}catch(s){let r=s;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await qn(n.installDir)){await ee.rm(e,{recursive:!0,force:!0}).catch(()=>{}),De(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version});return}throw s}Ue(`hydra-acp: installed ${n.agentId} to ${n.installDir}`),De(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version})}catch(t){throw await ee.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function De(n,e){if(n)try{n(e)}catch{}}async function nd(n){let e=sd(n.url),t=Ae.join(n.dir,e),s=await fetch(n.url,{redirect:"follow"});if(!s.ok||!s.body)throw new Error(`Failed to download ${n.url}: HTTP ${s.status} ${s.statusText}`);let r=Number(s.headers.get("content-length")??"0"),i=mr.createWriteStream(t),o=ed.fromWeb(s.body);De(n.onProgress,{phase:"download_start",agentId:n.agentId,version:n.version,totalBytes:r});let a=0,d=Date.now(),u=0,c=2e3,f=150;return o.on("data",p=>{a+=p.length;let l=Date.now();l-u>=f&&(u=l,De(n.onProgress,{phase:"download_progress",agentId:n.agentId,version:n.version,receivedBytes:a,totalBytes:r})),l-d>=c&&(d=l,Ue(pr(n.agentId,a,r)))}),await new Promise((p,l)=>{o.on("error",l),i.on("error",l),i.on("finish",()=>p()),o.pipe(i)}),Ue(pr(n.agentId,a,r,!0)),De(n.onProgress,{phase:"download_done",agentId:n.agentId,version:n.version,receivedBytes:a,totalBytes:r}),t}function pr(n,e,t,s=!1){let r=(e/1e6).toFixed(1);if(t>0){let o=(t/1e6).toFixed(1),a=Math.min(100,Math.floor(e/t*100));return`hydra-acp: ${s?"downloaded":"downloading"} ${n} ${r}/${o} MB (${a}%)`}return`hydra-acp: ${s?"downloaded":"downloading"} ${n} ${r} MB`}function sd(n){let e=new URL(n);return Ae.posix.basename(e.pathname)||"archive"}async function rd(n,e){let t=n.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await Ln("tar",["-xf",n,"-C",e]);return}if(t.endsWith(".zip")){if(await id("unzip")){await Ln("unzip",["-q",n,"-d",e]);return}await Ln("tar",["-xf",n,"-C",e]);return}throw new Error(`Unsupported archive format: ${n}`)}function Ln(n,e){return new Promise((t,s)=>{let r=gr(n,e,{stdio:["ignore","ignore","inherit"]});r.on("error",s),r.on("exit",(i,o)=>{if(i===0){t();return}s(new Error(`${n} ${e.join(" ")} exited with ${i!==null?`code ${i}`:`signal ${o}`}`))})})}async function id(n){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",s=gr(t,[n],{stdio:"ignore"});s.on("error",()=>e(!1)),s.on("exit",r=>e(r===0))})}async function qn(n){try{return await ee.access(n),!0}catch{return!1}}W();import*as se from"fs/promises";import*as me from"path";import{spawn as od}from"child_process";var Qn=n=>{process.stderr.write(n+`
9
- `)};function Gn(n){Qn=n??(e=>process.stderr.write(e+`
10
- `))}async function wr(n){let e=pe();if(!e)throw new Error(`Agent ${n.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=I.agentNpmInstallDir(n.agentId,e,n.version),s=ld(n.packageSpec),r=fd(s),i={installDir:t,packageName:s,hint:n.bin,basename:r},o=me.join(t,"node_modules",".bin",n.bin);if(await Fe(o))return o;if(await Fe(t)){let f=await yr(i);if(f)return f.binPath}await ad({agentId:n.agentId,version:n.version,packageSpec:n.packageSpec,installDir:t,registry:n.registry,onProgress:n.onProgress});let a=await yr(i);if(a)return a.binPath;let d=await br(t,s),u=typeof d=="object"&&d!==null?Object.keys(d):typeof d=="string"?[r]:[],c=u.length>0?` (package declares bins: ${u.join(", ")})`:"";throw new Error(`Agent ${n.agentId}: npm install of ${n.packageSpec} did not produce bin ${n.bin} (looked in ${t}/node_modules/.bin/)${c}`)}async function ad(n){await se.mkdir(me.dirname(n.installDir),{recursive:!0});let e=await se.mkdtemp(`${n.installDir}.partial-`);try{Qn(`hydra-acp: installing ${n.packageSpec} for ${n.agentId} into ${e}`),Wn(n.onProgress,{phase:"install_start",agentId:n.agentId,version:n.version,packageSpec:n.packageSpec}),await ud({packageSpec:n.packageSpec,cwd:e,registry:n.registry});try{await se.rename(e,n.installDir)}catch(t){let s=t;if((s.code==="EEXIST"||s.code==="ENOTEMPTY")&&await Fe(n.installDir)){await se.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Wn(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version});return}throw t}Qn(`hydra-acp: installed ${n.agentId} to ${n.installDir}`),Wn(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version})}catch(t){throw await se.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Wn(n,e){if(n)try{n(e)}catch{}}var dd=5,cd=25;function ud(n){return vr(n,0)}async function vr(n,e){try{await new Promise((t,s)=>{let r=n.registry?["--registry",n.registry]:[],i;try{i=od("npm",["install","--no-audit","--no-fund","--silent",...r,n.packageSpec],{cwd:n.cwd,stdio:["ignore","pipe","pipe"]})}catch(a){s(a);return}let o="";i.stdout?.on("data",a=>{}),i.stderr?.setEncoding("utf8"),i.stderr?.on("data",a=>{o=(o+a).slice(-4096)}),i.on("error",a=>{if(a.code==="ENOENT"){s(new Error("npm not found on PATH (install Node.js / npm, or use a binary-distributed agent)"));return}s(a)}),i.on("exit",(a,d)=>{if(a===0){t();return}let u=a!==null?`exit code ${a}`:`signal ${d??"unknown"}`,c=o.trim();s(new Error(c?`npm install ${n.packageSpec} failed (${u})
11
- stderr: ${c}`:`npm install ${n.packageSpec} failed (${u})`))})})}catch(t){if(t.code==="ETXTBSY"&&e<dd)return await new Promise(r=>setTimeout(r,cd*(e+1))),vr(n,e+1);throw t}}function ld(n){if(n.startsWith("@")){let t=n.indexOf("/");if(t===-1)return n;let r=n.slice(t+1).indexOf("@");return r===-1?n:n.slice(0,t+1+r)}let e=n.indexOf("@");return e<=0?n:n.slice(0,e)}function fd(n){let e=n.lastIndexOf("/");return e===-1?n:n.slice(e+1)}async function br(n,e){let t=me.join(n,"node_modules",e,"package.json");try{let s=await se.readFile(t,"utf8"),r=JSON.parse(s);return typeof r.bin=="string"||typeof r.bin=="object"&&r.bin!==null&&!Array.isArray(r.bin)?r.bin:void 0}catch{return}}async function yr(n){let e=me.join(n.installDir,"node_modules",".bin"),t=me.join(e,n.hint);if(await Fe(t))return{binName:n.hint,binPath:t};let s=await br(n.installDir,n.packageName);if(typeof s=="object"&&s!==null){let r=Object.keys(s);if(r.length===1){let i=r[0],o=me.join(e,i);if(await Fe(o))return{binName:i,binPath:o}}else if(r.length>1){for(let i of[n.hint,n.basename])if(r.includes(i)){let o=me.join(e,i);if(await Fe(o))return{binName:i,binPath:o}}}}if(n.basename!==n.hint){let r=me.join(e,n.basename);if(await Fe(r))return{binName:n.basename,binPath:r}}}async function Fe(n){try{return await se.access(n),!0}catch{return!1}}var pd=$.object({package:$.string(),bin:$.string().optional(),args:$.array($.string()).optional(),env:$.record($.string()).optional()}),Le=$.object({archive:$.string().url().optional(),cmd:$.string().optional(),args:$.array($.string()).optional(),env:$.record($.string()).optional()}),md=$.object({"darwin-aarch64":Le.optional(),"darwin-x86_64":Le.optional(),"linux-aarch64":Le.optional(),"linux-x86_64":Le.optional(),"windows-x86_64":Le.optional(),"windows-aarch64":Le.optional()}),gd=$.object({package:$.string(),args:$.array($.string()).optional(),env:$.record($.string()).optional()}),hd=$.object({command:$.string(),args:$.array($.string()).optional(),env:$.record($.string()).optional()}),yd=$.object({command:$.string().optional(),url:$.string().optional(),description:$.string().optional()}),wd=$.object({npx:pd.optional(),binary:md.optional(),uvx:gd.optional(),exec:hd.optional()}),vd=$.object({id:$.string(),name:$.string(),version:$.string().optional(),description:$.string().optional(),authors:$.array($.string()).optional(),license:$.string().optional(),icon:$.string().optional(),repository:$.string().optional(),website:$.string().optional(),distribution:wd,onboarding:yd.optional(),requiredEnv:$.array($.string().min(1)).optional()}),Sr=$.object({version:$.string(),agents:$.array(vd),extensions:$.array($.unknown()).optional()}),Bt=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)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}async getAgent(e){let t=this.localAgents().find(a=>a.id===e);if(t)return t;let s=await this.load(),r=s.agents.find(a=>a.id===e);if(r)return this.applyOverride(r);let i=s.agents.find(a=>Kn(a)===e);if(i)return this.applyOverride(i);let o=e.toLowerCase();if(o.length>0){let a=s.agents.filter(d=>d.id.toLowerCase().startsWith(o));if(a.length===1)return this.applyOverride(a[0])}}localAgents(){return Object.entries(this.config.agents??{}).map(([e,t])=>({id:e,name:t.name??e,description:t.description,version:"local",distribution:{exec:{command:Z(t.command??e),args:t.args?.map(Z),env:t.env}}}))}applyOverride(e){let t=this.config.agentOverrides?.[e.id];return!t?.packageSpec||!e.distribution.npx?e:{...e,version:bd(t.packageSpec),distribution:{...e.distribution,npx:{...e.distribution.npx,package:t.packageSpec}}}}isPinned(){return this.config.registry?.pinned===!0}isFresh(e){let t=Date.now()-e,s=this.config.registry.ttlHours*60*60*1e3;return t<s}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(),s=Sr.parse(t),r={fetchedAt:Date.now(),raw:t,data:s},i=this.options.onFetched;return i&&Promise.resolve().then(()=>i(s)).catch(()=>{}),r}async readDiskCache(){let e=await ue(I.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=Sr.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await ce(I.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function bd(n){let e=n.lastIndexOf("@"),s=(e>0?n.slice(e+1):"").replace(/[^a-zA-Z0-9._-]/g,"_");return s.length>0?`pin-${s}`:"pinned"}function Kn(n){let e=n.distribution.npx?.package;if(!e)return;let t=e.lastIndexOf("/"),s=t===-1?e:e.slice(t+1),r=s.lastIndexOf("@");return r<=0?s:s.slice(0,r)}async function qe(n){let e=typeof n.localAgents=="function"?n.localAgents():[],t;try{t=await n.load()}catch(o){if(e.length===0)throw o;t={version:"local-only",agents:[]}}let s=new Set(e.map(o=>o.id)),r=[...e,...t.agents.filter(o=>!s.has(o.id))],i=await Promise.all(r.map(async o=>({id:o.id,name:o.name,version:o.version,description:o.description,distributions:Object.keys(o.distribution),installed:await Vn(o),source:s.has(o.id)?"local":"registry",...o.onboarding?{onboarding:o.onboarding}:{}})));return{version:t.version,fetchedAt:n.lastFetchedAt(),agents:i}}async function Vn(n){let e=pe();if(!e)return"no";let t=n.version??"current";if(n.distribution.exec)return"yes";if(n.distribution.binary){let s=zn(n.distribution.binary,e);if(s?.cmd){let r=Ut.resolve(I.agentInstallDir(n.id,e,t),s.cmd);if(await Ir(r))return"yes"}}if(n.distribution.npx){let s=n.distribution.npx,r=s.bin??Kn(n)??s.package,i=I.agentNpmInstallDir(n.id,e,t),o=Ut.join(i,"node_modules",".bin",r);if(await Ir(o))return"yes"}return!n.distribution.npx&&!n.distribution.binary&&n.distribution.uvx?"lazy":"no"}async function Ir(n){try{return await kr.access(n),!0}catch{return!1}}async function oe(n,e=[],t={}){let s=n.version??"current";if(n.distribution.npx){let r=n.distribution.npx,i=e.length>0?e:r.args??[];if(process.env.HYDRA_ACP_SKIP_NPM_PREFETCH)return{command:"npx",args:["-y",r.package,...i],env:r.env??{},version:s};let o=r.bin??Kn(n)??r.package,a=t.onInstallProgress;return{command:await wr({agentId:n.id,version:s,packageSpec:r.package,bin:o,registry:t.npmRegistry,onProgress:a?u=>a({source:"npm",...u}):void 0}),args:i,env:r.env??{},version:s}}if(n.distribution.binary){let r=zn(n.distribution.binary);if(!r)throw new Error(`Agent ${n.id} has no binary distribution for ${pe()??"this platform"}.`);let i=t.onInstallProgress,o=await hr({agentId:n.id,version:s,target:r,onProgress:i?d=>i({source:"binary",...d}):void 0}),a=e.length>0?e:r.args??[];return{command:o,args:a,env:r.env??{},version:s}}if(n.distribution.uvx){let r=n.distribution.uvx,i=e.length>0?e:r.args??[];return{command:"uvx",args:[r.package,...i],env:r.env??{},version:s}}if(n.distribution.exec){let r=n.distribution.exec,i=e.length>0?e:r.args??[];return{command:r.command,args:i,env:r.env??{},version:s}}throw new Error(`Agent ${n.id} has no usable distribution method.`)}import{spawn as Cd}from"child_process";import*as qt from"fs";import*as jr from"path";var k={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,AuthRequired:-32e3,SessionNotFound:-32001,NotAuthorisedToAttach:-32002,MultiClientNotSupported:-32003,AgentNotInstalled:-32005,BundleAlreadyImported:-32010,PermissionDenied:-32011,AlreadyAttached:-32012,StreamNotEnabled:-32013,SessionClosing:-32014};import{z as q}from"zod";var Ar=q.object({protocolVersion:q.number().optional(),clientCapabilities:q.record(q.unknown()).optional(),clientInfo:q.object({name:q.string(),version:q.string().optional()}).optional()}),Sd=q.enum(["full","pending_only","none","after_message"]),Cr=q.object({cwd:q.string(),mcpServers:q.array(q.unknown()).optional(),_meta:q.record(q.unknown()).optional()}),xr=q.object({upstreamSessionId:q.string(),agentId:q.string(),cwd:q.string(),title:q.string().optional(),agentArgs:q.array(q.string()).optional()}),Rr=q.object({sessionId:q.string(),historyPolicy:Sd.default("full"),afterMessageId:q.string().optional(),clientId:q.string().optional(),clientInfo:q.object({name:q.string(),version:q.string().optional()}).optional(),_meta:q.record(q.unknown()).optional()});import{z as N}from"zod";var Er=N.object({sessionId:N.string()}),Mr=N.object({cwd:N.string().optional(),cursor:N.string().optional()}),Yn=N.object({used:N.number().optional(),size:N.number().optional(),costAmount:N.number().optional(),costCurrency:N.string().optional()}),xp=N.object({sessionId:N.string(),upstreamSessionId:N.string().optional(),cwd:N.string(),title:N.string().optional(),agentId:N.string().optional(),currentModel:N.string().optional(),currentUsage:Yn.optional(),importedFromMachine:N.string().optional(),importedFromUpstreamSessionId:N.string().optional(),parentSessionId:N.string().optional(),forkedFromSessionId:N.string().optional(),forkedFromMessageId:N.string().optional(),originatingClient:N.object({name:N.string(),version:N.string().optional()}).optional(),interactive:N.boolean().optional(),priority:N.number().int().nonnegative().optional(),updatedAt:N.string(),attachedClients:N.number().int().nonnegative(),status:N.enum(["warm","cold"]).default("warm"),busy:N.boolean().default(!1),awaitingInput:N.boolean().default(!1),compactionState:N.any().optional(),agentPid:N.number().int().positive().optional(),forkSynthesisState:N.enum(["running","failed"]).optional(),_meta:N.record(N.unknown()).optional()}),Id=N.object({sessionId:N.string(),cwd:N.string(),title:N.string().optional(),updatedAt:N.string().optional(),_meta:N.record(N.unknown()).optional()}),Rp=N.object({sessions:N.array(Id),nextCursor:N.string().optional()});function Dt(n,e){let t={attachedClients:n.attachedClients,status:n.status,busy:n.busy,awaitingInput:n.awaitingInput};return n.cwd!==void 0&&(t.cwd=n.cwd),n.title!==void 0&&(t.title=n.title),n.agentId!==void 0&&(t.agentId=n.agentId),n.upstreamSessionId!==void 0&&(t.upstreamSessionId=n.upstreamSessionId),n.currentModel!==void 0&&(t.currentModel=n.currentModel),n.currentUsage!==void 0&&(t.currentUsage=n.currentUsage),n.importedFromMachine!==void 0&&(t.importedFromMachine=n.importedFromMachine),n.importedFromUpstreamSessionId!==void 0&&(t.importedFromUpstreamSessionId=n.importedFromUpstreamSessionId),n.parentSessionId!==void 0&&(t.parentSessionId=n.parentSessionId),n.forkedFromSessionId!==void 0&&(t.forkedFromSessionId=n.forkedFromSessionId),n.forkedFromMessageId!==void 0&&(t.forkedFromMessageId=n.forkedFromMessageId),n.originatingClient!==void 0&&(t.originatingClient=n.originatingClient),n.interactive!==void 0&&(t.interactive=n.interactive),n.priority!==void 0&&n.priority>0&&(t.priority=n.priority),n.compactionState!==void 0&&(t.compactionState=n.compactionState),n.forkSynthesisState!==void 0&&(t.forkSynthesisState=n.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)),t}function Pr(n){let e={sessionId:n.sessionId,cwd:n.cwd,updatedAt:n.updatedAt,_meta:pt(n._meta,Dt(n))};return n.title!==void 0&&(e.title=n.title),e}var $e="hydra-acp";function kd(n){if(!n||typeof n!="object"||Array.isArray(n))return;let e={};for(let[t,s]of Object.entries(n)){if(typeof t!="string"||t.length===0||typeof s!="string")return;e[t]=s}return e}function mt(n){if(!n)return{};let e=n[$e];if(!e||typeof e!="object"||Array.isArray(e))return{};let t=e,s={};if(typeof t.upstreamSessionId=="string"&&(s.upstreamSessionId=t.upstreamSessionId),typeof t.agentId=="string"&&(s.agentId=t.agentId),typeof t.cwd=="string"&&(s.cwd=t.cwd),typeof t.clientId=="string"&&(s.clientId=t.clientId),typeof t.readonly=="boolean"&&(s.readonly=t.readonly),(t.replayMode==="instant"||t.replayMode==="drip")&&(s.replayMode=t.replayMode),typeof t.dripSpeed=="number"&&t.dripSpeed>0&&(s.dripSpeed=t.dripSpeed),(t.toolContent==="inline"||t.toolContent==="references")&&(s.toolContent=t.toolContent),t.detachStatus==="detached"&&(s.detachStatus=t.detachStatus),typeof t.title=="string"&&(s.title=t.title),Array.isArray(t.agentArgs)&&t.agentArgs.every(r=>typeof r=="string")&&(s.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(r=>typeof r=="string")&&(s.transformers=t.transformers),t.resume){let r=xr.safeParse(t.resume);r.success&&(s.resume=r.data)}if(typeof t.model=="string"&&(s.model=t.model),typeof t.currentModel=="string"&&(s.currentModel=t.currentModel),typeof t.currentMode=="string"&&(s.currentMode=t.currentMode),t.currentUsage){let r=Yn.safeParse(t.currentUsage);r.success&&(s.currentUsage=r.data)}if(typeof t.turnStartedAt=="number"&&t.turnStartedAt>0&&(s.turnStartedAt=t.turnStartedAt),Array.isArray(t.availableCommands)){let r=[];for(let i of t.availableCommands){if(!i||typeof i!="object"||Array.isArray(i))continue;let o=i;if(typeof o.name!="string")continue;let a={name:o.name};typeof o.description=="string"&&(a.description=o.description),r.push(a)}r.length>0&&(s.availableCommands=r)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let r=t.prompt,i={};typeof r.queueing=="boolean"&&(i.queueing=r.queueing),typeof r.cancelling=="boolean"&&(i.cancelling=r.cancelling),typeof r.updating=="boolean"&&(i.updating=r.updating),typeof r.amending=="boolean"&&(i.amending=r.amending),typeof r.pipelining=="boolean"&&(i.pipelining=r.pipelining),s.prompt=i}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let r=t.agents,i={};typeof r.list=="boolean"&&(i.list=r.list),typeof r.installProgress=="boolean"&&(i.installProgress=r.installProgress),s.agents=i}if(typeof t.mcpStdin=="boolean"&&(s.mcpStdin=t.mcpStdin),typeof t.interactive=="boolean"&&(s.interactive=t.interactive),typeof t.ancillary=="boolean"&&(s.ancillary=t.ancillary),Array.isArray(t.queue)){let r=[];for(let i of t.queue){if(!i||typeof i!="object"||Array.isArray(i))continue;let o=i,a=o.originator;if(typeof o.messageId!="string"||!a||typeof a.clientId!="string"||!Array.isArray(o.prompt)||typeof o.position!="number"||typeof o.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:o.messageId,originator:d,prompt:o.prompt,position:o.position,enqueuedAt:o.enqueuedAt})}r.length>0&&(s.queue=r)}if(Array.isArray(t.availableModes)){let r=[];for(let i of t.availableModes){if(!i||typeof i!="object"||Array.isArray(i))continue;let o=i;if(typeof o.id!="string")continue;let a={id:o.id};typeof o.name=="string"&&(a.name=o.name),typeof o.description=="string"&&(a.description=o.description),r.push(a)}r.length>0&&(s.availableModes=r)}if(Array.isArray(t.availableModels)){let r=[];for(let i of t.availableModels){if(!i||typeof i!="object"||Array.isArray(i))continue;let o=i;if(typeof o.modelId!="string")continue;let a={modelId:o.modelId};typeof o.name=="string"&&(a.name=o.name),typeof o.description=="string"&&(a.description=o.description),r.push(a)}r.length>0&&(s.availableModels=r)}if((t.status==="warm"||t.status==="cold")&&(s.status=t.status),typeof t.busy=="boolean"&&(s.busy=t.busy),typeof t.awaitingInput=="boolean"&&(s.awaitingInput=t.awaitingInput),typeof t.attachedClients=="number"&&(s.attachedClients=t.attachedClients),typeof t.resurrected=="boolean"&&(s.resurrected=t.resurrected),typeof t.importedFromMachine=="string"&&(s.importedFromMachine=t.importedFromMachine),typeof t.importedFromUpstreamSessionId=="string"&&(s.importedFromUpstreamSessionId=t.importedFromUpstreamSessionId),typeof t.parentSessionId=="string"&&(s.parentSessionId=t.parentSessionId),typeof t.forkedFromSessionId=="string"&&(s.forkedFromSessionId=t.forkedFromSessionId),typeof t.forkedFromMessageId=="string"&&(s.forkedFromMessageId=t.forkedFromMessageId),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let r=t.originatingClient;s.originatingClient={name:r.name,...typeof r.version=="string"?{version:r.version}:{}}}if(t.agentCapabilities!==void 0&&(s.agentCapabilities=t.agentCapabilities),t.env!==void 0){let r=kd(t.env);r!==void 0&&(s.env=r)}return s}function Ce(n,e){if(typeof e!="number"||!Number.isFinite(e)||!n||typeof n!="object"||Array.isArray(n))return n;let t=n,s=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=s[$e],i=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof i.recordedAt=="number"?n:{...t,_meta:{...s,[$e]:{...i,recordedAt:e}}}}function pt(n,e){return{...n??{},[$e]:e}}import{z as E}from"zod";var Tr=E.object({sessionId:E.string(),prompt:E.array(E.unknown()),_meta:E.record(E.unknown()).optional()}),Lt=E.object({sessionId:E.string()}),_r=E.object({clientId:E.string(),name:E.string().optional(),version:E.string().optional()}),Fp=E.object({sessionId:E.string(),messageId:E.string(),originator:_r,prompt:E.array(E.unknown()),position:E.number().int().nonnegative(),queueDepth:E.number().int().positive(),enqueuedAt:E.number()}),$p=E.object({sessionId:E.string(),messageId:E.string(),prompt:E.array(E.unknown())}),Op=E.object({sessionId:E.string(),messageId:E.string(),reason:E.enum(["started","cancelled","abandoned"])}),Fr=E.object({sessionId:E.string(),messageId:E.string()}),Np=E.object({cancelled:E.boolean(),reason:E.enum(["ok","not_found","already_running"])}),$r=E.object({sessionId:E.string(),messageId:E.string(),prompt:E.array(E.unknown())}),Hp=E.object({updated:E.boolean(),reason:E.enum(["ok","not_found","already_running"])}),Or=E.object({sessionId:E.string(),targetMessageId:E.string(),prompt:E.array(E.unknown()),replaceQueue:E.boolean().optional(),onTargetCompleted:E.enum(["reject","send_anyway"]).optional()}),jp=E.object({amended:E.boolean(),reason:E.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:E.string().optional()}),Bp=E.object({sessionId:E.string(),cancelledMessageId:E.string(),newMessageId:E.string(),prompt:E.array(E.unknown()),originator:_r,amendedAt:E.number()});import{z as xe}from"zod";var Lp=xe.object({agentId:xe.string(),version:xe.string(),source:xe.enum(["binary","npm"]),phase:xe.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:xe.number().optional(),totalBytes:xe.number().optional(),packageSpec:xe.string().optional()}),Nr="hydra-acp/agents/install_progress",ze={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function Hr(n,e){let t="",s=[],r=[],i=!1,o=a=>{if(!i){i=!0;for(let d of r)d(a)}};return n.setEncoding("utf8"),n.on("data",a=>{t+=a;let d=t.indexOf(`
2
+ var Fa=Object.defineProperty;var Bt=(n,e)=>()=>(n&&(e=n(n=0)),e);var Oa=(n,e)=>{for(var t in e)Fa(n,t,{get:e[t],enumerable:!0})};import*as H from"path";import*as Bn from"os";function $e(n){let e=Bn.homedir();return e?n===e?"~":n.startsWith(e+"/")?"~"+n.slice(e.length):n:n}function Ha(){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 j(){let n=process.env[Na];if(n&&n.length>0)return H.resolve(n);let e=Ha();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 H.join(Bn.homedir(),".hydra-acp")}var Na,I,W=Bt(()=>{"use strict";Na="HYDRA_ACP_HOME";I={home:j,config:()=>H.join(j(),"config.json"),authToken:()=>H.join(j(),"auth-token"),remotes:()=>H.join(j(),"remotes.json"),pidFile:()=>H.join(j(),"daemon.pid"),logFile:()=>H.join(j(),"daemon.log"),currentLogFile:()=>H.join(j(),"current.log"),registryCache:()=>H.join(j(),"registry.json"),themesDir:()=>H.join(j(),"themes"),ttySessionDir:()=>H.join(j(),"tty"),ttySessionFile:n=>H.join(j(),"tty",n),agentsDir:()=>H.join(j(),"agents"),agentLogFile:n=>H.join(j(),"agents","logs",`${n}.log`),agentInstallDir:(n,e,t)=>H.join(j(),"agents",e,n,t),agentNpmInstallDir:(n,e,t)=>H.join(j(),"agents",e,n,t,`node${process.versions.modules}`),sessionsDir:()=>H.join(j(),"sessions"),sessionDir:n=>H.join(j(),"sessions",n),sessionFile:n=>H.join(j(),"sessions",n,"meta.json"),historyFile:n=>H.join(j(),"sessions",n,"history.jsonl"),historyArchiveFile:(n,e)=>H.join(j(),"sessions",n,`history.jsonl.${e}`),toolsDir:n=>H.join(j(),"sessions",n,"tools"),toolBlobFile:(n,e)=>H.join(j(),"sessions",n,"tools",e),queueFile:n=>H.join(j(),"sessions",n,"queue.ndjson"),tombstonesDir:()=>H.join(j(),"sessions",".tombstones"),tombstoneAgentDir:n=>H.join(j(),"sessions",".tombstones",encodeURIComponent(n)),tombstoneFile:(n,e)=>H.join(j(),"sessions",".tombstones",encodeURIComponent(n),encodeURIComponent(e)),extensionsDir:()=>H.join(j(),"extensions"),extensionLogDir:n=>H.join(j(),"extensions",n),extensionLogFile:n=>H.join(j(),"extensions",n,"current.log"),extensionPidFile:n=>H.join(j(),"extensions",n,"extension.pid"),transformersDir:()=>H.join(j(),"transformers"),transformerLogDir:n=>H.join(j(),"transformers",n),transformerLogFile:n=>H.join(j(),"transformers",n,"current.log"),transformerPidFile:n=>H.join(j(),"transformers",n,"transformer.pid"),transformerState:(n,e)=>H.join(j(),"sessions",n,"transformer-state",e),tuiHistoryFile:n=>H.join(j(),"sessions",n,"prompt-history"),globalTuiHistoryFile:()=>H.join(j(),"prompt-history"),tuiLogFile:()=>H.join(j(),"tui.log"),shimWireLogFile:()=>H.join(j(),"shim-wire.log")}});import*as G from"fs/promises";import*as nr from"fs";import*as de from"path";import{randomBytes as Ba}from"crypto";async function ce(n,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
3
+ `;await Ua(n,r,t)}async function Ua(n,e,t={}){let s=await Da(n),r=La(s);await G.mkdir(r,{recursive:!0});let o=`${s}.tmp-${process.pid}-${qa()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await G.writeFile(o,e,i),await G.rename(o,s)}catch(i){throw await G.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{nr.chmodSync(s,t.mode)}catch{}}async function Da(n){let e;try{e=await G.lstat(n)}catch(r){if(r.code==="ENOENT")return n;throw r}if(!e.isSymbolicLink())return n;let t=await G.readlink(n),s=de.isAbsolute(t)?t:de.resolve(de.dirname(n),t);try{let r=await G.realpath(de.dirname(s));return de.join(r,de.basename(s))}catch(r){if(r.code==="ENOENT")return s;throw r}}async function ue(n){let e;try{e=await G.readFile(n,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}if(e.trim().length!==0)try{return JSON.parse(e)}catch{return}}function La(n){let e=n.lastIndexOf("/");return e<=0?".":n.slice(0,e)}function qa(){return Ba(4).toString("hex")}var Fe=Bt(()=>{"use strict"});function Hn(n,e){return`${n}:${e}`}var Ia=Bt(()=>{"use strict";W();Fe()});var Ta={};Oa(Ta,{_resetForTests:()=>ap,clearPin:()=>ep,fetchPeerFingerprint:()=>sp,formatFingerprint:()=>Ca,getPin:()=>tp,installGlobalTlsTrust:()=>rp,loadPinsFromStore:()=>np,setPin:()=>Aa,sha256Hex:()=>Ys,wsTlsOptions:()=>ip});import{createHash as Qf}from"crypto";import*as ka from"tls";import{Agent as Gf,Dispatcher as Kf,buildConnector as Yf,getGlobalDispatcher as Xf,setGlobalDispatcher as Zf}from"undici";function Aa(n,e,t){je.set(Hn(n,e),xa(t))}function ep(n,e){je.delete(Hn(n,e))}function tp(n,e){return je.get(Hn(n,e))}function np(n){je.clear();for(let e of n.list())e.entry.pinnedFingerprint&&Aa(e.host,e.port,e.entry.pinnedFingerprint)}async function sp(n,e,t={}){let s=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=ka.connect({host:n,port:e,servername:n,rejectUnauthorized:!1,autoSelectFamily:!0}),a=!1,d=(c,f)=>{if(!a){a=!0,clearTimeout(u);try{i.destroy()}catch{}c?o(c):f&&r(f)}},u=setTimeout(()=>{d(new Error(`TLS connect to ${n}:${e} timed out`))},s);i.once("secureConnect",()=>{let c=i.getPeerCertificate(!1);if(!c||!c.raw){d(new Error(`${n}:${e} did not present a TLS certificate`));return}d(null,Ys(c.raw))}),i.once("error",c=>d(c))})}function Ys(n){return Qf("sha256").update(n).digest("hex")}function Ca(n){let e=xa(n),t=e.match(/.{2}/g);return t?t.join(":"):e}function xa(n){return n.replace(/:/g,"").toLowerCase()}function rp(){if(Ks)return;Ks=!0;let n=Xf(),e=new Gf({connect:Yf({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(s,r)=>Ea(s,r)})}),t=new Kf;t.dispatch=(s,r)=>{let o=op(s.origin);return(o&&Ma(o)?e:n).dispatch(s,r)},t.close=(()=>Promise.all([e.close(),n.close()]).then(()=>{})),t.destroy=(s=>Promise.all([e.destroy(s??null),n.destroy(s??null)]).then(()=>{})),Zf(t)}function op(n){if(!n)return null;try{return new URL(String(n)).hostname}catch{return null}}function Ma(n){for(let e of je.keys())if(Ra(e)?.host===n)return!0;return!1}function Ea(n,e){if(!e||!e.raw)return new Error(`TLS peer ${n} did not present a certificate`);let t=Ys(e.raw);for(let[s,r]of je.entries()){let o=Ra(s);if(o&&o.host===n&&r===t)return}return new Error(`TLS pin mismatch for ${n} (cert sha256 ${Ca(t)})`)}function Ra(n){let e=n.lastIndexOf(":");if(e<0)return null;let t=n.slice(0,e),s=Number(n.slice(e+1));return Number.isInteger(s)?{host:t,port:s}:null}function ip(n){return Ma(n)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>Ea(e,t)}:{autoSelectFamily:!0}}function ap(){je.clear(),Ks=!1}var je,Ks,Pa=Bt(()=>{"use strict";Ia();je=new Map,Ks=!1});W();import*as Ce from"fs/promises";import{homedir as Ln}from"os";import{z as S}from"zod";W();import*as Ue from"fs/promises";function Un(){let n=new Uint8Array(32);crypto.getRandomValues(n);let e="";for(let t of n)e+=t.toString(16).padStart(2,"0");return`hydra_token_${e}`}async function ja(){try{let e=(await Ue.readFile(I.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(n){if(n.code==="ENOENT")return;throw n}}async function Dn(n){await Ue.mkdir(I.home(),{recursive:!0}),await Ue.writeFile(I.authToken(),n+`
4
+ `,{encoding:"utf8",mode:384})}async function tr(){let n=await ja();if(n)return n;let e=Un();return await Dn(e),process.stderr.write(`hydra-acp: initialized ${I.authToken()} with a fresh service token.
5
+ `),e}Fe();var or="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",za=S.object({cert:S.string(),key:S.string()}),ir=55514,Ja=S.object({host:S.string().default("127.0.0.1"),port:S.number().int().positive().default(ir),logLevel:S.enum(["debug","info","warn","error"]).default("info"),tls:za.optional(),sessionIdleTimeoutSeconds:S.number().int().nonnegative().default(3600),sessionHistoryMaxEntries:S.number().int().positive().default(1e4),sessionHistoryArchiveMaxBytes:S.number().int().nonnegative().default(1e7),sessionHistoryArchiveTiers:S.number().int().positive().default(10),agentStderrTailBytes:S.number().int().positive().default(4096),publicHost:S.string().optional(),agentSyncIntervalMinutes:S.number().nonnegative().default(60),scrubEnv:S.array(S.string()).default([]),sessionGcIntervalMinutes:S.number().nonnegative().default(60),sessionGcMaxAgeDays:S.number().positive().default(2)}),Wa=S.object({url:S.string().url().default(or),ttlHours:S.number().positive().default(24),pinned:S.boolean().default(!1)}),Va=S.object({name:S.string().optional(),description:S.string().optional(),command:S.string().optional(),args:S.array(S.string()).optional(),env:S.record(S.string()).optional()}),Qa=S.object({packageSpec:S.string().optional()}),Ga=S.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-y","ctrl-underscore","alt-underscore","escape"]),Ka=S.union([S.string(),S.object({field:S.string().optional(),text:S.string().optional(),maxWidth:S.number().int().positive().optional(),minWidth:S.number().int().nonnegative().optional(),priority:S.number().optional(),prefix:S.string().optional(),suffix:S.string().optional(),separator:S.string().optional(),style:S.string().optional(),onClick:S.string().optional(),onDoubleClick:S.string().optional()}).strict()]),sr=S.array(Ka);function qn(n,e){return S.object({left:sr.default(n),right:sr.default(e)}).default({})}var Ya=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],Xa=["usage"],Za=[],ed=["helpHint"],td=["cwd","title"],nd=["agentModel"],sd=S.object({composer:S.object({top:qn(Ya,Xa),bottom:qn(Za,ed)}).default({}),sessionbar:qn(td,nd),repaintThrottleMs:S.number().int().nonnegative().default(1e3),maxScrollbackLines:S.number().int().positive().default(1e4),mouse:S.boolean().default(!0),inAppSelection:S.boolean().optional(),selectionClipboard:S.enum(["primary","clipboard","both"]).default("both"),openFileCommand:S.union([S.string(),S.array(S.string())]).optional(),logMaxBytes:S.number().int().positive().default(5*1024*1024),cwdColumnMaxWidth:S.number().int().positive().default(32),progressIndicator:S.boolean().default(!0),defaultEnterAction:S.enum(["enqueue","amend"]).default("amend"),showThoughts:S.boolean().default(!0),ambiguousWidth:S.enum(["auto","narrow","wide"]).default("auto"),toolContent:S.enum(["inline","references"]).default("references"),diffContextLines:S.number().int().min(0).default(3),promptHistoryMaxEntries:S.number().int().positive().default(2e3),maxToolItems:S.number().int().nonnegative().default(5),maxPlanItems:S.number().int().nonnegative().default(5),sidebar:S.object({enabled:S.boolean().default(!1),width:S.number().int().positive().optional(),border:S.enum(["none","rule","frame"]).default("frame"),gadgets:S.array(S.string()).default(["activity","sessions","context","queue","todo","files","git","resources","info","tools"])}).default({}),showFileUpdates:S.enum(["none","edit","diff"]).default("edit"),sessionColumns:S.array(S.enum(["session","upstream","host","state","agent","model","age","cwd","title","cost"])).nonempty().optional(),hotkeys:S.record(Ga,S.object({command:S.union([S.string(),S.array(S.string())])})).default({}),theme:S.union([S.string(),S.record(S.string(),S.unknown())]).optional(),themeBackground:S.string().optional()}),rr=S.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),rd=S.object({command:S.array(S.string()).default([]),args:S.array(S.string()).default([]),env:S.record(S.string()).default({}),enabled:S.boolean().default(!0)}),od=S.object({command:S.array(S.string()).default([]),args:S.array(S.string()).default([]),env:S.record(S.string()).default({}),enabled:S.boolean().default(!0)}),id=S.object({daemon:Ja.default({}),registry:Wa.default({url:or,ttlHours:24,pinned:!1}),agents:S.record(S.string(),Va).default({}),agentOverrides:S.record(S.string(),Qa).default({}),defaultAgent:S.string().default("opencode"),defaultModels:S.record(S.string(),S.string()).default({}),synopsisAgent:S.string().optional(),synopsisModel:S.string().optional(),compaction:S.object({agent:S.string().optional(),model:S.string().optional(),tailK:S.number().int().nonnegative().default(20),maxIterations:S.number().int().positive().default(3),contextFraction:S.number().min(0).max(1).default(.5),hardCeilingFraction:S.number().min(0).max(1).default(.85),absoluteFallback:S.number().int().positive().default(2e5),idleBeforePromptMs:S.number().int().nonnegative().default(3e5),modelContextWindows:S.record(S.string(),S.number().int().positive()).default({})}).default({}),defaultCwd:S.string().default("~"),compressToolContent:S.boolean().default(!0),sessionListColdLimit:S.number().int().nonnegative().default(20),extensions:S.record(rr,rd).default({}),transformers:S.record(rr,od).default({}),defaultTransformers:S.array(S.string()).default([]),npmRegistry:S.string().url().optional(),tui:sd.default({})});function ar(n){return Object.entries(n.extensions).map(([e,t])=>({name:e,...t}))}function dr(n){return Object.entries(n.transformers).map(([e,t])=>({name:e,...t}))}async function cr(){return await ad(),await ue(I.config())??{}}async function ad(){let n;try{n=await Ce.lstat(I.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(n.isSymbolicLink())try{await Ce.stat(I.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await Ce.readlink(I.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${I.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 dd(){let n=await cr(),e=n.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let s=!1;try{await Ce.access(I.authToken()),s=!0}catch(r){if(r.code!=="ENOENT")throw r}if(s)throw new Error(`Auth token present in both ${I.authToken()} and ${I.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await Dn(t),delete e.authToken,Object.keys(e).length===0&&delete n.daemon,await ce(I.config(),n,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${I.config()} to ${I.authToken()}.
6
+ `)}async function zn(){return await dd(),id.parse(await cr())}function Z(n){return n==="~"||n==="$HOME"?Ln():n.startsWith("~/")?Ln()+n.slice(1):n.startsWith("$HOME/")?Ln()+n.slice(5):n}import*as wa from"fs";import*as Se from"fs/promises";import*as ba from"net";import*as mt from"path";import*as va from"tls";import Df from"fastify";import Lf from"@fastify/websocket";var ur="acp.v1";function lr(n,e){return n.has(ur)?ur:!1}import ha from"pino";import qf from"pino-roll";var cd={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"],hydra:["HYDRA_TAB_LABEL"]},fr="HYDRA_ACP_SESSION",ud=[fr],ld=[...Object.values(cd).flat(),...ud];function Ut(n,e){return n?{...e??{},[fr]:n}:e}var pr=[];function mr(n){pr=n?[...n]:[]}function fd(n,e){return e.endsWith("*")?n.startsWith(e.slice(0,-1)):n===e}function pd(){return[...ld,...pr]}function Dt(n=process.env){let e=pd(),t={};for(let[s,r]of Object.entries(n))r!==void 0&&(e.some(o=>fd(s,o))||(t[s]=r));return t}W();import*as K from"fs/promises";import{createHash as md}from"crypto";import{gzip as gd,gunzip as hd}from"zlib";import{promisify as gr}from"util";var hr=gr(gd),yd=gr(hd),yr=/^[A-Za-z0-9_-]+$/,wd=/^[a-f0-9]{64}$/,Jn=!0;function wr(n){Jn=n}function Lt(n,e){return yr.test(n)?e===void 0||wd.test(e):!1}function qt(n,e){return`${I.toolBlobFile(n,e)}.gz`}async function Wn(n,e){if(!Lt(n))return null;let t=md("sha256").update(e,"utf8").digest("hex"),s=qt(n,t),r=I.toolBlobFile(n,t);for(let a of[s,r])try{return await K.access(a),t}catch{}await K.mkdir(I.toolsDir(n),{recursive:!0});let o=Jn?s:r,i=Jn?await hr(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await K.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function gt(n,e){if(!Lt(n,e))return null;try{let t=await K.readFile(qt(n,e));return(await yd(t)).toString("utf8")}catch{}try{return await K.readFile(I.toolBlobFile(n,e),"utf8")}catch{return null}}async function br(n,e){if(!Lt(n,e))return null;try{return await K.readFile(qt(n,e))}catch{}try{let t=await K.readFile(I.toolBlobFile(n,e));return await hr(t)}catch{return null}}async function vr(n,e,t){if(!Lt(n,e))return;let s=qt(n,e);try{await K.access(s);return}catch{}await K.mkdir(I.toolsDir(n),{recursive:!0}),await K.writeFile(s,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function Sr(n){yr.test(n)&&await K.rm(I.toolsDir(n),{recursive:!0,force:!0}).catch(()=>{})}W();import*as _r from"fs/promises";import*as Jt from"path";import{z as F}from"zod";Fe();W();import*as kr from"fs";import*as ee from"fs/promises";import*as xe from"path";import{spawn as Ar}from"child_process";import{Readable as bd}from"stream";function me(){let n=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(!(!n||!e))return`${n}-${e}`}function Gn(n,e=me()){if(e)return n[e]}var De=n=>{process.stderr.write(n+`
7
+ `)};function Kn(n){De=n??(e=>process.stderr.write(e+`
8
+ `))}async function Cr(n){if(!n.target.archive)throw new Error(`Agent ${n.agentId} has no archive URL for ${me()??"this platform"}`);if(!n.target.cmd)throw new Error(`Agent ${n.agentId} has no cmd in its binary target`);let e=me();if(!e)throw new Error(`Agent ${n.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=I.agentInstallDir(n.agentId,e,n.version),s=xe.resolve(t,n.target.cmd);if(await Qn(s))return s;if(await vd({agentId:n.agentId,version:n.version,archiveUrl:n.target.archive,installDir:t,onProgress:n.onProgress}),!await Qn(s))throw new Error(`Agent ${n.agentId}: extracted archive did not contain ${n.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await ee.chmod(s,493).catch(()=>{}),s}async function vd(n){await ee.mkdir(xe.dirname(n.installDir),{recursive:!0});let e=await ee.mkdtemp(`${n.installDir}.partial-`);try{De(`hydra-acp: downloading ${n.agentId} from ${n.archiveUrl}`);let t=await Sd({url:n.archiveUrl,dir:e,agentId:n.agentId,version:n.version,onProgress:n.onProgress});De(`hydra-acp: extracting ${n.agentId}`),Le(n.onProgress,{phase:"extract",agentId:n.agentId,version:n.version}),await kd(t,e),await ee.unlink(t).catch(()=>{});try{await ee.rename(e,n.installDir)}catch(s){let r=s;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await Qn(n.installDir)){await ee.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Le(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version});return}throw s}De(`hydra-acp: installed ${n.agentId} to ${n.installDir}`),Le(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version})}catch(t){throw await ee.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Le(n,e){if(n)try{n(e)}catch{}}async function Sd(n){let e=Id(n.url),t=xe.join(n.dir,e),s=await fetch(n.url,{redirect:"follow"});if(!s.ok||!s.body)throw new Error(`Failed to download ${n.url}: HTTP ${s.status} ${s.statusText}`);let r=Number(s.headers.get("content-length")??"0"),o=kr.createWriteStream(t),i=bd.fromWeb(s.body);Le(n.onProgress,{phase:"download_start",agentId:n.agentId,version:n.version,totalBytes:r});let a=0,d=Date.now(),u=0,c=2e3,f=150;return i.on("data",p=>{a+=p.length;let l=Date.now();l-u>=f&&(u=l,Le(n.onProgress,{phase:"download_progress",agentId:n.agentId,version:n.version,receivedBytes:a,totalBytes:r})),l-d>=c&&(d=l,De(Ir(n.agentId,a,r)))}),await new Promise((p,l)=>{i.on("error",l),o.on("error",l),o.on("finish",()=>p()),i.pipe(o)}),De(Ir(n.agentId,a,r,!0)),Le(n.onProgress,{phase:"download_done",agentId:n.agentId,version:n.version,receivedBytes:a,totalBytes:r}),t}function Ir(n,e,t,s=!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: ${s?"downloaded":"downloading"} ${n} ${r}/${i} MB (${a}%)`}return`hydra-acp: ${s?"downloaded":"downloading"} ${n} ${r} MB`}function Id(n){let e=new URL(n);return xe.posix.basename(e.pathname)||"archive"}async function kd(n,e){let t=n.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await Vn("tar",["-xf",n,"-C",e]);return}if(t.endsWith(".zip")){if(await Ad("unzip")){await Vn("unzip",["-q",n,"-d",e]);return}await Vn("tar",["-xf",n,"-C",e]);return}throw new Error(`Unsupported archive format: ${n}`)}function Vn(n,e){return new Promise((t,s)=>{let r=Ar(n,e,{stdio:["ignore","ignore","inherit"]});r.on("error",s),r.on("exit",(o,i)=>{if(o===0){t();return}s(new Error(`${n} ${e.join(" ")} exited with ${o!==null?`code ${o}`:`signal ${i}`}`))})})}async function Ad(n){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",s=Ar(t,[n],{stdio:"ignore"});s.on("error",()=>e(!1)),s.on("exit",r=>e(r===0))})}async function Qn(n){try{return await ee.access(n),!0}catch{return!1}}W();import*as se from"fs/promises";import*as ge from"path";import{spawn as Cd}from"child_process";var Xn=n=>{process.stderr.write(n+`
9
+ `)};function Zn(n){Xn=n??(e=>process.stderr.write(e+`
10
+ `))}async function Mr(n){let e=me();if(!e)throw new Error(`Agent ${n.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=I.agentNpmInstallDir(n.agentId,e,n.version),s=Td(n.packageSpec),r=Pd(s),o={installDir:t,packageName:s,hint:n.bin,basename:r},i=ge.join(t,"node_modules",".bin",n.bin);if(await Oe(i))return i;if(await Oe(t)){let f=await xr(o);if(f)return f.binPath}await xd({agentId:n.agentId,version:n.version,packageSpec:n.packageSpec,installDir:t,registry:n.registry,onProgress:n.onProgress});let a=await xr(o);if(a)return a.binPath;let d=await Rr(t,s),u=typeof d=="object"&&d!==null?Object.keys(d):typeof d=="string"?[r]:[],c=u.length>0?` (package declares bins: ${u.join(", ")})`:"";throw new Error(`Agent ${n.agentId}: npm install of ${n.packageSpec} did not produce bin ${n.bin} (looked in ${t}/node_modules/.bin/)${c}`)}async function xd(n){await se.mkdir(ge.dirname(n.installDir),{recursive:!0});let e=await se.mkdtemp(`${n.installDir}.partial-`);try{Xn(`hydra-acp: installing ${n.packageSpec} for ${n.agentId} into ${e}`),Yn(n.onProgress,{phase:"install_start",agentId:n.agentId,version:n.version,packageSpec:n.packageSpec}),await Rd({packageSpec:n.packageSpec,cwd:e,registry:n.registry});try{await se.rename(e,n.installDir)}catch(t){let s=t;if((s.code==="EEXIST"||s.code==="ENOTEMPTY")&&await Oe(n.installDir)){await se.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Yn(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version});return}throw t}Xn(`hydra-acp: installed ${n.agentId} to ${n.installDir}`),Yn(n.onProgress,{phase:"installed",agentId:n.agentId,version:n.version})}catch(t){throw await se.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Yn(n,e){if(n)try{n(e)}catch{}}var Md=5,Ed=25;function Rd(n){return Er(n,0)}async function Er(n,e){try{await new Promise((t,s)=>{let r=n.registry?["--registry",n.registry]:[],o;try{o=Cd("npm",["install","--no-audit","--no-fund","--silent",...r,n.packageSpec],{cwd:n.cwd,stdio:["ignore","pipe","pipe"]})}catch(a){s(a);return}let i="";o.stdout?.on("data",a=>{}),o.stderr?.setEncoding("utf8"),o.stderr?.on("data",a=>{i=(i+a).slice(-4096)}),o.on("error",a=>{if(a.code==="ENOENT"){s(new Error("npm not found on PATH (install Node.js / npm, or use a binary-distributed agent)"));return}s(a)}),o.on("exit",(a,d)=>{if(a===0){t();return}let u=a!==null?`exit code ${a}`:`signal ${d??"unknown"}`,c=i.trim();s(new Error(c?`npm install ${n.packageSpec} failed (${u})
11
+ stderr: ${c}`:`npm install ${n.packageSpec} failed (${u})`))})})}catch(t){if(t.code==="ETXTBSY"&&e<Md)return await new Promise(r=>setTimeout(r,Ed*(e+1))),Er(n,e+1);throw t}}function Td(n){if(n.startsWith("@")){let t=n.indexOf("/");if(t===-1)return n;let r=n.slice(t+1).indexOf("@");return r===-1?n:n.slice(0,t+1+r)}let e=n.indexOf("@");return e<=0?n:n.slice(0,e)}function Pd(n){let e=n.lastIndexOf("/");return e===-1?n:n.slice(e+1)}async function Rr(n,e){let t=ge.join(n,"node_modules",e,"package.json");try{let s=await se.readFile(t,"utf8"),r=JSON.parse(s);return typeof r.bin=="string"||typeof r.bin=="object"&&r.bin!==null&&!Array.isArray(r.bin)?r.bin:void 0}catch{return}}async function xr(n){let e=ge.join(n.installDir,"node_modules",".bin"),t=ge.join(e,n.hint);if(await Oe(t))return{binName:n.hint,binPath:t};let s=await Rr(n.installDir,n.packageName);if(typeof s=="object"&&s!==null){let r=Object.keys(s);if(r.length===1){let o=r[0],i=ge.join(e,o);if(await Oe(i))return{binName:o,binPath:i}}else if(r.length>1){for(let o of[n.hint,n.basename])if(r.includes(o)){let i=ge.join(e,o);if(await Oe(i))return{binName:o,binPath:i}}}}if(n.basename!==n.hint){let r=ge.join(e,n.basename);if(await Oe(r))return{binName:n.basename,binPath:r}}}async function Oe(n){try{return await se.access(n),!0}catch{return!1}}var _d=F.object({package:F.string(),bin:F.string().optional(),args:F.array(F.string()).optional(),env:F.record(F.string()).optional()}),qe=F.object({archive:F.string().url().optional(),cmd:F.string().optional(),args:F.array(F.string()).optional(),env:F.record(F.string()).optional()}),$d=F.object({"darwin-aarch64":qe.optional(),"darwin-x86_64":qe.optional(),"linux-aarch64":qe.optional(),"linux-x86_64":qe.optional(),"windows-x86_64":qe.optional(),"windows-aarch64":qe.optional()}),Fd=F.object({package:F.string(),args:F.array(F.string()).optional(),env:F.record(F.string()).optional()}),Od=F.object({command:F.string(),args:F.array(F.string()).optional(),env:F.record(F.string()).optional()}),Nd=F.object({command:F.string().optional(),url:F.string().optional(),description:F.string().optional()}),Hd=F.object({npx:_d.optional(),binary:$d.optional(),uvx:Fd.optional(),exec:Od.optional()}),jd=F.object({id:F.string(),name:F.string(),version:F.string().optional(),description:F.string().optional(),authors:F.array(F.string()).optional(),license:F.string().optional(),icon:F.string().optional(),repository:F.string().optional(),website:F.string().optional(),distribution:Hd,onboarding:Nd.optional(),requiredEnv:F.array(F.string().min(1)).optional()}),Tr=F.object({version:F.string(),agents:F.array(jd),extensions:F.array(F.unknown()).optional()}),zt=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)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}async getAgent(e){let t=this.localAgents(),s=t.find(u=>u.id===e)??t.find(u=>u.id.toLowerCase()===`${e.toLowerCase()}-acp`);if(s)return s;let r=await this.load(),o=r.agents.find(u=>u.id===e);if(o)return this.applyOverride(o);let i=r.agents.find(u=>es(u)===e);if(i)return this.applyOverride(i);let a=e.toLowerCase(),d=r.agents.find(u=>u.id.toLowerCase()===`${a}-acp`);if(d)return this.applyOverride(d);if(a.length>0){let u=r.agents.filter(c=>c.id.toLowerCase().startsWith(a));if(u.length===1)return this.applyOverride(u[0])}}localAgents(){return Object.entries(this.config.agents??{}).map(([e,t])=>({id:e,name:t.name??e,description:t.description,version:"local",distribution:{exec:{command:Z(t.command??e),args:t.args?.map(Z),env:t.env}}}))}applyOverride(e){let t=this.config.agentOverrides?.[e.id];return!t?.packageSpec||!e.distribution.npx?e:{...e,version:Bd(t.packageSpec),distribution:{...e.distribution,npx:{...e.distribution.npx,package:t.packageSpec}}}}isPinned(){return this.config.registry?.pinned===!0}isFresh(e){let t=Date.now()-e,s=this.config.registry.ttlHours*60*60*1e3;return t<s}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(),s=Tr.parse(t),r={fetchedAt:Date.now(),raw:t,data:s},o=this.options.onFetched;return o&&Promise.resolve().then(()=>o(s)).catch(()=>{}),r}async readDiskCache(){let e=await ue(I.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=Tr.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await ce(I.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function Bd(n){let e=n.lastIndexOf("@"),s=(e>0?n.slice(e+1):"").replace(/[^a-zA-Z0-9._-]/g,"_");return s.length>0?`pin-${s}`:"pinned"}function es(n){let e=n.distribution.npx?.package;if(!e)return;let t=e.lastIndexOf("/"),s=t===-1?e:e.slice(t+1),r=s.lastIndexOf("@");return r<=0?s:s.slice(0,r)}async function ze(n){let e=typeof n.localAgents=="function"?n.localAgents():[],t;try{t=await n.load()}catch(i){if(e.length===0)throw i;t={version:"local-only",agents:[]}}let s=new Set(e.map(i=>i.id)),r=[...e,...t.agents.filter(i=>!s.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 ts(i),source:s.has(i.id)?"local":"registry",...i.onboarding?{onboarding:i.onboarding}:{}})));return{version:t.version,fetchedAt:n.lastFetchedAt(),agents:o}}async function ts(n){let e=me();if(!e)return"no";let t=n.version??"current";if(n.distribution.exec)return"yes";if(n.distribution.binary){let s=Gn(n.distribution.binary,e);if(s?.cmd){let r=Jt.resolve(I.agentInstallDir(n.id,e,t),s.cmd);if(await Pr(r))return"yes"}}if(n.distribution.npx){let s=n.distribution.npx,r=s.bin??es(n)??s.package,o=I.agentNpmInstallDir(n.id,e,t),i=Jt.join(o,"node_modules",".bin",r);if(await Pr(i))return"yes"}return!n.distribution.npx&&!n.distribution.binary&&n.distribution.uvx?"lazy":"no"}async function Pr(n){try{return await _r.access(n),!0}catch{return!1}}async function ie(n,e=[],t={}){let s=n.version??"current";if(n.distribution.npx){let r=n.distribution.npx,o=e.length>0?e:r.args??[];if(process.env.HYDRA_ACP_SKIP_NPM_PREFETCH)return{command:"npx",args:["-y",r.package,...o],env:r.env??{},version:s};let i=r.bin??es(n)??r.package,a=t.onInstallProgress;return{command:await Mr({agentId:n.id,version:s,packageSpec:r.package,bin:i,registry:t.npmRegistry,onProgress:a?u=>a({source:"npm",...u}):void 0}),args:o,env:r.env??{},version:s}}if(n.distribution.binary){let r=Gn(n.distribution.binary);if(!r)throw new Error(`Agent ${n.id} has no binary distribution for ${me()??"this platform"}.`);let o=t.onInstallProgress,i=await Cr({agentId:n.id,version:s,target:r,onProgress:o?d=>o({source:"binary",...d}):void 0}),a=e.length>0?e:r.args??[];return{command:i,args:a,env:r.env??{},version:s}}if(n.distribution.uvx){let r=n.distribution.uvx,o=e.length>0?e:r.args??[];return{command:"uvx",args:[r.package,...o],env:r.env??{},version:s}}if(n.distribution.exec){let r=n.distribution.exec,o=e.length>0?e:r.args??[];return{command:r.command,args:o,env:r.env??{},version:s}}throw new Error(`Agent ${n.id} has no usable distribution method.`)}import{spawn as zd}from"child_process";import*as Qt from"fs";import*as Vr from"path";var k={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,AuthRequired:-32e3,SessionNotFound:-32001,NotAuthorisedToAttach:-32002,MultiClientNotSupported:-32003,AgentNotInstalled:-32005,BundleAlreadyImported:-32010,PermissionDenied:-32011,AlreadyAttached:-32012,StreamNotEnabled:-32013,SessionClosing:-32014};import{z as q}from"zod";var $r=q.object({protocolVersion:q.number().optional(),clientCapabilities:q.record(q.unknown()).optional(),clientInfo:q.object({name:q.string(),version:q.string().optional()}).optional()}),Ud=q.enum(["full","pending_only","none","after_message"]),Fr=q.object({cwd:q.string(),mcpServers:q.array(q.unknown()).optional(),_meta:q.record(q.unknown()).optional()}),Or=q.object({upstreamSessionId:q.string(),agentId:q.string(),cwd:q.string(),title:q.string().optional(),agentArgs:q.array(q.string()).optional()}),Nr=q.object({sessionId:q.string(),historyPolicy:Ud.default("full"),afterMessageId:q.string().optional(),clientId:q.string().optional(),clientInfo:q.object({name:q.string(),version:q.string().optional()}).optional(),_meta:q.record(q.unknown()).optional()});import{z as N}from"zod";var Hr=N.object({sessionId:N.string()}),jr=N.object({cwd:N.string().optional(),cursor:N.string().optional()}),ns=N.object({used:N.number().optional(),size:N.number().optional(),costAmount:N.number().optional(),costCurrency:N.string().optional()}),Gp=N.object({sessionId:N.string(),upstreamSessionId:N.string().optional(),cwd:N.string(),title:N.string().optional(),agentId:N.string().optional(),currentModel:N.string().optional(),currentUsage:ns.optional(),importedFromMachine:N.string().optional(),importedFromUpstreamSessionId:N.string().optional(),parentSessionId:N.string().optional(),forkedFromSessionId:N.string().optional(),forkedFromMessageId:N.string().optional(),originatingClient:N.object({name:N.string(),version:N.string().optional()}).optional(),interactive:N.boolean().optional(),priority:N.number().int().nonnegative().optional(),updatedAt:N.string(),attachedClients:N.number().int().nonnegative(),status:N.enum(["warm","cold"]).default("warm"),busy:N.boolean().default(!1),awaitingInput:N.boolean().default(!1),compactionState:N.any().optional(),agentPid:N.number().int().positive().optional(),forkSynthesisState:N.enum(["running","failed"]).optional(),_meta:N.record(N.unknown()).optional()}),Dd=N.object({sessionId:N.string(),cwd:N.string(),title:N.string().optional(),updatedAt:N.string().optional(),_meta:N.record(N.unknown()).optional()}),Kp=N.object({sessions:N.array(Dd),nextCursor:N.string().optional()});function Wt(n,e){let t={attachedClients:n.attachedClients,status:n.status,busy:n.busy,awaitingInput:n.awaitingInput};return n.cwd!==void 0&&(t.cwd=n.cwd),n.title!==void 0&&(t.title=n.title),n.agentId!==void 0&&(t.agentId=n.agentId),n.upstreamSessionId!==void 0&&(t.upstreamSessionId=n.upstreamSessionId),n.currentModel!==void 0&&(t.currentModel=n.currentModel),n.currentUsage!==void 0&&(t.currentUsage=n.currentUsage),n.importedFromMachine!==void 0&&(t.importedFromMachine=n.importedFromMachine),n.importedFromUpstreamSessionId!==void 0&&(t.importedFromUpstreamSessionId=n.importedFromUpstreamSessionId),n.parentSessionId!==void 0&&(t.parentSessionId=n.parentSessionId),n.forkedFromSessionId!==void 0&&(t.forkedFromSessionId=n.forkedFromSessionId),n.forkedFromMessageId!==void 0&&(t.forkedFromMessageId=n.forkedFromMessageId),n.originatingClient!==void 0&&(t.originatingClient=n.originatingClient),n.interactive!==void 0&&(t.interactive=n.interactive),n.priority!==void 0&&n.priority>0&&(t.priority=n.priority),n.compactionState!==void 0&&(t.compactionState=n.compactionState),n.forkSynthesisState!==void 0&&(t.forkSynthesisState=n.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)),t}function Br(n){let e={sessionId:n.sessionId,cwd:n.cwd,updatedAt:n.updatedAt,_meta:ht(n._meta,Wt(n))};return n.title!==void 0&&(e.title=n.title),e}var le="hydra-acp";function Ld(n){if(!n||typeof n!="object"||Array.isArray(n))return;let e={};for(let[t,s]of Object.entries(n)){if(typeof t!="string"||t.length===0||typeof s!="string")return;e[t]=s}return e}function Je(n){if(!n)return{};let e=n[le];if(!e||typeof e!="object"||Array.isArray(e))return{};let t=e,s={};if(typeof t.upstreamSessionId=="string"&&(s.upstreamSessionId=t.upstreamSessionId),typeof t.agentId=="string"&&(s.agentId=t.agentId),typeof t.cwd=="string"&&(s.cwd=t.cwd),typeof t.clientId=="string"&&(s.clientId=t.clientId),typeof t.readonly=="boolean"&&(s.readonly=t.readonly),(t.replayMode==="instant"||t.replayMode==="drip")&&(s.replayMode=t.replayMode),typeof t.dripSpeed=="number"&&t.dripSpeed>0&&(s.dripSpeed=t.dripSpeed),(t.toolContent==="inline"||t.toolContent==="references")&&(s.toolContent=t.toolContent),t.detachStatus==="detached"&&(s.detachStatus=t.detachStatus),typeof t.title=="string"&&(s.title=t.title),Array.isArray(t.agentArgs)&&t.agentArgs.every(r=>typeof r=="string")&&(s.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(r=>typeof r=="string")&&(s.transformers=t.transformers),t.resume){let r=Or.safeParse(t.resume);r.success&&(s.resume=r.data)}if(typeof t.model=="string"&&(s.model=t.model),typeof t.currentModel=="string"&&(s.currentModel=t.currentModel),typeof t.currentMode=="string"&&(s.currentMode=t.currentMode),t.currentUsage){let r=ns.safeParse(t.currentUsage);r.success&&(s.currentUsage=r.data)}if(typeof t.turnStartedAt=="number"&&t.turnStartedAt>0&&(s.turnStartedAt=t.turnStartedAt),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&&(s.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),s.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),s.agents=o}if(typeof t.mcpStdin=="boolean"&&(s.mcpStdin=t.mcpStdin),typeof t.interactive=="boolean"&&(s.interactive=t.interactive),typeof t.ancillary=="boolean"&&(s.ancillary=t.ancillary),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&&(s.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&&(s.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&&(s.availableModels=r)}if((t.status==="warm"||t.status==="cold")&&(s.status=t.status),typeof t.busy=="boolean"&&(s.busy=t.busy),typeof t.awaitingInput=="boolean"&&(s.awaitingInput=t.awaitingInput),typeof t.attachedClients=="number"&&(s.attachedClients=t.attachedClients),typeof t.resurrected=="boolean"&&(s.resurrected=t.resurrected),typeof t.importedFromMachine=="string"&&(s.importedFromMachine=t.importedFromMachine),typeof t.importedFromUpstreamSessionId=="string"&&(s.importedFromUpstreamSessionId=t.importedFromUpstreamSessionId),typeof t.parentSessionId=="string"&&(s.parentSessionId=t.parentSessionId),typeof t.forkedFromSessionId=="string"&&(s.forkedFromSessionId=t.forkedFromSessionId),typeof t.forkedFromMessageId=="string"&&(s.forkedFromMessageId=t.forkedFromMessageId),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let r=t.originatingClient;s.originatingClient={name:r.name,...typeof r.version=="string"?{version:r.version}:{}}}if(t.agentCapabilities!==void 0&&(s.agentCapabilities=t.agentCapabilities),t.env!==void 0){let r=Ld(t.env);r!==void 0&&(s.env=r)}return s}function Me(n,e){if(typeof e!="number"||!Number.isFinite(e)||!n||typeof n!="object"||Array.isArray(n))return n;let t=n,s=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=s[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?n:{...t,_meta:{...s,[le]:{...o,recordedAt:e}}}}function ht(n,e){return{...n??{},[le]:e}}import{z as R}from"zod";var Ur=R.object({sessionId:R.string(),prompt:R.array(R.unknown()),_meta:R.record(R.unknown()).optional()}),Vt=R.object({sessionId:R.string()}),Dr=R.object({clientId:R.string(),name:R.string().optional(),version:R.string().optional()}),nm=R.object({sessionId:R.string(),messageId:R.string(),originator:Dr,prompt:R.array(R.unknown()),position:R.number().int().nonnegative(),queueDepth:R.number().int().positive(),enqueuedAt:R.number()}),sm=R.object({sessionId:R.string(),messageId:R.string(),prompt:R.array(R.unknown())}),rm=R.object({sessionId:R.string(),messageId:R.string(),reason:R.enum(["started","cancelled","abandoned"])}),Lr=R.object({sessionId:R.string(),messageId:R.string()}),om=R.object({cancelled:R.boolean(),reason:R.enum(["ok","not_found","already_running"])}),qr=R.object({sessionId:R.string(),messageId:R.string(),prompt:R.array(R.unknown())}),im=R.object({updated:R.boolean(),reason:R.enum(["ok","not_found","already_running"])}),zr=R.object({sessionId:R.string(),targetMessageId:R.string(),prompt:R.array(R.unknown()),replaceQueue:R.boolean().optional(),onTargetCompleted:R.enum(["reject","send_anyway"]).optional()}),am=R.object({amended:R.boolean(),reason:R.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:R.string().optional()}),dm=R.object({sessionId:R.string(),cancelledMessageId:R.string(),newMessageId:R.string(),prompt:R.array(R.unknown()),originator:Dr,amendedAt:R.number()});import{z as Ee}from"zod";var lm=Ee.object({agentId:Ee.string(),version:Ee.string(),source:Ee.enum(["binary","npm"]),phase:Ee.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:Ee.number().optional(),totalBytes:Ee.number().optional(),packageSpec:Ee.string().optional()}),Jr="hydra-acp/agents/install_progress",We={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function Wr(n,e){let t="",s=[],r=[],o=!1,i=a=>{if(!o){o=!0;for(let d of r)d(a)}};return n.setEncoding("utf8"),n.on("data",a=>{t+=a;let d=t.indexOf(`
12
12
  `);for(;d!==-1;){let u=t.slice(0,d).trim();if(t=t.slice(d+1),u.length>0)try{let c=JSON.parse(u);for(let f of s)f(c)}catch(c){for(let f of s)f({jsonrpc:"2.0",id:null,error:{code:k.ParseError,message:`Failed to parse ndjson line: ${c.message}`}})}d=t.indexOf(`
13
- `)}}),n.on("end",()=>o()),n.on("error",a=>o(a)),e.on("error",a=>o(a)),{async send(a){if(i)throw new Error("stream is closed");let d=JSON.stringify(a)+`
14
- `;await new Promise((u,c)=>{e.write(d,f=>{if(f){c(f);return}u()})})},onMessage(a){s.push(a)},onClose(a){r.push(a)},async close(){e.end(),o()}}}import{nanoid as Ad}from"nanoid";var Xn=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},Je=class n{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 s=this.bufferedNotifications.get(e);if(s){this.bufferedNotifications.delete(e);for(let r of s)try{t(r.params,r.method)}catch{}}}drainBuffered(e){let s=this.bufferedNotifications.get(e)?.length??0;return this.bufferedNotifications.delete(e),s}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 Xn;let s=Ad(),r={jsonrpc:"2.0",id:s,method:e,params:t},i=new Promise((o,a)=>{this.pending.set(s,{resolve:d=>o(d),reject:a}),this.stream.send(r).catch(d=>{this.pending.delete(s),a(d)})});return{id:s,response:i}}notify(e,t){if(this.closed)return Promise.resolve();let s={jsonrpc:"2.0",method:e,params:t};return this.stream.send(s)}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:k.MethodNotFound,message:`Method not found: ${e.method}`}).catch(()=>{});return}try{let s=await t(e.params,e.method),r={jsonrpc:"2.0",id:e.id,result:s};await this.stream.send(r).catch(()=>{})}catch(s){let r=s;await this.sendError(e.id,{code:r.code??k.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 s=this.bufferedNotifications.get(e.method);if(!s){if(this.bufferedNotifications.size>=n.MAX_BUFFERED_METHODS){let r=this.bufferedNotifications.keys().next().value;r!==void 0&&this.bufferedNotifications.delete(r)}s=[],this.bufferedNotifications.set(e.method,s)}s.push(e),s.length>n.MAX_BUFFERED_PER_METHOD&&s.shift()}handleResponse(e){let t=e.id===null?void 0:this.pending.get(e.id);if(!t){if(e.error)for(let s of this.orphanErrorHandlers)try{s({code:e.error.code,message:e.error.message,data:e.error.data})}catch{}return}if(this.pending.delete(e.id),e.error){let s=new Error(e.error.message);s.code=e.error.code,s.data=e.error.data,t.reject(s)}else t.resolve(e.result)}async sendError(e,t){let s={jsonrpc:"2.0",id:e,error:t};await this.stream.send(s)}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)}}};W();var xd=4096,Re=class n{agentId;version;cwd;connection;authMethods;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.cwd=e.cwd,this.child=t,this.stderrTailBytes=e.stderrTailBytes??xd,this.killEscalationMs=e.killEscalationMs??Rd,this.logger=e.logger,this.fileLog=Ed(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()} ---
15
- `),!t.stdout||!t.stdin)throw new Error("agent subprocess missing stdio");let s=Hr(t.stdout,t.stdin);this.connection=new Je(s),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 i of r.split(/\r?\n/))i.length>0&&this.logger.info(`[${e.agentId}] ${i}`);else process.stderr.write(`[${e.agentId}] ${r}`)}),t.on("error",r=>{let i=this.formatFailure(r.message);this.writeLog(`--- spawn error: ${r.message} time=${new Date().toISOString()} ---
16
- `),this.connection.fail(new Error(i))}),t.on("exit",(r,i)=>{if(this.exited=!0,this.writeLog(`--- exit code=${r} signal=${i} ${this.killed?"(after kill) ":""}time=${new Date().toISOString()} ---
17
- `),this.fileLog?.end(),this.fileLog=void 0,this.killed)this.logger?.info(`agent ${e.agentId} pid=${t.pid} exited after kill code=${r} signal=${i}`);else{let o=`agent ${e.agentId} exited before responding (code=${r} signal=${i})`;this.connection.fail(new Error(this.formatFailure(o))),this.logger?.warn(`agent ${e.agentId} pid=${t.pid} exited unexpectedly code=${r} signal=${i}`)}for(let o of this.exitHandlers)o(r,i)})}writeLog(e){if(this.fileLog)try{this.fileLog.write(e)}catch{}}formatFailure(e){let t=this.stderrTail.trim();return t?`${e}
18
- stderr: ${t}`:e}stderrTailText(){return this.stderrTail.trim()}static spawn(e){let t={...Nt(),...e.plan.env,...e.extraEnv??{}},s=Cd(e.plan.command,e.plan.args,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],detached:!0});return s.unref(),new n(e,s)}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()} ---
13
+ `)}}),n.on("end",()=>i()),n.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)+`
14
+ `;await new Promise((u,c)=>{e.write(d,f=>{if(f){c(f);return}u()})})},onMessage(a){s.push(a)},onClose(a){r.push(a)},async close(){e.end(),i()}}}import{nanoid as qd}from"nanoid";var ss=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},Ve=class n{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 s=this.bufferedNotifications.get(e);if(s){this.bufferedNotifications.delete(e);for(let r of s)try{t(r.params,r.method)}catch{}}}drainBuffered(e){let s=this.bufferedNotifications.get(e)?.length??0;return this.bufferedNotifications.delete(e),s}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 ss;let s=qd(),r={jsonrpc:"2.0",id:s,method:e,params:t},o=new Promise((i,a)=>{this.pending.set(s,{resolve:d=>i(d),reject:a}),this.stream.send(r).catch(d=>{this.pending.delete(s),a(d)})});return{id:s,response:o}}notify(e,t){if(this.closed)return Promise.resolve();let s={jsonrpc:"2.0",method:e,params:t};return this.stream.send(s)}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:k.MethodNotFound,message:`Method not found: ${e.method}`}).catch(()=>{});return}try{let s=await t(e.params,e.method),r={jsonrpc:"2.0",id:e.id,result:s};await this.stream.send(r).catch(()=>{})}catch(s){let r=s;await this.sendError(e.id,{code:r.code??k.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 s=this.bufferedNotifications.get(e.method);if(!s){if(this.bufferedNotifications.size>=n.MAX_BUFFERED_METHODS){let r=this.bufferedNotifications.keys().next().value;r!==void 0&&this.bufferedNotifications.delete(r)}s=[],this.bufferedNotifications.set(e.method,s)}s.push(e),s.length>n.MAX_BUFFERED_PER_METHOD&&s.shift()}handleResponse(e){let t=e.id===null?void 0:this.pending.get(e.id);if(!t){if(e.error)for(let s of this.orphanErrorHandlers)try{s({code:e.error.code,message:e.error.message,data:e.error.data})}catch{}return}if(this.pending.delete(e.id),e.error){let s=new Error(e.error.message);s.code=e.error.code,s.data=e.error.data,t.reject(s)}else t.resolve(e.result)}async sendError(e,t){let s={jsonrpc:"2.0",id:e,error:t};await this.stream.send(s)}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)}}};W();var Jd=4096,Re=class n{agentId;version;cwd;connection;authMethods;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.cwd=e.cwd,this.child=t,this.stderrTailBytes=e.stderrTailBytes??Jd,this.killEscalationMs=e.killEscalationMs??Wd,this.logger=e.logger,this.fileLog=Vd(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()} ---
15
+ `),!t.stdout||!t.stdin)throw new Error("agent subprocess missing stdio");let s=Wr(t.stdout,t.stdin);this.connection=new Ve(s),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()} ---
16
+ `),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()} ---
17
+ `),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}
18
+ stderr: ${t}`:e}stderrTailText(){return this.stderrTail.trim()}static spawn(e){let t={...Dt(),...e.plan.env,...e.extraEnv??{}},s=zd(e.plan.command,e.plan.args,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],detached:!0});return s.unref(),new n(e,s)}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()} ---
19
19
  `),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()} ---
20
- `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(this.killEscalationMs)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0)try{process.kill(-t,e)}catch{try{this.child.kill(e)}catch{}}}waitForExit(e){return this.exited?Promise.resolve():new Promise(t=>{let s=setTimeout(()=>{this.child.off("exit",r),t()},e),r=()=>{clearTimeout(s),t()};this.child.once("exit",r)})}},Rd=2e3;function Ed(n){try{let e=I.agentLogFile(n);qt.mkdirSync(jr.dirname(e),{recursive:!0});let t=qt.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}import*as Oe from"fs/promises";import*as Di from"os";import*as Br from"os";function gt(){return Br.hostname()}import*as xt from"path";import{customAlphabet as eu}from"nanoid";async function We(n){let{agent:e,upstreamSessionId:t,persistedMode:s,agentReportedMode:r,advertisedModes:i,logger:o}=n;if(!s)return r;if(s===r)return s;if(i&&i.length>0&&!i.some(a=>a.id===s)){let a=i.map(d=>d.id).join(", ");return o?.warn(`resurrect: persisted currentMode=${JSON.stringify(s)} not in agent's availableModes ([${a}]); skipping session/set_mode, session will use ${JSON.stringify(r)}`),r}try{return o?.info(`resurrect: pushing persisted modeId=${JSON.stringify(s)} to agent (agentReported=${JSON.stringify(r)})`),await e.connection.request("session/set_mode",{sessionId:t,modeId:s}),o?.info(`resurrect: session/set_mode accepted, effectiveMode=${JSON.stringify(s)}`),s}catch(a){return o?.warn(`resurrect: session/set_mode rejected by agent for modeId=${JSON.stringify(s)} (${a.message}); session will use ${JSON.stringify(r)}`),r}}async function Qe(n){let{agent:e,upstreamSessionId:t,persistedModel:s,agentReportedModel:r,logger:i}=n;if(!s)return r;if(s===r)return s;try{return i?.info(`resurrect: pushing persisted modelId=${JSON.stringify(s)} to agent (agentReported=${JSON.stringify(r)})`),await e.connection.request("session/set_model",{sessionId:t,modelId:s}),i?.info(`resurrect: session/set_model accepted, effectiveModel=${JSON.stringify(s)}`),s}catch(o){return i?.warn(`resurrect: session/set_model rejected by agent for modelId=${JSON.stringify(s)} (${o.message}); session will use ${JSON.stringify(r)}`),r}}import{customAlphabet as ni}from"nanoid";var Ur="edit",zt=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 Dr(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(t===null||typeof t!="object")continue;let s=t.path;typeof s=="string"&&s.length>0&&e.push(s)}return e}import*as qr from"fs/promises";var Md=64*1024*1024,Pd=1*1024*1024,Ge=64*1024,Td=6e4,_d=100,Fd=1e3,$d=64*1024,Od=256*1024,Lr=20;function Nd(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Jt=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??Md,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Pd,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 s=Math.max(0,Math.min(t,Ge));if(s===0){let f={bytes:Buffer.alloc(0),nextCursor:e};return this.closed&&e>=this.writeCursor&&(f.eof=!0),f}let r=e,i=0,o=this.oldestAvailable;r<o&&(i=o-r,r=o);let a=this.writeCursor-r;if(a<=0){let f={bytes:Buffer.alloc(0),nextCursor:r};return i>0&&(f.gap=i),this.closed&&(f.eof=!0),f}let d=Math.min(a,s),c={bytes:this.sliceFromRing(r,d),nextCursor:r+d};return i>0&&(c.gap=i),this.closed&&r+d>=this.writeCursor&&(c.eof=!0),c}tail(e){let t=Math.max(0,Math.min(e,Ge)),s=this.oldestAvailable,r=this.writeCursor-t,i=Math.max(s,r),o=r<s;return{bytes:this.sliceFromRing(i,this.writeCursor-i),startCursor:i,endCursor:this.writeCursor,truncated:o}}head(e){let t=Math.max(0,Math.min(e,Ge)),s=this.oldestAvailable,r=s>0,i=s,o=Math.min(this.writeCursor,i+t);return{bytes:this.sliceFromRing(i,o-i),startCursor:i,endCursor:o,truncated:r}}waitForData(e,t){if(e<this.writeCursor)return Promise.resolve("data");if(this.closed)return Promise.resolve("eof");let s=Math.max(0,Math.min(t,Td));return s===0?Promise.resolve("timeout"):new Promise(r=>{let i={resolve:o=>{i.timer!==void 0&&(clearTimeout(i.timer),i.timer=void 0),r(o)},timer:setTimeout(()=>{let o=this.waiters.indexOf(i);o>=0&&this.waiters.splice(o,1),i.timer=void 0,r("timeout")},s)};this.waiters.push(i)})}grep(e){let t=this.oldestAvailable,s=e.cursor,r=s??t,i=0;s!==void 0&&s<t&&(i=t-s,r=t),r>this.writeCursor&&(r=this.writeCursor);let o=this.sliceFromRing(r,this.writeCursor-r),a=e.regex??!0,d=e.caseInsensitive===!0?"i":"",u=a?new RegExp(e.pattern,d):new RegExp(Nd(e.pattern),d),c=e.invert??!1,f=Math.max(1,Math.min(e.maxMatches??_d,Fd)),p=Math.max(1,Math.min(e.maxBytes??$d,Od)),l=Math.max(0,Math.min(e.contextBefore??0,Lr)),g=Math.max(0,Math.min(e.contextAfter??0,Lr)),m=[],h=[],y=[],v=0,w=!1,S=0,A=0,C=(_,B)=>{for(let J of y)J.remaining>0&&(J.match.after===void 0&&(J.match.after=[]),J.match.after.push({cursor:_,line:B}),J.remaining--,v+=B.length);for(;y.length>0&&y[0].remaining===0;)y.shift();if(u.test(B)!==c&&m.length<f){let J={cursor:_,line:B};if(l>0&&h.length>0){J.before=h.slice();for(let ne of J.before)v+=ne.line.length}v+=B.length,m.push(J),g>0&&y.push({match:J,remaining:g})}if(l>0)for(h.push({cursor:_,line:B});h.length>l;)h.shift();let P=m.length>=f&&y.length===0,U=v>=p;return P||U};for(let _=0;_<o.length;_++){if(o[_]!==10)continue;let B=o.subarray(S,_).toString("utf8"),F=r+S;if(S=_+1,A=S,C(F,B)){w=!0;break}}if(!w&&S<o.length&&this.closed){let _=o.subarray(S).toString("utf8"),B=r+S;C(B,_)&&(w=!0),A=o.length}let x=Math.min(r+A,this.writeCursor),T={matches:m,truncated:w,nextCursor:x,scannedBytes:A};return i>0&&(T.gap=i),this.closed&&x>=this.writeCursor&&(T.eof=!0),T}wakeWaiters(e){if(this.waiters.length===0)return;let t=this.waiters;this.waiters=[];for(let s of t)s.resolve(e)}growIfNeeded(e){if(this.currentCapacityBytes>=this.maxCapacityBytes)return;let t=this.writeCursor+e;if(t<=this.currentCapacityBytes)return;let s=this.currentCapacityBytes;for(;s<t&&s<this.maxCapacityBytes;)s=Math.min(this.maxCapacityBytes,s*2);if(s===this.currentCapacityBytes)return;let r=Buffer.alloc(s);this.storage.copy(r,0,0,this.writeCursor),this.storage=r,this.currentCapacityBytes=s}writeRing(e){let t=e.length;if(this.growIfNeeded(t),t>=this.currentCapacityBytes){let i=t-this.currentCapacityBytes;e.copy(this.storage,0,i,t);return}let s=this.writeCursor%this.currentCapacityBytes,r=this.currentCapacityBytes-s;t<=r?e.copy(this.storage,s,0,t):(e.copy(this.storage,s,0,r),e.copy(this.storage,0,r,t))}sliceFromRing(e,t){if(t<=0)return Buffer.alloc(0);let s=Buffer.alloc(t),r=e%this.currentCapacityBytes,i=Math.min(t,this.currentCapacityBytes-r);return this.storage.copy(s,0,r,r+i),i<t&&this.storage.copy(s,i,0,t-i),s}scheduleFileWrite(e){let t=this.filePath;if(t===void 0||this.fileCapReached)return;let s=this.fileCapBytes-this.fileBytesWritten;if(s<=0){this.fileCapReached=!0,this.onFileCapReached?.();return}let r=e.length<=s?e:e.subarray(0,s);this.fileBytesWritten+=r.length;let i=this.fileBytesWritten>=this.fileCapBytes;this.fileWriteChain=this.fileWriteChain.then(()=>qr.appendFile(t,r)).catch(o=>{this.logWriteError?.(o)}),i&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var Ke=[{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:"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."}],fm=new Map(Ke.map(n=>[n.verb,n]));function zr(n){let e=n.lastIndexOf("/");return(e===-1?n:n.slice(e+1)).toLowerCase()}function Ve(n,e){return Zn(n,e.map(t=>t.modelId))}function Zn(n,e){if(e.length===0)return{kind:"none",requested:n};if(e.includes(n))return{kind:"exact",modelId:n};let t=zr(n),s=e.filter(i=>zr(i)===t);if(s.length===1)return{kind:"resolved",modelId:s[0],requested:n};if(s.length>1)return{kind:"ambiguous",requested:n,candidates:s};let r=n.toLowerCase();if(r.length>0){let i=e.filter(o=>o.toLowerCase().includes(r));if(i.length===1)return{kind:"resolved",modelId:i[0],requested:n};if(i.length>1)return{kind:"ambiguous",requested:n,candidates:i}}return{kind:"unknown",requested:n}}function Wr(n){if(n.length===0)return n;let e=new Map,t=new Map,s=new Map;for(let a=0;a<n.length;a++){let d=n[a];if(d===void 0)continue;let u=es(d);if(u?.sessionUpdate!=="tool_call_update")continue;let c=typeof u.toolCallId=="string"?u.toolCallId:void 0;if(c!==void 0){e.set(c,a);for(let f of Ud){if(!Jr(u[f]))continue;let p=s.get(c);p===void 0?s.set(c,new Map([[f,u[f]]])):p.set(f,u[f])}if(Array.isArray(u.content)&&u.content.length>0){let f=t.get(c);f?f.push(...u.content):t.set(c,[...u.content])}}}let r=[],i=null,o=null;for(let a=0;a<n.length;a++){let d=n[a];if(d===void 0)continue;let u=es(d);if(!u||typeof u.sessionUpdate!="string"){r.push(d),i=null;continue}let c=u.sessionUpdate;if(c==="agent_message_chunk"||c==="agent_thought_chunk"||c==="user_message_chunk"){i&&i.kind===c?jd(r,i.outIndex,Hd(u.content)):(r.push(d),i={outIndex:r.length-1,kind:c});continue}if(i=null,c==="tool_call_update"){let f=typeof u.toolCallId=="string"?u.toolCallId:void 0;if(f!==void 0&&e.get(f)!==a)continue;let p=f!==void 0&&t.has(f)?Bd(d,t.get(f)??[]):d,l=f===void 0?void 0:s.get(f);if(l!==void 0)for(let[g,m]of l)Jr(es(p)?.[g])||(p=Dd(p,g,m));r.push(p);continue}if(c==="plan"){o!==null?r[o]=d:(r.push(d),o=r.length-1);continue}(c==="prompt_received"||c==="turn_complete")&&(o=null),r.push(d)}return r}function es(n){if(n.method!=="session/update")return;let t=n.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Hd(n){if(!n||typeof n!="object")return"";let e=n;return typeof e.text=="string"?e.text:""}function jd(n,e,t){if(t.length===0)return;let s=n[e];if(s===void 0)return;let r=s.params??{},i=r.update??{},o=i.content??{},a=typeof o.text=="string"?o.text:"";n[e]={...s,params:{...r,update:{...i,content:{...o,text:a+t}}}}}function Bd(n,e){let t=n.params??{},s=t.update??{};return{...n,params:{...t,update:{...s,content:e}}}}var Ud=["rawInput","locations"];function Jr(n){return n==null||typeof n!="object"?!1:Array.isArray(n)?n.length>0:Object.keys(n).length>0}function Dd(n,e,t){let s=n.params??{},r=s.update??{};return{...n,params:{...s,update:{...r,[e]:t}}}}var Qr=`[older history truncated]
21
- `,Ld=["file_path","filePath","path","command","pattern","query"];function Ye(n,e={}){let t=e.maxChars??4e5,s=[],r="",i=()=>{r.length!==0&&(s.push(`Assistant: ${r}`),r="")};for(let o of n){if(o.method!=="session/update")continue;let d=o.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let u=d.sessionUpdate;if(u==="prompt_received"){i();let c=ns(d.prompt).trim();c.length>0&&s.push(`User: ${c}`)}else if(u==="agent_message_chunk"){let c=ss(d.content);c.length>0&&(r+=c)}else u==="tool_call"?(i(),s.push(ts(d))):u==="turn_complete"&&i()}return i(),Wd(s.join(`
22
- `),t)}function ts(n){let e=qd(n),t=zd(n.rawInput);return t.length===0?`Tool: ${e}`:`Tool: ${e}(${t.join(", ")})`}function qd(n){return typeof n.name=="string"&&n.name.length>0?n.name:typeof n.title=="string"&&n.title.length>0?n.title:"(unnamed)"}function zd(n){if(!n||typeof n!="object"||Array.isArray(n))return[];let e=n,t=[];for(let s of Ld){let r=e[s];typeof r=="string"&&r.length>0&&t.push(`${s}=${Jd(r,200)}`)}return t}function ns(n){return typeof n=="string"?n:Array.isArray(n)?n.map(e=>{if(e&&typeof e=="object"){let t=e.text;if(typeof t=="string")return t}return""}).join(""):""}function ss(n){if(!n||typeof n!="object")return"";let e=n.text;return typeof e=="string"?e:""}function Jd(n,e){return n.length<=e?n:n.slice(0,e-1)+"\u2026"}function Wd(n,e){if(n.length<=e)return n;let t=n.split(`
23
- `);for(;t.length>0;){let s=Qr+t.join(`
24
- `);if(s.length<=e)return s;t.shift()}return Qr}var Gr="(untitled)";function rs(n){let e=[],t=n.synopsis;if(t!==void 0){e.push("--- begin prior session compaction ---"),e.push(`[Title] ${n.title??Gr}`),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 o=ht("Open threads",t.open_threads);o.length>0&&e.push(o);let a=ht("Decisions",t.decisions);a.length>0&&e.push(a);let d=ht("File edit intentions",t.file_edit_intentions);d.length>0&&e.push(d);let u=ht("Unresolved errors",t.unresolved_errors);u.length>0&&e.push(u);let c=ht("Tool state",t.tool_state);c.length>0&&e.push(c);let f=Kr(t.files_touched);f.length>0&&e.push(`[Files previously touched] ${f}`);let p=Kr(t.tools_used);p.length>0&&e.push(`[Tools previously used] ${p}`),e.push("--- end prior session compaction ---")}else e.push(`[Title] ${n.title??Gr}`);let{closedText:s,openText:r,keptCount:i}=Qd(n.tail,n.tailK,n.watermark??0,n.tailFloor??0);return e.push("--- begin recent turns (verbatim, last "+i+") ---"),s.length>0&&e.push(s),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 ---")),e.push(""),t!==void 0?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.)"):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.join(`
25
- `)}function ht(n,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 s=t.map(r=>"- "+r.trim());return`[${n}] ${s.join(`
26
- `)}`}function Kr(n){if(!n||!Array.isArray(n))return"";let e=n.filter(t=>typeof t=="string"&&t.trim().length>0);return e.length===0?"":e.map(t=>t.trim()).join(", ")}function Qd(n,e,t,s){if(n.length===0)return{closedText:"",openText:"",keptCount:0};let{closed:r,open:i}=Gd(n),o=0,a=[];if(e>0&&r.length>0){let c=r.filter(l=>l.startEntryIndex>=t).length,f=Math.max(c,s),p=Math.min(f,e,r.length);o=p,a=p>0?r.slice(-p):[]}let d=a.length>0?Vr(a):"",u=i?Vr([i]):"";return{closedText:d,openText:u,keptCount:o}}function Vr(n){let e=[];for(let t of n){t.user.length>0&&e.push("User: "+t.user),t.agent.length>0&&e.push("Assistant: "+t.agent);for(let s of t.tools)e.push(s)}return e.join(`
27
- `)}function Gd(n){let e=[],t=null;for(let r=0;r<n.length;r++){let i=n[r];if(i.method!=="session/update")continue;let a=i.params?.update;if(!a||typeof a.sessionUpdate!="string")continue;let d=a.sessionUpdate;if(d==="prompt_received")t!==null&&t.user.length>0&&e.push(t),t={user:ns(a.prompt).trim(),agent:"",tools:[],startEntryIndex:r};else if(d==="agent_message_chunk"&&t!==null){let u=ss(a.content);u.length>0&&(t.agent+=u)}else d==="tool_call"&&t!==null?t.tools.push(ts(a)):d==="turn_complete"&&t!==null&&(e.push(t),t=null)}let s=t!==null&&t.user.length>0?t:null;return{closed:e,open:s}}W();import*as ge from"fs/promises";async function yt(n,e){let t=I.queueFile(n);if(e.length===0){await ge.unlink(t).catch(()=>{});return}await ge.mkdir(I.sessionDir(n),{recursive:!0});let s=e.map(r=>JSON.stringify(r)).join(`
20
+ `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(this.killEscalationMs)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0)try{process.kill(-t,e)}catch{try{this.child.kill(e)}catch{}}}waitForExit(e){return this.exited?Promise.resolve():new Promise(t=>{let s=setTimeout(()=>{this.child.off("exit",r),t()},e),r=()=>{clearTimeout(s),t()};this.child.once("exit",r)})}},Wd=2e3;function Vd(n){try{let e=I.agentLogFile(n);Qt.mkdirSync(Vr.dirname(e),{recursive:!0});let t=Qt.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}import*as Ne from"fs/promises";import*as ni from"os";import*as Qr from"os";function yt(){return Qr.hostname()}import*as Rt from"path";import{customAlphabet as vu}from"nanoid";var he="session/set_model",os="session/set_config_option",Yr="model";function rs(n){return!n||typeof n!="object"||Array.isArray(n)?!1:Array.isArray(n.availableModels)}function Xr(n){return Array.isArray(n)&&n.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===Yr)}function Gt(n){if(!n)return;if(rs(n)||rs(n.models))return he;let e=n._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,s]of Object.entries(e))if(t!=="hydra-acp"&&rs(s))return he}if(Xr(n.configOptions))return os}function Zr(n){if(!n||typeof n!="object"||Array.isArray(n))return;let e=n.sessionUpdate;if(e==="current_model_update")return he;if(e==="config_option_update"&&Xr(n.configOptions))return os}function Gr(n){return typeof n=="object"&&n!==null&&n.code===k.MethodNotFound}function Kr(n,e,t,s){let r={...s??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,n===he?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:Yr,value:t}}function Qd(n){return n===he?os:he}async function Qe(n){let{request:e,sessionId:t,modelId:s,extraParams:r,logger:o}=n,i=n.verb??he;try{let a=await e(i,Kr(i,t,s,r));return{verb:i,result:a}}catch(a){if(!Gr(a))throw a;let d=Qd(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(s)}`);try{let u=await e(d,Kr(d,t,s,r));return{verb:d,result:u}}catch(u){throw Gr(u)?a:u}}}async function Ge(n){let{agent:e,upstreamSessionId:t,persistedMode:s,agentReportedMode:r,advertisedModes:o,logger:i}=n;if(!s)return r;if(s===r)return s;if(o&&o.length>0&&!o.some(a=>a.id===s)){let a=o.map(d=>d.id).join(", ");return i?.warn(`resurrect: persisted currentMode=${JSON.stringify(s)} 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(s)} to agent (agentReported=${JSON.stringify(r)})`),await e.connection.request("session/set_mode",{sessionId:t,modeId:s}),i?.info(`resurrect: session/set_mode accepted, effectiveMode=${JSON.stringify(s)}`),s}catch(a){return i?.warn(`resurrect: session/set_mode rejected by agent for modeId=${JSON.stringify(s)} (${a.message}); session will use ${JSON.stringify(r)}`),r}}async function Ke(n){let{agent:e,upstreamSessionId:t,persistedModel:s,agentReportedModel:r,modelVerb:o,logger:i}=n;if(!s)return r;if(s===r)return s;try{i?.info(`resurrect: pushing persisted modelId=${JSON.stringify(s)} to agent (agentReported=${JSON.stringify(r)})`);let{verb:a}=await Qe({request:(d,u)=>e.connection.request(d,u),sessionId:t,modelId:s,...o?{verb:o}:{},logger:i});return i?.info(`resurrect: ${a} accepted, effectiveModel=${JSON.stringify(s)}`),s}catch(a){return i?.warn(`resurrect: session/set_model rejected by agent for modelId=${JSON.stringify(s)} (${a.message}); session will use ${JSON.stringify(r)}`),r}}import{customAlphabet as yo}from"nanoid";var eo="edit",Kt=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 to(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(t===null||typeof t!="object")continue;let s=t.path;typeof s=="string"&&s.length>0&&e.push(s)}return e}import*as so from"fs/promises";var Gd=64*1024*1024,Kd=1*1024*1024,Ye=64*1024,Yd=6e4,Xd=100,Zd=1e3,ec=64*1024,tc=256*1024,no=20;function nc(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Yt=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??Gd,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Kd,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 s=Math.max(0,Math.min(t,Ye));if(s===0){let f={bytes:Buffer.alloc(0),nextCursor:e};return this.closed&&e>=this.writeCursor&&(f.eof=!0),f}let r=e,o=0,i=this.oldestAvailable;r<i&&(o=i-r,r=i);let a=this.writeCursor-r;if(a<=0){let f={bytes:Buffer.alloc(0),nextCursor:r};return o>0&&(f.gap=o),this.closed&&(f.eof=!0),f}let d=Math.min(a,s),c={bytes:this.sliceFromRing(r,d),nextCursor:r+d};return o>0&&(c.gap=o),this.closed&&r+d>=this.writeCursor&&(c.eof=!0),c}tail(e){let t=Math.max(0,Math.min(e,Ye)),s=this.oldestAvailable,r=this.writeCursor-t,o=Math.max(s,r),i=r<s;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,Ye)),s=this.oldestAvailable,r=s>0,o=s,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 s=Math.max(0,Math.min(t,Yd));return s===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")},s)};this.waiters.push(o)})}grep(e){let t=this.oldestAvailable,s=e.cursor,r=s??t,o=0;s!==void 0&&s<t&&(o=t-s,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":"",u=a?new RegExp(e.pattern,d):new RegExp(nc(e.pattern),d),c=e.invert??!1,f=Math.max(1,Math.min(e.maxMatches??Xd,Zd)),p=Math.max(1,Math.min(e.maxBytes??ec,tc)),l=Math.max(0,Math.min(e.contextBefore??0,no)),m=Math.max(0,Math.min(e.contextAfter??0,no)),g=[],h=[],y=[],b=0,w=!1,v=0,A=0,C=(_,B)=>{for(let J of y)J.remaining>0&&(J.match.after===void 0&&(J.match.after=[]),J.match.after.push({cursor:_,line:B}),J.remaining--,b+=B.length);for(;y.length>0&&y[0].remaining===0;)y.shift();if(u.test(B)!==c&&g.length<f){let J={cursor:_,line:B};if(l>0&&h.length>0){J.before=h.slice();for(let ne of J.before)b+=ne.line.length}b+=B.length,g.push(J),m>0&&y.push({match:J,remaining:m})}if(l>0)for(h.push({cursor:_,line:B});h.length>l;)h.shift();let T=g.length>=f&&y.length===0,U=b>=p;return T||U};for(let _=0;_<i.length;_++){if(i[_]!==10)continue;let B=i.subarray(v,_).toString("utf8"),$=r+v;if(v=_+1,A=v,C($,B)){w=!0;break}}if(!w&&v<i.length&&this.closed){let _=i.subarray(v).toString("utf8"),B=r+v;C(B,_)&&(w=!0),A=i.length}let x=Math.min(r+A,this.writeCursor),P={matches:g,truncated:w,nextCursor:x,scannedBytes:A};return o>0&&(P.gap=o),this.closed&&x>=this.writeCursor&&(P.eof=!0),P}wakeWaiters(e){if(this.waiters.length===0)return;let t=this.waiters;this.waiters=[];for(let s of t)s.resolve(e)}growIfNeeded(e){if(this.currentCapacityBytes>=this.maxCapacityBytes)return;let t=this.writeCursor+e;if(t<=this.currentCapacityBytes)return;let s=this.currentCapacityBytes;for(;s<t&&s<this.maxCapacityBytes;)s=Math.min(this.maxCapacityBytes,s*2);if(s===this.currentCapacityBytes)return;let r=Buffer.alloc(s);this.storage.copy(r,0,0,this.writeCursor),this.storage=r,this.currentCapacityBytes=s}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 s=this.writeCursor%this.currentCapacityBytes,r=this.currentCapacityBytes-s;t<=r?e.copy(this.storage,s,0,t):(e.copy(this.storage,s,0,r),e.copy(this.storage,0,r,t))}sliceFromRing(e,t){if(t<=0)return Buffer.alloc(0);let s=Buffer.alloc(t),r=e%this.currentCapacityBytes,o=Math.min(t,this.currentCapacityBytes-r);return this.storage.copy(s,0,r,r+o),o<t&&this.storage.copy(s,o,0,t-o),s}scheduleFileWrite(e){let t=this.filePath;if(t===void 0||this.fileCapReached)return;let s=this.fileCapBytes-this.fileBytesWritten;if(s<=0){this.fileCapReached=!0,this.onFileCapReached?.();return}let r=e.length<=s?e:e.subarray(0,s);this.fileBytesWritten+=r.length;let o=this.fileBytesWritten>=this.fileCapBytes;this.fileWriteChain=this.fileWriteChain.then(()=>so.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var Xe=[{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:"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."}],jm=new Map(Xe.map(n=>[n.verb,n]));function ro(n){let e=n.lastIndexOf("/");return(e===-1?n:n.slice(e+1)).toLowerCase()}function Ze(n,e){return is(n,e.map(t=>t.modelId))}function is(n,e){if(e.length===0)return{kind:"none",requested:n};if(e.includes(n))return{kind:"exact",modelId:n};let t=ro(n),s=e.filter(o=>ro(o)===t);if(s.length===1)return{kind:"resolved",modelId:s[0],requested:n};if(s.length>1)return{kind:"ambiguous",requested:n,candidates:s};let r=n.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:n};if(o.length>1)return{kind:"ambiguous",requested:n,candidates:o}}return{kind:"unknown",requested:n}}function io(n){if(n.length===0)return n;let e=new Map,t=new Map,s=new Map;for(let a=0;a<n.length;a++){let d=n[a];if(d===void 0)continue;let u=as(d);if(u?.sessionUpdate!=="tool_call_update")continue;let c=typeof u.toolCallId=="string"?u.toolCallId:void 0;if(c!==void 0){e.set(c,a);for(let f of ic){if(!oo(u[f]))continue;let p=s.get(c);p===void 0?s.set(c,new Map([[f,u[f]]])):p.set(f,u[f])}if(Array.isArray(u.content)&&u.content.length>0){let f=t.get(c);f?f.push(...u.content):t.set(c,[...u.content])}}}let r=[],o=null,i=null;for(let a=0;a<n.length;a++){let d=n[a];if(d===void 0)continue;let u=as(d);if(!u||typeof u.sessionUpdate!="string"){r.push(d),o=null;continue}let c=u.sessionUpdate;if(c==="agent_message_chunk"||c==="agent_thought_chunk"||c==="user_message_chunk"){o&&o.kind===c?rc(r,o.outIndex,sc(u.content)):(r.push(d),o={outIndex:r.length-1,kind:c});continue}if(o=null,c==="tool_call_update"){let f=typeof u.toolCallId=="string"?u.toolCallId:void 0;if(f!==void 0&&e.get(f)!==a)continue;let p=f!==void 0&&t.has(f)?oc(d,t.get(f)??[]):d,l=f===void 0?void 0:s.get(f);if(l!==void 0)for(let[m,g]of l)oo(as(p)?.[m])||(p=ac(p,m,g));r.push(p);continue}if(c==="plan"){i!==null?r[i]=d:(r.push(d),i=r.length-1);continue}(c==="prompt_received"||c==="turn_complete")&&(i=null),r.push(d)}return r}function as(n){if(n.method!=="session/update")return;let t=n.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function sc(n){if(!n||typeof n!="object")return"";let e=n;return typeof e.text=="string"?e.text:""}function rc(n,e,t){if(t.length===0)return;let s=n[e];if(s===void 0)return;let r=s.params??{},o=r.update??{},i=o.content??{},a=typeof i.text=="string"?i.text:"";n[e]={...s,params:{...r,update:{...o,content:{...i,text:a+t}}}}}function oc(n,e){let t=n.params??{},s=t.update??{};return{...n,params:{...t,update:{...s,content:e}}}}var ic=["rawInput","locations"];function oo(n){return n==null||typeof n!="object"?!1:Array.isArray(n)?n.length>0:Object.keys(n).length>0}function ac(n,e,t){let s=n.params??{},r=s.update??{};return{...n,params:{...s,update:{...r,[e]:t}}}}var ao=`[older history truncated]
21
+ `,dc=["file_path","filePath","path","command","pattern","query"];function et(n,e={}){let t=e.maxChars??4e5,s=[],r="",o=()=>{r.length!==0&&(s.push(`Assistant: ${r}`),r="")};for(let i of n){if(i.method!=="session/update")continue;let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let u=d.sessionUpdate;if(u==="prompt_received"){o();let c=cs(d.prompt).trim();c.length>0&&s.push(`User: ${c}`)}else if(u==="agent_message_chunk"){let c=us(d.content);c.length>0&&(r+=c)}else u==="tool_call"?(o(),s.push(ds(d))):u==="turn_complete"&&o()}return o(),fc(s.join(`
22
+ `),t)}function ds(n){let e=cc(n),t=uc(n.rawInput);return t.length===0?`Tool: ${e}`:`Tool: ${e}(${t.join(", ")})`}function cc(n){return typeof n.name=="string"&&n.name.length>0?n.name:typeof n.title=="string"&&n.title.length>0?n.title:"(unnamed)"}function uc(n){if(!n||typeof n!="object"||Array.isArray(n))return[];let e=n,t=[];for(let s of dc){let r=e[s];typeof r=="string"&&r.length>0&&t.push(`${s}=${lc(r,200)}`)}return t}function cs(n){return typeof n=="string"?n:Array.isArray(n)?n.map(e=>{if(e&&typeof e=="object"){let t=e.text;if(typeof t=="string")return t}return""}).join(""):""}function us(n){if(!n||typeof n!="object")return"";let e=n.text;return typeof e=="string"?e:""}function lc(n,e){return n.length<=e?n:n.slice(0,e-1)+"\u2026"}function fc(n,e){if(n.length<=e)return n;let t=n.split(`
23
+ `);for(;t.length>0;){let s=ao+t.join(`
24
+ `);if(s.length<=e)return s;t.shift()}return ao}var co="(untitled)";function ls(n){let e=[],t=n.synopsis;if(t!==void 0){e.push("--- begin prior session compaction ---"),e.push(`[Title] ${n.title??co}`),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 i=wt("Open threads",t.open_threads);i.length>0&&e.push(i);let a=wt("Decisions",t.decisions);a.length>0&&e.push(a);let d=wt("File edit intentions",t.file_edit_intentions);d.length>0&&e.push(d);let u=wt("Unresolved errors",t.unresolved_errors);u.length>0&&e.push(u);let c=wt("Tool state",t.tool_state);c.length>0&&e.push(c);let f=uo(t.files_touched);f.length>0&&e.push(`[Files previously touched] ${f}`);let p=uo(t.tools_used);p.length>0&&e.push(`[Tools previously used] ${p}`),e.push("--- end prior session compaction ---")}else e.push(`[Title] ${n.title??co}`);let{closedText:s,openText:r,keptCount:o}=pc(n.tail,n.tailK,n.watermark??0,n.tailFloor??0);return e.push("--- begin recent turns (verbatim, last "+o+") ---"),s.length>0&&e.push(s),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 ---")),e.push(""),t!==void 0?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.)"):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.join(`
25
+ `)}function wt(n,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 s=t.map(r=>"- "+r.trim());return`[${n}] ${s.join(`
26
+ `)}`}function uo(n){if(!n||!Array.isArray(n))return"";let e=n.filter(t=>typeof t=="string"&&t.trim().length>0);return e.length===0?"":e.map(t=>t.trim()).join(", ")}function pc(n,e,t,s){if(n.length===0)return{closedText:"",openText:"",keptCount:0};let{closed:r,open:o}=mc(n),i=0,a=[];if(e>0&&r.length>0){let c=r.filter(l=>l.startEntryIndex>=t).length,f=Math.max(c,s),p=Math.min(f,e,r.length);i=p,a=p>0?r.slice(-p):[]}let d=a.length>0?lo(a):"",u=o?lo([o]):"";return{closedText:d,openText:u,keptCount:i}}function lo(n){let e=[];for(let t of n){t.user.length>0&&e.push("User: "+t.user),t.agent.length>0&&e.push("Assistant: "+t.agent);for(let s of t.tools)e.push(s)}return e.join(`
27
+ `)}function mc(n){let e=[],t=null;for(let r=0;r<n.length;r++){let o=n[r];if(o.method!=="session/update")continue;let a=o.params?.update;if(!a||typeof a.sessionUpdate!="string")continue;let d=a.sessionUpdate;if(d==="prompt_received")t!==null&&t.user.length>0&&e.push(t),t={user:cs(a.prompt).trim(),agent:"",tools:[],startEntryIndex:r};else if(d==="agent_message_chunk"&&t!==null){let u=us(a.content);u.length>0&&(t.agent+=u)}else d==="tool_call"&&t!==null?t.tools.push(ds(a)):d==="turn_complete"&&t!==null&&(e.push(t),t=null)}let s=t!==null&&t.user.length>0?t:null;return{closed:e,open:s}}W();import*as ye from"fs/promises";async function bt(n,e){let t=I.queueFile(n);if(e.length===0){await ye.unlink(t).catch(()=>{});return}await ye.mkdir(I.sessionDir(n),{recursive:!0});let s=e.map(r=>JSON.stringify(r)).join(`
28
28
  `)+`
29
- `;await ge.writeFile(t,s,"utf8")}async function Yr(n){let e=I.queueFile(n),t;try{t=await ge.readFile(e,"utf8")}catch(r){if(r.code==="ENOENT")return[];throw r}let s=[];for(let r of t.split(`
30
- `))if(r.trim())try{let i=JSON.parse(r);i&&typeof i.messageId=="string"&&Array.isArray(i.prompt)&&typeof i.enqueuedAt=="number"&&s.push(i)}catch{}return s}async function Xr(n){let e=I.queueFile(n);await ge.unlink(e).catch(()=>{})}import*as oi from"fs/promises";var si="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",ri=ni(si,16),is=ni(si,16),Kd=20,Vd=20,Yd=5,ve="hydra_session_";function Ee(){return`m_${ri()}`}function ii(n){return n.startsWith(ve)?n.slice(ve.length):n}var Xd=1e3,Wt=300*1e3,Zd=64,et=class n{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;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;modeChangeInFlight=!1;modelChangeInFlight=!1;queueWriteChain=Promise.resolve();closed=!1;closing=!1;closeInFlight;deleteRecordIntent=!1;closeHandlers=[];titleHandlers=[];scheduleSynopsisHook;scheduleCompactionHook;resolveAgentIdHook;getCompactionStateHook;getPendingAgentSwapHook;_liveCompactionPhase;broadcastHandlers=[];lastCancelAt=0;static CANCEL_ERROR_WINDOW_MS=2e3;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}promptStartedAt;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;idleEventTimeoutMs;idleHandlers=[];lastRecordedAt;spawnReplacementAgent;mintMcpServersForSwap;loadExistingAgentSession;clearRollbackBreadcrumbHook;onCompactionSwapHook;uncompactHook;forkHook;mcpServersConfig;forwardedEnv;listSessions;logger;transformChain;extensionCommands;extensionCommandsUnsub;pendingClaims=new Map;toolCompletionSeen=new Map;toolCallKind=new zt;filesEditedSeen=new Set;agentChangeHandlers=[];retiringGenerationCost;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;streamBuffer;streamFilePath;constructor(e){if(this.sessionId=e.sessionId??`${ve}${ri()}`,this.cwd=e.cwd,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.scheduleCompactionHook=e.scheduleCompaction,this.resolveAgentIdHook=e.resolveAgentId,this.getCompactionStateHook=e.getCompactionState,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]),this.idleTimeoutMs=e.idleTimeoutMs??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.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._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??Xd,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.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:"available_modes_update",availableModes:this.agentAdvertisedModes}})}broadcastAvailableModels(){let e={sessionUpdate:"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){e.connection.onNotification("session/update",t=>{if(this.internalPromptCapture){ic(this.internalPromptCapture,t);return}this.maybeEmitToolEdges(t),this.runResponseChain(t)}),e.connection.onRequest("session/request_permission",async t=>{let s=await this.runAgentRequestChain("session/request_permission",t),r=ei(s.shortCircuit?t:s.envelope);if(s.shortCircuit)return this.notifyChain("permission.replied",{toolCallId:r??null,outcome:s.payload,sourceWasTransformer:!0}),s.payload;let i=await this.handlePermissionRequest(s.envelope);return this.notifyChain("permission.replied",{toolCallId:r??null,outcome:i,sourceWasTransformer:!1}),i}),typeof e.connection.onOrphanError=="function"&&e.connection.onOrphanError(t=>{this.handleOrphanError(t)}),e.onExit(()=>{this.agent===e&&this.markClosed({deleteRecord:!1})})}handleOrphanError(e){let t=Date.now()-this.lastCancelAt;if(this.lastCancelAt===0||t>n.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,s=0,r="session/update"){let i=e,o=r==="session/update"?this.injectCumulativeCost(e):e,a=`response:${r}`;for(let c=s;c<this.transformChain.length;c++){let f=this.transformChain[c];if(t.has(f.name)||!f.intercepts.has(a))continue;let p=`t_${is()}`,l;try{l=await f.connection.request("hydra-acp/transformer/message",{token:p,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:o})}catch(m){this.logger?.warn(`transformer ${f.name} error on ${a}: ${m.message}`);continue}let g=l?.action??"continue";if(g==="stop")return;if(g==="processing"){let m=c,h=o,y=new Set(t),v=r;await new Promise(w=>{let S=setTimeout(()=>{this.pendingClaims.delete(p)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:p,transformerName:f.name}),this.runResponseChain(h,new Set([...y,f.name]),m+1,v).then(()=>w()).catch(()=>w()))},Wt);typeof S.unref=="function"&&S.unref(),this.pendingClaims.set(p,{resolve:()=>w(),timer:S,transformerName:f.name,method:v,envelope:h,chainIdx:m,originatedBy:y,side:"response"})});return}l?.payload&&typeof l.payload=="object"&&(o=l.payload),t.add(f.name)}if(r!=="session/update")return;let d=oc(o);if(d!==null){this.setAgentAdvertisedCommands(d);return}let u=rc(o);if(u!==null){this.setAgentAdvertisedModes(u);return}if(this.maybeApplyAgentModel(o)){this.recordAndBroadcast("session/update",o);return}if(this.maybeApplyAgentMode(o)){this.recordAndBroadcast("session/update",o);return}if(this.maybeApplyAgentConfigOption(o)){this.recordAndBroadcast("session/update",this.mergeAgentOptionIntoEnvelope(o));return}if(this.maybeApplyAgentUsage(i)){this.recordAndBroadcast("session/update",o);return}this.maybeApplyAgentSessionInfo(o),this.recordAndBroadcast("session/update",o)}onAgentChange(e){this.agentChangeHandlers.push(e)}get attachedCount(){return this.clients.size}connectedClients(e){let t=[];for(let s of this.clients.values()){if(e&&s.clientId===e)continue;let r={clientId:s.clientId};s.clientInfo?.name&&(r.name=s.clientInfo.name),s.clientInfo?.version&&(r.version=s.clientInfo.version),t.push(r)}return t}get turnStartedAt(){return this.promptStartedAt}get agentPid(){return this.agent.pid}get awaitingInput(){return this.attentionFlags.size>0}async isQuiescedForSwap(){return!(this.promptInFlight||this.modeChangeInFlight||this.modelChangeInFlight||await this._hasOpenToolCall())}isQuiescedSync(){return!(this.promptInFlight||this.modeChangeInFlight||this.modelChangeInFlight)}async swapUpstream(e){if(!await this.isQuiescedForSwap())throw new Error("session is not quiesced for swap \u2014 wait for in-flight work to complete");this.notifyChain("agent.swap",{phase:"pre",previousUpstreamSessionId:this.upstreamSessionId,agentId:this.agentId});let s=this.agentId,r=e.newAgentId??this.agentId,i=r!==this.agentId,o=this.cwd,a=this.agentArgs,d=this.forwardedEnv,u=this.currentModel,c=this.currentMode,f=this.spawnReplacementAgent;if(!f)throw new Error("agent spawning not configured for this session");let p=this.mintMcpServersForSwap?await this.mintMcpServersForSwap(this):this.mcpServersConfig??[],l=await f({agentId:r,cwd:o,agentArgs:a,...d?{forwardedEnv:d}:{},mcpServers:p});this.accumulateAndResetCost(),this.wireAgent(l.agent),i||(await Qe({agent:l.agent,upstreamSessionId:l.upstreamSessionId,persistedModel:u,agentReportedModel:l.initialModel,logger:this.logger}),await We({agent:l.agent,upstreamSessionId:l.upstreamSessionId,persistedMode:c,agentReportedMode:l.initialMode,logger:this.logger})),l.agent.connection.drainBuffered("session/update");let g=[];if(this.historyStore)try{g=await this.historyStore.load(this.sessionId)}catch(A){this.logger?.warn(`swapUpstream: historyStore.load failed: ${A.message}`)}let m=rs({synopsis:e.artifact,title:e.title,tail:g,tailK:e.tailK,tailFloor:e.tailFloor,...e.summarizedThroughEntry!==void 0?{watermark:e.summarizedThroughEntry}:{}});if(this.internalPromptCapture)throw new Error("swapUpstream: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await l.agent.connection.request("session/prompt",{sessionId:l.upstreamSessionId,prompt:[{type:"text",text:m}]});let A=this.internalPromptCapture;this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${m.length} toolCalls=${A.toolCalls} thinkingChars=${A.thinkingChars} messageChars=${A.messageChars} used=${A.lastUsed??"?"} size=${A.lastSize??"?"} reply=${JSON.stringify(A.chunks.join("").slice(0,200))}`)}finally{this.internalPromptCapture=void 0}let h=this.upstreamSessionId,y=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let v=this.agent;if(this.agent=l.agent,this.upstreamSessionId=l.upstreamSessionId,this.agentMeta=l.agentMeta,this.agentCapabilities=l.agentCapabilities,i&&(this.agentId=r,this.agentAdvertisedCommands=[],this.currentModel=l.initialModel,this.currentMode=l.initialMode,this.setAgentAdvertisedModels(l.initialModels??[]),this.setAgentAdvertisedModes(l.initialModes??[])),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream"),!i&&this.onCompactionSwapHook)try{this.onCompactionSwapHook({previousUpstreamSessionId:h,...y!==void 0?{previousSummarizedThroughEntry:y}:{}})}catch(A){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${A.message}`)}await v.kill().catch(()=>{}),this.notifyChain("agent.swap",{phase:"post",previousUpstreamSessionId:h,upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}),i||this.broadcastCompactionPhase({phase:"swapped",...this.title!==void 0?{title:this.title}:{},summarizedThroughEntry:e.summarizedThroughEntry??this._summarizedThroughEntry??0}),i&&this.broadcastAgentSwitch(s,r);let w=i?`
29
+ `;await ye.writeFile(t,s,"utf8")}async function fo(n){let e=I.queueFile(n),t;try{t=await ye.readFile(e,"utf8")}catch(r){if(r.code==="ENOENT")return[];throw r}let s=[];for(let r of t.split(`
30
+ `))if(r.trim())try{let o=JSON.parse(r);o&&typeof o.messageId=="string"&&Array.isArray(o.prompt)&&typeof o.enqueuedAt=="number"&&s.push(o)}catch{}return s}async function po(n){let e=I.queueFile(n);await ye.unlink(e).catch(()=>{})}import*as So from"fs/promises";var wo="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",bo=yo(wo,16),fs=yo(wo,16),gc=20,hc=20,yc=5,we="hydra_session_";function Te(){return`m_${bo()}`}function vo(n){return n.startsWith(we)?n.slice(we.length):n}var wc=1e3,Xt=300*1e3,bc=64,st=class n{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=he;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;modeChangeInFlight=!1;modelChangeInFlight=!1;queueWriteChain=Promise.resolve();closed=!1;closing=!1;closeInFlight;deleteRecordIntent=!1;closeHandlers=[];titleHandlers=[];scheduleSynopsisHook;scheduleCompactionHook;resolveAgentIdHook;getCompactionStateHook;getPendingAgentSwapHook;_liveCompactionPhase;broadcastHandlers=[];lastCancelAt=0;static CANCEL_ERROR_WINDOW_MS=2e3;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}promptStartedAt;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;idleEventTimeoutMs;idleHandlers=[];lastRecordedAt;spawnReplacementAgent;mintMcpServersForSwap;loadExistingAgentSession;clearRollbackBreadcrumbHook;onCompactionSwapHook;uncompactHook;forkHook;mcpServersConfig;forwardedEnv;listSessions;logger;transformChain;extensionCommands;extensionCommandsUnsub;pendingClaims=new Map;toolCompletionSeen=new Map;toolCallKind=new Kt;filesEditedSeen=new Set;agentChangeHandlers=[];retiringGenerationCost;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;streamBuffer;streamFilePath;constructor(e){if(this.sessionId=e.sessionId??`${we}${bo()}`,this.cwd=e.cwd,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.scheduleCompactionHook=e.scheduleCompaction,this.resolveAgentIdHook=e.resolveAgentId,this.getCompactionStateHook=e.getCompactionState,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]),this.idleTimeoutMs=e.idleTimeoutMs??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.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._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??wc,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:"available_modes_update",availableModes:this.agentAdvertisedModes}})}broadcastAvailableModels(){let e={sessionUpdate:"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){e.connection.onNotification("session/update",t=>{if(this.internalPromptCapture){Cc(this.internalPromptCapture,t);return}this.maybeEmitToolEdges(t),this.runResponseChain(t)}),e.connection.onRequest("session/request_permission",async t=>{let s=await this.runAgentRequestChain("session/request_permission",t),r=go(s.shortCircuit?t:s.envelope);if(s.shortCircuit)return this.notifyChain("permission.replied",{toolCallId:r??null,outcome:s.payload,sourceWasTransformer:!0}),s.payload;let o=await this.handlePermissionRequest(s.envelope);return this.notifyChain("permission.replied",{toolCallId:r??null,outcome:o,sourceWasTransformer:!1}),o}),typeof e.connection.onOrphanError=="function"&&e.connection.onOrphanError(t=>{this.handleOrphanError(t)}),e.onExit(()=>{this.agent===e&&this.markClosed({deleteRecord:!1})})}handleOrphanError(e){let t=Date.now()-this.lastCancelAt;if(this.lastCancelAt===0||t>n.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,s=0,r="session/update"){let o=e,i=r==="session/update"?this.injectCumulativeCost(e):e,a=`response:${r}`;for(let c=s;c<this.transformChain.length;c++){let f=this.transformChain[c];if(t.has(f.name)||!f.intercepts.has(a))continue;let p=`t_${fs()}`,l;try{l=await f.connection.request("hydra-acp/transformer/message",{token:p,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(g){this.logger?.warn(`transformer ${f.name} error on ${a}: ${g.message}`);continue}let m=l?.action??"continue";if(m==="stop")return;if(m==="processing"){let g=c,h=i,y=new Set(t),b=r;await new Promise(w=>{let v=setTimeout(()=>{this.pendingClaims.delete(p)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:p,transformerName:f.name}),this.runResponseChain(h,new Set([...y,f.name]),g+1,b).then(()=>w()).catch(()=>w()))},Xt);typeof v.unref=="function"&&v.unref(),this.pendingClaims.set(p,{resolve:()=>w(),timer:v,transformerName:f.name,method:b,envelope:h,chainIdx:g,originatedBy:y,side:"response"})});return}l?.payload&&typeof l.payload=="object"&&(i=l.payload),t.add(f.name)}if(r!=="session/update")return;let d=xc(i);if(d!==null){this.setAgentAdvertisedCommands(d);return}let u=Ac(i);if(u!==null){this.setAgentAdvertisedModes(u);return}if(this.noteModelVerbHint(Zr(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 s of this.clients.values()){if(e&&s.clientId===e)continue;let r={clientId:s.clientId};s.clientInfo?.name&&(r.name=s.clientInfo.name),s.clientInfo?.version&&(r.version=s.clientInfo.version),t.push(r)}return t}get turnStartedAt(){return this.promptStartedAt}get agentPid(){return this.agent.pid}get awaitingInput(){return this.attentionFlags.size>0}async isQuiescedForSwap(){return!(this.promptInFlight||this.modeChangeInFlight||this.modelChangeInFlight||await this._hasOpenToolCall())}isQuiescedSync(){return!(this.promptInFlight||this.modeChangeInFlight||this.modelChangeInFlight)}async swapUpstream(e){if(!await this.isQuiescedForSwap())throw new Error("session is not quiesced for swap \u2014 wait for in-flight work to complete");this.notifyChain("agent.swap",{phase:"pre",previousUpstreamSessionId:this.upstreamSessionId,agentId:this.agentId});let s=this.agentId,r=e.newAgentId??this.agentId,o=r!==this.agentId,i=this.cwd,a=this.agentArgs,d=this.forwardedEnv,u=this.currentModel,c=this.currentMode,f=this.spawnReplacementAgent;if(!f)throw new Error("agent spawning not configured for this session");let p=this.mintMcpServersForSwap?await this.mintMcpServersForSwap(this):this.mcpServersConfig??[],l=await f({agentId:r,cwd:i,agentArgs:a,...d?{forwardedEnv:d}:{},mcpServers:p});this.accumulateAndResetCost(),this.wireAgent(l.agent),o||(await Ke({agent:l.agent,upstreamSessionId:l.upstreamSessionId,persistedModel:u,agentReportedModel:l.initialModel,logger:this.logger}),await Ge({agent:l.agent,upstreamSessionId:l.upstreamSessionId,persistedMode:c,agentReportedMode:l.initialMode,logger:this.logger})),l.agent.connection.drainBuffered("session/update");let m=[];if(this.historyStore)try{m=await this.historyStore.load(this.sessionId)}catch(A){this.logger?.warn(`swapUpstream: historyStore.load failed: ${A.message}`)}let g=ls({synopsis:e.artifact,title:e.title,tail:m,tailK:e.tailK,tailFloor:e.tailFloor,...e.summarizedThroughEntry!==void 0?{watermark:e.summarizedThroughEntry}:{}});if(this.internalPromptCapture)throw new Error("swapUpstream: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await l.agent.connection.request("session/prompt",{sessionId:l.upstreamSessionId,prompt:[{type:"text",text:g}]});let A=this.internalPromptCapture;this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${g.length} toolCalls=${A.toolCalls} thinkingChars=${A.thinkingChars} messageChars=${A.messageChars} used=${A.lastUsed??"?"} size=${A.lastSize??"?"} reply=${JSON.stringify(A.chunks.join("").slice(0,200))}`)}finally{this.internalPromptCapture=void 0}let h=this.upstreamSessionId,y=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let b=this.agent;if(this.agent=l.agent,this.upstreamSessionId=l.upstreamSessionId,this.agentMeta=l.agentMeta,this.agentCapabilities=l.agentCapabilities,this.resetModelVerb(l.modelVerb),o&&(this.agentId=r,this.agentAdvertisedCommands=[],this.currentModel=l.initialModel,this.currentMode=l.initialMode,this.setAgentAdvertisedModels(l.initialModels??[]),this.setAgentAdvertisedModes(l.initialModes??[])),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream"),!o&&this.onCompactionSwapHook)try{this.onCompactionSwapHook({previousUpstreamSessionId:h,...y!==void 0?{previousSummarizedThroughEntry:y}:{}})}catch(A){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${A.message}`)}await b.kill().catch(()=>{}),this.notifyChain("agent.swap",{phase:"post",previousUpstreamSessionId:h,upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}),o||this.broadcastCompactionPhase({phase:"swapped",...this.title!==void 0?{title:this.title}:{},summarizedThroughEntry:e.summarizedThroughEntry??this._summarizedThroughEntry??0}),o&&this.broadcastAgentSwitch(s,r);let w=o?`
31
31
  Switched to ${r}.
32
32
  `:`
33
33
  Compaction completed.
34
- `,S=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:w},_meta:{"hydra-acp":{synthetic:!0}}}});for(let A of this.clients.values())A.connection.notify("session/update",S).catch(()=>{});this.updatedAt=Date.now()}async rollbackToUpstream(e){if(!await this.isQuiescedForSwap())throw new Error("session is not quiesced for rollback \u2014 wait for in-flight work to complete");let s=this.loadExistingAgentSession;if(!s)throw new Error("loadExistingAgentSession not configured for this session");let r=this.agentId,i=this.cwd,o=this.agentArgs,a=this.forwardedEnv,d=this.currentModel,u=this.currentMode,c=await s(e.previousUpstreamSessionId,{agentId:r,cwd:i,agentArgs:o,...a?{forwardedEnv:a}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(c.agent),await Qe({agent:c.agent,upstreamSessionId:c.upstreamSessionId,persistedModel:d,agentReportedModel:c.initialModel,logger:this.logger}),await We({agent:c.agent,upstreamSessionId:c.upstreamSessionId,persistedMode:u,agentReportedMode:c.initialMode,logger:this.logger}),c.agent.connection.drainBuffered("session/update");let f=this.agent;this.agent=c.agent,this.upstreamSessionId=c.upstreamSessionId,this.agentMeta=c.agentMeta,this.agentCapabilities=c.agentCapabilities,this.broadcastMergedCommands(),this.broadcastConfigOptions(),await f.kill().catch(()=>{}),this._summarizedThroughEntry=e.previousSummarizedThroughEntry,this.broadcastCompactionPhase({phase:"rolled_back",summarizedThroughEntry:e.previousSummarizedThroughEntry??0}),this.notifyAgentChange("rollbackToUpstream"),this.updatedAt=Date.now()}async _hasOpenToolCall(e=Kd){if(!this.historyStore)return!1;let t=await this.historyStore.load(this.sessionId),s=t.length>e?t.slice(-e):t,r=new Set,i=new Set;for(let o of s){let d=o.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let u=d.sessionUpdate,c=typeof d.toolCallId=="string"?d.toolCallId:void 0;if(c){if(u==="tool_call")r.add(c);else if(u==="tool_call_update"){let f=d.status;(f==="completed"||f==="failed")&&i.add(c)}}}for(let o of r)if(!i.has(o))return!0;return!1}async getHistorySnapshot(e="inline"){return this.historyStore?this.historyStore.load(this.sessionId,{tools:e}).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 s of this.clients.values())s.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 s=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"hydra_compaction",...e}});for(let r of this.broadcastHandlers)try{r({method:"session/update",params:s,recordedAt:Date.now()})}catch{}for(let r of this.clients.values())r.connection.notify("session/update",s).catch(()=>{});this.notifyChain("compaction",{...e})}attach(e,t,s={}){if(this.closed)throw re(new Error("session is closed"),k.SessionNotFound);if(this.clients.has(e.clientId))throw re(new Error(`client ${e.clientId} is already attached`),k.AlreadyAttached);return this.clients.set(e.clientId,e),this.updatedAt=Date.now(),t==="none"?Promise.resolve({entries:[],appliedPolicy:t}):t==="pending_only"?Promise.resolve({entries:this.buildStateSnapshotReplay(),appliedPolicy:t}):this.loadReplay(t,s)}async loadReplay(e,t){let s=a=>t.raw?a:Wr(a),i=(await this.getHistorySnapshot(t.toolContent??"inline")).filter(a=>!Zr(a.method,a.params)),o=this.buildStateSnapshotReplay();if(e==="after_message"){let a=t.afterMessageId?Qt(i,t.afterMessageId):-1;return a<0?{entries:[...o,...s(i)],appliedPolicy:"full"}:{entries:[...o,...s(i.slice(a+1))],appliedPolicy:"after_message"}}return{entries:[...o,...s(i)],appliedPolicy:"full"}}buildStateSnapshotReplay(){let e=[],t=this.sessionId,s=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:s}),this.currentModel!==void 0&&this.currentModel.length>0||this.agentAdvertisedModels.length>0){let i={sessionUpdate:"current_model_update"};this.currentModel!==void 0&&this.currentModel.length>0&&(i.currentModel=this.currentModel),this.agentAdvertisedModels.length>0&&(i.availableModels=[...this.agentAdvertisedModels]),e.push({method:"session/update",params:{sessionId:t,update:i},recordedAt:s})}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:s});let r=this.mergedAvailableCommands();if(r.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_commands_update",availableCommands:r}},recordedAt:s}),this.agentAdvertisedModes.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_modes_update",availableModes:[...this.agentAdvertisedModes]}},recordedAt:s}),this.currentUsage!==void 0){let i=this.currentUsage,o={sessionUpdate:"usage_update"};if(typeof i.used=="number"&&(o.used=i.used),typeof i.size=="number"&&(o.size=i.size),typeof i.costAmount=="number"||typeof i.costCurrency=="string"){let a={};typeof i.costAmount=="number"&&(a.amount=i.costAmount),typeof i.costCurrency=="string"&&(a.currency=i.costCurrency),o.cost=a}Object.keys(o).length>1&&e.push({method:"session/update",params:{sessionId:t,update:o},recordedAt:s})}return this._liveCompactionPhase!==void 0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"hydra_compaction",...this._liveCompactionPhase}},recordedAt:s}),e}replayPendingPermissions(e){for(let t of this.attentionFlags.values()){if(t.source!=="daemon"||!t.reason.startsWith("permission:"))continue;let s=t.reason.slice(11),r=this.permissionCallbacks.get(s);r&&r(e)}}detach(e){let t=this.clients.get(e);t&&(this.clients.delete(e),this.updatedAt=Date.now(),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 s={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:s}).catch(()=>{})}async prompt(e,t){let s=this.clients.get(e);if(!s)throw re(new Error("client not attached"),k.SessionNotFound);if(this.closing)throw re(new Error("session is closing; new prompts cannot be accepted"),k.SessionClosing);let r=Ee();if(this.maybeSeedTitleFromPrompt(t),this._firstPromptSeeded=!0,!(mt((t??{})._meta).ancillary===!0)&&this._interactive!==!0){this._interactive=!0;for(let o of this.interactiveHandlers)try{o(!0)}catch{}}return this.enqueueUserPrompt(s,t,r)}broadcastPromptReceived(e){let t={clientId:e.originator.clientId};e.originator.name&&(t.name=e.originator.name),e.originator.version&&(t.version=e.originator.version),this.promptStartedAt=Date.now(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"prompt_received",messageId:e.messageId,prompt:e.prompt,sentBy:t}},e.clientId);let s=Xe(e.prompt);s.length>0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:s},_meta:{"hydra-acp":{compatFor:"prompt_received"}}}},e.clientId)}recordCurrentUsageSnapshot(){if(this.historyStore===void 0)return;let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let r={};typeof e.costAmount=="number"&&(r.amount=e.costAmount),typeof e.costCurrency=="string"&&(r.currency=e.costCurrency),t.cost=r}if(Object.keys(t).length<=1)return;t._meta={"hydra-acp":{upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}};let s={sessionId:this.sessionId,update:t};this.historyStore.append(this.sessionId,{method:"session/update",params:s,recordedAt:Date.now()}).catch(()=>{})}broadcastTurnComplete(e,t,s,r){let i=t&&typeof t=="object"&&"stopReason"in t&&typeof t.stopReason=="string"?t.stopReason:void 0,o={sessionUpdate:"turn_complete",messageId:Ee()};i!==void 0&&(o.stopReason=i);let a=this.amendInProgress;a&&s!==void 0&&a.cancelledMessageId===s&&(o._meta={"hydra-acp":{amended:{cancelledMessageId:a.cancelledMessageId,newMessageId:a.newMessageId}}}),this.promptStartedAt=void 0,s!==void 0&&i!==void 0&&this.recordTerminal(s,i),this.recordCurrentUsageSnapshot(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:o},r?void 0:e),a&&s!==void 0&&a.cancelledMessageId===s&&this.broadcastPromptAmended(a)}recordTerminal(e,t){for(this.recentlyTerminal.set(e,{stopReason:t,terminatedAt:Date.now()});this.recentlyTerminal.size>Zd;){let s=this.recentlyTerminal.keys().next().value;if(s===void 0)break;this.recentlyTerminal.delete(s)}}broadcastPromptAmended(e){let t=this.findUserEntry(e.newMessageId);if(!t)return;let s={sessionId:this.sessionId,cancelledMessageId:e.cancelledMessageId,newMessageId:e.newMessageId,prompt:t.prompt,originator:t.originator,amendedAt:Date.now()};this.broadcastQueueNotification("hydra-acp/prompt/amended",s)}findUserEntry(e){if(this.currentEntry?.messageId===e&&this.currentEntry.kind==="user")return this.currentEntry;let t=this.promptQueue.find(s=>s.messageId===e&&s.kind==="user");return t?.kind==="user"?t:void 0}visibleQueueDepth(){let e=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;for(let t of this.promptQueue)t.kind==="user"&&!t.cancelled&&(e+=1);return e}broadcastQueueAdded(e,t){let s=this.visibleQueueDepth(),r=t?.position??Math.max(0,s-1),i={sessionId:this.sessionId,messageId:e.messageId,originator:e.originator,prompt:e.prompt,position:r,queueDepth:s,enqueuedAt:e.enqueuedAt};t?.amending!==void 0&&(i._meta={"hydra-acp":{amending:t.amending}}),this.broadcastQueueNotification("hydra-acp/prompt_queue/added",i)}broadcastQueueUpdated(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/updated",{sessionId:this.sessionId,messageId:e,prompt:t})}broadcastQueueRemoved(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/removed",{sessionId:this.sessionId,messageId:e,reason:t})}broadcastQueueNotification(e,t){for(let s of this.clients.values())s.connection.notify(e,t).catch(()=>{})}queueSnapshot(){let e=[],t=0;this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled&&e.push({messageId:this.currentEntry.messageId,originator:this.currentEntry.originator,prompt:this.currentEntry.prompt,position:t++,enqueuedAt:this.currentEntry.enqueuedAt});for(let s of this.promptQueue)s.kind!=="user"||s.cancelled||e.push({messageId:s.messageId,originator:s.originator,prompt:s.prompt,position:t++,enqueuedAt:s.enqueuedAt});return e}async flushPersistWrites(){await this.queueWriteChain.catch(()=>{})}replayPersistedQueue(e){for(let t of e){let s={clientId:`hydra-resurrected_${t.messageId}`};t.originator.clientInfo.name!==void 0&&(s.name=t.originator.clientInfo.name),t.originator.clientInfo.version!==void 0&&(s.version=t.originator.clientInfo.version);let r={kind:"user",messageId:t.messageId,originator:s,clientId:s.clientId,prompt:t.prompt,enqueuedAt:t.enqueuedAt,cancelled:!1,resolve:()=>{},reject:()=>{}};this.promptQueue.push(r),this.broadcastQueueAdded(r)}this.drainQueue()}cancelQueuedPrompt(e){if(this.currentEntry?.messageId===e)return{cancelled:!1,reason:"already_running"};let t=this.promptQueue.findIndex(r=>r.messageId===e);if(t<0)return{cancelled:!1,reason:"not_found"};let s=this.promptQueue[t];return s.cancelled=!0,this.promptQueue.splice(t,1),s.kind==="user"&&(this.broadcastQueueRemoved(e,"cancelled"),this.persistRewrite()),this.amendInProgress?.newMessageId===e&&(this.amendInProgress=void 0),s.resolve({stopReason:"cancelled"}),{cancelled:!0,reason:"ok"}}updateQueuedPrompt(e,t){if(this.currentEntry?.messageId===e)return{updated:!1,reason:"already_running"};let s=this.promptQueue.find(r=>r.messageId===e);return!s||s.kind!=="user"?{updated:!1,reason:"not_found"}:(s.prompt=t,this.broadcastQueueUpdated(e,t),this.persistRewrite(),{updated:!0,reason:"ok"})}amendPrompt(e,t){let s=this.clients.get(e);if(!s)throw re(new Error("client not attached"),k.SessionNotFound);let{targetMessageId:r,prompt:i,replaceQueue:o,onTargetCompleted:a}=t;if(this.currentEntry?.messageId===r&&this.currentEntry.kind==="user"&&!this.currentEntry.cancelled&&this.amendInProgress===void 0)return this.amendOnHead(s,i,r,o);let d=this.promptQueue.find(c=>c.messageId===r&&c.kind==="user");if(d&&d.kind==="user"&&!d.cancelled)return d.prompt=i,this.broadcastQueueUpdated(r,i),this.persistRewrite(),{amended:!0,reason:"ok",messageId:r};let u=this.recentlyTerminal.get(r);return u?u.stopReason==="cancelled"?{amended:!1,reason:"target_cancelled"}:a==="send_anyway"?{amended:!1,reason:"target_completed",messageId:this.enqueueAmendmentAsFollowUp(s,i)}:{amended:!1,reason:"target_completed"}:{amended:!1,reason:"target_not_found"}}amendOnHead(e,t,s,r){let i=Ee(),o={clientId:e.clientId};if(e.clientInfo?.name&&(o.name=e.clientInfo.name),e.clientInfo?.version&&(o.version=e.clientInfo.version),r){let d=[];for(let u of this.promptQueue){if(u.kind==="user"&&!u.cancelled){u.cancelled=!0,this.broadcastQueueRemoved(u.messageId,"cancelled"),u.resolve({stopReason:"cancelled"});continue}d.push(u)}this.promptQueue=d}let a={kind:"user",messageId:i,originator:o,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,wasAmend:!0,resolve:()=>{},reject:()=>{}};return this.promptQueue.unshift(a),this.persistRewrite(),this.broadcastQueueAdded(a,{amending:s,position:1}),this.amendInProgress={cancelledMessageId:s,newMessageId:i},this.cancelExtensionDispatch(s,"amended"),this.agent.connection.notify("session/cancel",{sessionId:this.upstreamSessionId}).catch(()=>{}),{amended:!0,reason:"ok",messageId:i}}enqueueAmendmentAsFollowUp(e,t){let s=Ee(),r={clientId:e.clientId};e.clientInfo?.name&&(r.name=e.clientInfo.name),e.clientInfo?.version&&(r.version=e.clientInfo.version);let i={kind:"user",messageId:s,originator:r,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,resolve:()=>{},reject:()=>{}};return this.promptQueue.push(i),this.persistRewrite(),this.broadcastQueueAdded(i),this.drainQueue(),s}async cancel(e){if(!this.clients.get(e))throw re(new Error("client not attached"),k.SessionNotFound);this.lastCancelAt=Date.now(),this.currentEntry?.kind==="user"&&this.currentEntry.messageId!==void 0&&this.cancelExtensionDispatch(this.currentEntry.messageId,"cancelled"),await this.forwardRequest("session/cancel",{sessionId:this.sessionId},new Set,0,"notification")}addTransformer(e){let t=this.transformChain.findIndex(s=>s.name===e.name);t>=0?this.transformChain[t]=e:this.transformChain.push(e),e.intercepts.has("lifecycle:session.opened")&&e.connection.notify("hydra-acp/transformer/session_event",{event:"session.opened",sessionId:this.sessionId}).catch(()=>{})}async forwardRequest(e,t,s=new Set,r=0,i="request"){let o=this.rewriteForAgent(t);for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(s.has(d.name))continue;let u=`request:${e}`;if(!d.intercepts.has(u))continue;let c=`t_${is()}`,f;try{f=await d.connection.request("hydra-acp/transformer/message",{token:c,phase:"request",method:e,direction:"client\u2192agent",sessionId:this.sessionId,envelope:o})}catch(l){this.logger?.warn(`transformer ${d.name} error on ${u}: ${l.message}`);continue}let p=f?.action??"continue";if(p==="stop")return i==="notification"?void 0:f?.payload??os(e);if(p==="continue"){f?.payload&&typeof f.payload=="object"&&(o=f.payload),s.add(d.name);continue}if(p==="processing"){let l=a,g=o,m=new Set(s);return new Promise(h=>{let y=setTimeout(()=>{this.pendingClaims.delete(c)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:c,transformerName:d.name}),this.forwardRequest(e,g,new Set([...m,d.name]),l+1,i).then(h).catch(()=>h(i==="notification"?void 0:os(e))))},Wt);typeof y.unref=="function"&&y.unref(),this.pendingClaims.set(c,{resolve:h,timer:y,transformerName:d.name,method:e,envelope:g,chainIdx:l,originatedBy:m,side:"request",tailKind:i})})}s.add(d.name)}if(i==="notification"){await this.agent.connection.notify(e,o);return}return this.agent.connection.request(e,o)}async runAgentRequestChain(e,t,s=new Set,r=0){let i=t,o=`request:${e}`;for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(s.has(d.name)||!d.intercepts.has(o))continue;let u=`t_${is()}`,c;try{c=await d.connection.request("hydra-acp/transformer/message",{token:u,phase:"request",method:e,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(p){this.logger?.warn(`transformer ${d.name} error on ${o}: ${p.message}`);continue}let f=c?.action??"continue";if(f==="stop")return{shortCircuit:!0,payload:c?.payload??pc(e)};if(f==="continue"){c?.payload&&typeof c.payload=="object"&&(i=c.payload),s.add(d.name);continue}if(f==="processing"){let p=a,l=i,g=new Set(s),m=e;return new Promise(h=>{let y=setTimeout(()=>{this.pendingClaims.delete(u)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:u,transformerName:d.name}),this.runAgentRequestChain(m,l,new Set([...g,d.name]),p+1).then(h).catch(()=>h({shortCircuit:!1,envelope:l})))},Wt);typeof y.unref=="function"&&y.unref(),this.pendingClaims.set(u,{resolve:v=>h({shortCircuit:!0,payload:v}),timer:y,transformerName:d.name,method:m,envelope:l,chainIdx:p,originatedBy:g,side:"agent-request"})})}s.add(d.name)}return{shortCircuit:!1,envelope:i}}dischargeClaim(e,t){let s=this.pendingClaims.get(e);return s?(clearTimeout(s.timer),this.pendingClaims.delete(e),s.resolve(t),!0):!1}keepAliveClaim(e,t){let s=this.pendingClaims.get(e);if(!s)return!1;clearTimeout(s.timer);let r=typeof t=="number"&&t>0?Math.min(t*1.5,1800*1e3):Wt,i=setTimeout(()=>{if(this.pendingClaims.delete(e))if(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:e,transformerName:s.transformerName}),s.side==="response")this.runResponseChain(s.envelope,new Set([...s.originatedBy,s.transformerName]),s.chainIdx+1).then(()=>s.resolve(void 0)).catch(()=>s.resolve(void 0));else if(s.side==="agent-request")this.runAgentRequestChain(s.method,s.envelope,new Set([...s.originatedBy,s.transformerName]),s.chainIdx+1).then(s.resolve).catch(()=>s.resolve({shortCircuit:!1,envelope:s.envelope}));else{let o=s.tailKind??"request";this.forwardRequest(s.method,s.envelope,new Set([...s.originatedBy,s.transformerName]),s.chainIdx+1,o).then(s.resolve).catch(()=>s.resolve(o==="notification"?void 0:os(s.method)))}},r);return typeof i.unref=="function"&&i.unref(),s.timer=i,!0}async emitToChain(e,t,s){let r=this.transformChain.findIndex(a=>a.name===e),i=r>=0?r+1:0,o=new Set([e]);if(t==="session/update"){await this.runResponseChain(s,o,i);return}return this.forwardRequest(t,s,o,i)}async emitToQueue(e,t){let s=this.transformChain.findIndex(u=>u.name===e),r=s>=0?s+1:0,i=(t??{}).prompt??[],o=Ee(),a=`transformer:${e}`,d={clientId:a,name:e};return new Promise((u,c)=>{let f={kind:"user",messageId:o,originator:d,clientId:a,prompt:i,enqueuedAt:Date.now(),cancelled:!1,emitterName:e,chainStartIdx:r,resolve:u,reject:c},p=this.insertEntryAt(f,"tail");this.persistRewrite(),this.broadcastQueueAdded(f,{position:p}),this.drainQueue()})}rewriteForAgent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.sessionId===this.sessionId)return{...t,sessionId:this.upstreamSessionId}}return e}async close(e={}){if(e.deleteRecord&&(this.deleteRecordIntent=!0),!this.closed)return this.closeInFlight?this.closeInFlight:(this.closing=!0,this.closeInFlight=this.doClose(e),this.closeInFlight)}async doClose(e){this.logger?.info(`session ${this.sessionId} closing deleteRecord=${e.deleteRecord??!1}`),this.cancelIdleTimer();for(let t of this.pendingClaims.values())clearTimeout(t.timer);this.pendingClaims.clear(),await this.agent.kill().catch(()=>{}),this.markClosed({deleteRecord:e.deleteRecord??!1})}onClose(e){return this.closeHandlers.push(e),()=>{let t=this.closeHandlers.indexOf(e);t>=0&&this.closeHandlers.splice(t,1)}}onTitleChange(e){this.titleHandlers.push(e)}retitle(e){return this.runTitleCommand(e)}retitleFromAgent(){return this.runTitleCommand("")}setTitle(e){let t=e.trim();if(!(!t||t===this.title)){this.title=t,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",title:t,updatedAt:new Date().toISOString()}});for(let s of this.titleHandlers)try{s(t)}catch{}}}maybeSeedTitleFromPrompt(e){if(this.firstPromptSeeded)return;let s=Xe((e??{}).prompt),r=as(s,200);r&&(r.startsWith("/")||(this._firstPromptSeeded=!0,this.setTitle(r)))}maybeApplyAgentModel(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="current_model_update")return!1;let r=Ze(s.availableModels);r.length>0&&this.setAgentAdvertisedModels(r);let i=typeof s.currentModel=="string"?s.currentModel:typeof s.model=="string"?s.model:void 0;if(i===void 0)return!0;let o=i.trim();if(!o||o===this.currentModel)return!0;this.logger?.info(`live current_model_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(o)}`),this.currentModel=o;for(let a of this.modelHandlers)try{a(o)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentConfigOption(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="config_option_update")return!1;let r=s.configOptions;if(!Array.isArray(r))return!0;for(let i of r){if(!i||typeof i!="object")continue;let o=i;if(o.id==="model"){let a=Ze(o.options);a.length>0&&this.setAgentAdvertisedModels(a);let d=o.currentValue;if(typeof d=="string"){let u=d.trim();u&&u!==this.currentModel&&(this.logger?.info(`live config_option_update(model): sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(u)}`),this.applyModelChange(u))}}else if(o.id==="mode"){let a=wt(o.options);a.length>0&&this.setAgentAdvertisedModes(a);let d=o.currentValue;if(typeof d=="string"){let u=d.trim();u&&u!==this.currentMode&&(this.logger?.info(`live config_option_update(mode): sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(u)}`),this.applyModeChange(u))}}else if(typeof o.id=="string"&&o.id.trim()){let a=o.id.trim(),d=Ze(o.options);if(d.length>0){let u=wt(o.options),c=u.length>0?u.map(h=>({value:h.id,name:h.name??h.id})):d.map(h=>({value:h.modelId,name:h.name??h.modelId})),f=o.name,p=typeof f=="string"&&f.trim()?f.trim():a,l=o.currentValue,g=typeof l=="string"&&l.trim()?l.trim():c[0]?.value??"",m=this.agentAdvertisedConfigOptions.findIndex(h=>h.id===a);if(m>=0){let h={...this.agentAdvertisedConfigOptions[m]};h.options=c,typeof l=="string"&&l.trim()&&(h.currentValue=l.trim()),this.agentAdvertisedConfigOptions[m]=h}else this.agentAdvertisedConfigOptions.push({id:a,name:p,category:"other",type:"select",currentValue:g,options:c})}}}return!0}maybeApplyAgentMode(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="current_mode_update")return!1;let r=typeof s.currentModeId=="string"?s.currentModeId:typeof s.currentMode=="string"?s.currentMode:typeof s.mode=="string"?s.mode:void 0;if(r===void 0)return!0;let i=r.trim();if(!i||i===this.currentMode)return!0;this.logger?.info(`current_mode_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(i)}`),this.currentMode=i;for(let o of this.modeHandlers)try{o(i)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentUsage(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="usage_update")return!1;let r={...this._currentUsage??{}},i=!1;if(typeof s.used=="number"&&r.used!==s.used&&(r.used=s.used,i=!0),typeof s.size=="number"&&r.size!==s.size&&(r.size=s.size,i=!0),s.cost&&typeof s.cost=="object"){let a=s.cost;typeof a.amount=="number"&&(this.reconcileCostLedger(a.amount)&&(i=!0),r.costAmount!==a.amount&&(r.costAmount=a.amount,i=!0)),typeof a.currency=="string"&&r.costCurrency!==a.currency&&(r.costCurrency=a.currency,i=!0)}if(!i)return!0;this._currentUsage=r;let o=this.persistableUsage??r;for(let a of this.usageHandlers)try{a(o)}catch{}return!0}armCostLedgerProbe(){let e=this._currentUsage?.costAmount;typeof e=="number"&&e>0&&(this.costLedgerProbe=e)}reconcileCostLedger(e){let t=this.costLedgerProbe;return t===void 0||(this.costLedgerProbe=void 0,e>=t-1e-6)?!1:(this.cumulativeCost+=t,!0)}notifyAgentChange(e){let t=this.retiringGenerationCost;this.retiringGenerationCost=void 0;for(let s of this.agentChangeHandlers)try{s({agentId:this.agentId,upstreamSessionId:this.upstreamSessionId,...t!==void 0?{retiredCost:t}:{}})}catch(r){this.logger?.warn(`${e}: agentChange handler failed: ${r.message}`)}}accumulateAndResetCost(){let e=this._currentUsage?.costAmount;e&&(this.cumulativeCost+=e,this.retiringGenerationCost=e);let t={used:0,cumulativeCost:this.cumulativeCost,...typeof this._currentUsage?.size=="number"?{size:this._currentUsage.size}:{},...this._currentUsage?.costCurrency?{costCurrency:this._currentUsage.costCurrency}:{}};this._currentUsage=t;for(let r of this.usageHandlers)try{r(t)}catch{}let s=this.currentUsage;if(s!==void 0){let r={sessionUpdate:"usage_update"};if(typeof s.used=="number"&&(r.used=s.used),typeof s.size=="number"&&(r.size=s.size),typeof s.costAmount=="number"||typeof s.costCurrency=="string"){let i={};typeof s.costAmount=="number"&&(i.amount=s.costAmount),typeof s.costCurrency=="string"&&(i.currency=s.costCurrency),r.cost=i}this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:r})}}injectCumulativeCost(e){if(!this.cumulativeCost||!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let s=t.update;if(s.sessionUpdate!=="usage_update"||!s.cost||typeof s.cost!="object")return e;let r=s.cost;return typeof r.amount!="number"?e:{...t,update:{...s,cost:{...r,amount:this.cumulativeCost+r.amount}}}}get totalUsage(){return this.currentUsage}setAgentAdvertisedCommands(e){if(tc(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(nc(this.agentAdvertisedModes,e)){this.broadcastAvailableModes();return}this.agentAdvertisedModes=e;for(let t of this.agentModesHandlers)try{t(e)}catch{}this.broadcastAvailableModes()}setAgentAdvertisedModels(e){if(this.logger?.info(`setAgentAdvertisedModels: sessionId=${this.sessionId} currentModel=${JSON.stringify(this.currentModel)} newList=[${e.map(t=>t.modelId).join(",")}]`),sc(this.agentAdvertisedModels,e)){this.broadcastAvailableModels();return}this.agentAdvertisedModels=e;for(let t of this.agentModelsHandlers)try{t(e)}catch{}this.broadcastAvailableModels()}onAgentCommandsChange(e){this.agentCommandsHandlers.push(e)}onAgentModesChange(e){this.agentModesHandlers.push(e)}onAgentModelsChange(e){this.agentModelsHandlers.push(e)}onModelChange(e){this.modelHandlers.push(e)}onModeChange(e){this.modeHandlers.push(e)}onInteractiveChange(e){this.interactiveHandlers.push(e)}onPriorityChange(e){this.priorityHandlers.push(e)}setPriority(e){let t=e===void 0||e<=0?void 0:Math.floor(e);if(t!==this._priority){this._priority=t,this.updatedAt=Date.now();for(let s of this.priorityHandlers)try{s(t)}catch{}}}applyModelChange(e){let t=e.trim();if(t){this.modelChangeInFlight=!0;try{if(t!==this.currentModel){this.logger?.info(`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(t)}`),this.currentModel=t;for(let r of this.modelHandlers)try{r(t)}catch{}}let s={sessionUpdate:"current_model_update",currentModel:t};this.agentAdvertisedModels.length>0&&(s.availableModels=[...this.agentAdvertisedModels]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:s}),this.broadcastConfigOptions()}finally{this.modelChangeInFlight=!1}}}applyModeChange(e){let t=e.trim();if(t){this.modeChangeInFlight=!0;try{if(t!==this.currentMode){this.logger?.info(`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(t)}`),this.currentMode=t;for(let r of this.modeHandlers)try{r(t)}catch{}}let s={sessionUpdate:"current_mode_update",currentModeId:t};this.agentAdvertisedModes.length>0&&(s.availableModes=[...this.agentAdvertisedModes]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:s}),this.broadcastConfigOptions()}finally{this.modeChangeInFlight=!1}}}buildConfigOptions(){let e=[];if(this.agentAdvertisedModels.length>0){let r=this.agentAdvertisedModels.map(o=>({value:o.modelId,name:o.name??o.modelId,...o.description!==void 0?{description:o.description}:{}})),i=this.currentModel&&r.some(o=>o.value===this.currentModel)?this.currentModel:r[0].value;e.push({id:"model",name:"Model",category:"model",type:"select",currentValue:i,options:r})}if(this.agentAdvertisedModes.length>0){let r=this.agentAdvertisedModes.map(o=>({value:o.id,name:o.name??o.id,...o.description!==void 0?{description:o.description}:{}})),i=this.currentMode&&r.some(o=>o.value===this.currentMode)?this.currentMode:r[0].value;e.push({id:"mode",name:"Session Mode",category:"mode",type:"select",currentValue:i,options:r})}let s=(this.availableAgentsFn?.()??[]).map(r=>({value:r.id,name:r.name??r.id,...r.description!==void 0?{description:r.description}:{}}));return s.some(r=>r.value===this.agentId)||s.unshift({value:this.agentId,name:this.agentId}),e.push({id:"agent",name:"Agent",category:"_hydra_agent",type:"select",currentValue:this.agentId,options:s}),e.push(...this.agentAdvertisedConfigOptions),e}broadcastConfigOptions(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"config_option_update",configOptions:this.buildConfigOptions()}})}mergeAgentOptionIntoEnvelope(e){if(!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let s=t.update,r=Array.isArray(s.configOptions)?[...s.configOptions]:[];if(r.some(a=>a&&typeof a=="object"&&a.id==="agent"))return e;let o=this.buildConfigOptions().find(a=>a.id==="agent");return o?{...t,update:{...s,configOptions:[...r,o]}}:e}onUsageChange(e){this.usageHandlers.push(e)}mergedAvailableCommands(){let e=this.daemonTopLevelCommands(),t=this.aliasableBareVerbs();for(let s of Ke){if(t.get(s.verb)!=="__hydra__")continue;let r=s.argsHint?`${s.verb} ${s.argsHint}`:s.verb;e.push({name:r,description:`Alias for '/hydra ${s.verb}': ${s.description}`})}if(this.extensionCommands)for(let{name:s,command:r}of this.extensionCommands.list()){let i=r.verb?`hydra ${s} ${r.verb}`:`hydra ${s}`,a={name:r.argsHint?`${i} ${r.argsHint}`:i};r.description&&(a.description=r.description),e.push(a);let d=s.startsWith("hydra-acp-")?s.slice(10):s;if(s.startsWith("hydra-acp-")&&d.length>0){let u=r.verb?`hydra ${d} ${r.verb}`:`hydra ${d}`,f={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(f.description=r.description),e.push(f)}if(d.length>0&&t.get(d)===s){let u=r.verb?`${d} ${r.verb}`:d,f={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(f.description=r.description),e.push(f)}}return e.push(...this.agentAdvertisedCommands),e}daemonTopLevelCommands(){return[{name:"hydra",description:"Hydra session command (kill, restart, title, agent <agent>)"},{name:"model",description:"Switch model; omit arg to list available models"},{name:"mode",description:"Switch mode; omit arg to list available modes"},{name:"sessions",description:"List all sessions"},{name:"help",description:"Show available commands"}]}aliasableBareVerbs(){let e=new Set,t=o=>o.split(/\s+/)[0]??"";for(let o of this.daemonTopLevelCommands()){let a=t(o.name);a&&e.add(a)}for(let o of this.agentAdvertisedCommands){let a=t(o.name),d=a.startsWith("/")?a.slice(1):a;d&&e.add(d)}let s=new Map;for(let o of Ke)e.has(o.verb)||s.set(o.verb,"__hydra__");if(!this.extensionCommands)return s;let r=new Map,i=new Set;for(let{name:o}of this.extensionCommands.list()){if(i.has(o))continue;i.add(o);let a=o.startsWith("hydra-acp-")?o.slice(10):o;if(!a||e.has(a)||s.has(a))continue;let d=r.get(a);d===void 0?r.set(a,o):d!==o&&r.set(a,"__conflict__")}for(let[o,a]of r)a!=="__conflict__"&&s.set(o,a);return s}agentOnlyAdvertisedCommands(){return[...this.agentAdvertisedCommands]}agentKnowsSlashCommand(e){let t=r=>r.startsWith("/")?r.slice(1):r,s=t(e);if(!s)return!1;for(let r of this.agentAdvertisedCommands)if(t(r.name.split(/\s+/)[0]??"")===s)return!0;return!1}availableModes(){return[...this.agentAdvertisedModes]}availableModels(){return[...this.agentAdvertisedModels]}maybeApplyAgentSessionInfo(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="session_info_update"||typeof s.title!="string")return;let r=s.title.trim();if(!(!r||r===this.title)){this.title=r,this._firstPromptSeeded=!0;for(let i of this.titleHandlers)try{i(r)}catch{}}}async handleSlashCommand(e,t){let r=e.slice(6).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),i=r?.[1]??"",o=(r?.[2]??"").trim();if(i==="")return{stopReason:"end_turn"};let a=t!==void 0;if(Ke.some(f=>f.verb===i))switch(i){case"title":return a?this.runTitleCommandInline(o):this.runTitleCommand(o);case"agent":return a?this.runAgentCommandInline(o):this.runAgentCommand(o);case"config":return this.handleConfigCommand(`/config ${o}`);case"kill":return this.runKillCommand();case"restart":return a?this.runRestartCommandInline():this.runRestartCommand();case"compact":return a?this.runCompactCommandInline(o):this.runCompactCommand(o);case"uncompact":return a?this.runUncompactCommandInline():this.runUncompactCommand();case"fork":return a?this.runForkCommandInline(o,t):this.runForkCommand(o);default:{let f=new Error(`no dispatcher for /hydra verb ${i}`);throw f.code=k.InternalError,f}}if(this.extensionCommands?.has(i))return a?this.runExtensionCommandInline(i,o,t):this.runExtensionCommand(i,o);let d=`hydra-acp-${i}`;if(this.extensionCommands?.has(d))return a?this.runExtensionCommandInline(d,o,t):this.runExtensionCommand(d,o);let u=Ke.map(f=>f.verb);if(this.extensionCommands){let f=new Set;for(let{name:p}of this.extensionCommands.list())f.has(p)||(u.push(p),f.add(p))}let c=new Error(`unknown /hydra verb: ${i} (known: ${u.join(", ")})`);throw c.code=k.InvalidParams,c}runExtensionCommand(e,t){return this.enqueuePrompt(()=>this.runExtensionCommandInline(e,t,void 0))}async runExtensionCommandInline(e,t,s){let r=this.extensionCommands?.get(e);if(!r)return this.emitExtensionReply(`extension "${e}" is no longer connected`);let i=t.match(/^(\S+)(?:\s+([\s\S]*))?$/),o=i?.[1]??"",a=(i?.[2]??"").trim();if(!r.commands.some(g=>g.verb===o)){let g=r.commands.map(m=>m.verb).join(", ");return this.emitExtensionReply(`/hydra ${e}${o?` ${o}`:""}: unknown verb (known: ${g||"(none)"})`)}let d={sessionId:this.sessionId,verb:o,args:a};s!==void 0&&(d.messageId=s);let u=()=>{},c=new Promise(g=>{u=g});s!==void 0&&this.inFlightExtensionDispatches.set(s,{extensionName:e,connection:r.connection,cancel:g=>u({stopReason:"cancelled",reason:g})});let f,p=!1;try{let g=r.connection.request("hydra-acp/commands/invoke",d),m=await Promise.race([g,c]);if(m&&typeof m=="object"&&m.stopReason==="cancelled"&&"reason"in m)return p=!0,this.logger?.info(`extension ${e} ${o} cancelled (cancelExtensionDispatch); abandoning in-flight commands/invoke`),{stopReason:"cancelled"};f=m}catch(g){return this.emitExtensionReply(`${e} ${o}: ${g.message}`)}finally{s!==void 0&&!p&&this.inFlightExtensionDispatches.delete(s)}let l=f&&typeof f=="object"&&typeof f.text=="string"?f.text:"";return l.length>0?this.emitExtensionReply(l):{stopReason:"end_turn"}}cancelExtensionDispatch(e,t){let s=this.inFlightExtensionDispatches.get(e);if(!s)return!1;this.inFlightExtensionDispatches.delete(e);try{s.connection.notify("hydra-acp/commands/cancel",{sessionId:this.sessionId,messageId:e,reason:t})}catch(r){this.logger?.warn(`notify commands/cancel to ${s.extensionName} failed: ${r.message}`)}return s.cancel(t),!0}emitExtensionReply(e){return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
34
+ `,v=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:w},_meta:{"hydra-acp":{synthetic:!0}}}});for(let A of this.clients.values())A.connection.notify("session/update",v).catch(()=>{});this.updatedAt=Date.now()}async rollbackToUpstream(e){if(!await this.isQuiescedForSwap())throw new Error("session is not quiesced for rollback \u2014 wait for in-flight work to complete");let s=this.loadExistingAgentSession;if(!s)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,u=this.currentMode,c=await s(e.previousUpstreamSessionId,{agentId:r,cwd:o,agentArgs:i,...a?{forwardedEnv:a}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(c.agent),await Ke({agent:c.agent,upstreamSessionId:c.upstreamSessionId,persistedModel:d,agentReportedModel:c.initialModel,logger:this.logger}),await Ge({agent:c.agent,upstreamSessionId:c.upstreamSessionId,persistedMode:u,agentReportedMode:c.initialMode,logger:this.logger}),c.agent.connection.drainBuffered("session/update");let f=this.agent;this.agent=c.agent,this.upstreamSessionId=c.upstreamSessionId,this.agentMeta=c.agentMeta,this.agentCapabilities=c.agentCapabilities,this.resetModelVerb(c.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await f.kill().catch(()=>{}),this._summarizedThroughEntry=e.previousSummarizedThroughEntry,this.broadcastCompactionPhase({phase:"rolled_back",summarizedThroughEntry:e.previousSummarizedThroughEntry??0}),this.notifyAgentChange("rollbackToUpstream"),this.updatedAt=Date.now()}async _hasOpenToolCall(e=gc){if(!this.historyStore)return!1;let t=await this.historyStore.load(this.sessionId),s=t.length>e?t.slice(-e):t,r=new Set,o=new Set;for(let i of s){let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let u=d.sessionUpdate,c=typeof d.toolCallId=="string"?d.toolCallId:void 0;if(c){if(u==="tool_call")r.add(c);else if(u==="tool_call_update"){let f=d.status;(f==="completed"||f==="failed")&&o.add(c)}}}for(let i of r)if(!o.has(i))return!0;return!1}async getHistorySnapshot(e="inline"){return this.historyStore?this.historyStore.load(this.sessionId,{tools:e}).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 s of this.clients.values())s.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 s=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"hydra_compaction",...e}});for(let r of this.broadcastHandlers)try{r({method:"session/update",params:s,recordedAt:Date.now()})}catch{}for(let r of this.clients.values())r.connection.notify("session/update",s).catch(()=>{});this.notifyChain("compaction",{...e})}attach(e,t,s={}){if(this.closed)throw re(new Error("session is closed"),k.SessionNotFound);if(this.clients.has(e.clientId))throw re(new Error(`client ${e.clientId} is already attached`),k.AlreadyAttached);return this.clients.set(e.clientId,e),this.updatedAt=Date.now(),t==="none"?Promise.resolve({entries:[],appliedPolicy:t}):t==="pending_only"?Promise.resolve({entries:this.buildStateSnapshotReplay(),appliedPolicy:t}):this.loadReplay(t,s)}async loadReplay(e,t){let s=a=>t.raw?a:io(a),o=(await this.getHistorySnapshot(t.toolContent??"inline")).filter(a=>!mo(a.method,a.params)),i=this.buildStateSnapshotReplay();if(e==="after_message"){let a=t.afterMessageId?Zt(o,t.afterMessageId):-1;return a<0?{entries:[...i,...s(o)],appliedPolicy:"full"}:{entries:[...i,...s(o.slice(a+1))],appliedPolicy:"after_message"}}return{entries:[...i,...s(o)],appliedPolicy:"full"}}buildStateSnapshotReplay(){let e=[],t=this.sessionId,s=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:s}),this.currentModel!==void 0&&this.currentModel.length>0||this.agentAdvertisedModels.length>0){let o={sessionUpdate:"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:s})}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:s});let r=this.mergedAvailableCommands();if(r.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_commands_update",availableCommands:r}},recordedAt:s}),this.agentAdvertisedModes.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_modes_update",availableModes:[...this.agentAdvertisedModes]}},recordedAt:s}),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:s})}return this._liveCompactionPhase!==void 0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"hydra_compaction",...this._liveCompactionPhase}},recordedAt:s}),e}replayPendingPermissions(e){for(let t of this.attentionFlags.values()){if(t.source!=="daemon"||!t.reason.startsWith("permission:"))continue;let s=t.reason.slice(11),r=this.permissionCallbacks.get(s);r&&r(e)}}detach(e){let t=this.clients.get(e);t&&(this.clients.delete(e),this.updatedAt=Date.now(),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 s={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:s}).catch(()=>{})}async prompt(e,t,s){let r=this.clients.get(e);if(!r)throw re(new Error("client not attached"),k.SessionNotFound);if(this.closing)throw re(new Error("session is closing; new prompts cannot be accepted"),k.SessionClosing);let o=Te();if(this.maybeSeedTitleFromPrompt(t),this._firstPromptSeeded=!0,!(Je((t??{})._meta).ancillary===!0)&&this._interactive!==!0){this._interactive=!0;for(let a of this.interactiveHandlers)try{a(!0)}catch{}}return this.enqueueUserPrompt(r,t,o,s)}broadcastPromptReceived(e){let t={clientId:e.originator.clientId};e.originator.name&&(t.name=e.originator.name),e.originator.version&&(t.version=e.originator.version),e.originator.fromSession&&(t.fromSession=e.originator.fromSession),e.originator.fromSessionTitle&&(t.fromSessionTitle=e.originator.fromSessionTitle),e.originator.fromLabel&&(t.fromLabel=e.originator.fromLabel),e.originator.depth!==void 0&&(t.depth=e.originator.depth),this.promptStartedAt=Date.now(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"prompt_received",messageId:e.messageId,prompt:e.prompt,sentBy:t}},e.clientId);let s=tt(e.prompt);s.length>0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:s},_meta:{"hydra-acp":{compatFor:"prompt_received"}}}},e.clientId)}recordCurrentUsageSnapshot(){if(this.historyStore===void 0)return;let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let r={};typeof e.costAmount=="number"&&(r.amount=e.costAmount),typeof e.costCurrency=="string"&&(r.currency=e.costCurrency),t.cost=r}if(Object.keys(t).length<=1)return;t._meta={"hydra-acp":{upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}};let s={sessionId:this.sessionId,update:t};this.historyStore.append(this.sessionId,{method:"session/update",params:s,recordedAt:Date.now()}).catch(()=>{})}broadcastTurnComplete(e,t,s,r){let o=t&&typeof t=="object"&&"stopReason"in t&&typeof t.stopReason=="string"?t.stopReason:void 0,i={sessionUpdate:"turn_complete",messageId:Te()};o!==void 0&&(i.stopReason=o);let a=this.amendInProgress;a&&s!==void 0&&a.cancelledMessageId===s&&(i._meta={"hydra-acp":{amended:{cancelledMessageId:a.cancelledMessageId,newMessageId:a.newMessageId}}}),this.promptStartedAt=void 0,s!==void 0&&o!==void 0&&this.recordTerminal(s,o),this.recordCurrentUsageSnapshot(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:i},r?void 0:e),a&&s!==void 0&&a.cancelledMessageId===s&&this.broadcastPromptAmended(a)}recordTerminal(e,t){for(this.recentlyTerminal.set(e,{stopReason:t,terminatedAt:Date.now()});this.recentlyTerminal.size>bc;){let s=this.recentlyTerminal.keys().next().value;if(s===void 0)break;this.recentlyTerminal.delete(s)}}broadcastPromptAmended(e){let t=this.findUserEntry(e.newMessageId);if(!t)return;let s={sessionId:this.sessionId,cancelledMessageId:e.cancelledMessageId,newMessageId:e.newMessageId,prompt:t.prompt,originator:t.originator,amendedAt:Date.now()};this.broadcastQueueNotification("hydra-acp/prompt/amended",s)}findUserEntry(e){if(this.currentEntry?.messageId===e&&this.currentEntry.kind==="user")return this.currentEntry;let t=this.promptQueue.find(s=>s.messageId===e&&s.kind==="user");return t?.kind==="user"?t:void 0}visibleQueueDepth(){let e=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;for(let t of this.promptQueue)t.kind==="user"&&!t.cancelled&&(e+=1);return e}broadcastQueueAdded(e,t){let s=this.visibleQueueDepth(),r=t?.position??Math.max(0,s-1),o={sessionId:this.sessionId,messageId:e.messageId,originator:e.originator,prompt:e.prompt,position:r,queueDepth:s,enqueuedAt:e.enqueuedAt};t?.amending!==void 0&&(o._meta={"hydra-acp":{amending:t.amending}}),this.broadcastQueueNotification("hydra-acp/prompt_queue/added",o)}broadcastQueueUpdated(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/updated",{sessionId:this.sessionId,messageId:e,prompt:t})}broadcastQueueRemoved(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/removed",{sessionId:this.sessionId,messageId:e,reason:t})}broadcastQueueNotification(e,t){for(let s of this.clients.values())s.connection.notify(e,t).catch(()=>{})}queueSnapshot(){let e=[],t=0;this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled&&e.push({messageId:this.currentEntry.messageId,originator:this.currentEntry.originator,prompt:this.currentEntry.prompt,position:t++,enqueuedAt:this.currentEntry.enqueuedAt});for(let s of this.promptQueue)s.kind!=="user"||s.cancelled||e.push({messageId:s.messageId,originator:s.originator,prompt:s.prompt,position:t++,enqueuedAt:s.enqueuedAt});return e}async flushPersistWrites(){await this.queueWriteChain.catch(()=>{})}replayPersistedQueue(e){for(let t of e){let s={clientId:`hydra-resurrected_${t.messageId}`};t.originator.clientInfo.name!==void 0&&(s.name=t.originator.clientInfo.name),t.originator.clientInfo.version!==void 0&&(s.version=t.originator.clientInfo.version);let r={kind:"user",messageId:t.messageId,originator:s,clientId:s.clientId,prompt:t.prompt,enqueuedAt:t.enqueuedAt,cancelled:!1,resolve:()=>{},reject:()=>{}};this.promptQueue.push(r),this.broadcastQueueAdded(r)}this.drainQueue()}cancelQueuedPrompt(e){if(this.currentEntry?.messageId===e)return{cancelled:!1,reason:"already_running"};let t=this.promptQueue.findIndex(r=>r.messageId===e);if(t<0)return{cancelled:!1,reason:"not_found"};let s=this.promptQueue[t];return s.cancelled=!0,this.promptQueue.splice(t,1),s.kind==="user"&&(this.broadcastQueueRemoved(e,"cancelled"),this.persistRewrite()),this.amendInProgress?.newMessageId===e&&(this.amendInProgress=void 0),s.resolve({stopReason:"cancelled"}),{cancelled:!0,reason:"ok"}}updateQueuedPrompt(e,t){if(this.currentEntry?.messageId===e)return{updated:!1,reason:"already_running"};let s=this.promptQueue.find(r=>r.messageId===e);return!s||s.kind!=="user"?{updated:!1,reason:"not_found"}:(s.prompt=t,this.broadcastQueueUpdated(e,t),this.persistRewrite(),{updated:!0,reason:"ok"})}amendPrompt(e,t){let s=this.clients.get(e);if(!s)throw re(new Error("client not attached"),k.SessionNotFound);let{targetMessageId:r,prompt:o,replaceQueue:i,onTargetCompleted:a}=t;if(this.currentEntry?.messageId===r&&this.currentEntry.kind==="user"&&!this.currentEntry.cancelled&&this.amendInProgress===void 0)return this.amendOnHead(s,o,r,i);let d=this.promptQueue.find(c=>c.messageId===r&&c.kind==="user");if(d&&d.kind==="user"&&!d.cancelled)return d.prompt=o,this.broadcastQueueUpdated(r,o),this.persistRewrite(),{amended:!0,reason:"ok",messageId:r};let u=this.recentlyTerminal.get(r);return u?u.stopReason==="cancelled"?{amended:!1,reason:"target_cancelled"}:a==="send_anyway"?{amended:!1,reason:"target_completed",messageId:this.enqueueAmendmentAsFollowUp(s,o)}:{amended:!1,reason:"target_completed"}:{amended:!1,reason:"target_not_found"}}amendOnHead(e,t,s,r){let o=Te(),i={clientId:e.clientId};if(e.clientInfo?.name&&(i.name=e.clientInfo.name),e.clientInfo?.version&&(i.version=e.clientInfo.version),r){let d=[];for(let u of this.promptQueue){if(u.kind==="user"&&!u.cancelled){u.cancelled=!0,this.broadcastQueueRemoved(u.messageId,"cancelled"),u.resolve({stopReason:"cancelled"});continue}d.push(u)}this.promptQueue=d}let a={kind:"user",messageId:o,originator:i,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,wasAmend:!0,resolve:()=>{},reject:()=>{}};return this.promptQueue.unshift(a),this.persistRewrite(),this.broadcastQueueAdded(a,{amending:s,position:1}),this.amendInProgress={cancelledMessageId:s,newMessageId:o},this.cancelExtensionDispatch(s,"amended"),this.agent.connection.notify("session/cancel",{sessionId:this.upstreamSessionId}).catch(()=>{}),{amended:!0,reason:"ok",messageId:o}}enqueueAmendmentAsFollowUp(e,t){let s=Te(),r={clientId:e.clientId};e.clientInfo?.name&&(r.name=e.clientInfo.name),e.clientInfo?.version&&(r.version=e.clientInfo.version);let o={kind:"user",messageId:s,originator:r,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,resolve:()=>{},reject:()=>{}};return this.promptQueue.push(o),this.persistRewrite(),this.broadcastQueueAdded(o),this.drainQueue(),s}async cancel(e){if(!this.clients.get(e))throw re(new Error("client not attached"),k.SessionNotFound);this.lastCancelAt=Date.now(),this.currentEntry?.kind==="user"&&this.currentEntry.messageId!==void 0&&this.cancelExtensionDispatch(this.currentEntry.messageId,"cancelled"),await this.forwardRequest("session/cancel",{sessionId:this.sessionId},new Set,0,"notification")}addTransformer(e){let t=this.transformChain.findIndex(s=>s.name===e.name);t>=0?this.transformChain[t]=e:this.transformChain.push(e),e.intercepts.has("lifecycle:session.opened")&&e.connection.notify("hydra-acp/transformer/session_event",{event:"session.opened",sessionId:this.sessionId}).catch(()=>{})}async forwardRequest(e,t,s=new Set,r=0,o="request"){let i=this.rewriteForAgent(t);for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(s.has(d.name))continue;let u=`request:${e}`;if(!d.intercepts.has(u))continue;let c=`t_${fs()}`,f;try{f=await d.connection.request("hydra-acp/transformer/message",{token:c,phase:"request",method:e,direction:"client\u2192agent",sessionId:this.sessionId,envelope:i})}catch(l){this.logger?.warn(`transformer ${d.name} error on ${u}: ${l.message}`);continue}let p=f?.action??"continue";if(p==="stop")return o==="notification"?void 0:f?.payload??ps(e);if(p==="continue"){f?.payload&&typeof f.payload=="object"&&(i=f.payload),s.add(d.name);continue}if(p==="processing"){let l=a,m=i,g=new Set(s);return new Promise(h=>{let y=setTimeout(()=>{this.pendingClaims.delete(c)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:c,transformerName:d.name}),this.forwardRequest(e,m,new Set([...g,d.name]),l+1,o).then(h).catch(()=>h(o==="notification"?void 0:ps(e))))},Xt);typeof y.unref=="function"&&y.unref(),this.pendingClaims.set(c,{resolve:h,timer:y,transformerName:d.name,method:e,envelope:m,chainIdx:l,originatedBy:g,side:"request",tailKind:o})})}s.add(d.name)}if(o==="notification"){await this.agent.connection.notify(e,i);return}return this.agent.connection.request(e,i)}async forwardModelChange(e,t){let s=await Qe({request:(r,o)=>this.forwardRequest(r,o),sessionId:this.sessionId,modelId:e,verb:this.modelVerb,extraParams:t,logger:this.logger});return this.modelVerb=s.verb,this.modelVerbConfirmed=!0,s.result}noteModelVerbHint(e,t){e===void 0||this.modelVerbConfirmed||e===this.modelVerb||(this.logger?.info(`model verb for agent ${this.agentId} inferred as ${e} from ${t} (was ${this.modelVerb})`),this.modelVerb=e)}resetModelVerb(e){this.modelVerb=e??he,this.modelVerbConfirmed=!1}async runAgentRequestChain(e,t,s=new Set,r=0){let o=t,i=`request:${e}`;for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(s.has(d.name)||!d.intercepts.has(i))continue;let u=`t_${fs()}`,c;try{c=await d.connection.request("hydra-acp/transformer/message",{token:u,phase:"request",method:e,direction:"agent\u2192client",sessionId:this.sessionId,envelope:o})}catch(p){this.logger?.warn(`transformer ${d.name} error on ${i}: ${p.message}`);continue}let f=c?.action??"continue";if(f==="stop")return{shortCircuit:!0,payload:c?.payload??$c(e)};if(f==="continue"){c?.payload&&typeof c.payload=="object"&&(o=c.payload),s.add(d.name);continue}if(f==="processing"){let p=a,l=o,m=new Set(s),g=e;return new Promise(h=>{let y=setTimeout(()=>{this.pendingClaims.delete(u)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:u,transformerName:d.name}),this.runAgentRequestChain(g,l,new Set([...m,d.name]),p+1).then(h).catch(()=>h({shortCircuit:!1,envelope:l})))},Xt);typeof y.unref=="function"&&y.unref(),this.pendingClaims.set(u,{resolve:b=>h({shortCircuit:!0,payload:b}),timer:y,transformerName:d.name,method:g,envelope:l,chainIdx:p,originatedBy:m,side:"agent-request"})})}s.add(d.name)}return{shortCircuit:!1,envelope:o}}dischargeClaim(e,t){let s=this.pendingClaims.get(e);return s?(clearTimeout(s.timer),this.pendingClaims.delete(e),s.resolve(t),!0):!1}keepAliveClaim(e,t){let s=this.pendingClaims.get(e);if(!s)return!1;clearTimeout(s.timer);let r=typeof t=="number"&&t>0?Math.min(t*1.5,1800*1e3):Xt,o=setTimeout(()=>{if(this.pendingClaims.delete(e))if(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:e,transformerName:s.transformerName}),s.side==="response")this.runResponseChain(s.envelope,new Set([...s.originatedBy,s.transformerName]),s.chainIdx+1).then(()=>s.resolve(void 0)).catch(()=>s.resolve(void 0));else if(s.side==="agent-request")this.runAgentRequestChain(s.method,s.envelope,new Set([...s.originatedBy,s.transformerName]),s.chainIdx+1).then(s.resolve).catch(()=>s.resolve({shortCircuit:!1,envelope:s.envelope}));else{let i=s.tailKind??"request";this.forwardRequest(s.method,s.envelope,new Set([...s.originatedBy,s.transformerName]),s.chainIdx+1,i).then(s.resolve).catch(()=>s.resolve(i==="notification"?void 0:ps(s.method)))}},r);return typeof o.unref=="function"&&o.unref(),s.timer=o,!0}async emitToChain(e,t,s){let r=this.transformChain.findIndex(a=>a.name===e),o=r>=0?r+1:0,i=new Set([e]);if(t==="session/update"){await this.runResponseChain(s,i,o);return}return this.forwardRequest(t,s,i,o)}async emitToQueue(e,t){let s=this.transformChain.findIndex(u=>u.name===e),r=s>=0?s+1:0,o=(t??{}).prompt??[],i=Te(),a=`transformer:${e}`,d={clientId:a,name:e};return new Promise((u,c)=>{let f={kind:"user",messageId:i,originator:d,clientId:a,prompt:o,enqueuedAt:Date.now(),cancelled:!1,emitterName:e,chainStartIdx:r,resolve:u,reject:c},p=this.insertEntryAt(f,"tail");this.persistRewrite(),this.broadcastQueueAdded(f,{position:p}),this.drainQueue()})}rewriteForAgent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.sessionId===this.sessionId)return{...t,sessionId:this.upstreamSessionId}}return e}async close(e={}){if(e.deleteRecord&&(this.deleteRecordIntent=!0),!this.closed)return this.closeInFlight?this.closeInFlight:(this.closing=!0,this.closeInFlight=this.doClose(e),this.closeInFlight)}async doClose(e){this.logger?.info(`session ${this.sessionId} closing deleteRecord=${e.deleteRecord??!1}`),this.cancelIdleTimer();for(let t of this.pendingClaims.values())clearTimeout(t.timer);this.pendingClaims.clear(),await this.agent.kill().catch(()=>{}),this.markClosed({deleteRecord:e.deleteRecord??!1})}onClose(e){return this.closeHandlers.push(e),()=>{let t=this.closeHandlers.indexOf(e);t>=0&&this.closeHandlers.splice(t,1)}}onTitleChange(e){this.titleHandlers.push(e)}retitle(e){return this.runTitleCommand(e)}retitleFromAgent(){return this.runTitleCommand("")}setTitle(e){let t=e.trim();if(!(!t||t===this.title)){this.title=t,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",title:t,updatedAt:new Date().toISOString()}});for(let s of this.titleHandlers)try{s(t)}catch{}}}maybeSeedTitleFromPrompt(e){if(this.firstPromptSeeded||Je((e??{})._meta).ancillary===!0||this.promptCarriesSentBy(e))return;let r=tt((e??{}).prompt),o=ms(r,200);o&&(o.startsWith("/")||(this._firstPromptSeeded=!0,this.setTitle(o)))}maybeApplyAgentModel(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="current_model_update")return!1;let r=nt(s.availableModels);r.length>0&&this.setAgentAdvertisedModels(r);let o=typeof s.currentModel=="string"?s.currentModel:typeof s.model=="string"?s.model:void 0;if(o===void 0)return!0;let i=o.trim();if(!i||i===this.currentModel)return!0;this.logger?.info(`live current_model_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(i)}`),this.currentModel=i;for(let a of this.modelHandlers)try{a(i)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentConfigOption(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="config_option_update")return!1;let r=s.configOptions;if(!Array.isArray(r))return!0;for(let o of r){if(!o||typeof o!="object")continue;let i=o;if(i.id==="model"){let a=nt(i.options);a.length>0&&this.setAgentAdvertisedModels(a);let d=i.currentValue;if(typeof d=="string"){let u=d.trim();u&&u!==this.currentModel&&(this.logger?.info(`live config_option_update(model): sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(u)}`),this.applyModelChange(u))}}else if(i.id==="mode"){let a=vt(i.options);a.length>0&&this.setAgentAdvertisedModes(a);let d=i.currentValue;if(typeof d=="string"){let u=d.trim();u&&u!==this.currentMode&&(this.logger?.info(`live config_option_update(mode): sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(u)}`),this.applyModeChange(u))}}else if(typeof i.id=="string"&&i.id.trim()){let a=i.id.trim(),d=nt(i.options);if(d.length>0){let u=vt(i.options),c=u.length>0?u.map(h=>({value:h.id,name:h.name??h.id})):d.map(h=>({value:h.modelId,name:h.name??h.modelId})),f=i.name,p=typeof f=="string"&&f.trim()?f.trim():a,l=i.currentValue,m=typeof l=="string"&&l.trim()?l.trim():c[0]?.value??"",g=this.agentAdvertisedConfigOptions.findIndex(h=>h.id===a);if(g>=0){let h={...this.agentAdvertisedConfigOptions[g]};h.options=c,typeof l=="string"&&l.trim()&&(h.currentValue=l.trim()),this.agentAdvertisedConfigOptions[g]=h}else this.agentAdvertisedConfigOptions.push({id:a,name:p,category:"other",type:"select",currentValue:m,options:c})}}}return!0}maybeApplyAgentMode(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="current_mode_update")return!1;let r=typeof s.currentModeId=="string"?s.currentModeId:typeof s.currentMode=="string"?s.currentMode:typeof s.mode=="string"?s.mode:void 0;if(r===void 0)return!0;let o=r.trim();if(!o||o===this.currentMode)return!0;this.logger?.info(`current_mode_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(o)}`),this.currentMode=o;for(let i of this.modeHandlers)try{i(o)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentUsage(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="usage_update")return!1;let r={...this._currentUsage??{}},o=!1;if(typeof s.used=="number"&&r.used!==s.used&&(r.used=s.used,o=!0),typeof s.size=="number"&&r.size!==s.size&&(r.size=s.size,o=!0),s.cost&&typeof s.cost=="object"){let a=s.cost;typeof a.amount=="number"&&(this.reconcileCostLedger(a.amount)&&(o=!0),r.costAmount!==a.amount&&(r.costAmount=a.amount,o=!0)),typeof a.currency=="string"&&r.costCurrency!==a.currency&&(r.costCurrency=a.currency,o=!0)}if(!o)return!0;this._currentUsage=r;let i=this.persistableUsage??r;for(let a of this.usageHandlers)try{a(i)}catch{}return!0}armCostLedgerProbe(){let e=this._currentUsage?.costAmount;typeof e=="number"&&e>0&&(this.costLedgerProbe=e)}reconcileCostLedger(e){let t=this.costLedgerProbe;return t===void 0||(this.costLedgerProbe=void 0,e>=t-1e-6)?!1:(this.cumulativeCost+=t,!0)}notifyAgentChange(e){let t=this.retiringGenerationCost;this.retiringGenerationCost=void 0;for(let s of this.agentChangeHandlers)try{s({agentId:this.agentId,upstreamSessionId:this.upstreamSessionId,...t!==void 0?{retiredCost:t}:{}})}catch(r){this.logger?.warn(`${e}: agentChange handler failed: ${r.message}`)}}accumulateAndResetCost(){let e=this._currentUsage?.costAmount;e&&(this.cumulativeCost+=e,this.retiringGenerationCost=e);let t={used:0,cumulativeCost:this.cumulativeCost,...typeof this._currentUsage?.size=="number"?{size:this._currentUsage.size}:{},...this._currentUsage?.costCurrency?{costCurrency:this._currentUsage.costCurrency}:{}};this._currentUsage=t;for(let r of this.usageHandlers)try{r(t)}catch{}let s=this.currentUsage;if(s!==void 0){let r={sessionUpdate:"usage_update"};if(typeof s.used=="number"&&(r.used=s.used),typeof s.size=="number"&&(r.size=s.size),typeof s.costAmount=="number"||typeof s.costCurrency=="string"){let o={};typeof s.costAmount=="number"&&(o.amount=s.costAmount),typeof s.costCurrency=="string"&&(o.currency=s.costCurrency),r.cost=o}this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:r})}}injectCumulativeCost(e){if(!this.cumulativeCost||!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let s=t.update;if(s.sessionUpdate!=="usage_update"||!s.cost||typeof s.cost!="object")return e;let r=s.cost;return typeof r.amount!="number"?e:{...t,update:{...s,cost:{...r,amount:this.cumulativeCost+r.amount}}}}get totalUsage(){return this.currentUsage}setAgentAdvertisedCommands(e){if(Sc(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(Ic(this.agentAdvertisedModes,e)){this.broadcastAvailableModes();return}this.agentAdvertisedModes=e;for(let t of this.agentModesHandlers)try{t(e)}catch{}this.broadcastAvailableModes()}setAgentAdvertisedModels(e){if(this.logger?.info(`setAgentAdvertisedModels: sessionId=${this.sessionId} currentModel=${JSON.stringify(this.currentModel)} newList=[${e.map(t=>t.modelId).join(",")}]`),kc(this.agentAdvertisedModels,e)){this.broadcastAvailableModels();return}this.agentAdvertisedModels=e;for(let t of this.agentModelsHandlers)try{t(e)}catch{}this.broadcastAvailableModels()}onAgentCommandsChange(e){this.agentCommandsHandlers.push(e)}onAgentModesChange(e){this.agentModesHandlers.push(e)}onAgentModelsChange(e){this.agentModelsHandlers.push(e)}onModelChange(e){this.modelHandlers.push(e)}onModeChange(e){this.modeHandlers.push(e)}onInteractiveChange(e){this.interactiveHandlers.push(e)}onPriorityChange(e){this.priorityHandlers.push(e)}setPriority(e){let t=e===void 0||e<=0?void 0:Math.floor(e);if(t!==this._priority){this._priority=t,this.updatedAt=Date.now();for(let s of this.priorityHandlers)try{s(t)}catch{}}}applyModelChange(e){let t=e.trim();if(t){this.modelChangeInFlight=!0;try{if(t!==this.currentModel){this.logger?.info(`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(t)}`),this.currentModel=t;for(let r of this.modelHandlers)try{r(t)}catch{}}let s={sessionUpdate:"current_model_update",currentModel:t};this.agentAdvertisedModels.length>0&&(s.availableModels=[...this.agentAdvertisedModels]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:s}),this.broadcastConfigOptions()}finally{this.modelChangeInFlight=!1}}}applyModeChange(e){let t=e.trim();if(t){this.modeChangeInFlight=!0;try{if(t!==this.currentMode){this.logger?.info(`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(t)}`),this.currentMode=t;for(let r of this.modeHandlers)try{r(t)}catch{}}let s={sessionUpdate:"current_mode_update",currentModeId:t};this.agentAdvertisedModes.length>0&&(s.availableModes=[...this.agentAdvertisedModes]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:s}),this.broadcastConfigOptions()}finally{this.modeChangeInFlight=!1}}}buildConfigOptions(){let e=[];if(this.agentAdvertisedModels.length>0){let r=this.agentAdvertisedModels.map(i=>({value:i.modelId,name:i.name??i.modelId,...i.description!==void 0?{description:i.description}:{}})),o=this.currentModel&&r.some(i=>i.value===this.currentModel)?this.currentModel:r[0].value;e.push({id:"model",name:"Model",category:"model",type:"select",currentValue:o,options:r})}if(this.agentAdvertisedModes.length>0){let r=this.agentAdvertisedModes.map(i=>({value:i.id,name:i.name??i.id,...i.description!==void 0?{description:i.description}:{}})),o=this.currentMode&&r.some(i=>i.value===this.currentMode)?this.currentMode:r[0].value;e.push({id:"mode",name:"Session Mode",category:"mode",type:"select",currentValue:o,options:r})}let s=(this.availableAgentsFn?.()??[]).map(r=>({value:r.id,name:r.name??r.id,...r.description!==void 0?{description:r.description}:{}}));return s.some(r=>r.value===this.agentId)||s.unshift({value:this.agentId,name:this.agentId}),e.push({id:"agent",name:"Agent",category:"_hydra_agent",type:"select",currentValue:this.agentId,options:s}),e.push(...this.agentAdvertisedConfigOptions),e}broadcastConfigOptions(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"config_option_update",configOptions:this.buildConfigOptions()}})}mergeAgentOptionIntoEnvelope(e){if(!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let s=t.update,r=Array.isArray(s.configOptions)?[...s.configOptions]:[];if(r.some(a=>a&&typeof a=="object"&&a.id==="agent"))return e;let i=this.buildConfigOptions().find(a=>a.id==="agent");return i?{...t,update:{...s,configOptions:[...r,i]}}:e}onUsageChange(e){this.usageHandlers.push(e)}mergedAvailableCommands(){let e=this.daemonTopLevelCommands(),t=this.aliasableBareVerbs();for(let s of Xe){if(t.get(s.verb)!=="__hydra__")continue;let r=s.argsHint?`${s.verb} ${s.argsHint}`:s.verb;e.push({name:r,description:`Alias for '/hydra ${s.verb}': ${s.description}`})}if(this.extensionCommands)for(let{name:s,command:r}of this.extensionCommands.list()){let o=r.verb?`hydra ${s} ${r.verb}`:`hydra ${s}`,a={name:r.argsHint?`${o} ${r.argsHint}`:o};r.description&&(a.description=r.description),e.push(a);let d=s.startsWith("hydra-acp-")?s.slice(10):s;if(s.startsWith("hydra-acp-")&&d.length>0){let u=r.verb?`hydra ${d} ${r.verb}`:`hydra ${d}`,f={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(f.description=r.description),e.push(f)}if(d.length>0&&t.get(d)===s){let u=r.verb?`${d} ${r.verb}`:d,f={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(f.description=r.description),e.push(f)}}return e.push(...this.agentAdvertisedCommands),e}daemonTopLevelCommands(){return[{name:"hydra",description:"Hydra session command (kill, restart, title, agent <agent>)"},{name:"model",description:"Switch model; omit arg to list available models"},{name:"mode",description:"Switch mode; omit arg to list available modes"},{name:"sessions",description:"List all sessions"},{name:"help",description:"Show available commands"}]}aliasableBareVerbs(){let e=new Set,t=i=>i.split(/\s+/)[0]??"";for(let i of this.daemonTopLevelCommands()){let a=t(i.name);a&&e.add(a)}for(let i of this.agentAdvertisedCommands){let a=t(i.name),d=a.startsWith("/")?a.slice(1):a;d&&e.add(d)}let s=new Map;for(let i of Xe)e.has(i.verb)||s.set(i.verb,"__hydra__");if(!this.extensionCommands)return s;let r=new Map,o=new Set;for(let{name:i}of this.extensionCommands.list()){if(o.has(i))continue;o.add(i);let a=i.startsWith("hydra-acp-")?i.slice(10):i;if(!a||e.has(a)||s.has(a))continue;let d=r.get(a);d===void 0?r.set(a,i):d!==i&&r.set(a,"__conflict__")}for(let[i,a]of r)a!=="__conflict__"&&s.set(i,a);return s}agentOnlyAdvertisedCommands(){return[...this.agentAdvertisedCommands]}agentKnowsSlashCommand(e){let t=r=>r.startsWith("/")?r.slice(1):r,s=t(e);if(!s)return!1;for(let r of this.agentAdvertisedCommands)if(t(r.name.split(/\s+/)[0]??"")===s)return!0;return!1}availableModes(){return[...this.agentAdvertisedModes]}availableModels(){return[...this.agentAdvertisedModels]}maybeApplyAgentSessionInfo(e){let s=(e??{}).update??{};if(s.sessionUpdate!=="session_info_update"||typeof s.title!="string")return;let r=s.title.trim();if(!(!r||r===this.title)){this.title=r,this._firstPromptSeeded=!0;for(let o of this.titleHandlers)try{o(r)}catch{}}}async handleSlashCommand(e,t){let r=e.slice(6).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),o=r?.[1]??"",i=(r?.[2]??"").trim();if(o==="")return{stopReason:"end_turn"};let a=t!==void 0;if(Xe.some(f=>f.verb===o))switch(o){case"title":return a?this.runTitleCommandInline(i):this.runTitleCommand(i);case"agent":return a?this.runAgentCommandInline(i):this.runAgentCommand(i);case"config":return this.handleConfigCommand(`/config ${i}`);case"kill":return this.runKillCommand();case"restart":return a?this.runRestartCommandInline():this.runRestartCommand();case"compact":return a?this.runCompactCommandInline(i):this.runCompactCommand(i);case"uncompact":return a?this.runUncompactCommandInline():this.runUncompactCommand();case"fork":return a?this.runForkCommandInline(i,t):this.runForkCommand(i);default:{let f=new Error(`no dispatcher for /hydra verb ${o}`);throw f.code=k.InternalError,f}}if(this.extensionCommands?.has(o))return a?this.runExtensionCommandInline(o,i,t):this.runExtensionCommand(o,i);let d=`hydra-acp-${o}`;if(this.extensionCommands?.has(d))return a?this.runExtensionCommandInline(d,i,t):this.runExtensionCommand(d,i);let u=Xe.map(f=>f.verb);if(this.extensionCommands){let f=new Set;for(let{name:p}of this.extensionCommands.list())f.has(p)||(u.push(p),f.add(p))}let c=new Error(`unknown /hydra verb: ${o} (known: ${u.join(", ")})`);throw c.code=k.InvalidParams,c}runExtensionCommand(e,t){return this.enqueuePrompt(()=>this.runExtensionCommandInline(e,t,void 0))}async runExtensionCommandInline(e,t,s){let r=this.extensionCommands?.get(e);if(!r)return this.emitExtensionReply(`extension "${e}" is no longer connected`);let o=t.match(/^(\S+)(?:\s+([\s\S]*))?$/),i=o?.[1]??"",a=(o?.[2]??"").trim();if(!r.commands.some(m=>m.verb===i)){let m=r.commands.map(g=>g.verb).join(", ");return this.emitExtensionReply(`/hydra ${e}${i?` ${i}`:""}: unknown verb (known: ${m||"(none)"})`)}let d={sessionId:this.sessionId,verb:i,args:a};s!==void 0&&(d.messageId=s);let u=()=>{},c=new Promise(m=>{u=m});s!==void 0&&this.inFlightExtensionDispatches.set(s,{extensionName:e,connection:r.connection,cancel:m=>u({stopReason:"cancelled",reason:m})});let f,p=!1;try{let m=r.connection.request("hydra-acp/commands/invoke",d),g=await Promise.race([m,c]);if(g&&typeof g=="object"&&g.stopReason==="cancelled"&&"reason"in g)return p=!0,this.logger?.info(`extension ${e} ${i} cancelled (cancelExtensionDispatch); abandoning in-flight commands/invoke`),{stopReason:"cancelled"};f=g}catch(m){return this.emitExtensionReply(`${e} ${i}: ${m.message}`)}finally{s!==void 0&&!p&&this.inFlightExtensionDispatches.delete(s)}let l=f&&typeof f=="object"&&typeof f.text=="string"?f.text:"";return l.length>0?this.emitExtensionReply(l):{stopReason:"end_turn"}}cancelExtensionDispatch(e,t){let s=this.inFlightExtensionDispatches.get(e);if(!s)return!1;this.inFlightExtensionDispatches.delete(e);try{s.connection.notify("hydra-acp/commands/cancel",{sessionId:this.sessionId,messageId:e,reason:t})}catch(r){this.logger?.warn(`notify commands/cancel to ${s.extensionName} failed: ${r.message}`)}return s.cancel(t),!0}emitExtensionReply(e){return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
35
35
  ${e}
36
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}async handleSessionsCommand(){let e;if(!this.listSessions)e="_(session listing not available)_";else{let t=await this.listSessions();if(t.length===0)e="_(no sessions)_";else{let s=t.map(r=>{let i=r.sessionId.replace(/^hydra_session_/,"").slice(0,12),o=r.currentModel?` \xB7 ${r.currentModel}`:"",a=r.sessionId===this.sessionId?" \u25C0":"",d=r.title?` ${r.title}`:"";return`\`${i}\` ${r.cwd}${o}${a}${d}`});e=`Sessions (${t.length}):
36
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}async handleSessionsCommand(){let e;if(!this.listSessions)e="_(session listing not available)_";else{let t=await this.listSessions();if(t.length===0)e="_(no sessions)_";else{let s=t.map(r=>{let o=r.sessionId.replace(/^hydra_session_/,"").slice(0,12),i=r.currentModel?` \xB7 ${r.currentModel}`:"",a=r.sessionId===this.sessionId?" \u25C0":"",d=r.title?` ${r.title}`:"";return`\`${o}\` ${r.cwd}${i}${a}${d}`});e=`Sessions (${t.length}):
37
37
  ${s.join(`
38
38
  `)}`}}return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
39
39
  ${e}
40
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}handleHelpCommand(){let t=this.mergedAvailableCommands().map(r=>{let i=r.description?` ${r.description}`:"";return`\`/${r.name}\`${i}`}),s=t.length>0?`Available commands:
40
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}handleHelpCommand(){let t=this.mergedAvailableCommands().map(r=>{let o=r.description?` ${r.description}`:"";return`\`/${r.name}\`${o}`}),s=t.length>0?`Available commands:
41
41
  ${t.join(`
42
42
  `)}`:"_(no commands advertised)_";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
43
43
  ${s}
44
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),Promise.resolve({stopReason:"end_turn"})}async handleModelCommand(e){let t=e.slice(6).trim();if(t===""){let i=this.agentAdvertisedModels,o=this.currentModel,a;if(i.length===0)a=o?`Current model: ${o}`:"_(no models advertised yet)_";else{let d=o?i.some(c=>c.modelId===o):!0,u=i.map(c=>{let f=c.modelId===o?"\u25B6 ":" ",p=c.name&&c.name!==c.modelId?` ${c.name}`:"";return`${f}${c.modelId}${p}`});!d&&o&&u.unshift(`\u25B6 ${o}`),a=u.join(`
44
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),Promise.resolve({stopReason:"end_turn"})}async handleModelCommand(e){let t=e.slice(6).trim();if(t===""){let o=this.agentAdvertisedModels,i=this.currentModel,a;if(o.length===0)a=i?`Current model: ${i}`:"_(no models advertised yet)_";else{let d=i?o.some(c=>c.modelId===i):!0,u=o.map(c=>{let f=c.modelId===i?"\u25B6 ":" ",p=c.name&&c.name!==c.modelId?` ${c.name}`:"";return`${f}${c.modelId}${p}`});!d&&i&&u.unshift(`\u25B6 ${i}`),a=u.join(`
45
45
  `)}return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
46
46
  ${a}
47
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let s=Ve(t,this.agentAdvertisedModels),r=t;if(s.kind==="resolved")r=s.modelId;else if(s.kind==="ambiguous"||s.kind==="unknown"){let i=this.agentAdvertisedModels.map(f=>f.modelId),o=t.toLowerCase(),a=s.kind==="ambiguous"?s.candidates:i.filter(f=>f.toLowerCase().includes(o)),d=a.length>0?a:i,u=s.kind==="ambiguous"?`"${t}" matches multiple models: ${s.candidates.join(", ")}`:a.length>0?`"${t}" is not an available model. Did you mean`:`"${t}" is not an available model`,c=s.kind==="ambiguous"||a.length===0?"Available models":"Matching models";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
47
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let s=Ze(t,this.agentAdvertisedModels),r=t;if(s.kind==="resolved")r=s.modelId;else if(s.kind==="ambiguous"||s.kind==="unknown"){let o=this.agentAdvertisedModels.map(f=>f.modelId),i=t.toLowerCase(),a=s.kind==="ambiguous"?s.candidates:o.filter(f=>f.toLowerCase().includes(i)),d=a.length>0?a:o,u=s.kind==="ambiguous"?`"${t}" matches multiple models: ${s.candidates.join(", ")}`:a.length>0?`"${t}" is not an available model. Did you mean`:`"${t}" is not an available model`,c=s.kind==="ambiguous"||a.length===0?"Available models":"Matching models";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
48
48
  ${u}.
49
49
  ${c}:
50
50
  ${d.join(`
51
51
  `)}
52
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}return await this.forwardRequest("session/set_model",{sessionId:this.sessionId,modelId:r}),this.applyModelChange(r),{stopReason:"end_turn"}}async handleModeCommand(e){let t=e.slice(5).trim();if(t===""){let r=this.agentAdvertisedModes,i=this.currentMode,o;if(r.length===0)o=i?`Current mode: ${i}`:"_(no modes advertised yet)_";else{let a=i?r.some(u=>u.id===i):!0,d=r.map(u=>{let c=u.id===i?"\u25B6 ":" ",f=u.name&&u.name!==u.id?` ${u.name}`:"";return`${c}${u.id}${f}`});!a&&i&&d.unshift(`\u25B6 ${i}`),o=d.join(`
52
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}return await this.forwardModelChange(r),this.applyModelChange(r),{stopReason:"end_turn"}}async handleModeCommand(e){let t=e.slice(5).trim();if(t===""){let r=this.agentAdvertisedModes,o=this.currentMode,i;if(r.length===0)i=o?`Current mode: ${o}`:"_(no modes advertised yet)_";else{let a=o?r.some(u=>u.id===o):!0,d=r.map(u=>{let c=u.id===o?"\u25B6 ":" ",f=u.name&&u.name!==u.id?` ${u.name}`:"";return`${c}${u.id}${f}`});!a&&o&&d.unshift(`\u25B6 ${o}`),i=d.join(`
53
53
  `)}return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
54
- ${o}
55
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let s=this.agentAdvertisedModes;if(s.length>0&&!s.some(r=>r.id===t)){let r=s.map(i=>i.id).join(", ");throw re(new Error(`unknown mode: ${t} (known: ${r})`),k.InvalidParams)}return await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:t}),this.applyModeChange(t),{stopReason:"end_turn"}}async handleConfigCommand(e){let t=e.slice(7).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),s=t?.[1],r=t?.[2]??"";if(!s){let c=this.buildConfigOptions();if(c.length===0)return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
54
+ ${i}
55
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let s=this.agentAdvertisedModes;if(s.length>0&&!s.some(r=>r.id===t)){let r=s.map(o=>o.id).join(", ");throw re(new Error(`unknown mode: ${t} (known: ${r})`),k.InvalidParams)}return await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:t}),this.applyModeChange(t),{stopReason:"end_turn"}}async handleConfigCommand(e){let t=e.slice(7).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),s=t?.[1],r=t?.[2]??"";if(!s){let c=this.buildConfigOptions();if(c.length===0)return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
56
56
  _(no config options advertised yet)_
57
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let f=c.map(p=>ti(p));return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
57
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let f=c.map(p=>ho(p));return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
58
58
  ${f.join(`
59
59
 
60
60
  `)}
61
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let i=this.buildConfigOptions(),o=i.find(c=>c.id===s);if(!o){let c=i.map(f=>f.id).join(`
61
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let o=this.buildConfigOptions(),i=o.find(c=>c.id===s);if(!i){let c=o.map(f=>f.id).join(`
62
62
  `);return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
63
63
  "${s}" is not a known config option.
64
64
  Available options:
65
65
  ${c}
66
66
  `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}if(!r)return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
67
- ${ti(o)}
68
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let a=o.options.map(c=>c.value),d=Zn(r,a),u=r;if(d.kind==="resolved")u=d.modelId;else if(d.kind==="ambiguous"||d.kind==="unknown"){let c=r.toLowerCase(),f=d.kind==="ambiguous"?d.candidates:a.filter(m=>m.toLowerCase().includes(c)),p=f.length>0?f:a,l=d.kind==="ambiguous"?`"${r}" matches multiple values for "${s}": ${d.candidates.join(", ")}`:f.length>0?`"${r}" is not a valid value for "${s}". Did you mean`:`"${r}" is not a valid value for "${s}"`,g=d.kind==="ambiguous"||f.length===0?"Valid values":"Matching values";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
67
+ ${ho(i)}
68
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let a=i.options.map(c=>c.value),d=is(r,a),u=r;if(d.kind==="resolved")u=d.modelId;else if(d.kind==="ambiguous"||d.kind==="unknown"){let c=r.toLowerCase(),f=d.kind==="ambiguous"?d.candidates:a.filter(g=>g.toLowerCase().includes(c)),p=f.length>0?f:a,l=d.kind==="ambiguous"?`"${r}" matches multiple values for "${s}": ${d.candidates.join(", ")}`:f.length>0?`"${r}" is not a valid value for "${s}". Did you mean`:`"${r}" is not a valid value for "${s}"`,m=d.kind==="ambiguous"||f.length===0?"Valid values":"Matching values";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
69
69
  ${l}.
70
- ${g}:
70
+ ${m}:
71
71
  ${p.join(`
72
72
  `)}
73
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}return s==="model"?(u!==this.currentModel&&await this.forwardRequest("session/set_model",{sessionId:this.sessionId,modelId:u}),this.applyModelChange(u),{stopReason:"end_turn"}):s==="mode"?(u!==this.currentMode&&await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:u}),this.applyModeChange(u),{stopReason:"end_turn"}):s==="agent"?(u!==this.agentId&&await this.runAgentCommandInline(u),{stopReason:"end_turn"}):(await this.forwardRequest("session/set_config_option",{sessionId:this.sessionId,configId:s,value:u}),{stopReason:"end_turn"})}runTitleCommand(e){return this.enqueuePrompt(()=>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.runAgentCommand(e)}runAgentCommand(e){return this.enqueuePrompt(()=>this.runAgentCommandInline(e))}async runAgentCommandInline(e){if(e==="status")return this.runAgentStatusCommandInline();let t=e;if(!t)throw re(new Error("/hydra agent requires an agent id"),k.InvalidParams);let r=(this.resolveAgentIdHook?await this.resolveAgentIdHook(t):void 0)??t;if(r===this.agentId)throw re(new Error(`already on agent ${r}`),k.InvalidParams);return this.scheduleCompactionHook?(this.scheduleCompactionHook({targetAgentId:r}),this.emitExtensionReply(`Agent switch to ${r} scheduled. The session will rotate to ${r} once synthesis completes.`),{stopReason:"end_turn"}):(this.emitExtensionReply("agent switching not configured for this session"),{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}),{stopReason:"end_turn"}}runRestartCommand(){return this.enqueuePrompt(()=>this.runRestartCommandInline())}async runRestartCommandInline(){if(!this.spawnReplacementAgent)throw re(new Error("agent restart not configured for this session"),k.InternalError);return await this.respawnAgent(),{stopReason:"end_turn"}}runCompactCommand(e){return this.enqueuePrompt(()=>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;if(e==null&&t==null)return this.emitExtensionReply("This session has never been compacted."),{stopReason:"end_turn"};if(e==null)return this.emitExtensionReply(`No compaction in progress. Last summarized through entry: ${t}`),{stopReason:"end_turn"};let s=[`Compaction state: ${e.status}${e.iter!=null?` (iteration ${e.iter})`:""}`,`Summarized through entry: ${t??0}`,`Pending attempts: ${e.attempts??0}`];return this.emitExtensionReply(s.join(`
74
- `)),{stopReason:"end_turn"}}runUncompactCommand(){return this.enqueuePrompt(()=>this.runUncompactCommandInline())}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(()=>this.runForkCommandInline(e,void 0))}async findMessageIdBefore(e){if(!this.historyStore)return;let t=await this.historyStore.load(this.sessionId),s;for(let r of t){if(r.method!=="session/update")continue;let o=r.params?.update?.messageId;if(typeof o=="string"){if(o===e)return s;s=o}}}async runForkCommandInline(e,t){if(!this.forkHook)return this.emitExtensionReply("Fork not configured for this session."),{stopReason:"end_turn"};let s=(e??"").trim(),r;if(s==="verbatim")r="verbatim";else if(s==="synthesis"||s==="")r=void 0;else return this.emitExtensionReply(`Unknown fork argument: \`${s}\`. Use \`/hydra fork\` or \`/hydra fork verbatim\`.`),{stopReason:"end_turn"};try{let i={};if(r&&(i.mode=r),t&&this.historyStore){let d=await this.findMessageIdBefore(t).catch(()=>{});d&&(i.forkAt=d)}let a=(await this.forkHook(Object.keys(i).length>0?i:void 0)).sessionId.replace(/^hydra_session_/,"");this.emitExtensionReply(`Forked to [\`${a}\`](hydra://sessions/${a}).`)}catch(i){this.emitExtensionReply(`Fork failed: ${i instanceof Error?i.message:String(i)}`)}return{stopReason:"end_turn"}}async forceCancel(){if(this.closed||this.closing)throw re(new Error("session is closing"),k.SessionClosing);return this.lastCancelAt=0,this.forceCancelling=!0,await this.close({deleteRecord:!1}),{stopReason:"cancelled"}}async respawnAgent(){let e=this.spawnReplacementAgent,t=this.agentId,s=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);let i=this.agent;this.agent=r.agent,this.upstreamSessionId=r.upstreamSessionId,this.agentMeta=r.agentMeta,this.agentCapabilities=r.agentCapabilities,this.agentAdvertisedCommands=[],this.broadcastMergedCommands(),this.currentModel=r.initialModel,this.currentMode=r.initialMode,this.setAgentAdvertisedModels(r.initialModels??[]),this.setAgentAdvertisedModes(r.initialModes??[]),await i.kill().catch(()=>{}),s&&await this.runInternalPrompt(s).catch(()=>{}),this.broadcastAgentSwitch(t,t);let o={agentId:t,upstreamSessionId:this.upstreamSessionId};for(let a of this.agentChangeHandlers)try{a(o)}catch{}}async buildSwitchTranscript(e,t){let s=[],r=await this.getHistorySnapshot();for(let u of r){if(u.method!=="session/update")continue;let f=(u.params??{}).update;if(!f||f._meta?.["hydra-acp"]?.synthetic)continue;let l=f.sessionUpdate;if(l==="prompt_received"){let g=Xe(f.prompt);g&&s.push({speaker:"user",text:g})}else if(l==="agent_message_chunk"){let m=f.content?.text;m&&s.push({speaker:`agent: ${e}`,text:m})}else if(l==="tool_call"||l==="tool_call_update"){let g=f.status,m=f.title;(g==="completed"||g==="failed")&&s.push({speaker:"tool",text:`${m??"?"} ${g}`})}}if(s.length===0)return"";let i=[],o;for(let u of s)o&&o.speaker===u.speaker?o.text+=u.text:(o&&i.push(`<${o.speaker}>: ${o.text.trim()}`),o={speaker:u.speaker,text:u.text});o&&i.push(`<${o.speaker}>: ${o.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 ---",...i,"--- end transcript ---"].join(`
75
- `)}async seedFromImport(){await this.enqueuePrompt(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(async()=>{let t=this.title??"(untitled)",s=[];if(this.historyStore)try{s=await this.historyStore.load(this.sessionId)}catch(i){this.logger?.warn(`seedFromFork: historyStore.load failed: ${i.message}`)}let r=rs({synopsis:e,title:t,tail:s,tailK:Vd,tailFloor:Yd,watermark:this._summarizedThroughEntry});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 i=this.internalPromptCapture;this.logger?.info(`seedFromFork: seed processed sessionId=${this.sessionId} seedChars=${r.length} toolCalls=${i.toolCalls} thinkingChars=${i.thinkingChars} messageChars=${i.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 s=(e.mode??"memory")==="file"&&e.filePathFor!==void 0?e.filePathFor(this.sessionId):void 0,r={};e.capacityBytes!==void 0&&(r.capacityBytes=e.capacityBytes),s!==void 0&&(r.filePath=s),e.fileCapBytes!==void 0&&(r.fileCapBytes=e.fileCapBytes),r.onFileCapReached=()=>{this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"stream_truncated",...s!==void 0?{filePath:s}:{},fileCapBytes:e.fileCapBytes}})};let i=new Jt(r);this.streamBuffer=i,this.streamFilePath=s;let o={capacityBytes:i.capacity};return s!==void 0&&(o.filePath=s),e.fileCapBytes!==void 0&&(o.fileCapBytes=e.fileCapBytes),o}streamWrite(e,t){let s=this.requireStreamBuffer();if(e.length>0){let r=Buffer.from(e,"base64");s.append(r)}return t===!0&&s.close(),{writeCursor:s.writeCursorPos}}async streamRead(e,t,s){let r=this.requireStreamBuffer(),i=Math.max(0,Math.min(t??Ge,Ge)),o=r.read(e,i);if(o.bytes.length===0&&o.eof!==!0&&s!==void 0&&s>0){let d=await r.waitForData(o.nextCursor,s);(d==="data"||d==="eof")&&(o=r.read(o.nextCursor,i))}let a={bytes:o.bytes.toString("base64"),nextCursor:o.nextCursor};return o.gap!==void 0&&(a.gap=o.gap),o.eof===!0&&(a.eof=!0),a}streamTail(e){let s=this.requireStreamBuffer().tail(e);return{bytes:s.bytes.toString("base64"),startCursor:s.startCursor,endCursor:s.endCursor,truncated:s.truncated}}streamHead(e){let s=this.requireStreamBuffer().head(e);return{bytes:s.bytes.toString("base64"),startCursor:s.startCursor,endCursor:s.endCursor,truncated:s.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=k.StreamNotEnabled,e}return this.streamBuffer}markClosed(e){if(this.closed)return;e={deleteRecord:e.deleteRecord||this.deleteRecordIntent},this.closing=!0,this.closed=!0,this.cancelIdleTimer(),this.extensionCommandsUnsub&&(this.extensionCommandsUnsub(),this.extensionCommandsUnsub=void 0);for(let i of[...this.inFlightExtensionDispatches.keys()])this.cancelExtensionDispatch(i,"abandoned");this.currentEntry?.kind==="user"&&!this.recentlyTerminal.has(this.currentEntry.messageId)&&this.broadcastTurnComplete(this.currentEntry.clientId,{stopReason:"interrupted"},this.currentEntry.messageId,this.currentEntry.wasAmend),this.currentEntry=void 0;let s=this.promptQueue;this.promptQueue=[];for(let i of s){i.cancelled=!0,i.kind==="user"&&this.broadcastQueueRemoved(i.messageId,"abandoned");try{i.resolve({stopReason:"cancelled"})}catch{}}this.notifyChain("session.closed",{}),this.toolCompletionSeen.clear(),this.toolCallKind.clear(),this.filesEditedSeen.clear();let r=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Xr(r).catch(()=>{}));for(let i of this.clients.values())i.connection.notify("hydra-acp/session/closed",{sessionId:this.sessionId}).catch(()=>{});if(this.clients.clear(),this.streamBuffer!==void 0){let i=this.streamBuffer,o=this.streamFilePath;this.streamBuffer=void 0,this.streamFilePath=void 0,i.close(),o!==void 0&&i.drainFileWrites().then(()=>oi.unlink(o).catch(()=>{}))}for(let i of this.closeHandlers)i(e)}get lastActivityAt(){return this.lastRecordedAt}setAttentionFlag(e,t,s){this._setAttentionFlag(e,t,s,!0)}_setAttentionFlag(e,t,s,r){let i=`${e}::${t}`,o=this.attentionFlags.get(i);if(o){if(JSON.stringify(o.payload)===JSON.stringify(s))return;this.attentionFlags.set(i,{...o,payload:s,raisedAt:o.raisedAt})}else this.attentionFlags.set(i,{source:e,reason:t,raisedAt:Date.now(),payload:s});r&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}clearAttentionFlag(e,t){this._clearAttentionFlag(e,t,!0)}_clearAttentionFlag(e,t,s){let r=`${e}::${t}`;this.attentionFlags.delete(r)&&s&&(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.turnStartedAt!==void 0||this.hasPermissionFlag||this.promptQueue.length>0){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},s=Math.round(e/1e3);this.logger?.info(`session ${this.sessionId} idle timeout fired after ${s}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()}onIdle(e,t){let s={fn:e,once:!!t?.once,debounceMs:t?.debounceMs??0};return this.idleHandlers.push(s),()=>{let r=this.idleHandlers.indexOf(s);r>=0&&this.idleHandlers.splice(r,1),s.timer&&(clearTimeout(s.timer),s.timer=void 0)}}onceIdle(e){return this.onIdle(e,{once:!0})}dispatchIdle(){if(this.closed)return;if(!this.isQuiescedSync()){for(let s of this.idleHandlers)s.timer&&(clearTimeout(s.timer),s.timer=void 0);return}let t=[...this.idleHandlers];for(let s of t){if(s.debounceMs===0){if(s.once){let r=this.idleHandlers.indexOf(s);r>=0&&this.idleHandlers.splice(r,1)}try{s.fn(this)}catch{}continue}s.timer&&(clearTimeout(s.timer),s.timer=void 0),s.timer=setTimeout(()=>{if(s.timer=void 0,!this.closed&&this.isQuiescedSync()){if(s.once){let r=this.idleHandlers.indexOf(s);r>=0&&this.idleHandlers.splice(r,1)}try{s.fn(this)}catch{}}},s.debounceMs),typeof s.timer.unref=="function"&&s.timer.unref()}}disposeIdleHandlers(){for(let e of this.idleHandlers)e.timer&&(clearTimeout(e.timer),e.timer=void 0);this.idleHandlers.length=0}maybeEmitToolEdges(e){if(!e||typeof e!="object")return;let t=e.update;if(!t||typeof t!="object")return;let s=t,r=typeof s.sessionUpdate=="string"?s.sessionUpdate:"";if(r!=="tool_call"&&r!=="tool_call_update")return;let i=typeof s.toolCallId=="string"&&s.toolCallId.length>0?s.toolCallId:void 0;if(!i)return;let o=typeof s.kind=="string"?s.kind:void 0;this.toolCallKind.note(i,o);let a=this.toolCallKind.effective(i,o);if(a===Ur&&Array.isArray(s.locations))for(let c of s.locations){if(!c||typeof c!="object")continue;let f=c.path;if(typeof f!="string"||f.length===0||this.filesEditedSeen.has(f))continue;this.filesEditedSeen.add(f);let p=c.line,l={path:f,toolCallId:i};typeof p=="number"&&(l.line=p),this.notifyChain("file.edited",l)}if(r!=="tool_call_update")return;let d=typeof s.status=="string"?s.status:void 0;if(d!=="completed"&&d!=="failed"||this.toolCompletionSeen.has(i))return;this.toolCompletionSeen.set(i,d);let u={toolCallId:i,status:d};a&&(u.kind=a),s.content!==void 0&&(u.content=s.content),Array.isArray(s.locations)&&(u.locations=s.locations),this.notifyChain("tool.completed",u)}notifyChain(e,t){let s=`lifecycle:${e}`;for(let r of this.transformChain)r.intercepts.has(s)&&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,s){let r=this.rewriteForClient(t),i=!Zr(e,r),o=i?ac(e,r):r,a=Date.now(),d=i?Ce(o,a):o;if(i){let u={method:e,params:o,recordedAt:a};if(this.lastRecordedAt=u.recordedAt,this.appendCount+=1,this.historyStore){let c=this.historyStore;c.append(this.sessionId,u).catch(()=>{}),this.appendCount>=this.compactEvery&&(this.appendCount=0,c.compact(this.sessionId,this.historyMaxEntries).catch(()=>{}))}for(let c of this.broadcastHandlers)try{c(u)}catch{}this.scheduleIdleCheck(),this.dispatchIdle()}this.updatedAt=Date.now();for(let u of this.clients.values())s&&u.clientId===s||u.connection.notify(e,d).catch(()=>{})}async requestPermissionFromClients(e){return this.handlePermissionRequest(e)}async handlePermissionRequest(e){let t=[...this.clients.values()];if(t.length===0)throw re(new Error("no clients attached to handle permission request"),k.PermissionDenied);let s=this.rewriteForClient(e),r=ei(s),i=Ee(),{toolCall:o,options:a}=s??{};return new Promise((d,u)=>{let c=!1,f=[],p=0,l,g=this.sessionId,m=v=>{c||(c=!0,this.clearAttentionFlag("daemon",`permission:${i}`),this.permissionCallbacks.delete(i),v())},h=v=>v?.code===k.MethodNotFound;function y(v){if(c)return;let w=v.connection.request("session/request_permission",s);f.push({client:v}),p++,w.then(S=>{p--,m(()=>{let A=dc({toolCallId:r,result:S,resolver:v});for(let C of f)C.client.clientId!==v.clientId&&C.client.connection.notify("session/update",{sessionId:g,update:A}).catch(()=>{});d(S)})}).catch(S=>{if(p--,h(S)||(l=S),p===0&&!c){let A=l??re(new Error("no client handled permission request"),k.PermissionDenied);m(()=>u(A))}})}this.setAttentionFlag("daemon",`permission:${i}`,{kind:"permission",toolCall:o??null,options:a??null}),this.permissionCallbacks.set(i,y);for(let v of t)y(v)})}async enqueuePrompt(e){return new Promise((t,s)=>{let r={kind:"internal",messageId:Ee(),enqueuedAt:Date.now(),cancelled:!1,task:e,resolve:t,reject:s};this.promptQueue.push(r),this.drainQueue()})}async enqueueUserPrompt(e,t,s){let r=(t??{}).prompt??[],i={clientId:e.clientId};e.clientInfo?.name&&(i.name=e.clientInfo.name),e.clientInfo?.version&&(i.version=e.clientInfo.version);let o=this.parseQueuePosition(t);return new Promise((a,d)=>{let u={kind:"user",messageId:s,originator:i,clientId:e.clientId,prompt:r,enqueuedAt:Date.now(),cancelled:!1,resolve:a,reject:d},c=this.insertEntryAt(u,o);this.persistRewrite(),this.broadcastQueueAdded(u,{position:c}),this.drainQueue()})}parseQueuePosition(e){if(!e||typeof e!="object")return"tail";let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return"tail";let s=t["hydra-acp"];if(!s||typeof s!="object"||Array.isArray(s))return"tail";let r=s.queuePosition;if(r==="head"||r==="tail")return r;if(r&&typeof r=="object"&&!Array.isArray(r)){let i=r.afterMessageId;if(typeof i=="string"&&i.length>0)return{afterMessageId:i}}return"tail"}insertEntryAt(e,t){let s=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;if(t==="head")return this.promptQueue.unshift(e),s;if(typeof t=="object"){let r=t.afterMessageId,i=this.promptQueue.findIndex(o=>o.messageId===r);if(i>=0)return this.promptQueue.splice(i+1,0,e),s+i+1}return this.promptQueue.push(e),s+this.promptQueue.length-1}persistRewrite(){let e=[];for(let s of this.promptQueue)s.kind!=="user"||s.cancelled||e.push(this.persistedFromEntry(s));let t=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>yt(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.shift();if(!e)break;if(!e.cancelled){this.currentEntry=e,e.kind==="user"&&this.persistRewrite(),e.kind==="user"&&this.broadcastQueueRemoved(e.messageId,"started");try{let t=await this.runQueueEntry(e);e.resolve(t),await new Promise(s=>setImmediate(s))}catch(t){e.reject(t)}finally{this.currentEntry=void 0}}}}finally{this.promptInFlight=!1,this.dispatchIdle()}}}async runQueueEntry(e){if(e.kind==="internal")return e.task();this.broadcastPromptReceived(e);let t=Xe(e.prompt).replace(/\s+$/,""),s=!t.includes(`
76
- `)&&t.startsWith("/")?t.split(/\s+/)[0]??"":"",r=s.startsWith("/")?s.slice(1):"",i=r.length>0&&this.aliasableBareVerbs().has(r);if(s==="/model"||s==="/mode"||s==="/sessions"||s==="/help"||s==="/hydra"||i){let d;if(s==="/sessions")d=await this.handleSessionsCommand();else if(s==="/help")d=await this.handleHelpCommand();else if(s==="/mode")d=await this.handleModeCommand(t);else if(s==="/model")d=await this.handleModelCommand(t);else if(i){let u=t.slice(s.length).trim(),c=u?`/hydra ${r} ${u}`:`/hydra ${r}`;d=await this.handleSlashCommand(c,e.messageId)}else d=await this.handleSlashCommand(t,e.messageId);return this.closed||this.broadcastTurnComplete(e.clientId,d,e.messageId,e.wasAmend),this.clearAmendIfMatches(e.messageId),d}if(this.clearRollbackBreadcrumbHook)try{this.clearRollbackBreadcrumbHook()}catch{}let o=e.prompt;s&&this.agentAdvertisedCommands.length>0&&!this.agentKnowsSlashCommand(s)&&(o=fc(e.prompt,lc));let a;try{a=await this.forwardRequest("session/prompt",{sessionId:this.sessionId,prompt:o},e.emitterName?new Set([e.emitterName]):new Set,e.chainStartIdx??0)}catch(d){if(this.forceCancelling)return this.clearAmendIfMatches(e.messageId),{stopReason:"cancelled"};throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,e.wasAmend),this.clearAmendIfMatches(e.messageId),d}return this.closed||this.broadcastTurnComplete(e.clientId,a,e.messageId,e.wasAmend),this.clearAmendIfMatches(e.messageId),a}clearAmendIfMatches(e){this.amendInProgress?.cancelledMessageId===e&&(this.amendInProgress=void 0)}};function re(n,e){return n.code=e,n}var ec=new Set(["session_info_update","current_model_update","current_mode_update","available_commands_update","available_modes_update","usage_update","config_option_update","hydra_compaction"]);function Zr(n,e){if(n!=="session/update")return!1;let s=(e??{}).update?.sessionUpdate;return typeof s=="string"&&ec.has(s)}function tc(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]?.name!==e[t]?.name||n[t]?.description!==e[t]?.description)return!1;return!0}function nc(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]?.id!==e[t]?.id||n[t]?.name!==e[t]?.name||n[t]?.description!==e[t]?.description)return!1;return!0}function sc(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]?.modelId!==e[t]?.modelId||n[t]?.name!==e[t]?.name||n[t]?.description!==e[t]?.description)return!1;return!0}function Ze(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(!t||typeof t!="object"||Array.isArray(t))continue;let s=t,r=typeof s.modelId=="string"&&s.modelId.trim()||typeof s.value=="string"&&s.value.trim()||typeof s.id=="string"&&s.id.trim()||void 0;if(!r)continue;let i={modelId:r};typeof s.name=="string"&&s.name.length>0&&(i.name=s.name),typeof s.description=="string"&&s.description.length>0&&(i.description=s.description),e.push(i)}return e}function wt(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(!t||typeof t!="object"||Array.isArray(t))continue;let s=t,r=typeof s.value=="string"&&s.value.trim()||typeof s.id=="string"&&s.id.trim()||void 0;if(!r)continue;let i={id:r};typeof s.name=="string"&&s.name.length>0&&(i.name=s.name),typeof s.description=="string"&&s.description.length>0&&(i.description=s.description),e.push(i)}return e}function rc(n){let t=(n??{}).update??{};if(t.sessionUpdate!=="available_modes_update")return null;let s=t.availableModes;if(!Array.isArray(s))return[];let r=[];for(let i of s){if(!i||typeof i!="object")continue;let o=i;if(typeof o.id!="string"||o.id.length===0)continue;let a={id:o.id};typeof o.name=="string"&&(a.name=o.name),typeof o.description=="string"&&(a.description=o.description),r.push(a)}return r}function ic(n,e){let s=(e??{}).update??{},r=s.sessionUpdate;if(r==="agent_message_chunk"){let i=s.content??{};typeof i.text=="string"&&(n.chunks.push(i.text),n.messageChars+=i.text.length);return}if(r==="agent_thought_chunk"){let i=s.content??{};typeof i.text=="string"&&(n.thinkingChars+=i.text.length);return}if(r==="tool_call"){n.toolCalls++;return}if(r==="usage_update"){typeof s.used=="number"&&(n.lastUsed=s.used),typeof s.size=="number"&&(n.lastSize=s.size);return}}function oc(n){let t=(n??{}).update??{};if(t.sessionUpdate!=="available_commands_update")return null;let s=t.availableCommands??t.commands;if(!Array.isArray(s))return[];let r=[];for(let i of s){if(!i||typeof i!="object")continue;let o=i;if(typeof o.name!="string"||o.name.length===0)continue;let a={name:o.name};typeof o.description=="string"&&(a.description=o.description),r.push(a)}return r}function ac(n,e){if(n!=="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:Ee()}}}function Qt(n,e){for(let t=0;t<n.length;t++){let s=n[t];if(!s||s.method!=="session/update")continue;if(s.params?.update?.messageId===e)return t}return-1}function ei(n){if(!n||typeof n!="object")return;let e=n.toolCall;if(!e||typeof e!="object")return;let t=e.toolCallId;return typeof t=="string"?t:void 0}function dc(n){let e=cc(n.result),t={sessionUpdate:"permission_resolved"};return n.toolCallId!==void 0&&(t.toolCallId=n.toolCallId),e&&(t.outcome=e,e.kind==="selected"&&typeof e.optionId=="string"&&(t.chosenOptionId=e.optionId)),t.resolvedBy=uc(n.resolver),t}function cc(n){if(!n||typeof n!="object")return;let e=n.outcome;if(!e||typeof e!="object")return;let t=e.kind;if(typeof t!="string")return;let s={kind:t},r=e.optionId;typeof r=="string"&&(s.optionId=r);let i=e.reason;return typeof i=="string"&&(s.reason=i),s}function uc(n){let e={clientId:n.clientId};return n.clientInfo?.name&&(e.name=n.clientInfo.name),n.clientInfo?.version&&(e.version=n.clientInfo.version),e}function Xe(n){return typeof n=="string"?n:Array.isArray(n)?n.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var lc="\u200B";function fc(n,e){let t=n.findIndex(i=>i&&typeof i=="object"&&typeof i.text=="string");if(t<0)return n;let s=n[t],r=[...n];return r[t]={...s,text:`${e}${s.text}`},r}function os(n){return n==="session/prompt"?{stopReason:"stopped"}:{}}function pc(n){return n==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function ti(n){let e=n.name&&n.name!==n.id?`${n.id} (${n.name}) \u2014 \u25B6 ${n.currentValue}`:`${n.id} \u2014 \u25B6 ${n.currentValue}`;if(n.options.length===0)return e;let t=Math.max(...n.options.map(r=>r.value.length)),s=n.options.map(r=>{let i=r.value===n.currentValue?"\u25B6":"\xB7",o=r.name&&r.name!==r.value,a=o?r.value.padEnd(t):r.value;return o?` ${i} ${a} ${r.name}`:` ${i} ${a}`});return`${e}
73
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}return s==="model"?(u!==this.currentModel&&await this.forwardModelChange(u),this.applyModelChange(u),{stopReason:"end_turn"}):s==="mode"?(u!==this.currentMode&&await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:u}),this.applyModeChange(u),{stopReason:"end_turn"}):s==="agent"?(u!==this.agentId&&await this.runAgentCommandInline(u),{stopReason:"end_turn"}):(await this.forwardRequest("session/set_config_option",{sessionId:this.sessionId,configId:s,value:u}),{stopReason:"end_turn"})}runTitleCommand(e){return this.enqueuePrompt(()=>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.runAgentCommand(e)}runAgentCommand(e){return this.enqueuePrompt(()=>this.runAgentCommandInline(e))}async runAgentCommandInline(e){if(e==="status")return this.runAgentStatusCommandInline();let t=e;if(!t)throw re(new Error("/hydra agent requires an agent id"),k.InvalidParams);let r=(this.resolveAgentIdHook?await this.resolveAgentIdHook(t):void 0)??t;if(r===this.agentId)throw re(new Error(`already on agent ${r}`),k.InvalidParams);return this.scheduleCompactionHook?(this.scheduleCompactionHook({targetAgentId:r}),this.emitExtensionReply(`Agent switch to ${r} scheduled. The session will rotate to ${r} once synthesis completes.`),{stopReason:"end_turn"}):(this.emitExtensionReply("agent switching not configured for this session"),{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}),{stopReason:"end_turn"}}runRestartCommand(){return this.enqueuePrompt(()=>this.runRestartCommandInline())}async runRestartCommandInline(){if(!this.spawnReplacementAgent)throw re(new Error("agent restart not configured for this session"),k.InternalError);return await this.respawnAgent(),{stopReason:"end_turn"}}runCompactCommand(e){return this.enqueuePrompt(()=>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;if(e==null&&t==null)return this.emitExtensionReply("This session has never been compacted."),{stopReason:"end_turn"};if(e==null)return this.emitExtensionReply(`No compaction in progress. Last summarized through entry: ${t}`),{stopReason:"end_turn"};let s=[`Compaction state: ${e.status}${e.iter!=null?` (iteration ${e.iter})`:""}`,`Summarized through entry: ${t??0}`,`Pending attempts: ${e.attempts??0}`];return this.emitExtensionReply(s.join(`
74
+ `)),{stopReason:"end_turn"}}runUncompactCommand(){return this.enqueuePrompt(()=>this.runUncompactCommandInline())}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(()=>this.runForkCommandInline(e,void 0))}async findMessageIdBefore(e){if(!this.historyStore)return;let t=await this.historyStore.load(this.sessionId),s;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 s;s=i}}}async runForkCommandInline(e,t){if(!this.forkHook)return this.emitExtensionReply("Fork not configured for this session."),{stopReason:"end_turn"};let s=(e??"").trim(),r;if(s==="verbatim")r="verbatim";else if(s==="synthesis"||s==="")r=void 0;else return this.emitExtensionReply(`Unknown fork argument: \`${s}\`. 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 re(new Error("session is closing"),k.SessionClosing);return this.lastCancelAt=0,this.forceCancelling=!0,await this.close({deleteRecord:!1}),{stopReason:"cancelled"}}async respawnAgent(){let e=this.spawnReplacementAgent,t=this.agentId,s=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);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??[]),await o.kill().catch(()=>{}),s&&await this.runInternalPrompt(s).catch(()=>{}),this.broadcastAgentSwitch(t,t);let i={agentId:t,upstreamSessionId:this.upstreamSessionId};for(let a of this.agentChangeHandlers)try{a(i)}catch{}}async buildSwitchTranscript(e,t){let s=[],r=await this.getHistorySnapshot();for(let u of r){if(u.method!=="session/update")continue;let f=(u.params??{}).update;if(!f||f._meta?.["hydra-acp"]?.synthetic)continue;let l=f.sessionUpdate;if(l==="prompt_received"){let m=tt(f.prompt);m&&s.push({speaker:"user",text:m})}else if(l==="agent_message_chunk"){let g=f.content?.text;g&&s.push({speaker:`agent: ${e}`,text:g})}else if(l==="tool_call"||l==="tool_call_update"){let m=f.status,g=f.title;(m==="completed"||m==="failed")&&s.push({speaker:"tool",text:`${g??"?"} ${m}`})}}if(s.length===0)return"";let o=[],i;for(let u of s)i&&i.speaker===u.speaker?i.text+=u.text:(i&&o.push(`<${i.speaker}>: ${i.text.trim()}`),i={speaker:u.speaker,text:u.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(`
75
+ `)}async seedFromImport(){await this.enqueuePrompt(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(async()=>{let t=this.title??"(untitled)",s=[];if(this.historyStore)try{s=await this.historyStore.load(this.sessionId)}catch(o){this.logger?.warn(`seedFromFork: historyStore.load failed: ${o.message}`)}let r=ls({synopsis:e,title:t,tail:s,tailK:hc,tailFloor:yc,watermark:this._summarizedThroughEntry});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 s=(e.mode??"memory")==="file"&&e.filePathFor!==void 0?e.filePathFor(this.sessionId):void 0,r={};e.capacityBytes!==void 0&&(r.capacityBytes=e.capacityBytes),s!==void 0&&(r.filePath=s),e.fileCapBytes!==void 0&&(r.fileCapBytes=e.fileCapBytes),r.onFileCapReached=()=>{this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"stream_truncated",...s!==void 0?{filePath:s}:{},fileCapBytes:e.fileCapBytes}})};let o=new Yt(r);this.streamBuffer=o,this.streamFilePath=s;let i={capacityBytes:o.capacity};return s!==void 0&&(i.filePath=s),e.fileCapBytes!==void 0&&(i.fileCapBytes=e.fileCapBytes),i}streamWrite(e,t){let s=this.requireStreamBuffer();if(e.length>0){let r=Buffer.from(e,"base64");s.append(r)}return t===!0&&s.close(),{writeCursor:s.writeCursorPos}}async streamRead(e,t,s){let r=this.requireStreamBuffer(),o=Math.max(0,Math.min(t??Ye,Ye)),i=r.read(e,o);if(i.bytes.length===0&&i.eof!==!0&&s!==void 0&&s>0){let d=await r.waitForData(i.nextCursor,s);(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 s=this.requireStreamBuffer().tail(e);return{bytes:s.bytes.toString("base64"),startCursor:s.startCursor,endCursor:s.endCursor,truncated:s.truncated}}streamHead(e){let s=this.requireStreamBuffer().head(e);return{bytes:s.bytes.toString("base64"),startCursor:s.startCursor,endCursor:s.endCursor,truncated:s.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=k.StreamNotEnabled,e}return this.streamBuffer}markClosed(e){if(this.closed)return;e={deleteRecord:e.deleteRecord||this.deleteRecordIntent},this.closing=!0,this.closed=!0,this.cancelIdleTimer(),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.currentEntry.wasAmend),this.currentEntry=void 0;let s=this.promptQueue;this.promptQueue=[];for(let o of s){o.cancelled=!0,o.kind==="user"&&this.broadcastQueueRemoved(o.messageId,"abandoned");try{o.resolve({stopReason:"cancelled"})}catch{}}this.notifyChain("session.closed",{}),this.toolCompletionSeen.clear(),this.toolCallKind.clear(),this.filesEditedSeen.clear();let r=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>po(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(()=>So.unlink(i).catch(()=>{}))}for(let o of this.closeHandlers)o(e)}get lastActivityAt(){return this.lastRecordedAt}setAttentionFlag(e,t,s){this._setAttentionFlag(e,t,s,!0)}_setAttentionFlag(e,t,s,r){let o=`${e}::${t}`,i=this.attentionFlags.get(o);if(i){if(JSON.stringify(i.payload)===JSON.stringify(s))return;this.attentionFlags.set(o,{...i,payload:s,raisedAt:i.raisedAt})}else this.attentionFlags.set(o,{source:e,reason:t,raisedAt:Date.now(),payload:s});r&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}clearAttentionFlag(e,t){this._clearAttentionFlag(e,t,!0)}_clearAttentionFlag(e,t,s){let r=`${e}::${t}`;this.attentionFlags.delete(r)&&s&&(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},s=Math.round(e/1e3);this.logger?.info(`session ${this.sessionId} idle timeout fired after ${s}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()}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}onIdle(e,t){let s={fn:e,once:!!t?.once,debounceMs:t?.debounceMs??0};return this.idleHandlers.push(s),()=>{let r=this.idleHandlers.indexOf(s);r>=0&&this.idleHandlers.splice(r,1),s.timer&&(clearTimeout(s.timer),s.timer=void 0)}}onceIdle(e){return this.onIdle(e,{once:!0})}dispatchIdle(){if(this.closed)return;if(!this.isQuiescedSync()){for(let s of this.idleHandlers)s.timer&&(clearTimeout(s.timer),s.timer=void 0);return}let t=[...this.idleHandlers];for(let s of t){if(s.debounceMs===0){if(s.once){let r=this.idleHandlers.indexOf(s);r>=0&&this.idleHandlers.splice(r,1)}try{s.fn(this)}catch{}continue}s.timer&&(clearTimeout(s.timer),s.timer=void 0),s.timer=setTimeout(()=>{if(s.timer=void 0,!this.closed&&this.isQuiescedSync()){if(s.once){let r=this.idleHandlers.indexOf(s);r>=0&&this.idleHandlers.splice(r,1)}try{s.fn(this)}catch{}}},s.debounceMs),typeof s.timer.unref=="function"&&s.timer.unref()}}disposeIdleHandlers(){for(let e of this.idleHandlers)e.timer&&(clearTimeout(e.timer),e.timer=void 0);this.idleHandlers.length=0}maybeEmitToolEdges(e){if(!e||typeof e!="object")return;let t=e.update;if(!t||typeof t!="object")return;let s=t,r=typeof s.sessionUpdate=="string"?s.sessionUpdate:"";if(r!=="tool_call"&&r!=="tool_call_update")return;let o=typeof s.toolCallId=="string"&&s.toolCallId.length>0?s.toolCallId:void 0;if(!o)return;let i=typeof s.kind=="string"?s.kind:void 0;this.toolCallKind.note(o,i);let a=this.toolCallKind.effective(o,i);if(a===eo&&Array.isArray(s.locations))for(let c of s.locations){if(!c||typeof c!="object")continue;let f=c.path;if(typeof f!="string"||f.length===0||this.filesEditedSeen.has(f))continue;this.filesEditedSeen.add(f);let p=c.line,l={path:f,toolCallId:o};typeof p=="number"&&(l.line=p),this.notifyChain("file.edited",l)}if(r!=="tool_call_update")return;let d=typeof s.status=="string"?s.status:void 0;if(d!=="completed"&&d!=="failed"||this.toolCompletionSeen.has(o))return;this.toolCompletionSeen.set(o,d);let u={toolCallId:o,status:d};a&&(u.kind=a),s.content!==void 0&&(u.content=s.content),Array.isArray(s.locations)&&(u.locations=s.locations),this.notifyChain("tool.completed",u)}notifyChain(e,t){let s=`lifecycle:${e}`;for(let r of this.transformChain)r.intercepts.has(s)&&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,s){let r=this.rewriteForClient(t),o=!mo(e,r),i=o?Mc(e,r):r,a=Date.now(),d=o?Me(i,a):i;if(o){let u={method:e,params:i,recordedAt:a};if(this.lastRecordedAt=u.recordedAt,this.appendCount+=1,this.historyStore){let c=this.historyStore;c.append(this.sessionId,u).catch(()=>{}),this.appendCount>=this.compactEvery&&(this.appendCount=0,c.compact(this.sessionId,this.historyMaxEntries).catch(()=>{}))}for(let c of this.broadcastHandlers)try{c(u)}catch{}this.scheduleIdleCheck(),this.dispatchIdle()}this.updatedAt=Date.now();for(let u of this.clients.values())s&&u.clientId===s||u.connection.notify(e,d).catch(()=>{})}async requestPermissionFromClients(e){return this.handlePermissionRequest(e)}async handlePermissionRequest(e){let t=[...this.clients.values()];if(t.length===0)throw re(new Error("no clients attached to handle permission request"),k.PermissionDenied);let s=this.rewriteForClient(e),r=go(s),o=Te(),{toolCall:i,options:a}=s??{};return new Promise((d,u)=>{let c=!1,f=[],p=0,l,m=this.sessionId,g=b=>{c||(c=!0,this.clearAttentionFlag("daemon",`permission:${o}`),this.permissionCallbacks.delete(o),b())},h=b=>b?.code===k.MethodNotFound;function y(b){if(c)return;let w=b.connection.request("session/request_permission",s);f.push({client:b}),p++,w.then(v=>{p--,g(()=>{let A=Ec({toolCallId:r,result:v,resolver:b});for(let C of f)C.client.clientId!==b.clientId&&C.client.connection.notify("session/update",{sessionId:m,update:A}).catch(()=>{});d(v)})}).catch(v=>{if(p--,h(v)||(l=v),p===0&&!c){let A=l??re(new Error("no client handled permission request"),k.PermissionDenied);g(()=>u(A))}})}this.setAttentionFlag("daemon",`permission:${o}`,{kind:"permission",toolCall:i??null,options:a??null}),this.permissionCallbacks.set(o,y);for(let b of t)y(b)})}async enqueuePrompt(e){return new Promise((t,s)=>{let r={kind:"internal",messageId:Te(),enqueuedAt:Date.now(),cancelled:!1,task:e,resolve:t,reject:s};this.promptQueue.push(r),this.drainQueue()})}async enqueueUserPrompt(e,t,s,r){let o=(t??{}).prompt??[],i={clientId:e.clientId};e.clientInfo?.name&&(i.name=e.clientInfo.name),e.clientInfo?.version&&(i.version=e.clientInfo.version),r?.fromSession&&(i.fromSession=r.fromSession),r?.fromSessionTitle&&(i.fromSessionTitle=r.fromSessionTitle),r?.fromLabel&&(i.fromLabel=r.fromLabel),r?.depth!==void 0&&(i.depth=r.depth);let a=this.parseQueuePosition(t);return new Promise((d,u)=>{let c={kind:"user",messageId:s,originator:i,clientId:e.clientId,prompt:o,enqueuedAt:Date.now(),cancelled:!1,resolve:d,reject:u},f=this.insertEntryAt(c,a);this.persistRewrite(),this.broadcastQueueAdded(c,{position:f}),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 s=t[le];if(!s||typeof s!="object"||Array.isArray(s))return!1;let r=s.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 s=t["hydra-acp"];if(!s||typeof s!="object"||Array.isArray(s))return"tail";let r=s.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 s=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;if(t==="head")return this.promptQueue.unshift(e),s;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),s+o+1}return this.promptQueue.push(e),s+this.promptQueue.length-1}persistRewrite(){let e=[];for(let s of this.promptQueue)s.kind!=="user"||s.cancelled||e.push(this.persistedFromEntry(s));let t=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>bt(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.shift();if(!e)break;if(!e.cancelled){this.currentEntry=e,e.kind==="user"&&this.persistRewrite(),e.kind==="user"&&this.broadcastQueueRemoved(e.messageId,"started");try{let t=await this.runQueueEntry(e);e.resolve(t),await new Promise(s=>setImmediate(s))}catch(t){e.reject(t)}finally{this.currentEntry=void 0}}}}finally{this.promptInFlight=!1,this.dispatchIdle()}}}async runQueueEntry(e){if(e.kind==="internal")return e.task();this.broadcastPromptReceived(e);let t=tt(e.prompt).replace(/\s+$/,""),s=!t.includes(`
76
+ `)&&t.startsWith("/")?t.split(/\s+/)[0]??"":"",r=s.startsWith("/")?s.slice(1):"",o=r.length>0&&this.aliasableBareVerbs().has(r);if(s==="/model"||s==="/mode"||s==="/sessions"||s==="/help"||s==="/hydra"||o){let d;if(s==="/sessions")d=await this.handleSessionsCommand();else if(s==="/help")d=await this.handleHelpCommand();else if(s==="/mode")d=await this.handleModeCommand(t);else if(s==="/model")d=await this.handleModelCommand(t);else if(o){let u=t.slice(s.length).trim(),c=u?`/hydra ${r} ${u}`:`/hydra ${r}`;d=await this.handleSlashCommand(c,e.messageId)}else d=await this.handleSlashCommand(t,e.messageId);return this.closed||this.broadcastTurnComplete(e.clientId,d,e.messageId,e.wasAmend),this.clearAmendIfMatches(e.messageId),d}if(this.clearRollbackBreadcrumbHook)try{this.clearRollbackBreadcrumbHook()}catch{}let i=e.prompt;s&&this.agentAdvertisedCommands.length>0&&!this.agentKnowsSlashCommand(s)&&(i=_c(e.prompt,Pc));let a;try{a=await this.forwardRequest("session/prompt",{sessionId:this.sessionId,prompt:i},e.emitterName?new Set([e.emitterName]):new Set,e.chainStartIdx??0)}catch(d){if(this.forceCancelling)return this.clearAmendIfMatches(e.messageId),{stopReason:"cancelled"};throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,e.wasAmend),this.clearAmendIfMatches(e.messageId),d}return this.closed||this.broadcastTurnComplete(e.clientId,a,e.messageId,e.wasAmend),this.clearAmendIfMatches(e.messageId),a}clearAmendIfMatches(e){this.amendInProgress?.cancelledMessageId===e&&(this.amendInProgress=void 0)}};function re(n,e){return n.code=e,n}var vc=new Set(["session_info_update","current_model_update","current_mode_update","available_commands_update","available_modes_update","usage_update","config_option_update","hydra_compaction"]);function mo(n,e){if(n!=="session/update")return!1;let s=(e??{}).update?.sessionUpdate;return typeof s=="string"&&vc.has(s)}function Sc(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]?.name!==e[t]?.name||n[t]?.description!==e[t]?.description)return!1;return!0}function Ic(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]?.id!==e[t]?.id||n[t]?.name!==e[t]?.name||n[t]?.description!==e[t]?.description)return!1;return!0}function kc(n,e){if(n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]?.modelId!==e[t]?.modelId||n[t]?.name!==e[t]?.name||n[t]?.description!==e[t]?.description)return!1;return!0}function nt(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(!t||typeof t!="object"||Array.isArray(t))continue;let s=t,r=typeof s.modelId=="string"&&s.modelId.trim()||typeof s.value=="string"&&s.value.trim()||typeof s.id=="string"&&s.id.trim()||void 0;if(!r)continue;let o={modelId:r};typeof s.name=="string"&&s.name.length>0&&(o.name=s.name),typeof s.description=="string"&&s.description.length>0&&(o.description=s.description),e.push(o)}return e}function vt(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(!t||typeof t!="object"||Array.isArray(t))continue;let s=t,r=typeof s.value=="string"&&s.value.trim()||typeof s.id=="string"&&s.id.trim()||void 0;if(!r)continue;let o={id:r};typeof s.name=="string"&&s.name.length>0&&(o.name=s.name),typeof s.description=="string"&&s.description.length>0&&(o.description=s.description),e.push(o)}return e}function Ac(n){let t=(n??{}).update??{};if(t.sessionUpdate!=="available_modes_update")return null;let s=t.availableModes;if(!Array.isArray(s))return[];let r=[];for(let o of s){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 Cc(n,e){let s=(e??{}).update??{},r=s.sessionUpdate;if(r==="agent_message_chunk"){let o=s.content??{};typeof o.text=="string"&&(n.chunks.push(o.text),n.messageChars+=o.text.length);return}if(r==="agent_thought_chunk"){let o=s.content??{};typeof o.text=="string"&&(n.thinkingChars+=o.text.length);return}if(r==="tool_call"){n.toolCalls++;return}if(r==="usage_update"){typeof s.used=="number"&&(n.lastUsed=s.used),typeof s.size=="number"&&(n.lastSize=s.size);return}}function xc(n){let t=(n??{}).update??{};if(t.sessionUpdate!=="available_commands_update")return null;let s=t.availableCommands??t.commands;if(!Array.isArray(s))return[];let r=[];for(let o of s){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 Mc(n,e){if(n!=="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:Te()}}}function Zt(n,e){for(let t=0;t<n.length;t++){let s=n[t];if(!s||s.method!=="session/update")continue;if(s.params?.update?.messageId===e)return t}return-1}function go(n){if(!n||typeof n!="object")return;let e=n.toolCall;if(!e||typeof e!="object")return;let t=e.toolCallId;return typeof t=="string"?t:void 0}function Ec(n){let e=Rc(n.result),t={sessionUpdate:"permission_resolved"};return n.toolCallId!==void 0&&(t.toolCallId=n.toolCallId),e&&(t.outcome=e,e.kind==="selected"&&typeof e.optionId=="string"&&(t.chosenOptionId=e.optionId)),t.resolvedBy=Tc(n.resolver),t}function Rc(n){if(!n||typeof n!="object")return;let e=n.outcome;if(!e||typeof e!="object")return;let t=e.kind;if(typeof t!="string")return;let s={kind:t},r=e.optionId;typeof r=="string"&&(s.optionId=r);let o=e.reason;return typeof o=="string"&&(s.reason=o),s}function Tc(n){let e={clientId:n.clientId};return n.clientInfo?.name&&(e.name=n.clientInfo.name),n.clientInfo?.version&&(e.version=n.clientInfo.version),e}function tt(n){return typeof n=="string"?n:Array.isArray(n)?n.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var Pc="\u200B";function _c(n,e){let t=n.findIndex(o=>o&&typeof o=="object"&&typeof o.text=="string");if(t<0)return n;let s=n[t],r=[...n];return r[t]={...s,text:`${e}${s.text}`},r}function ps(n){return n==="session/prompt"?{stopReason:"stopped"}:{}}function $c(n){return n==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function ho(n){let e=n.name&&n.name!==n.id?`${n.id} (${n.name}) \u2014 \u25B6 ${n.currentValue}`:`${n.id} \u2014 \u25B6 ${n.currentValue}`;if(n.options.length===0)return e;let t=Math.max(...n.options.map(r=>r.value.length)),s=n.options.map(r=>{let o=r.value===n.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}
77
77
  ${s.join(`
78
- `)}`}function as(n,e){for(let t of n.split(/\r?\n/)){let s=t.trim();if(s)return s.length>e?`${s.slice(0,e)}\u2026`:s}}W();_e();import*as st from"fs/promises";import*as Nm from"path";import{customAlphabet as hc}from"nanoid";import{z as R}from"zod";import{z as tt}from"zod";var mc=tt.object({source:tt.string(),reason:tt.string(),raisedAt:tt.number(),payload:tt.unknown()}),ai=tt.array(mc);import{z}from"zod";var di=z.object({status:z.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:z.number(),iter:z.number().int().nonnegative().optional(),attempts:z.number().int().nonnegative().optional(),lastError:z.string().optional(),worker:z.object({upstreamSessionId:z.string(),pid:z.number().int().nonnegative()}).optional()}),vt=z.object({goal:z.string().optional(),outcome:z.string().optional(),files_touched:z.array(z.string()).optional(),tools_used:z.array(z.string()).optional(),rejected_approaches:z.array(z.string()).optional(),open_threads:z.array(z.string()).optional(),decisions:z.array(z.string()).optional(),file_edit_intentions:z.array(z.string()).optional(),unresolved_errors:z.array(z.string()).optional(),tool_state:z.array(z.string()).optional()}),ci=200,ds=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
78
+ `)}`}function ms(n,e){for(let t of n.split(/\r?\n/)){let s=t.trim();if(s)return s.length>e?`${s.slice(0,e)}\u2026`:s}}W();Fe();import*as it from"fs/promises";import*as ug from"path";import{customAlphabet as Nc}from"nanoid";import{z as M}from"zod";import{z as rt}from"zod";var Fc=rt.object({source:rt.string(),reason:rt.string(),raisedAt:rt.number(),payload:rt.unknown()}),Io=rt.array(Fc);import{z}from"zod";var ko=z.object({status:z.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:z.number(),iter:z.number().int().nonnegative().optional(),attempts:z.number().int().nonnegative().optional(),lastError:z.string().optional(),worker:z.object({upstreamSessionId:z.string(),pid:z.number().int().nonnegative()}).optional()}),St=z.object({goal:z.string().optional(),outcome:z.string().optional(),files_touched:z.array(z.string()).optional(),tools_used:z.array(z.string()).optional(),rejected_approaches:z.array(z.string()).optional(),open_threads:z.array(z.string()).optional(),decisions:z.array(z.string()).optional(),file_edit_intentions:z.array(z.string()).optional(),unresolved_errors:z.array(z.string()).optional(),tool_state:z.array(z.string()).optional()}),Ao=200,gs=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
79
79
  {
80
80
  "title": "short summary, max 80 chars",
81
81
  "synopsis": {
@@ -85,7 +85,7 @@ ${s.join(`
85
85
  "open_threads": ["work started but not finished"]
86
86
  }
87
87
  }
88
- Use empty arrays/strings where a field doesn't apply.`;function ui(n){let e=n.trim();if(e.length===0)return;let t=nt(e);if(t===void 0){let i=e.indexOf("{"),o=e.lastIndexOf("}");i>=0&&o>i&&(t=nt(e.slice(i,o+1)))}if(t===void 0){let i=fi(e);i!==void 0&&(t=nt(i))}if(t===void 0||t===null||typeof t!="object")return;let s=t,r={};if(typeof s.title=="string"){let i=s.title.trim();i.length>0&&(r.title=i.slice(0,ci))}if(s.synopsis!==void 0&&s.synopsis!==null){let i=vt.safeParse(s.synopsis);i.success&&gc(i.data)&&(r.synopsis=i.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var cs=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
88
+ Use empty arrays/strings where a field doesn't apply.`;function Co(n){let e=n.trim();if(e.length===0)return;let t=ot(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=ot(e.slice(o,i+1)))}if(t===void 0){let o=Mo(e);o!==void 0&&(t=ot(o))}if(t===void 0||t===null||typeof t!="object")return;let s=t,r={};if(typeof s.title=="string"){let o=s.title.trim();o.length>0&&(r.title=o.slice(0,Ao))}if(s.synopsis!==void 0&&s.synopsis!==null){let o=St.safeParse(s.synopsis);o.success&&Oc(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var hs=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
89
89
  {
90
90
  "title": "short summary, max 80 chars",
91
91
  "goal": "the user's original ask",
@@ -97,58 +97,58 @@ Use empty arrays/strings where a field doesn't apply.`;function ui(n){let e=n.tr
97
97
  "unresolved_errors": ["errors left open at session end"],
98
98
  "tool_state": ["runtime state relevant for recall"]
99
99
  }
100
- Use empty arrays/strings where a field doesn't apply.`;function li(n){let e=n.trim();if(e.length===0)return;let t=nt(e);if(t===void 0){let u=e.indexOf("{"),c=e.lastIndexOf("}");u>=0&&c>u&&(t=nt(e.slice(u,c+1)))}if(t===void 0){let u=fi(e);u!==void 0&&(t=nt(u))}if(t===void 0||t===null||typeof t!="object")return;let s=t,r={};if(typeof s.title=="string"){let u=s.title.trim();u.length>0&&(r.title=u.slice(0,ci))}let i={},o=!1,a=["goal","outcome"];for(let u of a)if(typeof s[u]=="string"){let c=s[u].trim();c.length>0&&(i[u]=c,o=!0)}let d=["files_touched","tools_used","rejected_approaches","open_threads","decisions","file_edit_intentions","unresolved_errors","tool_state"];for(let u of d)if(Array.isArray(s[u])){let c=s[u],f=z.array(z.string()).safeParse(c);f.success&&c.length>0&&(i[u]=f.data,o=!0)}if(o&&(r.synopsis=i),!(r.title===void 0&&r.synopsis===void 0))return r}function nt(n){try{return JSON.parse(n)}catch{return}}function fi(n){let e=n.indexOf("{");if(e<0)return;let t=0,s=!1,r=!1;for(let i=e;i<n.length;i++){let o=n[i];if(s){r?r=!1:o==="\\"?r=!0:o==='"'&&(s=!1);continue}if(o==='"'){s=!0;continue}if(o==="{")t++;else if(o==="}"&&(t--,t===0))return n.slice(e,i+1)}}function gc(n){return n.goal!==void 0&&n.goal.trim().length>0||n.outcome!==void 0&&n.outcome.trim().length>0||n.files_touched!==void 0&&n.files_touched.length>0||n.tools_used!==void 0&&n.tools_used.length>0||n.rejected_approaches!==void 0&&n.rejected_approaches.length>0||n.open_threads!==void 0&&n.open_threads.length>0||n.decisions!==void 0&&n.decisions.length>0||n.file_edit_intentions!==void 0&&n.file_edit_intentions.length>0||n.unresolved_errors!==void 0&&n.unresolved_errors.length>0||n.tool_state!==void 0&&n.tool_state.length>0}var yc="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",wc=hc(yc,16),vc="hydra_lineage_";function bt(){return`${vc}${wc()}`}var ls=R.object({name:R.string(),description:R.string().optional()}),fs=R.object({id:R.string(),name:R.string().optional(),description:R.string().optional()}),bc=R.object({modelId:R.string(),name:R.string().optional(),description:R.string().optional()}),ps=R.object({used:R.number().optional(),size:R.number().optional(),costAmount:R.number().optional(),costCurrency:R.string().optional(),cumulativeCost:R.number().optional()}),ms=R.object({name:R.string(),version:R.string().optional()}),Sc=R.object({previousUpstreamSessionId:R.string(),previousSummarizedThroughEntry:R.number().int().nonnegative().optional()}),Ic=R.object({upstreamSessionId:R.string(),agentId:R.string(),startedAt:R.string().optional(),endedAt:R.string().optional(),cost:R.number().nonnegative().optional(),inferred:R.boolean().optional()}),kc=R.object({version:R.literal(1),sessionId:R.string(),lineageId:R.string().optional(),upstreamSessionId:R.string(),importedFromSessionId:R.string().optional(),importedFromUpstreamSessionId:R.string().optional(),importedFromMachine:R.string().optional(),agentId:R.string(),cwd:R.string(),title:R.string().optional(),synopsis:vt.optional(),compactionState:di.optional(),rollbackBreadcrumb:Sc.optional(),upstreamGenerations:R.array(Ic).optional(),summarizedThroughEntry:R.number().int().nonnegative().optional(),agentArgs:R.array(R.string()).optional(),currentModel:R.string().optional(),currentMode:R.string().optional(),currentUsage:ps.optional(),agentCommands:R.array(ls).optional(),agentModes:R.array(fs).optional(),agentModels:R.array(bc).optional(),pendingHistorySync:R.boolean().optional(),pendingAgentSwap:R.string().optional(),parentSessionId:R.string().optional(),forkedFromSessionId:R.string().optional(),forkedFromMessageId:R.string().optional(),forkSynthesisState:R.enum(["running","failed"]).optional(),originatingClient:ms.optional(),interactive:R.boolean().optional(),priority:R.number().int().nonnegative().optional(),forwardedEnv:R.record(R.string(),R.string()).optional(),attentionFlags:ai.default([]).optional(),extensionState:R.record(R.string(),R.record(R.string(),R.unknown())).default({}).optional(),createdAt:R.string(),updatedAt:R.string()}),us=/^[A-Za-z0-9_-]+$/;function Ac(n){if(!us.test(n))throw new Error(`unsafe session id: ${n}`)}var Gt=class{async write(e){Ac(e.sessionId);let t={version:1,...e};await ce(I.sessionFile(e.sessionId),t,{mode:384})}async read(e){if(!us.test(e))return;let t=await ue(I.sessionFile(e));if(t!==void 0)try{return kc.parse(t)}catch{return}}async delete(e){if(us.test(e)){try{await st.unlink(I.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await st.rmdir(I.sessionDir(e))}catch(t){let s=t;if(s.code!=="ENOENT"&&s.code!=="ENOTEMPTY")throw t}}}async findByLineageId(e){if(e.length===0)return;let t=await this.list().catch(()=>[]);for(let s of t)if(s.lineageId===e)return s}async list(){let e;try{e=await st.readdir(I.sessionsDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let t=await Promise.all(e.map(r=>this.read(r).catch(()=>{}))),s=[];for(let r of t)r&&s.push(r);return s}};function gs(n){let e=new Date().toISOString(),t=n.createdAt??e,s=n.upstreamGenerations??(n.upstreamSessionId?[{upstreamSessionId:n.upstreamSessionId,agentId:n.agentId,startedAt:t}]:[]);return{sessionId:n.sessionId,lineageId:n.lineageId,upstreamSessionId:n.upstreamSessionId,importedFromSessionId:n.importedFromSessionId,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,importedFromMachine:n.importedFromMachine,agentId:n.agentId,cwd:n.cwd,title:n.title,synopsis:n.synopsis,summarizedThroughEntry:n.summarizedThroughEntry,compactionState:n.compactionState,rollbackBreadcrumb:n.rollbackBreadcrumb,upstreamGenerations:s,agentArgs:n.agentArgs,currentModel:n.currentModel,currentMode:n.currentMode,currentUsage:n.currentUsage,agentCommands:n.agentCommands,agentModes:n.agentModes,agentModels:n.agentModels,pendingHistorySync:n.pendingHistorySync,pendingAgentSwap:n.pendingAgentSwap,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:n.interactive,priority:n.priority,forwardedEnv:n.forwardedEnv,attentionFlags:n.attentionFlags??[],extensionState:n.extensionState??{},createdAt:t,updatedAt:n.updatedAt??e}}W();_e();import*as be from"fs/promises";import{z as he}from"zod";var Cc=he.object({version:he.literal(1),agentId:he.string(),upstreamSessionId:he.string(),deletedAt:he.string(),upstreamUpdatedAt:he.string().optional(),cwd:he.string().optional(),title:he.string().optional(),reason:he.enum(["user","expired"]).optional(),interactive:he.boolean().optional()}),Kt=class{async add(e){let t={version:1,...e};await ce(I.tombstoneFile(e.agentId,e.upstreamSessionId),t,{mode:384})}async has(e,t){try{return await be.access(I.tombstoneFile(e,t)),!0}catch{return!1}}async read(e,t){let s=I.tombstoneFile(e,t),r=await ue(s);if(r===void 0)return await this.has(e,t)?{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}:void 0;try{return Cc.parse(r)}catch{return{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}}}async remove(e,t){try{await be.unlink(I.tombstoneFile(e,t))}catch(s){if(s.code!=="ENOENT")throw s}try{await be.rmdir(I.tombstoneAgentDir(e))}catch(s){let r=s;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw s}}async list(e){if(e!==void 0)return this.listForAgent(e);let t;try{t=await be.readdir(I.tombstonesDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let s=[];for(let r of t){let i;try{i=decodeURIComponent(r)}catch{continue}s.push(...await this.listForAgent(i))}return s}async listForAgent(e){let t;try{t=await be.readdir(I.tombstoneAgentDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let s=[];for(let r of t){let i;try{i=decodeURIComponent(r)}catch{continue}let o=await this.read(e,i);o&&s.push(o)}return s}};function pi(n,e){return n.reason==="user"||e===void 0?!1:n.upstreamUpdatedAt===void 0?!0:e>n.upstreamUpdatedAt}import*as Ci from"fs/promises";import{fileURLToPath as xc}from"url";import*as St from"path";import*as Vt from"fs";function Rc(){try{let n=St.dirname(xc(import.meta.url));for(let e=0;e<8;e+=1){let t=St.join(n,"package.json");if(Vt.existsSync(t)){let r=JSON.parse(Vt.readFileSync(t,"utf8"));if(typeof r.version=="string"&&r.version.length>0&&(typeof r.name!="string"||r.name.includes("hydra-acp")))return r.version}let s=St.dirname(n);if(s===n)break;n=s}}catch{}return"0.0.0"}var Y=Rc(),Yt="hydra-acp-cat";var Ec=12e4;async function gi(n,e,t){let s=n.timeoutMs??Ec,r,i,o=!1;try{let a=(async()=>{r=Re.spawn({agentId:n.agentId,cwd:n.cwd,plan:n.plan,logger:n.logger});let d=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:{name:"hydra-synopsis",version:Y}}),u=await r.connection.request("session/new",{cwd:n.cwd,mcpServers:[]}),c=u.sessionId;if(typeof c!="string"){n.logger?.warn(`synopsis: agent ${n.agentId} returned non-string sessionId from session/new`),n.onFailure?.(`agent ${n.agentId} did not return a sessionId from session/new`);return}if(n.onWorkerSpawned?.(c,r.pid),n.modelId){let g=Pc(u);if(g.size===0||g.has(n.modelId))try{await r.connection.request("session/set_model",{sessionId:c,modelId:n.modelId})}catch(m){n.logger?.warn(`synopsis: agent ${n.agentId} rejected set_model ${JSON.stringify(n.modelId)}: ${m.message}; continuing on default`)}else n.logger?.warn(`synopsis: model ${JSON.stringify(n.modelId)} not advertised by agent ${n.agentId} (have [${[...g].join(", ")}]); continuing on default`)}let f=[];r.connection.onNotification("session/update",g=>{let m=Mc(g);m.length>0&&f.push(m)}),await r.connection.request("session/prompt",{sessionId:c,prompt:[{type:"text",text:e}]});let p=f.join(""),l=t(p);if(!l){let g=JSON.stringify(p.slice(0,200));n.logger?.warn(`synopsis: agent ${n.agentId} reply did not parse (replyLen=${p.length} preview=${g})`);let m=p.slice(0,120).replace(/\s+/g," ").trim();n.onFailure?.(`agent ${n.agentId} returned unparseable JSON (${p.length} chars): ${m}${p.length>120?"\u2026":""}`)}return l})();return await new Promise((d,u)=>{i=setTimeout(()=>{o=!0,n.logger?.warn(`synopsis: agent ${n.agentId} timed out after ${s}ms`),n.onFailure?.(`agent ${n.agentId} timed out after ${s}ms`),d(void 0)},s),i.unref?.(),a.then(c=>{i&&clearTimeout(i),o||d(c)},c=>{i&&clearTimeout(i),o||u(c)})})}catch(a){let d=a.message;n.logger?.warn(`synopsis: agent ${n.agentId} failed: ${d}`),n.onFailure?.(`agent ${n.agentId} failed: ${d}`);return}finally{i&&clearTimeout(i),r&&await r.kill().catch(()=>{})}}async function Xt(n){let e=Ye(n.history,{maxChars:n.maxTranscriptChars}),t=n.sessionId!==void 0?`[hydra-acp title-regen worker for session ${n.sessionId}]`:"[hydra-acp title-regen worker]",s=e.length>0?`${t}
100
+ Use empty arrays/strings where a field doesn't apply.`;function xo(n){let e=n.trim();if(e.length===0)return;let t=ot(e);if(t===void 0){let u=e.indexOf("{"),c=e.lastIndexOf("}");u>=0&&c>u&&(t=ot(e.slice(u,c+1)))}if(t===void 0){let u=Mo(e);u!==void 0&&(t=ot(u))}if(t===void 0||t===null||typeof t!="object")return;let s=t,r={};if(typeof s.title=="string"){let u=s.title.trim();u.length>0&&(r.title=u.slice(0,Ao))}let o={},i=!1,a=["goal","outcome"];for(let u of a)if(typeof s[u]=="string"){let c=s[u].trim();c.length>0&&(o[u]=c,i=!0)}let d=["files_touched","tools_used","rejected_approaches","open_threads","decisions","file_edit_intentions","unresolved_errors","tool_state"];for(let u of d)if(Array.isArray(s[u])){let c=s[u],f=z.array(z.string()).safeParse(c);f.success&&c.length>0&&(o[u]=f.data,i=!0)}if(i&&(r.synopsis=o),!(r.title===void 0&&r.synopsis===void 0))return r}function ot(n){try{return JSON.parse(n)}catch{return}}function Mo(n){let e=n.indexOf("{");if(e<0)return;let t=0,s=!1,r=!1;for(let o=e;o<n.length;o++){let i=n[o];if(s){r?r=!1:i==="\\"?r=!0:i==='"'&&(s=!1);continue}if(i==='"'){s=!0;continue}if(i==="{")t++;else if(i==="}"&&(t--,t===0))return n.slice(e,o+1)}}function Oc(n){return n.goal!==void 0&&n.goal.trim().length>0||n.outcome!==void 0&&n.outcome.trim().length>0||n.files_touched!==void 0&&n.files_touched.length>0||n.tools_used!==void 0&&n.tools_used.length>0||n.rejected_approaches!==void 0&&n.rejected_approaches.length>0||n.open_threads!==void 0&&n.open_threads.length>0||n.decisions!==void 0&&n.decisions.length>0||n.file_edit_intentions!==void 0&&n.file_edit_intentions.length>0||n.unresolved_errors!==void 0&&n.unresolved_errors.length>0||n.tool_state!==void 0&&n.tool_state.length>0}var Hc="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",jc=Nc(Hc,16),Bc="hydra_lineage_";function It(){return`${Bc}${jc()}`}var ws=M.object({name:M.string(),description:M.string().optional()}),bs=M.object({id:M.string(),name:M.string().optional(),description:M.string().optional()}),Uc=M.object({modelId:M.string(),name:M.string().optional(),description:M.string().optional()}),vs=M.object({used:M.number().optional(),size:M.number().optional(),costAmount:M.number().optional(),costCurrency:M.string().optional(),cumulativeCost:M.number().optional()}),Ss=M.object({name:M.string(),version:M.string().optional()}),Dc=M.object({previousUpstreamSessionId:M.string(),previousSummarizedThroughEntry:M.number().int().nonnegative().optional()}),Lc=M.object({upstreamSessionId:M.string(),agentId:M.string(),startedAt:M.string().optional(),endedAt:M.string().optional(),cost:M.number().nonnegative().optional(),inferred:M.boolean().optional()}),qc=M.object({version:M.literal(1),sessionId:M.string(),lineageId:M.string().optional(),upstreamSessionId:M.string(),importedFromSessionId:M.string().optional(),importedFromUpstreamSessionId:M.string().optional(),importedFromMachine:M.string().optional(),agentId:M.string(),cwd:M.string(),title:M.string().optional(),synopsis:St.optional(),compactionState:ko.optional(),rollbackBreadcrumb:Dc.optional(),upstreamGenerations:M.array(Lc).optional(),summarizedThroughEntry:M.number().int().nonnegative().optional(),agentArgs:M.array(M.string()).optional(),currentModel:M.string().optional(),currentMode:M.string().optional(),currentUsage:vs.optional(),agentCommands:M.array(ws).optional(),agentModes:M.array(bs).optional(),agentModels:M.array(Uc).optional(),pendingHistorySync:M.boolean().optional(),pendingAgentSwap:M.string().optional(),parentSessionId:M.string().optional(),forkedFromSessionId:M.string().optional(),forkedFromMessageId:M.string().optional(),forkSynthesisState:M.enum(["running","failed"]).optional(),originatingClient:Ss.optional(),interactive:M.boolean().optional(),priority:M.number().int().nonnegative().optional(),forwardedEnv:M.record(M.string(),M.string()).optional(),attentionFlags:Io.default([]).optional(),extensionState:M.record(M.string(),M.record(M.string(),M.unknown())).default({}).optional(),createdAt:M.string(),updatedAt:M.string()}),ys=/^[A-Za-z0-9_-]+$/;function zc(n){if(!ys.test(n))throw new Error(`unsafe session id: ${n}`)}var en=class{async write(e){zc(e.sessionId);let t={version:1,...e};await ce(I.sessionFile(e.sessionId),t,{mode:384})}async read(e){if(!ys.test(e))return;let t=await ue(I.sessionFile(e));if(t!==void 0)try{return qc.parse(t)}catch{return}}async delete(e){if(ys.test(e)){try{await it.unlink(I.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await it.rmdir(I.sessionDir(e))}catch(t){let s=t;if(s.code!=="ENOENT"&&s.code!=="ENOTEMPTY")throw t}}}async findByLineageId(e){if(e.length===0)return;let t=await this.list().catch(()=>[]);for(let s of t)if(s.lineageId===e)return s}async list(){let e;try{e=await it.readdir(I.sessionsDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let t=await Promise.all(e.map(r=>this.read(r).catch(()=>{}))),s=[];for(let r of t)r&&s.push(r);return s}};function Is(n){let e=new Date().toISOString(),t=n.createdAt??e,s=n.upstreamGenerations??(n.upstreamSessionId?[{upstreamSessionId:n.upstreamSessionId,agentId:n.agentId,startedAt:t}]:[]);return{sessionId:n.sessionId,lineageId:n.lineageId,upstreamSessionId:n.upstreamSessionId,importedFromSessionId:n.importedFromSessionId,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,importedFromMachine:n.importedFromMachine,agentId:n.agentId,cwd:n.cwd,title:n.title,synopsis:n.synopsis,summarizedThroughEntry:n.summarizedThroughEntry,compactionState:n.compactionState,rollbackBreadcrumb:n.rollbackBreadcrumb,upstreamGenerations:s,agentArgs:n.agentArgs,currentModel:n.currentModel,currentMode:n.currentMode,currentUsage:n.currentUsage,agentCommands:n.agentCommands,agentModes:n.agentModes,agentModels:n.agentModels,pendingHistorySync:n.pendingHistorySync,pendingAgentSwap:n.pendingAgentSwap,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:n.interactive,priority:n.priority,forwardedEnv:n.forwardedEnv,attentionFlags:n.attentionFlags??[],extensionState:n.extensionState??{},createdAt:t,updatedAt:n.updatedAt??e}}W();Fe();import*as Ie from"fs/promises";import{z as be}from"zod";var Jc=be.object({version:be.literal(1),agentId:be.string(),upstreamSessionId:be.string(),deletedAt:be.string(),upstreamUpdatedAt:be.string().optional(),cwd:be.string().optional(),title:be.string().optional(),reason:be.enum(["user","expired"]).optional(),interactive:be.boolean().optional()}),tn=class{async add(e){let t={version:1,...e};await ce(I.tombstoneFile(e.agentId,e.upstreamSessionId),t,{mode:384})}async has(e,t){try{return await Ie.access(I.tombstoneFile(e,t)),!0}catch{return!1}}async read(e,t){let s=I.tombstoneFile(e,t),r=await ue(s);if(r===void 0)return await this.has(e,t)?{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}:void 0;try{return Jc.parse(r)}catch{return{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}}}async remove(e,t){try{await Ie.unlink(I.tombstoneFile(e,t))}catch(s){if(s.code!=="ENOENT")throw s}try{await Ie.rmdir(I.tombstoneAgentDir(e))}catch(s){let r=s;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw s}}async list(e){if(e!==void 0)return this.listForAgent(e);let t;try{t=await Ie.readdir(I.tombstonesDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let s=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}s.push(...await this.listForAgent(o))}return s}async listForAgent(e){let t;try{t=await Ie.readdir(I.tombstoneAgentDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let s=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}let i=await this.read(e,o);i&&s.push(i)}return s}};function Eo(n,e){return n.reason==="user"||e===void 0?!1:n.upstreamUpdatedAt===void 0?!0:e>n.upstreamUpdatedAt}import*as Uo from"fs/promises";import{fileURLToPath as Wc}from"url";import*as kt from"path";import*as nn from"fs";function Vc(){try{let n=kt.dirname(Wc(import.meta.url));for(let e=0;e<8;e+=1){let t=kt.join(n,"package.json");if(nn.existsSync(t)){let r=JSON.parse(nn.readFileSync(t,"utf8"));if(typeof r.version=="string"&&r.version.length>0&&(typeof r.name!="string"||r.name.includes("hydra-acp")))return r.version}let s=kt.dirname(n);if(s===n)break;n=s}}catch{}return"0.0.0"}var Y=Vc(),sn="hydra-acp-cat";var Qc=12e4;async function To(n,e,t){let s=n.timeoutMs??Qc,r,o,i=!1;try{let a=(async()=>{r=Re.spawn({agentId:n.agentId,cwd:n.cwd,plan:n.plan,logger:n.logger});let d=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:{name:"hydra-synopsis",version:Y}}),u=await r.connection.request("session/new",{cwd:n.cwd,mcpServers:[]}),c=u.sessionId;if(typeof c!="string"){n.logger?.warn(`synopsis: agent ${n.agentId} returned non-string sessionId from session/new`),n.onFailure?.(`agent ${n.agentId} did not return a sessionId from session/new`);return}if(n.onWorkerSpawned?.(c,r.pid),n.modelId){let m=Kc(u);if(m.size===0||m.has(n.modelId))try{await r.connection.request("session/set_model",{sessionId:c,modelId:n.modelId})}catch(g){n.logger?.warn(`synopsis: agent ${n.agentId} rejected set_model ${JSON.stringify(n.modelId)}: ${g.message}; continuing on default`)}else n.logger?.warn(`synopsis: model ${JSON.stringify(n.modelId)} not advertised by agent ${n.agentId} (have [${[...m].join(", ")}]); continuing on default`)}let f=[];r.connection.onNotification("session/update",m=>{let g=Gc(m);g.length>0&&f.push(g)}),await r.connection.request("session/prompt",{sessionId:c,prompt:[{type:"text",text:e}]});let p=f.join(""),l=t(p);if(!l){let m=JSON.stringify(p.slice(0,200));n.logger?.warn(`synopsis: agent ${n.agentId} reply did not parse (replyLen=${p.length} preview=${m})`);let g=p.slice(0,120).replace(/\s+/g," ").trim();n.onFailure?.(`agent ${n.agentId} returned unparseable JSON (${p.length} chars): ${g}${p.length>120?"\u2026":""}`)}return l})();return await new Promise((d,u)=>{o=setTimeout(()=>{i=!0,n.logger?.warn(`synopsis: agent ${n.agentId} timed out after ${s}ms`),n.onFailure?.(`agent ${n.agentId} timed out after ${s}ms`),d(void 0)},s),o.unref?.(),a.then(c=>{o&&clearTimeout(o),i||d(c)},c=>{o&&clearTimeout(o),i||u(c)})})}catch(a){let d=a.message;n.logger?.warn(`synopsis: agent ${n.agentId} failed: ${d}`),n.onFailure?.(`agent ${n.agentId} failed: ${d}`);return}finally{o&&clearTimeout(o),r&&await r.kill().catch(()=>{})}}async function rn(n){let e=et(n.history,{maxChars:n.maxTranscriptChars}),t=n.sessionId!==void 0?`[hydra-acp title-regen worker for session ${n.sessionId}]`:"[hydra-acp title-regen worker]",s=e.length>0?`${t}
101
101
 
102
102
  ${e}
103
103
 
104
- ${ds}`:`${t}
104
+ ${gs}`:`${t}
105
105
 
106
- ${ds}`;return gi(n,s,ui)}async function hi(n){let e=Ye(n.history,{maxChars:n.maxTranscriptChars}),t=n.sessionId!==void 0?`[hydra-acp compaction worker for session ${n.sessionId}]`:"[hydra-acp compaction worker]",s=e.length>0?`${t}
106
+ ${gs}`;return To(n,s,Co)}async function Po(n){let e=et(n.history,{maxChars:n.maxTranscriptChars}),t=n.sessionId!==void 0?`[hydra-acp compaction worker for session ${n.sessionId}]`:"[hydra-acp compaction worker]",s=e.length>0?`${t}
107
107
 
108
108
  ${e}
109
109
 
110
- ${cs}`:`${t}
110
+ ${hs}`:`${t}
111
111
 
112
- ${cs}`;return gi(n,s,li)}function Mc(n){if(!n||typeof n!="object")return"";let e=n.update;if(!e||typeof e!="object")return"";let t=e;if(t.sessionUpdate!=="agent_message_chunk")return"";let s=t.content;return s&&typeof s.text=="string"?s.text:""}function Pc(n){let e=new Set;mi(e,n.availableModels);let t=n.models;return t&&typeof t=="object"&&!Array.isArray(t)&&mi(e,t.availableModels),e}function mi(n,e){if(Array.isArray(e)){for(let t of e)if(t&&typeof t=="object"){let s=t.modelId??t.value??t.id;typeof s=="string"&&s.length>0&&n.add(s)}}}function Tc(n){let e=new Map;for(let t of Si(n).values())e.set(t.toolName,(e.get(t.toolName)??0)+1);return[...e.entries()].map(([t,s])=>({name:t,count:s})).sort((t,s)=>s.count-t.count||t.name.localeCompare(s.name))}function vi(n){return Tc(n).map(e=>e.name)}function _c(n){let e=new Map;for(let t of Si(n).values())for(let s of t.paths){let r=e.get(s);r===void 0&&(r=new Map,e.set(s,r)),r.set(t.toolName,(r.get(t.toolName)??0)+1)}return[...e.entries()].map(([t,s])=>{let r=[...s.entries()].map(([o,a])=>({name:o,count:a})).sort((o,a)=>a.count-o.count||o.name.localeCompare(a.name)),i=r.reduce((o,a)=>o+a.count,0);return{path:t,count:i,byTool:r}}).sort((t,s)=>s.count-t.count||t.path.localeCompare(s.path))}function bi(n){return _c(n).map(e=>e.path)}function Si(n){let e=new Map,t=0;for(let s of n){let i=s.params?.update;if(!i)continue;let o=i.sessionUpdate;if(o!=="tool_call"&&o!=="tool_call_update")continue;if(o==="tool_call"){let d=typeof i.toolCallId=="string"&&i.toolCallId.length>0?i.toolCallId:`__synth_${t++}`,u=e.get(d);u===void 0?(u={toolName:yi(i),paths:new Set},e.set(d,u)):u.toolName=yi(i);for(let c of wi(i.rawInput,i.locations))u.paths.add(c);continue}if(typeof i.toolCallId!="string"||i.toolCallId.length===0)continue;let a=e.get(i.toolCallId);if(a!==void 0)for(let d of wi(i.rawInput,i.locations))a.paths.add(d)}return e}function yi(n){return typeof n.name=="string"&&n.name.length>0?n.name:typeof n.title=="string"&&n.title.length>0?n.title:"(unnamed)"}function wi(n,e){let t=new Set;if(n&&typeof n=="object"&&!Array.isArray(n)){let s=n;typeof s.file_path=="string"?t.add(s.file_path):typeof s.path=="string"&&t.add(s.path);let r=s.edits;if(Array.isArray(r)){for(let i of r)if(i&&typeof i=="object"){let o=i.file_path;typeof o=="string"&&t.add(o)}}}for(let s of Dr(e))t.add(s);return t}W();var Fc=2,Zt=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??Fc}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 s=t?.targetAgentId;if(this.inflight.has(e))return;let r=this.queued[e];if(r&&r.kind==="title"){this.queued[e]={kind:"compaction",...s?{targetAgentId:s}:{}};return}this.queued[e]={kind:"compaction",...s?{targetAgentId:s}:{}},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 s=t-Date.now();if(s<=0)return;let r=[...this.inflight.values()];if(r.length===0){await new Promise(i=>{setTimeout(i,25).unref?.()});continue}await Promise.race([Promise.race(r),new Promise(i=>{setTimeout(i,s).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 s=this.queued[t];delete this.queued[t];let r=this.runOne(t,s).finally(()=>{this.inflight.delete(t),this.drain()});this.inflight.set(t,r)}}async runOne(e,t){let s=t.kind,r=t.targetAgentId;try{let i=await this.opts.store.read(e);if(!i){this.opts.logger?.info(`synopsis: session ${e} record missing; skipping`);return}let o=await this.opts.histories.load(e,{maxEntries:1/0}),a=i.summarizedThroughEntry;if(a!==void 0&&o.length===a){this.opts.logger?.info(`synopsis: skip ${e} (history unchanged at ${o.length})`);return}a!==void 0&&o.length<a&&this.opts.logger?.warn(`synopsis: watermark ahead of history (last=${a} history=${o.length}) for ${e} \u2014 re-baselining`);let d=s==="compaction"?r??this.opts.compactionAgent??i.agentId:this.opts.synopsisAgent??i.agentId,u=await this.opts.registry.getAgent(d);if(!u){this.opts.logger?.warn(`synopsis: agent ${d} not in registry for session ${e}; skipping`);return}let c=await oe(u,[],{npmRegistry:this.opts.npmRegistry}),f=this.opts.compactionAgent===void 0&&r===void 0,p=s==="compaction"?this.opts.compactionModel??(f?i.currentModel:void 0):this.opts.synopsisModel,l=I.sessionDir(e);if(await Ci.mkdir(l,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${o.length} model=${JSON.stringify(p??"(default)")} cwd=${l}`),s==="compaction"){let g=this.opts.compactionMaxIterations??3,m=0,h=a??0,y,v=0,w,S=Date.now(),A={targetAgentId:r},C=T=>this.opts.onCompactionStateChange?.(e,T,A)??Promise.resolve(),x=T=>{this.opts.broadcastHydraCompaction?.(e,T,A)};await C({status:"requested",requestedAt:S}),x({sessionUpdate:"hydra_compaction",phase:"started",requestedAt:S});try{do{m++,this.opts.logger?.info(`synopsis: compaction iteration ${m} sessionId=${e} historyLen=${o.length} watermark=${h}`);let T=await this.opts.histories.load(e,{maxEntries:1/0});if(T.length===h)break;let _=await hi({agentId:d,cwd:l,plan:c,history:T,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:(F,P)=>{C({status:"running",requestedAt:S,iter:m,worker:{upstreamSessionId:F,pid:P??0}})},onFailure:F=>{w=F}});if(_){let F=Ii(_.synopsis,T);F&&ki(F)&&(await this.opts.persistSynopsis(e,F,T.length),y=F,v=T.length,w=void 0,await C({status:"running",requestedAt:S,iter:m}),x({sessionUpdate:"hydra_compaction",phase:"iteration",iter:m,historyLen:T.length}),await this.opts.onSynthesisArtifact?.(e,F,v,r),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${m} fields=${Ai(F)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${m} returned no result`);if(h=T.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===h)break}while(m<g);if(y)m>=g&&this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} watermark=${v} iterations=${m}`);else{m>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${g} without producing artifact sessionId=${e}: ${w??"no reason captured"}`);let T=w??(m===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${m} iteration(s)`);await C({status:"failed",requestedAt:S,iter:m,lastError:T}),x({sessionUpdate:"hydra_compaction",phase:"failed",error:T})}}catch(T){let _=T instanceof Error?T.message:String(T);this.opts.logger?.warn(`synopsis: compaction threw for sessionId=${e}: ${_}`),await C({status:"failed",requestedAt:S,iter:m,lastError:_}),this.opts.broadcastHydraCompaction?.(e,{sessionUpdate:"hydra_compaction",phase:"failed",error:_},{targetAgentId:r})}}else{let g=await Xt({agentId:d,cwd:l,plan:c,history:o,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs});if(!g){this.opts.logger?.warn(`synopsis: sessionId=${e} no parseable result; not persisting`);return}let m=Ii(g.synopsis,o);m&&ki(m)?(await this.opts.persistSynopsis(e,m,o.length),g.title&&await this.opts.persistTitle(e,g.title),this.opts.logger?.info(`synopsis: persisted sessionId=${e} title=${JSON.stringify(!!g.title)} fields=${Ai(m)}`)):g.title&&(await this.opts.persistTitle(e,g.title),this.opts.logger?.info(`synopsis: persisted title only sessionId=${e}`))}}catch(i){this.opts.logger?.warn(`synopsis: sessionId=${e} failed: ${i.message}`)}}};function Ii(n,e){let t=bi(e),s=vi(e);return n?{...n,files_touched:t.length>0?t:n.files_touched,tools_used:s.length>0?s:n.tools_used}:t.length===0&&s.length===0?void 0:{files_touched:t.length>0?t:void 0,tools_used:s.length>0?s:void 0}}function ki(n){return!!(n.goal&&n.goal.trim().length>0||n.outcome&&n.outcome.trim().length>0||n.files_touched&&n.files_touched.length>0||n.tools_used&&n.tools_used.length>0||n.rejected_approaches&&n.rejected_approaches.length>0||n.open_threads&&n.open_threads.length>0)}function Ai(n){let e=[];return n.goal&&e.push("goal"),n.outcome&&e.push("outcome"),n.files_touched&&n.files_touched.length>0&&e.push(`files=${n.files_touched.length}`),n.tools_used&&n.tools_used.length>0&&e.push(`tools=${n.tools_used.length}`),n.rejected_approaches&&n.rejected_approaches.length>0&&e.push(`rejected=${n.rejected_approaches.length}`),n.open_threads&&n.open_threads.length>0&&e.push(`open=${n.open_threads.length}`),`[${e.join(",")}]`}W();import*as L from"fs/promises";import{createReadStream as Uc}from"fs";import{createGunzip as Dc,gzip as Lc,gunzip as qc}from"zlib";import{createInterface as zc}from"readline";import{promisify as Ti}from"util";function xi(n){return n==="summary"?"summary":"inline"}var hs=256,$c=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],Oc=["content","stdout","stderr"];function Ri(n,e){return e!=="summary"?n:n.map(Nc)}function Nc(n){if(n.method!=="session/update")return n;let e=n.params;if(!e||typeof e!="object"||Array.isArray(e))return n;let t=e,s=t.update;if(!s||typeof s!="object"||Array.isArray(s))return n;let r=s;if(r.sessionUpdate!=="tool_call"&&r.sessionUpdate!=="tool_call_update")return n;let i={...r};Array.isArray(r.content)&&(i.content=r.content.map(Ei));let o=r.rawOutput;if(o&&typeof o=="object"&&!Array.isArray(o)){let a=o,d={};a.error!==void 0&&(d.error=en(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let u of $c)a[u]!==void 0&&(d[u]=a[u]);for(let u of Oc)typeof a[u]=="string"&&(d[u]=en(a[u]));i.rawOutput=d}return{...n,params:{...t,update:i}}}function Hc(n){return!!n&&typeof n=="object"&&!Array.isArray(n)&&n.type==="diff"}function Ei(n){if(Hc(n)){let s=n,r={type:"diff",oldText:"",newText:""};return typeof s.path=="string"&&(r.path=s.path),r}if(!n||typeof n!="object"||Array.isArray(n))return n;let e=n,t={...e};return typeof e.text=="string"&&(t.text=en(e.text)),typeof e.content=="string"?t.content=en(e.content):e.content&&typeof e.content=="object"&&(t.content=Ei(e.content)),t}function en(n){if(typeof n=="string"&&n.length>hs){let e=n.length-hs;return`${n.slice(0,hs)}\u2026[+${e} chars omitted from summary export]`}return n}var jc=2048;function Mi(n){let e=new Set,t=s=>{if(Pi(s)){e.add(s.__hydraBlob);return}if(Array.isArray(s)){for(let r of s)t(r);return}if(s&&typeof s=="object")for(let r of Object.values(s))t(r)};for(let s of n)t(s.params);return e}function Pi(n){return!!n&&typeof n=="object"&&!Array.isArray(n)&&typeof n.__hydraBlob=="string"}function Bc(n){if(n.method!=="session/update")return!1;let e=n.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 s=t.sessionUpdate;return s==="tool_call"||s==="tool_call_update"}async function vs(n,e){if(!Bc(n))return n;let t=n.params,s=t.update,r=await ys(s,e);return{...n,params:{...t,update:r}}}async function ys(n,e){if(typeof n=="string"){if(n.length<=jc)return n;let t=await e(n);return t===null?n:{__hydraBlob:t,bytes:n.length}}if(Array.isArray(n)){let t=[];for(let s of n)t.push(await ys(s,e));return t}if(n&&typeof n=="object"){let t={};for(let[s,r]of Object.entries(n))t[s]=await ys(r,e);return t}return n}async function bs(n,e){let t=n.params;if(!t||typeof t!="object"||Array.isArray(t))return n;let s=await ws(t,e);return s===t?n:{...n,params:s}}async function ws(n,e){if(Pi(n))return await e(n.__hydraBlob)??"";if(Array.isArray(n)){let t=!1,s=[];for(let r of n){let i=await ws(r,e);i!==r&&(t=!0),s.push(i)}return t?s:n}if(n&&typeof n=="object"){let t=!1,s={};for(let[r,i]of Object.entries(n)){let o=await ws(i,e);o!==i&&(t=!0),s[r]=o}return t?s:n}return n}var Jc=Ti(Lc),Wc=Ti(qc),Qc=/^history\.jsonl\.(\d+)(\.gz)?$/,le=/^[A-Za-z0-9_-]+$/,Gc=1e3,Kc=1e7,Vc=10,tn=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??Gc,this.archiveMaxBytes=e.archiveMaxBytes??Kc,this.archiveTiers=e.archiveTiers??Vc}async append(e,t){if(le.test(e))return this.enqueue(e,async()=>{await L.mkdir(I.sessionDir(e),{recursive:!0});let s=await vs(t,i=>Dn(e,i)),r=JSON.stringify(s)+`
113
- `;await L.appendFile(I.historyFile(e),r,{encoding:"utf8",mode:384})})}async rewrite(e,t){if(le.test(e))return this.enqueue(e,async()=>{await L.mkdir(I.sessionDir(e),{recursive:!0});let s=[];for(let i of t)s.push(await vs(i,o=>Dn(e,o)));let r=s.length===0?"":s.map(i=>JSON.stringify(i)).join(`
112
+ ${hs}`;return To(n,s,xo)}function Gc(n){if(!n||typeof n!="object")return"";let e=n.update;if(!e||typeof e!="object")return"";let t=e;if(t.sessionUpdate!=="agent_message_chunk")return"";let s=t.content;return s&&typeof s.text=="string"?s.text:""}function Kc(n){let e=new Set;Ro(e,n.availableModels);let t=n.models;return t&&typeof t=="object"&&!Array.isArray(t)&&Ro(e,t.availableModels),e}function Ro(n,e){if(Array.isArray(e)){for(let t of e)if(t&&typeof t=="object"){let s=t.modelId??t.value??t.id;typeof s=="string"&&s.length>0&&n.add(s)}}}function Yc(n){let e=new Map;for(let t of No(n).values())e.set(t.toolName,(e.get(t.toolName)??0)+1);return[...e.entries()].map(([t,s])=>({name:t,count:s})).sort((t,s)=>s.count-t.count||t.name.localeCompare(s.name))}function Fo(n){return Yc(n).map(e=>e.name)}function Xc(n){let e=new Map;for(let t of No(n).values())for(let s of t.paths){let r=e.get(s);r===void 0&&(r=new Map,e.set(s,r)),r.set(t.toolName,(r.get(t.toolName)??0)+1)}return[...e.entries()].map(([t,s])=>{let r=[...s.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,s)=>s.count-t.count||t.path.localeCompare(s.path))}function Oo(n){return Xc(n).map(e=>e.path)}function No(n){let e=new Map,t=0;for(let s of n){let o=s.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++}`,u=e.get(d);u===void 0?(u={toolName:_o(o),paths:new Set},e.set(d,u)):u.toolName=_o(o);for(let c of $o(o.rawInput,o.locations))u.paths.add(c);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 $o(o.rawInput,o.locations))a.paths.add(d)}return e}function _o(n){return typeof n.name=="string"&&n.name.length>0?n.name:typeof n.title=="string"&&n.title.length>0?n.title:"(unnamed)"}function $o(n,e){let t=new Set;if(n&&typeof n=="object"&&!Array.isArray(n)){let s=n;typeof s.file_path=="string"?t.add(s.file_path):typeof s.path=="string"&&t.add(s.path);let r=s.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 s of to(e))t.add(s);return t}W();var Zc=2,on=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??Zc}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 s=t?.targetAgentId;if(this.inflight.has(e))return;let r=this.queued[e];if(r&&r.kind==="title"){this.queued[e]={kind:"compaction",...s?{targetAgentId:s}:{}};return}this.queued[e]={kind:"compaction",...s?{targetAgentId:s}:{}},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 s=t-Date.now();if(s<=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,s).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 s=this.queued[t];delete this.queued[t];let r=this.runOne(t,s).finally(()=>{this.inflight.delete(t),this.drain()});this.inflight.set(t,r)}}async runOne(e,t){let s=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=s==="compaction"?r??this.opts.compactionAgent??o.agentId:this.opts.synopsisAgent??o.agentId,u=await this.opts.registry.getAgent(d);if(!u){this.opts.logger?.warn(`synopsis: agent ${d} not in registry for session ${e}; skipping`);return}let c=await ie(u,[],{npmRegistry:this.opts.npmRegistry}),f=this.opts.compactionAgent===void 0&&r===void 0,p=s==="compaction"?this.opts.compactionModel??(f?o.currentModel:void 0):this.opts.synopsisModel,l=I.sessionDir(e);if(await Uo.mkdir(l,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(p??"(default)")} cwd=${l}`),s==="compaction"){let m=this.opts.compactionMaxIterations??3,g=0,h=a??0,y,b=0,w,v=Date.now(),A={targetAgentId:r},C=P=>this.opts.onCompactionStateChange?.(e,P,A)??Promise.resolve(),x=P=>{this.opts.broadcastHydraCompaction?.(e,P,A)};await C({status:"requested",requestedAt:v}),x({sessionUpdate:"hydra_compaction",phase:"started",requestedAt:v});try{do{g++,this.opts.logger?.info(`synopsis: compaction iteration ${g} sessionId=${e} historyLen=${i.length} watermark=${h}`);let P=await this.opts.histories.load(e,{maxEntries:1/0});if(P.length===h)break;let _=await Po({agentId:d,cwd:l,plan:c,history:P,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:($,T)=>{C({status:"running",requestedAt:v,iter:g,worker:{upstreamSessionId:$,pid:T??0}})},onFailure:$=>{w=$}});if(_){let $=Ho(_.synopsis,P);$&&jo($)&&(await this.opts.persistSynopsis(e,$,P.length),y=$,b=P.length,w=void 0,await C({status:"running",requestedAt:v,iter:g}),x({sessionUpdate:"hydra_compaction",phase:"iteration",iter:g,historyLen:P.length}),await this.opts.onSynthesisArtifact?.(e,$,b,r),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${g} fields=${Bo($)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${g} returned no result`);if(h=P.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===h)break}while(g<m);if(y)g>=m&&this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} watermark=${b} iterations=${g}`);else{g>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${m} without producing artifact sessionId=${e}: ${w??"no reason captured"}`);let P=w??(g===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${g} iteration(s)`);await C({status:"failed",requestedAt:v,iter:g,lastError:P}),x({sessionUpdate:"hydra_compaction",phase:"failed",error:P})}}catch(P){let _=P instanceof Error?P.message:String(P);this.opts.logger?.warn(`synopsis: compaction threw for sessionId=${e}: ${_}`),await C({status:"failed",requestedAt:v,iter:g,lastError:_}),this.opts.broadcastHydraCompaction?.(e,{sessionUpdate:"hydra_compaction",phase:"failed",error:_},{targetAgentId:r})}}else{let m=await rn({agentId:d,cwd:l,plan:c,history:i,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs});if(!m){this.opts.logger?.warn(`synopsis: sessionId=${e} no parseable result; not persisting`);return}let g=Ho(m.synopsis,i);g&&jo(g)?(await this.opts.persistSynopsis(e,g,i.length),m.title&&await this.opts.persistTitle(e,m.title),this.opts.logger?.info(`synopsis: persisted sessionId=${e} title=${JSON.stringify(!!m.title)} fields=${Bo(g)}`)):m.title&&(await this.opts.persistTitle(e,m.title),this.opts.logger?.info(`synopsis: persisted title only sessionId=${e}`))}}catch(o){this.opts.logger?.warn(`synopsis: sessionId=${e} failed: ${o.message}`)}}};function Ho(n,e){let t=Oo(e),s=Fo(e);return n?{...n,files_touched:t.length>0?t:n.files_touched,tools_used:s.length>0?s:n.tools_used}:t.length===0&&s.length===0?void 0:{files_touched:t.length>0?t:void 0,tools_used:s.length>0?s:void 0}}function jo(n){return!!(n.goal&&n.goal.trim().length>0||n.outcome&&n.outcome.trim().length>0||n.files_touched&&n.files_touched.length>0||n.tools_used&&n.tools_used.length>0||n.rejected_approaches&&n.rejected_approaches.length>0||n.open_threads&&n.open_threads.length>0)}function Bo(n){let e=[];return n.goal&&e.push("goal"),n.outcome&&e.push("outcome"),n.files_touched&&n.files_touched.length>0&&e.push(`files=${n.files_touched.length}`),n.tools_used&&n.tools_used.length>0&&e.push(`tools=${n.tools_used.length}`),n.rejected_approaches&&n.rejected_approaches.length>0&&e.push(`rejected=${n.rejected_approaches.length}`),n.open_threads&&n.open_threads.length>0&&e.push(`open=${n.open_threads.length}`),`[${e.join(",")}]`}W();import*as L from"fs/promises";import{createReadStream as iu}from"fs";import{createGunzip as au,gzip as du,gunzip as cu}from"zlib";import{createInterface as uu}from"readline";import{promisify as Wo}from"util";function Do(n){return n==="summary"?"summary":"inline"}var ks=256,eu=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],tu=["content","stdout","stderr"];function Lo(n,e){return e!=="summary"?n:n.map(nu)}function nu(n){if(n.method!=="session/update")return n;let e=n.params;if(!e||typeof e!="object"||Array.isArray(e))return n;let t=e,s=t.update;if(!s||typeof s!="object"||Array.isArray(s))return n;let r=s;if(r.sessionUpdate!=="tool_call"&&r.sessionUpdate!=="tool_call_update")return n;let o={...r};Array.isArray(r.content)&&(o.content=r.content.map(qo));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=an(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let u of eu)a[u]!==void 0&&(d[u]=a[u]);for(let u of tu)typeof a[u]=="string"&&(d[u]=an(a[u]));o.rawOutput=d}return{...n,params:{...t,update:o}}}function su(n){return!!n&&typeof n=="object"&&!Array.isArray(n)&&n.type==="diff"}function qo(n){if(su(n)){let s=n,r={type:"diff",oldText:"",newText:""};return typeof s.path=="string"&&(r.path=s.path),r}if(!n||typeof n!="object"||Array.isArray(n))return n;let e=n,t={...e};return typeof e.text=="string"&&(t.text=an(e.text)),typeof e.content=="string"?t.content=an(e.content):e.content&&typeof e.content=="object"&&(t.content=qo(e.content)),t}function an(n){if(typeof n=="string"&&n.length>ks){let e=n.length-ks;return`${n.slice(0,ks)}\u2026[+${e} chars omitted from summary export]`}return n}var ru=2048;function zo(n){let e=new Set,t=s=>{if(Jo(s)){e.add(s.__hydraBlob);return}if(Array.isArray(s)){for(let r of s)t(r);return}if(s&&typeof s=="object")for(let r of Object.values(s))t(r)};for(let s of n)t(s.params);return e}function Jo(n){return!!n&&typeof n=="object"&&!Array.isArray(n)&&typeof n.__hydraBlob=="string"}function ou(n){if(n.method!=="session/update")return!1;let e=n.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 s=t.sessionUpdate;return s==="tool_call"||s==="tool_call_update"}async function xs(n,e){if(!ou(n))return n;let t=n.params,s=t.update,r=await As(s,e);return{...n,params:{...t,update:r}}}async function As(n,e){if(typeof n=="string"){if(n.length<=ru)return n;let t=await e(n);return t===null?n:{__hydraBlob:t,bytes:n.length}}if(Array.isArray(n)){let t=[];for(let s of n)t.push(await As(s,e));return t}if(n&&typeof n=="object"){let t={};for(let[s,r]of Object.entries(n))t[s]=await As(r,e);return t}return n}async function Ms(n,e){let t=n.params;if(!t||typeof t!="object"||Array.isArray(t))return n;let s=await Cs(t,e);return s===t?n:{...n,params:s}}async function Cs(n,e){if(Jo(n))return await e(n.__hydraBlob)??"";if(Array.isArray(n)){let t=!1,s=[];for(let r of n){let o=await Cs(r,e);o!==r&&(t=!0),s.push(o)}return t?s:n}if(n&&typeof n=="object"){let t=!1,s={};for(let[r,o]of Object.entries(n)){let i=await Cs(o,e);i!==o&&(t=!0),s[r]=i}return t?s:n}return n}var lu=Wo(du),fu=Wo(cu),pu=/^history\.jsonl\.(\d+)(\.gz)?$/,fe=/^[A-Za-z0-9_-]+$/,mu=1e3,gu=1e7,hu=10,dn=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??mu,this.archiveMaxBytes=e.archiveMaxBytes??gu,this.archiveTiers=e.archiveTiers??hu}async append(e,t){if(fe.test(e))return this.enqueue(e,async()=>{await L.mkdir(I.sessionDir(e),{recursive:!0});let s=await xs(t,o=>Wn(e,o)),r=JSON.stringify(s)+`
113
+ `;await L.appendFile(I.historyFile(e),r,{encoding:"utf8",mode:384})})}async rewrite(e,t){if(fe.test(e))return this.enqueue(e,async()=>{await L.mkdir(I.sessionDir(e),{recursive:!0});let s=[];for(let o of t)s.push(await xs(o,i=>Wn(e,i)));let r=s.length===0?"":s.map(o=>JSON.stringify(o)).join(`
114
114
  `)+`
115
- `;await L.writeFile(I.historyFile(e),r,{encoding:"utf8",mode:384})})}async compact(e,t){if(le.test(e))return this.enqueue(e,async()=>{let s;try{s=await L.readFile(I.historyFile(e),"utf8")}catch(a){if(a.code==="ENOENT")return;throw a}let r=s.split(`
116
- `).filter(a=>a.length>0);if(r.length<=t)return;let i=r.slice(0,r.length-t),o=r.slice(-t);this.archiveMaxBytes>0&&i.length>0&&await this.spillToArchive(e,i),await L.writeFile(I.historyFile(e),o.join(`
115
+ `;await L.writeFile(I.historyFile(e),r,{encoding:"utf8",mode:384})})}async compact(e,t){if(fe.test(e))return this.enqueue(e,async()=>{let s;try{s=await L.readFile(I.historyFile(e),"utf8")}catch(a){if(a.code==="ENOENT")return;throw a}let r=s.split(`
116
+ `).filter(a=>a.length>0);if(r.length<=t)return;let o=r.slice(0,r.length-t),i=r.slice(-t);this.archiveMaxBytes>0&&o.length>0&&await this.spillToArchive(e,o),await L.writeFile(I.historyFile(e),i.join(`
117
117
  `)+`
118
118
  `,{encoding:"utf8",mode:384})})}async spillToArchive(e,t){let s=t.join(`
119
119
  `)+`
120
- `,r=await this.resolveNextArchiveIndex(e);await this.enforceArchiveTierCap(e,r);let i=I.historyArchiveFile(e,r);await L.mkdir(I.sessionDir(e),{recursive:!0}),await L.appendFile(i,s,{encoding:"utf8",mode:384});let o=0;try{o=(await L.stat(i)).size}catch{o=0}o>=this.archiveMaxBytes?(await this.sealArchive(e,r),this.nextArchiveIndex.set(e,r+1)):this.nextArchiveIndex.set(e,r),this.archiveLineCounts.delete(e)}async sealArchive(e,t){let s=I.historyArchiveFile(e,t),r;try{r=await L.readFile(s)}catch(o){if(o.code==="ENOENT")return;throw o}let i=await Jc(r);await L.writeFile(s+".gz",i,{mode:384});try{await L.unlink(s)}catch(o){if(o.code!=="ENOENT")throw o}}async resolveNextArchiveIndex(e){let t=this.nextArchiveIndex.get(e);if(t!==void 0)return t;let s=await this.listArchiveIndices(e),r=s.length===0?0:s[s.length-1],i=r===0?1:r;if(r>0){let o=I.historyArchiveFile(e,r),a=o+".gz",d=!1;try{await L.access(a),d=!0}catch{d=!1}if(d)i=r+1;else try{(await L.stat(o)).size>=this.archiveMaxBytes&&(i=r+1)}catch{i=r}}return this.nextArchiveIndex.set(e,i),i}async enforceArchiveTierCap(e,t){if(this.archiveTiers<=0)return;let s=await this.listArchiveIndices(e),i=(s.includes(t)?s.length:s.length+1)-this.archiveTiers,o=0;for(;i>0&&o<s.length;){let a=s[o];a!==t&&(await this.unlinkArchive(e,a),i-=1),o+=1}}async unlinkArchive(e,t){let s=I.historyArchiveFile(e,t);for(let r of[s,s+".gz"])try{await L.unlink(r)}catch(i){if(i.code!=="ENOENT")throw i}this.archiveLineCounts.delete(e)}async listArchiveIndices(e){let t;try{t=await L.readdir(I.sessionDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let s=new Set;for(let r of t){let i=Qc.exec(r);if(!i)continue;let o=Number.parseInt(i[1],10);Number.isFinite(o)&&o>0&&s.add(o)}return[...s].sort((r,i)=>r-i)}async listArchives(e){if(!le.test(e))return[];let t=await this.listArchiveIndices(e),s=[];for(let r of t){let i=I.historyArchiveFile(e,r),o=i+".gz",a=i;try{await L.access(o),a=o}catch{a=i}s.push({index:r,path:a})}return s}async loadArchives(e){if(!le.test(e))return[];let t=this.writeQueues.get(e);t&&await t;let s=await this.listArchives(e),r=[];for(let{path:i}of s){let o;try{if(i.endsWith(".gz")){let a=await L.readFile(i);o=(await Wc(a)).toString("utf8")}else o=await L.readFile(i,"utf8")}catch(a){if(a.code==="ENOENT")continue;throw a}for(let a of o.split(`
121
- `)){if(a.length===0)continue;let d;try{d=JSON.parse(a)}catch{continue}if(!d||typeof d!="object"||Array.isArray(d))continue;let u=d;typeof u.method=="string"&&typeof u.recordedAt=="number"&&r.push({method:u.method,params:u.params,recordedAt:u.recordedAt})}}return r}async*streamFile(e){let t;try{t=Uc(e)}catch(o){if(o.code==="ENOENT")return;throw o}if(await new Promise(o=>{let a=!1,d=u=>{a||(a=!0,o(u))};t.once("error",u=>{u.code==="ENOENT"?d(!0):(t.destroy(),d(!1))}),t.once("readable",()=>d(!1)),t.once("end",()=>d(!1))}))return;let r=e.endsWith(".gz")?t.pipe(Dc()):t,i=zc({input:r,crlfDelay:1/0});try{for await(let o of i){if(o.length===0)continue;let a;try{a=JSON.parse(o)}catch{continue}if(!a||typeof a!="object"||Array.isArray(a))continue;let d=a;typeof d.method=="string"&&typeof d.recordedAt=="number"&&(yield{method:d.method,params:d.params,recordedAt:d.recordedAt})}}finally{i.close(),t.destroy()}}async getArchiveLineCounts(e){if(!le.test(e))return[];let t=this.archiveLineCounts.get(e),s=await this.listArchives(e);if(t&&t.length===s.length&&t.every((i,o)=>i.index===s[o].index&&i.path===s[o].path))return t;let r=[];for(let{index:i,path:o}of s){let a=t?.find(u=>u.index===i&&u.path===o);if(a){r.push(a);continue}let d=0;for await(let u of this.streamFile(o))d+=1;r.push({index:i,path:o,lineCount:d})}return this.archiveLineCounts.set(e,r),r}async hydrateEntry(e,t,s){return bs(t,async r=>{let i=s.get(r);if(i!==void 0)return i;let o=await ft(e,r);return s.set(r,o),o})}async*iterRecallNewestFirst(e){if(!le.test(e))return;let t=this.writeQueues.get(e);t&&await t;let s=await this.getArchiveLineCounts(e),r=0;for(let u of s)r+=u.lineCount;let i=new Map,o=[];for await(let u of this.streamFile(I.historyFile(e)))o.push(u);for(let u=o.length-1;u>=0;u--){let c=await this.hydrateEntry(e,o[u],i);yield{entryId:r+u,entry:c}}let a=new Array(s.length),d=0;for(let u=0;u<s.length;u++)a[u]=d,d+=s[u].lineCount;for(let u=s.length-1;u>=0;u--){let c=s[u],f=[];for await(let l of this.streamFile(c.path))f.push(l);let p=a[u];for(let l=f.length-1;l>=0;l--){let g=await this.hydrateEntry(e,f[l],i);yield{entryId:p+l,entry:g}}}}async rangeSlice(e,t,s){if(!le.test(e))return[];if(s<t)return[];let r=this.writeQueues.get(e);r&&await r;let i=await this.getArchiveLineCounts(e),o=0;for(let c of i)o+=c.lineCount;let a=[],d=new Map,u=0;for(let c of i){let f=u,p=u+c.lineCount;if(u=p,p<=t)continue;if(f>s)break;let l=0;for await(let g of this.streamFile(c.path)){let m=f+l;if(l+=1,m<t)continue;if(m>s)break;let h=await this.hydrateEntry(e,g,d);a.push({entryId:m,entry:h})}}if(s>=o){let c=Math.max(t-o,0),f=s-o,p=0;for await(let l of this.streamFile(I.historyFile(e))){if(p>f)break;if(p>=c){let g=await this.hydrateEntry(e,l,d);a.push({entryId:o+p,entry:g})}p+=1}}return a}async getRecallTotalCount(e){if(!le.test(e))return 0;let t=await this.getArchiveLineCounts(e),s=0;for(let i of t)s+=i.lineCount;let r=0;for await(let i of this.streamFile(I.historyFile(e)))r+=1;return s+r}async load(e,t={}){if(!le.test(e))return[];let s=(t.tools??"inline")==="inline",r=this.writeQueues.get(e);r&&await r;let i;try{i=await L.readFile(I.historyFile(e),"utf8")}catch(p){if(p.code==="ENOENT")return[];throw p}let o=[];for(let p of i.split(`
122
- `)){if(p.length===0)continue;let l;try{l=JSON.parse(p)}catch{continue}if(!l||typeof l!="object"||Array.isArray(l))continue;let g=l;typeof g.method=="string"&&typeof g.recordedAt=="number"&&o.push({method:g.method,params:g.params,recordedAt:g.recordedAt})}let a=t.maxEntries??this.maxEntries,d=o.length>a?o.slice(-a):o;if(!s)return d;let u=new Map,c=async p=>{let l=u.get(p);if(l!==void 0)return l;let g=await ft(e,p);return u.set(p,g),g},f=[];for(let p of d)f.push(await bs(p,c));return f}async flushAll(){let e=[...this.writeQueues.values()];e.length!==0&&await Promise.allSettled(e)}async delete(e){if(le.test(e))return this.enqueue(e,async()=>{try{await L.unlink(I.historyFile(e))}catch(s){if(s.code!=="ENOENT")throw s}let t=await this.listArchiveIndices(e);for(let s of t)await this.unlinkArchive(e,s);this.nextArchiveIndex.delete(e),this.archiveLineCounts.delete(e),await fr(e);try{await L.rmdir(I.sessionDir(e))}catch(s){let r=s;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw s}})}enqueue(e,t){let r=(this.writeQueues.get(e)??Promise.resolve()).then(t,t),i=r.catch(()=>{});return this.writeQueues.set(e,i),i.finally(()=>{this.writeQueues.get(e)===i&&this.writeQueues.delete(e)}),r}};W();import{promises as _i}from"fs";import*as Fi from"path";async function $i(n,e){await _i.mkdir(Fi.dirname(n),{recursive:!0});let t=e.map(s=>JSON.stringify(s));await _i.writeFile(n,t.length>0?t.join(`
120
+ `,r=await this.resolveNextArchiveIndex(e);await this.enforceArchiveTierCap(e,r);let o=I.historyArchiveFile(e,r);await L.mkdir(I.sessionDir(e),{recursive:!0}),await L.appendFile(o,s,{encoding:"utf8",mode:384});let i=0;try{i=(await L.stat(o)).size}catch{i=0}i>=this.archiveMaxBytes?(await this.sealArchive(e,r),this.nextArchiveIndex.set(e,r+1)):this.nextArchiveIndex.set(e,r),this.archiveLineCounts.delete(e)}async sealArchive(e,t){let s=I.historyArchiveFile(e,t),r;try{r=await L.readFile(s)}catch(i){if(i.code==="ENOENT")return;throw i}let o=await lu(r);await L.writeFile(s+".gz",o,{mode:384});try{await L.unlink(s)}catch(i){if(i.code!=="ENOENT")throw i}}async resolveNextArchiveIndex(e){let t=this.nextArchiveIndex.get(e);if(t!==void 0)return t;let s=await this.listArchiveIndices(e),r=s.length===0?0:s[s.length-1],o=r===0?1:r;if(r>0){let i=I.historyArchiveFile(e,r),a=i+".gz",d=!1;try{await L.access(a),d=!0}catch{d=!1}if(d)o=r+1;else try{(await L.stat(i)).size>=this.archiveMaxBytes&&(o=r+1)}catch{o=r}}return this.nextArchiveIndex.set(e,o),o}async enforceArchiveTierCap(e,t){if(this.archiveTiers<=0)return;let s=await this.listArchiveIndices(e),o=(s.includes(t)?s.length:s.length+1)-this.archiveTiers,i=0;for(;o>0&&i<s.length;){let a=s[i];a!==t&&(await this.unlinkArchive(e,a),o-=1),i+=1}}async unlinkArchive(e,t){let s=I.historyArchiveFile(e,t);for(let r of[s,s+".gz"])try{await L.unlink(r)}catch(o){if(o.code!=="ENOENT")throw o}this.archiveLineCounts.delete(e)}async listArchiveIndices(e){let t;try{t=await L.readdir(I.sessionDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let s=new Set;for(let r of t){let o=pu.exec(r);if(!o)continue;let i=Number.parseInt(o[1],10);Number.isFinite(i)&&i>0&&s.add(i)}return[...s].sort((r,o)=>r-o)}async listArchives(e){if(!fe.test(e))return[];let t=await this.listArchiveIndices(e),s=[];for(let r of t){let o=I.historyArchiveFile(e,r),i=o+".gz",a=o;try{await L.access(i),a=i}catch{a=o}s.push({index:r,path:a})}return s}async loadArchives(e){if(!fe.test(e))return[];let t=this.writeQueues.get(e);t&&await t;let s=await this.listArchives(e),r=[];for(let{path:o}of s){let i;try{if(o.endsWith(".gz")){let a=await L.readFile(o);i=(await fu(a)).toString("utf8")}else i=await L.readFile(o,"utf8")}catch(a){if(a.code==="ENOENT")continue;throw a}for(let a of i.split(`
121
+ `)){if(a.length===0)continue;let d;try{d=JSON.parse(a)}catch{continue}if(!d||typeof d!="object"||Array.isArray(d))continue;let u=d;typeof u.method=="string"&&typeof u.recordedAt=="number"&&r.push({method:u.method,params:u.params,recordedAt:u.recordedAt})}}return r}async*streamFile(e){let t;try{t=iu(e)}catch(i){if(i.code==="ENOENT")return;throw i}if(await new Promise(i=>{let a=!1,d=u=>{a||(a=!0,i(u))};t.once("error",u=>{u.code==="ENOENT"?d(!0):(t.destroy(),d(!1))}),t.once("readable",()=>d(!1)),t.once("end",()=>d(!1))}))return;let r=e.endsWith(".gz")?t.pipe(au()):t,o=uu({input:r,crlfDelay:1/0});try{for await(let i of o){if(i.length===0)continue;let a;try{a=JSON.parse(i)}catch{continue}if(!a||typeof a!="object"||Array.isArray(a))continue;let d=a;typeof d.method=="string"&&typeof d.recordedAt=="number"&&(yield{method:d.method,params:d.params,recordedAt:d.recordedAt})}}finally{o.close(),t.destroy()}}async getArchiveLineCounts(e){if(!fe.test(e))return[];let t=this.archiveLineCounts.get(e),s=await this.listArchives(e);if(t&&t.length===s.length&&t.every((o,i)=>o.index===s[i].index&&o.path===s[i].path))return t;let r=[];for(let{index:o,path:i}of s){let a=t?.find(u=>u.index===o&&u.path===i);if(a){r.push(a);continue}let d=0;for await(let u of this.streamFile(i))d+=1;r.push({index:o,path:i,lineCount:d})}return this.archiveLineCounts.set(e,r),r}async hydrateEntry(e,t,s){return Ms(t,async r=>{let o=s.get(r);if(o!==void 0)return o;let i=await gt(e,r);return s.set(r,i),i})}async*iterRecallNewestFirst(e){if(!fe.test(e))return;let t=this.writeQueues.get(e);t&&await t;let s=await this.getArchiveLineCounts(e),r=0;for(let u of s)r+=u.lineCount;let o=new Map,i=[];for await(let u of this.streamFile(I.historyFile(e)))i.push(u);for(let u=i.length-1;u>=0;u--){let c=await this.hydrateEntry(e,i[u],o);yield{entryId:r+u,entry:c}}let a=new Array(s.length),d=0;for(let u=0;u<s.length;u++)a[u]=d,d+=s[u].lineCount;for(let u=s.length-1;u>=0;u--){let c=s[u],f=[];for await(let l of this.streamFile(c.path))f.push(l);let p=a[u];for(let l=f.length-1;l>=0;l--){let m=await this.hydrateEntry(e,f[l],o);yield{entryId:p+l,entry:m}}}}async rangeSlice(e,t,s){if(!fe.test(e))return[];if(s<t)return[];let r=this.writeQueues.get(e);r&&await r;let o=await this.getArchiveLineCounts(e),i=0;for(let c of o)i+=c.lineCount;let a=[],d=new Map,u=0;for(let c of o){let f=u,p=u+c.lineCount;if(u=p,p<=t)continue;if(f>s)break;let l=0;for await(let m of this.streamFile(c.path)){let g=f+l;if(l+=1,g<t)continue;if(g>s)break;let h=await this.hydrateEntry(e,m,d);a.push({entryId:g,entry:h})}}if(s>=i){let c=Math.max(t-i,0),f=s-i,p=0;for await(let l of this.streamFile(I.historyFile(e))){if(p>f)break;if(p>=c){let m=await this.hydrateEntry(e,l,d);a.push({entryId:i+p,entry:m})}p+=1}}return a}async getRecallTotalCount(e){if(!fe.test(e))return 0;let t=await this.getArchiveLineCounts(e),s=0;for(let o of t)s+=o.lineCount;let r=0;for await(let o of this.streamFile(I.historyFile(e)))r+=1;return s+r}async load(e,t={}){if(!fe.test(e))return[];let s=(t.tools??"inline")==="inline",r=this.writeQueues.get(e);r&&await r;let o;try{o=await L.readFile(I.historyFile(e),"utf8")}catch(p){if(p.code==="ENOENT")return[];throw p}let i=[];for(let p of o.split(`
122
+ `)){if(p.length===0)continue;let l;try{l=JSON.parse(p)}catch{continue}if(!l||typeof l!="object"||Array.isArray(l))continue;let m=l;typeof m.method=="string"&&typeof m.recordedAt=="number"&&i.push({method:m.method,params:m.params,recordedAt:m.recordedAt})}let a=t.maxEntries??this.maxEntries,d=i.length>a?i.slice(-a):i;if(!s)return d;let u=new Map,c=async p=>{let l=u.get(p);if(l!==void 0)return l;let m=await gt(e,p);return u.set(p,m),m},f=[];for(let p of d)f.push(await Ms(p,c));return f}async flushAll(){let e=[...this.writeQueues.values()];e.length!==0&&await Promise.allSettled(e)}async delete(e){if(fe.test(e))return this.enqueue(e,async()=>{try{await L.unlink(I.historyFile(e))}catch(s){if(s.code!=="ENOENT")throw s}let t=await this.listArchiveIndices(e);for(let s of t)await this.unlinkArchive(e,s);this.nextArchiveIndex.delete(e),this.archiveLineCounts.delete(e),await Sr(e);try{await L.rmdir(I.sessionDir(e))}catch(s){let r=s;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw s}})}enqueue(e,t){let r=(this.writeQueues.get(e)??Promise.resolve()).then(t,t),o=r.catch(()=>{});return this.writeQueues.set(e,o),o.finally(()=>{this.writeQueues.get(e)===o&&this.writeQueues.delete(e)}),r}};W();import{promises as Vo}from"fs";import*as Qo from"path";async function Go(n,e){await Vo.mkdir(Qo.dirname(n),{recursive:!0});let t=e.map(s=>JSON.stringify(s));await Vo.writeFile(n,t.length>0?t.join(`
123
123
  `)+`
124
- `:"")}import{z as D}from"zod";var Yc=D.object({method:D.string(),params:D.unknown(),recordedAt:D.number()}),Xc=D.object({sessionId:D.string(),lineageId:D.string(),upstreamSessionId:D.string().optional(),agentId:D.string(),cwd:D.string(),title:D.string().optional(),synopsis:vt.optional(),summarizedThroughEntry:D.number().int().nonnegative().optional(),currentModel:D.string().optional(),currentMode:D.string().optional(),currentUsage:ps.optional(),agentCommands:D.array(ls).optional(),agentModes:D.array(fs).optional(),interactive:D.boolean().optional(),originatingClient:ms.optional(),priority:D.number().int().nonnegative().optional(),createdAt:D.string(),updatedAt:D.string()}),Zc=D.object({version:D.literal(1),exportedAt:D.string(),exportedFrom:D.object({hydraVersion:D.string(),machine:D.string(),hydraHost:D.string().optional()}),session:Xc,history:D.array(Yc),promptHistory:D.array(D.string()).optional(),toolBlobs:D.record(D.string()).optional()});function It(n){let e={version:1,exportedAt:new Date().toISOString(),exportedFrom:{hydraVersion:n.hydraVersion,machine:n.machine,...n.hydraHost!==void 0&&n.hydraHost.length>0?{hydraHost:n.hydraHost}:{}},session:{sessionId:n.record.sessionId,lineageId:n.record.lineageId,...n.record.upstreamSessionId?{upstreamSessionId:n.record.upstreamSessionId}:{},agentId:n.record.agentId,cwd:n.record.cwd,...n.record.title!==void 0?{title:n.record.title}:{},...n.record.synopsis!==void 0?{synopsis:n.record.synopsis}:{},...n.record.summarizedThroughEntry!==void 0?{summarizedThroughEntry:n.record.summarizedThroughEntry}:{},...n.record.currentModel!==void 0?{currentModel:n.record.currentModel}:{},...n.record.currentMode!==void 0?{currentMode:n.record.currentMode}:{},...n.record.currentUsage!==void 0?{currentUsage:n.record.currentUsage}:{},...n.record.agentCommands!==void 0?{agentCommands:n.record.agentCommands}:{},...n.record.agentModes!==void 0?{agentModes:n.record.agentModes}:{},...n.record.interactive!==void 0?{interactive:n.record.interactive}:{},...n.record.originatingClient!==void 0?{originatingClient:n.record.originatingClient}:{},...n.record.priority!==void 0&&n.record.priority>0?{priority:n.record.priority}:{},createdAt:n.record.createdAt,updatedAt:n.record.updatedAt},history:n.history};return n.promptHistory!==void 0&&(e.promptHistory=n.promptHistory),n.toolBlobs!==void 0&&Object.keys(n.toolBlobs).length>0&&(e.toolBlobs=n.toolBlobs),e}function Oi(n){return Zc.parse(n)}function Ss(n){if(n&&!(n.costAmount===void 0&&n.cumulativeCost===void 0))return(n.cumulativeCost??0)+(n.costAmount??0)}function kt(n){if(!n)return;let e={};n.used!==void 0&&(e.used=n.used),n.size!==void 0&&(e.size=n.size);let t=Ss(n);return t&&(e.costAmount=t),n.costCurrency!==void 0&&(e.costCurrency=n.costCurrency),e}var Ni=900*1e3,tu="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",nn=eu(tu,16),sn=class n{constructor(e,t,s,r={}){this.registry=e;this.spawner=t??(a=>Re.spawn(a)),this.store=s??new Gt,this.tombstones=r.tombstones??new Kt,this.sessionHistoryMaxEntries=r.sessionHistoryMaxEntries??1e3,this.histories=new tn({maxEntries:this.sessionHistoryMaxEntries,archiveMaxBytes:r.sessionHistoryArchiveMaxBytes,archiveTiers:r.sessionHistoryArchiveTiers}),this.idleTimeoutMs=r.idleTimeoutMs??0,this.idleEventTimeoutMs=r.idleEventTimeoutMs??3e4,this.defaultModels=r.defaultModels??{},this.synopsisAgent=r.synopsisAgent,this.synopsisModel=r.synopsisModel,this.compactionAgent=r.compactionAgent,this.compactionModel=r.compactionModel,this.defaultTransformers=r.defaultTransformers??[],this.logger=r.logger,this.npmRegistry=r.npmRegistry,this.extensionCommands=r.extensionCommands,this.defaultCwd=r.defaultCwd??"~";let i=r.compaction??{},o=i.tailK??20;this.compactionTailK=o,this.synopsisCoordinator=new Zt({registry:this.registry,store:this.store,histories:this.histories,synopsisAgent:this.synopsisAgent,synopsisModel:this.synopsisModel,compactionAgent:this.compactionAgent,compactionModel:this.compactionModel,compactionMaxIterations:i.maxIterations,persistTitle:async(a,d)=>{let u=this.get(a);if(u){await u.retitle(d);return}await this.persistTitle(a,d)},persistSynopsis:(a,d,u)=>this.persistSynopsis(a,d,u),logger:this.logger,npmRegistry:this.npmRegistry,onCompactionStateChange:async(a,d,u)=>{if(u.targetAgentId)return;let c=this.get(a);c&&(c.compactionState=d),await this.mutateRecord(a,{compactionState:d})},broadcastHydraCompaction:(a,d,u)=>{this.emitSwapPhase(a,u.targetAgentId,d)},onSynthesisArtifact:async(a,d,u,c)=>{await this.dispatchSynthesisSwap(a,d,u,c)}}),this.refreshAgentCatalog()}registry;sessions=new Map;resurrectionInflight=new Map;pendingAuthAgents=new Map;spawner;store;tombstones;histories;idleTimeoutMs;defaultModels;synopsisAgent;synopsisModel;compactionAgent;compactionModel;defaultTransformers;idleEventTimeoutMs;sessionHistoryMaxEntries;metaWriteQueues=new Map;listCache=new Map;static LIST_CACHE_TTL_MS=500;logger;npmRegistry;extensionCommands;defaultCwd;synopsisCoordinator;pendingDeletions=new Map;pendingSwapDisposers=new Map;rollbackLocks=new Set;compactionTailK=20;agentCatalog=[];async dispatchSynthesisSwap(e,t,s,r){let i=this.get(e);if(!i){this.logger?.info(`compaction: persisted artifact for cold session sessionId=${e}`),await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:s});return}let o=this.compactionTailK;try{if(await i.isQuiescedForSwap()){this.pendingSwapDisposers.get(e)?.(),this.pendingSwapDisposers.delete(e),await this.performSynthesisSwap(i,t,o,s,r);return}this.pendingSwapDisposers.get(e)?.(),this.logger?.info(`compaction: session not quiesced, parking onceIdle swap sessionId=${e}`),this.emitSwapPhase(e,r,{phase:"deferred"});let d=i.onceIdle(()=>{this.pendingSwapDisposers.delete(e),this.onIdleAttemptSwap(e)});this.pendingSwapDisposers.set(e,d)}catch(a){this.logger?.warn(`compaction: dispatch failed for sessionId=${e}: ${a instanceof Error?a.message:String(a)}, leaving session as-is`)}}async onIdleAttemptSwap(e){let t=this.get(e);if(!t)return;let s=this.compactionTailK;try{if(!await t.isQuiescedForSwap()){let d=await this.store.read(e).catch(()=>{});d?.synopsis&&d.summarizedThroughEntry!==void 0&&this.dispatchSynthesisSwap(e,d.synopsis,d.summarizedThroughEntry,d.pendingAgentSwap);return}let i=await this.store.read(e).catch(()=>{});if(!i?.synopsis||i.summarizedThroughEntry===void 0){this.logger?.warn(`compaction: persisted artifact missing for sessionId=${e}, abandoning swap`),t.compactionState=void 0,await this.mutateRecord(e,{},["compactionState"]);return}let o=i.pendingAgentSwap,a=await this.histories.load(e).catch(()=>[]);if(a.length>i.summarizedThroughEntry){this.logger?.info(`compaction: history grew during deferral (have=${a.length} artifact=${i.summarizedThroughEntry}), rescheduling synopsis sessionId=${e}`),o?this.synopsisCoordinator.scheduleCompaction(e,{targetAgentId:o}):this.synopsisCoordinator.scheduleCompaction(e);return}await this.performSynthesisSwap(t,i.synopsis,s,i.summarizedThroughEntry,o)}catch(r){this.logger?.warn(`compaction: onIdleAttemptSwap failed for sessionId=${e}: ${r instanceof Error?r.message:String(r)}`)}}async performSynthesisSwap(e,t,s,r,i){try{let o=i?Math.min(5,s):0;await e.swapUpstream({artifact:t,tailK:s,tailFloor:o,summarizedThroughEntry:r,...i?{newAgentId:i}:{}}),i?await this.mutateRecord(e.sessionId,{},["pendingAgentSwap"]):(e.compactionState=void 0,await this.mutateRecord(e.sessionId,{},["compactionState"]))}catch(o){this.logger?.warn(`compaction: swap failed for sessionId=${e.sessionId}: ${o instanceof Error?o.message:String(o)}, leaving session as-is`)}}async refreshAgentCatalog(){try{let{agents:e}=await qe(this.registry);this.agentCatalog=e.map(t=>({id:t.id,name:t.name,...t.description!==void 0?{description:t.description}:{}}))}catch{}}async create(e){let t=await this.registry.getAgent(e.agentId);t&&t.id!==e.agentId&&(e={...e,agentId:t.id});let s=await this.bootstrapAgent({agentId:e.agentId,cwd:e.cwd,agentArgs:e.agentArgs,mcpServers:e.mcpServers,model:e.model,onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv});if(e.transformChain&&e.transformChain.length>0){let i={...s.agentCapabilities??{}};for(let o of e.transformChain)if(o.intercepts.has("agent:initialize"))try{let a=await o.connection.request("hydra-acp/transformer/message",{token:`t_${nn()}`,phase:"response",method:"initialize",direction:"agent\u2192daemon",sessionId:"(pre-session)",envelope:i});a.action==="stop"&&a.payload&&(i=a.payload)}catch{}s.agentCapabilities=i}let r=new et({cwd:e.cwd,agentId:e.agentId,agent:s.agent,upstreamSessionId:s.upstreamSessionId,agentMeta:s.agentMeta,agentCapabilities:s.agentCapabilities,title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,idleEventTimeoutMs:this.idleEventTimeoutMs,logger:this.logger,spawnReplacementAgent:i=>this.bootstrapAgent({...i,mcpServers:i.mcpServers??[]}),loadExistingAgentSession:(i,o)=>this.bootstrapAgentLoad(i,{...o,mcpServers:o.mcpServers??[]}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:s.initialModel,currentMode:s.initialMode,agentModes:s.initialModes,agentModels:s.initialModels,transformChain:e.transformChain,parentSessionId:e.parentSessionId,originatingClient:e.originatingClient,interactive:e.interactive,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(r.sessionId),scheduleCompaction:i=>this.scheduleCompaction(r.sessionId,i),resolveAgentId:async i=>(await this.registry.getAgent(i))?.id,getCompactionState:()=>this.getCompactionState(r.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(r.sessionId),uncompactHook:()=>this.performUncompact(r.sessionId),forkHook:i=>this.forkSession(r.sessionId,i??{}),onCompactionSwapHook:i=>{this.mutateRecord(r.sessionId,{rollbackBreadcrumb:i}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(r.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(r),r}async resurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t){if(t.upstreamSessionId!==e.upstreamSessionId){let i=new Error(`session ${e.hydraSessionId} already exists with a different upstream id`);throw i.code=k.AlreadyAttached,i}return t}let s=this.resurrectionInflight.get(e.hydraSessionId);if(s)return s;let r=this.doResurrect(e);this.resurrectionInflight.set(e.hydraSessionId,r);try{return await r}finally{this.resurrectionInflight.delete(e.hydraSessionId)}}async doResurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t)return t;let s=await this.registry.getAgent(e.agentId);if(!s){let m=new Error(`agent ${e.agentId} not found in registry; cannot resurrect`);throw m.code=k.AgentNotInstalled,m}if(e.upstreamSessionId==="")return this.doResurrectFromImport(e);if(!await this.dirExists(e.cwd))return this.doResurrectFromImport(e);let r=await oe(s,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...e.forwardedEnv?{extraEnv:e.forwardedEnv}:{}}),o;try{let m=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:ze,clientInfo:{name:"hydra",version:Y}});o=m.agentCapabilities,i.authMethods=At(m.authMethods)}catch(m){throw await i.kill().catch(()=>{}),Me(m,i)}let a;try{let m=Hi(e.agentId,e.currentModel);a=await i.connection.request("session/load",{sessionId:e.upstreamSessionId,cwd:e.cwd,mcpServers:e.mcpServers??[],...m&&{_meta:m}})}catch(m){if(m&&typeof m=="object"&&m.code===k.AuthRequired)throw await i.kill().catch(()=>{}),Me(m,i);return process.stderr.write(`session/load failed for upstream ${e.upstreamSessionId} on ${e.agentId} (${m.message}); recovering via import-reseed
125
- `),await i.kill().catch(()=>{}),this.doResurrectFromImport(e)}if(e.pendingHistorySync===!0)this.clearPendingHistorySync(e.hydraSessionId).catch(()=>{});else{let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain1 dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let d=xs(a??{}),u=e.agentModes??ks(Cs(a??{}));this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedMode=${JSON.stringify(e.currentMode)} agentReportedMode=${JSON.stringify(d)} advertisedModes=${JSON.stringify(u?.map(m=>m.id))}`);let c=await We({agent:i,upstreamSessionId:e.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:d,advertisedModes:u,logger:this.logger});this.logger?.info(`resurrect: effectiveMode=${JSON.stringify(c)} for sessionId=${e.hydraSessionId}`);let f=Is(a??{}),p=ks(As(a??{}))??e.agentModels;if(this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedModel=${JSON.stringify(e.currentModel)} agentReportedModel=${JSON.stringify(f)} advertisedModels=${JSON.stringify(p?.map(m=>m.modelId))}`),e.pendingHistorySync!==!0){let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain2 (post-mode-restore) dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let l=await Qe({agent:i,upstreamSessionId:e.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:f,logger:this.logger});if(e.pendingHistorySync!==!0){let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain3 (post-model-restore) dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let g=new et({sessionId:e.hydraSessionId,cwd:e.cwd,agentId:e.agentId,agent:i,upstreamSessionId:e.upstreamSessionId,agentMeta:a?._meta,agentCapabilities:o,title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,logger:this.logger,spawnReplacementAgent:m=>this.bootstrapAgent({...m,mcpServers:m.mcpServers??e.mcpServers??[]}),loadExistingAgentSession:(m,h)=>this.bootstrapAgentLoad(m,{...h,mcpServers:h.mcpServers??e.mcpServers??[]}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:l,currentMode:c,currentUsage:e.currentUsage,reloadsUpstreamLedger:!0,agentCommands:e.agentCommands,agentModes:u,agentModels:p,summarizedThroughEntry:e.summarizedThroughEntry,compactionState:e.compactionState,firstPromptSeeded:!!e.title,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(g.sessionId),scheduleCompaction:m=>this.scheduleCompaction(g.sessionId,m),resolveAgentId:async m=>(await this.registry.getAgent(m))?.id,getCompactionState:()=>this.getCompactionState(g.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(g.sessionId),uncompactHook:()=>this.performUncompact(g.sessionId),forkHook:m=>this.forkSession(g.sessionId,m??{}),onCompactionSwapHook:m=>{this.mutateRecord(g.sessionId,{rollbackBreadcrumb:m}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(g.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(g),g}async doResurrectFromImport(e){let t=await this.resolveResurrectCwd(e.cwd),s=await this.bootstrapAgent({agentId:e.agentId,cwd:t,agentArgs:e.agentArgs,mcpServers:e.mcpServers??[],onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,model:e.currentModel}),r=e.agentModes??s.initialModes,i=await We({agent:s.agent,upstreamSessionId:s.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:s.initialMode,advertisedModes:r,logger:this.logger}),o=e.agentModels??s.initialModels,a=await Qe({agent:s.agent,upstreamSessionId:s.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:s.initialModel,logger:this.logger});s.agent.connection.drainBuffered("session/update");let d=new et({sessionId:e.hydraSessionId,cwd:t,agentId:e.agentId,agent:s.agent,upstreamSessionId:s.upstreamSessionId,agentMeta:s.agentMeta,agentCapabilities:s.agentCapabilities,title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,logger:this.logger,spawnReplacementAgent:u=>this.bootstrapAgent({...u,mcpServers:u.mcpServers??e.mcpServers??[]}),loadExistingAgentSession:(u,c)=>this.bootstrapAgentLoad(u,{...c,mcpServers:c.mcpServers??e.mcpServers??[]}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:a,currentMode:i,currentUsage:e.currentUsage,agentCommands:e.agentCommands,agentModes:r,agentModels:o,summarizedThroughEntry:e.summarizedThroughEntry,firstPromptSeeded:!!e.title,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(d.sessionId),scheduleCompaction:u=>this.scheduleCompaction(d.sessionId,u),resolveAgentId:async u=>(await this.registry.getAgent(u))?.id,getCompactionState:()=>this.getCompactionState(d.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(d.sessionId),uncompactHook:()=>this.performUncompact(d.sessionId),forkHook:u=>this.forkSession(d.sessionId,u??{}),onCompactionSwapHook:u=>{this.mutateRecord(d.sessionId,{rollbackBreadcrumb:u}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(d.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(d),e.forkedFromSessionId&&e.forkSynthesisState==="running"?this.logger?.info(`fork ${d.sessionId}: synthesis in flight \u2014 skipping seed, recall available`):e.forkedFromSessionId&&(e.synopsis||(e.summarizedThroughEntry??0)>0)?d.seedFromFork(e.synopsis).catch(()=>{}):d.seedFromImport().catch(()=>{}),d}async dirExists(e){try{return(await Oe.stat(e)).isDirectory()}catch{return!1}}async reapIfOrphanedNonInteractive(e){let t=this.sessions.get(e);!t||t.attachedCount>0||t.interactive!==!0&&(this.logger?.info(`reaping orphaned non-interactive session ${e} (agent killed, cold record kept)`),await t.close({deleteRecord:!1}).catch(()=>{}))}async resolveResurrectCwd(e){return await this.dirExists(e)?e:Z(this.defaultCwd)}async syncFromAgent(e){let t=await this.registry.getAgent(e);if(!t){let l=new Error(`agent ${e} not found in registry`);throw l.code=k.AgentNotInstalled,l}let s=await oe(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:Di.homedir(),plan:s}),i;try{i=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:ze,clientInfo:{name:"hydra",version:Y}})}catch(l){throw await r.kill().catch(()=>{}),Me(l,r)}if(r.authMethods=At(i.authMethods),(i.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(l){throw await r.kill().catch(()=>{}),l}await r.kill().catch(()=>{});let d=new Set;for(let l of this.sessions.values())d.add(`${l.agentId}::${l.upstreamSessionId}`);let u=await this.store.list().catch(()=>[]);for(let l of u)d.add(`${l.agentId}::${l.upstreamSessionId}`);let c=I.sessionsDir(),f=[],p=0;for(let l of a){let g=`${e}::${l.sessionId}`;if(d.has(g)){p+=1;continue}if(nu(l.cwd,c)){p+=1;continue}let m=await this.tombstones.read(e,l.sessionId).catch(()=>{});if(m){if(!pi(m,l.updatedAt)){p+=1;continue}await this.tombstones.remove(e,l.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${l.sessionId} (upstream updatedAt advanced past ${m.upstreamUpdatedAt??"<unset>"})`)}d.add(g);let h=`${ve}${nn()}`,y=new Date().toISOString(),v=l.updatedAt??y,w={sessionId:h,lineageId:bt(),upstreamSessionId:l.sessionId,agentId:e,cwd:l.cwd,pendingHistorySync:!0,interactive:!0,createdAt:v,updatedAt:v};l.title!==void 0&&(w.title=l.title);let S=gs(w);await this.store.write(S),f.push({version:1,...S})}return{synced:f,skipped:p}}async collectAgentSessions(e){let t=[],s,r=new Set;for(let i=0;i<100;i+=1){let o={};s!==void 0&&(o.cursor=s);let a=await e.connection.request("session/list",o),d=Array.isArray(a.sessions)?a.sessions:[];for(let u of d){if(typeof u.sessionId!="string"||typeof u.cwd!="string")continue;let c={sessionId:u.sessionId,cwd:u.cwd};typeof u.title=="string"&&(c.title=u.title),typeof u.updatedAt=="string"&&(c.updatedAt=u.updatedAt),t.push(c)}if(typeof a.nextCursor!="string"||a.nextCursor.length===0||r.has(a.nextCursor))break;r.add(a.nextCursor),s=a.nextCursor}return t}async applySeedModel(e,t,s,r){try{return await e.connection.request("session/set_model",{sessionId:t,modelId:s}),this.logger?.info(`${r}: session/set_model accepted`),!0}catch(i){return this.logger?.warn(`${r} rejected by agent (${i.message}); session will use the agent's own default`),!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=k.AgentNotInstalled,i}let s=await oe(t,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),r=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:s,...e.forwardedEnv?{extraEnv:e.forwardedEnv}:{}});try{let i=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:ze,clientInfo:{name:"hydra",version:Y}}),o=i.agentCapabilities;r.authMethods=At(i.authMethods);let a=await r.connection.request("session/new",{cwd:e.cwd,mcpServers:e.mcpServers??[]}),d=a.sessionId;if(typeof d!="string")throw new Error(`agent ${e.agentId} returned a non-string sessionId from session/new`);let u=Is(a),c=As(a),f=e.model??this.defaultModels[e.agentId];if(f&&f!==u){let g=Ve(f,c),m=e.model!==void 0?`model=${JSON.stringify(f)}`:`defaultModels[${e.agentId}]=${JSON.stringify(f)}`;if(g.kind==="exact"||g.kind==="none")await this.applySeedModel(r,d,f,m)&&(u=f);else if(g.kind==="resolved")(g.modelId===u||await this.applySeedModel(r,d,g.modelId,`${m} resolved to ${JSON.stringify(g.modelId)}`))&&(u=g.modelId);else if(g.kind==="ambiguous")this.logger?.warn(`${m} is ambiguous (trailing-segment matches [${g.candidates.join(", ")}]); skipping session/set_model, session will use ${JSON.stringify(u)}`);else{let h=c.map(y=>y.modelId).join(", ");this.logger?.warn(`${m} not in agent's availableModels ([${h}]); skipping session/set_model, session will use ${JSON.stringify(u)}`)}}let p=Cs(a),l=xs(a);return{agent:r,upstreamSessionId:d,agentMeta:a._meta,agentCapabilities:o,initialModel:u,initialModels:c.length>0?c:void 0,initialModes:p.length>0?p:void 0,initialMode:l}}catch(i){throw await r.kill().catch(()=>{}),Me(Bi(i,r,e.agentId,{command:s.command,args:s.args,cwd:e.cwd}),r)}}async bootstrapAgentLoad(e,t){let s=await this.registry.getAgent(t.agentId);if(!s){let o=new Error(`agent ${t.agentId} not found in registry`);throw o.code=k.AgentNotInstalled,o}let r=await oe(s,t.agentArgs??[],{npmRegistry:this.npmRegistry}),i=this.spawner({agentId:t.agentId,cwd:t.cwd,plan:r,...t.forwardedEnv?{extraEnv:t.forwardedEnv}:{}});try{let o=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:ze,clientInfo:{name:"hydra",version:Y}}),a=o.agentCapabilities;i.authMethods=At(o.authMethods);let d=Hi(t.agentId,void 0),u=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...d&&{_meta:d}}),c=Is(u),f=ks(As(u)),p=Cs(u),l=xs(u);return{agent:i,upstreamSessionId:e,agentMeta:u._meta,agentCapabilities:a,initialModel:c,initialModels:f,initialModes:p.length>0?p:void 0,initialMode:l}}catch(o){throw await i.kill().catch(()=>{}),Me(Bi(o,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 s=await this.store.read(e);if(!s)throw new Error("session record not found");let r=s.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 i=s.compactionState;if(i!=null)throw new Error(`compaction is in progress (status: ${i.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 s=this.pendingAuthAgents.get(e);if(s&&s.isAlive())return s;let r=await this.registry.getAgent(e);if(!r){let d=new Error(`agent ${e} not found in registry`);throw d.code=k.AgentNotInstalled,d}let i=await oe(r,[],{npmRegistry:this.npmRegistry}),o=t??Z(this.defaultCwd),a=this.spawner({agentId:e,cwd:o,plan:i});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:ze,clientInfo:{name:"hydra",version:Y}});a.authMethods=At(d.authMethods)}catch(d){throw await a.kill().catch(()=>{}),Me(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 s=new Error(`agent ${e} not found in registry`);throw s.code=k.AgentNotInstalled,s}return oe(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.invalidateListCache(),t){if(e.upstreamSessionId){let r=rt({interactive:e.interactive,...e.originatingClient?{originatingClient:e.originatingClient}:{}},!0),i=this.tombstones.add({agentId:e.agentId,upstreamSessionId:e.upstreamSessionId,deletedAt:new Date().toISOString(),upstreamUpdatedAt:new Date(e.updatedAt).toISOString(),cwd:e.cwd,title:e.title,reason:"user",...r!==void 0?{interactive:r}:{}}).catch(()=>{}).then(()=>this.store.delete(e.sessionId).catch(()=>{})).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===i&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,i);return}let s=this.store.delete(e.sessionId).catch(()=>{}).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===s&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,s);return}}),e.onTitleChange(t=>{this.persistTitle(e.sessionId,t).catch(()=>{})}),e.onPriorityChange(t=>{this.persistPriority(e.sessionId,t).catch(()=>{})}),e.onAgentChange(({agentId:t,upstreamSessionId:s,retiredCost:r})=>{this.persistAgentChange(e.sessionId,t,s,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:Li(t)}).catch(()=>{})}),e.onAgentCommandsChange(t=>{this.persistSnapshot(e.sessionId,{agentCommands:t.map(s=>({name:s.name,...s.description!==void 0?{description:s.description}:{}}))}).catch(()=>{})}),e.onAgentModesChange(t=>{this.persistSnapshot(e.sessionId,{agentModes:t.map(s=>({id:s.id,...s.name!==void 0?{name:s.name}:{},...s.description!==void 0?{description:s.description}:{}}))}).catch(()=>{})}),e.onAgentModelsChange(t=>{this.persistSnapshot(e.sessionId,{agentModels:t.map(s=>({modelId:s.modelId,...s.name!==void 0?{name:s.name}:{},...s.description!==void 0?{description:s.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),s=su(e,t);await this.store.write(s)}).catch(()=>{})}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 ft(e,t)}async loadFromDisk(e){let t=await this.store.read(e);if(!t)return;let s=t.title;return s||(s=await this.deriveTitleFromHistory(e)),{hydraSessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,agentId:t.agentId,cwd:t.cwd,title:s,synopsis:t.synopsis,summarizedThroughEntry:t.summarizedThroughEntry,agentArgs:t.agentArgs,currentModel:t.currentModel,currentMode:t.currentMode,currentUsage:ru(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,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 s=this.sessions.get(e);s&&(s.forwardedEnv=t),await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r)return;let i={...r,forwardedEnv:t};await this.store.write(i)})}async clearPendingHistorySync(e){await this.enqueueMetaWrite(e,async()=>{let t=await this.store.read(e);if(!t||t.pendingHistorySync!==!0)return;let s={...t};delete s.pendingHistorySync,await this.store.write(s)})}async deriveTitleFromHistory(e){let t=await this.histories.load(e).catch(()=>[]);for(let s of t){let r=s.params;if(r?.update?.sessionUpdate!=="prompt_received")continue;let i=Xe(r.update.prompt),o=as(i,200);if(o)return o}}get(e){return this.sessions.get(e)}liveSessions(){return this.sessions.values()}activeAgentVersions(){let e=new Map;for(let t of this.sessions.values()){let s=t.agent.agentId,r=t.agent.version,i=e.get(s);i||(i=new Set,e.set(s,i)),i.add(r)}return e}async resolveCanonicalId(e){if(this.sessions.has(e)||await this.store.read(e))return e;if(e.startsWith(ve))return;let t=ve+e;if(this.sessions.has(t)||await this.store.read(t))return t}require(e){let t=this.sessions.get(e);if(!t){let s=new Error(`session ${e} not found`);throw s.code=k.SessionNotFound,s}return t}liveListEntry(e){return{sessionId:e.sessionId,upstreamSessionId:e.upstreamSessionId,cwd:e.cwd,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,awaitingInput:e.awaitingInput,agentPid:e.agentPid}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Ct(t.sessionId),d=rt({interactive:t.interactive,...t.originatingClient?{originatingClient:t.originatingClient}:{}},a.hasContent),u=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:u,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,awaitingInput:t.awaitingInput}}let s=await this.store.read(e).catch(()=>{});if(!s)return;let r=await Ct(s.sessionId),i=rt(s,r.hasContent),o=r.mtime??s.updatedAt;return{sessionId:s.sessionId,upstreamSessionId:s.upstreamSessionId,cwd:s.cwd,title:s.title,agentId:s.agentId,currentModel:s.currentModel,currentUsage:kt(s.currentUsage),importedFromMachine:s.importedFromMachine,importedFromUpstreamSessionId:s.importedFromUpstreamSessionId,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:i,priority:s.priority,updatedAt:o,attachedClients:0,status:"cold",busy:!1,awaitingInput:!1}}async list(e={}){let t=`${e.cwd??""}|${e.includeNonInteractive?"1":"0"}|${e.status??""}`,s=Date.now(),r=this.listCache.get(t);if(r&&r.expiresAt>s)return r.promise;let i=this.listUncached(e);return this.listCache.set(t,{expiresAt:s+n.LIST_CACHE_TTL_MS,promise:i}),i.catch(()=>{let o=this.listCache.get(t);o&&o.promise===i&&this.listCache.delete(t)}),i}invalidateListCache(){this.listCache.clear()}async listUncached(e={}){let t=[],s=new Set,r=c=>e.includeNonInteractive?!0:c===!0,i=[...this.sessions.values()].filter(c=>!e.cwd||c.cwd===e.cwd);if(e.status==="cold")for(let c of i)s.add(c.sessionId);let o=e.status==="cold"?[]:await Promise.all(i.map(c=>Ct(c.sessionId)));for(let c=0;c<o.length;c+=1){let f=i[c],p=o[c];s.add(f.sessionId);let l=rt({interactive:f.interactive,...f.originatingClient?{originatingClient:f.originatingClient}:{}},p.hasContent);if(!r(l))continue;let g=p.mtime??new Date(f.updatedAt).toISOString();t.push({sessionId:f.sessionId,upstreamSessionId:f.upstreamSessionId,cwd:f.cwd,title:f.title,agentId:f.agentId,currentModel:f.currentModel,currentUsage:f.currentUsage,parentSessionId:f.parentSessionId,forkedFromSessionId:f.forkedFromSessionId,forkedFromMessageId:f.forkedFromMessageId,originatingClient:f.originatingClient,interactive:l,priority:f.priority,updatedAt:g,attachedClients:f.attachedCount,status:"warm",agentPid:f.agentPid,busy:f.turnStartedAt!==void 0,awaitingInput:f.awaitingInput,compactionState:f.compactionState,forkSynthesisState:f.forkSynthesisState})}if(e.status==="warm")return t;let d=(await this.store.list().catch(c=>{throw this.logger?.warn(`session list: store.list() failed: ${c?.message??String(c)}`),c})).filter(c=>!s.has(c.sessionId)&&(!e.cwd||c.cwd===e.cwd)),u=await Promise.all(d.map(c=>Ct(c.sessionId)));for(let c=0;c<d.length;c+=1){let f=d[c],p=u[c],l=rt(f,p.hasContent);if(!r(l))continue;let g=p.mtime??f.updatedAt;t.push({sessionId:f.sessionId,upstreamSessionId:f.upstreamSessionId,cwd:f.cwd,title:f.title,agentId:f.agentId,currentModel:f.currentModel,currentUsage:kt(f.currentUsage),importedFromMachine:f.importedFromMachine,importedFromUpstreamSessionId:f.importedFromUpstreamSessionId,parentSessionId:f.parentSessionId,forkedFromSessionId:f.forkedFromSessionId,forkedFromMessageId:f.forkedFromMessageId,originatingClient:f.originatingClient,interactive:l,priority:f.priority,updatedAt:g,attachedClients:0,status:"cold",busy:!1,awaitingInput:!1,compactionState:f.compactionState,forkSynthesisState:f.forkSynthesisState})}return t.sort((c,f)=>c.updatedAt<f.updatedAt?1:-1),t}async exportBundle(e,t={}){let s=await this.store.read(e);if(!s)return;let r;if(s.lineageId)r=s;else{let u=bt(),c={...s,lineageId:u};await this.enqueueMetaWrite(e,async()=>{let f=await this.store.read(e);f&&(f.lineageId||await this.store.write({...f,lineageId:u}))}).catch(()=>{}),r=c}let i=t.tools??"inline",o=await this.histories.load(e,i==="references"?{tools:"references"}:{}).catch(()=>[]),a=await Ui(e);if(i!=="references")return{record:r,history:o,promptHistory:a};let d={};for(let u of Mi(o)){let c=await ur(e,u);c&&(d[u]=c.toString("base64"))}return{record:r,history:o,promptHistory:a,toolBlobs:d}}async importBundle(e,t={}){let s=await this.store.findByLineageId(e.session.lineageId);if(s){if(!t.replace){let o=new Error(`bundle already imported as ${s.sessionId}`);throw o.code=k.BundleAlreadyImported,o.existingSessionId=s.sessionId,o}let i=this.sessions.get(s.sessionId);return i&&await i.close({deleteRecord:!1}).catch(()=>{}),await this.writeImportedRecord({sessionId:s.sessionId,bundle:e,preservedCreatedAt:s.createdAt,cwd:t.cwd}),{sessionId:s.sessionId,importedFromSessionId:e.session.sessionId,replaced:!0}}let r=`${ve}${nn()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let s=await this.store.read(e);if(!s){let w=new Error(`source session not found: ${e}`);throw w.code=k.SessionNotFound,w}let r=t.agentId??s.agentId,i=r!==s.agentId;if(i&&!await this.registry.getAgent(r)){let S=new Error(`agent ${r} not found in registry`);throw S.code=k.AgentNotInstalled,S}let o=await this.histories.load(e).catch(()=>[]),a=o,d,u=t.mode??"synthesis",c,f,p,l=12e4;if(u==="verbatim")if(t.forkAt!==void 0){let w=Qt(o,t.forkAt);if(w<0){let S=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw S.code=k.InvalidParams,S}d=t.forkAt,a=o.slice(0,w+1)}else{let w=ou(o);w?(d=w.messageId,a=o.slice(0,w.index+1)):(d="",a=o.slice(0,0))}else{if(t.forkAt!==void 0&&t.forkAt!==""){let S=Qt(o,t.forkAt);if(S<0){let A=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw A.code=k.InvalidParams,A}d=t.forkAt,a=o.slice(0,S+1)}else d="",a=o;let w=await this.registry.getAgent(r);if(!w){let S=new Error(`agent ${r} not found in registry`);throw S.code=k.AgentNotInstalled,S}p=w,f=s.currentModel,c="running"}let g=await Ui(e),m=u==="synthesis",h={...s,lineageId:bt(),agentId:r,interactive:!1,...c!==void 0?{forkSynthesisState:c}:{},summarizedThroughEntry:a.length,...t.title!==void 0?{title:t.title}:{},currentUsage:void 0,...i?{currentModel:void 0,currentMode:void 0,agentCommands:void 0,agentModes:void 0,agentModels:void 0}:{},...t.model!==void 0?{currentModel:t.model}:{}},y=It({record:h,history:a,promptHistory:g.length>0?g:void 0,hydraVersion:Y,machine:gt()}),v=`${ve}${nn()}`;return await this.writeImportedRecord({sessionId:v,bundle:y,cwd:t.cwd,forkedFromSessionId:e,forkedFromMessageId:d,...c!==void 0?{forkSynthesisState:c}:{}}),m&&(async()=>{try{let w=await oe(p,[],{npmRegistry:this.npmRegistry}),S=await Xt({agentId:r,cwd:t.cwd??I.sessionDir(e),plan:w,history:a,modelId:f,sessionId:e,logger:this.logger,timeoutMs:l});S&&S.synopsis?await this.mutateRecord(v,{synopsis:S.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(v,{},["forkSynthesisState"]))}catch(w){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${w.message}`);try{await this.mutateRecord(v,{},["forkSynthesisState"])}catch(S){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${S.message}`)}}})(),{sessionId:v,forkedFromSessionId:e,forkedAt:d}}async writeImportedRecord(e){if(await this.histories.rewrite(e.sessionId,e.bundle.history),e.bundle.toolBlobs)for(let[i,o]of Object.entries(e.bundle.toolBlobs))await lr(e.sessionId,i,Buffer.from(o,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await Oe.utimes(I.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await $i(I.tuiHistoryFile(e.sessionId),e.bundle.promptHistory).catch(()=>{});let s=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,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??s,updatedAt:e.bundle.session.updatedAt})})}async deleteRecord(e,t="user"){let s=await this.store.read(e);if(!s)return!1;if(s.upstreamSessionId){let r=await Ct(e),i=rt(s,r.hasContent);await this.tombstones.add({agentId:s.agentId,upstreamSessionId:s.upstreamSessionId,deletedAt:new Date().toISOString(),upstreamUpdatedAt:s.updatedAt,cwd:s.cwd,title:s.title,reason:t,...i!==void 0?{interactive:i}:{}}).catch(()=>{})}return 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){return(await this.tombstones.read(e,t).catch(()=>{}))?.reason==="user"}async hasRecord(e){return await this.store.read(e).catch(()=>{})!==void 0}async setPriority(e,t){let s=this.get(e);if(s)return s.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 s=this.get(e);return s?(await s.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,s){await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:s})}async persistAgentChange(e,t,s,r){await this.mutateRecord(e,{agentId:t,upstreamSessionId:s},void 0,i=>({upstreamGenerations:qi(i,t,s,void 0,r)}))}async persistSnapshot(e,t){let s={};t.currentModel!==void 0&&(s.currentModel=t.currentModel),t.currentMode!==void 0&&(s.currentMode=t.currentMode),t.currentUsage!==void 0&&(s.currentUsage=t.currentUsage),t.agentCommands!==void 0&&(s.agentCommands=t.agentCommands),t.agentModes!==void 0&&(s.agentModes=t.agentModes),t.agentModels!==void 0&&(s.agentModels=t.agentModels),t.interactive!==void 0&&(s.interactive=t.interactive),t.cwd!==void 0&&(s.cwd=t.cwd),await this.mutateRecord(e,s)}async mutateRecord(e,t,s=[],r){await this.enqueueMetaWrite(e,async()=>{let i=await this.store.read(e);if(!i)return;let o={...i,...t,...r?r(i):{},updatedAt:new Date().toISOString()};for(let a of s)delete o[a];await this.store.write(o)})}static EXTENSION_STATE_CAP_BYTES=64*1024;async getExtensionState(e,t){return(await this.store.read(e))?.extensionState?.[t]??{}}async getExtensionStateKey(e,t,s){return(await this.getExtensionState(e,t))[s]}async setExtensionStateKey(e,t,s,r){await this.enqueueMetaWrite(e,async()=>{let i=await this.store.read(e);if(!i)return;let o={...i.extensionState??{}},a={...o[t]??{},[s]:r},d=Buffer.byteLength(JSON.stringify(a),"utf8");if(d>n.EXTENSION_STATE_CAP_BYTES)throw new Error(`extension_state: bucket for ${t} would be ${d} bytes; cap is ${n.EXTENSION_STATE_CAP_BYTES}`);o[t]=a;let u={...i,extensionState:o,updatedAt:new Date().toISOString()};await this.store.write(u)})}async deleteExtensionStateKey(e,t,s){await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r?.extensionState?.[t])return;let i={...r.extensionState},o={...i[t]};if(!(s in o))return;delete o[s],Object.keys(o).length===0?delete i[t]:i[t]=o;let a={...r,extensionState:i,updatedAt:new Date().toISOString()};await this.store.write(a)})}enqueueMetaWrite(e,t){let r=(this.metaWriteQueues.get(e)??Promise.resolve()).catch(()=>{}).then(t),i=r.catch(()=>{});return this.metaWriteQueues.set(e,i),i.finally(()=>{this.metaWriteQueues.get(e)===i&&this.metaWriteQueues.delete(e)}),r}async closeAll(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(t=>t.close({deleteRecord:!1}))),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 s=t.targetAgentId;(async()=>{try{let r=await this.store.read(e);if(!r?.synopsis||r.summarizedThroughEntry===void 0){this.synopsisCoordinator.scheduleCompaction(e,t);return}if((await this.histories.load(e,{maxEntries:1/0})).length!==r.summarizedThroughEntry){this.synopsisCoordinator.scheduleCompaction(e,t);return}this.logger?.info(`compaction: fast-path swap sessionId=${e} target=${s} (reusing artifact @${r.summarizedThroughEntry})`),await this.dispatchSynthesisSwap(e,r.synopsis,r.summarizedThroughEntry,s)}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 getRollbackBreadcrumb(e){return(await this.store.read(e).catch(()=>{}))?.rollbackBreadcrumb}emitSwapPhase(e,t,s){let r=this.get(e);if(r){if(t){let i=s.phase==="failed";r.broadcastPendingAgentSwap(i?null:t);return}r.broadcastCompactionPhase(s)}}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 s of e){let r=s.attentionFlags??[],i=r.filter(o=>!(o.source==="daemon"&&o.reason.startsWith("permission:")));if(i.length!==r.length){let o=r.length-i.length;t+=o,await this.mutateRecord(s.sessionId,{attentionFlags:i}).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 s of t){let r=s.compactionState;if(r!=null){if(!e.has(r.status)){this.logger?.info(`compaction: not resuming sessionId=${s.sessionId} status=${r.status} (terminal \u2014 user must re-trigger explicitly)`);continue}this.logger?.info(`compaction: resuming sessionId=${s.sessionId} status=${r.status} from prior daemon`);try{this.scheduleCompaction(s.sessionId)}catch(i){this.logger?.warn(`compaction: resume failed for sessionId=${s.sessionId}: ${i instanceof Error?i.message:String(i)}`)}}}}async resumePendingAgentSwaps(){let e=await this.store.list().catch(()=>[]);for(let t of e){let s=t.pendingAgentSwap;if(s)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=${s} with persisted synopsis (history=${r.length})`),await this.dispatchSynthesisSwap(t.sessionId,t.synopsis,t.summarizedThroughEntry??r.length,s)):(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${s} via fresh synthesis (history=${r.length} watermark=${t.summarizedThroughEntry??"(none)"})`),this.scheduleCompaction(t.sessionId,{targetAgentId:s}))}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 s=await Yr(t.sessionId).catch(()=>[]);if(s.length===0)continue;let r=Date.now(),i=s.filter(d=>r-d.enqueuedAt<Ni),o=s.length-i.length;if(o>0&&(this.logger?.info(`queue replay: dropping ${o} stale prompt(s) for ${t.sessionId} (TTL ${Ni/1e3}s)`),await yt(t.sessionId,i).catch(()=>{})),i.length===0)continue;let a=await this.loadFromDisk(t.sessionId).catch(()=>{});if(!a){this.logger?.warn(`queue replay: no meta for ${t.sessionId}; discarding ${i.length} entr${i.length===1?"y":"ies"}`),await yt(t.sessionId,[]).catch(()=>{});continue}try{let d=await this.resurrect(a);this.logger?.info(`queue replay: resurrected ${t.sessionId} and replaying ${i.length} prompt(s)`),d.replayPersistedQueue(i)}catch(d){this.logger?.warn(`queue replay: failed to resurrect ${t.sessionId}: ${d.message}`)}}}};function nu(n,e){if(typeof n!="string"||n.length===0)return!1;let t=xt.resolve(n),s=xt.resolve(e);return t===s||t.startsWith(s+xt.sep)}function su(n,e){let s=(n.mergedAvailableCommands().length>0?n.agentOnlyAdvertisedCommands().map(c=>c.description!==void 0?{name:c.name,description:c.description}:{name:c.name}):void 0)??e?.agentCommands,r=n.availableModes(),o=(r.length>0?r.map(c=>{let f={id:c.id};return c.name!==void 0&&(f.name=c.name),c.description!==void 0&&(f.description=c.description),f}):void 0)??e?.agentModes,a=n.availableModels(),u=(a.length>0?a.map(c=>{let f={modelId:c.modelId};return c.name!==void 0&&(f.name=c.name),c.description!==void 0&&(f.description=c.description),f}):void 0)??e?.agentModels;return gs({sessionId:n.sessionId,lineageId:e?.lineageId??bt(),upstreamSessionId:n.upstreamSessionId,importedFromSessionId:e?.importedFromSessionId,importedFromUpstreamSessionId:e?.importedFromUpstreamSessionId,importedFromMachine:e?.importedFromMachine,agentId:n.agentId,cwd:n.cwd,title:n.title,synopsis:e?.synopsis,summarizedThroughEntry:e?.summarizedThroughEntry,agentArgs:n.agentArgs,currentModel:n.currentModel??e?.currentModel,currentMode:n.currentMode??e?.currentMode,currentUsage:Li(n.persistableUsage)??e?.currentUsage,agentCommands:s,agentModes:o,agentModels:u,parentSessionId:n.parentSessionId??e?.parentSessionId,forkedFromSessionId:n.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId??e?.forkedFromMessageId,originatingClient:n.originatingClient??e?.originatingClient,interactive:n.interactive??e?.interactive,priority:n.priority??e?.priority,forwardedEnv:n.forwardedEnv??e?.forwardedEnv,attentionFlags:n.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?qi(e,n.agentId,n.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(n.createdAt).toISOString()})}function Li(n){if(!n)return;let e={};return n.used!==void 0&&(e.used=n.used),n.size!==void 0&&(e.size=n.size),n.costAmount!==void 0&&(e.costAmount=n.costAmount),n.costCurrency!==void 0&&(e.costCurrency=n.costCurrency),n.cumulativeCost!==void 0&&(e.cumulativeCost=n.cumulativeCost),Object.keys(e).length>0?e:void 0}function ru(n){return n?{...n}:void 0}function Hi(n,e){if(e&&n==="claude-acp")return{claudeCode:{options:{model:e}}}}function rn(n,e){let t=e.fromObject(n);if(t!==void 0)return t;let s=n[e.nestedKey];if(s&&typeof s=="object"&&!Array.isArray(s)){let o=e.fromObject(s);if(o!==void 0)return o}let r=n._meta;if(r&&typeof r=="object"&&!Array.isArray(r)){for(let[o,a]of Object.entries(r))if(o!=="hydra-acp"&&a&&typeof a=="object"&&!Array.isArray(a)){let d=e.fromObject(a);if(d!==void 0)return d}}let i=iu(n,e.configId);if(i){let o=e.fromConfig(i);if(o!==void 0)return o}}function Is(n){return rn(n,{nestedKey:"models",configId:"model",fromObject:e=>ye(e.currentModelId)??ye(e.currentModel)??ye(e.modelId)??ye(e.model),fromConfig:e=>ye(e.currentValue)})}function Me(n,e){if(!n||typeof n!="object")return n;let t=n;if(t.code!==k.AuthRequired)return n;let s=u=>!!u&&typeof u=="object"&&!Array.isArray(u),r=s(t.data)?t.data:{},i=s(r._meta)?r._meta:{},o=s(i["hydra-acp"])?i["hydra-acp"]:{},a=typeof t.message=="string"?t.message:"authentication required",d=new Error(a);return d.code=k.AuthRequired,d.data={...r,_meta:{...i,"hydra-acp":{...o,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function ji(n){return/^[A-Za-z0-9_\-./=:@]+$/.test(n)?n:`'${n.replace(/'/g,"'\\''")}'`}function Bi(n,e,t,s){if(n&&typeof n=="object"&&n.code===k.AuthRequired)return n;let r=n instanceof Error?n.message:String(n),i=r.includes("stderr:"),o=i?"":e.stderrTailText(),a=s?`to reproduce: (cd ${ji(s.cwd)} && ${[s.command,...s.args].map(ji).join(" ")})`:"";if(!o&&!a)return n;let d=[i?r:`agent ${t} failed to start: ${r}`];o&&d.push(`stderr: ${o}`),a&&d.push(a);let u=new Error(d.join(`
126
- `));if(n&&typeof n=="object"){let c=n;typeof c.code=="number"&&(u.code=c.code),c.data!==void 0&&(u.data=c.data)}return u}function At(n){if(!Array.isArray(n))return;let e=[];for(let t of n){if(!t||typeof t!="object")continue;let s=t;if(typeof s.id!="string")continue;let r=typeof s.description=="string"?s.description:"",i=s.type==="agent"||s.type==="terminal"?s.type:void 0,o=typeof s.name=="string"?s.name:void 0,a=s._meta,d=a!==null&&typeof a=="object"&&!Array.isArray(a)?a:void 0;e.push({id:s.id,description:r,...i&&{type:i},...o!==void 0&&{name:o},...d&&{_meta:d}})}return e.length>0?e:void 0}function ye(n){if(typeof n!="string")return;let e=n.trim();return e.length>0?e:void 0}function iu(n,e){let t=n.configOptions;if(Array.isArray(t))for(let s of t){if(!s||typeof s!="object"||Array.isArray(s))continue;let r=s;if(r.id===e)return r}}function ks(n){return n.length>0?n:void 0}function As(n){return rn(n,{nestedKey:"models",configId:"model",fromObject:e=>{let t=Ze(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=Ze(e.options);return t.length>0?t:void 0}})??[]}function Cs(n){return rn(n,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=wt(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=wt(e.options);return t.length>0?t:void 0}})??[]}function xs(n){return rn(n,{nestedKey:"modes",configId:"mode",fromObject:e=>ye(e.currentModeId)??ye(e.currentMode)??ye(e.modeId)??ye(e.mode),fromConfig:e=>ye(e.currentValue)})}function ou(n){for(let e=n.length-1;e>=0;e--){let t=n[e];if(!t||t.method!=="session/update")continue;let s=t.params?.update;if(s?.sessionUpdate==="turn_complete"&&!(typeof s.messageId!="string"||s.messageId.length===0))return{index:e,messageId:s.messageId}}}async function Ui(n){try{let e=await Oe.readFile(I.tuiHistoryFile(n),"utf8"),t=[];for(let s of e.split(`
127
- `))if(s.length!==0)try{let r=JSON.parse(s);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function qi(n,e,t,s=new Date().toISOString(),r){let i=n.upstreamGenerations&&n.upstreamGenerations.length>0?[...n.upstreamGenerations]:n.upstreamSessionId?[{upstreamSessionId:n.upstreamSessionId,agentId:n.agentId}]:[],o=i[i.length-1];if(o&&o.upstreamSessionId===t){if(r!==void 0&&i.length>=2){let a=i[i.length-2];a&&a.cost===void 0&&(i[i.length-2]={...a,cost:r})}return i}return o&&o.endedAt===void 0&&(i[i.length-1]={...o,endedAt:s,...r!==void 0?{cost:r}:{}}),i.push({upstreamSessionId:t,agentId:e,startedAt:s}),i}async function Ct(n){try{let e=await Oe.stat(I.historyFile(n));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function rt(n,e){return n.interactive!==void 0?n.interactive:n.originatingClient?.name===Yt?!1:e?!0:void 0}import{spawn as au}from"child_process";import*as an from"fs";import*as Ie from"fs/promises";import*as dn from"path";import du from"pino-roll";var on=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,s){if(e===78){let o=`exited with code 78 (unrecoverable); fix and run \`${s}s start ${t}\``;return this.tripped_=o,{tripped:o}}let r=this.now();this.recentExits.push(r);let i=r-this.windowMs;for(;this.recentExits.length>0&&this.recentExits[0]<i;)this.recentExits.shift();if(this.recentExits.length>this.maxFailures){let o=Math.round(this.windowMs/6e4),a=`${this.recentExits.length} exits in ${o}m (crash loop); fix and run \`${s}s start ${t}\``;return this.tripped_=a,{tripped:a}}return"restart"}reset(){this.recentExits=[],this.tripped_=void 0}get tripped(){return this.tripped_}};var cu=1e3,uu=6e4,Rs=3e3,it=class{entries=new Map;stopping=!1;context;tokenRegistry;breakerOptions;restartBaseMs;restartCapMs;adapter;constructor(e,t,s,r={}){this.adapter=t,this.context=s,this.tokenRegistry=r.tokenRegistry,this.breakerOptions=r.breakerOptions,this.restartBaseMs=r.restartBaseMs??cu,this.restartCapMs=r.restartCapMs??uu;for(let i of e)this.entries.set(i.name,this.makeEntry(i))}setContext(e){this.context=e}reportVersion(e,t){let s=this.entries.get(e);s&&(s.version=t)}async start(){if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before start`);await Ie.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 s=t.child;if(s){try{s.kill("SIGTERM")}catch{}e.push(new Promise(r=>{if(s.exitCode!==null||s.signalCode!==null){r();return}let i=setTimeout(()=>{try{s.kill("SIGKILL")}catch{}r()},Rs);s.on("exit",()=>{clearTimeout(i),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 Rt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw Rt(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 Rt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let s=t.child;return s?(await this.terminate(t,s),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 Rt(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(s=>{t.failureReason=`spawn: ${s.message}`}),this.infoFor(t)}async unregister(e){let t=this.entries.get(e);if(!t)throw Rt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let s=t.child;s&&await this.terminate(t,s);try{t.logStream?.end()}catch{}this.entries.delete(e)}async terminate(e,t){if(t.exitCode!==null||t.signalCode!==null)return;let s=new Promise(i=>{e.exitWaiters.push(i)});try{t.kill("SIGTERM")}catch{}let r=setTimeout(()=>{try{t.kill("SIGKILL")}catch{}},Rs);typeof r.unref=="function"&&r.unref();try{await s}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 on(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await Ie.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 s=this.adapter.paths.pidFile(t.name),r;try{let i=await Ie.readFile(s,"utf8"),o=Number.parseInt(i.trim(),10);Number.isInteger(o)&&o>0&&(r=o)}catch{}if(typeof r=="number"&&Es(r)){try{process.kill(r,"SIGTERM")}catch{}let i=Date.now()+Rs;for(;Date.now()<i&&Es(r);)await new Promise(o=>setTimeout(o,50));if(Es(r))try{process.kill(r,"SIGKILL")}catch{}}await Ie.unlink(s).catch(()=>{})}}async spawn(e,t){if(this.stopping||e.manuallyStopped)return;let s=this.context;if(!s)throw new Error(`${this.managerName()}.spawn called before setContext`);let r=e.config,i=r.command.length>0?r.command:[r.name],o=dn.dirname(this.adapter.paths.logFile(r.name)),a;try{await Ie.mkdir(o,{recursive:!0}),a=await du({file:dn.join(o,`${r.name}.log`),size:"5m",mkdir:!0,symlink:!0,limit:{count:5}}),a.on("error",h=>{e.failureReason=`log stream: ${h.message}`})}catch(h){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${h.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})
128
- `);let d=this.tokenRegistry?.mint(r.name,this.adapter.tokenRole)??s.serviceToken;e.processToken=d,e.version=void 0;let u={...Nt(),HYDRA_ACP_DAEMON_URL:s.daemonUrl,HYDRA_ACP_DAEMON_HOST:s.daemonHost,HYDRA_ACP_DAEMON_PORT:String(s.daemonPort),HYDRA_ACP_TOKEN:d,HYDRA_ACP_WS_URL:s.daemonWsUrl,HYDRA_ACP_HOME:s.hydraHome,[this.adapter.nameEnvVar]:r.name,...r.env},[c,...f]=i;if(c===void 0){a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} has empty command
129
- `),a.end();return}let p=Z(c),l=[...f,...r.args].map(Z),g;try{g=au(p,l,{env:u,stdio:["ignore","pipe","pipe"],detached:!1})}catch(h){a.write(`[hydra-acp] failed to spawn ${r.name}: ${h.message}
130
- `),a.end(),this.scheduleRestart(e,t);return}let m=h=>{try{a.write(typeof h=="string"?h:h.toString())}catch{}};if(g.stdout?.on("data",m),g.stderr?.on("data",m),typeof g.pid=="number")try{an.writeFileSync(this.adapter.paths.pidFile(r.name),`${g.pid}
124
+ `:"")}import{z as D}from"zod";var yu=D.object({method:D.string(),params:D.unknown(),recordedAt:D.number()}),wu=D.object({sessionId:D.string(),lineageId:D.string(),upstreamSessionId:D.string().optional(),agentId:D.string(),cwd:D.string(),title:D.string().optional(),synopsis:St.optional(),summarizedThroughEntry:D.number().int().nonnegative().optional(),currentModel:D.string().optional(),currentMode:D.string().optional(),currentUsage:vs.optional(),agentCommands:D.array(ws).optional(),agentModes:D.array(bs).optional(),interactive:D.boolean().optional(),originatingClient:Ss.optional(),priority:D.number().int().nonnegative().optional(),createdAt:D.string(),updatedAt:D.string()}),bu=D.object({version:D.literal(1),exportedAt:D.string(),exportedFrom:D.object({hydraVersion:D.string(),machine:D.string(),hydraHost:D.string().optional()}),session:wu,history:D.array(yu),promptHistory:D.array(D.string()).optional(),toolBlobs:D.record(D.string()).optional()});function At(n){let e={version:1,exportedAt:new Date().toISOString(),exportedFrom:{hydraVersion:n.hydraVersion,machine:n.machine,...n.hydraHost!==void 0&&n.hydraHost.length>0?{hydraHost:n.hydraHost}:{}},session:{sessionId:n.record.sessionId,lineageId:n.record.lineageId,...n.record.upstreamSessionId?{upstreamSessionId:n.record.upstreamSessionId}:{},agentId:n.record.agentId,cwd:n.record.cwd,...n.record.title!==void 0?{title:n.record.title}:{},...n.record.synopsis!==void 0?{synopsis:n.record.synopsis}:{},...n.record.summarizedThroughEntry!==void 0?{summarizedThroughEntry:n.record.summarizedThroughEntry}:{},...n.record.currentModel!==void 0?{currentModel:n.record.currentModel}:{},...n.record.currentMode!==void 0?{currentMode:n.record.currentMode}:{},...n.record.currentUsage!==void 0?{currentUsage:n.record.currentUsage}:{},...n.record.agentCommands!==void 0?{agentCommands:n.record.agentCommands}:{},...n.record.agentModes!==void 0?{agentModes:n.record.agentModes}:{},...n.record.interactive!==void 0?{interactive:n.record.interactive}:{},...n.record.originatingClient!==void 0?{originatingClient:n.record.originatingClient}:{},...n.record.priority!==void 0&&n.record.priority>0?{priority:n.record.priority}:{},createdAt:n.record.createdAt,updatedAt:n.record.updatedAt},history:n.history};return n.promptHistory!==void 0&&(e.promptHistory=n.promptHistory),n.toolBlobs!==void 0&&Object.keys(n.toolBlobs).length>0&&(e.toolBlobs=n.toolBlobs),e}function Ko(n){return bu.parse(n)}function Es(n){if(n&&!(n.costAmount===void 0&&n.cumulativeCost===void 0))return(n.cumulativeCost??0)+(n.costAmount??0)}function Ct(n){if(!n)return;let e={};n.used!==void 0&&(e.used=n.used),n.size!==void 0&&(e.size=n.size);let t=Es(n);return t&&(e.costAmount=t),n.costCurrency!==void 0&&(e.costCurrency=n.costCurrency),e}var Yo=900*1e3,Su="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",xt=vu(Su,16),cn=class n{constructor(e,t,s,r={}){this.registry=e;this.spawner=t??(a=>Re.spawn(a)),this.store=s??new en,this.tombstones=r.tombstones??new tn,this.sessionHistoryMaxEntries=r.sessionHistoryMaxEntries??1e3,this.histories=new dn({maxEntries:this.sessionHistoryMaxEntries,archiveMaxBytes:r.sessionHistoryArchiveMaxBytes,archiveTiers:r.sessionHistoryArchiveTiers}),this.idleTimeoutMs=r.idleTimeoutMs??0,this.idleEventTimeoutMs=r.idleEventTimeoutMs??3e4,this.defaultModels=r.defaultModels??{},this.synopsisAgent=r.synopsisAgent,this.synopsisModel=r.synopsisModel,this.compactionAgent=r.compactionAgent,this.compactionModel=r.compactionModel,this.defaultTransformers=r.defaultTransformers??[],this.logger=r.logger,this.npmRegistry=r.npmRegistry,this.extensionCommands=r.extensionCommands,this.defaultCwd=r.defaultCwd??"~";let o=r.compaction??{},i=o.tailK??20;this.compactionTailK=i,this.synopsisCoordinator=new on({registry:this.registry,store:this.store,histories:this.histories,synopsisAgent:this.synopsisAgent,synopsisModel:this.synopsisModel,compactionAgent:this.compactionAgent,compactionModel:this.compactionModel,compactionMaxIterations:o.maxIterations,persistTitle:async(a,d)=>{let u=this.get(a);if(u){await u.retitle(d);return}await this.persistTitle(a,d)},persistSynopsis:(a,d,u)=>this.persistSynopsis(a,d,u),logger:this.logger,npmRegistry:this.npmRegistry,onCompactionStateChange:async(a,d,u)=>{if(u.targetAgentId)return;let c=this.get(a);c&&(c.compactionState=d),await this.mutateRecord(a,{compactionState:d})},broadcastHydraCompaction:(a,d,u)=>{this.emitSwapPhase(a,u.targetAgentId,d)},onSynthesisArtifact:async(a,d,u,c)=>{await this.dispatchSynthesisSwap(a,d,u,c)}}),this.refreshAgentCatalog()}registry;sessions=new Map;resurrectionInflight=new Map;pendingAuthAgents=new Map;spawner;store;tombstones;histories;idleTimeoutMs;defaultModels;synopsisAgent;synopsisModel;compactionAgent;compactionModel;defaultTransformers;idleEventTimeoutMs;sessionHistoryMaxEntries;metaWriteQueues=new Map;listCache=new Map;static LIST_CACHE_TTL_MS=500;logger;npmRegistry;extensionCommands;defaultCwd;synopsisCoordinator;pendingDeletions=new Map;pendingSwapDisposers=new Map;rollbackLocks=new Set;compactionTailK=20;agentCatalog=[];async dispatchSynthesisSwap(e,t,s,r){let o=this.get(e);if(!o){this.logger?.info(`compaction: persisted artifact for cold session sessionId=${e}`),await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:s});return}let i=this.compactionTailK;try{if(await o.isQuiescedForSwap()){this.pendingSwapDisposers.get(e)?.(),this.pendingSwapDisposers.delete(e),await this.performSynthesisSwap(o,t,i,s,r);return}this.pendingSwapDisposers.get(e)?.(),this.logger?.info(`compaction: session not quiesced, parking onceIdle swap sessionId=${e}`),this.emitSwapPhase(e,r,{phase:"deferred"});let d=o.onceIdle(()=>{this.pendingSwapDisposers.delete(e),this.onIdleAttemptSwap(e)});this.pendingSwapDisposers.set(e,d)}catch(a){this.logger?.warn(`compaction: dispatch failed for sessionId=${e}: ${a instanceof Error?a.message:String(a)}, leaving session as-is`)}}async onIdleAttemptSwap(e){let t=this.get(e);if(!t)return;let s=this.compactionTailK;try{if(!await t.isQuiescedForSwap()){let d=await this.store.read(e).catch(()=>{});d?.synopsis&&d.summarizedThroughEntry!==void 0&&this.dispatchSynthesisSwap(e,d.synopsis,d.summarizedThroughEntry,d.pendingAgentSwap);return}let o=await this.store.read(e).catch(()=>{});if(!o?.synopsis||o.summarizedThroughEntry===void 0){this.logger?.warn(`compaction: persisted artifact missing for sessionId=${e}, abandoning swap`),t.compactionState=void 0,await this.mutateRecord(e,{},["compactionState"]);return}let i=o.pendingAgentSwap,a=await this.histories.load(e).catch(()=>[]);if(a.length>o.summarizedThroughEntry){this.logger?.info(`compaction: history grew during deferral (have=${a.length} artifact=${o.summarizedThroughEntry}), rescheduling synopsis sessionId=${e}`),i?this.synopsisCoordinator.scheduleCompaction(e,{targetAgentId:i}):this.synopsisCoordinator.scheduleCompaction(e);return}await this.performSynthesisSwap(t,o.synopsis,s,o.summarizedThroughEntry,i)}catch(r){this.logger?.warn(`compaction: onIdleAttemptSwap failed for sessionId=${e}: ${r instanceof Error?r.message:String(r)}`)}}async performSynthesisSwap(e,t,s,r,o){try{let i=o?Math.min(5,s):0;await e.swapUpstream({artifact:t,tailK:s,tailFloor:i,summarizedThroughEntry:r,...o?{newAgentId:o}:{}}),o?await this.mutateRecord(e.sessionId,{},["pendingAgentSwap"]):(e.compactionState=void 0,await this.mutateRecord(e.sessionId,{},["compactionState"]))}catch(i){this.logger?.warn(`compaction: swap failed for sessionId=${e.sessionId}: ${i instanceof Error?i.message:String(i)}, leaving session as-is`)}}async refreshAgentCatalog(){try{let{agents:e}=await ze(this.registry);this.agentCatalog=e.map(t=>({id:t.id,name:t.name,...t.description!==void 0?{description:t.description}:{}}))}catch{}}async create(e){let t=await this.registry.getAgent(e.agentId);t&&t.id!==e.agentId&&(e={...e,agentId:t.id});let s=`${we}${xt()}`,r=await this.bootstrapAgent({agentId:e.agentId,cwd:e.cwd,agentArgs:e.agentArgs,mcpServers:e.mcpServers,model:e.model,onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,selfSessionId:s});if(e.transformChain&&e.transformChain.length>0){let i={...r.agentCapabilities??{}};for(let a of e.transformChain)if(a.intercepts.has("agent:initialize"))try{let d=await a.connection.request("hydra-acp/transformer/message",{token:`t_${xt()}`,phase:"response",method:"initialize",direction:"agent\u2192daemon",sessionId:"(pre-session)",envelope:i});d.action==="stop"&&d.payload&&(i=d.payload)}catch{}r.agentCapabilities=i}let o=new st({sessionId:s,cwd:e.cwd,agentId:e.agentId,agent:r.agent,upstreamSessionId:r.upstreamSessionId,agentMeta:r.agentMeta,agentCapabilities:r.agentCapabilities,...r.modelVerb?{modelVerb:r.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,idleEventTimeoutMs:this.idleEventTimeoutMs,logger:this.logger,spawnReplacementAgent:i=>this.bootstrapAgent({...i,mcpServers:i.mcpServers??[],selfSessionId:s}),loadExistingAgentSession:(i,a)=>this.bootstrapAgentLoad(i,{...a,mcpServers:a.mcpServers??[],selfSessionId:s}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:r.initialModel,currentMode:r.initialMode,agentModes:r.initialModes,agentModels:r.initialModels,transformChain:e.transformChain,parentSessionId:e.parentSessionId,originatingClient:e.originatingClient,interactive:e.interactive,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(o.sessionId),scheduleCompaction:i=>this.scheduleCompaction(o.sessionId,i),resolveAgentId:async i=>(await this.registry.getAgent(i))?.id,getCompactionState:()=>this.getCompactionState(o.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(o.sessionId),uncompactHook:()=>this.performUncompact(o.sessionId),forkHook:i=>this.forkSession(o.sessionId,i??{}),onCompactionSwapHook:i=>{this.mutateRecord(o.sessionId,{rollbackBreadcrumb:i}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(o.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(o),o}async resurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t){if(t.upstreamSessionId!==e.upstreamSessionId){let o=new Error(`session ${e.hydraSessionId} already exists with a different upstream id`);throw o.code=k.AlreadyAttached,o}return t}let s=this.resurrectionInflight.get(e.hydraSessionId);if(s)return s;let r=this.doResurrect(e);this.resurrectionInflight.set(e.hydraSessionId,r);try{return await r}finally{this.resurrectionInflight.delete(e.hydraSessionId)}}async doResurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t)return t;let s=await this.registry.getAgent(e.agentId);if(!s){let y=new Error(`agent ${e.agentId} not found in registry; cannot resurrect`);throw y.code=k.AgentNotInstalled,y}if(e.upstreamSessionId==="")return this.doResurrectFromImport(e);if(!await this.dirExists(e.cwd))return this.doResurrectFromImport(e);let r=await ie(s,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),o=Ut(e.hydraSessionId,e.forwardedEnv),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...o?{extraEnv:o}:{}}),a;try{let y=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:We,clientInfo:{name:"hydra",version:Y}});a=y.agentCapabilities,i.authMethods=Mt(y.authMethods)}catch(y){throw await i.kill().catch(()=>{}),Pe(y,i)}let d;try{let y=Xo(e.agentId,e.currentModel);d=await i.connection.request("session/load",{sessionId:e.upstreamSessionId,cwd:e.cwd,mcpServers:e.mcpServers??[],...y&&{_meta:y}})}catch(y){if(y&&typeof y=="object"&&y.code===k.AuthRequired)throw await i.kill().catch(()=>{}),Pe(y,i);return process.stderr.write(`session/load failed for upstream ${e.upstreamSessionId} on ${e.agentId} (${y.message}); recovering via import-reseed
125
+ `),await i.kill().catch(()=>{}),this.doResurrectFromImport(e)}if(e.pendingHistorySync===!0)this.clearPendingHistorySync(e.hydraSessionId).catch(()=>{});else{let y=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain1 dropped ${y} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let u=$s(d??{}),c=e.agentModes??Ts(_s(d??{}));this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedMode=${JSON.stringify(e.currentMode)} agentReportedMode=${JSON.stringify(u)} advertisedModes=${JSON.stringify(c?.map(y=>y.id))}`);let f=await Ge({agent:i,upstreamSessionId:e.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:u,advertisedModes:c,logger:this.logger});this.logger?.info(`resurrect: effectiveMode=${JSON.stringify(f)} for sessionId=${e.hydraSessionId}`);let p=Rs(d??{}),l=Ts(Ps(d??{}))??e.agentModels;if(this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedModel=${JSON.stringify(e.currentModel)} agentReportedModel=${JSON.stringify(p)} advertisedModels=${JSON.stringify(l?.map(y=>y.modelId))}`),e.pendingHistorySync!==!0){let y=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain2 (post-mode-restore) dropped ${y} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let m=Gt(d),g=await Ke({agent:i,upstreamSessionId:e.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:p,...m?{modelVerb:m}:{},logger:this.logger});if(e.pendingHistorySync!==!0){let y=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain3 (post-model-restore) dropped ${y} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let h=new st({sessionId:e.hydraSessionId,cwd:e.cwd,agentId:e.agentId,agent:i,upstreamSessionId:e.upstreamSessionId,agentMeta:d?._meta,agentCapabilities:a,...m?{modelVerb:m}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,logger:this.logger,spawnReplacementAgent:y=>this.bootstrapAgent({...y,mcpServers:y.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(y,b)=>this.bootstrapAgentLoad(y,{...b,mcpServers:b.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:g,currentMode:f,currentUsage:e.currentUsage,reloadsUpstreamLedger:!0,agentCommands:e.agentCommands,agentModes:c,agentModels:l,summarizedThroughEntry:e.summarizedThroughEntry,compactionState:e.compactionState,firstPromptSeeded:!!e.title,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(h.sessionId),scheduleCompaction:y=>this.scheduleCompaction(h.sessionId,y),resolveAgentId:async y=>(await this.registry.getAgent(y))?.id,getCompactionState:()=>this.getCompactionState(h.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(h.sessionId),uncompactHook:()=>this.performUncompact(h.sessionId),forkHook:y=>this.forkSession(h.sessionId,y??{}),onCompactionSwapHook:y=>{this.mutateRecord(h.sessionId,{rollbackBreadcrumb:y}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(h.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(h),h}async doResurrectFromImport(e){let t=await this.resolveResurrectCwd(e.cwd),s=await this.bootstrapAgent({agentId:e.agentId,cwd:t,agentArgs:e.agentArgs,mcpServers:e.mcpServers??[],onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,model:e.currentModel}),r=e.agentModes??s.initialModes,o=await Ge({agent:s.agent,upstreamSessionId:s.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:s.initialMode,advertisedModes:r,logger:this.logger}),i=e.agentModels??s.initialModels,a=await Ke({agent:s.agent,upstreamSessionId:s.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:s.initialModel,...s.modelVerb?{modelVerb:s.modelVerb}:{},logger:this.logger});s.agent.connection.drainBuffered("session/update");let d=new st({sessionId:e.hydraSessionId,cwd:t,agentId:e.agentId,agent:s.agent,upstreamSessionId:s.upstreamSessionId,agentMeta:s.agentMeta,agentCapabilities:s.agentCapabilities,...s.modelVerb?{modelVerb:s.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,logger:this.logger,spawnReplacementAgent:u=>this.bootstrapAgent({...u,mcpServers:u.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(u,c)=>this.bootstrapAgentLoad(u,{...c,mcpServers:c.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:a,currentMode:o,currentUsage:e.currentUsage,agentCommands:e.agentCommands,agentModes:r,agentModels:i,summarizedThroughEntry:e.summarizedThroughEntry,firstPromptSeeded:!!e.title,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(d.sessionId),scheduleCompaction:u=>this.scheduleCompaction(d.sessionId,u),resolveAgentId:async u=>(await this.registry.getAgent(u))?.id,getCompactionState:()=>this.getCompactionState(d.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(d.sessionId),uncompactHook:()=>this.performUncompact(d.sessionId),forkHook:u=>this.forkSession(d.sessionId,u??{}),onCompactionSwapHook:u=>{this.mutateRecord(d.sessionId,{rollbackBreadcrumb:u}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(d.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(d),e.forkedFromSessionId&&e.forkSynthesisState==="running"?this.logger?.info(`fork ${d.sessionId}: synthesis in flight \u2014 skipping seed, recall available`):e.forkedFromSessionId&&(e.synopsis||(e.summarizedThroughEntry??0)>0)?d.seedFromFork(e.synopsis).catch(()=>{}):d.seedFromImport().catch(()=>{}),d}async dirExists(e){try{return(await Ne.stat(e)).isDirectory()}catch{return!1}}async reapIfOrphanedNonInteractive(e){let t=this.sessions.get(e);if(!(!t||t.attachedCount>0)&&t.interactive!==!0){if(t.hasWorkInFlight){this.logger?.info(`deferring reap of ${e}: work still in flight after detach`),t.onceIdle(s=>{this.reapIfOrphanedNonInteractive(s.sessionId).catch(()=>{})});return}this.logger?.info(`reaping orphaned non-interactive session ${e} (agent killed, cold record kept)`),await t.close({deleteRecord:!1}).catch(()=>{})}}async resolveResurrectCwd(e){return await this.dirExists(e)?e:Z(this.defaultCwd)}async syncFromAgent(e){let t=await this.registry.getAgent(e);if(!t){let l=new Error(`agent ${e} not found in registry`);throw l.code=k.AgentNotInstalled,l}let s=await ie(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:ni.homedir(),plan:s}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:We,clientInfo:{name:"hydra",version:Y}})}catch(l){throw await r.kill().catch(()=>{}),Pe(l,r)}if(r.authMethods=Mt(o.authMethods),(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(l){throw await r.kill().catch(()=>{}),l}await r.kill().catch(()=>{});let d=new Set;for(let l of this.sessions.values())d.add(`${l.agentId}::${l.upstreamSessionId}`);let u=await this.store.list().catch(()=>[]);for(let l of u)d.add(`${l.agentId}::${l.upstreamSessionId}`);let c=I.sessionsDir(),f=[],p=0;for(let l of a){let m=`${e}::${l.sessionId}`;if(d.has(m)){p+=1;continue}if(Iu(l.cwd,c)){p+=1;continue}let g=await this.tombstones.read(e,l.sessionId).catch(()=>{});if(g){if(!Eo(g,l.updatedAt)){p+=1;continue}await this.tombstones.remove(e,l.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${l.sessionId} (upstream updatedAt advanced past ${g.upstreamUpdatedAt??"<unset>"})`)}d.add(m);let h=`${we}${xt()}`,y=new Date().toISOString(),b=l.updatedAt??y,w={sessionId:h,lineageId:It(),upstreamSessionId:l.sessionId,agentId:e,cwd:l.cwd,pendingHistorySync:!0,interactive:!0,createdAt:b,updatedAt:b};l.title!==void 0&&(w.title=l.title);let v=Is(w);await this.store.write(v),f.push({version:1,...v})}return{synced:f,skipped:p}}async collectAgentSessions(e){let t=[],s,r=new Set;for(let o=0;o<100;o+=1){let i={};s!==void 0&&(i.cursor=s);let a=await e.connection.request("session/list",i),d=Array.isArray(a.sessions)?a.sessions:[];for(let u of d){if(typeof u.sessionId!="string"||typeof u.cwd!="string")continue;let c={sessionId:u.sessionId,cwd:u.cwd};typeof u.title=="string"&&(c.title=u.title),typeof u.updatedAt=="string"&&(c.updatedAt=u.updatedAt),t.push(c)}if(typeof a.nextCursor!="string"||a.nextCursor.length===0||r.has(a.nextCursor))break;r.add(a.nextCursor),s=a.nextCursor}return t}async applySeedModel(e,t,s,r,o){try{let{verb:i}=await Qe({request:(a,d)=>e.connection.request(a,d),sessionId:t,modelId:s,...o?{verb:o}:{},logger:this.logger});return this.logger?.info(`${r}: ${i} accepted`),!0}catch(i){return this.logger?.warn(`${r} rejected by agent (${i.message}); session will use the agent's own default`),!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=k.AgentNotInstalled,i}let s=await ie(t,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),r=Ut(e.selfSessionId,e.forwardedEnv),o=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:s,...r?{extraEnv:r}:{}});try{let i=await o.connection.request("initialize",{protocolVersion:1,clientCapabilities:We,clientInfo:{name:"hydra",version:Y}}),a=i.agentCapabilities;o.authMethods=Mt(i.authMethods);let d=await o.connection.request("session/new",{cwd:e.cwd,mcpServers:e.mcpServers??[]}),u=d.sessionId;if(typeof u!="string")throw new Error(`agent ${e.agentId} returned a non-string sessionId from session/new`);let c=Rs(d),f=Ps(d),p=Gt(d),l=e.model??this.defaultModels[e.agentId];if(l&&l!==c){let h=Ze(l,f),y=e.model!==void 0?`model=${JSON.stringify(l)}`:`defaultModels[${e.agentId}]=${JSON.stringify(l)}`;if(h.kind==="exact"||h.kind==="none")await this.applySeedModel(o,u,l,y,p)&&(c=l);else if(h.kind==="resolved")(h.modelId===c||await this.applySeedModel(o,u,h.modelId,`${y} resolved to ${JSON.stringify(h.modelId)}`,p))&&(c=h.modelId);else if(h.kind==="ambiguous")this.logger?.warn(`${y} is ambiguous (trailing-segment matches [${h.candidates.join(", ")}]); skipping session/set_model, session will use ${JSON.stringify(c)}`);else{let b=f.map(w=>w.modelId).join(", ");this.logger?.warn(`${y} not in agent's availableModels ([${b}]); skipping session/set_model, session will use ${JSON.stringify(c)}`)}}let m=_s(d),g=$s(d);return{agent:o,upstreamSessionId:u,agentMeta:d._meta,agentCapabilities:a,initialModel:c,initialModels:f.length>0?f:void 0,initialModes:m.length>0?m:void 0,initialMode:g,modelVerb:p}}catch(i){throw await o.kill().catch(()=>{}),Pe(ei(i,o,e.agentId,{command:s.command,args:s.args,cwd:e.cwd}),o)}}async bootstrapAgentLoad(e,t){let s=await this.registry.getAgent(t.agentId);if(!s){let a=new Error(`agent ${t.agentId} not found in registry`);throw a.code=k.AgentNotInstalled,a}let r=await ie(s,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=Ut(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:We,clientInfo:{name:"hydra",version:Y}}),d=a.agentCapabilities;i.authMethods=Mt(a.authMethods);let u=Xo(t.agentId,void 0),c=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...u&&{_meta:u}}),f=Rs(c),p=Ts(Ps(c)),l=_s(c),m=$s(c);return{agent:i,upstreamSessionId:e,agentMeta:c._meta,agentCapabilities:d,initialModel:f,initialModels:p,initialModes:l.length>0?l:void 0,initialMode:m,modelVerb:Gt(c)}}catch(a){throw await i.kill().catch(()=>{}),Pe(ei(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 s=await this.store.read(e);if(!s)throw new Error("session record not found");let r=s.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=s.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 s=this.pendingAuthAgents.get(e);if(s&&s.isAlive())return s;let r=await this.registry.getAgent(e);if(!r){let d=new Error(`agent ${e} not found in registry`);throw d.code=k.AgentNotInstalled,d}let o=await ie(r,[],{npmRegistry:this.npmRegistry}),i=t??Z(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:We,clientInfo:{name:"hydra",version:Y}});a.authMethods=Mt(d.authMethods)}catch(d){throw await a.kill().catch(()=>{}),Pe(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 s=new Error(`agent ${e} not found in registry`);throw s.code=k.AgentNotInstalled,s}return ie(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.invalidateListCache(),t){if(e.upstreamSessionId){let r=at({interactive:e.interactive,...e.originatingClient?{originatingClient:e.originatingClient}:{}},!0),o=this.tombstones.add({agentId:e.agentId,upstreamSessionId:e.upstreamSessionId,deletedAt:new Date().toISOString(),upstreamUpdatedAt:new Date(e.updatedAt).toISOString(),cwd:e.cwd,title:e.title,reason:"user",...r!==void 0?{interactive:r}:{}}).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 s=this.store.delete(e.sessionId).catch(()=>{}).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===s&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,s);return}}),e.onTitleChange(t=>{this.persistTitle(e.sessionId,t).catch(()=>{})}),e.onPriorityChange(t=>{this.persistPriority(e.sessionId,t).catch(()=>{})}),e.onAgentChange(({agentId:t,upstreamSessionId:s,retiredCost:r})=>{this.persistAgentChange(e.sessionId,t,s,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:si(t)}).catch(()=>{})}),e.onAgentCommandsChange(t=>{this.persistSnapshot(e.sessionId,{agentCommands:t.map(s=>({name:s.name,...s.description!==void 0?{description:s.description}:{}}))}).catch(()=>{})}),e.onAgentModesChange(t=>{this.persistSnapshot(e.sessionId,{agentModes:t.map(s=>({id:s.id,...s.name!==void 0?{name:s.name}:{},...s.description!==void 0?{description:s.description}:{}}))}).catch(()=>{})}),e.onAgentModelsChange(t=>{this.persistSnapshot(e.sessionId,{agentModels:t.map(s=>({modelId:s.modelId,...s.name!==void 0?{name:s.name}:{},...s.description!==void 0?{description:s.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),s=ku(e,t);await this.store.write(s)}).catch(()=>{})}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 gt(e,t)}async loadFromDisk(e){let t=await this.store.read(e);if(!t)return;let s=t.title;return s||(s=await this.deriveTitleFromHistory(e)),{hydraSessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,agentId:t.agentId,cwd:t.cwd,title:s,synopsis:t.synopsis,summarizedThroughEntry:t.summarizedThroughEntry,agentArgs:t.agentArgs,currentModel:t.currentModel,currentMode:t.currentMode,currentUsage:Au(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,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 s=this.sessions.get(e);s&&(s.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 s={...t};delete s.pendingHistorySync,await this.store.write(s)})}async deriveTitleFromHistory(e){let t=await this.histories.load(e).catch(()=>[]);for(let s of t){let r=s.params;if(r?.update?.sessionUpdate!=="prompt_received")continue;let o=tt(r.update.prompt),i=ms(o,200);if(i)return i}}get(e){return this.sessions.get(e)}liveSessions(){return this.sessions.values()}activeAgentVersions(){let e=new Map;for(let t of this.sessions.values()){let s=t.agent.agentId,r=t.agent.version,o=e.get(s);o||(o=new Set,e.set(s,o)),o.add(r)}return e}async resolveCanonicalId(e){if(this.sessions.has(e)||await this.store.read(e))return e;if(e.startsWith(we))return;let t=we+e;if(this.sessions.has(t)||await this.store.read(t))return t}require(e){let t=this.sessions.get(e);if(!t){let s=new Error(`session ${e} not found`);throw s.code=k.SessionNotFound,s}return t}liveListEntry(e){return{sessionId:e.sessionId,upstreamSessionId:e.upstreamSessionId,cwd:e.cwd,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,awaitingInput:e.awaitingInput,agentPid:e.agentPid}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Et(t.sessionId),d=at({interactive:t.interactive,...t.originatingClient?{originatingClient:t.originatingClient}:{}},a.hasContent),u=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:u,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,awaitingInput:t.awaitingInput}}let s=await this.store.read(e).catch(()=>{});if(!s)return;let r=await Et(s.sessionId),o=at(s,r.hasContent),i=r.mtime??s.updatedAt;return{sessionId:s.sessionId,upstreamSessionId:s.upstreamSessionId,cwd:s.cwd,title:s.title,agentId:s.agentId,currentModel:s.currentModel,currentUsage:Ct(s.currentUsage),importedFromMachine:s.importedFromMachine,importedFromUpstreamSessionId:s.importedFromUpstreamSessionId,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:o,priority:s.priority,updatedAt:i,attachedClients:0,status:"cold",busy:!1,awaitingInput:!1}}async list(e={}){let t=`${e.cwd??""}|${e.includeNonInteractive?"1":"0"}|${e.status??""}`,s=Date.now(),r=this.listCache.get(t);if(r&&r.expiresAt>s)return r.promise;let o=this.listUncached(e);return this.listCache.set(t,{expiresAt:s+n.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=[],s=new Set,r=c=>e.includeNonInteractive?!0:c===!0,o=[...this.sessions.values()].filter(c=>!e.cwd||c.cwd===e.cwd);if(e.status==="cold")for(let c of o)s.add(c.sessionId);let i=e.status==="cold"?[]:await Promise.all(o.map(c=>Et(c.sessionId)));for(let c=0;c<i.length;c+=1){let f=o[c],p=i[c];s.add(f.sessionId);let l=at({interactive:f.interactive,...f.originatingClient?{originatingClient:f.originatingClient}:{}},p.hasContent);if(!r(l))continue;let m=p.mtime??new Date(f.updatedAt).toISOString();t.push({sessionId:f.sessionId,upstreamSessionId:f.upstreamSessionId,cwd:f.cwd,title:f.title,agentId:f.agentId,currentModel:f.currentModel,currentUsage:f.currentUsage,parentSessionId:f.parentSessionId,forkedFromSessionId:f.forkedFromSessionId,forkedFromMessageId:f.forkedFromMessageId,originatingClient:f.originatingClient,interactive:l,priority:f.priority,updatedAt:m,attachedClients:f.attachedCount,status:"warm",agentPid:f.agentPid,busy:f.turnStartedAt!==void 0,awaitingInput:f.awaitingInput,compactionState:f.compactionState,forkSynthesisState:f.forkSynthesisState})}if(e.status==="warm")return t;let d=(await this.store.list().catch(c=>{throw this.logger?.warn(`session list: store.list() failed: ${c?.message??String(c)}`),c})).filter(c=>!s.has(c.sessionId)&&(!e.cwd||c.cwd===e.cwd)),u=await Promise.all(d.map(c=>Et(c.sessionId)));for(let c=0;c<d.length;c+=1){let f=d[c],p=u[c],l=at(f,p.hasContent);if(!r(l))continue;let m=p.mtime??f.updatedAt;t.push({sessionId:f.sessionId,upstreamSessionId:f.upstreamSessionId,cwd:f.cwd,title:f.title,agentId:f.agentId,currentModel:f.currentModel,currentUsage:Ct(f.currentUsage),importedFromMachine:f.importedFromMachine,importedFromUpstreamSessionId:f.importedFromUpstreamSessionId,parentSessionId:f.parentSessionId,forkedFromSessionId:f.forkedFromSessionId,forkedFromMessageId:f.forkedFromMessageId,originatingClient:f.originatingClient,interactive:l,priority:f.priority,updatedAt:m,attachedClients:0,status:"cold",busy:!1,awaitingInput:!1,compactionState:f.compactionState,forkSynthesisState:f.forkSynthesisState})}return t.sort((c,f)=>c.updatedAt<f.updatedAt?1:-1),t}async exportBundle(e,t={}){let s=await this.store.read(e);if(!s)return;let r;if(s.lineageId)r=s;else{let u=It(),c={...s,lineageId:u};await this.enqueueMetaWrite(e,async()=>{let f=await this.store.read(e);f&&(f.lineageId||await this.store.write({...f,lineageId:u}))}).catch(()=>{}),r=c}let o=t.tools??"inline",i=await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await ti(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let u of zo(i)){let c=await br(e,u);c&&(d[u]=c.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}async importBundle(e,t={}){let s=await this.store.findByLineageId(e.session.lineageId);if(s){if(!t.replace){let i=new Error(`bundle already imported as ${s.sessionId}`);throw i.code=k.BundleAlreadyImported,i.existingSessionId=s.sessionId,i}let o=this.sessions.get(s.sessionId);return o&&await o.close({deleteRecord:!1}).catch(()=>{}),await this.writeImportedRecord({sessionId:s.sessionId,bundle:e,preservedCreatedAt:s.createdAt,cwd:t.cwd}),{sessionId:s.sessionId,importedFromSessionId:e.session.sessionId,replaced:!0}}let r=`${we}${xt()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let s=await this.store.read(e);if(!s){let w=new Error(`source session not found: ${e}`);throw w.code=k.SessionNotFound,w}let r=t.agentId??s.agentId,o=r!==s.agentId;if(o&&!await this.registry.getAgent(r)){let v=new Error(`agent ${r} not found in registry`);throw v.code=k.AgentNotInstalled,v}let i=await this.histories.load(e).catch(()=>[]),a=i,d,u=t.mode??"synthesis",c,f,p,l=12e4;if(u==="verbatim")if(t.forkAt!==void 0){let w=Zt(i,t.forkAt);if(w<0){let v=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw v.code=k.InvalidParams,v}d=t.forkAt,a=i.slice(0,w+1)}else{let w=xu(i);w?(d=w.messageId,a=i.slice(0,w.index+1)):(d="",a=i.slice(0,0))}else{if(t.forkAt!==void 0&&t.forkAt!==""){let v=Zt(i,t.forkAt);if(v<0){let A=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw A.code=k.InvalidParams,A}d=t.forkAt,a=i.slice(0,v+1)}else d="",a=i;let w=await this.registry.getAgent(r);if(!w){let v=new Error(`agent ${r} not found in registry`);throw v.code=k.AgentNotInstalled,v}p=w,f=s.currentModel,c="running"}let m=await ti(e),g=u==="synthesis",h={...s,lineageId:It(),agentId:r,interactive:!1,...c!==void 0?{forkSynthesisState:c}:{},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}:{}},y=At({record:h,history:a,promptHistory:m.length>0?m:void 0,hydraVersion:Y,machine:yt()}),b=`${we}${xt()}`;return await this.writeImportedRecord({sessionId:b,bundle:y,cwd:t.cwd,forkedFromSessionId:e,forkedFromMessageId:d,...c!==void 0?{forkSynthesisState:c}:{}}),g&&(async()=>{try{let w=await ie(p,[],{npmRegistry:this.npmRegistry}),v=await rn({agentId:r,cwd:t.cwd??I.sessionDir(e),plan:w,history:a,modelId:f,sessionId:e,logger:this.logger,timeoutMs:l});v&&v.synopsis?await this.mutateRecord(b,{synopsis:v.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(b,{},["forkSynthesisState"]))}catch(w){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${w.message}`);try{await this.mutateRecord(b,{},["forkSynthesisState"])}catch(v){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${v.message}`)}}})(),{sessionId:b,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 vr(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await Ne.utimes(I.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await Go(I.tuiHistoryFile(e.sessionId),e.bundle.promptHistory).catch(()=>{});let s=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,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??s,updatedAt:e.bundle.session.updatedAt})})}async deleteRecord(e,t="user"){let s=await this.store.read(e);if(!s)return!1;if(s.upstreamSessionId){let r=await Et(e),o=at(s,r.hasContent);await this.tombstones.add({agentId:s.agentId,upstreamSessionId:s.upstreamSessionId,deletedAt:new Date().toISOString(),upstreamUpdatedAt:s.updatedAt,cwd:s.cwd,title:s.title,reason:t,...o!==void 0?{interactive:o}:{}}).catch(()=>{})}return 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){return(await this.tombstones.read(e,t).catch(()=>{}))?.reason==="user"}async hasRecord(e){return await this.store.read(e).catch(()=>{})!==void 0}async setPriority(e,t){let s=this.get(e);if(s)return s.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 s=this.get(e);return s?(await s.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,s){await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:s})}async persistAgentChange(e,t,s,r){await this.mutateRecord(e,{agentId:t,upstreamSessionId:s},void 0,o=>({upstreamGenerations:ri(o,t,s,void 0,r)}))}async persistSnapshot(e,t){let s={};t.currentModel!==void 0&&(s.currentModel=t.currentModel),t.currentMode!==void 0&&(s.currentMode=t.currentMode),t.currentUsage!==void 0&&(s.currentUsage=t.currentUsage),t.agentCommands!==void 0&&(s.agentCommands=t.agentCommands),t.agentModes!==void 0&&(s.agentModes=t.agentModes),t.agentModels!==void 0&&(s.agentModels=t.agentModels),t.interactive!==void 0&&(s.interactive=t.interactive),t.cwd!==void 0&&(s.cwd=t.cwd),await this.mutateRecord(e,s)}async mutateRecord(e,t,s=[],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 s)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,s){return(await this.getExtensionState(e,t))[s]}async setExtensionStateKey(e,t,s,r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o.extensionState??{}},a={...i[t]??{},[s]:r},d=Buffer.byteLength(JSON.stringify(a),"utf8");if(d>n.EXTENSION_STATE_CAP_BYTES)throw new Error(`extension_state: bucket for ${t} would be ${d} bytes; cap is ${n.EXTENSION_STATE_CAP_BYTES}`);i[t]=a;let u={...o,extensionState:i,updatedAt:new Date().toISOString()};await this.store.write(u)})}async deleteExtensionStateKey(e,t,s){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(!(s in i))return;delete i[s],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){let r=(this.metaWriteQueues.get(e)??Promise.resolve()).catch(()=>{}).then(t),o=r.catch(()=>{});return this.metaWriteQueues.set(e,o),o.finally(()=>{this.metaWriteQueues.get(e)===o&&this.metaWriteQueues.delete(e)}),r}async closeAll(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(t=>t.close({deleteRecord:!1}))),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 s=t.targetAgentId;(async()=>{try{let r=await this.store.read(e);if(!r?.synopsis||r.summarizedThroughEntry===void 0){this.synopsisCoordinator.scheduleCompaction(e,t);return}if((await this.histories.load(e,{maxEntries:1/0})).length!==r.summarizedThroughEntry){this.synopsisCoordinator.scheduleCompaction(e,t);return}this.logger?.info(`compaction: fast-path swap sessionId=${e} target=${s} (reusing artifact @${r.summarizedThroughEntry})`),await this.dispatchSynthesisSwap(e,r.synopsis,r.summarizedThroughEntry,s)}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 getRollbackBreadcrumb(e){return(await this.store.read(e).catch(()=>{}))?.rollbackBreadcrumb}emitSwapPhase(e,t,s){let r=this.get(e);if(r){if(t){let o=s.phase==="failed";r.broadcastPendingAgentSwap(o?null:t);return}r.broadcastCompactionPhase(s)}}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 s of e){let r=s.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(s.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 s of t){let r=s.compactionState;if(r!=null){if(!e.has(r.status)){this.logger?.info(`compaction: not resuming sessionId=${s.sessionId} status=${r.status} (terminal \u2014 user must re-trigger explicitly)`);continue}this.logger?.info(`compaction: resuming sessionId=${s.sessionId} status=${r.status} from prior daemon`);try{this.scheduleCompaction(s.sessionId)}catch(o){this.logger?.warn(`compaction: resume failed for sessionId=${s.sessionId}: ${o instanceof Error?o.message:String(o)}`)}}}}async resumePendingAgentSwaps(){let e=await this.store.list().catch(()=>[]);for(let t of e){let s=t.pendingAgentSwap;if(s)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=${s} with persisted synopsis (history=${r.length})`),await this.dispatchSynthesisSwap(t.sessionId,t.synopsis,t.summarizedThroughEntry??r.length,s)):(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${s} via fresh synthesis (history=${r.length} watermark=${t.summarizedThroughEntry??"(none)"})`),this.scheduleCompaction(t.sessionId,{targetAgentId:s}))}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 s=await fo(t.sessionId).catch(()=>[]);if(s.length===0)continue;let r=Date.now(),o=s.filter(d=>r-d.enqueuedAt<Yo),i=s.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${Yo/1e3}s)`),await bt(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 bt(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 Iu(n,e){if(typeof n!="string"||n.length===0)return!1;let t=Rt.resolve(n),s=Rt.resolve(e);return t===s||t.startsWith(s+Rt.sep)}function ku(n,e){let s=(n.mergedAvailableCommands().length>0?n.agentOnlyAdvertisedCommands().map(c=>c.description!==void 0?{name:c.name,description:c.description}:{name:c.name}):void 0)??e?.agentCommands,r=n.availableModes(),i=(r.length>0?r.map(c=>{let f={id:c.id};return c.name!==void 0&&(f.name=c.name),c.description!==void 0&&(f.description=c.description),f}):void 0)??e?.agentModes,a=n.availableModels(),u=(a.length>0?a.map(c=>{let f={modelId:c.modelId};return c.name!==void 0&&(f.name=c.name),c.description!==void 0&&(f.description=c.description),f}):void 0)??e?.agentModels;return Is({sessionId:n.sessionId,lineageId:e?.lineageId??It(),upstreamSessionId:n.upstreamSessionId,importedFromSessionId:e?.importedFromSessionId,importedFromUpstreamSessionId:e?.importedFromUpstreamSessionId,importedFromMachine:e?.importedFromMachine,agentId:n.agentId,cwd:n.cwd,title:n.title,synopsis:e?.synopsis,summarizedThroughEntry:e?.summarizedThroughEntry,agentArgs:n.agentArgs,currentModel:n.currentModel??e?.currentModel,currentMode:n.currentMode??e?.currentMode,currentUsage:si(n.persistableUsage)??e?.currentUsage,agentCommands:s,agentModes:i,agentModels:u,parentSessionId:n.parentSessionId??e?.parentSessionId,forkedFromSessionId:n.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId??e?.forkedFromMessageId,originatingClient:n.originatingClient??e?.originatingClient,interactive:n.interactive??e?.interactive,priority:n.priority??e?.priority,forwardedEnv:n.forwardedEnv??e?.forwardedEnv,attentionFlags:n.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?ri(e,n.agentId,n.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(n.createdAt).toISOString()})}function si(n){if(!n)return;let e={};return n.used!==void 0&&(e.used=n.used),n.size!==void 0&&(e.size=n.size),n.costAmount!==void 0&&(e.costAmount=n.costAmount),n.costCurrency!==void 0&&(e.costCurrency=n.costCurrency),n.cumulativeCost!==void 0&&(e.cumulativeCost=n.cumulativeCost),Object.keys(e).length>0?e:void 0}function Au(n){return n?{...n}:void 0}function Xo(n,e){if(e&&n==="claude-acp")return{claudeCode:{options:{model:e}}}}function un(n,e){let t=e.fromObject(n);if(t!==void 0)return t;let s=n[e.nestedKey];if(s&&typeof s=="object"&&!Array.isArray(s)){let i=e.fromObject(s);if(i!==void 0)return i}let r=n._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=Cu(n,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function Rs(n){return un(n,{nestedKey:"models",configId:"model",fromObject:e=>ve(e.currentModelId)??ve(e.currentModel)??ve(e.modelId)??ve(e.model),fromConfig:e=>ve(e.currentValue)})}function Pe(n,e){if(!n||typeof n!="object")return n;let t=n;if(t.code!==k.AuthRequired)return n;let s=u=>!!u&&typeof u=="object"&&!Array.isArray(u),r=s(t.data)?t.data:{},o=s(r._meta)?r._meta:{},i=s(o["hydra-acp"])?o["hydra-acp"]:{},a=typeof t.message=="string"?t.message:"authentication required",d=new Error(a);return d.code=k.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function Zo(n){return/^[A-Za-z0-9_\-./=:@]+$/.test(n)?n:`'${n.replace(/'/g,"'\\''")}'`}function ei(n,e,t,s){if(n&&typeof n=="object"&&n.code===k.AuthRequired)return n;let r=n instanceof Error?n.message:String(n),o=r.includes("stderr:"),i=o?"":e.stderrTailText(),a=s?`to reproduce: (cd ${Zo(s.cwd)} && ${[s.command,...s.args].map(Zo).join(" ")})`:"";if(!i&&!a)return n;let d=[o?r:`agent ${t} failed to start: ${r}`];i&&d.push(`stderr: ${i}`),a&&d.push(a);let u=new Error(d.join(`
126
+ `));if(n&&typeof n=="object"){let c=n;typeof c.code=="number"&&(u.code=c.code),c.data!==void 0&&(u.data=c.data)}return u}function Mt(n){if(!Array.isArray(n))return;let e=[];for(let t of n){if(!t||typeof t!="object")continue;let s=t;if(typeof s.id!="string")continue;let r=typeof s.description=="string"?s.description:"",o=s.type==="agent"||s.type==="terminal"?s.type:void 0,i=typeof s.name=="string"?s.name:void 0,a=s._meta,d=a!==null&&typeof a=="object"&&!Array.isArray(a)?a:void 0;e.push({id:s.id,description:r,...o&&{type:o},...i!==void 0&&{name:i},...d&&{_meta:d}})}return e.length>0?e:void 0}function ve(n){if(typeof n!="string")return;let e=n.trim();return e.length>0?e:void 0}function Cu(n,e){let t=n.configOptions;if(Array.isArray(t))for(let s of t){if(!s||typeof s!="object"||Array.isArray(s))continue;let r=s;if(r.id===e)return r}}function Ts(n){return n.length>0?n:void 0}function Ps(n){return un(n,{nestedKey:"models",configId:"model",fromObject:e=>{let t=nt(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=nt(e.options);return t.length>0?t:void 0}})??[]}function _s(n){return un(n,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=vt(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=vt(e.options);return t.length>0?t:void 0}})??[]}function $s(n){return un(n,{nestedKey:"modes",configId:"mode",fromObject:e=>ve(e.currentModeId)??ve(e.currentMode)??ve(e.modeId)??ve(e.mode),fromConfig:e=>ve(e.currentValue)})}function xu(n){for(let e=n.length-1;e>=0;e--){let t=n[e];if(!t||t.method!=="session/update")continue;let s=t.params?.update;if(s?.sessionUpdate==="turn_complete"&&!(typeof s.messageId!="string"||s.messageId.length===0))return{index:e,messageId:s.messageId}}}async function ti(n){try{let e=await Ne.readFile(I.tuiHistoryFile(n),"utf8"),t=[];for(let s of e.split(`
127
+ `))if(s.length!==0)try{let r=JSON.parse(s);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function ri(n,e,t,s=new Date().toISOString(),r){let o=n.upstreamGenerations&&n.upstreamGenerations.length>0?[...n.upstreamGenerations]:n.upstreamSessionId?[{upstreamSessionId:n.upstreamSessionId,agentId:n.agentId}]:[],i=o[o.length-1];if(i&&i.upstreamSessionId===t){if(r!==void 0&&o.length>=2){let a=o[o.length-2];a&&a.cost===void 0&&(o[o.length-2]={...a,cost:r})}return o}return i&&i.endedAt===void 0&&(o[o.length-1]={...i,endedAt:s,...r!==void 0?{cost:r}:{}}),o.push({upstreamSessionId:t,agentId:e,startedAt:s}),o}async function Et(n){try{let e=await Ne.stat(I.historyFile(n));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function at(n,e){return n.interactive!==void 0?n.interactive:n.originatingClient?.name===sn?!1:e?!0:void 0}import{spawn as Mu}from"child_process";import*as fn from"fs";import*as Ae from"fs/promises";import*as pn from"path";import Eu from"pino-roll";var ln=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,s){if(e===78){let i=`exited with code 78 (unrecoverable); fix and run \`${s}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 \`${s}s start ${t}\``;return this.tripped_=a,{tripped:a}}return"restart"}reset(){this.recentExits=[],this.tripped_=void 0}get tripped(){return this.tripped_}};var Ru=1e3,Tu=6e4,Fs=3e3,dt=class{entries=new Map;stopping=!1;context;tokenRegistry;breakerOptions;restartBaseMs;restartCapMs;adapter;constructor(e,t,s,r={}){this.adapter=t,this.context=s,this.tokenRegistry=r.tokenRegistry,this.breakerOptions=r.breakerOptions,this.restartBaseMs=r.restartBaseMs??Ru,this.restartCapMs=r.restartCapMs??Tu;for(let o of e)this.entries.set(o.name,this.makeEntry(o))}setContext(e){this.context=e}reportVersion(e,t){let s=this.entries.get(e);s&&(s.version=t)}async start(){if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before start`);await Ae.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 s=t.child;if(s){try{s.kill("SIGTERM")}catch{}e.push(new Promise(r=>{if(s.exitCode!==null||s.signalCode!==null){r();return}let o=setTimeout(()=>{try{s.kill("SIGKILL")}catch{}r()},Fs);s.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 Tt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw Tt(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 Tt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let s=t.child;return s?(await this.terminate(t,s),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 Tt(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(s=>{t.failureReason=`spawn: ${s.message}`}),this.infoFor(t)}async unregister(e){let t=this.entries.get(e);if(!t)throw Tt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let s=t.child;s&&await this.terminate(t,s);try{t.logStream?.end()}catch{}this.entries.delete(e)}async terminate(e,t){if(t.exitCode!==null||t.signalCode!==null)return;let s=new Promise(o=>{e.exitWaiters.push(o)});try{t.kill("SIGTERM")}catch{}let r=setTimeout(()=>{try{t.kill("SIGKILL")}catch{}},Fs);typeof r.unref=="function"&&r.unref();try{await s}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 ln(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await Ae.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 s=this.adapter.paths.pidFile(t.name),r;try{let o=await Ae.readFile(s,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&Os(r)){try{process.kill(r,"SIGTERM")}catch{}let o=Date.now()+Fs;for(;Date.now()<o&&Os(r);)await new Promise(i=>setTimeout(i,50));if(Os(r))try{process.kill(r,"SIGKILL")}catch{}}await Ae.unlink(s).catch(()=>{})}}async spawn(e,t){if(this.stopping||e.manuallyStopped)return;let s=this.context;if(!s)throw new Error(`${this.managerName()}.spawn called before setContext`);let r=e.config,o=r.command.length>0?r.command:[r.name],i=pn.dirname(this.adapter.paths.logFile(r.name)),a;try{await Ae.mkdir(i,{recursive:!0}),a=await Eu({file:pn.join(i,`${r.name}.log`),size:"5m",mkdir:!0,symlink:!0,limit:{count:5}}),a.on("error",h=>{e.failureReason=`log stream: ${h.message}`})}catch(h){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${h.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})
128
+ `);let d=this.tokenRegistry?.mint(r.name,this.adapter.tokenRole)??s.serviceToken;e.processToken=d,e.version=void 0;let u={...Dt(),HYDRA_ACP_DAEMON_URL:s.daemonUrl,HYDRA_ACP_DAEMON_HOST:s.daemonHost,HYDRA_ACP_DAEMON_PORT:String(s.daemonPort),HYDRA_ACP_TOKEN:d,HYDRA_ACP_WS_URL:s.daemonWsUrl,HYDRA_ACP_HOME:s.hydraHome,[this.adapter.nameEnvVar]:r.name,...r.env},[c,...f]=o;if(c===void 0){a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} has empty command
129
+ `),a.end();return}let p=Z(c),l=[...f,...r.args].map(Z),m;try{m=Mu(p,l,{env:u,stdio:["ignore","pipe","pipe"],detached:!1})}catch(h){a.write(`[hydra-acp] failed to spawn ${r.name}: ${h.message}
130
+ `),a.end(),this.scheduleRestart(e,t);return}let g=h=>{try{a.write(typeof h=="string"?h:h.toString())}catch{}};if(m.stdout?.on("data",g),m.stderr?.on("data",g),typeof m.pid=="number")try{fn.writeFileSync(this.adapter.paths.pidFile(r.name),`${m.pid}
131
131
  `,{encoding:"utf8",mode:384})}catch(h){a.write(`[hydra-acp] failed to write pid file for ${r.name}: ${h.message}
132
- `)}e.child=g,e.logStream=a,e.pid=typeof g.pid=="number"?g.pid:void 0,e.startedAt=Date.now(),e.lastExitCode=void 0,g.on("error",h=>{a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} error: ${h.message}
133
- `)}),g.on("exit",(h,y)=>{try{an.unlinkSync(this.adapter.paths.pidFile(r.name))}catch{}a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} exited code=${h??"null"} signal=${y??"null"}
134
- `),e.child=void 0,e.pid=void 0,e.lastExitCode=typeof h=="number"?h:void 0,e.processToken&&(this.tokenRegistry?.revoke(r.name),e.processToken=void 0);let v=e.exitWaiters.splice(0);for(let S of v)S();if(this.stopping||e.manuallyStopped){try{a.end()}catch{}e.logStream=void 0;return}e.restartCount+=1;let w=e.breaker.recordExit(h,r.name,this.adapter.kind);if(typeof w=="object"){e.failureReason=w.tripped,a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} circuit breaker tripped: ${w.tripped}
135
- `);try{a.end()}catch{}e.logStream=void 0;return}this.scheduleRestart(e,t+1)})}scheduleRestart(e,t){if(this.stopping||e.manuallyStopped)return;let s=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}`})},s),typeof e.restartTimer.unref=="function"&&e.restartTimer.unref()}managerName(){return this.adapter.kind==="extension"?"ExtensionManager":"TransformerManager"}};function Es(n){try{return process.kill(n,0),!0}catch{return!1}}function Rt(n,e){return n.code=e,n}W();var lu={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:I.extensionsDir,logFile:I.extensionLogFile,pidFile:I.extensionPidFile}},cn=class extends it{constructor(e,t,s={}){super(e,lu,t,s)}};W();var fu={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:I.transformersDir,logFile:I.transformerLogFile,pidFile:I.transformerPidFile}},un=class extends it{connected=new Map;constructor(e,t,s={}){super(e,fu,t,s)}registerConnection(e,t,s){this.connected.set(e,{name:e,connection:t,intercepts:new Set(s)})}deregisterConnection(e){this.connected.delete(e)}resolveChain(e){let t=[];for(let s of e){let r=this.connected.get(s);r&&t.push(r)}return t}interestedIn(e){let t=[];for(let s of this.connected.values())s.intercepts.has(e)&&t.push(s);return t}};var ln=class{entries=new Map;changeHandlers=[];register(e,t,s){this.entries.set(e,{connection:t,commands:[...s]}),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,s]of this.entries)for(let r of s.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{}}};W();W();import*as Ms from"fs/promises";async function zi(n){await Ms.writeFile(I.pidFile(),JSON.stringify(n)+`
136
- `,{encoding:"utf8",mode:384})}W();import*as Mt from"fs/promises";import*as fn from"path";var Et=n=>{process.stderr.write(n+`
137
- `)};function Ps(n){Et=n??(e=>process.stderr.write(e+`
138
- `))}async function Ji(n,e){let t=pe();if(!t)return;let s=await n.load(),r=new Map;for(let d of s.agents)r.set(d.id,d.version??"current");let i=e.activeAgentVersions(),o=fn.join(I.agentsDir(),t),a;try{a=await Mt.readdir(o,{withFileTypes:!0})}catch(d){let u=d;if(u.code==="ENOENT")return;Et(`hydra-acp: prune: failed to read ${o}: ${u.message}`);return}for(let d of a){if(!d.isDirectory())continue;let u=d.name,c=r.get(u);if(c===void 0)continue;let f=i.get(u)??new Set,p=fn.join(o,u),l;try{l=await Mt.readdir(p,{withFileTypes:!0})}catch(g){Et(`hydra-acp: prune: failed to read ${p}: ${g.message}`);continue}for(let g of l){if(!g.isDirectory())continue;let m=g.name;if(m===c||f.has(m)||m.includes(".partial-"))continue;let h=fn.join(p,m);try{await Mt.rm(h,{recursive:!0,force:!0}),Et(`hydra-acp: pruned stale ${u} ${m} (${h})`)}catch(y){Et(`hydra-acp: prune: failed to remove ${h}: ${y.message}`)}}}}function Wi(n){let e,t=!1,s=0,r=(a,d)=>{n.logger&&n.logger[a](`agent-sync: ${d}`)},i=async()=>{let a=[];try{let c=await n.registry.load();for(let f of c.agents)await Vn(f)==="yes"&&a.push(f.id)}catch(c){return r("warn",`registry load failed: ${c.message}`),n.intervalMs}if(a.length===0)return n.intervalMs;let d=s%a.length;s=(s+1)%a.length;let u=a[d];try{let{synced:c,skipped:f}=await n.manager.syncFromAgent(u);r("info",`${u}: synced ${c.length}, skipped ${f}`)}catch(c){r("warn",`${u}: ${c.message}`)}return Math.max(1,Math.floor(n.intervalMs/a.length))},o=a=>{t||(e=setTimeout(()=>{i().then(d=>{o(d)}).catch(d=>{r("warn",`tick crashed: ${d.message}`),o(n.intervalMs)})},a),e.unref())};return o(n.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}async function Ts(n){let e=n.maxDeletions??200,t=(l,g)=>{n.logger&&n.logger[l](`session-gc: ${g}`)},s=Date.now(),r=n.maxAgeMs>0?s-n.maxAgeMs:Number.POSITIVE_INFINITY,i=await n.manager.list({includeNonInteractive:!0}).catch(l=>(t("warn",`manager.list failed: ${l.message}`),[])),o=[];for(let l of i){if(l.status!=="cold")continue;if((n.selection??"explicit")==="explicit"){if(l.interactive!==!1)continue}else if(l.interactive===!0)continue;let m=Date.parse(l.updatedAt);Number.isFinite(m)&&(n.maxAgeMs>0&&m>r||o.push({sessionId:l.sessionId,lastUsedMs:m}))}if(o.length===0)return n.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};o.sort((l,g)=>l.lastUsedMs-g.lastUsedMs);let a=o.slice(0,e),d=a[0]?.lastUsedMs,u=0,c=0;for(let{sessionId:l}of a)try{await n.manager.deleteRecord(l,"expired")&&(u+=1)}catch(g){c+=1,t("warn",`delete ${l} failed: ${g.message}`)}let f=o.length-a.length;if(n.verbose||u>0||c>0){let l=(n.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${u} ${l} session(s) older than ${pu(n.maxAgeMs)}`+(c>0?`; ${c} failed`:"")+(f>0?`; ${f} deferred to next sweep`:""))}let p={considered:o.length,deleted:u,failed:c,deferred:f};return d!==void 0&&(p.oldestLastUsedMs=d),p}function Qi(n){let e,t=!1,s=!1,r=i=>{t||(e=setTimeout(()=>{(async()=>{if(!s){s=!0;try{await Ts({manager:n.manager,maxAgeMs:n.maxAgeMs,selection:"unpromoted",...n.maxDeletionsPerSweep!==void 0?{maxDeletions:n.maxDeletionsPerSweep}:{},...n.logger?{logger:n.logger}:{}})}finally{s=!1}}})().catch(a=>{n.logger?.warn(`session-gc: sweep crashed: ${a.message}`)}).finally(()=>{r(n.intervalMs)})},i),e.unref())};return r(n.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}function pu(n){if(n<=0)return"any age";let e=n/(1440*60*1e3);if(e>=1)return`${e.toFixed(e>=10?0:1)}d`;let t=n/(3600*1e3);return`${t.toFixed(t>=10?0:1)}h`}import{createHash as mu}from"crypto";function _s(n){if(Array.isArray(n))return n.map(_s);if(n!==null&&typeof n=="object"){let e={};for(let t of Object.keys(n).sort())e[t]=_s(n[t]);return e}return n}function Gi(n){let{tui:e,...t}=n,s=JSON.stringify(_s(t));return mu("sha256").update(s).digest("hex").slice(0,16)}W();_e();import*as Yi from"path";import{createHash as gu,randomBytes as hu,timingSafeEqual as yu}from"crypto";var Xi="hydra_session_",wu=3600*24*30,Ki=12,vu=32,bu=50;function Su(){return Yi.join(I.home(),"session-tokens.json")}function Vi(n){return gu("sha256").update(n).digest("hex")}function Zi(n){return hu(n).toString("hex")}function Iu(){return Zi(Ki).slice(0,Ki*2)}function ku(){return`${Xi}${Zi(vu)}`}var pn=class n{records=new Map;writeTimer=null;writeInflight=null;filePath;constructor(e,t){this.filePath=t;for(let s of e)this.records.set(s.hash,s)}static async load(){let e=[],t=Su(),s=await ue(t);s&&Array.isArray(s.records)&&(e=s.records.filter(Au));let r=new n(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=ku(),s=Vi(t),r=Iu(),i=new Date,o=e.ttlSec&&e.ttlSec>0?e.ttlSec:wu,a=new Date(i.getTime()+o*1e3),d={id:r,hash:s,label:e.label,createdAt:i.toISOString(),expiresAt:a.toISOString(),lastUsedAt:i.toISOString()};return this.records.set(s,d),this.scheduleWrite(),{id:r,token:t,expiresAt:d.expiresAt}}async verify(e){if(typeof e!="string"||!e.startsWith(Xi))return;let t=Vi(e),s=this.records.get(t);if(!s)return;let r=Buffer.from(s.hash,"hex"),i=Buffer.from(t,"hex");if(r.length!==i.length||!yu(r,i))return;let o=new Date;if(new Date(s.expiresAt).getTime()<=o.getTime()){this.records.delete(t),this.scheduleWrite();return}return s.lastUsedAt=o.toISOString(),this.scheduleWrite(),s.id}async revoke(e){for(let[t,s]of this.records)if(s.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:s,expiresAt:r,lastUsedAt:i})=>({id:e,label:t,createdAt:s,expiresAt:r,lastUsedAt:i})).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}sweepExpired(e=new Date){let t=0;for(let[s,r]of this.records)new Date(r.expiresAt).getTime()<=e.getTime()&&(this.records.delete(s),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(()=>{})},bu))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>ce(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 Au(n){if(!n||typeof n!="object")return!1;let e=n;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 eo="Bearer ",mn=class{constructor(e){this.token=e}token;async validate(e){return Cu(e,this.token)?"service":void 0}},gn=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},hn=class{constructor(e){this.validators=e}validators;async validate(e){for(let t of this.validators){let s=await t.validate(e);if(s!==void 0)return s}}};function to(n){return async function(t,s){let r=t.headers.authorization;if(!r||!r.startsWith(eo)){s.code(401).send({error:"Missing bearer token"});return}let i=r.slice(eo.length).trim(),o=await n.validator.validate(i);if(!o){s.code(403).send({error:"Invalid token"});return}t.authIdentity=o}}function no(n){let e=n.headers["sec-websocket-protocol"],t=Array.isArray(e)?e.join(","):e;if(t)for(let s of t.split(",")){let r=s.trim(),i="hydra-acp-token.";if(r.startsWith(i))return r.slice(i.length)}if(n.url)try{let r=new URL(n.url,"http://localhost").searchParams.get("token");if(r)return r}catch{return}}var yn=class{tokens=new Map;mint(e,t){let s=On();return this.tokens.set(s,{name:e,kind:t}),s}revoke(e){for(let[t,s]of this.tokens)s.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}`}};function Cu(n,e){if(n.length!==e.length)return!1;let t=0;for(let s=0;s<n.length;s+=1)t|=n.charCodeAt(s)^e.charCodeAt(s);return t===0}var wn=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(),s=this.entries.get(e);if(!s||t-s.windowStart>this.windowMs){this.entries.set(e,{fails:1,windowStart:t});return}s.fails+=1}recordSuccess(e){this.entries.delete(e)}sweepExpired(){let e=Date.now();for(let[t,s]of this.entries)e-s.windowStart>this.windowMs&&this.entries.delete(t)}};import*as Hs from"fs";import*as Ro from"os";import*as Eo from"path";import*as js from"readline";W();function Fs(n){return Math.floor(n/4)}function so(n){let e=0,t=new Map;for(let s of n){let r=s.params;if(!r||typeof r!="object")continue;let i=r.update;if(!i||typeof i!="object")continue;let o=i;switch(o.sessionUpdate){case"user_message_chunk":case"agent_message_chunk":case"agent_thought_chunk":e+=Ne(o.content);break;case"tool_call":case"tool_call_update":{let a=typeof o.toolCallId=="string"?o.toolCallId:"",d=xu(o),u=t.get(a)??0;d>u&&t.set(a,d);break}default:break}}for(let s of t.values())e+=s;return e}function xu(n){let e=0;return typeof n.title=="string"&&(e+=n.title.length),e+=vn(n.rawInput),e+=Ne(n.content),e+=vn(n.rawOutput),e}function vn(n){if(n==null)return 0;if(typeof n=="string")return n.length;if(typeof n=="number"||typeof n=="boolean")return String(n).length;if(Array.isArray(n)){let e=0;for(let t of n)e+=vn(t);return e}if(typeof n=="object"){let e=n.bytes;if(typeof n.__hydraBlob=="string"&&typeof e=="number")return e;let t=0;for(let s of Object.values(n))t+=vn(s);return t}return 0}function Ne(n){if(n==null)return 0;if(typeof n=="string")return n.length;if(Array.isArray(n)){let t=0;for(let s of n)t+=Ne(s);return t}if(typeof n!="object")return 0;let e=n;return typeof e.__hydraBlob=="string"&&typeof e.bytes=="number"?e.bytes:e.text!==void 0?Ne(e.text):e.type==="diff"?Ne(e.oldText)+Ne(e.newText):e.content!==void 0?Ne(e.content):0}function ro(n){if(n.compactionInFlight||n.totalEntries===0)return!1;let e,t;if(typeof n.agentReportedUsed=="number"&&typeof n.agentReportedSize=="number"&&n.agentReportedSize>0)e=n.agentReportedUsed/n.agentReportedSize,t=!0;else{let r=Fs(n.unsummarizedChars),i=n.currentModel!==void 0?n.config.modelContextWindows[n.currentModel]??n.config.absoluteFallback:n.config.absoluteFallback;e=r/i,t=!1}if(t&&e>=n.config.hardCeilingFraction)return!0;let s=n.nowMs-n.lastActivityMs;return e>=n.config.contextFraction&&s>=n.config.idleBeforePromptMs}W();import{posix as Ru}from"path";import Eu from"strip-ansi";function Pt(n){if(!n||typeof n!="object")return;let e=n;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}var Mu=/[\x00-\x08\x0b-\x1f\x7f]/g;function ae(n){return Eu(n).replace(Mu,"")}function G(n){return ae(n).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function ao(n,e={}){if(!n||typeof n!="object")return null;let t=n,s=t.sessionUpdate??t.kind;if(typeof s!="string")return null;switch(s){case"agent_message_chunk":return Nu(t);case"agent_thought_chunk":case"agent_thought":return Hu(t);case"user_message_chunk":return ju(t);case"prompt_received":return Bu(t);case"tool_call":return Uu(t,e);case"tool_call_update":return Ju(t,e);case"plan":return Ku(t);case"current_mode_update":return Vu(t);case"current_model_update":return Yu(t);case"turn_complete":return Xu(t);case"usage_update":return Ou(t);case"available_commands_update":return Fu(t);case"available_modes_update":return $u(t);case"session_info_update":return Tu(t);case"config_option_update":return Pu(t);default:return{kind:"unknown",sessionUpdate:s,raw:n}}}function Pu(n){let e=n.configOptions;if(!Array.isArray(e))return null;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s;if(typeof r.id!="string"||typeof r.currentValue!="string"||!Array.isArray(r.options))continue;let i=[];for(let o of r.options){if(!o||typeof o!="object")continue;let a=o;typeof a.value=="string"&&i.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:i,...typeof r.category=="string"?{category:r.category}:{}})}return{kind:"config-options",options:t}}function Tu(n){let e=Q(n,"title"),t=e!==void 0?G(e):void 0,s=n._meta,r,i;if(s&&typeof s=="object"&&!Array.isArray(s)){let a=s["hydra-acp"];if(a&&typeof a=="object"&&!Array.isArray(a)){let d=a.agentId;if(typeof d=="string"&&(r=d),"pendingAgentSwap"in a){let u=a.pendingAgentSwap;typeof u=="string"?i=u:u===null&&(i=null)}}}if(t===void 0&&r===void 0&&i===void 0)return null;let o={kind:"session-info"};return t!==void 0&&(o.title=t),r!==void 0&&(o.agentId=r),i!==void 0&&(o.pendingAgentSwap=i),o}function _u(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(!t||typeof t!="object")continue;let s=t;if(typeof s.name!="string"||s.name.length===0)continue;let r=s.name.startsWith("/")?s.name:`/${s.name}`,i={name:G(r)};typeof s.description=="string"&&(i.description=G(s.description)),e.push(i)}return e}function Fu(n){let e=n.availableCommands??n.commands;return Array.isArray(e)?{kind:"available-commands",commands:_u(e)}:null}function $u(n){let e=n.availableModes;if(!Array.isArray(e))return null;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s;if(typeof r.id!="string"||r.id.length===0)continue;let i={id:G(r.id)};typeof r.name=="string"&&(i.name=G(r.name)),typeof r.description=="string"&&(i.description=G(r.description)),t.push(i)}return{kind:"available-modes",modes:t}}function Ou(n){let e={kind:"usage-update"};if(typeof n.used=="number"&&(e.used=n.used),typeof n.size=="number"&&(e.size=n.size),n.cost&&typeof n.cost=="object"){let t=n.cost;typeof t.amount=="number"&&(e.costAmount=t.amount),typeof t.currency=="string"&&(e.costCurrency=t.currency)}return e}function Nu(n){let e=Tt(n.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:Pt(n)}}function Hu(n){let e=typeof n.text=="string"?ae(n.text):Tt(n.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:Pt(n)}}function ju(n){let e=n._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){let s=e["hydra-acp"];if(s&&typeof s=="object"&&!Array.isArray(s)&&s.compatFor==="prompt_received")return null}let t=Tt(n.content);return t===null?null:{kind:"user-text",text:t}}function Bu(n){let e=Zu(n.prompt);return e===null?null:{kind:"user-text",text:e}}function co(n){return n?n.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function io(n){if(typeof n=="string")return{text:n};if(n&&typeof n=="object"&&!Array.isArray(n)){let e=n;if(typeof e.__hydraBlob=="string")return{ref:{hash:e.__hydraBlob,bytes:typeof e.bytes=="number"?e.bytes:0}}}}function bn(n){let e=n.content;if(Array.isArray(e))for(let s of e){if(!s||typeof s!="object")continue;let r=s;if(r.type!=="diff")continue;let i=io(r.oldText),o=io(r.newText);if(i===void 0&&o===void 0)continue;let a=typeof r.path=="string"?r.path:void 0;return{...a!==void 0?{path:a}:{},oldText:i?.text??"",newText:o?.text??"",...i?.ref?{oldRef:i.ref}:{},...o?.ref?{newRef:o.ref}:{}}}let t=n.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let s=t,r=typeof s.file_path=="string"?s.file_path:typeof s.path=="string"?s.path:void 0;if(typeof s.old_string=="string"&&typeof s.new_string=="string")return{...r!==void 0?{path:r}:{},oldText:s.old_string,newText:s.new_string};if(typeof s.content=="string")return{...r!==void 0?{path:r}:{},oldText:"",newText:s.content}}return null}function uo(n){let e=n.rawInput;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e.plan;return typeof t!="string"||t.length===0?null:ae(t)}function Uu(n,e={}){let t=Q(n,"toolCallId")??Q(n,"id");if(!t)return null;let s=Q(n,"title")??Q(n,"name")??Q(n,"label")??"tool call",r=Q(n,"name")??Q(n,"title");if(co(r)){let g=uo(n);if(g!==null){let m=Q(n,"status"),h={kind:"exit-plan-mode",toolCallId:t,plan:g};return m!==void 0&&(h.status=m),h}}let i=po(G(s),n,e),o=Q(n,"status"),a=Q(n,"kind"),d={kind:"tool-call",toolCallId:t,title:i};o!==void 0&&(d.status=o),a!==void 0&&(d.rawKind=a);let u=bn(n);u!==null&&(d.editDiff=u);let c=fo(n);c!==void 0&&(d.detail=c);let f=$s(n);f!==void 0&&(d.detailFull=f);let p=lo(n);p!==void 0&&(d.locations=p);let l=Pt(n);return l!==void 0&&(d.workerTaskId=l),d}function lo(n){let e=n.locations;if(!Array.isArray(e))return;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s;if(typeof r.path!="string"||r.path.length===0)continue;let i={path:r.path};typeof r.line=="number"&&Number.isFinite(r.line)&&r.line>=1&&(i.line=Math.floor(r.line)),t.push(i)}return t.length>0?t:void 0}var oo=64;function fo(n){let e=$s(n);if(e===void 0)return;let t=G(e),s=n.rawInput;return s&&typeof s.command=="string"?qu(t,oo):zu(t,oo)}function $s(n){let e=n.rawInput;if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.command=="string"&&t.command.trim().length>0)return ae(t.command).trim().replace(/^cd\s+\S+\s+&&\s+/,"");let s=typeof t.file_path=="string"?t.file_path:typeof t.filePath=="string"?t.filePath:typeof t.path=="string"?t.path:void 0;if(s!==void 0&&s.length>0)return Te(G(s))}if(Array.isArray(n.locations)){for(let t of n.locations)if(t&&typeof t=="object"){let s=t.path;if(typeof s=="string"&&s.length>0)return Te(G(s))}}}var Du=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function Lu(n){for(let e of Du)if(n.startsWith(e))return!0;return!1}function po(n,e,t={}){if(n.length===0)return n;if(n.startsWith("/"))return Te(n);if(n.startsWith("~")||!n.includes("/")||/\s/.test(n))return n;let s=e.rawInput;if(s&&typeof s=="object"&&!Array.isArray(s)){let r=s,i=[r.file_path,r.filePath,r.path];for(let o of i)if(!(typeof o!="string"||o.length===0)&&(o===`/${n}`||o.endsWith(`/${n}`)||o===n))return Te(o)}return Lu(n)?Te(`/${n}`):t.cwd&&t.cwd.length>0?Te(Ru.resolve(t.cwd,n)):n}function qu(n,e){return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function zu(n,e){if(n.length<=e)return n;let t=n.slice(-(e-1)),s=t.indexOf("/");return s>=0&&s<e/2?`\u2026${t.slice(s)}`:`\u2026${t}`}function Ju(n,e={}){let t=Q(n,"toolCallId")??Q(n,"id");if(!t)return null;let s=Q(n,"title"),r=s!==void 0?po(G(s),n,e):void 0,i=Q(n,"status"),o=bn(n),a=fo(n),d=Wu(n);if(!(r!==void 0||o!==null||a!==void 0||d!==void 0||i==="completed"||i==="failed"||i==="rejected"||i==="cancelled"))return null;let c=Q(n,"name")??s;if(co(c)){let m={kind:"exit-plan-mode",toolCallId:t},h=uo(n);return h!==null&&(m.plan=h),i!==void 0&&(m.status=i),m}let f={kind:"tool-call-update",toolCallId:t};r!==void 0&&(f.title=r),a!==void 0&&(f.detail=a);let p=$s(n);p!==void 0&&(f.detailFull=p);let l=lo(n);if(l!==void 0&&(f.locations=l),d!==void 0&&(f.resultSummary=d),i!==void 0&&(f.status=i),o!==null&&(f.editDiff=o),i==="failed"){let m=Qu(n);m!==null&&(f.errorText=m),Gu(n,m)&&(f.upstreamInterrupted=!0)}let g=Pt(n);return g!==void 0&&(f.workerTaskId=g),f}function Wu(n){if(!n||typeof n!="object")return;let e=n.rawOutput;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,s=c=>{let f=t[c];return typeof f=="number"&&Number.isFinite(f)?f:void 0},r=(c,f,p=`${f}s`)=>`${c} ${c===1?f:p}`,i=[],o=s("totalMatches");o!==void 0&&i.push(r(o,"match","matches"));let a=s("totalFiles");a!==void 0&&i.push(r(a,"file"));let d=s("referenceCount");d!==void 0&&i.push(r(d,"reference")),i.length>0&&t.truncated===!0&&i.push("truncated");let u=s("exitCode");return u!==void 0&&u!==0&&i.push(`exit ${u}`),i.length>0?i.join(", "):void 0}function Qu(n){let e=n.content;if(Array.isArray(e))for(let s of e){if(!s||typeof s!="object")continue;let i=Tt(s.content);if(i!==null&&i.length>0)return i}let t=n.rawOutput;if(t&&typeof t=="object"){let s=t.error;if(typeof s=="string"&&s.length>0)return ae(s)}return null}function Gu(n,e){let t=n.rawOutput;if(t&&typeof t=="object"){let s=t.metadata;if(s&&typeof s=="object"&&s.interrupted===!0)return!0}return!!(e!==null&&e.toLowerCase().includes("tool execution aborted"))}function Ku(n){let e=n.entries;if(!Array.isArray(e)||e.length===0)return null;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s,i=typeof r.content=="string"?G(r.content):void 0;if(!i)continue;let o={content:i};typeof r.status=="string"&&(o.status=r.status),typeof r.priority=="string"&&(o.priority=r.priority),t.push(o)}return{kind:"plan",entries:t}}function Vu(n){let e=Q(n,"currentModeId")??Q(n,"currentMode")??Q(n,"mode");return e?{kind:"mode-changed",mode:G(e)}:null}function Yu(n){let e=Q(n,"currentModel")??Q(n,"model");if(!e)return null;let t=n.availableModels,s=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:G(e),...s&&s.length>0?{availableModels:s}:{}}}function Xu(n){let e=Q(n,"stopReason"),t=n._meta,s=t?.["hydra-acp"]?.amended!==void 0&&t["hydra-acp"].amended!==null,r={kind:"turn-complete"};return e!==void 0&&(r.stopReason=e),s&&(r.amended=!0),r}function Tt(n){if(typeof n=="string")return ae(n);if(!n||typeof n!="object")return null;let e=n;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?ae(e.text):null}function Zu(n){if(!Array.isArray(n))return null;let e=[];for(let t of n){let s=Tt(t);s!==null&&e.push(s)}return e.length===0?null:e.join("")}function Q(n,e){let t=n[e];return typeof t=="string"?t:void 0}function mo(n){let e=new Map,t=new Map;for(let r of n){let o=r.params?.update;if(!o||typeof o!="object")continue;let a=o.sessionUpdate;if(a!=="tool_call"&&a!=="tool_call_update")continue;let d=typeof o.toolCallId=="string"&&o.toolCallId.length>0?o.toolCallId:void 0,u=tl(o);if(u.length===0)continue;let c=u;if(d!==void 0){let f=e.get(d)??[],p=[];for(let l of u)f.some(g=>g.path===l.path&&g.oldText===l.oldText&&g.newText===l.newText)||p.push(l);if(p.length===0)continue;e.set(d,[...f,...p]),c=p}for(let f of c)el(t,f)}let s=[];for(let[r,i]of t)s.push({path:r,hunks:i.hunks,created:i.created});return s}function go(n){let e=[];for(let t of n){let s=-1;for(let i=e.length-1;i>=0;i--)if(e[i].newText===t.oldText){s=i;break}if(s===-1){e.push(t);continue}let r=e[s];e.splice(s,1,{oldText:r.oldText,newText:t.newText})}return e}function el(n,e){let t={oldText:e.oldText,newText:e.newText},s=n.get(e.path);if(s===void 0){n.set(e.path,{hunks:[t],created:e.oldText.length===0});return}s.hunks.push(t)}function tl(n){let e=[],t=n.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let i=t,o=typeof i.file_path=="string"?i.file_path:typeof i.path=="string"?i.path:void 0,a=i.edits;if(o!==void 0&&Array.isArray(a)){for(let d of a){if(!d||typeof d!="object")continue;let u=d,c=typeof u.old_string=="string"?u.old_string:void 0,f=typeof u.new_string=="string"?u.new_string:void 0;c===void 0||f===void 0||e.push({path:o,oldText:c,newText:f})}if(e.length>0)return e}}let s=n.content;if(Array.isArray(s)){for(let i of s){if(!i||typeof i!="object")continue;let o=i;if(o.type!=="diff")continue;let a=typeof o.path=="string"?o.path:void 0;if(a===void 0)continue;let d=typeof o.oldText=="string"?o.oldText:"",u=typeof o.newText=="string"?o.newText:"";e.push({path:a,oldText:d,newText:u})}if(e.length>0)return e}let r=bn(n);return r&&r.path&&e.push({path:r.path,oldText:r.oldText,newText:r.newText}),e}function yo(n,e={}){let t=nl(n),s=sl(t),r=[];rl(r,n),il(r,t,s,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let i=r.join(`
139
- `);return i.endsWith(`
140
- `)||(i+=`
141
- `),i}function nl(n){let e=[];for(let t of n.history){if(t.method!=="session/update")continue;let s=t.params;if(!s||typeof s!="object")continue;let r=ao(s.update,{cwd:n.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function sl(n){let e=new Map;for(let{event:t}of n){if(t.kind==="tool-call"){let s=e.get(t.toolCallId);e.set(t.toolCallId,{title:t.title,status:t.status??s?.status??"pending"});continue}if(t.kind==="tool-call-update"){let s=e.get(t.toolCallId)??{title:"tool call",status:"pending"};e.set(t.toolCallId,{title:t.title??s.title,status:t.status??s.status})}}return e}function rl(n,e){let t=e.session,s=ii(t.sessionId),r=t.title?.trim()||`Hydra session ${s}`;n.push(`# ${ot(r)}`),n.push("");let i=[];i.push(`- **Session:** \`${s}\` (lineage \`${t.lineageId}\`)`);let o=[t.agentId];t.currentModel&&o.push(`model: ${t.currentModel}`),t.currentMode&&o.push(`mode: ${t.currentMode}`),i.push(`- **Agent:** ${o.filter(Boolean).join(" \xB7 ")}`),i.push(`- **Cwd:** ${t.cwd}`),i.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 c=a.size!==void 0?`${Os(a.size)}`:void 0;d.push(c?`${Os(a.used)} / ${c} tokens`:`${Os(a.used)} tokens`)}let u=Ss(a);if(u!==void 0){let c=a.costCurrency??"USD";d.push(`$${u.toFixed(2)} ${c}`)}i.push(`- **Usage:** ${d.join(" \xB7 ")}`)}n.push(i.join(`
142
- `)),n.push("")}function il(n,e,t,s){let{includeTools:r,includeThoughts:i}=s;if(!e.some(m=>ol(m.event,i))){n.push("_No conversation history recorded._"),n.push("");return}let o=0,a="",d="",u=[],c=new Set,f=!1,p=()=>{if(u.length!==0){for(let m of u)n.push(m);n.push(""),u=[]}},l=()=>{p(),d.length>0&&(ho(n,d.trimEnd(),"*"),n.push(""),d=""),a.length!==0&&(n.push(a.trimEnd()),n.push(""),a="")},g=()=>{f||(f=!0)};for(let{event:m}of e)switch(m.kind){case"user-text":{l(),n.push("---"),n.push(""),o+=1,ho(n,m.text,"**"),n.push(""),f=!0;break}case"agent-text":g(),a+=m.text;break;case"agent-thought":{if(!i)break;g(),a.length>0&&(n.push(a.trimEnd()),n.push(""),a=""),d+=m.text;break}case"tool-call":{if(!r||(g(),(a.length>0||d.length>0)&&l(),c.has(m.toolCallId)))break;c.add(m.toolCallId);let h=t.get(m.toolCallId)??{title:m.title,status:m.status??"pending"};u.push(`- ${dl(h.status)} ${al(h)}`);break}case"tool-call-update":break;case"plan":{g(),l(),n.push("**Plan:**"),n.push("");for(let h of m.entries){let y=h.status==="completed"?"[x]":"[ ]";n.push(`- ${y} ${ot(h.content)}`)}n.push("");break}case"mode-changed":g(),l(),n.push(`_mode: ${ot(m.mode)}_`),n.push("");break;case"model-changed":g(),l(),n.push(`_model: ${ot(m.model)}_`),n.push("");break;case"turn-complete":l();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}l()}function ol(n,e){switch(n.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 al(n){let e=n.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${ot(n.title)}${t}`}function dl(n){switch(n){case"completed":return"\u2713";case"failed":return"\u2717";case"cancelled":case"rejected":return"\u2298";case"in_progress":return"\u21BB";default:return"\xB7"}}function ho(n,e,t){let s=e.split(/\n\s*\n/);for(let r=0;r<s.length;r++){let i=s[r];if(i.trim().length===0)continue;let o=i.split(`
143
- `);for(let a=0;a<o.length;a++){let d=o[a],u=ot(d);n.push(a===0&&a===o.length-1?`${t}${u}${t}`:a===0?`${t}${u}`:a===o.length-1?`${u}${t}`:u)}r<s.length-1&&n.push("")}}function ot(n){return n.replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Os(n){return n.toLocaleString("en-US")}function wo(n){return n==="127.0.0.1"||n==="::1"||n==="localhost"||n==="[::1]"}function cl(n){let e=n.trim();if(e.length===0)return{operator:"OR",terms:[]};let t=/\w+:"[^"]*"|"[^"]*"|\S+/g,s=[],r;for(;(r=t.exec(e))!==null;)s.push(r[0]);let i="OR",o=!1,a=!1,d=[];for(let c of s){let f=c.toUpperCase();f==="AND"?o=!0:f==="OR"?a=!0:d.push(c)}o?i="AND":a&&(i="OR");let u=d.map(c=>ul(c)).filter(c=>c.term.length>0);return{operator:i,terms:u}}function ul(n){let e=/^(\w+):"([^"]*)"$/.exec(n);if(e)return{scope:vo(e[1]),term:e[2]};let t=/^"([^"]*)"$/.exec(n);if(t)return{scope:"all",term:t[1]};let s=/^(prompt|response|tool):([\s\S]*)$/i.exec(n);return s?{scope:vo(s[1]),term:s[2].trim()}:{scope:"all",term:n.trim()}}function vo(n){switch(n.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";default:return"all"}}function ll(n,e){return n==="all"?!0:n==="user"?e==="user":n==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var fl=5,pl=200,In=72,ml=24,gl=512;function Io(n){return Number.isFinite(n)?Math.max(ml,Math.min(gl,Math.floor(n))):In}async function ko(n,e,t={}){let s=cl(e);if(s.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??fl,i=t.maxSessions??pl,o=Io(t.snippetWidth??In),a=t.sessionIds?new Set(t.sessionIds):null,d=await n.list(),u=a?d.filter(p=>a.has(p.sessionId)):d,c=[],f=!1;for(let p of u){if(c.length>=i){f=!0;break}let l=await n.loadHistory(p.sessionId,{tools:"references"}).catch(()=>[]),g=hl(l,s,r,o);if(g.snippets.length===0)continue;let m={sessionId:p.sessionId,cwd:p.cwd,status:p.status,updatedAt:p.updatedAt,totalMatches:g.totalMatches,snippets:g.snippets};p.title!==void 0&&(m.title=p.title),c.push(m)}return{query:e,truncated:f,results:c}}function hl(n,e,t,s=In){if(e.terms.length===0)return{totalMatches:0,snippets:[]};let r=0,i=[],o=Math.max(1,Math.floor(t/e.terms.length)),a=[];for(let{scope:d,term:u}of e.terms){let c=yl(n,u,d,t,s);if(e.operator==="AND"&&c.totalMatches===0)return{totalMatches:0,snippets:[]};r+=c.totalMatches,i.push(...c.snippets.slice(0,o)),a.push(...c.snippets.slice(o))}for(let d of a){if(i.length>=t)break;i.push(d)}return{totalMatches:r,snippets:i.slice(0,t)}}function yl(n,e,t,s,r){let i=e.toLowerCase(),o=0,a=[];for(let d of n){let u=wl(d).filter(c=>ll(t,c.kind));for(let c of u){let f=c.text.toLowerCase(),p=f.indexOf(i);if(p===-1)continue;let l=0;for(;p!==-1;)l++,p=f.indexOf(i,p+i.length);if(o+=l,a.length<s){let g=f.indexOf(i),m={kind:c.kind,text:Al(c.text,g,i.length,r),recordedAt:d.recordedAt};c.toolName!==void 0&&(m.toolName=c.toolName),a.push(m)}}}return{totalMatches:o,snippets:a}}function wl(n){if(n.method!=="session/update")return[];let e=n.params;if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return[];let s=t,r=typeof s.sessionUpdate=="string"?s.sessionUpdate:s.kind;if(typeof r!="string")return[];switch(r){case"agent_message_chunk":{let i=Sn(s.content);return i?[{kind:"agent",text:i}]:[]}case"agent_thought":case"agent_thought_chunk":{let i=typeof s.text=="string"?ae(s.text):Sn(s.content);return i?[{kind:"thought",text:i}]:[]}case"user_message_chunk":{if(Il(s))return[];let i=Sn(s.content);return i?[{kind:"user",text:i}]:[]}case"prompt_received":{let i=kl(s.prompt);return i?[{kind:"user",text:i}]:[]}case"tool_call":case"tool_call_update":return vl(s);default:return[]}}function vl(n){let e=bo(n,"name"),t=bo(n,"title"),s=[];if(t!==void 0){let a=G(t);if(a.length>0){let d={kind:"tool",text:a};e!==void 0&&(d.toolName=e),s.push(d)}}if(e!==void 0&&e!==t){let a=G(e);a.length>0&&s.push({kind:"tool",toolName:e,text:a})}let r=n.rawInput;if(r&&typeof r=="object"){let a=So(r);if(a.length>0){let d={kind:"tool-input",text:G(a)};e!==void 0&&(d.toolName=e),s.push(d)}}let i=n.locations;if(Array.isArray(i)&&i.length>0){let a=So(i);if(a.length>0){let d={kind:"tool-input",text:G(a)};e!==void 0&&(d.toolName=e),s.push(d)}}let o=bl(n);if(o!==null){let a={kind:"tool",text:o};e!==void 0&&(a.toolName=e),s.push(a)}return s}function bl(n){if(!Sl(n.status))return null;let e=n.content;if(Array.isArray(e))for(let s of e){if(!s||typeof s!="object")continue;let i=s.content;if(!i||typeof i!="object")continue;let o=i;if(o.type==="text"&&typeof o.text=="string"){let a=G(o.text);if(a.length>0)return a}}let t=n.rawOutput;if(t&&typeof t=="object"){let s=t.error;if(typeof s=="string"){let r=G(s);if(r.length>0)return r}}return null}function Sl(n){return n==="failed"||n==="rejected"||n==="cancelled"}function Il(n){let e=n._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 Sn(n){if(typeof n=="string")return ae(n);if(!n||typeof n!="object"||Array.isArray(n))return"";let e=n;return typeof e.text=="string"?ae(e.text):""}function kl(n){if(!Array.isArray(n))return"";let e=[];for(let t of n){let s=Sn(t);s.length>0&&e.push(s)}return e.join("")}function bo(n,e){let t=n[e];return typeof t=="string"?t:void 0}function So(n){try{return JSON.stringify(n)}catch{return""}}function Al(n,e,t,s=In){let r=n.replace(/\s+/g," ").trim();if(r.length===0)return"";let i=r.toLowerCase(),o=n.slice(e,e+t).toLowerCase().replace(/\s+/g," ").trim(),a=o.length>0?i.indexOf(o):0;a===-1&&(a=0);let d=Io(s),u=Math.max(0,d-o.length),c=Math.floor(u/2),f=Math.min(c,a),p=Math.min(u-f,r.length-(a+o.length)),l=Math.max(0,a-(u-p)),g=Math.min(r.length,a+o.length+p),m=l>0?"\u2026":"",h=g<r.length?"\u2026":"";return`${m}${r.slice(l,g)}${h}`}import{randomBytes as Co}from"crypto";function Ao(n){let e=Co(32).toString("hex");return n.tokenRegistry.reserve(e).complete(n.session),n.session.onClose(()=>{n.tokenRegistry.unbind(e)}),{name:n.name,type:"http",url:`${n.getOrigin()}/mcp/${n.name}`,headers:[{name:"Authorization",value:`Bearer ${e}`}]}}function Ns(n){if(n.deps.mcpTokenRegistry===void 0||n.deps.getDaemonOrigin===void 0)return;let e=n.deps.mcpTokenRegistry,t=n.deps.getDaemonOrigin;return async s=>{let r=[...n.baselineMcpServers??[]];n.stdinEnabled&&r.push(Ao({name:"hydra-acp-stdin",session:s,tokenRegistry:e,getOrigin:t})),r.push(Ao({name:"hydra-acp-recall",session:s,tokenRegistry:e,getOrigin:t}));let i=at(n.deps);return i!==void 0&&(i.bindToSession(s),r=[...r,...i.descriptors]),r}}function at(n){if(n.extensionMcp===void 0||n.mcpTokenRegistry===void 0||n.getDaemonOrigin===void 0)return;let e=n.extensionMcp.list();if(e.length===0)return;let t=Co(32).toString("hex"),s=n.mcpTokenRegistry.reserve(t),r=n.getDaemonOrigin(),i=e.map(a=>({name:a,type:"http",url:`${r}/mcp/${a}`,headers:[{name:"Authorization",value:`Bearer ${t}`}]})),o=n.mcpTokenRegistry;return{descriptors:i,bindToSession:a=>{s.complete(a),a.onClose(()=>{o.unbind(t)})},abandon:a=>s.abandon(a)}}var kn=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function xo(n){if(n.publicHost&&n.publicHost.length>0)return n.publicHost;if(n.host&&!wo(n.host))return n.port!==void 0?`${n.host}:${n.port}`:n.host}function Mo(n,e,t,s={}){n.get("/v1/sessions",async u=>{let c=u.query,f=c?.includeNonInteractive==="1"||c?.includeNonInteractive==="true",p=c?.status==="warm"||c?.status==="cold"?c.status:void 0;return{sessions:await e.list({cwd:c?.cwd,includeNonInteractive:f,...p?{status:p}:{}})}}),n.get("/v1/sessions/:id",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=await e.getOne(p);return l||(c.code(404).send({error:"session not found"}),c)}),n.post("/v1/sessions/search",async(u,c)=>{let f=u.body??{},p=typeof f.q=="string"?f.q:"";if(p.trim().length===0)return c.code(400).send({error:"q is required"}),c;let g={sessionIds:Array.isArray(f.sessionIds)?f.sessionIds.filter(h=>typeof h=="string"&&h.length>0):void 0};return typeof f.snippetWidth=="number"&&(g.snippetWidth=f.snippetWidth),await ko(e,p,g)}),n.post("/v1/sessions",async(u,c)=>{let f=u.body??{},p=Z(f.cwd??t.cwd),l=f.agentId??t.agentId,g=at(s),m=g!==void 0?[...f.mcpServers??[],...g.descriptors]:f.mcpServers;try{let h=await e.create({cwd:p,agentId:l,mcpServers:m});g!==void 0&&g.bindToSession(h),c.code(201).send({sessionId:h.sessionId,agentId:h.agentId,cwd:h.cwd})}catch(h){g!==void 0&&g.abandon(h instanceof Error?h:void 0),c.code(500).send({error:h.message})}}),n.post("/v1/sessions/collect",async(u,c)=>{let f=u.body??{},p=typeof f.maxAgeDays=="number"&&f.maxAgeDays>0?f.maxAgeDays*24*60*60*1e3:0,l=typeof f.limit=="number"&&f.limit>0?f.limit:1e3,g=f.selection==="explicit"||f.selection==="unpromoted"?f.selection:"unpromoted";try{let m=await Ts({manager:e,maxAgeMs:p,maxDeletions:l,selection:g,verbose:!1});c.code(200).send(m)}catch(m){c.code(500).send({error:m.message})}}),n.post("/v1/sessions/:id/kill",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(l){l.close({deleteRecord:!1}).catch(()=>{}),c.code(202).send();return}if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}c.code(204).send()}),n.post("/v1/sessions/:id/stdin/open",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(!l)return c.code(404).send({error:"session not found"}),c;let g=u.body??{},m={};(g.mode==="memory"||g.mode==="file")&&(m.mode=g.mode),typeof g.capacityBytes=="number"&&(m.capacityBytes=g.capacityBytes),typeof g.fileCapBytes=="number"&&(m.fileCapBytes=g.fileCapBytes),(m.mode??"memory")==="file"&&(m.filePathFor=h=>Eo.join(Ro.tmpdir(),`hydra-acp-stdin-${h}.log`));try{return l.openStream(m)}catch(h){return c.code(409).send({error:h.message}),c}}),n.post("/v1/sessions/:id/stdin",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(!l)return c.code(404).send({error:"session not found"}),c;let g=u.body??{},m=typeof g.chunk=="string"?g.chunk:"",h=g.eof===!0;try{return l.streamWrite(m,h)}catch(y){return c.code(409).send({error:y.message}),c}}),n.patch("/v1/sessions/:id",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=u.body??{};if(l.priority!==void 0){let m=l.priority,h;if(m===null||m===0)h=void 0;else if(typeof m=="number"&&Number.isInteger(m)&&m>0)h=m;else{c.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(p,h)){c.code(404).send({error:"session not found"});return}c.code(204).send();return}if(l.regen===!0){if(!(e.get(p)!==void 0||await e.hasRecord(p))){c.code(404).send({error:"session not found"});return}e.scheduleSynopsis(p),c.code(202).send();return}if(typeof l.title!="string"||l.title.trim().length===0){c.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(p,l.title)){c.code(404).send({error:"session not found"});return}c.code(204).send()}),n.delete("/v1/sessions/:id",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(l){await l.close({deleteRecord:!0}),await e.waitForDeletion(p),await e.hasRecord(p)&&await e.deleteRecord(p),c.code(204).send();return}if(!await e.deleteRecord(p)){c.code(404).send({error:"session not found"});return}c.code(204).send()}),n.get("/v1/sessions/:id/export",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=u.query?.tools,g=l==="references"?"references":xi(l),m=await e.exportBundle(p,g==="references"?{tools:"references"}:{});if(!m){c.code(404).send({error:"session not found"});return}let h=It({record:m.record,history:g==="summary"?Ri(m.history,"summary"):m.history,promptHistory:m.promptHistory.length>0?m.promptHistory:void 0,...m.toolBlobs!==void 0?{toolBlobs:m.toolBlobs}:{},hydraVersion:Y,machine:gt(),hydraHost:xo(t)}),y=new Date().toISOString().replace(/[:.]/g,"-");c.header("Content-Disposition",`attachment; filename="${p}-${y}.hydra"`),c.code(200).send(h)}),n.get("/v1/sessions/:id/diff",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=await e.exportBundle(p);if(!l){c.code(404).send({error:"session not found"});return}let g=u.query??{},m=g.fold==="true"||g.fold==="1",h=typeof g.paths=="string"&&g.paths.length>0?new Set(g.paths.split(",").map(v=>v.trim()).filter(v=>v.length>0)):void 0,y=mo(l.history);h&&(y=y.filter(v=>h.has(v.path))),m&&(y=y.map(v=>({...v,hunks:go(v.hunks)}))),c.code(200).send(y)}),n.get("/v1/sessions/:id/tools/:hash",async(u,c)=>{let f=u.params,p=await e.resolveCanonicalId(f.id)??f.id,l=await e.loadToolBlob(p,f.hash);if(l===null){c.code(404).send({error:"tool blob not found"});return}c.header("Content-Type","text/plain; charset=utf-8"),c.code(200).send(l)}),n.get("/v1/sessions/:id/transcript",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=await e.exportBundle(p);if(!l){c.code(404).send({error:"session not found"});return}let g=It({record:l.record,history:l.history,promptHistory:l.promptHistory.length>0?l.promptHistory:void 0,hydraVersion:Y,machine:gt(),hydraHost:xo(t)}),m=u.query,h=y=>y==="1"||y==="true"||y==="yes";c.header("Content-Type","text/markdown; charset=utf-8"),c.code(200).send(yo(g,{includeTools:h(m?.tools),includeThoughts:h(m?.thoughts)}))}),n.post("/v1/sessions/:id/fork",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=u.body??{},g={};if(l.forkAt!==void 0){if(typeof l.forkAt!="string"||l.forkAt.length===0){c.code(400).send({error:"forkAt must be a non-empty string"});return}g.forkAt=l.forkAt}if(l.cwd!==void 0){if(typeof l.cwd!="string"||l.cwd.length===0){c.code(400).send({error:"cwd must be a non-empty string"});return}g.cwd=Z(l.cwd)}if(l.agentId!==void 0){if(typeof l.agentId!="string"||l.agentId.length===0){c.code(400).send({error:"agentId must be a non-empty string"});return}g.agentId=l.agentId}if(l.title!==void 0){if(typeof l.title!="string"){c.code(400).send({error:"title must be a string"});return}g.title=l.title}if(l.mode!==void 0){if(l.mode!=="verbatim"&&l.mode!=="synthesis"){c.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}g.mode=l.mode}if(l.model!==void 0){if(typeof l.model!="string"||l.model.length===0){c.code(400).send({error:"model must be a non-empty string"});return}g.model=l.model}try{let m=await e.forkSession(p,g);c.code(201).send(m)}catch(m){let h=m;if(h.code===k.SessionNotFound){c.code(404).send({error:h.message});return}if(h.code===k.InvalidParams||h.code===k.AgentNotInstalled){c.code(400).send({error:h.message});return}c.code(500).send({error:h.message})}}),n.post("/v1/sessions/import",async(u,c)=>{let f=u.body??{};if(f.bundle===void 0){c.code(400).send({error:"missing bundle"});return}let p;if(f.cwd!==void 0){if(typeof f.cwd!="string"||f.cwd.length===0){c.code(400).send({error:"cwd must be a non-empty string"});return}p=f.cwd}let l;try{l=Oi(f.bundle)}catch(g){c.code(400).send({error:"invalid bundle",details:g.message});return}try{let g=await e.importBundle(l,{replace:f.replace===!0,...p!==void 0?{cwd:p}:{}});c.code(201).send(g)}catch(g){let m=g;if(m.code===k.BundleAlreadyImported){c.code(409).send({error:"bundle already imported",existingSessionId:m.existingSessionId});return}c.code(500).send({error:m.message})}}),n.get("/v1/sessions/:id/compact/status",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p),g;if(l?g=l.summarizedThroughEntry:g=await e.getSummarizedThroughEntry(p),g===void 0&&!await e.hasRecord(p))return c.code(404).send({error:"session not found"}),c;let m=await e.getCompactionState(p),h=await e.getRollbackBreadcrumb(p),y=!1,v,S=await e.getHistory(p).catch(()=>[])??[];if(S.length>0&&t.compaction){let A=g??0,C=S.length,x=S.slice(A),T=so(x);v=Fs(T);let _=l?.currentModel,B=S.at(-1).recordedAt,F=l?.currentUsage;y=ro({summarizedThroughEntry:A,totalEntries:C,unsummarizedChars:T,compactionInFlight:e.getCompactionInFlight(),currentModel:_,lastActivityMs:B,nowMs:Date.now(),config:t.compaction,...typeof F?.used=="number"?{agentReportedUsed:F.used}:{},...typeof F?.size=="number"?{agentReportedSize:F.size}:{}})}return{summarizedThroughEntry:g??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:y,...v!=null?{approxTokens:v}:{},...m!=null?{compactionState:m}:{},...h!=null?{rollbackBreadcrumb:h}:{}}}),n.post("/v1/sessions/:id/compact",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f;if(e.get(p)){e.scheduleCompaction(p),c.code(202).send({scheduled:!0});return}if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}e.scheduleCompaction(p),c.code(202).send({scheduled:!0})}),n.post("/v1/sessions/:id/compact/rollback",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f;if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}try{await e.performUncompact(p),c.code(202).send({rolledBack:!0})}catch(l){let g=l instanceof Error?l.message:String(l);c.code(409).send({error:g})}}),n.get("/v1/sessions/:id/history",async(u,c)=>{let f=u.params.id,p=u.query,l=p?.follow==="1"||p?.follow==="true",g=await e.resolveCanonicalId(f)??f,m=e.get(g),h,y,v=!1,w=1e4,S=[];if(m){l&&(y=m.onBroadcast(C=>{c.raw.writableEnded||(v?c.raw.write(JSON.stringify(C)+`
144
- `):(S.push(C),S.length>w&&S.shift()))})),u.raw.on("close",()=>{y?.(),c.raw.writableEnded||c.raw.end()});try{h=await m.getHistorySnapshot()}catch(C){throw y?.(),C}}else{let C=await e.getHistory(g);if(C===void 0)return c.code(404).send({error:"session not found"}),c;h=C}c.raw.setHeader("Content-Type","application/x-ndjson"),c.raw.setHeader("Cache-Control","no-cache"),c.raw.statusCode=200;let A=new Set;for(let C of h??[]){c.raw.write(JSON.stringify(C)+`
145
- `);let x=C;typeof x.recordedAt=="number"&&A.add(String(x.recordedAt))}for(;S.length>0;){let C=S.splice(0,S.length);for(let x of C){let T=x,_=typeof T.recordedAt=="number"?String(T.recordedAt):"";_&&A.has(_)||c.raw.write(JSON.stringify(x)+`
146
- `)}}return v=!0,y||c.raw.end(),c});function r(u,c,f){let p=typeof u=="string"?u.trim():"";if(p.length===0)return null;let l;try{l=JSON.parse(p)}catch{return console.debug("events endpoint: skipping malformed JSONL line"),null}if(!l||typeof l!="object"||Array.isArray(l))return console.debug("events endpoint: skipping non-object JSONL line"),null;let g=l;if(typeof g.recordedAt!="number"||f!==void 0&&g.recordedAt<f||typeof g.params!="object"||g.params===null||Array.isArray(g.params))return null;let m=g.params;if(typeof m.update!="object"||m.update===null||Array.isArray(m.update))return null;let y=m.update.sessionUpdate;return typeof y!="string"||!c.has(y)?null:{recordedAt:g.recordedAt,entry:l}}function i(u,c,f){let l=c.params.update,g={sessionId:u,ts:new Date(c.recordedAt).toISOString(),kind:f,update:l};return l.messageId!==void 0&&l.messageId!==null&&(g.messageId=l.messageId),g}async function*o(u,c,f,p){for await(let l of c){let g=r(l,f,p);if(g){let m=g.entry.params.update.sessionUpdate;yield{ts:g.recordedAt,row:i(u,g.entry,m)}}}}async function a(u,c,f,p){let l=js.createInterface({input:Hs.createReadStream(c),crlfDelay:1/0}),g=o(u,l,f,p),m=await g.next(),h=m.done?null:m.value;return{sessionId:u,rl:l,gen:g,current:h,exhausted:h===null}}async function d(u){let c=await u.gen.next();c.done?(u.exhausted=!0,u.current=null):u.current=c.value}n.get("/v1/sessions/events",async(u,c)=>{let f=u.query,p=f.kinds;if(!p||p.trim().length===0)return c.code(400).send({error:"kinds parameter is required"}),c;let l=p.split(",").map(w=>w.trim());if(l.length===0)return c.code(400).send({error:"kinds parameter is required"}),c;for(let w of l)if(!kn.has(w))return c.code(400).send({error:`kind "${w}" is not queryable; allowed kinds: ${[...kn].join(", ")}`}),c;let g=new Set(l),m;if(f.since!==void 0&&f.since.trim().length>0){let w=new Date(f.since);if(isNaN(w.getTime()))return c.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),c;m=w.getTime()}let h=await e.list({includeNonInteractive:!0}),y=m!==void 0?h.filter(w=>new Date(w.updatedAt).getTime()>=m):h;c.raw.setHeader("content-type","application/x-ndjson"),c.raw.statusCode=200;let v=[];for(let w of y)try{let S=I.historyFile(w.sessionId),A=await a(w.sessionId,S,g,m);A.exhausted||v.push(A)}catch(S){if(S.code==="ENOENT")continue;throw S}u.raw.on("close",()=>{for(let w of v)try{w.rl.close()}catch{}c.raw.writableEnded||c.raw.end()});try{for(;v.length>0;){let w=-1,S=1/0;for(let C=0;C<v.length;C++){let x=v[C];x.current!==null&&x.current.ts<S&&(S=x.current.ts,w=C)}if(w===-1)break;let A=v[w];if(c.raw.write(JSON.stringify(A.current.row)+`
147
- `),await d(A),A.exhausted){try{A.rl.close()}catch{}v.splice(w,1)}}}catch(w){for(let S of v)try{S.rl.close()}catch{}throw w}return c.raw.end(),c}),n.get("/v1/sessions/:id/events",async(u,c)=>{let f=u.params.id,p=u.query,l=await e.resolveCanonicalId(f)??f;if(!e.get(l)&&!await e.hasRecord(l))return c.code(404).send({error:"session not found"}),c;let m=p.kinds;if(!m||m.trim().length===0)return c.code(400).send({error:"kinds parameter is required"}),c;let h=m.split(",").map(C=>C.trim());if(h.length===0)return c.code(400).send({error:"kinds parameter is required"}),c;for(let C of h)if(!kn.has(C))return c.code(400).send({error:`kind "${C}" is not queryable; allowed kinds: ${[...kn].join(", ")}`}),c;let y=new Set(h),v;if(p.since!==void 0&&p.since.trim().length>0){let C=new Date(p.since);if(isNaN(C.getTime()))return c.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),c;v=C.getTime()}let w=I.historyFile(l),S=Hs.createReadStream(w),A=js.createInterface({input:S,crlfDelay:1/0});c.raw.setHeader("content-type","application/x-ndjson"),c.raw.statusCode=200;try{for await(let C of A){let x=typeof C=="string"?C.trim():"";if(x.length===0)continue;let T;try{T=JSON.parse(x)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",w);continue}if(!T||typeof T!="object"||Array.isArray(T)){console.debug("events endpoint: skipping non-object JSONL line in %s",w);continue}let _=T;if(typeof _.recordedAt!="number"||typeof _.params!="object"||_.params===null||Array.isArray(_.params))continue;let B=_.params;if(typeof B.update!="object"||B.update===null||Array.isArray(B.update))continue;let F=B.update,P=F.sessionUpdate;if(typeof P!="string"||!y.has(P)||v!==void 0&&_.recordedAt<v)continue;let U={ts:new Date(_.recordedAt).toISOString(),kind:P,update:F};F.messageId!==void 0&&F.messageId!==null&&(U.messageId=F.messageId),c.raw.write(JSON.stringify(U)+`
148
- `)}}catch(C){if(C.code==="ENOENT")return c.raw.end(),c;throw C}return c.raw.end(),c}),n.get("/v1/sessions/:id/attention",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);return!l&&!await e.hasRecord(p)?(c.code(404).send({error:"session not found"}),c):l?{flags:l.listAttentionFlags()}:{flags:(await e.store.read(p))?.attentionFlags??[]}}),n.get("/v1/sessions/attention",async(u,c)=>{let f=u.query;if(!f.source||f.source.trim().length===0)return c.code(400).send({error:"source query parameter is required"}),c;let p=await e.list({includeNonInteractive:!0}),l=[];for(let g of p){let m=e.get(g.sessionId),h;m?h=m.listAttentionFlags():h=(await e.store.read(g.sessionId))?.attentionFlags??[];for(let y of h)y.source===f.source&&l.push({...y,sessionId:g.sessionId})}return{flags:l}}),n.post("/v1/sessions/:id/attention/clear",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,g=u.body??{},m=typeof g.source=="string"?g.source:"",h=typeof g.reason=="string"?g.reason:"";if((m.length>0||h.length>0)&&!(m.length>0&&h.length>0)){c.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}m.length===0&&h.length;let y=e.get(p);if(y){if(m.length>0&&h.length>0)y.clearAttentionFlag(m,h);else{let C=Array.from(y.listAttentionFlags()).map(x=>`${x.source}::${x.reason}`);for(let x of C)y.clearAttentionFlag(x.split("::")[0],x.split("::").slice(1).join("::"))}c.code(204).send();return}if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}let v=e.store,w=await v.read(p);if(!w){c.code(404).send({error:"session not found"});return}let S=w.attentionFlags??[],A;if(m.length>0&&h.length>0){let C=`${m}::${h}`;A=S.filter(x=>`${x.source}::${x.reason}`!==C)}else A=[];if(A.length===S.length&&A.every((C,x)=>C.source===S[x].source&&C.reason===S[x].reason)){c.code(204).send();return}await v.write({...w,attentionFlags:A}),c.code(204).send()})}function Po(n,e,t,s={}){n.get("/v1/agents",async()=>qe(e)),n.get("/v1/registry",async()=>e.load()),n.post("/v1/registry/refresh",async()=>{let r=await e.refresh();return{version:r.version,agentCount:r.agents.length}}),n.post("/v1/agents/:id/install",async(r,i)=>{let o=r.params.id,a=await e.getAgent(o);if(!a){i.code(404).send({error:`agent ${o} not found in registry`});return}if(a.distribution.uvx&&!a.distribution.npx&&!a.distribution.binary){i.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 oe(a,[],{npmRegistry:s.npmRegistry}),u=a.distribution.npx?"npx":a.distribution.binary?"binary":"unknown";i.send({agentId:a.id,version:d.version,distribution:u,installed:!0,command:d.command})}catch(d){i.code(500).send({error:d.message})}}),n.post("/v1/agents/:id/sync",async(r,i)=>{let o=r.params.id;try{let{synced:a,skipped:d}=await t.syncFromAgent(o);return{synced:a.map(u=>({sessionId:u.sessionId,upstreamSessionId:u.upstreamSessionId,agentId:u.agentId,cwd:u.cwd,title:u.title,updatedAt:u.updatedAt})),skipped:d}}catch(a){let d=a;if(d.code===k.AgentNotInstalled){i.code(404).send({error:d.message});return}i.code(409).send({error:d.message})}})}function To(n,e,t){n.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t}))}var Cl=/^[A-Za-z0-9._-]+$/;function An(n,e,t){let s=e==="extension"?"extensions":"transformers",r=`/v1/${s}`;n.get(r,async()=>({[s]:t.list()})),n.get(`${r}/:name`,async(i,o)=>{let a=i.params.name,d=t.get(a);if(!d){o.code(404).send({error:`unknown ${e}: ${a}`});return}return d}),n.post(r,async(i,o)=>{let a=i.body??{},d=xl(a);if("error"in d){o.code(400).send({error:d.error});return}try{let u=t.register(d.config);o.code(201).send(u)}catch(u){_t(o,u)}}),n.delete(`${r}/:name`,async(i,o)=>{let a=i.params.name;try{await t.unregister(a),o.code(204).send()}catch(d){_t(o,d)}}),n.post(`${r}/:name/start`,async(i,o)=>{let a=i.params.name;try{let d=await t.startByName(a);o.code(200).send(d)}catch(d){_t(o,d)}}),n.post(`${r}/:name/stop`,async(i,o)=>{let a=i.params.name;try{let d=await t.stopByName(a);o.code(200).send(d)}catch(d){_t(o,d)}}),n.post(`${r}/:name/restart`,async(i,o)=>{let a=i.params.name;try{let d=await t.restartByName(a);o.code(200).send(d)}catch(d){_t(o,d)}})}function _t(n,e){let t=e.code,s=e.message??"unknown error";if(t==="NOT_FOUND"){n.code(404).send({error:s});return}if(t==="CONFLICT"){n.code(409).send({error:s});return}n.code(500).send({error:s})}function xl(n){let e=n.name;if(typeof e!="string"||!Cl.test(e))return{error:"name must match [A-Za-z0-9._-]+"};let t=n.command;if(t!==void 0&&(!Array.isArray(t)||t.some(o=>typeof o!="string")))return{error:"command must be string[]"};let s=n.args;if(s!==void 0&&(!Array.isArray(s)||s.some(o=>typeof o!="string")))return{error:"args must be string[]"};let r=n.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(o=>typeof o!="string"))return{error:"env values must be strings"};let i=n.enabled;return i!==void 0&&typeof i!="boolean"?{error:"enabled must be a boolean"}:{config:{name:e,command:t??[],args:s??[],env:r??{},enabled:i===void 0?!0:i}}}function _o(n,e){An(n,"extension",e)}function Fo(n,e){An(n,"transformer",e)}function $o(n,e){n.get("/v1/config",async()=>e)}import{z as ct}from"zod";W();import*as dt from"fs/promises";import*as Oo from"path";import{randomBytes as vy,scrypt as Rl,timingSafeEqual as El}from"crypto";import{promisify as Ml}from"util";var Pl=Ml(Rl);function No(){return Oo.join(I.home(),"password-hash")}var Tl=128*1024*1024;async function Ho(){try{return(await dt.readFile(No(),"utf8")).trim().length>0}catch(n){if(n.code==="ENOENT")return!1;throw n}}async function jo(n){if(typeof n!="string"||n.length===0)return!1;let e;try{e=(await dt.readFile(No(),"utf8")).trim()}catch(u){if(u.code==="ENOENT")return!1;throw u}let t=e.split("$");if(t.length!==6||t[0]!=="scrypt")return!1;let s=parseInt(t[1],10),r=parseInt(t[2],10),i=parseInt(t[3],10);if(!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(i))return!1;let o=Buffer.from(t[4],"hex"),a=Buffer.from(t[5],"hex");if(o.length===0||a.length===0)return!1;let d=await Pl(n,o,a.length,{N:s,r,p:i,maxmem:Tl});return d.length!==a.length?!1:El(d,a)}var _l=ct.object({password:ct.string().min(1),label:ct.string().min(1).max(256).optional(),ttlSec:ct.number().int().positive().optional()}),Fl=ct.object({id:ct.string().optional()}).optional();function Bo(n,e){n.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,s)=>{let r=$l(t);if(e.rateLimiter.isBlocked(r))return s.code(429).send({error:"Too many failed attempts; try again later."});let i;try{i=_l.parse(t.body)}catch{return s.code(400).send({error:"Invalid request body"})}if(!await Ho())return s.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await jo(i.password))return e.rateLimiter.recordFailure(r),s.code(401).send({error:"Invalid password"});e.rateLimiter.recordSuccess(r);let a=await e.store.issue({label:i.label,ttlSec:i.ttlSec});return s.code(200).send({session_token:a.token,id:a.id,expires_at:a.expiresAt})}),n.post("/v1/auth/logout",async(t,s)=>{let r;try{r=Fl.parse(t.body??void 0)}catch{return s.code(400).send({error:"Invalid request body"})}let i=r?.id??t.authIdentity;if(!i||i==="service")return s.code(200).send({revoked:!1});let o=await e.store.revoke(i);return s.code(200).send({revoked:o})}),n.get("/v1/auth/verify",async(t,s)=>s.code(200).send({ok:!0})),n.get("/v1/auth/sessions",async(t,s)=>s.code(200).send({sessions:e.store.list()})),n.delete("/v1/auth/sessions/:id",async(t,s)=>{let r=t.params.id;return await e.store.revoke(r)?s.code(204).send():s.code(404).send({error:"Not found"})})}function $l(n){return n.ip||"unknown"}import{nanoid as Bs}from"nanoid";function Uo(n){let e=[],t=[],s=!1,r=i=>{if(!s){s=!0;for(let o of t)o(i)}};return n.on("message",(i,o)=>{if(o)return;let a=i.toString("utf8");try{let d=JSON.parse(a);for(let u of e)u(d)}catch(d){for(let u of e)u({jsonrpc:"2.0",id:null,error:{code:k.ParseError,message:`Failed to parse WS frame: ${d.message}`}})}}),n.on("close",()=>r()),n.on("error",i=>r(i)),{async send(i){if(s)throw new Error("ws is closed");let o=JSON.stringify(i);await new Promise((a,d)=>{n.send(o,u=>{if(u){d(u);return}a()})})},onMessage(i){e.push(i)},onClose(i){t.push(i)},async close(){s||(await new Promise(i=>{let o=!1,a=()=>{o||(o=!0,clearTimeout(d),i())},d=setTimeout(a,5e3);n.once("close",a);try{n.close()}catch{a()}}),r())}}}import{randomBytes as Lo}from"crypto";import*as qo from"os";import*as zo from"path";function M(n,e,t){let s=new Error(e);return s.code=n,t!==void 0&&(s.data=t),s}function Bl(n){if(!n||typeof n!="object")return 512;let s=n.params?.update;if(!s)return 512;let r=512,i=s.content;if(typeof i=="string")r+=i.length;else if(i&&typeof i=="object"){let a=i;typeof a.text=="string"&&(r+=a.text.length),typeof a.data=="string"&&(r+=a.data.length)}let o=s.toolCall;if(o&&(typeof o.rawInput=="string"?r+=o.rawInput.length:o.rawInput&&typeof o.rawInput=="object"&&(r+=256),typeof o.rawOutput=="string"?r+=o.rawOutput.length:o.rawOutput&&typeof o.rawOutput=="object"&&(r+=256),Array.isArray(o.content)))for(let a of o.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 u=d.content;typeof u.text=="string"&&(r+=u.text.length)}}return r}function ie(n,e,t){let s=n.get(e);if(!s)throw M(k.SessionNotFound,t??`session ${e} not found`);return s}async function Cn(n,e){let t=at(n),s,r,i;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&n.mcpTokenRegistry!==void 0&&n.getDaemonOrigin!==void 0&&(s=Lo(32).toString("hex"),r=n.mcpTokenRegistry.reserve(s),i={name:"hydra-acp-recall",type:"http",url:`${n.getDaemonOrigin()}/mcp/hydra-acp-recall`,headers:[{name:"Authorization",value:`Bearer ${s}`}]});let a=[...t?.descriptors??[],...i!==void 0?[i]:[]],d=Ns({baselineMcpServers:void 0,stdinEnabled:!1,deps:n}),u;try{u=await n.manager.resurrect({...e,mcpServers:a,...d?{mintMcpServersForSwap:d}:{}})}catch(c){throw t!==void 0&&t.abandon(c instanceof Error?c:void 0),r!==void 0&&r.abandon(c instanceof Error?c:void 0),c}if(t!==void 0&&t.bindToSession(u),s!==void 0&&r!==void 0&&n.mcpTokenRegistry!==void 0){let c=s,f=n.mcpTokenRegistry;r.complete(u),u.onClose(()=>{f.unbind(c)})}return Gl(u,n),Wo(u.sessionId,n),u}function Jo(n,e){n.get("/acp",{websocket:!0},async(t,s)=>{let r=no({headers:s.headers,url:s.url});if(!r||!await e.validator.validate(r)){t.close(4401,"Unauthorized");return}let i=e.processRegistry?.resolve(r),o=Uo(t),a=new Je(o),d={clientId:`hydra_client_${Bs(12)}`,processIdentity:i,attached:new Map};a.onClose(()=>{for(let f of d.attached.values())e.manager.get(f.sessionId)?.detach(f.clientId);d.attached.clear()});let u=(f,p)=>{if(d.attached.get(f)?.readonly)throw M(k.PermissionDenied,`${p} not permitted on a read-only attachment`)};if(a.onRequest("initialize",async f=>{let p=Ar.parse(f??{});p.clientInfo?.name&&(d.clientInfo={name:p.clientInfo.name,...p.clientInfo.version!==void 0?{version:p.clientInfo.version}:{}});let l=p.clientInfo?.version;return l&&i&&(i.kind==="extension"?e.onExtensionVersion?.(i.name,l):e.onTransformerVersion?.(i.name,l)),Ql()}),i&&e.extensionCommands){let f=e.extensionCommands;a.onRequest("hydra-acp/commands/register",async p=>{let l=p??{},g=Array.isArray(l.commands)?l.commands.map(m=>{if(!m||typeof m!="object")return;let h=m;if(typeof h.verb!="string")return;let y={verb:h.verb};return typeof h.argsHint=="string"&&(y.argsHint=h.argsHint),typeof h.description=="string"&&(y.description=h.description),y}).filter(m=>m!==void 0):[];return f.register(i.name,a,g),{ok:!0,registered:g.length}}),a.onClose(()=>{f.clear(i.name)})}if(i&&e.extensionMcp){let f=e.extensionMcp;a.onRequest("hydra-acp/mcp_tools/register",async l=>{let g=l??{},m=typeof g.instructions=="string"?g.instructions:void 0,h=Array.isArray(g.tools)?g.tools.map(y=>{if(!y||typeof y!="object")return;let v=y;if(typeof v.name!="string"||v.name.length===0||typeof v.description!="string"||v.inputSchema===null||typeof v.inputSchema!="object")return;let w={name:v.name,description:v.description,inputSchema:v.inputSchema};return v.outputSchema!==null&&typeof v.outputSchema=="object"&&(w.outputSchema=v.outputSchema),w}).filter(y=>y!==void 0):[];if(h.length===0)throw new Error("register_mcp_tools requires at least one tool");return f.register(i.name,a,m,h),{ok:!0,registered:h.length}});let p=l=>{let g=l??{};if(typeof g.sessionId!="string"||g.sessionId.length===0)throw M(k.InvalidParams,"sessionId is required");return g.sessionId};if(a.onRequest("hydra-acp/session/extension_state/get",async l=>{let g=p(l),m=l??{};if(typeof m.key!="string"||m.key.length===0)throw M(k.InvalidParams,"key is required");if(!e.manager)throw M(k.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(g,i.name,m.key)??null}}),a.onRequest("hydra-acp/session/extension_state/list",async l=>{let g=p(l);if(!e.manager)throw M(k.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(g,i.name)}}),a.onRequest("hydra-acp/session/extension_state/set",async l=>{let g=p(l),m=l??{};if(typeof m.key!="string"||m.key.length===0)throw M(k.InvalidParams,"key is required");if(m.value===void 0)throw M(k.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw M(k.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(g,i.name,m.key,m.value)}catch(h){throw M(k.InvalidParams,h.message)}return{ok:!0}}),a.onRequest("hydra-acp/session/extension_state/delete",async l=>{let g=p(l),m=l??{};if(typeof m.key!="string"||m.key.length===0)throw M(k.InvalidParams,"key is required");if(!e.manager)throw M(k.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(g,i.name,m.key),{ok:!0}}),e.extensionMcpControls){let l=e.extensionMcpControls;a.onRequest("hydra-acp/mcp_tools/refresh_session",async g=>{let m=g??{};if(typeof m.sessionId!="string"||m.sessionId.length===0)throw M(k.InvalidParams,"refresh_session requires sessionId");return await l.notifyToolListChanged(m.sessionId,i.name),{ok:!0}})}a.onClose(()=>{f.clear(i.name)})}if(i?.kind==="transformer"){a.onRequest("hydra-acp/transformer/initialize",async p=>{let l=p??{},g=Array.isArray(l.intercepts)?l.intercepts.filter(m=>typeof m=="string"):[];if(e.transformers&&(e.transformers.registerConnection(i.name,a,g),e.manager?.defaultTransformers.includes(i.name))){let m=e.transformers.resolveChain([i.name])[0];if(m)for(let h of e.manager.liveSessions())h.addTransformer(m)}return{ack:!0}}),a.onClose(()=>{e.transformers?.deregisterConnection(i.name)}),a.onRequest("hydra-acp/message/emit",async p=>{let l=p??{},g=typeof l.sessionId=="string"?l.sessionId:void 0,m=typeof l.method=="string"?l.method:void 0,h=l.envelope,y=l.route;if(!g)throw M(-32602,"emit_message requires sessionId");if(!m&&y!=="client_broadcast")throw M(-32602,"emit_message requires method");let v=ie(e.manager,g),w=typeof l.respondsTo=="string"?l.respondsTo:void 0;if(w)return v.dischargeClaim(w,h),{ok:!0};if(y==="chain")return{ok:!0,response:await v.emitToChain(i.name,m,h)};if(y==="queue"){if(m!=="session/prompt")throw M(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await v.emitToQueue(i.name,h)}}if(y==="daemon")return{ok:!0,response:await v.emitToChain(i.name,m,h)};if(y==="client_broadcast"){if(!h||typeof h!="object")throw M(-32602,"client_broadcast requires an envelope object");return v.broadcastClientUpdate(h),{ok:!0}}throw M(-32602,`unsupported route: ${JSON.stringify(y)}`)}),a.onRequest("hydra-acp/session/request_permission",async p=>{let l=p??{},g=typeof l.sessionId=="string"?l.sessionId:void 0;if(!g)throw M(-32602,"hydra-acp/session/request_permission requires sessionId");return ie(e.manager,g).requestPermissionFromClients(l)}),a.onRequest("hydra-acp/transformer/attach",async p=>ql(p,i.name,e)),a.onRequest("hydra-acp/child_session/spawn",async p=>{let l=p??{},g=typeof l.agentId=="string"?l.agentId:e.defaultAgent,m=typeof l.cwd=="string"?l.cwd:void 0,h=typeof l.parentSessionId=="string"?l.parentSessionId:void 0,y=l._meta&&typeof l._meta=="object"?l._meta:void 0,v=y&&y["hydra-acp"]&&typeof y["hydra-acp"]=="object"?y["hydra-acp"]:void 0,w=v&&typeof v.title=="string"?v.title:void 0,S=v&&typeof v.model=="string"?v.model:void 0;if(!m&&h){let x=e.manager.get(h);x&&(m=x.cwd)}if(!m)throw M(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let A=typeof l.interactive=="boolean"?l.interactive:!1;return{childSessionId:(await e.manager.create({agentId:g,cwd:m,parentSessionId:h,interactive:A,transformChain:[],title:w,model:S})).sessionId}}),a.onRequest("hydra-acp/session/fork",async p=>{let l=p??{};if(typeof l.sessionId!="string")throw M(k.InvalidParams,"fork_session requires sessionId");let g=typeof l.forkAt=="string"?l.forkAt:void 0,m=typeof l.cwd=="string"?l.cwd:void 0,h=typeof l.agentId=="string"?l.agentId:void 0,y=typeof l.mode=="string"&&(l.mode==="verbatim"||l.mode==="synthesis")?l.mode:void 0,v=typeof l.model=="string"&&l.model.length>0?l.model:void 0;return await e.manager.forkSession(l.sessionId,{...g!==void 0?{forkAt:g}:{},...m!==void 0?{cwd:m}:{},...h!==void 0?{agentId:h}:{},...y!==void 0?{mode:y}:{},...v!==void 0?{model:v}:{}})}),a.onRequest("session/fork",async p=>{let l=p??{};if(typeof l.sessionId!="string")throw M(k.InvalidParams,"session/fork requires sessionId");let g=typeof l.cwd=="string"?l.cwd:void 0;return{sessionId:(await e.manager.forkSession(l.sessionId,{...g!==void 0?{cwd:g}:{},mode:"verbatim"})).sessionId}});let f=async(p,l)=>{let g=p??{};if(typeof g.sessionId!="string")throw M(k.InvalidParams,`${l} requires sessionId`);let m=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,h=e.manager.get(m);if(h)return await h.close({deleteRecord:!0}),await e.manager.waitForDeletion(m),await e.manager.hasRecord(m)&&await e.manager.deleteRecord(m),{id:m,existed:!0};let y=await e.manager.deleteRecord(m);return{id:m,existed:y}};a.onRequest("session/delete",async p=>(await f(p,"session/delete"),{})),a.onRequest("session/close",async p=>{let l=p??{};if(typeof l.sessionId!="string")throw M(k.InvalidParams,"session/close requires sessionId");u(l.sessionId,"session/close");let g=await e.manager.resolveCanonicalId(l.sessionId)??l.sessionId,m=e.manager.get(g);if(m)return await m.close({deleteRecord:!1}),{};if(await e.manager.hasRecord(g))return{};throw M(k.SessionNotFound,`session ${g} not found`)}),a.onRequest("hydra-acp/session/delete",async p=>{let{id:l,existed:g}=await f(p,"hydra-acp/session/delete");if(!g)throw M(k.SessionNotFound,`session ${l} not found`);return{deleted:!0,sessionId:l}}),a.onRequest("hydra-acp/child_session/await",async p=>{let l=p??{},g=typeof l.childSessionId=="string"?l.childSessionId:void 0,m=l.until==="idle"?"idle":"turn_complete",h=typeof l.timeoutMs=="number"?Math.min(l.timeoutMs,18e5):3e5;if(!g)throw M(-32602,"await_child requires childSessionId");let y=ie(e.manager,g,`child session ${g} not found`);return new Promise(v=>{let A=[],C=[],x=0,T=!1,_,B,F=!1,P=()=>{F||(F=!0,clearTimeout(U),_?.(),B?.(),v(T?{entries:A,truncated:!0}:{entries:A}))};_=y.onBroadcast(J=>{let ne=Bl(J);for(A.push(J),C.push(ne),x+=ne;A.length>0&&(A.length>1e3||x>1048576);)A.shift(),x-=C.shift()??0,T=!0;m==="turn_complete"&&J.params?.update?.sessionUpdate==="turn_complete"&&P()});let U=setTimeout(P,h);typeof U.unref=="function"&&U.unref(),B=y.onClose(()=>P())})}),a.onRequest("hydra-acp/child_session/close",async p=>{let l=p??{},g=typeof l.childSessionId=="string"?l.childSessionId:void 0;if(!g)throw M(-32602,"close_child_session requires childSessionId");let m=e.manager.get(g);return m&&await m.close({deleteRecord:!1}),{ok:!0}}),a.onRequest("hydra-acp/attention/set",async p=>zl(p,i.name,e)),a.onRequest("hydra-acp/attention/clear",async p=>Jl(p,i.name,e)),a.onRequest("hydra-acp/connection/keep_alive",async p=>{let l=p??{},g=typeof l.token=="string"?l.token:void 0,m=typeof l.sessionId=="string"?l.sessionId:void 0,h=typeof l.estimatedRemainingMs=="number"?l.estimatedRemainingMs:void 0;return g&&m&&e.manager.get(m)?.keepAliveClaim(g,h),{ok:!0}})}a.onRequest("hydra-acp/session/tool_content",async f=>{let p=f??{};if(typeof p.sessionId!="string"||typeof p.hash!="string")throw M(k.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let l=await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,g=await e.manager.loadToolBlob(l,p.hash);if(g===null)throw M(k.SessionNotFound,"tool content not found");return{content:g}}),a.onRequest("authenticate",async f=>Ul(f,e)),a.onRequest("logout",async f=>Dl(f,e)),a.onRequest("session/new",async f=>{let p=Cr.parse(f),l=mt(f?._meta),g=Array.isArray(l.transformers)&&l.transformers.every(P=>typeof P=="string")?l.transformers:e.manager.defaultTransformers??[],m=e.transformers?.resolveChain(g)??[],h,y,v=p.mcpServers;if(l.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){h=Lo(32).toString("hex"),y=e.mcpTokenRegistry.reserve(h);let U={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${h}`}]};v=[...p.mcpServers??[],U]}let w,S,A=at(e);A!==void 0&&(v=[...v??[],...A.descriptors]);let C=Ns({baselineMcpServers:p.mcpServers,stdinEnabled:l.mcpStdin===!0,deps:e}),x;try{x=await e.manager.create({cwd:p.cwd,agentId:l.agentId??e.defaultAgent,mcpServers:v,title:l.title,agentArgs:l.agentArgs,model:l.model,onInstallProgress:Do(a),transformChain:m,originatingClient:d.clientInfo,...l.interactive!==void 0?{interactive:l.interactive}:{},...l.env!==void 0?{forwardedEnv:l.env}:{},...C?{mintMcpServersForSwap:C}:{}})}catch(P){throw y!==void 0&&y.abandon(P instanceof Error?P:void 0),S!==void 0&&S.abandon(P instanceof Error?P:void 0),A!==void 0&&A.abandon(P instanceof Error?P:void 0),P}if(h!==void 0&&y!==void 0&&e.mcpTokenRegistry!==void 0){let P=h,U=e.mcpTokenRegistry;y.complete(x),x.onClose(()=>{U.unbind(P)})}if(w!==void 0&&S!==void 0&&e.mcpTokenRegistry!==void 0){let P=w,U=e.mcpTokenRegistry;S.complete(x),x.onClose(()=>{U.unbind(P)})}A!==void 0&&A.bindToSession(x),Wo(x.sessionId,e);let T,_;try{Mn(d,x,x.sessionId),T=Ft(a,x,d),{entries:_}=await x.attach(T,"full")}catch(P){throw await x.close({deleteRecord:!1}).catch(()=>{}),P}d.attached.set(x.sessionId,{sessionId:x.sessionId,clientId:T.clientId,readonly:!1}),setImmediate(()=>{(async()=>{for(let P of _){if(a.isClosed())break;await a.notify(P.method,Ce(P.params,P.recordedAt)).catch(()=>{})}})()});let B=xn(x),F=Rn(x);return{sessionId:x.sessionId,...B?{modes:B}:{},...F?{models:F}:{},configOptions:x.buildConfigOptions(),_meta:En(e.manager,x,{clientId:T.clientId})}}),a.onRequest("session/attach",async f=>{let p=Rr.parse(f),l=p.clientInfo?.version;l&&i&&(i.kind==="extension"?e.onExtensionVersion?.(i.name,l):e.onTransformerVersion?.(i.name,l));let g=mt(p._meta),m=g.resume,h=g.readonly===!0,y=g.env;n.log.info(`session/attach sessionId=${p.sessionId} hasResumeHints=${!!m} readonly=${h}`);let v=m?p.sessionId:await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,w=e.manager.get(v);if(!w&&h){let F=await e.manager.loadFromDisk(v);if(!F)throw M(k.SessionNotFound,`session ${p.sessionId} not found`);let P=await e.manager.loadHistory(v),U=p.clientId??`cli_${Bs(8)}`;d.attached.set(F.hydraSessionId,{sessionId:F.hydraSessionId,clientId:U,readonly:!0}),n.log.info(`session/attach OK (viewer) sessionId=${F.hydraSessionId} clientId=${U} attachedCount=${d.attached.size} replayed=${P.length}`);for(let J of P)await a.notify(J.method,Ce(J.params,J.recordedAt)).catch(()=>{});return{sessionId:F.hydraSessionId,clientId:U,connectedClients:[U],historyPolicy:"full",replayed:P.length,_meta:Wl(F)}}let S=!w;if(!w){let F=await e.manager.loadFromDisk(v),P=F;if(m&&(P={...F,hydraSessionId:p.sessionId,upstreamSessionId:m.upstreamSessionId,agentId:m.agentId,cwd:m.cwd,...m.title!==void 0?{title:m.title}:{},...m.agentArgs!==void 0?{agentArgs:m.agentArgs}:{}}),!P)throw M(k.SessionNotFound,`session ${p.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(P.agentId,P.upstreamSessionId))throw M(k.SessionNotFound,`session ${p.sessionId} was deleted`);let U=P.originatingClient?P:{...P,originatingClient:d.clientInfo},J=y!==void 0?{...U,forwardedEnv:y}:U;w=await Cn(e,{...J,onInstallProgress:Do(a)})}Mn(d,w,w.sessionId);let A=Ft(a,w,d,p.clientInfo,p.clientId),C=g.replayMode==="drip",{entries:x,appliedPolicy:T}=await w.attach(A,p.historyPolicy,{afterMessageId:p.afterMessageId,raw:C,...g.toolContent!==void 0?{toolContent:g.toolContent}:{}});if(d.attached.set(w.sessionId,{sessionId:w.sessionId,clientId:A.clientId,readonly:h}),y!==void 0&&await e.manager.setForwardedEnv(w.sessionId,y).catch(()=>{}),n.log.info(`session/attach OK sessionId=${w.sessionId} clientId=${A.clientId} attachedCount=${d.attached.size} requestedPolicy=${p.historyPolicy} appliedPolicy=${T} replayed=${x.length} readonly=${h}${C?" replayMode=drip":""}`),C){let F=g.dripSpeed&&g.dripSpeed>0?g.dripSpeed:1,P=750;(async()=>{let U=null;for(let J of x){let ne=typeof J.recordedAt=="number"?J.recordedAt:null;if(U!==null&&ne!==null){let je=Math.min(P,Math.max(0,(ne-U)/F));je>0&&await new Promise($t=>setTimeout($t,je))}ne!==null&&(U=ne);try{await a.notify(J.method,Ce(J.params,ne??void 0))}catch{return}}})()}else for(let F=0;F<x.length&&!a.isClosed();F++){let P=x[F],U=a.notify(P.method,Ce(P.params,P.recordedAt)).catch(()=>{});(F+1)%200===0&&await U}w.replayPendingPermissions(A);let _=xn(w),B=Rn(w);return{sessionId:w.sessionId,clientId:A.clientId,connectedClients:w.connectedClients(A.clientId),historyPolicy:T,replayed:x.length,..._?{modes:_}:{},...B?{models:B}:{},configOptions:w.buildConfigOptions(),_meta:En(e.manager,w,{resurrected:S})}}),a.onRequest("session/detach",async f=>{let p=Er.parse(f),l=d.attached.get(p.sessionId);if(!l)throw M(k.SessionNotFound,"client not attached to that session");let g=e.manager.get(p.sessionId);return g?.detach(l.clientId),d.attached.delete(p.sessionId),g&&e.manager.reapIfOrphanedNonInteractive(p.sessionId),{sessionId:p.sessionId,_meta:{[$e]:{detachStatus:"detached"}}}}),a.onRequest("session/list",async f=>{let p=Mr.parse(f??{});return{sessions:(await e.manager.list({cwd:p.cwd})).filter(h=>h.originatingClient?.name!==Yt).map(Pr)}}),a.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw M(k.InternalError,"agent registry unavailable");return qe(e.registry)}),a.onRequest("hydra-acp/agents/auth_methods",async f=>{let p=f??{};if(typeof p.agentId!="string"||p.agentId.length===0)throw M(k.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(p.agentId)).authMethods??[]}}),a.onRequest("session/prompt",async f=>{let p=Tr.parse(f);u(p.sessionId,"session/prompt");let l=d.attached.get(p.sessionId);if(!l)throw n.log.warn(`session/prompt rejected: not attached sessionId=${p.sessionId} attachedKeys=[${[...d.attached.keys()].join(",")}]`),M(k.SessionNotFound,"not attached to session");let g=e.manager.get(p.sessionId);if(!g){let m=await e.manager.loadFromDisk(p.sessionId);if(!m)throw M(k.SessionNotFound,`session ${p.sessionId} not found`);n.log.info(`session/prompt auto-resurrecting cold sessionId=${p.sessionId}`),g=await Cn(e,m);let h=Ft(a,g,d,void 0,l.clientId);await g.attach(h,"none")}return g.prompt(l.clientId,p)});let c=f=>{let p;try{p=Lt.parse(f)}catch(m){n.log.warn(`session/cancel: invalid params: ${m.message}`);return}let l=d.attached.get(p.sessionId);if(!l)return;if(l.readonly){n.log.warn(`session/cancel dropped (readonly attachment) sessionId=${p.sessionId}`);return}let g=e.manager.get(p.sessionId);g&&g.cancel(l.clientId).catch(m=>{n.log.warn(`session/cancel for ${p.sessionId}: ${m.message}`)})};a.onNotification("session/cancel",c),a.onRequest("session/cancel",async f=>{let p=Lt.parse(f);return u(p.sessionId,"session/cancel"),c(f),null}),a.onRequest("hydra-acp/prompt/cancel",async f=>{let p=Fr.parse(f);return u(p.sessionId,"hydra-acp/prompt/cancel"),ie(e.manager,p.sessionId).cancelQueuedPrompt(p.messageId)}),a.onRequest("hydra-acp/session/force_cancel",async f=>{let p=Lt.parse(f);return u(p.sessionId,"hydra-acp/session/force_cancel"),ie(e.manager,p.sessionId).forceCancel()}),a.onRequest("hydra-acp/prompt/update",async f=>{let p=$r.parse(f);return u(p.sessionId,"hydra-acp/prompt/update"),ie(e.manager,p.sessionId).updateQueuedPrompt(p.messageId,p.prompt)}),a.onRequest("hydra-acp/prompt/amend",async f=>{let p=Or.parse(f);u(p.sessionId,"hydra-acp/prompt/amend");let l=d.attached.get(p.sessionId);if(!l)throw M(k.SessionNotFound,"not attached to session");return ie(e.manager,p.sessionId).amendPrompt(l.clientId,p)}),a.onRequest("session/resume",async f=>{let p=f??{},l=typeof p.sessionId=="string"?p.sessionId:void 0;if(!l)throw M(k.InvalidParams,"session/resume requires sessionId");let g=await e.manager.resolveCanonicalId(l)??l,m=e.manager.get(g);if(!m){let w=await e.manager.loadFromDisk(g);if(!w)throw M(k.SessionNotFound,`session ${l} not found in memory or on disk`);m=await Cn(e,w)}Mn(d,m,m.sessionId);let h=Ft(a,m,d);await m.attach(h,"pending_only"),d.attached.set(m.sessionId,{sessionId:m.sessionId,clientId:h.clientId,readonly:!1}),m.replayPendingPermissions(h);let y=xn(m),v=Rn(m);return{sessionId:m.sessionId,...y?{modes:y}:{},...v?{models:v}:{},configOptions:m.buildConfigOptions(),_meta:En(e.manager,m,{clientId:h.clientId})}}),a.onRequest("session/load",async f=>{let p=f??{},l=typeof p.sessionId=="string"?p.sessionId:void 0;if(!l)throw M(k.InvalidParams,"session/load requires sessionId");let g=await e.manager.resolveCanonicalId(l)??l,m=e.manager.get(g);if(!m){let S=await e.manager.loadFromDisk(g);if(!S)throw M(k.SessionNotFound,`session ${l} not found in memory or on disk`);m=await Cn(e,S)}Mn(d,m,m.sessionId);let h=Ft(a,m,d),{entries:y}=await m.attach(h,"pending_only");d.attached.set(m.sessionId,{sessionId:m.sessionId,clientId:h.clientId,readonly:!1});for(let S of y){if(a.isClosed())break;await a.notify(S.method,Ce(S.params,S.recordedAt)).catch(()=>{})}m.replayPendingPermissions(h);let v=xn(m),w=Rn(m);return{sessionId:m.sessionId,...v?{modes:v}:{},...w?{models:w}:{},configOptions:m.buildConfigOptions(),_meta:En(e.manager,m,{clientId:h.clientId})}}),a.onRequest("session/set_model",async f=>{let p=f?.sessionId;typeof p=="string"&&u(p,"session/set_model");let l=Ll(f,e.manager);if(l.kind==="error")throw n.log.warn(l.logMessage),M(l.code,l.message);if(l.kind==="no_op")return n.log.warn(l.logMessage),await a.notify("session/update",{sessionId:l.sessionId,update:{sessionUpdate:"current_model_update",currentModel:l.currentModel}}).catch(()=>{}),null;n.log.info(l.logMessage);let{modelId:g}=l,m=await l.session.forwardRequest("session/set_model",{...f,modelId:g});return l.session.applyModelChange(g),m}),a.onRequest("session/set_mode",async f=>{let p=f,l=p?.sessionId;if(typeof l=="string"&&u(l,"session/set_mode"),!p||typeof p.sessionId!="string")throw M(k.InvalidParams,"session/set_mode requires string sessionId");if(typeof p.modeId!="string")throw M(k.InvalidParams,"session/set_mode requires string modeId");let g=ie(e.manager,p.sessionId),m=await g.forwardRequest("session/set_mode",f);return g.applyModeChange(p.modeId),m}),a.onRequest("session/set_config_option",async f=>{let p=f,l=y=>M(k.InvalidParams,y),g=p?.sessionId;if(typeof g=="string"&&u(g,"session/set_config_option"),!p||typeof p.sessionId!="string")throw l("session/set_config_option requires string sessionId");if(typeof p.configId!="string")throw l("session/set_config_option requires string configId");if(typeof p.value!="string")throw l("session/set_config_option requires string value");let m=ie(e.manager,p.sessionId),h=m.buildConfigOptions().find(y=>y.id===p.configId);if(!h)throw l(`unknown configId ${JSON.stringify(p.configId)} for this session`);if(!h.options.some(y=>y.value===p.value))throw l(`value ${JSON.stringify(p.value)} is not valid for configId ${JSON.stringify(p.configId)}`);switch(p.configId){case"model":{p.value!==m.currentModel&&await m.forwardRequest("session/set_model",{sessionId:p.sessionId,modelId:p.value}),m.applyModelChange(p.value);break}case"mode":{p.value!==m.currentMode&&await m.forwardRequest("session/set_mode",{sessionId:p.sessionId,modeId:p.value}),m.applyModeChange(p.value);break}case"agent":{p.value!==m.agentId&&await m.setAgent(p.value);break}default:throw l(`configId ${JSON.stringify(p.configId)} is not settable`)}return{configOptions:m.buildConfigOptions()}}),a.setDefaultHandler(async(f,p)=>{let l=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),g=p.startsWith("session/"),m=p.startsWith("hydra-acp/");if(!g&&!m||f===null||typeof f!="object"||l.has(p))throw M(k.MethodNotFound,`Method not found: ${p}`);let h=f.sessionId;if(typeof h!="string")throw M(k.MethodNotFound,`Method not found: ${p}`);return u(h,p),ie(e.manager,h).forwardRequest(p,f)})})}async function Ul(n,e){let t=n??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw M(k.InvalidParams,"authenticate requires a non-empty methodId string");let s=t.methodId,r=t._meta?.["hydra-acp"],i=typeof r?.sessionId=="string"?r.sessionId:void 0,o=typeof r?.agentId=="string"?r.agentId:void 0,a=i!==void 0?e.manager.getAgentForSession(i):void 0;if(!a||!a.isAlive()){let l=o??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(l)}let d=a.authMethods??[],u=d.find(l=>l.id===s);if(!u){let l=d.map(g=>g.id);throw M(k.InvalidParams,`authenticate: methodId ${JSON.stringify(s)} is not advertised by agent ${a.agentId}; valid: [${l.map(g=>JSON.stringify(g)).join(", ")}]`)}let c=u._meta?.type,f=(()=>{let l=u._meta?.["terminal-auth"];if(l&&typeof l=="object"&&!Array.isArray(l))return l})();if((u.type??(c==="agent"||c==="terminal"?c:f!==void 0?"terminal":"agent"))==="terminal"){let l=(w,S)=>{if(!Array.isArray(w))throw M(k.InvalidParams,`authenticate: method ${JSON.stringify(s)} ${S} must be a string[]; got ${w===null?"null":typeof w}`);for(let A of w)if(typeof A!="string")throw M(k.InvalidParams,`authenticate: method ${JSON.stringify(s)} ${S} must be string[]; got non-string entry ${JSON.stringify(A)}`);return w},g=await e.manager.planSpawnForAgent(a.agentId),m,h;if(f?.args!==void 0){let w=typeof f.command=="string"?f.command:void 0;m=w!==void 0&&zo.isAbsolute(w)?w:g.command,h=l(f.args,'_meta["terminal-auth"].args')}else{let w=u.args!==void 0?{raw:u.args,label:"args"}:u._meta?.args!==void 0?{raw:u._meta.args,label:"_meta.args"}:void 0,S=w!==void 0?l(w.raw,w.label):[];m=g.command,h=[...g.args,...S]}let y={};for(let[w,S]of Object.entries(process.env))typeof S=="string"&&(y[w]=S);Object.assign(y,g.env);let v=qo.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${s}`),{kind:"terminal",command:m,args:h,env:y,cwd:v}}try{return await a.connection.request("authenticate",{methodId:s})}catch(l){throw Me(l,a)}}async function Dl(n,e){let s=(n??{})._meta?.["hydra-acp"],r=typeof s?.sessionId=="string"?s.sessionId:void 0,i=typeof s?.agentId=="string"?s.agentId:void 0,o=r!==void 0?e.manager.getAgentForSession(r):void 0;if(!o||!o.isAlive()){let a=i??e.defaultAgent;o=await e.manager.bootstrapAgentForAuth(a)}return await o.connection.request("logout",{})}function Do(n){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),n.notify(Nr,t).catch(()=>{})}}function xn(n){let e=n.availableModes();if(e.length===0)return;let t=e.map(r=>{let i={id:r.id,name:r.name??r.id};return r.description!==void 0&&(i.description=r.description),i});return{currentModeId:n.currentMode??e[0].id,availableModes:t}}function Rn(n){let e=n.availableModels();if(e.length===0)return;let t=e.map(r=>{let i={modelId:r.modelId};return r.name!==void 0&&(i.name=r.name),r.description!==void 0&&(i.description=r.description),i});return{currentModelId:n.currentModel??e[0].modelId,availableModels:t}}function Ll(n,e){if(!n||typeof n!="object")return{kind:"error",code:k.InvalidParams,message:"session/set_model requires params",logMessage:"session/set_model rejected: params not an object"};let t=n;if(typeof t.sessionId!="string")return{kind:"error",code:k.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:k.InvalidParams,message:"session/set_model requires string modelId",logMessage:`session/set_model rejected: missing/non-string modelId sessionId=${t.sessionId}`};let s=e.get(t.sessionId);if(!s)return{kind:"error",code:k.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=s.availableModels(),i=Ve(t.modelId,r);if(i.kind==="none")return{kind:"ok",session:s,modelId:t.modelId,logMessage:`session/set_model passthrough (no availableModels) sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(i.kind==="exact")return{kind:"ok",session:s,modelId:t.modelId,logMessage:`session/set_model accepted sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(i.kind==="resolved")return{kind:"ok",session:s,modelId:i.modelId,logMessage:`session/set_model resolved sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} \u2192 ${JSON.stringify(i.modelId)}`};let o=r.map(d=>d.modelId).join(", "),a=i.kind==="ambiguous"?`ambiguous (trailing-segment matches [${i.candidates.join(", ")}])`:"not in availableModels";return s.currentModel!==void 0&&s.currentModel.length>0?{kind:"no_op",session:s,sessionId:t.sessionId,currentModel:s.currentModel,logMessage:`session/set_model no_op (resyncing client) sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} ${a} actual=${JSON.stringify(s.currentModel)} agentId=${s.agentId} known=[${o}]`}:{kind:"error",code:k.InvalidParams,message:`model "${t.modelId}" is ${a==="not in availableModels"?"not in this session's availableModels":a} (agent ${s.agentId}); known models: ${o}`,logMessage:`session/set_model rejected sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)} ${a} agentId=${s.agentId} known=[${o}] (no current model to fall back to)`}}async function ql(n,e,t){let s=n??{},r=typeof s.sessionId=="string"?s.sessionId:void 0;if(!r)throw M(k.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw M(k.InternalError,"transformer manager not configured");let i=t.transformers.resolveChain([e])[0];if(!i)throw M(k.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return ie(t.manager,r).addTransformer(i),{ok:!0}}async function zl(n,e,t){let s=n??{},r=typeof s.sessionId=="string"?s.sessionId:void 0,i=typeof s.reason=="string"?s.reason:void 0;if(!r)throw M(k.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!i)throw M(k.InvalidParams,"hydra-acp/attention/set requires string reason");return ie(t.manager,r).setAttentionFlag(e,i,s.payload),{ok:!0}}async function Jl(n,e,t){let s=n??{},r=typeof s.sessionId=="string"?s.sessionId:void 0,i=typeof s.reason=="string"?s.reason:void 0;if(!r)throw M(k.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!i)throw M(k.InvalidParams,"hydra-acp/attention/clear requires string reason");return ie(t.manager,r).clearAttentionFlag(e,i),{ok:!0}}function Wl(n){let e={sessionId:n.hydraSessionId,upstreamSessionId:n.upstreamSessionId,cwd:n.cwd,title:n.title,agentId:n.agentId,currentModel:n.currentModel,currentUsage:kt(n.currentUsage),forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:n.interactive,updatedAt:n.createdAt??new Date().toISOString(),attachedClients:0,status:"cold",busy:!1,awaitingInput:!1},t={currentMode:n.currentMode,agentArgs:n.agentArgs,availableCommands:n.agentCommands,availableModes:n.agentModes,availableModels:n.agentModels};return{[$e]:Dt(e,t)}}function En(n,e,t={}){let s=n.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(),...t.resurrected===!0?{resurrected:!0}:{}};return pt(e.agentMeta,Dt(s,r))}function Ql(){return{protocolVersion:1,agentInfo:{name:"hydra",version:Y},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:pt(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}}})}}function Gl(n,e){if(!(!e.transformers||!e.manager))for(let t of e.manager.defaultTransformers){let s=e.transformers.resolveChain([t])[0];s&&n.addTransformer(s)}}function Wo(n,e){if(!e.transformers)return;let t=e.transformers.interestedIn("lifecycle:session.starting");for(let s of t)s.connection.notify("hydra-acp/transformer/session_event",{event:"session.starting",sessionId:n}).catch(()=>{})}function Ft(n,e,t,s,r){return{clientId:r??`cli_${Bs(8)}`,connection:n,clientInfo:s}}function Mn(n,e,t){let s=n.attached.get(t);s&&(e.detach(s.clientId),n.attached.delete(t))}var Pn=class{byToken=new Map;reserve(e){if(this.byToken.has(e))throw new Error("mcp token already bound");let t,s,r=new Promise((o,a)=>{t=o,s=a});r.catch(()=>{});let i={session:void 0,sessionReady:r,disposers:[]};return this.byToken.set(e,i),{complete:o=>{i.session=o,t(o)},abandon:o=>{this.byToken.delete(e),s(o??new Error("mcp token reservation abandoned"))}}}bind(e,t){let{complete:s}=this.reserve(e);s(t)}lookup(e){return this.byToken.get(e)}addDisposer(e,t){let s=this.byToken.get(e);s!==void 0&&s.disposers.push(t)}async unbind(e){let t=this.byToken.get(e);if(t!==void 0){this.byToken.delete(e);for(let s of t.disposers)try{await s()}catch{}}}size(){return this.byToken.size}};import{randomUUID as Kl}from"crypto";import{McpServer as Vl}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Yl}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as X}from"zod";function Us(n){if(n.method!=="session/update")return null;let t=n.params?.update;return!t||typeof t.sessionUpdate!="string"?null:{kind:t.sessionUpdate,update:t}}function te(n){return{content:[{type:"text",text:JSON.stringify(n)}],structuredContent:n}}var Qo="Bearer ";function ut(n){let e=n.headers.authorization;if(typeof e!="string"||!e.startsWith(Qo))return;let t=e.slice(Qo.length).trim();return t.length>0?t:void 0}function Xl(n){let e=new Vl({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:X.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let s=n.streamTail(t);return te(s)}),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:X.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let s=n.streamHead(t);return te(s)}),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:X.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:X.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:X.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:s,wait_ms:r})=>{let i=await n.streamRead(t,s,r);return te(i)}),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:X.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:X.number().int().min(0).describe("Maximum ms to block (server caps at 60_000).")}},async({cursor:t,timeout_ms:s})=>{let r=await n.streamWaitFor(t,s),i=n.streamInfo();return te({outcome:r,writeCursor:i.writeCursor,closed:i.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:X.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:X.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:X.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:X.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:X.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:X.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:X.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:X.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:X.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 s={pattern:t.pattern};t.regex!==void 0&&(s.regex=t.regex),t.case_insensitive!==void 0&&(s.caseInsensitive=t.case_insensitive),t.invert!==void 0&&(s.invert=t.invert),t.max_matches!==void 0&&(s.maxMatches=t.max_matches),t.max_bytes!==void 0&&(s.maxBytes=t.max_bytes),t.context_before!==void 0&&(s.contextBefore=t.context_before),t.context_after!==void 0&&(s.contextAfter=t.context_after),t.cursor!==void 0&&(s.cursor=t.cursor);let r=n.streamGrep(s);return te(r)}),e.registerTool("info",{description:"Report cursor / capacity / closed state of the stdin ring. Cheap; safe to call repeatedly.",inputSchema:{}},async()=>{let t=n.streamInfo();return te(t)}),e}var Zl=1e4;function Go(n,e){let t=new Map;async function s(o,a){let d=t.get(o);if(d!==void 0)return d.transport;let u=Xl(a),c=new Yl({sessionIdGenerator:()=>Kl()});await u.connect(c);let f={server:u,transport:c};return t.set(o,f),e.addDisposer(o,async()=>{t.delete(o);try{await c.close()}catch{}try{await u.close()}catch{}}),c}async function r(o,a){let d=ut(o);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let u=e.lookup(d);if(u===void 0){a.code(404).send({error:"unknown stdin token"});return}let c;if(u.session!==void 0)c=u.session;else{let p,l=new Promise(m=>{p=setTimeout(()=>m(void 0),Zl)}),g=await Promise.race([u.sessionReady.catch(()=>{}),l]);if(p!==void 0&&clearTimeout(p),g===void 0){a.code(503).send({error:"session not ready"});return}c=g}let f=await s(d,c);a.hijack(),await f.handleRequest(o.raw,a.raw,o.body)}let i={config:{skipAuth:!0}};n.post("/mcp/hydra-acp-stdin",i,async(o,a)=>{await r(o,a)}),n.get("/mcp/hydra-acp-stdin",i,async(o,a)=>{await r(o,a)}),n.delete("/mcp/hydra-acp-stdin",i,async(o,a)=>{await r(o,a)})}import{randomUUID as ef}from"crypto";import{McpServer as tf}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as nf}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as Pe}from"zod";function sf(n){switch(n){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}function rf(n,e){if(n.length<=148)return n;let r=Math.floor(148/2),i=e-r;i<0&&(i=0);let o=i+148;o>n.length&&(i=n.length-148,i<0&&(i=0));let a=n.slice(i,o);return i>0&&(a="\u2026"+a),o<n.length&&(a=a+"\u2026"),a}function of(n){let e=new tf({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. 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:Pe.string().min(1).describe("Case-insensitive substring to search for."),limit:Pe.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:Pe.boolean().optional().describe("Whether to include tool_call entries in the search (default true).")}},async({query:t,limit:s=10,include_tool_calls:r=!0})=>{let i=await n();if(!i.summarizedThroughEntry||i.summarizedThroughEntry===0)return te({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 o=[],a=t.toLowerCase();for await(let{entryId:u,entry:c}of i.iterRecallNewestFirst()){let f=Us(c);if(!f)continue;let{kind:p}=f;if(p==="tool_call"&&!r)continue;let l=Ye([c]),g=l.toLowerCase().indexOf(a);if(g<0)continue;let m=sf(p),h=rf(l,g),y=typeof c.recordedAt=="number"?String(c.recordedAt):void 0;if(o.push({entryId:u,speaker:m,snippet:h,timestamp:y}),o.length>=s)break}o.sort((u,c)=>u.entryId-c.entryId);let d=o.length>=s;return te({matches:o,total_matched:o.length,truncated:d})}),e.registerTool("range",{description:"Pull a contiguous range of prior conversation entries verbatim from this session's pre-compaction history. Use after `search` narrows in on what you need. Capped at 50 entries per call.",inputSchema:{from_entry:Pe.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:Pe.number().int().min(0).describe("Zero-based index of the last entry to include (inclusive).")}},async({from_entry:t,to_entry:s})=>{let r=await n();if(!r.summarizedThroughEntry||r.summarizedThroughEntry===0)return te({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(s<t)throw new Error(`range: to_entry (${s}) must be >= from_entry (${t})`);let i=s-t+1;if(i>50)throw new Error(`range: range size (${i}) exceeds maximum of 50 entries`);let o=await r.getRecallTotalCount();if(o===0)return te({text:"",entry_count:0,truncated:!1});let a=Math.min(t,o-1),d=Math.min(s,o-1),u=a>t||d<s;if(a>d)return{content:[{type:"text",text:""}],structuredContent:{text:"",entry_count:0,truncated:u}};let c=await r.sliceRecallHistory(a,d),f=Ye(c);return{content:[{type:"text",text:f}],structuredContent:{text:f,entry_count:c.length,truncated:u}}}),e.registerTool("tool_calls",{description:"Search this session's prior tool invocations by tool name and/or file path. Returns when each tool was called, the arguments, and the result status. Use this to recall which files were read/edited, what shell commands ran, etc.",inputSchema:{tool_name:Pe.string().optional(),file_path:Pe.string().optional(),limit:Pe.number().int().min(1).max(100).optional()}},async({tool_name:t,file_path:s,limit:r=20})=>{let i=await n();if(!i.summarizedThroughEntry||i.summarizedThroughEntry===0)return te({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 o=typeof t=="string"&&t.length>0,a=typeof s=="string"&&s.length>0;if(!o&&!a)throw new Error("tool_calls: at least one of tool_name or file_path must be provided");let d=new Map,u=Math.max(r*4,200);for await(let{entryId:l,entry:g}of i.iterRecallNewestFirst()){let m=Us(g);if(!m)continue;let{kind:h,update:y}=m;if(h!=="tool_call"&&h!=="tool_call_update")continue;let v=typeof y.toolCallId=="string"&&y.toolCallId.length>0?y.toolCallId:`__noid_${l}`,w=d.get(v);w||(w={entryId:l,toolName:"(unnamed)",rawInput:{},locations:[],status:"in_progress"},d.set(v,w)),l<w.entryId&&(w.entryId=l),typeof y.name=="string"&&y.name.length>0?w.toolName=y.name:w.toolName==="(unnamed)"&&typeof y.title=="string"&&y.title.length>0&&(w.toolName=y.title);let S=y.rawInput;if(S&&typeof S=="object"&&!Array.isArray(S)&&Object.keys(S).length>0)for(let[A,C]of Object.entries(S))w.rawInput[A]===void 0&&(w.rawInput[A]=C);if(Array.isArray(y.locations))for(let A of y.locations){let C=A?.path;typeof C=="string"&&C.length>0&&!w.locations.includes(C)&&w.locations.push(C)}if(typeof y.status=="string"&&w.status==="in_progress"&&(w.status=y.status),g.recordedAt!==void 0&&w.timestamp===void 0&&(w.timestamp=String(g.recordedAt)),d.size>=u)break}let c=[...d.keys()].sort((l,g)=>d.get(l).entryId-d.get(g).entryId),f=[];for(let l of c){let g=d.get(l);if(t!==void 0&&g.toolName.toLowerCase()!==t.toLowerCase())continue;if(a){let h=s.toLowerCase(),y=["file_path","filePath","path"],v=!1;for(let w of y){let S=g.rawInput[w];if(typeof S=="string"&&S.toLowerCase().includes(h)){v=!0;break}}if(!v){for(let w of g.locations)if(w.toLowerCase().includes(h)){v=!0;break}}if(!v)continue}let m={};for(let[h,y]of Object.entries(g.rawInput))typeof y=="string"?m[h]=y.length>500?y.slice(0,497)+"\u2026":y:(typeof y=="number"||typeof y=="boolean")&&(m[h]=y);if(g.locations.length>0&&m.locations===void 0&&(m.locations=g.locations),f.push({entryId:g.entryId,tool:g.toolName,args:m,status:g.status,timestamp:g.timestamp}),f.length>=r)break}let p=f.length>=r;return te({calls:f,truncated:p})}),e}var af=1e4;function Ko(n,e){let t=new Map;async function s(o,a){let d=t.get(o);if(d!==void 0)return d.transport;let u=of(a),c=new nf({sessionIdGenerator:()=>ef()});await u.connect(c);let f={server:u,transport:c};return t.set(o,f),e.addDisposer(o,async()=>{t.delete(o);try{await c.close()}catch{}try{await u.close()}catch{}}),c}async function r(o,a){let d=ut(o);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let u=e.lookup(d);if(u===void 0){a.code(404).send({error:"unknown recall token"});return}let f=await s(d,async()=>{if(u.session!==void 0)return u.session;let p,l=new Promise(m=>{p=setTimeout(()=>m(void 0),af)}),g=await Promise.race([u.sessionReady.catch(()=>{}),l]);if(p!==void 0&&clearTimeout(p),g===void 0)throw new Error("recall: session not ready");return g});a.hijack(),await f.handleRequest(o.raw,a.raw,o.body)}let i={config:{skipAuth:!0}};n.post("/mcp/hydra-acp-recall",i,async(o,a)=>{await r(o,a)}),n.get("/mcp/hydra-acp-recall",i,async(o,a)=>{await r(o,a)}),n.delete("/mcp/hydra-acp-recall",i,async(o,a)=>{await r(o,a)})}var Tn=class{byName=new Map;changeHandlers=[];register(e,t,s,r){this.byName.set(e,{connection:t,instructions:s,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 s of this.changeHandlers)try{s(e,t)}catch{}}};import{StreamableHTTPServerTransport as gf}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as hf}from"crypto";import{Server as df}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as cf,ListToolsRequestSchema as uf}from"@modelcontextprotocol/sdk/types.js";function Vo(n,e,t,s){let r=typeof t=="function"?async()=>t():async()=>t,i=new df({name:n,version:"1.0.0"},{capabilities:{tools:{listChanged:!0}},...e.instructions!==void 0?{instructions:e.instructions}:{}}),o=a=>({name:a.name,description:a.description,inputSchema:a.inputSchema,...a.outputSchema!==void 0?{outputSchema:a.outputSchema}:{}});return i.setRequestHandler(uf,async()=>{let a=s?.peekSessionId?.();if(a!==void 0&&s?.fetchSessionTools!==void 0)try{let d=await s.fetchSessionTools(a);if(d!==void 0)return{tools:d.map(o)}}catch{}return{tools:e.tools.map(o)}}),i.setRequestHandler(cf,async(a,d)=>{let u=a.params.name,c=d._meta?.progressToken??d.requestId,f=ff(c,d.sendNotification);try{let p=await r(),l=await pf(e.connection,n,u,a.params.arguments??{},p);return mf(l,u)}catch(p){return Ds(p instanceof Error?p.message:String(p))}finally{f()}}),i}var lf=15e3;function ff(n,e,t=lf){if(n===void 0)return()=>{};let s=0,r=setInterval(()=>{s+=1,e({method:"notifications/progress",params:{progressToken:n,progress:s}}).catch(()=>{})},t);return r.unref?.(),()=>clearInterval(r)}async function pf(n,e,t,s,r){return await n.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:s,sessionId:r})}function mf(n,e){if(n===null||typeof n!="object")return Ds(`extension ${e} returned non-object`);let t=n;return Array.isArray(t.content)?t:Ds(`extension ${e} omitted content array`)}function Ds(n){return{content:[{type:"text",text:n}],isError:!0}}var yf=1e4;function Yo(n,e,t){let s=new Map;async function r(c){try{await c.transport.close()}catch{}try{await c.server.close()}catch{}}function i(c){for(let f of s.values()){let p=f.get(c);p!==void 0&&(f.delete(c),r(p))}}async function o(c,f){for(let[p,l]of s){if(e.lookup(p)?.session?.sessionId!==c)continue;let m=l.get(f);if(m!==void 0)try{await m.server.sendToolListChanged()}catch{}}}t.onChange(c=>{i(c)});async function a(c,f){let p=s.get(c);p===void 0&&(p=new Map,s.set(c,p),e.addDisposer(c,async()=>{let S=s.get(c);if(S!==void 0){s.delete(c);for(let A of S.values())await r(A)}}));let l=p.get(f);if(l!==void 0)return l.transport;let g=t.lookup(f);if(g===void 0)return;let v=Vo(f,g,async()=>{let S=e.lookup(c);if(S===void 0)throw new Error("mcp token no longer bound");if(S.session!==void 0)return S.session.sessionId;let A,C=new Promise(T=>{A=setTimeout(()=>T(void 0),yf)}),x=await Promise.race([S.sessionReady.catch(()=>{}),C]);if(A!==void 0&&clearTimeout(A),x===void 0)throw new Error("session not ready");return x.sessionId},{peekSessionId:()=>e.lookup(c)?.session?.sessionId,fetchSessionTools:async S=>{let A=await g.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:S});if(!A||typeof A!="object")return;let C=A.tools;if(!Array.isArray(C))return;let x=[];for(let T of C){if(!T||typeof T!="object")continue;let _=T;if(typeof _.name!="string"||_.name.length===0||typeof _.description!="string"||_.inputSchema===null||typeof _.inputSchema!="object")continue;let B={name:_.name,description:_.description,inputSchema:_.inputSchema};_.outputSchema!==null&&typeof _.outputSchema=="object"&&(B.outputSchema=_.outputSchema),x.push(B)}return x}}),w=new gf({sessionIdGenerator:()=>hf()});return await v.connect(w),p.set(f,{server:v,transport:w}),w}async function d(c,f){let p=ut(c);if(p===void 0){f.code(401).send({error:"missing bearer token"});return}if(e.lookup(p)===void 0){f.code(404).send({error:"unknown mcp token"});return}let g=c.params.name,m=await a(p,g);if(m===void 0){f.code(404).send({error:`unknown mcp server: ${g}`});return}f.hijack(),await m.handleRequest(c.raw,f.raw,c.body)}let u={config:{skipAuth:!0}};return n.post("/mcp/:name",u,async(c,f)=>{await d(c,f)}),n.get("/mcp/:name",u,async(c,f)=>{await d(c,f)}),n.delete("/mcp/:name",u,async(c,f)=>{await d(c,f)}),{notifyToolListChanged:o}}async function sa(n,e){Af(n),ir(n.daemon.scrubEnv);let t=n.daemon.tls?await we.readFile(Z(n.daemon.tls.key)):void 0,s=n.daemon.tls?await we.readFile(Z(n.daemon.tls.cert)):void 0;await we.mkdir(I.home(),{recursive:!0});let{stream:r,fileStream:i}=await If(n.daemon.logLevel),o=wf({logger:{level:n.daemon.logLevel,stream:r},bodyLimit:256*1024*1024});await o.register(vf,{options:{handleProtocols:sr}}),Jn(O=>{o.log.info(O)}),Gn(O=>{o.log.info(O)});let a=await pn.load(),d=new wn,u=new yn,c=new hn([new mn(e),new gn(a),u]),f=to({validator:c});o.addHook("onRequest",async(O,fe)=>{O.routeOptions.config?.skipAuth||O.url==="/acp"||O.url?.startsWith("/acp?")||await f(O,fe)});let p=setInterval(()=>{a.sweepExpired()},300*1e3);p.unref();let l=setInterval(()=>{d.sweepExpired()},300*1e3);l.unref();let g=new Bt(n,{onFetched:()=>{Ji(g,v)}});Ps(O=>o.log.info(O));let m={info:O=>o.log.info(O),warn:O=>o.log.warn(O)},h=O=>Re.spawn({...O,stderrTailBytes:n.daemon.agentStderrTailBytes,logger:m});cr(n.compressToolContent);let y=new ln,v=new sn(g,h,void 0,{idleTimeoutMs:n.daemon.sessionIdleTimeoutSeconds*1e3,defaultModels:n.defaultModels,synopsisAgent:n.synopsisAgent,synopsisModel:n.synopsisModel,compactionAgent:n.compaction?.agent,compactionModel:n.compaction?.model,defaultTransformers:n.defaultTransformers,sessionHistoryMaxEntries:n.daemon.sessionHistoryMaxEntries,sessionHistoryArchiveMaxBytes:n.daemon.sessionHistoryArchiveMaxBytes,sessionHistoryArchiveTiers:n.daemon.sessionHistoryArchiveTiers,logger:m,npmRegistry:n.npmRegistry,extensionCommands:y,defaultCwd:n.defaultCwd}),w=new cn(Zs(n),void 0,{tokenRegistry:u}),S=new un(er(n),void 0,{tokenRegistry:u});To(o,Y,Gi(n));let A=new Pn,C=new Tn,x,T=()=>{if(x!==void 0)return x;let O=o.server.address();return x=`http://127.0.0.1:${O&&typeof O=="object"?O.port:n.daemon.port}`,x};Mo(o,v,{agentId:n.defaultAgent,cwd:n.defaultCwd,publicHost:n.daemon.publicHost,host:n.daemon.host,port:n.daemon.port,compaction:n.compaction},{extensionMcp:C,mcpTokenRegistry:A,getDaemonOrigin:T}),Po(o,g,v,{npmRegistry:n.npmRegistry}),_o(o,w),Fo(o,S),$o(o,{defaultAgent:n.defaultAgent,defaultCwd:n.defaultCwd,defaultModels:{...n.defaultModels},...n.synopsisAgent!==void 0?{synopsisAgent:n.synopsisAgent}:{},...n.synopsisModel!==void 0?{synopsisModel:n.synopsisModel}:{},defaultTransformers:[...n.defaultTransformers]}),Bo(o,{store:a,rateLimiter:d}),Go(o,A),Ko(o,A);let _=Yo(o,A,C);Jo(o,{validator:c,manager:v,defaultAgent:n.defaultAgent,processRegistry:u,onExtensionVersion:(O,fe)=>w.reportVersion(O,fe),onTransformerVersion:(O,fe)=>S.reportVersion(O,fe),transformers:S,extensionCommands:y,mcpTokenRegistry:A,extensionMcp:C,extensionMcpControls:_,getDaemonOrigin:T,registry:g});let B=!!n.daemon.tls;await o.listen({host:B?"127.0.0.1":n.daemon.host,port:B?0:n.daemon.port});let F=o.server.address(),P=F&&typeof F=="object"?F.port:n.daemon.port,U,J=n.daemon.host,ne=P;if(B&&t&&s){U=kf({listenHost:n.daemon.host,listenPort:n.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:P,tlsOptions:{key:t,cert:s},logger:o.log});let O=U.address();O&&typeof O=="object"&&(ne=O.port)}await we.mkdir(I.home(),{recursive:!0}),await zi({pid:process.pid,host:J,port:ne,loopbackPort:P,startedAt:new Date().toISOString()});let je={daemonUrl:`http://127.0.0.1:${P}`,daemonHost:"127.0.0.1",daemonPort:P,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${P}/acp`,hydraHome:I.home()};w.setContext(je),S.setContext(je),await w.start(),await S.start();try{await v.reconcilePermissionFlags()}catch(O){o.log.warn(`permission flag reconcile failed: ${O.message}`)}v.resurrectPendingQueues().catch(O=>{o.log.warn(`queue replay scan failed: ${O.message}`)}),v.resumePendingCompactions().catch(O=>{o.log.warn(`compaction resume scan failed: ${O.message}`)}),v.resumePendingAgentSwaps().catch(O=>{o.log.warn(`agent-swap resume scan failed: ${O.message}`)});let $t=n.daemon.agentSyncIntervalMinutes*60*1e3,zs=$t>0?Wi({registry:g,manager:v,intervalMs:$t,logger:m}):void 0,Js=n.daemon.sessionGcIntervalMinutes*60*1e3,ma=n.daemon.sessionGcMaxAgeDays*24*60*60*1e3,Ws=Js>0?Qi({manager:v,intervalMs:Js,maxAgeMs:ma,logger:m}):void 0;return{app:o,manager:v,registry:g,extensions:w,transformers:S,mcpTokenRegistry:A,extensionMcp:C,processRegistry:u,shutdown:async()=>{Ws&&Ws(),zs&&zs(),clearInterval(p),clearInterval(l);let O=async(fe,ga)=>{try{await ga()}catch(Fn){o.log.warn(`shutdown step ${fe} failed: ${Fn instanceof Error?Fn.message:String(Fn)}`)}};await O("sessionTokenStore.flush",()=>a.flush()),await O("extensions.stop",()=>w.stop()),await O("transformers.stop",()=>S.stop()),await O("manager.closeAll",()=>v.closeAll()),await O("manager.flushSynopsis",()=>v.flushSynopsis(3e4)),await O("manager.shutdownSynopsis",()=>v.shutdownSynopsis()),await O("manager.flushMetaWrites",()=>v.flushMetaWrites()),await O("manager.flushHistoryWrites",()=>v.flushHistoryWrites()),Jn(null),Gn(null),Ps(null),U&&await O("tlsTerminator.close",()=>new Promise(fe=>U.close(()=>fe()))),await O("app.close",()=>o.close());try{ea.unlinkSync(I.pidFile())}catch{}await O("fileStream.flushSync",()=>i.flushSync())}}}var Zo=20;async function Sf(n,e){let t=lt.dirname(n),s=lt.basename(n,".log"),r=new RegExp(`^${s}\\.(\\d+)\\.log$`),i;try{i=await we.readdir(t)}catch{return}let o=[];for(let d of i){let u=d.match(r);u&&o.push({name:d,n:Number(u[1])})}if(o.length<=e)return;o.sort((d,u)=>d.n-u.n);let a=o.slice(0,o.length-e);await Promise.allSettled(a.map(d=>we.unlink(lt.join(t,d.name))))}async function If(n){await Sf(I.logFile(),Zo);let e=await bf({file:I.logFile(),size:"10m",mkdir:!0,symlink:!0,limit:{count:Zo,removeOtherLogFiles:!0}}),t=Xo.destination(2);return{stream:Xo.multistream([{stream:e,level:n},{stream:t,level:n}]),fileStream:e}}function kf(n){let e=na.createServer(n.tlsOptions,t=>{let s=ta.connect({host:n.upstreamHost,port:n.upstreamPort}),r=!1,i=o=>{if(!r){r=!0,o&&n.logger.warn(`tls terminator forwarder error: ${o.message??String(o)}`);try{t.destroy()}catch{}try{s.destroy()}catch{}}};t.on("error",i),s.on("error",i),t.on("close",()=>i()),s.on("close",()=>i()),t.pipe(s),s.pipe(t)});return e.on("tlsClientError",t=>{n.logger.warn(`tls handshake error: ${t.message}`)}),e.listen({host:n.listenHost,port:n.listenPort}),e}function Af(n){let e=n.daemon.host;if(!(e==="127.0.0.1"||e==="::1"||e==="localhost"||e==="[::1]")&&!n.daemon.tls)throw new Error(`Refusing to bind to non-loopback host ${e} without TLS configured.`)}async function Bf(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:n}=await Promise.resolve().then(()=>(pa(),fa));n();let e=await Bn(),t=await Qs(),s=await sa(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
149
- `);let r=1e4,i=!1,o=async()=>{i&&(process.stderr.write(`Second signal received; exiting immediately.
150
- `),process.exit(1)),i=!0,process.stdout.write(`Shutting down...
132
+ `)}e.child=m,e.logStream=a,e.pid=typeof m.pid=="number"?m.pid:void 0,e.startedAt=Date.now(),e.lastExitCode=void 0,m.on("error",h=>{a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} error: ${h.message}
133
+ `)}),m.on("exit",(h,y)=>{try{fn.unlinkSync(this.adapter.paths.pidFile(r.name))}catch{}a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} exited code=${h??"null"} signal=${y??"null"}
134
+ `),e.child=void 0,e.pid=void 0,e.lastExitCode=typeof h=="number"?h:void 0,e.processToken&&(this.tokenRegistry?.revoke(r.name),e.processToken=void 0);let b=e.exitWaiters.splice(0);for(let v of b)v();if(this.stopping||e.manuallyStopped){try{a.end()}catch{}e.logStream=void 0;return}e.restartCount+=1;let w=e.breaker.recordExit(h,r.name,this.adapter.kind);if(typeof w=="object"){e.failureReason=w.tripped,a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} circuit breaker tripped: ${w.tripped}
135
+ `);try{a.end()}catch{}e.logStream=void 0;return}this.scheduleRestart(e,t+1)})}scheduleRestart(e,t){if(this.stopping||e.manuallyStopped)return;let s=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}`})},s),typeof e.restartTimer.unref=="function"&&e.restartTimer.unref()}managerName(){return this.adapter.kind==="extension"?"ExtensionManager":"TransformerManager"}};function Os(n){try{return process.kill(n,0),!0}catch{return!1}}function Tt(n,e){return n.code=e,n}W();var Pu={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:I.extensionsDir,logFile:I.extensionLogFile,pidFile:I.extensionPidFile}},mn=class extends dt{constructor(e,t,s={}){super(e,Pu,t,s)}};W();var _u={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:I.transformersDir,logFile:I.transformerLogFile,pidFile:I.transformerPidFile}},gn=class extends dt{connected=new Map;constructor(e,t,s={}){super(e,_u,t,s)}registerConnection(e,t,s){this.connected.set(e,{name:e,connection:t,intercepts:new Set(s)})}deregisterConnection(e){this.connected.delete(e)}resolveChain(e){let t=[];for(let s of e){let r=this.connected.get(s);r&&t.push(r)}return t}interestedIn(e){let t=[];for(let s of this.connected.values())s.intercepts.has(e)&&t.push(s);return t}};var hn=class{entries=new Map;changeHandlers=[];register(e,t,s){this.entries.set(e,{connection:t,commands:[...s]}),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,s]of this.entries)for(let r of s.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{}}};W();W();import*as Ns from"fs/promises";async function oi(n){await Ns.writeFile(I.pidFile(),JSON.stringify(n)+`
136
+ `,{encoding:"utf8",mode:384})}W();import*as _t from"fs/promises";import*as yn from"path";var Pt=n=>{process.stderr.write(n+`
137
+ `)};function Hs(n){Pt=n??(e=>process.stderr.write(e+`
138
+ `))}async function ii(n,e){let t=me();if(!t)return;let s=await n.load(),r=new Map;for(let d of s.agents)r.set(d.id,d.version??"current");let o=e.activeAgentVersions(),i=yn.join(I.agentsDir(),t),a;try{a=await _t.readdir(i,{withFileTypes:!0})}catch(d){let u=d;if(u.code==="ENOENT")return;Pt(`hydra-acp: prune: failed to read ${i}: ${u.message}`);return}for(let d of a){if(!d.isDirectory())continue;let u=d.name,c=r.get(u);if(c===void 0)continue;let f=o.get(u)??new Set,p=yn.join(i,u),l;try{l=await _t.readdir(p,{withFileTypes:!0})}catch(m){Pt(`hydra-acp: prune: failed to read ${p}: ${m.message}`);continue}for(let m of l){if(!m.isDirectory())continue;let g=m.name;if(g===c||f.has(g)||g.includes(".partial-"))continue;let h=yn.join(p,g);try{await _t.rm(h,{recursive:!0,force:!0}),Pt(`hydra-acp: pruned stale ${u} ${g} (${h})`)}catch(y){Pt(`hydra-acp: prune: failed to remove ${h}: ${y.message}`)}}}}function ai(n){let e,t=!1,s=0,r=(a,d)=>{n.logger&&n.logger[a](`agent-sync: ${d}`)},o=async()=>{let a=[];try{let c=await n.registry.load();for(let f of c.agents)await ts(f)==="yes"&&a.push(f.id)}catch(c){return r("warn",`registry load failed: ${c.message}`),n.intervalMs}if(a.length===0)return n.intervalMs;let d=s%a.length;s=(s+1)%a.length;let u=a[d];try{let{synced:c,skipped:f}=await n.manager.syncFromAgent(u);r("info",`${u}: synced ${c.length}, skipped ${f}`)}catch(c){r("warn",`${u}: ${c.message}`)}return Math.max(1,Math.floor(n.intervalMs/a.length))},i=a=>{t||(e=setTimeout(()=>{o().then(d=>{i(d)}).catch(d=>{r("warn",`tick crashed: ${d.message}`),i(n.intervalMs)})},a),e.unref())};return i(n.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}async function js(n){let e=n.maxDeletions??200,t=(l,m)=>{n.logger&&n.logger[l](`session-gc: ${m}`)},s=Date.now(),r=n.maxAgeMs>0?s-n.maxAgeMs:Number.POSITIVE_INFINITY,o=await n.manager.list({includeNonInteractive:!0}).catch(l=>(t("warn",`manager.list failed: ${l.message}`),[])),i=[];for(let l of o){if(l.status!=="cold")continue;if((n.selection??"explicit")==="explicit"){if(l.interactive!==!1)continue}else if(l.interactive===!0)continue;let g=Date.parse(l.updatedAt);Number.isFinite(g)&&(n.maxAgeMs>0&&g>r||i.push({sessionId:l.sessionId,lastUsedMs:g}))}if(i.length===0)return n.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((l,m)=>l.lastUsedMs-m.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,u=0,c=0;for(let{sessionId:l}of a)try{await n.manager.deleteRecord(l,"expired")&&(u+=1)}catch(m){c+=1,t("warn",`delete ${l} failed: ${m.message}`)}let f=i.length-a.length;if(n.verbose||u>0||c>0){let l=(n.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${u} ${l} session(s) older than ${$u(n.maxAgeMs)}`+(c>0?`; ${c} failed`:"")+(f>0?`; ${f} deferred to next sweep`:""))}let p={considered:i.length,deleted:u,failed:c,deferred:f};return d!==void 0&&(p.oldestLastUsedMs=d),p}function di(n){let e,t=!1,s=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!s){s=!0;try{await js({manager:n.manager,maxAgeMs:n.maxAgeMs,selection:"unpromoted",...n.maxDeletionsPerSweep!==void 0?{maxDeletions:n.maxDeletionsPerSweep}:{},...n.logger?{logger:n.logger}:{}})}finally{s=!1}}})().catch(a=>{n.logger?.warn(`session-gc: sweep crashed: ${a.message}`)}).finally(()=>{r(n.intervalMs)})},o),e.unref())};return r(n.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}function $u(n){if(n<=0)return"any age";let e=n/(1440*60*1e3);if(e>=1)return`${e.toFixed(e>=10?0:1)}d`;let t=n/(3600*1e3);return`${t.toFixed(t>=10?0:1)}h`}import{createHash as Fu}from"crypto";function Bs(n){if(Array.isArray(n))return n.map(Bs);if(n!==null&&typeof n=="object"){let e={};for(let t of Object.keys(n).sort())e[t]=Bs(n[t]);return e}return n}function ci(n){let{tui:e,...t}=n,s=JSON.stringify(Bs(t));return Fu("sha256").update(s).digest("hex").slice(0,16)}W();Fe();import*as fi from"path";import{createHash as Ou,randomBytes as Nu,timingSafeEqual as Hu}from"crypto";var pi="hydra_session_",ju=3600*24*30,ui=12,Bu=32,Uu=50;function Du(){return fi.join(I.home(),"session-tokens.json")}function li(n){return Ou("sha256").update(n).digest("hex")}function mi(n){return Nu(n).toString("hex")}function Lu(){return mi(ui).slice(0,ui*2)}function qu(){return`${pi}${mi(Bu)}`}var wn=class n{records=new Map;writeTimer=null;writeInflight=null;filePath;constructor(e,t){this.filePath=t;for(let s of e)this.records.set(s.hash,s)}static async load(){let e=[],t=Du(),s=await ue(t);s&&Array.isArray(s.records)&&(e=s.records.filter(zu));let r=new n(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=qu(),s=li(t),r=Lu(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:ju,a=new Date(o.getTime()+i*1e3),d={id:r,hash:s,label:e.label,createdAt:o.toISOString(),expiresAt:a.toISOString(),lastUsedAt:o.toISOString()};return this.records.set(s,d),this.scheduleWrite(),{id:r,token:t,expiresAt:d.expiresAt}}async verify(e){if(typeof e!="string"||!e.startsWith(pi))return;let t=li(e),s=this.records.get(t);if(!s)return;let r=Buffer.from(s.hash,"hex"),o=Buffer.from(t,"hex");if(r.length!==o.length||!Hu(r,o))return;let i=new Date;if(new Date(s.expiresAt).getTime()<=i.getTime()){this.records.delete(t),this.scheduleWrite();return}return s.lastUsedAt=i.toISOString(),this.scheduleWrite(),s.id}async revoke(e){for(let[t,s]of this.records)if(s.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:s,expiresAt:r,lastUsedAt:o})=>({id:e,label:t,createdAt:s,expiresAt:r,lastUsedAt:o})).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}sweepExpired(e=new Date){let t=0;for(let[s,r]of this.records)new Date(r.expiresAt).getTime()<=e.getTime()&&(this.records.delete(s),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(()=>{})},Uu))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>ce(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 zu(n){if(!n||typeof n!="object")return!1;let e=n;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 gi="Bearer ",bn=class{constructor(e){this.token=e}token;async validate(e){return Ju(e,this.token)?"service":void 0}},vn=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},Sn=class{constructor(e){this.validators=e}validators;async validate(e){for(let t of this.validators){let s=await t.validate(e);if(s!==void 0)return s}}};function hi(n){return async function(t,s){let r=t.headers.authorization;if(!r||!r.startsWith(gi)){s.code(401).send({error:"Missing bearer token"});return}let o=r.slice(gi.length).trim(),i=await n.validator.validate(o);if(!i){s.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function yi(n){let e=n.headers["sec-websocket-protocol"],t=Array.isArray(e)?e.join(","):e;if(t)for(let s of t.split(",")){let r=s.trim(),o="hydra-acp-token.";if(r.startsWith(o))return r.slice(o.length)}if(n.url)try{let r=new URL(n.url,"http://localhost").searchParams.get("token");if(r)return r}catch{return}}var In=class{tokens=new Map;mint(e,t){let s=Un();return this.tokens.set(s,{name:e,kind:t}),s}revoke(e){for(let[t,s]of this.tokens)s.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}`}};function Ju(n,e){if(n.length!==e.length)return!1;let t=0;for(let s=0;s<n.length;s+=1)t|=n.charCodeAt(s)^e.charCodeAt(s);return t===0}var kn=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(),s=this.entries.get(e);if(!s||t-s.windowStart>this.windowMs){this.entries.set(e,{fails:1,windowStart:t});return}s.fails+=1}recordSuccess(e){this.entries.delete(e)}sweepExpired(){let e=Date.now();for(let[t,s]of this.entries)e-s.windowStart>this.windowMs&&this.entries.delete(t)}};import*as Js from"fs";import*as Di from"os";import*as Li from"path";import*as Ws from"readline";W();function Us(n){return Math.floor(n/4)}function wi(n){let e=0,t=new Map;for(let s of n){let r=s.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+=He(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=Wu(i),u=t.get(a)??0;d>u&&t.set(a,d);break}default:break}}for(let s of t.values())e+=s;return e}function Wu(n){let e=0;return typeof n.title=="string"&&(e+=n.title.length),e+=An(n.rawInput),e+=He(n.content),e+=An(n.rawOutput),e}function An(n){if(n==null)return 0;if(typeof n=="string")return n.length;if(typeof n=="number"||typeof n=="boolean")return String(n).length;if(Array.isArray(n)){let e=0;for(let t of n)e+=An(t);return e}if(typeof n=="object"){let e=n.bytes;if(typeof n.__hydraBlob=="string"&&typeof e=="number")return e;let t=0;for(let s of Object.values(n))t+=An(s);return t}return 0}function He(n){if(n==null)return 0;if(typeof n=="string")return n.length;if(Array.isArray(n)){let t=0;for(let s of n)t+=He(s);return t}if(typeof n!="object")return 0;let e=n;return typeof e.__hydraBlob=="string"&&typeof e.bytes=="number"?e.bytes:e.text!==void 0?He(e.text):e.type==="diff"?He(e.oldText)+He(e.newText):e.content!==void 0?He(e.content):0}function bi(n){if(n.compactionInFlight||n.totalEntries===0)return!1;let e,t;if(typeof n.agentReportedUsed=="number"&&typeof n.agentReportedSize=="number"&&n.agentReportedSize>0)e=n.agentReportedUsed/n.agentReportedSize,t=!0;else{let r=Us(n.unsummarizedChars),o=n.currentModel!==void 0?n.config.modelContextWindows[n.currentModel]??n.config.absoluteFallback:n.config.absoluteFallback;e=r/o,t=!1}if(t&&e>=n.config.hardCeilingFraction)return!0;let s=n.nowMs-n.lastActivityMs;return e>=n.config.contextFraction&&s>=n.config.idleBeforePromptMs}W();import{posix as Vu}from"path";import Qu from"strip-ansi";function $t(n){if(!n||typeof n!="object")return;let e=n;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}var Gu=/[\x00-\x08\x0b-\x1f\x7f]/g;function ae(n){return Qu(n).replace(Gu,"")}function Q(n){return ae(n).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function Ii(n,e={}){if(!n||typeof n!="object")return null;let t=n,s=t.sessionUpdate??t.kind;if(typeof s!="string")return null;switch(s){case"agent_message_chunk":return nl(t);case"agent_thought_chunk":case"agent_thought":return sl(t);case"user_message_chunk":return rl(t);case"prompt_received":return ol(t);case"tool_call":return il(t,e);case"tool_call_update":return ll(t,e);case"plan":return gl(t);case"current_mode_update":return hl(t);case"current_model_update":return yl(t);case"turn_complete":return wl(t);case"usage_update":return tl(t);case"available_commands_update":return Zu(t);case"available_modes_update":return el(t);case"session_info_update":return Yu(t);case"config_option_update":return Ku(t);default:return{kind:"unknown",sessionUpdate:s,raw:n}}}function Ku(n){let e=n.configOptions;if(!Array.isArray(e))return null;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s;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 Yu(n){let e=V(n,"title"),t=e!==void 0?Q(e):void 0,s=n._meta,r,o;if(s&&typeof s=="object"&&!Array.isArray(s)){let a=s["hydra-acp"];if(a&&typeof a=="object"&&!Array.isArray(a)){let d=a.agentId;if(typeof d=="string"&&(r=d),"pendingAgentSwap"in a){let u=a.pendingAgentSwap;typeof u=="string"?o=u:u===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 Xu(n){if(!Array.isArray(n))return[];let e=[];for(let t of n){if(!t||typeof t!="object")continue;let s=t;if(typeof s.name!="string"||s.name.length===0)continue;let r=s.name.startsWith("/")?s.name:`/${s.name}`,o={name:Q(r)};typeof s.description=="string"&&(o.description=Q(s.description)),e.push(o)}return e}function Zu(n){let e=n.availableCommands??n.commands;return Array.isArray(e)?{kind:"available-commands",commands:Xu(e)}:null}function el(n){let e=n.availableModes;if(!Array.isArray(e))return null;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s;if(typeof r.id!="string"||r.id.length===0)continue;let o={id:Q(r.id)};typeof r.name=="string"&&(o.name=Q(r.name)),typeof r.description=="string"&&(o.description=Q(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function tl(n){let e={kind:"usage-update"};if(typeof n.used=="number"&&(e.used=n.used),typeof n.size=="number"&&(e.size=n.size),n.cost&&typeof n.cost=="object"){let t=n.cost;typeof t.amount=="number"&&(e.costAmount=t.amount),typeof t.currency=="string"&&(e.costCurrency=t.currency)}return e}function nl(n){let e=Ft(n.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:$t(n)}}function sl(n){let e=typeof n.text=="string"?ae(n.text):Ft(n.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:$t(n)}}function rl(n){let e=n._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){let s=e["hydra-acp"];if(s&&typeof s=="object"&&!Array.isArray(s)&&s.compatFor==="prompt_received")return null}let t=Ft(n.content);return t===null?null:{kind:"user-text",text:t}}function ol(n){let e=bl(n.prompt);return e===null?null:{kind:"user-text",text:e}}function ki(n){return n?n.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function vi(n){if(typeof n=="string")return{text:n};if(n&&typeof n=="object"&&!Array.isArray(n)){let e=n;if(typeof e.__hydraBlob=="string")return{ref:{hash:e.__hydraBlob,bytes:typeof e.bytes=="number"?e.bytes:0}}}}function Cn(n){let e=n.content;if(Array.isArray(e))for(let s of e){if(!s||typeof s!="object")continue;let r=s;if(r.type!=="diff")continue;let o=vi(r.oldText),i=vi(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=n.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let s=t,r=typeof s.file_path=="string"?s.file_path:typeof s.path=="string"?s.path:void 0;if(typeof s.old_string=="string"&&typeof s.new_string=="string")return{...r!==void 0?{path:r}:{},oldText:s.old_string,newText:s.new_string};if(typeof s.content=="string")return{...r!==void 0?{path:r}:{},oldText:"",newText:s.content}}return null}function Ai(n){let e=n.rawInput;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e.plan;return typeof t!="string"||t.length===0?null:ae(t)}function il(n,e={}){let t=V(n,"toolCallId")??V(n,"id");if(!t)return null;let s=V(n,"title")??V(n,"name")??V(n,"label")??"tool call",r=V(n,"name")??V(n,"title");if(ki(r)){let m=Ai(n);if(m!==null){let g=V(n,"status"),h={kind:"exit-plan-mode",toolCallId:t,plan:m};return g!==void 0&&(h.status=g),h}}let o=Mi(Q(s),n,e),i=V(n,"status"),a=V(n,"kind"),d={kind:"tool-call",toolCallId:t,title:o};i!==void 0&&(d.status=i),a!==void 0&&(d.rawKind=a);let u=Cn(n);u!==null&&(d.editDiff=u);let c=xi(n);c!==void 0&&(d.detail=c);let f=Ds(n);f!==void 0&&(d.detailFull=f);let p=Ci(n);p!==void 0&&(d.locations=p);let l=$t(n);return l!==void 0&&(d.workerTaskId=l),d}function Ci(n){let e=n.locations;if(!Array.isArray(e))return;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s;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 Si=64;function xi(n){let e=Ds(n);if(e===void 0)return;let t=Q(e),s=n.rawInput;return s&&typeof s.command=="string"?cl(t,Si):ul(t,Si)}function Ds(n){let e=n.rawInput;if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.command=="string"&&t.command.trim().length>0)return ae(t.command).trim().replace(/^cd\s+\S+\s+&&\s+/,"");let s=typeof t.file_path=="string"?t.file_path:typeof t.filePath=="string"?t.filePath:typeof t.path=="string"?t.path:void 0;if(s!==void 0&&s.length>0)return $e(Q(s))}if(Array.isArray(n.locations)){for(let t of n.locations)if(t&&typeof t=="object"){let s=t.path;if(typeof s=="string"&&s.length>0)return $e(Q(s))}}}var al=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function dl(n){for(let e of al)if(n.startsWith(e))return!0;return!1}function Mi(n,e,t={}){if(n.length===0)return n;if(n.startsWith("/"))return $e(n);if(n.startsWith("~")||!n.includes("/")||/\s/.test(n))return n;let s=e.rawInput;if(s&&typeof s=="object"&&!Array.isArray(s)){let r=s,o=[r.file_path,r.filePath,r.path];for(let i of o)if(!(typeof i!="string"||i.length===0)&&(i===`/${n}`||i.endsWith(`/${n}`)||i===n))return $e(i)}return dl(n)?$e(`/${n}`):t.cwd&&t.cwd.length>0?$e(Vu.resolve(t.cwd,n)):n}function cl(n,e){return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function ul(n,e){if(n.length<=e)return n;let t=n.slice(-(e-1)),s=t.indexOf("/");return s>=0&&s<e/2?`\u2026${t.slice(s)}`:`\u2026${t}`}function ll(n,e={}){let t=V(n,"toolCallId")??V(n,"id");if(!t)return null;let s=V(n,"title"),r=s!==void 0?Mi(Q(s),n,e):void 0,o=V(n,"status"),i=Cn(n),a=xi(n),d=fl(n);if(!(r!==void 0||i!==null||a!==void 0||d!==void 0||o==="completed"||o==="failed"||o==="rejected"||o==="cancelled"))return null;let c=V(n,"name")??s;if(ki(c)){let g={kind:"exit-plan-mode",toolCallId:t},h=Ai(n);return h!==null&&(g.plan=h),o!==void 0&&(g.status=o),g}let f={kind:"tool-call-update",toolCallId:t};r!==void 0&&(f.title=r),a!==void 0&&(f.detail=a);let p=Ds(n);p!==void 0&&(f.detailFull=p);let l=Ci(n);if(l!==void 0&&(f.locations=l),d!==void 0&&(f.resultSummary=d),o!==void 0&&(f.status=o),i!==null&&(f.editDiff=i),o==="failed"){let g=pl(n);g!==null&&(f.errorText=g),ml(n,g)&&(f.upstreamInterrupted=!0)}let m=$t(n);return m!==void 0&&(f.workerTaskId=m),f}function fl(n){if(!n||typeof n!="object")return;let e=n.rawOutput;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,s=c=>{let f=t[c];return typeof f=="number"&&Number.isFinite(f)?f:void 0},r=(c,f,p=`${f}s`)=>`${c} ${c===1?f:p}`,o=[],i=s("totalMatches");i!==void 0&&o.push(r(i,"match","matches"));let a=s("totalFiles");a!==void 0&&o.push(r(a,"file"));let d=s("referenceCount");d!==void 0&&o.push(r(d,"reference")),o.length>0&&t.truncated===!0&&o.push("truncated");let u=s("exitCode");return u!==void 0&&u!==0&&o.push(`exit ${u}`),o.length>0?o.join(", "):void 0}function pl(n){let e=n.content;if(Array.isArray(e))for(let s of e){if(!s||typeof s!="object")continue;let o=Ft(s.content);if(o!==null&&o.length>0)return o}let t=n.rawOutput;if(t&&typeof t=="object"){let s=t.error;if(typeof s=="string"&&s.length>0)return ae(s)}return null}function ml(n,e){let t=n.rawOutput;if(t&&typeof t=="object"){let s=t.metadata;if(s&&typeof s=="object"&&s.interrupted===!0)return!0}return!!(e!==null&&e.toLowerCase().includes("tool execution aborted"))}function gl(n){let e=n.entries;if(!Array.isArray(e)||e.length===0)return null;let t=[];for(let s of e){if(!s||typeof s!="object")continue;let r=s,o=typeof r.content=="string"?Q(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 hl(n){let e=V(n,"currentModeId")??V(n,"currentMode")??V(n,"mode");return e?{kind:"mode-changed",mode:Q(e)}:null}function yl(n){let e=V(n,"currentModel")??V(n,"model");if(!e)return null;let t=n.availableModels,s=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:Q(e),...s&&s.length>0?{availableModels:s}:{}}}function wl(n){let e=V(n,"stopReason"),t=n._meta,s=t?.["hydra-acp"]?.amended!==void 0&&t["hydra-acp"].amended!==null,r={kind:"turn-complete"};return e!==void 0&&(r.stopReason=e),s&&(r.amended=!0),r}function Ft(n){if(typeof n=="string")return ae(n);if(!n||typeof n!="object")return null;let e=n;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?ae(e.text):null}function bl(n){if(!Array.isArray(n))return null;let e=[];for(let t of n){let s=Ft(t);s!==null&&e.push(s)}return e.length===0?null:e.join("")}function V(n,e){let t=n[e];return typeof t=="string"?t:void 0}function Ei(n){let e=new Map,t=new Map;for(let r of n){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,u=Sl(i);if(u.length===0)continue;let c=u;if(d!==void 0){let f=e.get(d)??[],p=[];for(let l of u)f.some(m=>m.path===l.path&&m.oldText===l.oldText&&m.newText===l.newText)||p.push(l);if(p.length===0)continue;e.set(d,[...f,...p]),c=p}for(let f of c)vl(t,f)}let s=[];for(let[r,o]of t)s.push({path:r,hunks:o.hunks,created:o.created});return s}function Ri(n){let e=[];for(let t of n){let s=-1;for(let o=e.length-1;o>=0;o--)if(e[o].newText===t.oldText){s=o;break}if(s===-1){e.push(t);continue}let r=e[s];e.splice(s,1,{oldText:r.oldText,newText:t.newText})}return e}function vl(n,e){let t={oldText:e.oldText,newText:e.newText},s=n.get(e.path);if(s===void 0){n.set(e.path,{hunks:[t],created:e.oldText.length===0});return}s.hunks.push(t)}function Sl(n){let e=[],t=n.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 u=d,c=typeof u.old_string=="string"?u.old_string:void 0,f=typeof u.new_string=="string"?u.new_string:void 0;c===void 0||f===void 0||e.push({path:i,oldText:c,newText:f})}if(e.length>0)return e}}let s=n.content;if(Array.isArray(s)){for(let o of s){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:"",u=typeof i.newText=="string"?i.newText:"";e.push({path:a,oldText:d,newText:u})}if(e.length>0)return e}let r=Cn(n);return r&&r.path&&e.push({path:r.path,oldText:r.oldText,newText:r.newText}),e}function Pi(n,e={}){let t=kl(n),{events:s,window:r}=Il(t,e),o=Al(s),i=[];Cl(i,n),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),xl(i,s,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
139
+ `);return a.endsWith(`
140
+ `)||(a+=`
141
+ `),a}function Ls(n,e){let t=n<0?e+n+1:n;return t<1?1:t>e?e:t}function Il(n,e){if(!(e.from!==void 0||e.to!==void 0||e.last!==void 0)&&e.sinceMs===void 0)return{events:n};let s=[],r=0;for(let{event:l}of n)l.kind==="user-text"&&(r+=1),s.push(r===0?1:r);let o=Math.max(r,1),i=1,a=o;if(e.last!==void 0&&e.last>0?i=Ls(o-e.last+1,o):(e.from!==void 0&&(i=Ls(e.from,o)),e.to!==void 0&&(a=Ls(e.to,o))),i>a)return{events:[],window:{from:i,to:a,total:o}};let d=e.sinceMs,u=new Set;d!==void 0&&n.forEach((l,m)=>{l.recordedAt>=d&&u.add(s[m])});let c=[],f,p;return n.forEach((l,m)=>{let g=s[m];g<i||g>a||d!==void 0&&!u.has(g)||(c.push(l),f??=g,p=g)}),{events:c,window:{from:f??i,to:p??a,total:o}}}function kl(n){let e=[];for(let t of n.history){if(t.method!=="session/update")continue;let s=t.params;if(!s||typeof s!="object")continue;let r=Ii(s.update,{cwd:n.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function Al(n){let e=new Map;for(let{event:t}of n){if(t.kind==="tool-call"){let s=e.get(t.toolCallId);e.set(t.toolCallId,{title:t.title,status:t.status??s?.status??"pending"});continue}if(t.kind==="tool-call-update"){let s=e.get(t.toolCallId)??{title:"tool call",status:"pending"};e.set(t.toolCallId,{title:t.title??s.title,status:t.status??s.status})}}return e}function Cl(n,e){let t=e.session,s=vo(t.sessionId),r=t.title?.trim()||`Hydra session ${s}`;n.push(`# ${ct(r)}`),n.push("");let o=[];o.push(`- **Session:** \`${s}\` (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 c=a.size!==void 0?`${qs(a.size)}`:void 0;d.push(c?`${qs(a.used)} / ${c} tokens`:`${qs(a.used)} tokens`)}let u=Es(a);if(u!==void 0){let c=a.costCurrency??"USD";d.push(`$${u.toFixed(2)} ${c}`)}o.push(`- **Usage:** ${d.join(" \xB7 ")}`)}n.push(o.join(`
142
+ `)),n.push("")}function xl(n,e,t,s){let{includeTools:r,includeThoughts:o}=s;if(!e.some(g=>Ml(g.event,o))){n.push("_No conversation history recorded._"),n.push("");return}let i=0,a="",d="",u=[],c=new Set,f=!1,p=()=>{if(u.length!==0){for(let g of u)n.push(g);n.push(""),u=[]}},l=()=>{p(),d.length>0&&(Ti(n,d.trimEnd(),"*"),n.push(""),d=""),a.length!==0&&(n.push(a.trimEnd()),n.push(""),a="")},m=()=>{f||(f=!0)};for(let{event:g}of e)switch(g.kind){case"user-text":{l(),n.push("---"),n.push(""),i+=1,Ti(n,g.text,"**"),n.push(""),f=!0;break}case"agent-text":m(),a+=g.text;break;case"agent-thought":{if(!o)break;m(),a.length>0&&(n.push(a.trimEnd()),n.push(""),a=""),d+=g.text;break}case"tool-call":{if(!r||(m(),(a.length>0||d.length>0)&&l(),c.has(g.toolCallId)))break;c.add(g.toolCallId);let h=t.get(g.toolCallId)??{title:g.title,status:g.status??"pending"};u.push(`- ${Rl(h.status)} ${El(h)}`);break}case"tool-call-update":break;case"plan":{m(),l(),n.push("**Plan:**"),n.push("");for(let h of g.entries){let y=h.status==="completed"?"[x]":"[ ]";n.push(`- ${y} ${ct(h.content)}`)}n.push("");break}case"mode-changed":m(),l(),n.push(`_mode: ${ct(g.mode)}_`),n.push("");break;case"model-changed":m(),l(),n.push(`_model: ${ct(g.model)}_`),n.push("");break;case"turn-complete":l();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}l()}function Ml(n,e){switch(n.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 El(n){let e=n.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${ct(n.title)}${t}`}function Rl(n){switch(n){case"completed":return"\u2713";case"failed":return"\u2717";case"cancelled":case"rejected":return"\u2298";case"in_progress":return"\u21BB";default:return"\xB7"}}function Ti(n,e,t){let s=e.split(/\n\s*\n/);for(let r=0;r<s.length;r++){let o=s[r];if(o.trim().length===0)continue;let i=o.split(`
143
+ `);for(let a=0;a<i.length;a++){let d=i[a],u=ct(d);n.push(a===0&&a===i.length-1?`${t}${u}${t}`:a===0?`${t}${u}`:a===i.length-1?`${u}${t}`:u)}r<s.length-1&&n.push("")}}function ct(n){return n.replace(/</g,"&lt;").replace(/>/g,"&gt;")}function qs(n){return n.toLocaleString("en-US")}function _i(n){return n==="127.0.0.1"||n==="::1"||n==="localhost"||n==="[::1]"}function Tl(n){let e=n.trim();if(e.length===0)return{operator:"OR",terms:[]};let t=/\w+:"[^"]*"|"[^"]*"|\S+/g,s=[],r;for(;(r=t.exec(e))!==null;)s.push(r[0]);let o="OR",i=!1,a=!1,d=[];for(let c of s){let f=c.toUpperCase();f==="AND"?i=!0:f==="OR"?a=!0:d.push(c)}i?o="AND":a&&(o="OR");let u=d.map(c=>Pl(c)).filter(c=>c.term.length>0);return{operator:o,terms:u}}function Pl(n){let e=/^(\w+):"([^"]*)"$/.exec(n);if(e)return{scope:$i(e[1]),term:e[2]};let t=/^"([^"]*)"$/.exec(n);if(t)return{scope:"all",term:t[1]};let s=/^(prompt|response|tool):([\s\S]*)$/i.exec(n);return s?{scope:$i(s[1]),term:s[2].trim()}:{scope:"all",term:n.trim()}}function $i(n){switch(n.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";default:return"all"}}function _l(n,e){return n==="all"?!0:n==="user"?e==="user":n==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var $l=5,Fl=200,Mn=72,Ol=24,Nl=512;function Ni(n){return Number.isFinite(n)?Math.max(Ol,Math.min(Nl,Math.floor(n))):Mn}async function Hi(n,e,t={}){let s=Tl(e);if(s.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??$l,o=t.maxSessions??Fl,i=Ni(t.snippetWidth??Mn),a=t.sessionIds?new Set(t.sessionIds):null,d=await n.list(),u=a?d.filter(p=>a.has(p.sessionId)):d,c=[],f=!1;for(let p of u){if(c.length>=o){f=!0;break}let l=await n.loadHistory(p.sessionId,{tools:"references"}).catch(()=>[]),m=Hl(l,s,r,i);if(m.snippets.length===0)continue;let g={sessionId:p.sessionId,cwd:p.cwd,status:p.status,updatedAt:p.updatedAt,totalMatches:m.totalMatches,snippets:m.snippets};p.title!==void 0&&(g.title=p.title),c.push(g)}return{query:e,truncated:f,results:c}}function Hl(n,e,t,s=Mn){if(e.terms.length===0)return{totalMatches:0,snippets:[]};let r=0,o=[],i=Math.max(1,Math.floor(t/e.terms.length)),a=[];for(let{scope:d,term:u}of e.terms){let c=jl(n,u,d,t,s);if(e.operator==="AND"&&c.totalMatches===0)return{totalMatches:0,snippets:[]};r+=c.totalMatches,o.push(...c.snippets.slice(0,i)),a.push(...c.snippets.slice(i))}for(let d of a){if(o.length>=t)break;o.push(d)}return{totalMatches:r,snippets:o.slice(0,t)}}function jl(n,e,t,s,r){let o=e.toLowerCase(),i=0,a=[];for(let d of n){let u=Bl(d).filter(c=>_l(t,c.kind));for(let c of u){let f=c.text.toLowerCase(),p=f.indexOf(o);if(p===-1)continue;let l=0;for(;p!==-1;)l++,p=f.indexOf(o,p+o.length);if(i+=l,a.length<s){let m=f.indexOf(o),g={kind:c.kind,text:Jl(c.text,m,o.length,r),recordedAt:d.recordedAt};c.toolName!==void 0&&(g.toolName=c.toolName),a.push(g)}}}return{totalMatches:i,snippets:a}}function Bl(n){if(n.method!=="session/update")return[];let e=n.params;if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return[];let s=t,r=typeof s.sessionUpdate=="string"?s.sessionUpdate:s.kind;if(typeof r!="string")return[];switch(r){case"agent_message_chunk":{let o=xn(s.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof s.text=="string"?ae(s.text):xn(s.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if(ql(s))return[];let o=xn(s.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=zl(s.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return Ul(s);default:return[]}}function Ul(n){let e=Fi(n,"name"),t=Fi(n,"title"),s=[];if(t!==void 0){let a=Q(t);if(a.length>0){let d={kind:"tool",text:a};e!==void 0&&(d.toolName=e),s.push(d)}}if(e!==void 0&&e!==t){let a=Q(e);a.length>0&&s.push({kind:"tool",toolName:e,text:a})}let r=n.rawInput;if(r&&typeof r=="object"){let a=Oi(r);if(a.length>0){let d={kind:"tool-input",text:Q(a)};e!==void 0&&(d.toolName=e),s.push(d)}}let o=n.locations;if(Array.isArray(o)&&o.length>0){let a=Oi(o);if(a.length>0){let d={kind:"tool-input",text:Q(a)};e!==void 0&&(d.toolName=e),s.push(d)}}let i=Dl(n);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),s.push(a)}return s}function Dl(n){if(!Ll(n.status))return null;let e=n.content;if(Array.isArray(e))for(let s of e){if(!s||typeof s!="object")continue;let o=s.content;if(!o||typeof o!="object")continue;let i=o;if(i.type==="text"&&typeof i.text=="string"){let a=Q(i.text);if(a.length>0)return a}}let t=n.rawOutput;if(t&&typeof t=="object"){let s=t.error;if(typeof s=="string"){let r=Q(s);if(r.length>0)return r}}return null}function Ll(n){return n==="failed"||n==="rejected"||n==="cancelled"}function ql(n){let e=n._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 xn(n){if(typeof n=="string")return ae(n);if(!n||typeof n!="object"||Array.isArray(n))return"";let e=n;return typeof e.text=="string"?ae(e.text):""}function zl(n){if(!Array.isArray(n))return"";let e=[];for(let t of n){let s=xn(t);s.length>0&&e.push(s)}return e.join("")}function Fi(n,e){let t=n[e];return typeof t=="string"?t:void 0}function Oi(n){try{return JSON.stringify(n)}catch{return""}}function Jl(n,e,t,s=Mn){let r=n.replace(/\s+/g," ").trim();if(r.length===0)return"";let o=r.toLowerCase(),i=n.slice(e,e+t).toLowerCase().replace(/\s+/g," ").trim(),a=i.length>0?o.indexOf(i):0;a===-1&&(a=0);let d=Ni(s),u=Math.max(0,d-i.length),c=Math.floor(u/2),f=Math.min(c,a),p=Math.min(u-f,r.length-(a+i.length)),l=Math.max(0,a-(u-p)),m=Math.min(r.length,a+i.length+p),g=l>0?"\u2026":"",h=m<r.length?"\u2026":"";return`${g}${r.slice(l,m)}${h}`}import{randomBytes as Bi}from"crypto";function ji(n){let e=Bi(32).toString("hex");return n.tokenRegistry.reserve(e).complete(n.session),n.session.onClose(()=>{n.tokenRegistry.unbind(e)}),{name:n.name,type:"http",url:`${n.getOrigin()}/mcp/${n.name}`,headers:[{name:"Authorization",value:`Bearer ${e}`}]}}function zs(n){if(n.deps.mcpTokenRegistry===void 0||n.deps.getDaemonOrigin===void 0)return;let e=n.deps.mcpTokenRegistry,t=n.deps.getDaemonOrigin;return async s=>{let r=[...n.baselineMcpServers??[]];n.stdinEnabled&&r.push(ji({name:"hydra-acp-stdin",session:s,tokenRegistry:e,getOrigin:t})),r.push(ji({name:"hydra-acp-recall",session:s,tokenRegistry:e,getOrigin:t}));let o=ut(n.deps);return o!==void 0&&(o.bindToSession(s),r=[...r,...o.descriptors]),r}}function ut(n){if(n.extensionMcp===void 0||n.mcpTokenRegistry===void 0||n.getDaemonOrigin===void 0)return;let e=n.extensionMcp.list();if(e.length===0)return;let t=Bi(32).toString("hex"),s=n.mcpTokenRegistry.reserve(t),r=n.getDaemonOrigin(),o=e.map(a=>({name:a,type:"http",url:`${r}/mcp/${a}`,headers:[{name:"Authorization",value:`Bearer ${t}`}]})),i=n.mcpTokenRegistry;return{descriptors:o,bindToSession:a=>{s.complete(a),a.onClose(()=>{i.unbind(t)})},abandon:a=>s.abandon(a)}}var En=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function Ui(n){if(n.publicHost&&n.publicHost.length>0)return n.publicHost;if(n.host&&!_i(n.host))return n.port!==void 0?`${n.host}:${n.port}`:n.host}function qi(n,e,t,s={}){n.get("/v1/sessions",async u=>{let c=u.query,f=c?.includeNonInteractive==="1"||c?.includeNonInteractive==="true",p=c?.status==="warm"||c?.status==="cold"?c.status:void 0;return{sessions:await e.list({cwd:c?.cwd,includeNonInteractive:f,...p?{status:p}:{}})}}),n.get("/v1/sessions/:id",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=await e.getOne(p);return l||(c.code(404).send({error:"session not found"}),c)}),n.post("/v1/sessions/search",async(u,c)=>{let f=u.body??{},p=typeof f.q=="string"?f.q:"";if(p.trim().length===0)return c.code(400).send({error:"q is required"}),c;let m={sessionIds:Array.isArray(f.sessionIds)?f.sessionIds.filter(h=>typeof h=="string"&&h.length>0):void 0};return typeof f.snippetWidth=="number"&&(m.snippetWidth=f.snippetWidth),await Hi(e,p,m)}),n.post("/v1/sessions",async(u,c)=>{let f=u.body??{},p=Z(f.cwd??t.cwd),l=f.agentId??t.agentId,m=ut(s),g=m!==void 0?[...f.mcpServers??[],...m.descriptors]:f.mcpServers;try{let h=await e.create({cwd:p,agentId:l,mcpServers:g});m!==void 0&&m.bindToSession(h),c.code(201).send({sessionId:h.sessionId,agentId:h.agentId,cwd:h.cwd})}catch(h){m!==void 0&&m.abandon(h instanceof Error?h:void 0),c.code(500).send({error:h.message})}}),n.post("/v1/sessions/collect",async(u,c)=>{let f=u.body??{},p=typeof f.maxAgeDays=="number"&&f.maxAgeDays>0?f.maxAgeDays*24*60*60*1e3:0,l=typeof f.limit=="number"&&f.limit>0?f.limit:1e3,m=f.selection==="explicit"||f.selection==="unpromoted"?f.selection:"unpromoted";try{let g=await js({manager:e,maxAgeMs:p,maxDeletions:l,selection:m,verbose:!1});c.code(200).send(g)}catch(g){c.code(500).send({error:g.message})}}),n.post("/v1/sessions/:id/kill",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(l){l.close({deleteRecord:!1}).catch(()=>{}),c.code(202).send();return}if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}c.code(204).send()}),n.post("/v1/sessions/:id/stdin/open",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(!l)return c.code(404).send({error:"session not found"}),c;let m=u.body??{},g={};(m.mode==="memory"||m.mode==="file")&&(g.mode=m.mode),typeof m.capacityBytes=="number"&&(g.capacityBytes=m.capacityBytes),typeof m.fileCapBytes=="number"&&(g.fileCapBytes=m.fileCapBytes),(g.mode??"memory")==="file"&&(g.filePathFor=h=>Li.join(Di.tmpdir(),`hydra-acp-stdin-${h}.log`));try{return l.openStream(g)}catch(h){return c.code(409).send({error:h.message}),c}}),n.post("/v1/sessions/:id/stdin",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(!l)return c.code(404).send({error:"session not found"}),c;let m=u.body??{},g=typeof m.chunk=="string"?m.chunk:"",h=m.eof===!0;try{return l.streamWrite(g,h)}catch(y){return c.code(409).send({error:y.message}),c}}),n.patch("/v1/sessions/:id",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=u.body??{};if(l.priority!==void 0){let g=l.priority,h;if(g===null||g===0)h=void 0;else if(typeof g=="number"&&Number.isInteger(g)&&g>0)h=g;else{c.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(p,h)){c.code(404).send({error:"session not found"});return}c.code(204).send();return}if(l.regen===!0){if(!(e.get(p)!==void 0||await e.hasRecord(p))){c.code(404).send({error:"session not found"});return}e.scheduleSynopsis(p),c.code(202).send();return}if(typeof l.title!="string"||l.title.trim().length===0){c.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(p,l.title)){c.code(404).send({error:"session not found"});return}c.code(204).send()}),n.delete("/v1/sessions/:id",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);if(l){await l.close({deleteRecord:!0}),await e.waitForDeletion(p),await e.hasRecord(p)&&await e.deleteRecord(p),c.code(204).send();return}if(!await e.deleteRecord(p)){c.code(404).send({error:"session not found"});return}c.code(204).send()}),n.get("/v1/sessions/:id/export",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=u.query?.tools,m=l==="references"?"references":Do(l),g=await e.exportBundle(p,m==="references"?{tools:"references"}:{});if(!g){c.code(404).send({error:"session not found"});return}let h=At({record:g.record,history:m==="summary"?Lo(g.history,"summary"):g.history,promptHistory:g.promptHistory.length>0?g.promptHistory:void 0,...g.toolBlobs!==void 0?{toolBlobs:g.toolBlobs}:{},hydraVersion:Y,machine:yt(),hydraHost:Ui(t)}),y=new Date().toISOString().replace(/[:.]/g,"-");c.header("Content-Disposition",`attachment; filename="${p}-${y}.hydra"`),c.code(200).send(h)}),n.get("/v1/sessions/:id/diff",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=await e.exportBundle(p);if(!l){c.code(404).send({error:"session not found"});return}let m=u.query??{},g=m.fold==="true"||m.fold==="1",h=typeof m.paths=="string"&&m.paths.length>0?new Set(m.paths.split(",").map(b=>b.trim()).filter(b=>b.length>0)):void 0,y=Ei(l.history);h&&(y=y.filter(b=>h.has(b.path))),g&&(y=y.map(b=>({...b,hunks:Ri(b.hunks)}))),c.code(200).send(y)}),n.get("/v1/sessions/:id/tools/:hash",async(u,c)=>{let f=u.params,p=await e.resolveCanonicalId(f.id)??f.id,l=await e.loadToolBlob(p,f.hash);if(l===null){c.code(404).send({error:"tool blob not found"});return}c.header("Content-Type","text/plain; charset=utf-8"),c.code(200).send(l)}),n.get("/v1/sessions/:id/transcript",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=await e.exportBundle(p);if(!l){c.code(404).send({error:"session not found"});return}let m=At({record:l.record,history:l.history,promptHistory:l.promptHistory.length>0?l.promptHistory:void 0,hydraVersion:Y,machine:yt(),hydraHost:Ui(t)}),g=u.query,h=w=>w==="1"||w==="true"||w==="yes",y=w=>{let v=g?.[w];if(v===void 0||v==="")return;let A=Number(v);return Number.isFinite(A)?A:"bad"},b={};for(let w of["from","to","last","since"]){let v=y(w);if(v==="bad"){c.code(400).send({error:`${w} must be a number`});return}v!==void 0&&(b[w==="since"?"sinceMs":w]=v)}c.header("Content-Type","text/markdown; charset=utf-8"),c.code(200).send(Pi(m,{includeTools:h(g?.tools),includeThoughts:h(g?.thoughts),...b}))}),n.post("/v1/sessions/:id/fork",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=u.body??{},m={};if(l.forkAt!==void 0){if(typeof l.forkAt!="string"||l.forkAt.length===0){c.code(400).send({error:"forkAt must be a non-empty string"});return}m.forkAt=l.forkAt}if(l.cwd!==void 0){if(typeof l.cwd!="string"||l.cwd.length===0){c.code(400).send({error:"cwd must be a non-empty string"});return}m.cwd=Z(l.cwd)}if(l.agentId!==void 0){if(typeof l.agentId!="string"||l.agentId.length===0){c.code(400).send({error:"agentId must be a non-empty string"});return}m.agentId=l.agentId}if(l.title!==void 0){if(typeof l.title!="string"){c.code(400).send({error:"title must be a string"});return}m.title=l.title}if(l.mode!==void 0){if(l.mode!=="verbatim"&&l.mode!=="synthesis"){c.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}m.mode=l.mode}if(l.model!==void 0){if(typeof l.model!="string"||l.model.length===0){c.code(400).send({error:"model must be a non-empty string"});return}m.model=l.model}try{let g=await e.forkSession(p,m);c.code(201).send(g)}catch(g){let h=g;if(h.code===k.SessionNotFound){c.code(404).send({error:h.message});return}if(h.code===k.InvalidParams||h.code===k.AgentNotInstalled){c.code(400).send({error:h.message});return}c.code(500).send({error:h.message})}}),n.post("/v1/sessions/import",async(u,c)=>{let f=u.body??{};if(f.bundle===void 0){c.code(400).send({error:"missing bundle"});return}let p;if(f.cwd!==void 0){if(typeof f.cwd!="string"||f.cwd.length===0){c.code(400).send({error:"cwd must be a non-empty string"});return}p=f.cwd}let l;try{l=Ko(f.bundle)}catch(m){c.code(400).send({error:"invalid bundle",details:m.message});return}try{let m=await e.importBundle(l,{replace:f.replace===!0,...p!==void 0?{cwd:p}:{}});c.code(201).send(m)}catch(m){let g=m;if(g.code===k.BundleAlreadyImported){c.code(409).send({error:"bundle already imported",existingSessionId:g.existingSessionId});return}c.code(500).send({error:g.message})}}),n.get("/v1/sessions/:id/compact/status",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p),m;if(l?m=l.summarizedThroughEntry:m=await e.getSummarizedThroughEntry(p),m===void 0&&!await e.hasRecord(p))return c.code(404).send({error:"session not found"}),c;let g=await e.getCompactionState(p),h=await e.getRollbackBreadcrumb(p),y=!1,b,v=await e.getHistory(p).catch(()=>[])??[];if(v.length>0&&t.compaction){let A=m??0,C=v.length,x=v.slice(A),P=wi(x);b=Us(P);let _=l?.currentModel,B=v.at(-1).recordedAt,$=l?.currentUsage;y=bi({summarizedThroughEntry:A,totalEntries:C,unsummarizedChars:P,compactionInFlight:e.getCompactionInFlight(),currentModel:_,lastActivityMs:B,nowMs:Date.now(),config:t.compaction,...typeof $?.used=="number"?{agentReportedUsed:$.used}:{},...typeof $?.size=="number"?{agentReportedSize:$.size}:{}})}return{summarizedThroughEntry:m??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:y,...b!=null?{approxTokens:b}:{},...g!=null?{compactionState:g}:{},...h!=null?{rollbackBreadcrumb:h}:{}}}),n.post("/v1/sessions/:id/compact",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f;if(e.get(p)){e.scheduleCompaction(p),c.code(202).send({scheduled:!0});return}if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}e.scheduleCompaction(p),c.code(202).send({scheduled:!0})}),n.post("/v1/sessions/:id/compact/rollback",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f;if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}try{await e.performUncompact(p),c.code(202).send({rolledBack:!0})}catch(l){let m=l instanceof Error?l.message:String(l);c.code(409).send({error:m})}}),n.get("/v1/sessions/:id/history",async(u,c)=>{let f=u.params.id,p=u.query,l=p?.follow==="1"||p?.follow==="true",m=await e.resolveCanonicalId(f)??f,g=e.get(m),h,y,b=!1,w=1e4,v=[];if(g){l&&(y=g.onBroadcast(C=>{c.raw.writableEnded||(b?c.raw.write(JSON.stringify(C)+`
144
+ `):(v.push(C),v.length>w&&v.shift()))})),u.raw.on("close",()=>{y?.(),c.raw.writableEnded||c.raw.end()});try{h=await g.getHistorySnapshot()}catch(C){throw y?.(),C}}else{let C=await e.getHistory(m);if(C===void 0)return c.code(404).send({error:"session not found"}),c;h=C}c.raw.setHeader("Content-Type","application/x-ndjson"),c.raw.setHeader("Cache-Control","no-cache"),c.raw.statusCode=200;let A=new Set;for(let C of h??[]){c.raw.write(JSON.stringify(C)+`
145
+ `);let x=C;typeof x.recordedAt=="number"&&A.add(String(x.recordedAt))}for(;v.length>0;){let C=v.splice(0,v.length);for(let x of C){let P=x,_=typeof P.recordedAt=="number"?String(P.recordedAt):"";_&&A.has(_)||c.raw.write(JSON.stringify(x)+`
146
+ `)}}return b=!0,y||c.raw.end(),c});function r(u,c,f){let p=typeof u=="string"?u.trim():"";if(p.length===0)return null;let l;try{l=JSON.parse(p)}catch{return console.debug("events endpoint: skipping malformed JSONL line"),null}if(!l||typeof l!="object"||Array.isArray(l))return console.debug("events endpoint: skipping non-object JSONL line"),null;let m=l;if(typeof m.recordedAt!="number"||f!==void 0&&m.recordedAt<f||typeof m.params!="object"||m.params===null||Array.isArray(m.params))return null;let g=m.params;if(typeof g.update!="object"||g.update===null||Array.isArray(g.update))return null;let y=g.update.sessionUpdate;return typeof y!="string"||!c.has(y)?null:{recordedAt:m.recordedAt,entry:l}}function o(u,c,f){let l=c.params.update,m={sessionId:u,ts:new Date(c.recordedAt).toISOString(),kind:f,update:l};return l.messageId!==void 0&&l.messageId!==null&&(m.messageId=l.messageId),m}async function*i(u,c,f,p){for await(let l of c){let m=r(l,f,p);if(m){let g=m.entry.params.update.sessionUpdate;yield{ts:m.recordedAt,row:o(u,m.entry,g)}}}}async function a(u,c,f,p){let l=Ws.createInterface({input:Js.createReadStream(c),crlfDelay:1/0}),m=i(u,l,f,p),g=await m.next(),h=g.done?null:g.value;return{sessionId:u,rl:l,gen:m,current:h,exhausted:h===null}}async function d(u){let c=await u.gen.next();c.done?(u.exhausted=!0,u.current=null):u.current=c.value}n.get("/v1/sessions/events",async(u,c)=>{let f=u.query,p=f.kinds;if(!p||p.trim().length===0)return c.code(400).send({error:"kinds parameter is required"}),c;let l=p.split(",").map(w=>w.trim());if(l.length===0)return c.code(400).send({error:"kinds parameter is required"}),c;for(let w of l)if(!En.has(w))return c.code(400).send({error:`kind "${w}" is not queryable; allowed kinds: ${[...En].join(", ")}`}),c;let m=new Set(l),g;if(f.since!==void 0&&f.since.trim().length>0){let w=new Date(f.since);if(isNaN(w.getTime()))return c.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),c;g=w.getTime()}let h=await e.list({includeNonInteractive:!0}),y=g!==void 0?h.filter(w=>new Date(w.updatedAt).getTime()>=g):h;c.raw.setHeader("content-type","application/x-ndjson"),c.raw.statusCode=200;let b=[];for(let w of y)try{let v=I.historyFile(w.sessionId),A=await a(w.sessionId,v,m,g);A.exhausted||b.push(A)}catch(v){if(v.code==="ENOENT")continue;throw v}u.raw.on("close",()=>{for(let w of b)try{w.rl.close()}catch{}c.raw.writableEnded||c.raw.end()});try{for(;b.length>0;){let w=-1,v=1/0;for(let C=0;C<b.length;C++){let x=b[C];x.current!==null&&x.current.ts<v&&(v=x.current.ts,w=C)}if(w===-1)break;let A=b[w];if(c.raw.write(JSON.stringify(A.current.row)+`
147
+ `),await d(A),A.exhausted){try{A.rl.close()}catch{}b.splice(w,1)}}}catch(w){for(let v of b)try{v.rl.close()}catch{}throw w}return c.raw.end(),c}),n.get("/v1/sessions/:id/events",async(u,c)=>{let f=u.params.id,p=u.query,l=await e.resolveCanonicalId(f)??f;if(!e.get(l)&&!await e.hasRecord(l))return c.code(404).send({error:"session not found"}),c;let g=p.kinds;if(!g||g.trim().length===0)return c.code(400).send({error:"kinds parameter is required"}),c;let h=g.split(",").map(C=>C.trim());if(h.length===0)return c.code(400).send({error:"kinds parameter is required"}),c;for(let C of h)if(!En.has(C))return c.code(400).send({error:`kind "${C}" is not queryable; allowed kinds: ${[...En].join(", ")}`}),c;let y=new Set(h),b;if(p.since!==void 0&&p.since.trim().length>0){let C=new Date(p.since);if(isNaN(C.getTime()))return c.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),c;b=C.getTime()}let w=I.historyFile(l),v=Js.createReadStream(w),A=Ws.createInterface({input:v,crlfDelay:1/0});c.raw.setHeader("content-type","application/x-ndjson"),c.raw.statusCode=200;try{for await(let C of A){let x=typeof C=="string"?C.trim():"";if(x.length===0)continue;let P;try{P=JSON.parse(x)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",w);continue}if(!P||typeof P!="object"||Array.isArray(P)){console.debug("events endpoint: skipping non-object JSONL line in %s",w);continue}let _=P;if(typeof _.recordedAt!="number"||typeof _.params!="object"||_.params===null||Array.isArray(_.params))continue;let B=_.params;if(typeof B.update!="object"||B.update===null||Array.isArray(B.update))continue;let $=B.update,T=$.sessionUpdate;if(typeof T!="string"||!y.has(T)||b!==void 0&&_.recordedAt<b)continue;let U={ts:new Date(_.recordedAt).toISOString(),kind:T,update:$};$.messageId!==void 0&&$.messageId!==null&&(U.messageId=$.messageId),c.raw.write(JSON.stringify(U)+`
148
+ `)}}catch(C){if(C.code==="ENOENT")return c.raw.end(),c;throw C}return c.raw.end(),c}),n.get("/v1/sessions/:id/attention",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,l=e.get(p);return!l&&!await e.hasRecord(p)?(c.code(404).send({error:"session not found"}),c):l?{flags:l.listAttentionFlags()}:{flags:(await e.store.read(p))?.attentionFlags??[]}}),n.get("/v1/sessions/attention",async(u,c)=>{let f=u.query;if(!f.source||f.source.trim().length===0)return c.code(400).send({error:"source query parameter is required"}),c;let p=await e.list({includeNonInteractive:!0}),l=[];for(let m of p){let g=e.get(m.sessionId),h;g?h=g.listAttentionFlags():h=(await e.store.read(m.sessionId))?.attentionFlags??[];for(let y of h)y.source===f.source&&l.push({...y,sessionId:m.sessionId})}return{flags:l}}),n.post("/v1/sessions/:id/attention/clear",async(u,c)=>{let f=u.params.id,p=await e.resolveCanonicalId(f)??f,m=u.body??{},g=typeof m.source=="string"?m.source:"",h=typeof m.reason=="string"?m.reason:"";if((g.length>0||h.length>0)&&!(g.length>0&&h.length>0)){c.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}g.length===0&&h.length;let y=e.get(p);if(y){if(g.length>0&&h.length>0)y.clearAttentionFlag(g,h);else{let C=Array.from(y.listAttentionFlags()).map(x=>`${x.source}::${x.reason}`);for(let x of C)y.clearAttentionFlag(x.split("::")[0],x.split("::").slice(1).join("::"))}c.code(204).send();return}if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}let b=e.store,w=await b.read(p);if(!w){c.code(404).send({error:"session not found"});return}let v=w.attentionFlags??[],A;if(g.length>0&&h.length>0){let C=`${g}::${h}`;A=v.filter(x=>`${x.source}::${x.reason}`!==C)}else A=[];if(A.length===v.length&&A.every((C,x)=>C.source===v[x].source&&C.reason===v[x].reason)){c.code(204).send();return}await b.write({...w,attentionFlags:A}),c.code(204).send()})}function zi(n,e,t,s={}){n.get("/v1/agents",async()=>ze(e)),n.get("/v1/registry",async()=>e.load()),n.post("/v1/registry/refresh",async()=>{let r=await e.refresh();return{version:r.version,agentCount:r.agents.length}}),n.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 ie(a,[],{npmRegistry:s.npmRegistry}),u=a.distribution.npx?"npx":a.distribution.binary?"binary":"unknown";o.send({agentId:a.id,version:d.version,distribution:u,installed:!0,command:d.command})}catch(d){o.code(500).send({error:d.message})}}),n.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(u=>({sessionId:u.sessionId,upstreamSessionId:u.upstreamSessionId,agentId:u.agentId,cwd:u.cwd,title:u.title,updatedAt:u.updatedAt})),skipped:d}}catch(a){let d=a;if(d.code===k.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}function Ji(n,e,t){n.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t}))}var Wl=/^[A-Za-z0-9._-]+$/;function Rn(n,e,t){let s=e==="extension"?"extensions":"transformers",r=`/v1/${s}`;n.get(r,async()=>({[s]:t.list()})),n.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}),n.post(r,async(o,i)=>{let a=o.body??{},d=Vl(a);if("error"in d){i.code(400).send({error:d.error});return}try{let u=t.register(d.config);i.code(201).send(u)}catch(u){Ot(i,u)}}),n.delete(`${r}/:name`,async(o,i)=>{let a=o.params.name;try{await t.unregister(a),i.code(204).send()}catch(d){Ot(i,d)}}),n.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){Ot(i,d)}}),n.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){Ot(i,d)}}),n.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){Ot(i,d)}})}function Ot(n,e){let t=e.code,s=e.message??"unknown error";if(t==="NOT_FOUND"){n.code(404).send({error:s});return}if(t==="CONFLICT"){n.code(409).send({error:s});return}n.code(500).send({error:s})}function Vl(n){let e=n.name;if(typeof e!="string"||!Wl.test(e))return{error:"name must match [A-Za-z0-9._-]+"};let t=n.command;if(t!==void 0&&(!Array.isArray(t)||t.some(i=>typeof i!="string")))return{error:"command must be string[]"};let s=n.args;if(s!==void 0&&(!Array.isArray(s)||s.some(i=>typeof i!="string")))return{error:"args must be string[]"};let r=n.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=n.enabled;return o!==void 0&&typeof o!="boolean"?{error:"enabled must be a boolean"}:{config:{name:e,command:t??[],args:s??[],env:r??{},enabled:o===void 0?!0:o}}}function Wi(n,e){Rn(n,"extension",e)}function Vi(n,e){Rn(n,"transformer",e)}function Qi(n,e){n.get("/v1/config",async()=>e)}import{z as ft}from"zod";W();import*as lt from"fs/promises";import*as Gi from"path";import{randomBytes as Gy,scrypt as Ql,timingSafeEqual as Gl}from"crypto";import{promisify as Kl}from"util";var Yl=Kl(Ql);function Ki(){return Gi.join(I.home(),"password-hash")}var Xl=128*1024*1024;async function Yi(){try{return(await lt.readFile(Ki(),"utf8")).trim().length>0}catch(n){if(n.code==="ENOENT")return!1;throw n}}async function Xi(n){if(typeof n!="string"||n.length===0)return!1;let e;try{e=(await lt.readFile(Ki(),"utf8")).trim()}catch(u){if(u.code==="ENOENT")return!1;throw u}let t=e.split("$");if(t.length!==6||t[0]!=="scrypt")return!1;let s=parseInt(t[1],10),r=parseInt(t[2],10),o=parseInt(t[3],10);if(!Number.isFinite(s)||!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 Yl(n,i,a.length,{N:s,r,p:o,maxmem:Xl});return d.length!==a.length?!1:Gl(d,a)}var Zl=ft.object({password:ft.string().min(1),label:ft.string().min(1).max(256).optional(),ttlSec:ft.number().int().positive().optional()}),ef=ft.object({id:ft.string().optional()}).optional();function Zi(n,e){n.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,s)=>{let r=tf(t);if(e.rateLimiter.isBlocked(r))return s.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=Zl.parse(t.body)}catch{return s.code(400).send({error:"Invalid request body"})}if(!await Yi())return s.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await Xi(o.password))return e.rateLimiter.recordFailure(r),s.code(401).send({error:"Invalid password"});e.rateLimiter.recordSuccess(r);let a=await e.store.issue({label:o.label,ttlSec:o.ttlSec});return s.code(200).send({session_token:a.token,id:a.id,expires_at:a.expiresAt})}),n.post("/v1/auth/logout",async(t,s)=>{let r;try{r=ef.parse(t.body??void 0)}catch{return s.code(400).send({error:"Invalid request body"})}let o=r?.id??t.authIdentity;if(!o||o==="service")return s.code(200).send({revoked:!1});let i=await e.store.revoke(o);return s.code(200).send({revoked:i})}),n.get("/v1/auth/verify",async(t,s)=>s.code(200).send({ok:!0})),n.get("/v1/auth/sessions",async(t,s)=>s.code(200).send({sessions:e.store.list()})),n.delete("/v1/auth/sessions/:id",async(t,s)=>{let r=t.params.id;return await e.store.revoke(r)?s.code(204).send():s.code(404).send({error:"Not found"})})}function tf(n){return n.ip||"unknown"}import{nanoid as Vs}from"nanoid";function ea(n){let e=[],t=[],s=!1,r=o=>{if(!s){s=!0;for(let i of t)i(o)}};return n.on("message",(o,i)=>{if(i)return;let a=o.toString("utf8");try{let d=JSON.parse(a);for(let u of e)u(d)}catch(d){for(let u of e)u({jsonrpc:"2.0",id:null,error:{code:k.ParseError,message:`Failed to parse WS frame: ${d.message}`}})}}),n.on("close",()=>r()),n.on("error",o=>r(o)),{async send(o){if(s)throw new Error("ws is closed");let i=JSON.stringify(o);await new Promise((a,d)=>{n.send(i,u=>{if(u){d(u);return}a()})})},onMessage(o){e.push(o)},onClose(o){t.push(o)},async close(){s||(await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,clearTimeout(d),o())},d=setTimeout(a,5e3);n.once("close",a);try{n.close()}catch{a()}}),r())}}}import{randomBytes as ia}from"crypto";import*as aa from"os";import*as da from"path";var nf=200;function sf(n){if(!n||typeof n!="object")return;let e=n._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[le];if(!t||typeof t!="object"||Array.isArray(t))return;let s=t.sentBy;if(!s||typeof s!="object"||Array.isArray(s))return;let r=s,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,nf)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function ta(n,e,t){let s=sf(n);if(!s)return;let r={};if(s.label!==void 0&&(r.fromLabel=s.label),s.awaiting===!0&&(r.awaiting=!0),s.sessionId!==void 0){let o=await e.resolveCanonicalId(s.sessionId)??s.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?.(s.sessionId)}if(!(r.fromSession===void 0&&r.fromLabel===void 0))return r}var Nt=new Map;function na(n,e){let t=Nt.get(n);t||(t=new Set,Nt.set(n,t)),t.add(e);let s=!1;return()=>{if(s)return;s=!0;let r=Nt.get(n);r&&(r.delete(e),r.size===0&&Nt.delete(n))}}function sa(n,e){if(n===e)return!0;let t=new Set,s=[e];for(;s.length>0;){let r=s.pop();if(t.has(r))continue;t.add(r);let o=Nt.get(r);if(o){if(o.has(n))return!0;for(let i of o)s.push(i)}}return!1}function E(n,e,t){let s=new Error(e);return s.code=n,t!==void 0&&(s.data=t),s}function cf(n){if(!n||typeof n!="object")return 512;let s=n.params?.update;if(!s)return 512;let r=512,o=s.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=s.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 u=d.content;typeof u.text=="string"&&(r+=u.text.length)}}return r}function oe(n,e,t){let s=n.get(e);if(!s)throw E(k.SessionNotFound,t??`session ${e} not found`);return s}async function Tn(n,e){let t=ut(n),s,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&n.mcpTokenRegistry!==void 0&&n.getDaemonOrigin!==void 0&&(s=ia(32).toString("hex"),r=n.mcpTokenRegistry.reserve(s),o={name:"hydra-acp-recall",type:"http",url:`${n.getDaemonOrigin()}/mcp/hydra-acp-recall`,headers:[{name:"Authorization",value:`Bearer ${s}`}]});let a=[...t?.descriptors??[],...o!==void 0?[o]:[]],d=zs({baselineMcpServers:void 0,stdinEnabled:!1,deps:n}),u;try{u=await n.manager.resurrect({...e,mcpServers:a,...d?{mintMcpServersForSwap:d}:{}})}catch(c){throw t!==void 0&&t.abandon(c instanceof Error?c:void 0),r!==void 0&&r.abandon(c instanceof Error?c:void 0),c}if(t!==void 0&&t.bindToSession(u),s!==void 0&&r!==void 0&&n.mcpTokenRegistry!==void 0){let c=s,f=n.mcpTokenRegistry;r.complete(u),u.onClose(()=>{f.unbind(c)})}return wf(u,n),ua(u.sessionId,n),u}function ca(n,e){n.get("/acp",{websocket:!0},async(t,s)=>{let r=yi({headers:s.headers,url:s.url});if(!r||!await e.validator.validate(r)){t.close(4401,"Unauthorized");return}let o=e.processRegistry?.resolve(r),i=ea(t),a=new Ve(i),d={clientId:`hydra_client_${Vs(12)}`,processIdentity:o,attached:new Map};a.onClose(()=>{for(let f of d.attached.values())e.manager.get(f.sessionId)?.detach(f.clientId);d.attached.clear()});let u=(f,p)=>{if(d.attached.get(f)?.readonly)throw E(k.PermissionDenied,`${p} not permitted on a read-only attachment`)};if(a.onRequest("initialize",async f=>{let p=$r.parse(f??{});p.clientInfo?.name&&(d.clientInfo={name:p.clientInfo.name,...p.clientInfo.version!==void 0?{version:p.clientInfo.version}:{}});let l=p.clientInfo?.version;return l&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,l):e.onTransformerVersion?.(o.name,l)),yf()}),o&&e.extensionCommands){let f=e.extensionCommands;a.onRequest("hydra-acp/commands/register",async p=>{let l=p??{},m=Array.isArray(l.commands)?l.commands.map(g=>{if(!g||typeof g!="object")return;let h=g;if(typeof h.verb!="string")return;let y={verb:h.verb};return typeof h.argsHint=="string"&&(y.argsHint=h.argsHint),typeof h.description=="string"&&(y.description=h.description),y}).filter(g=>g!==void 0):[];return f.register(o.name,a,m),{ok:!0,registered:m.length}}),a.onClose(()=>{f.clear(o.name)})}if(o&&e.extensionMcp){let f=e.extensionMcp;a.onRequest("hydra-acp/mcp_tools/register",async l=>{let m=l??{},g=typeof m.instructions=="string"?m.instructions:void 0,h=Array.isArray(m.tools)?m.tools.map(y=>{if(!y||typeof y!="object")return;let b=y;if(typeof b.name!="string"||b.name.length===0||typeof b.description!="string"||b.inputSchema===null||typeof b.inputSchema!="object")return;let w={name:b.name,description:b.description,inputSchema:b.inputSchema};return b.outputSchema!==null&&typeof b.outputSchema=="object"&&(w.outputSchema=b.outputSchema),w}).filter(y=>y!==void 0):[];if(h.length===0)throw new Error("register_mcp_tools requires at least one tool");return f.register(o.name,a,g,h),{ok:!0,registered:h.length}});let p=l=>{let m=l??{};if(typeof m.sessionId!="string"||m.sessionId.length===0)throw E(k.InvalidParams,"sessionId is required");return m.sessionId};if(a.onRequest("hydra-acp/session/extension_state/get",async l=>{let m=p(l),g=l??{};if(typeof g.key!="string"||g.key.length===0)throw E(k.InvalidParams,"key is required");if(!e.manager)throw E(k.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(m,o.name,g.key)??null}}),a.onRequest("hydra-acp/session/extension_state/list",async l=>{let m=p(l);if(!e.manager)throw E(k.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(m,o.name)}}),a.onRequest("hydra-acp/session/extension_state/set",async l=>{let m=p(l),g=l??{};if(typeof g.key!="string"||g.key.length===0)throw E(k.InvalidParams,"key is required");if(g.value===void 0)throw E(k.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw E(k.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(m,o.name,g.key,g.value)}catch(h){throw E(k.InvalidParams,h.message)}return{ok:!0}}),a.onRequest("hydra-acp/session/extension_state/delete",async l=>{let m=p(l),g=l??{};if(typeof g.key!="string"||g.key.length===0)throw E(k.InvalidParams,"key is required");if(!e.manager)throw E(k.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(m,o.name,g.key),{ok:!0}}),e.extensionMcpControls){let l=e.extensionMcpControls;a.onRequest("hydra-acp/mcp_tools/refresh_session",async m=>{let g=m??{};if(typeof g.sessionId!="string"||g.sessionId.length===0)throw E(k.InvalidParams,"refresh_session requires sessionId");return await l.notifyToolListChanged(g.sessionId,o.name),{ok:!0}})}a.onClose(()=>{f.clear(o.name)})}if(o?.kind==="transformer"){a.onRequest("hydra-acp/transformer/initialize",async p=>{let l=p??{},m=Array.isArray(l.intercepts)?l.intercepts.filter(g=>typeof g=="string"):[];if(e.transformers&&(e.transformers.registerConnection(o.name,a,m),e.manager?.defaultTransformers.includes(o.name))){let g=e.transformers.resolveChain([o.name])[0];if(g)for(let h of e.manager.liveSessions())h.addTransformer(g)}return{ack:!0}}),a.onClose(()=>{e.transformers?.deregisterConnection(o.name)}),a.onRequest("hydra-acp/message/emit",async p=>{let l=p??{},m=typeof l.sessionId=="string"?l.sessionId:void 0,g=typeof l.method=="string"?l.method:void 0,h=l.envelope,y=l.route;if(!m)throw E(-32602,"emit_message requires sessionId");if(!g&&y!=="client_broadcast")throw E(-32602,"emit_message requires method");let b=oe(e.manager,m),w=typeof l.respondsTo=="string"?l.respondsTo:void 0;if(w)return b.dischargeClaim(w,h),{ok:!0};if(y==="chain")return{ok:!0,response:await b.emitToChain(o.name,g,h)};if(y==="queue"){if(g!=="session/prompt")throw E(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await b.emitToQueue(o.name,h)}}if(y==="daemon")return{ok:!0,response:await b.emitToChain(o.name,g,h)};if(y==="client_broadcast"){if(!h||typeof h!="object")throw E(-32602,"client_broadcast requires an envelope object");return b.broadcastClientUpdate(h),{ok:!0}}throw E(-32602,`unsupported route: ${JSON.stringify(y)}`)}),a.onRequest("hydra-acp/session/request_permission",async p=>{let l=p??{},m=typeof l.sessionId=="string"?l.sessionId:void 0;if(!m)throw E(-32602,"hydra-acp/session/request_permission requires sessionId");return oe(e.manager,m).requestPermissionFromClients(l)}),a.onRequest("hydra-acp/transformer/attach",async p=>pf(p,o.name,e)),a.onRequest("hydra-acp/child_session/spawn",async p=>{let l=p??{},m=typeof l.agentId=="string"?l.agentId:e.defaultAgent,g=typeof l.cwd=="string"?l.cwd:void 0,h=typeof l.parentSessionId=="string"?l.parentSessionId:void 0,y=l._meta&&typeof l._meta=="object"?l._meta:void 0,b=y&&y["hydra-acp"]&&typeof y["hydra-acp"]=="object"?y["hydra-acp"]:void 0,w=b&&typeof b.title=="string"?b.title:void 0,v=b&&typeof b.model=="string"?b.model:void 0;if(!g&&h){let x=e.manager.get(h);x&&(g=x.cwd)}if(!g)throw E(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let A=typeof l.interactive=="boolean"?l.interactive:!1;return{childSessionId:(await e.manager.create({agentId:m,cwd:g,parentSessionId:h,interactive:A,transformChain:[],title:w,model:v})).sessionId}}),a.onRequest("hydra-acp/session/fork",async p=>{let l=p??{};if(typeof l.sessionId!="string")throw E(k.InvalidParams,"fork_session requires sessionId");let m=typeof l.forkAt=="string"?l.forkAt:void 0,g=typeof l.cwd=="string"?l.cwd:void 0,h=typeof l.agentId=="string"?l.agentId:void 0,y=typeof l.mode=="string"&&(l.mode==="verbatim"||l.mode==="synthesis")?l.mode:void 0,b=typeof l.model=="string"&&l.model.length>0?l.model:void 0;return await e.manager.forkSession(l.sessionId,{...m!==void 0?{forkAt:m}:{},...g!==void 0?{cwd:g}:{},...h!==void 0?{agentId:h}:{},...y!==void 0?{mode:y}:{},...b!==void 0?{model:b}:{}})}),a.onRequest("session/fork",async p=>{let l=p??{};if(typeof l.sessionId!="string")throw E(k.InvalidParams,"session/fork requires sessionId");let m=typeof l.cwd=="string"?l.cwd:void 0;return{sessionId:(await e.manager.forkSession(l.sessionId,{...m!==void 0?{cwd:m}:{},mode:"verbatim"})).sessionId}});let f=async(p,l)=>{let m=p??{};if(typeof m.sessionId!="string")throw E(k.InvalidParams,`${l} requires sessionId`);let g=await e.manager.resolveCanonicalId(m.sessionId)??m.sessionId,h=e.manager.get(g);if(h)return await h.close({deleteRecord:!0}),await e.manager.waitForDeletion(g),await e.manager.hasRecord(g)&&await e.manager.deleteRecord(g),{id:g,existed:!0};let y=await e.manager.deleteRecord(g);return{id:g,existed:y}};a.onRequest("session/delete",async p=>(await f(p,"session/delete"),{})),a.onRequest("session/close",async p=>{let l=p??{};if(typeof l.sessionId!="string")throw E(k.InvalidParams,"session/close requires sessionId");u(l.sessionId,"session/close");let m=await e.manager.resolveCanonicalId(l.sessionId)??l.sessionId,g=e.manager.get(m);if(g)return await g.close({deleteRecord:!1}),{};if(await e.manager.hasRecord(m))return{};throw E(k.SessionNotFound,`session ${m} not found`)}),a.onRequest("hydra-acp/session/delete",async p=>{let{id:l,existed:m}=await f(p,"hydra-acp/session/delete");if(!m)throw E(k.SessionNotFound,`session ${l} not found`);return{deleted:!0,sessionId:l}}),a.onRequest("hydra-acp/child_session/await",async p=>{let l=p??{},m=typeof l.childSessionId=="string"?l.childSessionId:void 0,g=l.until==="idle"?"idle":"turn_complete",h=typeof l.timeoutMs=="number"?Math.min(l.timeoutMs,18e5):3e5;if(!m)throw E(-32602,"await_child requires childSessionId");let y=oe(e.manager,m,`child session ${m} not found`);return new Promise(b=>{let A=[],C=[],x=0,P=!1,_,B,$=!1,T=()=>{$||($=!0,clearTimeout(U),_?.(),B?.(),b(P?{entries:A,truncated:!0}:{entries:A}))};_=y.onBroadcast(J=>{let ne=cf(J);for(A.push(J),C.push(ne),x+=ne;A.length>0&&(A.length>1e3||x>1048576);)A.shift(),x-=C.shift()??0,P=!0;g==="turn_complete"&&J.params?.update?.sessionUpdate==="turn_complete"&&T()});let U=setTimeout(T,h);typeof U.unref=="function"&&U.unref(),B=y.onClose(()=>T())})}),a.onRequest("hydra-acp/child_session/close",async p=>{let l=p??{},m=typeof l.childSessionId=="string"?l.childSessionId:void 0;if(!m)throw E(-32602,"close_child_session requires childSessionId");let g=e.manager.get(m);return g&&await g.close({deleteRecord:!1}),{ok:!0}}),a.onRequest("hydra-acp/attention/set",async p=>mf(p,o.name,e)),a.onRequest("hydra-acp/attention/clear",async p=>gf(p,o.name,e)),a.onRequest("hydra-acp/connection/keep_alive",async p=>{let l=p??{},m=typeof l.token=="string"?l.token:void 0,g=typeof l.sessionId=="string"?l.sessionId:void 0,h=typeof l.estimatedRemainingMs=="number"?l.estimatedRemainingMs:void 0;return m&&g&&e.manager.get(g)?.keepAliveClaim(m,h),{ok:!0}})}a.onRequest("hydra-acp/session/tool_content",async f=>{let p=f??{};if(typeof p.sessionId!="string"||typeof p.hash!="string")throw E(k.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let l=await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,m=await e.manager.loadToolBlob(l,p.hash);if(m===null)throw E(k.SessionNotFound,"tool content not found");return{content:m}}),a.onRequest("authenticate",async f=>uf(f,e)),a.onRequest("logout",async f=>lf(f,e)),a.onRequest("session/new",async f=>{let p=Fr.parse(f),l=Je(f?._meta),m=Array.isArray(l.transformers)&&l.transformers.every(T=>typeof T=="string")?l.transformers:e.manager.defaultTransformers??[],g=e.transformers?.resolveChain(m)??[],h,y,b=p.mcpServers;if(l.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){h=ia(32).toString("hex"),y=e.mcpTokenRegistry.reserve(h);let U={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${h}`}]};b=[...p.mcpServers??[],U]}let w,v,A=ut(e);A!==void 0&&(b=[...b??[],...A.descriptors]);let C=zs({baselineMcpServers:p.mcpServers,stdinEnabled:l.mcpStdin===!0,deps:e}),x;try{x=await e.manager.create({cwd:p.cwd,agentId:l.agentId??e.defaultAgent,mcpServers:b,title:l.title,agentArgs:l.agentArgs,model:l.model,onInstallProgress:oa(a),transformChain:g,originatingClient:d.clientInfo,...l.interactive!==void 0?{interactive:l.interactive}:{},...l.env!==void 0?{forwardedEnv:l.env}:{},...C?{mintMcpServersForSwap:C}:{}})}catch(T){throw y!==void 0&&y.abandon(T instanceof Error?T:void 0),v!==void 0&&v.abandon(T instanceof Error?T:void 0),A!==void 0&&A.abandon(T instanceof Error?T:void 0),T}if(h!==void 0&&y!==void 0&&e.mcpTokenRegistry!==void 0){let T=h,U=e.mcpTokenRegistry;y.complete(x),x.onClose(()=>{U.unbind(T)})}if(w!==void 0&&v!==void 0&&e.mcpTokenRegistry!==void 0){let T=w,U=e.mcpTokenRegistry;v.complete(x),x.onClose(()=>{U.unbind(T)})}A!==void 0&&A.bindToSession(x),ua(x.sessionId,e);let P,_;try{Fn(d,x,x.sessionId),P=Ht(a,x,d),{entries:_}=await x.attach(P,"full")}catch(T){throw await x.close({deleteRecord:!1}).catch(()=>{}),T}d.attached.set(x.sessionId,{sessionId:x.sessionId,clientId:P.clientId,readonly:!1}),setImmediate(()=>{(async()=>{for(let T of _){if(a.isClosed())break;await a.notify(T.method,Me(T.params,T.recordedAt)).catch(()=>{})}})()});let B=Pn(x),$=_n(x);return{sessionId:x.sessionId,...B?{modes:B}:{},...$?{models:$}:{},configOptions:x.buildConfigOptions(),_meta:$n(e.manager,x,{clientId:P.clientId})}}),a.onRequest("session/attach",async f=>{let p=Nr.parse(f),l=p.clientInfo?.version;l&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,l):e.onTransformerVersion?.(o.name,l));let m=Je(p._meta),g=m.resume,h=m.readonly===!0,y=m.env;n.log.info(`session/attach sessionId=${p.sessionId} hasResumeHints=${!!g} readonly=${h}`);let b=g?p.sessionId:await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,w=e.manager.get(b);if(!w&&h){let $=await e.manager.loadFromDisk(b);if(!$)throw E(k.SessionNotFound,`session ${p.sessionId} not found`);let T=await e.manager.loadHistory(b),U=p.clientId??`cli_${Vs(8)}`;d.attached.set($.hydraSessionId,{sessionId:$.hydraSessionId,clientId:U,readonly:!0}),n.log.info(`session/attach OK (viewer) sessionId=${$.hydraSessionId} clientId=${U} attachedCount=${d.attached.size} replayed=${T.length}`);for(let J of T)await a.notify(J.method,Me(J.params,J.recordedAt)).catch(()=>{});return{sessionId:$.hydraSessionId,clientId:U,connectedClients:[U],historyPolicy:"full",replayed:T.length,_meta:hf($)}}let v=!w;if(!w){let $=await e.manager.loadFromDisk(b),T=$;if(g&&(T={...$,hydraSessionId:p.sessionId,upstreamSessionId:g.upstreamSessionId,agentId:g.agentId,cwd:g.cwd,...g.title!==void 0?{title:g.title}:{},...g.agentArgs!==void 0?{agentArgs:g.agentArgs}:{}}),!T)throw E(k.SessionNotFound,`session ${p.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(T.agentId,T.upstreamSessionId))throw E(k.SessionNotFound,`session ${p.sessionId} was deleted`);let U=T.originatingClient?T:{...T,originatingClient:d.clientInfo},J=y!==void 0?{...U,forwardedEnv:y}:U;w=await Tn(e,{...J,onInstallProgress:oa(a)})}Fn(d,w,w.sessionId);let A=Ht(a,w,d,p.clientInfo,p.clientId),C=m.replayMode==="drip",{entries:x,appliedPolicy:P}=await w.attach(A,p.historyPolicy,{afterMessageId:p.afterMessageId,raw:C,...m.toolContent!==void 0?{toolContent:m.toolContent}:{}});if(d.attached.set(w.sessionId,{sessionId:w.sessionId,clientId:A.clientId,readonly:h}),y!==void 0&&await e.manager.setForwardedEnv(w.sessionId,y).catch(()=>{}),n.log.info(`session/attach OK sessionId=${w.sessionId} clientId=${A.clientId} attachedCount=${d.attached.size} requestedPolicy=${p.historyPolicy} appliedPolicy=${P} replayed=${x.length} readonly=${h}${C?" replayMode=drip":""}`),C){let $=m.dripSpeed&&m.dripSpeed>0?m.dripSpeed:1,T=750;(async()=>{let U=null;for(let J of x){let ne=typeof J.recordedAt=="number"?J.recordedAt:null;if(U!==null&&ne!==null){let Be=Math.min(T,Math.max(0,(ne-U)/$));Be>0&&await new Promise(jt=>setTimeout(jt,Be))}ne!==null&&(U=ne);try{await a.notify(J.method,Me(J.params,ne??void 0))}catch{return}}})()}else for(let $=0;$<x.length&&!a.isClosed();$++){let T=x[$],U=a.notify(T.method,Me(T.params,T.recordedAt)).catch(()=>{});($+1)%200===0&&await U}w.replayPendingPermissions(A);let _=Pn(w),B=_n(w);return{sessionId:w.sessionId,clientId:A.clientId,connectedClients:w.connectedClients(A.clientId),historyPolicy:P,replayed:x.length,..._?{modes:_}:{},...B?{models:B}:{},configOptions:w.buildConfigOptions(),_meta:$n(e.manager,w,{resurrected:v})}}),a.onRequest("session/detach",async f=>{let p=Hr.parse(f),l=d.attached.get(p.sessionId);if(!l)throw E(k.SessionNotFound,"client not attached to that session");let m=e.manager.get(p.sessionId);return m?.detach(l.clientId),d.attached.delete(p.sessionId),m&&e.manager.reapIfOrphanedNonInteractive(p.sessionId),{sessionId:p.sessionId,_meta:{[le]:{detachStatus:"detached"}}}}),a.onRequest("session/list",async f=>{let p=jr.parse(f??{});return{sessions:(await e.manager.list({cwd:p.cwd})).filter(h=>h.originatingClient?.name!==sn).map(Br)}}),a.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw E(k.InternalError,"agent registry unavailable");return ze(e.registry)}),a.onRequest("hydra-acp/agents/auth_methods",async f=>{let p=f??{};if(typeof p.agentId!="string"||p.agentId.length===0)throw E(k.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(p.agentId)).authMethods??[]}}),a.onRequest("session/prompt",async f=>{let p=Ur.parse(f);u(p.sessionId,"session/prompt");let l=await ta(p,e.manager,y=>{n.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${y} sessionId=${p.sessionId}`)});if(l?.fromSession!==void 0){if((l.depth??0)>3)throw n.log.warn(`session/prompt: refusing depth ${l.depth} chain from ${l.fromSession} to ${p.sessionId}`),E(k.InvalidRequest,`message chain too deep (${l.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(l.awaiting===!0&&sa(l.fromSession,p.sessionId))throw n.log.warn(`session/prompt: refusing deadlock ${l.fromSession} -> ${p.sessionId}`),E(k.InvalidRequest,`would deadlock: ${p.sessionId} is already blocked waiting on ${l.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let m=d.attached.get(p.sessionId);if(!m)throw n.log.warn(`session/prompt rejected: not attached sessionId=${p.sessionId} attachedKeys=[${[...d.attached.keys()].join(",")}]`),E(k.SessionNotFound,"not attached to session");let g=e.manager.get(p.sessionId);if(!g){let y=await e.manager.loadFromDisk(p.sessionId);if(!y)throw E(k.SessionNotFound,`session ${p.sessionId} not found`);n.log.info(`session/prompt auto-resurrecting cold sessionId=${p.sessionId}`),g=await Tn(e,y);let b=Ht(a,g,d,void 0,m.clientId);await g.attach(b,"none")}let h=l?.awaiting===!0&&l.fromSession!==void 0?na(l.fromSession,p.sessionId):void 0;try{return await g.prompt(m.clientId,p,l)}finally{h?.()}});let c=f=>{let p;try{p=Vt.parse(f)}catch(g){n.log.warn(`session/cancel: invalid params: ${g.message}`);return}let l=d.attached.get(p.sessionId);if(!l)return;if(l.readonly){n.log.warn(`session/cancel dropped (readonly attachment) sessionId=${p.sessionId}`);return}let m=e.manager.get(p.sessionId);m&&m.cancel(l.clientId).catch(g=>{n.log.warn(`session/cancel for ${p.sessionId}: ${g.message}`)})};a.onNotification("session/cancel",c),a.onRequest("session/cancel",async f=>{let p=Vt.parse(f);return u(p.sessionId,"session/cancel"),c(f),null}),a.onRequest("hydra-acp/prompt/cancel",async f=>{let p=Lr.parse(f);return u(p.sessionId,"hydra-acp/prompt/cancel"),oe(e.manager,p.sessionId).cancelQueuedPrompt(p.messageId)}),a.onRequest("hydra-acp/session/force_cancel",async f=>{let p=Vt.parse(f);return u(p.sessionId,"hydra-acp/session/force_cancel"),oe(e.manager,p.sessionId).forceCancel()}),a.onRequest("hydra-acp/prompt/update",async f=>{let p=qr.parse(f);return u(p.sessionId,"hydra-acp/prompt/update"),oe(e.manager,p.sessionId).updateQueuedPrompt(p.messageId,p.prompt)}),a.onRequest("hydra-acp/prompt/amend",async f=>{let p=zr.parse(f);u(p.sessionId,"hydra-acp/prompt/amend");let l=d.attached.get(p.sessionId);if(!l)throw E(k.SessionNotFound,"not attached to session");return oe(e.manager,p.sessionId).amendPrompt(l.clientId,p)}),a.onRequest("session/resume",async f=>{let p=f??{},l=typeof p.sessionId=="string"?p.sessionId:void 0;if(!l)throw E(k.InvalidParams,"session/resume requires sessionId");let m=await e.manager.resolveCanonicalId(l)??l,g=e.manager.get(m);if(!g){let w=await e.manager.loadFromDisk(m);if(!w)throw E(k.SessionNotFound,`session ${l} not found in memory or on disk`);g=await Tn(e,w)}Fn(d,g,g.sessionId);let h=Ht(a,g,d);await g.attach(h,"pending_only"),d.attached.set(g.sessionId,{sessionId:g.sessionId,clientId:h.clientId,readonly:!1}),g.replayPendingPermissions(h);let y=Pn(g),b=_n(g);return{sessionId:g.sessionId,...y?{modes:y}:{},...b?{models:b}:{},configOptions:g.buildConfigOptions(),_meta:$n(e.manager,g,{clientId:h.clientId})}}),a.onRequest("session/load",async f=>{let p=f??{},l=typeof p.sessionId=="string"?p.sessionId:void 0;if(!l)throw E(k.InvalidParams,"session/load requires sessionId");let m=await e.manager.resolveCanonicalId(l)??l,g=e.manager.get(m);if(!g){let v=await e.manager.loadFromDisk(m);if(!v)throw E(k.SessionNotFound,`session ${l} not found in memory or on disk`);g=await Tn(e,v)}Fn(d,g,g.sessionId);let h=Ht(a,g,d),{entries:y}=await g.attach(h,"pending_only");d.attached.set(g.sessionId,{sessionId:g.sessionId,clientId:h.clientId,readonly:!1});for(let v of y){if(a.isClosed())break;await a.notify(v.method,Me(v.params,v.recordedAt)).catch(()=>{})}g.replayPendingPermissions(h);let b=Pn(g),w=_n(g);return{sessionId:g.sessionId,...b?{modes:b}:{},...w?{models:w}:{},configOptions:g.buildConfigOptions(),_meta:$n(e.manager,g,{clientId:h.clientId})}}),a.onRequest("session/set_model",async f=>{let p=f?.sessionId;typeof p=="string"&&u(p,"session/set_model");let l=ff(f,e.manager);if(l.kind==="error")throw n.log.warn(l.logMessage),E(l.code,l.message);if(l.kind==="no_op")return n.log.warn(l.logMessage),await a.notify("session/update",{sessionId:l.sessionId,update:{sessionUpdate:"current_model_update",currentModel:l.currentModel}}).catch(()=>{}),null;n.log.info(l.logMessage);let{modelId:m}=l,g=await l.session.forwardModelChange(m,f);return l.session.applyModelChange(m),g}),a.onRequest("session/set_mode",async f=>{let p=f,l=p?.sessionId;if(typeof l=="string"&&u(l,"session/set_mode"),!p||typeof p.sessionId!="string")throw E(k.InvalidParams,"session/set_mode requires string sessionId");if(typeof p.modeId!="string")throw E(k.InvalidParams,"session/set_mode requires string modeId");let m=oe(e.manager,p.sessionId),g=await m.forwardRequest("session/set_mode",f);return m.applyModeChange(p.modeId),g}),a.onRequest("session/set_config_option",async f=>{let p=f,l=y=>E(k.InvalidParams,y),m=p?.sessionId;if(typeof m=="string"&&u(m,"session/set_config_option"),!p||typeof p.sessionId!="string")throw l("session/set_config_option requires string sessionId");if(typeof p.configId!="string")throw l("session/set_config_option requires string configId");if(typeof p.value!="string")throw l("session/set_config_option requires string value");let g=oe(e.manager,p.sessionId),h=g.buildConfigOptions().find(y=>y.id===p.configId);if(!h)throw l(`unknown configId ${JSON.stringify(p.configId)} for this session`);if(!h.options.some(y=>y.value===p.value))throw l(`value ${JSON.stringify(p.value)} is not valid for configId ${JSON.stringify(p.configId)}`);switch(p.configId){case"model":{p.value!==g.currentModel&&await g.forwardModelChange(p.value),g.applyModelChange(p.value);break}case"mode":{p.value!==g.currentMode&&await g.forwardRequest("session/set_mode",{sessionId:p.sessionId,modeId:p.value}),g.applyModeChange(p.value);break}case"agent":{p.value!==g.agentId&&await g.setAgent(p.value);break}default:await g.forwardRequest("session/set_config_option",{sessionId:p.sessionId,configId:p.configId,value:p.value})}return{configOptions:g.buildConfigOptions()}}),a.setDefaultHandler(async(f,p)=>{let l=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),m=p.startsWith("session/"),g=p.startsWith("hydra-acp/");if(!m&&!g||f===null||typeof f!="object"||l.has(p))throw E(k.MethodNotFound,`Method not found: ${p}`);let h=f.sessionId;if(typeof h!="string")throw E(k.MethodNotFound,`Method not found: ${p}`);return u(h,p),oe(e.manager,h).forwardRequest(p,f)})})}async function uf(n,e){let t=n??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw E(k.InvalidParams,"authenticate requires a non-empty methodId string");let s=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 l=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(l)}let d=a.authMethods??[],u=d.find(l=>l.id===s);if(!u){let l=d.map(m=>m.id);throw E(k.InvalidParams,`authenticate: methodId ${JSON.stringify(s)} is not advertised by agent ${a.agentId}; valid: [${l.map(m=>JSON.stringify(m)).join(", ")}]`)}let c=u._meta?.type,f=(()=>{let l=u._meta?.["terminal-auth"];if(l&&typeof l=="object"&&!Array.isArray(l))return l})();if((u.type??(c==="agent"||c==="terminal"?c:f!==void 0?"terminal":"agent"))==="terminal"){let l=(w,v)=>{if(!Array.isArray(w))throw E(k.InvalidParams,`authenticate: method ${JSON.stringify(s)} ${v} must be a string[]; got ${w===null?"null":typeof w}`);for(let A of w)if(typeof A!="string")throw E(k.InvalidParams,`authenticate: method ${JSON.stringify(s)} ${v} must be string[]; got non-string entry ${JSON.stringify(A)}`);return w},m=await e.manager.planSpawnForAgent(a.agentId),g,h;if(f?.args!==void 0){let w=typeof f.command=="string"?f.command:void 0;g=w!==void 0&&da.isAbsolute(w)?w:m.command,h=l(f.args,'_meta["terminal-auth"].args')}else{let w=u.args!==void 0?{raw:u.args,label:"args"}:u._meta?.args!==void 0?{raw:u._meta.args,label:"_meta.args"}:void 0,v=w!==void 0?l(w.raw,w.label):[];g=m.command,h=[...m.args,...v]}let y={};for(let[w,v]of Object.entries(process.env))typeof v=="string"&&(y[w]=v);Object.assign(y,m.env);let b=aa.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${s}`),{kind:"terminal",command:g,args:h,env:y,cwd:b}}try{return await a.connection.request("authenticate",{methodId:s})}catch(l){throw Pe(l,a)}}async function lf(n,e){let s=(n??{})._meta?.["hydra-acp"],r=typeof s?.sessionId=="string"?s.sessionId:void 0,o=typeof s?.agentId=="string"?s.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 oa(n){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),n.notify(Jr,t).catch(()=>{})}}function Pn(n){let e=n.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:n.currentMode??e[0].id,availableModes:t}}function _n(n){let e=n.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:n.currentModel??e[0].modelId,availableModels:t}}function ff(n,e){if(!n||typeof n!="object")return{kind:"error",code:k.InvalidParams,message:"session/set_model requires params",logMessage:"session/set_model rejected: params not an object"};let t=n;if(typeof t.sessionId!="string")return{kind:"error",code:k.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:k.InvalidParams,message:"session/set_model requires string modelId",logMessage:`session/set_model rejected: missing/non-string modelId sessionId=${t.sessionId}`};let s=e.get(t.sessionId);if(!s)return{kind:"error",code:k.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=s.availableModels(),o=Ze(t.modelId,r);if(o.kind==="none")return{kind:"ok",session:s,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:s,modelId:t.modelId,logMessage:`session/set_model accepted sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="resolved")return{kind:"ok",session:s,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 s.currentModel!==void 0&&s.currentModel.length>0?{kind:"no_op",session:s,sessionId:t.sessionId,currentModel:s.currentModel,logMessage:`session/set_model no_op (resyncing client) sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} ${a} actual=${JSON.stringify(s.currentModel)} agentId=${s.agentId} known=[${i}]`}:{kind:"error",code:k.InvalidParams,message:`model "${t.modelId}" is ${a==="not in availableModels"?"not in this session's availableModels":a} (agent ${s.agentId}); known models: ${i}`,logMessage:`session/set_model rejected sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)} ${a} agentId=${s.agentId} known=[${i}] (no current model to fall back to)`}}async function pf(n,e,t){let s=n??{},r=typeof s.sessionId=="string"?s.sessionId:void 0;if(!r)throw E(k.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw E(k.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw E(k.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return oe(t.manager,r).addTransformer(o),{ok:!0}}async function mf(n,e,t){let s=n??{},r=typeof s.sessionId=="string"?s.sessionId:void 0,o=typeof s.reason=="string"?s.reason:void 0;if(!r)throw E(k.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw E(k.InvalidParams,"hydra-acp/attention/set requires string reason");return oe(t.manager,r).setAttentionFlag(e,o,s.payload),{ok:!0}}async function gf(n,e,t){let s=n??{},r=typeof s.sessionId=="string"?s.sessionId:void 0,o=typeof s.reason=="string"?s.reason:void 0;if(!r)throw E(k.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw E(k.InvalidParams,"hydra-acp/attention/clear requires string reason");return oe(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function hf(n){let e={sessionId:n.hydraSessionId,upstreamSessionId:n.upstreamSessionId,cwd:n.cwd,title:n.title,agentId:n.agentId,currentModel:n.currentModel,currentUsage:Ct(n.currentUsage),forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:n.interactive,updatedAt:n.createdAt??new Date().toISOString(),attachedClients:0,status:"cold",busy:!1,awaitingInput:!1},t={currentMode:n.currentMode,agentArgs:n.agentArgs,availableCommands:n.agentCommands,availableModes:n.agentModes,availableModels:n.agentModels};return{[le]:Wt(e,t)}}function $n(n,e,t={}){let s=n.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(),...t.resurrected===!0?{resurrected:!0}:{}};return ht(e.agentMeta,Wt(s,r))}function yf(){return{protocolVersion:1,agentInfo:{name:"hydra",version:Y},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:ht(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}}})}}function wf(n,e){if(!(!e.transformers||!e.manager))for(let t of e.manager.defaultTransformers){let s=e.transformers.resolveChain([t])[0];s&&n.addTransformer(s)}}function ua(n,e){if(!e.transformers)return;let t=e.transformers.interestedIn("lifecycle:session.starting");for(let s of t)s.connection.notify("hydra-acp/transformer/session_event",{event:"session.starting",sessionId:n}).catch(()=>{})}function Ht(n,e,t,s,r){return{clientId:r??`cli_${Vs(8)}`,connection:n,clientInfo:s}}function Fn(n,e,t){let s=n.attached.get(t);s&&(e.detach(s.clientId),n.attached.delete(t))}var On=class{byToken=new Map;reserve(e){if(this.byToken.has(e))throw new Error("mcp token already bound");let t,s,r=new Promise((i,a)=>{t=i,s=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),s(i??new Error("mcp token reservation abandoned"))}}}bind(e,t){let{complete:s}=this.reserve(e);s(t)}lookup(e){return this.byToken.get(e)}addDisposer(e,t){let s=this.byToken.get(e);s!==void 0&&s.disposers.push(t)}async unbind(e){let t=this.byToken.get(e);if(t!==void 0){this.byToken.delete(e);for(let s of t.disposers)try{await s()}catch{}}}size(){return this.byToken.size}};import{randomUUID as bf}from"crypto";import{McpServer as vf}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Sf}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as X}from"zod";function Qs(n){if(n.method!=="session/update")return null;let t=n.params?.update;return!t||typeof t.sessionUpdate!="string"?null:{kind:t.sessionUpdate,update:t}}function te(n){return{content:[{type:"text",text:JSON.stringify(n)}],structuredContent:n}}var la="Bearer ";function pt(n){let e=n.headers.authorization;if(typeof e!="string"||!e.startsWith(la))return;let t=e.slice(la.length).trim();return t.length>0?t:void 0}function If(n){let e=new vf({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:X.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let s=n.streamTail(t);return te(s)}),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:X.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let s=n.streamHead(t);return te(s)}),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:X.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:X.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:X.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:s,wait_ms:r})=>{let o=await n.streamRead(t,s,r);return te(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:X.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:X.number().int().min(0).describe("Maximum ms to block (server caps at 60_000).")}},async({cursor:t,timeout_ms:s})=>{let r=await n.streamWaitFor(t,s),o=n.streamInfo();return te({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:X.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:X.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:X.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:X.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:X.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:X.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:X.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:X.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:X.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 s={pattern:t.pattern};t.regex!==void 0&&(s.regex=t.regex),t.case_insensitive!==void 0&&(s.caseInsensitive=t.case_insensitive),t.invert!==void 0&&(s.invert=t.invert),t.max_matches!==void 0&&(s.maxMatches=t.max_matches),t.max_bytes!==void 0&&(s.maxBytes=t.max_bytes),t.context_before!==void 0&&(s.contextBefore=t.context_before),t.context_after!==void 0&&(s.contextAfter=t.context_after),t.cursor!==void 0&&(s.cursor=t.cursor);let r=n.streamGrep(s);return te(r)}),e.registerTool("info",{description:"Report cursor / capacity / closed state of the stdin ring. Cheap; safe to call repeatedly.",inputSchema:{}},async()=>{let t=n.streamInfo();return te(t)}),e}var kf=1e4;function fa(n,e){let t=new Map;async function s(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let u=If(a),c=new Sf({sessionIdGenerator:()=>bf()});await u.connect(c);let f={server:u,transport:c};return t.set(i,f),e.addDisposer(i,async()=>{t.delete(i);try{await c.close()}catch{}try{await u.close()}catch{}}),c}async function r(i,a){let d=pt(i);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let u=e.lookup(d);if(u===void 0){a.code(404).send({error:"unknown stdin token"});return}let c;if(u.session!==void 0)c=u.session;else{let p,l=new Promise(g=>{p=setTimeout(()=>g(void 0),kf)}),m=await Promise.race([u.sessionReady.catch(()=>{}),l]);if(p!==void 0&&clearTimeout(p),m===void 0){a.code(503).send({error:"session not ready"});return}c=m}let f=await s(d,c);a.hijack(),await f.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};n.post("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),n.get("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),n.delete("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)})}import{randomUUID as Af}from"crypto";import{McpServer as Cf}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as xf}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as _e}from"zod";function Mf(n){switch(n){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}function Ef(n,e){if(n.length<=148)return n;let r=Math.floor(148/2),o=e-r;o<0&&(o=0);let i=o+148;i>n.length&&(o=n.length-148,o<0&&(o=0));let a=n.slice(o,i);return o>0&&(a="\u2026"+a),i<n.length&&(a=a+"\u2026"),a}function Rf(n){let e=new Cf({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. 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:_e.string().min(1).describe("Case-insensitive substring to search for."),limit:_e.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:_e.boolean().optional().describe("Whether to include tool_call entries in the search (default true).")}},async({query:t,limit:s=10,include_tool_calls:r=!0})=>{let o=await n();if(!o.summarizedThroughEntry||o.summarizedThroughEntry===0)return te({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:u,entry:c}of o.iterRecallNewestFirst()){let f=Qs(c);if(!f)continue;let{kind:p}=f;if(p==="tool_call"&&!r)continue;let l=et([c]),m=l.toLowerCase().indexOf(a);if(m<0)continue;let g=Mf(p),h=Ef(l,m),y=typeof c.recordedAt=="number"?String(c.recordedAt):void 0;if(i.push({entryId:u,speaker:g,snippet:h,timestamp:y}),i.length>=s)break}i.sort((u,c)=>u.entryId-c.entryId);let d=i.length>=s;return te({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. Use after `search` narrows in on what you need. Capped at 50 entries per call.",inputSchema:{from_entry:_e.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:_e.number().int().min(0).describe("Zero-based index of the last entry to include (inclusive).")}},async({from_entry:t,to_entry:s})=>{let r=await n();if(!r.summarizedThroughEntry||r.summarizedThroughEntry===0)return te({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(s<t)throw new Error(`range: to_entry (${s}) must be >= from_entry (${t})`);let o=s-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 te({text:"",entry_count:0,truncated:!1});let a=Math.min(t,i-1),d=Math.min(s,i-1),u=a>t||d<s;if(a>d)return{content:[{type:"text",text:""}],structuredContent:{text:"",entry_count:0,truncated:u}};let c=await r.sliceRecallHistory(a,d),f=et(c);return{content:[{type:"text",text:f}],structuredContent:{text:f,entry_count:c.length,truncated:u}}}),e.registerTool("tool_calls",{description:"Search this session's prior tool invocations by tool name and/or file path. Returns when each tool was called, the arguments, and the result status. Use this to recall which files were read/edited, what shell commands ran, etc.",inputSchema:{tool_name:_e.string().optional(),file_path:_e.string().optional(),limit:_e.number().int().min(1).max(100).optional()}},async({tool_name:t,file_path:s,limit:r=20})=>{let o=await n();if(!o.summarizedThroughEntry||o.summarizedThroughEntry===0)return te({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 i=typeof t=="string"&&t.length>0,a=typeof s=="string"&&s.length>0;if(!i&&!a)throw new Error("tool_calls: at least one of tool_name or file_path must be provided");let d=new Map,u=Math.max(r*4,200);for await(let{entryId:l,entry:m}of o.iterRecallNewestFirst()){let g=Qs(m);if(!g)continue;let{kind:h,update:y}=g;if(h!=="tool_call"&&h!=="tool_call_update")continue;let b=typeof y.toolCallId=="string"&&y.toolCallId.length>0?y.toolCallId:`__noid_${l}`,w=d.get(b);w||(w={entryId:l,toolName:"(unnamed)",rawInput:{},locations:[],status:"in_progress"},d.set(b,w)),l<w.entryId&&(w.entryId=l),typeof y.name=="string"&&y.name.length>0?w.toolName=y.name:w.toolName==="(unnamed)"&&typeof y.title=="string"&&y.title.length>0&&(w.toolName=y.title);let v=y.rawInput;if(v&&typeof v=="object"&&!Array.isArray(v)&&Object.keys(v).length>0)for(let[A,C]of Object.entries(v))w.rawInput[A]===void 0&&(w.rawInput[A]=C);if(Array.isArray(y.locations))for(let A of y.locations){let C=A?.path;typeof C=="string"&&C.length>0&&!w.locations.includes(C)&&w.locations.push(C)}if(typeof y.status=="string"&&w.status==="in_progress"&&(w.status=y.status),m.recordedAt!==void 0&&w.timestamp===void 0&&(w.timestamp=String(m.recordedAt)),d.size>=u)break}let c=[...d.keys()].sort((l,m)=>d.get(l).entryId-d.get(m).entryId),f=[];for(let l of c){let m=d.get(l);if(t!==void 0&&m.toolName.toLowerCase()!==t.toLowerCase())continue;if(a){let h=s.toLowerCase(),y=["file_path","filePath","path"],b=!1;for(let w of y){let v=m.rawInput[w];if(typeof v=="string"&&v.toLowerCase().includes(h)){b=!0;break}}if(!b){for(let w of m.locations)if(w.toLowerCase().includes(h)){b=!0;break}}if(!b)continue}let g={};for(let[h,y]of Object.entries(m.rawInput))typeof y=="string"?g[h]=y.length>500?y.slice(0,497)+"\u2026":y:(typeof y=="number"||typeof y=="boolean")&&(g[h]=y);if(m.locations.length>0&&g.locations===void 0&&(g.locations=m.locations),f.push({entryId:m.entryId,tool:m.toolName,args:g,status:m.status,timestamp:m.timestamp}),f.length>=r)break}let p=f.length>=r;return te({calls:f,truncated:p})}),e}var Tf=1e4;function pa(n,e){let t=new Map;async function s(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let u=Rf(a),c=new xf({sessionIdGenerator:()=>Af()});await u.connect(c);let f={server:u,transport:c};return t.set(i,f),e.addDisposer(i,async()=>{t.delete(i);try{await c.close()}catch{}try{await u.close()}catch{}}),c}async function r(i,a){let d=pt(i);if(d===void 0){a.code(401).send({error:"missing bearer token"});return}let u=e.lookup(d);if(u===void 0){a.code(404).send({error:"unknown recall token"});return}let f=await s(d,async()=>{if(u.session!==void 0)return u.session;let p,l=new Promise(g=>{p=setTimeout(()=>g(void 0),Tf)}),m=await Promise.race([u.sessionReady.catch(()=>{}),l]);if(p!==void 0&&clearTimeout(p),m===void 0)throw new Error("recall: session not ready");return m});a.hijack(),await f.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};n.post("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),n.get("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),n.delete("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)})}var Nn=class{byName=new Map;changeHandlers=[];register(e,t,s,r){this.byName.set(e,{connection:t,instructions:s,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 s of this.changeHandlers)try{s(e,t)}catch{}}};import{StreamableHTTPServerTransport as jf}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as Bf}from"crypto";import{Server as Pf}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as _f,ListToolsRequestSchema as $f}from"@modelcontextprotocol/sdk/types.js";function ma(n,e,t,s){let r=typeof t=="function"?async()=>t():async()=>t,o=new Pf({name:n,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($f,async()=>{let a=s?.peekSessionId?.();if(a!==void 0&&s?.fetchSessionTools!==void 0)try{let d=await s.fetchSessionTools(a);if(d!==void 0)return{tools:d.map(i)}}catch{}return{tools:e.tools.map(i)}}),o.setRequestHandler(_f,async(a,d)=>{let u=a.params.name,c=d._meta?.progressToken??d.requestId,f=Of(c,d.sendNotification);try{let p=await r(),l=await Nf(e.connection,n,u,a.params.arguments??{},p);return Hf(l,u)}catch(p){return Gs(p instanceof Error?p.message:String(p))}finally{f()}}),o}var Ff=15e3;function Of(n,e,t=Ff){if(n===void 0)return()=>{};let s=0,r=setInterval(()=>{s+=1,e({method:"notifications/progress",params:{progressToken:n,progress:s}}).catch(()=>{})},t);return r.unref?.(),()=>clearInterval(r)}async function Nf(n,e,t,s,r){return await n.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:s,sessionId:r})}function Hf(n,e){if(n===null||typeof n!="object")return Gs(`extension ${e} returned non-object`);let t=n;return Array.isArray(t.content)?t:Gs(`extension ${e} omitted content array`)}function Gs(n){return{content:[{type:"text",text:n}],isError:!0}}var Uf=1e4;function ga(n,e,t){let s=new Map;async function r(c){try{await c.transport.close()}catch{}try{await c.server.close()}catch{}}function o(c){for(let f of s.values()){let p=f.get(c);p!==void 0&&(f.delete(c),r(p))}}async function i(c,f){for(let[p,l]of s){if(e.lookup(p)?.session?.sessionId!==c)continue;let g=l.get(f);if(g!==void 0)try{await g.server.sendToolListChanged()}catch{}}}t.onChange(c=>{o(c)});async function a(c,f){let p=s.get(c);p===void 0&&(p=new Map,s.set(c,p),e.addDisposer(c,async()=>{let v=s.get(c);if(v!==void 0){s.delete(c);for(let A of v.values())await r(A)}}));let l=p.get(f);if(l!==void 0)return l.transport;let m=t.lookup(f);if(m===void 0)return;let b=ma(f,m,async()=>{let v=e.lookup(c);if(v===void 0)throw new Error("mcp token no longer bound");if(v.session!==void 0)return v.session.sessionId;let A,C=new Promise(P=>{A=setTimeout(()=>P(void 0),Uf)}),x=await Promise.race([v.sessionReady.catch(()=>{}),C]);if(A!==void 0&&clearTimeout(A),x===void 0)throw new Error("session not ready");return x.sessionId},{peekSessionId:()=>e.lookup(c)?.session?.sessionId,fetchSessionTools:async v=>{let A=await m.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:v});if(!A||typeof A!="object")return;let C=A.tools;if(!Array.isArray(C))return;let x=[];for(let P of C){if(!P||typeof P!="object")continue;let _=P;if(typeof _.name!="string"||_.name.length===0||typeof _.description!="string"||_.inputSchema===null||typeof _.inputSchema!="object")continue;let B={name:_.name,description:_.description,inputSchema:_.inputSchema};_.outputSchema!==null&&typeof _.outputSchema=="object"&&(B.outputSchema=_.outputSchema),x.push(B)}return x}}),w=new jf({sessionIdGenerator:()=>Bf()});return await b.connect(w),p.set(f,{server:b,transport:w}),w}async function d(c,f){let p=pt(c);if(p===void 0){f.code(401).send({error:"missing bearer token"});return}if(e.lookup(p)===void 0){f.code(404).send({error:"unknown mcp token"});return}let m=c.params.name,g=await a(p,m);if(g===void 0){f.code(404).send({error:`unknown mcp server: ${m}`});return}f.hijack(),await g.handleRequest(c.raw,f.raw,c.body)}let u={config:{skipAuth:!0}};return n.post("/mcp/:name",u,async(c,f)=>{await d(c,f)}),n.get("/mcp/:name",u,async(c,f)=>{await d(c,f)}),n.delete("/mcp/:name",u,async(c,f)=>{await d(c,f)}),{notifyToolListChanged:i}}async function Sa(n,e){Vf(n),mr(n.daemon.scrubEnv);let t=n.daemon.tls?await Se.readFile(Z(n.daemon.tls.key)):void 0,s=n.daemon.tls?await Se.readFile(Z(n.daemon.tls.cert)):void 0;await Se.mkdir(I.home(),{recursive:!0});let{stream:r,fileStream:o}=await Jf(n.daemon.logLevel),i=Df({logger:{level:n.daemon.logLevel,stream:r},bodyLimit:256*1024*1024});await i.register(Lf,{options:{handleProtocols:lr}}),Kn(O=>{i.log.info(O)}),Zn(O=>{i.log.info(O)});let a=await wn.load(),d=new kn,u=new In,c=new Sn([new bn(e),new vn(a),u]),f=hi({validator:c});i.addHook("onRequest",async(O,pe)=>{O.routeOptions.config?.skipAuth||O.url==="/acp"||O.url?.startsWith("/acp?")||await f(O,pe)});let p=setInterval(()=>{a.sweepExpired()},300*1e3);p.unref();let l=setInterval(()=>{d.sweepExpired()},300*1e3);l.unref();let m=new zt(n,{onFetched:()=>{ii(m,b)}});Hs(O=>i.log.info(O));let g={info:O=>i.log.info(O),warn:O=>i.log.warn(O)},h=O=>Re.spawn({...O,stderrTailBytes:n.daemon.agentStderrTailBytes,logger:g});wr(n.compressToolContent);let y=new hn,b=new cn(m,h,void 0,{idleTimeoutMs:n.daemon.sessionIdleTimeoutSeconds*1e3,defaultModels:n.defaultModels,synopsisAgent:n.synopsisAgent,synopsisModel:n.synopsisModel,compactionAgent:n.compaction?.agent,compactionModel:n.compaction?.model,defaultTransformers:n.defaultTransformers,sessionHistoryMaxEntries:n.daemon.sessionHistoryMaxEntries,sessionHistoryArchiveMaxBytes:n.daemon.sessionHistoryArchiveMaxBytes,sessionHistoryArchiveTiers:n.daemon.sessionHistoryArchiveTiers,logger:g,npmRegistry:n.npmRegistry,extensionCommands:y,defaultCwd:n.defaultCwd}),w=new mn(ar(n),void 0,{tokenRegistry:u}),v=new gn(dr(n),void 0,{tokenRegistry:u});Ji(i,Y,ci(n));let A=new On,C=new Nn,x,P=()=>{if(x!==void 0)return x;let O=i.server.address();return x=`http://127.0.0.1:${O&&typeof O=="object"?O.port:n.daemon.port}`,x};qi(i,b,{agentId:n.defaultAgent,cwd:n.defaultCwd,publicHost:n.daemon.publicHost,host:n.daemon.host,port:n.daemon.port,compaction:n.compaction},{extensionMcp:C,mcpTokenRegistry:A,getDaemonOrigin:P}),zi(i,m,b,{npmRegistry:n.npmRegistry}),Wi(i,w),Vi(i,v),Qi(i,{defaultAgent:n.defaultAgent,defaultCwd:n.defaultCwd,defaultModels:{...n.defaultModels},...n.synopsisAgent!==void 0?{synopsisAgent:n.synopsisAgent}:{},...n.synopsisModel!==void 0?{synopsisModel:n.synopsisModel}:{},defaultTransformers:[...n.defaultTransformers]}),Zi(i,{store:a,rateLimiter:d}),fa(i,A),pa(i,A);let _=ga(i,A,C);ca(i,{validator:c,manager:b,defaultAgent:n.defaultAgent,processRegistry:u,onExtensionVersion:(O,pe)=>w.reportVersion(O,pe),onTransformerVersion:(O,pe)=>v.reportVersion(O,pe),transformers:v,extensionCommands:y,mcpTokenRegistry:A,extensionMcp:C,extensionMcpControls:_,getDaemonOrigin:P,registry:m});let B=!!n.daemon.tls;await i.listen({host:B?"127.0.0.1":n.daemon.host,port:B?0:n.daemon.port});let $=i.server.address(),T=$&&typeof $=="object"?$.port:n.daemon.port,U,J=n.daemon.host,ne=T;if(B&&t&&s){U=Wf({listenHost:n.daemon.host,listenPort:n.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:T,tlsOptions:{key:t,cert:s},logger:i.log});let O=U.address();O&&typeof O=="object"&&(ne=O.port)}await Se.mkdir(I.home(),{recursive:!0}),await oi({pid:process.pid,host:J,port:ne,loopbackPort:T,startedAt:new Date().toISOString()});let Be={daemonUrl:`http://127.0.0.1:${T}`,daemonHost:"127.0.0.1",daemonPort:T,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${T}/acp`,hydraHome:I.home()};w.setContext(Be),v.setContext(Be),await w.start(),await v.start();try{await b.reconcilePermissionFlags()}catch(O){i.log.warn(`permission flag reconcile failed: ${O.message}`)}b.resurrectPendingQueues().catch(O=>{i.log.warn(`queue replay scan failed: ${O.message}`)}),b.resumePendingCompactions().catch(O=>{i.log.warn(`compaction resume scan failed: ${O.message}`)}),b.resumePendingAgentSwaps().catch(O=>{i.log.warn(`agent-swap resume scan failed: ${O.message}`)});let jt=n.daemon.agentSyncIntervalMinutes*60*1e3,Xs=jt>0?ai({registry:m,manager:b,intervalMs:jt,logger:g}):void 0,Zs=n.daemon.sessionGcIntervalMinutes*60*1e3,_a=n.daemon.sessionGcMaxAgeDays*24*60*60*1e3,er=Zs>0?di({manager:b,intervalMs:Zs,maxAgeMs:_a,logger:g}):void 0;return{app:i,manager:b,registry:m,extensions:w,transformers:v,mcpTokenRegistry:A,extensionMcp:C,processRegistry:u,shutdown:async()=>{er&&er(),Xs&&Xs(),clearInterval(p),clearInterval(l);let O=async(pe,$a)=>{try{await $a()}catch(jn){i.log.warn(`shutdown step ${pe} failed: ${jn instanceof Error?jn.message:String(jn)}`)}};await O("sessionTokenStore.flush",()=>a.flush()),await O("extensions.stop",()=>w.stop()),await O("transformers.stop",()=>v.stop()),await O("manager.closeAll",()=>b.closeAll()),await O("manager.flushSynopsis",()=>b.flushSynopsis(3e4)),await O("manager.shutdownSynopsis",()=>b.shutdownSynopsis()),await O("manager.flushMetaWrites",()=>b.flushMetaWrites()),await O("manager.flushHistoryWrites",()=>b.flushHistoryWrites()),Kn(null),Zn(null),Hs(null),U&&await O("tlsTerminator.close",()=>new Promise(pe=>U.close(()=>pe()))),await O("app.close",()=>i.close());try{wa.unlinkSync(I.pidFile())}catch{}await O("fileStream.flushSync",()=>o.flushSync())}}}var ya=20;async function zf(n,e){let t=mt.dirname(n),s=mt.basename(n,".log"),r=new RegExp(`^${s}\\.(\\d+)\\.log$`),o;try{o=await Se.readdir(t)}catch{return}let i=[];for(let d of o){let u=d.match(r);u&&i.push({name:d,n:Number(u[1])})}if(i.length<=e)return;i.sort((d,u)=>d.n-u.n);let a=i.slice(0,i.length-e);await Promise.allSettled(a.map(d=>Se.unlink(mt.join(t,d.name))))}async function Jf(n){await zf(I.logFile(),ya);let e=await qf({file:I.logFile(),size:"10m",mkdir:!0,symlink:!0,limit:{count:ya,removeOtherLogFiles:!0}}),t=ha.destination(2);return{stream:ha.multistream([{stream:e,level:n},{stream:t,level:n}]),fileStream:e}}function Wf(n){let e=va.createServer(n.tlsOptions,t=>{let s=ba.connect({host:n.upstreamHost,port:n.upstreamPort}),r=!1,o=i=>{if(!r){r=!0,i&&n.logger.warn(`tls terminator forwarder error: ${i.message??String(i)}`);try{t.destroy()}catch{}try{s.destroy()}catch{}}};t.on("error",o),s.on("error",o),t.on("close",()=>o()),s.on("close",()=>o()),t.pipe(s),s.pipe(t)});return e.on("tlsClientError",t=>{n.logger.warn(`tls handshake error: ${t.message}`)}),e.listen({host:n.listenHost,port:n.listenPort}),e}function Vf(n){let e=n.daemon.host;if(!(e==="127.0.0.1"||e==="::1"||e==="localhost"||e==="[::1]")&&!n.daemon.tls)throw new Error(`Refusing to bind to non-loopback host ${e} without TLS configured.`)}async function dp(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:n}=await Promise.resolve().then(()=>(Pa(),Ta));n();let e=await zn(),t=await tr(),s=await Sa(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
149
+ `);let r=1e4,o=!1,i=async()=>{o&&(process.stderr.write(`Second signal received; exiting immediately.
150
+ `),process.exit(1)),o=!0,process.stdout.write(`Shutting down...
151
151
  `);let a=setTimeout(()=>{process.stderr.write(`Graceful shutdown did not complete within ${r}ms; forcing exit.
152
152
  `),process.exit(1)},r);a.unref();try{await s.shutdown()}catch(d){process.stderr.write(`shutdown failed: ${d instanceof Error?d.message:String(d)}
153
- `)}clearTimeout(a),process.exit(0)};process.on("SIGINT",()=>{o()}),process.on("SIGTERM",()=>{o()}),process.on("SIGHUP",()=>{})}Bf().catch(n=>{process.stderr.write(`hydra-acp-daemon: ${n instanceof Error?n.message:String(n)}
153
+ `)}clearTimeout(a),process.exit(0)};process.on("SIGINT",()=>{i()}),process.on("SIGTERM",()=>{i()}),process.on("SIGHUP",()=>{})}dp().catch(n=>{process.stderr.write(`hydra-acp-daemon: ${n instanceof Error?n.message:String(n)}
154
154
  `),process.exit(1)});