@ai-agent-forge/agent-forge 0.85.6 → 0.85.8

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.
@@ -904,7 +904,7 @@ ${command}`:command,spawnContext=resolveSpawnContext(resolvedCommand,ctx?.cwd||c
904
904
  `),maxLineNum=Math.max(oldLines.length,newLines.length),lineNumWidth=String(maxLineNum).length,oldLineNum=1,newLineNum=1,lastWasChange=!1,firstChangedLine;for(let i=0;i<parts.length;i++){let part=parts[i],raw=part.value.split(`
905
905
  `);if(raw[raw.length-1]===""&&raw.pop(),part.added||part.removed){firstChangedLine===void 0&&(firstChangedLine=newLineNum);for(let line of raw)if(part.added){let lineNum=String(newLineNum).padStart(lineNumWidth," ");output.push(`+${lineNum} ${line}`),newLineNum++}else{let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(`-${lineNum} ${line}`),oldLineNum++}lastWasChange=!0}else{let nextPartIsChange=i<parts.length-1&&(parts[i+1].added||parts[i+1].removed),hasLeadingChange=lastWasChange,hasTrailingChange=nextPartIsChange;if(hasLeadingChange&&hasTrailingChange)if(raw.length<=contextLines*2)for(let line of raw){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}else{let leadingLines=raw.slice(0,contextLines),trailingLines=raw.slice(raw.length-contextLines),skippedLines=raw.length-leadingLines.length-trailingLines.length;for(let line of leadingLines){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}output.push(` ${"".padStart(lineNumWidth," ")} ...`),oldLineNum+=skippedLines,newLineNum+=skippedLines;for(let line of trailingLines){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}}else if(hasLeadingChange){let shownLines=raw.slice(0,contextLines),skippedLines=raw.length-shownLines.length;for(let line of shownLines){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}skippedLines>0&&(output.push(` ${"".padStart(lineNumWidth," ")} ...`),oldLineNum+=skippedLines,newLineNum+=skippedLines)}else if(hasTrailingChange){let skippedLines=Math.max(0,raw.length-contextLines);skippedLines>0&&(output.push(` ${"".padStart(lineNumWidth," ")} ...`),oldLineNum+=skippedLines,newLineNum+=skippedLines);for(let line of raw.slice(skippedLines)){let lineNum=String(oldLineNum).padStart(lineNumWidth," ");output.push(` ${lineNum} ${line}`),oldLineNum++,newLineNum++}}else oldLineNum+=raw.length,newLineNum+=raw.length;lastWasChange=!1}}return{diff:output.join(`
906
906
  `),firstChangedLine}}var defaultEditDiffOperations={access:absolutePath=>access2(absolutePath,constants4.R_OK),readFile:absolutePath=>readFile8(absolutePath,"utf-8")};async function computeEditsDiff(path15,edits,cwd,operations=defaultEditDiffOperations){let absolutePath=resolveToCwd(path15,cwd);try{try{await operations.access(absolutePath)}catch(error2){let errorMessage2=error2 instanceof Error&&"code"in error2?`Error code: ${error2.code}`:String(error2);return{error:`Could not edit file: ${path15}. ${errorMessage2}.`}}let rawContent=await operations.readFile(absolutePath),{text:content}=splitBom(rawContent),normalizedContent=normalizeToLF2(content),{baseContent,newContent}=applyEditsToNormalizedContent2(normalizedContent,edits,path15);return generateDiffString2(baseContent,newContent)}catch(err2){return{error:err2 instanceof Error?err2.message:String(err2)}}}import{realpath}from"node:fs/promises";import{resolve as resolve9}from"node:path";var fileMutationQueues=new Map,registrationQueue=Promise.resolve();function isMissingPathError2(error2){return typeof error2=="object"&&error2!==null&&"code"in error2&&(error2.code==="ENOENT"||error2.code==="ENOTDIR")}async function getMutationQueueKey(filePath){let resolvedPath=resolve9(filePath);try{return await realpath(resolvedPath)}catch(error2){if(isMissingPathError2(error2))return resolvedPath;throw error2}}async function withFileMutationQueue2(filePath,fn){let registration=registrationQueue.then(async()=>{let key2=await getMutationQueueKey(filePath),currentQueue2=fileMutationQueues.get(key2)??Promise.resolve(),releaseNext2,nextQueue=new Promise(resolveQueue=>{releaseNext2=resolveQueue}),chainedQueue2=currentQueue2.then(()=>nextQueue);return fileMutationQueues.set(key2,chainedQueue2),{key:key2,currentQueue:currentQueue2,chainedQueue:chainedQueue2,releaseNext:releaseNext2}});registrationQueue=registration.then(()=>{},()=>{});let{key,currentQueue,chainedQueue,releaseNext}=await registration;await currentQueue;try{return await fn()}finally{releaseNext(),fileMutationQueues.get(key)===chainedQueue&&fileMutationQueues.delete(key)}}import{constants as constants5}from"fs";import{access as fsAccess2,readFile as fsReadFile,writeFile as fsWriteFile}from"fs/promises";var replaceEditSchema2=typebox_exports.Object({oldText:typebox_exports.String({description:"Exact text for one targeted replacement. It must be unique in the original file and must not overlap with any other edits[].oldText in the same call."}),newText:typebox_exports.String({description:"Replacement text for this targeted edit."})},{}),editSchema2=typebox_exports.Object({path:typebox_exports.String({description:"Path to the file to edit (relative or absolute)"}),edits:typebox_exports.Array(replaceEditSchema2,{description:"One or more targeted replacements. Each edit is matched against the original file, not incrementally. Do not include overlapping or nested edits. If two changes touch the same block or nearby lines, merge them into one edit instead."})},{}),editToolSystemPromptContribution={snippet:"Make precise file edits with exact text replacement, including multiple disjoint edits in one call",guidelines:["Use edit for precise changes (edits[].oldText must match exactly)","When changing multiple separate locations in one file, use one edit call with multiple entries in edits[] instead of multiple edit calls","Each edits[].oldText is matched against the original file, not after earlier edits are applied. Do not emit overlapping or nested edits. Merge nearby changes into one edit.","Keep edits[].oldText as small as possible while still being unique in the file. Do not pad with large unchanged regions."]};function isSingleEditInput(value){if(!value||typeof value!="object"||Array.isArray(value))return!1;let edit=value;return typeof edit.oldText=="string"&&typeof edit.newText=="string"}var defaultEditOperations={readFile:path15=>fsReadFile(path15),writeFile:(path15,content)=>fsWriteFile(path15,content,"utf-8"),access:path15=>fsAccess2(path15,constants5.R_OK|constants5.W_OK)};function prepareEditArguments(input){if(!input||typeof input!="object")return input;let args=input;if(typeof args.edits=="string")try{let parsed=JSON.parse(args.edits);Array.isArray(parsed)?args.edits=parsed:isSingleEditInput(parsed)&&(args.edits=[parsed])}catch{}else isSingleEditInput(args.edits)&&(args.edits=[args.edits]);let legacy=args;if(typeof legacy.oldText!="string"||typeof legacy.newText!="string")return args;let edits=Array.isArray(legacy.edits)?[...legacy.edits]:[];edits.push({oldText:legacy.oldText,newText:legacy.newText});let{oldText:_oldText,newText:_newText,...rest}=legacy;return{...rest,edits}}function validateEditInput(input){if(!Array.isArray(input.edits)||input.edits.length===0)throw new Error("Edit tool input is invalid. edits must contain at least one replacement.");return{path:input.path,edits:input.edits}}function createEditCallRenderComponent(){return Object.assign(new Box(1,1,text=>text),{preview:void 0,previewArgsKey:void 0,previewPending:!1,settledError:!1})}function getEditCallRenderComponent(state2,lastComponent){if(lastComponent instanceof Box){let component2=lastComponent;return state2.callComponent=component2,component2}if(state2.callComponent)return state2.callComponent;let component=createEditCallRenderComponent();return state2.callComponent=component,component}function getRenderablePreviewInput(args){if(!args)return null;let path15=typeof args.path=="string"?args.path:typeof args.file_path=="string"?args.file_path:null;return path15?Array.isArray(args.edits)&&args.edits.length>0&&args.edits.every(edit=>typeof edit?.oldText=="string"&&typeof edit?.newText=="string")?{path:path15,edits:args.edits}:typeof args.oldText=="string"&&typeof args.newText=="string"?{path:path15,edits:[{oldText:args.oldText,newText:args.newText}]}:null:null}function formatEditCall(args,theme2,cwd){let pathDisplay=renderToolPath(str(args?.file_path??args?.path),theme2,cwd);return`${theme2.fg("toolTitle",theme2.bold("edit"))} ${pathDisplay}`}function formatEditResult(args,preview,result,theme2,isError){let rawPath=str(args?.file_path??args?.path),previewDiff=preview&&!("error"in preview)?preview.diff:void 0,previewError=preview&&"error"in preview?preview.error:void 0;if(isError){let errorText=result.content.filter(c2=>c2.type==="text").map(c2=>c2.text||"").join(`
907
- `);return!errorText||errorText===previewError?void 0:theme2.fg("error",errorText)}let resultDiff=result.details?.diff;if(resultDiff&&resultDiff!==previewDiff)return renderDiff(resultDiff,{filePath:rawPath??void 0})}function getEditHeaderBg(preview,settledError,theme2){return preview?"error"in preview?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolSuccessBg",text):settledError?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolPendingBg",text)}function buildEditCallComponent(component,args,theme2,cwd){if(component.setBgFn(getEditHeaderBg(component.preview,component.settledError,theme2)),component.clear(),component.addChild(new Text(formatEditCall(args,theme2,cwd),0,0)),!component.preview)return component;let body="error"in component.preview?theme2.fg("error",component.preview.error):renderDiff(component.preview.diff);return component.addChild(new Spacer(1)),component.addChild(new Text(body,0,0)),component}function setEditPreview(component,preview,argsKey){let current=component.preview,changed=current===void 0||("error"in current&&"error"in preview?current.error!==preview.error:"error"in current!="error"in preview)||!("error"in current)&&!("error"in preview)&&(current.diff!==preview.diff||current.firstChangedLine!==preview.firstChangedLine);return component.preview=preview,component.previewArgsKey=argsKey,component.previewPending=!1,changed}function createEditToolDefinition(cwd,options){let ops=options?.operations??defaultEditOperations;return{name:"edit",label:"edit",description:"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.",promptSnippet:editToolSystemPromptContribution.snippet,promptGuidelines:[...editToolSystemPromptContribution.guidelines],parameters:editSchema2,constrainedSampling:{type:"json_schema",strict:"prefer"},renderShell:"self",prepareArguments:prepareEditArguments,async execute(_toolCallId,input,signal,_onUpdate,ctx){let{path:path15,edits}=validateEditInput(input),absolutePath=resolveToCwd(path15,ctx?.cwd||cwd);return withFileMutationQueue2(absolutePath,async()=>{let throwIfAborted=()=>{if(signal?.aborted)throw new Error("Operation aborted")};throwIfAborted();try{await ops.access(absolutePath)}catch(error2){throwIfAborted();let errorMessage2=error2 instanceof Error&&"code"in error2?`Error code: ${error2.code}`:String(error2);throw new Error(`Could not edit file: ${path15}. ${errorMessage2}.`)}throwIfAborted();let rawContent=(await ops.readFile(absolutePath)).toString("utf-8");throwIfAborted();let{bom,text:content}=splitBom(rawContent),originalEnding=detectLineEnding2(content),normalizedContent=normalizeToLF2(content),{baseContent,newContent}=applyEditsToNormalizedContent2(normalizedContent,edits,path15);throwIfAborted();let finalContent=bom+restoreLineEndings2(newContent,originalEnding);await ops.writeFile(absolutePath,finalContent),throwIfAborted();let diffResult=generateDiffString2(baseContent,newContent),patch=generateUnifiedPatch2(path15,baseContent,newContent);return{content:[{type:"text",text:`Successfully replaced ${edits.length} block(s) in ${path15}.`}],details:{diff:diffResult.diff,patch,firstChangedLine:diffResult.firstChangedLine}}})},renderCall(args,theme2,context){let component=getEditCallRenderComponent(context.state,context.lastComponent),previewInput=getRenderablePreviewInput(args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0;if(component.previewArgsKey!==argsKey&&(component.preview=void 0,component.previewArgsKey=argsKey,component.previewPending=!1,component.settledError=!1),context.argsComplete&&previewInput&&!component.preview&&!component.previewPending){component.previewPending=!0;let requestKey=argsKey;computeEditsDiff(previewInput.path,previewInput.edits,context.cwd).then(preview=>{component.previewArgsKey===requestKey&&(setEditPreview(component,preview,requestKey),context.invalidate())})}return buildEditCallComponent(component,args,theme2,context.cwd)},renderResult(result,_options,theme2,context){let callComponent=context.state.callComponent,previewInput=getRenderablePreviewInput(context.args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0,typedResult=result,resultDiff=context.isError?void 0:typedResult.details?.diff,changed=!1;callComponent&&(typeof resultDiff=="string"&&(changed=setEditPreview(callComponent,{diff:resultDiff,firstChangedLine:typedResult.details?.firstChangedLine},argsKey)||changed),callComponent.settledError!==context.isError&&(callComponent.settledError=context.isError,changed=!0),changed&&buildEditCallComponent(callComponent,context.args,theme2,context.cwd));let output=formatEditResult(context.args,callComponent?.preview,typedResult,theme2,context.isError),component=context.lastComponent??new Container;return component.clear(),output&&(component.addChild(new Spacer(1)),component.addChild(new Text(output,1,0))),component}}}function createEditTool2(cwd,options){return wrapToolDefinition(createEditToolDefinition(cwd,options))}import{createInterface as createInterface2}from"node:readline";import{spawn as spawn4}from"child_process";import path9 from"path";import{spawnSync as spawnSync3}from"child_process";import{createHash as createHash6}from"crypto";import{chmodSync,createWriteStream as createWriteStream2,existsSync as existsSync9,mkdirSync as mkdirSync8,readdirSync as readdirSync9,renameSync as renameSync2,rmSync as rmSync2}from"fs";import{arch,platform}from"os";import{join as join33}from"path";import{Readable,Transform}from"stream";import{pipeline}from"stream/promises";var TOOLS_DIR=getBinDir(),NETWORK_TIMEOUT_MS=1e4,DOWNLOAD_TIMEOUT_MS=12e4;function isOfflineModeEnabled(){let value=process.env.AGENT_FORGE_OFFLINE;return value?value==="1"||value.toLowerCase()==="true"||value.toLowerCase()==="yes":!1}var TOOLS={fd:{name:"fd",repo:"sharkdp/fd",binaryName:"fd",systemBinaryNames:["fd","fdfind"],tagPrefix:"v",pinnedVersion:"10.5.0",digests:{"fd-v10.5.0-x86_64-apple-darwin.tar.gz":"7e31028c62c6955877735d0406807aa484c2a5e6f86235a59e26c29c301da590","fd-v10.5.0-aarch64-apple-darwin.tar.gz":"b67e1836c468e42e411984b56e52fa7abec08c2bd22c867398e7cc134aac5e12","fd-v10.5.0-x86_64-unknown-linux-musl.tar.gz":"761c72dc8e120d85b22292063be8a796e2eeb20eb3e4f38b8fa2343ccf3514a7","fd-v10.5.0-aarch64-unknown-linux-musl.tar.gz":"d76c4317f7d5dba69f8a2a15856c90c777e7f0dd4e85f0de8c76de6992c374d4","fd-v10.5.0-x86_64-pc-windows-msvc.zip":"a227701b8551c35a9931d9f6da75503cf86d88e182d71fb849a70864c5d57cd7","fd-v10.5.0-aarch64-pc-windows-msvc.zip":"a2bcddcfd259b05357a77bbc6cd671fdb30f63fd266a0e748305890a8c5ceaa6"},getAssetName:(version,plat,architecture)=>plat==="darwin"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null},rg:{name:"ripgrep",repo:"BurntSushi/ripgrep",binaryName:"rg",tagPrefix:"",checksumSuffix:".sha256",getAssetName:(version,plat,architecture)=>plat==="darwin"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null}};function commandExists(cmd){try{let result=spawnSync3(cmd,["--version"],{stdio:"pipe"});return result.error===void 0||result.error===null}catch{return!1}}function getToolPath(tool){let config=TOOLS[tool];if(!config)return null;let localPath=join33(TOOLS_DIR,config.binaryName+(platform()==="win32"?".exe":""));if(existsSync9(localPath))return localPath;let systemBinaryNames=config.systemBinaryNames??[config.binaryName];for(let systemBinaryName of systemBinaryNames)if(commandExists(systemBinaryName))return systemBinaryName;return null}async function getLatestVersion(repo){let response2=await fetchWithRetry(`https://github.com/${repo}/releases/latest`,{headers:{"User-Agent":`${APP_NAME}-agent-forge`},redirect:"manual"},{timeoutMs:NETWORK_TIMEOUT_MS});try{await response2.body?.cancel()}catch{}let location=response2.status>=300&&response2.status<400?response2.headers.get("location"):null;if(!location)throw new Error(`Failed to resolve latest ${repo} release: HTTP ${response2.status} without redirect`);let tag=new URL(location,"https://github.com").pathname.split("/").pop();if(!tag||!location.includes("/releases/tag/"))throw new Error(`Failed to resolve latest ${repo} release: unexpected redirect to ${location}`);return decodeURIComponent(tag).replace(/^v/,"")}var DownloadIntegrityError=class extends Error{expectedSha256;actualSha256;constructor(url,expectedSha256,actualSha256){super(`Download integrity check failed for ${url}: expected sha256 ${expectedSha256}, got ${actualSha256}`),this.name="DownloadIntegrityError",this.expectedSha256=expectedSha256,this.actualSha256=actualSha256}};async function downloadFile(url,dest,expectedSha256){let response2=await fetchWithRetry(url,void 0,{timeoutMs:DOWNLOAD_TIMEOUT_MS});if(!response2.ok)throw new Error(`Download failed with HTTP ${response2.status}: ${url}`);if(!response2.body)throw new Error("No response body");let hash=createHash6("sha256"),digestTap=new Transform({transform(chunk,_encoding,callback){hash.update(chunk),callback(null,chunk)}}),fileStream=createWriteStream2(dest);if(await pipeline(Readable.fromWeb(response2.body),digestTap,fileStream),expectedSha256===void 0)return;let actual=hash.digest("hex"),expected=expectedSha256.trim().toLowerCase();if(actual!==expected)throw rmSync2(dest,{force:!0}),new DownloadIntegrityError(url,expected,actual)}var SHA256_HEX_PATTERN=/^[0-9a-f]{64}$/;async function resolveExpectedSha256(config,downloadUrl,assetName){let digests=config.digests;if(digests){let digest=digests[assetName];if(digest===void 0)throw new Error(`No committed sha256 for ${config.name} asset ${assetName}; refresh the pin and its digests`);return digest}if(config.checksumSuffix!==void 0)return fetchReleaseSha256(`${downloadUrl}${config.checksumSuffix}`)}async function fetchReleaseSha256(checksumUrl){let response2=await fetchWithRetry(checksumUrl,void 0,{timeoutMs:NETWORK_TIMEOUT_MS});if(!response2.ok)throw new Error(`Failed to fetch release checksum: HTTP ${response2.status}: ${checksumUrl}`);let digest=(await response2.text()).trim().split(/\s+/)[0]?.toLowerCase()??"";if(!SHA256_HEX_PATTERN.test(digest))throw new Error(`Release checksum has an unexpected format: ${checksumUrl}`);return digest}function findBinaryRecursively(rootDir,binaryFileName){let stack=[rootDir];for(;stack.length>0;){let currentDir=stack.pop();if(!currentDir)continue;let entries=readdirSync9(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join33(currentDir,entry.name);if(entry.isFile()&&entry.name===binaryFileName)return fullPath;entry.isDirectory()&&stack.push(fullPath)}}return null}function formatSpawnFailure(result){if(result.error?.message)return result.error.message;let stderr=result.stderr?.toString().trim();if(stderr)return stderr;let stdout=result.stdout?.toString().trim();return stdout||`exit status ${result.status??"unknown"}`}function runExtractionCommand(command,args){let result=spawnSync3(command,args,{stdio:"pipe"});return!result.error&&result.status===0?null:`${command}: ${formatSpawnFailure(result)}`}function extractTarGzArchive(archivePath,extractDir,assetName){let failure2=runExtractionCommand("tar",["xzf",archivePath,"-C",extractDir]);if(failure2)throw new Error(`Failed to extract ${assetName}: ${failure2}`)}function getWindowsTarCommand(){let systemRoot=process.env.SystemRoot??process.env.WINDIR;if(systemRoot){let systemTar=join33(systemRoot,"System32","tar.exe");if(existsSync9(systemTar))return systemTar}return"tar.exe"}function extractZipArchive(archivePath,extractDir,assetName){let failures=[];if(platform()==="win32"){let tarFailure=runExtractionCommand(getWindowsTarCommand(),["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure);let powershellFailure=runExtractionCommand("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command","& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }",archivePath,extractDir]);if(!powershellFailure)return;failures.push(powershellFailure)}else{let unzipFailure=runExtractionCommand("unzip",["-q",archivePath,"-d",extractDir]);if(!unzipFailure)return;failures.push(unzipFailure);let tarFailure=runExtractionCommand("tar",["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure)}throw new Error(`Failed to extract ${assetName}: ${failures.join("; ")}`)}async function downloadTool(tool){let config=TOOLS[tool];if(!config)throw new Error(`Unknown tool: ${tool}`);let plat=platform(),architecture=arch(),version=config.pinnedVersion??await getLatestVersion(config.repo),assetName=config.getAssetName(version,plat,architecture);if(!assetName)throw new Error(`Unsupported platform: ${plat}/${architecture}`);mkdirSync8(TOOLS_DIR,{recursive:!0});let downloadUrl=`https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`,expectedSha256=await resolveExpectedSha256(config,downloadUrl,assetName),archivePath=join33(TOOLS_DIR,assetName),binaryExt=plat==="win32"?".exe":"",binaryPath=join33(TOOLS_DIR,config.binaryName+binaryExt);await downloadFile(downloadUrl,archivePath,expectedSha256);let extractDir=join33(TOOLS_DIR,`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2,10)}`);mkdirSync8(extractDir,{recursive:!0});try{if(assetName.endsWith(".tar.gz"))extractTarGzArchive(archivePath,extractDir,assetName);else if(assetName.endsWith(".zip"))extractZipArchive(archivePath,extractDir,assetName);else throw new Error(`Unsupported archive format: ${assetName}`);let binaryFileName=config.binaryName+binaryExt,extractedDir=join33(extractDir,assetName.replace(/\.(tar\.gz|zip)$/,"")),extractedBinary=[join33(extractedDir,binaryFileName),join33(extractDir,binaryFileName)].find(candidate=>existsSync9(candidate));if(extractedBinary||(extractedBinary=findBinaryRecursively(extractDir,binaryFileName)??void 0),extractedBinary)renameSync2(extractedBinary,binaryPath);else throw new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);plat!=="win32"&&chmodSync(binaryPath,493)}finally{rmSync2(archivePath,{force:!0}),rmSync2(extractDir,{recursive:!0,force:!0})}return binaryPath}var TERMUX_PACKAGES={fd:"fd",rg:"ripgrep"};async function ensureTool(tool,onStatus){let existingPath=getToolPath(tool);if(existingPath)return existingPath;let config=TOOLS[tool];if(config){if(isOfflineModeEnabled()){onStatus?.({type:"warning",message:`${config.name} not found. Offline mode enabled, skipping download.`});return}if(platform()==="android"){let pkgName=TERMUX_PACKAGES[tool]??tool;onStatus?.({type:"warning",message:`${config.name} not found. Install with: pkg install ${pkgName}`});return}onStatus?.({type:"info",message:`${config.name} not found. Downloading...`});try{let path15=await downloadTool(tool);return onStatus?.({type:"info",message:`${config.name} installed to ${path15}`}),path15}catch(e){let messages=[];for(let current=e,depth=0;current instanceof Error&&depth<5;current=current.cause,depth++)messages.includes(current.message)||messages.push(current.message);onStatus?.({type:"warning",message:`Failed to download ${config.name}: ${messages.length>0?messages.join(": "):String(e)}`});return}}}function relativizeFindResultPath(resultPath,searchPath,pathModule=path9){let hadTrailingSeparator=resultPath.endsWith(pathModule.sep)||pathModule.sep==="\\"&&resultPath.endsWith("/"),posixPath=(pathModule.isAbsolute(resultPath)?pathModule.relative(searchPath,resultPath):resultPath).split(pathModule.sep).join("/");return hadTrailingSeparator&&!posixPath.endsWith("/")?`${posixPath}/`:posixPath}var findSchema=typebox_exports.Object({pattern:typebox_exports.String({description:"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'"}),path:typebox_exports.Optional(typebox_exports.String({description:"Directory to search in (default: current directory)"})),limit:typebox_exports.Optional(typebox_exports.Number({description:"Maximum number of results (default: 1000)"}))}),findToolSystemPromptContribution={snippet:"Find files by glob pattern (respects .gitignore)",guidelines:[]},DEFAULT_LIMIT=1e3,defaultFindOperations={exists:pathExists,glob:()=>[]};function formatFindCall(args,theme2){let pattern=str(args?.pattern),rawPath=str(args?.path),path15=rawPath!==null?shortenPath(rawPath||"."):null,limit=args?.limit,invalidArg=invalidArgText(theme2),text=theme2.fg("toolTitle",theme2.bold("find"))+" "+(pattern===null?invalidArg:theme2.fg("accent",pattern||""))+theme2.fg("toolOutput",` in ${path15===null?invalidArg:path15}`);return limit!==void 0&&(text+=theme2.fg("toolOutput",` (limit ${limit})`)),text}function formatFindResult(result,options,theme2,showImages){let output=getTextOutput(result,showImages).trim(),text="";if(output){let lines=output.split(`
907
+ `);return!errorText||errorText===previewError?void 0:theme2.fg("error",errorText)}let resultDiff=result.details?.diff;if(resultDiff&&resultDiff!==previewDiff)return renderDiff(resultDiff,{filePath:rawPath??void 0})}function getEditHeaderBg(preview,settledError,theme2){return preview?"error"in preview?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolSuccessBg",text):settledError?text=>theme2.bg("toolErrorBg",text):text=>theme2.bg("toolPendingBg",text)}function buildEditCallComponent(component,args,theme2,cwd){if(component.setBgFn(getEditHeaderBg(component.preview,component.settledError,theme2)),component.clear(),component.addChild(new Text(formatEditCall(args,theme2,cwd),0,0)),!component.preview)return component;let body="error"in component.preview?theme2.fg("error",component.preview.error):renderDiff(component.preview.diff);return component.addChild(new Spacer(1)),component.addChild(new Text(body,0,0)),component}function setEditPreview(component,preview,argsKey){let current=component.preview,changed=current===void 0||("error"in current&&"error"in preview?current.error!==preview.error:"error"in current!="error"in preview)||!("error"in current)&&!("error"in preview)&&(current.diff!==preview.diff||current.firstChangedLine!==preview.firstChangedLine);return component.preview=preview,component.previewArgsKey=argsKey,component.previewPending=!1,changed}function createEditToolDefinition(cwd,options){let ops=options?.operations??defaultEditOperations;return{name:"edit",label:"edit",description:"Edit a single file using exact text replacement. Every edits[].oldText must match a unique, non-overlapping region of the original file. If two changes affect the same block or nearby lines, merge them into one edit instead of emitting overlapping edits. Do not include large unchanged regions just to connect distant changes.",promptSnippet:editToolSystemPromptContribution.snippet,promptGuidelines:[...editToolSystemPromptContribution.guidelines],parameters:editSchema2,constrainedSampling:{type:"json_schema",strict:"prefer"},renderShell:"self",prepareArguments:prepareEditArguments,async execute(_toolCallId,input,signal,_onUpdate,ctx){let{path:path15,edits}=validateEditInput(input),absolutePath=resolveToCwd(path15,ctx?.cwd||cwd);return withFileMutationQueue2(absolutePath,async()=>{let throwIfAborted=()=>{if(signal?.aborted)throw new Error("Operation aborted")};throwIfAborted();try{await ops.access(absolutePath)}catch(error2){throwIfAborted();let errorMessage2=error2 instanceof Error&&"code"in error2?`Error code: ${error2.code}`:String(error2);throw new Error(`Could not edit file: ${path15}. ${errorMessage2}.`)}throwIfAborted();let rawContent=(await ops.readFile(absolutePath)).toString("utf-8");throwIfAborted();let{bom,text:content}=splitBom(rawContent),originalEnding=detectLineEnding2(content),normalizedContent=normalizeToLF2(content),{baseContent,newContent}=applyEditsToNormalizedContent2(normalizedContent,edits,path15);throwIfAborted();let finalContent=bom+restoreLineEndings2(newContent,originalEnding);await ops.writeFile(absolutePath,finalContent),throwIfAborted();let diffResult=generateDiffString2(baseContent,newContent),patch=generateUnifiedPatch2(path15,baseContent,newContent);return{content:[{type:"text",text:`Successfully replaced ${edits.length} block(s) in ${path15}.`}],details:{diff:diffResult.diff,patch,firstChangedLine:diffResult.firstChangedLine}}})},renderCall(args,theme2,context){let component=getEditCallRenderComponent(context.state,context.lastComponent),previewInput=getRenderablePreviewInput(args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0;if(component.previewArgsKey!==argsKey&&(component.preview=void 0,component.previewArgsKey=argsKey,component.previewPending=!1,component.settledError=!1),context.argsComplete&&previewInput&&!component.preview&&!component.previewPending){component.previewPending=!0;let requestKey=argsKey;computeEditsDiff(previewInput.path,previewInput.edits,context.cwd).then(preview=>{component.previewArgsKey===requestKey&&(setEditPreview(component,preview,requestKey),context.invalidate())})}return buildEditCallComponent(component,args,theme2,context.cwd)},renderResult(result,_options,theme2,context){let callComponent=context.state.callComponent,previewInput=getRenderablePreviewInput(context.args),argsKey=previewInput?JSON.stringify({path:previewInput.path,edits:previewInput.edits}):void 0,typedResult=result,resultDiff=context.isError?void 0:typedResult.details?.diff,changed=!1;callComponent&&(typeof resultDiff=="string"&&(changed=setEditPreview(callComponent,{diff:resultDiff,firstChangedLine:typedResult.details?.firstChangedLine},argsKey)||changed),callComponent.settledError!==context.isError&&(callComponent.settledError=context.isError,changed=!0),changed&&buildEditCallComponent(callComponent,context.args,theme2,context.cwd));let output=formatEditResult(context.args,callComponent?.preview,typedResult,theme2,context.isError),component=context.lastComponent??new Container;return component.clear(),output&&(component.addChild(new Spacer(1)),component.addChild(new Text(output,1,0))),component}}}function createEditTool2(cwd,options){return wrapToolDefinition(createEditToolDefinition(cwd,options))}import{createInterface as createInterface2}from"node:readline";import{spawn as spawn4}from"child_process";import path9 from"path";import{spawnSync as spawnSync3}from"child_process";import{createHash as createHash6}from"crypto";import{chmodSync,createWriteStream as createWriteStream2,existsSync as existsSync9,mkdirSync as mkdirSync8,readdirSync as readdirSync9,renameSync as renameSync2,rmSync as rmSync2}from"fs";import{arch,platform}from"os";import{join as join33}from"path";import{Readable,Transform}from"stream";import{pipeline}from"stream/promises";var TOOLS_DIR=getBinDir(),NETWORK_TIMEOUT_MS=1e4,DOWNLOAD_TIMEOUT_MS=12e4,DOWNLOAD_PROGRESS_INTERVAL_MS=15e3;function isOfflineModeEnabled(){let value=process.env.AGENT_FORGE_OFFLINE;return value?value==="1"||value.toLowerCase()==="true"||value.toLowerCase()==="yes":!1}var TOOLS={fd:{name:"fd",repo:"sharkdp/fd",binaryName:"fd",systemBinaryNames:["fd","fdfind"],tagPrefix:"v",pinnedVersion:"10.5.0",digests:{"fd-v10.5.0-x86_64-apple-darwin.tar.gz":"7e31028c62c6955877735d0406807aa484c2a5e6f86235a59e26c29c301da590","fd-v10.5.0-aarch64-apple-darwin.tar.gz":"b67e1836c468e42e411984b56e52fa7abec08c2bd22c867398e7cc134aac5e12","fd-v10.5.0-x86_64-unknown-linux-musl.tar.gz":"761c72dc8e120d85b22292063be8a796e2eeb20eb3e4f38b8fa2343ccf3514a7","fd-v10.5.0-aarch64-unknown-linux-musl.tar.gz":"d76c4317f7d5dba69f8a2a15856c90c777e7f0dd4e85f0de8c76de6992c374d4","fd-v10.5.0-x86_64-pc-windows-msvc.zip":"a227701b8551c35a9931d9f6da75503cf86d88e182d71fb849a70864c5d57cd7","fd-v10.5.0-aarch64-pc-windows-msvc.zip":"a2bcddcfd259b05357a77bbc6cd671fdb30f63fd266a0e748305890a8c5ceaa6"},getAssetName:(version,plat,architecture)=>plat==="darwin"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`fd-v${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null},rg:{name:"ripgrep",repo:"BurntSushi/ripgrep",binaryName:"rg",tagPrefix:"",checksumSuffix:".sha256",getAssetName:(version,plat,architecture)=>plat==="darwin"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-apple-darwin.tar.gz`:plat==="linux"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-unknown-linux-musl.tar.gz`:plat==="win32"?`ripgrep-${version}-${architecture==="arm64"?"aarch64":"x86_64"}-pc-windows-msvc.zip`:null}};function commandExists(cmd){try{let result=spawnSync3(cmd,["--version"],{stdio:"pipe"});return result.error===void 0||result.error===null}catch{return!1}}function getToolPath(tool){let config=TOOLS[tool];if(!config)return null;let localPath=join33(TOOLS_DIR,config.binaryName+(platform()==="win32"?".exe":""));if(existsSync9(localPath))return localPath;let systemBinaryNames=config.systemBinaryNames??[config.binaryName];for(let systemBinaryName of systemBinaryNames)if(commandExists(systemBinaryName))return systemBinaryName;return null}async function getLatestVersion(repo){let response2=await fetchWithRetry(`https://github.com/${repo}/releases/latest`,{headers:{"User-Agent":`${APP_NAME}-agent-forge`},redirect:"manual"},{timeoutMs:NETWORK_TIMEOUT_MS});try{await response2.body?.cancel()}catch{}let location=response2.status>=300&&response2.status<400?response2.headers.get("location"):null;if(!location)throw new Error(`Failed to resolve latest ${repo} release: HTTP ${response2.status} without redirect`);let tag=new URL(location,"https://github.com").pathname.split("/").pop();if(!tag||!location.includes("/releases/tag/"))throw new Error(`Failed to resolve latest ${repo} release: unexpected redirect to ${location}`);return decodeURIComponent(tag).replace(/^v/,"")}var DownloadIntegrityError=class extends Error{expectedSha256;actualSha256;constructor(url,expectedSha256,actualSha256){super(`Download integrity check failed for ${url}: expected sha256 ${expectedSha256}, got ${actualSha256}`),this.name="DownloadIntegrityError",this.expectedSha256=expectedSha256,this.actualSha256=actualSha256}};async function downloadFile(url,dest,expectedSha256){let response2=await fetchWithRetry(url,void 0,{timeoutMs:DOWNLOAD_TIMEOUT_MS});if(!response2.ok)throw new Error(`Download failed with HTTP ${response2.status}: ${url}`);if(!response2.body)throw new Error("No response body");let hash=createHash6("sha256"),digestTap=new Transform({transform(chunk,_encoding,callback){hash.update(chunk),callback(null,chunk)}}),fileStream=createWriteStream2(dest);if(await pipeline(Readable.fromWeb(response2.body),digestTap,fileStream),expectedSha256===void 0)return;let actual=hash.digest("hex"),expected=expectedSha256.trim().toLowerCase();if(actual!==expected)throw rmSync2(dest,{force:!0}),new DownloadIntegrityError(url,expected,actual)}var SHA256_HEX_PATTERN=/^[0-9a-f]{64}$/;async function resolveExpectedSha256(config,downloadUrl,assetName){let digests=config.digests;if(digests){let digest=digests[assetName];if(digest===void 0)throw new Error(`No committed sha256 for ${config.name} asset ${assetName}; refresh the pin and its digests`);return digest}if(config.checksumSuffix!==void 0)return fetchReleaseSha256(`${downloadUrl}${config.checksumSuffix}`)}async function fetchReleaseSha256(checksumUrl){let response2=await fetchWithRetry(checksumUrl,void 0,{timeoutMs:NETWORK_TIMEOUT_MS});if(!response2.ok)throw new Error(`Failed to fetch release checksum: HTTP ${response2.status}: ${checksumUrl}`);let digest=(await response2.text()).trim().split(/\s+/)[0]?.toLowerCase()??"";if(!SHA256_HEX_PATTERN.test(digest))throw new Error(`Release checksum has an unexpected format: ${checksumUrl}`);return digest}function findBinaryRecursively(rootDir,binaryFileName){let stack=[rootDir];for(;stack.length>0;){let currentDir=stack.pop();if(!currentDir)continue;let entries=readdirSync9(currentDir,{withFileTypes:!0});for(let entry of entries){let fullPath=join33(currentDir,entry.name);if(entry.isFile()&&entry.name===binaryFileName)return fullPath;entry.isDirectory()&&stack.push(fullPath)}}return null}function formatSpawnFailure(result){if(result.error?.message)return result.error.message;let stderr=result.stderr?.toString().trim();if(stderr)return stderr;let stdout=result.stdout?.toString().trim();return stdout||`exit status ${result.status??"unknown"}`}function runExtractionCommand(command,args){let result=spawnSync3(command,args,{stdio:"pipe"});return!result.error&&result.status===0?null:`${command}: ${formatSpawnFailure(result)}`}function extractTarGzArchive(archivePath,extractDir,assetName){let failure2=runExtractionCommand("tar",["xzf",archivePath,"-C",extractDir]);if(failure2)throw new Error(`Failed to extract ${assetName}: ${failure2}`)}function getWindowsTarCommand(){let systemRoot=process.env.SystemRoot??process.env.WINDIR;if(systemRoot){let systemTar=join33(systemRoot,"System32","tar.exe");if(existsSync9(systemTar))return systemTar}return"tar.exe"}function extractZipArchive(archivePath,extractDir,assetName){let failures=[];if(platform()==="win32"){let tarFailure=runExtractionCommand(getWindowsTarCommand(),["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure);let powershellFailure=runExtractionCommand("powershell.exe",["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command","& { param($archive, $destination) $ErrorActionPreference = 'Stop'; Expand-Archive -LiteralPath $archive -DestinationPath $destination -Force }",archivePath,extractDir]);if(!powershellFailure)return;failures.push(powershellFailure)}else{let unzipFailure=runExtractionCommand("unzip",["-q",archivePath,"-d",extractDir]);if(!unzipFailure)return;failures.push(unzipFailure);let tarFailure=runExtractionCommand("tar",["xf",archivePath,"-C",extractDir]);if(!tarFailure)return;failures.push(tarFailure)}throw new Error(`Failed to extract ${assetName}: ${failures.join("; ")}`)}async function downloadTool(tool){let config=TOOLS[tool];if(!config)throw new Error(`Unknown tool: ${tool}`);let plat=platform(),architecture=arch(),version=config.pinnedVersion??await getLatestVersion(config.repo),assetName=config.getAssetName(version,plat,architecture);if(!assetName)throw new Error(`Unsupported platform: ${plat}/${architecture}`);mkdirSync8(TOOLS_DIR,{recursive:!0});let downloadUrl=`https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`,expectedSha256=await resolveExpectedSha256(config,downloadUrl,assetName),archivePath=join33(TOOLS_DIR,assetName),binaryExt=plat==="win32"?".exe":"",binaryPath=join33(TOOLS_DIR,config.binaryName+binaryExt);try{await downloadFile(downloadUrl,archivePath,expectedSha256)}catch(error2){throw rmSync2(archivePath,{force:!0}),error2}let extractDir=join33(TOOLS_DIR,`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2,10)}`);mkdirSync8(extractDir,{recursive:!0});try{if(assetName.endsWith(".tar.gz"))extractTarGzArchive(archivePath,extractDir,assetName);else if(assetName.endsWith(".zip"))extractZipArchive(archivePath,extractDir,assetName);else throw new Error(`Unsupported archive format: ${assetName}`);let binaryFileName=config.binaryName+binaryExt,extractedDir=join33(extractDir,assetName.replace(/\.(tar\.gz|zip)$/,"")),extractedBinary=[join33(extractedDir,binaryFileName),join33(extractDir,binaryFileName)].find(candidate=>existsSync9(candidate));if(extractedBinary||(extractedBinary=findBinaryRecursively(extractDir,binaryFileName)??void 0),extractedBinary)renameSync2(extractedBinary,binaryPath);else throw new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);plat!=="win32"&&chmodSync(binaryPath,493)}finally{rmSync2(archivePath,{force:!0}),rmSync2(extractDir,{recursive:!0,force:!0})}return binaryPath}var TERMUX_PACKAGES={fd:"fd",rg:"ripgrep"};async function ensureTool(tool,onStatus){let existingPath=getToolPath(tool);if(existingPath)return existingPath;let config=TOOLS[tool];if(!config)return;if(isOfflineModeEnabled()){onStatus?.({type:"warning",message:`${config.name} not found. Offline mode enabled, skipping download.`});return}if(platform()==="android"){let pkgName=TERMUX_PACKAGES[tool]??tool;onStatus?.({type:"warning",message:`${config.name} not found. Install with: pkg install ${pkgName}`});return}onStatus?.({type:"info",message:`${config.name} not found. Downloading from GitHub releases (slow networks can take up to ${Math.round(DOWNLOAD_TIMEOUT_MS/1e3)}s; set AGENT_FORGE_OFFLINE=1 to skip)...`});let startedAt=Date.now(),progressTicker=setInterval(()=>{onStatus?.({type:"info",message:`${config.name} still downloading... ${Math.round((Date.now()-startedAt)/1e3)}s elapsed`})},DOWNLOAD_PROGRESS_INTERVAL_MS);try{let path15=await downloadTool(tool);return onStatus?.({type:"info",message:`${config.name} installed to ${path15}`}),path15}catch(e){let messages=[];for(let current=e,depth=0;current instanceof Error&&depth<5;current=current.cause,depth++)messages.includes(current.message)||messages.push(current.message);onStatus?.({type:"warning",message:`Failed to download ${config.name}: ${messages.length>0?messages.join(": "):String(e)}`});return}finally{clearInterval(progressTicker)}}function relativizeFindResultPath(resultPath,searchPath,pathModule=path9){let hadTrailingSeparator=resultPath.endsWith(pathModule.sep)||pathModule.sep==="\\"&&resultPath.endsWith("/"),posixPath=(pathModule.isAbsolute(resultPath)?pathModule.relative(searchPath,resultPath):resultPath).split(pathModule.sep).join("/");return hadTrailingSeparator&&!posixPath.endsWith("/")?`${posixPath}/`:posixPath}var findSchema=typebox_exports.Object({pattern:typebox_exports.String({description:"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'"}),path:typebox_exports.Optional(typebox_exports.String({description:"Directory to search in (default: current directory)"})),limit:typebox_exports.Optional(typebox_exports.Number({description:"Maximum number of results (default: 1000)"}))}),findToolSystemPromptContribution={snippet:"Find files by glob pattern (respects .gitignore)",guidelines:[]},DEFAULT_LIMIT=1e3,defaultFindOperations={exists:pathExists,glob:()=>[]};function formatFindCall(args,theme2){let pattern=str(args?.pattern),rawPath=str(args?.path),path15=rawPath!==null?shortenPath(rawPath||"."):null,limit=args?.limit,invalidArg=invalidArgText(theme2),text=theme2.fg("toolTitle",theme2.bold("find"))+" "+(pattern===null?invalidArg:theme2.fg("accent",pattern||""))+theme2.fg("toolOutput",` in ${path15===null?invalidArg:path15}`);return limit!==void 0&&(text+=theme2.fg("toolOutput",` (limit ${limit})`)),text}function formatFindResult(result,options,theme2,showImages){let output=getTextOutput(result,showImages).trim(),text="";if(output){let lines=output.split(`
908
908
  `),maxLines=options.expanded?lines.length:20,displayLines=lines.slice(0,maxLines),remaining=lines.length-maxLines;text+=`
909
909
  ${displayLines.map(line=>theme2.fg("toolOutput",line)).join(`
910
910
  `)}`,remaining>0&&(text+=`${theme2.fg("muted",`
@@ -980,7 +980,7 @@ ${getProviderLoginHelp()}
980
980
 
981
981
  Then use /model to select a model.`}function formatNoApiKeyFoundMessage(provider){return`No API key found for ${provider===UNKNOWN_PROVIDER?"the selected model":provider}.
982
982
 
983
- ${getProviderLoginHelp()}`}function withoutDeletedHeaders(headers){return headers?Object.fromEntries(Object.entries(headers).filter(entry=>entry[1]!==null)):void 0}function estimateMessagesTokens(messages){let tokens=0;for(let message of messages)tokens+=estimateTokens2(message);return tokens}async function getRequiredRequestAuth(session,model){let result;try{result=await session._modelRuntime.getAuth(model)}catch(error2){let cause=error2 instanceof Error?error2.cause:void 0;throw cause instanceof Error&&cause.message==="authHeader requires a resolved API key"?new Error(formatNoApiKeyFoundMessage(model.provider)):error2}if(result&&(result.auth.apiKey||result.auth.headers))return{model:result.auth.baseUrl?{...model,baseUrl:result.auth.baseUrl}:model,apiKey:result.auth.apiKey,headers:withoutDeletedHeaders(result.auth.headers),env:result.env};throw session._modelRuntime.isUsingOAuth(model.provider)?new Error(`Authentication failed for "${model.provider}". Credentials may have expired or network is unavailable. Run '/login ${model.provider}' to re-authenticate.`):new Error(formatNoApiKeyFoundMessage(model.provider))}async function getSummarizationRequestAuth(session,model){if(session.agent.streamFunction===streamSimple)return getRequiredRequestAuth(session,model);try{let result=await session._modelRuntime.getAuth(model);return result?{model:result.auth.baseUrl?{...model,baseUrl:result.auth.baseUrl}:model,apiKey:result.auth.apiKey,headers:withoutDeletedHeaders(result.auth.headers),env:result.env}:{model}}catch{return{model}}}function summaryModelFacts(model){return{id:model.id,contextWindow:model.contextWindow,maxTokens:model.maxTokens,reasoning:model.reasoning}}function createSummaryModelInvocationV1(session,auth,retry,callbacks,options={}){return{invoke:async(input,signal)=>{let maxTokens=input.maxTokens===void 0||auth.model.maxTokens<=0?input.maxTokens:Math.min(input.maxTokens,auth.model.maxTokens),requestOptions={...maxTokens===void 0?{}:{maxTokens},signal,apiKey:auth.apiKey,headers:auth.headers,env:auth.env,cacheRetention:"none",sessionId:options.routingSessionId??uuidv7()};auth.model.reasoning&&input.thinkingLevel&&input.thinkingLevel!=="off"&&(requestOptions.reasoning=input.thinkingLevel);let context={systemPrompt:input.systemPrompt,messages:[{role:"user",content:[{type:"text",text:input.prompt}],timestamp:Date.now()}]},produce=async()=>{let streamFn=session.agent.streamFunction;return streamFn?(await streamFn(auth.model,context,requestOptions)).result():completeSimple(auth.model,context,requestOptions)},response2;try{response2=await retryAssistantCall(produce,retry,requestOptions.signal,callbacks)}catch(error2){return error2 instanceof Error&&error2.name==="AbortError"?{version:1,status:"aborted"}:{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError,message:error2 instanceof Error?error2.message:String(error2)}}}return response2.stopReason==="aborted"?{version:1,status:"aborted"}:response2.stopReason==="error"?{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.providerError,message:response2.errorMessage||"Unknown error"}}:response2.stopReason==="length"?{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.lengthCap,message:"generation hit the token cap and the summary is incomplete"}}:response2.content.some(block=>block.type==="toolCall")?{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.toolCall,message:"attempted to call a tool"}}:{version:1,status:"completed",text:contentText(response2.content),usage:response2.usage}}}}async function compactBeforeNextAssistantResponse(session,context,signal){let model=session.model,settings2=session.settingsManager.getCompactionSettings();if(!model||model.contextWindow<=0)return context;let contextTokens=estimateContextTokens2(context.messages).tokens,decision=await decideCompaction(session,{reason:"threshold",contextOverflow:!1,recoverableLength:!1,contextUsage:{contextTokens,contextWindow:model.contextWindow,reserveTokens:settings2.reserveTokens},canContinue:!1,signal:signal??session._policyDecisionAbortController?.signal});return await dispatchCompactionDecisionLifecycle(session,{reason:"threshold",compact:decision.compact,willRetry:!1,contextTokens,contextWindow:model.contextWindow,reserveTokens:settings2.reserveTokens,...decision.failureMessage===void 0?{}:{failureMessage:decision.failureMessage}}),decision.compact?(await session._runAutoCompaction("threshold",!1),{...context,messages:session.agent.state.messages.slice()}):context}function executionFacts(session,phase,operationId,revision){let inputRevision=detachedSessionSnapshot(revision??session.sessionManager.getRevision());return Object.freeze({version:1,operationId:operationId??`${phase}:${inputRevision.sessionId}:${inputRevision.sequence}:${inputRevision.leafId??"root"}`,sessionId:session.sessionId,inputRevision,phase})}async function runCompactionSummary(session,preparation,auth,customInstructions,signal,reason,execution){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let result=await runtime.summarizeCompaction(session._compactionPolicyName,{preparation,model:summaryModelFacts(auth.model),invocation:createSummaryModelInvocationV1(session,auth,summarizationRetryPolicy(session,execution.operationId,execution.inputRevision,signal),summarizationRetryCallbacks(session,{source:"compaction",reason}),{routingSessionId:session.sessionId}),customInstructions,signal,reason,thinkingLevel:session.thinkingLevel,sessionId:session.sessionId,context:{version:1,sessionId:session.sessionId,phase:"compaction"},execution});return{...result,usage:result.usage}}async function decideCompaction(session,input){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");return session._compactionPolicyName===DEFAULT_COMPACTION_POLICY_NAME&&!runtime.hasCompactionPolicy(session._compactionPolicyName)?(session._hostLogger?.warn("compaction","no compaction policy registered; skipping automatic compaction",{fields:{policyName:session._compactionPolicyName,reason:input.reason}}),{compact:!1,retry:!1}):runtime.decideCompaction(session._compactionPolicyName,{enabled:session.settingsManager.getCompactionSettings().enabled,recoveryAttempted:session._overflowRecoveryAttempted,...input,context:{version:1,sessionId:session.sessionId,phase:"compaction"},execution:input.execution??executionFacts(session,"compaction"),signal:input.signal})}async function prepareCompaction3(session,pathEntries,settings2,execution,signal){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let preparation=await runtime.prepareCompaction(session._compactionPolicyName,{entries:pathEntries,settings:settings2,context:{version:1,sessionId:session.sessionId,phase:"compaction"},execution:execution??executionFacts(session,"compaction"),signal});if(preparation===void 0)return;let value=preparation;if(!preparation||typeof preparation!="object"||typeof value.firstKeptEntryId!="string"||!Array.isArray(value.messagesToSummarize)||!Array.isArray(value.turnPrefixMessages)||typeof value.isSplitTurn!="boolean"||!Number.isFinite(value.tokensBefore)||typeof value.fileOps!="object"||typeof value.settings!="object")throw new Error(`Compaction policy returned an invalid preparation: ${session._compactionPolicyName}`);return preparation}function captureCompactionCommitBoundary(session,reason){let pathEntries=session.sessionManager.getBranch(),expectedRevision=session.sessionManager.getRevision();return{pathEntries,expectedRevision,operationId:`compaction:${reason}:${expectedRevision.sessionId}:${expectedRevision.sequence}:${expectedRevision.leafId??"root"}`}}function enqueueCompaction(session,operation){let previous=session._compactionQueue,release;session._compactionQueue=new Promise(resolve25=>{release=resolve25});let queued=previous.then(()=>{if(session._reloadInProgress)throw new Error("Session reload in progress; compaction was not started");return operation()}).finally(release);return session._activeCompactionPromise=queued,queued.then(()=>{session._activeCompactionPromise===queued&&(session._activeCompactionPromise=void 0)},()=>{session._activeCompactionPromise===queued&&(session._activeCompactionPromise=void 0)}),queued}function commitCompaction(session,input){let commit=session.sessionManager.commitCompaction({version:1,operationId:input.operationId,expectedRevision:input.expectedRevision,summary:input.summary,firstKeptEntryId:input.firstKeptEntryId,tokensBefore:input.tokensBefore,details:input.details,fromHook:!1,usage:input.usage});if(commit.status==="revision_conflict")throw new Error(`Compaction commit revision conflict: expected ${input.expectedRevision.sequence}/${input.expectedRevision.leafId??"root"}, current ${commit.currentRevision.sequence}/${commit.currentRevision.leafId??"root"}`);let entry=session.sessionManager.getEntry(commit.entryId);if(entry?.type!=="compaction"||entry.operationId!==input.operationId)throw new Error(`Compaction commit entry is unavailable: ${commit.entryId}`);return{entry,status:commit.status,revision:commit.revision}}async function dispatchCompactionCommitLifecycle(session,reason,commit){try{let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let entry=commit.entry,data={version:1,status:commit.status,entryId:entry.id,operationId:entry.operationId??"",revision:commit.revision,reason,summary:entry.summary,firstKeptEntryId:entry.firstKeptEntryId,tokensBefore:entry.tokensBefore,fromHook:entry.fromHook===!0,...entry.usage===void 0?{}:{usage:entry.usage},...entry.details===void 0?{}:{details:entry.details}},delivery=await runtime.dispatchLifecycle({type:SESSION_COMPACTION_COMMIT_EVENT_ID,version:SESSION_COMPACTION_COMMIT_EVENT_VERSION,phase:"committed",data,operationId:entry.operationId,source:"agent-session"});for(let failure2 of delivery.report.failures)session._observeLifecycleDeliveryError(failure2.error,failure2.pluginId,`${SESSION_COMPACTION_COMMIT_EVENT_ID}@${SESSION_COMPACTION_COMMIT_EVENT_VERSION}/${failure2.kind}`)}catch(error2){let report=error2.report;if(report?.failures)for(let failure2 of report.failures)session._observeLifecycleDeliveryError(failure2.error,failure2.pluginId,`${SESSION_COMPACTION_COMMIT_EVENT_ID}@${SESSION_COMPACTION_COMMIT_EVENT_VERSION}/${failure2.kind}`);else session._observeLifecycleDeliveryError(error2,"<capability-lifecycle>",`${SESSION_COMPACTION_COMMIT_EVENT_ID}@${SESSION_COMPACTION_COMMIT_EVENT_VERSION}`)}}async function decideOverflow(session,message,execution,signal){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");return runtime.decideOverflow(session._overflowPolicyName,{message,contextWindow:session.model?.contextWindow,desiredMaxOutput:session.model?.maxTokens??0,context:{version:1,sessionId:session.sessionId,phase:"overflow"},execution:execution??executionFacts(session,"overflow"),signal})}function clearManualCompactionState(session){session._compactionAbortController=void 0,session._resolveIdleWaitIfIdle()}async function compactInternal(session,customInstructions){if(await session._abortInternal(),session._reloadInProgress)return{cancelled:!0,aborted:!0};session._compactionAbortController=new AbortController,session._emit({type:"compaction_start",reason:"manual"});try{if(!session.model)throw new Error(formatNoModelSelectedMessage());let auth=await getSummarizationRequestAuth(session,session.model),{pathEntries,expectedRevision,operationId}=captureCompactionCommitBoundary(session,"manual"),settings2=session.settingsManager.getCompactionSettings(),execution=executionFacts(session,"compaction",operationId),preparation=await prepareCompaction3(session,pathEntries,settings2,execution,session._compactionAbortController.signal);if(!preparation)throw pathEntries[pathEntries.length-1]?.type==="compaction"?new Error("Already compacted"):new Error("Nothing to compact (session too small)");let{summary,firstKeptEntryId,tokensBefore,usage,details}=await runCompactionSummary(session,preparation,auth,customInstructions,session._compactionAbortController.signal,"manual",execution);if(session._compactionAbortController.signal.aborted||session._reloadInProgress)throw new SessionCancelledError("signal");let compactionCommit=commitCompaction(session,{expectedRevision,operationId,summary,firstKeptEntryId,tokensBefore,details,usage});await dispatchCompactionCommitLifecycle(session,"manual",compactionCommit);let sessionContext=session.sessionManager.buildSessionContext();await session._applyContextTransition(sessionContext.messages,"compaction");let estimatedTokensAfter=estimateMessagesTokens(session.agent.state.messages),compactionResult={summary,firstKeptEntryId,tokensBefore,estimatedTokensAfter,usage,details};return clearManualCompactionState(session),session._emit({type:"compaction_end",reason:"manual",result:compactionResult,aborted:!1,willRetry:!1}),compactionResult}catch(error2){if(error2 instanceof SessionCancelledError||error2 instanceof Error&&error2.name==="AbortError")return clearManualCompactionState(session),session._emit({type:"compaction_end",reason:"manual",result:void 0,aborted:!0,willRetry:!1}),{cancelled:!0,aborted:!0};let errorMessage2=`Compaction failed: ${error2 instanceof Error?error2.message:String(error2)}`;throw clearManualCompactionState(session),session._emit({type:"compaction_end",reason:"manual",result:void 0,aborted:!1,willRetry:!1,errorMessage:errorMessage2}),session._hostLogger?.error("compaction","compaction failed",{fields:{reason:"manual"},cause:error2}),await dispatchCompactionFailedLifecycle(session,{reason:"manual",errorMessage:errorMessage2}),error2}finally{clearManualCompactionState(session)}}async function checkCompaction(session,assistantMessage,skipAbortedCheck=!0,signal){if(signal?.aborted)return!1;let settings2=session.settingsManager.getCompactionSettings();if(skipAbortedCheck&&assistantMessage.stopReason==="aborted")return!1;let contextWindow=session.model?.contextWindow??0,sameModel=session.model!==void 0&&assistantMessage.provider===session.model.provider&&assistantMessage.model===session.model.id,compactionEntry=getLatestCompactionEntry(session.sessionManager.getBranch());if(compactionEntry!==null&&assistantMessage.timestamp<=new Date(compactionEntry.timestamp).getTime())return!1;let overflow=sameModel?await decideOverflow(session,assistantMessage,void 0,signal):{contextOverflow:!1,recoverableLength:!1},{contextOverflow,recoverableLength}=overflow;if(contextOverflow||recoverableLength){let decision2=await decideCompaction(session,{reason:"overflow",contextOverflow,recoverableLength,canContinue:assistantMessage.stopReason!=="stop",signal});if(await dispatchCompactionDecisionLifecycle(session,{reason:"overflow",compact:decision2.compact,willRetry:decision2.retry===!0,...decision2.failureMessage===void 0?{}:{failureMessage:decision2.failureMessage}}),!decision2.compact){if(decision2.failureMessage){let errorMessage2=decision2.failureMessage;session._emit({type:"compaction_end",reason:"overflow",result:void 0,aborted:!1,willRetry:!1,errorMessage:errorMessage2}),session._hostLogger?.error("compaction","compaction failed",{fields:{reason:"overflow"},cause:errorMessage2}),await dispatchCompactionFailedLifecycle(session,{reason:"overflow",errorMessage:errorMessage2})}return!1}let willRetry=decision2.retry===!0;return willRetry&&(session._overflowRecoveryAttempted=!0),await session._runAutoCompaction("overflow",willRetry)}let contextTokens,directContextTokens=assistantMessage.usage?calculateContextTokens2(assistantMessage.usage):0;if(assistantMessage.stopReason==="error"||directContextTokens===0){let messages=session.agent.state.messages,estimate=estimateContextTokens2(messages);if(estimate.lastUsageIndex!==null){let usageMsg=messages[estimate.lastUsageIndex];if(compactionEntry&&usageMsg.role==="assistant"&&usageMsg.timestamp<=new Date(compactionEntry.timestamp).getTime())return!1}contextTokens=estimate.tokens}else contextTokens=directContextTokens;let decision=await decideCompaction(session,{reason:"threshold",contextOverflow:!1,recoverableLength:!1,contextUsage:{contextTokens,contextWindow,reserveTokens:settings2.reserveTokens},canContinue:!1,branchEntries:session.sessionManager.getBranch(),keepRecentTokens:settings2.keepRecentTokens,signal});if(await dispatchCompactionDecisionLifecycle(session,{reason:"threshold",compact:decision.compact,willRetry:decision.retry===!0,contextTokens,contextWindow,reserveTokens:settings2.reserveTokens,...decision.failureMessage===void 0?{}:{failureMessage:decision.failureMessage}}),decision.relief!==void 0&&!decision.compact){session.sessionManager.appendCustomEntry(decision.relief.customType,decision.relief.data);let sessionContext=session.sessionManager.buildSessionContext();return await session._applyContextTransition(sessionContext.messages,"compaction"),session._hostLogger?.info("compaction","policy relief applied",{fields:{customType:decision.relief.customType}}),session.agent.hasQueuedMessages()}return decision.compact?session._runAutoCompaction("threshold",decision.retry===!0):!1}async function runAutoCompaction(session,reason,willRetry){return session._reloadInProgress?!1:enqueueCompaction(session,()=>runAutoCompactionInternal(session,reason,willRetry))}async function runAutoCompactionInternal(session,reason,willRetry){session._autoCompactionAbortController=new AbortController;let autoCompactionSignal=session._autoCompactionAbortController.signal;try{try{if(willRetry){let messages=session.agent.state.messages;messages.length>0&&messages[messages.length-1].role==="assistant"&&await session._applyContextTransition(messages.slice(0,-1),"overflow_recovery")}if(autoCompactionSignal.aborted||session._reloadInProgress)return!1}catch(error2){throw session._autoCompactionAbortController=void 0,error2}let settings2=session.settingsManager.getCompactionSettings(),started=!1;try{if(!session.model)return!1;let auth=await getSummarizationRequestAuth(session,session.model),{pathEntries,expectedRevision,operationId}=captureCompactionCommitBoundary(session,reason),execution=executionFacts(session,"compaction",operationId),preparation=await prepareCompaction3(session,pathEntries,settings2,execution,autoCompactionSignal);if(!preparation)return!1;session._emit({type:"compaction_start",reason}),started=!0;let{summary,firstKeptEntryId,tokensBefore,usage,details}=await runCompactionSummary(session,preparation,auth,void 0,autoCompactionSignal,reason,execution);if(autoCompactionSignal.aborted||session._reloadInProgress)return session._emit({type:"compaction_end",reason,result:void 0,aborted:!0,willRetry:!1}),!1;let compactionCommit=commitCompaction(session,{expectedRevision,operationId,summary,firstKeptEntryId,tokensBefore,details,usage});await dispatchCompactionCommitLifecycle(session,reason,compactionCommit);let sessionContext=session.sessionManager.buildSessionContext();await session._applyContextTransition(sessionContext.messages,"compaction");let estimatedTokensAfter=estimateMessagesTokens(session.agent.state.messages),result={summary,firstKeptEntryId,tokensBefore,estimatedTokensAfter,usage,details};if(session._emit({type:"compaction_end",reason,result,aborted:!1,willRetry}),willRetry){let messages=session.agent.state.messages,lastMsg=messages[messages.length-1];return lastMsg?.role==="assistant"&&(lastMsg.stopReason==="error"||lastMsg.stopReason==="length")&&await session._applyContextTransition(messages.slice(0,-1),"overflow_recovery"),!0}return session.agent.hasQueuedMessages()}catch(error2){let errorMessage2=error2 instanceof Error?error2.message:"compaction failed";if(started){let formattedErrorMessage=reason==="overflow"?`Context overflow recovery failed: ${errorMessage2}`:`Auto-compaction failed: ${errorMessage2}`;session._emit({type:"compaction_end",reason,result:void 0,aborted:!1,willRetry:!1,errorMessage:formattedErrorMessage}),session._hostLogger?.error("compaction","compaction failed",{fields:{reason},cause:error2}),await dispatchCompactionFailedLifecycle(session,{reason,errorMessage:formattedErrorMessage})}return!1}}finally{session._autoCompactionAbortController=void 0,session._resolveIdleWaitIfIdle()}}function summarizationRetryCallbacks(session,source){let attempts=[];return{onRetryScheduled:(attempt2,_maxAttempts,delayMs,errorMessage2)=>{attempts.push({attempt:attempt2,at:Date.now(),ok:!1,failure:errorMessage2,waitedMs:delayMs}),session._emit({type:"summarization_retry_scheduled",attempt:attempt2,maxAttempts:_maxAttempts,delayMs,errorMessage:errorMessage2})},onRetryAttemptStart:()=>{session._emit({type:"summarization_retry_attempt_start",...source})},onRetryFinished:(success,attempt2,finalError)=>{attempts.push(success?{attempt:attempt2+1,at:Date.now(),ok:!0,waitedMs:0}:{attempt:attempt2+1,at:Date.now(),ok:!1,waitedMs:0,...finalError===void 0?{}:{failure:finalError}}),session._emit({type:"summarization_retry_finished",source,attempts})}}}function summarizationRetryPolicy(session,operationId,inputRevision,signal){let settings2=session.settingsManager.getRetrySettings(),runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let execution=executionFacts(session,"retry",operationId?`${operationId}:retry`:void 0,inputRevision);return{...settings2,classify:message=>runtime.classifyRetry(session._retryPolicyName,{message,signal,context:{version:1,sessionId:session.sessionId,phase:"retry"},execution}),decide:({message,retryable,attempt:attempt2,maxAttempts,baseDelayMs})=>runtime.decideRetry(session._retryPolicyName,{retryable,enabled:settings2.enabled,attempt:attempt2,maxAttempts,baseDelayMs,errorMessage:message.errorMessage,signal,context:{version:1,sessionId:session.sessionId,phase:"retry"},execution})}}async function navigateTree(session,targetId,options={}){if(session.isStreaming)throw new Error("Wait for the current response to finish before navigating the session tree.");if(session._compactionAbortController!==void 0||session._autoCompactionAbortController!==void 0)throw new Error("Wait for the current compaction or tree navigation to finish before navigating the session tree.");let oldLeafId=session.sessionManager.getLeafId();if(targetId===oldLeafId)return{cancelled:!1};if(options.summarize&&!session.model)throw new Error("No model available for summarization");let targetEntry=session.sessionManager.getEntry(targetId);if(!targetEntry)throw new Error(`Entry ${targetId} not found`);let{entries:entriesToSummarize}=collectEntriesForBranchSummary2(session.sessionManager,oldLeafId,targetId),customInstructions=options.customInstructions,replaceInstructions=options.replaceInstructions,label=options.label;if(session._reloadInProgress)throw new Error("Session reload in progress; tree navigation is unavailable");if(session._branchSummaryAbortController)throw new Error("Branch navigation is already in progress");session._branchSummaryAbortController=new AbortController;let branchSummaryPromise=new Promise(resolve25=>{session._resolveBranchSummaryPromise=resolve25});session._branchSummaryPromise=branchSummaryPromise;try{let summaryText,summaryDetails,summaryUsage;if(options.summarize&&entriesToSummarize.length>0){let model=session.model,auth=await getSummarizationRequestAuth(session,model),branchSummarySettings=session.settingsManager.getBranchSummarySettings(),runtime=session._capabilityRuntime;if(!runtime||!runtime.hasBranchSummaryPolicy(session._branchSummaryPolicyName))throw new Error(`Branch summary policy is not registered: ${session._branchSummaryPolicyName}`);let execution=executionFacts(session,"branch_summary",`branch_summary:${session.sessionId}:${oldLeafId??"root"}:${targetId}`),result=await runtime.summarizeBranch(session._branchSummaryPolicyName,{entries:entriesToSummarize,model:summaryModelFacts(auth.model),invocation:createSummaryModelInvocationV1(session,auth,summarizationRetryPolicy(session,execution.operationId,execution.inputRevision,session._branchSummaryAbortController.signal),summarizationRetryCallbacks(session,{source:"branchSummary"})),signal:session._branchSummaryAbortController.signal,customInstructions,replaceInstructions,reserveTokens:branchSummarySettings.reserveTokens,context:{version:1,sessionId:session.sessionId,phase:"branch_summary"},execution});if(result.aborted)return{cancelled:!0,aborted:!0};if(result.error)throw new Error(result.error);summaryText=result.summary,summaryUsage=result.usage,summaryDetails={readFiles:result.readFiles||[],modifiedFiles:result.modifiedFiles||[]}}if(session._branchSummaryAbortController.signal.aborted||session._reloadInProgress)return{cancelled:!0,aborted:!0};let newLeafId,editorText;targetEntry.type==="message"&&targetEntry.message.role==="user"?(newLeafId=targetEntry.parentId,editorText=contentText(targetEntry.message.content,"")):targetEntry.type==="custom_message"?(newLeafId=targetEntry.parentId,editorText=contentText(targetEntry.content,"")):newLeafId=targetId;let summaryEntry;if(summaryText){let summaryId=session.sessionManager.branchWithSummary(newLeafId,summaryText,summaryDetails,!1,summaryUsage);summaryEntry=session.sessionManager.getEntry(summaryId),label&&session.sessionManager.appendLabelChange(summaryId,label)}else newLeafId===null?session.sessionManager.resetLeaf():session.sessionManager.branch(newLeafId);label&&!summaryText&&session.sessionManager.appendLabelChange(targetId,label);let sessionContext=session.sessionManager.buildSessionContext();return await session._applyContextTransition(sessionContext.messages,"tree"),{editorText,cancelled:!1,summaryEntry}}finally{session._branchSummaryAbortController=void 0,session._resolveIdleWaitIfIdle(),session._resolveBranchSummaryPromise?.(),session._resolveBranchSummaryPromise=void 0,session._branchSummaryPromise===branchSummaryPromise&&(session._branchSummaryPromise=void 0)}}function requireContextStrategy(session){let name=session._contextStrategyName;if(!name)throw new Error("Context strategy is not configured");let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");if(!runtime.hasContextStrategy(name))throw new Error(`Configured context strategy is not registered: ${name}`);return{runtime,name}}function requireIdleContextOperation(session,operation){if(!session.isIdle)throw new Error(`Cannot ${operation} while the session is running`)}function beginContextTransitionFence(session){session._contextEpoch+=1,session._contextTransitionAbortController.abort("context runtime replaced"),session._contextTransitionAbortController=new AbortController}function isContextTransitionCurrent(session,epoch,allowReload){return!session.isDisposed&&epoch===session._contextEpoch&&(allowReload||!session._reloadInProgress)}function assertContextTransitionCurrent(session,epoch,allowReload){if(!session._isContextTransitionCurrent(epoch,allowReload))throw new Error(session.isDisposed?"Session is disposed; context transition was cancelled":session._reloadInProgress?"Session reload in progress; context transition was cancelled":"Context transition was superseded")}function enqueueContextTransition(session,operation,options){let allowReload=options?.allowReload??!1;if(session.isDisposed)return Promise.reject(new Error("Session is disposed; context transition is unavailable"));if(session._reloadInProgress&&!allowReload)return Promise.reject(new Error("Session reload in progress; context transition is unavailable"));let epoch=session._contextEpoch,fenceSignal=session._contextTransitionAbortController.signal,signal=options?.signal?AbortSignal.any([fenceSignal,options.signal]):fenceSignal,queued=(session._activeContextTransition?.catch(()=>{})??Promise.resolve()).then(()=>(session._assertContextTransitionCurrent(epoch,allowReload),operation(epoch,signal)));return session._activeContextTransition=queued,queued.then(()=>{session._activeContextTransition===queued&&(session._activeContextTransition=void 0)},()=>{session._activeContextTransition===queued&&(session._activeContextTransition=void 0)}),queued}function copyContextMessages(value,strategyName,direction){if(!Array.isArray(value)||value.some(message=>typeof message!="object"||message===null||!("role"in message)||typeof message.role!="string"))throw new Error(direction==="result"?`Context strategy must return an AgentMessage array: ${strategyName}`:`Context transition requires an AgentMessage array: ${strategyName}`);try{return structuredClone(value)}catch(error2){throw new Error(direction==="result"?`Context strategy must return structured-cloneable AgentMessage values: ${strategyName}`:`Context transition requires structured-cloneable AgentMessage values: ${strategyName}`,{cause:error2})}}function applyContextTransition(session,messages,reason="session_replace",signal,options){return session._enqueueContextTransition(async(epoch,transitionSignal)=>{let name=session._contextStrategyName,runtime=session._capabilityRuntime;if(name){if(!runtime)throw new Error("Capability runtime is not available");if(!runtime.hasContextStrategy(name))throw new Error(`Configured context strategy is not registered: ${name}`);let replaced=await runtime.replaceContext(name,session._copyContextMessages(messages,name,"input"),{signal:transitionSignal,reason,sessionId:session.sessionId});session._assertContextTransitionCurrent(epoch,options?.allowReload??!1);let committed=session._copyContextMessages(replaced,name,"result");return session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),session.agent.state.messages=committed,session._contextRevision+=1,session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),await session._dispatchContextReplacedLifecycle(reason,name),committed}return session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),session.agent.state.messages=messages,session._contextRevision+=1,session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),await session._dispatchContextReplacedLifecycle(reason),messages},{signal,allowReload:options?.allowReload})}function restoreContextTransition(session,snapshot2,reason,options){return session._enqueueContextTransition(async(epoch,signal)=>{let{runtime,name}=session._requireContextStrategy(),restored=await runtime.restoreContext(name,snapshot2,{signal,reason,sessionId:session.sessionId});session._assertContextTransitionCurrent(epoch,options?.allowReload??!1);let committed=session._copyContextMessages(restored,name,"result");return session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),session.agent.state.messages=committed,session._contextRevision+=1,session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),await session._dispatchContextReplacedLifecycle(reason,name),committed},{allowReload:options?.allowReload})}async function snapshotContext(session){session._requireIdleContextOperation("snapshot context");let{runtime,name}=session._requireContextStrategy();return runtime.snapshotContext(name,session._copyContextMessages(session.agent.state.messages,name,"input"),{reason:"reload",sessionId:session.sessionId})}async function restoreContext(session,snapshot2){return session._requireIdleContextOperation("restore context"),session._restoreContextTransition(snapshot2,"session_replace")}async function replaceContext(session,context){session._requireIdleContextOperation("replace context");let{name}=session._requireContextStrategy();return session._applyContextTransition(session._copyContextMessages(context,name,"input"),"session_replace")}import{basename as basename7,dirname as dirname17}from"node:path";async function extendResourcesFromExtensions(session,reason){dispatchResourcesDiscoverV1Lifecycle(session,{cwd:session._cwd,reason});let contributed=await dispatchResourcesDiscoverV2Lifecycle(session,reason),{skillPaths,promptPaths,themePaths}=contributed;if(skillPaths.length===0&&promptPaths.length===0&&themePaths.length===0)return;let extensionPaths={skillPaths:session.buildExtensionResourcePaths(skillPaths),promptPaths:session.buildExtensionResourcePaths(promptPaths),themePaths:session.buildExtensionResourcePaths(themePaths)};session._resourceLoader.extendResources(extensionPaths),await session._refreshBootstrapSkills(),session._baseSystemPrompt=session._rebuildSystemPrompt(session.getActiveToolNames()),session.agent.state.systemPrompt=session._baseSystemPrompt}function buildExtensionResourcePaths(session,entries){return entries.map(entry=>{let source=session.getExtensionSourceLabel(entry.extensionPath),baseDir=entry.extensionPath.startsWith("<")?void 0:dirname17(entry.extensionPath);return{path:entry.path,metadata:{source,scope:"temporary",origin:"top-level",baseDir}}})}function getExtensionSourceLabel(extensionPath){return extensionPath.startsWith("<")?`extension:${extensionPath.replace(/[<>]/g,"")}`:`extension:${basename7(extensionPath).replace(/\.(ts|js)$/,"")}`}function collectCommandInfos(session){let templates=session.promptTemplates.map(template=>({name:template.name,description:template.description,source:"prompt",sourceInfo:template.sourceInfo})),skills=session._getAvailableSkills().map(skill=>({name:`skill:${skill.name}`,description:skill.description,source:"skill",sourceInfo:skill.sourceInfo}));return[...templates,...skills]}function wireDefaultLoop(session){let previousPrepareNextTurnWithContext=session.agent.prepareNextTurnWithContext??(session.agent.prepareNextTurn?async(_turn,signal)=>await session.agent.prepareNextTurn?.(signal):void 0);session._initialPrepareNextTurn=previousPrepareNextTurnWithContext;let previousTransform=session.agent.transformContext,transformHead=previousTransform?async(messages,signal)=>await previousTransform(messages,signal):void 0;session.agent.beforeToolCall=async({toolCall,args},signal)=>{let chain=session._capabilityRuntime?.getLoopHookChain("beforeToolCall")??[],currentArgs=args,replaced=!1;for(let link of chain){let result=await link({toolCallId:toolCall.id,toolName:toolCall.name,args:currentArgs,signal});if(result){if(result.block){let reason=typeof result.reason=="string"&&result.reason.trim()!==""?result.reason:void 0;return await dispatchToolGateBlockedLifecycle(session,toolCall.id,toolCall.name,reason),result}"args"in result&&(currentArgs=result.args,replaced=!0)}}return replaced?{args:currentArgs}:void 0},session.agent.afterToolCall=async({toolCall,args,result,isError},signal)=>{let chain=session._capabilityRuntime?.getLoopHookChain("afterToolCall")??[],current=result,override;for(let link of chain){let linkResult=await link({toolCallId:toolCall.id,toolName:toolCall.name,args,result:current,isError,signal});linkResult!==void 0&&(current=linkResult,override=linkResult)}return override},session.agent.transformContext=async(messages,signal)=>{let current=messages;if(transformHead){let transformed=await transformHead(current,signal);transformed!==void 0&&(current=transformed)}let chain=session._capabilityRuntime?.getLoopHookChain("transformContext")??[];for(let link of chain){let transformed=await link(current,signal);transformed!==void 0&&(current=transformed)}return current},session.agent.prepareNextTurnWithContext=async(turn,signal)=>{let chain=session._capabilityRuntime?.getLoopHookChain("prepareNextTurn")??[],current=turn;for(let link of chain){let revised=await link(current,signal);revised!==void 0&&(current=revised)}return current};let previousShouldStopAfterTurn=session.agent.shouldStopAfterTurn;session.agent.shouldStopAfterTurn=async(context,signal)=>{if(previousShouldStopAfterTurn&&await previousShouldStopAfterTurn(context,signal))return!0;let chain=session._capabilityRuntime?.getLoopHookChain("shouldStopAfterTurn")??[];for(let link of chain)if(await link(context,signal))return!0;return!1}}function createLoopWiring(session){return{getSessionId:()=>session.sessionId,getRevision:()=>detachedSessionSnapshot(session.sessionManager.getRevision()),getTurnCorrelationId:()=>session._turnCorrelationId,observeError:(error2,source,event)=>{session._observeLifecycleDeliveryError(error2,source,event)},getImageAutoResize:()=>session.settingsManager.getImageAutoResize(),compactBeforeNextAssistantResponse:(context,signal)=>session._compactBeforeNextAssistantResponse(context,signal),getTurnRefresh:()=>({systemPrompt:session._systemPromptOverride??session._baseSystemPrompt,tools:session.agent.state.tools.slice(),model:session.agent.state.model,thinkingLevel:session.agent.state.thinkingLevel}),getInitialPrepareNextTurn:()=>session._initialPrepareNextTurn,getContextStrategyName:()=>session._contextStrategyName}}async function runPromptLoop(session,messages){return session._loopExecutor?session._loopExecutor(session,messages):runDefaultLoop(session,messages)}async function runDefaultLoop(session,messages,drive=postAgentRun){let policyDecisionController=new AbortController,previousPolicyDecisionController=session._policyDecisionAbortController;session._policyDecisionAbortController=policyDecisionController,session._isAgentRunActive=!0,session._currentRunAborted=!1;let turnCorrelationId=`turn:${++session._turnCorrelationCounter}`;session._turnCorrelationId=turnCorrelationId;try{for(await session.agent.prompt(messages);await drive(session);)await session.agent.continue();return session._currentRunAborted?{status:"aborted",reason:session._lastAbortReason??"interrupted"}:{status:"done"}}finally{session._turnCorrelationId===turnCorrelationId&&(session._turnCorrelationId=void 0);try{session._systemPromptOverride=void 0,session._flushPendingBashMessages(),session._flushPendingCustomMessages(),await session._emitAgentSettled()}finally{session._policyDecisionAbortController===policyDecisionController&&(session._policyDecisionAbortController=previousPolicyDecisionController)}}}async function postAgentRun(session){let msg=session._lastAssistantMessage;if(session._lastAssistantMessage=void 0,!msg)return session._pendingRetryDecision=void 0,!1;let pendingDecision=session._pendingRetryDecision;session._pendingRetryDecision=void 0;let policySignal=session._policyDecisionAbortController?.signal;try{if(pendingDecision?!policySignal?.aborted&&await session._prepareRetry(msg,pendingDecision.decision):await session._isRetryableError(msg,void 0,policySignal)&&await session._prepareRetry(msg))return await decideRunLoop(session,{willRetry:!0,willCompact:!1,queuedFollowUp:session.agent.hasQueuedMessages(),hostWillContinue:!0},policySignal)}catch(error2){if(!policySignal?.aborted)throw error2}msg.stopReason==="error"&&session._retryAttempt>0&&(session._emit({type:"auto_retry_end",success:!1,attempt:session._retryAttempt,finalError:msg.errorMessage}),session._retryAttempt=0);try{if(await session._checkCompaction(msg,!0,policySignal))return await decideRunLoop(session,{willRetry:!1,willCompact:!0,queuedFollowUp:session.agent.hasQueuedMessages(),hostWillContinue:!0},policySignal)}catch(error2){if(!policySignal?.aborted)throw error2}let queuedFollowUp=session.agent.hasQueuedMessages();return decideRunLoop(session,{willRetry:!1,willCompact:!1,queuedFollowUp,hostWillContinue:queuedFollowUp},policySignal)}async function decideRunLoop(session,facts,signal){let runtime=session._capabilityRuntime;if(!runtime?.hasRunLoopStrategy(session._runLoopStrategyName))return facts.hostWillContinue;try{let decision=await runtime.decideRunLoop(session._runLoopStrategyName,{...facts,signal});return facts.hostWillContinue&&decision.continueLoop}catch(error2){if(!signal?.aborted)throw error2;return facts.hostWillContinue}}async function emitModelSelect(session,nextModel,previousModel,source){modelsAreEqual(previousModel,nextModel)||await dispatchModelSelectLifecycle(session,{provider:nextModel.provider,id:nextModel.id},source)}async function setModel(session,model,options={}){if(!await session._modelRuntime.checkAuth(model.provider))throw new Error(`No API key for ${model.provider}/${model.id}`);let previousModel=session.model,thinkingLevel=session._getThinkingLevelForModelSwitch(model);session.agent.state.model=model,session.sessionManager.appendModelChange(model.provider,model.id),options.persist&&(session.settingsManager.setDefaultModelAndProvider(model.provider,model.id),session._addPersistedDefaultToNonEmptyScope(model)),session.setThinkingLevel(thinkingLevel),await session._emitModelSelect(model,previousModel,"set")}function addPersistedDefaultToNonEmptyScope(session,model){if(session._scopedModels.length===0||session._scopedModels.some(scoped=>modelsAreEqual(scoped.model,model)))return;session._scopedModels=[...session._scopedModels,{model}];let enabledModels=session.settingsManager.getEnabledModels();if(!enabledModels?.length)return;let modelReference=`${model.provider}/${model.id}`;enabledModels.some(pattern=>pattern.toLowerCase()===modelReference.toLowerCase())||session.settingsManager.setEnabledModels([...enabledModels,modelReference])}async function cycleModel(session,direction="forward",options={}){return session._scopedModels.length>0?session._cycleScopedModel(direction,options):session._cycleAvailableModel(direction,options)}async function cycleScopedModel(session,direction,options){let availableIds=new Set(session._modelRuntime.getAvailableSnapshot().map(model=>`${model.provider}\0${model.id}`)),scopedModels=session._scopedModels.filter(scoped=>availableIds.has(`${scoped.model.provider}\0${scoped.model.id}`));if(scopedModels.length<=1)return;let currentModel=session.model,currentIndex=scopedModels.findIndex(sm=>modelsAreEqual(sm.model,currentModel));currentIndex===-1&&(currentIndex=0);let len=scopedModels.length,nextIndex=direction==="forward"?(currentIndex+1)%len:(currentIndex-1+len)%len,next=scopedModels[nextIndex],thinkingLevel=session._getThinkingLevelForModelSwitch(next.model,next.thinkingLevel);return session.agent.state.model=next.model,session.sessionManager.appendModelChange(next.model.provider,next.model.id),options.persist&&(session.settingsManager.setDefaultModelAndProvider(next.model.provider,next.model.id),session._addPersistedDefaultToNonEmptyScope(next.model)),session.setThinkingLevel(thinkingLevel),await session._emitModelSelect(next.model,currentModel,"cycle"),{model:next.model,thinkingLevel:session.thinkingLevel,isScoped:!0}}async function cycleAvailableModel(session,direction,options){let availableModels=session._modelRuntime.getAvailableSnapshot();if(availableModels.length<=1)return;let currentModel=session.model,currentIndex=availableModels.findIndex(m2=>modelsAreEqual(m2,currentModel));currentIndex===-1&&(currentIndex=0);let len=availableModels.length,nextIndex=direction==="forward"?(currentIndex+1)%len:(currentIndex-1+len)%len,nextModel=availableModels[nextIndex],thinkingLevel=session._getThinkingLevelForModelSwitch(nextModel);return session.agent.state.model=nextModel,session.sessionManager.appendModelChange(nextModel.provider,nextModel.id),options.persist&&(session.settingsManager.setDefaultModelAndProvider(nextModel.provider,nextModel.id),session._addPersistedDefaultToNonEmptyScope(nextModel)),session.setThinkingLevel(thinkingLevel),await session._emitModelSelect(nextModel,currentModel,"cycle"),{model:nextModel,thinkingLevel:session.thinkingLevel,isScoped:!1}}function getScopedModels(session){return session._scopedModels}function modelFactsView(model){return{provider:model.provider,id:model.id,contextWindow:model.contextWindow,maxTokens:model.maxTokens,reasoning:model.reasoning}}function setScopedModels(session,scopedModels){session._scopedModels=scopedModels}function getThinkingLevelForModelSwitch(session,targetModel,explicitLevel){if(explicitLevel!==void 0)return explicitLevel;if(targetModel){let perModel=session.settingsManager.getModelThinkingLevel(targetModel.provider,targetModel.id);if(perModel!==void 0)return perModel}return session.settingsManager.getDefaultThinkingLevel()??session.thinkingLevel??DEFAULT_THINKING_LEVEL}import{existsSync as existsSync10,readFileSync as readFileSync9,writeFileSync as writeFileSync7}from"fs";import{basename as basename8,join as join36}from"path";function parseColor(color){let hexMatch=color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);if(hexMatch)return{r:Number.parseInt(hexMatch[1],16),g:Number.parseInt(hexMatch[2],16),b:Number.parseInt(hexMatch[3],16)};let rgbMatch=color.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);if(rgbMatch)return{r:Number.parseInt(rgbMatch[1],10),g:Number.parseInt(rgbMatch[2],10),b:Number.parseInt(rgbMatch[3],10)}}function getLuminance(r,g2,b2){let toLinear=c2=>{let s=c2/255;return s<=.03928?s/12.92:((s+.055)/1.055)**2.4};return .2126*toLinear(r)+.7152*toLinear(g2)+.0722*toLinear(b2)}function adjustBrightness(color,factor){let parsed=parseColor(color);if(!parsed)return color;let adjust=c2=>Math.min(255,Math.max(0,Math.round(c2*factor)));return`rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`}function deriveExportColors(baseColor){let parsed=parseColor(baseColor);return parsed?getLuminance(parsed.r,parsed.g,parsed.b)>.5?{pageBg:adjustBrightness(baseColor,.96),cardBg:baseColor,infoBg:`rgb(${Math.min(255,parsed.r+10)}, ${Math.min(255,parsed.g+5)}, ${Math.max(0,parsed.b-20)})`}:{pageBg:adjustBrightness(baseColor,.7),cardBg:adjustBrightness(baseColor,.85),infoBg:`rgb(${Math.min(255,parsed.r+20)}, ${Math.min(255,parsed.g+15)}, ${parsed.b})`}:{pageBg:"rgb(24, 24, 30)",cardBg:"rgb(30, 30, 36)",infoBg:"rgb(60, 55, 40)"}}function generateThemeVars(themeName){let colors=getResolvedThemeColors(themeName),lines=[];for(let[key,value]of Object.entries(colors))lines.push(`--${key}: ${value};`);let themeExport=getThemeExportColors(themeName),userMessageBg=colors.userMessageBg||"#343541",derivedColors=deriveExportColors(userMessageBg);return lines.push(`--exportPageBg: ${themeExport.pageBg??derivedColors.pageBg};`),lines.push(`--exportCardBg: ${themeExport.cardBg??derivedColors.cardBg};`),lines.push(`--exportInfoBg: ${themeExport.infoBg??derivedColors.infoBg};`),lines.join(`
983
+ ${getProviderLoginHelp()}`}function withoutDeletedHeaders(headers){return headers?Object.fromEntries(Object.entries(headers).filter(entry=>entry[1]!==null)):void 0}function estimateMessagesTokens(messages){let tokens=0;for(let message of messages)tokens+=estimateTokens2(message);return tokens}async function getRequiredRequestAuth(session,model){let result;try{result=await session._modelRuntime.getAuth(model)}catch(error2){let cause=error2 instanceof Error?error2.cause:void 0;throw cause instanceof Error&&cause.message==="authHeader requires a resolved API key"?new Error(formatNoApiKeyFoundMessage(model.provider)):error2}if(result&&(result.auth.apiKey||result.auth.headers))return{model:result.auth.baseUrl?{...model,baseUrl:result.auth.baseUrl}:model,apiKey:result.auth.apiKey,headers:withoutDeletedHeaders(result.auth.headers),env:result.env};throw session._modelRuntime.isUsingOAuth(model.provider)?new Error(`Authentication failed for "${model.provider}". Credentials may have expired or network is unavailable. Run '/login ${model.provider}' to re-authenticate.`):new Error(formatNoApiKeyFoundMessage(model.provider))}async function getSummarizationRequestAuth(session,model){if(session.agent.streamFunction===streamSimple)return getRequiredRequestAuth(session,model);try{let result=await session._modelRuntime.getAuth(model);return result?{model:result.auth.baseUrl?{...model,baseUrl:result.auth.baseUrl}:model,apiKey:result.auth.apiKey,headers:withoutDeletedHeaders(result.auth.headers),env:result.env}:{model}}catch{return{model}}}function summaryModelFacts(model){return{id:model.id,contextWindow:model.contextWindow,maxTokens:model.maxTokens,reasoning:model.reasoning}}function createSummaryModelInvocationV1(session,auth,retry,callbacks,options={}){return{invoke:async(input,signal)=>{let maxTokens=input.maxTokens===void 0||auth.model.maxTokens<=0?input.maxTokens:Math.min(input.maxTokens,auth.model.maxTokens),requestOptions={...maxTokens===void 0?{}:{maxTokens},signal,apiKey:auth.apiKey,headers:auth.headers,env:auth.env,cacheRetention:"none",sessionId:options.routingSessionId??uuidv7()};auth.model.reasoning&&input.thinkingLevel&&input.thinkingLevel!=="off"&&(requestOptions.reasoning=input.thinkingLevel);let context={systemPrompt:input.systemPrompt,messages:[{role:"user",content:[{type:"text",text:input.prompt}],timestamp:Date.now()}]},produce=async()=>{let streamFn=session.agent.streamFunction;return streamFn?(await streamFn(auth.model,context,requestOptions)).result():completeSimple(auth.model,context,requestOptions)},response2;try{response2=await retryAssistantCall(produce,retry,requestOptions.signal,callbacks)}catch(error2){return error2 instanceof Error&&error2.name==="AbortError"?{version:1,status:"aborted"}:{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError,message:error2 instanceof Error?error2.message:String(error2)}}}return response2.stopReason==="aborted"?{version:1,status:"aborted"}:response2.stopReason==="error"?{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.providerError,message:response2.errorMessage||"Unknown error"}}:response2.stopReason==="length"?{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.lengthCap,message:"generation hit the token cap and the summary is incomplete"}}:response2.content.some(block=>block.type==="toolCall")?{version:1,status:"failed",error:{code:SUMMARY_MODEL_INVOCATION_ERROR_CODES.toolCall,message:"attempted to call a tool"}}:{version:1,status:"completed",text:contentText(response2.content),usage:response2.usage}}}}async function compactBeforeNextAssistantResponse(session,context,signal){let model=session.model,settings2=session.settingsManager.getCompactionSettings();if(!model||model.contextWindow<=0)return context;let contextTokens=estimateContextTokens2(context.messages).tokens,decision=await decideCompaction(session,{reason:"threshold",contextOverflow:!1,recoverableLength:!1,contextUsage:{contextTokens,contextWindow:model.contextWindow,reserveTokens:settings2.reserveTokens},canContinue:!1,signal:signal??session._policyDecisionAbortController?.signal});return await dispatchCompactionDecisionLifecycle(session,{reason:"threshold",compact:decision.compact,willRetry:!1,contextTokens,contextWindow:model.contextWindow,reserveTokens:settings2.reserveTokens,...decision.failureMessage===void 0?{}:{failureMessage:decision.failureMessage}}),decision.compact?(await session._runAutoCompaction("threshold",!1),{...context,messages:session.agent.state.messages.slice()}):context}function executionFacts(session,phase,operationId,revision){let inputRevision=detachedSessionSnapshot(revision??session.sessionManager.getRevision());return Object.freeze({version:1,operationId:operationId??`${phase}:${inputRevision.sessionId}:${inputRevision.sequence}:${inputRevision.leafId??"root"}`,sessionId:session.sessionId,inputRevision,phase})}async function runCompactionSummary(session,preparation,auth,customInstructions,signal,reason,execution){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let result=await runtime.summarizeCompaction(session._compactionPolicyName,{preparation,model:summaryModelFacts(auth.model),invocation:createSummaryModelInvocationV1(session,auth,summarizationRetryPolicy(session,execution.operationId,execution.inputRevision,signal),summarizationRetryCallbacks(session,{source:"compaction",reason}),{routingSessionId:session.sessionId}),customInstructions,signal,reason,thinkingLevel:session.thinkingLevel,sessionId:session.sessionId,context:{version:1,sessionId:session.sessionId,phase:"compaction"},execution});return{...result,usage:result.usage}}async function decideCompaction(session,input){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");return session._compactionPolicyName===DEFAULT_COMPACTION_POLICY_NAME&&!runtime.hasCompactionPolicy(session._compactionPolicyName)?(session._hostLogger?.warn("compaction","no compaction policy registered; skipping automatic compaction",{fields:{policyName:session._compactionPolicyName,reason:input.reason}}),{compact:!1,retry:!1}):runtime.decideCompaction(session._compactionPolicyName,{enabled:session.settingsManager.getCompactionSettings().enabled,recoveryAttempted:session._overflowRecoveryAttempted,...input,context:{version:1,sessionId:session.sessionId,phase:"compaction"},execution:input.execution??executionFacts(session,"compaction"),signal:input.signal})}async function prepareCompaction3(session,pathEntries,settings2,execution,signal){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let preparation=await runtime.prepareCompaction(session._compactionPolicyName,{entries:pathEntries,settings:settings2,context:{version:1,sessionId:session.sessionId,phase:"compaction"},execution:execution??executionFacts(session,"compaction"),signal});if(preparation===void 0)return;let value=preparation;if(!preparation||typeof preparation!="object"||typeof value.firstKeptEntryId!="string"||!Array.isArray(value.messagesToSummarize)||!Array.isArray(value.turnPrefixMessages)||typeof value.isSplitTurn!="boolean"||!Number.isFinite(value.tokensBefore)||typeof value.fileOps!="object"||typeof value.settings!="object")throw new Error(`Compaction policy returned an invalid preparation: ${session._compactionPolicyName}`);return preparation}function captureCompactionCommitBoundary(session,reason){let pathEntries=session.sessionManager.getBranch(),expectedRevision=session.sessionManager.getRevision();return{pathEntries,expectedRevision,operationId:`compaction:${reason}:${expectedRevision.sessionId}:${expectedRevision.sequence}:${expectedRevision.leafId??"root"}`}}function enqueueCompaction(session,operation){let previous=session._compactionQueue,release;session._compactionQueue=new Promise(resolve25=>{release=resolve25});let queued=previous.then(()=>{if(session._reloadInProgress)throw new Error("Session reload in progress; compaction was not started");return operation()}).finally(release);return session._activeCompactionPromise=queued,queued.then(()=>{session._activeCompactionPromise===queued&&(session._activeCompactionPromise=void 0)},()=>{session._activeCompactionPromise===queued&&(session._activeCompactionPromise=void 0)}),queued}function commitCompaction(session,input){let commit=session.sessionManager.commitCompaction({version:1,operationId:input.operationId,expectedRevision:input.expectedRevision,summary:input.summary,firstKeptEntryId:input.firstKeptEntryId,tokensBefore:input.tokensBefore,details:input.details,fromHook:!1,usage:input.usage});if(commit.status==="revision_conflict")throw new Error(`Compaction commit revision conflict: expected ${input.expectedRevision.sequence}/${input.expectedRevision.leafId??"root"}, current ${commit.currentRevision.sequence}/${commit.currentRevision.leafId??"root"}`);let entry=session.sessionManager.getEntry(commit.entryId);if(entry?.type!=="compaction"||entry.operationId!==input.operationId)throw new Error(`Compaction commit entry is unavailable: ${commit.entryId}`);return{entry,status:commit.status,revision:commit.revision}}async function dispatchCompactionCommitLifecycle(session,reason,commit){try{let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let entry=commit.entry,data={version:1,status:commit.status,entryId:entry.id,operationId:entry.operationId??"",revision:commit.revision,reason,summary:entry.summary,firstKeptEntryId:entry.firstKeptEntryId,tokensBefore:entry.tokensBefore,fromHook:entry.fromHook===!0,...entry.usage===void 0?{}:{usage:entry.usage},...entry.details===void 0?{}:{details:entry.details}},delivery=await runtime.dispatchLifecycle({type:SESSION_COMPACTION_COMMIT_EVENT_ID,version:SESSION_COMPACTION_COMMIT_EVENT_VERSION,phase:"committed",data,operationId:entry.operationId,source:"agent-session"});for(let failure2 of delivery.report.failures)session._observeLifecycleDeliveryError(failure2.error,failure2.pluginId,`${SESSION_COMPACTION_COMMIT_EVENT_ID}@${SESSION_COMPACTION_COMMIT_EVENT_VERSION}/${failure2.kind}`)}catch(error2){let report=error2.report;if(report?.failures)for(let failure2 of report.failures)session._observeLifecycleDeliveryError(failure2.error,failure2.pluginId,`${SESSION_COMPACTION_COMMIT_EVENT_ID}@${SESSION_COMPACTION_COMMIT_EVENT_VERSION}/${failure2.kind}`);else session._observeLifecycleDeliveryError(error2,"<capability-lifecycle>",`${SESSION_COMPACTION_COMMIT_EVENT_ID}@${SESSION_COMPACTION_COMMIT_EVENT_VERSION}`)}}async function decideOverflow(session,message,execution,signal){let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");return runtime.decideOverflow(session._overflowPolicyName,{message,contextWindow:session.model?.contextWindow,desiredMaxOutput:session.model?.maxTokens??0,context:{version:1,sessionId:session.sessionId,phase:"overflow"},execution:execution??executionFacts(session,"overflow"),signal})}function clearManualCompactionState(session){session._compactionAbortController=void 0,session._resolveIdleWaitIfIdle()}async function compactInternal(session,customInstructions){if(await session._abortInternal(),session._reloadInProgress)return{cancelled:!0,aborted:!0};session._compactionAbortController=new AbortController,session._emit({type:"compaction_start",reason:"manual"});try{if(!session.model)throw new Error(formatNoModelSelectedMessage());let auth=await getSummarizationRequestAuth(session,session.model),{pathEntries,expectedRevision,operationId}=captureCompactionCommitBoundary(session,"manual"),settings2=session.settingsManager.getCompactionSettings(),execution=executionFacts(session,"compaction",operationId),preparation=await prepareCompaction3(session,pathEntries,settings2,execution,session._compactionAbortController.signal);if(!preparation)throw pathEntries[pathEntries.length-1]?.type==="compaction"?new Error("Already compacted"):new Error("Nothing to compact (session too small)");let{summary,firstKeptEntryId,tokensBefore,usage,details}=await runCompactionSummary(session,preparation,auth,customInstructions,session._compactionAbortController.signal,"manual",execution);if(session._compactionAbortController.signal.aborted||session._reloadInProgress)throw new SessionCancelledError("signal");let compactionCommit=commitCompaction(session,{expectedRevision,operationId,summary,firstKeptEntryId,tokensBefore,details,usage});await dispatchCompactionCommitLifecycle(session,"manual",compactionCommit);let sessionContext=session.sessionManager.buildSessionContext();await session._applyContextTransition(sessionContext.messages,"compaction");let estimatedTokensAfter=estimateMessagesTokens(session.agent.state.messages),compactionResult={summary,firstKeptEntryId,tokensBefore,estimatedTokensAfter,usage,details};return clearManualCompactionState(session),session._emit({type:"compaction_end",reason:"manual",result:compactionResult,aborted:!1,willRetry:!1}),compactionResult}catch(error2){if(error2 instanceof SessionCancelledError||error2 instanceof Error&&error2.name==="AbortError")return clearManualCompactionState(session),session._emit({type:"compaction_end",reason:"manual",result:void 0,aborted:!0,willRetry:!1}),{cancelled:!0,aborted:!0};let errorMessage2=`Compaction failed: ${error2 instanceof Error?error2.message:String(error2)}`;throw clearManualCompactionState(session),session._emit({type:"compaction_end",reason:"manual",result:void 0,aborted:!1,willRetry:!1,errorMessage:errorMessage2}),session._hostLogger?.error("compaction","compaction failed",{fields:{reason:"manual"},cause:error2}),await dispatchCompactionFailedLifecycle(session,{reason:"manual",errorMessage:errorMessage2}),error2}finally{clearManualCompactionState(session)}}async function checkCompaction(session,assistantMessage,skipAbortedCheck=!0,signal){if(signal?.aborted)return!1;let settings2=session.settingsManager.getCompactionSettings();if(skipAbortedCheck&&assistantMessage.stopReason==="aborted")return!1;let contextWindow=session.model?.contextWindow??0,sameModel=session.model!==void 0&&assistantMessage.provider===session.model.provider&&assistantMessage.model===session.model.id,compactionEntry=getLatestCompactionEntry(session.sessionManager.getBranch());if(compactionEntry!==null&&assistantMessage.timestamp<=new Date(compactionEntry.timestamp).getTime())return!1;let overflow=sameModel?await decideOverflow(session,assistantMessage,void 0,signal):{contextOverflow:!1,recoverableLength:!1},{contextOverflow,recoverableLength}=overflow;if(contextOverflow||recoverableLength){let decision2=await decideCompaction(session,{reason:"overflow",contextOverflow,recoverableLength,canContinue:assistantMessage.stopReason!=="stop",signal});if(await dispatchCompactionDecisionLifecycle(session,{reason:"overflow",compact:decision2.compact,willRetry:decision2.retry===!0,...decision2.failureMessage===void 0?{}:{failureMessage:decision2.failureMessage}}),!decision2.compact){if(decision2.failureMessage){let errorMessage2=decision2.failureMessage;session._emit({type:"compaction_end",reason:"overflow",result:void 0,aborted:!1,willRetry:!1,errorMessage:errorMessage2}),session._hostLogger?.error("compaction","compaction failed",{fields:{reason:"overflow"},cause:errorMessage2}),await dispatchCompactionFailedLifecycle(session,{reason:"overflow",errorMessage:errorMessage2})}return!1}let willRetry=decision2.retry===!0;return willRetry&&(session._overflowRecoveryAttempted=!0),await session._runAutoCompaction("overflow",willRetry)}let contextTokens,directContextTokens=assistantMessage.usage?calculateContextTokens2(assistantMessage.usage):0;if(assistantMessage.stopReason==="error"||directContextTokens===0){let messages=session.agent.state.messages,estimate=estimateContextTokens2(messages);if(estimate.lastUsageIndex!==null){let usageMsg=messages[estimate.lastUsageIndex];if(compactionEntry&&usageMsg.role==="assistant"&&usageMsg.timestamp<=new Date(compactionEntry.timestamp).getTime())return!1}contextTokens=estimate.tokens}else contextTokens=directContextTokens;let decision=await decideCompaction(session,{reason:"threshold",contextOverflow:!1,recoverableLength:!1,contextUsage:{contextTokens,contextWindow,reserveTokens:settings2.reserveTokens},canContinue:!1,branchEntries:session.sessionManager.getBranch(),keepRecentTokens:settings2.keepRecentTokens,signal});if(await dispatchCompactionDecisionLifecycle(session,{reason:"threshold",compact:decision.compact,willRetry:decision.retry===!0,contextTokens,contextWindow,reserveTokens:settings2.reserveTokens,...decision.failureMessage===void 0?{}:{failureMessage:decision.failureMessage}}),decision.relief!==void 0&&!decision.compact){session.sessionManager.appendCustomEntry(decision.relief.customType,decision.relief.data);let sessionContext=session.sessionManager.buildSessionContext();return await session._applyContextTransition(sessionContext.messages,"compaction"),session._hostLogger?.info("compaction","policy relief applied",{fields:{customType:decision.relief.customType}}),session.agent.hasQueuedMessages()}return decision.compact?session._runAutoCompaction("threshold",decision.retry===!0):!1}async function runAutoCompaction(session,reason,willRetry){return session._reloadInProgress?!1:enqueueCompaction(session,()=>runAutoCompactionInternal(session,reason,willRetry))}async function runAutoCompactionInternal(session,reason,willRetry){session._autoCompactionAbortController=new AbortController;let autoCompactionSignal=session._autoCompactionAbortController.signal;try{try{if(willRetry){let messages=session.agent.state.messages;messages.length>0&&messages[messages.length-1].role==="assistant"&&await session._applyContextTransition(messages.slice(0,-1),"overflow_recovery")}if(autoCompactionSignal.aborted||session._reloadInProgress)return!1}catch(error2){throw session._autoCompactionAbortController=void 0,error2}let settings2=session.settingsManager.getCompactionSettings(),started=!1;try{if(!session.model)return!1;let auth=await getSummarizationRequestAuth(session,session.model),{pathEntries,expectedRevision,operationId}=captureCompactionCommitBoundary(session,reason),execution=executionFacts(session,"compaction",operationId),preparation=await prepareCompaction3(session,pathEntries,settings2,execution,autoCompactionSignal);if(!preparation)return session._emit({type:"compaction_skipped",reason,cause:"nothing_to_compact"}),!1;session._emit({type:"compaction_start",reason}),started=!0;let{summary,firstKeptEntryId,tokensBefore,usage,details}=await runCompactionSummary(session,preparation,auth,void 0,autoCompactionSignal,reason,execution);if(autoCompactionSignal.aborted||session._reloadInProgress)return session._emit({type:"compaction_end",reason,result:void 0,aborted:!0,willRetry:!1}),!1;let compactionCommit=commitCompaction(session,{expectedRevision,operationId,summary,firstKeptEntryId,tokensBefore,details,usage});await dispatchCompactionCommitLifecycle(session,reason,compactionCommit);let sessionContext=session.sessionManager.buildSessionContext();await session._applyContextTransition(sessionContext.messages,"compaction");let estimatedTokensAfter=estimateMessagesTokens(session.agent.state.messages),result={summary,firstKeptEntryId,tokensBefore,estimatedTokensAfter,usage,details};if(session._emit({type:"compaction_end",reason,result,aborted:!1,willRetry}),willRetry){let messages=session.agent.state.messages,lastMsg=messages[messages.length-1];return lastMsg?.role==="assistant"&&(lastMsg.stopReason==="error"||lastMsg.stopReason==="length")&&await session._applyContextTransition(messages.slice(0,-1),"overflow_recovery"),!0}return session.agent.hasQueuedMessages()}catch(error2){let errorMessage2=error2 instanceof Error?error2.message:"compaction failed";if(started){let formattedErrorMessage=reason==="overflow"?`Context overflow recovery failed: ${errorMessage2}`:`Auto-compaction failed: ${errorMessage2}`;session._emit({type:"compaction_end",reason,result:void 0,aborted:!1,willRetry:!1,errorMessage:formattedErrorMessage}),session._hostLogger?.error("compaction","compaction failed",{fields:{reason},cause:error2}),await dispatchCompactionFailedLifecycle(session,{reason,errorMessage:formattedErrorMessage})}return!1}}finally{session._autoCompactionAbortController=void 0,session._resolveIdleWaitIfIdle()}}function summarizationRetryCallbacks(session,source){let attempts=[];return{onRetryScheduled:(attempt2,_maxAttempts,delayMs,errorMessage2)=>{attempts.push({attempt:attempt2,at:Date.now(),ok:!1,failure:errorMessage2,waitedMs:delayMs}),session._emit({type:"summarization_retry_scheduled",attempt:attempt2,maxAttempts:_maxAttempts,delayMs,errorMessage:errorMessage2})},onRetryAttemptStart:()=>{session._emit({type:"summarization_retry_attempt_start",...source})},onRetryFinished:(success,attempt2,finalError)=>{attempts.push(success?{attempt:attempt2+1,at:Date.now(),ok:!0,waitedMs:0}:{attempt:attempt2+1,at:Date.now(),ok:!1,waitedMs:0,...finalError===void 0?{}:{failure:finalError}}),session._emit({type:"summarization_retry_finished",source,attempts})}}}function summarizationRetryPolicy(session,operationId,inputRevision,signal){let settings2=session.settingsManager.getRetrySettings(),runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");let execution=executionFacts(session,"retry",operationId?`${operationId}:retry`:void 0,inputRevision);return{...settings2,classify:message=>runtime.classifyRetry(session._retryPolicyName,{message,signal,context:{version:1,sessionId:session.sessionId,phase:"retry"},execution}),decide:({message,retryable,attempt:attempt2,maxAttempts,baseDelayMs})=>runtime.decideRetry(session._retryPolicyName,{retryable,enabled:settings2.enabled,attempt:attempt2,maxAttempts,baseDelayMs,errorMessage:message.errorMessage,signal,context:{version:1,sessionId:session.sessionId,phase:"retry"},execution})}}async function navigateTree(session,targetId,options={}){if(session.isStreaming)throw new Error("Wait for the current response to finish before navigating the session tree.");if(session._compactionAbortController!==void 0||session._autoCompactionAbortController!==void 0)throw new Error("Wait for the current compaction or tree navigation to finish before navigating the session tree.");let oldLeafId=session.sessionManager.getLeafId();if(targetId===oldLeafId)return{cancelled:!1};if(options.summarize&&!session.model)throw new Error("No model available for summarization");let targetEntry=session.sessionManager.getEntry(targetId);if(!targetEntry)throw new Error(`Entry ${targetId} not found`);let{entries:entriesToSummarize}=collectEntriesForBranchSummary2(session.sessionManager,oldLeafId,targetId),customInstructions=options.customInstructions,replaceInstructions=options.replaceInstructions,label=options.label;if(session._reloadInProgress)throw new Error("Session reload in progress; tree navigation is unavailable");if(session._branchSummaryAbortController)throw new Error("Branch navigation is already in progress");session._branchSummaryAbortController=new AbortController;let branchSummaryPromise=new Promise(resolve25=>{session._resolveBranchSummaryPromise=resolve25});session._branchSummaryPromise=branchSummaryPromise;try{let summaryText,summaryDetails,summaryUsage;if(options.summarize&&entriesToSummarize.length>0){let model=session.model,auth=await getSummarizationRequestAuth(session,model),branchSummarySettings=session.settingsManager.getBranchSummarySettings(),runtime=session._capabilityRuntime;if(!runtime||!runtime.hasBranchSummaryPolicy(session._branchSummaryPolicyName))throw new Error(`Branch summary policy is not registered: ${session._branchSummaryPolicyName}`);let execution=executionFacts(session,"branch_summary",`branch_summary:${session.sessionId}:${oldLeafId??"root"}:${targetId}`),result=await runtime.summarizeBranch(session._branchSummaryPolicyName,{entries:entriesToSummarize,model:summaryModelFacts(auth.model),invocation:createSummaryModelInvocationV1(session,auth,summarizationRetryPolicy(session,execution.operationId,execution.inputRevision,session._branchSummaryAbortController.signal),summarizationRetryCallbacks(session,{source:"branchSummary"})),signal:session._branchSummaryAbortController.signal,customInstructions,replaceInstructions,reserveTokens:branchSummarySettings.reserveTokens,context:{version:1,sessionId:session.sessionId,phase:"branch_summary"},execution});if(result.aborted)return{cancelled:!0,aborted:!0};if(result.error)throw new Error(result.error);summaryText=result.summary,summaryUsage=result.usage,summaryDetails={readFiles:result.readFiles||[],modifiedFiles:result.modifiedFiles||[]}}if(session._branchSummaryAbortController.signal.aborted||session._reloadInProgress)return{cancelled:!0,aborted:!0};let newLeafId,editorText;targetEntry.type==="message"&&targetEntry.message.role==="user"?(newLeafId=targetEntry.parentId,editorText=contentText(targetEntry.message.content,"")):targetEntry.type==="custom_message"?(newLeafId=targetEntry.parentId,editorText=contentText(targetEntry.content,"")):newLeafId=targetId;let summaryEntry;if(summaryText){let summaryId=session.sessionManager.branchWithSummary(newLeafId,summaryText,summaryDetails,!1,summaryUsage);summaryEntry=session.sessionManager.getEntry(summaryId),label&&session.sessionManager.appendLabelChange(summaryId,label)}else newLeafId===null?session.sessionManager.resetLeaf():session.sessionManager.branch(newLeafId);label&&!summaryText&&session.sessionManager.appendLabelChange(targetId,label);let sessionContext=session.sessionManager.buildSessionContext();return await session._applyContextTransition(sessionContext.messages,"tree"),{editorText,cancelled:!1,summaryEntry}}finally{session._branchSummaryAbortController=void 0,session._resolveIdleWaitIfIdle(),session._resolveBranchSummaryPromise?.(),session._resolveBranchSummaryPromise=void 0,session._branchSummaryPromise===branchSummaryPromise&&(session._branchSummaryPromise=void 0)}}function requireContextStrategy(session){let name=session._contextStrategyName;if(!name)throw new Error("Context strategy is not configured");let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");if(!runtime.hasContextStrategy(name))throw new Error(`Configured context strategy is not registered: ${name}`);return{runtime,name}}function requireIdleContextOperation(session,operation){if(!session.isIdle)throw new Error(`Cannot ${operation} while the session is running`)}function beginContextTransitionFence(session){session._contextEpoch+=1,session._contextTransitionAbortController.abort("context runtime replaced"),session._contextTransitionAbortController=new AbortController}function isContextTransitionCurrent(session,epoch,allowReload){return!session.isDisposed&&epoch===session._contextEpoch&&(allowReload||!session._reloadInProgress)}function assertContextTransitionCurrent(session,epoch,allowReload){if(!session._isContextTransitionCurrent(epoch,allowReload))throw new Error(session.isDisposed?"Session is disposed; context transition was cancelled":session._reloadInProgress?"Session reload in progress; context transition was cancelled":"Context transition was superseded")}function enqueueContextTransition(session,operation,options){let allowReload=options?.allowReload??!1;if(session.isDisposed)return Promise.reject(new Error("Session is disposed; context transition is unavailable"));if(session._reloadInProgress&&!allowReload)return Promise.reject(new Error("Session reload in progress; context transition is unavailable"));let epoch=session._contextEpoch,fenceSignal=session._contextTransitionAbortController.signal,signal=options?.signal?AbortSignal.any([fenceSignal,options.signal]):fenceSignal,queued=(session._activeContextTransition?.catch(()=>{})??Promise.resolve()).then(()=>(session._assertContextTransitionCurrent(epoch,allowReload),operation(epoch,signal)));return session._activeContextTransition=queued,queued.then(()=>{session._activeContextTransition===queued&&(session._activeContextTransition=void 0)},()=>{session._activeContextTransition===queued&&(session._activeContextTransition=void 0)}),queued}function copyContextMessages(value,strategyName,direction){if(!Array.isArray(value)||value.some(message=>typeof message!="object"||message===null||!("role"in message)||typeof message.role!="string"))throw new Error(direction==="result"?`Context strategy must return an AgentMessage array: ${strategyName}`:`Context transition requires an AgentMessage array: ${strategyName}`);try{return structuredClone(value)}catch(error2){throw new Error(direction==="result"?`Context strategy must return structured-cloneable AgentMessage values: ${strategyName}`:`Context transition requires structured-cloneable AgentMessage values: ${strategyName}`,{cause:error2})}}function applyContextTransition(session,messages,reason="session_replace",signal,options){return session._enqueueContextTransition(async(epoch,transitionSignal)=>{let name=session._contextStrategyName,runtime=session._capabilityRuntime;if(name){if(!runtime)throw new Error("Capability runtime is not available");if(!runtime.hasContextStrategy(name))throw new Error(`Configured context strategy is not registered: ${name}`);let replaced=await runtime.replaceContext(name,session._copyContextMessages(messages,name,"input"),{signal:transitionSignal,reason,sessionId:session.sessionId});session._assertContextTransitionCurrent(epoch,options?.allowReload??!1);let committed=session._copyContextMessages(replaced,name,"result");return session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),session.agent.state.messages=committed,session._contextRevision+=1,session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),await session._dispatchContextReplacedLifecycle(reason,name),committed}return session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),session.agent.state.messages=messages,session._contextRevision+=1,session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),await session._dispatchContextReplacedLifecycle(reason),messages},{signal,allowReload:options?.allowReload})}function restoreContextTransition(session,snapshot2,reason,options){return session._enqueueContextTransition(async(epoch,signal)=>{let{runtime,name}=session._requireContextStrategy(),restored=await runtime.restoreContext(name,snapshot2,{signal,reason,sessionId:session.sessionId});session._assertContextTransitionCurrent(epoch,options?.allowReload??!1);let committed=session._copyContextMessages(restored,name,"result");return session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),session.agent.state.messages=committed,session._contextRevision+=1,session._assertContextTransitionCurrent(epoch,options?.allowReload??!1),await session._dispatchContextReplacedLifecycle(reason,name),committed},{allowReload:options?.allowReload})}async function snapshotContext(session){session._requireIdleContextOperation("snapshot context");let{runtime,name}=session._requireContextStrategy();return runtime.snapshotContext(name,session._copyContextMessages(session.agent.state.messages,name,"input"),{reason:"reload",sessionId:session.sessionId})}async function restoreContext(session,snapshot2){return session._requireIdleContextOperation("restore context"),session._restoreContextTransition(snapshot2,"session_replace")}async function replaceContext(session,context){session._requireIdleContextOperation("replace context");let{name}=session._requireContextStrategy();return session._applyContextTransition(session._copyContextMessages(context,name,"input"),"session_replace")}import{basename as basename7,dirname as dirname17}from"node:path";async function extendResourcesFromExtensions(session,reason){dispatchResourcesDiscoverV1Lifecycle(session,{cwd:session._cwd,reason});let contributed=await dispatchResourcesDiscoverV2Lifecycle(session,reason),{skillPaths,promptPaths,themePaths}=contributed;if(skillPaths.length===0&&promptPaths.length===0&&themePaths.length===0)return;let extensionPaths={skillPaths:session.buildExtensionResourcePaths(skillPaths),promptPaths:session.buildExtensionResourcePaths(promptPaths),themePaths:session.buildExtensionResourcePaths(themePaths)};session._resourceLoader.extendResources(extensionPaths),await session._refreshBootstrapSkills(),session._baseSystemPrompt=session._rebuildSystemPrompt(session.getActiveToolNames()),session.agent.state.systemPrompt=session._baseSystemPrompt}function buildExtensionResourcePaths(session,entries){return entries.map(entry=>{let source=session.getExtensionSourceLabel(entry.extensionPath),baseDir=entry.extensionPath.startsWith("<")?void 0:dirname17(entry.extensionPath);return{path:entry.path,metadata:{source,scope:"temporary",origin:"top-level",baseDir}}})}function getExtensionSourceLabel(extensionPath){return extensionPath.startsWith("<")?`extension:${extensionPath.replace(/[<>]/g,"")}`:`extension:${basename7(extensionPath).replace(/\.(ts|js)$/,"")}`}function collectCommandInfos(session){let templates=session.promptTemplates.map(template=>({name:template.name,description:template.description,source:"prompt",sourceInfo:template.sourceInfo})),skills=session._getAvailableSkills().map(skill=>({name:`skill:${skill.name}`,description:skill.description,source:"skill",sourceInfo:skill.sourceInfo}));return[...templates,...skills]}function wireDefaultLoop(session){let previousPrepareNextTurnWithContext=session.agent.prepareNextTurnWithContext??(session.agent.prepareNextTurn?async(_turn,signal)=>await session.agent.prepareNextTurn?.(signal):void 0);session._initialPrepareNextTurn=previousPrepareNextTurnWithContext;let previousTransform=session.agent.transformContext,transformHead=previousTransform?async(messages,signal)=>await previousTransform(messages,signal):void 0;session.agent.beforeToolCall=async({toolCall,args},signal)=>{let chain=session._capabilityRuntime?.getLoopHookChain("beforeToolCall")??[],currentArgs=args,replaced=!1;for(let link of chain){let result=await link({toolCallId:toolCall.id,toolName:toolCall.name,args:currentArgs,signal});if(result){if(result.block){let reason=typeof result.reason=="string"&&result.reason.trim()!==""?result.reason:void 0;return await dispatchToolGateBlockedLifecycle(session,toolCall.id,toolCall.name,reason),result}"args"in result&&(currentArgs=result.args,replaced=!0)}}return replaced?{args:currentArgs}:void 0},session.agent.afterToolCall=async({toolCall,args,result,isError},signal)=>{let chain=session._capabilityRuntime?.getLoopHookChain("afterToolCall")??[],current=result,override;for(let link of chain){let linkResult=await link({toolCallId:toolCall.id,toolName:toolCall.name,args,result:current,isError,signal});linkResult!==void 0&&(current=linkResult,override=linkResult)}return override},session.agent.transformContext=async(messages,signal)=>{let current=messages;if(transformHead){let transformed=await transformHead(current,signal);transformed!==void 0&&(current=transformed)}let chain=session._capabilityRuntime?.getLoopHookChain("transformContext")??[];for(let link of chain){let transformed=await link(current,signal);transformed!==void 0&&(current=transformed)}return current},session.agent.prepareNextTurnWithContext=async(turn,signal)=>{let chain=session._capabilityRuntime?.getLoopHookChain("prepareNextTurn")??[],current=turn;for(let link of chain){let revised=await link(current,signal);revised!==void 0&&(current=revised)}return current};let previousShouldStopAfterTurn=session.agent.shouldStopAfterTurn;session.agent.shouldStopAfterTurn=async(context,signal)=>{if(previousShouldStopAfterTurn&&await previousShouldStopAfterTurn(context,signal))return!0;let chain=session._capabilityRuntime?.getLoopHookChain("shouldStopAfterTurn")??[];for(let link of chain)if(await link(context,signal))return!0;return!1}}function createLoopWiring(session){return{getSessionId:()=>session.sessionId,getRevision:()=>detachedSessionSnapshot(session.sessionManager.getRevision()),getTurnCorrelationId:()=>session._turnCorrelationId,observeError:(error2,source,event)=>{session._observeLifecycleDeliveryError(error2,source,event)},getImageAutoResize:()=>session.settingsManager.getImageAutoResize(),compactBeforeNextAssistantResponse:(context,signal)=>session._compactBeforeNextAssistantResponse(context,signal),getTurnRefresh:()=>({systemPrompt:session._systemPromptOverride??session._baseSystemPrompt,tools:session.agent.state.tools.slice(),model:session.agent.state.model,thinkingLevel:session.agent.state.thinkingLevel}),getInitialPrepareNextTurn:()=>session._initialPrepareNextTurn,getContextStrategyName:()=>session._contextStrategyName}}async function runPromptLoop(session,messages){return session._loopExecutor?session._loopExecutor(session,messages):runDefaultLoop(session,messages)}async function runDefaultLoop(session,messages,drive=postAgentRun){let policyDecisionController=new AbortController,previousPolicyDecisionController=session._policyDecisionAbortController;session._policyDecisionAbortController=policyDecisionController,session._isAgentRunActive=!0,session._currentRunAborted=!1;let turnCorrelationId=`turn:${++session._turnCorrelationCounter}`;session._turnCorrelationId=turnCorrelationId;try{for(await session.agent.prompt(messages);await drive(session);)await session.agent.continue();return session._currentRunAborted?{status:"aborted",reason:session._lastAbortReason??"interrupted"}:{status:"done"}}finally{session._turnCorrelationId===turnCorrelationId&&(session._turnCorrelationId=void 0);try{session._systemPromptOverride=void 0,session._flushPendingBashMessages(),session._flushPendingCustomMessages(),await session._emitAgentSettled()}finally{session._policyDecisionAbortController===policyDecisionController&&(session._policyDecisionAbortController=previousPolicyDecisionController)}}}async function postAgentRun(session){let msg=session._lastAssistantMessage;if(session._lastAssistantMessage=void 0,!msg)return session._pendingRetryDecision=void 0,!1;let pendingDecision=session._pendingRetryDecision;session._pendingRetryDecision=void 0;let policySignal=session._policyDecisionAbortController?.signal;try{if(pendingDecision?!policySignal?.aborted&&await session._prepareRetry(msg,pendingDecision.decision):await session._isRetryableError(msg,void 0,policySignal)&&await session._prepareRetry(msg))return await decideRunLoop(session,{willRetry:!0,willCompact:!1,queuedFollowUp:session.agent.hasQueuedMessages(),hostWillContinue:!0},policySignal)}catch(error2){if(!policySignal?.aborted)throw error2}msg.stopReason==="error"&&session._retryAttempt>0&&(session._emit({type:"auto_retry_end",success:!1,attempt:session._retryAttempt,finalError:msg.errorMessage}),session._retryAttempt=0);try{if(await session._checkCompaction(msg,!0,policySignal))return await decideRunLoop(session,{willRetry:!1,willCompact:!0,queuedFollowUp:session.agent.hasQueuedMessages(),hostWillContinue:!0},policySignal)}catch(error2){if(!policySignal?.aborted)throw error2}let queuedFollowUp=session.agent.hasQueuedMessages();return decideRunLoop(session,{willRetry:!1,willCompact:!1,queuedFollowUp,hostWillContinue:queuedFollowUp},policySignal)}async function decideRunLoop(session,facts,signal){let runtime=session._capabilityRuntime;if(!runtime?.hasRunLoopStrategy(session._runLoopStrategyName))return facts.hostWillContinue;try{let decision=await runtime.decideRunLoop(session._runLoopStrategyName,{...facts,signal});return facts.hostWillContinue&&decision.continueLoop}catch(error2){if(!signal?.aborted)throw error2;return facts.hostWillContinue}}async function emitModelSelect(session,nextModel,previousModel,source){modelsAreEqual(previousModel,nextModel)||await dispatchModelSelectLifecycle(session,{provider:nextModel.provider,id:nextModel.id},source)}async function setModel(session,model,options={}){if(!await session._modelRuntime.checkAuth(model.provider))throw new Error(`No API key for ${model.provider}/${model.id}`);let previousModel=session.model,thinkingLevel=session._getThinkingLevelForModelSwitch(model);session.agent.state.model=model,session.sessionManager.appendModelChange(model.provider,model.id),options.persist&&(session.settingsManager.setDefaultModelAndProvider(model.provider,model.id),session._addPersistedDefaultToNonEmptyScope(model)),session.setThinkingLevel(thinkingLevel),await session._emitModelSelect(model,previousModel,"set")}function addPersistedDefaultToNonEmptyScope(session,model){if(session._scopedModels.length===0||session._scopedModels.some(scoped=>modelsAreEqual(scoped.model,model)))return;session._scopedModels=[...session._scopedModels,{model}];let enabledModels=session.settingsManager.getEnabledModels();if(!enabledModels?.length)return;let modelReference=`${model.provider}/${model.id}`;enabledModels.some(pattern=>pattern.toLowerCase()===modelReference.toLowerCase())||session.settingsManager.setEnabledModels([...enabledModels,modelReference])}async function cycleModel(session,direction="forward",options={}){return session._scopedModels.length>0?session._cycleScopedModel(direction,options):session._cycleAvailableModel(direction,options)}async function cycleScopedModel(session,direction,options){let availableIds=new Set(session._modelRuntime.getAvailableSnapshot().map(model=>`${model.provider}\0${model.id}`)),scopedModels=session._scopedModels.filter(scoped=>availableIds.has(`${scoped.model.provider}\0${scoped.model.id}`));if(scopedModels.length<=1)return;let currentModel=session.model,currentIndex=scopedModels.findIndex(sm=>modelsAreEqual(sm.model,currentModel));currentIndex===-1&&(currentIndex=0);let len=scopedModels.length,nextIndex=direction==="forward"?(currentIndex+1)%len:(currentIndex-1+len)%len,next=scopedModels[nextIndex],thinkingLevel=session._getThinkingLevelForModelSwitch(next.model,next.thinkingLevel);return session.agent.state.model=next.model,session.sessionManager.appendModelChange(next.model.provider,next.model.id),options.persist&&(session.settingsManager.setDefaultModelAndProvider(next.model.provider,next.model.id),session._addPersistedDefaultToNonEmptyScope(next.model)),session.setThinkingLevel(thinkingLevel),await session._emitModelSelect(next.model,currentModel,"cycle"),{model:next.model,thinkingLevel:session.thinkingLevel,isScoped:!0}}async function cycleAvailableModel(session,direction,options){let availableModels=session._modelRuntime.getAvailableSnapshot();if(availableModels.length<=1)return;let currentModel=session.model,currentIndex=availableModels.findIndex(m2=>modelsAreEqual(m2,currentModel));currentIndex===-1&&(currentIndex=0);let len=availableModels.length,nextIndex=direction==="forward"?(currentIndex+1)%len:(currentIndex-1+len)%len,nextModel=availableModels[nextIndex],thinkingLevel=session._getThinkingLevelForModelSwitch(nextModel);return session.agent.state.model=nextModel,session.sessionManager.appendModelChange(nextModel.provider,nextModel.id),options.persist&&(session.settingsManager.setDefaultModelAndProvider(nextModel.provider,nextModel.id),session._addPersistedDefaultToNonEmptyScope(nextModel)),session.setThinkingLevel(thinkingLevel),await session._emitModelSelect(nextModel,currentModel,"cycle"),{model:nextModel,thinkingLevel:session.thinkingLevel,isScoped:!1}}function getScopedModels(session){return session._scopedModels}function modelFactsView(model){return{provider:model.provider,id:model.id,contextWindow:model.contextWindow,maxTokens:model.maxTokens,reasoning:model.reasoning}}function setScopedModels(session,scopedModels){session._scopedModels=scopedModels}function getThinkingLevelForModelSwitch(session,targetModel,explicitLevel){if(explicitLevel!==void 0)return explicitLevel;if(targetModel){let perModel=session.settingsManager.getModelThinkingLevel(targetModel.provider,targetModel.id);if(perModel!==void 0)return perModel}return session.settingsManager.getDefaultThinkingLevel()??session.thinkingLevel??DEFAULT_THINKING_LEVEL}import{existsSync as existsSync10,readFileSync as readFileSync9,writeFileSync as writeFileSync7}from"fs";import{basename as basename8,join as join36}from"path";function parseColor(color){let hexMatch=color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);if(hexMatch)return{r:Number.parseInt(hexMatch[1],16),g:Number.parseInt(hexMatch[2],16),b:Number.parseInt(hexMatch[3],16)};let rgbMatch=color.match(/^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);if(rgbMatch)return{r:Number.parseInt(rgbMatch[1],10),g:Number.parseInt(rgbMatch[2],10),b:Number.parseInt(rgbMatch[3],10)}}function getLuminance(r,g2,b2){let toLinear=c2=>{let s=c2/255;return s<=.03928?s/12.92:((s+.055)/1.055)**2.4};return .2126*toLinear(r)+.7152*toLinear(g2)+.0722*toLinear(b2)}function adjustBrightness(color,factor){let parsed=parseColor(color);if(!parsed)return color;let adjust=c2=>Math.min(255,Math.max(0,Math.round(c2*factor)));return`rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`}function deriveExportColors(baseColor){let parsed=parseColor(baseColor);return parsed?getLuminance(parsed.r,parsed.g,parsed.b)>.5?{pageBg:adjustBrightness(baseColor,.96),cardBg:baseColor,infoBg:`rgb(${Math.min(255,parsed.r+10)}, ${Math.min(255,parsed.g+5)}, ${Math.max(0,parsed.b-20)})`}:{pageBg:adjustBrightness(baseColor,.7),cardBg:adjustBrightness(baseColor,.85),infoBg:`rgb(${Math.min(255,parsed.r+20)}, ${Math.min(255,parsed.g+15)}, ${parsed.b})`}:{pageBg:"rgb(24, 24, 30)",cardBg:"rgb(30, 30, 36)",infoBg:"rgb(60, 55, 40)"}}function generateThemeVars(themeName){let colors=getResolvedThemeColors(themeName),lines=[];for(let[key,value]of Object.entries(colors))lines.push(`--${key}: ${value};`);let themeExport=getThemeExportColors(themeName),userMessageBg=colors.userMessageBg||"#343541",derivedColors=deriveExportColors(userMessageBg);return lines.push(`--exportPageBg: ${themeExport.pageBg??derivedColors.pageBg};`),lines.push(`--exportCardBg: ${themeExport.cardBg??derivedColors.cardBg};`),lines.push(`--exportInfoBg: ${themeExport.infoBg??derivedColors.infoBg};`),lines.join(`
984
984
  `)}function generateHtml(sessionData,themeName){let templateDir=getExportTemplateDir(),template=readFileSync9(join36(templateDir,"template.html"),"utf-8"),templateCss=readFileSync9(join36(templateDir,"template.css"),"utf-8"),templateJs=readFileSync9(join36(templateDir,"template.js"),"utf-8"),markedJs=readFileSync9(join36(templateDir,"vendor","marked.min.js"),"utf-8"),hljsJs=readFileSync9(join36(templateDir,"vendor","highlight.min.js"),"utf-8"),themeVars=generateThemeVars(themeName),colors=getResolvedThemeColors(themeName),themeExport=getThemeExportColors(themeName),derivedExportColors=deriveExportColors(colors.userMessageBg||"#343541"),bodyBg=themeExport.pageBg??derivedExportColors.pageBg,containerBg=themeExport.cardBg??derivedExportColors.cardBg,infoBg=themeExport.infoBg??derivedExportColors.infoBg,sessionDataBase64=Buffer.from(JSON.stringify(sessionData)).toString("base64"),css=templateCss.replace("{{THEME_VARS}}",themeVars).replace("{{BODY_BG}}",bodyBg).replace("{{CONTAINER_BG}}",containerBg).replace("{{INFO_BG}}",infoBg);return template.replace("{{CSS}}",css).replace("{{JS}}",templateJs).replace("{{SESSION_DATA}}",sessionDataBase64).replace("{{MARKED_JS}}",markedJs).replace("{{HIGHLIGHT_JS}}",hljsJs)}var TEMPLATE_RENDERED_TOOLS=new Set(["bash","read","write","edit","ls"]);function preRenderCustomTools(entries,toolRenderer){let renderedTools={};for(let entry of entries){if(entry.type!=="message")continue;let msg=entry.message;if(msg.role==="assistant"&&Array.isArray(msg.content)){for(let block of msg.content)if(block.type==="toolCall"&&!TEMPLATE_RENDERED_TOOLS.has(block.name)){let callHtml=toolRenderer.renderCall(block.id,block.name,block.arguments);callHtml&&(renderedTools[block.id]={callHtml})}}if(msg.role==="toolResult"&&msg.toolCallId){let toolName=msg.toolName||"",existing=renderedTools[msg.toolCallId];if(existing||!TEMPLATE_RENDERED_TOOLS.has(toolName)){let rendered=toolRenderer.renderResult(msg.toolCallId,toolName,msg.content,msg.details,msg.isError||!1);rendered&&(renderedTools[msg.toolCallId]={...existing,resultHtmlCollapsed:rendered.collapsed,resultHtmlExpanded:rendered.expanded})}}}return renderedTools}async function exportSessionToHtml(sm,state2,options){let opts=typeof options=="string"?{outputPath:options}:options||{},sessionFile=sm.getSessionFile();if(!sessionFile)throw new Error("Cannot export in-memory session to HTML");if(!existsSync10(sessionFile))throw new Error("Nothing to export yet - start a conversation first");let entries=sm.getEntries(),renderedTools;opts.toolRenderer&&(renderedTools=preRenderCustomTools(entries,opts.toolRenderer),Object.keys(renderedTools).length===0&&(renderedTools=void 0));let sessionData={header:sm.getHeader(),entries,leafId:sm.getLeafId(),systemPrompt:state2?.systemPrompt,tools:state2?.tools?.map(t=>({name:t.name,description:t.description,parameters:t.parameters})),renderedTools},html=generateHtml(sessionData,opts.themeName),outputPath=opts.outputPath?normalizePath(opts.outputPath):void 0;if(!outputPath){let sessionBasename=basename8(sessionFile,".jsonl");outputPath=`${APP_NAME}-session-${sessionBasename}.html`}return writeFileSync7(outputPath,html,"utf8"),outputPath}async function exportFromFile(inputPath,options){let opts=typeof options=="string"?{outputPath:options}:options||{},resolvedInputPath=resolvePath(inputPath);if(!existsSync10(resolvedInputPath))throw new Error(`File not found: ${resolvedInputPath}`);let sm=SessionManager.open(resolvedInputPath),sessionData={header:sm.getHeader(),entries:sm.getEntries(),leafId:sm.getLeafId(),systemPrompt:void 0,tools:void 0},html=generateHtml(sessionData,opts.themeName),outputPath=opts.outputPath?normalizePath(opts.outputPath):void 0;if(!outputPath){let inputBasename=basename8(resolvedInputPath,".jsonl");outputPath=`${APP_NAME}-session-${inputBasename}.html`}return writeFileSync7(outputPath,html,"utf8"),outputPath}var ANSI_COLORS=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff"];function color256ToHex(index3){if(index3<16)return ANSI_COLORS[index3];if(index3<232){let cubeIndex=index3-16,r=Math.floor(cubeIndex/36),g2=Math.floor(cubeIndex%36/6),b2=cubeIndex%6,toComponent=n=>n===0?0:55+n*40,toHex=n=>toComponent(n).toString(16).padStart(2,"0");return`#${toHex(r)}${toHex(g2)}${toHex(b2)}`}let grayHex=(8+(index3-232)*10).toString(16).padStart(2,"0");return`#${grayHex}${grayHex}${grayHex}`}function escapeHtml(text){return text.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function createEmptyStyle(){return{fg:null,bg:null,bold:!1,dim:!1,italic:!1,underline:!1}}function styleToInlineCSS(style){let parts=[];return style.fg&&parts.push(`color:${style.fg}`),style.bg&&parts.push(`background-color:${style.bg}`),style.bold&&parts.push("font-weight:bold"),style.dim&&parts.push("opacity:0.6"),style.italic&&parts.push("font-style:italic"),style.underline&&parts.push("text-decoration:underline"),parts.join(";")}function hasStyle(style){return style.fg!==null||style.bg!==null||style.bold||style.dim||style.italic||style.underline}function applySgrCode(params,style){let i=0;for(;i<params.length;){let code=params[i];if(code===0)style.fg=null,style.bg=null,style.bold=!1,style.dim=!1,style.italic=!1,style.underline=!1;else if(code===1)style.bold=!0;else if(code===2)style.dim=!0;else if(code===3)style.italic=!0;else if(code===4)style.underline=!0;else if(code===22)style.bold=!1,style.dim=!1;else if(code===23)style.italic=!1;else if(code===24)style.underline=!1;else if(code>=30&&code<=37)style.fg=ANSI_COLORS[code-30];else if(code===38){if(params[i+1]===5&&params.length>i+2)style.fg=color256ToHex(params[i+2]),i+=2;else if(params[i+1]===2&&params.length>i+4){let r=params[i+2],g2=params[i+3],b2=params[i+4];style.fg=`rgb(${r},${g2},${b2})`,i+=4}}else if(code===39)style.fg=null;else if(code>=40&&code<=47)style.bg=ANSI_COLORS[code-40];else if(code===48){if(params[i+1]===5&&params.length>i+2)style.bg=color256ToHex(params[i+2]),i+=2;else if(params[i+1]===2&&params.length>i+4){let r=params[i+2],g2=params[i+3],b2=params[i+4];style.bg=`rgb(${r},${g2},${b2})`,i+=4}}else code===49?style.bg=null:code>=90&&code<=97?style.fg=ANSI_COLORS[code-90+8]:code>=100&&code<=107&&(style.bg=ANSI_COLORS[code-100+8]);i++}}var ANSI_REGEX=/\x1b\[([\d;]*)m/g;function ansiToHtml(text){let style=createEmptyStyle(),result="",lastIndex=0,inSpan=!1;ANSI_REGEX.lastIndex=0;let match2=ANSI_REGEX.exec(text);for(;match2!==null;){let beforeText=text.slice(lastIndex,match2.index);beforeText&&(result+=escapeHtml(beforeText));let paramStr=match2[1],params=paramStr?paramStr.split(";").map(p=>parseInt(p,10)||0):[0];inSpan&&(result+="</span>",inSpan=!1),applySgrCode(params,style),hasStyle(style)&&(result+=`<span style="${styleToInlineCSS(style)}">`,inSpan=!0),lastIndex=match2.index+match2[0].length,match2=ANSI_REGEX.exec(text)}let remainingText=text.slice(lastIndex);return remainingText&&(result+=escapeHtml(remainingText)),inSpan&&(result+="</span>"),result}function ansiLinesToHtml(lines){return lines.map(line=>`<div class="ansi-line">${ansiToHtml(line)||"&nbsp;"}</div>`).join("")}var ANSI_ESCAPE_REGEX=/\x1b\[[\d;]*m/g;function isBlankRenderedLine(line){return line.replace(ANSI_ESCAPE_REGEX,"").trim().length===0}function trimRenderedResultLines(lines){let start=0,end=lines.length;for(;start<end&&isBlankRenderedLine(lines[start]);)start++;for(;end>start&&isBlankRenderedLine(lines[end-1]);)end--;return lines.slice(start,end)}function createToolHtmlRenderer(deps){let{getToolDefinition:getToolDefinition2,theme:theme2,cwd,width=100}=deps,renderedCallComponents=new Map,renderedResultComponents=new Map,renderedStates=new Map,renderedArgs=new Map,getState=toolCallId=>{let state2=renderedStates.get(toolCallId);return state2||(state2={},renderedStates.set(toolCallId,state2)),state2},createRenderContext=(toolCallId,lastComponent,expanded,isPartial,isError)=>({args:renderedArgs.get(toolCallId),toolCallId,invalidate:()=>{},lastComponent,state:getState(toolCallId),cwd,executionStarted:!0,argsComplete:!0,isPartial,expanded,showImages:!1,isError});return{renderCall(toolCallId,toolName,args){try{renderedArgs.set(toolCallId,args);let toolDef=getToolDefinition2(toolName);if(!toolDef?.renderCall)return;let component=toolDef.renderCall(args,theme2,createRenderContext(toolCallId,renderedCallComponents.get(toolCallId),!1,!0,!1));renderedCallComponents.set(toolCallId,component);let lines=component.render(width);return ansiLinesToHtml(lines)}catch{return}},renderResult(toolCallId,toolName,result,details,isError){try{let toolDef=getToolDefinition2(toolName);if(!toolDef?.renderResult)return;let agentToolResult={content:result,details,isError},collapsedComponent=toolDef.renderResult(agentToolResult,{expanded:!1,isPartial:!1},theme2,createRenderContext(toolCallId,renderedResultComponents.get(toolCallId),!1,!1,isError));renderedResultComponents.set(toolCallId,collapsedComponent);let collapsed=ansiLinesToHtml(trimRenderedResultLines(collapsedComponent.render(width))),expandedComponent=toolDef.renderResult(agentToolResult,{expanded:!0,isPartial:!1},theme2,createRenderContext(toolCallId,renderedResultComponents.get(toolCallId),!0,!1,isError));renderedResultComponents.set(toolCallId,expandedComponent);let expanded=ansiLinesToHtml(trimRenderedResultLines(expandedComponent.render(width)));return{...collapsed&&collapsed!==expanded?{collapsed}:{},expanded}}catch{return}}}}import{existsSync as existsSync11,mkdirSync as mkdirSync9,writeFileSync as writeFileSync8}from"node:fs";import{dirname as dirname18}from"node:path";function serializeSessionBranch(sessionManager,header,createTrailingEntries){let lines=[JSON.stringify(header)],parentId=null;for(let entry of sessionManager.getBranch())lines.push(JSON.stringify({...entry,parentId})),parentId=entry.id;for(let entry of createTrailingEntries?.(parentId,header.timestamp)??[])lines.push(JSON.stringify(entry));return`${lines.join(`
985
985
  `)}
986
986
  `}function createSessionJsonlArtifact(sessionManager){let header=sessionManager.getHeader();if(!header)throw new Error("Cannot export a session without a session header");return{version:1,format:"jsonl",mediaType:"application/x-ndjson",fileName:`session-${header.id}.jsonl`,bytes:new TextEncoder().encode(serializeSessionBranch(sessionManager,{...header}))}}function exportSessionToJsonl(sessionManager,outputPath,createTrailingEntries){let filePath=resolvePath(outputPath??`session-${new Date().toISOString().replace(/[:.]/g,"-")}.jsonl`,process.cwd()),dir=dirname18(filePath);existsSync11(dir)||mkdirSync9(dir,{recursive:!0});let timestamp=new Date().toISOString(),header={type:"session",version:CURRENT_SESSION_VERSION,id:sessionManager.getSessionId(),timestamp,cwd:sessionManager.getCwd()};return writeFileSync8(filePath,serializeSessionBranch(sessionManager,header,createTrailingEntries)),filePath}function createUsageTotals(){return{input:0,output:0,cacheRead:0,cacheWrite:0,cost:0}}function addUsageToTotals(totals,usage){totals.input+=usage.input,totals.output+=usage.output,totals.cacheRead+=usage.cacheRead,totals.cacheWrite+=usage.cacheWrite,totals.cost+=usage.cost.total}function getUsageCostBreakdown(entries){let totalsByKey=new Map;for(let entry of entries){let key,usage;if(entry.type==="message"&&entry.message.role==="assistant"?(key=`${entry.message.provider}/${entry.message.responseModel??entry.message.model}`,usage=entry.message.usage):entry.type==="message"&&entry.message.role==="toolResult"&&entry.message.usage?(key="Tools/summaries",usage=entry.message.usage):(entry.type==="branch_summary"||entry.type==="compaction")&&entry.usage&&(key="Tools/summaries",usage=entry.usage),!key||!usage)continue;let totals=totalsByKey.get(key);totals||(totals=createUsageTotals(),totalsByKey.set(key,totals)),addUsageToTotals(totals,usage)}return Array.from(totalsByKey,([key,totals])=>({key,cost:totals.cost,tokens:totals.input+totals.output+totals.cacheRead+totals.cacheWrite,totals})).filter(entry=>entry.cost>0||entry.tokens>0).sort((a,b2)=>b2.cost-a.cost)}function getUserMessagesForForking(session){let entries=session.sessionManager.getEntries(),result=[];for(let entry of entries){if(entry.type!=="message"||entry.message.role!=="user")continue;let text=contentText(entry.message.content,"");text&&result.push({entryId:entry.id,text})}return result}function getSessionStats(session){let userMessages=0,assistantMessages=0,toolResults=0,totalMessages=0,toolCalls=0,usageTotals=createUsageTotals();for(let entry of session.sessionManager.getEntries()){if((entry.type==="branch_summary"||entry.type==="compaction")&&entry.usage&&addUsageToTotals(usageTotals,entry.usage),entry.type!=="message")continue;totalMessages++;let message=entry.message;if(message.role==="user")userMessages++;else if(message.role==="toolResult")toolResults++,message.usage&&addUsageToTotals(usageTotals,message.usage);else if(message.role==="assistant"){assistantMessages++;let assistantMsg=message;Array.isArray(assistantMsg.content)&&(toolCalls+=assistantMsg.content.filter(c2=>c2.type==="toolCall").length),addUsageToTotals(usageTotals,assistantMsg.usage)}}return{sessionFile:session.sessionFile,sessionId:session.sessionId,userMessages,assistantMessages,toolCalls,toolResults,totalMessages,tokens:{input:usageTotals.input,output:usageTotals.output,cacheRead:usageTotals.cacheRead,cacheWrite:usageTotals.cacheWrite,total:usageTotals.input+usageTotals.output+usageTotals.cacheRead+usageTotals.cacheWrite},cost:usageTotals.cost,contextUsage:session.getContextUsage()}}function getContextUsage(session){let model=session.model;if(!model)return;let contextWindow=model.contextWindow??0;if(contextWindow<=0)return;let branchEntries=session.sessionManager.getBranch(),latestCompaction=getLatestCompactionEntry(branchEntries);if(latestCompaction){let compactionIndex=branchEntries.lastIndexOf(latestCompaction),hasPostCompactionUsage=!1;for(let i=branchEntries.length-1;i>compactionIndex;i--){let entry=branchEntries[i];if(entry.type==="message"&&entry.message.role==="assistant"){let assistant=entry.message;if(assistant.stopReason!=="aborted"&&assistant.stopReason!=="error"&&calculateContextTokens2(assistant.usage)>0){hasPostCompactionUsage=!0;break}}}if(!hasPostCompactionUsage)return{tokens:null,contextWindow,percent:null}}let estimate=estimateContextTokens2(session.messages),percent=estimate.tokens/contextWindow*100;return{tokens:estimate.tokens,contextWindow,percent}}async function exportToHtml(session,outputPath,options={}){let themeName=[options.themeName,session.settingsManager.getTheme()].find(candidate=>candidate!==void 0&&getThemeByName(candidate)!==void 0),toolRenderer=createToolHtmlRenderer({getToolDefinition:name=>session.getToolDefinition(name),theme,cwd:session.sessionManager.getCwd()});return await exportSessionToHtml(session.sessionManager,session.agent.state,{outputPath,themeName,toolRenderer})}function exportToJsonl(session,outputPath){return exportSessionToJsonl(session.sessionManager,outputPath)}function getLastAssistantText(session){let lastAssistant=session.messages.slice().reverse().find(m2=>{if(m2.role!=="assistant")return!1;let msg=m2;return!(msg.stopReason==="aborted"&&msg.content.length===0)});if(!lastAssistant)return;let text="";for(let content of lastAssistant.content)content.type==="text"&&(text+=content.text);return text.trim()||void 0}function sleep3(ms,signal){return new Promise((resolve25,reject2)=>{if(signal?.aborted){reject2(new Error("Aborted"));return}let timeout=setTimeout(resolve25,ms);signal?.addEventListener("abort",()=>{clearTimeout(timeout),reject2(new Error("Aborted"))})})}async function willRetryAfterAgentEnd(session,event,signal){if(signal?.aborted)return session._pendingRetryDecision=void 0,!1;let settings2=session.settingsManager.getRetrySettings();if(session._retryAttempt>=settings2.maxRetries)return session._pendingRetryDecision=void 0,!1;for(let i=event.messages.length-1;i>=0;i--){let message=event.messages[i];if(message.role==="assistant"){let assistantMessage=message;try{let decision=await decideRetry(session,assistantMessage,void 0,signal);return session._pendingRetryDecision={message:assistantMessage,decision},decision.retry}catch(error2){if(signal?.aborted)return session._pendingRetryDecision=void 0,!1;throw error2}}}return session._pendingRetryDecision=void 0,!1}async function isRetryableError(session,message,execution,signal){if((await decideOverflow(session,message,execution,signal)).contextOverflow)return!1;let runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");return runtime.classifyRetry(session._retryPolicyName,{message,signal,context:{version:1,sessionId:session.sessionId,phase:"retry"},execution:execution??executionFacts(session,"retry")})}async function decideRetry(session,message,execution,signal){let settings2=session.settingsManager.getRetrySettings(),runtime=session._capabilityRuntime;if(!runtime)throw new Error("Capability runtime is not available");return runtime.decideRetry(session._retryPolicyName,{retryable:await session._isRetryableError(message,execution,signal),enabled:settings2.enabled,attempt:session._retryAttempt+1,maxAttempts:settings2.maxRetries,baseDelayMs:settings2.baseDelayMs,errorMessage:message.errorMessage,signal,context:{version:1,sessionId:session.sessionId,phase:"retry"},execution:execution??executionFacts(session,"retry")})}async function prepareRetry(session,message,precomputedDecision){let settings2=session.settingsManager.getRetrySettings(),decision=precomputedDecision??await decideRetry(session,message);if(!decision.retry)return!1;session._retryAttempt++;let baseDelayMs=Math.min(decision.delayMs??retryDelayMs(settings2,session._retryAttempt),settings2.maxAgentDelayMs),delayMs=Math.round(baseDelayMs*(.9+Math.random()*.2));session._retryAbortController=new AbortController,session._emit({type:"auto_retry_start",attempt:session._retryAttempt,maxAttempts:settings2.maxRetries,delayMs,errorMessage:message.errorMessage||"Unknown error"}),await dispatchAutoRetryLifecycle(session,{attempt:session._retryAttempt,maxAttempts:settings2.maxRetries,delayMs,errorMessage:message.errorMessage||"Unknown error"});let messages=session.agent.state.messages;messages.length>0&&messages[messages.length-1].role==="assistant"&&await session._applyContextTransition(messages.slice(0,-1),"retry");try{await sleep3(delayMs,session._retryAbortController.signal)}catch{let attempt2=session._retryAttempt;return session._retryAttempt=0,session._emit({type:"auto_retry_end",success:!1,attempt:attempt2,finalError:"Retry cancelled"}),!1}finally{session._retryAbortController=void 0}return!0}function buildSystemPrompt(options){let{customPrompt,orientationPrompt,preferenceCard,selectedTools,toolSnippets,promptGuidelines,appendSystemPrompt,cwd,contextFiles:providedContextFiles,skills:providedSkills}=options,promptCwd=cwd.replace(/\\/g,"/"),appendSection=appendSystemPrompt?`
@@ -1374,7 +1374,7 @@ ${expandedBody}`,this.getStartupExpansionState(),0,0);this.loadedResourcesContai
1374
1374
  ${warningLines}`,0,0)),this.loadedResourcesContainer.addChild(new Spacer(1))}let promptDiagnostics=promptsResult.diagnostics;if(promptDiagnostics.length>0){let warningLines=this.formatDiagnostics(promptDiagnostics,sourceInfos);this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning","[Prompt conflicts]")}
1375
1375
  ${warningLines}`,0,0)),this.loadedResourcesContainer.addChild(new Spacer(1))}let themeDiagnostics=themesResult.diagnostics;if(themeDiagnostics.length>0){let warningLines=this.formatDiagnostics(themeDiagnostics,sourceInfos);this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning","[Theme conflicts]")}
1376
1376
  ${warningLines}`,0,0)),this.loadedResourcesContainer.addChild(new Spacer(1))}}}async bindCurrentSessionExtensions(){await this.session.startSession(),setRegisteredThemes(buildRegisteredThemes(this.facade.getThemes().themes)),this.setupAutocompleteProvider(),this.showLoadedResources({force:!1,showDiagnosticsWhenQuiet:!0}),this.showStartupNoticesIfNeeded()}applyFullscreenScrollbarSetting(){this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar())}applyRuntimeSettings(){setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides()),configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs()),this.applyFullscreenScrollbarSetting(),this.renderer instanceof TuiAltScreen&&this.renderer.setCopyOnSelect(this.settingsManager.getFullscreenCopyOnSelect()),this.footer.setSession(this.session),this.footer.setAutoCompactEnabled(this.facade.isAutoCompactionEnabled()),this.footerDataProvider.setCwd(this.facade.getCwd()),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),this.outputPad=this.settingsManager.getOutputPad(),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());let clearOnShrink=this.settingsManager.getClearOnShrink();this.ui.setClearOnShrink(clearOnShrink),!clearOnShrink&&!this.activeStatusIndicator&&this.statusContainer.clear();let editorPaddingX=this.settingsManager.getEditorPaddingX(),autocompleteMaxVisible=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(editorPaddingX),this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(editorPaddingX),this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible))}async rebindCurrentSession(options={}){let session=this.session;this.unsubscribe?.(),this.unsubscribe=void 0,this.applyRuntimeSettings(),options.renderBeforeBind&&(this.renderCurrentSessionState(),this.subscribeToAgent()),await this.bindCurrentSessionExtensions(),this.session===session&&(options.renderBeforeBind||this.subscribeToAgent(),await this.updateAvailableProviderCount(),this.updateEditorBorderColor(),this.updateTerminalTitle())}async handleFatalRuntimeError(prefix,error2){let message=error2 instanceof Error?error2.message:String(error2);this.showError(`${prefix}: ${message}`),stopThemeWatcher(),this.stop("transcript"),process.exit(1)}renderCurrentSessionState(){this.loadedResourcesContainer.clear(),this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.compactionQueuedMessages=[],this.streamingComponent=void 0,this.streamingMessage=void 0,this.pendingTools.clear(),this.renderInitialMessages()}getRegisteredToolDefinition(toolName){return this.facade.getToolDefinition(toolName)}getMarkdownTransformers(){return[this.mermaidMarkdownTransformer]}showStatusIndicator(indicator){this.activeStatusIndicator?.dispose(),this.activeStatusIndicator=indicator,this.statusContainer.clear(),this.statusContainer.addChild(indicator)}clearStatusIndicator(kind){if(kind&&this.activeStatusIndicator?.kind!==kind)return;let hadActiveStatusIndicator=this.activeStatusIndicator!==void 0;this.activeStatusIndicator?.dispose(),this.activeStatusIndicator=void 0,this.statusContainer.clear(),hadActiveStatusIndicator&&this.options.tuiMode==="regular"&&this.ui.getClearOnShrink()&&this.statusContainer.addChild(this.idleStatus)}showWorkingStatusIndicator(){this.showStatusIndicator(new WorkingStatusIndicator(this.ui,this.workingMessage??this.defaultWorkingMessage,this.workingIndicatorOptions))}setWorkingVisible(visible){if(this.workingVisible=visible,!visible){this.clearStatusIndicator("working"),this.ui.requestRender();return}this.facade.isStreaming()&&this.activeStatusIndicator?.kind!=="working"&&this.showWorkingStatusIndicator(),this.ui.requestRender()}setWorkingIndicator(options){this.workingIndicatorOptions=options,this.activeStatusIndicator?.kind==="working"&&this.activeStatusIndicator.setIndicator(options),this.ui.requestRender()}setHiddenThinkingLabel(label){this.hiddenThinkingLabel=label??this.defaultHiddenThinkingLabel;for(let child of this.chatContainer.children)child instanceof AssistantMessageComponent&&child.setHiddenThinkingLabel(this.hiddenThinkingLabel);this.streamingComponent&&this.streamingComponent.setHiddenThinkingLabel(this.hiddenThinkingLabel),this.ui.requestRender()}setWorkingMessage(message){this.workingMessage=message,this.activeStatusIndicator?.kind==="working"&&this.activeStatusIndicator.setMessage(message??this.defaultWorkingMessage)}resetDialogUI(){this.dialogSelector&&this.hideDialogSelector(),this.dialogInput&&this.hideDialogInput(),this.dialogEditor&&this.hideDialogEditor(),this.ui.hideOverlay(),this.footer.invalidate(),this.setupAutocompleteProvider(),this.updateTerminalTitle(),this.workingMessage=void 0,this.workingVisible=!0,this.setWorkingIndicator(),this.activeStatusIndicator?.kind==="working"&&this.activeStatusIndicator.setMessage(`${this.defaultWorkingMessage} (${keyText("app.interrupt")} to interrupt)`),this.setHiddenThinkingLabel()}applyExtensionTheme(themeOrName){if(themeOrName instanceof Theme)return this.themeController.setThemeInstance(themeOrName);let result=this.themeController.setThemeName(themeOrName);return result.success&&this.settingsManager.getTheme()!==themeOrName&&this.settingsManager.setTheme(themeOrName),result}createInteractionHostV1(){return createInteractionHostV1(this)}showDialogSelector(title,options,opts){return showDialogSelector(this,title,options,opts)}hideDialogSelector(){hideDialogSelector(this)}async showDialogConfirm(title,message,opts){return showDialogConfirm(this,title,message,opts)}async promptForMissingSessionCwd(error2){return await this.showDialogConfirm("Session cwd not found",formatMissingSessionCwdPrompt(error2.issue))?error2.issue.fallbackCwd:void 0}showDialogInput(title,placeholder,opts){return showDialogInput(this,title,placeholder,opts)}hideDialogInput(){hideDialogInput(this)}showDialogEditor(title,prefill){return showDialogEditor(this,title,prefill)}getExternalEditorCommand(){return this.settingsManager.getExternalEditorCommand()}hideDialogEditor(){hideDialogEditor(this)}showDialogNotify(message,type){showDialogNotify(this,message,type)}setupKeyHandlers(){this.defaultEditor.onEscape=()=>{if(this.facade.isStreaming())this.restoreQueuedMessagesToEditor({abort:!0});else if(this.facade.isBashRunning())this.facade.abortBash();else if(this.isBashMode)this.editor.setText(""),this.isBashMode=!1,this.updateEditorBorderColor();else if(!this.editor.getText().trim()){let action=this.settingsManager.getDoubleEscapeAction();if(action!=="none"){let now=Date.now();now-this.lastEscapeTime<500?(action==="tree"?this.showTreeSelector():this.showUserMessageSelector(),this.lastEscapeTime=0):this.lastEscapeTime=now}}},this.defaultEditor.onAction("app.clear",()=>this.handleCtrlC()),this.defaultEditor.onCtrlD=()=>this.handleCtrlD(),this.defaultEditor.onAction("app.suspend",()=>this.handleCtrlZ()),this.defaultEditor.onAction("app.thinking.cycle",()=>this.cycleThinkingLevel()),this.defaultEditor.onAction("app.model.cycleForward",()=>this.cycleModel("forward")),this.defaultEditor.onAction("app.model.cycleBackward",()=>this.cycleModel("backward")),this.ui.onDebug=()=>this.handleDebugCommand(),this.defaultEditor.onAction("app.model.select",()=>this.showModelSelector()),this.defaultEditor.onAction("app.tools.expand",()=>this.toggleToolOutputExpansion()),this.defaultEditor.onAction("app.thinking.toggle",()=>this.toggleThinkingBlockVisibility()),this.defaultEditor.onAction("app.editor.external",()=>{this.handleOpenExternalEditor()}),this.defaultEditor.onAction("app.message.copy",()=>{this.handleCopyCommand({flashConfirmation:!0,preferSelection:!0})}),this.defaultEditor.onAction("app.message.followUp",()=>this.handleFollowUp()),this.defaultEditor.onAction("app.message.dequeue",()=>this.handleDequeue()),this.defaultEditor.onAction("app.session.new",()=>this.handleClearCommand()),this.defaultEditor.onAction("app.session.tree",()=>this.showTreeSelector()),this.defaultEditor.onAction("app.session.fork",()=>this.showUserMessageSelector()),this.defaultEditor.onAction("app.session.resume",()=>this.showSessionSelector()),this.defaultEditor.onChange=text=>{let wasBashMode=this.isBashMode;this.isBashMode=text.trimStart().startsWith("!"),wasBashMode!==this.isBashMode&&this.updateEditorBorderColor()},this.defaultEditor.onPasteImage=()=>{this.handleClipboardPaste()}}async handleRightClickPaste(){let target=this.renderer.getFocusedComponent(),handleInput=target?.handleInput;if(!(!target||!handleInput))try{let text=await readClipboardText();if(!text||this.renderer.getFocusedComponent()!==target)return;handleInput.call(target,`\x1B[200~${text}\x1B[201~`),this.ui.requestRender()}catch{}}async handleClipboardPaste(){try{let image=await readClipboardImage();if(image){let tmpDir=os6.tmpdir(),ext2=extensionForImageMimeType(image.mimeType)??"png",fileName=`agent-forge-clipboard-${crypto.randomUUID()}.${ext2}`,filePath=path14.join(tmpDir,fileName);fs5.writeFileSync(filePath,Buffer.from(image.bytes)),this.editor.insertTextAtCursor?.(filePath),this.ui.requestRender();return}let text=await readClipboardText();text&&(this.editor.insertTextAtCursor?.(text),this.ui.requestRender())}catch{}}handleStartupSubmit(text){text.trim()&&(this.pendingUserInputs.push(text),this.showStatus("Startup in progress \u2014 input queued and will run when startup completes"))}setupEditorSubmitHandler(){this.defaultEditor.onSubmit=async rawText=>{let text=rawText.trim();if(text&&!await this.dispatchCommandOrBash(text)){if(this.facade.isCompacting()){this.queueCompactionMessage(text,"steer");return}if(this.facade.isStreaming()){this.editor.addToHistory?.(text),this.editor.setText(""),await this.facade.prompt(text,{streamingBehavior:"steer"}),this.updatePendingMessagesDisplay(),this.ui.requestRender();return}this.flushPendingBashComponents(),this.onInputCallback?this.onInputCallback(text):this.pendingUserInputs.push(text),this.editor.addToHistory?.(text)}}}async dispatchCommandOrBash(text){let dispatched=this.dispatchEditorCommand(text);if(dispatched)return dispatched.pending&&await dispatched.pending,!0;if(text.startsWith("!")){let isExcluded=text.startsWith("!!"),command=isExcluded?text.slice(2).trim():text.slice(1).trim();if(command)return this.facade.isBashRunning()?(this.showWarning("A bash command is already running. Press Esc to cancel it first."),this.editor.setText(text),!0):(this.editor.addToHistory?.(text),await this.handleBashCommand(command,isExcluded),this.isBashMode=!1,this.updateEditorBorderColor(),!0)}return!1}dispatchEditorCommand(text){let match2=matchCommandDispatchEntry(COMMAND_DISPATCH_ENTRIES,text);if(!match2)return;let{entry,arg}=match2;entry.clearEditorBeforeRun&&this.setEditorText("");let result=entry.run(this,text,arg);return result instanceof Promise?{pending:entry.clearEditorBeforeRun?result:result.then(()=>this.setEditorText(""))}:(entry.clearEditorBeforeRun||this.setEditorText(""),{pending:void 0})}setEditorText(text){this.editor.setText(text)}subscribeToAgent(){this.unsubscribe=this.facade.subscribe(async event=>{await this.handleEvent(event)})}async handleEvent(event){switch(this.isInitialized||await this.init(),this.footer.invalidate(),event.type){case"agent_start":this.pendingTools.clear(),this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0);break;case"turn_start":this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.workingVisible?this.activeStatusIndicator?.kind!=="working"&&this.showWorkingStatusIndicator():this.clearStatusIndicator(),this.ui.requestRender();break;case"queue_update":this.updatePendingMessagesDisplay(),this.ui.requestRender();break;case"entry_appended":break;case"session_info_changed":this.updateTerminalTitle(),this.footer.invalidate(),this.ui.requestRender();break;case"thinking_level_changed":this.footer.invalidate(),this.updateEditorBorderColor();break;case"message_start":event.message.role==="custom"?(this.addMessageToChat(event.message),this.ui.requestRender()):event.message.role==="user"?(this.addMessageToChat(event.message),this.updatePendingMessagesDisplay(),this.ui.requestRender()):event.message.role==="assistant"&&(this.streamingComponent=new AssistantMessageComponent(void 0,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel,this.outputPad,this.getMarkdownTransformers()),this.streamingMessage=event.message,this.chatContainer.addChild(this.streamingComponent),this.streamingComponent.updateContent(this.streamingMessage,!0),this.ui.requestRender());break;case"message_update":if(this.streamingComponent&&event.message.role==="assistant"){this.streamingMessage=event.message,this.streamingComponent.updateContent(this.streamingMessage,!0);for(let content of this.streamingMessage.content)if(content.type==="toolCall")if(this.pendingTools.has(content.id)){let component=this.pendingTools.get(content.id);component&&component.updateArgs(content.arguments)}else{let component=new ToolExecutionComponent(content.name,content.id,content.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(content.name),this.ui,this.facade.getCwd());component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component),this.pendingTools.set(content.id,component)}this.ui.requestRender()}break;case"message_end":if(event.message.role==="user")break;if(this.streamingComponent&&event.message.role==="assistant"){this.streamingMessage=event.message;let errorMessage2;if(this.streamingMessage.stopReason==="aborted"){let retryAttempt=this.facade.getRetryAttempt();errorMessage2=retryAttempt>0?`Aborted after ${retryAttempt} retry attempt${retryAttempt>1?"s":""}`:"Operation aborted",this.streamingMessage.errorMessage=errorMessage2}if(this.streamingComponent.updateContent(this.streamingMessage,!1),this.streamingMessage.stopReason==="aborted"||this.streamingMessage.stopReason==="error"){errorMessage2||(errorMessage2=this.streamingMessage.errorMessage||"Error");for(let[,component]of this.pendingTools.entries())component.updateResult({content:[{type:"text",text:errorMessage2}],isError:!0});this.pendingTools.clear()}else{for(let[,component]of this.pendingTools.entries())component.setArgsComplete();this.maybeShowAssistantDiagnostics(this.streamingMessage),this.maybeShowCacheMissNotice(this.streamingMessage)}this.streamingComponent=void 0,this.streamingMessage=void 0,this.footer.invalidate()}this.ui.requestRender();break;case"bash_execution_update":break;case"tool_execution_start":{let component=this.pendingTools.get(event.toolCallId);component||(component=new ToolExecutionComponent(event.toolName,event.toolCallId,event.args,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(event.toolName),this.ui,this.facade.getCwd()),component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component),this.pendingTools.set(event.toolCallId,component)),component.markExecutionStarted(),this.ui.requestRender();break}case"tool_execution_update":{let component=this.pendingTools.get(event.toolCallId);component&&(component.updateResult({...event.partialResult,isError:!1},!0),this.ui.requestRender());break}case"tool_execution_end":{let component=this.pendingTools.get(event.toolCallId);component&&(component.updateResult({...event.result,isError:event.isError}),this.pendingTools.delete(event.toolCallId),this.ui.requestRender());break}case"capability_command_result":{let links=event.result.links?.map(link=>`${link.label}: ${link.url}`)??[],message=[event.result.message,...links].filter(Boolean).join(`
1377
- `);event.result.status==="error"?this.showError(message):this.showStatus(message),this.ui.requestRender();break}case"agent_end":this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.clearStatusIndicator("working"),this.streamingComponent&&(this.chatContainer.removeChild(this.streamingComponent),this.streamingComponent=void 0,this.streamingMessage=void 0),this.pendingTools.clear(),this.ui.requestRender();break;case"agent_settled":await this.checkShutdownRequested();break;case"compaction_start":{this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.autoCompactionEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.facade.abortCompaction()},this.showStatusIndicator(new CompactionStatusIndicator(this.ui,event.reason)),this.ui.requestRender();break}case"compaction_end":{if(this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.autoCompactionEscapeHandler&&(this.defaultEditor.onEscape=this.autoCompactionEscapeHandler,this.autoCompactionEscapeHandler=void 0),this.clearStatusIndicator("compaction"),event.aborted)event.reason==="manual"?this.showError("Compaction cancelled"):this.showStatus("Auto-compaction cancelled");else if(event.result){let entries=this.facade.getContextEntries();if(entries[0]?.type!=="compaction")throw new Error("Completed compaction is missing from the session context");this.chatContainer.clear(),this.renderSessionEntries(entries.slice(1)),this.addMessageToChat(createCompactionSummaryMessage2(event.result.summary,event.result.tokensBefore,new Date().toISOString())),event.result.usage&&this.addCompactionCostNotice({type:"compaction_cost",kind:"compaction",usage:event.result.usage}),this.footer.invalidate()}else event.errorMessage&&(event.reason==="manual"?this.showError(event.errorMessage):(this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("error",event.errorMessage),1,0))));this.flushCompactionQueue({willRetry:event.willRetry}),this.ui.requestRender();break}case"auto_retry_start":{this.retryEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.facade.abortRetry()},this.showStatusIndicator(new RetryStatusIndicator(this.ui,event.attempt,event.maxAttempts,event.delayMs)),this.ui.requestRender();break}case"auto_retry_end":{this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.clearStatusIndicator("retry"),event.success||this.showError(`Retry failed after ${event.attempt} attempts: ${event.finalError||"Unknown error"}`),this.ui.requestRender();break}case"summarization_retry_scheduled":{this.showError(event.errorMessage),this.showStatusIndicator(new RetryStatusIndicator(this.ui,event.attempt,event.maxAttempts,event.delayMs)),this.ui.requestRender();break}case"summarization_retry_attempt_start":{this.clearStatusIndicator("retry"),event.source==="branchSummary"?this.showStatusIndicator(new BranchSummaryStatusIndicator(this.ui)):this.showStatusIndicator(new CompactionStatusIndicator(this.ui,event.reason)),this.ui.requestRender();break}case"summarization_retry_finished":{this.clearStatusIndicator("retry"),this.ui.requestRender();break}}}getUserMessageText(message){return message.role!=="user"?"":(typeof message.content=="string"?[{type:"text",text:message.content}]:message.content.filter(c2=>c2.type==="text")).map(c2=>c2.text).join("")}showManagedToolStatus(status2){this.managedToolStatusStarted||(this.chatContainer.addChild(new Spacer(1)),this.managedToolStatusStarted=!0);let message=status2.type==="warning"?`Warning: ${status2.message}`:status2.message,color=status2.type==="warning"?"warning":"dim";this.chatContainer.addChild(new Text(theme.fg(color,message),1,0)),this.lastStatusSpacer=void 0,this.lastStatusText=void 0,this.ui.requestRender()}showStatus(message){let children=this.chatContainer.children,last=children.length>0?children[children.length-1]:void 0,secondLast=children.length>1?children[children.length-2]:void 0;if(last&&secondLast&&last===this.lastStatusText&&secondLast===this.lastStatusSpacer){this.lastStatusText.setText(theme.fg("dim",message)),this.ui.requestRender();return}let spacer=new Spacer(1),text=new Text(theme.fg("dim",message),1,0);this.chatContainer.addChild(spacer),this.chatContainer.addChild(text),this.lastStatusSpacer=spacer,this.lastStatusText=text,this.ui.requestRender()}addMessageToChat(message,options){switch(message.role){case"bashExecution":{let component=new BashExecutionComponent(message.command,this.ui,message.excludeFromContext);message.output&&component.appendOutput(message.output),component.setComplete(message.exitCode,message.cancelled,message.truncated?{truncated:!0}:void 0,message.fullOutputPath),this.chatContainer.addChild(component);break}case"custom":{if(message.display){let component=new CustomMessageComponent(message,void 0,this.getMarkdownThemeWithSettings(),this.outputPad);component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component)}break}case"compactionSummary":{this.chatContainer.addChild(new Spacer(1));let component=new CompactionSummaryMessageComponent(message,this.getMarkdownThemeWithSettings());component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component);break}case"branchSummary":{this.chatContainer.addChild(new Spacer(1));let component=new BranchSummaryMessageComponent(message,this.getMarkdownThemeWithSettings());component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component);break}case"user":{let textContent=this.getUserMessageText(message);if(textContent){this.chatContainer.children.length>0&&this.chatContainer.addChild(new Spacer(1));let skillBlock=parseSkillBlock(textContent);if(skillBlock){let component=new SkillInvocationMessageComponent(skillBlock,this.getMarkdownThemeWithSettings());if(component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component),skillBlock.userMessage){this.chatContainer.addChild(new Spacer(1));let userComponent=new UserMessageComponent(skillBlock.userMessage,this.getMarkdownThemeWithSettings(),this.outputPad,this.getMarkdownTransformers());this.chatContainer.addChild(userComponent)}}else{let userComponent=new UserMessageComponent(textContent,this.getMarkdownThemeWithSettings(),this.outputPad,this.getMarkdownTransformers());this.chatContainer.addChild(userComponent)}options?.populateHistory&&this.editor.addToHistory?.(textContent)}break}case"assistant":{let assistantComponent=new AssistantMessageComponent(message,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel,this.outputPad,this.getMarkdownTransformers());this.chatContainer.addChild(assistantComponent);break}case"toolResult":break;default:{let _exhaustive=message}}}renderSessionItems(items,options={}){this.pendingTools.clear();let renderedPendingTools=new Map,cacheMisses=this.settingsManager.getShowCacheMissNotices()?collectCacheMisses(this.facade.getEntries(),this.facade.getModelPriceSource()):new Map;options.updateFooter&&(this.footer.invalidate(),this.updateEditorBorderColor());for(let item of items){if(isCustomSessionEntry(item))continue;if(isCompactionCostNotice(item)){this.addCompactionCostNotice(item);continue}let message=item;if(message.role==="assistant"){this.addMessageToChat(message);for(let content of message.content)if(content.type==="toolCall"){let component=new ToolExecutionComponent(content.name,content.id,content.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(content.name),this.ui,this.facade.getCwd());if(component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component),message.stopReason==="aborted"||message.stopReason==="error"){let errorMessage2;if(message.stopReason==="aborted"){let retryAttempt=this.facade.getRetryAttempt();errorMessage2=retryAttempt>0?`Aborted after ${retryAttempt} retry attempt${retryAttempt>1?"s":""}`:"Operation aborted"}else errorMessage2=message.errorMessage||"Error";component.updateResult({content:[{type:"text",text:errorMessage2}],isError:!0})}else renderedPendingTools.set(content.id,component)}if(message.stopReason!=="aborted"&&message.stopReason!=="error"){this.maybeShowAssistantDiagnostics(message);let miss=cacheMisses.get(message);miss&&this.addCacheMissNotice(miss)}}else if(message.role==="toolResult"){let component=renderedPendingTools.get(message.toolCallId);component&&(component.updateResult(message),renderedPendingTools.delete(message.toolCallId))}else this.addMessageToChat(message,options)}for(let[toolCallId,component]of renderedPendingTools)this.pendingTools.set(toolCallId,component);this.ui.requestRender()}renderSessionEntries(entries,options={}){let items=entries.flatMap(entry=>{if(entry.type==="custom")return[entry];let messages=sessionEntryToContextMessages(entry);return(entry.type==="compaction"||entry.type==="branch_summary")&&entry.usage&&messages.length>0?[...messages,{type:"compaction_cost",kind:entry.type,usage:entry.usage}]:messages});this.renderSessionItems(items,options)}addCompactionCostNotice(notice){if(!this.settingsManager.getShowCacheMissNotices())return;let{usage}=notice,tokens=usage.input+usage.output+usage.cacheRead+usage.cacheWrite,cost=usage.cost.total>=.01?` (~$${usage.cost.total.toFixed(2)})`:"",label=notice.kind==="compaction"?"Compaction":"Branch summary";this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("warning",`${label}: ${formatTokens(tokens)} tokens billed${cost}`),1,0))}maybeShowAssistantDiagnostics(message){if(this.settingsManager.getShowCacheMissNotices())for(let diagnostic5 of message.diagnostics??[]){if(diagnostic5.type!=="anthropic_input_transformations")continue;let transformations=diagnostic5.details?.transformations;if(!Array.isArray(transformations))continue;let dropped=transformations.flatMap(transformation=>{if(typeof transformation!="object"||transformation===null)return[];let details=transformation;if(details.type!=="thinking_dropped")return[];let reason=typeof details.reason=="string"?details.reason:"unknown reason",location=typeof details.path=="string"?` at ${details.path}`:"";return[`${reason}${location}`]});if(dropped.length===0)continue;let noun=dropped.length===1?"thinking block":`${dropped.length} thinking blocks`;this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("warning",`Anthropic dropped ${noun}: ${dropped.join("; ")}`),1,0))}}maybeShowCacheMissNotice(message){if(!this.settingsManager.getShowCacheMissNotices())return;let miss=detectCacheMiss(this.facade.getEntries(),message,this.facade.getModelPriceSource());miss&&this.addCacheMissNotice(miss)}addCacheMissNotice(miss){if(miss.missedTokens<2e4&&miss.missedCost<.1)return;let cost=miss.missedCost>=.01?` (~$${miss.missedCost.toFixed(2)})`:"",reBilled=`${formatTokens(miss.missedTokens)} tokens re-billed${cost}`,label="Cache miss";miss.modelChanged?label="Cache miss after model switch":miss.idleMs>=3e5&&(label=`Cache miss after ${Math.round(miss.idleMs/6e4)}m idle`);let text=theme.fg("warning",`${label}: ${reBilled}`);this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(text,1,0))}renderInitialMessages(){let entries=this.facade.getContextEntries();this.renderSessionEntries(entries,{updateFooter:!0,populateHistory:!0});let compactionCount=this.facade.getEntries().filter(e=>e.type==="compaction").length;if(compactionCount>0){let times=compactionCount===1?"1 time":`${compactionCount} times`;this.showStatus(`Session compacted ${times}`)}}async getUserInput(){let queuedInput=this.pendingUserInputs.shift();return queuedInput!==void 0?queuedInput:new Promise(resolve25=>{this.onInputCallback=text=>{this.onInputCallback=void 0,resolve25(text)}})}rebuildChatFromMessages(){this.chatContainer.clear(),this.renderSessionEntries(this.facade.getContextEntries())}handleCtrlC(){let now=Date.now();now-this.lastSigintTime<500?this.shutdown():(this.clearEditor(),this.lastSigintTime=now)}handleCtrlD(){this.shutdown()}isShuttingDown=!1;async shutdown(options){if(this.isShuttingDown)return;this.isShuttingDown=!0,options?.fromSignal&&(await this.runtimeFacade.dispose(),this.themeController.disableAutoSync(),await this.ui.terminal.drainInput(1e3),this.stop(),process.exit(0)),this.themeController.disableAutoSync(),await this.ui.terminal.drainInput(1e3),this.stop(),await this.runtimeFacade.dispose();let resumeCommand=formatResumeCommand(this.runtimeFacade);resumeCommand&&process.stdout.write(`${source_default.dim("To resume this session:")} ${resumeCommand}
1377
+ `);event.result.status==="error"?this.showError(message):this.showStatus(message),this.ui.requestRender();break}case"agent_end":this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.clearStatusIndicator("working"),this.streamingComponent&&(this.chatContainer.removeChild(this.streamingComponent),this.streamingComponent=void 0,this.streamingMessage=void 0),this.pendingTools.clear(),this.ui.requestRender();break;case"agent_settled":await this.checkShutdownRequested();break;case"compaction_start":{this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.autoCompactionEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.facade.abortCompaction()},this.showStatusIndicator(new CompactionStatusIndicator(this.ui,event.reason)),this.ui.requestRender();break}case"compaction_end":{if(this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.autoCompactionEscapeHandler&&(this.defaultEditor.onEscape=this.autoCompactionEscapeHandler,this.autoCompactionEscapeHandler=void 0),this.clearStatusIndicator("compaction"),event.aborted)event.reason==="manual"?this.showError("Compaction cancelled"):this.showStatus("Auto-compaction cancelled");else if(event.result){let entries=this.facade.getContextEntries();if(entries[0]?.type!=="compaction")throw new Error("Completed compaction is missing from the session context");this.chatContainer.clear(),this.renderSessionEntries(entries.slice(1)),this.addMessageToChat(createCompactionSummaryMessage2(event.result.summary,event.result.tokensBefore,new Date().toISOString())),event.result.usage&&this.addCompactionCostNotice({type:"compaction_cost",kind:"compaction",usage:event.result.usage}),this.footer.invalidate()}else event.errorMessage&&(event.reason==="manual"?this.showError(event.errorMessage):(this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("error",event.errorMessage),1,0))));this.flushCompactionQueue({willRetry:event.willRetry}),this.ui.requestRender();break}case"compaction_skipped":{this.showStatus("Auto-compaction skipped: nothing to compact"),this.ui.requestRender();break}case"auto_retry_start":{this.retryEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.facade.abortRetry()},this.showStatusIndicator(new RetryStatusIndicator(this.ui,event.attempt,event.maxAttempts,event.delayMs)),this.ui.requestRender();break}case"auto_retry_end":{this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.clearStatusIndicator("retry"),event.success||this.showError(`Retry failed after ${event.attempt} attempts: ${event.finalError||"Unknown error"}`),this.ui.requestRender();break}case"summarization_retry_scheduled":{this.showError(event.errorMessage),this.showStatusIndicator(new RetryStatusIndicator(this.ui,event.attempt,event.maxAttempts,event.delayMs)),this.ui.requestRender();break}case"summarization_retry_attempt_start":{this.clearStatusIndicator("retry"),event.source==="branchSummary"?this.showStatusIndicator(new BranchSummaryStatusIndicator(this.ui)):this.showStatusIndicator(new CompactionStatusIndicator(this.ui,event.reason)),this.ui.requestRender();break}case"summarization_retry_finished":{this.clearStatusIndicator("retry"),this.ui.requestRender();break}}}getUserMessageText(message){return message.role!=="user"?"":(typeof message.content=="string"?[{type:"text",text:message.content}]:message.content.filter(c2=>c2.type==="text")).map(c2=>c2.text).join("")}showManagedToolStatus(status2){this.managedToolStatusStarted||(this.chatContainer.addChild(new Spacer(1)),this.managedToolStatusStarted=!0);let message=status2.type==="warning"?`Warning: ${status2.message}`:status2.message,color=status2.type==="warning"?"warning":"dim";this.chatContainer.addChild(new Text(theme.fg(color,message),1,0)),this.lastStatusSpacer=void 0,this.lastStatusText=void 0,this.ui.requestRender()}showStatus(message){let children=this.chatContainer.children,last=children.length>0?children[children.length-1]:void 0,secondLast=children.length>1?children[children.length-2]:void 0;if(last&&secondLast&&last===this.lastStatusText&&secondLast===this.lastStatusSpacer){this.lastStatusText.setText(theme.fg("dim",message)),this.ui.requestRender();return}let spacer=new Spacer(1),text=new Text(theme.fg("dim",message),1,0);this.chatContainer.addChild(spacer),this.chatContainer.addChild(text),this.lastStatusSpacer=spacer,this.lastStatusText=text,this.ui.requestRender()}addMessageToChat(message,options){switch(message.role){case"bashExecution":{let component=new BashExecutionComponent(message.command,this.ui,message.excludeFromContext);message.output&&component.appendOutput(message.output),component.setComplete(message.exitCode,message.cancelled,message.truncated?{truncated:!0}:void 0,message.fullOutputPath),this.chatContainer.addChild(component);break}case"custom":{if(message.display){let component=new CustomMessageComponent(message,void 0,this.getMarkdownThemeWithSettings(),this.outputPad);component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component)}break}case"compactionSummary":{this.chatContainer.addChild(new Spacer(1));let component=new CompactionSummaryMessageComponent(message,this.getMarkdownThemeWithSettings());component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component);break}case"branchSummary":{this.chatContainer.addChild(new Spacer(1));let component=new BranchSummaryMessageComponent(message,this.getMarkdownThemeWithSettings());component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component);break}case"user":{let textContent=this.getUserMessageText(message);if(textContent){this.chatContainer.children.length>0&&this.chatContainer.addChild(new Spacer(1));let skillBlock=parseSkillBlock(textContent);if(skillBlock){let component=new SkillInvocationMessageComponent(skillBlock,this.getMarkdownThemeWithSettings());if(component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component),skillBlock.userMessage){this.chatContainer.addChild(new Spacer(1));let userComponent=new UserMessageComponent(skillBlock.userMessage,this.getMarkdownThemeWithSettings(),this.outputPad,this.getMarkdownTransformers());this.chatContainer.addChild(userComponent)}}else{let userComponent=new UserMessageComponent(textContent,this.getMarkdownThemeWithSettings(),this.outputPad,this.getMarkdownTransformers());this.chatContainer.addChild(userComponent)}options?.populateHistory&&this.editor.addToHistory?.(textContent)}break}case"assistant":{let assistantComponent=new AssistantMessageComponent(message,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel,this.outputPad,this.getMarkdownTransformers());this.chatContainer.addChild(assistantComponent);break}case"toolResult":break;default:{let _exhaustive=message}}}renderSessionItems(items,options={}){this.pendingTools.clear();let renderedPendingTools=new Map,cacheMisses=this.settingsManager.getShowCacheMissNotices()?collectCacheMisses(this.facade.getEntries(),this.facade.getModelPriceSource()):new Map;options.updateFooter&&(this.footer.invalidate(),this.updateEditorBorderColor());for(let item of items){if(isCustomSessionEntry(item))continue;if(isCompactionCostNotice(item)){this.addCompactionCostNotice(item);continue}let message=item;if(message.role==="assistant"){this.addMessageToChat(message);for(let content of message.content)if(content.type==="toolCall"){let component=new ToolExecutionComponent(content.name,content.id,content.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(content.name),this.ui,this.facade.getCwd());if(component.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(component),message.stopReason==="aborted"||message.stopReason==="error"){let errorMessage2;if(message.stopReason==="aborted"){let retryAttempt=this.facade.getRetryAttempt();errorMessage2=retryAttempt>0?`Aborted after ${retryAttempt} retry attempt${retryAttempt>1?"s":""}`:"Operation aborted"}else errorMessage2=message.errorMessage||"Error";component.updateResult({content:[{type:"text",text:errorMessage2}],isError:!0})}else renderedPendingTools.set(content.id,component)}if(message.stopReason!=="aborted"&&message.stopReason!=="error"){this.maybeShowAssistantDiagnostics(message);let miss=cacheMisses.get(message);miss&&this.addCacheMissNotice(miss)}}else if(message.role==="toolResult"){let component=renderedPendingTools.get(message.toolCallId);component&&(component.updateResult(message),renderedPendingTools.delete(message.toolCallId))}else this.addMessageToChat(message,options)}for(let[toolCallId,component]of renderedPendingTools)this.pendingTools.set(toolCallId,component);this.ui.requestRender()}renderSessionEntries(entries,options={}){let items=entries.flatMap(entry=>{if(entry.type==="custom")return[entry];let messages=sessionEntryToContextMessages(entry);return(entry.type==="compaction"||entry.type==="branch_summary")&&entry.usage&&messages.length>0?[...messages,{type:"compaction_cost",kind:entry.type,usage:entry.usage}]:messages});this.renderSessionItems(items,options)}addCompactionCostNotice(notice){if(!this.settingsManager.getShowCacheMissNotices())return;let{usage}=notice,tokens=usage.input+usage.output+usage.cacheRead+usage.cacheWrite,cost=usage.cost.total>=.01?` (~$${usage.cost.total.toFixed(2)})`:"",label=notice.kind==="compaction"?"Compaction":"Branch summary";this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("warning",`${label}: ${formatTokens(tokens)} tokens billed${cost}`),1,0))}maybeShowAssistantDiagnostics(message){if(this.settingsManager.getShowCacheMissNotices())for(let diagnostic5 of message.diagnostics??[]){if(diagnostic5.type!=="anthropic_input_transformations")continue;let transformations=diagnostic5.details?.transformations;if(!Array.isArray(transformations))continue;let dropped=transformations.flatMap(transformation=>{if(typeof transformation!="object"||transformation===null)return[];let details=transformation;if(details.type!=="thinking_dropped")return[];let reason=typeof details.reason=="string"?details.reason:"unknown reason",location=typeof details.path=="string"?` at ${details.path}`:"";return[`${reason}${location}`]});if(dropped.length===0)continue;let noun=dropped.length===1?"thinking block":`${dropped.length} thinking blocks`;this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("warning",`Anthropic dropped ${noun}: ${dropped.join("; ")}`),1,0))}}maybeShowCacheMissNotice(message){if(!this.settingsManager.getShowCacheMissNotices())return;let miss=detectCacheMiss(this.facade.getEntries(),message,this.facade.getModelPriceSource());miss&&this.addCacheMissNotice(miss)}addCacheMissNotice(miss){if(miss.missedTokens<2e4&&miss.missedCost<.1)return;let cost=miss.missedCost>=.01?` (~$${miss.missedCost.toFixed(2)})`:"",reBilled=`${formatTokens(miss.missedTokens)} tokens re-billed${cost}`,label="Cache miss";miss.modelChanged?label="Cache miss after model switch":miss.idleMs>=3e5&&(label=`Cache miss after ${Math.round(miss.idleMs/6e4)}m idle`);let text=theme.fg("warning",`${label}: ${reBilled}`);this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(text,1,0))}renderInitialMessages(){let entries=this.facade.getContextEntries();this.renderSessionEntries(entries,{updateFooter:!0,populateHistory:!0});let compactionCount=this.facade.getEntries().filter(e=>e.type==="compaction").length;if(compactionCount>0){let times=compactionCount===1?"1 time":`${compactionCount} times`;this.showStatus(`Session compacted ${times}`)}}async getUserInput(){let queuedInput=this.pendingUserInputs.shift();return queuedInput!==void 0?queuedInput:new Promise(resolve25=>{this.onInputCallback=text=>{this.onInputCallback=void 0,resolve25(text)}})}rebuildChatFromMessages(){this.chatContainer.clear(),this.renderSessionEntries(this.facade.getContextEntries())}handleCtrlC(){let now=Date.now();now-this.lastSigintTime<500?this.shutdown():(this.clearEditor(),this.lastSigintTime=now)}handleCtrlD(){this.shutdown()}isShuttingDown=!1;async shutdown(options){if(this.isShuttingDown)return;this.isShuttingDown=!0,options?.fromSignal&&(await this.runtimeFacade.dispose(),this.themeController.disableAutoSync(),await this.ui.terminal.drainInput(1e3),this.stop(),process.exit(0)),this.themeController.disableAutoSync(),await this.ui.terminal.drainInput(1e3),this.stop(),await this.runtimeFacade.dispose();let resumeCommand=formatResumeCommand(this.runtimeFacade);resumeCommand&&process.stdout.write(`${source_default.dim("To resume this session:")} ${resumeCommand}
1378
1378
  `),process.exit(0)}emergencyTerminalExit(){this.isShuttingDown=!0,this.unregisterSignalHandlers(),killTrackedDetachedChildren(),process.exit(129)}uncaughtCrash(error2){this.isShuttingDown&&process.exit(1),this.isShuttingDown=!0;try{this.unregisterSignalHandlers()}catch{}try{killTrackedDetachedChildren()}catch{}try{this.ui.stop()}catch{}console.error(`${APP_NAME} exiting due to uncaughtException:`),console.error(error2),process.exit(1)}async checkShutdownRequested(){this.shutdownRequested&&await this.shutdown()}registerSignalHandlers(){this.unregisterSignalHandlers();let signals=["SIGTERM"];process.platform!=="win32"&&signals.push("SIGHUP");for(let signal of signals){let handler=()=>{killTrackedDetachedChildren(),this.shutdown({fromSignal:!0})};process.prependListener(signal,handler),this.signalCleanupHandlers.push(()=>process.off(signal,handler))}let terminalErrorHandler=error2=>{throw isDeadTerminalError(error2)&&this.emergencyTerminalExit(),error2};process.stdout.on("error",terminalErrorHandler),process.stderr.on("error",terminalErrorHandler),this.signalCleanupHandlers.push(()=>process.stdout.off("error",terminalErrorHandler)),this.signalCleanupHandlers.push(()=>process.stderr.off("error",terminalErrorHandler));let uncaughtExceptionHandler=error2=>this.uncaughtCrash(error2);process.prependListener("uncaughtException",uncaughtExceptionHandler),this.signalCleanupHandlers.push(()=>process.off("uncaughtException",uncaughtExceptionHandler))}unregisterSignalHandlers(){for(let cleanup of this.signalCleanupHandlers)cleanup();this.signalCleanupHandlers=[]}handleCtrlZ(){if(process.platform==="win32"){this.showStatus("Suspend to background is not supported on Windows");return}let suspendKeepAlive=setInterval(()=>{},2**30),ignoreSigint=()=>{};process.on("SIGINT",ignoreSigint),process.once("SIGCONT",()=>{clearInterval(suspendKeepAlive),process.removeListener("SIGINT",ignoreSigint),this.ui.start(),this.ui.requestRender(!0)});try{this.ui.stop(),process.kill(0,"SIGTSTP")}catch(error2){throw clearInterval(suspendKeepAlive),process.removeListener("SIGINT",ignoreSigint),error2}}async handleFollowUp(){let text=(this.editor.getExpandedText?.()??this.editor.getText()).trim();if(text){if(this.facade.isCompacting()){this.queueCompactionMessage(text,"followUp");return}this.facade.isStreaming()?(this.editor.addToHistory?.(text),this.editor.setText(""),await this.facade.prompt(text,{streamingBehavior:"followUp"}),this.updatePendingMessagesDisplay(),this.ui.requestRender()):this.editor.onSubmit&&(this.editor.setText(""),this.editor.onSubmit(text))}}handleDequeue(){let restored=this.restoreQueuedMessagesToEditor();restored===0?this.showStatus("No queued messages to restore"):this.showStatus(`Restored ${restored} queued message${restored>1?"s":""} to editor`)}updateEditorBorderColor(){if(this.isBashMode)this.editor.borderColor=theme.getBashModeBorderColor();else{let level=this.facade.getState().thinkingLevel||"off";this.editor.borderColor=theme.getThinkingBorderColor(level)}this.ui.requestRender()}cycleThinkingLevel(){let newLevel=this.facade.cycleThinkingLevel();newLevel===void 0?this.showStatus("Current model does not support thinking"):(this.footer.invalidate(),this.updateEditorBorderColor(),this.showStatus(`Thinking level: ${newLevel}`))}async cycleModel(direction){try{let result=await this.facade.cycleModel(direction);if(result===void 0){let msg=this.facade.getScopedModels().length>0?"Only one model in scope":"Only one model available";this.showStatus(msg)}else{this.footer.invalidate(),this.updateEditorBorderColor();let thinkingStr=result.model.reasoning&&result.thinkingLevel!=="off"?` (thinking: ${result.thinkingLevel})`:"";this.showStatus(`Switched to ${result.model.name||result.model.id}${thinkingStr}`),this.maybeWarnAboutAnthropicSubscriptionAuth(result.model)}}catch(error2){this.showError(error2 instanceof Error?error2.message:String(error2))}}toggleToolOutputExpansion(){this.setToolsExpanded(!this.toolOutputExpanded)}setToolsExpanded(expanded){if(expanded===this.toolOutputExpanded)return;this.toolOutputExpanded=expanded;let activeHeader=this.builtInHeader;isExpandable(activeHeader)&&activeHeader.setExpanded(expanded);for(let container of[this.loadedResourcesContainer,this.chatContainer])for(let child of container.children)isExpandable(child)&&child.setExpanded(expanded);this.showStatus(`Tool output: ${expanded?"expanded":"collapsed"}`)}updateThinkingBlockVisibility(){for(let child of this.chatContainer.children)child instanceof AssistantMessageComponent&&child.setHideThinkingBlock(this.hideThinkingBlock);this.ui.requestRender()}toggleThinkingBlockVisibility(){this.hideThinkingBlock=!this.hideThinkingBlock,this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock),this.updateThinkingBlockVisibility(),this.showStatus(`Thinking blocks: ${this.hideThinkingBlock?"hidden":"visible"}`)}async handleOpenExternalEditor(){let editorCmd=this.settingsManager.getExternalEditorCommand(),content=this.editor.getExpandedText?.()??this.editor.getText();this.ui.stop();try{let result=await editInExternalEditor({command:editorCmd,content});result.status==="complete"&&this.editor.setText(result.content)}finally{this.ui.start(),this.ui.requestRender(!0)}}clearEditor(){this.editor.setText(""),this.ui.requestRender()}showError(errorMessage2){this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("error",`Error: ${errorMessage2}`),this.outputPad,0)),this.ui.requestRender()}showWarning(warningMessage){this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Text(theme.fg("warning",`Warning: ${warningMessage}`),1,0)),this.ui.requestRender()}showNewVersionNotification(release){let action=theme.fg("accent",`${APP_NAME} update`),updateInstruction=theme.fg("muted",`New version ${release.version} is available. Run `)+action,changelogUrl=process.env.AGENT_FORGE_CHANGELOG_URL,changelogLine=changelogUrl?theme.fg("muted","Changelog: ")+(getCapabilities().hyperlinks?hyperlink(theme.fg("accent",changelogUrl),changelogUrl):theme.fg("accent",changelogUrl)):theme.fg("muted","Changelog URL is not configured."),note=release.note?.trim();this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new DynamicBorder(text=>theme.fg("warning",text))),this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning","Update Available"))}
