@hydra-acp/cli 0.1.216 → 0.1.218

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,67 +1,73 @@
1
1
  #!/usr/bin/env node
2
- var $l=Object.defineProperty;var is=(s,e)=>()=>(s&&(e=s(s=0)),e);var Ol=(s,e)=>{for(var t in e)$l(s,t,{get:e[t],enumerable:!0})};import*as B from"path";import*as Pr from"os";function O(s,e=Pr.homedir()){return process.platform==="win32"||!e?s:s===e?"~":s.startsWith(e+"/")?"~"+s.slice(e.length):s}function as(s){return process.platform!=="win32"||!/^(?:[a-zA-Z]:[\\/]|[\\/]{2}[^\\/])/.test(s)?s:B.win32.resolve(s)}function ds(s){if(process.platform==="win32"){let e=B.win32.normalize(s).toLowerCase();return e.length>3?e.replace(/\\+$/,""):e}return s.length>1?s.replace(/\/+$/,""):s}function Fl(){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 Nl(s,e){_i||B.isAbsolute(s)||(_i=!0,process.stderr.write(`hydra-acp: ${$i} is relative (${JSON.stringify(s)}); resolved against the current directory to ${e}. Processes started from elsewhere will use a different home and will not see each other's daemon. Set an absolute path.
3
- `))}function q(){let s=process.env[$i];if(s&&s.length>0){let t=B.resolve(s);return Nl(s,t),t}let e=Fl();if(e)throw new Error(`HYDRA_ACP_HOME is unset under a test runner (${e}); refusing to fall back to ~/.hydra-acp. The harness must set HYDRA_ACP_HOME \u2014 vitest.setup.ts does this, but \`bun test\` bypasses the vitest config and does not. Run the suite with \`npx vitest run\`, not \`bun test\`.`);return B.join(Pr.homedir(),".hydra-acp")}var $i,_i,E,Q=is(()=>{"use strict";$i="HYDRA_ACP_HOME";_i=!1;E={home:q,config:()=>B.join(q(),"config.json"),authToken:()=>B.join(q(),"auth-token"),remotes:()=>B.join(q(),"remotes.json"),peers:()=>B.join(q(),"peers.json"),tlsDir:()=>B.join(q(),"tls"),pidFile:()=>B.join(q(),"daemon.pid"),logFile:()=>B.join(q(),"daemon.log"),daemonBootLog:()=>B.join(q(),"daemon-boot.log"),currentLogFile:()=>B.join(q(),"current.log"),registryCache:()=>B.join(q(),"registry.json"),themesDir:()=>B.join(q(),"themes"),ttySessionDir:()=>B.join(q(),"tty"),ttySessionFile:s=>B.join(q(),"tty",s),agentsDir:()=>B.join(q(),"agents"),agentLogFile:s=>B.join(q(),"agents","logs",`${s}.log`),agentInstallDir:(s,e,t)=>B.join(q(),"agents",e,s,t),agentNpmInstallDir:(s,e,t)=>B.join(q(),"agents",e,s,t,`node${process.versions.modules}`),sessionsDir:()=>B.join(q(),"sessions"),sessionDir:s=>B.join(q(),"sessions",s),sessionFile:s=>B.join(q(),"sessions",s,"meta.json"),historyFile:s=>B.join(q(),"sessions",s,"history.jsonl"),historyArchiveFile:(s,e)=>B.join(q(),"sessions",s,`history.jsonl.${e}`),toolsDir:s=>B.join(q(),"sessions",s,"tools"),toolBlobFile:(s,e)=>B.join(q(),"sessions",s,"tools",e),queueFile:s=>B.join(q(),"sessions",s,"queue.ndjson"),tombstonesDir:()=>B.join(q(),"sessions",".tombstones"),tombstoneAgentDir:s=>B.join(q(),"sessions",".tombstones",encodeURIComponent(s)),tombstoneFile:(s,e)=>B.join(q(),"sessions",".tombstones",encodeURIComponent(s),encodeURIComponent(e)),extensionsDir:()=>B.join(q(),"extensions"),extensionLogDir:s=>B.join(q(),"extensions",s),extensionLogFile:s=>B.join(q(),"extensions",s,"current.log"),extensionPidFile:s=>B.join(q(),"extensions",s,"extension.pid"),transformersDir:()=>B.join(q(),"transformers"),transformerLogDir:s=>B.join(q(),"transformers",s),transformerLogFile:s=>B.join(q(),"transformers",s,"current.log"),transformerPidFile:s=>B.join(q(),"transformers",s,"transformer.pid"),transformerState:(s,e)=>B.join(q(),"sessions",s,"transformer-state",e),tuiHistoryFile:s=>B.join(q(),"sessions",s,"prompt-history"),globalTuiHistoryFile:()=>B.join(q(),"prompt-history"),tuiLogFile:()=>B.join(q(),"tui.log"),shimWireLogFile:()=>B.join(q(),"shim-wire.log")}});import*as ge from"fs/promises";import*as Fi from"fs";import*as Pe from"path";import{randomBytes as Hl}from"crypto";async function me(s,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
4
- `;await Bl(s,r,t)}async function Ll(s,e,t={}){let n=t.rename??ge.rename,r=t.platform??process.platform,o=t.sleep??(i=>new Promise(a=>setTimeout(a,i)));for(let i=0;;i++)try{await n(s,e);return}catch(a){let d=a.code??"";if(!(r==="win32"&&jl.has(d)&&i<Ul-1))throw a;await o(10*(i+1))}}async function Bl(s,e,t={}){let n=await Wl(s),r=Pe.dirname(n);await ge.mkdir(r,{recursive:!0});let o=`${n}.tmp-${process.pid}-${ql()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await ge.writeFile(o,e,i),await Ll(o,n)}catch(i){throw await ge.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{Fi.chmodSync(n,t.mode)}catch{}}async function Wl(s){let e;try{e=await ge.lstat(s)}catch(r){if(r.code==="ENOENT")return s;throw r}if(!e.isSymbolicLink())return s;let t=await ge.readlink(s),n=Pe.isAbsolute(t)?t:Pe.resolve(Pe.dirname(s),t);try{let r=await ge.realpath(Pe.dirname(n));return Pe.join(r,Pe.basename(n))}catch(r){if(r.code==="ENOENT")return n;throw r}}async function ce(s){let e;try{e=await ge.readFile(s,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}if(e.trim().length!==0)try{return JSON.parse(e)}catch{return}}function ql(){return Hl(4).toString("hex")}var jl,Ul,He=is(()=>{"use strict";jl=new Set(["EPERM","EACCES","EBUSY"]),Ul=10});function vr(s,e){return`${s}:${e}`}var Gu=is(()=>{"use strict";Q();He()});var tl={};Ol(tl,{_resetForTests:()=>yw,clearPin:()=>hi,fetchPeerFingerprint:()=>mw,formatFingerprint:()=>Qu,getPin:()=>pw,installGlobalTlsTrust:()=>ki,loadPinsFromPeerStore:()=>yi,loadPinsFromStore:()=>gw,setPin:()=>ts,sha256Hex:()=>wi,wsTlsOptions:()=>vi});import{createHash as aw}from"crypto";import*as Ku from"tls";import{Agent as dw,Dispatcher as cw,buildConnector as uw,getGlobalDispatcher as lw,setGlobalDispatcher as fw}from"undici";function ts(s,e,t){Pt.set(vr(s,e),Yu(t))}function hi(s,e){Pt.delete(vr(s,e))}function pw(s,e){return Pt.get(vr(s,e))}function gw(s){Pt.clear();for(let e of s.list())e.entry.pinnedFingerprint&&ts(e.host,e.port,e.entry.pinnedFingerprint)}function yi(s){for(let e of s.list())e.pinnedFingerprint&&ts(e.host,e.port,e.pinnedFingerprint)}async function mw(s,e,t={}){let n=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=Ku.connect({host:s,port:e,servername:s,rejectUnauthorized:!1,autoSelectFamily:!0}),a=!1,d=(u,l)=>{if(!a){a=!0,clearTimeout(c);try{i.destroy()}catch{}u?o(u):l&&r(l)}},c=setTimeout(()=>{d(new Error(`TLS connect to ${s}:${e} timed out`))},n);i.once("secureConnect",()=>{let u=i.getPeerCertificate(!1);if(!u||!u.raw){d(new Error(`${s}:${e} did not present a TLS certificate`));return}d(null,wi(u.raw))}),i.once("error",u=>d(u))})}function wi(s){return aw("sha256").update(s).digest("hex")}function Qu(s){let e=Yu(s),t=e.match(/.{2}/g);return t?t.join(":"):e}function Yu(s){return s.replace(/:/g,"").toLowerCase()}function ki(){if(mi)return;mi=!0;let s=lw(),e=new dw({connect:uw({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(n,r)=>Zu(n,r)})}),t=new cw;t.dispatch=(n,r)=>{let o=hw(n.origin);return(o&&Xu(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(()=>{})),fw(t)}function hw(s){if(!s)return null;try{return new URL(String(s)).hostname}catch{return null}}function Xu(s){for(let e of Pt.keys())if(el(e)?.host===s)return!0;return!1}function Zu(s,e){if(!e||!e.raw)return new Error(`TLS peer ${s} did not present a certificate`);let t=wi(e.raw);for(let[n,r]of Pt.entries()){let o=el(n);if(o&&o.host===s&&r===t)return}return new Error(`TLS pin mismatch for ${s} (cert sha256 ${Qu(t)})`)}function el(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 vi(s){return Xu(s)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>Zu(e,t)}:{autoSelectFamily:!0}}function yw(){Pt.clear(),mi=!1}var Pt,mi,ns=is(()=>{"use strict";Gu();Pt=new Map,mi=!1});Q();import*as ot from"fs/promises";import{homedir as wn}from"os";import{z as C}from"zod";Q();import*as $t from"fs/promises";function Mr(){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 Dl(){try{let e=(await $t.readFile(E.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(s){if(s.code==="ENOENT")return;throw s}}async function _r(s){await $t.mkdir(E.home(),{recursive:!0}),await $t.writeFile(E.authToken(),s+`
5
- `,{encoding:"utf8",mode:384})}async function Oi(){let s=await Dl();if(s)return s;let e=Mr();return await _r(e),process.stderr.write(`hydra-acp: initialized ${E.authToken()} with a fresh service token.
6
- `),e}He();import*as Di from"fs/promises";import*as hn from"os";import*as je from"path";var ne="read by the daemon, which loads config.json at startup",Ni={daemon:{reload:"restart",overlay:"partial",overlayNote:"only changes which daemon this client dials; a daemon started from here still binds config.json's host/port. Use `home` for a separate daemon",nested:!0},agents:{reload:"live",overlay:"inert",overlayNote:ne},agentOverrides:{reload:"live",overlay:"inert",overlayNote:ne},registry:{reload:"live",overlay:"inert",overlayNote:ne},npmRegistry:{reload:"live",overlay:"inert",overlayNote:ne},defaultAgent:{reload:"live",overlay:"effective"},defaultCwd:{reload:"live",overlay:"effective"},sessionDefaults:{reload:"live",overlay:"partial",overlayNote:"applies to WS session/new and child_session/spawn; POST /v1/sessions has no model/mode/effort field to apply any of it to"},synopsisAgent:{reload:"warn",overlay:"inert",overlayNote:ne},synopsisModel:{reload:"warn",overlay:"inert",overlayNote:ne},compaction:{reload:"warn",overlay:"inert",overlayNote:ne},defaultTransformers:{reload:"warn",overlay:"inert",overlayNote:ne},disableWorkspaceSnapshots:{reload:"warn",overlay:"inert",overlayNote:ne},compressToolContent:{reload:"warn",overlay:"inert",overlayNote:ne},extensions:{reload:"warn",overlay:"inert",overlayNote:ne},transformers:{reload:"warn",overlay:"inert",overlayNote:ne},tui:{reload:"client",overlay:"effective"},sessionListColdLimit:{reload:"client",overlay:"effective"}},zl={host:{reload:"restart",overlay:"inert"},port:{reload:"restart",overlay:"inert"},publicHost:{reload:"restart",overlay:"inert"},tls:{reload:"restart",overlay:"inert"},scrubEnv:{reload:"live",overlay:"inert",overlayNote:ne},logLevel:{reload:"warn",overlay:"inert",overlayNote:ne},sessionIdleTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},backgroundTaskTracking:{reload:"warn",overlay:"inert",overlayNote:ne},nonInteractiveOrphanTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryMaxEntries:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveMaxBytes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveTiers:{reload:"warn",overlay:"inert",overlayNote:ne},agentStderrTailBytes:{reload:"warn",overlay:"inert",overlayNote:ne},agentSyncIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcMaxAgeDays:{reload:"warn",overlay:"inert",overlayNote:ne}};function $r(s){return Ni[s]??{reload:"restart",overlay:"inert"}}function Or(s){return zl[s]??{reload:"restart",overlay:"inert"}}function Fr(){let s=[];for(let[e,t]of Object.entries(Ni))t.overlay!=="effective"&&s.push({key:e,effect:t.overlay,note:t.overlayNote??ne});return s}var Jl=".hydra-acp.json",Nr="home",Vl=64,_k=Fr().map(s=>s.key);function Gl(s){return s==="~"?hn.homedir():s.startsWith("~/")?je.join(hn.homedir(),s.slice(2)):s.startsWith("$HOME/")?je.join(hn.homedir(),s.slice(6)):s}function Dr(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function Hr(s,e){let t={...s};for(let[n,r]of Object.entries(e)){let o=t[n];t[n]=Dr(o)&&Dr(r)?Hr(o,r):r}return t}async function Kl(s,e=hn.homedir()){let t=[],n=[],r=je.resolve(e),o=je.resolve(s);for(let i=0;i<Vl;i+=1){let a=je.join(o,Jl),d;try{d=await Di.readFile(a,"utf8")}catch{d=void 0}if(d!==void 0)try{let u=JSON.parse(d);Dr(u)?t.push({file:a,data:u}):n.push({file:a,key:"",message:"expected a JSON object; ignoring this file"})}catch(u){n.push({file:a,key:"",message:`is not valid JSON (${u.message}); ignoring this file`})}if(o===r)break;let c=je.dirname(o);if(c===o)break;o=c}return t.reverse(),{layers:t,notices:n}}function Ql(s){let e=new Map(Fr().map(n=>[n.key,n])),t=[];for(let n of s)for(let r of Object.keys(n.data)){let o=e.get(r);if(!o)continue;let i=o.effect==="partial"?`\`${r}\` ${o.note}`:`\`${r}\` is ${o.note}, so it has no effect in a directory config`;t.push({file:n.file,key:r,message:i})}return t}async function Yl(s=process.cwd()){let{layers:e,notices:t}=await Kl(s);t.push(...Ql(e));let n={};for(let i of e)n=Hr(n,i.data);let r,o=n[Nr];return typeof o=="string"&&o.length>0?r=je.resolve(Gl(o)):o!==void 0&&t.push({file:e[e.length-1].file,key:Nr,message:"`home` must be a non-empty string; ignoring it"}),delete n[Nr],{layers:e,notices:t,merged:n,...r!==void 0?{homeRequest:r}:{}}}function Xl(s,e){let t=s[e];return typeof t=="string"&&t.length>0?t:void 0}function Zl(s,e){let t=s[e];if(t===null||typeof t!="object"||Array.isArray(t))return;let n={};for(let[r,o]of Object.entries(t)){if(o===null||typeof o!="object"||Array.isArray(o))continue;let i={};for(let[a,d]of Object.entries(o))typeof d=="string"&&(i[a]=d);Object.keys(i).length>0&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}async function yn(s){let e={};try{e=(await Yl(s)).merged}catch{return{}}let t=Xl(e,"defaultAgent"),n=Zl(e,"sessionDefaults");return{...t!==void 0?{agentId:t}:{},...n!==void 0?{configDefaults:n}:{}}}var Ui="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",ef=C.object({cert:C.string(),key:C.string()}),Ot=55514,tf=C.object({host:C.string().default("127.0.0.1"),port:C.number().int().positive().default(Ot),logLevel:C.enum(["debug","info","warn","error"]).default("info"),tls:ef.optional(),sessionIdleTimeoutSeconds:C.number().int().nonnegative().default(3600),backgroundTaskTracking:C.boolean().optional(),nonInteractiveOrphanTimeoutSeconds:C.number().int().nonnegative().default(180),sessionHistoryMaxEntries:C.number().int().positive().default(1e4),sessionHistoryArchiveMaxBytes:C.number().int().nonnegative().default(1e7),sessionHistoryArchiveTiers:C.number().int().positive().default(10),agentStderrTailBytes:C.number().int().positive().default(4096),publicHost:C.string().optional(),agentSyncIntervalMinutes:C.number().nonnegative().default(60),scrubEnv:C.array(C.string()).default([]),sessionGcIntervalMinutes:C.number().nonnegative().default(60),sessionGcMaxAgeDays:C.number().positive().default(2)}),nf=C.object({url:C.string().url().default(Ui),ttlHours:C.number().positive().default(24),pinned:C.boolean().default(!1)}),sf=C.object({extends:C.string().optional(),name:C.string().optional(),description:C.string().optional(),command:C.string().optional(),args:C.array(C.string()).optional(),env:C.record(C.string()).optional()}),rf=C.object({packageSpec:C.string().optional(),extraArgs:C.array(C.string()).optional(),env:C.record(C.string()).optional()}),of=C.enum(["enter","alt-enter","shift-enter","ctrl-enter","alt-b","alt-f","alt-n","alt-tab","shift-tab","tab","up","down","left","right","home","end","backspace","alt-backspace","delete","ctrl-a","ctrl-b","ctrl-c","ctrl-d","ctrl-e","ctrl-f","ctrl-g","ctrl-k","ctrl-l","ctrl-n","ctrl-o","ctrl-p","ctrl-q","ctrl-r","ctrl-s","ctrl-u","ctrl-v","ctrl-t","ctrl-w","ctrl-x","ctrl-x-ctrl-e","ctrl-y","ctrl-underscore","alt-underscore","escape"]),af=C.union([C.string(),C.object({field:C.string().optional(),text:C.string().optional(),script:C.string().optional(),refreshMs:C.number().int().positive().optional(),maxWidth:C.number().int().positive().optional(),minWidth:C.number().int().nonnegative().optional(),truncate:C.boolean().optional(),priority:C.number().optional(),prefix:C.string().optional(),suffix:C.string().optional(),separator:C.string().optional(),style:C.string().optional(),onClick:C.string().optional(),onDoubleClick:C.string().optional()}).strict()]),df=C.object({id:C.string().min(1),script:C.string().min(1),refreshMs:C.number().int().positive().optional(),title:C.string().optional(),cap:C.number().int().positive().optional()}).strict(),cf=C.union([C.string(),df]),Hi=C.array(af);function jr(s,e){return C.object({left:Hi.default(s),right:Hi.default(e)}).default({})}var uf=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],lf=["usage"],ff=[],pf=["helpHint"],gf=["cwd","title"],mf=["agentModel"],hf=C.object({composer:C.object({top:jr(uf,lf),bottom:jr(ff,pf),hintTurns:C.number().int().nonnegative().nullable().default(3)}).default({}),sessionbar:jr(gf,mf),scriptRefreshMs:C.number().int().positive().default(5e3),readIdleSeconds:C.number().int().nonnegative().default(180),repaintThrottleMs:C.number().int().nonnegative().default(1e3),maxScrollbackLines:C.number().int().positive().default(1e4),mouse:C.boolean().default(!0),inAppSelection:C.boolean().optional(),selectionClipboard:C.enum(["primary","clipboard","both"]).default("both"),openFileCommand:C.union([C.string(),C.array(C.string())]).optional(),openFileInTerminal:C.boolean().optional(),logMaxBytes:C.number().int().positive().default(5*1024*1024),keyTrace:C.boolean().optional(),cwdColumnMaxWidth:C.number().int().positive().default(32),progressIndicator:C.boolean().default(!0),terminalHost:C.union([C.boolean(),C.enum(["auto","paseo","herdr","tmux"])]).default(!0),launcherModeWhenHosted:C.boolean().default(!1),skipPermissions:C.boolean().default(!1),defaultEnterAction:C.enum(["enqueue","amend"]).default("amend"),showThoughts:C.boolean().default(!0),ambiguousWidth:C.enum(["auto","narrow","wide"]).default("auto"),toolContent:C.enum(["inline","references"]).default("references"),diffContextLines:C.number().int().min(0).default(3),promptHistoryMaxEntries:C.number().int().positive().default(2e3),maxToolItems:C.number().int().nonnegative().default(5),maxPlanItems:C.number().int().nonnegative().default(5),sidebar:C.object({enabled:C.boolean().default(!0),width:C.number().int().positive().optional(),border:C.enum(["none","rule","frame"]).default("frame"),gadgets:C.array(cf).default(["activity","sessions","tasks","context","queue","todo","files","git","resources","info","tools"])}).default({}),showFileUpdates:C.enum(["none","edit","diff"]).default("edit"),sessionColumns:C.array(C.enum(["session","upstream","host","state","agent","model","age","cwd","title","cost"])).nonempty().optional(),defaultHost:C.string().min(1).default("remote:all"),hotkeys:C.record(of,C.object({command:C.union([C.string(),C.array(C.string())])})).default({}),theme:C.union([C.string(),C.record(C.string(),C.unknown())]).optional(),themeBackground:C.string().optional()}),ji=C.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),yf=C.object({command:C.array(C.string()).default([]),args:C.array(C.string()).default([]),env:C.record(C.string()).default({}),enabled:C.boolean().default(!0)}),wf=C.object({command:C.array(C.string()).default([]),args:C.array(C.string()).default([]),env:C.record(C.string()).default({}),enabled:C.boolean().default(!0)}),kf=C.object({daemon:tf.default({}),registry:nf.default({url:Ui,ttlHours:24,pinned:!1}),agents:C.record(C.string(),sf).default({}),agentOverrides:C.record(C.string(),rf).default({}),defaultAgent:C.string().default("opencode"),sessionDefaults:C.record(C.string(),C.record(C.string(),C.string())).default({}),synopsisAgent:C.string().optional(),synopsisModel:C.string().optional(),compaction:C.object({agent:C.string().optional(),model:C.string().optional(),tailK:C.number().int().nonnegative().default(20),maxIterations:C.number().int().positive().default(3),contextFraction:C.number().min(0).max(1).default(.5),hardCeilingFraction:C.number().min(0).max(1).default(.85),absoluteFallback:C.number().int().positive().default(2e5),idleBeforePromptMs:C.number().int().nonnegative().default(3e5),modelContextWindows:C.record(C.string(),C.number().int().positive()).default({})}).default({}),defaultCwd:C.string().default("~"),disableWorkspaceSnapshots:C.boolean().optional(),compressToolContent:C.boolean().default(!0),sessionListColdLimit:C.number().int().nonnegative().default(20),extensions:C.record(ji,yf).default({}),transformers:C.record(ji,wf).default({}),defaultTransformers:C.array(C.string()).default([]),npmRegistry:C.string().url().optional(),tui:hf.default({})});function Li(s){return Object.entries(s.extensions).map(([e,t])=>({name:e,...t}))}function Bi(s){return Object.entries(s.transformers).map(([e,t])=>({name:e,...t}))}async function Ur(){return await vf(),await ce(E.config())??{}}async function vf(){let s;try{s=await ot.lstat(E.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(s.isSymbolicLink())try{await ot.stat(E.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await ot.readlink(E.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${E.config()} is a broken symlink (-> ${t}); its target is missing. Refusing to treat this as "no config" and overwrite it. Restore the target (e.g. decrypt/check out your dotfiles) or remove the dangling link.`)}}async function bf(){let s=await Ur(),e=s.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let n=!1;try{await ot.access(E.authToken()),n=!0}catch(r){if(r.code!=="ENOENT")throw r}if(n)throw new Error(`Auth token present in both ${E.authToken()} and ${E.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await _r(t),delete e.authToken,Object.keys(e).length===0&&delete s.daemon,await me(E.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${E.config()} to ${E.authToken()}.
7
- `)}async function Sf(){let s=await Ur(),e=s.defaultModels&&typeof s.defaultModels=="object"&&!Array.isArray(s.defaultModels)?s.defaultModels:void 0;if(!e)return;let t=s.sessionDefaults&&typeof s.sessionDefaults=="object"&&!Array.isArray(s.sessionDefaults)?s.sessionDefaults:{};for(let[n,r]of Object.entries(e)){if(typeof r!="string")continue;let o=t[n]&&typeof t[n]=="object"&&!Array.isArray(t[n])?t[n]:{};o.model===void 0&&(o.model=r),t[n]=o}s.sessionDefaults=t,delete s.defaultModels,await me(E.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated defaultModels to sessionDefaults in ${E.config()}.
8
- `)}async function kn(){return await bf(),await Sf(),kf.parse(await Ur())}function ie(s){if(s==="~"||s==="$HOME")return wn();if(s.startsWith("~/"))return wn()+s.slice(1);if(s.startsWith("$HOME/"))return wn()+s.slice(5);if(process.platform==="win32"){if(s.startsWith("~\\"))return wn()+s.slice(1);if(s.startsWith("$HOME\\"))return wn()+s.slice(5)}return s}Q();import*as et from"fs/promises";import*as Wi from"path";var If=64*1024;async function qi(s){let e=E.daemonBootLog(),t=`[${new Date().toISOString()}] pid=${process.pid} ${s}
9
- `;if(await et.mkdir(Wi.dirname(e),{recursive:!0}),await et.stat(e).then(r=>r.size).catch(()=>0)>If){await et.writeFile(e,t,{encoding:"utf8",mode:384});return}await et.appendFile(e,t,{encoding:"utf8",mode:384})}var Af={exit:s=>process.exit(s),out:s=>process.stdout.write(s),err:s=>process.stderr.write(s)},zi=!1;async function Ji(s,e=Af){zi&&(e.err(`Second signal received; exiting immediately.
10
- `),e.exit(1)),zi=!0,e.out(`Shutting down...
2
+ var ef=Object.defineProperty;var fs=(s,e)=>()=>(s&&(e=s(s=0)),e);var tf=(s,e)=>{for(var t in e)ef(s,t,{get:e[t],enumerable:!0})};import*as B from"path";import*as Ur from"os";function F(s,e=Ur.homedir()){return process.platform==="win32"||!e?s:s===e?"~":s.startsWith(e+"/")?"~"+s.slice(e.length):s}function ps(s){return process.platform!=="win32"||!/^(?:[a-zA-Z]:[\\/]|[\\/]{2}[^\\/])/.test(s)?s:B.win32.resolve(s)}function gs(s){if(process.platform==="win32"){let e=B.win32.normalize(s).toLowerCase();return e.length>3?e.replace(/\\+$/,""):e}return s.length>1?s.replace(/\/+$/,""):s}function nf(){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 sf(s,e){Ji||B.isAbsolute(s)||(Ji=!0,process.stderr.write(`hydra-acp: ${Vi} is relative (${JSON.stringify(s)}); resolved against the current directory to ${e}. Processes started from elsewhere will use a different home and will not see each other's daemon. Set an absolute path.
3
+ `))}function q(){let s=process.env[Vi];if(s&&s.length>0){let t=B.resolve(s);return sf(s,t),t}let e=nf();if(e)throw new Error(`HYDRA_ACP_HOME is unset under a test runner (${e}); refusing to fall back to ~/.hydra-acp. The harness must set HYDRA_ACP_HOME \u2014 vitest.setup.ts does this, but \`bun test\` bypasses the vitest config and does not. Run the suite with \`npx vitest run\`, not \`bun test\`.`);return B.join(Ur.homedir(),".hydra-acp")}var Vi,Ji,E,Q=fs(()=>{"use strict";Vi="HYDRA_ACP_HOME";Ji=!1;E={home:q,config:()=>B.join(q(),"config.json"),authToken:()=>B.join(q(),"auth-token"),remotes:()=>B.join(q(),"remotes.json"),peers:()=>B.join(q(),"peers.json"),tlsDir:()=>B.join(q(),"tls"),pidFile:()=>B.join(q(),"daemon.pid"),logFile:()=>B.join(q(),"daemon.log"),daemonBootLog:()=>B.join(q(),"daemon-boot.log"),currentLogFile:()=>B.join(q(),"current.log"),registryCache:()=>B.join(q(),"registry.json"),themesDir:()=>B.join(q(),"themes"),ttySessionDir:()=>B.join(q(),"tty"),ttySessionFile:s=>B.join(q(),"tty",s),agentsDir:()=>B.join(q(),"agents"),agentLogFile:s=>B.join(q(),"agents","logs",`${s}.log`),agentInstallDir:(s,e,t)=>B.join(q(),"agents",e,s,t),agentNpmInstallDir:(s,e,t)=>B.join(q(),"agents",e,s,t,`node${process.versions.modules}`),sessionsDir:()=>B.join(q(),"sessions"),sessionDir:s=>B.join(q(),"sessions",s),sessionFile:s=>B.join(q(),"sessions",s,"meta.json"),historyFile:s=>B.join(q(),"sessions",s,"history.jsonl"),historyArchiveFile:(s,e)=>B.join(q(),"sessions",s,`history.jsonl.${e}`),toolsDir:s=>B.join(q(),"sessions",s,"tools"),toolBlobFile:(s,e)=>B.join(q(),"sessions",s,"tools",e),queueFile:s=>B.join(q(),"sessions",s,"queue.ndjson"),tombstonesDir:()=>B.join(q(),"sessions",".tombstones"),tombstoneAgentDir:s=>B.join(q(),"sessions",".tombstones",encodeURIComponent(s)),tombstoneFile:(s,e)=>B.join(q(),"sessions",".tombstones",encodeURIComponent(s),encodeURIComponent(e)),extensionsDir:()=>B.join(q(),"extensions"),extensionLogDir:s=>B.join(q(),"extensions",s),extensionLogFile:s=>B.join(q(),"extensions",s,"current.log"),extensionPidFile:s=>B.join(q(),"extensions",s,"extension.pid"),transformersDir:()=>B.join(q(),"transformers"),transformerLogDir:s=>B.join(q(),"transformers",s),transformerLogFile:s=>B.join(q(),"transformers",s,"current.log"),transformerPidFile:s=>B.join(q(),"transformers",s,"transformer.pid"),transformerState:(s,e)=>B.join(q(),"sessions",s,"transformer-state",e),tuiHistoryFile:s=>B.join(q(),"sessions",s,"prompt-history"),globalTuiHistoryFile:()=>B.join(q(),"prompt-history"),tuiLogFile:()=>B.join(q(),"tui.log"),shimWireLogFile:()=>B.join(q(),"shim-wire.log")}});import*as ge from"fs/promises";import*as Ki from"fs";import*as Pe from"path";import{randomBytes as of}from"crypto";async function me(s,e,t={}){let r=(t.pretty??!0?JSON.stringify(e,null,2):JSON.stringify(e))+`
4
+ `;await uf(s,r,t)}async function cf(s,e,t={}){let n=t.rename??ge.rename,r=t.platform??process.platform,o=t.sleep??(i=>new Promise(a=>setTimeout(a,i)));for(let i=0;;i++)try{await n(s,e);return}catch(a){let d=a.code??"";if(!(r==="win32"&&af.has(d)&&i<df-1))throw a;await o(10*(i+1))}}async function uf(s,e,t={}){let n=await lf(s),r=Pe.dirname(n);await ge.mkdir(r,{recursive:!0});let o=`${n}.tmp-${process.pid}-${ff()}`;try{let i={encoding:"utf8"};t.mode!==void 0&&(i.mode=t.mode),await ge.writeFile(o,e,i),await cf(o,n)}catch(i){throw await ge.unlink(o).catch(()=>{}),i}if(t.mode!==void 0)try{Ki.chmodSync(n,t.mode)}catch{}}async function lf(s){let e;try{e=await ge.lstat(s)}catch(r){if(r.code==="ENOENT")return s;throw r}if(!e.isSymbolicLink())return s;let t=await ge.readlink(s),n=Pe.isAbsolute(t)?t:Pe.resolve(Pe.dirname(s),t);try{let r=await ge.realpath(Pe.dirname(n));return Pe.join(r,Pe.basename(n))}catch(r){if(r.code==="ENOENT")return n;throw r}}async function ce(s){let e;try{e=await ge.readFile(s,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}if(e.trim().length!==0)try{return JSON.parse(e)}catch{return}}function ff(){return of(4).toString("hex")}var af,df,He=fs(()=>{"use strict";af=new Set(["EPERM","EACCES","EBUSY"]),df=10});function Mr(s,e){return`${s}:${e}`}var ml=fs(()=>{"use strict";Q();He()});var Sl={};tf(Sl,{_resetForTests:()=>Ww,clearPin:()=>Pi,fetchPeerFingerprint:()=>Uw,formatFingerprint:()=>yl,getPin:()=>Hw,installGlobalTlsTrust:()=>$i,loadPinsFromPeerStore:()=>Mi,loadPinsFromStore:()=>jw,setPin:()=>as,sha256Hex:()=>_i,wsTlsOptions:()=>Fi});import{createHash as $w}from"crypto";import*as hl from"tls";import{Agent as Fw,Dispatcher as Ow,buildConnector as Nw,getGlobalDispatcher as Dw,setGlobalDispatcher as Lw}from"undici";function as(s,e,t){$t.set(Mr(s,e),wl(t))}function Pi(s,e){$t.delete(Mr(s,e))}function Hw(s,e){return $t.get(Mr(s,e))}function jw(s){$t.clear();for(let e of s.list())e.entry.pinnedFingerprint&&as(e.host,e.port,e.entry.pinnedFingerprint)}function Mi(s){for(let e of s.list())e.pinnedFingerprint&&as(e.host,e.port,e.pinnedFingerprint)}async function Uw(s,e,t={}){let n=t.timeoutMs??1e4;return new Promise((r,o)=>{let i=hl.connect({host:s,port:e,servername:s,rejectUnauthorized:!1,autoSelectFamily:!0}),a=!1,d=(u,l)=>{if(!a){a=!0,clearTimeout(c);try{i.destroy()}catch{}u?o(u):l&&r(l)}},c=setTimeout(()=>{d(new Error(`TLS connect to ${s}:${e} timed out`))},n);i.once("secureConnect",()=>{let u=i.getPeerCertificate(!1);if(!u||!u.raw){d(new Error(`${s}:${e} did not present a TLS certificate`));return}d(null,_i(u.raw))}),i.once("error",u=>d(u))})}function _i(s){return $w("sha256").update(s).digest("hex")}function yl(s){let e=wl(s),t=e.match(/.{2}/g);return t?t.join(":"):e}function wl(s){return s.replace(/:/g,"").toLowerCase()}function $i(){if(Ei)return;Ei=!0;let s=Dw(),e=new Fw({connect:Nw({rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(n,r)=>vl(n,r)})}),t=new Ow;t.dispatch=(n,r)=>{let o=Bw(n.origin);return(o&&kl(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(()=>{})),Lw(t)}function Bw(s){if(!s)return null;try{return new URL(String(s)).hostname}catch{return null}}function kl(s){for(let e of $t.keys())if(bl(e)?.host===s)return!0;return!1}function vl(s,e){if(!e||!e.raw)return new Error(`TLS peer ${s} did not present a certificate`);let t=_i(e.raw);for(let[n,r]of $t.entries()){let o=bl(n);if(o&&o.host===s&&r===t)return}return new Error(`TLS pin mismatch for ${s} (cert sha256 ${yl(t)})`)}function bl(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 Fi(s){return kl(s)?{rejectUnauthorized:!1,autoSelectFamily:!0,checkServerIdentity:(e,t)=>vl(e,t)}:{autoSelectFamily:!0}}function Ww(){$t.clear(),Ei=!1}var $t,Ei,ds=fs(()=>{"use strict";ml();$t=new Map,Ei=!1});Q();import*as it from"fs/promises";import{homedir as In}from"os";import{z as C}from"zod";Q();import*as Nt from"fs/promises";function Br(){let s=new Uint8Array(32);crypto.getRandomValues(s);let e="";for(let t of s)e+=t.toString(16).padStart(2,"0");return`hydra_token_${e}`}async function rf(){try{let e=(await Nt.readFile(E.authToken(),"utf8")).trim();return e.length>0?e:void 0}catch(s){if(s.code==="ENOENT")return;throw s}}async function Wr(s){await Nt.mkdir(E.home(),{recursive:!0}),await Nt.writeFile(E.authToken(),s+`
5
+ `,{encoding:"utf8",mode:384})}async function Gi(){let s=await rf();if(s)return s;let e=Br();return await Wr(e),process.stderr.write(`hydra-acp: initialized ${E.authToken()} with a fresh service token.
6
+ `),e}He();import*as Yi from"fs/promises";import*as bn from"os";import*as je from"path";var ne="read by the daemon, which loads config.json at startup",Qi={daemon:{reload:"restart",overlay:"partial",overlayNote:"only changes which daemon this client dials; a daemon started from here still binds config.json's host/port. Use `home` for a separate daemon",nested:!0},agents:{reload:"live",overlay:"inert",overlayNote:ne},agentOverrides:{reload:"live",overlay:"inert",overlayNote:ne},registry:{reload:"live",overlay:"inert",overlayNote:ne},npmRegistry:{reload:"live",overlay:"inert",overlayNote:ne},defaultAgent:{reload:"live",overlay:"effective"},defaultCwd:{reload:"live",overlay:"effective"},sessionDefaults:{reload:"live",overlay:"partial",overlayNote:"applies to WS session/new and child_session/spawn; POST /v1/sessions has no model/mode/effort field to apply any of it to"},synopsisAgent:{reload:"warn",overlay:"inert",overlayNote:ne},synopsisModel:{reload:"warn",overlay:"inert",overlayNote:ne},compaction:{reload:"warn",overlay:"inert",overlayNote:ne},defaultTransformers:{reload:"warn",overlay:"inert",overlayNote:ne},disableWorkspaceSnapshots:{reload:"warn",overlay:"inert",overlayNote:ne},compressToolContent:{reload:"warn",overlay:"inert",overlayNote:ne},elicitationForms:{reload:"warn",overlay:"inert",overlayNote:ne},extensions:{reload:"warn",overlay:"inert",overlayNote:ne},transformers:{reload:"warn",overlay:"inert",overlayNote:ne},tui:{reload:"client",overlay:"effective"},sessionListColdLimit:{reload:"client",overlay:"effective"}},pf={host:{reload:"restart",overlay:"inert"},port:{reload:"restart",overlay:"inert"},publicHost:{reload:"restart",overlay:"inert"},tls:{reload:"restart",overlay:"inert"},scrubEnv:{reload:"live",overlay:"inert",overlayNote:ne},logLevel:{reload:"warn",overlay:"inert",overlayNote:ne},sessionIdleTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},backgroundTaskTracking:{reload:"warn",overlay:"inert",overlayNote:ne},nonInteractiveOrphanTimeoutSeconds:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryMaxEntries:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveMaxBytes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionHistoryArchiveTiers:{reload:"warn",overlay:"inert",overlayNote:ne},agentStderrTailBytes:{reload:"warn",overlay:"inert",overlayNote:ne},agentSyncIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcIntervalMinutes:{reload:"warn",overlay:"inert",overlayNote:ne},sessionGcMaxAgeDays:{reload:"warn",overlay:"inert",overlayNote:ne}};function qr(s){return Qi[s]??{reload:"restart",overlay:"inert"}}function zr(s){return pf[s]??{reload:"restart",overlay:"inert"}}function Jr(){let s=[];for(let[e,t]of Object.entries(Qi))t.overlay!=="effective"&&s.push({key:e,effect:t.overlay,note:t.overlayNote??ne});return s}var gf=".hydra-acp.json",Vr="home",mf=64,rv=Jr().map(s=>s.key);function hf(s){return s==="~"?bn.homedir():s.startsWith("~/")?je.join(bn.homedir(),s.slice(2)):s.startsWith("$HOME/")?je.join(bn.homedir(),s.slice(6)):s}function Gr(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function Kr(s,e){let t={...s};for(let[n,r]of Object.entries(e)){let o=t[n];t[n]=Gr(o)&&Gr(r)?Kr(o,r):r}return t}async function yf(s,e=bn.homedir()){let t=[],n=[],r=je.resolve(e),o=je.resolve(s);for(let i=0;i<mf;i+=1){let a=je.join(o,gf),d;try{d=await Yi.readFile(a,"utf8")}catch{d=void 0}if(d!==void 0)try{let u=JSON.parse(d);Gr(u)?t.push({file:a,data:u}):n.push({file:a,key:"",message:"expected a JSON object; ignoring this file"})}catch(u){n.push({file:a,key:"",message:`is not valid JSON (${u.message}); ignoring this file`})}if(o===r)break;let c=je.dirname(o);if(c===o)break;o=c}return t.reverse(),{layers:t,notices:n}}function wf(s){let e=new Map(Jr().map(n=>[n.key,n])),t=[];for(let n of s)for(let r of Object.keys(n.data)){let o=e.get(r);if(!o)continue;let i=o.effect==="partial"?`\`${r}\` ${o.note}`:`\`${r}\` is ${o.note}, so it has no effect in a directory config`;t.push({file:n.file,key:r,message:i})}return t}async function kf(s=process.cwd()){let{layers:e,notices:t}=await yf(s);t.push(...wf(e));let n={};for(let i of e)n=Kr(n,i.data);let r,o=n[Vr];return typeof o=="string"&&o.length>0?r=je.resolve(hf(o)):o!==void 0&&t.push({file:e[e.length-1].file,key:Vr,message:"`home` must be a non-empty string; ignoring it"}),delete n[Vr],{layers:e,notices:t,merged:n,...r!==void 0?{homeRequest:r}:{}}}function vf(s,e){let t=s[e];return typeof t=="string"&&t.length>0?t:void 0}function bf(s,e){let t=s[e];if(t===null||typeof t!="object"||Array.isArray(t))return;let n={};for(let[r,o]of Object.entries(t)){if(o===null||typeof o!="object"||Array.isArray(o))continue;let i={};for(let[a,d]of Object.entries(o))typeof d=="string"&&(i[a]=d);Object.keys(i).length>0&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}async function Sn(s){let e={};try{e=(await kf(s)).merged}catch{return{}}let t=vf(e,"defaultAgent"),n=bf(e,"sessionDefaults");return{...t!==void 0?{agentId:t}:{},...n!==void 0?{configDefaults:n}:{}}}var ea="https://cdn.agentclientprotocol.com/registry/v1/latest/registry.json",Sf=C.object({cert:C.string(),key:C.string()}),Dt=55514,If=C.object({host:C.string().default("127.0.0.1"),port:C.number().int().positive().default(Dt),logLevel:C.enum(["debug","info","warn","error"]).default("info"),tls:Sf.optional(),sessionIdleTimeoutSeconds:C.number().int().nonnegative().default(3600),backgroundTaskTracking:C.boolean().optional(),nonInteractiveOrphanTimeoutSeconds:C.number().int().nonnegative().default(180),sessionHistoryMaxEntries:C.number().int().positive().default(1e4),sessionHistoryArchiveMaxBytes:C.number().int().nonnegative().default(1e7),sessionHistoryArchiveTiers:C.number().int().positive().default(10),agentStderrTailBytes:C.number().int().positive().default(4096),publicHost:C.string().optional(),agentSyncIntervalMinutes:C.number().nonnegative().default(60),scrubEnv:C.array(C.string()).default([]),sessionGcIntervalMinutes:C.number().nonnegative().default(60),sessionGcMaxAgeDays:C.number().positive().default(2)}),Af=C.object({url:C.string().url().default(ea),ttlHours:C.number().positive().default(24),pinned:C.boolean().default(!1)}),Cf=C.object({extends:C.string().optional(),name:C.string().optional(),description:C.string().optional(),command:C.string().optional(),args:C.array(C.string()).optional(),env:C.record(C.string()).optional()}),Rf=C.object({packageSpec:C.string().optional(),extraArgs:C.array(C.string()).optional(),env:C.record(C.string()).optional()}),xf=C.enum(["enter","alt-enter","shift-enter","ctrl-enter","alt-b","alt-f","alt-n","alt-tab","shift-tab","tab","up","down","left","right","home","end","backspace","alt-backspace","delete","ctrl-a","ctrl-b","ctrl-c","ctrl-d","ctrl-e","ctrl-f","ctrl-g","ctrl-k","ctrl-l","ctrl-n","ctrl-o","ctrl-p","ctrl-q","ctrl-r","ctrl-s","ctrl-u","ctrl-v","ctrl-t","ctrl-w","ctrl-x","ctrl-x-ctrl-e","ctrl-y","ctrl-underscore","alt-underscore","escape"]),Tf=C.union([C.string(),C.object({field:C.string().optional(),text:C.string().optional(),script:C.string().optional(),refreshMs:C.number().int().positive().optional(),maxWidth:C.number().int().positive().optional(),minWidth:C.number().int().nonnegative().optional(),truncate:C.boolean().optional(),priority:C.number().optional(),prefix:C.string().optional(),suffix:C.string().optional(),separator:C.string().optional(),style:C.string().optional(),onClick:C.string().optional(),onDoubleClick:C.string().optional()}).strict()]),Ef=C.object({id:C.string().min(1),script:C.string().min(1),refreshMs:C.number().int().positive().optional(),title:C.string().optional(),cap:C.number().int().positive().optional()}).strict(),Pf=C.union([C.string(),Ef]),Xi=C.array(Tf);function Qr(s,e){return C.object({left:Xi.default(s),right:Xi.default(e)}).default({})}var Mf=["status",{field:"elapsed",separator:" "},"sessionId","queued","scroll"],_f=["usage"],$f=[],Ff=["helpHint"],Of=["cwd","title"],Nf=["agentModel"],Df=C.object({composer:C.object({top:Qr(Mf,_f),bottom:Qr($f,Ff),hintTurns:C.number().int().nonnegative().nullable().default(3)}).default({}),sessionbar:Qr(Of,Nf),scriptRefreshMs:C.number().int().positive().default(5e3),readIdleSeconds:C.number().int().nonnegative().default(180),repaintThrottleMs:C.number().int().nonnegative().default(1e3),maxScrollbackLines:C.number().int().positive().default(1e4),mouse:C.boolean().default(!0),inAppSelection:C.boolean().optional(),selectionClipboard:C.enum(["primary","clipboard","both"]).default("both"),openFileCommand:C.union([C.string(),C.array(C.string())]).optional(),openFileInTerminal:C.boolean().optional(),logMaxBytes:C.number().int().positive().default(5*1024*1024),keyTrace:C.boolean().optional(),cwdColumnMaxWidth:C.number().int().positive().default(32),progressIndicator:C.boolean().default(!0),terminalHost:C.union([C.boolean(),C.enum(["auto","paseo","herdr","tmux"])]).default(!0),launcherModeWhenHosted:C.boolean().default(!1),skipPermissions:C.boolean().default(!1),defaultEnterAction:C.enum(["enqueue","amend"]).default("amend"),showThoughts:C.boolean().default(!0),ambiguousWidth:C.enum(["auto","narrow","wide"]).default("auto"),toolContent:C.enum(["inline","references"]).default("references"),diffContextLines:C.number().int().min(0).default(3),promptHistoryMaxEntries:C.number().int().positive().default(2e3),maxToolItems:C.number().int().nonnegative().default(5),maxPlanItems:C.number().int().nonnegative().default(5),sidebar:C.object({enabled:C.boolean().default(!0),width:C.number().int().positive().optional(),border:C.enum(["none","rule","frame"]).default("frame"),gadgets:C.array(Pf).default(["activity","sessions","tasks","context","queue","todo","files","git","resources","info","tools"])}).default({}),showFileUpdates:C.enum(["none","edit","diff"]).default("edit"),sessionColumns:C.array(C.enum(["session","upstream","host","state","agent","model","age","cwd","title","cost"])).nonempty().optional(),defaultHost:C.string().min(1).default("remote:all"),hotkeys:C.record(xf,C.object({command:C.union([C.string(),C.array(C.string())])})).default({}),theme:C.union([C.string(),C.record(C.string(),C.unknown())]).optional(),themeBackground:C.string().optional()}),Zi=C.string().min(1).regex(/^[A-Za-z0-9._-]+$/,"extension name must be filename-safe"),Lf=C.object({command:C.array(C.string()).default([]),args:C.array(C.string()).default([]),env:C.record(C.string()).default({}),enabled:C.boolean().default(!0)}),Hf=C.object({command:C.array(C.string()).default([]),args:C.array(C.string()).default([]),env:C.record(C.string()).default({}),enabled:C.boolean().default(!0)}),jf=C.object({daemon:If.default({}),registry:Af.default({url:ea,ttlHours:24,pinned:!1}),agents:C.record(C.string(),Cf).default({}),agentOverrides:C.record(C.string(),Rf).default({}),elicitationForms:C.boolean().optional(),defaultAgent:C.string().default("opencode"),sessionDefaults:C.record(C.string(),C.record(C.string(),C.string())).default({}),synopsisAgent:C.string().optional(),synopsisModel:C.string().optional(),compaction:C.object({agent:C.string().optional(),model:C.string().optional(),tailK:C.number().int().nonnegative().default(20),maxIterations:C.number().int().positive().default(3),contextFraction:C.number().min(0).max(1).default(.5),hardCeilingFraction:C.number().min(0).max(1).default(.85),absoluteFallback:C.number().int().positive().default(2e5),idleBeforePromptMs:C.number().int().nonnegative().default(3e5),modelContextWindows:C.record(C.string(),C.number().int().positive()).default({})}).default({}),defaultCwd:C.string().default("~"),disableWorkspaceSnapshots:C.boolean().optional(),compressToolContent:C.boolean().default(!0),sessionListColdLimit:C.number().int().nonnegative().default(20),extensions:C.record(Zi,Lf).default({}),transformers:C.record(Zi,Hf).default({}),defaultTransformers:C.array(C.string()).default([]),npmRegistry:C.string().url().optional(),tui:Df.default({})});function ta(s){return Object.entries(s.extensions).map(([e,t])=>({name:e,...t}))}function na(s){return Object.entries(s.transformers).map(([e,t])=>({name:e,...t}))}async function Yr(){return await Uf(),await ce(E.config())??{}}async function Uf(){let s;try{s=await it.lstat(E.config())}catch(e){if(e.code==="ENOENT")return;throw e}if(s.isSymbolicLink())try{await it.stat(E.config())}catch(e){if(e.code!=="ENOENT")throw e;let t=await it.readlink(E.config()).catch(()=>"<unknown>");throw new Error(`config.json at ${E.config()} is a broken symlink (-> ${t}); its target is missing. Refusing to treat this as "no config" and overwrite it. Restore the target (e.g. decrypt/check out your dotfiles) or remove the dangling link.`)}}async function Bf(){let s=await Yr(),e=s.daemon,t=e&&typeof e.authToken=="string"?e.authToken:void 0;if(!t)return;let n=!1;try{await it.access(E.authToken()),n=!0}catch(r){if(r.code!=="ENOENT")throw r}if(n)throw new Error(`Auth token present in both ${E.authToken()} and ${E.config()} (daemon.authToken). Remove daemon.authToken from config.json to resolve.`);await Wr(t),delete e.authToken,Object.keys(e).length===0&&delete s.daemon,await me(E.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated auth token from ${E.config()} to ${E.authToken()}.
7
+ `)}async function Wf(){let s=await Yr(),e=s.defaultModels&&typeof s.defaultModels=="object"&&!Array.isArray(s.defaultModels)?s.defaultModels:void 0;if(!e)return;let t=s.sessionDefaults&&typeof s.sessionDefaults=="object"&&!Array.isArray(s.sessionDefaults)?s.sessionDefaults:{};for(let[n,r]of Object.entries(e)){if(typeof r!="string")continue;let o=t[n]&&typeof t[n]=="object"&&!Array.isArray(t[n])?t[n]:{};o.model===void 0&&(o.model=r),t[n]=o}s.sessionDefaults=t,delete s.defaultModels,await me(E.config(),s,{mode:384}),process.stderr.write(`hydra-acp: migrated defaultModels to sessionDefaults in ${E.config()}.
8
+ `)}async function An(){return await Bf(),await Wf(),jf.parse(await Yr())}function ie(s){if(s==="~"||s==="$HOME")return In();if(s.startsWith("~/"))return In()+s.slice(1);if(s.startsWith("$HOME/"))return In()+s.slice(5);if(process.platform==="win32"){if(s.startsWith("~\\"))return In()+s.slice(1);if(s.startsWith("$HOME\\"))return In()+s.slice(5)}return s}Q();import*as et from"fs/promises";import*as sa from"path";var qf=64*1024;async function ra(s){let e=E.daemonBootLog(),t=`[${new Date().toISOString()}] pid=${process.pid} ${s}
9
+ `;if(await et.mkdir(sa.dirname(e),{recursive:!0}),await et.stat(e).then(r=>r.size).catch(()=>0)>qf){await et.writeFile(e,t,{encoding:"utf8",mode:384});return}await et.appendFile(e,t,{encoding:"utf8",mode:384})}var zf={exit:s=>process.exit(s),out:s=>process.stdout.write(s),err:s=>process.stderr.write(s)},oa=!1;async function ia(s,e=zf){oa&&(e.err(`Second signal received; exiting immediately.
10
+ `),e.exit(1)),oa=!0,e.out(`Shutting down...
11
11
  `);let t=e.hardTimeoutMs??1e4,n=setTimeout(()=>{e.err(`Graceful shutdown did not complete within ${t}ms; forcing exit.
12
12
  `),e.exit(1)},t);n.unref();try{await s.shutdown()}catch(r){e.err(`shutdown failed: ${r instanceof Error?r.message:String(r)}
13
- `)}clearTimeout(n),e.exit(0)}import*as Rl from"fs";import*as Xe from"fs/promises";import*as xl from"net";import*as pn from"path";import*as Tl from"tls";import mk from"fastify";import hk from"@fastify/websocket";var Vi="acp.v1";function Gi(s,e){return s.has(Vi)?Vi:!1}import Al from"pino";import yk from"pino-roll";var Cf={herdr:["HERDR_PANE_ID","HERDR_TAB_ID","HERDR_WORKSPACE_ID","HERDR_STARTUP_CWD"],tmux:["TMUX_PANE"],zellij:["ZELLIJ_PANE_ID","ZELLIJ_SESSION_NAME"],wezterm:["WEZTERM_PANE"],kitty:["KITTY_WINDOW_ID"],screen:["STY"],iterm2:["ITERM_SESSION_ID"],paseo:["PASEO_TERMINAL_ID","PASEO_ACTIVITY_TOKEN"],hydra:["HYDRA_TAB_LABEL"]},Ki="HYDRA_ACP_SESSION",Rf=[Ki],xf=[...Object.values(Cf).flat(),...Rf];function cs(s,e){return s?{...e??{},[Ki]:s}:e}var Qi=[];function Lr(s){Qi=s?[...s]:[]}function Tf(s,e){return e.endsWith("*")?s.startsWith(e.slice(0,-1)):s===e}function Ef(){return[...xf,...Qi]}function us(s=process.env){let e=Ef(),t={};for(let[n,r]of Object.entries(s))r!==void 0&&(e.some(o=>Tf(n,o))||(t[n]=r));return t}Q();import*as he from"fs/promises";import{createHash as Pf}from"crypto";import{gzip as Mf,gunzip as _f}from"zlib";import{promisify as Yi}from"util";var Xi=Yi(Mf),$f=Yi(_f),Zi=/^[A-Za-z0-9_-]+$/,Of=/^[a-f0-9]{64}$/,Br=!0;function ea(s){Br=s}function ls(s,e){return Zi.test(s)?e===void 0||Of.test(e):!1}function fs(s,e){return`${E.toolBlobFile(s,e)}.gz`}async function Wr(s,e){if(!ls(s))return null;let t=Pf("sha256").update(e,"utf8").digest("hex"),n=fs(s,t),r=E.toolBlobFile(s,t);for(let a of[n,r])try{return await he.access(a),t}catch{}await he.mkdir(E.toolsDir(s),{recursive:!0});let o=Br?n:r,i=Br?await Xi(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await he.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function vn(s,e){if(!ls(s,e))return null;try{let t=await he.readFile(fs(s,e));return(await $f(t)).toString("utf8")}catch{}try{return await he.readFile(E.toolBlobFile(s,e),"utf8")}catch{return null}}async function ta(s,e){if(!ls(s,e))return null;try{return await he.readFile(fs(s,e))}catch{}try{let t=await he.readFile(E.toolBlobFile(s,e));return await Xi(t)}catch{return null}}async function na(s,e,t){if(!ls(s,e))return;let n=fs(s,e);try{await he.access(n);return}catch{}await he.mkdir(E.toolsDir(s),{recursive:!0}),await he.writeFile(n,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function sa(s){Zi.test(s)&&await he.rm(E.toolsDir(s),{recursive:!0,force:!0}).catch(()=>{})}Q();import*as ya from"fs/promises";import*as gs from"path";import{z as W}from"zod";He();Q();import*as oa from"fs";import*as ke from"fs/promises";import*as it from"path";import{spawn as ia}from"child_process";import{Readable as Ff}from"stream";function Ue(){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 Jr(s,e=Ue()){if(e)return s[e]}var Ft=s=>{process.stderr.write(s+`
14
- `)};function Vr(s){Ft=s??(e=>process.stderr.write(e+`
15
- `))}async function aa(s){if(!s.target.archive)throw new Error(`Agent ${s.agentId} has no archive URL for ${Ue()??"this platform"}`);if(!s.target.cmd)throw new Error(`Agent ${s.agentId} has no cmd in its binary target`);let e=Ue();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=E.agentInstallDir(s.agentId,e,s.version),n=it.resolve(t,s.target.cmd);if(await zr(n))return n;if(await Nf({agentId:s.agentId,version:s.version,archiveUrl:s.target.archive,installDir:t,onProgress:s.onProgress}),!await zr(n))throw new Error(`Agent ${s.agentId}: extracted archive did not contain ${s.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await ke.chmod(n,493).catch(()=>{}),n}async function Nf(s){await ke.mkdir(it.dirname(s.installDir),{recursive:!0});let e=await ke.mkdtemp(`${s.installDir}.partial-`);try{Ft(`hydra-acp: downloading ${s.agentId} from ${s.archiveUrl}`);let t=await Df({url:s.archiveUrl,dir:e,agentId:s.agentId,version:s.version,onProgress:s.onProgress});Ft(`hydra-acp: extracting ${s.agentId}`),Nt(s.onProgress,{phase:"extract",agentId:s.agentId,version:s.version}),await jf(t,e),await ke.unlink(t).catch(()=>{});try{await ke.rename(e,s.installDir)}catch(n){let r=n;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await zr(s.installDir)){await ke.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Nt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw n}Ft(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),Nt(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await ke.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Nt(s,e){if(s)try{s(e)}catch{}}async function Df(s){let e=Hf(s.url),t=it.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=oa.createWriteStream(t),i=Ff.fromWeb(n.body);Nt(s.onProgress,{phase:"download_start",agentId:s.agentId,version:s.version,totalBytes:r});let a=0,d=Date.now(),c=0,u=2e3,l=150;return i.on("data",w=>{a+=w.length;let h=Date.now();h-c>=l&&(c=h,Nt(s.onProgress,{phase:"download_progress",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r})),h-d>=u&&(d=h,Ft(ra(s.agentId,a,r)))}),await new Promise((w,h)=>{i.on("error",h),o.on("error",h),o.on("finish",()=>w()),i.pipe(o)}),Ft(ra(s.agentId,a,r,!0)),Nt(s.onProgress,{phase:"download_done",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r}),t}function ra(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 Hf(s){let e=new URL(s);return it.posix.basename(e.pathname)||"archive"}async function jf(s,e){let t=s.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await qr("tar",["-xf",s,"-C",e]);return}if(t.endsWith(".zip")){if(await Uf("unzip")){await qr("unzip",["-q",s,"-d",e]);return}await qr("tar",["-xf",s,"-C",e]);return}throw new Error(`Unsupported archive format: ${s}`)}function qr(s,e){return new Promise((t,n)=>{let r=ia(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 Uf(s){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",n=ia(t,[s],{stdio:"ignore"});n.on("error",()=>e(!1)),n.on("exit",r=>e(r===0))})}async function zr(s){try{return await ke.access(s),!0}catch{return!1}}Q();import*as ve from"fs/promises";import*as Oe from"path";import{delimiter as Kf}from"path";import{spawn as Qf}from"child_process";import{statSync as Lf}from"fs";import{delimiter as Bf,join as Wf}from"path";var qf=".COM;.EXE;.BAT;.CMD";function da(s){try{return Lf(s).isFile()}catch{return!1}}function zf(s){let e=(s.PATHEXT??qf).split(";").map(n=>n.trim()).filter(n=>n.length>0),t=[];for(let n of e)for(let r of[n,n.toLowerCase(),n.toUpperCase()])t.includes(r)||t.push(r);return t}function Jf(s,e){let t=s.toLowerCase();return e.some(n=>t.endsWith(n.toLowerCase()))}function Vf(s,e={}){if((e.platform??process.platform)!=="win32")return s;let n=e.env??process.env,r=zf(n);if(Jf(s,r))return s;if(/[\\/]/.test(s)){for(let i of r){let a=s+i;if(da(a))return a}return s}let o=n.PATH??n.Path??"";for(let i of o.split(Bf).filter(a=>a.length>0))for(let a of r){let d=Wf(i,s+a);if(da(d))return d}return s}var Gf=/["%\r\n]/;function ca(s){if(Gf.test(s))throw new Error(`cannot pass ${JSON.stringify(s)} through cmd.exe: it contains a quote, a percent sign, or a newline, none of which can be escaped unambiguously`);return/[\s&|<>^()]/.test(s)?`"${s}"`:s}function Dt(s,e,t={}){let n=t.platform??process.platform,r=Vf(s,t);return n!=="win32"||!/\.(cmd|bat)$/i.test(r)?{command:r,args:[...e],shell:!1}:{command:ca(r),args:e.map(ca),shell:!0}}var Kr=s=>{process.stderr.write(s+`
16
- `)};function Qr(s){Kr=s??(e=>process.stderr.write(e+`
17
- `))}async function la(s){let e=Ue();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=E.agentNpmInstallDir(s.agentId,e,s.version),n=tp(s.packageSpec),r=np(n),o={installDir:t,packageName:n,hint:s.bin,basename:r},i=Oe.join(t,"node_modules",".bin",s.bin);if(await bt(i))return i;if(await bt(t)){let l=await ua(o);if(l)return l.binPath}await Yf({agentId:s.agentId,version:s.version,packageSpec:s.packageSpec,installDir:t,registry:s.registry,onProgress:s.onProgress});let a=await ua(o);if(a)return a.binPath;let d=await pa(t,n),c=typeof d=="object"&&d!==null?Object.keys(d):typeof d=="string"?[r]:[],u=c.length>0?` (package declares bins: ${c.join(", ")})`:"";throw new Error(`Agent ${s.agentId}: npm install of ${s.packageSpec} did not produce bin ${s.bin} (looked in ${t}/node_modules/.bin/)${u}`)}async function Yf(s){await ve.mkdir(Oe.dirname(s.installDir),{recursive:!0});let e=await ve.mkdtemp(`${s.installDir}.partial-`);try{Kr(`hydra-acp: installing ${s.packageSpec} for ${s.agentId} into ${e}`),Gr(s.onProgress,{phase:"install_start",agentId:s.agentId,version:s.version,packageSpec:s.packageSpec}),await ve.writeFile(Oe.join(e,"package.json"),`{"private":true}
18
- `),await ep({packageSpec:s.packageSpec,cwd:e,registry:s.registry});try{await ve.rename(e,s.installDir)}catch(t){let n=t;if((n.code==="EEXIST"||n.code==="ENOTEMPTY")&&await bt(s.installDir)){await ve.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Gr(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw t}Kr(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),Gr(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await ve.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Gr(s,e){if(s)try{s(e)}catch{}}var Xf=5,Zf=25;function ep(s){return fa(s,0)}async function fa(s,e){try{await new Promise((t,n)=>{let r=s.registry?["--registry",s.registry]:[],o=Dt("npm",["install","--no-audit","--no-fund","--silent",...r,s.packageSpec]),i;try{i=Qf(o.command,o.args,{cwd:s.cwd,stdio:["ignore","pipe","pipe"],shell:o.shell,windowsHide:!0})}catch(d){n(d);return}let a="";i.stdout?.on("data",d=>{}),i.stderr?.setEncoding("utf8"),i.stderr?.on("data",d=>{a=(a+d).slice(-4096)}),i.on("error",d=>{if(d.code==="ENOENT"){let u=(process.env.PATH??process.env.Path??"").split(Kf).filter(l=>l.length>0);n(new Error(`npm not found on PATH: tried to run ${JSON.stringify(o.command)}${o.shell?" through a shell":""} against ${u.length} PATH entries. Install Node.js / npm, or use a binary-distributed agent.`));return}n(d)}),i.on("exit",(d,c)=>{if(d===0){t();return}let u=d!==null?`exit code ${d}`:`signal ${c??"unknown"}`,l=a.trim();n(new Error(l?`npm install ${s.packageSpec} failed (${u})
19
- stderr: ${l}`:`npm install ${s.packageSpec} failed (${u})`))})})}catch(t){if(t.code==="ETXTBSY"&&e<Xf)return await new Promise(r=>setTimeout(r,Zf*(e+1))),fa(s,e+1);throw t}}function tp(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 np(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}async function pa(s,e){let t=Oe.join(s,"node_modules",e,"package.json");try{let n=await ve.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 ua(s){let e=Oe.join(s.installDir,"node_modules",".bin"),t=Oe.join(e,s.hint);if(await bt(t))return{binName:s.hint,binPath:t};let n=await pa(s.installDir,s.packageName);if(typeof n=="object"&&n!==null){let r=Object.keys(n);if(r.length===1){let o=r[0],i=Oe.join(e,o);if(await bt(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=Oe.join(e,o);if(await bt(i))return{binName:o,binPath:i}}}}if(s.basename!==s.hint){let r=Oe.join(e,s.basename);if(await bt(r))return{binName:s.basename,binPath:r}}}async function bt(s){try{return await ve.access(s),!0}catch{return!1}}var sp=W.object({package:W.string(),bin:W.string().optional(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),Ht=W.object({archive:W.string().url().optional(),cmd:W.string().optional(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),rp=W.object({"darwin-aarch64":Ht.optional(),"darwin-x86_64":Ht.optional(),"linux-aarch64":Ht.optional(),"linux-x86_64":Ht.optional(),"windows-x86_64":Ht.optional(),"windows-aarch64":Ht.optional()}),op=W.object({package:W.string(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),ip=W.object({command:W.string(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),ap=W.object({command:W.string().optional(),url:W.string().optional(),description:W.string().optional()}),dp=W.object({npx:sp.optional(),binary:rp.optional(),uvx:op.optional(),exec:ip.optional()}),cp=W.object({id:W.string(),name:W.string(),version:W.string().optional(),description:W.string().optional(),authors:W.array(W.string()).optional(),license:W.string().optional(),icon:W.string().optional(),repository:W.string().optional(),website:W.string().optional(),distribution:dp,onboarding:ap.optional(),requiredEnv:W.array(W.string().min(1)).optional()}),ga=8;function wa(s){return s.installId??s.id}function Xr(s){let e=s.extendsChain;return e&&e.length>0?e[e.length-1]:s.id}function Zr(s,e){if(s)for(let t of e.extendsChain??[e.id]){let n=s[t];if(n!==void 0)return{value:n,from:t}}}function ka(s,e){if(!s)return;let t,n;for(let r of[...e.extendsChain??[e.id]].reverse()){let o=s[r];o!==void 0&&(t={...t,...o},n=r)}return t!==void 0&&n!==void 0?{value:t,from:n}:void 0}var ma=W.object({version:W.string(),agents:W.array(cp),extensions:W.array(W.unknown()).optional()}),ps=class{constructor(e,t={}){this.config=e;this.options=t}config;options;cache;async load(){if(this.cache&&(this.isPinned()||this.isFresh(this.cache.fetchedAt)))return this.cache.data;let e=await this.readDiskCache();if(e&&(this.isPinned()||this.isFresh(e.fetchedAt)))return this.cache=e,e.data;try{let t=await this.fetchFromNetwork();return this.cache=t,await this.writeDiskCache(t),t.data}catch(t){if(e){let n=this.options.onStaleFallback;if(n)try{n(t,Date.now()-e.fetchedAt)}catch{}return this.cache=e,e.data}throw t}}async refresh(){let e=await this.fetchFromNetwork();return this.cache=e,await this.writeDiskCache(e),e.data}lastFetchedAt(){return this.cache?.fetchedAt}setConfig(e){this.config=e}async getAgent(e){return this.resolveAgent(e,[])}async resolveAgent(e,t){let n=this.findLocalDef(e);if(n){if(n.def.extends===void 0)return{...Yr(n.id,n.def),extendsChain:[n.id]};if(t.includes(n.id))throw new Error(`agent ${n.id}: extends cycle (${[...t,n.id].join(" -> ")})`);if(t.length+1>=ga)throw new Error(`agent ${n.id}: extends chain deeper than ${ga} (${[...t,n.id].join(" -> ")})`);let c=await this.resolveAgent(n.def.extends,[...t,n.id]);if(!c)throw new Error(`agent ${n.id}: extends ${JSON.stringify(n.def.extends)}, which is not a known agent`);return this.applyOverride(lp(n.id,n.def,c))}let r=await this.load(),o=r.agents.find(c=>c.id===e);if(o)return this.applyOverride(o);let i=r.agents.find(c=>eo(c)===e);if(i)return this.applyOverride(i);let a=e.toLowerCase(),d=r.agents.find(c=>c.id.toLowerCase()===`${a}-acp`);if(d)return this.applyOverride(d);if(a.length>0){let c=r.agents.filter(u=>u.id.toLowerCase().startsWith(a));if(c.length===1)return this.applyOverride(c[0])}}findLocalDef(e){let t=this.config.agents??{},n=t[e];if(n)return{id:e,def:n};let r=e.toLowerCase();for(let[o,i]of Object.entries(t))if(o.toLowerCase()===`${r}-acp`)return{id:o,def:i}}localAgents(){return Object.entries(this.config.agents??{}).filter(([,e])=>e.extends===void 0).map(([e,t])=>Yr(e,t))}async resolvedLocalAgents(){let e=[];for(let t of Object.keys(this.config.agents??{}))try{let n=await this.resolveAgent(t,[]);n&&e.push(n)}catch(n){this.options.onResolveError?.(t,n)}return e}applyOverride(e){let t=e.extendsChain?e:{...e,extendsChain:[e.id]},n=this.config.agentOverrides?.[t.id];if(!n)return t;let r=t.distribution,o=t.version,i=t.installId;return n.packageSpec&&r.npx&&(o=fp(n.packageSpec),i=t.id,r={...r,npx:{...r.npx,package:n.packageSpec}}),n.extraArgs?.length&&(r=up(r,n.extraArgs)),n.env&&Object.keys(n.env).length>0&&(r=ba(r,{env:n.env})),r===t.distribution?t:{...t,version:o,installId:i,distribution:r}}isPinned(){return this.config.registry?.pinned===!0}isFresh(e){let t=Date.now()-e,n=this.config.registry.ttlHours*60*60*1e3;return t<n}async fetchFromNetwork(){let e=await fetch(this.config.registry.url);if(!e.ok)throw new Error(`Registry fetch failed: HTTP ${e.status}`);let t=await e.json(),n=ma.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 ce(E.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=ma.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await me(E.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function va(s){return s&&Object.fromEntries(Object.entries(s).map(([e,t])=>[e,ie(t)]))}function Yr(s,e){return{id:s,name:e.name??s,description:e.description,version:"local",distribution:{exec:{command:ie(e.command??s),args:e.args?.map(ie),env:va(e.env)}}}}function ba(s,e){let t=e.args?.map(ie),n=va(e.env),r=o=>({...o,...t?{args:t}:{},...n?{env:{...o.env,...n}}:{}});return{...s.npx?{npx:r(s.npx)}:{},...s.uvx?{uvx:r(s.uvx)}:{},...s.exec?{exec:r(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([o,i])=>[o,i&&r(i)]))}:{}}}function up(s,e){let t=n=>({...n,args:[...n.args??[],...e]});return{...s.npx?{npx:t(s.npx)}:{},...s.uvx?{uvx:t(s.uvx)}:{},...s.exec?{exec:t(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([n,r])=>[n,r&&t(r)]))}:{}}}function lp(s,e,t){let n=e.command!==void 0;return{...t,id:s,name:e.name??t.name,description:e.description??t.description,version:n?"local":t.version,distribution:n?Yr(s,e).distribution:ba(t.distribution,e),installId:n?s:t.installId??t.id,extendsChain:[s,...t.extendsChain??[t.id]]}}function fp(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 eo(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 jt(s){let e=typeof s.resolvedLocalAgents=="function"?await s.resolvedLocalAgents():typeof s.localAgents=="function"?s.localAgents():[],t;try{t=await s.load()}catch(i){if(e.length===0)throw i;t={version:"local-only",agents:[]}}let n=new Set(e.map(i=>i.id)),r=[...e,...t.agents.filter(i=>!n.has(i.id))],o=await Promise.all(r.map(async i=>({id:i.id,name:i.name,version:i.version,description:i.description,distributions:Object.keys(i.distribution),installed:await to(i),...i.extendsChain?{extendsChain:i.extendsChain}:{},source:n.has(i.id)?"local":"registry",...i.onboarding?{onboarding:i.onboarding}:{}})));return{version:t.version,fetchedAt:s.lastFetchedAt(),agents:o}}async function to(s){let e=Ue();if(!e)return"no";let t=s.version??"current",n=wa(s);if(s.distribution.exec)return"yes";if(s.distribution.binary){let r=Jr(s.distribution.binary,e);if(r?.cmd){let o=gs.resolve(E.agentInstallDir(n,e,t),r.cmd);if(await ha(o))return"yes"}}if(s.distribution.npx){let r=s.distribution.npx,o=r.bin??eo(s)??r.package,i=E.agentNpmInstallDir(n,e,t),a=gs.join(i,"node_modules",".bin",o);if(await ha(a))return"yes"}return!s.distribution.npx&&!s.distribution.binary&&s.distribution.uvx?"lazy":"no"}async function ha(s){try{return await ya.access(s),!0}catch{return!1}}async function Me(s,e=[],t={}){let n=s.version??"current",r=wa(s);if(s.distribution.npx){let o=s.distribution.npx,i=e.length>0?e:o.args??[];if(process.env.HYDRA_ACP_SKIP_NPM_PREFETCH)return{command:"npx",args:["-y",o.package,...i],env:o.env??{},version:n,installId:r};let a=o.bin??eo(s)??o.package,d=t.onInstallProgress;return{command:await la({agentId:r,version:n,packageSpec:o.package,bin:a,registry:t.npmRegistry,onProgress:d?u=>d({source:"npm",...u}):void 0}),args:i,env:o.env??{},version:n,installId:r}}if(s.distribution.binary){let o=Jr(s.distribution.binary);if(!o)throw new Error(`Agent ${s.id} has no binary distribution for ${Ue()??"this platform"}.`);let i=t.onInstallProgress,a=await aa({agentId:r,version:n,target:o,onProgress:i?c=>i({source:"binary",...c}):void 0}),d=e.length>0?e:o.args??[];return{command:a,args:d,env:o.env??{},version:n,installId:r}}if(s.distribution.uvx){let o=s.distribution.uvx,i=e.length>0?e:o.args??[];return{command:"uvx",args:[o.package,...i],env:o.env??{},version:n,installId:r}}if(s.distribution.exec){let o=s.distribution.exec,i=e.length>0?e:o.args??[];return{command:o.command,args:i,env:o.env??{},version:n,installId:r}}throw new Error(`Agent ${s.id} has no usable distribution method.`)}import{spawn as yp,spawnSync as wp}from"child_process";import*as ys from"fs";import*as Ha from"path";var x={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,AuthRequired:-32e3,SessionNotFound:-32001,NotAuthorisedToAttach:-32002,MultiClientNotSupported:-32003,AgentNotInstalled:-32005,BundleAlreadyImported:-32010,PermissionDenied:-32011,AlreadyAttached:-32012,StreamNotEnabled:-32013,SessionClosing:-32014};import{z as Y}from"zod";var Sa=Y.object({protocolVersion:Y.number().optional(),clientCapabilities:Y.record(Y.unknown()).optional(),clientInfo:Y.object({name:Y.string(),version:Y.string().optional()}).optional()}),pp=Y.enum(["full","pending_only","none","after_message"]),Ia=Y.object({cwd:Y.string(),mcpServers:Y.array(Y.unknown()).optional(),_meta:Y.record(Y.unknown()).optional()}),Aa=Y.object({upstreamSessionId:Y.string(),agentId:Y.string(),cwd:Y.string(),title:Y.string().optional(),agentArgs:Y.array(Y.string()).optional()}),Ca=Y.object({sessionId:Y.string(),historyPolicy:pp.default("full"),afterMessageId:Y.string().optional(),afterSeq:Y.number().optional(),clientId:Y.string().optional(),clientInfo:Y.object({name:Y.string(),version:Y.string().optional()}).optional(),_meta:Y.record(Y.unknown()).optional()});import{z as bn}from"zod";var Ut=bn.object({selection:bn.object({text:bn.string().min(1),responsePartId:bn.string().optional()}).optional(),contextThroughSeq:bn.number().optional()});import{z as D}from"zod";var Ra=D.object({sessionId:D.string()}),xa=D.object({cwd:D.string().optional(),cursor:D.string().optional()}),no=D.object({used:D.number().optional(),size:D.number().optional(),costAmount:D.number().optional(),costCurrency:D.string().optional()}),Rv=D.object({sessionId:D.string(),upstreamSessionId:D.string().optional(),cwd:D.string(),workspace:D.object({path:D.string(),sourceCwd:D.string(),label:D.string(),provider:D.string(),snapshot:D.string().optional(),vcs:D.record(D.string(),D.string()).optional()}).optional(),workspaceError:D.string().optional(),title:D.string().optional(),agentId:D.string().optional(),currentModel:D.string().optional(),currentUsage:no.optional(),importedFromMachine:D.string().optional(),importedFromUpstreamSessionId:D.string().optional(),parentSessionId:D.string().optional(),forkedFromSessionId:D.string().optional(),forkedFromMessageId:D.string().optional(),side:Ut.optional(),originatingClient:D.object({name:D.string(),version:D.string().optional()}).optional(),interactive:D.boolean().optional(),priority:D.number().int().nonnegative().optional(),lastTurnEndedAt:D.number().optional(),readAt:D.number().optional(),unread:D.boolean().optional(),createdAt:D.string().optional(),updatedAt:D.string(),attachedClients:D.number().int().nonnegative(),status:D.enum(["warm","cold"]).default("warm"),busy:D.boolean().default(!1),awaitingInput:D.boolean().default(!1),turnStartedAt:D.number().optional(),armedTasks:D.number().int().nonnegative().optional(),armedSince:D.number().int().positive().optional(),compactionState:D.any().optional(),agentPid:D.number().int().positive().optional(),forkSynthesisState:D.enum(["running","failed"]).optional(),_meta:D.record(D.unknown()).optional()}),gp=D.object({sessionId:D.string(),cwd:D.string(),title:D.string().optional(),updatedAt:D.string().optional(),_meta:D.record(D.unknown()).optional()}),xv=D.object({sessions:D.array(gp),nextCursor:D.string().optional()});function ms(s,e){let t={attachedClients:s.attachedClients,status:s.status,busy:s.busy,awaitingInput:s.awaitingInput};return s.cwd!==void 0&&(t.cwd=s.cwd),s.workspace!==void 0&&(t.workspaceInfo=s.workspace),s.workspaceError!==void 0&&(t.workspaceError=s.workspaceError),s.title!==void 0&&(t.title=s.title),s.agentId!==void 0&&(t.agentId=s.agentId),s.upstreamSessionId!==void 0&&(t.upstreamSessionId=s.upstreamSessionId),s.createdAt!==void 0&&(t.createdAt=s.createdAt),s.currentModel!==void 0&&(t.currentModel=s.currentModel),s.currentUsage!==void 0&&(t.currentUsage=s.currentUsage),s.importedFromMachine!==void 0&&(t.importedFromMachine=s.importedFromMachine),s.importedFromUpstreamSessionId!==void 0&&(t.importedFromUpstreamSessionId=s.importedFromUpstreamSessionId),s.parentSessionId!==void 0&&(t.parentSessionId=s.parentSessionId),s.forkedFromSessionId!==void 0&&(t.forkedFromSessionId=s.forkedFromSessionId),s.forkedFromMessageId!==void 0&&(t.forkedFromMessageId=s.forkedFromMessageId),s.side!==void 0&&(t.side=s.side),s.originatingClient!==void 0&&(t.originatingClient=s.originatingClient),s.interactive!==void 0&&(t.interactive=s.interactive),s.priority!==void 0&&s.priority>0&&(t.priority=s.priority),s.lastTurnEndedAt!==void 0&&(t.lastTurnEndedAt=s.lastTurnEndedAt),s.readAt!==void 0&&(t.readAt=s.readAt),s.unread&&(t.unread=!0),s.armedTasks!==void 0&&(t.armedTasks=s.armedTasks),s.armedSince!==void 0&&(t.armedSince=s.armedSince),s.compactionState!==void 0&&(t.compactionState=s.compactionState),s.forkSynthesisState!==void 0&&(t.forkSynthesisState=s.forkSynthesisState),e&&(e.clientId!==void 0&&(t.clientId=e.clientId),e.currentMode!==void 0&&(t.currentMode=e.currentMode),e.agentArgs!==void 0&&e.agentArgs.length>0&&(t.agentArgs=e.agentArgs),e.availableCommands!==void 0&&e.availableCommands.length>0&&(t.availableCommands=e.availableCommands),e.availableModes!==void 0&&e.availableModes.length>0&&(t.availableModes=e.availableModes),e.availableModels!==void 0&&e.availableModels.length>0&&(t.availableModels=e.availableModels),e.turnStartedAt!==void 0&&(t.turnStartedAt=e.turnStartedAt),e.agentCapabilities!==void 0&&(t.agentCapabilities=e.agentCapabilities),e.queue!==void 0&&e.queue.length>0&&(t.queue=e.queue),e.resurrected===!0&&(t.resurrected=!0),e.armedTaskList!==void 0&&(t.armedTaskList=e.armedTaskList)),t}function Ta(s){let e={sessionId:s.sessionId,cwd:s.cwd,updatedAt:s.updatedAt,_meta:Sn(s._meta,ms(s))};return s.title!==void 0&&(e.title=s.title),e}var le="hydra-acp";function mp(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 at(s){if(!s)return{};let e=s[le];if(!e||typeof e!="object"||Array.isArray(e))return{};let t=e,n={};if(typeof t.upstreamSessionId=="string"&&(n.upstreamSessionId=t.upstreamSessionId),typeof t.agentId=="string"&&(n.agentId=t.agentId),typeof t.cwd=="string"&&(n.cwd=t.cwd),t.workspace!==null&&typeof t.workspace=="object"&&!Array.isArray(t.workspace)){let o=t.workspace,i={};typeof o.label=="string"&&(i.label=o.label),typeof o.from=="string"&&(i.from=o.from),o.required===!0&&(i.required=!0),o.adopt===!0&&(i.adopt=!0),typeof o.provider=="string"&&(i.provider=o.provider),n.workspace=i}if(t.workspaceInfo!==null&&typeof t.workspaceInfo=="object"&&!Array.isArray(t.workspaceInfo)){let o=t.workspaceInfo;if(typeof o.path=="string"&&typeof o.sourceCwd=="string"&&typeof o.label=="string"&&typeof o.provider=="string"){let i={path:o.path,sourceCwd:o.sourceCwd,label:o.label,provider:o.provider};if(typeof o.snapshot=="string"&&(i.snapshot=o.snapshot),o.vcs!==null&&typeof o.vcs=="object"&&!Array.isArray(o.vcs)){let a={};for(let[d,c]of Object.entries(o.vcs))typeof c=="string"&&(a[d]=c);i.vcs=a}n.workspaceInfo=i}}if(typeof t.workspaceError=="string"&&(n.workspaceError=t.workspaceError),typeof t.clientId=="string"&&(n.clientId=t.clientId),typeof t.readonly=="boolean"&&(n.readonly=t.readonly),(t.replayMode==="instant"||t.replayMode==="drip")&&(n.replayMode=t.replayMode),typeof t.dripSpeed=="number"&&t.dripSpeed>0&&(n.dripSpeed=t.dripSpeed),typeof t.historyLimit=="number"&&Number.isFinite(t.historyLimit)&&t.historyLimit>=0&&(n.historyLimit=t.historyLimit),(t.toolContent==="inline"||t.toolContent==="references")&&(n.toolContent=t.toolContent),t.detachStatus==="detached"&&(n.detachStatus=t.detachStatus),typeof t.title=="string"&&(n.title=t.title),Array.isArray(t.agentArgs)&&t.agentArgs.every(o=>typeof o=="string")&&(n.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(o=>typeof o=="string")&&(n.transformers=t.transformers),t.resume){let o=Aa.safeParse(t.resume);o.success&&(n.resume=o.data)}if(typeof t.model=="string"&&(n.model=t.model),typeof t.currentModel=="string"&&(n.currentModel=t.currentModel),typeof t.currentMode=="string"&&(n.currentMode=t.currentMode),t.currentUsage){let o=no.safeParse(t.currentUsage);o.success&&(n.currentUsage=o.data)}if(typeof t.turnStartedAt=="number"&&t.turnStartedAt>0&&(n.turnStartedAt=t.turnStartedAt),typeof t.armedTasks=="number"&&t.armedTasks>=0&&(n.armedTasks=t.armedTasks),typeof t.armedSince=="number"&&t.armedSince>0&&(n.armedSince=t.armedSince),Array.isArray(t.armedTaskList)){let o=[];for(let i of t.armedTaskList){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;typeof a.label!="string"||typeof a.since!="number"||o.push({label:a.label,since:a.since,...typeof a.taskId=="string"?{taskId:a.taskId}:{},...typeof a.taskType=="string"?{taskType:a.taskType}:{},...typeof a.toolCallId=="string"?{toolCallId:a.toolCallId}:{},...a.endUnobservable===!0?{endUnobservable:!0}:{}})}n.armedTaskList=o}if(Array.isArray(t.availableCommands)){let o=[];for(let i of t.availableCommands){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.name!="string")continue;let d={name:a.name};typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableCommands=o)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let o=t.prompt,i={};typeof o.queueing=="boolean"&&(i.queueing=o.queueing),typeof o.cancelling=="boolean"&&(i.cancelling=o.cancelling),typeof o.updating=="boolean"&&(i.updating=o.updating),typeof o.amending=="boolean"&&(i.amending=o.amending),typeof o.pipelining=="boolean"&&(i.pipelining=o.pipelining),n.prompt=i}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let o=t.agents,i={};typeof o.list=="boolean"&&(i.list=o.list),typeof o.installProgress=="boolean"&&(i.installProgress=o.installProgress),n.agents=i}if(typeof t.mcpStdin=="boolean"&&(n.mcpStdin=t.mcpStdin),typeof t.interactive=="boolean"&&(n.interactive=t.interactive),typeof t.ancillary=="boolean"&&(n.ancillary=t.ancillary),t.salvaged&&typeof t.salvaged=="object"&&!Array.isArray(t.salvaged)){let o=t.salvaged;typeof o.reason=="string"&&typeof o.supersededMessageId=="string"&&(n.salvaged={reason:o.reason,supersededMessageId:o.supersededMessageId})}if(Array.isArray(t.queue)){let o=[];for(let i of t.queue){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i,d=a.originator;if(typeof a.messageId!="string"||!d||typeof d.clientId!="string"||!Array.isArray(a.prompt)||typeof a.position!="number"||typeof a.enqueuedAt!="number")continue;let c={clientId:d.clientId};typeof d.name=="string"&&(c.name=d.name),typeof d.version=="string"&&(c.version=d.version),o.push({messageId:a.messageId,originator:c,prompt:a.prompt,position:a.position,enqueuedAt:a.enqueuedAt})}o.length>0&&(n.queue=o)}if(Array.isArray(t.availableModes)){let o=[];for(let i of t.availableModes){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.id!="string")continue;let d={id:a.id};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModes=o)}if(Array.isArray(t.availableModels)){let o=[];for(let i of t.availableModels){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.modelId!="string")continue;let d={modelId:a.modelId};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModels=o)}(t.status==="warm"||t.status==="cold")&&(n.status=t.status),typeof t.busy=="boolean"&&(n.busy=t.busy),typeof t.awaitingInput=="boolean"&&(n.awaitingInput=t.awaitingInput),typeof t.attachedClients=="number"&&(n.attachedClients=t.attachedClients),typeof t.resurrected=="boolean"&&(n.resurrected=t.resurrected),typeof t.importedFromMachine=="string"&&(n.importedFromMachine=t.importedFromMachine),typeof t.importedFromUpstreamSessionId=="string"&&(n.importedFromUpstreamSessionId=t.importedFromUpstreamSessionId),typeof t.parentSessionId=="string"&&(n.parentSessionId=t.parentSessionId),typeof t.forkedFromSessionId=="string"&&(n.forkedFromSessionId=t.forkedFromSessionId),typeof t.forkedFromMessageId=="string"&&(n.forkedFromMessageId=t.forkedFromMessageId);let r=Ut.safeParse(t.side);if(r.success&&(n.side=r.data),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let o=t.originatingClient;n.originatingClient={name:o.name,...typeof o.version=="string"?{version:o.version}:{}}}if(t.agentCapabilities!==void 0&&(n.agentCapabilities=t.agentCapabilities),t.env!==void 0){let o=mp(t.env);o!==void 0&&(n.env=o)}return n}function Le(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?s:{...t,_meta:{...n,[le]:{...o,recordedAt:e}}}}function Be(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.seq=="number"?s:{...t,_meta:{...n,[le]:{...o,seq:e}}}}function Sn(s,e){return{...s??{},[le]:e}}import{z as _}from"zod";var Ea=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.record(_.unknown()).optional()}),hs=_.object({sessionId:_.string()}),Pa=_.object({clientId:_.string(),name:_.string().optional(),version:_.string().optional()}),Ov=_.object({sessionId:_.string(),messageId:_.string(),originator:Pa,prompt:_.array(_.unknown()),position:_.number().int().nonnegative(),queueDepth:_.number().int().positive(),enqueuedAt:_.number()}),Fv=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),Nv=_.object({sessionId:_.string(),messageId:_.string(),reason:_.enum(["started","cancelled","abandoned"])}),Ma=_.object({sessionId:_.string(),messageId:_.string()}),Dv=_.object({cancelled:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),_a=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),Hv=_.object({updated:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),$a=_.object({sessionId:_.string(),targetMessageId:_.string(),prompt:_.array(_.unknown()),replaceQueue:_.boolean().optional(),onTargetCompleted:_.enum(["reject","send_anyway"]).optional()}),jv=_.object({amended:_.boolean(),reason:_.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:_.string().optional()}),Oa=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.object({steering:_.object({idleBehavior:_.literal("promptRequired").optional()}).optional()}).optional()}),Uv=_.object({outcome:_.enum(["injected","startedNewTurn","promptRequired","failed"]),reason:_.literal("noRunningTurn").optional(),detached:_.boolean().optional()}),Lv=_.object({sessionId:_.string(),cancelledMessageId:_.string(),newMessageId:_.string(),prompt:_.array(_.unknown()),originator:Pa,amendedAt:_.number()});import{z as dt}from"zod";var qv=dt.object({agentId:dt.string(),version:dt.string(),source:dt.enum(["binary","npm"]),phase:dt.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:dt.number().optional(),totalBytes:dt.number().optional(),packageSpec:dt.string().optional()}),Fa="hydra-acp/agents/install_progress",Lt={auth:{terminal:!0},_meta:{"terminal-auth":!0}};function Na(s,e){let t="",n=[],r=[],o=!1,i=a=>{if(!o){o=!0;for(let d of r)d(a)}};return s.setEncoding("utf8"),s.on("data",a=>{t+=a;let d=t.indexOf(`
13
+ `)}clearTimeout(n),e.exit(0)}import*as Vl from"fs";import*as Xe from"fs/promises";import*as Gl from"net";import*as wn from"path";import*as Kl from"tls";import Uk from"fastify";import Bk from"@fastify/websocket";var aa="acp.v1";function da(s,e){return s.has(aa)?aa:!1}import zl from"pino";import Wk from"pino-roll";var Jf={herdr:["HERDR_PANE_ID","HERDR_TAB_ID","HERDR_WORKSPACE_ID","HERDR_STARTUP_CWD"],tmux:["TMUX_PANE"],zellij:["ZELLIJ_PANE_ID","ZELLIJ_SESSION_NAME"],wezterm:["WEZTERM_PANE"],kitty:["KITTY_WINDOW_ID"],screen:["STY"],iterm2:["ITERM_SESSION_ID"],paseo:["PASEO_TERMINAL_ID","PASEO_ACTIVITY_TOKEN"],hydra:["HYDRA_TAB_LABEL"]},ca="HYDRA_ACP_SESSION",Vf=[ca],Gf=[...Object.values(Jf).flat(),...Vf];function ms(s,e){return s?{...e??{},[ca]:s}:e}var ua=[];function Xr(s){ua=s?[...s]:[]}function Kf(s,e){return e.endsWith("*")?s.startsWith(e.slice(0,-1)):s===e}function Qf(){return[...Gf,...ua]}function hs(s=process.env){let e=Qf(),t={};for(let[n,r]of Object.entries(s))r!==void 0&&(e.some(o=>Kf(n,o))||(t[n]=r));return t}Q();import*as he from"fs/promises";import{createHash as Yf}from"crypto";import{gzip as Xf,gunzip as Zf}from"zlib";import{promisify as la}from"util";var fa=la(Xf),ep=la(Zf),pa=/^[A-Za-z0-9_-]+$/,tp=/^[a-f0-9]{64}$/,Zr=!0;function ga(s){Zr=s}function ys(s,e){return pa.test(s)?e===void 0||tp.test(e):!1}function ws(s,e){return`${E.toolBlobFile(s,e)}.gz`}async function eo(s,e){if(!ys(s))return null;let t=Yf("sha256").update(e,"utf8").digest("hex"),n=ws(s,t),r=E.toolBlobFile(s,t);for(let a of[n,r])try{return await he.access(a),t}catch{}await he.mkdir(E.toolsDir(s),{recursive:!0});let o=Zr?n:r,i=Zr?await fa(Buffer.from(e,"utf8")):Buffer.from(e,"utf8");return await he.writeFile(o,i,{mode:384,flag:"wx"}).catch(async a=>{if(a.code!=="EEXIST")throw a}),t}async function Cn(s,e){if(!ys(s,e))return null;try{let t=await he.readFile(ws(s,e));return(await ep(t)).toString("utf8")}catch{}try{return await he.readFile(E.toolBlobFile(s,e),"utf8")}catch{return null}}async function ma(s,e){if(!ys(s,e))return null;try{return await he.readFile(ws(s,e))}catch{}try{let t=await he.readFile(E.toolBlobFile(s,e));return await fa(t)}catch{return null}}async function ha(s,e,t){if(!ys(s,e))return;let n=ws(s,e);try{await he.access(n);return}catch{}await he.mkdir(E.toolsDir(s),{recursive:!0}),await he.writeFile(n,t,{mode:384,flag:"wx"}).catch(r=>{if(r.code!=="EEXIST")throw r})}async function ya(s){pa.test(s)&&await he.rm(E.toolsDir(s),{recursive:!0,force:!0}).catch(()=>{})}Q();import*as Ma from"fs/promises";import*as vs from"path";import{z as W}from"zod";He();Q();import*as ka from"fs";import*as ke from"fs/promises";import*as at from"path";import{spawn as va}from"child_process";import{Readable as np}from"stream";function Ue(){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 so(s,e=Ue()){if(e)return s[e]}var Lt=s=>{process.stderr.write(s+`
14
+ `)};function ro(s){Lt=s??(e=>process.stderr.write(e+`
15
+ `))}async function ba(s){if(!s.target.archive)throw new Error(`Agent ${s.agentId} has no archive URL for ${Ue()??"this platform"}`);if(!s.target.cmd)throw new Error(`Agent ${s.agentId} has no cmd in its binary target`);let e=Ue();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=E.agentInstallDir(s.agentId,e,s.version),n=at.resolve(t,s.target.cmd);if(await no(n))return n;if(await sp({agentId:s.agentId,version:s.version,archiveUrl:s.target.archive,installDir:t,onProgress:s.onProgress}),!await no(n))throw new Error(`Agent ${s.agentId}: extracted archive did not contain ${s.target.cmd} (looked in ${t})`);return process.platform!=="win32"&&await ke.chmod(n,493).catch(()=>{}),n}async function sp(s){await ke.mkdir(at.dirname(s.installDir),{recursive:!0});let e=await ke.mkdtemp(`${s.installDir}.partial-`);try{Lt(`hydra-acp: downloading ${s.agentId} from ${s.archiveUrl}`);let t=await rp({url:s.archiveUrl,dir:e,agentId:s.agentId,version:s.version,onProgress:s.onProgress});Lt(`hydra-acp: extracting ${s.agentId}`),Ht(s.onProgress,{phase:"extract",agentId:s.agentId,version:s.version}),await ip(t,e),await ke.unlink(t).catch(()=>{});try{await ke.rename(e,s.installDir)}catch(n){let r=n;if((r.code==="EEXIST"||r.code==="ENOTEMPTY")&&await no(s.installDir)){await ke.rm(e,{recursive:!0,force:!0}).catch(()=>{}),Ht(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw n}Lt(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),Ht(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await ke.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function Ht(s,e){if(s)try{s(e)}catch{}}async function rp(s){let e=op(s.url),t=at.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=ka.createWriteStream(t),i=np.fromWeb(n.body);Ht(s.onProgress,{phase:"download_start",agentId:s.agentId,version:s.version,totalBytes:r});let a=0,d=Date.now(),c=0,u=2e3,l=150;return i.on("data",y=>{a+=y.length;let h=Date.now();h-c>=l&&(c=h,Ht(s.onProgress,{phase:"download_progress",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r})),h-d>=u&&(d=h,Lt(wa(s.agentId,a,r)))}),await new Promise((y,h)=>{i.on("error",h),o.on("error",h),o.on("finish",()=>y()),i.pipe(o)}),Lt(wa(s.agentId,a,r,!0)),Ht(s.onProgress,{phase:"download_done",agentId:s.agentId,version:s.version,receivedBytes:a,totalBytes:r}),t}function wa(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 op(s){let e=new URL(s);return at.posix.basename(e.pathname)||"archive"}async function ip(s,e){let t=s.toLowerCase();if(t.endsWith(".tar.gz")||t.endsWith(".tgz")||t.endsWith(".tar")){await to("tar",["-xf",s,"-C",e]);return}if(t.endsWith(".zip")){if(await ap("unzip")){await to("unzip",["-q",s,"-d",e]);return}await to("tar",["-xf",s,"-C",e]);return}throw new Error(`Unsupported archive format: ${s}`)}function to(s,e){return new Promise((t,n)=>{let r=va(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 ap(s){return new Promise(e=>{let t=process.platform==="win32"?"where":"which",n=va(t,[s],{stdio:"ignore"});n.on("error",()=>e(!1)),n.on("exit",r=>e(r===0))})}async function no(s){try{return await ke.access(s),!0}catch{return!1}}Q();import*as ve from"fs/promises";import*as Fe from"path";import{delimiter as hp}from"path";import{spawn as yp}from"child_process";import{statSync as dp}from"fs";import{delimiter as cp,join as up}from"path";var lp=".COM;.EXE;.BAT;.CMD";function Sa(s){try{return dp(s).isFile()}catch{return!1}}function fp(s){let e=(s.PATHEXT??lp).split(";").map(n=>n.trim()).filter(n=>n.length>0),t=[];for(let n of e)for(let r of[n,n.toLowerCase(),n.toUpperCase()])t.includes(r)||t.push(r);return t}function pp(s,e){let t=s.toLowerCase();return e.some(n=>t.endsWith(n.toLowerCase()))}function gp(s,e={}){if((e.platform??process.platform)!=="win32")return s;let n=e.env??process.env,r=fp(n);if(pp(s,r))return s;if(/[\\/]/.test(s)){for(let i of r){let a=s+i;if(Sa(a))return a}return s}let o=n.PATH??n.Path??"";for(let i of o.split(cp).filter(a=>a.length>0))for(let a of r){let d=up(i,s+a);if(Sa(d))return d}return s}var mp=/["%\r\n]/;function Ia(s){if(mp.test(s))throw new Error(`cannot pass ${JSON.stringify(s)} through cmd.exe: it contains a quote, a percent sign, or a newline, none of which can be escaped unambiguously`);return/[\s&|<>^()]/.test(s)?`"${s}"`:s}function jt(s,e,t={}){let n=t.platform??process.platform,r=gp(s,t);return n!=="win32"||!/\.(cmd|bat)$/i.test(r)?{command:r,args:[...e],shell:!1}:{command:Ia(r),args:e.map(Ia),shell:!0}}var io=s=>{process.stderr.write(s+`
16
+ `)};function ao(s){io=s??(e=>process.stderr.write(e+`
17
+ `))}async function Ca(s){let e=Ue();if(!e)throw new Error(`Agent ${s.agentId}: cannot determine platform key for ${process.platform}/${process.arch}`);let t=E.agentNpmInstallDir(s.agentId,e,s.version),n=Sp(s.packageSpec),r=Ip(n),o={installDir:t,packageName:n,hint:s.bin,basename:r},i=Fe.join(t,"node_modules",".bin",s.bin);if(await It(i))return i;if(await It(t)){let l=await Aa(o);if(l)return l.binPath}await wp({agentId:s.agentId,version:s.version,packageSpec:s.packageSpec,installDir:t,registry:s.registry,onProgress:s.onProgress});let a=await Aa(o);if(a)return a.binPath;let d=await xa(t,n),c=typeof d=="object"&&d!==null?Object.keys(d):typeof d=="string"?[r]:[],u=c.length>0?` (package declares bins: ${c.join(", ")})`:"";throw new Error(`Agent ${s.agentId}: npm install of ${s.packageSpec} did not produce bin ${s.bin} (looked in ${t}/node_modules/.bin/)${u}`)}async function wp(s){await ve.mkdir(Fe.dirname(s.installDir),{recursive:!0});let e=await ve.mkdtemp(`${s.installDir}.partial-`);try{io(`hydra-acp: installing ${s.packageSpec} for ${s.agentId} into ${e}`),oo(s.onProgress,{phase:"install_start",agentId:s.agentId,version:s.version,packageSpec:s.packageSpec}),await ve.writeFile(Fe.join(e,"package.json"),`{"private":true}
18
+ `),await bp({packageSpec:s.packageSpec,cwd:e,registry:s.registry});try{await ve.rename(e,s.installDir)}catch(t){let n=t;if((n.code==="EEXIST"||n.code==="ENOTEMPTY")&&await It(s.installDir)){await ve.rm(e,{recursive:!0,force:!0}).catch(()=>{}),oo(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version});return}throw t}io(`hydra-acp: installed ${s.agentId} to ${s.installDir}`),oo(s.onProgress,{phase:"installed",agentId:s.agentId,version:s.version})}catch(t){throw await ve.rm(e,{recursive:!0,force:!0}).catch(()=>{}),t}}function oo(s,e){if(s)try{s(e)}catch{}}var kp=5,vp=25;function bp(s){return Ra(s,0)}async function Ra(s,e){try{await new Promise((t,n)=>{let r=s.registry?["--registry",s.registry]:[],o=jt("npm",["install","--no-audit","--no-fund","--silent",...r,s.packageSpec]),i;try{i=yp(o.command,o.args,{cwd:s.cwd,stdio:["ignore","pipe","pipe"],shell:o.shell,windowsHide:!0})}catch(d){n(d);return}let a="";i.stdout?.on("data",d=>{}),i.stderr?.setEncoding("utf8"),i.stderr?.on("data",d=>{a=(a+d).slice(-4096)}),i.on("error",d=>{if(d.code==="ENOENT"){let u=(process.env.PATH??process.env.Path??"").split(hp).filter(l=>l.length>0);n(new Error(`npm not found on PATH: tried to run ${JSON.stringify(o.command)}${o.shell?" through a shell":""} against ${u.length} PATH entries. Install Node.js / npm, or use a binary-distributed agent.`));return}n(d)}),i.on("exit",(d,c)=>{if(d===0){t();return}let u=d!==null?`exit code ${d}`:`signal ${c??"unknown"}`,l=a.trim();n(new Error(l?`npm install ${s.packageSpec} failed (${u})
19
+ stderr: ${l}`:`npm install ${s.packageSpec} failed (${u})`))})})}catch(t){if(t.code==="ETXTBSY"&&e<kp)return await new Promise(r=>setTimeout(r,vp*(e+1))),Ra(s,e+1);throw t}}function Sp(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 Ip(s){let e=s.lastIndexOf("/");return e===-1?s:s.slice(e+1)}async function xa(s,e){let t=Fe.join(s,"node_modules",e,"package.json");try{let n=await ve.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 Aa(s){let e=Fe.join(s.installDir,"node_modules",".bin"),t=Fe.join(e,s.hint);if(await It(t))return{binName:s.hint,binPath:t};let n=await xa(s.installDir,s.packageName);if(typeof n=="object"&&n!==null){let r=Object.keys(n);if(r.length===1){let o=r[0],i=Fe.join(e,o);if(await It(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=Fe.join(e,o);if(await It(i))return{binName:o,binPath:i}}}}if(s.basename!==s.hint){let r=Fe.join(e,s.basename);if(await It(r))return{binName:s.basename,binPath:r}}}async function It(s){try{return await ve.access(s),!0}catch{return!1}}var Ap=W.object({package:W.string(),bin:W.string().optional(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),Ut=W.object({archive:W.string().url().optional(),cmd:W.string().optional(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),Cp=W.object({"darwin-aarch64":Ut.optional(),"darwin-x86_64":Ut.optional(),"linux-aarch64":Ut.optional(),"linux-x86_64":Ut.optional(),"windows-x86_64":Ut.optional(),"windows-aarch64":Ut.optional()}),Rp=W.object({package:W.string(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),xp=W.object({command:W.string(),args:W.array(W.string()).optional(),env:W.record(W.string()).optional()}),Tp=W.object({command:W.string().optional(),url:W.string().optional(),description:W.string().optional()}),Ep=W.object({npx:Ap.optional(),binary:Cp.optional(),uvx:Rp.optional(),exec:xp.optional()}),Pp=W.object({id:W.string(),name:W.string(),version:W.string().optional(),description:W.string().optional(),authors:W.array(W.string()).optional(),license:W.string().optional(),icon:W.string().optional(),repository:W.string().optional(),website:W.string().optional(),distribution:Ep,onboarding:Tp.optional(),requiredEnv:W.array(W.string().min(1)).optional()}),Ta=8;function _a(s){return s.installId??s.id}function uo(s){let e=s.extendsChain;return e&&e.length>0?e[e.length-1]:s.id}function lo(s,e){if(s)for(let t of e.extendsChain??[e.id]){let n=s[t];if(n!==void 0)return{value:n,from:t}}}function $a(s,e){if(!s)return;let t,n;for(let r of[...e.extendsChain??[e.id]].reverse()){let o=s[r];o!==void 0&&(t={...t,...o},n=r)}return t!==void 0&&n!==void 0?{value:t,from:n}:void 0}var Ea=W.object({version:W.string(),agents:W.array(Pp),extensions:W.array(W.unknown()).optional()}),ks=class{constructor(e,t={}){this.config=e;this.options=t}config;options;cache;async load(){if(this.cache&&(this.isPinned()||this.isFresh(this.cache.fetchedAt)))return this.cache.data;let e=await this.readDiskCache();if(e&&(this.isPinned()||this.isFresh(e.fetchedAt)))return this.cache=e,e.data;try{let t=await this.fetchFromNetwork();return this.cache=t,await this.writeDiskCache(t),t.data}catch(t){if(e){let n=this.options.onStaleFallback;if(n)try{n(t,Date.now()-e.fetchedAt)}catch{}return this.cache=e,e.data}throw t}}async refresh(){let e=await this.fetchFromNetwork();return this.cache=e,await this.writeDiskCache(e),e.data}lastFetchedAt(){return this.cache?.fetchedAt}setConfig(e){this.config=e}async getAgent(e){return this.resolveAgent(e,[])}async resolveAgent(e,t){let n=this.findLocalDef(e);if(n){if(n.def.extends===void 0)return{...co(n.id,n.def),extendsChain:[n.id]};if(t.includes(n.id))throw new Error(`agent ${n.id}: extends cycle (${[...t,n.id].join(" -> ")})`);if(t.length+1>=Ta)throw new Error(`agent ${n.id}: extends chain deeper than ${Ta} (${[...t,n.id].join(" -> ")})`);let c=await this.resolveAgent(n.def.extends,[...t,n.id]);if(!c)throw new Error(`agent ${n.id}: extends ${JSON.stringify(n.def.extends)}, which is not a known agent`);return this.applyOverride(_p(n.id,n.def,c))}let r=await this.load(),o=r.agents.find(c=>c.id===e);if(o)return this.applyOverride(o);let i=r.agents.find(c=>fo(c)===e);if(i)return this.applyOverride(i);let a=e.toLowerCase(),d=r.agents.find(c=>c.id.toLowerCase()===`${a}-acp`);if(d)return this.applyOverride(d);if(a.length>0){let c=r.agents.filter(u=>u.id.toLowerCase().startsWith(a));if(c.length===1)return this.applyOverride(c[0])}}findLocalDef(e){let t=this.config.agents??{},n=t[e];if(n)return{id:e,def:n};let r=e.toLowerCase();for(let[o,i]of Object.entries(t))if(o.toLowerCase()===`${r}-acp`)return{id:o,def:i}}localAgents(){return Object.entries(this.config.agents??{}).filter(([,e])=>e.extends===void 0).map(([e,t])=>co(e,t))}async resolvedLocalAgents(){let e=[];for(let t of Object.keys(this.config.agents??{}))try{let n=await this.resolveAgent(t,[]);n&&e.push(n)}catch(n){this.options.onResolveError?.(t,n)}return e}applyOverride(e){let t=e.extendsChain?e:{...e,extendsChain:[e.id]},n=this.config.agentOverrides?.[t.id];if(!n)return t;let r=t.distribution,o=t.version,i=t.installId;return n.packageSpec&&r.npx&&(o=$p(n.packageSpec),i=t.id,r={...r,npx:{...r.npx,package:n.packageSpec}}),n.extraArgs?.length&&(r=Mp(r,n.extraArgs)),n.env&&Object.keys(n.env).length>0&&(r=Oa(r,{env:n.env})),r===t.distribution?t:{...t,version:o,installId:i,distribution:r}}isPinned(){return this.config.registry?.pinned===!0}isFresh(e){let t=Date.now()-e,n=this.config.registry.ttlHours*60*60*1e3;return t<n}async fetchFromNetwork(){let e=await fetch(this.config.registry.url);if(!e.ok)throw new Error(`Registry fetch failed: HTTP ${e.status}`);let t=await e.json(),n=Ea.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 ce(E.registryCache());if(!(!e||typeof e.fetchedAt!="number"||e.data===void 0))try{let t=Ea.parse(e.data);return{fetchedAt:e.fetchedAt,raw:e.data,data:t}}catch{return}}async writeDiskCache(e){await me(E.registryCache(),{fetchedAt:e.fetchedAt,data:e.raw})}};function Fa(s){return s&&Object.fromEntries(Object.entries(s).map(([e,t])=>[e,ie(t)]))}function co(s,e){return{id:s,name:e.name??s,description:e.description,version:"local",distribution:{exec:{command:ie(e.command??s),args:e.args?.map(ie),env:Fa(e.env)}}}}function Oa(s,e){let t=e.args?.map(ie),n=Fa(e.env),r=o=>({...o,...t?{args:t}:{},...n?{env:{...o.env,...n}}:{}});return{...s.npx?{npx:r(s.npx)}:{},...s.uvx?{uvx:r(s.uvx)}:{},...s.exec?{exec:r(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([o,i])=>[o,i&&r(i)]))}:{}}}function Mp(s,e){let t=n=>({...n,args:[...n.args??[],...e]});return{...s.npx?{npx:t(s.npx)}:{},...s.uvx?{uvx:t(s.uvx)}:{},...s.exec?{exec:t(s.exec)}:{},...s.binary?{binary:Object.fromEntries(Object.entries(s.binary).map(([n,r])=>[n,r&&t(r)]))}:{}}}function _p(s,e,t){let n=e.command!==void 0;return{...t,id:s,name:e.name??t.name,description:e.description??t.description,version:n?"local":t.version,distribution:n?co(s,e).distribution:Oa(t.distribution,e),installId:n?s:t.installId??t.id,extendsChain:[s,...t.extendsChain??[t.id]]}}function $p(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 fo(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 Bt(s){let e=typeof s.resolvedLocalAgents=="function"?await s.resolvedLocalAgents():typeof s.localAgents=="function"?s.localAgents():[],t;try{t=await s.load()}catch(i){if(e.length===0)throw i;t={version:"local-only",agents:[]}}let n=new Set(e.map(i=>i.id)),r=[...e,...t.agents.filter(i=>!n.has(i.id))],o=await Promise.all(r.map(async i=>({id:i.id,name:i.name,version:i.version,description:i.description,distributions:Object.keys(i.distribution),installed:await po(i),...i.extendsChain?{extendsChain:i.extendsChain}:{},source:n.has(i.id)?"local":"registry",...i.onboarding?{onboarding:i.onboarding}:{}})));return{version:t.version,fetchedAt:s.lastFetchedAt(),agents:o}}async function po(s){let e=Ue();if(!e)return"no";let t=s.version??"current",n=_a(s);if(s.distribution.exec)return"yes";if(s.distribution.binary){let r=so(s.distribution.binary,e);if(r?.cmd){let o=vs.resolve(E.agentInstallDir(n,e,t),r.cmd);if(await Pa(o))return"yes"}}if(s.distribution.npx){let r=s.distribution.npx,o=r.bin??fo(s)??r.package,i=E.agentNpmInstallDir(n,e,t),a=vs.join(i,"node_modules",".bin",o);if(await Pa(a))return"yes"}return!s.distribution.npx&&!s.distribution.binary&&s.distribution.uvx?"lazy":"no"}async function Pa(s){try{return await Ma.access(s),!0}catch{return!1}}async function Me(s,e=[],t={}){let n=s.version??"current",r=_a(s);if(s.distribution.npx){let o=s.distribution.npx,i=e.length>0?e:o.args??[];if(process.env.HYDRA_ACP_SKIP_NPM_PREFETCH)return{command:"npx",args:["-y",o.package,...i],env:o.env??{},version:n,installId:r};let a=o.bin??fo(s)??o.package,d=t.onInstallProgress;return{command:await Ca({agentId:r,version:n,packageSpec:o.package,bin:a,registry:t.npmRegistry,onProgress:d?u=>d({source:"npm",...u}):void 0}),args:i,env:o.env??{},version:n,installId:r}}if(s.distribution.binary){let o=so(s.distribution.binary);if(!o)throw new Error(`Agent ${s.id} has no binary distribution for ${Ue()??"this platform"}.`);let i=t.onInstallProgress,a=await ba({agentId:r,version:n,target:o,onProgress:i?c=>i({source:"binary",...c}):void 0}),d=e.length>0?e:o.args??[];return{command:a,args:d,env:o.env??{},version:n,installId:r}}if(s.distribution.uvx){let o=s.distribution.uvx,i=e.length>0?e:o.args??[];return{command:"uvx",args:[o.package,...i],env:o.env??{},version:n,installId:r}}if(s.distribution.exec){let o=s.distribution.exec,i=e.length>0?e:o.args??[];return{command:o.command,args:i,env:o.env??{},version:n,installId:r}}throw new Error(`Agent ${s.id} has no usable distribution method.`)}import{spawn as Lp,spawnSync as Hp}from"child_process";import*as Is from"fs";import*as ed from"path";var x={ParseError:-32700,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602,InternalError:-32603,AuthRequired:-32e3,SessionNotFound:-32001,NotAuthorisedToAttach:-32002,MultiClientNotSupported:-32003,AgentNotInstalled:-32005,BundleAlreadyImported:-32010,PermissionDenied:-32011,AlreadyAttached:-32012,StreamNotEnabled:-32013,SessionClosing:-32014};import{z as Y}from"zod";var Na=Y.object({protocolVersion:Y.number().optional(),clientCapabilities:Y.record(Y.unknown()).optional(),clientInfo:Y.object({name:Y.string(),version:Y.string().optional()}).optional()}),Fp=Y.enum(["full","pending_only","none","after_message"]),Da=Y.object({cwd:Y.string(),mcpServers:Y.array(Y.unknown()).optional(),_meta:Y.record(Y.unknown()).optional()}),La=Y.object({upstreamSessionId:Y.string(),agentId:Y.string(),cwd:Y.string(),title:Y.string().optional(),agentArgs:Y.array(Y.string()).optional()}),Ha=Y.object({sessionId:Y.string(),historyPolicy:Fp.default("full"),afterMessageId:Y.string().optional(),afterSeq:Y.number().optional(),clientId:Y.string().optional(),clientInfo:Y.object({name:Y.string(),version:Y.string().optional()}).optional(),_meta:Y.record(Y.unknown()).optional()});import{z as Rn}from"zod";var Wt=Rn.object({selection:Rn.object({text:Rn.string().min(1),responsePartId:Rn.string().optional()}).optional(),contextThroughSeq:Rn.number().optional()});import{z as D}from"zod";var ja=D.object({sessionId:D.string()}),Ua=D.object({cwd:D.string().optional(),cursor:D.string().optional()}),go=D.object({used:D.number().optional(),size:D.number().optional(),costAmount:D.number().optional(),costCurrency:D.string().optional()}),Xv=D.object({sessionId:D.string(),upstreamSessionId:D.string().optional(),cwd:D.string(),workspace:D.object({path:D.string(),sourceCwd:D.string(),label:D.string(),provider:D.string(),snapshot:D.string().optional(),vcs:D.record(D.string(),D.string()).optional()}).optional(),workspaceError:D.string().optional(),title:D.string().optional(),agentId:D.string().optional(),currentModel:D.string().optional(),currentUsage:go.optional(),importedFromMachine:D.string().optional(),importedFromUpstreamSessionId:D.string().optional(),parentSessionId:D.string().optional(),forkedFromSessionId:D.string().optional(),forkedFromMessageId:D.string().optional(),side:Wt.optional(),originatingClient:D.object({name:D.string(),version:D.string().optional()}).optional(),interactive:D.boolean().optional(),priority:D.number().int().nonnegative().optional(),tags:D.array(D.string()).optional(),lastTurnEndedAt:D.number().optional(),readAt:D.number().optional(),unread:D.boolean().optional(),createdAt:D.string().optional(),updatedAt:D.string(),attachedClients:D.number().int().nonnegative(),status:D.enum(["warm","cold"]).default("warm"),busy:D.boolean().default(!1),awaitingInput:D.boolean().default(!1),turnStartedAt:D.number().optional(),armedTasks:D.number().int().nonnegative().optional(),armedSince:D.number().int().positive().optional(),compactionState:D.any().optional(),agentPid:D.number().int().positive().optional(),forkSynthesisState:D.enum(["running","failed"]).optional(),_meta:D.record(D.unknown()).optional()}),Op=D.object({sessionId:D.string(),cwd:D.string(),title:D.string().optional(),updatedAt:D.string().optional(),_meta:D.record(D.unknown()).optional()}),Zv=D.object({sessions:D.array(Op),nextCursor:D.string().optional()});function bs(s,e){let t={attachedClients:s.attachedClients,status:s.status,busy:s.busy,awaitingInput:s.awaitingInput};return s.cwd!==void 0&&(t.cwd=s.cwd),s.workspace!==void 0&&(t.workspaceInfo=s.workspace),s.workspaceError!==void 0&&(t.workspaceError=s.workspaceError),s.title!==void 0&&(t.title=s.title),s.agentId!==void 0&&(t.agentId=s.agentId),s.upstreamSessionId!==void 0&&(t.upstreamSessionId=s.upstreamSessionId),s.createdAt!==void 0&&(t.createdAt=s.createdAt),s.currentModel!==void 0&&(t.currentModel=s.currentModel),s.currentUsage!==void 0&&(t.currentUsage=s.currentUsage),s.importedFromMachine!==void 0&&(t.importedFromMachine=s.importedFromMachine),s.importedFromUpstreamSessionId!==void 0&&(t.importedFromUpstreamSessionId=s.importedFromUpstreamSessionId),s.parentSessionId!==void 0&&(t.parentSessionId=s.parentSessionId),s.forkedFromSessionId!==void 0&&(t.forkedFromSessionId=s.forkedFromSessionId),s.forkedFromMessageId!==void 0&&(t.forkedFromMessageId=s.forkedFromMessageId),s.side!==void 0&&(t.side=s.side),s.originatingClient!==void 0&&(t.originatingClient=s.originatingClient),s.interactive!==void 0&&(t.interactive=s.interactive),s.priority!==void 0&&s.priority>0&&(t.priority=s.priority),s.tags!==void 0&&s.tags.length>0&&(t.tags=s.tags),s.lastTurnEndedAt!==void 0&&(t.lastTurnEndedAt=s.lastTurnEndedAt),s.readAt!==void 0&&(t.readAt=s.readAt),s.unread&&(t.unread=!0),s.armedTasks!==void 0&&(t.armedTasks=s.armedTasks),s.armedSince!==void 0&&(t.armedSince=s.armedSince),s.compactionState!==void 0&&(t.compactionState=s.compactionState),s.forkSynthesisState!==void 0&&(t.forkSynthesisState=s.forkSynthesisState),e&&(e.clientId!==void 0&&(t.clientId=e.clientId),e.currentMode!==void 0&&(t.currentMode=e.currentMode),e.agentArgs!==void 0&&e.agentArgs.length>0&&(t.agentArgs=e.agentArgs),e.availableCommands!==void 0&&e.availableCommands.length>0&&(t.availableCommands=e.availableCommands),e.availableModes!==void 0&&e.availableModes.length>0&&(t.availableModes=e.availableModes),e.availableModels!==void 0&&e.availableModels.length>0&&(t.availableModels=e.availableModels),e.turnStartedAt!==void 0&&(t.turnStartedAt=e.turnStartedAt),e.agentCapabilities!==void 0&&(t.agentCapabilities=e.agentCapabilities),e.queue!==void 0&&e.queue.length>0&&(t.queue=e.queue),e.resurrected===!0&&(t.resurrected=!0),e.armedTaskList!==void 0&&(t.armedTaskList=e.armedTaskList)),t}function Ba(s){let e={sessionId:s.sessionId,cwd:s.cwd,updatedAt:s.updatedAt,_meta:xn(s._meta,bs(s))};return s.title!==void 0&&(e.title=s.title),e}var le="hydra-acp";function Np(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 dt(s){if(!s)return{};let e=s[le];if(!e||typeof e!="object"||Array.isArray(e))return{};let t=e,n={};if(typeof t.upstreamSessionId=="string"&&(n.upstreamSessionId=t.upstreamSessionId),typeof t.agentId=="string"&&(n.agentId=t.agentId),typeof t.cwd=="string"&&(n.cwd=t.cwd),t.workspace!==null&&typeof t.workspace=="object"&&!Array.isArray(t.workspace)){let o=t.workspace,i={};typeof o.label=="string"&&(i.label=o.label),typeof o.from=="string"&&(i.from=o.from),o.required===!0&&(i.required=!0),o.adopt===!0&&(i.adopt=!0),typeof o.provider=="string"&&(i.provider=o.provider),n.workspace=i}if(t.workspaceInfo!==null&&typeof t.workspaceInfo=="object"&&!Array.isArray(t.workspaceInfo)){let o=t.workspaceInfo;if(typeof o.path=="string"&&typeof o.sourceCwd=="string"&&typeof o.label=="string"&&typeof o.provider=="string"){let i={path:o.path,sourceCwd:o.sourceCwd,label:o.label,provider:o.provider};if(typeof o.snapshot=="string"&&(i.snapshot=o.snapshot),o.vcs!==null&&typeof o.vcs=="object"&&!Array.isArray(o.vcs)){let a={};for(let[d,c]of Object.entries(o.vcs))typeof c=="string"&&(a[d]=c);i.vcs=a}n.workspaceInfo=i}}if(typeof t.workspaceError=="string"&&(n.workspaceError=t.workspaceError),typeof t.clientId=="string"&&(n.clientId=t.clientId),typeof t.readonly=="boolean"&&(n.readonly=t.readonly),(t.replayMode==="instant"||t.replayMode==="drip")&&(n.replayMode=t.replayMode),typeof t.dripSpeed=="number"&&t.dripSpeed>0&&(n.dripSpeed=t.dripSpeed),typeof t.historyLimit=="number"&&Number.isFinite(t.historyLimit)&&t.historyLimit>=0&&(n.historyLimit=t.historyLimit),(t.toolContent==="inline"||t.toolContent==="references")&&(n.toolContent=t.toolContent),t.detachStatus==="detached"&&(n.detachStatus=t.detachStatus),typeof t.title=="string"&&(n.title=t.title),Array.isArray(t.agentArgs)&&t.agentArgs.every(o=>typeof o=="string")&&(n.agentArgs=t.agentArgs),Array.isArray(t.transformers)&&t.transformers.every(o=>typeof o=="string")&&(n.transformers=t.transformers),t.resume){let o=La.safeParse(t.resume);o.success&&(n.resume=o.data)}if(typeof t.model=="string"&&(n.model=t.model),typeof t.currentModel=="string"&&(n.currentModel=t.currentModel),typeof t.currentMode=="string"&&(n.currentMode=t.currentMode),t.currentUsage){let o=go.safeParse(t.currentUsage);o.success&&(n.currentUsage=o.data)}if(typeof t.turnStartedAt=="number"&&t.turnStartedAt>0&&(n.turnStartedAt=t.turnStartedAt),typeof t.armedTasks=="number"&&t.armedTasks>=0&&(n.armedTasks=t.armedTasks),typeof t.armedSince=="number"&&t.armedSince>0&&(n.armedSince=t.armedSince),Array.isArray(t.armedTaskList)){let o=[];for(let i of t.armedTaskList){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;typeof a.label!="string"||typeof a.since!="number"||o.push({label:a.label,since:a.since,...typeof a.taskId=="string"?{taskId:a.taskId}:{},...typeof a.taskType=="string"?{taskType:a.taskType}:{},...typeof a.toolCallId=="string"?{toolCallId:a.toolCallId}:{},...a.endUnobservable===!0?{endUnobservable:!0}:{}})}n.armedTaskList=o}if(Array.isArray(t.availableCommands)){let o=[];for(let i of t.availableCommands){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.name!="string")continue;let d={name:a.name};typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableCommands=o)}if(t.prompt&&typeof t.prompt=="object"&&!Array.isArray(t.prompt)){let o=t.prompt,i={};typeof o.queueing=="boolean"&&(i.queueing=o.queueing),typeof o.cancelling=="boolean"&&(i.cancelling=o.cancelling),typeof o.updating=="boolean"&&(i.updating=o.updating),typeof o.amending=="boolean"&&(i.amending=o.amending),typeof o.pipelining=="boolean"&&(i.pipelining=o.pipelining),n.prompt=i}if(t.agents&&typeof t.agents=="object"&&!Array.isArray(t.agents)){let o=t.agents,i={};typeof o.list=="boolean"&&(i.list=o.list),typeof o.installProgress=="boolean"&&(i.installProgress=o.installProgress),n.agents=i}if(typeof t.mcpStdin=="boolean"&&(n.mcpStdin=t.mcpStdin),typeof t.interactive=="boolean"&&(n.interactive=t.interactive),typeof t.elicitationForms=="boolean"&&(n.elicitationForms=t.elicitationForms),typeof t.ancillary=="boolean"&&(n.ancillary=t.ancillary),t.salvaged&&typeof t.salvaged=="object"&&!Array.isArray(t.salvaged)){let o=t.salvaged;typeof o.reason=="string"&&typeof o.supersededMessageId=="string"&&(n.salvaged={reason:o.reason,supersededMessageId:o.supersededMessageId})}if(Array.isArray(t.queue)){let o=[];for(let i of t.queue){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i,d=a.originator;if(typeof a.messageId!="string"||!d||typeof d.clientId!="string"||!Array.isArray(a.prompt)||typeof a.position!="number"||typeof a.enqueuedAt!="number")continue;let c={clientId:d.clientId};typeof d.name=="string"&&(c.name=d.name),typeof d.version=="string"&&(c.version=d.version),o.push({messageId:a.messageId,originator:c,prompt:a.prompt,position:a.position,enqueuedAt:a.enqueuedAt})}o.length>0&&(n.queue=o)}if(Array.isArray(t.availableModes)){let o=[];for(let i of t.availableModes){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.id!="string")continue;let d={id:a.id};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModes=o)}if(Array.isArray(t.availableModels)){let o=[];for(let i of t.availableModels){if(!i||typeof i!="object"||Array.isArray(i))continue;let a=i;if(typeof a.modelId!="string")continue;let d={modelId:a.modelId};typeof a.name=="string"&&(d.name=a.name),typeof a.description=="string"&&(d.description=a.description),o.push(d)}o.length>0&&(n.availableModels=o)}(t.status==="warm"||t.status==="cold")&&(n.status=t.status),typeof t.busy=="boolean"&&(n.busy=t.busy),typeof t.awaitingInput=="boolean"&&(n.awaitingInput=t.awaitingInput),typeof t.attachedClients=="number"&&(n.attachedClients=t.attachedClients),typeof t.resurrected=="boolean"&&(n.resurrected=t.resurrected),typeof t.importedFromMachine=="string"&&(n.importedFromMachine=t.importedFromMachine),typeof t.importedFromUpstreamSessionId=="string"&&(n.importedFromUpstreamSessionId=t.importedFromUpstreamSessionId),typeof t.parentSessionId=="string"&&(n.parentSessionId=t.parentSessionId),typeof t.forkedFromSessionId=="string"&&(n.forkedFromSessionId=t.forkedFromSessionId),typeof t.forkedFromMessageId=="string"&&(n.forkedFromMessageId=t.forkedFromMessageId);let r=Wt.safeParse(t.side);if(r.success&&(n.side=r.data),t.originatingClient&&typeof t.originatingClient=="object"&&!Array.isArray(t.originatingClient)&&typeof t.originatingClient.name=="string"){let o=t.originatingClient;n.originatingClient={name:o.name,...typeof o.version=="string"?{version:o.version}:{}}}if(t.agentCapabilities!==void 0&&(n.agentCapabilities=t.agentCapabilities),t.env!==void 0){let o=Np(t.env);o!==void 0&&(n.env=o)}return n}function Be(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.recordedAt=="number"?s:{...t,_meta:{...n,[le]:{...o,recordedAt:e}}}}function We(s,e){if(typeof e!="number"||!Number.isFinite(e)||!s||typeof s!="object"||Array.isArray(s))return s;let t=s,n=t._meta&&typeof t._meta=="object"&&!Array.isArray(t._meta)?t._meta:{},r=n[le],o=r&&typeof r=="object"&&!Array.isArray(r)?r:{};return typeof o.seq=="number"?s:{...t,_meta:{...n,[le]:{...o,seq:e}}}}function xn(s,e){return{...s??{},[le]:e}}import{z as _}from"zod";var Wa=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.record(_.unknown()).optional()}),Ss=_.object({sessionId:_.string()}),qa=_.object({clientId:_.string(),name:_.string().optional(),version:_.string().optional()}),ib=_.object({sessionId:_.string(),messageId:_.string(),originator:qa,prompt:_.array(_.unknown()),position:_.number().int().nonnegative(),queueDepth:_.number().int().positive(),enqueuedAt:_.number()}),ab=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),db=_.object({sessionId:_.string(),messageId:_.string(),reason:_.enum(["started","cancelled","abandoned"])}),za=_.object({sessionId:_.string(),messageId:_.string()}),cb=_.object({cancelled:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Ja=_.object({sessionId:_.string(),messageId:_.string(),prompt:_.array(_.unknown())}),ub=_.object({updated:_.boolean(),reason:_.enum(["ok","not_found","already_running"])}),Va=_.object({sessionId:_.string(),targetMessageId:_.string(),prompt:_.array(_.unknown()),replaceQueue:_.boolean().optional(),onTargetCompleted:_.enum(["reject","send_anyway"]).optional()}),lb=_.object({amended:_.boolean(),reason:_.enum(["ok","target_completed","target_cancelled","target_not_found"]),messageId:_.string().optional()}),Ga=_.object({sessionId:_.string(),prompt:_.array(_.unknown()),_meta:_.object({steering:_.object({idleBehavior:_.literal("promptRequired").optional()}).optional()}).optional()}),fb=_.object({outcome:_.enum(["injected","startedNewTurn","promptRequired","failed"]),reason:_.literal("noRunningTurn").optional(),detached:_.boolean().optional()}),pb=_.object({sessionId:_.string(),cancelledMessageId:_.string(),newMessageId:_.string(),prompt:_.array(_.unknown()),originator:qa,amendedAt:_.number()});import{z as ct}from"zod";var hb=ct.object({agentId:ct.string(),version:ct.string(),source:ct.enum(["binary","npm"]),phase:ct.enum(["download_start","download_progress","download_done","extract","install_start","installed"]),receivedBytes:ct.number().optional(),totalBytes:ct.number().optional(),packageSpec:ct.string().optional()}),Qa="hydra-acp/agents/install_progress",Ka={auth:{terminal:!0},elicitation:{form:{}},_meta:{"terminal-auth":!0}};function Ya(s){if(s)return Ka;let{elicitation:e,...t}=Ka;return t}function Xa(s,e){let t="",n=[],r=[],o=!1,i=a=>{if(!o){o=!0;for(let d of r)d(a)}};return s.setEncoding("utf8"),s.on("data",a=>{t+=a;let d=t.indexOf(`
20
20
  `);for(;d!==-1;){let c=t.slice(0,d).trim();if(t=t.slice(d+1),c.length>0)try{let u=JSON.parse(c);for(let l of n)l(u)}catch(u){for(let l of n)l({jsonrpc:"2.0",id:null,error:{code:x.ParseError,message:`Failed to parse ndjson line: ${u.message}`}})}d=t.indexOf(`
21
21
  `)}}),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)+`
22
- `;await new Promise((c,u)=>{e.write(d,l=>{if(l){u(l);return}c()})})},onMessage(a){n.push(a)},onClose(a){r.push(a)},async close(){e.end(),i()}}}import{nanoid as hp}from"nanoid";var so=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},We=class s{constructor(e){this.stream=e;this.stream.onMessage(t=>this.handleIncoming(t)),this.stream.onClose(t=>this.handleClose(t))}stream;requestHandlers=new Map;defaultRequestHandler;notificationHandlers=new Map;paramsRewriter;anyNotificationHandlers=[];bufferedNotifications=new Map;static MAX_BUFFERED_PER_METHOD=64;static MAX_BUFFERED_METHODS=256;pending=new Map;closed=!1;closeHandlers=[];orphanErrorHandlers=[];onRequest(e,t){this.requestHandlers.set(e,t)}setDefaultHandler(e){this.defaultRequestHandler=e}setParamsRewriter(e){this.paramsRewriter=e}onNotification(e,t){this.notificationHandlers.set(e,t);let n=this.bufferedNotifications.get(e);if(n){this.bufferedNotifications.delete(e);for(let r of n)try{t(r.params,r.method)}catch{}}}drainBuffered(e){let n=this.bufferedNotifications.get(e)?.length??0;return this.bufferedNotifications.delete(e),n}dropBufferedWhere(e,t){let n=this.bufferedNotifications.get(e);if(!n)return 0;let r=n.filter(o=>!t(o.params));return r.length>0?this.bufferedNotifications.set(e,r):this.bufferedNotifications.delete(e),n.length-r.length}onAnyNotification(e){this.anyNotificationHandlers.push(e)}onClose(e){this.closeHandlers.push(e)}isClosed(){return this.closed}onOrphanError(e){this.orphanErrorHandlers.push(e)}async request(e,t){return this.requestWithId(e,t).response}requestWithId(e,t){if(this.closed)throw new so;let n=hp(),r={jsonrpc:"2.0",id:n,method:e,params:t},o=new Promise((i,a)=>{this.pending.set(n,{resolve:d=>i(d),reject:a}),this.stream.send(r).catch(d=>{this.pending.delete(n),a(d)})});return{id:n,response:o}}notify(e,t){if(this.closed)return Promise.resolve();let n={jsonrpc:"2.0",method:e,params:t};return this.stream.send(n)}async close(){this.closed||await this.stream.close()}fail(e){this.handleClose(e)}handleIncoming(e){"method"in e?(this.paramsRewriter&&(e={...e,params:this.paramsRewriter(e.params,e.method)}),"id"in e&&e.id!==void 0?this.handleRequest(e).catch(()=>{}):this.handleNotification(e)):"id"in e?this.handleResponse(e):"error"in e&&this.handleResponse(e)}async handleRequest(e){let t=this.requestHandlers.get(e.method)??this.defaultRequestHandler;if(!t){await this.sendError(e.id,{code:x.MethodNotFound,message:`Method not found: ${e.method}`}).catch(()=>{});return}try{let n=await t(e.params,e.method),r={jsonrpc:"2.0",id:e.id,result:n};await this.stream.send(r).catch(()=>{})}catch(n){let r=n;await this.sendError(e.id,{code:r.code??x.InternalError,message:r.message,data:r.data}).catch(()=>{})}}handleNotification(e){for(let r of this.anyNotificationHandlers)try{r(e.params,e.method)}catch{}let t=this.notificationHandlers.get(e.method);if(t){t(e.params,e.method);return}let n=this.bufferedNotifications.get(e.method);if(!n){if(this.bufferedNotifications.size>=s.MAX_BUFFERED_METHODS){let r=this.bufferedNotifications.keys().next().value;r!==void 0&&this.bufferedNotifications.delete(r)}n=[],this.bufferedNotifications.set(e.method,n)}n.push(e),n.length>s.MAX_BUFFERED_PER_METHOD&&n.shift()}handleResponse(e){let t=e.id===null?void 0:this.pending.get(e.id);if(!t){if(e.error)for(let n of this.orphanErrorHandlers)try{n({code:e.error.code,message:e.error.message,data:e.error.data})}catch{}return}if(this.pending.delete(e.id),e.error){let n=new Error(e.error.message);n.code=e.error.code,n.data=e.error.data,t.reject(n)}else t.resolve(e.result)}async sendError(e,t){let n={jsonrpc:"2.0",id:e,error:t};await this.stream.send(n)}handleClose(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e??new Error("connection closed"));this.pending.clear();for(let t of this.closeHandlers)t(e)}}};Q();var kp=4096,ct=class s{agentId;version;installId;cwd;connection;authMethods;steeringSupported;child;get pid(){return this.child.pid}exited=!1;killed=!1;stderrTail="";stderrTailBytes;killEscalationMs;logger;fileLog;exitHandlers=[];constructor(e,t){if(this.agentId=e.agentId,this.version=e.plan.version,this.installId=e.plan.installId??e.agentId,this.cwd=e.cwd,this.child=t,this.stderrTailBytes=e.stderrTailBytes??kp,this.killEscalationMs=e.killEscalationMs??vp,this.logger=e.logger,this.fileLog=bp(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()} ---
23
- `),!t.stdout||!t.stdin)throw new Error("agent subprocess missing stdio");let n=Na(t.stdout,t.stdin);this.connection=new We(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()} ---
22
+ `;await new Promise((c,u)=>{e.write(d,l=>{if(l){u(l);return}c()})})},onMessage(a){n.push(a)},onClose(a){r.push(a)},async close(){e.end(),i()}}}import{nanoid as Dp}from"nanoid";var mo=class extends Error{code="ERR_CONNECTION_CLOSED";constructor(e="connection is closed"){super(e),this.name="ConnectionClosedError"}},qe=class s{constructor(e){this.stream=e;this.stream.onMessage(t=>this.handleIncoming(t)),this.stream.onClose(t=>this.handleClose(t))}stream;requestHandlers=new Map;defaultRequestHandler;notificationHandlers=new Map;paramsRewriter;anyNotificationHandlers=[];bufferedNotifications=new Map;static MAX_BUFFERED_PER_METHOD=64;static MAX_BUFFERED_METHODS=256;pending=new Map;closed=!1;closeHandlers=[];orphanErrorHandlers=[];onRequest(e,t){this.requestHandlers.set(e,t)}setDefaultHandler(e){this.defaultRequestHandler=e}setParamsRewriter(e){this.paramsRewriter=e}onNotification(e,t){this.notificationHandlers.set(e,t);let n=this.bufferedNotifications.get(e);if(n){this.bufferedNotifications.delete(e);for(let r of n)try{t(r.params,r.method)}catch{}}}drainBuffered(e){let n=this.bufferedNotifications.get(e)?.length??0;return this.bufferedNotifications.delete(e),n}dropBufferedWhere(e,t){let n=this.bufferedNotifications.get(e);if(!n)return 0;let r=n.filter(o=>!t(o.params));return r.length>0?this.bufferedNotifications.set(e,r):this.bufferedNotifications.delete(e),n.length-r.length}onAnyNotification(e){this.anyNotificationHandlers.push(e)}onClose(e){this.closeHandlers.push(e)}isClosed(){return this.closed}onOrphanError(e){this.orphanErrorHandlers.push(e)}async request(e,t){return this.requestWithId(e,t).response}requestWithId(e,t){if(this.closed)throw new mo;let n=Dp(),r={jsonrpc:"2.0",id:n,method:e,params:t},o=new Promise((i,a)=>{this.pending.set(n,{resolve:d=>i(d),reject:a}),this.stream.send(r).catch(d=>{this.pending.delete(n),a(d)})});return{id:n,response:o}}notify(e,t){if(this.closed)return Promise.resolve();let n={jsonrpc:"2.0",method:e,params:t};return this.stream.send(n)}async close(){this.closed||await this.stream.close()}fail(e){this.handleClose(e)}handleIncoming(e){"method"in e?(this.paramsRewriter&&(e={...e,params:this.paramsRewriter(e.params,e.method)}),"id"in e&&e.id!==void 0?this.handleRequest(e).catch(()=>{}):this.handleNotification(e)):"id"in e?this.handleResponse(e):"error"in e&&this.handleResponse(e)}async handleRequest(e){let t=this.requestHandlers.get(e.method)??this.defaultRequestHandler;if(!t){await this.sendError(e.id,{code:x.MethodNotFound,message:`Method not found: ${e.method}`}).catch(()=>{});return}try{let n=await t(e.params,e.method),r={jsonrpc:"2.0",id:e.id,result:n};await this.stream.send(r).catch(()=>{})}catch(n){let r=n;await this.sendError(e.id,{code:r.code??x.InternalError,message:r.message,data:r.data}).catch(()=>{})}}handleNotification(e){for(let r of this.anyNotificationHandlers)try{r(e.params,e.method)}catch{}let t=this.notificationHandlers.get(e.method);if(t){t(e.params,e.method);return}let n=this.bufferedNotifications.get(e.method);if(!n){if(this.bufferedNotifications.size>=s.MAX_BUFFERED_METHODS){let r=this.bufferedNotifications.keys().next().value;r!==void 0&&this.bufferedNotifications.delete(r)}n=[],this.bufferedNotifications.set(e.method,n)}n.push(e),n.length>s.MAX_BUFFERED_PER_METHOD&&n.shift()}handleResponse(e){let t=e.id===null?void 0:this.pending.get(e.id);if(!t){if(e.error)for(let n of this.orphanErrorHandlers)try{n({code:e.error.code,message:e.error.message,data:e.error.data})}catch{}return}if(this.pending.delete(e.id),e.error){let n=new Error(e.error.message);n.code=e.error.code,n.data=e.error.data,t.reject(n)}else t.resolve(e.result)}async sendError(e,t){let n={jsonrpc:"2.0",id:e,error:t};await this.stream.send(n)}handleClose(e){if(!this.closed){this.closed=!0;for(let t of this.pending.values())t.reject(e??new Error("connection closed"));this.pending.clear();for(let t of this.closeHandlers)t(e)}}};Q();var jp=4096,ut=class s{agentId;version;installId;cwd;connection;authMethods;steeringSupported;child;get pid(){return this.child.pid}exited=!1;killed=!1;stderrTail="";stderrTailBytes;killEscalationMs;logger;fileLog;exitHandlers=[];constructor(e,t){if(this.agentId=e.agentId,this.version=e.plan.version,this.installId=e.plan.installId??e.agentId,this.cwd=e.cwd,this.child=t,this.stderrTailBytes=e.stderrTailBytes??jp,this.killEscalationMs=e.killEscalationMs??Up,this.logger=e.logger,this.fileLog=Bp(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()} ---
23
+ `),!t.stdout||!t.stdin)throw new Error("agent subprocess missing stdio");let n=Xa(t.stdout,t.stdin);this.connection=new qe(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()} ---
24
24
  `),t.pid===void 0&&(this.fileLog?.end(),this.fileLog=void 0),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()} ---
25
25
  `),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}
26
- stderr: ${t}`:e}stderrTailText(){return this.stderrTail.trim()}static spawn(e){let t={...us(),...e.plan.env,...e.extraEnv??{}},n=Dt(e.plan.command,e.plan.args),r=yp(n.command,n.args,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],shell:n.shell,windowsHide:!0,detached:process.platform!=="win32"});return r.unref(),new s(e,r)}onExit(e){this.exitHandlers.push(e)}isAlive(){return!this.exited}async kill(e="SIGTERM"){this.exited||(this.killed=!0,this.writeLog(`--- kill requested signal=${e} time=${new Date().toISOString()} ---
26
+ stderr: ${t}`:e}stderrTailText(){return this.stderrTail.trim()}static spawn(e){let t={...hs(),...e.plan.env,...e.extraEnv??{}},n=jt(e.plan.command,e.plan.args),r=Lp(n.command,n.args,{cwd:e.cwd,env:t,stdio:["pipe","pipe","pipe"],shell:n.shell,windowsHide:!0,detached:process.platform!=="win32"});return r.unref(),new s(e,r)}onExit(e){this.exitHandlers.push(e)}isAlive(){return!this.exited}async kill(e="SIGTERM"){this.exited||(this.killed=!0,this.writeLog(`--- kill requested signal=${e} time=${new Date().toISOString()} ---
27
27
  `),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()} ---
28
- `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(Da),this.exited||this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} still has not exited ${Da}ms after SIGKILL; giving up on the reap`)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0){if(process.platform==="win32"){try{wp("taskkill",["/pid",String(t),"/T","/F"],{stdio:"ignore",windowsHide:!0})}catch{try{this.child.kill()}catch{}}return}try{process.kill(-t,e)}catch{try{this.child.kill(e)}catch{}}}}waitForExit(e){return this.exited?Promise.resolve():new Promise(t=>{let n=setTimeout(()=>{this.child.off("exit",r),t()},e),r=()=>{clearTimeout(n),t()};this.child.once("exit",r)})}},vp=2e3,Da=5e3;function bp(s){try{let e=E.agentLogFile(s);ys.mkdirSync(Ha.dirname(e),{recursive:!0});let t=ys.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}function ws(s){if(s.length===0)return s;let e=new Map,t=new Map,n=new Map;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=ro(d);if(c?.sessionUpdate!=="tool_call_update")continue;let u=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(u!==void 0){e.set(u,a);for(let l of Rp){if(!ja(c[l]))continue;let w=n.get(u);w===void 0?n.set(u,new Map([[l,c[l]]])):w.set(l,c[l])}Array.isArray(c.content)&&c.content.length>0&&t.set(u,c.content)}}let r=[],o=null,i=null;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=ro(d);if(!c||typeof c.sessionUpdate!="string"){r.push(d),o=null;continue}let u=c.sessionUpdate;if(u==="agent_message_chunk"||u==="agent_thought_chunk"||u==="user_message_chunk"){o&&o.kind===u?(Ap(r,o.outIndex,Sp(c.content)),Ip(r,o.outIndex,d.seq)):(r.push(d),o={outIndex:r.length-1,kind:u});continue}if(o=null,u==="tool_call_update"){let l=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(l!==void 0&&e.get(l)!==a)continue;let w=l!==void 0&&t.has(l)?Cp(d,t.get(l)??[]):d,h=l===void 0?void 0:n.get(l);if(h!==void 0)for(let[f,k]of h)ja(ro(w)?.[f])||(w=xp(w,f,k));r.push(w);continue}if(u==="plan"){i!==null?r[i]=d:(r.push(d),i=r.length-1);continue}(u==="prompt_received"||u==="turn_complete")&&(i=null),r.push(d)}return r}function ro(s){if(s.method!=="session/update")return;let t=s.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Sp(s){if(!s||typeof s!="object")return"";let e=s;return typeof e.text=="string"?e.text:""}function Ip(s,e,t){let n=s[e];n===void 0||typeof t!="number"||n.seq!==void 0&&n.seq>=t||(s[e]={...n,seq:t})}function Ap(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 Cp(s,e){let t=s.params??{},n=t.update??{};return{...s,params:{...t,update:{...n,content:e}}}}var Rp=["rawInput","locations"];function ja(s){return s==null||typeof s!="object"?!1:Array.isArray(s)?s.length>0:Object.keys(s).length>0}function xp(s,e,t){let n=s.params??{},r=n.update??{};return{...s,params:{...n,update:{...r,[e]:t}}}}function Bt(s,e){let t=e?.contextThroughSeq;return t===void 0?[...s]:s.filter(n=>n.seq===void 0||n.seq>t)}function Ua(s){let e;for(let t of s)t.seq!==void 0&&(e===void 0||t.seq>e)&&(e=t.seq);return e===void 0?{}:{contextThroughSeq:e}}import*as Tt from"fs/promises";import*as jc from"os";import*as La from"os";function St(){return La.hostname()}import*as qn from"path";import{customAlphabet as Oh}from"nanoid";var qe="session/set_model",io="session/set_config_option",qa="model";function oo(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.availableModels)}function za(s){return Array.isArray(s)&&s.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===qa)}function Wt(s){if(!s)return;if(oo(s)||oo(s.models))return qe;let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,n]of Object.entries(e))if(t!=="hydra-acp"&&oo(n))return qe}if(za(s.configOptions))return io}function Ja(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.sessionUpdate;if(e==="_hydra_current_model_update")return qe;if(e==="config_option_update"&&za(s.configOptions))return io}function Ba(s){return typeof s=="object"&&s!==null&&s.code===x.MethodNotFound}function Wa(s,e,t,n){let r={...n??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,s===qe?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:qa,value:t}}function Tp(s){return s===qe?io:qe}async function ut(s){let{request:e,sessionId:t,modelId:n,extraParams:r,logger:o}=s,i=s.verb??qe;try{let a=await e(i,Wa(i,t,n,r));return{verb:i,result:a}}catch(a){if(!Ba(a))throw a;let d=Tp(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(n)}`);try{let c=await e(d,Wa(d,t,n,r));return{verb:d,result:c}}catch(c){throw Ba(c)?a:c}}}async function lt(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 ft(s){let{agent:e,upstreamSessionId:t,persistedModel:n,agentReportedModel:r,modelVerb:o,logger:i}=s;if(!n)return{modelId:r};if(n===r)return{modelId:n};try{i?.info(`resurrect: pushing persisted modelId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`);let{verb:a,result:d}=await ut({request:(c,u)=>e.connection.request(c,u),sessionId:t,modelId:n,...o?{verb:o}:{},logger:i});return i?.info(`resurrect: ${a} accepted, effectiveModel=${JSON.stringify(n)}`),{modelId:n,result:d}}catch(a){return i?.warn(`resurrect: session/set_model rejected by agent for modelId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),{modelId:r}}}var qt=class{started=performance.now();last=this.started;phases=[];mark(e){let t=performance.now();this.phases.push([e,t-this.last]),this.last=t}absorb(e,t){for(let[n,r]of t.phases)this.phases.push([`${e}.${n}`,r]);this.last=performance.now()}totalMs(){return performance.now()-this.started}summary(){let e=this.phases.map(([t,n])=>`${t}=${Math.round(n)}ms`);return`total=${Math.round(this.totalMs())}ms ${e.join(" ")}`}};var Va="edit",ks=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 Ga(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(t===null||typeof t!="object")continue;let n=t.path;typeof n=="string"&&n.length>0&&e.push(n)}return e}function ao(s){let e=[],t=[],n=!1;for(let r of s.split(`
28
+ `),this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} did not exit after ${e}; sending SIGKILL`),this.signalProcessGroup("SIGKILL"),await this.waitForExit(Za),this.exited||this.logger?.warn(`agent ${this.agentId} pid=${this.child.pid} still has not exited ${Za}ms after SIGKILL; giving up on the reap`)))}signalProcessGroup(e){let t=this.child.pid;if(t!==void 0){if(process.platform==="win32"){try{Hp("taskkill",["/pid",String(t),"/T","/F"],{stdio:"ignore",windowsHide:!0})}catch{try{this.child.kill()}catch{}}return}try{process.kill(-t,e)}catch{try{this.child.kill(e)}catch{}}}}waitForExit(e){return this.exited?Promise.resolve():new Promise(t=>{let n=setTimeout(()=>{this.child.off("exit",r),t()},e),r=()=>{clearTimeout(n),t()};this.child.once("exit",r)})}},Up=2e3,Za=5e3;function Bp(s){try{let e=E.agentLogFile(s);Is.mkdirSync(ed.dirname(e),{recursive:!0});let t=Is.createWriteStream(e,{flags:"a"});return t.on("error",()=>{}),t}catch{return}}function As(s){if(s.length===0)return s;let e=new Map,t=new Map,n=new Map;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=ho(d);if(c?.sessionUpdate!=="tool_call_update")continue;let u=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(u!==void 0){e.set(u,a);for(let l of Vp){if(!td(c[l]))continue;let y=n.get(u);y===void 0?n.set(u,new Map([[l,c[l]]])):y.set(l,c[l])}Array.isArray(c.content)&&c.content.length>0&&t.set(u,c.content)}}let r=[],o=null,i=null;for(let a=0;a<s.length;a++){let d=s[a];if(d===void 0)continue;let c=ho(d);if(!c||typeof c.sessionUpdate!="string"){r.push(d),o=null;continue}let u=c.sessionUpdate;if(u==="agent_message_chunk"||u==="agent_thought_chunk"||u==="user_message_chunk"){o&&o.kind===u?(zp(r,o.outIndex,Wp(c.content)),qp(r,o.outIndex,d.seq)):(r.push(d),o={outIndex:r.length-1,kind:u});continue}if(o=null,u==="tool_call_update"){let l=typeof c.toolCallId=="string"?c.toolCallId:void 0;if(l!==void 0&&e.get(l)!==a)continue;let y=l!==void 0&&t.has(l)?Jp(d,t.get(l)??[]):d,h=l===void 0?void 0:n.get(l);if(h!==void 0)for(let[f,k]of h)td(ho(y)?.[f])||(y=Gp(y,f,k));r.push(y);continue}if(u==="plan"){i!==null?r[i]=d:(r.push(d),i=r.length-1);continue}(u==="prompt_received"||u==="turn_complete")&&(i=null),r.push(d)}return r}function ho(s){if(s.method!=="session/update")return;let t=s.params?.update;if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function Wp(s){if(!s||typeof s!="object")return"";let e=s;return typeof e.text=="string"?e.text:""}function qp(s,e,t){let n=s[e];n===void 0||typeof t!="number"||n.seq!==void 0&&n.seq>=t||(s[e]={...n,seq:t})}function zp(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 Jp(s,e){let t=s.params??{},n=t.update??{};return{...s,params:{...t,update:{...n,content:e}}}}var Vp=["rawInput","locations"];function td(s){return s==null||typeof s!="object"?!1:Array.isArray(s)?s.length>0:Object.keys(s).length>0}function Gp(s,e,t){let n=s.params??{},r=n.update??{};return{...s,params:{...n,update:{...r,[e]:t}}}}function qt(s,e){let t=e?.contextThroughSeq;return t===void 0?[...s]:s.filter(n=>n.seq===void 0||n.seq>t)}function nd(s){let e;for(let t of s)t.seq!==void 0&&(e===void 0||t.seq>e)&&(e=t.seq);return e===void 0?{}:{contextThroughSeq:e}}import*as Mt from"fs/promises";import*as iu from"os";import*as sd from"os";function At(){return sd.hostname()}import*as Qn from"path";import{customAlphabet as iy}from"nanoid";var ze="session/set_model",wo="session/set_config_option",id="model";function yo(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.availableModels)}function ad(s){return Array.isArray(s)&&s.some(e=>e!==null&&typeof e=="object"&&!Array.isArray(e)&&e.id===id)}function zt(s){if(!s)return;if(yo(s)||yo(s.models))return ze;let e=s._meta;if(e&&typeof e=="object"&&!Array.isArray(e)){for(let[t,n]of Object.entries(e))if(t!=="hydra-acp"&&yo(n))return ze}if(ad(s.configOptions))return wo}function dd(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.sessionUpdate;if(e==="_hydra_current_model_update")return ze;if(e==="config_option_update"&&ad(s.configOptions))return wo}function rd(s){return typeof s=="object"&&s!==null&&s.code===x.MethodNotFound}function od(s,e,t,n){let r={...n??{}};return delete r.sessionId,delete r.modelId,delete r.configId,delete r.value,s===ze?{...r,sessionId:e,modelId:t}:{...r,sessionId:e,configId:id,value:t}}function Kp(s){return s===ze?wo:ze}async function lt(s){let{request:e,sessionId:t,modelId:n,extraParams:r,logger:o}=s,i=s.verb??ze;try{let a=await e(i,od(i,t,n,r));return{verb:i,result:a}}catch(a){if(!rd(a))throw a;let d=Kp(i);o?.info(`agent does not implement ${i} (MethodNotFound); retrying model change via ${d} modelId=${JSON.stringify(n)}`);try{let c=await e(d,od(d,t,n,r));return{verb:d,result:c}}catch(c){throw rd(c)?a:c}}}async function ft(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 pt(s){let{agent:e,upstreamSessionId:t,persistedModel:n,agentReportedModel:r,modelVerb:o,logger:i}=s;if(!n)return{modelId:r};if(n===r)return{modelId:n};try{i?.info(`resurrect: pushing persisted modelId=${JSON.stringify(n)} to agent (agentReported=${JSON.stringify(r)})`);let{verb:a,result:d}=await lt({request:(c,u)=>e.connection.request(c,u),sessionId:t,modelId:n,...o?{verb:o}:{},logger:i});return i?.info(`resurrect: ${a} accepted, effectiveModel=${JSON.stringify(n)}`),{modelId:n,result:d}}catch(a){return i?.warn(`resurrect: session/set_model rejected by agent for modelId=${JSON.stringify(n)} (${a.message}); session will use ${JSON.stringify(r)}`),{modelId:r}}}var Jt=class{started=performance.now();last=this.started;phases=[];mark(e){let t=performance.now();this.phases.push([e,t-this.last]),this.last=t}absorb(e,t){for(let[n,r]of t.phases)this.phases.push([`${e}.${n}`,r]);this.last=performance.now()}totalMs(){return performance.now()-this.started}summary(){let e=this.phases.map(([t,n])=>`${t}=${Math.round(n)}ms`);return`total=${Math.round(this.totalMs())}ms ${e.join(" ")}`}};var cd="edit",Cs=class{kinds=new Map;note(e,t){t!==void 0&&t.length>0&&!this.kinds.has(e)&&this.kinds.set(e,t)}get(e){return this.kinds.get(e)}effective(e,t){return t!==void 0&&t.length>0?t:this.kinds.get(e)}clear(){this.kinds.clear()}get size(){return this.kinds.size}};function ud(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(t===null||typeof t!="object")continue;let n=t.path;typeof n=="string"&&n.length>0&&e.push(n)}return e}function ko(s){let e=[],t=[],n=!1;for(let r of s.split(`
29
29
  `)){if(r.startsWith("@@")){n=!0;continue}if(!n||r.startsWith("\\"))continue;let o=r.slice(1);r.startsWith("-")?e.push(o):r.startsWith("+")?t.push(o):r.startsWith(" ")&&(e.push(o),t.push(o))}return{oldText:e.length>0?e.join(`
30
30
  `)+`
31
31
  `:"",newText:t.length>0?t.join(`
32
32
  `)+`
33
- `:""}}function Ka(s){if(s===null||typeof s!="object")return[];let e=s.rawOutput;if(e===null||typeof e!="object")return[];let t=e.metadata;if(t===null||typeof t!="object")return[];let n=t.files;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(o===null||typeof o!="object")continue;let i=o,a=typeof i.filePath=="string"&&i.filePath.length>0?i.filePath:i.file;if(typeof a!="string"||a.length===0)continue;let d=i.patch,c=d!==null&&typeof d=="object"?d:void 0;r.push({path:a,...typeof i.additions=="number"?{added:i.additions}:{},...typeof i.deletions=="number"?{removed:i.deletions}:{},...typeof d=="string"?{patch:d}:{},...typeof c?.__hydraBlob=="string"?{patchRef:{hash:c.__hydraBlob,bytes:typeof c.bytes=="number"?c.bytes:0}}:{}})}return r}function It(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 vs(s){let e=s.rawInput;return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function co(s){return typeof s.file_path=="string"?s.file_path:typeof s.path=="string"?s.path:void 0}function bs(s){let e=s.content;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(r.type!=="diff")continue;let o=It(r.oldText),i=It(r.newText);o===void 0&&i===void 0||t.push({...typeof r.path=="string"?{path:r.path}:{},...o?{old:o}:{},...i?{new:i}:{}})}return t}function Ss(s){let e=vs(s);if(!e)return;let t=co(e);if(e.old_string!==void 0||e.new_string!==void 0){let n=It(e.old_string),r=It(e.new_string);return{...t!==void 0?{path:t}:{},...n?{old:n}:{},...r?{new:r}:{}}}if(e.content!==void 0){let n=It(e.content);return{...t!==void 0?{path:t}:{},old:{text:""},...n?{new:n}:{}}}}function Ep(s){let e=vs(s),t=e?co(e):void 0;if(!e||t===void 0||!Array.isArray(e.edits))return[];let n=[];for(let r of e.edits){if(!r||typeof r!="object")continue;let o=r,i=It(o.old_string),a=It(o.new_string);i===void 0||a===void 0||n.push({path:t,old:i,new:a})}return n}function Qa(s){return Ka(s).map(e=>({path:e.path,...e.patch!==void 0?{patch:{text:e.patch}}:{},...e.patchRef!==void 0?{patch:{ref:e.patchRef}}:{}}))}function Is(s){let e=Ep(s);if(e.length>0)return e.map(r=>({...r,scope:"snippet"}));let t=bs(s).filter(r=>r.path!==void 0);if(t.length>0){let r=Pp(s);return r===void 0?t:t.map(o=>({...o,scope:r}))}let n=Ss(s);return n?.path!==void 0?[{...n,scope:n.old?.text===""?"file":"snippet"}]:Qa(s).map(r=>({...r,scope:"snippet"}))}function Pp(s){let e=vs(s);return e&&(e.old_string!==void 0||e.new_string!==void 0)?"snippet":e&&e.content!==void 0||Mp(s)?"file":void 0}function Mp(s){let e=s.rawOutput;return Array.isArray(e?.metadata?.files)}function Ya(s){let e=new Set,t=vs(s),n=[...bs(s).map(r=>r.path),Ss(s)?.path,t&&Array.isArray(t.edits)?co(t):void 0,...Qa(s).map(r=>r.path)];for(let r of n)typeof r=="string"&&r.length>0&&e.add(r);return[...e]}function Xa(s){return s.patch!==void 0?s.patch.text!==void 0?ao(s.patch.text):{oldText:"",newText:""}:{oldText:s.old?.text??"",newText:s.new?.text??""}}Q();import{posix as _p}from"path";import $p from"strip-ansi";function In(s){if(!s||typeof s!="object")return;let e=s;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}function uo(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.parentToolUseId;return typeof n=="string"?n:void 0}var Op=/[\x00-\x08\x0b-\x1f\x7f]/g;function be(s){return $p(s).replace(Op,"")}function ae(s){return be(s).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function nd(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 Lp(t);case"agent_thought_chunk":case"agent_thought":return Bp(t);case"user_message_chunk":return Wp(t);case"prompt_received":return qp(t);case"tool_call":return zp(t,e);case"tool_call_update":return Qp(t,e);case"plan":return eg(t);case"current_mode_update":return tg(t);case"_hydra_current_model_update":return ng(t);case"turn_complete":return sg(t);case"_hydra_turn_started":return td(t,"turn-started");case"_hydra_turn_ended":return td(t,"turn-ended");case"usage_update":return Up(t);case"available_commands_update":return Hp(t);case"_hydra_available_modes_update":return jp(t);case"session_info_update":return Np(t);case"config_option_update":return Fp(t);default:return{kind:"unknown",sessionUpdate:n,raw:s}}}function Fp(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 Np(s){let e=re(s,"title"),t=e!==void 0?ae(e):void 0,n=s._meta,r,o;if(n&&typeof n=="object"&&!Array.isArray(n)){let a=n["hydra-acp"];if(a&&typeof a=="object"&&!Array.isArray(a)){let d=a.agentId;if(typeof d=="string"&&(r=d),"pendingAgentSwap"in a){let c=a.pendingAgentSwap;typeof c=="string"?o=c:c===null&&(o=null)}}}if(t===void 0&&r===void 0&&o===void 0)return null;let i={kind:"session-info"};return t!==void 0&&(i.title=t),r!==void 0&&(i.agentId=r),o!==void 0&&(i.pendingAgentSwap=o),i}function Dp(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:ae(r)};typeof n.description=="string"&&(o.description=ae(n.description)),e.push(o)}return e}function Hp(s){let e=s.availableCommands??s.commands;return Array.isArray(e)?{kind:"available-commands",commands:Dp(e)}:null}function jp(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:ae(r.id)};typeof r.name=="string"&&(o.name=ae(r.name)),typeof r.description=="string"&&(o.description=ae(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function Up(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 Lp(s){let e=An(s.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:In(s)}}function Bp(s){let e=typeof s.text=="string"?be(s.text):An(s.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:In(s)}}function Wp(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=An(s.content);return t===null?null:{kind:"user-text",text:t}}function qp(s){let e=rg(s.prompt);return e===null?null:{kind:"user-text",text:e}}function sd(s){return s?s.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function rd(s){let e=bs(s)[0];if(e)return Za(e);let t=Ss(s);return t?.old?.text!==void 0&&t.new?.text!==void 0?Za(t):null}function Za(s){return{...s.path!==void 0?{path:s.path}:{},oldText:s.old?.text??"",newText:s.new?.text??"",...s.old?.ref?{oldRef:s.old.ref}:{},...s.new?.ref?{newRef:s.new.ref}:{}}}function od(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:be(t)}function zp(s,e={}){let t=re(s,"toolCallId")??re(s,"id");if(!t)return null;let n=re(s,"title")??re(s,"name")??re(s,"label")??"tool call",r=re(s,"name")??re(s,"title");if(sd(r)){let k=od(s);if(k!==null){let p=re(s,"status"),g={kind:"exit-plan-mode",toolCallId:t,plan:k};return p!==void 0&&(g.status=p),g}}let o=dd(ae(n),s,e),i=re(s,"status"),a=re(s,"kind"),d={kind:"tool-call",toolCallId:t,title:o};i!==void 0&&(d.status=i),a!==void 0&&(d.rawKind=a);let c=rd(s);c!==null&&(d.editDiff=c);let u=ad(s);u!==void 0&&(d.detail=u);let l=lo(s);l!==void 0&&(d.detailFull=l);let w=id(s);w!==void 0&&(d.locations=w);let h=In(s);h!==void 0&&(d.workerTaskId=h);let f=uo(s);return f!==void 0&&(d.parentToolUseId=f),d}function id(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 ed=64;function ad(s){let e=lo(s);if(e===void 0)return;let t=ae(e),n=s.rawInput;return n&&typeof n.command=="string"?Gp(t,ed):Kp(t,ed)}function lo(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 be(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(ae(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(ae(n))}}}var Jp=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function Vp(s){for(let e of Jp)if(s.startsWith(e))return!0;return!1}function dd(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 Vp(s)?O(`/${s}`):t.cwd&&t.cwd.length>0?O(_p.resolve(t.cwd,s)):s}function Gp(s,e){return s.length>e?`${s.slice(0,e-1)}\u2026`:s}function Kp(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 Qp(s,e={}){let t=re(s,"toolCallId")??re(s,"id");if(!t)return null;let n=re(s,"title"),r=n!==void 0?dd(ae(n),s,e):void 0,o=re(s,"status"),i=rd(s),a=ad(s),d=Yp(s);if(!(r!==void 0||i!==null||a!==void 0||d!==void 0||o==="completed"||o==="failed"||o==="rejected"||o==="cancelled"))return null;let u=re(s,"name")??n;if(sd(u)){let p={kind:"exit-plan-mode",toolCallId:t},g=od(s);return g!==null&&(p.plan=g),o!==void 0&&(p.status=o),p}let l={kind:"tool-call-update",toolCallId:t};r!==void 0&&(l.title=r),a!==void 0&&(l.detail=a);let w=lo(s);w!==void 0&&(l.detailFull=w);let h=id(s);if(h!==void 0&&(l.locations=h),d!==void 0&&(l.resultSummary=d),o!==void 0&&(l.status=o),i!==null&&(l.editDiff=i),o==="failed"){let p=Xp(s);p!==null&&(l.errorText=p),Zp(s,p)&&(l.upstreamInterrupted=!0)}let f=In(s);f!==void 0&&(l.workerTaskId=f);let k=uo(s);return k!==void 0&&(l.parentToolUseId=k),l}function Yp(s){if(!s||typeof s!="object")return;let e=s.rawOutput;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=u=>{let l=t[u];return typeof l=="number"&&Number.isFinite(l)?l:void 0},r=(u,l,w=`${l}s`)=>`${u} ${u===1?l:w}`,o=[],i=n("totalMatches");i!==void 0&&o.push(r(i,"match","matches"));let a=n("totalFiles");a!==void 0&&o.push(r(a,"file"));let d=n("referenceCount");d!==void 0&&o.push(r(d,"reference")),o.length>0&&t.truncated===!0&&o.push("truncated");let c=n("exitCode");return c!==void 0&&c!==0&&o.push(`exit ${c}`),o.length>0?o.join(", "):void 0}function Xp(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=An(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 be(n)}return null}function Zp(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 eg(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"?ae(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 tg(s){let e=re(s,"currentModeId")??re(s,"currentMode")??re(s,"mode");return e?{kind:"mode-changed",mode:ae(e)}:null}function ng(s){let e=re(s,"currentModel")??re(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:ae(e),...n&&n.length>0?{availableModels:n}:{}}}function sg(s){let e=re(s,"stopReason"),t=s._meta,n=t?.["hydra-acp"]?.amended!==void 0&&t["hydra-acp"].amended!==null,r={kind:"turn-complete"};e!==void 0&&(r.stopReason=e);let o=re(s,"errorMessage");return o!==void 0&&(r.errorMessage=o),n&&(r.amended=!0),r}function td(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 An(s){if(typeof s=="string")return be(s);if(!s||typeof s!="object")return null;let e=s;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?be(e.text):null}function rg(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){let n=An(t);n!==null&&e.push(n)}return e.length===0?null:e.join("")}function re(s,e){let t=s[e];return typeof t=="string"?t:void 0}function og(s,e){let t=be(s).split(`
33
+ `:""}}function ld(s){if(s===null||typeof s!="object")return[];let e=s.rawOutput;if(e===null||typeof e!="object")return[];let t=e.metadata;if(t===null||typeof t!="object")return[];let n=t.files;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(o===null||typeof o!="object")continue;let i=o,a=typeof i.filePath=="string"&&i.filePath.length>0?i.filePath:i.file;if(typeof a!="string"||a.length===0)continue;let d=i.patch,c=d!==null&&typeof d=="object"?d:void 0;r.push({path:a,...typeof i.additions=="number"?{added:i.additions}:{},...typeof i.deletions=="number"?{removed:i.deletions}:{},...typeof d=="string"?{patch:d}:{},...typeof c?.__hydraBlob=="string"?{patchRef:{hash:c.__hydraBlob,bytes:typeof c.bytes=="number"?c.bytes:0}}:{}})}return r}function Ct(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 Rs(s){let e=s.rawInput;return e&&typeof e=="object"&&!Array.isArray(e)?e:void 0}function vo(s){return typeof s.file_path=="string"?s.file_path:typeof s.path=="string"?s.path:void 0}function xs(s){let e=s.content;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n;if(r.type!=="diff")continue;let o=Ct(r.oldText),i=Ct(r.newText);o===void 0&&i===void 0||t.push({...typeof r.path=="string"?{path:r.path}:{},...o?{old:o}:{},...i?{new:i}:{}})}return t}function Ts(s){let e=Rs(s);if(!e)return;let t=vo(e);if(e.old_string!==void 0||e.new_string!==void 0){let n=Ct(e.old_string),r=Ct(e.new_string);return{...t!==void 0?{path:t}:{},...n?{old:n}:{},...r?{new:r}:{}}}if(e.content!==void 0){let n=Ct(e.content);return{...t!==void 0?{path:t}:{},old:{text:""},...n?{new:n}:{}}}}function Qp(s){let e=Rs(s),t=e?vo(e):void 0;if(!e||t===void 0||!Array.isArray(e.edits))return[];let n=[];for(let r of e.edits){if(!r||typeof r!="object")continue;let o=r,i=Ct(o.old_string),a=Ct(o.new_string);i===void 0||a===void 0||n.push({path:t,old:i,new:a})}return n}function fd(s){return ld(s).map(e=>({path:e.path,...e.patch!==void 0?{patch:{text:e.patch}}:{},...e.patchRef!==void 0?{patch:{ref:e.patchRef}}:{}}))}function Es(s){let e=Qp(s);if(e.length>0)return e.map(r=>({...r,scope:"snippet"}));let t=xs(s).filter(r=>r.path!==void 0);if(t.length>0){let r=Yp(s);return r===void 0?t:t.map(o=>({...o,scope:r}))}let n=Ts(s);return n?.path!==void 0?[{...n,scope:n.old?.text===""?"file":"snippet"}]:fd(s).map(r=>({...r,scope:"snippet"}))}function Yp(s){let e=Rs(s);return e&&(e.old_string!==void 0||e.new_string!==void 0)?"snippet":e&&e.content!==void 0||Xp(s)?"file":void 0}function Xp(s){let e=s.rawOutput;return Array.isArray(e?.metadata?.files)}function pd(s){let e=new Set,t=Rs(s),n=[...xs(s).map(r=>r.path),Ts(s)?.path,t&&Array.isArray(t.edits)?vo(t):void 0,...fd(s).map(r=>r.path)];for(let r of n)typeof r=="string"&&r.length>0&&e.add(r);return[...e]}function gd(s){return s.patch!==void 0?s.patch.text!==void 0?ko(s.patch.text):{oldText:"",newText:""}:{oldText:s.old?.text??"",newText:s.new?.text??""}}Q();import{posix as Zp}from"path";import eg from"strip-ansi";function Tn(s){if(!s||typeof s!="object")return;let e=s;return typeof e.workerTaskId=="string"?e.workerTaskId:void 0}function bo(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object")return;let t=e.claudeCode;if(!t||typeof t!="object")return;let n=t.parentToolUseId;return typeof n=="string"?n:void 0}var tg=/[\x00-\x08\x0b-\x1f\x7f]/g;function be(s){return eg(s).replace(tg,"")}function ae(s){return be(s).replace(/[\n\t]+/g," ").replace(/ +/g," ").trim()}function wd(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 dg(t);case"agent_thought_chunk":case"agent_thought":return cg(t);case"user_message_chunk":return ug(t);case"prompt_received":return lg(t);case"tool_call":return fg(t,e);case"tool_call_update":return yg(t,e);case"plan":return bg(t);case"current_mode_update":return Sg(t);case"_hydra_current_model_update":return Ig(t);case"turn_complete":return Ag(t);case"_hydra_turn_started":return yd(t,"turn-started");case"_hydra_turn_ended":return yd(t,"turn-ended");case"usage_update":return ag(t);case"available_commands_update":return og(t);case"_hydra_available_modes_update":return ig(t);case"session_info_update":return sg(t);case"config_option_update":return ng(t);default:return{kind:"unknown",sessionUpdate:n,raw:s}}}function ng(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 sg(s){let e=re(s,"title"),t=e!==void 0?ae(e):void 0,n=s._meta,r,o;if(n&&typeof n=="object"&&!Array.isArray(n)){let a=n["hydra-acp"];if(a&&typeof a=="object"&&!Array.isArray(a)){let d=a.agentId;if(typeof d=="string"&&(r=d),"pendingAgentSwap"in a){let c=a.pendingAgentSwap;typeof c=="string"?o=c:c===null&&(o=null)}}}if(t===void 0&&r===void 0&&o===void 0)return null;let i={kind:"session-info"};return t!==void 0&&(i.title=t),r!==void 0&&(i.agentId=r),o!==void 0&&(i.pendingAgentSwap=o),i}function rg(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:ae(r)};typeof n.description=="string"&&(o.description=ae(n.description)),e.push(o)}return e}function og(s){let e=s.availableCommands??s.commands;return Array.isArray(e)?{kind:"available-commands",commands:rg(e)}:null}function ig(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:ae(r.id)};typeof r.name=="string"&&(o.name=ae(r.name)),typeof r.description=="string"&&(o.description=ae(r.description)),t.push(o)}return{kind:"available-modes",modes:t}}function ag(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 dg(s){let e=En(s.content);return e===null?null:{kind:"agent-text",text:e,workerTaskId:Tn(s)}}function cg(s){let e=typeof s.text=="string"?be(s.text):En(s.content);return e===null?null:{kind:"agent-thought",text:e,workerTaskId:Tn(s)}}function ug(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=En(s.content);return t===null?null:{kind:"user-text",text:t}}function lg(s){let e=Cg(s.prompt);return e===null?null:{kind:"user-text",text:e}}function kd(s){return s?s.toLowerCase().replace(/[_\s-]/g,"")==="exitplanmode":!1}function vd(s){let e=xs(s)[0];if(e)return md(e);let t=Ts(s);return t?.old?.text!==void 0&&t.new?.text!==void 0?md(t):null}function md(s){return{...s.path!==void 0?{path:s.path}:{},oldText:s.old?.text??"",newText:s.new?.text??"",...s.old?.ref?{oldRef:s.old.ref}:{},...s.new?.ref?{newRef:s.new.ref}:{}}}function bd(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:be(t)}function fg(s,e={}){let t=re(s,"toolCallId")??re(s,"id");if(!t)return null;let n=re(s,"title")??re(s,"name")??re(s,"label")??"tool call",r=re(s,"name")??re(s,"title");if(kd(r)){let k=bd(s);if(k!==null){let g=re(s,"status"),p={kind:"exit-plan-mode",toolCallId:t,plan:k};return g!==void 0&&(p.status=g),p}}let o=Ad(ae(n),s,e),i=re(s,"status"),a=re(s,"kind"),d={kind:"tool-call",toolCallId:t,title:o};i!==void 0&&(d.status=i),a!==void 0&&(d.rawKind=a);let c=vd(s);c!==null&&(d.editDiff=c);let u=Id(s);u!==void 0&&(d.detail=u);let l=So(s);l!==void 0&&(d.detailFull=l);let y=Sd(s);y!==void 0&&(d.locations=y);let h=Tn(s);h!==void 0&&(d.workerTaskId=h);let f=bo(s);return f!==void 0&&(d.parentToolUseId=f),d}function Sd(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 hd=64;function Id(s){let e=So(s);if(e===void 0)return;let t=ae(e),n=s.rawInput;return n&&typeof n.command=="string"?mg(t,hd):hg(t,hd)}function So(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 be(t.command).trim().replace(/^cd\s+\S+\s+&&\s+/,"");let n=typeof t.file_path=="string"?t.file_path:typeof t.filePath=="string"?t.filePath:typeof t.path=="string"?t.path:void 0;if(n!==void 0&&n.length>0)return F(ae(n))}if(Array.isArray(s.locations)){for(let t of s.locations)if(t&&typeof t=="object"){let n=t.path;if(typeof n=="string"&&n.length>0)return F(ae(n))}}}var pg=["home/","Users/","root/","tmp/","var/","opt/","etc/","usr/","mnt/","private/"];function gg(s){for(let e of pg)if(s.startsWith(e))return!0;return!1}function Ad(s,e,t={}){if(s.length===0)return s;if(s.startsWith("/"))return F(s);if(s.startsWith("~")||!s.includes("/")||/\s/.test(s))return s;let n=e.rawInput;if(n&&typeof n=="object"&&!Array.isArray(n)){let r=n,o=[r.file_path,r.filePath,r.path];for(let i of o)if(!(typeof i!="string"||i.length===0)&&(i===`/${s}`||i.endsWith(`/${s}`)||i===s))return F(i)}return gg(s)?F(`/${s}`):t.cwd&&t.cwd.length>0?F(Zp.resolve(t.cwd,s)):s}function mg(s,e){return s.length>e?`${s.slice(0,e-1)}\u2026`:s}function hg(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 yg(s,e={}){let t=re(s,"toolCallId")??re(s,"id");if(!t)return null;let n=re(s,"title"),r=n!==void 0?Ad(ae(n),s,e):void 0,o=re(s,"status"),i=vd(s),a=Id(s),d=wg(s);if(!(r!==void 0||i!==null||a!==void 0||d!==void 0||o==="completed"||o==="failed"||o==="rejected"||o==="cancelled"))return null;let u=re(s,"name")??n;if(kd(u)){let g={kind:"exit-plan-mode",toolCallId:t},p=bd(s);return p!==null&&(g.plan=p),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 y=So(s);y!==void 0&&(l.detailFull=y);let h=Sd(s);if(h!==void 0&&(l.locations=h),d!==void 0&&(l.resultSummary=d),o!==void 0&&(l.status=o),i!==null&&(l.editDiff=i),o==="failed"){let g=kg(s);g!==null&&(l.errorText=g),vg(s,g)&&(l.upstreamInterrupted=!0)}let f=Tn(s);f!==void 0&&(l.workerTaskId=f);let k=bo(s);return k!==void 0&&(l.parentToolUseId=k),l}function wg(s){if(!s||typeof s!="object")return;let e=s.rawOutput;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n=u=>{let l=t[u];return typeof l=="number"&&Number.isFinite(l)?l:void 0},r=(u,l,y=`${l}s`)=>`${u} ${u===1?l:y}`,o=[],i=n("totalMatches");i!==void 0&&o.push(r(i,"match","matches"));let a=n("totalFiles");a!==void 0&&o.push(r(a,"file"));let d=n("referenceCount");d!==void 0&&o.push(r(d,"reference")),o.length>0&&t.truncated===!0&&o.push("truncated");let c=n("exitCode");return c!==void 0&&c!==0&&o.push(`exit ${c}`),o.length>0?o.join(", "):void 0}function kg(s){let e=s.content;if(Array.isArray(e))for(let n of e){if(!n||typeof n!="object")continue;let o=En(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 be(n)}return null}function vg(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 bg(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"?ae(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 Sg(s){let e=re(s,"currentModeId")??re(s,"currentMode")??re(s,"mode");return e?{kind:"mode-changed",mode:ae(e)}:null}function Ig(s){let e=re(s,"currentModel")??re(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:ae(e),...n&&n.length>0?{availableModels:n}:{}}}function Ag(s){let e=re(s,"stopReason"),t=s._meta,n=t?.["hydra-acp"]?.amended!==void 0&&t["hydra-acp"].amended!==null,r={kind:"turn-complete"};e!==void 0&&(r.stopReason=e);let o=re(s,"errorMessage");return o!==void 0&&(r.errorMessage=o),n&&(r.amended=!0),r}function yd(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 En(s){if(typeof s=="string")return be(s);if(!s||typeof s!="object")return null;let e=s;return e.type==="text"&&typeof e.text=="string"||typeof e.text=="string"?be(e.text):null}function Cg(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){let n=En(t);n!==null&&e.push(n)}return e.length===0?null:e.join("")}function re(s,e){let t=s[e];return typeof t=="string"?t:void 0}function Rg(s,e){let t=be(s).split(`
34
34
  `),n=be(e).split(`
35
- `);return t.length>0&&t[t.length-1]===""&&t.pop(),n.length>0&&n[n.length-1]===""&&n.pop(),{oldLines:t,newLines:n}}function cd(s,e){let{oldLines:t,newLines:n}=og(s,e),r=0,o=0;for(let i of ig(t,n))i.op==="+"?r++:i.op==="-"&&o++;return{added:r,removed:o}}function ig(s,e){let t=0,n=Math.min(s.length,e.length);for(;t<n&&s[t]===e[t];)t++;let r=s.length,o=e.length;for(;r>t&&o>t&&s[r-1]===e[o-1];)r--,o--;let i=[];for(let a=0;a<t;a++)i.push({op:"=",text:s[a]});i.push(...ag(s.slice(t,r),e.slice(t,o)));for(let a=r;a<s.length;a++)i.push({op:"=",text:s[a]});return i}function ag(s,e){let t=s.length,n=e.length;if(t===0||n===0){let d=[];for(let c of s)d.push({op:"-",text:c});for(let c of e)d.push({op:"+",text:c});return d}let r=Array.from({length:t+1},()=>new Array(n+1).fill(0));for(let d=t-1;d>=0;d--)for(let c=n-1;c>=0;c--)s[d]===e[c]?r[d][c]=r[d+1][c+1]+1:r[d][c]=Math.max(r[d+1][c],r[d][c+1]);let o=[],i=0,a=0;for(;i<t&&a<n;)s[i]===e[a]?(o.push({op:"=",text:s[i]}),i++,a++):r[i+1][a]>=r[i][a+1]?(o.push({op:"-",text:s[i]}),i++):(o.push({op:"+",text:e[a]}),a++);for(;i<t;)o.push({op:"-",text:s[i]}),i++;for(;a<n;)o.push({op:"+",text:e[a]}),a++;return o}var ud="hydra-acp";function dg(s){let e=0,t=0,n=!1;for(let r of s.split(`
36
- `)){if(r.startsWith("@@")){n=!0;continue}n&&(r.startsWith("+")?e++:r.startsWith("-")&&t++)}return{added:e,removed:t}}function cg(s){let e=[];for(let t of Is(s))if(t.path!==void 0){if(t.patch!==void 0){t.patch.text!==void 0&&e.push({path:t.path,...dg(t.patch.text)});continue}t.old!==void 0&&t.old.text===void 0||t.new!==void 0&&t.new.text===void 0||e.push({path:t.path,...cd(t.old?.text??"",t.new?.text??"")})}return e}function ld(s){let e=s.update;if(!e||e.sessionUpdate!=="tool_call"&&e.sessionUpdate!=="tool_call_update")return s;let t=cg(e);if(t.length===0)return s;let n=e._meta??{},r=n[ud]??{};return{...s,update:{...e,_meta:{...n,[ud]:{...r,editStats:t}}}}}var fd=["hydra-acp-","hydra-"];function fo(s){for(let e of fd)if(s.startsWith(e)&&s.length>e.length)return s.slice(e.length)}function pd(s){return fd.map(e=>`${e}${s}`)}import{customAlphabet as Ld}from"nanoid";function ze(s){return`${s.name}:${s.localId}`}function pt(s){let e=s.indexOf(":");if(e===-1)return;let t=s.slice(0,e),n=s.slice(e+1);if(!(t.length===0||n.length===0))return{name:t,localId:n}}import{createHmac as ug}from"crypto";function lg(s,e){return ug("sha256",s).update(e).digest("hex")}function po(s,e){let t=JSON.stringify(e),n=lg(s.secret,t);fetch(s.callbackUrl,{method:"POST",headers:{"Content-Type":"application/json","X-Hydra-Turn-Notify-Signature":n},body:t}).catch(()=>{})}function Cn(s,e){return s!==void 0&&e!==void 0&&s>e}function zt(s){return{...s.lastTurnEndedAt!==void 0?{lastTurnEndedAt:s.lastTurnEndedAt}:{},...s.readAt!==void 0?{readAt:s.readAt}:{},unread:Cn(s.lastTurnEndedAt,s.readAt)}}function As(s,e,t=Date.now()){let n;if(e){if(s.readAt!==void 0&&!Cn(s.lastTurnEndedAt,s.readAt))return;n=Math.max(t,s.lastTurnEndedAt??0)}else s.lastTurnEndedAt!==void 0&&!Cn(s.lastTurnEndedAt,s.readAt)&&(n=s.lastTurnEndedAt-1);return n===s.readAt?void 0:n}import*as md from"fs/promises";var fg=64*1024*1024,pg=1*1024*1024,Jt=64*1024,gg=6e4,mg=100,hg=1e3,yg=64*1024,wg=256*1024,gd=20;function kg(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Cs=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??fg,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(pg,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,Jt));if(n===0){let l={bytes:Buffer.alloc(0),nextCursor:e};return this.closed&&e>=this.writeCursor&&(l.eof=!0),l}let r=e,o=0,i=this.oldestAvailable;r<i&&(o=i-r,r=i);let a=this.writeCursor-r;if(a<=0){let l={bytes:Buffer.alloc(0),nextCursor:r};return o>0&&(l.gap=o),this.closed&&(l.eof=!0),l}let d=Math.min(a,n),u={bytes:this.sliceFromRing(r,d),nextCursor:r+d};return o>0&&(u.gap=o),this.closed&&r+d>=this.writeCursor&&(u.eof=!0),u}tail(e){let t=Math.max(0,Math.min(e,Jt)),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,Jt)),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,gg));return n===0?Promise.resolve("timeout"):new Promise(r=>{let o={resolve:i=>{o.timer!==void 0&&(clearTimeout(o.timer),o.timer=void 0),r(i)},timer:setTimeout(()=>{let i=this.waiters.indexOf(o);i>=0&&this.waiters.splice(i,1),o.timer=void 0,r("timeout")},n)};this.waiters.push(o)})}grep(e){let t=this.oldestAvailable,n=e.cursor,r=n??t,o=0;n!==void 0&&n<t&&(o=t-n,r=t),r>this.writeCursor&&(r=this.writeCursor);let i=this.sliceFromRing(r,this.writeCursor-r),a=e.regex??!0,d=e.caseInsensitive===!0?"i":"",c=a?new RegExp(e.pattern,d):new RegExp(kg(e.pattern),d),u=e.invert??!1,l=Math.max(1,Math.min(e.maxMatches??mg,hg)),w=Math.max(1,Math.min(e.maxBytes??yg,wg)),h=Math.max(0,Math.min(e.contextBefore??0,gd)),f=Math.max(0,Math.min(e.contextAfter??0,gd)),k=[],p=[],g=[],y=0,m=!1,v=0,S=0,b=(T,R)=>{for(let J of g)J.remaining>0&&(J.match.after===void 0&&(J.match.after=[]),J.match.after.push({cursor:T,line:R}),J.remaining--,y+=R.length);for(;g.length>0&&g[0].remaining===0;)g.shift();if(c.test(R)!==u&&k.length<l){let J={cursor:T,line:R};if(h>0&&p.length>0){J.before=p.slice();for(let z of J.before)y+=z.line.length}y+=R.length,k.push(J),f>0&&g.push({match:J,remaining:f})}if(h>0)for(p.push({cursor:T,line:R});p.length>h;)p.shift();let $=k.length>=l&&g.length===0,H=y>=w;return $||H};for(let T=0;T<i.length;T++){if(i[T]!==10)continue;let R=i.subarray(v,T).toString("utf8"),P=r+v;if(v=T+1,S=v,b(P,R)){m=!0;break}}if(!m&&v<i.length&&this.closed){let T=i.subarray(v).toString("utf8"),R=r+v;b(R,T)&&(m=!0),S=i.length}let I=Math.min(r+S,this.writeCursor),A={matches:k,truncated:m,nextCursor:I,scannedBytes:S};return o>0&&(A.gap=o),this.closed&&I>=this.writeCursor&&(A.eof=!0),A}wakeWaiters(e){if(this.waiters.length===0)return;let t=this.waiters;this.waiters=[];for(let n of t)n.resolve(e)}growIfNeeded(e){if(this.currentCapacityBytes>=this.maxCapacityBytes)return;let t=this.writeCursor+e;if(t<=this.currentCapacityBytes)return;let n=this.currentCapacityBytes;for(;n<t&&n<this.maxCapacityBytes;)n=Math.min(this.maxCapacityBytes,n*2);if(n===this.currentCapacityBytes)return;let r=Buffer.alloc(n);this.storage.copy(r,0,0,this.writeCursor),this.storage=r,this.currentCapacityBytes=n}writeRing(e){let t=e.length;if(this.growIfNeeded(t),t>=this.currentCapacityBytes){let o=t-this.currentCapacityBytes;e.copy(this.storage,0,o,t);return}let n=this.writeCursor%this.currentCapacityBytes,r=this.currentCapacityBytes-n;t<=r?e.copy(this.storage,n,0,t):(e.copy(this.storage,n,0,r),e.copy(this.storage,0,r,t))}sliceFromRing(e,t){if(t<=0)return Buffer.alloc(0);let n=Buffer.alloc(t),r=e%this.currentCapacityBytes,o=Math.min(t,this.currentCapacityBytes-r);return this.storage.copy(n,0,r,r+o),o<t&&this.storage.copy(n,o,0,t-o),n}scheduleFileWrite(e){let t=this.filePath;if(t===void 0||this.fileCapReached)return;let n=this.fileCapBytes-this.fileBytesWritten;if(n<=0){this.fileCapReached=!0,this.onFileCapReached?.();return}let r=e.length<=n?e:e.subarray(0,n);this.fileBytesWritten+=r.length;let o=this.fileBytesWritten>=this.fileCapBytes;this.fileWriteChain=this.fileWriteChain.then(()=>md.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var Vt=[{verb:"title",name:"hydra title",description:"Regenerate the session title + synopsis via the agent (or set title manually with an arg)"},{verb:"agent",name:"hydra agent",argsHint:"<agent | status>",description:"Schedule a swap to a different agent (synthesizes a brief in the target's idiom, rotates on idle); `status` reports any pending swap"},{verb:"workspace",name:"hydra workspace",argsHint:"<start [name] [--clean] | sync | merge | apply | stop | detach | clean [--deep] | discard | status>",description:"Move this session into an isolated workspace so its edits cannot collide with other work, then land or discard them. `start` copies your uncommitted changes in and leaves the real tree untouched; `start --clean` leaves them behind so the workspace begins at the last commit. `stop` merges and returns; `discard` throws the work away and returns; `detach` returns without merging, leaving the workspace and its branch intact; `merge` lands the work without leaving; `apply` also stays, but delivers the work as ONE staged, uncommitted changeset instead of as the agent's commits, so you review and commit it yourself, with no fast-forward needed, which is what makes it work once the source has moved on; `clean` throws away everything done in the workspace and stays there, putting it back exactly as `start --clean` would have made it (add `--deep` to rebuild dependencies and carried config files too, rather than keeping them); `sync` pulls the source's committed history INTO the workspace, so you can test against what you will land onto, and because landing is fast-forward-only, syncing is also how you recover once the source has moved on. `start <name>` naming a workspace another live session is already in JOINS it instead of making a second one, so two sessions can share a checkout deliberately: edits interleave, `stop` behaves as `detach` while anyone else is still there, and the work lands when the last of them leaves."},{verb:"kill",name:"hydra kill",description:"Close this session (kills the agent; record is kept so it can be resumed later)"},{verb:"restart",name:"hydra restart",description:"Restart the agent with a fresh session/new while preserving conversation history (useful when the proxy has changed available models)"},{verb:"compact",name:"hydra compact",description:"Compact this session's history. Use '/hydra compact status' to inspect current compaction state without triggering."},{verb:"uncompact",name:"hydra uncompact",description:"Roll back the most recent compaction swap (only available immediately after a swap, before any new turns)"},{verb:"clear",name:"hydra clear",description:"Drop every turn of this conversation, this command included, and restart the agent with no context"},{verb:"fork",name:"hydra fork",argsHint:"[--verbatim] [prompt]",description:"Fork this conversation into a new session (default: synthesis mode with a synopsis brief; pass --verbatim to slice at the last completed turn instead). A prompt is sent to the fork as its first turn once it's ready."},{verb:"config",name:"hydra config",argsHint:"[<id> [<value>]]",description:"List or set an agent-advertised configOption (model, mode, effort, etc.). With no args, lists all options; with <id>, shows its choices; with <id> <value>, applies it."}],Lb=new Map(Vt.map(s=>[s.verb,s]));function hd(s){let e=s.lastIndexOf("/");return(e===-1?s:s.slice(e+1)).toLowerCase()}function Gt(s,e){return Kt(s,e.map(t=>t.modelId))}function Kt(s,e){if(e.length===0)return{kind:"none",requested:s};if(e.includes(s))return{kind:"exact",modelId:s};let t=hd(s),n=e.filter(o=>hd(o)===t);if(n.length===1)return{kind:"resolved",modelId:n[0],requested:s};if(n.length>1)return{kind:"ambiguous",requested:s,candidates:n};let r=s.toLowerCase();if(r.length>0){let o=e.filter(i=>i.toLowerCase().includes(r));if(o.length===1)return{kind:"resolved",modelId:o[0],requested:s};if(o.length>1)return{kind:"ambiguous",requested:s,candidates:o}}return{kind:"unknown",requested:s}}var vg="Compact conversation",bg="contextCompaction",Sg=`
35
+ `);return t.length>0&&t[t.length-1]===""&&t.pop(),n.length>0&&n[n.length-1]===""&&n.pop(),{oldLines:t,newLines:n}}function Cd(s,e){let{oldLines:t,newLines:n}=Rg(s,e),r=0,o=0;for(let i of xg(t,n))i.op==="+"?r++:i.op==="-"&&o++;return{added:r,removed:o}}function xg(s,e){let t=0,n=Math.min(s.length,e.length);for(;t<n&&s[t]===e[t];)t++;let r=s.length,o=e.length;for(;r>t&&o>t&&s[r-1]===e[o-1];)r--,o--;let i=[];for(let a=0;a<t;a++)i.push({op:"=",text:s[a]});i.push(...Tg(s.slice(t,r),e.slice(t,o)));for(let a=r;a<s.length;a++)i.push({op:"=",text:s[a]});return i}function Tg(s,e){let t=s.length,n=e.length;if(t===0||n===0){let d=[];for(let c of s)d.push({op:"-",text:c});for(let c of e)d.push({op:"+",text:c});return d}let r=Array.from({length:t+1},()=>new Array(n+1).fill(0));for(let d=t-1;d>=0;d--)for(let c=n-1;c>=0;c--)s[d]===e[c]?r[d][c]=r[d+1][c+1]+1:r[d][c]=Math.max(r[d+1][c],r[d][c+1]);let o=[],i=0,a=0;for(;i<t&&a<n;)s[i]===e[a]?(o.push({op:"=",text:s[i]}),i++,a++):r[i+1][a]>=r[i][a+1]?(o.push({op:"-",text:s[i]}),i++):(o.push({op:"+",text:e[a]}),a++);for(;i<t;)o.push({op:"-",text:s[i]}),i++;for(;a<n;)o.push({op:"+",text:e[a]}),a++;return o}var Rd="hydra-acp";function Eg(s){let e=0,t=0,n=!1;for(let r of s.split(`
36
+ `)){if(r.startsWith("@@")){n=!0;continue}n&&(r.startsWith("+")?e++:r.startsWith("-")&&t++)}return{added:e,removed:t}}function Pg(s){let e=[];for(let t of Es(s))if(t.path!==void 0){if(t.patch!==void 0){t.patch.text!==void 0&&e.push({path:t.path,...Eg(t.patch.text)});continue}t.old!==void 0&&t.old.text===void 0||t.new!==void 0&&t.new.text===void 0||e.push({path:t.path,...Cd(t.old?.text??"",t.new?.text??"")})}return e}function xd(s){let e=s.update;if(!e||e.sessionUpdate!=="tool_call"&&e.sessionUpdate!=="tool_call_update")return s;let t=Pg(e);if(t.length===0)return s;let n=e._meta??{},r=n[Rd]??{};return{...s,update:{...e,_meta:{...n,[Rd]:{...r,editStats:t}}}}}var Td=["hydra-acp-","hydra-"];function Io(s){for(let e of Td)if(s.startsWith(e)&&s.length>e.length)return s.slice(e.length)}function Ed(s){return Td.map(e=>`${e}${s}`)}import{customAlphabet as ac}from"nanoid";function Je(s){return`${s.name}:${s.localId}`}function gt(s){let e=s.indexOf(":");if(e===-1)return;let t=s.slice(0,e),n=s.slice(e+1);if(!(t.length===0||n.length===0))return{name:t,localId:n}}import{createHmac as Mg}from"crypto";function _g(s,e){return Mg("sha256",s).update(e).digest("hex")}function Ao(s,e){let t=JSON.stringify(e),n=_g(s.secret,t);fetch(s.callbackUrl,{method:"POST",headers:{"Content-Type":"application/json","X-Hydra-Turn-Notify-Signature":n},body:t}).catch(()=>{})}function Pn(s,e){return s!==void 0&&e!==void 0&&s>e}function Vt(s){return{...s.lastTurnEndedAt!==void 0?{lastTurnEndedAt:s.lastTurnEndedAt}:{},...s.readAt!==void 0?{readAt:s.readAt}:{},unread:Pn(s.lastTurnEndedAt,s.readAt)}}function Ps(s,e,t=Date.now()){let n;if(e){if(s.readAt!==void 0&&!Pn(s.lastTurnEndedAt,s.readAt))return;n=Math.max(t,s.lastTurnEndedAt??0)}else s.lastTurnEndedAt!==void 0&&!Pn(s.lastTurnEndedAt,s.readAt)&&(n=s.lastTurnEndedAt-1);return n===s.readAt?void 0:n}import*as Md from"fs/promises";var $g=64*1024*1024,Fg=1*1024*1024,Gt=64*1024,Og=6e4,Ng=100,Dg=1e3,Lg=64*1024,Hg=256*1024,Pd=20;function jg(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Ms=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??$g,this.maxCapacityBytes<=0)throw new Error("capacityBytes must be > 0");this.currentCapacityBytes=Math.min(Fg,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,Gt));if(n===0){let l={bytes:Buffer.alloc(0),nextCursor:e};return this.closed&&e>=this.writeCursor&&(l.eof=!0),l}let r=e,o=0,i=this.oldestAvailable;r<i&&(o=i-r,r=i);let a=this.writeCursor-r;if(a<=0){let l={bytes:Buffer.alloc(0),nextCursor:r};return o>0&&(l.gap=o),this.closed&&(l.eof=!0),l}let d=Math.min(a,n),u={bytes:this.sliceFromRing(r,d),nextCursor:r+d};return o>0&&(u.gap=o),this.closed&&r+d>=this.writeCursor&&(u.eof=!0),u}tail(e){let t=Math.max(0,Math.min(e,Gt)),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,Gt)),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,Og));return n===0?Promise.resolve("timeout"):new Promise(r=>{let o={resolve:i=>{o.timer!==void 0&&(clearTimeout(o.timer),o.timer=void 0),r(i)},timer:setTimeout(()=>{let i=this.waiters.indexOf(o);i>=0&&this.waiters.splice(i,1),o.timer=void 0,r("timeout")},n)};this.waiters.push(o)})}grep(e){let t=this.oldestAvailable,n=e.cursor,r=n??t,o=0;n!==void 0&&n<t&&(o=t-n,r=t),r>this.writeCursor&&(r=this.writeCursor);let i=this.sliceFromRing(r,this.writeCursor-r),a=e.regex??!0,d=e.caseInsensitive===!0?"i":"",c=a?new RegExp(e.pattern,d):new RegExp(jg(e.pattern),d),u=e.invert??!1,l=Math.max(1,Math.min(e.maxMatches??Ng,Dg)),y=Math.max(1,Math.min(e.maxBytes??Lg,Hg)),h=Math.max(0,Math.min(e.contextBefore??0,Pd)),f=Math.max(0,Math.min(e.contextAfter??0,Pd)),k=[],g=[],p=[],w=0,m=!1,v=0,S=0,b=(T,R)=>{for(let J of p)J.remaining>0&&(J.match.after===void 0&&(J.match.after=[]),J.match.after.push({cursor:T,line:R}),J.remaining--,w+=R.length);for(;p.length>0&&p[0].remaining===0;)p.shift();if(c.test(R)!==u&&k.length<l){let J={cursor:T,line:R};if(h>0&&g.length>0){J.before=g.slice();for(let z of J.before)w+=z.line.length}w+=R.length,k.push(J),f>0&&p.push({match:J,remaining:f})}if(h>0)for(g.push({cursor:T,line:R});g.length>h;)g.shift();let $=k.length>=l&&p.length===0,L=w>=y;return $||L};for(let T=0;T<i.length;T++){if(i[T]!==10)continue;let R=i.subarray(v,T).toString("utf8"),P=r+v;if(v=T+1,S=v,b(P,R)){m=!0;break}}if(!m&&v<i.length&&this.closed){let T=i.subarray(v).toString("utf8"),R=r+v;b(R,T)&&(m=!0),S=i.length}let I=Math.min(r+S,this.writeCursor),A={matches:k,truncated:m,nextCursor:I,scannedBytes:S};return o>0&&(A.gap=o),this.closed&&I>=this.writeCursor&&(A.eof=!0),A}wakeWaiters(e){if(this.waiters.length===0)return;let t=this.waiters;this.waiters=[];for(let n of t)n.resolve(e)}growIfNeeded(e){if(this.currentCapacityBytes>=this.maxCapacityBytes)return;let t=this.writeCursor+e;if(t<=this.currentCapacityBytes)return;let n=this.currentCapacityBytes;for(;n<t&&n<this.maxCapacityBytes;)n=Math.min(this.maxCapacityBytes,n*2);if(n===this.currentCapacityBytes)return;let r=Buffer.alloc(n);this.storage.copy(r,0,0,this.writeCursor),this.storage=r,this.currentCapacityBytes=n}writeRing(e){let t=e.length;if(this.growIfNeeded(t),t>=this.currentCapacityBytes){let o=t-this.currentCapacityBytes;e.copy(this.storage,0,o,t);return}let n=this.writeCursor%this.currentCapacityBytes,r=this.currentCapacityBytes-n;t<=r?e.copy(this.storage,n,0,t):(e.copy(this.storage,n,0,r),e.copy(this.storage,0,r,t))}sliceFromRing(e,t){if(t<=0)return Buffer.alloc(0);let n=Buffer.alloc(t),r=e%this.currentCapacityBytes,o=Math.min(t,this.currentCapacityBytes-r);return this.storage.copy(n,0,r,r+o),o<t&&this.storage.copy(n,o,0,t-o),n}scheduleFileWrite(e){let t=this.filePath;if(t===void 0||this.fileCapReached)return;let n=this.fileCapBytes-this.fileBytesWritten;if(n<=0){this.fileCapReached=!0,this.onFileCapReached?.();return}let r=e.length<=n?e:e.subarray(0,n);this.fileBytesWritten+=r.length;let o=this.fileBytesWritten>=this.fileCapBytes;this.fileWriteChain=this.fileWriteChain.then(()=>Md.appendFile(t,r)).catch(i=>{this.logWriteError?.(i)}),o&&!this.fileCapReached&&(this.fileCapReached=!0,this.onFileCapReached?.())}async drainFileWrites(){await this.fileWriteChain.catch(()=>{})}};var Kt=[{verb:"title",name:"hydra title",description:"Regenerate the session title + synopsis via the agent (or set title manually with an arg)"},{verb:"agent",name:"hydra agent",argsHint:"<agent | status>",description:"Schedule a swap to a different agent (synthesizes a brief in the target's idiom, rotates on idle); `status` reports any pending swap"},{verb:"workspace",name:"hydra workspace",argsHint:"<start [name] [--clean] | sync | merge | apply | stop | detach | clean [--deep] | discard | status>",description:"Move this session into an isolated workspace so its edits cannot collide with other work, then land or discard them. `start` copies your uncommitted changes in and leaves the real tree untouched; `start --clean` leaves them behind so the workspace begins at the last commit. `stop` merges and returns; `discard` throws the work away and returns; `detach` returns without merging, leaving the workspace and its branch intact; `merge` lands the work without leaving; `apply` also stays, but delivers the work as ONE staged, uncommitted changeset instead of as the agent's commits, so you review and commit it yourself, with no fast-forward needed, which is what makes it work once the source has moved on; `clean` throws away everything done in the workspace and stays there, putting it back exactly as `start --clean` would have made it (add `--deep` to rebuild dependencies and carried config files too, rather than keeping them); `sync` pulls the source's committed history INTO the workspace, so you can test against what you will land onto, and because landing is fast-forward-only, syncing is also how you recover once the source has moved on. `start <name>` naming a workspace another live session is already in JOINS it instead of making a second one, so two sessions can share a checkout deliberately: edits interleave, `stop` behaves as `detach` while anyone else is still there, and the work lands when the last of them leaves."},{verb:"kill",name:"hydra kill",description:"Close this session (kills the agent; record is kept so it can be resumed later)"},{verb:"restart",name:"hydra restart",description:"Restart the agent with a fresh session/new while preserving conversation history (useful when the proxy has changed available models)"},{verb:"compact",name:"hydra compact",description:"Compact this session's history. Use '/hydra compact status' to inspect current compaction state without triggering."},{verb:"uncompact",name:"hydra uncompact",description:"Roll back the most recent compaction swap (only available immediately after a swap, before any new turns)"},{verb:"clear",name:"hydra clear",description:"Drop every turn of this conversation, this command included, and restart the agent with no context"},{verb:"tag",name:"hydra tag",argsHint:"[<tag...>]",description:"Add free-form tags to this session (lowercase letters, digits, . _ / -); with no args, lists them. Searchable from the session picker as #tag."},{verb:"untag",name:"hydra untag",argsHint:"<tag...> | --all",description:"Remove tags from this session"},{verb:"fork",name:"hydra fork",argsHint:"[--verbatim] [prompt]",description:"Fork this conversation into a new session (default: synthesis mode with a synopsis brief; pass --verbatim to slice at the last completed turn instead). A prompt is sent to the fork as its first turn once it's ready."},{verb:"config",name:"hydra config",argsHint:"[<id> [<value>]]",description:"List or set an agent-advertised configOption (model, mode, effort, etc.). With no args, lists all options; with <id>, shows its choices; with <id> <value>, applies it."}],pS=new Map(Kt.map(s=>[s.verb,s]));function Rt(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function tt(s){return typeof s=="string"&&s.length>0?s:void 0}function Qt(s){return s.replace(/\s+/g," ").trim()}function _s(s){if(!Array.isArray(s))return null;let e=[];for(let t of s){if(typeof t=="string"){e.push({value:t,label:t});continue}if(!Rt(t)||typeof t.const!="string")return null;let n=tt(t.description);e.push({value:t.const,label:tt(t.title)??t.const,...n!==void 0?{note:Qt(n)}:{}})}return e}function Ug(s,e,t){if(!Rt(e))return null;let n=Qt(tt(e.title)??tt(e.description)??s),r=tt(e.title)!==void 0&&tt(e.description)!==void 0?Qt(e.description):void 0,o={key:s,title:n,...r!==void 0?{description:r}:{},required:t,...e.default!==void 0?{default:e.default}:{}},i=d=>typeof d=="number"&&Number.isFinite(d)?d:void 0,a=d=>{for(let c of Object.keys(d))d[c]===void 0&&delete d[c];return d};switch(e.type){case"string":{let d=_s(e.oneOf)??_s(e.enum);return d!==null&&d.length>0?{...o,kind:"single",options:d}:{...o,kind:"text",...a({minLength:i(e.minLength),maxLength:i(e.maxLength),pattern:tt(e.pattern),format:tt(e.format)})}}case"boolean":return{...o,kind:"single",options:[{value:"true",label:"Yes"},{value:"false",label:"No"}]};case"number":case"integer":return{...o,kind:"text",numeric:e.type,...a({minimum:i(e.minimum),maximum:i(e.maximum)})};case"array":{let d=Rt(e.items)?e.items:{},c=_s(d.anyOf)??_s(d.enum);return c===null||c.length===0?null:{...o,kind:"multi",options:c,...a({minItems:i(e.minItems),maxItems:i(e.maxItems)})}}default:return null}}function $s(s){if(!Rt(s)||s.mode!=="form"||!Rt(s.requestedSchema))return null;let e=s.requestedSchema.properties;if(!Rt(e))return null;let t=Array.isArray(s.requestedSchema.required)?s.requestedSchema.required:[],n=[],r=new Set;for(let[o,i]of Object.entries(e)){if(r.has(o))continue;let a=Ug(o,i,t.includes(o));if(a===null)return null;let d=`${o}_custom`,c=e[d];a.kind!=="text"&&Rt(c)&&c.type==="string"&&c.oneOf===void 0&&c.enum===void 0&&(a.customKey=d,r.add(d)),n.push(a)}return n.length===0?null:{message:Qt(tt(s.message)??"The agent has a question"),fields:n}}var Bg=256,Wg=1e4;function qg(s,e){if(s.minLength!==void 0&&e.length<s.minLength)return`at least ${s.minLength} characters`;if(s.maxLength!==void 0&&e.length>s.maxLength)return`at most ${s.maxLength} characters`;if(s.pattern!==void 0&&s.pattern.length<=Bg&&e.length<=Wg)try{if(!new RegExp(s.pattern,"u").test(e))return"does not match the expected format"}catch{}switch(s.format){case"email":return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)?null:"not an email address";case"uri":return URL.canParse(e)?null:"not a URI";case"date":return/^\d{4}-\d{2}-\d{2}$/.test(e)&&!Number.isNaN(Date.parse(e))?null:"expected YYYY-MM-DD";case"date-time":return/^\d{4}-\d{2}-\d{2}T/.test(e)&&!Number.isNaN(Date.parse(e))?null:"expected an ISO 8601 date-time";default:return null}}function _d(s,e){if(s.numeric!==void 0){let n=Number(e);return!Number.isFinite(n)||s.numeric==="integer"&&!Number.isInteger(n)?{error:s.numeric==="integer"?"not an integer":"not a number"}:s.minimum!==void 0&&n<s.minimum?{error:`at least ${s.minimum}`}:s.maximum!==void 0&&n>s.maximum?{error:`at most ${s.maximum}`}:{value:n}}let t=qg(s,e);return t===null?{value:e}:{error:t}}function Co(s){return s.description!==void 0?`${s.description} (${s.title})`:s.title}function $d(s,e){return s.kind==="text"?e:s.options.find(t=>t.value===e)?.label??e}function xo(s,e=!0){if(s.kind==="text")return Co(s);let t=s.options.map(o=>o.label).join(" / "),n=s.customKey!==void 0?" / or type your own":"",r=s.kind==="multi"?" (pick any)":"";return e?`${Co(s)}${r}: ${t}${n}`:`${t}${n}${r}`}function Os(s){let e=$s(s),t=Qt(typeof s?.message=="string"?s.message:"The agent has a question");if(e===null)return`**The agent asked:** ${t}`;let n=e.fields.map((o,i)=>e.fields.length>1?`${i+1}. ${xo(o)}`:`Options: ${xo(o,!1)}`),r=e.fields.length===1&&e.fields[0].kind==="text"?[]:n;return[`**The agent asked:** ${e.message}`,...r].join(`
37
+ `)}function zg(s,e){let t=e[s.key],n=[];Array.isArray(t)?n.push(...t.map(o=>$d(s,String(o)))):t!=null&&t!==""&&n.push($d(s,String(t)));let r=s.customKey!==void 0?e[s.customKey]:void 0;return typeof r=="string"&&r.length>0&&n.push(r),n.length>0?n.join(", "):null}function Mn(s,e,t){let n=e?.action,r=t!==void 0?` by ${t}`:"",o=$s(s),i=o?.message??"the agent's question";if(n==="decline")return`**Skipped${r}:** ${i}`;if(n!=="accept")return t!==void 0?`**Dismissed${r}:** ${i}`:`**Not answered:** ${i}`;let a=e.content??{};if(o===null)return`**Answered${r}:** ${i}`;let d=o.fields.map(c=>{let u=zg(c,a)??"(no answer)";return o.fields.length>1?`${c.title}: ${u}`:u});return o.fields.length>1?[`**Answered${r}:** ${i}`,...d.map(c=>`- ${c}`)].join(`
38
+ `):`**Answered${r}:** ${i} ${d[0]}`}function Fd(s,e){let t=e.trim();if(/^\d+$/.test(t))return s.options[Number(t)-1]?.value??null;let n=t.toLowerCase();return s.options.find(o=>o.label.toLowerCase()===n||o.value.toLowerCase()===n)?.value??null}function Ro(s){let e=s.required?"":", or `skip`";if(s.kind==="text")return`_Reply with ${s.numeric!==void 0?"a number":"a value"}${e}._`;let t=s.kind==="multi"?"option numbers or names, comma-separated":"an option number or name",n=s.customKey!==void 0?", or any text":"";return`_Reply with ${t}${n}${e}._`}var Fs=class s{constructor(e){this.parsed=e}parsed;index=0;answers={};static create(e){let t=$s(e);return t===null?null:new s(t)}get field(){return this.parsed.fields[this.index]}prompt(){let e=this.parsed.fields.length,t=this.field;return e===1?`${Os({mode:"form",message:this.parsed.message,requestedSchema:this.schemaOf(t)})}
39
+ ${Ro(t)}`:`${this.index===0?`**The agent asked:** ${this.parsed.message}
40
+ `:""}Question ${this.index+1} of ${e}: ${xo(t)}
41
+ ${Ro(t)}`}schemaOf(e){return{type:"object",properties:{[e.key]:{type:e.kind==="multi"?"array":"string",title:e.title,...e.kind==="multi"?{items:{anyOf:e.options.map(t=>({const:t.value,title:t.label}))}}:e.kind==="single"?{oneOf:e.options.map(t=>({const:t.value,title:t.label}))}:{}},...e.customKey!==void 0?{[e.customKey]:{type:"string"}}:{}}}}reply(e){let t=this.field,n=e.trim(),r=o=>({type:"retry",message:`${o}
42
+ ${Ro(t)}`});if(n.length===0)return r("Empty reply.");if(!t.required&&/^skip$/i.test(n))return this.advance();if(t.kind==="text"){let o=_d(t,n);return"error"in o?r(`Not accepted: ${o.error}.`):(this.answers[t.key]=o.value,this.advance())}if(t.kind==="single"){let o=Fd(t,n);if(o!==null){let i=t.options.length===2&&t.options[0].value==="true"&&t.options[1].value==="false";return this.answers[t.key]=i?o==="true":o,this.advance()}}else{let o=n.split(",").map(i=>Fd(t,i));if(o.every(i=>i!==null))return this.answers[t.key]=[...new Set(o)],this.advance()}return t.customKey!==void 0?(this.answers[t.customKey]=n,this.advance()):r("Not one of the options.")}advance(){return this.index+=1,this.index>=this.parsed.fields.length?{type:"done",response:{action:"accept",content:this.answers}}:{type:"next",prompt:this.prompt()}}};function Od(s){let e=s.lastIndexOf("/");return(e===-1?s:s.slice(e+1)).toLowerCase()}function Yt(s,e){return Xt(s,e.map(t=>t.modelId))}function Xt(s,e){if(e.length===0)return{kind:"none",requested:s};if(e.includes(s))return{kind:"exact",modelId:s};let t=Od(s),n=e.filter(o=>Od(o)===t);if(n.length===1)return{kind:"resolved",modelId:n[0],requested:s};if(n.length>1)return{kind:"ambiguous",requested:s,candidates:n};let r=s.toLowerCase();if(r.length>0){let o=e.filter(i=>i.toLowerCase().includes(r));if(o.length===1)return{kind:"resolved",modelId:o[0],requested:s};if(o.length>1)return{kind:"ambiguous",requested:s,candidates:o}}return{kind:"unknown",requested:s}}var Jg="Compact conversation",Vg="contextCompaction",Gg=`
37
43
 
38
- Compacting completed.`;function Ig(s){if(!s||s.status!=="completed"||s.sessionUpdate!=="tool_call"&&s.sessionUpdate!=="tool_call_update")return!1;let e=s._meta,t=e!==null&&typeof e=="object"&&bg in e;return s.title===vg||t}function Ag(s){if(!s||s.sessionUpdate!=="agent_message_chunk")return!1;let e=s.content;return!e||typeof e!="object"||Array.isArray(e)?!1:e.text===Sg}function wd(s){return Ig(s)||Ag(s)}var yd=[`## Objective
44
+ Compacting completed.`;function Kg(s){if(!s||s.status!=="completed"||s.sessionUpdate!=="tool_call"&&s.sessionUpdate!=="tool_call_update")return!1;let e=s._meta,t=e!==null&&typeof e=="object"&&Vg in e;return s.title===Jg||t}function Qg(s){if(!s||s.sessionUpdate!=="agent_message_chunk")return!1;let e=s.content;return!e||typeof e!="object"||Array.isArray(e)?!1:e.text===Gg}function Dd(s){return Kg(s)||Qg(s)}var Nd=[`## Objective
39
45
  `,`## Important Details
40
- `],Cg=8e3,Rg=2e4,xg=.5;function kd(s,e){return s!==void 0&&s>=Rg&&e>0&&e<s*xg}var Rs=class{messageId;buffer="";settled=!1;feed(e){if(!e||e.sessionUpdate!=="agent_message_chunk")return!1;let t=e.content;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t.text;if(typeof n!="string")return!1;let r=typeof e.messageId=="string"?e.messageId:void 0;if((r===void 0||r!==this.messageId)&&(this.messageId=r,this.buffer="",this.settled=r===void 0),this.settled)return!1;this.buffer+=n;let o=yd[0],i=this.buffer.slice(0,o.length);return!o.startsWith(i)||this.buffer.length>Cg?(this.settled=!0,this.buffer="",!1):yd.every(a=>this.buffer.includes(a))?(this.settled=!0,this.buffer="",!0):!1}};var vd=`[older history truncated]
41
- `,bd=["file_path","filePath","path","command","pattern","query"];function Qt(s,e={}){let t=e.maxChars??4e5,n=go(s),r=[],o="",i=e.toolOutput?.maxTotal??0,a=()=>{o.length!==0&&(r.push(`Assistant: ${o}`),o="")};for(let d of s){if(d.method!=="session/update")continue;let u=d.params?.update;if(!u||typeof u.sessionUpdate!="string")continue;let l=u.sessionUpdate;if(l==="prompt_received"){a();let w=wo(u.prompt).trim();w.length>0&&r.push(`User: ${w}`)}else if(l==="agent_message_chunk"){let w=ko(u.content);w.length>0&&(o+=w)}else if(l==="tool_call"){if(a(),r.push(yo(u,n)),e.toolOutput!==void 0){let w=ho(u),h=w!==void 0?n.get(w)?.output:void 0;if(h!==void 0&&i>0){let f=Math.min(e.toolOutput.maxPerCall,i),k=h.length<=f?h:`${h.slice(0,f)}\u2026[${h.length-f} more chars]`;r.push(`Output: ${k}`),i-=Math.min(k.length,f)}}}else if(l==="turn_complete"){a();let w=u.errorMessage;typeof w=="string"&&w.length>0&&r.push(`Error: turn failed: ${w}`)}}return a(),Og(r.join(`
42
- `),t)}function go(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=ho(r);if(i===void 0)continue;let a=e.get(i);if(a===void 0&&(a={name:"(unnamed)",rawInput:{}},e.set(i,a)),a.name==="(unnamed)"){let c=Eg(r,o);c!==void 0&&(a.name=c)}if(a.kind===void 0&&typeof r.kind=="string"&&r.kind.length>0&&(a.kind=r.kind),a.output===void 0){let c=xs(r);c!==void 0&&(a.output=c)}let d=r.rawInput;d&&typeof d=="object"&&!Array.isArray(d)&&Object.assign(a.rawInput,d)}for(let t of e.values())t.name=mo(t);return e}function mo(s){return Tg(s)?s.kind??"(unnamed)":s.name}function Tg(s){for(let e of bd){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 Eg(s,e){let t=Rn(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 ho(s){let e=s.toolCallId;if(typeof e=="string"&&e.length>0)return e}function xs(s){let e=Pg(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 Pg(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(`
43
- `)}function Rn(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 yo(s,e){let t=ho(s),n=t!==void 0?e?.get(t):void 0,r=n?.name??Mg(s),o=_g(n?.rawInput??s.rawInput);return o.length===0?`Tool: ${r}`:`Tool: ${r}(${o.join(", ")})`}function Mg(s){let e=Rn(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 _g(s){if(!s||typeof s!="object"||Array.isArray(s))return[];let e=s,t=[];for(let n of bd){let r=e[n];typeof r=="string"&&r.length>0&&t.push(`${n}=${$g(r,600)}`)}return t}function wo(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 ko(s){if(!s||typeof s!="object")return"";let e=s.text;return typeof e=="string"?e:""}function $g(s,e){return s.length<=e?s:s.slice(0,e-1)+"\u2026"}function Og(s,e){if(s.length<=e)return s;let t=s.split(`
44
- `);for(;t.length>0;){let n=vd+t.join(`
45
- `);if(n.length<=e)return n;t.shift()}return vd}var Sd="(untitled)";function vo(s){let e=[],t=s.synopsis;if(t!==void 0){e.push("--- begin prior session compaction ---"),e.push(`[Title] ${s.title??Sd}`),t.goal!==void 0&&t.goal.trim().length>0&&e.push(`[Goal] ${t.goal}`),t.outcome!==void 0&&t.outcome.trim().length>0&&e.push(`[Outcome] ${t.outcome}`);let d=xn("Open threads",t.open_threads);d.length>0&&e.push(d);let c=xn("Decisions",t.decisions);c.length>0&&e.push(c);let u=xn("File edit intentions",t.file_edit_intentions);u.length>0&&e.push(u);let l=xn("Unresolved errors",t.unresolved_errors);l.length>0&&e.push(l);let w=xn("Tool state",t.tool_state);w.length>0&&e.push(w);let h=Id(t.files_touched);h.length>0&&e.push(`[Files previously touched] ${h}`);let f=Id(t.tools_used);f.length>0&&e.push(`[Tools previously used] ${f}`),e.push("--- end prior session compaction ---")}else e.push(`[Title] ${s.title??Sd}`);s.note!==void 0&&s.note.trim().length>0&&e.push(`[Situation] ${s.note.trim()}`);let{closedText:n,openText:r,keptCount:o}=Fg(s.tail,s.tailK,s.watermark??0,s.tailFloor??0);e.push("--- begin recent turns (verbatim, last "+o+") ---"),n.length>0&&e.push(n),e.push("--- end recent turns ---"),r.length>0&&(e.push("--- begin current in-flight turn (no completion yet) ---"),e.push(r),e.push("--- end current in-flight turn ---"));let i=s.recallArmed??!0;e.push("");let a=s.framing??(t!==void 0?"compaction":"fork");return a==="swap"?e.push(i?"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)":"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):a==="compaction"&&i?e.push("(Hydra has compacted earlier conversation. Do NOT call any tools yet. Do NOT read any files, run any commands, or invoke hydra-recall. Reply with the single word 'OK' and wait for the next user message \u2014 at that point you can use the hydra-recall tools to look up specifics on demand if needed.)"):a==="compaction"?e.push("(Hydra has compacted earlier conversation; the turns above are what survives. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):i?e.push("(This is a side conversation forked from another session. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):e.push("(This is a side conversation forked from another session. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"),e.join(`
46
- `)}function xn(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(`
47
- `)}`}function Id(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 Fg(s,e,t,n){if(s.length===0)return{closedText:"",openText:"",keptCount:0};let{closed:r,open:o}=Ng(s),i=0,a=[];if(e>0&&r.length>0){let u=r.filter(h=>h.startEntryIndex>=t).length,l=Math.max(u,n),w=Math.min(l,e,r.length);i=w,a=w>0?r.slice(-w):[]}let d=a.length>0?Ad(a):"",c=o?Ad([o]):"";return{closedText:d,openText:c,keptCount:i}}function Ad(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(`
48
- `)}function Ng(s){let e=[],t=null,n=go(s);for(let o=0;o<s.length;o++){let i=s[o];if(i.method!=="session/update")continue;let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate;if(c==="prompt_received")t!==null&&t.user.length>0&&e.push(t),t={user:wo(d.prompt).trim(),agent:"",tools:[],startEntryIndex:o};else if(c==="agent_message_chunk"&&t!==null){let u=ko(d.content);u.length>0&&(t.agent+=u)}else c==="tool_call"&&t!==null?t.tools.push(yo(d,n)):c==="turn_complete"&&t!==null&&(e.push(t),t=null)}let r=t!==null&&t.user.length>0?t:null;return{closed:e,open:r}}function Rd(s,e){let t=s??[],n=(e??0)>0,r=[],o=new Set,i=t[0];i&&o.add(i.upstreamSessionId);for(let d=1;d<t.length;d++){let c=t[d],u=t[d-1],l={upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,...c.startedAt!==void 0?{at:c.startedAt}:{},...c.endedAt!==void 0?{endedAt:c.endedAt}:{},...c.cost!==void 0?{cost:c.cost}:{},...c.usedAtStart!==void 0?{usedAfter:c.usedAtStart}:{},...u.usedAtEnd!==void 0?{usedBefore:u.usedAtEnd}:{},...c.reason!==void 0?{reason:c.reason}:{},...c.runId!==void 0?{runId:c.runId}:{}};c.reason===void 0&&(c.agentId!==u.agentId?l.inferredReason="agent-swap":o.has(c.upstreamSessionId)?l.inferredReason="rollback":n||(l.notCompaction=!0)),o.add(c.upstreamSessionId),r.push(l)}let a=r.filter(d=>d.reason==="compaction");return{rotations:r,compactions:a,runs:Dg(a),unknownCount:r.filter(d=>d.reason===void 0&&d.inferredReason===void 0&&!d.notCompaction).length}}function Dg(s){let e=[],t;for(let n of s){let r=e[e.length-1];if(r!==void 0&&n.runId!==void 0&&n.runId===t){r.swaps++,r.upstreamSessionId=n.upstreamSessionId,r.current=n.endedAt===void 0,n.cost!==void 0&&(r.cost=(r.cost??0)+n.cost),n.usedAfter!==void 0&&(r.usedAfter=n.usedAfter);continue}e.push({...n.at!==void 0?{at:n.at}:{},upstreamSessionId:n.upstreamSessionId,swaps:1,...n.cost!==void 0?{cost:n.cost}:{},...n.usedBefore!==void 0?{usedBefore:n.usedBefore}:{},...n.usedAfter!==void 0?{usedAfter:n.usedAfter}:{},current:n.endedAt===void 0}),t=n.runId}return e}function Hg(s){if(!s)return"unknown time";let e=Date.parse(s);return Number.isNaN(e)?"unknown time":`${new Date(e).toISOString().slice(0,16)}Z`}function Cd(s){if(s<1e3)return String(s);let e=s/1e3;return e<100?`${e.toFixed(1)}k`:`${Math.round(e)}k`}function jg(s){return s.usedBefore===void 0||s.usedAfter===void 0?"":` ${Cd(s.usedBefore)} \u2192 ${Cd(s.usedAfter)}`}function xd(s){let{runs:e,unknownCount:t}=s,n=[];if(e.length>0){n.push(e.length===1?"Compacted 1 time:":`Compacted ${e.length} times:`);for(let r of e){let o=jg(r),i=r.cost!==void 0?` $${r.cost.toFixed(2)}`:"",a=r.current?" (current)":"",d=r.swaps>1?` (${r.swaps} swaps)`:"";n.push(` ${Hg(r.at)} ${r.upstreamSessionId}${o}${i}${d}${a}`)}}if(t>0){let r=t===1?"rotation":"rotations";n.push(e.length>0?`${t} earlier ${r}, cause not recorded; the count above is a lower bound.`:`No compactions on record. ${t} ${r} predate reason tracking, and any of them may have been a compaction.`)}return n}import*as gt from"path";function Ug(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function bo(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(`${Ug(n)}/(?![/\\s])`,"g");return{text:s.replace(i,(d,c)=>{let u=s.slice(c+d.length),l=u.search(/[\s"'`,;:)\]}]|$/);return o.push(`${n}/${u.slice(0,l<0?void 0:l)}`),`${r}/`}),rewritten:o}}function So(s,e){if(e.length===0)return!1;let t=e.endsWith("/")?e.slice(0,-1):e;return s.includes(t)}function Td(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(`
49
- `)}function Ed(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(`
50
- `)}function Pd(s,e,t){return s.length===0||!gt.isAbsolute(s)||Ts(s,t)?!1:Ts(s,e)}function Ts(s,e){let t=gt.relative(gt.resolve(e),gt.resolve(s));return!(t.length===0||t.startsWith("..")||gt.isAbsolute(t))}Q();import*as Je from"fs/promises";async function Tn(s,e){let t=E.queueFile(s);if(e.length===0){await Je.unlink(t).catch(()=>{});return}await Je.mkdir(E.sessionDir(s),{recursive:!0});let n=e.map(r=>JSON.stringify(r)).join(`
46
+ `],Yg=8e3,Xg=2e4,Zg=.5;function Ld(s,e){return s!==void 0&&s>=Xg&&e>0&&e<s*Zg}var Ns=class{messageId;buffer="";settled=!1;feed(e){if(!e||e.sessionUpdate!=="agent_message_chunk")return!1;let t=e.content;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t.text;if(typeof n!="string")return!1;let r=typeof e.messageId=="string"?e.messageId:void 0;if((r===void 0||r!==this.messageId)&&(this.messageId=r,this.buffer="",this.settled=r===void 0),this.settled)return!1;this.buffer+=n;let o=Nd[0],i=this.buffer.slice(0,o.length);return!o.startsWith(i)||this.buffer.length>Yg?(this.settled=!0,this.buffer="",!1):Nd.every(a=>this.buffer.includes(a))?(this.settled=!0,this.buffer="",!0):!1}};var Hd=`[older history truncated]
47
+ `,jd=["file_path","filePath","path","command","pattern","query"];function Zt(s,e={}){let t=e.maxChars??4e5,n=To(s),r=[],o="",i=e.toolOutput?.maxTotal??0,a=()=>{o.length!==0&&(r.push(`Assistant: ${o}`),o="")};for(let d of s){if(d.method!=="session/update")continue;let u=d.params?.update;if(!u||typeof u.sessionUpdate!="string")continue;let l=u.sessionUpdate;if(l==="prompt_received"){a();let y=_o(u.prompt).trim();y.length>0&&r.push(`User: ${y}`)}else if(l==="agent_message_chunk"){let y=$o(u.content);y.length>0&&(o+=y)}else if(l==="tool_call"){if(a(),r.push(Mo(u,n)),e.toolOutput!==void 0){let y=Po(u),h=y!==void 0?n.get(y)?.output:void 0;if(h!==void 0&&i>0){let f=Math.min(e.toolOutput.maxPerCall,i),k=h.length<=f?h:`${h.slice(0,f)}\u2026[${h.length-f} more chars]`;r.push(`Output: ${k}`),i-=Math.min(k.length,f)}}}else if(l==="turn_complete"){a();let y=u.errorMessage;typeof y=="string"&&y.length>0&&r.push(`Error: turn failed: ${y}`)}}return a(),im(r.join(`
48
+ `),t)}function To(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=Po(r);if(i===void 0)continue;let a=e.get(i);if(a===void 0&&(a={name:"(unnamed)",rawInput:{}},e.set(i,a)),a.name==="(unnamed)"){let c=tm(r,o);c!==void 0&&(a.name=c)}if(a.kind===void 0&&typeof r.kind=="string"&&r.kind.length>0&&(a.kind=r.kind),a.output===void 0){let c=Ds(r);c!==void 0&&(a.output=c)}let d=r.rawInput;d&&typeof d=="object"&&!Array.isArray(d)&&Object.assign(a.rawInput,d)}for(let t of e.values())t.name=Eo(t);return e}function Eo(s){return em(s)?s.kind??"(unnamed)":s.name}function em(s){for(let e of jd){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 tm(s,e){let t=_n(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 Po(s){let e=s.toolCallId;if(typeof e=="string"&&e.length>0)return e}function Ds(s){let e=nm(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 nm(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(`
49
+ `)}function _n(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 Mo(s,e){let t=Po(s),n=t!==void 0?e?.get(t):void 0,r=n?.name??sm(s),o=rm(n?.rawInput??s.rawInput);return o.length===0?`Tool: ${r}`:`Tool: ${r}(${o.join(", ")})`}function sm(s){let e=_n(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 rm(s){if(!s||typeof s!="object"||Array.isArray(s))return[];let e=s,t=[];for(let n of jd){let r=e[n];typeof r=="string"&&r.length>0&&t.push(`${n}=${om(r,600)}`)}return t}function _o(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 $o(s){if(!s||typeof s!="object")return"";let e=s.text;return typeof e=="string"?e:""}function om(s,e){return s.length<=e?s:s.slice(0,e-1)+"\u2026"}function im(s,e){if(s.length<=e)return s;let t=s.split(`
50
+ `);for(;t.length>0;){let n=Hd+t.join(`
51
+ `);if(n.length<=e)return n;t.shift()}return Hd}var Ud="(untitled)";function Fo(s){let e=[],t=s.synopsis;if(t!==void 0){e.push("--- begin prior session compaction ---"),e.push(`[Title] ${s.title??Ud}`),t.goal!==void 0&&t.goal.trim().length>0&&e.push(`[Goal] ${t.goal}`),t.outcome!==void 0&&t.outcome.trim().length>0&&e.push(`[Outcome] ${t.outcome}`);let d=$n("Open threads",t.open_threads);d.length>0&&e.push(d);let c=$n("Decisions",t.decisions);c.length>0&&e.push(c);let u=$n("File edit intentions",t.file_edit_intentions);u.length>0&&e.push(u);let l=$n("Unresolved errors",t.unresolved_errors);l.length>0&&e.push(l);let y=$n("Tool state",t.tool_state);y.length>0&&e.push(y);let h=Bd(t.files_touched);h.length>0&&e.push(`[Files previously touched] ${h}`);let f=Bd(t.tools_used);f.length>0&&e.push(`[Tools previously used] ${f}`),e.push("--- end prior session compaction ---")}else e.push(`[Title] ${s.title??Ud}`);s.note!==void 0&&s.note.trim().length>0&&e.push(`[Situation] ${s.note.trim()}`);let{closedText:n,openText:r,keptCount:o}=am(s.tail,s.tailK,s.watermark??0,s.tailFloor??0);e.push("--- begin recent turns (verbatim, last "+o+") ---"),n.length>0&&e.push(n),e.push("--- end recent turns ---"),r.length>0&&(e.push("--- begin current in-flight turn (no completion yet) ---"),e.push(r),e.push("--- end current in-flight turn ---"));let i=s.recallArmed??!0;e.push("");let a=s.framing??(t!==void 0?"compaction":"fork");return a==="swap"?e.push(i?"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)":"(This session's agent process was replaced; nothing was summarized away. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):a==="compaction"&&i?e.push("(Hydra has compacted earlier conversation. Do NOT call any tools yet. Do NOT read any files, run any commands, or invoke hydra-recall. Reply with the single word 'OK' and wait for the next user message \u2014 at that point you can use the hydra-recall tools to look up specifics on demand if needed.)"):a==="compaction"?e.push("(Hydra has compacted earlier conversation; the turns above are what survives. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):i?e.push("(This is a side conversation forked from another session. The turns above are the most recent; earlier history is available on demand via the hydra-recall tools. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"):e.push("(This is a side conversation forked from another session. The turns above are the most recent. Do NOT call any tools yet. Do NOT read any files or run any commands. Reply with the single word 'OK' and wait for the next user message.)"),e.join(`
52
+ `)}function $n(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(`
53
+ `)}`}function Bd(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 am(s,e,t,n){if(s.length===0)return{closedText:"",openText:"",keptCount:0};let{closed:r,open:o}=dm(s),i=0,a=[];if(e>0&&r.length>0){let u=r.filter(h=>h.startEntryIndex>=t).length,l=Math.max(u,n),y=Math.min(l,e,r.length);i=y,a=y>0?r.slice(-y):[]}let d=a.length>0?Wd(a):"",c=o?Wd([o]):"";return{closedText:d,openText:c,keptCount:i}}function Wd(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(`
54
+ `)}function dm(s){let e=[],t=null,n=To(s);for(let o=0;o<s.length;o++){let i=s[o];if(i.method!=="session/update")continue;let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate;if(c==="prompt_received")t!==null&&t.user.length>0&&e.push(t),t={user:_o(d.prompt).trim(),agent:"",tools:[],startEntryIndex:o};else if(c==="agent_message_chunk"&&t!==null){let u=$o(d.content);u.length>0&&(t.agent+=u)}else c==="tool_call"&&t!==null?t.tools.push(Mo(d,n)):c==="turn_complete"&&t!==null&&(e.push(t),t=null)}let r=t!==null&&t.user.length>0?t:null;return{closed:e,open:r}}function zd(s,e){let t=s??[],n=(e??0)>0,r=[],o=new Set,i=t[0];i&&o.add(i.upstreamSessionId);for(let d=1;d<t.length;d++){let c=t[d],u=t[d-1],l={upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,...c.startedAt!==void 0?{at:c.startedAt}:{},...c.endedAt!==void 0?{endedAt:c.endedAt}:{},...c.cost!==void 0?{cost:c.cost}:{},...c.usedAtStart!==void 0?{usedAfter:c.usedAtStart}:{},...u.usedAtEnd!==void 0?{usedBefore:u.usedAtEnd}:{},...c.reason!==void 0?{reason:c.reason}:{},...c.runId!==void 0?{runId:c.runId}:{}};c.reason===void 0&&(c.agentId!==u.agentId?l.inferredReason="agent-swap":o.has(c.upstreamSessionId)?l.inferredReason="rollback":n||(l.notCompaction=!0)),o.add(c.upstreamSessionId),r.push(l)}let a=r.filter(d=>d.reason==="compaction");return{rotations:r,compactions:a,runs:cm(a),unknownCount:r.filter(d=>d.reason===void 0&&d.inferredReason===void 0&&!d.notCompaction).length}}function cm(s){let e=[],t;for(let n of s){let r=e[e.length-1];if(r!==void 0&&n.runId!==void 0&&n.runId===t){r.swaps++,r.upstreamSessionId=n.upstreamSessionId,r.current=n.endedAt===void 0,n.cost!==void 0&&(r.cost=(r.cost??0)+n.cost),n.usedAfter!==void 0&&(r.usedAfter=n.usedAfter);continue}e.push({...n.at!==void 0?{at:n.at}:{},upstreamSessionId:n.upstreamSessionId,swaps:1,...n.cost!==void 0?{cost:n.cost}:{},...n.usedBefore!==void 0?{usedBefore:n.usedBefore}:{},...n.usedAfter!==void 0?{usedAfter:n.usedAfter}:{},current:n.endedAt===void 0}),t=n.runId}return e}function um(s){if(!s)return"unknown time";let e=Date.parse(s);return Number.isNaN(e)?"unknown time":`${new Date(e).toISOString().slice(0,16)}Z`}function qd(s){if(s<1e3)return String(s);let e=s/1e3;return e<100?`${e.toFixed(1)}k`:`${Math.round(e)}k`}function lm(s){return s.usedBefore===void 0||s.usedAfter===void 0?"":` ${qd(s.usedBefore)} \u2192 ${qd(s.usedAfter)}`}function Jd(s){let{runs:e,unknownCount:t}=s,n=[];if(e.length>0){n.push(e.length===1?"Compacted 1 time:":`Compacted ${e.length} times:`);for(let r of e){let o=lm(r),i=r.cost!==void 0?` $${r.cost.toFixed(2)}`:"",a=r.current?" (current)":"",d=r.swaps>1?` (${r.swaps} swaps)`:"";n.push(` ${um(r.at)} ${r.upstreamSessionId}${o}${i}${d}${a}`)}}if(t>0){let r=t===1?"rotation":"rotations";n.push(e.length>0?`${t} earlier ${r}, cause not recorded; the count above is a lower bound.`:`No compactions on record. ${t} ${r} predate reason tracking, and any of them may have been a compaction.`)}return n}import*as mt from"path";function fm(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Oo(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(`${fm(n)}/(?![/\\s])`,"g");return{text:s.replace(i,(d,c)=>{let u=s.slice(c+d.length),l=u.search(/[\s"'`,;:)\]}]|$/);return o.push(`${n}/${u.slice(0,l<0?void 0:l)}`),`${r}/`}),rewritten:o}}function No(s,e){if(e.length===0)return!1;let t=e.endsWith("/")?e.slice(0,-1):e;return s.includes(t)}function Vd(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(`
55
+ `)}function Gd(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(`
56
+ `)}function Kd(s,e,t){return s.length===0||!mt.isAbsolute(s)||Ls(s,t)?!1:Ls(s,e)}function Ls(s,e){let t=mt.relative(mt.resolve(e),mt.resolve(s));return!(t.length===0||t.startsWith("..")||mt.isAbsolute(t))}Q();import*as Ve from"fs/promises";async function Fn(s,e){let t=E.queueFile(s);if(e.length===0){await Ve.unlink(t).catch(()=>{});return}await Ve.mkdir(E.sessionDir(s),{recursive:!0});let n=e.map(r=>JSON.stringify(r)).join(`
51
57
  `)+`
52
- `;await Je.writeFile(t,n,"utf8")}async function Md(s){let e=E.queueFile(s),t;try{t=await Je.readFile(e,"utf8")}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t.split(`
53
- `))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 _d(s){let e=E.queueFile(s);await Je.unlink(e).catch(()=>{})}import*as qd from"fs/promises";var Bd="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Wd=Ld(Bd,16),Io=Ld(Bd,16),Lg=2e3,Bg=20,Wg=20,qg=5,zg=32,ye="hydra_session_";function Ve(){return`m_${Wd()}`}function tt(s){let e=pt(s)?.localId??s;return e.startsWith(ye)?e.slice(ye.length):e}var $d=["start","merge","apply","sync","stop","detach","discard","clean","status"],Jg=1e3,Es=300*1e3,Vg=64,Gg=new Set(["task-notification","peer","coordinator","observer","observer-activity"]);function Kg(s){let e=s?.update;if(!e||typeof e!="object"||e.sessionUpdate!=="usage_update")return!1;let t=e._meta;if(!t||typeof t!="object")return!1;let n=t["_claude/origin"];if(!n||typeof n!="object")return!1;let r=n.kind;return typeof r=="string"&&Gg.has(r)}function Od(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="usage_update"}function Qg(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="tool_call_update"}function Yg(s,e){return e===void 0?!1:s.some(t=>{if(!t||typeof t!="object")return!1;let n=t.id;return typeof n=="string"&&n.trim()!==""&&n.trim()!==e})}var Ao=120;function Xg(s){let e=s.split(`
54
- `).map(t=>t.trim()).filter(t=>t!=="");return e.length===0?"":e[e.length-1]}var Zg=128,em=new Set(["local_bash"]),tm=1e3,nm=1e4,Yt=class s{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=qe;modelVerbConfirmed=!1;agentArgs;parentSessionId;forkedFromSessionId;forkedFromMessageId;side;forkSynthesisState;originatingClient;_interactive;get interactive(){return this._interactive}_priority;get priority(){return this._priority}_lastTurnEndedAt;get lastTurnEndedAt(){return this._lastTurnEndedAt}_readAt;get readAt(){return this._readAt}title;_summarizedThroughEntry;get summarizedThroughEntry(){return this._summarizedThroughEntry}set summarizedThroughEntry(e){this._summarizedThroughEntry=e}currentModel;currentMode;compactionState;_currentUsage;updatedAt;createdAt;clients=new Map;historyStore;promptQueue=[];currentEntry;promptInFlight=!1;agentTurnInFlight=!1;swapInFlight=!1;opencodeSummary=new Rs;modeChangeInFlight=!1;modelChangeInFlight=!1;queueWriteChain=Promise.resolve();closed=!1;closing=!1;closeInFlight;deleteRecordIntent=!1;closeHandlers=[];titleHandlers=[];scheduleSynopsisHook;scheduleWorkspaceSnapshotHook;scheduleCompactionHook;resolveAgentIdHook;getCompactionStateHook;getUpstreamGenerationsHook;getPendingAgentSwapHook;_liveCompactionPhase;broadcastHandlers=[];lastCancelAt=0;static CANCEL_ERROR_WINDOW_MS=2e3;lastUnsolicitedCancelAt=0;cancelReopenStreak=0;static UNSOLICITED_REOPEN_WINDOW_MS=1e4;static UNSOLICITED_REOPEN_LIMIT=3;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}_titleSeedPending=!0;_upstreamRespawned=!1;promptStartedAt;turnRanTool=!1;unsolicitedTurn;pendingSteerDetach;supersededAutonomousTurn;autonomousSalvage;lastBackgroundTask;toolLabels=new Map;armedTasks=new Map;upstreamBaselineMs;upstreamBaselineGen=0;upstreamPollTimer;lastArmedBroadcast;liveBackgroundTasks=new Map;sawBackgroundTaskLevel=!1;sawTurnComplete=!1;appendCount=0;historyMaxEntries;compactEvery;permissionCallbacks=new Map;attentionFlags=new Map;get hasPermissionFlag(){for(let e of this.attentionFlags.values())if(e.source==="daemon"&&e.reason.startsWith("permission:"))return!0;return!1}attentionFlagsChangeHandlers=[];internalPromptCapture;idleTimeoutMs;backgroundTaskTracking;idleTimer;orphanTimeoutMs;orphanTimer;idleEventTimeoutMs;idleHandlers=[];lastRecordedAt;lastSeq=0;spawnReplacementAgent;mintMcpServersForSwap;loadExistingAgentSession;clearRollbackBreadcrumbHook;onCompactionSwapHook;persistWatermarkHook;uncompactHook;rewindHook;forkHook;mcpServersConfig;forwardedEnv;workspace;workspaceError;workspaceNotes=[];workspaceHook;workspacePreambleSent=!1;formerWorkspace;departureNoteSent=!1;listSessions;logger;transformChain;extensionCommands;extensionCommandsUnsub;pendingClaims=new Map;toolCompletionSeen=new Map;toolCallKind=new ks;filesEditedSeen=new Set;openToolCalls=new Map;agentChangeHandlers=[];retiringGenerationCost;retiringGenerationUsed;rotationLifetimeCost;agentAdvertisedCommands=[];agentAdvertisedModes=[];agentAdvertisedModels=[];agentAdvertisedConfigOptions=[];agentCommandsHandlers=[];agentModesHandlers=[];agentModelsHandlers=[];configOptionsHandlers=[];availableAgentsFn;modelHandlers=[];modeHandlers=[];interactiveHandlers=[];priorityHandlers=[];readStateHandlers=[];usageHandlers=[];cumulativeCost=0;costLedgerProbe;get persistableUsage(){if(!(!this._currentUsage&&!this.cumulativeCost))return{...this._currentUsage??{},...this.cumulativeCost?{cumulativeCost:this.cumulativeCost}:{cumulativeCost:void 0}}}get currentUsage(){if(!this._currentUsage&&!this.cumulativeCost)return;let e=this._currentUsage??{},t=this.cumulativeCost+(e.costAmount??0);return{...e,costAmount:t||void 0,cumulativeCost:void 0}}amendInProgress;inFlightExtensionDispatches=new Map;recentlyTerminal=new Map;pendingTurnNotifiers=new Map;streamBuffer;streamFilePath;constructor(e){if(this.sessionId=e.sessionId??`${ye}${Wd()}`,this.cwd=e.cwd,this.workspace=e.workspace,this.workspaceError=e.workspaceError,this.workspaceHook=e.workspaceHook,this.agentId=e.agentId,this.agent=e.agent,this.upstreamSessionId=e.upstreamSessionId,this.agentMeta=e.agentMeta,this.agentCapabilities=e.agentCapabilities,this.agentArgs=e.agentArgs,this.parentSessionId=e.parentSessionId,this.forkedFromSessionId=e.forkedFromSessionId,this.forkedFromMessageId=e.forkedFromMessageId,this.side=e.side,this.forkSynthesisState=e.forkSynthesisState,this.originatingClient=e.originatingClient,this.title=e.title,this.scheduleSynopsisHook=e.scheduleSynopsis,this.scheduleWorkspaceSnapshotHook=e.scheduleWorkspaceSnapshot,this.scheduleCompactionHook=e.scheduleCompaction,this.resolveAgentIdHook=e.resolveAgentId,this.getCompactionStateHook=e.getCompactionState,this.getUpstreamGenerationsHook=e.getUpstreamGenerations,this.getPendingAgentSwapHook=e.getPendingAgentSwap,this.currentModel=e.currentModel,this.currentMode=e.currentMode,this._currentUsage=e.currentUsage,this.cumulativeCost=e.currentUsage?.cumulativeCost??0,e.reloadsUpstreamLedger&&this.armCostLedgerProbe(),e.agentCommands&&e.agentCommands.length>0&&(this.agentAdvertisedCommands=[...e.agentCommands]),e.agentModes&&e.agentModes.length>0&&(this.agentAdvertisedModes=[...e.agentModes]),e.agentModels&&e.agentModels.length>0&&(this.agentAdvertisedModels=[...e.agentModels]),e.agentConfigOptions&&e.agentConfigOptions.length>0&&(this.agentAdvertisedConfigOptions=[...e.agentConfigOptions]),this.idleTimeoutMs=e.idleTimeoutMs??0,this.backgroundTaskTracking=e.backgroundTaskTracking,this.orphanTimeoutMs=e.orphanTimeoutMs??0,this.idleEventTimeoutMs=e.idleEventTimeoutMs??3e4,this.idleEventTimeoutMs>0&&this.onIdle(t=>t.notifyChain("session.idle",{}),{debounceMs:this.idleEventTimeoutMs}),this.spawnReplacementAgent=e.spawnReplacementAgent,this.mintMcpServersForSwap=e.mintMcpServersForSwap,this.loadExistingAgentSession=e.loadExistingAgentSession,this.clearRollbackBreadcrumbHook=e.clearRollbackBreadcrumbHook,this.onCompactionSwapHook=e.onCompactionSwapHook,this.persistWatermarkHook=e.persistWatermarkHook,this.uncompactHook=e.uncompactHook,this.forkHook=e.forkHook,this.mcpServersConfig=e.mcpServers,this.forwardedEnv=e.forwardedEnv,this.availableAgentsFn=e.availableAgents,this.listSessions=e.listSessions,this.logger=e.logger,this.transformChain=e.transformChain??[],this.extensionCommands=e.extensionCommands,this.extensionCommands&&(this.extensionCommandsUnsub=this.extensionCommands.onChange(()=>{this.closed||this.broadcastMergedCommands()})),e.firstPromptSeeded&&(this._firstPromptSeeded=!0,this._titleSeedPending=!1),e.upstreamRespawned&&(this._upstreamRespawned=!0),this._interactive=e.interactive,this._priority=e.priority,this._lastTurnEndedAt=e.lastTurnEndedAt,this._readAt=e.readAt,this._summarizedThroughEntry=e.summarizedThroughEntry,this.compactionState=e.compactionState,e.compactionState){let t=e.compactionState;(t.status==="requested"||t.status==="running"||t.status==="swap_pending"||t.status==="swap_deferred")&&(t.status==="swap_deferred"?this._liveCompactionPhase={phase:"deferred",attempts:t.attempts}:this._liveCompactionPhase={phase:t.status==="requested"?"started":"iteration",iter:t.iter})}if(e.attentionFlags&&e.attentionFlags.length>0)for(let t of e.attentionFlags)this.attentionFlags.set(`${t.source}::${t.reason}`,t);this.historyStore=e.historyStore,this.historyMaxEntries=e.historyMaxEntries??Jg,this.compactEvery=Math.max(1,Math.floor(this.historyMaxEntries*.2)),this.updatedAt=Date.now(),this.createdAt=e.createdAt??this.updatedAt,this.lastRecordedAt=this.updatedAt,this.resetModelVerb(e.modelVerb),this.wireAgent(this.agent),this.scheduleIdleCheck(),this.notifyChain("session.opened",{})}broadcastMergedCommands(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"available_commands_update",availableCommands:this.mergedAvailableCommands()}})}broadcastAvailableModes(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:this.agentAdvertisedModes}})}broadcastAvailableModels(){let e={sessionUpdate:"_hydra_current_model_update",availableModels:[...this.agentAdvertisedModels]};this.currentModel!==void 0&&this.currentModel.length>0&&(e.currentModel=this.currentModel),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:e})}wireAgent(e,t){this.resetBackgroundTaskLevel(),t?.respawn&&(this._upstreamRespawned=!0),e.connection.onNotification("session/update",n=>{if(this.internalPromptCapture){hm(this.internalPromptCapture,n);return}this.maybeEmitToolEdges(n),this.runResponseChain(n)}),e.connection.onNotification("_claude/sdkMessage",n=>{this.applyBackgroundTaskLevel(n)}),e.connection.onRequest("session/request_permission",async n=>{let r=await this.runAgentRequestChain("session/request_permission",n),o=Hd(r.shortCircuit?n:r.envelope);if(r.shortCircuit)return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:r.payload,sourceWasTransformer:!0}),r.payload;let i=await this.handlePermissionRequest(r.envelope);return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:i,sourceWasTransformer:!1}),i}),typeof e.connection.onOrphanError=="function"&&e.connection.onOrphanError(n=>{this.handleOrphanError(n)}),e.onExit(()=>{this.agent===e&&this.markClosed({deleteRecord:!1})})}handleOrphanError(e){let t=Date.now()-this.lastCancelAt;if(this.lastCancelAt===0||t>s.CANCEL_ERROR_WINDOW_MS){this.logger?.warn(`agent ${this.agentId} sent uncorrelated error frame code=${e.code} message=${e.message}`);return}this.lastCancelAt=0,this.logger?.warn(`agent ${this.agentId} rejected session/cancel code=${e.code} message=${e.message}`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,code:e.code,message:e.message})}async runResponseChain(e,t=new Set,n=0,r="session/update"){let o=e,i=r==="session/update"?this.injectCumulativeCost(e):e,a=`response:${r}`;for(let l=n;l<this.transformChain.length;l++){let w=this.transformChain[l];if(t.has(w.name)||!w.intercepts.has(a))continue;let h=`t_${Io()}`,f;try{f=await w.connection.request("hydra-acp/transformer/message",{token:h,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(p){this.logger?.warn(`transformer ${w.name} error on ${a}: ${p.message}`);continue}let k=f?.action??"continue";if(k==="stop")return;if(k==="processing"){let p=l,g=i,y=new Set(t),m=r;await new Promise(v=>{let S=setTimeout(()=>{this.pendingClaims.delete(h)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:h,transformerName:w.name}),this.runResponseChain(g,new Set([...y,w.name]),p+1,m).then(()=>v()).catch(()=>v()))},Es);typeof S.unref=="function"&&S.unref(),this.pendingClaims.set(h,{resolve:()=>v(),timer:S,transformerName:w.name,method:m,envelope:g,chainIdx:p,originatedBy:y,side:"response"})});return}f?.payload&&typeof f.payload=="object"&&(i=f.payload),t.add(w.name)}if(r!=="session/update")return;this.noteAgentActivity(i);let d=i.update;(wd(d)||this.agentId==="opencode"&&this.opencodeSummary.feed(d))&&this.armRecallFromSelfCompaction();let c=ym(i);if(c!==null){this.setAgentAdvertisedCommands(c);return}let u=mm(i);if(u!==null){this.setAgentAdvertisedModes(u);return}if(this.noteModelVerbHint(Ja(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",ld(i))}armRecallFromSelfCompaction(){this.armRecallInPlace().catch(e=>{this.logger?.warn(`armRecallInPlace failed: ${e.message}`)})}async armRecallInPlace(){if(!this.historyStore)return;let e=await this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0);if(!(e<=(this._summarizedThroughEntry??0))){if(this._summarizedThroughEntry=e,this.persistWatermarkHook)try{this.persistWatermarkHook(e)}catch(t){this.logger?.warn(`armRecallInPlace: persistWatermarkHook failed: ${t.message}`)}this.broadcastQueueNotification("hydra-acp/context_self_compacted",{sessionId:this.sessionId})}}onAgentChange(e){this.agentChangeHandlers.push(e)}get attachedCount(){return this.clients.size}connectedClients(e){let t=[];for(let n of this.clients.values()){if(e&&n.clientId===e)continue;let r={clientId:n.clientId};n.clientInfo?.name&&(r.name=n.clientInfo.name),n.clientInfo?.version&&(r.version=n.clientInfo.version),t.push(r)}return t}get turnStartedAt(){return this.promptStartedAt}get inUnsolicitedTurn(){return this.unsolicitedTurn!==void 0}get agentPid(){return this.agent.pid}get awaitingInput(){return this.attentionFlags.size>0}async isQuiescedForSwap(){return await this.quiesceBlocker()===void 0}async quiesceBlocker(){if(this.agentTurnInFlight)return"the agent is still working; wait for the current turn to finish, then try again";if(this.unsolicitedTurn!==void 0)return"the agent is part-way through a turn it started by itself; wait for it to finish or interrupt it (^C), then try again";if(this.internalPromptCapture!==void 0)return"hydra is driving the agent right now (compaction seed or transcript injection); this clears by itself, so try again in a moment";if(this.modelChangeInFlight)return"a model change is still settling; try again in a moment";if(this.modeChangeInFlight)return"a mode change is still settling; try again in a moment";let e=this.pendingOneShotBackgroundTasks();if(e.length>0)return`${e.length} background task(s) still running (${e.join(", ")}); a swap would kill the agent process and abandon them. Wait for them to finish, or cancel them, then try again`;let t=await this.openToolCallIdsInHistory();if(t.length>0)return`${t.length} tool call(s) from an earlier turn never reported a result, so the session still reads as busy. ^C closes an abandoned chain; failing that it clears as new history accumulates`}isQuiescedSync(){return!(this.promptInFlight||this.unsolicitedTurn!==void 0||this.modeChangeInFlight||this.modelChangeInFlight)}async swapIntoWorkspace(e){await this.swapUpstream({...e.synopsis!==void 0?{artifact:e.synopsis}:{},note:e.note,framing:"swap",...e.title!==void 0?{title:e.title}:{},tailK:8,tailFloor:4,summarizedThroughEntry:e.historyLength,newCwd:e.cwd,reason:e.workspace!==void 0?"workspace-enter":"workspace-leave"}),this.workspace=e.workspace,e.left!==void 0?(this.formerWorkspace={path:e.left.path,sourceCwd:e.cwd,removed:e.left.removed},this.departureNoteSent=!1):this.formerWorkspace=void 0}async swapUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for swap: ${t}`);if(this.swapInFlight)throw new Error("a swap is already in progress for this session");this.swapInFlight=!0;try{await this.doSwapUpstream(e)}finally{this.swapInFlight=!1}}async doSwapUpstream(e){this.notifyChain("agent.swap",{phase:"pre",previousUpstreamSessionId:this.upstreamSessionId,agentId:this.agentId});let t=this.agentId,n=e.newAgentId??this.agentId,r=n!==this.agentId,o=e.reason!==void 0&&e.reason!=="compaction"?e.reason:r?"agent-swap":"compaction",i=e.newCwd??this.cwd,a=this.agentArgs,d=this.forwardedEnv,c=this.currentModel,u=this.currentMode,l=this.spawnReplacementAgent;if(!l)throw new Error("agent spawning not configured for this session");let w=this.mintMcpServersForSwap?await this.mintMcpServersForSwap(this):this.mcpServersConfig??[],h=await l({agentId:n,cwd:i,agentArgs:a,...d?{forwardedEnv:d}:{},mcpServers:w});if(this.accumulateAndResetCost(),this.cwd=i,this.wireAgent(h.agent,{respawn:!0}),!r){let P=await ft({agent:h.agent,upstreamSessionId:h.upstreamSessionId,persistedModel:c,agentReportedModel:h.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(P.result,"model"),await lt({agent:h.agent,upstreamSessionId:h.upstreamSessionId,persistedMode:u,agentReportedMode:h.initialMode,logger:this.logger})}h.agent.connection.drainBuffered("session/update");let f=[];if(this.historyStore)try{f=await this.historyStore.load(this.sessionId)}catch(P){this.logger?.warn(`swapUpstream: historyStore.load failed: ${P.message}`)}let k=vo({...e.artifact!==void 0?{synopsis:e.artifact}:{},...e.note!==void 0?{note:e.note}:{},...e.framing!==void 0?{framing:e.framing}:{},title:e.title,tail: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};let p,g;try{await h.agent.connection.request("session/prompt",{sessionId:h.upstreamSessionId,prompt:[{type:"text",text:k}]});let P=this.internalPromptCapture;p=P.lastUsed,g=P.lastSize,this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${k.length} toolCalls=${P.toolCalls} thinkingChars=${P.thinkingChars} messageChars=${P.messageChars} used=${P.lastUsed??"?"} size=${P.lastSize??"?"} reply=${JSON.stringify(P.chunks.join("").slice(0,200))}`)}finally{this.internalPromptCapture=void 0}p!==void 0&&(this.maybeApplyAgentUsage({update:{sessionUpdate:"usage_update",used:p,...g!==void 0?{size:g}:{}}}),this.broadcastCurrentUsage());let y=this.upstreamSessionId,m=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let v=this.agent;if(this.agent=h.agent,this.upstreamSessionId=h.upstreamSessionId,this.agentMeta=h.agentMeta,this.agentCapabilities=h.agentCapabilities,this.resetModelVerb(h.modelVerb),this.sawTurnComplete=!1,r&&(this.agentId=n,this.agentAdvertisedCommands=[],this.currentModel=h.initialModel,this.currentMode=h.initialMode,this.setAgentAdvertisedModels(h.initialModels??[]),this.setAgentAdvertisedModes(h.initialModes??[]),this.agentAdvertisedConfigOptions=h.initialConfigOptions??[]),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream",o,e.runId,p),e.summarizedThroughEntry!==void 0&&this.persistWatermarkHook)try{this.persistWatermarkHook(e.summarizedThroughEntry)}catch(P){this.logger?.warn(`swapUpstream: persistWatermarkHook failed: ${P.message}`)}if(!r&&this.onCompactionSwapHook)try{this.onCompactionSwapHook({previousUpstreamSessionId:y,...m!==void 0?{previousSummarizedThroughEntry:m}:{},...e.runId!==void 0?{runId:e.runId}:{}})}catch(P){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${P.message}`)}let S=await this.retireAgent(v,r?"agent switch":e.reason==="workspace-enter"||e.reason==="workspace-leave"?"workspace move":"compaction swap");this.notifyChain("agent.swap",{phase:"post",previousUpstreamSessionId:y,upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}),r||this.broadcastCompactionPhase({phase:"swapped",...this.title!==void 0?{title:this.title}:{},summarizedThroughEntry:e.summarizedThroughEntry??this._summarizedThroughEntry??0}),r&&this.broadcastAgentSwitch(t,n);let b=S.length>0?`
58
+ `;await Ve.writeFile(t,n,"utf8")}async function Qd(s){let e=E.queueFile(s),t;try{t=await Ve.readFile(e,"utf8")}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t.split(`
59
+ `))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 Yd(s){let e=E.queueFile(s);await Ve.unlink(e).catch(()=>{})}import*as uc from"fs/promises";var pm=/^[a-z0-9][a-z0-9._/-]*$/;function en(s){let e=s.trim().replace(/^#/,"").toLowerCase();if(!(e.length===0||e.length>40))return pm.test(e)?e:void 0}function xt(s){let e=[];for(let t of s){let n=en(t);n!==void 0&&!e.includes(n)&&e.push(n)}return e.slice(0,16)}function Xd(s,e){let t=s??[],n=e??[];return t.length===n.length&&t.every((r,o)=>r===n[o])}var dc="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",cc=ac(dc,16),Do=ac(dc,16),gm=2e3,mm=20,hm=20,ym=5,wm=32,ye="hydra_session_";function Oe(){return`m_${cc()}`}function nt(s){let e=gt(s)?.localId??s;return e.startsWith(ye)?e.slice(ye.length):e}var Zd=["start","merge","apply","sync","stop","detach","discard","clean","status"],km=1e3,Hs=300*1e3,vm=64,bm=new Set(["task-notification","peer","coordinator","observer","observer-activity"]);function Sm(s){let e=s?.update;if(!e||typeof e!="object"||e.sessionUpdate!=="usage_update")return!1;let t=e._meta;if(!t||typeof t!="object")return!1;let n=t["_claude/origin"];if(!n||typeof n!="object")return!1;let r=n.kind;return typeof r=="string"&&bm.has(r)}function ec(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="usage_update"}function Im(s){let e=s?.update;return!!e&&typeof e=="object"&&e.sessionUpdate==="tool_call_update"}function Am(s,e){return e===void 0?!1:s.some(t=>{if(!t||typeof t!="object")return!1;let n=t.id;return typeof n=="string"&&n.trim()!==""&&n.trim()!==e})}var Lo=120;function Cm(s){let e=s.split(`
60
+ `).map(t=>t.trim()).filter(t=>t!=="");return e.length===0?"":e[e.length-1]}var Rm=128,xm=new Set(["local_bash"]),Tm=1e3,Em=1e4,nn=class s{sessionId;cwd;agentId;agent;upstreamSessionId;agentMeta;agentCapabilities;modelVerb=ze;modelVerbConfirmed=!1;agentArgs;parentSessionId;forkedFromSessionId;forkedFromMessageId;side;forkSynthesisState;originatingClient;_interactive;get interactive(){return this._interactive}_priority;_tags;get tags(){return this._tags}get priority(){return this._priority}_lastTurnEndedAt;get lastTurnEndedAt(){return this._lastTurnEndedAt}_readAt;get readAt(){return this._readAt}title;_summarizedThroughEntry;get summarizedThroughEntry(){return this._summarizedThroughEntry}set summarizedThroughEntry(e){this._summarizedThroughEntry=e}currentModel;currentMode;compactionState;_currentUsage;updatedAt;createdAt;clients=new Map;historyStore;promptQueue=[];currentEntry;promptInFlight=!1;agentTurnInFlight=!1;swapInFlight=!1;opencodeSummary=new Ns;modeChangeInFlight=!1;modelChangeInFlight=!1;queueWriteChain=Promise.resolve();closed=!1;closing=!1;closeInFlight;deleteRecordIntent=!1;closeHandlers=[];titleHandlers=[];scheduleSynopsisHook;scheduleWorkspaceSnapshotHook;scheduleCompactionHook;resolveAgentIdHook;getCompactionStateHook;getUpstreamGenerationsHook;getPendingAgentSwapHook;_liveCompactionPhase;broadcastHandlers=[];lastCancelAt=0;static CANCEL_ERROR_WINDOW_MS=2e3;lastUnsolicitedCancelAt=0;cancelReopenStreak=0;static UNSOLICITED_REOPEN_WINDOW_MS=1e4;static UNSOLICITED_REOPEN_LIMIT=3;forceCancelling=!1;_firstPromptSeeded=!1;get firstPromptSeeded(){return this._firstPromptSeeded}_titleSeedPending=!0;_upstreamRespawned=!1;promptStartedAt;turnRanTool=!1;unsolicitedTurn;pendingSteerDetach;supersededAutonomousTurn;autonomousSalvage;lastBackgroundTask;toolLabels=new Map;armedTasks=new Map;upstreamBaselineMs;upstreamBaselineGen=0;upstreamPollTimer;lastArmedBroadcast;liveBackgroundTasks=new Map;sawBackgroundTaskLevel=!1;sawTurnComplete=!1;appendCount=0;historyMaxEntries;compactEvery;permissionCallbacks=new Map;elicitationCallbacks=new Map;elicitationCancellers=new Map;permissionCancellers=new Map;elicitationQuestions=new Map;elicitationAnswerers=new Map;attentionFlags=new Map;get hasPermissionFlag(){for(let e of this.attentionFlags.values())if(e.source==="daemon"&&(e.reason.startsWith("permission:")||e.reason.startsWith("elicitation:")))return!0;return!1}attentionFlagsChangeHandlers=[];internalPromptCapture;idleTimeoutMs;backgroundTaskTracking;idleTimer;orphanTimeoutMs;orphanTimer;idleEventTimeoutMs;idleHandlers=[];lastRecordedAt;lastSeq=0;spawnReplacementAgent;mintMcpServersForSwap;loadExistingAgentSession;clearRollbackBreadcrumbHook;onCompactionSwapHook;persistWatermarkHook;uncompactHook;rewindHook;forkHook;mcpServersConfig;forwardedEnv;elicitationForms;workspace;workspaceError;workspaceNotes=[];workspaceHook;workspacePreambleSent=!1;formerWorkspace;departureNoteSent=!1;listSessions;logger;transformChain;extensionCommands;extensionCommandsUnsub;pendingClaims=new Map;toolCompletionSeen=new Map;toolCallKind=new Cs;filesEditedSeen=new Set;openToolCalls=new Map;agentChangeHandlers=[];retiringGenerationCost;retiringGenerationUsed;rotationLifetimeCost;agentAdvertisedCommands=[];agentAdvertisedModes=[];agentAdvertisedModels=[];agentAdvertisedConfigOptions=[];agentCommandsHandlers=[];agentModesHandlers=[];agentModelsHandlers=[];configOptionsHandlers=[];availableAgentsFn;modelHandlers=[];modeHandlers=[];interactiveHandlers=[];priorityHandlers=[];tagsHandlers=[];readStateHandlers=[];usageHandlers=[];cumulativeCost=0;costLedgerProbe;get persistableUsage(){if(!(!this._currentUsage&&!this.cumulativeCost))return{...this._currentUsage??{},...this.cumulativeCost?{cumulativeCost:this.cumulativeCost}:{cumulativeCost:void 0}}}get currentUsage(){if(!this._currentUsage&&!this.cumulativeCost)return;let e=this._currentUsage??{},t=this.cumulativeCost+(e.costAmount??0);return{...e,costAmount:t||void 0,cumulativeCost:void 0}}amendInProgress;inFlightExtensionDispatches=new Map;recentlyTerminal=new Map;pendingTurnNotifiers=new Map;streamBuffer;streamFilePath;constructor(e){if(this.sessionId=e.sessionId??`${ye}${cc()}`,this.cwd=e.cwd,this.workspace=e.workspace,this.workspaceError=e.workspaceError,this.workspaceHook=e.workspaceHook,this.agentId=e.agentId,this.agent=e.agent,this.upstreamSessionId=e.upstreamSessionId,this.agentMeta=e.agentMeta,this.agentCapabilities=e.agentCapabilities,this.agentArgs=e.agentArgs,this.parentSessionId=e.parentSessionId,this.forkedFromSessionId=e.forkedFromSessionId,this.forkedFromMessageId=e.forkedFromMessageId,this.side=e.side,this.forkSynthesisState=e.forkSynthesisState,this.originatingClient=e.originatingClient,this.title=e.title,this.scheduleSynopsisHook=e.scheduleSynopsis,this.scheduleWorkspaceSnapshotHook=e.scheduleWorkspaceSnapshot,this.scheduleCompactionHook=e.scheduleCompaction,this.resolveAgentIdHook=e.resolveAgentId,this.getCompactionStateHook=e.getCompactionState,this.getUpstreamGenerationsHook=e.getUpstreamGenerations,this.getPendingAgentSwapHook=e.getPendingAgentSwap,this.currentModel=e.currentModel,this.currentMode=e.currentMode,this._currentUsage=e.currentUsage,this.cumulativeCost=e.currentUsage?.cumulativeCost??0,e.reloadsUpstreamLedger&&this.armCostLedgerProbe(),e.agentCommands&&e.agentCommands.length>0&&(this.agentAdvertisedCommands=[...e.agentCommands]),e.agentModes&&e.agentModes.length>0&&(this.agentAdvertisedModes=[...e.agentModes]),e.agentModels&&e.agentModels.length>0&&(this.agentAdvertisedModels=[...e.agentModels]),e.agentConfigOptions&&e.agentConfigOptions.length>0&&(this.agentAdvertisedConfigOptions=[...e.agentConfigOptions]),this.idleTimeoutMs=e.idleTimeoutMs??0,this.backgroundTaskTracking=e.backgroundTaskTracking,this.orphanTimeoutMs=e.orphanTimeoutMs??0,this.idleEventTimeoutMs=e.idleEventTimeoutMs??3e4,this.idleEventTimeoutMs>0&&this.onIdle(t=>t.notifyChain("session.idle",{}),{debounceMs:this.idleEventTimeoutMs}),this.spawnReplacementAgent=e.spawnReplacementAgent,this.mintMcpServersForSwap=e.mintMcpServersForSwap,this.loadExistingAgentSession=e.loadExistingAgentSession,this.clearRollbackBreadcrumbHook=e.clearRollbackBreadcrumbHook,this.onCompactionSwapHook=e.onCompactionSwapHook,this.persistWatermarkHook=e.persistWatermarkHook,this.uncompactHook=e.uncompactHook,this.forkHook=e.forkHook,this.mcpServersConfig=e.mcpServers,this.forwardedEnv=e.forwardedEnv,this.elicitationForms=e.elicitationForms,this.availableAgentsFn=e.availableAgents,this.listSessions=e.listSessions,this.logger=e.logger,this.transformChain=e.transformChain??[],this.extensionCommands=e.extensionCommands,this.extensionCommands&&(this.extensionCommandsUnsub=this.extensionCommands.onChange(()=>{this.closed||this.broadcastMergedCommands()})),e.firstPromptSeeded&&(this._firstPromptSeeded=!0,this._titleSeedPending=!1),e.upstreamRespawned&&(this._upstreamRespawned=!0),this._interactive=e.interactive,this._priority=e.priority,this._tags=e.tags!==void 0&&e.tags.length>0?xt(e.tags):void 0,this._lastTurnEndedAt=e.lastTurnEndedAt,this._readAt=e.readAt,this._summarizedThroughEntry=e.summarizedThroughEntry,this.compactionState=e.compactionState,e.compactionState){let t=e.compactionState;(t.status==="requested"||t.status==="running"||t.status==="swap_pending"||t.status==="swap_deferred")&&(t.status==="swap_deferred"?this._liveCompactionPhase={phase:"deferred",attempts:t.attempts}:this._liveCompactionPhase={phase:t.status==="requested"?"started":"iteration",iter:t.iter})}if(e.attentionFlags&&e.attentionFlags.length>0)for(let t of e.attentionFlags)this.attentionFlags.set(`${t.source}::${t.reason}`,t);this.historyStore=e.historyStore,this.historyMaxEntries=e.historyMaxEntries??km,this.compactEvery=Math.max(1,Math.floor(this.historyMaxEntries*.2)),this.updatedAt=Date.now(),this.createdAt=e.createdAt??this.updatedAt,this.lastRecordedAt=this.updatedAt,this.resetModelVerb(e.modelVerb),this.wireAgent(this.agent),this.scheduleIdleCheck(),this.notifyChain("session.opened",{})}broadcastMergedCommands(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"available_commands_update",availableCommands:this.mergedAvailableCommands()}})}broadcastAvailableModes(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:this.agentAdvertisedModes}})}broadcastAvailableModels(){let e={sessionUpdate:"_hydra_current_model_update",availableModels:[...this.agentAdvertisedModels]};this.currentModel!==void 0&&this.currentModel.length>0&&(e.currentModel=this.currentModel),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:e})}wireAgent(e,t){this.resetBackgroundTaskLevel(),t?.respawn&&(this._upstreamRespawned=!0),e.connection.onNotification("session/update",n=>{if(this.internalPromptCapture){Wm(this.internalPromptCapture,n);return}this.maybeEmitToolEdges(n),this.runResponseChain(n)}),e.connection.onNotification("_claude/sdkMessage",n=>{this.applyBackgroundTaskLevel(n)}),e.connection.onRequest("session/request_permission",async n=>{let r=await this.runAgentRequestChain("session/request_permission",n),o=rc(r.shortCircuit?n:r.envelope);if(r.shortCircuit)return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:r.payload,sourceWasTransformer:!0}),r.payload;let i=await this.handlePermissionRequest(r.envelope,{fromAgent:!0});return this.notifyChain("permission.replied",{toolCallId:o??null,outcome:i,sourceWasTransformer:!1}),i}),e.connection.onRequest("elicitation/create",async n=>this.handleElicitationRequest(n)),typeof e.connection.onOrphanError=="function"&&e.connection.onOrphanError(n=>{this.handleOrphanError(n)}),e.onExit(()=>{this.agent===e&&this.markClosed({deleteRecord:!1})})}handleOrphanError(e){let t=Date.now()-this.lastCancelAt;if(this.lastCancelAt===0||t>s.CANCEL_ERROR_WINDOW_MS){this.logger?.warn(`agent ${this.agentId} sent uncorrelated error frame code=${e.code} message=${e.message}`);return}this.lastCancelAt=0,this.logger?.warn(`agent ${this.agentId} rejected session/cancel code=${e.code} message=${e.message}`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,code:e.code,message:e.message})}async runResponseChain(e,t=new Set,n=0,r="session/update"){let o=e,i=r==="session/update"?this.injectCumulativeCost(e):e,a=`response:${r}`;for(let l=n;l<this.transformChain.length;l++){let y=this.transformChain[l];if(t.has(y.name)||!y.intercepts.has(a))continue;let h=`t_${Do()}`,f;try{f=await y.connection.request("hydra-acp/transformer/message",{token:h,phase:"response",method:r,direction:"agent\u2192client",sessionId:this.sessionId,envelope:i})}catch(g){this.logger?.warn(`transformer ${y.name} error on ${a}: ${g.message}`);continue}let k=f?.action??"continue";if(k==="stop")return;if(k==="processing"){let g=l,p=i,w=new Set(t),m=r;await new Promise(v=>{let S=setTimeout(()=>{this.pendingClaims.delete(h)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:h,transformerName:y.name}),this.runResponseChain(p,new Set([...w,y.name]),g+1,m).then(()=>v()).catch(()=>v()))},Hs);typeof S.unref=="function"&&S.unref(),this.pendingClaims.set(h,{resolve:()=>v(),timer:S,transformerName:y.name,method:m,envelope:p,chainIdx:g,originatedBy:w,side:"response"})});return}f?.payload&&typeof f.payload=="object"&&(i=f.payload),t.add(y.name)}if(r!=="session/update")return;this.noteAgentActivity(i);let d=i.update;(Dd(d)||this.agentId==="opencode"&&this.opencodeSummary.feed(d))&&this.armRecallFromSelfCompaction();let c=qm(i);if(c!==null){this.setAgentAdvertisedCommands(c);return}let u=Bm(i);if(u!==null){this.setAgentAdvertisedModes(u);return}if(this.noteModelVerbHint(dd(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",xd(i))}armRecallFromSelfCompaction(){this.armRecallInPlace().catch(e=>{this.logger?.warn(`armRecallInPlace failed: ${e.message}`)})}async armRecallInPlace(){if(!this.historyStore)return;let e=await this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0);if(!(e<=(this._summarizedThroughEntry??0))){if(this._summarizedThroughEntry=e,this.persistWatermarkHook)try{this.persistWatermarkHook(e)}catch(t){this.logger?.warn(`armRecallInPlace: persistWatermarkHook failed: ${t.message}`)}this.broadcastQueueNotification("hydra-acp/context_self_compacted",{sessionId:this.sessionId})}}onAgentChange(e){this.agentChangeHandlers.push(e)}get attachedCount(){return this.clients.size}connectedClients(e){let t=[];for(let n of this.clients.values()){if(e&&n.clientId===e)continue;let r={clientId:n.clientId};n.clientInfo?.name&&(r.name=n.clientInfo.name),n.clientInfo?.version&&(r.version=n.clientInfo.version),t.push(r)}return t}get turnStartedAt(){return this.promptStartedAt}get inUnsolicitedTurn(){return this.unsolicitedTurn!==void 0}get agentPid(){return this.agent.pid}get awaitingInput(){return this.attentionFlags.size>0}async isQuiescedForSwap(){return await this.quiesceBlocker()===void 0}async quiesceBlocker(){if(this.agentTurnInFlight)return"the agent is still working; wait for the current turn to finish, then try again";if(this.unsolicitedTurn!==void 0)return"the agent is part-way through a turn it started by itself; wait for it to finish or interrupt it (^C), then try again";if(this.internalPromptCapture!==void 0)return"hydra is driving the agent right now (compaction seed or transcript injection); this clears by itself, so try again in a moment";if(this.modelChangeInFlight)return"a model change is still settling; try again in a moment";if(this.modeChangeInFlight)return"a mode change is still settling; try again in a moment";let e=this.pendingOneShotBackgroundTasks();if(e.length>0)return`${e.length} background task(s) still running (${e.join(", ")}); a swap would kill the agent process and abandon them. Wait for them to finish, or cancel them, then try again`;let t=await this.openToolCallIdsInHistory();if(t.length>0)return`${t.length} tool call(s) from an earlier turn never reported a result, so the session still reads as busy. ^C closes an abandoned chain; failing that it clears as new history accumulates`}isQuiescedSync(){return!(this.promptInFlight||this.unsolicitedTurn!==void 0||this.modeChangeInFlight||this.modelChangeInFlight)}async swapIntoWorkspace(e){await this.swapUpstream({...e.synopsis!==void 0?{artifact:e.synopsis}:{},note:e.note,framing:"swap",...e.title!==void 0?{title:e.title}:{},tailK:8,tailFloor:4,summarizedThroughEntry:e.historyLength,newCwd:e.cwd,reason:e.workspace!==void 0?"workspace-enter":"workspace-leave"}),this.workspace=e.workspace,e.left!==void 0?(this.formerWorkspace={path:e.left.path,sourceCwd:e.cwd,removed:e.left.removed},this.departureNoteSent=!1):this.formerWorkspace=void 0}async swapUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for swap: ${t}`);if(this.swapInFlight)throw new Error("a swap is already in progress for this session");this.swapInFlight=!0;try{await this.doSwapUpstream(e)}finally{this.swapInFlight=!1}}async doSwapUpstream(e){this.notifyChain("agent.swap",{phase:"pre",previousUpstreamSessionId:this.upstreamSessionId,agentId:this.agentId});let t=this.agentId,n=e.newAgentId??this.agentId,r=n!==this.agentId,o=e.reason!==void 0&&e.reason!=="compaction"?e.reason:r?"agent-swap":"compaction",i=e.newCwd??this.cwd,a=this.agentArgs,d=this.forwardedEnv,c=this.currentModel,u=this.currentMode,l=this.spawnReplacementAgent;if(!l)throw new Error("agent spawning not configured for this session");let y=this.mintMcpServersForSwap?await this.mintMcpServersForSwap(this):this.mcpServersConfig??[],h=await l({agentId:n,cwd:i,agentArgs:a,...d?{forwardedEnv:d}:{},...this.elicitationForms===!1?{elicitationForms:!1}:{},mcpServers:y});if(this.accumulateAndResetCost(),this.cwd=i,this.wireAgent(h.agent,{respawn:!0}),!r){let P=await pt({agent:h.agent,upstreamSessionId:h.upstreamSessionId,persistedModel:c,agentReportedModel:h.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(P.result,"model"),await ft({agent:h.agent,upstreamSessionId:h.upstreamSessionId,persistedMode:u,agentReportedMode:h.initialMode,logger:this.logger})}h.agent.connection.drainBuffered("session/update");let f=[];if(this.historyStore)try{f=await this.historyStore.load(this.sessionId)}catch(P){this.logger?.warn(`swapUpstream: historyStore.load failed: ${P.message}`)}let k=Fo({...e.artifact!==void 0?{synopsis:e.artifact}:{},...e.note!==void 0?{note:e.note}:{},...e.framing!==void 0?{framing:e.framing}:{},title:e.title,tail: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};let g,p;try{await h.agent.connection.request("session/prompt",{sessionId:h.upstreamSessionId,prompt:[{type:"text",text:k}]});let P=this.internalPromptCapture;g=P.lastUsed,p=P.lastSize,this.logger?.info(`swapUpstream: seed processed sessionId=${this.sessionId} seedChars=${k.length} toolCalls=${P.toolCalls} thinkingChars=${P.thinkingChars} messageChars=${P.messageChars} used=${P.lastUsed??"?"} size=${P.lastSize??"?"} reply=${JSON.stringify(P.chunks.join("").slice(0,200))}`)}finally{this.internalPromptCapture=void 0}g!==void 0&&(this.maybeApplyAgentUsage({update:{sessionUpdate:"usage_update",used:g,...p!==void 0?{size:p}:{}}}),this.broadcastCurrentUsage());let w=this.upstreamSessionId,m=this._summarizedThroughEntry;e.summarizedThroughEntry!==void 0&&(this._summarizedThroughEntry=e.summarizedThroughEntry);let v=this.agent;if(this.agent=h.agent,this.upstreamSessionId=h.upstreamSessionId,this.agentMeta=h.agentMeta,this.agentCapabilities=h.agentCapabilities,this.resetModelVerb(h.modelVerb),this.sawTurnComplete=!1,r&&(this.agentId=n,this.agentAdvertisedCommands=[],this.currentModel=h.initialModel,this.currentMode=h.initialMode,this.setAgentAdvertisedModels(h.initialModels??[]),this.setAgentAdvertisedModes(h.initialModes??[]),this.agentAdvertisedConfigOptions=h.initialConfigOptions??[]),this.broadcastMergedCommands(),this.broadcastConfigOptions(),this.notifyAgentChange("swapUpstream",o,e.runId,g),e.summarizedThroughEntry!==void 0&&this.persistWatermarkHook)try{this.persistWatermarkHook(e.summarizedThroughEntry)}catch(P){this.logger?.warn(`swapUpstream: persistWatermarkHook failed: ${P.message}`)}if(!r&&this.onCompactionSwapHook)try{this.onCompactionSwapHook({previousUpstreamSessionId:w,...m!==void 0?{previousSummarizedThroughEntry:m}:{},...e.runId!==void 0?{runId:e.runId}:{}})}catch(P){this.logger?.warn(`swapUpstream: onCompactionSwapHook failed: ${P.message}`)}let S=await this.retireAgent(v,r?"agent switch":e.reason==="workspace-enter"||e.reason==="workspace-leave"?"workspace move":"compaction swap");this.notifyChain("agent.swap",{phase:"post",previousUpstreamSessionId:w,upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}),r||this.broadcastCompactionPhase({phase:"swapped",...this.title!==void 0?{title:this.title}:{},summarizedThroughEntry:e.summarizedThroughEntry??this._summarizedThroughEntry??0}),r&&this.broadcastAgentSwitch(t,n);let b=S.length>0?`
55
61
  Stopped ${S.length} background task(s) with the previous agent: ${S.join(", ")}. Re-arm anything still needed.
56
62
  `:"",T=(e.reason==="workspace-enter"||e.reason==="workspace-leave"?"":r?`
57
63
  Switched to ${n}.
58
64
  `:`
59
65
  Compaction completed.
60
- `)+b,R=T===""?void 0:T;if(R!==void 0){let P=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:R},_meta:{"hydra-acp":{synthetic:!0}}}});for(let $ of this.clients.values())$.connection.notify("session/update",P).catch(()=>{})}this.updatedAt=Date.now()}async rollbackToUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for rollback: ${t}`);let n=this.loadExistingAgentSession;if(!n)throw new Error("loadExistingAgentSession not configured for this session");let r=this.agentId,o=this.cwd,i=this.agentArgs,a=this.forwardedEnv,d=this.currentModel,c=this.currentMode,u=await n(e.previousUpstreamSessionId,{agentId:r,cwd:o,agentArgs:i,...a?{forwardedEnv:a}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(u.agent,{respawn:!0});let l=await ft({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedModel:d,agentReportedModel:u.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(l.result,"model"),await lt({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedMode:c,agentReportedMode:u.initialMode,logger:this.logger}),u.agent.connection.drainBuffered("session/update");let w=this.agent;this.agent=u.agent,this.upstreamSessionId=u.upstreamSessionId,this.agentMeta=u.agentMeta,this.agentCapabilities=u.agentCapabilities,this.resetModelVerb(u.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(w,"rollback"),this._summarizedThroughEntry=e.previousSummarizedThroughEntry,this.broadcastCompactionPhase({phase:"rolled_back",summarizedThroughEntry:e.previousSummarizedThroughEntry??0}),this.notifyAgentChange("rollbackToUpstream","rollback"),this.updatedAt=Date.now()}async reloadUpstreamAfterAgentLoss(){let e=this.loadExistingAgentSession;if(!e)throw new Error("loadExistingAgentSession not configured for this session");let t=this.currentModel,n=this.currentMode,r=await e(this.upstreamSessionId,{agentId:this.agentId,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(r.agent,{respawn:!0});let o=await ft({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:t,agentReportedModel:r.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(o.result,"model"),await lt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:n,agentReportedMode:r.initialMode,logger:this.logger}),r.agent.connection.drainBuffered("session/update");let i=this.agent;this.agent=r.agent,this.upstreamSessionId=r.upstreamSessionId,this.agentMeta=r.agentMeta,this.agentCapabilities=r.agentCapabilities,this.resetModelVerb(r.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(i,"upstream-lost"),this.notifyAgentChange("reloadUpstreamAfterAgentLoss"),this.updatedAt=Date.now()}async openToolCallIdsInHistory(e=Bg){if(!this.historyStore)return[];let t=await this.historyStore.load(this.sessionId),n=t.length>e?t.slice(-e):t,r=new Set,o=new Set;for(let i of n){let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate,u=typeof d.toolCallId=="string"?d.toolCallId:void 0;if(!u)continue;let l=d.status;c==="tool_call"&&r.add(u),(c==="tool_call"||c==="tool_call_update")&&(l==="completed"||l==="failed")&&o.add(u)}return[...r].filter(i=>!o.has(i))}async getHistorySnapshot(e="inline",t){return this.historyStore?this.historyStore.load(this.sessionId,{tools:e,...t!==void 0?{maxEntries:t}:{}}).catch(()=>[]):[]}async*iterRecallNewestFirst(){this.historyStore&&(yield*this.historyStore.iterRecallNewestFirst(this.sessionId))}async getRecallTotalCount(){return this.historyStore?this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0):0}async sliceRecallHistory(e,t){return this.historyStore?(await this.historyStore.rangeSlice(this.sessionId,e,t).catch(()=>[])).map(r=>r.entry):[]}onBroadcast(e){return this.broadcastHandlers.push(e),()=>{let t=this.broadcastHandlers.indexOf(e);t>=0&&this.broadcastHandlers.splice(t,1)}}broadcastClientUpdate(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:e});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}broadcastCompactionPhase(e){let t=e.phase;t==="swapped"||t==="failed"||t==="rolled_back"?this._liveCompactionPhase=void 0:this._liveCompactionPhase=e;let n=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_compaction",...e}});for(let r of this.broadcastHandlers)try{r({method:"session/update",params:n,recordedAt:Date.now()})}catch{}for(let r of this.clients.values())r.connection.notify("session/update",n).catch(()=>{});this.notifyChain("compaction",{...e})}broadcastWorkspacePhase(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_workspace",...e}});for(let n of this.broadcastHandlers)try{n({method:"session/update",params:t,recordedAt:Date.now()})}catch{}for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{});this.notifyChain("workspace",{...e})}broadcastSyntheticText(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:e},_meta:{"hydra-acp":{synthetic:!0}}}});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}attach(e,t,n={}){if(this.closed)throw fe(new Error("session is closed"),x.SessionNotFound);if(this.clients.has(e.clientId))throw fe(new Error(`client ${e.clientId} is already attached`),x.AlreadyAttached);return this.clients.set(e.clientId,e),this.cancelOrphanTimer(),this.updatedAt=Date.now(),t==="none"?Promise.resolve({entries:[],appliedPolicy:t}):t==="pending_only"?Promise.resolve({entries:this.buildStateSnapshotReplay(),appliedPolicy:t}):this.loadReplay(t,n)}async loadReplay(e,t){let n=t.toolContent??"inline",r=n==="inline"&&!t.raw&&this.historyStore!==void 0,o=async u=>{if(t.raw)return u;let l=ws(u);return r&&this.historyStore?this.historyStore.hydrate(this.sessionId,l):l},i=t.historyLimit===0?1/0:t.historyLimit??this.historyMaxEntries,a=Bt(await this.getHistorySnapshot(r?"references":n,i===1/0?1/0:i*2),this.side),d=km(a.filter(u=>!En(u.method,u.params)),i),c=this.buildStateSnapshotReplay();if(e==="after_message"){let u=t.afterSeq!==void 0?vm(d,t.afterSeq):t.afterMessageId?bm(d,t.afterMessageId):-1;return u<0?{entries:[...c,...await o(d)],appliedPolicy:"full"}:{entries:[...c,...await o(d.slice(u+1))],appliedPolicy:"after_message"}}return{entries:[...c,...await o(d)],appliedPolicy:"full"}}buildStateSnapshotReplay(){let e=[],t=this.sessionId,n=Date.now();if(this.title!==void 0&&this.title.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"session_info_update",title:this.title}},recordedAt:n}),this.currentModel!==void 0&&this.currentModel.length>0||this.agentAdvertisedModels.length>0){let o={sessionUpdate:"_hydra_current_model_update"};this.currentModel!==void 0&&this.currentModel.length>0&&(o.currentModel=this.currentModel),this.agentAdvertisedModels.length>0&&(o.availableModels=[...this.agentAdvertisedModels]),e.push({method:"session/update",params:{sessionId:t,update:o},recordedAt:n})}this.currentMode!==void 0&&this.currentMode.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"current_mode_update",currentModeId:this.currentMode}},recordedAt:n});let r=this.mergedAvailableCommands();if(r.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_commands_update",availableCommands:r}},recordedAt:n}),this.agentAdvertisedModes.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:[...this.agentAdvertisedModes]}},recordedAt:n}),this.currentUsage!==void 0){let o=this.currentUsage,i={sessionUpdate:"usage_update"};if(typeof o.used=="number"&&(i.used=o.used),typeof o.size=="number"&&(i.size=o.size),typeof o.costAmount=="number"||typeof o.costCurrency=="string"){let a={};typeof o.costAmount=="number"&&(a.amount=o.costAmount),typeof o.costCurrency=="string"&&(a.currency=o.costCurrency),i.cost=a}Object.keys(i).length>1&&e.push({method:"session/update",params:{sessionId:t,update:i},recordedAt:n})}return this._liveCompactionPhase!==void 0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_compaction",...this._liveCompactionPhase}},recordedAt:n}),e}replayPendingPermissions(e){for(let t of this.attentionFlags.values()){if(t.source!=="daemon"||!t.reason.startsWith("permission:"))continue;let n=t.reason.slice(11),r=this.permissionCallbacks.get(n);r&&r(e)}}detach(e){let t=this.clients.get(e);t&&(this.clients.delete(e),this.updatedAt=Date.now(),this.scheduleOrphanCheck(),this.broadcastClientDisconnected(t))}broadcastClientDisconnected(e){let t={clientId:e.clientId};e.clientInfo?.name&&(t.name=e.clientInfo.name),e.clientInfo?.version&&(t.version=e.clientInfo.version);let n={sessionUpdate:"client_disconnected",client:t,timestamp:new Date().toISOString()};for(let r of this.clients.values())r.connection.notify("session/update",{sessionId:this.sessionId,update:n}).catch(()=>{})}reportIsolationBreach(e,t){let n=this.workspace;if(n===void 0){let r=this.formerWorkspace;r!==void 0&&Ts(e,r.path)&&(this.logger?.warn?.(`STALE WORKSPACE WRITE on session ${this.sessionId}: the agent wrote ${e}, which is inside the workspace this session already left. That work will not reach ${r.sourceCwd}.`),this.notifyChain("workspace.staleWrite",{path:e,formerWorkspacePath:r.path,sourceCwd:r.sourceCwd,toolCallId:t}));return}Pd(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=jd(e,o=>So(o,t.path)?(n=!0,bo(o,t.path,t.sourceCwd).text):o);if(!this.departureNoteSent||n){let o=Td({sourceCwd:t.sourceCwd,formerWorkspacePath:t.path,removed:t.removed});r=Co(r,`${o}
66
+ `)+b,R=T===""?void 0:T;if(R!==void 0){let P=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:R},_meta:{"hydra-acp":{synthetic:!0}}}});for(let $ of this.clients.values())$.connection.notify("session/update",P).catch(()=>{})}this.updatedAt=Date.now()}async rollbackToUpstream(e){let t=await this.quiesceBlocker();if(t!==void 0)throw new Error(`session is not quiesced for rollback: ${t}`);let n=this.loadExistingAgentSession;if(!n)throw new Error("loadExistingAgentSession not configured for this session");let r=this.agentId,o=this.cwd,i=this.agentArgs,a=this.forwardedEnv,d=this.currentModel,c=this.currentMode,u=await n(e.previousUpstreamSessionId,{agentId:r,cwd:o,agentArgs:i,...a?{forwardedEnv:a}:{},...this.elicitationForms===!1?{elicitationForms:!1}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(u.agent,{respawn:!0});let l=await pt({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedModel:d,agentReportedModel:u.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(l.result,"model"),await ft({agent:u.agent,upstreamSessionId:u.upstreamSessionId,persistedMode:c,agentReportedMode:u.initialMode,logger:this.logger}),u.agent.connection.drainBuffered("session/update");let y=this.agent;this.agent=u.agent,this.upstreamSessionId=u.upstreamSessionId,this.agentMeta=u.agentMeta,this.agentCapabilities=u.agentCapabilities,this.resetModelVerb(u.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(y,"rollback"),this._summarizedThroughEntry=e.previousSummarizedThroughEntry,this.broadcastCompactionPhase({phase:"rolled_back",summarizedThroughEntry:e.previousSummarizedThroughEntry??0}),this.notifyAgentChange("rollbackToUpstream","rollback"),this.updatedAt=Date.now()}async reloadUpstreamAfterAgentLoss(){let e=this.loadExistingAgentSession;if(!e)throw new Error("loadExistingAgentSession not configured for this session");let t=this.currentModel,n=this.currentMode,r=await e(this.upstreamSessionId,{agentId:this.agentId,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{},...this.elicitationForms===!1?{elicitationForms:!1}:{},mcpServers:this.mcpServersConfig??[]});this.accumulateAndResetCost(),this.wireAgent(r.agent,{respawn:!0});let o=await pt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:t,agentReportedModel:r.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(o.result,"model"),await ft({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:n,agentReportedMode:r.initialMode,logger:this.logger}),r.agent.connection.drainBuffered("session/update");let i=this.agent;this.agent=r.agent,this.upstreamSessionId=r.upstreamSessionId,this.agentMeta=r.agentMeta,this.agentCapabilities=r.agentCapabilities,this.resetModelVerb(r.modelVerb),this.broadcastMergedCommands(),this.broadcastConfigOptions(),await this.retireAgent(i,"upstream-lost"),this.notifyAgentChange("reloadUpstreamAfterAgentLoss"),this.updatedAt=Date.now()}async openToolCallIdsInHistory(e=mm){if(!this.historyStore)return[];let t=await this.historyStore.load(this.sessionId),n=t.length>e?t.slice(-e):t,r=new Set,o=new Set;for(let i of n){let d=i.params?.update;if(!d||typeof d.sessionUpdate!="string")continue;let c=d.sessionUpdate,u=typeof d.toolCallId=="string"?d.toolCallId:void 0;if(!u)continue;let l=d.status;c==="tool_call"&&r.add(u),(c==="tool_call"||c==="tool_call_update")&&(l==="completed"||l==="failed")&&o.add(u)}return[...r].filter(i=>!o.has(i))}async getHistorySnapshot(e="inline",t){return this.historyStore?this.historyStore.load(this.sessionId,{tools:e,...t!==void 0?{maxEntries:t}:{}}).catch(()=>[]):[]}async*iterRecallNewestFirst(){this.historyStore&&(yield*this.historyStore.iterRecallNewestFirst(this.sessionId))}async getRecallTotalCount(){return this.historyStore?this.historyStore.getRecallTotalCount(this.sessionId).catch(()=>0):0}async sliceRecallHistory(e,t){return this.historyStore?(await this.historyStore.rangeSlice(this.sessionId,e,t).catch(()=>[])).map(r=>r.entry):[]}onBroadcast(e){return this.broadcastHandlers.push(e),()=>{let t=this.broadcastHandlers.indexOf(e);t>=0&&this.broadcastHandlers.splice(t,1)}}broadcastClientUpdate(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:e});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}broadcastCompactionPhase(e){let t=e.phase;t==="swapped"||t==="failed"||t==="rolled_back"?this._liveCompactionPhase=void 0:this._liveCompactionPhase=e;let n=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_compaction",...e}});for(let r of this.broadcastHandlers)try{r({method:"session/update",params:n,recordedAt:Date.now()})}catch{}for(let r of this.clients.values())r.connection.notify("session/update",n).catch(()=>{});this.notifyChain("compaction",{...e})}broadcastWorkspacePhase(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_workspace",...e}});for(let n of this.broadcastHandlers)try{n({method:"session/update",params:t,recordedAt:Date.now()})}catch{}for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{});this.notifyChain("workspace",{...e})}broadcastSyntheticText(e){let t=this.rewriteForClient({sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:e},_meta:{"hydra-acp":{synthetic:!0}}}});for(let n of this.clients.values())n.connection.notify("session/update",t).catch(()=>{})}attach(e,t,n={}){if(this.closed)throw fe(new Error("session is closed"),x.SessionNotFound);if(this.clients.has(e.clientId))throw fe(new Error(`client ${e.clientId} is already attached`),x.AlreadyAttached);return this.clients.set(e.clientId,e),this.cancelOrphanTimer(),this.updatedAt=Date.now(),t==="none"?Promise.resolve({entries:[],appliedPolicy:t}):t==="pending_only"?Promise.resolve({entries:this.buildStateSnapshotReplay(),appliedPolicy:t}):this.loadReplay(t,n)}async loadReplay(e,t){let n=t.toolContent??"inline",r=n==="inline"&&!t.raw&&this.historyStore!==void 0,o=async u=>{if(t.raw)return u;let l=As(u);return r&&this.historyStore?this.historyStore.hydrate(this.sessionId,l):l},i=t.historyLimit===0?1/0:t.historyLimit??this.historyMaxEntries,a=qt(await this.getHistorySnapshot(r?"references":n,i===1/0?1/0:i*2),this.side),d=Jm(a.filter(u=>!On(u.method,u.params)),i),c=this.buildStateSnapshotReplay();if(e==="after_message"){let u=t.afterSeq!==void 0?Vm(d,t.afterSeq):t.afterMessageId?Gm(d,t.afterMessageId):-1;return u<0?{entries:[...c,...await o(d)],appliedPolicy:"full"}:{entries:[...c,...await o(d.slice(u+1))],appliedPolicy:"after_message"}}return{entries:[...c,...await o(d)],appliedPolicy:"full"}}buildStateSnapshotReplay(){let e=[],t=this.sessionId,n=Date.now();if(this.title!==void 0&&this.title.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"session_info_update",title:this.title}},recordedAt:n}),this.currentModel!==void 0&&this.currentModel.length>0||this.agentAdvertisedModels.length>0){let o={sessionUpdate:"_hydra_current_model_update"};this.currentModel!==void 0&&this.currentModel.length>0&&(o.currentModel=this.currentModel),this.agentAdvertisedModels.length>0&&(o.availableModels=[...this.agentAdvertisedModels]),e.push({method:"session/update",params:{sessionId:t,update:o},recordedAt:n})}this.currentMode!==void 0&&this.currentMode.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"current_mode_update",currentModeId:this.currentMode}},recordedAt:n});let r=this.mergedAvailableCommands();if(r.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"available_commands_update",availableCommands:r}},recordedAt:n}),this.agentAdvertisedModes.length>0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_available_modes_update",availableModes:[...this.agentAdvertisedModes]}},recordedAt:n}),this.currentUsage!==void 0){let o=this.currentUsage,i={sessionUpdate:"usage_update"};if(typeof o.used=="number"&&(i.used=o.used),typeof o.size=="number"&&(i.size=o.size),typeof o.costAmount=="number"||typeof o.costCurrency=="string"){let a={};typeof o.costAmount=="number"&&(a.amount=o.costAmount),typeof o.costCurrency=="string"&&(a.currency=o.costCurrency),i.cost=a}Object.keys(i).length>1&&e.push({method:"session/update",params:{sessionId:t,update:i},recordedAt:n})}return this._liveCompactionPhase!==void 0&&e.push({method:"session/update",params:{sessionId:t,update:{sessionUpdate:"_hydra_compaction",...this._liveCompactionPhase}},recordedAt:n}),e}replayPendingPermissions(e){for(let t of this.attentionFlags.values())if(t.source==="daemon"){if(t.reason.startsWith("permission:"))this.permissionCallbacks.get(t.reason.slice(11))?.(e);else if(t.reason.startsWith("elicitation:")){let n=t.reason.slice(12);if(tn(e))this.elicitationCallbacks.get(n)?.(e);else{let r=this.elicitationQuestions.get(n);r!==void 0&&this.sendElicitationQuestionText(e,r())}}}}detach(e){let t=this.clients.get(e);t&&(this.clients.delete(e),this.updatedAt=Date.now(),this.scheduleOrphanCheck(),this.broadcastClientDisconnected(t))}broadcastClientDisconnected(e){let t={clientId:e.clientId};e.clientInfo?.name&&(t.name=e.clientInfo.name),e.clientInfo?.version&&(t.version=e.clientInfo.version);let n={sessionUpdate:"client_disconnected",client:t,timestamp:new Date().toISOString()};for(let r of this.clients.values())r.connection.notify("session/update",{sessionId:this.sessionId,update:n}).catch(()=>{})}reportIsolationBreach(e,t){let n=this.workspace;if(n===void 0){let r=this.formerWorkspace;r!==void 0&&Ls(e,r.path)&&(this.logger?.warn?.(`STALE WORKSPACE WRITE on session ${this.sessionId}: the agent wrote ${e}, which is inside the workspace this session already left. That work will not reach ${r.sourceCwd}.`),this.notifyChain("workspace.staleWrite",{path:e,formerWorkspacePath:r.path,sourceCwd:r.sourceCwd,toolCallId:t}));return}Kd(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=oc(e,o=>No(o,t.path)?(n=!0,Oo(o,t.path,t.sourceCwd).text):o);if(!this.departureNoteSent||n){let o=Vd({sourceCwd:t.sourceCwd,formerWorkspacePath:t.path,removed:t.removed});r=Ho(r,`${o}
61
67
 
62
- `),this.departureNoteSent=!0}return r}applyWorkspacePromptRewrite(e){let t=this.workspace;if(t===void 0)return this.applyDepartedPromptRewrite(e);let n=!1,r=jd(e,i=>So(i,t.sourceCwd)?(n=!0,bo(i,t.sourceCwd,t.path).text):i);if(!this.workspacePreambleSent||n){let i=Ed({workspacePath:t.path,sourceCwd:t.sourceCwd,notes:this.workspaceNotes,...this.workspacePreambleSent?{reassert:!0}:{}});r=Co(r,`${i}
68
+ `),this.departureNoteSent=!0}return r}applyWorkspacePromptRewrite(e){let t=this.workspace;if(t===void 0)return this.applyDepartedPromptRewrite(e);let n=!1,r=oc(e,i=>No(i,t.sourceCwd)?(n=!0,Oo(i,t.sourceCwd,t.path).text):i);if(!this.workspacePreambleSent||n){let i=Gd({workspacePath:t.path,sourceCwd:t.sourceCwd,notes:this.workspaceNotes,...this.workspacePreambleSent?{reassert:!0}:{}});r=Ho(r,`${i}
63
69
 
64
- `),this.workspacePreambleSent=!0}return r}async prompt(e,t,n,r){let o=this.clients.get(e);if(!o)throw fe(new Error("client not attached"),x.SessionNotFound);if(this.closing)throw fe(new Error("session is closing; new prompts cannot be accepted"),x.SessionClosing);let i=Ve();if(this.maybeSeedTitleFromPrompt(t),this._firstPromptSeeded=!0,!(at((t??{})._meta).ancillary===!0)&&this._interactive!==!0){this._interactive=!0,this.cancelOrphanTimer();for(let d of this.interactiveHandlers)try{d(!0)}catch{}}return this.enqueueUserPrompt(o,t,i,n,r)}broadcastPromptReceived(e){this.closeUnsolicitedTurn("superseded",`prompt:${e.messageId}`);let t={clientId:e.originator.clientId};e.originator.name&&(t.name=e.originator.name),e.originator.version&&(t.version=e.originator.version),e.originator.fromSession&&(t.fromSession=e.originator.fromSession),e.originator.fromSessionTitle&&(t.fromSessionTitle=e.originator.fromSessionTitle),e.originator.fromLabel&&(t.fromLabel=e.originator.fromLabel),e.originator.depth!==void 0&&(t.depth=e.originator.depth),this.promptStartedAt=Date.now(),this.turnRanTool=!1,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"prompt_received",messageId:e.messageId,prompt:e.prompt,sentBy:t}},e.clientId);let n=At(e.prompt);n.length>0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{compatFor:"prompt_received"}}}},e.clientId)}recordCurrentUsageSnapshot(){if(this.historyStore===void 0)return;let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let r={};typeof e.costAmount=="number"&&(r.amount=e.costAmount),typeof e.costCurrency=="string"&&(r.currency=e.costCurrency),t.cost=r}if(Object.keys(t).length<=1)return;t._meta={"hydra-acp":{upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}};let n={sessionId:this.sessionId,update:t};this.historyStore.append(this.sessionId,{method:"session/update",params:n,recordedAt:Date.now()}).catch(()=>{})}originatorNeedsTurnComplete(e){return e.wasAmend===!0||e.wasSteer===!0}broadcastTurnComplete(e,t,n,r,o){let i=t&&typeof t=="object"&&"stopReason"in t&&typeof t.stopReason=="string"?t.stopReason:void 0,a={sessionUpdate:"turn_complete",messageId:Ve()};i!==void 0&&(a.stopReason=i),o!==void 0&&(a.errorMessage=o);let d=at(t?._meta).salvaged;d!==void 0&&(a._meta={[le]:{salvaged:d}}),this.supersededAutonomousTurn=void 0;let c=this.amendInProgress;if(c&&n!==void 0&&c.cancelledMessageId===n&&(a._meta={[le]:{...d!==void 0?{salvaged:d}:{},amended:{cancelledMessageId:c.cancelledMessageId,newMessageId:c.newMessageId}}}),this.promptStartedAt=void 0,this.noteTurnEnded(),this.sawTurnComplete=!0,this.scheduleWorkspaceSnapshotHook?.(),n!==void 0&&i!==void 0){this.recordTerminal(n,i);let u=this.pendingTurnNotifiers.get(n);u&&(this.pendingTurnNotifiers.delete(n),po(u,{sessionId:this.sessionId,messageId:u.originalMessageId,stopReason:i,deliveredAt:Date.now(),...n!==u.originalMessageId?{amendedTo:n}:{}}))}i==="cancelled"||i==="error"||i==="refusal"?this.closeOpenToolCalls(i):this.armOpenToolCalls(),this.recordCurrentUsageSnapshot(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:a},r?void 0:e),c&&n!==void 0&&c.cancelledMessageId===n&&this.broadcastPromptAmended(c)}noteAgentActivity(e){if(!(this.closing||this.closed)){if(Kg(e)||this.steerCausedTurnTerminal(e)){if(this.unsolicitedTurn!==void 0){this.closeUnsolicitedTurn("completed");return}this.salvageSupersededTerminal();return}this.pendingSteerDetach!==void 0&&this.currentEntry?.messageId===this.pendingSteerDetach.messageId&&Od(e)&&(this.pendingSteerDetach=void 0),!En("session/update",e)&&(this.noteBackgroundTaskArming(e),this.unsolicitedTurn===void 0&&(this.promptInFlight||!this.sawTurnComplete||Qg(e)||this.openUnsolicitedTurn()))}}steerCausedTurnTerminal(e){return this.unsolicitedTurn?.steerCaused!==!0?!1:Od(e)}noteBackgroundTaskArming(e){let t=e?.update;if(!t||typeof t!="object")return;let n=typeof t.toolCallId=="string"?t.toolCallId:void 0;if(n===void 0)return;let r=t.rawInput,o=lm(t._meta);if(this.rememberToolLabel(n,t,r,o),this.noteBackgroundTaskStopped(t,r,o),this.backgroundTaskTracking===!1)return;let i=this.backgroundTaskTracking===!0,a=i?um(t.rawOutput):void 0,d=typeof o?.toolResponse?.taskId=="string"?o.toolResponse.taskId:a??cm(t.rawOutput),c=a!==void 0||i&&r?.background===!0;if(!(d!==void 0||c||r!==void 0&&r.run_in_background===!0))return;let l=this.toolLabels.get(n)?.label??"background task";this.lastBackgroundTask={toolCallId:n,label:l};let w=Date.now(),h=this.armedTasks.get(n),f=d??h?.taskId,k=dm(t.title,o,r)||h?.repeating===!0;this.armedTasks.set(n,{label:l,...f!==void 0?{taskId:f}:{},repeating:k,armedAt:h?.armedAt??w,...c||h?.endUnobservable===!0?{endUnobservable:!0}:{}}),this.onArmedTasksChanged()}applyBackgroundTaskLevel(e){if(this.backgroundTaskTracking===!1)return;let t=e?.message;if(!t||t.subtype!=="background_tasks_changed")return;let n=t.tasks;if(!Array.isArray(n))return;let r=Date.now(),o=new Map;for(let a of n){let d=a,c=typeof d?.task_id=="string"?d.task_id:void 0;c!==void 0&&o.set(c,{taskType:typeof d?.task_type=="string"?d.task_type:"unknown",description:typeof d?.description=="string"?d.description:"",firstSeen:this.liveBackgroundTasks.get(c)?.firstSeen??r})}let i=[...this.liveBackgroundTasks.keys()].filter(a=>!o.has(a));this.liveBackgroundTasks=o,this.sawBackgroundTaskLevel=!0,this.logger?.info(`session ${this.sessionId} background level: ${o.size} live`+(i.length>0?` (ended: ${i.join(", ")})`:"")),this.onArmedTasksChanged()}get armedBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.entries()].map(([e,t])=>({taskId:e,label:t.description||t.taskType,taskType:t.taskType,since:t.firstSeen})):[...this.armedTasks.entries()].map(([e,t])=>({toolCallId:e,label:t.label,...t.taskId!==void 0?{taskId:t.taskId}:{},since:t.armedAt,...t.endUnobservable===!0?{endUnobservable:!0}:{}}))}pendingOneShotBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.values()].filter(e=>em.has(e.taskType)).map(e=>e.description||e.taskType):[...this.armedTasks.values()].filter(e=>!e.repeating&&e.endUnobservable!==!0).map(e=>e.label)}get armedSince(){let e;if(this.sawBackgroundTaskLevel){for(let t of this.liveBackgroundTasks.values())(e===void 0||t.firstSeen<e)&&(e=t.firstSeen);return e}for(let t of this.armedTasks.values())(e===void 0||t.armedAt<e)&&(e=t.armedAt);return e}onArmedTasksChanged(){let e=this.armedBackgroundTasks,t=e.length,n=this.armedSince,r=e.map(o=>o.taskId??o.toolCallId??o.label).sort().join("\0");r===this.lastArmedBroadcast?.key&&n===this.lastArmedBroadcast?.since||this.closed||(this.lastArmedBroadcast={key:r,since:n},this.broadcastQueueNotification("hydra-acp/session/armed_tasks_updated",{sessionId:this.sessionId,count:t,...n!==void 0?{since:n}:{},tasks:e}),this.dispatchIdle())}async retireAgent(e,t){return await e.kill().catch(()=>{}),this.resetBackgroundTaskLevel(),this.discardArmedTasks(t)}resetBackgroundTaskLevel(){this.liveBackgroundTasks.clear(),this.sawBackgroundTaskLevel=!1}discardArmedTasks(e){if(this.armedTasks.size===0)return[];let t=[...this.armedTasks.values()].map(n=>n.label);for(let[n,r]of this.armedTasks)r.openToolCall===!0&&this.openToolCalls.delete(n);return this.armedTasks.clear(),this.upstreamBaselineMs=void 0,this.logger?.info(`session ${this.sessionId} discarded ${t.length} armed task(s) on ${e}: ${t.join(", ")}`),this.onArmedTasksChanged(),t}noteBackgroundTaskStopped(e,t,n){if(!(n?.toolName==="TaskStop"||e.title==="TaskStop"))return;let o=t?.task_id;if(typeof o!="string"||o.length===0)return;let i=!1;for(let[a,d]of this.armedTasks)d.taskId===o&&(this.armedTasks.delete(a),i=!0);i&&this.onArmedTasksChanged()}rememberToolLabel(e,t,n,r){let o=n!==void 0&&typeof n.description=="string"&&n.description?n.description:void 0;if(o!==void 0)this.toolLabels.set(e,{label:o.slice(0,Ao),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,Ao),fromDescription:!1})}for(;this.toolLabels.size>Zg;){let i=this.toolLabels.keys().next().value;if(i===void 0)break;this.toolLabels.delete(i)}}openUnsolicitedTurn(){let e=Date.now();if(this.lastUnsolicitedCancelAt!==0&&e-this.lastUnsolicitedCancelAt<=s.UNSOLICITED_REOPEN_WINDOW_MS?this.cancelReopenStreak+=1:this.cancelReopenStreak=0,this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak>=s.UNSOLICITED_REOPEN_LIMIT){this.escalateUnresponsiveCancel();return}let t=this.lastBackgroundTask,n=!1;for(let[i,a]of this.armedTasks)a.repeating||a.openToolCall===!0||(this.armedTasks.delete(i),n=!0);n&&this.onArmedTasksChanged();let r={messageId:Ve(),startedAt:e,cause:t,steerCaused:this.pendingSteerDetach!==void 0};this.pendingSteerDetach=void 0,this.unsolicitedTurn=r,this.promptStartedAt=e,this.logger?.info(`session ${this.sessionId} agent resumed with no prompt in flight`+(t?` (after ${t.label})`:""));let o={unsolicited:!0};t&&(o.cause=t),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_started",messageId:r.messageId,_meta:{"hydra-acp":o}}})}async holdForUnsolicitedTurn(e){if(this.unsolicitedTurn===void 0){this.logger?.info(`session ${this.sessionId} queue hold skipped for ${e.messageId} (no unsolicited turn open)`);return}let t=Date.now(),n=this.unsolicitedTurn.cause;this.logger?.info(`session ${this.sessionId} holding ${e.messageId} behind unsolicited turn ${this.unsolicitedTurn.messageId}`+(n?` cause=${JSON.stringify(n.label)}`:"")),this.broadcastQueueNotification("hydra-acp/prompt_queue/held",{sessionId:this.sessionId,messageId:e.messageId,reason:"agent_resumed",...n?{cause:n}:{}});let r="turn_ended";for(;;){if(this.closing||this.closed){r="closing";break}if(e.cancelled){r="cancelled";break}if(this.unsolicitedTurn===void 0){r="turn_ended";break}await new Promise(i=>{let a=setTimeout(i,tm);typeof a.unref=="function"&&a.unref()})}let o=Date.now()-t;this.logger?.info(`session ${this.sessionId} released ${e.messageId} reason=${r} heldMs=${o}`),this.broadcastQueueNotification("hydra-acp/prompt_queue/released",{sessionId:this.sessionId,messageId:e.messageId,reason:r,heldMs:o})}closeUnsolicitedTurn(e,t){let n=this.unsolicitedTurn;if(n===void 0)return;let r=Date.now()-n.startedAt;this.unsolicitedTurn=void 0,this.promptStartedAt=void 0,this.noteTurnEnded(),e==="cancelled"?this.lastUnsolicitedCancelAt=Date.now():(this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak=0),this.logger?.info(`session ${this.sessionId} unsolicited turn ${n.messageId} closed reason=${e} durationMs=${r}`+(t?` by=${t}`:"")+(n.cause?` cause=${JSON.stringify(n.cause.label)}`:"")),e==="superseded"&&(this.supersededAutonomousTurn={turnMessageId:n.messageId,cause:n.cause,supersededAt:Date.now()}),this.recordCurrentUsageSnapshot(),!this.closed&&(e==="cancelled"?this.closeOpenToolCalls("cancelled"):e==="completed"&&this.armOpenToolCalls(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_ended",messageId:Ve(),startedMessageId:n.messageId,durationMs:r,_meta:{"hydra-acp":{unsolicited:!0,reason:e}}}}))}salvageSupersededTerminal(){let e=this.supersededAutonomousTurn;if(e===void 0)return;this.supersededAutonomousTurn=void 0;let t=this.autonomousSalvage;t!==void 0&&(this.autonomousSalvage=void 0,this.logger?.warn(`session ${this.sessionId} salvaged session/prompt from autonomous terminal (superseded turn ${e.turnMessageId}, ${Date.now()-e.supersededAt}ms earlier)`+(e.cause?` cause=${JSON.stringify(e.cause.label)}`:"")),t({stopReason:"end_turn",_meta:{[le]:{salvaged:{reason:"autonomous_terminal",supersededMessageId:e.turnMessageId}}}}))}async awaitPromptResponse(e){if(this.supersededAutonomousTurn===void 0)return e;try{return await new Promise((t,n)=>{this.autonomousSalvage=t,e.then(t,n)})}finally{this.autonomousSalvage=void 0}}recordTerminal(e,t){for(this.recentlyTerminal.set(e,{stopReason:t,terminatedAt:Date.now()});this.recentlyTerminal.size>Vg;){let n=this.recentlyTerminal.keys().next().value;if(n===void 0)break;this.recentlyTerminal.delete(n)}}registerTurnNotify(e,t,n){let r=this.recentlyTerminal.get(e);if(r)return{alreadyTerminal:!0,stopReason:r.stopReason};for(this.pendingTurnNotifiers.set(e,{callbackUrl:t,secret:n,registeredAt:Date.now(),originalMessageId:e});this.pendingTurnNotifiers.size>zg;){let o=this.pendingTurnNotifiers.keys().next().value;if(o===void 0)break;this.pendingTurnNotifiers.delete(o)}return{alreadyTerminal:!1}}broadcastPromptAmended(e){let t=this.findUserEntry(e.newMessageId);if(!t)return;let n={sessionId:this.sessionId,cancelledMessageId:e.cancelledMessageId,newMessageId:e.newMessageId,prompt:t.prompt,originator:t.originator,amendedAt:Date.now()};this.broadcastQueueNotification("hydra-acp/prompt/amended",n)}findUserEntry(e){if(this.currentEntry?.messageId===e&&this.currentEntry.kind==="user")return this.currentEntry;let t=this.promptQueue.find(n=>n.messageId===e&&n.kind==="user");return t?.kind==="user"?t:void 0}visibleQueueDepth(){let e=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;for(let t of this.promptQueue)t.kind==="user"&&!t.cancelled&&(e+=1);return e}broadcastQueueAdded(e,t){let n=this.visibleQueueDepth(),r=t?.position??Math.max(0,n-1),o={sessionId:this.sessionId,messageId:e.messageId,originator:e.originator,prompt:e.prompt,position:r,queueDepth:n,enqueuedAt:e.enqueuedAt};t?.amending!==void 0&&(o._meta={"hydra-acp":{amending:t.amending}}),this.broadcastQueueNotification("hydra-acp/prompt_queue/added",o)}broadcastQueueUpdated(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/updated",{sessionId:this.sessionId,messageId:e,prompt:t})}broadcastQueueRemoved(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/removed",{sessionId:this.sessionId,messageId:e,reason:t})}broadcastQueueNotification(e,t){for(let n of this.clients.values())n.connection.notify(e,t).catch(()=>{})}queueSnapshot(){let e=[],t=0;this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled&&e.push({messageId:this.currentEntry.messageId,originator:this.currentEntry.originator,prompt:this.currentEntry.prompt,position:t++,enqueuedAt:this.currentEntry.enqueuedAt});for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push({messageId:n.messageId,originator:n.originator,prompt:n.prompt,position:t++,enqueuedAt:n.enqueuedAt});return e}async flushPersistWrites(){await this.queueWriteChain.catch(()=>{})}replayPersistedQueue(e){for(let t of e){let n={clientId:`hydra-resurrected_${t.messageId}`};t.originator.clientInfo.name!==void 0&&(n.name=t.originator.clientInfo.name),t.originator.clientInfo.version!==void 0&&(n.version=t.originator.clientInfo.version);let r={kind:"user",messageId:t.messageId,originator:n,clientId:n.clientId,prompt:t.prompt,enqueuedAt:t.enqueuedAt,cancelled:!1,resolve:()=>{},reject:()=>{}};this.promptQueue.push(r),this.broadcastQueueAdded(r)}this.drainQueue()}cancelQueuedPrompt(e){if(this.currentEntry?.messageId===e)return{cancelled:!1,reason:"already_running"};let t=this.promptQueue.findIndex(r=>r.messageId===e);if(t<0)return{cancelled:!1,reason:"not_found"};let n=this.promptQueue[t];return n.cancelled=!0,this.promptQueue.splice(t,1),n.kind==="user"&&(this.broadcastQueueRemoved(e,"cancelled"),this.persistRewrite()),this.amendInProgress?.newMessageId===e&&(this.amendInProgress=void 0),n.resolve({stopReason:"cancelled"}),{cancelled:!0,reason:"ok"}}updateQueuedPrompt(e,t){if(this.currentEntry?.messageId===e)return{updated:!1,reason:"already_running"};let n=this.promptQueue.find(r=>r.messageId===e);return!n||n.kind!=="user"?{updated:!1,reason:"not_found"}:(n.prompt=t,this.broadcastQueueUpdated(e,t),this.persistRewrite(),{updated:!0,reason:"ok"})}amendPrompt(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let{targetMessageId:r,prompt:o,replaceQueue:i,onTargetCompleted:a}=t;if(this.currentEntry?.messageId===r&&this.currentEntry.kind==="user"&&!this.currentEntry.cancelled&&this.amendInProgress===void 0)return this.amendOnHead(n,o,r,i);let d=this.promptQueue.find(u=>u.messageId===r&&u.kind==="user");if(d&&d.kind==="user"&&!d.cancelled)return d.prompt=o,this.broadcastQueueUpdated(r,o),this.persistRewrite(),{amended:!0,reason:"ok",messageId:r};let c=this.recentlyTerminal.get(r);return c?c.stopReason==="cancelled"?{amended:!1,reason:"target_cancelled"}:a==="send_anyway"?{amended:!1,reason:"target_completed",messageId:this.enqueueAmendmentAsFollowUp(n,o)}:{amended:!1,reason:"target_completed"}:{amended:!1,reason:"target_not_found"}}amendOnHead(e,t,n,r){let o=Ve(),i={clientId:e.clientId};if(e.clientInfo?.name&&(i.name=e.clientInfo.name),e.clientInfo?.version&&(i.version=e.clientInfo.version),r){let c=[];for(let u of this.promptQueue){if(u.kind==="user"&&!u.cancelled){u.cancelled=!0,this.broadcastQueueRemoved(u.messageId,"cancelled"),u.resolve({stopReason:"cancelled"});continue}c.push(u)}this.promptQueue=c}let a={kind:"user",messageId:o,originator:i,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,wasAmend:!0,resolve:()=>{},reject:()=>{}};this.promptQueue.unshift(a),this.persistRewrite(),this.broadcastQueueAdded(a,{amending:n,position:1}),this.amendInProgress={cancelledMessageId:n,newMessageId:o};let d=this.pendingTurnNotifiers.get(n);return d&&(this.pendingTurnNotifiers.delete(n),this.pendingTurnNotifiers.set(o,d)),this.cancelExtensionDispatch(n,"amended"),this.agent.connection.notify("session/cancel",{sessionId:this.upstreamSessionId}).catch(()=>{}),{amended:!0,reason:"ok",messageId:o}}async steer(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let r=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled;if(r&&this.agent.steeringSupported){this.pendingSteerDetach={messageId:this.currentEntry.messageId};let o;try{o=await this.forwardRequest("_session/steering",t)}catch(d){throw this.pendingSteerDetach=void 0,d}let i=o?.outcome,a=i==="injected"||i==="startedNewTurn"||i==="promptRequired"||i==="failed"?o:{outcome:"failed"};return a.outcome!=="startedNewTurn"&&(this.pendingSteerDetach=void 0),a.outcome==="injected"&&this.recordSteerAsUserMessageChunk(t.prompt,e),a.outcome==="startedNewTurn"?{...a,detached:!0}:a}return r?(this.amendOnHead(n,t.prompt,this.currentEntry.messageId,!1),{outcome:"startedNewTurn"}):t._meta?.steering?.idleBehavior==="promptRequired"?{outcome:"promptRequired",reason:"noRunningTurn"}:(this.prompt(e,{sessionId:t.sessionId,prompt:t.prompt},void 0,{steerOriginated:!0}).catch(o=>{this.logger?.warn(`steer-originated prompt failed to enqueue: ${o.message}`)}),{outcome:"startedNewTurn"})}recordSteerAsUserMessageChunk(e,t){let n=At(e);n.length!==0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{steered:!0}}}},t)}enqueueAmendmentAsFollowUp(e,t){let n=Ve(),r={clientId:e.clientId};e.clientInfo?.name&&(r.name=e.clientInfo.name),e.clientInfo?.version&&(r.version=e.clientInfo.version);let o={kind:"user",messageId:n,originator:r,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,resolve:()=>{},reject:()=>{}};return this.promptQueue.push(o),this.persistRewrite(),this.broadcastQueueAdded(o),this.drainQueue(),n}async cancel(e){if(!this.clients.get(e))throw fe(new Error("client not attached"),x.SessionNotFound);this.logger?.info(`session ${this.sessionId} session/cancel from ${e} promptInFlight=${this.promptInFlight} agentTurnInFlight=${this.agentTurnInFlight} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length}`),this.lastCancelAt=Date.now(),this.currentEntry?.kind==="user"&&this.currentEntry.messageId!==void 0&&this.cancelExtensionDispatch(this.currentEntry.messageId,"cancelled"),this.closeUnsolicitedTurn("cancelled"),this.agentTurnInFlight||this.closeOpenToolCalls("cancelled"),await this.forwardRequest("session/cancel",{sessionId:this.sessionId},new Set,0,"notification")}addTransformer(e){let t=this.transformChain.findIndex(n=>n.name===e.name);t>=0?this.transformChain[t]=e:this.transformChain.push(e),e.intercepts.has("lifecycle:session.opened")&&e.connection.notify("hydra-acp/transformer/session_event",{event:"session.opened",sessionId:this.sessionId}).catch(()=>{})}async forwardRequest(e,t,n=new Set,r=0,o="request"){let i=this.rewriteForAgent(t);for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name))continue;let c=`request:${e}`;if(!d.intercepts.has(c))continue;let u=`t_${Io()}`,l;try{l=await d.connection.request("hydra-acp/transformer/message",{token:u,phase:"request",method:e,direction:"client\u2192agent",sessionId:this.sessionId,envelope:i})}catch(h){this.logger?.warn(`transformer ${d.name} error on ${c}: ${h.message}`);continue}let w=l?.action??"continue";if(w==="stop")return o==="notification"?void 0:l?.payload??Ro(e);if(w==="continue"){l?.payload&&typeof l.payload=="object"&&(i=l.payload),n.add(d.name);continue}if(w==="processing"){let h=a,f=i,k=new Set(n);return new Promise(p=>{let g=setTimeout(()=>{this.pendingClaims.delete(u)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:u,transformerName:d.name}),this.forwardRequest(e,f,new Set([...k,d.name]),h+1,o).then(p).catch(()=>p(o==="notification"?void 0:Ro(e))))},Es);typeof g.unref=="function"&&g.unref(),this.pendingClaims.set(u,{resolve:p,timer:g,transformerName:d.name,method:e,envelope:f,chainIdx:h,originatedBy:k,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 ut({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??qe,this.modelVerbConfirmed=!1}async runAgentRequestChain(e,t,n=new Set,r=0){let o=t,i=`request:${e}`;for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name)||!d.intercepts.has(i))continue;let c=`t_${Io()}`,u;try{u=await d.connection.request("hydra-acp/transformer/message",{token:c,phase:"request",method:e,direction:"agent\u2192client",sessionId:this.sessionId,envelope:o})}catch(w){this.logger?.warn(`transformer ${d.name} error on ${i}: ${w.message}`);continue}let l=u?.action??"continue";if(l==="stop")return{shortCircuit:!0,payload:u?.payload??Rm(e)};if(l==="continue"){u?.payload&&typeof u.payload=="object"&&(o=u.payload),n.add(d.name);continue}if(l==="processing"){let w=a,h=o,f=new Set(n),k=e;return new Promise(p=>{let g=setTimeout(()=>{this.pendingClaims.delete(c)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:c,transformerName:d.name}),this.runAgentRequestChain(k,h,new Set([...f,d.name]),w+1).then(p).catch(()=>p({shortCircuit:!1,envelope:h})))},Es);typeof g.unref=="function"&&g.unref(),this.pendingClaims.set(c,{resolve:y=>p({shortCircuit:!0,payload:y}),timer:g,transformerName:d.name,method:k,envelope:h,chainIdx:w,originatedBy:f,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):Es,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:Ro(n.method)))}},r);return typeof o.unref=="function"&&o.unref(),n.timer=o,!0}async emitToChain(e,t,n){let r=this.transformChain.findIndex(a=>a.name===e),o=r>=0?r+1:0,i=new Set([e]);if(t==="session/update"){await this.runResponseChain(n,i,o);return}return this.forwardRequest(t,n,i,o)}async emitToQueue(e,t){let n=this.transformChain.findIndex(c=>c.name===e),r=n>=0?n+1:0,o=(t??{}).prompt??[],i=Ve(),a=`transformer:${e}`,d={clientId:a,name:e};return new Promise((c,u)=>{let l={kind:"user",messageId:i,originator:d,clientId:a,prompt:o,enqueuedAt:Date.now(),cancelled:!1,emitterName:e,chainStartIdx:r,resolve:c,reject:u},w=this.insertEntryAt(l,"tail");this.persistRewrite(),this.broadcastQueueAdded(l,{position:w}),this.drainQueue()})}rewriteForAgent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.sessionId===this.sessionId)return{...t,sessionId:this.upstreamSessionId}}return e}async close(e={}){if(e.deleteRecord&&(this.deleteRecordIntent=!0),!this.closed)return this.closeInFlight?this.closeInFlight:(this.closing=!0,this.closeInFlight=this.doClose(e),this.closeInFlight)}async doClose(e){let t=this.turnStartedAt!==void 0;this.logger?.info(`session ${this.sessionId} closing deleteRecord=${e.deleteRecord??!1} by=${e.by??"unknown"} midTurn=${t} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length} awaitingPermission=${this.hasPermissionFlag}`),t&&this.logger?.warn(`session ${this.sessionId} closed mid-turn by=${e.by??"unknown"}; the in-flight turn will not settle and the agent is being killed`),this.cancelIdleTimer(),this.cancelOrphanTimer(),clearTimeout(this.upstreamPollTimer);for(let n of this.pendingClaims.values())clearTimeout(n.timer);this.pendingClaims.clear(),await this.requestAgentSessionClose(),await this.agent.kill().catch(()=>{}),this.markClosed({deleteRecord:e.deleteRecord??!1})}async requestAgentSessionClose(){if(this.agentCapabilities?.sessionCapabilities?.close===void 0)return;let e,t=new Promise(r=>{e=setTimeout(r,Lg)}),n=this.agent.connection.request("session/close",{sessionId:this.upstreamSessionId}).then(()=>{},()=>{});await Promise.race([n,t]),clearTimeout(e)}onClose(e){return this.closeHandlers.push(e),()=>{let t=this.closeHandlers.indexOf(e);t>=0&&this.closeHandlers.splice(t,1)}}onTitleChange(e){this.titleHandlers.push(e)}retitle(e){return this.runTitleCommand(e)}retitleFromAgent(){return this.runTitleCommand("")}setTitle(e){let t=e.trim();if(!(!t||t===this.title)){this._titleSeedPending=!1,this.title=t,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",title:t,updatedAt:new Date().toISOString()}});for(let n of this.titleHandlers)try{n(t)}catch{}}}maybeSeedTitleFromPrompt(e){if(!this._titleSeedPending||at((e??{})._meta).ancillary===!0||this.promptCarriesSentBy(e))return;let r=At((e??{}).prompt),o=To(r,200);!o||o.startsWith("/")||(this._titleSeedPending=!1,this.setTitle(o))}maybeApplyAgentModel(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="_hydra_current_model_update")return!1;let r=Pn(n.availableModels);r.length>0&&this.setAgentAdvertisedModels(r);let o=typeof n.currentModel=="string"?n.currentModel:typeof n.model=="string"?n.model:void 0;if(o===void 0)return!0;let i=o.trim();if(!i||i===this.currentModel)return!0;this.logger?.info(`live current_model_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(i)}`),this.currentModel=i;for(let a of this.modelHandlers)try{a(i)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentConfigOption(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="config_option_update")return!1;let r=n.configOptions;if(!Array.isArray(r))return!0;for(let i of r)this.applyOneConfigOptionEntry(i);let o=new Set(r.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i&&i!=="model"&&i!=="mode"&&i!=="agent"));return this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id)),this.fireConfigOptionsHandlers(),!0}applyAgentConfigOptionResponse(e,t){let n=e?.configOptions;if(!Array.isArray(n))return!1;let r=JSON.stringify(this.agentAdvertisedConfigOptions);for(let o of n){let i=o?.id;i==="model"||i==="mode"||i==="agent"||this.applyOneConfigOptionEntry(o)}if(Yg(n,t)){let o=new Set(n.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i));this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id))}return JSON.stringify(this.agentAdvertisedConfigOptions)!==r}applyOneConfigOptionEntry(e){if(!e||typeof e!="object")return;let t=e;if(t.id==="model"){let k=Pn(t.options);k.length>0&&this.setAgentAdvertisedModels(k);let p=t.currentValue;if(typeof p=="string"){let g=p.trim();g&&g!==this.currentModel&&(this.logger?.info(`live config_option_update(model): sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(g)}`),this.applyModelChange(g))}return}if(t.id==="mode"){let k=Ps(t.options);k.length>0&&this.setAgentAdvertisedModes(k);let p=t.currentValue;if(typeof p=="string"){let g=p.trim();g&&g!==this.currentMode&&(this.logger?.info(`live config_option_update(mode): sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(g)}`),this.applyModeChange(g))}return}if(typeof t.id!="string"||!t.id.trim())return;let n=t.id.trim(),r=xo(t.options);if(r.length===0)return;let o=t.name,i=typeof o=="string"&&o.trim()?o.trim():n,a=t.category,d=typeof a=="string"&&a.trim()?a.trim():"other",c=t.description,u=typeof c=="string"&&c.trim()?c.trim():void 0,l=t.currentValue,w=typeof l=="string"&&l.trim()?l.trim():r[0].value,h={id:n,name:i,category:d,type:"select",currentValue:w,options:r,...u?{description:u}:{}},f=this.agentAdvertisedConfigOptions.findIndex(k=>k.id===n);f>=0?this.agentAdvertisedConfigOptions[f]=h:this.agentAdvertisedConfigOptions.push(h)}maybeApplyAgentMode(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="current_mode_update")return!1;let r=typeof n.currentModeId=="string"?n.currentModeId:typeof n.currentMode=="string"?n.currentMode:typeof n.mode=="string"?n.mode:void 0;if(r===void 0)return!0;let o=r.trim();if(!o||o===this.currentMode)return!0;this.logger?.info(`current_mode_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(o)}`),this.currentMode=o;for(let i of this.modeHandlers)try{i(o)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentUsage(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="usage_update")return!1;let r={...this._currentUsage??{}},o=!1;if(typeof n.used=="number"&&!this.swapInFlight&&kd(r.used,n.used)&&this.armRecallFromSelfCompaction(),typeof n.used=="number"&&r.used!==n.used&&(r.used=n.used,o=!0),typeof n.size=="number"&&r.size!==n.size&&(r.size=n.size,o=!0),n.cost&&typeof n.cost=="object"){let a=n.cost;typeof a.amount=="number"&&(this.reconcileCostLedger(a.amount)&&(o=!0),r.costAmount!==a.amount&&(r.costAmount=a.amount,o=!0)),typeof a.currency=="string"&&r.costCurrency!==a.currency&&(r.costCurrency=a.currency,o=!0)}if(!o)return!0;this._currentUsage=r;let i=this.persistableUsage??r;for(let a of this.usageHandlers)try{a(i)}catch{}return!0}armCostLedgerProbe(){let e=this._currentUsage?.costAmount;typeof e=="number"&&e>0&&(this.costLedgerProbe=e)}reconcileCostLedger(e){let t=this.costLedgerProbe;return t===void 0||(this.costLedgerProbe=void 0,e>=t-1e-6)?!1:(this.cumulativeCost+=t,!0)}notifyAgentChange(e,t,n,r){let o=this.retiringGenerationCost;this.retiringGenerationCost=void 0;let i=this.retiringGenerationUsed;this.retiringGenerationUsed=void 0;let a=this.rotationLifetimeCost;this.rotationLifetimeCost=void 0;for(let d of this.agentChangeHandlers)try{d({agentId:this.agentId,upstreamSessionId:this.upstreamSessionId,...o!==void 0?{retiredCost:o}:{},...a!==void 0?{lifetimeCost:a}:{},...i!==void 0?{retiredUsed:i}:{},...r!==void 0?{startedUsed:r}:{},...t!==void 0?{reason:t}:{},...n!==void 0?{runId:n}:{}})}catch(c){this.logger?.warn(`${e}: agentChange handler failed: ${c.message}`)}}accumulateAndResetCost(){let e=this._currentUsage?.costAmount;e&&(this.cumulativeCost+=e,this.retiringGenerationCost=e);let t=this._currentUsage?.used;typeof t=="number"&&t>0&&(this.retiringGenerationUsed=t),this.rotationLifetimeCost=this.cumulativeCost;let n={used:0,cumulativeCost:this.cumulativeCost,...typeof this._currentUsage?.size=="number"?{size:this._currentUsage.size}:{},...this._currentUsage?.costCurrency?{costCurrency:this._currentUsage.costCurrency}:{}};this._currentUsage=n;for(let r of this.usageHandlers)try{r(n)}catch{}this.broadcastCurrentUsage()}broadcastCurrentUsage(){let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let n={};typeof e.costAmount=="number"&&(n.amount=e.costAmount),typeof e.costCurrency=="string"&&(n.currency=e.costCurrency),t.cost=n}this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:t})}injectCumulativeCost(e){if(!this.cumulativeCost||!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update;if(n.sessionUpdate!=="usage_update"||!n.cost||typeof n.cost!="object")return e;let r=n.cost;return typeof r.amount!="number"?e:{...t,update:{...n,cost:{...r,amount:this.cumulativeCost+r.amount}}}}get totalUsage(){return this.currentUsage}setAgentAdvertisedCommands(e){if(fm(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(pm(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(",")}]`),gm(this.agentAdvertisedModels,e)){this.broadcastAvailableModels();return}this.agentAdvertisedModels=e;for(let t of this.agentModelsHandlers)try{t(e)}catch{}this.broadcastAvailableModels()}onAgentCommandsChange(e){this.agentCommandsHandlers.push(e)}onAgentModesChange(e){this.agentModesHandlers.push(e)}onAgentModelsChange(e){this.agentModelsHandlers.push(e)}onConfigOptionsChange(e){this.configOptionsHandlers.push(e)}extraConfigOptionValues(){return Object.fromEntries(this.agentAdvertisedConfigOptions.map(e=>[e.id,e.currentValue]))}onModelChange(e){this.modelHandlers.push(e)}onModeChange(e){this.modeHandlers.push(e)}onInteractiveChange(e){this.interactiveHandlers.push(e)}onPriorityChange(e){this.priorityHandlers.push(e)}onReadStateChange(e){this.readStateHandlers.push(e)}get unread(){return Cn(this._lastTurnEndedAt,this._readAt)}setRead(e,t=Date.now()){let n=As({lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt},e,t);n!==void 0&&(this._readAt=n,this.fireReadState())}noteTurnEnded(e=Date.now()){this._readAt===void 0&&(this._readAt=Math.min(this._lastTurnEndedAt??this.createdAt,e-1)),this._lastTurnEndedAt=e,this.fireReadState(),this.captureUpstreamBaseline()}hasEndUnobservableTask(){for(let e of this.armedTasks.values())if(e.endUnobservable===!0)return!0;return!1}captureUpstreamBaseline(){let e=++this.upstreamBaselineGen;if(!this.hasEndUnobservableTask()){this.upstreamBaselineMs=void 0;return}this.fetchUpstreamUpdatedAt().then(t=>{t===void 0||e!==this.upstreamBaselineGen||this.promptInFlight||this.unsolicitedTurn!==void 0||(this.upstreamBaselineMs=t,this.scheduleUpstreamPoll(e))}).catch(()=>{})}scheduleUpstreamPoll(e){clearTimeout(this.upstreamPollTimer),this.upstreamPollTimer=setTimeout(()=>{this.upstreamPollTimer=void 0,this.pollUpstream(e)},nm),this.upstreamPollTimer.unref()}async pollUpstream(e){if(!this.upstreamPollLive(e))return;let t=await this.fetchUpstreamUpdatedAt().catch(()=>{});this.upstreamPollLive(e)&&(t!==void 0&&this.applyUpstreamUpdatedAt(t),this.upstreamPollLive(e)&&this.scheduleUpstreamPoll(e))}upstreamPollLive(e){return e===this.upstreamBaselineGen&&this.upstreamBaselineMs!==void 0&&!this.closing&&!this.closed&&this.hasEndUnobservableTask()}async fetchUpstreamUpdatedAt(){let t=(await this.agent.connection.request("session/list",{cwd:this.cwd}))?.sessions?.find(r=>r.sessionId===this.upstreamSessionId),n=typeof t?.updatedAt=="string"?Date.parse(t.updatedAt):NaN;return Number.isNaN(n)?void 0:n}noteUpstreamUpdatedAt(e){let t=e===void 0?NaN:Date.parse(e);Number.isNaN(t)||this.applyUpstreamUpdatedAt(t)}applyUpstreamUpdatedAt(e){if(this.upstreamBaselineMs===void 0||e<=this.upstreamBaselineMs||this.promptInFlight||this.unsolicitedTurn!==void 0)return;let t=0;for(let[n,r]of this.armedTasks)r.endUnobservable===!0&&(this.armedTasks.delete(n),t+=1);this.upstreamBaselineMs=void 0,t>0&&(this.logger?.info(`session ${this.sessionId} cleared ${t} armed task(s): agent updated the session after its turn ended`),this.onArmedTasksChanged())}fireReadState(){let e={lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt};for(let t of this.readStateHandlers)try{t(e)}catch{}}setPriority(e){let t=e===void 0||e<=0?void 0:Math.floor(e);if(t!==this._priority){this._priority=t,this.updatedAt=Date.now();for(let n of this.priorityHandlers)try{n(t)}catch{}}}applyModelChange(e){let t=e.trim();if(t){this.modelChangeInFlight=!0;try{if(t!==this.currentModel){this.logger?.info(`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(t)}`),this.currentModel=t;for(let r of this.modelHandlers)try{r(t)}catch{}}let n={sessionUpdate:"_hydra_current_model_update",currentModel:t};this.agentAdvertisedModels.length>0&&(n.availableModels=[...this.agentAdvertisedModels]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modelChangeInFlight=!1}}}applyModeChange(e){let t=e.trim();if(t){this.modeChangeInFlight=!0;try{if(t!==this.currentMode){this.logger?.info(`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(t)}`),this.currentMode=t;for(let r of this.modeHandlers)try{r(t)}catch{}}let n={sessionUpdate:"current_mode_update",currentModeId:t};this.agentAdvertisedModes.length>0&&(n.availableModes=[...this.agentAdvertisedModes]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modeChangeInFlight=!1}}}buildConfigOptions(){let e=[];if(this.agentAdvertisedModels.length>0){let r=this.agentAdvertisedModels.map(i=>({value:i.modelId,name:i.name??i.modelId,...i.description!==void 0?{description:i.description}:{}}));this.currentModel&&!r.some(i=>i.value===this.currentModel)&&r.unshift({value:this.currentModel,name:this.currentModel});let o=this.currentModel||r[0].value;e.push({id:"model",name:"Model",category:"model",type:"select",currentValue:o,options:r})}if(this.agentAdvertisedModes.length>0){let r=this.agentAdvertisedModes.map(i=>({value:i.id,name:i.name??i.id,...i.description!==void 0?{description:i.description}:{}}));this.currentMode&&!r.some(i=>i.value===this.currentMode)&&r.unshift({value:this.currentMode,name:this.currentMode});let o=this.currentMode||r[0].value;e.push({id:"mode",name:"Session Mode",category:"mode",type:"select",currentValue:o,options:r})}let n=(this.availableAgentsFn?.()??[]).map(r=>({value:r.id,name:r.name??r.id,...r.description!==void 0?{description:r.description}:{}}));return n.some(r=>r.value===this.agentId)||n.unshift({value:this.agentId,name:this.agentId}),e.push({id:"agent",name:"Agent",category:"_hydra_agent",type:"select",currentValue:this.agentId,options:n}),e.push(...this.agentAdvertisedConfigOptions),e}broadcastConfigOptions(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"config_option_update",configOptions:this.buildConfigOptions()}}),this.fireConfigOptionsHandlers()}fireConfigOptionsHandlers(){for(let e of this.configOptionsHandlers)try{e(this.agentAdvertisedConfigOptions)}catch{}}mergeAgentOptionIntoEnvelope(e){if(!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update,r=Array.isArray(n.configOptions)?[...n.configOptions]:[];if(r.some(a=>a&&typeof a=="object"&&a.id==="agent"))return e;let i=this.buildConfigOptions().find(a=>a.id==="agent");return i?{...t,update:{...n,configOptions:[...r,i]}}:e}onUsageChange(e){this.usageHandlers.push(e)}mergedAvailableCommands(){let e=this.daemonTopLevelCommands(),t=this.aliasableBareVerbs();for(let n of Vt){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=fo(n),c=d??n;if(d!==void 0){let u=r.verb?`hydra ${c} ${r.verb}`:`hydra ${c}`,w={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(w.description=r.description),e.push(w)}if(c.length>0&&t.get(c)===n){let u=r.verb?`${c} ${r.verb}`:c,w={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(w.description=r.description),e.push(w)}}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 Vt)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=fo(i)??i;if(!a||e.has(a)||n.has(a))continue;let d=r.get(a);d===void 0?r.set(a,i):d!==i&&r.set(a,"__conflict__")}for(let[i,a]of r)a!=="__conflict__"&&n.set(i,a);return n}agentOnlyAdvertisedCommands(){return[...this.agentAdvertisedCommands]}agentKnowsSlashCommand(e){let t=r=>r.startsWith("/")?r.slice(1):r,n=t(e);if(!n)return!1;for(let r of this.agentAdvertisedCommands)if(t(r.name.split(/\s+/)[0]??"")===n)return!0;return!1}availableModes(){return[...this.agentAdvertisedModes]}availableModels(){return[...this.agentAdvertisedModels]}maybeApplyAgentSessionInfo(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="session_info_update"||typeof n.title!="string"||this._upstreamRespawned)return;let r=n.title.trim();if(!(!r||r===this.title)){this.title=r,this._firstPromptSeeded=!0,this._titleSeedPending=!1;for(let o of this.titleHandlers)try{o(r)}catch{}}}async handleSlashCommand(e,t){let r=e.slice(6).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),o=r?.[1]??"",i=(r?.[2]??"").trim();if(o==="")return{stopReason:"end_turn"};let a=t!==void 0;if(Vt.some(l=>l.verb===o))switch(o){case"title":return a?this.runTitleCommandInline(i):this.runTitleCommand(i);case"agent":return this.runAgentCommandInline(i);case"config":return this.handleConfigCommand(`/config ${i}`);case"kill":return this.runKillCommand();case"workspace":return this.runWorkspaceCommand(i);case"restart":return a?this.runRestartCommandInline():this.runRestartCommand();case"clear":return this.runClearCommand();case"compact":return a?this.runCompactCommandInline(i):this.runCompactCommand(i);case"uncompact":return a?this.runUncompactCommandInline():this.runUncompactCommand();case"fork":return a?this.runForkCommandInline(i,t):this.runForkCommand(i);default:{let l=new Error(`no dispatcher for /hydra verb ${o}`);throw l.code=x.InternalError,l}}if(this.extensionCommands?.has(o))return a?this.runExtensionCommandInline(o,i,t):this.runExtensionCommand(o,i);let d=pd(o).find(l=>this.extensionCommands?.has(l));if(d!==void 0)return a?this.runExtensionCommandInline(d,i,t):this.runExtensionCommand(d,i);let c=Vt.map(l=>l.verb);if(this.extensionCommands){let l=new Set;for(let{name:w}of this.extensionCommands.list())l.has(w)||(c.push(w),l.add(w))}let u=new Error(`unknown /hydra verb: ${o} (known: ${c.join(", ")})`);throw u.code=x.InvalidParams,u}runExtensionCommand(e,t){return this.enqueuePrompt(`extension:${e}`,()=>this.runExtensionCommandInline(e,t,void 0))}async runExtensionCommandInline(e,t,n){let r=this.extensionCommands?.get(e);if(!r)return this.emitExtensionReply(`extension "${e}" is no longer connected`);let o=t.match(/^(\S+)(?:\s+([\s\S]*))?$/),i=o?.[1]??"",a=(o?.[2]??"").trim();if(!r.commands.some(f=>f.verb===i)){let f=r.commands.map(k=>k.verb).join(", ");return this.emitExtensionReply(`/hydra ${e}${i?` ${i}`:""}: unknown verb (known: ${f||"(none)"})`)}let d={sessionId:this.sessionId,verb:i,args:a};n!==void 0&&(d.messageId=n);let c=()=>{},u=new Promise(f=>{c=f});n!==void 0&&this.inFlightExtensionDispatches.set(n,{extensionName:e,connection:r.connection,cancel:f=>c({stopReason:"cancelled",reason:f})});let l,w=!1;try{let f=r.connection.request("hydra-acp/commands/invoke",d),k=await Promise.race([f,u]);if(k&&typeof k=="object"&&k.stopReason==="cancelled"&&"reason"in k)return w=!0,this.logger?.info(`extension ${e} ${i} cancelled (cancelExtensionDispatch); abandoning in-flight commands/invoke`),{stopReason:"cancelled"};l=k}catch(f){return this.emitExtensionReply(`${e} ${i}: ${f.message}`)}finally{n!==void 0&&!w&&this.inFlightExtensionDispatches.delete(n)}let h=l&&typeof l=="object"&&typeof l.text=="string"?l.text:"";return h.length>0?this.emitExtensionReply(h):{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:`
70
+ `),this.workspacePreambleSent=!0}return r}async prompt(e,t,n,r){let o=this.clients.get(e);if(!o)throw fe(new Error("client not attached"),x.SessionNotFound);if(this.closing)throw fe(new Error("session is closing; new prompts cannot be accepted"),x.SessionClosing);if(this.tryAnswerElicitationFromPrompt(o,t,n))return{stopReason:"end_turn"};let i=Oe();if(this.maybeSeedTitleFromPrompt(t),this._firstPromptSeeded=!0,!(dt((t??{})._meta).ancillary===!0)&&this._interactive!==!0){this._interactive=!0,this.cancelOrphanTimer();for(let d of this.interactiveHandlers)try{d(!0)}catch{}}return this.enqueueUserPrompt(o,t,i,n,r)}broadcastPromptReceived(e){this.closeUnsolicitedTurn("superseded",`prompt:${e.messageId}`);let t={clientId:e.originator.clientId};e.originator.name&&(t.name=e.originator.name),e.originator.version&&(t.version=e.originator.version),e.originator.fromSession&&(t.fromSession=e.originator.fromSession),e.originator.fromSessionTitle&&(t.fromSessionTitle=e.originator.fromSessionTitle),e.originator.fromLabel&&(t.fromLabel=e.originator.fromLabel),e.originator.depth!==void 0&&(t.depth=e.originator.depth),this.promptStartedAt=Date.now(),this.turnRanTool=!1,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"prompt_received",messageId:e.messageId,prompt:e.prompt,sentBy:t}},e.clientId);let n=ht(e.prompt);n.length>0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{compatFor:"prompt_received"}}}},e.clientId)}recordCurrentUsageSnapshot(){if(this.historyStore===void 0)return;let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let r={};typeof e.costAmount=="number"&&(r.amount=e.costAmount),typeof e.costCurrency=="string"&&(r.currency=e.costCurrency),t.cost=r}if(Object.keys(t).length<=1)return;t._meta={"hydra-acp":{upstreamSessionId:this.upstreamSessionId,agentId:this.agentId}};let n={sessionId:this.sessionId,update:t};this.historyStore.append(this.sessionId,{method:"session/update",params:n,recordedAt:Date.now()}).catch(()=>{})}originatorNeedsTurnComplete(e){return e.wasAmend===!0||e.wasSteer===!0}broadcastTurnComplete(e,t,n,r,o){let i=t&&typeof t=="object"&&"stopReason"in t&&typeof t.stopReason=="string"?t.stopReason:void 0,a={sessionUpdate:"turn_complete",messageId:Oe()};i!==void 0&&(a.stopReason=i),o!==void 0&&(a.errorMessage=o);let d=dt(t?._meta).salvaged;d!==void 0&&(a._meta={[le]:{salvaged:d}}),this.supersededAutonomousTurn=void 0;let c=this.amendInProgress;if(c&&n!==void 0&&c.cancelledMessageId===n&&(a._meta={[le]:{...d!==void 0?{salvaged:d}:{},amended:{cancelledMessageId:c.cancelledMessageId,newMessageId:c.newMessageId}}}),this.promptStartedAt=void 0,this.noteTurnEnded(),this.sawTurnComplete=!0,this.scheduleWorkspaceSnapshotHook?.(),n!==void 0&&i!==void 0){this.recordTerminal(n,i);let u=this.pendingTurnNotifiers.get(n);u&&(this.pendingTurnNotifiers.delete(n),Ao(u,{sessionId:this.sessionId,messageId:u.originalMessageId,stopReason:i,deliveredAt:Date.now(),...n!==u.originalMessageId?{amendedTo:n}:{}}))}i==="cancelled"||i==="error"||i==="refusal"?this.closeOpenToolCalls(i):this.armOpenToolCalls(),this.recordCurrentUsageSnapshot(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:a},r?void 0:e),c&&n!==void 0&&c.cancelledMessageId===n&&this.broadcastPromptAmended(c)}noteAgentActivity(e){if(!(this.closing||this.closed)){if(Sm(e)||this.steerCausedTurnTerminal(e)){if(this.unsolicitedTurn!==void 0){this.closeUnsolicitedTurn("completed");return}this.salvageSupersededTerminal();return}this.pendingSteerDetach!==void 0&&this.currentEntry?.messageId===this.pendingSteerDetach.messageId&&ec(e)&&(this.pendingSteerDetach=void 0),!On("session/update",e)&&(this.noteBackgroundTaskArming(e),this.unsolicitedTurn===void 0&&(this.promptInFlight||!this.sawTurnComplete||Im(e)||this.openUnsolicitedTurn()))}}steerCausedTurnTerminal(e){return this.unsolicitedTurn?.steerCaused!==!0?!1:ec(e)}noteBackgroundTaskArming(e){let t=e?.update;if(!t||typeof t!="object")return;let n=typeof t.toolCallId=="string"?t.toolCallId:void 0;if(n===void 0)return;let r=t.rawInput,o=Lm(t._meta);if(this.rememberToolLabel(n,t,r,o),this.noteBackgroundTaskStopped(t,r,o),this.backgroundTaskTracking===!1)return;let i=this.backgroundTaskTracking===!0,a=i?Dm(t.rawOutput):void 0,d=typeof o?.toolResponse?.taskId=="string"?o.toolResponse.taskId:a??Nm(t.rawOutput),c=a!==void 0||i&&r?.background===!0;if(!(d!==void 0||c||r!==void 0&&r.run_in_background===!0))return;let l=this.toolLabels.get(n)?.label??"background task";this.lastBackgroundTask={toolCallId:n,label:l};let y=Date.now(),h=this.armedTasks.get(n),f=d??h?.taskId,k=Om(t.title,o,r)||h?.repeating===!0;this.armedTasks.set(n,{label:l,...f!==void 0?{taskId:f}:{},repeating:k,armedAt:h?.armedAt??y,...c||h?.endUnobservable===!0?{endUnobservable:!0}:{}}),this.onArmedTasksChanged()}applyBackgroundTaskLevel(e){if(this.backgroundTaskTracking===!1)return;let t=e?.message;if(!t||t.subtype!=="background_tasks_changed")return;let n=t.tasks;if(!Array.isArray(n))return;let r=Date.now(),o=new Map;for(let a of n){let d=a,c=typeof d?.task_id=="string"?d.task_id:void 0;c!==void 0&&o.set(c,{taskType:typeof d?.task_type=="string"?d.task_type:"unknown",description:typeof d?.description=="string"?d.description:"",firstSeen:this.liveBackgroundTasks.get(c)?.firstSeen??r})}let i=[...this.liveBackgroundTasks.keys()].filter(a=>!o.has(a));this.liveBackgroundTasks=o,this.sawBackgroundTaskLevel=!0,this.logger?.info(`session ${this.sessionId} background level: ${o.size} live`+(i.length>0?` (ended: ${i.join(", ")})`:"")),this.onArmedTasksChanged()}get armedBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.entries()].map(([e,t])=>({taskId:e,label:t.description||t.taskType,taskType:t.taskType,since:t.firstSeen})):[...this.armedTasks.entries()].map(([e,t])=>({toolCallId:e,label:t.label,...t.taskId!==void 0?{taskId:t.taskId}:{},since:t.armedAt,...t.endUnobservable===!0?{endUnobservable:!0}:{}}))}pendingOneShotBackgroundTasks(){return this.sawBackgroundTaskLevel?[...this.liveBackgroundTasks.values()].filter(e=>xm.has(e.taskType)).map(e=>e.description||e.taskType):[...this.armedTasks.values()].filter(e=>!e.repeating&&e.endUnobservable!==!0).map(e=>e.label)}get armedSince(){let e;if(this.sawBackgroundTaskLevel){for(let t of this.liveBackgroundTasks.values())(e===void 0||t.firstSeen<e)&&(e=t.firstSeen);return e}for(let t of this.armedTasks.values())(e===void 0||t.armedAt<e)&&(e=t.armedAt);return e}onArmedTasksChanged(){let e=this.armedBackgroundTasks,t=e.length,n=this.armedSince,r=e.map(o=>o.taskId??o.toolCallId??o.label).sort().join("\0");r===this.lastArmedBroadcast?.key&&n===this.lastArmedBroadcast?.since||this.closed||(this.lastArmedBroadcast={key:r,since:n},this.broadcastQueueNotification("hydra-acp/session/armed_tasks_updated",{sessionId:this.sessionId,count:t,...n!==void 0?{since:n}:{},tasks:e}),this.dispatchIdle())}cancelPendingAgentRequests(){for(let e of[...this.elicitationCancellers.values()])e();for(let e of[...this.permissionCancellers.values()])e()}async retireAgent(e,t){return this.cancelPendingAgentRequests(),await e.kill().catch(()=>{}),this.resetBackgroundTaskLevel(),this.discardArmedTasks(t)}resetBackgroundTaskLevel(){this.liveBackgroundTasks.clear(),this.sawBackgroundTaskLevel=!1}discardArmedTasks(e){if(this.armedTasks.size===0)return[];let t=[...this.armedTasks.values()].map(n=>n.label);for(let[n,r]of this.armedTasks)r.openToolCall===!0&&this.openToolCalls.delete(n);return this.armedTasks.clear(),this.upstreamBaselineMs=void 0,this.logger?.info(`session ${this.sessionId} discarded ${t.length} armed task(s) on ${e}: ${t.join(", ")}`),this.onArmedTasksChanged(),t}noteBackgroundTaskStopped(e,t,n){if(!(n?.toolName==="TaskStop"||e.title==="TaskStop"))return;let o=t?.task_id;if(typeof o!="string"||o.length===0)return;let i=!1;for(let[a,d]of this.armedTasks)d.taskId===o&&(this.armedTasks.delete(a),i=!0);i&&this.onArmedTasksChanged()}rememberToolLabel(e,t,n,r){let o=n!==void 0&&typeof n.description=="string"&&n.description?n.description:void 0;if(o!==void 0)this.toolLabels.set(e,{label:o.slice(0,Lo),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,Lo),fromDescription:!1})}for(;this.toolLabels.size>Rm;){let i=this.toolLabels.keys().next().value;if(i===void 0)break;this.toolLabels.delete(i)}}openUnsolicitedTurn(){let e=Date.now();if(this.lastUnsolicitedCancelAt!==0&&e-this.lastUnsolicitedCancelAt<=s.UNSOLICITED_REOPEN_WINDOW_MS?this.cancelReopenStreak+=1:this.cancelReopenStreak=0,this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak>=s.UNSOLICITED_REOPEN_LIMIT){this.escalateUnresponsiveCancel();return}let t=this.lastBackgroundTask,n=!1;for(let[i,a]of this.armedTasks)a.repeating||a.openToolCall===!0||(this.armedTasks.delete(i),n=!0);n&&this.onArmedTasksChanged();let r={messageId:Oe(),startedAt:e,cause:t,steerCaused:this.pendingSteerDetach!==void 0};this.pendingSteerDetach=void 0,this.unsolicitedTurn=r,this.promptStartedAt=e,this.logger?.info(`session ${this.sessionId} agent resumed with no prompt in flight`+(t?` (after ${t.label})`:""));let o={unsolicited:!0};t&&(o.cause=t),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_started",messageId:r.messageId,_meta:{"hydra-acp":o}}})}async holdForUnsolicitedTurn(e){if(this.unsolicitedTurn===void 0){this.logger?.info(`session ${this.sessionId} queue hold skipped for ${e.messageId} (no unsolicited turn open)`);return}let t=Date.now(),n=this.unsolicitedTurn.cause;this.logger?.info(`session ${this.sessionId} holding ${e.messageId} behind unsolicited turn ${this.unsolicitedTurn.messageId}`+(n?` cause=${JSON.stringify(n.label)}`:"")),this.broadcastQueueNotification("hydra-acp/prompt_queue/held",{sessionId:this.sessionId,messageId:e.messageId,reason:"agent_resumed",...n?{cause:n}:{}});let r="turn_ended";for(;;){if(this.closing||this.closed){r="closing";break}if(e.cancelled){r="cancelled";break}if(this.unsolicitedTurn===void 0){r="turn_ended";break}await new Promise(i=>{let a=setTimeout(i,Tm);typeof a.unref=="function"&&a.unref()})}let o=Date.now()-t;this.logger?.info(`session ${this.sessionId} released ${e.messageId} reason=${r} heldMs=${o}`),this.broadcastQueueNotification("hydra-acp/prompt_queue/released",{sessionId:this.sessionId,messageId:e.messageId,reason:r,heldMs:o})}closeUnsolicitedTurn(e,t){let n=this.unsolicitedTurn;if(n===void 0)return;let r=Date.now()-n.startedAt;this.unsolicitedTurn=void 0,this.promptStartedAt=void 0,this.noteTurnEnded(),e==="cancelled"?this.lastUnsolicitedCancelAt=Date.now():(this.lastUnsolicitedCancelAt=0,this.cancelReopenStreak=0),this.logger?.info(`session ${this.sessionId} unsolicited turn ${n.messageId} closed reason=${e} durationMs=${r}`+(t?` by=${t}`:"")+(n.cause?` cause=${JSON.stringify(n.cause.label)}`:"")),e==="superseded"&&(this.supersededAutonomousTurn={turnMessageId:n.messageId,cause:n.cause,supersededAt:Date.now()}),this.recordCurrentUsageSnapshot(),!this.closed&&(e==="cancelled"?this.closeOpenToolCalls("cancelled"):e==="completed"&&this.armOpenToolCalls(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"_hydra_turn_ended",messageId:Oe(),startedMessageId:n.messageId,durationMs:r,_meta:{"hydra-acp":{unsolicited:!0,reason:e}}}}))}salvageSupersededTerminal(){let e=this.supersededAutonomousTurn;if(e===void 0)return;this.supersededAutonomousTurn=void 0;let t=this.autonomousSalvage;t!==void 0&&(this.autonomousSalvage=void 0,this.logger?.warn(`session ${this.sessionId} salvaged session/prompt from autonomous terminal (superseded turn ${e.turnMessageId}, ${Date.now()-e.supersededAt}ms earlier)`+(e.cause?` cause=${JSON.stringify(e.cause.label)}`:"")),t({stopReason:"end_turn",_meta:{[le]:{salvaged:{reason:"autonomous_terminal",supersededMessageId:e.turnMessageId}}}}))}async awaitPromptResponse(e){if(this.supersededAutonomousTurn===void 0)return e;try{return await new Promise((t,n)=>{this.autonomousSalvage=t,e.then(t,n)})}finally{this.autonomousSalvage=void 0}}recordTerminal(e,t){for(this.recentlyTerminal.set(e,{stopReason:t,terminatedAt:Date.now()});this.recentlyTerminal.size>vm;){let n=this.recentlyTerminal.keys().next().value;if(n===void 0)break;this.recentlyTerminal.delete(n)}}registerTurnNotify(e,t,n){let r=this.recentlyTerminal.get(e);if(r)return{alreadyTerminal:!0,stopReason:r.stopReason};for(this.pendingTurnNotifiers.set(e,{callbackUrl:t,secret:n,registeredAt:Date.now(),originalMessageId:e});this.pendingTurnNotifiers.size>wm;){let o=this.pendingTurnNotifiers.keys().next().value;if(o===void 0)break;this.pendingTurnNotifiers.delete(o)}return{alreadyTerminal:!1}}broadcastPromptAmended(e){let t=this.findUserEntry(e.newMessageId);if(!t)return;let n={sessionId:this.sessionId,cancelledMessageId:e.cancelledMessageId,newMessageId:e.newMessageId,prompt:t.prompt,originator:t.originator,amendedAt:Date.now()};this.broadcastQueueNotification("hydra-acp/prompt/amended",n)}findUserEntry(e){if(this.currentEntry?.messageId===e&&this.currentEntry.kind==="user")return this.currentEntry;let t=this.promptQueue.find(n=>n.messageId===e&&n.kind==="user");return t?.kind==="user"?t:void 0}visibleQueueDepth(){let e=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;for(let t of this.promptQueue)t.kind==="user"&&!t.cancelled&&(e+=1);return e}broadcastQueueAdded(e,t){let n=this.visibleQueueDepth(),r=t?.position??Math.max(0,n-1),o={sessionId:this.sessionId,messageId:e.messageId,originator:e.originator,prompt:e.prompt,position:r,queueDepth:n,enqueuedAt:e.enqueuedAt};t?.amending!==void 0&&(o._meta={"hydra-acp":{amending:t.amending}}),this.broadcastQueueNotification("hydra-acp/prompt_queue/added",o)}broadcastQueueUpdated(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/updated",{sessionId:this.sessionId,messageId:e,prompt:t})}broadcastQueueRemoved(e,t){this.broadcastQueueNotification("hydra-acp/prompt_queue/removed",{sessionId:this.sessionId,messageId:e,reason:t})}broadcastQueueNotification(e,t){for(let n of this.clients.values())n.connection.notify(e,t).catch(()=>{})}queueSnapshot(){let e=[],t=0;this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled&&e.push({messageId:this.currentEntry.messageId,originator:this.currentEntry.originator,prompt:this.currentEntry.prompt,position:t++,enqueuedAt:this.currentEntry.enqueuedAt});for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push({messageId:n.messageId,originator:n.originator,prompt:n.prompt,position:t++,enqueuedAt:n.enqueuedAt});return e}async flushPersistWrites(){await this.queueWriteChain.catch(()=>{})}replayPersistedQueue(e){for(let t of e){let n={clientId:`hydra-resurrected_${t.messageId}`};t.originator.clientInfo.name!==void 0&&(n.name=t.originator.clientInfo.name),t.originator.clientInfo.version!==void 0&&(n.version=t.originator.clientInfo.version);let r={kind:"user",messageId:t.messageId,originator:n,clientId:n.clientId,prompt:t.prompt,enqueuedAt:t.enqueuedAt,cancelled:!1,resolve:()=>{},reject:()=>{}};this.promptQueue.push(r),this.broadcastQueueAdded(r)}this.drainQueue()}cancelQueuedPrompt(e){if(this.currentEntry?.messageId===e)return{cancelled:!1,reason:"already_running"};let t=this.promptQueue.findIndex(r=>r.messageId===e);if(t<0)return{cancelled:!1,reason:"not_found"};let n=this.promptQueue[t];return n.cancelled=!0,this.promptQueue.splice(t,1),n.kind==="user"&&(this.broadcastQueueRemoved(e,"cancelled"),this.persistRewrite()),this.amendInProgress?.newMessageId===e&&(this.amendInProgress=void 0),n.resolve({stopReason:"cancelled"}),{cancelled:!0,reason:"ok"}}updateQueuedPrompt(e,t){if(this.currentEntry?.messageId===e)return{updated:!1,reason:"already_running"};let n=this.promptQueue.find(r=>r.messageId===e);return!n||n.kind!=="user"?{updated:!1,reason:"not_found"}:(n.prompt=t,this.broadcastQueueUpdated(e,t),this.persistRewrite(),{updated:!0,reason:"ok"})}amendPrompt(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let{targetMessageId:r,prompt:o,replaceQueue:i,onTargetCompleted:a}=t;if(this.currentEntry?.messageId===r&&this.currentEntry.kind==="user"&&!this.currentEntry.cancelled&&this.amendInProgress===void 0)return this.amendOnHead(n,o,r,i);let d=this.promptQueue.find(u=>u.messageId===r&&u.kind==="user");if(d&&d.kind==="user"&&!d.cancelled)return d.prompt=o,this.broadcastQueueUpdated(r,o),this.persistRewrite(),{amended:!0,reason:"ok",messageId:r};let c=this.recentlyTerminal.get(r);return c?c.stopReason==="cancelled"?{amended:!1,reason:"target_cancelled"}:a==="send_anyway"?{amended:!1,reason:"target_completed",messageId:this.enqueueAmendmentAsFollowUp(n,o)}:{amended:!1,reason:"target_completed"}:{amended:!1,reason:"target_not_found"}}amendOnHead(e,t,n,r){let o=Oe(),i={clientId:e.clientId};if(e.clientInfo?.name&&(i.name=e.clientInfo.name),e.clientInfo?.version&&(i.version=e.clientInfo.version),r){let c=[];for(let u of this.promptQueue){if(u.kind==="user"&&!u.cancelled){u.cancelled=!0,this.broadcastQueueRemoved(u.messageId,"cancelled"),u.resolve({stopReason:"cancelled"});continue}c.push(u)}this.promptQueue=c}let a={kind:"user",messageId:o,originator:i,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,wasAmend:!0,resolve:()=>{},reject:()=>{}};this.promptQueue.unshift(a),this.persistRewrite(),this.broadcastQueueAdded(a,{amending:n,position:1}),this.amendInProgress={cancelledMessageId:n,newMessageId:o};let d=this.pendingTurnNotifiers.get(n);return d&&(this.pendingTurnNotifiers.delete(n),this.pendingTurnNotifiers.set(o,d)),this.cancelExtensionDispatch(n,"amended"),this.agent.connection.notify("session/cancel",{sessionId:this.upstreamSessionId}).catch(()=>{}),{amended:!0,reason:"ok",messageId:o}}async steer(e,t){let n=this.clients.get(e);if(!n)throw fe(new Error("client not attached"),x.SessionNotFound);let r=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled;if(r&&this.agent.steeringSupported){this.pendingSteerDetach={messageId:this.currentEntry.messageId};let o;try{o=await this.forwardRequest("_session/steering",t)}catch(d){throw this.pendingSteerDetach=void 0,d}let i=o?.outcome,a=i==="injected"||i==="startedNewTurn"||i==="promptRequired"||i==="failed"?o:{outcome:"failed"};return a.outcome!=="startedNewTurn"&&(this.pendingSteerDetach=void 0),a.outcome==="injected"&&this.recordSteerAsUserMessageChunk(t.prompt,e),a.outcome==="startedNewTurn"?{...a,detached:!0}:a}return r?(this.amendOnHead(n,t.prompt,this.currentEntry.messageId,!1),{outcome:"startedNewTurn"}):t._meta?.steering?.idleBehavior==="promptRequired"?{outcome:"promptRequired",reason:"noRunningTurn"}:(this.prompt(e,{sessionId:t.sessionId,prompt:t.prompt},void 0,{steerOriginated:!0}).catch(o=>{this.logger?.warn(`steer-originated prompt failed to enqueue: ${o.message}`)}),{outcome:"startedNewTurn"})}recordSteerAsUserMessageChunk(e,t){let n=ht(e);n.length!==0&&this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"user_message_chunk",content:{type:"text",text:n},_meta:{"hydra-acp":{steered:!0}}}},t)}enqueueAmendmentAsFollowUp(e,t){let n=Oe(),r={clientId:e.clientId};e.clientInfo?.name&&(r.name=e.clientInfo.name),e.clientInfo?.version&&(r.version=e.clientInfo.version);let o={kind:"user",messageId:n,originator:r,clientId:e.clientId,prompt:t,enqueuedAt:Date.now(),cancelled:!1,resolve:()=>{},reject:()=>{}};return this.promptQueue.push(o),this.persistRewrite(),this.broadcastQueueAdded(o),this.drainQueue(),n}async cancel(e){if(!this.clients.get(e))throw fe(new Error("client not attached"),x.SessionNotFound);this.logger?.info(`session ${this.sessionId} session/cancel from ${e} promptInFlight=${this.promptInFlight} agentTurnInFlight=${this.agentTurnInFlight} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length}`),this.lastCancelAt=Date.now(),this.currentEntry?.kind==="user"&&this.currentEntry.messageId!==void 0&&this.cancelExtensionDispatch(this.currentEntry.messageId,"cancelled"),this.closeUnsolicitedTurn("cancelled"),this.cancelPendingAgentRequests(),this.agentTurnInFlight||this.closeOpenToolCalls("cancelled"),await this.forwardRequest("session/cancel",{sessionId:this.sessionId},new Set,0,"notification")}addTransformer(e){let t=this.transformChain.findIndex(n=>n.name===e.name);t>=0?this.transformChain[t]=e:this.transformChain.push(e),e.intercepts.has("lifecycle:session.opened")&&e.connection.notify("hydra-acp/transformer/session_event",{event:"session.opened",sessionId:this.sessionId}).catch(()=>{})}async forwardRequest(e,t,n=new Set,r=0,o="request"){let i=this.rewriteForAgent(t);for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name))continue;let c=`request:${e}`;if(!d.intercepts.has(c))continue;let u=`t_${Do()}`,l;try{l=await d.connection.request("hydra-acp/transformer/message",{token:u,phase:"request",method:e,direction:"client\u2192agent",sessionId:this.sessionId,envelope:i})}catch(h){this.logger?.warn(`transformer ${d.name} error on ${c}: ${h.message}`);continue}let y=l?.action??"continue";if(y==="stop")return o==="notification"?void 0:l?.payload??jo(e);if(y==="continue"){l?.payload&&typeof l.payload=="object"&&(i=l.payload),n.add(d.name);continue}if(y==="processing"){let h=a,f=i,k=new Set(n);return new Promise(g=>{let p=setTimeout(()=>{this.pendingClaims.delete(u)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:u,transformerName:d.name}),this.forwardRequest(e,f,new Set([...k,d.name]),h+1,o).then(g).catch(()=>g(o==="notification"?void 0:jo(e))))},Hs);typeof p.unref=="function"&&p.unref(),this.pendingClaims.set(u,{resolve:g,timer:p,transformerName:d.name,method:e,envelope:f,chainIdx:h,originatedBy:k,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 lt({request:(r,o)=>this.forwardRequest(r,o),sessionId:this.sessionId,modelId:e,verb:this.modelVerb,extraParams:t,logger:this.logger});return this.modelVerb=n.verb,this.modelVerbConfirmed=!0,n.result}noteModelVerbHint(e,t){e===void 0||this.modelVerbConfirmed||e===this.modelVerb||(this.logger?.info(`model verb for agent ${this.agentId} inferred as ${e} from ${t} (was ${this.modelVerb})`),this.modelVerb=e)}resetModelVerb(e){this.modelVerb=e??ze,this.modelVerbConfirmed=!1}async runAgentRequestChain(e,t,n=new Set,r=0){let o=t,i=`request:${e}`;for(let a=r;a<this.transformChain.length;a++){let d=this.transformChain[a];if(n.has(d.name)||!d.intercepts.has(i))continue;let c=`t_${Do()}`,u;try{u=await d.connection.request("hydra-acp/transformer/message",{token:c,phase:"request",method:e,direction:"agent\u2192client",sessionId:this.sessionId,envelope:o})}catch(y){this.logger?.warn(`transformer ${d.name} error on ${i}: ${y.message}`);continue}let l=u?.action??"continue";if(l==="stop")return{shortCircuit:!0,payload:u?.payload??Xm(e)};if(l==="continue"){u?.payload&&typeof u.payload=="object"&&(o=u.payload),n.add(d.name);continue}if(l==="processing"){let y=a,h=o,f=new Set(n),k=e;return new Promise(g=>{let p=setTimeout(()=>{this.pendingClaims.delete(c)&&(this.broadcastQueueNotification("hydra-acp/transformer/abandoned_request",{sessionId:this.sessionId,token:c,transformerName:d.name}),this.runAgentRequestChain(k,h,new Set([...f,d.name]),y+1).then(g).catch(()=>g({shortCircuit:!1,envelope:h})))},Hs);typeof p.unref=="function"&&p.unref(),this.pendingClaims.set(c,{resolve:w=>g({shortCircuit:!0,payload:w}),timer:p,transformerName:d.name,method:k,envelope:h,chainIdx:y,originatedBy:f,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):Hs,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:jo(n.method)))}},r);return typeof o.unref=="function"&&o.unref(),n.timer=o,!0}async emitToChain(e,t,n){let r=this.transformChain.findIndex(a=>a.name===e),o=r>=0?r+1:0,i=new Set([e]);if(t==="session/update"){await this.runResponseChain(n,i,o);return}return this.forwardRequest(t,n,i,o)}async emitToQueue(e,t){let n=this.transformChain.findIndex(c=>c.name===e),r=n>=0?n+1:0,o=(t??{}).prompt??[],i=Oe(),a=`transformer:${e}`,d={clientId:a,name:e};return new Promise((c,u)=>{let l={kind:"user",messageId:i,originator:d,clientId:a,prompt:o,enqueuedAt:Date.now(),cancelled:!1,emitterName:e,chainStartIdx:r,resolve:c,reject:u},y=this.insertEntryAt(l,"tail");this.persistRewrite(),this.broadcastQueueAdded(l,{position:y}),this.drainQueue()})}rewriteForAgent(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(t.sessionId===this.sessionId)return{...t,sessionId:this.upstreamSessionId}}return e}async close(e={}){if(e.deleteRecord&&(this.deleteRecordIntent=!0),!this.closed)return this.closeInFlight?this.closeInFlight:(this.closing=!0,this.closeInFlight=this.doClose(e),this.closeInFlight)}async doClose(e){let t=this.turnStartedAt!==void 0;this.logger?.info(`session ${this.sessionId} closing deleteRecord=${e.deleteRecord??!1} by=${e.by??"unknown"} midTurn=${t} unsolicitedTurn=${this.unsolicitedTurn!==void 0} queued=${this.promptQueue.length} awaitingPermission=${this.hasPermissionFlag}`),t&&this.logger?.warn(`session ${this.sessionId} closed mid-turn by=${e.by??"unknown"}; the in-flight turn will not settle and the agent is being killed`),this.cancelIdleTimer(),this.cancelOrphanTimer(),clearTimeout(this.upstreamPollTimer);for(let n of this.pendingClaims.values())clearTimeout(n.timer);this.pendingClaims.clear(),await this.requestAgentSessionClose(),await this.agent.kill().catch(()=>{}),this.markClosed({deleteRecord:e.deleteRecord??!1})}async requestAgentSessionClose(){if(this.agentCapabilities?.sessionCapabilities?.close===void 0)return;let e,t=new Promise(r=>{e=setTimeout(r,gm)}),n=this.agent.connection.request("session/close",{sessionId:this.upstreamSessionId}).then(()=>{},()=>{});await Promise.race([n,t]),clearTimeout(e)}onClose(e){return this.closeHandlers.push(e),()=>{let t=this.closeHandlers.indexOf(e);t>=0&&this.closeHandlers.splice(t,1)}}onTitleChange(e){this.titleHandlers.push(e)}retitle(e){return this.runTitleCommand(e)}retitleFromAgent(){return this.runTitleCommand("")}setTitle(e){let t=e.trim();if(!(!t||t===this.title)){this._titleSeedPending=!1,this.title=t,this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",title:t,updatedAt:new Date().toISOString()}});for(let n of this.titleHandlers)try{n(t)}catch{}}}maybeSeedTitleFromPrompt(e){if(!this._titleSeedPending||dt((e??{})._meta).ancillary===!0||this.promptCarriesSentBy(e))return;let r=ht((e??{}).prompt),o=Bo(r,200);!o||o.startsWith("/")||(this._titleSeedPending=!1,this.setTitle(o))}maybeApplyAgentModel(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="_hydra_current_model_update")return!1;let r=Nn(n.availableModels);r.length>0&&this.setAgentAdvertisedModels(r);let o=typeof n.currentModel=="string"?n.currentModel:typeof n.model=="string"?n.model:void 0;if(o===void 0)return!0;let i=o.trim();if(!i||i===this.currentModel)return!0;this.logger?.info(`live current_model_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(i)}`),this.currentModel=i;for(let a of this.modelHandlers)try{a(i)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentConfigOption(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="config_option_update")return!1;let r=n.configOptions;if(!Array.isArray(r))return!0;for(let i of r)this.applyOneConfigOptionEntry(i);let o=new Set(r.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i&&i!=="model"&&i!=="mode"&&i!=="agent"));return this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id)),this.fireConfigOptionsHandlers(),!0}applyAgentConfigOptionResponse(e,t){let n=e?.configOptions;if(!Array.isArray(n))return!1;let r=JSON.stringify(this.agentAdvertisedConfigOptions);for(let o of n){let i=o?.id;i==="model"||i==="mode"||i==="agent"||this.applyOneConfigOptionEntry(o)}if(Am(n,t)){let o=new Set(n.filter(i=>!!i&&typeof i=="object").map(i=>typeof i.id=="string"?i.id.trim():void 0).filter(i=>!!i));this.agentAdvertisedConfigOptions=this.agentAdvertisedConfigOptions.filter(i=>o.has(i.id))}return JSON.stringify(this.agentAdvertisedConfigOptions)!==r}applyOneConfigOptionEntry(e){if(!e||typeof e!="object")return;let t=e;if(t.id==="model"){let k=Nn(t.options);k.length>0&&this.setAgentAdvertisedModels(k);let g=t.currentValue;if(typeof g=="string"){let p=g.trim();p&&p!==this.currentModel&&(this.logger?.info(`live config_option_update(model): sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(p)}`),this.applyModelChange(p))}return}if(t.id==="mode"){let k=Us(t.options);k.length>0&&this.setAgentAdvertisedModes(k);let g=t.currentValue;if(typeof g=="string"){let p=g.trim();p&&p!==this.currentMode&&(this.logger?.info(`live config_option_update(mode): sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(p)}`),this.applyModeChange(p))}return}if(typeof t.id!="string"||!t.id.trim())return;let n=t.id.trim(),r=Uo(t.options);if(r.length===0)return;let o=t.name,i=typeof o=="string"&&o.trim()?o.trim():n,a=t.category,d=typeof a=="string"&&a.trim()?a.trim():"other",c=t.description,u=typeof c=="string"&&c.trim()?c.trim():void 0,l=t.currentValue,y=typeof l=="string"&&l.trim()?l.trim():r[0].value,h={id:n,name:i,category:d,type:"select",currentValue:y,options:r,...u?{description:u}:{}},f=this.agentAdvertisedConfigOptions.findIndex(k=>k.id===n);f>=0?this.agentAdvertisedConfigOptions[f]=h:this.agentAdvertisedConfigOptions.push(h)}maybeApplyAgentMode(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="current_mode_update")return!1;let r=typeof n.currentModeId=="string"?n.currentModeId:typeof n.currentMode=="string"?n.currentMode:typeof n.mode=="string"?n.mode:void 0;if(r===void 0)return!0;let o=r.trim();if(!o||o===this.currentMode)return!0;this.logger?.info(`current_mode_update: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(o)}`),this.currentMode=o;for(let i of this.modeHandlers)try{i(o)}catch{}return this.broadcastConfigOptions(),!0}maybeApplyAgentUsage(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="usage_update")return!1;let r={...this._currentUsage??{}},o=!1;if(typeof n.used=="number"&&!this.swapInFlight&&Ld(r.used,n.used)&&this.armRecallFromSelfCompaction(),typeof n.used=="number"&&r.used!==n.used&&(r.used=n.used,o=!0),typeof n.size=="number"&&r.size!==n.size&&(r.size=n.size,o=!0),n.cost&&typeof n.cost=="object"){let a=n.cost;typeof a.amount=="number"&&(this.reconcileCostLedger(a.amount)&&(o=!0),r.costAmount!==a.amount&&(r.costAmount=a.amount,o=!0)),typeof a.currency=="string"&&r.costCurrency!==a.currency&&(r.costCurrency=a.currency,o=!0)}if(!o)return!0;this._currentUsage=r;let i=this.persistableUsage??r;for(let a of this.usageHandlers)try{a(i)}catch{}return!0}armCostLedgerProbe(){let e=this._currentUsage?.costAmount;typeof e=="number"&&e>0&&(this.costLedgerProbe=e)}reconcileCostLedger(e){let t=this.costLedgerProbe;return t===void 0||(this.costLedgerProbe=void 0,e>=t-1e-6)?!1:(this.cumulativeCost+=t,!0)}notifyAgentChange(e,t,n,r){let o=this.retiringGenerationCost;this.retiringGenerationCost=void 0;let i=this.retiringGenerationUsed;this.retiringGenerationUsed=void 0;let a=this.rotationLifetimeCost;this.rotationLifetimeCost=void 0;for(let d of this.agentChangeHandlers)try{d({agentId:this.agentId,upstreamSessionId:this.upstreamSessionId,...o!==void 0?{retiredCost:o}:{},...a!==void 0?{lifetimeCost:a}:{},...i!==void 0?{retiredUsed:i}:{},...r!==void 0?{startedUsed:r}:{},...t!==void 0?{reason:t}:{},...n!==void 0?{runId:n}:{}})}catch(c){this.logger?.warn(`${e}: agentChange handler failed: ${c.message}`)}}accumulateAndResetCost(){let e=this._currentUsage?.costAmount;e&&(this.cumulativeCost+=e,this.retiringGenerationCost=e);let t=this._currentUsage?.used;typeof t=="number"&&t>0&&(this.retiringGenerationUsed=t),this.rotationLifetimeCost=this.cumulativeCost;let n={used:0,cumulativeCost:this.cumulativeCost,...typeof this._currentUsage?.size=="number"?{size:this._currentUsage.size}:{},...this._currentUsage?.costCurrency?{costCurrency:this._currentUsage.costCurrency}:{}};this._currentUsage=n;for(let r of this.usageHandlers)try{r(n)}catch{}this.broadcastCurrentUsage()}broadcastCurrentUsage(){let e=this.currentUsage;if(e===void 0)return;let t={sessionUpdate:"usage_update"};if(typeof e.used=="number"&&(t.used=e.used),typeof e.size=="number"&&(t.size=e.size),typeof e.costAmount=="number"||typeof e.costCurrency=="string"){let n={};typeof e.costAmount=="number"&&(n.amount=e.costAmount),typeof e.costCurrency=="string"&&(n.currency=e.costCurrency),t.cost=n}this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:t})}injectCumulativeCost(e){if(!this.cumulativeCost||!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update;if(n.sessionUpdate!=="usage_update"||!n.cost||typeof n.cost!="object")return e;let r=n.cost;return typeof r.amount!="number"?e:{...t,update:{...n,cost:{...r,amount:this.cumulativeCost+r.amount}}}}get totalUsage(){return this.currentUsage}setAgentAdvertisedCommands(e){if(Hm(this.agentAdvertisedCommands,e)){this.broadcastMergedCommands();return}this.agentAdvertisedCommands=e;for(let t of this.agentCommandsHandlers)try{t(e)}catch{}this.broadcastMergedCommands()}setAgentAdvertisedModes(e){if(jm(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(",")}]`),Um(this.agentAdvertisedModels,e)){this.broadcastAvailableModels();return}this.agentAdvertisedModels=e;for(let t of this.agentModelsHandlers)try{t(e)}catch{}this.broadcastAvailableModels()}onAgentCommandsChange(e){this.agentCommandsHandlers.push(e)}onAgentModesChange(e){this.agentModesHandlers.push(e)}onAgentModelsChange(e){this.agentModelsHandlers.push(e)}onConfigOptionsChange(e){this.configOptionsHandlers.push(e)}extraConfigOptionValues(){return Object.fromEntries(this.agentAdvertisedConfigOptions.map(e=>[e.id,e.currentValue]))}onModelChange(e){this.modelHandlers.push(e)}onModeChange(e){this.modeHandlers.push(e)}onInteractiveChange(e){this.interactiveHandlers.push(e)}onTagsChange(e){this.tagsHandlers.push(e)}onPriorityChange(e){this.priorityHandlers.push(e)}onReadStateChange(e){this.readStateHandlers.push(e)}get unread(){return Pn(this._lastTurnEndedAt,this._readAt)}setRead(e,t=Date.now()){let n=Ps({lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt},e,t);n!==void 0&&(this._readAt=n,this.fireReadState())}noteTurnEnded(e=Date.now()){this._readAt===void 0&&(this._readAt=Math.min(this._lastTurnEndedAt??this.createdAt,e-1)),this._lastTurnEndedAt=e,this.fireReadState(),this.captureUpstreamBaseline()}hasEndUnobservableTask(){for(let e of this.armedTasks.values())if(e.endUnobservable===!0)return!0;return!1}captureUpstreamBaseline(){let e=++this.upstreamBaselineGen;if(!this.hasEndUnobservableTask()){this.upstreamBaselineMs=void 0;return}this.fetchUpstreamUpdatedAt().then(t=>{t===void 0||e!==this.upstreamBaselineGen||this.promptInFlight||this.unsolicitedTurn!==void 0||(this.upstreamBaselineMs=t,this.scheduleUpstreamPoll(e))}).catch(()=>{})}scheduleUpstreamPoll(e){clearTimeout(this.upstreamPollTimer),this.upstreamPollTimer=setTimeout(()=>{this.upstreamPollTimer=void 0,this.pollUpstream(e)},Em),this.upstreamPollTimer.unref()}async pollUpstream(e){if(!this.upstreamPollLive(e))return;let t=await this.fetchUpstreamUpdatedAt().catch(()=>{});this.upstreamPollLive(e)&&(t!==void 0&&this.applyUpstreamUpdatedAt(t),this.upstreamPollLive(e)&&this.scheduleUpstreamPoll(e))}upstreamPollLive(e){return e===this.upstreamBaselineGen&&this.upstreamBaselineMs!==void 0&&!this.closing&&!this.closed&&this.hasEndUnobservableTask()}async fetchUpstreamUpdatedAt(){let t=(await this.agent.connection.request("session/list",{cwd:this.cwd}))?.sessions?.find(r=>r.sessionId===this.upstreamSessionId),n=typeof t?.updatedAt=="string"?Date.parse(t.updatedAt):NaN;return Number.isNaN(n)?void 0:n}noteUpstreamUpdatedAt(e){let t=e===void 0?NaN:Date.parse(e);Number.isNaN(t)||this.applyUpstreamUpdatedAt(t)}applyUpstreamUpdatedAt(e){if(this.upstreamBaselineMs===void 0||e<=this.upstreamBaselineMs||this.promptInFlight||this.unsolicitedTurn!==void 0)return;let t=0;for(let[n,r]of this.armedTasks)r.endUnobservable===!0&&(this.armedTasks.delete(n),t+=1);this.upstreamBaselineMs=void 0,t>0&&(this.logger?.info(`session ${this.sessionId} cleared ${t} armed task(s): agent updated the session after its turn ended`),this.onArmedTasksChanged())}fireReadState(){let e={lastTurnEndedAt:this._lastTurnEndedAt,readAt:this._readAt};for(let t of this.readStateHandlers)try{t(e)}catch{}}setPriority(e){let t=e===void 0||e<=0?void 0:Math.floor(e);if(t!==this._priority){this._priority=t,this.updatedAt=Date.now();for(let n of this.priorityHandlers)try{n(t)}catch{}}}setTags(e){let t=xt(e),n=t.length>0?t:void 0;if(!Xd(n,this._tags)){this._tags=n,this.updatedAt=Date.now(),this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,tags:n??[]}}}});for(let r of this.tagsHandlers)try{r(n)}catch{}}}applyModelChange(e){let t=e.trim();if(t){this.modelChangeInFlight=!0;try{if(t!==this.currentModel){this.logger?.info(`applyModelChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentModel)} \u2192 ${JSON.stringify(t)}`),this.currentModel=t;for(let r of this.modelHandlers)try{r(t)}catch{}}let n={sessionUpdate:"_hydra_current_model_update",currentModel:t};this.agentAdvertisedModels.length>0&&(n.availableModels=[...this.agentAdvertisedModels]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modelChangeInFlight=!1}}}applyModeChange(e){let t=e.trim();if(t){this.modeChangeInFlight=!0;try{if(t!==this.currentMode){this.logger?.info(`applyModeChange: sessionId=${this.sessionId} ${JSON.stringify(this.currentMode)} \u2192 ${JSON.stringify(t)}`),this.currentMode=t;for(let r of this.modeHandlers)try{r(t)}catch{}}let n={sessionUpdate:"current_mode_update",currentModeId:t};this.agentAdvertisedModes.length>0&&(n.availableModes=[...this.agentAdvertisedModes]),this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:n}),this.broadcastConfigOptions()}finally{this.modeChangeInFlight=!1}}}buildConfigOptions(){let e=[];if(this.agentAdvertisedModels.length>0){let r=this.agentAdvertisedModels.map(i=>({value:i.modelId,name:i.name??i.modelId,...i.description!==void 0?{description:i.description}:{}}));this.currentModel&&!r.some(i=>i.value===this.currentModel)&&r.unshift({value:this.currentModel,name:this.currentModel});let o=this.currentModel||r[0].value;e.push({id:"model",name:"Model",category:"model",type:"select",currentValue:o,options:r})}if(this.agentAdvertisedModes.length>0){let r=this.agentAdvertisedModes.map(i=>({value:i.id,name:i.name??i.id,...i.description!==void 0?{description:i.description}:{}}));this.currentMode&&!r.some(i=>i.value===this.currentMode)&&r.unshift({value:this.currentMode,name:this.currentMode});let o=this.currentMode||r[0].value;e.push({id:"mode",name:"Session Mode",category:"mode",type:"select",currentValue:o,options:r})}let n=(this.availableAgentsFn?.()??[]).map(r=>({value:r.id,name:r.name??r.id,...r.description!==void 0?{description:r.description}:{}}));return n.some(r=>r.value===this.agentId)||n.unshift({value:this.agentId,name:this.agentId}),e.push({id:"agent",name:"Agent",category:"_hydra_agent",type:"select",currentValue:this.agentId,options:n}),e.push(...this.agentAdvertisedConfigOptions),e}broadcastConfigOptions(){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"config_option_update",configOptions:this.buildConfigOptions()}}),this.fireConfigOptionsHandlers()}fireConfigOptionsHandlers(){for(let e of this.configOptionsHandlers)try{e(this.agentAdvertisedConfigOptions)}catch{}}mergeAgentOptionIntoEnvelope(e){if(!e||typeof e!="object")return e;let t=e;if(!t.update||typeof t.update!="object")return e;let n=t.update,r=Array.isArray(n.configOptions)?[...n.configOptions]:[];if(r.some(a=>a&&typeof a=="object"&&a.id==="agent"))return e;let i=this.buildConfigOptions().find(a=>a.id==="agent");return i?{...t,update:{...n,configOptions:[...r,i]}}:e}onUsageChange(e){this.usageHandlers.push(e)}mergedAvailableCommands(){let e=this.daemonTopLevelCommands(),t=this.aliasableBareVerbs();for(let n of Kt){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=Io(n),c=d??n;if(d!==void 0){let u=r.verb?`hydra ${c} ${r.verb}`:`hydra ${c}`,y={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(y.description=r.description),e.push(y)}if(c.length>0&&t.get(c)===n){let u=r.verb?`${c} ${r.verb}`:c,y={name:r.argsHint?`${u} ${r.argsHint}`:u};r.description&&(y.description=r.description),e.push(y)}}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 Kt)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=Io(i)??i;if(!a||e.has(a)||n.has(a))continue;let d=r.get(a);d===void 0?r.set(a,i):d!==i&&r.set(a,"__conflict__")}for(let[i,a]of r)a!=="__conflict__"&&n.set(i,a);return n}agentOnlyAdvertisedCommands(){return[...this.agentAdvertisedCommands]}agentKnowsSlashCommand(e){let t=r=>r.startsWith("/")?r.slice(1):r,n=t(e);if(!n)return!1;for(let r of this.agentAdvertisedCommands)if(t(r.name.split(/\s+/)[0]??"")===n)return!0;return!1}availableModes(){return[...this.agentAdvertisedModes]}availableModels(){return[...this.agentAdvertisedModels]}maybeApplyAgentSessionInfo(e){let n=(e??{}).update??{};if(n.sessionUpdate!=="session_info_update"||typeof n.title!="string"||this._upstreamRespawned)return;let r=n.title.trim();if(!(!r||r===this.title)){this.title=r,this._firstPromptSeeded=!0,this._titleSeedPending=!1;for(let o of this.titleHandlers)try{o(r)}catch{}}}async handleSlashCommand(e,t){let r=e.slice(6).trim().match(/^(\S+)(?:\s+([\s\S]*))?$/),o=r?.[1]??"",i=(r?.[2]??"").trim();if(o==="")return{stopReason:"end_turn"};let a=t!==void 0;if(Kt.some(l=>l.verb===o))switch(o){case"title":return a?this.runTitleCommandInline(i):this.runTitleCommand(i);case"agent":return this.runAgentCommandInline(i);case"config":return this.handleConfigCommand(`/config ${i}`);case"kill":return this.runKillCommand();case"workspace":return this.runWorkspaceCommand(i);case"restart":return a?this.runRestartCommandInline():this.runRestartCommand();case"clear":return this.runClearCommand();case"tag":case"untag":return this.runTagCommand(o==="untag",i);case"compact":return a?this.runCompactCommandInline(i):this.runCompactCommand(i);case"uncompact":return a?this.runUncompactCommandInline():this.runUncompactCommand();case"fork":return a?this.runForkCommandInline(i,t):this.runForkCommand(i);default:{let l=new Error(`no dispatcher for /hydra verb ${o}`);throw l.code=x.InternalError,l}}if(this.extensionCommands?.has(o))return a?this.runExtensionCommandInline(o,i,t):this.runExtensionCommand(o,i);let d=Ed(o).find(l=>this.extensionCommands?.has(l));if(d!==void 0)return a?this.runExtensionCommandInline(d,i,t):this.runExtensionCommand(d,i);let c=Kt.map(l=>l.verb);if(this.extensionCommands){let l=new Set;for(let{name:y}of this.extensionCommands.list())l.has(y)||(c.push(y),l.add(y))}let u=new Error(`unknown /hydra verb: ${o} (known: ${c.join(", ")})`);throw u.code=x.InvalidParams,u}runExtensionCommand(e,t){return this.enqueuePrompt(`extension:${e}`,()=>this.runExtensionCommandInline(e,t,void 0))}async runExtensionCommandInline(e,t,n){let r=this.extensionCommands?.get(e);if(!r)return this.emitExtensionReply(`extension "${e}" is no longer connected`);let o=t.match(/^(\S+)(?:\s+([\s\S]*))?$/),i=o?.[1]??"",a=(o?.[2]??"").trim();if(!r.commands.some(f=>f.verb===i)){let f=r.commands.map(k=>k.verb).join(", ");return this.emitExtensionReply(`/hydra ${e}${i?` ${i}`:""}: unknown verb (known: ${f||"(none)"})`)}let d={sessionId:this.sessionId,verb:i,args:a};n!==void 0&&(d.messageId=n);let c=()=>{},u=new Promise(f=>{c=f});n!==void 0&&this.inFlightExtensionDispatches.set(n,{extensionName:e,connection:r.connection,cancel:f=>c({stopReason:"cancelled",reason:f})});let l,y=!1;try{let f=r.connection.request("hydra-acp/commands/invoke",d),k=await Promise.race([f,u]);if(k&&typeof k=="object"&&k.stopReason==="cancelled"&&"reason"in k)return y=!0,this.logger?.info(`extension ${e} ${i} cancelled (cancelExtensionDispatch); abandoning in-flight commands/invoke`),{stopReason:"cancelled"};l=k}catch(f){return this.emitExtensionReply(`${e} ${i}: ${f.message}`)}finally{n!==void 0&&!y&&this.inFlightExtensionDispatches.delete(n)}let h=l&&typeof l=="object"&&typeof l.text=="string"?l.text:"";return h.length>0?this.emitExtensionReply(h):{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:`
65
71
  ${e}
66
72
  `},_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?" \u25C4":"",d=r.title?` ${r.title}`:"";return`\`${o}\` ${r.cwd}${i}${a}${d}`});e=`Sessions (${t.length}):
67
73
  ${n.join(`
@@ -71,10 +77,10 @@ ${e}
71
77
  ${t.join(`
72
78
  `)}`:"_(no commands advertised)_";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
73
79
  ${n}
74
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),Promise.resolve({stopReason:"end_turn"})}async handleModelCommand(e){let t=e.slice(6).trim();if(t===""){let i=this.agentAdvertisedModels,a=this.currentModel,d;if(i.length===0)d=a?`Current model: ${a}`:"_(no models advertised yet)_";else{let c=a?i.some(l=>l.modelId===a):!0,u=i.map(l=>{let w=l.modelId===a?"\u25BA ":" ",h=l.name&&l.name!==l.modelId?` ${l.name}`:"";return`${w}${l.modelId}${h}`});!c&&a&&u.unshift(`\u25BA ${a}`),d=u.join(`
80
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),Promise.resolve({stopReason:"end_turn"})}async handleModelCommand(e){let t=e.slice(6).trim();if(t===""){let i=this.agentAdvertisedModels,a=this.currentModel,d;if(i.length===0)d=a?`Current model: ${a}`:"_(no models advertised yet)_";else{let c=a?i.some(l=>l.modelId===a):!0,u=i.map(l=>{let y=l.modelId===a?"\u25BA ":" ",h=l.name&&l.name!==l.modelId?` ${l.name}`:"";return`${y}${l.modelId}${h}`});!c&&a&&u.unshift(`\u25BA ${a}`),d=u.join(`
75
81
  `)}return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
76
82
  ${d}
77
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let n=Gt(t,this.agentAdvertisedModels),r=t;if(n.kind==="resolved")r=n.modelId;else if(n.kind==="ambiguous"||n.kind==="unknown"){let i=this.agentAdvertisedModels.map(w=>w.modelId),a=t.toLowerCase(),d=n.kind==="ambiguous"?n.candidates:i.filter(w=>w.toLowerCase().includes(a)),c=d.length>0?d:i,u=n.kind==="ambiguous"?`"${t}" matches multiple models: ${n.candidates.join(", ")}`:d.length>0?`"${t}" is not an available model. Did you mean`:`"${t}" is not an available model`,l=n.kind==="ambiguous"||d.length===0?"Available models":"Matching models";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
83
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let n=Yt(t,this.agentAdvertisedModels),r=t;if(n.kind==="resolved")r=n.modelId;else if(n.kind==="ambiguous"||n.kind==="unknown"){let i=this.agentAdvertisedModels.map(y=>y.modelId),a=t.toLowerCase(),d=n.kind==="ambiguous"?n.candidates:i.filter(y=>y.toLowerCase().includes(a)),c=d.length>0?d:i,u=n.kind==="ambiguous"?`"${t}" matches multiple models: ${n.candidates.join(", ")}`:d.length>0?`"${t}" is not an available model. Did you mean`:`"${t}" is not an available model`,l=n.kind==="ambiguous"||d.length===0?"Available models":"Matching models";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
78
84
  ${u}.
79
85
  ${l}:
80
86
  ${c.join(`
@@ -84,28 +90,33 @@ ${l}:
84
90
  ${i}
85
91
  `},_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 fe(new Error(`unknown mode: ${t} (known: ${r})`),x.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 l=this.buildConfigOptions();if(l.length===0)return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
86
92
  _(no config options advertised yet)_
87
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let w=l.map(h=>Ud(h));return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
88
- ${w.join(`
93
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let y=l.map(h=>ic(h));return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
94
+ ${y.join(`
89
95
 
90
96
  `)}
91
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let o=this.buildConfigOptions(),i=o.find(l=>l.id===n);if(!i){let l=o.map(w=>w.id).join(`
97
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}let o=this.buildConfigOptions(),i=o.find(l=>l.id===n);if(!i){let l=o.map(y=>y.id).join(`
92
98
  `);return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
93
99
  "${n}" is not a known config option.
94
100
  Available options:
95
101
  ${l}
96
102
  `},_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:`
97
- ${Ud(i)}
98
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let a=i.options.map(l=>l.value),d=Kt(r,a),c=r;if(d.kind==="resolved")c=d.modelId;else if(d.kind==="ambiguous"||d.kind==="unknown"){let l=r.toLowerCase(),w=d.kind==="ambiguous"?d.candidates:a.filter(p=>p.toLowerCase().includes(l)),h=w.length>0?w:a,f=d.kind==="ambiguous"?`"${r}" matches multiple values for "${n}": ${d.candidates.join(", ")}`:w.length>0?`"${r}" is not a valid value for "${n}". Did you mean`:`"${r}" is not a valid value for "${n}"`,k=d.kind==="ambiguous"||w.length===0?"Valid values":"Matching values";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
103
+ ${ic(i)}
104
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"};let a=i.options.map(l=>l.value),d=Xt(r,a),c=r;if(d.kind==="resolved")c=d.modelId;else if(d.kind==="ambiguous"||d.kind==="unknown"){let l=r.toLowerCase(),y=d.kind==="ambiguous"?d.candidates:a.filter(g=>g.toLowerCase().includes(l)),h=y.length>0?y:a,f=d.kind==="ambiguous"?`"${r}" matches multiple values for "${n}": ${d.candidates.join(", ")}`:y.length>0?`"${r}" is not a valid value for "${n}". Did you mean`:`"${r}" is not a valid value for "${n}"`,k=d.kind==="ambiguous"||y.length===0?"Valid values":"Matching values";return this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
99
105
  ${f}.
100
106
  ${k}:
101
107
  ${h.join(`
102
108
  `)}
103
- `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}if(n==="model"){if(c!==this.currentModel){let l=await this.forwardModelChange(c);this.applyAgentConfigOptionResponse(l,"model")}return this.applyModelChange(c),{stopReason:"end_turn"}}if(n==="mode")return c!==this.currentMode&&await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:c}),this.applyModeChange(c),{stopReason:"end_turn"};if(n==="agent")return c!==this.agentId&&await this.runAgentCommandInline(c),{stopReason:"end_turn"};let u=await this.forwardRequest("session/set_config_option",{sessionId:this.sessionId,configId:n,value:c});return this.applyAgentConfigOptionResponse(u,n)&&this.broadcastConfigOptions(),{stopReason:"end_turn"}}runTitleCommand(e){return this.enqueuePrompt("title",()=>this.runTitleCommandInline(e))}async runTitleCommandInline(e){return e?(this.setTitle(e),{stopReason:"end_turn"}):(this.scheduleSynopsisHook?.(),{stopReason:"end_turn"})}async runInternalPrompt(e){if(this.internalPromptCapture)throw new Error("internal prompt already in flight");let t={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};this.internalPromptCapture=t;try{return await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:e}]}),t.chunks.join("")}finally{this.internalPromptCapture=void 0}}setAgent(e){return this.runAgentCommandInline(e)}async runAgentCommandInline(e){if(e==="status")return this.runAgentStatusCommandInline();let t=e;if(!t)throw fe(new Error("/hydra agent requires an agent id"),x.InvalidParams);let r=(this.resolveAgentIdHook?await this.resolveAgentIdHook(t):void 0)??t;if(r===this.agentId)throw fe(new Error(`already on agent ${r}`),x.InvalidParams);if(!this.scheduleCompactionHook)return this.emitExtensionReply("agent switching not configured for this session"),{stopReason:"end_turn"};this.scheduleCompactionHook({targetAgentId:r});let o=this.agentTurnInFlight||this.unsolicitedTurn!==void 0;return this.emitExtensionReply(o?`Agent switch to ${r} scheduled. A turn is still in flight \u2014 the rotation lands on the next idle edge; cancel the turn to make that happen now.`:`Agent switch to ${r} scheduled. The session will rotate to ${r} once synthesis completes.`),{stopReason:"end_turn"}}async runAgentStatusCommandInline(){let e=await this.getPendingAgentSwapHook?.();return e?(this.emitExtensionReply(`Agent switch to ${e} pending \u2014 will rotate on the next idle edge.`),{stopReason:"end_turn"}):(this.emitExtensionReply("No agent switch pending."),{stopReason:"end_turn"})}async runKillCommand(){return await this.close({deleteRecord:!1,by:"/hydra kill"}),{stopReason:"end_turn"}}runRestartCommand(){return this.enqueuePrompt("restart",()=>this.runRestartCommandInline())}async runRestartCommandInline(){if(!this.spawnReplacementAgent)throw fe(new Error("agent restart not configured for this session"),x.InternalError);return await this.respawnAgent(),{stopReason:"end_turn"}}runCompactCommand(e){return this.enqueuePrompt("compact",()=>this.runCompactCommandInline(e))}async runCompactCommandInline(e){return e==="status"?this.runCompactStatusCommandInline():this.scheduleCompactionHook?(this.scheduleCompactionHook(),this.emitExtensionReply("Compaction scheduled. The session will rotate to a fresh upstream once summarization completes."),{stopReason:"end_turn"}):(this.emitExtensionReply("compaction scheduling not configured for this session"),{stopReason:"end_turn"})}async runCompactStatusCommandInline(){let e=await this.getCompactionStateHook?.(),t=this._summarizedThroughEntry,n=await this.getUpstreamGenerationsHook?.()??[],r=Rd(n,t),o=xd(r);if(e==null&&t==null&&o.length===0)return this.emitExtensionReply("This session has never been compacted."),{stopReason:"end_turn"};let i=[];return e==null?i.push(`No compaction in progress. Last summarized through entry: ${t??0}`):(i.push(`Compaction state: ${e.status}${e.iter!=null?` (iteration ${e.iter})`:""}`,`Summarized through entry: ${t??0}`,`Pending attempts: ${e.attempts??0}`),e.lastError!==void 0&&i.push(`Last error: ${e.lastError}`)),i.push(`Current upstream: ${this.upstreamSessionId}`),o.length>0&&i.push("",...o),this.emitExtensionReply(i.join(`
104
- `)),{stopReason:"end_turn"}}runUncompactCommand(){return this.enqueuePrompt("uncompact",()=>this.runUncompactCommandInline())}async runWorkspaceCommand(e){if(!this.workspaceHook)return this.emitExtensionReply("Workspaces are not available on this session (no workspace hook configured)."),{stopReason:"end_turn"};let[t="status",...n]=e.split(/\s+/).filter(d=>d.length>0);if(!$d.includes(t))return this.emitExtensionReply(`Unknown workspace verb "${t}". Use one of: ${$d.join(", ")}.`),{stopReason:"end_turn"};let r=n.filter(d=>d.startsWith("--")),o=r.filter(d=>d!=="--clean"&&d!=="--deep");if(o.length>0)return this.emitExtensionReply(`Unknown workspace flag(s) ${o.join(", ")}. Supported: --clean (start), --deep (clean).`),{stopReason:"end_turn"};let i={clean:r.includes("--clean"),deep:r.includes("--deep")};if(i.clean&&t!=="start")return this.emitExtensionReply(`--clean applies to \`start\`, not to \`${t}\`.`),{stopReason:"end_turn"};if(i.deep&&t!=="clean")return this.emitExtensionReply(`--deep applies to \`clean\`, not to \`${t}\`.`),{stopReason:"end_turn"};let a=n.filter(d=>!d.startsWith("--")).join(" ").trim();try{let d=await this.workspaceHook(t,a.length>0?a:void 0,i);this.emitExtensionReply(d)}catch(d){this.emitExtensionReply(`Workspace ${t} failed: ${d instanceof Error?d.message:String(d)}`)}return{stopReason:"end_turn"}}async runUncompactCommandInline(){if(!this.uncompactHook)return this.emitExtensionReply("Rollback not available: uncompact hook not configured for this session."),{stopReason:"end_turn"};try{await this.uncompactHook(),this.emitExtensionReply("Rolled back to pre-compaction upstream. The session is now using the previous agent context.")}catch(e){this.emitExtensionReply(`Rollback failed: ${e instanceof Error?e.message:String(e)}`)}return{stopReason:"end_turn"}}runForkCommand(e){return this.enqueuePrompt("fork",()=>this.runForkCommandInline(e,void 0))}async findMessageIdBefore(e){if(!this.historyStore)return;let t=await this.historyStore.load(this.sessionId),n;for(let r of t){if(r.method!=="session/update")continue;let i=r.params?.update?.messageId;if(typeof i=="string"){if(i===e)return n;n=i}}}async runForkCommandInline(e,t){if(!this.forkHook)return this.emitExtensionReply("Fork not configured for this session."),{stopReason:"end_turn"};let n=(e??"").trim(),r=n.match(/^--verbatim(?:\s+([\s\S]*))?$/),o=r?"verbatim":void 0,i=(r?r[1]??"":n).trim();try{let a={};if(o&&(a.mode=o),i!==""&&(a.prompt=i),t&&this.historyStore){let u=await this.findMessageIdBefore(t).catch(()=>{});u&&(a.forkAt=u)}let c=(await this.forkHook(Object.keys(a).length>0?a:void 0)).sessionId.replace(/^hydra_session_/,"");this.emitExtensionReply(i!==""?`Forked to [\`${c}\`](hydra://sessions/${c}) and sent the prompt.`:`Forked to [\`${c}\`](hydra://sessions/${c}).`)}catch(a){this.emitExtensionReply(`Fork failed: ${a instanceof Error?a.message:String(a)}`)}return{stopReason:"end_turn"}}escalateUnresponsiveCancel(){this.cancelReopenStreak=0,this.logger?.warn(`session ${this.sessionId} agent ${this.agentId} reopened an unsolicited turn right after cancel ${s.UNSOLICITED_REOPEN_LIMIT} times in a row; forcing a restart`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,reason:"unresponsive",message:`${this.agentId} kept resuming after repeated cancels; restarting the agent`}),this.forceCancel().catch(e=>{this.logger?.warn(`session ${this.sessionId} forceCancel after unresponsive-cancel escalation failed: ${e instanceof Error?e.message:String(e)}`)})}async forceCancel(){if(this.closed||this.closing)throw fe(new Error("session is closing"),x.SessionClosing);return this.lastCancelAt=0,this.forceCancelling=!0,await this.close({deleteRecord:!1,by:"force-cancel"}),{stopReason:"cancelled"}}async rewind(e,t,n={}){let r=()=>this.promptInFlight&&!n.afterCurrentTurn||this.promptQueue.length>0?"the session is busy; wait for the current turn and queued prompts to finish, then try again":this.swapInFlight?"the session's agent is being replaced; try again in a moment":void 0,o=r()??await this.quiesceBlocker()??r();if(o!==void 0)throw fe(new Error(o),x.InvalidRequest);if(!this.spawnReplacementAgent)throw fe(new Error("agent restart not configured for this session"),x.InternalError);await this.enqueuePrompt("rewind",async()=>{this.swapInFlight=!0;try{if(!await t())return;await this.respawnAgent({rewind:!0})}finally{this.swapInFlight=!1}this.broadcastClientUpdate({sessionUpdate:"_hydra_history_truncated",keepThrough:e})})}runClearCommand(){if(!this.rewindHook)throw fe(new Error("clear not configured for this session"),x.InternalError);return this.rewindHook(null).catch(e=>{this.broadcastSyntheticText(`/hydra clear failed: ${e.message}`)}),Promise.resolve({stopReason:"end_turn"})}async respawnAgent(e={}){let t=this.spawnReplacementAgent,n=this.agentId,r=await this.buildSwitchTranscript(n,e.rewind?{intro:"You are continuing a conversation whose later turns were withdrawn by the user. Below is the transcript of what remains.",followup:"Each line is prefixed with its speaker. Treat this as context for the next user message; do not re-respond to earlier turns."}:void 0),o=this.currentModel,i=this.currentMode,a=await t({agentId:n,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{}});if(this.accumulateAndResetCost(),this.wireAgent(a.agent,{respawn:!0}),e.rewind){let c=await ft({agent:a.agent,upstreamSessionId:a.upstreamSessionId,persistedModel:o,agentReportedModel:a.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(c.result,"model"),await lt({agent:a.agent,upstreamSessionId:a.upstreamSessionId,persistedMode:i,agentReportedMode:a.initialMode,logger:this.logger}),a.agent.connection.drainBuffered("session/update")}let d=this.agent;this.agent=a.agent,this.upstreamSessionId=a.upstreamSessionId,this.agentMeta=a.agentMeta,this.agentCapabilities=a.agentCapabilities,this.resetModelVerb(a.modelVerb),this.agentAdvertisedCommands=[],this.broadcastMergedCommands(),e.rewind||(this.currentModel=a.initialModel,this.currentMode=a.initialMode),this.setAgentAdvertisedModels(a.initialModels??[]),this.setAgentAdvertisedModes(a.initialModes??[]),this.agentAdvertisedConfigOptions=a.initialConfigOptions??[],await this.retireAgent(d,"agent restart"),r&&await this.runInternalPrompt(r).catch(()=>{}),e.rewind||this.broadcastAgentSwitch(n,n),this.notifyAgentChange("respawnAgent","restart")}async buildSwitchTranscript(e,t){let n=[],r=await this.getHistorySnapshot();for(let c of r){if(c.method!=="session/update")continue;let l=(c.params??{}).update;if(!l||l._meta?.["hydra-acp"]?.synthetic)continue;let h=l.sessionUpdate;if(h==="prompt_received"){let f=At(l.prompt);f&&n.push({speaker:"user",text:f})}else if(h==="agent_message_chunk"){let k=l.content?.text;k&&n.push({speaker:`agent: ${e}`,text:k})}else if(h==="tool_call"||h==="tool_call_update"){let f=l.status,k=l.title;(f==="completed"||f==="failed")&&n.push({speaker:"tool",text:`${k??"?"} ${f}`})}}if(n.length===0)return"";let o=[],i;for(let c of n)i&&i.speaker===c.speaker?i.text+=c.text:(i&&o.push(`<${i.speaker}>: ${i.text.trim()}`),i={speaker:c.speaker,text:c.text});i&&o.push(`<${i.speaker}>: ${i.text.trim()}`);let a=t?.intro??`You are taking over this conversation from ${e}. Below is the transcript so far.`,d=t?.followup??`Each line is prefixed with its speaker. Continue from where ${e} left off, responding to the user's most recent message.`;return[a,d,"","--- begin transcript ---",...o,"--- end transcript ---"].join(`
105
- `)}async seedFromImport(){await this.enqueuePrompt("seed:import",async()=>{let e=await this.buildSwitchTranscript(this.agentId,{intro:"You are continuing a conversation that was imported from another hydra. Below is the transcript so far.",followup:"Each line is prefixed with its speaker. Treat this as context for the next user message; do not re-respond to earlier turns."});e&&await this.runInternalPrompt(e).catch(()=>{})})}async seedFromFork(e){await this.enqueuePrompt("seed:fork",async()=>{let t=this.title??"(untitled)",n=[];if(this.historyStore)try{n=await this.historyStore.load(this.sessionId)}catch(o){this.logger?.warn(`seedFromFork: historyStore.load failed: ${o.message}`)}let r=vo({synopsis:e,title:t,tail:n,tailK:Wg,tailFloor:qg,watermark:this._summarizedThroughEntry,recallArmed:(this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("seedFromFork: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:r}]});let o=this.internalPromptCapture;this.logger?.info(`seedFromFork: seed processed sessionId=${this.sessionId} seedChars=${r.length} toolCalls=${o.toolCalls} thinkingChars=${o.thinkingChars} messageChars=${o.messageChars}`)}finally{this.internalPromptCapture=void 0}})}broadcastAgentSwitch(e,t){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,agentId:t,pendingAgentSwap:null}}}}),this.broadcastConfigOptions()}broadcastPendingAgentSwap(e){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,pendingAgentSwap:e}}}})}hasStreamBuffer(){return this.streamBuffer!==void 0}get streamPath(){return this.streamFilePath}openStream(e){if(this.streamBuffer!==void 0)throw new Error(`stream buffer already open for session ${this.sessionId}`);let n=(e.mode??"memory")==="file"&&e.filePathFor!==void 0?e.filePathFor(this.sessionId):void 0,r={};e.capacityBytes!==void 0&&(r.capacityBytes=e.capacityBytes),n!==void 0&&(r.filePath=n),e.fileCapBytes!==void 0&&(r.fileCapBytes=e.fileCapBytes),r.onFileCapReached=()=>{this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_stream_truncated",...n!==void 0?{filePath:n}:{},fileCapBytes:e.fileCapBytes}})};let o=new Cs(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??Jt,Jt)),i=r.read(e,o);if(i.bytes.length===0&&i.eof!==!0&&n!==void 0&&n>0){let d=await r.waitForData(i.nextCursor,n);(d==="data"||d==="eof")&&(i=r.read(i.nextCursor,o))}let a={bytes:i.bytes.toString("base64"),nextCursor:i.nextCursor};return i.gap!==void 0&&(a.gap=i.gap),i.eof===!0&&(a.eof=!0),a}streamTail(e){let n=this.requireStreamBuffer().tail(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}streamHead(e){let n=this.requireStreamBuffer().head(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}async streamWaitFor(e,t){return this.requireStreamBuffer().waitForData(e,t)}streamGrep(e){return this.requireStreamBuffer().grep(e)}streamInfo(){let e=this.requireStreamBuffer();return{writeCursor:e.writeCursorPos,oldestAvailable:e.oldestAvailable,capacity:e.capacity,closed:e.isClosed}}requireStreamBuffer(){if(this.streamBuffer===void 0){let e=new Error(`session ${this.sessionId} has no stream buffer; POST /v1/sessions/:id/stdin/open first`);throw e.code=x.StreamNotEnabled,e}return this.streamBuffer}markClosed(e){if(this.closed)return;this.closeUnsolicitedTurn("closed"),e={deleteRecord:e.deleteRecord||this.deleteRecordIntent},this.closing=!0,this.closed=!0,this.cancelIdleTimer(),this.cancelOrphanTimer(),this.extensionCommandsUnsub&&(this.extensionCommandsUnsub(),this.extensionCommandsUnsub=void 0);for(let o of[...this.inFlightExtensionDispatches.keys()])this.cancelExtensionDispatch(o,"abandoned");this.currentEntry?.kind==="user"&&!this.recentlyTerminal.has(this.currentEntry.messageId)&&this.broadcastTurnComplete(this.currentEntry.clientId,{stopReason:"interrupted"},this.currentEntry.messageId,this.originatorNeedsTurnComplete(this.currentEntry)),this.currentEntry=void 0;let n=this.promptQueue;this.promptQueue=[];for(let o of n){o.cancelled=!0,o.kind==="user"&&this.broadcastQueueRemoved(o.messageId,"abandoned");let i=this.pendingTurnNotifiers.get(o.messageId);i&&(this.pendingTurnNotifiers.delete(o.messageId),po(i,{sessionId:this.sessionId,messageId:i.originalMessageId,stopReason:"cancelled",deliveredAt:Date.now(),...o.messageId!==i.originalMessageId?{amendedTo:o.messageId}:{}}));try{o.resolve({stopReason:"cancelled"})}catch{}}this.notifyChain("session.closed",{}),this.toolCompletionSeen.clear(),this.toolCallKind.clear(),this.filesEditedSeen.clear(),this.openToolCalls.clear();let r=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>_d(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(()=>qd.unlink(i).catch(()=>{}))}for(let o of this.closeHandlers)o(e)}get lastActivityAt(){return this.lastRecordedAt}setAttentionFlag(e,t,n){this._setAttentionFlag(e,t,n,!0)}_setAttentionFlag(e,t,n,r){let o=`${e}::${t}`,i=this.attentionFlags.get(o);if(i){if(JSON.stringify(i.payload)===JSON.stringify(n))return;this.attentionFlags.set(o,{...i,payload:n,raisedAt:i.raisedAt})}else this.attentionFlags.set(o,{source:e,reason:t,raisedAt:Date.now(),payload:n});r&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}clearAttentionFlag(e,t){this._clearAttentionFlag(e,t,!0)}_clearAttentionFlag(e,t,n){let r=`${e}::${t}`;this.attentionFlags.delete(r)&&n&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}listAttentionFlags(){return Array.from(this.attentionFlags.values()).sort((e,t)=>e.raisedAt-t.raisedAt)}listAttentionFlagsBySource(e){return this.listAttentionFlags().filter(t=>t.source===e)}onAttentionFlagsChange(e){this.attentionFlagsChangeHandlers.push(e)}fireAttentionFlagsChange(){let e=this.listAttentionFlags();for(let t of this.attentionFlagsChangeHandlers)try{t(e)}catch{}}broadcastAttentionUpdated(){for(let e of this.clients.values())e.connection.notify("hydra-acp/session/attention_updated",{sessionId:this.sessionId,flags:this.listAttentionFlags()}).catch(()=>{})}scheduleIdleCheck(){if(this.closed||this.idleTimeoutMs<=0)return;let e=this.lastActivityAt+this.idleTimeoutMs;this.armIdleTimer(Math.max(0,e-Date.now()))}armIdleTimer(e){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{this.idleTimer=void 0,this.checkIdle()},e),typeof this.idleTimer.unref=="function"&&this.idleTimer.unref()}checkIdle(){if(this.closed||this.idleTimeoutMs<=0)return;if(this.hasWorkInFlight){this.armIdleTimer(this.idleTimeoutMs);return}let e=Date.now()-this.lastActivityAt;if(e<this.idleTimeoutMs){this.armIdleTimer(this.idleTimeoutMs-e);return}let t=this.firstPromptSeeded?{deleteRecord:!1}:{deleteRecord:!0},n=Math.round(e/1e3);this.logger?.info(`session ${this.sessionId} idle timeout fired after ${n}s (window=${Math.round(this.idleTimeoutMs/1e3)}s) \u2014 closing`),this.close(t).catch(()=>{})}cancelIdleTimer(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=void 0),this.disposeIdleHandlers()}scheduleOrphanCheck(){this.closed||this.orphanTimeoutMs<=0||this.clients.size>0||this._interactive===!0||this.armOrphanTimer(this.orphanTimeoutMs)}armOrphanTimer(e){this.orphanTimer&&clearTimeout(this.orphanTimer),this.orphanTimer=setTimeout(()=>{this.orphanTimer=void 0,this.checkOrphan()},e),typeof this.orphanTimer.unref=="function"&&this.orphanTimer.unref()}checkOrphan(){if(!this.closed&&!(this.clients.size>0||this._interactive===!0)){if(this.hasWorkInFlight){this.armOrphanTimer(this.orphanTimeoutMs);return}this.logger?.info(`session ${this.sessionId} orphan timeout fired after ${Math.round(this.orphanTimeoutMs/1e3)}s with no attached client and no prompt ever received \u2014 closing`),this.close({deleteRecord:!1,by:"reap-orphaned"}).catch(()=>{})}}cancelOrphanTimer(){this.orphanTimer&&(clearTimeout(this.orphanTimer),this.orphanTimer=void 0)}get currentPromptDepth(){if(this.currentEntry?.kind==="user")return this.currentEntry.originator.depth??0}get hasWorkInFlight(){return this.turnStartedAt!==void 0||this.hasPermissionFlag||this.promptQueue.length>0||this.armedBackgroundTasks.length>0}onIdle(e,t){let n={fn:e,once:!!t?.once,debounceMs:t?.debounceMs??0};return this.idleHandlers.push(n),()=>{let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1),n.timer&&(clearTimeout(n.timer),n.timer=void 0)}}onceIdle(e){return this.onIdle(e,{once:!0})}dispatchIdle(){if(this.closed)return;if(!this.isQuiescedSync()){for(let n of this.idleHandlers)n.timer&&(clearTimeout(n.timer),n.timer=void 0);return}let t=[...this.idleHandlers];for(let n of t){if(n.debounceMs===0){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}continue}n.timer&&(clearTimeout(n.timer),n.timer=void 0),n.timer=setTimeout(()=>{if(n.timer=void 0,!this.closed&&this.isQuiescedSync()){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}}},n.debounceMs),typeof n.timer.unref=="function"&&n.timer.unref()}}disposeIdleHandlers(){for(let e of this.idleHandlers)e.timer&&(clearTimeout(e.timer),e.timer=void 0);this.idleHandlers.length=0}noteRecordedToolCall(e,t){if(e!=="session/update")return;let n=t?.update;if(n===void 0)return;let r=typeof n.toolCallId=="string"?n.toolCallId:"";if(r.length===0)return;let o=typeof n.title=="string"&&n.title!==""?n.title:void 0;if(n.sessionUpdate==="tool_call"){this.turnRanTool=!0,n.status!=="completed"&&n.status!=="failed"&&this.openToolCalls.set(r,{startedAt:Date.now(),...o!==void 0?{title:o}:{}});return}if(n.sessionUpdate!=="tool_call_update")return;if(n.status==="completed"||n.status==="failed"){this.openToolCalls.delete(r),this.disarmOpenToolCall(r);return}let i=this.openToolCalls.get(r);i!==void 0&&o!==void 0&&(i.title=o)}armOpenToolCalls(){let e=!1;for(let[t,n]of this.openToolCalls){if(this.armedTasks.has(t))continue;let r=this.toolLabels.get(t),o=r?.fromDescription===!0?r.label:Xg(n.title??r?.label??"").slice(0,Ao);this.armedTasks.set(t,{label:o===""?"running tool":o,repeating:!1,armedAt:n.startedAt,openToolCall:!0}),e=!0}e&&this.onArmedTasksChanged()}disarmOpenToolCall(e){this.armedTasks.get(e)?.openToolCall===!0&&(this.armedTasks.delete(e),this.onArmedTasksChanged())}closeOpenToolCalls(e){if(this.openToolCalls.size===0||this.closed)return;let t=[...this.openToolCalls.keys()];this.openToolCalls.clear();for(let n of t)this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"tool_call_update",toolCallId:n,status:"failed",_meta:{[le]:{synthetic:!0,closedBy:e}}}});this.logger?.info(`session ${this.sessionId} closed ${t.length} open tool call(s) on ${e}`)}maybeEmitToolEdges(e){if(!e||typeof e!="object")return;let t=e.update;if(!t||typeof t!="object")return;let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:"";if(r!=="tool_call"&&r!=="tool_call_update")return;let o=typeof n.toolCallId=="string"&&n.toolCallId.length>0?n.toolCallId:void 0;if(!o)return;let i=typeof n.kind=="string"?n.kind:void 0;this.toolCallKind.note(o,i);let a=this.toolCallKind.effective(o,i);if(a===Va&&Array.isArray(n.locations))for(let u of n.locations){if(!u||typeof u!="object")continue;let l=u.path;if(typeof l!="string"||l.length===0||this.filesEditedSeen.has(l))continue;this.filesEditedSeen.add(l);let w=u.line,h={path:l,toolCallId:o};typeof w=="number"&&(h.line=w),this.notifyChain("file.edited",h),this.reportIsolationBreach(l,o)}if(r!=="tool_call_update")return;let d=typeof n.status=="string"?n.status:void 0;if(d!=="completed"&&d!=="failed"||this.toolCompletionSeen.has(o))return;this.toolCompletionSeen.set(o,d);let c={toolCallId:o,status:d};a&&(c.kind=a),n.content!==void 0&&(c.content=n.content),Array.isArray(n.locations)&&(c.locations=n.locations),this.notifyChain("tool.completed",c)}notifyChain(e,t){let n=`lifecycle:${e}`;for(let r of this.transformChain)r.intercepts.has(n)&&r.connection.notify("hydra-acp/transformer/session_event",{event:e,sessionId:this.sessionId,payload:t}).catch(()=>{})}rewriteForClient(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.sessionId=="string"&&t.sessionId!==this.sessionId)return{...t,sessionId:this.sessionId}}return e}recordAndBroadcast(e,t,n){let r=this.rewriteForClient(t),o=!En(e,r),i=o?wm(e,r):r,a=Date.now(),d=o?this.lastSeq=Math.max(this.lastSeq+1,a):void 0,c=o?Be(Le(i,a),d):i;if(o){this.noteRecordedToolCall(e,i);let u={method:e,params:i,recordedAt:a,seq:d};if(this.lastRecordedAt=u.recordedAt,this.appendCount+=1,this.historyStore){let l=this.historyStore;l.append(this.sessionId,u).catch(()=>{}),this.appendCount>=this.compactEvery&&(this.appendCount=0,l.compact(this.sessionId,this.historyMaxEntries).catch(()=>{}))}for(let l of this.broadcastHandlers)try{l(u)}catch{}this.scheduleIdleCheck(),this.dispatchIdle()}this.updatedAt=Date.now();for(let u of this.clients.values())n&&u.clientId===n||u.connection.notify(e,c).catch(()=>{})}async requestPermissionFromClients(e){return this.handlePermissionRequest(e)}async handlePermissionRequest(e){let t=[...this.clients.values()];if(t.length===0)throw fe(new Error("no clients attached to handle permission request"),x.PermissionDenied);let n=this.rewriteForClient(e),r=Hd(n),o=Ve(),{toolCall:i,options:a}=n??{};return new Promise((d,c)=>{let u=!1,l=[],w=0,h,f=this.sessionId,k=y=>{u||(u=!0,this.clearAttentionFlag("daemon",`permission:${o}`),this.permissionCallbacks.delete(o),y())},p=y=>y?.code===x.MethodNotFound;function g(y){if(u)return;let m=y.connection.request("session/request_permission",n);l.push({client:y}),w++,m.then(v=>{w--,k(()=>{let S=Sm({toolCallId:r,result:v,resolver:y});for(let b of l)b.client.clientId!==y.clientId&&b.client.connection.notify("session/update",{sessionId:f,update:S}).catch(()=>{});d(v)})}).catch(v=>{if(w--,p(v)||(h=v),w===0&&!u){let S=h??fe(new Error("no client handled permission request"),x.PermissionDenied);k(()=>c(S))}})}this.setAttentionFlag("daemon",`permission:${o}`,{kind:"permission",toolCall:i??null,options:a??null}),this.permissionCallbacks.set(o,g);for(let y of t)g(y)})}async enqueuePrompt(e,t){return new Promise((n,r)=>{let o={kind:"internal",messageId:Ve(),label:e,enqueuedAt:Date.now(),cancelled:!1,task:t,resolve:n,reject:r};this.promptQueue.push(o),this.drainQueue()})}async enqueueUserPrompt(e,t,n,r,o){let i=(t??{}).prompt??[],a={clientId:e.clientId};e.clientInfo?.name&&(a.name=e.clientInfo.name),e.clientInfo?.version&&(a.version=e.clientInfo.version),r?.fromSession&&(a.fromSession=r.fromSession),r?.fromSessionTitle&&(a.fromSessionTitle=r.fromSessionTitle),r?.fromLabel&&(a.fromLabel=r.fromLabel),r?.depth!==void 0&&(a.depth=r.depth);let d=this.parseQueuePosition(t);return new Promise((c,u)=>{let l={kind:"user",messageId:n,originator:a,clientId:e.clientId,prompt:i,enqueuedAt:Date.now(),cancelled:!1,resolve:c,reject:u};o?.steerOriginated===!0&&(l.wasSteer=!0);let w=this.insertEntryAt(l,d);this.persistRewrite(),this.broadcastQueueAdded(l,{position:w}),this.drainQueue()})}promptCarriesSentBy(e){if(!e||typeof e!="object")return!1;let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t[le];if(!n||typeof n!="object"||Array.isArray(n))return!1;let r=n.sentBy;return!!r&&typeof r=="object"}parseQueuePosition(e){if(!e||typeof e!="object")return"tail";let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return"tail";let n=t["hydra-acp"];if(!n||typeof n!="object"||Array.isArray(n))return"tail";let r=n.queuePosition;if(r==="head"||r==="tail")return r;if(r&&typeof r=="object"&&!Array.isArray(r)){let o=r.afterMessageId;if(typeof o=="string"&&o.length>0)return{afterMessageId:o}}return"tail"}insertEntryAt(e,t){let n=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;if(t==="head")return this.promptQueue.unshift(e),n;if(typeof t=="object"){let r=t.afterMessageId,o=this.promptQueue.findIndex(i=>i.messageId===r);if(o>=0)return this.promptQueue.splice(o+1,0,e),n+o+1}return this.promptQueue.push(e),n+this.promptQueue.length-1}persistRewrite(){let e=[];for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push(this.persistedFromEntry(n));let t=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Tn(t,e).catch(()=>{}))}persistedFromEntry(e){return{messageId:e.messageId,originator:{clientInfo:{...e.originator.name!==void 0?{name:e.originator.name}:{},...e.originator.version!==void 0?{version:e.originator.version}:{}}},prompt:e.prompt,enqueuedAt:e.enqueuedAt}}async drainQueue(){if(!this.promptInFlight){this.promptInFlight=!0,await new Promise(e=>setImmediate(e));try{for(;this.promptQueue.length>0&&!this.closing;){let e=this.promptQueue[0];if(e?.kind==="user"&&(await this.holdForUnsolicitedTurn(e),this.closing))break;let t=this.promptQueue.shift();if(!t)break;if(!t.cancelled){this.currentEntry=t,t.kind==="user"&&this.persistRewrite(),t.kind==="user"&&this.broadcastQueueRemoved(t.messageId,"started");try{let n=await this.runQueueEntry(t);t.resolve(n),await new Promise(r=>setImmediate(r))}catch(n){t.reject(n)}finally{this.currentEntry=void 0}}}}finally{this.promptInFlight=!1,this.supersededAutonomousTurn=void 0,this.dispatchIdle()}}}async runQueueEntry(e){if(e.kind==="internal")return this.closeUnsolicitedTurn("superseded",`internal:${e.label}`),e.task();this.broadcastPromptReceived(e);let t=At(e.prompt).replace(/\s+$/,""),n=!t.includes(`
106
- `)&&t.startsWith("/")?t.split(/\s+/)[0]??"":"",r=n.startsWith("/")?n.slice(1):"",o=r.length>0&&this.aliasableBareVerbs().has(r);if(n==="/model"||n==="/mode"||n==="/sessions"||n==="/help"||n==="/hydra"||o){let d;try{if(n==="/sessions")d=await this.handleSessionsCommand();else if(n==="/help")d=await this.handleHelpCommand();else if(n==="/mode")d=await this.handleModeCommand(t);else if(n==="/model")d=await this.handleModelCommand(t);else if(o){let c=t.slice(n.length).trim(),u=c?`/hydra ${r} ${c}`:`/hydra ${r}`;d=await this.handleSlashCommand(u,e.messageId)}else d=await this.handleSlashCommand(t,e.messageId)}catch(c){throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e),Nd(c)),this.clearAmendIfMatches(e.messageId),c}return this.closed||this.broadcastTurnComplete(e.clientId,d,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),d}if(this.clearRollbackBreadcrumbHook)try{this.clearRollbackBreadcrumbHook()}catch{}let i=e.prompt;n&&this.agentAdvertisedCommands.length>0&&!this.agentKnowsSlashCommand(n)&&(i=Co(e.prompt,Cm));let a;this.agentTurnInFlight=!0;try{i=this.applyWorkspacePromptRewrite(i),a=await this.dispatchPrompt(e,i)}catch(d){if(this.forceCancelling)return this.clearAmendIfMatches(e.messageId),{stopReason:"cancelled"};throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e),Nd(d)),this.clearAmendIfMatches(e.messageId),d}finally{this.agentTurnInFlight=!1}return this.closed||this.broadcastTurnComplete(e.clientId,a,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),a}async dispatchPrompt(e,t){let n=()=>this.awaitPromptResponse(this.forwardRequest("session/prompt",{sessionId:this.sessionId,prompt:t},e.emitterName?new Set([e.emitterName]):new Set,e.chainStartIdx??0));try{return await n()}catch(r){if(this.loadExistingAgentSession&&rm(r))return this.logger?.warn(`agent ${this.agentId} no longer knows upstream session ${this.upstreamSessionId} for ${this.sessionId}; reloading it onto a fresh process and retrying the prompt once`),await this.reloadUpstreamAfterAgentLoss(),await n();if(!im(r)||this.turnRanTool||(this.logger?.warn(`agent ${this.agentId} hit a transient auth failure for ${this.sessionId}; retrying the prompt once in ${Dd}ms`),await new Promise(o=>setTimeout(o,Dd)),e.cancelled))throw r;return await n()}}clearAmendIfMatches(e){this.amendInProgress?.cancelledMessageId===e&&(this.amendInProgress=void 0)}},Fd=2e3;function Nd(s){let e=s?.message;if(!(typeof e!="string"||e.trim().length===0))return e.length>Fd?`${e.slice(0,Fd)}...`:e}var sm=["session not found","the claude agent session has ended"];function zd(s){let e=s;if(e?.code!==x.InternalError)return;let t=e.data?.details;return`${typeof e.message=="string"?e.message:""} ${typeof t=="string"?t:""}`.toLowerCase()}function rm(s){let e=zd(s);return e!==void 0&&sm.some(t=>e.includes(t))}var om=["failed to refresh oauth token"],Dd=6e4;function im(s){let e=zd(s);return e!==void 0&&om.some(t=>e.includes(t))}function fe(s,e){return s.code=e,s}var am=new Set(["session_info_update","_hydra_current_model_update","current_mode_update","available_commands_update","_hydra_available_modes_update","usage_update","config_option_update","_hydra_compaction"]);function dm(s,e,t){return t?.run_in_background===!0||t?.background===!0?!1:e?.toolName==="Monitor"||s==="Monitor"||typeof e?.toolResponse?.taskId=="string"}function cm(s){return typeof s!="string"?void 0:/Command running in background with ID: ([A-Za-z0-9_-]+)/.exec(s)?.[1]}function um(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.metadata;if(!e||typeof e!="object")return;let{status:t,shellID:n}=e;return t==="running"&&typeof n=="string"&&n!==""?n:void 0}function lm(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 En(s,e){if(s!=="session/update")return!1;let n=(e??{}).update?.sessionUpdate;return typeof n=="string"&&am.has(n)}function fm(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 pm(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 gm(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 Pn(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 Ps(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 xo(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o=typeof n.name=="string"&&n.name.trim()?n.name.trim():r,i={value:r,name:o};typeof n.description=="string"&&n.description.length>0&&(i.description=n.description),e.push(i)}return e}function mm(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="_hydra_available_modes_update")return null;let n=t.availableModes;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.id!="string"||i.id.length===0)continue;let a={id:i.id};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function hm(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 ym(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 wm(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:Ve()}}}function km(s,e){if(s.length<=e)return s;let t=s.length-e;for(let n=t;n>=0;n--)if(s[n]?.params?.update?.sessionUpdate==="prompt_received")return s.slice(n);return s.slice(t)}function vm(s,e){for(let t=s.length-1;t>=0;t--)if(s[t]?.seq===e)return t;return-1}function bm(s,e){for(let t=s.length-1;t>=0;t--){let n=s[t];if(!n||n.method!=="session/update")continue;if(n.params?.update?.messageId===e)return t}return-1}function Hd(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 Sm(s){let e=Im(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=Am(s.resolver),t}function Im(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 Am(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 At(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var Cm="\u200B";function jd(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 Co(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 Ro(s){return s==="session/prompt"?{stopReason:"stopped"}:{}}function Rm(s){return s==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function Ud(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}
109
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}),{stopReason:"end_turn"}}if(n==="model"){if(c!==this.currentModel){let l=await this.forwardModelChange(c);this.applyAgentConfigOptionResponse(l,"model")}return this.applyModelChange(c),{stopReason:"end_turn"}}if(n==="mode")return c!==this.currentMode&&await this.forwardRequest("session/set_mode",{sessionId:this.sessionId,modeId:c}),this.applyModeChange(c),{stopReason:"end_turn"};if(n==="agent")return c!==this.agentId&&await this.runAgentCommandInline(c),{stopReason:"end_turn"};let u=await this.forwardRequest("session/set_config_option",{sessionId:this.sessionId,configId:n,value:c});return this.applyAgentConfigOptionResponse(u,n)&&this.broadcastConfigOptions(),{stopReason:"end_turn"}}runTitleCommand(e){return this.enqueuePrompt("title",()=>this.runTitleCommandInline(e))}async runTitleCommandInline(e){return e?(this.setTitle(e),{stopReason:"end_turn"}):(this.scheduleSynopsisHook?.(),{stopReason:"end_turn"})}async runInternalPrompt(e){if(this.internalPromptCapture)throw new Error("internal prompt already in flight");let t={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};this.internalPromptCapture=t;try{return await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:e}]}),t.chunks.join("")}finally{this.internalPromptCapture=void 0}}setAgent(e){return this.runAgentCommandInline(e)}async runAgentCommandInline(e){if(e==="status")return this.runAgentStatusCommandInline();let t=e;if(!t)throw fe(new Error("/hydra agent requires an agent id"),x.InvalidParams);let r=(this.resolveAgentIdHook?await this.resolveAgentIdHook(t):void 0)??t;if(r===this.agentId)throw fe(new Error(`already on agent ${r}`),x.InvalidParams);if(!this.scheduleCompactionHook)return this.emitExtensionReply("agent switching not configured for this session"),{stopReason:"end_turn"};this.scheduleCompactionHook({targetAgentId:r});let o=this.agentTurnInFlight||this.unsolicitedTurn!==void 0;return this.emitExtensionReply(o?`Agent switch to ${r} scheduled. A turn is still in flight \u2014 the rotation lands on the next idle edge; cancel the turn to make that happen now.`:`Agent switch to ${r} scheduled. The session will rotate to ${r} once synthesis completes.`),{stopReason:"end_turn"}}async runAgentStatusCommandInline(){let e=await this.getPendingAgentSwapHook?.();return e?(this.emitExtensionReply(`Agent switch to ${e} pending \u2014 will rotate on the next idle edge.`),{stopReason:"end_turn"}):(this.emitExtensionReply("No agent switch pending."),{stopReason:"end_turn"})}async runKillCommand(){return await this.close({deleteRecord:!1,by:"/hydra kill"}),{stopReason:"end_turn"}}runRestartCommand(){return this.enqueuePrompt("restart",()=>this.runRestartCommandInline())}async runRestartCommandInline(){if(!this.spawnReplacementAgent)throw fe(new Error("agent restart not configured for this session"),x.InternalError);return await this.respawnAgent(),{stopReason:"end_turn"}}runCompactCommand(e){return this.enqueuePrompt("compact",()=>this.runCompactCommandInline(e))}async runCompactCommandInline(e){return e==="status"?this.runCompactStatusCommandInline():this.scheduleCompactionHook?(this.scheduleCompactionHook(),this.emitExtensionReply("Compaction scheduled. The session will rotate to a fresh upstream once summarization completes."),{stopReason:"end_turn"}):(this.emitExtensionReply("compaction scheduling not configured for this session"),{stopReason:"end_turn"})}async runCompactStatusCommandInline(){let e=await this.getCompactionStateHook?.(),t=this._summarizedThroughEntry,n=await this.getUpstreamGenerationsHook?.()??[],r=zd(n,t),o=Jd(r);if(e==null&&t==null&&o.length===0)return this.emitExtensionReply("This session has never been compacted."),{stopReason:"end_turn"};let i=[];return e==null?i.push(`No compaction in progress. Last summarized through entry: ${t??0}`):(i.push(`Compaction state: ${e.status}${e.iter!=null?` (iteration ${e.iter})`:""}`,`Summarized through entry: ${t??0}`,`Pending attempts: ${e.attempts??0}`),e.lastError!==void 0&&i.push(`Last error: ${e.lastError}`)),i.push(`Current upstream: ${this.upstreamSessionId}`),o.length>0&&i.push("",...o),this.emitExtensionReply(i.join(`
110
+ `)),{stopReason:"end_turn"}}runUncompactCommand(){return this.enqueuePrompt("uncompact",()=>this.runUncompactCommandInline())}async runWorkspaceCommand(e){if(!this.workspaceHook)return this.emitExtensionReply("Workspaces are not available on this session (no workspace hook configured)."),{stopReason:"end_turn"};let[t="status",...n]=e.split(/\s+/).filter(d=>d.length>0);if(!Zd.includes(t))return this.emitExtensionReply(`Unknown workspace verb "${t}". Use one of: ${Zd.join(", ")}.`),{stopReason:"end_turn"};let r=n.filter(d=>d.startsWith("--")),o=r.filter(d=>d!=="--clean"&&d!=="--deep");if(o.length>0)return this.emitExtensionReply(`Unknown workspace flag(s) ${o.join(", ")}. Supported: --clean (start), --deep (clean).`),{stopReason:"end_turn"};let i={clean:r.includes("--clean"),deep:r.includes("--deep")};if(i.clean&&t!=="start")return this.emitExtensionReply(`--clean applies to \`start\`, not to \`${t}\`.`),{stopReason:"end_turn"};if(i.deep&&t!=="clean")return this.emitExtensionReply(`--deep applies to \`clean\`, not to \`${t}\`.`),{stopReason:"end_turn"};let a=n.filter(d=>!d.startsWith("--")).join(" ").trim();try{let d=await this.workspaceHook(t,a.length>0?a:void 0,i);this.emitExtensionReply(d)}catch(d){this.emitExtensionReply(`Workspace ${t} failed: ${d instanceof Error?d.message:String(d)}`)}return{stopReason:"end_turn"}}async runUncompactCommandInline(){if(!this.uncompactHook)return this.emitExtensionReply("Rollback not available: uncompact hook not configured for this session."),{stopReason:"end_turn"};try{await this.uncompactHook(),this.emitExtensionReply("Rolled back to pre-compaction upstream. The session is now using the previous agent context.")}catch(e){this.emitExtensionReply(`Rollback failed: ${e instanceof Error?e.message:String(e)}`)}return{stopReason:"end_turn"}}runForkCommand(e){return this.enqueuePrompt("fork",()=>this.runForkCommandInline(e,void 0))}async findMessageIdBefore(e){if(!this.historyStore)return;let t=await this.historyStore.load(this.sessionId),n;for(let r of t){if(r.method!=="session/update")continue;let i=r.params?.update?.messageId;if(typeof i=="string"){if(i===e)return n;n=i}}}async runForkCommandInline(e,t){if(!this.forkHook)return this.emitExtensionReply("Fork not configured for this session."),{stopReason:"end_turn"};let n=(e??"").trim(),r=n.match(/^--verbatim(?:\s+([\s\S]*))?$/),o=r?"verbatim":void 0,i=(r?r[1]??"":n).trim();try{let a={};if(o&&(a.mode=o),i!==""&&(a.prompt=i),t&&this.historyStore){let u=await this.findMessageIdBefore(t).catch(()=>{});u&&(a.forkAt=u)}let c=(await this.forkHook(Object.keys(a).length>0?a:void 0)).sessionId.replace(/^hydra_session_/,"");this.emitExtensionReply(i!==""?`Forked to [\`${c}\`](hydra://sessions/${c}) and sent the prompt.`:`Forked to [\`${c}\`](hydra://sessions/${c}).`)}catch(a){this.emitExtensionReply(`Fork failed: ${a instanceof Error?a.message:String(a)}`)}return{stopReason:"end_turn"}}escalateUnresponsiveCancel(){this.cancelReopenStreak=0,this.logger?.warn(`session ${this.sessionId} agent ${this.agentId} reopened an unsolicited turn right after cancel ${s.UNSOLICITED_REOPEN_LIMIT} times in a row; forcing a restart`),this.broadcastQueueNotification("hydra-acp/cancel_failed",{sessionId:this.sessionId,reason:"unresponsive",message:`${this.agentId} kept resuming after repeated cancels; restarting the agent`}),this.forceCancel().catch(e=>{this.logger?.warn(`session ${this.sessionId} forceCancel after unresponsive-cancel escalation failed: ${e instanceof Error?e.message:String(e)}`)})}async forceCancel(){if(this.closed||this.closing)throw fe(new Error("session is closing"),x.SessionClosing);return this.lastCancelAt=0,this.forceCancelling=!0,await this.close({deleteRecord:!1,by:"force-cancel"}),{stopReason:"cancelled"}}async rewind(e,t,n={}){let r=()=>this.promptInFlight&&!n.afterCurrentTurn||this.promptQueue.length>0?"the session is busy; wait for the current turn and queued prompts to finish, then try again":this.swapInFlight?"the session's agent is being replaced; try again in a moment":void 0,o=r()??await this.quiesceBlocker()??r();if(o!==void 0)throw fe(new Error(o),x.InvalidRequest);if(!this.spawnReplacementAgent)throw fe(new Error("agent restart not configured for this session"),x.InternalError);await this.enqueuePrompt("rewind",async()=>{this.swapInFlight=!0;try{if(!await t())return;await this.respawnAgent({rewind:!0})}finally{this.swapInFlight=!1}this.broadcastClientUpdate({sessionUpdate:"_hydra_history_truncated",keepThrough:e})})}runTagCommand(e,t){let n=t.split(/\s+/).filter(a=>a.length>0),r=this._tags??[],o=()=>{this.broadcastSyntheticText(r.length>0?`tags: ${r.map(a=>`#${a}`).join(" ")}`:"no tags")};if(n.length===0)return e?this.broadcastSyntheticText("usage: /hydra untag <tag...> | --all"):o(),Promise.resolve({stopReason:"end_turn"});if(e){let a=n.length===1&&n[0]==="--all"?null:new Set(n.map(d=>en(d)??d));this.setTags(a===null?[]:r.filter(d=>!a.has(d)))}else{let a=n.filter(c=>en(c)===void 0);if(a.length>0)return this.broadcastSyntheticText(`invalid tag: ${a.join(" ")} (use letters, digits, . _ / -)`),Promise.resolve({stopReason:"end_turn"});let d=xt([...r,...n]);if(d.length<new Set([...r,...xt(n)]).size)return this.broadcastSyntheticText(`at most ${16} tags per session`),Promise.resolve({stopReason:"end_turn"});this.setTags(d)}let i=this._tags??[];return this.broadcastSyntheticText(i.length>0?`tags: ${i.map(a=>`#${a}`).join(" ")}`:"no tags"),Promise.resolve({stopReason:"end_turn"})}runClearCommand(){if(!this.rewindHook)throw fe(new Error("clear not configured for this session"),x.InternalError);return this.rewindHook(null).catch(e=>{this.broadcastSyntheticText(`/hydra clear failed: ${e.message}`)}),Promise.resolve({stopReason:"end_turn"})}async respawnAgent(e={}){let t=this.spawnReplacementAgent,n=this.agentId,r=await this.buildSwitchTranscript(n,e.rewind?{intro:"You are continuing a conversation whose later turns were withdrawn by the user. Below is the transcript of what remains.",followup:"Each line is prefixed with its speaker. Treat this as context for the next user message; do not re-respond to earlier turns."}:void 0),o=this.currentModel,i=this.currentMode,a=await t({agentId:n,cwd:this.cwd,agentArgs:this.agentArgs,...this.forwardedEnv?{forwardedEnv:this.forwardedEnv}:{},...this.elicitationForms===!1?{elicitationForms:!1}:{}});if(this.accumulateAndResetCost(),this.wireAgent(a.agent,{respawn:!0}),e.rewind){let c=await pt({agent:a.agent,upstreamSessionId:a.upstreamSessionId,persistedModel:o,agentReportedModel:a.initialModel,logger:this.logger});this.applyAgentConfigOptionResponse(c.result,"model"),await ft({agent:a.agent,upstreamSessionId:a.upstreamSessionId,persistedMode:i,agentReportedMode:a.initialMode,logger:this.logger}),a.agent.connection.drainBuffered("session/update")}let d=this.agent;this.agent=a.agent,this.upstreamSessionId=a.upstreamSessionId,this.agentMeta=a.agentMeta,this.agentCapabilities=a.agentCapabilities,this.resetModelVerb(a.modelVerb),this.agentAdvertisedCommands=[],this.broadcastMergedCommands(),e.rewind||(this.currentModel=a.initialModel,this.currentMode=a.initialMode),this.setAgentAdvertisedModels(a.initialModels??[]),this.setAgentAdvertisedModes(a.initialModes??[]),this.agentAdvertisedConfigOptions=a.initialConfigOptions??[],await this.retireAgent(d,"agent restart"),r&&await this.runInternalPrompt(r).catch(()=>{}),e.rewind||this.broadcastAgentSwitch(n,n),this.notifyAgentChange("respawnAgent","restart")}async buildSwitchTranscript(e,t){let n=[],r=await this.getHistorySnapshot();for(let c of r){if(c.method!=="session/update")continue;let l=(c.params??{}).update;if(!l||l._meta?.["hydra-acp"]?.synthetic)continue;let h=l.sessionUpdate;if(h==="prompt_received"){let f=ht(l.prompt);f&&n.push({speaker:"user",text:f})}else if(h==="agent_message_chunk"){let k=l.content?.text;k&&n.push({speaker:`agent: ${e}`,text:k})}else if(h==="tool_call"||h==="tool_call_update"){let f=l.status,k=l.title;(f==="completed"||f==="failed")&&n.push({speaker:"tool",text:`${k??"?"} ${f}`})}}if(n.length===0)return"";let o=[],i;for(let c of n)i&&i.speaker===c.speaker?i.text+=c.text:(i&&o.push(`<${i.speaker}>: ${i.text.trim()}`),i={speaker:c.speaker,text:c.text});i&&o.push(`<${i.speaker}>: ${i.text.trim()}`);let a=t?.intro??`You are taking over this conversation from ${e}. Below is the transcript so far.`,d=t?.followup??`Each line is prefixed with its speaker. Continue from where ${e} left off, responding to the user's most recent message.`;return[a,d,"","--- begin transcript ---",...o,"--- end transcript ---"].join(`
111
+ `)}async seedFromImport(){await this.enqueuePrompt("seed:import",async()=>{let e=await this.buildSwitchTranscript(this.agentId,{intro:"You are continuing a conversation that was imported from another hydra. Below is the transcript so far.",followup:"Each line is prefixed with its speaker. Treat this as context for the next user message; do not re-respond to earlier turns."});e&&await this.runInternalPrompt(e).catch(()=>{})})}async seedFromFork(e){await this.enqueuePrompt("seed:fork",async()=>{let t=this.title??"(untitled)",n=[];if(this.historyStore)try{n=await this.historyStore.load(this.sessionId)}catch(o){this.logger?.warn(`seedFromFork: historyStore.load failed: ${o.message}`)}let r=Fo({synopsis:e,title:t,tail:n,tailK:hm,tailFloor:ym,watermark:this._summarizedThroughEntry,recallArmed:(this._summarizedThroughEntry??0)>0});if(this.internalPromptCapture)throw new Error("seedFromFork: internal prompt already in flight");this.internalPromptCapture={chunks:[],toolCalls:0,thinkingChars:0,messageChars:0};try{await this.agent.connection.request("session/prompt",{sessionId:this.upstreamSessionId,prompt:[{type:"text",text:r}]});let o=this.internalPromptCapture;this.logger?.info(`seedFromFork: seed processed sessionId=${this.sessionId} seedChars=${r.length} toolCalls=${o.toolCalls} thinkingChars=${o.thinkingChars} messageChars=${o.messageChars}`)}finally{this.internalPromptCapture=void 0}})}broadcastAgentSwitch(e,t){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,agentId:t,pendingAgentSwap:null}}}}),this.broadcastConfigOptions()}broadcastPendingAgentSwap(e){this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"session_info_update",_meta:{"hydra-acp":{synthetic:!0,pendingAgentSwap:e}}}})}hasStreamBuffer(){return this.streamBuffer!==void 0}get streamPath(){return this.streamFilePath}openStream(e){if(this.streamBuffer!==void 0)throw new Error(`stream buffer already open for session ${this.sessionId}`);let n=(e.mode??"memory")==="file"&&e.filePathFor!==void 0?e.filePathFor(this.sessionId):void 0,r={};e.capacityBytes!==void 0&&(r.capacityBytes=e.capacityBytes),n!==void 0&&(r.filePath=n),e.fileCapBytes!==void 0&&(r.fileCapBytes=e.fileCapBytes),r.onFileCapReached=()=>{this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"_hydra_stream_truncated",...n!==void 0?{filePath:n}:{},fileCapBytes:e.fileCapBytes}})};let o=new Ms(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??Gt,Gt)),i=r.read(e,o);if(i.bytes.length===0&&i.eof!==!0&&n!==void 0&&n>0){let d=await r.waitForData(i.nextCursor,n);(d==="data"||d==="eof")&&(i=r.read(i.nextCursor,o))}let a={bytes:i.bytes.toString("base64"),nextCursor:i.nextCursor};return i.gap!==void 0&&(a.gap=i.gap),i.eof===!0&&(a.eof=!0),a}streamTail(e){let n=this.requireStreamBuffer().tail(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}streamHead(e){let n=this.requireStreamBuffer().head(e);return{bytes:n.bytes.toString("base64"),startCursor:n.startCursor,endCursor:n.endCursor,truncated:n.truncated}}async streamWaitFor(e,t){return this.requireStreamBuffer().waitForData(e,t)}streamGrep(e){return this.requireStreamBuffer().grep(e)}streamInfo(){let e=this.requireStreamBuffer();return{writeCursor:e.writeCursorPos,oldestAvailable:e.oldestAvailable,capacity:e.capacity,closed:e.isClosed}}requireStreamBuffer(){if(this.streamBuffer===void 0){let e=new Error(`session ${this.sessionId} has no stream buffer; POST /v1/sessions/:id/stdin/open first`);throw e.code=x.StreamNotEnabled,e}return this.streamBuffer}markClosed(e){if(this.cancelPendingAgentRequests(),this.closed)return;this.closeUnsolicitedTurn("closed"),e={deleteRecord:e.deleteRecord||this.deleteRecordIntent},this.closing=!0,this.closed=!0,this.cancelIdleTimer(),this.cancelOrphanTimer(),this.extensionCommandsUnsub&&(this.extensionCommandsUnsub(),this.extensionCommandsUnsub=void 0);for(let o of[...this.inFlightExtensionDispatches.keys()])this.cancelExtensionDispatch(o,"abandoned");this.currentEntry?.kind==="user"&&!this.recentlyTerminal.has(this.currentEntry.messageId)&&this.broadcastTurnComplete(this.currentEntry.clientId,{stopReason:"interrupted"},this.currentEntry.messageId,this.originatorNeedsTurnComplete(this.currentEntry)),this.currentEntry=void 0;let n=this.promptQueue;this.promptQueue=[];for(let o of n){o.cancelled=!0,o.kind==="user"&&this.broadcastQueueRemoved(o.messageId,"abandoned");let i=this.pendingTurnNotifiers.get(o.messageId);i&&(this.pendingTurnNotifiers.delete(o.messageId),Ao(i,{sessionId:this.sessionId,messageId:i.originalMessageId,stopReason:"cancelled",deliveredAt:Date.now(),...o.messageId!==i.originalMessageId?{amendedTo:o.messageId}:{}}));try{o.resolve({stopReason:"cancelled"})}catch{}}this.notifyChain("session.closed",{}),this.toolCompletionSeen.clear(),this.toolCallKind.clear(),this.filesEditedSeen.clear(),this.openToolCalls.clear();let r=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Yd(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(()=>uc.unlink(i).catch(()=>{}))}for(let o of this.closeHandlers)o(e)}get lastActivityAt(){return this.lastRecordedAt}setAttentionFlag(e,t,n){this._setAttentionFlag(e,t,n,!0)}_setAttentionFlag(e,t,n,r){let o=`${e}::${t}`,i=this.attentionFlags.get(o);if(i){if(JSON.stringify(i.payload)===JSON.stringify(n))return;this.attentionFlags.set(o,{...i,payload:n,raisedAt:i.raisedAt})}else this.attentionFlags.set(o,{source:e,reason:t,raisedAt:Date.now(),payload:n});r&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}clearAttentionFlag(e,t){this._clearAttentionFlag(e,t,!0)}_clearAttentionFlag(e,t,n){let r=`${e}::${t}`;this.attentionFlags.delete(r)&&n&&(this.broadcastAttentionUpdated(),this.fireAttentionFlagsChange())}listAttentionFlags(){return Array.from(this.attentionFlags.values()).sort((e,t)=>e.raisedAt-t.raisedAt)}listAttentionFlagsBySource(e){return this.listAttentionFlags().filter(t=>t.source===e)}onAttentionFlagsChange(e){this.attentionFlagsChangeHandlers.push(e)}fireAttentionFlagsChange(){let e=this.listAttentionFlags();for(let t of this.attentionFlagsChangeHandlers)try{t(e)}catch{}}broadcastAttentionUpdated(){for(let e of this.clients.values())e.connection.notify("hydra-acp/session/attention_updated",{sessionId:this.sessionId,flags:this.listAttentionFlags()}).catch(()=>{})}scheduleIdleCheck(){if(this.closed||this.idleTimeoutMs<=0)return;let e=this.lastActivityAt+this.idleTimeoutMs;this.armIdleTimer(Math.max(0,e-Date.now()))}armIdleTimer(e){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{this.idleTimer=void 0,this.checkIdle()},e),typeof this.idleTimer.unref=="function"&&this.idleTimer.unref()}checkIdle(){if(this.closed||this.idleTimeoutMs<=0)return;if(this.hasWorkInFlight){this.armIdleTimer(this.idleTimeoutMs);return}let e=Date.now()-this.lastActivityAt;if(e<this.idleTimeoutMs){this.armIdleTimer(this.idleTimeoutMs-e);return}let t=this.firstPromptSeeded?{deleteRecord:!1}:{deleteRecord:!0},n=Math.round(e/1e3);this.logger?.info(`session ${this.sessionId} idle timeout fired after ${n}s (window=${Math.round(this.idleTimeoutMs/1e3)}s) \u2014 closing`),this.close(t).catch(()=>{})}cancelIdleTimer(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=void 0),this.disposeIdleHandlers()}scheduleOrphanCheck(){this.closed||this.orphanTimeoutMs<=0||this.clients.size>0||this._interactive===!0||this.armOrphanTimer(this.orphanTimeoutMs)}armOrphanTimer(e){this.orphanTimer&&clearTimeout(this.orphanTimer),this.orphanTimer=setTimeout(()=>{this.orphanTimer=void 0,this.checkOrphan()},e),typeof this.orphanTimer.unref=="function"&&this.orphanTimer.unref()}checkOrphan(){if(!this.closed&&!(this.clients.size>0||this._interactive===!0)){if(this.hasWorkInFlight){this.armOrphanTimer(this.orphanTimeoutMs);return}this.logger?.info(`session ${this.sessionId} orphan timeout fired after ${Math.round(this.orphanTimeoutMs/1e3)}s with no attached client and no prompt ever received \u2014 closing`),this.close({deleteRecord:!1,by:"reap-orphaned"}).catch(()=>{})}}cancelOrphanTimer(){this.orphanTimer&&(clearTimeout(this.orphanTimer),this.orphanTimer=void 0)}get currentPromptDepth(){if(this.currentEntry?.kind==="user")return this.currentEntry.originator.depth??0}get hasWorkInFlight(){return this.turnStartedAt!==void 0||this.hasPermissionFlag||this.promptQueue.length>0||this.armedBackgroundTasks.length>0}onIdle(e,t){let n={fn:e,once:!!t?.once,debounceMs:t?.debounceMs??0};return this.idleHandlers.push(n),()=>{let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1),n.timer&&(clearTimeout(n.timer),n.timer=void 0)}}onceIdle(e){return this.onIdle(e,{once:!0})}dispatchIdle(){if(this.closed)return;if(!this.isQuiescedSync()){for(let n of this.idleHandlers)n.timer&&(clearTimeout(n.timer),n.timer=void 0);return}let t=[...this.idleHandlers];for(let n of t){if(n.debounceMs===0){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}continue}n.timer&&(clearTimeout(n.timer),n.timer=void 0),n.timer=setTimeout(()=>{if(n.timer=void 0,!this.closed&&this.isQuiescedSync()){if(n.once){let r=this.idleHandlers.indexOf(n);r>=0&&this.idleHandlers.splice(r,1)}try{n.fn(this)}catch{}}},n.debounceMs),typeof n.timer.unref=="function"&&n.timer.unref()}}disposeIdleHandlers(){for(let e of this.idleHandlers)e.timer&&(clearTimeout(e.timer),e.timer=void 0);this.idleHandlers.length=0}noteRecordedToolCall(e,t){if(e!=="session/update")return;let n=t?.update;if(n===void 0)return;let r=typeof n.toolCallId=="string"?n.toolCallId:"";if(r.length===0)return;let o=typeof n.title=="string"&&n.title!==""?n.title:void 0;if(n.sessionUpdate==="tool_call"){this.turnRanTool=!0,n.status!=="completed"&&n.status!=="failed"&&this.openToolCalls.set(r,{startedAt:Date.now(),...o!==void 0?{title:o}:{}});return}if(n.sessionUpdate!=="tool_call_update")return;if(n.status==="completed"||n.status==="failed"){this.openToolCalls.delete(r),this.disarmOpenToolCall(r);return}let i=this.openToolCalls.get(r);i!==void 0&&o!==void 0&&(i.title=o)}armOpenToolCalls(){let e=!1;for(let[t,n]of this.openToolCalls){if(this.armedTasks.has(t))continue;let r=this.toolLabels.get(t),o=r?.fromDescription===!0?r.label:Cm(n.title??r?.label??"").slice(0,Lo);this.armedTasks.set(t,{label:o===""?"running tool":o,repeating:!1,armedAt:n.startedAt,openToolCall:!0}),e=!0}e&&this.onArmedTasksChanged()}disarmOpenToolCall(e){this.armedTasks.get(e)?.openToolCall===!0&&(this.armedTasks.delete(e),this.onArmedTasksChanged())}closeOpenToolCalls(e){if(this.openToolCalls.size===0||this.closed)return;let t=[...this.openToolCalls.keys()];this.openToolCalls.clear();for(let n of t)this.recordAndBroadcast("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"tool_call_update",toolCallId:n,status:"failed",_meta:{[le]:{synthetic:!0,closedBy:e}}}});this.logger?.info(`session ${this.sessionId} closed ${t.length} open tool call(s) on ${e}`)}maybeEmitToolEdges(e){if(!e||typeof e!="object")return;let t=e.update;if(!t||typeof t!="object")return;let n=t,r=typeof n.sessionUpdate=="string"?n.sessionUpdate:"";if(r!=="tool_call"&&r!=="tool_call_update")return;let o=typeof n.toolCallId=="string"&&n.toolCallId.length>0?n.toolCallId:void 0;if(!o)return;let i=typeof n.kind=="string"?n.kind:void 0;this.toolCallKind.note(o,i);let a=this.toolCallKind.effective(o,i);if(a===cd&&Array.isArray(n.locations))for(let u of n.locations){if(!u||typeof u!="object")continue;let l=u.path;if(typeof l!="string"||l.length===0||this.filesEditedSeen.has(l))continue;this.filesEditedSeen.add(l);let y=u.line,h={path:l,toolCallId:o};typeof y=="number"&&(h.line=y),this.notifyChain("file.edited",h),this.reportIsolationBreach(l,o)}if(r!=="tool_call_update")return;let d=typeof n.status=="string"?n.status:void 0;if(d!=="completed"&&d!=="failed"||this.toolCompletionSeen.has(o))return;this.toolCompletionSeen.set(o,d);let c={toolCallId:o,status:d};a&&(c.kind=a),n.content!==void 0&&(c.content=n.content),Array.isArray(n.locations)&&(c.locations=n.locations),this.notifyChain("tool.completed",c)}notifyChain(e,t){let n=`lifecycle:${e}`;for(let r of this.transformChain)r.intercepts.has(n)&&r.connection.notify("hydra-acp/transformer/session_event",{event:e,sessionId:this.sessionId,payload:t}).catch(()=>{})}rewriteForClient(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;if(typeof t.sessionId=="string"&&t.sessionId!==this.sessionId)return{...t,sessionId:this.sessionId}}return e}recordAndBroadcast(e,t,n){let r=this.rewriteForClient(t),o=!On(e,r),i=o?zm(e,r):r,a=Date.now(),d=o?this.lastSeq=Math.max(this.lastSeq+1,a):void 0,c=o?We(Be(i,a),d):i;if(o){this.noteRecordedToolCall(e,i);let u={method:e,params:i,recordedAt:a,seq:d};if(this.lastRecordedAt=u.recordedAt,this.appendCount+=1,this.historyStore){let l=this.historyStore;l.append(this.sessionId,u).catch(()=>{}),this.appendCount>=this.compactEvery&&(this.appendCount=0,l.compact(this.sessionId,this.historyMaxEntries).catch(()=>{}))}for(let l of this.broadcastHandlers)try{l(u)}catch{}this.scheduleIdleCheck(),this.dispatchIdle()}this.updatedAt=Date.now();for(let u of this.clients.values())n&&u.clientId===n||u.connection.notify(e,c).catch(()=>{})}async requestPermissionFromClients(e){return this.handlePermissionRequest(e)}async handlePermissionRequest(e,t={}){let n=[...this.clients.values()];if(n.length===0)throw fe(new Error("no clients attached to handle permission request"),x.PermissionDenied);let r=this.rewriteForClient(e),o=rc(r),i=Oe(),{toolCall:a,options:d}=r??{};return new Promise((c,u)=>{let l=!1,y=[],h=0,f,k=!1,g=this.sessionId,p=v=>{l||(l=!0,this.clearAttentionFlag("daemon",`permission:${i}`),this.permissionCallbacks.delete(i),this.permissionCancellers.delete(i),v())},w=v=>v?.code===x.MethodNotFound;function m(v){if(l)return;let S=v.connection.request("session/request_permission",r);y.push({client:v}),h++,k=!1,S.then(b=>{h--,p(()=>{let I=Km({toolCallId:o,result:b,resolver:v});for(let A of y)A.client.clientId!==v.clientId&&A.client.connection.notify("session/update",{sessionId:g,update:I}).catch(()=>{});c(b)})}).catch(b=>{if(h--,v.connection.isClosed()){k=!0;return}if(w(b)||(f=b),h===0&&!l&&!k){let I=f??fe(new Error("no client handled permission request"),x.PermissionDenied);p(()=>u(I))}})}this.setAttentionFlag("daemon",`permission:${i}`,{kind:"permission",toolCall:a??null,options:d??null}),this.permissionCallbacks.set(i,m),t.fromAgent===!0&&this.permissionCancellers.set(i,()=>{p(()=>{let v={sessionUpdate:"permission_resolved",...o!==void 0?{toolCallId:o}:{},outcome:{kind:"cancelled"}};for(let S of y)S.client.connection.notify("session/update",{sessionId:g,update:v}).catch(()=>{});c({outcome:{outcome:"cancelled"}})})});for(let v of n)m(v)})}async handleElicitationRequest(e){let t=[...this.clients.values()];if(t.length===0)return{action:"cancel"};let n=t.filter(tn);if(n.length===0)return this.recordElicitationText(`${Os(e)}
112
+ _No attached client can show a form, so this was not answered. Reply here to answer._`),{action:"cancel"};let r=Oe(),o=this.rewriteForClient(e)??{},i=o._meta??{},a=i["hydra-acp"]??{},d={...o,_meta:{...i,"hydra-acp":{...a,elicitationId:r}}},c=this.sessionId,u=Fs.create(e),l=()=>u!==null?u.prompt():Os(e);this.elicitationQuestions.set(r,l);for(let y of t)tn(y)||this.sendElicitationQuestionText(y,l());return new Promise(y=>{let h=!1,f=0,k=!1,g=[],p=v=>{h||(h=!0,this.clearAttentionFlag("daemon",`elicitation:${r}`),this.elicitationCallbacks.delete(r),this.elicitationCancellers.delete(r),this.elicitationQuestions.delete(r),this.elicitationAnswerers.delete(r),v())},w=(v,S)=>{p(()=>{let b={sessionUpdate:"elicitation_resolved",elicitationId:r,action:S.action,resolvedBy:fc(v)};for(let I of g)I.clientId!==v.clientId&&I.connection.notify("session/update",{sessionId:c,update:b}).catch(()=>{});this.recordElicitationText(Mn(e,S,v.clientInfo?.name)),y(S)})},m=v=>{h||!tn(v)||(g.push(v),f++,k=!1,v.connection.request("elicitation/create",d).then(S=>{if(f--,typeof S?.action!="string"){f===0&&p(()=>{this.recordElicitationText(Mn(e,{action:"cancel"},void 0)),y({action:"cancel"})});return}w(v,S)}).catch(()=>{if(f--,v.connection.isClosed()){k=!0;return}f===0&&!k&&p(()=>{this.recordElicitationText(Mn(e,{action:"cancel"},void 0)),y({action:"cancel"})})}))};this.setAttentionFlag("daemon",`elicitation:${r}`,{kind:"elicitation",message:o.message??null}),this.elicitationCallbacks.set(r,m),u!==null&&this.elicitationAnswerers.set(r,(v,S)=>{if(h)return!1;let b=u.reply(S);if(b.type==="done")return w(v,b.response),!0;if(b.type==="retry")return this.sendElicitationQuestionText(v,b.message),!0;for(let I of this.clients.values())!tn(I)&&I.readonly!==!0&&this.sendElicitationQuestionText(I,b.prompt);return!0}),this.elicitationCancellers.set(r,()=>{p(()=>{let v={sessionUpdate:"elicitation_resolved",elicitationId:r,action:"cancel"};for(let S of g)S.connection.notify("session/update",{sessionId:c,update:v}).catch(()=>{});this.recordElicitationText(Mn(e,{action:"cancel"},void 0)),y({action:"cancel"})})});for(let v of n)m(v)})}tryAnswerElicitationFromPrompt(e,t,n){if(this.elicitationAnswerers.size===0||tn(e)||e.readonly===!0||n?.fromSession!==void 0)return!1;let r=ht(t?.prompt).trim();if(r.length===0||r.startsWith("/"))return!1;for(let o of[...this.elicitationAnswerers.values()])if(o(e,r))return!0;return!1}sendElicitationQuestionText(e,t){e.connection.notify("session/update",{sessionId:this.sessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
113
+ ${t}
114
+ `},_meta:{"hydra-acp":{synthetic:!0}}}}).catch(()=>{})}recordElicitationText(e){this.recordAndBroadcast("session/update",{sessionId:this.upstreamSessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`
115
+ ${e}
116
+ `},_meta:{"hydra-acp":{synthetic:!0}}}})}async enqueuePrompt(e,t){return new Promise((n,r)=>{let o={kind:"internal",messageId:Oe(),label:e,enqueuedAt:Date.now(),cancelled:!1,task:t,resolve:n,reject:r};this.promptQueue.push(o),this.drainQueue()})}async enqueueUserPrompt(e,t,n,r,o){let i=(t??{}).prompt??[],a={clientId:e.clientId};e.clientInfo?.name&&(a.name=e.clientInfo.name),e.clientInfo?.version&&(a.version=e.clientInfo.version),r?.fromSession&&(a.fromSession=r.fromSession),r?.fromSessionTitle&&(a.fromSessionTitle=r.fromSessionTitle),r?.fromLabel&&(a.fromLabel=r.fromLabel),r?.depth!==void 0&&(a.depth=r.depth);let d=this.parseQueuePosition(t);return new Promise((c,u)=>{let l={kind:"user",messageId:n,originator:a,clientId:e.clientId,prompt:i,enqueuedAt:Date.now(),cancelled:!1,resolve:c,reject:u};o?.steerOriginated===!0&&(l.wasSteer=!0);let y=this.insertEntryAt(l,d);this.persistRewrite(),this.broadcastQueueAdded(l,{position:y}),this.drainQueue()})}promptCarriesSentBy(e){if(!e||typeof e!="object")return!1;let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return!1;let n=t[le];if(!n||typeof n!="object"||Array.isArray(n))return!1;let r=n.sentBy;return!!r&&typeof r=="object"}parseQueuePosition(e){if(!e||typeof e!="object")return"tail";let t=e._meta;if(!t||typeof t!="object"||Array.isArray(t))return"tail";let n=t["hydra-acp"];if(!n||typeof n!="object"||Array.isArray(n))return"tail";let r=n.queuePosition;if(r==="head"||r==="tail")return r;if(r&&typeof r=="object"&&!Array.isArray(r)){let o=r.afterMessageId;if(typeof o=="string"&&o.length>0)return{afterMessageId:o}}return"tail"}insertEntryAt(e,t){let n=this.currentEntry?.kind==="user"&&!this.currentEntry.cancelled?1:0;if(t==="head")return this.promptQueue.unshift(e),n;if(typeof t=="object"){let r=t.afterMessageId,o=this.promptQueue.findIndex(i=>i.messageId===r);if(o>=0)return this.promptQueue.splice(o+1,0,e),n+o+1}return this.promptQueue.push(e),n+this.promptQueue.length-1}persistRewrite(){let e=[];for(let n of this.promptQueue)n.kind!=="user"||n.cancelled||e.push(this.persistedFromEntry(n));let t=this.sessionId;this.queueWriteChain=this.queueWriteChain.catch(()=>{}).then(()=>Fn(t,e).catch(()=>{}))}persistedFromEntry(e){return{messageId:e.messageId,originator:{clientInfo:{...e.originator.name!==void 0?{name:e.originator.name}:{},...e.originator.version!==void 0?{version:e.originator.version}:{}}},prompt:e.prompt,enqueuedAt:e.enqueuedAt}}async drainQueue(){if(!this.promptInFlight){this.promptInFlight=!0,await new Promise(e=>setImmediate(e));try{for(;this.promptQueue.length>0&&!this.closing;){let e=this.promptQueue[0];if(e?.kind==="user"&&(await this.holdForUnsolicitedTurn(e),this.closing))break;let t=this.promptQueue.shift();if(!t)break;if(!t.cancelled){this.currentEntry=t,t.kind==="user"&&this.persistRewrite(),t.kind==="user"&&this.broadcastQueueRemoved(t.messageId,"started");try{let n=await this.runQueueEntry(t);t.resolve(n),await new Promise(r=>setImmediate(r))}catch(n){t.reject(n)}finally{this.currentEntry=void 0}}}}finally{this.promptInFlight=!1,this.supersededAutonomousTurn=void 0,this.dispatchIdle()}}}async runQueueEntry(e){if(e.kind==="internal")return this.closeUnsolicitedTurn("superseded",`internal:${e.label}`),e.task();this.broadcastPromptReceived(e);let t=ht(e.prompt).replace(/\s+$/,""),n=!t.includes(`
117
+ `)&&t.startsWith("/")?t.split(/\s+/)[0]??"":"",r=n.startsWith("/")?n.slice(1):"",o=r.length>0&&this.aliasableBareVerbs().has(r);if(n==="/model"||n==="/mode"||n==="/sessions"||n==="/help"||n==="/hydra"||o){let d;try{if(n==="/sessions")d=await this.handleSessionsCommand();else if(n==="/help")d=await this.handleHelpCommand();else if(n==="/mode")d=await this.handleModeCommand(t);else if(n==="/model")d=await this.handleModelCommand(t);else if(o){let c=t.slice(n.length).trim(),u=c?`/hydra ${r} ${c}`:`/hydra ${r}`;d=await this.handleSlashCommand(u,e.messageId)}else d=await this.handleSlashCommand(t,e.messageId)}catch(c){throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e),nc(c)),this.clearAmendIfMatches(e.messageId),c}return this.closed||this.broadcastTurnComplete(e.clientId,d,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),d}if(this.clearRollbackBreadcrumbHook)try{this.clearRollbackBreadcrumbHook()}catch{}let i=e.prompt;n&&this.agentAdvertisedCommands.length>0&&!this.agentKnowsSlashCommand(n)&&(i=Ho(e.prompt,Ym));let a;this.agentTurnInFlight=!0;try{i=this.applyWorkspacePromptRewrite(i),a=await this.dispatchPrompt(e,i)}catch(d){if(this.forceCancelling)return this.clearAmendIfMatches(e.messageId),{stopReason:"cancelled"};throw this.closed||this.broadcastTurnComplete(e.clientId,{stopReason:"error"},e.messageId,this.originatorNeedsTurnComplete(e),nc(d)),this.clearAmendIfMatches(e.messageId),d}finally{this.agentTurnInFlight=!1}return this.closed||this.broadcastTurnComplete(e.clientId,a,e.messageId,this.originatorNeedsTurnComplete(e)),this.clearAmendIfMatches(e.messageId),a}async dispatchPrompt(e,t){let n=()=>this.awaitPromptResponse(this.forwardRequest("session/prompt",{sessionId:this.sessionId,prompt:t},e.emitterName?new Set([e.emitterName]):new Set,e.chainStartIdx??0));try{return await n()}catch(r){if(this.loadExistingAgentSession&&Mm(r))return this.logger?.warn(`agent ${this.agentId} no longer knows upstream session ${this.upstreamSessionId} for ${this.sessionId}; reloading it onto a fresh process and retrying the prompt once`),await this.reloadUpstreamAfterAgentLoss(),await n();if(!$m(r)||this.turnRanTool||(this.logger?.warn(`agent ${this.agentId} hit a transient auth failure for ${this.sessionId}; retrying the prompt once in ${sc}ms`),await new Promise(o=>setTimeout(o,sc)),e.cancelled))throw r;return await n()}}clearAmendIfMatches(e){this.amendInProgress?.cancelledMessageId===e&&(this.amendInProgress=void 0)}},tc=2e3;function nc(s){let e=s?.message;if(!(typeof e!="string"||e.trim().length===0))return e.length>tc?`${e.slice(0,tc)}...`:e}var Pm=["session not found","the claude agent session has ended"];function lc(s){let e=s;if(e?.code!==x.InternalError)return;let t=e.data?.details;return`${typeof e.message=="string"?e.message:""} ${typeof t=="string"?t:""}`.toLowerCase()}function Mm(s){let e=lc(s);return e!==void 0&&Pm.some(t=>e.includes(t))}var _m=["failed to refresh oauth token"],sc=6e4;function $m(s){let e=lc(s);return e!==void 0&&_m.some(t=>e.includes(t))}function fe(s,e){return s.code=e,s}var Fm=new Set(["session_info_update","_hydra_current_model_update","current_mode_update","available_commands_update","_hydra_available_modes_update","usage_update","config_option_update","_hydra_compaction"]);function Om(s,e,t){return t?.run_in_background===!0||t?.background===!0?!1:e?.toolName==="Monitor"||s==="Monitor"||typeof e?.toolResponse?.taskId=="string"}function Nm(s){return typeof s!="string"?void 0:/Command running in background with ID: ([A-Za-z0-9_-]+)/.exec(s)?.[1]}function Dm(s){if(!s||typeof s!="object"||Array.isArray(s))return;let e=s.metadata;if(!e||typeof e!="object")return;let{status:t,shellID:n}=e;return t==="running"&&typeof n=="string"&&n!==""?n:void 0}function Lm(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 On(s,e){if(s!=="session/update")return!1;let n=(e??{}).update?.sessionUpdate;return typeof n=="string"&&Fm.has(n)}function Hm(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 jm(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 Um(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 Nn(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 Us(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 Uo(s){if(!Array.isArray(s))return[];let e=[];for(let t of s){if(!t||typeof t!="object"||Array.isArray(t))continue;let n=t,r=typeof n.value=="string"&&n.value.trim()||typeof n.id=="string"&&n.id.trim()||void 0;if(!r)continue;let o=typeof n.name=="string"&&n.name.trim()?n.name.trim():r,i={value:r,name:o};typeof n.description=="string"&&n.description.length>0&&(i.description=n.description),e.push(i)}return e}function Bm(s){let t=(s??{}).update??{};if(t.sessionUpdate!=="_hydra_available_modes_update")return null;let n=t.availableModes;if(!Array.isArray(n))return[];let r=[];for(let o of n){if(!o||typeof o!="object")continue;let i=o;if(typeof i.id!="string"||i.id.length===0)continue;let a={id:i.id};typeof i.name=="string"&&(a.name=i.name),typeof i.description=="string"&&(a.description=i.description),r.push(a)}return r}function Wm(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 qm(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 zm(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:Oe()}}}function Jm(s,e){if(s.length<=e)return s;let t=s.length-e;for(let n=t;n>=0;n--)if(s[n]?.params?.update?.sessionUpdate==="prompt_received")return s.slice(n);return s.slice(t)}function Vm(s,e){for(let t=s.length-1;t>=0;t--)if(s[t]?.seq===e)return t;return-1}function Gm(s,e){for(let t=s.length-1;t>=0;t--){let n=s[t];if(!n||n.method!=="session/update")continue;if(n.params?.update?.messageId===e)return t}return-1}function rc(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 Km(s){let e=Qm(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=fc(s.resolver),t}function Qm(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 tn(s){return s.elicitationForm===!0&&s.readonly!==!0}function fc(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 ht(s){return typeof s=="string"?s:Array.isArray(s)?s.map(e=>e&&typeof e=="object"&&typeof e.text=="string"?e.text:"").join(""):""}var Ym="\u200B";function oc(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 Ho(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 jo(s){return s==="session/prompt"?{stopReason:"stopped"}:{}}function Xm(s){return s==="session/request_permission"?{outcome:{outcome:"cancelled"}}:{}}function ic(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}
107
118
  ${n.join(`
108
- `)}`}function To(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}}Q();He();import*as _e from"fs/promises";import*as CS from"path";import{customAlphabet as Em}from"nanoid";import{z as M}from"zod";import{z as Xt}from"zod";var xm=Xt.object({source:Xt.string(),reason:Xt.string(),raisedAt:Xt.number(),payload:Xt.unknown()}),Jd=Xt.array(xm);import{z as X}from"zod";var Vd=X.object({status:X.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:X.number(),runId:X.string().optional(),iter:X.number().int().nonnegative().optional(),attempts:X.number().int().nonnegative().optional(),lastError:X.string().optional(),worker:X.object({upstreamSessionId:X.string(),pid:X.number().int().nonnegative()}).optional()}),Mn=X.object({goal:X.string().optional(),outcome:X.string().optional(),files_touched:X.array(X.string()).optional(),tools_used:X.array(X.string()).optional(),rejected_approaches:X.array(X.string()).optional(),open_threads:X.array(X.string()).optional(),decisions:X.array(X.string()).optional(),file_edit_intentions:X.array(X.string()).optional(),unresolved_errors:X.array(X.string()).optional(),tool_state:X.array(X.string()).optional()}),Gd=200,Eo=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
119
+ `)}`}function Bo(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}}Q();He();import*as _e from"fs/promises";import*as sI from"path";import{customAlphabet as th}from"nanoid";import{z as M}from"zod";import{z as sn}from"zod";var Zm=sn.object({source:sn.string(),reason:sn.string(),raisedAt:sn.number(),payload:sn.unknown()}),pc=sn.array(Zm);import{z as X}from"zod";var gc=X.object({status:X.enum(["requested","running","swap_pending","swap_deferred","failed"]),requestedAt:X.number(),runId:X.string().optional(),iter:X.number().int().nonnegative().optional(),attempts:X.number().int().nonnegative().optional(),lastError:X.string().optional(),worker:X.object({upstreamSessionId:X.string(),pid:X.number().int().nonnegative()}).optional()}),Dn=X.object({goal:X.string().optional(),outcome:X.string().optional(),files_touched:X.array(X.string()).optional(),tools_used:X.array(X.string()).optional(),rejected_approaches:X.array(X.string()).optional(),open_threads:X.array(X.string()).optional(),decisions:X.array(X.string()).optional(),file_edit_intentions:X.array(X.string()).optional(),unresolved_errors:X.array(X.string()).optional(),tool_state:X.array(X.string()).optional()}),mc=200,Wo=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
109
120
  {
110
121
  "title": "short summary, max 80 chars",
111
122
  "synopsis": {
@@ -115,7 +126,7 @@ ${n.join(`
115
126
  "open_threads": ["work started but not finished"]
116
127
  }
117
128
  }
118
- Use empty arrays/strings where a field doesn't apply.`;function Kd(s){let e=s.trim();if(e.length===0)return;let t=Zt(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=Zt(e.slice(o,i+1)))}if(t===void 0){let o=Yd(e);o!==void 0&&(t=Zt(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,Gd))}if(n.synopsis!==void 0&&n.synopsis!==null){let o=Mn.safeParse(n.synopsis);o.success&&Tm(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var Po=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
129
+ Use empty arrays/strings where a field doesn't apply.`;function hc(s){let e=s.trim();if(e.length===0)return;let t=rn(e);if(t===void 0){let o=e.indexOf("{"),i=e.lastIndexOf("}");o>=0&&i>o&&(t=rn(e.slice(o,i+1)))}if(t===void 0){let o=wc(e);o!==void 0&&(t=rn(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,mc))}if(n.synopsis!==void 0&&n.synopsis!==null){let o=Dn.safeParse(n.synopsis);o.success&&eh(o.data)&&(r.synopsis=o.data)}if(!(r.title===void 0&&r.synopsis===void 0))return r}var qo=`Reply with ONLY a JSON object with exactly these keys, no prose, no markdown, no code fences:
119
130
  {
120
131
  "title": "short summary, max 80 chars",
121
132
  "goal": "the user's original ask",
@@ -127,93 +138,93 @@ Use empty arrays/strings where a field doesn't apply.`;function Kd(s){let e=s.tr
127
138
  "unresolved_errors": ["errors left open at session end"],
128
139
  "tool_state": ["runtime state relevant for recall"]
129
140
  }
130
- Use empty arrays/strings where a field doesn't apply.`;function Qd(s){let e=s.trim();if(e.length===0)return;let t=Zt(e);if(t===void 0){let c=e.indexOf("{"),u=e.lastIndexOf("}");c>=0&&u>c&&(t=Zt(e.slice(c,u+1)))}if(t===void 0){let c=Yd(e);c!==void 0&&(t=Zt(c))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let c=n.title.trim();c.length>0&&(r.title=c.slice(0,Gd))}let o={},i=!1,a=["goal","outcome"];for(let c of a)if(typeof n[c]=="string"){let u=n[c].trim();u.length>0&&(o[c]=u,i=!0)}let d=["files_touched","tools_used","rejected_approaches","open_threads","decisions","file_edit_intentions","unresolved_errors","tool_state"];for(let c of d)if(Array.isArray(n[c])){let u=n[c],l=X.array(X.string()).safeParse(u);l.success&&u.length>0&&(o[c]=l.data,i=!0)}if(i&&(r.synopsis=o),!(r.title===void 0&&r.synopsis===void 0))return r}function Zt(s){try{return JSON.parse(s)}catch{return}}function Yd(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 Tm(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 Pm="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Mm=Em(Pm,16),_m="hydra_lineage_";function $n(){return`${_m}${Mm()}`}var Mo=M.object({name:M.string(),description:M.string().optional()}),_o=M.object({id:M.string(),name:M.string().optional(),description:M.string().optional()}),$m=M.object({modelId:M.string(),name:M.string().optional(),description:M.string().optional()}),$o=M.object({used:M.number().optional(),size:M.number().optional(),costAmount:M.number().optional(),costCurrency:M.string().optional(),cumulativeCost:M.number().optional()}),Oo=M.object({name:M.string(),version:M.string().optional()}),Om=M.object({path:M.string(),sourceCwd:M.string(),label:M.string(),requestedLabel:M.string().optional(),provider:M.string(),snapshot:M.string().optional(),line:M.string().optional(),vcs:M.record(M.string(),M.string()).optional(),clean:M.boolean().optional()}),Fm=M.object({previousUpstreamSessionId:M.string(),previousSummarizedThroughEntry:M.number().int().nonnegative().optional(),runId:M.string().optional()}),Nm=M.enum(["compaction","agent-swap","workspace-enter","workspace-leave","rollback","restart"]),Dm=M.object({upstreamSessionId:M.string(),agentId:M.string(),reason:Nm.optional(),runId:M.string().optional(),startedAt:M.string().optional(),endedAt:M.string().optional(),cost:M.number().nonnegative().optional(),lifetimeCostAtStart:M.number().nonnegative().optional(),usedAtStart:M.number().nonnegative().optional(),usedAtEnd:M.number().nonnegative().optional(),inferred:M.boolean().optional()}),Hm=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:Mn.optional(),compactionState:Vd.optional(),rollbackBreadcrumb:Fm.optional(),upstreamGenerations:M.array(Dm).optional(),summarizedThroughEntry:M.number().int().nonnegative().optional(),agentArgs:M.array(M.string()).optional(),currentModel:M.string().optional(),currentMode:M.string().optional(),currentUsage:$o.optional(),agentCommands:M.array(Mo).optional(),agentModes:M.array(_o).optional(),agentModels:M.array($m).optional(),configOptionValues:M.record(M.string(),M.string()).optional(),pendingHistorySync:M.boolean().optional(),pendingAgentSwap:M.string().optional(),parentSessionId:M.string().optional(),forkedFromSessionId:M.string().optional(),forkedFromMessageId:M.string().optional(),side:Ut.optional(),forkSynthesisState:M.enum(["running","failed"]).optional(),originatingClient:Oo.optional(),interactive:M.boolean().optional(),priority:M.number().int().nonnegative().optional(),lastTurnEndedAt:M.number().int().nonnegative().optional(),readAt:M.number().int().nonnegative().optional(),forwardedEnv:M.record(M.string(),M.string()).optional(),workspace:Om.optional(),attentionFlags:Jd.default([]).optional(),extensionState:M.record(M.string(),M.record(M.string(),M.unknown())).default({}).optional(),createdAt:M.string(),updatedAt:M.string()}),_n=/^[A-Za-z0-9_-]+$/;function jm(s){if(!_n.test(s))throw new Error(`unsafe session id: ${s}`)}var Ms=class{index;indexSeed;async write(e){jm(e.sessionId);let t={version:1,...e};await me(E.sessionFile(e.sessionId),t,{mode:384}),await this.reindex(e.sessionId)}async touch(e){if(!_n.test(e))return;let t=new Date;try{await _e.utimes(E.sessionFile(e),t,t)}catch(n){if(n.code!=="ENOENT")throw n;return}await this.reindex(e)}async markDeleted(e,t){await this.ensureIndex();let n=this.index.get(e);n&&!n.deleted||n&&n.mtimeMs>=t||this.index.set(e,{mtimeMs:t,deleted:!0})}async cursor(){await this.ensureIndex();let e=0;for(let t of this.index.values())t.mtimeMs>e&&(e=t.mtimeMs);return e}async listChangedSince(e){let t=await this.cursor(),n=[],r=[];for(let[a,d]of this.index)d.mtimeMs<e||(d.deleted?r.push(a):n.push(a));let o=await Promise.all(n.map(a=>this.read(a).catch(()=>{}))),i=[];for(let a of o)a&&i.push(a);return{records:i,removed:r,cursor:t}}async ensureIndex(){this.index||(this.indexSeed||(this.indexSeed=this.seedIndex()),await this.indexSeed)}async seedIndex(){let e=new Map,t=[];try{t=await _e.readdir(E.sessionsDir())}catch(n){if(n.code!=="ENOENT")throw n}await Promise.all(t.map(async n=>{if(_n.test(n))try{let r=await _e.stat(E.sessionFile(n));e.set(n,{mtimeMs:r.mtimeMs,deleted:!1})}catch{}})),this.index=e}async reindex(e){if(this.indexSeed){await this.indexSeed;try{let t=await _e.stat(E.sessionFile(e));this.index.set(e,{mtimeMs:t.mtimeMs,deleted:!1})}catch{}}}async read(e){if(!_n.test(e))return;let t=await ce(E.sessionFile(e));if(t!==void 0)try{return Hm.parse(t)}catch{return}}async delete(e){if(_n.test(e)){this.indexSeed&&(await this.indexSeed,this.index.set(e,{mtimeMs:Date.now(),deleted:!0}));try{await _e.unlink(E.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await _e.rmdir(E.sessionDir(e))}catch(t){let n=t;if(n.code!=="ENOENT"&&n.code!=="ENOTEMPTY")throw t}}}async findByLineageId(e){if(e.length===0)return;let t=await this.list().catch(()=>[]);for(let n of t)if(n.lineageId===e)return n}async list(){let e;try{e=await _e.readdir(E.sessionsDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let t=await Promise.all(e.map(r=>this.read(r).catch(()=>{}))),n=[];for(let r of t)r&&n.push(r);return n}};function Fo(s){let e=new Date().toISOString(),t=s.createdAt??e,n=(s.currentUsage?.cumulativeCost??0)+(s.currentUsage?.costAmount??0),r=s.upstreamGenerations??(s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId,startedAt:t,...n===0?{lifetimeCostAtStart:0}:{}}]:[]);return{sessionId:s.sessionId,lineageId:s.lineageId,upstreamSessionId:s.upstreamSessionId,importedFromSessionId:s.importedFromSessionId,importedFromUpstreamSessionId:s.importedFromUpstreamSessionId,importedFromMachine:s.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:s.synopsis,summarizedThroughEntry:s.summarizedThroughEntry,compactionState:s.compactionState,rollbackBreadcrumb:s.rollbackBreadcrumb,upstreamGenerations:r,agentArgs:s.agentArgs,currentModel:s.currentModel,currentMode:s.currentMode,currentUsage:s.currentUsage,agentCommands:s.agentCommands,agentModes:s.agentModes,agentModels:s.agentModels,configOptionValues:s.configOptionValues,pendingHistorySync:s.pendingHistorySync,pendingAgentSwap:s.pendingAgentSwap,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,side:s.side,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,priority:s.priority,lastTurnEndedAt:s.lastTurnEndedAt,readAt:s.readAt,forwardedEnv:s.forwardedEnv,workspace:s.workspace,attentionFlags:s.attentionFlags??[],extensionState:s.extensionState??{},createdAt:t,updatedAt:s.updatedAt??e}}He();Q();import*as de from"fs/promises";import*as Se from"path";Q();import*as _s from"path";import{createHash as Um}from"crypto";var Fe=class extends Error{constructor(e,t){super(`provider "${e}" does not support ${t}; check capabilities().supports before calling`),this.name="WorkspaceUnsupportedError"}};function en(s){let e=Um("sha256").update(_s.resolve(s)).digest("hex").slice(0,12);return _s.join(q(),"workspaces",e)}async function $s(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 Ct(s,e=10){if(s.length<=e)return[...s];let t=s.slice(0,e),n=s.length-e;return[...t,`... and ${n} more`]}function No(s){return s.changedPaths.length>0||s.recorded!==void 0&&s.recorded!==s.actual}function Lm(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 Do(s,e){let t=new Set(e.map(r=>r.relPath));return[...s.filter(r=>!t.has(r.replace(/\/$/,""))),...Lm(e.filter(No))]}function Os(s){let e=s.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e.slice(0,64):"workspace"}var Ho="copy",Zd=new Set([".git"]);function On(s){return`${s}.manifest.json`}async function Xd(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 de.readdir(n,{withFileTypes:!0})}catch{continue}for(let o of r){let i=Se.join(n,o.name);if(!(n===s&&Zd.has(o.name))){if(o.isDirectory()){t.push(i);continue}if(o.isFile())try{let a=await de.stat(i);e.set(Se.relative(s,i),{size:a.size,mtimeMs:a.mtimeMs})}catch{continue}}}}return e}var Fs=class{kind=Ho;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=Se.resolve(e.sourceCwd),n=e.contentFrom!==void 0?Se.resolve(e.contentFrom):t;try{n=await de.realpath(n)}catch{}try{if(!(await de.stat(n)).isDirectory())return{ok:!1,reason:`${n} is not a directory`}}catch{return{ok:!1,reason:`${n} does not exist`}}let r=en(t);try{await de.mkdir(r,{recursive:!0})}catch(u){return{ok:!1,reason:`could not create workspace root: ${String(u)}`}}let o=await $s(Os(e.label),async u=>de.access(Se.join(r,u)).then(()=>!1).catch(()=>!0));if(o===void 0)return{ok:!1,reason:`no free name available for "${e.label}"`};let i=Se.join(r,o),a;try{a=await de.readdir(n)}catch(u){return{ok:!1,reason:`copy failed: ${String(u)}`}}try{await de.mkdir(i,{recursive:!0});for(let u of a)Zd.has(u)||await de.cp(Se.join(n,u),Se.join(i,u),{recursive:!0,errorOnExist:!1,force:!0})}catch(u){return await de.rm(i,{recursive:!0,force:!0}).catch(()=>{}),{ok:!1,reason:`copy failed: ${String(u)}`}}let d=await Xd(i),c={sourceCwd:t,label:o,createdAt:new Date().toISOString(),entries:Object.fromEntries(d)};return await me(On(i),c,{pretty:!1}),{ok:!0,workspace:{path:i,sourceCwd:t,label:o,provider:this.kind}}}async removeWorkspace(e,t){if(!t.force){let n=await this.status(e);if(!n.clean)throw new Error(`workspace ${e.path} has ${n.changedPaths.length} changed path(s); pass force to remove`)}await de.rm(e.path,{recursive:!0,force:!0}),await de.rm(On(e.path),{force:!0})}async listWorkspaces(e){let t=en(Se.resolve(e)),n;try{n=await de.readdir(t)}catch{return[]}let r=[];for(let o of n){if(o.endsWith(".manifest.json"))continue;let i=Se.join(t,o),a=await ce(On(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 ce(On(e.path)),n=await Xd(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:`,...Ct(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 Fe(this.kind,"captureWorkingState")}async record(){throw new Fe(this.kind,"record")}async attributeOrphan(e){let t=await ce(On(e));if(t?.sourceCwd!==void 0)return{path:e,sourceCwd:t.sourceCwd,label:t.label??Se.basename(e),provider:this.kind}}async discardLine(){return{ok:!0,dropped:0}}ownsLine(){return!1}async pruneStale(){}async changedPaths(){throw new Fe(this.kind,"changedPaths")}async integrate(){return{ok:!1,conflicts:[],declined:!0,reason:`the "${this.kind}" provider keeps no history, so there is nothing to integrate from`}}async currentState(){}async contentId(){}async currentLineName(){}async resolveRoot(e){return e}async resolveRetained(){}async contains(){return!1}async divergence(){}async changedPathsBetween(){return[]}async captureDelta(){throw new Fe(this.kind,"captureDelta")}async applyDelta(){return{ok:!1,reason:`the "${this.kind}" provider cannot reproduce a captured change`}}async resetTo(){return{ok:!1,reason:`the "${this.kind}" provider records no state to return to`}}async integrationInProgress(){return!1}async abortIntegration(){}async conflictedPaths(){return[]}async listNested(){return[]}async captureNested(){return[]}async reproduceNested(){return{applied:[],failed:[]}}async integrateNested(){return{applied:[],failed:[]}}async lock(){throw new Fe(this.kind,"lock")}async unlock(){throw new Fe(this.kind,"unlock")}};Q();import{execFile as rc}from"child_process";import{randomBytes as zm}from"crypto";import*as Ne from"fs/promises";import*as oc from"os";import*as Z from"path";function Bm(s){let e=s.indexOf(" ");return e===-1?{key:s,value:""}:{key:s.slice(0,e),value:s.slice(e+1)}}function ec(s){let e=[],t,n=()=>{t!==void 0&&(e.push(t),t=void 0)};for(let r of s.split(`
131
- `)){let o=r.replace(/\r$/,"");if(o.length===0){n();continue}let{key:i,value:a}=Bm(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 tc(s){if(s===void 0)return;let e="refs/heads/";return s.startsWith(e)?s.slice(e.length):s}var Hs="git",nc="hydra-acp:",jo="hydra",V=5e3,pe=12e4,Ns=9e5;function sc(s){return Ne.access(s).then(()=>!0).catch(()=>!1)}function Fn(s){return s.length===0?s:Z.normalize(s)}function Jm(s){return Ne.realpath(s).catch(()=>s)}function j(s,e,t,n){return new Promise(r=>{rc("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 Uo(s,e,t,n=pe){return new Promise(r=>{let o=rc("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 Lo(s){let e=[];for(let t of s.split(`
132
- `)){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 Ds=class{kind=Hs;refRoot(e){return e.vcs?.repoRoot??e.sourceCwd}ownsLine(e){return e.startsWith(`${jo}/`)}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 sc(Z.join(e.path,".gitmodules")))return{ok:!0,count:0};let r=await j(["submodule","update","--init","--recursive",...t?.discardLocal===!0?["--force"]:[]],e.path,Ns);if(!r.ok)return{ok:!1,count:0,reason:r.stderr.trim()||"git submodule update --init failed"};if(t?.discardLocal===!0){let a=await j(["submodule","foreach","--recursive","git","reset","--hard"],e.path,Ns);if(!a.ok)return{ok:!1,count:0,reason:a.stderr.trim()||"could not reset submodules"};let d=t.purgeIgnored===!0?"-ffdx":"-fd",c=await j(["submodule","foreach","--recursive","git","clean",d],e.path,Ns);if(!c.ok)return{ok:!1,count:0,reason:c.stderr.trim()||"could not clean submodules"}}let o=await j(["submodule","status","--recursive"],e.path,V);return{ok:!0,count:o.ok?o.stdout.split(`
133
- `).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 sc(n))return{ok:!1,reason:`source repository ${n} no longer exists`};let r=await j(["rev-parse","--verify","--quiet",`refs/heads/${t}`],n,V);if(!r.ok||r.stdout.trim().length===0)return{ok:!1,reason:`branch ${t} no longer exists in ${n}`};await j(["worktree","unlock",e.path],n,V),await j(["worktree","prune"],n,V);let o=await j(["worktree","add",e.path,t],n,pe);return o.ok?{ok:!0,workspace:{...e,line:t,vcs:{...e.vcs??{},kind:"git",branch:t,repoRoot:n}}}:{ok:!1,reason:`could not restore worktree: ${o.stderr.trim()||"unknown error"}`}}async createWorkspace(e){let t=Z.resolve(e.sourceCwd),n=await j(["rev-parse","--show-toplevel"],t,V);if(!n.ok)return{ok:!1,reason:`${t} is not a git repository (or git is unavailable)`};let r=Fn(n.stdout.trim());if(r.length===0)return{ok:!1,reason:`could not resolve the repository root for ${t}`};let o=await j(["rev-parse","HEAD"],r,V);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=Os(e.label),d=en(t);try{await Ne.mkdir(d,{recursive:!0})}catch(h){return{ok:!1,reason:`could not create workspace root: ${String(h)}`}}let c=await $s(a,async h=>await Ne.access(Z.join(d,h)).then(()=>!0).catch(()=>!1)?!1:!(await j(["rev-parse","--verify","--quiet",`refs/heads/${jo}/${h}`],r,V)).ok);if(c===void 0)return{ok:!1,reason:`no free name available for "${a}"`};let u=Z.join(d,c),l=`${jo}/${c}`,w=await j(["worktree","add","--no-track","-b",l,u,i],r,pe);return w.ok?{ok:!0,workspace:{path:u,sourceCwd:t,label:c,provider:this.kind,snapshot:i,line:l,vcs:{kind:"git",branch:l,base:i,repoRoot:r}}}:{ok:!1,reason:`git worktree add failed: ${w.stderr.trim()||"unknown error"}`}}async removeWorkspace(e,t){if(!t.force){let o=await this.status(e);if(!o.clean)throw new Error(`workspace ${e.path} has ${o.changedPaths.length} changed path(s)${o.hasRecordedWork?" and unintegrated recorded work":""}; pass force to remove`)}let n=this.refRoot(e);await this.unlock(e).catch(()=>{});let r=await j(["worktree","remove","--force",e.path],n,pe);t.discardLine===!0&&e.vcs?.branch!==void 0&&await j(["branch","-D",e.vcs.branch],n,V),r.ok||(await Ne.rm(e.path,{recursive:!0,force:!0}),await j(["worktree","prune"],n,V))}async listWorkspaces(e){let t=Z.resolve(e),n=await j(["rev-parse","--show-toplevel"],t,V);if(!n.ok)return[];let r=Fn(n.stdout.trim()),o=await j(["worktree","list","--porcelain"],r,V);if(!o.ok)return[];let i=en(t),a=await Jm(i),d=[];for(let c of ec(o.stdout)){let u=Fn(c.path),l=Z.dirname(u);if(l!==i&&l!==a)continue;let w=Z.join(i,Z.basename(u)),h={kind:"git",repoRoot:r},f=tc(c.branch);f!==void 0&&(h.branch=f),c.head!==void 0&&(h.head=c.head),c.lockedReason!==void 0&&(h.locked=c.lockedReason);let k=c.lockedReason?.startsWith(nc)===!0;d.push({path:w,sourceCwd:t,label:Z.basename(w),...k?{heldByUs:!0}:{},provider:this.kind,...f!==void 0?{line:f}:{},vcs:h})}return d}async status(e){let t=await j(["status","--porcelain","--untracked-files=all"],e.path,V);if(!t.ok)return{clean:!1,changedPaths:[],hasRecordedWork:!1};let n=Lo(t.stdout),r=n.map(a=>a.path),o=n.some(({code:a})=>a!=="??"&&a[0]!==" "&&a[0]!=="?"),i=!1;if(e.snapshot!==void 0){let a=await j(["rev-list","--count",`${e.snapshot}..HEAD`],e.path,V);a.ok&&(i=Number.parseInt(a.stdout.trim(),10)>0)}return{clean:r.length===0&&!i,changedPaths:r,hasRecordedWork:i,hasStagedWork:o}}async lock(e,t){let n=this.refRoot(e);await j(["worktree","lock","--reason",`${nc}${t}`,e.path],n,V)}async unlock(e){let t=this.refRoot(e);await j(["worktree","unlock",e.path],t,V)}async environmentNotes(e){let t=[],n=e.vcs?.branch;return t.push(`This directory is a git worktree of ${e.sourceCwd}${n!==void 0?`, on branch ${n}`:""}. Do not read or write ${e.sourceCwd} directly; paths under it refer to the corresponding file here. Prefer repo-relative paths, which are identical in both.`),t.push("`.git` here is a file, not a directory. That is normal for a worktree and does not need repairing."),await Ne.access(Z.join(e.path,".gitmodules")).then(()=>!0).catch(()=>!1)&&t.push("Submodules here are initialized and checked out at the commits this tree records, which means each sits on a detached HEAD. That is normal and does not need repairing. Never re-add a submodule's contents as ordinary tracked files in the superproject: that silently corrupts the integration back to the source branch."),t}async statusReport(e){let t=[],n=await j(["status","--porcelain","--untracked-files=all"],e.path,V);if(n.ok){let r=Lo(n.stdout);if(r.length===0)t.push("no uncommitted changes");else{let o=0,i=0,a=0;for(let{code:c}of r){if(c==="??"){a+=1;continue}c[0]!==" "&&c[0]!=="?"&&(o+=1),c[1]!==" "&&c[1]!=="?"&&(i+=1)}let d=[];o>0&&d.push(`${o} staged`),i>0&&d.push(`${i} unstaged`),a>0&&d.push(`${a} untracked`),t.push(`${d.join(", ")}:`),t.push(...Ct(r.map(c=>` ${c.code} ${c.path}`)))}}return t.push(...await this.syncLines(e)),t}async syncLines(e){if(e.vcs?.branch===void 0)return[];let[t,n]=await Promise.all([j(["rev-parse","HEAD"],e.sourceCwd,V),j(["rev-parse","HEAD"],e.path,V)]),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 j(["rev-list","--left-right","--count",`${r}...${o}`],e.path,V),d=a.stdout.trim().split(/\s+/).map(w=>Number.parseInt(w,10)),c=d[0],u=d[1];if(!a.ok||c===void 0||u===void 0||!Number.isFinite(c)||!Number.isFinite(u))return[];let l=[];return c>0&&l.push(`${c} commit(s) behind ${i}. \`/hydra workspace sync\` brings them in; landing is fast-forward-only, so this also unblocks \`stop\`.`),u>0&&l.push(`${u} commit(s) recorded here and not landed yet.`),l}async captureWorkingState(e,t){let n=Z.join(oc.tmpdir(),`hydra-index-${process.pid}-${zm(6).toString("hex")}`),r={GIT_INDEX_FILE:n};try{let o=await j(["rev-parse","--verify","HEAD"],e,V),i=o.ok&&o.stdout.trim().length>0;if(i){let l=await j(["read-tree","HEAD"],e,pe,r);if(!l.ok)throw new Error(`could not seed the snapshot index: ${l.stderr.trim()}`)}let a=await j(["add","-A"],e,pe,r);if(!a.ok)throw new Error(`could not stage working state: ${a.stderr.trim()}`);let d=await j(["write-tree"],e,pe,r);if(!d.ok||d.stdout.trim().length===0)throw new Error(`could not write tree: ${d.stderr.trim()}`);let c=["commit-tree",d.stdout.trim(),"-m",t];i&&c.push("-p",o.stdout.trim());let u=await j(c,e,pe,r);if(!u.ok||u.stdout.trim().length===0)throw new Error(`could not create snapshot commit: ${u.stderr.trim()}`);return u.stdout.trim()}finally{await Ne.rm(n,{force:!0}).catch(()=>{})}}async retainSnapshot(e,t,n){let r=this.refRoot(e);await j(["update-ref","--create-reflog",t,n],r,V)}async dropSnapshotRef(e,t){let n=this.refRoot(e);await j(["update-ref","-d",t],n,V)}async currentState(e){let t=await j(["rev-parse","HEAD"],e,V),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async contentId(e,t){let n=await j(["rev-parse",`${t}^{tree}`],e,V),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async currentLineName(e){let t=await j(["rev-parse","--abbrev-ref","HEAD"],e,V),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async resolveRoot(e){let t=await j(["rev-parse","--show-toplevel"],e,V),n=Fn(t.stdout.trim());return t.ok&&n.length>0?n:void 0}async resolveRetained(e,t){let n=await j(["rev-parse","--verify","--quiet",`${t}^{commit}`],this.refRoot(e),V),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async contains(e,t){return(await j(["merge-base","--is-ancestor",t.state,t.within],e,V)).ok}async divergence(e,t,n){let r=await j(["rev-list","--left-right","--count",`${t}...${n}`],e,V);if(!r.ok)return;let o=r.stdout.trim().split(/\s+/).map(d=>Number.parseInt(d,10)),i=o[0],a=o[1];if(!(i===void 0||a===void 0||!Number.isFinite(i)||!Number.isFinite(a)))return{ahead:i,behind:a}}async changedPathsBetween(e,t,n){let r=await j(["diff","--name-only",t,n],e,V);return r.ok?r.stdout.split(`
134
- `).map(o=>o.replace(/\r$/,"").trim()).filter(o=>o.length>0):[]}async captureDelta(e,t,n){let r=await j(["diff","--binary","--ignore-submodules=all",t,n],e,pe);if(r.ok)return r.stdout}async applyDelta(e,t,n){if(t.trim().length===0)return{ok:!0,alreadyPresent:!0};let r=n?.stage===!0?["--index"]:[],o=await Uo(["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 Uo(["apply","--reverse","--check"],e,t)).ok)return{ok:!0,alreadyPresent:!0};let a=await Uo(["apply","--3way"],e,t);return a.ok?{ok:!0}:{ok:!1,reason:a.stderr.trim()||"the change overlaps what is already there"}}async resetTo(e,t,n){let r=await j(["reset","--hard",t],e,pe);if(!r.ok)return{ok:!1,reason:r.stderr.trim()||"could not return to that state"};let o=await j(["clean",n?.purgeIgnored===!0?"-ffdx":"-fd"],e,pe);if(!o.ok)return{ok:!1,reason:o.stderr.trim()||"returned to that state but could not remove extra files"};let i=await this.materializeNested({path:e,sourceCwd:e,label:"",provider:this.kind},{discardLocal:!0,...n?.purgeIgnored===!0?{purgeIgnored:!0}:{}});return i.ok?{ok:!0}:{ok:!1,reason:i.reason??"could not reset nested trees"}}async integrationInProgress(e){return(await j(["rev-parse","-q","--verify","MERGE_HEAD"],e,V)).ok}async abortIntegration(e){await j(["merge","--abort"],e,pe)}async conflictedPaths(e){let t=await j(["diff","--name-only","--diff-filter=U"],e,V);return t.ok?t.stdout.split(`
135
- `).map(n=>n.replace(/\r$/,"").trim()).filter(n=>n.length>0):[]}async record(e,t){let n=await j(["add","-A"],e.path,pe);if(!n.ok)throw new Error(`could not stage ${e.path}: ${n.stderr.trim()||"unknown error"}`);let r=await this.status(e),o=await this.currentState(e.path);if(r.changedPaths.length===0){if(o===void 0)throw new Error(`could not read the state of ${e.path}`);return o}let i=await j(["commit","-m",t],e.path,pe);if(!i.ok)throw new Error(`could not record ${e.path}: ${i.stderr.trim()||i.stdout.trim()||"unknown error"}`);let a=await this.currentState(e.path);if(a===void 0)throw new Error(`recorded ${e.path} but could not read the resulting state`);return a}async attributeOrphan(e){let t=await j(["rev-parse","--path-format=absolute","--git-common-dir"],e,V),n=Fn(t.stdout.trim());if(!t.ok||n.length===0)return;let r=Z.dirname(n),o=await this.currentLineName(e);return{path:e,sourceCwd:r,label:Z.basename(e),provider:this.kind,...o!==void 0?{line:o}:{},vcs:{repoRoot:r,...o!==void 0?{branch:o}:{}}}}async discardLine(e,t){let n=this.refRoot(e),o=(await this.divergence(n,"HEAD",t))?.behind??0,i=await j(["branch","-D",t],n,V);return i.ok?{ok:!0,dropped:o}:{ok:!1,dropped:o,reason:i.stderr.trim()||"could not discard the line"}}async pruneStale(e){await j(["worktree","prune"],this.refRoot(e),V)}async changedPaths(){throw new Fe(this.kind,"changedPaths")}async integrate(e){let{into:t,from:n}=e,r=await this.currentState(t);if(r===void 0)return{ok:!1,conflicts:[],declined:!0,reason:`cannot read the state of ${t}`};if(await this.contains(t,{state:n,within:r}))return{ok:!0,snapshot:r,alreadyUpToDate:!0};if(e.fastForwardOnly===!0&&!await this.contains(t,{state:r,within:n}))return{ok:!1,conflicts:[],declined:!0,reason:`${t} cannot simply advance to that state; it has moved on independently`};let o=e.fastForwardOnly===!0?["merge","--ff-only",n]:["merge","--no-edit","-m",e.message??"hydra: integrate",n],i=await j(o,t,pe);if(i.ok){let c=await this.currentState(t);return c===void 0?{ok:!1,conflicts:[],reason:"integrated but could not read the resulting state"}:{ok:!0,snapshot:c}}let a=await this.conflictedPaths(t),d=await this.integrationInProgress(t);return a.length===0&&!d?{ok:!1,conflicts:[],declined:!0,reason:i.stderr.trim()||"the integration was refused"}:(e.onConflict==="abort"&&await this.abortIntegration(t),{ok:!1,conflicts:a})}async listNested(e){let t=await j(["submodule","status","--recursive"],e,pe);if(!t.ok)return[];let n=[];for(let r of t.stdout.split(`
136
- `)){let o=r.replace(/\r$/,"");if(o.trim().length===0||(o[0]??" ")==="-")continue;let a=o.slice(1),d=a.indexOf(" ");if(d<=0)continue;let c=a.slice(d+1).replace(/\s+\(.*\)\s*$/,"").trim();if(c.length===0||!Vm(e,c))continue;let u=Z.join(e,c),[l,w,h]=await Promise.all([this.currentState(u),j(["rev-parse",`HEAD:${c}`],e,V),j(["status","--porcelain","--untracked-files=all"],u,V)]);if(l===void 0)continue;let f=w.ok?w.stdout.trim():"";n.push({relPath:c,actual:l,...f.length>0?{recorded:f}:{},changedPaths:h.ok?Lo(h.stdout).map(k=>k.path):[]})}return n}async captureNested(e,t){let n=[];for(let r of t){if(!No(r))continue;if(r.changedPaths.length===0){n.push(r);continue}let o=Z.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=Z.join(e,i.relPath),d=Z.join(t,i.relPath),c=await this.alignNested(a,d,i.actual);if(c!==void 0){o.push({path:i.relPath,reason:c});continue}if(i.delta!==void 0){let u=await this.applyDelta(a,i.delta);if(!u.ok){o.push({path:i.relPath,reason:u.reason??"changes did not apply"});continue}}r.push(i.relPath)}return{applied:r,failed:o}}async integrateNested(e,t,n){let r=[],o=[],i=new Map(n.map(c=>[c.relPath,c])),a=await this.listNested(e),d=new Set([...a.map(c=>c.relPath),...i.keys()]);for(let c of[...d].sort()){let u=a.find(p=>p.relPath===c),l=i.get(c);if(u===void 0){o.push({path:c,reason:"not populated in the receiving tree"});continue}let w=u.recorded!==void 0&&u.recorded!==u.actual,h=l?.delta!==void 0;if(!w&&!h)continue;if(u.changedPaths.length>0){o.push({path:c,reason:`it has ${u.changedPaths.length} uncommitted change(s) of its own, and nothing can tell those apart from what was integrated`});continue}let f=Z.join(e,c),k=Z.join(t,c);if(w&&u.recorded!==void 0){let p=await this.alignNested(f,k,u.recorded);if(p!==void 0){o.push({path:c,reason:p});continue}}if(l?.delta!==void 0){let p=await this.applyDelta(f,l.delta);if(!p.ok){o.push({path:c,reason:p.reason??"the uncommitted changes there did not apply"});continue}}r.push(c)}return{applied:r,failed:o}}async alignNested(e,t,n){let r=await this.currentState(e);if(r===void 0)return"not populated here";if(r===n)return;if(!(await j(["cat-file","-e",`${n}^{commit}`],e,V)).ok&&!(await j(["fetch","--no-tags",t,n],e,Ns)).ok)return`could not transfer ${n.slice(0,8)} from the other copy`;if(!(await j(["checkout","--detach",n],e,pe)).ok)return`could not move to ${n.slice(0,8)}`}};function Vm(s,e){if(Z.isAbsolute(e))return!1;let t=Z.resolve(s),n=Z.resolve(t,e);return n!==t&&n.startsWith(t+Z.sep)}var Gm=Hs,Km=new Map([[Hs,new Ds],[Ho,new Fs]]);function oe(s){return Km.get(s??Gm)}var js="refs/hydra";function tn(s){let e=`${js}/workspaces/${s}`;return{autosave:`${e}/autosave`,start:`${e}/start`,baseline:`${e}/baseline`}}function Bo(s){return`${js}/landing/${s}`}function ic(s){return`${js}/sync/${s}`}function ac(s,e){return`${js}/retired/${s}-${e.slice(0,12)}`}function dc(s){let e=tn(s);return[e.autosave,e.start,e.baseline]}async function Wo(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 w=await i.resolveRetained(t,l).catch(()=>{});if(w!==void 0){d=w;break}}let c=a===void 0||a.changedPaths.length>0;if(d.length===0){if(c)throw new Error(`${e} has uncommitted changes but this workspace has no start anchor, so its copy of your work cannot be told apart from edits you made since. Refusing rather than reporting a conflict that is not yours. Commit or stash the source, then retry.`);d=await i.currentState(e).catch(()=>{})??""}if(!c)return{clean:!0,base:d};if(i.capabilities().supports.captureWorkingState!==!0)throw new Error(`${e} has uncommitted changes and this provider cannot snapshot them, so they cannot be preserved across the landing. Commit or stash them first.`);let u=await i.captureWorkingState(e,"hydra: source state before landing").catch(()=>{});if(u===void 0)throw new Error(`could not snapshot the uncommitted changes in ${e}, so refusing to touch them`);return await i.retainSnapshot({...t,path:e},o,u),{clean:!1,snapshot:u,base:d,retainedRef:o}}async function Rt(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 Nn(s){s.capture.retainedRef===void 0||s.provider===void 0||await s.provider.dropSnapshotRef({...s.ws,path:s.source},s.capture.retainedRef).catch(()=>{})}He();import{exec as Qm}from"child_process";import*as Ge from"fs/promises";import*as Te from"path";var Ym=".hydra/worktree.json",Xm=".worktreeinclude",Zm=120;async function Us(s){let e=await ce(Te.join(s,Ym))??{},t=new Set(Array.isArray(e.carry)?e.carry:[]),n=await Ge.readFile(Te.join(s,Xm),"utf8").catch(()=>{});if(n!==void 0)for(let o of n.split(`
137
- `)){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 qo(s,e,t){let n=[],r=[],o=Te.resolve(s),i=Te.resolve(e);for(let a of t){let d=Te.resolve(o,a),c=Te.resolve(i,a);if(!d.startsWith(o+Te.sep)||!c.startsWith(i+Te.sep)){r.push(a);continue}if(await Ge.access(c).then(()=>!0).catch(()=>!1)){r.push(a);continue}let l=await Ge.stat(d).catch(()=>{});if(l===void 0){r.push(a);continue}try{await Ge.mkdir(Te.dirname(c),{recursive:!0}),await Ge.cp(d,c,{recursive:l.isDirectory(),dereference:!0}),n.push(a)}catch{r.push(a)}}return{copied:n,skipped:r}}async function Ls(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??Zm)*1e3;return new Promise(r=>{let o=Qm(s,{cwd:e.workspacePath,timeout:n,maxBuffer:8388608,windowsHide:!0,env:{...process.env,HYDRA_WORKSPACE_PATH:e.workspacePath,HYDRA_SOURCE_CWD:e.sourceCwd,HYDRA_WORKSPACE_LABEL:e.label,...e.sessionId!==void 0?{HYDRA_SESSION_ID:e.sessionId}:{}}},(i,a,d)=>{if(i){let c=(d||i.message||"").trim().slice(0,500);r({ok:!1,reason:c.length>0?c:"hook failed"});return}r({ok:!0})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}Q();He();import*as nt from"fs/promises";import{z as De}from"zod";var eh=De.object({version:De.literal(1),agentId:De.string(),upstreamSessionId:De.string(),sessionId:De.string().optional(),deletedAt:De.string(),upstreamUpdatedAt:De.string().optional(),cwd:De.string().optional(),title:De.string().optional(),reason:De.enum(["user","expired"]).optional(),interactive:De.boolean().optional()}),Bs=class{async add(e){let t={version:1,...e};await me(E.tombstoneFile(e.agentId,e.upstreamSessionId),t,{mode:384})}async has(e,t){try{return await nt.access(E.tombstoneFile(e,t)),!0}catch{return!1}}async read(e,t){let n=E.tombstoneFile(e,t),r=await ce(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 eh.parse(r)}catch{return{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}}}async remove(e,t){try{await nt.unlink(E.tombstoneFile(e,t))}catch(n){if(n.code!=="ENOENT")throw n}try{await nt.rmdir(E.tombstoneAgentDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}}async list(e){if(e!==void 0)return this.listForAgent(e);let t;try{t=await nt.readdir(E.tombstonesDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}n.push(...await this.listForAgent(o))}return n}async listForAgent(e){let t;try{t=await nt.readdir(E.tombstoneAgentDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}let i=await this.read(e,o);i&&n.push(i)}return n}};function cc(s,e){return s.reason==="user"||e===void 0?!1:s.upstreamUpdatedAt===void 0?!0:e>s.upstreamUpdatedAt}import*as Ic from"fs/promises";import{customAlphabet as uh}from"nanoid";import{fileURLToPath as th}from"url";import*as Dn from"path";import*as Ws from"fs";function nh(){try{let s=Dn.dirname(th(import.meta.url));for(let e=0;e<8;e+=1){let t=Dn.join(s,"package.json");if(Ws.existsSync(t)){let r=JSON.parse(Ws.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=Dn.dirname(s);if(n===s)break;s=n}}catch{}return"0.0.0"}var ue=nh(),qs="hydra-acp-cat";var sh=12e4;async function lc(s,e,t){let n=s.timeoutMs??sh,r,o,i=!1;try{let a=(async()=>{r=ct.spawn({agentId:s.agentId,cwd:s.cwd,plan:s.plan,logger:s.logger});let d=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:{name:"hydra-synopsis",version:ue}}),c=await r.connection.request("session/new",{cwd:s.cwd,mcpServers:[]}),u=c.sessionId;if(typeof u!="string"){s.logger?.warn(`synopsis: agent ${s.agentId} returned non-string sessionId from session/new`),s.onFailure?.(`agent ${s.agentId} did not return a sessionId from session/new`);return}if(s.onWorkerSpawned?.(u,r.pid),s.modelId){let f=oh(c);if(f.size===0||f.has(s.modelId)){let k=r.connection;try{await ut({request:(p,g)=>k.request(p,g),sessionId:u,modelId:s.modelId,verb:Wt(c),logger:s.logger})}catch(p){s.logger?.warn(`synopsis: agent ${s.agentId} rejected model change to ${JSON.stringify(s.modelId)}: ${p.message}; continuing on default`)}}else s.logger?.warn(`synopsis: model ${JSON.stringify(s.modelId)} not advertised by agent ${s.agentId} (have [${[...f].join(", ")}]); continuing on default`)}let l=[];r.connection.onNotification("session/update",f=>{let k=rh(f);k.length>0&&l.push(k)}),await r.connection.request("session/prompt",{sessionId:u,prompt:[{type:"text",text:e}]});let w=l.join(""),h=t(w);if(!h){let f=JSON.stringify(w.slice(0,200));s.logger?.warn(`synopsis: agent ${s.agentId} reply did not parse (replyLen=${w.length} preview=${f})`);let k=w.slice(0,120).replace(/\s+/g," ").trim();s.onFailure?.(`agent ${s.agentId} returned unparseable JSON (${w.length} chars): ${k}${w.length>120?"\u2026":""}`)}return h})();return await new Promise((d,c)=>{o=setTimeout(()=>{i=!0,s.logger?.warn(`synopsis: agent ${s.agentId} timed out after ${n}ms`),s.onFailure?.(`agent ${s.agentId} timed out after ${n}ms`),d(void 0)},n),o.unref?.(),a.then(u=>{o&&clearTimeout(o),i||d(u)},u=>{o&&clearTimeout(o),i||c(u)})})}catch(a){let d=a.message;s.logger?.warn(`synopsis: agent ${s.agentId} failed: ${d}`),s.onFailure?.(`agent ${s.agentId} failed: ${d}`);return}finally{o&&clearTimeout(o),r&&await r.kill().catch(()=>{})}}async function zs(s){let e=Qt(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}
141
+ Use empty arrays/strings where a field doesn't apply.`;function yc(s){let e=s.trim();if(e.length===0)return;let t=rn(e);if(t===void 0){let c=e.indexOf("{"),u=e.lastIndexOf("}");c>=0&&u>c&&(t=rn(e.slice(c,u+1)))}if(t===void 0){let c=wc(e);c!==void 0&&(t=rn(c))}if(t===void 0||t===null||typeof t!="object")return;let n=t,r={};if(typeof n.title=="string"){let c=n.title.trim();c.length>0&&(r.title=c.slice(0,mc))}let o={},i=!1,a=["goal","outcome"];for(let c of a)if(typeof n[c]=="string"){let u=n[c].trim();u.length>0&&(o[c]=u,i=!0)}let d=["files_touched","tools_used","rejected_approaches","open_threads","decisions","file_edit_intentions","unresolved_errors","tool_state"];for(let c of d)if(Array.isArray(n[c])){let u=n[c],l=X.array(X.string()).safeParse(u);l.success&&u.length>0&&(o[c]=l.data,i=!0)}if(i&&(r.synopsis=o),!(r.title===void 0&&r.synopsis===void 0))return r}function rn(s){try{return JSON.parse(s)}catch{return}}function wc(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 eh(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 nh="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",sh=th(nh,16),rh="hydra_lineage_";function Hn(){return`${rh}${sh()}`}var zo=M.object({name:M.string(),description:M.string().optional()}),Jo=M.object({id:M.string(),name:M.string().optional(),description:M.string().optional()}),oh=M.object({modelId:M.string(),name:M.string().optional(),description:M.string().optional()}),Vo=M.object({used:M.number().optional(),size:M.number().optional(),costAmount:M.number().optional(),costCurrency:M.string().optional(),cumulativeCost:M.number().optional()}),Go=M.object({name:M.string(),version:M.string().optional()}),ih=M.object({path:M.string(),sourceCwd:M.string(),label:M.string(),requestedLabel:M.string().optional(),provider:M.string(),snapshot:M.string().optional(),line:M.string().optional(),vcs:M.record(M.string(),M.string()).optional(),clean:M.boolean().optional()}),ah=M.object({previousUpstreamSessionId:M.string(),previousSummarizedThroughEntry:M.number().int().nonnegative().optional(),runId:M.string().optional()}),dh=M.enum(["compaction","agent-swap","workspace-enter","workspace-leave","rollback","restart"]),ch=M.object({upstreamSessionId:M.string(),agentId:M.string(),reason:dh.optional(),runId:M.string().optional(),startedAt:M.string().optional(),endedAt:M.string().optional(),cost:M.number().nonnegative().optional(),lifetimeCostAtStart:M.number().nonnegative().optional(),usedAtStart:M.number().nonnegative().optional(),usedAtEnd:M.number().nonnegative().optional(),inferred:M.boolean().optional()}),uh=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:Dn.optional(),compactionState:gc.optional(),rollbackBreadcrumb:ah.optional(),upstreamGenerations:M.array(ch).optional(),summarizedThroughEntry:M.number().int().nonnegative().optional(),agentArgs:M.array(M.string()).optional(),currentModel:M.string().optional(),currentMode:M.string().optional(),currentUsage:Vo.optional(),agentCommands:M.array(zo).optional(),agentModes:M.array(Jo).optional(),agentModels:M.array(oh).optional(),configOptionValues:M.record(M.string(),M.string()).optional(),pendingHistorySync:M.boolean().optional(),pendingAgentSwap:M.string().optional(),parentSessionId:M.string().optional(),forkedFromSessionId:M.string().optional(),forkedFromMessageId:M.string().optional(),side:Wt.optional(),forkSynthesisState:M.enum(["running","failed"]).optional(),originatingClient:Go.optional(),interactive:M.boolean().optional(),priority:M.number().int().nonnegative().optional(),tags:M.array(M.string()).optional(),lastTurnEndedAt:M.number().int().nonnegative().optional(),readAt:M.number().int().nonnegative().optional(),forwardedEnv:M.record(M.string(),M.string()).optional(),elicitationForms:M.boolean().optional(),workspace:ih.optional(),attentionFlags:pc.default([]).optional(),extensionState:M.record(M.string(),M.record(M.string(),M.unknown())).default({}).optional(),createdAt:M.string(),updatedAt:M.string()}),Ln=/^[A-Za-z0-9_-]+$/;function lh(s){if(!Ln.test(s))throw new Error(`unsafe session id: ${s}`)}var Bs=class{index;indexSeed;async write(e){lh(e.sessionId);let t={version:1,...e};await me(E.sessionFile(e.sessionId),t,{mode:384}),await this.reindex(e.sessionId)}async touch(e){if(!Ln.test(e))return;let t=new Date;try{await _e.utimes(E.sessionFile(e),t,t)}catch(n){if(n.code!=="ENOENT")throw n;return}await this.reindex(e)}async markDeleted(e,t){await this.ensureIndex();let n=this.index.get(e);n&&!n.deleted||n&&n.mtimeMs>=t||this.index.set(e,{mtimeMs:t,deleted:!0})}async cursor(){await this.ensureIndex();let e=0;for(let t of this.index.values())t.mtimeMs>e&&(e=t.mtimeMs);return e}async listChangedSince(e){let t=await this.cursor(),n=[],r=[];for(let[a,d]of this.index)d.mtimeMs<e||(d.deleted?r.push(a):n.push(a));let o=await Promise.all(n.map(a=>this.read(a).catch(()=>{}))),i=[];for(let a of o)a&&i.push(a);return{records:i,removed:r,cursor:t}}async ensureIndex(){this.index||(this.indexSeed||(this.indexSeed=this.seedIndex()),await this.indexSeed)}async seedIndex(){let e=new Map,t=[];try{t=await _e.readdir(E.sessionsDir())}catch(n){if(n.code!=="ENOENT")throw n}await Promise.all(t.map(async n=>{if(Ln.test(n))try{let r=await _e.stat(E.sessionFile(n));e.set(n,{mtimeMs:r.mtimeMs,deleted:!1})}catch{}})),this.index=e}async reindex(e){if(this.indexSeed){await this.indexSeed;try{let t=await _e.stat(E.sessionFile(e));this.index.set(e,{mtimeMs:t.mtimeMs,deleted:!1})}catch{}}}async read(e){if(!Ln.test(e))return;let t=await ce(E.sessionFile(e));if(t!==void 0)try{return uh.parse(t)}catch{return}}async delete(e){if(Ln.test(e)){this.indexSeed&&(await this.indexSeed,this.index.set(e,{mtimeMs:Date.now(),deleted:!0}));try{await _e.unlink(E.sessionFile(e))}catch(t){if(t.code!=="ENOENT")throw t}try{await _e.rmdir(E.sessionDir(e))}catch(t){let n=t;if(n.code!=="ENOENT"&&n.code!=="ENOTEMPTY")throw t}}}async findByLineageId(e){if(e.length===0)return;let t=await this.list().catch(()=>[]);for(let n of t)if(n.lineageId===e)return n}async list(){let e;try{e=await _e.readdir(E.sessionsDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let t=await Promise.all(e.map(r=>this.read(r).catch(()=>{}))),n=[];for(let r of t)r&&n.push(r);return n}};function Ko(s){let e=new Date().toISOString(),t=s.createdAt??e,n=(s.currentUsage?.cumulativeCost??0)+(s.currentUsage?.costAmount??0),r=s.upstreamGenerations??(s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId,startedAt:t,...n===0?{lifetimeCostAtStart:0}:{}}]:[]);return{sessionId:s.sessionId,lineageId:s.lineageId,upstreamSessionId:s.upstreamSessionId,importedFromSessionId:s.importedFromSessionId,importedFromUpstreamSessionId:s.importedFromUpstreamSessionId,importedFromMachine:s.importedFromMachine,agentId:s.agentId,cwd:s.cwd,title:s.title,synopsis:s.synopsis,summarizedThroughEntry:s.summarizedThroughEntry,compactionState:s.compactionState,rollbackBreadcrumb:s.rollbackBreadcrumb,upstreamGenerations:r,agentArgs:s.agentArgs,currentModel:s.currentModel,currentMode:s.currentMode,currentUsage:s.currentUsage,agentCommands:s.agentCommands,agentModes:s.agentModes,agentModels:s.agentModels,configOptionValues:s.configOptionValues,pendingHistorySync:s.pendingHistorySync,pendingAgentSwap:s.pendingAgentSwap,parentSessionId:s.parentSessionId,forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,side:s.side,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,priority:s.priority,tags:s.tags,lastTurnEndedAt:s.lastTurnEndedAt,readAt:s.readAt,forwardedEnv:s.forwardedEnv,elicitationForms:s.elicitationForms,workspace:s.workspace,attentionFlags:s.attentionFlags??[],extensionState:s.extensionState??{},createdAt:t,updatedAt:s.updatedAt??e}}He();Q();import*as de from"fs/promises";import*as Se from"path";Q();import*as Ws from"path";import{createHash as fh}from"crypto";var Ne=class extends Error{constructor(e,t){super(`provider "${e}" does not support ${t}; check capabilities().supports before calling`),this.name="WorkspaceUnsupportedError"}};function on(s){let e=fh("sha256").update(Ws.resolve(s)).digest("hex").slice(0,12);return Ws.join(q(),"workspaces",e)}async function qs(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 Tt(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 Qo(s){return s.changedPaths.length>0||s.recorded!==void 0&&s.recorded!==s.actual}function ph(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 Yo(s,e){let t=new Set(e.map(r=>r.relPath));return[...s.filter(r=>!t.has(r.replace(/\/$/,""))),...ph(e.filter(Qo))]}function zs(s){let e=s.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return e.length>0?e.slice(0,64):"workspace"}var Xo="copy",vc=new Set([".git"]);function jn(s){return`${s}.manifest.json`}async function kc(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 de.readdir(n,{withFileTypes:!0})}catch{continue}for(let o of r){let i=Se.join(n,o.name);if(!(n===s&&vc.has(o.name))){if(o.isDirectory()){t.push(i);continue}if(o.isFile())try{let a=await de.stat(i);e.set(Se.relative(s,i),{size:a.size,mtimeMs:a.mtimeMs})}catch{continue}}}}return e}var Js=class{kind=Xo;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=Se.resolve(e.sourceCwd),n=e.contentFrom!==void 0?Se.resolve(e.contentFrom):t;try{n=await de.realpath(n)}catch{}try{if(!(await de.stat(n)).isDirectory())return{ok:!1,reason:`${n} is not a directory`}}catch{return{ok:!1,reason:`${n} does not exist`}}let r=on(t);try{await de.mkdir(r,{recursive:!0})}catch(u){return{ok:!1,reason:`could not create workspace root: ${String(u)}`}}let o=await qs(zs(e.label),async u=>de.access(Se.join(r,u)).then(()=>!1).catch(()=>!0));if(o===void 0)return{ok:!1,reason:`no free name available for "${e.label}"`};let i=Se.join(r,o),a;try{a=await de.readdir(n)}catch(u){return{ok:!1,reason:`copy failed: ${String(u)}`}}try{await de.mkdir(i,{recursive:!0});for(let u of a)vc.has(u)||await de.cp(Se.join(n,u),Se.join(i,u),{recursive:!0,errorOnExist:!1,force:!0})}catch(u){return await de.rm(i,{recursive:!0,force:!0}).catch(()=>{}),{ok:!1,reason:`copy failed: ${String(u)}`}}let d=await kc(i),c={sourceCwd:t,label:o,createdAt:new Date().toISOString(),entries:Object.fromEntries(d)};return await me(jn(i),c,{pretty:!1}),{ok:!0,workspace:{path:i,sourceCwd:t,label:o,provider:this.kind}}}async removeWorkspace(e,t){if(!t.force){let n=await this.status(e);if(!n.clean)throw new Error(`workspace ${e.path} has ${n.changedPaths.length} changed path(s); pass force to remove`)}await de.rm(e.path,{recursive:!0,force:!0}),await de.rm(jn(e.path),{force:!0})}async listWorkspaces(e){let t=on(Se.resolve(e)),n;try{n=await de.readdir(t)}catch{return[]}let r=[];for(let o of n){if(o.endsWith(".manifest.json"))continue;let i=Se.join(t,o),a=await ce(jn(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 ce(jn(e.path)),n=await kc(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:`,...Tt(t.map(r=>` ${r}`))];return n.push(`Not tracking ${F(e.sourceCwd)}: a copied directory has no shared history, so there is nothing to be in or out of sync with.`),n}async environmentNotes(e){return[`This directory is an isolated copy of ${e.sourceCwd}. It is not under version control: there is no history, no branches, and version-control commands will not behave as they would in the original.`,"Changes here are not automatically returned to the original directory."]}async captureWorkingState(){throw new Ne(this.kind,"captureWorkingState")}async record(){throw new Ne(this.kind,"record")}async attributeOrphan(e){let t=await ce(jn(e));if(t?.sourceCwd!==void 0)return{path:e,sourceCwd:t.sourceCwd,label:t.label??Se.basename(e),provider:this.kind}}async discardLine(){return{ok:!0,dropped:0}}ownsLine(){return!1}async pruneStale(){}async changedPaths(){throw new Ne(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 Ne(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 Ne(this.kind,"lock")}async unlock(){throw new Ne(this.kind,"unlock")}};Q();import{execFile as Cc}from"child_process";import{randomBytes as yh}from"crypto";import*as De from"fs/promises";import*as Rc from"os";import*as Z from"path";function gh(s){let e=s.indexOf(" ");return e===-1?{key:s,value:""}:{key:s.slice(0,e),value:s.slice(e+1)}}function bc(s){let e=[],t,n=()=>{t!==void 0&&(e.push(t),t=void 0)};for(let r of s.split(`
142
+ `)){let o=r.replace(/\r$/,"");if(o.length===0){n();continue}let{key:i,value:a}=gh(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 Sc(s){if(s===void 0)return;let e="refs/heads/";return s.startsWith(e)?s.slice(e.length):s}var Ks="git",Ic="hydra-acp:",Zo="hydra",V=5e3,pe=12e4,Vs=9e5;function Ac(s){return De.access(s).then(()=>!0).catch(()=>!1)}function Un(s){return s.length===0?s:Z.normalize(s)}function wh(s){return De.realpath(s).catch(()=>s)}function H(s,e,t,n){return new Promise(r=>{Cc("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 ei(s,e,t,n=pe){return new Promise(r=>{let o=Cc("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 ti(s){let e=[];for(let t of s.split(`
143
+ `)){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 Gs=class{kind=Ks;refRoot(e){return e.vcs?.repoRoot??e.sourceCwd}ownsLine(e){return e.startsWith(`${Zo}/`)}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 Ac(Z.join(e.path,".gitmodules")))return{ok:!0,count:0};let r=await H(["submodule","update","--init","--recursive",...t?.discardLocal===!0?["--force"]:[]],e.path,Vs);if(!r.ok)return{ok:!1,count:0,reason:r.stderr.trim()||"git submodule update --init failed"};if(t?.discardLocal===!0){let a=await H(["submodule","foreach","--recursive","git","reset","--hard"],e.path,Vs);if(!a.ok)return{ok:!1,count:0,reason:a.stderr.trim()||"could not reset submodules"};let d=t.purgeIgnored===!0?"-ffdx":"-fd",c=await H(["submodule","foreach","--recursive","git","clean",d],e.path,Vs);if(!c.ok)return{ok:!1,count:0,reason:c.stderr.trim()||"could not clean submodules"}}let o=await H(["submodule","status","--recursive"],e.path,V);return{ok:!0,count:o.ok?o.stdout.split(`
144
+ `).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 Ac(n))return{ok:!1,reason:`source repository ${n} no longer exists`};let r=await H(["rev-parse","--verify","--quiet",`refs/heads/${t}`],n,V);if(!r.ok||r.stdout.trim().length===0)return{ok:!1,reason:`branch ${t} no longer exists in ${n}`};await H(["worktree","unlock",e.path],n,V),await H(["worktree","prune"],n,V);let o=await H(["worktree","add",e.path,t],n,pe);return o.ok?{ok:!0,workspace:{...e,line:t,vcs:{...e.vcs??{},kind:"git",branch:t,repoRoot:n}}}:{ok:!1,reason:`could not restore worktree: ${o.stderr.trim()||"unknown error"}`}}async createWorkspace(e){let t=Z.resolve(e.sourceCwd),n=await H(["rev-parse","--show-toplevel"],t,V);if(!n.ok)return{ok:!1,reason:`${t} is not a git repository (or git is unavailable)`};let r=Un(n.stdout.trim());if(r.length===0)return{ok:!1,reason:`could not resolve the repository root for ${t}`};let o=await H(["rev-parse","HEAD"],r,V);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=zs(e.label),d=on(t);try{await De.mkdir(d,{recursive:!0})}catch(h){return{ok:!1,reason:`could not create workspace root: ${String(h)}`}}let c=await qs(a,async h=>await De.access(Z.join(d,h)).then(()=>!0).catch(()=>!1)?!1:!(await H(["rev-parse","--verify","--quiet",`refs/heads/${Zo}/${h}`],r,V)).ok);if(c===void 0)return{ok:!1,reason:`no free name available for "${a}"`};let u=Z.join(d,c),l=`${Zo}/${c}`,y=await H(["worktree","add","--no-track","-b",l,u,i],r,pe);return y.ok?{ok:!0,workspace:{path:u,sourceCwd:t,label:c,provider:this.kind,snapshot:i,line:l,vcs:{kind:"git",branch:l,base:i,repoRoot:r}}}:{ok:!1,reason:`git worktree add failed: ${y.stderr.trim()||"unknown error"}`}}async removeWorkspace(e,t){if(!t.force){let o=await this.status(e);if(!o.clean)throw new Error(`workspace ${e.path} has ${o.changedPaths.length} changed path(s)${o.hasRecordedWork?" and unintegrated recorded work":""}; pass force to remove`)}let n=this.refRoot(e);await this.unlock(e).catch(()=>{});let r=await H(["worktree","remove","--force",e.path],n,pe);t.discardLine===!0&&e.vcs?.branch!==void 0&&await H(["branch","-D",e.vcs.branch],n,V),r.ok||(await De.rm(e.path,{recursive:!0,force:!0}),await H(["worktree","prune"],n,V))}async listWorkspaces(e){let t=Z.resolve(e),n=await H(["rev-parse","--show-toplevel"],t,V);if(!n.ok)return[];let r=Un(n.stdout.trim()),o=await H(["worktree","list","--porcelain"],r,V);if(!o.ok)return[];let i=on(t),a=await wh(i),d=[];for(let c of bc(o.stdout)){let u=Un(c.path),l=Z.dirname(u);if(l!==i&&l!==a)continue;let y=Z.join(i,Z.basename(u)),h={kind:"git",repoRoot:r},f=Sc(c.branch);f!==void 0&&(h.branch=f),c.head!==void 0&&(h.head=c.head),c.lockedReason!==void 0&&(h.locked=c.lockedReason);let k=c.lockedReason?.startsWith(Ic)===!0;d.push({path:y,sourceCwd:t,label:Z.basename(y),...k?{heldByUs:!0}:{},provider:this.kind,...f!==void 0?{line:f}:{},vcs:h})}return d}async status(e){let t=await H(["status","--porcelain","--untracked-files=all"],e.path,V);if(!t.ok)return{clean:!1,changedPaths:[],hasRecordedWork:!1};let n=ti(t.stdout),r=n.map(a=>a.path),o=n.some(({code:a})=>a!=="??"&&a[0]!==" "&&a[0]!=="?"),i=!1;if(e.snapshot!==void 0){let a=await H(["rev-list","--count",`${e.snapshot}..HEAD`],e.path,V);a.ok&&(i=Number.parseInt(a.stdout.trim(),10)>0)}return{clean:r.length===0&&!i,changedPaths:r,hasRecordedWork:i,hasStagedWork:o}}async lock(e,t){let n=this.refRoot(e);await H(["worktree","lock","--reason",`${Ic}${t}`,e.path],n,V)}async unlock(e){let t=this.refRoot(e);await H(["worktree","unlock",e.path],t,V)}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 De.access(Z.join(e.path,".gitmodules")).then(()=>!0).catch(()=>!1)&&t.push("Submodules here are initialized and checked out at the commits this tree records, which means each sits on a detached HEAD. That is normal and does not need repairing. Never re-add a submodule's contents as ordinary tracked files in the superproject: that silently corrupts the integration back to the source branch."),t}async statusReport(e){let t=[],n=await H(["status","--porcelain","--untracked-files=all"],e.path,V);if(n.ok){let r=ti(n.stdout);if(r.length===0)t.push("no uncommitted changes");else{let o=0,i=0,a=0;for(let{code:c}of r){if(c==="??"){a+=1;continue}c[0]!==" "&&c[0]!=="?"&&(o+=1),c[1]!==" "&&c[1]!=="?"&&(i+=1)}let d=[];o>0&&d.push(`${o} staged`),i>0&&d.push(`${i} unstaged`),a>0&&d.push(`${a} untracked`),t.push(`${d.join(", ")}:`),t.push(...Tt(r.map(c=>` ${c.code} ${c.path}`)))}}return t.push(...await this.syncLines(e)),t}async syncLines(e){if(e.vcs?.branch===void 0)return[];let[t,n]=await Promise.all([H(["rev-parse","HEAD"],e.sourceCwd,V),H(["rev-parse","HEAD"],e.path,V)]),r=t.stdout.trim(),o=n.stdout.trim();if(!t.ok||!n.ok||r.length===0||o.length===0)return[];let i=F(e.sourceCwd);if(r===o)return[`in sync with ${i}`];let a=await H(["rev-list","--left-right","--count",`${r}...${o}`],e.path,V),d=a.stdout.trim().split(/\s+/).map(y=>Number.parseInt(y,10)),c=d[0],u=d[1];if(!a.ok||c===void 0||u===void 0||!Number.isFinite(c)||!Number.isFinite(u))return[];let l=[];return c>0&&l.push(`${c} commit(s) behind ${i}. \`/hydra workspace sync\` brings them in; landing is fast-forward-only, so this also unblocks \`stop\`.`),u>0&&l.push(`${u} commit(s) recorded here and not landed yet.`),l}async captureWorkingState(e,t){let n=Z.join(Rc.tmpdir(),`hydra-index-${process.pid}-${yh(6).toString("hex")}`),r={GIT_INDEX_FILE:n};try{let o=await H(["rev-parse","--verify","HEAD"],e,V),i=o.ok&&o.stdout.trim().length>0;if(i){let l=await H(["read-tree","HEAD"],e,pe,r);if(!l.ok)throw new Error(`could not seed the snapshot index: ${l.stderr.trim()}`)}let a=await H(["add","-A"],e,pe,r);if(!a.ok)throw new Error(`could not stage working state: ${a.stderr.trim()}`);let d=await H(["write-tree"],e,pe,r);if(!d.ok||d.stdout.trim().length===0)throw new Error(`could not write tree: ${d.stderr.trim()}`);let c=["commit-tree",d.stdout.trim(),"-m",t];i&&c.push("-p",o.stdout.trim());let u=await H(c,e,pe,r);if(!u.ok||u.stdout.trim().length===0)throw new Error(`could not create snapshot commit: ${u.stderr.trim()}`);return u.stdout.trim()}finally{await De.rm(n,{force:!0}).catch(()=>{})}}async retainSnapshot(e,t,n){let r=this.refRoot(e);await H(["update-ref","--create-reflog",t,n],r,V)}async dropSnapshotRef(e,t){let n=this.refRoot(e);await H(["update-ref","-d",t],n,V)}async currentState(e){let t=await H(["rev-parse","HEAD"],e,V),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async contentId(e,t){let n=await H(["rev-parse",`${t}^{tree}`],e,V),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async currentLineName(e){let t=await H(["rev-parse","--abbrev-ref","HEAD"],e,V),n=t.stdout.trim();return t.ok&&n.length>0?n:void 0}async resolveRoot(e){let t=await H(["rev-parse","--show-toplevel"],e,V),n=Un(t.stdout.trim());return t.ok&&n.length>0?n:void 0}async resolveRetained(e,t){let n=await H(["rev-parse","--verify","--quiet",`${t}^{commit}`],this.refRoot(e),V),r=n.stdout.trim();return n.ok&&r.length>0?r:void 0}async contains(e,t){return(await H(["merge-base","--is-ancestor",t.state,t.within],e,V)).ok}async divergence(e,t,n){let r=await H(["rev-list","--left-right","--count",`${t}...${n}`],e,V);if(!r.ok)return;let o=r.stdout.trim().split(/\s+/).map(d=>Number.parseInt(d,10)),i=o[0],a=o[1];if(!(i===void 0||a===void 0||!Number.isFinite(i)||!Number.isFinite(a)))return{ahead:i,behind:a}}async changedPathsBetween(e,t,n){let r=await H(["diff","--name-only",t,n],e,V);return r.ok?r.stdout.split(`
145
+ `).map(o=>o.replace(/\r$/,"").trim()).filter(o=>o.length>0):[]}async captureDelta(e,t,n){let r=await H(["diff","--binary","--ignore-submodules=all",t,n],e,pe);if(r.ok)return r.stdout}async applyDelta(e,t,n){if(t.trim().length===0)return{ok:!0,alreadyPresent:!0};let r=n?.stage===!0?["--index"]:[],o=await ei(["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 ei(["apply","--reverse","--check"],e,t)).ok)return{ok:!0,alreadyPresent:!0};let a=await ei(["apply","--3way"],e,t);return a.ok?{ok:!0}:{ok:!1,reason:a.stderr.trim()||"the change overlaps what is already there"}}async resetTo(e,t,n){let r=await H(["reset","--hard",t],e,pe);if(!r.ok)return{ok:!1,reason:r.stderr.trim()||"could not return to that state"};let o=await H(["clean",n?.purgeIgnored===!0?"-ffdx":"-fd"],e,pe);if(!o.ok)return{ok:!1,reason:o.stderr.trim()||"returned to that state but could not remove extra files"};let i=await this.materializeNested({path:e,sourceCwd:e,label:"",provider:this.kind},{discardLocal:!0,...n?.purgeIgnored===!0?{purgeIgnored:!0}:{}});return i.ok?{ok:!0}:{ok:!1,reason:i.reason??"could not reset nested trees"}}async integrationInProgress(e){return(await H(["rev-parse","-q","--verify","MERGE_HEAD"],e,V)).ok}async abortIntegration(e){await H(["merge","--abort"],e,pe)}async conflictedPaths(e){let t=await H(["diff","--name-only","--diff-filter=U"],e,V);return t.ok?t.stdout.split(`
146
+ `).map(n=>n.replace(/\r$/,"").trim()).filter(n=>n.length>0):[]}async record(e,t){let n=await H(["add","-A"],e.path,pe);if(!n.ok)throw new Error(`could not stage ${e.path}: ${n.stderr.trim()||"unknown error"}`);let r=await this.status(e),o=await this.currentState(e.path);if(r.changedPaths.length===0){if(o===void 0)throw new Error(`could not read the state of ${e.path}`);return o}let i=await H(["commit","-m",t],e.path,pe);if(!i.ok)throw new Error(`could not record ${e.path}: ${i.stderr.trim()||i.stdout.trim()||"unknown error"}`);let a=await this.currentState(e.path);if(a===void 0)throw new Error(`recorded ${e.path} but could not read the resulting state`);return a}async attributeOrphan(e){let t=await H(["rev-parse","--path-format=absolute","--git-common-dir"],e,V),n=Un(t.stdout.trim());if(!t.ok||n.length===0)return;let r=Z.dirname(n),o=await this.currentLineName(e);return{path:e,sourceCwd:r,label:Z.basename(e),provider:this.kind,...o!==void 0?{line:o}:{},vcs:{repoRoot:r,...o!==void 0?{branch:o}:{}}}}async discardLine(e,t){let n=this.refRoot(e),o=(await this.divergence(n,"HEAD",t))?.behind??0,i=await H(["branch","-D",t],n,V);return i.ok?{ok:!0,dropped:o}:{ok:!1,dropped:o,reason:i.stderr.trim()||"could not discard the line"}}async pruneStale(e){await H(["worktree","prune"],this.refRoot(e),V)}async changedPaths(){throw new Ne(this.kind,"changedPaths")}async integrate(e){let{into:t,from:n}=e,r=await this.currentState(t);if(r===void 0)return{ok:!1,conflicts:[],declined:!0,reason:`cannot read the state of ${t}`};if(await this.contains(t,{state:n,within:r}))return{ok:!0,snapshot:r,alreadyUpToDate:!0};if(e.fastForwardOnly===!0&&!await this.contains(t,{state:r,within:n}))return{ok:!1,conflicts:[],declined:!0,reason:`${t} cannot simply advance to that state; it has moved on independently`};let o=e.fastForwardOnly===!0?["merge","--ff-only",n]:["merge","--no-edit","-m",e.message??"hydra: integrate",n],i=await H(o,t,pe);if(i.ok){let c=await this.currentState(t);return c===void 0?{ok:!1,conflicts:[],reason:"integrated but could not read the resulting state"}:{ok:!0,snapshot:c}}let a=await this.conflictedPaths(t),d=await this.integrationInProgress(t);return a.length===0&&!d?{ok:!1,conflicts:[],declined:!0,reason:i.stderr.trim()||"the integration was refused"}:(e.onConflict==="abort"&&await this.abortIntegration(t),{ok:!1,conflicts:a})}async listNested(e){let t=await H(["submodule","status","--recursive"],e,pe);if(!t.ok)return[];let n=[];for(let r of t.stdout.split(`
147
+ `)){let o=r.replace(/\r$/,"");if(o.trim().length===0||(o[0]??" ")==="-")continue;let a=o.slice(1),d=a.indexOf(" ");if(d<=0)continue;let c=a.slice(d+1).replace(/\s+\(.*\)\s*$/,"").trim();if(c.length===0||!kh(e,c))continue;let u=Z.join(e,c),[l,y,h]=await Promise.all([this.currentState(u),H(["rev-parse",`HEAD:${c}`],e,V),H(["status","--porcelain","--untracked-files=all"],u,V)]);if(l===void 0)continue;let f=y.ok?y.stdout.trim():"";n.push({relPath:c,actual:l,...f.length>0?{recorded:f}:{},changedPaths:h.ok?ti(h.stdout).map(k=>k.path):[]})}return n}async captureNested(e,t){let n=[];for(let r of t){if(!Qo(r))continue;if(r.changedPaths.length===0){n.push(r);continue}let o=Z.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=Z.join(e,i.relPath),d=Z.join(t,i.relPath),c=await this.alignNested(a,d,i.actual);if(c!==void 0){o.push({path:i.relPath,reason:c});continue}if(i.delta!==void 0){let u=await this.applyDelta(a,i.delta);if(!u.ok){o.push({path:i.relPath,reason:u.reason??"changes did not apply"});continue}}r.push(i.relPath)}return{applied:r,failed:o}}async integrateNested(e,t,n){let r=[],o=[],i=new Map(n.map(c=>[c.relPath,c])),a=await this.listNested(e),d=new Set([...a.map(c=>c.relPath),...i.keys()]);for(let c of[...d].sort()){let u=a.find(g=>g.relPath===c),l=i.get(c);if(u===void 0){o.push({path:c,reason:"not populated in the receiving tree"});continue}let y=u.recorded!==void 0&&u.recorded!==u.actual,h=l?.delta!==void 0;if(!y&&!h)continue;if(u.changedPaths.length>0){o.push({path:c,reason:`it has ${u.changedPaths.length} uncommitted change(s) of its own, and nothing can tell those apart from what was integrated`});continue}let f=Z.join(e,c),k=Z.join(t,c);if(y&&u.recorded!==void 0){let g=await this.alignNested(f,k,u.recorded);if(g!==void 0){o.push({path:c,reason:g});continue}}if(l?.delta!==void 0){let g=await this.applyDelta(f,l.delta);if(!g.ok){o.push({path:c,reason:g.reason??"the uncommitted changes there did not apply"});continue}}r.push(c)}return{applied:r,failed:o}}async alignNested(e,t,n){let r=await this.currentState(e);if(r===void 0)return"not populated here";if(r===n)return;if(!(await H(["cat-file","-e",`${n}^{commit}`],e,V)).ok&&!(await H(["fetch","--no-tags",t,n],e,Vs)).ok)return`could not transfer ${n.slice(0,8)} from the other copy`;if(!(await H(["checkout","--detach",n],e,pe)).ok)return`could not move to ${n.slice(0,8)}`}};function kh(s,e){if(Z.isAbsolute(e))return!1;let t=Z.resolve(s),n=Z.resolve(t,e);return n!==t&&n.startsWith(t+Z.sep)}var vh=Ks,bh=new Map([[Ks,new Gs],[Xo,new Js]]);function oe(s){return bh.get(s??vh)}var Qs="refs/hydra";function an(s){let e=`${Qs}/workspaces/${s}`;return{autosave:`${e}/autosave`,start:`${e}/start`,baseline:`${e}/baseline`}}function ni(s){return`${Qs}/landing/${s}`}function xc(s){return`${Qs}/sync/${s}`}function Tc(s,e){return`${Qs}/retired/${s}-${e.slice(0,12)}`}function Ec(s){let e=an(s);return[e.autosave,e.start,e.baseline]}async function si(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 y=await i.resolveRetained(t,l).catch(()=>{});if(y!==void 0){d=y;break}}let c=a===void 0||a.changedPaths.length>0;if(d.length===0){if(c)throw new Error(`${e} has uncommitted changes but this workspace has no start anchor, so its copy of your work cannot be told apart from edits you made since. Refusing rather than reporting a conflict that is not yours. Commit or stash the source, then retry.`);d=await i.currentState(e).catch(()=>{})??""}if(!c)return{clean:!0,base:d};if(i.capabilities().supports.captureWorkingState!==!0)throw new Error(`${e} has uncommitted changes and this provider cannot snapshot them, so they cannot be preserved across the landing. Commit or stash them first.`);let u=await i.captureWorkingState(e,"hydra: source state before landing").catch(()=>{});if(u===void 0)throw new Error(`could not snapshot the uncommitted changes in ${e}, so refusing to touch them`);return await i.retainSnapshot({...t,path:e},o,u),{clean:!1,snapshot:u,base:d,retainedRef:o}}async function Et(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 Bn(s){s.capture.retainedRef===void 0||s.provider===void 0||await s.provider.dropSnapshotRef({...s.ws,path:s.source},s.capture.retainedRef).catch(()=>{})}He();import{exec as Sh}from"child_process";import*as Ge from"fs/promises";import*as Te from"path";var Ih=".hydra/worktree.json",Ah=".worktreeinclude",Ch=120;async function Ys(s){let e=await ce(Te.join(s,Ih))??{},t=new Set(Array.isArray(e.carry)?e.carry:[]),n=await Ge.readFile(Te.join(s,Ah),"utf8").catch(()=>{});if(n!==void 0)for(let o of n.split(`
148
+ `)){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 ri(s,e,t){let n=[],r=[],o=Te.resolve(s),i=Te.resolve(e);for(let a of t){let d=Te.resolve(o,a),c=Te.resolve(i,a);if(!d.startsWith(o+Te.sep)||!c.startsWith(i+Te.sep)){r.push(a);continue}if(await Ge.access(c).then(()=>!0).catch(()=>!1)){r.push(a);continue}let l=await Ge.stat(d).catch(()=>{});if(l===void 0){r.push(a);continue}try{await Ge.mkdir(Te.dirname(c),{recursive:!0}),await Ge.cp(d,c,{recursive:l.isDirectory(),dereference:!0}),n.push(a)}catch{r.push(a)}}return{copied:n,skipped:r}}async function Xs(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??Ch)*1e3;return new Promise(r=>{let o=Sh(s,{cwd:e.workspacePath,timeout:n,maxBuffer:8388608,windowsHide:!0,env:{...process.env,HYDRA_WORKSPACE_PATH:e.workspacePath,HYDRA_SOURCE_CWD:e.sourceCwd,HYDRA_WORKSPACE_LABEL:e.label,...e.sessionId!==void 0?{HYDRA_SESSION_ID:e.sessionId}:{}}},(i,a,d)=>{if(i){let c=(d||i.message||"").trim().slice(0,500);r({ok:!1,reason:c.length>0?c:"hook failed"});return}r({ok:!0})});o.stdin?.on("error",()=>{}),o.stdin?.end(t)})}Q();He();import*as st from"fs/promises";import{z as Le}from"zod";var Rh=Le.object({version:Le.literal(1),agentId:Le.string(),upstreamSessionId:Le.string(),sessionId:Le.string().optional(),deletedAt:Le.string(),upstreamUpdatedAt:Le.string().optional(),cwd:Le.string().optional(),title:Le.string().optional(),reason:Le.enum(["user","expired"]).optional(),interactive:Le.boolean().optional()}),Zs=class{async add(e){let t={version:1,...e};await me(E.tombstoneFile(e.agentId,e.upstreamSessionId),t,{mode:384})}async has(e,t){try{return await st.access(E.tombstoneFile(e,t)),!0}catch{return!1}}async read(e,t){let n=E.tombstoneFile(e,t),r=await ce(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 Rh.parse(r)}catch{return{version:1,agentId:e,upstreamSessionId:t,deletedAt:new Date(0).toISOString()}}}async remove(e,t){try{await st.unlink(E.tombstoneFile(e,t))}catch(n){if(n.code!=="ENOENT")throw n}try{await st.rmdir(E.tombstoneAgentDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}}async list(e){if(e!==void 0)return this.listForAgent(e);let t;try{t=await st.readdir(E.tombstonesDir())}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}n.push(...await this.listForAgent(o))}return n}async listForAgent(e){let t;try{t=await st.readdir(E.tombstoneAgentDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=[];for(let r of t){let o;try{o=decodeURIComponent(r)}catch{continue}let i=await this.read(e,o);i&&n.push(i)}return n}};function Pc(s,e){return s.reason==="user"||e===void 0?!1:s.upstreamUpdatedAt===void 0?!0:e>s.upstreamUpdatedAt}import*as qc from"fs/promises";import{customAlphabet as Nh}from"nanoid";import{fileURLToPath as xh}from"url";import*as Wn from"path";import*as er from"fs";function Th(){try{let s=Wn.dirname(xh(import.meta.url));for(let e=0;e<8;e+=1){let t=Wn.join(s,"package.json");if(er.existsSync(t)){let r=JSON.parse(er.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=Wn.dirname(s);if(n===s)break;s=n}}catch{}return"0.0.0"}var ue=Th(),tr="hydra-acp-cat";var Eh=12e4;async function _c(s,e,t){let n=s.timeoutMs??Eh,r,o,i=!1;try{let a=(async()=>{r=ut.spawn({agentId:s.agentId,cwd:s.cwd,plan:s.plan,logger:s.logger});let d=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:{},clientInfo:{name:"hydra-synopsis",version:ue}}),c=await r.connection.request("session/new",{cwd:s.cwd,mcpServers:[]}),u=c.sessionId;if(typeof u!="string"){s.logger?.warn(`synopsis: agent ${s.agentId} returned non-string sessionId from session/new`),s.onFailure?.(`agent ${s.agentId} did not return a sessionId from session/new`);return}if(s.onWorkerSpawned?.(u,r.pid),s.modelId){let f=Mh(c);if(f.size===0||f.has(s.modelId)){let k=r.connection;try{await lt({request:(g,p)=>k.request(g,p),sessionId:u,modelId:s.modelId,verb:zt(c),logger:s.logger})}catch(g){s.logger?.warn(`synopsis: agent ${s.agentId} rejected model change to ${JSON.stringify(s.modelId)}: ${g.message}; continuing on default`)}}else s.logger?.warn(`synopsis: model ${JSON.stringify(s.modelId)} not advertised by agent ${s.agentId} (have [${[...f].join(", ")}]); continuing on default`)}let l=[];r.connection.onNotification("session/update",f=>{let k=Ph(f);k.length>0&&l.push(k)}),await r.connection.request("session/prompt",{sessionId:u,prompt:[{type:"text",text:e}]});let y=l.join(""),h=t(y);if(!h){let f=JSON.stringify(y.slice(0,200));s.logger?.warn(`synopsis: agent ${s.agentId} reply did not parse (replyLen=${y.length} preview=${f})`);let k=y.slice(0,120).replace(/\s+/g," ").trim();s.onFailure?.(`agent ${s.agentId} returned unparseable JSON (${y.length} chars): ${k}${y.length>120?"\u2026":""}`)}return h})();return await new Promise((d,c)=>{o=setTimeout(()=>{i=!0,s.logger?.warn(`synopsis: agent ${s.agentId} timed out after ${n}ms`),s.onFailure?.(`agent ${s.agentId} timed out after ${n}ms`),d(void 0)},n),o.unref?.(),a.then(u=>{o&&clearTimeout(o),i||d(u)},u=>{o&&clearTimeout(o),i||c(u)})})}catch(a){let d=a.message;s.logger?.warn(`synopsis: agent ${s.agentId} failed: ${d}`),s.onFailure?.(`agent ${s.agentId} failed: ${d}`);return}finally{o&&clearTimeout(o),r&&await r.kill().catch(()=>{})}}async function nr(s){let e=Zt(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}
138
149
 
139
150
  ${e}
140
151
 
141
- ${Eo}`:`${t}
152
+ ${Wo}`:`${t}
142
153
 
143
- ${Eo}`;return lc(s,n,Kd)}async function fc(s){let e=Qt(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}
154
+ ${Wo}`;return _c(s,n,hc)}async function $c(s){let e=Zt(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}
144
155
 
145
156
  ${e}
146
157
 
147
- ${Po}`:`${t}
158
+ ${qo}`:`${t}
148
159
 
149
- ${Po}`;return lc(s,n,Qd)}function rh(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 oh(s){let e=new Set;uc(e,s.availableModels);let t=s.models;return t&&typeof t=="object"&&!Array.isArray(t)&&uc(e,t.availableModels),e}function uc(s,e){if(Array.isArray(e)){for(let t of e)if(t&&typeof t=="object"){let n=t.modelId??t.value??t.id;typeof n=="string"&&n.length>0&&s.add(n)}}}var ih="guardian_assessment:",ah="Guardian Review";function pc(s,e){return s!==void 0&&s.startsWith(ih)||e===ah}function dh(s){let e=new Map;for(let t of kc(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 hc(s){return dh(s).map(e=>e.name)}function ch(s){let e=new Map;for(let t of kc(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 yc(s){return ch(s).map(e=>e.path)}function wc(s){let e=0;for(let t of s)t.params?.update?.sessionUpdate==="prompt_received"&&(e+=1);return e}function kc(s){let e=new Map,t=0;for(let n of s){let o=n.params?.update;if(!o)continue;let i=o.sessionUpdate;if(i!=="tool_call"&&i!=="tool_call_update")continue;if(i==="tool_call"){let d=typeof o.toolCallId=="string"&&o.toolCallId.length>0?o.toolCallId:void 0,c=typeof o.title=="string"?o.title:void 0;if(pc(d,c))continue;let u=d??`__synth_${t++}`,l=e.get(u);l===void 0?(l={toolName:gc(o),paths:new Set},e.set(u,l)):l.toolName=gc(o);for(let w of mc(o.rawInput,o.locations))l.paths.add(w);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 mc(o.rawInput,o.locations))a.paths.add(d)}return e}function gc(s){return typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function mc(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 Ga(e))t.add(n);return t}Q();var lh=uh("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",12),fh=2,Js=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??fh}opts;queued={};inflight=new Map;stopped=!1;maxConcurrent;schedule(e){this.stopped||this.inflight.has(e)||e in this.queued||(this.queued[e]={kind:"title"},this.drain())}scheduleCompaction(e,t){if(this.stopped)return;let n=t?.targetAgentId;if(this.inflight.has(e))return;let r=this.queued[e];if(r&&r.kind==="title"){this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}};return}this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}},this.drain()}size(){return{queued:Object.keys(this.queued).length,inflight:this.inflight.size}}async flush(e){let t=Date.now()+e;for(;Object.keys(this.queued).length>0||this.inflight.size>0;){let n=t-Date.now();if(n<=0)return;let r=[...this.inflight.values()];if(r.length===0){await new Promise(o=>{setTimeout(o,25).unref?.()});continue}await Promise.race([Promise.race(r),new Promise(o=>{setTimeout(o,n).unref?.()})])}}async shutdown(){this.stopped=!0,this.queued={},await Promise.allSettled([...this.inflight.values()])}drain(){if(!this.stopped)for(;this.inflight.size<this.maxConcurrent&&Object.keys(this.queued).length>0;){let t=Object.keys(this.queued)[0];if(!t)return;let n=this.queued[t];delete this.queued[t];let r=this.runOne(t,n).finally(()=>{this.inflight.delete(t),this.drain()});this.inflight.set(t,r)}}async runOne(e,t){let n=t.kind,r=t.targetAgentId;try{let o=await this.opts.store.read(e);if(!o){this.opts.logger?.info(`synopsis: session ${e} record missing; skipping`);return}let i=await this.opts.histories.load(e,{maxEntries:1/0}),a=o.summarizedThroughEntry;if(a!==void 0&&i.length===a){this.opts.logger?.info(`synopsis: skip ${e} (history unchanged at ${i.length})`);return}a!==void 0&&i.length<a&&this.opts.logger?.warn(`synopsis: watermark ahead of history (last=${a} history=${i.length}) for ${e} \u2014 re-baselining`);let d=n==="compaction"?r??this.opts.compactionAgent??o.agentId:this.opts.synopsisAgent??o.agentId,c=await this.opts.registry.getAgent(d);if(!c){this.opts.logger?.warn(`synopsis: agent ${d} not in registry for session ${e}; skipping`);return}let u=await Me(c,[],{npmRegistry:this.opts.npmRegistry}),l=this.opts.compactionAgent===void 0&&r===void 0,w=n==="compaction"?this.opts.compactionModel??(l?o.currentModel:void 0):this.opts.synopsisModel,h=E.sessionDir(e);if(await Ic.mkdir(h,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(w??"(default)")} cwd=${h}`),n==="compaction"){let f=this.opts.compactionMaxIterations??3,k=0,p=a??0,g,y=0,m,v=Date.now(),S=lh(),b={targetAgentId:r},I=T=>this.opts.onCompactionStateChange?.(e,{runId:S,...T},b)??Promise.resolve(),A=T=>{this.opts.broadcastHydraCompaction?.(e,T,b)};await I({status:"requested",requestedAt:v}),A({sessionUpdate:"_hydra_compaction",phase:"started",requestedAt:v});try{do{k++,this.opts.logger?.info(`synopsis: compaction iteration ${k} sessionId=${e} historyLen=${i.length} watermark=${p}`);let T=await this.opts.histories.load(e,{maxEntries:1/0});if(T.length===p)break;let R=await fc({agentId:d,cwd:h,plan:u,history:T,modelId:w,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:($,H)=>{I({status:"running",requestedAt:v,iter:k,worker:{upstreamSessionId:$,pid:H??0}})},onFailure:$=>{m=$}});if(R){let $=vc(R.synopsis,T);$&&bc($)&&(await this.opts.persistSynopsis(e,$,T.length),g=$,y=T.length,m=void 0,await I({status:"running",requestedAt:v,iter:k}),A({sessionUpdate:"_hydra_compaction",phase:"iteration",iter:k,historyLen:T.length}),await this.opts.onSynthesisArtifact?.(e,$,y,r,S),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${k} fields=${Sc($)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${k} returned no result`);if(p=T.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===p)break}while(k<f);if(g)this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} runId=${S} watermark=${y} iterations=${k}`+(k>=f?` (hit maxIterations=${f})`:"")),A({sessionUpdate:"_hydra_compaction",phase:"converged",iter:k,summarizedThroughEntry:y});else{k>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${f} without producing artifact sessionId=${e}: ${m??"no reason captured"}`);let T=m??(k===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${k} iteration(s)`);await I({status:"failed",requestedAt:v,iter:k,lastError:T}),A({sessionUpdate:"_hydra_compaction",phase:"failed",error:T}),r&&await this.opts.onSynthesisUnavailable?.(e,r,T)}}catch(T){let R=T instanceof Error?T.message:String(T);if(this.opts.logger?.warn(`synopsis: compaction threw for sessionId=${e}: ${R}`),await I({status:"failed",requestedAt:v,iter:k,lastError:R}),this.opts.broadcastHydraCompaction?.(e,{sessionUpdate:"_hydra_compaction",phase:"failed",error:R},{targetAgentId:r}),r)try{await this.opts.onSynthesisUnavailable?.(e,r,R)}catch{}}}else{let f=await zs({agentId:d,cwd:h,plan:u,history:i,modelId:w,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs});if(!f){this.opts.logger?.warn(`synopsis: sessionId=${e} no parseable result; not persisting`);return}let k=vc(f.synopsis,i);k&&bc(k)?(await this.opts.persistSynopsis(e,k,i.length),f.title&&await this.opts.persistTitle(e,f.title),this.opts.logger?.info(`synopsis: persisted sessionId=${e} title=${JSON.stringify(!!f.title)} fields=${Sc(k)}`)):f.title&&(await this.opts.persistTitle(e,f.title),this.opts.logger?.info(`synopsis: persisted title only sessionId=${e}`))}}catch(o){this.opts.logger?.warn(`synopsis: sessionId=${e} failed: ${o.message}`)}}};function vc(s,e){let t=yc(e),n=hc(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 bc(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 Sc(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(",")}]`}Q();import*as G from"fs/promises";import{createReadStream as kh}from"fs";import{createGunzip as vh,gzip as bh,gunzip as Sh}from"zlib";import{createInterface as Ih}from"readline";import{promisify as Ec}from"util";function Ac(s){return s==="summary"?"summary":"inline"}var zo=256,ph=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],gh=["content","stdout","stderr"];function Cc(s,e){return e!=="summary"?s:s.map(mh)}function mh(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(Rc));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=Vs(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let c of ph)a[c]!==void 0&&(d[c]=a[c]);for(let c of gh)typeof a[c]=="string"&&(d[c]=Vs(a[c]));o.rawOutput=d}return{...s,params:{...t,update:o}}}function hh(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&s.type==="diff"}function Rc(s){if(hh(s)){let n=s,r={type:"diff",oldText:"",newText:""};return typeof n.path=="string"&&(r.path=n.path),r}if(!s||typeof s!="object"||Array.isArray(s))return s;let e=s,t={...e};return typeof e.text=="string"&&(t.text=Vs(e.text)),typeof e.content=="string"?t.content=Vs(e.content):e.content&&typeof e.content=="object"&&(t.content=Rc(e.content)),t}function Vs(s){if(typeof s=="string"&&s.length>zo){let e=s.length-zo;return`${s.slice(0,zo)}\u2026[+${e} chars omitted from summary export]`}return s}var yh=2048;function xc(s){let e=new Set,t=n=>{if(Tc(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 Tc(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.__hydraBlob=="string"}function wh(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 Go(s,e){if(!wh(s))return s;let t=s.params,n=t.update,r=await Jo(n,e);return{...s,params:{...t,update:r}}}async function Jo(s,e){if(typeof s=="string"){if(s.length<=yh)return s;let t=await e(s);return t===null?s:{__hydraBlob:t,bytes:s.length}}if(Array.isArray(s)){let t=[];for(let n of s)t.push(await Jo(n,e));return t}if(s&&typeof s=="object"){let t={};for(let[n,r]of Object.entries(s))t[n]=await Jo(r,e);return t}return s}async function Ko(s,e){let t=s.params;if(!t||typeof t!="object"||Array.isArray(t))return s;let n=await Vo(t,e);return n===t?s:{...s,params:n}}async function Vo(s,e){if(Tc(s))return await e(s.__hydraBlob)??"";if(Array.isArray(s)){let t=!1,n=[];for(let r of s){let o=await Vo(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 Vo(o,e);i!==o&&(t=!0),n[r]=i}return t?n:s}return s}function Hn(s,e){let t=-1;for(let n=s.length-1;n>=0;n--)if(s[n]?.messageId===e){t=n;break}if(t<0)return-1;for(let n=t;n<s.length;n++){let r=s[n]?.sessionUpdate;if(r==="turn_complete"||r==="_hydra_turn_ended")return n;if(n>t&&(r==="prompt_received"||r==="_hydra_turn_started"))return n-1}return s.length-1}function Qo(s){return s.map(e=>e.method==="session/update"?e.params?.update:void 0)}var Ah=Ec(bh),Ch=Ec(Sh),Rh=/^history\.jsonl\.(\d+)(\.gz)?$/,$e=/^[A-Za-z0-9_-]+$/;function xh(s){try{let e=JSON.parse(s);return e.method==="session/update"?e.params?.update:void 0}catch{return}}var Th=1e3,Eh=1e7,Ph=10,Gs=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??Th,this.archiveMaxBytes=e.archiveMaxBytes??Eh,this.archiveTiers=e.archiveTiers??Ph}async append(e,t){if($e.test(e))return this.enqueue(e,async()=>{await G.mkdir(E.sessionDir(e),{recursive:!0});let n=await Go(t,o=>Wr(e,o)),r=JSON.stringify(n)+`
150
- `;await G.appendFile(E.historyFile(e),r,{encoding:"utf8",mode:384})})}async rewrite(e,t){if($e.test(e))return this.enqueue(e,async()=>{await G.mkdir(E.sessionDir(e),{recursive:!0});let n=[];for(let o of t)n.push(await Go(o,i=>Wr(e,i)));let r=n.length===0?"":n.map(o=>JSON.stringify(o)).join(`
160
+ ${qo}`;return _c(s,n,yc)}function Ph(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 Mh(s){let e=new Set;Mc(e,s.availableModels);let t=s.models;return t&&typeof t=="object"&&!Array.isArray(t)&&Mc(e,t.availableModels),e}function Mc(s,e){if(Array.isArray(e)){for(let t of e)if(t&&typeof t=="object"){let n=t.modelId??t.value??t.id;typeof n=="string"&&n.length>0&&s.add(n)}}}var _h="guardian_assessment:",$h="Guardian Review";function Fc(s,e){return s!==void 0&&s.startsWith(_h)||e===$h}function Fh(s){let e=new Map;for(let t of jc(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 Dc(s){return Fh(s).map(e=>e.name)}function Oh(s){let e=new Map;for(let t of jc(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 Lc(s){return Oh(s).map(e=>e.path)}function Hc(s){let e=0;for(let t of s)t.params?.update?.sessionUpdate==="prompt_received"&&(e+=1);return e}function jc(s){let e=new Map,t=0;for(let n of s){let o=n.params?.update;if(!o)continue;let i=o.sessionUpdate;if(i!=="tool_call"&&i!=="tool_call_update")continue;if(i==="tool_call"){let d=typeof o.toolCallId=="string"&&o.toolCallId.length>0?o.toolCallId:void 0,c=typeof o.title=="string"?o.title:void 0;if(Fc(d,c))continue;let u=d??`__synth_${t++}`,l=e.get(u);l===void 0?(l={toolName:Oc(o),paths:new Set},e.set(u,l)):l.toolName=Oc(o);for(let y of Nc(o.rawInput,o.locations))l.paths.add(y);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 Nc(o.rawInput,o.locations))a.paths.add(d)}return e}function Oc(s){return typeof s.name=="string"&&s.name.length>0?s.name:typeof s.title=="string"&&s.title.length>0?s.title:"(unnamed)"}function Nc(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 ud(e))t.add(n);return t}Q();var Dh=Nh("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",12),Lh=2,sr=class{constructor(e){this.opts=e;this.maxConcurrent=e.maxConcurrent??Lh}opts;queued={};inflight=new Map;stopped=!1;maxConcurrent;schedule(e){this.stopped||this.inflight.has(e)||e in this.queued||(this.queued[e]={kind:"title"},this.drain())}scheduleCompaction(e,t){if(this.stopped)return;let n=t?.targetAgentId;if(this.inflight.has(e))return;let r=this.queued[e];if(r&&r.kind==="title"){this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}};return}this.queued[e]={kind:"compaction",...n?{targetAgentId:n}:{}},this.drain()}size(){return{queued:Object.keys(this.queued).length,inflight:this.inflight.size}}async flush(e){let t=Date.now()+e;for(;Object.keys(this.queued).length>0||this.inflight.size>0;){let n=t-Date.now();if(n<=0)return;let r=[...this.inflight.values()];if(r.length===0){await new Promise(o=>{setTimeout(o,25).unref?.()});continue}await Promise.race([Promise.race(r),new Promise(o=>{setTimeout(o,n).unref?.()})])}}async shutdown(){this.stopped=!0,this.queued={},await Promise.allSettled([...this.inflight.values()])}drain(){if(!this.stopped)for(;this.inflight.size<this.maxConcurrent&&Object.keys(this.queued).length>0;){let t=Object.keys(this.queued)[0];if(!t)return;let n=this.queued[t];delete this.queued[t];let r=this.runOne(t,n).finally(()=>{this.inflight.delete(t),this.drain()});this.inflight.set(t,r)}}async runOne(e,t){let n=t.kind,r=t.targetAgentId;try{let o=await this.opts.store.read(e);if(!o){this.opts.logger?.info(`synopsis: session ${e} record missing; skipping`);return}let i=await this.opts.histories.load(e,{maxEntries:1/0}),a=o.summarizedThroughEntry;if(a!==void 0&&i.length===a){this.opts.logger?.info(`synopsis: skip ${e} (history unchanged at ${i.length})`);return}a!==void 0&&i.length<a&&this.opts.logger?.warn(`synopsis: watermark ahead of history (last=${a} history=${i.length}) for ${e} \u2014 re-baselining`);let d=n==="compaction"?r??this.opts.compactionAgent??o.agentId:this.opts.synopsisAgent??o.agentId,c=await this.opts.registry.getAgent(d);if(!c){this.opts.logger?.warn(`synopsis: agent ${d} not in registry for session ${e}; skipping`);return}let u=await Me(c,[],{npmRegistry:this.opts.npmRegistry}),l=this.opts.compactionAgent===void 0&&r===void 0,y=n==="compaction"?this.opts.compactionModel??(l?o.currentModel:void 0):this.opts.synopsisModel,h=E.sessionDir(e);if(await qc.mkdir(h,{recursive:!0}).catch(()=>{}),this.opts.logger?.info(`synopsis: start sessionId=${e} agentId=${d} historyLen=${i.length} model=${JSON.stringify(y??"(default)")} cwd=${h}`),n==="compaction"){let f=this.opts.compactionMaxIterations??3,k=0,g=a??0,p,w=0,m,v=Date.now(),S=Dh(),b={targetAgentId:r},I=T=>this.opts.onCompactionStateChange?.(e,{runId:S,...T},b)??Promise.resolve(),A=T=>{this.opts.broadcastHydraCompaction?.(e,T,b)};await I({status:"requested",requestedAt:v}),A({sessionUpdate:"_hydra_compaction",phase:"started",requestedAt:v});try{do{k++,this.opts.logger?.info(`synopsis: compaction iteration ${k} sessionId=${e} historyLen=${i.length} watermark=${g}`);let T=await this.opts.histories.load(e,{maxEntries:1/0});if(T.length===g)break;let R=await $c({agentId:d,cwd:h,plan:u,history:T,modelId:y,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs,onWorkerSpawned:($,L)=>{I({status:"running",requestedAt:v,iter:k,worker:{upstreamSessionId:$,pid:L??0}})},onFailure:$=>{m=$}});if(R){let $=Uc(R.synopsis,T);$&&Bc($)&&(await this.opts.persistSynopsis(e,$,T.length),p=$,w=T.length,m=void 0,await I({status:"running",requestedAt:v,iter:k}),A({sessionUpdate:"_hydra_compaction",phase:"iteration",iter:k,historyLen:T.length}),await this.opts.onSynthesisArtifact?.(e,$,w,r,S),this.opts.logger?.info(`synopsis: persisted compaction sessionId=${e} iteration=${k} fields=${Wc($)}`))}else this.opts.logger?.warn(`synopsis: sessionId=${e} compaction iteration ${k} returned no result`);if(g=T.length,(await this.opts.histories.load(e,{maxEntries:1/0})).length===g)break}while(k<f);if(p)this.opts.logger?.info(`synopsis: compaction converged sessionId=${e} runId=${S} watermark=${w} iterations=${k}`+(k>=f?` (hit maxIterations=${f})`:"")),A({sessionUpdate:"_hydra_compaction",phase:"converged",iter:k,summarizedThroughEntry:w});else{k>0&&this.opts.logger?.warn(`synopsis: compaction hit maxIterations=${f} without producing artifact sessionId=${e}: ${m??"no reason captured"}`);let T=m??(k===0?"no new history to compact since last summary":`compaction did not produce an artifact after ${k} iteration(s)`);await I({status:"failed",requestedAt:v,iter:k,lastError:T}),A({sessionUpdate:"_hydra_compaction",phase:"failed",error:T}),r&&await this.opts.onSynthesisUnavailable?.(e,r,T)}}catch(T){let R=T instanceof Error?T.message:String(T);if(this.opts.logger?.warn(`synopsis: compaction threw for sessionId=${e}: ${R}`),await I({status:"failed",requestedAt:v,iter:k,lastError:R}),this.opts.broadcastHydraCompaction?.(e,{sessionUpdate:"_hydra_compaction",phase:"failed",error:R},{targetAgentId:r}),r)try{await this.opts.onSynthesisUnavailable?.(e,r,R)}catch{}}}else{let f=await nr({agentId:d,cwd:h,plan:u,history:i,modelId:y,sessionId:e,logger:this.opts.logger,timeoutMs:this.opts.generateTimeoutMs});if(!f){this.opts.logger?.warn(`synopsis: sessionId=${e} no parseable result; not persisting`);return}let k=Uc(f.synopsis,i);k&&Bc(k)?(await this.opts.persistSynopsis(e,k,i.length),f.title&&await this.opts.persistTitle(e,f.title),this.opts.logger?.info(`synopsis: persisted sessionId=${e} title=${JSON.stringify(!!f.title)} fields=${Wc(k)}`)):f.title&&(await this.opts.persistTitle(e,f.title),this.opts.logger?.info(`synopsis: persisted title only sessionId=${e}`))}}catch(o){this.opts.logger?.warn(`synopsis: sessionId=${e} failed: ${o.message}`)}}};function Uc(s,e){let t=Lc(e),n=Dc(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 Bc(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 Wc(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(",")}]`}Q();import*as K from"fs/promises";import{createReadStream as zh}from"fs";import{createGunzip as Jh,gzip as Vh,gunzip as Gh}from"zlib";import{createInterface as Kh}from"readline";import{promisify as Qc}from"util";function zc(s){return s==="summary"?"summary":"inline"}var oi=256,Hh=["totalMatches","totalFiles","referenceCount","truncated","exitCode"],jh=["content","stdout","stderr"];function Jc(s,e){return e!=="summary"?s:s.map(Uh)}function Uh(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(Vc));let i=r.rawOutput;if(i&&typeof i=="object"&&!Array.isArray(i)){let a=i,d={};a.error!==void 0&&(d.error=rr(a.error)),a.metadata!==void 0&&(d.metadata=a.metadata);for(let c of Hh)a[c]!==void 0&&(d[c]=a[c]);for(let c of jh)typeof a[c]=="string"&&(d[c]=rr(a[c]));o.rawOutput=d}return{...s,params:{...t,update:o}}}function Bh(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&s.type==="diff"}function Vc(s){if(Bh(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=rr(e.text)),typeof e.content=="string"?t.content=rr(e.content):e.content&&typeof e.content=="object"&&(t.content=Vc(e.content)),t}function rr(s){if(typeof s=="string"&&s.length>oi){let e=s.length-oi;return`${s.slice(0,oi)}\u2026[+${e} chars omitted from summary export]`}return s}var Wh=2048;function Gc(s){let e=new Set,t=n=>{if(Kc(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 Kc(s){return!!s&&typeof s=="object"&&!Array.isArray(s)&&typeof s.__hydraBlob=="string"}function qh(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 di(s,e){if(!qh(s))return s;let t=s.params,n=t.update,r=await ii(n,e);return{...s,params:{...t,update:r}}}async function ii(s,e){if(typeof s=="string"){if(s.length<=Wh)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 ii(n,e));return t}if(s&&typeof s=="object"){let t={};for(let[n,r]of Object.entries(s))t[n]=await ii(r,e);return t}return s}async function ci(s,e){let t=s.params;if(!t||typeof t!="object"||Array.isArray(t))return s;let n=await ai(t,e);return n===t?s:{...s,params:n}}async function ai(s,e){if(Kc(s))return await e(s.__hydraBlob)??"";if(Array.isArray(s)){let t=!1,n=[];for(let r of s){let o=await ai(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 ai(o,e);i!==o&&(t=!0),n[r]=i}return t?n:s}return s}function qn(s,e){let t=-1;for(let n=s.length-1;n>=0;n--)if(s[n]?.messageId===e){t=n;break}if(t<0)return-1;for(let n=t;n<s.length;n++){let r=s[n]?.sessionUpdate;if(r==="turn_complete"||r==="_hydra_turn_ended")return n;if(n>t&&(r==="prompt_received"||r==="_hydra_turn_started"))return n-1}return s.length-1}function ui(s){return s.map(e=>e.method==="session/update"?e.params?.update:void 0)}var Qh=Qc(Vh),Yh=Qc(Gh),Xh=/^history\.jsonl\.(\d+)(\.gz)?$/,$e=/^[A-Za-z0-9_-]+$/;function Zh(s){try{let e=JSON.parse(s);return e.method==="session/update"?e.params?.update:void 0}catch{return}}var ey=1e3,ty=1e7,ny=10,or=class{writeQueues=new Map;maxEntries;archiveMaxBytes;archiveTiers;nextArchiveIndex=new Map;archiveLineCounts=new Map;constructor(e={}){this.maxEntries=e.maxEntries??ey,this.archiveMaxBytes=e.archiveMaxBytes??ty,this.archiveTiers=e.archiveTiers??ny}async append(e,t){if($e.test(e))return this.enqueue(e,async()=>{await K.mkdir(E.sessionDir(e),{recursive:!0});let n=await di(t,o=>eo(e,o)),r=JSON.stringify(n)+`
161
+ `;await K.appendFile(E.historyFile(e),r,{encoding:"utf8",mode:384})})}async rewrite(e,t){if($e.test(e))return this.enqueue(e,async()=>{await K.mkdir(E.sessionDir(e),{recursive:!0});let n=[];for(let o of t)n.push(await di(o,i=>eo(e,i)));let r=n.length===0?"":n.map(o=>JSON.stringify(o)).join(`
151
162
  `)+`
152
- `;await G.writeFile(E.historyFile(e),r,{encoding:"utf8",mode:384})})}async truncateAfterTurn(e,t){if(!$e.test(e))return;let n;return await this.enqueue(e,async()=>{let r="";try{r=await G.readFile(E.historyFile(e),"utf8")}catch(d){if(d.code!=="ENOENT")throw d}let o=r.split(`
153
- `).filter(d=>d.length>0),i=0;if(t!==null){let d=Hn(o.map(xh),t);if(d<0)return;i=d+1}let a=o.slice(0,i);if(await G.writeFile(E.historyFile(e),a.length===0?"":a.join(`
163
+ `;await K.writeFile(E.historyFile(e),r,{encoding:"utf8",mode:384})})}async truncateAfterTurn(e,t){if(!$e.test(e))return;let n;return await this.enqueue(e,async()=>{let r="";try{r=await K.readFile(E.historyFile(e),"utf8")}catch(d){if(d.code!=="ENOENT")throw d}let o=r.split(`
164
+ `).filter(d=>d.length>0),i=0;if(t!==null){let d=qn(o.map(Zh),t);if(d<0)return;i=d+1}let a=o.slice(0,i);if(await K.writeFile(E.historyFile(e),a.length===0?"":a.join(`
154
165
  `)+`
155
- `,{encoding:"utf8",mode:384}),t===null){for(let d of await this.listArchiveIndices(e))await this.unlinkArchive(e,d);this.nextArchiveIndex.delete(e)}this.archiveLineCounts.delete(e),n={kept:a.length,removed:o.length-a.length}}),n}async compact(e,t){if($e.test(e))return this.enqueue(e,async()=>{let n;try{n=await G.readFile(E.historyFile(e),"utf8")}catch(a){if(a.code==="ENOENT")return;throw a}let r=n.split(`
156
- `).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 G.writeFile(E.historyFile(e),i.join(`
166
+ `,{encoding:"utf8",mode:384}),t===null){for(let d of await this.listArchiveIndices(e))await this.unlinkArchive(e,d);this.nextArchiveIndex.delete(e)}this.archiveLineCounts.delete(e),n={kept:a.length,removed:o.length-a.length}}),n}async compact(e,t){if($e.test(e))return this.enqueue(e,async()=>{let n;try{n=await K.readFile(E.historyFile(e),"utf8")}catch(a){if(a.code==="ENOENT")return;throw a}let r=n.split(`
167
+ `).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 K.writeFile(E.historyFile(e),i.join(`
157
168
  `)+`
158
169
  `,{encoding:"utf8",mode:384})})}async spillToArchive(e,t){let n=t.join(`
159
170
  `)+`
160
- `,r=await this.resolveNextArchiveIndex(e);await this.enforceArchiveTierCap(e,r);let o=E.historyArchiveFile(e,r);await G.mkdir(E.sessionDir(e),{recursive:!0}),await G.appendFile(o,n,{encoding:"utf8",mode:384});let i=0;try{i=(await G.stat(o)).size}catch{i=0}i>=this.archiveMaxBytes?(await this.sealArchive(e,r),this.nextArchiveIndex.set(e,r+1)):this.nextArchiveIndex.set(e,r),this.archiveLineCounts.delete(e)}async sealArchive(e,t){let n=E.historyArchiveFile(e,t),r;try{r=await G.readFile(n)}catch(i){if(i.code==="ENOENT")return;throw i}let o=await Ah(r);await G.writeFile(n+".gz",o,{mode:384});try{await G.unlink(n)}catch(i){if(i.code!=="ENOENT")throw i}}async resolveNextArchiveIndex(e){let t=this.nextArchiveIndex.get(e);if(t!==void 0)return t;let n=await this.listArchiveIndices(e),r=n.length===0?0:n[n.length-1],o=r===0?1:r;if(r>0){let i=E.historyArchiveFile(e,r),a=i+".gz",d=!1;try{await G.access(a),d=!0}catch{d=!1}if(d)o=r+1;else try{(await G.stat(i)).size>=this.archiveMaxBytes&&(o=r+1)}catch{o=r}}return this.nextArchiveIndex.set(e,o),o}async enforceArchiveTierCap(e,t){if(this.archiveTiers<=0)return;let n=await this.listArchiveIndices(e),o=(n.includes(t)?n.length:n.length+1)-this.archiveTiers,i=0;for(;o>0&&i<n.length;){let a=n[i];a!==t&&(await this.unlinkArchive(e,a),o-=1),i+=1}}async unlinkArchive(e,t){let n=E.historyArchiveFile(e,t);for(let r of[n,n+".gz"])try{await G.unlink(r)}catch(o){if(o.code!=="ENOENT")throw o}this.archiveLineCounts.delete(e)}async listArchiveIndices(e){let t;try{t=await G.readdir(E.sessionDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=new Set;for(let r of t){let o=Rh.exec(r);if(!o)continue;let i=Number.parseInt(o[1],10);Number.isFinite(i)&&i>0&&n.add(i)}return[...n].sort((r,o)=>r-o)}async listArchives(e){if(!$e.test(e))return[];let t=await this.listArchiveIndices(e),n=[];for(let r of t){let o=E.historyArchiveFile(e,r),i=o+".gz",a=o;try{await G.access(i),a=i}catch{a=o}n.push({index:r,path:a})}return n}async loadArchives(e){if(!$e.test(e))return[];let t=this.writeQueues.get(e);t&&await t;let n=await this.listArchives(e),r=[];for(let{path:o}of n){let i;try{if(o.endsWith(".gz")){let a=await G.readFile(o);i=(await Ch(a)).toString("utf8")}else i=await G.readFile(o,"utf8")}catch(a){if(a.code==="ENOENT")continue;throw a}for(let a of i.split(`
161
- `)){if(a.length===0)continue;let d;try{d=JSON.parse(a)}catch{continue}if(!d||typeof d!="object"||Array.isArray(d))continue;let c=d;typeof c.method=="string"&&typeof c.recordedAt=="number"&&r.push({method:c.method,params:c.params,recordedAt:c.recordedAt,...typeof c.seq=="number"?{seq:c.seq}:{}})}}return r}async*streamFile(e){let t;try{t=kh(e)}catch(i){if(i.code==="ENOENT")return;throw i}if(await new Promise(i=>{let a=!1,d=c=>{a||(a=!0,i(c))};t.once("error",c=>{c.code==="ENOENT"?d(!0):(t.destroy(),d(!1))}),t.once("readable",()=>d(!1)),t.once("end",()=>d(!1))}))return;let r=e.endsWith(".gz")?t.pipe(vh()):t,o=Ih({input:r,crlfDelay:1/0});try{for await(let i of o){if(i.length===0)continue;let a;try{a=JSON.parse(i)}catch{continue}if(!a||typeof a!="object"||Array.isArray(a))continue;let d=a;typeof d.method=="string"&&typeof d.recordedAt=="number"&&(yield{method:d.method,params:d.params,recordedAt:d.recordedAt,...typeof d.seq=="number"?{seq:d.seq}:{}})}}finally{o.close(),t.destroy()}}async getArchiveLineCounts(e){if(!$e.test(e))return[];let t=this.archiveLineCounts.get(e),n=await this.listArchives(e);if(t&&t.length===n.length&&t.every((o,i)=>o.index===n[i].index&&o.path===n[i].path))return t;let r=[];for(let{index:o,path:i}of n){let a=t?.find(c=>c.index===o&&c.path===i);if(a){r.push(a);continue}let d=0;for await(let c of this.streamFile(i))d+=1;r.push({index:o,path:i,lineCount:d})}return this.archiveLineCounts.set(e,r),r}async hydrate(e,t){let n=new Map,r=[];for(let o of t)r.push(await this.hydrateEntry(e,o,n));return r}async hydrateEntry(e,t,n){return Ko(t,async r=>{let o=n.get(r);if(o!==void 0)return o;let i=await vn(e,r);return n.set(r,i),i})}async*iterRecallNewestFirst(e,t={}){if(!$e.test(e))return;let n=this.writeQueues.get(e);n&&await n;let r=await this.getArchiveLineCounts(e),o=0;for(let l of r)o+=l.lineCount;let i=new Map,a=[];for await(let l of this.streamFile(E.historyFile(e)))a.push(l);let d=t.hydrate!==!1;for(let l=a.length-1;l>=0;l--){let w=d?await this.hydrateEntry(e,a[l],i):a[l];yield{entryId:o+l,entry:w}}let c=new Array(r.length),u=0;for(let l=0;l<r.length;l++)c[l]=u,u+=r[l].lineCount;for(let l=r.length-1;l>=0;l--){let w=r[l],h=[];for await(let k of this.streamFile(w.path))h.push(k);let f=c[l];for(let k=h.length-1;k>=0;k--){let p=d?await this.hydrateEntry(e,h[k],i):h[k];yield{entryId:f+k,entry:p}}}}async pageBefore(e,t){let n=[],r=0,o=!1,i=!1;for await(let{entry:a}of this.iterRecallNewestFirst(e,{hydrate:t.hydrate})){if(!o){if(a.seq===void 0||a.seq>=t.beforeSeq)continue;o=!0}if(t.skip?.(a))continue;if(r>=t.turns){i=!0;break}let d=a.params?.update;n.push(a),d?.sessionUpdate==="prompt_received"&&(r+=1)}return n.reverse(),{entries:n,hasMore:i}}async rangeSlice(e,t,n){if(!$e.test(e))return[];if(n<t)return[];let r=this.writeQueues.get(e);r&&await r;let o=await this.getArchiveLineCounts(e),i=0;for(let u of o)i+=u.lineCount;let a=[],d=new Map,c=0;for(let u of o){let l=c,w=c+u.lineCount;if(c=w,w<=t)continue;if(l>n)break;let h=0;for await(let f of this.streamFile(u.path)){let k=l+h;if(h+=1,k<t)continue;if(k>n)break;let p=await this.hydrateEntry(e,f,d);a.push({entryId:k,entry:p})}}if(n>=i){let u=Math.max(t-i,0),l=n-i,w=0;for await(let h of this.streamFile(E.historyFile(e))){if(w>l)break;if(w>=u){let f=await this.hydrateEntry(e,h,d);a.push({entryId:i+w,entry:f})}w+=1}}return a}async getRecallTotalCount(e){if(!$e.test(e))return 0;let t=await this.getArchiveLineCounts(e),n=0;for(let o of t)n+=o.lineCount;let r=0;for await(let o of this.streamFile(E.historyFile(e)))r+=1;return n+r}async load(e,t={}){if(!$e.test(e))return[];let n=(t.tools??"inline")==="inline",r=this.writeQueues.get(e);r&&await r;let o;try{o=await G.readFile(E.historyFile(e),"utf8")}catch(w){if(w.code==="ENOENT")return[];throw w}let i=[];for(let w of o.split(`
162
- `)){if(w.length===0)continue;let h;try{h=JSON.parse(w)}catch{continue}if(!h||typeof h!="object"||Array.isArray(h))continue;let f=h;typeof f.method=="string"&&typeof f.recordedAt=="number"&&i.push({method:f.method,params:f.params,recordedAt:f.recordedAt,...typeof f.seq=="number"?{seq:f.seq}:{}})}let a=t.maxEntries??this.maxEntries,d=i.length>a?i.slice(-a):i;if(!n)return d;let c=new Map,u=async w=>{let h=c.get(w);if(h!==void 0)return h;let f=await vn(e,w);return c.set(w,f),f},l=[];for(let w of d)l.push(await Ko(w,u));return l}async flushAll(){let e=[...this.writeQueues.values()];e.length!==0&&await Promise.allSettled(e)}async delete(e){if($e.test(e))return this.enqueue(e,async()=>{try{await G.unlink(E.historyFile(e))}catch(n){if(n.code!=="ENOENT")throw n}let t=await this.listArchiveIndices(e);for(let n of t)await this.unlinkArchive(e,n);this.nextArchiveIndex.delete(e),this.archiveLineCounts.delete(e),await sa(e);try{await G.rmdir(E.sessionDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}})}enqueue(e,t){let r=(this.writeQueues.get(e)??Promise.resolve()).then(t,t),o=r.catch(()=>{});return this.writeQueues.set(e,o),o.finally(()=>{this.writeQueues.get(e)===o&&this.writeQueues.delete(e)}),r}};Q();import{promises as Pc}from"fs";import*as Mc from"path";async function _c(s,e){await Pc.mkdir(Mc.dirname(s),{recursive:!0});let t=e.map(n=>JSON.stringify(n));await Pc.writeFile(s,t.length>0?t.join(`
171
+ `,r=await this.resolveNextArchiveIndex(e);await this.enforceArchiveTierCap(e,r);let o=E.historyArchiveFile(e,r);await K.mkdir(E.sessionDir(e),{recursive:!0}),await K.appendFile(o,n,{encoding:"utf8",mode:384});let i=0;try{i=(await K.stat(o)).size}catch{i=0}i>=this.archiveMaxBytes?(await this.sealArchive(e,r),this.nextArchiveIndex.set(e,r+1)):this.nextArchiveIndex.set(e,r),this.archiveLineCounts.delete(e)}async sealArchive(e,t){let n=E.historyArchiveFile(e,t),r;try{r=await K.readFile(n)}catch(i){if(i.code==="ENOENT")return;throw i}let o=await Qh(r);await K.writeFile(n+".gz",o,{mode:384});try{await K.unlink(n)}catch(i){if(i.code!=="ENOENT")throw i}}async resolveNextArchiveIndex(e){let t=this.nextArchiveIndex.get(e);if(t!==void 0)return t;let n=await this.listArchiveIndices(e),r=n.length===0?0:n[n.length-1],o=r===0?1:r;if(r>0){let i=E.historyArchiveFile(e,r),a=i+".gz",d=!1;try{await K.access(a),d=!0}catch{d=!1}if(d)o=r+1;else try{(await K.stat(i)).size>=this.archiveMaxBytes&&(o=r+1)}catch{o=r}}return this.nextArchiveIndex.set(e,o),o}async enforceArchiveTierCap(e,t){if(this.archiveTiers<=0)return;let n=await this.listArchiveIndices(e),o=(n.includes(t)?n.length:n.length+1)-this.archiveTiers,i=0;for(;o>0&&i<n.length;){let a=n[i];a!==t&&(await this.unlinkArchive(e,a),o-=1),i+=1}}async unlinkArchive(e,t){let n=E.historyArchiveFile(e,t);for(let r of[n,n+".gz"])try{await K.unlink(r)}catch(o){if(o.code!=="ENOENT")throw o}this.archiveLineCounts.delete(e)}async listArchiveIndices(e){let t;try{t=await K.readdir(E.sessionDir(e))}catch(r){if(r.code==="ENOENT")return[];throw r}let n=new Set;for(let r of t){let o=Xh.exec(r);if(!o)continue;let i=Number.parseInt(o[1],10);Number.isFinite(i)&&i>0&&n.add(i)}return[...n].sort((r,o)=>r-o)}async listArchives(e){if(!$e.test(e))return[];let t=await this.listArchiveIndices(e),n=[];for(let r of t){let o=E.historyArchiveFile(e,r),i=o+".gz",a=o;try{await K.access(i),a=i}catch{a=o}n.push({index:r,path:a})}return n}async loadArchives(e){if(!$e.test(e))return[];let t=this.writeQueues.get(e);t&&await t;let n=await this.listArchives(e),r=[];for(let{path:o}of n){let i;try{if(o.endsWith(".gz")){let a=await K.readFile(o);i=(await Yh(a)).toString("utf8")}else i=await K.readFile(o,"utf8")}catch(a){if(a.code==="ENOENT")continue;throw a}for(let a of i.split(`
172
+ `)){if(a.length===0)continue;let d;try{d=JSON.parse(a)}catch{continue}if(!d||typeof d!="object"||Array.isArray(d))continue;let c=d;typeof c.method=="string"&&typeof c.recordedAt=="number"&&r.push({method:c.method,params:c.params,recordedAt:c.recordedAt,...typeof c.seq=="number"?{seq:c.seq}:{}})}}return r}async*streamFile(e){let t;try{t=zh(e)}catch(i){if(i.code==="ENOENT")return;throw i}if(await new Promise(i=>{let a=!1,d=c=>{a||(a=!0,i(c))};t.once("error",c=>{c.code==="ENOENT"?d(!0):(t.destroy(),d(!1))}),t.once("readable",()=>d(!1)),t.once("end",()=>d(!1))}))return;let r=e.endsWith(".gz")?t.pipe(Jh()):t,o=Kh({input:r,crlfDelay:1/0});try{for await(let i of o){if(i.length===0)continue;let a;try{a=JSON.parse(i)}catch{continue}if(!a||typeof a!="object"||Array.isArray(a))continue;let d=a;typeof d.method=="string"&&typeof d.recordedAt=="number"&&(yield{method:d.method,params:d.params,recordedAt:d.recordedAt,...typeof d.seq=="number"?{seq:d.seq}:{}})}}finally{o.close(),t.destroy()}}async getArchiveLineCounts(e){if(!$e.test(e))return[];let t=this.archiveLineCounts.get(e),n=await this.listArchives(e);if(t&&t.length===n.length&&t.every((o,i)=>o.index===n[i].index&&o.path===n[i].path))return t;let r=[];for(let{index:o,path:i}of n){let a=t?.find(c=>c.index===o&&c.path===i);if(a){r.push(a);continue}let d=0;for await(let c of this.streamFile(i))d+=1;r.push({index:o,path:i,lineCount:d})}return this.archiveLineCounts.set(e,r),r}async hydrate(e,t){let n=new Map,r=[];for(let o of t)r.push(await this.hydrateEntry(e,o,n));return r}async hydrateEntry(e,t,n){return ci(t,async r=>{let o=n.get(r);if(o!==void 0)return o;let i=await Cn(e,r);return n.set(r,i),i})}async*iterRecallNewestFirst(e,t={}){if(!$e.test(e))return;let n=this.writeQueues.get(e);n&&await n;let r=await this.getArchiveLineCounts(e),o=0;for(let l of r)o+=l.lineCount;let i=new Map,a=[];for await(let l of this.streamFile(E.historyFile(e)))a.push(l);let d=t.hydrate!==!1;for(let l=a.length-1;l>=0;l--){let y=d?await this.hydrateEntry(e,a[l],i):a[l];yield{entryId:o+l,entry:y}}let c=new Array(r.length),u=0;for(let l=0;l<r.length;l++)c[l]=u,u+=r[l].lineCount;for(let l=r.length-1;l>=0;l--){let y=r[l],h=[];for await(let k of this.streamFile(y.path))h.push(k);let f=c[l];for(let k=h.length-1;k>=0;k--){let g=d?await this.hydrateEntry(e,h[k],i):h[k];yield{entryId:f+k,entry:g}}}}async pageBefore(e,t){let n=[],r=0,o=!1,i=!1;for await(let{entry:a}of this.iterRecallNewestFirst(e,{hydrate:t.hydrate})){if(!o){if(a.seq===void 0||a.seq>=t.beforeSeq)continue;o=!0}if(t.skip?.(a))continue;if(r>=t.turns){i=!0;break}let d=a.params?.update;n.push(a),d?.sessionUpdate==="prompt_received"&&(r+=1)}return n.reverse(),{entries:n,hasMore:i}}async rangeSlice(e,t,n){if(!$e.test(e))return[];if(n<t)return[];let r=this.writeQueues.get(e);r&&await r;let o=await this.getArchiveLineCounts(e),i=0;for(let u of o)i+=u.lineCount;let a=[],d=new Map,c=0;for(let u of o){let l=c,y=c+u.lineCount;if(c=y,y<=t)continue;if(l>n)break;let h=0;for await(let f of this.streamFile(u.path)){let k=l+h;if(h+=1,k<t)continue;if(k>n)break;let g=await this.hydrateEntry(e,f,d);a.push({entryId:k,entry:g})}}if(n>=i){let u=Math.max(t-i,0),l=n-i,y=0;for await(let h of this.streamFile(E.historyFile(e))){if(y>l)break;if(y>=u){let f=await this.hydrateEntry(e,h,d);a.push({entryId:i+y,entry:f})}y+=1}}return a}async getRecallTotalCount(e){if(!$e.test(e))return 0;let t=await this.getArchiveLineCounts(e),n=0;for(let o of t)n+=o.lineCount;let r=0;for await(let o of this.streamFile(E.historyFile(e)))r+=1;return n+r}async load(e,t={}){if(!$e.test(e))return[];let n=(t.tools??"inline")==="inline",r=this.writeQueues.get(e);r&&await r;let o;try{o=await K.readFile(E.historyFile(e),"utf8")}catch(y){if(y.code==="ENOENT")return[];throw y}let i=[];for(let y of o.split(`
173
+ `)){if(y.length===0)continue;let h;try{h=JSON.parse(y)}catch{continue}if(!h||typeof h!="object"||Array.isArray(h))continue;let f=h;typeof f.method=="string"&&typeof f.recordedAt=="number"&&i.push({method:f.method,params:f.params,recordedAt:f.recordedAt,...typeof f.seq=="number"?{seq:f.seq}:{}})}let a=t.maxEntries??this.maxEntries,d=i.length>a?i.slice(-a):i;if(!n)return d;let c=new Map,u=async y=>{let h=c.get(y);if(h!==void 0)return h;let f=await Cn(e,y);return c.set(y,f),f},l=[];for(let y of d)l.push(await ci(y,u));return l}async flushAll(){let e=[...this.writeQueues.values()];e.length!==0&&await Promise.allSettled(e)}async delete(e){if($e.test(e))return this.enqueue(e,async()=>{try{await K.unlink(E.historyFile(e))}catch(n){if(n.code!=="ENOENT")throw n}let t=await this.listArchiveIndices(e);for(let n of t)await this.unlinkArchive(e,n);this.nextArchiveIndex.delete(e),this.archiveLineCounts.delete(e),await ya(e);try{await K.rmdir(E.sessionDir(e))}catch(n){let r=n;if(r.code!=="ENOENT"&&r.code!=="ENOTEMPTY")throw n}})}enqueue(e,t){let r=(this.writeQueues.get(e)??Promise.resolve()).then(t,t),o=r.catch(()=>{});return this.writeQueues.set(e,o),o.finally(()=>{this.writeQueues.get(e)===o&&this.writeQueues.delete(e)}),r}};Q();import{promises as Yc}from"fs";import*as Xc from"path";async function Zc(s,e){await Yc.mkdir(Xc.dirname(s),{recursive:!0});let t=e.map(n=>JSON.stringify(n));await Yc.writeFile(s,t.length>0?t.join(`
163
174
  `)+`
164
- `:"")}import{z as K}from"zod";var Mh=K.object({method:K.string(),params:K.unknown(),recordedAt:K.number()}),_h=K.object({sessionId:K.string(),lineageId:K.string(),upstreamSessionId:K.string().optional(),agentId:K.string(),cwd:K.string(),title:K.string().optional(),synopsis:Mn.optional(),summarizedThroughEntry:K.number().int().nonnegative().optional(),currentModel:K.string().optional(),currentMode:K.string().optional(),currentUsage:$o.optional(),agentCommands:K.array(Mo).optional(),agentModes:K.array(_o).optional(),interactive:K.boolean().optional(),originatingClient:Oo.optional(),priority:K.number().int().nonnegative().optional(),createdAt:K.string(),updatedAt:K.string()}),$h=K.object({version:K.literal(1),exportedAt:K.string(),exportedFrom:K.object({hydraVersion:K.string(),machine:K.string(),hydraHost:K.string().optional()}),session:_h,history:K.array(Mh),promptHistory:K.array(K.string()).optional(),toolBlobs:K.record(K.string()).optional()});function jn(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 $c(s){return $h.parse(s)}function Yo(s){if(s&&!(s.costAmount===void 0&&s.cumulativeCost===void 0))return(s.cumulativeCost??0)+(s.costAmount??0)}function Un(s){if(!s)return;let e={};s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size);let t=Yo(s);return t&&(e.costAmount=t),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),e}var Oc=900*1e3,Fh=12,Nh="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",xt=Oh(Nh,16);function Dh(){let s,e,t=!1;return{send(n){if(t)return Promise.resolve();if("method"in n&&"id"in n){let r={jsonrpc:"2.0",id:n.id,error:{code:x.MethodNotFound,message:`no handler for ${n.method} (headless fork-prompt client)`}};queueMicrotask(()=>s?.(r))}return Promise.resolve()},onMessage(n){s=n},onClose(n){e=n},close(){return t||(t=!0,e?.()),Promise.resolve()}}}var Ks=class s{constructor(e,t,n,r={}){this.registry=e;this.spawner=t??(a=>ct.spawn(a)),this.store=n??new Ms,this.tombstones=r.tombstones??new Bs,this.sessionHistoryMaxEntries=r.sessionHistoryMaxEntries??1e3,this.histories=new Gs({maxEntries:this.sessionHistoryMaxEntries,archiveMaxBytes:r.sessionHistoryArchiveMaxBytes,archiveTiers:r.sessionHistoryArchiveTiers}),this.workspaceSnapshotsDisabled=r.disableWorkspaceSnapshots===!0,this.idleTimeoutMs=r.idleTimeoutMs??0,this.backgroundTaskTracking=r.backgroundTaskTracking,this.orphanTimeoutMs=r.orphanTimeoutMs??0,this.idleEventTimeoutMs=r.idleEventTimeoutMs??3e4,this.sessionDefaults=r.sessionDefaults??{},this.synopsisAgent=r.synopsisAgent,this.synopsisModel=r.synopsisModel,this.compactionAgent=r.compactionAgent,this.compactionModel=r.compactionModel,this.defaultTransformers=r.defaultTransformers??[],this.logger=r.logger,this.npmRegistry=r.npmRegistry,this.extensionCommands=r.extensionCommands,this.defaultCwd=r.defaultCwd??"~";let o=r.compaction??{},i=o.tailK??20;this.compactionTailK=i,this.synopsisCoordinator=new Js({registry:this.registry,store:this.store,histories:this.histories,synopsisAgent:this.synopsisAgent,synopsisModel:this.synopsisModel,compactionAgent:this.compactionAgent,compactionModel:this.compactionModel,compactionMaxIterations:o.maxIterations,persistTitle:async(a,d)=>{let c=this.get(a);if(c){await c.retitle(d);return}await this.persistTitle(a,d)},persistSynopsis:(a,d,c)=>this.persistSynopsis(a,d,c),logger:this.logger,npmRegistry:this.npmRegistry,onCompactionStateChange:async(a,d,c)=>{if(c.targetAgentId)return;let u=this.get(a);u&&(u.compactionState=d),await this.mutateRecord(a,{compactionState:d})},broadcastHydraCompaction:(a,d,c)=>{this.emitSwapPhase(a,c.targetAgentId,d)},onSynthesisArtifact:async(a,d,c,u,l)=>{await this.dispatchSynthesisSwap(a,d,c,u,l)},onSynthesisUnavailable:async(a,d,c)=>{let u=await this.store.read(a).catch(()=>{});if(u?.synopsis&&u.summarizedThroughEntry!==void 0){this.logger?.info(`agent switch: synthesis produced no new artifact for sessionId=${a} (${c}); swapping to ${d} on the persisted synopsis`),await this.dispatchSynthesisSwap(a,u.synopsis,u.summarizedThroughEntry,d);return}let l=(await this.histories.load(a).catch(()=>[])).length;this.logger?.warn(`agent switch: synthesis unavailable for sessionId=${a} (${c}); swapping to ${d} on verbatim tail`),await this.dispatchSynthesisSwap(a,void 0,l,d)}}),this.refreshAgentCatalog()}registry;sessions=new Map;resurrectionInflight=new Map;snapshotInFlight=new Set;snapshotPending=new Set;workspaceSnapshotsDisabled=!1;driftNoticed=new Map;pendingAuthAgents=new Map;spawner;store;tombstones;histories;idleTimeoutMs;backgroundTaskTracking;orphanTimeoutMs;sessionDefaults;synopsisAgent;synopsisModel;compactionAgent;compactionModel;defaultTransformers;idleEventTimeoutMs;sessionHistoryMaxEntries;metaWriteQueues=new Map;workspaceQueues=new Map;listCache=new Map;static LIST_CACHE_TTL_MS=500;logger;npmRegistry;extensionCommands;defaultCwd;synopsisCoordinator;pendingDeletions=new Map;pendingSwapDisposers=new Map;rollbackLocks=new Set;compactionTailK=20;agentCatalog=[];async dispatchSynthesisSwap(e,t,n,r,o){let i=this.get(e);if(t===void 0&&r===void 0)return;if(!i){if(this.logger?.info(`compaction: persisted artifact for cold session sessionId=${e}`),t===void 0)return;await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:n});return}let a=this.compactionTailK;try{if(await i.isQuiescedForSwap()){this.pendingSwapDisposers.get(e)?.(),this.pendingSwapDisposers.delete(e),await this.performSynthesisSwap(i,t,a,n,r,o);return}this.pendingSwapDisposers.get(e)?.(),this.logger?.info(`compaction: session not quiesced, parking onceIdle swap sessionId=${e}`),this.emitSwapPhase(e,r,{phase:"deferred"});let c=i.onceIdle(()=>{this.pendingSwapDisposers.delete(e),this.onIdleAttemptSwap(e)});this.pendingSwapDisposers.set(e,c)}catch(d){this.logger?.warn(`compaction: dispatch failed for sessionId=${e}: ${d instanceof Error?d.message:String(d)}, leaving session as-is`)}}async onIdleAttemptSwap(e){let t=this.get(e);if(!t)return;let n=this.compactionTailK;try{if(!await t.isQuiescedForSwap()){let d=await this.store.read(e).catch(()=>{});d?.synopsis&&d.summarizedThroughEntry!==void 0?this.dispatchSynthesisSwap(e,d.synopsis,d.summarizedThroughEntry,d.pendingAgentSwap):d?.pendingAgentSwap&&this.dispatchSynthesisSwap(e,void 0,(await this.histories.load(e).catch(()=>[])).length,d.pendingAgentSwap);return}let o=await this.store.read(e).catch(()=>{});if(!o?.synopsis||o.summarizedThroughEntry===void 0){if(o?.pendingAgentSwap){let d=(await this.histories.load(e).catch(()=>[])).length;this.logger?.info(`compaction: no artifact for sessionId=${e}, swapping to ${o.pendingAgentSwap} on verbatim tail`),await this.performSynthesisSwap(t,void 0,n,d,o.pendingAgentSwap);return}this.logger?.warn(`compaction: persisted artifact missing for sessionId=${e}, abandoning swap`),t.compactionState=void 0,await this.mutateRecord(e,{},["compactionState"]);return}let i=o.pendingAgentSwap,a=await this.histories.load(e).catch(()=>[]);if(a.length>o.summarizedThroughEntry){this.logger?.info(`compaction: history grew during deferral (have=${a.length} artifact=${o.summarizedThroughEntry}), rescheduling synopsis sessionId=${e}`),i?this.synopsisCoordinator.scheduleCompaction(e,{targetAgentId:i}):this.synopsisCoordinator.scheduleCompaction(e);return}await this.performSynthesisSwap(t,o.synopsis,n,o.summarizedThroughEntry,i,o.compactionState?.runId)}catch(r){this.logger?.warn(`compaction: onIdleAttemptSwap failed for sessionId=${e}: ${r instanceof Error?r.message:String(r)}`)}}async recordSynopsisFor(e){let t=await this.store.read(e).catch(()=>{});return t?.synopsis?{synopsis:t.synopsis}:{}}async performSynthesisSwap(e,t,n,r,o,i){try{let a=o?Math.min(t===void 0?Fh:5,n):0;await e.swapUpstream({...t!==void 0?{artifact:t}:{},tailK:n,tailFloor:a,summarizedThroughEntry:r,...o?{newAgentId:o}:{},...i!==void 0?{runId:i}:{}}),o?await this.mutateRecord(e.sessionId,{},["pendingAgentSwap"]):(e.compactionState=void 0,await this.mutateRecord(e.sessionId,{},["compactionState"]))}catch(a){this.logger?.warn(`compaction: swap failed for sessionId=${e.sessionId}: ${a instanceof Error?a.message:String(a)}, leaving session as-is`)}finally{this.invalidateListCache()}}async refreshAgentCatalog(){try{let{agents:e}=await jt(this.registry);this.agentCatalog=e.map(t=>({id:t.id,name:t.name,...t.description!==void 0?{description:t.description}:{}}))}catch{}}async adoptWorkspace(e,t,n){let r=t.label;if(r===void 0)throw new Error("workspace.adopt requires workspace.label");let o=this.liveSessionsWithLabel(n.cwd,r)[0]?.workspace,i=o!==void 0?this.asWorkspace(o):(await e.listWorkspaces(n.cwd).catch(()=>[])).find(a=>a.label===r);if(i===void 0)throw new Error(`cannot adopt workspace "${r}": no workspace by that name derived from ${O(n.cwd)}`);return await this.enqueueKeyed(this.workspaceQueues,i.path,async()=>(e.capabilities().locking&&await e.lock(i,`session ${n.title??"live"}`).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},...o?.clean!==void 0?{clean:o.clean}:{}}}))}async resolveWorkspace(e){let t=e.workspace;if(t===void 0)return{cwd:e.cwd};let n=oe(t.provider);if(n===void 0){let u=`unknown workspace provider "${t.provider}"`;if(t.required===!0)throw new Error(`isolation required but unavailable: ${u}`);return this.logger?.warn?.(`session workspace: ${u}; running in ${e.cwd}`),{cwd:e.cwd,isolationError:u}}if(t.adopt===!0)return await this.adoptWorkspace(n,t,e);let r=t.label??`s-${xt().slice(0,8)}`,o=await n.createWorkspace({sourceCwd:e.cwd,label:r,...t.from!==void 0?{from:t.from}:{}}).catch(u=>({ok:!1,reason:String(u)}));if(!o.ok){if(t.required===!0)throw new Error(`isolation required but unavailable: ${o.reason}`);return this.logger?.warn?.(`session workspace: ${o.reason}; falling back to ${e.cwd} (unisolated)`),{cwd:e.cwd,isolationError:o.reason}}let i=o.workspace;n.capabilities().locking&&await n.lock(i,`session ${e.title??"live"}`).catch(()=>{});let a=await Us(i.sourceCwd).catch(()=>({})),d,c=await this.materializeNestedTrees(i);if(c!==void 0&&this.logger?.info?.(`session workspace: ${c} in ${i.path}`),a.carry!==void 0&&a.carry.length>0){let u=await qo(i.sourceCwd,i.path,a.carry).catch(()=>{});u!==void 0&&u.copied.length>0&&this.logger?.info?.(`session workspace: carried ${u.copied.length} file(s) into ${i.path}`)}if(a.postCreate!==void 0){let u=await Ls(a.postCreate,{workspacePath:i.path,sourceCwd:i.sourceCwd,label:i.label,...a.hookTimeoutSeconds!==void 0?{timeoutSeconds:a.hookTimeoutSeconds}:{}});u.ok||(d=`postCreate failed: ${u.reason??"unknown"}`,this.logger?.warn?.(`session workspace: ${d} (${i.path})`))}return i.snapshot!==void 0&&await n.retainSnapshot(i,this.startRefFor(i.label),i.snapshot).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},clean:!0},...d!==void 0?{isolationError:d}:{}}}logInfo(e){this.logger?.info(e)}async create(e){e={...e,cwd:as(ie(e.cwd))};let t=e.timer??new qt,n=await this.registry.getAgent(e.agentId);n&&n.id!==e.agentId&&(e={...e,agentId:n.id}),t.mark("create.canonicalize");let r=`${ye}${xt()}`,o=await this.resolveWorkspace(e),i=o.cwd;t.mark("create.workspace");let a=await this.bootstrapAgent({timer:t,agentId:e.agentId,cwd:i,agentArgs:e.agentArgs,mcpServers:e.mcpServers,model:e.model,configDefaults:e.configDefaults,onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,selfSessionId:r});if(e.transformChain&&e.transformChain.length>0){let c={...a.agentCapabilities??{}};for(let u of e.transformChain)if(u.intercepts.has("agent:initialize"))try{let l=await u.connection.request("hydra-acp/transformer/message",{token:`t_${xt()}`,phase:"response",method:"initialize",direction:"agent\u2192daemon",sessionId:"(pre-session)",envelope:c});l.action==="stop"&&l.payload&&(c=l.payload)}catch{}a.agentCapabilities=c}t.mark("create.transformers");let d=new Yt({sessionId:r,cwd:i,...o.workspace!==void 0?{workspace:o.workspace}:{},...o.isolationError!==void 0?{workspaceError:o.isolationError}:{},agentId:e.agentId,agent:a.agent,upstreamSessionId:a.upstreamSessionId,agentMeta:a.agentMeta,agentCapabilities:a.agentCapabilities,...a.modelVerb?{modelVerb:a.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,...this.backgroundTaskTracking!==void 0?{backgroundTaskTracking:this.backgroundTaskTracking}:{},orphanTimeoutMs:this.orphanTimeoutMs,idleEventTimeoutMs:this.idleEventTimeoutMs,logger:this.logger,spawnReplacementAgent:c=>this.bootstrapAgent({...c,mcpServers:c.mcpServers??[],selfSessionId:r}),loadExistingAgentSession:(c,u)=>this.bootstrapAgentLoad(c,{...u,mcpServers:u.mcpServers??[],selfSessionId:r}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:a.initialModel,currentMode:a.initialMode,agentModes:a.initialModes,agentModels:a.initialModels,agentConfigOptions:a.initialConfigOptions,transformChain:e.transformChain,parentSessionId:e.parentSessionId,originatingClient:e.originatingClient,interactive:e.interactive,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(d.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(d),scheduleCompaction:c=>this.scheduleCompaction(d.sessionId,c),resolveAgentId:async c=>(await this.registry.getAgent(c))?.id,getCompactionState:()=>this.getCompactionState(d.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(d.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(d.sessionId),uncompactHook:()=>this.performUncompact(d.sessionId),forkHook:c=>this.forkSession(d.sessionId,c??{}),workspaceHook:(c,u,l)=>this.runWorkspaceAction(d.sessionId,c,u,l),onCompactionSwapHook:c=>{this.persistRollbackBreadcrumb(d.sessionId,c).catch(()=>{})},persistWatermarkHook:c=>{this.mutateRecord(d.sessionId,{summarizedThroughEntry:c}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(d.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});if(t.mark("create.session-ctor"),o.workspace!==void 0){let c=oe(o.workspace.provider);c!==void 0&&c.capabilities().supports.environmentNotes&&(d.workspaceNotes=await c.environmentNotes({path:o.workspace.path,sourceCwd:o.workspace.sourceCwd,label:o.workspace.label,provider:o.workspace.provider,...o.workspace.snapshot!==void 0?{snapshot:o.workspace.snapshot}:{},...o.workspace.vcs!==void 0?{vcs:o.workspace.vcs}:{}}).catch(()=>[]))}return await this.attachManagerHooks(d),t.mark("create.persist"),d}async resurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t){if(t.upstreamSessionId!==e.upstreamSessionId){let o=new Error(`session ${e.hydraSessionId} already exists with a different upstream id`);throw o.code=x.AlreadyAttached,o}return t}let n=this.resurrectionInflight.get(e.hydraSessionId);if(n)return n;let r=this.doResurrect(e);this.resurrectionInflight.set(e.hydraSessionId,r);try{return await r}finally{this.resurrectionInflight.delete(e.hydraSessionId)}}async doResurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t)return t;let n=await this.registry.getAgent(e.agentId);if(!n){let m=new Error(`agent ${e.agentId} not found in registry; cannot resurrect`);throw m.code=x.AgentNotInstalled,m}if(e.upstreamSessionId==="")return this.doResurrectFromImport(e);if(!await this.dirExists(e.cwd))return this.doResurrectFromImport(e);let r=await Me(n,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),o=cs(e.hydraSessionId,e.forwardedEnv),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...o?{extraEnv:o}:{}}),a;try{let m=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:Lt,clientInfo:{name:"hydra",version:ue}});a=m.agentCapabilities,i.authMethods=Bn(m.authMethods),i.steeringSupported=Ln(m)}catch(m){throw await i.kill().catch(()=>{}),ht(m,i)}let d;try{let m=Xo(n,{model:e.currentModel});d=await i.connection.request("session/load",{sessionId:e.upstreamSessionId,cwd:e.cwd,mcpServers:e.mcpServers??[],...m&&{_meta:m}})}catch(m){if(m&&typeof m=="object"&&m.code===x.AuthRequired)throw await i.kill().catch(()=>{}),ht(m,i);return process.stderr.write(`session/load failed for upstream ${e.upstreamSessionId} on ${e.agentId} (${m.message}); recovering via import-reseed
165
- `),await i.kill().catch(()=>{}),this.doResurrectFromImport(e)}if(e.pendingHistorySync===!0)this.clearPendingHistorySync(e.hydraSessionId).catch(()=>{});else{let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain1 dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let c=ni(d??{}),u=e.agentModes??mt(ti(d??{}));this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedMode=${JSON.stringify(e.currentMode)} agentReportedMode=${JSON.stringify(c)} advertisedModes=${JSON.stringify(u?.map(m=>m.id))}`);let l=await lt({agent:i,upstreamSessionId:e.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:c,advertisedModes:u,logger:this.logger});this.logger?.info(`resurrect: effectiveMode=${JSON.stringify(l)} for sessionId=${e.hydraSessionId}`);let w=Zo(d??{}),h=mt(ei(d??{}))??e.agentModels;if(this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedModel=${JSON.stringify(e.currentModel)} agentReportedModel=${JSON.stringify(w)} advertisedModels=${JSON.stringify(h?.map(m=>m.modelId))}`),e.pendingHistorySync!==!0){let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain2 (post-mode-restore) dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let f=Wt(d),k=await ft({agent:i,upstreamSessionId:e.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:w,...f?{modelVerb:f}:{},logger:this.logger}),p=k.modelId,g=mt(sn(nn(k.result)?k.result:d??{}));if(g=mt(await this.restoreConfigOptionValues(i,e.upstreamSessionId,e.configOptionValues,g??[])),e.pendingHistorySync!==!0){let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain3 (post-model-restore) dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let y=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,...f?{modelVerb:f}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,...this.backgroundTaskTracking!==void 0?{backgroundTaskTracking:this.backgroundTaskTracking}:{},orphanTimeoutMs:this.orphanTimeoutMs,logger:this.logger,spawnReplacementAgent:m=>this.bootstrapAgent({...m,mcpServers:m.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(m,v)=>this.bootstrapAgentLoad(m,{...v,mcpServers:v.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:p,currentMode:l,currentUsage:e.currentUsage,reloadsUpstreamLedger:!0,agentCommands:e.agentCommands,agentModes:u,agentModels:h,agentConfigOptions:g,summarizedThroughEntry:e.summarizedThroughEntry,compactionState:e.compactionState,firstPromptSeeded:!!e.title,upstreamRespawned:!0,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,lastTurnEndedAt:e.lastTurnEndedAt,readAt:e.readAt,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(y.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(y),scheduleCompaction:m=>this.scheduleCompaction(y.sessionId,m),resolveAgentId:async m=>(await this.registry.getAgent(m))?.id,getCompactionState:()=>this.getCompactionState(y.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(y.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(y.sessionId),uncompactHook:()=>this.performUncompact(y.sessionId),forkHook:m=>this.forkSession(y.sessionId,m??{}),workspaceHook:(m,v,S)=>this.runWorkspaceAction(y.sessionId,m,v,S),onCompactionSwapHook:m=>{this.persistRollbackBreadcrumb(y.sessionId,m).catch(()=>{})},persistWatermarkHook:m=>{this.mutateRecord(y.sessionId,{summarizedThroughEntry:m}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(y.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(y),y}async doResurrectFromImport(e){let t=await this.resolveResurrectTarget(e.cwd,e.workspace),n=t.cwd,r=await this.bootstrapAgent({agentId:e.agentId,cwd:n,agentArgs:e.agentArgs,mcpServers:e.mcpServers??[],onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,model:e.currentModel}),o=e.agentModes??r.initialModes,i=await lt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:r.initialMode,advertisedModes:o,logger:this.logger}),a=e.agentModels??r.initialModels,d=await ft({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:r.initialModel,...r.modelVerb?{modelVerb:r.modelVerb}:{},logger:this.logger}),c=d.modelId,u=nn(d.result)?mt(sn(d.result)):void 0;u=mt(await this.restoreConfigOptionValues(r.agent,r.upstreamSessionId,e.configOptionValues,u??r.initialConfigOptions??[])),r.agent.connection.drainBuffered("session/update");let l=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,...this.backgroundTaskTracking!==void 0?{backgroundTaskTracking:this.backgroundTaskTracking}:{},orphanTimeoutMs:this.orphanTimeoutMs,logger:this.logger,spawnReplacementAgent:w=>this.bootstrapAgent({...w,mcpServers:w.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(w,h)=>this.bootstrapAgentLoad(w,{...h,mcpServers:h.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:c,currentMode:i,currentUsage:e.currentUsage,agentCommands:e.agentCommands,agentModes:o,agentModels:a,agentConfigOptions:u??r.initialConfigOptions,summarizedThroughEntry:e.summarizedThroughEntry,firstPromptSeeded:!!e.title,upstreamRespawned:!0,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,lastTurnEndedAt:e.lastTurnEndedAt,readAt:e.readAt,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forwardedEnv:e.forwardedEnv,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(l.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(l),scheduleCompaction:w=>this.scheduleCompaction(l.sessionId,w),resolveAgentId:async w=>(await this.registry.getAgent(w))?.id,getCompactionState:()=>this.getCompactionState(l.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(l.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(l.sessionId),uncompactHook:()=>this.performUncompact(l.sessionId),forkHook:w=>this.forkSession(l.sessionId,w??{}),workspaceHook:(w,h,f)=>this.runWorkspaceAction(l.sessionId,w,h,f),onCompactionSwapHook:w=>{this.persistRollbackBreadcrumb(l.sessionId,w).catch(()=>{})},persistWatermarkHook:w=>{this.mutateRecord(l.sessionId,{summarizedThroughEntry:w}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(l.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(l),e.forkedFromSessionId&&e.forkSynthesisState==="running"?this.logger?.info(`fork ${l.sessionId}: synthesis in flight \u2014 skipping seed, recall available`):e.forkedFromSessionId&&(e.synopsis||(e.summarizedThroughEntry??0)>0)?l.seedFromFork(e.synopsis).catch(()=>{}):l.seedFromImport().catch(()=>{}),l}async dirExists(e){try{return(await Tt.stat(e)).isDirectory()}catch{return!1}}async reapIfOrphanedNonInteractive(e){let t=this.sessions.get(e);if(!(!t||t.attachedCount>0)&&t.interactive!==!0){if(t.hasWorkInFlight){this.logger?.info(`deferring reap of ${e}: work still in flight after detach`),t.onceIdle(n=>{this.reapIfOrphanedNonInteractive(n.sessionId).catch(()=>{})});return}this.logger?.info(`reaping orphaned non-interactive session ${e} (agent killed, cold record kept)`),await t.close({deleteRecord:!1,by:"reap-orphaned"}).catch(()=>{})}}async resolveResurrectTarget(e,t){if(await this.dirExists(e))return t!==void 0?{cwd:e,workspace:t}:{cwd:e};if(t!==void 0){let n=await this.recoverWorkspace(t);if(n!==void 0)return{cwd:n.path,workspace:n}}return{cwd:ie(this.defaultCwd)}}async releaseWorkspace(e,t){let n=oe(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(h=>tt(h.sessionId)).join(", ")}, and a sync would move files under them. Sync it from a session that has it to itself.`);let o=await e.quiesceBlocker();if(o!==void 0)throw new Error(o);let i=oe(t.provider);if(t.line===void 0||i?.capabilities().sharedHistory!==!0)throw new Error(`workspace ${t.label} uses the "${t.provider}" provider, which has no history to merge from \u2014 a sync needs a common base, and a copied directory has none. Land its work with \`/hydra workspace merge\` instead, or start a git-backed workspace if you need to track the source.`);let[a,d]=await Promise.all([i.currentState(t.sourceCwd),i.currentState(t.path)]);if(a===void 0||d===void 0)throw new Error("could not read the state of the source or the workspace");if(await i.contains(t.path,{state:a,within:d}))return{ok:!0,message:`Already up to date with ${O(t.sourceCwd)} (${a.slice(0,8)}).`};let c=await i.divergence(t.path,d,a),u=String(c?.behind??0),l=await i.integrate({into:t.path,from:a,message:`hydra: sync ${t.label} with the source`});if(!l.ok){let h=l.conflicts,f=await i.integrationInProgress(t.path);if(h.length===0&&!f){let p=await this.syncOverDirtyTree(t,{provider:i,before:d,sourceHead:a,incoming:u});if(p!==void 0)return p}let k=h.length>0?`
166
- ${h.map(p=>` ${p}`).join(`
167
- `)}`:` (${l.reason??"the integration failed"})`;return h.length===0?{ok:!1,message:`the source could not be merged into ${O(t.path)}; nothing changed.${k}
168
- `+(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 i.abortIntegration(t.path).catch(()=>{}),{ok:!1,message:`${h.length} file(s) conflict between the source and this workspace:${k}`}):{ok:!1,message:`Synced with conflicts. ${h.length} file(s) need resolving in ${O(t.path)}:${k}
169
- 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 w=(await i.changedPathsBetween(t.path,d,l.snapshot)).length;return{ok:!0,message:`Synced ${O(t.path)} with ${O(t.sourceCwd)}: ${u} commit(s), ${w} 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 c=await n.captureWorkingState(e.path,`hydra: work set aside to sync ${e.label}`).catch(()=>{});if(c===void 0)return;let u=ic(e.label);if(await n.retainSnapshot(a,u,c).then(()=>n.resolveRetained(a,u)).catch(()=>{})===void 0)return;let w={clean:!1,snapshot:c,base:r},h=`git -C ${e.path} cherry-pick --no-commit ${u} # 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 Rt({source:e.path,capture:w,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 ${u}: ${h}`}`}}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 Rt({source:e.path,capture:w,provider:n});return v&&await n.dropSnapshotRef(a,u).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.
170
- `+(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 ${u}. Recover it with:
171
- ${h}`)}}let p=await Rt({source:e.path,capture:w,provider:n}),g=await n.currentState(e.path),y=g===void 0?0:(await n.changedPathsBetween(e.path,r,g)).length,m=`Synced ${O(e.path)} with ${O(e.sourceCwd)}: ${i} commit(s), ${y} file(s) changed.`;return p?(await n.dropSnapshotRef(a,u).catch(()=>{}),{ok:!0,message:`${m} Your uncommitted work was set aside for the merge and restored on top.`}):{ok:!1,message:`${m}
175
+ `:"")}import{z as G}from"zod";var sy=G.object({method:G.string(),params:G.unknown(),recordedAt:G.number()}),ry=G.object({sessionId:G.string(),lineageId:G.string(),upstreamSessionId:G.string().optional(),agentId:G.string(),cwd:G.string(),title:G.string().optional(),synopsis:Dn.optional(),summarizedThroughEntry:G.number().int().nonnegative().optional(),currentModel:G.string().optional(),currentMode:G.string().optional(),currentUsage:Vo.optional(),agentCommands:G.array(zo).optional(),agentModes:G.array(Jo).optional(),interactive:G.boolean().optional(),originatingClient:Go.optional(),priority:G.number().int().nonnegative().optional(),tags:G.array(G.string()).optional(),createdAt:G.string(),updatedAt:G.string()}),oy=G.object({version:G.literal(1),exportedAt:G.string(),exportedFrom:G.object({hydraVersion:G.string(),machine:G.string(),hydraHost:G.string().optional()}),session:ry,history:G.array(sy),promptHistory:G.array(G.string()).optional(),toolBlobs:G.record(G.string()).optional()});function zn(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}:{},...s.record.tags!==void 0&&s.record.tags.length>0?{tags:s.record.tags}:{},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 eu(s){return oy.parse(s)}function li(s){if(s&&!(s.costAmount===void 0&&s.cumulativeCost===void 0))return(s.cumulativeCost??0)+(s.costAmount??0)}function Jn(s){if(!s)return;let e={};s.used!==void 0&&(e.used=s.used),s.size!==void 0&&(e.size=s.size);let t=li(s);return t&&(e.costAmount=t),s.costCurrency!==void 0&&(e.costCurrency=s.costCurrency),e}var tu=900*1e3,ay=12,dy="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Pt=iy(dy,16);function cy(){let s,e,t=!1;return{send(n){if(t)return Promise.resolve();if("method"in n&&"id"in n){let r={jsonrpc:"2.0",id:n.id,error:{code:x.MethodNotFound,message:`no handler for ${n.method} (headless fork-prompt client)`}};queueMicrotask(()=>s?.(r))}return Promise.resolve()},onMessage(n){s=n},onClose(n){e=n},close(){return t||(t=!0,e?.()),Promise.resolve()}}}var ir=class s{constructor(e,t,n,r={}){this.registry=e;this.spawner=t??(a=>ut.spawn(a)),this.store=n??new Bs,this.tombstones=r.tombstones??new Zs,this.sessionHistoryMaxEntries=r.sessionHistoryMaxEntries??1e3,this.histories=new or({maxEntries:this.sessionHistoryMaxEntries,archiveMaxBytes:r.sessionHistoryArchiveMaxBytes,archiveTiers:r.sessionHistoryArchiveTiers}),this.workspaceSnapshotsDisabled=r.disableWorkspaceSnapshots===!0,this.idleTimeoutMs=r.idleTimeoutMs??0,this.elicitationEnabled=r.elicitationForms!==!1,this.backgroundTaskTracking=r.backgroundTaskTracking,this.orphanTimeoutMs=r.orphanTimeoutMs??0,this.idleEventTimeoutMs=r.idleEventTimeoutMs??3e4,this.sessionDefaults=r.sessionDefaults??{},this.synopsisAgent=r.synopsisAgent,this.synopsisModel=r.synopsisModel,this.compactionAgent=r.compactionAgent,this.compactionModel=r.compactionModel,this.defaultTransformers=r.defaultTransformers??[],this.logger=r.logger,this.npmRegistry=r.npmRegistry,this.extensionCommands=r.extensionCommands,this.defaultCwd=r.defaultCwd??"~";let o=r.compaction??{},i=o.tailK??20;this.compactionTailK=i,this.synopsisCoordinator=new sr({registry:this.registry,store:this.store,histories:this.histories,synopsisAgent:this.synopsisAgent,synopsisModel:this.synopsisModel,compactionAgent:this.compactionAgent,compactionModel:this.compactionModel,compactionMaxIterations:o.maxIterations,persistTitle:async(a,d)=>{let c=this.get(a);if(c){await c.retitle(d);return}await this.persistTitle(a,d)},persistSynopsis:(a,d,c)=>this.persistSynopsis(a,d,c),logger:this.logger,npmRegistry:this.npmRegistry,onCompactionStateChange:async(a,d,c)=>{if(c.targetAgentId)return;let u=this.get(a);u&&(u.compactionState=d),await this.mutateRecord(a,{compactionState:d})},broadcastHydraCompaction:(a,d,c)=>{this.emitSwapPhase(a,c.targetAgentId,d)},onSynthesisArtifact:async(a,d,c,u,l)=>{await this.dispatchSynthesisSwap(a,d,c,u,l)},onSynthesisUnavailable:async(a,d,c)=>{let u=await this.store.read(a).catch(()=>{});if(u?.synopsis&&u.summarizedThroughEntry!==void 0){this.logger?.info(`agent switch: synthesis produced no new artifact for sessionId=${a} (${c}); swapping to ${d} on the persisted synopsis`),await this.dispatchSynthesisSwap(a,u.synopsis,u.summarizedThroughEntry,d);return}let l=(await this.histories.load(a).catch(()=>[])).length;this.logger?.warn(`agent switch: synthesis unavailable for sessionId=${a} (${c}); swapping to ${d} on verbatim tail`),await this.dispatchSynthesisSwap(a,void 0,l,d)}}),this.refreshAgentCatalog()}registry;sessions=new Map;resurrectionInflight=new Map;snapshotInFlight=new Set;snapshotPending=new Set;workspaceSnapshotsDisabled=!1;driftNoticed=new Map;pendingAuthAgents=new Map;spawner;store;tombstones;histories;idleTimeoutMs;backgroundTaskTracking;orphanTimeoutMs;sessionDefaults;synopsisAgent;synopsisModel;compactionAgent;compactionModel;defaultTransformers;idleEventTimeoutMs;sessionHistoryMaxEntries;metaWriteQueues=new Map;workspaceQueues=new Map;listCache=new Map;static LIST_CACHE_TTL_MS=500;logger;npmRegistry;extensionCommands;defaultCwd;synopsisCoordinator;pendingDeletions=new Map;pendingSwapDisposers=new Map;rollbackLocks=new Set;compactionTailK=20;agentCatalog=[];elicitationEnabled;clientCaps(e){return Ya(this.elicitationEnabled&&e!==!1)}async dispatchSynthesisSwap(e,t,n,r,o){let i=this.get(e);if(t===void 0&&r===void 0)return;if(!i){if(this.logger?.info(`compaction: persisted artifact for cold session sessionId=${e}`),t===void 0)return;await this.mutateRecord(e,{synopsis:t,summarizedThroughEntry:n});return}let a=this.compactionTailK;try{if(await i.isQuiescedForSwap()){this.pendingSwapDisposers.get(e)?.(),this.pendingSwapDisposers.delete(e),await this.performSynthesisSwap(i,t,a,n,r,o);return}this.pendingSwapDisposers.get(e)?.(),this.logger?.info(`compaction: session not quiesced, parking onceIdle swap sessionId=${e}`),this.emitSwapPhase(e,r,{phase:"deferred"});let c=i.onceIdle(()=>{this.pendingSwapDisposers.delete(e),this.onIdleAttemptSwap(e)});this.pendingSwapDisposers.set(e,c)}catch(d){this.logger?.warn(`compaction: dispatch failed for sessionId=${e}: ${d instanceof Error?d.message:String(d)}, leaving session as-is`)}}async onIdleAttemptSwap(e){let t=this.get(e);if(!t)return;let n=this.compactionTailK;try{if(!await t.isQuiescedForSwap()){let d=await this.store.read(e).catch(()=>{});d?.synopsis&&d.summarizedThroughEntry!==void 0?this.dispatchSynthesisSwap(e,d.synopsis,d.summarizedThroughEntry,d.pendingAgentSwap):d?.pendingAgentSwap&&this.dispatchSynthesisSwap(e,void 0,(await this.histories.load(e).catch(()=>[])).length,d.pendingAgentSwap);return}let o=await this.store.read(e).catch(()=>{});if(!o?.synopsis||o.summarizedThroughEntry===void 0){if(o?.pendingAgentSwap){let d=(await this.histories.load(e).catch(()=>[])).length;this.logger?.info(`compaction: no artifact for sessionId=${e}, swapping to ${o.pendingAgentSwap} on verbatim tail`),await this.performSynthesisSwap(t,void 0,n,d,o.pendingAgentSwap);return}this.logger?.warn(`compaction: persisted artifact missing for sessionId=${e}, abandoning swap`),t.compactionState=void 0,await this.mutateRecord(e,{},["compactionState"]);return}let i=o.pendingAgentSwap,a=await this.histories.load(e).catch(()=>[]);if(a.length>o.summarizedThroughEntry){this.logger?.info(`compaction: history grew during deferral (have=${a.length} artifact=${o.summarizedThroughEntry}), rescheduling synopsis sessionId=${e}`),i?this.synopsisCoordinator.scheduleCompaction(e,{targetAgentId:i}):this.synopsisCoordinator.scheduleCompaction(e);return}await this.performSynthesisSwap(t,o.synopsis,n,o.summarizedThroughEntry,i,o.compactionState?.runId)}catch(r){this.logger?.warn(`compaction: onIdleAttemptSwap failed for sessionId=${e}: ${r instanceof Error?r.message:String(r)}`)}}async recordSynopsisFor(e){let t=await this.store.read(e).catch(()=>{});return t?.synopsis?{synopsis:t.synopsis}:{}}async performSynthesisSwap(e,t,n,r,o,i){try{let a=o?Math.min(t===void 0?ay:5,n):0;await e.swapUpstream({...t!==void 0?{artifact:t}:{},tailK:n,tailFloor:a,summarizedThroughEntry:r,...o?{newAgentId:o}:{},...i!==void 0?{runId:i}:{}}),o?await this.mutateRecord(e.sessionId,{},["pendingAgentSwap"]):(e.compactionState=void 0,await this.mutateRecord(e.sessionId,{},["compactionState"]))}catch(a){this.logger?.warn(`compaction: swap failed for sessionId=${e.sessionId}: ${a instanceof Error?a.message:String(a)}, leaving session as-is`)}finally{this.invalidateListCache()}}async refreshAgentCatalog(){try{let{agents:e}=await Bt(this.registry);this.agentCatalog=e.map(t=>({id:t.id,name:t.name,...t.description!==void 0?{description:t.description}:{}}))}catch{}}async adoptWorkspace(e,t,n){let r=t.label;if(r===void 0)throw new Error("workspace.adopt requires workspace.label");let o=this.liveSessionsWithLabel(n.cwd,r)[0]?.workspace,i=o!==void 0?this.asWorkspace(o):(await e.listWorkspaces(n.cwd).catch(()=>[])).find(a=>a.label===r);if(i===void 0)throw new Error(`cannot adopt workspace "${r}": no workspace by that name derived from ${F(n.cwd)}`);return await this.enqueueKeyed(this.workspaceQueues,i.path,async()=>(e.capabilities().locking&&await e.lock(i,`session ${n.title??"live"}`).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},...o?.clean!==void 0?{clean:o.clean}:{}}}))}async resolveWorkspace(e){let t=e.workspace;if(t===void 0)return{cwd:e.cwd};let n=oe(t.provider);if(n===void 0){let u=`unknown workspace provider "${t.provider}"`;if(t.required===!0)throw new Error(`isolation required but unavailable: ${u}`);return this.logger?.warn?.(`session workspace: ${u}; running in ${e.cwd}`),{cwd:e.cwd,isolationError:u}}if(t.adopt===!0)return await this.adoptWorkspace(n,t,e);let r=t.label??`s-${Pt().slice(0,8)}`,o=await n.createWorkspace({sourceCwd:e.cwd,label:r,...t.from!==void 0?{from:t.from}:{}}).catch(u=>({ok:!1,reason:String(u)}));if(!o.ok){if(t.required===!0)throw new Error(`isolation required but unavailable: ${o.reason}`);return this.logger?.warn?.(`session workspace: ${o.reason}; falling back to ${e.cwd} (unisolated)`),{cwd:e.cwd,isolationError:o.reason}}let i=o.workspace;n.capabilities().locking&&await n.lock(i,`session ${e.title??"live"}`).catch(()=>{});let a=await Ys(i.sourceCwd).catch(()=>({})),d,c=await this.materializeNestedTrees(i);if(c!==void 0&&this.logger?.info?.(`session workspace: ${c} in ${i.path}`),a.carry!==void 0&&a.carry.length>0){let u=await ri(i.sourceCwd,i.path,a.carry).catch(()=>{});u!==void 0&&u.copied.length>0&&this.logger?.info?.(`session workspace: carried ${u.copied.length} file(s) into ${i.path}`)}if(a.postCreate!==void 0){let u=await Xs(a.postCreate,{workspacePath:i.path,sourceCwd:i.sourceCwd,label:i.label,...a.hookTimeoutSeconds!==void 0?{timeoutSeconds:a.hookTimeoutSeconds}:{}});u.ok||(d=`postCreate failed: ${u.reason??"unknown"}`,this.logger?.warn?.(`session workspace: ${d} (${i.path})`))}return i.snapshot!==void 0&&await n.retainSnapshot(i,this.startRefFor(i.label),i.snapshot).catch(()=>{}),{cwd:i.path,workspace:{path:i.path,sourceCwd:i.sourceCwd,label:i.label,provider:i.provider,...i.snapshot!==void 0?{snapshot:i.snapshot}:{},...i.line!==void 0?{line:i.line}:{},...i.vcs!==void 0?{vcs:{...i.vcs}}:{},clean:!0},...d!==void 0?{isolationError:d}:{}}}logInfo(e){this.logger?.info(e)}async create(e){e={...e,cwd:ps(ie(e.cwd))};let t=e.timer??new Jt,n=await this.registry.getAgent(e.agentId);n&&n.id!==e.agentId&&(e={...e,agentId:n.id}),t.mark("create.canonicalize");let r=`${ye}${Pt()}`,o=await this.resolveWorkspace(e),i=o.cwd;t.mark("create.workspace");let a=await this.bootstrapAgent({timer:t,agentId:e.agentId,cwd:i,agentArgs:e.agentArgs,mcpServers:e.mcpServers,model:e.model,configDefaults:e.configDefaults,onInstallProgress:e.onInstallProgress,forwardedEnv:e.forwardedEnv,elicitationForms:e.elicitationForms,selfSessionId:r});if(e.transformChain&&e.transformChain.length>0){let c={...a.agentCapabilities??{}};for(let u of e.transformChain)if(u.intercepts.has("agent:initialize"))try{let l=await u.connection.request("hydra-acp/transformer/message",{token:`t_${Pt()}`,phase:"response",method:"initialize",direction:"agent\u2192daemon",sessionId:"(pre-session)",envelope:c});l.action==="stop"&&l.payload&&(c=l.payload)}catch{}a.agentCapabilities=c}t.mark("create.transformers");let d=new nn({sessionId:r,cwd:i,...o.workspace!==void 0?{workspace:o.workspace}:{},...o.isolationError!==void 0?{workspaceError:o.isolationError}:{},agentId:e.agentId,agent:a.agent,upstreamSessionId:a.upstreamSessionId,agentMeta:a.agentMeta,agentCapabilities:a.agentCapabilities,...a.modelVerb?{modelVerb:a.modelVerb}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,...this.backgroundTaskTracking!==void 0?{backgroundTaskTracking:this.backgroundTaskTracking}:{},orphanTimeoutMs:this.orphanTimeoutMs,idleEventTimeoutMs:this.idleEventTimeoutMs,logger:this.logger,spawnReplacementAgent:c=>this.bootstrapAgent({...c,mcpServers:c.mcpServers??[],selfSessionId:r}),loadExistingAgentSession:(c,u)=>this.bootstrapAgentLoad(c,{...u,mcpServers:u.mcpServers??[],selfSessionId:r}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:a.initialModel,currentMode:a.initialMode,agentModes:a.initialModes,agentModels:a.initialModels,agentConfigOptions:a.initialConfigOptions,transformChain:e.transformChain,parentSessionId:e.parentSessionId,originatingClient:e.originatingClient,interactive:e.interactive,forwardedEnv:e.forwardedEnv,elicitationForms:e.elicitationForms,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(d.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(d),scheduleCompaction:c=>this.scheduleCompaction(d.sessionId,c),resolveAgentId:async c=>(await this.registry.getAgent(c))?.id,getCompactionState:()=>this.getCompactionState(d.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(d.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(d.sessionId),uncompactHook:()=>this.performUncompact(d.sessionId),forkHook:c=>this.forkSession(d.sessionId,c??{}),workspaceHook:(c,u,l)=>this.runWorkspaceAction(d.sessionId,c,u,l),onCompactionSwapHook:c=>{this.persistRollbackBreadcrumb(d.sessionId,c).catch(()=>{})},persistWatermarkHook:c=>{this.mutateRecord(d.sessionId,{summarizedThroughEntry:c}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(d.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});if(t.mark("create.session-ctor"),o.workspace!==void 0){let c=oe(o.workspace.provider);c!==void 0&&c.capabilities().supports.environmentNotes&&(d.workspaceNotes=await c.environmentNotes({path:o.workspace.path,sourceCwd:o.workspace.sourceCwd,label:o.workspace.label,provider:o.workspace.provider,...o.workspace.snapshot!==void 0?{snapshot:o.workspace.snapshot}:{},...o.workspace.vcs!==void 0?{vcs:o.workspace.vcs}:{}}).catch(()=>[]))}return await this.attachManagerHooks(d),t.mark("create.persist"),d}async resurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t){if(t.upstreamSessionId!==e.upstreamSessionId){let o=new Error(`session ${e.hydraSessionId} already exists with a different upstream id`);throw o.code=x.AlreadyAttached,o}return t}let n=this.resurrectionInflight.get(e.hydraSessionId);if(n)return n;let r=this.doResurrect(e);this.resurrectionInflight.set(e.hydraSessionId,r);try{return await r}finally{this.resurrectionInflight.delete(e.hydraSessionId)}}async doResurrect(e){let t=this.sessions.get(e.hydraSessionId);if(t)return t;let n=await this.registry.getAgent(e.agentId);if(!n){let m=new Error(`agent ${e.agentId} not found in registry; cannot resurrect`);throw m.code=x.AgentNotInstalled,m}if(e.upstreamSessionId==="")return this.doResurrectFromImport(e);if(!await this.dirExists(e.cwd))return this.doResurrectFromImport(e);let r=await Me(n,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress}),o=ms(e.hydraSessionId,e.forwardedEnv),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...o?{extraEnv:o}:{}}),a;try{let m=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:this.clientCaps(e.elicitationForms),clientInfo:{name:"hydra",version:ue}});a=m.agentCapabilities,i.authMethods=Gn(m.authMethods),i.steeringSupported=Vn(m)}catch(m){throw await i.kill().catch(()=>{}),wt(m,i)}let d;try{let m=fi(n,{model:e.currentModel});d=await i.connection.request("session/load",{sessionId:e.upstreamSessionId,cwd:e.cwd,mcpServers:e.mcpServers??[],...m&&{_meta:m}})}catch(m){if(m&&typeof m=="object"&&m.code===x.AuthRequired)throw await i.kill().catch(()=>{}),wt(m,i);return process.stderr.write(`session/load failed for upstream ${e.upstreamSessionId} on ${e.agentId} (${m.message}); recovering via import-reseed
176
+ `),await i.kill().catch(()=>{}),this.doResurrectFromImport(e)}if(e.pendingHistorySync===!0)this.clearPendingHistorySync(e.hydraSessionId).catch(()=>{});else{let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain1 dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let c=hi(d??{}),u=e.agentModes??yt(mi(d??{}));this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedMode=${JSON.stringify(e.currentMode)} agentReportedMode=${JSON.stringify(c)} advertisedModes=${JSON.stringify(u?.map(m=>m.id))}`);let l=await ft({agent:i,upstreamSessionId:e.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:c,advertisedModes:u,logger:this.logger});this.logger?.info(`resurrect: effectiveMode=${JSON.stringify(l)} for sessionId=${e.hydraSessionId}`);let y=pi(d??{}),h=yt(gi(d??{}))??e.agentModels;if(this.logger?.info(`resurrect: sessionId=${e.hydraSessionId} persistedModel=${JSON.stringify(e.currentModel)} agentReportedModel=${JSON.stringify(y)} advertisedModels=${JSON.stringify(h?.map(m=>m.modelId))}`),e.pendingHistorySync!==!0){let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain2 (post-mode-restore) dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let f=zt(d),k=await pt({agent:i,upstreamSessionId:e.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:y,...f?{modelVerb:f}:{},logger:this.logger}),g=k.modelId,p=yt(cn(dn(k.result)?k.result:d??{}));if(p=yt(await this.restoreConfigOptionValues(i,e.upstreamSessionId,e.configOptionValues,p??[])),e.pendingHistorySync!==!0){let m=i.connection.drainBuffered("session/update");this.logger?.info(`resurrect: drain3 (post-model-restore) dropped ${m} buffered session/update(s) for sessionId=${e.hydraSessionId}`)}let w=new nn({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,...f?{modelVerb:f}:{},title:e.title,agentArgs:e.agentArgs,idleTimeoutMs:this.idleTimeoutMs,...this.backgroundTaskTracking!==void 0?{backgroundTaskTracking:this.backgroundTaskTracking}:{},orphanTimeoutMs:this.orphanTimeoutMs,logger:this.logger,spawnReplacementAgent:m=>this.bootstrapAgent({...m,mcpServers:m.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(m,v)=>this.bootstrapAgentLoad(m,{...v,mcpServers:v.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:g,currentMode:l,currentUsage:e.currentUsage,reloadsUpstreamLedger:!0,agentCommands:e.agentCommands,agentModes:u,agentModels:h,agentConfigOptions:p,summarizedThroughEntry:e.summarizedThroughEntry,compactionState:e.compactionState,firstPromptSeeded:!!e.title,upstreamRespawned:!0,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,tags:e.tags,lastTurnEndedAt:e.lastTurnEndedAt,readAt:e.readAt,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forwardedEnv:e.forwardedEnv,elicitationForms:e.elicitationForms,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(w.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(w),scheduleCompaction:m=>this.scheduleCompaction(w.sessionId,m),resolveAgentId:async m=>(await this.registry.getAgent(m))?.id,getCompactionState:()=>this.getCompactionState(w.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(w.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(w.sessionId),uncompactHook:()=>this.performUncompact(w.sessionId),forkHook:m=>this.forkSession(w.sessionId,m??{}),workspaceHook:(m,v,S)=>this.runWorkspaceAction(w.sessionId,m,v,S),onCompactionSwapHook:m=>{this.persistRollbackBreadcrumb(w.sessionId,m).catch(()=>{})},persistWatermarkHook:m=>{this.mutateRecord(w.sessionId,{summarizedThroughEntry:m}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(w.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(w),w}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,elicitationForms:e.elicitationForms,model:e.currentModel}),o=e.agentModes??r.initialModes,i=await ft({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedMode:e.currentMode,agentReportedMode:r.initialMode,advertisedModes:o,logger:this.logger}),a=e.agentModels??r.initialModels,d=await pt({agent:r.agent,upstreamSessionId:r.upstreamSessionId,persistedModel:e.currentModel,agentReportedModel:r.initialModel,...r.modelVerb?{modelVerb:r.modelVerb}:{},logger:this.logger}),c=d.modelId,u=dn(d.result)?yt(cn(d.result)):void 0;u=yt(await this.restoreConfigOptionValues(r.agent,r.upstreamSessionId,e.configOptionValues,u??r.initialConfigOptions??[])),r.agent.connection.drainBuffered("session/update");let l=new nn({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,...this.backgroundTaskTracking!==void 0?{backgroundTaskTracking:this.backgroundTaskTracking}:{},orphanTimeoutMs:this.orphanTimeoutMs,logger:this.logger,spawnReplacementAgent:y=>this.bootstrapAgent({...y,mcpServers:y.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),loadExistingAgentSession:(y,h)=>this.bootstrapAgentLoad(y,{...h,mcpServers:h.mcpServers??e.mcpServers??[],selfSessionId:e.hydraSessionId}),...e.mintMcpServersForSwap?{mintMcpServersForSwap:e.mintMcpServersForSwap}:{},listSessions:()=>this.list(),availableAgents:()=>this.agentCatalog,historyStore:this.histories,historyMaxEntries:this.sessionHistoryMaxEntries,currentModel:c,currentMode:i,currentUsage:e.currentUsage,agentCommands:e.agentCommands,agentModes:o,agentModels:a,agentConfigOptions:u??r.initialConfigOptions,summarizedThroughEntry:e.summarizedThroughEntry,firstPromptSeeded:!!e.title,upstreamRespawned:!0,createdAt:e.createdAt?new Date(e.createdAt).getTime():void 0,originatingClient:e.originatingClient,interactive:e.interactive,priority:e.priority,tags:e.tags,lastTurnEndedAt:e.lastTurnEndedAt,readAt:e.readAt,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forwardedEnv:e.forwardedEnv,elicitationForms:e.elicitationForms,mcpServers:e.mcpServers??[],extensionCommands:this.extensionCommands,attentionFlags:e.attentionFlags,scheduleSynopsis:()=>this.synopsisCoordinator.schedule(l.sessionId),scheduleWorkspaceSnapshot:()=>this.scheduleWorkspaceSnapshot(l),scheduleCompaction:y=>this.scheduleCompaction(l.sessionId,y),resolveAgentId:async y=>(await this.registry.getAgent(y))?.id,getCompactionState:()=>this.getCompactionState(l.sessionId),getUpstreamGenerations:()=>this.getUpstreamGenerations(l.sessionId),getPendingAgentSwap:()=>this.getPendingAgentSwap(l.sessionId),uncompactHook:()=>this.performUncompact(l.sessionId),forkHook:y=>this.forkSession(l.sessionId,y??{}),workspaceHook:(y,h,f)=>this.runWorkspaceAction(l.sessionId,y,h,f),onCompactionSwapHook:y=>{this.persistRollbackBreadcrumb(l.sessionId,y).catch(()=>{})},persistWatermarkHook:y=>{this.mutateRecord(l.sessionId,{summarizedThroughEntry:y}).catch(()=>{})},clearRollbackBreadcrumbHook:()=>{this.mutateRecord(l.sessionId,{},["rollbackBreadcrumb"]).catch(()=>{})}});return await this.attachManagerHooks(l),e.forkedFromSessionId&&e.forkSynthesisState==="running"?this.logger?.info(`fork ${l.sessionId}: synthesis in flight \u2014 skipping seed, recall available`):e.forkedFromSessionId&&(e.synopsis||(e.summarizedThroughEntry??0)>0)?l.seedFromFork(e.synopsis).catch(()=>{}):l.seedFromImport().catch(()=>{}),l}async dirExists(e){try{return(await Mt.stat(e)).isDirectory()}catch{return!1}}async reapIfOrphanedNonInteractive(e){let t=this.sessions.get(e);if(!(!t||t.attachedCount>0)&&t.interactive!==!0){if(t.hasWorkInFlight){this.logger?.info(`deferring reap of ${e}: work still in flight after detach`),t.onceIdle(n=>{this.reapIfOrphanedNonInteractive(n.sessionId).catch(()=>{})});return}this.logger?.info(`reaping orphaned non-interactive session ${e} (agent killed, cold record kept)`),await t.close({deleteRecord:!1,by:"reap-orphaned"}).catch(()=>{})}}async resolveResurrectTarget(e,t){if(await this.dirExists(e))return t!==void 0?{cwd:e,workspace:t}:{cwd:e};if(t!==void 0){let n=await this.recoverWorkspace(t);if(n!==void 0)return{cwd:n.path,workspace:n}}return{cwd:ie(this.defaultCwd)}}async releaseWorkspace(e,t){let n=oe(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(`${F(t.path)} is shared with ${r.map(h=>nt(h.sessionId)).join(", ")}, and a sync would move files under them. Sync it from a session that has it to itself.`);let o=await e.quiesceBlocker();if(o!==void 0)throw new Error(o);let i=oe(t.provider);if(t.line===void 0||i?.capabilities().sharedHistory!==!0)throw new Error(`workspace ${t.label} uses the "${t.provider}" provider, which has no history to merge from \u2014 a sync needs a common base, and a copied directory has none. Land its work with \`/hydra workspace merge\` instead, or start a git-backed workspace if you need to track the source.`);let[a,d]=await Promise.all([i.currentState(t.sourceCwd),i.currentState(t.path)]);if(a===void 0||d===void 0)throw new Error("could not read the state of the source or the workspace");if(await i.contains(t.path,{state:a,within:d}))return{ok:!0,message:`Already up to date with ${F(t.sourceCwd)} (${a.slice(0,8)}).`};let c=await i.divergence(t.path,d,a),u=String(c?.behind??0),l=await i.integrate({into:t.path,from:a,message:`hydra: sync ${t.label} with the source`});if(!l.ok){let h=l.conflicts,f=await i.integrationInProgress(t.path);if(h.length===0&&!f){let g=await this.syncOverDirtyTree(t,{provider:i,before:d,sourceHead:a,incoming:u});if(g!==void 0)return g}let k=h.length>0?`
177
+ ${h.map(g=>` ${g}`).join(`
178
+ `)}`:` (${l.reason??"the integration failed"})`;return h.length===0?{ok:!1,message:`the source could not be merged into ${F(t.path)}; nothing changed.${k}
179
+ `+(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 i.abortIntegration(t.path).catch(()=>{}),{ok:!1,message:`${h.length} file(s) conflict between the source and this workspace:${k}`}):{ok:!1,message:`Synced with conflicts. ${h.length} file(s) need resolving in ${F(t.path)}:${k}
180
+ 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 y=(await i.changedPathsBetween(t.path,d,l.snapshot)).length;return{ok:!0,message:`Synced ${F(t.path)} with ${F(t.sourceCwd)}: ${u} commit(s), ${y} 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 c=await n.captureWorkingState(e.path,`hydra: work set aside to sync ${e.label}`).catch(()=>{});if(c===void 0)return;let u=xc(e.label);if(await n.retainSnapshot(a,u,c).then(()=>n.resolveRetained(a,u)).catch(()=>{})===void 0)return;let y={clean:!1,snapshot:c,base:r},h=`git -C ${e.path} cherry-pick --no-commit ${u} # 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 Et({source:e.path,capture:y,provider:n});return{ok:!1,message:`Could not clear ${F(e.path)} to merge into it, so nothing was synced. ${v?"Your uncommitted work is back in place.":`Your uncommitted work is at ${u}: ${h}`}`}}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 Et({source:e.path,capture:y,provider:n});return v&&await n.dropSnapshotRef(a,u).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.
181
+ `+(v?`Your uncommitted work is back in place (unstaged) and nothing else changed. Commit it in ${F(e.path)}, then \`/hydra workspace sync\` again to resolve the conflict there.`:`Your uncommitted work could not be put back and is preserved at ${u}. Recover it with:
182
+ ${h}`)}}let g=await Et({source:e.path,capture:y,provider:n}),p=await n.currentState(e.path),w=p===void 0?0:(await n.changedPathsBetween(e.path,r,p)).length,m=`Synced ${F(e.path)} with ${F(e.sourceCwd)}: ${i} commit(s), ${w} file(s) changed.`;return g?(await n.dropSnapshotRef(a,u).catch(()=>{}),{ok:!0,message:`${m} Your uncommitted work was set aside for the merge and restored on top.`}):{ok:!1,message:`${m}
172
183
  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 ${u} if you would rather start over:
173
- ${h}`}}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=oe(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 Us(t.sourceCwd).catch(()=>({}));if(o.preRemove!==void 0){let a=await Ls(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"}`)}let i=await e.status(r).catch(()=>({clean:!1,changedPaths:["<unknown>"],hasRecordedWork:!1}));if(i.changedPaths.length>0){await e.dropSnapshotRef(r,tn(t.label).autosave).catch(()=>{}),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}for(let a of dc(t.label))await e.dropSnapshotRef(r,a).catch(()=>{});await e.removeWorkspace(r,{force:!0}).catch(a=>this.logger?.warn?.(`session workspace: could not remove ${t.path}: ${String(a)}`))}snapshotRefFor(e){return tn(e).autosave}startRefFor(e){return tn(e).start}baselineRefFor(e){return tn(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=oe(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=oe(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(`
174
- ${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.
175
- `))}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)}.
176
- Use \`/hydra workspace start\` to move into an isolated workspace.`;let d=this.liveSessionsIn(a.path,o.sessionId).map(h=>tt(h.sessionId)),c=a.line,u=[`Isolated in ${O(a.path)}`,` source: ${O(a.sourceCwd)}`,` provider: ${a.provider}${c!==void 0?` (${c})`:""}`];d.length>0&&u.push(` shared with: ${d.join(", ")}`);let w=await oe(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 h of w??[])u.push(` ${h}`);return u.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."),u.join(`
177
- `)}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 c=d instanceof Error?d.message:String(d);throw o.broadcastWorkspacePhase({phase:"failed",error:c}),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(`
184
+ ${h}`}}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=oe(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`${F(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 Ys(t.sourceCwd).catch(()=>({}));if(o.preRemove!==void 0){let a=await Xs(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"}`)}let i=await e.status(r).catch(()=>({clean:!1,changedPaths:["<unknown>"],hasRecordedWork:!1}));if(i.changedPaths.length>0){await e.dropSnapshotRef(r,an(t.label).autosave).catch(()=>{}),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}for(let a of Ec(t.label))await e.dropSnapshotRef(r,a).catch(()=>{});await e.removeWorkspace(r,{force:!0}).catch(a=>this.logger?.warn?.(`session workspace: could not remove ${t.path}: ${String(a)}`))}snapshotRefFor(e){return an(e).autosave}startRefFor(e){return an(e).start}baselineRefFor(e){return an(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=oe(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=oe(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(`
185
+ ${F(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.
186
+ `))}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 ${F(o.cwd)}.
187
+ Use \`/hydra workspace start\` to move into an isolated workspace.`;let d=this.liveSessionsIn(a.path,o.sessionId).map(h=>nt(h.sessionId)),c=a.line,u=[`Isolated in ${F(a.path)}`,` source: ${F(a.sourceCwd)}`,` provider: ${a.provider}${c!==void 0?` (${c})`:""}`];d.length>0&&u.push(` shared with: ${d.join(", ")}`);let y=await oe(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 h of y??[])u.push(` ${h}`);return u.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."),u.join(`
188
+ `)}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 c=d instanceof Error?d.message:String(d);throw o.broadcastWorkspacePhase({phase:"failed",error:c}),d}return o.broadcastWorkspacePhase({phase:"entered",cwd:o.cwd,sourceCwd:i.sourceCwd,label:i.label}),[`${a.merged}; still working in ${F(i.path)}.`,...a.warnings].join(`
178
189
  `)}if(t==="apply"){o.broadcastWorkspacePhase({phase:"applying"});let a;try{a=await this.applyWorkspaceToSource(i,o.sessionId)}catch(d){let c=d instanceof Error?d.message:String(d);throw o.broadcastWorkspacePhase({phase:"failed",error:c}),d}return o.broadcastWorkspacePhase({phase:"entered",cwd:o.cwd,sourceCwd:i.sourceCwd,label:i.label}),[a.applied,...a.warnings].join(`
179
- `)}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 c=a.map(w=>tt(w.sessionId)).join(", "),u=[`Left ${O(i.path)} and returned to ${O(i.sourceCwd)}.`,`Nothing landed yet: ${c} still working there. It lands when the last session leaves.`],l=await this.fastForwardBlocked(i);return l!==void 0&&u.push(`WARNING: that merge will not fast-forward as things stand \u2014 ${l}`),u.join(`
190
+ `)}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 c=a.map(y=>nt(y.sessionId)).join(", "),u=[`Left ${F(i.path)} and returned to ${F(i.sourceCwd)}.`,`Nothing landed yet: ${c} still working there. It lands when the last session leaves.`],l=await this.fastForwardBlocked(i);return l!==void 0&&u.push(`WARNING: that merge will not fast-forward as things stand \u2014 ${l}`),u.join(`
180
191
  `)}o.broadcastWorkspacePhase({phase:"landing"});let d;try{d=await this.mergeWorkspaceIntoSource(i,o.sessionId)}catch(c){let u=c instanceof Error?c.message:String(c);throw o.broadcastWorkspacePhase({phase:"failed",error:u}),c}o.broadcastWorkspacePhase({phase:"returning"});try{await this.leaveWorkspace(o,i,{exit:"landed"})}catch(c){let u=c instanceof Error?c.message:String(c);throw new Error(`${d.merged}, but the session could not leave the workspace: ${u}`)}return[`${d.merged} and returned there; workspace removed.`,...d.warnings].join(`
181
- `)}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(u=>tt(u.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),c=[`Discarded ${O(i.path)} and its branch ${i.line??"(none)"}; returned to ${O(i.sourceCwd)}.`];return d!==void 0&&c.push(`The last autosave is kept at ${d} if you want it back: git -C ${i.sourceCwd} checkout ${d}`),c.join(`
182
- `)}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(`
183
- `)}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=oe(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=ac(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(m=>tt(m.sessionId)).join(", ")}, and a clean would destroy their work too. Clean it from a session that has it to itself.`);let o=await e.quiesceBlocker();if(o!==void 0)throw new Error(o);let i=oe(t.provider);if(i===void 0)throw new Error(`no provider "${t.provider}" available to clean this workspace`);if(t.snapshot===void 0||i.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 a=this.asWorkspace(t),d=t.snapshot,u=(await i.status(a).catch(()=>{}))?.changedPaths.length??0,w=(await i.divergence(t.path,d,"HEAD").catch(()=>{}))?.behind??0,h=await i.currentState(t.path)??"",f=await this.retireAutosave(t);e.broadcastWorkspacePhase({phase:"cleaning",label:t.label});let k=await i.resetTo(t.path,d,{purgeIgnored:n.deep});if(!k.ok)throw new Error(`could not return ${O(t.path)} to its base: ${k.reason??"unknown error"}. Nothing was changed.`);let p=n.deep?await this.applyWorkspaceSetup(t,e.sessionId):void 0;await i.retainSnapshot(a,this.startRefFor(t.label),t.snapshot).catch(()=>{});let g={...t,clean:!0};e.workspace=g,await this.mutateRecord(e.sessionId,{workspace:g}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:t.sourceCwd,label:t.label,...a.line!==void 0?{branch:a.line}:{}});let y=[`Cleaned ${O(t.path)} back to the state it was created in.`];if(u>0||w>0){let m=[];u>0&&m.push(`${u} uncommitted change(s)`),w>0&&m.push(`${w} commit(s)`),y.push(` discarded ${m.join(" and ")}`)}else y.push(" nothing to discard; it was already at its base");return p!==void 0&&y.push(` ${p}`),f!==void 0&&y.push(` last autosave kept at ${f}: git -C ${t.sourceCwd} checkout ${f}`),w>0&&h.length>0&&y.push(` discarded commits are still at ${h.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(`
184
- `)})}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=oe(e.provider),a=this.asWorkspace(e),d=await Wo({source:n,ws:a,startSnapshotRef:this.startRefFor(e.label),baselineRef:this.baselineRefFor(e.label),retainRef:Bo(t),provider:i});if(i===void 0)throw new Error(`no provider "${e.provider}" available to land this workspace`);let c=await i.currentState(n);if(c===void 0)throw new Error(`could not read the state of ${O(n)}`);let u=await i.contains(n,{state:c,within:r}),l=[];if(!u){let b=this.get(t),I="";if(b!==void 0)try{let A=await this.syncWorkspaceFromSource(b,e,{onConflict:"abort"});A.ok?(l.push(`
192
+ `)}if(t==="discard"){let a=this.liveSessionsIn(i.path,o.sessionId);if(a.length>0)throw new Error(`${F(i.path)} is shared with ${a.map(u=>nt(u.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),c=[`Discarded ${F(i.path)} and its branch ${i.line??"(none)"}; returned to ${F(i.sourceCwd)}.`];return d!==void 0&&c.push(`The last autosave is kept at ${d} if you want it back: git -C ${i.sourceCwd} checkout ${d}`),c.join(`
193
+ `)}return o.broadcastWorkspacePhase({phase:"returning"}),await this.leaveWorkspace(o,i,{exit:"detached"}),[`Returned to ${F(i.sourceCwd)} WITHOUT merging.`,`The workspace is still at ${F(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(`
194
+ `)}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=oe(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=Tc(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(`${F(t.path)} is shared with ${r.map(m=>nt(m.sessionId)).join(", ")}, and a clean would destroy their work too. Clean it from a session that has it to itself.`);let o=await e.quiesceBlocker();if(o!==void 0)throw new Error(o);let i=oe(t.provider);if(i===void 0)throw new Error(`no provider "${t.provider}" available to clean this workspace`);if(t.snapshot===void 0||i.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 a=this.asWorkspace(t),d=t.snapshot,u=(await i.status(a).catch(()=>{}))?.changedPaths.length??0,y=(await i.divergence(t.path,d,"HEAD").catch(()=>{}))?.behind??0,h=await i.currentState(t.path)??"",f=await this.retireAutosave(t);e.broadcastWorkspacePhase({phase:"cleaning",label:t.label});let k=await i.resetTo(t.path,d,{purgeIgnored:n.deep});if(!k.ok)throw new Error(`could not return ${F(t.path)} to its base: ${k.reason??"unknown error"}. Nothing was changed.`);let g=n.deep?await this.applyWorkspaceSetup(t,e.sessionId):void 0;await i.retainSnapshot(a,this.startRefFor(t.label),t.snapshot).catch(()=>{});let p={...t,clean:!0};e.workspace=p,await this.mutateRecord(e.sessionId,{workspace:p}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:t.sourceCwd,label:t.label,...a.line!==void 0?{branch:a.line}:{}});let w=[`Cleaned ${F(t.path)} back to the state it was created in.`];if(u>0||y>0){let m=[];u>0&&m.push(`${u} uncommitted change(s)`),y>0&&m.push(`${y} commit(s)`),w.push(` discarded ${m.join(" and ")}`)}else w.push(" nothing to discard; it was already at its base");return g!==void 0&&w.push(` ${g}`),f!==void 0&&w.push(` last autosave kept at ${f}: git -C ${t.sourceCwd} checkout ${f}`),y>0&&h.length>0&&w.push(` discarded commits are still at ${h.slice(0,12)} (and in the reflog for ${t.line??"this branch"})`),w.push(`Your uncommitted work in ${F(t.sourceCwd)} was never touched by this.`),w.join(`
195
+ `)})}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 ${F(n)} no longer exists`);let i=oe(e.provider),a=this.asWorkspace(e),d=await si({source:n,ws:a,startSnapshotRef:this.startRefFor(e.label),baselineRef:this.baselineRefFor(e.label),retainRef:ni(t),provider:i});if(i===void 0)throw new Error(`no provider "${e.provider}" available to land this workspace`);let c=await i.currentState(n);if(c===void 0)throw new Error(`could not read the state of ${F(n)}`);let u=await i.contains(n,{state:c,within:r}),l=[];if(!u){let b=this.get(t),I="";if(b!==void 0)try{let A=await this.syncWorkspaceFromSource(b,e,{onConflict:"abort"});A.ok?(l.push(`
185
196
  synced with the source first: ${A.message}`),u=await i.contains(n,{state:c,within:r})):I=`
186
197
  A sync was attempted first and could not complete: ${A.message}`}catch(A){I=`
187
- A sync was attempted first but was refused: ${A instanceof Error?A.message:String(A)}`}if(!u){let A=await i.currentLineName(n)??"the source";throw new Error(`cannot fast-forward ${A} in ${O(n)} to ${r}. The source has moved on since this workspace was created. The source is untouched.${I}
188
- `+(I.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 w=i!==void 0&&i.capabilities().supports.nestedTrees?await i.captureNested(e.path,await i.listNested(e.path)).catch(()=>[]):[],h,f=await i.status(a).catch(()=>{});if(f!==void 0&&f.changedPaths.length>0&&(h=await i.captureWorkingState(e.path,`hydra: uncommitted work in ${e.label}`).catch(()=>{}),h===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,c)).ok)throw new Error(`could not clear ${O(n)} for the merge; your work is preserved at ${d.retainedRef}. Nothing was merged.`);let k=await i.integrate({into:n,from:r,fastForwardOnly:!0});if(!k.ok)throw new Error(`merge failed: ${k.reason??"unknown error"}`);let p=!0;if(h!==void 0){let b=await i.captureDelta(n,k.snapshot,h);b!==void 0&&(p=(await i.applyDelta(n,b)).ok)}let g=await Rt({source:n,capture:d,provider:i});g&&await Nn({source:n,ws:a,capture:d,provider:i});let y={applied:[],failed:[]},m=i!==void 0&&i.capabilities().supports.nestedTrees?await i.integrateNested(n,e.path,w).catch(()=>y):y,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 S=[];p||S.push(` WARNING: the workspace's uncommitted changes could not be replayed; they remain reachable from ${r}.`),g||S.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 b of m.failed)S.push(` WARNING: nested tree ${b.path} was NOT reconciled: ${b.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:S}}async applyWorkspaceToSource(e,t){let n=e.sourceCwd;if(!await this.dirExists(n))throw new Error(`source tree ${O(n)} no longer exists`);let r=oe(e.provider);if(r===void 0)throw new Error(`no provider "${e.provider}" available to apply this workspace`);if(!r.capabilities().supports.captureWorkingState)throw new Error(`provider "${e.provider}" cannot snapshot a working tree, so there is no change set to apply. Use \`/hydra workspace stop\` to land this workspace instead.`);let o=this.asWorkspace(e);if((await r.status({...o,path:n}).catch(()=>{}))?.hasStagedWork===!0)throw new Error(`${O(n)} already has changes staged for its next commit, and \`apply\` delivers into that same index: the two sets would be indistinguishable, and unstaging one would unstage both. Commit or unstage them first, or use \`/hydra workspace merge\`, which lands the work as commits and does not touch the index.`);let a=await r.currentState(n);if(a===void 0)throw new Error(`could not read the state of ${O(n)}`);let d=e.line,c=d!==void 0&&await r.contains(n,{state:a,within:d}).catch(()=>!1),u=c?a:e.snapshot??"";if(u.length===0)throw new Error(`workspace ${e.label} has no recorded base to measure its changes against, so there is no way to tell its work apart from what the source already had`);let l=await Wo({source:n,ws:o,startSnapshotRef:this.startRefFor(e.label),baselineRef:this.baselineRefFor(e.label),retainRef:Bo(t),provider:r}),w=r.capabilities().supports.nestedTrees?(await r.listNested(e.path).catch(()=>[])).filter(m=>m.changedPaths.length>0||m.recorded!==void 0&&m.recorded!==m.actual):[],h=await r.captureWorkingState(e.path,`hydra: apply from ${e.label}`).catch(()=>{});if(h===void 0)throw new Error(`could not snapshot the work in ${O(e.path)}; nothing was changed`);let f=await r.captureDelta(n,u,h);if(f===void 0)throw new Error(`could not work out what ${e.label} changed; ${O(n)} was not touched`);if(f.trim().length===0)return await Nn({source:n,ws:o,capture:l,provider:r}),{applied:`Nothing to apply: ${e.label} holds no changes ${O(n)} does not already have.`,warnings:[]};if(!l.clean&&!(await r.resetTo(n,a)).ok)throw new Error(`could not clear ${O(n)} to apply onto; your work is preserved at ${l.retainedRef}. Nothing was applied.`);let k=await r.applyDelta(n,f,{stage:!0,tolerant:!c});if(!k.ok){await r.resetTo(n,a).catch(()=>{});let m=await Rt({source:n,capture:l,provider:r});throw m&&await Nn({source:n,ws:o,capture:l,provider:r}),new Error(`could not apply ${e.label} into ${O(n)}: ${k.reason??"the change set did not apply"}.`+(c?"":" The source has moved on since this workspace was created; `/hydra workspace sync` brings those commits in here, which is what lets the change set apply against them.")+(m?` ${O(n)} is as you left it.`:` Your uncommitted work there is preserved at ${l.retainedRef}.`))}let p=await Rt({source:n,capture:l,provider:r});p&&await Nn({source:n,ws:o,capture:l,provider:r});let g=await r.captureWorkingState(n,`hydra: source state after applying ${e.label}`).catch(()=>{});g!==void 0&&await r.retainSnapshot({...o,path:n},this.baselineRefFor(e.label),g).catch(()=>{});let y=[];k.alreadyPresent===!0&&y.push(` Nothing was staged: ${O(n)} already had every one of those changes.`),p||y.push(` WARNING: your own edits to ${O(n)} overlap the workspace's changes and could not be replayed on top. They are preserved at ${l.retainedRef}; recover with: git -C ${n} diff ${l.base} ${l.retainedRef}`);for(let m of w)y.push(` WARNING: nested tree ${m.relPath} was NOT included: a change set can only move the pointer to it, not what is inside. Land it with \`/hydra workspace stop\`, or copy that work across by hand.`);return{applied:`Applied ${e.label} into ${O(n)} as staged changes; still working in ${O(e.path)}.
189
- Nothing was committed: review it with \`git -C ${n} diff --cached\` and commit it however you like. The workspace and its history are untouched.`,warnings:y}}async leaveWorkspace(e,t,n){let r=n.exit!=="detached",o=oe(t.provider),i={path:t.path,sourceCwd:t.sourceCwd,label:t.label,provider:t.provider,...t.snapshot!==void 0?{snapshot:t.snapshot}:{},...t.vcs!==void 0?{vcs:t.vcs}:{}},a=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:t.sourceCwd,workspace:void 0,historyLength:a.length,note:`Returned to the source tree at ${t.sourceCwd}`+(n.exit==="landed"?" after merging the workspace.":n.exit==="discarded"?" after discarding the workspace and its work.":" without merging."),...await this.recordSynopsisFor(e.sessionId),left:{path:t.path,removed:r}}),await this.mutateRecord(e.sessionId,{cwd:e.cwd},["workspace"]),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"left",cwd:e.cwd,sourceCwd:t.sourceCwd,integrated:n.exit==="landed"}),o!==void 0&&await this.enqueueKeyed(this.workspaceQueues,t.path,async()=>{let d=this.liveSessionsIn(t.path,e.sessionId);if(d.length>0){this.logger?.info?.(`session workspace: ${e.sessionId} left ${t.path}; ${d.length} live session(s) remain, so it stays`);return}await this.reclaimAfterLastLeaver(o,i,t,e.sessionId,n)})}async reclaimAfterLastLeaver(e,t,n,r,o){await e.unlock(t).catch(()=>{});for(let i of[this.startRefFor(n.label),this.baselineRefFor(n.label)])await e.dropSnapshotRef(t,i).catch(()=>{});o.exit!=="detached"&&(o.exit==="landed"&&await e.dropSnapshotRef(t,this.snapshotRefFor(n.label)).catch(()=>{}),await e.removeWorkspace(t,{force:!0,discardLine:!0}).catch(()=>{}))}async joinDivergence(e,t,n){let[r,o]=await Promise.all([e.captureWorkingState(t,"hydra: source state at join").catch(()=>{}),e.captureWorkingState(n.path,"hydra: workspace state at join").catch(()=>{})]);if(r===void 0||o===void 0)return`could not compare ${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=oe(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,note:`Continuing in an isolated workspace at ${n.path}, derived from ${r}, shared with another session.`,...await this.recordSynopsisFor(e.sessionId)}),await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache();let a=n.line;e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:n.sourceCwd,label:n.label,...a!==void 0?{branch:a}:{}});let d=this.liveSessionsIn(n.path,e.sessionId).map(u=>tt(u.sessionId)),c=[`Joined workspace ${O(n.path)}`,` source: ${O(n.sourceCwd)}`];return a!==void 0&&c.push(` branch: ${a}`),c.push(` shared with: ${d.join(", ")}`),c.push(" your edits will interleave with that session's"),c.push("Use `/hydra workspace stop` to leave; the work lands when the last session leaves."),c.join(`
190
- `)})}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=oe();if(o===void 0)throw new Error("no workspace provider available");let i=await e.quiesceBlocker();if(i!==void 0)throw new Error(i);let a=o.capabilities();if(t!==void 0){let b=this.liveSessionsWithLabel(r,t)[0];if(b!==void 0&&b.workspace!==void 0)return await this.joinWorkspace(e,b,b.workspace,r)}let d,c=[],u=!1,l=!1,w=[],h=[],f=n?.clean===!0;if(a.supports.captureWorkingState){let b=await o.status({path:r,sourceCwd:r,label:"source",provider:o.kind}).catch(()=>{});l=b!==void 0;let I=a.supports.nestedTrees&&b!==void 0&&b.changedPaths.length>0?await o.listNested(r).catch(()=>[]):[];if(b!==void 0&&b.changedPaths.length>0&&f)w=Do(b.changedPaths,I);else if(b!==void 0&&b.changedPaths.length>0&&(c=Do(b.changedPaths,I),h=await o.captureNested(r,I).catch(()=>[]),u=b.hasStagedWork===!0,d=await o.captureWorkingState(r,"hydra: work carried into workspace").catch(()=>{}),d===void 0))throw new Error("could not snapshot your uncommitted work, so refusing to move it. Commit or stash first.")}e.broadcastWorkspacePhase({phase:"provisioning"});let k=await o.createWorkspace({sourceCwd:r,label:t??`s-${e.sessionId.slice(-8)}`});if(!k.ok)throw e.broadcastWorkspacePhase({phase:"failed",error:k.reason}),new Error(k.reason);let p=k.workspace,g=this.startRefFor(p.label),y,m=!1,v=[];try{a.locking&&await o.lock(p,`session ${e.sessionId}`).catch(()=>{});let b=d??p.snapshot;if(b===void 0)throw new Error(`provider "${p.provider}" gave the workspace no base to anchor landing against`);await o.retainSnapshot(p,g,b),e.broadcastWorkspacePhase({phase:"setup"}),m=d!==void 0?await this.copyCarriedWork(p,d,r):!0;let I=await this.materializeNestedTrees(p);if(h.length>0){let T=await o.reproduceNested(p.path,r,h).catch(R=>({applied:[],failed:h.map(P=>({path:P.relPath,reason:R instanceof Error?R.message:String(R)}))}));T.failed.length>0&&(m=!1,v=T.failed)}y=await this.applyWorkspaceSetup(p,e.sessionId),I!==void 0&&(y=y===void 0?I:`${I}; ${y}`),e.broadcastWorkspacePhase({phase:"swapping"});let A=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:p.path,workspace:{path:p.path,sourceCwd:p.sourceCwd,label:p.label,...t!==void 0&&t!==p.label?{requestedLabel:t}:{},provider:p.provider,...p.snapshot!==void 0?{snapshot:p.snapshot}:{},...p.line!==void 0?{line:p.line}:{},...p.vcs!==void 0?{vcs:{...p.vcs}}:{},...d===void 0?{clean:!0}:{}},historyLength:A.length,note:`Continuing in an isolated workspace at ${p.path}, derived from ${r}.`,...await this.recordSynopsisFor(e.sessionId)})}catch(b){let I=await this.unwindStartWorkspace({provider:o,ws:p,startRef:g,carried:d}),A=b instanceof Error?b.message:String(b);throw e.broadcastWorkspacePhase({phase:"failed",error:A}),new Error(I===void 0?A:`${A}
191
- ${I}`)}await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:p.sourceCwd,label:p.label,...p.line!==void 0?{branch:p.line}:{}});let S=[`Moved into workspace ${O(p.path)}`,` source: ${O(r)}`];if(p.line!==void 0&&S.push(` branch: ${p.line}`),t!==void 0&&t!==p.label&&S.push(` note: "${t}" was already taken by a surviving branch, so this is "${p.label}"`),d!==void 0){S.push(m?` carried ${c.length} uncommitted file(s) in; the source tree is untouched:`:` WARNING: could not copy ${c.length} uncommitted file(s); the workspace starts from HEAD. They are untouched in the source tree:`);for(let b of Ct(c))S.push(` ${b}`);m&&u&&S.push(" staging did not come along; everything above is unstaged here");for(let b of v)S.push(` nested tree ${b.path}: ${b.reason}`)}else if(w.length>0){S.push(` started clean: ${w.length} uncommitted file(s) stayed in the source and did NOT come along:`);for(let b of Ct(w))S.push(` ${b}`)}else l&&S.push(" source tree was clean; nothing carried in");return y!==void 0&&S.push(` ${y}`),S.push("Use `/hydra workspace stop` to merge back and return."),S.join(`
192
- `)}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=oe(e.provider);return o===void 0?!1:(await o.applyDelta(e.path,r)).ok}async patchFromSnapshot(e,t,n){let r=oe(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=oe(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 Us(e.sourceCwd).catch(()=>({})),r=[];if(n.carry!==void 0&&n.carry.length>0){let o=await qo(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 Ls(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=oe(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=oe(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=oe(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 p=new Error(`agent ${e} not found in registry`);throw p.code=x.AgentNotInstalled,p}let n=await Me(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:jc.homedir(),plan:n}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:Lt,clientInfo:{name:"hydra",version:ue}})}catch(p){throw await r.kill().catch(()=>{}),ht(p,r)}if(r.authMethods=Bn(o.authMethods),r.steeringSupported=Ln(o),(o.agentCapabilities??{}).sessionCapabilities?.list===void 0)throw await r.kill().catch(()=>{}),new Error(`agent ${e} does not advertise sessionCapabilities.list; cannot sync`);let a;try{a=await this.collectAgentSessions(r)}catch(p){throw await r.kill().catch(()=>{}),p}await r.kill().catch(()=>{});let d=new Map,c=Xr(t);d.set(e,c);let u=new Set,l=new Map;for(let p of this.sessions.values()){let g=await this.agentStoreKey(p.agentId,d);u.add(`${g}::${p.upstreamSessionId}`),g===c&&l.set(p.upstreamSessionId,p)}let w=await this.store.list().catch(()=>[]);for(let p of w){u.add(`${await this.agentStoreKey(p.agentId,d)}::${p.upstreamSessionId}`);for(let g of p.upstreamGenerations??[])u.add(`${await this.agentStoreKey(g.agentId,d)}::${g.upstreamSessionId}`)}let h=E.sessionsDir(),f=[],k=0;for(let p of a){l.get(p.sessionId)?.noteUpstreamUpdatedAt(p.updatedAt);let g=`${c}::${p.sessionId}`;if(u.has(g)){k+=1;continue}if(Hh(p.cwd,h)){k+=1;continue}let y=c,m=await this.tombstones.read(y,p.sessionId).catch(()=>{});if(!m&&c!==e&&(y=e,m=await this.tombstones.read(y,p.sessionId).catch(()=>{})),m){if(!cc(m,p.updatedAt)){k+=1;continue}await this.tombstones.remove(y,p.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${p.sessionId} (upstream updatedAt advanced past ${m.upstreamUpdatedAt??"<unset>"})`)}u.add(g);let v=`${ye}${xt()}`,S=new Date().toISOString(),b=p.updatedAt??S,I={sessionId:v,lineageId:$n(),upstreamSessionId:p.sessionId,agentId:e,cwd:p.cwd,pendingHistorySync:!0,interactive:!jh(p.title),createdAt:b,updatedAt:b};p.title!==void 0&&(I.title=p.title);let A=Fo(I);await this.store.write(A),f.push({version:1,...A})}return{synced:f,skipped:k}}async listTombstones(e={}){let t=e.grep?.toLowerCase();return(await this.tombstones.list(e.agentId)).filter(r=>e.since===void 0||r.deletedAt>=e.since).filter(r=>t===void 0||[r.title,r.cwd,r.sessionId,r.upstreamSessionId].some(o=>o?.toLowerCase().includes(t))).sort((r,o)=>r.deletedAt<o.deletedAt?1:-1)}async undeleteSessions(e){let t=await this.tombstones.list(),n=[],r=[],o=[];for(let a of e){let d=t.filter(u=>u.upstreamSessionId===a),c=d.length>0?d:t.filter(u=>u.sessionId===a||u.sessionId===`${ye}${a}`);if(c.length===0){r.push({id:a,reason:"no tombstone found"});continue}if(c.length>1){r.push({id:a,reason:"ambiguous: several tombstones match; pass an upstream id",candidates:c.map(u=>u.upstreamSessionId)});continue}o.push({id:a,tombstone:c[0]})}let i=new Map;for(let a of o){let d=i.get(a.tombstone.agentId)??[];d.push(a),i.set(a.tombstone.agentId,d)}for(let[a,d]of i){let c=l=>{let{version:w,...h}=l;return this.tombstones.add(h).catch(()=>{})};for(let l of d)await this.tombstones.remove(a,l.tombstone.upstreamSessionId);let u;try{u=(await this.syncFromAgent(a)).synced}catch(l){for(let w of d)await c(w.tombstone),r.push({id:w.id,reason:`agent sync failed: ${l.message}`});continue}for(let l of d){let w=u.find(h=>h.upstreamSessionId===l.tombstone.upstreamSessionId);if(!w){await c(l.tombstone),r.push({id:l.id,reason:`agent ${a} no longer lists this session`});continue}n.push({id:l.id,sessionId:w.sessionId,upstreamSessionId:l.tombstone.upstreamSessionId})}}return{restored:n,failed:r}}async collectAgentSessions(e){let t=[],n,r=new Set;for(let o=0;o<100;o+=1){let i={};n!==void 0&&(i.cursor=n);let a=await e.connection.request("session/list",i),d=Array.isArray(a.sessions)?a.sessions:[];for(let c of d){if(typeof c.sessionId!="string"||typeof c.cwd!="string")continue;let u={sessionId:c.sessionId,cwd:c.cwd};typeof c.title=="string"&&(u.title=c.title),typeof c.updatedAt=="string"&&(u.updatedAt=c.updatedAt),t.push(u)}if(typeof a.nextCursor!="string"||a.nextCursor.length===0||r.has(a.nextCursor))break;r.add(a.nextCursor),n=a.nextCursor}return t}async applySeedModel(e,t,n,r,o){try{let{verb:i,result:a}=await ut({request:(d,c)=>e.connection.request(d,c),sessionId:t,modelId:n,...o?{verb:o}:{},logger:this.logger});return this.logger?.info(`${r}: ${i} accepted`),{accepted:!0,result:a}}catch(i){return this.logger?.warn(`${r} rejected by agent (${i.message}); session will use the agent's own default`),{accepted:!1}}}async applySeedMode(e,t,n,r){try{let o=await e.connection.request("session/set_mode",{sessionId:t,modeId:n});return this.logger?.info(`${r}: session/set_mode accepted`),{accepted:!0,result:o}}catch(o){return this.logger?.warn(`${r} rejected by agent (${o.message}); session will use the agent's own default mode`),{accepted:!1}}}async restoreConfigOptionValues(e,t,n,r){if(!n||Object.keys(n).length===0)return this.logger?.info(`resurrect: no persisted configOptionValues; agent reports ${JSON.stringify(Object.fromEntries(r.map(i=>[i.id,i.currentValue])))}`),r;let o=r;for(let[i,a]of Object.entries(n)){let d=`resurrect: persisted configOptionValues.${i}=${JSON.stringify(a)}`,c=o.find(w=>w.id===i);if(!c){this.logger?.warn(`${d}: agent does not currently advertise configId=${i}; skipping session/set_config_option`);continue}if(a===c.currentValue){this.logger?.info(`${d}: agent already reports ${JSON.stringify(c.currentValue)}; nothing to restore`);continue}this.logger?.info(`${d}: agent reports ${JSON.stringify(c.currentValue)}; restoring`);let u=Kt(a,c.options.map(w=>w.value));if(u.kind!=="exact"&&u.kind!=="resolved"){this.logger?.warn(`${d} ${u.kind}; skipping session/set_config_option`);continue}let l=u.kind==="resolved"?u.modelId:a;try{let w=await e.connection.request("session/set_config_option",{sessionId:t,configId:i,value:l});this.logger?.info(`${d}: session/set_config_option accepted`),o=nn(w)?sn(w):o.map(h=>h.id===i?{...h,currentValue:l}:h)}catch(w){this.logger?.warn(`${d}: session/set_config_option rejected by agent (${w.message})`)}}return o}async bootstrapAgent(e){let t=e.timer,n=await this.registry.getAgent(e.agentId);if(!n){let a=new Error(`agent ${e.agentId} not found in registry`);throw a.code=x.AgentNotInstalled,a}t?.mark("boot.resolve-agent");let r=await Me(n,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress});t?.mark("boot.plan-spawn");let o=cs(e.selfSessionId,e.forwardedEnv),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...o?{extraEnv:o}:{}});t?.mark("boot.spawn");try{let a=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:Lt,clientInfo:{name:"hydra",version:ue}}),d=a.agentCapabilities;i.authMethods=Bn(a.authMethods),i.steeringSupported=Ln(a),t?.mark("boot.initialize");let c=Xo(n),u=await i.connection.request("session/new",{cwd:e.cwd,mcpServers:e.mcpServers??[],...c&&{_meta:c}});t?.mark("boot.session-new");let l=u.sessionId;if(typeof l!="string")throw new Error(`agent ${e.agentId} returned a non-string sessionId from session/new`);let w=Zo(u),h=ei(u),f=Wt(u),k=ka(this.sessionDefaults,n),p=k?.value,g=e.configDefaults,y=k?.from??e.agentId,m=e.model??g?.model??p?.model,v;if(m&&m!==w){let R=Gt(m,h),P=e.model!==void 0?`model=${JSON.stringify(m)}`:g?.model!==void 0?`configDefaults.model=${JSON.stringify(m)}`:`sessionDefaults[${y}].model=${JSON.stringify(m)}`;if(R.kind==="exact"||R.kind==="none"){let $=await this.applySeedModel(i,l,m,P,f);$.accepted&&(w=m,v=$.result)}else if(R.kind==="resolved")if(R.modelId===w)w=R.modelId;else{let $=await this.applySeedModel(i,l,R.modelId,`${P} resolved to ${JSON.stringify(R.modelId)}`,f);$.accepted&&(w=R.modelId,v=$.result)}else if(R.kind==="ambiguous")this.logger?.warn(`${P} is ambiguous (trailing-segment matches [${R.candidates.join(", ")}]); skipping session/set_model, session will use ${JSON.stringify(w)}`);else{let $=h.map(H=>H.modelId).join(", ");this.logger?.warn(`${P} not in agent's availableModels ([${$}]); skipping session/set_model, session will use ${JSON.stringify(w)}`)}}t?.mark("boot.seed-model");let S=ti(u),b=ni(u),I=g?.mode??p?.mode;if(I&&I!==b){let R=g?.mode!==void 0?`configDefaults.mode=${JSON.stringify(I)}`:`sessionDefaults[${y}].mode=${JSON.stringify(I)}`;if(S.length>0&&!S.some(P=>P.id===I)){let P=S.map($=>$.id).join(", ");this.logger?.warn(`${R} not in agent's availableModes ([${P}]); skipping session/set_mode, session will use ${JSON.stringify(b)}`)}else{let P=await this.applySeedMode(i,l,I,R);P.accepted&&(b=I,nn(P.result)&&(v=P.result))}}t?.mark("boot.seed-mode");let A={...p??{},...g??{}};delete A.model,delete A.mode;let T=sn(nn(v)?v:u);if(Object.keys(A).length>0)for(let[R,P]of Object.entries(A)){let $=`sessionDefaults[${y}].${R}=${JSON.stringify(P)}`,H=T.find(L=>L.id===R);if(!H){this.logger?.warn(`${$}: agent does not currently advertise configId=${R}; skipping session/set_config_option`);continue}let J=Kt(P,H.options.map(L=>L.value));if(J.kind!=="exact"&&J.kind!=="resolved"){this.logger?.warn(`${$} ${J.kind}; skipping session/set_config_option`);continue}let z=J.kind==="resolved"?J.modelId:P;if(z!==H.currentValue)try{let L=await i.connection.request("session/set_config_option",{sessionId:l,configId:R,value:z});this.logger?.info(`${$}: session/set_config_option accepted`),nn(L)?(T=sn(L),v=L):T=T.map(U=>U.id===R?{...U,currentValue:z}:U)}catch(L){this.logger?.warn(`${$}: session/set_config_option rejected by agent (${L.message})`)}}return t?.mark("boot.seed-config"),i.connection.dropBufferedWhere("session/update",R=>R?.update?.sessionUpdate==="config_option_update"),{agent:i,upstreamSessionId:l,agentMeta:u._meta,agentCapabilities:d,initialModel:w,initialModels:h.length>0?h:void 0,initialModes:S.length>0?S:void 0,initialMode:b,initialConfigOptions:T.length>0?T:void 0,modelVerb:f}}catch(a){throw await i.kill().catch(()=>{}),ht(Dc(a,i,e.agentId,{command:r.command,args:r.args,cwd:e.cwd}),i)}}async bootstrapAgentLoad(e,t){let n=await this.registry.getAgent(t.agentId);if(!n){let a=new Error(`agent ${t.agentId} not found in registry`);throw a.code=x.AgentNotInstalled,a}let r=await Me(n,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=cs(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:Lt,clientInfo:{name:"hydra",version:ue}}),d=a.agentCapabilities;i.authMethods=Bn(a.authMethods),i.steeringSupported=Ln(a);let c=Xo(n),u=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...c&&{_meta:c}}),l=Zo(u),w=mt(ei(u)),h=ti(u),f=ni(u),k=mt(sn(u));return{agent:i,upstreamSessionId:e,agentMeta:u._meta,agentCapabilities:d,initialModel:l,initialModels:w,initialModes:h.length>0?h:void 0,initialMode:f,initialConfigOptions:k,modelVerb:Wt(u)}}catch(a){throw await i.kill().catch(()=>{}),ht(Dc(a,i,t.agentId,{command:r.command,args:r.args,cwd:t.cwd}),i)}}async rewindSession(e,t,n={}){let r=await this.store.read(e);if(!r){let a=new Error(`session not found: ${e}`);throw a.code=x.SessionNotFound,a}if(this.rollbackLocks.has(e)||r.compactionState!=null){let a=new Error("the session is being compacted or rolled back; try again when that finishes");throw a.code=x.InvalidRequest,a}let o=0,i=async()=>{let a=await this.histories.truncateAfterTurn(e,t);if(!a){let u=new Error(`keepThrough messageId not found in the session's recent history: ${t}`);throw u.code=x.InvalidParams,u}if(o=a.removed,o===0)return!1;let d=r.summarizedThroughEntry,c=d!==void 0&&a.kept<d;if(c){let u=this.get(e);u&&(u.summarizedThroughEntry=void 0)}return await this.mutateRecord(e,{},c?["rollbackBreadcrumb","synopsis","summarizedThroughEntry"]:["rollbackBreadcrumb"]),!0};this.rollbackLocks.add(e);try{let a=this.get(e);a?await a.rewind(t,i,n):await i()&&await this.mutateRecord(e,{upstreamSessionId:""})}finally{this.rollbackLocks.delete(e)}return{sessionId:e,removed:o}}async performUncompact(e){if(this.rollbackLocks.has(e))throw new Error("a rollback is already in progress for this session");let t=this.get(e);if(!t)throw new Error("session is not live \u2014 cannot roll back a cold session");let n=await this.store.read(e);if(!n)throw new Error("session record not found");let r=n.rollbackBreadcrumb;if(!r)throw new Error("no rollback breadcrumb found \u2014 either the session has not been compacted, the rollback window has closed (a new turn was dispatched), or a previous rollback already consumed the breadcrumb");let o=n.compactionState;if(o!=null)throw new Error(`compaction is in progress (status: ${o.status}) \u2014 wait for it to complete before rolling back`);if(!await t.isQuiescedForSwap())throw new Error("session is not quiesced for rollback \u2014 wait for in-flight work to complete");this.rollbackLocks.add(e);try{await t.rollbackToUpstream({previousUpstreamSessionId:r.previousUpstreamSessionId,previousSummarizedThroughEntry:r.previousSummarizedThroughEntry}),await this.mutateRecord(e,{summarizedThroughEntry:r.previousSummarizedThroughEntry},["synopsis","rollbackBreadcrumb"])}finally{this.rollbackLocks.delete(e)}}async bootstrapAgentForAuth(e,t){let n=this.pendingAuthAgents.get(e);if(n&&n.isAlive())return n;let r=await this.registry.getAgent(e);if(!r){let d=new Error(`agent ${e} not found in registry`);throw d.code=x.AgentNotInstalled,d}let o=await Me(r,[],{npmRegistry:this.npmRegistry}),i=t??ie(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:Lt,clientInfo:{name:"hydra",version:ue}});a.authMethods=Bn(d.authMethods),a.steeringSupported=Ln(d)}catch(d){throw await a.kill().catch(()=>{}),ht(d,a)}return this.pendingAuthAgents.set(e,a),a.onExit(()=>{this.pendingAuthAgents.get(e)===a&&this.pendingAuthAgents.delete(e)}),a}async planSpawnForAgent(e){let t=await this.registry.getAgent(e);if(!t){let n=new Error(`agent ${e} not found in registry`);throw n.code=x.AgentNotInstalled,n}return Me(t,[],{npmRegistry:this.npmRegistry})}consumePendingAuthAgent(e){let t=this.pendingAuthAgents.get(e);if(t&&(this.pendingAuthAgents.delete(e),!!t.isAlive()))return t}getAgentForSession(e){return this.sessions.get(e)?.agent}async attachManagerHooks(e){e.onClose(({deleteRecord:t})=>{if(this.sessions.delete(e.sessionId),this.driftNoticed.delete(e.sessionId),this.invalidateListCache(),t||this.store.touch(e.sessionId).catch(()=>{}),t&&e.workspace!==void 0&&this.releaseWorkspace(e.workspace,e.sessionId).catch(()=>{}),t){if(e.upstreamSessionId){let r=rn({interactive:e.interactive,...e.originatingClient?{originatingClient:e.originatingClient}:{}},!0),o=this.tombstoneAllGenerations(e.sessionId,{agentId:e.agentId,upstreamSessionId:e.upstreamSessionId,upstreamUpdatedAt:new Date(e.updatedAt).toISOString(),cwd:e.cwd,...e.title!==void 0?{title:e.title}:{},...r!==void 0?{interactive:r}:{}},"user").catch(()=>{}).then(()=>this.store.delete(e.sessionId).catch(()=>{})).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===o&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,o);return}let n=this.store.delete(e.sessionId).catch(()=>{}).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===n&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,n);return}}),e.rewindHook=t=>this.rewindSession(e.sessionId,t,{afterCurrentTurn:!0}),e.onTitleChange(t=>{this.persistTitle(e.sessionId,t).catch(()=>{})}),e.onPriorityChange(t=>{this.persistPriority(e.sessionId,t).catch(()=>{})}),e.onAgentChange(({agentId:t,upstreamSessionId:n,...r})=>{this.persistAgentChange(e.sessionId,t,n,r).catch(()=>{})}),e.onModelChange(t=>{this.persistSnapshot(e.sessionId,{currentModel:t}).catch(()=>{})}),e.onModeChange(t=>{this.persistSnapshot(e.sessionId,{currentMode:t}).catch(()=>{})}),e.onInteractiveChange(t=>{this.persistSnapshot(e.sessionId,{interactive:t}).catch(()=>{})}),e.onUsageChange(t=>{this.persistSnapshot(e.sessionId,{currentUsage:Uc(t)}).catch(()=>{})}),e.onAgentCommandsChange(t=>{this.persistSnapshot(e.sessionId,{agentCommands:t.map(n=>({name:n.name,...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModesChange(t=>{this.persistSnapshot(e.sessionId,{agentModes:t.map(n=>({id:n.id,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModelsChange(t=>{this.persistSnapshot(e.sessionId,{agentModels:t.map(n=>({modelId:n.modelId,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onConfigOptionsChange(t=>{this.persistSnapshot(e.sessionId,{configOptionValues:Object.fromEntries(t.map(n=>[n.id,n.currentValue]))}).catch(()=>{})}),e.onAttentionFlagsChange(t=>{this.mutateRecord(e.sessionId,{attentionFlags:t}).catch(()=>{})}),e.onReadStateChange(t=>{this.invalidateListCache(),this.persistReadState(e.sessionId,t).then(()=>this.invalidateListCache()).catch(()=>{})}),this.sessions.set(e.sessionId,e),this.invalidateListCache(),await this.enqueueMetaWrite(e.sessionId,async()=>{let t=await this.store.read(e.sessionId),n=Uh(e,t);await this.store.write(n)}).catch(t=>{this.logger?.warn(`failed to persist session record for ${e.sessionId}: ${t instanceof Error?t.message:String(t)}`)})}async getHistory(e){if(this.sessions.has(e))return this.histories.load(e).catch(()=>[]);if(await this.store.read(e))return this.histories.load(e).catch(()=>[])}async pageHistory(e,t){let n=await this.store.read(e);if(!this.sessions.has(e)&&!n)return;let r=this.sessions.get(e)?.side??n?.side,o=await this.histories.pageBefore(e,{...t,skip:a=>En(a.method,a.params),hydrate:!1}),i=Bt(o.entries,r);return{entries:await this.histories.hydrate(e,ws(i)),hasMore:o.hasMore&&i.length===o.entries.length}}async loadHistory(e,t={}){return this.histories.load(e,t)}async loadToolBlob(e,t){return vn(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:Lh(t.currentUsage),agentCommands:t.agentCommands,agentModes:t.agentModes,agentModels:t.agentModels,configOptionValues:t.configOptionValues,createdAt:t.createdAt,pendingHistorySync:t.pendingHistorySync,originatingClient:t.originatingClient,interactive:t.interactive,priority:t.priority,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,forwardedEnv:t.forwardedEnv,workspace:t.workspace,compactionState:t.compactionState,attentionFlags:t.attentionFlags?.filter(r=>!(r.source==="daemon"&&r.reason.startsWith("permission:")))}}async setForwardedEnv(e,t){if(t===void 0)return;let n=this.sessions.get(e);n&&(n.forwardedEnv=t),await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r)return;let o={...r,forwardedEnv:t};await this.store.write(o)})}async clearPendingHistorySync(e){await this.enqueueMetaWrite(e,async()=>{let t=await this.store.read(e);if(!t||t.pendingHistorySync!==!0)return;let n={...t};delete n.pendingHistorySync,await this.store.write(n)})}async deriveTitleFromHistory(e){let t=await this.histories.load(e).catch(()=>[]);for(let n of t){let r=n.params;if(r?.update?.sessionUpdate!=="prompt_received")continue;let o=r.update.sentBy;if(typeof o?.fromSession=="string"||typeof o?.clientId=="string"&&o.clientId.startsWith("transformer:"))continue;let i=At(r.update.prompt),a=To(i,200);if(a&&!a.startsWith("/"))return a}}get(e){return this.sessions.get(e)}liveSessions(){return this.sessions.values()}setLiveConfig(e){e.sessionDefaults&&(this.sessionDefaults=e.sessionDefaults)}activeAgentVersions(){let e=new Map;for(let t of this.sessions.values()){let n=t.agent.installId,r=t.agent.version,o=e.get(n);o||(o=new Set,e.set(n,o)),o.add(r)}return e}async resolveCanonicalId(e){if(this.sessions.has(e)||await this.store.read(e))return e;if(e.startsWith(ye))return;let t=ye+e;if(this.sessions.has(t)||await this.store.read(t))return t}require(e){let t=this.sessions.get(e);if(!t){let n=new Error(`session ${e} not found`);throw n.code=x.SessionNotFound,n}return t}liveListEntry(e){return{sessionId:e.sessionId,upstreamSessionId:e.upstreamSessionId,cwd:e.cwd,workspace:e.workspace,workspaceError:e.workspaceError,title:e.title,agentId:e.agentId,currentModel:e.currentModel,currentUsage:e.currentUsage,parentSessionId:e.parentSessionId,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forkSynthesisState:e.forkSynthesisState,originatingClient:e.originatingClient,interactive:e.interactive,createdAt:new Date(e.createdAt).toISOString(),updatedAt:new Date(e.updatedAt).toISOString(),attachedClients:e.attachedCount,status:"warm",busy:e.turnStartedAt!==void 0,turnStartedAt:e.turnStartedAt,armedTasks:e.armedBackgroundTasks.length,...e.armedSince!==void 0?{armedSince:e.armedSince}:{},awaitingInput:e.awaitingInput,agentPid:e.agentPid,...zt(e)}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Wn(t.sessionId),d=rn({interactive:t.interactive,...t.originatingClient?{originatingClient:t.originatingClient}:{}},a.hasContent),c=a.mtime??new Date(t.updatedAt).toISOString();return{sessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,cwd:t.cwd,title:t.title,agentId:t.agentId,currentModel:t.currentModel,currentUsage:t.currentUsage,parentSessionId:t.parentSessionId,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,originatingClient:t.originatingClient,interactive:d,priority:t.priority,createdAt:new Date(t.createdAt).toISOString(),updatedAt:c,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,turnStartedAt:t.turnStartedAt,armedTasks:t.armedBackgroundTasks.length,...t.armedSince!==void 0?{armedSince:t.armedSince}:{},awaitingInput:t.awaitingInput,...zt(t)}}let n=await this.store.read(e).catch(()=>{});if(!n)return;let r=await Wn(n.sessionId),o=rn(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:Un(n.currentUsage),importedFromMachine:n.importedFromMachine,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,side:n.side,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:o,priority:n.priority,createdAt:n.createdAt,updatedAt:i,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,...zt(n)}}async list(e={}){return(await this.listing(e)).entries}async listing(e={}){let t=`${e.cwd??""}|${e.includeNonInteractive?"1":"0"}|${e.status??""}`,n=Date.now(),r=this.listCache.get(t);if(r&&r.expiresAt>n)return r.promise;let o=this.listUncached(e);return this.listCache.set(t,{expiresAt:n+s.LIST_CACHE_TTL_MS,promise:o}),o.catch(()=>{let i=this.listCache.get(t);i&&i.promise===o&&this.listCache.delete(t)}),o}invalidateListCache(){this.listCache.clear()}async listUncached(e={}){let t=await this.store.cursor(),{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,cursor:t};let o=await this.store.list().catch(i=>{throw this.logger?.warn(`session list: store.list() failed: ${i?.message??String(i)}`),i});return n.push(...await this.coldRows(o,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,cursor:t}}async listSince(e,t){let{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,removed:[],cursor:await this.store.cursor()};let o=await this.store.listChangedSince(t);return n.push(...await this.coldRows(o.records,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,removed:o.removed,cursor:o.cursor}}async seedSessionIndex(){await this.store.ensureIndex();let e=await this.tombstones.list().catch(()=>[]);for(let t of e){if(t.sessionId===void 0)continue;let n=Date.parse(t.deletedAt);Number.isNaN(n)||await this.store.markDeleted(t.sessionId,n)}}static includeRow(e,t){return e.includeNonInteractive?!0:t===!0}async warmRows(e){let t=[],n=new Set,r=[...this.sessions.values()].filter(i=>Fc(e.cwd,i));if(e.status==="cold"){for(let i of r)n.add(i.sessionId);return{entries:t,liveIds:n}}let o=await Promise.all(r.map(i=>Wn(i.sessionId)));for(let i=0;i<o.length;i+=1){let a=r[i],d=o[i];n.add(a.sessionId);let c=rn({interactive:a.interactive,...a.originatingClient?{originatingClient:a.originatingClient}:{}},d.hasContent);if(!s.includeRow(e,c))continue;let u=d.mtime??new Date(a.updatedAt).toISOString();t.push({sessionId:a.sessionId,upstreamSessionId:a.upstreamSessionId,cwd:a.cwd,workspace:a.workspace,workspaceError:a.workspaceError,title:a.title,agentId:a.agentId,currentModel:a.currentModel,currentUsage:a.currentUsage,parentSessionId:a.parentSessionId,forkedFromSessionId:a.forkedFromSessionId,forkedFromMessageId:a.forkedFromMessageId,side:a.side,originatingClient:a.originatingClient,interactive:c,priority:a.priority,createdAt:new Date(a.createdAt).toISOString(),updatedAt:u,attachedClients:a.attachedCount,status:"warm",agentPid:a.agentPid,busy:a.turnStartedAt!==void 0,turnStartedAt:a.turnStartedAt,armedTasks:a.armedBackgroundTasks.length,...a.armedSince!==void 0?{armedSince:a.armedSince}:{},awaitingInput:a.awaitingInput,compactionState:a.compactionState,forkSynthesisState:a.forkSynthesisState,...zt(a)})}return{entries:t,liveIds:n}}async coldRows(e,t,n){let r=[],o=e.filter(a=>!t.has(a.sessionId)&&Fc(n.cwd,a)),i=await Promise.all(o.map(a=>Wn(a.sessionId)));for(let a=0;a<o.length;a+=1){let d=o[a],c=i[a],u=rn(d,c.hasContent);if(!s.includeRow(n,u))continue;let l=c.mtime??d.updatedAt;r.push({sessionId:d.sessionId,upstreamSessionId:d.upstreamSessionId,cwd:d.cwd,workspace:d.workspace,title:d.title,agentId:d.agentId,currentModel:d.currentModel,currentUsage:Un(d.currentUsage),importedFromMachine:d.importedFromMachine,importedFromUpstreamSessionId:d.importedFromUpstreamSessionId,parentSessionId:d.parentSessionId,forkedFromSessionId:d.forkedFromSessionId,forkedFromMessageId:d.forkedFromMessageId,side:d.side,originatingClient:d.originatingClient,interactive:u,priority:d.priority,createdAt:d.createdAt,updatedAt:l,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,compactionState:d.compactionState,forkSynthesisState:d.forkSynthesisState,...zt(d)})}return r}async exportBundle(e,t={}){let n=await this.store.read(e);if(!n)return;let r;if(n.lineageId)r=n;else{let c=$n(),u={...n,lineageId:c};await this.enqueueMetaWrite(e,async()=>{let l=await this.store.read(e);l&&(l.lineageId||await this.store.write({...l,lineageId:c}))}).catch(()=>{}),r=u}let o=t.tools??"inline",i=t.includeArchivedHistory?await this.loadArchivedHistory(e,o):await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await Hc(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let c of xc(i)){let u=await ta(e,c);u&&(d[c]=u.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}async loadArchivedHistory(e,t){let n=await this.histories.loadArchives(e),r=await this.histories.load(e,{tools:"references",maxEntries:1/0}),o=[...n,...r];return t==="references"?o:this.histories.hydrate(e,o)}async importBundle(e,t={}){let n=await this.store.findByLineageId(e.session.lineageId);if(n){if(!t.replace){let i=new Error(`bundle already imported as ${n.sessionId}`);throw i.code=x.BundleAlreadyImported,i.existingSessionId=n.sessionId,i}let o=this.sessions.get(n.sessionId);return o&&await o.close({deleteRecord:!1,by:"bundle-import-overwrite"}).catch(()=>{}),await this.writeImportedRecord({sessionId:n.sessionId,bundle:e,preservedCreatedAt:n.createdAt,cwd:t.cwd}),{sessionId:n.sessionId,importedFromSessionId:e.session.sessionId,replaced:!0}}let r=`${ye}${xt()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let n=await this.store.read(e);if(!n){let b=new Error(`source session not found: ${e}`);throw b.code=x.SessionNotFound,b}let r=t.agentId??n.agentId,o=r!==n.agentId;if(o&&!await this.registry.getAgent(r)){let I=new Error(`agent ${r} not found in registry`);throw I.code=x.AgentNotInstalled,I}let i=await this.histories.load(e).catch(()=>[]),a=i,d,c=t.mode??(t.side?"verbatim":"synthesis"),u,l,w,h=12e4;if(c==="verbatim")if(t.forkAt!==void 0){let b=Hn(Qo(i),t.forkAt);if(b<0){let I=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw I.code=x.InvalidParams,I}d=t.forkAt,a=i.slice(0,b+1)}else{let b=zh(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 I=Hn(Qo(i),t.forkAt);if(I<0){let A=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw A.code=x.InvalidParams,A}d=t.forkAt,a=i.slice(0,I+1)}else d="",a=i;let b=await this.registry.getAgent(r);if(!b){let I=new Error(`agent ${r} not found in registry`);throw I.code=x.AgentNotInstalled,I}w=b,l=n.currentModel,u="running"}let f=await Hc(e),k=c==="synthesis",p={...n,lineageId:$n(),agentId:r,interactive:!1,...u!==void 0?{forkSynthesisState:u}:{},summarizedThroughEntry:a.length,...t.title!==void 0?{title:t.title}:{},currentUsage:void 0,...o?{currentModel:void 0,currentMode:void 0,agentCommands:void 0,agentModes:void 0,agentModels:void 0}:{},...t.model!==void 0?{currentModel:t.model}:{}},g=jn({record:p,history:a,promptHistory:f.length>0?f:void 0,hydraVersion:ue,machine:St()}),y=`${ye}${xt()}`,m=t.cwd===void 0?void 0:as(ie(t.cwd)),v;if(t.cwd===void 0&&n.workspace!==void 0){let b=await this.deriveForkWorkspace(n.workspace,`${n.workspace.label}-fork-${y.slice(-6)}`);b!==void 0?(v=b,m=b.path):(m=n.workspace.sourceCwd,this.logger?.warn?.(`fork ${y}: could not derive an isolated workspace from ${n.workspace.path}; running unisolated in ${m}`))}await this.writeImportedRecord({sessionId:y,bundle:g,cwd:m,...v!==void 0?{workspace:v}:{},forkedFromSessionId:e,forkedFromMessageId:d,...t.side!==void 0?{side:{...t.side.selection!==void 0?{selection:t.side.selection}:{},...Ua(a)}}:{},...u!==void 0?{forkSynthesisState:u}:{}});let S=k?(async()=>{try{let b=await Me(w,[],{npmRegistry:this.npmRegistry}),I=await zs({agentId:r,cwd:t.cwd??E.sessionDir(e),plan:b,history:a,modelId:l,sessionId:e,logger:this.logger,timeoutMs:h});I&&I.synopsis?await this.mutateRecord(y,{synopsis:I.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(y,{},["forkSynthesisState"]))}catch(b){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${b.message}`);try{await this.mutateRecord(y,{},["forkSynthesisState"])}catch(I){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${I.message}`)}}})():Promise.resolve();if(t.prompt!==void 0&&t.prompt.trim()!==""){let b=t.prompt;S.catch(()=>{}).then(()=>this.deliverHeadlessPrompt(y,b)).catch(I=>{this.logger?.warn(`forkSession(${e}): headless prompt delivery to ${y} failed: ${I.message}`)})}return{sessionId:y,forkedFromSessionId:e,forkedAt:d}}async deliverHeadlessPrompt(e,t){let n=await this.loadFromDisk(e);if(!n){this.logger?.warn(`deliverHeadlessPrompt: ${e} vanished before its prompt could be sent`);return}let r=this.sessions.get(e)??await this.resurrect(n),o=Dh(),i={clientId:`fork-prompt-${xt().slice(0,8)}`,connection:new We(o),clientInfo:{name:"hydra-acp-fork",version:ue}};await r.attach(i,"none");try{await r.prompt(i.clientId,{sessionId:e,prompt:[{type:"text",text:t}]})}finally{r.detach(i.clientId),o.close()}}async writeImportedRecord(e){if(await this.histories.rewrite(e.sessionId,e.bundle.history),e.bundle.toolBlobs)for(let[o,i]of Object.entries(e.bundle.toolBlobs))await na(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await Tt.utimes(E.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await _c(E.tuiHistoryFile(e.sessionId),e.bundle.promptHistory).catch(()=>{});let n=new Date().toISOString(),r=e.forkedFromSessionId!==void 0;await this.enqueueMetaWrite(e.sessionId,async()=>{await this.store.write({sessionId:e.sessionId,lineageId:e.bundle.session.lineageId,upstreamSessionId:"",...r?{forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,...e.side!==void 0?{side:e.side}:{}}:{importedFromSessionId:e.bundle.session.sessionId,importedFromUpstreamSessionId:e.bundle.session.upstreamSessionId,importedFromMachine:e.bundle.exportedFrom.machine},agentId:e.bundle.session.agentId,cwd:e.cwd??e.bundle.session.cwd,workspace:e.workspace,title:e.bundle.session.title,synopsis:e.bundle.session.synopsis,summarizedThroughEntry:e.bundle.session.summarizedThroughEntry,...e.forkSynthesisState!==void 0?{forkSynthesisState:e.forkSynthesisState}:{},currentModel:e.bundle.session.currentModel,currentMode:e.bundle.session.currentMode,currentUsage:e.bundle.session.currentUsage,agentCommands:e.bundle.session.agentCommands,agentModes:e.bundle.session.agentModes,interactive:e.bundle.session.interactive,originatingClient:e.bundle.session.originatingClient,priority:e.bundle.session.priority,attentionFlags:[],createdAt:e.preservedCreatedAt??n,updatedAt:e.bundle.session.updatedAt})})}async agentStoreKey(e,t){let n=t.get(e);if(n!==void 0)return n;let r=e;try{let o=await this.registry.getAgent(e);o&&(r=Xr(o))}catch{}return t.set(e,r),r}async tombstoneAllGenerations(e,t,n){let r=await this.store.read(e).catch(()=>{}),o=new Map;for(let d of r?.upstreamGenerations??[])d.upstreamSessionId&&o.set(`${d.agentId}::${d.upstreamSessionId}`,{agentId:d.agentId,upstreamSessionId:d.upstreamSessionId});o.set(`${t.agentId}::${t.upstreamSessionId}`,{agentId:t.agentId,upstreamSessionId:t.upstreamSessionId});let i=new Date().toISOString(),a=new Map;for(let d of o.values())await this.tombstones.add({agentId:await this.agentStoreKey(d.agentId,a),upstreamSessionId:d.upstreamSessionId,sessionId:e,deletedAt:i,upstreamUpdatedAt:t.upstreamUpdatedAt,cwd:t.cwd,...t.title!==void 0?{title:t.title}:{},reason:n,...t.interactive!==void 0?{interactive:t.interactive}:{}}).catch(()=>{})}async deleteRecord(e,t="user"){let n=await this.store.read(e);if(!n)return!1;if(n.upstreamSessionId){let r=await Wn(e),o=rn(n,r.hasContent);await this.tombstoneAllGenerations(e,{agentId:n.agentId,upstreamSessionId:n.upstreamSessionId,upstreamUpdatedAt:n.updatedAt,cwd:n.cwd,...n.title!==void 0?{title:n.title}:{},...o!==void 0?{interactive:o}:{}},t)}return n.workspace!==void 0&&await this.releaseWorkspace(n.workspace,e).catch(()=>{}),await this.store.delete(e).catch(()=>{}),await this.histories.delete(e).catch(()=>{}),this.invalidateListCache(),!0}async waitForDeletion(e){let t=this.pendingDeletions.get(e);t&&await t}async isTombstoned(e,t){let n=await this.agentStoreKey(e,new Map);return(await this.tombstones.read(n,t).catch(()=>{})??(n!==e?await this.tombstones.read(e,t).catch(()=>{}):void 0))?.reason==="user"}async hasRecord(e){return await this.store.read(e).catch(()=>{})!==void 0}async isRetiredGeneration(e,t){let n=await this.store.read(e).catch(()=>{});return!n||n.upstreamSessionId===t?!1:(n.upstreamGenerations??[]).some(r=>r.upstreamSessionId===t)}async clearWorkspaceBinding(e){if(this.get(e)!==void 0)return"live";let t=await this.store.read(e).catch(()=>{});if(!t)return"missing";let n=t.workspace?.sourceCwd;return await this.mutateRecord(e,n!==void 0?{cwd:n}:{},["workspace"]),"cleared"}async setCwd(e,t){if(t=as(t),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:Lc(o,t,n,void 0,r)}))}async persistSnapshot(e,t){let n={};t.currentModel!==void 0&&(n.currentModel=t.currentModel),t.currentMode!==void 0&&(n.currentMode=t.currentMode),t.currentUsage!==void 0&&(n.currentUsage=t.currentUsage),t.agentCommands!==void 0&&(n.agentCommands=t.agentCommands),t.agentModes!==void 0&&(n.agentModes=t.agentModes),t.agentModels!==void 0&&(n.agentModels=t.agentModels),t.configOptionValues!==void 0&&(n.configOptionValues=t.configOptionValues),t.interactive!==void 0&&(n.interactive=t.interactive),t.cwd!==void 0&&(n.cwd=t.cwd),await this.mutateRecord(e,n)}async setRead(e,t){let n=this.sessions.get(e);if(n)return n.setRead(t),!0;let r=!1;return await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;r=!0;let i=As(o,t);i!==void 0&&await this.store.write({...o,readAt:i})}),this.invalidateListCache(),r}async persistReadState(e,t){await this.enqueueMetaWrite(e,async()=>{let n=await this.store.read(e);n&&await this.store.write({...n,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt})})}async mutateRecord(e,t,n=[],r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o,...t,...r?r(o):{},updatedAt:new Date().toISOString()};for(let a of n)delete i[a];await this.store.write(i)})}static EXTENSION_STATE_CAP_BYTES=64*1024;async getExtensionState(e,t){return(await this.store.read(e))?.extensionState?.[t]??{}}async getExtensionStateKey(e,t,n){return(await this.getExtensionState(e,t))[n]}async setExtensionStateKey(e,t,n,r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o.extensionState??{}},a={...i[t]??{},[n]:r},d=Buffer.byteLength(JSON.stringify(a),"utf8");if(d>s.EXTENSION_STATE_CAP_BYTES)throw new Error(`extension_state: bucket for ${t} would be ${d} bytes; cap is ${s.EXTENSION_STATE_CAP_BYTES}`);i[t]=a;let c={...o,extensionState:i,updatedAt:new Date().toISOString()};await this.store.write(c)})}async deleteExtensionStateKey(e,t,n){await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r?.extensionState?.[t])return;let o={...r.extensionState},i={...o[t]};if(!(n in i))return;delete i[n],Object.keys(i).length===0?delete o[t]:o[t]=i;let a={...r,extensionState:o,updatedAt:new Date().toISOString()};await this.store.write(a)})}enqueueMetaWrite(e,t){return this.enqueueKeyed(this.metaWriteQueues,e,t)}enqueueKeyed(e,t,n){let o=(e.get(t)??Promise.resolve()).catch(()=>{}).then(n),i=o.catch(()=>{});return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)}),o}liveSessionsIn(e,t){let n=[];for(let r of this.sessions.values())r.sessionId!==t&&r.workspace?.path===e&&n.push(r);return n}async closeAll(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(t=>t.close({deleteRecord:!1,by:"daemon-shutdown"}))),this.sessions.clear()}async flushSynopsis(e){await this.synopsisCoordinator.flush(e)}async shutdownSynopsis(){await this.synopsisCoordinator.shutdown()}scheduleSynopsis(e){this.synopsisCoordinator.schedule(e)}scheduleCompaction(e,t){if(t?.targetAgentId){this.mutateRecord(e,{pendingAgentSwap:t.targetAgentId}).catch(r=>{this.logger?.warn(`scheduleCompaction: failed to stamp pendingAgentSwap for ${e}: ${r instanceof Error?r.message:String(r)}`)});let n=t.targetAgentId;(async()=>{try{let r=await this.store.read(e),o=await this.histories.load(e,{maxEntries:1/0});if(wc(o)===0){this.logger?.info(`compaction: zero-turn fast-path swap sessionId=${e} target=${n}`),await this.dispatchSynthesisSwap(e,void 0,o.length,n);return}if(!r?.synopsis||r.summarizedThroughEntry===void 0){this.synopsisCoordinator.scheduleCompaction(e,t);return}if(o.length!==r.summarizedThroughEntry){this.synopsisCoordinator.scheduleCompaction(e,t);return}this.logger?.info(`compaction: fast-path swap sessionId=${e} target=${n} (reusing artifact @${r.summarizedThroughEntry})`),await this.dispatchSynthesisSwap(e,r.synopsis,r.summarizedThroughEntry,n)}catch(r){this.logger?.warn(`scheduleCompaction: fast-path check failed for ${e}: ${r instanceof Error?r.message:String(r)} \u2014 falling back to synthesis`),this.synopsisCoordinator.scheduleCompaction(e,t)}})();return}this.synopsisCoordinator.scheduleCompaction(e,t)}getCompactionInFlight(){let e=this.synopsisCoordinator.size();return e.inflight>0||e.queued>0}async getPendingAgentSwap(e){return(await this.store.read(e).catch(()=>{}))?.pendingAgentSwap}async getCompactionState(e){return(await this.store.read(e).catch(()=>{}))?.compactionState}async persistRollbackBreadcrumb(e,t){await this.mutateRecord(e,{},void 0,n=>{let r=n.rollbackBreadcrumb;return r!==void 0&&t.runId!==void 0&&r.runId===t.runId?(this.logger?.info(`compaction: keeping rollback breadcrumb pinned at ${r.previousUpstreamSessionId} for runId=${t.runId} sessionId=${e} (later swap of the same run)`),{}):{rollbackBreadcrumb:t}})}async getUpstreamGenerations(e){return(await this.store.read(e).catch(()=>{}))?.upstreamGenerations??[]}async getRollbackBreadcrumb(e){return(await this.store.read(e).catch(()=>{}))?.rollbackBreadcrumb}emitSwapPhase(e,t,n){let r=this.get(e);if(r){if(t){if(n.phase==="failed"){r.broadcastPendingAgentSwap(null);return}if(n.phase==="converged")return;r.broadcastPendingAgentSwap(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 Md(t.sessionId).catch(()=>[]);if(n.length===0)continue;let r=Date.now(),o=n.filter(d=>r-d.enqueuedAt<Oc),i=n.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${Oc/1e3}s)`),await Tn(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 Tn(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 Hh(s,e){if(typeof s!="string"||s.length===0)return!1;let t=qn.resolve(s),n=qn.resolve(e);return t===n||t.startsWith(n+qn.sep)}function jh(s){return s!==void 0&&/^\{\s*"session_id"\s*:\s*"[^"]*"\s*,\s*"(?:transcript_path|cwd|permission_mode|hook_event_name)"\s*:/.test(s)}function Fc(s,e){if(s===void 0||s.length===0)return!0;let t=ds(s);if(ds(e.cwd)===t)return!0;let n=e.workspace?.sourceCwd;return n!==void 0&&ds(n)===t}function Uh(s,e){let n=(s.mergedAvailableCommands().length>0?s.agentOnlyAdvertisedCommands().map(w=>w.description!==void 0?{name:w.name,description:w.description}:{name:w.name}):void 0)??e?.agentCommands,r=s.availableModes(),i=(r.length>0?r.map(w=>{let h={id:w.id};return w.name!==void 0&&(h.name=w.name),w.description!==void 0&&(h.description=w.description),h}):void 0)??e?.agentModes,a=s.availableModels(),c=(a.length>0?a.map(w=>{let h={modelId:w.modelId};return w.name!==void 0&&(h.name=w.name),w.description!==void 0&&(h.description=w.description),h}):void 0)??e?.agentModels,u=s.extraConfigOptionValues(),l=Object.keys(u).length>0?u:e?.configOptionValues;return Fo({sessionId:s.sessionId,lineageId:e?.lineageId??$n(),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:Uc(s.persistableUsage)??e?.currentUsage,agentCommands:n,agentModes:i,agentModels:c,configOptionValues:l,parentSessionId:s.parentSessionId??e?.parentSessionId,forkedFromSessionId:s.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId??e?.forkedFromMessageId,side:s.side??e?.side,originatingClient:s.originatingClient??e?.originatingClient,interactive:s.interactive??e?.interactive,priority:s.priority??e?.priority,lastTurnEndedAt:s.lastTurnEndedAt??e?.lastTurnEndedAt,readAt:s.readAt??e?.readAt,forwardedEnv:s.forwardedEnv??e?.forwardedEnv,workspace:s.workspace,attentionFlags:s.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?Lc(e,s.agentId,s.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(s.createdAt).toISOString()})}function Uc(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 Lh(s){return s?{...s}:void 0}function Bh(s){return(s.extendsChain??[s.id]).some(t=>t==="claude-acp"||t.startsWith("claude-acp-"))}var Wh=[{type:"system",subtype:"background_tasks_changed"}];function Xo(s,e={}){if(!Bh(s))return;let t={extraArgs:{"thinking-display":"summarized"}};return e.model&&(t.model=e.model),{claudeCode:{options:t,emitRawSDKMessages:Wh}}}function Qs(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=qh(s,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function Zo(s){return Qs(s,{nestedKey:"models",configId:"model",fromObject:e=>Ie(e.currentModelId)??Ie(e.currentModel)??Ie(e.modelId)??Ie(e.model),fromConfig:e=>Ie(e.currentValue)})}function ht(s,e){if(!s||typeof s!="object")return s;let t=s;if(t.code!==x.AuthRequired)return s;let n=c=>!!c&&typeof c=="object"&&!Array.isArray(c),r=n(t.data)?t.data:{},o=n(r._meta)?r._meta:{},i=n(o["hydra-acp"])?o["hydra-acp"]:{},a=typeof t.message=="string"?t.message:"authentication required",d=new Error(a);return d.code=x.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function Nc(s){return/^[A-Za-z0-9_\-./=:@]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function Dc(s,e,t,n){if(s&&typeof s=="object"&&s.code===x.AuthRequired)return s;let r=s instanceof Error?s.message:String(s),o=r.includes("stderr:"),i=o?"":e.stderrTailText(),a=n?`to reproduce: (cd ${Nc(n.cwd)} && ${[n.command,...n.args].map(Nc).join(" ")})`:"";if(!i&&!a)return s;let d=[o?r:`agent ${t} failed to start: ${r}`];i&&d.push(`stderr: ${i}`),a&&d.push(a);let c=new Error(d.join(`
193
- `));if(s&&typeof s=="object"){let u=s;typeof u.code=="number"&&(c.code=u.code),u.data!==void 0&&(c.data=u.data)}return c}function Ln(s){return s._meta?.steering?.supported===!0}function Bn(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 Ie(s){if(typeof s!="string")return;let e=s.trim();return e.length>0?e:void 0}function qh(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 nn(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.configOptions)}function sn(s){let e=s.configOptions;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object"||Array.isArray(n))continue;let r=n,o=Ie(r.id);if(!o||o==="model"||o==="mode"||o==="agent")continue;let i=xo(r.options);if(i.length===0)continue;let a=Ie(r.description);t.push({id:o,name:Ie(r.name)??o,...a?{description:a}:{},category:Ie(r.category)??"other",type:"select",currentValue:Ie(r.currentValue)??i[0].value,options:i})}return t}function mt(s){return s.length>0?s:void 0}function ei(s){return Qs(s,{nestedKey:"models",configId:"model",fromObject:e=>{let t=Pn(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=Pn(e.options);return t.length>0?t:void 0}})??[]}function ti(s){return Qs(s,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=Ps(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=Ps(e.options);return t.length>0?t:void 0}})??[]}function ni(s){return Qs(s,{nestedKey:"modes",configId:"mode",fromObject:e=>Ie(e.currentModeId)??Ie(e.currentMode)??Ie(e.modeId)??Ie(e.mode),fromConfig:e=>Ie(e.currentValue)})}function zh(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 Hc(s){try{let e=await Tt.readFile(E.tuiHistoryFile(s),"utf8"),t=[];for(let n of e.split(`
194
- `))if(n.length!==0)try{let r=JSON.parse(n);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function Lc(s,e,t,n=new Date().toISOString(),r={}){let{retiredCost:o,retiredUsed:i,startedUsed:a,lifetimeCost:d,reason:c,runId:u}=r,l=f=>d!==void 0&&f.lifetimeCostAtStart!==void 0?Math.max(0,d-f.lifetimeCostAtStart):o,w=s.upstreamGenerations&&s.upstreamGenerations.length>0?[...s.upstreamGenerations]:s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId}]:[],h=w[w.length-1];if(h&&h.upstreamSessionId===t){if(w.length>=2){let f=w[w.length-2];if(f){let k=l(f);w[w.length-2]={...f,...k!==void 0&&f.cost===void 0?{cost:k}:{},...i!==void 0&&f.usedAtEnd===void 0?{usedAtEnd:i}:{}}}}return(c!==void 0&&h.reason===void 0||a!==void 0&&h.usedAtStart===void 0||d!==void 0&&h.lifetimeCostAtStart===void 0)&&(w[w.length-1]={...h,...c!==void 0&&h.reason===void 0?{reason:c,...u!==void 0?{runId:u}:{}}:{},...a!==void 0&&h.usedAtStart===void 0?{usedAtStart:a}:{},...d!==void 0&&h.lifetimeCostAtStart===void 0?{lifetimeCostAtStart:d}:{}}),w}return h&&h.endedAt===void 0&&(w[w.length-1]={...h,endedAt:n,...(()=>{let f=l(h);return f!==void 0?{cost:f}:{}})(),...i!==void 0?{usedAtEnd:i}:{}}),w.push({upstreamSessionId:t,agentId:e,startedAt:n,...c!==void 0?{reason:c}:{},...u!==void 0?{runId:u}:{},...a!==void 0?{usedAtStart:a}:{},...d!==void 0?{lifetimeCostAtStart:d}:{}}),w}async function Wn(s){try{let e=await Tt.stat(E.historyFile(s));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function rn(s,e){return s.interactive!==void 0?s.interactive:s.originatingClient?.name===qs?!1:e?!0:void 0}import{spawn as Vh}from"child_process";import*as Zs from"fs";import*as rt from"fs/promises";import*as er from"path";import Gh from"pino-roll";var Ys=class{windowMs;maxFailures;now;recentExits=[];tripped_;constructor(e={}){this.windowMs=e.windowMs??3e5,this.maxFailures=e.maxFailuresInWindow??10,this.now=e.now??Date.now}recordExit(e,t,n){if(e===78){let i=`exited with code 78 (unrecoverable); fix and run \`${n}s start ${t}\``;return this.tripped_=i,{tripped:i}}let r=this.now();this.recentExits.push(r);let o=r-this.windowMs;for(;this.recentExits.length>0&&this.recentExits[0]<o;)this.recentExits.shift();if(this.recentExits.length>this.maxFailures){let i=Math.round(this.windowMs/6e4),a=`${this.recentExits.length} exits in ${i}m (crash loop); fix and run \`${n}s start ${t}\``;return this.tripped_=a,{tripped:a}}return"restart"}reset(){this.recentExits=[],this.tripped_=void 0}get tripped(){return this.tripped_}};import*as Bc from"fs/promises";import*as si from"path";var Xs=process.platform!=="win32";import{spawnSync as Jh}from"child_process";function Wc(s){let e=Jh("taskkill",["/pid",String(s),"/T","/F"],{stdio:"ignore",windowsHide:!0});if(e.error)throw e.error}function zn(s,e,t={}){let n=t.platform??process.platform,r=s.pid;if(n==="win32"&&r!==void 0)try{(t.killTree??Wc)(r);return}catch{}s.kill(e)}function ri(s,e,t={}){if((t.platform??process.platform)==="win32")try{(t.killTree??Wc)(s);return}catch{}process.kill(s,e)}var Kh=1e3,Qh=6e4,oi=3e3,on=class{entries=new Map;stopping=!1;context;tokenRegistry;breakerOptions;processTree;restartBaseMs;restartCapMs;adapter;constructor(e,t,n,r={}){this.adapter=t,this.context=n,this.tokenRegistry=r.tokenRegistry,this.breakerOptions=r.breakerOptions,this.processTree=r.processTree,this.restartBaseMs=r.restartBaseMs??Kh,this.restartCapMs=r.restartCapMs??Qh;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 rt.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{zn(n,"SIGTERM",this.processTree)}catch{}e.push(new Promise(r=>{if(n.exitCode!==null||n.signalCode!==null){r();return}let o=setTimeout(()=>{try{zn(n,"SIGKILL",this.processTree)}catch{}r()},oi);n.on("exit",()=>{clearTimeout(o),r()})}))}}await Promise.allSettled(e);for(let t of this.entries.values()){try{t.logStream?.end()}catch{}t.child=void 0,t.logStream=void 0,t.pid=void 0}}list(){return[...this.entries.values()].map(e=>this.infoFor(e))}get(e){let t=this.entries.get(e);return t?this.infoFor(t):void 0}has(e){return this.entries.has(e)}async startByName(e){let t=this.entries.get(e);if(!t)throw Jn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw Jn(new Error(`${this.adapter.kind} ${e} already running`),"CONFLICT");return t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0),t.manuallyStopped=!1,t.restartCount=0,t.breaker.reset(),t.failureReason=void 0,await this.spawn(t,0),this.infoFor(t)}async stopByName(e){let t=this.entries.get(e);if(!t)throw Jn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;return n?(await this.terminate(t,n),this.infoFor(t)):this.infoFor(t)}async restartByName(e){return await this.stopByName(e),this.startByName(e)}register(e){if(this.entries.has(e.name))throw Jn(new Error(`${this.adapter.kind} ${e.name} already exists`),"CONFLICT");if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before register`);let t=this.makeEntry(e);return this.entries.set(e.name,t),e.enabled&&this.spawn(t,0).catch(n=>{t.failureReason=`spawn: ${n.message}`}),this.infoFor(t)}async unregister(e){let t=this.entries.get(e);if(!t)throw Jn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;n&&await this.terminate(t,n);try{t.logStream?.end()}catch{}this.entries.delete(e)}async terminate(e,t){if(t.exitCode!==null||t.signalCode!==null)return;let n=new Promise(o=>{e.exitWaiters.push(o)});try{zn(t,"SIGTERM",this.processTree)}catch{}let r=setTimeout(()=>{try{zn(t,"SIGKILL",this.processTree)}catch{}},oi);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 Ys(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await rt.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 rt.readFile(n,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&ii(r)){try{ri(r,"SIGTERM",this.processTree)}catch{}let o=Date.now()+oi;for(;Date.now()<o&&ii(r);)await new Promise(i=>setTimeout(i,50));if(ii(r))try{ri(r,"SIGKILL",this.processTree)}catch{}}await rt.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=er.dirname(this.adapter.paths.logFile(r.name)),a;try{await rt.mkdir(i,{recursive:!0}),a=await Gh({file:er.join(i,`${r.name}.log`),size:"5m",mkdir:!0,symlink:Xs,limit:{count:5}}),a.on("error",p=>{e.failureReason=`log stream: ${p.message}`})}catch(p){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${p.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})
195
- `);let d=this.tokenRegistry?.mint(r.name,this.adapter.tokenRole)??n.serviceToken;e.processToken=d,e.version=void 0;let c={...us(),HYDRA_ACP_DAEMON_URL:n.daemonUrl,HYDRA_ACP_DAEMON_HOST:n.daemonHost,HYDRA_ACP_DAEMON_PORT:String(n.daemonPort),HYDRA_ACP_TOKEN:d,HYDRA_ACP_WS_URL:n.daemonWsUrl,HYDRA_ACP_HOME:n.hydraHome,[this.adapter.nameEnvVar]:r.name,...r.env},[u,...l]=o;if(u===void 0){a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} has empty command
196
- `),a.end();return}let w=ie(u),h=[...l,...r.args].map(ie),f;try{let p=Dt(w,h);f=Vh(p.command,p.args,{env:c,stdio:["ignore","pipe","pipe"],detached:!1,shell:p.shell,windowsHide:!0})}catch(p){a.write(`[hydra-acp] failed to spawn ${r.name}: ${p.message}
197
- `),a.end(),this.scheduleRestart(e,t);return}let k=p=>{try{a.write(typeof p=="string"?p:p.toString())}catch{}};if(f.stdout?.on("data",k),f.stderr?.on("data",k),typeof f.pid=="number")try{Zs.writeFileSync(this.adapter.paths.pidFile(r.name),`${f.pid}
198
- `,{encoding:"utf8",mode:384})}catch(p){a.write(`[hydra-acp] failed to write pid file for ${r.name}: ${p.message}
199
- `)}e.child=f,e.logStream=a,e.pid=typeof f.pid=="number"?f.pid:void 0,e.startedAt=Date.now(),e.lastExitCode=void 0,f.on("error",p=>{a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} error: ${p.message}
200
- `)}),f.on("exit",(p,g)=>{try{Zs.unlinkSync(this.adapter.paths.pidFile(r.name))}catch{}a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} exited code=${p??"null"} signal=${g??"null"}
201
- `),e.child=void 0,e.pid=void 0,e.lastExitCode=typeof p=="number"?p:void 0,e.processToken&&(this.tokenRegistry?.revoke(r.name),e.processToken=void 0);let y=e.exitWaiters.splice(0);for(let v of y)v();if(this.stopping||e.manuallyStopped){try{a.end()}catch{}e.logStream=void 0;return}e.restartCount+=1;let m=e.breaker.recordExit(p,r.name,this.adapter.kind);if(typeof m=="object"){e.failureReason=m.tripped,a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} circuit breaker tripped: ${m.tripped}
202
- `);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 ii(s){try{return process.kill(s,0),!0}catch{return!1}}function Jn(s,e){return s.code=e,s}Q();var Yh={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:E.extensionsDir,logFile:E.extensionLogFile,pidFile:E.extensionPidFile}},tr=class extends on{constructor(e,t,n={}){super(e,Yh,t,n)}};Q();var Xh={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:E.transformersDir,logFile:E.transformerLogFile,pidFile:E.transformerPidFile}},nr=class extends on{connected=new Map;constructor(e,t,n={}){super(e,Xh,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 sr=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{}}};Q();Q();import*as Vn from"fs/promises";async function qc(s){let e=E.pidFile(),t=`${e}.${process.pid}.tmp`;await Vn.writeFile(t,JSON.stringify(s)+`
203
- `,{encoding:"utf8",mode:384}),await Vn.rename(t,e)}Q();import*as Kn from"fs/promises";import*as rr from"path";var Gn=s=>{process.stderr.write(s+`
204
- `)};function ai(s){Gn=s??(e=>process.stderr.write(e+`
205
- `))}async function zc(s,e){let t=Ue();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=rr.join(E.agentsDir(),t),a;try{a=await Kn.readdir(i,{withFileTypes:!0})}catch(d){let c=d;if(c.code==="ENOENT")return;Gn(`hydra-acp: prune: failed to read ${i}: ${c.message}`);return}for(let d of a){if(!d.isDirectory())continue;let c=d.name,u=r.get(c);if(u===void 0)continue;let l=o.get(c)??new Set,w=rr.join(i,c),h;try{h=await Kn.readdir(w,{withFileTypes:!0})}catch(f){Gn(`hydra-acp: prune: failed to read ${w}: ${f.message}`);continue}for(let f of h){if(!f.isDirectory())continue;let k=f.name;if(k===u||l.has(k)||k.includes(".partial-"))continue;let p=rr.join(w,k);try{await Kn.rm(p,{recursive:!0,force:!0}),Gn(`hydra-acp: pruned stale ${c} ${k} (${p})`)}catch(g){Gn(`hydra-acp: prune: failed to remove ${p}: ${g.message}`)}}}}function Jc(s){let e,t=!1,n=0,r=(a,d)=>{s.logger&&s.logger[a](`agent-sync: ${d}`)},o=async()=>{let a=[];try{let u=await s.registry.load();for(let l of u.agents)await to(l)==="yes"&&a.push(l.id)}catch(u){return r("warn",`registry load failed: ${u.message}`),s.intervalMs}if(a.length===0)return s.intervalMs;let d=n%a.length;n=(n+1)%a.length;let c=a[d];try{let{synced:u,skipped:l}=await s.manager.syncFromAgent(c);r("info",`${c}: synced ${u.length}, skipped ${l}`)}catch(u){r("warn",`${c}: ${u.message}`)}return Math.max(1,Math.floor(s.intervalMs/a.length))},i=a=>{t||(e=setTimeout(()=>{o().then(d=>{i(d)}).catch(d=>{r("warn",`tick crashed: ${d.message}`),i(s.intervalMs)})},a),e.unref())};return i(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}async function di(s){let e=s.maxDeletions??200,t=(h,f)=>{s.logger&&s.logger[h](`session-gc: ${f}`)},n=Date.now(),r=s.maxAgeMs>0?n-s.maxAgeMs:Number.POSITIVE_INFINITY,o=await s.manager.list({includeNonInteractive:!0}).catch(h=>(t("warn",`manager.list failed: ${h.message}`),[])),i=[];for(let h of o){if(h.status!=="cold")continue;if((s.selection??"explicit")==="explicit"){if(h.interactive!==!1)continue}else if(h.interactive===!0)continue;let k=Date.parse(h.updatedAt);Number.isFinite(k)&&(s.maxAgeMs>0&&k>r||i.push({sessionId:h.sessionId,lastUsedMs:k}))}if(i.length===0)return s.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((h,f)=>h.lastUsedMs-f.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,c=0,u=0;for(let{sessionId:h}of a)try{await s.manager.deleteRecord(h,"expired")&&(c+=1)}catch(f){u+=1,t("warn",`delete ${h} failed: ${f.message}`)}let l=i.length-a.length;if(s.verbose||c>0||u>0){let h=(s.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${c} ${h} session(s) older than ${Zh(s.maxAgeMs)}`+(u>0?`; ${u} failed`:"")+(l>0?`; ${l} deferred to next sweep`:""))}let w={considered:i.length,deleted:c,failed:u,deferred:l};return d!==void 0&&(w.oldestLastUsedMs=d),w}function Vc(s){let e,t=!1,n=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!n){n=!0;try{await di({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 Zh(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 ey}from"crypto";function Qn(s){if(Array.isArray(s))return s.map(Qn);if(s!==null&&typeof s=="object"){let e={};for(let t of Object.keys(s).sort())e[t]=Qn(s[t]);return e}return s}function Gc(s){let e={};for(let[n,r]of Object.entries(s)){let o=$r(n);if(o.nested){let i={};for(let[a,d]of Object.entries(r??{}))Or(a).reload==="restart"&&(i[a]=d);Object.keys(i).length>0&&(e[n]=i);continue}o.reload==="restart"&&(e[n]=r)}let t=JSON.stringify(Qn(e));return ey("sha256").update(t).digest("hex").slice(0,16)}function Kc(s,e){let t=[],n=(r,o)=>JSON.stringify(Qn(r))!==JSON.stringify(Qn(o));for(let r of Object.keys(e)){let o=$r(r),i=e[r],a=s[r];if(o.nested){for(let d of Object.keys(i??{})){if(Or(d).reload!=="warn")continue;let c=i[d],u=(a??{})[d];n(u,c)&&t.push(`${r}.${d}`)}continue}o.reload==="warn"&&n(a,i)&&t.push(r)}return t}import*as Yc from"fs/promises";Q();var ty=3e3;async function Qc(){try{return(await Yc.stat(E.config())).mtimeMs}catch{return}}function Xc(s){let e=s.intervalMs??ty,t=!1,n,r,o=Qc().then(d=>{r=d}),i=async()=>{await o;let d=await Qc();if(d===r)return;r=d;let c;try{c=await kn()}catch(l){s.logger?.warn(`config-reload: config.json changed but did not parse (${l.message}); keeping the loaded config`);return}try{s.apply(c)}catch(l){s.logger?.warn(`config-reload: applying live config failed: ${l.message}`)}let u=Kc(s.bootConfig,c);s.onDrift?.(u),s.logger?.info(u.length>0?`config-reload: applied live config; restart-only keys differing from boot: ${u.join(", ")}`:"config-reload: applied live config")},a=()=>{t||(n=setTimeout(()=>{i().finally(a)},e),n.unref?.())};return a(),()=>{t=!0,n&&clearTimeout(n)}}Q();He();import*as tu from"path";import{createHash as ny,randomBytes as sy,timingSafeEqual as ry}from"crypto";var nu="hydra_session_",oy=3600*24*30,Zc=12,iy=32,ay=50;function dy(){return tu.join(E.home(),"session-tokens.json")}function eu(s){return ny("sha256").update(s).digest("hex")}function su(s){return sy(s).toString("hex")}function cy(){return su(Zc).slice(0,Zc*2)}function uy(){return`${nu}${su(iy)}`}var or=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=dy(),n=await ce(t);n&&Array.isArray(n.records)&&(e=n.records.filter(ly));let r=new s(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=uy(),n=eu(t),r=cy(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:oy,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(nu))return;let t=eu(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||!ry(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(()=>{})},ay))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>me(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 ly(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 ru="Bearer ",ir=class{constructor(e){this.token=e}token;async validate(e){return py(e,this.token)?"service":void 0}rotate(e){this.token=e}},ar=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},dr=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 ou(s){return async function(t,n){let r=t.headers.authorization;if(!r||!r.startsWith(ru)){n.code(401).send({error:"Missing bearer token"});return}let o=r.slice(ru.length).trim(),i=await s.validator.validate(o);if(!i){n.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function iu(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 cr=class{tokens=new Map;mint(e,t){let n=Mr();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}`}},fy=new Set(["GET /v1/sessions","GET /v1/sessions/:id","GET /v1/config","GET /v1/system"]);function au(s,e){return e?fy.has(`${s} ${e}`):!1}function py(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 ur=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 dn from"fs";import*as Tu from"os";import*as Xn from"path";import*as pi from"readline";import*as Eu from"zlib";Q();function ci(s){return Math.floor(s/4)}function du(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+=Et(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=gy(i),c=t.get(a)??0;d>c&&t.set(a,d);break}default:break}}for(let n of t.values())e+=n;return e}function gy(s){let e=0;return typeof s.title=="string"&&(e+=s.title.length),e+=lr(s.rawInput),e+=Et(s.content),e+=lr(s.rawOutput),e}function lr(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+=lr(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+=lr(n);return t}return 0}function Et(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+=Et(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?Et(e.text):e.type==="diff"?Et(e.oldText)+Et(e.newText):e.content!==void 0?Et(e.content):0}function cu(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=ci(s.unsummarizedChars),o=s.currentModel!==void 0?s.config.modelContextWindows[s.currentModel]??s.config.absoluteFallback:s.config.absoluteFallback;e=r/o,t=!1}if(t&&e>=s.config.hardCeilingFraction)return!0;let n=s.nowMs-s.lastActivityMs;return e>=s.config.contextFraction&&n>=s.config.idleBeforePromptMs}function uu(s){let e=new Map,t=new Map,n=new Map;for(let o of s){let a=o.params?.update;if(!a||typeof a!="object")continue;let d=a.sessionUpdate;if(d!=="tool_call"&&d!=="tool_call_update")continue;let c=typeof a.toolCallId=="string"&&a.toolCallId.length>0?a.toolCallId:void 0,u=hy(a);if(u.length===0)continue;let l=u;if(c!==void 0){let w=e.get(c)??[],h=[];for(let f of u){let k=w.find(p=>p.path===f.path&&p.oldText===f.oldText&&p.newText===f.newText);if(k===void 0)h.push(f);else if(k.scope===void 0&&f.scope!==void 0){k.scope=f.scope;let p=t.get(k);p&&(p.scope=f.scope)}}if(h.length===0)continue;e.set(c,[...w,...h]),l=h}for(let w of l)t.set(w,my(n,w))}let r=[];for(let[o,i]of n)r.push({path:o,hunks:i.hunks,created:i.created});return r}function lu(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,...r.scope!==void 0&&r.scope===t.scope?{scope:r.scope}:{}})}return e}function my(s,e){let t={oldText:e.oldText,newText:e.newText,...e.scope!==void 0?{scope:e.scope}:{}},n=s.get(e.path);return n===void 0?(s.set(e.path,{hunks:[t],created:e.oldText.length===0}),t):(n.hunks.push(t),t)}function hy(s){let e=[];for(let t of Is(s))t.path!==void 0&&e.push({path:t.path,...Xa(t),...t.scope!==void 0?{scope:t.scope}:{}});return e}function pu(s,e={}){let t=wy(s),{events:n,window:r}=yy(t,e),o=ky(n),i=[];vy(i,s),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),by(i,n,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
198
+ A sync was attempted first but was refused: ${A instanceof Error?A.message:String(A)}`}if(!u){let A=await i.currentLineName(n)??"the source";throw new Error(`cannot fast-forward ${A} in ${F(n)} to ${r}. The source has moved on since this workspace was created. The source is untouched.${I}
199
+ `+(I.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 y=i!==void 0&&i.capabilities().supports.nestedTrees?await i.captureNested(e.path,await i.listNested(e.path)).catch(()=>[]):[],h,f=await i.status(a).catch(()=>{});if(f!==void 0&&f.changedPaths.length>0&&(h=await i.captureWorkingState(e.path,`hydra: uncommitted work in ${e.label}`).catch(()=>{}),h===void 0))throw new Error(`could not capture the uncommitted work in ${F(e.path)}; nothing was changed`);if(!d.clean&&!(await i.resetTo(n,c)).ok)throw new Error(`could not clear ${F(n)} for the merge; your work is preserved at ${d.retainedRef}. Nothing was merged.`);let k=await i.integrate({into:n,from:r,fastForwardOnly:!0});if(!k.ok)throw new Error(`merge failed: ${k.reason??"unknown error"}`);let g=!0;if(h!==void 0){let b=await i.captureDelta(n,k.snapshot,h);b!==void 0&&(g=(await i.applyDelta(n,b)).ok)}let p=await Et({source:n,capture:d,provider:i});p&&await Bn({source:n,ws:a,capture:d,provider:i});let w={applied:[],failed:[]},m=i!==void 0&&i.capabilities().supports.nestedTrees?await i.integrateNested(n,e.path,y).catch(()=>w):w,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 S=[];g||S.push(` WARNING: the workspace's uncommitted changes could not be replayed; they remain reachable from ${r}.`),p||S.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 ${F(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 b of m.failed)S.push(` WARNING: nested tree ${b.path} was NOT reconciled: ${b.reason}. ${F(n)} now records a different state for it, so it will report it as modified until you resolve that.`);return{merged:`Merged ${r} into ${F(n)}${l.join("")}`,warnings:S}}async applyWorkspaceToSource(e,t){let n=e.sourceCwd;if(!await this.dirExists(n))throw new Error(`source tree ${F(n)} no longer exists`);let r=oe(e.provider);if(r===void 0)throw new Error(`no provider "${e.provider}" available to apply this workspace`);if(!r.capabilities().supports.captureWorkingState)throw new Error(`provider "${e.provider}" cannot snapshot a working tree, so there is no change set to apply. Use \`/hydra workspace stop\` to land this workspace instead.`);let o=this.asWorkspace(e);if((await r.status({...o,path:n}).catch(()=>{}))?.hasStagedWork===!0)throw new Error(`${F(n)} already has changes staged for its next commit, and \`apply\` delivers into that same index: the two sets would be indistinguishable, and unstaging one would unstage both. Commit or unstage them first, or use \`/hydra workspace merge\`, which lands the work as commits and does not touch the index.`);let a=await r.currentState(n);if(a===void 0)throw new Error(`could not read the state of ${F(n)}`);let d=e.line,c=d!==void 0&&await r.contains(n,{state:a,within:d}).catch(()=>!1),u=c?a:e.snapshot??"";if(u.length===0)throw new Error(`workspace ${e.label} has no recorded base to measure its changes against, so there is no way to tell its work apart from what the source already had`);let l=await si({source:n,ws:o,startSnapshotRef:this.startRefFor(e.label),baselineRef:this.baselineRefFor(e.label),retainRef:ni(t),provider:r}),y=r.capabilities().supports.nestedTrees?(await r.listNested(e.path).catch(()=>[])).filter(m=>m.changedPaths.length>0||m.recorded!==void 0&&m.recorded!==m.actual):[],h=await r.captureWorkingState(e.path,`hydra: apply from ${e.label}`).catch(()=>{});if(h===void 0)throw new Error(`could not snapshot the work in ${F(e.path)}; nothing was changed`);let f=await r.captureDelta(n,u,h);if(f===void 0)throw new Error(`could not work out what ${e.label} changed; ${F(n)} was not touched`);if(f.trim().length===0)return await Bn({source:n,ws:o,capture:l,provider:r}),{applied:`Nothing to apply: ${e.label} holds no changes ${F(n)} does not already have.`,warnings:[]};if(!l.clean&&!(await r.resetTo(n,a)).ok)throw new Error(`could not clear ${F(n)} to apply onto; your work is preserved at ${l.retainedRef}. Nothing was applied.`);let k=await r.applyDelta(n,f,{stage:!0,tolerant:!c});if(!k.ok){await r.resetTo(n,a).catch(()=>{});let m=await Et({source:n,capture:l,provider:r});throw m&&await Bn({source:n,ws:o,capture:l,provider:r}),new Error(`could not apply ${e.label} into ${F(n)}: ${k.reason??"the change set did not apply"}.`+(c?"":" The source has moved on since this workspace was created; `/hydra workspace sync` brings those commits in here, which is what lets the change set apply against them.")+(m?` ${F(n)} is as you left it.`:` Your uncommitted work there is preserved at ${l.retainedRef}.`))}let g=await Et({source:n,capture:l,provider:r});g&&await Bn({source:n,ws:o,capture:l,provider:r});let p=await r.captureWorkingState(n,`hydra: source state after applying ${e.label}`).catch(()=>{});p!==void 0&&await r.retainSnapshot({...o,path:n},this.baselineRefFor(e.label),p).catch(()=>{});let w=[];k.alreadyPresent===!0&&w.push(` Nothing was staged: ${F(n)} already had every one of those changes.`),g||w.push(` WARNING: your own edits to ${F(n)} overlap the workspace's changes and could not be replayed on top. They are preserved at ${l.retainedRef}; recover with: git -C ${n} diff ${l.base} ${l.retainedRef}`);for(let m of y)w.push(` WARNING: nested tree ${m.relPath} was NOT included: a change set can only move the pointer to it, not what is inside. Land it with \`/hydra workspace stop\`, or copy that work across by hand.`);return{applied:`Applied ${e.label} into ${F(n)} as staged changes; still working in ${F(e.path)}.
200
+ Nothing was committed: review it with \`git -C ${n} diff --cached\` and commit it however you like. The workspace and its history are untouched.`,warnings:w}}async leaveWorkspace(e,t,n){let r=n.exit!=="detached",o=oe(t.provider),i={path:t.path,sourceCwd:t.sourceCwd,label:t.label,provider:t.provider,...t.snapshot!==void 0?{snapshot:t.snapshot}:{},...t.vcs!==void 0?{vcs:t.vcs}:{}},a=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:t.sourceCwd,workspace:void 0,historyLength:a.length,note:`Returned to the source tree at ${t.sourceCwd}`+(n.exit==="landed"?" after merging the workspace.":n.exit==="discarded"?" after discarding the workspace and its work.":" without merging."),...await this.recordSynopsisFor(e.sessionId),left:{path:t.path,removed:r}}),await this.mutateRecord(e.sessionId,{cwd:e.cwd},["workspace"]),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"left",cwd:e.cwd,sourceCwd:t.sourceCwd,integrated:n.exit==="landed"}),o!==void 0&&await this.enqueueKeyed(this.workspaceQueues,t.path,async()=>{let d=this.liveSessionsIn(t.path,e.sessionId);if(d.length>0){this.logger?.info?.(`session workspace: ${e.sessionId} left ${t.path}; ${d.length} live session(s) remain, so it stays`);return}await this.reclaimAfterLastLeaver(o,i,t,e.sessionId,n)})}async reclaimAfterLastLeaver(e,t,n,r,o){await e.unlock(t).catch(()=>{});for(let i of[this.startRefFor(n.label),this.baselineRefFor(n.label)])await e.dropSnapshotRef(t,i).catch(()=>{});o.exit!=="detached"&&(o.exit==="landed"&&await e.dropSnapshotRef(t,this.snapshotRefFor(n.label)).catch(()=>{}),await e.removeWorkspace(t,{force:!0,discardLine:!0}).catch(()=>{}))}async joinDivergence(e,t,n){let[r,o]=await Promise.all([e.captureWorkingState(t,"hydra: source state at join").catch(()=>{}),e.captureWorkingState(n.path,"hydra: workspace state at join").catch(()=>{})]);if(r===void 0||o===void 0)return`could not compare ${F(t)} with ${F(n.path)}, so refusing to join a workspace that may not match your tree`;let i=await Promise.all([r,o].map(a=>e.contentId(t,a).catch(()=>{})));if(!(i[0]!==void 0&&i[0]===i[1]))return`${F(t)} and ${F(n.path)} have diverged, and joining does not carry work across \u2014 whichever side you are not in would be left behind. Land or stash one of them first: \`git -C ${t} stash\` if the difference is yours, or \`/hydra workspace merge\` from the session already in there if it is theirs.`}liveSessionsWithLabel(e,t){let n=[];for(let r of this.sessions.values()){let o=r.workspace;o===void 0||o.sourceCwd!==e||(o.label===t||o.requestedLabel===t)&&n.push(r)}return n}async joinWorkspace(e,t,n,r){let o=oe(n.provider);if(o===void 0)throw new Error(`no provider "${n.provider}" to join that workspace with`);if(o.capabilities().supports.captureWorkingState){let i=await this.joinDivergence(o,r,n);if(i!==void 0)throw new Error(i)}return await this.enqueueKeyed(this.workspaceQueues,n.path,async()=>{if(this.sessions.get(t.sessionId)?.workspace?.path!==n.path)throw new Error(`${F(n.path)} was released while joining it; run the command again`);e.broadcastWorkspacePhase({phase:"swapping"});let i=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:n.path,workspace:{path:n.path,sourceCwd:n.sourceCwd,label:n.label,...n.requestedLabel!==void 0?{requestedLabel:n.requestedLabel}:{},provider:n.provider,...n.snapshot!==void 0?{snapshot:n.snapshot}:{},...n.line!==void 0?{line:n.line}:{},...n.vcs!==void 0?{vcs:{...n.vcs}}:{}},historyLength:i.length,note:`Continuing in an isolated workspace at ${n.path}, derived from ${r}, shared with another session.`,...await this.recordSynopsisFor(e.sessionId)}),await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache();let a=n.line;e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:n.sourceCwd,label:n.label,...a!==void 0?{branch:a}:{}});let d=this.liveSessionsIn(n.path,e.sessionId).map(u=>nt(u.sessionId)),c=[`Joined workspace ${F(n.path)}`,` source: ${F(n.sourceCwd)}`];return a!==void 0&&c.push(` branch: ${a}`),c.push(` shared with: ${d.join(", ")}`),c.push(" your edits will interleave with that session's"),c.push("Use `/hydra workspace stop` to leave; the work lands when the last session leaves."),c.join(`
201
+ `)})}async startWorkspace(e,t,n){if(e.workspace!==void 0)throw new Error(`already isolated in ${F(e.workspace.path)}. Use \`/hydra workspace stop\` to merge and return first, or \`detach\` to leave it behind.`);let r=e.cwd,o=oe();if(o===void 0)throw new Error("no workspace provider available");let i=await e.quiesceBlocker();if(i!==void 0)throw new Error(i);let a=o.capabilities();if(t!==void 0){let b=this.liveSessionsWithLabel(r,t)[0];if(b!==void 0&&b.workspace!==void 0)return await this.joinWorkspace(e,b,b.workspace,r)}let d,c=[],u=!1,l=!1,y=[],h=[],f=n?.clean===!0;if(a.supports.captureWorkingState){let b=await o.status({path:r,sourceCwd:r,label:"source",provider:o.kind}).catch(()=>{});l=b!==void 0;let I=a.supports.nestedTrees&&b!==void 0&&b.changedPaths.length>0?await o.listNested(r).catch(()=>[]):[];if(b!==void 0&&b.changedPaths.length>0&&f)y=Yo(b.changedPaths,I);else if(b!==void 0&&b.changedPaths.length>0&&(c=Yo(b.changedPaths,I),h=await o.captureNested(r,I).catch(()=>[]),u=b.hasStagedWork===!0,d=await o.captureWorkingState(r,"hydra: work carried into workspace").catch(()=>{}),d===void 0))throw new Error("could not snapshot your uncommitted work, so refusing to move it. Commit or stash first.")}e.broadcastWorkspacePhase({phase:"provisioning"});let k=await o.createWorkspace({sourceCwd:r,label:t??`s-${e.sessionId.slice(-8)}`});if(!k.ok)throw e.broadcastWorkspacePhase({phase:"failed",error:k.reason}),new Error(k.reason);let g=k.workspace,p=this.startRefFor(g.label),w,m=!1,v=[];try{a.locking&&await o.lock(g,`session ${e.sessionId}`).catch(()=>{});let b=d??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,p,b),e.broadcastWorkspacePhase({phase:"setup"}),m=d!==void 0?await this.copyCarriedWork(g,d,r):!0;let I=await this.materializeNestedTrees(g);if(h.length>0){let T=await o.reproduceNested(g.path,r,h).catch(R=>({applied:[],failed:h.map(P=>({path:P.relPath,reason:R instanceof Error?R.message:String(R)}))}));T.failed.length>0&&(m=!1,v=T.failed)}w=await this.applyWorkspaceSetup(g,e.sessionId),I!==void 0&&(w=w===void 0?I:`${I}; ${w}`),e.broadcastWorkspacePhase({phase:"swapping"});let A=await this.histories.load(e.sessionId).catch(()=>[]);await e.swapIntoWorkspace({cwd:g.path,workspace:{path:g.path,sourceCwd:g.sourceCwd,label:g.label,...t!==void 0&&t!==g.label?{requestedLabel:t}:{},provider:g.provider,...g.snapshot!==void 0?{snapshot:g.snapshot}:{},...g.line!==void 0?{line:g.line}:{},...g.vcs!==void 0?{vcs:{...g.vcs}}:{},...d===void 0?{clean:!0}:{}},historyLength:A.length,note:`Continuing in an isolated workspace at ${g.path}, derived from ${r}.`,...await this.recordSynopsisFor(e.sessionId)})}catch(b){let I=await this.unwindStartWorkspace({provider:o,ws:g,startRef:p,carried:d}),A=b instanceof Error?b.message:String(b);throw e.broadcastWorkspacePhase({phase:"failed",error:A}),new Error(I===void 0?A:`${A}
202
+ ${I}`)}await this.mutateRecord(e.sessionId,{cwd:e.cwd,workspace:e.workspace}),this.invalidateListCache(),e.broadcastWorkspacePhase({phase:"entered",cwd:e.cwd,sourceCwd:g.sourceCwd,label:g.label,...g.line!==void 0?{branch:g.line}:{}});let S=[`Moved into workspace ${F(g.path)}`,` source: ${F(r)}`];if(g.line!==void 0&&S.push(` branch: ${g.line}`),t!==void 0&&t!==g.label&&S.push(` note: "${t}" was already taken by a surviving branch, so this is "${g.label}"`),d!==void 0){S.push(m?` carried ${c.length} uncommitted file(s) in; the source tree is untouched:`:` WARNING: could not copy ${c.length} uncommitted file(s); the workspace starts from HEAD. They are untouched in the source tree:`);for(let b of Tt(c))S.push(` ${b}`);m&&u&&S.push(" staging did not come along; everything above is unstaged here");for(let b of v)S.push(` nested tree ${b.path}: ${b.reason}`)}else if(y.length>0){S.push(` started clean: ${y.length} uncommitted file(s) stayed in the source and did NOT come along:`);for(let b of Tt(y))S.push(` ${b}`)}else l&&S.push(" source tree was clean; nothing carried in");return w!==void 0&&S.push(` ${w}`),S.push("Use `/hydra workspace stop` to merge back and return."),S.join(`
203
+ `)}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=oe(e.provider);return o===void 0?!1:(await o.applyDelta(e.path,r)).ok}async patchFromSnapshot(e,t,n){let r=oe(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=oe(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 Ys(e.sourceCwd).catch(()=>({})),r=[];if(n.carry!==void 0&&n.carry.length>0){let o=await ri(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 Xs(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=oe(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=oe(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=oe(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 g=new Error(`agent ${e} not found in registry`);throw g.code=x.AgentNotInstalled,g}let n=await Me(t,[],{npmRegistry:this.npmRegistry}),r=this.spawner({agentId:e,cwd:iu.homedir(),plan:n}),o;try{o=await r.connection.request("initialize",{protocolVersion:1,clientCapabilities:this.clientCaps(),clientInfo:{name:"hydra",version:ue}})}catch(g){throw await r.kill().catch(()=>{}),wt(g,r)}if(r.authMethods=Gn(o.authMethods),r.steeringSupported=Vn(o),(o.agentCapabilities??{}).sessionCapabilities?.list===void 0)throw await r.kill().catch(()=>{}),new Error(`agent ${e} does not advertise sessionCapabilities.list; cannot sync`);let a;try{a=await this.collectAgentSessions(r)}catch(g){throw await r.kill().catch(()=>{}),g}await r.kill().catch(()=>{});let d=new Map,c=uo(t);d.set(e,c);let u=new Set,l=new Map;for(let g of this.sessions.values()){let p=await this.agentStoreKey(g.agentId,d);u.add(`${p}::${g.upstreamSessionId}`),p===c&&l.set(g.upstreamSessionId,g)}let y=await this.store.list().catch(()=>[]);for(let g of y){u.add(`${await this.agentStoreKey(g.agentId,d)}::${g.upstreamSessionId}`);for(let p of g.upstreamGenerations??[])u.add(`${await this.agentStoreKey(p.agentId,d)}::${p.upstreamSessionId}`)}let h=E.sessionsDir(),f=[],k=0;for(let g of a){l.get(g.sessionId)?.noteUpstreamUpdatedAt(g.updatedAt);let p=`${c}::${g.sessionId}`;if(u.has(p)){k+=1;continue}if(uy(g.cwd,h)){k+=1;continue}let w=c,m=await this.tombstones.read(w,g.sessionId).catch(()=>{});if(!m&&c!==e&&(w=e,m=await this.tombstones.read(w,g.sessionId).catch(()=>{})),m){if(!Pc(m,g.updatedAt)){k+=1;continue}await this.tombstones.remove(w,g.sessionId).catch(()=>{}),this.logger?.info(`syncFromAgent: resurrecting tombstoned ${e}/${g.sessionId} (upstream updatedAt advanced past ${m.upstreamUpdatedAt??"<unset>"})`)}u.add(p);let v=`${ye}${Pt()}`,S=new Date().toISOString(),b=g.updatedAt??S,I={sessionId:v,lineageId:Hn(),upstreamSessionId:g.sessionId,agentId:e,cwd:g.cwd,pendingHistorySync:!0,interactive:!ly(g.title),createdAt:b,updatedAt:b};g.title!==void 0&&(I.title=g.title);let A=Ko(I);await this.store.write(A),f.push({version:1,...A})}return{synced:f,skipped:k}}async listTombstones(e={}){let t=e.grep?.toLowerCase();return(await this.tombstones.list(e.agentId)).filter(r=>e.since===void 0||r.deletedAt>=e.since).filter(r=>t===void 0||[r.title,r.cwd,r.sessionId,r.upstreamSessionId].some(o=>o?.toLowerCase().includes(t))).sort((r,o)=>r.deletedAt<o.deletedAt?1:-1)}async undeleteSessions(e){let t=await this.tombstones.list(),n=[],r=[],o=[];for(let a of e){let d=t.filter(u=>u.upstreamSessionId===a),c=d.length>0?d:t.filter(u=>u.sessionId===a||u.sessionId===`${ye}${a}`);if(c.length===0){r.push({id:a,reason:"no tombstone found"});continue}if(c.length>1){r.push({id:a,reason:"ambiguous: several tombstones match; pass an upstream id",candidates:c.map(u=>u.upstreamSessionId)});continue}o.push({id:a,tombstone:c[0]})}let i=new Map;for(let a of o){let d=i.get(a.tombstone.agentId)??[];d.push(a),i.set(a.tombstone.agentId,d)}for(let[a,d]of i){let c=l=>{let{version:y,...h}=l;return this.tombstones.add(h).catch(()=>{})};for(let l of d)await this.tombstones.remove(a,l.tombstone.upstreamSessionId);let u;try{u=(await this.syncFromAgent(a)).synced}catch(l){for(let y of d)await c(y.tombstone),r.push({id:y.id,reason:`agent sync failed: ${l.message}`});continue}for(let l of d){let y=u.find(h=>h.upstreamSessionId===l.tombstone.upstreamSessionId);if(!y){await c(l.tombstone),r.push({id:l.id,reason:`agent ${a} no longer lists this session`});continue}n.push({id:l.id,sessionId:y.sessionId,upstreamSessionId:l.tombstone.upstreamSessionId})}}return{restored:n,failed:r}}async collectAgentSessions(e){let t=[],n,r=new Set;for(let o=0;o<100;o+=1){let i={};n!==void 0&&(i.cursor=n);let a=await e.connection.request("session/list",i),d=Array.isArray(a.sessions)?a.sessions:[];for(let c of d){if(typeof c.sessionId!="string"||typeof c.cwd!="string")continue;let u={sessionId:c.sessionId,cwd:c.cwd};typeof c.title=="string"&&(u.title=c.title),typeof c.updatedAt=="string"&&(u.updatedAt=c.updatedAt),t.push(u)}if(typeof a.nextCursor!="string"||a.nextCursor.length===0||r.has(a.nextCursor))break;r.add(a.nextCursor),n=a.nextCursor}return t}async applySeedModel(e,t,n,r,o){try{let{verb:i,result:a}=await lt({request:(d,c)=>e.connection.request(d,c),sessionId:t,modelId:n,...o?{verb:o}:{},logger:this.logger});return this.logger?.info(`${r}: ${i} accepted`),{accepted:!0,result:a}}catch(i){return this.logger?.warn(`${r} rejected by agent (${i.message}); session will use the agent's own default`),{accepted:!1}}}async applySeedMode(e,t,n,r){try{let o=await e.connection.request("session/set_mode",{sessionId:t,modeId:n});return this.logger?.info(`${r}: session/set_mode accepted`),{accepted:!0,result:o}}catch(o){return this.logger?.warn(`${r} rejected by agent (${o.message}); session will use the agent's own default mode`),{accepted:!1}}}async restoreConfigOptionValues(e,t,n,r){if(!n||Object.keys(n).length===0)return this.logger?.info(`resurrect: no persisted configOptionValues; agent reports ${JSON.stringify(Object.fromEntries(r.map(i=>[i.id,i.currentValue])))}`),r;let o=r;for(let[i,a]of Object.entries(n)){let d=`resurrect: persisted configOptionValues.${i}=${JSON.stringify(a)}`,c=o.find(y=>y.id===i);if(!c){this.logger?.warn(`${d}: agent does not currently advertise configId=${i}; skipping session/set_config_option`);continue}if(a===c.currentValue){this.logger?.info(`${d}: agent already reports ${JSON.stringify(c.currentValue)}; nothing to restore`);continue}this.logger?.info(`${d}: agent reports ${JSON.stringify(c.currentValue)}; restoring`);let u=Xt(a,c.options.map(y=>y.value));if(u.kind!=="exact"&&u.kind!=="resolved"){this.logger?.warn(`${d} ${u.kind}; skipping session/set_config_option`);continue}let l=u.kind==="resolved"?u.modelId:a;try{let y=await e.connection.request("session/set_config_option",{sessionId:t,configId:i,value:l});this.logger?.info(`${d}: session/set_config_option accepted`),o=dn(y)?cn(y):o.map(h=>h.id===i?{...h,currentValue:l}:h)}catch(y){this.logger?.warn(`${d}: session/set_config_option rejected by agent (${y.message})`)}}return o}async bootstrapAgent(e){let t=e.timer,n=await this.registry.getAgent(e.agentId);if(!n){let a=new Error(`agent ${e.agentId} not found in registry`);throw a.code=x.AgentNotInstalled,a}t?.mark("boot.resolve-agent");let r=await Me(n,e.agentArgs??[],{npmRegistry:this.npmRegistry,onInstallProgress:e.onInstallProgress});t?.mark("boot.plan-spawn");let o=ms(e.selfSessionId,e.forwardedEnv),i=this.spawner({agentId:e.agentId,cwd:e.cwd,plan:r,...o?{extraEnv:o}:{}});t?.mark("boot.spawn");try{let a=await i.connection.request("initialize",{protocolVersion:1,clientCapabilities:this.clientCaps(e.elicitationForms),clientInfo:{name:"hydra",version:ue}}),d=a.agentCapabilities;i.authMethods=Gn(a.authMethods),i.steeringSupported=Vn(a),t?.mark("boot.initialize");let c=fi(n),u=await i.connection.request("session/new",{cwd:e.cwd,mcpServers:e.mcpServers??[],...c&&{_meta:c}});t?.mark("boot.session-new");let l=u.sessionId;if(typeof l!="string")throw new Error(`agent ${e.agentId} returned a non-string sessionId from session/new`);let y=pi(u),h=gi(u),f=zt(u),k=$a(this.sessionDefaults,n),g=k?.value,p=e.configDefaults,w=k?.from??e.agentId,m=e.model??p?.model??g?.model,v;if(m&&m!==y){let R=Yt(m,h),P=e.model!==void 0?`model=${JSON.stringify(m)}`:p?.model!==void 0?`configDefaults.model=${JSON.stringify(m)}`:`sessionDefaults[${w}].model=${JSON.stringify(m)}`;if(R.kind==="exact"||R.kind==="none"){let $=await this.applySeedModel(i,l,m,P,f);$.accepted&&(y=m,v=$.result)}else if(R.kind==="resolved")if(R.modelId===y)y=R.modelId;else{let $=await this.applySeedModel(i,l,R.modelId,`${P} resolved to ${JSON.stringify(R.modelId)}`,f);$.accepted&&(y=R.modelId,v=$.result)}else if(R.kind==="ambiguous")this.logger?.warn(`${P} is ambiguous (trailing-segment matches [${R.candidates.join(", ")}]); skipping session/set_model, session will use ${JSON.stringify(y)}`);else{let $=h.map(L=>L.modelId).join(", ");this.logger?.warn(`${P} not in agent's availableModels ([${$}]); skipping session/set_model, session will use ${JSON.stringify(y)}`)}}t?.mark("boot.seed-model");let S=mi(u),b=hi(u),I=p?.mode??g?.mode;if(I&&I!==b){let R=p?.mode!==void 0?`configDefaults.mode=${JSON.stringify(I)}`:`sessionDefaults[${w}].mode=${JSON.stringify(I)}`;if(S.length>0&&!S.some(P=>P.id===I)){let P=S.map($=>$.id).join(", ");this.logger?.warn(`${R} not in agent's availableModes ([${P}]); skipping session/set_mode, session will use ${JSON.stringify(b)}`)}else{let P=await this.applySeedMode(i,l,I,R);P.accepted&&(b=I,dn(P.result)&&(v=P.result))}}t?.mark("boot.seed-mode");let A={...g??{},...p??{}};delete A.model,delete A.mode;let T=cn(dn(v)?v:u);if(Object.keys(A).length>0)for(let[R,P]of Object.entries(A)){let $=`sessionDefaults[${w}].${R}=${JSON.stringify(P)}`,L=T.find(U=>U.id===R);if(!L){this.logger?.warn(`${$}: agent does not currently advertise configId=${R}; skipping session/set_config_option`);continue}let J=Xt(P,L.options.map(U=>U.value));if(J.kind!=="exact"&&J.kind!=="resolved"){this.logger?.warn(`${$} ${J.kind}; skipping session/set_config_option`);continue}let z=J.kind==="resolved"?J.modelId:P;if(z!==L.currentValue)try{let U=await i.connection.request("session/set_config_option",{sessionId:l,configId:R,value:z});this.logger?.info(`${$}: session/set_config_option accepted`),dn(U)?(T=cn(U),v=U):T=T.map(j=>j.id===R?{...j,currentValue:z}:j)}catch(U){this.logger?.warn(`${$}: session/set_config_option rejected by agent (${U.message})`)}}return t?.mark("boot.seed-config"),i.connection.dropBufferedWhere("session/update",R=>R?.update?.sessionUpdate==="config_option_update"),{agent:i,upstreamSessionId:l,agentMeta:u._meta,agentCapabilities:d,initialModel:y,initialModels:h.length>0?h:void 0,initialModes:S.length>0?S:void 0,initialMode:b,initialConfigOptions:T.length>0?T:void 0,modelVerb:f}}catch(a){throw await i.kill().catch(()=>{}),wt(ru(a,i,e.agentId,{command:r.command,args:r.args,cwd:e.cwd}),i)}}async bootstrapAgentLoad(e,t){let n=await this.registry.getAgent(t.agentId);if(!n){let a=new Error(`agent ${t.agentId} not found in registry`);throw a.code=x.AgentNotInstalled,a}let r=await Me(n,t.agentArgs??[],{npmRegistry:this.npmRegistry}),o=ms(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:this.clientCaps(t.elicitationForms),clientInfo:{name:"hydra",version:ue}}),d=a.agentCapabilities;i.authMethods=Gn(a.authMethods),i.steeringSupported=Vn(a);let c=fi(n),u=await i.connection.request("session/load",{sessionId:e,cwd:t.cwd,mcpServers:t.mcpServers??[],...c&&{_meta:c}}),l=pi(u),y=yt(gi(u)),h=mi(u),f=hi(u),k=yt(cn(u));return{agent:i,upstreamSessionId:e,agentMeta:u._meta,agentCapabilities:d,initialModel:l,initialModels:y,initialModes:h.length>0?h:void 0,initialMode:f,initialConfigOptions:k,modelVerb:zt(u)}}catch(a){throw await i.kill().catch(()=>{}),wt(ru(a,i,t.agentId,{command:r.command,args:r.args,cwd:t.cwd}),i)}}async rewindSession(e,t,n={}){let r=await this.store.read(e);if(!r){let a=new Error(`session not found: ${e}`);throw a.code=x.SessionNotFound,a}if(this.rollbackLocks.has(e)||r.compactionState!=null){let a=new Error("the session is being compacted or rolled back; try again when that finishes");throw a.code=x.InvalidRequest,a}let o=0,i=async()=>{let a=await this.histories.truncateAfterTurn(e,t);if(!a){let u=new Error(`keepThrough messageId not found in the session's recent history: ${t}`);throw u.code=x.InvalidParams,u}if(o=a.removed,o===0)return!1;let d=r.summarizedThroughEntry,c=d!==void 0&&a.kept<d;if(c){let u=this.get(e);u&&(u.summarizedThroughEntry=void 0)}return await this.mutateRecord(e,{},c?["rollbackBreadcrumb","synopsis","summarizedThroughEntry"]:["rollbackBreadcrumb"]),!0};this.rollbackLocks.add(e);try{let a=this.get(e);a?await a.rewind(t,i,n):await i()&&await this.mutateRecord(e,{upstreamSessionId:""})}finally{this.rollbackLocks.delete(e)}return{sessionId:e,removed:o}}async performUncompact(e){if(this.rollbackLocks.has(e))throw new Error("a rollback is already in progress for this session");let t=this.get(e);if(!t)throw new Error("session is not live \u2014 cannot roll back a cold session");let n=await this.store.read(e);if(!n)throw new Error("session record not found");let r=n.rollbackBreadcrumb;if(!r)throw new Error("no rollback breadcrumb found \u2014 either the session has not been compacted, the rollback window has closed (a new turn was dispatched), or a previous rollback already consumed the breadcrumb");let o=n.compactionState;if(o!=null)throw new Error(`compaction is in progress (status: ${o.status}) \u2014 wait for it to complete before rolling back`);if(!await t.isQuiescedForSwap())throw new Error("session is not quiesced for rollback \u2014 wait for in-flight work to complete");this.rollbackLocks.add(e);try{await t.rollbackToUpstream({previousUpstreamSessionId:r.previousUpstreamSessionId,previousSummarizedThroughEntry:r.previousSummarizedThroughEntry}),await this.mutateRecord(e,{summarizedThroughEntry:r.previousSummarizedThroughEntry},["synopsis","rollbackBreadcrumb"])}finally{this.rollbackLocks.delete(e)}}async bootstrapAgentForAuth(e,t){let n=this.pendingAuthAgents.get(e);if(n&&n.isAlive())return n;let r=await this.registry.getAgent(e);if(!r){let d=new Error(`agent ${e} not found in registry`);throw d.code=x.AgentNotInstalled,d}let o=await Me(r,[],{npmRegistry:this.npmRegistry}),i=t??ie(this.defaultCwd),a=this.spawner({agentId:e,cwd:i,plan:o});try{let d=await a.connection.request("initialize",{protocolVersion:1,clientCapabilities:this.clientCaps(),clientInfo:{name:"hydra",version:ue}});a.authMethods=Gn(d.authMethods),a.steeringSupported=Vn(d)}catch(d){throw await a.kill().catch(()=>{}),wt(d,a)}return this.pendingAuthAgents.set(e,a),a.onExit(()=>{this.pendingAuthAgents.get(e)===a&&this.pendingAuthAgents.delete(e)}),a}async planSpawnForAgent(e){let t=await this.registry.getAgent(e);if(!t){let n=new Error(`agent ${e} not found in registry`);throw n.code=x.AgentNotInstalled,n}return Me(t,[],{npmRegistry:this.npmRegistry})}consumePendingAuthAgent(e){let t=this.pendingAuthAgents.get(e);if(t&&(this.pendingAuthAgents.delete(e),!!t.isAlive()))return t}getAgentForSession(e){return this.sessions.get(e)?.agent}async attachManagerHooks(e){e.onClose(({deleteRecord:t})=>{if(this.sessions.delete(e.sessionId),this.driftNoticed.delete(e.sessionId),this.invalidateListCache(),t||this.store.touch(e.sessionId).catch(()=>{}),t&&e.workspace!==void 0&&this.releaseWorkspace(e.workspace,e.sessionId).catch(()=>{}),t){if(e.upstreamSessionId){let r=un({interactive:e.interactive,...e.originatingClient?{originatingClient:e.originatingClient}:{}},!0),o=this.tombstoneAllGenerations(e.sessionId,{agentId:e.agentId,upstreamSessionId:e.upstreamSessionId,upstreamUpdatedAt:new Date(e.updatedAt).toISOString(),cwd:e.cwd,...e.title!==void 0?{title:e.title}:{},...r!==void 0?{interactive:r}:{}},"user").catch(()=>{}).then(()=>this.store.delete(e.sessionId).catch(()=>{})).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===o&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,o);return}let n=this.store.delete(e.sessionId).catch(()=>{}).then(()=>this.histories.delete(e.sessionId).catch(()=>{})).finally(()=>{this.pendingDeletions.get(e.sessionId)===n&&this.pendingDeletions.delete(e.sessionId)});this.pendingDeletions.set(e.sessionId,n);return}}),e.rewindHook=t=>this.rewindSession(e.sessionId,t,{afterCurrentTurn:!0}),e.onTitleChange(t=>{this.persistTitle(e.sessionId,t).catch(()=>{})}),e.onTagsChange(t=>{this.persistTags(e.sessionId,t).catch(()=>{})}),e.onPriorityChange(t=>{this.persistPriority(e.sessionId,t).catch(()=>{})}),e.onAgentChange(({agentId:t,upstreamSessionId:n,...r})=>{this.persistAgentChange(e.sessionId,t,n,r).catch(()=>{})}),e.onModelChange(t=>{this.persistSnapshot(e.sessionId,{currentModel:t}).catch(()=>{})}),e.onModeChange(t=>{this.persistSnapshot(e.sessionId,{currentMode:t}).catch(()=>{})}),e.onInteractiveChange(t=>{this.persistSnapshot(e.sessionId,{interactive:t}).catch(()=>{})}),e.onUsageChange(t=>{this.persistSnapshot(e.sessionId,{currentUsage:au(t)}).catch(()=>{})}),e.onAgentCommandsChange(t=>{this.persistSnapshot(e.sessionId,{agentCommands:t.map(n=>({name:n.name,...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModesChange(t=>{this.persistSnapshot(e.sessionId,{agentModes:t.map(n=>({id:n.id,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onAgentModelsChange(t=>{this.persistSnapshot(e.sessionId,{agentModels:t.map(n=>({modelId:n.modelId,...n.name!==void 0?{name:n.name}:{},...n.description!==void 0?{description:n.description}:{}}))}).catch(()=>{})}),e.onConfigOptionsChange(t=>{this.persistSnapshot(e.sessionId,{configOptionValues:Object.fromEntries(t.map(n=>[n.id,n.currentValue]))}).catch(()=>{})}),e.onAttentionFlagsChange(t=>{this.mutateRecord(e.sessionId,{attentionFlags:t}).catch(()=>{})}),e.onReadStateChange(t=>{this.invalidateListCache(),this.persistReadState(e.sessionId,t).then(()=>this.invalidateListCache()).catch(()=>{})}),this.sessions.set(e.sessionId,e),this.invalidateListCache(),await this.enqueueMetaWrite(e.sessionId,async()=>{let t=await this.store.read(e.sessionId),n=fy(e,t);await this.store.write(n)}).catch(t=>{this.logger?.warn(`failed to persist session record for ${e.sessionId}: ${t instanceof Error?t.message:String(t)}`)})}async getHistory(e){if(this.sessions.has(e))return this.histories.load(e).catch(()=>[]);if(await this.store.read(e))return this.histories.load(e).catch(()=>[])}async pageHistory(e,t){let n=await this.store.read(e);if(!this.sessions.has(e)&&!n)return;let r=this.sessions.get(e)?.side??n?.side,o=await this.histories.pageBefore(e,{...t,skip:a=>On(a.method,a.params),hydrate:!1}),i=qt(o.entries,r);return{entries:await this.histories.hydrate(e,As(i)),hasMore:o.hasMore&&i.length===o.entries.length}}async loadHistory(e,t={}){return this.histories.load(e,t)}async loadToolBlob(e,t){return Cn(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:py(t.currentUsage),agentCommands:t.agentCommands,agentModes:t.agentModes,agentModels:t.agentModels,configOptionValues:t.configOptionValues,createdAt:t.createdAt,pendingHistorySync:t.pendingHistorySync,originatingClient:t.originatingClient,interactive:t.interactive,priority:t.priority,tags:t.tags,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,forwardedEnv:t.forwardedEnv,elicitationForms:t.elicitationForms,workspace:t.workspace,compactionState:t.compactionState,attentionFlags:t.attentionFlags?.filter(r=>!(r.source==="daemon"&&(r.reason.startsWith("permission:")||r.reason.startsWith("elicitation:"))))}}async setForwardedEnv(e,t){if(t===void 0)return;let n=this.sessions.get(e);n&&(n.forwardedEnv=t),await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r)return;let o={...r,forwardedEnv:t};await this.store.write(o)})}async clearPendingHistorySync(e){await this.enqueueMetaWrite(e,async()=>{let t=await this.store.read(e);if(!t||t.pendingHistorySync!==!0)return;let n={...t};delete n.pendingHistorySync,await this.store.write(n)})}async deriveTitleFromHistory(e){let t=await this.histories.load(e).catch(()=>[]);for(let n of t){let r=n.params;if(r?.update?.sessionUpdate!=="prompt_received")continue;let o=r.update.sentBy;if(typeof o?.fromSession=="string"||typeof o?.clientId=="string"&&o.clientId.startsWith("transformer:"))continue;let i=ht(r.update.prompt),a=Bo(i,200);if(a&&!a.startsWith("/"))return a}}get(e){return this.sessions.get(e)}liveSessions(){return this.sessions.values()}setLiveConfig(e){e.sessionDefaults&&(this.sessionDefaults=e.sessionDefaults)}activeAgentVersions(){let e=new Map;for(let t of this.sessions.values()){let n=t.agent.installId,r=t.agent.version,o=e.get(n);o||(o=new Set,e.set(n,o)),o.add(r)}return e}async resolveCanonicalId(e){if(this.sessions.has(e)||await this.store.read(e))return e;if(e.startsWith(ye))return;let t=ye+e;if(this.sessions.has(t)||await this.store.read(t))return t}require(e){let t=this.sessions.get(e);if(!t){let n=new Error(`session ${e} not found`);throw n.code=x.SessionNotFound,n}return t}liveListEntry(e){return{sessionId:e.sessionId,upstreamSessionId:e.upstreamSessionId,cwd:e.cwd,workspace:e.workspace,workspaceError:e.workspaceError,title:e.title,agentId:e.agentId,currentModel:e.currentModel,currentUsage:e.currentUsage,parentSessionId:e.parentSessionId,forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,side:e.side,forkSynthesisState:e.forkSynthesisState,originatingClient:e.originatingClient,interactive:e.interactive,createdAt:new Date(e.createdAt).toISOString(),updatedAt:new Date(e.updatedAt).toISOString(),attachedClients:e.attachedCount,status:"warm",busy:e.turnStartedAt!==void 0,turnStartedAt:e.turnStartedAt,armedTasks:e.armedBackgroundTasks.length,...e.armedSince!==void 0?{armedSince:e.armedSince}:{},awaitingInput:e.awaitingInput,agentPid:e.agentPid,...Vt(e)}}async getOne(e){let t=this.sessions.get(e);if(t){let a=await Kn(t.sessionId),d=un({interactive:t.interactive,...t.originatingClient?{originatingClient:t.originatingClient}:{}},a.hasContent),c=a.mtime??new Date(t.updatedAt).toISOString();return{sessionId:t.sessionId,upstreamSessionId:t.upstreamSessionId,cwd:t.cwd,title:t.title,agentId:t.agentId,currentModel:t.currentModel,currentUsage:t.currentUsage,parentSessionId:t.parentSessionId,forkedFromSessionId:t.forkedFromSessionId,forkedFromMessageId:t.forkedFromMessageId,side:t.side,forkSynthesisState:t.forkSynthesisState,originatingClient:t.originatingClient,interactive:d,priority:t.priority,tags:t.tags,createdAt:new Date(t.createdAt).toISOString(),updatedAt:c,attachedClients:t.attachedCount,status:"warm",agentPid:t.agentPid,busy:t.turnStartedAt!==void 0,turnStartedAt:t.turnStartedAt,armedTasks:t.armedBackgroundTasks.length,...t.armedSince!==void 0?{armedSince:t.armedSince}:{},awaitingInput:t.awaitingInput,...Vt(t)}}let n=await this.store.read(e).catch(()=>{});if(!n)return;let r=await Kn(n.sessionId),o=un(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:Jn(n.currentUsage),importedFromMachine:n.importedFromMachine,importedFromUpstreamSessionId:n.importedFromUpstreamSessionId,parentSessionId:n.parentSessionId,forkedFromSessionId:n.forkedFromSessionId,forkedFromMessageId:n.forkedFromMessageId,side:n.side,forkSynthesisState:n.forkSynthesisState,originatingClient:n.originatingClient,interactive:o,priority:n.priority,tags:n.tags,createdAt:n.createdAt,updatedAt:i,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,...Vt(n)}}async list(e={}){return(await this.listing(e)).entries}async listing(e={}){let t=`${e.cwd??""}|${e.includeNonInteractive?"1":"0"}|${e.status??""}`,n=Date.now(),r=this.listCache.get(t);if(r&&r.expiresAt>n)return r.promise;let o=this.listUncached(e);return this.listCache.set(t,{expiresAt:n+s.LIST_CACHE_TTL_MS,promise:o}),o.catch(()=>{let i=this.listCache.get(t);i&&i.promise===o&&this.listCache.delete(t)}),o}invalidateListCache(){this.listCache.clear()}async listUncached(e={}){let t=await this.store.cursor(),{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,cursor:t};let o=await this.store.list().catch(i=>{throw this.logger?.warn(`session list: store.list() failed: ${i?.message??String(i)}`),i});return n.push(...await this.coldRows(o,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,cursor:t}}async listSince(e,t){let{entries:n,liveIds:r}=await this.warmRows(e);if(e.status==="warm")return{entries:n,removed:[],cursor:await this.store.cursor()};let o=await this.store.listChangedSince(t);return n.push(...await this.coldRows(o.records,r,e)),n.sort((i,a)=>i.updatedAt<a.updatedAt?1:-1),{entries:n,removed:o.removed,cursor:o.cursor}}async seedSessionIndex(){await this.store.ensureIndex();let e=await this.tombstones.list().catch(()=>[]);for(let t of e){if(t.sessionId===void 0)continue;let n=Date.parse(t.deletedAt);Number.isNaN(n)||await this.store.markDeleted(t.sessionId,n)}}static includeRow(e,t){return e.includeNonInteractive?!0:t===!0}async warmRows(e){let t=[],n=new Set,r=[...this.sessions.values()].filter(i=>nu(e.cwd,i));if(e.status==="cold"){for(let i of r)n.add(i.sessionId);return{entries:t,liveIds:n}}let o=await Promise.all(r.map(i=>Kn(i.sessionId)));for(let i=0;i<o.length;i+=1){let a=r[i],d=o[i];n.add(a.sessionId);let c=un({interactive:a.interactive,...a.originatingClient?{originatingClient:a.originatingClient}:{}},d.hasContent);if(!s.includeRow(e,c))continue;let u=d.mtime??new Date(a.updatedAt).toISOString();t.push({sessionId:a.sessionId,upstreamSessionId:a.upstreamSessionId,cwd:a.cwd,workspace:a.workspace,workspaceError:a.workspaceError,title:a.title,agentId:a.agentId,currentModel:a.currentModel,currentUsage:a.currentUsage,parentSessionId:a.parentSessionId,forkedFromSessionId:a.forkedFromSessionId,forkedFromMessageId:a.forkedFromMessageId,side:a.side,originatingClient:a.originatingClient,interactive:c,priority:a.priority,tags:a.tags,createdAt:new Date(a.createdAt).toISOString(),updatedAt:u,attachedClients:a.attachedCount,status:"warm",agentPid:a.agentPid,busy:a.turnStartedAt!==void 0,turnStartedAt:a.turnStartedAt,armedTasks:a.armedBackgroundTasks.length,...a.armedSince!==void 0?{armedSince:a.armedSince}:{},awaitingInput:a.awaitingInput,compactionState:a.compactionState,forkSynthesisState:a.forkSynthesisState,...Vt(a)})}return{entries:t,liveIds:n}}async coldRows(e,t,n){let r=[],o=e.filter(a=>!t.has(a.sessionId)&&nu(n.cwd,a)),i=await Promise.all(o.map(a=>Kn(a.sessionId)));for(let a=0;a<o.length;a+=1){let d=o[a],c=i[a],u=un(d,c.hasContent);if(!s.includeRow(n,u))continue;let l=c.mtime??d.updatedAt;r.push({sessionId:d.sessionId,upstreamSessionId:d.upstreamSessionId,cwd:d.cwd,workspace:d.workspace,title:d.title,agentId:d.agentId,currentModel:d.currentModel,currentUsage:Jn(d.currentUsage),importedFromMachine:d.importedFromMachine,importedFromUpstreamSessionId:d.importedFromUpstreamSessionId,parentSessionId:d.parentSessionId,forkedFromSessionId:d.forkedFromSessionId,forkedFromMessageId:d.forkedFromMessageId,side:d.side,originatingClient:d.originatingClient,interactive:u,priority:d.priority,tags:d.tags,createdAt:d.createdAt,updatedAt:l,attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1,compactionState:d.compactionState,forkSynthesisState:d.forkSynthesisState,...Vt(d)})}return r}async exportBundle(e,t={}){let n=await this.store.read(e);if(!n)return;let r;if(n.lineageId)r=n;else{let c=Hn(),u={...n,lineageId:c};await this.enqueueMetaWrite(e,async()=>{let l=await this.store.read(e);l&&(l.lineageId||await this.store.write({...l,lineageId:c}))}).catch(()=>{}),r=u}let o=t.tools??"inline",i=t.includeArchivedHistory?await this.loadArchivedHistory(e,o):await this.histories.load(e,o==="references"?{tools:"references"}:{}).catch(()=>[]),a=await ou(e);if(o!=="references")return{record:r,history:i,promptHistory:a};let d={};for(let c of Gc(i)){let u=await ma(e,c);u&&(d[c]=u.toString("base64"))}return{record:r,history:i,promptHistory:a,toolBlobs:d}}async loadArchivedHistory(e,t){let n=await this.histories.loadArchives(e),r=await this.histories.load(e,{tools:"references",maxEntries:1/0}),o=[...n,...r];return t==="references"?o:this.histories.hydrate(e,o)}async importBundle(e,t={}){let n=await this.store.findByLineageId(e.session.lineageId);if(n){if(!t.replace){let i=new Error(`bundle already imported as ${n.sessionId}`);throw i.code=x.BundleAlreadyImported,i.existingSessionId=n.sessionId,i}let o=this.sessions.get(n.sessionId);return o&&await o.close({deleteRecord:!1,by:"bundle-import-overwrite"}).catch(()=>{}),await this.writeImportedRecord({sessionId:n.sessionId,bundle:e,preservedCreatedAt:n.createdAt,cwd:t.cwd}),{sessionId:n.sessionId,importedFromSessionId:e.session.sessionId,replaced:!0}}let r=`${ye}${Pt()}`;return await this.writeImportedRecord({sessionId:r,bundle:e,cwd:t.cwd}),{sessionId:r,importedFromSessionId:e.session.sessionId,replaced:!1}}async forkSession(e,t={}){let n=await this.store.read(e);if(!n){let b=new Error(`source session not found: ${e}`);throw b.code=x.SessionNotFound,b}let r=t.agentId??n.agentId,o=r!==n.agentId;if(o&&!await this.registry.getAgent(r)){let I=new Error(`agent ${r} not found in registry`);throw I.code=x.AgentNotInstalled,I}let i=await this.histories.load(e).catch(()=>[]),a=i,d,c=t.mode??(t.side?"verbatim":"synthesis"),u,l,y,h=12e4;if(c==="verbatim")if(t.forkAt!==void 0){let b=qn(ui(i),t.forkAt);if(b<0){let I=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw I.code=x.InvalidParams,I}d=t.forkAt,a=i.slice(0,b+1)}else{let b=yy(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 I=qn(ui(i),t.forkAt);if(I<0){let A=new Error(`forkAt messageId not found in source history: ${t.forkAt}`);throw A.code=x.InvalidParams,A}d=t.forkAt,a=i.slice(0,I+1)}else d="",a=i;let b=await this.registry.getAgent(r);if(!b){let I=new Error(`agent ${r} not found in registry`);throw I.code=x.AgentNotInstalled,I}y=b,l=n.currentModel,u="running"}let f=await ou(e),k=c==="synthesis",g={...n,lineageId:Hn(),agentId:r,interactive:!1,...u!==void 0?{forkSynthesisState:u}:{},summarizedThroughEntry:a.length,...t.title!==void 0?{title:t.title}:{},currentUsage:void 0,...o?{currentModel:void 0,currentMode:void 0,agentCommands:void 0,agentModes:void 0,agentModels:void 0}:{},...t.model!==void 0?{currentModel:t.model}:{}},p=zn({record:g,history:a,promptHistory:f.length>0?f:void 0,hydraVersion:ue,machine:At()}),w=`${ye}${Pt()}`,m=t.cwd===void 0?void 0:ps(ie(t.cwd)),v;if(t.cwd===void 0&&n.workspace!==void 0){let b=await this.deriveForkWorkspace(n.workspace,`${n.workspace.label}-fork-${w.slice(-6)}`);b!==void 0?(v=b,m=b.path):(m=n.workspace.sourceCwd,this.logger?.warn?.(`fork ${w}: could not derive an isolated workspace from ${n.workspace.path}; running unisolated in ${m}`))}await this.writeImportedRecord({sessionId:w,bundle:p,cwd:m,...v!==void 0?{workspace:v}:{},forkedFromSessionId:e,forkedFromMessageId:d,...t.side!==void 0?{side:{...t.side.selection!==void 0?{selection:t.side.selection}:{},...nd(a)}}:{},...u!==void 0?{forkSynthesisState:u}:{}});let S=k?(async()=>{try{let b=await Me(y,[],{npmRegistry:this.npmRegistry}),I=await nr({agentId:r,cwd:t.cwd??E.sessionDir(e),plan:b,history:a,modelId:l,sessionId:e,logger:this.logger,timeoutMs:h});I&&I.synopsis?await this.mutateRecord(w,{synopsis:I.synopsis},["forkSynthesisState"]):(this.logger?.warn(`forkSession(${e}): generateSynopsis returned no synopsis \u2014 fork usable via recall`),await this.mutateRecord(w,{},["forkSynthesisState"]))}catch(b){this.logger?.warn(`forkSession(${e}): generateSynopsis failed \u2014 fork usable via recall: ${b.message}`);try{await this.mutateRecord(w,{},["forkSynthesisState"])}catch(I){this.logger?.warn(`forkSession(${e}): mutateRecord to clear forkSynthesisState failed: ${I.message}`)}}})():Promise.resolve();if(t.prompt!==void 0&&t.prompt.trim()!==""){let b=t.prompt;S.catch(()=>{}).then(()=>this.deliverHeadlessPrompt(w,b)).catch(I=>{this.logger?.warn(`forkSession(${e}): headless prompt delivery to ${w} failed: ${I.message}`)})}return{sessionId:w,forkedFromSessionId:e,forkedAt:d}}async deliverHeadlessPrompt(e,t){let n=await this.loadFromDisk(e);if(!n){this.logger?.warn(`deliverHeadlessPrompt: ${e} vanished before its prompt could be sent`);return}let r=this.sessions.get(e)??await this.resurrect(n),o=cy(),i={clientId:`fork-prompt-${Pt().slice(0,8)}`,connection:new qe(o),clientInfo:{name:"hydra-acp-fork",version:ue}};await r.attach(i,"none");try{await r.prompt(i.clientId,{sessionId:e,prompt:[{type:"text",text:t}]})}finally{r.detach(i.clientId),o.close()}}async writeImportedRecord(e){if(await this.histories.rewrite(e.sessionId,e.bundle.history),e.bundle.toolBlobs)for(let[o,i]of Object.entries(e.bundle.toolBlobs))await ha(e.sessionId,o,Buffer.from(i,"base64")).catch(()=>{});let t=new Date(e.bundle.session.updatedAt);Number.isNaN(t.getTime())||await Mt.utimes(E.historyFile(e.sessionId),t,t).catch(()=>{}),e.bundle.promptHistory&&e.bundle.promptHistory.length>0&&await Zc(E.tuiHistoryFile(e.sessionId),e.bundle.promptHistory).catch(()=>{});let n=new Date().toISOString(),r=e.forkedFromSessionId!==void 0;await this.enqueueMetaWrite(e.sessionId,async()=>{await this.store.write({sessionId:e.sessionId,lineageId:e.bundle.session.lineageId,upstreamSessionId:"",...r?{forkedFromSessionId:e.forkedFromSessionId,forkedFromMessageId:e.forkedFromMessageId,...e.side!==void 0?{side:e.side}:{}}:{importedFromSessionId:e.bundle.session.sessionId,importedFromUpstreamSessionId:e.bundle.session.upstreamSessionId,importedFromMachine:e.bundle.exportedFrom.machine},agentId:e.bundle.session.agentId,cwd:e.cwd??e.bundle.session.cwd,workspace:e.workspace,title:e.bundle.session.title,synopsis:e.bundle.session.synopsis,summarizedThroughEntry:e.bundle.session.summarizedThroughEntry,...e.forkSynthesisState!==void 0?{forkSynthesisState:e.forkSynthesisState}:{},currentModel:e.bundle.session.currentModel,currentMode:e.bundle.session.currentMode,currentUsage:e.bundle.session.currentUsage,agentCommands:e.bundle.session.agentCommands,agentModes:e.bundle.session.agentModes,interactive:e.bundle.session.interactive,originatingClient:e.bundle.session.originatingClient,priority:e.bundle.session.priority,tags:e.bundle.session.tags,attentionFlags:[],createdAt:e.preservedCreatedAt??n,updatedAt:e.bundle.session.updatedAt})})}async agentStoreKey(e,t){let n=t.get(e);if(n!==void 0)return n;let r=e;try{let o=await this.registry.getAgent(e);o&&(r=uo(o))}catch{}return t.set(e,r),r}async tombstoneAllGenerations(e,t,n){let r=await this.store.read(e).catch(()=>{}),o=new Map;for(let d of r?.upstreamGenerations??[])d.upstreamSessionId&&o.set(`${d.agentId}::${d.upstreamSessionId}`,{agentId:d.agentId,upstreamSessionId:d.upstreamSessionId});o.set(`${t.agentId}::${t.upstreamSessionId}`,{agentId:t.agentId,upstreamSessionId:t.upstreamSessionId});let i=new Date().toISOString(),a=new Map;for(let d of o.values())await this.tombstones.add({agentId:await this.agentStoreKey(d.agentId,a),upstreamSessionId:d.upstreamSessionId,sessionId:e,deletedAt:i,upstreamUpdatedAt:t.upstreamUpdatedAt,cwd:t.cwd,...t.title!==void 0?{title:t.title}:{},reason:n,...t.interactive!==void 0?{interactive:t.interactive}:{}}).catch(()=>{})}async deleteRecord(e,t="user"){let n=await this.store.read(e);if(!n)return!1;if(n.upstreamSessionId){let r=await Kn(e),o=un(n,r.hasContent);await this.tombstoneAllGenerations(e,{agentId:n.agentId,upstreamSessionId:n.upstreamSessionId,upstreamUpdatedAt:n.updatedAt,cwd:n.cwd,...n.title!==void 0?{title:n.title}:{},...o!==void 0?{interactive:o}:{}},t)}return n.workspace!==void 0&&await this.releaseWorkspace(n.workspace,e).catch(()=>{}),await this.store.delete(e).catch(()=>{}),await this.histories.delete(e).catch(()=>{}),this.invalidateListCache(),!0}async waitForDeletion(e){let t=this.pendingDeletions.get(e);t&&await t}async isTombstoned(e,t){let n=await this.agentStoreKey(e,new Map);return(await this.tombstones.read(n,t).catch(()=>{})??(n!==e?await this.tombstones.read(e,t).catch(()=>{}):void 0))?.reason==="user"}async hasRecord(e){return await this.store.read(e).catch(()=>{})!==void 0}async isRetiredGeneration(e,t){let n=await this.store.read(e).catch(()=>{});return!n||n.upstreamSessionId===t?!1:(n.upstreamGenerations??[]).some(r=>r.upstreamSessionId===t)}async clearWorkspaceBinding(e){if(this.get(e)!==void 0)return"live";let t=await this.store.read(e).catch(()=>{});if(!t)return"missing";let n=t.workspace?.sourceCwd;return await this.mutateRecord(e,n!==void 0?{cwd:n}:{},["workspace"]),"cleared"}async setCwd(e,t){if(t=ps(t),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 setTags(e,t){let n=this.get(e);if(n)return n.setTags(t),!0;if(!await this.hasRecord(e))return!1;let r=xt(t);return await this.persistTags(e,r.length>0?r:void 0),!0}async persistTags(e,t){t===void 0?await this.mutateRecord(e,{},["tags"]):await this.mutateRecord(e,{tags:t}),this.invalidateListCache()}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:du(o,t,n,void 0,r)}))}async persistSnapshot(e,t){let n={};t.currentModel!==void 0&&(n.currentModel=t.currentModel),t.currentMode!==void 0&&(n.currentMode=t.currentMode),t.currentUsage!==void 0&&(n.currentUsage=t.currentUsage),t.agentCommands!==void 0&&(n.agentCommands=t.agentCommands),t.agentModes!==void 0&&(n.agentModes=t.agentModes),t.agentModels!==void 0&&(n.agentModels=t.agentModels),t.configOptionValues!==void 0&&(n.configOptionValues=t.configOptionValues),t.interactive!==void 0&&(n.interactive=t.interactive),t.cwd!==void 0&&(n.cwd=t.cwd),await this.mutateRecord(e,n)}async setRead(e,t){let n=this.sessions.get(e);if(n)return n.setRead(t),!0;let r=!1;return await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;r=!0;let i=Ps(o,t);i!==void 0&&await this.store.write({...o,readAt:i})}),this.invalidateListCache(),r}async persistReadState(e,t){await this.enqueueMetaWrite(e,async()=>{let n=await this.store.read(e);n&&await this.store.write({...n,lastTurnEndedAt:t.lastTurnEndedAt,readAt:t.readAt})})}async mutateRecord(e,t,n=[],r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o,...t,...r?r(o):{},updatedAt:new Date().toISOString()};for(let a of n)delete i[a];await this.store.write(i)})}static EXTENSION_STATE_CAP_BYTES=64*1024;async getExtensionState(e,t){return(await this.store.read(e))?.extensionState?.[t]??{}}async getExtensionStateKey(e,t,n){return(await this.getExtensionState(e,t))[n]}async setExtensionStateKey(e,t,n,r){await this.enqueueMetaWrite(e,async()=>{let o=await this.store.read(e);if(!o)return;let i={...o.extensionState??{}},a={...i[t]??{},[n]:r},d=Buffer.byteLength(JSON.stringify(a),"utf8");if(d>s.EXTENSION_STATE_CAP_BYTES)throw new Error(`extension_state: bucket for ${t} would be ${d} bytes; cap is ${s.EXTENSION_STATE_CAP_BYTES}`);i[t]=a;let c={...o,extensionState:i,updatedAt:new Date().toISOString()};await this.store.write(c)})}async deleteExtensionStateKey(e,t,n){await this.enqueueMetaWrite(e,async()=>{let r=await this.store.read(e);if(!r?.extensionState?.[t])return;let o={...r.extensionState},i={...o[t]};if(!(n in i))return;delete i[n],Object.keys(i).length===0?delete o[t]:o[t]=i;let a={...r,extensionState:o,updatedAt:new Date().toISOString()};await this.store.write(a)})}enqueueMetaWrite(e,t){return this.enqueueKeyed(this.metaWriteQueues,e,t)}enqueueKeyed(e,t,n){let o=(e.get(t)??Promise.resolve()).catch(()=>{}).then(n),i=o.catch(()=>{});return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)}),o}liveSessionsIn(e,t){let n=[];for(let r of this.sessions.values())r.sessionId!==t&&r.workspace?.path===e&&n.push(r);return n}async closeAll(){let e=[...this.sessions.values()];await Promise.allSettled(e.map(t=>t.close({deleteRecord:!1,by:"daemon-shutdown"}))),this.sessions.clear()}async flushSynopsis(e){await this.synopsisCoordinator.flush(e)}async shutdownSynopsis(){await this.synopsisCoordinator.shutdown()}scheduleSynopsis(e){this.synopsisCoordinator.schedule(e)}scheduleCompaction(e,t){if(t?.targetAgentId){this.mutateRecord(e,{pendingAgentSwap:t.targetAgentId}).catch(r=>{this.logger?.warn(`scheduleCompaction: failed to stamp pendingAgentSwap for ${e}: ${r instanceof Error?r.message:String(r)}`)});let n=t.targetAgentId;(async()=>{try{let r=await this.store.read(e),o=await this.histories.load(e,{maxEntries:1/0});if(Hc(o)===0){this.logger?.info(`compaction: zero-turn fast-path swap sessionId=${e} target=${n}`),await this.dispatchSynthesisSwap(e,void 0,o.length,n);return}if(!r?.synopsis||r.summarizedThroughEntry===void 0){this.synopsisCoordinator.scheduleCompaction(e,t);return}if(o.length!==r.summarizedThroughEntry){this.synopsisCoordinator.scheduleCompaction(e,t);return}this.logger?.info(`compaction: fast-path swap sessionId=${e} target=${n} (reusing artifact @${r.summarizedThroughEntry})`),await this.dispatchSynthesisSwap(e,r.synopsis,r.summarizedThroughEntry,n)}catch(r){this.logger?.warn(`scheduleCompaction: fast-path check failed for ${e}: ${r instanceof Error?r.message:String(r)} \u2014 falling back to synthesis`),this.synopsisCoordinator.scheduleCompaction(e,t)}})();return}this.synopsisCoordinator.scheduleCompaction(e,t)}getCompactionInFlight(){let e=this.synopsisCoordinator.size();return e.inflight>0||e.queued>0}async getPendingAgentSwap(e){return(await this.store.read(e).catch(()=>{}))?.pendingAgentSwap}async getCompactionState(e){return(await this.store.read(e).catch(()=>{}))?.compactionState}async persistRollbackBreadcrumb(e,t){await this.mutateRecord(e,{},void 0,n=>{let r=n.rollbackBreadcrumb;return r!==void 0&&t.runId!==void 0&&r.runId===t.runId?(this.logger?.info(`compaction: keeping rollback breadcrumb pinned at ${r.previousUpstreamSessionId} for runId=${t.runId} sessionId=${e} (later swap of the same run)`),{}):{rollbackBreadcrumb:t}})}async getUpstreamGenerations(e){return(await this.store.read(e).catch(()=>{}))?.upstreamGenerations??[]}async getRollbackBreadcrumb(e){return(await this.store.read(e).catch(()=>{}))?.rollbackBreadcrumb}emitSwapPhase(e,t,n){let r=this.get(e);if(r){if(t){if(n.phase==="failed"){r.broadcastPendingAgentSwap(null);return}if(n.phase==="converged")return;r.broadcastPendingAgentSwap(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 Qd(t.sessionId).catch(()=>[]);if(n.length===0)continue;let r=Date.now(),o=n.filter(d=>r-d.enqueuedAt<tu),i=n.length-o.length;if(i>0&&(this.logger?.info(`queue replay: dropping ${i} stale prompt(s) for ${t.sessionId} (TTL ${tu/1e3}s)`),await Fn(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 Fn(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 uy(s,e){if(typeof s!="string"||s.length===0)return!1;let t=Qn.resolve(s),n=Qn.resolve(e);return t===n||t.startsWith(n+Qn.sep)}function ly(s){return s!==void 0&&/^\{\s*"session_id"\s*:\s*"[^"]*"\s*,\s*"(?:transcript_path|cwd|permission_mode|hook_event_name)"\s*:/.test(s)}function nu(s,e){if(s===void 0||s.length===0)return!0;let t=gs(s);if(gs(e.cwd)===t)return!0;let n=e.workspace?.sourceCwd;return n!==void 0&&gs(n)===t}function fy(s,e){let n=(s.mergedAvailableCommands().length>0?s.agentOnlyAdvertisedCommands().map(y=>y.description!==void 0?{name:y.name,description:y.description}:{name:y.name}):void 0)??e?.agentCommands,r=s.availableModes(),i=(r.length>0?r.map(y=>{let h={id:y.id};return y.name!==void 0&&(h.name=y.name),y.description!==void 0&&(h.description=y.description),h}):void 0)??e?.agentModes,a=s.availableModels(),c=(a.length>0?a.map(y=>{let h={modelId:y.modelId};return y.name!==void 0&&(h.name=y.name),y.description!==void 0&&(h.description=y.description),h}):void 0)??e?.agentModels,u=s.extraConfigOptionValues(),l=Object.keys(u).length>0?u:e?.configOptionValues;return Ko({sessionId:s.sessionId,lineageId:e?.lineageId??Hn(),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:au(s.persistableUsage)??e?.currentUsage,agentCommands:n,agentModes:i,agentModels:c,configOptionValues:l,parentSessionId:s.parentSessionId??e?.parentSessionId,forkedFromSessionId:s.forkedFromSessionId??e?.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId??e?.forkedFromMessageId,side:s.side??e?.side,originatingClient:s.originatingClient??e?.originatingClient,interactive:s.interactive??e?.interactive,priority:s.priority??e?.priority,tags:s.tags??e?.tags,lastTurnEndedAt:s.lastTurnEndedAt??e?.lastTurnEndedAt,readAt:s.readAt??e?.readAt,forwardedEnv:s.forwardedEnv??e?.forwardedEnv,elicitationForms:s.elicitationForms??e?.elicitationForms,workspace:s.workspace,attentionFlags:s.listAttentionFlags(),extensionState:e?.extensionState,upstreamGenerations:e?du(e,s.agentId,s.upstreamSessionId):void 0,createdAt:e?.createdAt??new Date(s.createdAt).toISOString()})}function au(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 py(s){return s?{...s}:void 0}function gy(s){return(s.extendsChain??[s.id]).some(t=>t==="claude-acp"||t.startsWith("claude-acp-"))}var my=[{type:"system",subtype:"background_tasks_changed"}];function fi(s,e={}){if(!gy(s))return;let t={extraArgs:{"thinking-display":"summarized"}};return e.model&&(t.model=e.model),{claudeCode:{options:t,emitRawSDKMessages:my}}}function ar(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=hy(s,e.configId);if(o){let i=e.fromConfig(o);if(i!==void 0)return i}}function pi(s){return ar(s,{nestedKey:"models",configId:"model",fromObject:e=>Ie(e.currentModelId)??Ie(e.currentModel)??Ie(e.modelId)??Ie(e.model),fromConfig:e=>Ie(e.currentValue)})}function wt(s,e){if(!s||typeof s!="object")return s;let t=s;if(t.code!==x.AuthRequired)return s;let n=c=>!!c&&typeof c=="object"&&!Array.isArray(c),r=n(t.data)?t.data:{},o=n(r._meta)?r._meta:{},i=n(o["hydra-acp"])?o["hydra-acp"]:{},a=typeof t.message=="string"?t.message:"authentication required",d=new Error(a);return d.code=x.AuthRequired,d.data={...r,_meta:{...o,"hydra-acp":{...i,authMethods:e.authMethods??[],agentId:e.agentId}}},d}function su(s){return/^[A-Za-z0-9_\-./=:@]+$/.test(s)?s:`'${s.replace(/'/g,"'\\''")}'`}function ru(s,e,t,n){if(s&&typeof s=="object"&&s.code===x.AuthRequired)return s;let r=s instanceof Error?s.message:String(s),o=r.includes("stderr:"),i=o?"":e.stderrTailText(),a=n?`to reproduce: (cd ${su(n.cwd)} && ${[n.command,...n.args].map(su).join(" ")})`:"";if(!i&&!a)return s;let d=[o?r:`agent ${t} failed to start: ${r}`];i&&d.push(`stderr: ${i}`),a&&d.push(a);let c=new Error(d.join(`
204
+ `));if(s&&typeof s=="object"){let u=s;typeof u.code=="number"&&(c.code=u.code),u.data!==void 0&&(c.data=u.data)}return c}function Vn(s){return s._meta?.steering?.supported===!0}function Gn(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 Ie(s){if(typeof s!="string")return;let e=s.trim();return e.length>0?e:void 0}function hy(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 dn(s){return!s||typeof s!="object"||Array.isArray(s)?!1:Array.isArray(s.configOptions)}function cn(s){let e=s.configOptions;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object"||Array.isArray(n))continue;let r=n,o=Ie(r.id);if(!o||o==="model"||o==="mode"||o==="agent")continue;let i=Uo(r.options);if(i.length===0)continue;let a=Ie(r.description);t.push({id:o,name:Ie(r.name)??o,...a?{description:a}:{},category:Ie(r.category)??"other",type:"select",currentValue:Ie(r.currentValue)??i[0].value,options:i})}return t}function yt(s){return s.length>0?s:void 0}function gi(s){return ar(s,{nestedKey:"models",configId:"model",fromObject:e=>{let t=Nn(e.availableModels);return t.length>0?t:void 0},fromConfig:e=>{let t=Nn(e.options);return t.length>0?t:void 0}})??[]}function mi(s){return ar(s,{nestedKey:"modes",configId:"mode",fromObject:e=>{let t=Us(e.availableModes);return t.length>0?t:void 0},fromConfig:e=>{let t=Us(e.options);return t.length>0?t:void 0}})??[]}function hi(s){return ar(s,{nestedKey:"modes",configId:"mode",fromObject:e=>Ie(e.currentModeId)??Ie(e.currentMode)??Ie(e.modeId)??Ie(e.mode),fromConfig:e=>Ie(e.currentValue)})}function yy(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 ou(s){try{let e=await Mt.readFile(E.tuiHistoryFile(s),"utf8"),t=[];for(let n of e.split(`
205
+ `))if(n.length!==0)try{let r=JSON.parse(n);typeof r=="string"&&t.push(r)}catch{}return t}catch{return[]}}function du(s,e,t,n=new Date().toISOString(),r={}){let{retiredCost:o,retiredUsed:i,startedUsed:a,lifetimeCost:d,reason:c,runId:u}=r,l=f=>d!==void 0&&f.lifetimeCostAtStart!==void 0?Math.max(0,d-f.lifetimeCostAtStart):o,y=s.upstreamGenerations&&s.upstreamGenerations.length>0?[...s.upstreamGenerations]:s.upstreamSessionId?[{upstreamSessionId:s.upstreamSessionId,agentId:s.agentId}]:[],h=y[y.length-1];if(h&&h.upstreamSessionId===t){if(y.length>=2){let f=y[y.length-2];if(f){let k=l(f);y[y.length-2]={...f,...k!==void 0&&f.cost===void 0?{cost:k}:{},...i!==void 0&&f.usedAtEnd===void 0?{usedAtEnd:i}:{}}}}return(c!==void 0&&h.reason===void 0||a!==void 0&&h.usedAtStart===void 0||d!==void 0&&h.lifetimeCostAtStart===void 0)&&(y[y.length-1]={...h,...c!==void 0&&h.reason===void 0?{reason:c,...u!==void 0?{runId:u}:{}}:{},...a!==void 0&&h.usedAtStart===void 0?{usedAtStart:a}:{},...d!==void 0&&h.lifetimeCostAtStart===void 0?{lifetimeCostAtStart:d}:{}}),y}return h&&h.endedAt===void 0&&(y[y.length-1]={...h,endedAt:n,...(()=>{let f=l(h);return f!==void 0?{cost:f}:{}})(),...i!==void 0?{usedAtEnd:i}:{}}),y.push({upstreamSessionId:t,agentId:e,startedAt:n,...c!==void 0?{reason:c}:{},...u!==void 0?{runId:u}:{},...a!==void 0?{usedAtStart:a}:{},...d!==void 0?{lifetimeCostAtStart:d}:{}}),y}async function Kn(s){try{let e=await Mt.stat(E.historyFile(s));return{mtime:new Date(e.mtimeMs).toISOString(),hasContent:e.size>0}}catch{return{hasContent:!1}}}function un(s,e){return s.interactive!==void 0?s.interactive:s.originatingClient?.name===tr?!1:e?!0:void 0}import{spawn as ky}from"child_process";import*as ur from"fs";import*as ot from"fs/promises";import*as lr from"path";import vy from"pino-roll";var dr=class{windowMs;maxFailures;now;recentExits=[];tripped_;constructor(e={}){this.windowMs=e.windowMs??3e5,this.maxFailures=e.maxFailuresInWindow??10,this.now=e.now??Date.now}recordExit(e,t,n){if(e===78){let i=`exited with code 78 (unrecoverable); fix and run \`${n}s start ${t}\``;return this.tripped_=i,{tripped:i}}let r=this.now();this.recentExits.push(r);let o=r-this.windowMs;for(;this.recentExits.length>0&&this.recentExits[0]<o;)this.recentExits.shift();if(this.recentExits.length>this.maxFailures){let i=Math.round(this.windowMs/6e4),a=`${this.recentExits.length} exits in ${i}m (crash loop); fix and run \`${n}s start ${t}\``;return this.tripped_=a,{tripped:a}}return"restart"}reset(){this.recentExits=[],this.tripped_=void 0}get tripped(){return this.tripped_}};import*as cu from"fs/promises";import*as yi from"path";var cr=process.platform!=="win32";import{spawnSync as wy}from"child_process";function uu(s){let e=wy("taskkill",["/pid",String(s),"/T","/F"],{stdio:"ignore",windowsHide:!0});if(e.error)throw e.error}function Yn(s,e,t={}){let n=t.platform??process.platform,r=s.pid;if(n==="win32"&&r!==void 0)try{(t.killTree??uu)(r);return}catch{}s.kill(e)}function wi(s,e,t={}){if((t.platform??process.platform)==="win32")try{(t.killTree??uu)(s);return}catch{}process.kill(s,e)}var by=1e3,Sy=6e4,ki=3e3,ln=class{entries=new Map;stopping=!1;context;tokenRegistry;breakerOptions;processTree;restartBaseMs;restartCapMs;adapter;constructor(e,t,n,r={}){this.adapter=t,this.context=n,this.tokenRegistry=r.tokenRegistry,this.breakerOptions=r.breakerOptions,this.processTree=r.processTree,this.restartBaseMs=r.restartBaseMs??by,this.restartCapMs=r.restartCapMs??Sy;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 ot.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{Yn(n,"SIGTERM",this.processTree)}catch{}e.push(new Promise(r=>{if(n.exitCode!==null||n.signalCode!==null){r();return}let o=setTimeout(()=>{try{Yn(n,"SIGKILL",this.processTree)}catch{}r()},ki);n.on("exit",()=>{clearTimeout(o),r()})}))}}await Promise.allSettled(e);for(let t of this.entries.values()){try{t.logStream?.end()}catch{}t.child=void 0,t.logStream=void 0,t.pid=void 0}}list(){return[...this.entries.values()].map(e=>this.infoFor(e))}get(e){let t=this.entries.get(e);return t?this.infoFor(t):void 0}has(e){return this.entries.has(e)}async startByName(e){let t=this.entries.get(e);if(!t)throw Xn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");if(t.child)throw Xn(new Error(`${this.adapter.kind} ${e} already running`),"CONFLICT");return t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0),t.manuallyStopped=!1,t.restartCount=0,t.breaker.reset(),t.failureReason=void 0,await this.spawn(t,0),this.infoFor(t)}async stopByName(e){let t=this.entries.get(e);if(!t)throw Xn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;return n?(await this.terminate(t,n),this.infoFor(t)):this.infoFor(t)}async restartByName(e){return await this.stopByName(e),this.startByName(e)}register(e){if(this.entries.has(e.name))throw Xn(new Error(`${this.adapter.kind} ${e.name} already exists`),"CONFLICT");if(!this.context)throw new Error(`${this.managerName()}: setContext must be called before register`);let t=this.makeEntry(e);return this.entries.set(e.name,t),e.enabled&&this.spawn(t,0).catch(n=>{t.failureReason=`spawn: ${n.message}`}),this.infoFor(t)}async unregister(e){let t=this.entries.get(e);if(!t)throw Xn(new Error(`unknown ${this.adapter.kind}: ${e}`),"NOT_FOUND");t.manuallyStopped=!0,t.restartTimer&&(clearTimeout(t.restartTimer),t.restartTimer=void 0);let n=t.child;n&&await this.terminate(t,n);try{t.logStream?.end()}catch{}this.entries.delete(e)}async terminate(e,t){if(t.exitCode!==null||t.signalCode!==null)return;let n=new Promise(o=>{e.exitWaiters.push(o)});try{Yn(t,"SIGTERM",this.processTree)}catch{}let r=setTimeout(()=>{try{Yn(t,"SIGKILL",this.processTree)}catch{}},ki);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 dr(this.breakerOptions),failureReason:void 0}}async reapOrphans(){let e;try{e=await ot.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 ot.readFile(n,"utf8"),i=Number.parseInt(o.trim(),10);Number.isInteger(i)&&i>0&&(r=i)}catch{}if(typeof r=="number"&&vi(r)){try{wi(r,"SIGTERM",this.processTree)}catch{}let o=Date.now()+ki;for(;Date.now()<o&&vi(r);)await new Promise(i=>setTimeout(i,50));if(vi(r))try{wi(r,"SIGKILL",this.processTree)}catch{}}await ot.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=lr.dirname(this.adapter.paths.logFile(r.name)),a;try{await ot.mkdir(i,{recursive:!0}),a=await vy({file:lr.join(i,`${r.name}.log`),size:"5m",mkdir:!0,symlink:cr,limit:{count:5}}),a.on("error",g=>{e.failureReason=`log stream: ${g.message}`})}catch(g){if(this.stopping||e.manuallyStopped)return;e.failureReason=`log setup: ${g.message}`,this.scheduleRestart(e,t+1);return}if(this.stopping||e.manuallyStopped){try{a.end()}catch{}return}a.write(`[hydra-acp] ${new Date().toISOString()} starting ${this.adapter.kind} ${r.name} (attempt ${t+1})
206
+ `);let d=this.tokenRegistry?.mint(r.name,this.adapter.tokenRole)??n.serviceToken;e.processToken=d,e.version=void 0;let c={...hs(),HYDRA_ACP_DAEMON_URL:n.daemonUrl,HYDRA_ACP_DAEMON_HOST:n.daemonHost,HYDRA_ACP_DAEMON_PORT:String(n.daemonPort),HYDRA_ACP_TOKEN:d,HYDRA_ACP_WS_URL:n.daemonWsUrl,HYDRA_ACP_HOME:n.hydraHome,[this.adapter.nameEnvVar]:r.name,...r.env},[u,...l]=o;if(u===void 0){a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} has empty command
207
+ `),a.end();return}let y=ie(u),h=[...l,...r.args].map(ie),f;try{let g=jt(y,h);f=ky(g.command,g.args,{env:c,stdio:["ignore","pipe","pipe"],detached:!1,shell:g.shell,windowsHide:!0})}catch(g){a.write(`[hydra-acp] failed to spawn ${r.name}: ${g.message}
208
+ `),a.end(),this.scheduleRestart(e,t);return}let k=g=>{try{a.write(typeof g=="string"?g:g.toString())}catch{}};if(f.stdout?.on("data",k),f.stderr?.on("data",k),typeof f.pid=="number")try{ur.writeFileSync(this.adapter.paths.pidFile(r.name),`${f.pid}
209
+ `,{encoding:"utf8",mode:384})}catch(g){a.write(`[hydra-acp] failed to write pid file for ${r.name}: ${g.message}
210
+ `)}e.child=f,e.logStream=a,e.pid=typeof f.pid=="number"?f.pid:void 0,e.startedAt=Date.now(),e.lastExitCode=void 0,f.on("error",g=>{a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} error: ${g.message}
211
+ `)}),f.on("exit",(g,p)=>{try{ur.unlinkSync(this.adapter.paths.pidFile(r.name))}catch{}a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} exited code=${g??"null"} signal=${p??"null"}
212
+ `),e.child=void 0,e.pid=void 0,e.lastExitCode=typeof g=="number"?g:void 0,e.processToken&&(this.tokenRegistry?.revoke(r.name),e.processToken=void 0);let w=e.exitWaiters.splice(0);for(let v of w)v();if(this.stopping||e.manuallyStopped){try{a.end()}catch{}e.logStream=void 0;return}e.restartCount+=1;let m=e.breaker.recordExit(g,r.name,this.adapter.kind);if(typeof m=="object"){e.failureReason=m.tripped,a.write(`[hydra-acp] ${this.adapter.kind} ${r.name} circuit breaker tripped: ${m.tripped}
213
+ `);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 vi(s){try{return process.kill(s,0),!0}catch{return!1}}function Xn(s,e){return s.code=e,s}Q();var Iy={kind:"extension",nameEnvVar:"HYDRA_ACP_EXTENSION_NAME",tokenRole:"extension",paths:{dir:E.extensionsDir,logFile:E.extensionLogFile,pidFile:E.extensionPidFile}},fr=class extends ln{constructor(e,t,n={}){super(e,Iy,t,n)}};Q();var Ay={kind:"transformer",nameEnvVar:"HYDRA_ACP_TRANSFORMER_NAME",tokenRole:"transformer",paths:{dir:E.transformersDir,logFile:E.transformerLogFile,pidFile:E.transformerPidFile}},pr=class extends ln{connected=new Map;constructor(e,t,n={}){super(e,Ay,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 gr=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{}}};Q();Q();import*as Zn from"fs/promises";async function lu(s){let e=E.pidFile(),t=`${e}.${process.pid}.tmp`;await Zn.writeFile(t,JSON.stringify(s)+`
214
+ `,{encoding:"utf8",mode:384}),await Zn.rename(t,e)}Q();import*as ts from"fs/promises";import*as mr from"path";var es=s=>{process.stderr.write(s+`
215
+ `)};function bi(s){es=s??(e=>process.stderr.write(e+`
216
+ `))}async function fu(s,e){let t=Ue();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=mr.join(E.agentsDir(),t),a;try{a=await ts.readdir(i,{withFileTypes:!0})}catch(d){let c=d;if(c.code==="ENOENT")return;es(`hydra-acp: prune: failed to read ${i}: ${c.message}`);return}for(let d of a){if(!d.isDirectory())continue;let c=d.name,u=r.get(c);if(u===void 0)continue;let l=o.get(c)??new Set,y=mr.join(i,c),h;try{h=await ts.readdir(y,{withFileTypes:!0})}catch(f){es(`hydra-acp: prune: failed to read ${y}: ${f.message}`);continue}for(let f of h){if(!f.isDirectory())continue;let k=f.name;if(k===u||l.has(k)||k.includes(".partial-"))continue;let g=mr.join(y,k);try{await ts.rm(g,{recursive:!0,force:!0}),es(`hydra-acp: pruned stale ${c} ${k} (${g})`)}catch(p){es(`hydra-acp: prune: failed to remove ${g}: ${p.message}`)}}}}function pu(s){let e,t=!1,n=0,r=(a,d)=>{s.logger&&s.logger[a](`agent-sync: ${d}`)},o=async()=>{let a=[];try{let u=await s.registry.load();for(let l of u.agents)await po(l)==="yes"&&a.push(l.id)}catch(u){return r("warn",`registry load failed: ${u.message}`),s.intervalMs}if(a.length===0)return s.intervalMs;let d=n%a.length;n=(n+1)%a.length;let c=a[d];try{let{synced:u,skipped:l}=await s.manager.syncFromAgent(c);r("info",`${c}: synced ${u.length}, skipped ${l}`)}catch(u){r("warn",`${c}: ${u.message}`)}return Math.max(1,Math.floor(s.intervalMs/a.length))},i=a=>{t||(e=setTimeout(()=>{o().then(d=>{i(d)}).catch(d=>{r("warn",`tick crashed: ${d.message}`),i(s.intervalMs)})},a),e.unref())};return i(s.intervalMs),()=>{t=!0,e&&(clearTimeout(e),e=void 0)}}async function Si(s){let e=s.maxDeletions??200,t=(h,f)=>{s.logger&&s.logger[h](`session-gc: ${f}`)},n=Date.now(),r=s.maxAgeMs>0?n-s.maxAgeMs:Number.POSITIVE_INFINITY,o=await s.manager.list({includeNonInteractive:!0}).catch(h=>(t("warn",`manager.list failed: ${h.message}`),[])),i=[];for(let h of o){if(h.status!=="cold")continue;if((s.selection??"explicit")==="explicit"){if(h.interactive!==!1)continue}else if(h.interactive===!0)continue;let k=Date.parse(h.updatedAt);Number.isFinite(k)&&(s.maxAgeMs>0&&k>r||i.push({sessionId:h.sessionId,lastUsedMs:k}))}if(i.length===0)return s.verbose&&t("info","no candidates"),{considered:0,deleted:0,failed:0,deferred:0};i.sort((h,f)=>h.lastUsedMs-f.lastUsedMs);let a=i.slice(0,e),d=a[0]?.lastUsedMs,c=0,u=0;for(let{sessionId:h}of a)try{await s.manager.deleteRecord(h,"expired")&&(c+=1)}catch(f){u+=1,t("warn",`delete ${h} failed: ${f.message}`)}let l=i.length-a.length;if(s.verbose||c>0||u>0){let h=(s.selection??"explicit")==="unpromoted"?"unpromoted":"non-interactive";t("info",`swept ${c} ${h} session(s) older than ${Cy(s.maxAgeMs)}`+(u>0?`; ${u} failed`:"")+(l>0?`; ${l} deferred to next sweep`:""))}let y={considered:i.length,deleted:c,failed:u,deferred:l};return d!==void 0&&(y.oldestLastUsedMs=d),y}function gu(s){let e,t=!1,n=!1,r=o=>{t||(e=setTimeout(()=>{(async()=>{if(!n){n=!0;try{await Si({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 Cy(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 Ry}from"crypto";function ns(s){if(Array.isArray(s))return s.map(ns);if(s!==null&&typeof s=="object"){let e={};for(let t of Object.keys(s).sort())e[t]=ns(s[t]);return e}return s}function mu(s){let e={};for(let[n,r]of Object.entries(s)){let o=qr(n);if(o.nested){let i={};for(let[a,d]of Object.entries(r??{}))zr(a).reload==="restart"&&(i[a]=d);Object.keys(i).length>0&&(e[n]=i);continue}o.reload==="restart"&&(e[n]=r)}let t=JSON.stringify(ns(e));return Ry("sha256").update(t).digest("hex").slice(0,16)}function hu(s,e){let t=[],n=(r,o)=>JSON.stringify(ns(r))!==JSON.stringify(ns(o));for(let r of Object.keys(e)){let o=qr(r),i=e[r],a=s[r];if(o.nested){for(let d of Object.keys(i??{})){if(zr(d).reload!=="warn")continue;let c=i[d],u=(a??{})[d];n(u,c)&&t.push(`${r}.${d}`)}continue}o.reload==="warn"&&n(a,i)&&t.push(r)}return t}import*as wu from"fs/promises";Q();var xy=3e3;async function yu(){try{return(await wu.stat(E.config())).mtimeMs}catch{return}}function ku(s){let e=s.intervalMs??xy,t=!1,n,r,o=yu().then(d=>{r=d}),i=async()=>{await o;let d=await yu();if(d===r)return;r=d;let c;try{c=await An()}catch(l){s.logger?.warn(`config-reload: config.json changed but did not parse (${l.message}); keeping the loaded config`);return}try{s.apply(c)}catch(l){s.logger?.warn(`config-reload: applying live config failed: ${l.message}`)}let u=hu(s.bootConfig,c);s.onDrift?.(u),s.logger?.info(u.length>0?`config-reload: applied live config; restart-only keys differing from boot: ${u.join(", ")}`:"config-reload: applied live config")},a=()=>{t||(n=setTimeout(()=>{i().finally(a)},e),n.unref?.())};return a(),()=>{t=!0,n&&clearTimeout(n)}}Q();He();import*as Su from"path";import{createHash as Ty,randomBytes as Ey,timingSafeEqual as Py}from"crypto";var Iu="hydra_session_",My=3600*24*30,vu=12,_y=32,$y=50;function Fy(){return Su.join(E.home(),"session-tokens.json")}function bu(s){return Ty("sha256").update(s).digest("hex")}function Au(s){return Ey(s).toString("hex")}function Oy(){return Au(vu).slice(0,vu*2)}function Ny(){return`${Iu}${Au(_y)}`}var hr=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=Fy(),n=await ce(t);n&&Array.isArray(n.records)&&(e=n.records.filter(Dy));let r=new s(e,t);return r.sweepExpired(new Date)>0&&await r.flush(),r}async issue(e={}){let t=Ny(),n=bu(t),r=Oy(),o=new Date,i=e.ttlSec&&e.ttlSec>0?e.ttlSec:My,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(Iu))return;let t=bu(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||!Py(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(()=>{})},$y))}persist(){let e=(this.writeInflight??Promise.resolve()).catch(()=>{}).then(()=>me(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 Dy(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 Cu="Bearer ",yr=class{constructor(e){this.token=e}token;async validate(e){return Hy(e,this.token)?"service":void 0}rotate(e){this.token=e}},wr=class{constructor(e){this.store=e}store;async validate(e){return this.store.verify(e)}},kr=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 Ru(s){return async function(t,n){let r=t.headers.authorization;if(!r||!r.startsWith(Cu)){n.code(401).send({error:"Missing bearer token"});return}let o=r.slice(Cu.length).trim(),i=await s.validator.validate(o);if(!i){n.code(403).send({error:"Invalid token"});return}t.authIdentity=i}}function xu(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 vr=class{tokens=new Map;mint(e,t){let n=Br();return this.tokens.set(n,{name:e,kind:t}),n}revoke(e){for(let[t,n]of this.tokens)n.name===e&&this.tokens.delete(t)}resolve(e){return this.tokens.get(e)}async validate(e){let t=this.tokens.get(e);if(t)return`${t.kind}:${t.name}`}},Ly=new Set(["GET /v1/sessions","GET /v1/sessions/:id","GET /v1/config","GET /v1/system"]);function Tu(s,e){return e?Ly.has(`${s} ${e}`):!1}function Hy(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 br=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 pn from"fs";import*as Ku from"os";import*as rs from"path";import*as xi from"readline";import*as Qu from"zlib";Q();function Ii(s){return Math.floor(s/4)}function Eu(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+=_t(i.content);break;case"tool_call":case"tool_call_update":{let a=typeof i.toolCallId=="string"?i.toolCallId:"",d=jy(i),c=t.get(a)??0;d>c&&t.set(a,d);break}default:break}}for(let n of t.values())e+=n;return e}function jy(s){let e=0;return typeof s.title=="string"&&(e+=s.title.length),e+=Sr(s.rawInput),e+=_t(s.content),e+=Sr(s.rawOutput),e}function Sr(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+=Sr(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+=Sr(n);return t}return 0}function _t(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+=_t(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?_t(e.text):e.type==="diff"?_t(e.oldText)+_t(e.newText):e.content!==void 0?_t(e.content):0}function Pu(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=Ii(s.unsummarizedChars),o=s.currentModel!==void 0?s.config.modelContextWindows[s.currentModel]??s.config.absoluteFallback:s.config.absoluteFallback;e=r/o,t=!1}if(t&&e>=s.config.hardCeilingFraction)return!0;let n=s.nowMs-s.lastActivityMs;return e>=s.config.contextFraction&&n>=s.config.idleBeforePromptMs}function Mu(s){let e=new Map,t=new Map,n=new Map;for(let o of s){let a=o.params?.update;if(!a||typeof a!="object")continue;let d=a.sessionUpdate;if(d!=="tool_call"&&d!=="tool_call_update")continue;let c=typeof a.toolCallId=="string"&&a.toolCallId.length>0?a.toolCallId:void 0,u=By(a);if(u.length===0)continue;let l=u;if(c!==void 0){let y=e.get(c)??[],h=[];for(let f of u){let k=y.find(g=>g.path===f.path&&g.oldText===f.oldText&&g.newText===f.newText);if(k===void 0)h.push(f);else if(k.scope===void 0&&f.scope!==void 0){k.scope=f.scope;let g=t.get(k);g&&(g.scope=f.scope)}}if(h.length===0)continue;e.set(c,[...y,...h]),l=h}for(let y of l)t.set(y,Uy(n,y))}let r=[];for(let[o,i]of n)r.push({path:o,hunks:i.hunks,created:i.created});return r}function _u(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,...r.scope!==void 0&&r.scope===t.scope?{scope:r.scope}:{}})}return e}function Uy(s,e){let t={oldText:e.oldText,newText:e.newText,...e.scope!==void 0?{scope:e.scope}:{}},n=s.get(e.path);return n===void 0?(s.set(e.path,{hunks:[t],created:e.oldText.length===0}),t):(n.hunks.push(t),t)}function By(s){let e=[];for(let t of Es(s))t.path!==void 0&&e.push({path:t.path,...gd(t),...t.scope!==void 0?{scope:t.scope}:{}});return e}function Fu(s,e={}){let t=qy(s),{events:n,window:r}=Wy(t,e),o=zy(n),i=[];Jy(i,s),r&&(r.from>1||r.to<r.total)&&(i.push(`_Showing turns ${r.from}-${r.to} of ${r.total}._`),i.push("")),Vy(i,n,o,{includeTools:e.includeTools??!1,includeThoughts:e.includeThoughts??!1});let a=i.join(`
206
217
  `);return a.endsWith(`
207
218
  `)||(a+=`
208
- `),a}function ui(s,e){let t=s<0?e+s+1:s;return t<1?1:t>e?e:t}function yy(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:h}of s)h.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=ui(o-e.last+1,o):(e.from!==void 0&&(i=ui(e.from,o)),e.to!==void 0&&(a=ui(e.to,o))),i>a)return{events:[],window:{from:i,to:a,total:o}};let d=e.sinceMs,c=new Set;d!==void 0&&s.forEach((h,f)=>{h.recordedAt>=d&&c.add(n[f])});let u=[],l,w;return s.forEach((h,f)=>{let k=n[f];k<i||k>a||d!==void 0&&!c.has(k)||(u.push(h),l??=k,w=k)}),{events:u,window:{from:l??i,to:w??a,total:o}}}function wy(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=nd(n.update,{cwd:s.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function ky(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 vy(s,e){let t=e.session,n=tt(t.sessionId),r=t.title?.trim()||`Hydra session ${n}`;s.push(`# ${Yn(r)}`),s.push("");let o=[];o.push(`- **Session:** \`${n}\` (lineage \`${t.lineageId}\`)`);let i=[t.agentId];t.currentModel&&i.push(`model: ${t.currentModel}`),t.currentMode&&i.push(`mode: ${t.currentMode}`),o.push(`- **Agent:** ${i.filter(Boolean).join(" \xB7 ")}`),o.push(`- **Cwd:** ${t.cwd}`),o.push(`- **Exported:** ${e.exportedAt} from ${e.exportedFrom.machine} (hydra ${e.exportedFrom.hydraVersion})`);let a=t.currentUsage;if(a&&(a.used!==void 0||a.costAmount!==void 0||a.cumulativeCost!==void 0)){let d=[];if(a.used!==void 0){let u=a.size!==void 0?`${li(a.size)}`:void 0;d.push(u?`${li(a.used)} / ${u} tokens`:`${li(a.used)} tokens`)}let c=Yo(a);if(c!==void 0){let u=a.costCurrency??"USD";d.push(`$${c.toFixed(2)} ${u}`)}o.push(`- **Usage:** ${d.join(" \xB7 ")}`)}s.push(o.join(`
209
- `)),s.push("")}function by(s,e,t,n){let{includeTools:r,includeThoughts:o}=n;if(!e.some(k=>Sy(k.event,o))){s.push("_No conversation history recorded._"),s.push("");return}let i=0,a="",d="",c=[],u=new Set,l=!1,w=()=>{if(c.length!==0){for(let k of c)s.push(k);s.push(""),c=[]}},h=()=>{w(),d.length>0&&(fu(s,d.trimEnd(),"*"),s.push(""),d=""),a.length!==0&&(s.push(a.trimEnd()),s.push(""),a="")},f=()=>{l||(l=!0)};for(let{event:k}of e)switch(k.kind){case"user-text":{h(),s.push("---"),s.push(""),i+=1,fu(s,k.text,"**"),s.push(""),l=!0;break}case"agent-text":f(),a+=k.text;break;case"agent-thought":{if(!o)break;f(),a.length>0&&(s.push(a.trimEnd()),s.push(""),a=""),d+=k.text;break}case"tool-call":{if(!r||(f(),(a.length>0||d.length>0)&&h(),u.has(k.toolCallId)))break;u.add(k.toolCallId);let p=t.get(k.toolCallId)??{title:k.title,status:k.status??"pending"};c.push(`- ${Ay(p.status)} ${Iy(p)}`);break}case"tool-call-update":break;case"plan":{f(),h(),s.push("**Plan:**"),s.push("");for(let p of k.entries){let g=p.status==="completed"?"[x]":"[ ]";s.push(`- ${g} ${Yn(p.content)}`)}s.push("");break}case"mode-changed":f(),h(),s.push(`_mode: ${Yn(k.mode)}_`),s.push("");break;case"model-changed":f(),h(),s.push(`_model: ${Yn(k.model)}_`),s.push("");break;case"turn-complete":h();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}h()}function Sy(s,e){switch(s.kind){case"agent-thought":return e;case"usage-update":case"available-commands":case"session-info":case"unknown":case"turn-complete":return!1;default:return!0}}function Iy(s){let e=s.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${Yn(s.title)}${t}`}function Ay(s){switch(s){case"completed":return"\u221A";case"failed":return"\xD7";case"cancelled":case"rejected":return"\xF7";case"in_progress":return"\u25B8";default:return"\xB7"}}var gu=String.raw`<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s[^<>]*)?\/?>`,Cy=new RegExp(gu);function fu(s,e,t){if(Cy.test(e)){Ry(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(`
210
- `);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 Ry(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(`
211
- `))s.push(o);s.push(r)}function Yn(s){return s.replace(new RegExp(gu,"g"),e=>e.replace(/</g,"&lt;").replace(/>/g,"&gt;"))}function li(s){return s.toLocaleString("en-US")}function Ae(s){return s==="127.0.0.1"||s==="::1"||s==="localhost"||s==="[::1]"}function xy(s){let e=s.trim();if(e.length===0)return{operator:"OR",terms:[]};let t=/\w+:"[^"]*"|"[^"]*"|\S+/g,n=[],r;for(;(r=t.exec(e))!==null;)n.push(r[0]);let o="OR",i=!1,a=!1,d=[];for(let u of n){let l=u.toUpperCase();l==="AND"?i=!0:l==="OR"?a=!0:d.push(u)}i?o="AND":a&&(o="OR");let c=d.map(u=>Ty(u)).filter(u=>u.term.length>0);return{operator:o,terms:c}}function Ty(s){let e=/^(\w+):"([^"]*)"$/.exec(s);if(e)return{scope:mu(e[1]),term:e[2]};let t=/^"([^"]*)"$/.exec(s);if(t)return{scope:"all",term:t[1]};let n=/^(prompt|response|tool|edit|edited):([\s\S]*)$/i.exec(s);return n?{scope:mu(n[1]),term:n[2].trim()}:{scope:"all",term:s.trim()}}function mu(s){switch(s.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";case"edit":case"edited":return"edit";default:return"all"}}function Ey(s,e){return e==="edit"?s==="edit":s==="edit"?!1:s==="all"?!0:s==="user"?e==="user":s==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var Py=5,My=200,pr=72,_y=24,$y=512;function vu(s){return Number.isFinite(s)?Math.max(_y,Math.min($y,Math.floor(s))):pr}async function bu(s,e,t={}){let n=xy(e);if(n.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??Py,o=t.maxSessions??My,i=vu(t.snippetWidth??pr),a=t.sessionIds?new Set(t.sessionIds):null,d=await s.list(),c=a?d.filter(w=>a.has(w.sessionId)):d,u=[],l=!1;for(let w of c){if(u.length>=o){l=!0;break}let h=await s.loadHistory(w.sessionId,{tools:"references"}).catch(()=>[]),f=Fy(h,n,r,i,Oy(w));if(f.snippets.length===0)continue;let k={sessionId:w.sessionId,cwd:w.cwd,status:w.status,updatedAt:w.updatedAt,totalMatches:f.totalMatches,snippets:f.snippets};w.title!==void 0&&(k.title=w.title),u.push(k)}return{query:e,truncated:l,results:u}}function Oy(s){let e=s.workspace?.sourceCwd;if(e===void 0||e.length===0||s.cwd.length===0)return;let t=s.cwd.endsWith("/")?s.cwd:s.cwd+"/";return n=>n.startsWith(t)?e.replace(/\/+$/,"")+"/"+n.slice(t.length):n}function Fy(s,e,t,n=pr,r){if(e.terms.length===0)return{totalMatches:0,snippets:[]};let o=0,i=[],a=Math.max(1,Math.floor(t/e.terms.length)),d=[];for(let{scope:c,term:u}of e.terms){let l=Ny(s,u,c,t,n,r);if(e.operator==="AND"&&l.totalMatches===0)return{totalMatches:0,snippets:[]};o+=l.totalMatches,i.push(...l.snippets.slice(0,a)),d.push(...l.snippets.slice(a))}for(let c of d){if(i.length>=t)break;i.push(c)}return{totalMatches:o,snippets:i.slice(0,t)}}function Ny(s,e,t,n,r,o){let i=e.toLowerCase(),a=0,d=[],c=new Set;for(let u of s){let l=Dy(u).filter(w=>Ey(t,w.kind));for(let w of l){let h=w.text.toLowerCase();if(w.kind==="edit"){let p=o?.(w.text);if(!(hu(w.text,e)||(p!==void 0&&p!==w.text?hu(p,e):!1))||c.has(w.text))continue;if(c.add(w.text),a+=1,d.length<n){let y={kind:"edit",text:w.text,recordedAt:u.recordedAt};w.toolName!==void 0&&(y.toolName=w.toolName),d.push(y)}continue}let f=h.indexOf(i);if(f===-1)continue;let k=0;for(;f!==-1;)k++,f=h.indexOf(i,f+i.length);if(a+=k,d.length<n){let p=h.indexOf(i),g={kind:w.kind,text:Wy(w.text,p,i.length,r),recordedAt:u.recordedAt};w.toolName!==void 0&&(g.toolName=w.toolName),d.push(g)}}}return{totalMatches:a,snippets:d}}function Dy(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=fr(n.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof n.text=="string"?be(n.text):fr(n.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if(Ly(n))return[];let o=fr(n.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=By(n.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return Hy(n);default:return[]}}function Hy(s){let e=wu(s,"name"),t=wu(s,"title"),n=[];if(t!==void 0){let a=ae(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=ae(e);a.length>0&&n.push({kind:"tool",toolName:e,text:a})}let r=s.rawInput;if(r&&typeof r=="object"){let a=ku(r);if(a.length>0){let d={kind:"tool-input",text:ae(a)};e!==void 0&&(d.toolName=e),n.push(d)}}for(let a of Ya(s)){let d={kind:"edit",text:a};e!==void 0&&(d.toolName=e),n.push(d)}let o=s.locations;if(Array.isArray(o)&&o.length>0){let a=ku(o);if(a.length>0){let d={kind:"tool-input",text:ae(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let i=jy(s);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),n.push(a)}return n}function hu(s,e){let t=yu(s.toLowerCase()),n=yu(e.toLowerCase());if(n.length===0)return!1;if(n.startsWith("/"))return t===n||t.startsWith(n+"/");let r="/"+n,o=t.indexOf(r);for(;o!==-1;){let i=o+r.length;if(i===t.length||t[i]==="/")return!0;o=t.indexOf(r,o+1)}return t===n||t.startsWith(n+"/")}function yu(s){return s.length>1&&s.endsWith("/")?s.slice(0,-1):s}function jy(s){if(!Uy(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=ae(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=ae(n);if(r.length>0)return r}}return null}function Uy(s){return s==="failed"||s==="rejected"||s==="cancelled"}function Ly(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 fr(s){if(typeof s=="string")return be(s);if(!s||typeof s!="object"||Array.isArray(s))return"";let e=s;return typeof e.text=="string"?be(e.text):""}function By(s){if(!Array.isArray(s))return"";let e=[];for(let t of s){let n=fr(t);n.length>0&&e.push(n)}return e.join("")}function wu(s,e){let t=s[e];return typeof t=="string"?t:void 0}function ku(s){try{return JSON.stringify(s)}catch{return""}}function Wy(s,e,t,n=pr){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=vu(n),c=Math.max(0,d-i.length),u=Math.floor(c/2),l=Math.min(u,a),w=Math.min(c-l,r.length-(a+i.length)),h=Math.max(0,a-(c-w)),f=Math.min(r.length,a+i.length+w),k=h>0?"\u2026":"",p=f<r.length?"\u2026":"";return`${k}${r.slice(h,f)}${p}`}import{randomBytes as Iu}from"crypto";function Su(s){let e=Iu(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 fi(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(Su({name:"hydra-acp-stdin",session:n,tokenRegistry:e,getOrigin:t})),r.push(Su({name:"hydra-acp-recall",session:n,tokenRegistry:e,getOrigin:t}));let o=an(s.deps);return o!==void 0&&(o.bindToSession(n),r=[...r,...o.descriptors]),r}}function an(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=Iu(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 qy=new Set(["/v1/sessions/:id/history","/v1/sessions/:id/events"]);function Au(s,e){let t=e.fetchImpl??fetch;s.addHook("preHandler",async(n,r)=>{let o=n.routeOptions.url;if(!o||!o.startsWith("/v1/sessions/:id"))return;let i=n.params,a=i.id;if(typeof a!="string")return;let d=pt(a);if(!d){if(!e.localMiss||await e.localMiss.resolvesLocally(a))return;let g=e.localMiss.cache.findByLocalId(a);if(g.length===0)return;if(g.length>1){r.code(404).send({error:`Session "${a}" exists on more than one remote (${g.map(y=>y.name).join(", ")}). Address it as "<remote>:${a}".`});return}d=g[0]}let c=e.store.get(d.name);if(!c){r.code(404).send({error:`No remote named "${d.name}". Run \`hydra remote add\` first.`});return}let u=n.query;if(qy.has(o)&&Jy(u?.follow)){let g=c.port===Ot?"":`:${c.port}`;r.code(501).send({error:`Streaming a federated session isn't supported yet. Attach directly with hydra://${c.host}${g}/${d.localId} instead.`});return}let l=Vy(o,i,d.localId,n.url),h=`${Ae(c.host)?"http":"https"}://${c.host}:${c.port}${l}`,f;try{f=await t(h,{method:n.method,headers:{Authorization:`Bearer ${c.token}`,...n.body!==void 0?{"Content-Type":"application/json"}:{}},...n.body!==void 0&&n.method!=="GET"?{body:JSON.stringify(n.body)}:{}})}catch(g){r.code(502).send({error:`Could not reach remote "${d.name}" (${c.host}:${c.port}): ${g.message}`});return}if(n.method==="DELETE"&&o==="/v1/sessions/:id"&&(f.ok||f.status===404)&&e.localMiss?.cache.evict(d.name,d.localId),f.status===204){r.code(204).send();return}let k=await f.text(),p=f.headers.get("content-type");p&&r.header("content-type",p),r.code(f.status).send(k)})}var zy=5e3,gr=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;perPeer=new Map;timer;start(){this.timer||(this.refreshNow(),this.timer=setInterval(()=>{this.refreshNow()},this.opts.intervalMs??zy),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}async refreshNow(){let e=this.opts.fetchImpl??fetch,t=new Set(this.store.list().map(n=>n.name));for(let n of[...this.perPeer.keys()])t.has(n)||this.perPeer.delete(n);await Promise.allSettled(this.store.list().map(async n=>{let r=this.store.get(n.name);if(!r)return;let o=this.perPeer.get(n.name),i=Ae(r.host)?"http":"https",a=new URLSearchParams({includeNonInteractive:"1"}),d=o?.cursor!==void 0;d&&a.set("since",String(o.cursor));let c=`${i}://${r.host}:${r.port}/v1/sessions?${a.toString()}`,u;try{u=await e(c,{headers:{Authorization:`Bearer ${r.token}`}})}catch{return}if(!u.ok)return;let l=await u.json(),w=o?.sessions??new Map;if(d){for(let[h,f]of[...w])f.status!=="cold"&&w.delete(h);for(let h of l.removed??[])w.delete(ze({name:n.name,localId:h}))}else w.clear();for(let h of l.sessions??[]){let f=ze({name:n.name,localId:String(h.sessionId)});w.set(f,{...h,sessionId:f,remote:n.name})}this.perPeer.set(n.name,{cursor:l.cursor,sessions:w})}))}list(e){let t=[];for(let n of this.perPeer.values())t.push(...n.sessions.values());return t.filter(n=>!(e.status&&n.status!==e.status||!e.includeNonInteractive&&n.interactive!==!0))}evict(e,t){this.perPeer.get(e)?.sessions.delete(ze({name:e,localId:t}))}findByLocalId(e){let t=e.startsWith(ye)?[e]:[e,ye+e],n=[];for(let[r,o]of this.perPeer)for(let i of t)if(o.sessions.has(ze({name:r,localId:i}))){n.push({name:r,localId:i});break}return n}};async function Cu(s,e,t,n=fetch){let r=s.get(e);if(!r)return{status:404,body:{error:`No remote named "${e}". Run \`hydra remote add\` first.`}};let i=`${Ae(r.host)?"http":"https"}://${r.host}:${r.port}/v1/sessions`,a;try{a=await n(i,{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(l){return{status:502,body:{error:`Could not reach remote "${e}" (${r.host}:${r.port}): ${l.message}`}}}let d=await a.text(),c=null;try{c=d.length>0?JSON.parse(d):null}catch{c=null}if(!a.ok)return{status:a.status,body:c};let u=c;return u&&typeof u.sessionId=="string"?{status:a.status,body:{...u,sessionId:ze({name:e,localId:u.sessionId})}}:{status:a.status,body:c}}async function Ru(s,e,t=fetch){let n;if(e.sessionIds===void 0)n=s.list().map(a=>({name:a.name}));else{let a=new Map;for(let d of e.sessionIds){let c=pt(d);if(!c)continue;let u=a.get(c.name)??[];u.push(c.localId),a.set(c.name,u)}n=[...a.entries()].map(([d,c])=>({name:d,sessionIds:c}))}if(n.length===0)return{query:e.q,truncated:!1,results:[]};let r=await Promise.all(n.map(async a=>{let d=s.get(a.name);if(!d)return null;let u=`${Ae(d.host)?"http":"https"}://${d.host}:${d.port}/v1/sessions/search`,l;try{l=await t(u,{method:"POST",headers:{Authorization:`Bearer ${d.token}`,"Content-Type":"application/json"},body:JSON.stringify({q:e.q,...a.sessionIds?{sessionIds:a.sessionIds}:{},...e.snippetWidth!==void 0?{snippetWidth:e.snippetWidth}:{}})})}catch{return null}if(!l.ok)return null;let w;try{w=await l.json()}catch{return null}let h=w;if(!h||!Array.isArray(h.results))return null;let f=h.results.map(k=>({...k,sessionId:ze({name:a.name,localId:k.sessionId})}));return{query:e.q,truncated:h.truncated===!0,results:f}})),o=[],i=!1;for(let a of r)a!==null&&(o.push(...a.results),i=i||a.truncated);return{query:e.q,truncated:i,results:o}}function Jy(s){return s==="1"||s==="true"||s===!0}function Vy(s,e,t,n){let r=s.replace(/:([A-Za-z_]+)/g,(i,a)=>encodeURIComponent(a==="id"?t:e[a]??"")),o=n.indexOf("?");return o===-1?r:r+n.slice(o)}var mr=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function xu(s){if(s.publicHost&&s.publicHost.length>0)return s.publicHost;if(s.host&&!Ae(s.host))return s.port!==void 0?`${s.host}:${s.port}`:s.host}function Pu(s,e,t,n={},r,o){s.get("/v1/sessions",async(h,f)=>{let k=h.query,p=k?.includeNonInteractive==="1"||k?.includeNonInteractive==="true",g;if(k?.since!==void 0&&(g=Number(k.since),!Number.isFinite(g)||g<0))return f.code(400).send({error:`since must be a non-negative number, got ${JSON.stringify(k.since)}`});let y=k?.status==="warm"||k?.status==="cold"?k.status:void 0,m={cwd:k?.cwd,includeNonInteractive:p,...y?{status:y}:{}},v=o&&!m.cwd?o.list({includeNonInteractive:p,...y?{status:y}:{}}):[];if(g!==void 0){let b=await e.listSince(m,g);return{sessions:[...b.entries,...v],removed:b.removed,cursor:b.cursor}}let S=await e.listing(m);return{sessions:[...S.entries,...v],removed:[],cursor:S.cursor}}),s.get("/v1/sessions/:id",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=await e.getOne(p);return g||(f.code(404).send({error:"session not found"}),f)}),s.post("/v1/sessions/search",async(h,f)=>{let k=h.body??{},p=typeof k.q=="string"?k.q:"";if(p.trim().length===0)return f.code(400).send({error:"q is required"}),f;let g=Array.isArray(k.sessionIds)?k.sessionIds.filter(S=>typeof S=="string"&&S.length>0):void 0,y={sessionIds:g};typeof k.snippetWidth=="number"&&(y.snippetWidth=k.snippetWidth);let m=await bu(e,p,y);if(!r)return m;let v=await Ru(r,{q:p,...g?{sessionIds:g}:{},...y.snippetWidth!==void 0?{snippetWidth:y.snippetWidth}:{}});return{query:p,truncated:m.truncated||v.truncated,results:[...m.results,...v.results]}}),s.post("/v1/sessions",async(h,f)=>{let k=h.body??{};if(k.remote){if(!r)return f.code(404).send({error:`No remote named "${k.remote}". Run \`hydra remote add\` first.`});let S=await Cu(r,k.remote,{cwd:k.cwd,agentId:k.agentId,mcpServers:k.mcpServers,workspace:k.workspace});return f.code(S.status).send(S.body)}let p=ie(k.cwd??t.cwd),g=await yn(p),y=k.agentId??g.agentId??t.agentId,m=an(n),v=m!==void 0?[...k.mcpServers??[],...m.descriptors]:k.mcpServers;try{let S=await e.create({cwd:p,agentId:y,mcpServers:v,...k.workspace!==void 0?{workspace:k.workspace}:{}});m!==void 0&&m.bindToSession(S),f.code(201).send({sessionId:S.sessionId,agentId:S.agentId,cwd:S.cwd,...S.workspace!==void 0?{workspace:S.workspace}:{},...S.workspaceError!==void 0?{workspaceError:S.workspaceError}:{}})}catch(S){m!==void 0&&m.abandon(S instanceof Error?S:void 0),f.code(500).send({error:S.message})}}),s.post("/v1/sessions/collect",async(h,f)=>{let k=h.body??{},p=typeof k.maxAgeDays=="number"&&k.maxAgeDays>0?k.maxAgeDays*24*60*60*1e3:0,g=typeof k.limit=="number"&&k.limit>0?k.limit:1e3,y=k.selection==="explicit"||k.selection==="unpromoted"?k.selection:"unpromoted";try{let m=await di({manager:e,maxAgeMs:p,maxDeletions:g,selection:y,verbose:!1});f.code(200).send(m)}catch(m){f.code(500).send({error:m.message})}}),s.get("/v1/sessions/tombstones",async(h,f)=>{let k=h.query;if(k.since!==void 0&&Number.isNaN(Date.parse(k.since))){f.code(400).send({error:"since must be an ISO timestamp"});return}let p=await e.listTombstones({...k.agent?{agentId:k.agent}:{},...k.since?{since:k.since}:{},...k.grep?{grep:k.grep}:{}});f.code(200).send({tombstones:p})}),s.post("/v1/sessions/undelete",async(h,f)=>{let k=h.body??{};if(!Array.isArray(k.ids)||k.ids.length===0||!k.ids.every(p=>typeof p=="string"&&p.length>0)){f.code(400).send({error:"ids must be a non-empty array of strings"});return}try{f.code(200).send(await e.undeleteSessions(k.ids))}catch(p){f.code(500).send({error:p.message})}}),s.post("/v1/sessions/:id/kill",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=e.get(p);if(g){g.close({deleteRecord:!1,by:"REST POST /kill"}).catch(()=>{}),f.code(202).send();return}if(!await e.hasRecord(p)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.post("/v1/sessions/:id/stdin/open",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=e.get(p);if(!g)return f.code(404).send({error:"session not found"}),f;let y=h.body??{},m={};(y.mode==="memory"||y.mode==="file")&&(m.mode=y.mode),typeof y.capacityBytes=="number"&&(m.capacityBytes=y.capacityBytes),typeof y.fileCapBytes=="number"&&(m.fileCapBytes=y.fileCapBytes),(m.mode??"memory")==="file"&&(m.filePathFor=v=>Xn.join(Tu.tmpdir(),`hydra-acp-stdin-${v}.log`));try{return g.openStream(m)}catch(v){return f.code(409).send({error:v.message}),f}}),s.post("/v1/sessions/:id/stdin",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=e.get(p);if(!g)return f.code(404).send({error:"session not found"}),f;let y=h.body??{},m=typeof y.chunk=="string"?y.chunk:"",v=y.eof===!0;try{return g.streamWrite(m,v)}catch(S){return f.code(409).send({error:S.message}),f}}),s.patch("/v1/sessions/:id",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=h.body??{};if(g.cwd!==void 0){if(typeof g.cwd!="string"||!Xn.isAbsolute(g.cwd)){f.code(400).send({error:"cwd must be an absolute path"});return}let m=await e.setCwd(p,g.cwd);if(m==="missing"){f.code(404).send({error:"session not found"});return}if(m==="not-a-directory"){f.code(400).send({error:`${g.cwd} is not a directory`});return}if(m==="live"){f.code(409).send({error:"session is live; its agent was spawned in its cwd and cannot change directory. Moving a live session is a swap \u2014 use `workspace start` in it."});return}if(m==="bound"){f.code(409).send({error:"session is isolated, so its cwd IS its workspace. Clear the binding first (PATCH { workspace: null }) or leave the workspace from inside the session."});return}f.code(204).send();return}if("workspace"in g){if(g.workspace!==null){f.code(400).send({error:"workspace may only be set to null (clear the binding)"});return}let m=await e.clearWorkspaceBinding(p);if(m==="missing"){f.code(404).send({error:"session not found"});return}if(m==="live"){f.code(409).send({error:"session is live; its cwd is the workspace. Use `workspace stop` or `workspace detach` in the session so the agent moves with the binding."});return}f.code(204).send();return}if(g.priority!==void 0){let m=g.priority,v;if(m===null||m===0)v=void 0;else if(typeof m=="number"&&Number.isInteger(m)&&m>0)v=m;else{f.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(p,v)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(g.read!==void 0){if(typeof g.read!="boolean"){f.code(400).send({error:"read must be a boolean"});return}if(!await e.setRead(p,g.read)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(g.regen===!0){if(!(e.get(p)!==void 0||await e.hasRecord(p))){f.code(404).send({error:"session not found"});return}e.scheduleSynopsis(p),f.code(202).send();return}if(typeof g.title!="string"||g.title.trim().length===0){f.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(p,g.title)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.delete("/v1/sessions/:id",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=e.get(p);if(g){await g.close({deleteRecord:!0,by:"REST DELETE /v1/sessions"}),await e.waitForDeletion(p),await e.hasRecord(p)&&await e.deleteRecord(p),f.code(204).send();return}if(!await e.deleteRecord(p)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.get("/v1/sessions/:id/export",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=h.query?.tools,y=g==="references"?"references":Ac(g),m=await e.exportBundle(p,y==="references"?{tools:"references"}:{});if(!m){f.code(404).send({error:"session not found"});return}let v=jn({record:m.record,history:y==="summary"?Cc(m.history,"summary"):m.history,promptHistory:m.promptHistory.length>0?m.promptHistory:void 0,...m.toolBlobs!==void 0?{toolBlobs:m.toolBlobs}:{},hydraVersion:ue,machine:St(),hydraHost:xu(t)}),S=new Date().toISOString().replace(/[:.]/g,"-");f.header("Content-Disposition",`attachment; filename="${p}-${S}.hydra"`),f.code(200).send(v)}),s.get("/v1/sessions/:id/diff",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=await e.exportBundle(p,{includeArchivedHistory:!0});if(!g){f.code(404).send({error:"session not found"});return}let y=h.query??{},m=y.fold==="true"||y.fold==="1",v=typeof y.paths=="string"&&y.paths.length>0?new Set(y.paths.split(",").map(b=>b.trim()).filter(b=>b.length>0)):void 0,S=uu(g.history);v&&(S=S.filter(b=>v.has(b.path))),m&&(S=S.map(b=>({...b,hunks:lu(b.hunks)}))),f.code(200).send(S)}),s.get("/v1/sessions/:id/tools/:hash",async(h,f)=>{let k=h.params,p=await e.resolveCanonicalId(k.id)??k.id,g=await e.loadToolBlob(p,k.hash);if(g===null){f.code(404).send({error:"tool blob not found"});return}f.header("Content-Type","text/plain; charset=utf-8"),f.code(200).send(g)}),s.get("/v1/sessions/:id/transcript",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=await e.exportBundle(p);if(!g){f.code(404).send({error:"session not found"});return}let y=jn({record:g.record,history:g.history,promptHistory:g.promptHistory.length>0?g.promptHistory:void 0,hydraVersion:ue,machine:St(),hydraHost:xu(t)}),m=h.query,v=I=>I==="1"||I==="true"||I==="yes",S=I=>{let A=m?.[I];if(A===void 0||A==="")return;let T=Number(A);return Number.isFinite(T)?T:"bad"},b={};for(let I of["from","to","last","since"]){let A=S(I);if(A==="bad"){f.code(400).send({error:`${I} must be a number`});return}A!==void 0&&(b[I==="since"?"sinceMs":I]=A)}f.header("Content-Type","text/markdown; charset=utf-8"),f.code(200).send(pu(y,{includeTools:v(m?.tools),includeThoughts:v(m?.thoughts),...b}))});let i=h=>async(f,k)=>{let p=f.params.id,g=await e.resolveCanonicalId(p)??p,y=f.body??{},m={};if(y.forkAt!==void 0){if(typeof y.forkAt!="string"||y.forkAt.length===0){k.code(400).send({error:"forkAt must be a non-empty string"});return}m.forkAt=y.forkAt}if(y.cwd!==void 0){if(typeof y.cwd!="string"||y.cwd.length===0){k.code(400).send({error:"cwd must be a non-empty string"});return}m.cwd=ie(y.cwd)}if(y.agentId!==void 0){if(typeof y.agentId!="string"||y.agentId.length===0){k.code(400).send({error:"agentId must be a non-empty string"});return}m.agentId=y.agentId}if(y.title!==void 0){if(typeof y.title!="string"){k.code(400).send({error:"title must be a string"});return}m.title=y.title}if(h){let v=y.selection;if(v!==void 0){if(typeof v.text!="string"||v.text.length===0){k.code(400).send({error:"selection.text must be a non-empty string"});return}m.side={selection:{text:v.text,...typeof v.responsePartId=="string"?{responsePartId:v.responsePartId}:{}}}}else m.side={}}if(y.mode!==void 0&&!h){if(y.mode!=="verbatim"&&y.mode!=="synthesis"){k.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}m.mode=y.mode}if(y.model!==void 0){if(typeof y.model!="string"||y.model.length===0){k.code(400).send({error:"model must be a non-empty string"});return}m.model=y.model}try{let v=await e.forkSession(g,m);k.code(201).send(v)}catch(v){let S=v;if(S.code===x.SessionNotFound){k.code(404).send({error:S.message});return}if(S.code===x.InvalidParams||S.code===x.AgentNotInstalled){k.code(400).send({error:S.message});return}k.code(500).send({error:S.message})}};s.post("/v1/sessions/:id/fork",i(!1)),s.post("/v1/sessions/:id/side",i(!0)),s.post("/v1/sessions/:id/rewind",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=(h.body??{}).keepThrough;if(g!==null&&(typeof g!="string"||g.length===0)){f.code(400).send({error:"keepThrough must be a non-empty messageId, or null to drop every turn"});return}try{f.code(200).send(await e.rewindSession(p,g))}catch(y){let m=y;if(m.code===x.SessionNotFound){f.code(404).send({error:m.message});return}if(m.code===x.InvalidParams){f.code(400).send({error:m.message});return}if(m.code===x.InvalidRequest){f.code(409).send({error:m.message});return}f.code(500).send({error:m.message})}}),s.post("/v1/sessions/import",async(h,f)=>{let k=h.body??{};if(k.bundle===void 0){f.code(400).send({error:"missing bundle"});return}let p;if(k.cwd!==void 0){if(typeof k.cwd!="string"||k.cwd.length===0){f.code(400).send({error:"cwd must be a non-empty string"});return}p=k.cwd}let g;try{g=$c(k.bundle)}catch(y){f.code(400).send({error:"invalid bundle",details:y.message});return}try{let y=await e.importBundle(g,{replace:k.replace===!0,...p!==void 0?{cwd:p}:{}});f.code(201).send(y)}catch(y){let m=y;if(m.code===x.BundleAlreadyImported){f.code(409).send({error:"bundle already imported",existingSessionId:m.existingSessionId});return}f.code(500).send({error:m.message})}}),s.get("/v1/sessions/:id/compact/status",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=e.get(p),y;if(g?y=g.summarizedThroughEntry:y=await e.getSummarizedThroughEntry(p),y===void 0&&!await e.hasRecord(p))return f.code(404).send({error:"session not found"}),f;let m=await e.getCompactionState(p),v=await e.getRollbackBreadcrumb(p),S=await e.getPendingAgentSwap(p),b=!1,I,A=g?.currentUsage,T=typeof A?.used=="number"&&typeof A?.size=="number"&&A.size>0?{used:A.used,size:A.size}:void 0,R=await e.loadHistory(p,{tools:"references",maxEntries:1/0}).catch(()=>[]);if(R.length>0&&t.compaction){let P=y??0,$=R.length,H=P<=R.length?P:0,J=R.slice(H),z=du(J);I=ci(z);let L=g?.currentModel,U=R.at(-1).recordedAt;b=cu({summarizedThroughEntry:P,totalEntries:$,unsummarizedChars:z,compactionInFlight:e.getCompactionInFlight(),currentModel:L,lastActivityMs:U,nowMs:Date.now(),config:t.compaction,...typeof A?.used=="number"?{agentReportedUsed:A.used}:{},...typeof A?.size=="number"?{agentReportedSize:A.size}:{}})}return{summarizedThroughEntry:y??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:b,...I!=null?{approxTokens:I}:{},...T!=null?{currentUsage:T}:{},...m!=null?{compactionState:m}:{},...v!=null?{rollbackBreadcrumb:v}:{},...S!=null?{pendingAgentSwap:S}:{}}}),s.post("/v1/sessions/:id/compact",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k;if(e.get(p)){e.scheduleCompaction(p),f.code(202).send({scheduled:!0});return}if(!await e.hasRecord(p)){f.code(404).send({error:"session not found"});return}e.scheduleCompaction(p),f.code(202).send({scheduled:!0})}),s.post("/v1/sessions/:id/compact/rollback",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k;if(!await e.hasRecord(p)){f.code(404).send({error:"session not found"});return}try{await e.performUncompact(p),f.code(202).send({rolledBack:!0})}catch(g){let y=g instanceof Error?g.message:String(g);f.code(409).send({error:y})}}),s.post("/v1/sessions/:id/workspace/clean",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=h.body??{};if(g.deep!==void 0&&typeof g.deep!="boolean"){f.code(400).send({error:"deep must be a boolean"});return}if(!await e.hasRecord(p)){f.code(404).send({error:"session not found"});return}if(e.get(p)===void 0){f.code(409).send({error:"session is not live. Cleaning rewrites the workspace under a running agent, so it is only available inside a live session (`/hydra workspace clean`). For a cold workspace use `hydra workspace remove` instead."});return}try{let y=await e.runWorkspaceAction(p,"clean",void 0,{deep:g.deep===!0});f.code(202).send({report:y})}catch(y){f.code(409).send({error:y instanceof Error?y.message:String(y)})}}),s.get("/v1/sessions/:id/history/page",async(h,f)=>{let k=h.params.id,p=h.query,g=Number(p?.beforeSeq);if(p?.beforeSeq===void 0||p.beforeSeq===""||!Number.isFinite(g)){f.code(400).send({error:"beforeSeq must be a number"});return}let y=p.turns===void 0||p.turns===""?10:Number(p.turns);if(!Number.isInteger(y)||y<1){f.code(400).send({error:"turns must be a positive integer"});return}let m=await e.resolveCanonicalId(k)??k,v=await e.pageHistory(m,{beforeSeq:g,turns:Math.min(y,100)});if(!v){f.code(404).send({error:"session not found"});return}f.code(200).send({entries:v.entries,hasMore:v.hasMore})}),s.get("/v1/sessions/:id/history",async(h,f)=>{let k=h.params.id,p=h.query,g=p?.follow==="1"||p?.follow==="true",y=await e.resolveCanonicalId(k)??k,m=e.get(y),v,S,b=!1,I=1e4,A=[];if(m){g&&(S=m.onBroadcast(R=>{f.raw.writableEnded||(b?f.raw.write(JSON.stringify(R)+`
212
- `):(A.push(R),A.length>I&&A.shift()))})),h.raw.on("close",()=>{S?.(),f.raw.writableEnded||f.raw.end()});try{v=await m.getHistorySnapshot()}catch(R){throw S?.(),R}}else{let R=await e.getHistory(y);if(R===void 0)return f.code(404).send({error:"session not found"}),f;v=R}f.raw.setHeader("Content-Type","application/x-ndjson"),f.raw.setHeader("Cache-Control","no-cache"),f.raw.statusCode=200;let T=new Set;for(let R of v??[]){f.raw.write(JSON.stringify(R)+`
213
- `);let P=R;typeof P.recordedAt=="number"&&T.add(String(P.recordedAt))}for(;A.length>0;){let R=A.splice(0,A.length);for(let P of R){let $=P,H=typeof $.recordedAt=="number"?String($.recordedAt):"";H&&T.has(H)||f.raw.write(JSON.stringify(P)+`
214
- `)}}return b=!0,S||f.raw.end(),f});function a(h,f,k){let p=typeof h=="string"?h.trim():"";if(p.length===0)return null;let g;try{g=JSON.parse(p)}catch{return console.debug("events endpoint: skipping malformed JSONL line"),null}if(!g||typeof g!="object"||Array.isArray(g))return console.debug("events endpoint: skipping non-object JSONL line"),null;let y=g;if(typeof y.recordedAt!="number"||k!==void 0&&y.recordedAt<k||typeof y.params!="object"||y.params===null||Array.isArray(y.params))return null;let m=y.params;if(typeof m.update!="object"||m.update===null||Array.isArray(m.update))return null;let S=m.update.sessionUpdate;return typeof S!="string"||!f.has(S)?null:{recordedAt:y.recordedAt,entry:g}}function d(h,f,k){let g=f.params.update,y={sessionId:h,ts:new Date(f.recordedAt).toISOString(),kind:k,update:g};return g.messageId!==void 0&&g.messageId!==null&&(y.messageId=g.messageId),y}async function*c(h,f,k,p){for await(let g of f){let y=a(g,k,p);if(y){let m=y.entry.params.update.sessionUpdate;yield{ts:y.recordedAt,row:d(h,y.entry,m)}}}}async function u(h,f,k){let p=new Map;try{for(let y of await dn.promises.readdir(E.sessionDir(h))){let m=/^history\.jsonl\.(\d+)(\.gz)?$/.exec(y);if(!m)continue;let v=Number.parseInt(m[1],10);(m[2]!==void 0||!p.has(v))&&p.set(v,Xn.join(E.sessionDir(h),y))}}catch(y){if(y.code!=="ENOENT")throw y}let g=[];for(let y of[...p.keys()].sort((m,v)=>m-v)){let m=p.get(y);if(k!==void 0)try{if((await dn.promises.stat(m)).mtimeMs<k)continue}catch{continue}g.push(m)}return g.push(f),g}async function l(h,f,k,p){let g=await u(h,f,p),y=null,m=!1;async function*v(){for(let T of g){if(m)return;let R=dn.createReadStream(T),P=R;if(T.endsWith(".gz")){let H=Eu.createGunzip();R.on("error",J=>H.destroy(J)),P=R.pipe(H)}let $=pi.createInterface({input:P,crlfDelay:1/0});y=$;try{yield*$}catch(H){if(H.code==="ENOENT")continue;throw H}finally{$.close(),R.destroy()}}}let S={close(){m=!0,y?.close()}},b=c(h,v(),k,p),I=await b.next(),A=I.done?null:I.value;return{sessionId:h,rl:S,gen:b,current:A,exhausted:A===null}}async function w(h){let f=await h.gen.next();f.done?(h.exhausted=!0,h.current=null):h.current=f.value}s.get("/v1/sessions/events",async(h,f)=>{let k=h.query,p=k.kinds;if(!p||p.trim().length===0)return f.code(400).send({error:"kinds parameter is required"}),f;let g=p.split(",").map(I=>I.trim());if(g.length===0)return f.code(400).send({error:"kinds parameter is required"}),f;for(let I of g)if(!mr.has(I))return f.code(400).send({error:`kind "${I}" is not queryable; allowed kinds: ${[...mr].join(", ")}`}),f;let y=new Set(g),m;if(k.since!==void 0&&k.since.trim().length>0){let I=new Date(k.since);if(isNaN(I.getTime()))return f.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),f;m=I.getTime()}let v=await e.list({includeNonInteractive:!0}),S=m!==void 0?v.filter(I=>new Date(I.updatedAt).getTime()>=m):v;f.raw.setHeader("content-type","application/x-ndjson"),f.raw.statusCode=200;let b=[];for(let I of S)try{let A=E.historyFile(I.sessionId),T=await l(I.sessionId,A,y,m);T.exhausted||b.push(T)}catch(A){if(A.code==="ENOENT")continue;throw A}h.raw.on("close",()=>{for(let I of b)try{I.rl.close()}catch{}f.raw.writableEnded||f.raw.end()});try{for(;b.length>0;){let I=-1,A=1/0;for(let R=0;R<b.length;R++){let P=b[R];P.current!==null&&P.current.ts<A&&(A=P.current.ts,I=R)}if(I===-1)break;let T=b[I];if(f.raw.write(JSON.stringify(T.current.row)+`
215
- `),await w(T),T.exhausted){try{T.rl.close()}catch{}b.splice(I,1)}}}catch(I){for(let A of b)try{A.rl.close()}catch{}throw I}return f.raw.end(),f}),s.get("/v1/sessions/:id/events",async(h,f)=>{let k=h.params.id,p=h.query,g=await e.resolveCanonicalId(k)??k;if(!e.get(g)&&!await e.hasRecord(g))return f.code(404).send({error:"session not found"}),f;let m=p.kinds;if(!m||m.trim().length===0)return f.code(400).send({error:"kinds parameter is required"}),f;let v=m.split(",").map(R=>R.trim());if(v.length===0)return f.code(400).send({error:"kinds parameter is required"}),f;for(let R of v)if(!mr.has(R))return f.code(400).send({error:`kind "${R}" is not queryable; allowed kinds: ${[...mr].join(", ")}`}),f;let S=new Set(v),b;if(p.since!==void 0&&p.since.trim().length>0){let R=new Date(p.since);if(isNaN(R.getTime()))return f.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),f;b=R.getTime()}let I=E.historyFile(g),A=dn.createReadStream(I),T=pi.createInterface({input:A,crlfDelay:1/0});f.raw.setHeader("content-type","application/x-ndjson"),f.raw.statusCode=200;try{for await(let R of T){let P=typeof R=="string"?R.trim():"";if(P.length===0)continue;let $;try{$=JSON.parse(P)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",I);continue}if(!$||typeof $!="object"||Array.isArray($)){console.debug("events endpoint: skipping non-object JSONL line in %s",I);continue}let H=$;if(typeof H.recordedAt!="number"||typeof H.params!="object"||H.params===null||Array.isArray(H.params))continue;let J=H.params;if(typeof J.update!="object"||J.update===null||Array.isArray(J.update))continue;let z=J.update,L=z.sessionUpdate;if(typeof L!="string"||!S.has(L)||b!==void 0&&H.recordedAt<b)continue;let U={ts:new Date(H.recordedAt).toISOString(),kind:L,update:z};z.messageId!==void 0&&z.messageId!==null&&(U.messageId=z.messageId),f.raw.write(JSON.stringify(U)+`
216
- `)}}catch(R){if(R.code==="ENOENT")return f.raw.end(),f;throw R}return f.raw.end(),f}),s.post("/v1/sessions/:id/prompt/:messageId/notify",async(h,f)=>{let k=h.params,p=k.id,g=await e.resolveCanonicalId(p)??p,y=k.messageId,m=h.body,v=typeof m?.callbackUrl=="string"?m.callbackUrl:"",S=typeof m?.secret=="string"?m.secret:"";if(!y||!v||!S){f.code(400).send({error:"messageId, callbackUrl, and secret are all required"});return}let b;try{b=new URL(v)}catch{f.code(400).send({error:"callbackUrl must be a valid absolute URL"});return}if(b.protocol!=="https:"&&b.protocol!=="http:"){f.code(400).send({error:"callbackUrl must be http or https"});return}let I=e.get(g);if(!I){f.code(404).send({error:"session not found or not warm"});return}let A=I.registerTurnNotify(y,v,S);if(A.alreadyTerminal){f.code(200).send({status:"already_terminal",stopReason:A.stopReason});return}f.code(202).send({status:"registered"})}),s.get("/v1/sessions/:id/attention",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,g=e.get(p);return!g&&!await e.hasRecord(p)?(f.code(404).send({error:"session not found"}),f):g?{flags:g.listAttentionFlags()}:{flags:(await e.store.read(p))?.attentionFlags??[]}}),s.get("/v1/sessions/attention",async(h,f)=>{let k=h.query;if(!k.source||k.source.trim().length===0)return f.code(400).send({error:"source query parameter is required"}),f;let p=await e.list({includeNonInteractive:!0}),g=[];for(let y of p){let m=e.get(y.sessionId),v;m?v=m.listAttentionFlags():v=(await e.store.read(y.sessionId))?.attentionFlags??[];for(let S of v)S.source===k.source&&g.push({...S,sessionId:y.sessionId})}return{flags:g}}),s.post("/v1/sessions/:id/attention/clear",async(h,f)=>{let k=h.params.id,p=await e.resolveCanonicalId(k)??k,y=h.body??{},m=typeof y.source=="string"?y.source:"",v=typeof y.reason=="string"?y.reason:"";if((m.length>0||v.length>0)&&!(m.length>0&&v.length>0)){f.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}m.length===0&&v.length;let S=e.get(p);if(S){if(m.length>0&&v.length>0)S.clearAttentionFlag(m,v);else{let R=Array.from(S.listAttentionFlags()).map(P=>`${P.source}::${P.reason}`);for(let P of R)S.clearAttentionFlag(P.split("::")[0],P.split("::").slice(1).join("::"))}f.code(204).send();return}if(!await e.hasRecord(p)){f.code(404).send({error:"session not found"});return}let b=e.store,I=await b.read(p);if(!I){f.code(404).send({error:"session not found"});return}let A=I.attentionFlags??[],T;if(m.length>0&&v.length>0){let R=`${m}::${v}`;T=A.filter(P=>`${P.source}::${P.reason}`!==R)}else T=[];if(T.length===A.length&&T.every((R,P)=>R.source===A[P].source&&R.reason===A[P].reason)){f.code(204).send();return}await b.write({...I,attentionFlags:T}),f.code(204).send()})}function Mu(s,e,t,n={}){s.get("/v1/agents",async()=>jt(e)),s.get("/v1/registry",async()=>e.load()),s.post("/v1/registry/refresh",async()=>{let r=await e.refresh();return{version:r.version,agentCount:r.agents.length}}),s.post("/v1/agents/:id/install",async(r,o)=>{let i=r.params.id,a=await e.getAgent(i);if(!a){o.code(404).send({error:`agent ${i} not found in registry`});return}if(a.distribution.uvx&&!a.distribution.npx&&!a.distribution.binary){o.send({agentId:a.id,version:a.version??"current",distribution:"uvx",installed:!1,message:"uvx agents resolve on first run; nothing to pre-install."});return}try{let d=await Me(a,[],{npmRegistry:n.npmRegistry}),c=a.distribution.npx?"npx":a.distribution.binary?"binary":"unknown";o.send({agentId:a.id,version:d.version,distribution:c,installed:!0,command:d.command})}catch(d){o.code(500).send({error:d.message})}}),s.post("/v1/agents/:id/sync",async(r,o)=>{let i=r.params.id;try{let{synced:a,skipped:d}=await t.syncFromAgent(i);return{synced:a.map(c=>({sessionId:c.sessionId,upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,cwd:c.cwd,title:c.title,updatedAt:c.updatedAt})),skipped:d}}catch(a){let d=a;if(d.code===x.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}Q();function _u(s,e,t,n=()=>[]){s.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t,home:E.home(),driftedKeys:n()}))}import*as Nu from"os";Q();He();var Zn=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,hr=class s{data;constructor(e){this.data=e}static async load(){let e=await ce(E.peers());return new s(Gy(e))}get(e){return this.data.entries[e]}async set(e){this.data.entries[e.name]=e,await $u(this.data)}async delete(e){return e in this.data.entries?(delete this.data.entries[e],await $u(this.data),!0):!1}list(){return Object.values(this.data.entries).map(({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})=>({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})).sort((e,t)=>e.addedAt.localeCompare(t.addedAt))}};function Gy(s){if(!s||typeof s!="object")return{version:1,entries:{}};let e=s,t=e.entries&&typeof e.entries=="object"?e.entries:{},n={};for(let[r,o]of Object.entries(t)){if(!o||typeof o!="object")continue;let i=o;if(typeof i.name!="string"||typeof i.host!="string"||typeof i.port!="number"||typeof i.token!="string"||typeof i.expiresAt!="string"||typeof i.addedAt!="string")continue;let a={name:i.name,host:i.host,port:i.port,token:i.token,expiresAt:i.expiresAt,addedAt:i.addedAt};typeof i.label=="string"&&(a.label=i.label),typeof i.pinnedFingerprint=="string"&&(a.pinnedFingerprint=i.pinnedFingerprint),typeof i.pinnedAt=="string"&&(a.pinnedAt=i.pinnedAt),n[r]=a}return{version:1,entries:n}}async function $u(s){await me(E.peers(),s,{mode:384})}var Ky=3600*24*365,Ke=class extends Error{status;constructor(e,t){super(e),this.name="PeerLoginError",this.status=t}};function yr(s,e){return`${Ae(s)?"http":"https"}://${s}:${e}`}async function Ou(s){let e=s.fetchImpl??fetch,t=`${s.host}:${s.port}`,n=yr(s.host,s.port),r;try{r=await e(`${n}/v1/auth/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:s.password,label:s.label,ttlSec:s.ttlSec??Ky})})}catch(i){throw new Ke(`Could not reach ${t}: ${i.message}`,502)}if(r.status===401)throw new Ke(`Wrong password for ${t}.`,401);if(r.status===403)throw new Ke(`No password is configured on ${t}. Run \`hydra-acp auth password\` on that daemon first.`,502);if(r.status===429)throw new Ke(`Too many failed login attempts on ${t}; try again later.`,429);if(!r.ok)throw new Ke(`Login to ${t} failed: HTTP ${r.status}`,502);let o=await r.json();if(!o.session_token||!o.expires_at)throw new Ke(`Login to ${t} returned a malformed response.`,502);return{token:o.session_token,expiresAt:o.expires_at}}async function gi(s){let e=s.fetchImpl??fetch,t=yr(s.host,s.port);try{await e(`${t}/v1/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json"},body:JSON.stringify({})})}catch{}}function Du(s){return{machine:St(),hydraVersion:ue,startedAt:s,os:{platform:process.platform,release:Nu.release(),arch:process.arch},node:process.version}}async function wr(s){let e=s.fetchImpl??fetch,t;try{t=await e(`${yr(s.host,s.port)}/v1/system`,{headers:{Authorization:`Bearer ${s.token}`},signal:s.signal})}catch(n){return{kind:"error",message:n.message}}if(t.status===401||t.status===403)return{kind:"unauthorized"};if(t.status===404)return{kind:"unsupported"};if(!t.ok)return{kind:"error",message:`HTTP ${t.status}`};try{let n=await t.json();return typeof n?.machine=="string"?{kind:"ok",system:n}:{kind:"ok"}}catch{return{kind:"ok"}}}function Fu(s){return s!==void 0&&s.length<=64&&Zn.test(s)}function Hu(s,e){if(Fu(s))return s;if(/^[\d.]+$/.test(e)||e.includes(":"))return;let t=e.split(".")[0];return Fu(t)?t:void 0}function ju(s,e,t){s.get("/v1/system",async()=>Du(e)),s.post("/v1/daemon/shutdown",async(n,r)=>n.authIdentity!=="service"?r.code(403).send({error:"only the service token may stop the daemon"}):t===void 0?r.code(501).send({error:"this daemon cannot shut itself down"}):(r.code(202).send({status:"shutting-down"}),setTimeout(t,50),r))}var Qy=/^[A-Za-z0-9._-]+$/;function kr(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=Yy(a);if("error"in d){i.code(400).send({error:d.error});return}try{let c=t.register(d.config);i.code(201).send(c)}catch(c){es(i,c)}}),s.delete(`${r}/:name`,async(o,i)=>{let a=o.params.name;try{await t.unregister(a),i.code(204).send()}catch(d){es(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){es(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){es(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){es(i,d)}})}function es(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 Yy(s){let e=s.name;if(typeof e!="string"||!Qy.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 Uu(s,e){kr(s,"extension",e)}function Lu(s,e){kr(s,"transformer",e)}function Bu(s,e){s.get("/v1/config",async()=>e())}import{z as yt}from"zod";Q();import*as cn from"fs/promises";import*as Wu from"path";import{randomBytes as IR,scrypt as Xy,timingSafeEqual as Zy}from"crypto";import{promisify as ew}from"util";var tw=ew(Xy);function qu(){return Wu.join(E.home(),"password-hash")}var nw=128*1024*1024;async function zu(){try{return(await cn.readFile(qu(),"utf8")).trim().length>0}catch(s){if(s.code==="ENOENT")return!1;throw s}}async function Ju(s){if(typeof s!="string"||s.length===0)return!1;let e;try{e=(await cn.readFile(qu(),"utf8")).trim()}catch(c){if(c.code==="ENOENT")return!1;throw c}let t=e.split("$");if(t.length!==6||t[0]!=="scrypt")return!1;let n=parseInt(t[1],10),r=parseInt(t[2],10),o=parseInt(t[3],10);if(!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o))return!1;let i=Buffer.from(t[4],"hex"),a=Buffer.from(t[5],"hex");if(i.length===0||a.length===0)return!1;let d=await tw(s,i,a.length,{N:n,r,p:o,maxmem:nw});return d.length!==a.length?!1:Zy(d,a)}var sw=yt.object({password:yt.string().min(1),label:yt.string().min(1).max(256).optional(),ttlSec:yt.number().int().positive().optional()}),rw=yt.object({id:yt.string().optional()}).optional(),ow=yt.object({token:yt.string().min(32)});function Vu(s,e){s.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,n)=>{let r=iw(t);if(e.rateLimiter.isBlocked(r))return n.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=sw.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}if(!await zu())return n.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await Ju(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=rw.parse(t.body??void 0)}catch{return n.code(400).send({error:"Invalid request body"})}let o=r?.id??t.authIdentity;if(!o||o==="service")return n.code(200).send({revoked:!1});let i=await e.store.revoke(o);return n.code(200).send({revoked:i})}),s.get("/v1/auth/verify",async(t,n)=>n.code(200).send({ok:!0})),s.get("/v1/auth/sessions",async(t,n)=>n.code(200).send({sessions:e.store.list()})),s.delete("/v1/auth/sessions",async(t,n)=>{let r=await e.store.revokeAll();return n.code(200).send({revoked:r})}),s.delete("/v1/auth/sessions/:id",async(t,n)=>{let r=t.params.id;return await e.store.revoke(r)?n.code(204).send():n.code(404).send({error:"Not found"})}),s.post("/v1/auth/rotate-token",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=ow.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}return e.staticTokenValidator.rotate(r.token),n.code(200).send({rotated:!0})})}function iw(s){return s.ip||"unknown"}import{z as wt}from"zod";ns();var ww=wt.object({name:wt.string().min(1).max(64).regex(Zn).optional(),host:wt.string().min(1),port:wt.number().int().positive().optional(),password:wt.string().min(1),label:wt.string().min(1).max(256).optional(),ttlSec:wt.number().int().positive().optional(),pinnedFingerprint:wt.string().min(1).optional()});function nl(s,e){s.post("/v1/remotes",async(t,n)=>{let r;try{r=ww.parse(t.body)}catch{return n.code(400).send({error:`Invalid request body (name must match ${Zn} and the rest is a normal login request)`})}let o=r.port??Ot;r.pinnedFingerprint&&ts(r.host,o,r.pinnedFingerprint);let i;try{i=await Ou({host:r.host,port:o,password:r.password,label:r.label,ttlSec:r.ttlSec})}catch(w){if(w instanceof Ke)return n.code(w.status).send({error:w.message});throw w}let a=await wr({host:r.host,port:o,token:i.token}),d=a.kind==="ok"?a.system:void 0,c=r.name;if(c===void 0){c=Hu(d?.machine,r.host);let w=c!==void 0?e.store.get(c):void 0,h=w!==void 0&&(w.host!==r.host||w.port!==o);if(c===void 0||h){await gi({host:r.host,port:o,token:i.token});let f=c===void 0?`Couldn't derive a remote name for ${r.host}`:`A remote named ${c} already points at ${w.host}:${w.port}`;return n.code(c===void 0?400:409).send({error:`${f}. Pass a name: hydra-acp remote add <name> ${r.host}`})}}let u=new Date().toISOString(),l={name:c,host:r.host,port:o,token:i.token,expiresAt:i.expiresAt,addedAt:u,...r.label!==void 0?{label:r.label}:{},...r.pinnedFingerprint!==void 0?{pinnedFingerprint:r.pinnedFingerprint,pinnedAt:u}:{}};return await e.store.set(l),e.health?.markOk(l.name,d),n.code(201).send({name:l.name,host:l.host,port:l.port,expiresAt:l.expiresAt,label:l.label,addedAt:l.addedAt,pinnedFingerprint:l.pinnedFingerprint,status:e.health?.get(l.name)?.status??"unknown"})}),s.get("/v1/remotes",async(t,n)=>{let r=e.store.list().map(o=>{let i=e.health?.get(o.name);return{...o,status:i?.status??"unknown",...i?.checkedAt?{lastCheckedAt:i.checkedAt}:{},...i?.system?{system:i.system}:{}}});return n.code(200).send({remotes:r})}),s.get("/v1/remotes/:name/agents",async(t,n)=>{let r=e.store.get(t.params.name);if(!r)return n.code(404).send({error:"Not found"});let i=`${Ae(r.host)?"http":"https"}://${r.host}:${r.port}`,a={Authorization:`Bearer ${r.token}`};try{let[d,c]=await Promise.all([fetch(`${i}/v1/agents`,{headers:a}),fetch(`${i}/v1/config`,{headers:a}).catch(()=>null)]);if(!d.ok)return n.code(d.status).header("content-type","application/json").send(await d.text());let u=await d.json(),l={};if(c?.ok){let w=await c.json();l={defaultAgent:w.defaultAgent,sessionDefaults:w.sessionDefaults}}return n.code(200).send({...u,...l})}catch(d){return n.code(502).send({error:`Could not reach remote "${r.name}": ${d.message}`})}}),s.delete("/v1/remotes/:name",async(t,n)=>{let r=t.params.name,o=e.store.get(r);return o?(await gi({host:o.host,port:o.port,token:o.token}),await e.store.delete(r),e.health?.forget(r),e.store.list().some(a=>a.host===o.host&&a.port===o.port)||hi(o.host,o.port),n.code(204).send()):n.code(404).send({error:"Not found"})})}function br(s){let e=[],t=[],n=!1,r=o=>{if(!n){n=!0;for(let i of t)i(o)}};return s.on("message",(o,i)=>{if(i)return;let a=o.toString("utf8");try{let d=JSON.parse(a);for(let c of e)c(d)}catch(d){for(let c of e)c({jsonrpc:"2.0",id:null,error:{code:x.ParseError,message:`Failed to parse WS frame: ${d.message}`}})}}),s.on("close",()=>r()),s.on("error",o=>r(o)),{async send(o){if(n)throw new Error("ws is closed");let i=JSON.stringify(o);await new Promise((a,d)=>{s.send(i,c=>{if(c){d(c);return}a()})})},onMessage(o){e.push(o)},onClose(o){t.push(o)},async close(){n||(await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,clearTimeout(d),o())},d=setTimeout(a,5e3);s.once("close",a);try{s.close()}catch{a()}}),r())}}}ns();import{WebSocket as kw}from"ws";var vw=1e4,bi=class extends Error{url;elapsedMs;constructor(e,t){super(`hydra-acp: websocket connect to ${e} timed out after ${t}ms`),this.name="WsConnectTimeoutError",this.url=e,this.elapsedMs=t}};async function sl(s,e,t=vw){let n={};try{let r=new URL(s);if(r.protocol==="wss:"){let o=vi(r.hostname);o.rejectUnauthorized!==void 0&&(n.rejectUnauthorized=o.rejectUnauthorized),o.autoSelectFamily!==void 0&&(n.autoSelectFamily=o.autoSelectFamily),o.checkServerIdentity!==void 0&&(n.checkServerIdentity=o.checkServerIdentity)}}catch{}return new Promise((r,o)=>{let i=new kw(s,e,n),a=Date.now(),d=setTimeout(()=>{i.off("open",c),i.off("error",u),i.on("error",()=>{});try{i.terminate()}catch{}o(new bi(s,Date.now()-a))},t),c=()=>{clearTimeout(d),i.off("error",u),r(i)},u=l=>{clearTimeout(d),i.off("open",c),o(l)};i.once("open",c),i.once("error",u)})}var bw=new Set(["session/attach","session/detach","session/prompt","session/cancel","session/close","session/delete","hydra-acp/session/delete","session/set_model","session/set_mode","session/set_config_option","_session/steering","hydra-acp/prompt/cancel","hydra-acp/prompt/update","hydra-acp/prompt/amend","hydra-acp/session/tool_content","hydra-acp/session/force_cancel"]);function Sw(s){return bw.has(s)}function ol(s,e,t,n){let r=[],o=a=>{for(let d of r)d(a)},i=(a,d)=>{e.handleLocalMessage(a,d,{connection:t.connection,clientId:n}).then(c=>c?s.send(c):void 0).catch(()=>{})};return s.onMessage(a=>{if("method"in a&&Sw(a.method)){let d=a.params,c=typeof d?.sessionId=="string"?d.sessionId:void 0;if(c){if(pt(c)){i(a,c);return}if(a.method==="session/attach"){let u="id"in a;e.resolveLocalMiss(c).then(l=>{if(l.ok){i(a,l.foreignId);return}if(l.ambiguous&&u){s.send(ss(a.id,x.SessionNotFound,`Session "${c}" exists on more than one remote (${l.ambiguous.join(", ")}). Address it as "<remote>:${c}".`));return}o(a)});return}}}o(a)}),{send:a=>s.send(a),onMessage:a=>r.push(a),onClose:a=>s.onClose(a),close:()=>s.close()}}var Sr=class{constructor(e,t=Aw,n){this.store=e;this.dial=t;this.localMiss=n}store;dial;localMiss;attachments=new Map;async resolveLocalMiss(e){if(!this.localMiss)return{ok:!1};if(await this.localMiss.resolvesLocally(e))return{ok:!1};let t=this.localMiss.cache.findByLocalId(e);return t.length===0?{ok:!1}:t.length>1?{ok:!1,ambiguous:t.map(n=>n.name)}:{ok:!0,foreignId:ze(t[0])}}async handleLocalMessage(e,t,n){let r="id"in e,o=r?e.id:void 0,i=pt(t);if(!i)return r?ss(o,x.SessionNotFound,`not a federated session id: ${t}`):void 0;let a=rl(n.clientId,t),d={...e.params,sessionId:i.localId};if(e.method==="session/attach"){let u=this.store.get(i.name);if(!u)return r?ss(o,x.SessionNotFound,`No remote named "${i.name}". Run \`hydra remote add\` first.`):void 0;let l=this.attachments.get(a);l&&(this.attachments.delete(a),l.peerConnection.close().catch(()=>{}));let w;try{w=await this.dial(u)}catch(p){return r?ss(o,x.InternalError,`Could not reach remote "${i.name}": ${p.message}`):void 0}let h={peerConnection:w,localId:i.localId,target:n};this.wireAttachment(i.name,h);let f;try{f=await w.request("session/attach",d)}catch(p){return w.close().catch(()=>{}),r?Si(o,p):void 0}this.attachments.set(a,h);let k=f&&typeof f.sessionId=="string"?{...f,sessionId:t}:f;return r?{jsonrpc:"2.0",id:o,result:k}:void 0}let c=this.attachments.get(a);if(!c)return r?ss(o,x.SessionNotFound,`"${t}" is not attached through this daemon.`):void 0;if(e.method==="session/detach"){let u,l;try{u=await c.peerConnection.request("session/detach",d)}catch(w){l=w}return this.attachments.delete(a),c.peerConnection.close().catch(()=>{}),l?r?Si(o,l):void 0:r?{jsonrpc:"2.0",id:o,result:u??{}}:void 0}if(r)try{let u=await c.peerConnection.request(e.method,d);return{jsonrpc:"2.0",id:o,result:u}}catch(u){return Si(o,u)}await c.peerConnection.notify(e.method,d).catch(()=>{})}detachClient(e){for(let[t,n]of[...this.attachments.entries()])n.target.clientId===e&&(this.attachments.delete(t),n.peerConnection.request("session/detach",{sessionId:n.localId}).catch(()=>{}),n.peerConnection.close().catch(()=>{}))}wireAttachment(e,t){let{peerConnection:n,localId:r,target:o}=t,i=ze({name:e,localId:r}),a=()=>{this.attachments.delete(rl(o.clientId,i))};n.onAnyNotification((d,c)=>{let u=d;!u||u.sessionId!==r||(c==="hydra-acp/session/closed"&&a(),o.connection.notify(c,{...u,sessionId:i}).catch(()=>{}))}),n.onRequest("hydra-acp/session/request_permission",async d=>{let c=d;if(!c||c.sessionId!==r)throw{code:x.MethodNotFound,message:"unexpected sessionId"};return o.connection.request("hydra-acp/session/request_permission",{...c,sessionId:i})}),n.onClose(()=>{a(),o.connection.notify("hydra-acp/session/closed",{sessionId:i}).catch(()=>{})})}};function rl(s,e){return`${s} ${e}`}function ss(s,e,t){return{jsonrpc:"2.0",id:s,error:{code:e,message:t}}}function Si(s,e){let t=e,n=typeof t?.code=="number"?t.code:x.InternalError,r=typeof t?.message=="string"?t.message:String(e??"forward failed");return{jsonrpc:"2.0",id:s,error:{code:n,message:r,...t?.data!==void 0?{data:t.data}:{}}}}var Iw=1e4;async function Aw(s){let t=`${Ae(s.host)?"ws":"wss"}://${s.host}:${s.port}/acp`,n=await sl(t,["acp.v1",`hydra-acp-token.${s.token}`],Iw);return new We(br(n))}var Cw=3e4,Rw=5e3,Ir=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;snapshots=new Map;timer;start(){this.timer||(this.checkAll(),this.timer=setInterval(()=>{this.checkAll()},this.opts.intervalMs??Cw),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}get(e){return this.snapshots.get(e)}markOk(e,t){this.snapshots.set(e,{status:"ok",checkedAt:new Date().toISOString(),...t?{system:t}:{}})}forget(e){this.snapshots.delete(e)}async checkAll(){let e=this.opts.fetchImpl??fetch;await Promise.allSettled(this.store.list().map(async t=>{let n=this.store.get(t.name);if(!n)return;let r=new AbortController,o=setTimeout(()=>r.abort(),Rw);try{let i=await wr({host:n.host,port:n.port,token:n.token,fetchImpl:e,signal:r.signal});if(i.kind==="ok"){this.snapshots.set(t.name,{status:"ok",checkedAt:new Date().toISOString(),...i.system?{system:i.system}:{}});return}if(i.kind==="unauthorized"){this.snapshots.set(t.name,{status:"unauthorized",checkedAt:new Date().toISOString()});return}if(i.kind==="error")throw new Error(i.message);let d=`${Ae(n.host)?"http":"https"}://${n.host}:${n.port}/v1/auth/verify`,c=await e(d,{headers:{Authorization:`Bearer ${n.token}`},signal:r.signal});this.snapshots.set(t.name,{status:c.ok?"ok":"unauthorized",checkedAt:new Date().toISOString()})}catch(i){this.snapshots.set(t.name,{status:"unreachable",checkedAt:new Date().toISOString(),error:i.message})}finally{clearTimeout(o)}}))}};ns();import{z as il}from"zod";var xw=il.object({sessionLabel:il.string().min(1).max(256)});function al(s,e){s.post("/v1/process-tokens",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=xw.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}let o=e.processRegistry.mint(r.sessionLabel,"script");return n.code(201).send({token:o})}),s.delete("/v1/process-tokens/:sessionLabel",async(t,n)=>t.authIdentity!=="service"?n.code(403).send({error:"Requires the service token"}):(e.processRegistry.revoke(t.params.sessionLabel),n.code(204).send()))}import{nanoid as Ii}from"nanoid";import{randomBytes as fl}from"crypto";import*as pl from"os";import*as gl from"path";var Tw=200;function Ew(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[le];if(!t||typeof t!="object"||Array.isArray(t))return;let n=t.sentBy;if(!n||typeof n!="object"||Array.isArray(n))return;let r=n,o={};if(typeof r.sessionId=="string"&&r.sessionId.length>0&&(o.sessionId=r.sessionId),typeof r.label=="string"&&r.label.length>0&&(o.label=r.label.slice(0,Tw)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function dl(s,e,t){let n=Ew(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 rs=new Map;function cl(s,e){let t=rs.get(s);t||(t=new Set,rs.set(s,t)),t.add(e);let n=!1;return()=>{if(n)return;n=!0;let r=rs.get(s);r&&(r.delete(e),r.size===0&&rs.delete(s))}}function ul(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=rs.get(r);if(o){if(o.has(s))return!0;for(let i of o)n.push(i)}}return!1}function F(s,e,t){let n=new Error(e);return n.code=s,t!==void 0&&(n.data=t),n}function Ow(s){if(!s||typeof s!="object")return 512;let n=s.params?.update;if(!n)return 512;let r=512,o=n.content;if(typeof o=="string")r+=o.length;else if(o&&typeof o=="object"){let a=o;typeof a.text=="string"&&(r+=a.text.length),typeof a.data=="string"&&(r+=a.data.length)}let i=n.toolCall;if(i&&(typeof i.rawInput=="string"?r+=i.rawInput.length:i.rawInput&&typeof i.rawInput=="object"&&(r+=256),typeof i.rawOutput=="string"?r+=i.rawOutput.length:i.rawOutput&&typeof i.rawOutput=="object"&&(r+=256),Array.isArray(i.content)))for(let a of i.content){if(!a||typeof a!="object")continue;let d=a;if(typeof d.text=="string"&&(r+=d.text.length),d.content&&typeof d.content=="object"){let c=d.content;typeof c.text=="string"&&(r+=c.text.length)}}return r}function Ee(s,e,t){let n=s.get(e);if(!n)throw F(x.SessionNotFound,t??`session ${e} not found`);return n}async function Mt(s,e){let t=an(s),n,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&s.mcpTokenRegistry!==void 0&&s.getDaemonOrigin!==void 0&&(n=fl(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=fi({baselineMcpServers:void 0,stdinEnabled:!1,deps:s}),c;try{c=await s.manager.resurrect({...e,mcpServers:a,...d?{mintMcpServersForSwap:d}:{}})}catch(u){throw t!==void 0&&t.abandon(u instanceof Error?u:void 0),r!==void 0&&r.abandon(u instanceof Error?u:void 0),u}if(t!==void 0&&t.bindToSession(c),n!==void 0&&r!==void 0&&s.mcpTokenRegistry!==void 0){let u=n,l=s.mcpTokenRegistry;r.complete(c),c.onClose(()=>{l.unbind(u)})}return qw(c,s),hl(c.sessionId,s),c}function ml(s,e){s.get("/acp",{websocket:!0},async(t,n)=>{let r=iu({headers:n.headers,url:n.url});if(!r||!await e.validator.validate(r)){t.close(4401,"Unauthorized");return}let o=e.processRegistry?.resolve(r),i=`hydra_client_${Ii(12)}`,a=br(t),d={},c=e.foreignSessions?ol(a,e.foreignSessions,d,i):a,u=new We(c);d.connection=u;let l={clientId:i,processIdentity:o,attached:new Map};u.setParamsRewriter(p=>{if(p===null||typeof p!="object")return p;let g=p.sessionId;if(typeof g!="string"||l.attached.has(g))return p;let y=ye+g;return l.attached.has(y)?{...p,sessionId:y}:p}),u.onClose(()=>{for(let p of l.attached.values())e.manager.get(p.sessionId)?.detach(p.clientId);l.attached.clear(),e.foreignSessions?.detachClient(i)});let w=(p,g)=>{if(l.attached.get(p)?.readonly)throw F(x.PermissionDenied,`${g} not permitted on a read-only attachment`)};if(u.onRequest("initialize",async p=>{let g=Sa.parse(p??{});g.clientInfo?.name&&(l.clientInfo={name:g.clientInfo.name,...g.clientInfo.version!==void 0?{version:g.clientInfo.version}:{}});let y=g.clientInfo?.version;return y&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,y):e.onTransformerVersion?.(o.name,y)),Ww()}),o&&e.extensionCommands){let p=e.extensionCommands;u.onRequest("hydra-acp/commands/register",async g=>{let y=g??{},m=Array.isArray(y.commands)?y.commands.map(v=>{if(!v||typeof v!="object")return;let S=v;if(typeof S.verb!="string")return;let b={verb:S.verb};return typeof S.argsHint=="string"&&(b.argsHint=S.argsHint),typeof S.description=="string"&&(b.description=S.description),b}).filter(v=>v!==void 0):[];return p.register(o.name,u,m),{ok:!0,registered:m.length}}),u.onClose(()=>{p.clear(o.name)})}if(o&&e.extensionMcp){let p=e.extensionMcp;u.onRequest("hydra-acp/mcp_tools/register",async y=>{let m=y??{},v=typeof m.instructions=="string"?m.instructions:void 0,S=Array.isArray(m.tools)?m.tools.map(b=>{if(!b||typeof b!="object")return;let I=b;if(typeof I.name!="string"||I.name.length===0||typeof I.description!="string"||I.inputSchema===null||typeof I.inputSchema!="object")return;let A={name:I.name,description:I.description,inputSchema:I.inputSchema};return I.outputSchema!==null&&typeof I.outputSchema=="object"&&(A.outputSchema=I.outputSchema),A}).filter(b=>b!==void 0):[];if(S.length===0)throw new Error("register_mcp_tools requires at least one tool");return p.register(o.name,u,v,S),{ok:!0,registered:S.length}});let g=y=>{let m=y??{};if(typeof m.sessionId!="string"||m.sessionId.length===0)throw F(x.InvalidParams,"sessionId is required");return m.sessionId};if(u.onRequest("hydra-acp/session/extension_state/get",async y=>{let m=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw F(x.InvalidParams,"key is required");if(!e.manager)throw F(x.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(m,o.name,v.key)??null}}),u.onRequest("hydra-acp/session/extension_state/list",async y=>{let m=g(y);if(!e.manager)throw F(x.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(m,o.name)}}),u.onRequest("hydra-acp/session/extension_state/set",async y=>{let m=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw F(x.InvalidParams,"key is required");if(v.value===void 0)throw F(x.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw F(x.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(m,o.name,v.key,v.value)}catch(S){throw F(x.InvalidParams,S.message)}return{ok:!0}}),u.onRequest("hydra-acp/session/extension_state/delete",async y=>{let m=g(y),v=y??{};if(typeof v.key!="string"||v.key.length===0)throw F(x.InvalidParams,"key is required");if(!e.manager)throw F(x.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(m,o.name,v.key),{ok:!0}}),e.extensionMcpControls){let y=e.extensionMcpControls;u.onRequest("hydra-acp/mcp_tools/refresh_session",async m=>{let v=m??{};if(typeof v.sessionId!="string"||v.sessionId.length===0)throw F(x.InvalidParams,"refresh_session requires sessionId");return await y.notifyToolListChanged(v.sessionId,o.name),{ok:!0}})}u.onClose(()=>{p.clear(o.name)})}o?.kind==="transformer"&&(u.onRequest("hydra-acp/transformer/initialize",async p=>{let g=p??{},y=Array.isArray(g.intercepts)?g.intercepts.filter(m=>typeof m=="string"):[];if(e.transformers&&(e.transformers.registerConnection(o.name,u,y),e.manager?.defaultTransformers.includes(o.name))){let m=e.transformers.resolveChain([o.name])[0];if(m)for(let v of e.manager.liveSessions())v.addTransformer(m)}return{ack:!0}}),u.onClose(()=>{e.transformers?.deregisterConnection(o.name)}),u.onRequest("hydra-acp/message/emit",async p=>{let g=p??{},y=typeof g.sessionId=="string"?g.sessionId:void 0,m=typeof g.method=="string"?g.method:void 0,v=g.envelope,S=g.route;if(!y)throw F(-32602,"emit_message requires sessionId");if(!m&&S!=="client_broadcast")throw F(-32602,"emit_message requires method");let b=Ee(e.manager,y),I=typeof g.respondsTo=="string"?g.respondsTo:void 0;if(I)return b.dischargeClaim(I,v),{ok:!0};if(S==="chain")return{ok:!0,response:await b.emitToChain(o.name,m,v)};if(S==="queue"){if(m!=="session/prompt")throw F(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await b.emitToQueue(o.name,v)}}if(S==="daemon")return{ok:!0,response:await b.emitToChain(o.name,m,v)};if(S==="client_broadcast"){if(!v||typeof v!="object")throw F(-32602,"client_broadcast requires an envelope object");return b.broadcastClientUpdate(v),{ok:!0}}throw F(-32602,`unsupported route: ${JSON.stringify(S)}`)}),u.onRequest("hydra-acp/session/request_permission",async p=>{let g=p??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw F(-32602,"hydra-acp/session/request_permission requires sessionId");return Ee(e.manager,y).requestPermissionFromClients(g)}),u.onRequest("hydra-acp/transformer/attach",async p=>jw(p,o.name,e)),u.onRequest("hydra-acp/child_session/spawn",async p=>{let g=p??{},y=typeof g.agentId=="string"?g.agentId:void 0,m=typeof g.cwd=="string"?g.cwd:void 0,v=typeof g.parentSessionId=="string"?g.parentSessionId:void 0,S=at(g._meta??void 0),b=S.title,I=S.model,A=S.workspace;if(!m&&v){let L=e.manager.get(v);L&&(m=L.cwd)}if(!m)throw F(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let T=await yn(m),R=y??T.agentId??e.defaultAgent,P=await e.registry?.getAgent(R),$=Zr(T.configDefaults,P??{id:R})?.value,H=I??$?.model,J=typeof g.interactive=="boolean"?g.interactive:!1,z=await e.manager.create({agentId:R,cwd:m,parentSessionId:v,interactive:J,transformChain:[],title:b,model:H,configDefaults:$,...A!==void 0?{workspace:A}:{}});return{childSessionId:z.sessionId,...z.workspace!==void 0||z.workspaceError!==void 0?{_meta:{[le]:{...z.workspace!==void 0?{workspaceInfo:z.workspace}:{},...z.workspaceError!==void 0?{workspaceError:z.workspaceError}:{}}}}:{}}}));let h=async(p,g)=>{let y=p??{};if(typeof y.sessionId!="string")throw F(x.InvalidParams,"fork_session requires sessionId");let m=typeof y.forkAt=="string"?y.forkAt:void 0,v=typeof y.cwd=="string"?y.cwd:void 0,S=typeof y.agentId=="string"?y.agentId:void 0,b=g?void 0:typeof y.mode=="string"&&(y.mode==="verbatim"||y.mode==="synthesis")?y.mode:void 0,I=typeof y.model=="string"&&y.model.length>0?y.model:void 0,A;if(g){let H=y.selection;if(H!==void 0&&(typeof H.text!="string"||H.text.length===0))throw F(x.InvalidParams,"selection.text must be a non-empty string");A={...H!==void 0?{selection:{text:H.text,...typeof H.responsePartId=="string"?{responsePartId:H.responsePartId}:{}}}:{}}}let T=await e.manager.forkSession(y.sessionId,{...A!==void 0?{side:A}:{},...m!==void 0?{forkAt:m}:{},...v!==void 0?{cwd:v}:{},...S!==void 0?{agentId:S}:{},...b!==void 0?{mode:b}:{},...I!==void 0?{model:I}:{}}),R=e.manager.get(T.sessionId);if(!R){let H=await e.manager.loadFromDisk(T.sessionId);if(!H)throw F(x.InternalError,`fork ${T.sessionId} vanished before it could be attached`);R=await Mt(e,{...H,onInstallProgress:Ar(u)})}un(l,R,R.sessionId);let P=kt(u,R,l),{entries:$}=await R.attach(P,"full");l.attached.set(R.sessionId,{sessionId:R.sessionId,clientId:P.clientId,readonly:!1});for(let H of $){if(u.isClosed())break;await u.notify(H.method,Be(Le(H.params,H.recordedAt),H.seq)).catch(()=>{})}return{...T,sessionId:R.sessionId}};u.onRequest("hydra-acp/session/fork",p=>h(p,!1)),u.onRequest("hydra-acp/session/side",p=>h(p,!0)),u.onRequest("hydra-acp/session/rewind",async p=>{let g=p??{};if(typeof g.sessionId!="string")throw F(x.InvalidParams,"hydra-acp/session/rewind requires sessionId");let y=g.keepThrough;if(y!==null&&(typeof y!="string"||y.length===0))throw F(x.InvalidParams,"keepThrough must be a non-empty messageId, or null to drop every turn");let m=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId;try{return await e.manager.rewindSession(m,y)}catch(v){let S=v;throw F(S.code??x.InternalError,S.message)}}),u.onRequest("session/fork",async p=>{let g=p??{};if(typeof g.sessionId!="string")throw F(x.InvalidParams,"session/fork requires sessionId");let y=typeof g.cwd=="string"?g.cwd:void 0,m=await e.manager.forkSession(g.sessionId,{...y!==void 0?{cwd:y}:{},mode:"verbatim"}),v=e.manager.get(m.sessionId);if(!v){let I=await e.manager.loadFromDisk(m.sessionId);if(!I)throw F(x.InternalError,`fork ${m.sessionId} vanished before it could be attached`);v=await Mt(e,{...I,onInstallProgress:Ar(u)})}un(l,v,v.sessionId);let S=kt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let I of b){if(u.isClosed())break;await u.notify(I.method,Be(Le(I.params,I.recordedAt),I.seq)).catch(()=>{})}return{sessionId:v.sessionId}});let f=async(p,g)=>{let y=p??{};if(typeof y.sessionId!="string")throw F(x.InvalidParams,`${g} requires sessionId`);let m=await e.manager.resolveCanonicalId(y.sessionId)??y.sessionId,v=e.manager.get(m);if(v)return await v.close({deleteRecord:!0,by:`session/delete ${l.clientId}`}),await e.manager.waitForDeletion(m),await e.manager.hasRecord(m)&&await e.manager.deleteRecord(m),{id:m,existed:!0};let S=await e.manager.deleteRecord(m);return{id:m,existed:S}};u.onRequest("session/delete",async p=>(await f(p,"session/delete"),{})),u.onRequest("session/close",async p=>{let g=p??{};if(typeof g.sessionId!="string")throw F(x.InvalidParams,"session/close requires sessionId");w(g.sessionId,"session/close");let y=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,m=e.manager.get(y);if(m)return await m.close({deleteRecord:!1,by:`session/close ${l.clientId}`+(l.processIdentity?` (${l.processIdentity.name})`:"")}),{};if(await e.manager.hasRecord(y))return{};throw F(x.SessionNotFound,`session ${y} not found`)}),u.onRequest("hydra-acp/session/delete",async p=>{let{id:g,existed:y}=await f(p,"hydra-acp/session/delete");if(!y)throw F(x.SessionNotFound,`session ${g} not found`);return{deleted:!0,sessionId:g}}),o?.kind==="transformer"&&(u.onRequest("hydra-acp/child_session/await",async p=>{let g=p??{},y=typeof g.childSessionId=="string"?g.childSessionId:void 0,m=g.until==="idle"?"idle":"turn_complete",v=typeof g.timeoutMs=="number"?Math.min(g.timeoutMs,18e5):3e5;if(!y)throw F(-32602,"await_child requires childSessionId");let S=Ee(e.manager,y,`child session ${y} not found`);return new Promise(b=>{let T=[],R=[],P=0,$=!1,H,J,z=!1,L=()=>{z||(z=!0,clearTimeout(U),H?.(),J?.(),b($?{entries:T,truncated:!0}:{entries:T}))};H=S.onBroadcast(ee=>{let se=Ow(ee);for(T.push(ee),R.push(se),P+=se;T.length>0&&(T.length>1e3||P>1048576);)T.shift(),P-=R.shift()??0,$=!0;m==="turn_complete"&&ee.params?.update?.sessionUpdate==="turn_complete"&&L()});let U=setTimeout(L,v);typeof U.unref=="function"&&U.unref(),J=S.onClose(()=>L())})}),u.onRequest("hydra-acp/child_session/close",async p=>{let g=p??{},y=typeof g.childSessionId=="string"?g.childSessionId:void 0;if(!y)throw F(-32602,"close_child_session requires childSessionId");let m=e.manager.get(y);return m&&await m.close({deleteRecord:!1,by:`child_session/close ${l.clientId}`}),{ok:!0}}),u.onRequest("hydra-acp/attention/set",async p=>Uw(p,o.name,e)),u.onRequest("hydra-acp/attention/clear",async p=>Lw(p,o.name,e)),u.onRequest("hydra-acp/connection/keep_alive",async p=>{let g=p??{},y=typeof g.token=="string"?g.token:void 0,m=typeof g.sessionId=="string"?g.sessionId:void 0,v=typeof g.estimatedRemainingMs=="number"?g.estimatedRemainingMs:void 0;return y&&m&&e.manager.get(m)?.keepAliveClaim(y,v),{ok:!0}})),u.onRequest("hydra-acp/session/tool_content",async p=>{let g=p??{};if(typeof g.sessionId!="string"||typeof g.hash!="string")throw F(x.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let y=await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,m=await e.manager.loadToolBlob(y,g.hash);if(m===null)throw F(x.SessionNotFound,"tool content not found");return{content:m}}),u.onRequest("authenticate",async p=>Fw(p,e)),u.onRequest("logout",async p=>Nw(p,e)),u.onRequest("session/new",async p=>{let g=new qt,y=Ia.parse(p),m=at(p?._meta),v=Array.isArray(m.transformers)&&m.transformers.every(te=>typeof te=="string")?m.transformers:e.manager.defaultTransformers??[],S=e.transformers?.resolveChain(v)??[],b=await yn(y.cwd),I=m.agentId??b.agentId??e.defaultAgent,A=await e.registry?.getAgent(I),T=Zr(b.configDefaults,A??{id:I})?.value,R,P,$=y.mcpServers;if(m.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){R=fl(32).toString("hex"),P=e.mcpTokenRegistry.reserve(R);let Ze={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${R}`}]};$=[...y.mcpServers??[],Ze]}let H,J,z=an(e);z!==void 0&&($=[...$??[],...z.descriptors]);let L=fi({baselineMcpServers:y.mcpServers,stdinEnabled:m.mcpStdin===!0,deps:e});g.mark("ws.prepare");let U;try{U=await e.manager.create({timer:g,cwd:y.cwd,agentId:I,mcpServers:$,title:m.title,agentArgs:m.agentArgs,model:m.model??T?.model,configDefaults:T,onInstallProgress:Ar(u),transformChain:S,originatingClient:l.clientInfo,...m.interactive!==void 0?{interactive:m.interactive}:{},...m.env!==void 0?{forwardedEnv:m.env}:{},...m.workspace!==void 0?{workspace:m.workspace}:{},...L?{mintMcpServersForSwap:L}:{}})}catch(te){throw P!==void 0&&P.abandon(te instanceof Error?te:void 0),J!==void 0&&J.abandon(te instanceof Error?te:void 0),z!==void 0&&z.abandon(te instanceof Error?te:void 0),te}if(R!==void 0&&P!==void 0&&e.mcpTokenRegistry!==void 0){let te=R,Ze=e.mcpTokenRegistry;P.complete(U),U.onClose(()=>{Ze.unbind(te)})}if(H!==void 0&&J!==void 0&&e.mcpTokenRegistry!==void 0){let te=H,Ze=e.mcpTokenRegistry;J.complete(U),U.onClose(()=>{Ze.unbind(te)})}z!==void 0&&z.bindToSession(U),g.mark("ws.bind-mcp"),hl(U.sessionId,e);let ee,se;try{un(l,U,U.sessionId),ee=kt(u,U,l),{entries:se}=await U.attach(ee,"full")}catch(te){throw await U.close({deleteRecord:!1,by:"session/new attach-failed"}).catch(()=>{}),te}l.attached.set(U.sessionId,{sessionId:U.sessionId,clientId:ee.clientId,readonly:!1}),g.mark("ws.attach"),e.manager.logInfo(`session/new timing agent=${I} session=${U.sessionId} ${g.summary()}`),setImmediate(()=>{(async()=>{for(let te of se){if(u.isClosed())break;await u.notify(te.method,Be(Le(te.params,te.recordedAt),te.seq)).catch(()=>{})}})()});let xe=Cr(U),vt=Rr(U);return{sessionId:U.sessionId,...xe?{modes:xe}:{},...vt?{models:vt}:{},configOptions:U.buildConfigOptions(),_meta:xr(e.manager,U,{clientId:ee.clientId})}}),u.onRequest("session/attach",async p=>{let g=Ca.parse(p),y=g.clientInfo?.version;y&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,y):e.onTransformerVersion?.(o.name,y));let m=at(g._meta),v=m.resume,S=m.readonly===!0,b=m.env;s.log.info(`session/attach sessionId=${g.sessionId} hasResumeHints=${!!v} readonly=${S}`);let I=v?g.sessionId:await e.manager.resolveCanonicalId(g.sessionId)??g.sessionId,A=e.manager.get(I);if(!A&&S){let L=await e.manager.loadFromDisk(I);if(!L)throw F(x.SessionNotFound,`session ${g.sessionId} not found`);let U=Bt(await e.manager.loadHistory(I,{...m.historyLimit!==void 0?{maxEntries:m.historyLimit}:{}}),L.side),ee=g.clientId??`cli_${Ii(8)}`;l.attached.set(L.hydraSessionId,{sessionId:L.hydraSessionId,clientId:ee,readonly:!0}),s.log.info(`session/attach OK (viewer) sessionId=${L.hydraSessionId} clientId=${ee} attachedCount=${l.attached.size} replayed=${U.length}`);for(let se of U)await u.notify(se.method,Be(Le(se.params,se.recordedAt),se.seq)).catch(()=>{});return{sessionId:L.hydraSessionId,clientId:ee,connectedClients:[ee],historyPolicy:"full",replayed:U.length,_meta:Bw(L)}}let T=!A;if(!A){let L=await e.manager.loadFromDisk(I),U=await Dw(I,v,L?.upstreamSessionId,e.manager);U.kind==="ignore"&&s.log.warn(U.logMessage);let ee=L;if(v&&U.kind==="honor"&&(ee={...L,hydraSessionId:g.sessionId,upstreamSessionId:v.upstreamSessionId,agentId:v.agentId,cwd:L?.workspace?.path??v.cwd,...v.title!==void 0?{title:v.title}:{},...v.agentArgs!==void 0?{agentArgs:v.agentArgs}:{}}),!ee)throw F(x.SessionNotFound,`session ${g.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(ee.agentId,ee.upstreamSessionId))throw F(x.SessionNotFound,`session ${g.sessionId} was deleted`);let se=ee.originatingClient?ee:{...ee,originatingClient:l.clientInfo},xe=b!==void 0?{...se,forwardedEnv:b}:se;A=await Mt(e,{...xe,onInstallProgress:Ar(u)})}un(l,A,A.sessionId);let R=kt(u,A,l,g.clientInfo,g.clientId),P=m.replayMode==="drip",{entries:$,appliedPolicy:H}=await A.attach(R,g.historyPolicy,{afterMessageId:g.afterMessageId,afterSeq:g.afterSeq,raw:P,...m.historyLimit!==void 0?{historyLimit:m.historyLimit}:{},...m.toolContent!==void 0?{toolContent:m.toolContent}:{}});if(l.attached.set(A.sessionId,{sessionId:A.sessionId,clientId:R.clientId,readonly:S}),b!==void 0&&await e.manager.setForwardedEnv(A.sessionId,b).catch(()=>{}),s.log.info(`session/attach OK sessionId=${A.sessionId} clientId=${R.clientId} attachedCount=${l.attached.size} requestedPolicy=${g.historyPolicy} appliedPolicy=${H} replayed=${$.length} readonly=${S}${P?" replayMode=drip":""}`),P){let L=m.dripSpeed&&m.dripSpeed>0?m.dripSpeed:1,U=750;(async()=>{let ee=null;for(let se of $){let xe=typeof se.recordedAt=="number"?se.recordedAt:null;if(ee!==null&&xe!==null){let vt=Math.min(U,Math.max(0,(xe-ee)/L));vt>0&&await new Promise(te=>setTimeout(te,vt))}xe!==null&&(ee=xe);try{await u.notify(se.method,Be(Le(se.params,xe??void 0),se.seq))}catch{return}}})()}else for(let L=0;L<$.length&&!u.isClosed();L++){let U=$[L],ee=u.notify(U.method,Be(Le(U.params,U.recordedAt),U.seq)).catch(()=>{});(L+1)%200===0&&await ee}A.replayPendingPermissions(R);let J=Cr(A),z=Rr(A);return{sessionId:A.sessionId,clientId:R.clientId,connectedClients:A.connectedClients(R.clientId),historyPolicy:H,replayed:$.length,...J?{modes:J}:{},...z?{models:z}:{},configOptions:A.buildConfigOptions(),_meta:xr(e.manager,A,{resurrected:T})}}),u.onRequest("session/detach",async p=>{let g=Ra.parse(p),y=l.attached.get(g.sessionId);if(!y)throw F(x.SessionNotFound,"client not attached to that session");let m=e.manager.get(g.sessionId);return m?.detach(y.clientId),l.attached.delete(g.sessionId),m&&e.manager.reapIfOrphanedNonInteractive(g.sessionId),{sessionId:g.sessionId,_meta:{[le]:{detachStatus:"detached"}}}}),u.onRequest("session/list",async p=>{let g=xa.parse(p??{});return{sessions:(await e.manager.list({cwd:g.cwd})).filter(S=>S.originatingClient?.name!==qs).map(Ta)}}),u.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw F(x.InternalError,"agent registry unavailable");return jt(e.registry)}),u.onRequest("hydra-acp/agents/auth_methods",async p=>{let g=p??{};if(typeof g.agentId!="string"||g.agentId.length===0)throw F(x.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(g.agentId)).authMethods??[]}}),u.onRequest("session/prompt",async p=>{let g=Ea.parse(p);w(g.sessionId,"session/prompt");let y=await dl(g,e.manager,b=>{s.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${b} sessionId=${g.sessionId}`)});if(y?.fromSession!==void 0){if((y.depth??0)>3)throw s.log.warn(`session/prompt: refusing depth ${y.depth} chain from ${y.fromSession} to ${g.sessionId}`),F(x.InvalidRequest,`message chain too deep (${y.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(y.awaiting===!0&&ul(y.fromSession,g.sessionId))throw s.log.warn(`session/prompt: refusing deadlock ${y.fromSession} -> ${g.sessionId}`),F(x.InvalidRequest,`would deadlock: ${g.sessionId} is already blocked waiting on ${y.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let m=l.attached.get(g.sessionId);if(!m)throw s.log.warn(`session/prompt rejected: not attached sessionId=${g.sessionId} attachedKeys=[${[...l.attached.keys()].join(",")}]`),F(x.SessionNotFound,"not attached to session");let v=e.manager.get(g.sessionId);if(!v){let b=await e.manager.loadFromDisk(g.sessionId);if(!b)throw F(x.SessionNotFound,`session ${g.sessionId} not found`);s.log.info(`session/prompt auto-resurrecting cold sessionId=${g.sessionId}`),v=await Mt(e,b);let I=kt(u,v,l,void 0,m.clientId);await v.attach(I,"none")}let S=y?.awaiting===!0&&y.fromSession!==void 0?cl(y.fromSession,g.sessionId):void 0;try{return await v.prompt(m.clientId,g,y)}finally{S?.()}});let k=p=>{let g;try{g=hs.parse(p)}catch(v){s.log.warn(`session/cancel: invalid params: ${v.message}`);return}let y=l.attached.get(g.sessionId);if(!y)return;if(y.readonly){s.log.warn(`session/cancel dropped (readonly attachment) sessionId=${g.sessionId}`);return}let m=e.manager.get(g.sessionId);m&&m.cancel(y.clientId).catch(v=>{s.log.warn(`session/cancel for ${g.sessionId}: ${v.message}`)})};u.onNotification("session/cancel",k),u.onRequest("session/cancel",async p=>{let g=hs.parse(p);return w(g.sessionId,"session/cancel"),k(p),null}),u.onRequest("hydra-acp/prompt/cancel",async p=>{let g=Ma.parse(p);return w(g.sessionId,"hydra-acp/prompt/cancel"),Ee(e.manager,g.sessionId).cancelQueuedPrompt(g.messageId)}),u.onRequest("hydra-acp/session/force_cancel",async p=>{let g=hs.parse(p);return w(g.sessionId,"hydra-acp/session/force_cancel"),Ee(e.manager,g.sessionId).forceCancel()}),u.onRequest("hydra-acp/prompt/update",async p=>{let g=_a.parse(p);return w(g.sessionId,"hydra-acp/prompt/update"),Ee(e.manager,g.sessionId).updateQueuedPrompt(g.messageId,g.prompt)}),u.onRequest("hydra-acp/prompt/amend",async p=>{let g=$a.parse(p);w(g.sessionId,"hydra-acp/prompt/amend");let y=l.attached.get(g.sessionId);if(!y)throw F(x.SessionNotFound,"not attached to session");return Ee(e.manager,g.sessionId).amendPrompt(y.clientId,g)}),u.onRequest("_session/steering",async p=>{let g=Oa.parse(p);w(g.sessionId,"_session/steering");let y=l.attached.get(g.sessionId);if(!y)throw F(x.SessionNotFound,"not attached to session");let m=e.manager.get(g.sessionId);if(!m){let v=await e.manager.loadFromDisk(g.sessionId);if(!v)throw F(x.SessionNotFound,`session ${g.sessionId} not found`);m=await Mt(e,v);let S=kt(u,m,l,void 0,y.clientId);await m.attach(S,"none")}return m.steer(y.clientId,g)}),u.onRequest("session/resume",async p=>{let g=p??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw F(x.InvalidParams,"session/resume requires sessionId");let m=await e.manager.resolveCanonicalId(y)??y,v=e.manager.get(m);if(!v){let A=await e.manager.loadFromDisk(m);if(!A)throw F(x.SessionNotFound,`session ${y} not found in memory or on disk`);v=await Mt(e,A)}un(l,v,v.sessionId);let S=kt(u,v,l);await v.attach(S,"pending_only"),l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1}),v.replayPendingPermissions(S);let b=Cr(v),I=Rr(v);return{sessionId:v.sessionId,...b?{modes:b}:{},...I?{models:I}:{},configOptions:v.buildConfigOptions(),_meta:xr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/load",async p=>{let g=p??{},y=typeof g.sessionId=="string"?g.sessionId:void 0;if(!y)throw F(x.InvalidParams,"session/load requires sessionId");let m=await e.manager.resolveCanonicalId(y)??y,v=e.manager.get(m);if(!v){let T=await e.manager.loadFromDisk(m);if(!T)throw F(x.SessionNotFound,`session ${y} not found in memory or on disk`);v=await Mt(e,T)}un(l,v,v.sessionId);let S=kt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let T of b){if(u.isClosed())break;await u.notify(T.method,Be(Le(T.params,T.recordedAt),T.seq)).catch(()=>{})}v.replayPendingPermissions(S);let I=Cr(v),A=Rr(v);return{sessionId:v.sessionId,...I?{modes:I}:{},...A?{models:A}:{},configOptions:v.buildConfigOptions(),_meta:xr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/set_model",async p=>{let g=p?.sessionId;typeof g=="string"&&w(g,"session/set_model");let y=Hw(p,e.manager);if(y.kind==="error")throw s.log.warn(y.logMessage),F(y.code,y.message);if(y.kind==="no_op")return s.log.warn(y.logMessage),await u.notify("session/update",{sessionId:y.sessionId,update:{sessionUpdate:"_hydra_current_model_update",currentModel:y.currentModel}}).catch(()=>{}),null;s.log.info(y.logMessage);let{modelId:m}=y,v=await y.session.forwardModelChange(m,p);return y.session.applyAgentConfigOptionResponse(v,"model"),y.session.applyModelChange(m),v}),u.onRequest("session/set_mode",async p=>{let g=p,y=g?.sessionId;if(typeof y=="string"&&w(y,"session/set_mode"),!g||typeof g.sessionId!="string")throw F(x.InvalidParams,"session/set_mode requires string sessionId");if(typeof g.modeId!="string")throw F(x.InvalidParams,"session/set_mode requires string modeId");let m=Ee(e.manager,g.sessionId),v=await m.forwardRequest("session/set_mode",p);return m.applyModeChange(g.modeId),v}),u.onRequest("session/set_config_option",async p=>{let g=p,y=b=>F(x.InvalidParams,b),m=g?.sessionId;if(typeof m=="string"&&w(m,"session/set_config_option"),!g||typeof g.sessionId!="string")throw y("session/set_config_option requires string sessionId");if(typeof g.configId!="string")throw y("session/set_config_option requires string configId");if(typeof g.value!="string")throw y("session/set_config_option requires string value");let v=Ee(e.manager,g.sessionId),S=v.buildConfigOptions().find(b=>b.id===g.configId);if(!S)throw y(`unknown configId ${JSON.stringify(g.configId)} for this session`);if(!S.options.some(b=>b.value===g.value))throw y(`value ${JSON.stringify(g.value)} is not valid for configId ${JSON.stringify(g.configId)}`);switch(g.configId){case"model":{if(g.value!==v.currentModel){let b=await v.forwardModelChange(g.value);v.applyAgentConfigOptionResponse(b,"model")}v.applyModelChange(g.value);break}case"mode":{g.value!==v.currentMode&&await v.forwardRequest("session/set_mode",{sessionId:g.sessionId,modeId:g.value}),v.applyModeChange(g.value);break}case"agent":{g.value!==v.agentId&&await v.setAgent(g.value);break}default:{let b=await v.forwardRequest("session/set_config_option",{sessionId:g.sessionId,configId:g.configId,value:g.value});v.applyAgentConfigOptionResponse(b,g.configId)&&v.broadcastConfigOptions()}}return{configOptions:v.buildConfigOptions()}}),u.setDefaultHandler(async(p,g)=>{let y=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),m=g.startsWith("session/"),v=g.startsWith("hydra-acp/");if(!m&&!v||p===null||typeof p!="object"||y.has(g))throw F(x.MethodNotFound,`Method not found: ${g}`);let S=p.sessionId;if(typeof S!="string")throw F(x.MethodNotFound,`Method not found: ${g}`);return w(S,g),Ee(e.manager,S).forwardRequest(g,p)})})}async function Fw(s,e){let t=s??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw F(x.InvalidParams,"authenticate requires a non-empty methodId string");let n=t.methodId,r=t._meta?.["hydra-acp"],o=typeof r?.sessionId=="string"?r.sessionId:void 0,i=typeof r?.agentId=="string"?r.agentId:void 0,a=o!==void 0?e.manager.getAgentForSession(o):void 0;if(!a||!a.isAlive()){let h=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(h)}let d=a.authMethods??[],c=d.find(h=>h.id===n);if(!c){let h=d.map(f=>f.id);throw F(x.InvalidParams,`authenticate: methodId ${JSON.stringify(n)} is not advertised by agent ${a.agentId}; valid: [${h.map(f=>JSON.stringify(f)).join(", ")}]`)}let u=c._meta?.type,l=(()=>{let h=c._meta?.["terminal-auth"];if(h&&typeof h=="object"&&!Array.isArray(h))return h})();if((c.type??(u==="agent"||u==="terminal"?u:l!==void 0?"terminal":"agent"))==="terminal"){let h=(m,v)=>{if(!Array.isArray(m))throw F(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be a string[]; got ${m===null?"null":typeof m}`);for(let S of m)if(typeof S!="string")throw F(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be string[]; got non-string entry ${JSON.stringify(S)}`);return m},f=await e.manager.planSpawnForAgent(a.agentId),k,p;if(l?.args!==void 0){let m=typeof l.command=="string"?l.command:void 0;k=m!==void 0&&gl.isAbsolute(m)?m:f.command,p=h(l.args,'_meta["terminal-auth"].args')}else{let m=c.args!==void 0?{raw:c.args,label:"args"}:c._meta?.args!==void 0?{raw:c._meta.args,label:"_meta.args"}:void 0,v=m!==void 0?h(m.raw,m.label):[];k=f.command,p=[...f.args,...v]}let g={};for(let[m,v]of Object.entries(process.env))typeof v=="string"&&(g[m]=v);Object.assign(g,f.env);let y=pl.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${n}`),{kind:"terminal",command:k,args:p,env:g,cwd:y}}try{return await a.connection.request("authenticate",{methodId:n})}catch(h){throw ht(h,a)}}async function Nw(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 Ar(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(Fa,t).catch(()=>{})}}function Cr(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 Rr(s){let e=s.availableModels();if(e.length===0)return;let t=e.map(r=>{let o={modelId:r.modelId};return r.name!==void 0&&(o.name=r.name),r.description!==void 0&&(o.description=r.description),o});return{currentModelId:s.currentModel??e[0].modelId,availableModels:t}}async function Dw(s,e,t,n){return e?await n.isRetiredGeneration(s,e.upstreamSessionId)?{kind:"ignore",logMessage:`session/attach ignoring stale resume hint sessionId=${s} hintUpstream=${e.upstreamSessionId} recordUpstream=${t} (retired generation)`}:{kind:"honor"}:{kind:"none"}}function Hw(s,e){if(!s||typeof s!="object")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires params",logMessage:"session/set_model rejected: params not an object"};let t=s;if(typeof t.sessionId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string sessionId",logMessage:"session/set_model rejected: missing/non-string sessionId"};if(typeof t.modelId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string modelId",logMessage:`session/set_model rejected: missing/non-string modelId sessionId=${t.sessionId}`};let n=e.get(t.sessionId);if(!n)return{kind:"error",code:x.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=n.availableModels(),o=Gt(t.modelId,r);if(o.kind==="none")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model passthrough (no availableModels) sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="exact")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model accepted sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="resolved")return{kind:"ok",session:n,modelId:o.modelId,logMessage:`session/set_model resolved sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} \u2192 ${JSON.stringify(o.modelId)}`};let i=r.map(d=>d.modelId).join(", "),a=o.kind==="ambiguous"?`ambiguous (trailing-segment matches [${o.candidates.join(", ")}])`:"not in availableModels";return n.currentModel!==void 0&&n.currentModel.length>0?{kind:"no_op",session:n,sessionId:t.sessionId,currentModel:n.currentModel,logMessage:`session/set_model no_op (resyncing client) sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} ${a} actual=${JSON.stringify(n.currentModel)} agentId=${n.agentId} known=[${i}]`}:{kind:"error",code:x.InvalidParams,message:`model "${t.modelId}" is ${a==="not in availableModels"?"not in this session's availableModels":a} (agent ${n.agentId}); known models: ${i}`,logMessage:`session/set_model rejected sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)} ${a} agentId=${n.agentId} known=[${i}] (no current model to fall back to)`}}async function jw(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0;if(!r)throw F(x.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw F(x.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw F(x.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return Ee(t.manager,r).addTransformer(o),{ok:!0}}async function Uw(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 F(x.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw F(x.InvalidParams,"hydra-acp/attention/set requires string reason");return Ee(t.manager,r).setAttentionFlag(e,o,n.payload),{ok:!0}}async function Lw(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 F(x.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw F(x.InvalidParams,"hydra-acp/attention/clear requires string reason");return Ee(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function Bw(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:Un(s.currentUsage),forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,updatedAt:s.createdAt??new Date().toISOString(),attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1},t={currentMode:s.currentMode,agentArgs:s.agentArgs,availableCommands:s.agentCommands,availableModes:s.agentModes,availableModels:s.agentModels,armedTaskList:[]};return{[le]:ms(e,t)}}function xr(s,e,t={}){let n=s.liveListEntry(e),r={clientId:t.clientId,currentMode:e.currentMode,agentArgs:e.agentArgs,availableCommands:e.mergedAvailableCommands(),availableModes:e.availableModes(),availableModels:e.availableModels(),turnStartedAt:e.turnStartedAt,agentCapabilities:e.agentCapabilities,queue:e.queueSnapshot(),armedTaskList:e.armedBackgroundTasks,...t.resurrected===!0?{resurrected:!0}:{}};return Sn(e.agentMeta,ms(n,r))}function Ww(){return{protocolVersion:1,agentInfo:{name:"hydra",version:ue},agentCapabilities:{promptCapabilities:{image:!0,audio:!0,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0},loadSession:!0,auth:{logout:{}},sessionCapabilities:{attach:{},list:{},resume:{},delete:{},close:{},fork:{}}},authMethods:[{id:"proxy",name:"Hydra proxy",type:"agent",description:"Hydra proxies authentication to the downstream agent selected per session"}],_meta:{...Sn(void 0,{prompt:{queueing:!0,cancelling:!0,updating:!0,amending:!0,pipelining:!1},agents:{list:!0,installProgress:!0},session:{fork:{forkAt:!0,agentSwap:!0,synthesis:!0,model:!0},side:{selection:!0},rewind:{}}}),steering:{supported:!0}}}}function qw(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 hl(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 kt(s,e,t,n,r){return{clientId:r??`cli_${Ii(8)}`,connection:s,clientInfo:n}}function un(s,e,t){let n=s.attached.get(t);n&&(e.detach(n.clientId),s.attached.delete(t))}var Tr=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 Jw}from"crypto";import{McpServer as Vw}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Gw}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as we}from"zod";import{isInitializeRequest as zw}from"@modelcontextprotocol/sdk/types.js";function ln(s,e){return s.method==="POST"&&s.headers["mcp-session-id"]===void 0&&zw(s.body)&&e?.transport.sessionId!==void 0}async function Qe(s){try{await s.transport.close()}catch{}try{await s.server.close()}catch{}}function Ai(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 Re(s){return{content:[{type:"text",text:JSON.stringify(s)}],structuredContent:s}}var yl="Bearer ";function fn(s){let e=s.headers.authorization;if(typeof e!="string"||!e.startsWith(yl))return;let t=e.slice(yl.length).trim();return t.length>0?t:void 0}function Kw(s){let e=new Vw({name:"hydra-acp-stdin",version:"1.0.0"},{instructions:"Piped input from `hydra cat --stream` is exposed here as a byte stream. Use `tail` for the latest N bytes (good for finding the end of a log), `head` for the first N bytes (good for headers/preamble), `read` for windowed reads against an absolute byte cursor, `wait_for_more` to block until new bytes arrive past a cursor, and `info` for the current cursors/capacity/closed status. Byte payloads come back base64-encoded."});return e.registerTool("tail",{description:"Return the most recent `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means older bytes existed but have been evicted from the ring.",inputSchema:{bytes:we.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let n=s.streamTail(t);return Re(n)}),e.registerTool("head",{description:"Return the first `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means the head has already been evicted from the ring and the returned bytes start at the oldest still-resident cursor.",inputSchema:{bytes:we.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let n=s.streamHead(t);return Re(n)}),e.registerTool("read",{description:"Read up to `max_bytes` bytes starting at absolute byte `cursor`. Returns `{bytes, nextCursor, gap?, eof?}` \u2014 `gap` is the number of bytes silently skipped because the ring had evicted them; `eof:true` means the producer closed and there is nothing left to read.",inputSchema:{cursor:we.number().int().min(0).describe("Absolute byte offset to start reading from. Use 0 to read from the very beginning (may produce a gap if old bytes have been evicted)."),max_bytes:we.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:we.number().int().min(0).optional().describe("If no bytes are available, block up to this many ms for more (capped server-side at 60_000).")}},async({cursor:t,max_bytes:n,wait_ms:r})=>{let o=await s.streamRead(t,n,r);return Re(o)}),e.registerTool("wait_for_more",{description:"Block until bytes are available past `cursor`, the stream closes, or `timeout_ms` elapses. Returns one of {data, eof, timeout} plus the current `writeCursor`. Use this when you've consumed everything up to a cursor and want to wait for more without busy-polling.",inputSchema:{cursor:we.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:we.number().int().min(0).describe("Maximum ms to block (server caps at 60_000).")}},async({cursor:t,timeout_ms:n})=>{let r=await s.streamWaitFor(t,n),o=s.streamInfo();return Re({outcome:r,writeCursor:o.writeCursor,closed:o.closed})}),e.registerTool("grep",{description:"Scan piped stdin line-by-line and return lines matching `pattern`. Prefer this over `read` when the question is 'find lines that mention X' \u2014 it filters server-side so you don't pull and decode 64 KiB base64 windows. Returns `{matches: [{cursor, line, before?, after?}], truncated, nextCursor, gap?, scannedBytes, eof?}`. Lines come back as decoded UTF-8 strings (not base64). When `truncated:true`, re-call with `cursor: nextCursor` to resume.",inputSchema:{pattern:we.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:we.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:we.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:we.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:we.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:we.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:we.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:we.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:we.number().int().min(0).optional().describe("Optional absolute byte offset to start scanning from. Omit to scan from the oldest still-resident byte. Pass the `nextCursor` from a previous truncated call to resume.")}},async t=>{let n={pattern:t.pattern};t.regex!==void 0&&(n.regex=t.regex),t.case_insensitive!==void 0&&(n.caseInsensitive=t.case_insensitive),t.invert!==void 0&&(n.invert=t.invert),t.max_matches!==void 0&&(n.maxMatches=t.max_matches),t.max_bytes!==void 0&&(n.maxBytes=t.max_bytes),t.context_before!==void 0&&(n.contextBefore=t.context_before),t.context_after!==void 0&&(n.contextAfter=t.context_after),t.cursor!==void 0&&(n.cursor=t.cursor);let r=s.streamGrep(n);return Re(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 Re(t)}),e}var Qw=1e4;function wl(s,e){let t=new Map,n=new Map,r=new Set;async function o(c,u){let l=Kw(u),w=new Gw({sessionIdGenerator:()=>Jw()});await l.connect(w);let h={server:l,transport:w};return t.set(c,h),r.has(c)||(r.add(c),e.addDisposer(c,async()=>{r.delete(c);let f=t.get(c);t.delete(c),f!==void 0&&await Qe(f)})),h}async function i(c,u){let l=t.get(c);if(l!==void 0)return l.transport;let w=n.get(c);return w===void 0&&(w=o(c,u).finally(()=>{n.delete(c)}),n.set(c,w)),(await w).transport}async function a(c,u){let l=fn(c);if(l===void 0){u.code(401).send({error:"missing bearer token"});return}let w=e.lookup(l);if(w===void 0){u.code(404).send({error:"unknown stdin token"});return}let h;if(w.session!==void 0)h=w.session;else{let p,g=new Promise(m=>{p=setTimeout(()=>m(void 0),Qw)}),y=await Promise.race([w.sessionReady.catch(()=>{}),g]);if(p!==void 0&&clearTimeout(p),y===void 0){u.code(503).send({error:"session not ready"});return}h=y}let f=t.get(l);f!==void 0&&ln(c,f)&&(t.delete(l),Qe(f));let k=await i(l,h);u.hijack(),await k.handleRequest(c.raw,u.raw,c.body)}let d={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-stdin",d,async(c,u)=>{await a(c,u)}),s.get("/mcp/hydra-acp-stdin",d,async(c,u)=>{await a(c,u)}),s.delete("/mcp/hydra-acp-stdin",d,async(c,u)=>{await a(c,u)})}import{randomUUID as Yw}from"crypto";import{McpServer as Xw}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Zw}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as Ye}from"zod";function ek(s){switch(s){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}var kl=2e3,vl=2e4;function tk(s,e,t){if(e!=="tool_call"&&e!=="tool_call_update")return Qt([s]);let n=[],r=Rn(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=xs(t);return i!==void 0&&n.push(i),n.join(`
217
- `)}function nk(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 sk(s){let e=new Xw({name:"hydra-acp-recall",version:"1.0.0"},{instructions:"Search and retrieve detail from this session's pre-compaction history. After a compaction summary replaces earlier conversation in working memory, these tools let you page back specifics on demand. Use `search` to find entries by keyword, `range` to pull a contiguous slice verbatim, and `tool_calls` to enumerate prior tool invocations. These tools only return results once the session has been compacted at least once."});return e.registerTool("search",{description:"Search this session's prior conversation history (the part that was compacted out of your working memory) by keyword. Covers assistant and user messages, the arguments of every tool call including full shell commands, and what those calls printed. Returns matching entry ids with short snippets so you can decide which to pull in full via `range`. Use this when the compaction summary mentions something but you need the verbatim detail.",inputSchema:{query:Ye.string().min(1).describe("Case-insensitive substring to search for."),limit:Ye.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:Ye.boolean().optional().describe("Whether to include tool_call entries in the search (default true).")}},async({query:t,limit:n=10,include_tool_calls:r=!0})=>{let o=await s();if(!o.summarizedThroughEntry||o.summarizedThroughEntry===0)return Re({matches:[],total_matched:0,truncated:!1,note:"This session has no compacted history. `search` retrieves detail from entries that were summarized out of the working conversation; nothing has been summarized yet."});let i=[],a=t.toLowerCase();for await(let{entryId:c,entry:u}of o.iterRecallNewestFirst()){let l=Ai(u);if(!l)continue;let{kind:w,update:h}=l;if((w==="tool_call"||w==="tool_call_update")&&!r)continue;let f=tk(u,w,h),k=f.toLowerCase().indexOf(a);if(k<0)continue;let p=ek(w),g=nk(f,k),y=typeof u.recordedAt=="number"?String(u.recordedAt):void 0;if(i.push({entryId:c,speaker:p,snippet:g,timestamp:y}),i.length>=n)break}i.sort((c,u)=>c.entryId-u.entryId);let d=i.length>=n;return Re({matches:i,total_matched:i.length,truncated:d})}),e.registerTool("range",{description:"Pull a contiguous range of prior conversation entries verbatim from this session's pre-compaction history, including each tool call's arguments and what it printed. Use after `search` narrows in on what you need. Capped at 50 entries per call.",inputSchema:{from_entry:Ye.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:Ye.number().int().min(0).describe("Zero-based index of the last entry to include (inclusive).")}},async({from_entry:t,to_entry:n})=>{let r=await s();if(!r.summarizedThroughEntry||r.summarizedThroughEntry===0)return Re({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 Re({text:"",entry_count:0,truncated:!1});let a=Math.min(t,i-1),d=Math.min(n,i-1),c=a>t||d<n;if(a>d)return{content:[{type:"text",text:""}],structuredContent:{text:"",entry_count:0,truncated:c}};let u=await r.sliceRecallHistory(a,d),l=Qt(u,{toolOutput:{maxPerCall:kl,maxTotal:vl}});return{content:[{type:"text",text:l}],structuredContent:{text:l,entry_count:u.length,truncated:c}}}),e.registerTool("tool_calls",{description:"Search this session's prior tool invocations by tool name, ACP kind, and/or file path. Returns when each tool was called, its arguments (including the full shell command), the result status, and what the call printed. Use this to recall which files were read/edited, what shell commands ran, and what they output.",inputSchema:{tool_name:Ye.string().optional().describe("Case-insensitive substring of the tool name. Names vary by agent for the same tool (Bash, Terminal, bash), so prefer `kind` when you want every shell invocation."),kind:Ye.string().optional().describe("ACP tool kind: execute (shell), read, edit, think, other. Agent-independent, unlike tool_name."),file_path:Ye.string().optional(),limit:Ye.number().int().min(1).max(100).optional(),include_output:Ye.boolean().optional().describe("Include what each call printed (default true). Set false when you only need the commands and not their results.")}},async({tool_name:t,kind:n,file_path:r,limit:o=20,include_output:i=!0})=>{let a=await s();if(!a.summarizedThroughEntry||a.summarizedThroughEntry===0)return Re({calls:[],truncated:!1,note:"This session has no compacted history. `tool_calls` retrieves tool invocations from the pre-compaction transcript; nothing has been compacted yet."});let d=typeof t=="string"&&t.length>0,c=typeof n=="string"&&n.length>0,u=typeof r=="string"&&r.length>0;if(!d&&!c&&!u)throw new Error("tool_calls: at least one of tool_name, kind, or file_path must be provided");let l=new Map,w=Math.max(o*4,200);for await(let{entryId:y,entry:m}of a.iterRecallNewestFirst()){let v=Ai(m);if(!v)continue;let{kind:S,update:b}=v;if(S!=="tool_call"&&S!=="tool_call_update")continue;let I=typeof b.toolCallId=="string"&&b.toolCallId.length>0?b.toolCallId:`__noid_${y}`,A=l.get(I);if(A||(A={entryId:y,toolName:"(unnamed)",nameAuthoritative:!1,rawInput:{},locations:[],status:"in_progress"},l.set(I,A)),y<A.entryId&&(A.entryId=y),!A.nameAuthoritative){let R=Rn(b);R!==void 0?(A.toolName=R,A.nameAuthoritative=!0):typeof b.name=="string"&&b.name.length>0?(A.toolName=b.name,A.nameAuthoritative=!0):S==="tool_call"&&typeof b.title=="string"&&b.title.length>0&&(A.toolName=b.title,A.nameAuthoritative=!0)}if(A.kind===void 0&&typeof b.kind=="string"&&b.kind.length>0&&(A.kind=b.kind),A.output===void 0){let R=xs(b);R!==void 0&&(A.output=R)}let T=b.rawInput;if(T&&typeof T=="object"&&!Array.isArray(T)&&Object.keys(T).length>0)for(let[R,P]of Object.entries(T))A.rawInput[R]===void 0&&(A.rawInput[R]=P);if(Array.isArray(b.locations))for(let R of b.locations){let P=R?.path;typeof P=="string"&&P.length>0&&!A.locations.includes(P)&&A.locations.push(P)}if(typeof b.status=="string"&&A.status==="in_progress"&&(A.status=b.status),m.recordedAt!==void 0&&A.timestamp===void 0&&(A.timestamp=String(m.recordedAt)),l.size>=w)break}let h=[...l.keys()].sort((y,m)=>l.get(y).entryId-l.get(m).entryId),f=[],k=vl,p=!1;for(let y of h){let m=l.get(y);if(m.toolName=mo({name:m.toolName,rawInput:m.rawInput,...m.kind!==void 0?{kind:m.kind}:{}}),d&&!m.toolName.toLowerCase().includes(t.toLowerCase())||c&&(m.kind??"").toLowerCase()!==n.toLowerCase())continue;if(u){let b=r.toLowerCase(),I=["file_path","filePath","path"],A=!1;for(let T of I){let R=m.rawInput[T];if(typeof R=="string"&&R.toLowerCase().includes(b)){A=!0;break}}if(!A){for(let T of m.locations)if(T.toLowerCase().includes(b)){A=!0;break}}if(!A)continue}let v={};for(let[b,I]of Object.entries(m.rawInput))typeof I=="string"?v[b]=I.length>500?I.slice(0,497)+"\u2026":I:(typeof I=="number"||typeof I=="boolean")&&(v[b]=I);m.locations.length>0&&v.locations===void 0&&(v.locations=m.locations);let S={entryId:m.entryId,tool:m.toolName,args:v,status:m.status,timestamp:m.timestamp};if(m.kind!==void 0&&(S.kind=m.kind),i&&m.output!==void 0){let b=m.output,I=Math.min(kl,k);if(I<=0)p=!0;else{let A=b.length<=I?b:b.slice(0,I-1)+"\u2026";S.output=A,S.outputBytes=b.length,S.outputTruncated=A.length<b.length,k-=A.length}}if(f.push(S),f.length>=o)break}let g=f.length>=o;return Re({calls:f,truncated:g,...p?{outputBudgetExhausted:p}:{}})}),e}var rk=1e4;function bl(s,e){let t=new Map,n=new Map,r=new Set;async function o(c,u){let l=sk(u),w=new Zw({sessionIdGenerator:()=>Yw()});await l.connect(w);let h={server:l,transport:w};return t.set(c,h),r.has(c)||(r.add(c),e.addDisposer(c,async()=>{r.delete(c);let f=t.get(c);t.delete(c),f!==void 0&&await Qe(f)})),h}async function i(c,u){let l=t.get(c);if(l!==void 0)return l.transport;let w=n.get(c);return w===void 0&&(w=o(c,u).finally(()=>{n.delete(c)}),n.set(c,w)),(await w).transport}async function a(c,u){let l=fn(c);if(l===void 0){u.code(401).send({error:"missing bearer token"});return}let w=e.lookup(l);if(w===void 0){u.code(404).send({error:"unknown recall token"});return}let h=async()=>{if(w.session!==void 0)return w.session;let p,g=new Promise(m=>{p=setTimeout(()=>m(void 0),rk)}),y=await Promise.race([w.sessionReady.catch(()=>{}),g]);if(p!==void 0&&clearTimeout(p),y===void 0)throw new Error("recall: session not ready");return y},f=t.get(l);f!==void 0&&ln(c,f)&&(t.delete(l),Qe(f));let k=await i(l,h);u.hijack(),await k.handleRequest(c.raw,u.raw,c.body)}let d={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-recall",d,async(c,u)=>{await a(c,u)}),s.get("/mcp/hydra-acp-recall",d,async(c,u)=>{await a(c,u)}),s.delete("/mcp/hydra-acp-recall",d,async(c,u)=>{await a(c,u)})}var Er=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 fk}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as pk}from"crypto";import{Server as ok}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as ik,ListToolsRequestSchema as ak}from"@modelcontextprotocol/sdk/types.js";function Sl(s,e,t,n){let r=typeof t=="function"?async()=>t():async()=>t,o=new ok({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(ak,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(ik,async(a,d)=>{let c=a.params.name,u=d._meta?.progressToken??d.requestId,l=ck(u,d.sendNotification);try{let w=await r(),h=await uk(e.connection,s,c,a.params.arguments??{},w);return lk(h,c)}catch(w){return Ci(w instanceof Error?w.message:String(w))}finally{l()}}),o}var dk=15e3;function ck(s,e,t=dk){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 uk(s,e,t,n,r){return await s.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:n,sessionId:r})}function lk(s,e){if(s===null||typeof s!="object")return Ci(`extension ${e} returned non-object`);let t=s;return Array.isArray(t.content)?t:Ci(`extension ${e} omitted content array`)}function Ci(s){return{content:[{type:"text",text:s}],isError:!0}}var gk=1e4;function Il(s,e,t){let n=new Map;function r(c){for(let u of n.values()){let l=u.get(c);l!==void 0&&(u.delete(c),Qe(l))}}async function o(c,u){for(let[l,w]of n){if(e.lookup(l)?.session?.sessionId!==c)continue;let f=w.get(u);if(f!==void 0)try{await f.server.sendToolListChanged()}catch{}}}t.onChange(c=>{r(c)});async function i(c,u){let l=n.get(c);l===void 0&&(l=new Map,n.set(c,l),e.addDisposer(c,async()=>{let m=n.get(c);if(m!==void 0){n.delete(c);for(let v of m.values())await Qe(v)}}));let w=l.get(u);if(w!==void 0)return w.transport;let h=t.lookup(u);if(h===void 0)return;let g=Sl(u,h,async()=>{let m=e.lookup(c);if(m===void 0)throw new Error("mcp token no longer bound");if(m.session!==void 0)return m.session.sessionId;let v,S=new Promise(I=>{v=setTimeout(()=>I(void 0),gk)}),b=await Promise.race([m.sessionReady.catch(()=>{}),S]);if(v!==void 0&&clearTimeout(v),b===void 0)throw new Error("session not ready");return b.sessionId},{peekSessionId:()=>e.lookup(c)?.session?.sessionId,fetchSessionTools:async m=>{let v=await h.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:m});if(!v||typeof v!="object")return;let S=v.tools;if(!Array.isArray(S))return;let b=[];for(let I of S){if(!I||typeof I!="object")continue;let A=I;if(typeof A.name!="string"||A.name.length===0||typeof A.description!="string"||A.inputSchema===null||typeof A.inputSchema!="object")continue;let T={name:A.name,description:A.description,inputSchema:A.inputSchema};A.outputSchema!==null&&typeof A.outputSchema=="object"&&(T.outputSchema=A.outputSchema),b.push(T)}return b}}),y=new fk({sessionIdGenerator:()=>pk()});return await g.connect(y),l.set(u,{server:g,transport:y}),y}async function a(c,u){let l=fn(c);if(l===void 0){u.code(401).send({error:"missing bearer token"});return}if(e.lookup(l)===void 0){u.code(404).send({error:"unknown mcp token"});return}let h=c.params.name,f=n.get(l),k=f?.get(h);k!==void 0&&ln(c,k)&&(f?.delete(h),Qe(k));let p=await i(l,h);if(p===void 0){u.code(404).send({error:`unknown mcp server: ${h}`});return}u.hijack(),await p.handleRequest(c.raw,u.raw,c.body)}let d={config:{skipAuth:!0}};return s.post("/mcp/:name",d,async(c,u)=>{await a(c,u)}),s.get("/mcp/:name",d,async(c,u)=>{await a(c,u)}),s.delete("/mcp/:name",d,async(c,u)=>{await a(c,u)}),{notifyToolListChanged:o}}async function El(s,e,t={}){bk(s),Lr(s.daemon.scrubEnv);let n=s,r=s.daemon.tls?await Xe.readFile(ie(s.daemon.tls.key)):void 0,o=s.daemon.tls?await Xe.readFile(ie(s.daemon.tls.cert)):void 0;await Xe.mkdir(E.home(),{recursive:!0});let{stream:i,fileStream:a,closeFile:d}=await kk(s.daemon.logLevel),c=mk({logger:{level:s.daemon.logLevel,stream:i},bodyLimit:256*1024*1024});await c.register(hk,{options:{handleProtocols:Gi}}),Vr(N=>{c.log.info(N)}),Qr(N=>{c.log.info(N)});let u=await or.load(),l=await hr.load();ki(),yi(l);let w=new Ir(l);w.start();let h=new gr(l);h.start();let f=new ur,k=new cr,p=new ir(e),g=new dr([p,new ar(u),k]),y=ou({validator:g});c.addHook("onRequest",async(N,Ce)=>{N.routeOptions.config?.skipAuth||N.url==="/acp"||N.url?.startsWith("/acp?")||(await y(N,Ce),!Ce.sent&&N.authIdentity?.startsWith("script:")&&!au(N.method,N.routeOptions.url)&&Ce.code(403).send({error:"script tokens may only access read-only session data"}))});let m=setInterval(()=>{u.sweepExpired()},300*1e3);m.unref();let v=setInterval(()=>{f.sweepExpired()},300*1e3);v.unref();let S=new ps(s,{onFetched:()=>{zc(S,T)},onStaleFallback:(N,Ce)=>{let gn=Math.round(Ce/36e5),mn=gn>=48?`${Math.round(gn/24)}d`:`${gn}h`;c.log.warn(`registry fetch failed (${N.message}); serving stale cache last synced ${mn} ago; agent versions may be outdated ('hydra registry refresh' to retry)`)}});ai(N=>c.log.info(N));let b={info:N=>c.log.info(N),warn:N=>c.log.warn(N)},I=N=>ct.spawn({...N,stderrTailBytes:s.daemon.agentStderrTailBytes,logger:b});ea(s.compressToolContent);let A=new sr,T=new Ks(S,I,void 0,{idleTimeoutMs:s.daemon.sessionIdleTimeoutSeconds*1e3,...s.daemon.backgroundTaskTracking!==void 0?{backgroundTaskTracking:s.daemon.backgroundTaskTracking}:{},orphanTimeoutMs:s.daemon.nonInteractiveOrphanTimeoutSeconds*1e3,sessionDefaults:s.sessionDefaults,synopsisAgent:s.synopsisAgent,synopsisModel:s.synopsisModel,compactionAgent:s.compaction?.agent,compactionModel:s.compaction?.model,defaultTransformers:s.defaultTransformers,sessionHistoryMaxEntries:s.daemon.sessionHistoryMaxEntries,sessionHistoryArchiveMaxBytes:s.daemon.sessionHistoryArchiveMaxBytes,sessionHistoryArchiveTiers:s.daemon.sessionHistoryArchiveTiers,logger:b,npmRegistry:s.npmRegistry,extensionCommands:A,defaultCwd:s.defaultCwd,disableWorkspaceSnapshots:s.disableWorkspaceSnapshots}),R=new Sr(l,void 0,{resolvesLocally:async N=>await T.resolveCanonicalId(N)!==void 0,cache:h}),P=new tr(Li(s),void 0,{tokenRegistry:k}),$=new nr(Bi(s),void 0,{tokenRegistry:k}),H=[];_u(c,ue,Gc(s),()=>H);let J=new Date().toISOString();ju(c,J,t.requestShutdown);let z=new Tr,L=new Er,U,ee=()=>{if(U!==void 0)return U;let N=c.server.address();return U=`http://127.0.0.1:${N&&typeof N=="object"?N.port:s.daemon.port}`,U},se={agentId:s.defaultAgent,cwd:s.defaultCwd,publicHost:s.daemon.publicHost,host:s.daemon.host,port:s.daemon.port,compaction:s.compaction};Pu(c,T,se,{extensionMcp:L,mcpTokenRegistry:z,getDaemonOrigin:ee},l,h),Au(c,{store:l,localMiss:{resolvesLocally:async N=>await T.resolveCanonicalId(N)!==void 0,cache:h}}),Mu(c,S,T,{npmRegistry:s.npmRegistry}),Uu(c,P),Lu(c,$);let xe={host:s.daemon.host,port:s.daemon.port,...s.daemon.publicHost!==void 0?{publicHost:s.daemon.publicHost}:{},...s.daemon.tls?{tls:{cert:ie(s.daemon.tls.cert),key:ie(s.daemon.tls.key)}}:{}};Bu(c,()=>({defaultAgent:n.defaultAgent,defaultCwd:n.defaultCwd,sessionDefaults:{...n.sessionDefaults},...n.synopsisAgent!==void 0?{synopsisAgent:n.synopsisAgent}:{},...n.synopsisModel!==void 0?{synopsisModel:n.synopsisModel}:{},defaultTransformers:[...n.defaultTransformers],listen:xe})),Vu(c,{store:u,rateLimiter:f,staticTokenValidator:p}),nl(c,{store:l,health:w}),al(c,{processRegistry:k}),wl(c,z),bl(c,z);let vt=Il(c,z,L);ml(c,{validator:g,manager:T,defaultAgent:s.defaultAgent,processRegistry:k,onExtensionVersion:(N,Ce)=>P.reportVersion(N,Ce),onTransformerVersion:(N,Ce)=>$.reportVersion(N,Ce),transformers:$,extensionCommands:A,mcpTokenRegistry:z,extensionMcp:L,extensionMcpControls:vt,getDaemonOrigin:ee,registry:S,foreignSessions:R});let te=!!s.daemon.tls;await c.listen({host:te?"127.0.0.1":s.daemon.host,port:te?0:s.daemon.port});let Ze=c.server.address(),_t=Ze&&typeof Ze=="object"?Ze.port:s.daemon.port,os,Pl=s.daemon.host,Ri=_t;if(te&&r&&o){os=await vk({listenHost:s.daemon.host,listenPort:s.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:_t,tlsOptions:{key:r,cert:o},logger:c.log});let N=os.address();N&&typeof N=="object"&&(Ri=N.port)}await Xe.mkdir(E.home(),{recursive:!0}),await qc({pid:process.pid,host:Pl,port:Ri,loopbackPort:_t,startedAt:J});let xi={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:E.home()};P.setContext(xi),$.setContext(xi),await P.start(),await $.start();try{await T.reconcilePermissionFlags()}catch(N){c.log.warn(`permission flag reconcile failed: ${N.message}`)}try{await T.seedSessionIndex()}catch(N){c.log.warn(`session index seed failed: ${N.message}`)}T.resurrectPendingQueues().catch(N=>{c.log.warn(`queue replay scan failed: ${N.message}`)}),T.resumePendingCompactions().catch(N=>{c.log.warn(`compaction resume scan failed: ${N.message}`)}),T.resumePendingAgentSwaps().catch(N=>{c.log.warn(`agent-swap resume scan failed: ${N.message}`)});let Ti=s.daemon.agentSyncIntervalMinutes*60*1e3,Ei=Ti>0?Jc({registry:S,manager:T,intervalMs:Ti,logger:b}):void 0,Pi=s.daemon.sessionGcIntervalMinutes*60*1e3,Ml=s.daemon.sessionGcMaxAgeDays*24*60*60*1e3,Mi=Pi>0?Vc({manager:T,intervalMs:Pi,maxAgeMs:Ml,logger:b}):void 0,_l=Xc({bootConfig:s,apply:N=>{n=N,S.setConfig(N),T.setLiveConfig({sessionDefaults:N.sessionDefaults}),se.agentId=N.defaultAgent,se.cwd=N.defaultCwd,Lr(N.daemon.scrubEnv)},onDrift:N=>{H=N},logger:b});return{app:c,manager:T,registry:S,extensions:P,transformers:$,mcpTokenRegistry:z,extensionMcp:L,processRegistry:k,shutdown:async()=>{w.stop(),h.stop(),_l(),Mi&&Mi(),Ei&&Ei(),clearInterval(m),clearInterval(v);let N=async(Ce,gn)=>{try{await gn()}catch(mn){c.log.warn(`shutdown step ${Ce} failed: ${mn instanceof Error?mn.message:String(mn)}`)}};await N("sessionTokenStore.flush",()=>u.flush()),await N("extensions.stop",()=>P.stop()),await N("transformers.stop",()=>$.stop()),await N("manager.closeAll",()=>T.closeAll()),await N("manager.flushSynopsis",()=>T.flushSynopsis(3e4)),await N("manager.shutdownSynopsis",()=>T.shutdownSynopsis()),await N("manager.flushMetaWrites",()=>T.flushMetaWrites()),await N("manager.flushHistoryWrites",()=>T.flushHistoryWrites()),Vr(null),Qr(null),ai(null),os&&await N("tlsTerminator.close",()=>new Promise(Ce=>os.close(()=>Ce()))),await N("app.close",()=>c.close());try{Rl.unlinkSync(E.pidFile())}catch{}await N("fileStream.flushSync",()=>a.flushSync()),await N("fileStream.close",d)}}}var Cl=20;async function wk(s,e){let t=pn.dirname(s),n=pn.basename(s,".log"),r=new RegExp(`^${n}\\.(\\d+)\\.log$`),o;try{o=await Xe.readdir(t)}catch{return}let i=[];for(let d of o){let c=d.match(r);c&&i.push({name:d,n:Number(c[1])})}if(i.length<=e)return;i.sort((d,c)=>d.n-c.n);let a=i.slice(0,i.length-e);await Promise.allSettled(a.map(d=>Xe.unlink(pn.join(t,d.name))))}async function kk(s){await wk(E.logFile(),Cl);let e=await yk({file:E.logFile(),size:"10m",mkdir:!0,symlink:Xs,limit:{count:Cl,removeOtherLogFiles:!0}}),t=Al.destination(2),n=!1,r={write:a=>{n||e.write(a)}};return{stream:Al.multistream([{stream:r,level:s},{stream:t,level:s}]),fileStream:e,closeFile:()=>new Promise(a=>{n=!0,e.once("close",()=>a()),e.end()})}}async function vk(s){let e=Tl.createServer(s.tlsOptions,t=>{let n=xl.connect({host:s.upstreamHost,port:s.upstreamPort}),r=!1,o=i=>{if(!r){r=!0,i&&s.logger.warn(`tls terminator forwarder error: ${i.message??String(i)}`);try{t.destroy()}catch{}try{n.destroy()}catch{}}};t.on("error",o),n.on("error",o),t.on("close",()=>o()),n.on("close",()=>o()),t.pipe(n),n.pipe(t)});return e.on("tlsClientError",t=>{s.logger.warn(`tls handshake error: ${t.message}`)}),await new Promise((t,n)=>{let r=o=>{n(new Error(`TLS listener could not bind ${s.listenHost}:${s.listenPort}: ${o.message}`))};e.once("error",r),e.listen({host:s.listenHost,port:s.listenPort},()=>{e.off("error",r),t()})}),e.on("error",t=>{s.logger.warn(`tls terminator error: ${t.message}`)}),e}function bk(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 Sk(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:s}=await Promise.resolve().then(()=>(ns(),tl));s();let e=await kn(),t=await Oi(),n,r=()=>{n&&Ji(n)};n=await El(e,t,{requestShutdown:r}),process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
218
- `),process.on("SIGINT",r),process.on("SIGTERM",r),process.on("SIGHUP",()=>{})}Sk().catch(s=>{let e=s instanceof Error?s.stack??s.message:String(s);process.stderr.write(`hydra-acp-daemon: ${e}
219
- `),qi(e).catch(()=>{}).finally(()=>process.exit(1))});
219
+ `),a}function Ai(s,e){let t=s<0?e+s+1:s;return t<1?1:t>e?e:t}function Wy(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:h}of s)h.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=Ai(o-e.last+1,o):(e.from!==void 0&&(i=Ai(e.from,o)),e.to!==void 0&&(a=Ai(e.to,o))),i>a)return{events:[],window:{from:i,to:a,total:o}};let d=e.sinceMs,c=new Set;d!==void 0&&s.forEach((h,f)=>{h.recordedAt>=d&&c.add(n[f])});let u=[],l,y;return s.forEach((h,f)=>{let k=n[f];k<i||k>a||d!==void 0&&!c.has(k)||(u.push(h),l??=k,y=k)}),{events:u,window:{from:l??i,to:y??a,total:o}}}function qy(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=wd(n.update,{cwd:s.session.cwd});r!==null&&e.push({event:r,recordedAt:t.recordedAt})}return e}function zy(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 Jy(s,e){let t=e.session,n=nt(t.sessionId),r=t.title?.trim()||`Hydra session ${n}`;s.push(`# ${ss(r)}`),s.push("");let o=[];o.push(`- **Session:** \`${n}\` (lineage \`${t.lineageId}\`)`);let i=[t.agentId];t.currentModel&&i.push(`model: ${t.currentModel}`),t.currentMode&&i.push(`mode: ${t.currentMode}`),o.push(`- **Agent:** ${i.filter(Boolean).join(" \xB7 ")}`),o.push(`- **Cwd:** ${t.cwd}`),o.push(`- **Exported:** ${e.exportedAt} from ${e.exportedFrom.machine} (hydra ${e.exportedFrom.hydraVersion})`);let a=t.currentUsage;if(a&&(a.used!==void 0||a.costAmount!==void 0||a.cumulativeCost!==void 0)){let d=[];if(a.used!==void 0){let u=a.size!==void 0?`${Ci(a.size)}`:void 0;d.push(u?`${Ci(a.used)} / ${u} tokens`:`${Ci(a.used)} tokens`)}let c=li(a);if(c!==void 0){let u=a.costCurrency??"USD";d.push(`$${c.toFixed(2)} ${u}`)}o.push(`- **Usage:** ${d.join(" \xB7 ")}`)}s.push(o.join(`
220
+ `)),s.push("")}function Vy(s,e,t,n){let{includeTools:r,includeThoughts:o}=n;if(!e.some(k=>Gy(k.event,o))){s.push("_No conversation history recorded._"),s.push("");return}let i=0,a="",d="",c=[],u=new Set,l=!1,y=()=>{if(c.length!==0){for(let k of c)s.push(k);s.push(""),c=[]}},h=()=>{y(),d.length>0&&($u(s,d.trimEnd(),"*"),s.push(""),d=""),a.length!==0&&(s.push(a.trimEnd()),s.push(""),a="")},f=()=>{l||(l=!0)};for(let{event:k}of e)switch(k.kind){case"user-text":{h(),s.push("---"),s.push(""),i+=1,$u(s,k.text,"**"),s.push(""),l=!0;break}case"agent-text":f(),a+=k.text;break;case"agent-thought":{if(!o)break;f(),a.length>0&&(s.push(a.trimEnd()),s.push(""),a=""),d+=k.text;break}case"tool-call":{if(!r||(f(),(a.length>0||d.length>0)&&h(),u.has(k.toolCallId)))break;u.add(k.toolCallId);let g=t.get(k.toolCallId)??{title:k.title,status:k.status??"pending"};c.push(`- ${Qy(g.status)} ${Ky(g)}`);break}case"tool-call-update":break;case"plan":{f(),h(),s.push("**Plan:**"),s.push("");for(let g of k.entries){let p=g.status==="completed"?"[x]":"[ ]";s.push(`- ${p} ${ss(g.content)}`)}s.push("");break}case"mode-changed":f(),h(),s.push(`_mode: ${ss(k.mode)}_`),s.push("");break;case"model-changed":f(),h(),s.push(`_model: ${ss(k.model)}_`),s.push("");break;case"turn-complete":h();break;case"usage-update":case"available-commands":case"session-info":case"unknown":break}h()}function Gy(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 Ky(s){let e=s.status,t=e==="completed"||e===void 0?"":` _(${e})_`;return`${ss(s.title)}${t}`}function Qy(s){switch(s){case"completed":return"\u221A";case"failed":return"\xD7";case"cancelled":case"rejected":return"\xF7";case"in_progress":return"\u25B8";default:return"\xB7"}}var Ou=String.raw`<\/?[a-zA-Z][a-zA-Z0-9-]*(?:\s[^<>]*)?\/?>`,Yy=new RegExp(Ou);function $u(s,e,t){if(Yy.test(e)){Xy(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(`
221
+ `);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 Xy(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(`
222
+ `))s.push(o);s.push(r)}function ss(s){return s.replace(new RegExp(Ou,"g"),e=>e.replace(/</g,"&lt;").replace(/>/g,"&gt;"))}function Ci(s){return s.toLocaleString("en-US")}function Ae(s){return s==="127.0.0.1"||s==="::1"||s==="localhost"||s==="[::1]"}function Zy(s){let e=s.trim();if(e.length===0)return{operator:"OR",terms:[]};let t=/\w+:"[^"]*"|"[^"]*"|\S+/g,n=[],r;for(;(r=t.exec(e))!==null;)n.push(r[0]);let o="OR",i=!1,a=!1,d=[];for(let u of n){let l=u.toUpperCase();l==="AND"?i=!0:l==="OR"?a=!0:d.push(u)}i?o="AND":a&&(o="OR");let c=d.map(u=>ew(u)).filter(u=>u.term.length>0);return{operator:o,terms:c}}function ew(s){let e=/^(\w+):"([^"]*)"$/.exec(s);if(e)return{scope:Nu(e[1]),term:e[2]};let t=/^"([^"]*)"$/.exec(s);if(t)return{scope:"all",term:t[1]};let n=/^(prompt|response|tool|edit|edited):([\s\S]*)$/i.exec(s);return n?{scope:Nu(n[1]),term:n[2].trim()}:{scope:"all",term:s.trim()}}function Nu(s){switch(s.toLowerCase()){case"prompt":return"user";case"response":return"agent";case"tool":return"tool";case"edit":case"edited":return"edit";default:return"all"}}function tw(s,e){return e==="edit"?s==="edit":s==="edit"?!1:s==="all"?!0:s==="user"?e==="user":s==="agent"?e==="agent"||e==="thought":e==="tool"||e==="tool-input"}var nw=5,sw=200,Ar=72,rw=24,ow=512;function Uu(s){return Number.isFinite(s)?Math.max(rw,Math.min(ow,Math.floor(s))):Ar}async function Bu(s,e,t={}){let n=Zy(e);if(n.terms.length===0)return{query:e,truncated:!1,results:[]};let r=t.maxSnippetsPerSession??nw,o=t.maxSessions??sw,i=Uu(t.snippetWidth??Ar),a=t.sessionIds?new Set(t.sessionIds):null,d=await s.list(),c=a?d.filter(y=>a.has(y.sessionId)):d,u=[],l=!1;for(let y of c){if(u.length>=o){l=!0;break}let h=await s.loadHistory(y.sessionId,{tools:"references"}).catch(()=>[]),f=aw(h,n,r,i,iw(y));if(f.snippets.length===0)continue;let k={sessionId:y.sessionId,cwd:y.cwd,status:y.status,updatedAt:y.updatedAt,totalMatches:f.totalMatches,snippets:f.snippets};y.title!==void 0&&(k.title=y.title),u.push(k)}return{query:e,truncated:l,results:u}}function iw(s){let e=s.workspace?.sourceCwd;if(e===void 0||e.length===0||s.cwd.length===0)return;let t=s.cwd.endsWith("/")?s.cwd:s.cwd+"/";return n=>n.startsWith(t)?e.replace(/\/+$/,"")+"/"+n.slice(t.length):n}function aw(s,e,t,n=Ar,r){if(e.terms.length===0)return{totalMatches:0,snippets:[]};let o=0,i=[],a=Math.max(1,Math.floor(t/e.terms.length)),d=[];for(let{scope:c,term:u}of e.terms){let l=dw(s,u,c,t,n,r);if(e.operator==="AND"&&l.totalMatches===0)return{totalMatches:0,snippets:[]};o+=l.totalMatches,i.push(...l.snippets.slice(0,a)),d.push(...l.snippets.slice(a))}for(let c of d){if(i.length>=t)break;i.push(c)}return{totalMatches:o,snippets:i.slice(0,t)}}function dw(s,e,t,n,r,o){let i=e.toLowerCase(),a=0,d=[],c=new Set;for(let u of s){let l=cw(u).filter(y=>tw(t,y.kind));for(let y of l){let h=y.text.toLowerCase();if(y.kind==="edit"){let g=o?.(y.text);if(!(Du(y.text,e)||(g!==void 0&&g!==y.text?Du(g,e):!1))||c.has(y.text))continue;if(c.add(y.text),a+=1,d.length<n){let w={kind:"edit",text:y.text,recordedAt:u.recordedAt};y.toolName!==void 0&&(w.toolName=y.toolName),d.push(w)}continue}let f=h.indexOf(i);if(f===-1)continue;let k=0;for(;f!==-1;)k++,f=h.indexOf(i,f+i.length);if(a+=k,d.length<n){let g=h.indexOf(i),p={kind:y.kind,text:mw(y.text,g,i.length,r),recordedAt:u.recordedAt};y.toolName!==void 0&&(p.toolName=y.toolName),d.push(p)}}}return{totalMatches:a,snippets:d}}function cw(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=Ir(n.content);return o?[{kind:"agent",text:o}]:[]}case"agent_thought":case"agent_thought_chunk":{let o=typeof n.text=="string"?be(n.text):Ir(n.content);return o?[{kind:"thought",text:o}]:[]}case"user_message_chunk":{if(pw(n))return[];let o=Ir(n.content);return o?[{kind:"user",text:o}]:[]}case"prompt_received":{let o=gw(n.prompt);return o?[{kind:"user",text:o}]:[]}case"tool_call":case"tool_call_update":return uw(n);default:return[]}}function uw(s){let e=Hu(s,"name"),t=Hu(s,"title"),n=[];if(t!==void 0){let a=ae(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=ae(e);a.length>0&&n.push({kind:"tool",toolName:e,text:a})}let r=s.rawInput;if(r&&typeof r=="object"){let a=ju(r);if(a.length>0){let d={kind:"tool-input",text:ae(a)};e!==void 0&&(d.toolName=e),n.push(d)}}for(let a of pd(s)){let d={kind:"edit",text:a};e!==void 0&&(d.toolName=e),n.push(d)}let o=s.locations;if(Array.isArray(o)&&o.length>0){let a=ju(o);if(a.length>0){let d={kind:"tool-input",text:ae(a)};e!==void 0&&(d.toolName=e),n.push(d)}}let i=lw(s);if(i!==null){let a={kind:"tool",text:i};e!==void 0&&(a.toolName=e),n.push(a)}return n}function Du(s,e){let t=Lu(s.toLowerCase()),n=Lu(e.toLowerCase());if(n.length===0)return!1;if(n.startsWith("/"))return t===n||t.startsWith(n+"/");let r="/"+n,o=t.indexOf(r);for(;o!==-1;){let i=o+r.length;if(i===t.length||t[i]==="/")return!0;o=t.indexOf(r,o+1)}return t===n||t.startsWith(n+"/")}function Lu(s){return s.length>1&&s.endsWith("/")?s.slice(0,-1):s}function lw(s){if(!fw(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=ae(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=ae(n);if(r.length>0)return r}}return null}function fw(s){return s==="failed"||s==="rejected"||s==="cancelled"}function pw(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 Ir(s){if(typeof s=="string")return be(s);if(!s||typeof s!="object"||Array.isArray(s))return"";let e=s;return typeof e.text=="string"?be(e.text):""}function gw(s){if(!Array.isArray(s))return"";let e=[];for(let t of s){let n=Ir(t);n.length>0&&e.push(n)}return e.join("")}function Hu(s,e){let t=s[e];return typeof t=="string"?t:void 0}function ju(s){try{return JSON.stringify(s)}catch{return""}}function mw(s,e,t,n=Ar){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=Uu(n),c=Math.max(0,d-i.length),u=Math.floor(c/2),l=Math.min(u,a),y=Math.min(c-l,r.length-(a+i.length)),h=Math.max(0,a-(c-y)),f=Math.min(r.length,a+i.length+y),k=h>0?"\u2026":"",g=f<r.length?"\u2026":"";return`${k}${r.slice(h,f)}${g}`}import{randomBytes as qu}from"crypto";function Wu(s){let e=qu(32).toString("hex");return s.tokenRegistry.reserve(e).complete(s.session),s.session.onClose(()=>{s.tokenRegistry.unbind(e)}),{name:s.name,type:"http",url:`${s.getOrigin()}/mcp/${s.name}`,headers:[{name:"Authorization",value:`Bearer ${e}`}]}}function Ri(s){if(s.deps.mcpTokenRegistry===void 0||s.deps.getDaemonOrigin===void 0)return;let e=s.deps.mcpTokenRegistry,t=s.deps.getDaemonOrigin;return async n=>{let r=[...s.baselineMcpServers??[]];s.stdinEnabled&&r.push(Wu({name:"hydra-acp-stdin",session:n,tokenRegistry:e,getOrigin:t})),r.push(Wu({name:"hydra-acp-recall",session:n,tokenRegistry:e,getOrigin:t}));let o=fn(s.deps);return o!==void 0&&(o.bindToSession(n),r=[...r,...o.descriptors]),r}}function fn(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=qu(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 hw=new Set(["/v1/sessions/:id/history","/v1/sessions/:id/events"]);function zu(s,e){let t=e.fetchImpl??fetch;s.addHook("preHandler",async(n,r)=>{let o=n.routeOptions.url;if(!o||!o.startsWith("/v1/sessions/:id"))return;let i=n.params,a=i.id;if(typeof a!="string")return;let d=gt(a);if(!d){if(!e.localMiss||await e.localMiss.resolvesLocally(a))return;let p=e.localMiss.cache.findByLocalId(a);if(p.length===0)return;if(p.length>1){r.code(404).send({error:`Session "${a}" exists on more than one remote (${p.map(w=>w.name).join(", ")}). Address it as "<remote>:${a}".`});return}d=p[0]}let c=e.store.get(d.name);if(!c){r.code(404).send({error:`No remote named "${d.name}". Run \`hydra remote add\` first.`});return}let u=n.query;if(hw.has(o)&&ww(u?.follow)){let p=c.port===Dt?"":`:${c.port}`;r.code(501).send({error:`Streaming a federated session isn't supported yet. Attach directly with hydra://${c.host}${p}/${d.localId} instead.`});return}let l=kw(o,i,d.localId,n.url),h=`${Ae(c.host)?"http":"https"}://${c.host}:${c.port}${l}`,f;try{f=await t(h,{method:n.method,headers:{Authorization:`Bearer ${c.token}`,...n.body!==void 0?{"Content-Type":"application/json"}:{}},...n.body!==void 0&&n.method!=="GET"?{body:JSON.stringify(n.body)}:{}})}catch(p){r.code(502).send({error:`Could not reach remote "${d.name}" (${c.host}:${c.port}): ${p.message}`});return}if(n.method==="DELETE"&&o==="/v1/sessions/:id"&&(f.ok||f.status===404)&&e.localMiss?.cache.evict(d.name,d.localId),f.status===204){r.code(204).send();return}let k=await f.text(),g=f.headers.get("content-type");g&&r.header("content-type",g),r.code(f.status).send(k)})}var yw=5e3,Cr=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;perPeer=new Map;timer;start(){this.timer||(this.refreshNow(),this.timer=setInterval(()=>{this.refreshNow()},this.opts.intervalMs??yw),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}async refreshNow(){let e=this.opts.fetchImpl??fetch,t=new Set(this.store.list().map(n=>n.name));for(let n of[...this.perPeer.keys()])t.has(n)||this.perPeer.delete(n);await Promise.allSettled(this.store.list().map(async n=>{let r=this.store.get(n.name);if(!r)return;let o=this.perPeer.get(n.name),i=Ae(r.host)?"http":"https",a=new URLSearchParams({includeNonInteractive:"1"}),d=o?.cursor!==void 0;d&&a.set("since",String(o.cursor));let c=`${i}://${r.host}:${r.port}/v1/sessions?${a.toString()}`,u;try{u=await e(c,{headers:{Authorization:`Bearer ${r.token}`}})}catch{return}if(!u.ok)return;let l=await u.json(),y=o?.sessions??new Map;if(d){for(let[h,f]of[...y])f.status!=="cold"&&y.delete(h);for(let h of l.removed??[])y.delete(Je({name:n.name,localId:h}))}else y.clear();for(let h of l.sessions??[]){let f=Je({name:n.name,localId:String(h.sessionId)});y.set(f,{...h,sessionId:f,remote:n.name})}this.perPeer.set(n.name,{cursor:l.cursor,sessions:y})}))}list(e){let t=[];for(let n of this.perPeer.values())t.push(...n.sessions.values());return t.filter(n=>!(e.status&&n.status!==e.status||!e.includeNonInteractive&&n.interactive!==!0))}evict(e,t){this.perPeer.get(e)?.sessions.delete(Je({name:e,localId:t}))}findByLocalId(e){let t=e.startsWith(ye)?[e]:[e,ye+e],n=[];for(let[r,o]of this.perPeer)for(let i of t)if(o.sessions.has(Je({name:r,localId:i}))){n.push({name:r,localId:i});break}return n}};async function Ju(s,e,t,n=fetch){let r=s.get(e);if(!r)return{status:404,body:{error:`No remote named "${e}". Run \`hydra remote add\` first.`}};let i=`${Ae(r.host)?"http":"https"}://${r.host}:${r.port}/v1/sessions`,a;try{a=await n(i,{method:"POST",headers:{Authorization:`Bearer ${r.token}`,"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(l){return{status:502,body:{error:`Could not reach remote "${e}" (${r.host}:${r.port}): ${l.message}`}}}let d=await a.text(),c=null;try{c=d.length>0?JSON.parse(d):null}catch{c=null}if(!a.ok)return{status:a.status,body:c};let u=c;return u&&typeof u.sessionId=="string"?{status:a.status,body:{...u,sessionId:Je({name:e,localId:u.sessionId})}}:{status:a.status,body:c}}async function Vu(s,e,t=fetch){let n;if(e.sessionIds===void 0)n=s.list().map(a=>({name:a.name}));else{let a=new Map;for(let d of e.sessionIds){let c=gt(d);if(!c)continue;let u=a.get(c.name)??[];u.push(c.localId),a.set(c.name,u)}n=[...a.entries()].map(([d,c])=>({name:d,sessionIds:c}))}if(n.length===0)return{query:e.q,truncated:!1,results:[]};let r=await Promise.all(n.map(async a=>{let d=s.get(a.name);if(!d)return null;let u=`${Ae(d.host)?"http":"https"}://${d.host}:${d.port}/v1/sessions/search`,l;try{l=await t(u,{method:"POST",headers:{Authorization:`Bearer ${d.token}`,"Content-Type":"application/json"},body:JSON.stringify({q:e.q,...a.sessionIds?{sessionIds:a.sessionIds}:{},...e.snippetWidth!==void 0?{snippetWidth:e.snippetWidth}:{}})})}catch{return null}if(!l.ok)return null;let y;try{y=await l.json()}catch{return null}let h=y;if(!h||!Array.isArray(h.results))return null;let f=h.results.map(k=>({...k,sessionId:Je({name:a.name,localId:k.sessionId})}));return{query:e.q,truncated:h.truncated===!0,results:f}})),o=[],i=!1;for(let a of r)a!==null&&(o.push(...a.results),i=i||a.truncated);return{query:e.q,truncated:i,results:o}}function ww(s){return s==="1"||s==="true"||s===!0}function kw(s,e,t,n){let r=s.replace(/:([A-Za-z_]+)/g,(i,a)=>encodeURIComponent(a==="id"?t:e[a]??"")),o=n.indexOf("?");return o===-1?r:r+n.slice(o)}var Rr=new Set(["usage_update","tool_call","tool_call_update","prompt_received","turn_complete","permission_resolved"]);function Gu(s){if(s.publicHost&&s.publicHost.length>0)return s.publicHost;if(s.host&&!Ae(s.host))return s.port!==void 0?`${s.host}:${s.port}`:s.host}function Yu(s,e,t,n={},r,o){s.get("/v1/sessions",async(h,f)=>{let k=h.query,g=k?.includeNonInteractive==="1"||k?.includeNonInteractive==="true",p;if(k?.since!==void 0&&(p=Number(k.since),!Number.isFinite(p)||p<0))return f.code(400).send({error:`since must be a non-negative number, got ${JSON.stringify(k.since)}`});let w=k?.status==="warm"||k?.status==="cold"?k.status:void 0,m={cwd:k?.cwd,includeNonInteractive:g,...w?{status:w}:{}},v=o&&!m.cwd?o.list({includeNonInteractive:g,...w?{status:w}:{}}):[];if(p!==void 0){let b=await e.listSince(m,p);return{sessions:[...b.entries,...v],removed:b.removed,cursor:b.cursor}}let S=await e.listing(m);return{sessions:[...S.entries,...v],removed:[],cursor:S.cursor}}),s.get("/v1/sessions/:id",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=await e.getOne(g);return p||(f.code(404).send({error:"session not found"}),f)}),s.post("/v1/sessions/search",async(h,f)=>{let k=h.body??{},g=typeof k.q=="string"?k.q:"";if(g.trim().length===0)return f.code(400).send({error:"q is required"}),f;let p=Array.isArray(k.sessionIds)?k.sessionIds.filter(S=>typeof S=="string"&&S.length>0):void 0,w={sessionIds:p};typeof k.snippetWidth=="number"&&(w.snippetWidth=k.snippetWidth);let m=await Bu(e,g,w);if(!r)return m;let v=await Vu(r,{q:g,...p?{sessionIds:p}:{},...w.snippetWidth!==void 0?{snippetWidth:w.snippetWidth}:{}});return{query:g,truncated:m.truncated||v.truncated,results:[...m.results,...v.results]}}),s.post("/v1/sessions",async(h,f)=>{let k=h.body??{};if(k.remote){if(!r)return f.code(404).send({error:`No remote named "${k.remote}". Run \`hydra remote add\` first.`});let S=await Ju(r,k.remote,{cwd:k.cwd,agentId:k.agentId,mcpServers:k.mcpServers,workspace:k.workspace});return f.code(S.status).send(S.body)}let g=ie(k.cwd??t.cwd),p=await Sn(g),w=k.agentId??p.agentId??t.agentId,m=fn(n),v=m!==void 0?[...k.mcpServers??[],...m.descriptors]:k.mcpServers;try{let S=await e.create({cwd:g,agentId:w,mcpServers:v,...k.workspace!==void 0?{workspace:k.workspace}:{}});m!==void 0&&m.bindToSession(S),f.code(201).send({sessionId:S.sessionId,agentId:S.agentId,cwd:S.cwd,...S.workspace!==void 0?{workspace:S.workspace}:{},...S.workspaceError!==void 0?{workspaceError:S.workspaceError}:{}})}catch(S){m!==void 0&&m.abandon(S instanceof Error?S:void 0),f.code(500).send({error:S.message})}}),s.post("/v1/sessions/collect",async(h,f)=>{let k=h.body??{},g=typeof k.maxAgeDays=="number"&&k.maxAgeDays>0?k.maxAgeDays*24*60*60*1e3:0,p=typeof k.limit=="number"&&k.limit>0?k.limit:1e3,w=k.selection==="explicit"||k.selection==="unpromoted"?k.selection:"unpromoted";try{let m=await Si({manager:e,maxAgeMs:g,maxDeletions:p,selection:w,verbose:!1});f.code(200).send(m)}catch(m){f.code(500).send({error:m.message})}}),s.get("/v1/sessions/tombstones",async(h,f)=>{let k=h.query;if(k.since!==void 0&&Number.isNaN(Date.parse(k.since))){f.code(400).send({error:"since must be an ISO timestamp"});return}let g=await e.listTombstones({...k.agent?{agentId:k.agent}:{},...k.since?{since:k.since}:{},...k.grep?{grep:k.grep}:{}});f.code(200).send({tombstones:g})}),s.post("/v1/sessions/undelete",async(h,f)=>{let k=h.body??{};if(!Array.isArray(k.ids)||k.ids.length===0||!k.ids.every(g=>typeof g=="string"&&g.length>0)){f.code(400).send({error:"ids must be a non-empty array of strings"});return}try{f.code(200).send(await e.undeleteSessions(k.ids))}catch(g){f.code(500).send({error:g.message})}}),s.post("/v1/sessions/:id/kill",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=e.get(g);if(p){p.close({deleteRecord:!1,by:"REST POST /kill"}).catch(()=>{}),f.code(202).send();return}if(!await e.hasRecord(g)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.post("/v1/sessions/:id/stdin/open",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=e.get(g);if(!p)return f.code(404).send({error:"session not found"}),f;let w=h.body??{},m={};(w.mode==="memory"||w.mode==="file")&&(m.mode=w.mode),typeof w.capacityBytes=="number"&&(m.capacityBytes=w.capacityBytes),typeof w.fileCapBytes=="number"&&(m.fileCapBytes=w.fileCapBytes),(m.mode??"memory")==="file"&&(m.filePathFor=v=>rs.join(Ku.tmpdir(),`hydra-acp-stdin-${v}.log`));try{return p.openStream(m)}catch(v){return f.code(409).send({error:v.message}),f}}),s.post("/v1/sessions/:id/stdin",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=e.get(g);if(!p)return f.code(404).send({error:"session not found"}),f;let w=h.body??{},m=typeof w.chunk=="string"?w.chunk:"",v=w.eof===!0;try{return p.streamWrite(m,v)}catch(S){return f.code(409).send({error:S.message}),f}}),s.patch("/v1/sessions/:id",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=h.body??{};if(p.cwd!==void 0){if(typeof p.cwd!="string"||!rs.isAbsolute(p.cwd)){f.code(400).send({error:"cwd must be an absolute path"});return}let m=await e.setCwd(g,p.cwd);if(m==="missing"){f.code(404).send({error:"session not found"});return}if(m==="not-a-directory"){f.code(400).send({error:`${p.cwd} is not a directory`});return}if(m==="live"){f.code(409).send({error:"session is live; its agent was spawned in its cwd and cannot change directory. Moving a live session is a swap \u2014 use `workspace start` in it."});return}if(m==="bound"){f.code(409).send({error:"session is isolated, so its cwd IS its workspace. Clear the binding first (PATCH { workspace: null }) or leave the workspace from inside the session."});return}f.code(204).send();return}if("workspace"in p){if(p.workspace!==null){f.code(400).send({error:"workspace may only be set to null (clear the binding)"});return}let m=await e.clearWorkspaceBinding(g);if(m==="missing"){f.code(404).send({error:"session not found"});return}if(m==="live"){f.code(409).send({error:"session is live; its cwd is the workspace. Use `workspace stop` or `workspace detach` in the session so the agent moves with the binding."});return}f.code(204).send();return}if(p.priority!==void 0){let m=p.priority,v;if(m===null||m===0)v=void 0;else if(typeof m=="number"&&Number.isInteger(m)&&m>0)v=m;else{f.code(400).send({error:"priority must be a non-negative integer (or null to clear)"});return}if(!await e.setPriority(g,v)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(p.tags!==void 0){let m=p.tags;if(m!==null&&!Array.isArray(m)){f.code(400).send({error:"tags must be an array of strings (or null to clear)"});return}let v=m===null?[]:m;if(v.filter(I=>typeof I!="string"||en(I)===void 0).length>0||v.length>16){f.code(400).send({error:`tags must be at most ${16} strings of letters, digits, . _ / -`});return}if(!await e.setTags(g,v)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(p.read!==void 0){if(typeof p.read!="boolean"){f.code(400).send({error:"read must be a boolean"});return}if(!await e.setRead(g,p.read)){f.code(404).send({error:"session not found"});return}f.code(204).send();return}if(p.regen===!0){if(!(e.get(g)!==void 0||await e.hasRecord(g))){f.code(404).send({error:"session not found"});return}e.scheduleSynopsis(g),f.code(202).send();return}if(typeof p.title!="string"||p.title.trim().length===0){f.code(400).send({error:"title must be a non-empty string"});return}if(!await e.setTitle(g,p.title)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.delete("/v1/sessions/:id",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=e.get(g);if(p){await p.close({deleteRecord:!0,by:"REST DELETE /v1/sessions"}),await e.waitForDeletion(g),await e.hasRecord(g)&&await e.deleteRecord(g),f.code(204).send();return}if(!await e.deleteRecord(g)){f.code(404).send({error:"session not found"});return}f.code(204).send()}),s.get("/v1/sessions/:id/export",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=h.query?.tools,w=p==="references"?"references":zc(p),m=await e.exportBundle(g,w==="references"?{tools:"references"}:{});if(!m){f.code(404).send({error:"session not found"});return}let v=zn({record:m.record,history:w==="summary"?Jc(m.history,"summary"):m.history,promptHistory:m.promptHistory.length>0?m.promptHistory:void 0,...m.toolBlobs!==void 0?{toolBlobs:m.toolBlobs}:{},hydraVersion:ue,machine:At(),hydraHost:Gu(t)}),S=new Date().toISOString().replace(/[:.]/g,"-");f.header("Content-Disposition",`attachment; filename="${g}-${S}.hydra"`),f.code(200).send(v)}),s.get("/v1/sessions/:id/diff",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=await e.exportBundle(g,{includeArchivedHistory:!0});if(!p){f.code(404).send({error:"session not found"});return}let w=h.query??{},m=w.fold==="true"||w.fold==="1",v=typeof w.paths=="string"&&w.paths.length>0?new Set(w.paths.split(",").map(b=>b.trim()).filter(b=>b.length>0)):void 0,S=Mu(p.history);v&&(S=S.filter(b=>v.has(b.path))),m&&(S=S.map(b=>({...b,hunks:_u(b.hunks)}))),f.code(200).send(S)}),s.get("/v1/sessions/:id/tools/:hash",async(h,f)=>{let k=h.params,g=await e.resolveCanonicalId(k.id)??k.id,p=await e.loadToolBlob(g,k.hash);if(p===null){f.code(404).send({error:"tool blob not found"});return}f.header("Content-Type","text/plain; charset=utf-8"),f.code(200).send(p)}),s.get("/v1/sessions/:id/transcript",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=await e.exportBundle(g);if(!p){f.code(404).send({error:"session not found"});return}let w=zn({record:p.record,history:p.history,promptHistory:p.promptHistory.length>0?p.promptHistory:void 0,hydraVersion:ue,machine:At(),hydraHost:Gu(t)}),m=h.query,v=I=>I==="1"||I==="true"||I==="yes",S=I=>{let A=m?.[I];if(A===void 0||A==="")return;let T=Number(A);return Number.isFinite(T)?T:"bad"},b={};for(let I of["from","to","last","since"]){let A=S(I);if(A==="bad"){f.code(400).send({error:`${I} must be a number`});return}A!==void 0&&(b[I==="since"?"sinceMs":I]=A)}f.header("Content-Type","text/markdown; charset=utf-8"),f.code(200).send(Fu(w,{includeTools:v(m?.tools),includeThoughts:v(m?.thoughts),...b}))});let i=h=>async(f,k)=>{let g=f.params.id,p=await e.resolveCanonicalId(g)??g,w=f.body??{},m={};if(w.forkAt!==void 0){if(typeof w.forkAt!="string"||w.forkAt.length===0){k.code(400).send({error:"forkAt must be a non-empty string"});return}m.forkAt=w.forkAt}if(w.cwd!==void 0){if(typeof w.cwd!="string"||w.cwd.length===0){k.code(400).send({error:"cwd must be a non-empty string"});return}m.cwd=ie(w.cwd)}if(w.agentId!==void 0){if(typeof w.agentId!="string"||w.agentId.length===0){k.code(400).send({error:"agentId must be a non-empty string"});return}m.agentId=w.agentId}if(w.title!==void 0){if(typeof w.title!="string"){k.code(400).send({error:"title must be a string"});return}m.title=w.title}if(h){let v=w.selection;if(v!==void 0){if(typeof v.text!="string"||v.text.length===0){k.code(400).send({error:"selection.text must be a non-empty string"});return}m.side={selection:{text:v.text,...typeof v.responsePartId=="string"?{responsePartId:v.responsePartId}:{}}}}else m.side={}}if(w.mode!==void 0&&!h){if(w.mode!=="verbatim"&&w.mode!=="synthesis"){k.code(400).send({error:'mode must be "verbatim" or "synthesis"'});return}m.mode=w.mode}if(w.model!==void 0){if(typeof w.model!="string"||w.model.length===0){k.code(400).send({error:"model must be a non-empty string"});return}m.model=w.model}try{let v=await e.forkSession(p,m);k.code(201).send(v)}catch(v){let S=v;if(S.code===x.SessionNotFound){k.code(404).send({error:S.message});return}if(S.code===x.InvalidParams||S.code===x.AgentNotInstalled){k.code(400).send({error:S.message});return}k.code(500).send({error:S.message})}};s.post("/v1/sessions/:id/fork",i(!1)),s.post("/v1/sessions/:id/side",i(!0)),s.post("/v1/sessions/:id/rewind",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=(h.body??{}).keepThrough;if(p!==null&&(typeof p!="string"||p.length===0)){f.code(400).send({error:"keepThrough must be a non-empty messageId, or null to drop every turn"});return}try{f.code(200).send(await e.rewindSession(g,p))}catch(w){let m=w;if(m.code===x.SessionNotFound){f.code(404).send({error:m.message});return}if(m.code===x.InvalidParams){f.code(400).send({error:m.message});return}if(m.code===x.InvalidRequest){f.code(409).send({error:m.message});return}f.code(500).send({error:m.message})}}),s.post("/v1/sessions/import",async(h,f)=>{let k=h.body??{};if(k.bundle===void 0){f.code(400).send({error:"missing bundle"});return}let g;if(k.cwd!==void 0){if(typeof k.cwd!="string"||k.cwd.length===0){f.code(400).send({error:"cwd must be a non-empty string"});return}g=k.cwd}let p;try{p=eu(k.bundle)}catch(w){f.code(400).send({error:"invalid bundle",details:w.message});return}try{let w=await e.importBundle(p,{replace:k.replace===!0,...g!==void 0?{cwd:g}:{}});f.code(201).send(w)}catch(w){let m=w;if(m.code===x.BundleAlreadyImported){f.code(409).send({error:"bundle already imported",existingSessionId:m.existingSessionId});return}f.code(500).send({error:m.message})}}),s.get("/v1/sessions/:id/compact/status",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=e.get(g),w;if(p?w=p.summarizedThroughEntry:w=await e.getSummarizedThroughEntry(g),w===void 0&&!await e.hasRecord(g))return f.code(404).send({error:"session not found"}),f;let m=await e.getCompactionState(g),v=await e.getRollbackBreadcrumb(g),S=await e.getPendingAgentSwap(g),b=!1,I,A=p?.currentUsage,T=typeof A?.used=="number"&&typeof A?.size=="number"&&A.size>0?{used:A.used,size:A.size}:void 0,R=await e.loadHistory(g,{tools:"references",maxEntries:1/0}).catch(()=>[]);if(R.length>0&&t.compaction){let P=w??0,$=R.length,L=P<=R.length?P:0,J=R.slice(L),z=Eu(J);I=Ii(z);let U=p?.currentModel,j=R.at(-1).recordedAt;b=Pu({summarizedThroughEntry:P,totalEntries:$,unsummarizedChars:z,compactionInFlight:e.getCompactionInFlight(),currentModel:U,lastActivityMs:j,nowMs:Date.now(),config:t.compaction,...typeof A?.used=="number"?{agentReportedUsed:A.used}:{},...typeof A?.size=="number"?{agentReportedSize:A.size}:{}})}return{summarizedThroughEntry:w??void 0,inFlight:e.getCompactionInFlight(),shouldCompact:b,...I!=null?{approxTokens:I}:{},...T!=null?{currentUsage:T}:{},...m!=null?{compactionState:m}:{},...v!=null?{rollbackBreadcrumb:v}:{},...S!=null?{pendingAgentSwap:S}:{}}}),s.post("/v1/sessions/:id/compact",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k;if(e.get(g)){e.scheduleCompaction(g),f.code(202).send({scheduled:!0});return}if(!await e.hasRecord(g)){f.code(404).send({error:"session not found"});return}e.scheduleCompaction(g),f.code(202).send({scheduled:!0})}),s.post("/v1/sessions/:id/compact/rollback",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k;if(!await e.hasRecord(g)){f.code(404).send({error:"session not found"});return}try{await e.performUncompact(g),f.code(202).send({rolledBack:!0})}catch(p){let w=p instanceof Error?p.message:String(p);f.code(409).send({error:w})}}),s.post("/v1/sessions/:id/workspace/clean",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=h.body??{};if(p.deep!==void 0&&typeof p.deep!="boolean"){f.code(400).send({error:"deep must be a boolean"});return}if(!await e.hasRecord(g)){f.code(404).send({error:"session not found"});return}if(e.get(g)===void 0){f.code(409).send({error:"session is not live. Cleaning rewrites the workspace under a running agent, so it is only available inside a live session (`/hydra workspace clean`). For a cold workspace use `hydra workspace remove` instead."});return}try{let w=await e.runWorkspaceAction(g,"clean",void 0,{deep:p.deep===!0});f.code(202).send({report:w})}catch(w){f.code(409).send({error:w instanceof Error?w.message:String(w)})}}),s.get("/v1/sessions/:id/history/page",async(h,f)=>{let k=h.params.id,g=h.query,p=Number(g?.beforeSeq);if(g?.beforeSeq===void 0||g.beforeSeq===""||!Number.isFinite(p)){f.code(400).send({error:"beforeSeq must be a number"});return}let w=g.turns===void 0||g.turns===""?10:Number(g.turns);if(!Number.isInteger(w)||w<1){f.code(400).send({error:"turns must be a positive integer"});return}let m=await e.resolveCanonicalId(k)??k,v=await e.pageHistory(m,{beforeSeq:p,turns:Math.min(w,100)});if(!v){f.code(404).send({error:"session not found"});return}f.code(200).send({entries:v.entries,hasMore:v.hasMore})}),s.get("/v1/sessions/:id/history",async(h,f)=>{let k=h.params.id,g=h.query,p=g?.follow==="1"||g?.follow==="true",w=await e.resolveCanonicalId(k)??k,m=e.get(w),v,S,b=!1,I=1e4,A=[];if(m){p&&(S=m.onBroadcast(R=>{f.raw.writableEnded||(b?f.raw.write(JSON.stringify(R)+`
223
+ `):(A.push(R),A.length>I&&A.shift()))})),h.raw.on("close",()=>{S?.(),f.raw.writableEnded||f.raw.end()});try{v=await m.getHistorySnapshot()}catch(R){throw S?.(),R}}else{let R=await e.getHistory(w);if(R===void 0)return f.code(404).send({error:"session not found"}),f;v=R}f.raw.setHeader("Content-Type","application/x-ndjson"),f.raw.setHeader("Cache-Control","no-cache"),f.raw.statusCode=200;let T=new Set;for(let R of v??[]){f.raw.write(JSON.stringify(R)+`
224
+ `);let P=R;typeof P.recordedAt=="number"&&T.add(String(P.recordedAt))}for(;A.length>0;){let R=A.splice(0,A.length);for(let P of R){let $=P,L=typeof $.recordedAt=="number"?String($.recordedAt):"";L&&T.has(L)||f.raw.write(JSON.stringify(P)+`
225
+ `)}}return b=!0,S||f.raw.end(),f});function a(h,f,k){let g=typeof h=="string"?h.trim():"";if(g.length===0)return null;let p;try{p=JSON.parse(g)}catch{return console.debug("events endpoint: skipping malformed JSONL line"),null}if(!p||typeof p!="object"||Array.isArray(p))return console.debug("events endpoint: skipping non-object JSONL line"),null;let w=p;if(typeof w.recordedAt!="number"||k!==void 0&&w.recordedAt<k||typeof w.params!="object"||w.params===null||Array.isArray(w.params))return null;let m=w.params;if(typeof m.update!="object"||m.update===null||Array.isArray(m.update))return null;let S=m.update.sessionUpdate;return typeof S!="string"||!f.has(S)?null:{recordedAt:w.recordedAt,entry:p}}function d(h,f,k){let p=f.params.update,w={sessionId:h,ts:new Date(f.recordedAt).toISOString(),kind:k,update:p};return p.messageId!==void 0&&p.messageId!==null&&(w.messageId=p.messageId),w}async function*c(h,f,k,g){for await(let p of f){let w=a(p,k,g);if(w){let m=w.entry.params.update.sessionUpdate;yield{ts:w.recordedAt,row:d(h,w.entry,m)}}}}async function u(h,f,k){let g=new Map;try{for(let w of await pn.promises.readdir(E.sessionDir(h))){let m=/^history\.jsonl\.(\d+)(\.gz)?$/.exec(w);if(!m)continue;let v=Number.parseInt(m[1],10);(m[2]!==void 0||!g.has(v))&&g.set(v,rs.join(E.sessionDir(h),w))}}catch(w){if(w.code!=="ENOENT")throw w}let p=[];for(let w of[...g.keys()].sort((m,v)=>m-v)){let m=g.get(w);if(k!==void 0)try{if((await pn.promises.stat(m)).mtimeMs<k)continue}catch{continue}p.push(m)}return p.push(f),p}async function l(h,f,k,g){let p=await u(h,f,g),w=null,m=!1;async function*v(){for(let T of p){if(m)return;let R=pn.createReadStream(T),P=R;if(T.endsWith(".gz")){let L=Qu.createGunzip();R.on("error",J=>L.destroy(J)),P=R.pipe(L)}let $=xi.createInterface({input:P,crlfDelay:1/0});w=$;try{yield*$}catch(L){if(L.code==="ENOENT")continue;throw L}finally{$.close(),R.destroy()}}}let S={close(){m=!0,w?.close()}},b=c(h,v(),k,g),I=await b.next(),A=I.done?null:I.value;return{sessionId:h,rl:S,gen:b,current:A,exhausted:A===null}}async function y(h){let f=await h.gen.next();f.done?(h.exhausted=!0,h.current=null):h.current=f.value}s.get("/v1/sessions/events",async(h,f)=>{let k=h.query,g=k.kinds;if(!g||g.trim().length===0)return f.code(400).send({error:"kinds parameter is required"}),f;let p=g.split(",").map(I=>I.trim());if(p.length===0)return f.code(400).send({error:"kinds parameter is required"}),f;for(let I of p)if(!Rr.has(I))return f.code(400).send({error:`kind "${I}" is not queryable; allowed kinds: ${[...Rr].join(", ")}`}),f;let w=new Set(p),m;if(k.since!==void 0&&k.since.trim().length>0){let I=new Date(k.since);if(isNaN(I.getTime()))return f.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),f;m=I.getTime()}let v=await e.list({includeNonInteractive:!0}),S=m!==void 0?v.filter(I=>new Date(I.updatedAt).getTime()>=m):v;f.raw.setHeader("content-type","application/x-ndjson"),f.raw.statusCode=200;let b=[];for(let I of S)try{let A=E.historyFile(I.sessionId),T=await l(I.sessionId,A,w,m);T.exhausted||b.push(T)}catch(A){if(A.code==="ENOENT")continue;throw A}h.raw.on("close",()=>{for(let I of b)try{I.rl.close()}catch{}f.raw.writableEnded||f.raw.end()});try{for(;b.length>0;){let I=-1,A=1/0;for(let R=0;R<b.length;R++){let P=b[R];P.current!==null&&P.current.ts<A&&(A=P.current.ts,I=R)}if(I===-1)break;let T=b[I];if(f.raw.write(JSON.stringify(T.current.row)+`
226
+ `),await y(T),T.exhausted){try{T.rl.close()}catch{}b.splice(I,1)}}}catch(I){for(let A of b)try{A.rl.close()}catch{}throw I}return f.raw.end(),f}),s.get("/v1/sessions/:id/events",async(h,f)=>{let k=h.params.id,g=h.query,p=await e.resolveCanonicalId(k)??k;if(!e.get(p)&&!await e.hasRecord(p))return f.code(404).send({error:"session not found"}),f;let m=g.kinds;if(!m||m.trim().length===0)return f.code(400).send({error:"kinds parameter is required"}),f;let v=m.split(",").map(R=>R.trim());if(v.length===0)return f.code(400).send({error:"kinds parameter is required"}),f;for(let R of v)if(!Rr.has(R))return f.code(400).send({error:`kind "${R}" is not queryable; allowed kinds: ${[...Rr].join(", ")}`}),f;let S=new Set(v),b;if(g.since!==void 0&&g.since.trim().length>0){let R=new Date(g.since);if(isNaN(R.getTime()))return f.code(400).send({error:"since is not a valid ISO-8601 timestamp"}),f;b=R.getTime()}let I=E.historyFile(p),A=pn.createReadStream(I),T=xi.createInterface({input:A,crlfDelay:1/0});f.raw.setHeader("content-type","application/x-ndjson"),f.raw.statusCode=200;try{for await(let R of T){let P=typeof R=="string"?R.trim():"";if(P.length===0)continue;let $;try{$=JSON.parse(P)}catch{console.debug("events endpoint: skipping malformed JSONL line in %s",I);continue}if(!$||typeof $!="object"||Array.isArray($)){console.debug("events endpoint: skipping non-object JSONL line in %s",I);continue}let L=$;if(typeof L.recordedAt!="number"||typeof L.params!="object"||L.params===null||Array.isArray(L.params))continue;let J=L.params;if(typeof J.update!="object"||J.update===null||Array.isArray(J.update))continue;let z=J.update,U=z.sessionUpdate;if(typeof U!="string"||!S.has(U)||b!==void 0&&L.recordedAt<b)continue;let j={ts:new Date(L.recordedAt).toISOString(),kind:U,update:z};z.messageId!==void 0&&z.messageId!==null&&(j.messageId=z.messageId),f.raw.write(JSON.stringify(j)+`
227
+ `)}}catch(R){if(R.code==="ENOENT")return f.raw.end(),f;throw R}return f.raw.end(),f}),s.post("/v1/sessions/:id/prompt/:messageId/notify",async(h,f)=>{let k=h.params,g=k.id,p=await e.resolveCanonicalId(g)??g,w=k.messageId,m=h.body,v=typeof m?.callbackUrl=="string"?m.callbackUrl:"",S=typeof m?.secret=="string"?m.secret:"";if(!w||!v||!S){f.code(400).send({error:"messageId, callbackUrl, and secret are all required"});return}let b;try{b=new URL(v)}catch{f.code(400).send({error:"callbackUrl must be a valid absolute URL"});return}if(b.protocol!=="https:"&&b.protocol!=="http:"){f.code(400).send({error:"callbackUrl must be http or https"});return}let I=e.get(p);if(!I){f.code(404).send({error:"session not found or not warm"});return}let A=I.registerTurnNotify(w,v,S);if(A.alreadyTerminal){f.code(200).send({status:"already_terminal",stopReason:A.stopReason});return}f.code(202).send({status:"registered"})}),s.get("/v1/sessions/:id/attention",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,p=e.get(g);return!p&&!await e.hasRecord(g)?(f.code(404).send({error:"session not found"}),f):p?{flags:p.listAttentionFlags()}:{flags:(await e.store.read(g))?.attentionFlags??[]}}),s.get("/v1/sessions/attention",async(h,f)=>{let k=h.query;if(!k.source||k.source.trim().length===0)return f.code(400).send({error:"source query parameter is required"}),f;let g=await e.list({includeNonInteractive:!0}),p=[];for(let w of g){let m=e.get(w.sessionId),v;m?v=m.listAttentionFlags():v=(await e.store.read(w.sessionId))?.attentionFlags??[];for(let S of v)S.source===k.source&&p.push({...S,sessionId:w.sessionId})}return{flags:p}}),s.post("/v1/sessions/:id/attention/clear",async(h,f)=>{let k=h.params.id,g=await e.resolveCanonicalId(k)??k,w=h.body??{},m=typeof w.source=="string"?w.source:"",v=typeof w.reason=="string"?w.reason:"";if((m.length>0||v.length>0)&&!(m.length>0&&v.length>0)){f.code(400).send({error:"both source and reason are required to clear a specific flag, or omit both to clear all"});return}m.length===0&&v.length;let S=e.get(g);if(S){if(m.length>0&&v.length>0)S.clearAttentionFlag(m,v);else{let R=Array.from(S.listAttentionFlags()).map(P=>`${P.source}::${P.reason}`);for(let P of R)S.clearAttentionFlag(P.split("::")[0],P.split("::").slice(1).join("::"))}f.code(204).send();return}if(!await e.hasRecord(g)){f.code(404).send({error:"session not found"});return}let b=e.store,I=await b.read(g);if(!I){f.code(404).send({error:"session not found"});return}let A=I.attentionFlags??[],T;if(m.length>0&&v.length>0){let R=`${m}::${v}`;T=A.filter(P=>`${P.source}::${P.reason}`!==R)}else T=[];if(T.length===A.length&&T.every((R,P)=>R.source===A[P].source&&R.reason===A[P].reason)){f.code(204).send();return}await b.write({...I,attentionFlags:T}),f.code(204).send()})}function Xu(s,e,t,n={}){s.get("/v1/agents",async()=>Bt(e)),s.get("/v1/registry",async()=>e.load()),s.post("/v1/registry/refresh",async()=>{let r=await e.refresh();return{version:r.version,agentCount:r.agents.length}}),s.post("/v1/agents/:id/install",async(r,o)=>{let i=r.params.id,a=await e.getAgent(i);if(!a){o.code(404).send({error:`agent ${i} not found in registry`});return}if(a.distribution.uvx&&!a.distribution.npx&&!a.distribution.binary){o.send({agentId:a.id,version:a.version??"current",distribution:"uvx",installed:!1,message:"uvx agents resolve on first run; nothing to pre-install."});return}try{let d=await Me(a,[],{npmRegistry:n.npmRegistry}),c=a.distribution.npx?"npx":a.distribution.binary?"binary":"unknown";o.send({agentId:a.id,version:d.version,distribution:c,installed:!0,command:d.command})}catch(d){o.code(500).send({error:d.message})}}),s.post("/v1/agents/:id/sync",async(r,o)=>{let i=r.params.id;try{let{synced:a,skipped:d}=await t.syncFromAgent(i);return{synced:a.map(c=>({sessionId:c.sessionId,upstreamSessionId:c.upstreamSessionId,agentId:c.agentId,cwd:c.cwd,title:c.title,updatedAt:c.updatedAt})),skipped:d}}catch(a){let d=a;if(d.code===x.AgentNotInstalled){o.code(404).send({error:d.message});return}o.code(409).send({error:d.message})}})}Q();function Zu(s,e,t,n=()=>[]){s.get("/v1/health",{config:{skipAuth:!0}},async()=>({status:"ok",version:e,configDigest:t,home:E.home(),driftedKeys:n()}))}import*as sl from"os";Q();He();var os=/^[A-Za-z0-9][A-Za-z0-9._-]*$/,xr=class s{data;constructor(e){this.data=e}static async load(){let e=await ce(E.peers());return new s(vw(e))}get(e){return this.data.entries[e]}async set(e){this.data.entries[e.name]=e,await el(this.data)}async delete(e){return e in this.data.entries?(delete this.data.entries[e],await el(this.data),!0):!1}list(){return Object.values(this.data.entries).map(({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})=>({name:e,host:t,port:n,expiresAt:r,label:o,addedAt:i,pinnedFingerprint:a,pinnedAt:d})).sort((e,t)=>e.addedAt.localeCompare(t.addedAt))}};function vw(s){if(!s||typeof s!="object")return{version:1,entries:{}};let e=s,t=e.entries&&typeof e.entries=="object"?e.entries:{},n={};for(let[r,o]of Object.entries(t)){if(!o||typeof o!="object")continue;let i=o;if(typeof i.name!="string"||typeof i.host!="string"||typeof i.port!="number"||typeof i.token!="string"||typeof i.expiresAt!="string"||typeof i.addedAt!="string")continue;let a={name:i.name,host:i.host,port:i.port,token:i.token,expiresAt:i.expiresAt,addedAt:i.addedAt};typeof i.label=="string"&&(a.label=i.label),typeof i.pinnedFingerprint=="string"&&(a.pinnedFingerprint=i.pinnedFingerprint),typeof i.pinnedAt=="string"&&(a.pinnedAt=i.pinnedAt),n[r]=a}return{version:1,entries:n}}async function el(s){await me(E.peers(),s,{mode:384})}var bw=3600*24*365,Ke=class extends Error{status;constructor(e,t){super(e),this.name="PeerLoginError",this.status=t}};function Tr(s,e){return`${Ae(s)?"http":"https"}://${s}:${e}`}async function tl(s){let e=s.fetchImpl??fetch,t=`${s.host}:${s.port}`,n=Tr(s.host,s.port),r;try{r=await e(`${n}/v1/auth/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({password:s.password,label:s.label,ttlSec:s.ttlSec??bw})})}catch(i){throw new Ke(`Could not reach ${t}: ${i.message}`,502)}if(r.status===401)throw new Ke(`Wrong password for ${t}.`,401);if(r.status===403)throw new Ke(`No password is configured on ${t}. Run \`hydra-acp auth password\` on that daemon first.`,502);if(r.status===429)throw new Ke(`Too many failed login attempts on ${t}; try again later.`,429);if(!r.ok)throw new Ke(`Login to ${t} failed: HTTP ${r.status}`,502);let o=await r.json();if(!o.session_token||!o.expires_at)throw new Ke(`Login to ${t} returned a malformed response.`,502);return{token:o.session_token,expiresAt:o.expires_at}}async function Ti(s){let e=s.fetchImpl??fetch,t=Tr(s.host,s.port);try{await e(`${t}/v1/auth/logout`,{method:"POST",headers:{Authorization:`Bearer ${s.token}`,"Content-Type":"application/json"},body:JSON.stringify({})})}catch{}}function rl(s){return{machine:At(),hydraVersion:ue,startedAt:s,os:{platform:process.platform,release:sl.release(),arch:process.arch},node:process.version}}async function Er(s){let e=s.fetchImpl??fetch,t;try{t=await e(`${Tr(s.host,s.port)}/v1/system`,{headers:{Authorization:`Bearer ${s.token}`},signal:s.signal})}catch(n){return{kind:"error",message:n.message}}if(t.status===401||t.status===403)return{kind:"unauthorized"};if(t.status===404)return{kind:"unsupported"};if(!t.ok)return{kind:"error",message:`HTTP ${t.status}`};try{let n=await t.json();return typeof n?.machine=="string"?{kind:"ok",system:n}:{kind:"ok"}}catch{return{kind:"ok"}}}function nl(s){return s!==void 0&&s.length<=64&&os.test(s)}function ol(s,e){if(nl(s))return s;if(/^[\d.]+$/.test(e)||e.includes(":"))return;let t=e.split(".")[0];return nl(t)?t:void 0}function il(s,e,t){s.get("/v1/system",async()=>rl(e)),s.post("/v1/daemon/shutdown",async(n,r)=>n.authIdentity!=="service"?r.code(403).send({error:"only the service token may stop the daemon"}):t===void 0?r.code(501).send({error:"this daemon cannot shut itself down"}):(r.code(202).send({status:"shutting-down"}),setTimeout(t,50),r))}var Sw=/^[A-Za-z0-9._-]+$/;function Pr(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=Iw(a);if("error"in d){i.code(400).send({error:d.error});return}try{let c=t.register(d.config);i.code(201).send(c)}catch(c){is(i,c)}}),s.delete(`${r}/:name`,async(o,i)=>{let a=o.params.name;try{await t.unregister(a),i.code(204).send()}catch(d){is(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){is(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){is(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){is(i,d)}})}function is(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 Iw(s){let e=s.name;if(typeof e!="string"||!Sw.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 al(s,e){Pr(s,"extension",e)}function dl(s,e){Pr(s,"transformer",e)}function cl(s,e){s.get("/v1/config",async()=>e())}import{z as kt}from"zod";Q();import*as gn from"fs/promises";import*as ul from"path";import{randomBytes as sx,scrypt as Aw,timingSafeEqual as Cw}from"crypto";import{promisify as Rw}from"util";var xw=Rw(Aw);function ll(){return ul.join(E.home(),"password-hash")}var Tw=128*1024*1024;async function fl(){try{return(await gn.readFile(ll(),"utf8")).trim().length>0}catch(s){if(s.code==="ENOENT")return!1;throw s}}async function pl(s){if(typeof s!="string"||s.length===0)return!1;let e;try{e=(await gn.readFile(ll(),"utf8")).trim()}catch(c){if(c.code==="ENOENT")return!1;throw c}let t=e.split("$");if(t.length!==6||t[0]!=="scrypt")return!1;let n=parseInt(t[1],10),r=parseInt(t[2],10),o=parseInt(t[3],10);if(!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o))return!1;let i=Buffer.from(t[4],"hex"),a=Buffer.from(t[5],"hex");if(i.length===0||a.length===0)return!1;let d=await xw(s,i,a.length,{N:n,r,p:o,maxmem:Tw});return d.length!==a.length?!1:Cw(d,a)}var Ew=kt.object({password:kt.string().min(1),label:kt.string().min(1).max(256).optional(),ttlSec:kt.number().int().positive().optional()}),Pw=kt.object({id:kt.string().optional()}).optional(),Mw=kt.object({token:kt.string().min(32)});function gl(s,e){s.post("/v1/auth/login",{config:{skipAuth:!0}},async(t,n)=>{let r=_w(t);if(e.rateLimiter.isBlocked(r))return n.code(429).send({error:"Too many failed attempts; try again later."});let o;try{o=Ew.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}if(!await fl())return n.code(403).send({error:"No password configured. Run `hydra-acp auth password` on the daemon host."});if(!await pl(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=Pw.parse(t.body??void 0)}catch{return n.code(400).send({error:"Invalid request body"})}let o=r?.id??t.authIdentity;if(!o||o==="service")return n.code(200).send({revoked:!1});let i=await e.store.revoke(o);return n.code(200).send({revoked:i})}),s.get("/v1/auth/verify",async(t,n)=>n.code(200).send({ok:!0})),s.get("/v1/auth/sessions",async(t,n)=>n.code(200).send({sessions:e.store.list()})),s.delete("/v1/auth/sessions",async(t,n)=>{let r=await e.store.revokeAll();return n.code(200).send({revoked:r})}),s.delete("/v1/auth/sessions/:id",async(t,n)=>{let r=t.params.id;return await e.store.revoke(r)?n.code(204).send():n.code(404).send({error:"Not found"})}),s.post("/v1/auth/rotate-token",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=Mw.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}return e.staticTokenValidator.rotate(r.token),n.code(200).send({rotated:!0})})}function _w(s){return s.ip||"unknown"}import{z as vt}from"zod";ds();var qw=vt.object({name:vt.string().min(1).max(64).regex(os).optional(),host:vt.string().min(1),port:vt.number().int().positive().optional(),password:vt.string().min(1),label:vt.string().min(1).max(256).optional(),ttlSec:vt.number().int().positive().optional(),pinnedFingerprint:vt.string().min(1).optional()});function Il(s,e){s.post("/v1/remotes",async(t,n)=>{let r;try{r=qw.parse(t.body)}catch{return n.code(400).send({error:`Invalid request body (name must match ${os} and the rest is a normal login request)`})}let o=r.port??Dt;r.pinnedFingerprint&&as(r.host,o,r.pinnedFingerprint);let i;try{i=await tl({host:r.host,port:o,password:r.password,label:r.label,ttlSec:r.ttlSec})}catch(y){if(y instanceof Ke)return n.code(y.status).send({error:y.message});throw y}let a=await Er({host:r.host,port:o,token:i.token}),d=a.kind==="ok"?a.system:void 0,c=r.name;if(c===void 0){c=ol(d?.machine,r.host);let y=c!==void 0?e.store.get(c):void 0,h=y!==void 0&&(y.host!==r.host||y.port!==o);if(c===void 0||h){await Ti({host:r.host,port:o,token:i.token});let f=c===void 0?`Couldn't derive a remote name for ${r.host}`:`A remote named ${c} already points at ${y.host}:${y.port}`;return n.code(c===void 0?400:409).send({error:`${f}. Pass a name: hydra-acp remote add <name> ${r.host}`})}}let u=new Date().toISOString(),l={name:c,host:r.host,port:o,token:i.token,expiresAt:i.expiresAt,addedAt:u,...r.label!==void 0?{label:r.label}:{},...r.pinnedFingerprint!==void 0?{pinnedFingerprint:r.pinnedFingerprint,pinnedAt:u}:{}};return await e.store.set(l),e.health?.markOk(l.name,d),n.code(201).send({name:l.name,host:l.host,port:l.port,expiresAt:l.expiresAt,label:l.label,addedAt:l.addedAt,pinnedFingerprint:l.pinnedFingerprint,status:e.health?.get(l.name)?.status??"unknown"})}),s.get("/v1/remotes",async(t,n)=>{let r=e.store.list().map(o=>{let i=e.health?.get(o.name);return{...o,status:i?.status??"unknown",...i?.checkedAt?{lastCheckedAt:i.checkedAt}:{},...i?.system?{system:i.system}:{}}});return n.code(200).send({remotes:r})}),s.get("/v1/remotes/:name/agents",async(t,n)=>{let r=e.store.get(t.params.name);if(!r)return n.code(404).send({error:"Not found"});let i=`${Ae(r.host)?"http":"https"}://${r.host}:${r.port}`,a={Authorization:`Bearer ${r.token}`};try{let[d,c]=await Promise.all([fetch(`${i}/v1/agents`,{headers:a}),fetch(`${i}/v1/config`,{headers:a}).catch(()=>null)]);if(!d.ok)return n.code(d.status).header("content-type","application/json").send(await d.text());let u=await d.json(),l={};if(c?.ok){let y=await c.json();l={defaultAgent:y.defaultAgent,sessionDefaults:y.sessionDefaults}}return n.code(200).send({...u,...l})}catch(d){return n.code(502).send({error:`Could not reach remote "${r.name}": ${d.message}`})}}),s.delete("/v1/remotes/:name",async(t,n)=>{let r=t.params.name,o=e.store.get(r);return o?(await Ti({host:o.host,port:o.port,token:o.token}),await e.store.delete(r),e.health?.forget(r),e.store.list().some(a=>a.host===o.host&&a.port===o.port)||Pi(o.host,o.port),n.code(204).send()):n.code(404).send({error:"Not found"})})}function _r(s){let e=[],t=[],n=!1,r=o=>{if(!n){n=!0;for(let i of t)i(o)}};return s.on("message",(o,i)=>{if(i)return;let a=o.toString("utf8");try{let d=JSON.parse(a);for(let c of e)c(d)}catch(d){for(let c of e)c({jsonrpc:"2.0",id:null,error:{code:x.ParseError,message:`Failed to parse WS frame: ${d.message}`}})}}),s.on("close",()=>r()),s.on("error",o=>r(o)),{async send(o){if(n)throw new Error("ws is closed");let i=JSON.stringify(o);await new Promise((a,d)=>{s.send(i,c=>{if(c){d(c);return}a()})})},onMessage(o){e.push(o)},onClose(o){t.push(o)},async close(){n||(await new Promise(o=>{let i=!1,a=()=>{i||(i=!0,clearTimeout(d),o())},d=setTimeout(a,5e3);s.once("close",a);try{s.close()}catch{a()}}),r())}}}ds();import{WebSocket as zw}from"ws";var Jw=1e4,Oi=class extends Error{url;elapsedMs;constructor(e,t){super(`hydra-acp: websocket connect to ${e} timed out after ${t}ms`),this.name="WsConnectTimeoutError",this.url=e,this.elapsedMs=t}};async function Al(s,e,t=Jw){let n={};try{let r=new URL(s);if(r.protocol==="wss:"){let o=Fi(r.hostname);o.rejectUnauthorized!==void 0&&(n.rejectUnauthorized=o.rejectUnauthorized),o.autoSelectFamily!==void 0&&(n.autoSelectFamily=o.autoSelectFamily),o.checkServerIdentity!==void 0&&(n.checkServerIdentity=o.checkServerIdentity)}}catch{}return new Promise((r,o)=>{let i=new zw(s,e,n),a=Date.now(),d=setTimeout(()=>{i.off("open",c),i.off("error",u),i.on("error",()=>{});try{i.terminate()}catch{}o(new Oi(s,Date.now()-a))},t),c=()=>{clearTimeout(d),i.off("error",u),r(i)},u=l=>{clearTimeout(d),i.off("open",c),o(l)};i.once("open",c),i.once("error",u)})}var Vw=new Set(["session/attach","session/detach","session/prompt","session/cancel","session/close","session/delete","hydra-acp/session/delete","session/set_model","session/set_mode","session/set_config_option","_session/steering","hydra-acp/prompt/cancel","hydra-acp/prompt/update","hydra-acp/prompt/amend","hydra-acp/session/tool_content","hydra-acp/session/force_cancel"]);function Gw(s){return Vw.has(s)}function Rl(s,e,t,n){let r=[],o=a=>{for(let d of r)d(a)},i=(a,d)=>{e.handleLocalMessage(a,d,{connection:t.connection,clientId:n}).then(c=>c?s.send(c):void 0).catch(()=>{})};return s.onMessage(a=>{if("method"in a&&Gw(a.method)){let d=a.params,c=typeof d?.sessionId=="string"?d.sessionId:void 0;if(c){if(gt(c)){i(a,c);return}if(a.method==="session/attach"){let u="id"in a;e.resolveLocalMiss(c).then(l=>{if(l.ok){i(a,l.foreignId);return}if(l.ambiguous&&u){s.send(cs(a.id,x.SessionNotFound,`Session "${c}" exists on more than one remote (${l.ambiguous.join(", ")}). Address it as "<remote>:${c}".`));return}o(a)});return}}}o(a)}),{send:a=>s.send(a),onMessage:a=>r.push(a),onClose:a=>s.onClose(a),close:()=>s.close()}}var $r=class{constructor(e,t=Qw,n){this.store=e;this.dial=t;this.localMiss=n}store;dial;localMiss;attachments=new Map;async resolveLocalMiss(e){if(!this.localMiss)return{ok:!1};if(await this.localMiss.resolvesLocally(e))return{ok:!1};let t=this.localMiss.cache.findByLocalId(e);return t.length===0?{ok:!1}:t.length>1?{ok:!1,ambiguous:t.map(n=>n.name)}:{ok:!0,foreignId:Je(t[0])}}async handleLocalMessage(e,t,n){let r="id"in e,o=r?e.id:void 0,i=gt(t);if(!i)return r?cs(o,x.SessionNotFound,`not a federated session id: ${t}`):void 0;let a=Cl(n.clientId,t),d={...e.params,sessionId:i.localId};if(e.method==="session/attach"){let u=this.store.get(i.name);if(!u)return r?cs(o,x.SessionNotFound,`No remote named "${i.name}". Run \`hydra remote add\` first.`):void 0;let l=this.attachments.get(a);l&&(this.attachments.delete(a),l.peerConnection.close().catch(()=>{}));let y;try{y=await this.dial(u)}catch(g){return r?cs(o,x.InternalError,`Could not reach remote "${i.name}": ${g.message}`):void 0}let h={peerConnection:y,localId:i.localId,target:n};this.wireAttachment(i.name,h);let f;try{f=await y.request("session/attach",d)}catch(g){return y.close().catch(()=>{}),r?Ni(o,g):void 0}this.attachments.set(a,h);let k=f&&typeof f.sessionId=="string"?{...f,sessionId:t}:f;return r?{jsonrpc:"2.0",id:o,result:k}:void 0}let c=this.attachments.get(a);if(!c)return r?cs(o,x.SessionNotFound,`"${t}" is not attached through this daemon.`):void 0;if(e.method==="session/detach"){let u,l;try{u=await c.peerConnection.request("session/detach",d)}catch(y){l=y}return this.attachments.delete(a),c.peerConnection.close().catch(()=>{}),l?r?Ni(o,l):void 0:r?{jsonrpc:"2.0",id:o,result:u??{}}:void 0}if(r)try{let u=await c.peerConnection.request(e.method,d);return{jsonrpc:"2.0",id:o,result:u}}catch(u){return Ni(o,u)}await c.peerConnection.notify(e.method,d).catch(()=>{})}detachClient(e){for(let[t,n]of[...this.attachments.entries()])n.target.clientId===e&&(this.attachments.delete(t),n.peerConnection.request("session/detach",{sessionId:n.localId}).catch(()=>{}),n.peerConnection.close().catch(()=>{}))}wireAttachment(e,t){let{peerConnection:n,localId:r,target:o}=t,i=Je({name:e,localId:r}),a=()=>{this.attachments.delete(Cl(o.clientId,i))};n.onAnyNotification((d,c)=>{let u=d;!u||u.sessionId!==r||(c==="hydra-acp/session/closed"&&a(),o.connection.notify(c,{...u,sessionId:i}).catch(()=>{}))}),n.onRequest("hydra-acp/session/request_permission",async d=>{let c=d;if(!c||c.sessionId!==r)throw{code:x.MethodNotFound,message:"unexpected sessionId"};return o.connection.request("hydra-acp/session/request_permission",{...c,sessionId:i})}),n.onClose(()=>{a(),o.connection.notify("hydra-acp/session/closed",{sessionId:i}).catch(()=>{})})}};function Cl(s,e){return`${s} ${e}`}function cs(s,e,t){return{jsonrpc:"2.0",id:s,error:{code:e,message:t}}}function Ni(s,e){let t=e,n=typeof t?.code=="number"?t.code:x.InternalError,r=typeof t?.message=="string"?t.message:String(e??"forward failed");return{jsonrpc:"2.0",id:s,error:{code:n,message:r,...t?.data!==void 0?{data:t.data}:{}}}}var Kw=1e4;async function Qw(s){let t=`${Ae(s.host)?"ws":"wss"}://${s.host}:${s.port}/acp`,n=await Al(t,["acp.v1",`hydra-acp-token.${s.token}`],Kw);return new qe(_r(n))}var Yw=3e4,Xw=5e3,Fr=class{constructor(e,t={}){this.store=e;this.opts=t}store;opts;snapshots=new Map;timer;start(){this.timer||(this.checkAll(),this.timer=setInterval(()=>{this.checkAll()},this.opts.intervalMs??Yw),this.timer.unref?.())}stop(){this.timer&&(clearInterval(this.timer),this.timer=void 0)}get(e){return this.snapshots.get(e)}markOk(e,t){this.snapshots.set(e,{status:"ok",checkedAt:new Date().toISOString(),...t?{system:t}:{}})}forget(e){this.snapshots.delete(e)}async checkAll(){let e=this.opts.fetchImpl??fetch;await Promise.allSettled(this.store.list().map(async t=>{let n=this.store.get(t.name);if(!n)return;let r=new AbortController,o=setTimeout(()=>r.abort(),Xw);try{let i=await Er({host:n.host,port:n.port,token:n.token,fetchImpl:e,signal:r.signal});if(i.kind==="ok"){this.snapshots.set(t.name,{status:"ok",checkedAt:new Date().toISOString(),...i.system?{system:i.system}:{}});return}if(i.kind==="unauthorized"){this.snapshots.set(t.name,{status:"unauthorized",checkedAt:new Date().toISOString()});return}if(i.kind==="error")throw new Error(i.message);let d=`${Ae(n.host)?"http":"https"}://${n.host}:${n.port}/v1/auth/verify`,c=await e(d,{headers:{Authorization:`Bearer ${n.token}`},signal:r.signal});this.snapshots.set(t.name,{status:c.ok?"ok":"unauthorized",checkedAt:new Date().toISOString()})}catch(i){this.snapshots.set(t.name,{status:"unreachable",checkedAt:new Date().toISOString(),error:i.message})}finally{clearTimeout(o)}}))}};ds();import{z as xl}from"zod";var Zw=xl.object({sessionLabel:xl.string().min(1).max(256)});function Tl(s,e){s.post("/v1/process-tokens",async(t,n)=>{if(t.authIdentity!=="service")return n.code(403).send({error:"Requires the service token"});let r;try{r=Zw.parse(t.body)}catch{return n.code(400).send({error:"Invalid request body"})}let o=e.processRegistry.mint(r.sessionLabel,"script");return n.code(201).send({token:o})}),s.delete("/v1/process-tokens/:sessionLabel",async(t,n)=>t.authIdentity!=="service"?n.code(403).send({error:"Requires the service token"}):(e.processRegistry.revoke(t.params.sessionLabel),n.code(204).send()))}import{nanoid as Di}from"nanoid";import{randomBytes as $l}from"crypto";import*as Fl from"os";import*as Ol from"path";var ek=200;function tk(s){if(!s||typeof s!="object")return;let e=s._meta;if(!e||typeof e!="object"||Array.isArray(e))return;let t=e[le];if(!t||typeof t!="object"||Array.isArray(t))return;let n=t.sentBy;if(!n||typeof n!="object"||Array.isArray(n))return;let r=n,o={};if(typeof r.sessionId=="string"&&r.sessionId.length>0&&(o.sessionId=r.sessionId),typeof r.label=="string"&&r.label.length>0&&(o.label=r.label.slice(0,ek)),r.awaiting===!0&&(o.awaiting=!0),!(o.sessionId===void 0&&o.label===void 0))return o}async function El(s,e,t){let n=tk(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 us=new Map;function Pl(s,e){let t=us.get(s);t||(t=new Set,us.set(s,t)),t.add(e);let n=!1;return()=>{if(n)return;n=!0;let r=us.get(s);r&&(r.delete(e),r.size===0&&us.delete(s))}}function Ml(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=us.get(r);if(o){if(o.has(s))return!0;for(let i of o)n.push(i)}}return!1}function O(s,e,t){let n=new Error(e);return n.code=s,t!==void 0&&(n.data=t),n}function ik(s){if(!s||typeof s!="object")return 512;let n=s.params?.update;if(!n)return 512;let r=512,o=n.content;if(typeof o=="string")r+=o.length;else if(o&&typeof o=="object"){let a=o;typeof a.text=="string"&&(r+=a.text.length),typeof a.data=="string"&&(r+=a.data.length)}let i=n.toolCall;if(i&&(typeof i.rawInput=="string"?r+=i.rawInput.length:i.rawInput&&typeof i.rawInput=="object"&&(r+=256),typeof i.rawOutput=="string"?r+=i.rawOutput.length:i.rawOutput&&typeof i.rawOutput=="object"&&(r+=256),Array.isArray(i.content)))for(let a of i.content){if(!a||typeof a!="object")continue;let d=a;if(typeof d.text=="string"&&(r+=d.text.length),d.content&&typeof d.content=="object"){let c=d.content;typeof c.text=="string"&&(r+=c.text.length)}}return r}function Ee(s,e,t){let n=s.get(e);if(!n)throw O(x.SessionNotFound,t??`session ${e} not found`);return n}async function Ft(s,e){let t=fn(s),n,r,o;typeof e.summarizedThroughEntry=="number"&&e.summarizedThroughEntry>0&&s.mcpTokenRegistry!==void 0&&s.getDaemonOrigin!==void 0&&(n=$l(32).toString("hex"),r=s.mcpTokenRegistry.reserve(n),o={name:"hydra-acp-recall",type:"http",url:`${s.getDaemonOrigin()}/mcp/hydra-acp-recall`,headers:[{name:"Authorization",value:`Bearer ${n}`}]});let a=[...t?.descriptors??[],...o!==void 0?[o]:[]],d=Ri({baselineMcpServers:void 0,stdinEnabled:!1,deps:s}),c;try{c=await s.manager.resurrect({...e,mcpServers:a,...d?{mintMcpServersForSwap:d}:{}})}catch(u){throw t!==void 0&&t.abandon(u instanceof Error?u:void 0),r!==void 0&&r.abandon(u instanceof Error?u:void 0),u}if(t!==void 0&&t.bindToSession(c),n!==void 0&&r!==void 0&&s.mcpTokenRegistry!==void 0){let u=n,l=s.mcpTokenRegistry;r.complete(c),c.onClose(()=>{l.unbind(u)})}return hk(c,s),Dl(c.sessionId,s),c}function Nl(s,e){s.get("/acp",{websocket:!0},async(t,n)=>{let r=xu({headers:n.headers,url:n.url});if(!r||!await e.validator.validate(r)){t.close(4401,"Unauthorized");return}let o=e.processRegistry?.resolve(r),i=`hydra_client_${Di(12)}`,a=_r(t),d={},c=e.foreignSessions?Rl(a,e.foreignSessions,d,i):a,u=new qe(c);d.connection=u;let l={clientId:i,processIdentity:o,attached:new Map};u.setParamsRewriter(g=>{if(g===null||typeof g!="object")return g;let p=g.sessionId;if(typeof p!="string"||l.attached.has(p))return g;let w=ye+p;return l.attached.has(w)?{...g,sessionId:w}:g}),u.onClose(()=>{for(let g of l.attached.values())e.manager.get(g.sessionId)?.detach(g.clientId);l.attached.clear(),e.foreignSessions?.detachClient(i)});let y=(g,p)=>{if(l.attached.get(g)?.readonly)throw O(x.PermissionDenied,`${p} not permitted on a read-only attachment`)};if(u.onRequest("initialize",async g=>{let p=Na.parse(g??{});p.clientInfo?.name&&(l.clientInfo={name:p.clientInfo.name,...p.clientInfo.version!==void 0?{version:p.clientInfo.version}:{}});let w=p.clientCapabilities?.elicitation;l.elicitationForm=w!==null&&typeof w=="object"&&w.form!==void 0&&w.form!==null;let m=p.clientInfo?.version;return m&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,m):e.onTransformerVersion?.(o.name,m)),mk()}),o&&e.extensionCommands){let g=e.extensionCommands;u.onRequest("hydra-acp/commands/register",async p=>{let w=p??{},m=Array.isArray(w.commands)?w.commands.map(v=>{if(!v||typeof v!="object")return;let S=v;if(typeof S.verb!="string")return;let b={verb:S.verb};return typeof S.argsHint=="string"&&(b.argsHint=S.argsHint),typeof S.description=="string"&&(b.description=S.description),b}).filter(v=>v!==void 0):[];return g.register(o.name,u,m),{ok:!0,registered:m.length}}),u.onClose(()=>{g.clear(o.name)})}if(o&&e.extensionMcp){let g=e.extensionMcp;u.onRequest("hydra-acp/mcp_tools/register",async w=>{let m=w??{},v=typeof m.instructions=="string"?m.instructions:void 0,S=Array.isArray(m.tools)?m.tools.map(b=>{if(!b||typeof b!="object")return;let I=b;if(typeof I.name!="string"||I.name.length===0||typeof I.description!="string"||I.inputSchema===null||typeof I.inputSchema!="object")return;let A={name:I.name,description:I.description,inputSchema:I.inputSchema};return I.outputSchema!==null&&typeof I.outputSchema=="object"&&(A.outputSchema=I.outputSchema),A}).filter(b=>b!==void 0):[];if(S.length===0)throw new Error("register_mcp_tools requires at least one tool");return g.register(o.name,u,v,S),{ok:!0,registered:S.length}});let p=w=>{let m=w??{};if(typeof m.sessionId!="string"||m.sessionId.length===0)throw O(x.InvalidParams,"sessionId is required");return m.sessionId};if(u.onRequest("hydra-acp/session/extension_state/get",async w=>{let m=p(w),v=w??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(!e.manager)throw O(x.InternalError,"manager not wired");return{value:await e.manager.getExtensionStateKey(m,o.name,v.key)??null}}),u.onRequest("hydra-acp/session/extension_state/list",async w=>{let m=p(w);if(!e.manager)throw O(x.InternalError,"manager not wired");return{state:await e.manager.getExtensionState(m,o.name)}}),u.onRequest("hydra-acp/session/extension_state/set",async w=>{let m=p(w),v=w??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(v.value===void 0)throw O(x.InvalidParams,"value is required (use extension_state/delete to remove)");if(!e.manager)throw O(x.InternalError,"manager not wired");try{await e.manager.setExtensionStateKey(m,o.name,v.key,v.value)}catch(S){throw O(x.InvalidParams,S.message)}return{ok:!0}}),u.onRequest("hydra-acp/session/extension_state/delete",async w=>{let m=p(w),v=w??{};if(typeof v.key!="string"||v.key.length===0)throw O(x.InvalidParams,"key is required");if(!e.manager)throw O(x.InternalError,"manager not wired");return await e.manager.deleteExtensionStateKey(m,o.name,v.key),{ok:!0}}),e.extensionMcpControls){let w=e.extensionMcpControls;u.onRequest("hydra-acp/mcp_tools/refresh_session",async m=>{let v=m??{};if(typeof v.sessionId!="string"||v.sessionId.length===0)throw O(x.InvalidParams,"refresh_session requires sessionId");return await w.notifyToolListChanged(v.sessionId,o.name),{ok:!0}})}u.onClose(()=>{g.clear(o.name)})}o?.kind==="transformer"&&(u.onRequest("hydra-acp/transformer/initialize",async g=>{let p=g??{},w=Array.isArray(p.intercepts)?p.intercepts.filter(m=>typeof m=="string"):[];if(e.transformers&&(e.transformers.registerConnection(o.name,u,w),e.manager?.defaultTransformers.includes(o.name))){let m=e.transformers.resolveChain([o.name])[0];if(m)for(let v of e.manager.liveSessions())v.addTransformer(m)}return{ack:!0}}),u.onClose(()=>{e.transformers?.deregisterConnection(o.name)}),u.onRequest("hydra-acp/message/emit",async g=>{let p=g??{},w=typeof p.sessionId=="string"?p.sessionId:void 0,m=typeof p.method=="string"?p.method:void 0,v=p.envelope,S=p.route;if(!w)throw O(-32602,"emit_message requires sessionId");if(!m&&S!=="client_broadcast")throw O(-32602,"emit_message requires method");let b=Ee(e.manager,w),I=typeof p.respondsTo=="string"?p.respondsTo:void 0;if(I)return b.dischargeClaim(I,v),{ok:!0};if(S==="chain")return{ok:!0,response:await b.emitToChain(o.name,m,v)};if(S==="queue"){if(m!=="session/prompt")throw O(-32602,'route "queue" only supports method "session/prompt"');return{ok:!0,response:await b.emitToQueue(o.name,v)}}if(S==="daemon")return{ok:!0,response:await b.emitToChain(o.name,m,v)};if(S==="client_broadcast"){if(!v||typeof v!="object")throw O(-32602,"client_broadcast requires an envelope object");return b.broadcastClientUpdate(v),{ok:!0}}throw O(-32602,`unsupported route: ${JSON.stringify(S)}`)}),u.onRequest("hydra-acp/session/request_permission",async g=>{let p=g??{},w=typeof p.sessionId=="string"?p.sessionId:void 0;if(!w)throw O(-32602,"hydra-acp/session/request_permission requires sessionId");return Ee(e.manager,w).requestPermissionFromClients(p)}),u.onRequest("hydra-acp/transformer/attach",async g=>lk(g,o.name,e)),u.onRequest("hydra-acp/child_session/spawn",async g=>{let p=g??{},w=typeof p.agentId=="string"?p.agentId:void 0,m=typeof p.cwd=="string"?p.cwd:void 0,v=typeof p.parentSessionId=="string"?p.parentSessionId:void 0,S=dt(p._meta??void 0),b=S.title,I=S.model,A=S.workspace;if(!m&&v){let U=e.manager.get(v);U&&(m=U.cwd)}if(!m)throw O(-32602,"child_session/spawn requires cwd (or a parentSessionId pointing at a live session whose cwd we can inherit)");let T=await Sn(m),R=w??T.agentId??e.defaultAgent,P=await e.registry?.getAgent(R),$=lo(T.configDefaults,P??{id:R})?.value,L=I??$?.model,J=typeof p.interactive=="boolean"?p.interactive:!1,z=await e.manager.create({agentId:R,cwd:m,parentSessionId:v,interactive:J,transformChain:[],title:b,model:L,configDefaults:$,...A!==void 0?{workspace:A}:{}});return{childSessionId:z.sessionId,...z.workspace!==void 0||z.workspaceError!==void 0?{_meta:{[le]:{...z.workspace!==void 0?{workspaceInfo:z.workspace}:{},...z.workspaceError!==void 0?{workspaceError:z.workspaceError}:{}}}}:{}}}));let h=async(g,p)=>{let w=g??{};if(typeof w.sessionId!="string")throw O(x.InvalidParams,"fork_session requires sessionId");let m=typeof w.forkAt=="string"?w.forkAt:void 0,v=typeof w.cwd=="string"?w.cwd:void 0,S=typeof w.agentId=="string"?w.agentId:void 0,b=p?void 0:typeof w.mode=="string"&&(w.mode==="verbatim"||w.mode==="synthesis")?w.mode:void 0,I=typeof w.model=="string"&&w.model.length>0?w.model:void 0,A;if(p){let L=w.selection;if(L!==void 0&&(typeof L.text!="string"||L.text.length===0))throw O(x.InvalidParams,"selection.text must be a non-empty string");A={...L!==void 0?{selection:{text:L.text,...typeof L.responsePartId=="string"?{responsePartId:L.responsePartId}:{}}}:{}}}let T=await e.manager.forkSession(w.sessionId,{...A!==void 0?{side:A}:{},...m!==void 0?{forkAt:m}:{},...v!==void 0?{cwd:v}:{},...S!==void 0?{agentId:S}:{},...b!==void 0?{mode:b}:{},...I!==void 0?{model:I}:{}}),R=e.manager.get(T.sessionId);if(!R){let L=await e.manager.loadFromDisk(T.sessionId);if(!L)throw O(x.InternalError,`fork ${T.sessionId} vanished before it could be attached`);R=await Ft(e,{...L,onInstallProgress:Or(u)})}mn(l,R,R.sessionId);let P=bt(u,R,l),{entries:$}=await R.attach(P,"full");l.attached.set(R.sessionId,{sessionId:R.sessionId,clientId:P.clientId,readonly:!1});for(let L of $){if(u.isClosed())break;await u.notify(L.method,We(Be(L.params,L.recordedAt),L.seq)).catch(()=>{})}return{...T,sessionId:R.sessionId}};u.onRequest("hydra-acp/session/fork",g=>h(g,!1)),u.onRequest("hydra-acp/session/side",g=>h(g,!0)),u.onRequest("hydra-acp/session/rewind",async g=>{let p=g??{};if(typeof p.sessionId!="string")throw O(x.InvalidParams,"hydra-acp/session/rewind requires sessionId");let w=p.keepThrough;if(w!==null&&(typeof w!="string"||w.length===0))throw O(x.InvalidParams,"keepThrough must be a non-empty messageId, or null to drop every turn");let m=await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId;try{return await e.manager.rewindSession(m,w)}catch(v){let S=v;throw O(S.code??x.InternalError,S.message)}}),u.onRequest("session/fork",async g=>{let p=g??{};if(typeof p.sessionId!="string")throw O(x.InvalidParams,"session/fork requires sessionId");let w=typeof p.cwd=="string"?p.cwd:void 0,m=await e.manager.forkSession(p.sessionId,{...w!==void 0?{cwd:w}:{},mode:"verbatim"}),v=e.manager.get(m.sessionId);if(!v){let I=await e.manager.loadFromDisk(m.sessionId);if(!I)throw O(x.InternalError,`fork ${m.sessionId} vanished before it could be attached`);v=await Ft(e,{...I,onInstallProgress:Or(u)})}mn(l,v,v.sessionId);let S=bt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let I of b){if(u.isClosed())break;await u.notify(I.method,We(Be(I.params,I.recordedAt),I.seq)).catch(()=>{})}return{sessionId:v.sessionId}});let f=async(g,p)=>{let w=g??{};if(typeof w.sessionId!="string")throw O(x.InvalidParams,`${p} requires sessionId`);let m=await e.manager.resolveCanonicalId(w.sessionId)??w.sessionId,v=e.manager.get(m);if(v)return await v.close({deleteRecord:!0,by:`session/delete ${l.clientId}`}),await e.manager.waitForDeletion(m),await e.manager.hasRecord(m)&&await e.manager.deleteRecord(m),{id:m,existed:!0};let S=await e.manager.deleteRecord(m);return{id:m,existed:S}};u.onRequest("session/delete",async g=>(await f(g,"session/delete"),{})),u.onRequest("session/close",async g=>{let p=g??{};if(typeof p.sessionId!="string")throw O(x.InvalidParams,"session/close requires sessionId");y(p.sessionId,"session/close");let w=await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,m=e.manager.get(w);if(m)return await m.close({deleteRecord:!1,by:`session/close ${l.clientId}`+(l.processIdentity?` (${l.processIdentity.name})`:"")}),{};if(await e.manager.hasRecord(w))return{};throw O(x.SessionNotFound,`session ${w} not found`)}),u.onRequest("hydra-acp/session/delete",async g=>{let{id:p,existed:w}=await f(g,"hydra-acp/session/delete");if(!w)throw O(x.SessionNotFound,`session ${p} not found`);return{deleted:!0,sessionId:p}}),o?.kind==="transformer"&&(u.onRequest("hydra-acp/child_session/await",async g=>{let p=g??{},w=typeof p.childSessionId=="string"?p.childSessionId:void 0,m=p.until==="idle"?"idle":"turn_complete",v=typeof p.timeoutMs=="number"?Math.min(p.timeoutMs,18e5):3e5;if(!w)throw O(-32602,"await_child requires childSessionId");let S=Ee(e.manager,w,`child session ${w} not found`);return new Promise(b=>{let T=[],R=[],P=0,$=!1,L,J,z=!1,U=()=>{z||(z=!0,clearTimeout(j),L?.(),J?.(),b($?{entries:T,truncated:!0}:{entries:T}))};L=S.onBroadcast(ee=>{let se=ik(ee);for(T.push(ee),R.push(se),P+=se;T.length>0&&(T.length>1e3||P>1048576);)T.shift(),P-=R.shift()??0,$=!0;m==="turn_complete"&&ee.params?.update?.sessionUpdate==="turn_complete"&&U()});let j=setTimeout(U,v);typeof j.unref=="function"&&j.unref(),J=S.onClose(()=>U())})}),u.onRequest("hydra-acp/child_session/close",async g=>{let p=g??{},w=typeof p.childSessionId=="string"?p.childSessionId:void 0;if(!w)throw O(-32602,"close_child_session requires childSessionId");let m=e.manager.get(w);return m&&await m.close({deleteRecord:!1,by:`child_session/close ${l.clientId}`}),{ok:!0}}),u.onRequest("hydra-acp/attention/set",async g=>fk(g,o.name,e)),u.onRequest("hydra-acp/attention/clear",async g=>pk(g,o.name,e)),u.onRequest("hydra-acp/connection/keep_alive",async g=>{let p=g??{},w=typeof p.token=="string"?p.token:void 0,m=typeof p.sessionId=="string"?p.sessionId:void 0,v=typeof p.estimatedRemainingMs=="number"?p.estimatedRemainingMs:void 0;return w&&m&&e.manager.get(m)?.keepAliveClaim(w,v),{ok:!0}})),u.onRequest("hydra-acp/session/tool_content",async g=>{let p=g??{};if(typeof p.sessionId!="string"||typeof p.hash!="string")throw O(x.InvalidParams,"hydra-acp/session/tool_content requires sessionId and hash");let w=await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,m=await e.manager.loadToolBlob(w,p.hash);if(m===null)throw O(x.SessionNotFound,"tool content not found");return{content:m}}),u.onRequest("authenticate",async g=>ak(g,e)),u.onRequest("logout",async g=>dk(g,e)),u.onRequest("session/new",async g=>{let p=new Jt,w=Da.parse(g),m=dt(g?._meta),v=Array.isArray(m.transformers)&&m.transformers.every(te=>typeof te=="string")?m.transformers:e.manager.defaultTransformers??[],S=e.transformers?.resolveChain(v)??[],b=await Sn(w.cwd),I=m.agentId??b.agentId??e.defaultAgent,A=await e.registry?.getAgent(I),T=lo(b.configDefaults,A??{id:I})?.value,R,P,$=w.mcpServers;if(m.mcpStdin===!0&&e.mcpTokenRegistry!==void 0&&e.getDaemonOrigin!==void 0){R=$l(32).toString("hex"),P=e.mcpTokenRegistry.reserve(R);let Ze={name:"hydra-acp-stdin",type:"http",url:`${e.getDaemonOrigin()}/mcp/hydra-acp-stdin`,headers:[{name:"Authorization",value:`Bearer ${R}`}]};$=[...w.mcpServers??[],Ze]}let L,J,z=fn(e);z!==void 0&&($=[...$??[],...z.descriptors]);let U=Ri({baselineMcpServers:w.mcpServers,stdinEnabled:m.mcpStdin===!0,deps:e});p.mark("ws.prepare");let j;try{j=await e.manager.create({timer:p,cwd:w.cwd,agentId:I,mcpServers:$,title:m.title,agentArgs:m.agentArgs,model:m.model??T?.model,configDefaults:T,onInstallProgress:Or(u),transformChain:S,originatingClient:l.clientInfo,...m.elicitationForms!==void 0?{elicitationForms:m.elicitationForms}:{},...m.interactive!==void 0?{interactive:m.interactive}:{},...m.env!==void 0?{forwardedEnv:m.env}:{},...m.workspace!==void 0?{workspace:m.workspace}:{},...U?{mintMcpServersForSwap:U}:{}})}catch(te){throw P!==void 0&&P.abandon(te instanceof Error?te:void 0),J!==void 0&&J.abandon(te instanceof Error?te:void 0),z!==void 0&&z.abandon(te instanceof Error?te:void 0),te}if(R!==void 0&&P!==void 0&&e.mcpTokenRegistry!==void 0){let te=R,Ze=e.mcpTokenRegistry;P.complete(j),j.onClose(()=>{Ze.unbind(te)})}if(L!==void 0&&J!==void 0&&e.mcpTokenRegistry!==void 0){let te=L,Ze=e.mcpTokenRegistry;J.complete(j),j.onClose(()=>{Ze.unbind(te)})}z!==void 0&&z.bindToSession(j),p.mark("ws.bind-mcp"),Dl(j.sessionId,e);let ee,se;try{mn(l,j,j.sessionId),ee=bt(u,j,l),{entries:se}=await j.attach(ee,"full")}catch(te){throw await j.close({deleteRecord:!1,by:"session/new attach-failed"}).catch(()=>{}),te}l.attached.set(j.sessionId,{sessionId:j.sessionId,clientId:ee.clientId,readonly:!1}),p.mark("ws.attach"),e.manager.logInfo(`session/new timing agent=${I} session=${j.sessionId} ${p.summary()}`),setImmediate(()=>{(async()=>{for(let te of se){if(u.isClosed())break;await u.notify(te.method,We(Be(te.params,te.recordedAt),te.seq)).catch(()=>{})}})()});let xe=Nr(j),St=Dr(j);return{sessionId:j.sessionId,...xe?{modes:xe}:{},...St?{models:St}:{},configOptions:j.buildConfigOptions(),_meta:Lr(e.manager,j,{clientId:ee.clientId})}}),u.onRequest("session/attach",async g=>{let p=Ha.parse(g),w=p.clientInfo?.version;w&&o&&(o.kind==="extension"?e.onExtensionVersion?.(o.name,w):e.onTransformerVersion?.(o.name,w));let m=dt(p._meta),v=m.resume,S=m.readonly===!0,b=m.env;s.log.info(`session/attach sessionId=${p.sessionId} hasResumeHints=${!!v} readonly=${S}`);let I=v?p.sessionId:await e.manager.resolveCanonicalId(p.sessionId)??p.sessionId,A=e.manager.get(I);if(!A&&S){let U=await e.manager.loadFromDisk(I);if(!U)throw O(x.SessionNotFound,`session ${p.sessionId} not found`);let j=qt(await e.manager.loadHistory(I,{...m.historyLimit!==void 0?{maxEntries:m.historyLimit}:{}}),U.side),ee=p.clientId??`cli_${Di(8)}`;l.attached.set(U.hydraSessionId,{sessionId:U.hydraSessionId,clientId:ee,readonly:!0}),s.log.info(`session/attach OK (viewer) sessionId=${U.hydraSessionId} clientId=${ee} attachedCount=${l.attached.size} replayed=${j.length}`);for(let se of j)await u.notify(se.method,We(Be(se.params,se.recordedAt),se.seq)).catch(()=>{});return{sessionId:U.hydraSessionId,clientId:ee,connectedClients:[ee],historyPolicy:"full",replayed:j.length,_meta:gk(U)}}let T=!A;if(!A){let U=await e.manager.loadFromDisk(I),j=await ck(I,v,U?.upstreamSessionId,e.manager);j.kind==="ignore"&&s.log.warn(j.logMessage);let ee=U;if(v&&j.kind==="honor"&&(ee={...U,hydraSessionId:p.sessionId,upstreamSessionId:v.upstreamSessionId,agentId:v.agentId,cwd:U?.workspace?.path??v.cwd,...v.title!==void 0?{title:v.title}:{},...v.agentArgs!==void 0?{agentArgs:v.agentArgs}:{}}),!ee)throw O(x.SessionNotFound,`session ${p.sessionId} not found and no resume hints provided`);if(await e.manager.isTombstoned(ee.agentId,ee.upstreamSessionId))throw O(x.SessionNotFound,`session ${p.sessionId} was deleted`);let se=ee.originatingClient?ee:{...ee,originatingClient:l.clientInfo},xe=b!==void 0?{...se,forwardedEnv:b}:se;A=await Ft(e,{...xe,onInstallProgress:Or(u)})}mn(l,A,A.sessionId);let R=bt(u,A,l,p.clientInfo,p.clientId),P=m.replayMode==="drip",{entries:$,appliedPolicy:L}=await A.attach(R,p.historyPolicy,{afterMessageId:p.afterMessageId,afterSeq:p.afterSeq,raw:P,...m.historyLimit!==void 0?{historyLimit:m.historyLimit}:{},...m.toolContent!==void 0?{toolContent:m.toolContent}:{}});if(l.attached.set(A.sessionId,{sessionId:A.sessionId,clientId:R.clientId,readonly:S}),b!==void 0&&await e.manager.setForwardedEnv(A.sessionId,b).catch(()=>{}),s.log.info(`session/attach OK sessionId=${A.sessionId} clientId=${R.clientId} attachedCount=${l.attached.size} requestedPolicy=${p.historyPolicy} appliedPolicy=${L} replayed=${$.length} readonly=${S}${P?" replayMode=drip":""}`),P){let U=m.dripSpeed&&m.dripSpeed>0?m.dripSpeed:1,j=750;(async()=>{let ee=null;for(let se of $){let xe=typeof se.recordedAt=="number"?se.recordedAt:null;if(ee!==null&&xe!==null){let St=Math.min(j,Math.max(0,(xe-ee)/U));St>0&&await new Promise(te=>setTimeout(te,St))}xe!==null&&(ee=xe);try{await u.notify(se.method,We(Be(se.params,xe??void 0),se.seq))}catch{return}}})()}else for(let U=0;U<$.length&&!u.isClosed();U++){let j=$[U],ee=u.notify(j.method,We(Be(j.params,j.recordedAt),j.seq)).catch(()=>{});(U+1)%200===0&&await ee}A.replayPendingPermissions(R);let J=Nr(A),z=Dr(A);return{sessionId:A.sessionId,clientId:R.clientId,connectedClients:A.connectedClients(R.clientId),historyPolicy:L,replayed:$.length,...J?{modes:J}:{},...z?{models:z}:{},configOptions:A.buildConfigOptions(),_meta:Lr(e.manager,A,{resurrected:T})}}),u.onRequest("session/detach",async g=>{let p=ja.parse(g),w=l.attached.get(p.sessionId);if(!w)throw O(x.SessionNotFound,"client not attached to that session");let m=e.manager.get(p.sessionId);return m?.detach(w.clientId),l.attached.delete(p.sessionId),m&&e.manager.reapIfOrphanedNonInteractive(p.sessionId),{sessionId:p.sessionId,_meta:{[le]:{detachStatus:"detached"}}}}),u.onRequest("session/list",async g=>{let p=Ua.parse(g??{});return{sessions:(await e.manager.list({cwd:p.cwd})).filter(S=>S.originatingClient?.name!==tr).map(Ba)}}),u.onRequest("hydra-acp/agents/list",async()=>{if(!e.registry)throw O(x.InternalError,"agent registry unavailable");return Bt(e.registry)}),u.onRequest("hydra-acp/agents/auth_methods",async g=>{let p=g??{};if(typeof p.agentId!="string"||p.agentId.length===0)throw O(x.InvalidParams,"hydra-acp/agents/auth_methods requires a non-empty agentId string");return{authMethods:(await e.manager.bootstrapAgentForAuth(p.agentId)).authMethods??[]}}),u.onRequest("session/prompt",async g=>{let p=Wa.parse(g);y(p.sessionId,"session/prompt");let w=await El(p,e.manager,b=>{s.log.warn(`session/prompt: dropping unknown sentBy.sessionId=${b} sessionId=${p.sessionId}`)});if(w?.fromSession!==void 0){if((w.depth??0)>3)throw s.log.warn(`session/prompt: refusing depth ${w.depth} chain from ${w.fromSession} to ${p.sessionId}`),O(x.InvalidRequest,`message chain too deep (${w.depth} hops, max ${3}): refusing to continue a session-to-session loop`);if(w.awaiting===!0&&Ml(w.fromSession,p.sessionId))throw s.log.warn(`session/prompt: refusing deadlock ${w.fromSession} -> ${p.sessionId}`),O(x.InvalidRequest,`would deadlock: ${p.sessionId} is already blocked waiting on ${w.fromSession}. Send with --no-wait, or let the other turn finish first.`)}let m=l.attached.get(p.sessionId);if(!m)throw s.log.warn(`session/prompt rejected: not attached sessionId=${p.sessionId} attachedKeys=[${[...l.attached.keys()].join(",")}]`),O(x.SessionNotFound,"not attached to session");let v=e.manager.get(p.sessionId);if(!v){let b=await e.manager.loadFromDisk(p.sessionId);if(!b)throw O(x.SessionNotFound,`session ${p.sessionId} not found`);s.log.info(`session/prompt auto-resurrecting cold sessionId=${p.sessionId}`),v=await Ft(e,b);let I=bt(u,v,l,void 0,m.clientId);await v.attach(I,"none")}let S=w?.awaiting===!0&&w.fromSession!==void 0?Pl(w.fromSession,p.sessionId):void 0;try{return await v.prompt(m.clientId,p,w)}finally{S?.()}});let k=g=>{let p;try{p=Ss.parse(g)}catch(v){s.log.warn(`session/cancel: invalid params: ${v.message}`);return}let w=l.attached.get(p.sessionId);if(!w)return;if(w.readonly){s.log.warn(`session/cancel dropped (readonly attachment) sessionId=${p.sessionId}`);return}let m=e.manager.get(p.sessionId);m&&m.cancel(w.clientId).catch(v=>{s.log.warn(`session/cancel for ${p.sessionId}: ${v.message}`)})};u.onNotification("session/cancel",k),u.onRequest("session/cancel",async g=>{let p=Ss.parse(g);return y(p.sessionId,"session/cancel"),k(g),null}),u.onRequest("hydra-acp/prompt/cancel",async g=>{let p=za.parse(g);return y(p.sessionId,"hydra-acp/prompt/cancel"),Ee(e.manager,p.sessionId).cancelQueuedPrompt(p.messageId)}),u.onRequest("hydra-acp/session/force_cancel",async g=>{let p=Ss.parse(g);return y(p.sessionId,"hydra-acp/session/force_cancel"),Ee(e.manager,p.sessionId).forceCancel()}),u.onRequest("hydra-acp/prompt/update",async g=>{let p=Ja.parse(g);return y(p.sessionId,"hydra-acp/prompt/update"),Ee(e.manager,p.sessionId).updateQueuedPrompt(p.messageId,p.prompt)}),u.onRequest("hydra-acp/prompt/amend",async g=>{let p=Va.parse(g);y(p.sessionId,"hydra-acp/prompt/amend");let w=l.attached.get(p.sessionId);if(!w)throw O(x.SessionNotFound,"not attached to session");return Ee(e.manager,p.sessionId).amendPrompt(w.clientId,p)}),u.onRequest("_session/steering",async g=>{let p=Ga.parse(g);y(p.sessionId,"_session/steering");let w=l.attached.get(p.sessionId);if(!w)throw O(x.SessionNotFound,"not attached to session");let m=e.manager.get(p.sessionId);if(!m){let v=await e.manager.loadFromDisk(p.sessionId);if(!v)throw O(x.SessionNotFound,`session ${p.sessionId} not found`);m=await Ft(e,v);let S=bt(u,m,l,void 0,w.clientId);await m.attach(S,"none")}return m.steer(w.clientId,p)}),u.onRequest("session/resume",async g=>{let p=g??{},w=typeof p.sessionId=="string"?p.sessionId:void 0;if(!w)throw O(x.InvalidParams,"session/resume requires sessionId");let m=await e.manager.resolveCanonicalId(w)??w,v=e.manager.get(m);if(!v){let A=await e.manager.loadFromDisk(m);if(!A)throw O(x.SessionNotFound,`session ${w} not found in memory or on disk`);v=await Ft(e,A)}mn(l,v,v.sessionId);let S=bt(u,v,l);await v.attach(S,"pending_only"),l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1}),v.replayPendingPermissions(S);let b=Nr(v),I=Dr(v);return{sessionId:v.sessionId,...b?{modes:b}:{},...I?{models:I}:{},configOptions:v.buildConfigOptions(),_meta:Lr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/load",async g=>{let p=g??{},w=typeof p.sessionId=="string"?p.sessionId:void 0;if(!w)throw O(x.InvalidParams,"session/load requires sessionId");let m=await e.manager.resolveCanonicalId(w)??w,v=e.manager.get(m);if(!v){let T=await e.manager.loadFromDisk(m);if(!T)throw O(x.SessionNotFound,`session ${w} not found in memory or on disk`);v=await Ft(e,T)}mn(l,v,v.sessionId);let S=bt(u,v,l),{entries:b}=await v.attach(S,"full");l.attached.set(v.sessionId,{sessionId:v.sessionId,clientId:S.clientId,readonly:!1});for(let T of b){if(u.isClosed())break;await u.notify(T.method,We(Be(T.params,T.recordedAt),T.seq)).catch(()=>{})}v.replayPendingPermissions(S);let I=Nr(v),A=Dr(v);return{sessionId:v.sessionId,...I?{modes:I}:{},...A?{models:A}:{},configOptions:v.buildConfigOptions(),_meta:Lr(e.manager,v,{clientId:S.clientId})}}),u.onRequest("session/set_model",async g=>{let p=g?.sessionId;typeof p=="string"&&y(p,"session/set_model");let w=uk(g,e.manager);if(w.kind==="error")throw s.log.warn(w.logMessage),O(w.code,w.message);if(w.kind==="no_op")return s.log.warn(w.logMessage),await u.notify("session/update",{sessionId:w.sessionId,update:{sessionUpdate:"_hydra_current_model_update",currentModel:w.currentModel}}).catch(()=>{}),null;s.log.info(w.logMessage);let{modelId:m}=w,v=await w.session.forwardModelChange(m,g);return w.session.applyAgentConfigOptionResponse(v,"model"),w.session.applyModelChange(m),v}),u.onRequest("session/set_mode",async g=>{let p=g,w=p?.sessionId;if(typeof w=="string"&&y(w,"session/set_mode"),!p||typeof p.sessionId!="string")throw O(x.InvalidParams,"session/set_mode requires string sessionId");if(typeof p.modeId!="string")throw O(x.InvalidParams,"session/set_mode requires string modeId");let m=Ee(e.manager,p.sessionId),v=await m.forwardRequest("session/set_mode",g);return m.applyModeChange(p.modeId),v}),u.onRequest("session/set_config_option",async g=>{let p=g,w=b=>O(x.InvalidParams,b),m=p?.sessionId;if(typeof m=="string"&&y(m,"session/set_config_option"),!p||typeof p.sessionId!="string")throw w("session/set_config_option requires string sessionId");if(typeof p.configId!="string")throw w("session/set_config_option requires string configId");if(typeof p.value!="string")throw w("session/set_config_option requires string value");let v=Ee(e.manager,p.sessionId),S=v.buildConfigOptions().find(b=>b.id===p.configId);if(!S)throw w(`unknown configId ${JSON.stringify(p.configId)} for this session`);if(!S.options.some(b=>b.value===p.value))throw w(`value ${JSON.stringify(p.value)} is not valid for configId ${JSON.stringify(p.configId)}`);switch(p.configId){case"model":{if(p.value!==v.currentModel){let b=await v.forwardModelChange(p.value);v.applyAgentConfigOptionResponse(b,"model")}v.applyModelChange(p.value);break}case"mode":{p.value!==v.currentMode&&await v.forwardRequest("session/set_mode",{sessionId:p.sessionId,modeId:p.value}),v.applyModeChange(p.value);break}case"agent":{p.value!==v.agentId&&await v.setAgent(p.value);break}default:{let b=await v.forwardRequest("session/set_config_option",{sessionId:p.sessionId,configId:p.configId,value:p.value});v.applyAgentConfigOptionResponse(b,p.configId)&&v.broadcastConfigOptions()}}return{configOptions:v.buildConfigOptions()}}),u.setDefaultHandler(async(g,p)=>{let w=new Set(["hydra-acp/attention/set","hydra-acp/attention/clear"]),m=p.startsWith("session/"),v=p.startsWith("hydra-acp/");if(!m&&!v||g===null||typeof g!="object"||w.has(p))throw O(x.MethodNotFound,`Method not found: ${p}`);let S=g.sessionId;if(typeof S!="string")throw O(x.MethodNotFound,`Method not found: ${p}`);return y(S,p),Ee(e.manager,S).forwardRequest(p,g)})})}async function ak(s,e){let t=s??{};if(typeof t.methodId!="string"||t.methodId.length===0)throw O(x.InvalidParams,"authenticate requires a non-empty methodId string");let n=t.methodId,r=t._meta?.["hydra-acp"],o=typeof r?.sessionId=="string"?r.sessionId:void 0,i=typeof r?.agentId=="string"?r.agentId:void 0,a=o!==void 0?e.manager.getAgentForSession(o):void 0;if(!a||!a.isAlive()){let h=i??e.defaultAgent;a=await e.manager.bootstrapAgentForAuth(h)}let d=a.authMethods??[],c=d.find(h=>h.id===n);if(!c){let h=d.map(f=>f.id);throw O(x.InvalidParams,`authenticate: methodId ${JSON.stringify(n)} is not advertised by agent ${a.agentId}; valid: [${h.map(f=>JSON.stringify(f)).join(", ")}]`)}let u=c._meta?.type,l=(()=>{let h=c._meta?.["terminal-auth"];if(h&&typeof h=="object"&&!Array.isArray(h))return h})();if((c.type??(u==="agent"||u==="terminal"?u:l!==void 0?"terminal":"agent"))==="terminal"){let h=(m,v)=>{if(!Array.isArray(m))throw O(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be a string[]; got ${m===null?"null":typeof m}`);for(let S of m)if(typeof S!="string")throw O(x.InvalidParams,`authenticate: method ${JSON.stringify(n)} ${v} must be string[]; got non-string entry ${JSON.stringify(S)}`);return m},f=await e.manager.planSpawnForAgent(a.agentId),k,g;if(l?.args!==void 0){let m=typeof l.command=="string"?l.command:void 0;k=m!==void 0&&Ol.isAbsolute(m)?m:f.command,g=h(l.args,'_meta["terminal-auth"].args')}else{let m=c.args!==void 0?{raw:c.args,label:"args"}:c._meta?.args!==void 0?{raw:c._meta.args,label:"_meta.args"}:void 0,v=m!==void 0?h(m.raw,m.label):[];k=f.command,g=[...f.args,...v]}let p={};for(let[m,v]of Object.entries(process.env))typeof v=="string"&&(p[m]=v);Object.assign(p,f.env);let w=Fl.homedir();return console.error(`[authenticate] terminal-auth requested agentId=${a.agentId} methodId=${n}`),{kind:"terminal",command:k,args:g,env:p,cwd:w}}try{return await a.connection.request("authenticate",{methodId:n})}catch(h){throw wt(h,a)}}async function dk(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 Or(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(Qa,t).catch(()=>{})}}function Nr(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 Dr(s){let e=s.availableModels();if(e.length===0)return;let t=e.map(r=>{let o={modelId:r.modelId};return r.name!==void 0&&(o.name=r.name),r.description!==void 0&&(o.description=r.description),o});return{currentModelId:s.currentModel??e[0].modelId,availableModels:t}}async function ck(s,e,t,n){return e?await n.isRetiredGeneration(s,e.upstreamSessionId)?{kind:"ignore",logMessage:`session/attach ignoring stale resume hint sessionId=${s} hintUpstream=${e.upstreamSessionId} recordUpstream=${t} (retired generation)`}:{kind:"honor"}:{kind:"none"}}function uk(s,e){if(!s||typeof s!="object")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires params",logMessage:"session/set_model rejected: params not an object"};let t=s;if(typeof t.sessionId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string sessionId",logMessage:"session/set_model rejected: missing/non-string sessionId"};if(typeof t.modelId!="string")return{kind:"error",code:x.InvalidParams,message:"session/set_model requires string modelId",logMessage:`session/set_model rejected: missing/non-string modelId sessionId=${t.sessionId}`};let n=e.get(t.sessionId);if(!n)return{kind:"error",code:x.SessionNotFound,message:`session ${t.sessionId} not found`,logMessage:`session/set_model rejected: session not found sessionId=${t.sessionId}`};let r=n.availableModels(),o=Yt(t.modelId,r);if(o.kind==="none")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model passthrough (no availableModels) sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="exact")return{kind:"ok",session:n,modelId:t.modelId,logMessage:`session/set_model accepted sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)}`};if(o.kind==="resolved")return{kind:"ok",session:n,modelId:o.modelId,logMessage:`session/set_model resolved sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} \u2192 ${JSON.stringify(o.modelId)}`};let i=r.map(d=>d.modelId).join(", "),a=o.kind==="ambiguous"?`ambiguous (trailing-segment matches [${o.candidates.join(", ")}])`:"not in availableModels";return n.currentModel!==void 0&&n.currentModel.length>0?{kind:"no_op",session:n,sessionId:t.sessionId,currentModel:n.currentModel,logMessage:`session/set_model no_op (resyncing client) sessionId=${t.sessionId} requested=${JSON.stringify(t.modelId)} ${a} actual=${JSON.stringify(n.currentModel)} agentId=${n.agentId} known=[${i}]`}:{kind:"error",code:x.InvalidParams,message:`model "${t.modelId}" is ${a==="not in availableModels"?"not in this session's availableModels":a} (agent ${n.agentId}); known models: ${i}`,logMessage:`session/set_model rejected sessionId=${t.sessionId} modelId=${JSON.stringify(t.modelId)} ${a} agentId=${n.agentId} known=[${i}] (no current model to fall back to)`}}async function lk(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0;if(!r)throw O(x.InvalidParams,"transformer/attach requires sessionId");if(!t.transformers)throw O(x.InternalError,"transformer manager not configured");let o=t.transformers.resolveChain([e])[0];if(!o)throw O(x.InternalError,`transformer ${e} is not connected (call hydra-acp/transformer/initialize first)`);return Ee(t.manager,r).addTransformer(o),{ok:!0}}async function fk(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw O(x.InvalidParams,"hydra-acp/attention/set requires string sessionId");if(!o)throw O(x.InvalidParams,"hydra-acp/attention/set requires string reason");return Ee(t.manager,r).setAttentionFlag(e,o,n.payload),{ok:!0}}async function pk(s,e,t){let n=s??{},r=typeof n.sessionId=="string"?n.sessionId:void 0,o=typeof n.reason=="string"?n.reason:void 0;if(!r)throw O(x.InvalidParams,"hydra-acp/attention/clear requires string sessionId");if(!o)throw O(x.InvalidParams,"hydra-acp/attention/clear requires string reason");return Ee(t.manager,r).clearAttentionFlag(e,o),{ok:!0}}function gk(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:Jn(s.currentUsage),forkedFromSessionId:s.forkedFromSessionId,forkedFromMessageId:s.forkedFromMessageId,forkSynthesisState:s.forkSynthesisState,originatingClient:s.originatingClient,interactive:s.interactive,updatedAt:s.createdAt??new Date().toISOString(),attachedClients:0,status:"cold",busy:!1,armedTasks:0,awaitingInput:!1},t={currentMode:s.currentMode,agentArgs:s.agentArgs,availableCommands:s.agentCommands,availableModes:s.agentModes,availableModels:s.agentModels,armedTaskList:[]};return{[le]:bs(e,t)}}function Lr(s,e,t={}){let n=s.liveListEntry(e),r={clientId:t.clientId,currentMode:e.currentMode,agentArgs:e.agentArgs,availableCommands:e.mergedAvailableCommands(),availableModes:e.availableModes(),availableModels:e.availableModels(),turnStartedAt:e.turnStartedAt,agentCapabilities:e.agentCapabilities,queue:e.queueSnapshot(),armedTaskList:e.armedBackgroundTasks,...t.resurrected===!0?{resurrected:!0}:{}};return xn(e.agentMeta,bs(n,r))}function mk(){return{protocolVersion:1,agentInfo:{name:"hydra",version:ue},agentCapabilities:{promptCapabilities:{image:!0,audio:!0,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0},loadSession:!0,auth:{logout:{}},sessionCapabilities:{attach:{},list:{},resume:{},delete:{},close:{},fork:{}}},authMethods:[{id:"proxy",name:"Hydra proxy",type:"agent",description:"Hydra proxies authentication to the downstream agent selected per session"}],_meta:{...xn(void 0,{prompt:{queueing:!0,cancelling:!0,updating:!0,amending:!0,pipelining:!1},agents:{list:!0,installProgress:!0},session:{fork:{forkAt:!0,agentSwap:!0,synthesis:!0,model:!0},side:{selection:!0},rewind:{}}}),steering:{supported:!0}}}}function hk(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 Dl(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 bt(s,e,t,n,r){return{clientId:r??`cli_${Di(8)}`,connection:s,clientInfo:n??t.clientInfo,...t.elicitationForm===!0?{elicitationForm:!0}:{}}}function mn(s,e,t){let n=s.attached.get(t);n&&(e.detach(n.clientId),s.attached.delete(t))}var Hr=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 wk}from"crypto";import{McpServer as kk}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as vk}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as we}from"zod";import{isInitializeRequest as yk}from"@modelcontextprotocol/sdk/types.js";function hn(s,e){return s.method==="POST"&&s.headers["mcp-session-id"]===void 0&&yk(s.body)&&e?.transport.sessionId!==void 0}async function Qe(s){try{await s.transport.close()}catch{}try{await s.server.close()}catch{}}function Li(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 Re(s){return{content:[{type:"text",text:JSON.stringify(s)}],structuredContent:s}}var Ll="Bearer ";function yn(s){let e=s.headers.authorization;if(typeof e!="string"||!e.startsWith(Ll))return;let t=e.slice(Ll.length).trim();return t.length>0?t:void 0}function bk(s){let e=new kk({name:"hydra-acp-stdin",version:"1.0.0"},{instructions:"Piped input from `hydra cat --stream` is exposed here as a byte stream. Use `tail` for the latest N bytes (good for finding the end of a log), `head` for the first N bytes (good for headers/preamble), `read` for windowed reads against an absolute byte cursor, `wait_for_more` to block until new bytes arrive past a cursor, and `info` for the current cursors/capacity/closed status. Byte payloads come back base64-encoded."});return e.registerTool("tail",{description:"Return the most recent `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means older bytes existed but have been evicted from the ring.",inputSchema:{bytes:we.number().int().min(1).describe("How many trailing bytes to return.")}},async({bytes:t})=>{let n=s.streamTail(t);return Re(n)}),e.registerTool("head",{description:"Return the first `bytes` bytes of piped stdin (capped server-side, default 64 KiB max). `truncated:true` means the head has already been evicted from the ring and the returned bytes start at the oldest still-resident cursor.",inputSchema:{bytes:we.number().int().min(1).describe("How many leading bytes to return.")}},async({bytes:t})=>{let n=s.streamHead(t);return Re(n)}),e.registerTool("read",{description:"Read up to `max_bytes` bytes starting at absolute byte `cursor`. Returns `{bytes, nextCursor, gap?, eof?}` \u2014 `gap` is the number of bytes silently skipped because the ring had evicted them; `eof:true` means the producer closed and there is nothing left to read.",inputSchema:{cursor:we.number().int().min(0).describe("Absolute byte offset to start reading from. Use 0 to read from the very beginning (may produce a gap if old bytes have been evicted)."),max_bytes:we.number().int().min(1).optional().describe("Optional cap on how many bytes to return. Server caps at 64 KiB regardless."),wait_ms:we.number().int().min(0).optional().describe("If no bytes are available, block up to this many ms for more (capped server-side at 60_000).")}},async({cursor:t,max_bytes:n,wait_ms:r})=>{let o=await s.streamRead(t,n,r);return Re(o)}),e.registerTool("wait_for_more",{description:"Block until bytes are available past `cursor`, the stream closes, or `timeout_ms` elapses. Returns one of {data, eof, timeout} plus the current `writeCursor`. Use this when you've consumed everything up to a cursor and want to wait for more without busy-polling.",inputSchema:{cursor:we.number().int().min(0).describe("The cursor you've already consumed up to."),timeout_ms:we.number().int().min(0).describe("Maximum ms to block (server caps at 60_000).")}},async({cursor:t,timeout_ms:n})=>{let r=await s.streamWaitFor(t,n),o=s.streamInfo();return Re({outcome:r,writeCursor:o.writeCursor,closed:o.closed})}),e.registerTool("grep",{description:"Scan piped stdin line-by-line and return lines matching `pattern`. Prefer this over `read` when the question is 'find lines that mention X' \u2014 it filters server-side so you don't pull and decode 64 KiB base64 windows. Returns `{matches: [{cursor, line, before?, after?}], truncated, nextCursor, gap?, scannedBytes, eof?}`. Lines come back as decoded UTF-8 strings (not base64). When `truncated:true`, re-call with `cursor: nextCursor` to resume.",inputSchema:{pattern:we.string().min(1).describe("Search pattern. Treated as a JavaScript regular expression by default (set `regex:false` for a literal substring match)."),regex:we.boolean().optional().describe("Default true. Pass false to treat `pattern` as a literal substring."),case_insensitive:we.boolean().optional().describe("Default false. Pass true for case-insensitive matching."),invert:we.boolean().optional().describe("Default false. Pass true to return lines that do NOT match the pattern."),max_matches:we.number().int().min(1).optional().describe("Default 100. Capped server-side at 1000."),max_bytes:we.number().int().min(1).optional().describe("Default 64 KiB output. Capped server-side at 256 KiB."),context_before:we.number().int().min(0).optional().describe("Default 0. Number of lines before each match to include (capped at 20)."),context_after:we.number().int().min(0).optional().describe("Default 0. Number of lines after each match to include (capped at 20)."),cursor:we.number().int().min(0).optional().describe("Optional absolute byte offset to start scanning from. Omit to scan from the oldest still-resident byte. Pass the `nextCursor` from a previous truncated call to resume.")}},async t=>{let n={pattern:t.pattern};t.regex!==void 0&&(n.regex=t.regex),t.case_insensitive!==void 0&&(n.caseInsensitive=t.case_insensitive),t.invert!==void 0&&(n.invert=t.invert),t.max_matches!==void 0&&(n.maxMatches=t.max_matches),t.max_bytes!==void 0&&(n.maxBytes=t.max_bytes),t.context_before!==void 0&&(n.contextBefore=t.context_before),t.context_after!==void 0&&(n.contextAfter=t.context_after),t.cursor!==void 0&&(n.cursor=t.cursor);let r=s.streamGrep(n);return Re(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 Re(t)}),e}var Sk=1e4;function Hl(s,e){let t=new Map,n=new Map,r=new Set;async function o(c,u){let l=bk(u),y=new vk({sessionIdGenerator:()=>wk()});await l.connect(y);let h={server:l,transport:y};return t.set(c,h),r.has(c)||(r.add(c),e.addDisposer(c,async()=>{r.delete(c);let f=t.get(c);t.delete(c),f!==void 0&&await Qe(f)})),h}async function i(c,u){let l=t.get(c);if(l!==void 0)return l.transport;let y=n.get(c);return y===void 0&&(y=o(c,u).finally(()=>{n.delete(c)}),n.set(c,y)),(await y).transport}async function a(c,u){let l=yn(c);if(l===void 0){u.code(401).send({error:"missing bearer token"});return}let y=e.lookup(l);if(y===void 0){u.code(404).send({error:"unknown stdin token"});return}let h;if(y.session!==void 0)h=y.session;else{let g,p=new Promise(m=>{g=setTimeout(()=>m(void 0),Sk)}),w=await Promise.race([y.sessionReady.catch(()=>{}),p]);if(g!==void 0&&clearTimeout(g),w===void 0){u.code(503).send({error:"session not ready"});return}h=w}let f=t.get(l);f!==void 0&&hn(c,f)&&(t.delete(l),Qe(f));let k=await i(l,h);u.hijack(),await k.handleRequest(c.raw,u.raw,c.body)}let d={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-stdin",d,async(c,u)=>{await a(c,u)}),s.get("/mcp/hydra-acp-stdin",d,async(c,u)=>{await a(c,u)}),s.delete("/mcp/hydra-acp-stdin",d,async(c,u)=>{await a(c,u)})}import{randomUUID as Ik}from"crypto";import{McpServer as Ak}from"@modelcontextprotocol/sdk/server/mcp.js";import{StreamableHTTPServerTransport as Ck}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{z as Ye}from"zod";function Rk(s){switch(s){case"prompt_received":return"user";case"tool_call":case"tool_call_update":return"tool";default:return"agent"}}var jl=2e3,Ul=2e4;function xk(s,e,t){if(e!=="tool_call"&&e!=="tool_call_update")return Zt([s]);let n=[],r=_n(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=Ds(t);return i!==void 0&&n.push(i),n.join(`
228
+ `)}function Tk(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 Ek(s){let e=new Ak({name:"hydra-acp-recall",version:"1.0.0"},{instructions:"Search and retrieve detail from this session's pre-compaction history. After a compaction summary replaces earlier conversation in working memory, these tools let you page back specifics on demand. Use `search` to find entries by keyword, `range` to pull a contiguous slice verbatim, and `tool_calls` to enumerate prior tool invocations. These tools only return results once the session has been compacted at least once."});return e.registerTool("search",{description:"Search this session's prior conversation history (the part that was compacted out of your working memory) by keyword. Covers assistant and user messages, the arguments of every tool call including full shell commands, and what those calls printed. Returns matching entry ids with short snippets so you can decide which to pull in full via `range`. Use this when the compaction summary mentions something but you need the verbatim detail.",inputSchema:{query:Ye.string().min(1).describe("Case-insensitive substring to search for."),limit:Ye.number().int().min(1).max(50).optional().describe("Maximum number of matches to return (default 10, max 50)."),include_tool_calls:Ye.boolean().optional().describe("Whether to include tool_call entries in the search (default true).")}},async({query:t,limit:n=10,include_tool_calls:r=!0})=>{let o=await s();if(!o.summarizedThroughEntry||o.summarizedThroughEntry===0)return Re({matches:[],total_matched:0,truncated:!1,note:"This session has no compacted history. `search` retrieves detail from entries that were summarized out of the working conversation; nothing has been summarized yet."});let i=[],a=t.toLowerCase();for await(let{entryId:c,entry:u}of o.iterRecallNewestFirst()){let l=Li(u);if(!l)continue;let{kind:y,update:h}=l;if((y==="tool_call"||y==="tool_call_update")&&!r)continue;let f=xk(u,y,h),k=f.toLowerCase().indexOf(a);if(k<0)continue;let g=Rk(y),p=Tk(f,k),w=typeof u.recordedAt=="number"?String(u.recordedAt):void 0;if(i.push({entryId:c,speaker:g,snippet:p,timestamp:w}),i.length>=n)break}i.sort((c,u)=>c.entryId-u.entryId);let d=i.length>=n;return Re({matches:i,total_matched:i.length,truncated:d})}),e.registerTool("range",{description:"Pull a contiguous range of prior conversation entries verbatim from this session's pre-compaction history, including each tool call's arguments and what it printed. Use after `search` narrows in on what you need. Capped at 50 entries per call.",inputSchema:{from_entry:Ye.number().int().min(0).describe("Zero-based index of the first entry to include (inclusive)."),to_entry:Ye.number().int().min(0).describe("Zero-based index of the last entry to include (inclusive).")}},async({from_entry:t,to_entry:n})=>{let r=await s();if(!r.summarizedThroughEntry||r.summarizedThroughEntry===0)return Re({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 Re({text:"",entry_count:0,truncated:!1});let a=Math.min(t,i-1),d=Math.min(n,i-1),c=a>t||d<n;if(a>d)return{content:[{type:"text",text:""}],structuredContent:{text:"",entry_count:0,truncated:c}};let u=await r.sliceRecallHistory(a,d),l=Zt(u,{toolOutput:{maxPerCall:jl,maxTotal:Ul}});return{content:[{type:"text",text:l}],structuredContent:{text:l,entry_count:u.length,truncated:c}}}),e.registerTool("tool_calls",{description:"Search this session's prior tool invocations by tool name, ACP kind, and/or file path. Returns when each tool was called, its arguments (including the full shell command), the result status, and what the call printed. Use this to recall which files were read/edited, what shell commands ran, and what they output.",inputSchema:{tool_name:Ye.string().optional().describe("Case-insensitive substring of the tool name. Names vary by agent for the same tool (Bash, Terminal, bash), so prefer `kind` when you want every shell invocation."),kind:Ye.string().optional().describe("ACP tool kind: execute (shell), read, edit, think, other. Agent-independent, unlike tool_name."),file_path:Ye.string().optional(),limit:Ye.number().int().min(1).max(100).optional(),include_output:Ye.boolean().optional().describe("Include what each call printed (default true). Set false when you only need the commands and not their results.")}},async({tool_name:t,kind:n,file_path:r,limit:o=20,include_output:i=!0})=>{let a=await s();if(!a.summarizedThroughEntry||a.summarizedThroughEntry===0)return Re({calls:[],truncated:!1,note:"This session has no compacted history. `tool_calls` retrieves tool invocations from the pre-compaction transcript; nothing has been compacted yet."});let d=typeof t=="string"&&t.length>0,c=typeof n=="string"&&n.length>0,u=typeof r=="string"&&r.length>0;if(!d&&!c&&!u)throw new Error("tool_calls: at least one of tool_name, kind, or file_path must be provided");let l=new Map,y=Math.max(o*4,200);for await(let{entryId:w,entry:m}of a.iterRecallNewestFirst()){let v=Li(m);if(!v)continue;let{kind:S,update:b}=v;if(S!=="tool_call"&&S!=="tool_call_update")continue;let I=typeof b.toolCallId=="string"&&b.toolCallId.length>0?b.toolCallId:`__noid_${w}`,A=l.get(I);if(A||(A={entryId:w,toolName:"(unnamed)",nameAuthoritative:!1,rawInput:{},locations:[],status:"in_progress"},l.set(I,A)),w<A.entryId&&(A.entryId=w),!A.nameAuthoritative){let R=_n(b);R!==void 0?(A.toolName=R,A.nameAuthoritative=!0):typeof b.name=="string"&&b.name.length>0?(A.toolName=b.name,A.nameAuthoritative=!0):S==="tool_call"&&typeof b.title=="string"&&b.title.length>0&&(A.toolName=b.title,A.nameAuthoritative=!0)}if(A.kind===void 0&&typeof b.kind=="string"&&b.kind.length>0&&(A.kind=b.kind),A.output===void 0){let R=Ds(b);R!==void 0&&(A.output=R)}let T=b.rawInput;if(T&&typeof T=="object"&&!Array.isArray(T)&&Object.keys(T).length>0)for(let[R,P]of Object.entries(T))A.rawInput[R]===void 0&&(A.rawInput[R]=P);if(Array.isArray(b.locations))for(let R of b.locations){let P=R?.path;typeof P=="string"&&P.length>0&&!A.locations.includes(P)&&A.locations.push(P)}if(typeof b.status=="string"&&A.status==="in_progress"&&(A.status=b.status),m.recordedAt!==void 0&&A.timestamp===void 0&&(A.timestamp=String(m.recordedAt)),l.size>=y)break}let h=[...l.keys()].sort((w,m)=>l.get(w).entryId-l.get(m).entryId),f=[],k=Ul,g=!1;for(let w of h){let m=l.get(w);if(m.toolName=Eo({name:m.toolName,rawInput:m.rawInput,...m.kind!==void 0?{kind:m.kind}:{}}),d&&!m.toolName.toLowerCase().includes(t.toLowerCase())||c&&(m.kind??"").toLowerCase()!==n.toLowerCase())continue;if(u){let b=r.toLowerCase(),I=["file_path","filePath","path"],A=!1;for(let T of I){let R=m.rawInput[T];if(typeof R=="string"&&R.toLowerCase().includes(b)){A=!0;break}}if(!A){for(let T of m.locations)if(T.toLowerCase().includes(b)){A=!0;break}}if(!A)continue}let v={};for(let[b,I]of Object.entries(m.rawInput))typeof I=="string"?v[b]=I.length>500?I.slice(0,497)+"\u2026":I:(typeof I=="number"||typeof I=="boolean")&&(v[b]=I);m.locations.length>0&&v.locations===void 0&&(v.locations=m.locations);let S={entryId:m.entryId,tool:m.toolName,args:v,status:m.status,timestamp:m.timestamp};if(m.kind!==void 0&&(S.kind=m.kind),i&&m.output!==void 0){let b=m.output,I=Math.min(jl,k);if(I<=0)g=!0;else{let A=b.length<=I?b:b.slice(0,I-1)+"\u2026";S.output=A,S.outputBytes=b.length,S.outputTruncated=A.length<b.length,k-=A.length}}if(f.push(S),f.length>=o)break}let p=f.length>=o;return Re({calls:f,truncated:p,...g?{outputBudgetExhausted:g}:{}})}),e}var Pk=1e4;function Bl(s,e){let t=new Map,n=new Map,r=new Set;async function o(c,u){let l=Ek(u),y=new Ck({sessionIdGenerator:()=>Ik()});await l.connect(y);let h={server:l,transport:y};return t.set(c,h),r.has(c)||(r.add(c),e.addDisposer(c,async()=>{r.delete(c);let f=t.get(c);t.delete(c),f!==void 0&&await Qe(f)})),h}async function i(c,u){let l=t.get(c);if(l!==void 0)return l.transport;let y=n.get(c);return y===void 0&&(y=o(c,u).finally(()=>{n.delete(c)}),n.set(c,y)),(await y).transport}async function a(c,u){let l=yn(c);if(l===void 0){u.code(401).send({error:"missing bearer token"});return}let y=e.lookup(l);if(y===void 0){u.code(404).send({error:"unknown recall token"});return}let h=async()=>{if(y.session!==void 0)return y.session;let g,p=new Promise(m=>{g=setTimeout(()=>m(void 0),Pk)}),w=await Promise.race([y.sessionReady.catch(()=>{}),p]);if(g!==void 0&&clearTimeout(g),w===void 0)throw new Error("recall: session not ready");return w},f=t.get(l);f!==void 0&&hn(c,f)&&(t.delete(l),Qe(f));let k=await i(l,h);u.hijack(),await k.handleRequest(c.raw,u.raw,c.body)}let d={config:{skipAuth:!0}};s.post("/mcp/hydra-acp-recall",d,async(c,u)=>{await a(c,u)}),s.get("/mcp/hydra-acp-recall",d,async(c,u)=>{await a(c,u)}),s.delete("/mcp/hydra-acp-recall",d,async(c,u)=>{await a(c,u)})}var jr=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 Lk}from"@modelcontextprotocol/sdk/server/streamableHttp.js";import{randomUUID as Hk}from"crypto";import{Server as Mk}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as _k,ListToolsRequestSchema as $k}from"@modelcontextprotocol/sdk/types.js";function Wl(s,e,t,n){let r=typeof t=="function"?async()=>t():async()=>t,o=new Mk({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($k,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(_k,async(a,d)=>{let c=a.params.name,u=d._meta?.progressToken??d.requestId,l=Ok(u,d.sendNotification);try{let y=await r(),h=await Nk(e.connection,s,c,a.params.arguments??{},y);return Dk(h,c)}catch(y){return Hi(y instanceof Error?y.message:String(y))}finally{l()}}),o}var Fk=15e3;function Ok(s,e,t=Fk){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 Nk(s,e,t,n,r){return await s.request("hydra-acp/mcp_tools/invoke",{server:e,tool:t,args:n,sessionId:r})}function Dk(s,e){if(s===null||typeof s!="object")return Hi(`extension ${e} returned non-object`);let t=s;return Array.isArray(t.content)?t:Hi(`extension ${e} omitted content array`)}function Hi(s){return{content:[{type:"text",text:s}],isError:!0}}var jk=1e4;function ql(s,e,t){let n=new Map;function r(c){for(let u of n.values()){let l=u.get(c);l!==void 0&&(u.delete(c),Qe(l))}}async function o(c,u){for(let[l,y]of n){if(e.lookup(l)?.session?.sessionId!==c)continue;let f=y.get(u);if(f!==void 0)try{await f.server.sendToolListChanged()}catch{}}}t.onChange(c=>{r(c)});async function i(c,u){let l=n.get(c);l===void 0&&(l=new Map,n.set(c,l),e.addDisposer(c,async()=>{let m=n.get(c);if(m!==void 0){n.delete(c);for(let v of m.values())await Qe(v)}}));let y=l.get(u);if(y!==void 0)return y.transport;let h=t.lookup(u);if(h===void 0)return;let p=Wl(u,h,async()=>{let m=e.lookup(c);if(m===void 0)throw new Error("mcp token no longer bound");if(m.session!==void 0)return m.session.sessionId;let v,S=new Promise(I=>{v=setTimeout(()=>I(void 0),jk)}),b=await Promise.race([m.sessionReady.catch(()=>{}),S]);if(v!==void 0&&clearTimeout(v),b===void 0)throw new Error("session not ready");return b.sessionId},{peekSessionId:()=>e.lookup(c)?.session?.sessionId,fetchSessionTools:async m=>{let v=await h.connection.request("hydra-acp/mcp_tools/list_tools",{sessionId:m});if(!v||typeof v!="object")return;let S=v.tools;if(!Array.isArray(S))return;let b=[];for(let I of S){if(!I||typeof I!="object")continue;let A=I;if(typeof A.name!="string"||A.name.length===0||typeof A.description!="string"||A.inputSchema===null||typeof A.inputSchema!="object")continue;let T={name:A.name,description:A.description,inputSchema:A.inputSchema};A.outputSchema!==null&&typeof A.outputSchema=="object"&&(T.outputSchema=A.outputSchema),b.push(T)}return b}}),w=new Lk({sessionIdGenerator:()=>Hk()});return await p.connect(w),l.set(u,{server:p,transport:w}),w}async function a(c,u){let l=yn(c);if(l===void 0){u.code(401).send({error:"missing bearer token"});return}if(e.lookup(l)===void 0){u.code(404).send({error:"unknown mcp token"});return}let h=c.params.name,f=n.get(l),k=f?.get(h);k!==void 0&&hn(c,k)&&(f?.delete(h),Qe(k));let g=await i(l,h);if(g===void 0){u.code(404).send({error:`unknown mcp server: ${h}`});return}u.hijack(),await g.handleRequest(c.raw,u.raw,c.body)}let d={config:{skipAuth:!0}};return s.post("/mcp/:name",d,async(c,u)=>{await a(c,u)}),s.get("/mcp/:name",d,async(c,u)=>{await a(c,u)}),s.delete("/mcp/:name",d,async(c,u)=>{await a(c,u)}),{notifyToolListChanged:o}}async function Ql(s,e,t={}){Vk(s),Xr(s.daemon.scrubEnv);let n=s,r=s.daemon.tls?await Xe.readFile(ie(s.daemon.tls.key)):void 0,o=s.daemon.tls?await Xe.readFile(ie(s.daemon.tls.cert)):void 0;await Xe.mkdir(E.home(),{recursive:!0});let{stream:i,fileStream:a,closeFile:d}=await zk(s.daemon.logLevel),c=Uk({logger:{level:s.daemon.logLevel,stream:i},bodyLimit:256*1024*1024});await c.register(Bk,{options:{handleProtocols:da}}),ro(N=>{c.log.info(N)}),ao(N=>{c.log.info(N)});let u=await hr.load(),l=await xr.load();$i(),Mi(l);let y=new Fr(l);y.start();let h=new Cr(l);h.start();let f=new br,k=new vr,g=new yr(e),p=new kr([g,new wr(u),k]),w=Ru({validator:p});c.addHook("onRequest",async(N,Ce)=>{N.routeOptions.config?.skipAuth||N.url==="/acp"||N.url?.startsWith("/acp?")||(await w(N,Ce),!Ce.sent&&N.authIdentity?.startsWith("script:")&&!Tu(N.method,N.routeOptions.url)&&Ce.code(403).send({error:"script tokens may only access read-only session data"}))});let m=setInterval(()=>{u.sweepExpired()},300*1e3);m.unref();let v=setInterval(()=>{f.sweepExpired()},300*1e3);v.unref();let S=new ks(s,{onFetched:()=>{fu(S,T)},onStaleFallback:(N,Ce)=>{let kn=Math.round(Ce/36e5),vn=kn>=48?`${Math.round(kn/24)}d`:`${kn}h`;c.log.warn(`registry fetch failed (${N.message}); serving stale cache last synced ${vn} ago; agent versions may be outdated ('hydra registry refresh' to retry)`)}});bi(N=>c.log.info(N));let b={info:N=>c.log.info(N),warn:N=>c.log.warn(N)},I=N=>ut.spawn({...N,stderrTailBytes:s.daemon.agentStderrTailBytes,logger:b});ga(s.compressToolContent);let A=new gr,T=new ir(S,I,void 0,{idleTimeoutMs:s.daemon.sessionIdleTimeoutSeconds*1e3,...s.daemon.backgroundTaskTracking!==void 0?{backgroundTaskTracking:s.daemon.backgroundTaskTracking}:{},orphanTimeoutMs:s.daemon.nonInteractiveOrphanTimeoutSeconds*1e3,sessionDefaults:s.sessionDefaults,synopsisAgent:s.synopsisAgent,synopsisModel:s.synopsisModel,compactionAgent:s.compaction?.agent,compactionModel:s.compaction?.model,defaultTransformers:s.defaultTransformers,sessionHistoryMaxEntries:s.daemon.sessionHistoryMaxEntries,sessionHistoryArchiveMaxBytes:s.daemon.sessionHistoryArchiveMaxBytes,sessionHistoryArchiveTiers:s.daemon.sessionHistoryArchiveTiers,logger:b,npmRegistry:s.npmRegistry,extensionCommands:A,defaultCwd:s.defaultCwd,disableWorkspaceSnapshots:s.disableWorkspaceSnapshots,elicitationForms:s.elicitationForms}),R=new $r(l,void 0,{resolvesLocally:async N=>await T.resolveCanonicalId(N)!==void 0,cache:h}),P=new fr(ta(s),void 0,{tokenRegistry:k}),$=new pr(na(s),void 0,{tokenRegistry:k}),L=[];Zu(c,ue,mu(s),()=>L);let J=new Date().toISOString();il(c,J,t.requestShutdown);let z=new Hr,U=new jr,j,ee=()=>{if(j!==void 0)return j;let N=c.server.address();return j=`http://127.0.0.1:${N&&typeof N=="object"?N.port:s.daemon.port}`,j},se={agentId:s.defaultAgent,cwd:s.defaultCwd,publicHost:s.daemon.publicHost,host:s.daemon.host,port:s.daemon.port,compaction:s.compaction};Yu(c,T,se,{extensionMcp:U,mcpTokenRegistry:z,getDaemonOrigin:ee},l,h),zu(c,{store:l,localMiss:{resolvesLocally:async N=>await T.resolveCanonicalId(N)!==void 0,cache:h}}),Xu(c,S,T,{npmRegistry:s.npmRegistry}),al(c,P),dl(c,$);let xe={host:s.daemon.host,port:s.daemon.port,...s.daemon.publicHost!==void 0?{publicHost:s.daemon.publicHost}:{},...s.daemon.tls?{tls:{cert:ie(s.daemon.tls.cert),key:ie(s.daemon.tls.key)}}:{}};cl(c,()=>({defaultAgent:n.defaultAgent,defaultCwd:n.defaultCwd,sessionDefaults:{...n.sessionDefaults},...n.synopsisAgent!==void 0?{synopsisAgent:n.synopsisAgent}:{},...n.synopsisModel!==void 0?{synopsisModel:n.synopsisModel}:{},defaultTransformers:[...n.defaultTransformers],listen:xe})),gl(c,{store:u,rateLimiter:f,staticTokenValidator:g}),Il(c,{store:l,health:y}),Tl(c,{processRegistry:k}),Hl(c,z),Bl(c,z);let St=ql(c,z,U);Nl(c,{validator:p,manager:T,defaultAgent:s.defaultAgent,processRegistry:k,onExtensionVersion:(N,Ce)=>P.reportVersion(N,Ce),onTransformerVersion:(N,Ce)=>$.reportVersion(N,Ce),transformers:$,extensionCommands:A,mcpTokenRegistry:z,extensionMcp:U,extensionMcpControls:St,getDaemonOrigin:ee,registry:S,foreignSessions:R});let te=!!s.daemon.tls;await c.listen({host:te?"127.0.0.1":s.daemon.host,port:te?0:s.daemon.port});let Ze=c.server.address(),Ot=Ze&&typeof Ze=="object"?Ze.port:s.daemon.port,ls,Yl=s.daemon.host,ji=Ot;if(te&&r&&o){ls=await Jk({listenHost:s.daemon.host,listenPort:s.daemon.port,upstreamHost:"127.0.0.1",upstreamPort:Ot,tlsOptions:{key:r,cert:o},logger:c.log});let N=ls.address();N&&typeof N=="object"&&(ji=N.port)}await Xe.mkdir(E.home(),{recursive:!0}),await lu({pid:process.pid,host:Yl,port:ji,loopbackPort:Ot,startedAt:J});let Ui={daemonUrl:`http://127.0.0.1:${Ot}`,daemonHost:"127.0.0.1",daemonPort:Ot,serviceToken:e,daemonWsUrl:`ws://127.0.0.1:${Ot}/acp`,hydraHome:E.home()};P.setContext(Ui),$.setContext(Ui),await P.start(),await $.start();try{await T.reconcilePermissionFlags()}catch(N){c.log.warn(`permission flag reconcile failed: ${N.message}`)}try{await T.seedSessionIndex()}catch(N){c.log.warn(`session index seed failed: ${N.message}`)}T.resurrectPendingQueues().catch(N=>{c.log.warn(`queue replay scan failed: ${N.message}`)}),T.resumePendingCompactions().catch(N=>{c.log.warn(`compaction resume scan failed: ${N.message}`)}),T.resumePendingAgentSwaps().catch(N=>{c.log.warn(`agent-swap resume scan failed: ${N.message}`)});let Bi=s.daemon.agentSyncIntervalMinutes*60*1e3,Wi=Bi>0?pu({registry:S,manager:T,intervalMs:Bi,logger:b}):void 0,qi=s.daemon.sessionGcIntervalMinutes*60*1e3,Xl=s.daemon.sessionGcMaxAgeDays*24*60*60*1e3,zi=qi>0?gu({manager:T,intervalMs:qi,maxAgeMs:Xl,logger:b}):void 0,Zl=ku({bootConfig:s,apply:N=>{n=N,S.setConfig(N),T.setLiveConfig({sessionDefaults:N.sessionDefaults}),se.agentId=N.defaultAgent,se.cwd=N.defaultCwd,Xr(N.daemon.scrubEnv)},onDrift:N=>{L=N},logger:b});return{app:c,manager:T,registry:S,extensions:P,transformers:$,mcpTokenRegistry:z,extensionMcp:U,processRegistry:k,shutdown:async()=>{y.stop(),h.stop(),Zl(),zi&&zi(),Wi&&Wi(),clearInterval(m),clearInterval(v);let N=async(Ce,kn)=>{try{await kn()}catch(vn){c.log.warn(`shutdown step ${Ce} failed: ${vn instanceof Error?vn.message:String(vn)}`)}};await N("sessionTokenStore.flush",()=>u.flush()),await N("extensions.stop",()=>P.stop()),await N("transformers.stop",()=>$.stop()),await N("manager.closeAll",()=>T.closeAll()),await N("manager.flushSynopsis",()=>T.flushSynopsis(3e4)),await N("manager.shutdownSynopsis",()=>T.shutdownSynopsis()),await N("manager.flushMetaWrites",()=>T.flushMetaWrites()),await N("manager.flushHistoryWrites",()=>T.flushHistoryWrites()),ro(null),ao(null),bi(null),ls&&await N("tlsTerminator.close",()=>new Promise(Ce=>ls.close(()=>Ce()))),await N("app.close",()=>c.close());try{Vl.unlinkSync(E.pidFile())}catch{}await N("fileStream.flushSync",()=>a.flushSync()),await N("fileStream.close",d)}}}var Jl=20;async function qk(s,e){let t=wn.dirname(s),n=wn.basename(s,".log"),r=new RegExp(`^${n}\\.(\\d+)\\.log$`),o;try{o=await Xe.readdir(t)}catch{return}let i=[];for(let d of o){let c=d.match(r);c&&i.push({name:d,n:Number(c[1])})}if(i.length<=e)return;i.sort((d,c)=>d.n-c.n);let a=i.slice(0,i.length-e);await Promise.allSettled(a.map(d=>Xe.unlink(wn.join(t,d.name))))}async function zk(s){await qk(E.logFile(),Jl);let e=await Wk({file:E.logFile(),size:"10m",mkdir:!0,symlink:cr,limit:{count:Jl,removeOtherLogFiles:!0}}),t=zl.destination(2),n=!1,r={write:a=>{n||e.write(a)}};return{stream:zl.multistream([{stream:r,level:s},{stream:t,level:s}]),fileStream:e,closeFile:()=>new Promise(a=>{n=!0,e.once("close",()=>a()),e.end()})}}async function Jk(s){let e=Kl.createServer(s.tlsOptions,t=>{let n=Gl.connect({host:s.upstreamHost,port:s.upstreamPort}),r=!1,o=i=>{if(!r){r=!0,i&&s.logger.warn(`tls terminator forwarder error: ${i.message??String(i)}`);try{t.destroy()}catch{}try{n.destroy()}catch{}}};t.on("error",o),n.on("error",o),t.on("close",()=>o()),n.on("close",()=>o()),t.pipe(n),n.pipe(t)});return e.on("tlsClientError",t=>{s.logger.warn(`tls handshake error: ${t.message}`)}),await new Promise((t,n)=>{let r=o=>{n(new Error(`TLS listener could not bind ${s.listenHost}:${s.listenPort}: ${o.message}`))};e.once("error",r),e.listen({host:s.listenHost,port:s.listenPort},()=>{e.off("error",r),t()})}),e.on("error",t=>{s.logger.warn(`tls terminator error: ${t.message}`)}),e}function Vk(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 Gk(){process.title="hydra-acp-daemon";let{installGlobalTlsTrust:s}=await Promise.resolve().then(()=>(ds(),Sl));s();let e=await An(),t=await Gi(),n,r=()=>{n&&ia(n)};n=await Ql(e,t,{requestShutdown:r}),process.stdout.write(`hydra-acp daemon listening on ${e.daemon.host}:${e.daemon.port}
229
+ `),process.on("SIGINT",r),process.on("SIGTERM",r),process.on("SIGHUP",()=>{})}Gk().catch(s=>{let e=s instanceof Error?s.stack??s.message:String(s);process.stderr.write(`hydra-acp-daemon: ${e}
230
+ `),ra(e).catch(()=>{}).finally(()=>process.exit(1))});