@code-yeongyu/senpi 2026.10.18 → 2026.10.19
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/CHANGELOG.md +47 -0
- package/dist/bundle/chunks/{anthropic-messages-DDBWM4JZ.js → anthropic-messages-EMTBHJMM.js} +2 -2
- package/dist/bundle/chunks/{args-2MYPVFPH.js → args-LWR7VFKS.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-3UG5TQU7.js → azure-openai-responses-SNWKFDXK.js} +1 -1
- package/dist/bundle/chunks/chatgpt-subscription.js +1 -1
- package/dist/bundle/chunks/{chunk-SOF44GFZ.js → chunk-35M5MVUZ.js} +149 -145
- package/dist/bundle/chunks/chunk-3DNYAO3P.js +2 -0
- package/dist/bundle/chunks/{chunk-T2MHSEQ2.js → chunk-5AOKDC6G.js} +1 -1
- package/dist/bundle/chunks/{chunk-MYXNQ7YZ.js → chunk-7QPFFAJT.js} +3 -3
- package/dist/bundle/chunks/{chunk-R36U2DJC.js → chunk-AUZXSLZN.js} +1 -1
- package/dist/bundle/chunks/{chunk-PMTG4YNS.js → chunk-BOCN744P.js} +1 -1
- package/dist/bundle/chunks/{chunk-XTAWER7O.js → chunk-CICJOV6I.js} +1 -1
- package/dist/bundle/chunks/{chunk-4UCLDXEF.js → chunk-FM7NDZR5.js} +1 -1
- package/dist/bundle/chunks/{chunk-TBRWPNA4.js → chunk-FSENE7JK.js} +2 -2
- package/dist/bundle/chunks/{chunk-TUD7XRIS.js → chunk-G7LLAQXI.js} +3 -3
- package/dist/bundle/chunks/{chunk-BGD3MZ47.js → chunk-GOKAWZUO.js} +1 -1
- package/dist/bundle/chunks/{chunk-XC6UG5SI.js → chunk-IM6ZWYTW.js} +2 -2
- package/dist/bundle/chunks/{chunk-KHATAB7P.js → chunk-KM4FMQII.js} +1 -1
- package/dist/bundle/chunks/chunk-LAWS3FYQ.js +11 -0
- package/dist/bundle/chunks/{chunk-W6YQYGE2.js → chunk-MVNVDGYF.js} +1 -1
- package/dist/bundle/chunks/{chunk-W4BO6S7F.js → chunk-PMGEQYEP.js} +2 -2
- package/dist/bundle/chunks/chunk-QGJLZ6BI.js +2 -0
- package/dist/bundle/chunks/{chunk-5RQNCWS2.js → chunk-QJ6MUFXY.js} +1 -1
- package/dist/bundle/chunks/{chunk-57Q7Q627.js → chunk-QRGAMVEE.js} +1 -1
- package/dist/bundle/chunks/{chunk-W2257FYP.js → chunk-QXEWAKXA.js} +1 -1
- package/dist/bundle/chunks/{chunk-UUMKAA7S.js → chunk-RL5QMGQD.js} +9 -9
- package/dist/bundle/chunks/{chunk-D2UQYZVK.js → chunk-SHKXJWK3.js} +1 -1
- package/dist/bundle/chunks/chunk-T36LJ6MW.js +3 -0
- package/dist/bundle/chunks/{chunk-S4V72F76.js → chunk-VCD7FD64.js} +1 -1
- package/dist/bundle/chunks/{chunk-MYPTZCPF.js → chunk-VEKNDMUA.js} +1 -1
- package/dist/bundle/chunks/{chunk-IRBAGET4.js → chunk-VPV7ADF3.js} +4 -4
- package/dist/bundle/chunks/{chunk-6DDAEDY7.js → chunk-WEHIEACU.js} +1 -1
- package/dist/bundle/chunks/{chunk-C2HSPFXN.js → chunk-WQLMQGOW.js} +1 -1
- package/dist/bundle/chunks/{chunk-QZIKKUUP.js → chunk-X6TWPBI6.js} +2 -2
- package/dist/bundle/chunks/{chunk-VYWODOAM.js → chunk-YUMRZIKJ.js} +6 -6
- package/dist/bundle/chunks/chunk-ZPSJQHDK.js +395 -0
- package/dist/bundle/chunks/{cli-main-MVVPTGMS.js → cli-main-EABMHWFV.js} +1 -1
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-H4ZPUBX4.js → cloudflare-workers-ai-system-one-PF7FU63D.js} +1 -1
- package/dist/bundle/chunks/{google-generative-ai-YLAYNQLO.js → google-generative-ai-UFCHYLRE.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-THFXM5R2.js → google-vertex-2FWDY7XX.js} +1 -1
- package/dist/bundle/chunks/{help-fast-path-H4ERPCR5.js → help-fast-path-BYWJN6YX.js} +1 -1
- package/dist/bundle/chunks/{host-command-2CMRIKC3.js → host-command-5T34JLBP.js} +1 -1
- package/dist/bundle/chunks/{host-lifecycle-6Y2EKT4U.js → host-lifecycle-GSRIQP6Z.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle.js +5 -5
- package/dist/bundle/chunks/{host-session-command-MVHY4TKA.js → host-session-command-LF6JODPX.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-2ZQ43N73.js → interactive-mode-GMWHBIUC.js} +1 -1
- package/dist/bundle/chunks/{list-tips-AWDAUHF2.js → list-tips-VSWED3PT.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-GUGTVRCL.js → mistral-conversations-QHZLDTSP.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-NO4PIOVG.js → multi-session-host-3J7STKGD.js} +6 -6
- package/dist/bundle/chunks/openai-codex-responses-7YOBPZ2N.js +10 -0
- package/dist/bundle/chunks/{openai-completions-I5N2UIEK.js → openai-completions-HSZPYXEA.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-SGLUJVZW.js → openai-responses-7W2KF3W7.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +1 -1
- package/dist/bundle/chunks/{package-manager-cli-HTZQXYNI.js → package-manager-cli-LWQZSWKL.js} +1 -1
- package/dist/bundle/chunks/radius.js +1 -1
- package/dist/bundle/chunks/{rotation-stream-TOOIK43C.js → rotation-stream-QRRWL73X.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-6ZWGPICX.js → rpc-mode-6LSWRKXR.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-2YW4B655.js → schedule-command-7CXMW4WK.js} +1 -1
- package/dist/bundle/chunks/{session-control-endpoint-XC2LPLCD.js → session-control-endpoint-E265WAIQ.js} +1 -1
- package/dist/bundle/chunks/{session-picker-7W7GIRJT.js → session-picker-XRB3LP5W.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +315 -310
- package/dist/bundle/chunks/{typesafe-system-one-VBWWTJTF.js → typesafe-system-one-YA75435G.js} +1 -1
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/core/agent-run-continuation.d.ts +24 -0
- package/dist/core/agent-run-continuation.js +57 -0
- package/dist/core/agent-session.d.ts +38 -1
- package/dist/core/agent-session.js +122 -13
- package/dist/core/extension-handler-stall-report.d.ts +11 -0
- package/dist/core/extension-handler-stall-report.js +26 -0
- package/dist/core/extensions/builtin/anthropic-subscription/account-command.js +1 -0
- package/dist/core/extensions/builtin/anthropic-subscription/affinity.d.ts +13 -1
- package/dist/core/extensions/builtin/anthropic-subscription/affinity.js +15 -4
- package/dist/core/extensions/builtin/anthropic-subscription/auth-lane.js +2 -0
- package/dist/core/extensions/builtin/anthropic-subscription/executable.d.ts +5 -0
- package/dist/core/extensions/builtin/anthropic-subscription/executable.js +11 -1
- package/dist/core/extensions/builtin/anthropic-subscription/failover.d.ts +2 -0
- package/dist/core/extensions/builtin/anthropic-subscription/failover.js +3 -2
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.d.ts +8 -0
- package/dist/core/extensions/builtin/anthropic-subscription/guidance.js +29 -0
- package/dist/core/extensions/builtin/anthropic-subscription/settings.d.ts +2 -0
- package/dist/core/extensions/builtin/anthropic-subscription/settings.js +4 -0
- package/dist/core/extensions/builtin/anthropic-subscription/stream-guidance.js +4 -2
- package/dist/core/extensions/handler-budget.d.ts +84 -0
- package/dist/core/extensions/handler-budget.js +136 -0
- package/dist/core/extensions/runner.d.ts +23 -0
- package/dist/core/extensions/runner.js +184 -99
- package/dist/core/footer-data-provider.js +2 -1
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.js +3 -2
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/pending-input-journal.d.ts +6 -1
- package/dist/core/pending-input-journal.js +90 -34
- package/dist/core/pending-input-public.d.ts +11 -0
- package/dist/core/pending-input-public.js +10 -0
- package/dist/core/pending-input-session-port.d.ts +15 -0
- package/dist/core/pending-input-session-port.js +93 -0
- package/dist/core/pending-input-session.d.ts +108 -0
- package/dist/core/pending-input-session.js +220 -0
- package/dist/core/pending-input-store.d.ts +32 -1
- package/dist/core/pending-input-store.js +74 -26
- package/dist/core/pending-input-types.d.ts +25 -4
- package/dist/core/pending-input.js +36 -18
- package/dist/core/session-entry-file.js +1 -0
- package/dist/core/session-log.js +1 -1
- package/dist/core/session-manager.d.ts +1 -0
- package/dist/core/session-manager.js +5 -1
- package/dist/core/session-move/bundle.d.ts +39 -0
- package/dist/core/session-move/bundle.js +108 -0
- package/dist/core/session-move/export.d.ts +18 -0
- package/dist/core/session-move/export.js +83 -0
- package/dist/core/session-move/finish.d.ts +24 -0
- package/dist/core/session-move/finish.js +81 -0
- package/dist/core/session-move/import.d.ts +32 -0
- package/dist/core/session-move/import.js +124 -0
- package/dist/core/session-move/move-ledger.d.ts +47 -0
- package/dist/core/session-move/move-ledger.js +151 -0
- package/dist/core/session-move/ownership.d.ts +61 -0
- package/dist/core/session-move/ownership.js +89 -0
- package/dist/core/session-move/requeue.d.ts +8 -0
- package/dist/core/session-move/requeue.js +18 -0
- package/dist/core/session-move/write-guard.d.ts +22 -0
- package/dist/core/session-move/write-guard.js +44 -0
- package/dist/core/settings-manager.d.ts +13 -0
- package/dist/core/settings-manager.js +17 -0
- package/dist/core/turn-deadline.d.ts +2 -0
- package/dist/core/turn-deadline.js +10 -3
- package/dist/modes/interactive/components/ask-user-async-widget.d.ts +7 -0
- package/dist/modes/interactive/components/ask-user-async-widget.js +20 -6
- package/dist/modes/rpc/connection-handler.js +3 -0
- package/dist/modes/rpc/effect-commands.js +3 -4
- package/dist/modes/rpc/host-decision.d.ts +1 -1
- package/dist/modes/rpc/host-decision.js +2 -0
- package/dist/modes/rpc/host-ensure-liveness.d.ts +8 -0
- package/dist/modes/rpc/host-ensure-liveness.js +18 -1
- package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
- package/dist/modes/rpc/host-ensure.js +8 -2
- package/dist/modes/rpc/host-lifecycle-proxy.d.ts +9 -2
- package/dist/modes/rpc/host-lifecycle-proxy.js +36 -8
- package/dist/modes/rpc/host-observe-request.js +1 -0
- package/dist/modes/rpc/multi-session-host.js +3 -33
- package/dist/modes/rpc/rpc-client.d.ts +10 -0
- package/dist/modes/rpc/rpc-client.js +11 -0
- package/dist/modes/rpc/rpc-input-validation.js +8 -0
- package/dist/modes/rpc/rpc-types.d.ts +25 -1
- package/dist/modes/rpc/session-command-activity.js +1 -0
- package/dist/modes/rpc/session-control-actions-data.js +17 -8
- package/dist/modes/rpc/session-held.js +1 -0
- package/dist/modes/rpc/session-release.js +16 -1
- package/dist/modes/rpc/socket-ownership.d.ts +17 -0
- package/dist/modes/rpc/socket-ownership.js +52 -0
- package/dist/modes/rpc/tool-child/admission.d.ts +42 -0
- package/dist/modes/rpc/tool-child/admission.js +81 -0
- package/dist/modes/rpc/tool-child/admission.test.d.ts +2 -0
- package/dist/modes/rpc/tool-child/admission.test.js +166 -0
- package/dist/modes/rpc/tool-child/codec.d.ts +21 -0
- package/dist/modes/rpc/tool-child/codec.js +137 -0
- package/dist/modes/rpc/tool-child/codec.test.d.ts +2 -0
- package/dist/modes/rpc/tool-child/codec.test.js +234 -0
- package/dist/modes/rpc/tool-child/context.d.ts +42 -0
- package/dist/modes/rpc/tool-child/context.js +23 -0
- package/dist/modes/rpc/tool-child/flow-control.d.ts +24 -0
- package/dist/modes/rpc/tool-child/flow-control.js +80 -0
- package/dist/modes/rpc/tool-child/payload-ref-paths.d.ts +9 -0
- package/dist/modes/rpc/tool-child/payload-ref-paths.js +45 -0
- package/dist/modes/rpc/tool-child/payload-ref.d.ts +58 -0
- package/dist/modes/rpc/tool-child/payload-ref.js +166 -0
- package/dist/modes/rpc/tool-child/payload-ref.test.d.ts +2 -0
- package/dist/modes/rpc/tool-child/payload-ref.test.js +254 -0
- package/dist/modes/rpc/tool-child/payload-wire.d.ts +13 -0
- package/dist/modes/rpc/tool-child/payload-wire.js +22 -0
- package/dist/modes/rpc/tool-child/protocol-guard.d.ts +9 -0
- package/dist/modes/rpc/tool-child/protocol-guard.js +128 -0
- package/dist/modes/rpc/tool-child/protocol.d.ts +192 -0
- package/dist/modes/rpc/tool-child/protocol.js +54 -0
- package/dist/utils/wsl.d.ts +2 -2
- package/dist/utils/wsl.js +4 -4
- package/docs/providers.md +2 -0
- package/docs/rpc.md +20 -2
- package/docs/settings.md +1 -0
- package/docs/terminal-setup.md +2 -0
- package/package.json +10 -6
- package/dist/bundle/chunks/chunk-COJK5FDH.js +0 -2
- package/dist/bundle/chunks/chunk-ES3GHZE5.js +0 -395
- package/dist/bundle/chunks/chunk-IDXW4FAO.js +0 -2
- package/dist/bundle/chunks/chunk-PFNBY43W.js +0 -2
- package/dist/bundle/chunks/chunk-SA2ZLWBD.js +0 -11
- package/dist/bundle/chunks/openai-codex-responses-5LRKZCBW.js +0 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{resolveMovedPath}from"./chunk-4RSWXPUB.js";import{dropFailedAssistantTurns}from"./chunk-
|
|
2
|
+
import{resolveMovedPath}from"./chunk-4RSWXPUB.js";import{dropFailedAssistantTurns}from"./chunk-PMGEQYEP.js";import{CONTEXT_PROVENANCE_FIELD,contextProvenanceFingerprint,copyContextProvenance,getContextProvenance}from"./chunk-AUZXSLZN.js";import{APP_NAME,getAgentDir,getSessionsDir,normalizePath,resolvePath}from"./chunk-G3ZEPNGM.js";import{getCurrentSystemMessage,isModelType,lazyStream,normalizeProviderId}from"./chunk-LAWS3FYQ.js";var VIRTUAL_MODEL_API="pi-virtual",VIRTUAL_MODEL_STATE_ENTRY="pi.virtual-model-state",THINKING_LEVELS=["off","minimal","low","medium","high","xhigh","max"];function isVirtualModel(model){return model.api===VIRTUAL_MODEL_API}function findLatestResponse(messages){for(let i=messages.length-1;i>=0;i--){let message=messages[i];if(message.role==="assistant"&&message.stopReason!=="error"&&message.stopReason!=="aborted")return message}}function getBranchSelection(branch,getModel){for(let i=branch.length-1;i>=0;i--){let entry=branch[i];if(entry.type==="model_change")return{provider:entry.provider,modelId:entry.modelId};if(entry.type==="message"&&entry.message.role==="assistant"&&!isVirtualModel(entry.message)){let response={provider:entry.message.provider,modelId:entry.message.model},change=findLastModelChange(branch,i),model=change&&getModel(change.provider,change.modelId);return change&&model&&isVirtualModel(model)?change:response}}}function findLastModelChange(branch,before){for(let i=before-1;i>=0;i--){let entry=branch[i];if(entry.type==="model_change")return{provider:entry.provider,modelId:entry.modelId}}}function getVirtualModelState(branch,provider,modelId){for(let i=branch.length-1;i>=0;i--){let entry=branch[i];if(entry.type!=="custom"||entry.customType!==VIRTUAL_MODEL_STATE_ENTRY)continue;let data=entry.data;if(data?.provider===provider&&data.modelId===modelId)return data.state}}function createVirtualModel(definition){let levels=definition.thinkingLevels??["off"],thinkingLevelMap={};for(let level of THINKING_LEVELS)thinkingLevelMap[level]=levels.includes(level)?level:null;return{id:definition.id,name:definition.name,api:VIRTUAL_MODEL_API,provider:definition.provider,baseUrl:"",reasoning:levels.some(level=>level!=="off"),thinkingLevelMap,input:definition.input??["text","image"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:definition.contextWindow??0,maxTokens:definition.maxTokens??0}}function unroutedStream(model){return lazyStream(model,async()=>{throw new Error(`Virtual model ${model.provider}/${model.id} must be routed before streaming`)})}function withVirtualModels(providerId,provider,virtualModels){if(!provider)return{id:providerId,name:providerId,auth:{apiKey:{name:"Virtual model",resolve:async()=>({auth:{},source:"virtual"})}},getModels:()=>virtualModels,stream:unroutedStream,streamSimple:unroutedStream};let ids=new Set(virtualModels.map(model=>model.id)),physical=models=>models.filter(model=>!isVirtualModel(model)&&!(isModelType(model,"chat")&&ids.has(model.id))),virtual=models=>models.filter(model=>isVirtualModel(model)),{filterModels,filterAllModels}=provider;return{...provider,getModels:()=>[...physical(provider.getModels()),...virtualModels],getAllModels:()=>[...physical(provider.getAllModels?.()??provider.getModels()),...virtualModels],filterModels:(models,credential)=>{let real=physical(models);return[...filterModels?.(real,credential)??real,...virtual(models)]},filterAllModels:filterAllModels&&((models,credential)=>[...filterAllModels(physical(models),credential),...virtual(models)]),stream:(model,context,options)=>isVirtualModel(model)?unroutedStream(model):provider.stream(model,context,options),streamSimple:(model,context,options)=>isVirtualModel(model)?unroutedStream(model):provider.streamSimple(model,context,options)}}var ENVIRONMENT_CONTEXT_MESSAGE_TYPE="environment-context";function resolveEnvironmentContext(cwd,now=new Date){return{cwd:cwd.replace(/\\/g,"/"),currentDate:now.toISOString().slice(0,10)}}function formatEnvironmentContext(context){return["<environment_context>",` <cwd>${context.cwd}</cwd>`,` <current_date>${context.currentDate}</current_date>`,"</environment_context>"].join(`
|
|
3
3
|
`)}function isEnvironmentContext(value){if(typeof value!="object"||value===null)return!1;let candidate=value;return typeof candidate.cwd=="string"&&typeof candidate.currentDate=="string"}function latestEnvironmentContext(messages){for(let index=messages.length-1;index>=0;index--){let message=messages[index];if(message.role==="custom"&&message.customType===ENVIRONMENT_CONTEXT_MESSAGE_TYPE&&isEnvironmentContext(message.details))return message.details}}function createEnvironmentContextMessage(context,timestamp=Date.now()){return{role:"custom",customType:ENVIRONMENT_CONTEXT_MESSAGE_TYPE,content:formatEnvironmentContext(context),display:!1,details:{cwd:context.cwd,currentDate:context.currentDate},timestamp}}function environmentContextMessageIfChanged(messages,current){let latest=latestEnvironmentContext(messages);if(!(latest?.cwd===current.cwd&&latest.currentDate===current.currentDate))return createEnvironmentContextMessage(current)}function contentBlocks(content){return typeof content=="string"?[{type:"text",text:content}]:content}function foldEnvironmentContextIntoNextUserMessage(messages,environmentMessages){let folded=[];for(let index=0;index<messages.length;index++){let message=messages[index],next=messages[index+1];if(environmentMessages.has(message)&&message.role==="user"&&next?.role==="user"&&!environmentMessages.has(next)){folded.push({...next,content:[...contentBlocks(message.content),...contentBlocks(next.content)]}),index++;continue}folded.push(message)}return folded}import{createHash}from"node:crypto";var IMAGE_ELISION_PLACEHOLDER="[Image elided: an older image was removed to keep the request within the provider's size limit. Re-read the source file if you need to view it again.]",IMAGE_ID_LENGTH=12,ID_SUFFIX=new RegExp(`^ \\(image ids?: ([0-9a-f]{${IMAGE_ID_LENGTH}}(?:, [0-9a-f]{${IMAGE_ID_LENGTH}})*)\\)$`);function imageContentId(data){return createHash("sha256").update(data).digest("hex").slice(0,IMAGE_ID_LENGTH)}function elisionPlaceholder(ids){let label=ids.length===1?"id":"ids";return{type:"text",text:`${IMAGE_ELISION_PLACEHOLDER} (image ${label}: ${ids.join(", ")})`}}function elidedImageIds(text){return text.startsWith(IMAGE_ELISION_PLACEHOLDER)?ID_SUFFIX.exec(text.slice(IMAGE_ELISION_PLACEHOLDER.length))?.[1]?.split(", "):void 0}function replaceElidedImages(content,isElided){let replaced=[],pending=[],flush=()=>{pending.length>0&&replaced.push(elisionPlaceholder(pending)),pending=[]};return content.forEach((block,blockIndex)=>{if(block.type==="image"&&isElided(blockIndex)){pending.push(imageContentId(block.data));return}flush(),replaced.push(block)}),flush(),replaced}var PROVIDER_IMAGE_REJECTION_PATTERN=/does not represent a valid image|image_parse_error|invalid_image|unsupported image|could not process image|unable to process input image|image_url'?\.?[^\n]*invalid base64|expected a base64-encoded data url|image was specified using the image\/[a-z]+ media type|unsupported media type for base64 image|invalid data url for image/i;function isProviderImageRejection(errorMessage){return errorMessage!==void 0&&PROVIDER_IMAGE_REJECTION_PATTERN.test(errorMessage)}function rejectedImagePlaceholder(source){return`[Image omitted: the provider rejected this image (${source}) as invalid, so it is no longer sent with the conversation.]`}function field(message,key){return key in message?message[key]:void 0}function contentBlocks2(message){let content=field(message,"content");return Array.isArray(content)?content:[]}function toolCallSource(block){let args=block.arguments;if(typeof args!="object"||args===null)return;let record=args;for(let key of["path","file_path","filePath"]){let value=record[key];if(typeof value=="string"&&value.trim().length>0)return value}}function imageSource(message,toolCallSources){if(message.role!=="toolResult")return"an attached image";let toolCallId=field(message,"toolCallId"),known=typeof toolCallId=="string"?toolCallSources.get(toolCallId):void 0;if(known)return known;let toolName=field(message,"toolName");return typeof toolName=="string"?`${toolName} tool result`:"a tool result"}function scanRejectedImages(messages){let toolCallSources=new Map,rejections=new Map,unconfirmed=[];return messages.forEach((message,messageIndex)=>{if(message.role==="assistant"){for(let block of contentBlocks2(message)){let source=block.type==="toolCall"?toolCallSource(block):void 0;source&&typeof block.id=="string"&&toolCallSources.set(block.id,source)}let stopReason=field(message,"stopReason"),errorMessage=field(message,"errorMessage");stopReason==="error"&&isProviderImageRejection(typeof errorMessage=="string"?errorMessage:void 0)?(unconfirmed.length>0&&rejections.set(messageIndex,unconfirmed),unconfirmed=[]):stopReason!=="error"&&stopReason!=="aborted"&&(unconfirmed=[]);return}message.role!=="user"&&message.role!=="toolResult"||contentBlocks2(message).forEach((block,blockIndex)=>{block.type==="image"&&unconfirmed.push({messageIndex,blockIndex,source:imageSource(message,toolCallSources)})})}),rejections}function rejectedImageSources(messages,failedTurn){let failedIndex=messages.lastIndexOf(failedTurn);return(scanRejectedImages(messages).get(failedIndex)??[]).map(image=>image.source)}function omitProviderRejectedImages(messages){let rejected=new Map;for(let images of scanRejectedImages(messages).values())for(let image of images){let blocks=rejected.get(image.messageIndex)??new Map;blocks.set(image.blockIndex,image.source),rejected.set(image.messageIndex,blocks)}return rejected.size===0?messages:messages.map((message,messageIndex)=>{let blocks=rejected.get(messageIndex);if(!blocks)return message;let content=contentBlocks2(message).map((block,blockIndex)=>{let source=blocks.get(blockIndex);return source===void 0?block:{type:"text",text:rejectedImagePlaceholder(source)}});return{...message,content}})}function isUserWord(value){return typeof value=="object"&&value!==null&&"label"in value&&typeof value.label=="string"&&"text"in value&&typeof value.text=="string"}function toolResultUserWords(message){let details=message.details;return typeof details!="object"||details===null||!("userWords"in details)?[]:Array.isArray(details.userWords)?details.userWords.filter(isUserWord):[]}function userWordBlocks(words){return words.flatMap(word=>[{type:"text",text:`[${word.label}]`},{type:"text",text:word.text}])}function appendToolResultUserWords(messages){if(!messages.some(message=>message.role==="toolResult"&&toolResultUserWords(message).length>0))return messages;let result=[],pending=[],source,flush=next=>{source&&!startsWithBlocks(next,pending)&&result.push(wordMessage(pending,source)),pending=[],source=void 0};for(let message of messages){if(message.role!=="toolResult"&&flush(message),result.push(message),message.role!=="toolResult")continue;let blocks=userWordBlocks(toolResultUserWords(message));blocks.length!==0&&(pending.push(...blocks),source=message)}return flush(void 0),result}function wordMessage(content,source){let message={role:"user",content,timestamp:source.timestamp},provenance=getContextProvenance(source);if(!provenance)return message;let{integrity,...owned}=provenance;if(!(integrity===void 0||integrity===contextProvenanceFingerprint(source)))return message;let sealed=integrity===void 0?owned:{...owned,integrity:contextProvenanceFingerprint(message)};return Object.assign(message,{[CONTEXT_PROVENANCE_FIELD]:sealed})}function startsWithBlocks(message,blocks){if(message?.role!=="user"||typeof message.content=="string")return!1;let content=message.content;return blocks.every((block,index)=>{let candidate=content[index];return candidate?.type==="text"&&candidate.text===block.text})}var COMPACTION_SUMMARY_PREFIX=`The conversation history before this point was compacted into the following summary:
|
|
4
4
|
|
|
5
5
|
<summary>
|
|
@@ -16,7 +16,7 @@ ${msg.output}
|
|
|
16
16
|
|
|
17
17
|
Command exited with code ${msg.exitCode}`),msg.truncated&&msg.fullOutputPath&&(text+=`
|
|
18
18
|
|
|
19
|
-
[Output truncated. Full output: ${msg.fullOutputPath}]`),text}function createBranchSummaryMessage(summary,fromId,timestamp){return{role:"branchSummary",summary,fromId,timestamp:new Date(timestamp).getTime()}}function createCompactionSummaryMessage(summary,tokensBefore,timestamp,details){return{role:"compactionSummary",summary,tokensBefore,details,timestamp:new Date(timestamp).getTime()}}function createCustomMessage(customType,content,display,details,timestamp){return{role:"custom",customType,content,display,details,timestamp:new Date(timestamp).getTime()}}function convertToLlm(messages){let withContextProvenance=(source,target)=>copyContextProvenance(source,target),environmentMessages=new Set,converted=messages.map(m=>{switch(m.role){case"bashExecution":return m.excludeFromContext?void 0:withContextProvenance(m,{role:"user",content:[{type:"text",text:bashExecutionToText(m)}],timestamp:m.timestamp});case"custom":{if(isContextExcludedCustomMessage(m.customType))return;let content=typeof m.content=="string"?[{type:"text",text:m.content}]:m.content,converted2=withContextProvenance(m,{role:"user",content,timestamp:m.timestamp});return m.customType===ENVIRONMENT_CONTEXT_MESSAGE_TYPE&&environmentMessages.add(converted2),converted2}case"branchSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:BRANCH_SUMMARY_PREFIX+m.summary+BRANCH_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"compactionSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:COMPACTION_SUMMARY_PREFIX+m.summary+COMPACTION_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"configurationUpdate":return m;case"system":case"user":case"assistant":case"toolResult":return m;default:let _exhaustiveCheck=m;return}}).filter(m=>m!==void 0);return foldEnvironmentContextIntoNextUserMessage(appendToolResultUserWords(dropFailedAssistantTurns(omitProviderRejectedImages(converted))),environmentMessages)}var TRANSPORT_IMAGE_BUDGET_BYTES=24*1024*1024,BLOCKED_IMAGE_PLACEHOLDER="Image reading is disabled.";function dedupeConsecutivePlaceholder(content,placeholder){return content.filter((block,index,blocks)=>!(block.type==="text"&&block.text===placeholder&&index>0&&blocks[index-1].type==="text"&&blocks[index-1].text===placeholder))}function elideOldImages(messages,options){let budgetBytes=options?.budgetBytes??TRANSPORT_IMAGE_BUDGET_BYTES,alwaysKeepNewest=options?.alwaysKeepNewest??1,maxHistoricalImages=options?.maxHistoricalImages,lastAssistantIndex=messages.findLastIndex(message=>message.role==="assistant"),images=[];messages.forEach((message,messageIndex)=>{message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||message.content.forEach((block,blockIndex)=>{block.type==="image"&&images.push({key:`${messageIndex}:${blockIndex}`,bytes:block.data.length,currentTurn:maxHistoricalImages!==void 0&&messageIndex>lastAssistantIndex})})});let imagesToElide=new Set;if(maxHistoricalImages!==void 0){let historical=images.filter(image=>!image.currentTurn),step=Math.max(1,Math.floor(maxHistoricalImages/2)),excess=historical.length-maxHistoricalImages,cutoff=excess>0?Math.ceil(excess/step)*step:0;for(let image of historical.slice(0,cutoff))imagesToElide.add(image.key)}else{let protectedKeys=new Set(images.slice(Math.max(0,images.length-alwaysKeepNewest)).map(image=>image.key)),total=images.reduce((sum,image)=>sum+image.bytes,0);if(total>budgetBytes){let step=Math.max(1,Math.floor(budgetBytes/2)),threshold=Math.ceil((total-budgetBytes)/step)*step,offset=0,elidedBytes=0,straddler;for(let image of images){let start=offset;offset+=image.bytes,!protectedKeys.has(image.key)&&(offset<=threshold?(imagesToElide.add(image.key),elidedBytes+=image.bytes):start<threshold&&straddler===void 0&&(straddler=image))}straddler!==void 0&&total-elidedBytes>budgetBytes&&imagesToElide.add(straddler.key)}}return imagesToElide.size===0?messages:messages.map((message,messageIndex)=>message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some((_block,blockIndex)=>imagesToElide.has(`${messageIndex}:${blockIndex}`))?message:{...message,content:replaceElidedImages(message.content,blockIndex=>imagesToElide.has(`${messageIndex}:${blockIndex}`))})}function convertToLlmForTransport(messages,options){let converted=convertToLlm(messages);return options.blockImages?converted.map(message=>{if(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some(block=>block.type==="image"))return message;let replaced=message.content.map(block=>block.type==="image"?{type:"text",text:BLOCKED_IMAGE_PLACEHOLDER}:block);return{...message,content:dedupeConsecutivePlaceholder(replaced,BLOCKED_IMAGE_PLACEHOLDER)}}):elideOldImages(converted,options)}import{randomBytes,randomUUID as randomUUID2}from"crypto";import{appendFileSync,closeSync as closeSync4,existsSync as existsSync4,mkdirSync as mkdirSync2,openSync as openSync4,readdirSync,readSync as readSync3,rmSync as rmSync4,statSync as statSync3,writeFileSync as writeFileSync3}from"fs";import{appendFile as appendFile2,open as open3,readdir as readdir2,rm as rm3}from"fs/promises";import{join as join5,resolve as resolve2}from"path";import{StringDecoder as StringDecoder3}from"string_decoder";var EventLoopSlicer=class{constructor(options={}){this.budgetMs=options.budgetMs??8,this.clock=options.clock??(()=>performance.now()),this.sliceStart=this.clock()}get due(){return this.clock()-this.sliceStart>=this.budgetMs}async yield(){await new Promise(resolve3=>setImmediate(resolve3)),this.sliceStart=this.clock()}};async function mapInSlices(items,transform,slicer){let mapped=[];for(let item of items)mapped.push(transform(item)),slicer.due&&await slicer.yield();return mapped}var OMIT_JSON_VALUE=Symbol("omit-json-value");function transformJson(value,transformString){let transformed=transformJsonValue(value,transformString,"",new WeakSet);if(transformed===OMIT_JSON_VALUE){let serialized=JSON.stringify(value);if(serialized===void 0)throw new SyntaxError("JSON-compatible value expected");return JSON.parse(serialized)}return transformed}function transformJsonValue(value,transformString,key,seen){if(typeof value=="string")return transformString(value);if(typeof value=="number")return Number.isFinite(value)?value:null;if(value===null||typeof value=="boolean")return value;if(typeof value=="bigint")throw new TypeError("Do not know how to serialize a BigInt");if(typeof value>"u"||typeof value=="function"||typeof value=="symbol")return OMIT_JSON_VALUE;if(seen.has(value))throw new TypeError("Converting circular structure to JSON");seen.add(value);let jsonValue=hasJsonSerializer(value)?value.toJSON(key):value;if(jsonValue!==value){let transformed2=transformJsonValue(jsonValue,transformString,key,seen);return seen.delete(value),transformed2}if(Array.isArray(value)){let transformed2=Array.from({length:value.length},(_item,index)=>{let item=value[index],transformedItem=transformJsonValue(item,transformString,String(index),seen);return transformedItem===OMIT_JSON_VALUE?null:transformedItem});return seen.delete(value),transformed2}let transformed={};for(let[key2,item]of Object.entries(value)){let transformedItem=transformJsonValue(item,transformString,String(key2),seen);transformedItem!==OMIT_JSON_VALUE&&Object.defineProperty(transformed,key2,{configurable:!0,enumerable:!0,value:transformedItem,writable:!0})}return seen.delete(value),transformed}function hasJsonSerializer(value){return"toJSON"in value&&typeof value.toJSON=="function"}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isFiniteNumber(value){return typeof value=="number"&&Number.isFinite(value)}function hasTextOnlyContent(content,allowString){return typeof content=="string"?allowString:Array.isArray(content)?content.every(block=>isRecord(block)&&block.type==="text"&&typeof block.text=="string"):!1}function isWellFormedImageBlock(block){return block.type==="image"&&typeof block.mimeType=="string"&&block.mimeType.startsWith("image/")&&typeof block.data=="string"&&block.data.length>0}function hasSafeToolResultContent(content){return Array.isArray(content)?content.every(block=>isRecord(block)&&(block.type==="text"&&typeof block.text=="string"||isWellFormedImageBlock(block))):!1}function isUsage(value){if(!isRecord(value)||!isRecord(value.cost))return!1;for(let field2 of["input","output","cacheRead","cacheWrite","totalTokens"])if(!isFiniteNumber(value[field2]))return!1;for(let field2 of["input","output","cacheRead","cacheWrite","total"])if(!isFiniteNumber(value.cost[field2]))return!1;return(value.cacheWrite1h===void 0||isFiniteNumber(value.cacheWrite1h))&&(value.reasoning===void 0||isFiniteNumber(value.reasoning))}var base64SignaturePattern=/^[A-Za-z0-9+/]+={0,2}$/;function isValidOpaqueSignature(sig){return typeof sig=="string"&&sig.length>0&&sig.length<=65536}function isValidProviderSignature(sig,providerIsGoogle){return isValidOpaqueSignature(sig)?!providerIsGoogle||sig.length%4===0&&base64SignaturePattern.test(sig):!1}function hasSafeAssistantContent(content,providerIsGoogle){if(!Array.isArray(content))return!1;for(let block of content){if(!isRecord(block)||typeof block.type!="string")return!1;switch(block.type){case"text":if(typeof block.text!="string"||block.textSignature!==void 0&&!isValidProviderSignature(block.textSignature,providerIsGoogle))return!1;break;case"thinking":if(typeof block.thinking!="string"||block.startedAt!==void 0&&!isFiniteNumber(block.startedAt)||block.endedAt!==void 0&&!isFiniteNumber(block.endedAt)||block.redacted!==void 0&&typeof block.redacted!="boolean"||block.thinkingSignature!==void 0&&!isValidProviderSignature(block.thinkingSignature,providerIsGoogle)||block.redacted===!0&&!isValidOpaqueSignature(block.thinkingSignature))return!1;break;case"toolCall":if(typeof block.id!="string"||typeof block.name!="string"||!isRecord(block.arguments)||block.incomplete!==void 0&&block.incomplete!==!0||block.errorMessage!==void 0&&typeof block.errorMessage!="string"||block.thoughtSignature!==void 0&&!isValidProviderSignature(block.thoughtSignature,providerIsGoogle))return!1;break;default:return!1}}return!0}function hasSafeAssistantEnvelope(message){let provider=typeof message.provider=="string"?message.provider:"",providerIsGoogle=provider==="google"||provider==="google-vertex",stopReason=message.stopReason,stopDetails=message.stopDetails,safeStopDetails=stopDetails===void 0||isRecord(stopDetails)&&(stopDetails.type==="sensitive"||stopDetails.type==="refusal"&&(stopDetails.explanation===void 0||typeof stopDetails.explanation=="string"));return typeof message.api=="string"&&typeof message.provider=="string"&&typeof message.model=="string"&&isUsage(message.usage)&&(stopReason==="pending"||stopReason==="stop"||stopReason==="length"||stopReason==="toolUse"||stopReason==="error"||stopReason==="aborted")&&safeStopDetails&&isFiniteNumber(message.timestamp)&&(message.responseModel===void 0||typeof message.responseModel=="string")&&(message.responseId===void 0||typeof message.responseId=="string")&&(message.diagnostics===void 0||Array.isArray(message.diagnostics))&&(message.errorMessage===void 0||typeof message.errorMessage=="string")&&(message.rawStopReason===void 0||typeof message.rawStopReason=="string")&&hasSafeAssistantContent(message.content,providerIsGoogle)}function hasSafeToolResultEnvelope(message){return typeof message.toolCallId=="string"&&message.toolCallId.length>0&&typeof message.toolName=="string"&&message.toolName.length>0&&hasSafeToolResultContent(message.content)&&typeof message.isError=="boolean"&&isFiniteNumber(message.timestamp)&&(message.usage===void 0||isUsage(message.usage))&&(message.addedToolNames===void 0||Array.isArray(message.addedToolNames)&&message.addedToolNames.every(name=>typeof name=="string"))}function hasUnsafeRetainedContent(messages){for(let value of messages){if(!isRecord(value)||typeof value.role!="string")return!0;switch(value.role){case"user":if(!isFiniteNumber(value.timestamp)||!hasTextOnlyContent(value.content,!0))return!0;break;case"assistant":if(!hasSafeAssistantEnvelope(value))return!0;break;case"toolResult":if(!hasSafeToolResultEnvelope(value))return!0;break;case"custom":if(typeof value.customType!="string"||typeof value.display!="boolean"||!isFiniteNumber(value.timestamp)||!hasTextOnlyContent(value.content,!0))return!0;break;case"bashExecution":if(typeof value.command!="string"||typeof value.output!="string"||value.exitCode!==void 0&&!isFiniteNumber(value.exitCode)||typeof value.cancelled!="boolean"||typeof value.truncated!="boolean"||value.fullOutputPath!==void 0&&typeof value.fullOutputPath!="string"||value.excludeFromContext!==void 0&&typeof value.excludeFromContext!="boolean"||!isFiniteNumber(value.timestamp))return!0;break;case"compactionSummary":if(typeof value.summary!="string"||!isFiniteNumber(value.tokensBefore)||!isFiniteNumber(value.timestamp))return!0;break;default:return!0}}return!1}function isSafeBoundedValue(value,seen=new Set,depth=0){if(depth>32)return!1;if(value==null)return!0;let kind=typeof value;if(kind==="string"||kind==="number"||kind==="boolean")return!0;if(kind!=="object"||seen.has(value))return!1;if(seen.add(value),Array.isArray(value)){for(let item of value)if(!isSafeBoundedValue(item,seen,depth+1))return!1;return!0}let proto=Object.getPrototypeOf(value);if(proto!==Object.prototype&&proto!==null)return!1;for(let descriptor of Object.values(Object.getOwnPropertyDescriptors(value)))if(descriptor.get!==void 0||descriptor.set!==void 0||!isSafeBoundedValue(descriptor.value,seen,depth+1))return!1;return!0}function projectRetainedMessages(messages){let omittedCalls=new Set;return messages.map(original=>{let message=original,safe=!1;try{message=transformJson(original,text2=>text2),safe=isSafeBoundedValue(message)&&!hasUnsafeRetainedContent([message])}catch{}if(message.role==="assistant"&&Array.isArray(message.content))for(let block of message.content)block?.type!=="toolCall"||typeof block.id!="string"||(safe?omittedCalls.delete(block.id):omittedCalls.add(block.id));let orphanedByOmission=message.role==="toolResult"&&omittedCalls.has(message.toolCallId);if(safe&&!orphanedByOmission)return message;let timestamp=Number.isFinite(message.timestamp)?message.timestamp:0;if(message.role==="toolResult"&&!orphanedByOmission&&typeof message.toolCallId=="string"&&message.toolCallId.length>0&&typeof message.toolName=="string"&&message.toolName.length>0)return{role:"toolResult",toolCallId:message.toolCallId,toolName:message.toolName,content:[{type:"text",text:"[tool result omitted from retained context: not replay-safe]"}],isError:!0,timestamp};let text=message.role==="user"?typeof message.content=="string"?message.content:Array.isArray(message.content)?message.content.flatMap(block=>block?.type==="text"&&typeof block.text=="string"?[block.text]:[]).join(`
|
|
19
|
+
[Output truncated. Full output: ${msg.fullOutputPath}]`),text}function createBranchSummaryMessage(summary,fromId,timestamp){return{role:"branchSummary",summary,fromId,timestamp:new Date(timestamp).getTime()}}function createCompactionSummaryMessage(summary,tokensBefore,timestamp,details){return{role:"compactionSummary",summary,tokensBefore,details,timestamp:new Date(timestamp).getTime()}}function createCustomMessage(customType,content,display,details,timestamp){return{role:"custom",customType,content,display,details,timestamp:new Date(timestamp).getTime()}}function convertToLlm(messages){let withContextProvenance=(source,target)=>copyContextProvenance(source,target),environmentMessages=new Set,converted=messages.map(m=>{switch(m.role){case"bashExecution":return m.excludeFromContext?void 0:withContextProvenance(m,{role:"user",content:[{type:"text",text:bashExecutionToText(m)}],timestamp:m.timestamp});case"custom":{if(isContextExcludedCustomMessage(m.customType))return;let content=typeof m.content=="string"?[{type:"text",text:m.content}]:m.content,converted2=withContextProvenance(m,{role:"user",content,timestamp:m.timestamp});return m.customType===ENVIRONMENT_CONTEXT_MESSAGE_TYPE&&environmentMessages.add(converted2),converted2}case"branchSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:BRANCH_SUMMARY_PREFIX+m.summary+BRANCH_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"compactionSummary":return withContextProvenance(m,{role:"user",content:[{type:"text",text:COMPACTION_SUMMARY_PREFIX+m.summary+COMPACTION_SUMMARY_SUFFIX}],timestamp:m.timestamp});case"configurationUpdate":return m;case"system":case"user":case"assistant":case"toolResult":return m;default:let _exhaustiveCheck=m;return}}).filter(m=>m!==void 0);return foldEnvironmentContextIntoNextUserMessage(appendToolResultUserWords(dropFailedAssistantTurns(omitProviderRejectedImages(converted))),environmentMessages)}var TRANSPORT_IMAGE_BUDGET_BYTES=24*1024*1024,BLOCKED_IMAGE_PLACEHOLDER="Image reading is disabled.";function dedupeConsecutivePlaceholder(content,placeholder){return content.filter((block,index,blocks)=>!(block.type==="text"&&block.text===placeholder&&index>0&&blocks[index-1].type==="text"&&blocks[index-1].text===placeholder))}function elideOldImages(messages,options){let budgetBytes=options?.budgetBytes??TRANSPORT_IMAGE_BUDGET_BYTES,alwaysKeepNewest=options?.alwaysKeepNewest??1,maxHistoricalImages=options?.maxHistoricalImages,lastAssistantIndex=messages.findLastIndex(message=>message.role==="assistant"),images=[];messages.forEach((message,messageIndex)=>{message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||message.content.forEach((block,blockIndex)=>{block.type==="image"&&images.push({key:`${messageIndex}:${blockIndex}`,bytes:block.data.length,currentTurn:maxHistoricalImages!==void 0&&messageIndex>lastAssistantIndex})})});let imagesToElide=new Set;if(maxHistoricalImages!==void 0){let historical=images.filter(image=>!image.currentTurn),step=Math.max(1,Math.floor(maxHistoricalImages/2)),excess=historical.length-maxHistoricalImages,cutoff=excess>0?Math.ceil(excess/step)*step:0;for(let image of historical.slice(0,cutoff))imagesToElide.add(image.key)}else{let protectedKeys=new Set(images.slice(Math.max(0,images.length-alwaysKeepNewest)).map(image=>image.key)),total=images.reduce((sum,image)=>sum+image.bytes,0);if(total>budgetBytes){let step=Math.max(1,Math.floor(budgetBytes/2)),threshold=Math.ceil((total-budgetBytes)/step)*step,offset=0,elidedBytes=0,straddler;for(let image of images){let start=offset;offset+=image.bytes,!protectedKeys.has(image.key)&&(offset<=threshold?(imagesToElide.add(image.key),elidedBytes+=image.bytes):start<threshold&&straddler===void 0&&(straddler=image))}straddler!==void 0&&total-elidedBytes>budgetBytes&&imagesToElide.add(straddler.key)}}return imagesToElide.size===0?messages:messages.map((message,messageIndex)=>message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some((_block,blockIndex)=>imagesToElide.has(`${messageIndex}:${blockIndex}`))?message:{...message,content:replaceElidedImages(message.content,blockIndex=>imagesToElide.has(`${messageIndex}:${blockIndex}`))})}function convertToLlmForTransport(messages,options){let converted=convertToLlm(messages);return options.blockImages?converted.map(message=>{if(message.role!=="user"&&message.role!=="toolResult"||!Array.isArray(message.content)||!message.content.some(block=>block.type==="image"))return message;let replaced=message.content.map(block=>block.type==="image"?{type:"text",text:BLOCKED_IMAGE_PLACEHOLDER}:block);return{...message,content:dedupeConsecutivePlaceholder(replaced,BLOCKED_IMAGE_PLACEHOLDER)}}):elideOldImages(converted,options)}import{randomBytes,randomUUID as randomUUID2}from"crypto";import{appendFileSync,closeSync as closeSync4,existsSync as existsSync4,mkdirSync as mkdirSync2,openSync as openSync4,readdirSync,readSync as readSync3,rmSync as rmSync4,statSync as statSync3,writeFileSync as writeFileSync3}from"fs";import{appendFile as appendFile2,open as open3,readdir as readdir2,rm as rm3}from"fs/promises";import{join as join5,resolve as resolve2}from"path";import{StringDecoder as StringDecoder3}from"string_decoder";var EventLoopSlicer=class{constructor(options={}){this.budgetMs=options.budgetMs??8,this.clock=options.clock??(()=>performance.now()),this.sliceStart=this.clock()}get due(){return this.clock()-this.sliceStart>=this.budgetMs}async yield(){await new Promise(resolve3=>setImmediate(resolve3)),this.sliceStart=this.clock()}};async function mapInSlices(items,transform,slicer){let mapped=[];for(let item of items)mapped.push(transform(item)),slicer.due&&await slicer.yield();return mapped}var OMIT_JSON_VALUE=Symbol("omit-json-value");function transformJson(value,transformString){let transformed=transformJsonValue(value,transformString,"",new WeakSet);if(transformed===OMIT_JSON_VALUE){let serialized=JSON.stringify(value);if(serialized===void 0)throw new SyntaxError("JSON-compatible value expected");return JSON.parse(serialized)}return transformed}function transformJsonValue(value,transformString,key,seen){if(typeof value=="string")return transformString(value);if(typeof value=="number")return Number.isFinite(value)?value:null;if(value===null||typeof value=="boolean")return value;if(typeof value=="bigint")throw new TypeError("Do not know how to serialize a BigInt");if(typeof value>"u"||typeof value=="function"||typeof value=="symbol")return OMIT_JSON_VALUE;if(seen.has(value))throw new TypeError("Converting circular structure to JSON");seen.add(value);let jsonValue=hasJsonSerializer(value)?value.toJSON(key):value;if(jsonValue!==value){let transformed2=transformJsonValue(jsonValue,transformString,key,seen);return seen.delete(value),transformed2}if(Array.isArray(value)){let transformed2=Array.from({length:value.length},(_item,index)=>{let item=value[index],transformedItem=transformJsonValue(item,transformString,String(index),seen);return transformedItem===OMIT_JSON_VALUE?null:transformedItem});return seen.delete(value),transformed2}let transformed={};for(let[key2,item]of Object.entries(value)){let transformedItem=transformJsonValue(item,transformString,String(key2),seen);transformedItem!==OMIT_JSON_VALUE&&Object.defineProperty(transformed,key2,{configurable:!0,enumerable:!0,value:transformedItem,writable:!0})}return seen.delete(value),transformed}function hasJsonSerializer(value){return"toJSON"in value&&typeof value.toJSON=="function"}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isFiniteNumber(value){return typeof value=="number"&&Number.isFinite(value)}function hasTextOnlyContent(content,allowString){return typeof content=="string"?allowString:Array.isArray(content)?content.every(block=>isRecord(block)&&block.type==="text"&&typeof block.text=="string"):!1}function isWellFormedImageBlock(block){return block.type==="image"&&typeof block.mimeType=="string"&&block.mimeType.startsWith("image/")&&typeof block.data=="string"&&block.data.length>0}function hasSafeToolResultContent(content){return Array.isArray(content)?content.every(block=>isRecord(block)&&(block.type==="text"&&typeof block.text=="string"||isWellFormedImageBlock(block))):!1}function isUsage(value){if(!isRecord(value)||!isRecord(value.cost))return!1;for(let field3 of["input","output","cacheRead","cacheWrite","totalTokens"])if(!isFiniteNumber(value[field3]))return!1;for(let field3 of["input","output","cacheRead","cacheWrite","total"])if(!isFiniteNumber(value.cost[field3]))return!1;return(value.cacheWrite1h===void 0||isFiniteNumber(value.cacheWrite1h))&&(value.reasoning===void 0||isFiniteNumber(value.reasoning))}var base64SignaturePattern=/^[A-Za-z0-9+/]+={0,2}$/;function isValidOpaqueSignature(sig){return typeof sig=="string"&&sig.length>0&&sig.length<=65536}function isValidProviderSignature(sig,providerIsGoogle){return isValidOpaqueSignature(sig)?!providerIsGoogle||sig.length%4===0&&base64SignaturePattern.test(sig):!1}function hasSafeAssistantContent(content,providerIsGoogle){if(!Array.isArray(content))return!1;for(let block of content){if(!isRecord(block)||typeof block.type!="string")return!1;switch(block.type){case"text":if(typeof block.text!="string"||block.textSignature!==void 0&&!isValidProviderSignature(block.textSignature,providerIsGoogle))return!1;break;case"thinking":if(typeof block.thinking!="string"||block.startedAt!==void 0&&!isFiniteNumber(block.startedAt)||block.endedAt!==void 0&&!isFiniteNumber(block.endedAt)||block.redacted!==void 0&&typeof block.redacted!="boolean"||block.thinkingSignature!==void 0&&!isValidProviderSignature(block.thinkingSignature,providerIsGoogle)||block.redacted===!0&&!isValidOpaqueSignature(block.thinkingSignature))return!1;break;case"toolCall":if(typeof block.id!="string"||typeof block.name!="string"||!isRecord(block.arguments)||block.incomplete!==void 0&&block.incomplete!==!0||block.errorMessage!==void 0&&typeof block.errorMessage!="string"||block.thoughtSignature!==void 0&&!isValidProviderSignature(block.thoughtSignature,providerIsGoogle))return!1;break;default:return!1}}return!0}function hasSafeAssistantEnvelope(message){let provider=typeof message.provider=="string"?message.provider:"",providerIsGoogle=provider==="google"||provider==="google-vertex",stopReason=message.stopReason,stopDetails=message.stopDetails,safeStopDetails=stopDetails===void 0||isRecord(stopDetails)&&(stopDetails.type==="sensitive"||stopDetails.type==="refusal"&&(stopDetails.explanation===void 0||typeof stopDetails.explanation=="string"));return typeof message.api=="string"&&typeof message.provider=="string"&&typeof message.model=="string"&&isUsage(message.usage)&&(stopReason==="pending"||stopReason==="stop"||stopReason==="length"||stopReason==="toolUse"||stopReason==="error"||stopReason==="aborted")&&safeStopDetails&&isFiniteNumber(message.timestamp)&&(message.responseModel===void 0||typeof message.responseModel=="string")&&(message.responseId===void 0||typeof message.responseId=="string")&&(message.diagnostics===void 0||Array.isArray(message.diagnostics))&&(message.errorMessage===void 0||typeof message.errorMessage=="string")&&(message.rawStopReason===void 0||typeof message.rawStopReason=="string")&&hasSafeAssistantContent(message.content,providerIsGoogle)}function hasSafeToolResultEnvelope(message){return typeof message.toolCallId=="string"&&message.toolCallId.length>0&&typeof message.toolName=="string"&&message.toolName.length>0&&hasSafeToolResultContent(message.content)&&typeof message.isError=="boolean"&&isFiniteNumber(message.timestamp)&&(message.usage===void 0||isUsage(message.usage))&&(message.addedToolNames===void 0||Array.isArray(message.addedToolNames)&&message.addedToolNames.every(name=>typeof name=="string"))}function hasUnsafeRetainedContent(messages){for(let value of messages){if(!isRecord(value)||typeof value.role!="string")return!0;switch(value.role){case"user":if(!isFiniteNumber(value.timestamp)||!hasTextOnlyContent(value.content,!0))return!0;break;case"assistant":if(!hasSafeAssistantEnvelope(value))return!0;break;case"toolResult":if(!hasSafeToolResultEnvelope(value))return!0;break;case"custom":if(typeof value.customType!="string"||typeof value.display!="boolean"||!isFiniteNumber(value.timestamp)||!hasTextOnlyContent(value.content,!0))return!0;break;case"bashExecution":if(typeof value.command!="string"||typeof value.output!="string"||value.exitCode!==void 0&&!isFiniteNumber(value.exitCode)||typeof value.cancelled!="boolean"||typeof value.truncated!="boolean"||value.fullOutputPath!==void 0&&typeof value.fullOutputPath!="string"||value.excludeFromContext!==void 0&&typeof value.excludeFromContext!="boolean"||!isFiniteNumber(value.timestamp))return!0;break;case"compactionSummary":if(typeof value.summary!="string"||!isFiniteNumber(value.tokensBefore)||!isFiniteNumber(value.timestamp))return!0;break;default:return!0}}return!1}function isSafeBoundedValue(value,seen=new Set,depth=0){if(depth>32)return!1;if(value==null)return!0;let kind=typeof value;if(kind==="string"||kind==="number"||kind==="boolean")return!0;if(kind!=="object"||seen.has(value))return!1;if(seen.add(value),Array.isArray(value)){for(let item of value)if(!isSafeBoundedValue(item,seen,depth+1))return!1;return!0}let proto=Object.getPrototypeOf(value);if(proto!==Object.prototype&&proto!==null)return!1;for(let descriptor of Object.values(Object.getOwnPropertyDescriptors(value)))if(descriptor.get!==void 0||descriptor.set!==void 0||!isSafeBoundedValue(descriptor.value,seen,depth+1))return!1;return!0}function projectRetainedMessages(messages){let omittedCalls=new Set;return messages.map(original=>{let message=original,safe=!1;try{message=transformJson(original,text2=>text2),safe=isSafeBoundedValue(message)&&!hasUnsafeRetainedContent([message])}catch{}if(message.role==="assistant"&&Array.isArray(message.content))for(let block of message.content)block?.type!=="toolCall"||typeof block.id!="string"||(safe?omittedCalls.delete(block.id):omittedCalls.add(block.id));let orphanedByOmission=message.role==="toolResult"&&omittedCalls.has(message.toolCallId);if(safe&&!orphanedByOmission)return message;let timestamp=Number.isFinite(message.timestamp)?message.timestamp:0;if(message.role==="toolResult"&&!orphanedByOmission&&typeof message.toolCallId=="string"&&message.toolCallId.length>0&&typeof message.toolName=="string"&&message.toolName.length>0)return{role:"toolResult",toolCallId:message.toolCallId,toolName:message.toolName,content:[{type:"text",text:"[tool result omitted from retained context: not replay-safe]"}],isError:!0,timestamp};let text=message.role==="user"?typeof message.content=="string"?message.content:Array.isArray(message.content)?message.content.flatMap(block=>block?.type==="text"&&typeof block.text=="string"?[block.text]:[]).join(`
|
|
20
20
|
`):"":"";return{role:"user",content:`${text?`${text}
|
|
21
21
|
`:""}[message omitted from retained context: not replay-safe]`,timestamp}})}function sessionCwdMatcher(resolvedCwd){let mapped=new Map;return cwd=>{if(cwd===void 0||cwd==="")return!1;if(resolvePath(cwd)===resolvedCwd)return!0;let target=mapped.get(cwd);return target===void 0&&(target=resolvePath(resolveMovedPath(cwd)),mapped.set(cwd,target)),target===resolvedCwd}}import{existsSync}from"fs";import{readdir}from"fs/promises";import{join as join2}from"path";import{stat as stat2}from"fs/promises";import{resolve}from"path";import{open}from"fs/promises";import{StringDecoder}from"string_decoder";import{execFile}from"node:child_process";var REPOSITORY_IDENTITY_ENTRY_TYPE="repository-identity",GIT_TIMEOUT_MS=5e3,COMMIT_HASH=/^[0-9a-f]{40,64}$/,GIT_LOCATION_ENV=new Set(["GIT_DIR","GIT_WORK_TREE","GIT_COMMON_DIR","GIT_INDEX_FILE"]),runGit=(dir,args)=>new Promise(resolve3=>{let env=Object.fromEntries(Object.entries(process.env).filter(([name])=>!GIT_LOCATION_ENV.has(name)));execFile("git",["-C",dir,...args],{env,timeout:GIT_TIMEOUT_MS,windowsHide:!0},(error,stdout)=>{resolve3(error?void 0:stdout)})});async function readRepositoryIdentity(dir,run=runGit){let[roots,origin]=await Promise.all([run(dir,["rev-list","--max-parents=0","HEAD"]),run(dir,["config","--get","remote.origin.url"])]),rootCommits=(roots??"").split(/\s+/).filter(line=>COMMIT_HASH.test(line)).sort(),originUrl=origin?.trim()?normalizeRemoteUrl(origin):void 0;if(!(rootCommits.length===0&&originUrl===void 0))return originUrl===void 0?{rootCommits}:{rootCommits,originUrl}}function normalizeRemoteUrl(url){let trimmed=url.trim(),scpLike=/^(?:[^@/\s]+@)?([^:/\s]+):(?!\/)(.+)$/.exec(trimmed);return(scpLike?`${scpLike[1]}/${scpLike[2]}`:trimmed.replace(/^[a-z][a-z0-9+.-]*:\/\//i,"").replace(/^[^@/]+@/,"").replace(/^([^/:]+):\d+\//,"$1/")).replace(/\/+$/,"").replace(/\.git$/i,"").toLowerCase()}function compareRepositoryIdentities(a,b){return a===void 0||b===void 0?"unknown":a.rootCommits.length>0&&b.rootCommits.length>0?a.rootCommits.some(commit=>b.rootCommits.includes(commit))?"same":"different":a.originUrl!==void 0&&b.originUrl!==void 0?a.originUrl===b.originUrl?"same":"different":"unknown"}function parseRepositoryIdentity(value){if(typeof value!="object"||value===null)return;let{rootCommits,originUrl}=value;if(!Array.isArray(rootCommits)||!rootCommits.every(commit=>typeof commit=="string")||originUrl!==void 0&&typeof originUrl!="string")return;let commits=rootCommits.filter(commit=>COMMIT_HASH.test(commit)).sort();if(!(commits.length===0&&originUrl===void 0))return originUrl===void 0?{rootCommits:commits}:{rootCommits:commits,originUrl}}function sameRepositoryIdentity(a,b){return a===void 0||b===void 0?a===b:a.originUrl===b.originUrl&&a.rootCommits.join(",")===b.rootCommits.join(",")}function parseEntryLine(line){if(!line.trim())return null;try{return JSON.parse(line)}catch{return null}}function isMessageWithContent(message){return typeof message=="object"&&message!==null&&typeof message.role=="string"&&"content"in message}function extractTextContent(message){let content=message.content;return typeof content=="string"?content:content.filter(block=>block.type==="text").map(block=>block.text).join(" ")}function visibleMessage(entry){if(entry.type!=="message")return null;let message=entry.message;if(!isMessageWithContent(message)||message.role!=="user"&&message.role!=="assistant")return null;let messageTime=message.timestamp,entryTime=Date.parse(entry.timestamp),time=typeof messageTime=="number"?messageTime:Number.isNaN(entryTime)?void 0:entryTime;return{text:extractTextContent(message),role:message.role,time}}function sessionInfoName(entry){return entry.type!=="session_info"?null:entry.name?.trim()||void 0}function newAccumulator(){return{header:null,name:void 0,firstUserMessage:"",messageCount:0,lastActivityTime:void 0,repositoryIdentity:void 0,texts:[]}}function accumulateLine(accumulator,line){let entry=parseEntryLine(line);if(!entry)return!0;if(!accumulator.header)return entry.type!=="session"||typeof entry.id!="string"?!1:(accumulator.header=entry,!0);if(entry.type==="custom"&&entry.customType===REPOSITORY_IDENTITY_ENTRY_TYPE)return accumulator.repositoryIdentity=parseRepositoryIdentity(entry.data)??accumulator.repositoryIdentity,!0;let infoName=sessionInfoName(entry);if(infoName!==null)return accumulator.name=infoName,!0;if(entry.type!=="message")return!0;accumulator.messageCount++;let visible=visibleMessage(entry);return!visible||(typeof visible.time=="number"&&(accumulator.lastActivityTime=Math.max(accumulator.lastActivityTime??0,visible.time)),!visible.text)||(accumulator.texts.push(visible.text),!accumulator.firstUserMessage&&visible.role==="user"&&(accumulator.firstUserMessage=visible.text)),!0}var LINE_READ_BUFFER_SIZE=1024*1024;async function readFileLines(filePath,onLine){let handle=await open(filePath,"r");try{let decoder=new StringDecoder("utf8"),buffer=Buffer.allocUnsafe(LINE_READ_BUFFER_SIZE),pending="",bytes=0,lastByte=-1,emit=line=>onLine(line.endsWith("\r")?line.slice(0,-1):line);for(;;){let{bytesRead}=await handle.read(buffer,0,buffer.length,null);if(bytesRead===0)break;bytes+=bytesRead,lastByte=buffer[bytesRead-1]??-1;let searchFrom=pending.length;pending+=decoder.write(buffer.subarray(0,bytesRead));let lineStart=0,newlineIndex=pending.indexOf(`
|
|
22
22
|
`,searchFrom);for(;newlineIndex!==-1;){if(!emit(pending.slice(lineStart,newlineIndex)))return{completed:!1,bytes,endsWithNewline:!1};lineStart=newlineIndex+1,newlineIndex=pending.indexOf(`
|
|
@@ -27,13 +27,13 @@ Command exited with code ${msg.exitCode}`),msg.truncated&&msg.fullOutputPath&&(t
|
|
|
27
27
|
`;for(let entry of entries)await appendFile(path,prefix+entry.line),prefix=""}async function rewriteIndexFile(path,entries){let temp=`${path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;try{await writeFile(temp,HEADER_LINE+entries.map(entry=>entry.line).join("")),await rename(temp,path)}catch(error){throw await rm(temp,{force:!0}).catch(()=>{}),error}}var SESSION_SUMMARY_INDEX_MAX_BYTES=256*1024*1024,snapshots=new Map;function stampsMatch(left,right){return left.size===right.size&&left.mtimeMs===right.mtimeMs}async function statStamp(path){try{let stats=await stat(path);return{size:stats.size,mtimeMs:stats.mtimeMs}}catch(error){if(error instanceof Error)return;throw error}}function recency(entry){let headerTime=Date.parse(entry.summary.header.timestamp);return entry.summary.lastActivityTime??(Number.isNaN(headerTime)?0:headerTime)}function selectWithinBudget(entries,maxBytes){let kept=[],bytes=0;for(let entry of[...entries].sort((left,right)=>recency(right)-recency(left)))if(!(entry.lineBytes>maxBytes)){if(bytes+entry.lineBytes>maxBytes)break;kept.push(entry),bytes+=entry.lineBytes}return kept}var SessionSummaryIndex=class{constructor(dir,options={}){this.recorded=[],this.path=join(dir,SESSION_SUMMARY_INDEX_FILE),this.maxBytes=options.maxBytes??SESSION_SUMMARY_INDEX_MAX_BYTES}async lookup(filePath,stamp){let file=basename(filePath);if(!this.loading){this.snapshot??=this.currentSnapshot();let known=await this.snapshot,indexed=known?.entryStamps.get(file);if(known&&!(indexed&&stampsMatch(indexed,stamp)))return}this.loading??=this.load();let entry=(await this.loading).entries.get(file);return entry&&stampsMatch(entry.stamp,stamp)?entry.summary:void 0}record(filePath,stamp,summary){this.recorded.push({file:basename(filePath),stamp,summary})}async persist(presentFiles){if(!this.loading)return;let loaded=await this.loading,entries=new Map(loaded.entries),added=new Set;for(let{file,stamp,summary}of this.recorded){let existing=entries.get(file);if(existing&&stampsMatch(existing.stamp,stamp))continue;let entry=toIndexEntry(file,stamp,summary);entry&&(entries.set(file,entry),added.add(entry))}let present=new Set(presentFiles.map(path=>basename(path))),live=[...entries.values()].filter(entry=>present.has(entry.file)),kept=selectWithinBudget(live,this.maxBytes),keptBytes=kept.reduce((total,entry)=>total+entry.lineBytes,0),appended=kept.filter(entry=>added.has(entry)),appendedBytes=appended.reduce((total,entry)=>total+entry.lineBytes,0);try{if(!loaded.usable&&kept.length>0||loaded.usable&&loaded.entryBytes+appendedBytes>2*keptBytes)await rewriteIndexFile(this.path,kept),this.remember(await statStamp(this.path),kept);else if(loaded.usable&&appended.length>0){await appendIndexEntries(this.path,appended,loaded.endsWithNewline);let inFile=new Map(loaded.entries);for(let entry of appended)inFile.set(entry.file,entry);this.remember(await statStamp(this.path),inFile.values())}}catch(error){if(!(error instanceof Error))throw error;snapshots.delete(this.path)}}async currentSnapshot(){let recorded=snapshots.get(this.path);if(!recorded)return;let current=await statStamp(this.path);return current&&stampsMatch(current,recorded.indexStamp)?recorded:void 0}async load(){let before=await statStamp(this.path),loaded=await loadIndexFile(this.path);return this.remember(before,loaded.usable?loaded.entries.values():void 0),loaded}remember(indexStamp,entries){if(!indexStamp||!entries){snapshots.delete(this.path);return}let entryStamps=new Map;for(let entry of entries)entryStamps.set(entry.file,entry.stamp);snapshots.set(this.path,{indexStamp,entryStamps})}};var SessionSummaryLru=class{constructor(budget){this.entries=new Map,this.retainedTextBytes=0,this.budget=budget}get size(){return this.entries.size}get textBytes(){return this.retainedTextBytes}get(key){let retained=this.entries.get(key);if(retained)return this.entries.delete(key),this.entries.set(key,retained),retained.entry}drop(key){let retained=this.entries.get(key);retained&&(this.entries.delete(key),this.retainedTextBytes-=retained.textBytes)}retain(key,entry){this.drop(key);let textBytes=Buffer.byteLength(entry.summary.allMessagesText,"utf8");textBytes>this.budget.maxTextBytes||(this.entries.set(key,{entry,textBytes}),this.retainedTextBytes+=textBytes,this.evictUntilWithinBudget())}clear(){this.entries.clear(),this.retainedTextBytes=0}evictUntilWithinBudget(){for(;this.entries.size>this.budget.maxEntries||this.retainedTextBytes>this.budget.maxTextBytes;){let oldest=this.entries.keys().next();if(oldest.done)break;this.drop(oldest.value)}}};var SESSION_SUMMARY_CACHE_LIMIT=4096,SESSION_SUMMARY_CACHE_MAX_TEXT_BYTES=64*1024*1024,cache=new SessionSummaryLru({maxEntries:SESSION_SUMMARY_CACHE_LIMIT,maxTextBytes:SESSION_SUMMARY_CACHE_MAX_TEXT_BYTES}),streamedSummaries=0;function stampsMatch2(left,right){return left.size===right.size&&left.mtimeMs===right.mtimeMs}async function readCachedSessionSummary(filePath,store){let key=resolve(filePath),stamp,mtime;try{let stats=await stat2(filePath);stamp={size:stats.size,mtimeMs:stats.mtimeMs},mtime=stats.mtime}catch(error){if(!(error instanceof Error))throw error;return cache.drop(key),null}let cached=cache.get(key);if(cached&&stampsMatch2(cached.stamp,stamp))return store?.record(filePath,stamp,cached.summary),{summary:cached.summary,mtime:cached.mtime};let stored=await store?.lookup(filePath,stamp);if(stored)return cache.retain(key,{stamp,summary:stored,mtime}),{summary:stored,mtime};streamedSummaries++;let summary=await readSessionSummary(filePath);return summary?(cache.retain(key,{stamp,summary,mtime}),store?.record(filePath,stamp,summary),{summary,mtime}):(cache.drop(key),null)}var MAX_CONCURRENT_SESSION_INFO_LOADS=10,CURRENT_SESSION_LIST_PUBLISH_INTERVAL=10,ALL_SESSION_LIST_PUBLISH_INTERVAL=100;function sortSessionInfos(sessions){return sessions.sort((a,b)=>b.modified.getTime()-a.modified.getTime())}function resolveModified(activityTime,header,mtime){if(typeof activityTime=="number"&&activityTime>0)return new Date(activityTime);let headerTime=typeof header.timestamp=="string"?Date.parse(header.timestamp):Number.NaN;return Number.isNaN(headerTime)?mtime:new Date(headerTime)}async function buildSessionInfo(filePath,store){let cached=await readCachedSessionSummary(filePath,store);if(!cached)return null;let{summary,mtime}=cached,header=summary.header;return{path:filePath,id:header.id,cwd:typeof header.cwd=="string"?header.cwd:"",name:summary.name,parentSessionPath:header.parentSession,created:new Date(header.timestamp),modified:resolveModified(summary.lastActivityTime,header,mtime),messageCount:summary.messageCount,firstMessage:summary.firstUserMessage||"(no messages)",allMessagesText:summary.allMessagesText,...summary.repositoryIdentity?{repositoryIdentity:summary.repositoryIdentity}:{}}}async function buildSessionInfosWithConcurrency(files,onLoaded,store,signal){let results=new Array(files.length).fill(null),inFlight=new Set,nextIndex=0,startNext=()=>{let index=nextIndex++,file=files[index];if(!file)return;let task;task=buildSessionInfo(file,store).then(info=>{results[index]=info}).catch(()=>{results[index]=null}).finally(()=>{inFlight.delete(task),onLoaded(results[index]??null)}),inFlight.add(task)};for(;nextIndex<files.length||inFlight.size>0;){for(;!signal?.aborted&&nextIndex<files.length&&inFlight.size<MAX_CONCURRENT_SESSION_INFO_LOADS;)startNext();if(inFlight.size===0)break;await Promise.race(inFlight)}return signal?.throwIfAborted(),results}async function listSessionInfos(files,onLoaded,store,signal){let results=await buildSessionInfosWithConcurrency(files,onLoaded,store,signal),sessions=[];for(let info of results)info&&sessions.push(info);return sessions}async function listSessionFilesInDir(dir,files,onLoaded,signal){let index=new SessionSummaryIndex(dir),sessions=await listSessionInfos(files,onLoaded,index,signal);return await index.persist(files),sessions}async function listSessionsFromDir(dir,onProgress,signal){if(signal?.throwIfAborted(),!existsSync(dir))return[];try{let files=(await readdir(dir)).filter(name=>name.endsWith(".jsonl")).map(name=>join2(dir,name)),loaded=0,partialSessions=[];return await listSessionFilesInDir(dir,files,info=>{loaded++,info&&partialSessions.push(info);let publish=loaded===1||loaded%CURRENT_SESSION_LIST_PUBLISH_INTERVAL===0||loaded===files.length;onProgress?.(loaded,files.length,publish?sortSessionInfos([...partialSessions]):void 0)},signal)}catch{return signal?.throwIfAborted(),[]}}import{closeSync,existsSync as existsSync2,fstatSync,ftruncateSync,openSync,readSync,statSync,writeSync}from"node:fs";import{open as open2}from"node:fs/promises";import{StringDecoder as StringDecoder2}from"node:string_decoder";var SESSION_READ_BUFFER_SIZE=1024*1024;function parseSessionEntryLine(line){if(!line.trim())return null;try{return JSON.parse(line)}catch{return null}}var SessionLineSplitter=class{constructor(){this.decoder=new StringDecoder2("utf8"),this.pending=""}push(chunk){this.pending+=this.decoder.write(chunk);let lines=[],lineStart=0,newlineIndex=this.pending.indexOf(`
|
|
28
28
|
`,lineStart);for(;newlineIndex!==-1;)lines.push(this.pending.slice(lineStart,newlineIndex)),lineStart=newlineIndex+1,newlineIndex=this.pending.indexOf(`
|
|
29
29
|
`,lineStart);return this.pending=this.pending.slice(lineStart),lines}finish(){return this.pending+this.decoder.end()}};function acceptSessionEntries(entries){if(entries.length===0)return entries;let header=entries[0];return header?.type!=="session"||typeof header.id!="string"?[]:entries}function loadEntriesFromFile(filePath){let resolvedFilePath=normalizePath(filePath);if(!existsSync2(resolvedFilePath))return[];let entries=[],splitter=new SessionLineSplitter,fd=openSync(resolvedFilePath,"r");try{let buffer=Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);for(;;){let bytesRead=readSync(fd,buffer,0,buffer.length,null);if(bytesRead===0)break;for(let line of splitter.push(buffer.subarray(0,bytesRead))){let entry=parseSessionEntryLine(line);entry&&entries.push(entry)}}let finalEntry=parseSessionEntryLine(splitter.finish());finalEntry&&entries.push(finalEntry)}finally{closeSync(fd)}return acceptSessionEntries(entries)}async function loadEntriesFromFileAsync(filePath,slicer=new EventLoopSlicer){let resolvedFilePath=normalizePath(filePath);if(!existsSync2(resolvedFilePath))return[];let entries=[],splitter=new SessionLineSplitter,handle=await open2(resolvedFilePath,"r");try{let buffer=Buffer.allocUnsafe(SESSION_READ_BUFFER_SIZE);for(;;){let{bytesRead}=await handle.read(buffer,0,buffer.length,null);if(bytesRead===0)break;for(let line of splitter.push(buffer.subarray(0,bytesRead))){let entry=parseSessionEntryLine(line);entry&&entries.push(entry),slicer.due&&await slicer.yield()}}let finalEntry=parseSessionEntryLine(splitter.finish());finalEntry&&entries.push(finalEntry)}finally{await handle.close()}return acceptSessionEntries(entries)}function terminateFinalSessionLine(filePath){if(!existsSync2(filePath)||!statSync(filePath).isFile())return;let fd=openSync(filePath,"r+");try{let size=fstatSync(fd).size,segmentStart=finalSegmentStart(fd,size);if(segmentStart===size)return;let segment=Buffer.alloc(size-segmentStart);readSync(fd,segment,0,segment.length,segmentStart),parseSessionEntryLine(segment.toString("utf8"))===null?ftruncateSync(fd,segmentStart):writeSync(fd,`
|
|
30
|
-
`,size)}finally{closeSync(fd)}}function finalSegmentStart(fd,size){let chunk=Buffer.alloc(Math.min(65536,size)),end=size;for(;end>0;){let start=Math.max(0,end-chunk.length),read=readSync(fd,chunk,0,end-start,start),newline=chunk.subarray(0,read).lastIndexOf(10);if(newline>=0)return start+newline+1;end=start}return 0}function materializeSessionEntries(entries,options){let{residentStore,loadHistoryEntries,onMaterialized}=options,missingEntryIds=new Set,materialized=entries.map(entry=>residentStore.materialize(entry,()=>{missingEntryIds.add(entry.id)}));if(missingEntryIds.size===0){for(let entry of materialized)onMaterialized(entry);return materialized}let persistedById=new Map(loadHistoryEntries().filter(entry=>entry.type!=="session").map(entry=>[entry.id,entry])),repaired=materialized.map(entry=>{if(!missingEntryIds.has(entry.id))return entry;let persisted=persistedById.get(entry.id);return persisted===void 0?entry:residentStore.materialize(persisted)});for(let entry of repaired)onMaterialized(entry);return repaired}import{randomUUID}from"node:crypto";import{closeSync as closeSync2,fchmodSync,fsyncSync,openSync as openSync2,realpathSync,renameSync,rmSync,statSync as statSync2,writeFileSync}from"node:fs";import{basename as basename2,dirname,join as join3}from"node:path";var UNSUPPORTED_DIRECTORY_SYNC=new Set(["EINVAL","ENOTSUP","EOPNOTSUPP","EISDIR"]),DIRECTORY_NOT_WRITABLE=new Set(["EACCES","EPERM","EROFS"]);function errnoCode(error){return error instanceof Error&&"code"in error&&typeof error.code=="string"?error.code:void 0}function resolveTarget(filePath){try{let path=realpathSync(filePath);return{path,mode:statSync2(path).mode&4095}}catch(error){if(errnoCode(error)==="ENOENT")return{path:filePath,mode:void 0};throw error}}function openTemp(tempPath){try{return openSync2(tempPath,"wx")}catch(error){let code=errnoCode(error);if(code!==void 0&&DIRECTORY_NOT_WRITABLE.has(code))return;throw error}}function rewriteInPlace(path,chunks){let fd=openSync2(path,"w");try{for(let chunk of chunks)writeFileSync(fd,chunk)}finally{closeSync2(fd)}}function writeDurably(fd,chunks,mode){try{mode!==void 0&&fchmodSync(fd,mode);for(let chunk of chunks)writeFileSync(fd,chunk);fsyncSync(fd)}finally{closeSync2(fd)}}function syncDirectory(directory){if(process.platform==="win32")return;let fd=openSync2(directory,"r");try{fsyncSync(fd)}catch(error){let code=errnoCode(error);if(code===void 0||!UNSUPPORTED_DIRECTORY_SYNC.has(code))throw error}finally{closeSync2(fd)}}function replaceFileAtomically(filePath,chunks){let target=resolveTarget(filePath),tempPath=join3(dirname(target.path),`.${basename2(target.path)}.${randomUUID()}.tmp`),tempFd=openTemp(tempPath);if(tempFd===void 0){rewriteInPlace(target.path,chunks);return}try{writeDurably(tempFd,chunks,target.mode),renameSync(tempPath,target.path)}catch(error){try{rmSync(tempPath,{force:!0})}catch(cleanupError){throw new AggregateError([error,cleanupError],"session file rewrite failed and its temporary file could not be removed")}throw error}syncDirectory(dirname(target.path))}function planLoadedTail(entries){let byId=new Map,leaf;for(let entry of entries)if(entry.type!=="session"){if(byId.has(entry.id))return;byId.set(entry.id,entry),leaf=entry}let path=leafPath(leaf,byId),compaction=path.find(entry=>entry.type==="compaction");if(compaction===void 0)return;let pathIds=new Set(path.map(entry=>entry.id));if(!pathIds.has(compaction.firstKeptEntryId))return;let firstKeptIndex=entries.findIndex(entry=>entry.type!=="session"&&entry.id===compaction.firstKeptEntryId),firstKept=entries[firstKeptIndex];if(firstKept===void 0||firstKept.type==="session")return;let boundaryParent=firstKept.parentId,window=entries.slice(firstKeptIndex).filter(entry=>entry.type!=="session"),windowIds=new Set(window.map(entry=>entry.id));for(let entry of window)if(entry.parentId!==null&&entry.parentId!==boundaryParent&&!windowIds.has(entry.parentId))return;let header=entries.find(entry=>entry.type==="session"),prefix=entries.slice(0,firstKeptIndex).filter(entry=>entry.type!=="session"&&keepsBeforeWindow(entry,pathIds)),retained=header===void 0?[]:[header],parentId=null;for(let entry of prefix)retained.push({...entry,parentId}),parentId=entry.id;for(let entry of window)retained.push(entry.parentId===boundaryParent?{...entry,parentId}:entry);let retainedIds=new Set([...prefix,...window].map(entry=>entry.id)),trimmedIds=[...byId.keys()].filter(id=>!retainedIds.has(id));return trimmedIds.length===0?void 0:{retained,trimmedIds}}function keepsBeforeWindow(entry,pathIds){return entry.type==="label"||entry.type==="session_info"?!0:entry.type!=="message"&&pathIds.has(entry.id)}function leafPath(leaf,byId){let path=[],visited=new Set,current=leaf;for(;current!==void 0&&!visited.has(current.id);)visited.add(current.id),path.push(current),current=current.parentId===null?void 0:byId.get(current.parentId);return path}import{createHash as createHash2}from"node:crypto";import{existsSync as existsSync3,mkdirSync,readFileSync,renameSync as renameSync2,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{join as join4}from"node:path";import{Buffer as Buffer2}from"buffer";var ResidentSizeAccounting=class{constructor(){this.bytes=0,this.evictedCount=0,this.evictedBytes=0}get residentBytes(){return this.bytes}added(text){this.bytes+=Buffer2.byteLength(text,"utf8")}removed(text){this.bytes-=Buffer2.byteLength(text,"utf8")}evicted(text){this.evictedCount++,this.evictedBytes+=Buffer2.byteLength(text,"utf8")}reset(){this.bytes=0,this.evictedCount=0,this.evictedBytes=0}stats(){return{blobBytes:this.bytes,evictedCount:this.evictedCount,evictedBytes:this.evictedBytes}}};var RESIDENT_STRING_MIN_BYTES=32*1024,DEFAULT_RESIDENT_STRING_BUDGET_BYTES=64*1024*1024,RESIDENT_STRING_PREFIX="\0senpi-resident-string:v1:",ResidentStringStore=class{constructor(options={}){this.tokenFree=new WeakSet,this.strings=new Map,this.accounting=new ResidentSizeAccounting,this.maxBytes=options.maxBytes??DEFAULT_RESIDENT_STRING_BUDGET_BYTES,this.blobsDir=options.blobsDir}configure(options){this.blobsDir=options.blobsDir}clear(){this.strings.clear(),this.accounting.reset();let dir=this.blobsDir?.();if(dir)try{rmSync2(dir,{force:!0,recursive:!0})}catch{}}spillResident(){if(this.blobsDir?.())for(let[id,text]of this.strings)this._writeBlob(id,text)&&(this.strings.delete(id),this.accounting.removed(text))}stats(){return{blobCount:this.strings.size,...this.accounting.stats()}}size(){return{entries:this.strings.size,approxBytes:this.accounting.residentBytes}}externalize(value){let tokenized=!1,externalized=transformJson(value,text=>{let stored=this.externalizeString(text);return stored.startsWith(RESIDENT_STRING_PREFIX)&&(tokenized=!0),stored});return!tokenized&&typeof externalized=="object"&&externalized!==null&&this.tokenFree.add(externalized),externalized}materialize(value,onMissing){return typeof value=="object"&&value!==null&&this.tokenFree.has(value)?value:transformJson(value,text=>this.materializeString(text,onMissing))}isTokenFree(value){return this.tokenFree.has(value)}adoptTokenFree(value){this.tokenFree.add(value)}resolvedBlobsDir(){return this.blobsDir?.()}externalizeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.externalizeString(text))}materializeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.materializeString(text))}_mutateStringsInPlace(value,seen,mutate){if(typeof value!="object"||value===null||seen.has(value))return;seen.add(value);let record=value;for(let key of Object.keys(record)){let current=record[key];if(typeof current=="string"){let next=mutate(current);next!==current&&(record[key]=next)}else typeof current=="object"&¤t!==null&&this._mutateStringsInPlace(current,seen,mutate)}}externalizeString(text){if(text.length<RESIDENT_STRING_MIN_BYTES||text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=createHash2("sha256").update(text,"utf8").digest("hex"),token=`${RESIDENT_STRING_PREFIX}${id}`;return this.strings.has(id)?(this.strings.delete(id),this.strings.set(id,text),token):(this.strings.set(id,text),this.accounting.added(text),this._enforceBudget(),token)}materializeString(text,onMissing){if(!text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=text.slice(RESIDENT_STRING_PREFIX.length),resident=this.strings.get(id);if(resident!==void 0)return this.strings.delete(id),this.strings.set(id,resident),resident;let hydrated=this._readBlob(id);return hydrated!==void 0?hydrated:onMissing?.(id)??text}_enforceBudget(){for(;this.accounting.residentBytes>this.maxBytes&&this.strings.size>0;){let[oldestId,oldest]=this.strings.entries().next().value;if(!this._writeBlob(oldestId,oldest))return;this.strings.delete(oldestId),this.accounting.removed(oldest)}}_writeBlob(id,text){let dir=this.blobsDir?.();if(!dir)return!1;let final=join4(dir,`${id}.blob`),temp=`${final}.tmp`;try{mkdirSync(dir,{recursive:!0}),existsSync3(final)||(writeFileSync2(temp,JSON.stringify({v:1,text}),"utf8"),renameSync2(temp,final))}catch{try{rmSync2(temp,{force:!0})}catch{}return!1}return this.accounting.evicted(text),!0}_readBlob(id){let dir=this.blobsDir?.();if(!dir)return;let file=join4(dir,`${id}.blob`);try{let parsed=JSON.parse(readFileSync(file,"utf8"));if(typeof parsed.text=="string")return parsed.text}catch{}try{rmSync2(file,{force:!0})}catch{}}};import{closeSync as closeSync3,fstatSync as fstatSync2,ftruncateSync as ftruncateSync2,openSync as openSync3,readSync as readSync2,rmSync as rmSync3}from"node:fs";import{rm as rm2}from"node:fs/promises";var NEWLINE=10,SCAN_CHUNK_BYTES=64*1024;function truncateToLastCompleteLine(path){let fd=openSync3(path,"r+");try{let size=fstatSync2(fd).size,chunk=Buffer.alloc(Math.min(SCAN_CHUNK_BYTES,size)),end=size;for(;end>0;){let start=Math.max(0,end-chunk.length),read=readSync2(fd,chunk,0,end-start,start),newline=chunk.subarray(0,read).lastIndexOf(NEWLINE);if(newline>=0){let completeLength=start+newline+1;completeLength<size&&ftruncateSync2(fd,completeLength);return}end=start}}finally{closeSync3(fd)}}function discardFailedFirstFlush(path,fd,writeError){let cleanupErrors=[];try{closeSync3(fd)}catch(closeError){cleanupErrors.push(closeError)}try{rmSync3(path,{force:!0})}catch(removeError){cleanupErrors.push(removeError)}throwWriteError(path,writeError,cleanupErrors)}async function discardFailedFirstFlushAsync(path,handle,writeError){let cleanupErrors=[];if(handle!==void 0)try{await handle.close()}catch(closeError){cleanupErrors.push(closeError)}try{await rm2(path,{force:!0})}catch(removeError){cleanupErrors.push(removeError)}throwWriteError(path,writeError,cleanupErrors)}function throwWriteError(path,writeError,cleanupErrors){throw cleanupErrors.length>0?new AggregateError([writeError,...cleanupErrors],`Session file write failed and the partial file ${path} could not be cleaned up`):writeError}var reserve;function reserveSessionWrite(path){reserve?.(path)}var liveWriters=new Set,writerRefs=new WeakMap;function registerSessionWriter(owner){if(writerRefs.has(owner))return;let ref=new WeakRef(owner);writerRefs.set(owner,ref),liveWriters.add(ref)}function unregisterSessionWriter(owner){let ref=writerRefs.get(owner);ref&&(writerRefs.delete(owner),liveWriters.delete(ref))}function hasOtherLiveSessionWriter(path,self){for(let ref of liveWriters){let owner=ref.deref();if(!owner){liveWriters.delete(ref);continue}if(owner!==self&&owner.isPersisted()&&owner.getSessionFile()===path)return!0}return!1}function uuidv7(){let ts=BigInt(Date.now()),bytes=randomBytes(10),hex=[(ts>>40n&0xffn).toString(16).padStart(2,"0"),(ts>>32n&0xffn).toString(16).padStart(2,"0"),(ts>>24n&0xffn).toString(16).padStart(2,"0"),(ts>>16n&0xffn).toString(16).padStart(2,"0"),(ts>>8n&0xffn).toString(16).padStart(2,"0"),(ts&0xffn).toString(16).padStart(2,"0"),(112|bytes[0]&15).toString(16).padStart(2,"0"),bytes[1].toString(16).padStart(2,"0"),(128|bytes[2]&63).toString(16).padStart(2,"0"),bytes[3].toString(16).padStart(2,"0"),...Array.from(bytes.slice(4),b=>b.toString(16).padStart(2,"0"))].join("");return`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20,32)}`}function isPlainJson(value,depth=0){if(depth>64)return!1;if(value===null||typeof value=="string"||typeof value=="boolean")return!0;if(typeof value=="number")return Number.isFinite(value);if(Array.isArray(value)){for(let index=0;index<value.length;index++){let item=value[index];if(item===void 0||!isPlainJson(item,depth+1))return!1}return!0}if(typeof value!="object")return!1;let prototype=Object.getPrototypeOf(value);if(prototype!==Object.prototype&&prototype!==null)return!1;for(let item of Object.values(value))if(item!==void 0&&!isPlainJson(item,depth+1))return!1;return!0}var contextMessageEntryIds=new WeakMap,SESSION_CONTEXT_ENTRY_ID="__piSessionContextEntryId";function withContextEntryId(entryId,message){return contextMessageEntryIds.set(message,entryId),message}function getSessionContextEntryId(message){return contextMessageEntryIds.get(message)}function inheritSessionContextEntryId(derived,source){let fromProperty=Object.getOwnPropertyDescriptor(source,SESSION_CONTEXT_ENTRY_ID)?.value,entryId=getSessionContextEntryId(source)??(typeof fromProperty=="string"?fromProperty:void 0);return entryId===void 0||(contextMessageEntryIds.set(derived,entryId),Object.assign(derived,{[SESSION_CONTEXT_ENTRY_ID]:entryId})),derived}function emptyUsageTotals(){return{input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0}}var CURRENT_SESSION_VERSION=3;function createSessionId(){return uuidv7()}function assertValidSessionId(id){if(!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id))throw new Error("Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character")}function generateId(byId){for(let i=0;i<100;i++){let id=randomUUID2().slice(0,8);if(!byId.has(id))return id}return randomUUID2()}function migrateV1ToV2(entries){let ids=new Set,prevId=null;for(let entry of entries){if(entry.type==="session"){entry.version=2;continue}if(entry.id=generateId(ids),entry.parentId=prevId,prevId=entry.id,entry.type==="compaction"){let comp=entry;if(typeof comp.firstKeptEntryIndex=="number"){let targetEntry=entries[comp.firstKeptEntryIndex];targetEntry&&targetEntry.type!=="session"&&(comp.firstKeptEntryId=targetEntry.id),delete comp.firstKeptEntryIndex}}}}function migrateV2ToV3(entries){for(let entry of entries){if(entry.type==="session"){entry.version=3;continue}if(entry.type==="message"){let msgEntry=entry;msgEntry.message&&msgEntry.message.role==="hookMessage"&&(msgEntry.message.role="custom")}}}function migrateToCurrentVersion(entries){let version=entries.find(e=>e.type==="session")?.version??1;return version>=CURRENT_SESSION_VERSION?!1:(version<2&&migrateV1ToV2(entries),version<3&&migrateV2ToV3(entries),!0)}function migrateSessionEntries(entries){migrateToCurrentVersion(entries)}function parseSessionEntries(content){let entries=[],lines=content.trim().split(`
|
|
30
|
+
`,size)}finally{closeSync(fd)}}function finalSegmentStart(fd,size){let chunk=Buffer.alloc(Math.min(65536,size)),end=size;for(;end>0;){let start=Math.max(0,end-chunk.length),read=readSync(fd,chunk,0,end-start,start),newline=chunk.subarray(0,read).lastIndexOf(10);if(newline>=0)return start+newline+1;end=start}return 0}function materializeSessionEntries(entries,options){let{residentStore,loadHistoryEntries,onMaterialized}=options,missingEntryIds=new Set,materialized=entries.map(entry=>residentStore.materialize(entry,()=>{missingEntryIds.add(entry.id)}));if(missingEntryIds.size===0){for(let entry of materialized)onMaterialized(entry);return materialized}let persistedById=new Map(loadHistoryEntries().filter(entry=>entry.type!=="session").map(entry=>[entry.id,entry])),repaired=materialized.map(entry=>{if(!missingEntryIds.has(entry.id))return entry;let persisted=persistedById.get(entry.id);return persisted===void 0?entry:residentStore.materialize(persisted)});for(let entry of repaired)onMaterialized(entry);return repaired}import{randomUUID}from"node:crypto";import{closeSync as closeSync2,fchmodSync,fsyncSync,openSync as openSync2,realpathSync,renameSync,rmSync,statSync as statSync2,writeFileSync}from"node:fs";import{basename as basename2,dirname,join as join3}from"node:path";var UNSUPPORTED_DIRECTORY_SYNC=new Set(["EINVAL","ENOTSUP","EOPNOTSUPP","EISDIR"]),DIRECTORY_NOT_WRITABLE=new Set(["EACCES","EPERM","EROFS"]);function errnoCode(error){return error instanceof Error&&"code"in error&&typeof error.code=="string"?error.code:void 0}function resolveTarget(filePath){try{let path=realpathSync(filePath);return{path,mode:statSync2(path).mode&4095}}catch(error){if(errnoCode(error)==="ENOENT")return{path:filePath,mode:void 0};throw error}}function openTemp(tempPath){try{return openSync2(tempPath,"wx")}catch(error){let code=errnoCode(error);if(code!==void 0&&DIRECTORY_NOT_WRITABLE.has(code))return;throw error}}function rewriteInPlace(path,chunks){let fd=openSync2(path,"w");try{for(let chunk of chunks)writeFileSync(fd,chunk)}finally{closeSync2(fd)}}function writeDurably(fd,chunks,mode){try{mode!==void 0&&fchmodSync(fd,mode);for(let chunk of chunks)writeFileSync(fd,chunk);fsyncSync(fd)}finally{closeSync2(fd)}}function syncDirectory(directory){if(process.platform==="win32")return;let fd=openSync2(directory,"r");try{fsyncSync(fd)}catch(error){let code=errnoCode(error);if(code===void 0||!UNSUPPORTED_DIRECTORY_SYNC.has(code))throw error}finally{closeSync2(fd)}}function replaceFileAtomically(filePath,chunks){let target=resolveTarget(filePath),tempPath=join3(dirname(target.path),`.${basename2(target.path)}.${randomUUID()}.tmp`),tempFd=openTemp(tempPath);if(tempFd===void 0){rewriteInPlace(target.path,chunks);return}try{writeDurably(tempFd,chunks,target.mode),renameSync(tempPath,target.path)}catch(error){try{rmSync(tempPath,{force:!0})}catch(cleanupError){throw new AggregateError([error,cleanupError],"session file rewrite failed and its temporary file could not be removed")}throw error}syncDirectory(dirname(target.path))}function planLoadedTail(entries){let byId=new Map,leaf;for(let entry of entries)if(entry.type!=="session"){if(byId.has(entry.id))return;byId.set(entry.id,entry),leaf=entry}let path=leafPath(leaf,byId),compaction=path.find(entry=>entry.type==="compaction");if(compaction===void 0)return;let pathIds=new Set(path.map(entry=>entry.id));if(!pathIds.has(compaction.firstKeptEntryId))return;let firstKeptIndex=entries.findIndex(entry=>entry.type!=="session"&&entry.id===compaction.firstKeptEntryId),firstKept=entries[firstKeptIndex];if(firstKept===void 0||firstKept.type==="session")return;let boundaryParent=firstKept.parentId,window=entries.slice(firstKeptIndex).filter(entry=>entry.type!=="session"),windowIds=new Set(window.map(entry=>entry.id));for(let entry of window)if(entry.parentId!==null&&entry.parentId!==boundaryParent&&!windowIds.has(entry.parentId))return;let header=entries.find(entry=>entry.type==="session"),prefix=entries.slice(0,firstKeptIndex).filter(entry=>entry.type!=="session"&&keepsBeforeWindow(entry,pathIds)),retained=header===void 0?[]:[header],parentId=null;for(let entry of prefix)retained.push({...entry,parentId}),parentId=entry.id;for(let entry of window)retained.push(entry.parentId===boundaryParent?{...entry,parentId}:entry);let retainedIds=new Set([...prefix,...window].map(entry=>entry.id)),trimmedIds=[...byId.keys()].filter(id=>!retainedIds.has(id));return trimmedIds.length===0?void 0:{retained,trimmedIds}}function keepsBeforeWindow(entry,pathIds){return entry.type==="label"||entry.type==="session_info"?!0:entry.type!=="message"&&pathIds.has(entry.id)}function leafPath(leaf,byId){let path=[],visited=new Set,current=leaf;for(;current!==void 0&&!visited.has(current.id);)visited.add(current.id),path.push(current),current=current.parentId===null?void 0:byId.get(current.parentId);return path}var SESSION_RELEASED="session_released",SESSION_MOVED_IN="session_moved_in",SESSION_MOVED="session_moved",SESSION_RECLAIMED="session_reclaimed",WRITABLE={writable:!0},NONE={kind:"none"},REFUSED={kind:"refused"},OWNERSHIP_TYPES=new Set([SESSION_RELEASED,SESSION_MOVED_IN,SESSION_MOVED,SESSION_RECLAIMED]);function isOwnershipEntryType(customType){return customType!==void 0&&OWNERSHIP_TYPES.has(customType)}function field2(data,key){if(typeof data!="object"||data===null)return;let value=data[key];return typeof value=="string"?value:void 0}function requested(entry){let moveId=field2(entry.data,"move_id")??"",target=field2(entry.data,"target")??"";return entry.customType===SESSION_MOVED?{writable:!1,state:"moved",moveId,target}:entry.customType===SESSION_RELEASED&&field2(entry.data,"reason")==="move"?{writable:!1,state:"moving",moveId,target}:WRITABLE}function ownershipStep(current,entry,sessionId){if(entry.type!=="custom"||!isOwnershipEntryType(entry.customType))return NONE;let owner=field2(entry.data,"session_id");if(owner!==void 0&&sessionId!==void 0&&owner!==sessionId)return NONE;let next=requested(entry);if(current.writable)return{kind:"apply",next};if(current.state==="moved")return REFUSED;let sameMove=field2(entry.data,"move_id")===current.moveId,continuesMove=entry.customType===SESSION_MOVED||entry.customType===SESSION_RECLAIMED||entry.customType===SESSION_MOVED_IN;return sameMove&&continuesMove?{kind:"apply",next}:REFUSED}function headerSessionId(entries){let header=entries.find(entry=>entry.type==="session");return typeof header?.id=="string"?header.id:void 0}var SessionMovedAwayError=class extends Error{constructor(sessionFile,ownership){let where=ownership.target===""?"another device":ownership.target;super(ownership.state==="moving"?`This session is being moved to ${where}; it is read-only here. Wait for the move to finish, or make a copy to keep working here. (${sessionFile})`:`This session was moved to ${where}; it is read-only here. Open it on ${where}, or make a copy here. (${sessionFile})`),this.code="session_moved_away",this.name="SessionMovedAwayError",this.ownership=ownership}};var SessionWriteGuard=class{constructor(){this.seen=0,this.verdict={writable:!0}}assertWritable(entries,entry,sessionFile){let ownership=this.current(entries);if(!ownership.writable&&ownershipStep(ownership,entry,this.sessionId).kind!=="apply")throw new SessionMovedAwayError(sessionFile,ownership)}assertRewritable(entries,sessionFile){let ownership=this.current(entries);if(!ownership.writable)throw new SessionMovedAwayError(sessionFile,ownership)}isWritable(entries){return this.current(entries).writable}current(entries){for((entries!==this.source||entries.length<this.seen)&&(this.source=entries,this.seen=0,this.sessionId=headerSessionId(entries),this.verdict={writable:!0});this.seen<entries.length;this.seen+=1){let entry=entries[this.seen];if(entry===void 0)continue;let step=ownershipStep(this.verdict,entry,this.sessionId);step.kind==="apply"&&(this.verdict=step.next)}return this.verdict}};import{createHash as createHash2}from"node:crypto";import{existsSync as existsSync3,mkdirSync,readFileSync,renameSync as renameSync2,rmSync as rmSync2,writeFileSync as writeFileSync2}from"node:fs";import{join as join4}from"node:path";import{Buffer as Buffer2}from"buffer";var ResidentSizeAccounting=class{constructor(){this.bytes=0,this.evictedCount=0,this.evictedBytes=0}get residentBytes(){return this.bytes}added(text){this.bytes+=Buffer2.byteLength(text,"utf8")}removed(text){this.bytes-=Buffer2.byteLength(text,"utf8")}evicted(text){this.evictedCount++,this.evictedBytes+=Buffer2.byteLength(text,"utf8")}reset(){this.bytes=0,this.evictedCount=0,this.evictedBytes=0}stats(){return{blobBytes:this.bytes,evictedCount:this.evictedCount,evictedBytes:this.evictedBytes}}};var RESIDENT_STRING_MIN_BYTES=32*1024,DEFAULT_RESIDENT_STRING_BUDGET_BYTES=64*1024*1024,RESIDENT_STRING_PREFIX="\0senpi-resident-string:v1:",ResidentStringStore=class{constructor(options={}){this.tokenFree=new WeakSet,this.strings=new Map,this.accounting=new ResidentSizeAccounting,this.maxBytes=options.maxBytes??DEFAULT_RESIDENT_STRING_BUDGET_BYTES,this.blobsDir=options.blobsDir}configure(options){this.blobsDir=options.blobsDir}clear(){this.strings.clear(),this.accounting.reset();let dir=this.blobsDir?.();if(dir)try{rmSync2(dir,{force:!0,recursive:!0})}catch{}}spillResident(){if(this.blobsDir?.())for(let[id,text]of this.strings)this._writeBlob(id,text)&&(this.strings.delete(id),this.accounting.removed(text))}stats(){return{blobCount:this.strings.size,...this.accounting.stats()}}size(){return{entries:this.strings.size,approxBytes:this.accounting.residentBytes}}externalize(value){let tokenized=!1,externalized=transformJson(value,text=>{let stored=this.externalizeString(text);return stored.startsWith(RESIDENT_STRING_PREFIX)&&(tokenized=!0),stored});return!tokenized&&typeof externalized=="object"&&externalized!==null&&this.tokenFree.add(externalized),externalized}materialize(value,onMissing){return typeof value=="object"&&value!==null&&this.tokenFree.has(value)?value:transformJson(value,text=>this.materializeString(text,onMissing))}isTokenFree(value){return this.tokenFree.has(value)}adoptTokenFree(value){this.tokenFree.add(value)}resolvedBlobsDir(){return this.blobsDir?.()}externalizeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.externalizeString(text))}materializeInPlace(value){this._mutateStringsInPlace(value,new Set,text=>this.materializeString(text))}_mutateStringsInPlace(value,seen,mutate){if(typeof value!="object"||value===null||seen.has(value))return;seen.add(value);let record=value;for(let key of Object.keys(record)){let current=record[key];if(typeof current=="string"){let next=mutate(current);next!==current&&(record[key]=next)}else typeof current=="object"&¤t!==null&&this._mutateStringsInPlace(current,seen,mutate)}}externalizeString(text){if(text.length<RESIDENT_STRING_MIN_BYTES||text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=createHash2("sha256").update(text,"utf8").digest("hex"),token=`${RESIDENT_STRING_PREFIX}${id}`;return this.strings.has(id)?(this.strings.delete(id),this.strings.set(id,text),token):(this.strings.set(id,text),this.accounting.added(text),this._enforceBudget(),token)}materializeString(text,onMissing){if(!text.startsWith(RESIDENT_STRING_PREFIX))return text;let id=text.slice(RESIDENT_STRING_PREFIX.length),resident=this.strings.get(id);if(resident!==void 0)return this.strings.delete(id),this.strings.set(id,resident),resident;let hydrated=this._readBlob(id);return hydrated!==void 0?hydrated:onMissing?.(id)??text}_enforceBudget(){for(;this.accounting.residentBytes>this.maxBytes&&this.strings.size>0;){let[oldestId,oldest]=this.strings.entries().next().value;if(!this._writeBlob(oldestId,oldest))return;this.strings.delete(oldestId),this.accounting.removed(oldest)}}_writeBlob(id,text){let dir=this.blobsDir?.();if(!dir)return!1;let final=join4(dir,`${id}.blob`),temp=`${final}.tmp`;try{mkdirSync(dir,{recursive:!0}),existsSync3(final)||(writeFileSync2(temp,JSON.stringify({v:1,text}),"utf8"),renameSync2(temp,final))}catch{try{rmSync2(temp,{force:!0})}catch{}return!1}return this.accounting.evicted(text),!0}_readBlob(id){let dir=this.blobsDir?.();if(!dir)return;let file=join4(dir,`${id}.blob`);try{let parsed=JSON.parse(readFileSync(file,"utf8"));if(typeof parsed.text=="string")return parsed.text}catch{}try{rmSync2(file,{force:!0})}catch{}}};import{closeSync as closeSync3,fstatSync as fstatSync2,ftruncateSync as ftruncateSync2,openSync as openSync3,readSync as readSync2,rmSync as rmSync3}from"node:fs";import{rm as rm2}from"node:fs/promises";var NEWLINE=10,SCAN_CHUNK_BYTES=64*1024;function truncateToLastCompleteLine(path){let fd=openSync3(path,"r+");try{let size=fstatSync2(fd).size,chunk=Buffer.alloc(Math.min(SCAN_CHUNK_BYTES,size)),end=size;for(;end>0;){let start=Math.max(0,end-chunk.length),read=readSync2(fd,chunk,0,end-start,start),newline=chunk.subarray(0,read).lastIndexOf(NEWLINE);if(newline>=0){let completeLength=start+newline+1;completeLength<size&&ftruncateSync2(fd,completeLength);return}end=start}}finally{closeSync3(fd)}}function discardFailedFirstFlush(path,fd,writeError){let cleanupErrors=[];try{closeSync3(fd)}catch(closeError){cleanupErrors.push(closeError)}try{rmSync3(path,{force:!0})}catch(removeError){cleanupErrors.push(removeError)}throwWriteError(path,writeError,cleanupErrors)}async function discardFailedFirstFlushAsync(path,handle,writeError){let cleanupErrors=[];if(handle!==void 0)try{await handle.close()}catch(closeError){cleanupErrors.push(closeError)}try{await rm2(path,{force:!0})}catch(removeError){cleanupErrors.push(removeError)}throwWriteError(path,writeError,cleanupErrors)}function throwWriteError(path,writeError,cleanupErrors){throw cleanupErrors.length>0?new AggregateError([writeError,...cleanupErrors],`Session file write failed and the partial file ${path} could not be cleaned up`):writeError}var reserve;function reserveSessionWrite(path){reserve?.(path)}var liveWriters=new Set,writerRefs=new WeakMap;function registerSessionWriter(owner){if(writerRefs.has(owner))return;let ref=new WeakRef(owner);writerRefs.set(owner,ref),liveWriters.add(ref)}function unregisterSessionWriter(owner){let ref=writerRefs.get(owner);ref&&(writerRefs.delete(owner),liveWriters.delete(ref))}function hasOtherLiveSessionWriter(path,self){for(let ref of liveWriters){let owner=ref.deref();if(!owner){liveWriters.delete(ref);continue}if(owner!==self&&owner.isPersisted()&&owner.getSessionFile()===path)return!0}return!1}function uuidv7(){let ts=BigInt(Date.now()),bytes=randomBytes(10),hex=[(ts>>40n&0xffn).toString(16).padStart(2,"0"),(ts>>32n&0xffn).toString(16).padStart(2,"0"),(ts>>24n&0xffn).toString(16).padStart(2,"0"),(ts>>16n&0xffn).toString(16).padStart(2,"0"),(ts>>8n&0xffn).toString(16).padStart(2,"0"),(ts&0xffn).toString(16).padStart(2,"0"),(112|bytes[0]&15).toString(16).padStart(2,"0"),bytes[1].toString(16).padStart(2,"0"),(128|bytes[2]&63).toString(16).padStart(2,"0"),bytes[3].toString(16).padStart(2,"0"),...Array.from(bytes.slice(4),b=>b.toString(16).padStart(2,"0"))].join("");return`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20,32)}`}function isPlainJson(value,depth=0){if(depth>64)return!1;if(value===null||typeof value=="string"||typeof value=="boolean")return!0;if(typeof value=="number")return Number.isFinite(value);if(Array.isArray(value)){for(let index=0;index<value.length;index++){let item=value[index];if(item===void 0||!isPlainJson(item,depth+1))return!1}return!0}if(typeof value!="object")return!1;let prototype=Object.getPrototypeOf(value);if(prototype!==Object.prototype&&prototype!==null)return!1;for(let item of Object.values(value))if(item!==void 0&&!isPlainJson(item,depth+1))return!1;return!0}var contextMessageEntryIds=new WeakMap,SESSION_CONTEXT_ENTRY_ID="__piSessionContextEntryId";function withContextEntryId(entryId,message){return contextMessageEntryIds.set(message,entryId),message}function getSessionContextEntryId(message){return contextMessageEntryIds.get(message)}function inheritSessionContextEntryId(derived,source){let fromProperty=Object.getOwnPropertyDescriptor(source,SESSION_CONTEXT_ENTRY_ID)?.value,entryId=getSessionContextEntryId(source)??(typeof fromProperty=="string"?fromProperty:void 0);return entryId===void 0||(contextMessageEntryIds.set(derived,entryId),Object.assign(derived,{[SESSION_CONTEXT_ENTRY_ID]:entryId})),derived}function emptyUsageTotals(){return{input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0}}var CURRENT_SESSION_VERSION=3;function createSessionId(){return uuidv7()}function assertValidSessionId(id){if(!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(id))throw new Error("Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character")}function generateId(byId){for(let i=0;i<100;i++){let id=randomUUID2().slice(0,8);if(!byId.has(id))return id}return randomUUID2()}function migrateV1ToV2(entries){let ids=new Set,prevId=null;for(let entry of entries){if(entry.type==="session"){entry.version=2;continue}if(entry.id=generateId(ids),entry.parentId=prevId,prevId=entry.id,entry.type==="compaction"){let comp=entry;if(typeof comp.firstKeptEntryIndex=="number"){let targetEntry=entries[comp.firstKeptEntryIndex];targetEntry&&targetEntry.type!=="session"&&(comp.firstKeptEntryId=targetEntry.id),delete comp.firstKeptEntryIndex}}}}function migrateV2ToV3(entries){for(let entry of entries){if(entry.type==="session"){entry.version=3;continue}if(entry.type==="message"){let msgEntry=entry;msgEntry.message&&msgEntry.message.role==="hookMessage"&&(msgEntry.message.role="custom")}}}function migrateToCurrentVersion(entries){let version=entries.find(e=>e.type==="session")?.version??1;return version>=CURRENT_SESSION_VERSION?!1:(version<2&&migrateV1ToV2(entries),version<3&&migrateV2ToV3(entries),!0)}function migrateSessionEntries(entries){migrateToCurrentVersion(entries)}function parseSessionEntries(content){let entries=[],lines=content.trim().split(`
|
|
31
31
|
`);for(let line of lines)if(line.trim())try{let entry=JSON.parse(line);entries.push(entry)}catch{}return entries}function getLatestCompactionEntry(entries){for(let i=entries.length-1;i>=0;i--)if(entries[i].type==="compaction")return entries[i];return null}function buildEntryIndex(entries,byId){if(byId)return byId;let index=new Map;for(let entry of entries)index.set(entry.id,entry);return index}function buildSessionPath(entries,leafId,byId){let index=buildEntryIndex(entries,byId),leaf;if(leafId===null)return[];if(leafId&&(leaf=index.get(leafId)),leaf??=entries[entries.length-1],!leaf)return[];let path=[],visited=new Set,current=leaf;for(;current&&!visited.has(current);)visited.add(current),path.push(current),current=current.parentId?index.get(current.parentId):void 0;return path.reverse(),path}function getSessionContextSettings(path){let thinkingLevel="off",thinkingSelection,configurationUpdate,model=null,isModelSelectionExplicit=!1,isInFallbackWindow=!1,preFallbackThinkingLevel=thinkingLevel,preFallbackThinkingSelection=thinkingSelection;for(let entry of path)if(entry.type==="thinking_level_change")thinkingLevel=entry.thinkingLevel,thinkingSelection=entry.thinkingSelection;else if(entry.type==="configuration_update")configurationUpdate={effort:entry.reasoning.effort};else if(entry.type==="model_change")entry.reason==="fallback"?(isInFallbackWindow||(preFallbackThinkingLevel=thinkingLevel,preFallbackThinkingSelection=thinkingSelection,entry.originalProvider&&entry.originalModelId&&(model={provider:normalizeProviderId(entry.originalProvider),modelId:entry.originalModelId},isModelSelectionExplicit=!0)),isInFallbackWindow=!0):entry.reason==="fallback-revert"?(isInFallbackWindow&&(thinkingLevel=preFallbackThinkingLevel,thinkingSelection=preFallbackThinkingSelection),isInFallbackWindow=!1):(isInFallbackWindow=!1,entry.provider&&entry.modelId&&(model={provider:normalizeProviderId(entry.provider),modelId:entry.modelId},isModelSelectionExplicit=!0));else if(entry.type==="message"&&entry.message.role==="assistant"&&!isInFallbackWindow&&!isVirtualModel(entry.message)){if(isModelSelectionExplicit&&model?.provider===normalizeProviderId(entry.message.provider))continue;model={provider:normalizeProviderId(entry.message.provider),modelId:entry.message.model},isModelSelectionExplicit=!1}return isInFallbackWindow&&(thinkingLevel=preFallbackThinkingLevel,thinkingSelection=preFallbackThinkingSelection),{thinkingLevel,thinkingSelection,configurationUpdate,model}}function sessionEntryToContextMessages(entry){if(entry.type==="message"){let message=entry.message;return message.role==="system"&&message.content==null?[{...message,content:""}]:(message.role==="user"||message.role==="assistant"||message.role==="toolResult")&&message.content==null?[withContextEntryId(entry.id,{...message,content:[]})]:[withContextEntryId(entry.id,message)]}if(entry.type==="configuration_update")return[withContextEntryId(entry.id,{role:"configurationUpdate",content:[],effort:entry.reasoning.effort,timestamp:new Date(entry.timestamp).getTime()})];if(entry.type==="custom_message")return[withContextEntryId(entry.id,createCustomMessage(entry.customType,entry.content??[],entry.display,entry.details,entry.timestamp))];if(entry.type==="branch_summary"&&entry.summary)return[withContextEntryId(entry.id,createBranchSummaryMessage(entry.summary,entry.fromId,entry.timestamp))];if(entry.type==="compaction"){let summary=withContextEntryId(entry.id,createCompactionSummaryMessage(entry.summary,entry.tokensBefore,entry.timestamp,entry.details));return entry.systemMessage?[withContextEntryId(entry.id,entry.systemMessage),summary]:[summary]}return[]}function buildContextEntries(entries,leafId,byId){return contextEntriesOfPath(buildSessionPath(entries,leafId,byId))}function contextEntriesOfPath(path){let compaction=null;for(let entry of path)entry.type==="compaction"&&(compaction=entry);if(!compaction)return path;let compactionIdx=path.findIndex(entry=>entry.id===compaction.id);if(compactionIdx<0)return path;let contextEntries=[compaction],foundFirstKept=!1;for(let i=0;i<compactionIdx;i++){let entry=path[i];entry.type!=="compaction"&&(entry.id===compaction.firstKeptEntryId&&(foundFirstKept=!0),foundFirstKept&&!(entry.type==="message"&&entry.message.role==="system")&&contextEntries.push(entry))}return contextEntries.push(...path.slice(compactionIdx+1)),contextEntries}function projectContextEntry(entry,edit){let messages=sessionEntryToContextMessages(entry);if(!edit)return messages;let replacement=edit.replacement;return replacement===null?[]:messages.map(message=>{if(message.role!=="user"&&message.role!=="assistant"&&message.role!=="toolResult"&&message.role!=="custom")return message;let content=(message.role==="assistant"||message.role==="toolResult")&&typeof replacement.content=="string"?[{type:"text",text:replacement.content}]:replacement.content;return withContextEntryId(entry.id,{...message,content})})}function projectSession(entries,leafId,byId,knownPath){let path=knownPath??buildSessionPath(entries,leafId,byId),settings=getSessionContextSettings(path),contextEntries=contextEntriesOfPath(path),edits=new Map;for(let entry of contextEntries)entry.type==="context_edit"&&edits.set(entry.targetId,entry);let projectedEntries=contextEntries.map((sourceEntry,index)=>({sourceEntry,messages:sourceEntry.type==="compaction"&&index>0?[]:projectContextEntry(sourceEntry,edits.get(sourceEntry.id))})),recoveryIndex=path.findLastIndex(entry=>entry.type==="compaction"&&entry.details!==null&&typeof entry.details=="object"&&"retainedMessagePolicy"in entry.details&&entry.details.retainedMessagePolicy==="omit-unsafe-v1");if(recoveryIndex>=0){let retainedIds=new Set(path.slice(0,recoveryIndex).map(entry=>entry.id)),retained=projectedEntries.filter(entry=>retainedIds.has(entry.sourceEntry.id)),repaired=projectRetainedMessages(retained.flatMap(entry=>entry.messages)),index=0;for(let entry of retained)entry.messages=entry.messages.map(()=>withContextEntryId(entry.sourceEntry.id,repaired[index++]))}return{projection:{entries:projectedEntries,messages:projectedEntries.flatMap(entry=>entry.messages),thinkingLevel:settings.thinkingLevel,model:settings.model},settings}}function buildSessionProjection(entries,leafId,byId){return projectSession(entries,leafId,byId).projection}function buildSessionContext(entries,leafId,byId){let{projection,settings}=projectSession(entries,leafId,byId),{thinkingLevel,thinkingSelection,model,configurationUpdate}=settings;return{messages:projection.messages,thinkingLevel,thinkingSelection,model,configurationUpdate}}function getDefaultSessionDirPath(cwd,agentDir=getAgentDir()){let resolvedCwd=resolvePath(cwd),resolvedAgentDir=resolvePath(agentDir),safePath=`--${resolvedCwd.replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`;return join5(resolvedAgentDir,"sessions",safePath)}function getDefaultSessionDir(cwd,agentDir=getAgentDir()){let sessionDir=getDefaultSessionDirPath(cwd,agentDir);return existsSync4(sessionDir)||mkdirSync2(sessionDir,{recursive:!0}),sessionDir}var SESSION_HEADER_READ_BUFFER_SIZE=4096,MAX_SESSION_HEADER_SCAN_BYTES=1024*1024,SessionHeaderScanLimitError=class extends Error{constructor(filePath){super(`Session header exceeds ${MAX_SESSION_HEADER_SCAN_BYTES}-byte scan limit: ${filePath}`),this.name="SessionHeaderScanLimitError"}};function parseSessionHeaderCandidate(line){if(!line.trim())return;let entry=parseSessionEntryLine(line);if(entry)return entry.type!=="session"||typeof entry.id!="string"?null:entry}function readSessionHeader(filePath){let fd=openSync4(filePath,"r");try{let decoder=new StringDecoder3("utf8"),buffer=Buffer.allocUnsafe(SESSION_HEADER_READ_BUFFER_SIZE),lineChunks=[],scannedBytes=0;for(;scannedBytes<MAX_SESSION_HEADER_SCAN_BYTES;){let readLength=Math.min(buffer.length,MAX_SESSION_HEADER_SCAN_BYTES-scannedBytes),bytesRead=readSync3(fd,buffer,0,readLength,null);if(bytesRead===0)return lineChunks.push(decoder.end()),parseSessionHeaderCandidate(lineChunks.join(""))??null;scannedBytes+=bytesRead;let chunk=decoder.write(buffer.subarray(0,bytesRead)),lineStart=0,newlineIndex=chunk.indexOf(`
|
|
32
32
|
`,lineStart);for(;newlineIndex!==-1;){lineChunks.push(chunk.slice(lineStart,newlineIndex));let header=parseSessionHeaderCandidate(lineChunks.join(""));if(header!==void 0)return header;lineChunks.length=0,lineStart=newlineIndex+1,newlineIndex=chunk.indexOf(`
|
|
33
|
-
`,lineStart)}lineChunks.push(chunk.slice(lineStart))}let probe=Buffer.allocUnsafe(1);if(readSync3(fd,probe,0,probe.length,null)===0)return lineChunks.push(decoder.end()),parseSessionHeaderCandidate(lineChunks.join(""))??null;throw new SessionHeaderScanLimitError(filePath)}finally{closeSync4(fd)}}function readSessionHeaderForDiscovery(filePath){try{return readSessionHeader(filePath)}catch{return null}}function getSessionHeaderCwd(header){let cwd=header.cwd;return typeof cwd=="string"?cwd:void 0}function discoverOpenHeader(resolvedPath,cwdOverride){if(cwdOverride!==void 0||!existsSync4(resolvedPath))return{header:null,needsFullLoad:!1};try{return{header:readSessionHeader(resolvedPath),needsFullLoad:!1}}catch(error){if(!(error instanceof SessionHeaderScanLimitError))throw error;return{header:null,needsFullLoad:!0}}}function headerOf(entries){let firstEntry=entries?.[0];return firstEntry?.type==="session"?firstEntry:null}function openLocation(resolvedPath,sessionDir,cwdOverride,header){let headerCwd=header?getSessionHeaderCwd(header):void 0,cwd=cwdOverride??(headerCwd&&resolveMovedPath(headerCwd))??process.cwd(),dir=sessionDir?normalizePath(sessionDir):resolve2(resolvedPath,"..");return{cwd,dir}}function findMostRecentSession(sessionDir,cwd){let resolvedSessionDir=normalizePath(sessionDir),matchesCwd=cwd?sessionCwdMatcher(resolvePath(cwd)):void 0;try{let files=readdirSync(resolvedSessionDir).filter(file=>file.endsWith(".jsonl")).map(file=>join5(resolvedSessionDir,file)).map(path=>({path,mtime:statSync3(path).mtimeMs})).sort((a,b)=>b.mtime-a.mtime);for(let{path}of files){let header=readSessionHeaderForDiscovery(path);if(header&&(!matchesCwd||matchesCwd(getSessionHeaderCwd(header))))return path}return null}catch{return null}}var sessionEntryLoader=loadEntriesFromFile,DEFERRED_FILE_LOAD=Symbol("deferred-session-file-load");var SETUP_ENTRY_TYPES=new Set(["session","model_change","model_change_rejected","thinking_level_change","configuration_update","label"]);function isDisposableEntry(entry){return entry.type==="custom"?entry.startupBookkeeping===!0:SETUP_ENTRY_TYPES.has(entry.type)}function isConversationEntry(entry){return entry.type==="message"&&(entry.message.role==="user"||entry.message.role==="assistant")}var SessionManager=class _SessionManager{constructor(cwd,sessionDir,sessionFile,persist,newSessionOptions,preloadedFileEntries){this.sessionId="",this.flushed=!1,this.tailMayBeTorn=!1,this.fileEntries=[],this.byId=new Map,this.entryOrdersById=new Map,this.messageEntryPositions=new WeakMap,this.labelsById=new Map,this.labelTimestampsById=new Map,this.leafId=null,this.residentStore=new ResidentStringStore,this.mirrorTrimmed=!1,this.loadingFullMirror=!1,this.trimmedIds=new Set,this.idsInUse={has:id=>this.byId.has(id)||this.trimmedIds.has(id)},this.fullEntryCount=0,this.compactEntriesCache=null,this.compactView=null,this.projectionMemo=null,this.historyView=null,this.compactLookup=null,this.mutationCount=0,this.entriesCache=null,this.branchCache=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.cwd=resolvePath(cwd),this.sessionDir=normalizePath(sessionDir),this.persist=persist,persist&®isterSessionWriter(this),persist&&this.sessionDir&&!existsSync4(this.sessionDir)&&mkdirSync2(this.sessionDir,{recursive:!0}),this.residentStore.configure({blobsDir:()=>this.persist&&this.sessionId?join5(this.sessionDir,"resident-blobs",this.sessionId):void 0}),sessionFile?preloadedFileEntries!==DEFERRED_FILE_LOAD&&this._setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions):preloadedFileEntries!==DEFERRED_FILE_LOAD&&preloadedFileEntries?.length?this._loadEntries(preloadedFileEntries,newSessionOptions):this.newSession(newSessionOptions)}reloadFromDisk(){if(!this.sessionFile||!existsSync4(this.sessionFile))return;let fileEntries=loadEntriesFromFile(this.sessionFile);if(fileEntries.length===0){if(statSync3(this.sessionFile).size===0)return;throw new Error(`Session file is not a valid ${APP_NAME} session: ${this.sessionFile}`)}this._setSessionFile(this.sessionFile,fileEntries)}_loadFullMirrorFor(id){if(!(this.byId.has(id)||!this.sessionFile)){this.loadingFullMirror=!0;try{this.reloadFromDisk()}finally{this.loadingFullMirror=!1}}}setSessionFile(sessionFile){this._setSessionFile(sessionFile)}_setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions){let existingFile=this._beginSessionFile(sessionFile,newSessionOptions);if(existingFile===void 0)return;let entries=preloadedFileEntries??loadEntriesFromFile(existingFile);if(!this._adoptFileEntries(existingFile,entries,newSessionOptions))return;let loadedHistory=this._retainLoadedTail();this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._completeFileLoad(loadedHistory)}async _setSessionFileAsync(sessionFile,preloadedFileEntries,newSessionOptions,slicer){let existingFile=this._beginSessionFile(sessionFile,newSessionOptions);if(existingFile===void 0)return;let entries=preloadedFileEntries??await loadEntriesFromFileAsync(existingFile,slicer);if(!this._adoptFileEntries(existingFile,entries,newSessionOptions))return;let loadedHistory=this._retainLoadedTail();this.fileEntries=await mapInSlices(this.fileEntries,entry=>this.residentStore.externalize(entry),slicer),this._completeFileLoad(loadedHistory)}_beginSessionFile(sessionFile,newSessionOptions){let resolvedFile=resolvePath(sessionFile);if(this.persist&&reserveSessionWrite(resolvedFile),this.sessionFile=resolvedFile,this.mirrorTrimmed=!1,this.trimmedIds.clear(),this.residentStore.clear(),existsSync4(resolvedFile))return resolvedFile;this._resetToNewSession(newSessionOptions),newSessionOptions?.id!==void 0&&(this._rewriteFile(),this.flushed=!0)}_adoptFileEntries(sessionFile,entries,newSessionOptions){if(entries.length===0){if(statSync3(sessionFile).size>0)throw new Error(`Session file is not a valid ${APP_NAME} session: ${sessionFile}`);return this._resetToNewSession(newSessionOptions),this._rewriteFile(),this.flushed=!0,!1}this.fileEntries=entries;let header=this.fileEntries.find(e=>e.type==="session");return this.sessionId=header?.id??createSessionId(),this._releaseBlobsDirUnlessShared(),migrateToCurrentVersion(this.fileEntries)&&this._rewriteFile(),!0}_completeFileLoad(loadedHistory){this._buildIndex(),loadedHistory!==void 0&&(this.historyView={source:this.fileEntries,length:this.fileEntries.length,entries:loadedHistory}),this.mutationCount++,this.flushed=!0,this.ownedHeaderFile=void 0}newSession(options){let timestamp=this._resetToNewSession(options);if(this.ownedHeaderFile=void 0,this.persist){let fileTimestamp=timestamp.replace(/[:.]/g,"-"),path=join5(this.getSessionDir(),`${fileTimestamp}_${this.sessionId}.jsonl`);reserveSessionWrite(path),this.sessionFile=path}return this.sessionFile}_resetToNewSession(options){options?.id!==void 0&&assertValidSessionId(options.id);let previousBlobsDir=this.residentStore.resolvedBlobsDir();this.sessionId=options?.id??createSessionId();let timestamp=new Date().toISOString(),header={type:"session",version:CURRENT_SESSION_VERSION,id:this.sessionId,timestamp,cwd:this.cwd,parentSession:options?.parentSession};return this.fileEntries=[header],this.mirrorTrimmed=!1,this.trimmedIds.clear(),this.fullEntryCount=0,this.residentStore.clear(),previousBlobsDir&&this._removeBlobsDir(previousBlobsDir),this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.mutationCount++,this.flushed=!1,timestamp}_loadEntries(entries,options){let header=entries.find(e=>e.type==="session");header?(this.fileEntries=entries,this.sessionId=header.id,migrateToCurrentVersion(this.fileEntries)&&this._rewriteFile()):(this.newSession(options),this.fileEntries=this.fileEntries.concat(entries)),this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++}_retainLoadedTail(){if(!this.persist||this.loadingFullMirror)return;let tail=planLoadedTail(this.fileEntries);if(tail===void 0)return;let history=this.fileEntries.filter(entry=>entry.type!=="session");this.usageTotals=emptyUsageTotals(),this.fullEntryCount=history.length;for(let entry of history)this._accumulateUsage(entry);for(let id of tail.trimmedIds)this.trimmedIds.add(id);return this.mirrorTrimmed=!0,this.fileEntries=tail.retained,history}_buildIndex(){this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.mirrorTrimmed||(this.usageTotals=emptyUsageTotals());let fullEntryCount=0;for(let[order,entry]of this.fileEntries.entries())entry.type!=="session"&&(fullEntryCount++,this.byId.set(entry.id,entry),this.entryOrdersById.set(entry.id,order),this.leafId=entry.id,this.mirrorTrimmed||this._accumulateUsage(entry),entry.type==="session_info"&&(this.sessionNameCache=entry.name?.trim()||void 0),entry.type==="label"&&(entry.label?(this.labelsById.set(entry.targetId,entry.label),this.labelTimestampsById.set(entry.targetId,entry.timestamp)):(this.labelsById.delete(entry.targetId),this.labelTimestampsById.delete(entry.targetId))));this.mirrorTrimmed||(this.fullEntryCount=fullEntryCount)}_rewriteFile(){!this.persist||!this.sessionFile||(reserveSessionWrite(this.sessionFile),replaceFileAtomically(this.sessionFile,this._serializedFileEntries()))}*_serializedFileEntries(){for(let entry of this.fileEntries)yield`${JSON.stringify(this.residentStore.materialize(entry))}
|
|
33
|
+
`,lineStart)}lineChunks.push(chunk.slice(lineStart))}let probe=Buffer.allocUnsafe(1);if(readSync3(fd,probe,0,probe.length,null)===0)return lineChunks.push(decoder.end()),parseSessionHeaderCandidate(lineChunks.join(""))??null;throw new SessionHeaderScanLimitError(filePath)}finally{closeSync4(fd)}}function readSessionHeaderForDiscovery(filePath){try{return readSessionHeader(filePath)}catch{return null}}function getSessionHeaderCwd(header){let cwd=header.cwd;return typeof cwd=="string"?cwd:void 0}function discoverOpenHeader(resolvedPath,cwdOverride){if(cwdOverride!==void 0||!existsSync4(resolvedPath))return{header:null,needsFullLoad:!1};try{return{header:readSessionHeader(resolvedPath),needsFullLoad:!1}}catch(error){if(!(error instanceof SessionHeaderScanLimitError))throw error;return{header:null,needsFullLoad:!0}}}function headerOf(entries){let firstEntry=entries?.[0];return firstEntry?.type==="session"?firstEntry:null}function openLocation(resolvedPath,sessionDir,cwdOverride,header){let headerCwd=header?getSessionHeaderCwd(header):void 0,cwd=cwdOverride??(headerCwd&&resolveMovedPath(headerCwd))??process.cwd(),dir=sessionDir?normalizePath(sessionDir):resolve2(resolvedPath,"..");return{cwd,dir}}function findMostRecentSession(sessionDir,cwd){let resolvedSessionDir=normalizePath(sessionDir),matchesCwd=cwd?sessionCwdMatcher(resolvePath(cwd)):void 0;try{let files=readdirSync(resolvedSessionDir).filter(file=>file.endsWith(".jsonl")).map(file=>join5(resolvedSessionDir,file)).map(path=>({path,mtime:statSync3(path).mtimeMs})).sort((a,b)=>b.mtime-a.mtime);for(let{path}of files){let header=readSessionHeaderForDiscovery(path);if(header&&(!matchesCwd||matchesCwd(getSessionHeaderCwd(header))))return path}return null}catch{return null}}var sessionEntryLoader=loadEntriesFromFile,DEFERRED_FILE_LOAD=Symbol("deferred-session-file-load");var SETUP_ENTRY_TYPES=new Set(["session","model_change","model_change_rejected","thinking_level_change","configuration_update","label"]);function isDisposableEntry(entry){return entry.type==="custom"?entry.startupBookkeeping===!0:SETUP_ENTRY_TYPES.has(entry.type)}function isConversationEntry(entry){return entry.type==="message"&&(entry.message.role==="user"||entry.message.role==="assistant")}var SessionManager=class _SessionManager{constructor(cwd,sessionDir,sessionFile,persist,newSessionOptions,preloadedFileEntries){this.sessionId="",this.writeGuard=new SessionWriteGuard,this.flushed=!1,this.tailMayBeTorn=!1,this.fileEntries=[],this.byId=new Map,this.entryOrdersById=new Map,this.messageEntryPositions=new WeakMap,this.labelsById=new Map,this.labelTimestampsById=new Map,this.leafId=null,this.residentStore=new ResidentStringStore,this.mirrorTrimmed=!1,this.loadingFullMirror=!1,this.trimmedIds=new Set,this.idsInUse={has:id=>this.byId.has(id)||this.trimmedIds.has(id)},this.fullEntryCount=0,this.compactEntriesCache=null,this.compactView=null,this.projectionMemo=null,this.historyView=null,this.compactLookup=null,this.mutationCount=0,this.entriesCache=null,this.branchCache=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.cwd=resolvePath(cwd),this.sessionDir=normalizePath(sessionDir),this.persist=persist,persist&®isterSessionWriter(this),persist&&this.sessionDir&&!existsSync4(this.sessionDir)&&mkdirSync2(this.sessionDir,{recursive:!0}),this.residentStore.configure({blobsDir:()=>this.persist&&this.sessionId?join5(this.sessionDir,"resident-blobs",this.sessionId):void 0}),sessionFile?preloadedFileEntries!==DEFERRED_FILE_LOAD&&this._setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions):preloadedFileEntries!==DEFERRED_FILE_LOAD&&preloadedFileEntries?.length?this._loadEntries(preloadedFileEntries,newSessionOptions):this.newSession(newSessionOptions)}reloadFromDisk(){if(!this.sessionFile||!existsSync4(this.sessionFile))return;let fileEntries=loadEntriesFromFile(this.sessionFile);if(fileEntries.length===0){if(statSync3(this.sessionFile).size===0)return;throw new Error(`Session file is not a valid ${APP_NAME} session: ${this.sessionFile}`)}this._setSessionFile(this.sessionFile,fileEntries)}_loadFullMirrorFor(id){if(!(this.byId.has(id)||!this.sessionFile)){this.loadingFullMirror=!0;try{this.reloadFromDisk()}finally{this.loadingFullMirror=!1}}}setSessionFile(sessionFile){this._setSessionFile(sessionFile)}_setSessionFile(sessionFile,preloadedFileEntries,newSessionOptions){let existingFile=this._beginSessionFile(sessionFile,newSessionOptions);if(existingFile===void 0)return;let entries=preloadedFileEntries??loadEntriesFromFile(existingFile);if(!this._adoptFileEntries(existingFile,entries,newSessionOptions))return;let loadedHistory=this._retainLoadedTail();this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._completeFileLoad(loadedHistory)}async _setSessionFileAsync(sessionFile,preloadedFileEntries,newSessionOptions,slicer){let existingFile=this._beginSessionFile(sessionFile,newSessionOptions);if(existingFile===void 0)return;let entries=preloadedFileEntries??await loadEntriesFromFileAsync(existingFile,slicer);if(!this._adoptFileEntries(existingFile,entries,newSessionOptions))return;let loadedHistory=this._retainLoadedTail();this.fileEntries=await mapInSlices(this.fileEntries,entry=>this.residentStore.externalize(entry),slicer),this._completeFileLoad(loadedHistory)}_beginSessionFile(sessionFile,newSessionOptions){let resolvedFile=resolvePath(sessionFile);if(this.persist&&reserveSessionWrite(resolvedFile),this.sessionFile=resolvedFile,this.mirrorTrimmed=!1,this.trimmedIds.clear(),this.residentStore.clear(),existsSync4(resolvedFile))return resolvedFile;this._resetToNewSession(newSessionOptions),newSessionOptions?.id!==void 0&&(this._rewriteFile(),this.flushed=!0)}_adoptFileEntries(sessionFile,entries,newSessionOptions){if(entries.length===0){if(statSync3(sessionFile).size>0)throw new Error(`Session file is not a valid ${APP_NAME} session: ${sessionFile}`);return this._resetToNewSession(newSessionOptions),this._rewriteFile(),this.flushed=!0,!1}this.fileEntries=entries;let header=this.fileEntries.find(e=>e.type==="session");return this.sessionId=header?.id??createSessionId(),this._releaseBlobsDirUnlessShared(),migrateToCurrentVersion(this.fileEntries)&&this.writeGuard.isWritable(this.fileEntries)&&this._rewriteFile(),!0}_completeFileLoad(loadedHistory){this._buildIndex(),loadedHistory!==void 0&&(this.historyView={source:this.fileEntries,length:this.fileEntries.length,entries:loadedHistory}),this.mutationCount++,this.flushed=!0,this.ownedHeaderFile=void 0}newSession(options){let timestamp=this._resetToNewSession(options);if(this.ownedHeaderFile=void 0,this.persist){let fileTimestamp=timestamp.replace(/[:.]/g,"-"),path=join5(this.getSessionDir(),`${fileTimestamp}_${this.sessionId}.jsonl`);reserveSessionWrite(path),this.sessionFile=path}return this.sessionFile}_resetToNewSession(options){options?.id!==void 0&&assertValidSessionId(options.id);let previousBlobsDir=this.residentStore.resolvedBlobsDir();this.sessionId=options?.id??createSessionId();let timestamp=new Date().toISOString(),header={type:"session",version:CURRENT_SESSION_VERSION,id:this.sessionId,timestamp,cwd:this.cwd,parentSession:options?.parentSession};return this.fileEntries=[header],this.mirrorTrimmed=!1,this.trimmedIds.clear(),this.fullEntryCount=0,this.residentStore.clear(),previousBlobsDir&&this._removeBlobsDir(previousBlobsDir),this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.usageTotals={input:0,output:0,cacheRead:0,cacheWrite:0,cost:0,latestCacheHitRate:void 0},this.mutationCount++,this.flushed=!1,timestamp}_loadEntries(entries,options){let header=entries.find(e=>e.type==="session");header?(this.fileEntries=entries,this.sessionId=header.id,migrateToCurrentVersion(this.fileEntries)&&this._rewriteFile()):(this.newSession(options),this.fileEntries=this.fileEntries.concat(entries)),this.fileEntries=this.fileEntries.map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++}_retainLoadedTail(){if(!this.persist||this.loadingFullMirror)return;let tail=planLoadedTail(this.fileEntries);if(tail===void 0)return;let history=this.fileEntries.filter(entry=>entry.type!=="session");this.usageTotals=emptyUsageTotals(),this.fullEntryCount=history.length;for(let entry of history)this._accumulateUsage(entry);for(let id of tail.trimmedIds)this.trimmedIds.add(id);return this.mirrorTrimmed=!0,this.fileEntries=tail.retained,history}_buildIndex(){this.byId.clear(),this.entryOrdersById.clear(),this.messageEntryPositions=new WeakMap,this.labelsById.clear(),this.labelTimestampsById.clear(),this.leafId=null,this.sessionNameCache=void 0,this.mirrorTrimmed||(this.usageTotals=emptyUsageTotals());let fullEntryCount=0;for(let[order,entry]of this.fileEntries.entries())entry.type!=="session"&&(fullEntryCount++,this.byId.set(entry.id,entry),this.entryOrdersById.set(entry.id,order),this.leafId=entry.id,this.mirrorTrimmed||this._accumulateUsage(entry),entry.type==="session_info"&&(this.sessionNameCache=entry.name?.trim()||void 0),entry.type==="label"&&(entry.label?(this.labelsById.set(entry.targetId,entry.label),this.labelTimestampsById.set(entry.targetId,entry.timestamp)):(this.labelsById.delete(entry.targetId),this.labelTimestampsById.delete(entry.targetId))));this.mirrorTrimmed||(this.fullEntryCount=fullEntryCount)}_rewriteFile(){!this.persist||!this.sessionFile||(this.writeGuard.assertRewritable(this.fileEntries,this.sessionFile),reserveSessionWrite(this.sessionFile),replaceFileAtomically(this.sessionFile,this._serializedFileEntries()))}*_serializedFileEntries(){for(let entry of this.fileEntries)yield`${JSON.stringify(this.residentStore.materialize(entry))}
|
|
34
34
|
`}isPersisted(){return this.persist}getCwd(){return this.cwd}getSessionDir(){return this.sessionDir}usesDefaultSessionDir(){return this.sessionDir===getDefaultSessionDirPath(this.cwd)}getSessionId(){return this.sessionId}getSessionFile(){return this.sessionFile}getResidentStore(){return this.residentStore}getResidentStoreStats(){return this.residentStore.stats()}persistHeaderNow(){if(!this.persist||!this.sessionFile||this.flushed)return this.headerWrite??Promise.resolve();let sessionFile=this.sessionFile;return this.headerWrite??=this._writeHeaderAsync(sessionFile).finally(()=>{this.headerWrite=void 0}),this.headerWrite}isTranscriptFlushed(){return this.flushed}async discardHeaderOnlyFile(){return await this.headerWrite,!this.persist||!this.sessionFile||!this.flushed||this.ownedHeaderFile!==this.sessionFile||!this.fileEntries.every(isDisposableEntry)?!1:(await rm3(this.sessionFile,{force:!0}),this.ownedHeaderFile=void 0,this.flushed=!1,!0)}async _writeHeaderAsync(sessionFile){reserveSessionWrite(sessionFile);let entries=this.fileEntries,serialize=batch=>batch.map(e=>`${JSON.stringify(this.residentStore.materialize(e))}
|
|
35
|
-
`).join(""),written=0,handle=await open3(sessionFile,"wx");try{for(;written<entries.length;){let batch=entries.slice(written);written+=batch.length,await handle.writeFile(serialize(batch))}let closing=handle;for(handle=void 0,await closing.close();written<entries.length&&this.sessionFile===sessionFile&&this.fileEntries===entries;){let batch=entries.slice(written);written+=batch.length,await appendFile2(sessionFile,serialize(batch))}}catch(error){return discardFailedFirstFlushAsync(sessionFile,handle,error)}this.sessionFile===sessionFile&&this.fileEntries===entries&&written===entries.length&&(this.flushed=!0,this.ownedHeaderFile=sessionFile)}_hasConversation(){return this.fileEntries.some(isConversationEntry)}_persist(entry){if(!this.persist||!this.sessionFile)return;reserveSessionWrite(this.sessionFile);let persistedEntry=this.residentStore.materialize(entry);if(this.flushed){this.tailMayBeTorn&&(truncateToLastCompleteLine(this.sessionFile),this.tailMayBeTorn=!1);try{appendFileSync(this.sessionFile,`${JSON.stringify(persistedEntry)}
|
|
35
|
+
`).join(""),written=0,handle=await open3(sessionFile,"wx");try{for(;written<entries.length;){let batch=entries.slice(written);written+=batch.length,await handle.writeFile(serialize(batch))}let closing=handle;for(handle=void 0,await closing.close();written<entries.length&&this.sessionFile===sessionFile&&this.fileEntries===entries;){let batch=entries.slice(written);written+=batch.length,await appendFile2(sessionFile,serialize(batch))}}catch(error){return discardFailedFirstFlushAsync(sessionFile,handle,error)}this.sessionFile===sessionFile&&this.fileEntries===entries&&written===entries.length&&(this.flushed=!0,this.ownedHeaderFile=sessionFile)}_hasConversation(){return this.fileEntries.some(isConversationEntry)}_persist(entry){if(!this.persist||!this.sessionFile)return;this.writeGuard.assertWritable(this.fileEntries,entry,this.sessionFile),reserveSessionWrite(this.sessionFile);let persistedEntry=this.residentStore.materialize(entry);if(this.flushed){this.tailMayBeTorn&&(truncateToLastCompleteLine(this.sessionFile),this.tailMayBeTorn=!1);try{appendFileSync(this.sessionFile,`${JSON.stringify(persistedEntry)}
|
|
36
36
|
`)}catch(error){throw this.tailMayBeTorn=!0,error}return}if(!isConversationEntry(entry)&&!this._hasConversation()||this.headerWrite)return;let fd=openSync4(this.sessionFile,"wx");try{for(let e of[...this.fileEntries,entry])writeFileSync3(fd,`${JSON.stringify(this.residentStore.materialize(e))}
|
|
37
37
|
`)}catch(error){discardFailedFirstFlush(this.sessionFile,fd,error)}closeSync4(fd),this.flushed=!0}_appendEntry(entry,shareable){let residentEntry=this.residentStore.externalize(entry);this._persist(residentEntry),this._commitEntry(this._shareMessage(residentEntry,shareable))}_shareMessage(residentEntry,shareable){if(shareable===void 0||residentEntry.type!=="message"||!this.residentStore.isTokenFree(residentEntry)||!isPlainJson(shareable))return residentEntry;let shared={...residentEntry,message:{...shareable}};return this.residentStore.adoptTokenFree(shared),shared}_commitEntry(residentEntry){this.fileEntries.push(residentEntry),this.byId.set(residentEntry.id,residentEntry),this.entryOrdersById.set(residentEntry.id,this.fileEntries.length-1),this.leafId=residentEntry.id,this.fullEntryCount++,this._accumulateUsage(residentEntry),this.mutationCount++}appendEntry(entry){this._appendEntry(entry);let order=this.entryOrdersById.get(entry.id);entry.type==="message"&&order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order}),entry.type==="session_info"&&(this.sessionNameCache=entry.name?.trim()||void 0),entry.type==="label"&&(entry.label?(this.labelsById.set(entry.targetId,entry.label),this.labelTimestampsById.set(entry.targetId,entry.timestamp)):(this.labelsById.delete(entry.targetId),this.labelTimestampsById.delete(entry.targetId)))}_materializeEntry(entry){let missingResidentString=!1,materialized=this.residentStore.materialize(entry,()=>{missingResidentString=!0});if(missingResidentString&&this.sessionFile){let persisted=loadEntriesFromFile(this.sessionFile).find(candidate=>candidate.id===entry.id);if(persisted)return persisted}if(materialized.type==="message"){let order=this.entryOrdersById.get(materialized.id);order!==void 0&&this.messageEntryPositions.set(materialized.message,{entryId:materialized.id,order})}return materialized}_accumulateUsage(entry){if(entry.type!=="message"||entry.message.role!=="assistant")return;let usage=entry.message.usage;if(!usage)return;this.usageTotals.input+=usage.input,this.usageTotals.output+=usage.output,this.usageTotals.cacheRead+=usage.cacheRead,this.usageTotals.cacheWrite+=usage.cacheWrite,this.usageTotals.cost+=usage.cost?.total??0;let latestPromptTokens=usage.input+usage.cacheRead+usage.cacheWrite;this.usageTotals.latestCacheHitRate=latestPromptTokens>0?usage.cacheRead/latestPromptTokens*100:void 0}getUsageTotals(){return this.usageTotals}appendMessage(message){return this._appendMessage(message,!1)}appendOwnedMessage(message){return this._appendMessage(message,!0)}_appendMessage(message,owned){let entry={type:"message",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),message};this._appendEntry(entry,owned?message:void 0);let order=this.entryOrdersById.get(entry.id);return order!==void 0&&this.messageEntryPositions.set(message,{entryId:entry.id,order}),entry.id}getMessageEntryPosition(message){return this.messageEntryPositions.get(message)}getEntryOrder(entryId){return this.entryOrdersById.get(entryId)}appendThinkingLevelChange(thinkingLevel,thinkingSelection,trigger){let entry={type:"thinking_level_change",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),thinkingLevel,thinkingSelection,...trigger===void 0?{}:{triggerSource:trigger.source},...trigger?.actor===void 0?{}:{triggerActor:trigger.actor},...trigger?.effectId===void 0?{}:{effectId:trigger.effectId}};return this._appendEntry(entry),entry.id}appendConfigurationUpdate(effort){let entry={type:"configuration_update",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),reasoning:{effort}};return this._appendEntry(entry),entry.id}appendModelChangeRejected(details){let entry={type:"model_change_rejected",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),...details};return this._appendEntry(entry),entry.id}appendModelChange(provider,modelId,reason,originalProvider,originalModelId,attribution){let entry={type:"model_change",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),provider,modelId,reason,originalProvider,originalModelId,...attribution===void 0?{}:{source:attribution.origin.source},...attribution?.origin.actor===void 0?{}:{actor:attribution.origin.actor},...attribution?.duringTurn?{duringTurn:!0}:{},...attribution?.origin.effectId===void 0?{}:{effectId:attribution.origin.effectId}};return this._appendEntry(entry),entry.id}appendUsage(kind,provider,model,usage,note){let entry={type:"usage",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),kind,provider,model,usage,...note?{note}:{}};return this._appendEntry(entry),entry}appendCompaction(summary,firstKeptEntryId,tokensBefore,details,fromHook,usage){let timestamp=new Date().toISOString(),systemMessage=getCurrentSystemMessage(this.buildSessionProjection().messages),id=generateId(this.idsInUse),entry={type:"compaction",id,parentId:this.leafId,timestamp,summary,firstKeptEntryId:firstKeptEntryId??id,tokensBefore,details,usage,fromHook,...systemMessage?{systemMessage:{...systemMessage,timestamp:new Date(timestamp).getTime()}}:{}};return this._appendEntry(entry),this._trimMirrorAfterCompaction(entry),entry.id}dispose(){unregisterSessionWriter(this),this._releaseBlobsDirUnlessShared()}_releaseBlobsDirUnlessShared(){let blobsDir=this.residentStore.resolvedBlobsDir();blobsDir&&(this.sessionFile&&hasOtherLiveSessionWriter(this.sessionFile,this)||this._removeBlobsDir(blobsDir))}_removeBlobsDir(dir){try{rmSync4(dir,{force:!0,recursive:!0})}catch{}}_trimMirrorAfterCompaction(compaction){if(!this.persist)return;let firstKeptIndex=this.fileEntries.findIndex(entry=>entry.id===compaction.firstKeptEntryId),compactionIndex=this.fileEntries.findIndex(entry=>entry.id===compaction.id);if(firstKeptIndex<0||compactionIndex<firstKeptIndex)return;let header=this.fileEntries.find(entry=>entry.type==="session"),retained=[...this.fileEntries.slice(0,firstKeptIndex).filter(entry=>entry.type!=="message"),...this.fileEntries.slice(firstKeptIndex,compactionIndex+1)],parentId=null;for(let entry of retained)entry.type!=="session"&&(entry.parentId=parentId),parentId=entry.type==="session"?null:entry.id;let retainedIds=new Set(retained.map(entry=>entry.id));for(let entry of this.fileEntries)entry.type!=="session"&&!retainedIds.has(entry.id)&&this.trimmedIds.add(entry.id);this.residentStore.spillResident(),this.mirrorTrimmed=!0,this.fileEntries=[header,...retained].filter(entry=>entry!==void 0).map(entry=>this.residentStore.externalize(entry)),this._buildIndex(),this.mutationCount++}appendCustomEntry(customType,data,options){let entry={type:"custom",customType,data,...options?.startupBookkeeping===!0?{startupBookkeeping:!0}:{},id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString()};return this._appendEntry(entry),entry.id}appendSessionInfo(name){let sanitizedName=name.replace(/[\r\n]+/g," ").trim(),entry={type:"session_info",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),name:sanitizedName};return this._appendEntry(entry),this.sessionNameCache=sanitizedName||void 0,entry.id}getSessionName(){return this.sessionNameCache}appendCustomMessageEntry(customType,content,display,details){let entry={type:"custom_message",customType,content,display,details,id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString()};return this._appendEntry(entry),entry.id}appendContextEdit(targetId,replacement){if(replacement!==null&&(typeof replacement!="object"||!("content"in replacement)||typeof replacement.content!="string"&&!Array.isArray(replacement.content)))throw new Error("Context edit replacement must be null or contain string/array content");let target=this.byId.get(targetId);if(!target)throw new Error(`Entry ${targetId} not found`);if(!this.getBranch().some(entry2=>entry2.id===targetId))throw new Error(`Entry ${targetId} is not on the active branch`);if(!(target.type==="custom_message"||target.type==="message"&&(target.message.role==="user"||target.message.role==="assistant"||target.message.role==="toolResult")))throw new Error(`Entry ${targetId} does not contribute editable model content`);let targetRole=target.type==="message"?target.message.role:"custom",normalizedReplacement=replacement!==null&&(targetRole==="assistant"||targetRole==="toolResult")&&typeof replacement.content=="string"?{content:[{type:"text",text:replacement.content}]}:replacement,entry={type:"context_edit",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),targetId,replacement:normalizedReplacement};return this._appendEntry(entry),entry.id}getLeafId(){return this.leafId}getLeafEntry(){let entry=this.leafId?this.byId.get(this.leafId):void 0;return entry?this._materializeEntry(entry):void 0}getEntry(id){let entry=this.byId.get(id);if(entry)return this._materializeEntry(entry);if(this.mirrorTrimmed&&this.sessionFile){let persisted=this._loadFullHistoryEntries().find(candidate=>candidate.id===id);return persisted?this.residentStore.materialize(persisted):void 0}}getChildren(parentId){let children=[];for(let entry of this.byId.values())entry.parentId===parentId&&children.push(this._materializeEntry(entry));return children}getLabel(id){return this.labelsById.get(id)}appendLabelChange(targetId,label){if(!this.byId.has(targetId)&&!this.getEntries().some(entry2=>entry2.id===targetId))throw new Error(`Entry ${targetId} not found`);let entry={type:"label",id:generateId(this.idsInUse),parentId:this.leafId,timestamp:new Date().toISOString(),targetId,label};return this._appendEntry(entry),label?(this.labelsById.set(targetId,label),this.labelTimestampsById.set(targetId,entry.timestamp)):(this.labelsById.delete(targetId),this.labelTimestampsById.delete(targetId)),entry.id}getBranch(fromId){if(fromId===void 0&&this.branchCache!==null&&this.branchCache.leafId===this.leafId&&this.branchCache.mutation===this.mutationCount)return this.branchCache.entries;if(fromId===void 0){let extended=this._extendBranchCache();if(extended!==void 0)return extended}let path=[],startId=fromId??this.leafId,entriesById=this.byId;fromId!==void 0&&!entriesById.has(fromId)&&this.mirrorTrimmed&&this.sessionFile&&(entriesById=new Map(this._loadFullHistoryEntries().filter(entry=>entry.type!=="session").map(entry=>[entry.id,this.residentStore.materialize(entry)])));let current=startId?entriesById.get(startId):void 0,visited=new Set;for(;current&&!visited.has(current);)visited.add(current),path.push(current),current=current.parentId?entriesById.get(current.parentId):void 0;path.reverse();let materializedPath=(entriesById===this.byId?this._fromCompactView(path):void 0)??this._materializeEntries(path);return fromId===void 0&&(this.branchCache={leafId:this.leafId,mutation:this.mutationCount,entries:materializedPath,source:this.fileEntries}),materializedPath}getFullBranch(fromId){if(!this.mirrorTrimmed||!this.sessionFile)return this.getBranch(fromId);let byId=new Map;for(let entry of this.getEntries())byId.set(entry.id,entry);let path=[],visited=new Set,current=byId.get(fromId??this.leafId??"");for(;current&&!visited.has(current.id);)visited.add(current.id),path.push(current),current=current.parentId?byId.get(current.parentId):void 0;return path.reverse()}_extendBranchCache(){let cache2=this.branchCache;if(cache2===null||cache2.source!==this.fileEntries||cache2.leafId===null)return;let added=[],current=this.leafId?this.byId.get(this.leafId):void 0;for(;current&¤t.id!==cache2.leafId;){if(added.length>=256)return;added.push(current),current=current.parentId?this.byId.get(current.parentId):void 0}if(current===void 0)return;added.reverse();let entries=[...cache2.entries,...this._fromCompactView(added)??this._materializeEntries(added)];return this.branchCache={leafId:this.leafId,mutation:this.mutationCount,entries,source:this.fileEntries},entries}buildContextEntries(){return buildContextEntries(this._getCompactEntries(),this.leafId)}buildSessionProjection(){let{projection}=this._projectCurrent();return{...projection,messages:[...projection.messages],entries:[...projection.entries]}}_projectCurrent(){let entries=this._getCompactEntries(),memo=this.projectionMemo;if(memo?.source===entries&&memo.leafId===this.leafId)return memo.result;let path=this._extendPath(memo,entries)??buildSessionPath(entries,this.leafId),result=projectSession(entries,this.leafId,void 0,path);return this.projectionMemo={source:entries,leafId:this.leafId,path,result},result}_extendPath(memo,entries){if(!memo||memo.leafId===null||this.leafId===null)return;let previous=memo.source;if(entries.length<=previous.length||entries[previous.length-1]!==previous[previous.length-1])return;let parentId=memo.leafId,appended=[];for(let index=previous.length;index<entries.length;index++){let entry=entries[index];if(entry.parentId!==parentId)return;appended.push(entry),parentId=entry.id}if(parentId===this.leafId)return[...memo.path,...appended]}buildSessionContext(){let{projection,settings}=this._projectCurrent(),{thinkingLevel,thinkingSelection,model,configurationUpdate}=settings;return{messages:[...projection.messages],thinkingLevel,thinkingSelection,model,configurationUpdate}}hasContextMessages(){return this.hasBranchEntry(entry=>entry.type==="message"||entry.type==="custom_message"||entry.type==="compaction"||entry.type==="branch_summary"&&!!entry.summary)}hasThinkingLevelChanges(){return this.hasBranchEntry(entry=>entry.type==="thinking_level_change")}countCompactions(){let count=0;for(let entry of this.fileEntries)entry.type==="compaction"&&count++;return count}hasBranchEntry(predicate){let current=this.leafId?this.byId.get(this.leafId):void 0,visited=new Set;for(;current&&!visited.has(current);){if(predicate(current))return!0;visited.add(current),current=current.parentId?this.byId.get(current.parentId):void 0}return!1}getHeader(){let h=this.fileEntries.find(e=>e.type==="session");return h?this.residentStore.materialize(h):null}getEntries(){if(this.mirrorTrimmed&&this.sessionFile){let extended=this._extendView(this.historyView);if(extended!==void 0)return this.historyView={source:this.fileEntries,length:this.fileEntries.length,entries:extended},extended;let history=this._loadFullHistoryEntries().filter(e=>e.type!=="session").map(entry=>this.residentStore.materialize(entry));return this.historyView={source:this.fileEntries,length:this.fileEntries.length,entries:history},history}if(this.entriesCache!==null&&this.entriesCache.mutation===this.mutationCount)return this.entriesCache.entries;let materializedEntries=this._getCompactEntries();return this.entriesCache={mutation:this.mutationCount,entries:materializedEntries},materializedEntries}getEntryCount(){return this.fullEntryCount}dropMaterializedCaches(){this.entriesCache=null,this.branchCache=null,this.compactEntriesCache=null,this.compactView=null,this.historyView=null,this.compactLookup=null,this.projectionMemo=null}holdsMaterializedHistory(){return this.historyView!==null}_extendView(view){if(view===null||view.source!==this.fileEntries||view.length>this.fileEntries.length)return;if(view.length===this.fileEntries.length)return view.entries;let missing=!1,tail=[];for(let entry of this.fileEntries.slice(view.length)){if(entry.type==="session")continue;let materialized=this.residentStore.materialize(entry,()=>{missing=!0});tail.push(materialized)}if(!missing)return this._bindMessagePositions(tail),[...view.entries,...tail]}_fromCompactView(path){let entries=this._getCompactEntries(),lookup=this.compactLookup;(lookup===null||lookup.length>entries.length||lookup.length>0&&lookup.entries[lookup.length-1]!==entries[lookup.length-1])&&(lookup={entries,length:0,map:new Map});for(let index=lookup.length;index<entries.length;index++){let entry=entries[index];lookup.map.set(entry.id,entry)}this.compactLookup={entries,length:entries.length,map:lookup.map};let shared=[];for(let entry of path){let materialized=lookup.map.get(entry.id);if(materialized===void 0||materialized.parentId!==entry.parentId)return;shared.push(materialized)}return shared}_bindMessagePositions(entries){for(let entry of entries){if(entry.type!=="message")continue;let order=this.entryOrdersById.get(entry.id);order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order})}}_materializeEntries(entries){return materializeSessionEntries(entries,{residentStore:this.residentStore,loadHistoryEntries:()=>this._loadFullHistoryEntries(),onMaterialized:entry=>{if(entry.type!=="message")return;let order=this.entryOrdersById.get(entry.id);order!==void 0&&this.messageEntryPositions.set(entry.message,{entryId:entry.id,order})}})}_getCompactEntries(){let extended=this._extendView(this.compactView);if(extended!==void 0)return this.compactView={source:this.fileEntries,length:this.fileEntries.length,entries:extended},extended;this.compactEntriesCache?.mutation!==this.mutationCount&&(this.compactEntriesCache={mutation:this.mutationCount,entries:this.fileEntries.filter(e=>e.type!=="session")});let entries=this.compactEntriesCache.entries,missingEntryIds=new Set;for(let entry of entries)this.residentStore.materialize(entry,()=>{missingEntryIds.add(entry.id)});if(missingEntryIds.size>0&&this.sessionFile){let persistedById=new Map(this._loadFullHistoryEntries().map(entry=>[entry.id,entry]));for(let index=0;index<entries.length;index++){let entry=entries[index];if(!missingEntryIds.has(entry.id))continue;let persisted=persistedById.get(entry.id);persisted&&(entries[index]=this.residentStore.externalize(persisted))}}let materialized=entries.map(entry=>this.residentStore.materialize(entry));return this._bindMessagePositions(materialized),this.compactView={source:this.fileEntries,length:this.fileEntries.length,entries:materialized},materialized}_loadFullHistoryEntries(){return this.sessionFile?sessionEntryLoader(this.sessionFile):this.fileEntries}getTree(){let entries=this.getEntries(),nodeMap=new Map,roots=[];for(let entry of entries){if(nodeMap.has(entry.id))continue;let label=this.labelsById.get(entry.id),labelTimestamp=this.labelTimestampsById.get(entry.id);nodeMap.set(entry.id,{entry,children:[],label,labelTimestamp})}for(let entry of entries){let node=nodeMap.get(entry.id);if(node.entry===entry)if(entry.parentId===null||entry.parentId===entry.id)roots.push(node);else{let parent=nodeMap.get(entry.parentId);parent?parent.children.push(node):roots.push(node)}}let stack=[...roots];for(;stack.length>0;){let node=stack.pop();node.children.sort((a,b)=>new Date(a.entry.timestamp).getTime()-new Date(b.entry.timestamp).getTime()),stack.push(...node.children)}return roots}branch(branchFromId){if(this._loadFullMirrorFor(branchFromId),!this.byId.has(branchFromId))throw new Error(`Entry ${branchFromId} not found`);this.leafId=branchFromId,this.mutationCount++}resetLeaf(){this.leafId=null,this.mutationCount++}branchWithSummary(branchFromId,summary,details,fromHook,usage){if(branchFromId!==null&&this._loadFullMirrorFor(branchFromId),branchFromId!==null&&!this.byId.has(branchFromId))throw new Error(`Entry ${branchFromId} not found`);let fromId=this.leafId??"root",entry={type:"branch_summary",id:generateId(this.idsInUse),parentId:branchFromId,timestamp:new Date().toISOString(),fromId,summary,details,usage,fromHook};return this._appendEntry(entry),entry.id}createBranchedSession(leafId){let previousSessionFile=this.sessionFile,path=this.getFullBranch(leafId);if(path.length===0)throw new Error(`Entry ${leafId} not found`);let pathWithoutLabels=[],replacementByLabelId=new Map,pendingLabelIds=[],pathParentId=null;for(let entry of path){if(entry.type==="label"){pendingLabelIds.push(entry.id);continue}for(let labelId of pendingLabelIds)replacementByLabelId.set(labelId,entry.id);pendingLabelIds.length=0,pathWithoutLabels.push(entry.type==="compaction"?{...entry,parentId:pathParentId,firstKeptEntryId:entry.firstKeptEntryId===entry.id?entry.id:replacementByLabelId.get(entry.firstKeptEntryId)??entry.firstKeptEntryId}:{...entry,parentId:pathParentId}),pathParentId=entry.id}let newSessionId=createSessionId(),timestamp=new Date().toISOString(),fileTimestamp=timestamp.replace(/[:.]/g,"-"),newSessionFile=join5(this.getSessionDir(),`${fileTimestamp}_${newSessionId}.jsonl`),header={type:"session",version:CURRENT_SESSION_VERSION,id:newSessionId,timestamp,cwd:this.cwd,parentSession:this.persist?previousSessionFile:void 0},pathEntryIds=new Set(pathWithoutLabels.map(e=>e.id)),labelsToWrite=[];for(let[targetId,label]of this.labelsById)pathEntryIds.has(targetId)&&labelsToWrite.push({targetId,label,timestamp:this.labelTimestampsById.get(targetId)});if(this.persist){let parentId2=pathWithoutLabels[pathWithoutLabels.length-1]?.id||null,labelEntries2=[];for(let{targetId,label,timestamp:labelTimestamp}of labelsToWrite){let labelEntry={type:"label",id:generateId(new Set(pathEntryIds)),parentId:parentId2,timestamp:labelTimestamp,targetId,label};pathEntryIds.add(labelEntry.id),labelEntries2.push(labelEntry),parentId2=labelEntry.id}reserveSessionWrite(newSessionFile);let branchedEntries2=this._materializeEntries([...pathWithoutLabels,...labelEntries2]),previousBlobsDir=this.residentStore.resolvedBlobsDir();return this.residentStore.clear(),previousBlobsDir&&this._removeBlobsDir(previousBlobsDir),this.mirrorTrimmed=!1,this.trimmedIds.clear(),this.sessionId=newSessionId,this.sessionFile=newSessionFile,this.fileEntries=[header,...branchedEntries2.map(entry=>this.residentStore.externalize(entry))],this._buildIndex(),this.mutationCount++,this._hasConversation()?(this._rewriteFile(),this.flushed=!0):this.flushed=!1,newSessionFile}let labelEntries=[],parentId=pathWithoutLabels[pathWithoutLabels.length-1]?.id||null;for(let{targetId,label,timestamp:labelTimestamp}of labelsToWrite){let labelEntry={type:"label",id:generateId(new Set([...pathEntryIds,...labelEntries.map(e=>e.id)])),parentId,timestamp:labelTimestamp,targetId,label};labelEntries.push(labelEntry),parentId=labelEntry.id}let branchedEntries=this._materializeEntries([...pathWithoutLabels,...labelEntries]);this.residentStore.clear(),this.fileEntries=[header,...branchedEntries.map(entry=>this.residentStore.externalize(entry))],this.sessionId=newSessionId,this._buildIndex(),this.mutationCount++}static create(cwd,sessionDir,options){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd);return new _SessionManager(cwd,dir,void 0,!0,options)}static open(path,sessionDir,cwdOverride,options){let resolvedPath=resolvePath(path);reserveSessionWrite(resolvedPath);let discovery=discoverOpenHeader(resolvedPath,cwdOverride),preloadedFileEntries=discovery.needsFullLoad?loadEntriesFromFile(resolvedPath):void 0;terminateFinalSessionLine(resolvedPath);let header=discovery.header??headerOf(preloadedFileEntries),{cwd,dir}=openLocation(resolvedPath,sessionDir,cwdOverride,header);return new _SessionManager(cwd,dir,resolvedPath,!0,options,preloadedFileEntries)}static async openAsync(path,sessionDir,cwdOverride,options,slicer=new EventLoopSlicer){let resolvedPath=resolvePath(path);reserveSessionWrite(resolvedPath);let discovery=discoverOpenHeader(resolvedPath,cwdOverride),preloadedFileEntries=discovery.needsFullLoad?await loadEntriesFromFileAsync(resolvedPath,slicer):void 0;terminateFinalSessionLine(resolvedPath);let header=discovery.header??headerOf(preloadedFileEntries),{cwd,dir}=openLocation(resolvedPath,sessionDir,cwdOverride,header),manager=new _SessionManager(cwd,dir,resolvedPath,!0,options,DEFERRED_FILE_LOAD);try{await manager._setSessionFileAsync(resolvedPath,preloadedFileEntries,options,slicer)}catch(error){throw manager.dispose(),error}return manager}static continueRecent(cwd,sessionDir){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd),filterCwd=sessionDir!==void 0&&dir!==getDefaultSessionDirPath(cwd),mostRecent=findMostRecentSession(dir,filterCwd?cwd:void 0);return mostRecent?new _SessionManager(cwd,dir,mostRecent,!0):new _SessionManager(cwd,dir,void 0,!0)}static inMemory(cwd=process.cwd(),options,entries){return new _SessionManager(cwd,"",void 0,!1,options,entries)}static forkFrom(sourcePath,targetCwd,sessionDir,options){let resolvedSourcePath=resolvePath(sourcePath),resolvedTargetCwd=resolvePath(targetCwd),sourceEntries=loadEntriesFromFile(resolvedSourcePath);if(sourceEntries.length===0)throw new Error(`Cannot fork: source session file is empty or invalid: ${resolvedSourcePath}`);if(!sourceEntries.find(e=>e.type==="session"))throw new Error(`Cannot fork: source session has no header: ${resolvedSourcePath}`);let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(resolvedTargetCwd);existsSync4(dir)||mkdirSync2(dir,{recursive:!0}),options?.id!==void 0&&assertValidSessionId(options.id);let newSessionId=options?.id??createSessionId(),timestamp=new Date().toISOString(),fileTimestamp=timestamp.replace(/[:.]/g,"-"),newSessionFile=join5(dir,`${fileTimestamp}_${newSessionId}.jsonl`),newHeader={type:"session",version:CURRENT_SESSION_VERSION,id:newSessionId,timestamp,cwd:resolvedTargetCwd,parentSession:resolvedSourcePath};reserveSessionWrite(newSessionFile),writeFileSync3(newSessionFile,`${JSON.stringify(newHeader)}
|
|
38
38
|
`,{flag:"wx"});for(let entry of sourceEntries)entry.type!=="session"&&appendFileSync(newSessionFile,`${JSON.stringify(entry)}
|
|
39
|
-
`);return new _SessionManager(resolvedTargetCwd,dir,newSessionFile,!0)}static findById(cwd,id,sessionDir){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd),filterCwd=sessionDir!==void 0&&dir!==getDefaultSessionDirPath(cwd),matchesCwd=sessionCwdMatcher(resolvePath(cwd));try{for(let file of readdirSync(dir)){if(!file.endsWith(".jsonl"))continue;let path=join5(dir,file),header=readSessionHeaderForDiscovery(path);if(header?.id===id&&!(filterCwd&&!matchesCwd(getSessionHeaderCwd(header))))return path}}catch{}}static async list(cwd,sessionDir,onProgress,signal){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd),filterCwd=sessionDir!==void 0&&dir!==getDefaultSessionDirPath(cwd),matchesCwd=sessionCwdMatcher(resolvePath(cwd)),includeSession=session=>!filterCwd||matchesCwd(session.cwd),sessions=(await listSessionsFromDir(dir,onProgress?(loaded,total,partialSessions)=>onProgress(loaded,total,partialSessions?.filter(includeSession)):void 0,signal)).filter(includeSession);return sortSessionInfos(sessions)}static async listAll(sessionDirOrOnProgress,onProgressOrSignal,signal){let customSessionDir=typeof sessionDirOrOnProgress=="string"?normalizePath(sessionDirOrOnProgress):void 0,progress=typeof sessionDirOrOnProgress=="function"?sessionDirOrOnProgress:typeof onProgressOrSignal=="function"?onProgressOrSignal:void 0,abortSignal=typeof sessionDirOrOnProgress=="string"||typeof onProgressOrSignal=="function"?signal:onProgressOrSignal??signal;if(abortSignal?.throwIfAborted(),customSessionDir)return sortSessionInfos(await listSessionsFromDir(customSessionDir,progress,abortSignal));let sessionsDir=getSessionsDir();try{if(!existsSync4(sessionsDir))return[];let dirs=(await readdir2(sessionsDir,{withFileTypes:!0})).filter(entry=>entry.isDirectory()||entry.isSymbolicLink()).map(entry=>join5(sessionsDir,entry.name)),totalFiles=0,dirFiles=[];for(let dir of dirs)try{let files=(await readdir2(dir)).filter(f=>f.endsWith(".jsonl"));dirFiles.push(files.map(f=>join5(dir,f))),totalFiles+=files.length}catch{dirFiles.push([])}let loaded=0,partialSessions=[],onLoaded=info=>{loaded++,info&&partialSessions.push(info);let publish=loaded===1||loaded%ALL_SESSION_LIST_PUBLISH_INTERVAL===0||loaded===totalFiles;progress?.(loaded,totalFiles,publish?sortSessionInfos([...partialSessions]):void 0)},sessions=[];for(let[index,dir]of dirs.entries())sessions.push(...await listSessionFilesInDir(dir,dirFiles[index]??[],onLoaded,abortSignal));return sortSessionInfos(sessions)}catch{return abortSignal?.throwIfAborted(),[]}}};export{VIRTUAL_MODEL_STATE_ENTRY,isVirtualModel,findLatestResponse,getBranchSelection,getVirtualModelState,createVirtualModel,withVirtualModels,EventLoopSlicer,hasUnsafeRetainedContent,isSafeBoundedValue,sessionCwdMatcher,REPOSITORY_IDENTITY_ENTRY_TYPE,readRepositoryIdentity,compareRepositoryIdentities,parseRepositoryIdentity,sameRepositoryIdentity,parseEntryLine,readFileLines,listSessionsFromDir,loadEntriesFromFile,reserveSessionWrite,unregisterSessionWriter,resolveEnvironmentContext,environmentContextMessageIfChanged,imageContentId,elidedImageIds,rejectedImageSources,toolResultUserWords,userWordBlocks,GOAL_CONTINUATION_MESSAGE_TYPE,isContextExcludedCustomMessage,createBranchSummaryMessage,createCompactionSummaryMessage,createCustomMessage,convertToLlm,TRANSPORT_IMAGE_BUDGET_BYTES,convertToLlmForTransport,SESSION_CONTEXT_ENTRY_ID,getSessionContextEntryId,inheritSessionContextEntryId,CURRENT_SESSION_VERSION,assertValidSessionId,migrateSessionEntries,parseSessionEntries,getLatestCompactionEntry,sessionEntryToContextMessages,buildContextEntries,buildSessionProjection,buildSessionContext,getDefaultSessionDir,findMostRecentSession,SessionManager};
|
|
39
|
+
`);return new _SessionManager(resolvedTargetCwd,dir,newSessionFile,!0)}static findById(cwd,id,sessionDir){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd),filterCwd=sessionDir!==void 0&&dir!==getDefaultSessionDirPath(cwd),matchesCwd=sessionCwdMatcher(resolvePath(cwd));try{for(let file of readdirSync(dir)){if(!file.endsWith(".jsonl"))continue;let path=join5(dir,file),header=readSessionHeaderForDiscovery(path);if(header?.id===id&&!(filterCwd&&!matchesCwd(getSessionHeaderCwd(header))))return path}}catch{}}static async list(cwd,sessionDir,onProgress,signal){let dir=sessionDir?normalizePath(sessionDir):getDefaultSessionDir(cwd),filterCwd=sessionDir!==void 0&&dir!==getDefaultSessionDirPath(cwd),matchesCwd=sessionCwdMatcher(resolvePath(cwd)),includeSession=session=>!filterCwd||matchesCwd(session.cwd),sessions=(await listSessionsFromDir(dir,onProgress?(loaded,total,partialSessions)=>onProgress(loaded,total,partialSessions?.filter(includeSession)):void 0,signal)).filter(includeSession);return sortSessionInfos(sessions)}static async listAll(sessionDirOrOnProgress,onProgressOrSignal,signal){let customSessionDir=typeof sessionDirOrOnProgress=="string"?normalizePath(sessionDirOrOnProgress):void 0,progress=typeof sessionDirOrOnProgress=="function"?sessionDirOrOnProgress:typeof onProgressOrSignal=="function"?onProgressOrSignal:void 0,abortSignal=typeof sessionDirOrOnProgress=="string"||typeof onProgressOrSignal=="function"?signal:onProgressOrSignal??signal;if(abortSignal?.throwIfAborted(),customSessionDir)return sortSessionInfos(await listSessionsFromDir(customSessionDir,progress,abortSignal));let sessionsDir=getSessionsDir();try{if(!existsSync4(sessionsDir))return[];let dirs=(await readdir2(sessionsDir,{withFileTypes:!0})).filter(entry=>entry.isDirectory()||entry.isSymbolicLink()).map(entry=>join5(sessionsDir,entry.name)),totalFiles=0,dirFiles=[];for(let dir of dirs)try{let files=(await readdir2(dir)).filter(f=>f.endsWith(".jsonl"));dirFiles.push(files.map(f=>join5(dir,f))),totalFiles+=files.length}catch{dirFiles.push([])}let loaded=0,partialSessions=[],onLoaded=info=>{loaded++,info&&partialSessions.push(info);let publish=loaded===1||loaded%ALL_SESSION_LIST_PUBLISH_INTERVAL===0||loaded===totalFiles;progress?.(loaded,totalFiles,publish?sortSessionInfos([...partialSessions]):void 0)},sessions=[];for(let[index,dir]of dirs.entries())sessions.push(...await listSessionFilesInDir(dir,dirFiles[index]??[],onLoaded,abortSignal));return sortSessionInfos(sessions)}catch{return abortSignal?.throwIfAborted(),[]}}};export{VIRTUAL_MODEL_STATE_ENTRY,isVirtualModel,findLatestResponse,getBranchSelection,getVirtualModelState,createVirtualModel,withVirtualModels,EventLoopSlicer,hasUnsafeRetainedContent,isSafeBoundedValue,sessionCwdMatcher,REPOSITORY_IDENTITY_ENTRY_TYPE,readRepositoryIdentity,compareRepositoryIdentities,parseRepositoryIdentity,sameRepositoryIdentity,parseEntryLine,readFileLines,listSessionsFromDir,loadEntriesFromFile,SessionMovedAwayError,reserveSessionWrite,unregisterSessionWriter,resolveEnvironmentContext,environmentContextMessageIfChanged,imageContentId,elidedImageIds,rejectedImageSources,toolResultUserWords,userWordBlocks,GOAL_CONTINUATION_MESSAGE_TYPE,isContextExcludedCustomMessage,createBranchSummaryMessage,createCompactionSummaryMessage,createCustomMessage,convertToLlm,TRANSPORT_IMAGE_BUDGET_BYTES,convertToLlmForTransport,SESSION_CONTEXT_ENTRY_ID,getSessionContextEntryId,inheritSessionContextEntryId,CURRENT_SESSION_VERSION,assertValidSessionId,migrateSessionEntries,parseSessionEntries,getLatestCompactionEntry,sessionEntryToContextMessages,buildContextEntries,buildSessionProjection,buildSessionContext,getDefaultSessionDir,findMostRecentSession,SessionManager};
|