1379
1379
  ${updateInstruction}`,1,0)),note&&(this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Markdown(note,1,0,this.getMarkdownThemeWithSettings(),{color:text=>theme.fg("muted",text)})),this.chatContainer.addChild(new Spacer(1))),this.chatContainer.addChild(new Text(changelogLine,1,0)),this.chatContainer.addChild(new DynamicBorder(text=>theme.fg("warning",text))),this.ui.requestRender()}showPackageUpdateNotification(packages){let action=theme.fg("accent",`${APP_NAME} update --extensions`),updateInstruction=theme.fg("muted","Package updates are available. Run ")+action,packageLines=packages.map(pkg2=>`- ${pkg2}`).join(`
1380
1380
  `);this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new DynamicBorder(text=>theme.fg("warning",text))),this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning","Package Updates Available"))}
@@ -1487,7 +1487,7 @@ Auth commands require at least one of --provider or --model. Checks refresh expi
1487
1487
  ${content}
1488
1488
  </file>
1489
1489
  `}catch(error2){let message=error2 instanceof Error?error2.message:String(error2);console.error(source_default.red(`Error: Could not read file ${absolutePath}: ${message}`)),process.exit(1)}}return{text,images}}function buildInitialMessage({parsed,fileText,fileImages,stdinContent}){let parts=[];return stdinContent!==void 0&&parts.push(stdinContent),fileText&&parts.push(fileText),parsed.messages.length>0&&(parts.push(parsed.messages[0]),parsed.messages.shift()),{initialMessage:parts.length>0?parts.join(""):void 0,initialImages:fileImages&&fileImages.length>0?fileImages:void 0}}function formatTokenCount(count){if(count>=1e6){let millions=count/1e6;return millions%1===0?`${millions}M`:`${millions.toFixed(1)}M`}if(count>=1e3){let thousands=count/1e3;return thousands%1===0?`${thousands}K`:`${thousands.toFixed(1)}K`}return count.toString()}async function listModels(modelRuntime,searchPattern,signal){let loadError=modelRuntime.getError();loadError&&console.error(source_default.yellow(`Warning: errors loading models.json:
1490
- ${loadError}`));let models=[...await modelRuntime.getAvailable(void 0,{signal})];if(models.length===0){console.log(formatNoModelsAvailableMessage());return}let filteredModels=models;if(searchPattern&&(filteredModels=fuzzyFilter(models,searchPattern,m2=>`${m2.provider} ${m2.id}`)),filteredModels.length===0){console.log(`No models matching "${searchPattern}"`);return}filteredModels.sort((a,b2)=>{let providerCmp=a.provider.localeCompare(b2.provider);return providerCmp!==0?providerCmp:a.id.localeCompare(b2.id)});let rows=filteredModels.map(m2=>({provider:m2.provider,model:m2.id,context:formatTokenCount(m2.contextWindow),maxOut:formatTokenCount(m2.maxTokens),thinking:m2.reasoning?"yes":"no",images:m2.input.includes("image")?"yes":"no"})),headers={provider:"provider",model:"model",context:"context",maxOut:"max-out",thinking:"thinking",images:"images"},widths={provider:Math.max(headers.provider.length,...rows.map(r=>r.provider.length)),model:Math.max(headers.model.length,...rows.map(r=>r.model.length)),context:Math.max(headers.context.length,...rows.map(r=>r.context.length)),maxOut:Math.max(headers.maxOut.length,...rows.map(r=>r.maxOut.length)),thinking:Math.max(headers.thinking.length,...rows.map(r=>r.thinking.length)),images:Math.max(headers.images.length,...rows.map(r=>r.images.length))},headerLine=[headers.provider.padEnd(widths.provider),headers.model.padEnd(widths.model),headers.context.padEnd(widths.context),headers.maxOut.padEnd(widths.maxOut),headers.thinking.padEnd(widths.thinking),headers.images.padEnd(widths.images)].join(" ");console.log(headerLine);for(let row of rows){let line=[row.provider.padEnd(widths.provider),row.model.padEnd(widths.model),row.context.padEnd(widths.context),row.maxOut.padEnd(widths.maxOut),row.thinking.padEnd(widths.thinking),row.images.padEnd(widths.images)].join(" ");console.log(line)}}import{join as join59}from"node:path";function printResponse(response2,write){write(response2.text),response2.status!=="succeeded"&&(process.exitCode=1)}function buildMarketCli(options){let{market,overrides}=options;return createPluginEcosystemCliV1({host:overrides?.host??defaultPluginHostFactsV1(),manifests:listBuiltinPluginManifestsV1(),registry:overrides?.registry??market?.cliRegistry,...market?.acquisition===void 0?{}:{acquisition:market.acquisition},installer:overrides?.installer??market?.installer,...overrides?.distribution!==void 0||market?.distribution!==void 0?{distribution:overrides?.distribution??market.distribution}:{},stateStore:overrides?.stateStore??market?.stateStore??createPluginStateStoreV1({filePath:join59(options.agentDir,"plugin-state.json")}),projectStateStore:overrides?.projectStateStore??market?.projectStateStore??createPluginStateStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,"plugin-state.json")}),projectScopeRef:projectPluginScopeRefV1(options.cwd),selectionStore:overrides?.selectionStore??createPluginSelectionStoreV1({filePath:join59(options.agentDir,".plugin-selection.json")}),projectSelectionStore:overrides?.projectSelectionStore??createPluginSelectionStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,".plugin-selection.json")})})}async function createDefaultPluginManagerControllerV1(options){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=await createDefaultPluginMarketWiringV1({agentDir,cwd}),cli=buildMarketCli({agentDir,cwd,market});return{controller:createPluginManagerControllerV1({registry:market.registry,stateStore:options.scope==="project"?market.projectStateStore:market.stateStore,cli}),close:market.close}}async function handlePluginEcosystemCommand(args,options={}){if(args[0]!=="plugin")return!1;let write=options.write??(line=>console.log(line)),agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let response2=await buildMarketCli({agentDir,cwd,market,overrides:options}).execute({argv:args.slice(1)});return printResponse(response2,write),!0}finally{await market?.close()}}import{join as join60}from"node:path";var DEFAULT_DURABLE_LOG_RELATIVE_PATH=join60("durable","remote-server-ops.jsonl");function isAddrInUse(error2){return typeof error2=="object"&&error2!==null&&error2.code==="EADDRINUSE"}async function runServeMode(port,options){let handle,createListener=options?.createListener??(()=>createWsServerListener({port,httpRequestHandler:(request,response2)=>handle?.server.handleArtifactHttpRequest(request,response2)??!1,onError:error2=>{console.error(`remote-server error: ${error2.message}`)}})),startServer=options?.startServer??startCodingAgentRemoteServer,workspaceRoots=options?.workspaceRoots,sessionDir=options?.sessionDir,durable=options?.durable??createDurableService({backend:createFileDurableStoreBackend({path:join60(getAgentDir(),DEFAULT_DURABLE_LOG_RELATIVE_PATH)})}),writerId=readOrCreateWriterId(getAgentDir());try{handle=await startServer({sessionSourceOptions:{sessionsDir:sessionDir??getSessionsDir(),cwd:process.cwd(),agentDir:getAgentDir(),...workspaceRoots===void 0||workspaceRoots.length===0?{}:{workspaceRoots},agentTaskResults:{store:durable,writerId},subagentPoolFromSelfInvocation:!0,...options?.hostLogger===void 0?{}:{hostLogger:options.hostLogger}},listeners:[createListener()],onError:error2=>{console.error(`remote-server error: ${error2.message}`)},durable,writerId})}catch(error2){throw isAddrInUse(error2)&&(console.error(`Port ${port} is already in use`),process.exit(1)),error2}let closing=!1,shutdown=()=>{closing||(closing=!0,handle.close().then(()=>{process.exit(0)}).catch(error2=>{console.error(`Remote server shutdown failed: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}))};process.on("SIGINT",shutdown),process.on("SIGTERM",shutdown),console.log(`Remote server listening on ${handle.addresses.join(", ")}`)}import{existsSync as existsSync29}from"fs";var THEME_OPTIONS=[{value:"dark",label:"Dark"},{value:"light",label:"Light"}],ANALYTICS_OPTIONS=[{value:!0,label:"Share anonymous usage data"},{value:!1,label:"Don't share"}],SETUP_LOGO_LINES=["\u2588\u2588\u2588\u2588\u2588\u2588","\u2588\u2588 \u2588\u2588","\u2588\u2588\u2588\u2588 \u2588\u2588","\u2588\u2588 \u2588\u2588"],FirstTimeSetupComponent=class extends Container{step="theme";themeIndex;analyticsIndex=0;options;constructor(options){super(),this.options=options,this.themeIndex=Math.max(0,THEME_OPTIONS.findIndex(option=>option.value===options.detectedTheme)),this.update()}update(){this.clear(),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",SETUP_LOGO_LINES.join(`
1490
+ ${loadError}`));let models=[...await modelRuntime.getAvailable(void 0,{signal})];if(models.length===0){console.log(formatNoModelsAvailableMessage());return}let filteredModels=models;if(searchPattern&&(filteredModels=fuzzyFilter(models,searchPattern,m2=>`${m2.provider} ${m2.id}`)),filteredModels.length===0){console.log(`No models matching "${searchPattern}"`);return}filteredModels.sort((a,b2)=>{let providerCmp=a.provider.localeCompare(b2.provider);return providerCmp!==0?providerCmp:a.id.localeCompare(b2.id)});let rows=filteredModels.map(m2=>({provider:m2.provider,model:m2.id,context:formatTokenCount(m2.contextWindow),maxOut:formatTokenCount(m2.maxTokens),thinking:m2.reasoning?"yes":"no",images:m2.input.includes("image")?"yes":"no"})),headers={provider:"provider",model:"model",context:"context",maxOut:"max-out",thinking:"thinking",images:"images"},widths={provider:Math.max(headers.provider.length,...rows.map(r=>r.provider.length)),model:Math.max(headers.model.length,...rows.map(r=>r.model.length)),context:Math.max(headers.context.length,...rows.map(r=>r.context.length)),maxOut:Math.max(headers.maxOut.length,...rows.map(r=>r.maxOut.length)),thinking:Math.max(headers.thinking.length,...rows.map(r=>r.thinking.length)),images:Math.max(headers.images.length,...rows.map(r=>r.images.length))},headerLine=[headers.provider.padEnd(widths.provider),headers.model.padEnd(widths.model),headers.context.padEnd(widths.context),headers.maxOut.padEnd(widths.maxOut),headers.thinking.padEnd(widths.thinking),headers.images.padEnd(widths.images)].join(" ");console.log(headerLine);for(let row of rows){let line=[row.provider.padEnd(widths.provider),row.model.padEnd(widths.model),row.context.padEnd(widths.context),row.maxOut.padEnd(widths.maxOut),row.thinking.padEnd(widths.thinking),row.images.padEnd(widths.images)].join(" ");console.log(line)}}import{join as join59}from"node:path";function printResponse(response2,write){write(response2.text),response2.status!=="succeeded"&&(process.exitCode=1)}function buildMarketCli(options){let{market,overrides}=options;return createPluginEcosystemCliV1({host:overrides?.host??defaultPluginHostFactsV1(),manifests:listBuiltinPluginManifestsV1(),registry:overrides?.registry??market?.cliRegistry,...market?.acquisition===void 0?{}:{acquisition:market.acquisition},installer:overrides?.installer??market?.installer,...overrides?.distribution!==void 0||market?.distribution!==void 0?{distribution:overrides?.distribution??market.distribution}:{},stateStore:overrides?.stateStore??market?.stateStore??createPluginStateStoreV1({filePath:join59(options.agentDir,"plugin-state.json")}),projectStateStore:overrides?.projectStateStore??market?.projectStateStore??createPluginStateStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,"plugin-state.json")}),projectScopeRef:projectPluginScopeRefV1(options.cwd),selectionStore:overrides?.selectionStore??createPluginSelectionStoreV1({filePath:join59(options.agentDir,".plugin-selection.json")}),projectSelectionStore:overrides?.projectSelectionStore??createPluginSelectionStoreV1({filePath:join59(options.cwd,CONFIG_DIR_NAME,".plugin-selection.json")})})}async function createDefaultPluginManagerControllerV1(options){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=await createDefaultPluginMarketWiringV1({agentDir,cwd}),cli=buildMarketCli({agentDir,cwd,market});return{controller:createPluginManagerControllerV1({registry:market.registry,stateStore:options.scope==="project"?market.projectStateStore:market.stateStore,cli}),close:market.close}}async function handlePluginEcosystemCommand(args,options={}){if(args[0]!=="plugin")return!1;let write=options.write??(line=>console.log(line));if(args[1]==="update"&&args[2]==="--all")return await runBatchUpdate(args.slice(3),options,write),!0;let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let response2=await buildMarketCli({agentDir,cwd,market,overrides:options}).execute({argv:args.slice(1)});return printResponse(response2,write),!0}finally{await market?.close()}}async function runBatchUpdate(restArgs,options,write){let agentDir=options.agentDir??getAgentDir(),cwd=options.cwd??process.cwd(),scopeIndex=restArgs.indexOf("--scope"),scope=scopeIndex!==-1&&restArgs[scopeIndex+1]==="project"?"project":"global",market=options.registry===void 0&&options.installer===void 0?await createDefaultPluginMarketWiringV1({agentDir,cwd}):void 0;try{let cli=buildMarketCli({agentDir,cwd,market,overrides:options}),listResponse=await cli.execute({argv:["state","list","--scope",scope]});if(listResponse.status!=="succeeded"){printResponse(listResponse,write);return}let entries=(listResponse.data?.entries??[]).filter(entry=>entry.lifecycle==="active"&&entry.scope===scope);if(entries.length===0){write("No active plugins to update.");return}let updated=[],current=[],failed=[];for(let entry of entries){let response2=await cli.execute({argv:["update",entry.pluginId,"--scope",scope]});response2.status==="succeeded"?(updated.push(entry.pluginId),write(response2.text)):response2.error?.code==="already_installed"?current.push(entry.pluginId):(failed.push(entry.pluginId),write(response2.text))}let summary=[`updated ${updated.length}${updated.length>0?` (${updated.join(", ")})`:""}`,`already up to date ${current.length}${current.length>0?` (${current.join(", ")})`:""}`,`failed ${failed.length}${failed.length>0?` (${failed.join(", ")})`:""}`].join("; ");write(`plugin update --all [${scope}]: ${summary}`),failed.length>0&&(process.exitCode=1)}finally{await market?.close()}}import{join as join60}from"node:path";var DEFAULT_DURABLE_LOG_RELATIVE_PATH=join60("durable","remote-server-ops.jsonl");function isAddrInUse(error2){return typeof error2=="object"&&error2!==null&&error2.code==="EADDRINUSE"}async function runServeMode(port,options){let handle,createListener=options?.createListener??(()=>createWsServerListener({port,httpRequestHandler:(request,response2)=>handle?.server.handleArtifactHttpRequest(request,response2)??!1,onError:error2=>{console.error(`remote-server error: ${error2.message}`)}})),startServer=options?.startServer??startCodingAgentRemoteServer,workspaceRoots=options?.workspaceRoots,sessionDir=options?.sessionDir,durable=options?.durable??createDurableService({backend:createFileDurableStoreBackend({path:join60(getAgentDir(),DEFAULT_DURABLE_LOG_RELATIVE_PATH)})}),writerId=readOrCreateWriterId(getAgentDir());try{handle=await startServer({sessionSourceOptions:{sessionsDir:sessionDir??getSessionsDir(),cwd:process.cwd(),agentDir:getAgentDir(),...workspaceRoots===void 0||workspaceRoots.length===0?{}:{workspaceRoots},agentTaskResults:{store:durable,writerId},subagentPoolFromSelfInvocation:!0,...options?.hostLogger===void 0?{}:{hostLogger:options.hostLogger}},listeners:[createListener()],onError:error2=>{console.error(`remote-server error: ${error2.message}`)},durable,writerId})}catch(error2){throw isAddrInUse(error2)&&(console.error(`Port ${port} is already in use`),process.exit(1)),error2}let closing=!1,shutdown=()=>{closing||(closing=!0,handle.close().then(()=>{process.exit(0)}).catch(error2=>{console.error(`Remote server shutdown failed: ${error2 instanceof Error?error2.message:String(error2)}`),process.exit(1)}))};process.on("SIGINT",shutdown),process.on("SIGTERM",shutdown),console.log(`Remote server listening on ${handle.addresses.join(", ")}`)}import{existsSync as existsSync29}from"fs";var THEME_OPTIONS=[{value:"dark",label:"Dark"},{value:"light",label:"Light"}],ANALYTICS_OPTIONS=[{value:!0,label:"Share anonymous usage data"},{value:!1,label:"Don't share"}],SETUP_LOGO_LINES=["\u2588\u2588\u2588\u2588\u2588\u2588","\u2588\u2588 \u2588\u2588","\u2588\u2588\u2588\u2588 \u2588\u2588","\u2588\u2588 \u2588\u2588"],FirstTimeSetupComponent=class extends Container{step="theme";themeIndex;analyticsIndex=0;options;constructor(options){super(),this.options=options,this.themeIndex=Math.max(0,THEME_OPTIONS.findIndex(option=>option.value===options.detectedTheme)),this.update()}update(){this.clear(),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",SETUP_LOGO_LINES.join(`
1491
1491
  `)),1,0)),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",theme.bold(`Welcome to ${APP_NAME}, the minimal coding agent.`)),1,0)),this.addChild(new Spacer(1)),this.step==="theme"?(this.addChild(new Text(theme.fg("text","Pick a theme."),1,0)),this.addChild(new Text(theme.fg("muted",`Detected system appearance: ${this.options.detectedTheme}`),1,0)),this.addChild(new Spacer(1)),this.addOptionList(THEME_OPTIONS.map(option=>option.label),this.themeIndex)):(this.addChild(new Text(theme.fg("text","Opt-in to anonymous usage data sharing?"),1,0)),this.addChild(new Text(theme.fg("muted",`Opting in stores a tracking identifier in settings.json and enables anonymous
1492
1492
  usage analytics. This helps us to better debug, reproduce, and resolve issues
1493
1493
  and bugs within Agent Forge. You can observe what is shared using /privacy and make
@@ -1503,7 +1503,7 @@ changes anytime in settings.json.`),1,0)),this.addChild(new Spacer(1)),this.addO
1503
1503
  ${value.stack}`}
1504
1504
  `}return`${JSON.stringify(toSafeJson(value))}
1505
1505
  `}function createHostLogger(options){if(options.level!==void 0&&!HOST_LOG_LEVELS.includes(options.level))throw new Error(`Host logger level must be one of ${HOST_LOG_LEVELS.map(level=>`"${level}"`).join(" | ")}; got ${JSON.stringify(options.level)}`);let minRank=LEVEL_RANK[options.level??"info"],now=options.now??Date.now,maxAgeDays=options.maxAgeDays??DEFAULT_MAX_AGE_DAYS,processHost=options.processHost??NODE_PROCESS_HOST,closed=!1,dirReady=!1,written=0,failed=0,write=(level,src,msg,context)=>{if(closed||LEVEL_RANK[level]<minRank)return;let entry={v:1,t:now(),level,src,msg,sessionId:context?.sessionId,traceId:context?.traceId,fields:context?.fields===void 0?void 0:toSafeJson(context.fields),cause:context?.cause===void 0?void 0:boundCause(context.cause)};try{dirReady||(mkdirSync19(options.dir,{recursive:!0}),dirReady=!0),appendFileSync4(join61(options.dir,logFileName(entry.t)),`${JSON.stringify(entry)}
1506
- `),written+=1}catch{failed+=1,dirReady=!1}};(()=>{if(maxAgeDays<=0)return;let cutoff=now()-maxAgeDays*DAY_MS,currentName=logFileName(now()),names2;try{names2=readdirSync16(options.dir)}catch(error2){if(error2.code==="ENOENT")return;write("warn","logger","log sweep failed: cannot read log directory",{cause:error2});return}let removed=0,errors=0;for(let name of names2){if(!name.endsWith(".log")||name===currentName)continue;let fullPath=join61(options.dir,name);try{let stats=statSync18(fullPath);if(!stats.isFile()||stats.mtimeMs>=cutoff)continue;unlinkSync4(fullPath),removed+=1}catch{errors+=1}}errors>0&&write("warn","logger","log sweep finished with failures",{fields:{removed,errors}})})();let exit=processHost.exit??NODE_PROCESS_CRASH_HOST.exit,writeStderr=processHost.writeStderr??NODE_PROCESS_CRASH_HOST.writeStderr,deferThrow=processHost.deferThrow??NODE_PROCESS_CRASH_HOST.deferThrow,loggedFatalValues=new WeakSet,isFatalValueLogged=value=>value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.has(value),markFatalValueLogged=value=>{value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.add(value)};return processHost.onUncaughtException&&processHost.onUncaughtException(error2=>{isFatalValueLogged(error2)||(markFatalValueLogged(error2),write("error","process","uncaughtException",{cause:error2})),writeStderr(fatalStderrText(error2)),exit(1)}),processHost.onUnhandledRejection&&processHost.onUnhandledRejection(reason=>{markFatalValueLogged(reason),write("error","process","unhandledRejection",{cause:reason}),deferThrow(()=>{throw reason})}),{debug:(src,msg,context)=>write("debug",src,msg,context),info:(src,msg,context)=>write("info",src,msg,context),warn:(src,msg,context)=>write("warn",src,msg,context),error:(src,msg,context)=>write("error",src,msg,context),close:()=>(closed=!0,{written,failed})}}function collectSettingsDiagnostics(settingsManager){return settingsManager.drainErrors().map(({scope,path:path15,error:error2})=>({type:"warning",message:path15?`Invalid settings file ${path15}: ${error2.message}`:`Invalid ${scope} settings: ${error2.message}`}))}function deduplicateDiagnostics(diagnostics){let seen=new Set;return diagnostics.filter(diagnostic5=>{let key=`${diagnostic5.type}\0${diagnostic5.message}`;return seen.has(key)?!1:(seen.add(key),!0)})}import{readdirSync as readdirSync17,statSync as statSync19,unlinkSync as unlinkSync5}from"node:fs";import{join as join62}from"node:path";var DAY_MS2=1440*60*1e3,TRACE_FILE_SUFFIX=".trace.jsonl";function sweepTraceFiles(sessionsRoot,options){if(options.maxAgeDays<=0)return{scanned:0,deleted:0,failed:0};let now=options.now??Date.now,unlink4=options.unlink??(path15=>unlinkSync5(path15)),cutoff=now()-options.maxAgeDays*DAY_MS2,scanned=0,deleted=0,failed=0,readEntries=dir=>{try{return readdirSync17(dir,{withFileTypes:!0})}catch{return}},sweepFilesIn=(dir,entries)=>{for(let entry of entries){if(!entry.name.endsWith(TRACE_FILE_SUFFIX))continue;let fullPath=join62(dir,entry.name),isFile=!1,isExpired=!1;try{let stats=statSync19(fullPath);isFile=stats.isFile(),isExpired=isFile&&stats.mtimeMs<cutoff}catch{continue}if(isFile&&(scanned+=1,!!isExpired))try{unlink4(fullPath),deleted+=1}catch{failed+=1}}},rootEntries=readEntries(sessionsRoot);if(rootEntries===void 0)return{scanned:0,deleted:0,failed:0};sweepFilesIn(sessionsRoot,rootEntries);for(let entry of rootEntries){if(!entry.isDirectory())continue;let subdirectory=join62(sessionsRoot,entry.name),subEntries=readEntries(subdirectory);subEntries!==void 0&&sweepFilesIn(subdirectory,subEntries)}return{scanned,deleted,failed}}import{join as join63}from"node:path";var FACTORY_PLUGIN_RANGE=`^${VERSION}`,BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1=Object.freeze([{pluginId:"agent-forge.plugin.goal",npmName:"@ai-agent-forge/plugin-goal",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.plan",npmName:"@ai-agent-forge/plugin-plan",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.todo-set",npmName:"@ai-agent-forge/plugin-todo-set",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.session-share",npmName:"@ai-agent-forge/plugin-session-share",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.observability",npmName:"@ai-agent-forge/plugin-observability",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.subagent-delegate",npmName:"@ai-agent-forge/plugin-subagent-delegate",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.memory",npmName:"@ai-agent-forge/plugin-memory",range:FACTORY_PLUGIN_RANGE}]);var PLUGIN_BOOTSTRAP_VERSION_V1=1;function satisfiesRangeV1(version,range2){return selectNpmPackageVersionV1([version],range2)===version}function pluginBootstrapInstallCommandV1(entry){return`agent-forge plugin install ${entry.npmName}@${entry.range??"latest"}`}function errorMessage(error2){return error2 instanceof Error?error2.message:String(error2)}function acquireErrorCode(error2){return error2 instanceof PluginAcquisitionErrorV1?error2.code:"install_failed"}function actionOf(entry,status2,reason){return Object.freeze({pluginId:entry.pluginId,status:status2,reason,npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range}})}async function runPluginBootstrapV1(input){let now=input.deps.now??Date.now,startedAt=now(),finish=(status3,actions2,diagnostics2)=>Object.freeze({version:PLUGIN_BOOTSTRAP_VERSION_V1,status:status3,actions:Object.freeze([...actions2]),diagnostics:Object.freeze([...diagnostics2]),durationMs:Math.max(0,now()-startedAt)});if(input.manifest.length===0)return finish("succeeded",[],[]);let signal=input.deps.signal,active;try{active=await input.deps.listActive({...signal===void 0?{}:{signal}})}catch(error2){return finish("failed",[],[{code:"list_active_failed",message:`Active plugin state could not be read; bootstrap installed nothing: ${errorMessage(error2)}`}])}let actions=[],diagnostics=[];for(let entry of input.manifest){if(signal?.aborted===!0){diagnostics.push({code:"cancelled",message:"Plugin bootstrap was cancelled before all factory entries were processed"});break}let activeVersion=active.get(entry.pluginId);if(activeVersion!==void 0){if(satisfiesRangeV1(activeVersion,entry.range)){actions.push(Object.freeze({...actionOf(entry,"skipped","satisfies_range"),activeVersion}));continue}actions.push(Object.freeze({...actionOf(entry,"diagnosed","range_not_satisfied"),activeVersion})),diagnostics.push({code:"range_not_satisfied",pluginId:entry.pluginId,message:`Active version ${activeVersion} of ${entry.pluginId} does not satisfy the factory range ${entry.range??"latest"}; bootstrap never replaces active installations. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install a matching version.`});continue}try{let installed=await input.deps.installFromNpm({npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range},...signal===void 0?{}:{signal}});actions.push(Object.freeze({...actionOf(entry,"installed","installed"),installedVersion:installed.pluginVersion,source:installed.source}))}catch(error2){let errorCode2=acquireErrorCode(error2);actions.push(Object.freeze({...actionOf(entry,"failed","install_failed"),errorCode:errorCode2})),diagnostics.push({code:"install_failed",pluginId:entry.pluginId,message:`Bootstrap could not install ${entry.pluginId} from npm (${errorCode2}: ${errorMessage(error2)}). Startup continues without it; its capabilities stay unavailable until installed. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install it manually.`})}}let status2=actions.some(action=>action.status==="failed")?"failed":actions.some(action=>action.status==="diagnosed")?"degraded":"succeeded";return finish(status2,actions,diagnostics)}var AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1="AGENT_FORGE_PLUGIN_BOOTSTRAP",PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1="off";function readActiveVersions(store,scope,scopeRef,signal){return(async()=>{let result=await store.read({...signal===void 0?{}:{signal}});if(result.status!=="ok"&&result.status!=="missing")throw new Error(`plugin state read failed (${result.diagnostics[0]?.code??result.status}) for the ${scope} scope`);let versions=new Map;for(let record of result.snapshot.records)record.state.scope!==scope||record.state.scopeRef!==scopeRef||record.state.lifecycle==="active"&&versions.set(record.pluginId,record.pluginVersion);return versions})()}async function runNodePluginBootstrapV1(options){if(process.env[AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1]?.trim()===PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1)return Object.freeze({version:1,status:"succeeded",actions:Object.freeze([]),diagnostics:Object.freeze([]),durationMs:0,skipped:"disabled"});if(options.deps!==void 0)return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps:options.deps});let session,ensureSession=async()=>{if(session!==void 0)return session;let acquisition=createNodePluginAcquisitionHostV1({...options.npmRegistry===void 0?{}:{npmRegistry:options.npmRegistry},...options.npmToken===void 0?{}:{npmToken:options.npmToken},...options.fetch===void 0?{}:{fetch:options.fetch},...options.limits===void 0?{}:{limits:options.limits}}),installHost=await createNodePackageInstallHostV1({openArtifact:input=>acquisition.openArtifact(input),installationDirectory:defaultPluginInstallStoreDirectoryV1(options.agentDir),persistence:"persistent",supportedScopes:["global","project"],...options.limits===void 0?{}:{...options.limits}});return session={acquisition,installHost,installer:createPluginInstallerV1({host:installHost}),stateStore:createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)})},session},deps={listActive:async({signal})=>{let globalVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)}),"global",DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,signal),projectVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.cwd,CONFIG_DIR_NAME,DEFAULT_PLUGIN_STATE_FILE_V1)}),"project",projectPluginScopeRefV1(options.cwd),signal),[globalResult,projectResult]=await Promise.all([globalVersions,projectVersions]);return new Map([...globalResult,...projectResult])},installFromNpm:async({npmName,range:range2,signal})=>{let active=await ensureSession(),ref=range2===void 0?npmName:`${npmName}@${range2}`,acquired=await active.acquisition.resolvePackage({ref,...signal===void 0?{}:{signal}}),released=!1,release=async()=>{released||(released=!0,await acquired.release())};try{let verified=active.installer.prepare({manifest:acquired.manifest,source:acquired.source,host:defaultPluginHostFactsV1()});if(verified.status!=="verified")throw new Error(`installer prepare rejected ${acquired.manifest.id}: ${verified.reason}`);let installed=await active.installer.install({record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,artifact:acquired.artifact,...signal===void 0?{}:{signal}});if(installed.status!=="succeeded")throw new Error(`plugin install failed (${installed.error.code}) for ${acquired.manifest.id}`);let activated=await active.installer.activate({installation:installed.installation,record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,...signal===void 0?{}:{signal}});if(activated.status!=="succeeded")throw await active.installer.remove({installation:installed.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin activation failed (${activated.error.code}) for ${acquired.manifest.id}`);let persisted=await active.stateStore.upsert({installation:activated.installation,scope:"global",enabled:!0,source:acquired.source,...signal===void 0?{}:{signal}});if(persisted.status!=="ok")throw await active.installer.remove({installation:activated.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin state persist failed (${persisted.status}) for ${acquired.manifest.id}`);return{pluginVersion:activated.installation.pluginVersion,source:acquired.source}}finally{await release()}},...options.signal===void 0?{}:{signal:options.signal}};try{return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps})}finally{let active=session;session=void 0,active!==void 0&&(await active.installHost.close().catch(()=>{}),await active.acquisition.close().catch(()=>{}))}}import{existsSync as existsSync31,mkdirSync as mkdirSync20,readdirSync as readdirSync18,readFileSync as readFileSync27,renameSync as renameSync4,rmSync as rmSync6,writeFileSync as writeFileSync17}from"fs";import{dirname as dirname30,join as join64}from"path";var MIGRATION_GUIDE_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/CHANGELOG.md#extensions-migration",EXTENSIONS_DOC_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/docs/extensions.md";function migrateAuthToAuthJson(){let agentDir=getAgentDir(),authPath=join64(agentDir,"auth.json"),oauthPath=join64(agentDir,"oauth.json"),settingsPath=join64(agentDir,"settings.json");if(existsSync31(authPath))return[];let migrated={},providers=[];if(existsSync31(oauthPath))try{let oauth=JSON.parse(stripBom(readFileSync27(oauthPath,"utf-8")));for(let[provider,cred]of Object.entries(oauth))migrated[provider]={type:"oauth",...cred},providers.push(provider);renameSync4(oauthPath,`${oauthPath}.migrated`)}catch{}if(existsSync31(settingsPath))try{let content=readFileSync27(settingsPath,"utf-8"),settings2=JSON.parse(stripBom(content));if(settings2.apiKeys&&typeof settings2.apiKeys=="object"){for(let[provider,key]of Object.entries(settings2.apiKeys))!migrated[provider]&&typeof key=="string"&&(migrated[provider]={type:"api_key",key},providers.push(provider));delete settings2.apiKeys,writeFileSync17(settingsPath,JSON.stringify(settings2,null,2))}}catch{}return Object.keys(migrated).length>0&&(mkdirSync20(dirname30(authPath),{recursive:!0}),writeFileSync17(authPath,JSON.stringify(migrated,null,2),{mode:384})),providers}function migrateSessionsFromAgentRoot(){let agentDir=getAgentDir(),files;try{files=readdirSync18(agentDir).filter(f=>f.endsWith(".jsonl")).map(f=>join64(agentDir,f))}catch{return}if(files.length!==0)for(let file of files)try{let firstLine=readFileSync27(file,"utf8").split(`
1506
+ `),written+=1}catch{failed+=1,dirReady=!1}};(()=>{if(maxAgeDays<=0)return;let cutoff=now()-maxAgeDays*DAY_MS,currentName=logFileName(now()),names2;try{names2=readdirSync16(options.dir)}catch(error2){if(error2.code==="ENOENT")return;write("warn","logger","log sweep failed: cannot read log directory",{cause:error2});return}let removed=0,errors=0;for(let name of names2){if(!name.endsWith(".log")||name===currentName)continue;let fullPath=join61(options.dir,name);try{let stats=statSync18(fullPath);if(!stats.isFile()||stats.mtimeMs>=cutoff)continue;unlinkSync4(fullPath),removed+=1}catch{errors+=1}}errors>0&&write("warn","logger","log sweep finished with failures",{fields:{removed,errors}})})();let exit=processHost.exit??NODE_PROCESS_CRASH_HOST.exit,writeStderr=processHost.writeStderr??NODE_PROCESS_CRASH_HOST.writeStderr,deferThrow=processHost.deferThrow??NODE_PROCESS_CRASH_HOST.deferThrow,loggedFatalValues=new WeakSet,isFatalValueLogged=value=>value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.has(value),markFatalValueLogged=value=>{value!==null&&(typeof value=="object"||typeof value=="function")&&loggedFatalValues.add(value)};return processHost.onUncaughtException&&processHost.onUncaughtException(error2=>{isFatalValueLogged(error2)||(markFatalValueLogged(error2),write("error","process","uncaughtException",{cause:error2})),writeStderr(fatalStderrText(error2)),exit(1)}),processHost.onUnhandledRejection&&processHost.onUnhandledRejection(reason=>{markFatalValueLogged(reason),write("error","process","unhandledRejection",{cause:reason}),deferThrow(()=>{throw reason})}),{debug:(src,msg,context)=>write("debug",src,msg,context),info:(src,msg,context)=>write("info",src,msg,context),warn:(src,msg,context)=>write("warn",src,msg,context),error:(src,msg,context)=>write("error",src,msg,context),close:()=>(closed=!0,{written,failed})}}function collectSettingsDiagnostics(settingsManager){return settingsManager.drainErrors().map(({scope,path:path15,error:error2})=>({type:"warning",message:path15?`Invalid settings file ${path15}: ${error2.message}`:`Invalid ${scope} settings: ${error2.message}`}))}function deduplicateDiagnostics(diagnostics){let seen=new Set;return diagnostics.filter(diagnostic5=>{let key=`${diagnostic5.type}\0${diagnostic5.message}`;return seen.has(key)?!1:(seen.add(key),!0)})}import{readdirSync as readdirSync17,statSync as statSync19,unlinkSync as unlinkSync5}from"node:fs";import{join as join62}from"node:path";var DAY_MS2=1440*60*1e3,TRACE_FILE_SUFFIX=".trace.jsonl";function sweepTraceFiles(sessionsRoot,options){if(options.maxAgeDays<=0)return{scanned:0,deleted:0,failed:0};let now=options.now??Date.now,unlink4=options.unlink??(path15=>unlinkSync5(path15)),cutoff=now()-options.maxAgeDays*DAY_MS2,scanned=0,deleted=0,failed=0,readEntries=dir=>{try{return readdirSync17(dir,{withFileTypes:!0})}catch{return}},sweepFilesIn=(dir,entries)=>{for(let entry of entries){if(!entry.name.endsWith(TRACE_FILE_SUFFIX))continue;let fullPath=join62(dir,entry.name),isFile=!1,isExpired=!1;try{let stats=statSync19(fullPath);isFile=stats.isFile(),isExpired=isFile&&stats.mtimeMs<cutoff}catch{continue}if(isFile&&(scanned+=1,!!isExpired))try{unlink4(fullPath),deleted+=1}catch{failed+=1}}},rootEntries=readEntries(sessionsRoot);if(rootEntries===void 0)return{scanned:0,deleted:0,failed:0};sweepFilesIn(sessionsRoot,rootEntries);for(let entry of rootEntries){if(!entry.isDirectory())continue;let subdirectory=join62(sessionsRoot,entry.name),subEntries=readEntries(subdirectory);subEntries!==void 0&&sweepFilesIn(subdirectory,subEntries)}return{scanned,deleted,failed}}import{join as join63}from"node:path";var FACTORY_PLUGIN_RANGE=`^${VERSION}`,BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1=Object.freeze([{pluginId:"agent-forge.plugin.goal",npmName:"@ai-agent-forge/plugin-goal",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.plan",npmName:"@ai-agent-forge/plugin-plan",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.todo-set",npmName:"@ai-agent-forge/plugin-todo-set",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.session-share",npmName:"@ai-agent-forge/plugin-session-share",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.observability",npmName:"@ai-agent-forge/plugin-observability",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.subagent-delegate",npmName:"@ai-agent-forge/plugin-subagent-delegate",range:FACTORY_PLUGIN_RANGE},{pluginId:"agent-forge.plugin.memory",npmName:"@ai-agent-forge/plugin-memory",range:FACTORY_PLUGIN_RANGE}]);var PLUGIN_BOOTSTRAP_VERSION_V1=1;function satisfiesRangeV1(version,range2){return selectNpmPackageVersionV1([version],range2)===version}function pluginBootstrapInstallCommandV1(entry){return`agent-forge plugin install ${entry.npmName}@${entry.range??"latest"}`}function errorMessage(error2){return error2 instanceof Error?error2.message:String(error2)}function acquireErrorCode(error2){return error2 instanceof PluginAcquisitionErrorV1?error2.code:"install_failed"}function actionOf(entry,status2,reason){return Object.freeze({pluginId:entry.pluginId,status:status2,reason,npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range}})}async function runPluginBootstrapV1(input){let now=input.deps.now??Date.now,startedAt=now(),finish=(status3,actions2,diagnostics2)=>Object.freeze({version:PLUGIN_BOOTSTRAP_VERSION_V1,status:status3,actions:Object.freeze([...actions2]),diagnostics:Object.freeze([...diagnostics2]),durationMs:Math.max(0,now()-startedAt)});if(input.manifest.length===0)return finish("succeeded",[],[]);let signal=input.deps.signal,active;try{active=await input.deps.listActive({...signal===void 0?{}:{signal}})}catch(error2){return finish("failed",[],[{code:"list_active_failed",message:`Active plugin state could not be read; bootstrap installed nothing: ${errorMessage(error2)}`}])}let actions=[],diagnostics=[];for(let entry of input.manifest){if(signal?.aborted===!0){diagnostics.push({code:"cancelled",message:"Plugin bootstrap was cancelled before all factory entries were processed"});break}let activeVersion=active.get(entry.pluginId);if(activeVersion!==void 0){if(satisfiesRangeV1(activeVersion,entry.range)){actions.push(Object.freeze({...actionOf(entry,"skipped","satisfies_range"),activeVersion}));continue}actions.push(Object.freeze({...actionOf(entry,"diagnosed","range_not_satisfied"),activeVersion})),diagnostics.push({code:"range_not_satisfied",pluginId:entry.pluginId,message:`Active version ${activeVersion} of ${entry.pluginId} does not satisfy the factory range ${entry.range??"latest"}; bootstrap never replaces active installations. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install a matching version, or \`agent-forge plugin update --all\` to upgrade every outdated plugin at once.`});continue}try{let installed=await input.deps.installFromNpm({npmName:entry.npmName,...entry.range===void 0?{}:{range:entry.range},...signal===void 0?{}:{signal}});actions.push(Object.freeze({...actionOf(entry,"installed","installed"),installedVersion:installed.pluginVersion,source:installed.source}))}catch(error2){let errorCode2=acquireErrorCode(error2);actions.push(Object.freeze({...actionOf(entry,"failed","install_failed"),errorCode:errorCode2})),diagnostics.push({code:"install_failed",pluginId:entry.pluginId,message:`Bootstrap could not install ${entry.pluginId} from npm (${errorCode2}: ${errorMessage(error2)}). Startup continues without it; its capabilities stay unavailable until installed. Run \`${pluginBootstrapInstallCommandV1(entry)}\` to install it manually.`})}}let status2=actions.some(action=>action.status==="failed")?"failed":actions.some(action=>action.status==="diagnosed")?"degraded":"succeeded";return finish(status2,actions,diagnostics)}var AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1="AGENT_FORGE_PLUGIN_BOOTSTRAP",PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1="off";function readActiveVersions(store,scope,scopeRef,signal){return(async()=>{let result=await store.read({...signal===void 0?{}:{signal}});if(result.status!=="ok"&&result.status!=="missing")throw new Error(`plugin state read failed (${result.diagnostics[0]?.code??result.status}) for the ${scope} scope`);let versions=new Map;for(let record of result.snapshot.records)record.state.scope!==scope||record.state.scopeRef!==scopeRef||record.state.lifecycle==="active"&&versions.set(record.pluginId,record.pluginVersion);return versions})()}async function runNodePluginBootstrapV1(options){if(process.env[AGENT_FORGE_PLUGIN_BOOTSTRAP_ENV_V1]?.trim()===PLUGIN_BOOTSTRAP_DISABLED_VALUE_V1)return Object.freeze({version:1,status:"succeeded",actions:Object.freeze([]),diagnostics:Object.freeze([]),durationMs:0,skipped:"disabled"});if(options.deps!==void 0)return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps:options.deps});let session,ensureSession=async()=>{if(session!==void 0)return session;let acquisition=createNodePluginAcquisitionHostV1({...options.npmRegistry===void 0?{}:{npmRegistry:options.npmRegistry},...options.npmToken===void 0?{}:{npmToken:options.npmToken},...options.fetch===void 0?{}:{fetch:options.fetch},...options.limits===void 0?{}:{limits:options.limits}}),installHost=await createNodePackageInstallHostV1({openArtifact:input=>acquisition.openArtifact(input),installationDirectory:defaultPluginInstallStoreDirectoryV1(options.agentDir),persistence:"persistent",supportedScopes:["global","project"],...options.limits===void 0?{}:{...options.limits}});return session={acquisition,installHost,installer:createPluginInstallerV1({host:installHost}),stateStore:createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)})},session},deps={listActive:async({signal})=>{let globalVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.agentDir,DEFAULT_PLUGIN_STATE_FILE_V1)}),"global",DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,signal),projectVersions=readActiveVersions(createPluginStateStoreV1({filePath:join63(options.cwd,CONFIG_DIR_NAME,DEFAULT_PLUGIN_STATE_FILE_V1)}),"project",projectPluginScopeRefV1(options.cwd),signal),[globalResult,projectResult]=await Promise.all([globalVersions,projectVersions]);return new Map([...globalResult,...projectResult])},installFromNpm:async({npmName,range:range2,signal})=>{let active=await ensureSession(),ref=range2===void 0?npmName:`${npmName}@${range2}`,acquired=await active.acquisition.resolvePackage({ref,...signal===void 0?{}:{signal}}),released=!1,release=async()=>{released||(released=!0,await acquired.release())};try{let verified=active.installer.prepare({manifest:acquired.manifest,source:acquired.source,host:defaultPluginHostFactsV1()});if(verified.status!=="verified")throw new Error(`installer prepare rejected ${acquired.manifest.id}: ${verified.reason}`);let installed=await active.installer.install({record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,artifact:acquired.artifact,...signal===void 0?{}:{signal}});if(installed.status!=="succeeded")throw new Error(`plugin install failed (${installed.error.code}) for ${acquired.manifest.id}`);let activated=await active.installer.activate({installation:installed.installation,record:verified.record,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1,...signal===void 0?{}:{signal}});if(activated.status!=="succeeded")throw await active.installer.remove({installation:installed.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin activation failed (${activated.error.code}) for ${acquired.manifest.id}`);let persisted=await active.stateStore.upsert({installation:activated.installation,scope:"global",enabled:!0,source:acquired.source,...signal===void 0?{}:{signal}});if(persisted.status!=="ok")throw await active.installer.remove({installation:activated.installation,scope:"global",scopeRef:DEFAULT_GLOBAL_PLUGIN_SCOPE_REF_V1}).catch(()=>{}),new Error(`plugin state persist failed (${persisted.status}) for ${acquired.manifest.id}`);return{pluginVersion:activated.installation.pluginVersion,source:acquired.source}}finally{await release()}},...options.signal===void 0?{}:{signal:options.signal}};try{return await runPluginBootstrapV1({manifest:options.manifest??BOOTSTRAP_FACTORY_PLUGIN_MANIFEST_V1,deps})}finally{let active=session;session=void 0,active!==void 0&&(await active.installHost.close().catch(()=>{}),await active.acquisition.close().catch(()=>{}))}}import{existsSync as existsSync31,mkdirSync as mkdirSync20,readdirSync as readdirSync18,readFileSync as readFileSync27,renameSync as renameSync4,rmSync as rmSync6,writeFileSync as writeFileSync17}from"fs";import{dirname as dirname30,join as join64}from"path";var MIGRATION_GUIDE_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/CHANGELOG.md#extensions-migration",EXTENSIONS_DOC_URL="https://github.com/agent-forge/agent-forge/blob/main/packages/agent-forge/docs/extensions.md";function migrateAuthToAuthJson(){let agentDir=getAgentDir(),authPath=join64(agentDir,"auth.json"),oauthPath=join64(agentDir,"oauth.json"),settingsPath=join64(agentDir,"settings.json");if(existsSync31(authPath))return[];let migrated={},providers=[];if(existsSync31(oauthPath))try{let oauth=JSON.parse(stripBom(readFileSync27(oauthPath,"utf-8")));for(let[provider,cred]of Object.entries(oauth))migrated[provider]={type:"oauth",...cred},providers.push(provider);renameSync4(oauthPath,`${oauthPath}.migrated`)}catch{}if(existsSync31(settingsPath))try{let content=readFileSync27(settingsPath,"utf-8"),settings2=JSON.parse(stripBom(content));if(settings2.apiKeys&&typeof settings2.apiKeys=="object"){for(let[provider,key]of Object.entries(settings2.apiKeys))!migrated[provider]&&typeof key=="string"&&(migrated[provider]={type:"api_key",key},providers.push(provider));delete settings2.apiKeys,writeFileSync17(settingsPath,JSON.stringify(settings2,null,2))}}catch{}return Object.keys(migrated).length>0&&(mkdirSync20(dirname30(authPath),{recursive:!0}),writeFileSync17(authPath,JSON.stringify(migrated,null,2),{mode:384})),providers}function migrateSessionsFromAgentRoot(){let agentDir=getAgentDir(),files;try{files=readdirSync18(agentDir).filter(f=>f.endsWith(".jsonl")).map(f=>join64(agentDir,f))}catch{return}if(files.length!==0)for(let file of files)try{let firstLine=readFileSync27(file,"utf8").split(`
1507
1507
  `)[0];if(!firstLine?.trim())continue;let header=JSON.parse(firstLine);if(header.type!=="session"||!header.cwd)continue;let safePath=`--${header.cwd.replace(/^[/\\]/,"").replace(/[/\\:]/g,"-")}--`,correctDir=join64(agentDir,"sessions",safePath);existsSync31(correctDir)||mkdirSync20(correctDir,{recursive:!0});let fileName=file.split("/").pop()||file.split("\\").pop(),newPath=join64(correctDir,fileName);if(existsSync31(newPath))continue;renameSync4(file,newPath)}catch{}}function migrateCommandsToPrompts(baseDir,label){let commandsDir=join64(baseDir,"commands"),promptsDir=join64(baseDir,"prompts");if(existsSync31(commandsDir)&&!existsSync31(promptsDir))try{return renameSync4(commandsDir,promptsDir),console.log(source_default.green(`Migrated ${label} commands/ \u2192 prompts/`)),!0}catch(err2){console.log(source_default.yellow(`Warning: Could not migrate ${label} commands/ to prompts/: ${err2 instanceof Error?err2.message:err2}`))}return!1}function migrateKeybindingsConfigFile(){let configPath=join64(getAgentDir(),"keybindings.json");if(existsSync31(configPath))try{let parsed=JSON.parse(stripBom(readFileSync27(configPath,"utf-8")));if(typeof parsed!="object"||parsed===null||Array.isArray(parsed))return;let{config,migrated}=migrateKeybindingsConfig(parsed);if(!migrated)return;writeFileSync17(configPath,`${JSON.stringify(config,null,2)}
1508
1508
  `,"utf-8")}catch{}}function migrateToolsToBin(){let agentDir=getAgentDir(),toolsDir=join64(agentDir,"tools"),binDir=getBinDir();if(!existsSync31(toolsDir))return;let binaries=["fd","rg","fd.exe","rg.exe"],movedAny=!1;for(let bin of binaries){let oldPath=join64(toolsDir,bin),newPath=join64(binDir,bin);if(existsSync31(oldPath))if(existsSync31(binDir)||mkdirSync20(binDir,{recursive:!0}),existsSync31(newPath))try{rmSync6?.(oldPath,{force:!0})}catch{}else try{renameSync4(oldPath,newPath),movedAny=!0}catch{}}movedAny&&console.log(source_default.green("Migrated managed binaries tools/ \u2192 bin/"))}function checkDeprecatedExtensionDirs(baseDir,label){let hooksDir=join64(baseDir,"hooks"),toolsDir=join64(baseDir,"tools"),warnings=[];if(existsSync31(hooksDir)&&warnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`),existsSync31(toolsDir))try{readdirSync18(toolsDir).filter(e=>{let lower=e.toLowerCase();return lower!=="fd"&&lower!=="rg"&&lower!=="fd.exe"&&lower!=="rg.exe"&&!e.startsWith(".")}).length>0&&warnings.push(`${label} tools/ directory contains custom tools. Custom tools have been merged into extensions.`)}catch{}return warnings}function migrateExtensionSystem(cwd){let agentDir=getAgentDir(),projectDir=join64(cwd,CONFIG_DIR_NAME);return migrateCommandsToPrompts(agentDir,"Global"),migrateCommandsToPrompts(projectDir,"Project"),[...checkDeprecatedExtensionDirs(agentDir,"Global"),...checkDeprecatedExtensionDirs(projectDir,"Project")]}async function showDeprecationWarnings(warnings){if(warnings.length!==0){for(let warning of warnings)console.log(source_default.yellow(`Warning: ${warning}`));console.log(source_default.yellow(`
1509
1509
  Move your extensions to the extensions/ directory.`)),console.log(source_default.yellow(`Migration guide: ${MIGRATION_GUIDE_URL}`)),console.log(source_default.yellow(`Documentation: ${EXTENSIONS_DOC_URL}`)),console.log()}}function runMigrations(cwd){let migratedAuthProviders=migrateAuthToAuthJson();migrateSessionsFromAgentRoot(),migrateToolsToBin(),migrateKeybindingsConfigFile();let deprecationWarnings=migrateExtensionSystem(cwd);return{migratedAuthProviders,deprecationWarnings}}import{existsSync as existsSync33,mkdirSync as mkdirSync22,mkdtempSync as mkdtempSync2,readdirSync as readdirSync19,readFileSync as readFileSync28,renameSync as renameSync6,rmSync as rmSync8,writeFileSync as writeFileSync18}from"node:fs";import{join as join67,resolve as resolve24}from"node:path";var import_proper_lockfile3=__toESM(require_proper_lockfile(),1);import{homedir as homedir10}from"node:os";import{basename as basename16,dirname as dirname31,join as join65,relative as relative12}from"node:path";var MAX_PROFILE_ID_CHARS=128,MAX_SELECTION_IDS=128,MAX_CATALOG_ENTRIES=256,MAX_DIAGNOSTIC_CODES2=16;function boundedCount(value,maximum){return value===void 0?{count:0,truncated:!1}:{count:Math.min(value.length,maximum),truncated:value.length>maximum}}function summarizePluginSelectionV1(selection){if(selection===void 0)return Object.freeze({present:!1,selectedCount:0,disabledCount:0,truncated:!1});let selected=boundedCount(selection.selectedPluginIds,MAX_SELECTION_IDS),disabled=boundedCount(selection.disabledPluginIds,MAX_SELECTION_IDS);return Object.freeze({present:!0,selectedCount:selected.count,disabledCount:disabled.count,truncated:selected.truncated||disabled.truncated})}function summarizePluginCatalogV1(catalog){if(catalog===void 0)return Object.freeze({present:!1,entryCount:0,readyCount:0,unavailableCount:0,truncated:!1});let entries=catalog.entries.slice(0,MAX_CATALOG_ENTRIES),readyCount=entries.filter(entry=>entry.resolution.status==="installed-ready").length;return Object.freeze({present:!0,entryCount:entries.length,readyCount,unavailableCount:entries.length-readyCount,truncated:catalog.truncated||catalog.entries.length>MAX_CATALOG_ENTRIES})}function validateProfileId(profileId){if(typeof profileId!="string"||profileId.trim().length===0||profileId.length>MAX_PROFILE_ID_CHARS||/[\u0000-\u001f]/u.test(profileId))throw new Error("invalid plugin selection profile ID");return profileId}function emptySelectionSummary(){return Object.freeze({present:!1,selectedCount:0,disabledCount:0,truncated:!1})}function diagnosticCodes2(result){return result.status==="ok"||result.status==="missing"?Object.freeze([]):Object.freeze(result.diagnostics.slice(0,MAX_DIAGNOSTIC_CODES2).map(item=>item.code))}function selectionForProfile2(result,profileId){return result.snapshot.selections.find(selection=>selection.profileId===profileId)}var PluginSelectionEntryComponent=class{profileId;store;controller;onOpen;onClose;requestRender;selection;catalog;uiProfile;uiPluginIndex=0;_focused=!1;get focused(){return this._focused}set focused(value){this._focused=value}constructor(options){if(this.profileId=validateProfileId(options.profileId),options.selection!==void 0&&options.selection.profileId!==this.profileId)throw new Error("plugin selection profile does not match the entry profile");this.store=options.store,this.controller=options.controller,this.onOpen=options.onOpen,this.onClose=options.onClose,this.requestRender=options.requestRender,this.selection=summarizePluginSelectionV1(options.selection),this.catalog=summarizePluginCatalogV1(options.catalog),this.uiProfile=options.snapshot?.profiles.find(profile=>profile.profileId===this.profileId)}hasHostEntry(){return this.store!==void 0||this.controller!==void 0||this.onOpen!==void 0}render(width){if(!this.hasHostEntry())return[truncateToWidth(theme.fg("dim"," Plugins: unsupported (host selection entry not injected)"),width,"...")];if(this._focused&&this.uiProfile!==void 0){let lines=[truncateToWidth(theme.bold(` Plugins \xB7 ${this.uiProfile.profileId}`),width,"...")];for(let[index3,plugin]of this.uiProfile.plugins.entries()){let cursor=index3===this.uiPluginIndex?">":" ",state2=plugin.state==="selected"?"on":plugin.state==="disabled"?"off":"available",availability=plugin.availability==="ready"?"ready":"unavailable";lines.push(truncateToWidth(` ${cursor} [${state2}] ${plugin.pluginId} (${availability})`,width,"..."))}return lines.push(truncateToWidth(theme.fg("dim"," Enter/Space toggle \xB7 Esc close"),width,"...")),lines}let selectionText=this.selection.present?`selected ${this.selection.selectedCount}, disabled ${this.selection.disabledCount}${this.selection.truncated?", bounded":""}`:this.store===void 0?"selection pending":"selection not loaded",catalogText=this.catalog.present?`catalog ${this.catalog.entryCount} (${this.catalog.readyCount} ready, ${this.catalog.unavailableCount} unavailable${this.catalog.truncated?", bounded":""})`:"catalog unavailable",suffix=this.onOpen===void 0?"host store":"open via host callback";return[truncateToWidth(theme.fg("muted",` Plugins: profile ${this.profileId} \xB7 ${selectionText} \xB7 ${catalogText} \xB7 ${suffix}`),width,"...")]}setUiSnapshot(result){result.status==="ok"&&(this.uiProfile=result.snapshot.profiles.find(profile=>profile.profileId===this.profileId),this.uiProfile!==void 0&&(this.uiPluginIndex=Math.min(this.uiPluginIndex,Math.max(0,this.uiProfile.plugins.length-1))))}currentUiPlugin(){return this.uiProfile?.plugins[this.uiPluginIndex]}handleInput(data){if(!this._focused||this.uiProfile===void 0)return;let keybindings=getKeybindings();if(keybindings.matches(data,"tui.select.up")){this.uiPluginIndex=Math.max(0,this.uiPluginIndex-1),this.requestRender?.();return}if(keybindings.matches(data,"tui.select.down")){this.uiPluginIndex=Math.min(this.uiProfile.plugins.length-1,this.uiPluginIndex+1),this.requestRender?.();return}if(keybindings.matches(data,"tui.select.cancel")){this._focused=!1,this.onClose?.(),this.requestRender?.();return}if(!keybindings.matches(data,"tui.select.confirm")&&data!==" ")return;let plugin=this.currentUiPlugin();plugin===void 0||this.controller===void 0||plugin.state==="disabled"&&plugin.availability!=="ready"||this.controller.toggle({profileId:this.profileId,pluginId:plugin.pluginId}).then(result=>{this.setUiSnapshot(result),this.requestRender?.()}).catch(()=>this.requestRender?.())}async openPluginSelection(){let controllerResult;this.controller!==void 0&&(controllerResult=await this.controller.getSnapshot(),this.setUiSnapshot(controllerResult));let status2=this.hasHostEntry()?"ready":"unsupported",selection=this.selection,codes=Object.freeze([]);if(controllerResult?.status==="error"&&(status2=controllerResult.code==="store-cancelled"?"cancelled":"invalid"),this.store!==void 0){let result=await this.store.read();if(codes=diagnosticCodes2(result),result.status==="ok"||result.status==="missing"){let storedSelection=selectionForProfile2(result,this.profileId);selection=summarizePluginSelectionV1(storedSelection),status2=result.status==="ok"?"ready":"missing"}else selection=emptySelectionSummary(),status2=result.status;this.selection=selection}let context=Object.freeze({profileId:this.profileId,status:status2,selection,catalog:this.catalog,diagnosticCodes:codes});return this.onOpen!==void 0&&await this.onOpen(context),context}invalidate(){}getSelectionSummary(){return this.selection}getCatalogSummary(){return this.catalog}};var RESOURCE_TYPES2=["skills","prompts","themes"],RESOURCE_TYPE_LABELS={skills:"Skills",prompts:"Prompts",themes:"Themes"};function formatBaseDir(baseDir){let homeDir=homedir10(),displayPath;return baseDir===homeDir?displayPath="~":baseDir.startsWith(homeDir)?displayPath=`~${baseDir.slice(homeDir.length).replace(/\\/g,"/")}`:displayPath=baseDir.replace(/\\/g,"/"),displayPath.endsWith("/")?displayPath:`${displayPath}/`}function getGroupLabel(metadata,agentDir){return metadata.origin==="package"?`${metadata.source} (${metadata.scope})`:metadata.source==="auto"?metadata.baseDir?metadata.scope==="user"?`User (${formatBaseDir(metadata.baseDir)})`:`Project (${formatBaseDir(metadata.baseDir)})`:metadata.scope==="user"?`User (${formatBaseDir(agentDir)})`:`Project (${CONFIG_DIR_NAME}/)`:metadata.scope==="user"?"User settings":"Project settings"}function buildGroups(resolved,agentDir){let groupMap=new Map,addToGroup=(resources,resourceType)=>{for(let res of resources){let{path:path15,enabled,metadata}=res,groupKey2=`${metadata.origin}:${metadata.scope}:${metadata.source}:${metadata.baseDir??""}`;groupMap.has(groupKey2)||groupMap.set(groupKey2,{key:groupKey2,label:getGroupLabel(metadata,agentDir),scope:metadata.scope,origin:metadata.origin,source:metadata.source,subgroups:[]});let group=groupMap.get(groupKey2),subgroupKey=`${groupKey2}:${resourceType}`,subgroup=group.subgroups.find(sg=>sg.type===resourceType);subgroup||(subgroup={type:resourceType,label:RESOURCE_TYPE_LABELS[resourceType],items:[]},group.subgroups.push(subgroup));let fileName=basename16(path15),parentFolder=basename16(dirname31(path15)),displayName;resourceType==="skills"&&fileName==="SKILL.md"?displayName=parentFolder:displayName=fileName,subgroup.items.push({path:path15,enabled,metadata,resourceType,displayName,groupKey:groupKey2,subgroupKey})}};addToGroup(resolved.skills,"skills"),addToGroup(resolved.prompts,"prompts"),addToGroup(resolved.themes,"themes");let groups=Array.from(groupMap.values());groups.sort((a,b2)=>a.origin!==b2.origin?a.origin==="package"?-1:1:a.scope!==b2.scope?a.scope==="user"?-1:1:a.source.localeCompare(b2.source));let typeOrder={skills:0,prompts:1,themes:2};for(let group of groups){group.subgroups.sort((a,b2)=>typeOrder[a.type]-typeOrder[b2.type]);for(let subgroup of group.subgroups)subgroup.items.sort((a,b2)=>a.displayName.localeCompare(b2.displayName))}return groups}var ConfigSelectorHeader=class{writeScope;projectModeAvailable;constructor(writeScope,projectModeAvailable){this.writeScope=writeScope,this.projectModeAvailable=projectModeAvailable}setWriteScope(writeScope){this.writeScope=writeScope}invalidate(){}render(width){let title=theme.bold(this.writeScope==="project"?"Project Local Resources":"Global Resources"),sep15=theme.fg("muted"," \xB7 "),switchHint=this.projectModeAvailable?keyHint("tui.input.tab","switch mode")+sep15:"",actionHint=this.writeScope==="project"?rawKeyHint("space","cycle inherit/+/-"):rawKeyHint("space","toggle"),hint=switchHint+actionHint+sep15+rawKeyHint("esc","close"),spacing=Math.max(1,width-visibleWidth(title)-visibleWidth(hint)),scopeHint=this.writeScope==="project"?theme.fg("muted",`${CONFIG_DIR_NAME}/settings.json \xB7 inherited global resources are dimmed`):theme.fg("muted",`~/${CONFIG_DIR_NAME}/agent/settings.json`);return[truncateToWidth(`${title}${" ".repeat(spacing)}${hint}`,width,""),truncateToWidth(scopeHint,width,"")]}},ResourceList=class{groupsByScope;flatItems=[];filteredItems=[];selectedIndex=0;searchInput;maxVisible;settingsManager;cwd;agentDir;writeScope;inheritedEnabledByKey;pluginSelectionEntry;pluginManagerEntry;pluginManagerScope;onCancel;onExit;onToggle;onSwitchMode;_focused=!1;get focused(){return this._focused}set focused(value){this._focused=value,this.searchInput.focused=value}constructor(groupsByScope,settingsManager,cwd,agentDir,terminalHeight,writeScope="global",pluginSelectionEntry,pluginManagerEntry,pluginManagerScope="global"){this.groupsByScope=groupsByScope,this.settingsManager=settingsManager,this.cwd=cwd,this.agentDir=agentDir,this.writeScope=writeScope,this.pluginSelectionEntry=pluginSelectionEntry,this.pluginManagerEntry=pluginManagerEntry,this.pluginManagerScope=pluginManagerScope,this.inheritedEnabledByKey=this.buildInheritedEnabledMap(groupsByScope.global),this.searchInput=new Input;let chrome=8;this.maxVisible=Math.max(5,(terminalHeight??24)-chrome),this.buildFlatList(),this.filteredItems=[...this.flatItems]}setWriteScope(writeScope){this.writeScope=writeScope,this.buildFlatList(),this.filterItems(this.searchInput.getValue())}get groups(){return this.groupsByScope[this.writeScope]}buildInheritedEnabledMap(groups){let result=new Map;for(let group of groups)for(let subgroup of group.subgroups)for(let item of subgroup.items)result.set(this.getResourceItemKey(item),item.enabled);return result}buildFlatList(){this.flatItems=[];for(let group of this.groups){this.flatItems.push({type:"group",group});for(let subgroup of group.subgroups){this.flatItems.push({type:"subgroup",subgroup,group});for(let item of subgroup.items)this.flatItems.push({type:"item",item})}}this.pluginSelectionEntry!==void 0&&this.flatItems.push({type:"plugin",entry:this.pluginSelectionEntry}),this.pluginManagerEntry!==void 0&&this.writeScope===this.pluginManagerScope&&this.flatItems.push({type:"plugin-manager",entry:this.pluginManagerEntry}),this.selectedIndex=this.flatItems.findIndex(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager"),this.selectedIndex<0&&(this.selectedIndex=0)}findNextItem(fromIndex,direction){let idx=fromIndex+direction;for(;idx>=0&&idx<this.filteredItems.length;){if(this.filteredItems[idx].type==="item"||this.filteredItems[idx].type==="plugin"||this.filteredItems[idx].type==="plugin-manager")return idx;idx+=direction}return fromIndex}filterItems(query){if(!query.trim()){this.filteredItems=[...this.flatItems],this.selectFirstItem();return}let lowerQuery=query.toLowerCase(),matchingItems=new Set,matchingSubgroups=new Set,matchingGroups=new Set;for(let entry of this.flatItems)if(entry.type==="item"){let item=entry.item;(item.displayName.toLowerCase().includes(lowerQuery)||item.resourceType.toLowerCase().includes(lowerQuery)||item.path.toLowerCase().includes(lowerQuery))&&matchingItems.add(item)}for(let group of this.groups)for(let subgroup of group.subgroups)for(let item of subgroup.items)matchingItems.has(item)&&(matchingSubgroups.add(subgroup),matchingGroups.add(group));this.filteredItems=[];for(let entry of this.flatItems)entry.type==="group"&&matchingGroups.has(entry.group)?this.filteredItems.push(entry):entry.type==="subgroup"&&matchingSubgroups.has(entry.subgroup)?this.filteredItems.push(entry):entry.type==="item"&&matchingItems.has(entry.item)&&this.filteredItems.push(entry);this.selectFirstItem()}selectFirstItem(){let firstItemIndex=this.filteredItems.findIndex(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager");this.selectedIndex=firstItemIndex>=0?firstItemIndex:0}updateItem(item,enabled){item.enabled=enabled;for(let group of this.groups)for(let subgroup of group.subgroups){let found=subgroup.items.find(i=>i.path===item.path&&i.resourceType===item.resourceType);if(found){found.enabled=enabled;return}}}invalidate(){}render(width){let lines=[];if(lines.push(...this.searchInput.render(width)),lines.push(""),this.filteredItems.length===0)return lines.push(theme.fg("muted"," No resources found")),lines;let startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisible/2),this.filteredItems.length-this.maxVisible)),endIndex=Math.min(startIndex+this.maxVisible,this.filteredItems.length);for(let i=startIndex;i<endIndex;i++){let entry=this.filteredItems[i],isSelected=i===this.selectedIndex;if(entry.type==="group"){let inherited=this.writeScope==="project"&&entry.group.scope==="user",label=theme.bold(`${entry.group.label}${inherited?" \xB7 inherited global":""}`),groupLine=theme.fg(inherited?"dim":"accent",label);lines.push(truncateToWidth(` ${groupLine}`,width,""))}else if(entry.type==="subgroup"){let color=this.writeScope==="project"&&entry.group.scope==="user"?"dim":"muted",subgroupLine=theme.fg(color,entry.subgroup.label);lines.push(truncateToWidth(` ${subgroupLine}`,width,""))}else if(entry.type==="plugin"){let prefix=isSelected?"> ":" ";for(let line of entry.entry.render(width))lines.push(truncateToWidth(`${prefix}${line.trimStart()}`,width,"..."))}else if(entry.type==="plugin-manager"){let prefix=isSelected?"> ":" ";for(let line of entry.entry.render(width))lines.push(truncateToWidth(`${prefix}${line.trimStart()}`,width,"..."))}else{let item=entry.item,cursor=isSelected?"> ":" ",dimmed=this.isDimmedItem(item),nameText=isSelected&&!dimmed?theme.bold(item.displayName):item.displayName,name=dimmed?theme.fg("dim",nameText):nameText;lines.push(truncateToWidth(`${cursor} ${this.renderCheckbox(item)} ${name}${this.getItemSuffix(item)}`,width,"..."))}}if(startIndex>0||endIndex<this.filteredItems.length){let itemCount=this.filteredItems.filter(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager").length,currentItemIndex=this.filteredItems.slice(0,this.selectedIndex).filter(e=>e.type==="item"||e.type==="plugin"||e.type==="plugin-manager").length+1;lines.push(theme.fg("dim",` (${currentItemIndex}/${itemCount})`))}return lines}handleInput(data){let kb=getKeybindings();if(this.pluginSelectionEntry?.focused===!0){this.pluginSelectionEntry.handleInput(data);return}if(this.pluginManagerEntry?.focused===!0){this.pluginManagerEntry.handleInput(data);return}if(kb.matches(data,"tui.select.up")){this.selectedIndex=this.findNextItem(this.selectedIndex,-1);return}if(kb.matches(data,"tui.select.down")){this.selectedIndex=this.findNextItem(this.selectedIndex,1);return}if(kb.matches(data,"tui.select.pageUp")){let target=Math.max(0,this.selectedIndex-this.maxVisible);for(;target<this.filteredItems.length&&this.filteredItems[target].type!=="item"&&this.filteredItems[target].type!=="plugin"&&this.filteredItems[target].type!=="plugin-manager";)target++;target<this.filteredItems.length&&(this.selectedIndex=target);return}if(kb.matches(data,"tui.select.pageDown")){let target=Math.min(this.filteredItems.length-1,this.selectedIndex+this.maxVisible);for(;target>=0&&this.filteredItems[target].type!=="item"&&this.filteredItems[target].type!=="plugin"&&this.filteredItems[target].type!=="plugin-manager";)target--;target>=0&&(this.selectedIndex=target);return}if(kb.matches(data,"tui.select.cancel")){this.onCancel?.();return}if(kb.matches(data,"app.config.exit")){this.onExit?.();return}if(kb.matches(data,"tui.input.tab")){this.onSwitchMode?.();return}if(data===" "||kb.matches(data,"tui.select.confirm")){let entry=this.filteredItems[this.selectedIndex];if(entry?.type==="plugin"&&this.writeScope==="global"){entry.entry.focused=!0,entry.entry.openPluginSelection();return}if(entry?.type==="plugin-manager"&&this.writeScope===this.pluginManagerScope){entry.entry.focused=!0,entry.entry.openPluginManager();return}if(entry?.type==="item"&&(this.writeScope==="project"||this.getItemScope(entry.item)==="user")){let newEnabled=this.toggleResource(entry.item);newEnabled!==void 0&&(this.updateItem(entry.item,newEnabled),this.onToggle?.(entry.item,newEnabled))}return}this.searchInput.handleInput(data),this.filterItems(this.searchInput.getValue())}toggleResource(item){if(this.writeScope==="project"){let state2=this.getNextOverrideState(item);return this.setProjectResourceOverride(item,state2)?state2==="inherit"?this.getInheritedEnabled(item):state2==="load":void 0}let enabled=!item.enabled;return item.metadata.origin==="top-level"?this.toggleTopLevelResource(item,enabled):this.togglePackageResource(item,enabled),enabled}toggleTopLevelResource(item,enabled){let scope=item.metadata.scope,settings2=scope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings(),arrayKey=item.resourceType,current=settings2[arrayKey]??[],pattern=this.getResourcePattern(item),disablePattern=`-${pattern}`,enablePattern=`+${pattern}`,updated=current.filter(p=>(p.startsWith("!")||p.startsWith("+")||p.startsWith("-")?p.slice(1):p)!==pattern);enabled?updated.push(enablePattern):updated.push(disablePattern),scope==="project"?arrayKey==="skills"?this.settingsManager.setProjectSkillPaths(updated):arrayKey==="prompts"?this.settingsManager.setProjectPromptTemplatePaths(updated):arrayKey==="themes"&&this.settingsManager.setProjectThemePaths(updated):arrayKey==="skills"?this.settingsManager.setSkillPaths(updated):arrayKey==="prompts"?this.settingsManager.setPromptTemplatePaths(updated):arrayKey==="themes"&&this.settingsManager.setThemePaths(updated)}togglePackageResource(item,enabled){let scope=item.metadata.scope,packages=[...(scope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings()).packages??[]],pkgIndex=packages.findIndex(pkg3=>(typeof pkg3=="string"?pkg3:pkg3.source)===item.metadata.source);if(pkgIndex===-1)return;let pkg2=packages[pkgIndex];typeof pkg2=="string"&&(pkg2={source:pkg2},packages[pkgIndex]=pkg2);let arrayKey=item.resourceType,current=pkg2[arrayKey]??[],pattern=this.getPackageResourcePattern(item),disablePattern=`-${pattern}`,enablePattern=`+${pattern}`,updated=current.filter(p=>(p.startsWith("!")||p.startsWith("+")||p.startsWith("-")?p.slice(1):p)!==pattern);enabled?updated.push(enablePattern):updated.push(disablePattern),pkg2[arrayKey]=updated.length>0?updated:void 0,["skills","prompts","themes"].some(k=>pkg2[k]!==void 0)||(packages[pkgIndex]=pkg2.source),scope==="project"?this.settingsManager.setProjectPackages(packages):this.settingsManager.setPackages(packages)}renderCheckbox(item){if(this.writeScope==="project"){let state2=this.getProjectOverrideState(item);return state2==="load"?theme.fg("success","[+]"):state2==="unload"?theme.fg("warning","[-]"):theme.fg("dim",item.enabled?"[x]":"[ ]")}return item.enabled?theme.fg("success","[x]"):theme.fg("dim","[ ]")}getItemSuffix(item){if(this.writeScope!=="project")return"";let state2=this.getProjectOverrideState(item);return state2==="load"?theme.fg("muted"," project load"):state2==="unload"?theme.fg("muted"," project unload"):this.isInheritedGlobalItem(item)?theme.fg("dim"," inherited global"):""}isDimmedItem(item){return this.writeScope==="project"&&this.isInheritedGlobalItem(item)&&this.getProjectOverrideState(item)==="inherit"}setProjectResourceOverride(item,state2){return item.metadata.origin==="top-level"?this.setProjectTopLevelOverride(item,state2):this.setProjectPackageOverride(item,state2)}setProjectTopLevelOverride(item,state2){let current=this.settingsManager.getProjectSettings()[item.resourceType]??[],pattern=this.isInheritedGlobalItem(item)?item.path:this.getResourcePatternForScope(item,"project"),patterns=this.getTopLevelOverridePatterns(item,"project"),updated=current.filter(entry=>{let target=this.getPatternEntryTarget(entry);return(entry.startsWith("!")||entry.startsWith("+")||entry.startsWith("-"))&&patterns.has(target)?!1:!(state2==="inherit"&&this.isInheritedGlobalItem(item)&&target===pattern)});return state2!=="inherit"&&(this.isInheritedGlobalItem(item)&&!updated.includes(pattern)&&updated.push(pattern),updated.push(`${state2==="load"?"+":"-"}${pattern}`)),this.setProjectTopLevelPaths(item.resourceType,updated),!0}setProjectTopLevelPaths(key,paths){key==="skills"?this.settingsManager.setProjectSkillPaths(paths):key==="prompts"?this.settingsManager.setProjectPromptTemplatePaths(paths):this.settingsManager.setProjectThemePaths(paths)}setProjectPackageOverride(item,state2){let packages=[...this.settingsManager.getProjectSettings().packages??[]],pkgIndex=packages.findIndex(pkg3=>this.packageSourceStringMatches(item.metadata.source,this.getItemScope(item),typeof pkg3=="string"?pkg3:pkg3.source,"project"));if(pkgIndex===-1){if(state2==="inherit")return!1;packages.push(this.createPackageOverrideSource(item)),pkgIndex=packages.length-1}let pkg2=packages[pkgIndex];if(pkg2===void 0)return!1;typeof pkg2=="string"&&(pkg2={source:pkg2},packages[pkgIndex]=pkg2);let pattern=this.getPackageResourcePattern(item),updated=(pkg2[item.resourceType]??[]).filter(entry=>this.getPatternEntryTarget(entry)!==pattern);return state2!=="inherit"&&updated.push(`${state2==="load"?"+":"-"}${pattern}`),pkg2[item.resourceType]=updated.length>0?updated:void 0,RESOURCE_TYPES2.some(key=>pkg2[key]!==void 0)||(pkg2.autoload===!1?packages.splice(pkgIndex,1):packages[pkgIndex]=pkg2.source),this.settingsManager.setProjectPackages(packages),!0}getNextOverrideState(item){let state2=this.getProjectOverrideState(item),inheritedEnabled=this.getInheritedEnabled(item);return state2==="inherit"?inheritedEnabled?"unload":"load":state2==="unload"?inheritedEnabled?"load":"inherit":inheritedEnabled?"inherit":"unload"}getProjectOverrideState(item){if(this.writeScope!=="project")return"inherit";if(item.metadata.origin==="top-level")return this.getOverrideStateFromEntries(this.settingsManager.getProjectSettings()[item.resourceType]??[],this.getTopLevelOverridePatterns(item,"project"),!1);let pkg2=this.findMatchingPackageSource(item,"project");if(typeof pkg2!="object")return"inherit";let entries=pkg2[item.resourceType];return entries===void 0?"inherit":this.getOverrideStateFromEntries(entries,new Set([this.getPackageResourcePattern(item)]),pkg2.autoload!==!1)}getOverrideStateFromEntries(entries,patterns,emptyArrayIsUnload){if(entries.length===0&&emptyArrayIsUnload)return"unload";let state2="inherit";for(let entry of entries)patterns.has(this.getPatternEntryTarget(entry))&&(entry.startsWith("!")||entry.startsWith("-")?state2="unload":state2="load");return state2}getInheritedEnabled(item){return this.inheritedEnabledByKey.get(this.getResourceItemKey(item))??(this.getItemScope(item)==="user"?item.enabled:!0)}isInheritedGlobalItem(item){return this.getItemScope(item)==="user"||this.inheritedEnabledByKey.has(this.getResourceItemKey(item))}getTopLevelOverridePatterns(item,scope){let baseDir=this.getTopLevelBaseDir(scope),patterns=new Set([this.getResourcePatternForScope(item,scope),item.path,relative12(baseDir,item.path)]);return item.metadata.baseDir&&patterns.add(relative12(item.metadata.baseDir,item.path)),patterns}getResourcePatternForScope(item,scope){let sourceScope=this.getItemScope(item);if(scope!==sourceScope)return item.path;let baseDir=item.metadata.baseDir??this.getTopLevelBaseDir(sourceScope);return relative12(baseDir,item.path)}createPackageOverrideSource(item){let source=item.metadata.source;if(!isLocalPath(source))return{source,autoload:!1};let sourcePath=resolvePath(source,this.getTopLevelBaseDir(this.getItemScope(item)),{trim:!0});return{source:relative12(this.getTopLevelBaseDir("project"),sourcePath)||".",autoload:!1}}packageSourceStringMatches(leftSource,leftScope,rightSource,rightScope){if(leftSource===rightSource)return!0;if(!isLocalPath(leftSource)||!isLocalPath(rightSource))return!1;let left=resolvePath(leftSource,this.getTopLevelBaseDir(leftScope),{trim:!0}),right=resolvePath(rightSource,this.getTopLevelBaseDir(rightScope),{trim:!0});return left===right}findMatchingPackageSource(item,targetScope){return((targetScope==="project"?this.settingsManager.getProjectSettings():this.settingsManager.getGlobalSettings()).packages??[]).find(pkg2=>this.packageSourceStringMatches(item.metadata.source,this.getItemScope(item),typeof pkg2=="string"?pkg2:pkg2.source,targetScope))}getPatternEntryTarget(entry){return entry.startsWith("!")||entry.startsWith("+")||entry.startsWith("-")?entry.slice(1):entry}getResourceItemKey(item){return`${item.resourceType}:${canonicalizePath(item.path)}`}getItemScope(item){return item.metadata.scope==="project"?"project":"user"}getTopLevelBaseDir(scope){return scope==="project"?join65(this.cwd,CONFIG_DIR_NAME):this.agentDir}getResourcePattern(item){let scope=item.metadata.scope,baseDir=item.metadata.baseDir??this.getTopLevelBaseDir(scope);return relative12(baseDir,item.path)}getPackageResourcePattern(item){let baseDir=item.metadata.baseDir??dirname31(item.path);return relative12(baseDir,item.path)}},ConfigSelectorComponent=class extends Container{header;resourceList;pluginSelectionEntry;pluginManagerEntry;writeScope;_focused=!1;get focused(){return this._focused}set focused(value){this._focused=value,this.resourceList.focused=value}constructor(resolvedPaths,settingsManager,cwd,agentDir,onClose,onExit,requestRender,terminalHeight,writeScope="global",projectModeAvailable=!0,pluginSelection,pluginManager,pluginManagerScope="global"){super(),this.writeScope=writeScope;let groupsByScope={global:buildGroups(resolvedPaths.global,agentDir),project:buildGroups(resolvedPaths.project,agentDir)},pluginSelectionEntry=pluginSelection===void 0?void 0:new PluginSelectionEntryComponent({...pluginSelection,onClose:()=>{pluginSelection.onClose?.()},requestRender});this.pluginSelectionEntry=pluginSelectionEntry;let pluginManagerEntry=pluginManager===void 0?void 0:new PluginManagerEntryComponent({...pluginManager,onClose:()=>{pluginManager.onClose?.()},requestRender});this.pluginManagerEntry=pluginManagerEntry,this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.header=new ConfigSelectorHeader(this.writeScope,projectModeAvailable),this.addChild(this.header),this.addChild(new Spacer(1)),this.resourceList=new ResourceList(groupsByScope,settingsManager,cwd,agentDir,terminalHeight===void 0?void 0:Math.max(5,terminalHeight-(pluginSelection===void 0?0:2)-(pluginManager===void 0?0:2)),this.writeScope,pluginSelectionEntry,pluginManagerEntry,pluginManagerScope),this.resourceList.onCancel=onClose,this.resourceList.onExit=onExit,this.resourceList.onToggle=()=>requestRender(),projectModeAvailable&&(this.resourceList.onSwitchMode=()=>{this.switchWriteScope(),requestRender()}),this.addChild(this.resourceList),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder)}switchWriteScope(){this.writeScope=this.writeScope==="global"?"project":"global",this.header.setWriteScope(this.writeScope),this.resourceList.setWriteScope(this.writeScope)}getResourceList(){return this.resourceList}getPluginSelectionEntry(){return this.pluginSelectionEntry}getPluginManagerEntry(){return this.pluginManagerEntry}async openPluginSelection(){return this.pluginSelectionEntry===void 0?void 0:await this.pluginSelectionEntry.openPluginSelection()}async openPluginManager(){return this.pluginManagerEntry===void 0?void 0:await this.pluginManagerEntry.openPluginManager()}};async function selectConfig(options){initTheme(options.settingsManager.getTheme(),!0);let pluginSnapshot=options.pluginSelectionController?await options.pluginSelectionController.getSnapshot():void 0,pluginManagerSnapshot=options.pluginManagerController?await options.pluginManagerController.getSnapshot():void 0;return new Promise(resolve25=>{let ui=new TuiMainScreen(new ProcessTerminal,void 0,options.agentDir),resolved=!1,selector=new ConfigSelectorComponent(options.resolvedPaths,options.settingsManager,options.cwd,options.agentDir,()=>{resolved||(resolved=!0,ui.stop(),stopThemeWatcher(),resolve25())},()=>{ui.stop(),stopThemeWatcher(),process.exit(0)},()=>ui.requestRender(),ui.terminal.rows,options.writeScope,options.projectModeAvailable,options.pluginSelectionController===void 0?void 0:{profileId:options.pluginSelectionProfileId??"coding-core",controller:options.pluginSelectionController,snapshot:pluginSnapshot?.status==="ok"?pluginSnapshot.snapshot:void 0,onOpen:()=>ui.requestRender(),requestRender:()=>ui.requestRender()},options.pluginManagerController===void 0?void 0:{controller:options.pluginManagerController,snapshot:pluginManagerSnapshot?.status==="ok"?pluginManagerSnapshot.snapshot:void 0,requestRender:()=>ui.requestRender()},options.pluginManagerScope);ui.addChild(selector),ui.setFocus(selector.getResourceList()),ui.start()})}import{randomUUID as randomUUID21}from"node:crypto";import{copyFileSync as copyFileSync2,existsSync as existsSync32,mkdirSync as mkdirSync21,renameSync as renameSync5,rmSync as rmSync7}from"node:fs";import{basename as basename17,dirname as dirname32,join as join66,relative as relative13,resolve as resolve23,toNamespacedPath}from"node:path";var QUARANTINE_DIR_NAME=".agent-forge-native-quarantine";function normalizePath2(path15){return toNamespacedPath(resolve23(path15))}function getQuarantineRoot(packageDir){let current=resolve23(packageDir);for(;;){if(basename17(current).toLowerCase()==="node_modules")return join66(current,QUARANTINE_DIR_NAME);let parent=dirname32(current);if(parent===current)return;current=parent}}function getLoadedSharedObjectsInPackageDir(packageDir){let sharedObjects=process.report.getReport().sharedObjects;if(!Array.isArray(sharedObjects))return[];let root=normalizePath2(packageDir).toLowerCase(),seen=new Set,loadedFiles=[];for(let value of sharedObjects){if(typeof value!="string")continue;let filePath=normalizePath2(value),comparisonPath=filePath.toLowerCase();getCwdRelativePath(comparisonPath,root)===void 0||seen.has(comparisonPath)||(seen.add(comparisonPath),loadedFiles.push(filePath))}return loadedFiles}function cleanupWindowsSelfUpdateQuarantine(packageDir){let quarantineRoot=getQuarantineRoot(packageDir);if(quarantineRoot)try{rmSync7(quarantineRoot,{recursive:!0,force:!0})}catch{}}function quarantineWindowsNativeDependencies(packageDir){let resolvedPackageDir=normalizePath2(packageDir),quarantineRoot=getQuarantineRoot(resolvedPackageDir);if(!quarantineRoot)return;let loadedFiles=getLoadedSharedObjectsInPackageDir(resolvedPackageDir);if(loadedFiles.length===0)return;let quarantineRunDir=join66(quarantineRoot,`${Date.now()}-${process.pid}-${randomUUID21()}`);for(let loadedFile of loadedFiles){if(!existsSync32(loadedFile))continue;let quarantinePath=join66(quarantineRunDir,relative13(resolvedPackageDir,loadedFile));mkdirSync21(dirname32(quarantinePath),{recursive:!0}),renameSync5(loadedFile,quarantinePath),copyFileSync2(quarantinePath,loadedFile)}}var MANAGED_INSTALL_MARKER="managed-install.json",MANAGED_RELEASE_VERSION_RE=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;function getActiveManagedInstallRoot(){let configuredRoot=process.env.AGENT_FORGE_MANAGED_INSTALL_ROOT?.trim();if(!configuredRoot)return;let managedRoot=resolve24(configuredRoot),releasesDir=canonicalizePath(join67(managedRoot,"releases"));if(getCwdRelativePath(canonicalizePath(getPackageDir()),releasesDir)===void 0)return;let markerPath=join67(managedRoot,MANAGED_INSTALL_MARKER);try{let marker=JSON.parse(readFileSync28(markerPath,"utf8"));if(marker.kind!=="agent-forge-managed-install"||marker.schemaVersion!==1||marker.layout!=="releases-v1")throw new Error}catch{throw new Error(`Managed install marker is missing or invalid: ${markerPath}`)}return managedRoot}async function fetchInstallerArtifact(url,label){let response2=await fetch(url,{headers:{"User-Agent":getAgentForgeUserAgent(VERSION)}});if(!response2.ok)throw new Error(`Could not download managed installer ${label} from ${url}: HTTP ${response2.status}`);return await response2.text()}async function runManagedNpmCi(stageDir){let args=["ci","--ignore-scripts","--min-release-age=0","--omit=dev","--include=optional","--no-fund","--no-audit","--loglevel=error","--progress=false"],code=await waitForChildProcess(spawnProcess("npm",args,{cwd:stageDir,stdio:"inherit"}));if(code!==0)throw new Error(`npm ${args.join(" ")} exited with code ${code??"unknown"}`)}function verifyManagedRelease(releaseDir,expectedVersion){let binPath=join67(releaseDir,"node_modules",".bin",process.platform==="win32"?`${APP_NAME}.cmd`:APP_NAME),result=spawnProcessSync(binPath,["--version"],{encoding:"utf8",stdio:["ignore","pipe","pipe"]});if(result.error||result.status!==0){let reason=result.error?.message||result.stderr.trim()||`exit code ${result.status??"unknown"}`;throw new Error(`Could not verify managed ${APP_NAME} ${expectedVersion}: ${reason}`)}let installedVersion=result.stdout.trim();if(installedVersion!==expectedVersion)throw new Error(`Managed ${APP_NAME} smoke test returned version ${installedVersion}; expected ${expectedVersion}.`)}async function activateStagedRelease(stageDir,releaseDir){for(let attempt2=0;;attempt2++)try{renameSync6(stageDir,releaseDir);return}catch(error2){if(attempt2>=9||!existsSync33(stageDir))throw error2;await sleep3(1e3)}}function activateManagedRelease(managedRoot,version){let currentPath=join67(managedRoot,"current-version"),temporaryPath=join67(managedRoot,`current-version.tmp.${process.pid}-${Date.now()}`);try{writeFileSync18(temporaryPath,`${version}