@x-otto/runtime 0.1.0-alpha.13 → 0.1.0-alpha.14

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/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import{CostTracker as e,computeCacheHitRatio as t,createEventStream as n,createProviderRegistry as r,createStreamFunction as i}from"@x-otto/ai";import{createHookRegistry as a,defineHook as o}from"@x-otto/hooks";import{provisionBaselineSecurity as s}from"@x-otto/guard";import{EventBus as c,TypedEventEmitter as l,buildAllowedEnv as u,createLogger as d}from"@x-otto/shared";import{dirname as f,join as p,resolve as m,sep as h}from"node:path";import{DiskPanelStatePersistence as g,DiskPasteStatePersistence as _,FileAppendLog as v,HttpAppendLog as y,MemoryAppendLog as b,PANEL_STATE_VER as x,createInMemoryPanelStatePersistence as S,createInMemoryPasteStatePersistence as C,normalizePasteSnapshot as ee}from"@x-otto/persistence";import{EVENT_DOMAIN as te,SYSTEM_PROMPT_SECTIONS as w,applySectionBudget as T,getEventDomain as ne}from"@x-otto/interchange";import{InMemorySession as E,InMemorySessionPersistence as re,RemoteSessionPersistence as ie,RemoteSnapshotConflictError as ae,SESSION_IDLE_TIMEOUT_MS as oe,SESSION_MAX as se,SESSION_SNAPSHOT_VERSION as D,hasStrippedReplacements as ce,supportsArchive as le,supportsReplacementHydration as ue}from"@x-otto/session";import{SDK_VERSION as de,isProcessAlive as fe,isShadowModeEnabled as pe,listOttoProcesses as me}from"@x-otto/env";import{ENGINE_DEFAULTS as he,applyMemoryTransform as ge,createAgent as _e,createRecordingPorts as ve,createReplayPorts as ye,createTraceRecorder as be,extractNondetDraws as xe,extractToolResultText as Se,forceMemoryTransform as Ce,prompt as we,stripAnsi as Te,systemClock as Ee,systemId as De,systemRandom as Oe,wireSnapshotStore as ke}from"@x-otto/agent";import{mkdir as Ae,readFile as je,readdir as Me,rm as Ne,stat as Pe,unlink as Fe,writeFile as Ie}from"node:fs/promises";import{createHash as Le,randomUUID as O}from"node:crypto";import{SESSION_COMPACTION_TIMEOUT_MS as Re,SESSION_MAX_PER_SESSION_BYTES as ze,SESSION_MIN_PER_SESSION_BYTES as Be,SESSION_TOTAL_RESIDENCY_BUDGET as Ve,resolveResidencyBudget as k}from"@x-otto/session-contract";import{getHeapStatistics as He}from"node:v8";import{execFileSync as A,spawn as Ue,spawnSync as We}from"node:child_process";import{EventEmitter as Ge}from"node:events";import{appendFileSync as Ke,mkdirSync as qe,mkdtempSync as Je,readFileSync as Ye,readdirSync as Xe,realpathSync as j,writeFileSync as Ze}from"node:fs";import{tmpdir as M}from"node:os";function Qe(e,t){let n=t=>e.ephemeral?new b:e.sessionDir?new v({baseDir:p(e.sessionDir,t)}):e.remoteLog?new y(e.remoteLog):new b;return{traceStore:t?.traceStore??n(`trace`),checkpointStore:t?.checkpointStore??n(`checkpoint`)}}function N(e){let t=new Map;return[o({name:e.name,timing:`system.prompt.transform`,priority:e.priority,handle:async(n,r)=>{let i=t.get(n.sessionId);i===void 0&&(i=await e.compute(n)??``,t.set(n.sessionId,i)),i&&(r.systemPrompt=`${r.systemPrompt}\n\n${i}`)}}),o({name:`${e.name}-cleanup`,timing:`session.deleted`,priority:90,handle:e=>{t.delete(e.sessionId)}})]}var $e=class{sources=new Map;sealed=!1;register(e){if(this.sealed)throw Error(`ContextSourceRegistry: cannot register "${e.id}" — registry is sealed (hooks already built).`);if(this.sources.has(e.id))throw Error(`ContextSourceRegistry: duplicate context source id "${e.id}" — a source with this id is already registered (builtin or another plugin). Rename the source or drop the duplicate.`);this.sources.set(e.id,e)}list(){return[...this.sources.values()].sort((e,t)=>(e.priority??50)-(t.priority??50))}sealAndBuildHooks(e,t){this.sealed=!0;let n=[];for(let r of this.list())n.push(...N({name:`ctxsrc:${r.id}`,priority:r.priority??50,compute:async n=>{let i=await r.contribute({sessionId:n.sessionId,workspaceDir:e,memory:t});return i&&T(r.id,i)}}));return n}};async function et(e,t){let n={workspaceDir:e,date:new Date().toISOString().split(`T`)[0]??new Date().toLocaleDateString(),platform:`${process.platform}/${process.arch}`};if(!t)return n;try{let r=(await t(`git rev-parse --abbrev-ref HEAD`,e)).trim();r&&(n.gitBranch=r)}catch{}try{let r=(await t(`git status --porcelain --short`,e)).trim();if(r){let e=r.split(`
2
2
  `);n.gitStatus=e.length>10?`${e.slice(0,10).join(`
3
- `)}\n... and ${e.length-10} more files`:r}}catch{}return n}function tt(e){let t=[`### Runtime Environment`,`- Working directory: ${e.workspaceDir}`,`- Date: ${e.date}`,`- Platform: ${e.platform}`];return e.gitBranch&&t.push(`- Git branch: ${e.gitBranch}`),e.gitStatus&&t.push(`- Git status:\n\`\`\`\n${e.gitStatus}\n\`\`\``),t.join(`
4
- `)}function nt(e){return{id:`runtime:environment`,priority:w.environment.priority,async contribute(t){let n=async(e,t)=>{let{execSync:n}=await import(`node:child_process`);return n(e,{cwd:t,encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]})};try{return tt(await et(e,n))}catch{return}}}}const rt=d(`@x-otto/runtime/hooks`);function it(e){let{hookRegistry:t,agentName:n,sessionId:r}=e;return{async executeBeforeHooks(e){let i={args:{...e.args},cancelled:!1};return await t.execute(`tool.execute.before`,{...e,agentName:n,sessionId:r},i),i.cancelled||i.decision===`deny`?{kind:`deny`,reason:i.cancelReason??i.decisionReason??`Tool ${e.toolName} was blocked by pre-execution hook`}:i.decision===`ask`?{kind:`ask`,args:i.displayArgs??i.args,reason:i.decisionReason??`Requires confirmation`,risk:i.risk}:i.decision===`allow`||i.decision===void 0?{kind:`proceed`,args:i.displayArgs??i.args}:(rt.warn({toolName:e.toolName,decision:i.decision},`tool.execute.before hook returned unrecognized decision — denying as safety fallback`),{kind:`deny`,reason:`Tool ${e.toolName} was blocked: hook returned unrecognized decision "${String(i.decision)}"`})},async executeAfterHooks(e){let i={result:e.result,metadata:{}};return await t.execute(`tool.execute.after`,{...e,agentName:n,sessionId:r},i),i}}}function P(e){for(let t of e){if(t.role!==`user`)continue;let{content:e}=t,n;if(typeof e==`string`?n=e:Array.isArray(e)&&(n=e.filter(e=>e.type===`text`&&typeof e.text==`string`).map(e=>e.text).join(` `)),!n)continue;let r=n.replace(/\s+/g,` `).trim();if(r)return r.length>80?r.slice(0,80):r}}function at(e,t,n){return e?.trim()||(P(t)??n.slice(0,8))}function ot(e){return typeof e==`string`?e:Array.isArray(e)?e.filter(e=>{let t=e;return t.type===`text`&&typeof t.text==`string`}).map(e=>e.text).join(``):``}function st(e){let t=e.trim();if(!t)return null;let n=t.match(/\{[^{}]*"title"\s*:\s*"([^"]+)"[^{}]*\}/);if(!n&&/"title/.test(t))return null;let r=(n?.[1]??t).replace(/\s+/g,` `).trim();return r?r.length>80?r.slice(0,80):r:null}async function ct(e,t,n){let r=t.trim().slice(-2e3);if(!r)return null;let i=new AbortController,a=()=>i.abort();if(n.aborted)return null;n.addEventListener(`abort`,a,{once:!0});let o=setTimeout(()=>i.abort(),e.timeoutMs??15e3);try{let t=[{role:`user`,timestamp:Date.now(),content:[{type:`text`,text:r}]}];return st(ot((await e.stream({model:e.model,systemPrompt:`Generate a concise, sentence-case title (3-7 words) that captures the main topic or goal of this coding session, recognizable in a session list. Use sentence case: capitalize only the first word and proper nouns.
3
+ `)}\n... and ${e.length-10} more files`:r}}catch{}return n}function tt(e){return[`### Runtime Environment`,`- Working directory: ${e.workspaceDir}`,`- Platform: ${e.platform}`].join(`
4
+ `)}function nt(e){let t=[`- Date: ${e.date}`];return e.gitBranch&&t.push(`- Git branch: ${e.gitBranch}`),e.gitStatus&&t.push(`- Git status:\n\`\`\`\n${e.gitStatus}\n\`\`\``),t.join(`
5
+ `)}async function rt(e,t){let{execSync:n}=await import(`node:child_process`);return n(e,{cwd:t,encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]})}function it(e){return{id:`runtime:environment`,priority:w.environment.priority,async contribute(t){try{return tt(await et(e))}catch{return}}}}function at(e){let t=w.environmentVolatile;return[o({name:t.name,timing:`system.prompt.transform`,priority:t.priority,handle:async(n,r)=>{try{let n=nt(await et(e,rt));r.systemTail??=[],r.systemTail.push(T(t.name,n))}catch{}}})]}const ot=d(`@x-otto/runtime/hooks`);function st(e){let{hookRegistry:t,agentName:n,sessionId:r}=e;return{async executeBeforeHooks(e){let i={args:{...e.args},cancelled:!1};return await t.execute(`tool.execute.before`,{...e,agentName:n,sessionId:r},i),i.cancelled||i.decision===`deny`?{kind:`deny`,reason:i.cancelReason??i.decisionReason??`Tool ${e.toolName} was blocked by pre-execution hook`}:i.decision===`ask`?{kind:`ask`,args:i.displayArgs??i.args,reason:i.decisionReason??`Requires confirmation`,risk:i.risk}:i.decision===`allow`||i.decision===void 0?{kind:`proceed`,args:i.displayArgs??i.args}:(ot.warn({toolName:e.toolName,decision:i.decision},`tool.execute.before hook returned unrecognized decision — denying as safety fallback`),{kind:`deny`,reason:`Tool ${e.toolName} was blocked: hook returned unrecognized decision "${String(i.decision)}"`})},async executeAfterHooks(e){let i={result:e.result,metadata:{}};return await t.execute(`tool.execute.after`,{...e,agentName:n,sessionId:r},i),i}}}function P(e){for(let t of e){if(t.role!==`user`)continue;let{content:e}=t,n;if(typeof e==`string`?n=e:Array.isArray(e)&&(n=e.filter(e=>e.type===`text`&&typeof e.text==`string`).map(e=>e.text).join(` `)),!n)continue;let r=n.replace(/\s+/g,` `).trim();if(r)return r.length>80?r.slice(0,80):r}}function ct(e,t,n){return e?.trim()||(P(t)??n.slice(0,8))}function lt(e){return typeof e==`string`?e:Array.isArray(e)?e.filter(e=>{let t=e;return t.type===`text`&&typeof t.text==`string`}).map(e=>e.text).join(``):``}function ut(e){let t=e.trim();if(!t)return null;let n=t.match(/\{[^{}]*"title"\s*:\s*"([^"]+)"[^{}]*\}/);if(!n&&/"title/.test(t))return null;let r=(n?.[1]??t).replace(/\s+/g,` `).trim();return r?r.length>80?r.slice(0,80):r:null}async function dt(e,t,n){let r=t.trim().slice(-2e3);if(!r)return null;let i=new AbortController,a=()=>i.abort();if(n.aborted)return null;n.addEventListener(`abort`,a,{once:!0});let o=setTimeout(()=>i.abort(),e.timeoutMs??15e3);try{let t=[{role:`user`,timestamp:Date.now(),content:[{type:`text`,text:r}]}];return ut(lt((await e.stream({model:e.model,systemPrompt:`Generate a concise, sentence-case title (3-7 words) that captures the main topic or goal of this coding session, recognizable in a session list. Use sentence case: capitalize only the first word and proper nouns.
5
6
 
6
7
  Return JSON with a single "title" field.
7
8
 
@@ -11,25 +12,25 @@ Good examples:
11
12
 
12
13
  Bad (too vague): {"title": "Code changes"}
13
14
  Bad (too long): {"title": "Investigate and fix the issue where the login button does not respond on mobile devices"}
14
- Bad (wrong case): {"title": "Fix Login Button On Mobile"}`,messages:t,cacheRetention:`none`,maxTokens:64,temperature:0},i.signal).result()).content))}catch{return null}finally{clearTimeout(o),n.removeEventListener(`abort`,a)}}var lt=class{session;stream;titleModel;genSeq=0;abortController=new AbortController;disposed=!1;constructor(e){this.session=e.session,this.stream=e.stream,this.titleModel=e.titleModel}maybeGenerate(e=!1){if(!this.titleModel||this.disposed||this.session.metadata().titleSource===`custom`)return;let t=this.session.messages().filter(e=>e.role===`user`).length;if(t===0||!e&&t>3)return;let n=++this.genSeq,r=this.session.messages().map(e=>{let t=e.content;return typeof t==`string`?t:Array.isArray(t)?t.filter(e=>{let t=e;return t.type===`text`&&typeof t.text==`string`}).map(e=>e.text).join(` `):``}).filter(Boolean).join(`
15
- `);ct({stream:this.stream,model:this.titleModel},r,this.abortController.signal).then(e=>{!e||this.disposed||n===this.genSeq&&this.session.metadata().titleSource!==`custom`&&this.session.setTitle(e,`ai`)}).catch(()=>{})}backfill(){this.maybeGenerate(!0)}dispose(){this.disposed||(this.disposed=!0,this.abortController.abort())}},ut=class{constructor(e){this.deps=e}messages(){return this.deps.session.messages()}append(e){this.deps.session.append(e)}removeLast(){this.deps.session.removeLast()}persistInputBoundary(){this.deps.requestInputBoundaryFlush?.()}buildContext(){return this.deps.session.buildContext()}persistNew(e,t){let n=e.slice(t);for(let e of n)this.deps.session.append(e)}recordCompaction(e,t){let{session:n,sessionId:r,publish:i}=this.deps,a=n.buildContext().messages.length;n.recordCompaction(e,t);let o=n.buildContext().messages.length;o<a&&(i({"compaction.start":[{type:`compaction.start`,sessionId:r,messageCount:a}]}),i({"compaction.end":[{type:`compaction.end`,sessionId:r,retainedCount:o,summary:e}]}))}notifyPrune(e,t){this.deps.publish({"memory.pruned":[{type:`memory.pruned`,sessionId:this.deps.sessionId,tokensSaved:e,prunedCount:t?.prunedCount,messagesBefore:t?.messagesBefore,messagesAfter:t?.messagesAfter}]})}};const dt=`Before continuing, audit each remaining todo against the actual current state: if evidence shows it is already satisfied, mark it done; if it is scope creep beyond the original request, drop it (skipped, with a reason). Only work on items that a requirement-level audit proves unfinished. Do not add new todos unless the user's original request demands them. If work remains after this round, leave the genuinely-unfinished todos active — the engine will admit another round; do not wrap up or stop early merely because rounds or tokens look large.`,ft=`You made progress but did not update the todo list. Reconcile it now: mark each genuinely finished item done (or skipped/failed with a reason) via write_todos, then continue any remaining work.`,F=new Set([`done`,`skipped`,`failed`]);var pt=class e{session;sessionId;logger;todoContinuation;depth;publish;isAbortRequested;runPromptRound;withReducedThinking;needsCompaction;compactNow;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.logger=e.logger,this.todoContinuation=e.todoContinuation,this.depth=e.depth,this.publish=e.publish,this.isAbortRequested=e.isAbortRequested,this.runPromptRound=e.runPromptRound,this.withReducedThinking=e.withReducedThinking??(e=>e()),this.needsCompaction=e.needsCompaction,this.compactNow=e.compactNow}snapshot(){return new Map((this.session.getTodoList()??[]).map(e=>[e.id,e.status]))}countIncomplete(){return(this.session.getTodoList()??[]).filter(e=>!F.has(e.status??`pending`)).length}static hasStateProgress(e,t){for(let[n,r]of t){if(!F.has(r??``))continue;let t=e.get(n);if(!F.has(t??`pending`))return!0}return!1}wrapContinuation(e,t,n,r){return`<engine_continuation round="${e}" cap="${t}"${r?` type="${r}"`:``}>\n${n}\n</engine_continuation>`}async run(){if(!this.todoContinuation.enabled||this.depth>0)return;let t=this.todoContinuation.max*4,n=0,r=0,i=0,a=!1,o=dt,s=this.snapshot();for(;n<this.todoContinuation.max&&r<t&&!this.isAbortRequested()&&this.countIncomplete()>0;){n++,r++,this.publish({"prompt.continued":[{type:`prompt.continued`,sessionId:this.sessionId,round:r,maxRounds:t,incompleteCount:this.countIncomplete()}]}),this.logger.info({sessionId:this.sessionId,round:n,totalRounds:r,max:this.todoContinuation.max,hardCap:t},`Todo gate: auto-continuing unfinished todos`),this.needsCompaction&&this.compactNow&&this.needsCompaction()&&(this.logger.info({sessionId:this.sessionId},`Todo gate: pre-continuation compaction triggered (context near window limit)`),await this.compactNow());let c=o===ft,l=this.wrapContinuation(r,t,o,c?`sync`:void 0),u=await this.withReducedThinking(()=>this.runPromptRound(l,!0));if(u.cancelled)return;o=dt;let d=this.snapshot();if(e.hasStateProgress(s,d)){n--,i=0,s=d;continue}if(u.hadToolActivity&&!a){n--,a=!0,i=1,o=ft,this.logger.info({sessionId:this.sessionId,round:n},`Todo gate: tool activity without todo updates — nudging state reconciliation`);continue}if(u.hadToolActivity){i++,this.logger.info({sessionId:this.sessionId,staleActivityRounds:i},`Todo gate: diminishing returns (repeated activity without todo progress), stopping`);return}this.logger.info({sessionId:this.sessionId,round:n},`Todo gate: no progress between rounds, stopping early`);return}}};async function mt(e,t,n){let{session:r,sessionId:i,hookRegistry:a,logger:o,publish:s}=e,c=r.messages().length;await a.emit(`compaction.before`,{sessionId:i,messageCount:c}),s({"compaction.start":[{type:`compaction.start`,sessionId:i,messageCount:c}]}),o.info({sessionId:i,count:n},`Session compacting`),r.compact(t,n);let l=r.messages().length;await a.emit(`compaction.after`,{sessionId:i,retainedCount:l}),s({"compaction.end":[{type:`compaction.end`,sessionId:i,retainedCount:l,summary:t}]}),o.info({sessionId:i,retained:l,summaryChars:t.length},`Session compaction finished`)}async function ht(e,t){let{session:n,sessionId:r,hookRegistry:i,logger:a,memory:o,persistence:s}=e,c=n.buildContext(),l=c.messages.length;if(!o||t?.aborted)return{compacted:!1,before:l,after:l};await i.emit(`compaction.before`,{sessionId:r,messageCount:l}),a.info({sessionId:r,messageCount:l},`Session manual compaction (forced)`);let u={compacted:!1};await Ce(o,c.messages,r,t,{persistence:s,sink:u});let d=n.buildContext().messages.length;return await i.emit(`compaction.after`,{sessionId:r,retainedCount:d}),a.info({sessionId:r,retainedCount:d},`Session manual compaction finished`),{compacted:u.compacted,before:l,after:d}}function gt(e,t,n,r){return[e.on(`max.turns`,e=>{e.steered&&r(),n({"budget.notice":[{type:`budget.notice`,sessionId:t,turnIndex:e.turnIndex,maxTurns:e.maxTurns,extended:e.extended,...e.steered===void 0?{}:{steered:e.steered},...e.progressDenied===void 0?{}:{progressDenied:e.progressDenied}}]})}),e.on(`prompt.budget`,e=>{e.steered&&r(),n({"prompt.budget.notice":[{type:`prompt.budget.notice`,sessionId:t,turnIndex:e.turnIndex,dimension:e.dimension,used:e.used,budget:e.budget,steered:e.steered}]})}),e.on(`progress.stall`,e=>{n({"progress.stall.notice":[{type:`progress.stall.notice`,sessionId:t,turnIndex:e.turnIndex,windowTurns:e.windowTurns,maxRepeat:e.maxRepeat}]})}),e.on(`tool.call.mismatch`,e=>{n({"tool.call.mismatch.notice":[{type:`tool.call.mismatch.notice`,sessionId:t,turnIndex:e.turnIndex,outcome:e.outcome,retryCount:e.retryCount}]})}),e.on(`turn.idle`,e=>{n({"turn.idle.notice":[{type:`turn.idle.notice`,sessionId:t,turnIndex:e.turnIndex,outcome:e.outcome,textChars:e.textChars}]})}),e.on(`image.vision-delegate`,e=>{n({"image.vision-delegate":[{type:`image.vision-delegate`,sessionId:t,attemptedCount:e.attemptedCount,describedCount:e.describedCount,failedCount:e.failedCount}]})}),e.on(`compaction.reactive`,e=>{n({"compaction.reactive.notice":[{type:`compaction.reactive.notice`,sessionId:t,messagesBefore:e.messagesBefore,messagesAfter:e.messagesAfter}]})}),e.on(`image.degradation`,e=>{n({"image.degradation.notice":[{type:`image.degradation.notice`,sessionId:t,degradedCount:e.degradedCount,trigger:e.trigger}]})})]}function _t(e,t){if(e)return e.length>t?`${e.slice(0,t)}…`:e}function vt(e,t){if(t.toolCall.name!==`write_todos`||t.result.isError)return;let n=t.result.details?.todos;if(!Array.isArray(n))return;let r=new Map((e.getTodoList()??[]).map(e=>[e.id,e.turn]));e.setTodoList(n.map(e=>({id:e.id,title:e.title,status:e.status,turn:e.id===void 0?void 0:r.get(e.id)})))}function yt(e){let{agent:t,session:n,sessionId:r,modelId:i,hookRegistry:a,publish:o}=e;return[t.on(`stream.event`,async({event:e})=>{o({"stream.event":[{type:`stream.event`,sessionId:r,event:e}]}),e.type===`start`?(o({"streaming.start":[{type:`streaming.start`,sessionId:r,model:i()}]}),a.emit(`stream.start`,{sessionId:r,model:i()})):e.type===`done`&&(o({"streaming.end":[{type:`streaming.end`,sessionId:r,model:i(),stopReason:e.reason??`end_turn`}]}),await a.emit(`stream.end`,{sessionId:r,model:i(),stopReason:e.reason??`end_turn`,tokenUsage:{input:e.message.usage.inputTokens,output:e.message.usage.outputTokens}}))}),t.on(`turn.start`,e=>{o({"turn.start":[{type:`turn.start`,sessionId:r,turnIndex:e.turnIndex,toolTurnCount:e.toolTurnCount,maxToolTurns:e.maxToolTurns,promptOutputTokens:e.promptOutputTokens,promptOutputTokenBudget:e.promptOutputTokenBudget}]})}),t.on(`turn.end`,e=>{o({"turn.end":[{type:`turn.end`,sessionId:r,turnIndex:e.turnIndex}]})}),t.on(`tool.call.start`,e=>{o({"tool.call.start":[{type:`tool.call.start`,sessionId:r,toolCall:{id:e.toolCall.id,name:e.toolCall.name,arguments:e.toolCall.arguments}}]})}),t.on(`tool.call.end`,e=>{vt(n,e);let t=Te(Se(e.result)),i=e.contextChars??t.length;o({"tool.call.end":[{type:`tool.call.end`,sessionId:r,toolCall:{id:e.toolCall.id,name:e.toolCall.name,arguments:e.toolCall.arguments},isError:e.result.isError===!0,resultText:_t(t,he.traceResultMaxChars),resultTokensEstimate:Math.ceil(i/4),details:e.result.details??void 0}]})})]}const bt=100*1024*1024;function xt(e){return e.replace(/[^a-zA-Z0-9_-]/g,`_`).slice(0,128)||`unnamed`}var St=class{rootDir;constructor(e){this.rootDir=p(e,`tool-results`)}sessionDir(e){return p(this.rootDir,xt(e))}async spill(e,t,n){if(!pe())try{let r=this.sessionDir(e);await Ae(r,{recursive:!0});let i=p(r,`${xt(t)}.txt`);return await Ie(i,n,`utf-8`),this.evictIfOverBudget().catch(()=>{}),i}catch{return}}async cleanupSession(e){try{await Ne(this.sessionDir(e),{recursive:!0,force:!0})}catch{}}async evictIfOverBudget(){let e=[],t=0,n;try{n=await Me(this.rootDir)}catch{return}for(let r of n){let n=p(this.rootDir,r),i;try{i=await Me(n)}catch{continue}for(let r of i){let i=p(n,r);try{let n=await Pe(i);n.isFile()&&(e.push({path:i,mtimeMs:n.mtimeMs,size:n.size}),t+=n.size)}catch{}}}if(!(t<=bt)){e.sort((e,t)=>e.mtimeMs-t.mtimeMs);for(let n of e){if(t<=bt)break;try{await Fe(n.path),t-=n.size}catch{}}}}};let Ct;function wt(){return Ct??=new St(p(process.cwd(),`.otto`)),Ct}const Tt={spill(e,t,n){return wt().spill(e,t,n)},cleanupSession(e){return wt().cleanupSession(e)}},Et={maxToolTurns:he.maxToolTurns};function Dt(){let e,t,n=new Promise((n,r)=>{e=n,t=r});return{resolve:e,reject:t,promise:n}}var I=class{pending=new Map;open(e){let t=Dt();return this.pending.set(e,t),t.promise.finally(()=>{this.pending.delete(e)})}resolve(e,t){let n=this.pending.get(e);return n?(n.resolve(t),!0):!1}rejectAll(e){for(let t of this.pending.values())t.reject(e);this.pending.clear()}};const Ot=`[sandbox-escalation]`;function kt(e){return e.includes(Ot)}async function At(e,t,n,r,i){try{let a=await e(t,n,r,i);return a===`allow`||a===`deny`?a:`abstain`}catch{return`abstain`}}var jt=class{approvalGate=new I;grillGate=new I;planGate=new I;constructor(e){this.deps=e}async requestApproval(e,t,n,r,i){let{sessionId:a,interactive:o,logger:s,publish:c}=this.deps,l=this.deps.hostCapabilities?.permissionAsk;if(l)try{let o=await l({sessionId:a(),toolName:e,input:t,reason:n,risk:r},i??new AbortController().signal),c=o.decision===`allow`;return s.info({sessionId:a(),toolName:e,approved:c},`Approval decided by host capability port`),{approved:c,...o.updatedInput?{updatedArgs:o.updatedInput}:{},...o.message?{message:o.message}:{}}}catch(t){return s.warn({sessionId:a(),toolName:e,err:t},`Host permission port failed; denying (fail-closed)`),{approved:!1,message:`host approval port failed`}}if(!o)return s.warn({sessionId:a(),toolName:e},`Approval requested in a non-interactive session; denying (fail-closed, no human to respond)`),!1;let u=O(),d=this.approvalGate.open(u),f;if(this.deps.semanticReviewer&&kt(n)){let i=await At(this.deps.semanticReviewer,e,t,n,r);(i===`allow`||i===`deny`)&&(f=i,s.info({sessionId:a(),toolName:e,approvalId:u,verdict:i},`Semantic reviewer decided`),this.approvalGate.resolve(u,i===`allow`))}return c({"approval.required":[{type:`approval.required`,sessionId:a(),id:u,toolName:e,arguments:t,description:n,risk:r,...f?{semanticVerdict:f}:{}}]}),s.info({sessionId:a(),toolName:e,approvalId:u},`Approval requested`),d}resolveApproval(e,t){let{sessionId:n,logger:r,publish:i}=this.deps;this.approvalGate.resolve(e,t)&&(i({"approval.resolved":[{type:`approval.resolved`,sessionId:n(),id:e,approved:t}]}),r.info({sessionId:n(),approvalId:e,approved:t},`Approval resolved`))}async requestGrill(e){let{sessionId:t,interactive:n,logger:r,publish:i}=this.deps,a=this.deps.hostCapabilities?.userAsk;if(a){let n=O(),i={...e,id:n};try{return await a({sessionId:t(),question:i},new AbortController().signal)}catch(e){return r.warn({sessionId:t(),requestId:n,err:e},`Host user-ask port failed; not accepting recommendation (fail-closed)`),{answer:`(host ask port failed; no user answer)`,acceptedRecommendation:!1,resolvedBy:`environment_headless`}}}if(!n)return{answer:e.recommendation,acceptedRecommendation:!0,resolvedBy:`auto_recommendation`};let o=O(),s={...e,id:o},c=this.grillGate.open(o);return i({"ask.user.required":[{type:`ask.user.required`,sessionId:t(),requestId:o,question:s}]}),r.info({sessionId:t(),requestId:o,askedBy:e.askedBy},`Grill requested`),c}resolveAskUser(e,t){let{sessionId:n,logger:r,publish:i}=this.deps;t&&this.grillGate.resolve(e,t)&&(i({"ask.user.resolved":[{type:`ask.user.resolved`,sessionId:n(),requestId:e}]}),r.info({sessionId:n(),requestId:e},`Grill resolved`))}async requestPlanApproval(e){let{sessionId:t,logger:n,publish:r}=this.deps,i=O(),a=this.planGate.open(i);return r({"plan.approval.required":[{type:`plan.approval.required`,sessionId:t(),requestId:i,planContent:e}]}),n.info({sessionId:t(),requestId:i},`Plan approval requested`),a}resolvePlanApproval(e,t,n){let{sessionId:r,logger:i,publish:a}=this.deps;this.planGate.resolve(e,{action:t,feedback:n})&&(a({"plan.approval.resolved":[{type:`plan.approval.resolved`,sessionId:r(),requestId:e,action:t}]}),i.info({sessionId:r(),action:t,requestId:e},`Plan approval resolved`))}rejectAll(e){this.approvalGate.rejectAll(e),this.grillGate.rejectAll(e),this.planGate.rejectAll(e)}},Mt=class{costTracker=new e;sessionCrossedCostBudget=!1;lastTokenUsage;lastTotalInputTokens;lastCacheHitRatio=null;constructor(e){this.deps=e}record(e,n){let r=e.usage;if(e.count===0||e.lastAssistantApi===void 0)return;this.lastTokenUsage={input:r.inputTokens,output:r.outputTokens},this.lastTotalInputTokens=r.cacheReadTokens+r.cacheWriteTokens+r.inputTokens,this.lastCacheHitRatio=t(r,e.lastAssistantApi);let i=this.costTracker.record(n,r),a=this.costTracker.summary().totalCostUSD,{sessionId:o,logger:s,publish:c,sessionCostBudgetUSD:l}=this.deps;s.info({sessionId:o(),input:r.inputTokens,output:r.outputTokens,cacheRead:r.cacheReadTokens,cacheWrite:r.cacheWriteTokens,cacheHitRatio:this.lastCacheHitRatio,turnCost:i.toFixed(6),sessionCost:a.toFixed(6)},`Session usage`),!this.sessionCrossedCostBudget&&l!==void 0&&l>0&&a>=l&&(this.sessionCrossedCostBudget=!0,c({"session.cost-budget-exceeded":[{type:`session.cost-budget-exceeded`,sessionId:o(),totalCostUSD:a,budgetUSD:l}]}))}getLastTokenUsage(){return this.lastTokenUsage}getLastTotalInputTokens(){return this.lastTotalInputTokens}getCostSummary(){return this.costTracker.summary()}getLastCacheHitRatio(){return this.lastCacheHitRatio}};function Nt(e,t){e.ensureNotDisposed();let n=`steer-${++e.steerSeq.value}`,r={role:`user`,timestamp:e.clock?.now()??Date.now(),content:[{type:`text`,text:t}],uuid:n};return e.agent.steer(r),{id:n}}function Pt(e,t){return e.ensureNotDisposed(),e.agent.removeSteer(t)}function Ft(e,t){e.ensureNotDisposed(),e.agent.followUp({role:`user`,timestamp:e.clock?.now()??Date.now(),content:[{type:`text`,text:t}]})}async function It(e,t){let{text:n,internal:r,images:i,resumeLastRound:a}=t;if(e.compactionPending){let t=e.compactionPending;e.setCompactionPending(void 0);try{let n=e.getCompactionTimeoutMs?.()??Re;await Promise.race([t,new Promise((e,t)=>setTimeout(()=>t(Error(`compaction timeout`)),n))])}catch{}}if(e.promptRefresh){let t=await e.promptRefresh();t!==void 0&&e.setSystemPrompt(t)}let o=await we({text:n,internal:r,images:i,...a?{resumeLastRound:!0}:{},sessionId:e.id,agentName:e.agentName,model:e.model,tools:e.model.supportsTools===!1?[]:e.tools,params:{systemPrompt:e.systemPrompt,systemTail:e.systemTail,thinkingLevel:e.thinkingLevel,cacheRetention:e.interactive?`long`:`short`},runner:e.agent,hooks:e.hookRegistry,persistence:e.persistence,memory:e.memory,debug:e.devtools??void 0,recorder:e.recorder,clock:e.clock,isPauseRequested:e.pauseRequested,describeImages:e.describeImages});return o.cancelled?{cancelled:!0,hadToolActivity:!1}:(e.pauseRequested()&&e.publish({"run.paused":[{type:`run.paused`,sessionId:e.id}]}),e.setSystemPrompt(o.params.systemPrompt),e.setThinkingLevel(o.params.thinkingLevel),e.usageTracker.record(o.newMessagesUsageSummary,e.model),{cancelled:!1,hadToolActivity:o.newMessagesUsageSummary.hadToolActivity})}function Lt(e,t){return e>0||t?0:3}function Rt(e){let t=(e.OTTO_TODO_CONTINUE??``).toLowerCase(),n=!(t===`0`||t===`off`||t===`false`||t===`no`),r=Math.trunc(Number(e.OTTO_TODO_CONTINUE_MAX??3));return{enabled:n,max:Number.isFinite(r)&&r>=0?r:3}}var zt=class extends c{session;workspaceDir;workspaceId;agent;disposed=!1;promptGate=!1;titleManager;runStartedThisPrompt=!1;currentPrompt;compactionPending;getCompactionTimeoutMs;_model;_modelResolution;_tools;_systemPrompt;_systemTail;_maxToolTurns;_maxToolTurnExtensions;_promptOutputTokenBudget;_promptWallClockBudgetMs;_thinkingLevel;_promptRefresh;get model(){return this._model}get modelResolution(){return this._modelResolution}get tools(){return this._tools}get systemPrompt(){return this._systemPrompt}get systemTail(){return this._systemTail}get maxToolTurns(){return this._maxToolTurns}get maxToolTurnExtensions(){return this._maxToolTurnExtensions}get promptOutputTokenBudget(){return this._promptOutputTokenBudget}get promptWallClockBudgetMs(){return this._promptWallClockBudgetMs}get thinkingLevel(){return this._thinkingLevel}get promptRefresh(){return this._promptRefresh}applyModel(e,t){this._model=e,this._modelResolution=t}async applyModelWithContextFit(e,t){let n=this._model;if(this.applyModel(e,t),n?.contextWindow===e.contextWindow||!this.memory?.reconfigure||!this.memory.ensureFitsWindow)return{compacted:!1};this.memory.reconfigure({contextWindow:e.contextWindow,maxOutput:e.maxOutputTokens});let r=this.session.buildContext(),i=await this.memory.ensureFitsWindow(r.messages,this.id);return i?.compacted&&i.summary&&i.replacement?(this.session.recordCompaction(i.summary,i.replacement),{compacted:!0,summary:i.summary,replacement:i.replacement}):{compacted:!1}}applyThinkingLevel(e){this._thinkingLevel=e}applyTools(e){this._tools=e}applySystemPrompt(e){this._systemPrompt=e}applyBudgets(e){e.maxToolTurns!==void 0&&(this._maxToolTurns=e.maxToolTurns),e.maxToolTurnExtensions!==void 0&&(this._maxToolTurnExtensions=e.maxToolTurnExtensions),e.promptOutputTokenBudget!==void 0&&(this._promptOutputTokenBudget=e.promptOutputTokenBudget),e.promptWallClockBudgetMs!==void 0&&(this._promptWallClockBudgetMs=e.promptWallClockBudgetMs)}agentName;depth;parentTaskId;transient;listable;logger;hookRegistry;devtools;memory;recorder;describeImages;nondetFlush;clock;steerSeq={value:0};persistence;inputBoundaryFlusher;setInputBoundaryFlusher(e){this.inputBoundaryFlusher=e}gates;interactive;agentUnsubs=[];sessionCostBudgetUSD;usageTracker;todoGateRunner;abortRequested=!1;pauseRequested=!1;get id(){return this.session.id}get title(){return this.session.metadata().title}get status(){return this.agent.status}get pinned(){return this.session.metadata().pinned??!1}get pinGroup(){return this.session.metadata().pinGroup}get coreAgent(){return this.agent}get steerDeps(){return{agent:this.agent,clock:this.clock,steerSeq:this.steerSeq,ensureNotDisposed:()=>this.ensureNotDisposed()}}get isExecuting(){return this.agent.status===`streaming`||this.agent.status===`tool_executing`}get isBusy(){return this.promptGate||this.isExecuting}getSessionInfo(){return{sessionId:this.id,modelId:this.model.id,modelName:this.model.name,systemPromptLength:this.systemPrompt?.length??0,tools:this.tools.map(e=>e.name)}}constructor(e,t){super(),this.session=e;let n=t.hookRegistry??a({preset:`default`});t.hookRegistry||s(n);let r=t.logger??d(`agent-session:${e.id}`,{level:`info`,destination:`stdout`});this.getCompactionTimeoutMs=t.getCompactionTimeoutMs;let i=t.promptRefresh,o=t.systemPrompt??``,c=t.tools??[],l=t.thinkingLevel??`medium`,u=t.maxToolTurns??Et.maxToolTurns,f=t.depth??0,p=t.parentTaskId,m=t.maxToolTurnExtensions??Lt(f,t.transient),h=f===0?t.promptOutputTokenBudget:void 0,g=f===0?t.promptWallClockBudgetMs:void 0,_=t.stallDetection,v=t.idleTurnDetection,y=process.env.OTTO_BUDGET_STEER_WRAPUP,b=t.budgetSteerWrapUp??(y===`1`||y===`on`?!0:y===`0`||y===`off`?!1:f===0),x=t.workspaceDir??process.cwd(),{model:S,devtools:C,agentName:ee}=t;this._model=S,this._modelResolution=t.modelResolution,this._tools=c,this._systemPrompt=o,this._systemTail=t.systemTail,this._thinkingLevel=l,this._maxToolTurns=u,this._maxToolTurnExtensions=m,this._promptOutputTokenBudget=h,this._promptWallClockBudgetMs=g,this.hookRegistry=n,this.agentName=ee??`agent`,this.depth=f,this.parentTaskId=p,this.transient=t.transient??!1,this.listable=t.listable??!0,this.interactive=t.interactive??!1,this.devtools=C,this.memory=t.memory,this.recorder=t.recorder,this.describeImages=t.describeImages,this.nondetFlush=t.nondetFlush,this.clock=t.clock,this.logger=r,this.workspaceDir=x,this.sessionCostBudgetUSD=f===0?t.sessionCostBudgetUSD:void 0,this.workspaceId=t.workspaceId,this._promptRefresh=i,this.gates=new jt({sessionId:()=>this.id,interactive:this.interactive,logger:r,publish:e=>this.publish(e),semanticReviewer:t.semanticReviewer,hostCapabilities:t.hostCapabilities}),this.usageTracker=new Mt({sessionId:()=>this.id,sessionCostBudgetUSD:this.sessionCostBudgetUSD,logger:r,publish:e=>this.publish(e)}),this.titleManager=new lt({session:e,stream:t.stream,titleModel:t.titleModel}),this.todoGateRunner=new pt({session:e,sessionId:e.id,logger:r,todoContinuation:t.todoContinuation??Rt(process.env),depth:f,publish:e=>this.publish(e),isAbortRequested:()=>this.abortRequested,runPromptRound:(e,t)=>this.runPromptRound(e,t),withReducedThinking:async e=>{let t=this.thinkingLevel;this._thinkingLevel=`low`;try{return await e()}finally{this._thinkingLevel=t}},needsCompaction:()=>this.memory?.needsCompaction([...this.session.messages()])??!1,compactNow:async()=>{try{let e=[...this.session.messages()];return{compacted:(await this.memory?.process(e,this.id))?.compacted??!1}}catch{return{compacted:!1}}}}),this.agent=_e({stream:t.stream,logger:r,maxToolTurns:u,maxToolTurnExtensions:m,budgetSteerWrapUp:b,promptOutputTokenBudget:h,promptWallClockBudgetMs:g,stallDetection:_,idleTurnDetection:v,agentName:this.agentName,sessionId:e.id,depth:this.depth,parentTaskId:this.parentTaskId,toolHookExecutor:it({hookRegistry:n,agentName:this.agentName,sessionId:e.id}),debug:C,recorder:this.recorder,nondetFlush:this.nondetFlush,clock:this.clock,approval:(e,t,n,r,i)=>this.requestApproval(e,t,n,r,i),spill:(t,n)=>Tt.spill(e.id,t,n),wireSnapshotStore:ke,retryAccelerate:t.retryAccelerate,streamRetry:t.streamRetry,networkDisconnectRetry:t.networkDisconnectRetry,lifecycleAsyncTimeoutMs:t.lifecycleAsyncTimeoutMs}),this.agentUnsubs.push(this.agent.on(`status.change`,({to:e})=>{e===`streaming`&&(this.runStartedThisPrompt=!0)})),this.agentUnsubs.push(...gt(this.agent,this.id,e=>this.publish(e),()=>{this.budgetSteeredThisPrompt=!0})),this.agentUnsubs.push(...yt({agent:this.agent,session:this.session,sessionId:this.id,modelId:()=>this.model.id,hookRegistry:n,publish:e=>this.publish(e)})),this.agentUnsubs.push(this.agent.on(`steering.injected`,({messages:e})=>{for(let t of e){let e=t.uuid;e&&this.publish({"steer.consumed":[{type:`steer.consumed`,sessionId:this.id,id:e}]})}})),this.persistence=new ut({session:this.session,sessionId:this.id,publish:e=>this.publish(e),requestInputBoundaryFlush:()=>this.inputBoundaryFlusher?.()}),this.logger.info({sessionId:this.id,model:this.model.id},`Session initialized`)}notifyCreated(){this.publish({"session.start":[{type:`session.start`,sessionId:this.id}]})}budgetSteeredThisPrompt=!1;archive(){this.ensureNotDisposed(),this.agent.archive(),this.session.setArchived(!0)}unarchive(){this.ensureNotDisposed(),this.agent.unarchive(),this.session.setArchived(!1)}pin(e){this.ensureNotDisposed(),this.session.setPinned(!0,e?.trim()||void 0)}unpin(){this.ensureNotDisposed(),this.session.setPinned(!1)}async prompt(e,t){if(this.ensureNotDisposed(),this.status===`archived`)throw Error(`Session is archived. Unarchive it first before sending messages.`);if(this.isBusy){let{streamingBehavior:n}=t??{};if(n===`followUp`)this.followUp(e);else if(n===`steer`)this.steer(e);else throw Error(`Agent is processing. Specify streamingBehavior ("steer" or "followUp") to queue the message.`);return}let n=this.executePrompt(e,t);this.currentPrompt=n;try{await n}finally{this.currentPrompt===n&&(this.currentPrompt=void 0)}}async retryLastRound(){if(this.ensureNotDisposed(),this.status===`archived`)throw Error(`Session is archived. Unarchive it first before sending messages.`);if(this.isBusy)throw Error(`Agent is processing. Cannot retry while a round is in flight.`);if(![...this.session.messages()].reverse().find(e=>e.role===`user`)){let e=Error(`No resumable user message in history`);throw e.code=`RETRY_NO_RESUMABLE_ROUND`,e}let e=this.executePrompt(``,{resumeLastRound:!0});this.currentPrompt=e;try{await e}finally{this.currentPrompt===e&&(this.currentPrompt=void 0)}}async executePrompt(e,t){this.promptGate=!0,this.budgetSteeredThisPrompt=!1,this.runStartedThisPrompt=!1,this.abortRequested=!1,this.pauseRequested=!1;let n=this.model.id,r=this.thinkingLevel;try{if(this.publish({"prompt.start":[{type:`prompt.start`,sessionId:this.id,text:e}]}),!this.session.metadata().title?.trim()){let t=P([{role:`user`,content:e}]);t&&this.session.setTitle(t,`derived`)}if(this.logger.info({sessionId:this.id},`Session prompt started`),(await this.runPromptRound(e,void 0,t?.images,t?.resumeLastRound)).cancelled){this.publish({"prompt.end":[{type:`prompt.end`,sessionId:this.id,tokenUsage:this.usageTracker.getLastTokenUsage(),model:n,thinkingLevel:r,stopReason:`interrupted`}]});return}await this.todoGateRunner.run(),this.titleManager.maybeGenerate(),this.publish({"prompt.end":[{type:`prompt.end`,sessionId:this.id,tokenUsage:this.usageTracker.getLastTokenUsage(),model:n,thinkingLevel:r,stopReason:`completed`}]}),this.logger.info({sessionId:this.id},`Session prompt finished`)}catch(e){let t=e instanceof Error?e:Error(String(e)),i=t.code===`AGENT_ABORTED`||t.name===`AbortError`||this.agent.status===`aborted`;throw this.publish({"prompt.end":[{type:`prompt.end`,sessionId:this.id,tokenUsage:this.usageTracker.getLastTokenUsage(),model:n,thinkingLevel:r,stopReason:i?`interrupted`:`error`,errorMessage:i?void 0:t.message}]}),i||(this.publish({error:[{type:`error`,sessionId:this.id,error:t}]}),this.logger.error({sessionId:this.id,err:t.message},`Session prompt failed`)),e}finally{this.promptGate=!1}}async runPromptRound(e,t,n,r){return It(this.promptRoundHost,{text:e,internal:t,images:n,resumeLastRound:r})}get promptRoundHost(){return{id:this.id,agentName:this.agentName,agent:this.agent,model:this.model,tools:this.tools,systemPrompt:this.systemPrompt,systemTail:this.systemTail,thinkingLevel:this.thinkingLevel,interactive:this.interactive,hookRegistry:this.hookRegistry,persistence:this.persistence,memory:this.memory,devtools:this.devtools,recorder:this.recorder,clock:this.clock,describeImages:this.describeImages,pauseRequested:()=>this.pauseRequested,compactionPending:this.compactionPending,promptRefresh:this.promptRefresh,getCompactionTimeoutMs:this.getCompactionTimeoutMs,usageTracker:this.usageTracker,publish:e=>this.publish(e),setSystemPrompt:e=>{this._systemPrompt=e},setThinkingLevel:e=>{this._thinkingLevel=e},setCompactionPending:e=>{this.compactionPending=e}}}steer(e){return Nt(this.steerDeps,e)}removeSteer(e){return Pt(this.steerDeps,e)}followUp(e){Ft(this.steerDeps,e)}abort(){this.promptGate&&(this.abortRequested=!0),this.pauseRequested=!1;let e=this.isExecuting,t=this.promptGate&&!this.runStartedThisPrompt;!e&&!t||(this.rejectPendingGates(),this.agent.abort())}pauseRun(){return this.ensureNotDisposed(),this.isBusy?(this.pauseRequested=!0,this.publish({"run.pause_requested":[{type:`run.pause_requested`,sessionId:this.id}]}),!0):!1}cancelPauseRun(){return this.ensureNotDisposed(),!this.isBusy||!this.pauseRequested?!1:(this.pauseRequested=!1,this.publish({"run.pause_cancelled":[{type:`run.pause_cancelled`,sessionId:this.id}]}),!0)}resumeRun(){this.ensureNotDisposed(),this.pauseRequested&&(this.pauseRequested=!1,this.publish({"run.resumed":[{type:`run.resumed`,sessionId:this.id}]}))}get isPaused(){return this.pauseRequested}async compact(e,t){this.ensureNotDisposed(),await mt(this.compactionDeps(),e,t)}async compactNow(e){return this.ensureNotDisposed(),ht({...this.compactionDeps(),memory:this.memory,persistence:this.persistence},e)}compactionDeps(){return{session:this.session,sessionId:this.id,hookRegistry:this.hookRegistry,logger:this.logger,publish:e=>this.publish(e)}}async clearContext(){this.ensureNotDisposed(),this.isBusy&&(this.abort(),await this.currentPrompt?.catch(()=>{}));let e=this.session.messages().length;this.session.clearContext(),this.memory?.clearSession?.(this.id),this.logger.info({sessionId:this.id,clearedCount:e},`Session context cleared (/clear)`),this.publish({"session.cleared":[{type:`session.cleared`,sessionId:this.id,clearedCount:e}]})}clearTurnPanels(){this.session.setTodoList([]),this.session.setEditedFiles([]),this.session.setSubagents([]),this.session.setTurnSummaries([])}renameSession(e){this.session.setTitle(e,`custom`)}getCostSummary(){return this.usageTracker.getCostSummary()}getLastInputTokens(){return this.usageTracker.getLastTokenUsage()?.input}getLastTotalInputTokens(){return this.usageTracker.getLastTotalInputTokens()}getLastCacheHitRatio(){return this.usageTracker.getLastCacheHitRatio()}subscribe(e,t,n){if(typeof e==`function`)return this.subscribeAll((t,n)=>{e(n)});if(!t)throw Error(`callback is required when subscribing by type`);return super.subscribe(e,t,n)}async requestApproval(e,t,n,r,i){return this.gates.requestApproval(e,t,n,r,i)}resolveApproval(e,t){this.gates.resolveApproval(e,t)}async requestGrill(e){return this.gates.requestGrill(e)}resolveAskUser(e,t){this.gates.resolveAskUser(e,t)}async requestPlanApproval(e){return this.gates.requestPlanApproval(e)}resolvePlanApproval(e,t,n){this.gates.resolvePlanApproval(e,t,n)}rejectPendingGates(){this.gates.rejectAll(Error(`Session aborted`))}ensureNotDisposed(){if(this.disposed)throw Error(`AgentSession ${this.id} has been disposed`)}backfillTitle(){this.titleManager.backfill()}dispose(){if(!this.disposed){this.disposed=!0,this.titleManager.dispose(),this.rejectPendingGates(),ke.delete(this.id);for(let e of this.agentUnsubs)e();this.agentUnsubs.length=0,this.pauseRequested&&this.agent.status===`completed`||this.agent.abort(),this.memory?.forgetSession?.(this.id),this.publish({"session.end":[{type:`session.end`,sessionId:this.id}]}),this.removeAllListeners(),this.logger.info({sessionId:this.id},`Session disposed`)}}};function Bt(e,t,n,r,i,a,o){let s=a?.now()??Date.now(),c=new E(e,t,n.length,{clock:a,idGen:o});return c.restoreEntries([...n],{...r,createdAt:s,lastActiveAt:s,parentSessionId:t,forkPoint:n.length,tags:[...r.tags,`fork`]},i),c}function Vt(e,t){let n=m(e),r=m(n,t);if(!r.startsWith(n+h)&&r!==n)throw Error(`路径穿越拒绝:路径 "${t}" 不在工作目录 "${e}" 内`);return r}function Ht(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}async function Ut(e,t){let n=[];for(let r of t){let t=Vt(e,r);try{n.push({path:r,content:await je(t,`utf-8`)})}catch(e){if(Ht(e))n.push({path:r,content:null});else throw e}}return{files:n}}async function Wt(e,t){for(let n of t.files){let t=Vt(e,n.path);n.content===null?await Ne(t,{force:!0}):(await Ae(f(t),{recursive:!0}),await Ie(t,n.content,`utf-8`))}}function Gt(e){return typeof e==`object`&&!!e&&`type`in e}function Kt(e){return typeof e==`object`&&!!e&&`id`in e&&`name`in e&&(`result`in e||`resultSummary`in e)}function qt(e){return e.contentPreview?.map(e=>({type:`text`,text:e.text??e.preview??``}))??[]}function Jt(e){let t=new Map;for(let n of e.entries)t.set(n.id,n);let n=[],r=e.leafId?t.get(e.leafId):void 0;for(;r;)n.push(r),r=r.parentId?t.get(r.parentId):void 0;return n.reverse(),n.filter(e=>e.type===`message`).map(e=>e.message)}function Yt(e){return e.result?e.result.content:e.resultSummary?qt(e.resultSummary):[]}function Xt(e){if(typeof e==`object`&&e&&`text`in e){let t=e.text;return typeof t==`string`?t:void 0}}function Zt(e,t){let n=[...e];for(let e of t)if(e.kind===`lifecycle`&&e.node===`prompt.before`){let t=Xt(e.payload);t!==void 0&&n.push({role:`user`,content:[{type:`text`,text:t}],timestamp:e.ts})}else if(e.kind===`stream`&&e.node===`stream.event`)Gt(e.payload)&&e.payload.type===`done`&&n.push(e.payload.message);else if(e.kind===`tool`&&e.node===`tool.call.end`&&Kt(e.payload)){let{id:t,name:r,result:i,resultSummary:a}=e.payload,o=i?.isError??a?.isError??!1,s=i?.details??a?.details??{};n.push({role:`tool_result`,toolCallId:t,toolName:r,content:Yt(e.payload),isError:o,details:s,timestamp:e.ts})}return n}function Qt(e){return e.result?e.result:e.resultSummary?{content:qt(e.resultSummary),isError:e.resultSummary.isError,details:e.resultSummary.details}:{content:[],isError:!0,details:{error:`unable to extract result from trace payload`}}}function $t(e){let t=[],n=[];for(let r of e)r.kind===`stream`&&r.node===`stream.event`&&Gt(r.payload)&&(n.push(r.payload),r.payload.type===`done`&&(t.push(n),n=[]));return n.length>0&&t.push(n),t}function en(e){let t=$t(e),r=0;return()=>{let e=t[r]??[];r++;let i=n(),a;for(let t of e)i.push(t),t.type===`done`?a=t.message:`partial`in t&&(a=t.partial);return a?i.complete(a):i.fail(Error(`replay stream: no recorded LLM events for this turn`)),i}}function tn(e){let t=new Map;for(let n of e)n.kind===`tool`&&n.node===`tool.call.end`&&Kt(n.payload)&&t.set(n.payload.id,Qt(n.payload));return t}function nn(e,t){return e.map(e=>({...e,execute:async e=>t.get(e.id)||{content:[{type:`text`,text:`replay: no recorded result for tool call ${e.id}`}],isError:!0}}))}var rn=class extends Error{constructor(){super(`L2 deterministic re-execution requires a SandboxRunner (x-web-container runtime), which is not yet available. Use replay level "L1" (record/replay of tool results) for now.`),this.name=`SandboxUnavailableError`}},an=class{constructor(e){this.deps=e}replayPorts(e,t){let n=[...e];return{clock:ye(xe(n)).clock,stream:en(n),tools:nn(t,tn(n)),disableMemory:!0}}async replaySession(e,t,n={}){if(!this.deps.traceStore)throw Error(`replaySession requires a traceStore (record mode must be enabled)`);if((n.level??`L1`)===`L2`&&!n.sandbox)throw new rn;let r=this.deps.getConfig(e);if(!r)throw Error(`Cannot replay unknown session "${e}" (no resolved config)`);let i=[];for await(let t of this.deps.traceStore.read(e))i.push(t.entry);return this.deps.createSession({...r,id:t},this.replayPorts(i,r.tools))}async createCheckpoint(e,t={}){if(!this.deps.checkpointStore)throw Error(`createCheckpoint requires a checkpointStore`);let n=this.deps.getSession(e);if(!n)throw Error(`Cannot checkpoint unknown session "${e}"`);let r=n.session;if(!(r instanceof E))throw Error(`Session "${e}" does not support snapshots`);if(n.isBusy)throw Error(`Cannot checkpoint session "${e}" while a prompt is in flight (session busy); checkpoint requires a quiescent session for a consistent {conversation, traceSeq}`);let i=r.toSnapshot(),a=await this.ensureHydrated(e,i.entries,`checkpoint capture`),o=await this.countTraceEvents(e),s={sessionId:e,label:t.label,createdAt:Date.now(),traceSeq:o,conversation:{version:D,id:e,entries:a,metadata:i.metadata,leafId:i.leafId},files:t.files?await Ut(n.workspaceDir,t.files):void 0},c=await this.deps.checkpointStore.append(e,s);return{...c.entry,seq:c.seq}}async listCheckpoints(e){if(!this.deps.checkpointStore)return[];let t=[];for await(let n of this.deps.checkpointStore.read(e))t.push({...n.entry,seq:n.seq});return t}async restoreCheckpoint(e,t,n=`both`){if(!this.deps.checkpointStore)throw Error(`restoreCheckpoint requires a checkpointStore`);let r=this.deps.getSession(e);if(!r)throw Error(`Cannot restore unknown session "${e}"`);if(r.isBusy)throw Error(`Cannot restore/rollback session "${e}" while a prompt is in flight (session busy); abort the active prompt before rewinding`);let i=await this.readCheckpoint(e,t);if(n===`conversation`||n===`both`){let t=r.session;if(t instanceof E){let n=await this.ensureHydrated(e,i.conversation.entries,`checkpoint restore`);t.restoreEntries(n,i.conversation.metadata,i.conversation.leafId)}}(n===`code`||n===`both`)&&i.files&&await Wt(r.workspaceDir,i.files)}async ensureHydrated(e,t,n){if(!ce(t))return[...t];if(!this.deps.hydrateEntries)throw Error(`${n}: entries contain stripped compaction replacements but no hydrateEntries capability is wired (RFC-160 D4); refusing to proceed with stripped state`);return this.deps.hydrateEntries(e,t)}async readCheckpoint(e,t){if(!this.deps.checkpointStore)throw Error(`checkpoint operations require a checkpointStore`);let n;for await(let r of this.deps.checkpointStore.read(e,{from:t,to:t+1}))n=r.entry;if(!n)throw Error(`Checkpoint seq=${t} not found for session "${e}"`);if(n.conversation.version!==D)throw Error(`Checkpoint seq=${t} for session "${e}" has incompatible snapshot version ${n.conversation.version} (expected ${D})`);return n}async rollbackToCheckpoint(e,t,n=`both`){let r=await this.readCheckpoint(e,t);await this.restoreCheckpoint(e,t,n),this.deps.traceStore&&await this.deps.traceStore.truncate(e,r.traceSeq),this.deps.logger.info({sessionId:e,seq:t,traceSeq:r.traceSeq,mode:n},`Session rolled back`)}async forkFromCheckpoint(e,t,n){let r=this.deps.getSession(e),i=this.deps.getConfig(e);if(!r||!i)throw Error(`Cannot fork unknown session "${e}"`);let a=await this.readCheckpoint(e,t),o=n??crypto.randomUUID();if(this.deps.ensureCapacity(o),this.deps.traceStore)for await(let t of this.deps.traceStore.read(e,{to:a.traceSeq}))await this.deps.traceStore.append(o,t.entry);if(this.deps.checkpointStore)for await(let t of this.deps.checkpointStore.read(e))t.entry.traceSeq<=a.traceSeq&&await this.deps.checkpointStore.append(o,{...t.entry,sessionId:o});let s=Bt(o,e,await this.ensureHydrated(e,a.conversation.entries,`forkFromCheckpoint`),a.conversation.metadata,a.conversation.leafId),c=await this.deps.adoptForkedSession(s,{...i});return this.deps.logger.info({sessionId:o,sourceId:e,fromSeq:t},`Session forked from checkpoint`),c}async countTraceEvents(e){if(!this.deps.traceStore)return 0;let t=await this.deps.traceStore.count?.(e);if(t!==void 0)return t;let n=0;for await(let t of this.deps.traceStore.read(e))n++;return n}async replayTrace(e,t,n=0){if(!this.deps.traceStore)return[];let r={from:n,to:t===void 0?void 0:t+1},i=[];for await(let t of this.deps.traceStore.read(e,r))i.push(t.entry);return i}async traceback(e,t){let n=(await this.listCheckpoints(e)).filter(e=>e.traceSeq<=t).reduce((e,t)=>e===void 0||t.traceSeq>e.traceSeq?t:e,void 0),r=n?.traceSeq??0,i=n?Jt(n.conversation):[],a=await this.replayTrace(e,t,r);return{toSeq:t,baselineCheckpointSeq:n?.seq??null,fromTraceSeq:r,events:a,messages:Zt(i,a)}}};const L={healthy:1,warning:2,critical:4};var on=class{level=`healthy`;setLevel(e){this.level=e}get currentLevel(){return this.level}effectiveMaxMessages(e){return Math.max(1,Math.floor(e/L[this.level]))}effectiveMaxBytes(e){return Math.max(1,Math.floor(e/L[this.level]))}};const sn=2e3;var cn=class{gaps=new Map;constructor(e){this.deps=e}async detect(e,t){let n=this.deps.traceStore;if(!n)return;let r=t.entries[t.entries.length-1]?.timestamp??0;if(r!==0)try{let t=await n.count?.(e.id)??void 0,i=t!==void 0&&t>sn?{from:t-sn}:void 0,a=0,o=0;for await(let t of n.read(e.id,i)){let e=t.entry;e.kind!==`lifecycle`||e.node!==`turn.end`||e.ts>r+1e4&&(o++,e.ts>a&&(a=e.ts))}if(o===0)return;this.deps.logger.warn({sessionId:e.id,lostTurns:o,lastPersistedAt:r,lastTraceAt:a},`RFC-305 D3: crash gap detected — turns recorded in trace but never persisted to DB (lost in previous abnormal termination)`);let s={lostTurns:o,lastPersistedAt:r,lastTraceAt:a};this.gaps.set(e.id,s),this.deps.onDetected?.(e,s)}catch(t){this.deps.logger.debug?.({sessionId:e.id,err:t instanceof Error?t.message:String(t)},`RFC-305 D3: crash-gap reconciliation skipped (trace read failed)`)}}consume(e){let t=this.gaps.get(e);return this.gaps.delete(e),t}forget(e){this.gaps.delete(e)}};function ln(e,t){return t<=0?1:Math.min(1,e/t)}function R(e){let t=e.config?.totalBytes??Ve,n=e.config?.minPerSessionBytes??Be,r=e.config?.maxPerSessionBytes??ze,i=ln(e.currentTotalResidentBytes,t),a=Math.max(1,e.activeSessionCount),o=Math.floor(t*(1-i)/a),s=Math.max(n,Math.min(o,r)),c=Math.max(Math.floor(n/e.pressureDivisor),Math.floor(s/e.pressureDivisor));return{maxBytesPerSession:Math.max(1,c),globalPressure:Number(i.toFixed(4)),isGlobalPressure:i>=.85}}function un(e,t,n){return n?e.wouldByteTrimTouchActiveContext(Math.max(1,t)):e.wouldTrimTouchActiveContext(Math.max(1,t))}const dn=.9;function fn(e){let t=e.agentSession.session,n=R({activeSessionCount:e.activeSessionCount,currentTotalResidentBytes:e.currentTotalResidentBytes,pressureDivisor:e.pressureDivisor,config:e.residencyConfig}),r=t instanceof E?t.messageCount:0,i=Math.max(1,Math.floor(e.maxMessages*dn)),a=Math.max(1,Math.floor(n.maxBytesPerSession*dn));if(!(t instanceof E))return{action:`none`,maxBytes:n.maxBytesPerSession,isLossy:!1,boundaryLimited:!1,activeOversized:!1};let o=r>e.maxMessages&&un(t,i,!1),s=t.estimatedContentBytes>n.maxBytesPerSession&&un(t,a,!0),c=o||s,l=(e.lossyFailureCount??0)>=3;if(c&&!l)return{action:`request-compaction`,maxBytes:n.maxBytesPerSession,isLossy:!1,boundaryLimited:!1,activeOversized:!1};if(!c){let i=t.estimatedContentBytes>n.maxBytesPerSession,a=r>e.maxMessages;if(!i&&!a)return{action:`none`,maxBytes:n.maxBytesPerSession,isLossy:!1,boundaryLimited:!1,activeOversized:!1}}return{action:`trim`,maxBytes:n.maxBytesPerSession,isLossy:l&&c,boundaryLimited:!1,activeOversized:!1}}const z=.9;var pn=class{evalBaseline=new Map;publishBaseline=new Map;compactionFailures=new Map;compactionRequestBaseline=new Map;constructor(e){this.deps=e}evaluate(e){let t={action:`none`,removedCount:0,lossy:!1,shouldPublish:!1,trigger:`count`,capValue:0},n=e.session;if(!(n instanceof E))return t;let r=e.id,i=this.deps.residencyGovernor,a=i?i.effectiveMaxMessages(this.deps.maxHistoryMessages):this.deps.maxHistoryMessages,o=fn({agentSession:e,activeSessionCount:this.deps.countActiveSessions(),currentTotalResidentBytes:this.deps.sumEstimatedContentBytes(),pressureDivisor:i?this.deps.levelDivisor[i.currentLevel]:1,residencyConfig:this.deps.getResidencyConfig?.(),maxMessages:a,lossyFailureCount:this.compactionFailures.get(r)}),s=o.maxBytes,c=e=>e.role!==`tool_result`,l=n.messageCount;if(o.action===`request-compaction`)return this.deps.requestCompaction(e,l),this.deps.logger.debug({sessionId:r,msgCount:l},`[cap] trim would touch active context; requested compaction first, skipping trim this round (RFC-321 R12)`),this.evalBaseline.set(r,l),{...t,action:`request-compaction`};if(o.action===`none`)return this.evalBaseline.set(r,l),t;let u=o.isLossy,d=(this.compactionFailures.get(r)??0)>=3,f=Math.max(1,Math.floor(a*z)),p=Math.max(1,Math.floor(s*z)),m=l>a?n.capStoredHistory(f,c):{capped:!1,removedCount:0,boundaryLimited:!1,activeOversized:!1},h=n.estimatedContentBytes>s?n.capStoredHistoryByBytes(p,c):{capped:!1,removedCount:0,boundaryLimited:!1,activeOversized:!1},g=m.removedCount+h.removedCount,_=u&&g>0;u&&this.compactionFailures.delete(r),(m.boundaryLimited||h.boundaryLimited)&&this.deps.logger.debug({sessionId:r,removedCount:g,msgCount:l,activeOversized:m.activeOversized||h.activeOversized},`[cap] trimming stopped at active compaction boundary (RFC-321 R4); may remain above cap`),(m.activeOversized||h.activeOversized)&&!d&&(this.deps.requestCompaction(e,l),this.deps.logger.debug({sessionId:r,msgCount:l,bytes:n.estimatedContentBytes},`[cap] active region itself exceeds cap (RFC-321 activeOversized); compaction needed`));let v=this.publishBaseline.get(r),y=Math.max(1,Math.floor(a*(1-z))),b=!_&&v!==void 0&&l<v+y,x=g>0&&!b,S=i&&i.currentLevel!==`healthy`?`memory-pressure`:h.removedCount>m.removedCount?`bytes`:`count`;return x&&this.publishBaseline.set(r,l),this.evalBaseline.set(r,l-g),{action:`trim`,removedCount:g,lossy:_,shouldPublish:x,trigger:S,capValue:S===`bytes`?s:a}}shouldEvaluateInline(e){let t=e.session;if(!(t instanceof E))return!1;let n=t.messageCount,r=this.evalBaseline.get(e.id);return r===void 0?(this.evalBaseline.set(e.id,n),!1):n-r>=this.deps.inlineCheckInterval}shouldRequestCompaction(e,t){let n=this.compactionRequestBaseline.get(e);return n!==void 0&&t<n+this.deps.inlineCheckInterval?!1:(this.compactionRequestBaseline.set(e,t),!0)}onCompactionSucceeded(e){this.compactionFailures.delete(e)}onCompactionFailed(e){let t=(this.compactionFailures.get(e)??0)+1;return this.compactionFailures.set(e,t),t}forget(e){this.evalBaseline.delete(e),this.publishBaseline.delete(e),this.compactionFailures.delete(e),this.compactionRequestBaseline.delete(e)}};const B={touch:!1};function V(e,t){if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`||typeof t!=`object`||Array.isArray(e)!==Array.isArray(t))return!1;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length?e.every((e,n)=>V(e,t[n])):!1;let n=e,r=t,i=Object.keys(n),a=Object.keys(r);return i.length===a.length?i.every(e=>Object.hasOwn(r,e)&&V(n[e],r[e])):!1}function H(e,t){return e===void 0&&t===void 0?!0:e===void 0||t===void 0||e.length!==t.length?!1:V(e,t)}var mn=class{constructor(e){this.deps=e}async restore(e,t,n){let r=this.deps.panelStateStore;if(!r)return;let i=await r.loadAll(n);if(i){i.todoList!==void 0&&e.setTodoList(i.todoList,B),i.editedFiles!==void 0&&e.setEditedFiles(i.editedFiles,B),i.subagents!==void 0&&e.setSubagents(i.subagents,B),i.drafts!==void 0&&e.setDrafts(i.drafts,B),i.turnSummaries!==void 0&&e.setTurnSummaries(i.turnSummaries,B);return}let a=t.metadata.config,o=a?.todoList,s=a?.editedFiles,c=a?.subagents,l=a?.drafts;!o&&!s&&!c&&!l||(o&&e.setTodoList(o,B),s&&e.setEditedFiles(s,B),c&&e.setSubagents(c,B),l&&e.setDrafts(l,B),H(o,e.getTodoList())&&H(s,e.getEditedFiles())&&H(c,e.getSubagents())&&H(l,e.getDrafts())?await r.saveAll(n,{sessionId:n,todoList:o??[],editedFiles:s??[],subagents:c??[],drafts:l??[]}):this.deps.logger.warn({sessionId:n},`PanelState migration verification failed, using legacy in-memory data without persisting`))}},U=class{constructor(e,t){this.persistence=e,this.pasteStatePersistence=t}async getTodoList(e){return(await this.persistence.load(e))?.todoList}async setTodoList(e,t){let n=await this.loadOrInit(e);n.todoList=t,await this.persistence.save(n)}async getEditedFiles(e){return(await this.persistence.load(e))?.editedFiles}async setEditedFiles(e,t){let n=await this.loadOrInit(e);n.editedFiles=t,await this.persistence.save(n)}async getSubagents(e){return(await this.persistence.load(e))?.subagents}async setSubagents(e,t){let n=await this.loadOrInit(e);n.subagents=t,await this.persistence.save(n)}async getDrafts(e){return(await this.persistence.load(e))?.drafts}async setDrafts(e,t){let n=await this.loadOrInit(e);n.drafts=t,await this.persistence.save(n)}async getTurnSummaries(e){return(await this.persistence.load(e))?.turnSummaries}async setTurnSummaries(e,t){let n=await this.loadOrInit(e);n.turnSummaries=t,await this.persistence.save(n)}async getPaste(e){if(!this.pasteStatePersistence)return{sessionId:e,entries:[],nextId:1};try{return ee(e,await this.pasteStatePersistence.load(e))}catch{return{sessionId:e,entries:[],nextId:1}}}async setPaste(e,t){if(!this.pasteStatePersistence)return!1;if(t.sessionId!==e)throw Error(`PanelStateStore.setPaste: snapshot.sessionId (${t.sessionId}) !== sessionId (${e})`);try{return await this.pasteStatePersistence.save(t),!0}catch{return!1}}async deletePaste(e){if(!this.pasteStatePersistence)return!1;try{return await this.pasteStatePersistence.delete(e)}catch{return!1}}async loadAll(e){let t=await this.persistence.load(e);return t==null||t.ver!==x?null:t}async saveAll(e,t){if(t.sessionId!==e)throw Error(`PanelStateStore.saveAll: snapshot.sessionId (${t.sessionId}) !== sessionId (${e})`);await this.persistence.save({...t,ver:x})}async loadOrInit(e){return await this.persistence.load(e)??{sessionId:e}}};function hn(e){let t={};return e.interactive!==void 0&&(t.interactive=e.interactive),e.listable!==void 0&&(t.listable=e.listable),e.depth!==void 0&&(t.depth=e.depth),e.agentName!==void 0&&(t.agentName=e.agentName),e.thinkingLevel!==void 0&&(t.thinkingLevel=e.thinkingLevel),e.maxToolTurnExtensions!==void 0&&(t.maxToolTurnExtensions=e.maxToolTurnExtensions),e.transient!==void 0&&(t.transient=e.transient),e.model?.id&&(t.modelId=e.model.id),e.systemTail!==void 0&&(t.systemTail=e.systemTail),e.workspaceDir!==void 0&&(t.workspaceDir=e.workspaceDir),e.maxToolTurns!==void 0&&(t.maxToolTurns=e.maxToolTurns),e.permissionAlwaysAllow&&e.permissionAlwaysAllow.length>0&&(t.permissionAlwaysAllow=[...e.permissionAlwaysAllow]),e.availableModels&&e.availableModels.length>0&&(t.availableModels=[...e.availableModels]),t}function gn(e,t){if(!t)return e;let n={...e};return t.interactive!==void 0&&(n.interactive=t.interactive),t.listable!==void 0&&(n.listable=t.listable),t.depth!==void 0&&(n.depth=t.depth),t.agentName!==void 0&&(n.agentName=t.agentName),t.thinkingLevel!==void 0&&(n.thinkingLevel=t.thinkingLevel),t.maxToolTurnExtensions!==void 0&&(n.maxToolTurnExtensions=t.maxToolTurnExtensions),t.transient!==void 0&&(n.transient=t.transient),t.systemTail!==void 0&&(n.systemTail=t.systemTail),t.workspaceDir!==void 0&&(n.workspaceDir=t.workspaceDir),t.maxToolTurns!==void 0&&(n.maxToolTurns=t.maxToolTurns),t.permissionAlwaysAllow!==void 0&&(n.permissionAlwaysAllow=[...t.permissionAlwaysAllow]),t.availableModels!==void 0&&(n.availableModels=[...t.availableModels]),n}var _n=class{saveChains=new Map;crashGapDetector;panelStateRestorer;turnSaveState=new Map;leaseDeniedState=new Map;remoteRevisions=new Map;residencyCoordinator;constructor(e){this.deps=e,this.residencyCoordinator=new pn({logger:e.logger,...e.residencyGovernor?{residencyGovernor:e.residencyGovernor}:{},...e.getResidencyConfig?{getResidencyConfig:e.getResidencyConfig}:{},countActiveSessions:()=>this.countActiveSessionsForAllocation(),sumEstimatedContentBytes:()=>this.sumEstimatedContentBytes(),requestCompaction:(e,t)=>this.requestEscapeValveCompaction(e,t),maxHistoryMessages:k(this.deps.getResidencyConfig?.()).maxHistoryMessages,inlineCheckInterval:200,levelDivisor:L}),this.panelStateRestorer=new mn({...e.panelStateStore?{panelStateStore:e.panelStateStore}:{},logger:e.logger}),this.crashGapDetector=new cn({traceStore:e.traceStore,logger:e.logger,onDetected:(e,t)=>{e.publish({"session.crash-gap-detected":[{type:`session.crash-gap-detected`,sessionId:e.id,lostTurns:t.lostTurns,lastPersistedAt:t.lastPersistedAt,lastTraceAt:t.lastTraceAt}]})}})}applyResidencyCaps(e){let t=this.residencyCoordinator.evaluate(e);t.shouldPublish&&e.publish({"session.history-capped":[{type:`session.history-capped`,sessionId:e.id,removedCount:t.removedCount,trigger:t.trigger,capValue:t.capValue,...t.lossy?{lossy:!0}:{}}]})}requestEscapeValveCompaction(e,t){this.residencyCoordinator.shouldRequestCompaction(e.id,t)&&(e.compactionPending=e.compactNow().then(t=>(t.compacted?this.residencyCoordinator.onCompactionSucceeded(e.id):this.residencyCoordinator.onCompactionFailed(e.id),this.deps.logger.info({sessionId:e.id,compacted:t.compacted,before:t.before,after:t.after},`[cap] escape-valve compaction requested (RFC-321 R12 compaction-first)`),t)).catch(t=>{let n=this.residencyCoordinator.onCompactionFailed(e.id);return this.deps.logger.warn({sessionId:e.id,error:t,failures:n},`[cap] escape-valve compaction failed; lossy trim allowed after threshold`),{compacted:!1,before:0,after:0}}))}maybeInlineCapEval(e){this.residencyCoordinator.shouldEvaluateInline(e)&&this.applyResidencyCaps(e)}track(e,t){if(!this.deps.autoPersist||t)return;let n=this.deps.persistence,r=e.session;r instanceof E&&typeof n.getPersistedCursor==`function`&&r.setReplacementStripEligibility(t=>{let i=n.getPersistedCursor(e.id);if(!i)return this.deps.logger.debug?.({sessionId:e.id,entryId:t},`RFC-160 D2a: skip runtime replacement strip (no persisted cursor yet)`),!1;let a=!1;for(let n of r.entries())if(n.id===t&&(a=!0),n.id===i)return a||this.deps.logger.debug?.({sessionId:e.id,entryId:t,cursor:i},`RFC-160 D2a: skip runtime replacement strip (entry beyond persisted cursor)`),a;return!1});let i=t=>{if(t instanceof Error&&t.name===`SessionWriteLeaseDeniedError`){let t=this.leaseDeniedState.get(e.id)===!0;return this.leaseDeniedState.set(e.id,!0),t||e.publish({"session.write-lease-denied":[{type:`session.write-lease-denied`,sessionId:e.id}]}),!0}return!1},a=()=>{this.leaseDeniedState.get(e.id)===!0&&(this.leaseDeniedState.set(e.id,!1),e.publish({"session.write-lease-restored":[{type:`session.write-lease-restored`,sessionId:e.id}]}))},o=()=>{this.enqueue(e.id,async()=>{try{await this.doSave(e.id),a()}catch(t){i(t)||this.deps.logger.warn({sessionId:e.id,err:t instanceof Error?t.message:String(t)},`Session auto-persist failed`)}})},s=()=>{let t=e.id;this.enqueue(t,async()=>{try{await this.doSaveEntries(t),a()}catch(e){i(e)||this.deps.logger.warn({sessionId:t,err:e instanceof Error?e.message:String(e)},`Session turn-level auto-persist failed`)}})};e.subscribe(`prompt.end`,o),e.subscribe(`error`,o),e.subscribe(`session.cleared`,()=>{this.enqueue(e.id,async()=>{try{await this.doSave(e.id),a();let t=e.session;if(t instanceof E){let n=t.purgeClearedHistory();(n.removedCount>0||n.strippedReplacements>0)&&this.deps.logger.debug?.({sessionId:e.id,...n},`RFC-194: purged cleared history after successful save`)}}catch(t){i(t)||this.deps.logger.warn({sessionId:e.id,err:t instanceof Error?t.message:String(t)},`Session clear-persist failed (purge skipped, residency left to RFC-178 caps)`)}})}),e.subscribe(`turn.end`,()=>{let t=e.id;if(this.maybeInlineCapEval(e),(this.deps.turnFlush??`incremental`)===`snapshot`){let e=Date.now(),n=this.turnSaveState.get(t);if(!n){this.turnSaveState.set(t,{lastSaveAt:e,turnsSinceSave:1});return}n.turnsSinceSave++;let r=e-n.lastSaveAt;if(n.turnsSinceSave<5&&r<3e4)return;n.lastSaveAt=e,n.turnsSinceSave=0}s()}),e.setInputBoundaryFlusher?e.setInputBoundaryFlusher(()=>this.requestInputBoundaryFlush(e,t)):this.deps.logger.debug?.({sessionId:e.id},`RFC-336 D2: input-boundary flush disabled (session lacks setInputBoundaryFlusher)`)}async flushPending(e){let t=this.saveChains.get(e);t&&await t.catch(t=>{this.deps.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`flushPending: pending save chain settled with failure (already logged by the job itself; surfaced here for removeSession/restore callers)`)}),this.leaseDeniedState.delete(e),this.turnSaveState.delete(e),this.remoteRevisions.delete(e)}countActiveSessionsForAllocation(){let e=this.deps.listSessionIds(),t=0;for(let n of e)this.deps.getConfig?.(n)?.transient!==!0&&t++;return Math.max(1,t)}sumEstimatedContentBytes(){let e=0;for(let t of this.deps.listSessionIds()){if(this.deps.getConfig?.(t)?.transient===!0)continue;let n=this.deps.getSession(t);n?.session instanceof E&&(e+=n.session.estimatedContentBytes)}return e}forgetSession(e){this.leaseDeniedState.delete(e),this.residencyCoordinator.forget(e),this.crashGapDetector.forget(e),this.turnSaveState.delete(e),this.remoteRevisions.delete(e)}forgetEvictedSession(e){this.deps.getSession(e)||this.forgetSession(e)}isTransient(e){return this.deps.getConfig?.(e)?.transient===!0}async save(e){return this.enqueue(e,()=>this.doSave(e))}requestInputBoundaryFlush(e,t){if(!this.deps.autoPersist||t||(this.deps.turnFlush??`incremental`)===`snapshot`)return;let n=e.id;this.enqueue(n,async()=>{try{await this.doSaveEntries(n)}catch(e){if(e instanceof Error&&e.name===`SessionWriteLeaseDeniedError`)return;this.deps.logger.warn({sessionId:n,err:e instanceof Error?e.message:String(e)},`Input-boundary flush failed (RFC-336 D2; falls back to turn/prompt-end persistence)`)}})}precreateSessionRow(e,t){if(!this.deps.autoPersist||t)return;let n=e.id;this.enqueue(n,async()=>{try{await this.doSaveEntries(n)}catch(e){if(e instanceof Error&&e.name===`SessionWriteLeaseDeniedError`)return;this.deps.logger.warn({sessionId:n,err:e instanceof Error?e.message:String(e)},`Session row pre-creation failed (RFC-336 D1; falls back to first-turn persistence)`)}})}saveSnapshot(e,t,n){if(this.isTransient(e))return n?.(),Promise.resolve();let r=this.mergeSnapshotConfig(e,t.metadata),i=this.enqueue(e,async()=>{let n={version:D,id:e,...t,metadata:r};if(this.isRemoteCasPersistence()?await this.saveRemoteWithCas(e,n):await this.deps.persistence.save(n),this.deps.panelStateStore){let t=this.deps.getSession(e)?.session;t&&await this.deps.panelStateStore.saveAll(e,{sessionId:e,todoList:t.getTodoList(),editedFiles:t.getEditedFiles(),subagents:t.getSubagents(),drafts:t.getDrafts(),turnSummaries:t.getTurnSummaries()})}});return n&&i.then(n,n),i}mergeSnapshotConfig(e,t){let n=this.deps.getConfig?.(e),r=n?hn(n):void 0,i=t.config?.inputHistory,a=r||i?{...r,...i?{inputHistory:i}:{}}:void 0;return a?{...t,config:a}:t}enqueue(e,t){let n=(this.saveChains.get(e)??Promise.resolve()).catch(()=>{}).then(t);this.saveChains.set(e,n);let r=()=>{this.saveChains.get(e)===n&&this.saveChains.delete(e)};return n.then(r,r),n}async doSaveEntries(e){if(this.isTransient(e))return;let t=this.deps.getSession(e);if(!t)return;let n=t.session;if(n instanceof E){this.applyResidencyCaps(t);let r=n.toSnapshot(),i=this.mergeSnapshotConfig(n.id,r.metadata),a={version:D,id:n.id,...r,metadata:i};this.isRemoteCasPersistence()?await this.saveRemoteWithCas(e,a):await this.deps.persistence.save(a)}}isRemoteCasPersistence(){return typeof this.deps.persistence.saveWithRevision==`function`}async saveRemoteWithCas(e,t){let n=this.deps.persistence,r=this.remoteRevisions.get(e);try{let i=await n.saveWithRevision(t,r);this.remoteRevisions.set(e,i)}catch(i){if(!(i instanceof ae))throw i;this.deps.logger.warn({sessionId:e,expectedRevision:r,serverRevision:i.info.revision},`Remote session CAS conflict; reloading + rebasing for one retry`);let a=await n.loadWithRevision(e);if(!a){let r=await n.saveWithRevision(t,0);this.remoteRevisions.set(e,r);return}let o=this.rebaseSnapshotAgainstRemote(t,a.snapshot),s=await n.saveWithRevision(o,a.revision);this.remoteRevisions.set(e,s)}}rebaseSnapshotAgainstRemote(e,t){let n=new Set(t.entries.map(e=>e.id)),r=e.entries.filter(e=>!n.has(e.id));return{version:D,id:e.id,entries:[...t.entries,...r],metadata:e.metadata,leafId:e.leafId??t.leafId}}async doSave(e){if(await this.doSaveEntries(e),this.isTransient(e))return;let t=this.deps.getSession(e);if(!t)return;let n=t.session;this.deps.panelStateStore&&await this.deps.panelStateStore.saveAll(e,{sessionId:e,todoList:n.getTodoList(),editedFiles:n.getEditedFiles(),subagents:n.getSubagents(),drafts:n.getDrafts(),turnSummaries:n.getTurnSummaries()})}async saveAll(){let e=[...this.deps.listSessionIds()].filter(e=>{let t=this.deps.getSession(e)?.session;return!(t instanceof E)||t.entries().length>0});(await Promise.allSettled(e.map(e=>this.save(e)))).forEach((t,n)=>{t.status===`rejected`&&this.deps.logger.warn({sessionId:e[n],err:t.reason instanceof Error?t.reason.message:String(t.reason)},`saveAll: a session failed to persist (others unaffected)`)}),await Promise.allSettled(this.saveChains.values())}async restore(e){if(!this.deps.configProvider)return null;let t=this.deps.getSession(e);if(t)return t;await this.flushPending(e);let n=this.isRemoteCasPersistence()?await this.deps.persistence.loadWithRevision(e):null,r=n?.snapshot??(n===null&&this.isRemoteCasPersistence()?null:await this.deps.persistence.load(e));if(!r)return null;if(r.version!==D)return this.deps.logger.warn({sessionId:e,version:r.version,expected:D},`Session snapshot version mismatch, skipped`),null;if(!this.deps.canAccommodate(e))throw Error(`Max sessions reached, cannot restore ${e}.`);let i=new E(r.id,void 0,void 0,{clock:this.deps.clock,idGen:this.deps.idGen});i.restoreEntries(r.entries,r.metadata,r.leafId);let a=gn(this.deps.configProvider(r.metadata.config?.agentName,r.metadata.config?.modelId),r.metadata.config),o=await this.deps.adoptRestoredSession(i,a);return r.metadata.archived&&o.archive(),await this.panelStateRestorer.restore(i,r,e),n&&this.remoteRevisions.set(e,n.revision),this.track(o,!1),await this.crashGapDetector.detect(o,r),this.deps.logger.info({sessionId:e},`Session restored`),o}consumeCrashGap(e){let t=this.crashGapDetector.consume(e);return t?{lostTurns:t.lostTurns}:void 0}async restoreAll(){if(!this.deps.configProvider)return 0;let e=this.deps.capacityLeft();if(e===0){let e=(await this.deps.persistence.list()).filter(e=>!this.deps.hasSession(e)).length;return e>0&&this.deps.logger.info({candidates:e},`Session pool full, restoreAll skipped (restore on demand)`),0}let t=await this.deps.persistence.listRecentMeta(e),n=[],r=0;for(let e of t){if(this.deps.hasSession(e))continue;let t;try{if(this.isRemoteCasPersistence()){let n=await this.deps.persistence.loadWithRevision(e);t=n?{snapshot:n.snapshot,revision:n.revision}:null}else{let n=await this.deps.persistence.load(e);t=n?{snapshot:n}:null}}catch(t){this.deps.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`restoreAll: a session snapshot failed to load (skipped, others unaffected)`);continue}if(!t)continue;let r=t.snapshot;if(r.version!==D){this.deps.logger.warn({sessionId:e,version:r.version,expected:D},`Session snapshot version mismatch, skipped`);continue}n.push(t)}let i=this.deps.capacityLeft();for(;n.length>i;)n.pop(),r++;r>0&&this.deps.logger.info({skipped:r,capacity:i},`Sessions exceeding pool capacity left on storage (restore on demand)`);let a=0,o=null;for(let e of n){let{snapshot:t}=e;if(!this.deps.hasSession(t.id))try{let n=new E(t.id,void 0,void 0,{clock:this.deps.clock,idGen:this.deps.idGen});n.restoreEntries(t.entries,t.metadata,t.leafId);let r=gn(this.deps.configProvider(t.metadata.config?.agentName,t.metadata.config?.modelId),t.metadata.config),i=await this.deps.adoptRestoredSession(n,r);t.metadata.archived&&i.archive(),await this.panelStateRestorer.restore(n,t,t.id),e.revision!==void 0&&this.remoteRevisions.set(t.id,e.revision),this.track(i,!1),await this.crashGapDetector.detect(i,t),a++,o===null&&(o=t.id)}catch(e){this.deps.logger.warn({sessionId:t.id,err:e instanceof Error?e.message:String(e)},`restoreAll: 单条会话重建失败(跳过,余者不受影响)`)}}return o&&this.deps.setActiveIfNone(o),this.deps.logger.info({count:a},`Sessions restored`),a}},W=class{panelStateStoreRef;sessions=new Map;configs=new Map;residencyClock=new Map;persistence;maxSessions;idleTimeoutMs;threshold;activeSessionId;stream;hookRegistry;logger;devtools;memory;traceStore;checkpointStore;clock;idGen;randomGen;residencyGovernor;getResidencyConfig;planeRegistry;configProvider;writeLeaseManager;coldSessionLister;semanticReviewer;hostCapabilities;autoPersist;timeTravel;persistenceSync;constructor(e,t,n=!1){this.autoPersist=n,this.stream=i(e.providerRegistry),this.hookRegistry=e.hookRegistry,this.logger=e.logger,this.devtools=e.devtools,this.memory=e.memory,this.traceStore=e.traceStore,this.checkpointStore=e.checkpointStore,this.clock=e.clock,this.idGen=e.idGen??De,this.randomGen=e.randomGen??Oe,this.residencyGovernor=e.residencyGovernor,this.getResidencyConfig=e.getResidencyConfig,this.planeRegistry=e.planeRegistry,this.configProvider=e.configProvider,this.writeLeaseManager=e.writeLeaseManager,this.coldSessionLister=e.coldSessionLister,this.semanticReviewer=e.semanticReviewer,this.hostCapabilities=e.hostCapabilities,this.persistence=t;let r=e.maxSessions??se;this.maxSessions=r,this.idleTimeoutMs=e.idleTimeoutMs??oe,this.threshold=Math.max(0,Math.min(e.threshold??r,r)),this.timeTravel=new an({logger:this.logger,traceStore:this.traceStore,checkpointStore:this.checkpointStore,getSession:e=>this.sessions.get(e),getConfig:e=>this.configs.get(e),createSession:(e,t)=>this.createSession(e,t),ensureCapacity:e=>{if(this.sessions.has(e))throw Error(`Session with ID ${e} already exists.`);this.prepareCapacity(e)},adoptForkedSession:(e,t)=>this.adoptForkedSession(e,t),...ue(this.persistence)?{hydrateEntries:(e,t)=>this.persistence.hydrateReplacements(e,t)}:{}}),this.persistenceSync=new _n({persistence:this.persistence,logger:this.logger,autoPersist:this.autoPersist,traceStore:this.traceStore,clock:this.clock,idGen:this.idGen,turnFlush:this.persistence.turnFlush,getSession:e=>this.sessions.get(e),getConfig:e=>this.configs.get(e),hasSession:e=>this.sessions.has(e),listSessionIds:()=>this.sessions.keys(),canAccommodate:e=>this.canAccommodate(e),capacityLeft:()=>Math.max(0,this.maxSessions-this.sessions.size),adoptRestoredSession:async(e,t)=>{let n=this.buildAgentSession(e,t);return this.sessions.set(e.id,n),this.configs.set(e.id,t),this.admitToResidency(e.id),await this.hookRegistry.emit(`session.restored`,{sessionId:e.id,metadata:{}}),n.notifyCreated(),n},setActiveIfNone:e=>{this.activeSessionId||=e},configProvider:this.configProvider,panelStateStore:e.panelStateStore,residencyGovernor:e.residencyGovernor,getResidencyConfig:e.getResidencyConfig}),this.panelStateStoreRef=e.panelStateStore}get panelState(){return this.panelStateStoreRef}get active(){return this.activeSessionId?this.sessions.get(this.activeSessionId):void 0}getSessionPermissionAllow(e){return[...this.configs.get(e)?.permissionAlwaysAllow??[]]}setSessionPermissionAllow(e,t){let n=this.configs.get(e);if(n){if(t.length===0){delete n.permissionAlwaysAllow;return}n.permissionAlwaysAllow=[...t]}}getSessionAvailableModels(e){return[...this.configs.get(e)?.availableModels??[]]}setSessionAvailableModels(e,t){let n=this.configs.get(e);if(n){if(t.length===0){delete n.availableModels;return}n.availableModels=[...t]}}admitToResidency(e){this.residencyClock.set(e,(this.clock??Ee).now()),this.planeRegistry?.session(e)}clearSessionPlaneGrid(e){this.planeRegistry?.disposeSessionGrid(e)}residencySince(e,t){let n=this.residencyClock.get(e)??-1/0;return Math.max(n,t.session.metadata().lastActiveAt)}trackPersistence(e,t){this.persistenceSync.track(e,t)}precreateSessionRow(e,t){this.persistenceSync.precreateSessionRow(e,t)}async adoptForkedSession(e,t){let n=this.buildAgentSession(e,t);return this.sessions.set(e.id,n),this.configs.set(e.id,t),this.admitToResidency(e.id),this.trackPersistence(n,!1),this.precreateSessionRow(n,!1),await this.hookRegistry.emit(`session.created`,{sessionId:e.id,metadata:{}}),n.notifyCreated(),n}buildAgentSession(e,t,n){let r=n??this.recordPorts(e.id);return new zt(e,{model:t.model,titleModel:t.titleModel,modelResolution:t.modelResolution,agentName:t.agentName,systemPrompt:t.systemPrompt,systemTail:t.systemTail,tools:r.tools??t.tools,thinkingLevel:t.thinkingLevel,maxToolTurns:t.maxToolTurns,maxToolTurnExtensions:t.maxToolTurnExtensions,promptOutputTokenBudget:t.promptOutputTokenBudget,promptWallClockBudgetMs:t.promptWallClockBudgetMs,stallDetection:t.stallDetection,idleTurnDetection:t.idleTurnDetection,sessionCostBudgetUSD:t.sessionCostBudgetUSD,todoContinuation:t.todoContinuation,promptRefresh:t.promptRefresh,workspaceDir:t.workspaceDir,workspaceId:t.workspaceId,transient:t.transient,depth:t.depth,interactive:t.interactive,listable:t.listable,retryAccelerate:t.retryAccelerate,streamRetry:t.streamRetry,networkDisconnectRetry:t.networkDisconnectRetry,lifecycleAsyncTimeoutMs:t.lifecycleAsyncTimeoutMs,describeImages:t.describeImages,getCompactionTimeoutMs:()=>k(this.getResidencyConfig?.()).compactionTimeoutMs,hookRegistry:this.hookRegistry,stream:r.stream??this.stream,logger:this.logger.child({sessionId:e.id}),devtools:this.devtools,memory:r.disableMemory?void 0:this.memory,recorder:r.recorder,nondetFlush:r.nondetFlush,clock:r.clock,semanticReviewer:this.semanticReviewer,hostCapabilities:this.hostCapabilities})}recordPorts(e){let t=this.traceStore;if(!t)return{clock:this.clock};let n=this.clock??Ee,r=be({sink:{append:n=>t.append(e,n).then(()=>void 0)},sessionId:e,clock:n}),i=ve({clock:n,random:this.randomGen,id:this.idGen},r);return{clock:i.clock,recorder:r,nondetFlush:i.flushNondetBatch}}async createSession(e,t){let n=e.id??this.idGen.uuid();if(this.sessions.has(n))throw Error(`Session with ID ${n} already exists.`);this.prepareCapacity(n);let r=new E(n,void 0,void 0,{clock:this.clock,idGen:this.idGen});r.setSdkVersion(de);let i=this.buildAgentSession(r,e,t);return this.sessions.set(n,i),this.configs.set(n,e),this.admitToResidency(n),(e.transient??!1)||(this.activeSessionId=n),this.trackPersistence(i,e.transient??!1),this.precreateSessionRow(i,e.transient??!1),await this.hookRegistry.emit(`session.created`,{sessionId:n,metadata:{}}),i.notifyCreated(),this.logger.info({sessionId:n},`Session created`),i}replaySession(e,t,n={}){return this.timeTravel.replaySession(e,t,n)}createCheckpoint(e,t={}){return this.timeTravel.createCheckpoint(e,t)}listCheckpoints(e){return this.timeTravel.listCheckpoints(e)}restoreCheckpoint(e,t,n=`both`){return this.timeTravel.restoreCheckpoint(e,t,n)}rollbackToCheckpoint(e,t,n=`both`){return this.timeTravel.rollbackToCheckpoint(e,t,n)}forkFromCheckpoint(e,t,n){return this.timeTravel.forkFromCheckpoint(e,t,n)}replayTrace(e,t,n=0){return this.timeTravel.replayTrace(e,t,n)}traceback(e,t){return this.timeTravel.traceback(e,t)}getSession(e){return this.sessions.get(e)}getResidencyDiagnostics(){let e=0,t=0;for(let[n,r]of this.sessions){if(this.configs.get(n)?.transient)continue;let i=r.session;i instanceof E&&(e++,t+=i.estimatedContentBytes)}let n=this.residencyGovernor?.currentLevel??`healthy`,r=R({activeSessionCount:e,currentTotalResidentBytes:t,pressureDivisor:L[n],config:this.getResidencyConfig?.()});return{activeSessionCount:e,totalResidentBytes:t,globalPressure:r.globalPressure,isGlobalPressure:r.isGlobalPressure,maxBytesPerSession:r.maxBytesPerSession,pressureLevel:n}}listSessions(e){let t=Array.from(this.sessions.values());e?.workspaceId&&(t=t.filter(t=>t.workspaceId===e.workspaceId));let n=t.map(e=>{let t=e.session.metadata();return{id:e.id,title:at(t.title,e.session.messages(),e.id),messageCount:e.session.messages().length,createdAt:t.createdAt?new Date(t.createdAt):new Date,updatedAt:t.lastActiveAt?new Date(t.lastActiveAt):void 0,model:e.model.id,status:e.status,sdkVersion:t.sdkVersion,workspaceId:e.workspaceId,pinned:e.pinned,pinGroup:t.pinGroup,writeLocked:this.writeLeaseManager?.isLockedByOther(e.id)??!1}});return n.sort((e,t)=>{let n=e.updatedAt?.getTime()??e.createdAt.getTime();return(t.updatedAt?.getTime()??t.createdAt.getTime())-n}),n}async listAllPersistedSessions(e){let t=e?.workspaceKey??`default`;if(this.coldSessionLister)return this.coldSessionLister.listColdSessions(t);let n;try{n=await this.persistence.listPaginated({page:0,pageSize:100,sortBy:`lastActiveAt`,order:`desc`})}catch(e){return this.logger.warn({workspaceKey:t,err:e instanceof Error?e.message:String(e)},`listAllPersistedSessions: listPaginated failed (batch unavailable, not a per-session issue)`),[]}let r=[];for(let e of n.items)try{let t=await this.persistence.load(e);if(!t)continue;let n=t.metadata;r.push({id:e,title:n.title?.trim()||e.slice(0,8),messageCount:n.messageCount??0,createdAt:n.createdAt?new Date(n.createdAt):new Date,updatedAt:n.lastActiveAt?new Date(n.lastActiveAt):void 0,status:n.archived?`archived`:`idle`,pinned:n.pinned,pinGroup:n.pinGroup,writeLocked:this.writeLeaseManager?.isLockedByOther(e)??!1})}catch(t){this.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`listAllPersistedSessions: a session snapshot failed to load (skipped, others unaffected)`)}return r}backfillTitles(){let e=0,t=0;for(let n of this.sessions.values()){let r=n.session.metadata().titleSource;if(r===`custom`||r===`ai`){t++;continue}n.backfillTitle(),e++}return{triggered:e,skipped:t}}async archiveSession(e){let t=this.sessions.get(e);return t?(await this.persistenceSync.save(e),le(this.persistence)&&await this.persistence.archiveSession(e),t.archive(),!0):!1}async removeSession(e){let t=this.sessions.get(e);if(!t){await this.persistenceSync.flushPending(e);let t=await this.persistence.delete(e);return await this.clearSessionStores(e),t}return t.dispose(),this.sessions.delete(e),this.configs.delete(e),this.residencyClock.delete(e),this.clearSessionPlaneGrid(e),this.activeSessionId===e&&(this.activeSessionId=void 0),await this.persistenceSync.flushPending(e),await this.persistence.delete(e),await this.clearSessionStores(e),this.hookRegistry.emit(`session.deleted`,{sessionId:e,metadata:{reason:`removed`}}),this.logger.info({sessionId:e},`Session removed`),!0}async clearSessionStores(e){let t=async(t,n)=>{if(n)try{await n.clear(e)}catch(n){this.logger.warn({sessionId:e,err:n instanceof Error?n.message:String(n)},`Failed to clear ${t} on session removal`)}};await t(`trace store`,this.traceStore),await t(`checkpoint store`,this.checkpointStore)}async ensureEntriesHydrated(e,t,n){if(!ce(t))return t;if(!ue(this.persistence))throw Error(`${n}: entries contain stripped compaction replacements but persistence lacks hydration capability (RFC-160 D4); refusing to fork stripped state`);return this.persistence.hydrateReplacements(e,t)}async forkSession(e,t){let n=this.sessions.get(e),r=this.configs.get(e);if(!n||!r)return;let i=n.session;if(!(i instanceof E))return;let a=t??this.idGen.uuid();this.prepareCapacity(a);let o=i.toSnapshot(),s=Bt(a,e,await this.ensureEntriesHydrated(e,o.entries,`forkSession`),o.metadata,o.leafId,this.clock,this.idGen),c={...r,model:n.model,agentName:n.agentName===`agent`?void 0:n.agentName,systemPrompt:n.systemPrompt,systemTail:n.systemTail,tools:n.tools,thinkingLevel:n.thinkingLevel,maxToolTurns:n.maxToolTurns,maxToolTurnExtensions:n.maxToolTurnExtensions,promptOutputTokenBudget:n.promptOutputTokenBudget,promptWallClockBudgetMs:n.promptWallClockBudgetMs,promptRefresh:n.promptRefresh,workspaceDir:n.workspaceDir,workspaceId:n.workspaceId},l=await this.adoptForkedSession(s,c);return this.logger.info({sessionId:a,sourceId:e},`Session forked`),l}save(e){return this.persistenceSync.save(e)}saveAll(){return this.persistenceSync.saveAll()}inspectSessionWriteLease(e){return this.writeLeaseManager?.inspect(e)??{locked:!1}}forceReleaseSessionWriteLease(e){this.writeLeaseManager?.forceRelease(e)}restore(e){return this.persistenceSync.restore(e)}consumeCrashGap(e){return this.persistenceSync.consumeCrashGap(e)}restoreAll(){return this.persistenceSync.restoreAll()}collectIdle(){let e=(this.clock??Ee).now(),t=[];for(let[n,r]of this.sessions)if(!(r.isBusy||r.isPaused)&&e-this.residencySince(n,r)>this.idleTimeoutMs){let e=r.session,i=!1;if(this.autoPersist&&e instanceof E){let t=e.toSnapshot();t.entries.length>0&&(i=!0,this.persistenceSync.saveSnapshot(n,t,()=>{this.persistenceSync.forgetEvictedSession(n)}).catch(e=>{this.logger.warn({sessionId:n,err:e instanceof Error?e.message:String(e)},`Session snapshot flush on idle eviction failed`)}))}r.dispose(),this.sessions.delete(n),this.configs.delete(n),this.residencyClock.delete(n),this.clearSessionPlaneGrid(n),i||this.persistenceSync.forgetSession(n),this.activeSessionId===n&&(this.activeSessionId=void 0),this.hookRegistry.emit(`session.deleted`,{sessionId:n,metadata:{reason:`idle`}}),t.push(n)}return t}entryCount(e){let t=e.session;return t instanceof E?t.entries().length:t.messages().length}evictLeastRecent(e){let t=Array.from(this.sessions.entries()).filter(([t,n])=>t!==e&&t!==this.activeSessionId&&!n.isBusy&&!n.isPaused&&!(this.configs.get(t)?.transient??!1)).filter(([,e])=>this.autoPersist||this.entryCount(e)===0).sort(([e,t],[n,r])=>this.residencySince(e,t)-this.residencySince(n,r));for(let[e,n]of t){if(this.sessions.size<this.maxSessions)break;let t=n.session,r=!1;if(this.autoPersist&&t instanceof E){let n=t.toSnapshot();n.entries.length>0&&(r=!0,this.persistenceSync.saveSnapshot(e,n,()=>{this.persistenceSync.forgetEvictedSession(e)}).catch(t=>{this.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`Session snapshot flush on eviction failed`)}))}n.dispose(),this.sessions.delete(e),this.configs.delete(e),this.residencyClock.delete(e),this.clearSessionPlaneGrid(e),r||this.persistenceSync.forgetSession(e),this.hookRegistry.emit(`session.deleted`,{sessionId:e,metadata:{reason:`evicted`}}),this.logger.info({sessionId:e},`Session evicted (LRU)`)}}prepareCapacity(e){if(!this.sessions.has(e)&&(this.sessions.size+1>this.threshold&&this.collectIdle(),this.sessions.size>=this.maxSessions&&this.evictLeastRecent(e),this.sessions.size>=this.maxSessions))throw Error(`Max sessions (${this.maxSessions}) reached.`)}canAccommodate(e){return this.sessions.has(e)?!0:(this.sessions.size+1>this.threshold&&this.collectIdle(),this.sessions.size>=this.maxSessions&&this.evictLeastRecent(e),this.sessions.size<this.maxSessions)}dispose(){for(let e of this.sessions.values())e.dispose();for(let e of this.sessions.keys())this.clearSessionPlaneGrid(e);this.sessions.clear(),this.configs.clear(),this.residencyClock.clear(),this.activeSessionId=void 0}};function vn(e){let{sessionUrl:t}=e;if(!t)throw Error(`sessionUrl is required for RemoteSessionPool`);return new W(e,new ie({baseUrl:t,fetch:e.fetch,getAuth:e.getAuth,timeoutMs:e.timeoutMs??3e4,userId:e.userId,wsKey:e.wsKey}),!0)}function yn(e){return new W(e,new re)}function bn(e,t,n=!0){return new W(e,t,n)}function xn(e,t){let n=new $e;return n.register(nt(e)),n}function Sn(e={}){let t=e.logger??d(`otto-runtime`,{level:`info`,destination:`stdout`}),n=e.providerRegistry??r(),i=e.hookRegistry??a({preset:`default`});e.hookRegistry||s(i);let o=e.storage??{kind:`in-memory`},c=e.traceStore===void 0,l=e.checkpointStore===void 0,{traceStore:u,checkpointStore:f}=Qe(o.kind===`remote`?{remoteLog:{baseUrl:o.sessionUrl,getAuth:o.getAuth,fetch:o.fetch,timeoutMs:o.timeoutMs}}:{},{traceStore:e.traceStore,checkpointStore:e.checkpointStore}),p=xn(e.workspaceDir??process.cwd(),e.memory),m=(()=>{if(o.kind===`custom`&&(o.panelStatePersistence||o.pasteStatePersistence))return new U(o.panelStatePersistence??S(),o.pasteStatePersistence??C());let e=o.kind===`custom`&&o.panelStateDir?o.panelStateDir:void 0;if(e!==void 0)return new U(new g({baseDir:e}),new _({baseDir:`${e}/paste`}))})(),h={hookRegistry:i,providerRegistry:n,logger:t,memory:e.memory,traceStore:u,checkpointStore:f,clock:e.clock,maxSessions:e.maxSessions,idleTimeoutMs:e.idleTimeoutMs,devtools:e.devtools,configProvider:e.configProvider,panelStateStore:m,residencyGovernor:e.residencyGovernor,getResidencyConfig:e.getResidencyConfig,planeRegistry:e.planeRegistry,semanticReviewer:e.semanticReviewer,hostCapabilities:e.hostCapabilities},v=o.kind===`remote`?vn({...h,sessionUrl:o.sessionUrl,fetch:o.fetch,getAuth:o.getAuth,timeoutMs:o.timeoutMs,userId:o.userId,wsKey:o.wsKey}):o.kind===`custom`?bn({...h,writeLeaseManager:o.writeLeaseManager,coldSessionLister:o.coldSessionLister},o.persistence,o.autoPersist??!0):yn(h);return{createSession:(e,t)=>v.createSession(e,t),sessions:v,hookRegistry:i,stream:v.stream,contextSources:p,traceStore:u,checkpointStore:f,clock:e.clock,dispose:async()=>{v.dispose(),c&&await u.close?.(),l&&await f.close?.(),o.kind===`custom`&&await o.onDispose?.()}}}function Cn(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0&&r<=100?r:t}function G(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0?r:t}var wn=class{warnThresholdPct;hardThresholdPct;sampleIntervalMs;warningIntervalMs;criticalIntervalMs;warnCooldownMs;onWarning;onCritical;logger;now;postRestartGraceMs;ticker=null;lastLevel=`healthy`;lastWarningFiredAt;graceStartedAt;onCriticalDuringGrace;onLevelChange;onSample;disposed=!1;criticalTimeoutMs;onCriticalTimeout;criticalEnteredAt;criticalTimeoutFired=!1;constructor(e={}){this.warnThresholdPct=e.warnThresholdPct??Cn(`OTTO_MEMORY_WARN_PCT`,70),this.hardThresholdPct=e.hardThresholdPct??Cn(`OTTO_MEMORY_HARD_PCT`,85),this.sampleIntervalMs=e.sampleIntervalMs??G(`OTTO_MEMORY_SAMPLE_INTERVAL_MS`,3e4),this.warningIntervalMs=e.warningIntervalMs??G(`OTTO_MEMORY_WARNING_INTERVAL_MS`,1e4),this.criticalIntervalMs=e.criticalIntervalMs??G(`OTTO_MEMORY_CRITICAL_INTERVAL_MS`,5e3),this.warnCooldownMs=e.warnCooldownMs??3e5,this.postRestartGraceMs=e.postRestartGraceMs??6e5,this.criticalTimeoutMs=e.criticalTimeoutMs??G(`OTTO_MEMORY_CRITICAL_TIMEOUT_MS`,9e5),this.onWarning=e.onWarning,this.onCritical=e.onCritical,this.onCriticalDuringGrace=e.onCriticalDuringGrace,this.onLevelChange=e.onLevelChange,this.onSample=e.onSample,this.onCriticalTimeout=e.onCriticalTimeout,this.logger=e.logger,this.now=e.now??(()=>Date.now())}get currentLevel(){return this.lastLevel}setCallbacks(e){`onWarning`in e&&(this.onWarning=e.onWarning),`onCritical`in e&&(this.onCritical=e.onCritical),`onCriticalDuringGrace`in e&&(this.onCriticalDuringGrace=e.onCriticalDuringGrace),`onLevelChange`in e&&(this.onLevelChange=e.onLevelChange),`onSample`in e&&(this.onSample=e.onSample),`onCriticalTimeout`in e&&(this.onCriticalTimeout=e.onCriticalTimeout)}markRestarted(){this.graceStartedAt=this.now()}updateThresholds(e){e.warnThresholdPct!=null&&process.env.OTTO_MEMORY_WARN_PCT===void 0&&(this.warnThresholdPct=e.warnThresholdPct),e.hardThresholdPct!=null&&process.env.OTTO_MEMORY_HARD_PCT===void 0&&(this.hardThresholdPct=e.hardThresholdPct)}get inPostRestartGrace(){return this.graceStartedAt===void 0?!1:this.now()-this.graceStartedAt<this.postRestartGraceMs}sample(){let{heapUsed:e,rss:t,external:n}=process.memoryUsage(),{heap_size_limit:r}=He(),i=r>0?e/r*100:0;return{level:this.grade(i),heapUsed:e,heapSizeLimit:r,usedPct:i,rss:t,external:n,ts:this.now()}}grade(e){return e>=this.hardThresholdPct?`critical`:e>=this.warnThresholdPct?`warning`:`healthy`}start(){this.ticker||(this.ticker=setTimeout(()=>this.tick(),this.sampleIntervalMs),this.ticker.unref?.())}tick(){let e=this.sample();if(this.disposed)return;if(this.onSample?.(e),e.level!==this.lastLevel){if(this.logger?.info({from:this.lastLevel,to:e.level,usedPct:e.usedPct.toFixed(1),heapUsed:e.heapUsed,heapSizeLimit:e.heapSizeLimit},`[memory-governor] pressure level changed`),this.onLevelChange?.(e.level),e.level===`warning`){let e=this.now();this.lastWarningFiredAt!==void 0&&e-this.lastWarningFiredAt<this.warnCooldownMs?this.logger?.info({cooldownRemainingMs:this.warnCooldownMs-(e-this.lastWarningFiredAt)},`[memory-governor] onWarning skipped (within cooldown)`):(this.lastWarningFiredAt=e,this.onWarning?.())}e.level===`critical`&&(this.inPostRestartGrace?this.onCriticalDuringGrace?.(e):this.onCritical?.(e))}if(e.level===`critical`?this.criticalEnteredAt===void 0?(this.criticalEnteredAt=this.now(),this.criticalTimeoutFired=!1):!this.criticalTimeoutFired&&this.now()-this.criticalEnteredAt>=this.criticalTimeoutMs&&(this.criticalTimeoutFired=!0,this.onCriticalTimeout?.(e)):(this.criticalEnteredAt=void 0,this.criticalTimeoutFired=!1),this.lastLevel=e.level,this.disposed)return;let t=this.lastLevel===`critical`?this.criticalIntervalMs:this.lastLevel===`warning`?this.warningIntervalMs:this.sampleIntervalMs;this.ticker=setTimeout(()=>this.tick(),t),this.ticker.unref?.()}dispose(){this.disposed=!0,this.ticker&&=(clearTimeout(this.ticker),null)}};function K(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0?r:t}var Tn=class{sampleIntervalMs;maxProcesses;maxTotalRssMb;listProcesses;logger;now;onSample;onBudgetExceeded;ticker=null;disposed=!1;budgetExceededNotified=!1;constructor(e={}){this.sampleIntervalMs=e.sampleIntervalMs??K(`OTTO_FLEET_SAMPLE_INTERVAL_MS`,6e5),this.maxProcesses=e.maxProcesses??K(`OTTO_FLEET_MAX_PROCESSES`,8),this.maxTotalRssMb=e.maxTotalRssMb??K(`OTTO_FLEET_MAX_TOTAL_RSS_MB`,8192),this.listProcesses=e.listProcesses??me,this.onSample=e.onSample,this.onBudgetExceeded=e.onBudgetExceeded,this.logger=e.logger,this.now=e.now??(()=>Date.now())}setCallbacks(e){`onSample`in e&&(this.onSample=e.onSample),`onBudgetExceeded`in e&&(this.onBudgetExceeded=e.onBudgetExceeded)}sample(){let e;try{e=this.listProcesses()}catch(e){this.logger?.warn({err:e instanceof Error?e.message:String(e)},`[fleet-monitor] process enumeration failed (skipping sample)`);return}if(e.length===0)return;let t=0,n=0,r=0;for(let i of e)t+=i.rssKb,i.ppid===1&&i.tty===`??`&&n++,i.generation!==void 0&&i.generation>r&&(r=i.generation);return{processCount:e.length,totalRssMb:Math.round(t/1024),suspectedOrphanCount:n,maxGeneration:r,ts:this.now()}}tick(){if(this.disposed)return;let e=this.sample();if(e){this.onSample?.(e);let t=e.processCount>this.maxProcesses,n=e.totalRssMb>this.maxTotalRssMb;if(t||n){if(!this.budgetExceededNotified){this.budgetExceededNotified=!0;let n=t?`process-count`:`total-rss`;this.logger?.warn({processCount:e.processCount,totalRssMb:e.totalRssMb,maxProcesses:this.maxProcesses,maxTotalRssMb:this.maxTotalRssMb},`[fleet-monitor] fleet budget exceeded`),this.onBudgetExceeded?.(e,n)}}else this.budgetExceededNotified=!1}this.disposed||(this.ticker=setTimeout(()=>this.tick(),this.sampleIntervalMs),this.ticker.unref?.())}start(){this.ticker||this.disposed||(this.ticker=setTimeout(()=>this.tick(),this.sampleIntervalMs),this.ticker.unref?.())}dispose(){this.disposed=!0,this.ticker&&=(clearTimeout(this.ticker),null)}};const q=fe,J=(e,t)=>{try{process.kill(-e,t)}catch{try{process.kill(e,t)}catch{}}},Y=e=>{try{We(`taskkill`,[`/F`,`/T`,`/PID`,`${e}`],{stdio:`ignore`,timeout:5e3})}catch{}};var En=class{entries=new Map;maxProcesses;graceMs;clock;spawnListeners=new Set;exitListeners=new Set;constructor(e={}){this.maxProcesses=e.maxProcesses??64,this.graceMs=e.graceMs??2e3,this.clock=e.clock??(()=>Date.now())}onSpawn(e){return this.spawnListeners.add(e),()=>this.spawnListeners.delete(e)}onExit(e){return this.exitListeners.add(e),()=>this.exitListeners.delete(e)}notify(e,t){for(let n of[...e])try{n(t)}catch{}}register(e){if(this.entries.size>=this.maxProcesses&&this.evictLeastRecent(),this.entries.size>=this.maxProcesses)throw Error(`Background process limit (${this.maxProcesses}) reached; stop one with kill_shell first.`);let t=e.child.pid;if(t===void 0)throw Error(`Cannot register a child process without a pid`);let n=e.now??this.clock(),r={id:e.id,sessionId:e.sessionId,owner:e.owner,pid:t,pgid:t,command:e.command,cwd:e.cwd,port:e.port,url:e.url,logPath:e.logPath,startedAt:n,lastUsed:n,status:`running`,keepAlive:e.keepAlive},i={info:r,child:e.child};return this.entries.set(e.id,i),e.child.once(`exit`,e=>{r.status===`running`?(r.status=`exited`,r.exitCode=e??void 0):r.status===`killing`&&(r.status=`killed`),i.silenced||this.notify(this.exitListeners,r)}),this.notify(this.spawnListeners,r),r}get(e){return this.entries.get(e)?.info}getForSession(e,t){let n=this.entries.get(t);return n&&n.info.sessionId===e?n.info:void 0}list(){return[...this.entries.values()].map(e=>e.info)}listForSession(e){return this.list().filter(t=>t.sessionId===e)}touch(e){let t=this.entries.get(e);t&&(t.info.lastUsed=this.clock())}updateDetectedService(e,t){let n=this.entries.get(e);n&&(n.info.detectedService?.url&&!t.url||(n.info.detectedService=t))}remove(e){let t=this.entries.get(e);t&&(t.silenced=!0,this.entries.delete(e))}size(){return this.entries.size}async kill(e){let t=this.entries.get(e);t&&await this.killEntry(t)}async killAll(){await Promise.all([...this.entries.values()].map(e=>this.killEntry(e)))}async killAllForOwner(e){await Promise.all([...this.entries.values()].filter(t=>t.info.owner===e).map(e=>this.killEntry(e)))}async killAllForSession(e){await Promise.all([...this.entries.values()].filter(t=>t.info.sessionId===e).map(e=>this.killEntry(e)))}killAllSync(){for(let e of this.entries.values())this.killEntrySync(e)}killEntrySync(e){let{info:t}=e;t.status===`exited`||t.status===`killed`||(process.platform===`win32`?Y(t.pid):J(t.pgid,`SIGKILL`),t.status=`killed`)}evictLeastRecent(){let e;for(let t of this.entries.values()){if(t.info.status===`exited`||t.info.status===`killed`){e=t;break}t.info.keepAlive||(!e||t.info.lastUsed<e.info.lastUsed)&&(e=t)}e&&(e.silenced=!0,this.killEntrySync(e),this.entries.delete(e.info.id))}async killEntry(e){let{info:t}=e;if(t.status===`running`){if(t.status=`killing`,process.platform===`win32`){Y(t.pid),t.status=`killed`;return}J(t.pgid,`SIGTERM`),await this.waitForExit(e,this.graceMs)||J(t.pgid,`SIGKILL`),t.status=`killed`}}waitForExit(e,t){return new Promise(n=>{let r=!1,i,a=t=>{r||(r=!0,clearTimeout(i),e.child.removeListener(`exit`,o),n(t))},o=()=>a(!0);if(e.child.once(`exit`,o),!q(e.info.pid)){a(!0);return}i=setTimeout(()=>a(!1),t)})}};const Dn=new En;let On=!1;function kn(e=Dn){On||(On=!0,process.on(`exit`,()=>{e.killAllSync()}))}let An=0;var jn=class extends Ge{id;child;config;status=`starting`;_clock;_pid;_pgid;_exitResult=null;_exitResolve=null;_stdoutBuf=``;_stderrBuf=``;lastUsed;startedAt;_detectedService;constructor(e,t,n){if(super(),this._clock=n,this.id=`proc_${++An}_${this._clock()}`,this.child=e,this.config=t,this._pid=e.pid,this._pgid=e.pid,this.lastUsed=this._clock(),this.startedAt=this.lastUsed,this.child.on(`spawn`,()=>{this._pid=this.child.pid,this._pgid=this.child.pid,this.status===`starting`&&(this.status=`running`)}),this.child.on(`error`,e=>{this.lastUsed=this._clock(),(this.status===`starting`||this.status===`running`)&&(this.status=`errored`),this.emit(`error`,e)}),this.child.on(`exit`,(e,t)=>{this.lastUsed=this._clock();let n={code:e,signal:t,timedOut:!1};this._exitResult=n,this.status===`running`?this.status=`exited`:this.status===`killing`&&(this.status=`killed`),this.emit(`exit`,n),this._exitResolve&&=(this._exitResolve(n),null)}),this.child.stdout&&this.child.stdout.on(`data`,e=>{this.lastUsed=this._clock();let t=e.toString(`utf-8`);for(this._stdoutBuf+=t;;){let e=this._stdoutBuf.indexOf(`
15
+ Bad (wrong case): {"title": "Fix Login Button On Mobile"}`,messages:t,cacheRetention:`none`,maxTokens:64,temperature:0},i.signal).result()).content))}catch{return null}finally{clearTimeout(o),n.removeEventListener(`abort`,a)}}var ft=class{session;stream;titleModel;genSeq=0;abortController=new AbortController;disposed=!1;constructor(e){this.session=e.session,this.stream=e.stream,this.titleModel=e.titleModel}maybeGenerate(e=!1){if(!this.titleModel||this.disposed||this.session.metadata().titleSource===`custom`)return;let t=this.session.messages().filter(e=>e.role===`user`).length;if(t===0||!e&&t>3)return;let n=++this.genSeq,r=this.session.messages().map(e=>{let t=e.content;return typeof t==`string`?t:Array.isArray(t)?t.filter(e=>{let t=e;return t.type===`text`&&typeof t.text==`string`}).map(e=>e.text).join(` `):``}).filter(Boolean).join(`
16
+ `);dt({stream:this.stream,model:this.titleModel},r,this.abortController.signal).then(e=>{!e||this.disposed||n===this.genSeq&&this.session.metadata().titleSource!==`custom`&&this.session.setTitle(e,`ai`)}).catch(()=>{})}backfill(){this.maybeGenerate(!0)}dispose(){this.disposed||(this.disposed=!0,this.abortController.abort())}},pt=class{constructor(e){this.deps=e}messages(){return this.deps.session.messages()}append(e){this.deps.session.append(e)}removeLast(){this.deps.session.removeLast()}persistInputBoundary(){this.deps.requestInputBoundaryFlush?.()}buildContext(){return this.deps.session.buildContext()}persistNew(e,t){let n=e.slice(t);for(let e of n)this.deps.session.append(e)}recordCompaction(e,t){let{session:n,sessionId:r,publish:i}=this.deps,a=n.buildContext().messages.length;n.recordCompaction(e,t);let o=n.buildContext().messages.length;o<a&&(i({"compaction.start":[{type:`compaction.start`,sessionId:r,messageCount:a}]}),i({"compaction.end":[{type:`compaction.end`,sessionId:r,retainedCount:o,summary:e}]}))}notifyPrune(e,t){this.deps.publish({"memory.pruned":[{type:`memory.pruned`,sessionId:this.deps.sessionId,tokensSaved:e,prunedCount:t?.prunedCount,messagesBefore:t?.messagesBefore,messagesAfter:t?.messagesAfter}]})}};const mt=`Before continuing, audit each remaining todo against the actual current state: if evidence shows it is already satisfied, mark it done; if it is scope creep beyond the original request, drop it (skipped, with a reason). Only work on items that a requirement-level audit proves unfinished. Do not add new todos unless the user's original request demands them. If work remains after this round, leave the genuinely-unfinished todos active — the engine will admit another round; do not wrap up or stop early merely because rounds or tokens look large.`,ht=`You made progress but did not update the todo list. Reconcile it now: mark each genuinely finished item done (or skipped/failed with a reason) via write_todos, then continue any remaining work.`,F=new Set([`done`,`skipped`,`failed`]);var gt=class e{session;sessionId;logger;todoContinuation;depth;publish;isAbortRequested;runPromptRound;withReducedThinking;needsCompaction;compactNow;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.logger=e.logger,this.todoContinuation=e.todoContinuation,this.depth=e.depth,this.publish=e.publish,this.isAbortRequested=e.isAbortRequested,this.runPromptRound=e.runPromptRound,this.withReducedThinking=e.withReducedThinking??(e=>e()),this.needsCompaction=e.needsCompaction,this.compactNow=e.compactNow}snapshot(){return new Map((this.session.getTodoList()??[]).map(e=>[e.id,e.status]))}countIncomplete(){return(this.session.getTodoList()??[]).filter(e=>!F.has(e.status??`pending`)).length}static hasStateProgress(e,t){for(let[n,r]of t){if(!F.has(r??``))continue;let t=e.get(n);if(!F.has(t??`pending`))return!0}return!1}wrapContinuation(e,t,n,r){return`<engine_continuation round="${e}" cap="${t}"${r?` type="${r}"`:``}>\n${n}\n</engine_continuation>`}async run(){if(!this.todoContinuation.enabled||this.depth>0)return;let t=this.todoContinuation.max*4,n=0,r=0,i=0,a=!1,o=mt,s=this.snapshot();for(;n<this.todoContinuation.max&&r<t&&!this.isAbortRequested()&&this.countIncomplete()>0;){n++,r++,this.publish({"prompt.continued":[{type:`prompt.continued`,sessionId:this.sessionId,round:r,maxRounds:t,incompleteCount:this.countIncomplete()}]}),this.logger.info({sessionId:this.sessionId,round:n,totalRounds:r,max:this.todoContinuation.max,hardCap:t},`Todo gate: auto-continuing unfinished todos`),this.needsCompaction&&this.compactNow&&this.needsCompaction()&&(this.logger.info({sessionId:this.sessionId},`Todo gate: pre-continuation compaction triggered (context near window limit)`),await this.compactNow());let c=o===ht,l=this.wrapContinuation(r,t,o,c?`sync`:void 0),u=await this.withReducedThinking(()=>this.runPromptRound(l,!0));if(u.cancelled)return;o=mt;let d=this.snapshot();if(e.hasStateProgress(s,d)){n--,i=0,s=d;continue}if(u.hadToolActivity&&!a){n--,a=!0,i=1,o=ht,this.logger.info({sessionId:this.sessionId,round:n},`Todo gate: tool activity without todo updates — nudging state reconciliation`);continue}if(u.hadToolActivity){i++,this.logger.info({sessionId:this.sessionId,staleActivityRounds:i},`Todo gate: diminishing returns (repeated activity without todo progress), stopping`);return}this.logger.info({sessionId:this.sessionId,round:n},`Todo gate: no progress between rounds, stopping early`);return}}};async function _t(e,t,n){let{session:r,sessionId:i,hookRegistry:a,logger:o,publish:s}=e,c=r.messages().length;await a.emit(`compaction.before`,{sessionId:i,messageCount:c}),s({"compaction.start":[{type:`compaction.start`,sessionId:i,messageCount:c}]}),o.info({sessionId:i,count:n},`Session compacting`),r.compact(t,n);let l=r.messages().length;await a.emit(`compaction.after`,{sessionId:i,retainedCount:l}),s({"compaction.end":[{type:`compaction.end`,sessionId:i,retainedCount:l,summary:t}]}),o.info({sessionId:i,retained:l,summaryChars:t.length},`Session compaction finished`)}async function vt(e,t){let{session:n,sessionId:r,hookRegistry:i,logger:a,memory:o,persistence:s}=e,c=n.buildContext(),l=c.messages.length;if(!o||t?.aborted)return{compacted:!1,before:l,after:l};await i.emit(`compaction.before`,{sessionId:r,messageCount:l}),a.info({sessionId:r,messageCount:l},`Session manual compaction (forced)`);let u={compacted:!1};await Ce(o,c.messages,r,t,{persistence:s,sink:u});let d=n.buildContext().messages.length;return await i.emit(`compaction.after`,{sessionId:r,retainedCount:d}),a.info({sessionId:r,retainedCount:d},`Session manual compaction finished`),{compacted:u.compacted,before:l,after:d}}function yt(e,t,n,r){return[e.on(`max.turns`,e=>{e.steered&&r(),n({"budget.notice":[{type:`budget.notice`,sessionId:t,turnIndex:e.turnIndex,maxTurns:e.maxTurns,extended:e.extended,...e.steered===void 0?{}:{steered:e.steered},...e.progressDenied===void 0?{}:{progressDenied:e.progressDenied}}]})}),e.on(`prompt.budget`,e=>{e.steered&&r(),n({"prompt.budget.notice":[{type:`prompt.budget.notice`,sessionId:t,turnIndex:e.turnIndex,dimension:e.dimension,used:e.used,budget:e.budget,steered:e.steered}]})}),e.on(`progress.stall`,e=>{n({"progress.stall.notice":[{type:`progress.stall.notice`,sessionId:t,turnIndex:e.turnIndex,windowTurns:e.windowTurns,maxRepeat:e.maxRepeat}]})}),e.on(`tool.call.mismatch`,e=>{n({"tool.call.mismatch.notice":[{type:`tool.call.mismatch.notice`,sessionId:t,turnIndex:e.turnIndex,outcome:e.outcome,retryCount:e.retryCount}]})}),e.on(`turn.idle`,e=>{n({"turn.idle.notice":[{type:`turn.idle.notice`,sessionId:t,turnIndex:e.turnIndex,outcome:e.outcome,textChars:e.textChars}]})}),e.on(`image.vision-delegate`,e=>{n({"image.vision-delegate":[{type:`image.vision-delegate`,sessionId:t,attemptedCount:e.attemptedCount,describedCount:e.describedCount,failedCount:e.failedCount}]})}),e.on(`compaction.reactive`,e=>{n({"compaction.reactive.notice":[{type:`compaction.reactive.notice`,sessionId:t,messagesBefore:e.messagesBefore,messagesAfter:e.messagesAfter}]})}),e.on(`image.degradation`,e=>{n({"image.degradation.notice":[{type:`image.degradation.notice`,sessionId:t,degradedCount:e.degradedCount,trigger:e.trigger}]})})]}function bt(e,t){if(e)return e.length>t?`${e.slice(0,t)}…`:e}function xt(e,t){if(t.toolCall.name!==`write_todos`||t.result.isError)return;let n=t.result.details?.todos;if(!Array.isArray(n))return;let r=new Map((e.getTodoList()??[]).map(e=>[e.id,e.turn]));e.setTodoList(n.map(e=>({id:e.id,title:e.title,status:e.status,turn:e.id===void 0?void 0:r.get(e.id)})))}function St(e){let{agent:t,session:n,sessionId:r,modelId:i,hookRegistry:a,publish:o}=e;return[t.on(`stream.event`,async({event:e})=>{o({"stream.event":[{type:`stream.event`,sessionId:r,event:e}]}),e.type===`start`?(o({"streaming.start":[{type:`streaming.start`,sessionId:r,model:i()}]}),a.emit(`stream.start`,{sessionId:r,model:i()})):e.type===`done`&&(o({"streaming.end":[{type:`streaming.end`,sessionId:r,model:i(),stopReason:e.reason??`end_turn`}]}),await a.emit(`stream.end`,{sessionId:r,model:i(),stopReason:e.reason??`end_turn`,tokenUsage:{input:e.message.usage.inputTokens,output:e.message.usage.outputTokens}}))}),t.on(`turn.start`,e=>{o({"turn.start":[{type:`turn.start`,sessionId:r,turnIndex:e.turnIndex,toolTurnCount:e.toolTurnCount,maxToolTurns:e.maxToolTurns,promptOutputTokens:e.promptOutputTokens,promptOutputTokenBudget:e.promptOutputTokenBudget}]})}),t.on(`turn.end`,e=>{o({"turn.end":[{type:`turn.end`,sessionId:r,turnIndex:e.turnIndex}]})}),t.on(`tool.call.start`,e=>{o({"tool.call.start":[{type:`tool.call.start`,sessionId:r,toolCall:{id:e.toolCall.id,name:e.toolCall.name,arguments:e.toolCall.arguments}}]})}),t.on(`tool.call.end`,e=>{xt(n,e);let t=Te(Se(e.result)),i=e.contextChars??t.length;o({"tool.call.end":[{type:`tool.call.end`,sessionId:r,toolCall:{id:e.toolCall.id,name:e.toolCall.name,arguments:e.toolCall.arguments},isError:e.result.isError===!0,resultText:bt(t,he.traceResultMaxChars),resultTokensEstimate:Math.ceil(i/4),details:e.result.details??void 0}]})})]}const Ct=100*1024*1024;function wt(e){return e.replace(/[^a-zA-Z0-9_-]/g,`_`).slice(0,128)||`unnamed`}var Tt=class{rootDir;constructor(e){this.rootDir=p(e,`tool-results`)}sessionDir(e){return p(this.rootDir,wt(e))}async spill(e,t,n){if(!pe())try{let r=this.sessionDir(e);await Ae(r,{recursive:!0});let i=p(r,`${wt(t)}.txt`);return await Ie(i,n,`utf-8`),this.evictIfOverBudget().catch(()=>{}),i}catch{return}}async cleanupSession(e){try{await Ne(this.sessionDir(e),{recursive:!0,force:!0})}catch{}}async evictIfOverBudget(){let e=[],t=0,n;try{n=await Me(this.rootDir)}catch{return}for(let r of n){let n=p(this.rootDir,r),i;try{i=await Me(n)}catch{continue}for(let r of i){let i=p(n,r);try{let n=await Pe(i);n.isFile()&&(e.push({path:i,mtimeMs:n.mtimeMs,size:n.size}),t+=n.size)}catch{}}}if(!(t<=Ct)){e.sort((e,t)=>e.mtimeMs-t.mtimeMs);for(let n of e){if(t<=Ct)break;try{await Fe(n.path),t-=n.size}catch{}}}}};let Et;function Dt(){return Et??=new Tt(p(process.cwd(),`.otto`)),Et}const Ot={spill(e,t,n){return Dt().spill(e,t,n)},cleanupSession(e){return Dt().cleanupSession(e)}},kt={maxToolTurns:he.maxToolTurns};function At(){let e,t,n=new Promise((n,r)=>{e=n,t=r});return{resolve:e,reject:t,promise:n}}var I=class{pending=new Map;open(e){let t=At();return this.pending.set(e,t),t.promise.finally(()=>{this.pending.delete(e)})}resolve(e,t){let n=this.pending.get(e);return n?(n.resolve(t),!0):!1}rejectAll(e){for(let t of this.pending.values())t.reject(e);this.pending.clear()}};const jt=`[sandbox-escalation]`;function Mt(e){return e.includes(jt)}async function Nt(e,t,n,r,i){try{let a=await e(t,n,r,i);return a===`allow`||a===`deny`?a:`abstain`}catch{return`abstain`}}var Pt=class{approvalGate=new I;grillGate=new I;planGate=new I;constructor(e){this.deps=e}async requestApproval(e,t,n,r,i){let{sessionId:a,interactive:o,logger:s,publish:c}=this.deps,l=this.deps.hostCapabilities?.permissionAsk;if(l)try{let o=await l({sessionId:a(),toolName:e,input:t,reason:n,risk:r},i??new AbortController().signal),c=o.decision===`allow`;return s.info({sessionId:a(),toolName:e,approved:c},`Approval decided by host capability port`),{approved:c,...o.updatedInput?{updatedArgs:o.updatedInput}:{},...o.message?{message:o.message}:{}}}catch(t){return s.warn({sessionId:a(),toolName:e,err:t},`Host permission port failed; denying (fail-closed)`),{approved:!1,message:`host approval port failed`}}if(!o)return s.warn({sessionId:a(),toolName:e},`Approval requested in a non-interactive session; denying (fail-closed, no human to respond)`),!1;let u=O(),d=this.approvalGate.open(u),f;if(this.deps.semanticReviewer&&Mt(n)){let i=await Nt(this.deps.semanticReviewer,e,t,n,r);(i===`allow`||i===`deny`)&&(f=i,s.info({sessionId:a(),toolName:e,approvalId:u,verdict:i},`Semantic reviewer decided`),this.approvalGate.resolve(u,i===`allow`))}return c({"approval.required":[{type:`approval.required`,sessionId:a(),id:u,toolName:e,arguments:t,description:n,risk:r,...f?{semanticVerdict:f}:{}}]}),s.info({sessionId:a(),toolName:e,approvalId:u},`Approval requested`),d}resolveApproval(e,t){let{sessionId:n,logger:r,publish:i}=this.deps;this.approvalGate.resolve(e,t)&&(i({"approval.resolved":[{type:`approval.resolved`,sessionId:n(),id:e,approved:t}]}),r.info({sessionId:n(),approvalId:e,approved:t},`Approval resolved`))}async requestGrill(e){let{sessionId:t,interactive:n,logger:r,publish:i}=this.deps,a=this.deps.hostCapabilities?.userAsk;if(a){let n=O(),i={...e,id:n};try{return await a({sessionId:t(),question:i},new AbortController().signal)}catch(e){return r.warn({sessionId:t(),requestId:n,err:e},`Host user-ask port failed; not accepting recommendation (fail-closed)`),{answer:`(host ask port failed; no user answer)`,acceptedRecommendation:!1,resolvedBy:`environment_headless`}}}if(!n)return{answer:e.recommendation,acceptedRecommendation:!0,resolvedBy:`auto_recommendation`};let o=O(),s={...e,id:o},c=this.grillGate.open(o);return i({"ask.user.required":[{type:`ask.user.required`,sessionId:t(),requestId:o,question:s}]}),r.info({sessionId:t(),requestId:o,askedBy:e.askedBy},`Grill requested`),c}resolveAskUser(e,t){let{sessionId:n,logger:r,publish:i}=this.deps;t&&this.grillGate.resolve(e,t)&&(i({"ask.user.resolved":[{type:`ask.user.resolved`,sessionId:n(),requestId:e}]}),r.info({sessionId:n(),requestId:e},`Grill resolved`))}async requestPlanApproval(e){let{sessionId:t,logger:n,publish:r}=this.deps,i=O(),a=this.planGate.open(i);return r({"plan.approval.required":[{type:`plan.approval.required`,sessionId:t(),requestId:i,planContent:e}]}),n.info({sessionId:t(),requestId:i},`Plan approval requested`),a}resolvePlanApproval(e,t,n){let{sessionId:r,logger:i,publish:a}=this.deps;this.planGate.resolve(e,{action:t,feedback:n})&&(a({"plan.approval.resolved":[{type:`plan.approval.resolved`,sessionId:r(),requestId:e,action:t}]}),i.info({sessionId:r(),action:t,requestId:e},`Plan approval resolved`))}rejectAll(e){this.approvalGate.rejectAll(e),this.grillGate.rejectAll(e),this.planGate.rejectAll(e)}},Ft=class{costTracker=new e;sessionCrossedCostBudget=!1;lastTokenUsage;lastTotalInputTokens;lastCacheHitRatio=null;constructor(e){this.deps=e}record(e,n){let r=e.usage;if(e.count===0||e.lastAssistantApi===void 0)return;this.lastTokenUsage={input:r.inputTokens,output:r.outputTokens},this.lastTotalInputTokens=r.cacheReadTokens+r.cacheWriteTokens+r.inputTokens,this.lastCacheHitRatio=t(r,e.lastAssistantApi);let i=this.costTracker.record(n,r),a=this.costTracker.summary().totalCostUSD,{sessionId:o,logger:s,publish:c,sessionCostBudgetUSD:l}=this.deps;s.info({sessionId:o(),input:r.inputTokens,output:r.outputTokens,cacheRead:r.cacheReadTokens,cacheWrite:r.cacheWriteTokens,cacheHitRatio:this.lastCacheHitRatio,turnCost:i.toFixed(6),sessionCost:a.toFixed(6)},`Session usage`),!this.sessionCrossedCostBudget&&l!==void 0&&l>0&&a>=l&&(this.sessionCrossedCostBudget=!0,c({"session.cost-budget-exceeded":[{type:`session.cost-budget-exceeded`,sessionId:o(),totalCostUSD:a,budgetUSD:l}]}))}getLastTokenUsage(){return this.lastTokenUsage}getLastTotalInputTokens(){return this.lastTotalInputTokens}getCostSummary(){return this.costTracker.summary()}getLastCacheHitRatio(){return this.lastCacheHitRatio}};function It(e,t){e.ensureNotDisposed();let n=`steer-${++e.steerSeq.value}`,r={role:`user`,timestamp:e.clock?.now()??Date.now(),content:[{type:`text`,text:t}],uuid:n};return e.agent.steer(r),{id:n}}function Lt(e,t){return e.ensureNotDisposed(),e.agent.removeSteer(t)}function Rt(e,t){e.ensureNotDisposed(),e.agent.followUp({role:`user`,timestamp:e.clock?.now()??Date.now(),content:[{type:`text`,text:t}]})}async function zt(e,t){let{text:n,internal:r,images:i,resumeLastRound:a}=t;if(e.compactionPending){let t=e.compactionPending;e.setCompactionPending(void 0);try{let n=e.getCompactionTimeoutMs?.()??Re;await Promise.race([t,new Promise((e,t)=>setTimeout(()=>t(Error(`compaction timeout`)),n))])}catch{}}if(e.promptRefresh){let t=await e.promptRefresh();t!==void 0&&e.setSystemPrompt(t)}let o=await we({text:n,internal:r,images:i,...a?{resumeLastRound:!0}:{},sessionId:e.id,agentName:e.agentName,model:e.model,tools:e.model.supportsTools===!1?[]:e.tools,params:{systemPrompt:e.systemPrompt,systemTail:e.systemTail,thinkingLevel:e.thinkingLevel,cacheRetention:e.interactive?`long`:`short`},runner:e.agent,hooks:e.hookRegistry,persistence:e.persistence,memory:e.memory,debug:e.devtools??void 0,recorder:e.recorder,clock:e.clock,isPauseRequested:e.pauseRequested,describeImages:e.describeImages});return o.cancelled?{cancelled:!0,hadToolActivity:!1}:(e.pauseRequested()&&e.publish({"run.paused":[{type:`run.paused`,sessionId:e.id}]}),e.setSystemPrompt(o.params.systemPrompt),e.setThinkingLevel(o.params.thinkingLevel),e.usageTracker.record(o.newMessagesUsageSummary,e.model),{cancelled:!1,hadToolActivity:o.newMessagesUsageSummary.hadToolActivity})}function Bt(e,t){return e>0||t?0:3}function Vt(e){let t=(e.OTTO_TODO_CONTINUE??``).toLowerCase(),n=!(t===`0`||t===`off`||t===`false`||t===`no`),r=Math.trunc(Number(e.OTTO_TODO_CONTINUE_MAX??3));return{enabled:n,max:Number.isFinite(r)&&r>=0?r:3}}var Ht=class extends c{session;workspaceDir;workspaceId;agent;disposed=!1;promptGate=!1;titleManager;runStartedThisPrompt=!1;currentPrompt;compactionPending;getCompactionTimeoutMs;_model;_modelResolution;_tools;_systemPrompt;_systemTail;_maxToolTurns;_maxToolTurnExtensions;_promptOutputTokenBudget;_promptWallClockBudgetMs;_thinkingLevel;_promptRefresh;get model(){return this._model}get modelResolution(){return this._modelResolution}get tools(){return this._tools}get systemPrompt(){return this._systemPrompt}get systemTail(){return this._systemTail}get maxToolTurns(){return this._maxToolTurns}get maxToolTurnExtensions(){return this._maxToolTurnExtensions}get promptOutputTokenBudget(){return this._promptOutputTokenBudget}get promptWallClockBudgetMs(){return this._promptWallClockBudgetMs}get thinkingLevel(){return this._thinkingLevel}get promptRefresh(){return this._promptRefresh}applyModel(e,t){this._model=e,this._modelResolution=t}async applyModelWithContextFit(e,t){let n=this._model;if(this.applyModel(e,t),n?.contextWindow===e.contextWindow||!this.memory?.reconfigure||!this.memory.ensureFitsWindow)return{compacted:!1};this.memory.reconfigure({contextWindow:e.contextWindow,maxOutput:e.maxOutputTokens});let r=this.session.buildContext(),i=await this.memory.ensureFitsWindow(r.messages,this.id);return i?.compacted&&i.summary&&i.replacement?(this.session.recordCompaction(i.summary,i.replacement),{compacted:!0,summary:i.summary,replacement:i.replacement}):{compacted:!1}}applyThinkingLevel(e){this._thinkingLevel=e}applyTools(e){this._tools=e}applySystemPrompt(e){this._systemPrompt=e}applyBudgets(e){e.maxToolTurns!==void 0&&(this._maxToolTurns=e.maxToolTurns),e.maxToolTurnExtensions!==void 0&&(this._maxToolTurnExtensions=e.maxToolTurnExtensions),e.promptOutputTokenBudget!==void 0&&(this._promptOutputTokenBudget=e.promptOutputTokenBudget),e.promptWallClockBudgetMs!==void 0&&(this._promptWallClockBudgetMs=e.promptWallClockBudgetMs)}agentName;depth;parentTaskId;transient;listable;logger;hookRegistry;devtools;memory;recorder;describeImages;nondetFlush;clock;steerSeq={value:0};persistence;inputBoundaryFlusher;setInputBoundaryFlusher(e){this.inputBoundaryFlusher=e}gates;interactive;agentUnsubs=[];sessionCostBudgetUSD;usageTracker;todoGateRunner;abortRequested=!1;pauseRequested=!1;get id(){return this.session.id}get title(){return this.session.metadata().title}get status(){return this.agent.status}get pinned(){return this.session.metadata().pinned??!1}get pinGroup(){return this.session.metadata().pinGroup}get coreAgent(){return this.agent}get steerDeps(){return{agent:this.agent,clock:this.clock,steerSeq:this.steerSeq,ensureNotDisposed:()=>this.ensureNotDisposed()}}get isExecuting(){return this.agent.status===`streaming`||this.agent.status===`tool_executing`}get isBusy(){return this.promptGate||this.isExecuting}getSessionInfo(){return{sessionId:this.id,modelId:this.model.id,modelName:this.model.name,systemPromptLength:this.systemPrompt?.length??0,tools:this.tools.map(e=>e.name)}}constructor(e,t){super(),this.session=e;let n=t.hookRegistry??a({preset:`default`});t.hookRegistry||s(n);let r=t.logger??d(`agent-session:${e.id}`,{level:`info`,destination:`stdout`});this.getCompactionTimeoutMs=t.getCompactionTimeoutMs;let i=t.promptRefresh,o=t.systemPrompt??``,c=t.tools??[],l=t.thinkingLevel??`medium`,u=t.maxToolTurns??kt.maxToolTurns,f=t.depth??0,p=t.parentTaskId,m=t.maxToolTurnExtensions??Bt(f,t.transient),h=f===0?t.promptOutputTokenBudget:void 0,g=f===0?t.promptWallClockBudgetMs:void 0,_=t.stallDetection,v=t.idleTurnDetection,y=process.env.OTTO_BUDGET_STEER_WRAPUP,b=t.budgetSteerWrapUp??(y===`1`||y===`on`?!0:y===`0`||y===`off`?!1:f===0),x=t.workspaceDir??process.cwd(),{model:S,devtools:C,agentName:ee}=t;this._model=S,this._modelResolution=t.modelResolution,this._tools=c,this._systemPrompt=o,this._systemTail=t.systemTail,this._thinkingLevel=l,this._maxToolTurns=u,this._maxToolTurnExtensions=m,this._promptOutputTokenBudget=h,this._promptWallClockBudgetMs=g,this.hookRegistry=n,this.agentName=ee??`agent`,this.depth=f,this.parentTaskId=p,this.transient=t.transient??!1,this.listable=t.listable??!0,this.interactive=t.interactive??!1,this.devtools=C,this.memory=t.memory,this.recorder=t.recorder,this.describeImages=t.describeImages,this.nondetFlush=t.nondetFlush,this.clock=t.clock,this.logger=r,this.workspaceDir=x,this.sessionCostBudgetUSD=f===0?t.sessionCostBudgetUSD:void 0,this.workspaceId=t.workspaceId,this._promptRefresh=i,this.gates=new Pt({sessionId:()=>this.id,interactive:this.interactive,logger:r,publish:e=>this.publish(e),semanticReviewer:t.semanticReviewer,hostCapabilities:t.hostCapabilities}),this.usageTracker=new Ft({sessionId:()=>this.id,sessionCostBudgetUSD:this.sessionCostBudgetUSD,logger:r,publish:e=>this.publish(e)}),this.titleManager=new ft({session:e,stream:t.stream,titleModel:t.titleModel}),this.todoGateRunner=new gt({session:e,sessionId:e.id,logger:r,todoContinuation:t.todoContinuation??Vt(process.env),depth:f,publish:e=>this.publish(e),isAbortRequested:()=>this.abortRequested,runPromptRound:(e,t)=>this.runPromptRound(e,t),withReducedThinking:async e=>{let t=this.thinkingLevel;this._thinkingLevel=`low`;try{return await e()}finally{this._thinkingLevel=t}},needsCompaction:()=>this.memory?.needsCompaction([...this.session.messages()])??!1,compactNow:async()=>{try{let e=[...this.session.messages()];return{compacted:(await this.memory?.process(e,this.id))?.compacted??!1}}catch{return{compacted:!1}}}}),this.agent=_e({stream:t.stream,logger:r,maxToolTurns:u,maxToolTurnExtensions:m,budgetSteerWrapUp:b,promptOutputTokenBudget:h,promptWallClockBudgetMs:g,stallDetection:_,idleTurnDetection:v,agentName:this.agentName,sessionId:e.id,depth:this.depth,parentTaskId:this.parentTaskId,toolHookExecutor:st({hookRegistry:n,agentName:this.agentName,sessionId:e.id}),debug:C,recorder:this.recorder,nondetFlush:this.nondetFlush,clock:this.clock,approval:(e,t,n,r,i)=>this.requestApproval(e,t,n,r,i),spill:(t,n)=>Ot.spill(e.id,t,n),wireSnapshotStore:ke,retryAccelerate:t.retryAccelerate,streamRetry:t.streamRetry,networkDisconnectRetry:t.networkDisconnectRetry,lifecycleAsyncTimeoutMs:t.lifecycleAsyncTimeoutMs}),this.agentUnsubs.push(this.agent.on(`status.change`,({to:e})=>{e===`streaming`&&(this.runStartedThisPrompt=!0)})),this.agentUnsubs.push(...yt(this.agent,this.id,e=>this.publish(e),()=>{this.budgetSteeredThisPrompt=!0})),this.agentUnsubs.push(...St({agent:this.agent,session:this.session,sessionId:this.id,modelId:()=>this.model.id,hookRegistry:n,publish:e=>this.publish(e)})),this.agentUnsubs.push(this.agent.on(`steering.injected`,({messages:e})=>{for(let t of e){let e=t.uuid;e&&this.publish({"steer.consumed":[{type:`steer.consumed`,sessionId:this.id,id:e}]})}})),this.persistence=new pt({session:this.session,sessionId:this.id,publish:e=>this.publish(e),requestInputBoundaryFlush:()=>this.inputBoundaryFlusher?.()}),this.logger.info({sessionId:this.id,model:this.model.id},`Session initialized`)}notifyCreated(){this.publish({"session.start":[{type:`session.start`,sessionId:this.id}]})}budgetSteeredThisPrompt=!1;archive(){this.ensureNotDisposed(),this.agent.archive(),this.session.setArchived(!0)}unarchive(){this.ensureNotDisposed(),this.agent.unarchive(),this.session.setArchived(!1)}pin(e){this.ensureNotDisposed(),this.session.setPinned(!0,e?.trim()||void 0)}unpin(){this.ensureNotDisposed(),this.session.setPinned(!1)}async prompt(e,t){if(this.ensureNotDisposed(),this.status===`archived`)throw Error(`Session is archived. Unarchive it first before sending messages.`);if(this.isBusy){let{streamingBehavior:n}=t??{};if(n===`followUp`)this.followUp(e);else if(n===`steer`)this.steer(e);else throw Error(`Agent is processing. Specify streamingBehavior ("steer" or "followUp") to queue the message.`);return}let n=this.executePrompt(e,t);this.currentPrompt=n;try{await n}finally{this.currentPrompt===n&&(this.currentPrompt=void 0)}}async retryLastRound(){if(this.ensureNotDisposed(),this.status===`archived`)throw Error(`Session is archived. Unarchive it first before sending messages.`);if(this.isBusy)throw Error(`Agent is processing. Cannot retry while a round is in flight.`);if(![...this.session.messages()].reverse().find(e=>e.role===`user`)){let e=Error(`No resumable user message in history`);throw e.code=`RETRY_NO_RESUMABLE_ROUND`,e}let e=this.executePrompt(``,{resumeLastRound:!0});this.currentPrompt=e;try{await e}finally{this.currentPrompt===e&&(this.currentPrompt=void 0)}}async executePrompt(e,t){this.promptGate=!0,this.budgetSteeredThisPrompt=!1,this.runStartedThisPrompt=!1,this.abortRequested=!1,this.pauseRequested=!1;let n=this.model.id,r=this.thinkingLevel;try{if(this.publish({"prompt.start":[{type:`prompt.start`,sessionId:this.id,text:e}]}),!this.session.metadata().title?.trim()){let t=P([{role:`user`,content:e}]);t&&this.session.setTitle(t,`derived`)}if(this.logger.info({sessionId:this.id},`Session prompt started`),(await this.runPromptRound(e,void 0,t?.images,t?.resumeLastRound)).cancelled){this.publish({"prompt.end":[{type:`prompt.end`,sessionId:this.id,tokenUsage:this.usageTracker.getLastTokenUsage(),model:n,thinkingLevel:r,stopReason:`interrupted`}]});return}await this.todoGateRunner.run(),this.titleManager.maybeGenerate(),this.publish({"prompt.end":[{type:`prompt.end`,sessionId:this.id,tokenUsage:this.usageTracker.getLastTokenUsage(),model:n,thinkingLevel:r,stopReason:`completed`}]}),this.logger.info({sessionId:this.id},`Session prompt finished`)}catch(e){let t=e instanceof Error?e:Error(String(e)),i=t.code===`AGENT_ABORTED`||t.name===`AbortError`||this.agent.status===`aborted`;throw this.publish({"prompt.end":[{type:`prompt.end`,sessionId:this.id,tokenUsage:this.usageTracker.getLastTokenUsage(),model:n,thinkingLevel:r,stopReason:i?`interrupted`:`error`,errorMessage:i?void 0:t.message}]}),i||(this.publish({error:[{type:`error`,sessionId:this.id,error:t}]}),this.logger.error({sessionId:this.id,err:t.message},`Session prompt failed`)),e}finally{this.promptGate=!1}}async runPromptRound(e,t,n,r){return zt(this.promptRoundHost,{text:e,internal:t,images:n,resumeLastRound:r})}get promptRoundHost(){return{id:this.id,agentName:this.agentName,agent:this.agent,model:this.model,tools:this.tools,systemPrompt:this.systemPrompt,systemTail:this.systemTail,thinkingLevel:this.thinkingLevel,interactive:this.interactive,hookRegistry:this.hookRegistry,persistence:this.persistence,memory:this.memory,devtools:this.devtools,recorder:this.recorder,clock:this.clock,describeImages:this.describeImages,pauseRequested:()=>this.pauseRequested,compactionPending:this.compactionPending,promptRefresh:this.promptRefresh,getCompactionTimeoutMs:this.getCompactionTimeoutMs,usageTracker:this.usageTracker,publish:e=>this.publish(e),setSystemPrompt:e=>{this._systemPrompt=e},setThinkingLevel:e=>{this._thinkingLevel=e},setCompactionPending:e=>{this.compactionPending=e}}}steer(e){return It(this.steerDeps,e)}removeSteer(e){return Lt(this.steerDeps,e)}followUp(e){Rt(this.steerDeps,e)}abort(){this.promptGate&&(this.abortRequested=!0),this.pauseRequested=!1;let e=this.isExecuting,t=this.promptGate&&!this.runStartedThisPrompt;!e&&!t||(this.rejectPendingGates(),this.agent.abort())}pauseRun(){return this.ensureNotDisposed(),this.isBusy?(this.pauseRequested=!0,this.publish({"run.pause_requested":[{type:`run.pause_requested`,sessionId:this.id}]}),!0):!1}cancelPauseRun(){return this.ensureNotDisposed(),!this.isBusy||!this.pauseRequested?!1:(this.pauseRequested=!1,this.publish({"run.pause_cancelled":[{type:`run.pause_cancelled`,sessionId:this.id}]}),!0)}resumeRun(){this.ensureNotDisposed(),this.pauseRequested&&(this.pauseRequested=!1,this.publish({"run.resumed":[{type:`run.resumed`,sessionId:this.id}]}))}get isPaused(){return this.pauseRequested}async compact(e,t){this.ensureNotDisposed(),await _t(this.compactionDeps(),e,t)}async compactNow(e){return this.ensureNotDisposed(),vt({...this.compactionDeps(),memory:this.memory,persistence:this.persistence},e)}compactionDeps(){return{session:this.session,sessionId:this.id,hookRegistry:this.hookRegistry,logger:this.logger,publish:e=>this.publish(e)}}async clearContext(){this.ensureNotDisposed(),this.isBusy&&(this.abort(),await this.currentPrompt?.catch(()=>{}));let e=this.session.messages().length;this.session.clearContext(),this.memory?.clearSession?.(this.id),this.logger.info({sessionId:this.id,clearedCount:e},`Session context cleared (/clear)`),this.publish({"session.cleared":[{type:`session.cleared`,sessionId:this.id,clearedCount:e}]})}clearTurnPanels(){this.session.setTodoList([]),this.session.setEditedFiles([]),this.session.setSubagents([]),this.session.setTurnSummaries([])}renameSession(e){this.session.setTitle(e,`custom`)}getCostSummary(){return this.usageTracker.getCostSummary()}getLastInputTokens(){return this.usageTracker.getLastTokenUsage()?.input}getLastTotalInputTokens(){return this.usageTracker.getLastTotalInputTokens()}getLastCacheHitRatio(){return this.usageTracker.getLastCacheHitRatio()}subscribe(e,t,n){if(typeof e==`function`)return this.subscribeAll((t,n)=>{e(n)});if(!t)throw Error(`callback is required when subscribing by type`);return super.subscribe(e,t,n)}async requestApproval(e,t,n,r,i){return this.gates.requestApproval(e,t,n,r,i)}resolveApproval(e,t){this.gates.resolveApproval(e,t)}async requestGrill(e){return this.gates.requestGrill(e)}resolveAskUser(e,t){this.gates.resolveAskUser(e,t)}async requestPlanApproval(e){return this.gates.requestPlanApproval(e)}resolvePlanApproval(e,t,n){this.gates.resolvePlanApproval(e,t,n)}rejectPendingGates(){this.gates.rejectAll(Error(`Session aborted`))}ensureNotDisposed(){if(this.disposed)throw Error(`AgentSession ${this.id} has been disposed`)}backfillTitle(){this.titleManager.backfill()}dispose(){if(!this.disposed){this.disposed=!0,this.titleManager.dispose(),this.rejectPendingGates(),ke.delete(this.id);for(let e of this.agentUnsubs)e();this.agentUnsubs.length=0,this.pauseRequested&&this.agent.status===`completed`||this.agent.abort(),this.memory?.forgetSession?.(this.id),this.publish({"session.end":[{type:`session.end`,sessionId:this.id}]}),this.removeAllListeners(),this.logger.info({sessionId:this.id},`Session disposed`)}}};function Ut(e,t,n,r,i,a,o){let s=a?.now()??Date.now(),c=new E(e,t,n.length,{clock:a,idGen:o});return c.restoreEntries([...n],{...r,createdAt:s,lastActiveAt:s,parentSessionId:t,forkPoint:n.length,tags:[...r.tags,`fork`]},i),c}function Wt(e,t){let n=m(e),r=m(n,t);if(!r.startsWith(n+h)&&r!==n)throw Error(`路径穿越拒绝:路径 "${t}" 不在工作目录 "${e}" 内`);return r}function Gt(e){return typeof e==`object`&&!!e&&`code`in e&&e.code===`ENOENT`}async function Kt(e,t){let n=[];for(let r of t){let t=Wt(e,r);try{n.push({path:r,content:await je(t,`utf-8`)})}catch(e){if(Gt(e))n.push({path:r,content:null});else throw e}}return{files:n}}async function qt(e,t){for(let n of t.files){let t=Wt(e,n.path);n.content===null?await Ne(t,{force:!0}):(await Ae(f(t),{recursive:!0}),await Ie(t,n.content,`utf-8`))}}function Jt(e){return typeof e==`object`&&!!e&&`type`in e}function Yt(e){return typeof e==`object`&&!!e&&`id`in e&&`name`in e&&(`result`in e||`resultSummary`in e)}function Xt(e){return e.contentPreview?.map(e=>({type:`text`,text:e.text??e.preview??``}))??[]}function Zt(e){let t=new Map;for(let n of e.entries)t.set(n.id,n);let n=[],r=e.leafId?t.get(e.leafId):void 0;for(;r;)n.push(r),r=r.parentId?t.get(r.parentId):void 0;return n.reverse(),n.filter(e=>e.type===`message`).map(e=>e.message)}function Qt(e){return e.result?e.result.content:e.resultSummary?Xt(e.resultSummary):[]}function $t(e){if(typeof e==`object`&&e&&`text`in e){let t=e.text;return typeof t==`string`?t:void 0}}function en(e,t){let n=[...e];for(let e of t)if(e.kind===`lifecycle`&&e.node===`prompt.before`){let t=$t(e.payload);t!==void 0&&n.push({role:`user`,content:[{type:`text`,text:t}],timestamp:e.ts})}else if(e.kind===`stream`&&e.node===`stream.event`)Jt(e.payload)&&e.payload.type===`done`&&n.push(e.payload.message);else if(e.kind===`tool`&&e.node===`tool.call.end`&&Yt(e.payload)){let{id:t,name:r,result:i,resultSummary:a}=e.payload,o=i?.isError??a?.isError??!1,s=i?.details??a?.details??{};n.push({role:`tool_result`,toolCallId:t,toolName:r,content:Qt(e.payload),isError:o,details:s,timestamp:e.ts})}return n}function tn(e){return e.result?e.result:e.resultSummary?{content:Xt(e.resultSummary),isError:e.resultSummary.isError,details:e.resultSummary.details}:{content:[],isError:!0,details:{error:`unable to extract result from trace payload`}}}function nn(e){let t=[],n=[];for(let r of e)r.kind===`stream`&&r.node===`stream.event`&&Jt(r.payload)&&(n.push(r.payload),r.payload.type===`done`&&(t.push(n),n=[]));return n.length>0&&t.push(n),t}function rn(e){let t=nn(e),r=0;return()=>{let e=t[r]??[];r++;let i=n(),a;for(let t of e)i.push(t),t.type===`done`?a=t.message:`partial`in t&&(a=t.partial);return a?i.complete(a):i.fail(Error(`replay stream: no recorded LLM events for this turn`)),i}}function an(e){let t=new Map;for(let n of e)n.kind===`tool`&&n.node===`tool.call.end`&&Yt(n.payload)&&t.set(n.payload.id,tn(n.payload));return t}function on(e,t){return e.map(e=>({...e,execute:async e=>t.get(e.id)||{content:[{type:`text`,text:`replay: no recorded result for tool call ${e.id}`}],isError:!0}}))}var sn=class extends Error{constructor(){super(`L2 deterministic re-execution requires a SandboxRunner (x-web-container runtime), which is not yet available. Use replay level "L1" (record/replay of tool results) for now.`),this.name=`SandboxUnavailableError`}},cn=class{constructor(e){this.deps=e}replayPorts(e,t){let n=[...e];return{clock:ye(xe(n)).clock,stream:rn(n),tools:on(t,an(n)),disableMemory:!0}}async replaySession(e,t,n={}){if(!this.deps.traceStore)throw Error(`replaySession requires a traceStore (record mode must be enabled)`);if((n.level??`L1`)===`L2`&&!n.sandbox)throw new sn;let r=this.deps.getConfig(e);if(!r)throw Error(`Cannot replay unknown session "${e}" (no resolved config)`);let i=[];for await(let t of this.deps.traceStore.read(e))i.push(t.entry);return this.deps.createSession({...r,id:t},this.replayPorts(i,r.tools))}async createCheckpoint(e,t={}){if(!this.deps.checkpointStore)throw Error(`createCheckpoint requires a checkpointStore`);let n=this.deps.getSession(e);if(!n)throw Error(`Cannot checkpoint unknown session "${e}"`);let r=n.session;if(!(r instanceof E))throw Error(`Session "${e}" does not support snapshots`);if(n.isBusy)throw Error(`Cannot checkpoint session "${e}" while a prompt is in flight (session busy); checkpoint requires a quiescent session for a consistent {conversation, traceSeq}`);let i=r.toSnapshot(),a=await this.ensureHydrated(e,i.entries,`checkpoint capture`),o=await this.countTraceEvents(e),s={sessionId:e,label:t.label,createdAt:Date.now(),traceSeq:o,conversation:{version:D,id:e,entries:a,metadata:i.metadata,leafId:i.leafId},files:t.files?await Kt(n.workspaceDir,t.files):void 0},c=await this.deps.checkpointStore.append(e,s);return{...c.entry,seq:c.seq}}async listCheckpoints(e){if(!this.deps.checkpointStore)return[];let t=[];for await(let n of this.deps.checkpointStore.read(e))t.push({...n.entry,seq:n.seq});return t}async restoreCheckpoint(e,t,n=`both`){if(!this.deps.checkpointStore)throw Error(`restoreCheckpoint requires a checkpointStore`);let r=this.deps.getSession(e);if(!r)throw Error(`Cannot restore unknown session "${e}"`);if(r.isBusy)throw Error(`Cannot restore/rollback session "${e}" while a prompt is in flight (session busy); abort the active prompt before rewinding`);let i=await this.readCheckpoint(e,t);if(n===`conversation`||n===`both`){let t=r.session;if(t instanceof E){let n=await this.ensureHydrated(e,i.conversation.entries,`checkpoint restore`);t.restoreEntries(n,i.conversation.metadata,i.conversation.leafId)}}(n===`code`||n===`both`)&&i.files&&await qt(r.workspaceDir,i.files)}async ensureHydrated(e,t,n){if(!ce(t))return[...t];if(!this.deps.hydrateEntries)throw Error(`${n}: entries contain stripped compaction replacements but no hydrateEntries capability is wired (RFC-160 D4); refusing to proceed with stripped state`);return this.deps.hydrateEntries(e,t)}async readCheckpoint(e,t){if(!this.deps.checkpointStore)throw Error(`checkpoint operations require a checkpointStore`);let n;for await(let r of this.deps.checkpointStore.read(e,{from:t,to:t+1}))n=r.entry;if(!n)throw Error(`Checkpoint seq=${t} not found for session "${e}"`);if(n.conversation.version!==D)throw Error(`Checkpoint seq=${t} for session "${e}" has incompatible snapshot version ${n.conversation.version} (expected ${D})`);return n}async rollbackToCheckpoint(e,t,n=`both`){let r=await this.readCheckpoint(e,t);await this.restoreCheckpoint(e,t,n),this.deps.traceStore&&await this.deps.traceStore.truncate(e,r.traceSeq),this.deps.logger.info({sessionId:e,seq:t,traceSeq:r.traceSeq,mode:n},`Session rolled back`)}async forkFromCheckpoint(e,t,n){let r=this.deps.getSession(e),i=this.deps.getConfig(e);if(!r||!i)throw Error(`Cannot fork unknown session "${e}"`);let a=await this.readCheckpoint(e,t),o=n??crypto.randomUUID();if(this.deps.ensureCapacity(o),this.deps.traceStore)for await(let t of this.deps.traceStore.read(e,{to:a.traceSeq}))await this.deps.traceStore.append(o,t.entry);if(this.deps.checkpointStore)for await(let t of this.deps.checkpointStore.read(e))t.entry.traceSeq<=a.traceSeq&&await this.deps.checkpointStore.append(o,{...t.entry,sessionId:o});let s=Ut(o,e,await this.ensureHydrated(e,a.conversation.entries,`forkFromCheckpoint`),a.conversation.metadata,a.conversation.leafId),c=await this.deps.adoptForkedSession(s,{...i});return this.deps.logger.info({sessionId:o,sourceId:e,fromSeq:t},`Session forked from checkpoint`),c}async countTraceEvents(e){if(!this.deps.traceStore)return 0;let t=await this.deps.traceStore.count?.(e);if(t!==void 0)return t;let n=0;for await(let t of this.deps.traceStore.read(e))n++;return n}async replayTrace(e,t,n=0){if(!this.deps.traceStore)return[];let r={from:n,to:t===void 0?void 0:t+1},i=[];for await(let t of this.deps.traceStore.read(e,r))i.push(t.entry);return i}async traceback(e,t){let n=(await this.listCheckpoints(e)).filter(e=>e.traceSeq<=t).reduce((e,t)=>e===void 0||t.traceSeq>e.traceSeq?t:e,void 0),r=n?.traceSeq??0,i=n?Zt(n.conversation):[],a=await this.replayTrace(e,t,r);return{toSeq:t,baselineCheckpointSeq:n?.seq??null,fromTraceSeq:r,events:a,messages:en(i,a)}}};const L={healthy:1,warning:2,critical:4};var ln=class{level=`healthy`;setLevel(e){this.level=e}get currentLevel(){return this.level}effectiveMaxMessages(e){return Math.max(1,Math.floor(e/L[this.level]))}effectiveMaxBytes(e){return Math.max(1,Math.floor(e/L[this.level]))}};const un=2e3;var dn=class{gaps=new Map;constructor(e){this.deps=e}async detect(e,t){let n=this.deps.traceStore;if(!n)return;let r=t.entries[t.entries.length-1]?.timestamp??0;if(r!==0)try{let t=await n.count?.(e.id)??void 0,i=t!==void 0&&t>un?{from:t-un}:void 0,a=0,o=0;for await(let t of n.read(e.id,i)){let e=t.entry;e.kind!==`lifecycle`||e.node!==`turn.end`||e.ts>r+1e4&&(o++,e.ts>a&&(a=e.ts))}if(o===0)return;this.deps.logger.warn({sessionId:e.id,lostTurns:o,lastPersistedAt:r,lastTraceAt:a},`RFC-305 D3: crash gap detected — turns recorded in trace but never persisted to DB (lost in previous abnormal termination)`);let s={lostTurns:o,lastPersistedAt:r,lastTraceAt:a};this.gaps.set(e.id,s),this.deps.onDetected?.(e,s)}catch(t){this.deps.logger.debug?.({sessionId:e.id,err:t instanceof Error?t.message:String(t)},`RFC-305 D3: crash-gap reconciliation skipped (trace read failed)`)}}consume(e){let t=this.gaps.get(e);return this.gaps.delete(e),t}forget(e){this.gaps.delete(e)}};function fn(e,t){return t<=0?1:Math.min(1,e/t)}function R(e){let t=e.config?.totalBytes??Ve,n=e.config?.minPerSessionBytes??Be,r=e.config?.maxPerSessionBytes??ze,i=fn(e.currentTotalResidentBytes,t),a=Math.max(1,e.activeSessionCount),o=Math.floor(t*(1-i)/a),s=Math.max(n,Math.min(o,r)),c=Math.max(Math.floor(n/e.pressureDivisor),Math.floor(s/e.pressureDivisor));return{maxBytesPerSession:Math.max(1,c),globalPressure:Number(i.toFixed(4)),isGlobalPressure:i>=.85}}function pn(e,t,n){return n?e.wouldByteTrimTouchActiveContext(Math.max(1,t)):e.wouldTrimTouchActiveContext(Math.max(1,t))}const mn=.9;function hn(e){let t=e.agentSession.session,n=R({activeSessionCount:e.activeSessionCount,currentTotalResidentBytes:e.currentTotalResidentBytes,pressureDivisor:e.pressureDivisor,config:e.residencyConfig}),r=t instanceof E?t.messageCount:0,i=Math.max(1,Math.floor(e.maxMessages*mn)),a=Math.max(1,Math.floor(n.maxBytesPerSession*mn));if(!(t instanceof E))return{action:`none`,maxBytes:n.maxBytesPerSession,isLossy:!1,boundaryLimited:!1,activeOversized:!1};let o=r>e.maxMessages&&pn(t,i,!1),s=t.estimatedContentBytes>n.maxBytesPerSession&&pn(t,a,!0),c=o||s,l=(e.lossyFailureCount??0)>=3;if(c&&!l)return{action:`request-compaction`,maxBytes:n.maxBytesPerSession,isLossy:!1,boundaryLimited:!1,activeOversized:!1};if(!c){let i=t.estimatedContentBytes>n.maxBytesPerSession,a=r>e.maxMessages;if(!i&&!a)return{action:`none`,maxBytes:n.maxBytesPerSession,isLossy:!1,boundaryLimited:!1,activeOversized:!1}}return{action:`trim`,maxBytes:n.maxBytesPerSession,isLossy:l&&c,boundaryLimited:!1,activeOversized:!1}}const z=.9;var gn=class{evalBaseline=new Map;publishBaseline=new Map;compactionFailures=new Map;compactionRequestBaseline=new Map;constructor(e){this.deps=e}evaluate(e){let t={action:`none`,removedCount:0,lossy:!1,shouldPublish:!1,trigger:`count`,capValue:0},n=e.session;if(!(n instanceof E))return t;let r=e.id,i=this.deps.residencyGovernor,a=i?i.effectiveMaxMessages(this.deps.maxHistoryMessages):this.deps.maxHistoryMessages,o=hn({agentSession:e,activeSessionCount:this.deps.countActiveSessions(),currentTotalResidentBytes:this.deps.sumEstimatedContentBytes(),pressureDivisor:i?this.deps.levelDivisor[i.currentLevel]:1,residencyConfig:this.deps.getResidencyConfig?.(),maxMessages:a,lossyFailureCount:this.compactionFailures.get(r)}),s=o.maxBytes,c=e=>e.role!==`tool_result`,l=n.messageCount;if(o.action===`request-compaction`)return this.deps.requestCompaction(e,l),this.deps.logger.debug({sessionId:r,msgCount:l},`[cap] trim would touch active context; requested compaction first, skipping trim this round (RFC-321 R12)`),this.evalBaseline.set(r,l),{...t,action:`request-compaction`};if(o.action===`none`)return this.evalBaseline.set(r,l),t;let u=o.isLossy,d=(this.compactionFailures.get(r)??0)>=3,f=Math.max(1,Math.floor(a*z)),p=Math.max(1,Math.floor(s*z)),m=l>a?n.capStoredHistory(f,c):{capped:!1,removedCount:0,boundaryLimited:!1,activeOversized:!1},h=n.estimatedContentBytes>s?n.capStoredHistoryByBytes(p,c):{capped:!1,removedCount:0,boundaryLimited:!1,activeOversized:!1},g=m.removedCount+h.removedCount,_=u&&g>0;u&&this.compactionFailures.delete(r),(m.boundaryLimited||h.boundaryLimited)&&this.deps.logger.debug({sessionId:r,removedCount:g,msgCount:l,activeOversized:m.activeOversized||h.activeOversized},`[cap] trimming stopped at active compaction boundary (RFC-321 R4); may remain above cap`),(m.activeOversized||h.activeOversized)&&!d&&(this.deps.requestCompaction(e,l),this.deps.logger.debug({sessionId:r,msgCount:l,bytes:n.estimatedContentBytes},`[cap] active region itself exceeds cap (RFC-321 activeOversized); compaction needed`));let v=this.publishBaseline.get(r),y=Math.max(1,Math.floor(a*(1-z))),b=!_&&v!==void 0&&l<v+y,x=g>0&&!b,S=i&&i.currentLevel!==`healthy`?`memory-pressure`:h.removedCount>m.removedCount?`bytes`:`count`;return x&&this.publishBaseline.set(r,l),this.evalBaseline.set(r,l-g),{action:`trim`,removedCount:g,lossy:_,shouldPublish:x,trigger:S,capValue:S===`bytes`?s:a}}shouldEvaluateInline(e){let t=e.session;if(!(t instanceof E))return!1;let n=t.messageCount,r=this.evalBaseline.get(e.id);return r===void 0?(this.evalBaseline.set(e.id,n),!1):n-r>=this.deps.inlineCheckInterval}shouldRequestCompaction(e,t){let n=this.compactionRequestBaseline.get(e);return n!==void 0&&t<n+this.deps.inlineCheckInterval?!1:(this.compactionRequestBaseline.set(e,t),!0)}onCompactionSucceeded(e){this.compactionFailures.delete(e)}onCompactionFailed(e){let t=(this.compactionFailures.get(e)??0)+1;return this.compactionFailures.set(e,t),t}forget(e){this.evalBaseline.delete(e),this.publishBaseline.delete(e),this.compactionFailures.delete(e),this.compactionRequestBaseline.delete(e)}};const B={touch:!1};function V(e,t){if(e===t)return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`||typeof t!=`object`||Array.isArray(e)!==Array.isArray(t))return!1;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length?e.every((e,n)=>V(e,t[n])):!1;let n=e,r=t,i=Object.keys(n),a=Object.keys(r);return i.length===a.length?i.every(e=>Object.hasOwn(r,e)&&V(n[e],r[e])):!1}function H(e,t){return e===void 0&&t===void 0?!0:e===void 0||t===void 0||e.length!==t.length?!1:V(e,t)}var _n=class{constructor(e){this.deps=e}async restore(e,t,n){let r=this.deps.panelStateStore;if(!r)return;let i=await r.loadAll(n);if(i){i.todoList!==void 0&&e.setTodoList(i.todoList,B),i.editedFiles!==void 0&&e.setEditedFiles(i.editedFiles,B),i.subagents!==void 0&&e.setSubagents(i.subagents,B),i.drafts!==void 0&&e.setDrafts(i.drafts,B),i.turnSummaries!==void 0&&e.setTurnSummaries(i.turnSummaries,B);return}let a=t.metadata.config,o=a?.todoList,s=a?.editedFiles,c=a?.subagents,l=a?.drafts;!o&&!s&&!c&&!l||(o&&e.setTodoList(o,B),s&&e.setEditedFiles(s,B),c&&e.setSubagents(c,B),l&&e.setDrafts(l,B),H(o,e.getTodoList())&&H(s,e.getEditedFiles())&&H(c,e.getSubagents())&&H(l,e.getDrafts())?await r.saveAll(n,{sessionId:n,todoList:o??[],editedFiles:s??[],subagents:c??[],drafts:l??[]}):this.deps.logger.warn({sessionId:n},`PanelState migration verification failed, using legacy in-memory data without persisting`))}},U=class{constructor(e,t){this.persistence=e,this.pasteStatePersistence=t}async getTodoList(e){return(await this.persistence.load(e))?.todoList}async setTodoList(e,t){let n=await this.loadOrInit(e);n.todoList=t,await this.persistence.save(n)}async getEditedFiles(e){return(await this.persistence.load(e))?.editedFiles}async setEditedFiles(e,t){let n=await this.loadOrInit(e);n.editedFiles=t,await this.persistence.save(n)}async getSubagents(e){return(await this.persistence.load(e))?.subagents}async setSubagents(e,t){let n=await this.loadOrInit(e);n.subagents=t,await this.persistence.save(n)}async getDrafts(e){return(await this.persistence.load(e))?.drafts}async setDrafts(e,t){let n=await this.loadOrInit(e);n.drafts=t,await this.persistence.save(n)}async getTurnSummaries(e){return(await this.persistence.load(e))?.turnSummaries}async setTurnSummaries(e,t){let n=await this.loadOrInit(e);n.turnSummaries=t,await this.persistence.save(n)}async getPaste(e){if(!this.pasteStatePersistence)return{sessionId:e,entries:[],nextId:1};try{return ee(e,await this.pasteStatePersistence.load(e))}catch{return{sessionId:e,entries:[],nextId:1}}}async setPaste(e,t){if(!this.pasteStatePersistence)return!1;if(t.sessionId!==e)throw Error(`PanelStateStore.setPaste: snapshot.sessionId (${t.sessionId}) !== sessionId (${e})`);try{return await this.pasteStatePersistence.save(t),!0}catch{return!1}}async deletePaste(e){if(!this.pasteStatePersistence)return!1;try{return await this.pasteStatePersistence.delete(e)}catch{return!1}}async loadAll(e){let t=await this.persistence.load(e);return t==null||t.ver!==x?null:t}async saveAll(e,t){if(t.sessionId!==e)throw Error(`PanelStateStore.saveAll: snapshot.sessionId (${t.sessionId}) !== sessionId (${e})`);await this.persistence.save({...t,ver:x})}async loadOrInit(e){return await this.persistence.load(e)??{sessionId:e}}};function vn(e){let t={};return e.interactive!==void 0&&(t.interactive=e.interactive),e.listable!==void 0&&(t.listable=e.listable),e.depth!==void 0&&(t.depth=e.depth),e.agentName!==void 0&&(t.agentName=e.agentName),e.thinkingLevel!==void 0&&(t.thinkingLevel=e.thinkingLevel),e.maxToolTurnExtensions!==void 0&&(t.maxToolTurnExtensions=e.maxToolTurnExtensions),e.transient!==void 0&&(t.transient=e.transient),e.model?.id&&(t.modelId=e.model.id),e.systemTail!==void 0&&(t.systemTail=e.systemTail),e.workspaceDir!==void 0&&(t.workspaceDir=e.workspaceDir),e.maxToolTurns!==void 0&&(t.maxToolTurns=e.maxToolTurns),e.permissionAlwaysAllow&&e.permissionAlwaysAllow.length>0&&(t.permissionAlwaysAllow=[...e.permissionAlwaysAllow]),e.availableModels&&e.availableModels.length>0&&(t.availableModels=[...e.availableModels]),t}function yn(e,t){if(!t)return e;let n={...e};return t.interactive!==void 0&&(n.interactive=t.interactive),t.listable!==void 0&&(n.listable=t.listable),t.depth!==void 0&&(n.depth=t.depth),t.agentName!==void 0&&(n.agentName=t.agentName),t.thinkingLevel!==void 0&&(n.thinkingLevel=t.thinkingLevel),t.maxToolTurnExtensions!==void 0&&(n.maxToolTurnExtensions=t.maxToolTurnExtensions),t.transient!==void 0&&(n.transient=t.transient),t.systemTail!==void 0&&(n.systemTail=t.systemTail),t.workspaceDir!==void 0&&(n.workspaceDir=t.workspaceDir),t.maxToolTurns!==void 0&&(n.maxToolTurns=t.maxToolTurns),t.permissionAlwaysAllow!==void 0&&(n.permissionAlwaysAllow=[...t.permissionAlwaysAllow]),t.availableModels!==void 0&&(n.availableModels=[...t.availableModels]),n}var bn=class{saveChains=new Map;crashGapDetector;panelStateRestorer;turnSaveState=new Map;leaseDeniedState=new Map;remoteRevisions=new Map;residencyCoordinator;constructor(e){this.deps=e,this.residencyCoordinator=new gn({logger:e.logger,...e.residencyGovernor?{residencyGovernor:e.residencyGovernor}:{},...e.getResidencyConfig?{getResidencyConfig:e.getResidencyConfig}:{},countActiveSessions:()=>this.countActiveSessionsForAllocation(),sumEstimatedContentBytes:()=>this.sumEstimatedContentBytes(),requestCompaction:(e,t)=>this.requestEscapeValveCompaction(e,t),maxHistoryMessages:k(this.deps.getResidencyConfig?.()).maxHistoryMessages,inlineCheckInterval:200,levelDivisor:L}),this.panelStateRestorer=new _n({...e.panelStateStore?{panelStateStore:e.panelStateStore}:{},logger:e.logger}),this.crashGapDetector=new dn({traceStore:e.traceStore,logger:e.logger,onDetected:(e,t)=>{e.publish({"session.crash-gap-detected":[{type:`session.crash-gap-detected`,sessionId:e.id,lostTurns:t.lostTurns,lastPersistedAt:t.lastPersistedAt,lastTraceAt:t.lastTraceAt}]})}})}applyResidencyCaps(e){let t=this.residencyCoordinator.evaluate(e);t.shouldPublish&&e.publish({"session.history-capped":[{type:`session.history-capped`,sessionId:e.id,removedCount:t.removedCount,trigger:t.trigger,capValue:t.capValue,...t.lossy?{lossy:!0}:{}}]})}requestEscapeValveCompaction(e,t){this.residencyCoordinator.shouldRequestCompaction(e.id,t)&&(e.compactionPending=e.compactNow().then(t=>(t.compacted?this.residencyCoordinator.onCompactionSucceeded(e.id):this.residencyCoordinator.onCompactionFailed(e.id),this.deps.logger.info({sessionId:e.id,compacted:t.compacted,before:t.before,after:t.after},`[cap] escape-valve compaction requested (RFC-321 R12 compaction-first)`),t)).catch(t=>{let n=this.residencyCoordinator.onCompactionFailed(e.id);return this.deps.logger.warn({sessionId:e.id,error:t,failures:n},`[cap] escape-valve compaction failed; lossy trim allowed after threshold`),{compacted:!1,before:0,after:0}}))}maybeInlineCapEval(e){this.residencyCoordinator.shouldEvaluateInline(e)&&this.applyResidencyCaps(e)}track(e,t){if(!this.deps.autoPersist||t)return;let n=this.deps.persistence,r=e.session;r instanceof E&&typeof n.getPersistedCursor==`function`&&r.setReplacementStripEligibility(t=>{let i=n.getPersistedCursor(e.id);if(!i)return this.deps.logger.debug?.({sessionId:e.id,entryId:t},`RFC-160 D2a: skip runtime replacement strip (no persisted cursor yet)`),!1;let a=!1;for(let n of r.entries())if(n.id===t&&(a=!0),n.id===i)return a||this.deps.logger.debug?.({sessionId:e.id,entryId:t,cursor:i},`RFC-160 D2a: skip runtime replacement strip (entry beyond persisted cursor)`),a;return!1});let i=t=>{if(t instanceof Error&&t.name===`SessionWriteLeaseDeniedError`){let t=this.leaseDeniedState.get(e.id)===!0;return this.leaseDeniedState.set(e.id,!0),t||e.publish({"session.write-lease-denied":[{type:`session.write-lease-denied`,sessionId:e.id}]}),!0}return!1},a=()=>{this.leaseDeniedState.get(e.id)===!0&&(this.leaseDeniedState.set(e.id,!1),e.publish({"session.write-lease-restored":[{type:`session.write-lease-restored`,sessionId:e.id}]}))},o=()=>{this.enqueue(e.id,async()=>{try{await this.doSave(e.id),a()}catch(t){i(t)||this.deps.logger.warn({sessionId:e.id,err:t instanceof Error?t.message:String(t)},`Session auto-persist failed`)}})},s=()=>{let t=e.id;this.enqueue(t,async()=>{try{await this.doSaveEntries(t),a()}catch(e){i(e)||this.deps.logger.warn({sessionId:t,err:e instanceof Error?e.message:String(e)},`Session turn-level auto-persist failed`)}})};e.subscribe(`prompt.end`,o),e.subscribe(`error`,o),e.subscribe(`session.cleared`,()=>{this.enqueue(e.id,async()=>{try{await this.doSave(e.id),a();let t=e.session;if(t instanceof E){let n=t.purgeClearedHistory();(n.removedCount>0||n.strippedReplacements>0)&&this.deps.logger.debug?.({sessionId:e.id,...n},`RFC-194: purged cleared history after successful save`)}}catch(t){i(t)||this.deps.logger.warn({sessionId:e.id,err:t instanceof Error?t.message:String(t)},`Session clear-persist failed (purge skipped, residency left to RFC-178 caps)`)}})}),e.subscribe(`turn.end`,()=>{let t=e.id;if(this.maybeInlineCapEval(e),(this.deps.turnFlush??`incremental`)===`snapshot`){let e=Date.now(),n=this.turnSaveState.get(t);if(!n){this.turnSaveState.set(t,{lastSaveAt:e,turnsSinceSave:1});return}n.turnsSinceSave++;let r=e-n.lastSaveAt;if(n.turnsSinceSave<5&&r<3e4)return;n.lastSaveAt=e,n.turnsSinceSave=0}s()}),e.setInputBoundaryFlusher?e.setInputBoundaryFlusher(()=>this.requestInputBoundaryFlush(e,t)):this.deps.logger.debug?.({sessionId:e.id},`RFC-336 D2: input-boundary flush disabled (session lacks setInputBoundaryFlusher)`)}async flushPending(e){let t=this.saveChains.get(e);t&&await t.catch(t=>{this.deps.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`flushPending: pending save chain settled with failure (already logged by the job itself; surfaced here for removeSession/restore callers)`)}),this.leaseDeniedState.delete(e),this.turnSaveState.delete(e),this.remoteRevisions.delete(e)}countActiveSessionsForAllocation(){let e=this.deps.listSessionIds(),t=0;for(let n of e)this.deps.getConfig?.(n)?.transient!==!0&&t++;return Math.max(1,t)}sumEstimatedContentBytes(){let e=0;for(let t of this.deps.listSessionIds()){if(this.deps.getConfig?.(t)?.transient===!0)continue;let n=this.deps.getSession(t);n?.session instanceof E&&(e+=n.session.estimatedContentBytes)}return e}forgetSession(e){this.leaseDeniedState.delete(e),this.residencyCoordinator.forget(e),this.crashGapDetector.forget(e),this.turnSaveState.delete(e),this.remoteRevisions.delete(e)}forgetEvictedSession(e){this.deps.getSession(e)||this.forgetSession(e)}isTransient(e){return this.deps.getConfig?.(e)?.transient===!0}async save(e){return this.enqueue(e,()=>this.doSave(e))}requestInputBoundaryFlush(e,t){if(!this.deps.autoPersist||t||(this.deps.turnFlush??`incremental`)===`snapshot`)return;let n=e.id;this.enqueue(n,async()=>{try{await this.doSaveEntries(n)}catch(e){if(e instanceof Error&&e.name===`SessionWriteLeaseDeniedError`)return;this.deps.logger.warn({sessionId:n,err:e instanceof Error?e.message:String(e)},`Input-boundary flush failed (RFC-336 D2; falls back to turn/prompt-end persistence)`)}})}precreateSessionRow(e,t){if(!this.deps.autoPersist||t)return;let n=e.id;this.enqueue(n,async()=>{try{await this.doSaveEntries(n)}catch(e){if(e instanceof Error&&e.name===`SessionWriteLeaseDeniedError`)return;this.deps.logger.warn({sessionId:n,err:e instanceof Error?e.message:String(e)},`Session row pre-creation failed (RFC-336 D1; falls back to first-turn persistence)`)}})}saveSnapshot(e,t,n){if(this.isTransient(e))return n?.(),Promise.resolve();let r=this.mergeSnapshotConfig(e,t.metadata),i=this.enqueue(e,async()=>{let n={version:D,id:e,...t,metadata:r};if(this.isRemoteCasPersistence()?await this.saveRemoteWithCas(e,n):await this.deps.persistence.save(n),this.deps.panelStateStore){let t=this.deps.getSession(e)?.session;t&&await this.deps.panelStateStore.saveAll(e,{sessionId:e,todoList:t.getTodoList(),editedFiles:t.getEditedFiles(),subagents:t.getSubagents(),drafts:t.getDrafts(),turnSummaries:t.getTurnSummaries()})}});return n&&i.then(n,n),i}mergeSnapshotConfig(e,t){let n=this.deps.getConfig?.(e),r=n?vn(n):void 0,i=t.config?.inputHistory,a=r||i?{...r,...i?{inputHistory:i}:{}}:void 0;return a?{...t,config:a}:t}enqueue(e,t){let n=(this.saveChains.get(e)??Promise.resolve()).catch(()=>{}).then(t);this.saveChains.set(e,n);let r=()=>{this.saveChains.get(e)===n&&this.saveChains.delete(e)};return n.then(r,r),n}async doSaveEntries(e){if(this.isTransient(e))return;let t=this.deps.getSession(e);if(!t)return;let n=t.session;if(n instanceof E){this.applyResidencyCaps(t);let r=n.toSnapshot(),i=this.mergeSnapshotConfig(n.id,r.metadata),a={version:D,id:n.id,...r,metadata:i};this.isRemoteCasPersistence()?await this.saveRemoteWithCas(e,a):await this.deps.persistence.save(a)}}isRemoteCasPersistence(){return typeof this.deps.persistence.saveWithRevision==`function`}async saveRemoteWithCas(e,t){let n=this.deps.persistence,r=this.remoteRevisions.get(e);try{let i=await n.saveWithRevision(t,r);this.remoteRevisions.set(e,i)}catch(i){if(!(i instanceof ae))throw i;this.deps.logger.warn({sessionId:e,expectedRevision:r,serverRevision:i.info.revision},`Remote session CAS conflict; reloading + rebasing for one retry`);let a=await n.loadWithRevision(e);if(!a){let r=await n.saveWithRevision(t,0);this.remoteRevisions.set(e,r);return}let o=this.rebaseSnapshotAgainstRemote(t,a.snapshot),s=await n.saveWithRevision(o,a.revision);this.remoteRevisions.set(e,s)}}rebaseSnapshotAgainstRemote(e,t){let n=new Set(t.entries.map(e=>e.id)),r=e.entries.filter(e=>!n.has(e.id));return{version:D,id:e.id,entries:[...t.entries,...r],metadata:e.metadata,leafId:e.leafId??t.leafId}}async doSave(e){if(await this.doSaveEntries(e),this.isTransient(e))return;let t=this.deps.getSession(e);if(!t)return;let n=t.session;this.deps.panelStateStore&&await this.deps.panelStateStore.saveAll(e,{sessionId:e,todoList:n.getTodoList(),editedFiles:n.getEditedFiles(),subagents:n.getSubagents(),drafts:n.getDrafts(),turnSummaries:n.getTurnSummaries()})}async saveAll(){let e=[...this.deps.listSessionIds()].filter(e=>{let t=this.deps.getSession(e)?.session;return!(t instanceof E)||t.entries().length>0});(await Promise.allSettled(e.map(e=>this.save(e)))).forEach((t,n)=>{t.status===`rejected`&&this.deps.logger.warn({sessionId:e[n],err:t.reason instanceof Error?t.reason.message:String(t.reason)},`saveAll: a session failed to persist (others unaffected)`)}),await Promise.allSettled(this.saveChains.values())}async restore(e){if(!this.deps.configProvider)return null;let t=this.deps.getSession(e);if(t)return t;await this.flushPending(e);let n=this.isRemoteCasPersistence()?await this.deps.persistence.loadWithRevision(e):null,r=n?.snapshot??(n===null&&this.isRemoteCasPersistence()?null:await this.deps.persistence.load(e));if(!r)return null;if(r.version!==D)return this.deps.logger.warn({sessionId:e,version:r.version,expected:D},`Session snapshot version mismatch, skipped`),null;if(!this.deps.canAccommodate(e))throw Error(`Max sessions reached, cannot restore ${e}.`);let i=new E(r.id,void 0,void 0,{clock:this.deps.clock,idGen:this.deps.idGen});i.restoreEntries(r.entries,r.metadata,r.leafId);let a=yn(this.deps.configProvider(r.metadata.config?.agentName,r.metadata.config?.modelId),r.metadata.config),o=await this.deps.adoptRestoredSession(i,a);return r.metadata.archived&&o.archive(),await this.panelStateRestorer.restore(i,r,e),n&&this.remoteRevisions.set(e,n.revision),this.track(o,!1),await this.crashGapDetector.detect(o,r),this.deps.logger.info({sessionId:e},`Session restored`),o}consumeCrashGap(e){let t=this.crashGapDetector.consume(e);return t?{lostTurns:t.lostTurns}:void 0}async restoreAll(){if(!this.deps.configProvider)return 0;let e=this.deps.capacityLeft();if(e===0){let e=(await this.deps.persistence.list()).filter(e=>!this.deps.hasSession(e)).length;return e>0&&this.deps.logger.info({candidates:e},`Session pool full, restoreAll skipped (restore on demand)`),0}let t=await this.deps.persistence.listRecentMeta(e),n=[],r=0;for(let e of t){if(this.deps.hasSession(e))continue;let t;try{if(this.isRemoteCasPersistence()){let n=await this.deps.persistence.loadWithRevision(e);t=n?{snapshot:n.snapshot,revision:n.revision}:null}else{let n=await this.deps.persistence.load(e);t=n?{snapshot:n}:null}}catch(t){this.deps.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`restoreAll: a session snapshot failed to load (skipped, others unaffected)`);continue}if(!t)continue;let r=t.snapshot;if(r.version!==D){this.deps.logger.warn({sessionId:e,version:r.version,expected:D},`Session snapshot version mismatch, skipped`);continue}n.push(t)}let i=this.deps.capacityLeft();for(;n.length>i;)n.pop(),r++;r>0&&this.deps.logger.info({skipped:r,capacity:i},`Sessions exceeding pool capacity left on storage (restore on demand)`);let a=0,o=null;for(let e of n){let{snapshot:t}=e;if(!this.deps.hasSession(t.id))try{let n=new E(t.id,void 0,void 0,{clock:this.deps.clock,idGen:this.deps.idGen});n.restoreEntries(t.entries,t.metadata,t.leafId);let r=yn(this.deps.configProvider(t.metadata.config?.agentName,t.metadata.config?.modelId),t.metadata.config),i=await this.deps.adoptRestoredSession(n,r);t.metadata.archived&&i.archive(),await this.panelStateRestorer.restore(n,t,t.id),e.revision!==void 0&&this.remoteRevisions.set(t.id,e.revision),this.track(i,!1),await this.crashGapDetector.detect(i,t),a++,o===null&&(o=t.id)}catch(e){this.deps.logger.warn({sessionId:t.id,err:e instanceof Error?e.message:String(e)},`restoreAll: 单条会话重建失败(跳过,余者不受影响)`)}}return o&&this.deps.setActiveIfNone(o),this.deps.logger.info({count:a},`Sessions restored`),a}},W=class{panelStateStoreRef;sessions=new Map;configs=new Map;residencyClock=new Map;persistence;maxSessions;idleTimeoutMs;threshold;activeSessionId;stream;hookRegistry;logger;devtools;memory;traceStore;checkpointStore;clock;idGen;randomGen;residencyGovernor;getResidencyConfig;planeRegistry;configProvider;writeLeaseManager;coldSessionLister;semanticReviewer;hostCapabilities;autoPersist;timeTravel;persistenceSync;constructor(e,t,n=!1){this.autoPersist=n,this.stream=i(e.providerRegistry),this.hookRegistry=e.hookRegistry,this.logger=e.logger,this.devtools=e.devtools,this.memory=e.memory,this.traceStore=e.traceStore,this.checkpointStore=e.checkpointStore,this.clock=e.clock,this.idGen=e.idGen??De,this.randomGen=e.randomGen??Oe,this.residencyGovernor=e.residencyGovernor,this.getResidencyConfig=e.getResidencyConfig,this.planeRegistry=e.planeRegistry,this.configProvider=e.configProvider,this.writeLeaseManager=e.writeLeaseManager,this.coldSessionLister=e.coldSessionLister,this.semanticReviewer=e.semanticReviewer,this.hostCapabilities=e.hostCapabilities,this.persistence=t;let r=e.maxSessions??se;this.maxSessions=r,this.idleTimeoutMs=e.idleTimeoutMs??oe,this.threshold=Math.max(0,Math.min(e.threshold??r,r)),this.timeTravel=new cn({logger:this.logger,traceStore:this.traceStore,checkpointStore:this.checkpointStore,getSession:e=>this.sessions.get(e),getConfig:e=>this.configs.get(e),createSession:(e,t)=>this.createSession(e,t),ensureCapacity:e=>{if(this.sessions.has(e))throw Error(`Session with ID ${e} already exists.`);this.prepareCapacity(e)},adoptForkedSession:(e,t)=>this.adoptForkedSession(e,t),...ue(this.persistence)?{hydrateEntries:(e,t)=>this.persistence.hydrateReplacements(e,t)}:{}}),this.persistenceSync=new bn({persistence:this.persistence,logger:this.logger,autoPersist:this.autoPersist,traceStore:this.traceStore,clock:this.clock,idGen:this.idGen,turnFlush:this.persistence.turnFlush,getSession:e=>this.sessions.get(e),getConfig:e=>this.configs.get(e),hasSession:e=>this.sessions.has(e),listSessionIds:()=>this.sessions.keys(),canAccommodate:e=>this.canAccommodate(e),capacityLeft:()=>Math.max(0,this.maxSessions-this.sessions.size),adoptRestoredSession:async(e,t)=>{let n=this.buildAgentSession(e,t);return this.sessions.set(e.id,n),this.configs.set(e.id,t),this.admitToResidency(e.id),await this.hookRegistry.emit(`session.restored`,{sessionId:e.id,metadata:{}}),n.notifyCreated(),n},setActiveIfNone:e=>{this.activeSessionId||=e},configProvider:this.configProvider,panelStateStore:e.panelStateStore,residencyGovernor:e.residencyGovernor,getResidencyConfig:e.getResidencyConfig}),this.panelStateStoreRef=e.panelStateStore}get panelState(){return this.panelStateStoreRef}get active(){return this.activeSessionId?this.sessions.get(this.activeSessionId):void 0}getSessionPermissionAllow(e){return[...this.configs.get(e)?.permissionAlwaysAllow??[]]}setSessionPermissionAllow(e,t){let n=this.configs.get(e);if(n){if(t.length===0){delete n.permissionAlwaysAllow;return}n.permissionAlwaysAllow=[...t]}}getSessionAvailableModels(e){return[...this.configs.get(e)?.availableModels??[]]}setSessionAvailableModels(e,t){let n=this.configs.get(e);if(n){if(t.length===0){delete n.availableModels;return}n.availableModels=[...t]}}admitToResidency(e){this.residencyClock.set(e,(this.clock??Ee).now()),this.planeRegistry?.session(e)}clearSessionPlaneGrid(e){this.planeRegistry?.disposeSessionGrid(e)}residencySince(e,t){let n=this.residencyClock.get(e)??-1/0;return Math.max(n,t.session.metadata().lastActiveAt)}trackPersistence(e,t){this.persistenceSync.track(e,t)}precreateSessionRow(e,t){this.persistenceSync.precreateSessionRow(e,t)}async adoptForkedSession(e,t){let n=this.buildAgentSession(e,t);return this.sessions.set(e.id,n),this.configs.set(e.id,t),this.admitToResidency(e.id),this.trackPersistence(n,!1),this.precreateSessionRow(n,!1),await this.hookRegistry.emit(`session.created`,{sessionId:e.id,metadata:{}}),n.notifyCreated(),n}buildAgentSession(e,t,n){let r=n??this.recordPorts(e.id);return new Ht(e,{model:t.model,titleModel:t.titleModel,modelResolution:t.modelResolution,agentName:t.agentName,systemPrompt:t.systemPrompt,systemTail:t.systemTail,tools:r.tools??t.tools,thinkingLevel:t.thinkingLevel,maxToolTurns:t.maxToolTurns,maxToolTurnExtensions:t.maxToolTurnExtensions,promptOutputTokenBudget:t.promptOutputTokenBudget,promptWallClockBudgetMs:t.promptWallClockBudgetMs,stallDetection:t.stallDetection,idleTurnDetection:t.idleTurnDetection,sessionCostBudgetUSD:t.sessionCostBudgetUSD,todoContinuation:t.todoContinuation,promptRefresh:t.promptRefresh,workspaceDir:t.workspaceDir,workspaceId:t.workspaceId,transient:t.transient,depth:t.depth,interactive:t.interactive,listable:t.listable,retryAccelerate:t.retryAccelerate,streamRetry:t.streamRetry,networkDisconnectRetry:t.networkDisconnectRetry,lifecycleAsyncTimeoutMs:t.lifecycleAsyncTimeoutMs,describeImages:t.describeImages,getCompactionTimeoutMs:()=>k(this.getResidencyConfig?.()).compactionTimeoutMs,hookRegistry:this.hookRegistry,stream:r.stream??this.stream,logger:this.logger.child({sessionId:e.id}),devtools:this.devtools,memory:r.disableMemory?void 0:this.memory,recorder:r.recorder,nondetFlush:r.nondetFlush,clock:r.clock,semanticReviewer:this.semanticReviewer,hostCapabilities:this.hostCapabilities})}recordPorts(e){let t=this.traceStore;if(!t)return{clock:this.clock};let n=this.clock??Ee,r=be({sink:{append:n=>t.append(e,n).then(()=>void 0)},sessionId:e,clock:n}),i=ve({clock:n,random:this.randomGen,id:this.idGen},r);return{clock:i.clock,recorder:r,nondetFlush:i.flushNondetBatch}}async createSession(e,t){let n=e.id??this.idGen.uuid();if(this.sessions.has(n))throw Error(`Session with ID ${n} already exists.`);this.prepareCapacity(n);let r=new E(n,void 0,void 0,{clock:this.clock,idGen:this.idGen});r.setSdkVersion(de);let i=this.buildAgentSession(r,e,t);return this.sessions.set(n,i),this.configs.set(n,e),this.admitToResidency(n),(e.transient??!1)||(this.activeSessionId=n),this.trackPersistence(i,e.transient??!1),this.precreateSessionRow(i,e.transient??!1),await this.hookRegistry.emit(`session.created`,{sessionId:n,metadata:{}}),i.notifyCreated(),this.logger.info({sessionId:n},`Session created`),i}replaySession(e,t,n={}){return this.timeTravel.replaySession(e,t,n)}createCheckpoint(e,t={}){return this.timeTravel.createCheckpoint(e,t)}listCheckpoints(e){return this.timeTravel.listCheckpoints(e)}restoreCheckpoint(e,t,n=`both`){return this.timeTravel.restoreCheckpoint(e,t,n)}rollbackToCheckpoint(e,t,n=`both`){return this.timeTravel.rollbackToCheckpoint(e,t,n)}forkFromCheckpoint(e,t,n){return this.timeTravel.forkFromCheckpoint(e,t,n)}replayTrace(e,t,n=0){return this.timeTravel.replayTrace(e,t,n)}traceback(e,t){return this.timeTravel.traceback(e,t)}getSession(e){return this.sessions.get(e)}getResidencyDiagnostics(){let e=0,t=0;for(let[n,r]of this.sessions){if(this.configs.get(n)?.transient)continue;let i=r.session;i instanceof E&&(e++,t+=i.estimatedContentBytes)}let n=this.residencyGovernor?.currentLevel??`healthy`,r=R({activeSessionCount:e,currentTotalResidentBytes:t,pressureDivisor:L[n],config:this.getResidencyConfig?.()});return{activeSessionCount:e,totalResidentBytes:t,globalPressure:r.globalPressure,isGlobalPressure:r.isGlobalPressure,maxBytesPerSession:r.maxBytesPerSession,pressureLevel:n}}listSessions(e){let t=Array.from(this.sessions.values());e?.workspaceId&&(t=t.filter(t=>t.workspaceId===e.workspaceId));let n=t.map(e=>{let t=e.session.metadata();return{id:e.id,title:ct(t.title,e.session.messages(),e.id),messageCount:e.session.messages().length,createdAt:t.createdAt?new Date(t.createdAt):new Date,updatedAt:t.lastActiveAt?new Date(t.lastActiveAt):void 0,model:e.model.id,status:e.status,sdkVersion:t.sdkVersion,workspaceId:e.workspaceId,pinned:e.pinned,pinGroup:t.pinGroup,writeLocked:this.writeLeaseManager?.isLockedByOther(e.id)??!1}});return n.sort((e,t)=>{let n=e.updatedAt?.getTime()??e.createdAt.getTime();return(t.updatedAt?.getTime()??t.createdAt.getTime())-n}),n}async listAllPersistedSessions(e){let t=e?.workspaceKey??`default`;if(this.coldSessionLister)return this.coldSessionLister.listColdSessions(t);let n;try{n=await this.persistence.listPaginated({page:0,pageSize:100,sortBy:`lastActiveAt`,order:`desc`})}catch(e){return this.logger.warn({workspaceKey:t,err:e instanceof Error?e.message:String(e)},`listAllPersistedSessions: listPaginated failed (batch unavailable, not a per-session issue)`),[]}let r=[];for(let e of n.items)try{let t=await this.persistence.load(e);if(!t)continue;let n=t.metadata;r.push({id:e,title:n.title?.trim()||e.slice(0,8),messageCount:n.messageCount??0,createdAt:n.createdAt?new Date(n.createdAt):new Date,updatedAt:n.lastActiveAt?new Date(n.lastActiveAt):void 0,status:n.archived?`archived`:`idle`,pinned:n.pinned,pinGroup:n.pinGroup,writeLocked:this.writeLeaseManager?.isLockedByOther(e)??!1})}catch(t){this.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`listAllPersistedSessions: a session snapshot failed to load (skipped, others unaffected)`)}return r}backfillTitles(){let e=0,t=0;for(let n of this.sessions.values()){let r=n.session.metadata().titleSource;if(r===`custom`||r===`ai`){t++;continue}n.backfillTitle(),e++}return{triggered:e,skipped:t}}async archiveSession(e){let t=this.sessions.get(e);return t?(await this.persistenceSync.save(e),le(this.persistence)&&await this.persistence.archiveSession(e),t.archive(),!0):!1}async removeSession(e){let t=this.sessions.get(e);if(!t){await this.persistenceSync.flushPending(e);let t=await this.persistence.delete(e);return await this.clearSessionStores(e),t}return t.dispose(),this.sessions.delete(e),this.configs.delete(e),this.residencyClock.delete(e),this.clearSessionPlaneGrid(e),this.activeSessionId===e&&(this.activeSessionId=void 0),await this.persistenceSync.flushPending(e),await this.persistence.delete(e),await this.clearSessionStores(e),this.hookRegistry.emit(`session.deleted`,{sessionId:e,metadata:{reason:`removed`}}),this.logger.info({sessionId:e},`Session removed`),!0}async clearSessionStores(e){let t=async(t,n)=>{if(n)try{await n.clear(e)}catch(n){this.logger.warn({sessionId:e,err:n instanceof Error?n.message:String(n)},`Failed to clear ${t} on session removal`)}};await t(`trace store`,this.traceStore),await t(`checkpoint store`,this.checkpointStore)}async ensureEntriesHydrated(e,t,n){if(!ce(t))return t;if(!ue(this.persistence))throw Error(`${n}: entries contain stripped compaction replacements but persistence lacks hydration capability (RFC-160 D4); refusing to fork stripped state`);return this.persistence.hydrateReplacements(e,t)}async forkSession(e,t){let n=this.sessions.get(e),r=this.configs.get(e);if(!n||!r)return;let i=n.session;if(!(i instanceof E))return;let a=t??this.idGen.uuid();this.prepareCapacity(a);let o=i.toSnapshot(),s=Ut(a,e,await this.ensureEntriesHydrated(e,o.entries,`forkSession`),o.metadata,o.leafId,this.clock,this.idGen),c={...r,model:n.model,agentName:n.agentName===`agent`?void 0:n.agentName,systemPrompt:n.systemPrompt,systemTail:n.systemTail,tools:n.tools,thinkingLevel:n.thinkingLevel,maxToolTurns:n.maxToolTurns,maxToolTurnExtensions:n.maxToolTurnExtensions,promptOutputTokenBudget:n.promptOutputTokenBudget,promptWallClockBudgetMs:n.promptWallClockBudgetMs,promptRefresh:n.promptRefresh,workspaceDir:n.workspaceDir,workspaceId:n.workspaceId},l=await this.adoptForkedSession(s,c);return this.logger.info({sessionId:a,sourceId:e},`Session forked`),l}save(e){return this.persistenceSync.save(e)}saveAll(){return this.persistenceSync.saveAll()}inspectSessionWriteLease(e){return this.writeLeaseManager?.inspect(e)??{locked:!1}}forceReleaseSessionWriteLease(e){this.writeLeaseManager?.forceRelease(e)}restore(e){return this.persistenceSync.restore(e)}consumeCrashGap(e){return this.persistenceSync.consumeCrashGap(e)}restoreAll(){return this.persistenceSync.restoreAll()}collectIdle(){let e=(this.clock??Ee).now(),t=[];for(let[n,r]of this.sessions)if(!(r.isBusy||r.isPaused)&&e-this.residencySince(n,r)>this.idleTimeoutMs){let e=r.session,i=!1;if(this.autoPersist&&e instanceof E){let t=e.toSnapshot();t.entries.length>0&&(i=!0,this.persistenceSync.saveSnapshot(n,t,()=>{this.persistenceSync.forgetEvictedSession(n)}).catch(e=>{this.logger.warn({sessionId:n,err:e instanceof Error?e.message:String(e)},`Session snapshot flush on idle eviction failed`)}))}r.dispose(),this.sessions.delete(n),this.configs.delete(n),this.residencyClock.delete(n),this.clearSessionPlaneGrid(n),i||this.persistenceSync.forgetSession(n),this.activeSessionId===n&&(this.activeSessionId=void 0),this.hookRegistry.emit(`session.deleted`,{sessionId:n,metadata:{reason:`idle`}}),t.push(n)}return t}entryCount(e){let t=e.session;return t instanceof E?t.entries().length:t.messages().length}evictLeastRecent(e){let t=Array.from(this.sessions.entries()).filter(([t,n])=>t!==e&&t!==this.activeSessionId&&!n.isBusy&&!n.isPaused&&!(this.configs.get(t)?.transient??!1)).filter(([,e])=>this.autoPersist||this.entryCount(e)===0).sort(([e,t],[n,r])=>this.residencySince(e,t)-this.residencySince(n,r));for(let[e,n]of t){if(this.sessions.size<this.maxSessions)break;let t=n.session,r=!1;if(this.autoPersist&&t instanceof E){let n=t.toSnapshot();n.entries.length>0&&(r=!0,this.persistenceSync.saveSnapshot(e,n,()=>{this.persistenceSync.forgetEvictedSession(e)}).catch(t=>{this.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`Session snapshot flush on eviction failed`)}))}n.dispose(),this.sessions.delete(e),this.configs.delete(e),this.residencyClock.delete(e),this.clearSessionPlaneGrid(e),r||this.persistenceSync.forgetSession(e),this.hookRegistry.emit(`session.deleted`,{sessionId:e,metadata:{reason:`evicted`}}),this.logger.info({sessionId:e},`Session evicted (LRU)`)}}prepareCapacity(e){if(!this.sessions.has(e)&&(this.sessions.size+1>this.threshold&&this.collectIdle(),this.sessions.size>=this.maxSessions&&this.evictLeastRecent(e),this.sessions.size>=this.maxSessions))throw Error(`Max sessions (${this.maxSessions}) reached.`)}canAccommodate(e){return this.sessions.has(e)?!0:(this.sessions.size+1>this.threshold&&this.collectIdle(),this.sessions.size>=this.maxSessions&&this.evictLeastRecent(e),this.sessions.size<this.maxSessions)}dispose(){for(let e of this.sessions.values())e.dispose();for(let e of this.sessions.keys())this.clearSessionPlaneGrid(e);this.sessions.clear(),this.configs.clear(),this.residencyClock.clear(),this.activeSessionId=void 0}};function xn(e){let{sessionUrl:t}=e;if(!t)throw Error(`sessionUrl is required for RemoteSessionPool`);return new W(e,new ie({baseUrl:t,fetch:e.fetch,getAuth:e.getAuth,timeoutMs:e.timeoutMs??3e4,userId:e.userId,wsKey:e.wsKey}),!0)}function Sn(e){return new W(e,new re)}function Cn(e,t,n=!0){return new W(e,t,n)}function wn(e,t){let n=new $e;return n.register(it(e)),n}function Tn(e={}){let t=e.logger??d(`otto-runtime`,{level:`info`,destination:`stdout`}),n=e.providerRegistry??r(),i=e.hookRegistry??a({preset:`default`});e.hookRegistry||s(i);let o=e.storage??{kind:`in-memory`},c=e.traceStore===void 0,l=e.checkpointStore===void 0,{traceStore:u,checkpointStore:f}=Qe(o.kind===`remote`?{remoteLog:{baseUrl:o.sessionUrl,getAuth:o.getAuth,fetch:o.fetch,timeoutMs:o.timeoutMs}}:{},{traceStore:e.traceStore,checkpointStore:e.checkpointStore}),p=wn(e.workspaceDir??process.cwd(),e.memory),m=(()=>{if(o.kind===`custom`&&(o.panelStatePersistence||o.pasteStatePersistence))return new U(o.panelStatePersistence??S(),o.pasteStatePersistence??C());let e=o.kind===`custom`&&o.panelStateDir?o.panelStateDir:void 0;if(e!==void 0)return new U(new g({baseDir:e}),new _({baseDir:`${e}/paste`}))})(),h={hookRegistry:i,providerRegistry:n,logger:t,memory:e.memory,traceStore:u,checkpointStore:f,clock:e.clock,maxSessions:e.maxSessions,idleTimeoutMs:e.idleTimeoutMs,devtools:e.devtools,configProvider:e.configProvider,panelStateStore:m,residencyGovernor:e.residencyGovernor,getResidencyConfig:e.getResidencyConfig,planeRegistry:e.planeRegistry,semanticReviewer:e.semanticReviewer,hostCapabilities:e.hostCapabilities},v=o.kind===`remote`?xn({...h,sessionUrl:o.sessionUrl,fetch:o.fetch,getAuth:o.getAuth,timeoutMs:o.timeoutMs,userId:o.userId,wsKey:o.wsKey}):o.kind===`custom`?Cn({...h,writeLeaseManager:o.writeLeaseManager,coldSessionLister:o.coldSessionLister},o.persistence,o.autoPersist??!0):Sn(h);return{createSession:(e,t)=>v.createSession(e,t),sessions:v,hookRegistry:i,stream:v.stream,contextSources:p,traceStore:u,checkpointStore:f,clock:e.clock,dispose:async()=>{v.dispose(),c&&await u.close?.(),l&&await f.close?.(),o.kind===`custom`&&await o.onDispose?.()}}}function En(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0&&r<=100?r:t}function G(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0?r:t}var Dn=class{warnThresholdPct;hardThresholdPct;sampleIntervalMs;warningIntervalMs;criticalIntervalMs;warnCooldownMs;onWarning;onCritical;logger;now;postRestartGraceMs;ticker=null;lastLevel=`healthy`;lastWarningFiredAt;graceStartedAt;onCriticalDuringGrace;onLevelChange;onSample;disposed=!1;criticalTimeoutMs;onCriticalTimeout;criticalEnteredAt;criticalTimeoutFired=!1;constructor(e={}){this.warnThresholdPct=e.warnThresholdPct??En(`OTTO_MEMORY_WARN_PCT`,70),this.hardThresholdPct=e.hardThresholdPct??En(`OTTO_MEMORY_HARD_PCT`,85),this.sampleIntervalMs=e.sampleIntervalMs??G(`OTTO_MEMORY_SAMPLE_INTERVAL_MS`,3e4),this.warningIntervalMs=e.warningIntervalMs??G(`OTTO_MEMORY_WARNING_INTERVAL_MS`,1e4),this.criticalIntervalMs=e.criticalIntervalMs??G(`OTTO_MEMORY_CRITICAL_INTERVAL_MS`,5e3),this.warnCooldownMs=e.warnCooldownMs??3e5,this.postRestartGraceMs=e.postRestartGraceMs??6e5,this.criticalTimeoutMs=e.criticalTimeoutMs??G(`OTTO_MEMORY_CRITICAL_TIMEOUT_MS`,9e5),this.onWarning=e.onWarning,this.onCritical=e.onCritical,this.onCriticalDuringGrace=e.onCriticalDuringGrace,this.onLevelChange=e.onLevelChange,this.onSample=e.onSample,this.onCriticalTimeout=e.onCriticalTimeout,this.logger=e.logger,this.now=e.now??(()=>Date.now())}get currentLevel(){return this.lastLevel}setCallbacks(e){`onWarning`in e&&(this.onWarning=e.onWarning),`onCritical`in e&&(this.onCritical=e.onCritical),`onCriticalDuringGrace`in e&&(this.onCriticalDuringGrace=e.onCriticalDuringGrace),`onLevelChange`in e&&(this.onLevelChange=e.onLevelChange),`onSample`in e&&(this.onSample=e.onSample),`onCriticalTimeout`in e&&(this.onCriticalTimeout=e.onCriticalTimeout)}markRestarted(){this.graceStartedAt=this.now()}updateThresholds(e){e.warnThresholdPct!=null&&process.env.OTTO_MEMORY_WARN_PCT===void 0&&(this.warnThresholdPct=e.warnThresholdPct),e.hardThresholdPct!=null&&process.env.OTTO_MEMORY_HARD_PCT===void 0&&(this.hardThresholdPct=e.hardThresholdPct)}get inPostRestartGrace(){return this.graceStartedAt===void 0?!1:this.now()-this.graceStartedAt<this.postRestartGraceMs}sample(){let{heapUsed:e,rss:t,external:n}=process.memoryUsage(),{heap_size_limit:r}=He(),i=r>0?e/r*100:0;return{level:this.grade(i),heapUsed:e,heapSizeLimit:r,usedPct:i,rss:t,external:n,ts:this.now()}}grade(e){return e>=this.hardThresholdPct?`critical`:e>=this.warnThresholdPct?`warning`:`healthy`}start(){this.ticker||(this.ticker=setTimeout(()=>this.tick(),this.sampleIntervalMs),this.ticker.unref?.())}tick(){let e=this.sample();if(this.disposed)return;if(this.onSample?.(e),e.level!==this.lastLevel){if(this.logger?.info({from:this.lastLevel,to:e.level,usedPct:e.usedPct.toFixed(1),heapUsed:e.heapUsed,heapSizeLimit:e.heapSizeLimit},`[memory-governor] pressure level changed`),this.onLevelChange?.(e.level),e.level===`warning`){let e=this.now();this.lastWarningFiredAt!==void 0&&e-this.lastWarningFiredAt<this.warnCooldownMs?this.logger?.info({cooldownRemainingMs:this.warnCooldownMs-(e-this.lastWarningFiredAt)},`[memory-governor] onWarning skipped (within cooldown)`):(this.lastWarningFiredAt=e,this.onWarning?.())}e.level===`critical`&&(this.inPostRestartGrace?this.onCriticalDuringGrace?.(e):this.onCritical?.(e))}if(e.level===`critical`?this.criticalEnteredAt===void 0?(this.criticalEnteredAt=this.now(),this.criticalTimeoutFired=!1):!this.criticalTimeoutFired&&this.now()-this.criticalEnteredAt>=this.criticalTimeoutMs&&(this.criticalTimeoutFired=!0,this.onCriticalTimeout?.(e)):(this.criticalEnteredAt=void 0,this.criticalTimeoutFired=!1),this.lastLevel=e.level,this.disposed)return;let t=this.lastLevel===`critical`?this.criticalIntervalMs:this.lastLevel===`warning`?this.warningIntervalMs:this.sampleIntervalMs;this.ticker=setTimeout(()=>this.tick(),t),this.ticker.unref?.()}dispose(){this.disposed=!0,this.ticker&&=(clearTimeout(this.ticker),null)}};function K(e,t){let n=process.env[e];if(!n)return t;let r=Number(n);return Number.isFinite(r)&&r>0?r:t}var On=class{sampleIntervalMs;maxProcesses;maxTotalRssMb;listProcesses;logger;now;onSample;onBudgetExceeded;ticker=null;disposed=!1;budgetExceededNotified=!1;constructor(e={}){this.sampleIntervalMs=e.sampleIntervalMs??K(`OTTO_FLEET_SAMPLE_INTERVAL_MS`,6e5),this.maxProcesses=e.maxProcesses??K(`OTTO_FLEET_MAX_PROCESSES`,8),this.maxTotalRssMb=e.maxTotalRssMb??K(`OTTO_FLEET_MAX_TOTAL_RSS_MB`,8192),this.listProcesses=e.listProcesses??me,this.onSample=e.onSample,this.onBudgetExceeded=e.onBudgetExceeded,this.logger=e.logger,this.now=e.now??(()=>Date.now())}setCallbacks(e){`onSample`in e&&(this.onSample=e.onSample),`onBudgetExceeded`in e&&(this.onBudgetExceeded=e.onBudgetExceeded)}sample(){let e;try{e=this.listProcesses()}catch(e){this.logger?.warn({err:e instanceof Error?e.message:String(e)},`[fleet-monitor] process enumeration failed (skipping sample)`);return}if(e.length===0)return;let t=0,n=0,r=0;for(let i of e)t+=i.rssKb,i.ppid===1&&i.tty===`??`&&n++,i.generation!==void 0&&i.generation>r&&(r=i.generation);return{processCount:e.length,totalRssMb:Math.round(t/1024),suspectedOrphanCount:n,maxGeneration:r,ts:this.now()}}tick(){if(this.disposed)return;let e=this.sample();if(e){this.onSample?.(e);let t=e.processCount>this.maxProcesses,n=e.totalRssMb>this.maxTotalRssMb;if(t||n){if(!this.budgetExceededNotified){this.budgetExceededNotified=!0;let n=t?`process-count`:`total-rss`;this.logger?.warn({processCount:e.processCount,totalRssMb:e.totalRssMb,maxProcesses:this.maxProcesses,maxTotalRssMb:this.maxTotalRssMb},`[fleet-monitor] fleet budget exceeded`),this.onBudgetExceeded?.(e,n)}}else this.budgetExceededNotified=!1}this.disposed||(this.ticker=setTimeout(()=>this.tick(),this.sampleIntervalMs),this.ticker.unref?.())}start(){this.ticker||this.disposed||(this.ticker=setTimeout(()=>this.tick(),this.sampleIntervalMs),this.ticker.unref?.())}dispose(){this.disposed=!0,this.ticker&&=(clearTimeout(this.ticker),null)}};const q=fe,J=(e,t)=>{try{process.kill(-e,t)}catch{try{process.kill(e,t)}catch{}}},Y=e=>{try{We(`taskkill`,[`/F`,`/T`,`/PID`,`${e}`],{stdio:`ignore`,timeout:5e3})}catch{}};var kn=class{entries=new Map;maxProcesses;graceMs;clock;spawnListeners=new Set;exitListeners=new Set;constructor(e={}){this.maxProcesses=e.maxProcesses??64,this.graceMs=e.graceMs??2e3,this.clock=e.clock??(()=>Date.now())}onSpawn(e){return this.spawnListeners.add(e),()=>this.spawnListeners.delete(e)}onExit(e){return this.exitListeners.add(e),()=>this.exitListeners.delete(e)}notify(e,t){for(let n of[...e])try{n(t)}catch{}}register(e){if(this.entries.size>=this.maxProcesses&&this.evictLeastRecent(),this.entries.size>=this.maxProcesses)throw Error(`Background process limit (${this.maxProcesses}) reached; stop one with kill_shell first.`);let t=e.child.pid;if(t===void 0)throw Error(`Cannot register a child process without a pid`);let n=e.now??this.clock(),r={id:e.id,sessionId:e.sessionId,owner:e.owner,pid:t,pgid:t,command:e.command,cwd:e.cwd,port:e.port,url:e.url,logPath:e.logPath,startedAt:n,lastUsed:n,status:`running`,keepAlive:e.keepAlive},i={info:r,child:e.child};return this.entries.set(e.id,i),e.child.once(`exit`,e=>{r.status===`running`?(r.status=`exited`,r.exitCode=e??void 0):r.status===`killing`&&(r.status=`killed`),i.silenced||this.notify(this.exitListeners,r)}),this.notify(this.spawnListeners,r),r}get(e){return this.entries.get(e)?.info}getForSession(e,t){let n=this.entries.get(t);return n&&n.info.sessionId===e?n.info:void 0}list(){return[...this.entries.values()].map(e=>e.info)}listForSession(e){return this.list().filter(t=>t.sessionId===e)}touch(e){let t=this.entries.get(e);t&&(t.info.lastUsed=this.clock())}updateDetectedService(e,t){let n=this.entries.get(e);n&&(n.info.detectedService?.url&&!t.url||(n.info.detectedService=t))}remove(e){let t=this.entries.get(e);t&&(t.silenced=!0,this.entries.delete(e))}size(){return this.entries.size}async kill(e){let t=this.entries.get(e);t&&await this.killEntry(t)}async killAll(){await Promise.all([...this.entries.values()].map(e=>this.killEntry(e)))}async killAllForOwner(e){await Promise.all([...this.entries.values()].filter(t=>t.info.owner===e).map(e=>this.killEntry(e)))}async killAllForSession(e){await Promise.all([...this.entries.values()].filter(t=>t.info.sessionId===e).map(e=>this.killEntry(e)))}killAllSync(){for(let e of this.entries.values())this.killEntrySync(e)}killEntrySync(e){let{info:t}=e;t.status===`exited`||t.status===`killed`||(process.platform===`win32`?Y(t.pid):J(t.pgid,`SIGKILL`),t.status=`killed`)}evictLeastRecent(){let e;for(let t of this.entries.values()){if(t.info.status===`exited`||t.info.status===`killed`){e=t;break}t.info.keepAlive||(!e||t.info.lastUsed<e.info.lastUsed)&&(e=t)}e&&(e.silenced=!0,this.killEntrySync(e),this.entries.delete(e.info.id))}async killEntry(e){let{info:t}=e;if(t.status===`running`){if(t.status=`killing`,process.platform===`win32`){Y(t.pid),t.status=`killed`;return}J(t.pgid,`SIGTERM`),await this.waitForExit(e,this.graceMs)||J(t.pgid,`SIGKILL`),t.status=`killed`}}waitForExit(e,t){return new Promise(n=>{let r=!1,i,a=t=>{r||(r=!0,clearTimeout(i),e.child.removeListener(`exit`,o),n(t))},o=()=>a(!0);if(e.child.once(`exit`,o),!q(e.info.pid)){a(!0);return}i=setTimeout(()=>a(!1),t)})}};const An=new kn;let jn=!1;function Mn(e=An){jn||(jn=!0,process.on(`exit`,()=>{e.killAllSync()}))}let Nn=0;var Pn=class extends Ge{id;child;config;status=`starting`;_clock;_pid;_pgid;_exitResult=null;_exitResolve=null;_stdoutBuf=``;_stderrBuf=``;lastUsed;startedAt;_detectedService;constructor(e,t,n){if(super(),this._clock=n,this.id=`proc_${++Nn}_${this._clock()}`,this.child=e,this.config=t,this._pid=e.pid,this._pgid=e.pid,this.lastUsed=this._clock(),this.startedAt=this.lastUsed,this.child.on(`spawn`,()=>{this._pid=this.child.pid,this._pgid=this.child.pid,this.status===`starting`&&(this.status=`running`)}),this.child.on(`error`,e=>{this.lastUsed=this._clock(),(this.status===`starting`||this.status===`running`)&&(this.status=`errored`),this.emit(`error`,e)}),this.child.on(`exit`,(e,t)=>{this.lastUsed=this._clock();let n={code:e,signal:t,timedOut:!1};this._exitResult=n,this.status===`running`?this.status=`exited`:this.status===`killing`&&(this.status=`killed`),this.emit(`exit`,n),this._exitResolve&&=(this._exitResolve(n),null)}),this.child.stdout&&this.child.stdout.on(`data`,e=>{this.lastUsed=this._clock();let t=e.toString(`utf-8`);for(this._stdoutBuf+=t;;){let e=this._stdoutBuf.indexOf(`
16
17
  `);if(e===-1)break;let t=this._stdoutBuf.slice(0,e).replace(/\r$/,``);this._stdoutBuf=this._stdoutBuf.slice(e+1),this.emit(`stdoutLine`,t)}}),this.child.stderr&&this.child.stderr.on(`data`,e=>{this.lastUsed=this._clock();let t=e.toString(`utf-8`);for(this._stderrBuf+=t;;){let e=this._stderrBuf.indexOf(`
17
- `);if(e===-1)break;let t=this._stderrBuf.slice(0,e).replace(/\r$/,``);this._stderrBuf=this._stderrBuf.slice(e+1),this.emit(`stderrLine`,t)}}),t.signal){let e=()=>{this.kill({reason:`aborted`})};t.signal.aborted?e():t.signal.addEventListener(`abort`,e,{once:!0})}}get pid(){return this._pid}get pgid(){return this._pgid}get stdin(){return this.child.stdin&&!this.child.stdin.destroyed?this.child.stdin:null}get stdout(){return this.child.stdout&&!this.child.stdout.destroyed?this.child.stdout:null}get stderr(){return this.child.stderr&&!this.child.stderr.destroyed?this.child.stderr:null}get command(){return this.config.command}get cwd(){return this.config.cwd}get logPath(){return this.config.logPath}get port(){return this.config.port}get url(){return this.config.url}get exitCode(){return this._exitResult?.code??void 0}get detectedService(){return this._detectedService}setDetectedService(e){this._detectedService=e}onStdoutLine(e){return this.on(`stdoutLine`,e),()=>this.off(`stdoutLine`,e)}onStderrLine(e){return this.on(`stderrLine`,e),()=>this.off(`stderrLine`,e)}onExit(e){return this.on(`exit`,e),()=>this.off(`exit`,e)}onError(e){return this.on(`error`,e),()=>this.off(`error`,e)}async kill(e){if(this.status===`killed`||this.status===`exited`)return;this.status=`killing`,this.lastUsed=this._clock();let t=e?.graceMs??this.config.killGraceMs??2e3,n=this._pid,r=this._pgid;if(!n||!q(n)){this.status=`killed`;return}if(process.platform===`win32`){Y(n),this.status=`killed`;return}J(r??n,`SIGTERM`),await new Promise(e=>{let r=!1,i=t=>{r||(r=!0,clearTimeout(o),e(t))},a=()=>i(!0);if(this.child.once(`exit`,a),!q(n)){i(!0);return}let o=setTimeout(()=>{this.child.removeListener(`exit`,a),i(!1)},t)})||J(r??n,`SIGKILL`),this.status=`killed`}async waitForExit(e=3e4){return this._exitResult?this._exitResult:new Promise(t=>{if(this._exitResult){t(this._exitResult);return}let n=!1,r=e=>{n||(n=!0,clearTimeout(a),this.off(`exit`,i),t(e))},i=e=>r(e);this.on(`exit`,i);let a=setTimeout(()=>{r({code:null,signal:null,timedOut:!0})},e)})}},Mn=class{_entries=new Map;_maxProcesses;killGraceMs;killTimeoutMs;_clock;_spawnListeners=new Set;_exitListeners=new Set;constructor(e={}){this._maxProcesses=e.maxProcesses??128,this.killGraceMs=e.killGraceMs??2e3,this.killTimeoutMs=e.killTimeoutMs??3e4,this._clock=e.clock??(()=>Date.now())}onSpawn(e){return this._spawnListeners.add(e),()=>this._spawnListeners.delete(e)}onExit(e){return this._exitListeners.add(e),()=>this._exitListeners.delete(e)}onAllExited(e){let t=()=>{this._entries.size===0&&e()},n=()=>t();return this._exitListeners.add(n),t(),()=>this._exitListeners.delete(n)}spawn(e){if(this._entries.size>=this._maxProcesses&&this._evictLeastRecent(),this._entries.size>=this._maxProcesses)throw Error(`Process limit (${this._maxProcesses}) reached. Stop unused processes first.`);let t={...e.options,stdio:e.options?.stdio??[`pipe`,`pipe`,`pipe`],cwd:e.cwd??e.options?.cwd,env:u(e.env??e.options?.env),...e.keepAlive===!0?{}:{detached:!0}},n=Ue(e.command,e.args??[],t),r=new jn(n,e,this._clock);this._entries.set(r.id,{proc:r,child:n}),r.onExit(()=>{if(!this._entries.get(r.id))return;let t=e.lifecycle??`evictable`;e.keepAlive!==!0&&t!==`pinned`&&this._entries.delete(r.id);for(let e of[...this._exitListeners])try{e(r)}catch{}});for(let e of[...this._spawnListeners])try{e(r)}catch{}return r}get(e){return this._entries.get(e)?.proc}list(e){let t=[...this._entries.values()];return e?.owner&&(t=t.filter(t=>t.proc.config.owner.type===e.owner.type&&t.proc.config.owner.id===e.owner.id)),e?.sessionId&&(t=t.filter(t=>t.proc.config.sessionId===e.sessionId)),e?.category&&(t=t.filter(t=>t.proc.config.category===e.category)),t.map(e=>e.proc)}listForSession(e){return this.list({sessionId:e})}getForSession(e,t){let n=this._entries.get(t)?.proc;if(!(!n||n.config.sessionId!==e))return n}async kill(e,t){let n=this._entries.get(e);n&&await n.proc.kill(t)}updateDetectedService(e,t){let n=this._entries.get(e);n&&(n.proc.detectedService?.url&&!t.url||(n.proc.setDetectedService(t),this.touch(e)))}listForOwner(e){return this.list({owner:e})}touch(e){let t=this._entries.get(e);t&&(t.proc.lastUsed=this._clock())}remove(e){this._entries.delete(e)}size(){return this._entries.size}async killAll(e,t){let n=this.list(e).filter(e=>!e.config.keepAlive);await Promise.all(n.map(e=>e.kill(t)))}killAllSync(){let e=process.platform===`win32`,t=[];for(let[n,r]of this._entries){let i=r.proc;if(i.config.keepAlive||i.status!==`running`&&i.status!==`starting`)continue;let a=i.pid;a&&(e?t.push(a):J(i.pgid??a,`SIGKILL`),this._entries.delete(n))}if(e&&t.length>0)try{We(`taskkill`,[`/F`,`/T`,...t.map(String).flatMap(e=>[`/PID`,e])],{stdio:`ignore`,timeout:5e3})}catch{}}async killAllForOwner(e,t){return this.killAll({owner:{type:e,id:t}})}async killAllForSession(e){return this.killAll({sessionId:e})}registerChild(e,t){if(this._entries.size>=this._maxProcesses&&this._evictLeastRecent(),this._entries.size>=this._maxProcesses)throw Error(`Process limit (${this._maxProcesses}) reached. Stop unused processes first.`);let n=new jn(t,e,this._clock);this._entries.set(n.id,{proc:n,child:t}),n.onExit(()=>{if(!this._entries.get(n.id))return;let t=e.lifecycle??`evictable`;e.keepAlive!==!0&&t!==`pinned`&&this._entries.delete(n.id);for(let e of[...this._exitListeners])try{e(n)}catch{}});for(let e of[...this._spawnListeners])try{e(n)}catch{}return n}_evictLeastRecent(){let e;for(let t of this._entries.values()){let n=t.proc.config,r=n.lifecycle??`evictable`;if(t.proc.status===`exited`||t.proc.status===`killed`||t.proc.status===`errored`){e=t;break}n.keepAlive||r!==`pinned`&&(!e||t.proc.lastUsed<e.proc.lastUsed)&&(e=t)}if(!e)return;let t=e.proc.pid;t&&q(t)&&(process.platform===`win32`?Y(t):J(e.proc.pgid??t,`SIGKILL`)),this._entries.delete(e.proc.id)}};const Nn=new Mn;let Pn=!1;function Fn(e=Nn){Pn||(Pn=!0,process.on(`exit`,()=>{e.killAllSync()}))}function X(e,t){return A(`git`,[`-C`,e,...t],{encoding:`utf-8`,stdio:[`ignore`,`pipe`,`pipe`]}).trimEnd()}function In(e,t){let n=X(e,[`rev-parse`,`HEAD`]),r=`otto/job-${t}`,i=p(Je(p(M(),`otto-wt-`)),`job-${t}`);return X(e,[`worktree`,`add`,`-b`,r,i,n]),{path:i,branch:r,base:n,repoRoot:e}}function Ln(e){return X(e.path,[`add`,`-A`]),A(`git`,[`-C`,e.path,`diff`,`--cached`,`--binary`],{encoding:`utf-8`,maxBuffer:256*1024*1024})}function Z(e){return[...new Set(e.split(`
18
- `).map(e=>/(?:patch failed: |error: )([^\s:]+?)(?::| ?:?\s*(?:patch does not apply|does not exist))/.exec(e)?.[1]).filter(e=>!!e&&e!==`error`))]}function Rn(e,t){try{return X(e,[`rev-parse`,`HEAD`])!==t}catch{return!1}}function zn(e,t){if(!t.trim())return!0;try{return A(`git`,[`-C`,e,`apply`,`--check`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]}),!0}catch{return!1}}function Bn(e,t){if(!t.trim())return{applied:!0,conflictPaths:[]};try{A(`git`,[`-C`,e,`apply`,`--check`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]})}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}try{return A(`git`,[`-C`,e,`apply`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]}),{applied:!0,conflictPaths:[]}}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}}function Vn(e,t){if(!t.trim())return{applied:!0,conflictPaths:[]};try{A(`git`,[`-C`,e,`apply`,`--reverse`,`--check`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]})}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}try{return A(`git`,[`-C`,e,`apply`,`--reverse`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]}),{applied:!0,conflictPaths:[]}}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}}function Q(e,t){try{X(e.repoRoot,[`worktree`,`remove`,`--force`,e.path])}catch(e){t?.(`worktree remove`,e)}try{X(e.repoRoot,[`branch`,`-D`,e.branch])}catch(e){t?.(`branch delete`,e)}try{X(e.repoRoot,[`worktree`,`prune`])}catch(e){t?.(`worktree prune`,e)}}function Hn(e){let t=[],n;try{n=p(j(M()),`otto-wt-`)}catch{return t}let r;try{r=X(e,[`worktree`,`list`,`--porcelain`])}catch{return t}let i=r.split(`
18
+ `);if(e===-1)break;let t=this._stderrBuf.slice(0,e).replace(/\r$/,``);this._stderrBuf=this._stderrBuf.slice(e+1),this.emit(`stderrLine`,t)}}),t.signal){let e=()=>{this.kill({reason:`aborted`})};t.signal.aborted?e():t.signal.addEventListener(`abort`,e,{once:!0})}}get pid(){return this._pid}get pgid(){return this._pgid}get stdin(){return this.child.stdin&&!this.child.stdin.destroyed?this.child.stdin:null}get stdout(){return this.child.stdout&&!this.child.stdout.destroyed?this.child.stdout:null}get stderr(){return this.child.stderr&&!this.child.stderr.destroyed?this.child.stderr:null}get command(){return this.config.command}get cwd(){return this.config.cwd}get logPath(){return this.config.logPath}get port(){return this.config.port}get url(){return this.config.url}get exitCode(){return this._exitResult?.code??void 0}get detectedService(){return this._detectedService}setDetectedService(e){this._detectedService=e}onStdoutLine(e){return this.on(`stdoutLine`,e),()=>this.off(`stdoutLine`,e)}onStderrLine(e){return this.on(`stderrLine`,e),()=>this.off(`stderrLine`,e)}onExit(e){return this.on(`exit`,e),()=>this.off(`exit`,e)}onError(e){return this.on(`error`,e),()=>this.off(`error`,e)}async kill(e){if(this.status===`killed`||this.status===`exited`)return;this.status=`killing`,this.lastUsed=this._clock();let t=e?.graceMs??this.config.killGraceMs??2e3,n=this._pid,r=this._pgid;if(!n||!q(n)){this.status=`killed`;return}if(process.platform===`win32`){Y(n),this.status=`killed`;return}J(r??n,`SIGTERM`),await new Promise(e=>{let r=!1,i=t=>{r||(r=!0,clearTimeout(o),e(t))},a=()=>i(!0);if(this.child.once(`exit`,a),!q(n)){i(!0);return}let o=setTimeout(()=>{this.child.removeListener(`exit`,a),i(!1)},t)})||J(r??n,`SIGKILL`),this.status=`killed`}async waitForExit(e=3e4){return this._exitResult?this._exitResult:new Promise(t=>{if(this._exitResult){t(this._exitResult);return}let n=!1,r=e=>{n||(n=!0,clearTimeout(a),this.off(`exit`,i),t(e))},i=e=>r(e);this.on(`exit`,i);let a=setTimeout(()=>{r({code:null,signal:null,timedOut:!0})},e)})}},Fn=class{_entries=new Map;_maxProcesses;killGraceMs;killTimeoutMs;_clock;_spawnListeners=new Set;_exitListeners=new Set;constructor(e={}){this._maxProcesses=e.maxProcesses??128,this.killGraceMs=e.killGraceMs??2e3,this.killTimeoutMs=e.killTimeoutMs??3e4,this._clock=e.clock??(()=>Date.now())}onSpawn(e){return this._spawnListeners.add(e),()=>this._spawnListeners.delete(e)}onExit(e){return this._exitListeners.add(e),()=>this._exitListeners.delete(e)}onAllExited(e){let t=()=>{this._entries.size===0&&e()},n=()=>t();return this._exitListeners.add(n),t(),()=>this._exitListeners.delete(n)}spawn(e){if(this._entries.size>=this._maxProcesses&&this._evictLeastRecent(),this._entries.size>=this._maxProcesses)throw Error(`Process limit (${this._maxProcesses}) reached. Stop unused processes first.`);let t={...e.options,stdio:e.options?.stdio??[`pipe`,`pipe`,`pipe`],cwd:e.cwd??e.options?.cwd,env:u(e.env??e.options?.env),...e.keepAlive===!0?{}:{detached:!0}},n=Ue(e.command,e.args??[],t),r=new Pn(n,e,this._clock);this._entries.set(r.id,{proc:r,child:n}),r.onExit(()=>{if(!this._entries.get(r.id))return;let t=e.lifecycle??`evictable`;e.keepAlive!==!0&&t!==`pinned`&&this._entries.delete(r.id);for(let e of[...this._exitListeners])try{e(r)}catch{}});for(let e of[...this._spawnListeners])try{e(r)}catch{}return r}get(e){return this._entries.get(e)?.proc}list(e){let t=[...this._entries.values()];return e?.owner&&(t=t.filter(t=>t.proc.config.owner.type===e.owner.type&&t.proc.config.owner.id===e.owner.id)),e?.sessionId&&(t=t.filter(t=>t.proc.config.sessionId===e.sessionId)),e?.category&&(t=t.filter(t=>t.proc.config.category===e.category)),t.map(e=>e.proc)}listForSession(e){return this.list({sessionId:e})}getForSession(e,t){let n=this._entries.get(t)?.proc;if(!(!n||n.config.sessionId!==e))return n}async kill(e,t){let n=this._entries.get(e);n&&await n.proc.kill(t)}updateDetectedService(e,t){let n=this._entries.get(e);n&&(n.proc.detectedService?.url&&!t.url||(n.proc.setDetectedService(t),this.touch(e)))}listForOwner(e){return this.list({owner:e})}touch(e){let t=this._entries.get(e);t&&(t.proc.lastUsed=this._clock())}remove(e){this._entries.delete(e)}size(){return this._entries.size}async killAll(e,t){let n=this.list(e).filter(e=>!e.config.keepAlive);await Promise.all(n.map(e=>e.kill(t)))}killAllSync(){let e=process.platform===`win32`,t=[];for(let[n,r]of this._entries){let i=r.proc;if(i.config.keepAlive||i.status!==`running`&&i.status!==`starting`)continue;let a=i.pid;a&&(e?t.push(a):J(i.pgid??a,`SIGKILL`),this._entries.delete(n))}if(e&&t.length>0)try{We(`taskkill`,[`/F`,`/T`,...t.map(String).flatMap(e=>[`/PID`,e])],{stdio:`ignore`,timeout:5e3})}catch{}}async killAllForOwner(e,t){return this.killAll({owner:{type:e,id:t}})}async killAllForSession(e){return this.killAll({sessionId:e})}registerChild(e,t){if(this._entries.size>=this._maxProcesses&&this._evictLeastRecent(),this._entries.size>=this._maxProcesses)throw Error(`Process limit (${this._maxProcesses}) reached. Stop unused processes first.`);let n=new Pn(t,e,this._clock);this._entries.set(n.id,{proc:n,child:t}),n.onExit(()=>{if(!this._entries.get(n.id))return;let t=e.lifecycle??`evictable`;e.keepAlive!==!0&&t!==`pinned`&&this._entries.delete(n.id);for(let e of[...this._exitListeners])try{e(n)}catch{}});for(let e of[...this._spawnListeners])try{e(n)}catch{}return n}_evictLeastRecent(){let e;for(let t of this._entries.values()){let n=t.proc.config,r=n.lifecycle??`evictable`;if(t.proc.status===`exited`||t.proc.status===`killed`||t.proc.status===`errored`){e=t;break}n.keepAlive||r!==`pinned`&&(!e||t.proc.lastUsed<e.proc.lastUsed)&&(e=t)}if(!e)return;let t=e.proc.pid;t&&q(t)&&(process.platform===`win32`?Y(t):J(e.proc.pgid??t,`SIGKILL`)),this._entries.delete(e.proc.id)}};const In=new Fn;let Ln=!1;function Rn(e=In){Ln||(Ln=!0,process.on(`exit`,()=>{e.killAllSync()}))}function X(e,t){return A(`git`,[`-C`,e,...t],{encoding:`utf-8`,stdio:[`ignore`,`pipe`,`pipe`]}).trimEnd()}function zn(e,t){let n=X(e,[`rev-parse`,`HEAD`]),r=`otto/job-${t}`,i=p(Je(p(M(),`otto-wt-`)),`job-${t}`);return X(e,[`worktree`,`add`,`-b`,r,i,n]),{path:i,branch:r,base:n,repoRoot:e}}function Bn(e){return X(e.path,[`add`,`-A`]),A(`git`,[`-C`,e.path,`diff`,`--cached`,`--binary`],{encoding:`utf-8`,maxBuffer:256*1024*1024})}function Z(e){return[...new Set(e.split(`
19
+ `).map(e=>/(?:patch failed: |error: )([^\s:]+?)(?::| ?:?\s*(?:patch does not apply|does not exist))/.exec(e)?.[1]).filter(e=>!!e&&e!==`error`))]}function Vn(e,t){try{return X(e,[`rev-parse`,`HEAD`])!==t}catch{return!1}}function Hn(e,t){if(!t.trim())return!0;try{return A(`git`,[`-C`,e,`apply`,`--check`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]}),!0}catch{return!1}}function Un(e,t){if(!t.trim())return{applied:!0,conflictPaths:[]};try{A(`git`,[`-C`,e,`apply`,`--check`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]})}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}try{return A(`git`,[`-C`,e,`apply`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]}),{applied:!0,conflictPaths:[]}}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}}function Wn(e,t){if(!t.trim())return{applied:!0,conflictPaths:[]};try{A(`git`,[`-C`,e,`apply`,`--reverse`,`--check`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]})}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}try{return A(`git`,[`-C`,e,`apply`,`--reverse`,`--whitespace=nowarn`],{input:t,stdio:[`pipe`,`pipe`,`pipe`]}),{applied:!0,conflictPaths:[]}}catch(e){return{applied:!1,conflictPaths:Z(String(e.stderr??``))}}}function Q(e,t){try{X(e.repoRoot,[`worktree`,`remove`,`--force`,e.path])}catch(e){t?.(`worktree remove`,e)}try{X(e.repoRoot,[`branch`,`-D`,e.branch])}catch(e){t?.(`branch delete`,e)}try{X(e.repoRoot,[`worktree`,`prune`])}catch(e){t?.(`worktree prune`,e)}}function Gn(e){let t=[],n;try{n=p(j(M()),`otto-wt-`)}catch{return t}let r;try{r=X(e,[`worktree`,`list`,`--porcelain`])}catch{return t}let i=r.split(`
19
20
 
20
21
  `);for(let e of i){let r=e.split(`
21
- `),i=``,a=``;for(let e of r)e.startsWith(`worktree `)?i=e.slice(9):e.startsWith(`branch `)&&(a=e.slice(7));if(!i||!a)continue;let o=/^refs\/heads\/otto\/job-(.+)$/.exec(a);if(o){try{if(!j(i).startsWith(n))continue}catch{continue}t.push(o[1])}}return t}function Un(e,t){let n=new Set(t),r=[],i;try{i=p(j(M()),`otto-wt-`)}catch{return r}let a;try{a=X(e,[`worktree`,`list`,`--porcelain`])}catch{return r}let o=a.split(`
22
+ `),i=``,a=``;for(let e of r)e.startsWith(`worktree `)?i=e.slice(9):e.startsWith(`branch `)&&(a=e.slice(7));if(!i||!a)continue;let o=/^refs\/heads\/otto\/job-(.+)$/.exec(a);if(o){try{if(!j(i).startsWith(n))continue}catch{continue}t.push(o[1])}}return t}function Kn(e,t){let n=new Set(t),r=[],i;try{i=p(j(M()),`otto-wt-`)}catch{return r}let a;try{a=X(e,[`worktree`,`list`,`--porcelain`])}catch{return r}let o=a.split(`
22
23
 
23
24
  `);for(let t of o){let a=t.split(`
24
- `),o=``,s=``;for(let e of a)e.startsWith(`worktree `)?o=e.slice(9):e.startsWith(`branch `)&&(s=e.slice(7));if(!o||!s)continue;let c=/^refs\/heads\/otto\/job-(.+)$/.exec(s);if(!c)continue;let l=c[1],u;try{u=j(o)}catch{continue}if(u.startsWith(i)&&!n.has(l)){try{X(e,[`worktree`,`remove`,`--force`,o])}catch{}try{X(e,[`branch`,`-D`,s.slice(11)])}catch{}r.push(o)}}try{X(e,[`worktree`,`prune`])}catch{}return r}const Wn=[/(^|\/)governance\/forbidden-zone\./,/(^|\/)packages\/setting\//,/(^|\/)permission/i,/(^|\/)sandbox/i,/(^|\/)git-worktree\./,/(^|\/)agent-job-service\./,/(^|\/)mcp-controller\./,/(^|\/)packages\/mcp\/src\/oauth\//,/(allowlist|allow-list|egress|networkpolicy)/i];function Gn(e){if(e.length<2||!e.startsWith(`"`)||!e.endsWith(`"`))return e;let t=e.slice(1,-1),n=[];for(let e=0;e<t.length;e++){if(t[e]!==`\\`){n.push(t.charCodeAt(e));continue}let r=t[e+1];r&&r>=`0`&&r<=`7`?(n.push(parseInt(t.slice(e+1,e+4),8)),e+=3):(n.push({t:9,n:10,r:13,'"':34,"\\":92}[r]??(r?r.charCodeAt(0):92)),e+=1)}return Buffer.from(n).toString(`utf-8`)}function Kn(e){let t=Gn(e.trim());return t===`/dev/null`?null:t.replace(/^[ab]\//,``)}function qn(e){let t=/^("(?:[^"\\]|\\.)*") ("(?:[^"\\]|\\.)*")$/.exec(e);if(t)return[t[1],t[2]];let n=/^(a\/.+?) (b\/.+)$/.exec(e);return n?[n[1],n[2]]:[]}function Jn(e){let t=new Set;for(let n of e.split(`
25
- `)){if(n.startsWith(`diff --git `)){for(let e of qn(n.slice(11))){let n=Kn(e);n&&t.add(n)}continue}if(/^\+\+\+ "?[ab]\//.test(n)||/^--- "?[ab]\//.test(n)){let e=Kn(n.slice(4));e&&t.add(e)}}return[...t]}function Yn(e){return e.trim()?Jn(e).filter(e=>Wn.some(t=>t.test(e))):[]}const Xn=[/(^|\/)\.otto\/(agents|skills|teams)\//i,/(^|\/)\.otto\/[^/]*config/i,/(^|\/)otto\.config\./i];function Zn(e){return e.trim()?Jn(e).filter(e=>Xn.some(t=>t.test(e))):[]}const Qn=200;function $n(e,t){let{forbiddenZone:n,capabilityTouched:r,diffStat:i,conflict:a,origin:o}=e,s=t.maxAutoApplyLines??200,c=i.added+i.removed;if(o!==`user`&&n.length>0)return{action:`forbid`,reasons:[`触及治理禁区(高危自我修改):${n.join(`, `)}`]};if(o===`plugin`){let e=[`插件发起的作业需人手 apply(RFC-287 R2)`];return r.length&&e.push(`触及能力面:${r.join(`, `)}`),a&&e.push(`存在冲突`),c>s&&e.push(`改动较大(${c} 行 > ${s})`),{action:`gate`,reasons:e}}if(o===`user`){let e=[];return n.length&&e.push(`触及治理禁区:${n.join(`, `)}`),r.length&&e.push(`触及能力面:${r.join(`, `)}`),a&&e.push(`存在冲突,无法干净落地`),{action:`advise`,recommend:e.length?`review`:`apply`,reasons:e}}if(t.level<=1){let e=[];return r.length&&e.push(`触及能力面:${r.join(`, `)}`),a&&e.push(`存在冲突`),c>s&&e.push(`改动较大(${c} 行 > ${s})`),t.level===0?{action:`gate`,reasons:[`autonomy L0:需人手 apply`,...e]}:{action:`advise`,recommend:e.length?`review`:`apply`,reasons:e}}let l=[];return a&&l.push(`apply 有冲突`),c>s&&l.push(`改动超规模(${c} 行 > ${s})`),r.length&&t.level<3&&l.push(`触及能力面(需 L3+):${r.join(`, `)}`),l.length?{action:`gate`,reasons:l}:{action:`auto`}}function er(e){return{id:e.id,sessionId:e.sessionId,title:e.title,origin:e.origin,status:e.status,repoRoot:e.worktree.repoRoot,branch:e.worktree.branch,worktreePath:e.worktree.path,outputPath:e.outputPath,startedAt:e.startedAt,error:e.error}}function tr(e){return Le(`sha1`).update(e).digest(`hex`).slice(0,12)}function nr(e,t){return m(e,`${tr(t)}.jsonl`)}var rr=class{constructor(e){this.stateDir=e,qe(this.stateDir,{recursive:!0})}append(e){try{Ke(nr(this.stateDir,e.repoRoot),`${JSON.stringify(e)}\n`,`utf-8`)}catch{}}load(){let e=new Map;try{let t=ir(this.stateDir);for(let n of t){if(!n.endsWith(`.jsonl`))continue;let t=ar(m(this.stateDir,n));for(let n of t){let t=n.trim();if(t)try{let n=JSON.parse(t);n?.id&&n?.status&&e.set(n.id,n)}catch{}}}}catch{}return or([...e.values()])}remove(e,t){let n=nr(this.stateDir,t);try{let t=ar(n).filter(t=>{try{return JSON.parse(t).id!==e}catch{return!0}});Ze(n,t.join(`
25
+ `),o=``,s=``;for(let e of a)e.startsWith(`worktree `)?o=e.slice(9):e.startsWith(`branch `)&&(s=e.slice(7));if(!o||!s)continue;let c=/^refs\/heads\/otto\/job-(.+)$/.exec(s);if(!c)continue;let l=c[1],u;try{u=j(o)}catch{continue}if(u.startsWith(i)&&!n.has(l)){try{X(e,[`worktree`,`remove`,`--force`,o])}catch{}try{X(e,[`branch`,`-D`,s.slice(11)])}catch{}r.push(o)}}try{X(e,[`worktree`,`prune`])}catch{}return r}const qn=[/(^|\/)governance\/forbidden-zone\./,/(^|\/)packages\/setting\//,/(^|\/)permission/i,/(^|\/)sandbox/i,/(^|\/)git-worktree\./,/(^|\/)agent-job-service\./,/(^|\/)mcp-controller\./,/(^|\/)packages\/mcp\/src\/oauth\//,/(allowlist|allow-list|egress|networkpolicy)/i];function Jn(e){if(e.length<2||!e.startsWith(`"`)||!e.endsWith(`"`))return e;let t=e.slice(1,-1),n=[];for(let e=0;e<t.length;e++){if(t[e]!==`\\`){n.push(t.charCodeAt(e));continue}let r=t[e+1];r&&r>=`0`&&r<=`7`?(n.push(parseInt(t.slice(e+1,e+4),8)),e+=3):(n.push({t:9,n:10,r:13,'"':34,"\\":92}[r]??(r?r.charCodeAt(0):92)),e+=1)}return Buffer.from(n).toString(`utf-8`)}function Yn(e){let t=Jn(e.trim());return t===`/dev/null`?null:t.replace(/^[ab]\//,``)}function Xn(e){let t=/^("(?:[^"\\]|\\.)*") ("(?:[^"\\]|\\.)*")$/.exec(e);if(t)return[t[1],t[2]];let n=/^(a\/.+?) (b\/.+)$/.exec(e);return n?[n[1],n[2]]:[]}function Zn(e){let t=new Set;for(let n of e.split(`
26
+ `)){if(n.startsWith(`diff --git `)){for(let e of Xn(n.slice(11))){let n=Yn(e);n&&t.add(n)}continue}if(/^\+\+\+ "?[ab]\//.test(n)||/^--- "?[ab]\//.test(n)){let e=Yn(n.slice(4));e&&t.add(e)}}return[...t]}function Qn(e){return e.trim()?Zn(e).filter(e=>qn.some(t=>t.test(e))):[]}const $n=[/(^|\/)\.otto\/(agents|skills|teams)\//i,/(^|\/)\.otto\/[^/]*config/i,/(^|\/)otto\.config\./i];function er(e){return e.trim()?Zn(e).filter(e=>$n.some(t=>t.test(e))):[]}const tr=200;function nr(e,t){let{forbiddenZone:n,capabilityTouched:r,diffStat:i,conflict:a,origin:o}=e,s=t.maxAutoApplyLines??200,c=i.added+i.removed;if(o!==`user`&&n.length>0)return{action:`forbid`,reasons:[`触及治理禁区(高危自我修改):${n.join(`, `)}`]};if(o===`plugin`){let e=[`插件发起的作业需人手 apply(RFC-287 R2)`];return r.length&&e.push(`触及能力面:${r.join(`, `)}`),a&&e.push(`存在冲突`),c>s&&e.push(`改动较大(${c} 行 > ${s})`),{action:`gate`,reasons:e}}if(o===`user`){let e=[];return n.length&&e.push(`触及治理禁区:${n.join(`, `)}`),r.length&&e.push(`触及能力面:${r.join(`, `)}`),a&&e.push(`存在冲突,无法干净落地`),{action:`advise`,recommend:e.length?`review`:`apply`,reasons:e}}if(t.level<=1){let e=[];return r.length&&e.push(`触及能力面:${r.join(`, `)}`),a&&e.push(`存在冲突`),c>s&&e.push(`改动较大(${c} 行 > ${s})`),t.level===0?{action:`gate`,reasons:[`autonomy L0:需人手 apply`,...e]}:{action:`advise`,recommend:e.length?`review`:`apply`,reasons:e}}let l=[];return a&&l.push(`apply 有冲突`),c>s&&l.push(`改动超规模(${c} 行 > ${s})`),r.length&&t.level<3&&l.push(`触及能力面(需 L3+):${r.join(`, `)}`),l.length?{action:`gate`,reasons:l}:{action:`auto`}}function rr(e){return{id:e.id,sessionId:e.sessionId,title:e.title,origin:e.origin,status:e.status,repoRoot:e.worktree.repoRoot,branch:e.worktree.branch,worktreePath:e.worktree.path,outputPath:e.outputPath,startedAt:e.startedAt,error:e.error}}function ir(e){return Le(`sha1`).update(e).digest(`hex`).slice(0,12)}function ar(e,t){return m(e,`${ir(t)}.jsonl`)}var or=class{constructor(e){this.stateDir=e,qe(this.stateDir,{recursive:!0})}append(e){try{Ke(ar(this.stateDir,e.repoRoot),`${JSON.stringify(e)}\n`,`utf-8`)}catch{}}load(){let e=new Map;try{let t=sr(this.stateDir);for(let n of t){if(!n.endsWith(`.jsonl`))continue;let t=cr(m(this.stateDir,n));for(let n of t){let t=n.trim();if(t)try{let n=JSON.parse(t);n?.id&&n?.status&&e.set(n.id,n)}catch{}}}}catch{}return lr([...e.values()])}remove(e,t){let n=ar(this.stateDir,t);try{let t=cr(n).filter(t=>{try{return JSON.parse(t).id!==e}catch{return!0}});Ze(n,t.join(`
26
27
  `)+(t.length>0?`
27
- `:``),`utf-8`)}catch{}}};function ir(e){try{return Xe(e)}catch{return[]}}function ar(e){try{return Ye(e,`utf-8`).split(`
28
- `)}catch{return[]}}function or(e){let t=new Map;for(let n of e){let e=t.get(n.repoRoot)??[];e.push(n),t.set(n.repoRoot,e)}let n=[];for(let e of t.values()){let t=e.filter(e=>e.status!==`applied`&&e.status!==`failed`&&e.status!==`canceled`),r=e.filter(e=>e.status===`applied`||e.status===`failed`||e.status===`canceled`).sort((e,t)=>t.startedAt-e.startedAt).slice(0,100);n.push(...t,...r)}return n}const $=new Set([`applied`,`failed`,`canceled`]);var sr=class{entries=new Map;maxJobs;clock;onWorktreeCleanupError;stateStore;spawnListeners=new Set;updateListeners=new Set;exitListeners=new Set;removeListeners=new Set;retained=new Set;constructor(e={}){this.maxJobs=e.maxJobs??16,this.clock=e.clock??(()=>Date.now()),this.onWorktreeCleanupError=e.onWorktreeCleanupError}setWorktreeCleanupErrorHandler(e){this.onWorktreeCleanupError=e}setStateStore(e){this.stateStore=e}onSpawn(e){return this.spawnListeners.add(e),()=>this.spawnListeners.delete(e)}onUpdate(e){return this.updateListeners.add(e),()=>this.updateListeners.delete(e)}onExit(e){return this.exitListeners.add(e),()=>this.exitListeners.delete(e)}onRemove(e){return this.removeListeners.add(e),()=>this.removeListeners.delete(e)}retain(e,t){t?this.retained.add(e):this.retained.delete(e)}restore(e){if(this.entries.has(e.id)||e.status===`running`||e.status===`needs_input`)return;let t={id:e.id,type:`agent-session`,sessionId:e.sessionId,title:e.title,origin:e.origin,status:e.status,worktree:{path:e.worktreePath,branch:e.branch,base:e.branch.replace(`otto/job-`,``),repoRoot:e.repoRoot},outputPath:e.outputPath,startedAt:e.startedAt,diff:e.diff,error:e.error};return this.entries.set(e.id,{info:t,abort:()=>{}}),t}appendState(e){this.stateStore&&this.stateStore.append(er(e))}notify(e,t){for(let n of[...e])try{n(t)}catch{}}register(e){if(this.entries.size>=this.maxJobs&&this.evictTerminal(),this.entries.size>=this.maxJobs)throw Error(`Agent job limit (${this.maxJobs}) reached; cancel one with stop first.`);let t=e.now??this.clock(),n={id:e.id,sessionId:e.sessionId,type:`agent-session`,title:e.title,origin:e.origin??`user`,status:`running`,worktree:e.worktree,outputPath:e.outputPath,startedAt:t};return this.entries.set(e.id,{info:n,abort:e.abort}),this.appendState(n),this.notify(this.spawnListeners,n),n}get(e){return this.entries.get(e)?.info}getForSession(e,t){let n=this.entries.get(t);return n&&n.info.sessionId===e?n.info:void 0}list(){return[...this.entries.values()].map(e=>e.info)}listForSession(e){return this.list().filter(t=>t.sessionId===e)}size(){return this.entries.size}update(e,t){let n=this.entries.get(e);n&&($.has(n.info.status)||(Object.assign(n.info,t),this.appendState(n.info),this.notify(this.updateListeners,n.info),$.has(n.info.status)&&(n.info.status!==`canceled`&&Q(n.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),this.notify(this.exitListeners,n.info))))}cancel(e){let t=this.entries.get(e);if(!(!t||$.has(t.info.status))){try{t.abort()}catch{}Q(t.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),this.update(e,{status:`canceled`})}}remove(e){let t=this.entries.get(e);t&&Q(t.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),this.retained.delete(e),this.entries.delete(e),t&&this.stateStore&&this.stateStore.remove(e,t.info.worktree.repoRoot),t&&this.notify(this.removeListeners,t.info)}evictTerminal(){for(let[e,t]of this.entries)if($.has(t.info.status)&&!this.retained.has(e)){this.remove(e);return}}cleanupAll(){for(let[e,t]of this.entries)if(!$.has(t.info.status)){try{t.abort()}catch{}Q(t.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),t.info.status=`canceled`}}};const cr=new sr;let lr=!1;function ur(e=cr,t,n){if(!lr){if(lr=!0,n&&t)for(let r of n.load())r.repoRoot===t&&e.restore(r);if(t){let r=Hn(t),i=new Map;if(n)for(let e of n.load())e.repoRoot===t&&i.set(e.id,e);let a=e=>({path:dr(e),branch:`otto/job-${e}`,base:``,repoRoot:t});for(let t of r){let n=i.get(t);if(!e.get(t)){if(!n){fr(t)||Q(a(t),(n,r)=>e.onWorktreeCleanupError?.(t,n,r));continue}if(!(n.status===`running`||n.status===`needs_input`)&&(n.status===`applied`||n.status===`failed`||n.status===`canceled`)){Q(a(t),(n,r)=>e.onWorktreeCleanupError?.(t,n,r));continue}}}}if(t){let n=new Set(e.list().map(e=>e.id));for(let e of Hn(t))n.add(e);Un(t,n)}process.on(`exit`,()=>{e.cleanupAll()})}}function dr(e){return p(j(M()),`otto-wt-`,`job-${e}`)}function fr(e){try{return A(`git`,[`-C`,dr(e),`status`,`--porcelain`],{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`]}).trim().length>0}catch{return!1}}const pr=new Set([`done`,`error`,`aborted`]),mr=new Set([`edit`,`write`,`delete`,`edit_file`,`write_file`]);function hr(e){return mr.has(e)}var gr=class extends l{observations=new Map;abortFns=new Map;messagesRefs=new Map;streamingTexts=new Map;turns=new Map;evictTimers=new Map;pinned=new Set;now;warnMs;stalledMs;evictMs;constructor(e={}){super(),this.now=e.now??Date.now,this.warnMs=e.warnMs??3e3,this.stalledMs=e.stalledMs??3e4,this.evictMs=e.evictMs??15e3}register(e){let t=this.now(),n=this.evictTimers.get(e.id);n&&(clearTimeout(n),this.evictTimers.delete(e.id)),e.abort&&this.abortFns.set(e.id,e.abort),e.messages&&this.messagesRefs.set(e.id,e.messages),this.streamingTexts.set(e.id,``),this.turns.set(e.id,[]),this.observations.set(e.id,{id:e.id,agentName:e.agentName,title:e.title,prompt:e.prompt,model:e.model,modelDecidedBy:e.modelDecidedBy,origin:e.origin??`main`,depth:e.depth??0,status:`streaming`,turnIndex:0,toolUseCount:0,filesEdited:0,tokenCount:0,inputTokens:0,lastActivity:`starting`,lastEventAt:t,abortable:e.abortable??e.abort!==void 0,startedAt:t}),this.emit(`change`)}abort(e){let t=this.observations.get(e),n=this.abortFns.get(e);return!t||!n||pr.has(t.status)?!1:(n(),!0)}record(e,t){let n=this.observations.get(e);if(!n)return;n.lastEventAt=this.now();let r=!0;switch(t.type){case`turn.start`:n.turnIndex=t.turnIndex,n.status=`streaming`,n.lastActivity=`thinking`,n.blockedOn=`model_io`,n.blockDetail=void 0,this.streamingTexts.set(e,``),this.turns.get(e)?.push({index:t.turnIndex,startedAt:this.now(),toolCount:0,tools:[],outputTokens:0});break;case`stream.event`:{let i=t.event;i.type===`text_delta`?(n.lastActivity=`responding`,n.blockedOn=void 0,this.streamingTexts.set(e,(this.streamingTexts.get(e)??``)+i.delta)):i.type.startsWith(`thinking`)&&(n.lastActivity=`thinking`,n.blockedOn=void 0),r=!1;break}case`tool.call.start`:{n.toolUseCount+=1,n.status=`tool_executing`,n.lastActivity=`using ${t.toolCall.name}`,n.blockedOn=`process`,n.blockDetail=t.toolCall.name;let r=this.turns.get(e);r?.length&&(r[r.length-1].toolCount+=1,r[r.length-1].tools.push(t.toolCall.name));break}case`tool.call.end`:n.status=`streaming`,n.lastActivity=`thinking`,n.blockedOn=`model_io`,n.blockDetail=void 0,hr(t.toolCall.name)&&(n.filesEdited+=1);break;case`turn.end`:{let r=t.message.usage.outputTokens??0;n.tokenCount+=r,n.inputTokens=t.message.usage.inputTokens??n.inputTokens,this.streamingTexts.set(e,``);let i=this.turns.get(e),a=i?.[i.length-1];a&&a.endedAt===void 0&&(a.endedAt=this.now(),a.outputTokens=r);break}case`stream.retry`:n.lastActivity=`reconnecting ${t.attempt}/${t.maxRetries}`,n.blockedOn=`model_io`;break;case`status.change`:this.applyTerminal(n,t.to);break;case`error`:this.markTerminal(n,`error`);break;case`abort`:this.markTerminal(n,`aborted`);break;case`lifecycle.tool.completed`:n.lastActivity=`${t.toolName} ${t.isError?`failed`:`completed`} (background)`,n.lastEventAt=this.now(),r=!0;break;case`lifecycle.tool.completed.crossBoundary`:n.lastActivity=`${t.toolName} completed in background (result not shown — belongs to a previous prompt)`,n.lastEventAt=this.now(),r=!0;break;default:r=!1;break}r&&this.emit(`change`)}setAwaitingApproval(e,t){let n=this.observations.get(e);n&&(n.status=`awaiting_gate`,n.lastActivity=`awaiting approval`,n.blockedOn=`approval`,n.blockDetail=t,n.lastEventAt=this.now(),this.emit(`change`))}clearAwaitingApproval(e){let t=this.observations.get(e);!t||t.status!==`awaiting_gate`||(t.status=`streaming`,t.lastActivity=`thinking`,t.blockedOn=`model_io`,t.blockDetail=void 0,t.lastEventAt=this.now(),this.emit(`change`))}setToolWaiting(e,t){let n=this.observations.get(e);n&&(n.status=`tool_waiting`,n.lastActivity=t,n.blockedOn=`process`,n.blockDetail=t,n.lastEventAt=this.now(),this.emit(`change`))}clearToolWaiting(e){let t=this.observations.get(e);!t||t.status!==`tool_waiting`||(t.status=`streaming`,t.lastActivity=`thinking`,t.blockedOn=`model_io`,t.blockDetail=void 0,t.lastEventAt=this.now(),this.emit(`change`))}markEnded(e,t=`done`){let n=this.observations.get(e);!n||pr.has(n.status)||(this.markTerminal(n,t),this.emit(`change`))}pin(e){let t=this.evictTimers.get(e);t&&(clearTimeout(t),this.evictTimers.delete(e)),this.pinned.add(e)}unpin(e){this.pinned.delete(e);let t=this.observations.get(e);t&&t.endedAt!==void 0&&this.scheduleEvict(e)}remove(e){let t=this.evictTimers.get(e);t&&(clearTimeout(t),this.evictTimers.delete(e)),this.observations.delete(e),this.abortFns.delete(e),this.messagesRefs.delete(e),this.streamingTexts.delete(e),this.turns.delete(e),this.pinned.delete(e),this.emit(`change`)}get(e){let t=this.observations.get(e);return t?this.toSnapshot(t):void 0}getMessages(e){let t=this.messagesRefs.get(e);if(t)return[...typeof t==`function`?t():t]}setMessages(e,t){this.messagesRefs.has(e)&&this.messagesRefs.set(e,[...t])}getStreamingText(e){return this.streamingTexts.get(e)??``}getTurns(e){let t=this.turns.get(e);return t?t.map(e=>({...e,tools:[...e.tools]})):[]}list(){return[...this.observations.values()].map(e=>this.toSnapshot(e))}listActive(){return this.list().filter(e=>!pr.has(e.status))}subscribe(e){return this.on(`change`,e)}clear(){for(let e of this.evictTimers.values())clearTimeout(e);this.evictTimers.clear(),this.observations.clear(),this.abortFns.clear(),this.messagesRefs.clear(),this.streamingTexts.clear(),this.turns.clear(),this.pinned.clear()}applyTerminal(e,t){t===`completed`?this.markTerminal(e,`done`):t===`error`?this.markTerminal(e,`error`):t===`aborted`&&this.markTerminal(e,`aborted`)}markTerminal(e,t){e.status=t,e.lastActivity=t,e.blockedOn=void 0,e.blockDetail=void 0,e.endedAt=this.now(),this.scheduleEvict(e.id)}scheduleEvict(e){if(this.pinned.has(e))return;let t=this.evictTimers.get(e);t&&clearTimeout(t);let n=setTimeout(()=>{this.observations.delete(e),this.evictTimers.delete(e),this.abortFns.delete(e),this.messagesRefs.delete(e),this.streamingTexts.delete(e),this.turns.delete(e),this.emit(`change`)},this.evictMs);n.unref?.(),this.evictTimers.set(e,n)}toSnapshot(e){let t=e.endedAt!==void 0,n=t?0:Math.max(0,this.now()-e.lastEventAt),r=t?`none`:n>this.stalledMs?`stalled`:n>this.warnMs?`warn`:`none`;return{...e,idleMs:n,stall:r}}};const _r=new gr;function vr(e,t,n=_r){n.register(t);let r=t.id,i=[e.on(`turn.start`,e=>n.record(r,{type:`turn.start`,...e})),e.on(`turn.end`,e=>n.record(r,{type:`turn.end`,...e})),e.on(`stream.event`,e=>n.record(r,{type:`stream.event`,...e})),e.on(`tool.call.start`,e=>n.record(r,{type:`tool.call.start`,...e})),e.on(`tool.call.end`,e=>n.record(r,{type:`tool.call.end`,...e})),e.on(`status.change`,e=>n.record(r,{type:`status.change`,...e})),e.on(`stream.retry`,e=>n.record(r,{type:`stream.retry`,...e})),e.on(`error`,e=>n.record(r,{type:`error`,...e})),e.on(`abort`,()=>n.record(r,{type:`abort`})),e.on(`lifecycle.tool.completed`,e=>n.record(r,{type:`lifecycle.tool.completed`,...e})),e.on(`lifecycle.tool.completed.crossBoundary`,e=>n.record(r,{type:`lifecycle.tool.completed.crossBoundary`,...e}))];return()=>{for(let e of i)e()}}var yr=class{entries=new Map;disposed=!1;constructor(e){this.key=e}register(e){if(this.disposed)throw Error(`PlaneRegistry: workspace preset grid "${this.key}" already disposed, refusing registration (fail-closed)`);let t={...e,workspaceKey:this.key};return this.entries.set(t.id,t),t}unregister(e){return this.entries.delete(e)}unregisterByPlugin(e){let t=0;for(let[n,r]of this.entries)r.pluginId===e&&(this.entries.delete(n),t+=1);return t}list(){return[...this.entries.values()]}dispose(){this.entries.clear(),this.disposed=!0}},br=class{entries=new Map;disposed=!1;constructor(e){this.sessionId=e}register(e){if(this.disposed)throw Error(`PlaneRegistry: session preset grid "${this.sessionId}" already disposed, refusing registration (fail-closed)`);let t={...e,sessionId:this.sessionId};return this.entries.set(t.id,t),t}unregister(e){return this.entries.delete(e)}unregisterByPlugin(e){let t=0;for(let[n,r]of this.entries)r.pluginId===e&&(this.entries.delete(n),t+=1);return t}list(){return[...this.entries.values()]}dispose(){this.entries.clear(),this.disposed=!0}},xr=class{preset;constructor(e){this.workspaceKey=e,this.preset=new yr(e)}dispose(){this.preset.dispose()}},Sr=class{preset;constructor(e){this.sessionId=e,this.preset=new br(e)}dispose(){this.preset.dispose()}},Cr=class{hostEntries=new Map;workspaceScopes=new Map;sessionScopes=new Map;disposed=!1;ensureNotDisposed(){if(this.disposed)throw Error(`PlaneRegistry: HostRegistry already disposed (process lifecycle ended), refusing mutation (fail-closed)`)}register(e){this.ensureNotDisposed();let t={...e};return this.hostEntries.set(t.id,t),t}unregister(e){return this.hostEntries.delete(e)}unregisterByPlugin(e){let t=0;for(let[n,r]of this.hostEntries)r.pluginId===e&&(this.hostEntries.delete(n),t+=1);return t}list(){return[...this.hostEntries.values()]}workspace(e){this.ensureNotDisposed();let t=this.workspaceScopes.get(e);return t||(t=new xr(e),this.workspaceScopes.set(e,t)),t}session(e){this.ensureNotDisposed();let t=this.sessionScopes.get(e);return t||(t=new Sr(e),this.sessionScopes.set(e,t)),t}disposeWorkspaceGrid(e){let t=this.workspaceScopes.get(e);t&&(t.dispose(),this.workspaceScopes.delete(e))}migrateWorkspaceGrid(e,t){if(e===t)return;let n=this.workspaceScopes.get(e);if(!n)return;let r=this.workspace(t);for(let e of n.preset.list()){let{workspaceKey:t,...n}=e;r.preset.register(n)}this.disposeWorkspaceGrid(e)}disposeSessionGrid(e){let t=this.sessionScopes.get(e);t&&(t.dispose(),this.sessionScopes.delete(e))}unregisterByPluginEverywhere(e){let t=this.unregisterByPlugin(e);for(let n of this.workspaceScopes.values())t+=n.preset.unregisterByPlugin(e);for(let n of this.sessionScopes.values())t+=n.preset.unregisterByPlugin(e);return t}revalidatePlugin(e,t){let n=[];for(let r of this.hostEntries.values())r.pluginId===e&&r.pluginVersion!==t&&n.push({entry:r,registeredVersion:r.pluginVersion,currentVersion:t});for(let r of this.workspaceScopes.values())for(let i of r.preset.list())i.pluginId===e&&i.pluginVersion!==t&&n.push({entry:i,registeredVersion:i.pluginVersion,currentVersion:t});for(let r of this.sessionScopes.values())for(let i of r.preset.list())i.pluginId===e&&i.pluginVersion!==t&&n.push({entry:i,registeredVersion:i.pluginVersion,currentVersion:t});return n}resolveForEmit(e){let t=[...this.hostEntries.values()];if(e.workspaceKey!==void 0){let n=this.workspaceScopes.get(e.workspaceKey);n&&t.push(...n.preset.list())}if(e.sessionId!==void 0){let n=this.sessionScopes.get(e.sessionId);n&&t.push(...n.preset.list())}return t}listAll(){return[...this.hostEntries.values(),...this.workspaceScopes.values().flatMap(e=>[...e.preset.list()]),...this.sessionScopes.values().flatMap(e=>[...e.preset.list()])]}dispose(){for(let e of this.workspaceScopes.values())e.dispose();for(let e of this.sessionScopes.values())e.dispose();this.workspaceScopes.clear(),this.sessionScopes.clear(),this.hostEntries.clear(),this.disposed=!0}};function wr(e,t){let n=!1;return{id:`runtime:memory-index`,priority:w.agentKnowledge.priority,async contribute(e){if(!t)return;n||=(await t.loadMemory(),!0);let r=t.getMemoryPrompt();return r.trim()?r:void 0}}}function Tr(e){let t=0;for(let n of e)/[\u3000-\u9fff\uff00-\uffef]/.test(n)&&t++;return Math.ceil(t+(e.length-t)/4)}function Er(e,t){if(t<=0)return``;let n=t*4,r=Array.from(e);return r.length<=n?e:r.slice(0,n).join(``)}function Dr(e,t=4e3){let n=[`<agent_memory_updates note="本会话中途更新——取代上方缓存中的对应文件">`],r=0,i=0;for(let a of e){let e=Array.isArray(a)?{kind:`upsert`,path:a[0],content:a[1]}:a,o=t-r;if(o<=0){i++;continue}if(e.kind===`remove`){let t=`[removed during this session — disregard the cached version of ${e.path} above]`,a=Tr(t);if(a>o){i++;continue}n.push(`# ${e.path}`),n.push(t),n.push(``),r+=a;continue}let{path:s,content:c}=e,l=c.trim();if(!l)continue;if(o<=0){i++;continue}let u=Tr(l);if(u<=o)n.push(`# ${s}`),n.push(l),n.push(``),r+=u;else{let e=Er(l,o);n.push(`# ${s}`),n.push(e),n.push(`\n> ⚠ [truncated — content exceeded the memory delta budget (${t} tokens); remainder omitted]`),n.push(``),r=t}}return i>0&&(n.push(`> ⚠ [${i} additional changed memory source(s) omitted — delta budget (${t} tokens) reached]`),n.push(``)),n.push(`</agent_memory_updates>`),n.join(`
29
- `)}function Or(e,t=w.memoryDelta.priority){let n=new Map,r=new Map;return[o({name:w.memoryDelta.name,timing:`system.prompt.transform`,priority:t,handle:(t,i)=>{let a=e.getMemories(),o=n.get(t.sessionId);if(!o){n.set(t.sessionId,new Map(a));return}let s=r.get(t.sessionId)??new Set;for(let e of o.keys())a.has(e)||s.add(e);for(let e of a.keys())s.delete(e);r.set(t.sessionId,s);let c=[];for(let e of s)c.push({kind:`remove`,path:e});for(let[e,t]of a)o.get(e)!==t&&c.push({kind:`upsert`,path:e,content:t});c.length!==0&&(i.systemTail??=[],i.systemTail.push(T(w.memoryDelta.name,Dr(c))))}}),o({name:`memory-delta-cleanup`,timing:`session.deleted`,priority:90,handle:e=>{let t=e.sessionId;n.delete(t),r.delete(t)}})]}const kr=new Set([`done`,`skipped`,`failed`]);function Ar(e){return!kr.has(e??`pending`)}function jr(e){let t=[`<system-reminder>`,`Your todo list still has ${e.filter(e=>Ar(e.status)).length} unfinished item(s). Before ending your turn, audit each one against the actual current state: mark genuinely finished items done, mark out-of-scope or abandoned items skipped/failed with a reason, and finish the rest. Completion requires evidence, not activity. Latest todo state:`];for(let n of e)t.push(`- [${n.status??`pending`}] ${n.title??``}`);return t.push(`Continue with the unfinished items now. (This reminder is system-generated from your todo list; do not repeat it back to the user.)`),t.push(`</system-reminder>`),t.join(`
30
- `)}function Mr(e,t=w.todoReminder.priority){return[o({name:w.todoReminder.name,timing:`system.prompt.transform`,priority:t,handle:(t,n)=>{let r=e.getTodoList(t.sessionId);!r||r.length===0||r.some(e=>Ar(e.status))&&(n.systemTail??=[],n.systemTail.push(T(w.todoReminder.name,jr(r))))}})]}function Nr(){return{touchedDoc:!1,toolTouchedDoc:void 0,calledWriteTodos:!1}}function Pr(e){return[`<system-reminder>`,`You just modified a tracked progress document (via ${e}) but have not called write_todos in this turn. write_todos (the UI-pinned todo list) and progress documents are two independent tracking systems that do not auto-sync. If this document edit reflects real progress (e.g. a milestone Status flip to Done), call write_todos now to keep the pinned list consistent with the document. (This reminder is system-generated; do not repeat it back to the user.)`,`</system-reminder>`].join(`
31
- `)}function Fr(e,t=w.docSyncReminder.priority){let n=new Map;return[o({name:`doc-sync-tool-tracker`,timing:`tool.execute.after`,priority:90,handle:t=>{let r=n.get(t.sessionId)??Nr();t.toolName===`write_todos`?r.calledWriteTodos=!0:!r.touchedDoc&&e.isDocSyncTrigger(t)&&(r.touchedDoc=!0,r.toolTouchedDoc=t.toolName),n.set(t.sessionId,r)}}),o({name:`doc-sync-turn-reset`,timing:`chat.message.before`,priority:10,handle:e=>{e.message.internal!==!0&&n.set(e.sessionId,Nr())}}),o({name:w.docSyncReminder.name,timing:`system.prompt.transform`,priority:t,handle:(e,t)=>{let r=n.get(e.sessionId);!r?.touchedDoc||r.calledWriteTodos||(t.systemTail??=[],t.systemTail.push(T(w.docSyncReminder.name,Pr(r.toolTouchedDoc??`edit/write`))))}}),o({name:`doc-sync-cleanup`,timing:`session.deleted`,priority:90,handle:e=>{n.delete(e.sessionId)}})]}function Ir(e){let t=Object.values(w).find(t=>t.name===e.name);if(!t)throw Error(`definePromptSection: section "${e.name}" is not registered in SYSTEM_PROMPT_SECTIONS. Register the section in section-order.ts before defining its hook.`);if(t.lane!==`stable`)throw Error(`definePromptSection: section "${e.name}" is lane "${t.lane}", not "stable". Volatile sections carry per-turn state and must use defineHook directly.`);return N({name:t.name,priority:t.priority,compute:async n=>{let r=await e.compute(n);return r&&T(t.name,r)}})}function Lr(e){return typeof e==`string`?e:Array.isArray(e)?e.filter(e=>typeof e==`object`&&!!e&&e.type===`text`).map(e=>e.text).join(``):``}function Rr(e){let t=e.trim();if(!t)return`abstain`;let n=t.match(/"verdict"\s*:\s*"(allow|deny|abstain)"/i);if(!n)return`abstain`;let r=n[1].toLowerCase();return r===`allow`||r===`deny`?r:`abstain`}function zr(e){return async(t,n,r,i)=>{let a=typeof n?.command==`string`?n.command:``,o=[`Tool: ${t}`,i?`Risk hint: ${i}`:``,`Sandbox denial: ${r}`,`Command:\n${a}`].filter(Boolean).join(`
32
- `).slice(0,1200),s=new AbortController,c=setTimeout(()=>s.abort(),e.timeoutMs??1e4);try{let t=[{role:`user`,timestamp:Date.now(),content:[{type:`text`,text:o}]}];return Rr(Lr((await e.stream({model:e.model,systemPrompt:`You are a security reviewer for a coding agent's sandbox escalation request.
28
+ `:``),`utf-8`)}catch{}}};function sr(e){try{return Xe(e)}catch{return[]}}function cr(e){try{return Ye(e,`utf-8`).split(`
29
+ `)}catch{return[]}}function lr(e){let t=new Map;for(let n of e){let e=t.get(n.repoRoot)??[];e.push(n),t.set(n.repoRoot,e)}let n=[];for(let e of t.values()){let t=e.filter(e=>e.status!==`applied`&&e.status!==`failed`&&e.status!==`canceled`),r=e.filter(e=>e.status===`applied`||e.status===`failed`||e.status===`canceled`).sort((e,t)=>t.startedAt-e.startedAt).slice(0,100);n.push(...t,...r)}return n}const $=new Set([`applied`,`failed`,`canceled`]);var ur=class{entries=new Map;maxJobs;clock;onWorktreeCleanupError;stateStore;spawnListeners=new Set;updateListeners=new Set;exitListeners=new Set;removeListeners=new Set;retained=new Set;constructor(e={}){this.maxJobs=e.maxJobs??16,this.clock=e.clock??(()=>Date.now()),this.onWorktreeCleanupError=e.onWorktreeCleanupError}setWorktreeCleanupErrorHandler(e){this.onWorktreeCleanupError=e}setStateStore(e){this.stateStore=e}onSpawn(e){return this.spawnListeners.add(e),()=>this.spawnListeners.delete(e)}onUpdate(e){return this.updateListeners.add(e),()=>this.updateListeners.delete(e)}onExit(e){return this.exitListeners.add(e),()=>this.exitListeners.delete(e)}onRemove(e){return this.removeListeners.add(e),()=>this.removeListeners.delete(e)}retain(e,t){t?this.retained.add(e):this.retained.delete(e)}restore(e){if(this.entries.has(e.id)||e.status===`running`||e.status===`needs_input`)return;let t={id:e.id,type:`agent-session`,sessionId:e.sessionId,title:e.title,origin:e.origin,status:e.status,worktree:{path:e.worktreePath,branch:e.branch,base:e.branch.replace(`otto/job-`,``),repoRoot:e.repoRoot},outputPath:e.outputPath,startedAt:e.startedAt,diff:e.diff,error:e.error};return this.entries.set(e.id,{info:t,abort:()=>{}}),t}appendState(e){this.stateStore&&this.stateStore.append(rr(e))}notify(e,t){for(let n of[...e])try{n(t)}catch{}}register(e){if(this.entries.size>=this.maxJobs&&this.evictTerminal(),this.entries.size>=this.maxJobs)throw Error(`Agent job limit (${this.maxJobs}) reached; cancel one with stop first.`);let t=e.now??this.clock(),n={id:e.id,sessionId:e.sessionId,type:`agent-session`,title:e.title,origin:e.origin??`user`,status:`running`,worktree:e.worktree,outputPath:e.outputPath,startedAt:t};return this.entries.set(e.id,{info:n,abort:e.abort}),this.appendState(n),this.notify(this.spawnListeners,n),n}get(e){return this.entries.get(e)?.info}getForSession(e,t){let n=this.entries.get(t);return n&&n.info.sessionId===e?n.info:void 0}list(){return[...this.entries.values()].map(e=>e.info)}listForSession(e){return this.list().filter(t=>t.sessionId===e)}size(){return this.entries.size}update(e,t){let n=this.entries.get(e);n&&($.has(n.info.status)||(Object.assign(n.info,t),this.appendState(n.info),this.notify(this.updateListeners,n.info),$.has(n.info.status)&&(n.info.status!==`canceled`&&Q(n.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),this.notify(this.exitListeners,n.info))))}cancel(e){let t=this.entries.get(e);if(!(!t||$.has(t.info.status))){try{t.abort()}catch{}Q(t.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),this.update(e,{status:`canceled`})}}remove(e){let t=this.entries.get(e);t&&Q(t.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),this.retained.delete(e),this.entries.delete(e),t&&this.stateStore&&this.stateStore.remove(e,t.info.worktree.repoRoot),t&&this.notify(this.removeListeners,t.info)}evictTerminal(){for(let[e,t]of this.entries)if($.has(t.info.status)&&!this.retained.has(e)){this.remove(e);return}}cleanupAll(){for(let[e,t]of this.entries)if(!$.has(t.info.status)){try{t.abort()}catch{}Q(t.info.worktree,(t,n)=>this.onWorktreeCleanupError?.(e,t,n)),t.info.status=`canceled`}}};const dr=new ur;let fr=!1;function pr(e=dr,t,n){if(!fr){if(fr=!0,n&&t)for(let r of n.load())r.repoRoot===t&&e.restore(r);if(t){let r=Gn(t),i=new Map;if(n)for(let e of n.load())e.repoRoot===t&&i.set(e.id,e);let a=e=>({path:mr(e),branch:`otto/job-${e}`,base:``,repoRoot:t});for(let t of r){let n=i.get(t);if(!e.get(t)){if(!n){hr(t)||Q(a(t),(n,r)=>e.onWorktreeCleanupError?.(t,n,r));continue}if(!(n.status===`running`||n.status===`needs_input`)&&(n.status===`applied`||n.status===`failed`||n.status===`canceled`)){Q(a(t),(n,r)=>e.onWorktreeCleanupError?.(t,n,r));continue}}}}if(t){let n=new Set(e.list().map(e=>e.id));for(let e of Gn(t))n.add(e);Kn(t,n)}process.on(`exit`,()=>{e.cleanupAll()})}}function mr(e){return p(j(M()),`otto-wt-`,`job-${e}`)}function hr(e){try{return A(`git`,[`-C`,mr(e),`status`,`--porcelain`],{encoding:`utf-8`,stdio:[`pipe`,`pipe`,`pipe`]}).trim().length>0}catch{return!1}}const gr=new Set([`done`,`error`,`aborted`]),_r=new Set([`edit`,`write`,`delete`,`edit_file`,`write_file`]);function vr(e){return _r.has(e)}var yr=class extends l{observations=new Map;abortFns=new Map;messagesRefs=new Map;streamingTexts=new Map;turns=new Map;evictTimers=new Map;pinned=new Set;now;warnMs;stalledMs;evictMs;constructor(e={}){super(),this.now=e.now??Date.now,this.warnMs=e.warnMs??3e3,this.stalledMs=e.stalledMs??3e4,this.evictMs=e.evictMs??15e3}register(e){let t=this.now(),n=this.evictTimers.get(e.id);n&&(clearTimeout(n),this.evictTimers.delete(e.id)),e.abort&&this.abortFns.set(e.id,e.abort),e.messages&&this.messagesRefs.set(e.id,e.messages),this.streamingTexts.set(e.id,``),this.turns.set(e.id,[]),this.observations.set(e.id,{id:e.id,agentName:e.agentName,title:e.title,prompt:e.prompt,model:e.model,modelDecidedBy:e.modelDecidedBy,origin:e.origin??`main`,depth:e.depth??0,status:`streaming`,turnIndex:0,toolUseCount:0,filesEdited:0,tokenCount:0,inputTokens:0,lastActivity:`starting`,lastEventAt:t,abortable:e.abortable??e.abort!==void 0,startedAt:t}),this.emit(`change`)}abort(e){let t=this.observations.get(e),n=this.abortFns.get(e);return!t||!n||gr.has(t.status)?!1:(n(),!0)}record(e,t){let n=this.observations.get(e);if(!n)return;n.lastEventAt=this.now();let r=!0;switch(t.type){case`turn.start`:n.turnIndex=t.turnIndex,n.status=`streaming`,n.lastActivity=`thinking`,n.blockedOn=`model_io`,n.blockDetail=void 0,this.streamingTexts.set(e,``),this.turns.get(e)?.push({index:t.turnIndex,startedAt:this.now(),toolCount:0,tools:[],outputTokens:0});break;case`stream.event`:{let i=t.event;i.type===`text_delta`?(n.lastActivity=`responding`,n.blockedOn=void 0,this.streamingTexts.set(e,(this.streamingTexts.get(e)??``)+i.delta)):i.type.startsWith(`thinking`)&&(n.lastActivity=`thinking`,n.blockedOn=void 0),r=!1;break}case`tool.call.start`:{n.toolUseCount+=1,n.status=`tool_executing`,n.lastActivity=`using ${t.toolCall.name}`,n.blockedOn=`process`,n.blockDetail=t.toolCall.name;let r=this.turns.get(e);r?.length&&(r[r.length-1].toolCount+=1,r[r.length-1].tools.push(t.toolCall.name));break}case`tool.call.end`:n.status=`streaming`,n.lastActivity=`thinking`,n.blockedOn=`model_io`,n.blockDetail=void 0,vr(t.toolCall.name)&&(n.filesEdited+=1);break;case`turn.end`:{let r=t.message.usage.outputTokens??0;n.tokenCount+=r,n.inputTokens=t.message.usage.inputTokens??n.inputTokens,this.streamingTexts.set(e,``);let i=this.turns.get(e),a=i?.[i.length-1];a&&a.endedAt===void 0&&(a.endedAt=this.now(),a.outputTokens=r);break}case`stream.retry`:n.lastActivity=`reconnecting ${t.attempt}/${t.maxRetries}`,n.blockedOn=`model_io`;break;case`status.change`:this.applyTerminal(n,t.to);break;case`error`:this.markTerminal(n,`error`);break;case`abort`:this.markTerminal(n,`aborted`);break;case`lifecycle.tool.completed`:n.lastActivity=`${t.toolName} ${t.isError?`failed`:`completed`} (background)`,n.lastEventAt=this.now(),r=!0;break;case`lifecycle.tool.completed.crossBoundary`:n.lastActivity=`${t.toolName} completed in background (result not shown — belongs to a previous prompt)`,n.lastEventAt=this.now(),r=!0;break;default:r=!1;break}r&&this.emit(`change`)}setAwaitingApproval(e,t){let n=this.observations.get(e);n&&(n.status=`awaiting_gate`,n.lastActivity=`awaiting approval`,n.blockedOn=`approval`,n.blockDetail=t,n.lastEventAt=this.now(),this.emit(`change`))}clearAwaitingApproval(e){let t=this.observations.get(e);!t||t.status!==`awaiting_gate`||(t.status=`streaming`,t.lastActivity=`thinking`,t.blockedOn=`model_io`,t.blockDetail=void 0,t.lastEventAt=this.now(),this.emit(`change`))}setToolWaiting(e,t){let n=this.observations.get(e);n&&(n.status=`tool_waiting`,n.lastActivity=t,n.blockedOn=`process`,n.blockDetail=t,n.lastEventAt=this.now(),this.emit(`change`))}clearToolWaiting(e){let t=this.observations.get(e);!t||t.status!==`tool_waiting`||(t.status=`streaming`,t.lastActivity=`thinking`,t.blockedOn=`model_io`,t.blockDetail=void 0,t.lastEventAt=this.now(),this.emit(`change`))}markEnded(e,t=`done`){let n=this.observations.get(e);!n||gr.has(n.status)||(this.markTerminal(n,t),this.emit(`change`))}pin(e){let t=this.evictTimers.get(e);t&&(clearTimeout(t),this.evictTimers.delete(e)),this.pinned.add(e)}unpin(e){this.pinned.delete(e);let t=this.observations.get(e);t&&t.endedAt!==void 0&&this.scheduleEvict(e)}remove(e){let t=this.evictTimers.get(e);t&&(clearTimeout(t),this.evictTimers.delete(e)),this.observations.delete(e),this.abortFns.delete(e),this.messagesRefs.delete(e),this.streamingTexts.delete(e),this.turns.delete(e),this.pinned.delete(e),this.emit(`change`)}get(e){let t=this.observations.get(e);return t?this.toSnapshot(t):void 0}getMessages(e){let t=this.messagesRefs.get(e);if(t)return[...typeof t==`function`?t():t]}setMessages(e,t){this.messagesRefs.has(e)&&this.messagesRefs.set(e,[...t])}getStreamingText(e){return this.streamingTexts.get(e)??``}getTurns(e){let t=this.turns.get(e);return t?t.map(e=>({...e,tools:[...e.tools]})):[]}list(){return[...this.observations.values()].map(e=>this.toSnapshot(e))}listActive(){return this.list().filter(e=>!gr.has(e.status))}subscribe(e){return this.on(`change`,e)}clear(){for(let e of this.evictTimers.values())clearTimeout(e);this.evictTimers.clear(),this.observations.clear(),this.abortFns.clear(),this.messagesRefs.clear(),this.streamingTexts.clear(),this.turns.clear(),this.pinned.clear()}applyTerminal(e,t){t===`completed`?this.markTerminal(e,`done`):t===`error`?this.markTerminal(e,`error`):t===`aborted`&&this.markTerminal(e,`aborted`)}markTerminal(e,t){e.status=t,e.lastActivity=t,e.blockedOn=void 0,e.blockDetail=void 0,e.endedAt=this.now(),this.scheduleEvict(e.id)}scheduleEvict(e){if(this.pinned.has(e))return;let t=this.evictTimers.get(e);t&&clearTimeout(t);let n=setTimeout(()=>{this.observations.delete(e),this.evictTimers.delete(e),this.abortFns.delete(e),this.messagesRefs.delete(e),this.streamingTexts.delete(e),this.turns.delete(e),this.emit(`change`)},this.evictMs);n.unref?.(),this.evictTimers.set(e,n)}toSnapshot(e){let t=e.endedAt!==void 0,n=t?0:Math.max(0,this.now()-e.lastEventAt),r=t?`none`:n>this.stalledMs?`stalled`:n>this.warnMs?`warn`:`none`;return{...e,idleMs:n,stall:r}}};const br=new yr;function xr(e,t,n=br){n.register(t);let r=t.id,i=[e.on(`turn.start`,e=>n.record(r,{type:`turn.start`,...e})),e.on(`turn.end`,e=>n.record(r,{type:`turn.end`,...e})),e.on(`stream.event`,e=>n.record(r,{type:`stream.event`,...e})),e.on(`tool.call.start`,e=>n.record(r,{type:`tool.call.start`,...e})),e.on(`tool.call.end`,e=>n.record(r,{type:`tool.call.end`,...e})),e.on(`status.change`,e=>n.record(r,{type:`status.change`,...e})),e.on(`stream.retry`,e=>n.record(r,{type:`stream.retry`,...e})),e.on(`error`,e=>n.record(r,{type:`error`,...e})),e.on(`abort`,()=>n.record(r,{type:`abort`})),e.on(`lifecycle.tool.completed`,e=>n.record(r,{type:`lifecycle.tool.completed`,...e})),e.on(`lifecycle.tool.completed.crossBoundary`,e=>n.record(r,{type:`lifecycle.tool.completed.crossBoundary`,...e}))];return()=>{for(let e of i)e()}}var Sr=class{entries=new Map;disposed=!1;constructor(e){this.key=e}register(e){if(this.disposed)throw Error(`PlaneRegistry: workspace preset grid "${this.key}" already disposed, refusing registration (fail-closed)`);let t={...e,workspaceKey:this.key};return this.entries.set(t.id,t),t}unregister(e){return this.entries.delete(e)}unregisterByPlugin(e){let t=0;for(let[n,r]of this.entries)r.pluginId===e&&(this.entries.delete(n),t+=1);return t}list(){return[...this.entries.values()]}dispose(){this.entries.clear(),this.disposed=!0}},Cr=class{entries=new Map;disposed=!1;constructor(e){this.sessionId=e}register(e){if(this.disposed)throw Error(`PlaneRegistry: session preset grid "${this.sessionId}" already disposed, refusing registration (fail-closed)`);let t={...e,sessionId:this.sessionId};return this.entries.set(t.id,t),t}unregister(e){return this.entries.delete(e)}unregisterByPlugin(e){let t=0;for(let[n,r]of this.entries)r.pluginId===e&&(this.entries.delete(n),t+=1);return t}list(){return[...this.entries.values()]}dispose(){this.entries.clear(),this.disposed=!0}},wr=class{preset;constructor(e){this.workspaceKey=e,this.preset=new Sr(e)}dispose(){this.preset.dispose()}},Tr=class{preset;constructor(e){this.sessionId=e,this.preset=new Cr(e)}dispose(){this.preset.dispose()}},Er=class{hostEntries=new Map;workspaceScopes=new Map;sessionScopes=new Map;disposed=!1;ensureNotDisposed(){if(this.disposed)throw Error(`PlaneRegistry: HostRegistry already disposed (process lifecycle ended), refusing mutation (fail-closed)`)}register(e){this.ensureNotDisposed();let t={...e};return this.hostEntries.set(t.id,t),t}unregister(e){return this.hostEntries.delete(e)}unregisterByPlugin(e){let t=0;for(let[n,r]of this.hostEntries)r.pluginId===e&&(this.hostEntries.delete(n),t+=1);return t}list(){return[...this.hostEntries.values()]}workspace(e){this.ensureNotDisposed();let t=this.workspaceScopes.get(e);return t||(t=new wr(e),this.workspaceScopes.set(e,t)),t}session(e){this.ensureNotDisposed();let t=this.sessionScopes.get(e);return t||(t=new Tr(e),this.sessionScopes.set(e,t)),t}disposeWorkspaceGrid(e){let t=this.workspaceScopes.get(e);t&&(t.dispose(),this.workspaceScopes.delete(e))}migrateWorkspaceGrid(e,t){if(e===t)return;let n=this.workspaceScopes.get(e);if(!n)return;let r=this.workspace(t);for(let e of n.preset.list()){let{workspaceKey:t,...n}=e;r.preset.register(n)}this.disposeWorkspaceGrid(e)}disposeSessionGrid(e){let t=this.sessionScopes.get(e);t&&(t.dispose(),this.sessionScopes.delete(e))}unregisterByPluginEverywhere(e){let t=this.unregisterByPlugin(e);for(let n of this.workspaceScopes.values())t+=n.preset.unregisterByPlugin(e);for(let n of this.sessionScopes.values())t+=n.preset.unregisterByPlugin(e);return t}revalidatePlugin(e,t){let n=[];for(let r of this.hostEntries.values())r.pluginId===e&&r.pluginVersion!==t&&n.push({entry:r,registeredVersion:r.pluginVersion,currentVersion:t});for(let r of this.workspaceScopes.values())for(let i of r.preset.list())i.pluginId===e&&i.pluginVersion!==t&&n.push({entry:i,registeredVersion:i.pluginVersion,currentVersion:t});for(let r of this.sessionScopes.values())for(let i of r.preset.list())i.pluginId===e&&i.pluginVersion!==t&&n.push({entry:i,registeredVersion:i.pluginVersion,currentVersion:t});return n}resolveForEmit(e){let t=[...this.hostEntries.values()];if(e.workspaceKey!==void 0){let n=this.workspaceScopes.get(e.workspaceKey);n&&t.push(...n.preset.list())}if(e.sessionId!==void 0){let n=this.sessionScopes.get(e.sessionId);n&&t.push(...n.preset.list())}return t}listAll(){return[...this.hostEntries.values(),...this.workspaceScopes.values().flatMap(e=>[...e.preset.list()]),...this.sessionScopes.values().flatMap(e=>[...e.preset.list()])]}dispose(){for(let e of this.workspaceScopes.values())e.dispose();for(let e of this.sessionScopes.values())e.dispose();this.workspaceScopes.clear(),this.sessionScopes.clear(),this.hostEntries.clear(),this.disposed=!0}};function Dr(e,t){let n=!1;return{id:`runtime:memory-index`,priority:w.agentKnowledge.priority,async contribute(e){if(!t)return;n||=(await t.loadMemory(),!0);let r=t.getMemoryPrompt();return r.trim()?r:void 0}}}function Or(e){let t=0;for(let n of e)/[\u3000-\u9fff\uff00-\uffef]/.test(n)&&t++;return Math.ceil(t+(e.length-t)/4)}function kr(e,t){if(t<=0)return``;let n=t*4,r=Array.from(e);return r.length<=n?e:r.slice(0,n).join(``)}function Ar(e,t=4e3){let n=[`<agent_memory_updates note="本会话中途更新——取代上方缓存中的对应文件">`],r=0,i=0;for(let a of e){let e=Array.isArray(a)?{kind:`upsert`,path:a[0],content:a[1]}:a,o=t-r;if(o<=0){i++;continue}if(e.kind===`remove`){let t=`[removed during this session — disregard the cached version of ${e.path} above]`,a=Or(t);if(a>o){i++;continue}n.push(`# ${e.path}`),n.push(t),n.push(``),r+=a;continue}let{path:s,content:c}=e,l=c.trim();if(!l)continue;if(o<=0){i++;continue}let u=Or(l);if(u<=o)n.push(`# ${s}`),n.push(l),n.push(``),r+=u;else{let e=kr(l,o);n.push(`# ${s}`),n.push(e),n.push(`\n> ⚠ [truncated — content exceeded the memory delta budget (${t} tokens); remainder omitted]`),n.push(``),r=t}}return i>0&&(n.push(`> ⚠ [${i} additional changed memory source(s) omitted — delta budget (${t} tokens) reached]`),n.push(``)),n.push(`</agent_memory_updates>`),n.join(`
30
+ `)}function jr(e,t=w.memoryDelta.priority){let n=new Map,r=new Map;return[o({name:w.memoryDelta.name,timing:`system.prompt.transform`,priority:t,handle:(t,i)=>{let a=e.getMemories(),o=n.get(t.sessionId);if(!o){n.set(t.sessionId,new Map(a));return}let s=r.get(t.sessionId)??new Set;for(let e of o.keys())a.has(e)||s.add(e);for(let e of a.keys())s.delete(e);r.set(t.sessionId,s);let c=[];for(let e of s)c.push({kind:`remove`,path:e});for(let[e,t]of a)o.get(e)!==t&&c.push({kind:`upsert`,path:e,content:t});c.length!==0&&(i.systemTail??=[],i.systemTail.push(T(w.memoryDelta.name,Ar(c))))}}),o({name:`memory-delta-cleanup`,timing:`session.deleted`,priority:90,handle:e=>{let t=e.sessionId;n.delete(t),r.delete(t)}})]}const Mr=new Set([`done`,`skipped`,`failed`]);function Nr(e){return!Mr.has(e??`pending`)}function Pr(e){let t=[`<system-reminder>`,`Your todo list still has ${e.filter(e=>Nr(e.status)).length} unfinished item(s). Before ending your turn, audit each one against the actual current state: mark genuinely finished items done, mark out-of-scope or abandoned items skipped/failed with a reason, and finish the rest. Completion requires evidence, not activity. Latest todo state:`];for(let n of e)t.push(`- [${n.status??`pending`}] ${n.title??``}`);return t.push(`Continue with the unfinished items now. (This reminder is system-generated from your todo list; do not repeat it back to the user.)`),t.push(`</system-reminder>`),t.join(`
31
+ `)}function Fr(e,t=w.todoReminder.priority){return[o({name:w.todoReminder.name,timing:`system.prompt.transform`,priority:t,handle:(t,n)=>{let r=e.getTodoList(t.sessionId);!r||r.length===0||r.some(e=>Nr(e.status))&&(n.systemTail??=[],n.systemTail.push(T(w.todoReminder.name,Pr(r))))}})]}function Ir(){return{touchedDoc:!1,toolTouchedDoc:void 0,calledWriteTodos:!1}}function Lr(e){return[`<system-reminder>`,`You just modified a tracked progress document (via ${e}) but have not called write_todos in this turn. write_todos (the UI-pinned todo list) and progress documents are two independent tracking systems that do not auto-sync. If this document edit reflects real progress (e.g. a milestone Status flip to Done), call write_todos now to keep the pinned list consistent with the document. (This reminder is system-generated; do not repeat it back to the user.)`,`</system-reminder>`].join(`
32
+ `)}function Rr(e,t=w.docSyncReminder.priority){let n=new Map;return[o({name:`doc-sync-tool-tracker`,timing:`tool.execute.after`,priority:90,handle:t=>{let r=n.get(t.sessionId)??Ir();t.toolName===`write_todos`?r.calledWriteTodos=!0:!r.touchedDoc&&e.isDocSyncTrigger(t)&&(r.touchedDoc=!0,r.toolTouchedDoc=t.toolName),n.set(t.sessionId,r)}}),o({name:`doc-sync-turn-reset`,timing:`chat.message.before`,priority:10,handle:e=>{e.message.internal!==!0&&n.set(e.sessionId,Ir())}}),o({name:w.docSyncReminder.name,timing:`system.prompt.transform`,priority:t,handle:(e,t)=>{let r=n.get(e.sessionId);!r?.touchedDoc||r.calledWriteTodos||(t.systemTail??=[],t.systemTail.push(T(w.docSyncReminder.name,Lr(r.toolTouchedDoc??`edit/write`))))}}),o({name:`doc-sync-cleanup`,timing:`session.deleted`,priority:90,handle:e=>{n.delete(e.sessionId)}})]}function zr(e){let t=Object.values(w).find(t=>t.name===e.name);if(!t)throw Error(`definePromptSection: section "${e.name}" is not registered in SYSTEM_PROMPT_SECTIONS. Register the section in section-order.ts before defining its hook.`);if(t.lane!==`stable`)throw Error(`definePromptSection: section "${e.name}" is lane "${t.lane}", not "stable". Volatile sections carry per-turn state and must use defineHook directly.`);return N({name:t.name,priority:t.priority,compute:async n=>{let r=await e.compute(n);return r&&T(t.name,r)}})}function Br(e){return typeof e==`string`?e:Array.isArray(e)?e.filter(e=>typeof e==`object`&&!!e&&e.type===`text`).map(e=>e.text).join(``):``}function Vr(e){let t=e.trim();if(!t)return`abstain`;let n=t.match(/"verdict"\s*:\s*"(allow|deny|abstain)"/i);if(!n)return`abstain`;let r=n[1].toLowerCase();return r===`allow`||r===`deny`?r:`abstain`}function Hr(e){return async(t,n,r,i)=>{let a=typeof n?.command==`string`?n.command:``,o=[`Tool: ${t}`,i?`Risk hint: ${i}`:``,`Sandbox denial: ${r}`,`Command:\n${a}`].filter(Boolean).join(`
33
+ `).slice(0,1200),s=new AbortController,c=setTimeout(()=>s.abort(),e.timeoutMs??1e4);try{let t=[{role:`user`,timestamp:Date.now(),content:[{type:`text`,text:o}]}];return Vr(Br((await e.stream({model:e.model,systemPrompt:`You are a security reviewer for a coding agent's sandbox escalation request.
33
34
 
34
35
  A shell command was BLOCKED by an OS sandbox. The agent asks to re-run it WITHOUT the sandbox.
35
36
  Decide whether that is safe.
@@ -44,5 +45,5 @@ Answer with JSON only: {"verdict":"allow"} or {"verdict":"deny"} or {"verdict":"
44
45
  over the network, or you cannot tell what it does.
45
46
  - "abstain": you are unsure, or the request needs human judgement.
46
47
 
47
- When in doubt, prefer "deny" or "abstain" over "allow". Never explain; output JSON only.`,messages:t,cacheRetention:`none`,maxTokens:32,temperature:0},s.signal).result()).content))}catch{return`abstain`}finally{clearTimeout(c)}}}const Br=6e4;function Vr(e,t={}){let n=t.orphanTimeoutMs??6e4,r=()=>`${process.pid}:${Date.now()}`;return{async acquire(t,i){let a=e.compactionLockState?.(),o=a?.phase===`start`&&Date.now()-a.timestamp>n;return a?.phase===`start`&&!o?!1:(e.appendCompactionLock?.(`start`,i||r()),!0)},async release(t,n){let r=e.compactionLockState?.();r?.phase!==`start`||r.token!==n||e.appendCompactionLock?.(`end`,n)}}}function Hr(e,t){let{totalBytes:n,minPerSessionBytes:r,maxPerSessionBytes:i}=k(t);if(e<=0)return i;let a=Math.floor(n/e);return Math.max(r,Math.min(a,i))}function Ur(e,t,n){let{minPerSessionBytes:r}=k(n),i=Hr(e,n),a=Math.max(1,Math.floor(r/t));return Math.max(a,Math.floor(i/t))}export{sr as AgentJobRegistry,gr as AgentObservabilityRegistry,zt as AgentSession,Xn as CAPABILITY_SURFACE_PATTERNS,$e as ContextSourceRegistry,Br as DEFAULT_COMPACTION_LOCK_ORPHAN_TIMEOUT_MS,Qn as DEFAULT_MAX_AUTO_APPLY_LINES,Ot as ESCALATION_MARKER,te as EVENT_DOMAIN,Wn as FORBIDDEN_ZONE_PATTERNS,Tn as FleetMonitor,Cr as HostRegistry,rr as JobStateStore,L as LEVEL_DIVISOR,wn as MemoryGovernor,U as PanelStateStore,_n as PersistenceSync,En as ProcessRegistry,Mn as ProcessRuntime,Et as RUNTIME_DEFAULTS,on as ResidencyGovernor,w as SYSTEM_PROMPT_SECTIONS,rn as SandboxUnavailableError,W as SessionPool,an as TimeTravelController,Bn as applyDiff,ge as applyMemoryTransform,T as applySectionBudget,vr as attachAgentObserver,Qe as buildEngineStores,Ut as captureFiles,zn as checkApply,Sn as createAgentRuntime,xn as createDefaultContextSourceRegistry,Fr as createDocSyncReminderHooks,nt as createEnvironmentContextSource,yn as createInMemorySessionPool,zr as createLlmEscalationReviewer,Or as createMemoryDeltaHooks,wr as createMemoryIndexContextSource,vn as createRemoteSessionPool,Vr as createSessionCompactionLock,N as createSessionStableInjectionHooks,Mr as createTodoReminderHooks,it as createToolHookExecutor,In as createWorktree,$n as decideApply,R as decideResidency,Lt as defaultMaxToolTurnExtensions,Ir as definePromptSection,P as deriveSessionTitle,Jn as diffTouchedPaths,Ur as effectiveResidencyBudget,Pr as formatDocSyncReminder,ne as getEventDomain,cr as globalAgentJobRegistry,_r as globalAgentObservability,Dn as globalProcessRegistry,Nn as globalProcessRuntime,Tt as globalToolResultStore,Rn as hasRepoDrifted,ur as installAgentJobReaper,Fn as installExitReaper,kn as installProcessReaper,kt as isEscalationApproval,nr as jobStateFilePath,Hn as listWorktreeJobIds,Jt as messagesFromSnapshot,Rr as parseVerdict,Un as pruneOrphanWorktrees,Zt as reconstructMessages,Q as removeWorktree,at as resolveSessionTitle,Rt as resolveTodoContinuationConfig,Wt as restoreFiles,Vn as revertDiff,er as toJobStateEntry,Zn as touchesCapabilitySurface,Yn as touchesForbiddenZone,Ln as worktreeDiff};
48
+ When in doubt, prefer "deny" or "abstain" over "allow". Never explain; output JSON only.`,messages:t,cacheRetention:`none`,maxTokens:32,temperature:0},s.signal).result()).content))}catch{return`abstain`}finally{clearTimeout(c)}}}const Ur=6e4;function Wr(e,t={}){let n=t.orphanTimeoutMs??6e4,r=()=>`${process.pid}:${Date.now()}`;return{async acquire(t,i){let a=e.compactionLockState?.(),o=a?.phase===`start`&&Date.now()-a.timestamp>n;return a?.phase===`start`&&!o?!1:(e.appendCompactionLock?.(`start`,i||r()),!0)},async release(t,n){let r=e.compactionLockState?.();r?.phase!==`start`||r.token!==n||e.appendCompactionLock?.(`end`,n)}}}function Gr(e,t){let{totalBytes:n,minPerSessionBytes:r,maxPerSessionBytes:i}=k(t);if(e<=0)return i;let a=Math.floor(n/e);return Math.max(r,Math.min(a,i))}function Kr(e,t,n){let{minPerSessionBytes:r}=k(n),i=Gr(e,n),a=Math.max(1,Math.floor(r/t));return Math.max(a,Math.floor(i/t))}export{ur as AgentJobRegistry,yr as AgentObservabilityRegistry,Ht as AgentSession,$n as CAPABILITY_SURFACE_PATTERNS,$e as ContextSourceRegistry,Ur as DEFAULT_COMPACTION_LOCK_ORPHAN_TIMEOUT_MS,tr as DEFAULT_MAX_AUTO_APPLY_LINES,jt as ESCALATION_MARKER,te as EVENT_DOMAIN,qn as FORBIDDEN_ZONE_PATTERNS,On as FleetMonitor,Er as HostRegistry,or as JobStateStore,L as LEVEL_DIVISOR,Dn as MemoryGovernor,U as PanelStateStore,bn as PersistenceSync,kn as ProcessRegistry,Fn as ProcessRuntime,kt as RUNTIME_DEFAULTS,ln as ResidencyGovernor,w as SYSTEM_PROMPT_SECTIONS,sn as SandboxUnavailableError,W as SessionPool,cn as TimeTravelController,Un as applyDiff,ge as applyMemoryTransform,T as applySectionBudget,xr as attachAgentObserver,Qe as buildEngineStores,Kt as captureFiles,Hn as checkApply,Tn as createAgentRuntime,wn as createDefaultContextSourceRegistry,Rr as createDocSyncReminderHooks,it as createEnvironmentContextSource,at as createEnvironmentVolatileHooks,Sn as createInMemorySessionPool,Hr as createLlmEscalationReviewer,jr as createMemoryDeltaHooks,Dr as createMemoryIndexContextSource,xn as createRemoteSessionPool,Wr as createSessionCompactionLock,N as createSessionStableInjectionHooks,Fr as createTodoReminderHooks,st as createToolHookExecutor,zn as createWorktree,nr as decideApply,R as decideResidency,Bt as defaultMaxToolTurnExtensions,zr as definePromptSection,P as deriveSessionTitle,Zn as diffTouchedPaths,Kr as effectiveResidencyBudget,Lr as formatDocSyncReminder,ne as getEventDomain,dr as globalAgentJobRegistry,br as globalAgentObservability,An as globalProcessRegistry,In as globalProcessRuntime,Ot as globalToolResultStore,Vn as hasRepoDrifted,pr as installAgentJobReaper,Rn as installExitReaper,Mn as installProcessReaper,Mt as isEscalationApproval,ar as jobStateFilePath,Gn as listWorktreeJobIds,Zt as messagesFromSnapshot,Vr as parseVerdict,Kn as pruneOrphanWorktrees,en as reconstructMessages,Q as removeWorktree,ct as resolveSessionTitle,Vt as resolveTodoContinuationConfig,qt as restoreFiles,Wn as revertDiff,rr as toJobStateEntry,er as touchesCapabilitySurface,Qn as touchesForbiddenZone,Bn as worktreeDiff};
48
49
  //# sourceMappingURL=index.js.map