@hydra-acp/cli 0.1.150 → 0.1.151

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/daemon.js CHANGED
@@ -1,81 +1,88 @@
1
1
  #!/usr/bin/env node
2
- var Oa=Object.defineProperty;var Bt=(n,e)=>()=>(n&&(e=n(n=0)),e);var Na=(n,e)=>{for(var t in e)Oa(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 ja(){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[Ha];if(n&&n.length>0)return H.resolve(n);let e=ja();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 Ha,I,W=Bt(()=>{"use strict";Ha="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 Ua}from"crypto";async function ce(n,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
3
- `;await Da(n,r,t)}async function Da(n,e,t={}){let s=await La(n),r=qa(s);await G.mkdir(r,{recursive:!0});let o=`${s}.tmp-${process.pid}-${za()}`;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 La(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 qa(n){let e=n.lastIndexOf("/");return e<=0?".":n.slice(0,e)}function za(){return Ua(4).toString("hex")}var Fe=Bt(()=>{"use strict"});function Hn(n,e){return`${n}:${e}`}var ka=Bt(()=>{"use strict";W();Fe()});var Pa={};Na(Pa,{_resetForTests:()=>up,clearPin:()=>sp,fetchPeerFingerprint:()=>ip,formatFingerprint:()=>xa,getPin:()=>rp,installGlobalTlsTrust:()=>ap,loadPinsFromStore:()=>op,setPin:()=>Ca,sha256Hex:()=>Ys,wsTlsOptions:()=>cp});import{createHash as Yf}from"crypto";import*as Aa from"tls";import{Agent as Xf,Dispatcher as Zf,buildConnector as ep,getGlobalDispatcher as tp,setGlobalDispatcher as np}from"undici";function Ca(n,e,t){je.set(Hn(n,e),Ma(t))}function sp(n,e){je.delete(Hn(n,e))}function rp(n,e){return je.get(Hn(n,e))}function op(n){je.clear();for(let e of n.list())e.entry.pinnedFingerprint&&Ca(e.host,e.port,e.entry.pinnedFingerprint)}async function ip(n,e,t={}){let s=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=Aa.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 Yf("sha256").update(n).digest("hex")}function xa(n){let e=Ma(n),t=e.match(/.{2}/g);return t?t.join(":"):e}function Ma(n){return n.replace(/:/g,"").toLowerCase()}function ap(){if(Ks)return;Ks=!0;let n=tp(),e=new Xf({connect:ep({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(s,r)=>Ra(s,r)})}),t=new Zf;t.dispatch=(s,r)=>{let o=dp(s.origin);return(o&&Ea(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(()=>{})),np(t)}function dp(n){if(!n)return null;try{return new URL(String(n)).hostname}catch{return null}}function Ea(n){for(let e of je.keys())if(Ta(e)?.host===n)return!0;return!1}function Ra(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=Ta(s);if(o&&o.host===n&&r===t)return}return new Error(`TLS pin mismatch for ${n} (cert sha256 ${xa(t)})`)}function Ta(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 cp(n){return Ea(n)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>Ra(e,t)}:{autoSelectFamily:!0}}function up(){je.clear(),Ks=!1}var je,Ks,_a=Bt(()=>{"use strict";ka();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 Ba(){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 Ba();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",Ja=S.object({cert:S.string(),key:S.string()}),ir=55514,Wa=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:Ja.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)}),Va=S.object({url:S.string().url().default(or),ttlHours:S.number().positive().default(24),pinned:S.boolean().default(!1)}),Qa=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()}),Ga=S.object({packageSpec:S.string().optional()}),Ka=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"]),Ya=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(Ya);function qn(n,e){return S.object({left:sr.default(n),right:sr.default(e)}).default({})}var Xa=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],Za=["usage"],ed=[],td=["helpHint"],nd=["cwd","title"],sd=["agentModel"],rd=S.object({composer:S.object({top:qn(Xa,Za),bottom:qn(ed,td)}).default({}),sessionbar:qn(nd,sd),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(Ka,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"),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({command:S.array(S.string()).default([]),args:S.array(S.string()).default([]),env:S.record(S.string()).default({}),enabled:S.boolean().default(!0)}),ad=S.object({daemon:Wa.default({}),registry:Va.default({url:or,ttlHours:24,pinned:!1}),agents:S.record(S.string(),Qa).default({}),agentOverrides:S.record(S.string(),Ga).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,od).default({}),transformers:S.record(rr,id).default({}),defaultTransformers:S.array(S.string()).default([]),npmRegistry:S.string().url().optional(),tui:rd.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 dd(),await ue(I.config())??{}}async function dd(){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 cd(){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 cd(),ad.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 ba from"fs";import*as Se from"fs/promises";import*as va from"net";import*as pt from"path";import*as Sa from"tls";import zf from"fastify";import Jf from"@fastify/websocket";var ur="acp.v1";function lr(n,e){return n.has(ur)?ur:!1}import ya from"pino";import Wf from"pino-roll";var ud={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",ld=[fr],fd=[...Object.values(ud).flat(),...ld];function Ut(n,e){return n?{...e??{},[fr]:n}:e}var pr=[];function mr(n){pr=n?[...n]:[]}function pd(n,e){return e.endsWith("*")?n.startsWith(e.slice(0,-1)):n===e}function md(){return[...fd,...pr]}function Dt(n=process.env){let e=md(),t={};for(let[s,r]of Object.entries(n))r!==void 0&&(e.some(o=>pd(s,o))||(t[s]=r));return t}W();import*as K from"fs/promises";import{createHash as gd}from"crypto";import{gzip as hd,gunzip as yd}from"zlib";import{promisify as gr}from"util";var hr=gr(hd),wd=gr(yd),yr=/^[A-Za-z0-9_-]+$/,bd=/^[a-f0-9]{64}$/,Jn=!0;function wr(n){Jn=n}function Lt(n,e){return yr.test(n)?e===void 0||bd.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=gd("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 mt(n,e){if(!Lt(n,e))return null;try{let t=await K.readFile(qt(n,e));return(await wd(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 vd}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 Sd({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 Sd(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 Id({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 Ad(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 Id(n){let e=kd(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=vd.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 kd(n){let e=new URL(n);return xe.posix.basename(e.pathname)||"archive"}async function Ad(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 Cd("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 Cd(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 xd}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=Pd(n.packageSpec),r=_d(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 Md({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 Md(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 Td({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 Ed=5,Rd=25;function Td(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=xd("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<Ed)return await new Promise(r=>setTimeout(r,Rd*(e+1))),Er(n,e+1);throw t}}function Pd(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 _d(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()}),Fd=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()}),Od=F.object({package:F.string(),args:F.array(F.string()).optional(),env:F.record(F.string()).optional()}),Nd=F.object({command:F.string(),args:F.array(F.string()).optional(),env:F.record(F.string()).optional()}),Hd=F.object({command:F.string().optional(),url:F.string().optional(),description:F.string().optional()}),jd=F.object({npx:$d.optional(),binary:Fd.optional(),uvx:Od.optional(),exec:Nd.optional()}),Bd=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:jd,onboarding:Hd.optional(),requiredEnv:F.array(F.string().min(1)).optional()}),Tr=F.object({version:F.string(),agents:F.array(Bd),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:Ud(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 Ud(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 Jd}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()}),Dd=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:Dd.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()}),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: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()}),Ld=N.object({sessionId:N.string(),cwd:N.string(),title:N.string().optional(),updatedAt:N.string().optional(),_meta:N.record(N.unknown()).optional()}),Zp=N.object({sessions:N.array(Ld),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:gt(n._meta,Wt(n))};return n.title!==void 0&&(e.title=n.title),e}var le="hydra-acp";function qd(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=qd(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 gt(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()}),om=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()}),im=R.object({sessionId:R.string(),messageId:R.string(),prompt:R.array(R.unknown())}),am=R.object({sessionId:R.string(),messageId:R.string(),reason:R.enum(["started","cancelled","abandoned"])}),Lr=R.object({sessionId:R.string(),messageId:R.string()}),dm=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())}),cm=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()}),um=R.object({amended:R.boolean(),reason:R.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:R.string().optional()}),lm=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 mm=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
- `);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",()=>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 zd}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=zd(),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 Wd=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??Wd,this.killEscalationMs=e.killEscalationMs??Vd,this.logger=e.logger,this.fileLog=Qd(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()} ---
2
+ var Gd=Object.defineProperty;var rn=(s,e)=>()=>(s&&(e=s(s=0)),e);var Yd=(s,e)=>{for(var t in e)Gd(s,t,{get:e[t],enumerable:!0})};import*as L from"path";import*as ms from"os";function O(s){let e=ms.homedir();return e?s===e?"~":s.startsWith(e+"/")?"~"+s.slice(e.length):s:s}function Zd(){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 B(){let s=process.env[Xd];if(s&&s.length>0)return L.resolve(s);let e=Zd();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 L.join(ms.homedir(),".hydra-acp")}var Xd,A,K=rn(()=>{"use strict";Xd="HYDRA_ACP_HOME";A={home:B,config:()=>L.join(B(),"config.json"),authToken:()=>L.join(B(),"auth-token"),remotes:()=>L.join(B(),"remotes.json"),pidFile:()=>L.join(B(),"daemon.pid"),logFile:()=>L.join(B(),"daemon.log"),currentLogFile:()=>L.join(B(),"current.log"),registryCache:()=>L.join(B(),"registry.json"),themesDir:()=>L.join(B(),"themes"),ttySessionDir:()=>L.join(B(),"tty"),ttySessionFile:s=>L.join(B(),"tty",s),agentsDir:()=>L.join(B(),"agents"),agentLogFile:s=>L.join(B(),"agents","logs",`${s}.log`),agentInstallDir:(s,e,t)=>L.join(B(),"agents",e,s,t),agentNpmInstallDir:(s,e,t)=>L.join(B(),"agents",e,s,t,`node${process.versions.modules}`),sessionsDir:()=>L.join(B(),"sessions"),sessionDir:s=>L.join(B(),"sessions",s),sessionFile:s=>L.join(B(),"sessions",s,"meta.json"),historyFile:s=>L.join(B(),"sessions",s,"history.jsonl"),historyArchiveFile:(s,e)=>L.join(B(),"sessions",s,`history.jsonl.${e}`),toolsDir:s=>L.join(B(),"sessions",s,"tools"),toolBlobFile:(s,e)=>L.join(B(),"sessions",s,"tools",e),queueFile:s=>L.join(B(),"sessions",s,"queue.ndjson"),tombstonesDir:()=>L.join(B(),"sessions",".tombstones"),tombstoneAgentDir:s=>L.join(B(),"sessions",".tombstones",encodeURIComponent(s)),tombstoneFile:(s,e)=>L.join(B(),"sessions",".tombstones",encodeURIComponent(s),encodeURIComponent(e)),extensionsDir:()=>L.join(B(),"extensions"),extensionLogDir:s=>L.join(B(),"extensions",s),extensionLogFile:s=>L.join(B(),"extensions",s,"current.log"),extensionPidFile:s=>L.join(B(),"extensions",s,"extension.pid"),transformersDir:()=>L.join(B(),"transformers"),transformerLogDir:s=>L.join(B(),"transformers",s),transformerLogFile:s=>L.join(B(),"transformers",s,"current.log"),transformerPidFile:s=>L.join(B(),"transformers",s,"transformer.pid"),transformerState:(s,e)=>L.join(B(),"sessions",s,"transformer-state",e),tuiHistoryFile:s=>L.join(B(),"sessions",s,"prompt-history"),globalTuiHistoryFile:()=>L.join(B(),"prompt-history"),tuiLogFile:()=>L.join(B(),"tui.log"),shimWireLogFile:()=>L.join(B(),"shim-wire.log")}});import*as ne from"fs/promises";import*as Qr from"fs";import*as ke from"path";import{randomBytes as tc}from"crypto";async function fe(s,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
3
+ `;await nc(s,r,t)}async function nc(s,e,t={}){let n=await sc(s),r=rc(n);await ne.mkdir(r,{recursive:!0});let o=`${n}.tmp-${process.pid}-${oc()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await ne.writeFile(o,e,i),await ne.rename(o,n)}catch(i){throw await ne.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{Qr.chmodSync(n,t.mode)}catch{}}async function sc(s){let e;try{e=await ne.lstat(s)}catch(r){if(r.code==="ENOENT")return s;throw r}if(!e.isSymbolicLink())return s;let t=await ne.readlink(s),n=ke.isAbsolute(t)?t:ke.resolve(ke.dirname(s),t);try{let r=await ne.realpath(ke.dirname(n));return ke.join(r,ke.basename(n))}catch(r){if(r.code==="ENOENT")return n;throw r}}async function ee(s){let e;try{e=await ne.readFile(s,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}if(e.trim().length!==0)try{return JSON.parse(e)}catch{return}}function rc(s){let e=s.lastIndexOf("/");return e<=0?".":s.slice(0,e)}function oc(){return tc(4).toString("hex")}var Ne=rn(()=>{"use strict"});function ps(s,e){return`${s}:${e}`}var jd=rn(()=>{"use strict";K();Ne()});var Jd={};Yd(Jd,{_resetForTests:()=>Yg,clearPin:()=>qg,fetchPeerFingerprint:()=>Vg,formatFingerprint:()=>Bd,getPin:()=>zg,installGlobalTlsTrust:()=>Qg,loadPinsFromStore:()=>Jg,setPin:()=>Ld,sha256Hex:()=>Wr,wsTlsOptions:()=>Gg});import{createHash as jg}from"crypto";import*as Dd from"tls";import{Agent as Dg,Dispatcher as Lg,buildConnector as Bg,getGlobalDispatcher as Ug,setGlobalDispatcher as Wg}from"undici";function Ld(s,e,t){Xe.set(ps(s,e),Ud(t))}function qg(s,e){Xe.delete(ps(s,e))}function zg(s,e){return Xe.get(ps(s,e))}function Jg(s){Xe.clear();for(let e of s.list())e.entry.pinnedFingerprint&&Ld(e.host,e.port,e.entry.pinnedFingerprint)}async function Vg(s,e,t={}){let n=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=Dd.connect({host:s,port:e,servername:s,rejectUnauthorized:!1,autoSelectFamily:!0}),a=!1,d=(c,l)=>{if(!a){a=!0,clearTimeout(u);try{i.destroy()}catch{}c?o(c):l&&r(l)}},u=setTimeout(()=>{d(new Error(`TLS connect to ${s}:${e} timed out`))},n);i.once("secureConnect",()=>{let c=i.getPeerCertificate(!1);if(!c||!c.raw){d(new Error(`${s}:${e} did not present a TLS certificate`));return}d(null,Wr(c.raw))}),i.once("error",c=>d(c))})}function Wr(s){return jg("sha256").update(s).digest("hex")}function Bd(s){let e=Ud(s),t=e.match(/.{2}/g);return t?t.join(":"):e}function Ud(s){return s.replace(/:/g,"").toLowerCase()}function Qg(){if(Ur)return;Ur=!0;let s=Ug(),e=new Dg({connect:Bg({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(n,r)=>qd(n,r)})}),t=new Lg;t.dispatch=(n,r)=>{let o=Kg(n.origin);return(o&&Wd(o)?e:s).dispatch(n,r)},t.close=(()=>Promise.all([e.close(),s.close()]).then(()=>{})),t.destroy=(n=>Promise.all([e.destroy(n??null),s.destroy(n??null)]).then(()=>{})),Wg(t)}function Kg(s){if(!s)return null;try{return new URL(String(s)).hostname}catch{return null}}function Wd(s){for(let e of Xe.keys())if(zd(e)?.host===s)return!0;return!1}function qd(s,e){if(!e||!e.raw)return new Error(`TLS peer ${s} did not present a certificate`);let t=Wr(e.raw);for(let[n,r]of Xe.entries()){let o=zd(n);if(o&&o.host===s&&r===t)return}return new Error(`TLS pin mismatch for ${s} (cert sha256 ${Bd(t)})`)}function zd(s){let e=s.lastIndexOf(":");if(e<0)return null;let t=s.slice(0,e),n=Number(s.slice(e+1));return Number.isInteger(n)?{host:t,port:n}:null}function Gg(s){return Wd(s)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>qd(e,t)}:{autoSelectFamily:!0}}function Yg(){Xe.clear(),Ur=!1}var Xe,Ur,Vd=rn(()=>{"use strict";jd();Xe=new Map,Ur=!1});K();import*as Be from"fs/promises";import{homedir as ws}from"os";import{z as I}from"zod";K();import*as et from"fs/promises";function hs(){let s=new Uint8Array(32);crypto.getRandomValues(s);let e="";for(let t of s)e+=t.toString(16).padStart(2,"0");return`hydra_token_${e}`}async function ec(){try{let e=(await et.readFile(A.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(s){if(s.code==="ENOENT")return;throw s}}async function ys(s){await et.mkdir(A.home(),{recursive:!0}),await et.writeFile(A.authToken(),s+`
4
+ `,{encoding:"utf8",mode:384})}async function Vr(){let s=await ec();if(s)return s;let e=hs();return await ys(e),process.stderr.write(`hydra-acp: initialized ${A.authToken()} with a fresh service token.
5
+ `),e}Ne();var Yr="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",ic=I.object({cert:I.string(),key:I.string()}),Xr=55514,ac=I.object({host:I.string().default("127.0.0.1"),port:I.number().int().positive().default(Xr),logLevel:I.enum(["debug","info","warn","error"]).default("info"),tls:ic.optional(),sessionIdleTimeoutSeconds:I.number().int().nonnegative().default(3600),sessionHistoryMaxEntries:I.number().int().positive().default(1e4),sessionHistoryArchiveMaxBytes:I.number().int().nonnegative().default(1e7),sessionHistoryArchiveTiers:I.number().int().positive().default(10),agentStderrTailBytes:I.number().int().positive().default(4096),publicHost:I.string().optional(),agentSyncIntervalMinutes:I.number().nonnegative().default(60),scrubEnv:I.array(I.string()).default([]),sessionGcIntervalMinutes:I.number().nonnegative().default(60),sessionGcMaxAgeDays:I.number().positive().default(2)}),dc=I.object({url:I.string().url().default(Yr),ttlHours:I.number().positive().default(24),pinned:I.boolean().default(!1)}),cc=I.object({name:I.string().optional(),description:I.string().optional(),command:I.string().optional(),args:I.array(I.string()).optional(),env:I.record(I.string()).optional()}),uc=I.object({packageSpec:I.string().optional()}),lc=I.enum(["enter","alt-enter","shift-enter","ctrl-enter","alt-b","alt-f","alt-n","alt-tab","shift-tab","tab","up","down","left","right","home","end","backspace","alt-backspace","delete","ctrl-a","ctrl-b","ctrl-c","ctrl-d","ctrl-e","ctrl-f","ctrl-g","ctrl-k","ctrl-l","ctrl-n","ctrl-o","ctrl-p","ctrl-q","ctrl-r","ctrl-s","ctrl-u","ctrl-v","ctrl-t","ctrl-w","ctrl-x","ctrl-y","ctrl-underscore","alt-underscore","escape"]),fc=I.union([I.string(),I.object({field:I.string().optional(),text:I.string().optional(),maxWidth:I.number().int().positive().optional(),minWidth:I.number().int().nonnegative().optional(),priority:I.number().optional(),prefix:I.string().optional(),suffix:I.string().optional(),separator:I.string().optional(),style:I.string().optional(),onClick:I.string().optional(),onDoubleClick:I.string().optional()}).strict()]),Kr=I.array(fc);function ks(s,e){return I.object({left:Kr.default(s),right:Kr.default(e)}).default({})}var pc=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],gc=["usage"],mc=[],hc=["helpHint"],yc=["cwd","title"],wc=["agentModel"],kc=I.object({composer:I.object({top:ks(pc,gc),bottom:ks(mc,hc)}).default({}),sessionbar:ks(yc,wc),repaintThrottleMs:I.number().int().nonnegative().default(1e3),maxScrollbackLines:I.number().int().positive().default(1e4),mouse:I.boolean().default(!0),inAppSelection:I.boolean().optional(),selectionClipboard:I.enum(["primary","clipboard","both"]).default("both"),openFileCommand:I.union([I.string(),I.array(I.string())]).optional(),logMaxBytes:I.number().int().positive().default(5*1024*1024),cwdColumnMaxWidth:I.number().int().positive().default(32),progressIndicator:I.boolean().default(!0),launcherModeWhenHosted:I.boolean().default(!1),defaultEnterAction:I.enum(["enqueue","amend"]).default("amend"),showThoughts:I.boolean().default(!0),ambiguousWidth:I.enum(["auto","narrow","wide"]).default("auto"),toolContent:I.enum(["inline","references"]).default("references"),diffContextLines:I.number().int().min(0).default(3),promptHistoryMaxEntries:I.number().int().positive().default(2e3),maxToolItems:I.number().int().nonnegative().default(5),maxPlanItems:I.number().int().nonnegative().default(5),sidebar:I.object({enabled:I.boolean().default(!1),width:I.number().int().positive().optional(),border:I.enum(["none","rule","frame"]).default("frame"),gadgets:I.array(I.string()).default(["activity","sessions","context","queue","todo","files","git","resources","info","tools"])}).default({}),showFileUpdates:I.enum(["none","edit","diff"]).default("edit"),sessionColumns:I.array(I.enum(["session","upstream","host","state","agent","model","age","cwd","title","cost"])).nonempty().optional(),hotkeys:I.record(lc,I.object({command:I.union([I.string(),I.array(I.string())])})).default({}),theme:I.union([I.string(),I.record(I.string(),I.unknown())]).optional(),themeBackground:I.string().optional()}),Gr=I.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),vc=I.object({command:I.array(I.string()).default([]),args:I.array(I.string()).default([]),env:I.record(I.string()).default({}),enabled:I.boolean().default(!0)}),bc=I.object({command:I.array(I.string()).default([]),args:I.array(I.string()).default([]),env:I.record(I.string()).default({}),enabled:I.boolean().default(!0)}),Sc=I.object({daemon:ac.default({}),registry:dc.default({url:Yr,ttlHours:24,pinned:!1}),agents:I.record(I.string(),cc).default({}),agentOverrides:I.record(I.string(),uc).default({}),defaultAgent:I.string().default("opencode"),defaultModels:I.record(I.string(),I.string()).default({}),synopsisAgent:I.string().optional(),synopsisModel:I.string().optional(),compaction:I.object({agent:I.string().optional(),model:I.string().optional(),tailK:I.number().int().nonnegative().default(20),maxIterations:I.number().int().positive().default(3),contextFraction:I.number().min(0).max(1).default(.5),hardCeilingFraction:I.number().min(0).max(1).default(.85),absoluteFallback:I.number().int().positive().default(2e5),idleBeforePromptMs:I.number().int().nonnegative().default(3e5),modelContextWindows:I.record(I.string(),I.number().int().positive()).default({})}).default({}),defaultCwd:I.string().default("~"),disableWorkspaceSnapshots:I.boolean().optional(),compressToolContent:I.boolean().default(!0),sessionListColdLimit:I.number().int().nonnegative().default(20),extensions:I.record(Gr,vc).default({}),transformers:I.record(Gr,bc).default({}),defaultTransformers:I.array(I.string()).default([]),npmRegistry:I.string().url().optional(),tui:kc.default({})});function Zr(s){return Object.entries(s.extensions).map(([e,t])=>({name:e,...t}))}function eo(s){return Object.entries(s.transformers).map(([e,t])=>({name:e,...t}))}async function to(){return await Ic(),await ee(A.config())??{}}async function Ic(){let s;try{s=await Be.lstat(A.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(s.isSymbolicLink())try{await Be.stat(A.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await Be.readlink(A.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${A.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 Ac(){let s=await to(),e=s.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let n=!1;try{await Be.access(A.authToken()),n=!0}catch(r){if(r.code!=="ENOENT")throw r}if(n)throw new Error(`Auth token present in both ${A.authToken()} and ${A.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await ys(t),delete e.authToken,Object.keys(e).length===0&&delete s.daemon,await fe(A.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${A.config()} to ${A.authToken()}.
6
+ `)}async function vs(){return await Ac(),Sc.parse(await to())}function de(s){return s==="~"||s==="$HOME"?ws():s.startsWith("~/")?ws()+s.slice(1):s.startsWith("$HOME/")?ws()+s.slice(5):s}import*as Fd from"fs";import*as Fe from"fs/promises";import*as Nd from"net";import*as Pt from"path";import*as Od from"tls";import Tg from"fastify";import _g from"@fastify/websocket";var no="acp.v1";function so(s,e){return s.has(no)?no:!1}import _d from"pino";import $g from"pino-roll";var Cc={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"]},ro="HYDRA_ACP_SESSION",xc=[ro],Rc=[...Object.values(Cc).flat(),...xc];function on(s,e){return s?{...e??{},[ro]:s}:e}var oo=[];function io(s){oo=s?[...s]:[]}function Ec(s,e){return e.endsWith("*")?s.startsWith(e.slice(0,-1)):s===e}function Pc(){return[...Rc,...oo]}function an(s=process.env){let e=Pc(),t={};for(let[n,r]of Object.entries(s))r!==void 0&&(e.some(o=>Ec(n,o))||(t[n]=r));return t}K();import*as se from"fs/promises";import{createHash as Mc}from"crypto";import{gzip as Tc,gunzip as _c}from"zlib";import{promisify as ao}from"util";var co=ao(Tc),$c=ao(_c),uo=/^[A-Za-z0-9_-]+$/,Fc=/^[a-f0-9]{64}$/,bs=!0;function lo(s){bs=s}function dn(s,e){return uo.test(s)?e===void 0||Fc.test(e):!1}function cn(s,e){return`${A.toolBlobFile(s,e)}.gz`}async function Ss(s,e){if(!dn(s))return null;let t=Mc("sha256").update(e,"utf8").digest("hex"),n=cn(s,t),r=A.toolBlobFile(s,t);for(let a of[n,r])try{return await se.access(a),t}catch{}await se.mkdir(A.toolsDir(s),{recursive:!0});let o=bs?n:r,i=bs?await co(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await se.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function Mt(s,e){if(!dn(s,e))return null;try{let t=await se.readFile(cn(s,e));return(await $c(t)).toString("utf8")}catch{}try{return await se.readFile(A.toolBlobFile(s,e),"utf8")}catch{return null}}async function fo(s,e){if(!dn(s,e))return null;try{return await se.readFile(cn(s,e))}catch{}try{let t=await se.readFile(A.toolBlobFile(s,e));return await co(t)}catch{return null}}async function po(s,e,t){if(!dn(s,e))return;let n=cn(s,e);try{await se.access(n);return}catch{}await se.mkdir(A.toolsDir(s),{recursive:!0}),await se.writeFile(n,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function go(s){uo.test(s)&&await se.rm(A.toolsDir(s),{recursive:!0,force:!0}).catch(()=>{})}K();import*as Co from"fs/promises";import*as ln from"path";import{z as j}from"zod";Ne();K();import*as ho from"fs";import*as ce from"fs/promises";import*as Ue from"path";import{spawn as yo}from"child_process";import{Readable as Nc}from"stream";function Ae(){let s=process.platform==="darwin"?"darwin":process.platform==="linux"?"linux":process.platform==="win32"?"windows":void 0,e=process.arch==="arm64"?"aarch64":process.arch==="x64"?"x86_64":void 0;if(!(!s||!e))return`${s}-${e}`}function Cs(s,e=Ae()){if(e)return s[e]}var tt=s=>{process.stderr.write(s+`
7
+ `)};function xs(s){tt=s??(e=>process.stderr.write(e+`
8
+ `))}async function wo(s){if(!s.target.archive)throw new Error(`Agent ${s.agentId} has no archive URL for ${Ae()??"this platform"}`);if(!s.target.cmd)throw new Error(`Agent ${s.agentId} has no cmd in its binary target`);let e=Ae();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=A.agentInstallDir(s.agentId,e,s.version),n=Ue.resolve(t,s.target.cmd);if(await As(n))return n;if(await Oc({agentId:s.agentId,version:s.version,archiveUrl:s.target.archive,installDir:t,onProgress:s.onProgress}),!await As(n))throw new Error(`Agent ${s.agentId}: extracted archive did not contain ${s.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await ce.chmod(n,493).catch(()=>{}),n}async function Oc(s){await ce.mkdir(Ue.dirname(s.installDir),{recursive:!0});let e=await ce.mkdtemp(`${s.installDir}.partial-`);try{tt(`hydra-acp: downloading ${s.agentId} from ${s.archiveUrl}`);let t=await Hc({url:s.archiveUrl,dir:e,agentId:s.agentId,version:s.version,onProgress:s.onProgress});tt(`hydra-acp: extracting ${s.agentId}`),nt(s.onProgress,{phase:"extract",agentId:s.agentId,version:s.version}),await Dc(t,e),await ce.unlink(t).catch(()=>{});try{await ce.rename(e,s.installDir)}catch(n){let r=n;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await As(s.installDir)){await ce.rm(e,{recursive:!0,force:!0}).catch(()=>{}),nt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw n}tt(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),nt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await ce.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function nt(s,e){if(s)try{s(e)}catch{}}async function Hc(s){let e=jc(s.url),t=Ue.join(s.dir,e),n=await fetch(s.url,{redirect:"follow"});if(!n.ok||!n.body)throw new Error(`Failed to download ${s.url}: HTTP ${n.status} ${n.statusText}`);let r=Number(n.headers.get("content-length")??"0"),o=ho.createWriteStream(t),i=Nc.fromWeb(n.body);nt(s.onProgress,{phase:"download_start",agentId:s.agentId,version:s.version,totalBytes:r});let a=0,d=Date.now(),u=0,c=2e3,l=150;return i.on("data",p=>{a+=p.length;let f=Date.now();f-u>=l&&(u=f,nt(s.onProgress,{phase:"download_progress",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r})),f-d>=c&&(d=f,tt(mo(s.agentId,a,r)))}),await new Promise((p,f)=>{i.on("error",f),o.on("error",f),o.on("finish",()=>p()),i.pipe(o)}),tt(mo(s.agentId,a,r,!0)),nt(s.onProgress,{phase:"download_done",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r}),t}function mo(s,e,t,n=!1){let r=(e/1e6).toFixed(1);if(t>0){let i=(t/1e6).toFixed(1),a=Math.min(100,Math.floor(e/t*100));return`hydra-acp: ${n?"downloaded":"downloading"} ${s} ${r}/${i} MB (${a}%)`}return`hydra-acp: ${n?"downloaded":"downloading"} ${s} ${r} MB`}function jc(s){let e=new URL(s);return Ue.posix.basename(e.pathname)||"archive"}async function Dc(s,e){let t=s.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await Is("tar",["-xf",s,"-C",e]);return}if(t.endsWith(".zip")){if(await Lc("unzip")){await Is("unzip",["-q",s,"-d",e]);return}await Is("tar",["-xf",s,"-C",e]);return}throw new Error(`Unsupported archive format: ${s}`)}function Is(s,e){return new Promise((t,n)=>{let r=yo(s,e,{stdio:["ignore","ignore","inherit"]});r.on("error",n),r.on("exit",(o,i)=>{if(o===0){t();return}n(new Error(`${s} ${e.join(" ")} exited with ${o!==null?`code ${o}`:`signal ${i}`}`))})})}async function Lc(s){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",n=yo(t,[s],{stdio:"ignore"});n.on("error",()=>e(!1)),n.on("exit",r=>e(r===0))})}async function As(s){try{return await ce.access(s),!0}catch{return!1}}K();import*as pe from"fs/promises";import*as Ce from"path";import{spawn as Bc}from"child_process";var Es=s=>{process.stderr.write(s+`
9
+ `)};function Ps(s){Es=s??(e=>process.stderr.write(e+`
10
+ `))}async function vo(s){let e=Ae();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=A.agentNpmInstallDir(s.agentId,e,s.version),n=Jc(s.packageSpec),r=Vc(n),o={installDir:t,packageName:n,hint:s.bin,basename:r},i=Ce.join(t,"node_modules",".bin",s.bin);if(await Qe(i))return i;if(await Qe(t)){let l=await ko(o);if(l)return l.binPath}await Uc({agentId:s.agentId,version:s.version,packageSpec:s.packageSpec,installDir:t,registry:s.registry,onProgress:s.onProgress});let a=await ko(o);if(a)return a.binPath;let d=await So(t,n),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 ${s.agentId}: npm install of ${s.packageSpec} did not produce bin ${s.bin} (looked in ${t}/node_modules/.bin/)${c}`)}async function Uc(s){await pe.mkdir(Ce.dirname(s.installDir),{recursive:!0});let e=await pe.mkdtemp(`${s.installDir}.partial-`);try{Es(`hydra-acp: installing ${s.packageSpec} for ${s.agentId} into ${e}`),Rs(s.onProgress,{phase:"install_start",agentId:s.agentId,version:s.version,packageSpec:s.packageSpec}),await zc({packageSpec:s.packageSpec,cwd:e,registry:s.registry});try{await pe.rename(e,s.installDir)}catch(t){let n=t;if((n.code==="EEXIST"||n.code==="ENOTEMPTY")&&await Qe(s.installDir)){await pe.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Rs(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw t}Es(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),Rs(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await pe.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Rs(s,e){if(s)try{s(e)}catch{}}var Wc=5,qc=25;function zc(s){return bo(s,0)}async function bo(s,e){try{await new Promise((t,n)=>{let r=s.registry?["--registry",s.registry]:[],o;try{o=Bc("npm",["install","--no-audit","--no-fund","--silent",...r,s.packageSpec],{cwd:s.cwd,stdio:["ignore","pipe","pipe"]})}catch(a){n(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"){n(new Error("npm not found on PATH (install Node.js / npm, or use a binary-distributed agent)"));return}n(a)}),o.on("exit",(a,d)=>{if(a===0){t();return}let u=a!==null?`exit code ${a}`:`signal ${d??"unknown"}`,c=i.trim();n(new Error(c?`npm install ${s.packageSpec} failed (${u})
11
+ stderr: ${c}`:`npm install ${s.packageSpec} failed (${u})`))})})}catch(t){if(t.code==="ETXTBSY"&&e<Wc)return await new Promise(r=>setTimeout(r,qc*(e+1))),bo(s,e+1);throw t}}function Jc(s){if(s.startsWith("@")){let t=s.indexOf("/");if(t===-1)return s;let r=s.slice(t+1).indexOf("@");return r===-1?s:s.slice(0,t+1+r)}let e=s.indexOf("@");return e<=0?s:s.slice(0,e)}function Vc(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}async function So(s,e){let t=Ce.join(s,"node_modules",e,"package.json");try{let n=await pe.readFile(t,"utf8"),r=JSON.parse(n);return typeof r.bin=="string"||typeof r.bin=="object"&&r.bin!==null&&!Array.isArray(r.bin)?r.bin:void 0}catch{return}}async function ko(s){let e=Ce.join(s.installDir,"node_modules",".bin"),t=Ce.join(e,s.hint);if(await Qe(t))return{binName:s.hint,binPath:t};let n=await So(s.installDir,s.packageName);if(typeof n=="object"&&n!==null){let r=Object.keys(n);if(r.length===1){let o=r[0],i=Ce.join(e,o);if(await Qe(i))return{binName:o,binPath:i}}else if(r.length>1){for(let o of[s.hint,s.basename])if(r.includes(o)){let i=Ce.join(e,o);if(await Qe(i))return{binName:o,binPath:i}}}}if(s.basename!==s.hint){let r=Ce.join(e,s.basename);if(await Qe(r))return{binName:s.basename,binPath:r}}}async function Qe(s){try{return await pe.access(s),!0}catch{return!1}}var Qc=j.object({package:j.string(),bin:j.string().optional(),args:j.array(j.string()).optional(),env:j.record(j.string()).optional()}),st=j.object({archive:j.string().url().optional(),cmd:j.string().optional(),args:j.array(j.string()).optional(),env:j.record(j.string()).optional()}),Kc=j.object({"darwin-aarch64":st.optional(),"darwin-x86_64":st.optional(),"linux-aarch64":st.optional(),"linux-x86_64":st.optional(),"windows-x86_64":st.optional(),"windows-aarch64":st.optional()}),Gc=j.object({package:j.string(),args:j.array(j.string()).optional(),env:j.record(j.string()).optional()}),Yc=j.object({command:j.string(),args:j.array(j.string()).optional(),env:j.record(j.string()).optional()}),Xc=j.object({command:j.string().optional(),url:j.string().optional(),description:j.string().optional()}),Zc=j.object({npx:Qc.optional(),binary:Kc.optional(),uvx:Gc.optional(),exec:Yc.optional()}),eu=j.object({id:j.string(),name:j.string(),version:j.string().optional(),description:j.string().optional(),authors:j.array(j.string()).optional(),license:j.string().optional(),icon:j.string().optional(),repository:j.string().optional(),website:j.string().optional(),distribution:Zc,onboarding:Xc.optional(),requiredEnv:j.array(j.string().min(1)).optional()}),Io=j.object({version:j.string(),agents:j.array(eu),extensions:j.array(j.unknown()).optional()}),un=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(),n=t.find(u=>u.id===e)??t.find(u=>u.id.toLowerCase()===`${e.toLowerCase()}-acp`);if(n)return n;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=>Ms(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:de(t.command??e),args:t.args?.map(de),env:t.env}}}))}applyOverride(e){let t=this.config.agentOverrides?.[e.id];return!t?.packageSpec||!e.distribution.npx?e:{...e,version:tu(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,n=this.config.registry.ttlHours*60*60*1e3;return t<n}async fetchFromNetwork(){let e=await fetch(this.config.registry.url);if(!e.ok)throw new Error(`Registry fetch failed: HTTP ${e.status}`);let t=await e.json(),n=Io.parse(t),r={fetchedAt:Date.now(),raw:t,data:n},o=this.options.onFetched;return o&&Promise.resolve().then(()=>o(n)).catch(()=>{}),r}async readDiskCache(){let e=await ee(A.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=Io.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await fe(A.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function tu(s){let e=s.lastIndexOf("@"),n=(e>0?s.slice(e+1):"").replace(/[^a-zA-Z0-9._-]/g,"_");return n.length>0?`pin-${n}`:"pinned"}function Ms(s){let e=s.distribution.npx?.package;if(!e)return;let t=e.lastIndexOf("/"),n=t===-1?e:e.slice(t+1),r=n.lastIndexOf("@");return r<=0?n:n.slice(0,r)}async function rt(s){let e=typeof s.localAgents=="function"?s.localAgents():[],t;try{t=await s.load()}catch(i){if(e.length===0)throw i;t={version:"local-only",agents:[]}}let n=new Set(e.map(i=>i.id)),r=[...e,...t.agents.filter(i=>!n.has(i.id))],o=await Promise.all(r.map(async i=>({id:i.id,name:i.name,version:i.version,description:i.description,distributions:Object.keys(i.distribution),installed:await Ts(i),source:n.has(i.id)?"local":"registry",...i.onboarding?{onboarding:i.onboarding}:{}})));return{version:t.version,fetchedAt:s.lastFetchedAt(),agents:o}}async function Ts(s){let e=Ae();if(!e)return"no";let t=s.version??"current";if(s.distribution.exec)return"yes";if(s.distribution.binary){let n=Cs(s.distribution.binary,e);if(n?.cmd){let r=ln.resolve(A.agentInstallDir(s.id,e,t),n.cmd);if(await Ao(r))return"yes"}}if(s.distribution.npx){let n=s.distribution.npx,r=n.bin??Ms(s)??n.package,o=A.agentNpmInstallDir(s.id,e,t),i=ln.join(o,"node_modules",".bin",r);if(await Ao(i))return"yes"}return!s.distribution.npx&&!s.distribution.binary&&s.distribution.uvx?"lazy":"no"}async function Ao(s){try{return await Co.access(s),!0}catch{return!1}}async function ye(s,e=[],t={}){let n=s.version??"current";if(s.distribution.npx){let r=s.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:n};let i=r.bin??Ms(s)??r.package,a=t.onInstallProgress;return{command:await vo({agentId:s.id,version:n,packageSpec:r.package,bin:i,registry:t.npmRegistry,onProgress:a?u=>a({source:"npm",...u}):void 0}),args:o,env:r.env??{},version:n}}if(s.distribution.binary){let r=Cs(s.distribution.binary);if(!r)throw new Error(`Agent ${s.id} has no binary distribution for ${Ae()??"this platform"}.`);let o=t.onInstallProgress,i=await wo({agentId:s.id,version:n,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:n}}if(s.distribution.uvx){let r=s.distribution.uvx,o=e.length>0?e:r.args??[];return{command:"uvx",args:[r.package,...o],env:r.env??{},version:n}}if(s.distribution.exec){let r=s.distribution.exec,o=e.length>0?e:r.args??[];return{command:r.command,args:o,env:r.env??{},version:n}}throw new Error(`Agent ${s.id} has no usable distribution method.`)}import{spawn as iu}from"child_process";import*as gn from"fs";import*as Bo from"path";var C={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 J}from"zod";var xo=J.object({protocolVersion:J.number().optional(),clientCapabilities:J.record(J.unknown()).optional(),clientInfo:J.object({name:J.string(),version:J.string().optional()}).optional()}),nu=J.enum(["full","pending_only","none","after_message"]),Ro=J.object({cwd:J.string(),mcpServers:J.array(J.unknown()).optional(),_meta:J.record(J.unknown()).optional()}),Eo=J.object({upstreamSessionId:J.string(),agentId:J.string(),cwd:J.string(),title:J.string().optional(),agentArgs:J.array(J.string()).optional()}),Po=J.object({sessionId:J.string(),historyPolicy:nu.default("full"),afterMessageId:J.string().optional(),clientId:J.string().optional(),clientInfo:J.object({name:J.string(),version:J.string().optional()}).optional(),_meta:J.record(J.unknown()).optional()});import{z as $}from"zod";var Mo=$.object({sessionId:$.string()}),To=$.object({cwd:$.string().optional(),cursor:$.string().optional()}),_s=$.object({used:$.number().optional(),size:$.number().optional(),costAmount:$.number().optional(),costCurrency:$.string().optional()}),Dm=$.object({sessionId:$.string(),upstreamSessionId:$.string().optional(),cwd:$.string(),workspace:$.object({path:$.string(),sourceCwd:$.string(),label:$.string(),provider:$.string(),snapshot:$.string().optional(),vcs:$.record($.string(),$.string()).optional()}).optional(),workspaceError:$.string().optional(),title:$.string().optional(),agentId:$.string().optional(),currentModel:$.string().optional(),currentUsage:_s.optional(),importedFromMachine:$.string().optional(),importedFromUpstreamSessionId:$.string().optional(),parentSessionId:$.string().optional(),forkedFromSessionId:$.string().optional(),forkedFromMessageId:$.string().optional(),originatingClient:$.object({name:$.string(),version:$.string().optional()}).optional(),interactive:$.boolean().optional(),priority:$.number().int().nonnegative().optional(),updatedAt:$.string(),attachedClients:$.number().int().nonnegative(),status:$.enum(["warm","cold"]).default("warm"),busy:$.boolean().default(!1),awaitingInput:$.boolean().default(!1),armedTasks:$.number().int().nonnegative().optional(),armedSince:$.number().int().positive().optional(),compactionState:$.any().optional(),agentPid:$.number().int().positive().optional(),forkSynthesisState:$.enum(["running","failed"]).optional(),_meta:$.record($.unknown()).optional()}),su=$.object({sessionId:$.string(),cwd:$.string(),title:$.string().optional(),updatedAt:$.string().optional(),_meta:$.record($.unknown()).optional()}),Lm=$.object({sessions:$.array(su),nextCursor:$.string().optional()});function fn(s,e){let t={attachedClients:s.attachedClients,status:s.status,busy:s.busy,awaitingInput:s.awaitingInput};return s.cwd!==void 0&&(t.cwd=s.cwd),s.workspace!==void 0&&(t.workspaceInfo=s.workspace),s.workspaceError!==void 0&&(t.workspaceError=s.workspaceError),s.title!==void 0&&(t.title=s.title),s.agentId!==void 0&&(t.agentId=s.agentId),s.upstreamSessionId!==void 0&&(t.upstreamSessionId=s.upstreamSessionId),s.currentModel!==void 0&&(t.currentModel=s.currentModel),s.currentUsage!==void 0&&(t.currentUsage=s.currentUsage),s.importedFromMachine!==void 0&&(t.importedFromMachine=s.importedFromMachine),s.importedFromUpstreamSessionId!==void 0&&(t.importedFromUpstreamSessionId=s.importedFromUpstreamSessionId),s.parentSessionId!==void 0&&(t.parentSessionId=s.parentSessionId),s.forkedFromSessionId!==void 0&&(t.forkedFromSessionId=s.forkedFromSessionId),s.forkedFromMessageId!==void 0&&(t.forkedFromMessageId=s.forkedFromMessageId),s.originatingClient!==void 0&&(t.originatingClient=s.originatingClient),s.interactive!==void 0&&(t.interactive=s.interactive),s.priority!==void 0&&s.priority>0&&(t.priority=s.priority),s.compactionState!==void 0&&(t.compactionState=s.compactionState),s.forkSynthesisState!==void 0&&(t.forkSynthesisState=s.forkSynthesisState),e&&(e.clientId!==void 0&&(t.clientId=e.clientId),e.currentMode!==void 0&&(t.currentMode=e.currentMode),e.agentArgs!==void 0&&e.agentArgs.length>0&&(t.agentArgs=e.agentArgs),e.availableCommands!==void 0&&e.availableCommands.length>0&&(t.availableCommands=e.availableCommands),e.availableModes!==void 0&&e.availableModes.length>0&&(t.availableModes=e.availableModes),e.availableModels!==void 0&&e.availableModels.length>0&&(t.availableModels=e.availableModels),e.turnStartedAt!==void 0&&(t.turnStartedAt=e.turnStartedAt),e.agentCapabilities!==void 0&&(t.agentCapabilities=e.agentCapabilities),e.queue!==void 0&&e.queue.length>0&&(t.queue=e.queue),e.resurrected===!0&&(t.resurrected=!0)),t}function _o(s){let e={sessionId:s.sessionId,cwd:s.cwd,updatedAt:s.updatedAt,_meta:Tt(s._meta,fn(s))};return s.title!==void 0&&(e.title=s.title),e}var ve="hydra-acp";function ru(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e={};for(let[t,n]of Object.entries(s)){if(typeof t!="string"||t.length===0||typeof n!="string")return;e[t]=n}return e}function ot(s){if(!s)return{};let e=s[ve];if(!e||typeof e!="object"||Array.isArray(e))return{};let t=e,n={};if(typeof t.upstreamSessionId=="string"&&(n.upstreamSessionId=t.upstreamSessionId),typeof t.agentId=="string"&&(n.agentId=t.agentId),typeof t.cwd=="string"&&(n.cwd=t.cwd),t.workspace!==null&&typeof t.workspace=="object"&&!Array.isArray(t.workspace)){let r=t.workspace,o={};typeof r.label=="string"&&(o.label=r.label),typeof r.from=="string"&&(o.from=r.from),r.required===!0&&(o.required=!0),typeof r.provider=="string"&&(o.provider=r.provider),n.workspace=o}if(t.workspaceInfo!==null&&typeof t.workspaceInfo=="object"&&!Array.isArray(t.workspaceInfo)){let r=t.workspaceInfo;if(typeof r.path=="string"&&typeof r.sourceCwd=="string"&&typeof r.label=="string"&&typeof r.provider=="string"){let o={path:r.path,sourceCwd:r.sourceCwd,label:r.label,provider:r.provider};if(typeof r.snapshot=="string"&&(o.snapshot=r.snapshot),r.vcs!==null&&typeof r.vcs=="object"&&!Array.isArray(r.vcs)){let i={};for(let[a,d]of Object.entries(r.vcs))typeof d=="string"&&(i[a]=d);o.vcs=i}n.workspaceInfo=o}}if(typeof t.workspaceError=="string"&&(n.workspaceError=t.workspaceError),typeof t.clientId=="string"&&(n.clientId=t.clientId),typeof t.readonly=="boolean"&&(n.readonly=t.readonly),(t.replayMode==="instant"||t.replayMode==="drip")&&(n.replayMode=t.replayMode),typeof t.dripSpeed=="number"&&t.dripSpeed>0&&(n.dripSpeed=t.dripSpeed),(t.toolContent==="inline"||t.toolContent==="references")&&(n.toolContent=t.toolContent),t.detachStatus==="detached"&&(n.detachStatus=t.detachStatus),typeof t.title=="string"&&(n.title=t.title),Array.isArray(t.agentArgs)&&t.agentArgs.every(r=>typeof r=="string")&&(n.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(r=>typeof r=="string")&&(n.transformers=t.transformers),t.resume){let r=Eo.safeParse(t.resume);r.success&&(n.resume=r.data)}if(typeof t.model=="string"&&(n.model=t.model),typeof t.currentModel=="string"&&(n.currentModel=t.currentModel),typeof t.currentMode=="string"&&(n.currentMode=t.currentMode),t.currentUsage){let r=_s.safeParse(t.currentUsage);r.success&&(n.currentUsage=r.data)}if(typeof t.turnStartedAt=="number"&&t.turnStartedAt>0&&(n.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&&(n.availableCommands=r)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let r=t.prompt,o={};typeof r.queueing=="boolean"&&(o.queueing=r.queueing),typeof r.cancelling=="boolean"&&(o.cancelling=r.cancelling),typeof r.updating=="boolean"&&(o.updating=r.updating),typeof r.amending=="boolean"&&(o.amending=r.amending),typeof r.pipelining=="boolean"&&(o.pipelining=r.pipelining),n.prompt=o}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let r=t.agents,o={};typeof r.list=="boolean"&&(o.list=r.list),typeof r.installProgress=="boolean"&&(o.installProgress=r.installProgress),n.agents=o}if(typeof t.mcpStdin=="boolean"&&(n.mcpStdin=t.mcpStdin),typeof t.interactive=="boolean"&&(n.interactive=t.interactive),typeof t.ancillary=="boolean"&&(n.ancillary=t.ancillary),Array.isArray(t.queue)){let r=[];for(let o of t.queue){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o,a=i.originator;if(typeof i.messageId!="string"||!a||typeof a.clientId!="string"||!Array.isArray(i.prompt)||typeof i.position!="number"||typeof i.enqueuedAt!="number")continue;let d={clientId:a.clientId};typeof a.name=="string"&&(d.name=a.name),typeof a.version=="string"&&(d.version=a.version),r.push({messageId:i.messageId,originator:d,prompt:i.prompt,position:i.position,enqueuedAt:i.enqueuedAt})}r.length>0&&(n.queue=r)}if(Array.isArray(t.availableModes)){let r=[];for(let o of t.availableModes){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.id!="string")continue;let a={id:i.id};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}r.length>0&&(n.availableModes=r)}if(Array.isArray(t.availableModels)){let r=[];for(let o of t.availableModels){if(!o||typeof o!="object"||Array.isArray(o))continue;let i=o;if(typeof i.modelId!="string")continue;let a={modelId:i.modelId};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}r.length>0&&(n.availableModels=r)}if((t.status==="warm"||t.status==="cold")&&(n.status=t.status),typeof t.busy=="boolean"&&(n.busy=t.busy),typeof t.awaitingInput=="boolean"&&(n.awaitingInput=t.awaitingInput),typeof t.attachedClients=="number"&&(n.attachedClients=t.attachedClients),typeof t.resurrected=="boolean"&&(n.resurrected=t.resurrected),typeof t.importedFromMachine=="string"&&(n.importedFromMachine=t.importedFromMachine),typeof t.importedFromUpstreamSessionId=="string"&&(n.importedFromUpstreamSessionId=t.importedFromUpstreamSessionId),typeof t.parentSessionId=="string"&&(n.parentSessionId=t.parentSessionId),typeof t.forkedFromSessionId=="string"&&(n.forkedFromSessionId=t.forkedFromSessionId),typeof t.forkedFromMessageId=="string"&&(n.forkedFromMessageId=t.forkedFromMessageId),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let r=t.originatingClient;n.originatingClient={name:r.name,...typeof r.version=="string"?{version:r.version}:{}}}if(t.agentCapabilities!==void 0&&(n.agentCapabilities=t.agentCapabilities),t.env!==void 0){let r=ru(t.env);r!==void 0&&(n.env=r)}return n}function We(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[ve],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?s:{...t,_meta:{...n,[ve]:{...o,recordedAt:e}}}}function Tt(s,e){return{...s??{},[ve]:e}}import{z as T}from"zod";var $o=T.object({sessionId:T.string(),prompt:T.array(T.unknown()),_meta:T.record(T.unknown()).optional()}),pn=T.object({sessionId:T.string()}),Fo=T.object({clientId:T.string(),name:T.string().optional(),version:T.string().optional()}),Jm=T.object({sessionId:T.string(),messageId:T.string(),originator:Fo,prompt:T.array(T.unknown()),position:T.number().int().nonnegative(),queueDepth:T.number().int().positive(),enqueuedAt:T.number()}),Vm=T.object({sessionId:T.string(),messageId:T.string(),prompt:T.array(T.unknown())}),Qm=T.object({sessionId:T.string(),messageId:T.string(),reason:T.enum(["started","cancelled","abandoned"])}),No=T.object({sessionId:T.string(),messageId:T.string()}),Km=T.object({cancelled:T.boolean(),reason:T.enum(["ok","not_found","already_running"])}),Oo=T.object({sessionId:T.string(),messageId:T.string(),prompt:T.array(T.unknown())}),Gm=T.object({updated:T.boolean(),reason:T.enum(["ok","not_found","already_running"])}),Ho=T.object({sessionId:T.string(),targetMessageId:T.string(),prompt:T.array(T.unknown()),replaceQueue:T.boolean().optional(),onTargetCompleted:T.enum(["reject","send_anyway"]).optional()}),Ym=T.object({amended:T.boolean(),reason:T.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:T.string().optional()}),Xm=T.object({sessionId:T.string(),cancelledMessageId:T.string(),newMessageId:T.string(),prompt:T.array(T.unknown()),originator:Fo,amendedAt:T.number()});import{z as qe}from"zod";var th=qe.object({agentId:qe.string(),version:qe.string(),source:qe.enum(["binary","npm"]),phase:qe.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:qe.number().optional(),totalBytes:qe.number().optional(),packageSpec:qe.string().optional()}),jo="hydra-acp/agents/install_progress",it={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function Do(s,e){let t="",n=[],r=[],o=!1,i=a=>{if(!o){o=!0;for(let d of r)d(a)}};return s.setEncoding("utf8"),s.on("data",a=>{t+=a;let d=t.indexOf(`
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 l of n)l(c)}catch(c){for(let l of n)l({jsonrpc:"2.0",id:null,error:{code:C.ParseError,message:`Failed to parse ndjson line: ${c.message}`}})}d=t.indexOf(`
13
+ `)}}),s.on("end",()=>i()),s.on("error",a=>i(a)),e.on("error",a=>i(a)),{async send(a){if(o)throw new Error("stream is closed");let d=JSON.stringify(a)+`
14
+ `;await new Promise((u,c)=>{e.write(d,l=>{if(l){c(l);return}u()})})},onMessage(a){n.push(a)},onClose(a){r.push(a)},async close(){e.end(),i()}}}import{nanoid as ou}from"nanoid";var $s=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},at=class s{constructor(e){this.stream=e;this.stream.onMessage(t=>this.handleIncoming(t)),this.stream.onClose(t=>this.handleClose(t))}stream;requestHandlers=new Map;defaultRequestHandler;notificationHandlers=new Map;bufferedNotifications=new Map;static MAX_BUFFERED_PER_METHOD=64;static MAX_BUFFERED_METHODS=256;pending=new Map;closed=!1;closeHandlers=[];orphanErrorHandlers=[];onRequest(e,t){this.requestHandlers.set(e,t)}setDefaultHandler(e){this.defaultRequestHandler=e}onNotification(e,t){this.notificationHandlers.set(e,t);let n=this.bufferedNotifications.get(e);if(n){this.bufferedNotifications.delete(e);for(let r of n)try{t(r.params,r.method)}catch{}}}drainBuffered(e){let n=this.bufferedNotifications.get(e)?.length??0;return this.bufferedNotifications.delete(e),n}onClose(e){this.closeHandlers.push(e)}isClosed(){return this.closed}onOrphanError(e){this.orphanErrorHandlers.push(e)}async request(e,t){return this.requestWithId(e,t).response}requestWithId(e,t){if(this.closed)throw new $s;let n=ou(),r={jsonrpc:"2.0",id:n,method:e,params:t},o=new Promise((i,a)=>{this.pending.set(n,{resolve:d=>i(d),reject:a}),this.stream.send(r).catch(d=>{this.pending.delete(n),a(d)})});return{id:n,response:o}}notify(e,t){if(this.closed)return Promise.resolve();let n={jsonrpc:"2.0",method:e,params:t};return this.stream.send(n)}async close(){this.closed||await this.stream.close()}fail(e){this.handleClose(e)}handleIncoming(e){"method"in e?"id"in e&&e.id!==void 0?this.handleRequest(e).catch(()=>{}):this.handleNotification(e):"id"in e?this.handleResponse(e):"error"in e&&this.handleResponse(e)}async handleRequest(e){let t=this.requestHandlers.get(e.method)??this.defaultRequestHandler;if(!t){await this.sendError(e.id,{code:C.MethodNotFound,message:`Method not found: ${e.method}`}).catch(()=>{});return}try{let n=await t(e.params,e.method),r={jsonrpc:"2.0",id:e.id,result:n};await this.stream.send(r).catch(()=>{})}catch(n){let r=n;await this.sendError(e.id,{code:r.code??C.InternalError,message:r.message,data:r.data}).catch(()=>{})}}handleNotification(e){let t=this.notificationHandlers.get(e.method);if(t){t(e.params,e.method);return}let n=this.bufferedNotifications.get(e.method);if(!n){if(this.bufferedNotifications.size>=s.MAX_BUFFERED_METHODS){let r=this.bufferedNotifications.keys().next().value;r!==void 0&&this.bufferedNotifications.delete(r)}n=[],this.bufferedNotifications.set(e.method,n)}n.push(e),n.length>s.MAX_BUFFERED_PER_METHOD&&n.shift()}handleResponse(e){let t=e.id===null?void 0:this.pending.get(e.id);if(!t){if(e.error)for(let n of this.orphanErrorHandlers)try{n({code:e.error.code,message:e.error.message,data:e.error.data})}catch{}return}if(this.pending.delete(e.id),e.error){let n=new Error(e.error.message);n.code=e.error.code,n.data=e.error.data,t.reject(n)}else t.resolve(e.result)}async sendError(e,t){let n={jsonrpc:"2.0",id:e,error:t};await this.stream.send(n)}handleClose(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e??new Error("connection closed"));this.pending.clear();for(let t of this.closeHandlers)t(e)}}};K();var au=4096,ze=class s{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??au,this.killEscalationMs=e.killEscalationMs??du,this.logger=e.logger,this.fileLog=cu(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 n=Do(t.stdout,t.stdin);this.connection=new at(n),t.stderr?.setEncoding("utf8"),t.stderr?.on("data",r=>{if(this.stderrTail=(this.stderrTail+r).slice(-this.stderrTailBytes),this.writeLog(r),this.logger)for(let o of r.split(/\r?\n/))o.length>0&&this.logger.info(`[${e.agentId}] ${o}`);else process.stderr.write(`[${e.agentId}] ${r}`)}),t.on("error",r=>{let o=this.formatFailure(r.message);this.writeLog(`--- spawn error: ${r.message} time=${new Date().toISOString()} ---
16
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
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=Jd(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()} ---
18
+ stderr: ${t}`:e}stderrTailText(){return this.stderrTail.trim()}static spawn(e){let t={...an(),...e.plan.env,...e.extraEnv??{}},n=iu(e.plan.command,e.plan.args,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],detached:!0});return n.unref(),new s(e,n)}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)})}},Vd=2e3;function Qd(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 ht(){return Qr.hostname()}import*as Et from"path";import{customAlphabet as Su}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 Gd(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=Gd(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 Kd=64*1024*1024,Yd=1*1024*1024,Ye=64*1024,Xd=6e4,Zd=100,ec=1e3,tc=64*1024,nc=256*1024,no=20;function sc(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??Kd,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Yd,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,Xd));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(sc(e.pattern),d),c=e.invert??!1,f=Math.max(1,Math.min(e.maxMatches??Zd,ec)),p=Math.max(1,Math.min(e.maxBytes??tc,nc)),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."}],Dm=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 ac){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?oc(r,o.outIndex,rc(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)?ic(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=dc(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 rc(n){if(!n||typeof n!="object")return"";let e=n;return typeof e.text=="string"?e.text:""}function oc(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 ic(n,e){let t=n.params??{},s=t.update??{};return{...n,params:{...t,update:{...s,content:e}}}}var ac=["rawInput","locations"];function oo(n){return n==null||typeof n!="object"?!1:Array.isArray(n)?n.length>0:Object.keys(n).length>0}function dc(n,e,t){let s=n.params??{},r=s.update??{};return{...n,params:{...s,update:{...r,[e]:t}}}}var ao=`[older history truncated]
21
- `,cc=["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(),pc(s.join(`
22
- `),t)}function ds(n){let e=uc(n),t=lc(n.rawInput);return t.length===0?`Tool: ${e}`:`Tool: ${e}(${t.join(", ")})`}function uc(n){return typeof n.name=="string"&&n.name.length>0?n.name:typeof n.title=="string"&&n.title.length>0?n.title:"(unnamed)"}function lc(n){if(!n||typeof n!="object"||Array.isArray(n))return[];let e=n,t=[];for(let s of cc){let r=e[s];typeof r=="string"&&r.length>0&&t.push(`${s}=${fc(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 fc(n,e){return n.length<=e?n:n.slice(0,e-1)+"\u2026"}function pc(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=yt("Open threads",t.open_threads);i.length>0&&e.push(i);let a=yt("Decisions",t.decisions);a.length>0&&e.push(a);let d=yt("File edit intentions",t.file_edit_intentions);d.length>0&&e.push(d);let u=yt("Unresolved errors",t.unresolved_errors);u.length>0&&e.push(u);let c=yt("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}=mc(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 yt(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 mc(n,e,t,s){if(n.length===0)return{closedText:"",openText:"",keptCount:0};let{closed:r,open:o}=gc(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 gc(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 wt(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(`
20
+ `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(Lo),this.exited||this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} still has not exited ${Lo}ms after SIGKILL; giving up on the reap`)))}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 n=setTimeout(()=>{this.child.off("exit",r),t()},e),r=()=>{clearTimeout(n),t()};this.child.once("exit",r)})}},du=2e3,Lo=5e3;function cu(s){try{let e=A.agentLogFile(s);gn.mkdirSync(Bo.dirname(e),{recursive:!0});let t=gn.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}import*as Ge from"fs/promises";import*as ma from"os";import*as Uo from"os";function _t(){return Uo.hostname()}import*as Vt from"path";import{customAlphabet as df}from"nanoid";var xe="session/set_model",Ns="session/set_config_option",zo="model";function Fs(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.availableModels)}function Jo(s){return Array.isArray(s)&&s.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===zo)}function dt(s){if(!s)return;if(Fs(s)||Fs(s.models))return xe;let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,n]of Object.entries(e))if(t!=="hydra-acp"&&Fs(n))return xe}if(Jo(s.configOptions))return Ns}function Vo(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.sessionUpdate;if(e==="current_model_update")return xe;if(e==="config_option_update"&&Jo(s.configOptions))return Ns}function Wo(s){return typeof s=="object"&&s!==null&&s.code===C.MethodNotFound}function qo(s,e,t,n){let r={...n??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,s===xe?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:zo,value:t}}function uu(s){return s===xe?Ns:xe}async function Je(s){let{request:e,sessionId:t,modelId:n,extraParams:r,logger:o}=s,i=s.verb??xe;try{let a=await e(i,qo(i,t,n,r));return{verb:i,result:a}}catch(a){if(!Wo(a))throw a;let d=uu(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(n)}`);try{let u=await e(d,qo(d,t,n,r));return{verb:d,result:u}}catch(u){throw Wo(u)?a:u}}}async function ct(s){let{agent:e,upstreamSessionId:t,persistedMode:n,agentReportedMode:r,advertisedModes:o,logger:i}=s;if(!n)return r;if(n===r)return n;if(o&&o.length>0&&!o.some(a=>a.id===n)){let a=o.map(d=>d.id).join(", ");return i?.warn(`resurrect: persisted currentMode=${JSON.stringify(n)} not in agent's availableModes ([${a}]); skipping session/set_mode, session will use ${JSON.stringify(r)}`),r}try{return i?.info(`resurrect: pushing persisted modeId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`),await e.connection.request("session/set_mode",{sessionId:t,modeId:n}),i?.info(`resurrect: session/set_mode accepted, effectiveMode=${JSON.stringify(n)}`),n}catch(a){return i?.warn(`resurrect: session/set_mode rejected by agent for modeId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),r}}async function ut(s){let{agent:e,upstreamSessionId:t,persistedModel:n,agentReportedModel:r,modelVerb:o,logger:i}=s;if(!n)return r;if(n===r)return n;try{i?.info(`resurrect: pushing persisted modelId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`);let{verb:a}=await Je({request:(d,u)=>e.connection.request(d,u),sessionId:t,modelId:n,...o?{verb:o}:{},logger:i});return i?.info(`resurrect: ${a} accepted, effectiveModel=${JSON.stringify(n)}`),n}catch(a){return i?.warn(`resurrect: session/set_model rejected by agent for modelId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),r}}import{customAlphabet as hi}from"nanoid";var Qo="edit",mn=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 Ko(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(t===null||typeof t!="object")continue;let n=t.path;typeof n=="string"&&n.length>0&&e.push(n)}return e}import*as Yo from"fs/promises";var lu=64*1024*1024,fu=1*1024*1024,lt=64*1024,pu=6e4,gu=100,mu=1e3,hu=64*1024,yu=256*1024,Go=20;function wu(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var hn=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??lu,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(fu,this.maxCapacityBytes),this.storage=Buffer.alloc(this.currentCapacityBytes),this.filePath=e.filePath,this.fileCapBytes=e.fileCapBytes??Number.POSITIVE_INFINITY,this.onFileCapReached=e.onFileCapReached,this.logWriteError=e.logWriteError}get capacity(){return this.maxCapacityBytes}get allocatedBytes(){return this.currentCapacityBytes}get writeCursorPos(){return this.writeCursor}get oldestAvailable(){return Math.max(0,this.writeCursor-this.currentCapacityBytes)}get isClosed(){return this.closed}append(e){this.closed||e.length===0||(this.writeRing(e),this.writeCursor+=e.length,this.filePath!==void 0&&this.scheduleFileWrite(e),this.wakeWaiters("data"))}close(){this.closed||(this.closed=!0,this.wakeWaiters("eof"))}read(e,t){let n=Math.max(0,Math.min(t,lt));if(n===0){let l={bytes:Buffer.alloc(0),nextCursor:e};return this.closed&&e>=this.writeCursor&&(l.eof=!0),l}let r=e,o=0,i=this.oldestAvailable;r<i&&(o=i-r,r=i);let a=this.writeCursor-r;if(a<=0){let l={bytes:Buffer.alloc(0),nextCursor:r};return o>0&&(l.gap=o),this.closed&&(l.eof=!0),l}let d=Math.min(a,n),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,lt)),n=this.oldestAvailable,r=this.writeCursor-t,o=Math.max(n,r),i=r<n;return{bytes:this.sliceFromRing(o,this.writeCursor-o),startCursor:o,endCursor:this.writeCursor,truncated:i}}head(e){let t=Math.max(0,Math.min(e,lt)),n=this.oldestAvailable,r=n>0,o=n,i=Math.min(this.writeCursor,o+t);return{bytes:this.sliceFromRing(o,i-o),startCursor:o,endCursor:i,truncated:r}}waitForData(e,t){if(e<this.writeCursor)return Promise.resolve("data");if(this.closed)return Promise.resolve("eof");let n=Math.max(0,Math.min(t,pu));return n===0?Promise.resolve("timeout"):new Promise(r=>{let o={resolve:i=>{o.timer!==void 0&&(clearTimeout(o.timer),o.timer=void 0),r(i)},timer:setTimeout(()=>{let i=this.waiters.indexOf(o);i>=0&&this.waiters.splice(i,1),o.timer=void 0,r("timeout")},n)};this.waiters.push(o)})}grep(e){let t=this.oldestAvailable,n=e.cursor,r=n??t,o=0;n!==void 0&&n<t&&(o=t-n,r=t),r>this.writeCursor&&(r=this.writeCursor);let i=this.sliceFromRing(r,this.writeCursor-r),a=e.regex??!0,d=e.caseInsensitive===!0?"i":"",u=a?new RegExp(e.pattern,d):new RegExp(wu(e.pattern),d),c=e.invert??!1,l=Math.max(1,Math.min(e.maxMatches??gu,mu)),p=Math.max(1,Math.min(e.maxBytes??hu,yu)),f=Math.max(0,Math.min(e.contextBefore??0,Go)),m=Math.max(0,Math.min(e.contextAfter??0,Go)),g=[],h=[],y=[],k=0,w=!1,v=0,b=0,S=(P,H)=>{for(let Q of y)Q.remaining>0&&(Q.match.after===void 0&&(Q.match.after=[]),Q.match.after.push({cursor:P,line:H}),Q.remaining--,k+=H.length);for(;y.length>0&&y[0].remaining===0;)y.shift();if(u.test(H)!==c&&g.length<l){let Q={cursor:P,line:H};if(f>0&&h.length>0){Q.before=h.slice();for(let le of Q.before)k+=le.line.length}k+=H.length,g.push(Q),m>0&&y.push({match:Q,remaining:m})}if(f>0)for(h.push({cursor:P,line:H});h.length>f;)h.shift();let N=g.length>=l&&y.length===0,W=k>=p;return N||W};for(let P=0;P<i.length;P++){if(i[P]!==10)continue;let H=i.subarray(v,P).toString("utf8"),_=r+v;if(v=P+1,b=v,S(_,H)){w=!0;break}}if(!w&&v<i.length&&this.closed){let P=i.subarray(v).toString("utf8"),H=r+v;S(H,P)&&(w=!0),b=i.length}let x=Math.min(r+b,this.writeCursor),R={matches:g,truncated:w,nextCursor:x,scannedBytes:b};return o>0&&(R.gap=o),this.closed&&x>=this.writeCursor&&(R.eof=!0),R}wakeWaiters(e){if(this.waiters.length===0)return;let t=this.waiters;this.waiters=[];for(let n of t)n.resolve(e)}growIfNeeded(e){if(this.currentCapacityBytes>=this.maxCapacityBytes)return;let t=this.writeCursor+e;if(t<=this.currentCapacityBytes)return;let n=this.currentCapacityBytes;for(;n<t&&n<this.maxCapacityBytes;)n=Math.min(this.maxCapacityBytes,n*2);if(n===this.currentCapacityBytes)return;let r=Buffer.alloc(n);this.storage.copy(r,0,0,this.writeCursor),this.storage=r,this.currentCapacityBytes=n}writeRing(e){let t=e.length;if(this.growIfNeeded(t),t>=this.currentCapacityBytes){let o=t-this.currentCapacityBytes;e.copy(this.storage,0,o,t);return}let n=this.writeCursor%this.currentCapacityBytes,r=this.currentCapacityBytes-n;t<=r?e.copy(this.storage,n,0,t):(e.copy(this.storage,n,0,r),e.copy(this.storage,0,r,t))}sliceFromRing(e,t){if(t<=0)return Buffer.alloc(0);let n=Buffer.alloc(t),r=e%this.currentCapacityBytes,o=Math.min(t,this.currentCapacityBytes-r);return this.storage.copy(n,0,r,r+o),o<t&&this.storage.copy(n,o,0,t-o),n}scheduleFileWrite(e){let t=this.filePath;if(t===void 0||this.fileCapReached)return;let n=this.fileCapBytes-this.fileBytesWritten;if(n<=0){this.fileCapReached=!0,this.onFileCapReached?.();return}let r=e.length<=n?e:e.subarray(0,n);this.fileBytesWritten+=r.length;let o=this.fileBytesWritten>=this.fileCapBytes;this.fileWriteChain=this.fileWriteChain.then(()=>Yo.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var ft=[{verb:"title",name:"hydra title",description:"Regenerate the session title + synopsis via the agent (or set title manually with an arg)"},{verb:"agent",name:"hydra agent",argsHint:"<agent | status>",description:"Schedule a swap to a different agent (synthesizes a brief in the target's idiom, rotates on idle); `status` reports any pending swap"},{verb:"workspace",name:"hydra workspace",argsHint:"<start [name] [--clean] | sync | merge | stop | detach | clean [--deep] | discard | status>",description:"Move this session into an isolated workspace so its edits cannot collide with other work, then land or discard them. `start` copies your uncommitted changes in and leaves the real tree untouched; `start --clean` leaves them behind so the workspace begins at the last commit. `stop` merges and returns; `discard` throws the work away and returns; `detach` returns without merging, leaving the workspace and its branch intact; `merge` lands the work without leaving; `clean` throws away everything done in the workspace and stays there, putting it back exactly as `start --clean` would have made it (add `--deep` to rebuild dependencies and carried config files too, rather than keeping them); `sync` pulls the source's committed history INTO the workspace, so you can test against what you will land onto, and because landing is fast-forward-only, syncing is also how you recover once the source has moved on. `start <name>` naming a workspace another live session is already in JOINS it instead of making a second one, so two sessions can share a checkout deliberately: edits interleave, `stop` behaves as `detach` while anyone else is still there, and the work lands when the last of them leaves."},{verb:"kill",name:"hydra kill",description:"Close this session (kills the agent; record is kept so it can be resumed later)"},{verb:"restart",name:"hydra restart",description:"Restart the agent with a fresh session/new while preserving conversation history (useful when the proxy has changed available models)"},{verb:"compact",name:"hydra compact",description:"Compact this session's history. Use '/hydra compact status' to inspect current compaction state without triggering."},{verb:"uncompact",name:"hydra uncompact",description:"Roll back the most recent compaction swap (only available immediately after a swap, before any new turns)"},{verb:"fork",name:"hydra fork",argsHint:"[verbatim]",description:"Fork this conversation into a new session (default: synthesis mode with a synopsis brief; pass 'verbatim' to slice at the last completed turn instead)"},{verb:"config",name:"hydra config",argsHint:"[<id> [<value>]]",description:"List or set an agent-advertised configOption (model, mode, effort, etc.). With no args, lists all options; with <id>, shows its choices; with <id> <value>, applies it."}],Eh=new Map(ft.map(s=>[s.verb,s]));function Xo(s){let e=s.lastIndexOf("/");return(e===-1?s:s.slice(e+1)).toLowerCase()}function pt(s,e){return Os(s,e.map(t=>t.modelId))}function Os(s,e){if(e.length===0)return{kind:"none",requested:s};if(e.includes(s))return{kind:"exact",modelId:s};let t=Xo(s),n=e.filter(o=>Xo(o)===t);if(n.length===1)return{kind:"resolved",modelId:n[0],requested:s};if(n.length>1)return{kind:"ambiguous",requested:s,candidates:n};let r=s.toLowerCase();if(r.length>0){let o=e.filter(i=>i.toLowerCase().includes(r));if(o.length===1)return{kind:"resolved",modelId:o[0],requested:s};if(o.length>1)return{kind:"ambiguous",requested:s,candidates:o}}return{kind:"unknown",requested:s}}function ei(s){if(s.length===0)return s;let e=new Map,t=new Map,n=new Map;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let u=Hs(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 l of Su){if(!Zo(u[l]))continue;let p=n.get(c);p===void 0?n.set(c,new Map([[l,u[l]]])):p.set(l,u[l])}if(Array.isArray(u.content)&&u.content.length>0){let l=t.get(c);l?l.push(...u.content):t.set(c,[...u.content])}}}let r=[],o=null,i=null;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let u=Hs(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?vu(r,o.outIndex,ku(u.content)):(r.push(d),o={outIndex:r.length-1,kind:c});continue}if(o=null,c==="tool_call_update"){let l=typeof u.toolCallId=="string"?u.toolCallId:void 0;if(l!==void 0&&e.get(l)!==a)continue;let p=l!==void 0&&t.has(l)?bu(d,t.get(l)??[]):d,f=l===void 0?void 0:n.get(l);if(f!==void 0)for(let[m,g]of f)Zo(Hs(p)?.[m])||(p=Iu(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 Hs(s){if(s.method!=="session/update")return;let t=s.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function ku(s){if(!s||typeof s!="object")return"";let e=s;return typeof e.text=="string"?e.text:""}function vu(s,e,t){if(t.length===0)return;let n=s[e];if(n===void 0)return;let r=n.params??{},o=r.update??{},i=o.content??{},a=typeof i.text=="string"?i.text:"";s[e]={...n,params:{...r,update:{...o,content:{...i,text:a+t}}}}}function bu(s,e){let t=s.params??{},n=t.update??{};return{...s,params:{...t,update:{...n,content:e}}}}var Su=["rawInput","locations"];function Zo(s){return s==null||typeof s!="object"?!1:Array.isArray(s)?s.length>0:Object.keys(s).length>0}function Iu(s,e,t){let n=s.params??{},r=n.update??{};return{...s,params:{...n,update:{...r,[e]:t}}}}var ti=`[older history truncated]
21
+ `,ni=["file_path","filePath","path","command","pattern","query"];function gt(s,e={}){let t=e.maxChars??4e5,n=js(s),r=[],o="",i=e.toolOutput?.maxTotal??0,a=()=>{o.length!==0&&(r.push(`Assistant: ${o}`),o="")};for(let d of s){if(d.method!=="session/update")continue;let c=d.params?.update;if(!c||typeof c.sessionUpdate!="string")continue;let l=c.sessionUpdate;if(l==="prompt_received"){a();let p=Us(c.prompt).trim();p.length>0&&r.push(`User: ${p}`)}else if(l==="agent_message_chunk"){let p=Ws(c.content);p.length>0&&(o+=p)}else if(l==="tool_call"){if(a(),r.push(Bs(c,n)),e.toolOutput!==void 0){let p=Ls(c),f=p!==void 0?n.get(p)?.output:void 0;if(f!==void 0&&i>0){let m=Math.min(e.toolOutput.maxPerCall,i),g=f.length<=m?f:`${f.slice(0,m)}\u2026[${f.length-m} more chars]`;r.push(`Output: ${g}`),i-=Math.min(g.length,m)}}}else l==="turn_complete"&&a()}return a(),Mu(r.join(`
22
+ `),t)}function js(s){let e=new Map;for(let t of s){if(t.method!=="session/update")continue;let r=t.params?.update;if(!r)continue;let o=r.sessionUpdate;if(o!=="tool_call"&&o!=="tool_call_update")continue;let i=Ls(r);if(i===void 0)continue;let a=e.get(i);if(a===void 0&&(a={name:"(unnamed)",rawInput:{}},e.set(i,a)),a.name==="(unnamed)"){let u=Cu(r,o);u!==void 0&&(a.name=u)}if(a.kind===void 0&&typeof r.kind=="string"&&r.kind.length>0&&(a.kind=r.kind),a.output===void 0){let u=yn(r);u!==void 0&&(a.output=u)}let d=r.rawInput;d&&typeof d=="object"&&!Array.isArray(d)&&Object.assign(a.rawInput,d)}for(let t of e.values())t.name=Ds(t);return e}function Ds(s){return Au(s)?s.kind??"(unnamed)":s.name}function Au(s){for(let e of ni){let t=s.rawInput[e];if(!(typeof t!="string"||t.length===0)&&(t===s.name||s.name.length>=12&&t.startsWith(s.name)))return!0}return!1}function Cu(s,e){let t=$t(s);if(t!==void 0)return t;if(typeof s.name=="string"&&s.name.length>0)return s.name;if(e==="tool_call"&&typeof s.title=="string"&&s.title.length>0)return s.title}function Ls(s){let e=s.toolCallId;if(typeof e=="string"&&e.length>0)return e}function yn(s){let e=xu(s);if(e!==void 0)return e;let t=s.rawOutput;if(typeof t=="string")return t.length>0?t:void 0;if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t.output;if(typeof n=="string")return n.length>0?n:void 0}}function xu(s){let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.toolResponse;if(typeof n=="string")return n.length>0?n:void 0;if(!n||typeof n!="object")return;let{stdout:r,stderr:o}=n,i=[];if(typeof r=="string"&&r.length>0&&i.push(r),typeof o=="string"&&o.length>0&&i.push(`[stderr] ${o}`),i.length!==0)return i.join(`
23
+ `)}function $t(s){let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.toolName;if(typeof n=="string"&&n.length>0)return n}function Bs(s,e){let t=Ls(s),n=t!==void 0?e?.get(t):void 0,r=n?.name??Ru(s),o=Eu(n?.rawInput??s.rawInput);return o.length===0?`Tool: ${r}`:`Tool: ${r}(${o.join(", ")})`}function Ru(s){let e=$t(s);return e!==void 0?e:typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function Eu(s){if(!s||typeof s!="object"||Array.isArray(s))return[];let e=s,t=[];for(let n of ni){let r=e[n];typeof r=="string"&&r.length>0&&t.push(`${n}=${Pu(r,600)}`)}return t}function Us(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>{if(e&&typeof e=="object"){let t=e.text;if(typeof t=="string")return t}return""}).join(""):""}function Ws(s){if(!s||typeof s!="object")return"";let e=s.text;return typeof e=="string"?e:""}function Pu(s,e){return s.length<=e?s:s.slice(0,e-1)+"\u2026"}function Mu(s,e){if(s.length<=e)return s;let t=s.split(`
24
+ `);for(;t.length>0;){let n=ti+t.join(`
25
+ `);if(n.length<=e)return n;t.shift()}return ti}var si="(untitled)";function qs(s){let e=[],t=s.synopsis;if(t!==void 0){e.push("--- begin prior session compaction ---"),e.push(`[Title] ${s.title??si}`),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 a=Ft("Open threads",t.open_threads);a.length>0&&e.push(a);let d=Ft("Decisions",t.decisions);d.length>0&&e.push(d);let u=Ft("File edit intentions",t.file_edit_intentions);u.length>0&&e.push(u);let c=Ft("Unresolved errors",t.unresolved_errors);c.length>0&&e.push(c);let l=Ft("Tool state",t.tool_state);l.length>0&&e.push(l);let p=ri(t.files_touched);p.length>0&&e.push(`[Files previously touched] ${p}`);let f=ri(t.tools_used);f.length>0&&e.push(`[Tools previously used] ${f}`),e.push("--- end prior session compaction ---")}else e.push(`[Title] ${s.title??si}`);let{closedText:n,openText:r,keptCount:o}=Tu(s.tail,s.tailK,s.watermark??0,s.tailFloor??0);e.push("--- begin recent turns (verbatim, last "+o+") ---"),n.length>0&&e.push(n),e.push("--- end recent turns ---"),r.length>0&&(e.push("--- begin current in-flight turn (no completion yet) ---"),e.push(r),e.push("--- end current in-flight turn ---"));let i=s.recallArmed??!0;return e.push(""),t!==void 0&&i?e.push("(Hydra has compacted earlier conversation. Do NOT call any tools yet. Do NOT read any files, run any commands, or invoke hydra-recall. Reply with the single word 'OK' and wait for the next user message \u2014 at that point you can use the hydra-recall tools to look up specifics on demand if needed.)"):t!==void 0?e.push("(Hydra has compacted earlier conversation; the turns above are what survives. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):i?e.push("(This is a side conversation forked from another session. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):e.push("(This is a side conversation forked from another session. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"),e.join(`
26
+ `)}function Ft(s,e){if(!e||!Array.isArray(e))return"";let t=e.filter(r=>typeof r=="string"&&r.trim().length>0);if(t.length===0)return"";let n=t.map(r=>"- "+r.trim());return`[${s}] ${n.join(`
27
+ `)}`}function ri(s){if(!s||!Array.isArray(s))return"";let e=s.filter(t=>typeof t=="string"&&t.trim().length>0);return e.length===0?"":e.map(t=>t.trim()).join(", ")}function Tu(s,e,t,n){if(s.length===0)return{closedText:"",openText:"",keptCount:0};let{closed:r,open:o}=_u(s),i=0,a=[];if(e>0&&r.length>0){let c=r.filter(f=>f.startEntryIndex>=t).length,l=Math.max(c,n),p=Math.min(l,e,r.length);i=p,a=p>0?r.slice(-p):[]}let d=a.length>0?oi(a):"",u=o?oi([o]):"";return{closedText:d,openText:u,keptCount:i}}function oi(s){let e=[];for(let t of s){t.user.length>0&&e.push("User: "+t.user),t.agent.length>0&&e.push("Assistant: "+t.agent);for(let n of t.tools)e.push(n)}return e.join(`
28
+ `)}function _u(s){let e=[],t=null,n=js(s);for(let o=0;o<s.length;o++){let i=s[o];if(i.method!=="session/update")continue;let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let u=d.sessionUpdate;if(u==="prompt_received")t!==null&&t.user.length>0&&e.push(t),t={user:Us(d.prompt).trim(),agent:"",tools:[],startEntryIndex:o};else if(u==="agent_message_chunk"&&t!==null){let c=Ws(d.content);c.length>0&&(t.agent+=c)}else u==="tool_call"&&t!==null?t.tools.push(Bs(d,n)):u==="turn_complete"&&t!==null&&(e.push(t),t=null)}let r=t!==null&&t.user.length>0?t:null;return{closed:e,open:r}}function $u(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function zs(s,e,t){if(e.length===0||e===t)return{text:s,rewritten:[]};let n=e.endsWith("/")?e.slice(0,-1):e,r=t.endsWith("/")?t.slice(0,-1):t,o=[],i=new RegExp(`${$u(n)}/(?![/\\s])`,"g");return{text:s.replace(i,(d,u)=>{let c=s.slice(u+d.length),l=c.search(/[\s"'`,;:)\]}]|$/);return o.push(`${n}/${c.slice(0,l<0?void 0:l)}`),`${r}/`}),rewritten:o}}function Js(s,e){if(e.length===0)return!1;let t=e.endsWith("/")?e.slice(0,-1):e;return s.includes(t)}function ii(s){let e=[];return e.push("[workspace] You have LEFT the isolated workspace."),e.push(`- Your working directory is now ${s.sourceCwd}`),e.push(s.removed?`- The workspace at ${s.formerWorkspacePath} has been removed. Paths under it from earlier in this conversation no longer exist.`:`- The workspace at ${s.formerWorkspacePath} still exists but is NO LONGER YOURS. Editing anything under it is wasted: that work will not reach ${s.sourceCwd}.`),e.push("- Earlier turns refer to files by their workspace paths. Treat those as referring to the same files under your current working directory, and prefer repo-relative paths from here on."),e.join(`
29
+ `)}function ai(s){let e=[];e.push(s.reassert===!0?"[workspace] Reminder: you are NOT working in the directory that path names.":"[workspace] Before anything else, note where you are working:"),e.push(`- Your working directory is ${s.workspacePath}`),e.push(`- It is an isolated copy of ${s.sourceCwd}`),e.push(`- Any absolute path under ${s.sourceCwd} refers to the matching file under your working directory. Do not read or write ${s.sourceCwd} directly.`),e.push("- Prefer repo-relative paths (`src/foo.ts`). They are identical in both trees, so they cannot be misread.");for(let t of s.notes)e.push(`- ${t}`);return e.join(`
30
+ `)}function di(s,e,t){if(s.length===0||!s.startsWith("/"))return!1;let n=e.endsWith("/")?e:`${e}/`,r=t.endsWith("/")?t:`${t}/`;return s.startsWith(r)?!1:s.startsWith(n)}K();import*as Re from"fs/promises";async function Nt(s,e){let t=A.queueFile(s);if(e.length===0){await Re.unlink(t).catch(()=>{});return}await Re.mkdir(A.sessionDir(s),{recursive:!0});let n=e.map(r=>JSON.stringify(r)).join(`
28
31
  `)+`
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),hc=20,yc=20,wc=5,we="hydra_session_";function Te(){return`m_${bo()}`}function vo(n){return n.startsWith(we)?n.slice(we.length):n}var bc=1e3,Xt=300*1e3,vc=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??bc,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){xc(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=Mc(i);if(d!==null){this.setAgentAdvertisedCommands(d);return}let u=Cc(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
- Switched to ${r}.
32
+ `;await Re.writeFile(t,n,"utf8")}async function ci(s){let e=A.queueFile(s),t;try{t=await Re.readFile(e,"utf8")}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t.split(`
33
+ `))if(r.trim())try{let o=JSON.parse(r);o&&typeof o.messageId=="string"&&Array.isArray(o.prompt)&&typeof o.enqueuedAt=="number"&&n.push(o)}catch{}return n}async function ui(s){let e=A.queueFile(s);await Re.unlink(e).catch(()=>{})}import*as ki from"fs/promises";var yi="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",wi=hi(yi,16),Vs=hi(yi,16),Fu=20,Nu=20,Ou=5,Pe="hydra_session_";function Ee(){return`m_${wi()}`}function Oe(s){return s.startsWith(Pe)?s.slice(Pe.length):s}var li=["start","merge","sync","stop","detach","discard","clean","status"],Hu=1e3,wn=300*1e3,ju=64,Du=9e4,fi=120,Lu=128,Bu=1800*1e3,Uu=900*1e3,Wu=45e3,Qs=18e4,qu=1e3,yt=class s{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=xe;modelVerbConfirmed=!1;agentArgs;parentSessionId;forkedFromSessionId;forkedFromMessageId;forkSynthesisState;originatingClient;_interactive;get interactive(){return this._interactive}_priority;get priority(){return this._priority}title;_summarizedThroughEntry;get summarizedThroughEntry(){return this._summarizedThroughEntry}set summarizedThroughEntry(e){this._summarizedThroughEntry=e}currentModel;currentMode;compactionState;_currentUsage;updatedAt;createdAt;clients=new Map;historyStore;promptQueue=[];currentEntry;promptInFlight=!1;agentTurnInFlight=!1;swapInFlight=!1;modeChangeInFlight=!1;modelChangeInFlight=!1;queueWriteChain=Promise.resolve();closed=!1;closing=!1;closeInFlight;deleteRecordIntent=!1;closeHandlers=[];titleHandlers=[];scheduleSynopsisHook;scheduleWorkspaceSnapshotHook;scheduleCompactionHook;resolveAgentIdHook;getCompactionStateHook;getPendingAgentSwapHook;_liveCompactionPhase;broadcastHandlers=[];lastCancelAt=0;static CANCEL_ERROR_WINDOW_MS=2e3;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}promptStartedAt;unsolicitedTurn;lastBackgroundTask;toolLabels=new Map;armedTasks=new Map;armedExpiryTimer;lastArmedBroadcast;sawTurnComplete=!1;lastAgentActivityAt=0;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;persistWatermarkHook;uncompactHook;forkHook;mcpServersConfig;forwardedEnv;workspace;workspaceError;workspaceNotes=[];workspaceHook;workspacePreambleSent=!1;formerWorkspace;departureNoteSent=!1;listSessions;logger;transformChain;extensionCommands;extensionCommandsUnsub;pendingClaims=new Map;toolCompletionSeen=new Map;toolCallKind=new mn;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??`${Pe}${wi()}`,this.cwd=e.cwd,this.workspace=e.workspace,this.workspaceError=e.workspaceError,this.workspaceHook=e.workspaceHook,this.agentId=e.agentId,this.agent=e.agent,this.upstreamSessionId=e.upstreamSessionId,this.agentMeta=e.agentMeta,this.agentCapabilities=e.agentCapabilities,this.agentArgs=e.agentArgs,this.parentSessionId=e.parentSessionId,this.forkedFromSessionId=e.forkedFromSessionId,this.forkedFromMessageId=e.forkedFromMessageId,this.forkSynthesisState=e.forkSynthesisState,this.originatingClient=e.originatingClient,this.title=e.title,this.scheduleSynopsisHook=e.scheduleSynopsis,this.scheduleWorkspaceSnapshotHook=e.scheduleWorkspaceSnapshot,this.scheduleCompactionHook=e.scheduleCompaction,this.resolveAgentIdHook=e.resolveAgentId,this.getCompactionStateHook=e.getCompactionState,this.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.persistWatermarkHook=e.persistWatermarkHook,this.uncompactHook=e.uncompactHook,this.forkHook=e.forkHook,this.mcpServersConfig=e.mcpServers,this.forwardedEnv=e.forwardedEnv,this.availableAgentsFn=e.availableAgents,this.listSessions=e.listSessions,this.logger=e.logger,this.transformChain=e.transformChain??[],this.extensionCommands=e.extensionCommands,this.extensionCommands&&(this.extensionCommandsUnsub=this.extensionCommands.onChange(()=>{this.closed||this.broadcastMergedCommands()})),e.firstPromptSeeded&&(this._firstPromptSeeded=!0),this._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??Hu,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){Zu(this.internalPromptCapture,t);return}this.maybeEmitToolEdges(t),this.runResponseChain(t)}),e.connection.onRequest("session/request_permission",async t=>{let n=await this.runAgentRequestChain("session/request_permission",t),r=pi(n.shortCircuit?t:n.envelope);if(n.shortCircuit)return this.notifyChain("permission.replied",{toolCallId:r??null,outcome:n.payload,sourceWasTransformer:!0}),n.payload;let o=await this.handlePermissionRequest(n.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>s.CANCEL_ERROR_WINDOW_MS){this.logger?.warn(`agent ${this.agentId} sent uncorrelated error frame code=${e.code} message=${e.message}`);return}this.lastCancelAt=0,this.logger?.warn(`agent ${this.agentId} rejected session/cancel code=${e.code} message=${e.message}`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,code:e.code,message:e.message})}async runResponseChain(e,t=new Set,n=0,r="session/update"){let o=e,i=r==="session/update"?this.injectCumulativeCost(e):e,a=`response:${r}`;for(let c=n;c<this.transformChain.length;c++){let l=this.transformChain[c];if(t.has(l.name)||!l.intercepts.has(a))continue;let p=`t_${Vs()}`,f;try{f=await l.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 ${l.name} error on ${a}: ${g.message}`);continue}let m=f?.action??"continue";if(m==="stop")return;if(m==="processing"){let g=c,h=i,y=new Set(t),k=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:l.name}),this.runResponseChain(h,new Set([...y,l.name]),g+1,k).then(()=>w()).catch(()=>w()))},wn);typeof v.unref=="function"&&v.unref(),this.pendingClaims.set(p,{resolve:()=>w(),timer:v,transformerName:l.name,method:k,envelope:h,chainIdx:g,originatedBy:y,side:"response"})});return}f?.payload&&typeof f.payload=="object"&&(i=f.payload),t.add(l.name)}if(r!=="session/update")return;this.noteAgentActivity(i);let d=el(i);if(d!==null){this.setAgentAdvertisedCommands(d);return}let u=Xu(i);if(u!==null){this.setAgentAdvertisedModes(u);return}if(this.noteModelVerbHint(Vo(i.update),"session/update"),this.maybeApplyAgentModel(i)){this.recordAndBroadcast("session/update",i);return}if(this.maybeApplyAgentMode(i)){this.recordAndBroadcast("session/update",i);return}if(this.maybeApplyAgentConfigOption(i)){this.recordAndBroadcast("session/update",this.mergeAgentOptionIntoEnvelope(i));return}if(this.maybeApplyAgentUsage(o)){this.recordAndBroadcast("session/update",i);return}this.maybeApplyAgentSessionInfo(i),this.recordAndBroadcast("session/update",i)}onAgentChange(e){this.agentChangeHandlers.push(e)}get attachedCount(){return this.clients.size}connectedClients(e){let t=[];for(let n of this.clients.values()){if(e&&n.clientId===e)continue;let r={clientId:n.clientId};n.clientInfo?.name&&(r.name=n.clientInfo.name),n.clientInfo?.version&&(r.version=n.clientInfo.version),t.push(r)}return t}get turnStartedAt(){return this.promptStartedAt}get inUnsolicitedTurn(){return this.unsolicitedTurn!==void 0}get agentPid(){return this.agent.pid}get awaitingInput(){return this.attentionFlags.size>0}async isQuiescedForSwap(){return!(this.agentTurnInFlight||this.unsolicitedTurn!==void 0||this.internalPromptCapture!==void 0||this.modeChangeInFlight||this.modelChangeInFlight||await this._hasOpenToolCall())}isQuiescedSync(){return!(this.promptInFlight||this.unsolicitedTurn!==void 0||this.modeChangeInFlight||this.modelChangeInFlight)}async swapIntoWorkspace(e){await this.swapUpstream({artifact:e.artifact,...e.title!==void 0?{title:e.title}:{},tailK:8,tailFloor:4,summarizedThroughEntry:e.historyLength,newCwd:e.cwd,reason:e.workspace!==void 0?"workspace-enter":"workspace-leave"}),this.workspace=e.workspace,e.left!==void 0?(this.formerWorkspace={path:e.left.path,sourceCwd:e.cwd,removed:e.left.removed},this.departureNoteSent=!1):this.formerWorkspace=void 0}async swapUpstream(e){if(!await this.isQuiescedForSwap())throw new Error("session is not quiesced for swap \u2014 wait for in-flight work to complete");if(this.swapInFlight)throw new Error("a swap is already in progress for this session");this.swapInFlight=!0;try{await this.doSwapUpstream(e)}finally{this.swapInFlight=!1}}async doSwapUpstream(e){this.notifyChain("agent.swap",{phase:"pre",previousUpstreamSessionId:this.upstreamSessionId,agentId:this.agentId});let t=this.agentId,n=e.newAgentId??this.agentId,r=n!==this.agentId,o=e.newCwd??this.cwd,i=this.agentArgs,a=this.forwardedEnv,d=this.currentModel,u=this.currentMode,c=this.spawnReplacementAgent;if(!c)throw new Error("agent spawning not configured for this session");let l=this.mintMcpServersForSwap?await this.mintMcpServersForSwap(this):this.mcpServersConfig??[],p=await c({agentId:n,cwd:o,agentArgs:i,...a?{forwardedEnv:a}:{},mcpServers:l});this.accumulateAndResetCost(),this.cwd=o,this.wireAgent(p.agent),r||(await ut({agent:p.agent,upstreamSessionId:p.upstreamSessionId,persistedModel:d,agentReportedModel:p.initialModel,logger:this.logger}),await ct({agent:p.agent,upstreamSessionId:p.upstreamSessionId,persistedMode:u,agentReportedMode:p.initialMode,logger:this.logger})),p.agent.connection.drainBuffered("session/update");let f=[];if(this.historyStore)try{f=await this.historyStore.load(this.sessionId)}catch(w){this.logger?.warn(`swapUpstream: historyStore.load failed: ${w.message}`)}let m=qs({synopsis:e.artifact,title:e.title,tail:f,tailK:e.tailK,tailFloor:e.tailFloor,...e.summarizedThroughEntry!==void 0?{watermark:e.summarizedThroughEntry}:{},recallArmed:(e.summarizedThroughEntry??this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("swapUpstream: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await p.agent.connection.request("session/prompt",{sessionId:p.upstreamSessionId,prompt:[{type:"text",text:m}]});let w=this.internalPromptCapture;this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${m.length} toolCalls=${w.toolCalls} thinkingChars=${w.thinkingChars} messageChars=${w.messageChars} used=${w.lastUsed??"?"} size=${w.lastSize??"?"} reply=${JSON.stringify(w.chunks.join("").slice(0,200))}`)}finally{this.internalPromptCapture=void 0}let g=this.upstreamSessionId,h=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let y=this.agent;if(this.agent=p.agent,this.upstreamSessionId=p.upstreamSessionId,this.agentMeta=p.agentMeta,this.agentCapabilities=p.agentCapabilities,this.resetModelVerb(p.modelVerb),r&&(this.agentId=n,this.agentAdvertisedCommands=[],this.currentModel=p.initialModel,this.currentMode=p.initialMode,this.setAgentAdvertisedModels(p.initialModels??[]),this.setAgentAdvertisedModes(p.initialModes??[])),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream"),e.summarizedThroughEntry!==void 0&&this.persistWatermarkHook)try{this.persistWatermarkHook(e.summarizedThroughEntry)}catch(w){this.logger?.warn(`swapUpstream: persistWatermarkHook failed: ${w.message}`)}if(!r&&this.onCompactionSwapHook)try{this.onCompactionSwapHook({previousUpstreamSessionId:g,...h!==void 0?{previousSummarizedThroughEntry:h}:{}})}catch(w){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${w.message}`)}await y.kill().catch(()=>{}),this.notifyChain("agent.swap",{phase:"post",previousUpstreamSessionId:g,upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}),r||this.broadcastCompactionPhase({phase:"swapped",...this.title!==void 0?{title:this.title}:{},summarizedThroughEntry:e.summarizedThroughEntry??this._summarizedThroughEntry??0}),r&&this.broadcastAgentSwitch(t,n);let k=e.reason==="workspace-enter"||e.reason==="workspace-leave"?void 0:r?`
34
+ Switched to ${n}.
32
35
  `:`
33
36
  Compaction completed.
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=hc){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>vc;){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??Fc(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=bt(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=bt(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(Ic(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(kc(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(",")}]`),Ac(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:`
37
+ `;if(k!==void 0){let w=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:k},_meta:{"hydra-acp":{synthetic:!0}}}});for(let v of this.clients.values())v.connection.notify("session/update",w).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 n=this.loadExistingAgentSession;if(!n)throw new Error("loadExistingAgentSession not configured for this session");let r=this.agentId,o=this.cwd,i=this.agentArgs,a=this.forwardedEnv,d=this.currentModel,u=this.currentMode,c=await n(e.previousUpstreamSessionId,{agentId:r,cwd:o,agentArgs:i,...a?{forwardedEnv:a}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(c.agent),await ut({agent:c.agent,upstreamSessionId:c.upstreamSessionId,persistedModel:d,agentReportedModel:c.initialModel,logger:this.logger}),await ct({agent:c.agent,upstreamSessionId:c.upstreamSessionId,persistedMode:u,agentReportedMode:c.initialMode,logger:this.logger}),c.agent.connection.drainBuffered("session/update");let l=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 l.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=Fu){if(!this.historyStore)return!1;let t=await this.historyStore.load(this.sessionId),n=t.length>e?t.slice(-e):t,r=new Set,o=new Set;for(let i of n){let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let 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 l=d.status;(l==="completed"||l==="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 n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}broadcastCompactionPhase(e){let t=e.phase;t==="swapped"||t==="failed"||t==="rolled_back"?this._liveCompactionPhase=void 0:this._liveCompactionPhase=e;let n=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"hydra_compaction",...e}});for(let r of this.broadcastHandlers)try{r({method:"session/update",params:n,recordedAt:Date.now()})}catch{}for(let r of this.clients.values())r.connection.notify("session/update",n).catch(()=>{});this.notifyChain("compaction",{...e})}broadcastWorkspacePhase(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"hydra_workspace",...e}});for(let n of this.broadcastHandlers)try{n({method:"session/update",params:t,recordedAt:Date.now()})}catch{}for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{});this.notifyChain("workspace",{...e})}broadcastSyntheticText(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:e},_meta:{"hydra-acp":{synthetic:!0}}}});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}attach(e,t,n={}){if(this.closed)throw ge(new Error("session is closed"),C.SessionNotFound);if(this.clients.has(e.clientId))throw ge(new Error(`client ${e.clientId} is already attached`),C.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,n)}async loadReplay(e,t){let n=a=>t.raw?a:ei(a),o=(await this.getHistorySnapshot(t.toolContent??"inline")).filter(a=>!Ks(a.method,a.params)),i=this.buildStateSnapshotReplay();if(e==="after_message"){let a=t.afterMessageId?kn(o,t.afterMessageId):-1;return a<0?{entries:[...i,...n(o)],appliedPolicy:"full"}:{entries:[...i,...n(o.slice(a+1))],appliedPolicy:"after_message"}}return{entries:[...i,...n(o)],appliedPolicy:"full"}}buildStateSnapshotReplay(){let e=[],t=this.sessionId,n=Date.now();if(this.title!==void 0&&this.title.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"session_info_update",title:this.title}},recordedAt:n}),this.currentModel!==void 0&&this.currentModel.length>0||this.agentAdvertisedModels.length>0){let o={sessionUpdate:"current_model_update"};this.currentModel!==void 0&&this.currentModel.length>0&&(o.currentModel=this.currentModel),this.agentAdvertisedModels.length>0&&(o.availableModels=[...this.agentAdvertisedModels]),e.push({method:"session/update",params:{sessionId:t,update:o},recordedAt:n})}this.currentMode!==void 0&&this.currentMode.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"current_mode_update",currentModeId:this.currentMode}},recordedAt:n});let r=this.mergedAvailableCommands();if(r.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_commands_update",availableCommands:r}},recordedAt:n}),this.agentAdvertisedModes.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_modes_update",availableModes:[...this.agentAdvertisedModes]}},recordedAt:n}),this.currentUsage!==void 0){let o=this.currentUsage,i={sessionUpdate:"usage_update"};if(typeof o.used=="number"&&(i.used=o.used),typeof o.size=="number"&&(i.size=o.size),typeof o.costAmount=="number"||typeof o.costCurrency=="string"){let a={};typeof o.costAmount=="number"&&(a.amount=o.costAmount),typeof o.costCurrency=="string"&&(a.currency=o.costCurrency),i.cost=a}Object.keys(i).length>1&&e.push({method:"session/update",params:{sessionId:t,update:i},recordedAt:n})}return this._liveCompactionPhase!==void 0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"hydra_compaction",...this._liveCompactionPhase}},recordedAt:n}),e}replayPendingPermissions(e){for(let t of this.attentionFlags.values()){if(t.source!=="daemon"||!t.reason.startsWith("permission:"))continue;let n=t.reason.slice(11),r=this.permissionCallbacks.get(n);r&&r(e)}}detach(e){let t=this.clients.get(e);t&&(this.clients.delete(e),this.updatedAt=Date.now(),this.broadcastClientDisconnected(t))}broadcastClientDisconnected(e){let t={clientId:e.clientId};e.clientInfo?.name&&(t.name=e.clientInfo.name),e.clientInfo?.version&&(t.version=e.clientInfo.version);let n={sessionUpdate:"client_disconnected",client:t,timestamp:new Date().toISOString()};for(let r of this.clients.values())r.connection.notify("session/update",{sessionId:this.sessionId,update:n}).catch(()=>{})}reportIsolationBreach(e,t){let n=this.workspace;if(n===void 0){let r=this.formerWorkspace;r!==void 0&&e.startsWith(`${r.path}/`)&&(this.logger?.warn?.(`STALE WORKSPACE WRITE on session ${this.sessionId}: the agent wrote ${e}, which is inside the workspace this session already left. That work will not reach ${r.sourceCwd}.`),this.notifyChain("workspace.staleWrite",{path:e,formerWorkspacePath:r.path,sourceCwd:r.sourceCwd,toolCallId:t}));return}di(e,n.sourceCwd,n.path)&&(this.logger?.warn?.(`ISOLATION BREACH on session ${this.sessionId}: the agent wrote ${e}, which is in the source tree ${n.sourceCwd}, not its workspace ${n.path}. The user's checkout has been modified.`),this.notifyChain("workspace.breach",{path:e,sourceCwd:n.sourceCwd,workspacePath:n.path,toolCallId:t}))}applyDepartedPromptRewrite(e){let t=this.formerWorkspace;if(t===void 0)return e;let n=!1,r=gi(e,o=>Js(o,t.path)?(n=!0,zs(o,t.path,t.sourceCwd).text):o);if(!this.departureNoteSent||n){let o=ii({sourceCwd:t.sourceCwd,formerWorkspacePath:t.path,removed:t.removed});r=Gs(r,`${o}
38
+
39
+ `),this.departureNoteSent=!0}return r}applyWorkspacePromptRewrite(e){let t=this.workspace;if(t===void 0)return this.applyDepartedPromptRewrite(e);let n=!1,r=gi(e,i=>Js(i,t.sourceCwd)?(n=!0,zs(i,t.sourceCwd,t.path).text):i);if(!this.workspacePreambleSent||n){let i=ai({workspacePath:t.path,sourceCwd:t.sourceCwd,notes:this.workspaceNotes,...this.workspacePreambleSent?{reassert:!0}:{}});r=Gs(r,`${i}
40
+
41
+ `),this.workspacePreambleSent=!0}return r}async prompt(e,t,n){let r=this.clients.get(e);if(!r)throw ge(new Error("client not attached"),C.SessionNotFound);if(this.closing)throw ge(new Error("session is closing; new prompts cannot be accepted"),C.SessionClosing);let o=Ee();if(this.maybeSeedTitleFromPrompt(t),this._firstPromptSeeded=!0,!(ot((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,n)}broadcastPromptReceived(e){this.closeUnsolicitedTurn("superseded");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 n=mt(e.prompt);n.length>0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{compatFor:"prompt_received"}}}},e.clientId)}recordCurrentUsageSnapshot(){if(this.historyStore===void 0)return;let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let r={};typeof e.costAmount=="number"&&(r.amount=e.costAmount),typeof e.costCurrency=="string"&&(r.currency=e.costCurrency),t.cost=r}if(Object.keys(t).length<=1)return;t._meta={"hydra-acp":{upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}};let n={sessionId:this.sessionId,update:t};this.historyStore.append(this.sessionId,{method:"session/update",params:n,recordedAt:Date.now()}).catch(()=>{})}broadcastTurnComplete(e,t,n,r){let o=t&&typeof t=="object"&&"stopReason"in t&&typeof t.stopReason=="string"?t.stopReason:void 0,i={sessionUpdate:"turn_complete",messageId:Ee()};o!==void 0&&(i.stopReason=o);let a=this.amendInProgress;a&&n!==void 0&&a.cancelledMessageId===n&&(i._meta={"hydra-acp":{amended:{cancelledMessageId:a.cancelledMessageId,newMessageId:a.newMessageId}}}),this.promptStartedAt=void 0,this.sawTurnComplete=!0,this.scheduleWorkspaceSnapshotHook?.(),n!==void 0&&o!==void 0&&this.recordTerminal(n,o),this.recordCurrentUsageSnapshot(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:i},r?void 0:e),a&&n!==void 0&&a.cancelledMessageId===n&&this.broadcastPromptAmended(a)}noteAgentActivity(e){if(!(this.closing||this.closed)&&!Ks("session/update",e)){if(this.noteBackgroundTaskArming(e),this.lastAgentActivityAt=Date.now(),this.unsolicitedTurn!==void 0){this.armUnsolicitedTurnTimer();return}this.promptInFlight||!this.sawTurnComplete||this.openUnsolicitedTurn()}}noteBackgroundTaskArming(e){let t=e?.update;if(!t||typeof t!="object")return;let n=typeof t.toolCallId=="string"?t.toolCallId:void 0;if(n===void 0)return;let r=t.rawInput,o=Qu(t._meta);this.rememberToolLabel(n,t,r,o),this.noteBackgroundTaskStopped(t,r,o);let i=typeof o?.toolResponse?.taskId=="string"?o.toolResponse.taskId:Vu(t.rawOutput);if(!(i!==void 0||r!==void 0&&r.run_in_background===!0))return;let d=this.toolLabels.get(n)?.label??"background task";this.lastBackgroundTask={toolCallId:n,label:d};let u=Ju(o?.toolResponse?.timeoutMs),c=Date.now(),l=this.armedTasks.get(n),p=i??l?.taskId;this.armedTasks.set(n,{label:d,...p!==void 0?{taskId:p}:{},armedAt:l?.armedAt??c,expiresAt:c+u}),this.onArmedTasksChanged()}get armedBackgroundTasks(){return[...this.armedTasks.values()].map(e=>({label:e.label,...e.taskId!==void 0?{taskId:e.taskId}:{}}))}get armedSince(){let e;for(let t of this.armedTasks.values())(e===void 0||t.armedAt<e)&&(e=t.armedAt);return e}onArmedTasksChanged(){this.scheduleArmedExpiry();let e=this.armedTasks.size,t=this.armedSince;e===this.lastArmedBroadcast?.count&&t===this.lastArmedBroadcast?.since||(this.lastArmedBroadcast={count:e,since:t},!this.closed&&this.broadcastQueueNotification("hydra-acp/session/armed_tasks_updated",{sessionId:this.sessionId,count:e,...t!==void 0?{since:t}:{},tasks:this.armedBackgroundTasks}))}scheduleArmedExpiry(){this.armedExpiryTimer!==void 0&&(clearTimeout(this.armedExpiryTimer),this.armedExpiryTimer=void 0);let e;for(let t of this.armedTasks.values())(e===void 0||t.expiresAt<e)&&(e=t.expiresAt);e===void 0||this.closed||(this.armedExpiryTimer=setTimeout(()=>{this.armedExpiryTimer=void 0;let t=Date.now(),n=!1;for(let[r,o]of this.armedTasks)o.expiresAt<=t&&(this.armedTasks.delete(r),n=!0);n?this.onArmedTasksChanged():this.scheduleArmedExpiry()},Math.max(0,e-Date.now())),typeof this.armedExpiryTimer.unref=="function"&&this.armedExpiryTimer.unref())}noteBackgroundTaskStopped(e,t,n){if(!(n?.toolName==="TaskStop"||e.title==="TaskStop"))return;let o=t?.task_id;if(typeof o!="string"||o.length===0)return;let i=!1;for(let[a,d]of this.armedTasks)d.taskId===o&&(this.armedTasks.delete(a),i=!0);i&&this.onArmedTasksChanged()}rememberToolLabel(e,t,n,r){let o=n!==void 0&&typeof n.description=="string"&&n.description?n.description:void 0;if(o!==void 0)this.toolLabels.set(e,{label:o.slice(0,fi),fromDescription:!0});else if(this.toolLabels.get(e)?.fromDescription!==!0){let i=typeof t.title=="string"&&t.title?t.title:typeof r?.toolName=="string"&&r.toolName?r.toolName:void 0;i!==void 0&&this.toolLabels.set(e,{label:i.slice(0,fi),fromDescription:!1})}for(;this.toolLabels.size>Lu;){let i=this.toolLabels.keys().next().value;if(i===void 0)break;this.toolLabels.delete(i)}}openUnsolicitedTurn(){let e=Date.now(),t=this.lastBackgroundTask;this.armedTasks.size>0&&(this.armedTasks.clear(),this.onArmedTasksChanged()),this.unsolicitedTurn={messageId:Ee(),startedAt:e,timer:void 0,cause:t},this.promptStartedAt=e,this.logger?.info(`session ${this.sessionId} agent resumed with no prompt in flight`+(t?` (after ${t.label})`:""));let n={unsolicited:!0};t&&(n.cause=t),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"turn_started",messageId:this.unsolicitedTurn.messageId,_meta:{"hydra-acp":n}}}),this.armUnsolicitedTurnTimer()}async holdForUnsolicitedTurn(e){if(this.unsolicitedTurn===void 0)return;let t=Date.now(),n=this.unsolicitedTurn.cause;this.broadcastQueueNotification("hydra-acp/prompt_queue/held",{sessionId:this.sessionId,messageId:e.messageId,reason:"agent_resumed",...n?{cause:n}:{},holdCapMs:Qs});let r="quiet";for(;;){if(this.closing||this.closed){r="closing";break}if(e.cancelled){r="cancelled";break}if(this.unsolicitedTurn===void 0){r="turn_ended";break}let o=Date.now(),i=Qs-(o-t);if(i<=0){r="cap";break}let a=Wu-(o-this.lastAgentActivityAt);if(a<=0){r="quiet";break}let d=Math.min(i,a,qu);await new Promise(u=>{let c=setTimeout(u,d);typeof c.unref=="function"&&c.unref()})}this.broadcastQueueNotification("hydra-acp/prompt_queue/released",{sessionId:this.sessionId,messageId:e.messageId,reason:r,heldMs:Date.now()-t}),r==="cap"&&this.logger?.warn(`session ${this.sessionId} dispatching a prompt into a still-running agent turn after ${Qs}ms; responses may interleave`)}armUnsolicitedTurnTimer(){let e=this.unsolicitedTurn;e!==void 0&&(e.timer!==void 0&&clearTimeout(e.timer),e.timer=setTimeout(()=>{this.closeUnsolicitedTurn("idle")},Du),typeof e.timer.unref=="function"&&e.timer.unref())}closeUnsolicitedTurn(e){let t=this.unsolicitedTurn;t!==void 0&&(t.timer!==void 0&&clearTimeout(t.timer),this.unsolicitedTurn=void 0,this.promptStartedAt=void 0,this.recordCurrentUsageSnapshot(),!this.closed&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"turn_ended",messageId:Ee(),startedMessageId:t.messageId,durationMs:Date.now()-t.startedAt,_meta:{"hydra-acp":{unsolicited:!0,reason:e}}}}))}recordTerminal(e,t){for(this.recentlyTerminal.set(e,{stopReason:t,terminatedAt:Date.now()});this.recentlyTerminal.size>ju;){let n=this.recentlyTerminal.keys().next().value;if(n===void 0)break;this.recentlyTerminal.delete(n)}}broadcastPromptAmended(e){let t=this.findUserEntry(e.newMessageId);if(!t)return;let n={sessionId:this.sessionId,cancelledMessageId:e.cancelledMessageId,newMessageId:e.newMessageId,prompt:t.prompt,originator:t.originator,amendedAt:Date.now()};this.broadcastQueueNotification("hydra-acp/prompt/amended",n)}findUserEntry(e){if(this.currentEntry?.messageId===e&&this.currentEntry.kind==="user")return this.currentEntry;let t=this.promptQueue.find(n=>n.messageId===e&&n.kind==="user");return t?.kind==="user"?t:void 0}visibleQueueDepth(){let e=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;for(let t of this.promptQueue)t.kind==="user"&&!t.cancelled&&(e+=1);return e}broadcastQueueAdded(e,t){let n=this.visibleQueueDepth(),r=t?.position??Math.max(0,n-1),o={sessionId:this.sessionId,messageId:e.messageId,originator:e.originator,prompt:e.prompt,position:r,queueDepth:n,enqueuedAt:e.enqueuedAt};t?.amending!==void 0&&(o._meta={"hydra-acp":{amending:t.amending}}),this.broadcastQueueNotification("hydra-acp/prompt_queue/added",o)}broadcastQueueUpdated(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/updated",{sessionId:this.sessionId,messageId:e,prompt:t})}broadcastQueueRemoved(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/removed",{sessionId:this.sessionId,messageId:e,reason:t})}broadcastQueueNotification(e,t){for(let n of this.clients.values())n.connection.notify(e,t).catch(()=>{})}queueSnapshot(){let e=[],t=0;this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled&&e.push({messageId:this.currentEntry.messageId,originator:this.currentEntry.originator,prompt:this.currentEntry.prompt,position:t++,enqueuedAt:this.currentEntry.enqueuedAt});for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push({messageId:n.messageId,originator:n.originator,prompt:n.prompt,position:t++,enqueuedAt:n.enqueuedAt});return e}async flushPersistWrites(){await this.queueWriteChain.catch(()=>{})}replayPersistedQueue(e){for(let t of e){let n={clientId:`hydra-resurrected_${t.messageId}`};t.originator.clientInfo.name!==void 0&&(n.name=t.originator.clientInfo.name),t.originator.clientInfo.version!==void 0&&(n.version=t.originator.clientInfo.version);let r={kind:"user",messageId:t.messageId,originator:n,clientId:n.clientId,prompt:t.prompt,enqueuedAt:t.enqueuedAt,cancelled:!1,resolve:()=>{},reject:()=>{}};this.promptQueue.push(r),this.broadcastQueueAdded(r)}this.drainQueue()}cancelQueuedPrompt(e){if(this.currentEntry?.messageId===e)return{cancelled:!1,reason:"already_running"};let t=this.promptQueue.findIndex(r=>r.messageId===e);if(t<0)return{cancelled:!1,reason:"not_found"};let n=this.promptQueue[t];return n.cancelled=!0,this.promptQueue.splice(t,1),n.kind==="user"&&(this.broadcastQueueRemoved(e,"cancelled"),this.persistRewrite()),this.amendInProgress?.newMessageId===e&&(this.amendInProgress=void 0),n.resolve({stopReason:"cancelled"}),{cancelled:!0,reason:"ok"}}updateQueuedPrompt(e,t){if(this.currentEntry?.messageId===e)return{updated:!1,reason:"already_running"};let n=this.promptQueue.find(r=>r.messageId===e);return!n||n.kind!=="user"?{updated:!1,reason:"not_found"}:(n.prompt=t,this.broadcastQueueUpdated(e,t),this.persistRewrite(),{updated:!0,reason:"ok"})}amendPrompt(e,t){let n=this.clients.get(e);if(!n)throw ge(new Error("client not attached"),C.SessionNotFound);let{targetMessageId:r,prompt:o,replaceQueue:i,onTargetCompleted:a}=t;if(this.currentEntry?.messageId===r&&this.currentEntry.kind==="user"&&!this.currentEntry.cancelled&&this.amendInProgress===void 0)return this.amendOnHead(n,o,r,i);let d=this.promptQueue.find(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(n,o)}:{amended:!1,reason:"target_completed"}:{amended:!1,reason:"target_not_found"}}amendOnHead(e,t,n,r){let o=Ee(),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:n,position:1}),this.amendInProgress={cancelledMessageId:n,newMessageId:o},this.cancelExtensionDispatch(n,"amended"),this.agent.connection.notify("session/cancel",{sessionId:this.upstreamSessionId}).catch(()=>{}),{amended:!0,reason:"ok",messageId:o}}enqueueAmendmentAsFollowUp(e,t){let n=Ee(),r={clientId:e.clientId};e.clientInfo?.name&&(r.name=e.clientInfo.name),e.clientInfo?.version&&(r.version=e.clientInfo.version);let o={kind:"user",messageId:n,originator:r,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,resolve:()=>{},reject:()=>{}};return this.promptQueue.push(o),this.persistRewrite(),this.broadcastQueueAdded(o),this.drainQueue(),n}async cancel(e){if(!this.clients.get(e))throw ge(new Error("client not attached"),C.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(n=>n.name===e.name);t>=0?this.transformChain[t]=e:this.transformChain.push(e),e.intercepts.has("lifecycle:session.opened")&&e.connection.notify("hydra-acp/transformer/session_event",{event:"session.opened",sessionId:this.sessionId}).catch(()=>{})}async forwardRequest(e,t,n=new Set,r=0,o="request"){let i=this.rewriteForAgent(t);for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name))continue;let u=`request:${e}`;if(!d.intercepts.has(u))continue;let c=`t_${Vs()}`,l;try{l=await d.connection.request("hydra-acp/transformer/message",{token:c,phase:"request",method:e,direction:"client\u2192agent",sessionId:this.sessionId,envelope:i})}catch(f){this.logger?.warn(`transformer ${d.name} error on ${u}: ${f.message}`);continue}let p=l?.action??"continue";if(p==="stop")return o==="notification"?void 0:l?.payload??Ys(e);if(p==="continue"){l?.payload&&typeof l.payload=="object"&&(i=l.payload),n.add(d.name);continue}if(p==="processing"){let f=a,m=i,g=new Set(n);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]),f+1,o).then(h).catch(()=>h(o==="notification"?void 0:Ys(e))))},wn);typeof y.unref=="function"&&y.unref(),this.pendingClaims.set(c,{resolve:h,timer:y,transformerName:d.name,method:e,envelope:m,chainIdx:f,originatedBy:g,side:"request",tailKind:o})})}n.add(d.name)}if(o==="notification"){await this.agent.connection.notify(e,i);return}return this.agent.connection.request(e,i)}async forwardModelChange(e,t){let n=await Je({request:(r,o)=>this.forwardRequest(r,o),sessionId:this.sessionId,modelId:e,verb:this.modelVerb,extraParams:t,logger:this.logger});return this.modelVerb=n.verb,this.modelVerbConfirmed=!0,n.result}noteModelVerbHint(e,t){e===void 0||this.modelVerbConfirmed||e===this.modelVerb||(this.logger?.info(`model verb for agent ${this.agentId} inferred as ${e} from ${t} (was ${this.modelVerb})`),this.modelVerb=e)}resetModelVerb(e){this.modelVerb=e??xe,this.modelVerbConfirmed=!1}async runAgentRequestChain(e,t,n=new Set,r=0){let o=t,i=`request:${e}`;for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name)||!d.intercepts.has(i))continue;let u=`t_${Vs()}`,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 l=c?.action??"continue";if(l==="stop")return{shortCircuit:!0,payload:c?.payload??il(e)};if(l==="continue"){c?.payload&&typeof c.payload=="object"&&(o=c.payload),n.add(d.name);continue}if(l==="processing"){let p=a,f=o,m=new Set(n),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,f,new Set([...m,d.name]),p+1).then(h).catch(()=>h({shortCircuit:!1,envelope:f})))},wn);typeof y.unref=="function"&&y.unref(),this.pendingClaims.set(u,{resolve:k=>h({shortCircuit:!0,payload:k}),timer:y,transformerName:d.name,method:g,envelope:f,chainIdx:p,originatedBy:m,side:"agent-request"})})}n.add(d.name)}return{shortCircuit:!1,envelope:o}}dischargeClaim(e,t){let n=this.pendingClaims.get(e);return n?(clearTimeout(n.timer),this.pendingClaims.delete(e),n.resolve(t),!0):!1}keepAliveClaim(e,t){let n=this.pendingClaims.get(e);if(!n)return!1;clearTimeout(n.timer);let r=typeof t=="number"&&t>0?Math.min(t*1.5,1800*1e3):wn,o=setTimeout(()=>{if(this.pendingClaims.delete(e))if(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:e,transformerName:n.transformerName}),n.side==="response")this.runResponseChain(n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1).then(()=>n.resolve(void 0)).catch(()=>n.resolve(void 0));else if(n.side==="agent-request")this.runAgentRequestChain(n.method,n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1).then(n.resolve).catch(()=>n.resolve({shortCircuit:!1,envelope:n.envelope}));else{let i=n.tailKind??"request";this.forwardRequest(n.method,n.envelope,new Set([...n.originatedBy,n.transformerName]),n.chainIdx+1,i).then(n.resolve).catch(()=>n.resolve(i==="notification"?void 0:Ys(n.method)))}},r);return typeof o.unref=="function"&&o.unref(),n.timer=o,!0}async emitToChain(e,t,n){let r=this.transformChain.findIndex(a=>a.name===e),o=r>=0?r+1:0,i=new Set([e]);if(t==="session/update"){await this.runResponseChain(n,i,o);return}return this.forwardRequest(t,n,i,o)}async emitToQueue(e,t){let n=this.transformChain.findIndex(u=>u.name===e),r=n>=0?n+1:0,o=(t??{}).prompt??[],i=Ee(),a=`transformer:${e}`,d={clientId:a,name:e};return new Promise((u,c)=>{let l={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(l,"tail");this.persistRewrite(),this.broadcastQueueAdded(l,{position:p}),this.drainQueue()})}rewriteForAgent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.sessionId===this.sessionId)return{...t,sessionId:this.upstreamSessionId}}return e}async close(e={}){if(e.deleteRecord&&(this.deleteRecordIntent=!0),!this.closed)return this.closeInFlight?this.closeInFlight:(this.closing=!0,this.closeInFlight=this.doClose(e),this.closeInFlight)}async doClose(e){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 n of this.titleHandlers)try{n(t)}catch{}}}maybeSeedTitleFromPrompt(e){if(this.firstPromptSeeded||ot((e??{})._meta).ancillary===!0||this.promptCarriesSentBy(e))return;let r=mt((e??{}).prompt),o=Xs(r,200);o&&(o.startsWith("/")||(this._firstPromptSeeded=!0,this.setTitle(o)))}maybeApplyAgentModel(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="current_model_update")return!1;let r=ht(n.availableModels);r.length>0&&this.setAgentAdvertisedModels(r);let o=typeof n.currentModel=="string"?n.currentModel:typeof n.model=="string"?n.model:void 0;if(o===void 0)return!0;let i=o.trim();if(!i||i===this.currentModel)return!0;this.logger?.info(`live current_model_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(i)}`),this.currentModel=i;for(let a of this.modelHandlers)try{a(i)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentConfigOption(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="config_option_update")return!1;let r=n.configOptions;if(!Array.isArray(r))return!0;for(let o of r){if(!o||typeof o!="object")continue;let i=o;if(i.id==="model"){let a=ht(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=Ot(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=ht(i.options);if(d.length>0){let u=Ot(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})),l=i.name,p=typeof l=="string"&&l.trim()?l.trim():a,f=i.currentValue,m=typeof f=="string"&&f.trim()?f.trim():c[0]?.value??"",g=this.agentAdvertisedConfigOptions.findIndex(h=>h.id===a);if(g>=0){let h={...this.agentAdvertisedConfigOptions[g]};h.options=c,typeof f=="string"&&f.trim()&&(h.currentValue=f.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 n=(e??{}).update??{};if(n.sessionUpdate!=="current_mode_update")return!1;let r=typeof n.currentModeId=="string"?n.currentModeId:typeof n.currentMode=="string"?n.currentMode:typeof n.mode=="string"?n.mode:void 0;if(r===void 0)return!0;let o=r.trim();if(!o||o===this.currentMode)return!0;this.logger?.info(`current_mode_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(o)}`),this.currentMode=o;for(let i of this.modeHandlers)try{i(o)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentUsage(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="usage_update")return!1;let r={...this._currentUsage??{}},o=!1;if(typeof n.used=="number"&&r.used!==n.used&&(r.used=n.used,o=!0),typeof n.size=="number"&&r.size!==n.size&&(r.size=n.size,o=!0),n.cost&&typeof n.cost=="object"){let a=n.cost;typeof a.amount=="number"&&(this.reconcileCostLedger(a.amount)&&(o=!0),r.costAmount!==a.amount&&(r.costAmount=a.amount,o=!0)),typeof a.currency=="string"&&r.costCurrency!==a.currency&&(r.costCurrency=a.currency,o=!0)}if(!o)return!0;this._currentUsage=r;let i=this.persistableUsage??r;for(let a of this.usageHandlers)try{a(i)}catch{}return!0}armCostLedgerProbe(){let e=this._currentUsage?.costAmount;typeof e=="number"&&e>0&&(this.costLedgerProbe=e)}reconcileCostLedger(e){let t=this.costLedgerProbe;return t===void 0||(this.costLedgerProbe=void 0,e>=t-1e-6)?!1:(this.cumulativeCost+=t,!0)}notifyAgentChange(e){let t=this.retiringGenerationCost;this.retiringGenerationCost=void 0;for(let n of this.agentChangeHandlers)try{n({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 n=this.currentUsage;if(n!==void 0){let r={sessionUpdate:"usage_update"};if(typeof n.used=="number"&&(r.used=n.used),typeof n.size=="number"&&(r.size=n.size),typeof n.costAmount=="number"||typeof n.costCurrency=="string"){let o={};typeof n.costAmount=="number"&&(o.amount=n.costAmount),typeof n.costCurrency=="string"&&(o.currency=n.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 n=t.update;if(n.sessionUpdate!=="usage_update"||!n.cost||typeof n.cost!="object")return e;let r=n.cost;return typeof r.amount!="number"?e:{...t,update:{...n,cost:{...r,amount:this.cumulativeCost+r.amount}}}}get totalUsage(){return this.currentUsage}setAgentAdvertisedCommands(e){if(Ku(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(Gu(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(",")}]`),Yu(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 n of this.priorityHandlers)try{n(t)}catch{}}}applyModelChange(e){let t=e.trim();if(t){this.modelChangeInFlight=!0;try{if(t!==this.currentModel){this.logger?.info(`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(t)}`),this.currentModel=t;for(let r of this.modelHandlers)try{r(t)}catch{}}let n={sessionUpdate:"current_model_update",currentModel:t};this.agentAdvertisedModels.length>0&&(n.availableModels=[...this.agentAdvertisedModels]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modelChangeInFlight=!1}}}applyModeChange(e){let t=e.trim();if(t){this.modeChangeInFlight=!0;try{if(t!==this.currentMode){this.logger?.info(`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(t)}`),this.currentMode=t;for(let r of this.modeHandlers)try{r(t)}catch{}}let n={sessionUpdate:"current_mode_update",currentModeId:t};this.agentAdvertisedModes.length>0&&(n.availableModes=[...this.agentAdvertisedModes]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modeChangeInFlight=!1}}}buildConfigOptions(){let e=[];if(this.agentAdvertisedModels.length>0){let r=this.agentAdvertisedModels.map(i=>({value:i.modelId,name:i.name??i.modelId,...i.description!==void 0?{description:i.description}:{}})),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 n=(this.availableAgentsFn?.()??[]).map(r=>({value:r.id,name:r.name??r.id,...r.description!==void 0?{description:r.description}:{}}));return n.some(r=>r.value===this.agentId)||n.unshift({value:this.agentId,name:this.agentId}),e.push({id:"agent",name:"Agent",category:"_hydra_agent",type:"select",currentValue:this.agentId,options:n}),e.push(...this.agentAdvertisedConfigOptions),e}broadcastConfigOptions(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"config_option_update",configOptions:this.buildConfigOptions()}})}mergeAgentOptionIntoEnvelope(e){if(!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update,r=Array.isArray(n.configOptions)?[...n.configOptions]:[];if(r.some(a=>a&&typeof a=="object"&&a.id==="agent"))return e;let i=this.buildConfigOptions().find(a=>a.id==="agent");return i?{...t,update:{...n,configOptions:[...r,i]}}:e}onUsageChange(e){this.usageHandlers.push(e)}mergedAvailableCommands(){let e=this.daemonTopLevelCommands(),t=this.aliasableBareVerbs();for(let n of ft){if(t.get(n.verb)!=="__hydra__")continue;let r=n.argsHint?`${n.verb} ${n.argsHint}`:n.verb;e.push({name:r,description:`Alias for '/hydra ${n.verb}': ${n.description}`})}if(this.extensionCommands)for(let{name:n,command:r}of this.extensionCommands.list()){let o=r.verb?`hydra ${n} ${r.verb}`:`hydra ${n}`,a={name:r.argsHint?`${o} ${r.argsHint}`:o};r.description&&(a.description=r.description),e.push(a);let d=n.startsWith("hydra-acp-")?n.slice(10):n;if(n.startsWith("hydra-acp-")&&d.length>0){let u=r.verb?`hydra ${d} ${r.verb}`:`hydra ${d}`,l={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(l.description=r.description),e.push(l)}if(d.length>0&&t.get(d)===n){let u=r.verb?`${d} ${r.verb}`:d,l={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(l.description=r.description),e.push(l)}}return e.push(...this.agentAdvertisedCommands),e}daemonTopLevelCommands(){return[{name:"hydra",description:"Hydra session command (kill, restart, title, agent <agent>)"},{name:"model",description:"Switch model; omit arg to list available models"},{name:"mode",description:"Switch mode; omit arg to list available modes"},{name:"sessions",description:"List all sessions"},{name:"help",description:"Show available commands"}]}aliasableBareVerbs(){let e=new Set,t=i=>i.split(/\s+/)[0]??"";for(let i of this.daemonTopLevelCommands()){let a=t(i.name);a&&e.add(a)}for(let i of this.agentAdvertisedCommands){let a=t(i.name),d=a.startsWith("/")?a.slice(1):a;d&&e.add(d)}let n=new Map;for(let i of ft)e.has(i.verb)||n.set(i.verb,"__hydra__");if(!this.extensionCommands)return n;let r=new Map,o=new Set;for(let{name:i}of this.extensionCommands.list()){if(o.has(i))continue;o.add(i);let a=i.startsWith("hydra-acp-")?i.slice(10):i;if(!a||e.has(a)||n.has(a))continue;let d=r.get(a);d===void 0?r.set(a,i):d!==i&&r.set(a,"__conflict__")}for(let[i,a]of r)a!=="__conflict__"&&n.set(i,a);return n}agentOnlyAdvertisedCommands(){return[...this.agentAdvertisedCommands]}agentKnowsSlashCommand(e){let t=r=>r.startsWith("/")?r.slice(1):r,n=t(e);if(!n)return!1;for(let r of this.agentAdvertisedCommands)if(t(r.name.split(/\s+/)[0]??"")===n)return!0;return!1}availableModes(){return[...this.agentAdvertisedModes]}availableModels(){return[...this.agentAdvertisedModels]}maybeApplyAgentSessionInfo(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="session_info_update"||typeof n.title!="string")return;let r=n.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(ft.some(l=>l.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"workspace":return this.runWorkspaceCommand(i);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 l=new Error(`no dispatcher for /hydra verb ${o}`);throw l.code=C.InternalError,l}}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=ft.map(l=>l.verb);if(this.extensionCommands){let l=new Set;for(let{name:p}of this.extensionCommands.list())l.has(p)||(u.push(p),l.add(p))}let c=new Error(`unknown /hydra verb: ${o} (known: ${u.join(", ")})`);throw c.code=C.InvalidParams,c}runExtensionCommand(e,t){return this.enqueuePrompt(()=>this.runExtensionCommandInline(e,t,void 0))}async runExtensionCommandInline(e,t,n){let r=this.extensionCommands?.get(e);if(!r)return this.emitExtensionReply(`extension "${e}" is no longer connected`);let o=t.match(/^(\S+)(?:\s+([\s\S]*))?$/),i=o?.[1]??"",a=(o?.[2]??"").trim();if(!r.commands.some(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};n!==void 0&&(d.messageId=n);let u=()=>{},c=new Promise(m=>{u=m});n!==void 0&&this.inFlightExtensionDispatches.set(n,{extensionName:e,connection:r.connection,cancel:m=>u({stopReason:"cancelled",reason:m})});let l,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"};l=g}catch(m){return this.emitExtensionReply(`${e} ${i}: ${m.message}`)}finally{n!==void 0&&!p&&this.inFlightExtensionDispatches.delete(n)}let f=l&&typeof l=="object"&&typeof l.text=="string"?l.text:"";return f.length>0?this.emitExtensionReply(f):{stopReason:"end_turn"}}cancelExtensionDispatch(e,t){let n=this.inFlightExtensionDispatches.get(e);if(!n)return!1;this.inFlightExtensionDispatches.delete(e);try{n.connection.notify("hydra-acp/commands/cancel",{sessionId:this.sessionId,messageId:e,reason:t})}catch(r){this.logger?.warn(`notify commands/cancel to ${n.extensionName} failed: ${r.message}`)}return n.cancel(t),!0}emitExtensionReply(e){return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
35
42
  ${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 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
- ${s.join(`
43
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}async handleSessionsCommand(){let e;if(!this.listSessions)e="_(session listing not available)_";else{let t=await this.listSessions();if(t.length===0)e="_(no sessions)_";else{let n=t.map(r=>{let o=r.sessionId.replace(/^hydra_session_/,"").slice(0,12),i=r.currentModel?` \xB7 ${r.currentModel}`:"",a=r.sessionId===this.sessionId?" \u25C0":"",d=r.title?` ${r.title}`:"";return`\`${o}\` ${r.cwd}${i}${a}${d}`});e=`Sessions (${t.length}):
44
+ ${n.join(`
38
45
  `)}`}}return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
39
46
  ${e}
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:
47
+ `},_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}`}),n=t.length>0?`Available commands:
41
48
  ${t.join(`
42
49
  `)}`:"_(no commands advertised)_";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
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 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(`
50
+ ${n}
51
+ `},_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 l=c.modelId===i?"\u25B6 ":" ",p=c.name&&c.name!==c.modelId?` ${c.name}`:"";return`${l}${c.modelId}${p}`});!d&&i&&u.unshift(`\u25B6 ${i}`),a=u.join(`
45
52
  `)}return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
46
53
  ${a}
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:`
54
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let n=pt(t,this.agentAdvertisedModels),r=t;if(n.kind==="resolved")r=n.modelId;else if(n.kind==="ambiguous"||n.kind==="unknown"){let o=this.agentAdvertisedModels.map(l=>l.modelId),i=t.toLowerCase(),a=n.kind==="ambiguous"?n.candidates:o.filter(l=>l.toLowerCase().includes(i)),d=a.length>0?a:o,u=n.kind==="ambiguous"?`"${t}" matches multiple models: ${n.candidates.join(", ")}`:a.length>0?`"${t}" is not an available model. Did you mean`:`"${t}" is not an available model`,c=n.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
55
  ${u}.
49
56
  ${c}:
50
57
  ${d.join(`
51
58
  `)}
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(`
59
+ `},_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 ":" ",l=u.name&&u.name!==u.id?` ${u.name}`:"";return`${c}${u.id}${l}`});!a&&o&&d.unshift(`\u25B6 ${o}`),i=d.join(`
53
60
  `)}return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
54
61
  ${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:`
62
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let n=this.agentAdvertisedModes;if(n.length>0&&!n.some(r=>r.id===t)){let r=n.map(o=>o.id).join(", ");throw ge(new Error(`unknown mode: ${t} (known: ${r})`),C.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]*))?$/),n=t?.[1],r=t?.[2]??"";if(!n){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
63
  _(no config options advertised yet)_
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
- ${f.join(`
64
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let l=c.map(p=>mi(p));return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
65
+ ${l.join(`
59
66
 
60
67
  `)}
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(`
68
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let o=this.buildConfigOptions(),i=o.find(c=>c.id===n);if(!i){let c=o.map(l=>l.id).join(`
62
69
  `);return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
63
- "${s}" is not a known config option.
70
+ "${n}" is not a known config option.
64
71
  Available options:
65
72
  ${c}
66
73
  `},_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
- ${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
- ${l}.
74
+ ${mi(i)}
75
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let a=i.options.map(c=>c.value),d=Os(r,a),u=r;if(d.kind==="resolved")u=d.modelId;else if(d.kind==="ambiguous"||d.kind==="unknown"){let c=r.toLowerCase(),l=d.kind==="ambiguous"?d.candidates:a.filter(g=>g.toLowerCase().includes(c)),p=l.length>0?l:a,f=d.kind==="ambiguous"?`"${r}" matches multiple values for "${n}": ${d.candidates.join(", ")}`:l.length>0?`"${r}" is not a valid value for "${n}". Did you mean`:`"${r}" is not a valid value for "${n}"`,m=d.kind==="ambiguous"||l.length===0?"Valid values":"Matching values";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
76
+ ${f}.
70
77
  ${m}:
71
78
  ${p.join(`
72
79
  `)}
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:yc,tailFloor:wc,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?Ec(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=Rc({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(()=>wt(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,_c));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 Sc=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"&&Sc.has(s)}function Ic(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 kc(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 Ac(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 bt(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 Cc(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 xc(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 Mc(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 Ec(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 Rc(n){let e=Tc(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=Pc(n.resolver),t}function Tc(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 Pc(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 _c="\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 Fc(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
- ${s.join(`
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 pg from"path";import{customAlphabet as Hc}from"nanoid";import{z as M}from"zod";import{z as rt}from"zod";var Oc=rt.object({source:rt.string(),reason:rt.string(),raisedAt:rt.number(),payload:rt.unknown()}),Io=rt.array(Oc);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()}),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()}),Ao=200,gs=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
80
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}return n==="model"?(u!==this.currentModel&&await this.forwardModelChange(u),this.applyModelChange(u),{stopReason:"end_turn"}):n==="mode"?(u!==this.currentMode&&await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:u}),this.applyModeChange(u),{stopReason:"end_turn"}):n==="agent"?(u!==this.agentId&&await this.runAgentCommandInline(u),{stopReason:"end_turn"}):(await this.forwardRequest("session/set_config_option",{sessionId:this.sessionId,configId:n,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 ge(new Error("/hydra agent requires an agent id"),C.InvalidParams);let r=(this.resolveAgentIdHook?await this.resolveAgentIdHook(t):void 0)??t;if(r===this.agentId)throw ge(new Error(`already on agent ${r}`),C.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 ge(new Error("agent restart not configured for this session"),C.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 n=[`Compaction state: ${e.status}${e.iter!=null?` (iteration ${e.iter})`:""}`,`Summarized through entry: ${t??0}`,`Pending attempts: ${e.attempts??0}`];return this.emitExtensionReply(n.join(`
81
+ `)),{stopReason:"end_turn"}}runUncompactCommand(){return this.enqueuePrompt(()=>this.runUncompactCommandInline())}async runWorkspaceCommand(e){if(!this.workspaceHook)return this.emitExtensionReply("Workspaces are not available on this session (no workspace hook configured)."),{stopReason:"end_turn"};let[t="status",...n]=e.split(/\s+/).filter(d=>d.length>0);if(!li.includes(t))return this.emitExtensionReply(`Unknown workspace verb "${t}". Use one of: ${li.join(", ")}.`),{stopReason:"end_turn"};let r=n.filter(d=>d.startsWith("--")),o=r.filter(d=>d!=="--clean"&&d!=="--deep");if(o.length>0)return this.emitExtensionReply(`Unknown workspace flag(s) ${o.join(", ")}. Supported: --clean (start), --deep (clean).`),{stopReason:"end_turn"};let i={clean:r.includes("--clean"),deep:r.includes("--deep")};if(i.clean&&t!=="start")return this.emitExtensionReply(`--clean applies to \`start\`, not to \`${t}\`.`),{stopReason:"end_turn"};if(i.deep&&t!=="clean")return this.emitExtensionReply(`--deep applies to \`clean\`, not to \`${t}\`.`),{stopReason:"end_turn"};let a=n.filter(d=>!d.startsWith("--")).join(" ").trim();try{let d=await this.workspaceHook(t,a.length>0?a:void 0,i);this.emitExtensionReply(d)}catch(d){this.emitExtensionReply(`Workspace ${t} failed: ${d instanceof Error?d.message:String(d)}`)}return{stopReason:"end_turn"}}async runUncompactCommandInline(){if(!this.uncompactHook)return this.emitExtensionReply("Rollback not available: uncompact hook not configured for this session."),{stopReason:"end_turn"};try{await this.uncompactHook(),this.emitExtensionReply("Rolled back to pre-compaction upstream. The session is now using the previous agent context.")}catch(e){this.emitExtensionReply(`Rollback failed: ${e instanceof Error?e.message:String(e)}`)}return{stopReason:"end_turn"}}runForkCommand(e){return this.enqueuePrompt(()=>this.runForkCommandInline(e,void 0))}async findMessageIdBefore(e){if(!this.historyStore)return;let t=await this.historyStore.load(this.sessionId),n;for(let r of t){if(r.method!=="session/update")continue;let i=r.params?.update?.messageId;if(typeof i=="string"){if(i===e)return n;n=i}}}async runForkCommandInline(e,t){if(!this.forkHook)return this.emitExtensionReply("Fork not configured for this session."),{stopReason:"end_turn"};let n=(e??"").trim(),r;if(n==="verbatim")r="verbatim";else if(n==="synthesis"||n==="")r=void 0;else return this.emitExtensionReply(`Unknown fork argument: \`${n}\`. Use \`/hydra fork\` or \`/hydra fork verbatim\`.`),{stopReason:"end_turn"};try{let o={};if(r&&(o.mode=r),t&&this.historyStore){let d=await this.findMessageIdBefore(t).catch(()=>{});d&&(o.forkAt=d)}let a=(await this.forkHook(Object.keys(o).length>0?o:void 0)).sessionId.replace(/^hydra_session_/,"");this.emitExtensionReply(`Forked to [\`${a}\`](hydra://sessions/${a}).`)}catch(o){this.emitExtensionReply(`Fork failed: ${o instanceof Error?o.message:String(o)}`)}return{stopReason:"end_turn"}}async forceCancel(){if(this.closed||this.closing)throw ge(new Error("session is closing"),C.SessionClosing);return this.lastCancelAt=0,this.forceCancelling=!0,await this.close({deleteRecord:!1}),{stopReason:"cancelled"}}async respawnAgent(){let e=this.spawnReplacementAgent,t=this.agentId,n=await this.buildSwitchTranscript(t),r=await e({agentId:t,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{}});this.accumulateAndResetCost(),this.wireAgent(r.agent);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(()=>{}),n&&await this.runInternalPrompt(n).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 n=[],r=await this.getHistorySnapshot();for(let u of r){if(u.method!=="session/update")continue;let l=(u.params??{}).update;if(!l||l._meta?.["hydra-acp"]?.synthetic)continue;let f=l.sessionUpdate;if(f==="prompt_received"){let m=mt(l.prompt);m&&n.push({speaker:"user",text:m})}else if(f==="agent_message_chunk"){let g=l.content?.text;g&&n.push({speaker:`agent: ${e}`,text:g})}else if(f==="tool_call"||f==="tool_call_update"){let m=l.status,g=l.title;(m==="completed"||m==="failed")&&n.push({speaker:"tool",text:`${g??"?"} ${m}`})}}if(n.length===0)return"";let o=[],i;for(let u of n)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(`
82
+ `)}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)",n=[];if(this.historyStore)try{n=await this.historyStore.load(this.sessionId)}catch(o){this.logger?.warn(`seedFromFork: historyStore.load failed: ${o.message}`)}let r=qs({synopsis:e,title:t,tail:n,tailK:Nu,tailFloor:Ou,watermark:this._summarizedThroughEntry,recallArmed:(this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("seedFromFork: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:r}]});let o=this.internalPromptCapture;this.logger?.info(`seedFromFork: seed processed sessionId=${this.sessionId} seedChars=${r.length} toolCalls=${o.toolCalls} thinkingChars=${o.thinkingChars} messageChars=${o.messageChars}`)}finally{this.internalPromptCapture=void 0}})}broadcastAgentSwitch(e,t){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,agentId:t,pendingAgentSwap:null}}}}),this.broadcastConfigOptions()}broadcastPendingAgentSwap(e){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,pendingAgentSwap:e}}}})}hasStreamBuffer(){return this.streamBuffer!==void 0}get streamPath(){return this.streamFilePath}openStream(e){if(this.streamBuffer!==void 0)throw new Error(`stream buffer already open for session ${this.sessionId}`);let n=(e.mode??"memory")==="file"&&e.filePathFor!==void 0?e.filePathFor(this.sessionId):void 0,r={};e.capacityBytes!==void 0&&(r.capacityBytes=e.capacityBytes),n!==void 0&&(r.filePath=n),e.fileCapBytes!==void 0&&(r.fileCapBytes=e.fileCapBytes),r.onFileCapReached=()=>{this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"stream_truncated",...n!==void 0?{filePath:n}:{},fileCapBytes:e.fileCapBytes}})};let o=new hn(r);this.streamBuffer=o,this.streamFilePath=n;let i={capacityBytes:o.capacity};return n!==void 0&&(i.filePath=n),e.fileCapBytes!==void 0&&(i.fileCapBytes=e.fileCapBytes),i}streamWrite(e,t){let n=this.requireStreamBuffer();if(e.length>0){let r=Buffer.from(e,"base64");n.append(r)}return t===!0&&n.close(),{writeCursor:n.writeCursorPos}}async streamRead(e,t,n){let r=this.requireStreamBuffer(),o=Math.max(0,Math.min(t??lt,lt)),i=r.read(e,o);if(i.bytes.length===0&&i.eof!==!0&&n!==void 0&&n>0){let d=await r.waitForData(i.nextCursor,n);(d==="data"||d==="eof")&&(i=r.read(i.nextCursor,o))}let a={bytes:i.bytes.toString("base64"),nextCursor:i.nextCursor};return i.gap!==void 0&&(a.gap=i.gap),i.eof===!0&&(a.eof=!0),a}streamTail(e){let n=this.requireStreamBuffer().tail(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}streamHead(e){let n=this.requireStreamBuffer().head(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}async streamWaitFor(e,t){return this.requireStreamBuffer().waitForData(e,t)}streamGrep(e){return this.requireStreamBuffer().grep(e)}streamInfo(){let e=this.requireStreamBuffer();return{writeCursor:e.writeCursorPos,oldestAvailable:e.oldestAvailable,capacity:e.capacity,closed:e.isClosed}}requireStreamBuffer(){if(this.streamBuffer===void 0){let e=new Error(`session ${this.sessionId} has no stream buffer; POST /v1/sessions/:id/stdin/open first`);throw e.code=C.StreamNotEnabled,e}return this.streamBuffer}markClosed(e){if(this.closed)return;this.closeUnsolicitedTurn("closed"),this.armedExpiryTimer!==void 0&&(clearTimeout(this.armedExpiryTimer),this.armedExpiryTimer=void 0),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 n=this.promptQueue;this.promptQueue=[];for(let o of n){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(()=>ui(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(()=>ki.unlink(i).catch(()=>{}))}for(let o of this.closeHandlers)o(e)}get lastActivityAt(){return this.lastRecordedAt}setAttentionFlag(e,t,n){this._setAttentionFlag(e,t,n,!0)}_setAttentionFlag(e,t,n,r){let o=`${e}::${t}`,i=this.attentionFlags.get(o);if(i){if(JSON.stringify(i.payload)===JSON.stringify(n))return;this.attentionFlags.set(o,{...i,payload:n,raisedAt:i.raisedAt})}else this.attentionFlags.set(o,{source:e,reason:t,raisedAt:Date.now(),payload:n});r&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}clearAttentionFlag(e,t){this._clearAttentionFlag(e,t,!0)}_clearAttentionFlag(e,t,n){let r=`${e}::${t}`;this.attentionFlags.delete(r)&&n&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}listAttentionFlags(){return Array.from(this.attentionFlags.values()).sort((e,t)=>e.raisedAt-t.raisedAt)}listAttentionFlagsBySource(e){return this.listAttentionFlags().filter(t=>t.source===e)}onAttentionFlagsChange(e){this.attentionFlagsChangeHandlers.push(e)}fireAttentionFlagsChange(){let e=this.listAttentionFlags();for(let t of this.attentionFlagsChangeHandlers)try{t(e)}catch{}}broadcastAttentionUpdated(){for(let e of this.clients.values())e.connection.notify("hydra-acp/session/attention_updated",{sessionId:this.sessionId,flags:this.listAttentionFlags()}).catch(()=>{})}scheduleIdleCheck(){if(this.closed||this.idleTimeoutMs<=0)return;let e=this.lastActivityAt+this.idleTimeoutMs;this.armIdleTimer(Math.max(0,e-Date.now()))}armIdleTimer(e){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{this.idleTimer=void 0,this.checkIdle()},e),typeof this.idleTimer.unref=="function"&&this.idleTimer.unref()}checkIdle(){if(this.closed||this.idleTimeoutMs<=0)return;if(this.hasWorkInFlight){this.armIdleTimer(this.idleTimeoutMs);return}let e=Date.now()-this.lastActivityAt;if(e<this.idleTimeoutMs){this.armIdleTimer(this.idleTimeoutMs-e);return}let t=this.firstPromptSeeded?{deleteRecord:!1}:{deleteRecord:!0},n=Math.round(e/1e3);this.logger?.info(`session ${this.sessionId} idle timeout fired after ${n}s (window=${Math.round(this.idleTimeoutMs/1e3)}s) \u2014 closing`),this.close(t).catch(()=>{})}cancelIdleTimer(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=void 0),this.disposeIdleHandlers()}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 n={fn:e,once:!!t?.once,debounceMs:t?.debounceMs??0};return this.idleHandlers.push(n),()=>{let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1),n.timer&&(clearTimeout(n.timer),n.timer=void 0)}}onceIdle(e){return this.onIdle(e,{once:!0})}dispatchIdle(){if(this.closed)return;if(!this.isQuiescedSync()){for(let n of this.idleHandlers)n.timer&&(clearTimeout(n.timer),n.timer=void 0);return}let t=[...this.idleHandlers];for(let n of t){if(n.debounceMs===0){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}continue}n.timer&&(clearTimeout(n.timer),n.timer=void 0),n.timer=setTimeout(()=>{if(n.timer=void 0,!this.closed&&this.isQuiescedSync()){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}}},n.debounceMs),typeof n.timer.unref=="function"&&n.timer.unref()}}disposeIdleHandlers(){for(let e of this.idleHandlers)e.timer&&(clearTimeout(e.timer),e.timer=void 0);this.idleHandlers.length=0}maybeEmitToolEdges(e){if(!e||typeof e!="object")return;let t=e.update;if(!t||typeof t!="object")return;let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:"";if(r!=="tool_call"&&r!=="tool_call_update")return;let o=typeof n.toolCallId=="string"&&n.toolCallId.length>0?n.toolCallId:void 0;if(!o)return;let i=typeof n.kind=="string"?n.kind:void 0;this.toolCallKind.note(o,i);let a=this.toolCallKind.effective(o,i);if(a===Qo&&Array.isArray(n.locations))for(let c of n.locations){if(!c||typeof c!="object")continue;let l=c.path;if(typeof l!="string"||l.length===0||this.filesEditedSeen.has(l))continue;this.filesEditedSeen.add(l);let p=c.line,f={path:l,toolCallId:o};typeof p=="number"&&(f.line=p),this.notifyChain("file.edited",f),this.reportIsolationBreach(l,o)}if(r!=="tool_call_update")return;let d=typeof n.status=="string"?n.status:void 0;if(d!=="completed"&&d!=="failed"||this.toolCompletionSeen.has(o))return;this.toolCompletionSeen.set(o,d);let u={toolCallId:o,status:d};a&&(u.kind=a),n.content!==void 0&&(u.content=n.content),Array.isArray(n.locations)&&(u.locations=n.locations),this.notifyChain("tool.completed",u)}notifyChain(e,t){let n=`lifecycle:${e}`;for(let r of this.transformChain)r.intercepts.has(n)&&r.connection.notify("hydra-acp/transformer/session_event",{event:e,sessionId:this.sessionId,payload:t}).catch(()=>{})}rewriteForClient(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.sessionId=="string"&&t.sessionId!==this.sessionId)return{...t,sessionId:this.sessionId}}return e}recordAndBroadcast(e,t,n){let r=this.rewriteForClient(t),o=!Ks(e,r),i=o?tl(e,r):r,a=Date.now(),d=o?We(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())n&&u.clientId===n||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 ge(new Error("no clients attached to handle permission request"),C.PermissionDenied);let n=this.rewriteForClient(e),r=pi(n),o=Ee(),{toolCall:i,options:a}=n??{};return new Promise((d,u)=>{let c=!1,l=[],p=0,f,m=this.sessionId,g=k=>{c||(c=!0,this.clearAttentionFlag("daemon",`permission:${o}`),this.permissionCallbacks.delete(o),k())},h=k=>k?.code===C.MethodNotFound;function y(k){if(c)return;let w=k.connection.request("session/request_permission",n);l.push({client:k}),p++,w.then(v=>{p--,g(()=>{let b=nl({toolCallId:r,result:v,resolver:k});for(let S of l)S.client.clientId!==k.clientId&&S.client.connection.notify("session/update",{sessionId:m,update:b}).catch(()=>{});d(v)})}).catch(v=>{if(p--,h(v)||(f=v),p===0&&!c){let b=f??ge(new Error("no client handled permission request"),C.PermissionDenied);g(()=>u(b))}})}this.setAttentionFlag("daemon",`permission:${o}`,{kind:"permission",toolCall:i??null,options:a??null}),this.permissionCallbacks.set(o,y);for(let k of t)y(k)})}async enqueuePrompt(e){return new Promise((t,n)=>{let r={kind:"internal",messageId:Ee(),enqueuedAt:Date.now(),cancelled:!1,task:e,resolve:t,reject:n};this.promptQueue.push(r),this.drainQueue()})}async enqueueUserPrompt(e,t,n,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:n,originator:i,clientId:e.clientId,prompt:o,enqueuedAt:Date.now(),cancelled:!1,resolve:d,reject:u},l=this.insertEntryAt(c,a);this.persistRewrite(),this.broadcastQueueAdded(c,{position:l}),this.drainQueue()})}promptCarriesSentBy(e){if(!e||typeof e!="object")return!1;let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t[ve];if(!n||typeof n!="object"||Array.isArray(n))return!1;let r=n.sentBy;return!!r&&typeof r=="object"}parseQueuePosition(e){if(!e||typeof e!="object")return"tail";let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return"tail";let n=t["hydra-acp"];if(!n||typeof n!="object"||Array.isArray(n))return"tail";let r=n.queuePosition;if(r==="head"||r==="tail")return r;if(r&&typeof r=="object"&&!Array.isArray(r)){let o=r.afterMessageId;if(typeof o=="string"&&o.length>0)return{afterMessageId:o}}return"tail"}insertEntryAt(e,t){let n=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;if(t==="head")return this.promptQueue.unshift(e),n;if(typeof t=="object"){let r=t.afterMessageId,o=this.promptQueue.findIndex(i=>i.messageId===r);if(o>=0)return this.promptQueue.splice(o+1,0,e),n+o+1}return this.promptQueue.push(e),n+this.promptQueue.length-1}persistRewrite(){let e=[];for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push(this.persistedFromEntry(n));let t=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Nt(t,e).catch(()=>{}))}persistedFromEntry(e){return{messageId:e.messageId,originator:{clientInfo:{...e.originator.name!==void 0?{name:e.originator.name}:{},...e.originator.version!==void 0?{version:e.originator.version}:{}}},prompt:e.prompt,enqueuedAt:e.enqueuedAt}}async drainQueue(){if(!this.promptInFlight){this.promptInFlight=!0,await new Promise(e=>setImmediate(e));try{for(;this.promptQueue.length>0&&!this.closing;){let e=this.promptQueue[0];if(e?.kind==="user"&&(await this.holdForUnsolicitedTurn(e),this.closing))break;let t=this.promptQueue.shift();if(!t)break;if(!t.cancelled){this.currentEntry=t,t.kind==="user"&&this.persistRewrite(),t.kind==="user"&&this.broadcastQueueRemoved(t.messageId,"started");try{let n=await this.runQueueEntry(t);t.resolve(n),await new Promise(r=>setImmediate(r))}catch(n){t.reject(n)}finally{this.currentEntry=void 0}}}}finally{this.promptInFlight=!1,this.dispatchIdle()}}}async runQueueEntry(e){if(e.kind==="internal")return this.closeUnsolicitedTurn("superseded"),e.task();this.broadcastPromptReceived(e);let t=mt(e.prompt).replace(/\s+$/,""),n=!t.includes(`
83
+ `)&&t.startsWith("/")?t.split(/\s+/)[0]??"":"",r=n.startsWith("/")?n.slice(1):"",o=r.length>0&&this.aliasableBareVerbs().has(r);if(n==="/model"||n==="/mode"||n==="/sessions"||n==="/help"||n==="/hydra"||o){let d;if(n==="/sessions")d=await this.handleSessionsCommand();else if(n==="/help")d=await this.handleHelpCommand();else if(n==="/mode")d=await this.handleModeCommand(t);else if(n==="/model")d=await this.handleModelCommand(t);else if(o){let u=t.slice(n.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;n&&this.agentAdvertisedCommands.length>0&&!this.agentKnowsSlashCommand(n)&&(i=Gs(e.prompt,ol));let a;this.agentTurnInFlight=!0;try{i=this.applyWorkspacePromptRewrite(i),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}finally{this.agentTurnInFlight=!1}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 ge(s,e){return s.code=e,s}var zu=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 Ju(s){let e=typeof s=="number"&&s>0?s:Bu;return Math.min(e,Uu)}function Vu(s){return typeof s!="string"?void 0:/Command running in background with ID: ([A-Za-z0-9_-]+)/.exec(s)?.[1]}function Qu(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.claudeCode;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n={};return t.toolName!==void 0&&(n.toolName=t.toolName),t.toolResponse&&typeof t.toolResponse=="object"&&(n.toolResponse=t.toolResponse),n}function Ks(s,e){if(s!=="session/update")return!1;let n=(e??{}).update?.sessionUpdate;return typeof n=="string"&&zu.has(n)}function Ku(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function Gu(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.id!==e[t]?.id||s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function Yu(s,e){if(s.length!==e.length)return!1;for(let t=0;t<s.length;t++)if(s[t]?.modelId!==e[t]?.modelId||s[t]?.name!==e[t]?.name||s[t]?.description!==e[t]?.description)return!1;return!0}function ht(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.modelId=="string"&&n.modelId.trim()||typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o={modelId:r};typeof n.name=="string"&&n.name.length>0&&(o.name=n.name),typeof n.description=="string"&&n.description.length>0&&(o.description=n.description),e.push(o)}return e}function Ot(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o={id:r};typeof n.name=="string"&&n.name.length>0&&(o.name=n.name),typeof n.description=="string"&&n.description.length>0&&(o.description=n.description),e.push(o)}return e}function Xu(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="available_modes_update")return null;let n=t.availableModes;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.id!="string"||i.id.length===0)continue;let a={id:i.id};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function Zu(s,e){let n=(e??{}).update??{},r=n.sessionUpdate;if(r==="agent_message_chunk"){let o=n.content??{};typeof o.text=="string"&&(s.chunks.push(o.text),s.messageChars+=o.text.length);return}if(r==="agent_thought_chunk"){let o=n.content??{};typeof o.text=="string"&&(s.thinkingChars+=o.text.length);return}if(r==="tool_call"){s.toolCalls++;return}if(r==="usage_update"){typeof n.used=="number"&&(s.lastUsed=n.used),typeof n.size=="number"&&(s.lastSize=n.size);return}}function el(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="available_commands_update")return null;let n=t.availableCommands??t.commands;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.name!="string"||i.name.length===0)continue;let a={name:i.name};typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function tl(s,e){if(s!=="session/update"||!e||typeof e!="object")return e;let t=e;return!t.update||typeof t.update!="object"||Array.isArray(t.update)||typeof t.update.messageId=="string"?e:{...e,update:{...t.update,messageId:Ee()}}}function kn(s,e){for(let t=0;t<s.length;t++){let n=s[t];if(!n||n.method!=="session/update")continue;if(n.params?.update?.messageId===e)return t}return-1}function pi(s){if(!s||typeof s!="object")return;let e=s.toolCall;if(!e||typeof e!="object")return;let t=e.toolCallId;return typeof t=="string"?t:void 0}function nl(s){let e=sl(s.result),t={sessionUpdate:"permission_resolved"};return s.toolCallId!==void 0&&(t.toolCallId=s.toolCallId),e&&(t.outcome=e,e.kind==="selected"&&typeof e.optionId=="string"&&(t.chosenOptionId=e.optionId)),t.resolvedBy=rl(s.resolver),t}function sl(s){if(!s||typeof s!="object")return;let e=s.outcome;if(!e||typeof e!="object")return;let t=e.kind;if(typeof t!="string")return;let n={kind:t},r=e.optionId;typeof r=="string"&&(n.optionId=r);let o=e.reason;return typeof o=="string"&&(n.reason=o),n}function rl(s){let e={clientId:s.clientId};return s.clientInfo?.name&&(e.name=s.clientInfo.name),s.clientInfo?.version&&(e.version=s.clientInfo.version),e}function mt(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var ol="\u200B";function gi(s,e){return s.map(t=>{if(t&&typeof t=="object"&&typeof t.text=="string"){let n=t;return{...n,text:e(n.text)}}return t})}function Gs(s,e){let t=s.findIndex(o=>o&&typeof o=="object"&&typeof o.text=="string");if(t<0)return s;let n=s[t],r=[...s];return r[t]={...n,text:`${e}${n.text}`},r}function Ys(s){return s==="session/prompt"?{stopReason:"stopped"}:{}}function il(s){return s==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function mi(s){let e=s.name&&s.name!==s.id?`${s.id} (${s.name}) \u2014 \u25B6 ${s.currentValue}`:`${s.id} \u2014 \u25B6 ${s.currentValue}`;if(s.options.length===0)return e;let t=Math.max(...s.options.map(r=>r.value.length)),n=s.options.map(r=>{let o=r.value===s.currentValue?"\u25B6":"\xB7",i=r.name&&r.name!==r.value,a=i?r.value.padEnd(t):r.value;return i?` ${o} ${a} ${r.name}`:` ${o} ${a}`});return`${e}
84
+ ${n.join(`
85
+ `)}`}function Xs(s,e){for(let t of s.split(/\r?\n/)){let n=t.trim();if(n)return n.length>e?`${n.slice(0,e)}\u2026`:n}}K();Ne();import*as vt from"fs/promises";import*as ny from"path";import{customAlphabet as cl}from"nanoid";import{z as E}from"zod";import{z as wt}from"zod";var al=wt.object({source:wt.string(),reason:wt.string(),raisedAt:wt.number(),payload:wt.unknown()}),vi=wt.array(al);import{z as V}from"zod";var bi=V.object({status:V.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:V.number(),iter:V.number().int().nonnegative().optional(),attempts:V.number().int().nonnegative().optional(),lastError:V.string().optional(),worker:V.object({upstreamSessionId:V.string(),pid:V.number().int().nonnegative()}).optional()}),Ht=V.object({goal:V.string().optional(),outcome:V.string().optional(),files_touched:V.array(V.string()).optional(),tools_used:V.array(V.string()).optional(),rejected_approaches:V.array(V.string()).optional(),open_threads:V.array(V.string()).optional(),decisions:V.array(V.string()).optional(),file_edit_intentions:V.array(V.string()).optional(),unresolved_errors:V.array(V.string()).optional(),tool_state:V.array(V.string()).optional()}),Si=200,Zs=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
79
86
  {
80
87
  "title": "short summary, max 80 chars",
81
88
  "synopsis": {
@@ -85,7 +92,7 @@ ${s.join(`
85
92
  "open_threads": ["work started but not finished"]
86
93
  }
87
94
  }
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=vt.safeParse(s.synopsis);o.success&&Nc(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:
95
+ Use empty arrays/strings where a field doesn't apply.`;function Ii(s){let e=s.trim();if(e.length===0)return;let t=kt(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=kt(e.slice(o,i+1)))}if(t===void 0){let o=Ci(e);o!==void 0&&(t=kt(o))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let o=n.title.trim();o.length>0&&(r.title=o.slice(0,Si))}if(n.synopsis!==void 0&&n.synopsis!==null){let o=Ht.safeParse(n.synopsis);o.success&&dl(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var er=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
89
96
  {
90
97
  "title": "short summary, max 80 chars",
91
98
  "goal": "the user's original ask",
@@ -97,59 +104,92 @@ Use empty arrays/strings where a field doesn't apply.`;function Co(n){let e=n.tr
97
104
  "unresolved_errors": ["errors left open at session end"],
98
105
  "tool_state": ["runtime state relevant for recall"]
99
106
  }
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 Nc(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 jc="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Bc=Hc(jc,16),Uc="hydra_lineage_";function St(){return`${Uc}${Bc()}`}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()}),Dc=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()}),Lc=M.object({previousUpstreamSessionId:M.string(),previousSummarizedThroughEntry:M.number().int().nonnegative().optional()}),qc=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()}),zc=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:vt.optional(),compactionState:ko.optional(),rollbackBreadcrumb:Lc.optional(),upstreamGenerations:M.array(qc).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(Dc).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 Jc(n){if(!ys.test(n))throw new Error(`unsafe session id: ${n}`)}var en=class{async write(e){Jc(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 zc.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 Wc=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 Wc.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 Vc}from"url";import*as It from"path";import*as nn from"fs";function Qc(){try{let n=It.dirname(Vc(import.meta.url));for(let e=0;e<8;e+=1){let t=It.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=It.dirname(n);if(s===n)break;n=s}}catch{}return"0.0.0"}var Y=Qc(),sn="hydra-acp-cat";var Gc=12e4;async function To(n,e,t){let s=n.timeoutMs??Gc,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=Yc(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=Kc(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}
107
+ Use empty arrays/strings where a field doesn't apply.`;function Ai(s){let e=s.trim();if(e.length===0)return;let t=kt(e);if(t===void 0){let u=e.indexOf("{"),c=e.lastIndexOf("}");u>=0&&c>u&&(t=kt(e.slice(u,c+1)))}if(t===void 0){let u=Ci(e);u!==void 0&&(t=kt(u))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let u=n.title.trim();u.length>0&&(r.title=u.slice(0,Si))}let o={},i=!1,a=["goal","outcome"];for(let u of a)if(typeof n[u]=="string"){let c=n[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(n[u])){let c=n[u],l=V.array(V.string()).safeParse(c);l.success&&c.length>0&&(o[u]=l.data,i=!0)}if(i&&(r.synopsis=o),!(r.title===void 0&&r.synopsis===void 0))return r}function kt(s){try{return JSON.parse(s)}catch{return}}function Ci(s){let e=s.indexOf("{");if(e<0)return;let t=0,n=!1,r=!1;for(let o=e;o<s.length;o++){let i=s[o];if(n){r?r=!1:i==="\\"?r=!0:i==='"'&&(n=!1);continue}if(i==='"'){n=!0;continue}if(i==="{")t++;else if(i==="}"&&(t--,t===0))return s.slice(e,o+1)}}function dl(s){return s.goal!==void 0&&s.goal.trim().length>0||s.outcome!==void 0&&s.outcome.trim().length>0||s.files_touched!==void 0&&s.files_touched.length>0||s.tools_used!==void 0&&s.tools_used.length>0||s.rejected_approaches!==void 0&&s.rejected_approaches.length>0||s.open_threads!==void 0&&s.open_threads.length>0||s.decisions!==void 0&&s.decisions.length>0||s.file_edit_intentions!==void 0&&s.file_edit_intentions.length>0||s.unresolved_errors!==void 0&&s.unresolved_errors.length>0||s.tool_state!==void 0&&s.tool_state.length>0}var ul="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",ll=cl(ul,16),fl="hydra_lineage_";function jt(){return`${fl}${ll()}`}var nr=E.object({name:E.string(),description:E.string().optional()}),sr=E.object({id:E.string(),name:E.string().optional(),description:E.string().optional()}),pl=E.object({modelId:E.string(),name:E.string().optional(),description:E.string().optional()}),rr=E.object({used:E.number().optional(),size:E.number().optional(),costAmount:E.number().optional(),costCurrency:E.string().optional(),cumulativeCost:E.number().optional()}),or=E.object({name:E.string(),version:E.string().optional()}),gl=E.object({path:E.string(),sourceCwd:E.string(),label:E.string(),requestedLabel:E.string().optional(),provider:E.string(),snapshot:E.string().optional(),line:E.string().optional(),vcs:E.record(E.string(),E.string()).optional(),clean:E.boolean().optional()}),ml=E.object({previousUpstreamSessionId:E.string(),previousSummarizedThroughEntry:E.number().int().nonnegative().optional()}),hl=E.object({upstreamSessionId:E.string(),agentId:E.string(),startedAt:E.string().optional(),endedAt:E.string().optional(),cost:E.number().nonnegative().optional(),inferred:E.boolean().optional()}),yl=E.object({version:E.literal(1),sessionId:E.string(),lineageId:E.string().optional(),upstreamSessionId:E.string(),importedFromSessionId:E.string().optional(),importedFromUpstreamSessionId:E.string().optional(),importedFromMachine:E.string().optional(),agentId:E.string(),cwd:E.string(),title:E.string().optional(),synopsis:Ht.optional(),compactionState:bi.optional(),rollbackBreadcrumb:ml.optional(),upstreamGenerations:E.array(hl).optional(),summarizedThroughEntry:E.number().int().nonnegative().optional(),agentArgs:E.array(E.string()).optional(),currentModel:E.string().optional(),currentMode:E.string().optional(),currentUsage:rr.optional(),agentCommands:E.array(nr).optional(),agentModes:E.array(sr).optional(),agentModels:E.array(pl).optional(),pendingHistorySync:E.boolean().optional(),pendingAgentSwap:E.string().optional(),parentSessionId:E.string().optional(),forkedFromSessionId:E.string().optional(),forkedFromMessageId:E.string().optional(),forkSynthesisState:E.enum(["running","failed"]).optional(),originatingClient:or.optional(),interactive:E.boolean().optional(),priority:E.number().int().nonnegative().optional(),forwardedEnv:E.record(E.string(),E.string()).optional(),workspace:gl.optional(),attentionFlags:vi.default([]).optional(),extensionState:E.record(E.string(),E.record(E.string(),E.unknown())).default({}).optional(),createdAt:E.string(),updatedAt:E.string()}),tr=/^[A-Za-z0-9_-]+$/;function wl(s){if(!tr.test(s))throw new Error(`unsafe session id: ${s}`)}var vn=class{async write(e){wl(e.sessionId);let t={version:1,...e};await fe(A.sessionFile(e.sessionId),t,{mode:384})}async read(e){if(!tr.test(e))return;let t=await ee(A.sessionFile(e));if(t!==void 0)try{return yl.parse(t)}catch{return}}async delete(e){if(tr.test(e)){try{await vt.unlink(A.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await vt.rmdir(A.sessionDir(e))}catch(t){let n=t;if(n.code!=="ENOENT"&&n.code!=="ENOTEMPTY")throw t}}}async findByLineageId(e){if(e.length===0)return;let t=await this.list().catch(()=>[]);for(let n of t)if(n.lineageId===e)return n}async list(){let e;try{e=await vt.readdir(A.sessionsDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let t=await Promise.all(e.map(r=>this.read(r).catch(()=>{}))),n=[];for(let r of t)r&&n.push(r);return n}};function ir(s){let e=new Date().toISOString(),t=s.createdAt??e,n=s.upstreamGenerations??(s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId,startedAt:t}]:[]);return{sessionId:s.sessionId,lineageId:s.lineageId,upstreamSessionId:s.upstreamSessionId,importedFromSessionId:s.importedFromSessionId,importedFromUpstreamSessionId:s.importedFromUpstreamSessionId,importedFromMachine:s.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:s.synopsis,summarizedThroughEntry:s.summarizedThroughEntry,compactionState:s.compactionState,rollbackBreadcrumb:s.rollbackBreadcrumb,upstreamGenerations:n,agentArgs:s.agentArgs,currentModel:s.currentModel,currentMode:s.currentMode,currentUsage:s.currentUsage,agentCommands:s.agentCommands,agentModes:s.agentModes,agentModels:s.agentModels,pendingHistorySync:s.pendingHistorySync,pendingAgentSwap:s.pendingAgentSwap,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,priority:s.priority,forwardedEnv:s.forwardedEnv,workspace:s.workspace,attentionFlags:s.attentionFlags??[],extensionState:s.extensionState??{},createdAt:t,updatedAt:s.updatedAt??e}}Ne();K();import*as re from"fs/promises";import*as oe from"path";K();import*as bn from"path";import{createHash as kl}from"crypto";var be=class extends Error{constructor(e,t){super(`provider "${e}" does not support ${t}; check capabilities().supports before calling`),this.name="WorkspaceUnsupportedError"}};function bt(s){let e=kl("sha256").update(bn.resolve(s)).digest("hex").slice(0,12);return bn.join(B(),"workspaces",e)}async function Sn(s,e,t=100){if(await e(s))return s;for(let n=2;n<=t;n+=1){let r=`${s}-${n}`;if(await e(r))return r}}function Ke(s,e=10){if(s.length<=e)return[...s];let t=s.slice(0,e),n=s.length-e;return[...t,`... and ${n} more`]}function ar(s){return s.changedPaths.length>0||s.recorded!==void 0&&s.recorded!==s.actual}function vl(s){let e=[];for(let t of s){if(t.changedPaths.length===0){e.push(`${t.relPath} (nested tree advanced to ${t.actual.slice(0,8)})`);continue}for(let n of t.changedPaths)e.push(`${t.relPath}/${n}`)}return e}function dr(s,e){let t=new Set(e.map(r=>r.relPath));return[...s.filter(r=>!t.has(r.replace(/\/$/,""))),...vl(e.filter(ar))]}function In(s){let e=s.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e.slice(0,64):"workspace"}var cr="copy",Ri=new Set([".git"]);function Dt(s){return`${s}.manifest.json`}async function xi(s){let e=new Map,t=[s];for(;t.length>0;){let n=t.pop();if(n===void 0)break;let r;try{r=await re.readdir(n,{withFileTypes:!0})}catch{continue}for(let o of r){let i=oe.join(n,o.name);if(!(n===s&&Ri.has(o.name))){if(o.isDirectory()){t.push(i);continue}if(o.isFile())try{let a=await re.stat(i);e.set(oe.relative(s,i),{size:a.size,mtimeMs:a.mtimeMs})}catch{continue}}}}return e}var An=class{kind=cr;capabilities(){return{cheapWorkspaces:!1,sharedHistory:!1,nonMutatingCapture:!0,conflictReporting:!1,locking:!1,requiresServer:!1,supports:{record:!1,integrate:!1,captureWorkingState:!1,changedPaths:!1,environmentNotes:!0,rematerialize:!1,nestedTrees:!1}}}async materializeNested(){return{ok:!0,count:0}}async retainSnapshot(){}async dropSnapshotRef(){}async rematerialize(e){return{ok:!1,reason:`copy provider retains nothing outside ${e.path}; it cannot be rebuilt`}}async createWorkspace(e){if(e.from!==void 0)return{ok:!1,reason:"copy provider cannot create from a snapshot; it records none"};let t=oe.resolve(e.sourceCwd),n=e.contentFrom!==void 0?oe.resolve(e.contentFrom):t;try{if(!(await re.stat(n)).isDirectory())return{ok:!1,reason:`${n} is not a directory`}}catch{return{ok:!1,reason:`${n} does not exist`}}let r=bt(t);try{await re.mkdir(r,{recursive:!0})}catch(u){return{ok:!1,reason:`could not create workspace root: ${String(u)}`}}let o=await Sn(In(e.label),async u=>re.access(oe.join(r,u)).then(()=>!1).catch(()=>!0));if(o===void 0)return{ok:!1,reason:`no free name available for "${e.label}"`};let i=oe.join(r,o);try{await re.cp(n,i,{recursive:!0,errorOnExist:!1,force:!0,filter:u=>{let c=oe.relative(n,u);if(c.length===0)return!0;let l=c.split(oe.sep)[0];return l===void 0||!Ri.has(l)}})}catch(u){return await re.rm(i,{recursive:!0,force:!0}).catch(()=>{}),{ok:!1,reason:`copy failed: ${String(u)}`}}let a=await xi(i),d={sourceCwd:t,label:o,createdAt:new Date().toISOString(),entries:Object.fromEntries(a)};return await fe(Dt(i),d,{pretty:!1}),{ok:!0,workspace:{path:i,sourceCwd:t,label:o,provider:this.kind}}}async removeWorkspace(e,t){if(!t.force){let n=await this.status(e);if(!n.clean)throw new Error(`workspace ${e.path} has ${n.changedPaths.length} changed path(s); pass force to remove`)}await re.rm(e.path,{recursive:!0,force:!0}),await re.rm(Dt(e.path),{force:!0})}async listWorkspaces(e){let t=bt(oe.resolve(e)),n;try{n=await re.readdir(t)}catch{return[]}let r=[];for(let o of n){if(o.endsWith(".manifest.json"))continue;let i=oe.join(t,o),a=await ee(Dt(i));a!==void 0&&r.push({path:i,sourceCwd:a.sourceCwd,label:a.label,provider:this.kind})}return r}async status(e){let t=await ee(Dt(e.path)),n=await xi(e.path);if(t===void 0)return{clean:!1,changedPaths:[...n.keys()].sort(),hasRecordedWork:!1};let r=[];for(let[o,i]of n){let a=t.entries[o];(a===void 0||a.size!==i.size||a.mtimeMs!==i.mtimeMs)&&r.push(o)}for(let o of Object.keys(t.entries))n.has(o)||r.push(o);return r.sort(),{clean:r.length===0,changedPaths:r,hasRecordedWork:!1}}async statusReport(e){let{changedPaths:t}=await this.status(e),n=t.length===0?["no changes since this copy was made"]:[`${t.length} changed file(s) since this copy was made:`,...Ke(t.map(r=>` ${r}`))];return n.push(`Not tracking ${O(e.sourceCwd)}: a copied directory has no shared history, so there is nothing to be in or out of sync with.`),n}async environmentNotes(e){return[`This directory is an isolated copy of ${e.sourceCwd}. It is not under version control: there is no history, no branches, and version-control commands will not behave as they would in the original.`,"Changes here are not automatically returned to the original directory."]}async captureWorkingState(){throw new be(this.kind,"captureWorkingState")}async record(){throw new be(this.kind,"record")}async attributeOrphan(e){let t=await ee(Dt(e));if(t?.sourceCwd!==void 0)return{path:e,sourceCwd:t.sourceCwd,label:t.label??oe.basename(e),provider:this.kind}}async discardLine(){return{ok:!0,dropped:0}}ownsLine(){return!1}async pruneStale(){}async changedPaths(){throw new be(this.kind,"changedPaths")}async integrate(){return{ok:!1,conflicts:[],declined:!0,reason:`the "${this.kind}" provider keeps no history, so there is nothing to integrate from`}}async currentState(){}async contentId(){}async currentLineName(){}async resolveRoot(e){return e}async resolveRetained(){}async contains(){return!1}async divergence(){}async changedPathsBetween(){return[]}async captureDelta(){throw new be(this.kind,"captureDelta")}async applyDelta(){return{ok:!1,reason:`the "${this.kind}" provider cannot reproduce a captured change`}}async resetTo(){return{ok:!1,reason:`the "${this.kind}" provider records no state to return to`}}async integrationInProgress(){return!1}async abortIntegration(){}async conflictedPaths(){return[]}async listNested(){return[]}async captureNested(){return[]}async reproduceNested(){return{applied:[],failed:[]}}async integrateNested(){return{applied:[],failed:[]}}async lock(){throw new be(this.kind,"lock")}async unlock(){throw new be(this.kind,"unlock")}};K();import{execFile as _i}from"child_process";import{randomBytes as Al}from"crypto";import*as He from"fs/promises";import*as $i from"os";import*as G from"path";function bl(s){let e=s.indexOf(" ");return e===-1?{key:s,value:""}:{key:s.slice(0,e),value:s.slice(e+1)}}function Ei(s){let e=[],t,n=()=>{t!==void 0&&(e.push(t),t=void 0)};for(let r of s.split(`
108
+ `)){let o=r.replace(/\r$/,"");if(o.length===0){n();continue}let{key:i,value:a}=bl(o);if(i==="worktree"){n(),t={path:a,bare:!1,detached:!1};continue}if(t!==void 0)switch(i){case"HEAD":t.head=a;break;case"branch":t.branch=a;break;case"bare":t.bare=!0;break;case"detached":t.detached=!0;break;case"locked":t.lockedReason=a;break;case"prunable":t.prunableReason=a;break;default:break}}return n(),e}function Pi(s){if(s===void 0)return;let e="refs/heads/";return s.startsWith(e)?s.slice(e.length):s}var Rn="git",Mi="hydra-acp:",ur="hydra",U=5e3,te=12e4,Cn=9e5;function Ti(s){return He.access(s).then(()=>!0).catch(()=>!1)}function F(s,e,t,n){return new Promise(r=>{_i("git",s,{cwd:e,timeout:t,maxBuffer:8*1024*1024,...n?{env:{...process.env,...n}}:{}},(o,i,a)=>{r({ok:!o,stdout:i??"",stderr:a??""})})})}function lr(s,e,t,n=te){return new Promise(r=>{let o=_i("git",s,{cwd:e,timeout:n,maxBuffer:67108864},(i,a,d)=>{r({ok:!i,stdout:a??"",stderr:d??""})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}function fr(s){let e=[];for(let t of s.split(`
109
+ `)){let n=t.replace(/\r$/,"");if(n.length<4)continue;let r=n.slice(3),o=r.indexOf(" -> ");e.push({code:n.slice(0,2),path:o===-1?r:r.slice(o+4)})}return e}var xn=class{kind=Rn;refRoot(e){return e.vcs?.repoRoot??e.sourceCwd}ownsLine(e){return e.startsWith(`${ur}/`)}capabilities(){return{cheapWorkspaces:!0,sharedHistory:!0,nonMutatingCapture:!0,conflictReporting:!0,locking:!0,requiresServer:!1,supports:{record:!0,integrate:!0,captureWorkingState:!0,changedPaths:!1,environmentNotes:!0,rematerialize:!0,nestedTrees:!0}}}async materializeNested(e,t){if(!await Ti(G.join(e.path,".gitmodules")))return{ok:!0,count:0};let r=await F(["submodule","update","--init","--recursive",...t?.discardLocal===!0?["--force"]:[]],e.path,Cn);if(!r.ok)return{ok:!1,count:0,reason:r.stderr.trim()||"git submodule update --init failed"};if(t?.discardLocal===!0){let a=await F(["submodule","foreach","--recursive","git","reset","--hard"],e.path,Cn);if(!a.ok)return{ok:!1,count:0,reason:a.stderr.trim()||"could not reset submodules"};let d=t.purgeIgnored===!0?"-ffdx":"-fd",u=await F(["submodule","foreach","--recursive","git","clean",d],e.path,Cn);if(!u.ok)return{ok:!1,count:0,reason:u.stderr.trim()||"could not clean submodules"}}let o=await F(["submodule","status","--recursive"],e.path,U);return{ok:!0,count:o.ok?o.stdout.split(`
110
+ `).filter(a=>a.trim().length>0).length:0}}async rematerialize(e){let t=e.vcs?.branch;if(t===void 0)return{ok:!1,reason:"workspace has no recorded branch to restore from"};let n=this.refRoot(e);if(!await Ti(n))return{ok:!1,reason:`source repository ${n} no longer exists`};let r=await F(["rev-parse","--verify","--quiet",`refs/heads/${t}`],n,U);if(!r.ok||r.stdout.trim().length===0)return{ok:!1,reason:`branch ${t} no longer exists in ${n}`};await F(["worktree","unlock",e.path],n,U),await F(["worktree","prune"],n,U);let o=await F(["worktree","add",e.path,t],n,te);return o.ok?{ok:!0,workspace:{...e,line:t,vcs:{...e.vcs??{},kind:"git",branch:t,repoRoot:n}}}:{ok:!1,reason:`could not restore worktree: ${o.stderr.trim()||"unknown error"}`}}async createWorkspace(e){let t=G.resolve(e.sourceCwd),n=await F(["rev-parse","--show-toplevel"],t,U);if(!n.ok)return{ok:!1,reason:`${t} is not a git repository (or git is unavailable)`};let r=n.stdout.trim();if(r.length===0)return{ok:!1,reason:`could not resolve the repository root for ${t}`};let o=await F(["rev-parse","HEAD"],r,U);if(!o.ok)return{ok:!1,reason:`${r} has no commits yet, so there is nothing to branch from`};let i=e.from??o.stdout.trim(),a=In(e.label),d=bt(t);try{await He.mkdir(d,{recursive:!0})}catch(f){return{ok:!1,reason:`could not create workspace root: ${String(f)}`}}let u=await Sn(a,async f=>await He.access(G.join(d,f)).then(()=>!0).catch(()=>!1)?!1:!(await F(["rev-parse","--verify","--quiet",`refs/heads/${ur}/${f}`],r,U)).ok);if(u===void 0)return{ok:!1,reason:`no free name available for "${a}"`};let c=G.join(d,u),l=`${ur}/${u}`,p=await F(["worktree","add","--no-track","-b",l,c,i],r,te);return p.ok?{ok:!0,workspace:{path:c,sourceCwd:t,label:u,provider:this.kind,snapshot:i,line:l,vcs:{kind:"git",branch:l,base:i,repoRoot:r}}}:{ok:!1,reason:`git worktree add failed: ${p.stderr.trim()||"unknown error"}`}}async removeWorkspace(e,t){if(!t.force){let o=await this.status(e);if(!o.clean)throw new Error(`workspace ${e.path} has ${o.changedPaths.length} changed path(s)${o.hasRecordedWork?" and unintegrated recorded work":""}; pass force to remove`)}let n=this.refRoot(e);await this.unlock(e).catch(()=>{});let r=await F(["worktree","remove","--force",e.path],n,te);t.discardLine===!0&&e.vcs?.branch!==void 0&&await F(["branch","-D",e.vcs.branch],n,U),r.ok||(await He.rm(e.path,{recursive:!0,force:!0}),await F(["worktree","prune"],n,U))}async listWorkspaces(e){let t=G.resolve(e),n=await F(["rev-parse","--show-toplevel"],t,U);if(!n.ok)return[];let r=n.stdout.trim(),o=await F(["worktree","list","--porcelain"],r,U);if(!o.ok)return[];let i=bt(t),a=[];for(let d of Ei(o.stdout)){if(G.dirname(d.path)!==i)continue;let u={kind:"git",repoRoot:r},c=Pi(d.branch);c!==void 0&&(u.branch=c),d.head!==void 0&&(u.head=d.head),d.lockedReason!==void 0&&(u.locked=d.lockedReason);let l=d.lockedReason?.startsWith(Mi)===!0;a.push({path:d.path,sourceCwd:t,label:G.basename(d.path),...l?{heldByUs:!0}:{},provider:this.kind,...c!==void 0?{line:c}:{},vcs:u})}return a}async status(e){let t=await F(["status","--porcelain","--untracked-files=all"],e.path,U);if(!t.ok)return{clean:!1,changedPaths:[],hasRecordedWork:!1};let n=fr(t.stdout),r=n.map(a=>a.path),o=n.some(({code:a})=>a!=="??"&&a[0]!==" "&&a[0]!=="?"),i=!1;if(e.snapshot!==void 0){let a=await F(["rev-list","--count",`${e.snapshot}..HEAD`],e.path,U);a.ok&&(i=Number.parseInt(a.stdout.trim(),10)>0)}return{clean:r.length===0&&!i,changedPaths:r,hasRecordedWork:i,hasStagedWork:o}}async lock(e,t){let n=this.refRoot(e);await F(["worktree","lock","--reason",`${Mi}${t}`,e.path],n,U)}async unlock(e){let t=this.refRoot(e);await F(["worktree","unlock",e.path],t,U)}async environmentNotes(e){let t=[],n=e.vcs?.branch;return t.push(`This directory is a git worktree of ${e.sourceCwd}${n!==void 0?`, on branch ${n}`:""}. Do not read or write ${e.sourceCwd} directly; paths under it refer to the corresponding file here. Prefer repo-relative paths, which are identical in both.`),t.push("`.git` here is a file, not a directory. That is normal for a worktree and does not need repairing."),await He.access(G.join(e.path,".gitmodules")).then(()=>!0).catch(()=>!1)&&t.push("Submodules here are initialized and checked out at the commits this tree records, which means each sits on a detached HEAD. That is normal and does not need repairing. Never re-add a submodule's contents as ordinary tracked files in the superproject: that silently corrupts the integration back to the source branch."),t}async statusReport(e){let t=[],n=await F(["status","--porcelain","--untracked-files=all"],e.path,U);if(n.ok){let r=fr(n.stdout);if(r.length===0)t.push("no uncommitted changes");else{let o=0,i=0,a=0;for(let{code:u}of r){if(u==="??"){a+=1;continue}u[0]!==" "&&u[0]!=="?"&&(o+=1),u[1]!==" "&&u[1]!=="?"&&(i+=1)}let d=[];o>0&&d.push(`${o} staged`),i>0&&d.push(`${i} unstaged`),a>0&&d.push(`${a} untracked`),t.push(`${d.join(", ")}:`),t.push(...Ke(r.map(u=>` ${u.code} ${u.path}`)))}}return t.push(...await this.syncLines(e)),t}async syncLines(e){if(e.vcs?.branch===void 0)return[];let[t,n]=await Promise.all([F(["rev-parse","HEAD"],e.sourceCwd,U),F(["rev-parse","HEAD"],e.path,U)]),r=t.stdout.trim(),o=n.stdout.trim();if(!t.ok||!n.ok||r.length===0||o.length===0)return[];let i=O(e.sourceCwd);if(r===o)return[`in sync with ${i}`];let a=await F(["rev-list","--left-right","--count",`${r}...${o}`],e.path,U),d=a.stdout.trim().split(/\s+/).map(p=>Number.parseInt(p,10)),u=d[0],c=d[1];if(!a.ok||u===void 0||c===void 0||!Number.isFinite(u)||!Number.isFinite(c))return[];let l=[];return u>0&&l.push(`${u} commit(s) behind ${i}. \`/hydra workspace sync\` brings them in; landing is fast-forward-only, so this also unblocks \`stop\`.`),c>0&&l.push(`${c} commit(s) recorded here and not landed yet.`),l}async captureWorkingState(e,t){let n=G.join($i.tmpdir(),`hydra-index-${process.pid}-${Al(6).toString("hex")}`),r={GIT_INDEX_FILE:n};try{let o=await F(["rev-parse","--verify","HEAD"],e,U),i=o.ok&&o.stdout.trim().length>0;if(i){let l=await F(["read-tree","HEAD"],e,te,r);if(!l.ok)throw new Error(`could not seed the snapshot index: ${l.stderr.trim()}`)}let a=await F(["add","-A"],e,te,r);if(!a.ok)throw new Error(`could not stage working state: ${a.stderr.trim()}`);let d=await F(["write-tree"],e,te,r);if(!d.ok||d.stdout.trim().length===0)throw new Error(`could not write tree: ${d.stderr.trim()}`);let u=["commit-tree",d.stdout.trim(),"-m",t];i&&u.push("-p",o.stdout.trim());let c=await F(u,e,te,r);if(!c.ok||c.stdout.trim().length===0)throw new Error(`could not create snapshot commit: ${c.stderr.trim()}`);return c.stdout.trim()}finally{await He.rm(n,{force:!0}).catch(()=>{})}}async retainSnapshot(e,t,n){let r=this.refRoot(e);await F(["update-ref","--create-reflog",t,n],r,U)}async dropSnapshotRef(e,t){let n=this.refRoot(e);await F(["update-ref","-d",t],n,U)}async currentState(e){let t=await F(["rev-parse","HEAD"],e,U),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async contentId(e,t){let n=await F(["rev-parse",`${t}^{tree}`],e,U),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async currentLineName(e){let t=await F(["rev-parse","--abbrev-ref","HEAD"],e,U),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async resolveRoot(e){let t=await F(["rev-parse","--show-toplevel"],e,U),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async resolveRetained(e,t){let n=await F(["rev-parse","--verify","--quiet",`${t}^{commit}`],this.refRoot(e),U),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async contains(e,t){return(await F(["merge-base","--is-ancestor",t.state,t.within],e,U)).ok}async divergence(e,t,n){let r=await F(["rev-list","--left-right","--count",`${t}...${n}`],e,U);if(!r.ok)return;let o=r.stdout.trim().split(/\s+/).map(d=>Number.parseInt(d,10)),i=o[0],a=o[1];if(!(i===void 0||a===void 0||!Number.isFinite(i)||!Number.isFinite(a)))return{ahead:i,behind:a}}async changedPathsBetween(e,t,n){let r=await F(["diff","--name-only",t,n],e,U);return r.ok?r.stdout.split(`
111
+ `).map(o=>o.replace(/\r$/,"").trim()).filter(o=>o.length>0):[]}async captureDelta(e,t,n){let r=await F(["diff","--binary","--ignore-submodules=all",t,n],e,te);if(r.ok)return r.stdout}async applyDelta(e,t,n){if(t.trim().length===0)return{ok:!0,alreadyPresent:!0};let r=n?.stage===!0?["--index"]:[],o=await lr(["apply",...r],e,t);if(o.ok)return{ok:!0};if(n?.tolerant!==!0)return{ok:!1,reason:o.stderr.trim()||"the change did not apply"};if((await lr(["apply","--reverse","--check"],e,t)).ok)return{ok:!0,alreadyPresent:!0};let a=await lr(["apply","--3way"],e,t);return a.ok?{ok:!0}:{ok:!1,reason:a.stderr.trim()||"the change overlaps what is already there"}}async resetTo(e,t,n){let r=await F(["reset","--hard",t],e,te);if(!r.ok)return{ok:!1,reason:r.stderr.trim()||"could not return to that state"};let o=await F(["clean",n?.purgeIgnored===!0?"-ffdx":"-fd"],e,te);if(!o.ok)return{ok:!1,reason:o.stderr.trim()||"returned to that state but could not remove extra files"};let i=await this.materializeNested({path:e,sourceCwd:e,label:"",provider:this.kind},{discardLocal:!0,...n?.purgeIgnored===!0?{purgeIgnored:!0}:{}});return i.ok?{ok:!0}:{ok:!1,reason:i.reason??"could not reset nested trees"}}async integrationInProgress(e){return(await F(["rev-parse","-q","--verify","MERGE_HEAD"],e,U)).ok}async abortIntegration(e){await F(["merge","--abort"],e,te)}async conflictedPaths(e){let t=await F(["diff","--name-only","--diff-filter=U"],e,U);return t.ok?t.stdout.split(`
112
+ `).map(n=>n.replace(/\r$/,"").trim()).filter(n=>n.length>0):[]}async record(e,t){let n=await F(["add","-A"],e.path,te);if(!n.ok)throw new Error(`could not stage ${e.path}: ${n.stderr.trim()||"unknown error"}`);let r=await this.status(e),o=await this.currentState(e.path);if(r.changedPaths.length===0){if(o===void 0)throw new Error(`could not read the state of ${e.path}`);return o}let i=await F(["commit","-m",t],e.path,te);if(!i.ok)throw new Error(`could not record ${e.path}: ${i.stderr.trim()||i.stdout.trim()||"unknown error"}`);let a=await this.currentState(e.path);if(a===void 0)throw new Error(`recorded ${e.path} but could not read the resulting state`);return a}async attributeOrphan(e){let t=await F(["rev-parse","--path-format=absolute","--git-common-dir"],e,U),n=t.stdout.trim();if(!t.ok||n.length===0)return;let r=G.dirname(n),o=await this.currentLineName(e);return{path:e,sourceCwd:r,label:G.basename(e),provider:this.kind,...o!==void 0?{line:o}:{},vcs:{repoRoot:r,...o!==void 0?{branch:o}:{}}}}async discardLine(e,t){let n=this.refRoot(e),o=(await this.divergence(n,"HEAD",t))?.behind??0,i=await F(["branch","-D",t],n,U);return i.ok?{ok:!0,dropped:o}:{ok:!1,dropped:o,reason:i.stderr.trim()||"could not discard the line"}}async pruneStale(e){await F(["worktree","prune"],this.refRoot(e),U)}async changedPaths(){throw new be(this.kind,"changedPaths")}async integrate(e){let{into:t,from:n}=e,r=await this.currentState(t);if(r===void 0)return{ok:!1,conflicts:[],declined:!0,reason:`cannot read the state of ${t}`};if(await this.contains(t,{state:n,within:r}))return{ok:!0,snapshot:r,alreadyUpToDate:!0};if(e.fastForwardOnly===!0&&!await this.contains(t,{state:r,within:n}))return{ok:!1,conflicts:[],declined:!0,reason:`${t} cannot simply advance to that state; it has moved on independently`};let o=e.fastForwardOnly===!0?["merge","--ff-only",n]:["merge","--no-edit","-m",e.message??"hydra: integrate",n],i=await F(o,t,te);if(i.ok){let u=await this.currentState(t);return u===void 0?{ok:!1,conflicts:[],reason:"integrated but could not read the resulting state"}:{ok:!0,snapshot:u}}let a=await this.conflictedPaths(t),d=await this.integrationInProgress(t);return a.length===0&&!d?{ok:!1,conflicts:[],declined:!0,reason:i.stderr.trim()||"the integration was refused"}:(e.onConflict==="abort"&&await this.abortIntegration(t),{ok:!1,conflicts:a})}async listNested(e){let t=await F(["submodule","status","--recursive"],e,te);if(!t.ok)return[];let n=[];for(let r of t.stdout.split(`
113
+ `)){let o=r.replace(/\r$/,"");if(o.trim().length===0||(o[0]??" ")==="-")continue;let a=o.slice(1),d=a.indexOf(" ");if(d<=0)continue;let u=a.slice(d+1).replace(/\s+\(.*\)\s*$/,"").trim();if(u.length===0||!Cl(e,u))continue;let c=G.join(e,u),[l,p,f]=await Promise.all([this.currentState(c),F(["rev-parse",`HEAD:${u}`],e,U),F(["status","--porcelain","--untracked-files=all"],c,U)]);if(l===void 0)continue;let m=p.ok?p.stdout.trim():"";n.push({relPath:u,actual:l,...m.length>0?{recorded:m}:{},changedPaths:f.ok?fr(f.stdout).map(g=>g.path):[]})}return n}async captureNested(e,t){let n=[];for(let r of t){if(!ar(r))continue;if(r.changedPaths.length===0){n.push(r);continue}let o=G.join(e,r.relPath),i=await this.captureWorkingState(o,"hydra: nested work carried into workspace").catch(()=>{});if(i===void 0){n.push(r);continue}let a=await this.captureDelta(o,r.actual,i);n.push(a===void 0?r:{...r,delta:a})}return n}async reproduceNested(e,t,n){let r=[],o=[];for(let i of n){let a=G.join(e,i.relPath),d=G.join(t,i.relPath),u=await this.alignNested(a,d,i.actual);if(u!==void 0){o.push({path:i.relPath,reason:u});continue}if(i.delta!==void 0){let c=await this.applyDelta(a,i.delta);if(!c.ok){o.push({path:i.relPath,reason:c.reason??"changes did not apply"});continue}}r.push(i.relPath)}return{applied:r,failed:o}}async integrateNested(e,t,n){let r=[],o=[],i=new Map(n.map(u=>[u.relPath,u])),a=await this.listNested(e),d=new Set([...a.map(u=>u.relPath),...i.keys()]);for(let u of[...d].sort()){let c=a.find(h=>h.relPath===u),l=i.get(u);if(c===void 0){o.push({path:u,reason:"not populated in the receiving tree"});continue}let p=c.recorded!==void 0&&c.recorded!==c.actual,f=l?.delta!==void 0;if(!p&&!f)continue;if(c.changedPaths.length>0){o.push({path:u,reason:`it has ${c.changedPaths.length} uncommitted change(s) of its own, and nothing can tell those apart from what was integrated`});continue}let m=G.join(e,u),g=G.join(t,u);if(p&&c.recorded!==void 0){let h=await this.alignNested(m,g,c.recorded);if(h!==void 0){o.push({path:u,reason:h});continue}}if(l?.delta!==void 0){let h=await this.applyDelta(m,l.delta);if(!h.ok){o.push({path:u,reason:h.reason??"the uncommitted changes there did not apply"});continue}}r.push(u)}return{applied:r,failed:o}}async alignNested(e,t,n){let r=await this.currentState(e);if(r===void 0)return"not populated here";if(r===n)return;if(!(await F(["cat-file","-e",`${n}^{commit}`],e,U)).ok&&!(await F(["fetch","--no-tags",t,n],e,Cn)).ok)return`could not transfer ${n.slice(0,8)} from the other copy`;if(!(await F(["checkout","--detach",n],e,te)).ok)return`could not move to ${n.slice(0,8)}`}};function Cl(s,e){if(G.isAbsolute(e))return!1;let t=G.resolve(s),n=G.resolve(t,e);return n!==t&&n.startsWith(t+G.sep)}var xl=Rn,Rl=new Map([[Rn,new xn],[cr,new An]]);function X(s){return Rl.get(s??xl)}var En="refs/hydra";function Lt(s){let e=`${En}/workspaces/${s}`;return{autosave:`${e}/autosave`,start:`${e}/start`,baseline:`${e}/baseline`}}function Fi(s){return`${En}/landing/${s}`}function Ni(s){return`${En}/sync/${s}`}function Oi(s,e){return`${En}/retired/${s}-${e.slice(0,12)}`}function Hi(s){let e=Lt(s);return[e.autosave,e.start,e.baseline]}async function ji(s){let{source:e,ws:t,startSnapshotRef:n,baselineRef:r,retainRef:o,provider:i}=s;if(i===void 0)throw new Error("no provider available to inspect the source tree");let a=await i.status({...t,path:e}).catch(()=>{}),d="";for(let l of[r,n]){if(l===void 0)continue;let p=await i.resolveRetained(t,l).catch(()=>{});if(p!==void 0){d=p;break}}let u=a===void 0||a.changedPaths.length>0;if(d.length===0){if(u)throw new Error(`${e} has uncommitted changes but this workspace has no start anchor, so its copy of your work cannot be told apart from edits you made since. Refusing rather than reporting a conflict that is not yours. Commit or stash the source, then retry.`);d=await i.currentState(e).catch(()=>{})??""}if(!u)return{clean:!0,base:d};if(i.capabilities().supports.captureWorkingState!==!0)throw new Error(`${e} has uncommitted changes and this provider cannot snapshot them, so they cannot be preserved across the landing. Commit or stash them first.`);let c=await i.captureWorkingState(e,"hydra: source state before landing").catch(()=>{});if(c===void 0)throw new Error(`could not snapshot the uncommitted changes in ${e}, so refusing to touch them`);return await i.retainSnapshot({...t,path:e},o,c),{clean:!1,snapshot:c,base:d,retainedRef:o}}async function Bt(s){let{source:e,capture:t,provider:n}=s;if(t.clean||t.snapshot===void 0||n===void 0)return!0;let r=await n.captureDelta(e,t.base,t.snapshot).catch(()=>{});return r===void 0?!1:(await n.applyDelta(e,r,{tolerant:!0})).ok}async function Di(s){s.capture.retainedRef===void 0||s.provider===void 0||await s.provider.dropSnapshotRef({...s.ws,path:s.source},s.capture.retainedRef).catch(()=>{})}Ne();import{execFile as El}from"child_process";import*as Me from"fs/promises";import*as me from"path";var Pl=".hydra/worktree.json",Ml=".worktreeinclude",Tl=120;async function Pn(s){let e=await ee(me.join(s,Pl))??{},t=new Set(Array.isArray(e.carry)?e.carry:[]),n=await Me.readFile(me.join(s,Ml),"utf8").catch(()=>{});if(n!==void 0)for(let o of n.split(`
114
+ `)){let i=o.trim();i.length===0||i.startsWith("#")||i.startsWith("!")||i.includes("*")||i.includes("?")||t.add(i)}let r={};return t.size>0&&(r.carry=[...t]),typeof e.postCreate=="string"&&(r.postCreate=e.postCreate),typeof e.preRemove=="string"&&(r.preRemove=e.preRemove),typeof e.hookTimeoutSeconds=="number"&&(r.hookTimeoutSeconds=e.hookTimeoutSeconds),r}async function pr(s,e,t){let n=[],r=[],o=me.resolve(s),i=me.resolve(e);for(let a of t){let d=me.resolve(o,a),u=me.resolve(i,a);if(!d.startsWith(o+me.sep)||!u.startsWith(i+me.sep)){r.push(a);continue}if(await Me.access(u).then(()=>!0).catch(()=>!1)){r.push(a);continue}let l=await Me.stat(d).catch(()=>{});if(l===void 0){r.push(a);continue}try{await Me.mkdir(me.dirname(u),{recursive:!0}),await Me.cp(d,u,{recursive:l.isDirectory()}),n.push(a)}catch{r.push(a)}}return{copied:n,skipped:r}}async function Mn(s,e){let t=JSON.stringify({path:e.workspacePath,sourceCwd:e.sourceCwd,label:e.label,...e.sessionId!==void 0?{sessionId:e.sessionId}:{}}),n=(e.timeoutSeconds??Tl)*1e3;return new Promise(r=>{let o=El("/bin/sh",["-c",s],{cwd:e.workspacePath,timeout:n,maxBuffer:8388608,env:{...process.env,HYDRA_WORKSPACE_PATH:e.workspacePath,HYDRA_SOURCE_CWD:e.sourceCwd,HYDRA_WORKSPACE_LABEL:e.label,...e.sessionId!==void 0?{HYDRA_SESSION_ID:e.sessionId}:{}}},(i,a,d)=>{if(i){let u=(d||i.message||"").trim().slice(0,500);r({ok:!1,reason:u.length>0?u:"hook failed"});return}r({ok:!0})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}K();Ne();import*as je from"fs/promises";import{z as Te}from"zod";var _l=Te.object({version:Te.literal(1),agentId:Te.string(),upstreamSessionId:Te.string(),deletedAt:Te.string(),upstreamUpdatedAt:Te.string().optional(),cwd:Te.string().optional(),title:Te.string().optional(),reason:Te.enum(["user","expired"]).optional(),interactive:Te.boolean().optional()}),Tn=class{async add(e){let t={version:1,...e};await fe(A.tombstoneFile(e.agentId,e.upstreamSessionId),t,{mode:384})}async has(e,t){try{return await je.access(A.tombstoneFile(e,t)),!0}catch{return!1}}async read(e,t){let n=A.tombstoneFile(e,t),r=await ee(n);if(r===void 0)return await this.has(e,t)?{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}:void 0;try{return _l.parse(r)}catch{return{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}}}async remove(e,t){try{await je.unlink(A.tombstoneFile(e,t))}catch(n){if(n.code!=="ENOENT")throw n}try{await je.rmdir(A.tombstoneAgentDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}}async list(e){if(e!==void 0)return this.listForAgent(e);let t;try{t=await je.readdir(A.tombstonesDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}n.push(...await this.listForAgent(o))}return n}async listForAgent(e){let t;try{t=await je.readdir(A.tombstoneAgentDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}let i=await this.read(e,o);i&&n.push(i)}return n}};function Li(s,e){return s.reason==="user"||e===void 0?!1:s.upstreamUpdatedAt===void 0?!0:e>s.upstreamUpdatedAt}import*as Xi from"fs/promises";import{fileURLToPath as $l}from"url";import*as Ut from"path";import*as _n from"fs";function Fl(){try{let s=Ut.dirname($l(import.meta.url));for(let e=0;e<8;e+=1){let t=Ut.join(s,"package.json");if(_n.existsSync(t)){let r=JSON.parse(_n.readFileSync(t,"utf8"));if(typeof r.version=="string"&&r.version.length>0&&(typeof r.name!="string"||r.name.includes("hydra-acp")))return r.version}let n=Ut.dirname(s);if(n===s)break;s=n}}catch{}return"0.0.0"}var ie=Fl(),$n="hydra-acp-cat";var Nl=12e4;async function Ui(s,e,t){let n=s.timeoutMs??Nl,r,o,i=!1;try{let a=(async()=>{r=ze.spawn({agentId:s.agentId,cwd:s.cwd,plan:s.plan,logger:s.logger});let d=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:{name:"hydra-synopsis",version:ie}}),u=await r.connection.request("session/new",{cwd:s.cwd,mcpServers:[]}),c=u.sessionId;if(typeof c!="string"){s.logger?.warn(`synopsis: agent ${s.agentId} returned non-string sessionId from session/new`),s.onFailure?.(`agent ${s.agentId} did not return a sessionId from session/new`);return}if(s.onWorkerSpawned?.(c,r.pid),s.modelId){let m=Hl(u);if(m.size===0||m.has(s.modelId)){let g=r.connection;try{await Je({request:(h,y)=>g.request(h,y),sessionId:c,modelId:s.modelId,verb:dt(u),logger:s.logger})}catch(h){s.logger?.warn(`synopsis: agent ${s.agentId} rejected model change to ${JSON.stringify(s.modelId)}: ${h.message}; continuing on default`)}}else s.logger?.warn(`synopsis: model ${JSON.stringify(s.modelId)} not advertised by agent ${s.agentId} (have [${[...m].join(", ")}]); continuing on default`)}let l=[];r.connection.onNotification("session/update",m=>{let g=Ol(m);g.length>0&&l.push(g)}),await r.connection.request("session/prompt",{sessionId:c,prompt:[{type:"text",text:e}]});let p=l.join(""),f=t(p);if(!f){let m=JSON.stringify(p.slice(0,200));s.logger?.warn(`synopsis: agent ${s.agentId} reply did not parse (replyLen=${p.length} preview=${m})`);let g=p.slice(0,120).replace(/\s+/g," ").trim();s.onFailure?.(`agent ${s.agentId} returned unparseable JSON (${p.length} chars): ${g}${p.length>120?"\u2026":""}`)}return f})();return await new Promise((d,u)=>{o=setTimeout(()=>{i=!0,s.logger?.warn(`synopsis: agent ${s.agentId} timed out after ${n}ms`),s.onFailure?.(`agent ${s.agentId} timed out after ${n}ms`),d(void 0)},n),o.unref?.(),a.then(c=>{o&&clearTimeout(o),i||d(c)},c=>{o&&clearTimeout(o),i||u(c)})})}catch(a){let d=a.message;s.logger?.warn(`synopsis: agent ${s.agentId} failed: ${d}`),s.onFailure?.(`agent ${s.agentId} failed: ${d}`);return}finally{o&&clearTimeout(o),r&&await r.kill().catch(()=>{})}}async function Fn(s){let e=gt(s.history,{maxChars:s.maxTranscriptChars}),t=s.sessionId!==void 0?`[hydra-acp title-regen worker for session ${s.sessionId}]`:"[hydra-acp title-regen worker]",n=e.length>0?`${t}
101
115
 
102
116
  ${e}
103
117
 
104
- ${gs}`:`${t}
118
+ ${Zs}`:`${t}
105
119
 
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}
120
+ ${Zs}`;return Ui(s,n,Ii)}async function Wi(s){let e=gt(s.history,{maxChars:s.maxTranscriptChars}),t=s.sessionId!==void 0?`[hydra-acp compaction worker for session ${s.sessionId}]`:"[hydra-acp compaction worker]",n=e.length>0?`${t}
107
121
 
108
122
  ${e}
109
123
 
110
- ${hs}`:`${t}
124
+ ${er}`:`${t}
111
125
 
112
- ${hs}`;return To(n,s,xo)}function Kc(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 Yc(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 Xc(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 Xc(n).map(e=>e.name)}function Zc(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 Zc(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 eu=2,on=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??eu}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 au}from"fs";import{createGunzip as du,gzip as cu,gunzip as uu}from"zlib";import{createInterface as lu}from"readline";import{promisify as Wo}from"util";function Do(n){return n==="summary"?"summary":"inline"}var ks=256,tu=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],nu=["content","stdout","stderr"];function Lo(n,e){return e!=="summary"?n:n.map(su)}function su(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 tu)a[u]!==void 0&&(d[u]=a[u]);for(let u of nu)typeof a[u]=="string"&&(d[u]=an(a[u]));o.rawOutput=d}return{...n,params:{...t,update:o}}}function ru(n){return!!n&&typeof n=="object"&&!Array.isArray(n)&&n.type==="diff"}function qo(n){if(ru(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 ou=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 iu(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(!iu(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<=ou)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 fu=Wo(cu),pu=Wo(uu),mu=/^history\.jsonl\.(\d+)(\.gz)?$/,fe=/^[A-Za-z0-9_-]+$/,gu=1e3,hu=1e7,yu=10,dn=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??gu,this.archiveMaxBytes=e.archiveMaxBytes??hu,this.archiveTiers=e.archiveTiers??yu}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(`
126
+ ${er}`;return Ui(s,n,Ai)}function Ol(s){if(!s||typeof s!="object")return"";let e=s.update;if(!e||typeof e!="object")return"";let t=e;if(t.sessionUpdate!=="agent_message_chunk")return"";let n=t.content;return n&&typeof n.text=="string"?n.text:""}function Hl(s){let e=new Set;Bi(e,s.availableModels);let t=s.models;return t&&typeof t=="object"&&!Array.isArray(t)&&Bi(e,t.availableModels),e}function Bi(s,e){if(Array.isArray(e)){for(let t of e)if(t&&typeof t=="object"){let n=t.modelId??t.value??t.id;typeof n=="string"&&n.length>0&&s.add(n)}}}function jl(s){let e=new Map;for(let t of Qi(s).values())e.set(t.toolName,(e.get(t.toolName)??0)+1);return[...e.entries()].map(([t,n])=>({name:t,count:n})).sort((t,n)=>n.count-t.count||t.name.localeCompare(n.name))}function Ji(s){return jl(s).map(e=>e.name)}function Dl(s){let e=new Map;for(let t of Qi(s).values())for(let n of t.paths){let r=e.get(n);r===void 0&&(r=new Map,e.set(n,r)),r.set(t.toolName,(r.get(t.toolName)??0)+1)}return[...e.entries()].map(([t,n])=>{let r=[...n.entries()].map(([i,a])=>({name:i,count:a})).sort((i,a)=>a.count-i.count||i.name.localeCompare(a.name)),o=r.reduce((i,a)=>i+a.count,0);return{path:t,count:o,byTool:r}}).sort((t,n)=>n.count-t.count||t.path.localeCompare(n.path))}function Vi(s){return Dl(s).map(e=>e.path)}function Qi(s){let e=new Map,t=0;for(let n of s){let o=n.params?.update;if(!o)continue;let i=o.sessionUpdate;if(i!=="tool_call"&&i!=="tool_call_update")continue;if(i==="tool_call"){let d=typeof o.toolCallId=="string"&&o.toolCallId.length>0?o.toolCallId:`__synth_${t++}`,u=e.get(d);u===void 0?(u={toolName:qi(o),paths:new Set},e.set(d,u)):u.toolName=qi(o);for(let c of zi(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 zi(o.rawInput,o.locations))a.paths.add(d)}return e}function qi(s){return typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function zi(s,e){let t=new Set;if(s&&typeof s=="object"&&!Array.isArray(s)){let n=s;typeof n.file_path=="string"?t.add(n.file_path):typeof n.path=="string"&&t.add(n.path);let r=n.edits;if(Array.isArray(r)){for(let o of r)if(o&&typeof o=="object"){let i=o.file_path;typeof i=="string"&&t.add(i)}}}for(let n of Ko(e))t.add(n);return t}K();var Ll=2,Nn=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??Ll}opts;queued={};inflight=new Map;stopped=!1;maxConcurrent;schedule(e){this.stopped||this.inflight.has(e)||e in this.queued||(this.queued[e]={kind:"title"},this.drain())}scheduleCompaction(e,t){if(this.stopped)return;let n=t?.targetAgentId;if(this.inflight.has(e))return;let r=this.queued[e];if(r&&r.kind==="title"){this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}};return}this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}},this.drain()}size(){return{queued:Object.keys(this.queued).length,inflight:this.inflight.size}}async flush(e){let t=Date.now()+e;for(;Object.keys(this.queued).length>0||this.inflight.size>0;){let n=t-Date.now();if(n<=0)return;let r=[...this.inflight.values()];if(r.length===0){await new Promise(o=>{setTimeout(o,25).unref?.()});continue}await Promise.race([Promise.race(r),new Promise(o=>{setTimeout(o,n).unref?.()})])}}async shutdown(){this.stopped=!0,this.queued={},await Promise.allSettled([...this.inflight.values()])}drain(){if(!this.stopped)for(;this.inflight.size<this.maxConcurrent&&Object.keys(this.queued).length>0;){let t=Object.keys(this.queued)[0];if(!t)return;let n=this.queued[t];delete this.queued[t];let r=this.runOne(t,n).finally(()=>{this.inflight.delete(t),this.drain()});this.inflight.set(t,r)}}async runOne(e,t){let n=t.kind,r=t.targetAgentId;try{let o=await this.opts.store.read(e);if(!o){this.opts.logger?.info(`synopsis: session ${e} record missing; skipping`);return}let i=await this.opts.histories.load(e,{maxEntries:1/0}),a=o.summarizedThroughEntry;if(a!==void 0&&i.length===a){this.opts.logger?.info(`synopsis: skip ${e} (history unchanged at ${i.length})`);return}a!==void 0&&i.length<a&&this.opts.logger?.warn(`synopsis: watermark ahead of history (last=${a} history=${i.length}) for ${e} \u2014 re-baselining`);let d=n==="compaction"?r??this.opts.compactionAgent??o.agentId:this.opts.synopsisAgent??o.agentId,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 ye(u,[],{npmRegistry:this.opts.npmRegistry}),l=this.opts.compactionAgent===void 0&&r===void 0,p=n==="compaction"?this.opts.compactionModel??(l?o.currentModel:void 0):this.opts.synopsisModel,f=A.sessionDir(e);if(await Xi.mkdir(f,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(p??"(default)")} cwd=${f}`),n==="compaction"){let m=this.opts.compactionMaxIterations??3,g=0,h=a??0,y,k=0,w,v=Date.now(),b={targetAgentId:r},S=R=>this.opts.onCompactionStateChange?.(e,R,b)??Promise.resolve(),x=R=>{this.opts.broadcastHydraCompaction?.(e,R,b)};await S({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 R=await this.opts.histories.load(e,{maxEntries:1/0});if(R.length===h)break;let P=await Wi({agentId:d,cwd:f,plan:c,history:R,modelId:p,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:(_,N)=>{S({status:"running",requestedAt:v,iter:g,worker:{upstreamSessionId:_,pid:N??0}})},onFailure:_=>{w=_}});if(P){let _=Ki(P.synopsis,R);_&&Gi(_)&&(await this.opts.persistSynopsis(e,_,R.length),y=_,k=R.length,w=void 0,await S({status:"running",requestedAt:v,iter:g}),x({sessionUpdate:"hydra_compaction",phase:"iteration",iter:g,historyLen:R.length}),await this.opts.onSynthesisArtifact?.(e,_,k,r),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${g} fields=${Yi(_)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${g} returned no result`);if(h=R.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=${k} iterations=${g}`);else{g>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${m} without producing artifact sessionId=${e}: ${w??"no reason captured"}`);let R=w??(g===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${g} iteration(s)`);await S({status:"failed",requestedAt:v,iter:g,lastError:R}),x({sessionUpdate:"hydra_compaction",phase:"failed",error:R})}}catch(R){let P=R instanceof Error?R.message:String(R);this.opts.logger?.warn(`synopsis: compaction threw for sessionId=${e}: ${P}`),await S({status:"failed",requestedAt:v,iter:g,lastError:P}),this.opts.broadcastHydraCompaction?.(e,{sessionUpdate:"hydra_compaction",phase:"failed",error:P},{targetAgentId:r})}}else{let m=await Fn({agentId:d,cwd:f,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=Ki(m.synopsis,i);g&&Gi(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=${Yi(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 Ki(s,e){let t=Vi(e),n=Ji(e);return s?{...s,files_touched:t.length>0?t:s.files_touched,tools_used:n.length>0?n:s.tools_used}:t.length===0&&n.length===0?void 0:{files_touched:t.length>0?t:void 0,tools_used:n.length>0?n:void 0}}function Gi(s){return!!(s.goal&&s.goal.trim().length>0||s.outcome&&s.outcome.trim().length>0||s.files_touched&&s.files_touched.length>0||s.tools_used&&s.tools_used.length>0||s.rejected_approaches&&s.rejected_approaches.length>0||s.open_threads&&s.open_threads.length>0)}function Yi(s){let e=[];return s.goal&&e.push("goal"),s.outcome&&e.push("outcome"),s.files_touched&&s.files_touched.length>0&&e.push(`files=${s.files_touched.length}`),s.tools_used&&s.tools_used.length>0&&e.push(`tools=${s.tools_used.length}`),s.rejected_approaches&&s.rejected_approaches.length>0&&e.push(`rejected=${s.rejected_approaches.length}`),s.open_threads&&s.open_threads.length>0&&e.push(`open=${s.open_threads.length}`),`[${e.join(",")}]`}K();import*as z from"fs/promises";import{createReadStream as Vl}from"fs";import{createGunzip as Ql,gzip as Kl,gunzip as Gl}from"zlib";import{createInterface as Yl}from"readline";import{promisify as ra}from"util";function Zi(s){return s==="summary"?"summary":"inline"}var gr=256,Bl=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],Ul=["content","stdout","stderr"];function ea(s,e){return e!=="summary"?s:s.map(Wl)}function Wl(s){if(s.method!=="session/update")return s;let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return s;let t=e,n=t.update;if(!n||typeof n!="object"||Array.isArray(n))return s;let r=n;if(r.sessionUpdate!=="tool_call"&&r.sessionUpdate!=="tool_call_update")return s;let o={...r};Array.isArray(r.content)&&(o.content=r.content.map(ta));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=On(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let u of Bl)a[u]!==void 0&&(d[u]=a[u]);for(let u of Ul)typeof a[u]=="string"&&(d[u]=On(a[u]));o.rawOutput=d}return{...s,params:{...t,update:o}}}function ql(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&s.type==="diff"}function ta(s){if(ql(s)){let n=s,r={type:"diff",oldText:"",newText:""};return typeof n.path=="string"&&(r.path=n.path),r}if(!s||typeof s!="object"||Array.isArray(s))return s;let e=s,t={...e};return typeof e.text=="string"&&(t.text=On(e.text)),typeof e.content=="string"?t.content=On(e.content):e.content&&typeof e.content=="object"&&(t.content=ta(e.content)),t}function On(s){if(typeof s=="string"&&s.length>gr){let e=s.length-gr;return`${s.slice(0,gr)}\u2026[+${e} chars omitted from summary export]`}return s}var zl=2048;function na(s){let e=new Set,t=n=>{if(sa(n)){e.add(n.__hydraBlob);return}if(Array.isArray(n)){for(let r of n)t(r);return}if(n&&typeof n=="object")for(let r of Object.values(n))t(r)};for(let n of s)t(n.params);return e}function sa(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.__hydraBlob=="string"}function Jl(s){if(s.method!=="session/update")return!1;let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t.sessionUpdate;return n==="tool_call"||n==="tool_call_update"}async function yr(s,e){if(!Jl(s))return s;let t=s.params,n=t.update,r=await mr(n,e);return{...s,params:{...t,update:r}}}async function mr(s,e){if(typeof s=="string"){if(s.length<=zl)return s;let t=await e(s);return t===null?s:{__hydraBlob:t,bytes:s.length}}if(Array.isArray(s)){let t=[];for(let n of s)t.push(await mr(n,e));return t}if(s&&typeof s=="object"){let t={};for(let[n,r]of Object.entries(s))t[n]=await mr(r,e);return t}return s}async function wr(s,e){let t=s.params;if(!t||typeof t!="object"||Array.isArray(t))return s;let n=await hr(t,e);return n===t?s:{...s,params:n}}async function hr(s,e){if(sa(s))return await e(s.__hydraBlob)??"";if(Array.isArray(s)){let t=!1,n=[];for(let r of s){let o=await hr(r,e);o!==r&&(t=!0),n.push(o)}return t?n:s}if(s&&typeof s=="object"){let t=!1,n={};for(let[r,o]of Object.entries(s)){let i=await hr(o,e);i!==o&&(t=!0),n[r]=i}return t?n:s}return s}var Xl=ra(Kl),Zl=ra(Gl),ef=/^history\.jsonl\.(\d+)(\.gz)?$/,Se=/^[A-Za-z0-9_-]+$/,tf=1e3,nf=1e7,sf=10,Hn=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??tf,this.archiveMaxBytes=e.archiveMaxBytes??nf,this.archiveTiers=e.archiveTiers??sf}async append(e,t){if(Se.test(e))return this.enqueue(e,async()=>{await z.mkdir(A.sessionDir(e),{recursive:!0});let n=await yr(t,o=>Ss(e,o)),r=JSON.stringify(n)+`
127
+ `;await z.appendFile(A.historyFile(e),r,{encoding:"utf8",mode:384})})}async rewrite(e,t){if(Se.test(e))return this.enqueue(e,async()=>{await z.mkdir(A.sessionDir(e),{recursive:!0});let n=[];for(let o of t)n.push(await yr(o,i=>Ss(e,i)));let r=n.length===0?"":n.map(o=>JSON.stringify(o)).join(`
114
128
  `)+`
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(`
129
+ `;await z.writeFile(A.historyFile(e),r,{encoding:"utf8",mode:384})})}async compact(e,t){if(Se.test(e))return this.enqueue(e,async()=>{let n;try{n=await z.readFile(A.historyFile(e),"utf8")}catch(a){if(a.code==="ENOENT")return;throw a}let r=n.split(`
130
+ `).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 z.writeFile(A.historyFile(e),i.join(`
117
131
  `)+`
118
- `,{encoding:"utf8",mode:384})})}async spillToArchive(e,t){let s=t.join(`
132
+ `,{encoding:"utf8",mode:384})})}async spillToArchive(e,t){let n=t.join(`
119
133
  `)+`
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 fu(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=mu.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 pu(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=au(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(du()):t,o=lu({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 mt(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 mt(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(`
134
+ `,r=await this.resolveNextArchiveIndex(e);await this.enforceArchiveTierCap(e,r);let o=A.historyArchiveFile(e,r);await z.mkdir(A.sessionDir(e),{recursive:!0}),await z.appendFile(o,n,{encoding:"utf8",mode:384});let i=0;try{i=(await z.stat(o)).size}catch{i=0}i>=this.archiveMaxBytes?(await this.sealArchive(e,r),this.nextArchiveIndex.set(e,r+1)):this.nextArchiveIndex.set(e,r),this.archiveLineCounts.delete(e)}async sealArchive(e,t){let n=A.historyArchiveFile(e,t),r;try{r=await z.readFile(n)}catch(i){if(i.code==="ENOENT")return;throw i}let o=await Xl(r);await z.writeFile(n+".gz",o,{mode:384});try{await z.unlink(n)}catch(i){if(i.code!=="ENOENT")throw i}}async resolveNextArchiveIndex(e){let t=this.nextArchiveIndex.get(e);if(t!==void 0)return t;let n=await this.listArchiveIndices(e),r=n.length===0?0:n[n.length-1],o=r===0?1:r;if(r>0){let i=A.historyArchiveFile(e,r),a=i+".gz",d=!1;try{await z.access(a),d=!0}catch{d=!1}if(d)o=r+1;else try{(await z.stat(i)).size>=this.archiveMaxBytes&&(o=r+1)}catch{o=r}}return this.nextArchiveIndex.set(e,o),o}async enforceArchiveTierCap(e,t){if(this.archiveTiers<=0)return;let n=await this.listArchiveIndices(e),o=(n.includes(t)?n.length:n.length+1)-this.archiveTiers,i=0;for(;o>0&&i<n.length;){let a=n[i];a!==t&&(await this.unlinkArchive(e,a),o-=1),i+=1}}async unlinkArchive(e,t){let n=A.historyArchiveFile(e,t);for(let r of[n,n+".gz"])try{await z.unlink(r)}catch(o){if(o.code!=="ENOENT")throw o}this.archiveLineCounts.delete(e)}async listArchiveIndices(e){let t;try{t=await z.readdir(A.sessionDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=new Set;for(let r of t){let o=ef.exec(r);if(!o)continue;let i=Number.parseInt(o[1],10);Number.isFinite(i)&&i>0&&n.add(i)}return[...n].sort((r,o)=>r-o)}async listArchives(e){if(!Se.test(e))return[];let t=await this.listArchiveIndices(e),n=[];for(let r of t){let o=A.historyArchiveFile(e,r),i=o+".gz",a=o;try{await z.access(i),a=i}catch{a=o}n.push({index:r,path:a})}return n}async loadArchives(e){if(!Se.test(e))return[];let t=this.writeQueues.get(e);t&&await t;let n=await this.listArchives(e),r=[];for(let{path:o}of n){let i;try{if(o.endsWith(".gz")){let a=await z.readFile(o);i=(await Zl(a)).toString("utf8")}else i=await z.readFile(o,"utf8")}catch(a){if(a.code==="ENOENT")continue;throw a}for(let a of i.split(`
135
+ `)){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=Vl(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(Ql()):t,o=Yl({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(!Se.test(e))return[];let t=this.archiveLineCounts.get(e),n=await this.listArchives(e);if(t&&t.length===n.length&&t.every((o,i)=>o.index===n[i].index&&o.path===n[i].path))return t;let r=[];for(let{index:o,path:i}of n){let a=t?.find(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,n){return wr(t,async r=>{let o=n.get(r);if(o!==void 0)return o;let i=await Mt(e,r);return n.set(r,i),i})}async*iterRecallNewestFirst(e){if(!Se.test(e))return;let t=this.writeQueues.get(e);t&&await t;let n=await this.getArchiveLineCounts(e),r=0;for(let u of n)r+=u.lineCount;let o=new Map,i=[];for await(let u of this.streamFile(A.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(n.length),d=0;for(let u=0;u<n.length;u++)a[u]=d,d+=n[u].lineCount;for(let u=n.length-1;u>=0;u--){let c=n[u],l=[];for await(let f of this.streamFile(c.path))l.push(f);let p=a[u];for(let f=l.length-1;f>=0;f--){let m=await this.hydrateEntry(e,l[f],o);yield{entryId:p+f,entry:m}}}}async rangeSlice(e,t,n){if(!Se.test(e))return[];if(n<t)return[];let r=this.writeQueues.get(e);r&&await r;let o=await this.getArchiveLineCounts(e),i=0;for(let c of o)i+=c.lineCount;let a=[],d=new Map,u=0;for(let c of o){let l=u,p=u+c.lineCount;if(u=p,p<=t)continue;if(l>n)break;let f=0;for await(let m of this.streamFile(c.path)){let g=l+f;if(f+=1,g<t)continue;if(g>n)break;let h=await this.hydrateEntry(e,m,d);a.push({entryId:g,entry:h})}}if(n>=i){let c=Math.max(t-i,0),l=n-i,p=0;for await(let f of this.streamFile(A.historyFile(e))){if(p>l)break;if(p>=c){let m=await this.hydrateEntry(e,f,d);a.push({entryId:i+p,entry:m})}p+=1}}return a}async getRecallTotalCount(e){if(!Se.test(e))return 0;let t=await this.getArchiveLineCounts(e),n=0;for(let o of t)n+=o.lineCount;let r=0;for await(let o of this.streamFile(A.historyFile(e)))r+=1;return n+r}async load(e,t={}){if(!Se.test(e))return[];let n=(t.tools??"inline")==="inline",r=this.writeQueues.get(e);r&&await r;let o;try{o=await z.readFile(A.historyFile(e),"utf8")}catch(p){if(p.code==="ENOENT")return[];throw p}let i=[];for(let p of o.split(`
136
+ `)){if(p.length===0)continue;let f;try{f=JSON.parse(p)}catch{continue}if(!f||typeof f!="object"||Array.isArray(f))continue;let m=f;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(!n)return d;let u=new Map,c=async p=>{let f=u.get(p);if(f!==void 0)return f;let m=await Mt(e,p);return u.set(p,m),m},l=[];for(let p of d)l.push(await wr(p,c));return l}async flushAll(){let e=[...this.writeQueues.values()];e.length!==0&&await Promise.allSettled(e)}async delete(e){if(Se.test(e))return this.enqueue(e,async()=>{try{await z.unlink(A.historyFile(e))}catch(n){if(n.code!=="ENOENT")throw n}let t=await this.listArchiveIndices(e);for(let n of t)await this.unlinkArchive(e,n);this.nextArchiveIndex.delete(e),this.archiveLineCounts.delete(e),await go(e);try{await z.rmdir(A.sessionDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}})}enqueue(e,t){let r=(this.writeQueues.get(e)??Promise.resolve()).then(t,t),o=r.catch(()=>{});return this.writeQueues.set(e,o),o.finally(()=>{this.writeQueues.get(e)===o&&this.writeQueues.delete(e)}),r}};K();import{promises as oa}from"fs";import*as ia from"path";async function aa(s,e){await oa.mkdir(ia.dirname(s),{recursive:!0});let t=e.map(n=>JSON.stringify(n));await oa.writeFile(s,t.length>0?t.join(`
123
137
  `)+`
124
- `:"")}import{z as D}from"zod";var wu=D.object({method:D.string(),params:D.unknown(),recordedAt:D.number()}),bu=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: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()}),vu=D.object({version:D.literal(1),exportedAt:D.string(),exportedFrom:D.object({hydraVersion:D.string(),machine:D.string(),hydraHost:D.string().optional()}),session:bu,history:D.array(wu),promptHistory:D.array(D.string()).optional(),toolBlobs:D.record(D.string()).optional()});function kt(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 vu.parse(n)}function Es(n){if(n&&!(n.costAmount===void 0&&n.cumulativeCost===void 0))return(n.cumulativeCost??0)+(n.costAmount??0)}function At(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,Iu="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ct=Su(Iu,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}${Ct()}`,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_${Ct()}`,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=xt(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=xt(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(ku(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}${Ct()}`,y=new Date().toISOString(),b=l.updatedAt??y,w={sessionId:h,lineageId:St(),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=xt(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=xt(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=xt(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=Au(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 mt(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:Cu(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 Mt(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 Mt(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:At(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=>Mt(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=>Mt(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:At(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=St(),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}${Ct()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let 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=Mu(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:St(),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=kt({record:h,history:a,promptHistory:m.length>0?m:void 0,hydraVersion:Y,machine:ht()}),b=`${we}${Ct()}`;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 Mt(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 wt(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 wt(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 ku(n,e){if(typeof n!="string"||n.length===0)return!1;let t=Et.resolve(n),s=Et.resolve(e);return t===s||t.startsWith(s+Et.sep)}function Au(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??St(),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 Cu(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=xu(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 xt(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 xu(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=bt(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=bt(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 Mu(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 Mt(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 Eu}from"child_process";import*as fn from"fs";import*as Ae from"fs/promises";import*as pn from"path";import Ru 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 Tu=1e3,Pu=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??Tu,this.restartCapMs=r.restartCapMs??Pu;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 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(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 Ru({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=Eu(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}
138
+ `:"")}import{z as q}from"zod";var rf=q.object({method:q.string(),params:q.unknown(),recordedAt:q.number()}),of=q.object({sessionId:q.string(),lineageId:q.string(),upstreamSessionId:q.string().optional(),agentId:q.string(),cwd:q.string(),title:q.string().optional(),synopsis:Ht.optional(),summarizedThroughEntry:q.number().int().nonnegative().optional(),currentModel:q.string().optional(),currentMode:q.string().optional(),currentUsage:rr.optional(),agentCommands:q.array(nr).optional(),agentModes:q.array(sr).optional(),interactive:q.boolean().optional(),originatingClient:or.optional(),priority:q.number().int().nonnegative().optional(),createdAt:q.string(),updatedAt:q.string()}),af=q.object({version:q.literal(1),exportedAt:q.string(),exportedFrom:q.object({hydraVersion:q.string(),machine:q.string(),hydraHost:q.string().optional()}),session:of,history:q.array(rf),promptHistory:q.array(q.string()).optional(),toolBlobs:q.record(q.string()).optional()});function Wt(s){let e={version:1,exportedAt:new Date().toISOString(),exportedFrom:{hydraVersion:s.hydraVersion,machine:s.machine,...s.hydraHost!==void 0&&s.hydraHost.length>0?{hydraHost:s.hydraHost}:{}},session:{sessionId:s.record.sessionId,lineageId:s.record.lineageId,...s.record.upstreamSessionId?{upstreamSessionId:s.record.upstreamSessionId}:{},agentId:s.record.agentId,cwd:s.record.cwd,...s.record.title!==void 0?{title:s.record.title}:{},...s.record.synopsis!==void 0?{synopsis:s.record.synopsis}:{},...s.record.summarizedThroughEntry!==void 0?{summarizedThroughEntry:s.record.summarizedThroughEntry}:{},...s.record.currentModel!==void 0?{currentModel:s.record.currentModel}:{},...s.record.currentMode!==void 0?{currentMode:s.record.currentMode}:{},...s.record.currentUsage!==void 0?{currentUsage:s.record.currentUsage}:{},...s.record.agentCommands!==void 0?{agentCommands:s.record.agentCommands}:{},...s.record.agentModes!==void 0?{agentModes:s.record.agentModes}:{},...s.record.interactive!==void 0?{interactive:s.record.interactive}:{},...s.record.originatingClient!==void 0?{originatingClient:s.record.originatingClient}:{},...s.record.priority!==void 0&&s.record.priority>0?{priority:s.record.priority}:{},createdAt:s.record.createdAt,updatedAt:s.record.updatedAt},history:s.history};return s.promptHistory!==void 0&&(e.promptHistory=s.promptHistory),s.toolBlobs!==void 0&&Object.keys(s.toolBlobs).length>0&&(e.toolBlobs=s.toolBlobs),e}function da(s){return af.parse(s)}function kr(s){if(s&&!(s.costAmount===void 0&&s.cumulativeCost===void 0))return(s.cumulativeCost??0)+(s.costAmount??0)}function qt(s){if(!s)return;let e={};s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size);let t=kr(s);return t&&(e.costAmount=t),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),e}var ca=900*1e3,cf="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",St=df(cf,16),jn=class s{constructor(e,t,n,r={}){this.registry=e;this.spawner=t??(a=>ze.spawn(a)),this.store=n??new vn,this.tombstones=r.tombstones??new Tn,this.sessionHistoryMaxEntries=r.sessionHistoryMaxEntries??1e3,this.histories=new Hn({maxEntries:this.sessionHistoryMaxEntries,archiveMaxBytes:r.sessionHistoryArchiveMaxBytes,archiveTiers:r.sessionHistoryArchiveTiers}),this.workspaceSnapshotsDisabled=r.disableWorkspaceSnapshots===!0,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 Nn({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;snapshotInFlight=new Set;snapshotPending=new Set;workspaceSnapshotsDisabled=!1;driftNoticed=new Map;pendingAuthAgents=new Map;spawner;store;tombstones;histories;idleTimeoutMs;defaultModels;synopsisAgent;synopsisModel;compactionAgent;compactionModel;defaultTransformers;idleEventTimeoutMs;sessionHistoryMaxEntries;metaWriteQueues=new Map;workspaceQueues=new Map;listCache=new Map;static LIST_CACHE_TTL_MS=500;logger;npmRegistry;extensionCommands;defaultCwd;synopsisCoordinator;pendingDeletions=new Map;pendingSwapDisposers=new Map;rollbackLocks=new Set;compactionTailK=20;agentCatalog=[];async dispatchSynthesisSwap(e,t,n,r){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:n});return}let i=this.compactionTailK;try{if(await o.isQuiescedForSwap()){this.pendingSwapDisposers.get(e)?.(),this.pendingSwapDisposers.delete(e),await this.performSynthesisSwap(o,t,i,n,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 n=this.compactionTailK;try{if(!await t.isQuiescedForSwap()){let d=await this.store.read(e).catch(()=>{});d?.synopsis&&d.summarizedThroughEntry!==void 0&&this.dispatchSynthesisSwap(e,d.synopsis,d.summarizedThroughEntry,d.pendingAgentSwap);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,n,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,n,r,o){try{let i=o?Math.min(5,n):0;await e.swapUpstream({artifact:t,tailK:n,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 rt(this.registry);this.agentCatalog=e.map(t=>({id:t.id,name:t.name,...t.description!==void 0?{description:t.description}:{}}))}catch{}}async resolveWorkspace(e){let t=e.workspace;if(t===void 0)return{cwd:e.cwd};let n=X(t.provider);if(n===void 0){let c=`unknown workspace provider "${t.provider}"`;if(t.required===!0)throw new Error(`isolation required but unavailable: ${c}`);return this.logger?.warn?.(`session workspace: ${c}; running in ${e.cwd}`),{cwd:e.cwd,isolationError:c}}let r=t.label??`s-${St().slice(0,8)}`,o=await n.createWorkspace({sourceCwd:e.cwd,label:r,...t.from!==void 0?{from:t.from}:{}}).catch(c=>({ok:!1,reason:String(c)}));if(!o.ok){if(t.required===!0)throw new Error(`isolation required but unavailable: ${o.reason}`);return this.logger?.warn?.(`session workspace: ${o.reason}; falling back to ${e.cwd} (unisolated)`),{cwd:e.cwd,isolationError:o.reason}}let i=o.workspace;n.capabilities().locking&&await n.lock(i,`session ${e.title??"live"}`).catch(()=>{});let a=await Pn(i.sourceCwd).catch(()=>({})),d,u=await this.materializeNestedTrees(i);if(u!==void 0&&this.logger?.info?.(`session workspace: ${u} in ${i.path}`),a.carry!==void 0&&a.carry.length>0){let c=await pr(i.sourceCwd,i.path,a.carry).catch(()=>{});c!==void 0&&c.copied.length>0&&this.logger?.info?.(`session workspace: carried ${c.copied.length} file(s) into ${i.path}`)}if(a.postCreate!==void 0){let c=await Mn(a.postCreate,{workspacePath:i.path,sourceCwd:i.sourceCwd,label:i.label,...a.hookTimeoutSeconds!==void 0?{timeoutSeconds:a.hookTimeoutSeconds}:{}});c.ok||(d=`postCreate failed: ${c.reason??"unknown"}`,this.logger?.warn?.(`session workspace: ${d} (${i.path})`))}return i.snapshot!==void 0&&await n.retainSnapshot(i,this.startRefFor(i.label),i.snapshot).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},clean:!0},...d!==void 0?{isolationError:d}:{}}}async create(e){let t=await this.registry.getAgent(e.agentId);t&&t.id!==e.agentId&&(e={...e,agentId:t.id});let n=`${Pe}${St()}`,r=await this.resolveWorkspace(e),o=r.cwd,i=await this.bootstrapAgent({agentId:e.agentId,cwd:o,agentArgs:e.agentArgs,mcpServers:e.mcpServers,model:e.model,onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,selfSessionId:n});if(e.transformChain&&e.transformChain.length>0){let d={...i.agentCapabilities??{}};for(let u of e.transformChain)if(u.intercepts.has("agent:initialize"))try{let c=await u.connection.request("hydra-acp/transformer/message",{token:`t_${St()}`,phase:"response",method:"initialize",direction:"agent\u2192daemon",sessionId:"(pre-session)",envelope:d});c.action==="stop"&&c.payload&&(d=c.payload)}catch{}i.agentCapabilities=d}let a=new yt({sessionId:n,cwd:o,...r.workspace!==void 0?{workspace:r.workspace}:{},...r.isolationError!==void 0?{workspaceError:r.isolationError}:{},agentId:e.agentId,agent:i.agent,upstreamSessionId:i.upstreamSessionId,agentMeta:i.agentMeta,agentCapabilities:i.agentCapabilities,...i.modelVerb?{modelVerb:i.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,idleEventTimeoutMs:this.idleEventTimeoutMs,logger:this.logger,spawnReplacementAgent:d=>this.bootstrapAgent({...d,mcpServers:d.mcpServers??[],selfSessionId:n}),loadExistingAgentSession:(d,u)=>this.bootstrapAgentLoad(d,{...u,mcpServers:u.mcpServers??[],selfSessionId:n}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:i.initialModel,currentMode:i.initialMode,agentModes:i.initialModes,agentModels:i.initialModels,transformChain:e.transformChain,parentSessionId:e.parentSessionId,originatingClient:e.originatingClient,interactive:e.interactive,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(a.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(a),scheduleCompaction:d=>this.scheduleCompaction(a.sessionId,d),resolveAgentId:async d=>(await this.registry.getAgent(d))?.id,getCompactionState:()=>this.getCompactionState(a.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(a.sessionId),uncompactHook:()=>this.performUncompact(a.sessionId),forkHook:d=>this.forkSession(a.sessionId,d??{}),workspaceHook:(d,u,c)=>this.runWorkspaceAction(a.sessionId,d,u,c),onCompactionSwapHook:d=>{this.mutateRecord(a.sessionId,{rollbackBreadcrumb:d}).catch(()=>{})},persistWatermarkHook:d=>{this.mutateRecord(a.sessionId,{summarizedThroughEntry:d}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(a.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});if(r.workspace!==void 0){let d=X(r.workspace.provider);d!==void 0&&d.capabilities().supports.environmentNotes&&(a.workspaceNotes=await d.environmentNotes({path:r.workspace.path,sourceCwd:r.workspace.sourceCwd,label:r.workspace.label,provider:r.workspace.provider,...r.workspace.snapshot!==void 0?{snapshot:r.workspace.snapshot}:{},...r.workspace.vcs!==void 0?{vcs:r.workspace.vcs}:{}}).catch(()=>[]))}return await this.attachManagerHooks(a),a}async resurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t){if(t.upstreamSessionId!==e.upstreamSessionId){let o=new Error(`session ${e.hydraSessionId} already exists with a different upstream id`);throw o.code=C.AlreadyAttached,o}return t}let n=this.resurrectionInflight.get(e.hydraSessionId);if(n)return n;let r=this.doResurrect(e);this.resurrectionInflight.set(e.hydraSessionId,r);try{return await r}finally{this.resurrectionInflight.delete(e.hydraSessionId)}}async doResurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t)return t;let n=await this.registry.getAgent(e.agentId);if(!n){let y=new Error(`agent ${e.agentId} not found in registry; cannot resurrect`);throw y.code=C.AgentNotInstalled,y}if(e.upstreamSessionId==="")return this.doResurrectFromImport(e);if(!await this.dirExists(e.cwd))return this.doResurrectFromImport(e);let r=await ye(n,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),o=on(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:it,clientInfo:{name:"hydra",version:ie}});a=y.agentCapabilities,i.authMethods=zt(y.authMethods)}catch(y){throw await i.kill().catch(()=>{}),Ve(y,i)}let d;try{let y=la(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===C.AuthRequired)throw await i.kill().catch(()=>{}),Ve(y,i);return process.stderr.write(`session/load failed for upstream ${e.upstreamSessionId} on ${e.agentId} (${y.message}); recovering via import-reseed
139
+ `),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=Cr(d??{}),c=e.agentModes??Sr(Ar(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 l=await ct({agent:i,upstreamSessionId:e.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:u,advertisedModes:c,logger:this.logger});this.logger?.info(`resurrect: effectiveMode=${JSON.stringify(l)} for sessionId=${e.hydraSessionId}`);let p=br(d??{}),f=Sr(Ir(d??{}))??e.agentModels;if(this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedModel=${JSON.stringify(e.currentModel)} agentReportedModel=${JSON.stringify(p)} advertisedModels=${JSON.stringify(f?.map(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=dt(d),g=await ut({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 yt({sessionId:e.hydraSessionId,cwd:e.cwd,...e.workspace!==void 0?{workspace:e.workspace}:{},agentId:e.agentId,agent:i,upstreamSessionId:e.upstreamSessionId,agentMeta:d?._meta,agentCapabilities:a,...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,k)=>this.bootstrapAgentLoad(y,{...k,mcpServers:k.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:l,currentUsage:e.currentUsage,reloadsUpstreamLedger:!0,agentCommands:e.agentCommands,agentModes:c,agentModels:f,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),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(h),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??{}),workspaceHook:(y,k,w)=>this.runWorkspaceAction(h.sessionId,y,k,w),onCompactionSwapHook:y=>{this.mutateRecord(h.sessionId,{rollbackBreadcrumb:y}).catch(()=>{})},persistWatermarkHook:y=>{this.mutateRecord(h.sessionId,{summarizedThroughEntry:y}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(h.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(h),h}async doResurrectFromImport(e){let t=await this.resolveResurrectTarget(e.cwd,e.workspace),n=t.cwd,r=await this.bootstrapAgent({agentId:e.agentId,cwd:n,agentArgs:e.agentArgs,mcpServers:e.mcpServers??[],onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,model:e.currentModel}),o=e.agentModes??r.initialModes,i=await ct({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:r.initialMode,advertisedModes:o,logger:this.logger}),a=e.agentModels??r.initialModels,d=await ut({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:r.initialModel,...r.modelVerb?{modelVerb:r.modelVerb}:{},logger:this.logger});r.agent.connection.drainBuffered("session/update");let u=new yt({sessionId:e.hydraSessionId,cwd:n,...t.workspace!==void 0?{workspace:t.workspace}:{},agentId:e.agentId,agent:r.agent,upstreamSessionId:r.upstreamSessionId,agentMeta:r.agentMeta,agentCapabilities:r.agentCapabilities,...r.modelVerb?{modelVerb:r.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,logger:this.logger,spawnReplacementAgent:c=>this.bootstrapAgent({...c,mcpServers:c.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(c,l)=>this.bootstrapAgentLoad(c,{...l,mcpServers:l.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:d,currentMode:i,currentUsage:e.currentUsage,agentCommands:e.agentCommands,agentModes:o,agentModels:a,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(u.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(u),scheduleCompaction:c=>this.scheduleCompaction(u.sessionId,c),resolveAgentId:async c=>(await this.registry.getAgent(c))?.id,getCompactionState:()=>this.getCompactionState(u.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(u.sessionId),uncompactHook:()=>this.performUncompact(u.sessionId),forkHook:c=>this.forkSession(u.sessionId,c??{}),workspaceHook:(c,l,p)=>this.runWorkspaceAction(u.sessionId,c,l,p),onCompactionSwapHook:c=>{this.mutateRecord(u.sessionId,{rollbackBreadcrumb:c}).catch(()=>{})},persistWatermarkHook:c=>{this.mutateRecord(u.sessionId,{summarizedThroughEntry:c}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(u.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(u),e.forkedFromSessionId&&e.forkSynthesisState==="running"?this.logger?.info(`fork ${u.sessionId}: synthesis in flight \u2014 skipping seed, recall available`):e.forkedFromSessionId&&(e.synopsis||(e.summarizedThroughEntry??0)>0)?u.seedFromFork(e.synopsis).catch(()=>{}):u.seedFromImport().catch(()=>{}),u}async dirExists(e){try{return(await Ge.stat(e)).isDirectory()}catch{return!1}}async reapIfOrphanedNonInteractive(e){let t=this.sessions.get(e);if(!(!t||t.attachedCount>0)&&t.interactive!==!0){if(t.hasWorkInFlight){this.logger?.info(`deferring reap of ${e}: work still in flight after detach`),t.onceIdle(n=>{this.reapIfOrphanedNonInteractive(n.sessionId).catch(()=>{})});return}this.logger?.info(`reaping orphaned non-interactive session ${e} (agent killed, cold record kept)`),await t.close({deleteRecord:!1}).catch(()=>{})}}async resolveResurrectTarget(e,t){if(await this.dirExists(e))return t!==void 0?{cwd:e,workspace:t}:{cwd:e};if(t!==void 0){let n=await this.recoverWorkspace(t);if(n!==void 0)return{cwd:n.path,workspace:n}}return{cwd:de(this.defaultCwd)}}async releaseWorkspace(e,t){let n=X(e.provider);if(n===void 0){this.logger?.warn?.(`session workspace: no provider "${e.provider}" to release ${e.path}; leaving it in place`);return}return this.enqueueKeyed(this.workspaceQueues,e.path,async()=>{let r=this.liveSessionsIn(e.path,t);if(r.length>0){this.logger?.info?.(`session workspace: keeping ${e.path} \u2014 ${r.length} live session(s) still in it`);return}await this.tearDownWorkspace(n,e,t)})}async syncWorkspaceFromSource(e,t,n){let r=this.liveSessionsIn(t.path,e.sessionId);if(r.length>0)throw new Error(`${O(t.path)} is shared with ${r.map(p=>Oe(p.sessionId)).join(", ")}, and a sync would move files under them. Sync it from a session that has it to itself.`);if(!await e.isQuiescedForSwap())throw new Error("the agent is still working; wait for the current turn to finish, then try again");let o=X(t.provider);if(t.line===void 0||o?.capabilities().sharedHistory!==!0)throw new Error(`workspace ${t.label} uses the "${t.provider}" provider, which has no history to merge from \u2014 a sync needs a common base, and a copied directory has none. Land its work with \`/hydra workspace merge\` instead, or start a git-backed workspace if you need to track the source.`);let[i,a]=await Promise.all([o.currentState(t.sourceCwd),o.currentState(t.path)]);if(i===void 0||a===void 0)throw new Error("could not read the state of the source or the workspace");if(await o.contains(t.path,{state:i,within:a}))return{ok:!0,message:`Already up to date with ${O(t.sourceCwd)} (${i.slice(0,8)}).`};let d=await o.divergence(t.path,a,i),u=String(d?.behind??0),c=await o.integrate({into:t.path,from:i,message:`hydra: sync ${t.label} with the source`});if(!c.ok){let p=c.conflicts,f=await o.integrationInProgress(t.path);if(p.length===0&&!f){let g=await this.syncOverDirtyTree(t,{provider:o,before:a,sourceHead:i,incoming:u});if(g!==void 0)return g}let m=p.length>0?`
140
+ ${p.map(g=>` ${g}`).join(`
141
+ `)}`:` (${c.reason??"the integration failed"})`;return p.length===0?{ok:!1,message:`the source could not be merged into ${O(t.path)}; nothing changed.${m}
142
+ `+(f?"A merge is already in progress there. Finish it \u2014 resolve, commit \u2014 then `/hydra workspace sync` again.":"Clear that in the workspace, then `/hydra workspace sync` again.")}:n.onConflict==="abort"?(await o.abortIntegration(t.path).catch(()=>{}),{ok:!1,message:`${p.length} file(s) conflict between the source and this workspace:${m}`}):{ok:!1,message:`Synced with conflicts. ${p.length} file(s) need resolving in ${O(t.path)}:${m}
143
+ The merge is left in progress deliberately: fix the markers, commit, then \`/hydra workspace stop\`. To back it out instead: git -C ${t.path} merge --abort`}}let l=(await o.changedPathsBetween(t.path,a,c.snapshot)).length;return{ok:!0,message:`Synced ${O(t.path)} with ${O(t.sourceCwd)}: ${u} commit(s), ${l} file(s) changed. Your uncommitted work is untouched.`}}async syncOverDirtyTree(e,t){let{provider:n,before:r,sourceHead:o,incoming:i}=t;if(n?.capabilities().supports.captureWorkingState!==!0)return;let a=this.asWorkspace(e),d=await n.status(a).catch(()=>{});if(d===void 0||d.changedPaths.length===0)return;let u=await n.captureWorkingState(e.path,`hydra: work set aside to sync ${e.label}`).catch(()=>{});if(u===void 0)return;let c=Ni(e.label);if(await n.retainSnapshot(a,c,u).then(()=>n.resolveRetained(a,c)).catch(()=>{})===void 0)return;let p={clean:!1,snapshot:u,base:r},f=`git -C ${e.path} cherry-pick --no-commit ${c} # the snapshot's parent is ${r.slice(0,8)}, so this replays exactly your work`;if(!(await n.resetTo(e.path,r)).ok){let v=await Bt({source:e.path,capture:p,provider:n});return{ok:!1,message:`Could not clear ${O(e.path)} to merge into it, so nothing was synced. ${v?"Your uncommitted work is back in place.":`Your uncommitted work is at ${c}: ${f}`}`}}if(!(await n.integrate({into:e.path,from:o,message:`hydra: sync ${e.label} with the source`})).ok){await n.abortIntegration(e.path).catch(()=>{});let v=await Bt({source:e.path,capture:p,provider:n});return v&&await n.dropSnapshotRef(a,c).catch(()=>{}),{ok:!1,message:`The source's commits and this workspace's commits genuinely conflict, and that has to be resolved with a merge left in progress \u2014 which cannot happen while there is uncommitted work here, since the work has to be set aside for the merge to run at all.
144
+ `+(v?`Your uncommitted work is back in place (unstaged) and nothing else changed. Commit it in ${O(e.path)}, then \`/hydra workspace sync\` again to resolve the conflict there.`:`Your uncommitted work could not be put back and is preserved at ${c}. Recover it with:
145
+ ${f}`)}}let h=await Bt({source:e.path,capture:p,provider:n}),y=await n.currentState(e.path),k=y===void 0?0:(await n.changedPathsBetween(e.path,r,y)).length,w=`Synced ${O(e.path)} with ${O(e.sourceCwd)}: ${i} commit(s), ${k} file(s) changed.`;return h?(await n.dropSnapshotRef(a,c).catch(()=>{}),{ok:!0,message:`${w} Your uncommitted work was set aside for the merge and restored on top.`}):{ok:!1,message:`${w}
146
+ Your uncommitted work touches the same lines as the commits that just arrived, so replaying it left conflict markers where they collide. The whole set is preserved at ${c} if you would rather start over:
147
+ ${f}`}}async fastForwardBlocked(e){let n=this.asWorkspace(e).line;if(n===void 0)return"the workspace has no line of work to land from";let r=X(e.provider);if(r===void 0)return;let o=await r.currentState(e.sourceCwd);if(o===void 0||await r.contains(e.sourceCwd,{state:o,within:n}))return;let i=await r.currentLineName(e.sourceCwd);return`${O(e.sourceCwd)} has moved on since this workspace was created (it is on ${i??"an unknown branch"}). \`/hydra workspace sync\` brings those commits in here and makes the landing possible again, or land it by hand with: git -C ${e.sourceCwd} merge ${n}`}async tearDownWorkspace(e,t,n){let r={path:t.path,sourceCwd:t.sourceCwd,label:t.label,provider:t.provider,...t.snapshot!==void 0?{snapshot:t.snapshot}:{},...t.vcs!==void 0?{vcs:t.vcs}:{}},o=await Pn(t.sourceCwd).catch(()=>({}));if(o.preRemove!==void 0){let a=await Mn(o.preRemove,{workspacePath:t.path,sourceCwd:t.sourceCwd,label:t.label,...n!==void 0?{sessionId:n}:{},...o.hookTimeoutSeconds!==void 0?{timeoutSeconds:o.hookTimeoutSeconds}:{}});a.ok||this.logger?.warn?.(`session workspace: preRemove failed for ${t.path}: ${a.reason??"unknown"}`)}for(let a of Hi(t.label))await e.dropSnapshotRef(r,a).catch(()=>{});let i=await e.status(r).catch(()=>({clean:!1,changedPaths:["<unknown>"],hasRecordedWork:!1}));if(i.changedPaths.length>0){this.logger?.warn?.(`session workspace: keeping ${t.path} \u2014 it has ${i.changedPaths.length} uncommitted change(s) that removal would destroy. Remove it by hand once you have salvaged or discarded them.`);return}await e.removeWorkspace(r,{force:!0}).catch(a=>this.logger?.warn?.(`session workspace: could not remove ${t.path}: ${String(a)}`))}snapshotRefFor(e){return Lt(e).autosave}startRefFor(e){return Lt(e).start}baselineRefFor(e){return Lt(e).baseline}scheduleWorkspaceSnapshot(e){if(e.workspace===void 0){this.driftNoticed.delete(e.sessionId);return}if(this.snapshotInFlight.has(e.sessionId)){this.snapshotPending.add(e.sessionId);return}this.snapshotInFlight.add(e.sessionId),this.runWorkspaceSnapshot(e).catch(()=>{}).finally(()=>{this.snapshotInFlight.delete(e.sessionId),this.snapshotPending.delete(e.sessionId)&&this.scheduleWorkspaceSnapshot(e)})}async runWorkspaceSnapshot(e){let t=e.workspace;if(t===void 0)return;let n=X(t.provider);if(n===void 0||!n.capabilities().supports.captureWorkingState)return;let r={path:t.path,sourceCwd:t.sourceCwd,label:t.label,provider:t.provider,...t.snapshot!==void 0?{snapshot:t.snapshot}:{},...t.vcs!==void 0?{vcs:t.vcs}:{}};if(await this.noticeSourceDrift(e,t).catch(()=>{}),this.workspaceSnapshotsDisabled)return;let o=await n.status(r).catch(()=>{});if(o!==void 0&&o.changedPaths.length===0)return;let i=await n.captureWorkingState(t.path,`hydra: autosave ${e.sessionId}`);await n.retainSnapshot(r,this.snapshotRefFor(t.label),i)}async noticeSourceDrift(e,t){if(this.asWorkspace(t).line===void 0)return;let r=X(t.provider);if(r===void 0||!r.capabilities().sharedHistory)return;let o=await r.currentState(t.sourceCwd);if(o===void 0||this.driftNoticed.get(e.sessionId)===o)return;let i=await r.currentState(t.path);if(i===void 0)return;if(await r.contains(t.path,{state:o,within:i})){this.driftNoticed.delete(e.sessionId);return}let d=(await r.divergence(t.path,i,o))?.behind??0;d<=0||(this.driftNoticed.set(e.sessionId,o),e.broadcastWorkspacePhase({phase:"drift",label:t.label,sourceCwd:t.sourceCwd,behind:d}),e.broadcastSyntheticText(`
148
+ ${O(t.sourceCwd)} has moved on: ${d} commit(s) are there and not in this workspace. Landing is fast-forward-only, so \`/hydra workspace sync\` now is what keeps \`stop\` from refusing later.
149
+ `))}async runWorkspaceAction(e,t,n,r){let o=this.get(e);if(o===void 0)throw new Error("session is not live");if(t==="status"){let a=o.workspace;if(a===void 0)return`Not isolated. Working directly in ${O(o.cwd)}.
150
+ Use \`/hydra workspace start\` to move into an isolated workspace.`;let d=this.liveSessionsIn(a.path,o.sessionId).map(f=>Oe(f.sessionId)),u=a.line,c=[`Isolated in ${O(a.path)}`,` source: ${O(a.sourceCwd)}`,` provider: ${a.provider}${u!==void 0?` (${u})`:""}`];d.length>0&&c.push(` shared with: ${d.join(", ")}`);let p=await X(a.provider)?.statusReport({path:a.path,sourceCwd:a.sourceCwd,label:a.label,provider:a.provider,...a.snapshot!==void 0?{snapshot:a.snapshot}:{},...a.vcs!==void 0?{vcs:a.vcs}:{}}).catch(()=>{});for(let f of p??[])c.push(` ${f}`);return c.push(d.length>0?`\`stop\` behaves as \`detach\` while ${d.length===1?"that session is":"those sessions are"} still here; the work lands when the last one leaves.`:"Use `/hydra workspace stop` to merge and return, `discard` to throw the work away, `detach` to return and leave it here, or `clean` to wipe it and keep working here."),c.join(`
151
+ `)}if(t==="start")return this.startWorkspace(o,n,{clean:r?.clean===!0});let i=o.workspace;if(i===void 0)throw new Error("this session is not in a workspace. Use `/hydra workspace start` first.");if(t==="sync")return(await this.syncWorkspaceFromSource(o,i,{onConflict:"keep"})).message;if(t==="clean")return await this.cleanWorkspace(o,i,{deep:r?.deep===!0});if(t==="merge"){o.broadcastWorkspacePhase({phase:"landing"});let a;try{a=await this.mergeWorkspaceIntoSource(i,o.sessionId)}catch(d){let u=d instanceof Error?d.message:String(d);throw o.broadcastWorkspacePhase({phase:"failed",error:u}),d}return o.broadcastWorkspacePhase({phase:"entered",cwd:o.cwd,sourceCwd:i.sourceCwd,label:i.label}),[`${a.merged}; still working in ${O(i.path)}.`,...a.warnings].join(`
152
+ `)}if(t==="stop"){let a=this.liveSessionsIn(i.path,o.sessionId);if(a.length>0){o.broadcastWorkspacePhase({phase:"returning"}),await this.leaveWorkspace(o,i,{exit:"detached"});let u=a.map(p=>Oe(p.sessionId)).join(", "),c=[`Left ${O(i.path)} and returned to ${O(i.sourceCwd)}.`,`Nothing landed yet: ${u} still working there. It lands when the last session leaves.`],l=await this.fastForwardBlocked(i);return l!==void 0&&c.push(`WARNING: that merge will not fast-forward as things stand \u2014 ${l}`),c.join(`
153
+ `)}o.broadcastWorkspacePhase({phase:"landing"});let d;try{d=await this.mergeWorkspaceIntoSource(i,o.sessionId)}catch(u){let c=u instanceof Error?u.message:String(u);throw o.broadcastWorkspacePhase({phase:"failed",error:c}),u}o.broadcastWorkspacePhase({phase:"returning"});try{await this.leaveWorkspace(o,i,{exit:"landed"})}catch(u){let c=u instanceof Error?u.message:String(u);throw new Error(`${d.merged}, but the session could not leave the workspace: ${c}`)}return[`${d.merged} and returned there; workspace removed.`,...d.warnings].join(`
154
+ `)}if(t==="discard"){let a=this.liveSessionsIn(i.path,o.sessionId);if(a.length>0)throw new Error(`${O(i.path)} is shared with ${a.map(c=>Oe(c.sessionId)).join(", ")}, so its work is not yours alone to discard. Use \`/hydra workspace detach\` to leave it to them.`);o.broadcastWorkspacePhase({phase:"returning"}),await this.leaveWorkspace(o,i,{exit:"discarded"});let d=await this.retireAutosave(i),u=[`Discarded ${O(i.path)} and its branch ${i.line??"(none)"}; returned to ${O(i.sourceCwd)}.`];return d!==void 0&&u.push(`The last autosave is kept at ${d} if you want it back: git -C ${i.sourceCwd} checkout ${d}`),u.join(`
155
+ `)}return o.broadcastWorkspacePhase({phase:"returning"}),await this.leaveWorkspace(o,i,{exit:"detached"}),[`Returned to ${O(i.sourceCwd)} WITHOUT merging.`,`The workspace is still at ${O(i.path)} and its branch ${i.line??"(none)"} is intact, so nothing is lost. Land it later with \`hydra workspace merge\`, or drop it with \`/hydra workspace discard\`.`].join(`
156
+ `)}asWorkspace(e){return{path:e.path,sourceCwd:e.sourceCwd,label:e.label,provider:e.provider,...e.snapshot!==void 0?{snapshot:e.snapshot}:{},...e.line!==void 0?{line:e.line}:{},...e.vcs!==void 0?{vcs:e.vcs}:{}}}async retireAutosave(e){let t=X(e.provider);if(t===void 0)return;let n=this.asWorkspace(e),r=this.snapshotRefFor(e.label),o=await t.resolveRetained(n,r).catch(()=>{});if(o===void 0)return;let i=Oi(e.label,o);return await t.retainSnapshot(n,i,o).then(()=>!0).catch(()=>!1)?(await t.dropSnapshotRef(n,r).catch(()=>{}),i):r}async cleanWorkspace(e,t,n){return await this.enqueueKeyed(this.workspaceQueues,t.path,async()=>{let r=this.liveSessionsIn(t.path,e.sessionId);if(r.length>0)throw new Error(`${O(t.path)} is shared with ${r.map(k=>Oe(k.sessionId)).join(", ")}, and a clean would destroy their work too. Clean it from a session that has it to itself.`);if(!await e.isQuiescedForSwap())throw new Error("the agent is still working; wait for the current turn to finish, then try again");let o=X(t.provider);if(o===void 0)throw new Error(`no provider "${t.provider}" available to clean this workspace`);if(t.snapshot===void 0||o.capabilities().sharedHistory!==!0)throw new Error(`workspace ${t.label} uses the "${t.provider}" provider, which records no base state to return to, so there is nothing to clean back to. Use \`/hydra workspace discard\` to throw it away instead.`);let i=this.asWorkspace(t),a=t.snapshot,u=(await o.status(i).catch(()=>{}))?.changedPaths.length??0,l=(await o.divergence(t.path,a,"HEAD").catch(()=>{}))?.behind??0,p=await o.currentState(t.path)??"",f=await this.retireAutosave(t);e.broadcastWorkspacePhase({phase:"cleaning",label:t.label});let m=await o.resetTo(t.path,a,{purgeIgnored:n.deep});if(!m.ok)throw new Error(`could not return ${O(t.path)} to its base: ${m.reason??"unknown error"}. Nothing was changed.`);let g=n.deep?await this.applyWorkspaceSetup(t,e.sessionId):void 0;await o.retainSnapshot(i,this.startRefFor(t.label),t.snapshot).catch(()=>{});let h={...t,clean:!0};e.workspace=h,await this.mutateRecord(e.sessionId,{workspace:h}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:t.sourceCwd,label:t.label,...i.line!==void 0?{branch:i.line}:{}});let y=[`Cleaned ${O(t.path)} back to the state it was created in.`];if(u>0||l>0){let k=[];u>0&&k.push(`${u} uncommitted change(s)`),l>0&&k.push(`${l} commit(s)`),y.push(` discarded ${k.join(" and ")}`)}else y.push(" nothing to discard; it was already at its base");return g!==void 0&&y.push(` ${g}`),f!==void 0&&y.push(` last autosave kept at ${f}: git -C ${t.sourceCwd} checkout ${f}`),l>0&&p.length>0&&y.push(` discarded commits are still at ${p.slice(0,12)} (and in the reflog for ${t.line??"this branch"})`),y.push(`Your uncommitted work in ${O(t.sourceCwd)} was never touched by this.`),y.join(`
157
+ `)})}async mergeWorkspaceIntoSource(e,t){let n=e.sourceCwd,r=e.line;if(r===void 0)throw new Error(`workspace ${e.label} has no line of work to land from`);if(!await this.dirExists(n))throw new Error(`source tree ${O(n)} no longer exists`);let i=X(e.provider),a=this.asWorkspace(e),d=await ji({source:n,ws:a,startSnapshotRef:this.startRefFor(e.label),baselineRef:this.baselineRefFor(e.label),retainRef:Fi(t),provider:i});if(i===void 0)throw new Error(`no provider "${e.provider}" available to land this workspace`);let u=await i.currentState(n);if(u===void 0)throw new Error(`could not read the state of ${O(n)}`);let c=await i.contains(n,{state:u,within:r}),l=[];if(!c){let S=this.get(t),x="";if(S!==void 0)try{let R=await this.syncWorkspaceFromSource(S,e,{onConflict:"abort"});R.ok?(l.push(`
158
+ synced with the source first: ${R.message}`),c=await i.contains(n,{state:u,within:r})):x=`
159
+ A sync was attempted first and could not complete: ${R.message}`}catch(R){x=`
160
+ A sync was attempted first but was refused: ${R instanceof Error?R.message:String(R)}`}if(!c){let R=await i.currentLineName(n)??"the source";throw new Error(`cannot fast-forward ${R} in ${O(n)} to ${r}. The source has moved on since this workspace was created. The source is untouched.${x}
161
+ `+(x.length>0?`Or land it by hand with: git -C ${n} merge ${r}`:`Resolve it in the workspace with \`/hydra workspace sync\` (which leaves the conflict there to fix), or land it by hand with: git -C ${n} merge ${r}`))}}let p=i!==void 0&&i.capabilities().supports.nestedTrees?await i.captureNested(e.path,await i.listNested(e.path)).catch(()=>[]):[],f,m=await i.status(a).catch(()=>{});if(m!==void 0&&m.changedPaths.length>0&&(f=await i.captureWorkingState(e.path,`hydra: uncommitted work in ${e.label}`).catch(()=>{}),f===void 0))throw new Error(`could not capture the uncommitted work in ${O(e.path)}; nothing was changed`);if(!d.clean&&!(await i.resetTo(n,u)).ok)throw new Error(`could not clear ${O(n)} for the merge; your work is preserved at ${d.retainedRef}. Nothing was merged.`);let g=await i.integrate({into:n,from:r,fastForwardOnly:!0});if(!g.ok)throw new Error(`merge failed: ${g.reason??"unknown error"}`);let h=!0;if(f!==void 0){let S=await i.captureDelta(n,g.snapshot,f);S!==void 0&&(h=(await i.applyDelta(n,S)).ok)}let y=await Bt({source:n,capture:d,provider:i});y&&await Di({source:n,ws:a,capture:d,provider:i});let k={applied:[],failed:[]},w=i!==void 0&&i.capabilities().supports.nestedTrees?await i.integrateNested(n,e.path,p).catch(()=>k):k,v=await i.captureWorkingState(n,`hydra: source state after landing ${e.label}`).catch(()=>{});v!==void 0&&await i.retainSnapshot({...a,path:n},this.baselineRefFor(e.label),v).catch(()=>{});let b=[];h||b.push(` WARNING: the workspace's uncommitted changes could not be replayed; they remain reachable from ${r}.`),y||b.push(e.clean===!0?` WARNING: this workspace started clean, so your uncommitted work was never copied in. The whole of it is being replayed now and it overlaps what the agent changed. All of it is preserved at ${d.retainedRef}; recover with: git -C ${n} diff ${d.base} ${d.retainedRef}`:` WARNING: your own edits to ${O(n)} overlap the workspace's changes and could not be replayed on top. They are preserved at ${d.retainedRef}; recover with: git -C ${n} diff ${d.base} ${d.retainedRef}`);for(let S of w.failed)b.push(` WARNING: nested tree ${S.path} was NOT reconciled: ${S.reason}. ${O(n)} now records a different state for it, so it will report it as modified until you resolve that.`);return{merged:`Merged ${r} into ${O(n)}${l.join("")}`,warnings:b}}async leaveWorkspace(e,t,n){let r=n.exit!=="detached",o=X(t.provider),i={path:t.path,sourceCwd:t.sourceCwd,label:t.label,provider:t.provider,...t.snapshot!==void 0?{snapshot:t.snapshot}:{},...t.vcs!==void 0?{vcs:t.vcs}:{}},a=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:t.sourceCwd,workspace:void 0,historyLength:a.length,artifact:{summary:`Returned to the source tree at ${t.sourceCwd}`+(n.exit==="landed"?" after merging the workspace.":n.exit==="discarded"?" after discarding the workspace and its work.":" without merging.")},left:{path:t.path,removed:r}}),await this.mutateRecord(e.sessionId,{cwd:e.cwd},["workspace"]),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"left",cwd:e.cwd,sourceCwd:t.sourceCwd,integrated:n.exit==="landed"}),o!==void 0&&await this.enqueueKeyed(this.workspaceQueues,t.path,async()=>{let d=this.liveSessionsIn(t.path,e.sessionId);if(d.length>0){this.logger?.info?.(`session workspace: ${e.sessionId} left ${t.path}; ${d.length} live session(s) remain, so it stays`);return}await this.reclaimAfterLastLeaver(o,i,t,e.sessionId,n)})}async reclaimAfterLastLeaver(e,t,n,r,o){await e.unlock(t).catch(()=>{});for(let i of[this.startRefFor(n.label),this.baselineRefFor(n.label)])await e.dropSnapshotRef(t,i).catch(()=>{});o.exit!=="detached"&&(o.exit==="landed"&&await e.dropSnapshotRef(t,this.snapshotRefFor(n.label)).catch(()=>{}),await e.removeWorkspace(t,{force:!0,discardLine:!0}).catch(()=>{}))}async joinDivergence(e,t,n){let[r,o]=await Promise.all([e.captureWorkingState(t,"hydra: source state at join").catch(()=>{}),e.captureWorkingState(n.path,"hydra: workspace state at join").catch(()=>{})]);if(r===void 0||o===void 0)return`could not compare ${O(t)} with ${O(n.path)}, so refusing to join a workspace that may not match your tree`;let i=await Promise.all([r,o].map(a=>e.contentId(t,a).catch(()=>{})));if(!(i[0]!==void 0&&i[0]===i[1]))return`${O(t)} and ${O(n.path)} have diverged, and joining does not carry work across \u2014 whichever side you are not in would be left behind. Land or stash one of them first: \`git -C ${t} stash\` if the difference is yours, or \`/hydra workspace merge\` from the session already in there if it is theirs.`}liveSessionsWithLabel(e,t){let n=[];for(let r of this.sessions.values()){let o=r.workspace;o===void 0||o.sourceCwd!==e||(o.label===t||o.requestedLabel===t)&&n.push(r)}return n}async joinWorkspace(e,t,n,r){let o=X(n.provider);if(o===void 0)throw new Error(`no provider "${n.provider}" to join that workspace with`);if(o.capabilities().supports.captureWorkingState){let i=await this.joinDivergence(o,r,n);if(i!==void 0)throw new Error(i)}return await this.enqueueKeyed(this.workspaceQueues,n.path,async()=>{if(this.sessions.get(t.sessionId)?.workspace?.path!==n.path)throw new Error(`${O(n.path)} was released while joining it; run the command again`);e.broadcastWorkspacePhase({phase:"swapping"});let i=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:n.path,workspace:{path:n.path,sourceCwd:n.sourceCwd,label:n.label,...n.requestedLabel!==void 0?{requestedLabel:n.requestedLabel}:{},provider:n.provider,...n.snapshot!==void 0?{snapshot:n.snapshot}:{},...n.line!==void 0?{line:n.line}:{},...n.vcs!==void 0?{vcs:{...n.vcs}}:{}},historyLength:i.length,artifact:{summary:`Continuing in an isolated workspace at ${n.path}, derived from ${r}, shared with another session.`}}),await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache();let a=n.line;e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:n.sourceCwd,label:n.label,...a!==void 0?{branch:a}:{}});let d=this.liveSessionsIn(n.path,e.sessionId).map(c=>Oe(c.sessionId)),u=[`Joined workspace ${O(n.path)}`,` source: ${O(n.sourceCwd)}`];return a!==void 0&&u.push(` branch: ${a}`),u.push(` shared with: ${d.join(", ")}`),u.push(" your edits will interleave with that session's"),u.push("Use `/hydra workspace stop` to leave; the work lands when the last session leaves."),u.join(`
162
+ `)})}async startWorkspace(e,t,n){if(e.workspace!==void 0)throw new Error(`already isolated in ${O(e.workspace.path)}. Use \`/hydra workspace stop\` to merge and return first, or \`detach\` to leave it behind.`);let r=e.cwd,o=X();if(o===void 0)throw new Error("no workspace provider available");if(!await e.isQuiescedForSwap())throw new Error("the agent is still working; wait for the current turn to finish, then try again");let i=o.capabilities();if(t!==void 0){let b=this.liveSessionsWithLabel(r,t)[0];if(b!==void 0&&b.workspace!==void 0)return await this.joinWorkspace(e,b,b.workspace,r)}let a,d=[],u=!1,c=!1,l=[],p=[],f=n?.clean===!0;if(i.supports.captureWorkingState){let b=await o.status({path:r,sourceCwd:r,label:"source",provider:o.kind}).catch(()=>{});c=b!==void 0;let S=i.supports.nestedTrees&&b!==void 0&&b.changedPaths.length>0?await o.listNested(r).catch(()=>[]):[];if(b!==void 0&&b.changedPaths.length>0&&f)l=dr(b.changedPaths,S);else if(b!==void 0&&b.changedPaths.length>0&&(d=dr(b.changedPaths,S),p=await o.captureNested(r,S).catch(()=>[]),u=b.hasStagedWork===!0,a=await o.captureWorkingState(r,"hydra: work carried into workspace").catch(()=>{}),a===void 0))throw new Error("could not snapshot your uncommitted work, so refusing to move it. Commit or stash first.")}e.broadcastWorkspacePhase({phase:"provisioning"});let m=await o.createWorkspace({sourceCwd:r,label:t??`s-${e.sessionId.slice(-8)}`});if(!m.ok)throw e.broadcastWorkspacePhase({phase:"failed",error:m.reason}),new Error(m.reason);let g=m.workspace,h=this.startRefFor(g.label),y,k=!1,w=[];try{i.locking&&await o.lock(g,`session ${e.sessionId}`).catch(()=>{});let b=a??g.snapshot;if(b===void 0)throw new Error(`provider "${g.provider}" gave the workspace no base to anchor landing against`);await o.retainSnapshot(g,h,b),e.broadcastWorkspacePhase({phase:"setup"}),k=a!==void 0?await this.copyCarriedWork(g,a,r):!0;let S=await this.materializeNestedTrees(g);if(p.length>0){let R=await o.reproduceNested(g.path,r,p).catch(P=>({applied:[],failed:p.map(H=>({path:H.relPath,reason:P instanceof Error?P.message:String(P)}))}));R.failed.length>0&&(k=!1,w=R.failed)}y=await this.applyWorkspaceSetup(g,e.sessionId),S!==void 0&&(y=y===void 0?S:`${S}; ${y}`),e.broadcastWorkspacePhase({phase:"swapping"});let x=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:g.path,workspace:{path:g.path,sourceCwd:g.sourceCwd,label:g.label,...t!==void 0&&t!==g.label?{requestedLabel:t}:{},provider:g.provider,...g.snapshot!==void 0?{snapshot:g.snapshot}:{},...g.line!==void 0?{line:g.line}:{},...g.vcs!==void 0?{vcs:{...g.vcs}}:{},...a===void 0?{clean:!0}:{}},historyLength:x.length,artifact:{summary:`Continuing in an isolated workspace at ${g.path}, derived from ${r}.`}})}catch(b){let S=await this.unwindStartWorkspace({provider:o,ws:g,startRef:h,carried:a}),x=b instanceof Error?b.message:String(b);throw e.broadcastWorkspacePhase({phase:"failed",error:x}),new Error(S===void 0?x:`${x}
163
+ ${S}`)}await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:g.sourceCwd,label:g.label,...g.line!==void 0?{branch:g.line}:{}});let v=[`Moved into workspace ${O(g.path)}`,` source: ${O(r)}`];if(g.line!==void 0&&v.push(` branch: ${g.line}`),t!==void 0&&t!==g.label&&v.push(` note: "${t}" was already taken by a surviving branch, so this is "${g.label}"`),a!==void 0){v.push(k?` carried ${d.length} uncommitted file(s) in; the source tree is untouched:`:` WARNING: could not copy ${d.length} uncommitted file(s); the workspace starts from HEAD. They are untouched in the source tree:`);for(let b of Ke(d))v.push(` ${b}`);k&&u&&v.push(" staging did not come along; everything above is unstaged here");for(let b of w)v.push(` nested tree ${b.path}: ${b.reason}`)}else if(l.length>0){v.push(` started clean: ${l.length} uncommitted file(s) stayed in the source and did NOT come along:`);for(let b of Ke(l))v.push(` ${b}`)}else c&&v.push(" source tree was clean; nothing carried in");return y!==void 0&&v.push(` ${y}`),v.push("Use `/hydra workspace stop` to merge back and return."),v.join(`
164
+ `)}async copyCarriedWork(e,t,n){let r=await this.patchFromSnapshot(n,t,e.provider);if(r===void 0)return!1;if(r.length===0)return!0;let o=X(e.provider);return o===void 0?!1:(await o.applyDelta(e.path,r)).ok}async patchFromSnapshot(e,t,n){let r=X(n);if(r===void 0)return;let o=await r.currentState(e);if(o!==void 0)return await r.captureDelta(e,o,t).catch(()=>{})}async unwindStartWorkspace(e){let{provider:t,ws:n,startRef:r,carried:o}=e;await t.unlock(n).catch(()=>{}),o!==void 0&&await t.dropSnapshotRef(n,r).catch(()=>{}),await t.removeWorkspace(n,{force:!0}).catch(()=>{})}async materializeNestedTrees(e,t){let n=X(e.provider);if(n?.capabilities().supports.nestedTrees!==!0)return;let r=await n.materializeNested({path:e.path,sourceCwd:e.sourceCwd,label:e.label,provider:n.kind},t).catch(o=>({ok:!1,count:0,reason:o instanceof Error?o.message:String(o)}));return r.ok?r.count>0?`populated ${r.count} nested tree(s)`:void 0:`nested trees FAILED: ${r.reason??"unknown"}`}async applyWorkspaceSetup(e,t){let n=await Pn(e.sourceCwd).catch(()=>({})),r=[];if(n.carry!==void 0&&n.carry.length>0){let o=await pr(e.sourceCwd,e.path,n.carry).catch(()=>{});o!==void 0&&o.copied.length>0&&r.push(`carried ${o.copied.length} config file(s)`)}if(n.postCreate!==void 0){let o=await Mn(n.postCreate,{workspacePath:e.path,sourceCwd:e.sourceCwd,label:e.label,sessionId:t,...n.hookTimeoutSeconds!==void 0?{timeoutSeconds:n.hookTimeoutSeconds}:{}});r.push(o.ok?"ran postCreate":`postCreate FAILED: ${o.reason??"unknown"}`)}return r.length>0?r.join("; "):void 0}async deriveForkWorkspace(e,t){let n=X(e.provider);if(n===void 0)return;let r=n.capabilities(),o=r.sharedHistory?await n.currentState(e.path)??"":"",i=await n.createWorkspace({sourceCwd:e.sourceCwd,label:t,...o.length>0?{from:o}:{contentFrom:e.path}}).catch(d=>({ok:!1,reason:String(d)}));if(!i.ok){this.logger?.warn?.(`fork workspace: could not derive from ${e.path}: ${i.reason}`);return}let a=i.workspace;if(o.length>0&&r.supports.captureWorkingState){let d=await n.captureWorkingState(e.path,`hydra: fork carry from ${e.label}`).catch(()=>{});d!==void 0&&d!==o&&await this.copyUncommittedInto(e.path,a.path,o,d,a.provider).catch(()=>{})}return{path:a.path,sourceCwd:a.sourceCwd,label:a.label,provider:a.provider,...a.snapshot!==void 0?{snapshot:a.snapshot}:{},...a.line!==void 0?{line:a.line}:{},...a.vcs!==void 0?{vcs:{...a.vcs}}:{}}}async copyUncommittedInto(e,t,n,r,o){let i=X(o);if(i===void 0)return!1;let a=await i.captureDelta(e,n,r).catch(()=>{});return a===void 0||a.trim().length===0?!1:(await i.applyDelta(t,a,{stage:!0})).ok}async recoverWorkspace(e){let t=X(e.provider);if(t===void 0)return;let n={path:e.path,sourceCwd:e.sourceCwd,label:e.label,provider:e.provider,...e.snapshot!==void 0?{snapshot:e.snapshot}:{},...e.vcs!==void 0?{vcs:e.vcs}:{}};if(t.capabilities().supports.rematerialize){let o=await t.rematerialize(n).catch(i=>({ok:!1,reason:String(i)}));if(o.ok)return this.logger?.info?.(`session workspace: restored ${o.workspace.path} from retained state`),{...e,path:o.workspace.path};this.logger?.warn?.(`session workspace: could not restore: ${o.reason}`)}if(!await this.dirExists(e.sourceCwd))return;let r=await t.createWorkspace({sourceCwd:e.sourceCwd,label:`${e.label}-r`}).catch(o=>({ok:!1,reason:String(o)}));if(r.ok)return this.logger?.warn?.(`session workspace: ${e.path} is gone and could not be restored; resurrecting in a fresh workspace ${r.workspace.path} from ${e.sourceCwd}. Uncommitted work from the old workspace is not recoverable.`),{path:r.workspace.path,sourceCwd:r.workspace.sourceCwd,label:r.workspace.label,provider:r.workspace.provider,...r.workspace.snapshot!==void 0?{snapshot:r.workspace.snapshot}:{},...r.workspace.vcs!==void 0?{vcs:{...r.workspace.vcs}}:{}}}async syncFromAgent(e){let t=await this.registry.getAgent(e);if(!t){let f=new Error(`agent ${e} not found in registry`);throw f.code=C.AgentNotInstalled,f}let n=await ye(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:ma.homedir(),plan:n}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:it,clientInfo:{name:"hydra",version:ie}})}catch(f){throw await r.kill().catch(()=>{}),Ve(f,r)}if(r.authMethods=zt(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(f){throw await r.kill().catch(()=>{}),f}await r.kill().catch(()=>{});let d=new Set;for(let f of this.sessions.values())d.add(`${f.agentId}::${f.upstreamSessionId}`);let u=await this.store.list().catch(()=>[]);for(let f of u){d.add(`${f.agentId}::${f.upstreamSessionId}`);for(let m of f.upstreamGenerations??[])d.add(`${m.agentId}::${m.upstreamSessionId}`)}let c=A.sessionsDir(),l=[],p=0;for(let f of a){let m=`${e}::${f.sessionId}`;if(d.has(m)){p+=1;continue}if(uf(f.cwd,c)){p+=1;continue}let g=await this.tombstones.read(e,f.sessionId).catch(()=>{});if(g){if(!Li(g,f.updatedAt)){p+=1;continue}await this.tombstones.remove(e,f.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${f.sessionId} (upstream updatedAt advanced past ${g.upstreamUpdatedAt??"<unset>"})`)}d.add(m);let h=`${Pe}${St()}`,y=new Date().toISOString(),k=f.updatedAt??y,w={sessionId:h,lineageId:jt(),upstreamSessionId:f.sessionId,agentId:e,cwd:f.cwd,pendingHistorySync:!0,interactive:!0,createdAt:k,updatedAt:k};f.title!==void 0&&(w.title=f.title);let v=ir(w);await this.store.write(v),l.push({version:1,...v})}return{synced:l,skipped:p}}async collectAgentSessions(e){let t=[],n,r=new Set;for(let o=0;o<100;o+=1){let i={};n!==void 0&&(i.cursor=n);let a=await e.connection.request("session/list",i),d=Array.isArray(a.sessions)?a.sessions:[];for(let 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),n=a.nextCursor}return t}async applySeedModel(e,t,n,r,o){try{let{verb:i}=await Je({request:(a,d)=>e.connection.request(a,d),sessionId:t,modelId:n,...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=C.AgentNotInstalled,i}let n=await ye(t,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),r=on(e.selfSessionId,e.forwardedEnv),o=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:n,...r?{extraEnv:r}:{}});try{let i=await o.connection.request("initialize",{protocolVersion:1,clientCapabilities:it,clientInfo:{name:"hydra",version:ie}}),a=i.agentCapabilities;o.authMethods=zt(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=br(d),l=Ir(d),p=dt(d),f=e.model??this.defaultModels[e.agentId];if(f&&f!==c){let h=pt(f,l),y=e.model!==void 0?`model=${JSON.stringify(f)}`:`defaultModels[${e.agentId}]=${JSON.stringify(f)}`;if(h.kind==="exact"||h.kind==="none")await this.applySeedModel(o,u,f,y,p)&&(c=f);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 k=l.map(w=>w.modelId).join(", ");this.logger?.warn(`${y} not in agent's availableModels ([${k}]); skipping session/set_model, session will use ${JSON.stringify(c)}`)}}let m=Ar(d),g=Cr(d);return{agent:o,upstreamSessionId:u,agentMeta:d._meta,agentCapabilities:a,initialModel:c,initialModels:l.length>0?l:void 0,initialModes:m.length>0?m:void 0,initialMode:g,modelVerb:p}}catch(i){throw await o.kill().catch(()=>{}),Ve(pa(i,o,e.agentId,{command:n.command,args:n.args,cwd:e.cwd}),o)}}async bootstrapAgentLoad(e,t){let n=await this.registry.getAgent(t.agentId);if(!n){let a=new Error(`agent ${t.agentId} not found in registry`);throw a.code=C.AgentNotInstalled,a}let r=await ye(n,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=on(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:it,clientInfo:{name:"hydra",version:ie}}),d=a.agentCapabilities;i.authMethods=zt(a.authMethods);let u=la(t.agentId,void 0),c=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...u&&{_meta:u}}),l=br(c),p=Sr(Ir(c)),f=Ar(c),m=Cr(c);return{agent:i,upstreamSessionId:e,agentMeta:c._meta,agentCapabilities:d,initialModel:l,initialModels:p,initialModes:f.length>0?f:void 0,initialMode:m,modelVerb:dt(c)}}catch(a){throw await i.kill().catch(()=>{}),Ve(pa(a,i,t.agentId,{command:r.command,args:r.args,cwd:t.cwd}),i)}}async performUncompact(e){if(this.rollbackLocks.has(e))throw new Error("a rollback is already in progress for this session");let t=this.get(e);if(!t)throw new Error("session is not live \u2014 cannot roll back a cold session");let n=await this.store.read(e);if(!n)throw new Error("session record not found");let r=n.rollbackBreadcrumb;if(!r)throw new Error("no rollback breadcrumb found \u2014 either the session has not been compacted, the rollback window has closed (a new turn was dispatched), or a previous rollback already consumed the breadcrumb");let o=n.compactionState;if(o!=null)throw new Error(`compaction is in progress (status: ${o.status}) \u2014 wait for it to complete before rolling back`);if(!await t.isQuiescedForSwap())throw new Error("session is not quiesced for rollback \u2014 wait for in-flight work to complete");this.rollbackLocks.add(e);try{await t.rollbackToUpstream({previousUpstreamSessionId:r.previousUpstreamSessionId,previousSummarizedThroughEntry:r.previousSummarizedThroughEntry}),await this.mutateRecord(e,{summarizedThroughEntry:r.previousSummarizedThroughEntry},["synopsis","rollbackBreadcrumb"])}finally{this.rollbackLocks.delete(e)}}async bootstrapAgentForAuth(e,t){let n=this.pendingAuthAgents.get(e);if(n&&n.isAlive())return n;let r=await this.registry.getAgent(e);if(!r){let d=new Error(`agent ${e} not found in registry`);throw d.code=C.AgentNotInstalled,d}let o=await ye(r,[],{npmRegistry:this.npmRegistry}),i=t??de(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:it,clientInfo:{name:"hydra",version:ie}});a.authMethods=zt(d.authMethods)}catch(d){throw await a.kill().catch(()=>{}),Ve(d,a)}return this.pendingAuthAgents.set(e,a),a.onExit(()=>{this.pendingAuthAgents.get(e)===a&&this.pendingAuthAgents.delete(e)}),a}async planSpawnForAgent(e){let t=await this.registry.getAgent(e);if(!t){let n=new Error(`agent ${e} not found in registry`);throw n.code=C.AgentNotInstalled,n}return ye(t,[],{npmRegistry:this.npmRegistry})}consumePendingAuthAgent(e){let t=this.pendingAuthAgents.get(e);if(t&&(this.pendingAuthAgents.delete(e),!!t.isAlive()))return t}getAgentForSession(e){return this.sessions.get(e)?.agent}async attachManagerHooks(e){e.onClose(({deleteRecord:t})=>{if(this.sessions.delete(e.sessionId),this.driftNoticed.delete(e.sessionId),this.invalidateListCache(),t&&e.workspace!==void 0&&this.releaseWorkspace(e.workspace,e.sessionId).catch(()=>{}),t){if(e.upstreamSessionId){let r=It({interactive:e.interactive,...e.originatingClient?{originatingClient:e.originatingClient}:{}},!0),o=this.tombstoneAllGenerations(e.sessionId,{agentId:e.agentId,upstreamSessionId:e.upstreamSessionId,upstreamUpdatedAt:new Date(e.updatedAt).toISOString(),cwd:e.cwd,...e.title!==void 0?{title:e.title}:{},...r!==void 0?{interactive:r}:{}},"user").catch(()=>{}).then(()=>this.store.delete(e.sessionId).catch(()=>{})).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===o&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,o);return}let n=this.store.delete(e.sessionId).catch(()=>{}).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===n&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,n);return}}),e.onTitleChange(t=>{this.persistTitle(e.sessionId,t).catch(()=>{})}),e.onPriorityChange(t=>{this.persistPriority(e.sessionId,t).catch(()=>{})}),e.onAgentChange(({agentId:t,upstreamSessionId:n,retiredCost:r})=>{this.persistAgentChange(e.sessionId,t,n,r).catch(()=>{})}),e.onModelChange(t=>{this.persistSnapshot(e.sessionId,{currentModel:t}).catch(()=>{})}),e.onModeChange(t=>{this.persistSnapshot(e.sessionId,{currentMode:t}).catch(()=>{})}),e.onInteractiveChange(t=>{this.persistSnapshot(e.sessionId,{interactive:t}).catch(()=>{})}),e.onUsageChange(t=>{this.persistSnapshot(e.sessionId,{currentUsage:ha(t)}).catch(()=>{})}),e.onAgentCommandsChange(t=>{this.persistSnapshot(e.sessionId,{agentCommands:t.map(n=>({name:n.name,...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModesChange(t=>{this.persistSnapshot(e.sessionId,{agentModes:t.map(n=>({id:n.id,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModelsChange(t=>{this.persistSnapshot(e.sessionId,{agentModels:t.map(n=>({modelId:n.modelId,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAttentionFlagsChange(t=>{this.mutateRecord(e.sessionId,{attentionFlags:t}).catch(()=>{})}),this.sessions.set(e.sessionId,e),this.invalidateListCache(),await this.enqueueMetaWrite(e.sessionId,async()=>{let t=await this.store.read(e.sessionId),n=lf(e,t);await this.store.write(n)}).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 Mt(e,t)}async loadFromDisk(e){let t=await this.store.read(e);if(!t)return;let n=t.title;return n||(n=await this.deriveTitleFromHistory(e)),{hydraSessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,agentId:t.agentId,cwd:t.cwd,title:n,synopsis:t.synopsis,summarizedThroughEntry:t.summarizedThroughEntry,agentArgs:t.agentArgs,currentModel:t.currentModel,currentMode:t.currentMode,currentUsage:ff(t.currentUsage),agentCommands:t.agentCommands,agentModes:t.agentModes,agentModels:t.agentModels,createdAt:t.createdAt,pendingHistorySync:t.pendingHistorySync,originatingClient:t.originatingClient,interactive:t.interactive,priority:t.priority,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,forkSynthesisState:t.forkSynthesisState,forwardedEnv:t.forwardedEnv,workspace:t.workspace,compactionState:t.compactionState,attentionFlags:t.attentionFlags?.filter(r=>!(r.source==="daemon"&&r.reason.startsWith("permission:")))}}async setForwardedEnv(e,t){if(t===void 0)return;let n=this.sessions.get(e);n&&(n.forwardedEnv=t),await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r)return;let o={...r,forwardedEnv:t};await this.store.write(o)})}async clearPendingHistorySync(e){await this.enqueueMetaWrite(e,async()=>{let t=await this.store.read(e);if(!t||t.pendingHistorySync!==!0)return;let n={...t};delete n.pendingHistorySync,await this.store.write(n)})}async deriveTitleFromHistory(e){let t=await this.histories.load(e).catch(()=>[]);for(let n of t){let r=n.params;if(r?.update?.sessionUpdate!=="prompt_received")continue;let o=mt(r.update.prompt),i=Xs(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 n=t.agent.agentId,r=t.agent.version,o=e.get(n);o||(o=new Set,e.set(n,o)),o.add(r)}return e}async resolveCanonicalId(e){if(this.sessions.has(e)||await this.store.read(e))return e;if(e.startsWith(Pe))return;let t=Pe+e;if(this.sessions.has(t)||await this.store.read(t))return t}require(e){let t=this.sessions.get(e);if(!t){let n=new Error(`session ${e} not found`);throw n.code=C.SessionNotFound,n}return t}liveListEntry(e){return{sessionId:e.sessionId,upstreamSessionId:e.upstreamSessionId,cwd:e.cwd,workspace:e.workspace,workspaceError:e.workspaceError,title:e.title,agentId:e.agentId,currentModel:e.currentModel,currentUsage:e.currentUsage,parentSessionId:e.parentSessionId,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,forkSynthesisState:e.forkSynthesisState,originatingClient:e.originatingClient,interactive:e.interactive,updatedAt:new Date(e.updatedAt).toISOString(),attachedClients:e.attachedCount,status:"warm",busy:e.turnStartedAt!==void 0,armedTasks:e.armedBackgroundTasks.length,...e.armedSince!==void 0?{armedSince:e.armedSince}:{},awaitingInput:e.awaitingInput,agentPid:e.agentPid}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Jt(t.sessionId),d=It({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,armedTasks:t.armedBackgroundTasks.length,...t.armedSince!==void 0?{armedSince:t.armedSince}:{},awaitingInput:t.awaitingInput}}let n=await this.store.read(e).catch(()=>{});if(!n)return;let r=await Jt(n.sessionId),o=It(n,r.hasContent),i=r.mtime??n.updatedAt;return{sessionId:n.sessionId,upstreamSessionId:n.upstreamSessionId,cwd:n.cwd,title:n.title,agentId:n.agentId,currentModel:n.currentModel,currentUsage:qt(n.currentUsage),importedFromMachine:n.importedFromMachine,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:o,priority:n.priority,updatedAt:i,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1}}async list(e={}){let t=`${e.cwd??""}|${e.includeNonInteractive?"1":"0"}|${e.status??""}`,n=Date.now(),r=this.listCache.get(t);if(r&&r.expiresAt>n)return r.promise;let o=this.listUncached(e);return this.listCache.set(t,{expiresAt:n+s.LIST_CACHE_TTL_MS,promise:o}),o.catch(()=>{let i=this.listCache.get(t);i&&i.promise===o&&this.listCache.delete(t)}),o}invalidateListCache(){this.listCache.clear()}async listUncached(e={}){let t=[],n=new Set,r=c=>e.includeNonInteractive?!0:c===!0,o=[...this.sessions.values()].filter(c=>ua(e.cwd,c));if(e.status==="cold")for(let c of o)n.add(c.sessionId);let i=e.status==="cold"?[]:await Promise.all(o.map(c=>Jt(c.sessionId)));for(let c=0;c<i.length;c+=1){let l=o[c],p=i[c];n.add(l.sessionId);let f=It({interactive:l.interactive,...l.originatingClient?{originatingClient:l.originatingClient}:{}},p.hasContent);if(!r(f))continue;let m=p.mtime??new Date(l.updatedAt).toISOString();t.push({sessionId:l.sessionId,upstreamSessionId:l.upstreamSessionId,cwd:l.cwd,workspace:l.workspace,workspaceError:l.workspaceError,title:l.title,agentId:l.agentId,currentModel:l.currentModel,currentUsage:l.currentUsage,parentSessionId:l.parentSessionId,forkedFromSessionId:l.forkedFromSessionId,forkedFromMessageId:l.forkedFromMessageId,originatingClient:l.originatingClient,interactive:f,priority:l.priority,updatedAt:m,attachedClients:l.attachedCount,status:"warm",agentPid:l.agentPid,busy:l.turnStartedAt!==void 0,armedTasks:l.armedBackgroundTasks.length,...l.armedSince!==void 0?{armedSince:l.armedSince}:{},awaitingInput:l.awaitingInput,compactionState:l.compactionState,forkSynthesisState:l.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=>!n.has(c.sessionId)&&ua(e.cwd,c)),u=await Promise.all(d.map(c=>Jt(c.sessionId)));for(let c=0;c<d.length;c+=1){let l=d[c],p=u[c],f=It(l,p.hasContent);if(!r(f))continue;let m=p.mtime??l.updatedAt;t.push({sessionId:l.sessionId,upstreamSessionId:l.upstreamSessionId,cwd:l.cwd,workspace:l.workspace,title:l.title,agentId:l.agentId,currentModel:l.currentModel,currentUsage:qt(l.currentUsage),importedFromMachine:l.importedFromMachine,importedFromUpstreamSessionId:l.importedFromUpstreamSessionId,parentSessionId:l.parentSessionId,forkedFromSessionId:l.forkedFromSessionId,forkedFromMessageId:l.forkedFromMessageId,originatingClient:l.originatingClient,interactive:f,priority:l.priority,updatedAt:m,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,compactionState:l.compactionState,forkSynthesisState:l.forkSynthesisState})}return t.sort((c,l)=>c.updatedAt<l.updatedAt?1:-1),t}async exportBundle(e,t={}){let n=await this.store.read(e);if(!n)return;let r;if(n.lineageId)r=n;else{let u=jt(),c={...n,lineageId:u};await this.enqueueMetaWrite(e,async()=>{let l=await this.store.read(e);l&&(l.lineageId||await this.store.write({...l,lineageId:u}))}).catch(()=>{}),r=c}let o=t.tools??"inline",i=await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await ga(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let u of na(i)){let c=await fo(e,u);c&&(d[u]=c.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}async importBundle(e,t={}){let n=await this.store.findByLineageId(e.session.lineageId);if(n){if(!t.replace){let i=new Error(`bundle already imported as ${n.sessionId}`);throw i.code=C.BundleAlreadyImported,i.existingSessionId=n.sessionId,i}let o=this.sessions.get(n.sessionId);return o&&await o.close({deleteRecord:!1}).catch(()=>{}),await this.writeImportedRecord({sessionId:n.sessionId,bundle:e,preservedCreatedAt:n.createdAt,cwd:t.cwd}),{sessionId:n.sessionId,importedFromSessionId:e.session.sessionId,replaced:!0}}let r=`${Pe}${St()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let n=await this.store.read(e);if(!n){let b=new Error(`source session not found: ${e}`);throw b.code=C.SessionNotFound,b}let r=t.agentId??n.agentId,o=r!==n.agentId;if(o&&!await this.registry.getAgent(r)){let S=new Error(`agent ${r} not found in registry`);throw S.code=C.AgentNotInstalled,S}let i=await this.histories.load(e).catch(()=>[]),a=i,d,u=t.mode??"synthesis",c,l,p,f=12e4;if(u==="verbatim")if(t.forkAt!==void 0){let b=kn(i,t.forkAt);if(b<0){let S=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw S.code=C.InvalidParams,S}d=t.forkAt,a=i.slice(0,b+1)}else{let b=gf(i);b?(d=b.messageId,a=i.slice(0,b.index+1)):(d="",a=i.slice(0,0))}else{if(t.forkAt!==void 0&&t.forkAt!==""){let S=kn(i,t.forkAt);if(S<0){let x=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw x.code=C.InvalidParams,x}d=t.forkAt,a=i.slice(0,S+1)}else d="",a=i;let b=await this.registry.getAgent(r);if(!b){let S=new Error(`agent ${r} not found in registry`);throw S.code=C.AgentNotInstalled,S}p=b,l=n.currentModel,c="running"}let m=await ga(e),g=u==="synthesis",h={...n,lineageId:jt(),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=Wt({record:h,history:a,promptHistory:m.length>0?m:void 0,hydraVersion:ie,machine:_t()}),k=`${Pe}${St()}`,w=t.cwd,v;if(t.cwd===void 0&&n.workspace!==void 0){let b=await this.deriveForkWorkspace(n.workspace,`${n.workspace.label}-fork-${k.slice(-6)}`);b!==void 0?(v=b,w=b.path):(w=n.workspace.sourceCwd,this.logger?.warn?.(`fork ${k}: could not derive an isolated workspace from ${n.workspace.path}; running unisolated in ${w}`))}return await this.writeImportedRecord({sessionId:k,bundle:y,cwd:w,...v!==void 0?{workspace:v}:{},forkedFromSessionId:e,forkedFromMessageId:d,...c!==void 0?{forkSynthesisState:c}:{}}),g&&(async()=>{try{let b=await ye(p,[],{npmRegistry:this.npmRegistry}),S=await Fn({agentId:r,cwd:t.cwd??A.sessionDir(e),plan:b,history:a,modelId:l,sessionId:e,logger:this.logger,timeoutMs:f});S&&S.synopsis?await this.mutateRecord(k,{synopsis:S.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(k,{},["forkSynthesisState"]))}catch(b){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${b.message}`);try{await this.mutateRecord(k,{},["forkSynthesisState"])}catch(S){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${S.message}`)}}})(),{sessionId:k,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 po(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await Ge.utimes(A.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await aa(A.tuiHistoryFile(e.sessionId),e.bundle.promptHistory).catch(()=>{});let n=new Date().toISOString(),r=e.forkedFromSessionId!==void 0;await this.enqueueMetaWrite(e.sessionId,async()=>{await this.store.write({sessionId:e.sessionId,lineageId:e.bundle.session.lineageId,upstreamSessionId:"",...r?{forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId}:{importedFromSessionId:e.bundle.session.sessionId,importedFromUpstreamSessionId:e.bundle.session.upstreamSessionId,importedFromMachine:e.bundle.exportedFrom.machine},agentId:e.bundle.session.agentId,cwd:e.cwd??e.bundle.session.cwd,workspace:e.workspace,title:e.bundle.session.title,synopsis:e.bundle.session.synopsis,summarizedThroughEntry:e.bundle.session.summarizedThroughEntry,...e.forkSynthesisState!==void 0?{forkSynthesisState:e.forkSynthesisState}:{},currentModel:e.bundle.session.currentModel,currentMode:e.bundle.session.currentMode,currentUsage:e.bundle.session.currentUsage,agentCommands:e.bundle.session.agentCommands,agentModes:e.bundle.session.agentModes,interactive:e.bundle.session.interactive,originatingClient:e.bundle.session.originatingClient,priority:e.bundle.session.priority,attentionFlags:[],createdAt:e.preservedCreatedAt??n,updatedAt:e.bundle.session.updatedAt})})}async tombstoneAllGenerations(e,t,n){let r=await this.store.read(e).catch(()=>{}),o=new Map;for(let a of r?.upstreamGenerations??[])a.upstreamSessionId&&o.set(`${a.agentId}::${a.upstreamSessionId}`,{agentId:a.agentId,upstreamSessionId:a.upstreamSessionId});o.set(`${t.agentId}::${t.upstreamSessionId}`,{agentId:t.agentId,upstreamSessionId:t.upstreamSessionId});let i=new Date().toISOString();for(let a of o.values())await this.tombstones.add({agentId:a.agentId,upstreamSessionId:a.upstreamSessionId,deletedAt:i,upstreamUpdatedAt:t.upstreamUpdatedAt,cwd:t.cwd,...t.title!==void 0?{title:t.title}:{},reason:n,...t.interactive!==void 0?{interactive:t.interactive}:{}}).catch(()=>{})}async deleteRecord(e,t="user"){let n=await this.store.read(e);if(!n)return!1;if(n.upstreamSessionId){let r=await Jt(e),o=It(n,r.hasContent);await this.tombstoneAllGenerations(e,{agentId:n.agentId,upstreamSessionId:n.upstreamSessionId,upstreamUpdatedAt:n.updatedAt,cwd:n.cwd,...n.title!==void 0?{title:n.title}:{},...o!==void 0?{interactive:o}:{}},t)}return n.workspace!==void 0&&await this.releaseWorkspace(n.workspace,e).catch(()=>{}),await this.store.delete(e).catch(()=>{}),await this.histories.delete(e).catch(()=>{}),this.invalidateListCache(),!0}async waitForDeletion(e){let t=this.pendingDeletions.get(e);t&&await t}async isTombstoned(e,t){return(await this.tombstones.read(e,t).catch(()=>{}))?.reason==="user"}async hasRecord(e){return await this.store.read(e).catch(()=>{})!==void 0}async clearWorkspaceBinding(e){if(this.get(e)!==void 0)return"live";let t=await this.store.read(e).catch(()=>{});if(!t)return"missing";let n=t.workspace?.sourceCwd;return await this.mutateRecord(e,n!==void 0?{cwd:n}:{},["workspace"]),"cleared"}async setCwd(e,t){if(this.get(e)!==void 0)return"live";let n=await this.store.read(e).catch(()=>{});return n?n.workspace!==void 0?"bound":await this.dirExists(t)?(await this.mutateRecord(e,{cwd:t}),this.invalidateListCache(),"set"):"not-a-directory":"missing"}async setPriority(e,t){let n=this.get(e);if(n)return n.setPriority(t),!0;if(!await this.hasRecord(e))return!1;let r=t===void 0||t<=0?void 0:Math.floor(t);return await this.persistPriority(e,r),!0}async persistPriority(e,t){t===void 0?await this.mutateRecord(e,{},["priority"]):await this.mutateRecord(e,{priority:t}),this.invalidateListCache()}async setTitle(e,t){let n=this.get(e);return n?(await n.retitle(t),!0):await this.hasRecord(e)?(await this.persistTitle(e,t),!0):!1}async persistTitle(e,t){await this.mutateRecord(e,{title:t})}async persistSynopsis(e,t,n){await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:n})}async persistAgentChange(e,t,n,r){await this.mutateRecord(e,{agentId:t,upstreamSessionId:n},void 0,o=>({upstreamGenerations:ya(o,t,n,void 0,r)}))}async persistSnapshot(e,t){let n={};t.currentModel!==void 0&&(n.currentModel=t.currentModel),t.currentMode!==void 0&&(n.currentMode=t.currentMode),t.currentUsage!==void 0&&(n.currentUsage=t.currentUsage),t.agentCommands!==void 0&&(n.agentCommands=t.agentCommands),t.agentModes!==void 0&&(n.agentModes=t.agentModes),t.agentModels!==void 0&&(n.agentModels=t.agentModels),t.interactive!==void 0&&(n.interactive=t.interactive),t.cwd!==void 0&&(n.cwd=t.cwd),await this.mutateRecord(e,n)}async mutateRecord(e,t,n=[],r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o,...t,...r?r(o):{},updatedAt:new Date().toISOString()};for(let a of n)delete i[a];await this.store.write(i)})}static EXTENSION_STATE_CAP_BYTES=64*1024;async getExtensionState(e,t){return(await this.store.read(e))?.extensionState?.[t]??{}}async getExtensionStateKey(e,t,n){return(await this.getExtensionState(e,t))[n]}async setExtensionStateKey(e,t,n,r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o.extensionState??{}},a={...i[t]??{},[n]:r},d=Buffer.byteLength(JSON.stringify(a),"utf8");if(d>s.EXTENSION_STATE_CAP_BYTES)throw new Error(`extension_state: bucket for ${t} would be ${d} bytes; cap is ${s.EXTENSION_STATE_CAP_BYTES}`);i[t]=a;let u={...o,extensionState:i,updatedAt:new Date().toISOString()};await this.store.write(u)})}async deleteExtensionStateKey(e,t,n){await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r?.extensionState?.[t])return;let o={...r.extensionState},i={...o[t]};if(!(n in i))return;delete i[n],Object.keys(i).length===0?delete o[t]:o[t]=i;let a={...r,extensionState:o,updatedAt:new Date().toISOString()};await this.store.write(a)})}enqueueMetaWrite(e,t){return this.enqueueKeyed(this.metaWriteQueues,e,t)}enqueueKeyed(e,t,n){let o=(e.get(t)??Promise.resolve()).catch(()=>{}).then(n),i=o.catch(()=>{});return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)}),o}liveSessionsIn(e,t){let n=[];for(let r of this.sessions.values())r.sessionId!==t&&r.workspace?.path===e&&n.push(r);return n}async closeAll(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(t=>t.close({deleteRecord:!1}))),this.sessions.clear()}async flushSynopsis(e){await this.synopsisCoordinator.flush(e)}async shutdownSynopsis(){await this.synopsisCoordinator.shutdown()}scheduleSynopsis(e){this.synopsisCoordinator.schedule(e)}scheduleCompaction(e,t){if(t?.targetAgentId){this.mutateRecord(e,{pendingAgentSwap:t.targetAgentId}).catch(r=>{this.logger?.warn(`scheduleCompaction: failed to stamp pendingAgentSwap for ${e}: ${r instanceof Error?r.message:String(r)}`)});let n=t.targetAgentId;(async()=>{try{let r=await this.store.read(e);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=${n} (reusing artifact @${r.summarizedThroughEntry})`),await this.dispatchSynthesisSwap(e,r.synopsis,r.summarizedThroughEntry,n)}catch(r){this.logger?.warn(`scheduleCompaction: fast-path check failed for ${e}: ${r instanceof Error?r.message:String(r)} \u2014 falling back to synthesis`),this.synopsisCoordinator.scheduleCompaction(e,t)}})();return}this.synopsisCoordinator.scheduleCompaction(e,t)}getCompactionInFlight(){let e=this.synopsisCoordinator.size();return e.inflight>0||e.queued>0}async getPendingAgentSwap(e){return(await this.store.read(e).catch(()=>{}))?.pendingAgentSwap}async getCompactionState(e){return(await this.store.read(e).catch(()=>{}))?.compactionState}async getRollbackBreadcrumb(e){return(await this.store.read(e).catch(()=>{}))?.rollbackBreadcrumb}emitSwapPhase(e,t,n){let r=this.get(e);if(r){if(t){let o=n.phase==="failed";r.broadcastPendingAgentSwap(o?null:t);return}r.broadcastCompactionPhase(n)}}async getSummarizedThroughEntry(e){let t=this.sessions.get(e);return t?t.summarizedThroughEntry:(await this.store.read(e).catch(()=>{}))?.summarizedThroughEntry}async flushMetaWrites(){let e=[...this.metaWriteQueues.values()];e.length!==0&&await Promise.allSettled(e)}async flushHistoryWrites(){await this.histories.flushAll()}async reconcilePermissionFlags(){let e=await this.store.list().catch(()=>[]),t=0;for(let n of e){let r=n.attentionFlags??[],o=r.filter(i=>!(i.source==="daemon"&&i.reason.startsWith("permission:")));if(o.length!==r.length){let i=r.length-o.length;t+=i,await this.mutateRecord(n.sessionId,{attentionFlags:o}).catch(()=>{})}}t>0&&this.logger?.info(`cleared ${t} stale permission attention flags on startup`)}async resumePendingCompactions(){let e=new Set(["requested","running","swap_pending","swap_deferred"]),t=await this.store.list().catch(()=>[]);for(let n of t){let r=n.compactionState;if(r!=null){if(!e.has(r.status)){this.logger?.info(`compaction: not resuming sessionId=${n.sessionId} status=${r.status} (terminal \u2014 user must re-trigger explicitly)`);continue}this.logger?.info(`compaction: resuming sessionId=${n.sessionId} status=${r.status} from prior daemon`);try{this.scheduleCompaction(n.sessionId)}catch(o){this.logger?.warn(`compaction: resume failed for sessionId=${n.sessionId}: ${o instanceof Error?o.message:String(o)}`)}}}}async resumePendingAgentSwaps(){let e=await this.store.list().catch(()=>[]);for(let t of e){let n=t.pendingAgentSwap;if(n)try{let r=await this.histories.load(t.sessionId).catch(()=>[]);t.synopsis!==void 0&&t.summarizedThroughEntry!==void 0&&t.summarizedThroughEntry>=r.length&&t.synopsis?(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${n} with persisted synopsis (history=${r.length})`),await this.dispatchSynthesisSwap(t.sessionId,t.synopsis,t.summarizedThroughEntry??r.length,n)):(this.logger?.info(`agent-swap: resuming sessionId=${t.sessionId} target=${n} via fresh synthesis (history=${r.length} watermark=${t.summarizedThroughEntry??"(none)"})`),this.scheduleCompaction(t.sessionId,{targetAgentId:n}))}catch(r){this.logger?.warn(`agent-swap: resume failed for sessionId=${t.sessionId}: ${r instanceof Error?r.message:String(r)}`)}}}async resurrectPendingQueues(){let e=await this.store.list().catch(()=>[]);for(let t of e){let n=await ci(t.sessionId).catch(()=>[]);if(n.length===0)continue;let r=Date.now(),o=n.filter(d=>r-d.enqueuedAt<ca),i=n.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${ca/1e3}s)`),await Nt(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 Nt(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 uf(s,e){if(typeof s!="string"||s.length===0)return!1;let t=Vt.resolve(s),n=Vt.resolve(e);return t===n||t.startsWith(n+Vt.sep)}function ua(s,e){if(s===void 0||s.length===0)return!0;let t=vr(s);if(vr(e.cwd)===t)return!0;let n=e.workspace?.sourceCwd;return n!==void 0&&vr(n)===t}function vr(s){return s.length>1&&s.endsWith("/")?s.replace(/\/+$/,""):s}function lf(s,e){let n=(s.mergedAvailableCommands().length>0?s.agentOnlyAdvertisedCommands().map(c=>c.description!==void 0?{name:c.name,description:c.description}:{name:c.name}):void 0)??e?.agentCommands,r=s.availableModes(),i=(r.length>0?r.map(c=>{let l={id:c.id};return c.name!==void 0&&(l.name=c.name),c.description!==void 0&&(l.description=c.description),l}):void 0)??e?.agentModes,a=s.availableModels(),u=(a.length>0?a.map(c=>{let l={modelId:c.modelId};return c.name!==void 0&&(l.name=c.name),c.description!==void 0&&(l.description=c.description),l}):void 0)??e?.agentModels;return ir({sessionId:s.sessionId,lineageId:e?.lineageId??jt(),upstreamSessionId:s.upstreamSessionId,importedFromSessionId:e?.importedFromSessionId,importedFromUpstreamSessionId:e?.importedFromUpstreamSessionId,importedFromMachine:e?.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:e?.synopsis,summarizedThroughEntry:e?.summarizedThroughEntry,agentArgs:s.agentArgs,currentModel:s.currentModel??e?.currentModel,currentMode:s.currentMode??e?.currentMode,currentUsage:ha(s.persistableUsage)??e?.currentUsage,agentCommands:n,agentModes:i,agentModels:u,parentSessionId:s.parentSessionId??e?.parentSessionId,forkedFromSessionId:s.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId??e?.forkedFromMessageId,originatingClient:s.originatingClient??e?.originatingClient,interactive:s.interactive??e?.interactive,priority:s.priority??e?.priority,forwardedEnv:s.forwardedEnv??e?.forwardedEnv,workspace:s.workspace,attentionFlags:s.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?ya(e,s.agentId,s.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(s.createdAt).toISOString()})}function ha(s){if(!s)return;let e={};return s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size),s.costAmount!==void 0&&(e.costAmount=s.costAmount),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),s.cumulativeCost!==void 0&&(e.cumulativeCost=s.cumulativeCost),Object.keys(e).length>0?e:void 0}function ff(s){return s?{...s}:void 0}function la(s,e){if(e&&s==="claude-acp")return{claudeCode:{options:{model:e}}}}function Dn(s,e){let t=e.fromObject(s);if(t!==void 0)return t;let n=s[e.nestedKey];if(n&&typeof n=="object"&&!Array.isArray(n)){let i=e.fromObject(n);if(i!==void 0)return i}let r=s._meta;if(r&&typeof r=="object"&&!Array.isArray(r)){for(let[i,a]of Object.entries(r))if(i!=="hydra-acp"&&a&&typeof a=="object"&&!Array.isArray(a)){let d=e.fromObject(a);if(d!==void 0)return d}}let o=pf(s,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function br(s){return Dn(s,{nestedKey:"models",configId:"model",fromObject:e=>_e(e.currentModelId)??_e(e.currentModel)??_e(e.modelId)??_e(e.model),fromConfig:e=>_e(e.currentValue)})}function Ve(s,e){if(!s||typeof s!="object")return s;let t=s;if(t.code!==C.AuthRequired)return s;let n=u=>!!u&&typeof u=="object"&&!Array.isArray(u),r=n(t.data)?t.data:{},o=n(r._meta)?r._meta:{},i=n(o["hydra-acp"])?o["hydra-acp"]:{},a=typeof t.message=="string"?t.message:"authentication required",d=new Error(a);return d.code=C.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function fa(s){return/^[A-Za-z0-9_\-./=:@]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function pa(s,e,t,n){if(s&&typeof s=="object"&&s.code===C.AuthRequired)return s;let r=s instanceof Error?s.message:String(s),o=r.includes("stderr:"),i=o?"":e.stderrTailText(),a=n?`to reproduce: (cd ${fa(n.cwd)} && ${[n.command,...n.args].map(fa).join(" ")})`:"";if(!i&&!a)return s;let d=[o?r:`agent ${t} failed to start: ${r}`];i&&d.push(`stderr: ${i}`),a&&d.push(a);let u=new Error(d.join(`
165
+ `));if(s&&typeof s=="object"){let c=s;typeof c.code=="number"&&(u.code=c.code),c.data!==void 0&&(u.data=c.data)}return u}function zt(s){if(!Array.isArray(s))return;let e=[];for(let t of s){if(!t||typeof t!="object")continue;let n=t;if(typeof n.id!="string")continue;let r=typeof n.description=="string"?n.description:"",o=n.type==="agent"||n.type==="terminal"?n.type:void 0,i=typeof n.name=="string"?n.name:void 0,a=n._meta,d=a!==null&&typeof a=="object"&&!Array.isArray(a)?a:void 0;e.push({id:n.id,description:r,...o&&{type:o},...i!==void 0&&{name:i},...d&&{_meta:d}})}return e.length>0?e:void 0}function _e(s){if(typeof s!="string")return;let e=s.trim();return e.length>0?e:void 0}function pf(s,e){let t=s.configOptions;if(Array.isArray(t))for(let n of t){if(!n||typeof n!="object"||Array.isArray(n))continue;let r=n;if(r.id===e)return r}}function Sr(s){return s.length>0?s:void 0}function Ir(s){return Dn(s,{nestedKey:"models",configId:"model",fromObject:e=>{let t=ht(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=ht(e.options);return t.length>0?t:void 0}})??[]}function Ar(s){return Dn(s,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=Ot(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=Ot(e.options);return t.length>0?t:void 0}})??[]}function Cr(s){return Dn(s,{nestedKey:"modes",configId:"mode",fromObject:e=>_e(e.currentModeId)??_e(e.currentMode)??_e(e.modeId)??_e(e.mode),fromConfig:e=>_e(e.currentValue)})}function gf(s){for(let e=s.length-1;e>=0;e--){let t=s[e];if(!t||t.method!=="session/update")continue;let n=t.params?.update;if(n?.sessionUpdate==="turn_complete"&&!(typeof n.messageId!="string"||n.messageId.length===0))return{index:e,messageId:n.messageId}}}async function ga(s){try{let e=await Ge.readFile(A.tuiHistoryFile(s),"utf8"),t=[];for(let n of e.split(`
166
+ `))if(n.length!==0)try{let r=JSON.parse(n);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function ya(s,e,t,n=new Date().toISOString(),r){let o=s.upstreamGenerations&&s.upstreamGenerations.length>0?[...s.upstreamGenerations]:s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.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:n,...r!==void 0?{cost:r}:{}}),o.push({upstreamSessionId:t,agentId:e,startedAt:n}),o}async function Jt(s){try{let e=await Ge.stat(A.historyFile(s));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function It(s,e){return s.interactive!==void 0?s.interactive:s.originatingClient?.name===$n?!1:e?!0:void 0}import{spawn as mf}from"child_process";import*as Bn from"fs";import*as Le from"fs/promises";import*as Un from"path";import hf 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,n){if(e===78){let i=`exited with code 78 (unrecoverable); fix and run \`${n}s start ${t}\``;return this.tripped_=i,{tripped:i}}let r=this.now();this.recentExits.push(r);let o=r-this.windowMs;for(;this.recentExits.length>0&&this.recentExits[0]<o;)this.recentExits.shift();if(this.recentExits.length>this.maxFailures){let i=Math.round(this.windowMs/6e4),a=`${this.recentExits.length} exits in ${i}m (crash loop); fix and run \`${n}s start ${t}\``;return this.tripped_=a,{tripped:a}}return"restart"}reset(){this.recentExits=[],this.tripped_=void 0}get tripped(){return this.tripped_}};var yf=1e3,wf=6e4,xr=3e3,At=class{entries=new Map;stopping=!1;context;tokenRegistry;breakerOptions;restartBaseMs;restartCapMs;adapter;constructor(e,t,n,r={}){this.adapter=t,this.context=n,this.tokenRegistry=r.tokenRegistry,this.breakerOptions=r.breakerOptions,this.restartBaseMs=r.restartBaseMs??yf,this.restartCapMs=r.restartCapMs??wf;for(let o of e)this.entries.set(o.name,this.makeEntry(o))}setContext(e){this.context=e}reportVersion(e,t){let n=this.entries.get(e);n&&(n.version=t)}async start(){if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before start`);await Le.mkdir(this.adapter.paths.dir(),{recursive:!0}),await this.reapOrphans();let e=[];for(let t of this.entries.values())t.config.enabled&&e.push(this.spawn(t,0));await Promise.all(e)}async stop(){this.stopping=!0;let e=[];for(let t of this.entries.values()){t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;if(n){try{n.kill("SIGTERM")}catch{}e.push(new Promise(r=>{if(n.exitCode!==null||n.signalCode!==null){r();return}let o=setTimeout(()=>{try{n.kill("SIGKILL")}catch{}r()},xr);n.on("exit",()=>{clearTimeout(o),r()})}))}}await Promise.allSettled(e);for(let t of this.entries.values()){try{t.logStream?.end()}catch{}t.child=void 0,t.logStream=void 0,t.pid=void 0}}list(){return[...this.entries.values()].map(e=>this.infoFor(e))}get(e){let t=this.entries.get(e);return t?this.infoFor(t):void 0}has(e){return this.entries.has(e)}async startByName(e){let t=this.entries.get(e);if(!t)throw Qt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw Qt(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 Qt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;return n?(await this.terminate(t,n),this.infoFor(t)):this.infoFor(t)}async restartByName(e){return await this.stopByName(e),this.startByName(e)}register(e){if(this.entries.has(e.name))throw Qt(new Error(`${this.adapter.kind} ${e.name} already exists`),"CONFLICT");if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before register`);let t=this.makeEntry(e);return this.entries.set(e.name,t),e.enabled&&this.spawn(t,0).catch(n=>{t.failureReason=`spawn: ${n.message}`}),this.infoFor(t)}async unregister(e){let t=this.entries.get(e);if(!t)throw Qt(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;n&&await this.terminate(t,n);try{t.logStream?.end()}catch{}this.entries.delete(e)}async terminate(e,t){if(t.exitCode!==null||t.signalCode!==null)return;let n=new Promise(o=>{e.exitWaiters.push(o)});try{t.kill("SIGTERM")}catch{}let r=setTimeout(()=>{try{t.kill("SIGKILL")}catch{}},xr);typeof r.unref=="function"&&r.unref();try{await n}finally{clearTimeout(r)}}infoFor(e){let t;return e.failureReason!==void 0?t="failed":e.child?t="running":e.restartTimer?t="restarting":e.config.enabled?t="stopped":t="disabled",{name:e.config.name,status:t,pid:e.pid,enabled:e.config.enabled,restartCount:e.restartCount,startedAt:e.startedAt,lastExitCode:e.lastExitCode,logPath:this.adapter.paths.logFile(e.config.name),version:e.version,failureReason:e.failureReason}}makeEntry(e){return{config:e,child:void 0,logStream:void 0,restartTimer:void 0,pid:void 0,startedAt:void 0,restartCount:0,lastExitCode:void 0,manuallyStopped:!1,exitWaiters:[],version:void 0,processToken:void 0,breaker:new Ln(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await Le.readdir(this.adapter.paths.dir(),{withFileTypes:!0})}catch(t){if(t.code==="ENOENT")return;throw t}for(let t of e){if(!t.isDirectory())continue;let n=this.adapter.paths.pidFile(t.name),r;try{let o=await Le.readFile(n,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&Rr(r)){try{process.kill(r,"SIGTERM")}catch{}let o=Date.now()+xr;for(;Date.now()<o&&Rr(r);)await new Promise(i=>setTimeout(i,50));if(Rr(r))try{process.kill(r,"SIGKILL")}catch{}}await Le.unlink(n).catch(()=>{})}}async spawn(e,t){if(this.stopping||e.manuallyStopped)return;let n=this.context;if(!n)throw new Error(`${this.managerName()}.spawn called before setContext`);let r=e.config,o=r.command.length>0?r.command:[r.name],i=Un.dirname(this.adapter.paths.logFile(r.name)),a;try{await Le.mkdir(i,{recursive:!0}),a=await hf({file:Un.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})
167
+ `);let d=this.tokenRegistry?.mint(r.name,this.adapter.tokenRole)??n.serviceToken;e.processToken=d,e.version=void 0;let u={...an(),HYDRA_ACP_DAEMON_URL:n.daemonUrl,HYDRA_ACP_DAEMON_HOST:n.daemonHost,HYDRA_ACP_DAEMON_PORT:String(n.daemonPort),HYDRA_ACP_TOKEN:d,HYDRA_ACP_WS_URL:n.daemonWsUrl,HYDRA_ACP_HOME:n.hydraHome,[this.adapter.nameEnvVar]:r.name,...r.env},[c,...l]=o;if(c===void 0){a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} has empty command
168
+ `),a.end();return}let p=de(c),f=[...l,...r.args].map(de),m;try{m=mf(p,f,{env:u,stdio:["ignore","pipe","pipe"],detached:!1})}catch(h){a.write(`[hydra-acp] failed to spawn ${r.name}: ${h.message}
169
+ `),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{Bn.writeFileSync(this.adapter.paths.pidFile(r.name),`${m.pid}
131
170
  `,{encoding:"utf8",mode:384})}catch(h){a.write(`[hydra-acp] failed to write pid file for ${r.name}: ${h.message}
132
171
  `)}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 Rt(n,e){return n.code=e,n}W();var _u={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,_u,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 Pt from"fs/promises";import*as yn from"path";var Tt=n=>{process.stderr.write(n+`
137
- `)};function Hs(n){Tt=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 Pt.readdir(i,{withFileTypes:!0})}catch(d){let u=d;if(u.code==="ENOENT")return;Tt(`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 Pt.readdir(p,{withFileTypes:!0})}catch(m){Tt(`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 Pt.rm(h,{recursive:!0,force:!0}),Tt(`hydra-acp: pruned stale ${u} ${g} (${h})`)}catch(y){Tt(`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 ${Fu(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 Fu(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 Ou}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 Ou("sha256").update(s).digest("hex").slice(0,16)}W();Fe();import*as fi from"path";import{createHash as Nu,randomBytes as Hu,timingSafeEqual as ju}from"crypto";var pi="hydra_session_",Bu=3600*24*30,ui=12,Uu=32,Du=50;function Lu(){return fi.join(I.home(),"session-tokens.json")}function li(n){return Nu("sha256").update(n).digest("hex")}function mi(n){return Hu(n).toString("hex")}function qu(){return mi(ui).slice(0,ui*2)}function zu(){return`${pi}${mi(Uu)}`}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=Lu(),s=await ue(t);s&&Array.isArray(s.records)&&(e=s.records.filter(Ju));let r=new n(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=zu(),s=li(t),r=qu(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:Bu,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||!ju(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(()=>{})},Du))}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 Ju(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 Wu(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 Wu(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 Li from"os";import*as qi 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=Vu(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 Vu(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 Qu}from"path";import Gu 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 Ku=/[\x00-\x08\x0b-\x1f\x7f]/g;function ae(n){return Gu(n).replace(Ku,"")}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 sl(t);case"agent_thought_chunk":case"agent_thought":return rl(t);case"user_message_chunk":return ol(t);case"prompt_received":return il(t);case"tool_call":return al(t,e);case"tool_call_update":return fl(t,e);case"plan":return hl(t);case"current_mode_update":return yl(t);case"current_model_update":return wl(t);case"turn_complete":return bl(t);case"usage_update":return nl(t);case"available_commands_update":return el(t);case"available_modes_update":return tl(t);case"session_info_update":return Xu(t);case"config_option_update":return Yu(t);default:return{kind:"unknown",sessionUpdate:s,raw:n}}}function Yu(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 Xu(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 Zu(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 el(n){let e=n.availableCommands??n.commands;return Array.isArray(e)?{kind:"available-commands",commands:Zu(e)}:null}function tl(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 nl(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 sl(n){let e=$t(n.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:_t(n)}}function rl(n){let e=typeof n.text=="string"?ae(n.text):$t(n.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:_t(n)}}function ol(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=$t(n.content);return t===null?null:{kind:"user-text",text:t}}function il(n){let e=vl(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 al(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"?ul(t,Si):ll(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 dl=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function cl(n){for(let e of dl)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 cl(n)?$e(`/${n}`):t.cwd&&t.cwd.length>0?$e(Qu.resolve(t.cwd,n)):n}function ul(n,e){return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function ll(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 fl(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=pl(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=ml(n);g!==null&&(f.errorText=g),gl(n,g)&&(f.upstreamInterrupted=!0)}let m=_t(n);return m!==void 0&&(f.workerTaskId=m),f}function pl(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 ml(n){let e=n.content;if(Array.isArray(e))for(let s of e){if(!s||typeof s!="object")continue;let o=$t(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 gl(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 hl(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 yl(n){let e=V(n,"currentModeId")??V(n,"currentMode")??V(n,"mode");return e?{kind:"mode-changed",mode:Q(e)}:null}function wl(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 bl(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 $t(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 vl(n){if(!Array.isArray(n))return null;let e=[];for(let t of n){let s=$t(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=Il(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)Sl(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 Sl(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 Il(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=Al(n),{events:s,window:r}=kl(t,e),o=Cl(s),i=[];xl(i,n),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),Ml(i,s,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
172
+ `)}),m.on("exit",(h,y)=>{try{Bn.unlinkSync(this.adapter.paths.pidFile(r.name))}catch{}a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} exited code=${h??"null"} signal=${y??"null"}
173
+ `),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 k=e.exitWaiters.splice(0);for(let v of k)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}
174
+ `);try{a.end()}catch{}e.logStream=void 0;return}this.scheduleRestart(e,t+1)})}scheduleRestart(e,t){if(this.stopping||e.manuallyStopped)return;let n=Math.min(this.restartBaseMs*2**Math.min(t,10),this.restartCapMs);e.restartTimer=setTimeout(()=>{e.restartTimer=void 0,this.spawn(e,t).catch(r=>{e.failureReason=`spawn: ${r.message}`})},n),typeof e.restartTimer.unref=="function"&&e.restartTimer.unref()}managerName(){return this.adapter.kind==="extension"?"ExtensionManager":"TransformerManager"}};function Rr(s){try{return process.kill(s,0),!0}catch{return!1}}function Qt(s,e){return s.code=e,s}K();var kf={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:A.extensionsDir,logFile:A.extensionLogFile,pidFile:A.extensionPidFile}},Wn=class extends At{constructor(e,t,n={}){super(e,kf,t,n)}};K();var vf={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:A.transformersDir,logFile:A.transformerLogFile,pidFile:A.transformerPidFile}},qn=class extends At{connected=new Map;constructor(e,t,n={}){super(e,vf,t,n)}registerConnection(e,t,n){this.connected.set(e,{name:e,connection:t,intercepts:new Set(n)})}deregisterConnection(e){this.connected.delete(e)}resolveChain(e){let t=[];for(let n of e){let r=this.connected.get(n);r&&t.push(r)}return t}interestedIn(e){let t=[];for(let n of this.connected.values())n.intercepts.has(e)&&t.push(n);return t}};var zn=class{entries=new Map;changeHandlers=[];register(e,t,n){this.entries.set(e,{connection:t,commands:[...n]}),this.fireChanged()}clear(e){this.entries.delete(e)&&this.fireChanged()}get(e){return this.entries.get(e)}has(e){return this.entries.has(e)}list(){let e=[];for(let[t,n]of this.entries)for(let r of n.commands)e.push({name:t,command:r});return e}onChange(e){return this.changeHandlers.push(e),()=>{let t=this.changeHandlers.indexOf(e);t>=0&&this.changeHandlers.splice(t,1)}}fireChanged(){for(let e of this.changeHandlers)try{e()}catch{}}};K();K();import*as Er from"fs/promises";async function wa(s){await Er.writeFile(A.pidFile(),JSON.stringify(s)+`
175
+ `,{encoding:"utf8",mode:384})}K();import*as Gt from"fs/promises";import*as Jn from"path";var Kt=s=>{process.stderr.write(s+`
176
+ `)};function Pr(s){Kt=s??(e=>process.stderr.write(e+`
177
+ `))}async function ka(s,e){let t=Ae();if(!t)return;let n=await s.load(),r=new Map;for(let d of n.agents)r.set(d.id,d.version??"current");let o=e.activeAgentVersions(),i=Jn.join(A.agentsDir(),t),a;try{a=await Gt.readdir(i,{withFileTypes:!0})}catch(d){let u=d;if(u.code==="ENOENT")return;Kt(`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 l=o.get(u)??new Set,p=Jn.join(i,u),f;try{f=await Gt.readdir(p,{withFileTypes:!0})}catch(m){Kt(`hydra-acp: prune: failed to read ${p}: ${m.message}`);continue}for(let m of f){if(!m.isDirectory())continue;let g=m.name;if(g===c||l.has(g)||g.includes(".partial-"))continue;let h=Jn.join(p,g);try{await Gt.rm(h,{recursive:!0,force:!0}),Kt(`hydra-acp: pruned stale ${u} ${g} (${h})`)}catch(y){Kt(`hydra-acp: prune: failed to remove ${h}: ${y.message}`)}}}}function va(s){let e,t=!1,n=0,r=(a,d)=>{s.logger&&s.logger[a](`agent-sync: ${d}`)},o=async()=>{let a=[];try{let c=await s.registry.load();for(let l of c.agents)await Ts(l)==="yes"&&a.push(l.id)}catch(c){return r("warn",`registry load failed: ${c.message}`),s.intervalMs}if(a.length===0)return s.intervalMs;let d=n%a.length;n=(n+1)%a.length;let u=a[d];try{let{synced:c,skipped:l}=await s.manager.syncFromAgent(u);r("info",`${u}: synced ${c.length}, skipped ${l}`)}catch(c){r("warn",`${u}: ${c.message}`)}return Math.max(1,Math.floor(s.intervalMs/a.length))},i=a=>{t||(e=setTimeout(()=>{o().then(d=>{i(d)}).catch(d=>{r("warn",`tick crashed: ${d.message}`),i(s.intervalMs)})},a),e.unref())};return i(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}async function Mr(s){let e=s.maxDeletions??200,t=(f,m)=>{s.logger&&s.logger[f](`session-gc: ${m}`)},n=Date.now(),r=s.maxAgeMs>0?n-s.maxAgeMs:Number.POSITIVE_INFINITY,o=await s.manager.list({includeNonInteractive:!0}).catch(f=>(t("warn",`manager.list failed: ${f.message}`),[])),i=[];for(let f of o){if(f.status!=="cold")continue;if((s.selection??"explicit")==="explicit"){if(f.interactive!==!1)continue}else if(f.interactive===!0)continue;let g=Date.parse(f.updatedAt);Number.isFinite(g)&&(s.maxAgeMs>0&&g>r||i.push({sessionId:f.sessionId,lastUsedMs:g}))}if(i.length===0)return s.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((f,m)=>f.lastUsedMs-m.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,u=0,c=0;for(let{sessionId:f}of a)try{await s.manager.deleteRecord(f,"expired")&&(u+=1)}catch(m){c+=1,t("warn",`delete ${f} failed: ${m.message}`)}let l=i.length-a.length;if(s.verbose||u>0||c>0){let f=(s.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${u} ${f} session(s) older than ${bf(s.maxAgeMs)}`+(c>0?`; ${c} failed`:"")+(l>0?`; ${l} deferred to next sweep`:""))}let p={considered:i.length,deleted:u,failed:c,deferred:l};return d!==void 0&&(p.oldestLastUsedMs=d),p}function ba(s){let e,t=!1,n=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!n){n=!0;try{await Mr({manager:s.manager,maxAgeMs:s.maxAgeMs,selection:"unpromoted",...s.maxDeletionsPerSweep!==void 0?{maxDeletions:s.maxDeletionsPerSweep}:{},...s.logger?{logger:s.logger}:{}})}finally{n=!1}}})().catch(a=>{s.logger?.warn(`session-gc: sweep crashed: ${a.message}`)}).finally(()=>{r(s.intervalMs)})},o),e.unref())};return r(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}function bf(s){if(s<=0)return"any age";let e=s/(1440*60*1e3);if(e>=1)return`${e.toFixed(e>=10?0:1)}d`;let t=s/(3600*1e3);return`${t.toFixed(t>=10?0:1)}h`}import{createHash as Sf}from"crypto";function Tr(s){if(Array.isArray(s))return s.map(Tr);if(s!==null&&typeof s=="object"){let e={};for(let t of Object.keys(s).sort())e[t]=Tr(s[t]);return e}return s}function Sa(s){let{tui:e,...t}=s,n=JSON.stringify(Tr(t));return Sf("sha256").update(n).digest("hex").slice(0,16)}K();Ne();import*as Ca from"path";import{createHash as If,randomBytes as Af,timingSafeEqual as Cf}from"crypto";var xa="hydra_session_",xf=3600*24*30,Ia=12,Rf=32,Ef=50;function Pf(){return Ca.join(A.home(),"session-tokens.json")}function Aa(s){return If("sha256").update(s).digest("hex")}function Ra(s){return Af(s).toString("hex")}function Mf(){return Ra(Ia).slice(0,Ia*2)}function Tf(){return`${xa}${Ra(Rf)}`}var Vn=class s{records=new Map;writeTimer=null;writeInflight=null;filePath;constructor(e,t){this.filePath=t;for(let n of e)this.records.set(n.hash,n)}static async load(){let e=[],t=Pf(),n=await ee(t);n&&Array.isArray(n.records)&&(e=n.records.filter(_f));let r=new s(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=Tf(),n=Aa(t),r=Mf(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:xf,a=new Date(o.getTime()+i*1e3),d={id:r,hash:n,label:e.label,createdAt:o.toISOString(),expiresAt:a.toISOString(),lastUsedAt:o.toISOString()};return this.records.set(n,d),this.scheduleWrite(),{id:r,token:t,expiresAt:d.expiresAt}}async verify(e){if(typeof e!="string"||!e.startsWith(xa))return;let t=Aa(e),n=this.records.get(t);if(!n)return;let r=Buffer.from(n.hash,"hex"),o=Buffer.from(t,"hex");if(r.length!==o.length||!Cf(r,o))return;let i=new Date;if(new Date(n.expiresAt).getTime()<=i.getTime()){this.records.delete(t),this.scheduleWrite();return}return n.lastUsedAt=i.toISOString(),this.scheduleWrite(),n.id}async revoke(e){for(let[t,n]of this.records)if(n.id===e)return this.records.delete(t),this.scheduleWrite(),!0;return!1}async revokeAll(){let e=this.records.size;return this.records.clear(),this.scheduleWrite(),e}list(){return Array.from(this.records.values()).map(({id:e,label:t,createdAt:n,expiresAt:r,lastUsedAt:o})=>({id:e,label:t,createdAt:n,expiresAt:r,lastUsedAt:o})).sort((e,t)=>t.createdAt.localeCompare(e.createdAt))}sweepExpired(e=new Date){let t=0;for(let[n,r]of this.records)new Date(r.expiresAt).getTime()<=e.getTime()&&(this.records.delete(n),t+=1);return t>0&&this.scheduleWrite(),t}async flush(){this.writeTimer&&(clearTimeout(this.writeTimer),this.writeTimer=null),await this.persist()}scheduleWrite(){this.writeTimer||(this.writeTimer=setTimeout(()=>{this.writeTimer=null,this.persist().catch(()=>{})},Ef))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>fe(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 _f(s){if(!s||typeof s!="object")return!1;let e=s;return typeof e.id=="string"&&typeof e.hash=="string"&&typeof e.createdAt=="string"&&typeof e.expiresAt=="string"&&typeof e.lastUsedAt=="string"&&(e.label===void 0||typeof e.label=="string")}var Ea="Bearer ",Qn=class{constructor(e){this.token=e}token;async validate(e){return $f(e,this.token)?"service":void 0}},Kn=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},Gn=class{constructor(e){this.validators=e}validators;async validate(e){for(let t of this.validators){let n=await t.validate(e);if(n!==void 0)return n}}};function Pa(s){return async function(t,n){let r=t.headers.authorization;if(!r||!r.startsWith(Ea)){n.code(401).send({error:"Missing bearer token"});return}let o=r.slice(Ea.length).trim(),i=await s.validator.validate(o);if(!i){n.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function Ma(s){let e=s.headers["sec-websocket-protocol"],t=Array.isArray(e)?e.join(","):e;if(t)for(let n of t.split(",")){let r=n.trim(),o="hydra-acp-token.";if(r.startsWith(o))return r.slice(o.length)}if(s.url)try{let r=new URL(s.url,"http://localhost").searchParams.get("token");if(r)return r}catch{return}}var Yn=class{tokens=new Map;mint(e,t){let n=hs();return this.tokens.set(n,{name:e,kind:t}),n}revoke(e){for(let[t,n]of this.tokens)n.name===e&&this.tokens.delete(t)}resolve(e){return this.tokens.get(e)}async validate(e){let t=this.tokens.get(e);if(t)return`${t.kind}:${t.name}`}};function $f(s,e){if(s.length!==e.length)return!1;let t=0;for(let n=0;n<s.length;n+=1)t|=s.charCodeAt(n)^e.charCodeAt(n);return t===0}var Xn=class{entries=new Map;maxFails;windowMs;constructor(e=10,t=900*1e3){this.maxFails=e,this.windowMs=t}isBlocked(e){let t=this.entries.get(e);return t?Date.now()-t.windowStart>this.windowMs?(this.entries.delete(e),!1):t.fails>=this.maxFails:!1}recordFailure(e){let t=Date.now(),n=this.entries.get(e);if(!n||t-n.windowStart>this.windowMs){this.entries.set(e,{fails:1,windowStart:t});return}n.fails+=1}recordSuccess(e){this.entries.delete(e)}sweepExpired(){let e=Date.now();for(let[t,n]of this.entries)e-n.windowStart>this.windowMs&&this.entries.delete(t)}};import*as Hr from"fs";import*as nd from"os";import*as rs from"path";import*as jr from"readline";K();function _r(s){return Math.floor(s/4)}function Ta(s){let e=0,t=new Map;for(let n of s){let r=n.params;if(!r||typeof r!="object")continue;let o=r.update;if(!o||typeof o!="object")continue;let i=o;switch(i.sessionUpdate){case"user_message_chunk":case"agent_message_chunk":case"agent_thought_chunk":e+=Ye(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=Ff(i),u=t.get(a)??0;d>u&&t.set(a,d);break}default:break}}for(let n of t.values())e+=n;return e}function Ff(s){let e=0;return typeof s.title=="string"&&(e+=s.title.length),e+=Zn(s.rawInput),e+=Ye(s.content),e+=Zn(s.rawOutput),e}function Zn(s){if(s==null)return 0;if(typeof s=="string")return s.length;if(typeof s=="number"||typeof s=="boolean")return String(s).length;if(Array.isArray(s)){let e=0;for(let t of s)e+=Zn(t);return e}if(typeof s=="object"){let e=s.bytes;if(typeof s.__hydraBlob=="string"&&typeof e=="number")return e;let t=0;for(let n of Object.values(s))t+=Zn(n);return t}return 0}function Ye(s){if(s==null)return 0;if(typeof s=="string")return s.length;if(Array.isArray(s)){let t=0;for(let n of s)t+=Ye(n);return t}if(typeof s!="object")return 0;let e=s;return typeof e.__hydraBlob=="string"&&typeof e.bytes=="number"?e.bytes:e.text!==void 0?Ye(e.text):e.type==="diff"?Ye(e.oldText)+Ye(e.newText):e.content!==void 0?Ye(e.content):0}function _a(s){if(s.compactionInFlight||s.totalEntries===0)return!1;let e,t;if(typeof s.agentReportedUsed=="number"&&typeof s.agentReportedSize=="number"&&s.agentReportedSize>0)e=s.agentReportedUsed/s.agentReportedSize,t=!0;else{let r=_r(s.unsummarizedChars),o=s.currentModel!==void 0?s.config.modelContextWindows[s.currentModel]??s.config.absoluteFallback:s.config.absoluteFallback;e=r/o,t=!1}if(t&&e>=s.config.hardCeilingFraction)return!0;let n=s.nowMs-s.lastActivityMs;return e>=s.config.contextFraction&&n>=s.config.idleBeforePromptMs}K();import{posix as Nf}from"path";import Of from"strip-ansi";function Yt(s){if(!s||typeof s!="object")return;let e=s;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}var Hf=/[\x00-\x08\x0b-\x1f\x7f]/g;function we(s){return Of(s).replace(Hf,"")}function Z(s){return we(s).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function Oa(s,e={}){if(!s||typeof s!="object")return null;let t=s,n=t.sessionUpdate??t.kind;if(typeof n!="string")return null;switch(n){case"agent_message_chunk":return qf(t);case"agent_thought_chunk":case"agent_thought":return zf(t);case"user_message_chunk":return Jf(t);case"prompt_received":return Vf(t);case"tool_call":return Qf(t,e);case"tool_call_update":return Zf(t,e);case"plan":return sp(t);case"current_mode_update":return rp(t);case"current_model_update":return op(t);case"turn_complete":return ip(t);case"turn_started":return Na(t,"turn-started");case"turn_ended":return Na(t,"turn-ended");case"usage_update":return Wf(t);case"available_commands_update":return Bf(t);case"available_modes_update":return Uf(t);case"session_info_update":return Df(t);case"config_option_update":return jf(t);default:return{kind:"unknown",sessionUpdate:n,raw:s}}}function jf(s){let e=s.configOptions;if(!Array.isArray(e))return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.id!="string"||typeof r.currentValue!="string"||!Array.isArray(r.options))continue;let o=[];for(let i of r.options){if(!i||typeof i!="object")continue;let a=i;typeof a.value=="string"&&o.push({value:a.value,name:typeof a.name=="string"?a.name:a.value,...typeof a.description=="string"?{description:a.description}:{}})}t.push({id:r.id,name:typeof r.name=="string"?r.name:r.id,type:"select",currentValue:r.currentValue,options:o,...typeof r.category=="string"?{category:r.category}:{}})}return{kind:"config-options",options:t}}function Df(s){let e=Y(s,"title"),t=e!==void 0?Z(e):void 0,n=s._meta,r,o;if(n&&typeof n=="object"&&!Array.isArray(n)){let a=n["hydra-acp"];if(a&&typeof a=="object"&&!Array.isArray(a)){let d=a.agentId;if(typeof d=="string"&&(r=d),"pendingAgentSwap"in a){let 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 Lf(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object")continue;let n=t;if(typeof n.name!="string"||n.name.length===0)continue;let r=n.name.startsWith("/")?n.name:`/${n.name}`,o={name:Z(r)};typeof n.description=="string"&&(o.description=Z(n.description)),e.push(o)}return e}function Bf(s){let e=s.availableCommands??s.commands;return Array.isArray(e)?{kind:"available-commands",commands:Lf(e)}:null}function Uf(s){let e=s.availableModes;if(!Array.isArray(e))return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.id!="string"||r.id.length===0)continue;let o={id:Z(r.id)};typeof r.name=="string"&&(o.name=Z(r.name)),typeof r.description=="string"&&(o.description=Z(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function Wf(s){let e={kind:"usage-update"};if(typeof s.used=="number"&&(e.used=s.used),typeof s.size=="number"&&(e.size=s.size),s.cost&&typeof s.cost=="object"){let t=s.cost;typeof t.amount=="number"&&(e.costAmount=t.amount),typeof t.currency=="string"&&(e.costCurrency=t.currency)}return e}function qf(s){let e=Xt(s.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:Yt(s)}}function zf(s){let e=typeof s.text=="string"?we(s.text):Xt(s.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:Yt(s)}}function Jf(s){let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){let n=e["hydra-acp"];if(n&&typeof n=="object"&&!Array.isArray(n)&&n.compatFor==="prompt_received")return null}let t=Xt(s.content);return t===null?null:{kind:"user-text",text:t}}function Vf(s){let e=ap(s.prompt);return e===null?null:{kind:"user-text",text:e}}function Ha(s){return s?s.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function $a(s){if(typeof s=="string")return{text:s};if(s&&typeof s=="object"&&!Array.isArray(s)){let e=s;if(typeof e.__hydraBlob=="string")return{ref:{hash:e.__hydraBlob,bytes:typeof e.bytes=="number"?e.bytes:0}}}}function es(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(r.type!=="diff")continue;let o=$a(r.oldText),i=$a(r.newText);if(o===void 0&&i===void 0)continue;let a=typeof r.path=="string"?r.path:void 0;return{...a!==void 0?{path:a}:{},oldText:o?.text??"",newText:i?.text??"",...o?.ref?{oldRef:o.ref}:{},...i?.ref?{newRef:i.ref}:{}}}let t=s.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let n=t,r=typeof n.file_path=="string"?n.file_path:typeof n.path=="string"?n.path:void 0;if(typeof n.old_string=="string"&&typeof n.new_string=="string")return{...r!==void 0?{path:r}:{},oldText:n.old_string,newText:n.new_string};if(typeof n.content=="string")return{...r!==void 0?{path:r}:{},oldText:"",newText:n.content}}return null}function ja(s){let e=s.rawInput;if(!e||typeof e!="object"||Array.isArray(e))return null;let t=e.plan;return typeof t!="string"||t.length===0?null:we(t)}function Qf(s,e={}){let t=Y(s,"toolCallId")??Y(s,"id");if(!t)return null;let n=Y(s,"title")??Y(s,"name")??Y(s,"label")??"tool call",r=Y(s,"name")??Y(s,"title");if(Ha(r)){let m=ja(s);if(m!==null){let g=Y(s,"status"),h={kind:"exit-plan-mode",toolCallId:t,plan:m};return g!==void 0&&(h.status=g),h}}let o=Ba(Z(n),s,e),i=Y(s,"status"),a=Y(s,"kind"),d={kind:"tool-call",toolCallId:t,title:o};i!==void 0&&(d.status=i),a!==void 0&&(d.rawKind=a);let u=es(s);u!==null&&(d.editDiff=u);let c=La(s);c!==void 0&&(d.detail=c);let l=$r(s);l!==void 0&&(d.detailFull=l);let p=Da(s);p!==void 0&&(d.locations=p);let f=Yt(s);return f!==void 0&&(d.workerTaskId=f),d}function Da(s){let e=s.locations;if(!Array.isArray(e))return;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(typeof r.path!="string"||r.path.length===0)continue;let o={path:r.path};typeof r.line=="number"&&Number.isFinite(r.line)&&r.line>=1&&(o.line=Math.floor(r.line)),t.push(o)}return t.length>0?t:void 0}var Fa=64;function La(s){let e=$r(s);if(e===void 0)return;let t=Z(e),n=s.rawInput;return n&&typeof n.command=="string"?Yf(t,Fa):Xf(t,Fa)}function $r(s){let e=s.rawInput;if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.command=="string"&&t.command.trim().length>0)return we(t.command).trim().replace(/^cd\s+\S+\s+&&\s+/,"");let n=typeof t.file_path=="string"?t.file_path:typeof t.filePath=="string"?t.filePath:typeof t.path=="string"?t.path:void 0;if(n!==void 0&&n.length>0)return O(Z(n))}if(Array.isArray(s.locations)){for(let t of s.locations)if(t&&typeof t=="object"){let n=t.path;if(typeof n=="string"&&n.length>0)return O(Z(n))}}}var Kf=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function Gf(s){for(let e of Kf)if(s.startsWith(e))return!0;return!1}function Ba(s,e,t={}){if(s.length===0)return s;if(s.startsWith("/"))return O(s);if(s.startsWith("~")||!s.includes("/")||/\s/.test(s))return s;let n=e.rawInput;if(n&&typeof n=="object"&&!Array.isArray(n)){let r=n,o=[r.file_path,r.filePath,r.path];for(let i of o)if(!(typeof i!="string"||i.length===0)&&(i===`/${s}`||i.endsWith(`/${s}`)||i===s))return O(i)}return Gf(s)?O(`/${s}`):t.cwd&&t.cwd.length>0?O(Nf.resolve(t.cwd,s)):s}function Yf(s,e){return s.length>e?`${s.slice(0,e-1)}\u2026`:s}function Xf(s,e){if(s.length<=e)return s;let t=s.slice(-(e-1)),n=t.indexOf("/");return n>=0&&n<e/2?`\u2026${t.slice(n)}`:`\u2026${t}`}function Zf(s,e={}){let t=Y(s,"toolCallId")??Y(s,"id");if(!t)return null;let n=Y(s,"title"),r=n!==void 0?Ba(Z(n),s,e):void 0,o=Y(s,"status"),i=es(s),a=La(s),d=ep(s);if(!(r!==void 0||i!==null||a!==void 0||d!==void 0||o==="completed"||o==="failed"||o==="rejected"||o==="cancelled"))return null;let c=Y(s,"name")??n;if(Ha(c)){let g={kind:"exit-plan-mode",toolCallId:t},h=ja(s);return h!==null&&(g.plan=h),o!==void 0&&(g.status=o),g}let l={kind:"tool-call-update",toolCallId:t};r!==void 0&&(l.title=r),a!==void 0&&(l.detail=a);let p=$r(s);p!==void 0&&(l.detailFull=p);let f=Da(s);if(f!==void 0&&(l.locations=f),d!==void 0&&(l.resultSummary=d),o!==void 0&&(l.status=o),i!==null&&(l.editDiff=i),o==="failed"){let g=tp(s);g!==null&&(l.errorText=g),np(s,g)&&(l.upstreamInterrupted=!0)}let m=Yt(s);return m!==void 0&&(l.workerTaskId=m),l}function ep(s){if(!s||typeof s!="object")return;let e=s.rawOutput;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=c=>{let l=t[c];return typeof l=="number"&&Number.isFinite(l)?l:void 0},r=(c,l,p=`${l}s`)=>`${c} ${c===1?l:p}`,o=[],i=n("totalMatches");i!==void 0&&o.push(r(i,"match","matches"));let a=n("totalFiles");a!==void 0&&o.push(r(a,"file"));let d=n("referenceCount");d!==void 0&&o.push(r(d,"reference")),o.length>0&&t.truncated===!0&&o.push("truncated");let u=n("exitCode");return u!==void 0&&u!==0&&o.push(`exit ${u}`),o.length>0?o.join(", "):void 0}function tp(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=Xt(n.content);if(o!==null&&o.length>0)return o}let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.error;if(typeof n=="string"&&n.length>0)return we(n)}return null}function np(s,e){let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.metadata;if(n&&typeof n=="object"&&n.interrupted===!0)return!0}return!!(e!==null&&e.toLowerCase().includes("tool execution aborted"))}function sp(s){let e=s.entries;if(!Array.isArray(e)||e.length===0)return null;let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n,o=typeof r.content=="string"?Z(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 rp(s){let e=Y(s,"currentModeId")??Y(s,"currentMode")??Y(s,"mode");return e?{kind:"mode-changed",mode:Z(e)}:null}function op(s){let e=Y(s,"currentModel")??Y(s,"model");if(!e)return null;let t=s.availableModels,n=Array.isArray(t)?t.map(r=>typeof r=="object"&&r!==null?r.modelId:typeof r=="string"?r:void 0).filter(r=>typeof r=="string"&&r.length>0):void 0;return{kind:"model-changed",model:Z(e),...n&&n.length>0?{availableModels:n}:{}}}function ip(s){let e=Y(s,"stopReason"),t=s._meta,n=t?.["hydra-acp"]?.amended!==void 0&&t["hydra-acp"].amended!==null,r={kind:"turn-complete"};return e!==void 0&&(r.stopReason=e),n&&(r.amended=!0),r}function Na(s,e){let n=s._meta?.["hydra-acp"],r=n?.unsolicited===!0;if(e==="turn-started"){let i=n?.cause?.label,a={kind:e,unsolicited:r};return typeof i=="string"&&i.length>0&&(a.cause=i),a}let o={kind:e,unsolicited:r};return typeof n?.reason=="string"&&(o.reason=n.reason),o}function Xt(s){if(typeof s=="string")return we(s);if(!s||typeof s!="object")return null;let e=s;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?we(e.text):null}function ap(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){let n=Xt(t);n!==null&&e.push(n)}return e.length===0?null:e.join("")}function Y(s,e){let t=s[e];return typeof t=="string"?t:void 0}function Ua(s){let e=new Map,t=new Map;for(let r of s){let i=r.params?.update;if(!i||typeof i!="object")continue;let a=i.sessionUpdate;if(a!=="tool_call"&&a!=="tool_call_update")continue;let d=typeof i.toolCallId=="string"&&i.toolCallId.length>0?i.toolCallId:void 0,u=cp(i);if(u.length===0)continue;let c=u;if(d!==void 0){let l=e.get(d)??[],p=[];for(let f of u)l.some(m=>m.path===f.path&&m.oldText===f.oldText&&m.newText===f.newText)||p.push(f);if(p.length===0)continue;e.set(d,[...l,...p]),c=p}for(let l of c)dp(t,l)}let n=[];for(let[r,o]of t)n.push({path:r,hunks:o.hunks,created:o.created});return n}function Wa(s){let e=[];for(let t of s){let n=-1;for(let o=e.length-1;o>=0;o--)if(e[o].newText===t.oldText){n=o;break}if(n===-1){e.push(t);continue}let r=e[n];e.splice(n,1,{oldText:r.oldText,newText:t.newText})}return e}function dp(s,e){let t={oldText:e.oldText,newText:e.newText},n=s.get(e.path);if(n===void 0){s.set(e.path,{hunks:[t],created:e.oldText.length===0});return}n.hunks.push(t)}function cp(s){let e=[],t=s.rawInput;if(t&&typeof t=="object"&&!Array.isArray(t)){let o=t,i=typeof o.file_path=="string"?o.file_path:typeof o.path=="string"?o.path:void 0,a=o.edits;if(i!==void 0&&Array.isArray(a)){for(let d of a){if(!d||typeof d!="object")continue;let u=d,c=typeof u.old_string=="string"?u.old_string:void 0,l=typeof u.new_string=="string"?u.new_string:void 0;c===void 0||l===void 0||e.push({path:i,oldText:c,newText:l})}if(e.length>0)return e}}let n=s.content;if(Array.isArray(n)){for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(i.type!=="diff")continue;let a=typeof i.path=="string"?i.path:void 0;if(a===void 0)continue;let d=typeof i.oldText=="string"?i.oldText:"",u=typeof i.newText=="string"?i.newText:"";e.push({path:a,oldText:d,newText:u})}if(e.length>0)return e}let r=es(s);return r&&r.path&&e.push({path:r.path,oldText:r.oldText,newText:r.newText}),e}function za(s,e={}){let t=lp(s),{events:n,window:r}=up(t,e),o=fp(n),i=[];pp(i,s),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),gp(i,n,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
139
178
  `);return a.endsWith(`
140
179
  `)||(a+=`
141
- `),a}function Ls(n,e){let t=n<0?e+n+1:n;return t<1?1:t>e?e:t}function kl(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 Al(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 Cl(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 xl(n,e){let t=e.session,s=vo(t.sessionId),r=t.title?.trim()||`Hydra session ${s}`;n.push(`# ${Ft(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 Ml(n,e,t,s){let{includeTools:r,includeThoughts:o}=s;if(!e.some(g=>El(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(`- ${Tl(h.status)} ${Rl(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} ${Ft(h.content)}`)}n.push("");break}case"mode-changed":m(),l(),n.push(`_mode: ${Ft(g.mode)}_`),n.push("");break;case"model-changed":m(),l(),n.push(`_model: ${Ft(g.model)}_`),n.push("");break;case"turn-complete":l();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}l()}function El(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 Rl(n){let e=n.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${Ft(n.title)}${t}`}function Tl(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"}}var _i=String.raw`<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s[^<>]*)?\/?>`,Pl=new RegExp(_i);function Ti(n,e,t){if(Pl.test(e)){_l(n,e);return}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];n.push(a===0&&a===i.length-1?`${t}${d}${t}`:a===0?`${t}${d}`:a===i.length-1?`${d}${t}`:d)}r<s.length-1&&n.push("")}}function _l(n,e){let t=e.replace(/\s+$/,"");if(t.length===0)return;let s=0;for(let o of t.match(/`+/g)??[])s=Math.max(s,o.length);let r="`".repeat(Math.max(3,s+1));n.push(r);for(let o of t.split(`
144
- `))n.push(o);n.push(r)}function Ft(n){return n.replace(new RegExp(_i,"g"),e=>e.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 $l(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=>Fl(c)).filter(c=>c.term.length>0);return{operator:o,terms:u}}function Fl(n){let e=/^(\w+):"([^"]*)"$/.exec(n);if(e)return{scope:Fi(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:Fi(s[1]),term:s[2].trim()}:{scope:"all",term:n.trim()}}function Fi(n){switch(n.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";default:return"all"}}function Ol(n,e){return n==="all"?!0:n==="user"?e==="user":n==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var Nl=5,Hl=200,Mn=72,jl=24,Bl=512;function Hi(n){return Number.isFinite(n)?Math.max(jl,Math.min(Bl,Math.floor(n))):Mn}async function ji(n,e,t={}){let s=$l(e);if(s.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??Nl,o=t.maxSessions??Hl,i=Hi(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=Ul(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 Ul(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=Dl(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 Dl(n,e,t,s,r){let o=e.toLowerCase(),i=0,a=[];for(let d of n){let u=Ll(d).filter(c=>Ol(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:Ql(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 Ll(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(Wl(s))return[];let o=xn(s.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=Vl(s.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return ql(s);default:return[]}}function ql(n){let e=Oi(n,"name"),t=Oi(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=Ni(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=Ni(o);if(a.length>0){let d={kind:"tool-input",text:Q(a)};e!==void 0&&(d.toolName=e),s.push(d)}}let i=zl(n);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),s.push(a)}return s}function zl(n){if(!Jl(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 Jl(n){return n==="failed"||n==="rejected"||n==="cancelled"}function Wl(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 Vl(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 Oi(n,e){let t=n[e];return typeof t=="string"?t:void 0}function Ni(n){try{return JSON.stringify(n)}catch{return""}}function Ql(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=Hi(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 Ui}from"crypto";function Bi(n){let e=Ui(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(Bi({name:"hydra-acp-stdin",session:s,tokenRegistry:e,getOrigin:t})),r.push(Bi({name:"hydra-acp-recall",session:s,tokenRegistry:e,getOrigin:t}));let o=ct(n.deps);return o!==void 0&&(o.bindToSession(s),r=[...r,...o.descriptors]),r}}function ct(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=Ui(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 Di(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 zi(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 ji(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=ct(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=>qi.join(Li.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=kt({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:ht(),hydraHost:Di(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=kt({record:l.record,history:l.history,promptHistory:l.promptHistory.length>0?l.promptHistory:void 0,hydraVersion:Y,machine:ht(),hydraHost:Di(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)+`
145
- `):(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)+`
146
- `);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)+`
147
- `)}}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)+`
148
- `),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)+`
149
- `)}}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 Ji(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 Wi(n,e,t){n.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t}))}var Gl=/^[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=Kl(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 Kl(n){let e=n.name;if(typeof e!="string"||!Gl.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 Vi(n,e){Rn(n,"extension",e)}function Qi(n,e){Rn(n,"transformer",e)}function Gi(n,e){n.get("/v1/config",async()=>e)}import{z as lt}from"zod";W();import*as ut from"fs/promises";import*as Ki from"path";import{randomBytes as Xy,scrypt as Yl,timingSafeEqual as Xl}from"crypto";import{promisify as Zl}from"util";var ef=Zl(Yl);function Yi(){return Ki.join(I.home(),"password-hash")}var tf=128*1024*1024;async function Xi(){try{return(await ut.readFile(Yi(),"utf8")).trim().length>0}catch(n){if(n.code==="ENOENT")return!1;throw n}}async function Zi(n){if(typeof n!="string"||n.length===0)return!1;let e;try{e=(await ut.readFile(Yi(),"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 ef(n,i,a.length,{N:s,r,p:o,maxmem:tf});return d.length!==a.length?!1:Xl(d,a)}var nf=lt.object({password:lt.string().min(1),label:lt.string().min(1).max(256).optional(),ttlSec:lt.number().int().positive().optional()}),sf=lt.object({id:lt.string().optional()}).optional();function ea(n,e){n.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,s)=>{let r=rf(t);if(e.rateLimiter.isBlocked(r))return s.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=nf.parse(t.body)}catch{return s.code(400).send({error:"Invalid request body"})}if(!await Xi())return s.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await Zi(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=sf.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 rf(n){return n.ip||"unknown"}import{nanoid as Vs}from"nanoid";function ta(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 aa}from"crypto";import*as da from"os";import*as ca from"path";var of=200;function af(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,of)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function na(n,e,t){let s=af(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 sa(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 ra(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 ff(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=ct(n),s,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&n.mcpTokenRegistry!==void 0&&n.getDaemonOrigin!==void 0&&(s=aa(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 Sf(u,n),la(u.sessionId,n),u}function ua(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=ta(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)),vf()}),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=>hf(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=ff(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=>yf(p,o.name,e)),a.onRequest("hydra-acp/attention/clear",async p=>wf(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=>pf(f,e)),a.onRequest("logout",async f=>mf(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=aa(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=ct(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:ia(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),la(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:bf($)}}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:ia(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 na(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&&ra(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?sa(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=gf(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 pf(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&&ca.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=da.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 mf(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 ia(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 gf(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 hf(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 yf(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 wf(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 bf(n){let e={sessionId:n.hydraSessionId,upstreamSessionId:n.upstreamSessionId,cwd:n.cwd,title:n.title,agentId:n.agentId,currentModel:n.currentModel,currentUsage:At(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 gt(e.agentMeta,Wt(s,r))}function vf(){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:gt(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 Sf(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 la(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 If}from"crypto";import{McpServer as kf}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Af}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 fa="Bearer ";function ft(n){let e=n.headers.authorization;if(typeof e!="string"||!e.startsWith(fa))return;let t=e.slice(fa.length).trim();return t.length>0?t:void 0}function Cf(n){let e=new kf({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 xf=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=Cf(a),c=new Af({sessionIdGenerator:()=>If()});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=ft(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),xf)}),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 Mf}from"crypto";import{McpServer as Ef}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Rf}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as _e}from"zod";function Tf(n){switch(n){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}function Pf(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 _f(n){let e=new Ef({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=Tf(p),h=Pf(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 $f=1e4;function ma(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=_f(a),c=new Rf({sessionIdGenerator:()=>Mf()});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=ft(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),$f)}),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 Df}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as Lf}from"crypto";import{Server as Ff}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as Of,ListToolsRequestSchema as Nf}from"@modelcontextprotocol/sdk/types.js";function ga(n,e,t,s){let r=typeof t=="function"?async()=>t():async()=>t,o=new Ff({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(Nf,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(Of,async(a,d)=>{let u=a.params.name,c=d._meta?.progressToken??d.requestId,f=jf(c,d.sendNotification);try{let p=await r(),l=await Bf(e.connection,n,u,a.params.arguments??{},p);return Uf(l,u)}catch(p){return Gs(p instanceof Error?p.message:String(p))}finally{f()}}),o}var Hf=15e3;function jf(n,e,t=Hf){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 Bf(n,e,t,s,r){return await n.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:s,sessionId:r})}function Uf(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 qf=1e4;function ha(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=ga(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),qf)}),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 Df({sessionIdGenerator:()=>Lf()});return await b.connect(w),p.set(f,{server:b,transport:w}),w}async function d(c,f){let p=ft(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 Ia(n,e){Kf(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 Qf(n.daemon.logLevel),i=zf({logger:{level:n.daemon.logLevel,stream:r},bodyLimit:256*1024*1024});await i.register(Jf,{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});Wi(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};zi(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}),Ji(i,m,b,{npmRegistry:n.npmRegistry}),Vi(i,w),Qi(i,v),Gi(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]}),ea(i,{store:a,rateLimiter:d}),pa(i,A),ma(i,A);let _=ha(i,A,C);ua(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=Gf({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,Fa)=>{try{await Fa()}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{ba.unlinkSync(I.pidFile())}catch{}await O("fileStream.flushSync",()=>o.flushSync())}}}var wa=20;async function Vf(n,e){let t=pt.dirname(n),s=pt.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(pt.join(t,d.name))))}async function Qf(n){await Vf(I.logFile(),wa);let e=await Wf({file:I.logFile(),size:"10m",mkdir:!0,symlink:!0,limit:{count:wa,removeOtherLogFiles:!0}}),t=ya.destination(2);return{stream:ya.multistream([{stream:e,level:n},{stream:t,level:n}]),fileStream:e}}function Gf(n){let e=Sa.createServer(n.tlsOptions,t=>{let s=va.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 Kf(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 lp(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:n}=await Promise.resolve().then(()=>(_a(),Pa));n();let e=await zn(),t=await tr(),s=await Ia(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
180
+ `),a}function Fr(s,e){let t=s<0?e+s+1:s;return t<1?1:t>e?e:t}function up(s,e){if(!(e.from!==void 0||e.to!==void 0||e.last!==void 0)&&e.sinceMs===void 0)return{events:s};let n=[],r=0;for(let{event:f}of s)f.kind==="user-text"&&(r+=1),n.push(r===0?1:r);let o=Math.max(r,1),i=1,a=o;if(e.last!==void 0&&e.last>0?i=Fr(o-e.last+1,o):(e.from!==void 0&&(i=Fr(e.from,o)),e.to!==void 0&&(a=Fr(e.to,o))),i>a)return{events:[],window:{from:i,to:a,total:o}};let d=e.sinceMs,u=new Set;d!==void 0&&s.forEach((f,m)=>{f.recordedAt>=d&&u.add(n[m])});let c=[],l,p;return s.forEach((f,m)=>{let g=n[m];g<i||g>a||d!==void 0&&!u.has(g)||(c.push(f),l??=g,p=g)}),{events:c,window:{from:l??i,to:p??a,total:o}}}function lp(s){let e=[];for(let t of s.history){if(t.method!=="session/update")continue;let n=t.params;if(!n||typeof n!="object")continue;let r=Oa(n.update,{cwd:s.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function fp(s){let e=new Map;for(let{event:t}of s){if(t.kind==="tool-call"){let n=e.get(t.toolCallId);e.set(t.toolCallId,{title:t.title,status:t.status??n?.status??"pending"});continue}if(t.kind==="tool-call-update"){let n=e.get(t.toolCallId)??{title:"tool call",status:"pending"};e.set(t.toolCallId,{title:t.title??n.title,status:t.status??n.status})}}return e}function pp(s,e){let t=e.session,n=Oe(t.sessionId),r=t.title?.trim()||`Hydra session ${n}`;s.push(`# ${Zt(r)}`),s.push("");let o=[];o.push(`- **Session:** \`${n}\` (lineage \`${t.lineageId}\`)`);let i=[t.agentId];t.currentModel&&i.push(`model: ${t.currentModel}`),t.currentMode&&i.push(`mode: ${t.currentMode}`),o.push(`- **Agent:** ${i.filter(Boolean).join(" \xB7 ")}`),o.push(`- **Cwd:** ${t.cwd}`),o.push(`- **Exported:** ${e.exportedAt} from ${e.exportedFrom.machine} (hydra ${e.exportedFrom.hydraVersion})`);let a=t.currentUsage;if(a&&(a.used!==void 0||a.costAmount!==void 0||a.cumulativeCost!==void 0)){let d=[];if(a.used!==void 0){let c=a.size!==void 0?`${Nr(a.size)}`:void 0;d.push(c?`${Nr(a.used)} / ${c} tokens`:`${Nr(a.used)} tokens`)}let u=kr(a);if(u!==void 0){let c=a.costCurrency??"USD";d.push(`$${u.toFixed(2)} ${c}`)}o.push(`- **Usage:** ${d.join(" \xB7 ")}`)}s.push(o.join(`
181
+ `)),s.push("")}function gp(s,e,t,n){let{includeTools:r,includeThoughts:o}=n;if(!e.some(g=>mp(g.event,o))){s.push("_No conversation history recorded._"),s.push("");return}let i=0,a="",d="",u=[],c=new Set,l=!1,p=()=>{if(u.length!==0){for(let g of u)s.push(g);s.push(""),u=[]}},f=()=>{p(),d.length>0&&(qa(s,d.trimEnd(),"*"),s.push(""),d=""),a.length!==0&&(s.push(a.trimEnd()),s.push(""),a="")},m=()=>{l||(l=!0)};for(let{event:g}of e)switch(g.kind){case"user-text":{f(),s.push("---"),s.push(""),i+=1,qa(s,g.text,"**"),s.push(""),l=!0;break}case"agent-text":m(),a+=g.text;break;case"agent-thought":{if(!o)break;m(),a.length>0&&(s.push(a.trimEnd()),s.push(""),a=""),d+=g.text;break}case"tool-call":{if(!r||(m(),(a.length>0||d.length>0)&&f(),c.has(g.toolCallId)))break;c.add(g.toolCallId);let h=t.get(g.toolCallId)??{title:g.title,status:g.status??"pending"};u.push(`- ${yp(h.status)} ${hp(h)}`);break}case"tool-call-update":break;case"plan":{m(),f(),s.push("**Plan:**"),s.push("");for(let h of g.entries){let y=h.status==="completed"?"[x]":"[ ]";s.push(`- ${y} ${Zt(h.content)}`)}s.push("");break}case"mode-changed":m(),f(),s.push(`_mode: ${Zt(g.mode)}_`),s.push("");break;case"model-changed":m(),f(),s.push(`_model: ${Zt(g.model)}_`),s.push("");break;case"turn-complete":f();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}f()}function mp(s,e){switch(s.kind){case"agent-thought":return e;case"usage-update":case"available-commands":case"session-info":case"unknown":case"turn-complete":return!1;default:return!0}}function hp(s){let e=s.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${Zt(s.title)}${t}`}function yp(s){switch(s){case"completed":return"\u2713";case"failed":return"\u2717";case"cancelled":case"rejected":return"\u2298";case"in_progress":return"\u21BB";default:return"\xB7"}}var Ja=String.raw`<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s[^<>]*)?\/?>`,wp=new RegExp(Ja);function qa(s,e,t){if(wp.test(e)){kp(s,e);return}let n=e.split(/\n\s*\n/);for(let r=0;r<n.length;r++){let o=n[r];if(o.trim().length===0)continue;let i=o.split(`
182
+ `);for(let a=0;a<i.length;a++){let d=i[a];s.push(a===0&&a===i.length-1?`${t}${d}${t}`:a===0?`${t}${d}`:a===i.length-1?`${d}${t}`:d)}r<n.length-1&&s.push("")}}function kp(s,e){let t=e.replace(/\s+$/,"");if(t.length===0)return;let n=0;for(let o of t.match(/`+/g)??[])n=Math.max(n,o.length);let r="`".repeat(Math.max(3,n+1));s.push(r);for(let o of t.split(`
183
+ `))s.push(o);s.push(r)}function Zt(s){return s.replace(new RegExp(Ja,"g"),e=>e.replace(/</g,"&lt;").replace(/>/g,"&gt;"))}function Nr(s){return s.toLocaleString("en-US")}function Va(s){return s==="127.0.0.1"||s==="::1"||s==="localhost"||s==="[::1]"}function vp(s){let e=s.trim();if(e.length===0)return{operator:"OR",terms:[]};let t=/\w+:"[^"]*"|"[^"]*"|\S+/g,n=[],r;for(;(r=t.exec(e))!==null;)n.push(r[0]);let o="OR",i=!1,a=!1,d=[];for(let c of n){let l=c.toUpperCase();l==="AND"?i=!0:l==="OR"?a=!0:d.push(c)}i?o="AND":a&&(o="OR");let u=d.map(c=>bp(c)).filter(c=>c.term.length>0);return{operator:o,terms:u}}function bp(s){let e=/^(\w+):"([^"]*)"$/.exec(s);if(e)return{scope:Qa(e[1]),term:e[2]};let t=/^"([^"]*)"$/.exec(s);if(t)return{scope:"all",term:t[1]};let n=/^(prompt|response|tool):([\s\S]*)$/i.exec(s);return n?{scope:Qa(n[1]),term:n[2].trim()}:{scope:"all",term:s.trim()}}function Qa(s){switch(s.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";default:return"all"}}function Sp(s,e){return s==="all"?!0:s==="user"?e==="user":s==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var Ip=5,Ap=200,ns=72,Cp=24,xp=512;function Ya(s){return Number.isFinite(s)?Math.max(Cp,Math.min(xp,Math.floor(s))):ns}async function Xa(s,e,t={}){let n=vp(e);if(n.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??Ip,o=t.maxSessions??Ap,i=Ya(t.snippetWidth??ns),a=t.sessionIds?new Set(t.sessionIds):null,d=await s.list(),u=a?d.filter(p=>a.has(p.sessionId)):d,c=[],l=!1;for(let p of u){if(c.length>=o){l=!0;break}let f=await s.loadHistory(p.sessionId,{tools:"references"}).catch(()=>[]),m=Rp(f,n,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:l,results:c}}function Rp(s,e,t,n=ns){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=Ep(s,u,d,t,n);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 Ep(s,e,t,n,r){let o=e.toLowerCase(),i=0,a=[];for(let d of s){let u=Pp(d).filter(c=>Sp(t,c.kind));for(let c of u){let l=c.text.toLowerCase(),p=l.indexOf(o);if(p===-1)continue;let f=0;for(;p!==-1;)f++,p=l.indexOf(o,p+o.length);if(i+=f,a.length<n){let m=l.indexOf(o),g={kind:c.kind,text:Np(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 Pp(s){if(s.method!=="session/update")return[];let e=s.params;if(!e||typeof e!="object"||Array.isArray(e))return[];let t=e.update;if(!t||typeof t!="object"||Array.isArray(t))return[];let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:n.kind;if(typeof r!="string")return[];switch(r){case"agent_message_chunk":{let o=ts(n.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof n.text=="string"?we(n.text):ts(n.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if($p(n))return[];let o=ts(n.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=Fp(n.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return Mp(n);default:return[]}}function Mp(s){let e=Ka(s,"name"),t=Ka(s,"title"),n=[];if(t!==void 0){let a=Z(t);if(a.length>0){let d={kind:"tool",text:a};e!==void 0&&(d.toolName=e),n.push(d)}}if(e!==void 0&&e!==t){let a=Z(e);a.length>0&&n.push({kind:"tool",toolName:e,text:a})}let r=s.rawInput;if(r&&typeof r=="object"){let a=Ga(r);if(a.length>0){let d={kind:"tool-input",text:Z(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let o=s.locations;if(Array.isArray(o)&&o.length>0){let a=Ga(o);if(a.length>0){let d={kind:"tool-input",text:Z(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let i=Tp(s);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),n.push(a)}return n}function Tp(s){if(!_p(s.status))return null;let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=n.content;if(!o||typeof o!="object")continue;let i=o;if(i.type==="text"&&typeof i.text=="string"){let a=Z(i.text);if(a.length>0)return a}}let t=s.rawOutput;if(t&&typeof t=="object"){let n=t.error;if(typeof n=="string"){let r=Z(n);if(r.length>0)return r}}return null}function _p(s){return s==="failed"||s==="rejected"||s==="cancelled"}function $p(s){let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return!1;let t=e["hydra-acp"];return!t||typeof t!="object"||Array.isArray(t)?!1:t.compatFor==="prompt_received"}function ts(s){if(typeof s=="string")return we(s);if(!s||typeof s!="object"||Array.isArray(s))return"";let e=s;return typeof e.text=="string"?we(e.text):""}function Fp(s){if(!Array.isArray(s))return"";let e=[];for(let t of s){let n=ts(t);n.length>0&&e.push(n)}return e.join("")}function Ka(s,e){let t=s[e];return typeof t=="string"?t:void 0}function Ga(s){try{return JSON.stringify(s)}catch{return""}}function Np(s,e,t,n=ns){let r=s.replace(/\s+/g," ").trim();if(r.length===0)return"";let o=r.toLowerCase(),i=s.slice(e,e+t).toLowerCase().replace(/\s+/g," ").trim(),a=i.length>0?o.indexOf(i):0;a===-1&&(a=0);let d=Ya(n),u=Math.max(0,d-i.length),c=Math.floor(u/2),l=Math.min(c,a),p=Math.min(u-l,r.length-(a+i.length)),f=Math.max(0,a-(u-p)),m=Math.min(r.length,a+i.length+p),g=f>0?"\u2026":"",h=m<r.length?"\u2026":"";return`${g}${r.slice(f,m)}${h}`}import{randomBytes as ed}from"crypto";function Za(s){let e=ed(32).toString("hex");return s.tokenRegistry.reserve(e).complete(s.session),s.session.onClose(()=>{s.tokenRegistry.unbind(e)}),{name:s.name,type:"http",url:`${s.getOrigin()}/mcp/${s.name}`,headers:[{name:"Authorization",value:`Bearer ${e}`}]}}function Or(s){if(s.deps.mcpTokenRegistry===void 0||s.deps.getDaemonOrigin===void 0)return;let e=s.deps.mcpTokenRegistry,t=s.deps.getDaemonOrigin;return async n=>{let r=[...s.baselineMcpServers??[]];s.stdinEnabled&&r.push(Za({name:"hydra-acp-stdin",session:n,tokenRegistry:e,getOrigin:t})),r.push(Za({name:"hydra-acp-recall",session:n,tokenRegistry:e,getOrigin:t}));let o=Ct(s.deps);return o!==void 0&&(o.bindToSession(n),r=[...r,...o.descriptors]),r}}function Ct(s){if(s.extensionMcp===void 0||s.mcpTokenRegistry===void 0||s.getDaemonOrigin===void 0)return;let e=s.extensionMcp.list();if(e.length===0)return;let t=ed(32).toString("hex"),n=s.mcpTokenRegistry.reserve(t),r=s.getDaemonOrigin(),o=e.map(a=>({name:a,type:"http",url:`${r}/mcp/${a}`,headers:[{name:"Authorization",value:`Bearer ${t}`}]})),i=s.mcpTokenRegistry;return{descriptors:o,bindToSession:a=>{n.complete(a),a.onClose(()=>{i.unbind(t)})},abandon:a=>n.abandon(a)}}var ss=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function td(s){if(s.publicHost&&s.publicHost.length>0)return s.publicHost;if(s.host&&!Va(s.host))return s.port!==void 0?`${s.host}:${s.port}`:s.host}function sd(s,e,t,n={}){s.get("/v1/sessions",async u=>{let c=u.query,l=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:l,...p?{status:p}:{}})}}),s.get("/v1/sessions/:id",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=await e.getOne(p);return f||(c.code(404).send({error:"session not found"}),c)}),s.post("/v1/sessions/search",async(u,c)=>{let l=u.body??{},p=typeof l.q=="string"?l.q:"";if(p.trim().length===0)return c.code(400).send({error:"q is required"}),c;let m={sessionIds:Array.isArray(l.sessionIds)?l.sessionIds.filter(h=>typeof h=="string"&&h.length>0):void 0};return typeof l.snippetWidth=="number"&&(m.snippetWidth=l.snippetWidth),await Xa(e,p,m)}),s.post("/v1/sessions",async(u,c)=>{let l=u.body??{},p=de(l.cwd??t.cwd),f=l.agentId??t.agentId,m=Ct(n),g=m!==void 0?[...l.mcpServers??[],...m.descriptors]:l.mcpServers;try{let h=await e.create({cwd:p,agentId:f,mcpServers:g,...l.workspace!==void 0?{workspace:l.workspace}:{}});m!==void 0&&m.bindToSession(h),c.code(201).send({sessionId:h.sessionId,agentId:h.agentId,cwd:h.cwd,...h.workspace!==void 0?{workspace:h.workspace}:{},...h.workspaceError!==void 0?{workspaceError:h.workspaceError}:{}})}catch(h){m!==void 0&&m.abandon(h instanceof Error?h:void 0),c.code(500).send({error:h.message})}}),s.post("/v1/sessions/collect",async(u,c)=>{let l=u.body??{},p=typeof l.maxAgeDays=="number"&&l.maxAgeDays>0?l.maxAgeDays*24*60*60*1e3:0,f=typeof l.limit=="number"&&l.limit>0?l.limit:1e3,m=l.selection==="explicit"||l.selection==="unpromoted"?l.selection:"unpromoted";try{let g=await Mr({manager:e,maxAgeMs:p,maxDeletions:f,selection:m,verbose:!1});c.code(200).send(g)}catch(g){c.code(500).send({error:g.message})}}),s.post("/v1/sessions/:id/kill",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=e.get(p);if(f){f.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()}),s.post("/v1/sessions/:id/stdin/open",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=e.get(p);if(!f)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=>rs.join(nd.tmpdir(),`hydra-acp-stdin-${h}.log`));try{return f.openStream(g)}catch(h){return c.code(409).send({error:h.message}),c}}),s.post("/v1/sessions/:id/stdin",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=e.get(p);if(!f)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 f.streamWrite(g,h)}catch(y){return c.code(409).send({error:y.message}),c}}),s.patch("/v1/sessions/:id",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=u.body??{};if(f.cwd!==void 0){if(typeof f.cwd!="string"||!rs.isAbsolute(f.cwd)){c.code(400).send({error:"cwd must be an absolute path"});return}let g=await e.setCwd(p,f.cwd);if(g==="missing"){c.code(404).send({error:"session not found"});return}if(g==="not-a-directory"){c.code(400).send({error:`${f.cwd} is not a directory`});return}if(g==="live"){c.code(409).send({error:"session is live; its agent was spawned in its cwd and cannot change directory. Moving a live session is a swap \u2014 use `workspace start` in it."});return}if(g==="bound"){c.code(409).send({error:"session is isolated, so its cwd IS its workspace. Clear the binding first (PATCH { workspace: null }) or leave the workspace from inside the session."});return}c.code(204).send();return}if("workspace"in f){if(f.workspace!==null){c.code(400).send({error:"workspace may only be set to null (clear the binding)"});return}let g=await e.clearWorkspaceBinding(p);if(g==="missing"){c.code(404).send({error:"session not found"});return}if(g==="live"){c.code(409).send({error:"session is live; its cwd is the workspace. Use `workspace stop` or `workspace detach` in the session so the agent moves with the binding."});return}c.code(204).send();return}if(f.priority!==void 0){let g=f.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(f.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 f.title!="string"||f.title.trim().length===0){c.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(p,f.title)){c.code(404).send({error:"session not found"});return}c.code(204).send()}),s.delete("/v1/sessions/:id",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=e.get(p);if(f){await f.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()}),s.get("/v1/sessions/:id/export",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=u.query?.tools,m=f==="references"?"references":Zi(f),g=await e.exportBundle(p,m==="references"?{tools:"references"}:{});if(!g){c.code(404).send({error:"session not found"});return}let h=Wt({record:g.record,history:m==="summary"?ea(g.history,"summary"):g.history,promptHistory:g.promptHistory.length>0?g.promptHistory:void 0,...g.toolBlobs!==void 0?{toolBlobs:g.toolBlobs}:{},hydraVersion:ie,machine:_t(),hydraHost:td(t)}),y=new Date().toISOString().replace(/[:.]/g,"-");c.header("Content-Disposition",`attachment; filename="${p}-${y}.hydra"`),c.code(200).send(h)}),s.get("/v1/sessions/:id/diff",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=await e.exportBundle(p);if(!f){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(k=>k.trim()).filter(k=>k.length>0)):void 0,y=Ua(f.history);h&&(y=y.filter(k=>h.has(k.path))),g&&(y=y.map(k=>({...k,hunks:Wa(k.hunks)}))),c.code(200).send(y)}),s.get("/v1/sessions/:id/tools/:hash",async(u,c)=>{let l=u.params,p=await e.resolveCanonicalId(l.id)??l.id,f=await e.loadToolBlob(p,l.hash);if(f===null){c.code(404).send({error:"tool blob not found"});return}c.header("Content-Type","text/plain; charset=utf-8"),c.code(200).send(f)}),s.get("/v1/sessions/:id/transcript",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=await e.exportBundle(p);if(!f){c.code(404).send({error:"session not found"});return}let m=Wt({record:f.record,history:f.history,promptHistory:f.promptHistory.length>0?f.promptHistory:void 0,hydraVersion:ie,machine:_t(),hydraHost:td(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 b=Number(v);return Number.isFinite(b)?b:"bad"},k={};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&&(k[w==="since"?"sinceMs":w]=v)}c.header("Content-Type","text/markdown; charset=utf-8"),c.code(200).send(za(m,{includeTools:h(g?.tools),includeThoughts:h(g?.thoughts),...k}))}),s.post("/v1/sessions/:id/fork",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=u.body??{},m={};if(f.forkAt!==void 0){if(typeof f.forkAt!="string"||f.forkAt.length===0){c.code(400).send({error:"forkAt must be a non-empty string"});return}m.forkAt=f.forkAt}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}m.cwd=de(f.cwd)}if(f.agentId!==void 0){if(typeof f.agentId!="string"||f.agentId.length===0){c.code(400).send({error:"agentId must be a non-empty string"});return}m.agentId=f.agentId}if(f.title!==void 0){if(typeof f.title!="string"){c.code(400).send({error:"title must be a string"});return}m.title=f.title}if(f.mode!==void 0){if(f.mode!=="verbatim"&&f.mode!=="synthesis"){c.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}m.mode=f.mode}if(f.model!==void 0){if(typeof f.model!="string"||f.model.length===0){c.code(400).send({error:"model must be a non-empty string"});return}m.model=f.model}try{let g=await e.forkSession(p,m);c.code(201).send(g)}catch(g){let h=g;if(h.code===C.SessionNotFound){c.code(404).send({error:h.message});return}if(h.code===C.InvalidParams||h.code===C.AgentNotInstalled){c.code(400).send({error:h.message});return}c.code(500).send({error:h.message})}}),s.post("/v1/sessions/import",async(u,c)=>{let l=u.body??{};if(l.bundle===void 0){c.code(400).send({error:"missing bundle"});return}let p;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}p=l.cwd}let f;try{f=da(l.bundle)}catch(m){c.code(400).send({error:"invalid bundle",details:m.message});return}try{let m=await e.importBundle(f,{replace:l.replace===!0,...p!==void 0?{cwd:p}:{}});c.code(201).send(m)}catch(m){let g=m;if(g.code===C.BundleAlreadyImported){c.code(409).send({error:"bundle already imported",existingSessionId:g.existingSessionId});return}c.code(500).send({error:g.message})}}),s.get("/v1/sessions/:id/compact/status",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=e.get(p),m;if(f?m=f.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,k,v=await e.getHistory(p).catch(()=>[])??[];if(v.length>0&&t.compaction){let b=m??0,S=v.length,x=v.slice(b),R=Ta(x);k=_r(R);let P=f?.currentModel,H=v.at(-1).recordedAt,_=f?.currentUsage;y=_a({summarizedThroughEntry:b,totalEntries:S,unsummarizedChars:R,compactionInFlight:e.getCompactionInFlight(),currentModel:P,lastActivityMs:H,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,...k!=null?{approxTokens:k}:{},...g!=null?{compactionState:g}:{},...h!=null?{rollbackBreadcrumb:h}:{}}}),s.post("/v1/sessions/:id/compact",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l;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})}),s.post("/v1/sessions/:id/compact/rollback",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l;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(f){let m=f instanceof Error?f.message:String(f);c.code(409).send({error:m})}}),s.post("/v1/sessions/:id/workspace/clean",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=u.body??{};if(f.deep!==void 0&&typeof f.deep!="boolean"){c.code(400).send({error:"deep must be a boolean"});return}if(!await e.hasRecord(p)){c.code(404).send({error:"session not found"});return}if(e.get(p)===void 0){c.code(409).send({error:"session is not live. Cleaning rewrites the workspace under a running agent, so it is only available inside a live session (`/hydra workspace clean`). For a cold workspace use `hydra workspace remove` instead."});return}try{let m=await e.runWorkspaceAction(p,"clean",void 0,{deep:f.deep===!0});c.code(202).send({report:m})}catch(m){c.code(409).send({error:m instanceof Error?m.message:String(m)})}}),s.get("/v1/sessions/:id/history",async(u,c)=>{let l=u.params.id,p=u.query,f=p?.follow==="1"||p?.follow==="true",m=await e.resolveCanonicalId(l)??l,g=e.get(m),h,y,k=!1,w=1e4,v=[];if(g){f&&(y=g.onBroadcast(S=>{c.raw.writableEnded||(k?c.raw.write(JSON.stringify(S)+`
184
+ `):(v.push(S),v.length>w&&v.shift()))})),u.raw.on("close",()=>{y?.(),c.raw.writableEnded||c.raw.end()});try{h=await g.getHistorySnapshot()}catch(S){throw y?.(),S}}else{let S=await e.getHistory(m);if(S===void 0)return c.code(404).send({error:"session not found"}),c;h=S}c.raw.setHeader("Content-Type","application/x-ndjson"),c.raw.setHeader("Cache-Control","no-cache"),c.raw.statusCode=200;let b=new Set;for(let S of h??[]){c.raw.write(JSON.stringify(S)+`
185
+ `);let x=S;typeof x.recordedAt=="number"&&b.add(String(x.recordedAt))}for(;v.length>0;){let S=v.splice(0,v.length);for(let x of S){let R=x,P=typeof R.recordedAt=="number"?String(R.recordedAt):"";P&&b.has(P)||c.raw.write(JSON.stringify(x)+`
186
+ `)}}return k=!0,y||c.raw.end(),c});function r(u,c,l){let p=typeof u=="string"?u.trim():"";if(p.length===0)return null;let f;try{f=JSON.parse(p)}catch{return console.debug("events endpoint: skipping malformed JSONL line"),null}if(!f||typeof f!="object"||Array.isArray(f))return console.debug("events endpoint: skipping non-object JSONL line"),null;let m=f;if(typeof m.recordedAt!="number"||l!==void 0&&m.recordedAt<l||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:f}}function o(u,c,l){let f=c.params.update,m={sessionId:u,ts:new Date(c.recordedAt).toISOString(),kind:l,update:f};return f.messageId!==void 0&&f.messageId!==null&&(m.messageId=f.messageId),m}async function*i(u,c,l,p){for await(let f of c){let m=r(f,l,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,l,p){let f=jr.createInterface({input:Hr.createReadStream(c),crlfDelay:1/0}),m=i(u,f,l,p),g=await m.next(),h=g.done?null:g.value;return{sessionId:u,rl:f,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}s.get("/v1/sessions/events",async(u,c)=>{let l=u.query,p=l.kinds;if(!p||p.trim().length===0)return c.code(400).send({error:"kinds parameter is required"}),c;let f=p.split(",").map(w=>w.trim());if(f.length===0)return c.code(400).send({error:"kinds parameter is required"}),c;for(let w of f)if(!ss.has(w))return c.code(400).send({error:`kind "${w}" is not queryable; allowed kinds: ${[...ss].join(", ")}`}),c;let m=new Set(f),g;if(l.since!==void 0&&l.since.trim().length>0){let w=new Date(l.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 k=[];for(let w of y)try{let v=A.historyFile(w.sessionId),b=await a(w.sessionId,v,m,g);b.exhausted||k.push(b)}catch(v){if(v.code==="ENOENT")continue;throw v}u.raw.on("close",()=>{for(let w of k)try{w.rl.close()}catch{}c.raw.writableEnded||c.raw.end()});try{for(;k.length>0;){let w=-1,v=1/0;for(let S=0;S<k.length;S++){let x=k[S];x.current!==null&&x.current.ts<v&&(v=x.current.ts,w=S)}if(w===-1)break;let b=k[w];if(c.raw.write(JSON.stringify(b.current.row)+`
187
+ `),await d(b),b.exhausted){try{b.rl.close()}catch{}k.splice(w,1)}}}catch(w){for(let v of k)try{v.rl.close()}catch{}throw w}return c.raw.end(),c}),s.get("/v1/sessions/:id/events",async(u,c)=>{let l=u.params.id,p=u.query,f=await e.resolveCanonicalId(l)??l;if(!e.get(f)&&!await e.hasRecord(f))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(S=>S.trim());if(h.length===0)return c.code(400).send({error:"kinds parameter is required"}),c;for(let S of h)if(!ss.has(S))return c.code(400).send({error:`kind "${S}" is not queryable; allowed kinds: ${[...ss].join(", ")}`}),c;let y=new Set(h),k;if(p.since!==void 0&&p.since.trim().length>0){let S=new Date(p.since);if(isNaN(S.getTime()))return c.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),c;k=S.getTime()}let w=A.historyFile(f),v=Hr.createReadStream(w),b=jr.createInterface({input:v,crlfDelay:1/0});c.raw.setHeader("content-type","application/x-ndjson"),c.raw.statusCode=200;try{for await(let S of b){let x=typeof S=="string"?S.trim():"";if(x.length===0)continue;let R;try{R=JSON.parse(x)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",w);continue}if(!R||typeof R!="object"||Array.isArray(R)){console.debug("events endpoint: skipping non-object JSONL line in %s",w);continue}let P=R;if(typeof P.recordedAt!="number"||typeof P.params!="object"||P.params===null||Array.isArray(P.params))continue;let H=P.params;if(typeof H.update!="object"||H.update===null||Array.isArray(H.update))continue;let _=H.update,N=_.sessionUpdate;if(typeof N!="string"||!y.has(N)||k!==void 0&&P.recordedAt<k)continue;let W={ts:new Date(P.recordedAt).toISOString(),kind:N,update:_};_.messageId!==void 0&&_.messageId!==null&&(W.messageId=_.messageId),c.raw.write(JSON.stringify(W)+`
188
+ `)}}catch(S){if(S.code==="ENOENT")return c.raw.end(),c;throw S}return c.raw.end(),c}),s.get("/v1/sessions/:id/attention",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,f=e.get(p);return!f&&!await e.hasRecord(p)?(c.code(404).send({error:"session not found"}),c):f?{flags:f.listAttentionFlags()}:{flags:(await e.store.read(p))?.attentionFlags??[]}}),s.get("/v1/sessions/attention",async(u,c)=>{let l=u.query;if(!l.source||l.source.trim().length===0)return c.code(400).send({error:"source query parameter is required"}),c;let p=await e.list({includeNonInteractive:!0}),f=[];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===l.source&&f.push({...y,sessionId:m.sessionId})}return{flags:f}}),s.post("/v1/sessions/:id/attention/clear",async(u,c)=>{let l=u.params.id,p=await e.resolveCanonicalId(l)??l,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 S=Array.from(y.listAttentionFlags()).map(x=>`${x.source}::${x.reason}`);for(let x of S)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 k=e.store,w=await k.read(p);if(!w){c.code(404).send({error:"session not found"});return}let v=w.attentionFlags??[],b;if(g.length>0&&h.length>0){let S=`${g}::${h}`;b=v.filter(x=>`${x.source}::${x.reason}`!==S)}else b=[];if(b.length===v.length&&b.every((S,x)=>S.source===v[x].source&&S.reason===v[x].reason)){c.code(204).send();return}await k.write({...w,attentionFlags:b}),c.code(204).send()})}function rd(s,e,t,n={}){s.get("/v1/agents",async()=>rt(e)),s.get("/v1/registry",async()=>e.load()),s.post("/v1/registry/refresh",async()=>{let r=await e.refresh();return{version:r.version,agentCount:r.agents.length}}),s.post("/v1/agents/:id/install",async(r,o)=>{let i=r.params.id,a=await e.getAgent(i);if(!a){o.code(404).send({error:`agent ${i} not found in registry`});return}if(a.distribution.uvx&&!a.distribution.npx&&!a.distribution.binary){o.send({agentId:a.id,version:a.version??"current",distribution:"uvx",installed:!1,message:"uvx agents resolve on first run; nothing to pre-install."});return}try{let d=await ye(a,[],{npmRegistry:n.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})}}),s.post("/v1/agents/:id/sync",async(r,o)=>{let i=r.params.id;try{let{synced:a,skipped:d}=await t.syncFromAgent(i);return{synced:a.map(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===C.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}function od(s,e,t){s.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t}))}var Op=/^[A-Za-z0-9._-]+$/;function os(s,e,t){let n=e==="extension"?"extensions":"transformers",r=`/v1/${n}`;s.get(r,async()=>({[n]:t.list()})),s.get(`${r}/:name`,async(o,i)=>{let a=o.params.name,d=t.get(a);if(!d){i.code(404).send({error:`unknown ${e}: ${a}`});return}return d}),s.post(r,async(o,i)=>{let a=o.body??{},d=Hp(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){en(i,u)}}),s.delete(`${r}/:name`,async(o,i)=>{let a=o.params.name;try{await t.unregister(a),i.code(204).send()}catch(d){en(i,d)}}),s.post(`${r}/:name/start`,async(o,i)=>{let a=o.params.name;try{let d=await t.startByName(a);i.code(200).send(d)}catch(d){en(i,d)}}),s.post(`${r}/:name/stop`,async(o,i)=>{let a=o.params.name;try{let d=await t.stopByName(a);i.code(200).send(d)}catch(d){en(i,d)}}),s.post(`${r}/:name/restart`,async(o,i)=>{let a=o.params.name;try{let d=await t.restartByName(a);i.code(200).send(d)}catch(d){en(i,d)}})}function en(s,e){let t=e.code,n=e.message??"unknown error";if(t==="NOT_FOUND"){s.code(404).send({error:n});return}if(t==="CONFLICT"){s.code(409).send({error:n});return}s.code(500).send({error:n})}function Hp(s){let e=s.name;if(typeof e!="string"||!Op.test(e))return{error:"name must match [A-Za-z0-9._-]+"};let t=s.command;if(t!==void 0&&(!Array.isArray(t)||t.some(i=>typeof i!="string")))return{error:"command must be string[]"};let n=s.args;if(n!==void 0&&(!Array.isArray(n)||n.some(i=>typeof i!="string")))return{error:"args must be string[]"};let r=s.env;if(r!==void 0&&(typeof r!="object"||r===null||Array.isArray(r)))return{error:"env must be an object of string\u2192string"};if(r&&Object.values(r).some(i=>typeof i!="string"))return{error:"env values must be strings"};let o=s.enabled;return o!==void 0&&typeof o!="boolean"?{error:"enabled must be a boolean"}:{config:{name:e,command:t??[],args:n??[],env:r??{},enabled:o===void 0?!0:o}}}function id(s,e){os(s,"extension",e)}function ad(s,e){os(s,"transformer",e)}function dd(s,e){s.get("/v1/config",async()=>e)}import{z as Rt}from"zod";K();import*as xt from"fs/promises";import*as cd from"path";import{randomBytes as mv,scrypt as jp,timingSafeEqual as Dp}from"crypto";import{promisify as Lp}from"util";var Bp=Lp(jp);function ud(){return cd.join(A.home(),"password-hash")}var Up=128*1024*1024;async function ld(){try{return(await xt.readFile(ud(),"utf8")).trim().length>0}catch(s){if(s.code==="ENOENT")return!1;throw s}}async function fd(s){if(typeof s!="string"||s.length===0)return!1;let e;try{e=(await xt.readFile(ud(),"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 n=parseInt(t[1],10),r=parseInt(t[2],10),o=parseInt(t[3],10);if(!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o))return!1;let i=Buffer.from(t[4],"hex"),a=Buffer.from(t[5],"hex");if(i.length===0||a.length===0)return!1;let d=await Bp(s,i,a.length,{N:n,r,p:o,maxmem:Up});return d.length!==a.length?!1:Dp(d,a)}var Wp=Rt.object({password:Rt.string().min(1),label:Rt.string().min(1).max(256).optional(),ttlSec:Rt.number().int().positive().optional()}),qp=Rt.object({id:Rt.string().optional()}).optional();function pd(s,e){s.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,n)=>{let r=zp(t);if(e.rateLimiter.isBlocked(r))return n.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=Wp.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}if(!await ld())return n.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await fd(o.password))return e.rateLimiter.recordFailure(r),n.code(401).send({error:"Invalid password"});e.rateLimiter.recordSuccess(r);let a=await e.store.issue({label:o.label,ttlSec:o.ttlSec});return n.code(200).send({session_token:a.token,id:a.id,expires_at:a.expiresAt})}),s.post("/v1/auth/logout",async(t,n)=>{let r;try{r=qp.parse(t.body??void 0)}catch{return n.code(400).send({error:"Invalid request body"})}let o=r?.id??t.authIdentity;if(!o||o==="service")return n.code(200).send({revoked:!1});let i=await e.store.revoke(o);return n.code(200).send({revoked:i})}),s.get("/v1/auth/verify",async(t,n)=>n.code(200).send({ok:!0})),s.get("/v1/auth/sessions",async(t,n)=>n.code(200).send({sessions:e.store.list()})),s.delete("/v1/auth/sessions/:id",async(t,n)=>{let r=t.params.id;return await e.store.revoke(r)?n.code(204).send():n.code(404).send({error:"Not found"})})}function zp(s){return s.ip||"unknown"}import{nanoid as Dr}from"nanoid";function gd(s){let e=[],t=[],n=!1,r=o=>{if(!n){n=!0;for(let i of t)i(o)}};return s.on("message",(o,i)=>{if(i)return;let a=o.toString("utf8");try{let d=JSON.parse(a);for(let u of e)u(d)}catch(d){for(let u of e)u({jsonrpc:"2.0",id:null,error:{code:C.ParseError,message:`Failed to parse WS frame: ${d.message}`}})}}),s.on("close",()=>r()),s.on("error",o=>r(o)),{async send(o){if(n)throw new Error("ws is closed");let i=JSON.stringify(o);await new Promise((a,d)=>{s.send(i,u=>{if(u){d(u);return}a()})})},onMessage(o){e.push(o)},onClose(o){t.push(o)},async close(){n||(await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,clearTimeout(d),o())},d=setTimeout(a,5e3);s.once("close",a);try{s.close()}catch{a()}}),r())}}}import{randomBytes as vd}from"crypto";import*as bd from"os";import*as Sd from"path";var Jp=200;function Vp(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[ve];if(!t||typeof t!="object"||Array.isArray(t))return;let n=t.sentBy;if(!n||typeof n!="object"||Array.isArray(n))return;let r=n,o={};if(typeof r.sessionId=="string"&&r.sessionId.length>0&&(o.sessionId=r.sessionId),typeof r.label=="string"&&r.label.length>0&&(o.label=r.label.slice(0,Jp)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function md(s,e,t){let n=Vp(s);if(!n)return;let r={};if(n.label!==void 0&&(r.fromLabel=n.label),n.awaiting===!0&&(r.awaiting=!0),n.sessionId!==void 0){let o=await e.resolveCanonicalId(n.sessionId)??n.sessionId,i=await e.getOne(o);if(i){r.fromSession=o,i.title&&(r.fromSessionTitle=i.title);let a=e.get(o)?.currentPromptDepth;r.depth=(a??0)+1}else t?.(n.sessionId)}if(!(r.fromSession===void 0&&r.fromLabel===void 0))return r}var tn=new Map;function hd(s,e){let t=tn.get(s);t||(t=new Set,tn.set(s,t)),t.add(e);let n=!1;return()=>{if(n)return;n=!0;let r=tn.get(s);r&&(r.delete(e),r.size===0&&tn.delete(s))}}function yd(s,e){if(s===e)return!0;let t=new Set,n=[e];for(;n.length>0;){let r=n.pop();if(t.has(r))continue;t.add(r);let o=tn.get(r);if(o){if(o.has(s))return!0;for(let i of o)n.push(i)}}return!1}function M(s,e,t){let n=new Error(e);return n.code=s,t!==void 0&&(n.data=t),n}function Xp(s){if(!s||typeof s!="object")return 512;let n=s.params?.update;if(!n)return 512;let r=512,o=n.content;if(typeof o=="string")r+=o.length;else if(o&&typeof o=="object"){let a=o;typeof a.text=="string"&&(r+=a.text.length),typeof a.data=="string"&&(r+=a.data.length)}let i=n.toolCall;if(i&&(typeof i.rawInput=="string"?r+=i.rawInput.length:i.rawInput&&typeof i.rawInput=="object"&&(r+=256),typeof i.rawOutput=="string"?r+=i.rawOutput.length:i.rawOutput&&typeof i.rawOutput=="object"&&(r+=256),Array.isArray(i.content)))for(let a of i.content){if(!a||typeof a!="object")continue;let d=a;if(typeof d.text=="string"&&(r+=d.text.length),d.content&&typeof d.content=="object"){let u=d.content;typeof u.text=="string"&&(r+=u.text.length)}}return r}function he(s,e,t){let n=s.get(e);if(!n)throw M(C.SessionNotFound,t??`session ${e} not found`);return n}async function is(s,e){let t=Ct(s),n,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&s.mcpTokenRegistry!==void 0&&s.getDaemonOrigin!==void 0&&(n=vd(32).toString("hex"),r=s.mcpTokenRegistry.reserve(n),o={name:"hydra-acp-recall",type:"http",url:`${s.getDaemonOrigin()}/mcp/hydra-acp-recall`,headers:[{name:"Authorization",value:`Bearer ${n}`}]});let a=[...t?.descriptors??[],...o!==void 0?[o]:[]],d=Or({baselineMcpServers:void 0,stdinEnabled:!1,deps:s}),u;try{u=await s.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),n!==void 0&&r!==void 0&&s.mcpTokenRegistry!==void 0){let c=n,l=s.mcpTokenRegistry;r.complete(u),u.onClose(()=>{l.unbind(c)})}return ag(u,s),Ad(u.sessionId,s),u}function Id(s,e){s.get("/acp",{websocket:!0},async(t,n)=>{let r=Ma({headers:n.headers,url:n.url});if(!r||!await e.validator.validate(r)){t.close(4401,"Unauthorized");return}let o=e.processRegistry?.resolve(r),i=gd(t),a=new at(i),d={clientId:`hydra_client_${Dr(12)}`,processIdentity:o,attached:new Map};a.onClose(()=>{for(let l of d.attached.values())e.manager.get(l.sessionId)?.detach(l.clientId);d.attached.clear()});let u=(l,p)=>{if(d.attached.get(l)?.readonly)throw M(C.PermissionDenied,`${p} not permitted on a read-only attachment`)};if(a.onRequest("initialize",async l=>{let p=xo.parse(l??{});p.clientInfo?.name&&(d.clientInfo={name:p.clientInfo.name,...p.clientInfo.version!==void 0?{version:p.clientInfo.version}:{}});let f=p.clientInfo?.version;return f&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,f):e.onTransformerVersion?.(o.name,f)),ig()}),o&&e.extensionCommands){let l=e.extensionCommands;a.onRequest("hydra-acp/commands/register",async p=>{let f=p??{},m=Array.isArray(f.commands)?f.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 l.register(o.name,a,m),{ok:!0,registered:m.length}}),a.onClose(()=>{l.clear(o.name)})}if(o&&e.extensionMcp){let l=e.extensionMcp;a.onRequest("hydra-acp/mcp_tools/register",async f=>{let m=f??{},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 k=y;if(typeof k.name!="string"||k.name.length===0||typeof k.description!="string"||k.inputSchema===null||typeof k.inputSchema!="object")return;let w={name:k.name,description:k.description,inputSchema:k.inputSchema};return k.outputSchema!==null&&typeof k.outputSchema=="object"&&(w.outputSchema=k.outputSchema),w}).filter(y=>y!==void 0):[];if(h.length===0)throw new Error("register_mcp_tools requires at least one tool");return l.register(o.name,a,g,h),{ok:!0,registered:h.length}});let p=f=>{let m=f??{};if(typeof m.sessionId!="string"||m.sessionId.length===0)throw M(C.InvalidParams,"sessionId is required");return m.sessionId};if(a.onRequest("hydra-acp/session/extension_state/get",async f=>{let m=p(f),g=f??{};if(typeof g.key!="string"||g.key.length===0)throw M(C.InvalidParams,"key is required");if(!e.manager)throw M(C.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 f=>{let m=p(f);if(!e.manager)throw M(C.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(m,o.name)}}),a.onRequest("hydra-acp/session/extension_state/set",async f=>{let m=p(f),g=f??{};if(typeof g.key!="string"||g.key.length===0)throw M(C.InvalidParams,"key is required");if(g.value===void 0)throw M(C.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw M(C.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(m,o.name,g.key,g.value)}catch(h){throw M(C.InvalidParams,h.message)}return{ok:!0}}),a.onRequest("hydra-acp/session/extension_state/delete",async f=>{let m=p(f),g=f??{};if(typeof g.key!="string"||g.key.length===0)throw M(C.InvalidParams,"key is required");if(!e.manager)throw M(C.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(m,o.name,g.key),{ok:!0}}),e.extensionMcpControls){let f=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 M(C.InvalidParams,"refresh_session requires sessionId");return await f.notifyToolListChanged(g.sessionId,o.name),{ok:!0}})}a.onClose(()=>{l.clear(o.name)})}if(o?.kind==="transformer"){a.onRequest("hydra-acp/transformer/initialize",async p=>{let f=p??{},m=Array.isArray(f.intercepts)?f.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 f=p??{},m=typeof f.sessionId=="string"?f.sessionId:void 0,g=typeof f.method=="string"?f.method:void 0,h=f.envelope,y=f.route;if(!m)throw M(-32602,"emit_message requires sessionId");if(!g&&y!=="client_broadcast")throw M(-32602,"emit_message requires method");let k=he(e.manager,m),w=typeof f.respondsTo=="string"?f.respondsTo:void 0;if(w)return k.dischargeClaim(w,h),{ok:!0};if(y==="chain")return{ok:!0,response:await k.emitToChain(o.name,g,h)};if(y==="queue"){if(g!=="session/prompt")throw M(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await k.emitToQueue(o.name,h)}}if(y==="daemon")return{ok:!0,response:await k.emitToChain(o.name,g,h)};if(y==="client_broadcast"){if(!h||typeof h!="object")throw M(-32602,"client_broadcast requires an envelope object");return k.broadcastClientUpdate(h),{ok:!0}}throw M(-32602,`unsupported route: ${JSON.stringify(y)}`)}),a.onRequest("hydra-acp/session/request_permission",async p=>{let f=p??{},m=typeof f.sessionId=="string"?f.sessionId:void 0;if(!m)throw M(-32602,"hydra-acp/session/request_permission requires sessionId");return he(e.manager,m).requestPermissionFromClients(f)}),a.onRequest("hydra-acp/transformer/attach",async p=>ng(p,o.name,e)),a.onRequest("hydra-acp/child_session/spawn",async p=>{let f=p??{},m=typeof f.agentId=="string"?f.agentId:e.defaultAgent,g=typeof f.cwd=="string"?f.cwd:void 0,h=typeof f.parentSessionId=="string"?f.parentSessionId:void 0,y=f._meta&&typeof f._meta=="object"?f._meta:void 0,k=y&&y["hydra-acp"]&&typeof y["hydra-acp"]=="object"?y["hydra-acp"]:void 0,w=k&&typeof k.title=="string"?k.title:void 0,v=k&&typeof k.model=="string"?k.model:void 0;if(!g&&h){let x=e.manager.get(h);x&&(g=x.cwd)}if(!g)throw M(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let b=typeof f.interactive=="boolean"?f.interactive:!1;return{childSessionId:(await e.manager.create({agentId:m,cwd:g,parentSessionId:h,interactive:b,transformChain:[],title:w,model:v})).sessionId}}),a.onRequest("hydra-acp/session/fork",async p=>{let f=p??{};if(typeof f.sessionId!="string")throw M(C.InvalidParams,"fork_session requires sessionId");let m=typeof f.forkAt=="string"?f.forkAt:void 0,g=typeof f.cwd=="string"?f.cwd:void 0,h=typeof f.agentId=="string"?f.agentId:void 0,y=typeof f.mode=="string"&&(f.mode==="verbatim"||f.mode==="synthesis")?f.mode:void 0,k=typeof f.model=="string"&&f.model.length>0?f.model:void 0;return await e.manager.forkSession(f.sessionId,{...m!==void 0?{forkAt:m}:{},...g!==void 0?{cwd:g}:{},...h!==void 0?{agentId:h}:{},...y!==void 0?{mode:y}:{},...k!==void 0?{model:k}:{}})}),a.onRequest("session/fork",async p=>{let f=p??{};if(typeof f.sessionId!="string")throw M(C.InvalidParams,"session/fork requires sessionId");let m=typeof f.cwd=="string"?f.cwd:void 0;return{sessionId:(await e.manager.forkSession(f.sessionId,{...m!==void 0?{cwd:m}:{},mode:"verbatim"})).sessionId}});let l=async(p,f)=>{let m=p??{};if(typeof m.sessionId!="string")throw M(C.InvalidParams,`${f} 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 l(p,"session/delete"),{})),a.onRequest("session/close",async p=>{let f=p??{};if(typeof f.sessionId!="string")throw M(C.InvalidParams,"session/close requires sessionId");u(f.sessionId,"session/close");let m=await e.manager.resolveCanonicalId(f.sessionId)??f.sessionId,g=e.manager.get(m);if(g)return await g.close({deleteRecord:!1}),{};if(await e.manager.hasRecord(m))return{};throw M(C.SessionNotFound,`session ${m} not found`)}),a.onRequest("hydra-acp/session/delete",async p=>{let{id:f,existed:m}=await l(p,"hydra-acp/session/delete");if(!m)throw M(C.SessionNotFound,`session ${f} not found`);return{deleted:!0,sessionId:f}}),a.onRequest("hydra-acp/child_session/await",async p=>{let f=p??{},m=typeof f.childSessionId=="string"?f.childSessionId:void 0,g=f.until==="idle"?"idle":"turn_complete",h=typeof f.timeoutMs=="number"?Math.min(f.timeoutMs,18e5):3e5;if(!m)throw M(-32602,"await_child requires childSessionId");let y=he(e.manager,m,`child session ${m} not found`);return new Promise(k=>{let b=[],S=[],x=0,R=!1,P,H,_=!1,N=()=>{_||(_=!0,clearTimeout(W),P?.(),H?.(),k(R?{entries:b,truncated:!0}:{entries:b}))};P=y.onBroadcast(Q=>{let le=Xp(Q);for(b.push(Q),S.push(le),x+=le;b.length>0&&(b.length>1e3||x>1048576);)b.shift(),x-=S.shift()??0,R=!0;g==="turn_complete"&&Q.params?.update?.sessionUpdate==="turn_complete"&&N()});let W=setTimeout(N,h);typeof W.unref=="function"&&W.unref(),H=y.onClose(()=>N())})}),a.onRequest("hydra-acp/child_session/close",async p=>{let f=p??{},m=typeof f.childSessionId=="string"?f.childSessionId:void 0;if(!m)throw M(-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=>sg(p,o.name,e)),a.onRequest("hydra-acp/attention/clear",async p=>rg(p,o.name,e)),a.onRequest("hydra-acp/connection/keep_alive",async p=>{let f=p??{},m=typeof f.token=="string"?f.token:void 0,g=typeof f.sessionId=="string"?f.sessionId:void 0,h=typeof f.estimatedRemainingMs=="number"?f.estimatedRemainingMs:void 0;return m&&g&&e.manager.get(g)?.keepAliveClaim(m,h),{ok:!0}})}a.onRequest("hydra-acp/session/tool_content",async l=>{let p=l??{};if(typeof p.sessionId!="string"||typeof p.hash!="string")throw M(C.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let f=await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,m=await e.manager.loadToolBlob(f,p.hash);if(m===null)throw M(C.SessionNotFound,"tool content not found");return{content:m}}),a.onRequest("authenticate",async l=>Zp(l,e)),a.onRequest("logout",async l=>eg(l,e)),a.onRequest("session/new",async l=>{let p=Ro.parse(l),f=ot(l?._meta),m=Array.isArray(f.transformers)&&f.transformers.every(N=>typeof N=="string")?f.transformers:e.manager.defaultTransformers??[],g=e.transformers?.resolveChain(m)??[],h,y,k=p.mcpServers;if(f.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){h=vd(32).toString("hex"),y=e.mcpTokenRegistry.reserve(h);let W={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${h}`}]};k=[...p.mcpServers??[],W]}let w,v,b=Ct(e);b!==void 0&&(k=[...k??[],...b.descriptors]);let S=Or({baselineMcpServers:p.mcpServers,stdinEnabled:f.mcpStdin===!0,deps:e}),x;try{x=await e.manager.create({cwd:p.cwd,agentId:f.agentId??e.defaultAgent,mcpServers:k,title:f.title,agentArgs:f.agentArgs,model:f.model,onInstallProgress:kd(a),transformChain:g,originatingClient:d.clientInfo,...f.interactive!==void 0?{interactive:f.interactive}:{},...f.env!==void 0?{forwardedEnv:f.env}:{},...f.workspace!==void 0?{workspace:f.workspace}:{},...S?{mintMcpServersForSwap:S}:{}})}catch(N){throw y!==void 0&&y.abandon(N instanceof Error?N:void 0),v!==void 0&&v.abandon(N instanceof Error?N:void 0),b!==void 0&&b.abandon(N instanceof Error?N:void 0),N}if(h!==void 0&&y!==void 0&&e.mcpTokenRegistry!==void 0){let N=h,W=e.mcpTokenRegistry;y.complete(x),x.onClose(()=>{W.unbind(N)})}if(w!==void 0&&v!==void 0&&e.mcpTokenRegistry!==void 0){let N=w,W=e.mcpTokenRegistry;v.complete(x),x.onClose(()=>{W.unbind(N)})}b!==void 0&&b.bindToSession(x),Ad(x.sessionId,e);let R,P;try{us(d,x,x.sessionId),R=nn(a,x,d),{entries:P}=await x.attach(R,"full")}catch(N){throw await x.close({deleteRecord:!1}).catch(()=>{}),N}d.attached.set(x.sessionId,{sessionId:x.sessionId,clientId:R.clientId,readonly:!1}),setImmediate(()=>{(async()=>{for(let N of P){if(a.isClosed())break;await a.notify(N.method,We(N.params,N.recordedAt)).catch(()=>{})}})()});let H=as(x),_=ds(x);return{sessionId:x.sessionId,...H?{modes:H}:{},..._?{models:_}:{},configOptions:x.buildConfigOptions(),_meta:cs(e.manager,x,{clientId:R.clientId})}}),a.onRequest("session/attach",async l=>{let p=Po.parse(l),f=p.clientInfo?.version;f&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,f):e.onTransformerVersion?.(o.name,f));let m=ot(p._meta),g=m.resume,h=m.readonly===!0,y=m.env;s.log.info(`session/attach sessionId=${p.sessionId} hasResumeHints=${!!g} readonly=${h}`);let k=g?p.sessionId:await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,w=e.manager.get(k);if(!w&&h){let _=await e.manager.loadFromDisk(k);if(!_)throw M(C.SessionNotFound,`session ${p.sessionId} not found`);let N=await e.manager.loadHistory(k),W=p.clientId??`cli_${Dr(8)}`;d.attached.set(_.hydraSessionId,{sessionId:_.hydraSessionId,clientId:W,readonly:!0}),s.log.info(`session/attach OK (viewer) sessionId=${_.hydraSessionId} clientId=${W} attachedCount=${d.attached.size} replayed=${N.length}`);for(let Q of N)await a.notify(Q.method,We(Q.params,Q.recordedAt)).catch(()=>{});return{sessionId:_.hydraSessionId,clientId:W,connectedClients:[W],historyPolicy:"full",replayed:N.length,_meta:og(_)}}let v=!w;if(!w){let _=await e.manager.loadFromDisk(k),N=_;if(g&&(N={..._,hydraSessionId:p.sessionId,upstreamSessionId:g.upstreamSessionId,agentId:g.agentId,cwd:_?.workspace?.path??g.cwd,...g.title!==void 0?{title:g.title}:{},...g.agentArgs!==void 0?{agentArgs:g.agentArgs}:{}}),!N)throw M(C.SessionNotFound,`session ${p.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(N.agentId,N.upstreamSessionId))throw M(C.SessionNotFound,`session ${p.sessionId} was deleted`);let W=N.originatingClient?N:{...N,originatingClient:d.clientInfo},Q=y!==void 0?{...W,forwardedEnv:y}:W;w=await is(e,{...Q,onInstallProgress:kd(a)})}us(d,w,w.sessionId);let b=nn(a,w,d,p.clientInfo,p.clientId),S=m.replayMode==="drip",{entries:x,appliedPolicy:R}=await w.attach(b,p.historyPolicy,{afterMessageId:p.afterMessageId,raw:S,...m.toolContent!==void 0?{toolContent:m.toolContent}:{}});if(d.attached.set(w.sessionId,{sessionId:w.sessionId,clientId:b.clientId,readonly:h}),y!==void 0&&await e.manager.setForwardedEnv(w.sessionId,y).catch(()=>{}),s.log.info(`session/attach OK sessionId=${w.sessionId} clientId=${b.clientId} attachedCount=${d.attached.size} requestedPolicy=${p.historyPolicy} appliedPolicy=${R} replayed=${x.length} readonly=${h}${S?" replayMode=drip":""}`),S){let _=m.dripSpeed&&m.dripSpeed>0?m.dripSpeed:1,N=750;(async()=>{let W=null;for(let Q of x){let le=typeof Q.recordedAt=="number"?Q.recordedAt:null;if(W!==null&&le!==null){let Ze=Math.min(N,Math.max(0,(le-W)/_));Ze>0&&await new Promise(sn=>setTimeout(sn,Ze))}le!==null&&(W=le);try{await a.notify(Q.method,We(Q.params,le??void 0))}catch{return}}})()}else for(let _=0;_<x.length&&!a.isClosed();_++){let N=x[_],W=a.notify(N.method,We(N.params,N.recordedAt)).catch(()=>{});(_+1)%200===0&&await W}w.replayPendingPermissions(b);let P=as(w),H=ds(w);return{sessionId:w.sessionId,clientId:b.clientId,connectedClients:w.connectedClients(b.clientId),historyPolicy:R,replayed:x.length,...P?{modes:P}:{},...H?{models:H}:{},configOptions:w.buildConfigOptions(),_meta:cs(e.manager,w,{resurrected:v})}}),a.onRequest("session/detach",async l=>{let p=Mo.parse(l),f=d.attached.get(p.sessionId);if(!f)throw M(C.SessionNotFound,"client not attached to that session");let m=e.manager.get(p.sessionId);return m?.detach(f.clientId),d.attached.delete(p.sessionId),m&&e.manager.reapIfOrphanedNonInteractive(p.sessionId),{sessionId:p.sessionId,_meta:{[ve]:{detachStatus:"detached"}}}}),a.onRequest("session/list",async l=>{let p=To.parse(l??{});return{sessions:(await e.manager.list({cwd:p.cwd})).filter(h=>h.originatingClient?.name!==$n).map(_o)}}),a.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw M(C.InternalError,"agent registry unavailable");return rt(e.registry)}),a.onRequest("hydra-acp/agents/auth_methods",async l=>{let p=l??{};if(typeof p.agentId!="string"||p.agentId.length===0)throw M(C.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 l=>{let p=$o.parse(l);u(p.sessionId,"session/prompt");let f=await md(p,e.manager,y=>{s.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${y} sessionId=${p.sessionId}`)});if(f?.fromSession!==void 0){if((f.depth??0)>3)throw s.log.warn(`session/prompt: refusing depth ${f.depth} chain from ${f.fromSession} to ${p.sessionId}`),M(C.InvalidRequest,`message chain too deep (${f.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(f.awaiting===!0&&yd(f.fromSession,p.sessionId))throw s.log.warn(`session/prompt: refusing deadlock ${f.fromSession} -> ${p.sessionId}`),M(C.InvalidRequest,`would deadlock: ${p.sessionId} is already blocked waiting on ${f.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let m=d.attached.get(p.sessionId);if(!m)throw s.log.warn(`session/prompt rejected: not attached sessionId=${p.sessionId} attachedKeys=[${[...d.attached.keys()].join(",")}]`),M(C.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 M(C.SessionNotFound,`session ${p.sessionId} not found`);s.log.info(`session/prompt auto-resurrecting cold sessionId=${p.sessionId}`),g=await is(e,y);let k=nn(a,g,d,void 0,m.clientId);await g.attach(k,"none")}let h=f?.awaiting===!0&&f.fromSession!==void 0?hd(f.fromSession,p.sessionId):void 0;try{return await g.prompt(m.clientId,p,f)}finally{h?.()}});let c=l=>{let p;try{p=pn.parse(l)}catch(g){s.log.warn(`session/cancel: invalid params: ${g.message}`);return}let f=d.attached.get(p.sessionId);if(!f)return;if(f.readonly){s.log.warn(`session/cancel dropped (readonly attachment) sessionId=${p.sessionId}`);return}let m=e.manager.get(p.sessionId);m&&m.cancel(f.clientId).catch(g=>{s.log.warn(`session/cancel for ${p.sessionId}: ${g.message}`)})};a.onNotification("session/cancel",c),a.onRequest("session/cancel",async l=>{let p=pn.parse(l);return u(p.sessionId,"session/cancel"),c(l),null}),a.onRequest("hydra-acp/prompt/cancel",async l=>{let p=No.parse(l);return u(p.sessionId,"hydra-acp/prompt/cancel"),he(e.manager,p.sessionId).cancelQueuedPrompt(p.messageId)}),a.onRequest("hydra-acp/session/force_cancel",async l=>{let p=pn.parse(l);return u(p.sessionId,"hydra-acp/session/force_cancel"),he(e.manager,p.sessionId).forceCancel()}),a.onRequest("hydra-acp/prompt/update",async l=>{let p=Oo.parse(l);return u(p.sessionId,"hydra-acp/prompt/update"),he(e.manager,p.sessionId).updateQueuedPrompt(p.messageId,p.prompt)}),a.onRequest("hydra-acp/prompt/amend",async l=>{let p=Ho.parse(l);u(p.sessionId,"hydra-acp/prompt/amend");let f=d.attached.get(p.sessionId);if(!f)throw M(C.SessionNotFound,"not attached to session");return he(e.manager,p.sessionId).amendPrompt(f.clientId,p)}),a.onRequest("session/resume",async l=>{let p=l??{},f=typeof p.sessionId=="string"?p.sessionId:void 0;if(!f)throw M(C.InvalidParams,"session/resume requires sessionId");let m=await e.manager.resolveCanonicalId(f)??f,g=e.manager.get(m);if(!g){let w=await e.manager.loadFromDisk(m);if(!w)throw M(C.SessionNotFound,`session ${f} not found in memory or on disk`);g=await is(e,w)}us(d,g,g.sessionId);let h=nn(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=as(g),k=ds(g);return{sessionId:g.sessionId,...y?{modes:y}:{},...k?{models:k}:{},configOptions:g.buildConfigOptions(),_meta:cs(e.manager,g,{clientId:h.clientId})}}),a.onRequest("session/load",async l=>{let p=l??{},f=typeof p.sessionId=="string"?p.sessionId:void 0;if(!f)throw M(C.InvalidParams,"session/load requires sessionId");let m=await e.manager.resolveCanonicalId(f)??f,g=e.manager.get(m);if(!g){let v=await e.manager.loadFromDisk(m);if(!v)throw M(C.SessionNotFound,`session ${f} not found in memory or on disk`);g=await is(e,v)}us(d,g,g.sessionId);let h=nn(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,We(v.params,v.recordedAt)).catch(()=>{})}g.replayPendingPermissions(h);let k=as(g),w=ds(g);return{sessionId:g.sessionId,...k?{modes:k}:{},...w?{models:w}:{},configOptions:g.buildConfigOptions(),_meta:cs(e.manager,g,{clientId:h.clientId})}}),a.onRequest("session/set_model",async l=>{let p=l?.sessionId;typeof p=="string"&&u(p,"session/set_model");let f=tg(l,e.manager);if(f.kind==="error")throw s.log.warn(f.logMessage),M(f.code,f.message);if(f.kind==="no_op")return s.log.warn(f.logMessage),await a.notify("session/update",{sessionId:f.sessionId,update:{sessionUpdate:"current_model_update",currentModel:f.currentModel}}).catch(()=>{}),null;s.log.info(f.logMessage);let{modelId:m}=f,g=await f.session.forwardModelChange(m,l);return f.session.applyModelChange(m),g}),a.onRequest("session/set_mode",async l=>{let p=l,f=p?.sessionId;if(typeof f=="string"&&u(f,"session/set_mode"),!p||typeof p.sessionId!="string")throw M(C.InvalidParams,"session/set_mode requires string sessionId");if(typeof p.modeId!="string")throw M(C.InvalidParams,"session/set_mode requires string modeId");let m=he(e.manager,p.sessionId),g=await m.forwardRequest("session/set_mode",l);return m.applyModeChange(p.modeId),g}),a.onRequest("session/set_config_option",async l=>{let p=l,f=y=>M(C.InvalidParams,y),m=p?.sessionId;if(typeof m=="string"&&u(m,"session/set_config_option"),!p||typeof p.sessionId!="string")throw f("session/set_config_option requires string sessionId");if(typeof p.configId!="string")throw f("session/set_config_option requires string configId");if(typeof p.value!="string")throw f("session/set_config_option requires string value");let g=he(e.manager,p.sessionId),h=g.buildConfigOptions().find(y=>y.id===p.configId);if(!h)throw f(`unknown configId ${JSON.stringify(p.configId)} for this session`);if(!h.options.some(y=>y.value===p.value))throw f(`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(l,p)=>{let f=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),m=p.startsWith("session/"),g=p.startsWith("hydra-acp/");if(!m&&!g||l===null||typeof l!="object"||f.has(p))throw M(C.MethodNotFound,`Method not found: ${p}`);let h=l.sessionId;if(typeof h!="string")throw M(C.MethodNotFound,`Method not found: ${p}`);return u(h,p),he(e.manager,h).forwardRequest(p,l)})})}async function Zp(s,e){let t=s??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw M(C.InvalidParams,"authenticate requires a non-empty methodId string");let n=t.methodId,r=t._meta?.["hydra-acp"],o=typeof r?.sessionId=="string"?r.sessionId:void 0,i=typeof r?.agentId=="string"?r.agentId:void 0,a=o!==void 0?e.manager.getAgentForSession(o):void 0;if(!a||!a.isAlive()){let f=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(f)}let d=a.authMethods??[],u=d.find(f=>f.id===n);if(!u){let f=d.map(m=>m.id);throw M(C.InvalidParams,`authenticate: methodId ${JSON.stringify(n)} is not advertised by agent ${a.agentId}; valid: [${f.map(m=>JSON.stringify(m)).join(", ")}]`)}let c=u._meta?.type,l=(()=>{let f=u._meta?.["terminal-auth"];if(f&&typeof f=="object"&&!Array.isArray(f))return f})();if((u.type??(c==="agent"||c==="terminal"?c:l!==void 0?"terminal":"agent"))==="terminal"){let f=(w,v)=>{if(!Array.isArray(w))throw M(C.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be a string[]; got ${w===null?"null":typeof w}`);for(let b of w)if(typeof b!="string")throw M(C.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be string[]; got non-string entry ${JSON.stringify(b)}`);return w},m=await e.manager.planSpawnForAgent(a.agentId),g,h;if(l?.args!==void 0){let w=typeof l.command=="string"?l.command:void 0;g=w!==void 0&&Sd.isAbsolute(w)?w:m.command,h=f(l.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?f(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 k=bd.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${n}`),{kind:"terminal",command:g,args:h,env:y,cwd:k}}try{return await a.connection.request("authenticate",{methodId:n})}catch(f){throw Ve(f,a)}}async function eg(s,e){let n=(s??{})._meta?.["hydra-acp"],r=typeof n?.sessionId=="string"?n.sessionId:void 0,o=typeof n?.agentId=="string"?n.agentId:void 0,i=r!==void 0?e.manager.getAgentForSession(r):void 0;if(!i||!i.isAlive()){let a=o??e.defaultAgent;i=await e.manager.bootstrapAgentForAuth(a)}return await i.connection.request("logout",{})}function kd(s){return e=>{let t={agentId:e.agentId,version:e.version,source:e.source,phase:e.phase};"receivedBytes"in e&&(t.receivedBytes=e.receivedBytes),"totalBytes"in e&&(t.totalBytes=e.totalBytes),"packageSpec"in e&&(t.packageSpec=e.packageSpec),s.notify(jo,t).catch(()=>{})}}function as(s){let e=s.availableModes();if(e.length===0)return;let t=e.map(r=>{let o={id:r.id,name:r.name??r.id};return r.description!==void 0&&(o.description=r.description),o});return{currentModeId:s.currentMode??e[0].id,availableModes:t}}function ds(s){let e=s.availableModels();if(e.length===0)return;let t=e.map(r=>{let o={modelId:r.modelId};return r.name!==void 0&&(o.name=r.name),r.description!==void 0&&(o.description=r.description),o});return{currentModelId:s.currentModel??e[0].modelId,availableModels:t}}function tg(s,e){if(!s||typeof s!="object")return{kind:"error",code:C.InvalidParams,message:"session/set_model requires params",logMessage:"session/set_model rejected: params not an object"};let t=s;if(typeof t.sessionId!="string")return{kind:"error",code:C.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:C.InvalidParams,message:"session/set_model requires string modelId",logMessage:`session/set_model rejected: missing/non-string modelId sessionId=${t.sessionId}`};let n=e.get(t.sessionId);if(!n)return{kind:"error",code:C.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=n.availableModels(),o=pt(t.modelId,r);if(o.kind==="none")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model passthrough (no availableModels) sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="exact")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model accepted sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="resolved")return{kind:"ok",session:n,modelId:o.modelId,logMessage:`session/set_model resolved sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} \u2192 ${JSON.stringify(o.modelId)}`};let i=r.map(d=>d.modelId).join(", "),a=o.kind==="ambiguous"?`ambiguous (trailing-segment matches [${o.candidates.join(", ")}])`:"not in availableModels";return n.currentModel!==void 0&&n.currentModel.length>0?{kind:"no_op",session:n,sessionId:t.sessionId,currentModel:n.currentModel,logMessage:`session/set_model no_op (resyncing client) sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} ${a} actual=${JSON.stringify(n.currentModel)} agentId=${n.agentId} known=[${i}]`}:{kind:"error",code:C.InvalidParams,message:`model "${t.modelId}" is ${a==="not in availableModels"?"not in this session's availableModels":a} (agent ${n.agentId}); known models: ${i}`,logMessage:`session/set_model rejected sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)} ${a} agentId=${n.agentId} known=[${i}] (no current model to fall back to)`}}async function ng(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0;if(!r)throw M(C.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw M(C.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw M(C.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return he(t.manager,r).addTransformer(o),{ok:!0}}async function sg(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw M(C.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw M(C.InvalidParams,"hydra-acp/attention/set requires string reason");return he(t.manager,r).setAttentionFlag(e,o,n.payload),{ok:!0}}async function rg(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw M(C.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw M(C.InvalidParams,"hydra-acp/attention/clear requires string reason");return he(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function og(s){let e={sessionId:s.hydraSessionId,upstreamSessionId:s.upstreamSessionId,cwd:s.cwd,workspace:s.workspace,title:s.title,agentId:s.agentId,currentModel:s.currentModel,currentUsage:qt(s.currentUsage),forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,updatedAt:s.createdAt??new Date().toISOString(),attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1},t={currentMode:s.currentMode,agentArgs:s.agentArgs,availableCommands:s.agentCommands,availableModes:s.agentModes,availableModels:s.agentModels};return{[ve]:fn(e,t)}}function cs(s,e,t={}){let n=s.liveListEntry(e),r={clientId:t.clientId,currentMode:e.currentMode,agentArgs:e.agentArgs,availableCommands:e.mergedAvailableCommands(),availableModes:e.availableModes(),availableModels:e.availableModels(),turnStartedAt:e.turnStartedAt,agentCapabilities:e.agentCapabilities,queue:e.queueSnapshot(),...t.resurrected===!0?{resurrected:!0}:{}};return Tt(e.agentMeta,fn(n,r))}function ig(){return{protocolVersion:1,agentInfo:{name:"hydra",version:ie},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:Tt(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 ag(s,e){if(!(!e.transformers||!e.manager))for(let t of e.manager.defaultTransformers){let n=e.transformers.resolveChain([t])[0];n&&s.addTransformer(n)}}function Ad(s,e){if(!e.transformers)return;let t=e.transformers.interestedIn("lifecycle:session.starting");for(let n of t)n.connection.notify("hydra-acp/transformer/session_event",{event:"session.starting",sessionId:s}).catch(()=>{})}function nn(s,e,t,n,r){return{clientId:r??`cli_${Dr(8)}`,connection:s,clientInfo:n}}function us(s,e,t){let n=s.attached.get(t);n&&(e.detach(n.clientId),s.attached.delete(t))}var ls=class{byToken=new Map;reserve(e){if(this.byToken.has(e))throw new Error("mcp token already bound");let t,n,r=new Promise((i,a)=>{t=i,n=a});r.catch(()=>{});let o={session:void 0,sessionReady:r,disposers:[]};return this.byToken.set(e,o),{complete:i=>{o.session=i,t(i)},abandon:i=>{this.byToken.delete(e),n(i??new Error("mcp token reservation abandoned"))}}}bind(e,t){let{complete:n}=this.reserve(e);n(t)}lookup(e){return this.byToken.get(e)}addDisposer(e,t){let n=this.byToken.get(e);n!==void 0&&n.disposers.push(t)}async unbind(e){let t=this.byToken.get(e);if(t!==void 0){this.byToken.delete(e);for(let n of t.disposers)try{await n()}catch{}}}size(){return this.byToken.size}};import{randomUUID as dg}from"crypto";import{McpServer as cg}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as ug}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as ae}from"zod";function Lr(s){if(s.method!=="session/update")return null;let t=s.params?.update;return!t||typeof t.sessionUpdate!="string"?null:{kind:t.sessionUpdate,update:t}}function ue(s){return{content:[{type:"text",text:JSON.stringify(s)}],structuredContent:s}}var Cd="Bearer ";function Et(s){let e=s.headers.authorization;if(typeof e!="string"||!e.startsWith(Cd))return;let t=e.slice(Cd.length).trim();return t.length>0?t:void 0}function lg(s){let e=new cg({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:ae.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let n=s.streamTail(t);return ue(n)}),e.registerTool("head",{description:"Return the first `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means the head has already been evicted from the ring and the returned bytes start at the oldest still-resident cursor.",inputSchema:{bytes:ae.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let n=s.streamHead(t);return ue(n)}),e.registerTool("read",{description:"Read up to `max_bytes` bytes starting at absolute byte `cursor`. Returns `{bytes, nextCursor, gap?, eof?}` \u2014 `gap` is the number of bytes silently skipped because the ring had evicted them; `eof:true` means the producer closed and there is nothing left to read.",inputSchema:{cursor:ae.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:ae.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:ae.number().int().min(0).optional().describe("If no bytes are available, block up to this many ms for more (capped server-side at 60_000).")}},async({cursor:t,max_bytes:n,wait_ms:r})=>{let o=await s.streamRead(t,n,r);return ue(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:ae.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:ae.number().int().min(0).describe("Maximum ms to block (server caps at 60_000).")}},async({cursor:t,timeout_ms:n})=>{let r=await s.streamWaitFor(t,n),o=s.streamInfo();return ue({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:ae.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:ae.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:ae.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:ae.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:ae.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:ae.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:ae.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:ae.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:ae.number().int().min(0).optional().describe("Optional absolute byte offset to start scanning from. Omit to scan from the oldest still-resident byte. Pass the `nextCursor` from a previous truncated call to resume.")}},async t=>{let n={pattern:t.pattern};t.regex!==void 0&&(n.regex=t.regex),t.case_insensitive!==void 0&&(n.caseInsensitive=t.case_insensitive),t.invert!==void 0&&(n.invert=t.invert),t.max_matches!==void 0&&(n.maxMatches=t.max_matches),t.max_bytes!==void 0&&(n.maxBytes=t.max_bytes),t.context_before!==void 0&&(n.contextBefore=t.context_before),t.context_after!==void 0&&(n.contextAfter=t.context_after),t.cursor!==void 0&&(n.cursor=t.cursor);let r=s.streamGrep(n);return ue(r)}),e.registerTool("info",{description:"Report cursor / capacity / closed state of the stdin ring. Cheap; safe to call repeatedly.",inputSchema:{}},async()=>{let t=s.streamInfo();return ue(t)}),e}var fg=1e4;function xd(s,e){let t=new Map;async function n(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let u=lg(a),c=new ug({sessionIdGenerator:()=>dg()});await u.connect(c);let l={server:u,transport:c};return t.set(i,l),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=Et(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,f=new Promise(g=>{p=setTimeout(()=>g(void 0),fg)}),m=await Promise.race([u.sessionReady.catch(()=>{}),f]);if(p!==void 0&&clearTimeout(p),m===void 0){a.code(503).send({error:"session not ready"});return}c=m}let l=await n(d,c);a.hijack(),await l.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),s.get("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)}),s.delete("/mcp/hydra-acp-stdin",o,async(i,a)=>{await r(i,a)})}import{randomUUID as pg}from"crypto";import{McpServer as gg}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as mg}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as $e}from"zod";function hg(s){switch(s){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}var Rd=2e3,Ed=2e4;function yg(s,e,t){if(e!=="tool_call"&&e!=="tool_call_update")return gt([s]);let n=[],r=$t(t);r!==void 0?n.push(`Tool: ${r}`):typeof t.title=="string"&&t.title.length>0&&n.push(`Tool: ${t.title}`);let o=t.rawInput;if(o&&typeof o=="object"&&!Array.isArray(o))for(let[a,d]of Object.entries(o))typeof d=="string"&&d.length>0&&n.push(`${a}=${d}`);if(Array.isArray(t.locations))for(let a of t.locations)typeof a?.path=="string"&&a.path.length>0&&n.push(a.path);let i=yn(t);return i!==void 0&&n.push(i),n.join(`
189
+ `)}function wg(s,e){if(s.length<=148)return s;let r=Math.floor(148/2),o=e-r;o<0&&(o=0);let i=o+148;i>s.length&&(o=s.length-148,o<0&&(o=0));let a=s.slice(o,i);return o>0&&(a="\u2026"+a),i<s.length&&(a=a+"\u2026"),a}function kg(s){let e=new gg({name:"hydra-acp-recall",version:"1.0.0"},{instructions:"Search and retrieve detail from this session's pre-compaction history. After a compaction summary replaces earlier conversation in working memory, these tools let you page back specifics on demand. Use `search` to find entries by keyword, `range` to pull a contiguous slice verbatim, and `tool_calls` to enumerate prior tool invocations. These tools only return results once the session has been compacted at least once."});return e.registerTool("search",{description:"Search this session's prior conversation history (the part that was compacted out of your working memory) by keyword. Covers assistant and user messages, the arguments of every tool call including full shell commands, and what those calls printed. Returns matching entry ids with short snippets so you can decide which to pull in full via `range`. Use this when the compaction summary mentions something but you need the verbatim detail.",inputSchema:{query:$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:n=10,include_tool_calls:r=!0})=>{let o=await s();if(!o.summarizedThroughEntry||o.summarizedThroughEntry===0)return ue({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 l=Lr(c);if(!l)continue;let{kind:p,update:f}=l;if((p==="tool_call"||p==="tool_call_update")&&!r)continue;let m=yg(c,p,f),g=m.toLowerCase().indexOf(a);if(g<0)continue;let h=hg(p),y=wg(m,g),k=typeof c.recordedAt=="number"?String(c.recordedAt):void 0;if(i.push({entryId:u,speaker:h,snippet:y,timestamp:k}),i.length>=n)break}i.sort((u,c)=>u.entryId-c.entryId);let d=i.length>=n;return ue({matches:i,total_matched:i.length,truncated:d})}),e.registerTool("range",{description:"Pull a contiguous range of prior conversation entries verbatim from this session's pre-compaction history, including each tool call's arguments and what it printed. Use after `search` narrows in on what you need. Capped at 50 entries per call.",inputSchema:{from_entry:$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:n})=>{let r=await s();if(!r.summarizedThroughEntry||r.summarizedThroughEntry===0)return ue({text:"",entry_count:0,truncated:!1,note:"This session has no compacted history. `range` retrieves verbatim entries from the pre-compaction transcript; nothing has been compacted yet."});if(n<t)throw new Error(`range: to_entry (${n}) must be >= from_entry (${t})`);let o=n-t+1;if(o>50)throw new Error(`range: range size (${o}) exceeds maximum of 50 entries`);let i=await r.getRecallTotalCount();if(i===0)return ue({text:"",entry_count:0,truncated:!1});let a=Math.min(t,i-1),d=Math.min(n,i-1),u=a>t||d<n;if(a>d)return{content:[{type:"text",text:""}],structuredContent:{text:"",entry_count:0,truncated:u}};let c=await r.sliceRecallHistory(a,d),l=gt(c,{toolOutput:{maxPerCall:Rd,maxTotal:Ed}});return{content:[{type:"text",text:l}],structuredContent:{text:l,entry_count:c.length,truncated:u}}}),e.registerTool("tool_calls",{description:"Search this session's prior tool invocations by tool name, ACP kind, and/or file path. Returns when each tool was called, its arguments (including the full shell command), the result status, and what the call printed. Use this to recall which files were read/edited, what shell commands ran, and what they output.",inputSchema:{tool_name:$e.string().optional().describe("Case-insensitive substring of the tool name. Names vary by agent for the same tool (Bash, Terminal, bash), so prefer `kind` when you want every shell invocation."),kind:$e.string().optional().describe("ACP tool kind: execute (shell), read, edit, think, other. Agent-independent, unlike tool_name."),file_path:$e.string().optional(),limit:$e.number().int().min(1).max(100).optional(),include_output:$e.boolean().optional().describe("Include what each call printed (default true). Set false when you only need the commands and not their results.")}},async({tool_name:t,kind:n,file_path:r,limit:o=20,include_output:i=!0})=>{let a=await s();if(!a.summarizedThroughEntry||a.summarizedThroughEntry===0)return ue({calls:[],truncated:!1,note:"This session has no compacted history. `tool_calls` retrieves tool invocations from the pre-compaction transcript; nothing has been compacted yet."});let d=typeof t=="string"&&t.length>0,u=typeof n=="string"&&n.length>0,c=typeof r=="string"&&r.length>0;if(!d&&!u&&!c)throw new Error("tool_calls: at least one of tool_name, kind, or file_path must be provided");let l=new Map,p=Math.max(o*4,200);for await(let{entryId:k,entry:w}of a.iterRecallNewestFirst()){let v=Lr(w);if(!v)continue;let{kind:b,update:S}=v;if(b!=="tool_call"&&b!=="tool_call_update")continue;let x=typeof S.toolCallId=="string"&&S.toolCallId.length>0?S.toolCallId:`__noid_${k}`,R=l.get(x);if(R||(R={entryId:k,toolName:"(unnamed)",nameAuthoritative:!1,rawInput:{},locations:[],status:"in_progress"},l.set(x,R)),k<R.entryId&&(R.entryId=k),!R.nameAuthoritative){let H=$t(S);H!==void 0?(R.toolName=H,R.nameAuthoritative=!0):typeof S.name=="string"&&S.name.length>0?(R.toolName=S.name,R.nameAuthoritative=!0):b==="tool_call"&&typeof S.title=="string"&&S.title.length>0&&(R.toolName=S.title,R.nameAuthoritative=!0)}if(R.kind===void 0&&typeof S.kind=="string"&&S.kind.length>0&&(R.kind=S.kind),R.output===void 0){let H=yn(S);H!==void 0&&(R.output=H)}let P=S.rawInput;if(P&&typeof P=="object"&&!Array.isArray(P)&&Object.keys(P).length>0)for(let[H,_]of Object.entries(P))R.rawInput[H]===void 0&&(R.rawInput[H]=_);if(Array.isArray(S.locations))for(let H of S.locations){let _=H?.path;typeof _=="string"&&_.length>0&&!R.locations.includes(_)&&R.locations.push(_)}if(typeof S.status=="string"&&R.status==="in_progress"&&(R.status=S.status),w.recordedAt!==void 0&&R.timestamp===void 0&&(R.timestamp=String(w.recordedAt)),l.size>=p)break}let f=[...l.keys()].sort((k,w)=>l.get(k).entryId-l.get(w).entryId),m=[],g=Ed,h=!1;for(let k of f){let w=l.get(k);if(w.toolName=Ds({name:w.toolName,rawInput:w.rawInput,...w.kind!==void 0?{kind:w.kind}:{}}),d&&!w.toolName.toLowerCase().includes(t.toLowerCase())||u&&(w.kind??"").toLowerCase()!==n.toLowerCase())continue;if(c){let S=r.toLowerCase(),x=["file_path","filePath","path"],R=!1;for(let P of x){let H=w.rawInput[P];if(typeof H=="string"&&H.toLowerCase().includes(S)){R=!0;break}}if(!R){for(let P of w.locations)if(P.toLowerCase().includes(S)){R=!0;break}}if(!R)continue}let v={};for(let[S,x]of Object.entries(w.rawInput))typeof x=="string"?v[S]=x.length>500?x.slice(0,497)+"\u2026":x:(typeof x=="number"||typeof x=="boolean")&&(v[S]=x);w.locations.length>0&&v.locations===void 0&&(v.locations=w.locations);let b={entryId:w.entryId,tool:w.toolName,args:v,status:w.status,timestamp:w.timestamp};if(w.kind!==void 0&&(b.kind=w.kind),i&&w.output!==void 0){let S=w.output,x=Math.min(Rd,g);if(x<=0)h=!0;else{let R=S.length<=x?S:S.slice(0,x-1)+"\u2026";b.output=R,b.outputBytes=S.length,b.outputTruncated=R.length<S.length,g-=R.length}}if(m.push(b),m.length>=o)break}let y=m.length>=o;return ue({calls:m,truncated:y,...h?{outputBudgetExhausted:h}:{}})}),e}var vg=1e4;function Pd(s,e){let t=new Map;async function n(i,a){let d=t.get(i);if(d!==void 0)return d.transport;let u=kg(a),c=new mg({sessionIdGenerator:()=>pg()});await u.connect(c);let l={server:u,transport:c};return t.set(i,l),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=Et(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 l=await n(d,async()=>{if(u.session!==void 0)return u.session;let p,f=new Promise(g=>{p=setTimeout(()=>g(void 0),vg)}),m=await Promise.race([u.sessionReady.catch(()=>{}),f]);if(p!==void 0&&clearTimeout(p),m===void 0)throw new Error("recall: session not ready");return m});a.hijack(),await l.handleRequest(i.raw,a.raw,i.body)}let o={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),s.get("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)}),s.delete("/mcp/hydra-acp-recall",o,async(i,a)=>{await r(i,a)})}var fs=class{byName=new Map;changeHandlers=[];register(e,t,n,r){this.byName.set(e,{connection:t,instructions:n,tools:[...r]}),this.fireChanged(e,"register")}clear(e){this.byName.delete(e)&&this.fireChanged(e,"clear")}lookup(e){return this.byName.get(e)}list(){return Array.from(this.byName.keys())}onChange(e){return this.changeHandlers.push(e),()=>{let t=this.changeHandlers.indexOf(e);t>=0&&this.changeHandlers.splice(t,1)}}fireChanged(e,t){for(let n of this.changeHandlers)try{n(e,t)}catch{}}};import{StreamableHTTPServerTransport as Eg}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as Pg}from"crypto";import{Server as bg}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as Sg,ListToolsRequestSchema as Ig}from"@modelcontextprotocol/sdk/types.js";function Md(s,e,t,n){let r=typeof t=="function"?async()=>t():async()=>t,o=new bg({name:s,version:"1.0.0"},{capabilities:{tools:{listChanged:!0}},...e.instructions!==void 0?{instructions:e.instructions}:{}}),i=a=>({name:a.name,description:a.description,inputSchema:a.inputSchema,...a.outputSchema!==void 0?{outputSchema:a.outputSchema}:{}});return o.setRequestHandler(Ig,async()=>{let a=n?.peekSessionId?.();if(a!==void 0&&n?.fetchSessionTools!==void 0)try{let d=await n.fetchSessionTools(a);if(d!==void 0)return{tools:d.map(i)}}catch{}return{tools:e.tools.map(i)}}),o.setRequestHandler(Sg,async(a,d)=>{let u=a.params.name,c=d._meta?.progressToken??d.requestId,l=Cg(c,d.sendNotification);try{let p=await r(),f=await xg(e.connection,s,u,a.params.arguments??{},p);return Rg(f,u)}catch(p){return Br(p instanceof Error?p.message:String(p))}finally{l()}}),o}var Ag=15e3;function Cg(s,e,t=Ag){if(s===void 0)return()=>{};let n=0,r=setInterval(()=>{n+=1,e({method:"notifications/progress",params:{progressToken:s,progress:n}}).catch(()=>{})},t);return r.unref?.(),()=>clearInterval(r)}async function xg(s,e,t,n,r){return await s.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:n,sessionId:r})}function Rg(s,e){if(s===null||typeof s!="object")return Br(`extension ${e} returned non-object`);let t=s;return Array.isArray(t.content)?t:Br(`extension ${e} omitted content array`)}function Br(s){return{content:[{type:"text",text:s}],isError:!0}}var Mg=1e4;function Td(s,e,t){let n=new Map;async function r(c){try{await c.transport.close()}catch{}try{await c.server.close()}catch{}}function o(c){for(let l of n.values()){let p=l.get(c);p!==void 0&&(l.delete(c),r(p))}}async function i(c,l){for(let[p,f]of n){if(e.lookup(p)?.session?.sessionId!==c)continue;let g=f.get(l);if(g!==void 0)try{await g.server.sendToolListChanged()}catch{}}}t.onChange(c=>{o(c)});async function a(c,l){let p=n.get(c);p===void 0&&(p=new Map,n.set(c,p),e.addDisposer(c,async()=>{let v=n.get(c);if(v!==void 0){n.delete(c);for(let b of v.values())await r(b)}}));let f=p.get(l);if(f!==void 0)return f.transport;let m=t.lookup(l);if(m===void 0)return;let k=Md(l,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 b,S=new Promise(R=>{b=setTimeout(()=>R(void 0),Mg)}),x=await Promise.race([v.sessionReady.catch(()=>{}),S]);if(b!==void 0&&clearTimeout(b),x===void 0)throw new Error("session not ready");return x.sessionId},{peekSessionId:()=>e.lookup(c)?.session?.sessionId,fetchSessionTools:async v=>{let b=await m.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:v});if(!b||typeof b!="object")return;let S=b.tools;if(!Array.isArray(S))return;let x=[];for(let R of S){if(!R||typeof R!="object")continue;let P=R;if(typeof P.name!="string"||P.name.length===0||typeof P.description!="string"||P.inputSchema===null||typeof P.inputSchema!="object")continue;let H={name:P.name,description:P.description,inputSchema:P.inputSchema};P.outputSchema!==null&&typeof P.outputSchema=="object"&&(H.outputSchema=P.outputSchema),x.push(H)}return x}}),w=new Eg({sessionIdGenerator:()=>Pg()});return await k.connect(w),p.set(l,{server:k,transport:w}),w}async function d(c,l){let p=Et(c);if(p===void 0){l.code(401).send({error:"missing bearer token"});return}if(e.lookup(p)===void 0){l.code(404).send({error:"unknown mcp token"});return}let m=c.params.name,g=await a(p,m);if(g===void 0){l.code(404).send({error:`unknown mcp server: ${m}`});return}l.hijack(),await g.handleRequest(c.raw,l.raw,c.body)}let u={config:{skipAuth:!0}};return s.post("/mcp/:name",u,async(c,l)=>{await d(c,l)}),s.get("/mcp/:name",u,async(c,l)=>{await d(c,l)}),s.delete("/mcp/:name",u,async(c,l)=>{await d(c,l)}),{notifyToolListChanged:i}}async function Hd(s,e){Hg(s),io(s.daemon.scrubEnv);let t=s.daemon.tls?await Fe.readFile(de(s.daemon.tls.key)):void 0,n=s.daemon.tls?await Fe.readFile(de(s.daemon.tls.cert)):void 0;await Fe.mkdir(A.home(),{recursive:!0});let{stream:r,fileStream:o}=await Ng(s.daemon.logLevel),i=Tg({logger:{level:s.daemon.logLevel,stream:r},bodyLimit:256*1024*1024});await i.register(_g,{options:{handleProtocols:so}}),xs(D=>{i.log.info(D)}),Ps(D=>{i.log.info(D)});let a=await Vn.load(),d=new Xn,u=new Yn,c=new Gn([new Qn(e),new Kn(a),u]),l=Pa({validator:c});i.addHook("onRequest",async(D,Ie)=>{D.routeOptions.config?.skipAuth||D.url==="/acp"||D.url?.startsWith("/acp?")||await l(D,Ie)});let p=setInterval(()=>{a.sweepExpired()},300*1e3);p.unref();let f=setInterval(()=>{d.sweepExpired()},300*1e3);f.unref();let m=new un(s,{onFetched:()=>{ka(m,k)}});Pr(D=>i.log.info(D));let g={info:D=>i.log.info(D),warn:D=>i.log.warn(D)},h=D=>ze.spawn({...D,stderrTailBytes:s.daemon.agentStderrTailBytes,logger:g});lo(s.compressToolContent);let y=new zn,k=new jn(m,h,void 0,{idleTimeoutMs:s.daemon.sessionIdleTimeoutSeconds*1e3,defaultModels:s.defaultModels,synopsisAgent:s.synopsisAgent,synopsisModel:s.synopsisModel,compactionAgent:s.compaction?.agent,compactionModel:s.compaction?.model,defaultTransformers:s.defaultTransformers,sessionHistoryMaxEntries:s.daemon.sessionHistoryMaxEntries,sessionHistoryArchiveMaxBytes:s.daemon.sessionHistoryArchiveMaxBytes,sessionHistoryArchiveTiers:s.daemon.sessionHistoryArchiveTiers,logger:g,npmRegistry:s.npmRegistry,extensionCommands:y,defaultCwd:s.defaultCwd,disableWorkspaceSnapshots:s.disableWorkspaceSnapshots}),w=new Wn(Zr(s),void 0,{tokenRegistry:u}),v=new qn(eo(s),void 0,{tokenRegistry:u});od(i,ie,Sa(s));let b=new ls,S=new fs,x,R=()=>{if(x!==void 0)return x;let D=i.server.address();return x=`http://127.0.0.1:${D&&typeof D=="object"?D.port:s.daemon.port}`,x};sd(i,k,{agentId:s.defaultAgent,cwd:s.defaultCwd,publicHost:s.daemon.publicHost,host:s.daemon.host,port:s.daemon.port,compaction:s.compaction},{extensionMcp:S,mcpTokenRegistry:b,getDaemonOrigin:R}),rd(i,m,k,{npmRegistry:s.npmRegistry}),id(i,w),ad(i,v),dd(i,{defaultAgent:s.defaultAgent,defaultCwd:s.defaultCwd,defaultModels:{...s.defaultModels},...s.synopsisAgent!==void 0?{synopsisAgent:s.synopsisAgent}:{},...s.synopsisModel!==void 0?{synopsisModel:s.synopsisModel}:{},defaultTransformers:[...s.defaultTransformers]}),pd(i,{store:a,rateLimiter:d}),xd(i,b),Pd(i,b);let P=Td(i,b,S);Id(i,{validator:c,manager:k,defaultAgent:s.defaultAgent,processRegistry:u,onExtensionVersion:(D,Ie)=>w.reportVersion(D,Ie),onTransformerVersion:(D,Ie)=>v.reportVersion(D,Ie),transformers:v,extensionCommands:y,mcpTokenRegistry:b,extensionMcp:S,extensionMcpControls:P,getDaemonOrigin:R,registry:m});let H=!!s.daemon.tls;await i.listen({host:H?"127.0.0.1":s.daemon.host,port:H?0:s.daemon.port});let _=i.server.address(),N=_&&typeof _=="object"?_.port:s.daemon.port,W,Q=s.daemon.host,le=N;if(H&&t&&n){W=Og({listenHost:s.daemon.host,listenPort:s.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:N,tlsOptions:{key:t,cert:n},logger:i.log});let D=W.address();D&&typeof D=="object"&&(le=D.port)}await Fe.mkdir(A.home(),{recursive:!0}),await wa({pid:process.pid,host:Q,port:le,loopbackPort:N,startedAt:new Date().toISOString()});let Ze={daemonUrl:`http://127.0.0.1:${N}`,daemonHost:"127.0.0.1",daemonPort:N,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${N}/acp`,hydraHome:A.home()};w.setContext(Ze),v.setContext(Ze),await w.start(),await v.start();try{await k.reconcilePermissionFlags()}catch(D){i.log.warn(`permission flag reconcile failed: ${D.message}`)}k.resurrectPendingQueues().catch(D=>{i.log.warn(`queue replay scan failed: ${D.message}`)}),k.resumePendingCompactions().catch(D=>{i.log.warn(`compaction resume scan failed: ${D.message}`)}),k.resumePendingAgentSwaps().catch(D=>{i.log.warn(`agent-swap resume scan failed: ${D.message}`)});let sn=s.daemon.agentSyncIntervalMinutes*60*1e3,qr=sn>0?va({registry:m,manager:k,intervalMs:sn,logger:g}):void 0,zr=s.daemon.sessionGcIntervalMinutes*60*1e3,Qd=s.daemon.sessionGcMaxAgeDays*24*60*60*1e3,Jr=zr>0?ba({manager:k,intervalMs:zr,maxAgeMs:Qd,logger:g}):void 0;return{app:i,manager:k,registry:m,extensions:w,transformers:v,mcpTokenRegistry:b,extensionMcp:S,processRegistry:u,shutdown:async()=>{Jr&&Jr(),qr&&qr(),clearInterval(p),clearInterval(f);let D=async(Ie,Kd)=>{try{await Kd()}catch(gs){i.log.warn(`shutdown step ${Ie} failed: ${gs instanceof Error?gs.message:String(gs)}`)}};await D("sessionTokenStore.flush",()=>a.flush()),await D("extensions.stop",()=>w.stop()),await D("transformers.stop",()=>v.stop()),await D("manager.closeAll",()=>k.closeAll()),await D("manager.flushSynopsis",()=>k.flushSynopsis(3e4)),await D("manager.shutdownSynopsis",()=>k.shutdownSynopsis()),await D("manager.flushMetaWrites",()=>k.flushMetaWrites()),await D("manager.flushHistoryWrites",()=>k.flushHistoryWrites()),xs(null),Ps(null),Pr(null),W&&await D("tlsTerminator.close",()=>new Promise(Ie=>W.close(()=>Ie()))),await D("app.close",()=>i.close());try{Fd.unlinkSync(A.pidFile())}catch{}await D("fileStream.flushSync",()=>o.flushSync())}}}var $d=20;async function Fg(s,e){let t=Pt.dirname(s),n=Pt.basename(s,".log"),r=new RegExp(`^${n}\\.(\\d+)\\.log$`),o;try{o=await Fe.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=>Fe.unlink(Pt.join(t,d.name))))}async function Ng(s){await Fg(A.logFile(),$d);let e=await $g({file:A.logFile(),size:"10m",mkdir:!0,symlink:!0,limit:{count:$d,removeOtherLogFiles:!0}}),t=_d.destination(2);return{stream:_d.multistream([{stream:e,level:s},{stream:t,level:s}]),fileStream:e}}function Og(s){let e=Od.createServer(s.tlsOptions,t=>{let n=Nd.connect({host:s.upstreamHost,port:s.upstreamPort}),r=!1,o=i=>{if(!r){r=!0,i&&s.logger.warn(`tls terminator forwarder error: ${i.message??String(i)}`);try{t.destroy()}catch{}try{n.destroy()}catch{}}};t.on("error",o),n.on("error",o),t.on("close",()=>o()),n.on("close",()=>o()),t.pipe(n),n.pipe(t)});return e.on("tlsClientError",t=>{s.logger.warn(`tls handshake error: ${t.message}`)}),e.listen({host:s.listenHost,port:s.listenPort}),e}function Hg(s){let e=s.daemon.host;if(!(e==="127.0.0.1"||e==="::1"||e==="localhost"||e==="[::1]")&&!s.daemon.tls)throw new Error(`Refusing to bind to non-loopback host ${e} without TLS configured.`)}async function Xg(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:s}=await Promise.resolve().then(()=>(Vd(),Jd));s();let e=await vs(),t=await Vr(),n=await Hd(e,t);process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
150
190
  `);let r=1e4,o=!1,i=async()=>{o&&(process.stderr.write(`Second signal received; exiting immediately.
151
191
  `),process.exit(1)),o=!0,process.stdout.write(`Shutting down...
152
192
  `);let a=setTimeout(()=>{process.stderr.write(`Graceful shutdown did not complete within ${r}ms; forcing exit.
153
- `),process.exit(1)},r);a.unref();try{await s.shutdown()}catch(d){process.stderr.write(`shutdown failed: ${d instanceof Error?d.message:String(d)}
154
- `)}clearTimeout(a),process.exit(0)};process.on("SIGINT",()=>{i()}),process.on("SIGTERM",()=>{i()}),process.on("SIGHUP",()=>{})}lp().catch(n=>{process.stderr.write(`hydra-acp-daemon: ${n instanceof Error?n.message:String(n)}
193
+ `),process.exit(1)},r);a.unref();try{await n.shutdown()}catch(d){process.stderr.write(`shutdown failed: ${d instanceof Error?d.message:String(d)}
194
+ `)}clearTimeout(a),process.exit(0)};process.on("SIGINT",()=>{i()}),process.on("SIGTERM",()=>{i()}),process.on("SIGHUP",()=>{})}Xg().catch(s=>{process.stderr.write(`hydra-acp-daemon: ${s instanceof Error?s.message:String(s)}
155
195
  `),process.exit(1)});