@astralyn/pi 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/bundle/chunks/{chunk-4TT2QGFL.js → chunk-N2LEX5CU.js} +1 -1
- package/dist/bundle/chunks/{chunk-H2N2THAO.js → chunk-Q7TDQ5LT.js} +20 -14
- package/dist/bundle/chunks/{virtual-modules-YFKU7JZF.js → virtual-modules-UUHBXSJB.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/tasks/runtime.d.ts +1 -0
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +4 -0
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/types.d.ts +2 -0
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +4 -3
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/shell-tool.d.ts.map +1 -1
- package/dist/core/tools/shell-tool.js +9 -2
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/extensions/deepwiki/execute.d.ts +0 -3
- package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
- package/dist/extensions/deepwiki/execute.js.map +1 -1
- package/dist/extensions/deepwiki/render.d.ts.map +1 -1
- package/dist/extensions/deepwiki/render.js +0 -5
- package/dist/extensions/deepwiki/render.js.map +1 -1
- package/dist/extensions/question/render.d.ts.map +1 -1
- package/dist/extensions/question/render.js +3 -7
- package/dist/extensions/question/render.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +19 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tasks/index.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/index.js +10 -10
- package/dist/modes/interactive/tasks/index.js.map +1 -1
- package/dist/modes/interactive/tasks/layout.js +4 -5
- package/dist/modes/interactive/tasks/layout.js.map +1 -1
- package/dist/modes/interactive/tasks/manager.d.ts.map +1 -1
- package/dist/modes/interactive/tasks/manager.js +2 -0
- package/dist/modes/interactive/tasks/manager.js.map +1 -1
- package/dist/modes/interactive/tool-view/chat.d.ts +2 -3
- package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
- package/dist/modes/interactive/tool-view/chat.js +18 -5
- package/dist/modes/interactive/tool-view/chat.js.map +1 -1
- package/dist/modes/interactive/tool-view/style.d.ts +2 -1
- package/dist/modes/interactive/tool-view/style.d.ts.map +1 -1
- package/dist/modes/interactive/tool-view/style.js +2 -2
- package/dist/modes/interactive/tool-view/style.js.map +1 -1
- package/docs/bundled/tasks.md +5 -3
- package/docs/bundled/tool-presentation.md +4 -3
- package/docs/extensions.md +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -649,7 +649,7 @@ File: ${path14}`)}let config=parsed,providers=new Map;for(let[providerId,provide
|
|
|
649
649
|
|
|
650
650
|
The following skills provide specialized instructions for specific tasks.`,fileReadTool==="read"?"Use the read tool to load a skill's file when the task matches its description.":"Use bash to load a skill's file when the task matches its description.","When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.","","<available_skills>"];for(let skill of visibleSkills)lines.push(" <skill>"),lines.push(` <name>${escapeXml(skill.name)}</name>`),lines.push(` <description>${escapeXml(skill.description)}</description>`),lines.push(` <location>${escapeXml(skill.filePath)}</location>`),lines.push(" </skill>");return lines.push("</available_skills>"),lines.join(`
|
|
651
651
|
`)}function escapeXml(str2){return str2.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function loadSkills(options){let{agentDir,skillPaths,includeDefaults}=options,resolvedCwd=resolvePath(options.cwd),resolvedAgentDir=resolvePath(agentDir??getAgentDir()),skillMap=new Map,realPathSet=new Set,allDiagnostics=[],collisionDiagnostics=[];function addSkills(result2){allDiagnostics.push(...result2.diagnostics);for(let skill of result2.skills){let realPath=canonicalizePath(skill.filePath);if(realPathSet.has(realPath))continue;let existing=skillMap.get(skill.name);existing?collisionDiagnostics.push({type:"collision",message:`name "${skill.name}" collision`,path:skill.filePath,collision:{resourceType:"skill",name:skill.name,winnerPath:existing.filePath,loserPath:skill.filePath}}):(skillMap.set(skill.name,skill),realPathSet.add(realPath))}}includeDefaults&&(addSkills(loadSkillsFromDirInternal(join17(resolvedAgentDir,"skills"),"user",!0)),addSkills(loadSkillsFromDirInternal(resolve3(resolvedCwd,CONFIG_DIR_NAME,"skills"),"project",!0)));let userSkillsDir=join17(resolvedAgentDir,"skills"),projectSkillsDir=resolve3(resolvedCwd,CONFIG_DIR_NAME,"skills"),isUnderPath=(target,root)=>{let normalizedRoot=resolve3(root);if(target===normalizedRoot)return!0;let prefix=normalizedRoot.endsWith(sep5)?normalizedRoot:`${normalizedRoot}${sep5}`;return target.startsWith(prefix)},getSource=resolvedPath=>{if(!includeDefaults){if(isUnderPath(resolvedPath,userSkillsDir))return"user";if(isUnderPath(resolvedPath,projectSkillsDir))return"project"}return"path"};for(let rawPath of skillPaths){let resolvedPath=resolvePath(rawPath,resolvedCwd,{trim:!0});if(!existsSync9(resolvedPath)){allDiagnostics.push({type:"warning",message:"skill path does not exist",path:resolvedPath});continue}try{let stats=statSync5(resolvedPath),source=getSource(resolvedPath);if(stats.isDirectory())addSkills(loadSkillsFromDirInternal(resolvedPath,source,!0));else if(stats.isFile()&&resolvedPath.endsWith(".md")){let result2=loadSkillFromFile(resolvedPath,source);result2.skill?addSkills({skills:[result2.skill],diagnostics:result2.diagnostics}):allDiagnostics.push(...result2.diagnostics)}else allDiagnostics.push({type:"warning",message:"skill path is not a markdown file",path:resolvedPath})}catch(error){let message=error instanceof Error?error.message:"failed to read skill path";allDiagnostics.push({type:"warning",message,path:resolvedPath})}}return{skills:Array.from(skillMap.values()),diagnostics:[...allDiagnostics,...collisionDiagnostics]}}import{randomUUID as randomUUID2}from"node:crypto";import{open as open2}from"node:fs/promises";var TASK_RESULT_BYTES=48*1024,TASK_DETAILS_BYTES=120*1024,TASK_READ_BYTES=8*1024,TASK_TITLE_BYTES=1024;function finiteLimit(value,fallback,ceiling){return value===void 0||!Number.isFinite(value)?fallback:Math.max(0,Math.min(ceiling,Math.floor(value)))}function alignedSlice(buffer,start,end){for(;start<end&&(buffer[start]&192)===128;)start++;if(end<buffer.length)for(;end>start&&(buffer[end]&192)===128;)end--;let lead=end-1;for(;lead>=start&&(buffer[lead]&192)===128;)lead--;if(lead>=start){let byte=buffer[lead],width=byte>=240?4:byte>=224?3:byte>=192?2:1;end-lead<width&&(end=lead)}return buffer.subarray(start,end)}function boundText(text2,bytes=TASK_RESULT_BYTES){let limit=finiteLimit(bytes,TASK_RESULT_BYTES,TASK_RESULT_BYTES),prefix=text2.slice(0,limit+1),buffer=Buffer.from(prefix);return alignedSlice(buffer,0,Math.min(limit,buffer.length)).toString("utf8")}function boundTail(text2,bytes){let buffer=Buffer.from(text2);return buffer.length<=bytes?{text:text2,truncated:!1}:{text:alignedSlice(buffer,buffer.length-bytes,buffer.length).toString("utf8"),truncated:!0}}function boundedResult(result2){let remaining=TASK_RESULT_BYTES,content=[];for(let block of result2.content){if(remaining<=0)break;let text2=boundText(block.type==="text"?block.text:"[Image omitted from background history]",remaining);content.push({type:"text",text:text2}),remaining-=Math.max(1,Buffer.byteLength(text2))}let details;try{let budget=TASK_DETAILS_BYTES,json=JSON.stringify(result2.details,(key,value)=>{if(budget-=Buffer.byteLength(key)+3,budget-=typeof value=="string"?Buffer.byteLength(value)+2:8,budget<0)throw new Error("Background details exceed the storage budget");return value});json!==void 0&&Buffer.byteLength(json)<=TASK_DETAILS_BYTES&&(details=JSON.parse(json))}catch{}return{content,details}}function retainResult(task,result2,truncated=!1){let bounded=boundedResult({content:result2.content,details:void 0});task.result=bounded,task.resultTruncated=truncated||bounded.content.length!==result2.content.length||bounded.content.some((block,index3)=>{let original=result2.content[index3];return original?.type!=="text"||block.type!=="text"||block.text!==original.text})}async function readOutputSlice(path14,options={}){let bytes=finiteLimit(options.bytes,TASK_READ_BYTES,TASK_RESULT_BYTES),file=await open2(path14,"r");try{let{size}=await file.stat(),since=finiteLimit(options.sinceBytes,0,Number.MAX_SAFE_INTEGER),floor=since>size?0:since,start=options.sinceBytes!==void 0?Math.max(floor,size-bytes):options.mode==="head"?0:Math.max(0,size-bytes),length=Math.min(bytes,size-start),buffer=Buffer.alloc(Math.min(length+1,size-start)),{bytesRead}=await file.read(buffer,0,buffer.length,start),slice=alignedSlice(buffer.subarray(0,bytesRead),0,Math.min(length,bytesRead));return{text:slice.toString("utf8"),totalBytes:size,truncated:options.sinceBytes!==void 0?start>floor||slice.length<length:slice.length<size,fromByte:start+slice.byteOffset-buffer.byteOffset}}finally{await file.close()}}function sliceText(text2,options={}){let buffer=Buffer.from(text2),bytes=finiteLimit(options.bytes,TASK_READ_BYTES,TASK_RESULT_BYTES),since=finiteLimit(options.sinceBytes,0,Number.MAX_SAFE_INTEGER),floor=since>buffer.length?0:since,start=options.sinceBytes!==void 0?Math.max(floor,buffer.length-bytes):options.mode==="head"?0:Math.max(0,buffer.length-bytes),slice=alignedSlice(buffer,start,Math.min(buffer.length,start+bytes));return{text:slice.toString("utf8"),totalBytes:buffer.length,truncated:slice.length<buffer.length-floor,fromByte:slice.byteOffset-buffer.byteOffset}}var TASK_HISTORY_VERSION=2;function dataObject(value){if(value===null||typeof value!="object"||Array.isArray(value))throw new Error("Expected object");let prototype=Object.getPrototypeOf(value);if(prototype!==Object.prototype&&prototype!==null)throw new Error("Expected plain object");return value}function field(object3,key){let descriptor=Object.getOwnPropertyDescriptor(object3,key);if(descriptor&&!("value"in descriptor))throw new Error("Unexpected accessor");return descriptor?.value}function historyString(value,bytes,exact=!1){if(typeof value!="string")throw new Error("Expected string");if(exact&&(!value||value.length>bytes||Buffer.byteLength(value)>bytes||value.includes("\0")))throw new Error("Invalid identity or path");return boundText(value,bytes)}function parseTaskHistory(record){try{let envelope=dataObject(record);if(field(envelope,"version")!==TASK_HISTORY_VERSION)return;let source=dataObject(field(envelope,"task")),kind=field(source,"kind"),mode=field(source,"mode"),status=field(source,"status");if(typeof kind!="string"||!/^[a-z][a-z0-9-]{0,63}$/.test(kind)||mode!=="foreground"&&mode!=="background"||status!=="completed"&&status!=="partial"&&status!=="failed"&&status!=="cancelled"&&status!=="timeout")return;let startedAt=field(source,"startedAt"),endedAt=field(source,"endedAt");if(typeof startedAt!="number"||!Number.isSafeInteger(startedAt)||startedAt<0||typeof endedAt!="number"||!Number.isSafeInteger(endedAt)||endedAt<startedAt)return;let anchor=field(source,"anchorId"),task={id:historyString(field(source,"id"),512,!0),kind,mode,status,startedAt,endedAt,title:historyString(field(source,"title"),TASK_TITLE_BYTES),toolCallId:historyString(field(source,"toolCallId"),512,!0),anchorId:anchor===null?null:historyString(anchor,8192,!0)};if(!task.id.startsWith(`${kind}-`)||task.id.length<=kind.length+1)return;for(let[key,bytes]of[["command",8192],["cwd",4096],["error",4096],["outputPath",8192]]){let value=field(source,key);value!==void 0&&(task[key]=historyString(value,bytes,key==="outputPath"))}for(let key of["commandTruncated","resultTruncated"]){let value=field(source,key);if(value!==void 0&&typeof value!="boolean")return;task[key]=value}let exitCode=field(source,"exitCode");if(exitCode!==void 0){if(exitCode!==null&&(typeof exitCode!="number"||!Number.isSafeInteger(exitCode)))return;task.exitCode=exitCode}task.command!==void 0&&task.command!==field(source,"command")&&(task.commandTruncated=!0);let result2=field(source,"result");if(result2!==void 0){let object3=dataObject(result2),blocks=field(object3,"content");if(!Array.isArray(blocks))return;let content=[],remaining=TASK_RESULT_BYTES;for(let index3=0;index3<blocks.length&&remaining>0;index3++){let block=dataObject(field(blocks,String(index3))),type=field(block,"type");if(type!=="text"&&type!=="image")return;let original=type==="text"?field(block,"text"):void 0,text2=type==="text"?historyString(original,remaining):"[Image omitted from background history]";text2!==original&&(task.resultTruncated=!0),content.push({type:"text",text:text2}),remaining-=Math.max(1,Buffer.byteLength(text2))}content.length<blocks.length&&(task.resultTruncated=!0),task.result=boundedResult({content,details:void 0})}return task}catch{return}}var EXPIRED_OUTPUT="Output has expired: the managed log was released; showing the stored result.";function freeze(value){if(value!==null&&typeof value=="object"&&!Object.isFrozen(value)){for(let child of Object.values(value))freeze(child);Object.freeze(value)}return value}function snapshotOf(record){return record.snapshot??=freeze(structuredClone(record.task)),record.snapshot}function changed(record){record.snapshot=void 0}function errorText(error){try{return boundText(error instanceof Error?error.message:String(error),4096)}catch{return"Task cleanup failed"}}function oldestTask(tasks){let oldest;for(let task of tasks)(!oldest||task.endedAt<oldest.endedAt)&&(oldest=task);return oldest}var isForeground=task=>task.mode==="foreground",TaskStore=class{constructor(maxHistory,maxRetained,isClosed,onCleanupError){this.records=new Map,this.cleanups=new Set,this.maxHistory=maxHistory,this.maxRetained=maxRetained,this.isClosed=isClosed,this.onCleanupError=onCleanupError}get closed(){return this.isClosed()}restoreHistory(records,toolResults=new Map){if(this.closed)return;let history=this.historyRecords(),foreground=history.filter(record=>isForeground(record.task)).length,foregroundCapacity=Math.max(0,this.maxHistory-foreground),backgroundCapacity=Math.max(0,this.maxHistory-(history.length-foreground)),capacity=Math.max(0,Math.min(foregroundCapacity+backgroundCapacity,this.maxRetained-this.records.size-this.cleanups.size)),newest=new Map;for(let value of records){let task=parseTaskHistory(value);if(!task)continue;let existing=this.records.get(task.id);if(existing){existing.settled&&(existing.visible=!0);continue}if(capacity===0)continue;let previous=newest.get(task.id);if(previous&&previous.endedAt>task.endedAt)continue;newest.delete(task.id);let inline=isForeground(task),limit=inline?foregroundCapacity:backgroundCapacity;if(limit===0)continue;newest.set(task.id,task);let group=[...newest.values()].filter(candidate=>isForeground(candidate)===inline);if(group.length>limit&&newest.delete(oldestTask(group).id),newest.size>capacity){let inlineTasks=[...newest.values()].filter(isForeground);newest.delete(oldestTask(inlineTasks.length?inlineTasks:newest.values()).id)}}for(let task of[...newest.values()].sort((a,b2)=>a.endedAt-b2.endedAt)){let content=toolResults.get(task.toolCallId);!task.result&&content&&retainResult(task,{content,details:void 0});let expired=task.outputPath!==void 0;task.outputPath=void 0,this.records.set(task.id,{task,settled:!0,visible:!0,delivery:"delivered",pins:0,deliveryHolds:0,waiters:new Set,readError:expired?EXPIRED_OUTPUT:void 0})}}cleanupOutput(record){if(!record.settled||record.pins||record.waiters.size||!record.cleanup)return;let cleanup=record.cleanup;record.cleanup=void 0,record.task.outputPath=void 0,changed(record),record.readError=EXPIRED_OUTPUT;let pending=Promise.resolve().then(cleanup).catch(error=>{try{this.onCleanupError?.(errorText(error))}catch{}}).finally(()=>this.cleanups.delete(pending));this.cleanups.add(pending)}historyRecords(){return[...this.records.values()].filter(record=>record.settled&&record.delivery==="delivered"&&!record.pins&&!record.waiters.size)}trim(){if(this.closed){for(let record of this.records.values())this.cleanupOutput(record);return}let history=this.historyRecords(),expired=history.filter(record=>!record.visible);for(let inline of[!1,!0]){let group=history.filter(record=>record.visible&&isForeground(record.task)===inline);group.sort((left,right)=>(left.task.endedAt??0)-(right.task.endedAt??0)),expired.push(...group.slice(0,Math.max(0,group.length-this.maxHistory)))}for(let record of expired)this.records.delete(record.task.id),this.cleanupOutput(record)}};var TASK_BACKGROUND_REJECTION="Background execution is not permitted in this host. Run with background: false or omit background. No work was started.";function isTaskTerminal(status){return status!=="queued"&&status!=="running"&&status!=="stopping"}var TaskExecutionError=class extends Error{constructor(message,status){super(message),this.name="TaskExecutionError",this.status=status}},TaskLookupError=class extends Error{constructor(kind,matches){super(kind==="ambiguous"?"Ambiguous task ID":"Unknown task ID"),this.name="TaskLookupError",this.kind=kind,this.matches=matches}};function errorText2(error){try{return boundText(error instanceof Error?error.message:String(error),4096)}catch{return"Task execution failed (unprintable error)"}}var TaskRuntime=class{get closed(){return this._closed}constructor(options={}){this.executions=new Map,this.listeners=new Set,this._closed=!1,this.pauses=0,this.options=options,this.configuredEnabled=options.enabled??!1,this.maxActive=Math.max(1,finiteLimit(options.maxActive,8,128)),this.maxHistory=finiteLimit(options.maxHistory,32,1024),this.maxRetained=this.maxActive+2*Math.max(1,this.maxHistory)+this.maxHistory,this.store=new TaskStore(this.maxHistory,this.maxRetained,()=>this.closed,options.onCleanupError)}restoreHistory(records,toolResults){this.store.restoreHistory(records,toolResults)}get enabled(){return this.configuredEnabled&&!this.closed&&this.options.backgroundAllowed!==!1}setEnabled(enabled){this.configuredEnabled=enabled,this.emit()}backgroundActive(){let count=0;for(let record of this.store.records.values())!record.settled&&record.task.mode==="background"&&count++;return count}limitError(){return new Error(`Background task limit reached (${this.maxActive}); stop or wait for a background task, or run in the foreground.`)}async execute(execution){if(execution.background&&this.options.backgroundAllowed===!1)throw new Error(TASK_BACKGROUND_REJECTION);if(this.closed)throw new Error("Task service is closed");if(execution.background){if(!this.enabled)throw new Error("Background execution is not available in this host");if(this.backgroundActive()>=this.maxActive)throw this.limitError();if(this.store.records.size+this.store.cleanups.size>=this.maxRetained)throw new Error("Task history retention limit reached; deliver pending notifications or release pinned or claimed records")}if(execution.signal?.aborted)throw execution.signal.reason??new Error("Execution aborted");if(!/^[a-z][a-z0-9-]{0,63}$/.test(execution.kind))throw new Error("Invalid task source");let anchorId=this.options.anchor?.()??null;if(anchorId!==null&&Buffer.byteLength(anchorId)>8192)throw new Error("Task branch anchor is too large");let task={id:`${execution.kind}-${randomUUID2()}`,kind:execution.kind,title:boundText(execution.title,TASK_TITLE_BYTES),toolCallId:boundText(execution.toolCallId,512),anchorId,mode:execution.background?"background":"foreground",status:"queued",startedAt:Date.now(),command:execution.command===void 0?void 0:boundText(execution.command,8192),commandTruncated:execution.command===void 0?void 0:boundText(execution.command,8192)!==execution.command,cwd:execution.cwd===void 0?void 0:boundText(execution.cwd,4096)},resolveCaller,rejectCaller,caller=new Promise((resolve18,reject)=>{resolveCaller=resolve18,rejectCaller=reject}),resolveDone,record={task,settled:!1,visible:!0,delivery:"none",pins:0,deliveryHolds:0,waiters:new Set},active={controller:new AbortController,accepted:!1,handedOff:!1,detachRequested:execution.background??!1,modeListeners:new Set,removeParent:()=>{},handoff:()=>{!active.accepted||!active.detachRequested||record.settled||active.handedOff||this.closed||!record.visible||active.controller.signal.aborted||(active.handedOff=!0,task.mode="background",changed(record),active.removeParent(),resolveCaller({kind:"background",task:snapshotOf(record)}),this.emit())},done:new Promise(resolve18=>{resolveDone=resolve18})},parentSignal=execution.signal,onUpdate=execution.background?void 0:execution.onUpdate,parentAbort=()=>{(!active.detachRequested||!active.accepted)&&this.cancel(record)};parentSignal?.addEventListener("abort",parentAbort,{once:!0}),active.removeParent=()=>{parentSignal?.removeEventListener("abort",parentAbort),onUpdate=void 0},this.store.records.set(task.id,record),this.executions.set(task.id,active);let control={id:task.id,signal:active.controller.signal,get mode(){return task.mode},onModeChange:listener=>record.settled||this.closed?()=>{}:(active.modeListeners.add(listener),()=>{active.modeListeners.delete(listener)}),requestCancel:()=>this.cancel(record),accept:()=>{record.settled||active.accepted||this.closed||active.controller.signal.aborted||(active.accepted=!0,task.status==="queued"&&(task.status="running"),changed(record),active.detachRequested&&active.removeParent(),queueMicrotask(()=>queueMicrotask(active.handoff)),this.emit())},publish:result2=>{if(!(record.settled||this.closed)){if(retainResult(task,result2),changed(record),result2.usage!==void 0&&(active.publishedUsage=structuredClone(result2.usage)),!active.detachRequested&&!active.handedOff)try{onUpdate?.(result2)}catch{}this.emit()}},setOutputPath:(path14,cleanup)=>{if(record.settled){if(cleanup)throw new Error("Task execution has settled");return}if(record.cleanup)throw new Error("Managed output is already registered");if(Buffer.byteLength(path14)>8192)throw new Error("Task output path is too large");record.cleanup=cleanup,task.outputPath=path14,changed(record),this.emit()}},finish=(completion,error)=>{if(record.settled)return;record.settled=!0,active.modeListeners.clear(),active.removeParent(),task.endedAt=Date.now();let failed=completion===void 0;task.status=completion?.status??(error instanceof TaskExecutionError?error.status:active.controller.signal.aborted?"cancelled":failed?"failed":"completed"),completion&&(retainResult(task,completion.result),completion.error!==void 0&&(task.error=boundText(completion.error,4096)),completion.exitCode!==void 0&&(task.exitCode=completion.exitCode)),failed&&(task.error=errorText2(error),retainResult(task,{content:[{type:"text",text:task.error},...task.result?.content??[]],details:void 0},task.resultTruncated)),changed(record);let settlementWarning;try{this.options.onSettled?.(snapshotOf(record),completion?.usage??completion?.result.usage??active.publishedUsage)}catch(accountingError){let warning=`Usage settlement failed: ${errorText2(accountingError)}`;settlementWarning=warning,task.error=boundText([task.error,warning].filter(Boolean).join(`
|
|
652
|
-
`),8192),retainResult(task,{content:[{type:"text",text:warning},...task.result?.content??[]],details:void 0},task.resultTruncated),changed(record)}if(active.publishedUsage=void 0,record.delivery=active.handedOff?"pending":"delivered",!active.handedOff)if(failed)rejectCaller(error);else{let{usage:_usage,...result2}=completion.result;settlementWarning&&(result2.content=[{type:"text",text:settlementWarning},...result2.content]),resolveCaller({kind:"result",result:result2,status:task.status,error:task.error})}for(let waiter of[...record.waiters])waiter();resolveDone(),this.executions.delete(task.id),this.store.trim(),this.emit()};try{let running=execution.run(control);Promise.resolve(running).then(result2=>finish(result2),error=>finish(void 0,error))}catch(error){finish(void 0,error)}return this.emit(),caller}detachable(record){let active=this.executions.get(record.task.id);return!!active&&!record.settled&&!active.detachRequested&&!active.controller.signal.aborted}detachForeground(){if(!this.enabled)return 0;let eligible=[...this.store.records.values()].filter(record=>this.detachable(record)).sort((left,right)=>left.task.startedAt-right.task.startedAt);if(!eligible.length)return 0;let free=this.maxActive-this.backgroundActive();if(free<=0)throw this.limitError();let records=eligible.slice(0,free);for(let record of records)this.prepareDetach(record);for(let record of records)this.finishDetach(record);return this.emit(),records.length}detach(id){let record=this.lookup(id);if(!this.enabled||!this.detachable(record))return!1;if(this.backgroundActive()>=this.maxActive)throw this.limitError();return this.prepareDetach(record),this.finishDetach(record),this.emit(),!0}prepareDetach(record){let active=this.executions.get(record.task.id);active.detachRequested=!0,record.task.mode="background",changed(record),active.accepted&&active.removeParent()}finishDetach(record){let active=this.executions.get(record.task.id);active.handoff();for(let listener of active.modeListeners)try{listener(record.task.mode)}catch{}}list(){return[...this.store.records.values()].filter(record=>record.visible).map(snapshotOf)}lookup(id){let exact=this.store.records.get(id);if(exact)return exact;let matches=[...this.store.records.values()].filter(({task})=>task.id.startsWith(id)||task.id.slice(task.kind.length+1).startsWith(id));if(!id||matches.length!==1)throw new TaskLookupError(matches.length>1?"ambiguous":"unknown",matches.map(snapshotOf));return matches[0]}get(id){return snapshotOf(this.lookup(id))}async read(id,options={}){let record=this.lookup(id),release2=this.retain(record.task.id);try{let task=snapshotOf(record);if(task.outputPath)try{return{task,...await readOutputSlice(task.outputPath,options)}}catch(error){return{task,readError:boundText(`Output could not be read: ${errorText2(error)}`,4096),...sliceText(this.resultText(task),options)}}return{task,readError:record.readError,...sliceText(this.resultText(task),options)}}finally{release2()}}resultText(task){return boundText(task.result?.content.filter(block=>block.type==="text").map(block=>block.text).join(`
|
|
652
|
+
`),8192),retainResult(task,{content:[{type:"text",text:warning},...task.result?.content??[]],details:void 0},task.resultTruncated),changed(record)}if(active.publishedUsage=void 0,record.delivery=active.handedOff?"pending":"delivered",!active.handedOff)if(failed)rejectCaller(error);else{let{usage:_usage,...result2}=completion.result;settlementWarning&&(result2.content=[{type:"text",text:settlementWarning},...result2.content]),resolveCaller({kind:"result",result:result2,status:task.status,error:task.error})}for(let waiter of[...record.waiters])waiter();resolveDone(),this.executions.delete(task.id),this.store.trim(),this.emit()};try{let running=execution.run(control);Promise.resolve(running).then(result2=>finish(result2),error=>finish(void 0,error))}catch(error){finish(void 0,error)}return this.emit(),caller}detachable(record){let active=this.executions.get(record.task.id);return!!active&&!record.settled&&!active.detachRequested&&!active.controller.signal.aborted}detachForeground(){if(!this.enabled)return 0;let eligible=[...this.store.records.values()].filter(record=>this.detachable(record)).sort((left,right)=>left.task.startedAt-right.task.startedAt);if(!eligible.length)return 0;let free=this.maxActive-this.backgroundActive();if(free<=0)throw this.limitError();let records=eligible.slice(0,free);for(let record of records)this.prepareDetach(record);for(let record of records)this.finishDetach(record);return this.emit(),records.length}canDetach(id){let record=this.lookup(id);return this.enabled&&this.backgroundActive()<this.maxActive&&this.detachable(record)}detach(id){let record=this.lookup(id);if(!this.enabled||!this.detachable(record))return!1;if(this.backgroundActive()>=this.maxActive)throw this.limitError();return this.prepareDetach(record),this.finishDetach(record),this.emit(),!0}prepareDetach(record){let active=this.executions.get(record.task.id);active.detachRequested=!0,record.task.mode="background",changed(record),active.accepted&&active.removeParent()}finishDetach(record){let active=this.executions.get(record.task.id);active.handoff();for(let listener of active.modeListeners)try{listener(record.task.mode)}catch{}}list(){return[...this.store.records.values()].filter(record=>record.visible).map(snapshotOf)}lookup(id){let exact=this.store.records.get(id);if(exact)return exact;let matches=[...this.store.records.values()].filter(({task})=>task.id.startsWith(id)||task.id.slice(task.kind.length+1).startsWith(id));if(!id||matches.length!==1)throw new TaskLookupError(matches.length>1?"ambiguous":"unknown",matches.map(snapshotOf));return matches[0]}get(id){return snapshotOf(this.lookup(id))}async read(id,options={}){let record=this.lookup(id),release2=this.retain(record.task.id);try{let task=snapshotOf(record);if(task.outputPath)try{return{task,...await readOutputSlice(task.outputPath,options)}}catch(error){return{task,readError:boundText(`Output could not be read: ${errorText2(error)}`,4096),...sliceText(this.resultText(task),options)}}return{task,readError:record.readError,...sliceText(this.resultText(task),options)}}finally{release2()}}resultText(task){return boundText(task.result?.content.filter(block=>block.type==="text").map(block=>block.text).join(`
|
|
653
653
|
`)||task.error||"No output yet.")}async wait(id,timeoutMs=2e4,signal){if(signal?.aborted)throw signal.reason??new Error("Wait aborted");let record=this.lookup(id);return record.settled?snapshotOf(record):new Promise((resolve18,reject)=>{let finished=!1,timer,complete2=(aborted=!1)=>{finished||(finished=!0,timer!==void 0&&clearTimeout(timer),signal?.removeEventListener("abort",abort),record.waiters.delete(wake),aborted?reject(signal?.reason??new Error("Wait aborted")):resolve18(snapshotOf(record)),this.store.trim(),this.emit())},wake=()=>complete2(),abort=()=>complete2(!0);record.waiters.add(wake),signal?.addEventListener("abort",abort,{once:!0}),timer=setTimeout(wake,finiteLimit(timeoutMs,2e4,6e4)),this.closed&&wake()})}kill(id){return this.cancel(this.lookup(id))}cancel(record){let active=this.executions.get(record.task.id);return!active||record.settled||active.controller.signal.aborted?!1:(record.task.status="stopping",changed(record),active.controller.abort(),this.emit(),!0)}subscribe(listener){return this.closed?()=>{}:(this.listeners.add(listener),()=>{this.listeners.delete(listener)})}retain(id){let record=this.lookup(id);record.pins++;let released=!1;return()=>{released||(released=!0,record.pins--,this.store.trim(),!this.closed&&this.pauses===0&&this.candidate(record)&&this.emit())}}holdDelivery(id){let record=this.lookup(id),releaseRetention=this.retain(id);record.deliveryHolds++;let released=!1;return()=>{released||(released=!0,record.deliveryHolds--,releaseRetention())}}pause(){this.pauses++;let resumed=!1;return()=>{resumed||(resumed=!0,this.pauses--,this.emit())}}pendingNotifications(){return this.closed||this.pauses>0?[]:[...this.store.records.values()].filter(record=>this.candidate(record)).map(snapshotOf)}candidate(record){return record.visible&&record.delivery==="pending"&&record.waiters.size===0&&record.deliveryHolds===0}claimNotification(id){if(this.closed||this.pauses>0)return!1;let record=this.store.records.get(id);return!record||!this.candidate(record)?!1:(record.delivery="claimed",!0)}markDelivered(id){let record=this.store.records.get(id);record&&(record.delivery="delivered",this.store.trim())}releaseNotification(id){let record=this.store.records.get(id);!record||record.delivery!=="claimed"||(record.delivery="pending",this.store.trim(),this.emit())}close(){if(!this.closed){this._closed=!0,this.listeners.clear();for(let record of this.store.records.values()){this.executions.get(record.task.id)?.removeParent(),this.cancel(record);for(let waiter of[...record.waiters])waiter()}this.store.trim()}}async shutdown(graceMs=2e3){this.close(),await this.drain([...this.store.records.values()],graceMs)}activeOutsideBranch(ancestors){return[...this.store.records.values()].filter(record=>!record.settled&&record.task.anchorId!==null&&!ancestors.has(record.task.anchorId)).map(snapshotOf)}async cancelOutsideBranch(ancestors){for(let record of this.store.records.values())record.visible=record.task.anchorId===null||ancestors.has(record.task.anchorId);let outside=[...this.store.records.values()].filter(record=>!record.visible);for(let record of outside)this.cancel(record);this.store.trim(),this.emit(),await this.drain(outside,2e3)}async drain(records,graceMs){let timer;try{await Promise.race([Promise.all(records.map(record=>this.executions.get(record.task.id)?.done)).then(()=>Promise.all(this.store.cleanups)),new Promise(resolve18=>{timer=setTimeout(resolve18,finiteLimit(graceMs,2e3,6e4))})])}finally{timer!==void 0&&clearTimeout(timer)}}emit(){if(!this.closed)for(let listener of[...this.listeners]){if(this.closed)break;try{listener()}catch{}}}};var SYSTEM_PROMPT_SECTION_NAME=/^[a-z][a-z0-9_-]*$/;function normalizeBuildSystemPromptOptions(input2){return{customPrompt:input2.customPrompt,forceSystemPrompt:input2.forceSystemPrompt,selectedTools:[...input2.selectedTools??["read","bash","edit","write"]],toolSnippets:{...input2.toolSnippets??{}},toolGuidelines:Object.fromEntries(Object.entries(input2.toolGuidelines??{}).map(([name,guidelines])=>[name,[...guidelines]])),promptGuidelines:[...input2.promptGuidelines??[]],appendSystemPrompt:input2.appendSystemPrompt??"",sections:{...input2.sections??{}},cwd:input2.cwd,contextFiles:(input2.contextFiles??[]).map(file=>({...file})),skills:(input2.skills??[]).map(skill=>({...skill}))}}function renderProjectContext(contextFiles){return["Project-specific instructions and guidelines:",...contextFiles.map(({path:path14,content})=>`<project_instructions path="${path14}">
|
|
654
654
|
${content}
|
|
655
655
|
</project_instructions>`)].join(`
|
|
@@ -864,7 +864,7 @@ Hint: ${hints.join(`
|
|
|
864
864
|
Hint: `)}`:head;if(markerIndex!==-1){let bounded=truncateHead(received,{maxBytes:RECEIVED_ARGUMENTS_MAX_BYTES,maxLines:RECEIVED_ARGUMENTS_MAX_LINES});enriched+=`${RECEIVED_ARGUMENTS_MARKER}${bounded.content}`,bounded.truncated&&(enriched+=`
|
|
865
865
|
\u2026 (arguments truncated)`)}return new Error(enriched)}function wrapPrepareArguments(definition){let tool={name:definition.name,description:definition.description,parameters:definition.parameters};return raw=>{let args=definition.prepareArguments?definition.prepareArguments(raw):raw;try{validateToolArguments(tool,{type:"toolCall",id:"",name:definition.name,arguments:args})}catch(error){throw enrichValidationError(error,definition.parameters,args)}return args}}function wrapToolDefinition(definition,ctxFactory){return{name:definition.name,label:definition.label,description:definition.description,parameters:definition.parameters,outputSchema:definition.outputSchema,constrainedSampling:definition.constrainedSampling,prepareArguments:wrapPrepareArguments(definition),executionMode:definition.executionMode,execute:(toolCallId,params,signal,onUpdate,ctx)=>definition.execute(toolCallId,params,signal,onUpdate,ctx??ctxFactory?.(toolCallId,signal))}}function createToolDefinitionFromAgentTool(tool){return{name:tool.name,label:tool.label,description:tool.description,parameters:tool.parameters,outputSchema:tool.outputSchema,constrainedSampling:tool.constrainedSampling,prepareArguments:tool.prepareArguments,executionMode:tool.executionMode,execute:async(toolCallId,params,signal,onUpdate)=>tool.execute(toolCallId,params,signal,onUpdate)}}function wrapRegisteredTool(registeredTool,runner){return wrapToolDefinition(registeredTool.definition,(toolCallId,signal)=>runner.createToolContext(toolCallId,signal))}function wrapRegisteredTools(registeredTools,runner){return registeredTools.map(tool=>wrapRegisteredTool(tool,runner))}import*as fs5 from"node:fs";import{createRequire as createRequire5}from"node:module";import*as path7 from"node:path";import{fileURLToPath as fileURLToPath5}from"node:url";import{spawn as spawn3}from"node:child_process";async function execCommand(command,args,cwd,options){return new Promise(resolve18=>{let proc=spawn3(command,args,{cwd,shell:!1,stdio:["ignore","pipe","pipe"]}),stdout="",stderr="",killed=!1,timeoutId,killProcess=()=>{killed||(killed=!0,proc.kill("SIGTERM"),setTimeout(()=>{proc.killed||proc.kill("SIGKILL")},5e3))};options?.signal&&(options.signal.aborted?killProcess():options.signal.addEventListener("abort",killProcess,{once:!0})),options?.timeout&&options.timeout>0&&(timeoutId=setTimeout(()=>{killProcess()},options.timeout)),proc.stdout?.on("data",data=>{stdout+=data.toString()}),proc.stderr?.on("data",data=>{stderr+=data.toString()}),waitForChildProcess(proc).then(code=>{timeoutId&&clearTimeout(timeoutId),options?.signal&&options.signal.removeEventListener("abort",killProcess),resolve18({stdout,stderr,code:code??0,killed})}).catch(_err=>{timeoutId&&clearTimeout(timeoutId),options?.signal&&options.signal.removeEventListener("abort",killProcess),resolve18({stdout,stderr,code:1,killed})})})}var MCP_EXPOSURES=["codemode","deferred","direct","hidden"],MCP_EXPOSURE_ALIASES={"codemode-deferred":"codemode"},LOOPBACK_HOSTS=["localhost","127.0.0.1","[::1]"];function isLoopbackRedirectUri(value){if(!URL.canParse(value))return!1;let url=new URL(value);return url.protocol==="http:"&&LOOPBACK_HOSTS.includes(url.hostname)&&url.search===""&&url.hash===""}var SERVER_NAME=/^[A-Za-z0-9_-]+$/;function mcpNamespace(server){return`mcp__${server.replace(/-/g,"_")}`}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isStringRecord(value){return isRecord3(value)&&Object.values(value).every(entry=>typeof entry=="string")}function validateOAuth(value){if(value===void 0)return;if(!isRecord3(value))return"oauth must be an object";if(value.clientId!==void 0&&typeof value.clientId!="string")return"oauth.clientId must be a string";if(value.clientSecret!==void 0&&typeof value.clientSecret!="string")return"oauth.clientSecret must be a string";let port=value.callbackPort;if(port!==void 0&&(typeof port!="number"||!Number.isInteger(port)||port<1||port>65535))return"oauth.callbackPort must be a port number";if(value.callbackUrl!==void 0){if(typeof value.callbackUrl!="string"||!isLoopbackRedirectUri(value.callbackUrl))return"oauth.callbackUrl must be an http URI on localhost, 127.0.0.1, or [::1] without query or fragment";let urlPort=new URL(value.callbackUrl).port;if(urlPort&&port!==void 0&&Number(urlPort)!==port)return"oauth.callbackUrl and oauth.callbackPort name different ports"}if(value.scope!==void 0&&typeof value.scope!="string")return"oauth.scope must be a string";if(value.clientName!==void 0&&(typeof value.clientName!="string"||!value.clientName.trim()))return"oauth.clientName must be a non-empty string";if(value.clientRegistration!==void 0&&value.clientRegistration!=="dcr"){if(value.clientRegistration!=="cimd")return'oauth.clientRegistration must be "dcr" or "cimd"';if(value.clientId!==void 0||value.clientName!==void 0)return'oauth.clientRegistration "cimd" cannot be combined with oauth.clientId or oauth.clientName';let callback=typeof value.callbackUrl=="string"?new URL(value.callbackUrl):void 0;if(callback&&(callback.hostname==="[::1]"||callback.pathname!=="/callback"))return'oauth.clientRegistration "cimd" requires oauth.callbackUrl on localhost or 127.0.0.1 with path /callback'}let metadataUrl=value.authServerMetadataUrl;if(metadataUrl!==void 0){let url=typeof metadataUrl=="string"&&URL.canParse(metadataUrl)?new URL(metadataUrl):void 0;if(!url||!(url.protocol==="https:"||url.protocol==="http:"&&LOOPBACK_HOSTS.includes(url.hostname)))return"oauth.authServerMetadataUrl must be an https URL, or http on localhost, 127.0.0.1, or [::1]"}}function isExposure(value){return typeof value=="string"&&MCP_EXPOSURES.includes(value)}function resolveExposureAlias(value){return typeof value=="string"?MCP_EXPOSURE_ALIASES[value]??value:value}function resolveExposureAliases(value){let{exposure,toolExposure}=value,resolved={...value};return exposure!==void 0&&(resolved.exposure=resolveExposureAlias(exposure)),isRecord3(toolExposure)&&(resolved.toolExposure=Object.fromEntries(Object.entries(toolExposure).map(([tool,entry])=>[tool,resolveExposureAlias(entry)]))),resolved}function toolPatternRegExp(pattern){let source=pattern.split("*").map(part=>part.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${source}$`)}function getMcpToolExposure(config,toolName){let overrides=config.toolExposure??{},exact=overrides[toolName];if(exact!==void 0)return exact;for(let[pattern,exposure]of Object.entries(overrides))if(pattern.includes("*")&&toolPatternRegExp(pattern).test(toolName))return exposure;return config.exposure??"codemode"}function validateMcpServerConfig(name,raw){if(!SERVER_NAME.test(name))return`invalid server name "${name}" (use letters, digits, "_" and "-")`;if(!isRecord3(raw))return`server "${name}" must be an object`;let value=resolveExposureAliases(raw),{type,exposure,enabled,timeout,toolExposure,description}=value,exposures=MCP_EXPOSURES.map(value2=>`"${value2}"`).join(", ");if(exposure!==void 0&&!isExposure(exposure))return`server "${name}": exposure must be one of ${exposures}`;if(toolExposure!==void 0){if(!isRecord3(toolExposure))return`server "${name}": toolExposure must map tool names to exposures`;for(let[tool,value2]of Object.entries(toolExposure))if(!isExposure(value2))return`server "${name}": toolExposure "${tool}" must be one of ${exposures}`}if(enabled!==void 0&&typeof enabled!="boolean")return`server "${name}": enabled must be a boolean`;if(description!==void 0&&typeof description!="string")return`server "${name}": description must be a string`;if(timeout!==void 0&&(typeof timeout!="number"||!(timeout>0)))return`server "${name}": timeout must be a positive number of seconds`;if(type==="sse")return`server "${name}": legacy SSE transport is not supported; use the streamable HTTP URL`;if(typeof value.url=="string"&&(type===void 0||type==="http"||type==="streamable-http")){if(!URL.canParse(value.url)||!/^https?:$/.test(new URL(value.url).protocol))return`server "${name}": url must be an http or https URL`;if(value.headers!==void 0&&!isStringRecord(value.headers))return`server "${name}": headers must map names to strings`;let oauthError=validateOAuth(value.oauth);if(oauthError)return`server "${name}": ${oauthError}`;if(value.auth!==void 0){if(!isRecord3(value.auth)||typeof value.auth.provider!="string"||!value.auth.provider)return`server "${name}": auth.provider must be a provider name`;let url=new URL(value.url);if(url.protocol!=="https:"&&!LOOPBACK_HOSTS.includes(url.hostname))return`server "${name}": auth requires an https URL, or http on localhost, 127.0.0.1, or [::1]`}return value}return typeof value.command=="string"&&(type===void 0||type==="stdio")?value.args!==void 0&&!(Array.isArray(value.args)&&value.args.every(arg=>typeof arg=="string"))?`server "${name}": args must be an array of strings`:value.env!==void 0&&!isStringRecord(value.env)?`server "${name}": env must map names to strings`:value.cwd!==void 0&&typeof value.cwd!="string"?`server "${name}": cwd must be a string`:value:`server "${name}" needs either "command" (stdio) or "url" (streamable HTTP)`}var McpServerRegistry=class{constructor(){this.servers=new Map}register(server){this.servers.set(server.name,server),this.changeListener?.()}unregister(name,extensionPath){this.servers.get(name)?.extensionPath===extensionPath&&(this.servers.delete(name),this.changeListener?.())}get(name){return this.servers.get(name)}list(){return[...this.servers.values()].map(server=>({...server,config:structuredClone(server.config)}))}setChangeListener(listener){this.changeListener=listener}};var ENABLED=process.env.PI_TIMING==="1",timingNamespaces=new Map;function resetTimings(namespace="main"){ENABLED&&timingNamespaces.set(namespace,{timings:[],lastTime:Date.now()})}function time(label,namespace="main"){if(!ENABLED)return;let now=Date.now();timingNamespaces.has(namespace)||resetTimings(namespace);let timingNamespace=timingNamespaces.get(namespace);timingNamespace.timings.push({label,ms:now-timingNamespace.lastTime}),timingNamespace.lastTime=now}function printTimingGroup(title,timings){let printableTimings=timings.filter(timing=>timing.ms>=0);if(printableTimings.length!==0){console.error(`
|
|
866
866
|
--- ${title} ---`);for(let t of printableTimings)console.error(` ${t.label}: ${t.ms}ms`);console.error(` TOTAL: ${printableTimings.reduce((a,b2)=>a+b2.ms,0)}ms`),console.error(`${"-".repeat(title.length+8)}
|
|
867
|
-
`)}}function printTimings(){if(ENABLED)for(let[namespace,timingNamespace]of timingNamespaces)printTimingGroup(`Startup Timings: ${namespace}`,timingNamespace.timings)}var require3=createRequire5(import.meta.url),isNodeSeaBinary="sea"in process.features&&process.features.sea===!0||process.getBuiltinModule("node:sea")?.isSea()===!0,isTypeScriptSourceRuntime=!isBunBinary&&path7.extname(fileURLToPath5(import.meta.url))===".ts",usesEmbeddedModules=isBunBinary||isNodeSeaBinary||isBundledNode,createJitiPromise;function getCreateJiti(){return createJitiPromise??=(usesEmbeddedModules?import("./jiti-static-loader-CLT3YR3B.js"):import("./jiti-loader-BFSSLU7G.js")).then(module=>module.createJiti),createJitiPromise}var virtualModulesPromise;function getVirtualModules(){return virtualModulesPromise??=import("./virtual-modules-YFKU7JZF.js").then(module=>module.VIRTUAL_MODULES),virtualModulesPromise}var _aliases=null;function getAliases(){if(_aliases)return _aliases;let __dirname2=path7.dirname(fileURLToPath5(import.meta.url)),packageIndex=path7.resolve(__dirname2,"../..","index.js"),typeboxEntry=require3.resolve("typebox"),typeboxCompileEntry=require3.resolve("typebox/compile"),typeboxValueEntry=require3.resolve("typebox/value"),resolveImport=specifier=>fileURLToPath5(import.meta.resolve(specifier)),piCodingAgentEntry=packageIndex,piAgentCoreEntry=resolveImport("@earendil-works/pi-agent-core"),piTuiEntry=resolveImport("@earendil-works/pi-tui"),piAiCompatEntry=resolveImport("@earendil-works/pi-ai/compat"),piAiOauthEntry=resolveImport("@earendil-works/pi-ai/oauth"),piAiProvidersEntry=resolveImport("@earendil-works/pi-ai/providers/all");return _aliases={"@earendil-works/pi-coding-agent":piCodingAgentEntry,[DISTRIBUTION_PACKAGE_NAME]:piCodingAgentEntry,"@earendil-works/pi-agent-core":piAgentCoreEntry,"@earendil-works/pi-tui":piTuiEntry,"@earendil-works/pi-ai/providers/all":piAiProvidersEntry,"@earendil-works/pi-ai/compat":piAiCompatEntry,"@earendil-works/pi-ai/oauth":piAiOauthEntry,"@earendil-works/pi-ai":piAiCompatEntry,"@mariozechner/pi-coding-agent":piCodingAgentEntry,"@mariozechner/pi-agent-core":piAgentCoreEntry,"@mariozechner/pi-tui":piTuiEntry,"@mariozechner/pi-ai/providers/all":piAiProvidersEntry,"@mariozechner/pi-ai/compat":piAiCompatEntry,"@mariozechner/pi-ai/oauth":piAiOauthEntry,"@mariozechner/pi-ai":piAiCompatEntry,typebox:typeboxEntry,"typebox/compile":typeboxCompileEntry,"typebox/value":typeboxValueEntry,"@sinclair/typebox":typeboxEntry,"@sinclair/typebox/compile":typeboxCompileEntry,"@sinclair/typebox/value":typeboxValueEntry},_aliases}var extensionCacheCwd,extensionCacheGeneration=0,extensionCache=new Map;function clearExtensionCache(){extensionCache.clear(),extensionCacheCwd=void 0,extensionCacheGeneration++}function useExtensionCacheCwd(cwd){let resolvedCwd=resolvePath(cwd);return extensionCacheCwd!==void 0&&extensionCacheCwd!==resolvedCwd&&clearExtensionCache(),extensionCacheCwd=resolvedCwd,{cwd:resolvedCwd,generation:extensionCacheGeneration}}function createExtensionRuntime(){let notInitialized=()=>{throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.")},state2={},eventBusUnsubscribers=new Set,assertActive=()=>{if(state2.staleMessage)throw new Error(state2.staleMessage)},runtime={sendMessage:notInitialized,sendUserMessage:notInitialized,appendEntry:notInitialized,setSessionName:notInitialized,getSessionName:notInitialized,setLabel:notInitialized,getActiveTools:notInitialized,getAllTools:notInitialized,getSettings:notInitialized,setActiveTools:notInitialized,refreshTools:()=>{},getCommands:notInitialized,setModel:()=>Promise.reject(new Error("Extension runtime not initialized")),getThinkingLevel:notInitialized,setThinkingLevel:notInitialized,flagValues:new Map,pendingProviderRegistrations:[],pendingNativeProviderRegistrations:[],mcpServers:new McpServerRegistry,pendingVirtualModelRegistrations:[],createContext:notInitialized,assertActive,invalidate:message=>{if(!state2.staleMessage){state2.staleMessage=message??"This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().";for(let unsubscribe of eventBusUnsubscribers)unsubscribe();eventBusUnsubscribers.clear()}},trackEventBusSubscription:unsubscribe=>{let active=!0,trackedUnsubscribe=()=>{active&&(active=!1,eventBusUnsubscribers.delete(trackedUnsubscribe),unsubscribe())};return eventBusUnsubscribers.add(trackedUnsubscribe),trackedUnsubscribe},registerProvider:(name,config,extensionPath="<unknown>")=>{runtime.pendingProviderRegistrations.push({name,config,extensionPath})},registerNativeProvider:(provider,extensionPath="<unknown>")=>{runtime.pendingNativeProviderRegistrations.push({provider,extensionPath})},unregisterProvider:name=>{runtime.pendingProviderRegistrations=runtime.pendingProviderRegistrations.filter(r=>r.name!==name),runtime.pendingNativeProviderRegistrations=runtime.pendingNativeProviderRegistrations.filter(r=>r.provider.id!==name)},registerVirtualModel:(definition,extensionPath="<unknown>")=>{runtime.pendingVirtualModelRegistrations.push({definition,extensionPath})},unregisterVirtualModel:(provider,id)=>{runtime.pendingVirtualModelRegistrations=runtime.pendingVirtualModelRegistrations.filter(({definition})=>definition.provider!==provider||definition.id!==id)}};return runtime}function createExtensionAPI(extension,runtime,cwd,eventBus){let pendingFlagValues=new Map,pendingRuntimeChanges=[],loadingUnsubscribers=[],state2="loading",assertActive=()=>{if(state2==="failed")throw new Error(`Extension "${extension.path}" failed to load and its API is no longer active.`);runtime.assertActive()},applyRuntimeChange=change=>{state2==="loading"?pendingRuntimeChanges.push(change):change()},clearPending=()=>{pendingFlagValues.clear(),pendingRuntimeChanges.length=0,loadingUnsubscribers.length=0};return{api:{on(event,handler){assertActive();let registeredHandler=(...args)=>handler(...args),list2=extension.handlers.get(event)??[];return list2.push(registeredHandler),extension.handlers.set(event,list2),()=>{let handlers=extension.handlers.get(event);if(!handlers)return;let handlerIndex=handlers.indexOf(registeredHandler);handlerIndex!==-1&&(handlers.splice(handlerIndex,1),handlers.length===0&&extension.handlers.delete(event))}},registerTool(tool){if(assertActive(),typeof tool.parameters!="object"||tool.parameters===null||Array.isArray(tool.parameters))throw new Error(`Tool "${tool.name}" registered by extension "${extension.path}" must define an object parameter schema.`);extension.tools.set(tool.name,{definition:tool,sourceInfo:extension.sourceInfo}),runtime.refreshTools()},registerCommand(name,options){if(assertActive(),typeof name!="string"||name.length===0)throw new Error(`Command registered by extension "${extension.path}" must have a non-empty string name. Use pi.registerCommand("name", { description, handler }).`);if(typeof options?.handler!="function")throw new Error(`Command "/${name}" registered by extension "${extension.path}" must define handler().`);extension.commands.set(name,{name,sourceInfo:extension.sourceInfo,...options})},registerShortcut(shortcut,options){assertActive(),extension.shortcuts.set(shortcut,{shortcut,extensionPath:extension.path,...options})},registerFlag(name,options){if(assertActive(),options.default!==void 0&&typeof options.default!==options.type)throw new Error(`Invalid default for flag "${name}": expected ${options.type}, got ${typeof options.default}`);extension.flags.set(name,{name,extensionPath:extension.path,...options}),options.default!==void 0&&!runtime.flagValues.has(name)&&(state2==="loading"?pendingFlagValues.has(name)||pendingFlagValues.set(name,options.default):runtime.flagValues.set(name,options.default))},registerMessageRenderer(customType,renderer){assertActive(),extension.messageRenderers.set(customType,renderer)},registerMarkdownTransformer(transformer){assertActive(),extension.markdownTransformer=transformer},registerEntryRenderer(customType,renderer){assertActive(),extension.entryRenderers??=new Map,extension.entryRenderers.set(customType,renderer)},registerToolRenderer(resolver){assertActive(),extension.toolRenderers??=[],extension.toolRenderers.push(resolver)},getFlag(name){if(assertActive(),!!extension.flags.has(name))return runtime.flagValues.has(name)?runtime.flagValues.get(name):pendingFlagValues.get(name)},sendMessage(message,options){assertActive(),runtime.sendMessage(message,options)},sendUserMessage(content,options){assertActive(),runtime.sendUserMessage(content,options)},appendEntry(customType,data){assertActive(),runtime.appendEntry(customType,data)},setSessionName(name){assertActive(),runtime.setSessionName(name)},getSessionName(){return assertActive(),runtime.getSessionName()},setLabel(entryId,label){assertActive(),runtime.setLabel(entryId,label)},exec(command,args,options){return assertActive(),execCommand(command,args,options?.cwd??cwd,options)},getActiveTools(){return assertActive(),runtime.getActiveTools()},getAllTools(){return assertActive(),runtime.getAllTools()},getSettings(){return assertActive(),runtime.getSettings()},setActiveTools(toolNames){assertActive(),runtime.setActiveTools(toolNames)},getCommands(){return assertActive(),runtime.getCommands()},setModel(model){return assertActive(),runtime.setModel(model)},getThinkingLevel(){return assertActive(),runtime.getThinkingLevel()},setThinkingLevel(level){assertActive(),runtime.setThinkingLevel(level)},registerProvider(providerOrName,config){if(assertActive(),typeof providerOrName=="string"){if(!config)throw new Error("Provider config is required when registering by name");applyRuntimeChange(()=>runtime.registerProvider(providerOrName,config,extension.path));return}applyRuntimeChange(()=>runtime.registerNativeProvider(providerOrName,extension.path))},unregisterProvider(name){assertActive(),applyRuntimeChange(()=>runtime.unregisterProvider(name,extension.path))},registerMcpServer(name,config){assertActive();let validated=validateMcpServerConfig(name,config);if(typeof validated=="string")throw new Error(`Invalid MCP server registered by extension "${extension.path}": ${validated}`);let owner=runtime.mcpServers.get(name)?.extensionPath;if(owner!==void 0&&owner!==extension.path)throw new Error(`MCP server "${name}" is already registered by extension "${owner}"`);let clash=runtime.mcpServers.list().find(server2=>server2.name!==name&&mcpNamespace(server2.name)===mcpNamespace(name));if(clash)throw new Error(`MCP server "${name}" conflicts with registered server "${clash.name}"`);let server={name,config:structuredClone(validated),extensionPath:extension.path};applyRuntimeChange(()=>runtime.mcpServers.register(server))},unregisterMcpServer(name){assertActive(),applyRuntimeChange(()=>runtime.mcpServers.unregister(name,extension.path))},getMcpServers(){return assertActive(),runtime.mcpServers.list()},registerVirtualModel(model){assertActive();let definition={...model,route:request=>model.route(request,runtime.createContext())};applyRuntimeChange(()=>runtime.registerVirtualModel(definition,extension.path))},unregisterVirtualModel(provider,id){assertActive(),applyRuntimeChange(()=>runtime.unregisterVirtualModel(provider,id))},events:{emit(channel,data){assertActive(),eventBus.emit(channel,data)},on(channel,handler){assertActive();let unsubscribe=runtime.trackEventBusSubscription(eventBus.on(channel,handler));return state2==="loading"&&loadingUnsubscribers.push(unsubscribe),unsubscribe}}},commit:()=>{if(state2==="loading"){runtime.assertActive();for(let[name,value]of pendingFlagValues)runtime.flagValues.has(name)||runtime.flagValues.set(name,value);for(let apply of pendingRuntimeChanges)apply();state2="active",clearPending()}},discard:()=>{if(state2==="loading"){state2="failed";for(let unsubscribe of loadingUnsubscribers)unsubscribe();clearPending()}}}}function isCurrentCacheToken(cacheToken){return cacheToken!==void 0&&extensionCacheCwd===cacheToken.cwd&&extensionCacheGeneration===cacheToken.generation}async function loadExtensionModule(extensionPath,cacheToken){if(isCurrentCacheToken(cacheToken)){let cachedFactory=extensionCache.get(extensionPath);if(cachedFactory)return cachedFactory}let createJitiImpl=await getCreateJiti(),resolutionOptions=usesEmbeddedModules?{virtualModules:await getVirtualModules(),tryNative:!1}:isTypeScriptSourceRuntime?{virtualModules:await getVirtualModules(),tsconfigPaths:!0}:{alias:getAliases()},factory=await createJitiImpl(import.meta.url,{moduleCache:!1,...resolutionOptions}).import(extensionPath,{default:!0});if(typeof factory=="function")return isCurrentCacheToken(cacheToken)&&extensionCache.set(extensionPath,factory),factory}function createExtension(extensionPath,resolvedPath){let source=getSyntheticPathSource(extensionPath)??"local",baseDir=isSyntheticPath(extensionPath)?void 0:path7.dirname(resolvedPath);return{path:extensionPath,resolvedPath,sourceInfo:createSyntheticSourceInfo(extensionPath,{source,baseDir}),handlers:new Map,tools:new Map,messageRenderers:new Map,entryRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}async function initializeExtension(factory,extensionPath,resolvedPath,cwd,eventBus,runtime){let extension=createExtension(extensionPath,resolvedPath),load=createExtensionAPI(extension,runtime,cwd,eventBus);try{await factory(load.api),load.commit()}catch(error){throw load.discard(),error}return time(`${extensionPath} factory`,"extensions"),extension}async function loadExtension(extensionPath,cwd,eventBus,runtime,cacheToken){let resolvedPath=resolvePath(extensionPath,cwd,{normalizeUnicodeSpaces:!0});try{let factory=await loadExtensionModule(resolvedPath,cacheToken);return time(`${extensionPath} module import`,"extensions"),factory?{extension:await initializeExtension(factory,extensionPath,resolvedPath,cwd,eventBus,runtime),error:null}:{extension:null,error:`Extension does not export a valid factory function: ${extensionPath}`}}catch(err){return{extension:null,error:`Failed to load extension: ${err instanceof Error?err.message:String(err)}`}}}async function loadExtensionFromFactory(factory,cwd,eventBus,runtime,extensionPath="<inline>"){let resolvedCwd=resolvePath(cwd);return initializeExtension(factory,extensionPath,extensionPath,resolvedCwd,eventBus,runtime)}async function loadExtensionsInternal(paths,cwd,eventBus,runtime,useCache=!1){let extensions=[],errors=[],warnings=[],cacheToken=useCache?useExtensionCacheCwd(cwd):void 0,resolvedCwd=cacheToken?.cwd??resolvePath(cwd),resolvedEventBus=eventBus??createEventBus(),resolvedRuntime=runtime??createExtensionRuntime();for(let extPath of paths){let{extension,error}=await loadExtension(extPath,resolvedCwd,resolvedEventBus,resolvedRuntime,cacheToken);if(error){errors.push({path:extPath,error});continue}extension&&extensions.push(extension)}return{extensions,errors,warnings,runtime:resolvedRuntime}}async function loadExtensions(paths,cwd,eventBus,runtime){return loadExtensionsInternal(paths,cwd,eventBus,runtime)}async function loadExtensionsCached(paths,cwd,eventBus,runtime){return loadExtensionsInternal(paths,cwd,eventBus,runtime,!0)}function isExtensionFile(name){return name.endsWith(".ts")||name.endsWith(".js")}function resolveExtensionEntries2(dir){let packageJsonPath=path7.join(dir,"package.json");if(fs5.existsSync(packageJsonPath)){let manifest=readPiManifest(packageJsonPath);if(manifest?.extensions?.length){let entries=[];for(let extPath of manifest.extensions){let resolvedExtPath=path7.resolve(dir,extPath);fs5.existsSync(resolvedExtPath)&&entries.push(resolvedExtPath)}if(entries.length>0)return entries}}let indexTs=path7.join(dir,"index.ts"),indexJs=path7.join(dir,"index.js");return fs5.existsSync(indexTs)?[indexTs]:fs5.existsSync(indexJs)?[indexJs]:null}function discoverExtensionsInDir(dir){if(!fs5.existsSync(dir))return[];let discovered=[];try{let entries=fs5.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){let entryPath=path7.join(dir,entry.name);if((entry.isFile()||entry.isSymbolicLink())&&isExtensionFile(entry.name)){discovered.push(entryPath);continue}if(entry.isDirectory()||entry.isSymbolicLink()){let entries2=resolveExtensionEntries2(entryPath);entries2&&discovered.push(...entries2)}}}catch{return[]}return discovered}async function discoverAndLoadExtensions(configuredPaths,cwd,agentDir=getAgentDir(),eventBus){let resolvedCwd=resolvePath(cwd),resolvedAgentDir=resolvePath(agentDir),allPaths=[],seen=new Set,addPaths=paths=>{for(let p of paths){let resolved=path7.resolve(p);seen.has(resolved)||(seen.add(resolved),allPaths.push(p))}},localExtDir=path7.join(resolvedCwd,CONFIG_DIR_NAME,"extensions");addPaths(discoverExtensionsInDir(localExtDir));let globalExtDir=path7.join(resolvedAgentDir,"extensions");addPaths(discoverExtensionsInDir(globalExtDir));for(let p of configuredPaths){let resolved=resolvePath(p,resolvedCwd,{normalizeUnicodeSpaces:!0});if(fs5.existsSync(resolved)&&fs5.statSync(resolved).isDirectory()){let entries=resolveExtensionEntries2(resolved);if(entries){addPaths(entries);continue}addPaths(discoverExtensionsInDir(resolved));continue}addPaths([resolved])}return loadExtensions(allPaths,resolvedCwd,eventBus)}var ModelRegistry=class{constructor(runtime){this.runtime=runtime}getRuntime(){return this.runtime}refresh(options){return this.runtime.refresh(options)}getError(){return this.runtime.getError()}getAll(){return[...this.runtime.getModels()]}getAvailable(){return[...this.runtime.getAvailableSnapshot()]}find(provider,modelId){return this.runtime.getModel(provider,modelId)}findOfType(type,provider,modelId){return this.runtime.getModelOfType(type,provider,modelId)}hasConfiguredAuth(model){return this.runtime.hasConfiguredAuth(model.provider)}async getApiKeyAndHeaders(model){try{let resolution=await this.runtime.getAuth(model);if(!resolution){let compatibility=this.runtime.getCompatibilityRequestConfig(model);return compatibility.authHeader?{ok:!1,error:`No API key found for "${model.provider}"`}:{ok:!0,headers:compatibility.headers}}return{ok:!0,apiKey:resolution.auth.apiKey,headers:resolution.auth.headers,...resolution.auth.baseUrl?{baseUrl:resolution.auth.baseUrl}:{},env:resolution.env}}catch(error){let cause=error instanceof Error?error.cause:void 0,message=cause instanceof Error?cause.message:error instanceof Error?error.message:String(error);return{ok:!1,error:message==="authHeader requires a resolved API key"?`No API key found for "${model.provider}"`:message}}}getProviderAuthStatus(provider){return this.runtime.getProviderAuthStatus(provider)}getProvider(provider){return this.runtime.getProvider(provider)}stream(model,context,options){return this.runtime.stream(model,context,options)}streamSimple(model,context,options){return this.runtime.streamSimple(model,context,options)}complete(model,context,options){return this.runtime.complete(model,context,options)}getModelsOfType(type,provider){return this.runtime.getModelsOfType(type,provider)}getAvailableOfType(type,provider,options){return this.runtime.getAvailableOfType(type,provider,options)}getModelOfType(type,provider,modelId){return this.runtime.getModelOfType(type,provider,modelId)}classify(model,context,options){return this.runtime.classify(model,context,options)}generateImages(model,context,options){return this.runtime.generateImages(model,context,options)}getProviderDisplayName(provider){return this.runtime.getProvider(provider)?.name??provider}getProviderAuth(provider){return this.runtime.getAuth(provider)}async getApiKeyForProvider(provider){try{return(await this.runtime.getAuth(provider))?.auth.apiKey}catch{return}}isUsingOAuth(model){return this.runtime.isUsingOAuth(model.provider)}registerProvider(providerOrName,config){if(typeof providerOrName=="string"){if(!config)throw new Error("Provider config is required when registering by name");this.runtime.registerProvider(providerOrName,config);return}this.runtime.registerNativeProvider(providerOrName)}unregisterProvider(providerName){this.runtime.unregisterProvider(providerName)}registerVirtualModel(definition){this.runtime.registerVirtualModel(definition)}unregisterVirtualModel(providerName,id){this.runtime.unregisterVirtualModel(providerName,id)}getRegisteredProviderConfig(providerName){return this.runtime.getRegisteredProviderConfig(providerName)}getRegisteredNativeProvider(providerName){return this.runtime.getRegisteredNativeProvider(providerName)}getRegisteredProviderIds(){return this.runtime.getRegisteredProviderIds()}};function truncateToVisualLines(text2,maxVisualLines,width,paddingX=0,keep="end"){if(!text2)return{visualLines:[],skippedCount:0};let allVisualLines=new Text(text2,paddingX,0).render(width);if(allVisualLines.length<=maxVisualLines)return{visualLines:allVisualLines,skippedCount:0};let truncatedLines=keep==="start"?allVisualLines.slice(0,maxVisualLines):allVisualLines.slice(-maxVisualLines),skippedCount=allVisualLines.length-maxVisualLines;return{visualLines:truncatedLines,skippedCount}}var VisualLinePreview=class{constructor(options){this.options=options}render(width){if(this.cachedLines===void 0||this.cachedWidth!==width){let{text:text2,maxVisualLines,keep,formatHint}=this.options,preview=truncateToVisualLines(text2,maxVisualLines,width,0,keep),lines=preview.visualLines;if(preview.skippedCount>0){let hint=truncateToWidth(formatHint(preview.skippedCount),width,"...");this.cachedLines=keep==="start"?[...lines,hint]:[hint,...lines]}else this.cachedLines=lines;this.cachedWidth=width}return this.cachedLines}invalidate(){this.cachedWidth=void 0,this.cachedLines=void 0}};import{unlink as unlink2}from"node:fs/promises";import{randomBytes}from"node:crypto";import{closeSync as closeSync2,createWriteStream,openSync as openSync2,writeSync}from"node:fs";import{open as open3}from"node:fs/promises";import{tmpdir as tmpdir2}from"node:os";import{join as join20}from"node:path";function defaultTempFilePath(prefix){let id=randomBytes(8).toString("hex");return join20(tmpdir2(),`${prefix}-${id}.log`)}function byteLength(text2){return Buffer.byteLength(text2,"utf-8")}var OutputAccumulator=class{constructor(options={}){if(this.decoder=new TextDecoder,this.rawChunks=[],this.tailText="",this.tailBytes=0,this.tailStartsAtLineBoundary=!0,this.totalRawBytes=0,this.totalDecodedBytes=0,this.completedLines=0,this.totalLines=0,this.currentLineBytes=0,this.hasOpenLine=!1,this.finished=!1,this.maxLines=options.maxLines??2e3,this.maxBytes=options.maxBytes??51200,this.maxRollingBytes=Math.max(this.maxBytes*2,1),this.tempFilePrefix=options.tempFilePrefix??"pi-output",options.persistFromStart){let path14=defaultTempFilePath(this.tempFilePrefix);this.tempFileFd=openSync2(path14,"wx",384),this.tempFilePath=path14}}append(data){if(this.finished)throw new Error("Cannot append to a finished output accumulator");if(this.totalRawBytes+=data.length,this.appendDecodedText(this.decoder.decode(data,{stream:!0})),this.tempFileFd!==void 0){let offset=0;for(;offset<data.length;){let written=writeSync(this.tempFileFd,data,offset,data.length-offset);if(written===0)throw new Error("Output file write made no progress");offset+=written}}else this.tempFileStream||this.shouldUseTempFile()?(this.ensureTempFile(),this.tempFileStream?.write(data)):data.length>0&&this.rawChunks.push(data)}finish(){this.finished||(this.finished=!0,this.appendDecodedText(this.decoder.decode()),this.shouldUseTempFile()&&this.ensureTempFile())}snapshot(options={}){let maxBytes=Math.min(this.maxBytes,options.maxBytes??this.maxBytes),tailTruncation=truncateTail(this.getSnapshotText(),{maxLines:this.maxLines,maxBytes}),truncated=this.totalLines>this.maxLines||this.totalDecodedBytes>maxBytes,truncatedBy=truncated?tailTruncation.truncatedBy??(this.totalDecodedBytes>maxBytes?"bytes":"lines"):null,truncation={...tailTruncation,truncated,truncatedBy,totalLines:this.totalLines,totalBytes:this.totalDecodedBytes,maxLines:this.maxLines,maxBytes};return options.persistIfTruncated&&truncation.truncated&&this.ensureTempFile(),{content:truncation.content,truncation,fullOutputPath:this.tempFilePath}}getTotalBytes(){return this.totalRawBytes}async closeTempFile(){if(this.tempFileFd!==void 0){let fd=this.tempFileFd;this.tempFileFd=void 0,closeSync2(fd)}if(!this.tempFileStream)return;let stream2=this.tempFileStream;this.tempFileStream=void 0,await new Promise((resolve18,reject)=>{let onError=error=>{stream2.off("finish",onFinish),reject(error)},onFinish=()=>{stream2.off("error",onError),resolve18()};stream2.once("error",onError),stream2.once("finish",onFinish),stream2.end()})}async readFullOutput(maxBytes){if(!this.tempFilePath)return{content:new TextDecoder().decode(Buffer.concat(this.rawChunks)),truncated:!1};let file=await open3(this.tempFilePath,"r");try{let size=(await file.stat()).size;if(size<=maxBytes)return{content:new TextDecoder().decode(await file.readFile()),truncated:!1};let headBytes=Math.floor(maxBytes/2),tailBytes=maxBytes-headBytes,head=Buffer.alloc(headBytes),tail2=Buffer.alloc(tailBytes);await file.read(head,0,headBytes,0),await file.read(tail2,0,tailBytes,size-tailBytes);let headText=new TextDecoder().decode(head,{stream:!0}),tailStart=0;for(;tailStart<tail2.length&&(tail2[tailStart]&192)===128;)tailStart++;let tailText=new TextDecoder().decode(tail2.subarray(tailStart)),omitted=size-headBytes-tailBytes;return{content:`${headText}
|
|
867
|
+
`)}}function printTimings(){if(ENABLED)for(let[namespace,timingNamespace]of timingNamespaces)printTimingGroup(`Startup Timings: ${namespace}`,timingNamespace.timings)}var require3=createRequire5(import.meta.url),isNodeSeaBinary="sea"in process.features&&process.features.sea===!0||process.getBuiltinModule("node:sea")?.isSea()===!0,isTypeScriptSourceRuntime=!isBunBinary&&path7.extname(fileURLToPath5(import.meta.url))===".ts",usesEmbeddedModules=isBunBinary||isNodeSeaBinary||isBundledNode,createJitiPromise;function getCreateJiti(){return createJitiPromise??=(usesEmbeddedModules?import("./jiti-static-loader-CLT3YR3B.js"):import("./jiti-loader-BFSSLU7G.js")).then(module=>module.createJiti),createJitiPromise}var virtualModulesPromise;function getVirtualModules(){return virtualModulesPromise??=import("./virtual-modules-UUHBXSJB.js").then(module=>module.VIRTUAL_MODULES),virtualModulesPromise}var _aliases=null;function getAliases(){if(_aliases)return _aliases;let __dirname2=path7.dirname(fileURLToPath5(import.meta.url)),packageIndex=path7.resolve(__dirname2,"../..","index.js"),typeboxEntry=require3.resolve("typebox"),typeboxCompileEntry=require3.resolve("typebox/compile"),typeboxValueEntry=require3.resolve("typebox/value"),resolveImport=specifier=>fileURLToPath5(import.meta.resolve(specifier)),piCodingAgentEntry=packageIndex,piAgentCoreEntry=resolveImport("@earendil-works/pi-agent-core"),piTuiEntry=resolveImport("@earendil-works/pi-tui"),piAiCompatEntry=resolveImport("@earendil-works/pi-ai/compat"),piAiOauthEntry=resolveImport("@earendil-works/pi-ai/oauth"),piAiProvidersEntry=resolveImport("@earendil-works/pi-ai/providers/all");return _aliases={"@earendil-works/pi-coding-agent":piCodingAgentEntry,[DISTRIBUTION_PACKAGE_NAME]:piCodingAgentEntry,"@earendil-works/pi-agent-core":piAgentCoreEntry,"@earendil-works/pi-tui":piTuiEntry,"@earendil-works/pi-ai/providers/all":piAiProvidersEntry,"@earendil-works/pi-ai/compat":piAiCompatEntry,"@earendil-works/pi-ai/oauth":piAiOauthEntry,"@earendil-works/pi-ai":piAiCompatEntry,"@mariozechner/pi-coding-agent":piCodingAgentEntry,"@mariozechner/pi-agent-core":piAgentCoreEntry,"@mariozechner/pi-tui":piTuiEntry,"@mariozechner/pi-ai/providers/all":piAiProvidersEntry,"@mariozechner/pi-ai/compat":piAiCompatEntry,"@mariozechner/pi-ai/oauth":piAiOauthEntry,"@mariozechner/pi-ai":piAiCompatEntry,typebox:typeboxEntry,"typebox/compile":typeboxCompileEntry,"typebox/value":typeboxValueEntry,"@sinclair/typebox":typeboxEntry,"@sinclair/typebox/compile":typeboxCompileEntry,"@sinclair/typebox/value":typeboxValueEntry},_aliases}var extensionCacheCwd,extensionCacheGeneration=0,extensionCache=new Map;function clearExtensionCache(){extensionCache.clear(),extensionCacheCwd=void 0,extensionCacheGeneration++}function useExtensionCacheCwd(cwd){let resolvedCwd=resolvePath(cwd);return extensionCacheCwd!==void 0&&extensionCacheCwd!==resolvedCwd&&clearExtensionCache(),extensionCacheCwd=resolvedCwd,{cwd:resolvedCwd,generation:extensionCacheGeneration}}function createExtensionRuntime(){let notInitialized=()=>{throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.")},state2={},eventBusUnsubscribers=new Set,assertActive=()=>{if(state2.staleMessage)throw new Error(state2.staleMessage)},runtime={sendMessage:notInitialized,sendUserMessage:notInitialized,appendEntry:notInitialized,setSessionName:notInitialized,getSessionName:notInitialized,setLabel:notInitialized,getActiveTools:notInitialized,getAllTools:notInitialized,getSettings:notInitialized,setActiveTools:notInitialized,refreshTools:()=>{},getCommands:notInitialized,setModel:()=>Promise.reject(new Error("Extension runtime not initialized")),getThinkingLevel:notInitialized,setThinkingLevel:notInitialized,flagValues:new Map,pendingProviderRegistrations:[],pendingNativeProviderRegistrations:[],mcpServers:new McpServerRegistry,pendingVirtualModelRegistrations:[],createContext:notInitialized,assertActive,invalidate:message=>{if(!state2.staleMessage){state2.staleMessage=message??"This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().";for(let unsubscribe of eventBusUnsubscribers)unsubscribe();eventBusUnsubscribers.clear()}},trackEventBusSubscription:unsubscribe=>{let active=!0,trackedUnsubscribe=()=>{active&&(active=!1,eventBusUnsubscribers.delete(trackedUnsubscribe),unsubscribe())};return eventBusUnsubscribers.add(trackedUnsubscribe),trackedUnsubscribe},registerProvider:(name,config,extensionPath="<unknown>")=>{runtime.pendingProviderRegistrations.push({name,config,extensionPath})},registerNativeProvider:(provider,extensionPath="<unknown>")=>{runtime.pendingNativeProviderRegistrations.push({provider,extensionPath})},unregisterProvider:name=>{runtime.pendingProviderRegistrations=runtime.pendingProviderRegistrations.filter(r=>r.name!==name),runtime.pendingNativeProviderRegistrations=runtime.pendingNativeProviderRegistrations.filter(r=>r.provider.id!==name)},registerVirtualModel:(definition,extensionPath="<unknown>")=>{runtime.pendingVirtualModelRegistrations.push({definition,extensionPath})},unregisterVirtualModel:(provider,id)=>{runtime.pendingVirtualModelRegistrations=runtime.pendingVirtualModelRegistrations.filter(({definition})=>definition.provider!==provider||definition.id!==id)}};return runtime}function createExtensionAPI(extension,runtime,cwd,eventBus){let pendingFlagValues=new Map,pendingRuntimeChanges=[],loadingUnsubscribers=[],state2="loading",assertActive=()=>{if(state2==="failed")throw new Error(`Extension "${extension.path}" failed to load and its API is no longer active.`);runtime.assertActive()},applyRuntimeChange=change=>{state2==="loading"?pendingRuntimeChanges.push(change):change()},clearPending=()=>{pendingFlagValues.clear(),pendingRuntimeChanges.length=0,loadingUnsubscribers.length=0};return{api:{on(event,handler){assertActive();let registeredHandler=(...args)=>handler(...args),list2=extension.handlers.get(event)??[];return list2.push(registeredHandler),extension.handlers.set(event,list2),()=>{let handlers=extension.handlers.get(event);if(!handlers)return;let handlerIndex=handlers.indexOf(registeredHandler);handlerIndex!==-1&&(handlers.splice(handlerIndex,1),handlers.length===0&&extension.handlers.delete(event))}},registerTool(tool){if(assertActive(),typeof tool.parameters!="object"||tool.parameters===null||Array.isArray(tool.parameters))throw new Error(`Tool "${tool.name}" registered by extension "${extension.path}" must define an object parameter schema.`);extension.tools.set(tool.name,{definition:tool,sourceInfo:extension.sourceInfo}),runtime.refreshTools()},registerCommand(name,options){if(assertActive(),typeof name!="string"||name.length===0)throw new Error(`Command registered by extension "${extension.path}" must have a non-empty string name. Use pi.registerCommand("name", { description, handler }).`);if(typeof options?.handler!="function")throw new Error(`Command "/${name}" registered by extension "${extension.path}" must define handler().`);extension.commands.set(name,{name,sourceInfo:extension.sourceInfo,...options})},registerShortcut(shortcut,options){assertActive(),extension.shortcuts.set(shortcut,{shortcut,extensionPath:extension.path,...options})},registerFlag(name,options){if(assertActive(),options.default!==void 0&&typeof options.default!==options.type)throw new Error(`Invalid default for flag "${name}": expected ${options.type}, got ${typeof options.default}`);extension.flags.set(name,{name,extensionPath:extension.path,...options}),options.default!==void 0&&!runtime.flagValues.has(name)&&(state2==="loading"?pendingFlagValues.has(name)||pendingFlagValues.set(name,options.default):runtime.flagValues.set(name,options.default))},registerMessageRenderer(customType,renderer){assertActive(),extension.messageRenderers.set(customType,renderer)},registerMarkdownTransformer(transformer){assertActive(),extension.markdownTransformer=transformer},registerEntryRenderer(customType,renderer){assertActive(),extension.entryRenderers??=new Map,extension.entryRenderers.set(customType,renderer)},registerToolRenderer(resolver){assertActive(),extension.toolRenderers??=[],extension.toolRenderers.push(resolver)},getFlag(name){if(assertActive(),!!extension.flags.has(name))return runtime.flagValues.has(name)?runtime.flagValues.get(name):pendingFlagValues.get(name)},sendMessage(message,options){assertActive(),runtime.sendMessage(message,options)},sendUserMessage(content,options){assertActive(),runtime.sendUserMessage(content,options)},appendEntry(customType,data){assertActive(),runtime.appendEntry(customType,data)},setSessionName(name){assertActive(),runtime.setSessionName(name)},getSessionName(){return assertActive(),runtime.getSessionName()},setLabel(entryId,label){assertActive(),runtime.setLabel(entryId,label)},exec(command,args,options){return assertActive(),execCommand(command,args,options?.cwd??cwd,options)},getActiveTools(){return assertActive(),runtime.getActiveTools()},getAllTools(){return assertActive(),runtime.getAllTools()},getSettings(){return assertActive(),runtime.getSettings()},setActiveTools(toolNames){assertActive(),runtime.setActiveTools(toolNames)},getCommands(){return assertActive(),runtime.getCommands()},setModel(model){return assertActive(),runtime.setModel(model)},getThinkingLevel(){return assertActive(),runtime.getThinkingLevel()},setThinkingLevel(level){assertActive(),runtime.setThinkingLevel(level)},registerProvider(providerOrName,config){if(assertActive(),typeof providerOrName=="string"){if(!config)throw new Error("Provider config is required when registering by name");applyRuntimeChange(()=>runtime.registerProvider(providerOrName,config,extension.path));return}applyRuntimeChange(()=>runtime.registerNativeProvider(providerOrName,extension.path))},unregisterProvider(name){assertActive(),applyRuntimeChange(()=>runtime.unregisterProvider(name,extension.path))},registerMcpServer(name,config){assertActive();let validated=validateMcpServerConfig(name,config);if(typeof validated=="string")throw new Error(`Invalid MCP server registered by extension "${extension.path}": ${validated}`);let owner=runtime.mcpServers.get(name)?.extensionPath;if(owner!==void 0&&owner!==extension.path)throw new Error(`MCP server "${name}" is already registered by extension "${owner}"`);let clash=runtime.mcpServers.list().find(server2=>server2.name!==name&&mcpNamespace(server2.name)===mcpNamespace(name));if(clash)throw new Error(`MCP server "${name}" conflicts with registered server "${clash.name}"`);let server={name,config:structuredClone(validated),extensionPath:extension.path};applyRuntimeChange(()=>runtime.mcpServers.register(server))},unregisterMcpServer(name){assertActive(),applyRuntimeChange(()=>runtime.mcpServers.unregister(name,extension.path))},getMcpServers(){return assertActive(),runtime.mcpServers.list()},registerVirtualModel(model){assertActive();let definition={...model,route:request=>model.route(request,runtime.createContext())};applyRuntimeChange(()=>runtime.registerVirtualModel(definition,extension.path))},unregisterVirtualModel(provider,id){assertActive(),applyRuntimeChange(()=>runtime.unregisterVirtualModel(provider,id))},events:{emit(channel,data){assertActive(),eventBus.emit(channel,data)},on(channel,handler){assertActive();let unsubscribe=runtime.trackEventBusSubscription(eventBus.on(channel,handler));return state2==="loading"&&loadingUnsubscribers.push(unsubscribe),unsubscribe}}},commit:()=>{if(state2==="loading"){runtime.assertActive();for(let[name,value]of pendingFlagValues)runtime.flagValues.has(name)||runtime.flagValues.set(name,value);for(let apply of pendingRuntimeChanges)apply();state2="active",clearPending()}},discard:()=>{if(state2==="loading"){state2="failed";for(let unsubscribe of loadingUnsubscribers)unsubscribe();clearPending()}}}}function isCurrentCacheToken(cacheToken){return cacheToken!==void 0&&extensionCacheCwd===cacheToken.cwd&&extensionCacheGeneration===cacheToken.generation}async function loadExtensionModule(extensionPath,cacheToken){if(isCurrentCacheToken(cacheToken)){let cachedFactory=extensionCache.get(extensionPath);if(cachedFactory)return cachedFactory}let createJitiImpl=await getCreateJiti(),resolutionOptions=usesEmbeddedModules?{virtualModules:await getVirtualModules(),tryNative:!1}:isTypeScriptSourceRuntime?{virtualModules:await getVirtualModules(),tsconfigPaths:!0}:{alias:getAliases()},factory=await createJitiImpl(import.meta.url,{moduleCache:!1,...resolutionOptions}).import(extensionPath,{default:!0});if(typeof factory=="function")return isCurrentCacheToken(cacheToken)&&extensionCache.set(extensionPath,factory),factory}function createExtension(extensionPath,resolvedPath){let source=getSyntheticPathSource(extensionPath)??"local",baseDir=isSyntheticPath(extensionPath)?void 0:path7.dirname(resolvedPath);return{path:extensionPath,resolvedPath,sourceInfo:createSyntheticSourceInfo(extensionPath,{source,baseDir}),handlers:new Map,tools:new Map,messageRenderers:new Map,entryRenderers:new Map,commands:new Map,flags:new Map,shortcuts:new Map}}async function initializeExtension(factory,extensionPath,resolvedPath,cwd,eventBus,runtime){let extension=createExtension(extensionPath,resolvedPath),load=createExtensionAPI(extension,runtime,cwd,eventBus);try{await factory(load.api),load.commit()}catch(error){throw load.discard(),error}return time(`${extensionPath} factory`,"extensions"),extension}async function loadExtension(extensionPath,cwd,eventBus,runtime,cacheToken){let resolvedPath=resolvePath(extensionPath,cwd,{normalizeUnicodeSpaces:!0});try{let factory=await loadExtensionModule(resolvedPath,cacheToken);return time(`${extensionPath} module import`,"extensions"),factory?{extension:await initializeExtension(factory,extensionPath,resolvedPath,cwd,eventBus,runtime),error:null}:{extension:null,error:`Extension does not export a valid factory function: ${extensionPath}`}}catch(err){return{extension:null,error:`Failed to load extension: ${err instanceof Error?err.message:String(err)}`}}}async function loadExtensionFromFactory(factory,cwd,eventBus,runtime,extensionPath="<inline>"){let resolvedCwd=resolvePath(cwd);return initializeExtension(factory,extensionPath,extensionPath,resolvedCwd,eventBus,runtime)}async function loadExtensionsInternal(paths,cwd,eventBus,runtime,useCache=!1){let extensions=[],errors=[],warnings=[],cacheToken=useCache?useExtensionCacheCwd(cwd):void 0,resolvedCwd=cacheToken?.cwd??resolvePath(cwd),resolvedEventBus=eventBus??createEventBus(),resolvedRuntime=runtime??createExtensionRuntime();for(let extPath of paths){let{extension,error}=await loadExtension(extPath,resolvedCwd,resolvedEventBus,resolvedRuntime,cacheToken);if(error){errors.push({path:extPath,error});continue}extension&&extensions.push(extension)}return{extensions,errors,warnings,runtime:resolvedRuntime}}async function loadExtensions(paths,cwd,eventBus,runtime){return loadExtensionsInternal(paths,cwd,eventBus,runtime)}async function loadExtensionsCached(paths,cwd,eventBus,runtime){return loadExtensionsInternal(paths,cwd,eventBus,runtime,!0)}function isExtensionFile(name){return name.endsWith(".ts")||name.endsWith(".js")}function resolveExtensionEntries2(dir){let packageJsonPath=path7.join(dir,"package.json");if(fs5.existsSync(packageJsonPath)){let manifest=readPiManifest(packageJsonPath);if(manifest?.extensions?.length){let entries=[];for(let extPath of manifest.extensions){let resolvedExtPath=path7.resolve(dir,extPath);fs5.existsSync(resolvedExtPath)&&entries.push(resolvedExtPath)}if(entries.length>0)return entries}}let indexTs=path7.join(dir,"index.ts"),indexJs=path7.join(dir,"index.js");return fs5.existsSync(indexTs)?[indexTs]:fs5.existsSync(indexJs)?[indexJs]:null}function discoverExtensionsInDir(dir){if(!fs5.existsSync(dir))return[];let discovered=[];try{let entries=fs5.readdirSync(dir,{withFileTypes:!0});for(let entry of entries){let entryPath=path7.join(dir,entry.name);if((entry.isFile()||entry.isSymbolicLink())&&isExtensionFile(entry.name)){discovered.push(entryPath);continue}if(entry.isDirectory()||entry.isSymbolicLink()){let entries2=resolveExtensionEntries2(entryPath);entries2&&discovered.push(...entries2)}}}catch{return[]}return discovered}async function discoverAndLoadExtensions(configuredPaths,cwd,agentDir=getAgentDir(),eventBus){let resolvedCwd=resolvePath(cwd),resolvedAgentDir=resolvePath(agentDir),allPaths=[],seen=new Set,addPaths=paths=>{for(let p of paths){let resolved=path7.resolve(p);seen.has(resolved)||(seen.add(resolved),allPaths.push(p))}},localExtDir=path7.join(resolvedCwd,CONFIG_DIR_NAME,"extensions");addPaths(discoverExtensionsInDir(localExtDir));let globalExtDir=path7.join(resolvedAgentDir,"extensions");addPaths(discoverExtensionsInDir(globalExtDir));for(let p of configuredPaths){let resolved=resolvePath(p,resolvedCwd,{normalizeUnicodeSpaces:!0});if(fs5.existsSync(resolved)&&fs5.statSync(resolved).isDirectory()){let entries=resolveExtensionEntries2(resolved);if(entries){addPaths(entries);continue}addPaths(discoverExtensionsInDir(resolved));continue}addPaths([resolved])}return loadExtensions(allPaths,resolvedCwd,eventBus)}var ModelRegistry=class{constructor(runtime){this.runtime=runtime}getRuntime(){return this.runtime}refresh(options){return this.runtime.refresh(options)}getError(){return this.runtime.getError()}getAll(){return[...this.runtime.getModels()]}getAvailable(){return[...this.runtime.getAvailableSnapshot()]}find(provider,modelId){return this.runtime.getModel(provider,modelId)}findOfType(type,provider,modelId){return this.runtime.getModelOfType(type,provider,modelId)}hasConfiguredAuth(model){return this.runtime.hasConfiguredAuth(model.provider)}async getApiKeyAndHeaders(model){try{let resolution=await this.runtime.getAuth(model);if(!resolution){let compatibility=this.runtime.getCompatibilityRequestConfig(model);return compatibility.authHeader?{ok:!1,error:`No API key found for "${model.provider}"`}:{ok:!0,headers:compatibility.headers}}return{ok:!0,apiKey:resolution.auth.apiKey,headers:resolution.auth.headers,...resolution.auth.baseUrl?{baseUrl:resolution.auth.baseUrl}:{},env:resolution.env}}catch(error){let cause=error instanceof Error?error.cause:void 0,message=cause instanceof Error?cause.message:error instanceof Error?error.message:String(error);return{ok:!1,error:message==="authHeader requires a resolved API key"?`No API key found for "${model.provider}"`:message}}}getProviderAuthStatus(provider){return this.runtime.getProviderAuthStatus(provider)}getProvider(provider){return this.runtime.getProvider(provider)}stream(model,context,options){return this.runtime.stream(model,context,options)}streamSimple(model,context,options){return this.runtime.streamSimple(model,context,options)}complete(model,context,options){return this.runtime.complete(model,context,options)}getModelsOfType(type,provider){return this.runtime.getModelsOfType(type,provider)}getAvailableOfType(type,provider,options){return this.runtime.getAvailableOfType(type,provider,options)}getModelOfType(type,provider,modelId){return this.runtime.getModelOfType(type,provider,modelId)}classify(model,context,options){return this.runtime.classify(model,context,options)}generateImages(model,context,options){return this.runtime.generateImages(model,context,options)}getProviderDisplayName(provider){return this.runtime.getProvider(provider)?.name??provider}getProviderAuth(provider){return this.runtime.getAuth(provider)}async getApiKeyForProvider(provider){try{return(await this.runtime.getAuth(provider))?.auth.apiKey}catch{return}}isUsingOAuth(model){return this.runtime.isUsingOAuth(model.provider)}registerProvider(providerOrName,config){if(typeof providerOrName=="string"){if(!config)throw new Error("Provider config is required when registering by name");this.runtime.registerProvider(providerOrName,config);return}this.runtime.registerNativeProvider(providerOrName)}unregisterProvider(providerName){this.runtime.unregisterProvider(providerName)}registerVirtualModel(definition){this.runtime.registerVirtualModel(definition)}unregisterVirtualModel(providerName,id){this.runtime.unregisterVirtualModel(providerName,id)}getRegisteredProviderConfig(providerName){return this.runtime.getRegisteredProviderConfig(providerName)}getRegisteredNativeProvider(providerName){return this.runtime.getRegisteredNativeProvider(providerName)}getRegisteredProviderIds(){return this.runtime.getRegisteredProviderIds()}};function truncateToVisualLines(text2,maxVisualLines,width,paddingX=0,keep="end"){if(!text2)return{visualLines:[],skippedCount:0};let allVisualLines=new Text(text2,paddingX,0).render(width);if(allVisualLines.length<=maxVisualLines)return{visualLines:allVisualLines,skippedCount:0};let truncatedLines=keep==="start"?allVisualLines.slice(0,maxVisualLines):allVisualLines.slice(-maxVisualLines),skippedCount=allVisualLines.length-maxVisualLines;return{visualLines:truncatedLines,skippedCount}}var VisualLinePreview=class{constructor(options){this.options=options}render(width){if(this.cachedLines===void 0||this.cachedWidth!==width){let{text:text2,maxVisualLines,keep,formatHint}=this.options,preview=truncateToVisualLines(text2,maxVisualLines,width,0,keep),lines=preview.visualLines;if(preview.skippedCount>0){let hint=truncateToWidth(formatHint(preview.skippedCount),width,"...");this.cachedLines=keep==="start"?[...lines,hint]:[hint,...lines]}else this.cachedLines=lines;this.cachedWidth=width}return this.cachedLines}invalidate(){this.cachedWidth=void 0,this.cachedLines=void 0}};import{unlink as unlink2}from"node:fs/promises";import{randomBytes}from"node:crypto";import{closeSync as closeSync2,createWriteStream,openSync as openSync2,writeSync}from"node:fs";import{open as open3}from"node:fs/promises";import{tmpdir as tmpdir2}from"node:os";import{join as join20}from"node:path";function defaultTempFilePath(prefix){let id=randomBytes(8).toString("hex");return join20(tmpdir2(),`${prefix}-${id}.log`)}function byteLength(text2){return Buffer.byteLength(text2,"utf-8")}var OutputAccumulator=class{constructor(options={}){if(this.decoder=new TextDecoder,this.rawChunks=[],this.tailText="",this.tailBytes=0,this.tailStartsAtLineBoundary=!0,this.totalRawBytes=0,this.totalDecodedBytes=0,this.completedLines=0,this.totalLines=0,this.currentLineBytes=0,this.hasOpenLine=!1,this.finished=!1,this.maxLines=options.maxLines??2e3,this.maxBytes=options.maxBytes??51200,this.maxRollingBytes=Math.max(this.maxBytes*2,1),this.tempFilePrefix=options.tempFilePrefix??"pi-output",options.persistFromStart){let path14=defaultTempFilePath(this.tempFilePrefix);this.tempFileFd=openSync2(path14,"wx",384),this.tempFilePath=path14}}append(data){if(this.finished)throw new Error("Cannot append to a finished output accumulator");if(this.totalRawBytes+=data.length,this.appendDecodedText(this.decoder.decode(data,{stream:!0})),this.tempFileFd!==void 0){let offset=0;for(;offset<data.length;){let written=writeSync(this.tempFileFd,data,offset,data.length-offset);if(written===0)throw new Error("Output file write made no progress");offset+=written}}else this.tempFileStream||this.shouldUseTempFile()?(this.ensureTempFile(),this.tempFileStream?.write(data)):data.length>0&&this.rawChunks.push(data)}finish(){this.finished||(this.finished=!0,this.appendDecodedText(this.decoder.decode()),this.shouldUseTempFile()&&this.ensureTempFile())}snapshot(options={}){let maxBytes=Math.min(this.maxBytes,options.maxBytes??this.maxBytes),tailTruncation=truncateTail(this.getSnapshotText(),{maxLines:this.maxLines,maxBytes}),truncated=this.totalLines>this.maxLines||this.totalDecodedBytes>maxBytes,truncatedBy=truncated?tailTruncation.truncatedBy??(this.totalDecodedBytes>maxBytes?"bytes":"lines"):null,truncation={...tailTruncation,truncated,truncatedBy,totalLines:this.totalLines,totalBytes:this.totalDecodedBytes,maxLines:this.maxLines,maxBytes};return options.persistIfTruncated&&truncation.truncated&&this.ensureTempFile(),{content:truncation.content,truncation,fullOutputPath:this.tempFilePath}}getTotalBytes(){return this.totalRawBytes}async closeTempFile(){if(this.tempFileFd!==void 0){let fd=this.tempFileFd;this.tempFileFd=void 0,closeSync2(fd)}if(!this.tempFileStream)return;let stream2=this.tempFileStream;this.tempFileStream=void 0,await new Promise((resolve18,reject)=>{let onError=error=>{stream2.off("finish",onFinish),reject(error)},onFinish=()=>{stream2.off("error",onError),resolve18()};stream2.once("error",onError),stream2.once("finish",onFinish),stream2.end()})}async readFullOutput(maxBytes){if(!this.tempFilePath)return{content:new TextDecoder().decode(Buffer.concat(this.rawChunks)),truncated:!1};let file=await open3(this.tempFilePath,"r");try{let size=(await file.stat()).size;if(size<=maxBytes)return{content:new TextDecoder().decode(await file.readFile()),truncated:!1};let headBytes=Math.floor(maxBytes/2),tailBytes=maxBytes-headBytes,head=Buffer.alloc(headBytes),tail2=Buffer.alloc(tailBytes);await file.read(head,0,headBytes,0),await file.read(tail2,0,tailBytes,size-tailBytes);let headText=new TextDecoder().decode(head,{stream:!0}),tailStart=0;for(;tailStart<tail2.length&&(tail2[tailStart]&192)===128;)tailStart++;let tailText=new TextDecoder().decode(tail2.subarray(tailStart)),omitted=size-headBytes-tailBytes;return{content:`${headText}
|
|
868
868
|
|
|
869
869
|
[... ${omitted} bytes omitted ...]
|
|
870
870
|
|
|
@@ -879,14 +879,14 @@ ${imageIndicators}`:imageIndicators}return output}var COLLAPSED_ARGS_CHARS=100;f
|
|
|
879
879
|
`)}`});return`${header}
|
|
880
880
|
${theme2.fg("muted",lines.join(`
|
|
881
881
|
`))}`}let pairs=entries.map(([key,value])=>`${key}=${JSON.stringify(value)??String(value)}`).join(" "),preview=pairs.length>COLLAPSED_ARGS_CHARS?`${pairs.slice(0,COLLAPSED_ARGS_CHARS-3)}...`:pairs;return`${header} ${theme2.fg("muted",preview)}`}function invalidArgText(theme2){return theme2.fg("error","[invalid arg]")}function renderToolPath(rawPath,theme2,cwd,options){if(rawPath===null)return invalidArgText(theme2);let value=rawPath||options?.emptyFallback;return value?linkPath(theme2.fg("accent",shortenPath2(value)),value,cwd):theme2.fg("toolOutput","...")}var BASH_PREVIEW_LINES=5,BASH_UPDATE_THROTTLE_MS=100,BashCallRenderComponent=class{constructor(config){this.command="",this.expanded=!1,this.config=config}update(args,expanded){let command=str(args?.command),timeout=args?.timeout;this.command===command&&this.timeout===timeout&&this.expanded===expanded||(this.command=command,this.timeout=timeout,this.expanded=expanded,this.invalidate())}render(width){return(this.cachedLines===void 0||this.cachedWidth!==width)&&(this.cachedLines=this.renderLines(Math.max(1,width)),this.cachedWidth=width),this.cachedLines}invalidate(){this.cachedWidth=void 0,this.cachedLines=void 0}renderLines(width){let fullCall=formatFullShellCall(this.command,this.timeout,this.config),fullLines=new Text(fullCall,0,0).render(width);return this.expanded||fullLines.length<=1?fullLines:[formatTruncatedShellCall(this.command,this.timeout,width,this.config)]}},shellTiming=Symbol("shellTiming");function getShellTiming(context){if(!context.executionStarted)return;let state2=context.state;if(state2[shellTiming])return state2[shellTiming];let timing={startedAt:Date.now(),disposed:!1};state2[shellTiming]=timing;let previousDispose=state2.dispose;return state2.dispose=()=>{try{previousDispose?.call(state2)}finally{clearInterval(timing.interval),timing.interval=void 0,timing.disposed=!0}},timing}function formatDuration(ms){let seconds=ms/1e3;if(seconds<60)return`${seconds.toFixed(1)}s`;let totalSeconds=Math.floor(seconds),minutes=Math.floor(totalSeconds/60),remainder=totalSeconds%60;return minutes<60?`${minutes}m ${remainder}s`:`${Math.floor(minutes/60)}h ${minutes%60}m ${remainder}s`}function formatShellPrompt(prompt){return theme.fg("toolTitle",theme.bold(`${prompt} `))}function formatShellTimeout(timeout){return timeout?theme.fg("muted",` (timeout ${timeout}s)`):""}function styleShellCommand(command,config){let language=config.name==="powershell"?"powershell":"bash";return highlightCode(command,language).join(`
|
|
882
|
-
`)}function formatFullShellCall(command,timeout,config){let commandDisplay=command===null?invalidArgText(theme):command?styleShellCommand(command,config):theme.fg("toolOutput","...");return formatShellPrompt(config.prompt)+commandDisplay+formatShellTimeout(timeout)}function fitCollapsedShellCall(body,timeout,width,suffix,config){let prompt=formatShellPrompt(config.prompt),timeoutSuffix=formatShellTimeout(timeout),bodyWidth=Math.max(0,width-visibleWidth(prompt)-visibleWidth(suffix)-visibleWidth(timeoutSuffix)),fittedBody=truncateToWidth(body,bodyWidth,"");return truncateToWidth(prompt+fittedBody+suffix+timeoutSuffix,width,"\u2026")}function formatTruncatedShellCall(command,timeout,width,config){if(command===null)return truncateToWidth(formatFullShellCall(command,timeout,config),width,"\u2026");if(!command)return formatFullShellCall(command,timeout,config);let physicalLines=command.split(/\r?\n/).filter(line=>line.trim()),firstNonEmptyLine=physicalLines[0]?.trim()??command.trim(),hiddenLines=Math.max(0,physicalLines.length-1),suffix=hiddenLines>0?theme.fg("muted",` (+${hiddenLines} line${hiddenLines===1?"":"s"})`):theme.fg("muted"," \u2026");return fitCollapsedShellCall(styleShellCommand(firstNonEmptyLine,config),timeout,width,suffix,config)}function rebuildBashResultRenderComponent(component,result2,options,showImages,startedAt,endedAt){component.clear();let background=result2.details?.background,output=background?.kind==="background"
|
|
882
|
+
`)}function formatFullShellCall(command,timeout,config){let commandDisplay=command===null?invalidArgText(theme):command?styleShellCommand(command,config):theme.fg("toolOutput","...");return formatShellPrompt(config.prompt)+commandDisplay+formatShellTimeout(timeout)}function fitCollapsedShellCall(body,timeout,width,suffix,config){let prompt=formatShellPrompt(config.prompt),timeoutSuffix=formatShellTimeout(timeout),bodyWidth=Math.max(0,width-visibleWidth(prompt)-visibleWidth(suffix)-visibleWidth(timeoutSuffix)),fittedBody=truncateToWidth(body,bodyWidth,"");return truncateToWidth(prompt+fittedBody+suffix+timeoutSuffix,width,"\u2026")}function formatTruncatedShellCall(command,timeout,width,config){if(command===null)return truncateToWidth(formatFullShellCall(command,timeout,config),width,"\u2026");if(!command)return formatFullShellCall(command,timeout,config);let physicalLines=command.split(/\r?\n/).filter(line=>line.trim()),firstNonEmptyLine=physicalLines[0]?.trim()??command.trim(),hiddenLines=Math.max(0,physicalLines.length-1),suffix=hiddenLines>0?theme.fg("muted",` (+${hiddenLines} line${hiddenLines===1?"":"s"})`):theme.fg("muted"," \u2026");return fitCollapsedShellCall(styleShellCommand(firstNonEmptyLine,config),timeout,width,suffix,config)}function rebuildBashResultRenderComponent(component,result2,options,showImages,startedAt,endedAt,submittedAsBackground){component.clear();let background=result2.details?.background,output=background?.kind==="background"?`${submittedAsBackground?"Running in the background":"Moved to background"} \xB7 ${background.taskId}`:getTextOutput(result2,showImages).trim(),truncation=result2.details?.truncation,fullOutputPath=result2.details?.fullOutputPath;if(!options.isPartial&&truncation?.truncated&&fullOutputPath&&output.endsWith("]")){let footerStart=output.lastIndexOf(`
|
|
883
883
|
|
|
884
884
|
[`);footerStart!==-1&&output.slice(footerStart).includes(fullOutputPath)&&(output=output.slice(0,footerStart).trimEnd())}if(output){let styledOutput=output.split(`
|
|
885
885
|
`).map(line=>theme.fg("toolOutput",line)).join(`
|
|
886
886
|
`);options.expanded?component.addChild(new Text(`
|
|
887
887
|
${styledOutput}`,0,0)):(component.addChild(new Spacer(1)),component.addChild(new VisualLinePreview({text:styledOutput,maxVisualLines:BASH_PREVIEW_LINES,keep:"end",formatHint:hidden=>theme.fg("muted",`... (${hidden} earlier lines,`)+` ${keyHint("app.tools.expand","to expand")}${theme.fg("muted",")")}`})))}if(truncation?.truncated||fullOutputPath){let warnings=[];fullOutputPath&&warnings.push(`Full output: ${fullOutputPath}`),truncation?.truncated&&(truncation.truncatedBy==="lines"?warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`):warnings.push(`Truncated: ${truncation.outputLines} lines shown (${formatSize(truncation.maxBytes??51200)} limit)`)),component.addChild(new Text(`
|
|
888
888
|
${theme.fg("warning",`[${warnings.join(". ")}]`)}`,0,0))}if(startedAt!==void 0){let label=options.isPartial?"Elapsed":"Took",endTime=endedAt??Date.now();component.addChild(new Text(`
|
|
889
|
-
${theme.fg("muted",`${label} ${formatDuration(endTime-startedAt)}`)}`,0,0))}}function createShellRenderers(config){return{renderCall(args,_theme,context){getShellTiming(context);let component=context.lastComponent??new BashCallRenderComponent(config);return component.update(args,context.expanded),component},renderResult(result2,options,_theme,context){let timing=getShellTiming(context);timing&&(!options.isPartial||context.isError?(timing.endedAt??=Date.now(),clearInterval(timing.interval),timing.interval=void 0):!timing.disposed&&timing.interval===void 0&&(timing.interval=setInterval(()=>context.invalidate(),1e3),timing.interval.unref?.()));let component=context.lastComponent??new Container;return rebuildBashResultRenderComponent(component,result2,options,context.showImages,timing?.startedAt,timing?.endedAt),component.invalidate(),component}}}var CMD_NUL_REDIRECT_REGEX=/(\d?&?>+\s*)[Nn][Uu][Ll](?=\s|$|[|&;)\n])/g;function rewriteCmdNulRedirects(command){return command.replace(CMD_NUL_REDIRECT_REGEX,"$1/dev/null")}var MAX_BACKGROUND_OUTPUT_BYTES=20*1024*1024;function shellFailure(error){return error instanceof Error&&error.message==="aborted"?{status:"cancelled",error:"Command aborted"}:error instanceof Error&&error.message.startsWith("timeout:")?{status:"timeout",error:`Command timed out after ${error.message.split(":")[1]} seconds`}:{status:"failed",error:boundText(error instanceof Error?error.message:String(error),4096)}}function formatOutput(output,snapshot,managed,emptyText){let truncation=snapshot.truncation,text2=snapshot.content||emptyText,details=managed?{fullOutputPath:snapshot.fullOutputPath}:void 0;if(truncation.truncated){details={truncation,fullOutputPath:snapshot.fullOutputPath};let startLine=truncation.totalLines-truncation.outputLines+1,endLine=truncation.totalLines;if(truncation.lastLinePartial){let lastLineSize=formatSize(output.getLastLineBytes());text2+=`
|
|
889
|
+
${theme.fg("muted",`${label} ${formatDuration(endTime-startedAt)}`)}`,0,0))}}function createShellRenderers(config){return{renderCall(args,_theme,context){getShellTiming(context);let component=context.lastComponent??new BashCallRenderComponent(config);return component.update(args,context.expanded),component},renderResult(result2,options,_theme,context){let timing=getShellTiming(context);timing&&(!options.isPartial||context.isError?(timing.endedAt??=Date.now(),clearInterval(timing.interval),timing.interval=void 0):!timing.disposed&&timing.interval===void 0&&(timing.interval=setInterval(()=>context.invalidate(),1e3),timing.interval.unref?.()));let component=context.lastComponent??new Container,submitted=context.args?.background===!0;return rebuildBashResultRenderComponent(component,result2,options,context.showImages,timing?.startedAt,timing?.endedAt,submitted),component.invalidate(),component}}}var CMD_NUL_REDIRECT_REGEX=/(\d?&?>+\s*)[Nn][Uu][Ll](?=\s|$|[|&;)\n])/g;function rewriteCmdNulRedirects(command){return command.replace(CMD_NUL_REDIRECT_REGEX,"$1/dev/null")}var MAX_BACKGROUND_OUTPUT_BYTES=20*1024*1024;function shellFailure(error){return error instanceof Error&&error.message==="aborted"?{status:"cancelled",error:"Command aborted"}:error instanceof Error&&error.message.startsWith("timeout:")?{status:"timeout",error:`Command timed out after ${error.message.split(":")[1]} seconds`}:{status:"failed",error:boundText(error instanceof Error?error.message:String(error),4096)}}function formatOutput(output,snapshot,managed,emptyText){let truncation=snapshot.truncation,text2=snapshot.content||emptyText,details=managed?{fullOutputPath:snapshot.fullOutputPath}:void 0;if(truncation.truncated){details={truncation,fullOutputPath:snapshot.fullOutputPath};let startLine=truncation.totalLines-truncation.outputLines+1,endLine=truncation.totalLines;if(truncation.lastLinePartial){let lastLineSize=formatSize(output.getLastLineBytes());text2+=`
|
|
890
890
|
|
|
891
891
|
[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine} (line is ${lastLineSize}). Full output: ${snapshot.fullOutputPath}]`}else truncation.truncatedBy==="lines"?text2+=`
|
|
892
892
|
|
|
@@ -894,12 +894,12 @@ ${theme.fg("muted",`${label} ${formatDuration(endTime-startedAt)}`)}`,0,0))}}fun
|
|
|
894
894
|
|
|
895
895
|
[Showing lines ${startLine}-${endLine} of ${truncation.totalLines} (${formatSize(truncation.maxBytes)} limit). Full output: ${snapshot.fullOutputPath}]`}return{text:text2,details}}async function runShellCommand(options){let{operations,context,managed,signal,timeout}=options,output=new OutputAccumulator({tempFilePrefix:options.tempFilePrefix,persistFromStart:!!managed}),startedAt=performance.now(),outputError,acceptingOutput=!0,unsubscribe,updateTimer,updateDirty=!1,lastUpdateAt=0,failOutput=error=>{if(!outputError){outputError=error instanceof Error?error:new Error(String(error));try{managed&&managed.control.requestCancel()}catch{}}},checkOutputLimit=()=>{managed?.control.mode==="background"&&output.getTotalBytes()>MAX_BACKGROUND_OUTPUT_BYTES&&failOutput(new Error("Background command exceeded the 20 MiB output limit"))},snapshot=()=>output.snapshot({persistIfTruncated:!0,maxBytes:managed?.control.mode==="background"?40*1024:void 0}),publish=snapshot2=>{let result2={content:snapshot2?[{type:"text",text:snapshot2.content}]:[],details:snapshot2?{truncation:snapshot2.truncation.truncated?snapshot2.truncation:void 0,fullOutputPath:snapshot2.fullOutputPath}:void 0};managed?managed.control.publish(result2):options.onUpdate?.(result2)},emitOutputUpdate=()=>{!managed&&!options.onUpdate||!updateDirty||(updateDirty=!1,lastUpdateAt=Date.now(),publish(snapshot()))},clearUpdateTimer=()=>{updateTimer&&clearTimeout(updateTimer),updateTimer=void 0},scheduleOutputUpdate=()=>{if(!managed&&!options.onUpdate)return;updateDirty=!0;let delay2=BASH_UPDATE_THROTTLE_MS-(Date.now()-lastUpdateAt);delay2<=0?(clearUpdateTimer(),emitOutputUpdate()):updateTimer??=setTimeout(()=>{updateTimer=void 0,emitOutputUpdate()},delay2)},handleData=data=>{if(!(!acceptingOutput||outputError))try{if(managed?.control.mode==="background"&&output.getTotalBytes()+data.length>MAX_BACKGROUND_OUTPUT_BYTES){let remaining=Math.max(0,MAX_BACKGROUND_OUTPUT_BYTES-output.getTotalBytes());output.append(data.subarray(0,remaining)),failOutput(new Error("Background command exceeded the 20 MiB output limit"))}else output.append(data);scheduleOutputUpdate()}catch(error){if(!managed)throw error;failOutput(error)}};try{if(managed){let path14=output.snapshot().fullOutputPath,cleanup=async()=>{await output.closeTempFile(),await unlink2(path14).catch(error=>{if(error.code!=="ENOENT")throw error})};try{managed.control.setOutputPath(path14,cleanup)}catch(error){throw await cleanup(),error}unsubscribe=managed.control.onModeChange(checkOutputLimit)}publish();let failure,exitCode;try{if(signal?.aborted)throw new Error("aborted");let execution=operations.exec(context.command,context.cwd,{onData:handleData,signal,timeout,env:context.env});managed?.control.accept(),{exitCode}=await execution,exitCode===null?failure={status:"failed",error:"Command terminated without an exit code"}:exitCode!==0&&(failure={status:"failed",error:`Command exited with code ${exitCode}`})}catch(error){failure=shellFailure(error)}acceptingOutput=!1,output.finish(),clearUpdateTimer(),managed?publish(snapshot()):emitOutputUpdate();let final=snapshot();await output.closeTempFile(),outputError&&(failure={status:"failed",error:boundText(outputError.message,4096)});let{text:text2,details}=formatOutput(output,final,!!managed,failure?"":"(no output)"),fullOutput=typeof exitCode=="number"&&!outputError?await output.readFullOutput(1024*1024):void 0;return{status:failure?.status,error:failure?.error,...exitCode!==void 0?{exitCode}:{},result:{...fullOutput&&typeof exitCode=="number"?{structuredContent:{output:fullOutput.content,truncated:fullOutput.truncated,...fullOutput.truncated&&final.fullOutputPath?{full_output_path:final.fullOutputPath}:{},exit_code:exitCode,wall_time_seconds:Math.round((performance.now()-startedAt)/100)/10},...failure?{isError:!0}:{}}:{},content:[{type:"text",text:failure?`${text2?`${text2}
|
|
896
896
|
|
|
897
|
-
`:""}${failure.error}`:text2}],details}}}finally{acceptingOutput=!1,unsubscribe?.(),clearUpdateTimer(),await output.closeTempFile()}}import{constants as constants2}from"node:fs";import{access as fsAccess}from"node:fs/promises";import{constants as osConstants}from"node:os";import{spawn as spawn4}from"child_process";var MAX_TIMEOUT_MS=2147483647,MAX_TIMEOUT_SECONDS=MAX_TIMEOUT_MS/1e3;function resolveTimeoutMs(timeout){if(timeout===void 0)return;if(!Number.isFinite(timeout)||timeout<=0)throw new Error("Invalid timeout: must be a finite number of seconds");let timeoutMs=timeout*1e3;if(timeoutMs>MAX_TIMEOUT_MS)throw new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);return timeoutMs}var bashSchema=typebox_exports.Object({command:typebox_exports.String({description:"Shell command to execute"}),timeout:typebox_exports.Optional(typebox_exports.Number({description:"Timeout in seconds (optional, no default timeout)"})),background:typebox_exports.Optional(typebox_exports.Boolean({description:"true returns a managed task ID immediately and runs the command in the background; omit or false to block until exit"}))}),bashToolSystemPromptContribution={snippet:"Execute bash commands, foreground or background",guidelines:["You can inspect PI_* environment variables for current model and session details."]},bashOutputSchema=typebox_exports.Union([typebox_exports.Object({output:typebox_exports.String({description:"Combined stdout and stderr, up to 1 MiB, keeping head and tail when truncated."}),truncated:typebox_exports.Boolean(),full_output_path:typebox_exports.Optional(typebox_exports.String()),exit_code:typebox_exports.Number(),wall_time_seconds:typebox_exports.Number()}),typebox_exports.Object({task_id:typebox_exports.String(),status:typebox_exports.String()})]);function createLocalShellOperations(shellName,resolveShellConfig,normalizeCommand=command=>command){return{exec:async(command,cwd,{onData,signal,timeout,env:env2})=>{let timeoutMs=resolveTimeoutMs(timeout);if(signal?.aborted)throw new Error("aborted");let shellConfig=resolveShellConfig();try{await fsAccess(cwd,constants2.F_OK)}catch{throw new Error(`Working directory does not exist: ${cwd}
|
|
897
|
+
`:""}${failure.error}`:text2}],details}}}finally{acceptingOutput=!1,unsubscribe?.(),clearUpdateTimer(),await output.closeTempFile()}}import{constants as constants2}from"node:fs";import{access as fsAccess}from"node:fs/promises";import{constants as osConstants}from"node:os";import{spawn as spawn4}from"child_process";var MAX_TIMEOUT_MS=2147483647,MAX_TIMEOUT_SECONDS=MAX_TIMEOUT_MS/1e3;function resolveTimeoutMs(timeout){if(timeout===void 0)return;if(!Number.isFinite(timeout)||timeout<=0)throw new Error("Invalid timeout: must be a finite number of seconds");let timeoutMs=timeout*1e3;if(timeoutMs>MAX_TIMEOUT_MS)throw new Error(`Invalid timeout: maximum is ${MAX_TIMEOUT_SECONDS} seconds`);return timeoutMs}var bashSchema=typebox_exports.Object({command:typebox_exports.String({description:"Shell command to execute"}),timeout:typebox_exports.Optional(typebox_exports.Number({description:"Timeout in seconds (optional, no default timeout)"})),background:typebox_exports.Optional(typebox_exports.Boolean({description:"true returns a managed task ID immediately and runs the command in the background, and you are notified when it completes \u2014 do not poll for its result; omit or false to block until exit"}))}),bashToolSystemPromptContribution={snippet:"Execute bash commands, foreground or background",guidelines:["You can inspect PI_* environment variables for current model and session details."]},bashOutputSchema=typebox_exports.Union([typebox_exports.Object({output:typebox_exports.String({description:"Combined stdout and stderr, up to 1 MiB, keeping head and tail when truncated."}),truncated:typebox_exports.Boolean(),full_output_path:typebox_exports.Optional(typebox_exports.String()),exit_code:typebox_exports.Number(),wall_time_seconds:typebox_exports.Number()}),typebox_exports.Object({task_id:typebox_exports.String(),status:typebox_exports.String()})]);function createLocalShellOperations(shellName,resolveShellConfig,normalizeCommand=command=>command){return{exec:async(command,cwd,{onData,signal,timeout,env:env2})=>{let timeoutMs=resolveTimeoutMs(timeout);if(signal?.aborted)throw new Error("aborted");let shellConfig=resolveShellConfig();try{await fsAccess(cwd,constants2.F_OK)}catch{throw new Error(`Working directory does not exist: ${cwd}
|
|
898
898
|
Cannot execute ${shellName} commands.`)}if(signal?.aborted)throw new Error("aborted");let commandFromStdin=shellConfig.commandTransport==="stdin",normalizedCommand=normalizeCommand(command),child=spawn4(shellConfig.shell,commandFromStdin?shellConfig.args:[...shellConfig.args,normalizedCommand],{cwd,detached:process.platform!=="win32",env:env2??getShellEnv(),stdio:[commandFromStdin?"pipe":"ignore","pipe","pipe"],windowsHide:!0});commandFromStdin&&(child.stdin?.on("error",()=>{}),child.stdin?.end(normalizedCommand)),child.pid&&trackDetachedChildPid(child.pid);let timedOut=!1,timeoutHandle,onAbort=()=>{child.pid&&killProcessTree(child.pid)};try{timeoutMs!==void 0&&(timeoutHandle=setTimeout(()=>{timedOut=!0,child.pid&&killProcessTree(child.pid)},timeoutMs)),child.stdout?.on("data",onData),child.stderr?.on("data",onData),signal&&(signal.aborted?onAbort():signal.addEventListener("abort",onAbort,{once:!0}));let exitCode=await waitForChildProcess(child);if(signal?.aborted)throw new Error("aborted");if(timedOut)throw new Error(`timeout:${timeout}`);let signalCode=child.signalCode;return{exitCode:exitCode??(signalCode?128+(osConstants.signals[signalCode]??0):1)}}finally{child.pid&&untrackDetachedChildPid(child.pid),timeoutHandle&&clearTimeout(timeoutHandle),signal&&signal.removeEventListener("abort",onAbort)}}}}function resolveSpawnContext(command,cwd,spawnHook,exposeSessionEnvironment,ctx){let env2={...getShellEnv()};if(delete env2.PI_SESSION_ID,delete env2.PI_SESSION_FILE,delete env2.PI_PROVIDER,delete env2.PI_MODEL,delete env2.PI_REASONING_LEVEL,exposeSessionEnvironment&&ctx){let model=ctx.model;env2.PI_SESSION_ID=ctx.sessionManager.getSessionId();let sessionFile=ctx.sessionManager.getSessionFile();sessionFile&&(env2.PI_SESSION_FILE=sessionFile),model&&(env2.PI_PROVIDER=model.provider,env2.PI_MODEL=model.id),ctx.thinkingLevel&&(env2.PI_REASONING_LEVEL=ctx.thinkingLevel)}let baseContext={command,cwd,env:env2};return spawnHook?spawnHook(baseContext):baseContext}function shellToolResult(completion,managed){let status=completion.status;if(completion.result.structuredContent)return completion.result;if(status==="failed"||status==="timeout"||status==="cancelled"){let text2=completion.result.content.filter(part=>part.type==="text").map(part=>part.text).join(`
|
|
899
899
|
`),message=completion.error?text2||completion.error:`${text2?`${text2}
|
|
900
900
|
|
|
901
901
|
`:""}Command ${status}`;throw managed?new TaskExecutionError(message,status):new Error(message)}return completion.result}function createShellToolDefinition(cwd,config,options){let ops=options.operations,commandPrefix=options?.commandPrefix,exposeSessionEnvironment=options?.exposeSessionEnvironment??!0,spawnHook=options?.spawnHook;return{name:config.name,label:config.label,description:`Execute a ${config.shellName} command in the current working directory. Returns stdout and stderr, truncated to the last ${2e3} lines or ${51200/1024}KB (whichever is hit first); the full output is saved to a temp file. Optionally provide a timeout in seconds (no default). Choose the mode per call: foreground (default) blocks until the command exits \u2014 use it when your next step needs the output; background: true returns immediately with a task ID \u2014 use it for long-running work (builds, servers, watchers, big test suites) or when you have independent work to continue. A handoff is not completion: the result arrives later as an automatic completion notification; meanwhile use tasks read to inspect output, tasks wait to block until it settles, tasks kill to stop it. Background output is limited to 20 MiB; an expired tasks wait window never stops the command.`,promptSnippet:config.promptSnippet,promptGuidelines:exposeSessionEnvironment&&config.promptGuidelines?[...config.promptGuidelines]:void 0,parameters:bashSchema,outputSchema:bashOutputSchema,constrainedSampling:{type:"json_schema",strict:"prefer"},async execute(toolCallId,{command,timeout,background},parentSignal,originalUpdate,ctx){let host=ctx?.tasks;if(host?.closed)throw new Error("Task service is closed");let run=async managed=>{let signal=managed?.control.signal??parentSignal;try{if(managed){if(signal?.aborted)throw new Error("Command aborted");resolveTimeoutMs(timeout)}let resolvedCommand=commandPrefix?`${commandPrefix}
|
|
902
|
-
${command}`:command,spawnContext=resolveSpawnContext(resolvedCommand,ctx?.cwd||cwd,spawnHook,exposeSessionEnvironment,ctx);return await runShellCommand({operations:ops,context:spawnContext,tempFilePrefix:config.tempFilePrefix,timeout,signal,onUpdate:originalUpdate,managed})}catch(error){throw managed?new TaskExecutionError(error instanceof Error?error.message:String(error),managed.control.signal.aborted?"cancelled":"failed"):error}};if(!host){if(background)throw new Error("Background execution is not available in this host. No command was started.");return shellToolResult(await run(),!1)}let outcome=await host.execute({kind:config.name,title:command,toolCallId,command,cwd:ctx?.cwd||cwd,background,signal:parentSignal,onUpdate:originalUpdate,run:control=>run({control})});
|
|
902
|
+
${command}`:command,spawnContext=resolveSpawnContext(resolvedCommand,ctx?.cwd||cwd,spawnHook,exposeSessionEnvironment,ctx);return await runShellCommand({operations:ops,context:spawnContext,tempFilePrefix:config.tempFilePrefix,timeout,signal,onUpdate:originalUpdate,managed})}catch(error){throw managed?new TaskExecutionError(error instanceof Error?error.message:String(error),managed.control.signal.aborted?"cancelled":"failed"):error}};if(!host){if(background)throw new Error("Background execution is not available in this host. No command was started.");return shellToolResult(await run(),!1)}let outcome=await host.execute({kind:config.name,title:command,toolCallId,command,cwd:ctx?.cwd||cwd,background,signal:parentSignal,onUpdate:originalUpdate,run:control=>run({control})});if(outcome.kind==="result")return shellToolResult(outcome,!0);let tail2=`Task ID: ${outcome.task.id}. Status: ${outcome.task.status}. Completion arrives automatically as a notification \u2014 do not poll or immediately wait on it; continue with other work or hand back to the user. Use tasks read to inspect output, tasks wait only when your next step is blocked on the result (prefer foreground next time in that case), or tasks kill to stop it.`,handoff=background===!0?`Command handed to background. ${tail2}`:`Command moved to the background while it was running, by the user. The execution continues unchanged \u2014 no restart, and a supplied timeout is still measured from command startup. Output produced so far is already in the log, so tasks read now returns partial output, not a fresh start. ${tail2}`;return{structuredContent:{task_id:outcome.task.id,status:outcome.task.status},content:[{type:"text",text:`${handoff}${outcome.task.outputPath?`
|
|
903
903
|
Full output: ${outcome.task.outputPath}`:""}`}],details:{background:{kind:"background",taskId:outcome.task.id},fullOutputPath:outcome.task.outputPath}}},...createShellRenderers(config)}}function normalizeLocalBashCommand(command,platform3=process.platform){return platform3==="win32"?rewriteCmdNulRedirects(command):command}function createLocalBashOperations(options){return createLocalShellOperations("bash",()=>getShellConfig(options?.shellPath),normalizeLocalBashCommand)}var bashToolConfig={name:"bash",label:"bash",shellName:"bash",prompt:"$",promptSnippet:bashToolSystemPromptContribution.snippet,promptGuidelines:bashToolSystemPromptContribution.guidelines,tempFilePrefix:"pi-bash"};function createBashToolDefinition(cwd,options){return createShellToolDefinition(cwd,bashToolConfig,{...options,operations:options?.operations??createLocalBashOperations({shellPath:options?.shellPath})})}function createBashTool(cwd,options){let definition=createBashToolDefinition(cwd,options),tool=wrapToolDefinition(definition);return Object.assign(tool,{promptSnippet:definition.promptSnippet,promptGuidelines:definition.promptGuidelines}),tool}var Diff2=class{diff(oldStr,newStr,options={}){let callback;typeof options=="function"?(callback=options,options={}):"callback"in options&&(callback=options.callback);let oldString=this.castInput(oldStr,options),newString=this.castInput(newStr,options),oldTokens=this.removeEmpty(this.tokenize(oldString,options)),newTokens=this.removeEmpty(this.tokenize(newString,options));return this.diffWithOptionsObj(oldTokens,newTokens,options,callback)}diffWithOptionsObj(oldTokens,newTokens,options,callback){var _a2;let done=value=>{if(value=this.postProcess(value,options),callback){setTimeout(function(){callback(value)},0);return}else return value},newLen=newTokens.length,oldLen=oldTokens.length,editLength=1,maxEditLength=newLen+oldLen;options.maxEditLength!=null&&(maxEditLength=Math.min(maxEditLength,options.maxEditLength));let maxExecutionTime=(_a2=options.timeout)!==null&&_a2!==void 0?_a2:1/0,abortAfterTimestamp=Date.now()+maxExecutionTime,bestPath=[{oldPos:-1,lastComponent:void 0}],newPos=this.extractCommon(bestPath[0],newTokens,oldTokens,0,options);if(bestPath[0].oldPos+1>=oldLen&&newPos+1>=newLen)return done(this.buildValues(bestPath[0].lastComponent,newTokens,oldTokens));let minDiagonalToConsider=-1/0,maxDiagonalToConsider=1/0,execEditLength=()=>{for(let diagonalPath=Math.max(minDiagonalToConsider,-editLength);diagonalPath<=Math.min(maxDiagonalToConsider,editLength);diagonalPath+=2){let basePath,removePath=bestPath[diagonalPath-1],addPath=bestPath[diagonalPath+1];removePath&&(bestPath[diagonalPath-1]=void 0);let canAdd=!1;if(addPath){let addPathNewPos=addPath.oldPos-diagonalPath;canAdd=addPath&&0<=addPathNewPos&&addPathNewPos<newLen}let canRemove=removePath&&removePath.oldPos+1<oldLen;if(!canAdd&&!canRemove){bestPath[diagonalPath]=void 0;continue}if(!canRemove||canAdd&&removePath.oldPos<addPath.oldPos?basePath=this.addToPath(addPath,!0,!1,0,options):basePath=this.addToPath(removePath,!1,!0,1,options),newPos=this.extractCommon(basePath,newTokens,oldTokens,diagonalPath,options),basePath.oldPos+1>=oldLen&&newPos+1>=newLen)return done(this.buildValues(basePath.lastComponent,newTokens,oldTokens))||!0;bestPath[diagonalPath]=basePath,basePath.oldPos+1>=oldLen&&(maxDiagonalToConsider=Math.min(maxDiagonalToConsider,diagonalPath-1)),newPos+1>=newLen&&(minDiagonalToConsider=Math.max(minDiagonalToConsider,diagonalPath+1))}editLength++};if(callback)(function exec(){setTimeout(function(){if(editLength>maxEditLength||Date.now()>abortAfterTimestamp)return callback(void 0);execEditLength()||exec()},0)})();else for(;editLength<=maxEditLength&&Date.now()<=abortAfterTimestamp;){let ret=execEditLength();if(ret)return ret}}addToPath(path14,added,removed,oldPosInc,options){let last=path14.lastComponent;return last&&!options.oneChangePerToken&&last.added===added&&last.removed===removed?{oldPos:path14.oldPos+oldPosInc,lastComponent:{count:last.count+1,added,removed,previousComponent:last.previousComponent}}:{oldPos:path14.oldPos+oldPosInc,lastComponent:{count:1,added,removed,previousComponent:last}}}extractCommon(basePath,newTokens,oldTokens,diagonalPath,options){let newLen=newTokens.length,oldLen=oldTokens.length,oldPos=basePath.oldPos,newPos=oldPos-diagonalPath,commonCount=0;for(;newPos+1<newLen&&oldPos+1<oldLen&&this.equals(oldTokens[oldPos+1],newTokens[newPos+1],options);)newPos++,oldPos++,commonCount++,options.oneChangePerToken&&(basePath.lastComponent={count:1,previousComponent:basePath.lastComponent,added:!1,removed:!1});return commonCount&&!options.oneChangePerToken&&(basePath.lastComponent={count:commonCount,previousComponent:basePath.lastComponent,added:!1,removed:!1}),basePath.oldPos=oldPos,newPos}equals(left,right,options){return options.comparator?options.comparator(left,right):left===right||!!options.ignoreCase&&left.toLowerCase()===right.toLowerCase()}removeEmpty(array){let ret=[];for(let i=0;i<array.length;i++)array[i]&&ret.push(array[i]);return ret}castInput(value,options){return value}tokenize(value,options){return Array.from(value)}join(chars){return chars.join("")}postProcess(changeObjects,options){return changeObjects}get useLongestToken(){return!1}buildValues(lastComponent,newTokens,oldTokens){let components=[],nextComponent;for(;lastComponent;)components.push(lastComponent),nextComponent=lastComponent.previousComponent,delete lastComponent.previousComponent,lastComponent=nextComponent;components.reverse();let componentLen=components.length,componentPos=0,newPos=0,oldPos=0;for(;componentPos<componentLen;componentPos++){let component=components[componentPos];if(component.removed)component.value=this.join(oldTokens.slice(oldPos,oldPos+component.count)),oldPos+=component.count;else{if(!component.added&&this.useLongestToken){let value=newTokens.slice(newPos,newPos+component.count);value=value.map(function(value2,i){let oldValue=oldTokens[oldPos+i];return oldValue.length>value2.length?oldValue:value2}),component.value=this.join(value)}else component.value=this.join(newTokens.slice(newPos,newPos+component.count));newPos+=component.count,component.added||(oldPos+=component.count)}}return components}};function longestCommonPrefix(str1,str2){let i;for(i=0;i<str1.length&&i<str2.length;i++)if(str1[i]!=str2[i])return str1.slice(0,i);return str1.slice(0,i)}function longestCommonSuffix(str1,str2){let i;if(!str1||!str2||str1[str1.length-1]!=str2[str2.length-1])return"";for(i=0;i<str1.length&&i<str2.length;i++)if(str1[str1.length-(i+1)]!=str2[str2.length-(i+1)])return str1.slice(-i);return str1.slice(-i)}function replacePrefix(string2,oldPrefix,newPrefix){if(string2.slice(0,oldPrefix.length)!=oldPrefix)throw Error(`string ${JSON.stringify(string2)} doesn't start with prefix ${JSON.stringify(oldPrefix)}; this is a bug`);return newPrefix+string2.slice(oldPrefix.length)}function replaceSuffix(string2,oldSuffix,newSuffix){if(!oldSuffix)return string2+newSuffix;if(string2.slice(-oldSuffix.length)!=oldSuffix)throw Error(`string ${JSON.stringify(string2)} doesn't end with suffix ${JSON.stringify(oldSuffix)}; this is a bug`);return string2.slice(0,-oldSuffix.length)+newSuffix}function removePrefix(string2,oldPrefix){return replacePrefix(string2,oldPrefix,"")}function removeSuffix(string2,oldSuffix){return replaceSuffix(string2,oldSuffix,"")}function maximumOverlap(string1,string2){return string2.slice(0,overlapCount(string1,string2))}function overlapCount(a,b2){let startA=0;a.length>b2.length&&(startA=a.length-b2.length);let endB=b2.length;a.length<b2.length&&(endB=a.length);let map=Array(endB),k2=0;map[0]=0;for(let j2=1;j2<endB;j2++){for(b2[j2]==b2[k2]?map[j2]=map[k2]:map[j2]=k2;k2>0&&b2[j2]!=b2[k2];)k2=map[k2];b2[j2]==b2[k2]&&k2++}k2=0;for(let i=startA;i<a.length;i++){for(;k2>0&&a[i]!=b2[k2];)k2=map[k2];a[i]==b2[k2]&&k2++}return k2}function segment(string2,segmenter5){let parts=[];for(let segmentObj of Array.from(segmenter5.segment(string2))){let segment2=segmentObj.segment;parts.length&&/\s/.test(parts[parts.length-1])&&/\s/.test(segment2)?parts[parts.length-1]+=segment2:parts.push(segment2)}return parts}function trailingWs(string2,segmenter5){if(segmenter5)return leadingAndTrailingWs(string2,segmenter5)[1];let i;for(i=string2.length-1;i>=0&&string2[i].match(/\s/);i--);return string2.substring(i+1)}function leadingWs(string2,segmenter5){if(segmenter5)return leadingAndTrailingWs(string2,segmenter5)[0];let match2=string2.match(/^\s*/);return match2?match2[0]:""}function leadingAndTrailingWs(string2,segmenter5){if(!segmenter5)return[leadingWs(string2),trailingWs(string2)];if(segmenter5.resolvedOptions().granularity!="word")throw new Error('The segmenter passed must have a granularity of "word"');let segments=segment(string2,segmenter5),firstSeg=segments[0],lastSeg=segments[segments.length-1],head=/\s/.test(firstSeg)?firstSeg:"",tail2=/\s/.test(lastSeg)?lastSeg:"";return[head,tail2]}var extendedWordChars="a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}",tokenizeIncludingWhitespace=new RegExp(`[${extendedWordChars}]+|\\s+|[^${extendedWordChars}]`,"ug"),WordDiff=class extends Diff2{equals(left,right,options){return options.ignoreCase&&(left=left.toLowerCase(),right=right.toLowerCase()),left.trim()===right.trim()}tokenize(value,options={}){let parts;if(options.intlSegmenter){let segmenter5=options.intlSegmenter;if(segmenter5.resolvedOptions().granularity!="word")throw new Error('The segmenter passed must have a granularity of "word"');parts=segment(value,segmenter5)}else parts=value.match(tokenizeIncludingWhitespace)||[];let tokens2=[],prevPart=null;return parts.forEach(part=>{/\s/.test(part)?prevPart==null?tokens2.push(part):tokens2.push(tokens2.pop()+part):prevPart!=null&&/\s/.test(prevPart)?tokens2[tokens2.length-1]==prevPart?tokens2.push(tokens2.pop()+part):tokens2.push(prevPart+part):tokens2.push(part),prevPart=part}),tokens2}join(tokens2){return tokens2.map((token,i)=>i==0?token:token.replace(/^\s+/,"")).join("")}postProcess(changes,options){if(!changes||options.oneChangePerToken)return changes;let lastKeep=null,insertion=null,deletion=null;return changes.forEach(change=>{change.added?insertion=change:change.removed?deletion=change:((insertion||deletion)&&dedupeWhitespaceInChangeObjects(lastKeep,deletion,insertion,change,options.intlSegmenter),lastKeep=change,insertion=null,deletion=null)}),(insertion||deletion)&&dedupeWhitespaceInChangeObjects(lastKeep,deletion,insertion,null,options.intlSegmenter),changes}},wordDiff=new WordDiff;function diffWords(oldStr,newStr,options){return options?.ignoreWhitespace!=null&&!options.ignoreWhitespace?diffWordsWithSpace(oldStr,newStr,options):wordDiff.diff(oldStr,newStr,options)}function dedupeWhitespaceInChangeObjects(startKeep,deletion,insertion,endKeep,segmenter5){if(deletion&&insertion){let[oldWsPrefix,oldWsSuffix]=leadingAndTrailingWs(deletion.value,segmenter5),[newWsPrefix,newWsSuffix]=leadingAndTrailingWs(insertion.value,segmenter5);if(startKeep){let commonWsPrefix=longestCommonPrefix(oldWsPrefix,newWsPrefix);startKeep.value=replaceSuffix(startKeep.value,newWsPrefix,commonWsPrefix),deletion.value=removePrefix(deletion.value,commonWsPrefix),insertion.value=removePrefix(insertion.value,commonWsPrefix)}if(endKeep){let commonWsSuffix=longestCommonSuffix(oldWsSuffix,newWsSuffix);endKeep.value=replacePrefix(endKeep.value,newWsSuffix,commonWsSuffix),deletion.value=removeSuffix(deletion.value,commonWsSuffix),insertion.value=removeSuffix(insertion.value,commonWsSuffix)}}else if(insertion){if(startKeep){let ws=leadingWs(insertion.value,segmenter5);insertion.value=insertion.value.substring(ws.length)}if(endKeep){let ws=leadingWs(endKeep.value,segmenter5);endKeep.value=endKeep.value.substring(ws.length)}}else if(startKeep&&endKeep){let newWsFull=leadingWs(endKeep.value,segmenter5),[delWsStart,delWsEnd]=leadingAndTrailingWs(deletion.value,segmenter5),newWsStart=longestCommonPrefix(newWsFull,delWsStart);deletion.value=removePrefix(deletion.value,newWsStart);let newWsEnd=longestCommonSuffix(removePrefix(newWsFull,newWsStart),delWsEnd);deletion.value=removeSuffix(deletion.value,newWsEnd),endKeep.value=replacePrefix(endKeep.value,newWsFull,newWsEnd),startKeep.value=replaceSuffix(startKeep.value,newWsFull,newWsFull.slice(0,newWsFull.length-newWsEnd.length))}else if(endKeep){let endKeepWsPrefix=leadingWs(endKeep.value,segmenter5),deletionWsSuffix=trailingWs(deletion.value,segmenter5),overlap=maximumOverlap(deletionWsSuffix,endKeepWsPrefix);deletion.value=removeSuffix(deletion.value,overlap)}else if(startKeep){let startKeepWsSuffix=trailingWs(startKeep.value,segmenter5),deletionWsPrefix=leadingWs(deletion.value,segmenter5),overlap=maximumOverlap(startKeepWsSuffix,deletionWsPrefix);deletion.value=removePrefix(deletion.value,overlap)}}var WordsWithSpaceDiff=class extends Diff2{tokenize(value){let regex2=new RegExp(`(\\r?\\n)|[${extendedWordChars}]+|[^\\S\\n\\r]+|[^${extendedWordChars}]`,"ug");return value.match(regex2)||[]}},wordsWithSpaceDiff=new WordsWithSpaceDiff;function diffWordsWithSpace(oldStr,newStr,options){return wordsWithSpaceDiff.diff(oldStr,newStr,options)}var LineDiff=class extends Diff2{constructor(){super(...arguments),this.tokenize=tokenize}equals(left,right,options){return options.ignoreWhitespace?((!options.newlineIsToken||!left.includes(`
|
|
904
904
|
`))&&(left=left.trim()),(!options.newlineIsToken||!right.includes(`
|
|
905
905
|
`))&&(right=right.trim())):options.ignoreNewlineAtEof&&!options.newlineIsToken&&(left.endsWith(`
|
|
@@ -1713,7 +1713,7 @@ ${statusParts.join(`
|
|
|
1713
1713
|
|
|
1714
1714
|
`;content.addChild(new Markdown(header+this.message.summary,0,0,this.markdownTheme,{color:text2=>theme.fg("customMessageText",text2)}))}else content.addChild(new Text(theme.fg("customMessageText","Branch summary (")+theme.fg("dim",keyText("app.tools.expand"))+theme.fg("customMessageText"," to expand)"),0,0));this.addChild(new MouseRegion(content,event=>{if(!(event.type!=="click"||event.button!=="left"))return this.setExpanded(!this.expanded),{handled:!0}}))}};var CompactionSummaryMessageComponent=class extends Box{constructor(message,markdownTheme=getMarkdownTheme()){super(1,1,t=>theme.bg("customMessageBg",t)),this.expanded=!1,this.message=message,this.markdownTheme=markdownTheme,this.updateDisplay()}setExpanded(expanded){this.expanded=expanded,this.updateDisplay()}invalidate(){super.invalidate(),this.updateDisplay()}updateDisplay(){this.clear();let content=new Container,tokenStr=this.message.tokensBefore.toLocaleString(),label=theme.fg("customMessageLabel","\x1B[1m[compaction]\x1B[22m");if(content.addChild(new Text(label,0,0)),content.addChild(new Spacer(1)),this.expanded){let header=`**Compacted from ${tokenStr} tokens**
|
|
1715
1715
|
|
|
1716
|
-
`;content.addChild(new Markdown(header+this.message.summary,0,0,this.markdownTheme,{color:text2=>theme.fg("customMessageText",text2)}))}else content.addChild(new Text(theme.fg("customMessageText",`Compacted from ${tokenStr} tokens (`)+theme.fg("dim",keyText("app.tools.expand"))+theme.fg("customMessageText"," to expand)"),0,0));this.addChild(new MouseRegion(content,event=>{if(!(event.type!=="click"||event.button!=="left"))return this.setExpanded(!this.expanded),{handled:!0}}))}};var CustomEditor=class extends Editor{constructor(tui,theme2,keybindings,options){super(tui,theme2,options),this.actionHandlers=new Map,this.keybindings=keybindings,this.embedWorkingStatus=options?.embedWorkingStatus??!1}setWorkingStatusIndicator(indicator){this.workingStatusIndicator=indicator}renderTopBorder(width,hiddenLineCount){if(!this.embedWorkingStatus||!this.workingStatusIndicator||width<=0)return super.renderTopBorder(width,hiddenLineCount);let status=this.workingStatusIndicator.renderInBorder(Math.max(1,width-5)),statusWidth=visibleWidth(status);if(statusWidth===0)return super.renderTopBorder(width,hiddenLineCount);let overflowLabel=hiddenLineCount>0?` \u2191 ${hiddenLineCount} more `:void 0,overflowLabelWidth=overflowLabel?visibleWidth(overflowLabel):0,overflowStart=Math.floor((width-overflowLabelWidth)/2),canFitOverflow=()=>overflowLabel!==void 0&&overflowLabelWidth+2<=width&&overflowStart-(3+statusWidth+1)>=1;if(overflowLabel&&!canFitOverflow()&&(status=this.workingStatusIndicator.renderSpinnerInBorder(width),statusWidth=visibleWidth(status)),canFitOverflow()){let leftBlockWidth=3+statusWidth+1;return this.borderColor("\u2500\u2500 ")+status+this.borderColor(` ${"\u2500".repeat(overflowStart-leftBlockWidth)}${overflowLabel}${"\u2500".repeat(width-overflowStart-overflowLabelWidth)}`)}if(width>=statusWidth+5)return this.borderColor("\u2500\u2500 ")+status+this.borderColor(` ${"\u2500".repeat(width-statusWidth-4)}`);status=this.workingStatusIndicator.renderSpinnerInBorder(width),statusWidth=visibleWidth(status);let prefixWidth=Math.min(3,Math.max(0,width-statusWidth));return this.borderColor("\u2500".repeat(prefixWidth))+status+this.borderColor("\u2500".repeat(Math.max(0,width-prefixWidth-statusWidth)))}onAction(action,handler){this.actionHandlers.set(action,handler)}handleInput(data){if(!this.onExtensionShortcut?.(data)){if(this.keybindings.matches(data,"app.clipboard.pasteImage")){this.onPasteImage?.();return}if(this.keybindings.matches(data,"app.interrupt")){if(!this.isShowingAutocomplete()){let handler=this.onEscape??this.actionHandlers.get("app.interrupt");if(handler){handler();return}}super.handleInput(data);return}if(this.keybindings.matches(data,"app.exit")&&this.getText().length===0){let handler=this.onCtrlD??this.actionHandlers.get("app.exit");handler&&handler();return}if(this.keybindings.matches(data,"tui.editor.historyPrevious")||this.keybindings.matches(data,"tui.editor.historyNext")){super.handleInput(data);return}for(let[action,handler]of this.actionHandlers)if(action!=="app.interrupt"&&action!=="app.exit"&&this.keybindings.matches(data,action)){handler();return}super.handleInput(data)}}};var toolStyle={marker:{glyph:"\u25CF",color:{pending:"warning",success:"success",error:"error"}},rail:{glyph:"\u2502",color:"dim"},gap:{afterTool:0,afterOther:1},collapsed:{headerOnly:new Set(["read","grep","find","ls"]),fallbackLines:10},fallbackArgsWidth:120};function toolStatus(state2){return state2.isPartial?"pending":state2.isError?"error":"success"}function toolMarkerColor(status){return toolStyle.marker.color[status]}function cellWidth(){return Math.max(visibleWidth(toolStyle.marker.glyph),visibleWidth(toolStyle.rail.glyph))}function gutterWidth(){return cellWidth()+1}function gutterCell(glyph,color2){return`${theme.fg(color2,glyph)}${" ".repeat(cellWidth()-visibleWidth(glyph)+1)}`}function isBlankLine(line){return line===""||stripAnsi(line).trim()===""}function dropLeadingBlankLines(lines){let start=0;for(;start<lines.length&&isBlankLine(lines[start]);)start++;return lines.slice(start)}var FramedComponent=class{constructor(component,kind,markerColor){this.component=component,this.kind=kind,this.markerColor=markerColor}render(width){let rendered=this.component.render(Math.max(1,width-gutterWidth())),lines=this.kind==="body"?dropLeadingBlankLines(rendered):rendered.length>1?[rendered[0],...dropLeadingBlankLines(rendered.slice(1))]:rendered;if(lines.length===0)return[];let rail=gutterCell(toolStyle.rail.glyph,toolStyle.rail.color),bareRail=theme.fg(toolStyle.rail.color,toolStyle.rail.glyph);return lines.map((line,index3)=>index3===0&&this.kind==="header"?`${gutterCell(toolStyle.marker.glyph,this.markerColor())}${line}`:isBlankLine(line)?bareRail:`${rail}${line}`)}invalidate(){this.component.invalidate()}};var SOURCE_LIMIT=64*1024,CARD_ROWS=128,OUTPUT_ROWS=20,SHELL_NAMES={bash:"Bash",powershell:"PowerShell"};function clean(text2){return sanitizeBinaryOutput(stripTerminalSequences(text2)).replace(/\r\n?/g,`
|
|
1716
|
+
`;content.addChild(new Markdown(header+this.message.summary,0,0,this.markdownTheme,{color:text2=>theme.fg("customMessageText",text2)}))}else content.addChild(new Text(theme.fg("customMessageText",`Compacted from ${tokenStr} tokens (`)+theme.fg("dim",keyText("app.tools.expand"))+theme.fg("customMessageText"," to expand)"),0,0));this.addChild(new MouseRegion(content,event=>{if(!(event.type!=="click"||event.button!=="left"))return this.setExpanded(!this.expanded),{handled:!0}}))}};var CustomEditor=class extends Editor{constructor(tui,theme2,keybindings,options){super(tui,theme2,options),this.actionHandlers=new Map,this.keybindings=keybindings,this.embedWorkingStatus=options?.embedWorkingStatus??!1}setWorkingStatusIndicator(indicator){this.workingStatusIndicator=indicator}renderTopBorder(width,hiddenLineCount){if(!this.embedWorkingStatus||!this.workingStatusIndicator||width<=0)return super.renderTopBorder(width,hiddenLineCount);let status=this.workingStatusIndicator.renderInBorder(Math.max(1,width-5)),statusWidth=visibleWidth(status);if(statusWidth===0)return super.renderTopBorder(width,hiddenLineCount);let overflowLabel=hiddenLineCount>0?` \u2191 ${hiddenLineCount} more `:void 0,overflowLabelWidth=overflowLabel?visibleWidth(overflowLabel):0,overflowStart=Math.floor((width-overflowLabelWidth)/2),canFitOverflow=()=>overflowLabel!==void 0&&overflowLabelWidth+2<=width&&overflowStart-(3+statusWidth+1)>=1;if(overflowLabel&&!canFitOverflow()&&(status=this.workingStatusIndicator.renderSpinnerInBorder(width),statusWidth=visibleWidth(status)),canFitOverflow()){let leftBlockWidth=3+statusWidth+1;return this.borderColor("\u2500\u2500 ")+status+this.borderColor(` ${"\u2500".repeat(overflowStart-leftBlockWidth)}${overflowLabel}${"\u2500".repeat(width-overflowStart-overflowLabelWidth)}`)}if(width>=statusWidth+5)return this.borderColor("\u2500\u2500 ")+status+this.borderColor(` ${"\u2500".repeat(width-statusWidth-4)}`);status=this.workingStatusIndicator.renderSpinnerInBorder(width),statusWidth=visibleWidth(status);let prefixWidth=Math.min(3,Math.max(0,width-statusWidth));return this.borderColor("\u2500".repeat(prefixWidth))+status+this.borderColor("\u2500".repeat(Math.max(0,width-prefixWidth-statusWidth)))}onAction(action,handler){this.actionHandlers.set(action,handler)}handleInput(data){if(!this.onExtensionShortcut?.(data)){if(this.keybindings.matches(data,"app.clipboard.pasteImage")){this.onPasteImage?.();return}if(this.keybindings.matches(data,"app.interrupt")){if(!this.isShowingAutocomplete()){let handler=this.onEscape??this.actionHandlers.get("app.interrupt");if(handler){handler();return}}super.handleInput(data);return}if(this.keybindings.matches(data,"app.exit")&&this.getText().length===0){let handler=this.onCtrlD??this.actionHandlers.get("app.exit");handler&&handler();return}if(this.keybindings.matches(data,"tui.editor.historyPrevious")||this.keybindings.matches(data,"tui.editor.historyNext")){super.handleInput(data);return}for(let[action,handler]of this.actionHandlers)if(action!=="app.interrupt"&&action!=="app.exit"&&this.keybindings.matches(data,action)){handler();return}super.handleInput(data)}}};var toolStyle={marker:{glyph:"\u25CF",color:{pending:"warning",success:"success",error:"error"}},rail:{glyph:"\u2502",color:"dim"},gap:{afterTool:0,afterMultilineTool:1,afterOther:1},collapsed:{headerOnly:new Set(["read","grep","find","ls"]),fallbackLines:10},fallbackArgsWidth:120};function toolStatus(state2){return state2.isPartial?"pending":state2.isError?"error":"success"}function toolMarkerColor(status){return toolStyle.marker.color[status]}function cellWidth(){return Math.max(visibleWidth(toolStyle.marker.glyph),visibleWidth(toolStyle.rail.glyph))}function gutterWidth(){return cellWidth()+1}function gutterCell(glyph,color2){return`${theme.fg(color2,glyph)}${" ".repeat(cellWidth()-visibleWidth(glyph)+1)}`}function isBlankLine(line){return line===""||stripAnsi(line).trim()===""}function dropLeadingBlankLines(lines){let start=0;for(;start<lines.length&&isBlankLine(lines[start]);)start++;return lines.slice(start)}var FramedComponent=class{constructor(component,kind,markerColor){this.component=component,this.kind=kind,this.markerColor=markerColor}render(width){let rendered=this.component.render(Math.max(1,width-gutterWidth())),lines=this.kind==="body"?dropLeadingBlankLines(rendered):rendered.length>1?[rendered[0],...dropLeadingBlankLines(rendered.slice(1))]:rendered;if(lines.length===0)return[];let rail=gutterCell(toolStyle.rail.glyph,toolStyle.rail.color),bareRail=theme.fg(toolStyle.rail.color,toolStyle.rail.glyph);return lines.map((line,index3)=>index3===0&&this.kind==="header"?`${gutterCell(toolStyle.marker.glyph,this.markerColor())}${line}`:isBlankLine(line)?bareRail:`${rail}${line}`)}invalidate(){this.component.invalidate()}};var SOURCE_LIMIT=64*1024,CARD_ROWS=128,OUTPUT_ROWS=20,SHELL_NAMES={bash:"Bash",powershell:"PowerShell"};function clean(text2){return sanitizeBinaryOutput(stripTerminalSequences(text2)).replace(/\r\n?/g,`
|
|
1717
1717
|
`)}function savedText(message){let content=message.content,text2="",clipped=!1;if(typeof content=="string")text2=content.slice(0,SOURCE_LIMIT),clipped=content.length>SOURCE_LIMIT;else if(Array.isArray(content)){let visited2=0;for(let block of content){if(++visited2>256){clipped=!0;break}if(!block||block.type!=="text"||typeof block.text!="string")continue;let next=`${text2?`
|
|
1718
1718
|
`:""}${block.text.slice(0,SOURCE_LIMIT+1)}`,remaining=SOURCE_LIMIT-text2.length;if(text2+=next.slice(0,remaining),next.length>remaining||block.text.length>SOURCE_LIMIT){clipped=!0;break}}}return{text:clean(text2),clipped}}function completionView(message){let snapshot=readTaskCompletion(message.details);if(!snapshot){let{text:text2,clipped}=savedText(message);return{body:text2,truncated:clipped}}return{title:clean(snapshot.title),duration:runtimeLabel(snapshot),kind:snapshot.kind,status:snapshot.status,id:clean(snapshot.taskId),exitCode:snapshot.exitCode,command:snapshot.command===void 0?void 0:clean(snapshot.command.text),cwd:snapshot.cwd===void 0?void 0:clean(snapshot.cwd),path:snapshot.outputPath===void 0?void 0:clean(snapshot.outputPath),diagnostic:snapshot.error===void 0?void 0:clean(snapshot.error),output:clean(snapshot.output.text),body:"",truncated:snapshot.output.truncated||snapshot.command?.truncated===!0}}function color(status){return status===void 0?"muted":statusMarker(status).color}function shortId(id){return id.replace(/^(.+)-([0-9a-f]{8})-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,"$1-$2")}var CompletionCard=class{constructor(view,options,theme2){this.view=view,this.options=options,this.theme=theme2}invalidate(){}render(width){return width<1?[]:new FramedComponent({render:contentWidth=>this.renderContent(contentWidth),invalidate(){}},"header",()=>color(this.view.status)).render(width).map(line=>truncateToWidth(line,width,""))}renderContent(width){if(!Number.isFinite(width)||width<1)return[];let view=this.view,theme2=this.theme,options=this.options,padding=Math.min(Math.max(0,Math.floor(options.outputPad||0)-1),Math.floor((width-1)/2)),inner=width-padding*2,indent=inner>=3?" ":"",bodyWidth=Math.max(1,inner-indent.length),lines=[],status=view.status?statusName(view.status):"Result received",kind=view.kind===void 0?"Notification":SHELL_NAMES[view.kind]??view.kind;lines.push(`${theme2.fg("toolTitle",theme2.bold(kind))}${theme2.fg("muted",` \xB7 Background ${status.toLowerCase()}${view.duration?` \xB7 ${view.duration}`:""}`)}${view.id?theme2.fg("dim",` \xB7 ${shortId(view.id)}`):""}`);let summary=view.command?`$ ${view.command.split(`
|
|
1719
1719
|
`)[0]}`:view.title;if(!options.expanded)summary&&lines.push(theme2.fg("toolOutput",summary)),view.diagnostic&&lines.push(theme2.fg(color(view.status),view.diagnostic));else{view.truncated&&lines.push(theme2.fg("warning","The saved result is truncated; this is not the complete original output."));let section=(title,text2,limit,tail2=!1,error=!1)=>{lines.push("",theme2.fg("muted",theme2.bold(title)));let rendered=wrapTextWithAnsi(text2,bodyWidth).map(line=>theme2.fg(error?"error":"toolOutput",line)),omitted=Math.max(0,rendered.length-limit),selected=tail2?rendered.slice(-limit):rendered.slice(0,limit);tail2&&omitted&&lines.push(theme2.fg("dim",`${indent}\u2026 ${omitted} earlier display lines omitted`));for(let line of selected)lines.push(indent+line);!tail2&&omitted&&lines.push(theme2.fg("dim",`${indent}\u2026 ${omitted} more display lines omitted`))};view.output===void 0?section("Details",view.body||"No text result.",36):(view.command?section("Command",view.command,8):view.title&§ion("Task",view.title,4),view.cwd&§ion("Directory",view.cwd,2),section(view.status==="failed"||view.status==="timeout"?"Error":"Result",`${view.diagnostic??status}${view.exitCode!==void 0?` \xB7 ${view.exitCode===null?"terminated by signal":`exit ${view.exitCode}`}`:""}`,4,!1,view.status==="failed"),section("Output",view.output.trim()?view.output:"No output.",OUTPUT_ROWS,!0),view.path&§ion("Log",view.path,4)),view.id&&lines.push("",...wrapTextWithAnsi(`Task ID: ${view.id}`,inner).map(line=>theme2.fg("dim",line))),lines.push(theme2.fg("dim","Preview of the saved result."))}return(lines.length>CARD_ROWS?[...lines.slice(0,CARD_ROWS-1),theme2.fg("dim","\u2026 card shortened; use tasks read for retained output")]:lines).map(line=>" ".repeat(padding)+truncateToWidth(line,inner,"\u2026")+" ".repeat(padding))}};function renderTaskCompletion(message,options,theme2){let view;try{view=completionView(message)}catch{view={body:"The saved notification could not be interpreted. Its original message remains in session history.",truncated:!1}}return new CompletionCard(view,options,theme2)}function isPlainPrimaryClick(event){return event.type==="click"&&event.button==="left"&&!event.shift&&!event.alt&&!event.ctrl&&(event.clickCount??1)===1}var CustomMessageComponent=class extends Container{constructor(message,customRenderer,markdownTheme=getMarkdownTheme(),outputPad=1){super(),this._expanded=!1,this.message=message,this.customRenderer=customRenderer??(message.customType==="task-completion"?renderTaskCompletion:void 0),this.markdownTheme=markdownTheme,this.outputPad=outputPad,this.addChild(new Spacer(1)),this.box=new Box(1,1,t=>theme.bg("customMessageBg",t)),this.rebuild()}setExpanded(expanded){this._expanded!==expanded&&(this._expanded=expanded,this.rebuild())}setOutputPad(outputPad){this.outputPad!==outputPad&&(this.outputPad=outputPad,this.rebuild())}invalidate(){super.invalidate(),this.rebuild()}rebuild(){if(this.customComponent&&(this.removeChild(this.customComponent),this.customComponent=void 0),this.removeChild(this.box),this.customRenderer)try{let component=this.customRenderer(this.message,{expanded:this._expanded,outputPad:this.outputPad},theme);if(component){this.customComponent=new MouseRegion(component,event=>{if(isPlainPrimaryClick(event))return this.setExpanded(!this._expanded),{handled:!0}}),this.addChild(this.customComponent);return}}catch{}this.addChild(this.box),this.box.clear();let label=theme.fg("customMessageLabel",`\x1B[1m[${this.message.customType}]\x1B[22m`);this.box.addChild(new Text(label,0,0)),this.box.addChild(new Spacer(1));let text2;typeof this.message.content=="string"?text2=this.message.content:text2=this.message.content.filter(c=>c.type==="text").map(c=>c.text).join(`
|
|
@@ -1723,10 +1723,10 @@ ${statusParts.join(`
|
|
|
1723
1723
|
`;content.addChild(new Markdown(header+this.skillBlock.content,0,0,this.markdownTheme,{color:text2=>theme.fg("customMessageText",text2)}))}else{let line=theme.fg("customMessageLabel","\x1B[1m[skill]\x1B[22m ")+theme.fg("customMessageText",this.skillBlock.name)+theme.fg("dim",` (${keyText("app.tools.expand")} to expand)`);content.addChild(new Text(line,0,0))}this.addChild(new MouseRegion(content,event=>{if(!(event.type!=="click"||event.button!=="left"))return this.setExpanded(!this.expanded),{handled:!0}}))}};var THINKING_SELECT_LIST_LAYOUT={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},LEVEL_DESCRIPTIONS={off:"No reasoning",minimal:"Very brief reasoning (~1k tokens)",low:"Light reasoning (~2k tokens)",medium:"Moderate reasoning (~8k tokens)",high:"Deep reasoning (~16k tokens)",xhigh:"Extra-high reasoning (~32k tokens)",max:"Maximum reasoning"},ThinkingSelectorComponent=class extends Container{get focused(){return this._focused}set focused(value){this._focused=value,this.searchInput.focused=value}constructor(currentLevel,availableLevels,onSelect,onCancel,onSelectAsDefault,defaultThinkingLevel){super(),this._focused=!1,this.onSelect=onSelect,this.onCancel=onCancel,this.onSelectAsDefault=onSelectAsDefault,this.allItems=availableLevels.map(level=>({value:level,label:`${level===currentLevel?"\u2713 ":" "}${level}`,description:level===defaultThinkingLevel?`${LEVEL_DESCRIPTIONS[level]} \xB7 default`:LEVEL_DESCRIPTIONS[level]})),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text("Thinking Level",0,0)),this.addChild(new Spacer(1)),this.addChild(new Text(`${keyDisplayText("app.thinking.cycle")} cycles thinking levels in-session`,0,0)),this.addChild(new Spacer(1)),this.searchInput=new Input,this.searchInput.onSubmit=()=>this.selectList.handleInput("\r"),this.addChild(this.searchInput),this.addChild(new Spacer(1)),this.selectList=this.buildSelectList(this.allItems,currentLevel),this.selectListChildIndex=this.children.length,this.addChild(this.selectList),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("dim",` ${keyDisplayText("tui.select.confirm")} to select \xB7 ${keyDisplayText("app.thinking.save")} to set as default \xB7 ${keyDisplayText("tui.select.cancel")} to cancel`),0,0)),this.addChild(new DynamicBorder)}buildSelectList(items,preselect){let list2=new SelectList(items,Math.max(1,items.length),getSelectListTheme(),THINKING_SELECT_LIST_LAYOUT),currentIndex=items.findIndex(item=>item.value===preselect);return currentIndex!==-1&&list2.setSelectedIndex(currentIndex),list2.onSelect=item=>this.onSelect(item.value),list2.onCancel=()=>this.onCancel(),list2}applyFilter(query){let filtered=query?fuzzyFilter(this.allItems,query,item=>`${item.value} ${item.description??""}`):this.allItems,selectedValue=this.selectList.getSelectedItem()?.value,newList=this.buildSelectList(filtered,selectedValue);this.children[this.selectListChildIndex]=newList,this.selectList=newList}handleInput(keyData){let kb=getKeybindings();if(kb.matches(keyData,"app.thinking.save")&&this.onSelectAsDefault){let item=this.selectList.getSelectedItem();item&&this.onSelectAsDefault(item.value);return}if(kb.matches(keyData,"tui.select.up")||kb.matches(keyData,"tui.select.down")||kb.matches(keyData,"tui.select.confirm")||kb.matches(keyData,"tui.select.cancel")){this.selectList.handleInput(keyData);return}this.searchInput.handleInput(keyData),this.applyFilter(this.searchInput.getValue())}getSelectList(){return this.selectList}};var TREE_GUTTER_WIDTH=2,MIN_VISIBLE_ANCHOR_CONTENT_WIDTH=4,MAX_VISIBLE_ANCHOR_CONTENT_WIDTH=20,MIN_ANCHOR_CONTEXT_WIDTH=2,MAX_ANCHOR_CONTEXT_WIDTH=12;function renderHorizontalViewport(rows,width){let viewportWidth=Math.max(0,width-TREE_GUTTER_WIDTH),maxBodyWidth=rows.reduce((max,row)=>Math.max(max,row.bodyWidth),0),maxHorizontalScroll=Math.max(0,maxBodyWidth-viewportWidth),selectedRow=rows.find(row=>row.isSelected),horizontalScroll=0;if(selectedRow&&maxHorizontalScroll>0){let minVisibleAnchorContentWidth=Math.min(MAX_VISIBLE_ANCHOR_CONTENT_WIDTH,Math.max(MIN_VISIBLE_ANCHOR_CONTENT_WIDTH,Math.floor(viewportWidth/3)));if(selectedRow.anchorCol>viewportWidth-minVisibleAnchorContentWidth){let anchorContextWidth=Math.min(MAX_ANCHOR_CONTEXT_WIDTH,Math.max(MIN_ANCHOR_CONTEXT_WIDTH,Math.floor(viewportWidth/4)));horizontalScroll=Math.min(maxHorizontalScroll,selectedRow.anchorCol-anchorContextWidth)}}return rows.map(row=>{let line=horizontalScroll>0?`${row.gutter}${sliceByColumn(row.body,horizontalScroll,viewportWidth,!0)}\x1B[0m`:row.gutter+row.body;return truncateToWidth(line,width,"")})}var TreeList=class{constructor(tree,currentLeafId,maxVisibleLines,initialSelectedId,initialFilterMode){this.flatNodes=[],this.filteredNodes=[],this.selectedIndex=0,this.filterMode="default",this.searchQuery="",this.toolCallMap=new Map,this.multipleRoots=!1,this.showLabelTimestamps=!1,this.activePathIds=new Set,this.visibleParentMap=new Map,this.visibleChildrenMap=new Map,this.lastSelectedId=null,this.foldedNodes=new Set,this.currentLeafId=currentLeafId,this.maxVisibleLines=maxVisibleLines,this.filterMode=initialFilterMode??"default",this.multipleRoots=tree.length>1,this.flatNodes=this.flattenTree(tree),this.buildActivePath(),this.applyFilter();let targetId=initialSelectedId??currentLeafId;this.selectedIndex=this.findNearestVisibleIndex(targetId),this.lastSelectedId=this.filteredNodes[this.selectedIndex]?.node.entry.id??null}findNearestVisibleIndex(entryId){if(this.filteredNodes.length===0)return 0;let entryMap=new Map;for(let flatNode of this.flatNodes)entryMap.set(flatNode.node.entry.id,flatNode);let visibleIdToIndex=new Map(this.filteredNodes.map((node,i)=>[node.node.entry.id,i])),currentId=entryId;for(;currentId!==null;){let index3=visibleIdToIndex.get(currentId);if(index3!==void 0)return index3;let node=entryMap.get(currentId);if(!node)break;currentId=node.node.entry.parentId??null}return this.filteredNodes.length-1}buildActivePath(){if(this.activePathIds.clear(),!this.currentLeafId)return;let entryMap=new Map;for(let flatNode of this.flatNodes)entryMap.set(flatNode.node.entry.id,flatNode);let currentId=this.currentLeafId;for(;currentId;){this.activePathIds.add(currentId);let node=entryMap.get(currentId);if(!node)break;currentId=node.node.entry.parentId??null}}flattenTree(roots){let result2=[];this.toolCallMap.clear();let stack=[],containsActive=new Map,leafId=this.currentLeafId;{let allNodes=[],preOrderStack=[...roots];for(;preOrderStack.length>0;){let node=preOrderStack.pop();allNodes.push(node);for(let i=node.children.length-1;i>=0;i--)preOrderStack.push(node.children[i])}for(let i=allNodes.length-1;i>=0;i--){let node=allNodes[i],has=leafId!==null&&node.entry.id===leafId;for(let child of node.children)containsActive.get(child)&&(has=!0);containsActive.set(node,has)}}let multipleRoots=roots.length>1,orderedRoots=[...roots].sort((a,b2)=>Number(containsActive.get(b2))-Number(containsActive.get(a)));for(let i=orderedRoots.length-1;i>=0;i--){let isLast=i===orderedRoots.length-1;stack.push([orderedRoots[i],multipleRoots?1:0,multipleRoots,multipleRoots,isLast,[],multipleRoots])}for(;stack.length>0;){let[node,indent,justBranched,showConnector,isLast,gutters,isVirtualRootChild]=stack.pop(),entry=node.entry;if(entry.type==="message"&&entry.message.role==="assistant"){let content=entry.message.content;if(Array.isArray(content)){for(let block of content)if(typeof block=="object"&&block!==null&&"type"in block&&block.type==="toolCall"){let tc=block;this.toolCallMap.set(tc.id,{name:tc.name,arguments:tc.arguments})}}}result2.push({node,indent,showConnector,isLast,gutters,isVirtualRootChild});let children=node.children,multipleChildren=children.length>1,orderedChildren=(()=>{let prioritized=[],rest=[];for(let child of children)containsActive.get(child)?prioritized.push(child):rest.push(child);return[...prioritized,...rest]})(),childIndent;multipleChildren||justBranched&&indent>0?childIndent=indent+1:childIndent=indent;let connectorDisplayed=showConnector&&!isVirtualRootChild,currentDisplayIndent=this.multipleRoots?Math.max(0,indent-1):indent,connectorPosition=Math.max(0,currentDisplayIndent-1),childGutters=connectorDisplayed?[...gutters,{position:connectorPosition,show:!isLast}]:gutters;for(let i=orderedChildren.length-1;i>=0;i--){let childIsLast=i===orderedChildren.length-1;stack.push([orderedChildren[i],childIndent,multipleChildren,multipleChildren,childIsLast,childGutters,!1])}}return result2}applyFilter(){this.filteredNodes.length>0&&(this.lastSelectedId=this.filteredNodes[this.selectedIndex]?.node.entry.id??this.lastSelectedId);let searchTokens=this.searchQuery.toLowerCase().split(/\s+/).filter(Boolean);if(this.filteredNodes=this.flatNodes.filter(flatNode=>{let entry=flatNode.node.entry;if(entry.type==="usage")return!1;let isCurrentLeaf=entry.id===this.currentLeafId;if(entry.type==="message"&&entry.message.role==="assistant"&&!isCurrentLeaf){let msg=entry.message,hasText=this.hasTextContent(msg.content),isErrorOrAborted=msg.stopReason&&msg.stopReason!=="stop"&&msg.stopReason!=="toolUse";if(!hasText&&!isErrorOrAborted)return!1}let passesFilter=!0,isSettingsEntry=entry.type==="label"||entry.type==="context_edit"||entry.type==="custom"||entry.type==="model_change"||entry.type==="thinking_level_change"||entry.type==="session_info";switch(this.filterMode){case"user-only":passesFilter=entry.type==="message"&&entry.message.role==="user";break;case"no-tools":passesFilter=!isSettingsEntry&&!(entry.type==="message"&&entry.message.role==="toolResult");break;case"labeled-only":passesFilter=flatNode.node.label!==void 0;break;case"all":passesFilter=!0;break;default:passesFilter=!isSettingsEntry;break}if(!passesFilter)return!1;if(searchTokens.length>0){let nodeText=this.getSearchableText(flatNode.node).toLowerCase();return searchTokens.every(token=>nodeText.includes(token))}return!0}),this.foldedNodes.size>0){let skipSet=new Set;for(let flatNode of this.flatNodes){let{id,parentId}=flatNode.node.entry;parentId!=null&&(this.foldedNodes.has(parentId)||skipSet.has(parentId))&&skipSet.add(id)}this.filteredNodes=this.filteredNodes.filter(flatNode=>!skipSet.has(flatNode.node.entry.id))}this.recalculateVisualStructure(),this.lastSelectedId?this.selectedIndex=this.findNearestVisibleIndex(this.lastSelectedId):this.selectedIndex>=this.filteredNodes.length&&(this.selectedIndex=Math.max(0,this.filteredNodes.length-1)),this.filteredNodes.length>0&&(this.lastSelectedId=this.filteredNodes[this.selectedIndex]?.node.entry.id??this.lastSelectedId)}recalculateVisualStructure(){if(this.filteredNodes.length===0)return;let visibleIds=new Set(this.filteredNodes.map(n=>n.node.entry.id)),entryMap=new Map;for(let flatNode of this.flatNodes)entryMap.set(flatNode.node.entry.id,flatNode);let findVisibleAncestor=nodeId=>{let currentId=entryMap.get(nodeId)?.node.entry.parentId??null;for(;currentId!==null;){if(visibleIds.has(currentId))return currentId;currentId=entryMap.get(currentId)?.node.entry.parentId??null}return null},visibleParent=new Map,visibleChildren=new Map;visibleChildren.set(null,[]);for(let flatNode of this.filteredNodes){let nodeId=flatNode.node.entry.id,ancestorId=findVisibleAncestor(nodeId);visibleParent.set(nodeId,ancestorId),visibleChildren.has(ancestorId)||visibleChildren.set(ancestorId,[]),visibleChildren.get(ancestorId).push(nodeId)}let visibleRootIds=visibleChildren.get(null);this.multipleRoots=visibleRootIds.length>1;let filteredNodeMap=new Map;for(let flatNode of this.filteredNodes)filteredNodeMap.set(flatNode.node.entry.id,flatNode);let stack=[];for(let i=visibleRootIds.length-1;i>=0;i--){let isLast=i===visibleRootIds.length-1;stack.push([visibleRootIds[i],this.multipleRoots?1:0,this.multipleRoots,this.multipleRoots,isLast,[],this.multipleRoots])}for(;stack.length>0;){let[nodeId,indent,justBranched,showConnector,isLast,gutters,isVirtualRootChild]=stack.pop(),flatNode=filteredNodeMap.get(nodeId);if(!flatNode)continue;flatNode.indent=indent,flatNode.showConnector=showConnector,flatNode.isLast=isLast,flatNode.gutters=gutters,flatNode.isVirtualRootChild=isVirtualRootChild;let children=visibleChildren.get(nodeId)||[],multipleChildren=children.length>1,childIndent;multipleChildren||justBranched&&indent>0?childIndent=indent+1:childIndent=indent;let connectorDisplayed=showConnector&&!isVirtualRootChild,currentDisplayIndent=this.multipleRoots?Math.max(0,indent-1):indent,connectorPosition=Math.max(0,currentDisplayIndent-1),childGutters=connectorDisplayed?[...gutters,{position:connectorPosition,show:!isLast}]:gutters;for(let i=children.length-1;i>=0;i--){let childIsLast=i===children.length-1;stack.push([children[i],childIndent,multipleChildren,multipleChildren,childIsLast,childGutters,!1])}}this.visibleParentMap=visibleParent,this.visibleChildrenMap=visibleChildren}getSearchableText(node){let entry=node.entry,parts=[];switch(node.label&&parts.push(node.label),entry.type){case"message":{let msg=entry.message;if(parts.push(msg.role),"content"in msg&&msg.content&&parts.push(this.extractContent(msg.content)),msg.role==="bashExecution"){let bashMsg=msg;bashMsg.command&&parts.push(bashMsg.command)}break}case"custom_message":{parts.push(entry.customType),typeof entry.content=="string"?parts.push(entry.content):parts.push(this.extractContent(entry.content));break}case"compaction":parts.push("compaction");break;case"branch_summary":parts.push("branch summary",entry.summary);break;case"session_info":parts.push("title"),entry.name&&parts.push(entry.name);break;case"model_change":parts.push("model",entry.modelId);break;case"thinking_level_change":parts.push("thinking",entry.thinkingLevel);break;case"custom":parts.push("custom",entry.customType);break;case"context_edit":parts.push("context edit",entry.replacement===null?"omit":"replace",entry.targetId);break;case"label":parts.push("label",entry.label??"");break}return parts.join(" ")}invalidate(){}getSearchQuery(){return this.searchQuery}getSelectedNode(){return this.filteredNodes[this.selectedIndex]?.node}copySelected(){let node=this.getSelectedNode();this.onCopy?.(node?this.getEntryCopyText(node):void 0)}updateNodeLabel(entryId,label,labelTimestamp){for(let flatNode of this.flatNodes)if(flatNode.node.entry.id===entryId){flatNode.node.label=label,flatNode.node.labelTimestamp=label?labelTimestamp??new Date().toISOString():void 0;break}}getStatusLabels(){let labels="";switch(this.filterMode){case"no-tools":labels+=" [no-tools]";break;case"user-only":labels+=" [user]";break;case"labeled-only":labels+=" [labeled]";break;case"all":labels+=" [all]";break}return this.showLabelTimestamps&&(labels+=" [+label time]"),labels}render(width){let lines=[];if(this.filteredNodes.length===0)return lines.push(truncateToWidth(theme.fg("muted"," No entries found"),width)),lines.push(truncateToWidth(theme.fg("muted",` (0/0)${this.getStatusLabels()}`),width)),lines;let startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisibleLines/2),this.filteredNodes.length-this.maxVisibleLines)),endIndex=Math.min(startIndex+this.maxVisibleLines,this.filteredNodes.length),renderedRows=[];for(let i=startIndex;i<endIndex;i++){let flatNode=this.filteredNodes[i],entry=flatNode.node.entry,isSelected2=i===this.selectedIndex,cursor=isSelected2?theme.fg("accent","\u203A "):" ",displayIndent=this.multipleRoots?Math.max(0,flatNode.indent-1):flatNode.indent,connector=flatNode.showConnector&&!flatNode.isVirtualRootChild?flatNode.isLast?"\u2514\u2500 ":"\u251C\u2500 ":"",connectorPosition=connector?displayIndent-1:-1,totalChars=displayIndent*3,prefixChars=[],isFolded=this.foldedNodes.has(entry.id);for(let i2=0;i2<totalChars;i2++){let level=Math.floor(i2/3),posInLevel=i2%3,gutter2=flatNode.gutters.find(g=>g.position===level);if(gutter2)posInLevel===0?prefixChars.push(gutter2.show?"\u2502":" "):prefixChars.push(" ");else if(connector&&level===connectorPosition)if(posInLevel===0)prefixChars.push(flatNode.isLast?"\u2514":"\u251C");else if(posInLevel===1){let foldable=this.isFoldable(entry.id);prefixChars.push(isFolded?"\u229E":foldable?"\u229F":"\u2500")}else prefixChars.push(" ");else prefixChars.push(" ")}let prefix=prefixChars.join(""),showsFoldInConnector=flatNode.showConnector&&!flatNode.isVirtualRootChild,foldMarker=isFolded&&!showsFoldInConnector?theme.fg("accent","\u229E "):"",pathMarker=this.activePathIds.has(entry.id)?theme.fg("accent","\u2022 "):"",label=flatNode.node.label?theme.fg("warning",`[${flatNode.node.label}] `):"",labelTimestamp=this.showLabelTimestamps&&flatNode.node.label&&flatNode.node.labelTimestamp?theme.fg("muted",`${this.formatLabelTimestamp(flatNode.node.labelTimestamp)} `):"",content=this.getEntryDisplayText(flatNode.node,isSelected2),prefixPart=theme.fg("dim",prefix)+foldMarker+pathMarker,anchorCol=visibleWidth(prefixPart),gutter=cursor,body=prefixPart+label+labelTimestamp+content;isSelected2&&(gutter=theme.bg("selectedBg",gutter),body=theme.bg("selectedBg",body)),renderedRows.push({gutter,body,anchorCol,bodyWidth:visibleWidth(body),isSelected:isSelected2})}return lines.push(...renderHorizontalViewport(renderedRows,width)),lines.push(truncateToWidth(theme.fg("muted",` (${this.selectedIndex+1}/${this.filteredNodes.length})${this.getStatusLabels()}`),width)),lines}getEntryDisplayText(node,isSelected2){let entry=node.entry,result2,normalize2=s=>s.replace(/[\n\t]/g," ").trim();switch(entry.type){case"message":{let msg=entry.message,role=msg.role;if(role==="user"){let msgWithContent=msg,content=normalize2(this.extractContent(msgWithContent.content));result2=theme.fg("accent","user: ")+content}else if(role==="assistant"){let msgWithContent=msg,textContent=normalize2(this.extractContent(msgWithContent.content));if(textContent)result2=theme.fg("success","assistant: ")+textContent;else if(msgWithContent.stopReason==="aborted")result2=theme.fg("success","assistant: ")+theme.fg("muted","(aborted)");else if(msgWithContent.errorMessage){let errMsg=normalize2(msgWithContent.errorMessage).slice(0,80);result2=theme.fg("success","assistant: ")+theme.fg("error",errMsg)}else result2=theme.fg("success","assistant: ")+theme.fg("muted","(no content)")}else if(role==="toolResult"){let toolMsg=msg,toolCall=toolMsg.toolCallId?this.toolCallMap.get(toolMsg.toolCallId):void 0;toolCall?result2=theme.fg("muted",this.formatToolCall(toolCall.name,toolCall.arguments)):result2=theme.fg("muted",`[${toolMsg.toolName??"tool"}]`)}else if(role==="bashExecution"){let bashMsg=msg;result2=theme.fg("dim",`[bash]: ${normalize2(bashMsg.command??"")}`)}else result2=theme.fg("dim",`[${role}]`);break}case"custom_message":{let content=typeof entry.content=="string"?entry.content:entry.content.filter(c=>c.type==="text").map(c=>c.text).join("");result2=theme.fg("customMessageLabel",`[${entry.customType}]: `)+normalize2(content);break}case"compaction":{let tokens2=Math.round(entry.tokensBefore/1e3);result2=theme.fg("borderAccent",`[compaction: ${tokens2}k tokens]`);break}case"branch_summary":result2=theme.fg("warning","[branch summary]: ")+normalize2(entry.summary);break;case"model_change":result2=theme.fg("dim",`[model: ${entry.modelId}]`);break;case"thinking_level_change":result2=theme.fg("dim",`[thinking: ${entry.thinkingLevel}]`);break;case"custom":result2=theme.fg("dim",`[custom: ${entry.customType}]`);break;case"context_edit":result2=theme.fg("dim",`[context ${entry.replacement===null?"omit":"replace"}: ${entry.targetId}]`);break;case"label":result2=theme.fg("dim",`[label: ${entry.label??"(cleared)"}]`);break;case"session_info":result2=entry.name?[theme.fg("dim","[title: "),theme.fg("dim",entry.name),theme.fg("dim","]")].join(""):[theme.fg("dim","[title: "),theme.italic(theme.fg("dim","empty")),theme.fg("dim","]")].join("");break;default:result2=""}return isSelected2?theme.bold(result2):result2}formatLabelTimestamp(timestamp){let date=new Date(timestamp),now=new Date,hours=date.getHours().toString().padStart(2,"0"),minutes=date.getMinutes().toString().padStart(2,"0"),time2=`${hours}:${minutes}`;if(date.getFullYear()===now.getFullYear()&&date.getMonth()===now.getMonth()&&date.getDate()===now.getDate())return time2;let month=date.getMonth()+1,day=date.getDate();return date.getFullYear()===now.getFullYear()?`${month}/${day} ${time2}`:`${date.getFullYear().toString().slice(-2)}/${month}/${day} ${time2}`}extractContent(content){return this.extractFullContent(content).slice(0,200)}extractFullContent(content){if(typeof content=="string")return content;if(!Array.isArray(content))return"";let result2="";for(let block of content)typeof block=="object"&&block!==null&&"type"in block&&block.type==="text"&&(result2+=block.text);return result2}getEntryCopyText(node){let entry=node.entry,text2;switch(entry.type){case"message":entry.message.role==="bashExecution"?text2=entry.message.command:"content"in entry.message&&(text2=this.extractFullContent(entry.message.content),!text2&&entry.message.role==="assistant"&&(text2=entry.message.errorMessage));break;case"custom_message":text2=this.extractFullContent(entry.content);break;case"compaction":text2=entry.summary;break;case"branch_summary":text2=entry.summary;break}return text2?.trim()?text2:void 0}hasTextContent(content){if(typeof content=="string")return content.trim().length>0;if(Array.isArray(content)){for(let c of content)if(typeof c=="object"&&c!==null&&"type"in c&&c.type==="text"){let text2=c.text;if(text2&&text2.trim().length>0)return!0}}return!1}formatToolCall(name,args){let shortenPath3=p=>{let home=process.env.HOME||process.env.USERPROFILE||"";return home&&p.startsWith(home)?`~${p.slice(home.length)}`:p};switch(name){case"read":{let path14=shortenPath3(String(args.path||args.file_path||"")),offset=args.offset,limit=args.limit,display=path14;if(offset!==void 0||limit!==void 0){let start=offset??1,end=limit!==void 0?start+limit-1:"";display+=`:${start}${end?`-${end}`:""}`}return`[read: ${display}]`}case"write":return`[write: ${shortenPath3(String(args.path||args.file_path||""))}]`;case"edit":return`[edit: ${shortenPath3(String(args.path||args.file_path||""))}]`;case"bash":{let rawCmd=String(args.command||"");return`[bash: ${rawCmd.replace(/[\n\t]/g," ").trim().slice(0,50)}${rawCmd.length>50?"...":""}]`}case"grep":{let pattern=String(args.pattern||""),path14=shortenPath3(String(args.path||"."));return`[grep: /${pattern}/ in ${path14}]`}case"find":{let pattern=String(args.pattern||""),path14=shortenPath3(String(args.path||"."));return`[find: ${pattern} in ${path14}]`}case"ls":return`[ls: ${shortenPath3(String(args.path||"."))}]`;default:{let argsStr=JSON.stringify(args).slice(0,40);return`[${name}: ${argsStr}${JSON.stringify(args).length>40?"...":""}]`}}}handleInput(keyData){let kb=getKeybindings();if(kb.matches(keyData,"tui.select.up"))this.selectedIndex=this.selectedIndex===0?this.filteredNodes.length-1:this.selectedIndex-1;else if(kb.matches(keyData,"tui.select.down"))this.selectedIndex=this.selectedIndex===this.filteredNodes.length-1?0:this.selectedIndex+1;else if(kb.matches(keyData,"app.tree.foldOrUp")){let currentId=this.filteredNodes[this.selectedIndex]?.node.entry.id;currentId&&this.isFoldable(currentId)&&!this.foldedNodes.has(currentId)?(this.foldedNodes.add(currentId),this.applyFilter()):this.selectedIndex=this.findBranchSegmentStart("up")}else if(kb.matches(keyData,"app.tree.unfoldOrDown")){let currentId=this.filteredNodes[this.selectedIndex]?.node.entry.id;currentId&&this.foldedNodes.has(currentId)?(this.foldedNodes.delete(currentId),this.applyFilter()):this.selectedIndex=this.findBranchSegmentStart("down")}else if(kb.matches(keyData,"tui.editor.cursorLeft")||kb.matches(keyData,"tui.select.pageUp"))this.selectedIndex=Math.max(0,this.selectedIndex-this.maxVisibleLines);else if(kb.matches(keyData,"tui.editor.cursorRight")||kb.matches(keyData,"tui.select.pageDown"))this.selectedIndex=Math.min(this.filteredNodes.length-1,this.selectedIndex+this.maxVisibleLines);else if(kb.matches(keyData,"tui.select.confirm")){let selected=this.filteredNodes[this.selectedIndex];selected&&this.onSelect&&this.onSelect(selected.node.entry.id)}else if(kb.matches(keyData,"app.message.copy"))this.copySelected();else if(kb.matches(keyData,"tui.select.cancel"))this.searchQuery?(this.searchQuery="",this.foldedNodes.clear(),this.applyFilter()):this.onCancel?.();else if(kb.matches(keyData,"app.tree.filter.default"))this.filterMode="default",this.foldedNodes.clear(),this.applyFilter();else if(kb.matches(keyData,"app.tree.filter.noTools"))this.filterMode=this.filterMode==="no-tools"?"default":"no-tools",this.foldedNodes.clear(),this.applyFilter();else if(kb.matches(keyData,"app.tree.filter.userOnly"))this.filterMode=this.filterMode==="user-only"?"default":"user-only",this.foldedNodes.clear(),this.applyFilter();else if(kb.matches(keyData,"app.tree.filter.labeledOnly"))this.filterMode=this.filterMode==="labeled-only"?"default":"labeled-only",this.foldedNodes.clear(),this.applyFilter();else if(kb.matches(keyData,"app.tree.filter.all"))this.filterMode=this.filterMode==="all"?"default":"all",this.foldedNodes.clear(),this.applyFilter();else if(kb.matches(keyData,"app.tree.filter.cycleBackward")){let modes=["default","no-tools","user-only","labeled-only","all"],currentIndex=modes.indexOf(this.filterMode);this.filterMode=modes[(currentIndex-1+modes.length)%modes.length],this.foldedNodes.clear(),this.applyFilter()}else if(kb.matches(keyData,"app.tree.filter.cycleForward")){let modes=["default","no-tools","user-only","labeled-only","all"],currentIndex=modes.indexOf(this.filterMode);this.filterMode=modes[(currentIndex+1)%modes.length],this.foldedNodes.clear(),this.applyFilter()}else if(kb.matches(keyData,"tui.editor.deleteCharBackward"))this.searchQuery.length>0&&(this.searchQuery=this.searchQuery.slice(0,-1),this.foldedNodes.clear(),this.applyFilter());else if(kb.matches(keyData,"app.tree.editLabel")){let selected=this.filteredNodes[this.selectedIndex];selected&&this.onLabelEdit&&this.onLabelEdit(selected.node.entry.id,selected.node.label)}else kb.matches(keyData,"app.tree.toggleLabelTimestamp")?this.showLabelTimestamps=!this.showLabelTimestamps:![...keyData].some(ch=>{let code=ch.charCodeAt(0);return code<32||code===127||code>=128&&code<=159})&&keyData.length>0&&(this.searchQuery+=keyData,this.foldedNodes.clear(),this.applyFilter())}isFoldable(entryId){let children=this.visibleChildrenMap.get(entryId);if(!children||children.length===0)return!1;let parentId=this.visibleParentMap.get(entryId);if(parentId==null)return!0;let siblings=this.visibleChildrenMap.get(parentId);return siblings!==void 0&&siblings.length>1}findBranchSegmentStart(direction){let selectedId=this.filteredNodes[this.selectedIndex]?.node.entry.id;if(!selectedId)return this.selectedIndex;let indexByEntryId=new Map(this.filteredNodes.map((node,i)=>[node.node.entry.id,i])),currentId=selectedId;if(direction==="down")for(;;){let children=this.visibleChildrenMap.get(currentId)??[];if(children.length===0)return indexByEntryId.get(currentId);if(children.length>1)return indexByEntryId.get(children[0]);currentId=children[0]}for(;;){let parentId=this.visibleParentMap.get(currentId)??null;if(parentId===null)return indexByEntryId.get(currentId);if((this.visibleChildrenMap.get(parentId)??[]).length>1){let segmentStart=indexByEntryId.get(currentId);if(segmentStart<this.selectedIndex)return segmentStart}currentId=parentId}}},SearchLine=class{constructor(treeList){this.treeList=treeList}invalidate(){}render(width){let query=this.treeList.getSearchQuery();return query?[truncateToWidth(` ${theme.fg("muted","Type to search:")} ${theme.fg("accent",query)}`,width)]:[truncateToWidth(` ${theme.fg("muted","Type to search:")}`,width)]}handleInput(_keyData){}},TreeHelp=class{invalidate(){}render(width){let items=TREE_HELP_ITEMS.map(({keys,label,labelFirst})=>{let text2=formatHelpKeys(keys);return text2?labelFirst?`${label} ${text2}`:`${text2} ${label}`:label}),availableWidth=Math.max(1,width),indent=" ",separator=" \xB7 ",lines=[],currentLine="";for(let item of items){let candidate=currentLine?`${currentLine}${separator}${item}`:visibleWidth(`${indent}${item}`)<=availableWidth?`${indent}${item}`:item;if(!currentLine||visibleWidth(candidate)<=availableWidth){currentLine=candidate;continue}lines.push(...wrapTextWithAnsi(currentLine.trimEnd(),availableWidth)),currentLine=visibleWidth(`${indent}${item}`)<=availableWidth?`${indent}${item}`:item}return currentLine&&lines.push(...wrapTextWithAnsi(currentLine.trimEnd(),availableWidth)),lines.map(line=>theme.fg("muted",line))}},TREE_HELP_ITEMS=[{keys:["tui.select.up","tui.select.down"],label:"move"},{keys:["tui.editor.cursorLeft","tui.editor.cursorRight"],label:"page"},{keys:["app.tree.foldOrUp","app.tree.unfoldOrDown"],label:"branch"},{keys:["app.message.copy"],label:"copy"},{keys:["app.tree.editLabel"],label:"label"},{keys:["app.tree.toggleLabelTimestamp"],label:"label time"},{keys:["app.tree.filter.default","app.tree.filter.noTools","app.tree.filter.userOnly","app.tree.filter.labeledOnly","app.tree.filter.all"],label:"filters",labelFirst:!0},{keys:["app.tree.filter.cycleForward","app.tree.filter.cycleBackward"],label:"cycle",labelFirst:!0}];function formatHelpKeys(keybindings){let keys=[];for(let keybinding of keybindings){let key=getKeybindings().getKeys(keybinding)[0];key!==void 0&&keys.push(key)}return keys.length===0?"":formatKeyText(compactRawKeys(keys)).replace(/\bpageUp\b/g,"pgup").replace(/\bpageDown\b/g,"pgdn").replace(/\bup\b/g,"\u2191").replace(/\bdown\b/g,"\u2193").replace(/\bleft\b/g,"\u2190").replace(/\bright\b/g,"\u2192")}function compactRawKeys(keys){if(keys.length===1)return keys[0];let parts=keys.map(key=>{let separatorIndex=key.lastIndexOf("+");return separatorIndex===-1?{prefix:"",suffix:key}:{prefix:key.slice(0,separatorIndex+1),suffix:key.slice(separatorIndex+1)}}),prefix=parts[0].prefix;return prefix&&parts.every(part=>part.prefix===prefix)?`${prefix}${parts.map(part=>part.suffix).join("/")}`:keys.join("/")}var LabelInput=class{get focused(){return this._focused}set focused(value){this._focused=value,this.input.focused=value}constructor(entryId,currentLabel){this._focused=!1,this.entryId=entryId,this.input=new Input,currentLabel&&this.input.setValue(currentLabel)}invalidate(){}render(width){let lines=[],availableWidth=width-2;return lines.push(truncateToWidth(` ${theme.fg("muted","Label (empty to remove):")}`,width)),lines.push(...this.input.render(availableWidth).map(line=>truncateToWidth(` ${line}`,width))),lines.push(truncateToWidth(` ${keyHint("tui.select.confirm","save")} ${keyHint("tui.select.cancel","cancel")}`,width)),lines}handleInput(keyData){let kb=getKeybindings();if(kb.matches(keyData,"tui.select.confirm")){let value=this.input.getValue().trim();this.onSubmit?.(this.entryId,value||void 0)}else kb.matches(keyData,"tui.select.cancel")?this.onCancel?.():this.input.handleInput(keyData)}},TreeSelectorComponent=class extends Container{get focused(){return this._focused}set focused(value){this._focused=value,this.labelInput&&(this.labelInput.focused=value)}constructor(tree,currentLeafId,terminalHeight,onSelect,onCancel,onLabelChange,initialSelectedId,initialFilterMode){super(),this.labelInput=null,this._focused=!1,this.onLabelChangeCallback=onLabelChange;let maxVisibleLines=Math.max(5,Math.floor(terminalHeight/2));this.treeList=new TreeList(tree,currentLeafId,maxVisibleLines,initialSelectedId,initialFilterMode),this.treeList.onSelect=onSelect,this.treeList.onCancel=onCancel,this.treeList.onCopy=text2=>this.onCopy?.(text2),this.treeList.onLabelEdit=(entryId,currentLabel)=>this.showLabelInput(entryId,currentLabel),this.treeContainer=new Container,this.treeContainer.addChild(this.treeList),this.labelInputContainer=new Container,this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),this.addChild(new Text(theme.bold(" Session Tree"),1,0)),this.addChild(new TreeHelp),this.addChild(new SearchLine(this.treeList)),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(this.treeContainer),this.addChild(this.labelInputContainer),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),tree.length===0&&setTimeout(()=>onCancel(),100)}showLabelInput(entryId,currentLabel){this.labelInput=new LabelInput(entryId,currentLabel),this.labelInput.onSubmit=(id,label)=>{this.treeList.updateNodeLabel(id,label),this.onLabelChangeCallback?.(id,label),this.hideLabelInput()},this.labelInput.onCancel=()=>this.hideLabelInput(),this.labelInput.focused=this._focused,this.treeContainer.clear(),this.labelInputContainer.clear(),this.labelInputContainer.addChild(this.labelInput)}hideLabelInput(){this.labelInput=null,this.labelInputContainer.clear(),this.treeContainer.clear(),this.treeContainer.addChild(this.treeList)}handleInput(keyData){this.labelInput?this.labelInput.handleInput(keyData):this.treeList.handleInput(keyData)}getTreeList(){return this.treeList}};var OSC133_ZONE_START2="\x1B]133;A\x07",OSC133_ZONE_END2="\x1B]133;B\x07",OSC133_ZONE_FINAL2="\x1B]133;C\x07",UserMessageComponent=class extends Container{constructor(text2,markdownTheme=getMarkdownTheme(),outputPad=1,markdownTransformers=[]){super(),this.text=text2,this.markdownTheme=markdownTheme,this.outputPad=outputPad,this.markdownTransformers=markdownTransformers,this.rebuild()}setOutputPad(padding){this.outputPad=padding,this.rebuild()}rebuild(){this.clear(),this.addChild(new Markdown(this.text,this.outputPad,1,this.markdownTheme,{color:content=>theme.fg("userMessageText",content),bgColor:content=>theme.bg("userMessageBg",content)},{preserveOrderedListMarkers:!0,preserveBackslashEscapes:!0,transform:createMarkdownTransform("user",!1,this.markdownTransformers)}))}render(width){let lines=super.render(width);return lines.length===0||(lines[0]=OSC133_ZONE_START2+lines[0],lines[lines.length-1]=OSC133_ZONE_END2+OSC133_ZONE_FINAL2+lines[lines.length-1]),lines}};var UserMessageList=class{constructor(messages,initialSelectedId){this.messages=[],this.selectedIndex=0,this.maxVisible=10,this.messages=messages;let initialIndex=initialSelectedId?messages.findIndex(message=>message.id===initialSelectedId):-1;this.selectedIndex=initialIndex>=0?initialIndex:Math.max(0,messages.length-1)}invalidate(){}render(width){let lines=[];if(this.messages.length===0)return lines.push(theme.fg("muted"," No user messages found")),lines;let startIndex=Math.max(0,Math.min(this.selectedIndex-Math.floor(this.maxVisible/2),this.messages.length-this.maxVisible)),endIndex=Math.min(startIndex+this.maxVisible,this.messages.length);for(let i=startIndex;i<endIndex;i++){let message=this.messages[i],isSelected2=i===this.selectedIndex,normalizedMessage=message.text.replace(/\n/g," ").trim(),cursor=isSelected2?theme.fg("accent","\u203A "):" ",maxMsgWidth=width-2,truncatedMsg=truncateToWidth(normalizedMessage,maxMsgWidth),messageLine=cursor+(isSelected2?theme.bold(truncatedMsg):truncatedMsg);lines.push(messageLine);let metadata=` Message ${i+1} of ${this.messages.length}`,metadataLine=theme.fg("muted",metadata);lines.push(metadataLine),lines.push("")}if(startIndex>0||endIndex<this.messages.length){let scrollInfo=theme.fg("muted",` (${this.selectedIndex+1}/${this.messages.length})`);lines.push(scrollInfo)}return lines}handleInput(keyData){let kb=getKeybindings();if(kb.matches(keyData,"tui.select.up"))this.selectedIndex=this.selectedIndex===0?this.messages.length-1:this.selectedIndex-1;else if(kb.matches(keyData,"tui.select.down"))this.selectedIndex=this.selectedIndex===this.messages.length-1?0:this.selectedIndex+1;else if(kb.matches(keyData,"tui.select.confirm")){let selected=this.messages[this.selectedIndex];selected&&this.onSelect&&this.onSelect(selected.id)}else kb.matches(keyData,"tui.select.cancel")&&this.onCancel&&this.onCancel()}},UserMessageSelectorComponent=class extends Container{constructor(messages,onSelect,onCancel,initialSelectedId){super(),this.addChild(new Spacer(1)),this.addChild(new Text(theme.bold("Fork from Message"),1,0)),this.addChild(new Text(theme.fg("muted","Select a user message to copy the active path up to that point into a new session"),1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.messageList=new UserMessageList(messages,initialSelectedId),this.messageList.onSelect=onSelect,this.messageList.onCancel=onCancel,this.addChild(this.messageList),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),messages.length===0&&setTimeout(()=>onCancel(),100)}getMessageList(){return this.messageList}};function createAllToolRenderers(){return{tasks:{renderCall:(args,theme2,context)=>renderTasksCall(args,theme2,context),renderResult:renderTasksResult},read:readRenderers,bash:createShellRenderers({name:"bash",prompt:"$"}),powershell:createShellRenderers({name:"powershell",prompt:"PS>"}),edit:editRenderers,write:writeRenderers,grep:grepRenderers,find:findRenderers,ls:lsRenderers}}function withBuiltInRenderers(toolName,definition){let builtIn=createAllToolRenderers()[toolName];return definition?builtIn?{...definition,renderCall:definition.renderCall??builtIn.renderCall,renderResult:definition.renderResult??builtIn.renderResult}:definition:builtIn}function formatFallbackArgs(args){if(!args||typeof args!="object")return"";let entries=Object.entries(args);if(entries.length===0)return"";let summary=entries.map(([key,value])=>{try{return`${key}=${JSON.stringify(value)??String(value)}`}catch{return`${key}=${String(value)}`}}).join(" ").replace(/\s+/g," ");return truncateToWidth(summary,toolStyle.fallbackArgsWidth,"...")}function createCallFallback(toolName,args,expanded=!1){if(expanded)return new Text(formatToolCallWithArgs(toolName,args,theme,!0),0,0);let summary=formatFallbackArgs(args),suffix=summary?theme.fg("dim",`(${summary})`):"";return new Text(`${theme.fg("toolTitle",theme.bold(toolName))}${suffix}`,0,0)}var FallbackResultComponent=class{constructor(output,expanded){this.output=output,this.expanded=expanded}render(width){let styledOutput=theme.fg("toolOutput",this.output);if(this.expanded)return new Text(styledOutput,0,0).render(width);let preview=truncateToVisualLines(styledOutput,toolStyle.collapsed.fallbackLines,width);if(preview.skippedCount<=0)return preview.visualLines;let noun=preview.skippedCount===1?"line":"lines",hint=theme.fg("muted",`... (${preview.skippedCount} earlier ${noun},`)+` ${keyHint("app.tools.expand","to expand")}${theme.fg("muted",")")}`;return[truncateToWidth(hint,width,"..."),...preview.visualLines]}invalidate(){}};var builtInRenderers,ToolExecutionComponent=class extends Container{constructor(toolName,toolCallId,args,options={},toolDefinition,ui,cwd){super(),this.selfRenderHeight=0,this.rendererState={},this.imageComponents=[],this.imageSources=[],this.imageSpacers=[],this.expanded=!1,this.isPartial=!0,this.executionStarted=!1,this.argsComplete=!1,this.hideComponent=!1,this.disposed=!1,this.toolName=toolName,this.toolCallId=toolCallId,this.args=args,this.toolDefinition=toolDefinition,this.showImages=options.showImages??!0,this.imageWidthCells=options.imageWidthCells??60,this.ui=ui,this.cwd=cwd,this.gap=new Spacer(toolStyle.gap.afterOther),this.addChild(this.gap),this.contentContainer=new Container,this.selfRenderContainer=new Container,this.addChild(this.isSelfRendered()?this.selfRenderContainer:this.contentContainer),this.updateDisplay()}getCallRenderer(){return this.toolDefinition?.renderCall}getResultRenderer(){return this.toolDefinition?.renderResult}isSelfRendered(){return this.toolDefinition?.renderShell==="self"}status(){return toolStatus({isPartial:this.isPartial,isError:this.result?.isError??!1})}setLeadingGap(lines){this.gap.setLines(lines)}getRenderContext(lastComponent){return{args:this.args,toolCallId:this.toolCallId,invalidate:()=>{this.disposed||(this.invalidate(),this.ui.requestRender())},lastComponent,state:this.rendererState,cwd:this.cwd,executionStarted:this.executionStarted,argsComplete:this.argsComplete,isPartial:this.isPartial,expanded:this.expanded,showImages:this.showImages,isError:this.result?.isError??!1,result:this.result?{content:this.result.content,details:this.result.details}:void 0}}frame(component,kind){return new FramedComponent(component,kind,()=>toolMarkerColor(this.status()))}createResultFallback(){let output=this.getTextOutput();if(output)return new FallbackResultComponent(output,this.expanded)}hidesCollapsedResult(){if(this.expanded||this.result?.isError||!toolStyle.collapsed.headerOnly.has(this.toolName))return!1;builtInRenderers??=createAllToolRenderers();let builtIn=builtInRenderers[this.toolName];return builtIn?.renderResult!==void 0&&builtIn.renderResult===this.getResultRenderer()}createResultRegion(component){return new MouseRegion(component,event=>{if(!(!this.result||event.type!=="click"||event.button!=="left"))return this.setExpanded(!this.expanded),{handled:!0}})}updateArgs(args){this.args=args,this.updateDisplay()}markExecutionStarted(){this.disposed||(this.executionStarted=!0,this.updateDisplay(),this.ui.requestRender())}setArgsComplete(){this.argsComplete=!0,this.updateDisplay(),this.ui.requestRender()}updateResult(result2,isPartial=!1){this.result=result2,this.isPartial=isPartial,this.updateDisplay()}setExpanded(expanded){this.expanded=expanded,this.updateDisplay()}setShowImages(show){this.showImages=show,this.updateDisplay()}setImageWidthCells(width){this.imageWidthCells=Math.max(1,Math.floor(width)),this.updateDisplay()}invalidate(){super.invalidate(),this.updateDisplay()}render(width){if(this.hideComponent)return[];if(this.isSelfRendered()){let contentLines=this.selfRenderContainer.render(width);if(this.selfRenderHeight=contentLines.length,contentLines.length===0&&this.imageComponents.length===0)return[];let lines=[];contentLines.length>0&&(lines.push(""),lines.push(...contentLines));for(let i=0;i<this.imageComponents.length;i++){let spacer=this.imageSpacers[i];spacer&&lines.push(...spacer.render(width));let imageComponent=this.imageComponents[i];imageComponent&&lines.push(...imageComponent.render(width))}return lines}return super.render(width)}handleMouse(event){if(!this.isSelfRendered())return super.handleMouse(event);if(!(event.y<=0||event.y>this.selfRenderHeight))return this.selfRenderContainer.handleMouse({...event,y:event.y-1,height:this.selfRenderHeight})}updateDisplay(){let hasContent=!1;this.hideComponent=!1;let selfRendered=this.isSelfRendered(),renderContainer=selfRendered?this.selfRenderContainer:this.contentContainer;renderContainer.clear();let addCall=component=>{renderContainer.addChild(selfRendered?component:this.createResultRegion(this.frame(component,"header"))),hasContent=!0},addResult=component=>{renderContainer.addChild(selfRendered?component:this.createResultRegion(this.frame(component,"body"))),hasContent=!0},callRenderer=this.getCallRenderer();if(!callRenderer)addCall(createCallFallback(this.toolName,this.args,this.expanded));else try{let component=callRenderer(this.args,theme,this.getRenderContext(this.callRendererComponent));this.callRendererComponent=component,addCall(component)}catch{this.callRendererComponent=void 0,addCall(createCallFallback(this.toolName,this.args,this.expanded))}if(this.result&&(selfRendered||!this.hidesCollapsedResult())){let resultRenderer=this.getResultRenderer();if(resultRenderer)try{let component=resultRenderer({content:this.result.content,details:this.result.details},{expanded:this.expanded,isPartial:this.isPartial},theme,this.getRenderContext(this.resultRendererComponent));this.resultRendererComponent=component,addResult(component)}catch{this.resultRendererComponent=void 0;let component=this.createResultFallback();component&&addResult(component)}else{let component=this.createResultFallback();component&&addResult(component)}}let previousImages=this.imageComponents,previousSources=this.imageSources;for(let img of this.imageComponents)this.removeChild(img);this.imageComponents=[],this.imageSources=[];for(let spacer of this.imageSpacers)this.removeChild(spacer);if(this.imageSpacers=[],this.result){let imageBlocks=this.result.content.filter(c=>c.type==="image"),caps=getCapabilities();for(let img of imageBlocks)if(caps.images&&this.showImages&&img.data&&img.mimeType){let spacer=new Spacer(1);this.addChild(spacer),this.imageSpacers.push(spacer);let source={data:img.data,mimeType:img.mimeType,widthCells:this.imageWidthCells},index3=this.imageComponents.length,previous=previousSources[index3],imageComponent=previous?.data===source.data&&previous.mimeType===source.mimeType&&previous.widthCells===source.widthCells?previousImages[index3]:new Image(source.data,source.mimeType,{fallbackColor:s=>theme.fg("toolOutput",s)},{maxWidthCells:source.widthCells});source.mimeType!=="image/png"&&ensurePngTranscoder(()=>{this.disposed||(this.invalidate(),this.ui.requestRender())}),this.imageComponents.push(imageComponent),this.imageSources.push(source),this.addChild(imageComponent)}}!hasContent&&this.imageComponents.length===0&&(this.hideComponent=!0)}getTextOutput(){return getTextOutput(this.result,this.showImages)}dispose(){this.disposed||(this.disposed=!0,this.rendererState.dispose?.())}};var TaskViewport=class{constructor(follow=!1){this.scroll=0,this.entries=[],this.height=1,this.start=0,this.follow=follow}layout(lines,width,height){this.height=Math.max(1,height),(lines!==this.wrapped?.lines||width!==this.wrapped.width)&&(this.wrapped={lines,width},this.entries=lines.flatMap((line,index3)=>{let column=0;return wrapTextWithAnsi(line,Math.max(1,width)).map(text2=>{let entry={text:text2,line:index3,column};return column+=visibleWidth(text2),entry})}));let offset=this.scroll;if(this.anchor){let anchor=this.anchor,first=this.entries.findIndex(entry=>entry.line===anchor.line);if(first>=0)for(offset=first;offset+1<this.entries.length&&this.entries[offset+1].line===anchor.line&&this.entries[offset+1].column<=anchor.column;)offset++}return this.start=this.follow?this.max:Math.min(offset,this.max),this.entries.slice(this.start,this.start+this.height).map(entry=>entry.text)}get max(){return Math.max(0,this.entries.length-this.height)}move(direction,page,tail2){this.scroll=Math.max(0,Math.min(this.max,this.start+direction*(page?this.height:1)));let entry=this.entries[this.scroll];this.anchor=entry?{line:entry.line,column:entry.column}:void 0,this.follow=tail2&&direction>0&&this.scroll===this.max}jump(bottom,tail2){this.scroll=bottom?this.max:0;let entry=this.entries[this.scroll];this.anchor=entry?{line:entry.line,column:entry.column}:void 0,this.follow=bottom&&tail2}get range(){return`${this.entries.length?this.start+1:0}\u2013${Math.min(this.start+this.height,this.entries.length)}/${this.entries.length}`}};var SHELLS={bash:{name:"Bash",language:"bash"},powershell:{name:"PowerShell",language:"powershell"}};function taskLines(task,read,theme2){let shell=SHELLS[task.kind],command=cleanTaskText(task.command??task.title),[first="",...rest]=shell?highlightCode(command,shell.language):command.split(`
|
|
1724
1724
|
`),info=[theme2.fg("accent",shell?.name??task.kind),`${task.command===void 0?"Title ":"Command "}${first}`,...rest,...task.commandTruncated?["[Saved command truncated.]"]:[],...task.cwd?[`Directory ${cleanTaskText(task.cwd)}`]:[],...task.outputPath?[`Log ${cleanTaskText(task.outputPath)}`]:[],...task.exitCode!==void 0?[`Exit ${task.exitCode??"signal"}`]:[]],saved=task.result?.content.filter(block=>block.type==="text").map(block=>block.text).join(`
|
|
1725
1725
|
`),empty=task.status==="completed"?"Completed with no output.":isTaskTerminal(task.status)?"No saved output.":"No output yet.",output=cleanTaskText((read?read.text:saved)||empty).split(`
|
|
1726
|
-
`).map(line=>theme2.fg("toolOutput",line));return read?.readError&&output.unshift(theme2.fg("warning","Log unavailable; showing saved result.")),(!read||read.readError)&&task.resultTruncated&&output.push(theme2.fg("warning","Saved result truncated.")),{info,output}}var TaskInspector=class{constructor(options){this.positions=new Map,this.reading=!1,this.disposed=!1,this.options=options}get position(){let id=this.task?.id,position=id?this.positions.get(id):void 0;return position||(position={info:new TaskViewport,output:new TaskViewport(!0)},id&&this.positions.set(id,position)),position}select(task){if(!this.disposed){if(this.task?.id!==task?.id){let release2=task?this.options.host.retain(task.id):void 0,previous=this.release;this.release=release2,previous?.()}this.task=task}}prune(ids){for(let id of this.positions.keys())ids.has(id)||this.positions.delete(id)}invalidate(){this.cache=void 0}async refresh(){let task=this.task;if(this.disposed||!task||this.reading)return;let position=this.position;if(!(position.read&&(!position.output.follow||isTaskTerminal(position.read.task.status)))){this.reading=!0;try{let read=await this.options.host.read(task.id,{mode:"tail",bytes:49152});if(this.disposed||this.task?.id!==task.id||!position.output.follow&&position.read)return;position.read=read}catch(error){!this.disposed&&this.task?.id===task.id&&(position.output.follow||!position.read)&&(position.read={task,text:"",readError:`Cannot read output: ${cleanTaskText(String(error))}`,totalBytes:0,truncated:!1})}finally{this.reading=!1,this.disposed||this.options.requestRender(),!this.disposed&&this.task?.id!==task.id&&await this.refresh()}}}lines(tab){let task=this.task;if(!task)return[];let read=this.position.read;return(this.cache?.task!==task||this.cache.read!==read)&&(this.cache={task,read,lines:taskLines(task,read,this.options.theme)}),this.cache.lines[tab]}dispose(){this.disposed||(this.disposed=!0,this.release?.(),this.release=void 0,this.positions.clear())}};var pad=(text2,width)=>truncateToWidth(text2,Math.max(1,width),"\u2026",!0);function renderTasksLayout(options){let{width,height,theme:theme2,selection,inspector,list:list2,focus,keybindings}=options,hint=key=>keyLabel(key,{keybindings}),result2={hits:[],listWidth:0,listPageSize:1,lines:[]};if(width<1||height<1)return result2;if(width<60||height<14)return result2.lines=["Tasks","Terminal too small for /tasks. Resize to 60\xD714.",`${hint("tui.select.cancel")} close`].slice(0,height).map(line=>pad(line,width)),result2;let wide=width>=100,listWidth=wide?Math.min(42,Math.max(32,Math.floor(width*.32))):width,rightWidth=wide?width-listWidth-1:width,rightX=wide?listWidth+1:0,bodyHeight=height-5,hits=result2.hits;result2.listWidth=listWidth,result2.listPageSize=Math.max(1,Math.floor((bodyHeight-1)/2));let pane=(lines,size,active)=>{let border=text2=>theme2.fg(wide&&active?"borderAccent":"borderMuted",text2);return[border(`\u250C${"\u2500".repeat(size-2)}\u2510`),...lines.map(line=>border("\u2502")+pad(line,size-2)+border("\u2502")),border(`\u2514${"\u2500".repeat(size-2)}\u2518`)]},visible=list2.render(selection,theme2,listWidth-2,bodyHeight),listHeader=theme2.fg("text","Tasks"),searchLabel=`${hint("app.tasks.search")} find`;if(options.searchLine)listHeader=options.searchLine(listWidth-2);else{let x2=Math.max(6,listWidth-2-visibleWidth(searchLabel));listHeader+=" ".repeat(x2-5)+theme2.fg("dim",searchLabel),(wide||focus==="list")&&hits.push({x:x2+1,y:1,width:visibleWidth(searchLabel),key:"app.tasks.search"})}(wide||focus==="list")&&visible.forEach((row,index3)=>{row.taskId&&hits.push({x:1,y:2+index3,width:listWidth-2,taskId:row.taskId})});let left=[listHeader,...Array.from({length:bodyHeight},(_2,i)=>visible[i]?.text??""),theme2.fg("dim",list2.range)],task=inspector.task,tab=selection.state.tab,tabLabel=(id,label)=>theme2.style(label,{fg:"text",underline:tab===id}),right=[`${tabLabel("output","Output")} ${tabLabel("info","Details")}`];(wide||focus==="inspector")&&hits.push({x:rightX+1,y:1,width:6,tab:"output"},{x:rightX+9,y:1,width:7,tab:"info"});let content=[],reading="";if(task){wide||content.push(theme2.fg("text",cleanTaskText(firstCommandLine(task.command??task.title))),theme2.fg("muted",`${statusName(task.status)} \xB7 ${runtimeLabel(task)}`));let lines=inspector.lines(tab),position=inspector.position,read=position.read,diagnostics=[task.error,read?.readError].filter(text2=>!!text2).map(cleanTaskText);tab==="output"&&diagnostics.length&&content.push(theme2.fg("warning",diagnostics.join(" \xB7 ").replace(/\n/g," ")));let source=tab==="info"?[`Task ID ${task.id}`,`Status ${statusName(task.status)} \xB7 ${statusName(task.mode)} \xB7 ${runtimeLabel(task)}`,...diagnostics,...lines]:lines;content.push(...position[tab].layout(source,rightWidth-2,bodyHeight-content.length)),tab==="output"?(reading=position.output.follow?isTaskTerminal(task.status)?"Finished":"Live":isTaskTerminal(task.status)?`Finished \xB7 ${hint("app.tasks.follow")} load final output`:`Browsing \xB7 ${hint("app.tasks.follow")} follow output`,!position.output.follow&&(wide||focus==="inspector")&&hits.push({x:rightX+1,y:height-3,width:Math.min(rightWidth-2,visibleWidth(reading)),key:"app.tasks.follow"}),read?.truncated&&(reading+=` \xB7 Tail preview: ${formatSize(Buffer.byteLength(read.text))} of ${formatSize(read.totalBytes)}`)):tab==="info"&&(reading=`Details ${position.info.range}`)}else content.push(theme2.fg("muted","Select a task to inspect its result."));right.push(...Array.from({length:bodyHeight},(_2,i)=>content[i]??""),theme2.fg("dim",reading));let rightPane=pane(right,rightWidth,focus==="inspector"),panels=wide?pane(left,listWidth,focus==="list").map((line,i)=>`${line} ${rightPane[i]}`):pane(focus==="list"?left:right,width,!1),footer="",addHint=(key,label,target)=>{let text2=`${hint(key)} ${label}`,x2=visibleWidth(footer)+(footer?3:0);x2+visibleWidth(text2)>width||(footer+=(footer?" \xB7 ":"")+text2,target&&hits.push({x:x2,y:height-1,width:visibleWidth(text2),...target}))};if(options.help||options.pendingKill){hits.length=0;let body;if(options.help){let controls=[["app.tasks.nextFocus","Switch task list / inspector"],["app.tasks.previousFocus","Switch inspector / task list"],["app.tasks.previousTab","Output (inspector only)"],["app.tasks.nextTab","Details (inspector only)"],["tui.select.up","Previous task / scroll up"],["tui.select.down","Next task / scroll down"],["tui.select.pageUp","Page up in task list"],["tui.select.pageDown","Page down in task list"],["tui.editor.pageUp","Page up in inspector"],["tui.editor.pageDown","Page down in inspector"],["app.tasks.top","Top of list / content"],["app.tasks.bottom","Bottom of list / content"],["app.tasks.search","Locate a retained task; Enter chooses, Escape restores selection"],["app.tasks.follow","Follow latest / final output (Output only)"],["app.tasks.detachSelected","Move selected foreground task to background"],["app.tasks.kill","Request stop of selected whole task"],["app.tasks.confirmStop","Confirm stop"],["tui.select.cancel","Close current search, help or confirmation; otherwise close panel"]];body=[theme2.fg("text","Task controls"),...options.help.layout(controls.map(([key,label])=>hint(key).padEnd(14)+label),width-2,height-5),""],addHint("tui.select.up",`/ ${hint("tui.select.down")} scroll`),addHint("tui.select.cancel","back",{cancel:!0})}else{let target=selection.all.find(task2=>task2.id===options.pendingKill),command=wrapTextWithAnsi(cleanTaskText(target?.command??target?.title??options.pendingKill),width-2),preview=command.slice(0,height-8);preview.length<command.length&&(preview[preview.length-1]="\u2026 Full command in Details."),body=[theme2.fg("text","Stop task?"),"Stops the whole task, including its active work.",`Task ID: ${options.pendingKill}`,"",...preview],addHint("app.tasks.confirmStop","confirm",{key:"app.tasks.confirmStop"}),addHint("tui.select.cancel","cancel",{cancel:!0})}for(;body.length<height-3;)body.push("");panels=pane(body,width,!1)}else if(options.searchLine){for(let i=hits.length-1;i>=0;i--)hits[i].taskId||hits.splice(i,1);addHint("tui.select.up",`/ ${hint("tui.select.down")} choose`),addHint("tui.select.confirm","locate"),addHint("tui.select.cancel","cancel",{cancel:!0})}else if(addHint("tui.select.up",`/ ${hint("tui.select.down")}${focus==="list"?" tasks":" scroll"}`),addHint("app.tasks.nextFocus",focus==="list"?tab==="output"?"output":"details":"tasks",{key:"app.tasks.nextFocus"}),addHint("tui.select.cancel","close",{cancel:!0}),focus==="list"?addHint("app.tasks.search","find",{key:"app.tasks.search"}):(addHint("app.tasks.previousTab","output",{tab:"output"}),addHint("app.tasks.nextTab","details",{tab:"info"})),task&&!isTaskTerminal(task.status)&&task.status!=="stopping"&&(addHint("app.tasks.kill","stop",{key:"app.tasks.kill"}),task.mode==="foreground"&&options.canDetach&&addHint("app.tasks.detachSelected","background",{key:"app.tasks.detachSelected"})),addHint("app.tasks.help","keys",{key:"app.tasks.help"}),options.feedback){footer=options.feedback;for(let i=hits.length-1;i>=0;i--)hits[i].y===height-1&&hits.splice(i,1)}return result2.lines=[...panels,theme2.fg(options.pendingKill?"warning":"dim",pad(footer,width))],result2}var TaskList=class{constructor(){this.start=0,this.height=1,this.rows=[],this.selectedLine=-1,this.reveal=!1}showSelection(){this.reveal=!0}scroll(delta){this.start=Math.max(0,Math.min(Math.max(0,this.rows.length-this.height),this.start+delta))}render(selection,theme2,width,height){let rows=[],labels=selection.rows.map(task=>cleanTaskText(firstCommandLine(task.command??task.title))),fitted=labels.map(label=>truncateToWidth(label,Math.max(1,width-3),"\u2026")),group="",selectedLine=-1;for(let[index3,task]of selection.rows.entries()){let nextGroup=isTaskTerminal(task.status)?"Finished":"Active";nextGroup!==group&&(rows.push({text:theme2.fg("dim",nextGroup)}),group=nextGroup);let selected=task.id===selection.state.selectedId;selected&&(selectedLine=rows.length);let marker=statusMarker(task.status,{now:Date.now()}),duplicate=fitted.some((label,other)=>other!==index3&&label===fitted[index3]),meta=`${runtimeLabel(task)}${duplicate?` \xB7 ${task.id.slice(-8)}`:""}`,texts=[`${theme2.fg(marker.color,marker.glyph)} ${theme2.fg("text",labels[index3])}`,` ${theme2.fg(marker.color,statusName(task.status))}${theme2.fg("muted",` \xB7 ${meta}`)}`];for(let text2 of texts){let padded=truncateToWidth(text2,width,"\u2026",!0);rows.push({text:selected?theme2.getBgAnsi("selectedBg")==="\x1B[49m"?theme2.style(stripTerminalSequences(padded),{inverse:!0}):theme2.bg("selectedBg",padded):padded,taskId:task.id})}}rows.length||rows.push({text:theme2.fg("muted",selection.query?"No matching tasks.":"No retained tasks.")});let sameSelection=this.selectedId===selection.state.selectedId,selectedWasVisible=sameSelection&&this.selectedLine>=this.start&&this.selectedLine<this.start+this.height&&selectedLine>=0;if(selectedWasVisible)this.start+=selectedLine-this.selectedLine;else{let anchor=this.rows[this.start]?.taskId,offset=anchor&&this.rows[this.start-1]?.taskId===anchor?1:0,next=anchor?rows.findIndex(row=>row.taskId===anchor):-1;next>=0&&(this.start=next+offset)}return selectedLine>=0&&(!sameSelection||this.reveal||selectedWasVisible)&&(selectedLine<this.start?this.start=selectedLine:selectedLine+1>=this.start+height&&(this.start=selectedLine+2-height)),this.start=Math.max(0,Math.min(Math.max(0,rows.length-height),this.start)),this.rows=rows,this.height=height,this.selectedId=selection.state.selectedId,this.selectedLine=selectedLine,this.reveal=!1,rows.slice(this.start,this.start+height)}get range(){if(this.rows.length<=this.height)return"";let ids=[...new Set(this.rows.flatMap(row=>row.taskId?[row.taskId]:[]))],visible=this.rows.slice(this.start,this.start+this.height).flatMap(row=>row.taskId?[row.taskId]:[]);return`Tasks ${ids.indexOf(visible[0])+1}-${ids.indexOf(visible.at(-1))+1} of ${ids.length}`}};var TaskSelection=class{constructor(state2){this.all=[],this.rows=[],this.query="",this.state=state2}get selected(){return this.rows.find(task=>task.id===this.state.selectedId)}get activeCount(){return this.all.filter(task=>!isTaskTerminal(task.status)).length}sync(all){this.all=all,this.refresh()}select(id){this.state.selectedId=id,this.refresh()}refresh(){let{selectedId}=this.state,active=this.all.filter(task=>!isTaskTerminal(task.status)).sort((a,b2)=>b2.startedAt-a.startedAt||a.id.localeCompare(b2.id)),history=this.all.filter(task=>isTaskTerminal(task.status)).sort((a,b2)=>(b2.endedAt??0)-(a.endedAt??0)||a.id.localeCompare(b2.id)),rows=[...active,...history],search=this.query.toLocaleLowerCase().trim();this.rows=search?rows.filter(task=>`${task.title}
|
|
1726
|
+
`).map(line=>theme2.fg("toolOutput",line));return read?.readError&&output.unshift(theme2.fg("warning","Log unavailable; showing saved result.")),(!read||read.readError)&&task.resultTruncated&&output.push(theme2.fg("warning","Saved result truncated.")),{info,output}}var TaskInspector=class{constructor(options){this.positions=new Map,this.reading=!1,this.disposed=!1,this.options=options}get position(){let id=this.task?.id,position=id?this.positions.get(id):void 0;return position||(position={info:new TaskViewport,output:new TaskViewport(!0)},id&&this.positions.set(id,position)),position}select(task){if(!this.disposed){if(this.task?.id!==task?.id){let release2=task?this.options.host.retain(task.id):void 0,previous=this.release;this.release=release2,previous?.()}this.task=task}}prune(ids){for(let id of this.positions.keys())ids.has(id)||this.positions.delete(id)}invalidate(){this.cache=void 0}async refresh(){let task=this.task;if(this.disposed||!task||this.reading)return;let position=this.position;if(!(position.read&&(!position.output.follow||isTaskTerminal(position.read.task.status)))){this.reading=!0;try{let read=await this.options.host.read(task.id,{mode:"tail",bytes:49152});if(this.disposed||this.task?.id!==task.id||!position.output.follow&&position.read)return;position.read=read}catch(error){!this.disposed&&this.task?.id===task.id&&(position.output.follow||!position.read)&&(position.read={task,text:"",readError:`Cannot read output: ${cleanTaskText(String(error))}`,totalBytes:0,truncated:!1})}finally{this.reading=!1,this.disposed||this.options.requestRender(),!this.disposed&&this.task?.id!==task.id&&await this.refresh()}}}lines(tab){let task=this.task;if(!task)return[];let read=this.position.read;return(this.cache?.task!==task||this.cache.read!==read)&&(this.cache={task,read,lines:taskLines(task,read,this.options.theme)}),this.cache.lines[tab]}dispose(){this.disposed||(this.disposed=!0,this.release?.(),this.release=void 0,this.positions.clear())}};var pad=(text2,width)=>truncateToWidth(text2,Math.max(1,width),"\u2026",!0);function renderTasksLayout(options){let{width,height,theme:theme2,selection,inspector,list:list2,focus,keybindings}=options,hint=key=>keyLabel(key,{keybindings}),result2={hits:[],listWidth:0,listPageSize:1,lines:[]};if(width<1||height<1)return result2;if(width<60||height<14)return result2.lines=["Tasks","Terminal too small for /tasks. Resize to 60\xD714.",`${hint("tui.select.cancel")} close`].slice(0,height).map(line=>pad(line,width)),result2;let wide=width>=100,listWidth=wide?Math.min(42,Math.max(32,Math.floor(width*.32))):width,rightWidth=wide?width-listWidth-1:width,rightX=wide?listWidth+1:0,bodyHeight=height-5,hits=result2.hits;result2.listWidth=listWidth,result2.listPageSize=Math.max(1,Math.floor((bodyHeight-1)/2));let pane=(lines,size,active)=>{let border=text2=>theme2.fg(wide&&active?"borderAccent":"borderMuted",text2);return[border(`\u250C${"\u2500".repeat(size-2)}\u2510`),...lines.map(line=>border("\u2502")+pad(line,size-2)+border("\u2502")),border(`\u2514${"\u2500".repeat(size-2)}\u2518`)]},visible=list2.render(selection,theme2,listWidth-2,bodyHeight),listHeader=theme2.fg("text","Tasks"),searchLabel=`${hint("app.tasks.search")} find`;if(options.searchLine)listHeader=options.searchLine(listWidth-2);else{let x2=Math.max(6,listWidth-2-visibleWidth(searchLabel));listHeader+=" ".repeat(x2-5)+theme2.fg("dim",searchLabel),(wide||focus==="list")&&hits.push({x:x2+1,y:1,width:visibleWidth(searchLabel),key:"app.tasks.search"})}(wide||focus==="list")&&visible.forEach((row,index3)=>{row.taskId&&hits.push({x:1,y:2+index3,width:listWidth-2,taskId:row.taskId})});let left=[listHeader,...Array.from({length:bodyHeight},(_2,i)=>visible[i]?.text??""),theme2.fg("dim",list2.range)],task=inspector.task,tab=selection.state.tab,tabLabel=(id,label)=>theme2.style(label,{fg:"text",underline:tab===id}),right=[`${tabLabel("output","Output")} ${tabLabel("info","Details")}`];(wide||focus==="inspector")&&hits.push({x:rightX+1,y:1,width:6,tab:"output"},{x:rightX+9,y:1,width:7,tab:"info"});let content=[],reading="";if(task){wide||content.push(theme2.fg("text",cleanTaskText(firstCommandLine(task.command??task.title))),theme2.fg("muted",`${statusName(task.status)} \xB7 ${runtimeLabel(task)}`));let lines=inspector.lines(tab),position=inspector.position,read=position.read,diagnostics=[task.error,read?.readError].filter(text2=>!!text2).map(cleanTaskText);tab==="output"&&diagnostics.length&&content.push(theme2.fg("warning",diagnostics.join(" \xB7 ").replace(/\n/g," ")));let source=tab==="info"?[`Task ID ${task.id}`,`Status ${statusName(task.status)} \xB7 ${statusName(task.mode)} \xB7 ${runtimeLabel(task)}`,...diagnostics,...lines]:lines;content.push(...position[tab].layout(source,rightWidth-2,bodyHeight-content.length)),tab==="output"?(reading=position.output.follow?isTaskTerminal(task.status)?"Finished":"Live":isTaskTerminal(task.status)?`Finished \xB7 ${hint("app.tasks.follow")} load final output`:`Browsing \xB7 ${hint("app.tasks.follow")} follow output`,!position.output.follow&&(wide||focus==="inspector")&&hits.push({x:rightX+1,y:height-3,width:Math.min(rightWidth-2,visibleWidth(reading)),key:"app.tasks.follow"}),read?.truncated&&(reading+=` \xB7 Tail preview: ${formatSize(Buffer.byteLength(read.text))} of ${formatSize(read.totalBytes)}`)):tab==="info"&&(reading=`Details ${position.info.range}`)}else content.push(theme2.fg("muted","Select a task to inspect its result."));right.push(...Array.from({length:bodyHeight},(_2,i)=>content[i]??""),theme2.fg("dim",reading));let rightPane=pane(right,rightWidth,focus==="inspector"),panels=wide?pane(left,listWidth,focus==="list").map((line,i)=>`${line} ${rightPane[i]}`):pane(focus==="list"?left:right,width,!1),footer="",addHint=(key,label,target)=>{let text2=`${hint(key)} ${label}`,x2=visibleWidth(footer)+(footer?3:0);x2+visibleWidth(text2)>width||(footer+=(footer?" \xB7 ":"")+text2,target&&hits.push({x:x2,y:height-1,width:visibleWidth(text2),...target}))};if(options.help||options.pendingKill){hits.length=0;let body;if(options.help){let controls=[["app.tasks.nextFocus","Switch task list / inspector"],["app.tasks.previousFocus","Switch inspector / task list"],["app.tasks.previousTab","Output (inspector only)"],["app.tasks.nextTab","Details (inspector only)"],["tui.select.up","Previous task / scroll up"],["tui.select.down","Next task / scroll down"],["tui.select.pageUp","Page up in task list"],["tui.select.pageDown","Page down in task list"],["tui.editor.pageUp","Page up in inspector"],["tui.editor.pageDown","Page down in inspector"],["app.tasks.top","Top of list / content"],["app.tasks.bottom","Bottom of list / content"],["app.tasks.search","Locate a retained task; Enter chooses, Escape restores selection"],["app.tasks.follow","Follow latest / final output (Output only)"],["app.tasks.detach","Move every eligible foreground execution to the background"],["app.tasks.detachSelected","Move selected foreground task to background"],["app.tasks.kill","Request stop of selected whole task"],["app.tasks.confirmStop","Confirm stop"],["tui.select.cancel","Close current search, help or confirmation; otherwise close panel"]];body=[theme2.fg("text","Task controls"),...options.help.layout(controls.map(([key,label])=>hint(key).padEnd(14)+label),width-2,height-5),""],addHint("tui.select.up",`/ ${hint("tui.select.down")} scroll`),addHint("tui.select.cancel","back",{cancel:!0})}else{let target=selection.all.find(task2=>task2.id===options.pendingKill),command=wrapTextWithAnsi(cleanTaskText(target?.command??target?.title??options.pendingKill),width-2),preview=command.slice(0,height-8);preview.length<command.length&&(preview[preview.length-1]="\u2026 Full command in Details."),body=[theme2.fg("text","Stop task?"),"Stops the whole task, including its active work.",`Task ID: ${options.pendingKill}`,"",...preview],addHint("app.tasks.confirmStop","confirm",{key:"app.tasks.confirmStop"}),addHint("tui.select.cancel","cancel",{cancel:!0})}for(;body.length<height-3;)body.push("");panels=pane(body,width,!1)}else if(options.searchLine){for(let i=hits.length-1;i>=0;i--)hits[i].taskId||hits.splice(i,1);addHint("tui.select.up",`/ ${hint("tui.select.down")} choose`),addHint("tui.select.confirm","locate"),addHint("tui.select.cancel","cancel",{cancel:!0})}else addHint("tui.select.up",`/ ${hint("tui.select.down")}${focus==="list"?" tasks":" scroll"}`),addHint("app.tasks.nextFocus",focus==="list"?tab==="output"?"output":"details":"tasks",{key:"app.tasks.nextFocus"}),addHint("tui.select.cancel","close",{cancel:!0}),focus==="list"?addHint("app.tasks.search","find",{key:"app.tasks.search"}):(addHint("app.tasks.previousTab","output",{tab:"output"}),addHint("app.tasks.nextTab","details",{tab:"info"})),task&&!isTaskTerminal(task.status)&&task.status!=="stopping"&&(addHint("app.tasks.kill","stop",{key:"app.tasks.kill"}),task.mode==="foreground"&&options.canDetach&&addHint("app.tasks.detachSelected","background",{key:"app.tasks.detachSelected"})),addHint("app.tasks.help","keys",{key:"app.tasks.help"}),options.feedback&&(footer=options.feedback);return result2.lines=[...panels,theme2.fg(options.pendingKill?"warning":"dim",pad(footer,width))],result2}var TaskList=class{constructor(){this.start=0,this.height=1,this.rows=[],this.selectedLine=-1,this.reveal=!1}showSelection(){this.reveal=!0}scroll(delta){this.start=Math.max(0,Math.min(Math.max(0,this.rows.length-this.height),this.start+delta))}render(selection,theme2,width,height){let rows=[],labels=selection.rows.map(task=>cleanTaskText(firstCommandLine(task.command??task.title))),fitted=labels.map(label=>truncateToWidth(label,Math.max(1,width-3),"\u2026")),group="",selectedLine=-1;for(let[index3,task]of selection.rows.entries()){let nextGroup=isTaskTerminal(task.status)?"Finished":"Active";nextGroup!==group&&(rows.push({text:theme2.fg("dim",nextGroup)}),group=nextGroup);let selected=task.id===selection.state.selectedId;selected&&(selectedLine=rows.length);let marker=statusMarker(task.status,{now:Date.now()}),duplicate=fitted.some((label,other)=>other!==index3&&label===fitted[index3]),meta=`${runtimeLabel(task)}${duplicate?` \xB7 ${task.id.slice(-8)}`:""}`,texts=[`${theme2.fg(marker.color,marker.glyph)} ${theme2.fg("text",labels[index3])}`,` ${theme2.fg(marker.color,statusName(task.status))}${theme2.fg("muted",` \xB7 ${meta}`)}`];for(let text2 of texts){let padded=truncateToWidth(text2,width,"\u2026",!0);rows.push({text:selected?theme2.getBgAnsi("selectedBg")==="\x1B[49m"?theme2.style(stripTerminalSequences(padded),{inverse:!0}):theme2.bg("selectedBg",padded):padded,taskId:task.id})}}rows.length||rows.push({text:theme2.fg("muted",selection.query?"No matching tasks.":"No retained tasks.")});let sameSelection=this.selectedId===selection.state.selectedId,selectedWasVisible=sameSelection&&this.selectedLine>=this.start&&this.selectedLine<this.start+this.height&&selectedLine>=0;if(selectedWasVisible)this.start+=selectedLine-this.selectedLine;else{let anchor=this.rows[this.start]?.taskId,offset=anchor&&this.rows[this.start-1]?.taskId===anchor?1:0,next=anchor?rows.findIndex(row=>row.taskId===anchor):-1;next>=0&&(this.start=next+offset)}return selectedLine>=0&&(!sameSelection||this.reveal||selectedWasVisible)&&(selectedLine<this.start?this.start=selectedLine:selectedLine+1>=this.start+height&&(this.start=selectedLine+2-height)),this.start=Math.max(0,Math.min(Math.max(0,rows.length-height),this.start)),this.rows=rows,this.height=height,this.selectedId=selection.state.selectedId,this.selectedLine=selectedLine,this.reveal=!1,rows.slice(this.start,this.start+height)}get range(){if(this.rows.length<=this.height)return"";let ids=[...new Set(this.rows.flatMap(row=>row.taskId?[row.taskId]:[]))],visible=this.rows.slice(this.start,this.start+this.height).flatMap(row=>row.taskId?[row.taskId]:[]);return`Tasks ${ids.indexOf(visible[0])+1}-${ids.indexOf(visible.at(-1))+1} of ${ids.length}`}};var TaskSelection=class{constructor(state2){this.all=[],this.rows=[],this.query="",this.state=state2}get selected(){return this.rows.find(task=>task.id===this.state.selectedId)}get activeCount(){return this.all.filter(task=>!isTaskTerminal(task.status)).length}sync(all){this.all=all,this.refresh()}select(id){this.state.selectedId=id,this.refresh()}refresh(){let{selectedId}=this.state,active=this.all.filter(task=>!isTaskTerminal(task.status)).sort((a,b2)=>b2.startedAt-a.startedAt||a.id.localeCompare(b2.id)),history=this.all.filter(task=>isTaskTerminal(task.status)).sort((a,b2)=>(b2.endedAt??0)-(a.endedAt??0)||a.id.localeCompare(b2.id)),rows=[...active,...history],search=this.query.toLocaleLowerCase().trim();this.rows=search?rows.filter(task=>`${task.title}
|
|
1727
1727
|
${task.command??""}
|
|
1728
1728
|
${task.kind}
|
|
1729
|
-
${task.id}`.toLocaleLowerCase().includes(search)):rows,this.rows.some(task=>task.id===selectedId)||(this.state.selectedId=this.rows[0]?.id)}};var actions=["app.tasks.search","app.tasks.kill","app.tasks.detachSelected","app.tasks.previousTab","app.tasks.nextTab","app.tasks.follow","app.tasks.top","app.tasks.bottom","app.tasks.nextFocus","app.tasks.previousFocus","app.tasks.help"],TasksMenu=class{constructor(options){this.focused=!1,this.list=new TaskList,this.focus="list",this.searching=!1,this.dirty=!0,this.tickQueued=!1,this.refreshQueued=!1,this.disposed=!1,this.options=options,this.width=options.tui.terminal.columns,this.selection=new TaskSelection(options.state??{tab:"output"}),this.inspector=new TaskInspector({host:options.host,theme:options.theme,requestRender:()=>options.tui.requestRender()}),this.search=new Input({prompt:"Find task: ",placeholder:"title, command, kind or ID"}),this.sync(),this.unsubscribe=options.host.subscribe(()=>{this.dirty=!0,this.queueTick(),options.tui.requestRender()}),this.pollTimer=setInterval(()=>{this.queueTick(!0),this.selection.activeCount&&options.tui.requestRender()},options.pollIntervalMs??1e3),this.pollTimer.unref?.(),this.queueTick(!0)}sync(){if(this.disposed||!this.dirty)return;this.dirty=!1;let previous=this.selection.selected;this.selection.sync(this.options.host.list()),this.inspector.select(this.selection.selected),this.inspector.prune(new Set(this.selection.all.map(task=>task.id)));let selected=this.selection.selected;selected&&isTaskTerminal(selected.status)&&previous&&!isTaskTerminal(previous.status)&&(this.feedback=void 0),this.pendingKill&&(this.pendingKill!==selected?.id||selected&&isTaskTerminal(selected.status))&&this.clearKill();let animates=this.selection.all.some(task=>task.status==="running");animates&&!this.animationTimer?(this.animationTimer=setInterval(()=>this.options.tui.requestRender(),STATUS_SPINNER_INTERVAL_MS),this.animationTimer.unref?.()):animates||(clearInterval(this.animationTimer),this.animationTimer=void 0)}queueTick(refresh=!1){this.disposed||(this.refreshQueued||=refresh,!this.tickQueued&&(this.tickQueued=!0,Promise.resolve().then(async()=>{if(this.tickQueued=!1,this.disposed)return;let refresh2=this.refreshQueued;this.refreshQueued=!1,this.sync(),(refresh2||this.inspector.task&&isTaskTerminal(this.inspector.task.status))&&await this.inspector.refresh()}).catch(()=>{})))}invalidate(){this.inspector.invalidate()}clearKill(){this.pendingKill=void 0}selectedChanged(){this.clearKill(),this.list.showSelection(),this.inspector.select(this.selection.selected),this.queueTick(!0)}stop(confirm=!1){let task=this.selection.selected;if(confirm){let id=this.pendingKill;if(this.clearKill(),!id||id!==task?.id||isTaskTerminal(task.status))return;this.feedback=this.options.host.kill(id)?"Cancellation requested; waiting for cleanup.":"No new cancellation requested."}else task&&!isTaskTerminal(task.status)&&task.status!=="stopping"&&(this.pendingKill=task.id)}finishSearch(cancel){let id=cancel?this.beforeSearch?.id:this.selection.state.selectedId;!cancel&&!id||(this.focus=cancel?this.beforeSearch?.focus??"list":"list",this.searching=!1,this.search.focused=!1,this.selection.query="",this.selection.select(id),this.beforeSearch=void 0,this.selectedChanged())}action(key){switch(key){case"app.tasks.search":this.beforeSearch={id:this.selection.state.selectedId,focus:this.focus},this.focus="list",this.searching=!0,this.search.focused=!0,this.search.setValue("");break;case"app.tasks.previousTab":case"app.tasks.nextTab":this.focus==="inspector"&&(this.selection.state.tab=key==="app.tasks.previousTab"?"output":"info");break;case"app.tasks.nextFocus":case"app.tasks.previousFocus":this.focus=this.focus==="list"?"inspector":"list";break;case"app.tasks.follow":this.focus==="inspector"&&this.selection.state.tab==="output"&&(this.inspector.position.output.jump(!0,!0),this.queueTick(!0));break;case"app.tasks.top":case"app.tasks.bottom":this.focus==="list"?(this.selection.select(key==="app.tasks.top"?this.selection.rows[0]?.id:this.selection.rows.at(-1)?.id),this.selectedChanged()):this.inspector.position[this.selection.state.tab].jump(key==="app.tasks.bottom",this.selection.state.tab==="output");break;case"app.tasks.kill":this.stop();break;case"app.tasks.confirmStop":this.stop(!0);break;case"app.tasks.detachSelected":{let task=this.selection.selected;task?.mode==="foreground"&&!isTaskTerminal(task.status)&&task.status!=="stopping"&&this.options.host.enabled!==!1&&(this.feedback=this.options.host.detach?.(task.id)?"Selected task moved to background; execution continues.":"This task cannot move to background.");break}case"app.tasks.help":this.help=this.help?void 0:new TaskViewport;break}}move(direction,page=!1){if(this.help){this.help.move(direction,page,!1);return}if(this.focus==="list"){let rows=this.selection.rows;if(!rows.length)return;let index3=rows.findIndex(task=>task.id===this.selection.state.selectedId),next=page?Math.max(0,Math.min(rows.length-1,index3+direction*(this.layout?.listPageSize??1))):(index3+direction+rows.length)%rows.length;this.selection.select(rows[next]?.id),this.selectedChanged()}else this.inspector.position[this.selection.state.tab].move(direction,page,this.selection.state.tab==="output")}handleInput(data){if(this.disposed)return;this.sync(),this.render(this.width);let kb=this.options.keybindings;this.feedback=void 0;try{if(this.help)kb.matches(data,"tui.select.cancel")||kb.matches(data,"app.tasks.help")?this.help=void 0:kb.matches(data,"app.tasks.top")||kb.matches(data,"app.tasks.bottom")?this.help.jump(kb.matches(data,"app.tasks.bottom"),!1):kb.matches(data,"tui.select.up")||kb.matches(data,"tui.editor.pageUp")?this.help.move(-1,kb.matches(data,"tui.editor.pageUp"),!1):(kb.matches(data,"tui.select.down")||kb.matches(data,"tui.editor.pageDown"))&&this.help.move(1,kb.matches(data,"tui.editor.pageDown"),!1);else if(this.searching)kb.matches(data,"tui.select.cancel")?this.finishSearch(!0):kb.matches(data,"tui.select.confirm")?this.finishSearch(!1):kb.matches(data,"tui.select.up")||kb.matches(data,"tui.select.pageUp")?this.move(-1,kb.matches(data,"tui.select.pageUp")):kb.matches(data,"tui.select.down")||kb.matches(data,"tui.select.pageDown")?this.move(1,kb.matches(data,"tui.select.pageDown")):(this.search.handleInput(data),this.selection.query=this.search.getValue().slice(0,512),this.selection.refresh(),this.selectedChanged());else if(this.pendingKill)kb.matches(data,"app.tasks.confirmStop")?this.stop(!0):kb.matches(data,"tui.select.cancel")&&this.clearKill();else if(kb.matches(data,"tui.select.cancel")){this.dispose(),this.options.onClose();return}else{let pageUp=kb.matches(data,this.focus==="list"?"tui.select.pageUp":"tui.editor.pageUp"),pageDown=kb.matches(data,this.focus==="list"?"tui.select.pageDown":"tui.editor.pageDown");if(pageUp||kb.matches(data,"tui.select.up"))this.move(-1,pageUp);else if(pageDown||kb.matches(data,"tui.select.down"))this.move(1,pageDown);else{if(kb.matches(data,"tui.select.confirm"))return;{let key=actions.find(key2=>kb.matches(data,key2));key&&this.action(key)}}}}catch(error){this.feedback=cleanTaskText(error instanceof Error?error.message:String(error))}this.queueTick(!0),this.options.tui.requestRender()}handleMouse(event){if(this.disposed||event.ctrl||event.alt||event.shift)return;this.render(event.width);let layout=this.layout;if(event.type==="wheel"&&event.wheelDelta){if(!this.pendingKill&&event.y>=2&&event.y<this.options.tui.terminal.rows-3){let delta=Math.sign(event.wheelDelta)*Math.min(20,Math.abs(event.wheelDelta)),region=this.width>=100?event.x<layout.listWidth?"list":"inspector":this.focus;this.help?this.help.move(delta,!1,!1):region==="list"?this.list.scroll(delta):this.searching||this.inspector.position[this.selection.state.tab].move(delta,!1,this.selection.state.tab==="output")}}else if(event.type==="click"&&event.button==="left"){let hit=layout.hits.find(hit2=>hit2.y===event.y&&event.x>=hit2.x&&event.x<hit2.x+hit2.width);try{hit?.cancel?this.searching?this.finishSearch(!0):this.help?this.help=void 0:this.pendingKill?this.clearKill():(this.dispose(),this.options.onClose()):hit?.taskId?(this.selection.select(hit.taskId),this.selectedChanged(),this.focus="list",this.searching&&this.finishSearch(!1)):hit?.tab?(this.focus="inspector",this.selection.state.tab=hit.tab):hit?.key?(hit.key==="app.tasks.follow"&&(this.focus="inspector"),this.action(hit.key)):!this.pendingKill&&!this.searching&&!this.help&&event.y>=1&&event.y<this.options.tui.terminal.rows-2&&this.width>=100&&(this.focus=event.x<layout.listWidth?"list":"inspector")}catch(error){this.feedback=cleanTaskText(error instanceof Error?error.message:String(error))}}else return;return this.queueTick(!0),this.options.tui.requestRender(),{handled:!0,focus:event.type==="click"}}render(width){return this.width=width,this.sync(),this.layout=renderTasksLayout({width,height:this.options.tui.terminal.rows,theme:this.options.theme,keybindings:this.options.keybindings,selection:this.selection,inspector:this.inspector,list:this.list,focus:this.focus,searchLine:this.searching?width2=>this.search.render(width2).join(""):void 0,pendingKill:this.pendingKill,feedback:this.feedback,help:this.help,canDetach:this.options.host.enabled!==!1&&!!this.options.host.detach}),this.layout.lines}dispose(){this.disposed||(this.disposed=!0,clearInterval(this.pollTimer),clearInterval(this.animationTimer),this.clearKill(),this.unsubscribe(),this.inspector.dispose())}};function bindTasksUI(ctx){let state2={tab:"output"},unsubscribe,unsubscribeDetachKey,closeMenu,hintTimer,start=()=>{unsubscribe?.(),unsubscribeDetachKey?.();let update=()=>{clearTimeout(hintTimer),hintTimer=void 0;let all=ctx.tasks.list(),running=all.filter(task=>!isTaskTerminal(task.status)).length,recent=all.filter(task=>isTaskTerminal(task.status)&&task.mode==="background").length,parts=[];running?parts.push(`Tasks ${running} active \xB7 /tasks`):recent&&parts.push(`Tasks ${recent} recent background results \xB7 /tasks`);let detachKey=keyLabel("app.tasks.detach"),now=Date.now(),movable=(ctx.tasks.enabled?all:[]).filter(task=>task.mode==="foreground"&&(task.status==="running"||task.status==="queued")),waits=movable.map(task=>task.startedAt+1e4-now).filter(wait=>wait>0);detachKey&&movable.length>waits.length&&parts.push(`${detachKey} to background`),detachKey&&waits.length>0&&(hintTimer=setTimeout(update,Math.min(...waits)),hintTimer.unref?.()),ctx.ui.setStatus("background",parts.length?parts.join(" \xB7 "):void 0)};unsubscribe=ctx.tasks.subscribe(update),unsubscribeDetachKey=ctx.ui.onTerminalInput(data=>{if(!getKeybindings().matches(data,"app.tasks.detach"))return;let count;try{count=ctx.tasks.detachForeground()}catch(error){return ctx.ui.notify(error instanceof Error?error.message:String(error),"warning"),{consume:!0}}if(count!==0)return ctx.ui.notify(`Moved ${count} execution${count===1?"":"s"} to the background. Use /tasks to manage tasks.`),{consume:!0}}),update()},dispose=()=>{unsubscribe?.(),unsubscribe=void 0,unsubscribeDetachKey?.(),unsubscribeDetachKey=void 0,clearTimeout(hintTimer),hintTimer=void 0,closeMenu?.(),closeMenu=void 0,ctx.ui.setStatus("background",void 0)};return start(),{dispose,open:async()=>{closeMenu?.(),await ctx.ui.custom((tui,theme2,keybindings,done)=>{let close=()=>{closeMenu===close&&(closeMenu=void 0),done()};return closeMenu=close,new TasksMenu({state:state2,tui,theme:theme2,keybindings,host:ctx.tasks,onClose:close})},{overlay:!0,overlayOptions:{anchor:"center",width:"100%",maxHeight:"100%"}})}}}import*as crypto3 from"node:crypto";import*as fs8 from"node:fs";import*as os7 from"node:os";import*as path13 from"node:path";import{spawn as spawn12}from"child_process";function detectMiss(prev,message,models){let usage=message.usage,promptTokens=usage.input+usage.cacheRead+usage.cacheWrite;if(!prev||promptTokens<=0||usage.cacheRead+usage.cacheWrite===0&&!prev.reportedCache)return;let missedTokens=Math.min(prev.promptTokens,promptTokens)-usage.cacheRead;if(missedTokens<=1024)return;let paidTokens=usage.input+usage.cacheWrite,paidPerToken=paidTokens>0?(usage.cost.input+usage.cost.cacheWrite)/paidTokens:0,readPerToken=usage.cacheRead>0?usage.cost.cacheRead/usage.cacheRead:(models.getModel(message.provider,message.model)?.cost.cacheRead??0)/1e6;return{missedTokens,missedCost:missedTokens*Math.max(0,paidPerToken-readPerToken),idleMs:Math.max(0,message.timestamp-prev.timestamp),modelChanged:`${message.provider}/${message.model}`!==prev.modelKey}}function asPreviousRequest(message,reportedCache){let usage=message.usage,promptTokens=usage.input+usage.cacheRead+usage.cacheWrite;if(!(promptTokens<=0))return{promptTokens,modelKey:`${message.provider}/${message.model}`,timestamp:message.timestamp,reportedCache:reportedCache||usage.cacheRead+usage.cacheWrite>0}}function scan(entries,models){let prev,totals={missedTokens:0,missedCost:0,missCount:0},misses=new Map;for(let entry of entries){if(entry.type==="compaction"||entry.type==="branch_summary"){prev=void 0;continue}if(entry.type==="usage"&&entry.kind==="cache_warm"){let promptTokens=entry.usage.input+entry.usage.cacheRead+entry.usage.cacheWrite;promptTokens>0&&(prev={promptTokens,modelKey:`${entry.provider}/${entry.model}`,timestamp:Date.parse(entry.timestamp),reportedCache:!0})}else if(entry.type==="message"&&entry.message.role==="assistant"){let miss=detectMiss(prev,entry.message,models);miss&&(totals.missedTokens+=miss.missedTokens,totals.missedCost+=miss.missedCost,totals.missCount+=1,misses.set(entry.message,miss)),prev=asPreviousRequest(entry.message,prev?.reportedCache??!1)??prev}}return{prev,totals,misses}}function computeCacheWaste(entries,models){return scan(entries,models).totals}function collectCacheMisses(entries,models){return scan(entries,models).misses}function detectCacheMiss(entries,message,models){return detectMiss(scan(entries,models).prev,message,models)}import{mkdirSync as mkdirSync14,readFileSync as readFileSync18,rmSync as rmSync4,writeFileSync as writeFileSync12}from"node:fs";import{dirname as dirname23,join as join42}from"node:path";var MAX_CRASH_RECORDS=5,MAX_AGE=10080*60*1e3;function crashLogPath(agentDir=getAgentDir()){return join42(agentDir,"crashes.json")}function readCrashLog(path14=crashLogPath()){try{let records=JSON.parse(readFileSync18(path14,"utf8"));return Array.isArray(records)?records.filter(record=>typeof record=="object"&&record!==null&&typeof record.timestamp=="string"&&typeof record.message=="string"):[]}catch{return[]}}function writeCrashLog(records,path14){mkdirSync14(dirname23(path14),{recursive:!0}),writeFileSync12(path14,`${JSON.stringify(records,null,2)}
|
|
1729
|
+
${task.id}`.toLocaleLowerCase().includes(search)):rows,this.rows.some(task=>task.id===selectedId)||(this.state.selectedId=this.rows[0]?.id)}};var actions=["app.tasks.search","app.tasks.kill","app.tasks.detachSelected","app.tasks.previousTab","app.tasks.nextTab","app.tasks.follow","app.tasks.top","app.tasks.bottom","app.tasks.nextFocus","app.tasks.previousFocus","app.tasks.help"],TasksMenu=class{constructor(options){this.focused=!1,this.list=new TaskList,this.focus="list",this.searching=!1,this.dirty=!0,this.tickQueued=!1,this.refreshQueued=!1,this.disposed=!1,this.options=options,this.width=options.tui.terminal.columns,this.selection=new TaskSelection(options.state??{tab:"output"}),this.inspector=new TaskInspector({host:options.host,theme:options.theme,requestRender:()=>options.tui.requestRender()}),this.search=new Input({prompt:"Find task: ",placeholder:"title, command, kind or ID"}),this.sync(),this.unsubscribe=options.host.subscribe(()=>{this.dirty=!0,this.queueTick(),options.tui.requestRender()}),this.pollTimer=setInterval(()=>{this.queueTick(!0),this.selection.activeCount&&options.tui.requestRender()},options.pollIntervalMs??1e3),this.pollTimer.unref?.(),this.queueTick(!0)}sync(){if(this.disposed||!this.dirty)return;this.dirty=!1;let previous=this.selection.selected;this.selection.sync(this.options.host.list()),this.inspector.select(this.selection.selected),this.inspector.prune(new Set(this.selection.all.map(task=>task.id)));let selected=this.selection.selected;selected&&isTaskTerminal(selected.status)&&previous&&!isTaskTerminal(previous.status)&&(this.feedback=void 0),this.pendingKill&&(this.pendingKill!==selected?.id||selected&&isTaskTerminal(selected.status))&&this.clearKill();let animates=this.selection.all.some(task=>task.status==="running");animates&&!this.animationTimer?(this.animationTimer=setInterval(()=>this.options.tui.requestRender(),STATUS_SPINNER_INTERVAL_MS),this.animationTimer.unref?.()):animates||(clearInterval(this.animationTimer),this.animationTimer=void 0)}queueTick(refresh=!1){this.disposed||(this.refreshQueued||=refresh,!this.tickQueued&&(this.tickQueued=!0,Promise.resolve().then(async()=>{if(this.tickQueued=!1,this.disposed)return;let refresh2=this.refreshQueued;this.refreshQueued=!1,this.sync(),(refresh2||this.inspector.task&&isTaskTerminal(this.inspector.task.status))&&await this.inspector.refresh()}).catch(()=>{})))}invalidate(){this.inspector.invalidate()}clearKill(){this.pendingKill=void 0}selectedChanged(){this.clearKill(),this.list.showSelection(),this.inspector.select(this.selection.selected),this.queueTick(!0)}stop(confirm=!1){let task=this.selection.selected;if(confirm){let id=this.pendingKill;if(this.clearKill(),!id||id!==task?.id||isTaskTerminal(task.status))return;this.feedback=this.options.host.kill(id)?"Cancellation requested; waiting for cleanup.":"No new cancellation requested."}else task&&!isTaskTerminal(task.status)&&task.status!=="stopping"&&(this.pendingKill=task.id)}finishSearch(cancel){let id=cancel?this.beforeSearch?.id:this.selection.state.selectedId;!cancel&&!id||(this.focus=cancel?this.beforeSearch?.focus??"list":"list",this.searching=!1,this.search.focused=!1,this.selection.query="",this.selection.select(id),this.beforeSearch=void 0,this.selectedChanged())}action(key){switch(key){case"app.tasks.search":this.beforeSearch={id:this.selection.state.selectedId,focus:this.focus},this.focus="list",this.searching=!0,this.search.focused=!0,this.search.setValue("");break;case"app.tasks.previousTab":case"app.tasks.nextTab":this.focus==="inspector"&&(this.selection.state.tab=key==="app.tasks.previousTab"?"output":"info");break;case"app.tasks.nextFocus":case"app.tasks.previousFocus":this.focus=this.focus==="list"?"inspector":"list";break;case"app.tasks.follow":this.focus==="inspector"&&this.selection.state.tab==="output"&&(this.inspector.position.output.jump(!0,!0),this.queueTick(!0));break;case"app.tasks.top":case"app.tasks.bottom":this.focus==="list"?(this.selection.select(key==="app.tasks.top"?this.selection.rows[0]?.id:this.selection.rows.at(-1)?.id),this.selectedChanged()):this.inspector.position[this.selection.state.tab].jump(key==="app.tasks.bottom",this.selection.state.tab==="output");break;case"app.tasks.kill":this.stop();break;case"app.tasks.confirmStop":this.stop(!0);break;case"app.tasks.detachSelected":{let task=this.selection.selected;task?.mode==="foreground"&&!isTaskTerminal(task.status)&&task.status!=="stopping"&&this.options.host.enabled!==!1&&(this.feedback=this.options.host.detach?.(task.id)?"Selected task moved to background; execution continues.":"This task cannot move to background.");break}case"app.tasks.help":this.help=this.help?void 0:new TaskViewport;break}}move(direction,page=!1){if(this.help){this.help.move(direction,page,!1);return}if(this.focus==="list"){let rows=this.selection.rows;if(!rows.length)return;let index3=rows.findIndex(task=>task.id===this.selection.state.selectedId),next=page?Math.max(0,Math.min(rows.length-1,index3+direction*(this.layout?.listPageSize??1))):(index3+direction+rows.length)%rows.length;this.selection.select(rows[next]?.id),this.selectedChanged()}else this.inspector.position[this.selection.state.tab].move(direction,page,this.selection.state.tab==="output")}handleInput(data){if(this.disposed)return;this.sync(),this.render(this.width);let kb=this.options.keybindings;this.feedback=void 0;try{if(this.help)kb.matches(data,"tui.select.cancel")||kb.matches(data,"app.tasks.help")?this.help=void 0:kb.matches(data,"app.tasks.top")||kb.matches(data,"app.tasks.bottom")?this.help.jump(kb.matches(data,"app.tasks.bottom"),!1):kb.matches(data,"tui.select.up")||kb.matches(data,"tui.editor.pageUp")?this.help.move(-1,kb.matches(data,"tui.editor.pageUp"),!1):(kb.matches(data,"tui.select.down")||kb.matches(data,"tui.editor.pageDown"))&&this.help.move(1,kb.matches(data,"tui.editor.pageDown"),!1);else if(this.searching)kb.matches(data,"tui.select.cancel")?this.finishSearch(!0):kb.matches(data,"tui.select.confirm")?this.finishSearch(!1):kb.matches(data,"tui.select.up")||kb.matches(data,"tui.select.pageUp")?this.move(-1,kb.matches(data,"tui.select.pageUp")):kb.matches(data,"tui.select.down")||kb.matches(data,"tui.select.pageDown")?this.move(1,kb.matches(data,"tui.select.pageDown")):(this.search.handleInput(data),this.selection.query=this.search.getValue().slice(0,512),this.selection.refresh(),this.selectedChanged());else if(this.pendingKill)kb.matches(data,"app.tasks.confirmStop")?this.stop(!0):kb.matches(data,"tui.select.cancel")&&this.clearKill();else if(kb.matches(data,"tui.select.cancel")){this.dispose(),this.options.onClose();return}else{let pageUp=kb.matches(data,this.focus==="list"?"tui.select.pageUp":"tui.editor.pageUp"),pageDown=kb.matches(data,this.focus==="list"?"tui.select.pageDown":"tui.editor.pageDown");if(pageUp||kb.matches(data,"tui.select.up"))this.move(-1,pageUp);else if(pageDown||kb.matches(data,"tui.select.down"))this.move(1,pageDown);else{if(kb.matches(data,"tui.select.confirm"))return;{let key=actions.find(key2=>kb.matches(data,key2));key&&this.action(key)}}}}catch(error){this.feedback=cleanTaskText(error instanceof Error?error.message:String(error))}this.queueTick(!0),this.options.tui.requestRender()}handleMouse(event){if(this.disposed||event.ctrl||event.alt||event.shift)return;this.feedback=void 0,this.render(event.width);let layout=this.layout;if(event.type==="wheel"&&event.wheelDelta){if(!this.pendingKill&&event.y>=2&&event.y<this.options.tui.terminal.rows-3){let delta=Math.sign(event.wheelDelta)*Math.min(20,Math.abs(event.wheelDelta)),region=this.width>=100?event.x<layout.listWidth?"list":"inspector":this.focus;this.help?this.help.move(delta,!1,!1):region==="list"?this.list.scroll(delta):this.searching||this.inspector.position[this.selection.state.tab].move(delta,!1,this.selection.state.tab==="output")}}else if(event.type==="click"&&event.button==="left"){let hit=layout.hits.find(hit2=>hit2.y===event.y&&event.x>=hit2.x&&event.x<hit2.x+hit2.width);try{hit?.cancel?this.searching?this.finishSearch(!0):this.help?this.help=void 0:this.pendingKill?this.clearKill():(this.dispose(),this.options.onClose()):hit?.taskId?(this.selection.select(hit.taskId),this.selectedChanged(),this.focus="list",this.searching&&this.finishSearch(!1)):hit?.tab?(this.focus="inspector",this.selection.state.tab=hit.tab):hit?.key?(hit.key==="app.tasks.follow"&&(this.focus="inspector"),this.action(hit.key)):!this.pendingKill&&!this.searching&&!this.help&&event.y>=1&&event.y<this.options.tui.terminal.rows-2&&this.width>=100&&(this.focus=event.x<layout.listWidth?"list":"inspector")}catch(error){this.feedback=cleanTaskText(error instanceof Error?error.message:String(error))}}else return;return this.queueTick(!0),this.options.tui.requestRender(),{handled:!0,focus:event.type==="click"}}render(width){return this.width=width,this.sync(),this.layout=renderTasksLayout({width,height:this.options.tui.terminal.rows,theme:this.options.theme,keybindings:this.options.keybindings,selection:this.selection,inspector:this.inspector,list:this.list,focus:this.focus,searchLine:this.searching?width2=>this.search.render(width2).join(""):void 0,pendingKill:this.pendingKill,feedback:this.feedback,help:this.help,canDetach:this.options.host.enabled!==!1&&!!this.options.host.detach}),this.layout.lines}dispose(){this.disposed||(this.disposed=!0,clearInterval(this.pollTimer),clearInterval(this.animationTimer),this.clearKill(),this.unsubscribe(),this.inspector.dispose())}};function bindTasksUI(ctx){let state2={tab:"output"},unsubscribe,unsubscribeDetachKey,closeMenu,hintTimer,start=()=>{unsubscribe?.(),unsubscribeDetachKey?.();let update=()=>{clearTimeout(hintTimer),hintTimer=void 0;let all=ctx.tasks.list(),background=all.filter(task=>task.mode==="background"&&!isTaskTerminal(task.status)).length,parts=[];background&&(parts.push(theme.fg("text",`${background} background task${background===1?"":"s"}`)),parts.push(theme.fg("accent","/tasks")+theme.fg("muted"," to view")));let detachKey=keyLabel("app.tasks.detach"),now=Date.now(),movable=all.filter(task=>ctx.tasks.canDetach(task.id)),waits=movable.map(task=>task.startedAt+1e4-now).filter(wait=>wait>0);detachKey&&movable.length>waits.length&&parts.push(theme.fg("accent",detachKey)+theme.fg("muted"," to run in background")),detachKey&&waits.length>0&&(hintTimer=setTimeout(update,Math.min(...waits)),hintTimer.unref?.()),ctx.ui.setStatus("background",parts.length?parts.join(theme.fg("dim"," \xB7 ")):void 0)};unsubscribe=ctx.tasks.subscribe(update),unsubscribeDetachKey=ctx.ui.onTerminalInput(data=>{if(!getKeybindings().matches(data,"app.tasks.detach"))return;let count;try{count=ctx.tasks.detachForeground()}catch(error){return ctx.ui.notify(error instanceof Error?error.message:String(error),"warning"),{consume:!0}}if(count!==0)return ctx.ui.notify(`Moved ${count} execution${count===1?"":"s"} to the background. Use /tasks to manage tasks.`),{consume:!0}}),update()},dispose=()=>{unsubscribe?.(),unsubscribe=void 0,unsubscribeDetachKey?.(),unsubscribeDetachKey=void 0,clearTimeout(hintTimer),hintTimer=void 0,closeMenu?.(),closeMenu=void 0,ctx.ui.setStatus("background",void 0)};return start(),{dispose,open:async()=>{closeMenu?.(),await ctx.ui.custom((tui,theme2,keybindings,done)=>{let close=()=>{closeMenu===close&&(closeMenu=void 0),done()};return closeMenu=close,new TasksMenu({state:state2,tui,theme:theme2,keybindings,host:ctx.tasks,onClose:close})},{overlay:!0,overlayOptions:{anchor:"center",width:"100%",maxHeight:"100%"}})}}}import*as crypto3 from"node:crypto";import*as fs8 from"node:fs";import*as os7 from"node:os";import*as path13 from"node:path";import{spawn as spawn12}from"child_process";function detectMiss(prev,message,models){let usage=message.usage,promptTokens=usage.input+usage.cacheRead+usage.cacheWrite;if(!prev||promptTokens<=0||usage.cacheRead+usage.cacheWrite===0&&!prev.reportedCache)return;let missedTokens=Math.min(prev.promptTokens,promptTokens)-usage.cacheRead;if(missedTokens<=1024)return;let paidTokens=usage.input+usage.cacheWrite,paidPerToken=paidTokens>0?(usage.cost.input+usage.cost.cacheWrite)/paidTokens:0,readPerToken=usage.cacheRead>0?usage.cost.cacheRead/usage.cacheRead:(models.getModel(message.provider,message.model)?.cost.cacheRead??0)/1e6;return{missedTokens,missedCost:missedTokens*Math.max(0,paidPerToken-readPerToken),idleMs:Math.max(0,message.timestamp-prev.timestamp),modelChanged:`${message.provider}/${message.model}`!==prev.modelKey}}function asPreviousRequest(message,reportedCache){let usage=message.usage,promptTokens=usage.input+usage.cacheRead+usage.cacheWrite;if(!(promptTokens<=0))return{promptTokens,modelKey:`${message.provider}/${message.model}`,timestamp:message.timestamp,reportedCache:reportedCache||usage.cacheRead+usage.cacheWrite>0}}function scan(entries,models){let prev,totals={missedTokens:0,missedCost:0,missCount:0},misses=new Map;for(let entry of entries){if(entry.type==="compaction"||entry.type==="branch_summary"){prev=void 0;continue}if(entry.type==="usage"&&entry.kind==="cache_warm"){let promptTokens=entry.usage.input+entry.usage.cacheRead+entry.usage.cacheWrite;promptTokens>0&&(prev={promptTokens,modelKey:`${entry.provider}/${entry.model}`,timestamp:Date.parse(entry.timestamp),reportedCache:!0})}else if(entry.type==="message"&&entry.message.role==="assistant"){let miss=detectMiss(prev,entry.message,models);miss&&(totals.missedTokens+=miss.missedTokens,totals.missedCost+=miss.missedCost,totals.missCount+=1,misses.set(entry.message,miss)),prev=asPreviousRequest(entry.message,prev?.reportedCache??!1)??prev}}return{prev,totals,misses}}function computeCacheWaste(entries,models){return scan(entries,models).totals}function collectCacheMisses(entries,models){return scan(entries,models).misses}function detectCacheMiss(entries,message,models){return detectMiss(scan(entries,models).prev,message,models)}import{mkdirSync as mkdirSync14,readFileSync as readFileSync18,rmSync as rmSync4,writeFileSync as writeFileSync12}from"node:fs";import{dirname as dirname23,join as join42}from"node:path";var MAX_CRASH_RECORDS=5,MAX_AGE=10080*60*1e3;function crashLogPath(agentDir=getAgentDir()){return join42(agentDir,"crashes.json")}function readCrashLog(path14=crashLogPath()){try{let records=JSON.parse(readFileSync18(path14,"utf8"));return Array.isArray(records)?records.filter(record=>typeof record=="object"&&record!==null&&typeof record.timestamp=="string"&&typeof record.message=="string"):[]}catch{return[]}}function writeCrashLog(records,path14){mkdirSync14(dirname23(path14),{recursive:!0}),writeFileSync12(path14,`${JSON.stringify(records,null,2)}
|
|
1730
1730
|
`)}function normalizeStackPath(value){return value.replace(/\\/g,"/").replace(/\/+$/u,"")}function stackContainsPath(stack,targetPath,includeDescendants){let target=normalizeStackPath(targetPath);if(!target||isSyntheticPath(target))return!1;let caseInsensitive=/^[a-z]:\//iu.test(target),haystack=caseInsensitive?stack.toLowerCase():stack,needle=caseInsensitive?target.toLowerCase():target;if(includeDescendants)return haystack.includes(`${needle}/`);let index3=haystack.indexOf(needle);for(;index3!==-1;){let next=haystack[index3+needle.length];if(next===void 0||next===":"||next===")"||/\s/u.test(next))return!0;index3=haystack.indexOf(needle,index3+needle.length)}return!1}function findExtensionStackMatches(stack,extensions){if(!stack)return[];let normalizedStack=stack.split(`
|
|
1731
1731
|
`).slice(1).filter(line=>/^\s+at\s/u.test(line)).map(line=>{try{return decodeURI(line)}catch{return line}}).join(`
|
|
1732
1732
|
`).replace(/\\/g,"/"),matches=[],seen=new Set;for(let extension of extensions){let resolvedPath=normalizeStackPath(extension.resolvedPath),singleFilePackage=extension.sourceInfo.origin==="package"&&!/^(?:npm:|git:|https?:\/\/|ssh:\/\/)/u.test(extension.sourceInfo.source)&&/\.[cm]?[jt]s$/u.test(extension.sourceInfo.source),packageRoot=extension.sourceInfo.origin==="package"&&!singleFilePackage&&extension.sourceInfo.baseDir?extension.sourceInfo.baseDir:void 0,slashIndex=resolvedPath.lastIndexOf("/"),directoryEntry=/\/index\.[cm]?[jt]s$/u.test(resolvedPath);if(!(packageRoot?stackContainsPath(normalizedStack,packageRoot,!0):directoryEntry&&slashIndex!==-1?stackContainsPath(normalizedStack,resolvedPath.slice(0,slashIndex),!0):stackContainsPath(normalizedStack,resolvedPath,!1)))continue;let label=extension.sourceInfo.origin==="package"&&extension.sourceInfo.source?extension.sourceInfo.source:extension.path;seen.has(label)||(seen.add(label),matches.push(label))}return matches}function recordCrash(crash,path14=crashLogPath()){try{let{error}=crash,record={timestamp:new Date().toISOString(),version:VERSION,kind:crash.kind,message:error instanceof Error?error.message||error.name:String(error),stack:error instanceof Error&&error.stack?error.stack:null,sessionFile:crash.sessionFile??null,cwd:crash.cwd};return writeCrashLog([...readCrashLog(path14),record].slice(-MAX_CRASH_RECORDS),path14),record}catch{return}}function takeUnnotifiedCrash(path14=crashLogPath(),now=Date.now()){let records=readCrashLog(path14),crash=[...records].reverse().find(record=>!record.notified&&now-Date.parse(record.timestamp)<=MAX_AGE);if(crash){try{writeCrashLog(records.map(record=>record.notified?record:{...record,notified:!0}),path14)}catch{}return crash}}function clearCrashLog(path14=crashLogPath()){try{rmSync4(path14,{force:!0})}catch{}}var RADIUS_PROVIDER_ID="radius",ENV_RADIUS_GATEWAY="PI_RADIUS_GATEWAY",RADIUS_MCP_URL=`${normalizeRadiusGatewayUrl(DEFAULT_RADIUS_GATEWAY)}/mcp`;function getRadiusGatewayUrl(){return normalizeRadiusGatewayUrl(process.env[ENV_RADIUS_GATEWAY]??DEFAULT_RADIUS_GATEWAY)}var BUILTIN_SLASH_COMMANDS=[{name:"tasks",description:"View and manage session tasks"},{name:"settings",description:"Open settings menu"},{name:"model",description:"Select model (opens selector UI)",argumentHint:"<provider/model>"},{name:"tree",description:"Navigate session tree (switch branches)"},{name:"thinking",description:"Set thinking level",argumentHint:"<level>"},{name:"scoped-models",description:"Enable/disable models for Ctrl+P cycling"},{name:"export",description:"Export session (HTML default, or specify path: .html/.jsonl)"},{name:"import",description:"Import and resume a session from a JSONL file"},{name:"share",description:"Share session as a secret GitHub gist"},{name:"bug",description:"Report a bug to the Pi developers",argumentHint:"<description>"},{name:"copy",description:"Copy last agent message to clipboard"},{name:"name",description:"Set session display name"},{name:"session",description:"Show session info and stats"},{name:"changelog",description:"Show changelog entries"},{name:"hotkeys",description:"Show all keyboard shortcuts"},{name:"fork",description:"Create a new fork from a previous user message"},{name:"clone",description:"Duplicate the current session at the current position"},{name:"trust",description:"Save project trust decision for future sessions"},{name:"login",description:"Configure provider authentication",argumentHint:"<provider>"},{name:"logout",description:"Remove provider authentication"},{name:"new",description:"Start a new session"},{name:"compact",description:"Manually compact the session context"},{name:"resume",description:"Resume a different session"},{name:"reload",description:"Reload keybindings, extensions, skills, prompts, themes, and context files"},{name:"quit",description:`Quit ${APP_NAME}`}];import path10 from"node:path";import{existsSync as existsSync22,readFileSync as readFileSync19}from"fs";var GITHUB_REPO="earendil-works/pi",CHANGELOG_LINK_BASE_PATH="packages/coding-agent",LEGACY_REPO_RE=/^https:\/\/github\.com\/(?:badlogic|earendil-works)\/pi-mono(?=\/|$)/,URL_SCHEME_RE=/^[a-z][a-z0-9+.-]*:/i,INLINE_MARKDOWN_LINK_RE=/(!?\[[^\]\n]+\]\()([^\s)]+)((?:\s+[^)]*)?\))/g;function entryVersion(entry){return`${entry.major}.${entry.minor}.${entry.patch}`}function normalizeTag(version2){let versionString=typeof version2=="string"?version2:entryVersion(version2);return versionString.startsWith("v")?versionString:`v${versionString}`}function splitLocalTarget(target){let hashIndex=target.indexOf("#"),beforeHash=hashIndex===-1?target:target.slice(0,hashIndex),fragment=hashIndex===-1?"":target.slice(hashIndex),queryIndex=beforeHash.indexOf("?");return queryIndex===-1?{fragment,pathPart:beforeHash,query:""}:{fragment,pathPart:beforeHash.slice(0,queryIndex),query:beforeHash.slice(queryIndex)}}function normalizePathPart(value){return value.replaceAll("\\","/")}function resolveRepositoryPath(targetPath){let normalizedTarget=normalizePathPart(targetPath),joined=normalizedTarget.startsWith("/")?path10.posix.normalize(normalizedTarget.replace(/^\/+/,"")):path10.posix.normalize(path10.posix.join(CHANGELOG_LINK_BASE_PATH,normalizedTarget));if(!(joined==="."||joined.startsWith("../")||joined===".."))return joined}function isDirectoryTarget(originalPath,repositoryPath){return originalPath.endsWith("/")?!0:!path10.posix.basename(repositoryPath).includes(".")}function normalizeChangelogLinkTarget(target,tag){let canonicalTarget=target.replace(LEGACY_REPO_RE,`https://github.com/${GITHUB_REPO}`),repoUrl=`https://github.com/${GITHUB_REPO}`;for(let route2 of["blob","tree"])for(let branch of["main","master"]){let floatingRefPrefix=`${repoUrl}/${route2}/${branch}/`;canonicalTarget.startsWith(floatingRefPrefix)&&(canonicalTarget=`${repoUrl}/${route2}/${tag}/${canonicalTarget.slice(floatingRefPrefix.length)}`)}if(canonicalTarget.startsWith("#")||canonicalTarget.startsWith("//")||URL_SCHEME_RE.test(canonicalTarget))return canonicalTarget;let{fragment,pathPart,query}=splitLocalTarget(canonicalTarget);if(!pathPart)return canonicalTarget;let repositoryPath=resolveRepositoryPath(pathPart);if(!repositoryPath)return canonicalTarget;let route=isDirectoryTarget(pathPart,repositoryPath)?"tree":"blob";return`https://github.com/${GITHUB_REPO}/${route}/${tag}/${encodeURI(repositoryPath)}${query}${fragment}`}function normalizeChangelogLinks(markdown,version2){let tag=normalizeTag(version2);return markdown.replace(INLINE_MARKDOWN_LINK_RE,(_match,prefix,target,suffix)=>`${prefix}${normalizeChangelogLinkTarget(target,tag)}${suffix}`)}function parseChangelog(changelogPath){if(!existsSync22(changelogPath))return[];try{let lines=readFileSync19(changelogPath,"utf-8").split(`
|
|
@@ -1755,7 +1755,13 @@ ${codeSpan(styledWarning)}
|
|
|
1755
1755
|
`)}
|
|
1756
1756
|
`}).join("")}}var CORAL2=rgbColor(228,138,122),BLUE2=rgbColor(79,142,179),YELLOW2=rgbColor(234,182,93),RESET="\x1B[0m";function piLogoLines(){let mode=theme.getColorMode(),fg=color2=>foregroundAnsi(color2,mode),top=`${fg(CORAL2)}${backgroundAnsi(BLUE2,mode)}\u2580${RESET}${fg(CORAL2)}\u2580\u2588${RESET} `,bottom=`${fg(BLUE2)}\u2588\u2580${RESET} ${fg(YELLOW2)}\u2588${RESET}`;return[top,bottom]}function supportsPiLogo(){return!isAppleTerminalSession()}function piWordmark(){let mode=theme.getColorMode();return`${foregroundAnsi(CORAL2,mode)}P${RESET}${foregroundAnsi(YELLOW2,mode)}i${RESET}`}var RADIUS_COLORS=["#4d9abf","#83ccd2","#f1be57","#f09082"].map(hex=>parseColor(hex)),CHARS_PER_COLOR=4,CHARS_PER_SECOND=10,ANIMATION_FRAME_MS=50;function radiusShimmer(text2,elapsedMs){let mode=theme.getColorMode(),cycle=RADIUS_COLORS.length*CHARS_PER_COLOR,offset=elapsedMs/1e3*CHARS_PER_SECOND,result2="",index3=0;for(let char of text2){let position=((index3-offset)%cycle+cycle)%cycle,band=Math.floor(position/CHARS_PER_COLOR),t=position/CHARS_PER_COLOR-band,amount=t*t*(3-2*t),from=RADIUS_COLORS[band],to=RADIUS_COLORS[(band+1)%RADIUS_COLORS.length];result2+=foregroundAnsi(mixColors(from,to,amount,"srgb"),mode)+char,index3++}return`${result2}\x1B[39m`}var RadiusLoginMenuComponent=class extends ExtensionSelectorComponent{constructor(tui,title,options,radiusOption,onSelect,onCancel){super(title,options,option=>{this.stopAnimation(),onSelect(option)},()=>{this.stopAnimation(),onCancel()}),this.animationStart=performance.now(),this.animating=!1,this.radiusOption=radiusOption,this.animationTimer=setInterval(()=>{this.animating&&tui.requestRender()},ANIMATION_FRAME_MS),this.animationTimer.unref?.()}render(width){let lines=super.render(width),{label,text:text2}=this.radiusOption,selectedLine=new Text(theme.fg("accent","\u2192 ")+theme.fg("accent",label),1,0).render(width)[0],index3=selectedLine===void 0?-1:lines.indexOf(selectedLine);if(this.animating=index3>=0,this.animating){let shimmer=radiusShimmer(text2,performance.now()-this.animationStart),animatedLine=theme.fg("accent","\u2192 ")+shimmer+label.slice(text2.length);lines[index3]=new Text(animatedLine,1,0).render(width)[0]??""}return lines}stopAnimation(){clearInterval(this.animationTimer),this.animationTimer=void 0,this.animating=!1}dispose(){this.stopAnimation(),super.dispose()}};function createLoginMenuSelector(tui,title,options,radiusOption,onSelect,onCancel){return new RadiusLoginMenuComponent(tui,title,options,radiusOption,onSelect,onCancel)}function isEnabled2(enabledIds,id){return enabledIds===null||enabledIds.includes(id)}function normalizeEnabled(result2,allIds){return result2.length===allIds.length&&result2.every(id=>allIds.includes(id))?null:result2}function toggle(enabledIds,allIds,id){if(enabledIds===null)return allIds.filter(modelId=>modelId!==id);let index3=enabledIds.indexOf(id);return index3>=0?[...enabledIds.slice(0,index3),...enabledIds.slice(index3+1)]:normalizeEnabled([...enabledIds,id],allIds)}function enableAll(enabledIds,allIds,targetIds){if(enabledIds===null)return null;let targets=targetIds??allIds,result2=[...enabledIds];for(let id of targets)result2.includes(id)||result2.push(id);return normalizeEnabled(result2,allIds)}function clearAll(enabledIds,allIds,targetIds){if(enabledIds===null)return targetIds?allIds.filter(id=>!targetIds.includes(id)):[];let targets=new Set(targetIds??enabledIds);return enabledIds.filter(id=>!targets.has(id))}function move(enabledIds,id,delta){if(enabledIds===null)return null;let list2=[...enabledIds],index3=list2.indexOf(id);if(index3<0)return list2;let newIndex=index3+delta;if(newIndex<0||newIndex>=list2.length)return list2;let result2=[...list2];return[result2[index3],result2[newIndex]]=[result2[newIndex],result2[index3]],result2}function getSortedIds(enabledIds,allIds){if(enabledIds===null)return allIds;let enabledSet=new Set(enabledIds);return[...enabledIds,...allIds.filter(id=>!enabledSet.has(id))]}var ScopedModelsSelectorComponent=class extends Container{get focused(){return this._focused}set focused(value){this._focused=value,this.searchInput.focused=value}constructor(config,callbacks){super(),this.modelsById=new Map,this.allIds=[],this.enabledIds=null,this.filteredItems=[],this.selectedIndex=0,this._focused=!1,this.maxVisible=8,this.isDirty=!1,this.callbacks=callbacks;for(let model of config.allModels){let fullId=`${model.provider}/${model.id}`;this.modelsById.set(fullId,model),this.allIds.push(fullId)}this.enabledIds=config.enabledModelIds===null?null:[...config.enabledModelIds],this.filteredItems=this.buildItems(),this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",theme.bold("Model Configuration")),0,0)),this.addChild(new Text(theme.fg("muted",`Session-only. ${keyDisplayText("app.models.save")} to save to settings.`),0,0)),this.addChild(new Spacer(1)),this.searchInput=new Input,this.addChild(this.searchInput),this.addChild(new Spacer(1)),this.listContainer=new Container,this.addChild(this.listContainer),this.addChild(new Spacer(1)),config.refreshStatus&&(this.refreshStatusText=new Text(theme.fg("muted",` ${config.refreshStatus}`),0,0),this.addChild(this.refreshStatusText)),this.footerText=new Text(this.getFooterText(),0,0),this.addChild(this.footerText),this.addChild(new DynamicBorder),this.updateList()}updateModels(models,enabledModelIds){let selectedId=this.filteredItems[this.selectedIndex]?.fullId;enabledModelIds!==void 0&&(this.enabledIds=enabledModelIds===null?null:[...enabledModelIds]),this.modelsById.clear(),this.allIds=[];for(let model of models){let fullId=`${model.provider}/${model.id}`;this.modelsById.set(fullId,model),this.allIds.push(fullId)}this.refresh();let refreshedIndex=selectedId?this.filteredItems.findIndex(item=>item.fullId===selectedId):-1;refreshedIndex>=0&&(this.selectedIndex=refreshedIndex,this.updateList())}setRefreshStatus(message,kind){this.refreshStatusText?.setText(theme.fg(kind,` ${message}`))}buildItems(){return getSortedIds(this.enabledIds,this.allIds).map(id=>({fullId:id,model:this.modelsById.get(id),enabled:isEnabled2(this.enabledIds,id)}))}getFooterText(){let enabledCount=this.enabledIds?.filter(id=>this.modelsById.has(id)).length??this.allIds.length,unavailableCount=this.enabledIds?.filter(id=>!this.modelsById.has(id)).length??0,countText=this.enabledIds===null?"all enabled":`${enabledCount}/${this.allIds.length} enabled${unavailableCount?` \xB7 ${unavailableCount} unavailable`:""}`,parts=[`${keyDisplayText("tui.select.confirm")} toggle`,`${keyDisplayText("app.models.enableAll")} all`,`${keyDisplayText("app.models.clearAll")} clear`,`${keyDisplayText("app.models.toggleProvider")} provider`,`${keyDisplayText("app.models.reorderUp")}/${keyDisplayText("app.models.reorderDown")} reorder`,`${keyDisplayText("app.models.save")} save`,countText];return this.isDirty?theme.fg("dim",` ${parts.join(" \xB7 ")} `)+theme.fg("warning","(unsaved)"):theme.fg("dim",` ${parts.join(" \xB7 ")}`)}refresh(){let query=this.searchInput.getValue(),items=this.buildItems();this.filteredItems=query?fuzzyFilter(items,query,item=>item.model?getModelSearchText({id:item.model.id,provider:item.model.provider,name:item.model.name}):item.fullId):items,this.selectedIndex=Math.min(this.selectedIndex,Math.max(0,this.filteredItems.length-1)),this.updateList(),this.footerText.setText(this.getFooterText())}notifyChange(){this.callbacks.onChange(this.enabledIds===null?null:[...this.enabledIds])}updateList(){if(this.listContainer.clear(),this.filteredItems.length===0){this.listContainer.addChild(new Text(theme.fg("muted"," No matching models"),0,0));return}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 item=this.filteredItems[i],isSelected2=i===this.selectedIndex,prefix=isSelected2?theme.fg("accent","\u2192 "):" ",id=item.model?.id??item.fullId,styledId=item.model?id:theme.strikethrough(id),modelText2=isSelected2?theme.fg("accent",styledId):styledId,providerBadge=theme.fg("muted",item.model?` [${item.model.provider}]`:" [unavailable]"),status=item.model&&item.enabled?theme.fg("accent","\u2713 "):" ";this.listContainer.addChild(new Text(`${prefix}${status}${modelText2}${providerBadge}`,0,0))}if((startIndex>0||endIndex<this.filteredItems.length)&&this.listContainer.addChild(new Text(theme.fg("muted",` (${this.selectedIndex+1}/${this.filteredItems.length})`),0,0)),this.filteredItems.length>0){let selected=this.filteredItems[this.selectedIndex];this.listContainer.addChild(new Spacer(1)),this.listContainer.addChild(new Text(theme.fg("muted",` ${selected.model?`Model Name: ${selected.model.name}`:"Model unavailable"}`),0,0))}}handleInput(data){let kb=getKeybindings();if(kb.matches(data,"tui.select.up")){if(this.filteredItems.length===0)return;this.selectedIndex=this.selectedIndex===0?this.filteredItems.length-1:this.selectedIndex-1,this.updateList();return}if(kb.matches(data,"tui.select.down")){if(this.filteredItems.length===0)return;this.selectedIndex=this.selectedIndex===this.filteredItems.length-1?0:this.selectedIndex+1,this.updateList();return}let reorderUp=kb.matches(data,"app.models.reorderUp"),reorderDown=kb.matches(data,"app.models.reorderDown");if(reorderUp||reorderDown){if(this.enabledIds===null)return;let item=this.filteredItems[this.selectedIndex];if(item&&isEnabled2(this.enabledIds,item.fullId)){let delta=reorderUp?-1:1,newIndex=this.enabledIds.indexOf(item.fullId)+delta;newIndex>=0&&newIndex<this.enabledIds.length&&(this.enabledIds=move(this.enabledIds,item.fullId,delta),this.isDirty=!0,this.selectedIndex+=delta,this.refresh(),this.notifyChange())}return}if(kb.matches(data,"tui.select.confirm")){let item=this.filteredItems[this.selectedIndex];item&&(this.enabledIds=toggle(this.enabledIds,this.allIds,item.fullId),this.isDirty=!0,this.refresh(),this.notifyChange());return}if(kb.matches(data,"app.models.enableAll")){let targetIds=this.searchInput.getValue()?this.filteredItems.map(i=>i.fullId):void 0;this.enabledIds=enableAll(this.enabledIds,this.allIds,targetIds),this.isDirty=!0,this.refresh(),this.notifyChange();return}if(kb.matches(data,"app.models.clearAll")){let targetIds=this.searchInput.getValue()?this.filteredItems.map(i=>i.fullId):void 0;this.enabledIds=clearAll(this.enabledIds,this.allIds,targetIds),this.isDirty=!0,this.refresh(),this.notifyChange();return}if(kb.matches(data,"app.models.toggleProvider")){let item=this.filteredItems[this.selectedIndex];if(item?.model){let provider=item.model.provider,providerIds=this.allIds.filter(id=>this.modelsById.get(id).provider===provider),allEnabled=providerIds.every(id=>isEnabled2(this.enabledIds,id));this.enabledIds=allEnabled?clearAll(this.enabledIds,this.allIds,providerIds):enableAll(this.enabledIds,this.allIds,providerIds),this.isDirty=!0,this.refresh(),this.notifyChange()}return}if(kb.matches(data,"app.models.save")){this.callbacks.onPersist(this.enabledIds===null?null:[...this.enabledIds]),this.isDirty=!1,this.footerText.setText(this.getFooterText());return}if(matchesKey(data,Key.ctrl("c"))){this.searchInput.getValue()?(this.searchInput.setValue(""),this.refresh()):this.callbacks.onCancel();return}if(matchesKey(data,Key.escape)){this.callbacks.onCancel();return}this.searchInput.handleInput(data),this.refresh()}getSearchInput(){return this.searchInput}};var StatusIndicator=class extends Loader{constructor(kind,ui,spinnerColorFn,messageColorFn,message,indicator){super(ui,spinnerColorFn,messageColorFn,message,indicator),this.kind=kind}renderInBorder(width){let line=super.render(width+2)[1]??"";return truncateToWidth(line.startsWith(" ")?line.slice(1).trimEnd():line.trimEnd(),width,"")}renderSpinnerInBorder(width){return truncateToWidth(this.getRenderedIndicator(),width,"")}dispose(){this.stop()}},WorkingStatusIndicator=class extends StatusIndicator{constructor(ui,message,indicator,colorFn){super("working",ui,colorFn??(text2=>theme.fg("accent",text2)),colorFn??(text2=>theme.fg("muted",text2)),message,indicator)}},RetryStatusIndicator=class extends StatusIndicator{constructor(ui,attempt2,maxAttempts,delayMs){let retryMessage=seconds=>`Retrying (${attempt2}/${maxAttempts}) in ${seconds}s... (${keyText("app.interrupt")} to cancel)`;super("retry",ui,spinner=>theme.fg("warning",spinner),text2=>theme.fg("muted",text2),retryMessage(Math.ceil(delayMs/1e3))),this.countdown=new CountdownTimer(delayMs,ui,seconds=>{this.setMessage(retryMessage(seconds))},()=>{this.countdown=void 0})}dispose(){this.countdown?.dispose(),this.countdown=void 0,super.dispose()}},CompactionStatusIndicator=class extends StatusIndicator{constructor(ui,reason){let cancelHint=`(${keyText("app.interrupt")} to cancel)`,label=reason==="manual"?`Compacting context... ${cancelHint}`:`${reason==="overflow"?"Context overflow detected, ":""}Auto-compacting... ${cancelHint}`;super("compaction",ui,spinner=>theme.fg("accent",spinner),text2=>theme.fg("muted",text2),label)}},BranchSummaryStatusIndicator=class extends StatusIndicator{constructor(ui){super("branchSummary",ui,spinner=>theme.fg("accent",spinner),text2=>theme.fg("muted",text2),`Summarizing branch... (${keyText("app.interrupt")} to cancel)`)}},IdleStatus=class{invalidate(){}render(width){let emptyLine=" ".repeat(width);return[emptyLine,emptyLine]}};var ThemedText=class extends Text{constructor(build,paddingX=1,paddingY=1){super("",paddingX,paddingY),this.stale=!0,this.build=build}invalidate(){super.invalidate(),this.stale=!0}render(width){return this.stale&&(this.stale=!1,this.setText(this.build())),super.render(width)}};function formatDecision(trustPath,decision){if(decision===null)return"none";let label=decision.decision?"trusted":"untrusted";return trustPath!==void 0&&decision.path!==trustPath?`${label} (inherited from ${decision.path})`:`${label} (${decision.path})`}var TrustSelectorComponent=class extends Container{constructor(options){super(),this.savedDecision=options.savedDecision,this.trustOptions=getProjectTrustOptions(options.cwd),this.selectedIndex=Math.max(0,this.trustOptions.findIndex(option=>this.isSavedOption(option))),this.onSelectCallback=options.onSelect,this.onCancelCallback=options.onCancel,this.addChild(new DynamicBorder),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("accent",theme.bold("Project trust")),1,0)),this.addChild(new Text(theme.fg("muted",options.cwd),1,0)),this.addChild(new Spacer(1)),this.addChild(new Text(theme.fg("muted",`Saved decision: ${formatDecision(this.trustOptions[0]?.savedPath,options.savedDecision)}`),1,0)),this.addChild(new Text(theme.fg("muted",`Current session: ${options.projectTrusted?"trusted":"untrusted"}`),1,0)),this.addChild(new Spacer(1)),this.listContainer=new Container,this.addChild(this.listContainer),this.addChild(new Spacer(1)),this.addChild(new Text(rawKeyHint("\u2191\u2193","navigate")+" "+keyHint("tui.select.confirm","save")+" "+keyHint("tui.select.cancel","cancel"),1,0)),this.addChild(new Spacer(1)),this.addChild(new DynamicBorder),this.updateList()}isSavedOption(option){return option.savedPath!==void 0&&this.savedDecision?.decision===option.trusted&&this.savedDecision.path===option.savedPath}updateList(){this.listContainer.clear();for(let i=0;i<this.trustOptions.length;i++){let option=this.trustOptions[i];if(!option)continue;let isSelected2=i===this.selectedIndex,currentMarker=this.isSavedOption(option)?theme.fg("accent","\u2713 "):" ",prefix=isSelected2?theme.fg("accent","\u2192 "):" ",label=isSelected2?theme.fg("accent",option.label):theme.fg("text",option.label);this.listContainer.addChild(new Text(`${prefix}${currentMarker}${label}`,1,0))}}handleInput(keyData){let kb=getKeybindings();if(kb.matches(keyData,"tui.select.up")||keyData==="k")this.selectedIndex=Math.max(0,this.selectedIndex-1),this.updateList();else if(kb.matches(keyData,"tui.select.down")||keyData==="j")this.selectedIndex=Math.min(this.trustOptions.length-1,this.selectedIndex+1),this.updateList();else if(kb.matches(keyData,"tui.select.confirm")||keyData===`
|
|
1757
1757
|
`){let selected=this.trustOptions[this.selectedIndex];selected&&this.onSelectCallback({trusted:selected.trusted,updates:selected.updates})}else kb.matches(keyData,"tui.select.cancel")&&this.onCancelCallback()}};var HIDDEN_BUILTIN_COMMANDS=["debug","arminsayshi","dementedelves"],InteractiveEditorHost=class{constructor(options){this.submitHandlers=new Set,this.options=options}onSubmit(handler){return this.submitHandlers.add(handler),()=>this.submitHandlers.delete(handler)}getCursor(){return this.options.getEditor().getCursor?.()}onInput(handler){return this.options.addTerminalInputListener(data=>this.isEditorFocused()?handler(data):void 0)}isEditorFocused(){let editor=this.options.getEditor();return this.options.getFocusedComponent()===editor&&!this.options.hasOverlay()&&!editor.isShowingAutocomplete?.()}clear(){this.submitHandlers.clear()}classify(text2){if(text2.startsWith("!"))return"bash";if(!text2.startsWith("/"))return"prompt";let name=text2.slice(1).split(/\s/,1)[0];return BUILTIN_SLASH_COMMANDS.some(command=>command.name===name)||HIDDEN_BUILTIN_COMMANDS.includes(name)||this.options.isSessionCommand(name)?"command":"prompt"}intercept(text2,mode){if(mode==="steer"&&this.declinedFollowUp===text2||this.submitHandlers.size===0)return!1;let event={text:text2,mode,kind:this.classify(text2)};for(let handler of this.submitHandlers)try{let result2=handler(event);if(!result2?.handled)continue;return this.options.setEditorText(result2.editorText??""),this.options.requestRender(),!0}catch(error){return this.options.setEditorText(text2),this.options.showError(`Editor submit handler failed: ${error instanceof Error?error.message:String(error)}`),!0}return mode==="followUp"&&(this.declinedFollowUp=text2,queueMicrotask(()=>{this.declinedFollowUp=void 0})),!1}};var TERMINAL_QUERY_TIMEOUT_MS=100;function requestTerminalColors(ui,apply){let query;try{query=ui.queryTerminalColors({timeoutMs:TERMINAL_QUERY_TIMEOUT_MS,onLateReply:apply})}catch{query=Promise.resolve({})}return query.then(apply,()=>apply({}))}function sameRgb(a,b2){return a===b2||a!==void 0&&b2!==void 0&&a.r===b2.r&&a.g===b2.g&&a.b===b2.b}function sameTerminalColors(a,b2){return!sameRgb(a.foreground,b2.foreground)||!sameRgb(a.background,b2.background)?!1:a.palette===b2.palette?!0:!a.palette||!b2.palette||a.palette.length!==b2.palette.length?!1:a.palette.every((color2,index3)=>sameRgb(color2,b2.palette?.[index3]))}var InteractiveThemeController=class{constructor(ui,options){this.autoSyncEnabled=!1,this.terminalColorQuery=Promise.resolve(),this.ui=ui,this.getSettingsManager=options.getSettingsManager,this.showError=options.showError,this.onChanged=options.onChanged,this.currentThemeSetting=options.initialThemeSetting,this.activeThemeName=this.resolveThemeName(),markTerminalColorsPending(),initTheme(this.activeThemeName,!0),this.bindTerminalColorSchemeListener()}rebindTui(){this.terminalColorSchemeUnsubscribe?.(),this.bindTerminalColorSchemeListener(),this.ui.setTerminalColorSchemeNotifications(this.autoSyncEnabled)}applyFromSettings(){let themeSetting=this.getThemeSetting(),themeName=this.resolveThemeName();this.setAutoSync(parseAutoThemeSetting(themeSetting)!==void 0||themeName===SYSTEM_THEME_NAME),this.applyThemeName(themeName,themeSetting!==void 0),this.queryTerminalColors()}waitForTerminalColors(){return this.terminalColorQuery}getThemeSelection(){return this.currentThemeSetting??this.getSettingsManager().getThemeSetting()??this.activeThemeName}setThemeName(themeName,showError=!1){this.setAutoSync(themeName===SYSTEM_THEME_NAME);let result2=this.applyThemeName(themeName,showError);return result2.success&&(this.currentThemeSetting=themeName),result2}setThemeSetting(themeSetting){this.currentThemeSetting=themeSetting,this.applyFromSettings()}setThemeInstance(themeInstance){return this.setAutoSync(!1),setThemeInstance(themeInstance),this.activeThemeName="<in-memory>",this.notifyChanged(),{success:!0}}preview(themeSettingOrName){let themeName=resolveThemeSetting(themeSettingOrName,getTerminalTheme())??this.activeThemeName;themeName&&setTheme(themeName,!0).success&&(this.ui.invalidate(),this.ui.requestRender())}disableAutoSync(){this.setAutoSync(!1)}dispose(){this.setAutoSync(!1),this.terminalColorSchemeUnsubscribe?.(),this.terminalColorSchemeUnsubscribe=void 0}getTerminalTheme(){return getTerminalTheme()}getThemeSetting(){return this.currentThemeSetting??this.getSettingsManager().getThemeSetting()}resolveThemeName(){return resolveThemeSetting(this.getThemeSetting(),getTerminalTheme())??SYSTEM_THEME_NAME}applyThemeName(themeName,showError=!1){let result2=setTheme(themeName,!0);return this.activeThemeName=result2.success?themeName:SYSTEM_THEME_NAME,this.notifyChanged(),!result2.success&&showError&&this.showError(`Failed to load theme "${themeName}": ${result2.error}
|
|
1758
|
-
Fell back to the system theme.`),result2}queryTerminalColors(){this.terminalColorQuery=requestTerminalColors(this.ui,colors=>this.applyTerminalColors(colors))}applyTerminalColors(reported){let previous=this.terminalColors,next={foreground:reported.foreground??previous?.foreground,background:reported.background??previous?.background,palette:reported.palette??previous?.palette};previous&&sameTerminalColors(previous,next)||(this.terminalColors=next,setTerminalColors(next),this.reapplyForTerminal(),this.ui.invalidate(),this.ui.requestRender())}reapplyForTerminal(){if(this.activeThemeName==="<in-memory>")return;let themeName=this.resolveThemeName();(themeName===SYSTEM_THEME_NAME||themeName!==this.activeThemeName)&&this.applyThemeName(themeName)}setAutoSync(enabled){this.autoSyncEnabled!==enabled&&(this.autoSyncEnabled=enabled,this.ui.setTerminalColorSchemeNotifications(enabled))}bindTerminalColorSchemeListener(){this.terminalColorSchemeUnsubscribe=this.ui.onTerminalColorSchemeChange(terminalTheme=>this.applyTerminalColorSchemeChange(terminalTheme))}applyTerminalColorSchemeChange(terminalTheme){if(!this.autoSyncEnabled)return;let previous=getTerminalTheme();setTerminalColorScheme(terminalTheme),getTerminalTheme()!==previous&&this.reapplyForTerminal(),this.queryTerminalColors()}notifyChanged(){this.ui.invalidate(),this.onChanged()}};function disposeAll(components){for(let component of components){let disposable=component;typeof disposable.dispose=="function"&&disposable.dispose()}}var ToolChatContainer=class extends Container{render(width){let previous;for(let child of this.children){if(child instanceof ToolExecutionComponent){let{afterTool,afterOther}=toolStyle.gap;child.setLeadingGap(previous instanceof ToolExecutionComponent?afterTool:afterOther)}previous=child}return super.render(width)}clear(){disposeAll(this.children),super.clear()}},PendingToolMap=class extends Map{clear(){disposeAll(this.values()),super.clear()}};function disposeChatRows(chat){disposeAll(chat.children)}function createInteractiveTui(options){let terminal=options.terminal??new ProcessTerminal;if(options.tuiMode==="fullscreen"){let styleSearchMatch=text2=>theme.bg("searchMatchBg",theme.fg("searchMatchText",text2));return new TuiAltScreen(terminal,options.showHardwareCursor,options.logDirectory,{searchMatchStyle:text2=>theme.underline(styleSearchMatch(text2)),searchCurrentMatchStyle:text2=>theme.bold(theme.inverse(styleSearchMatch(text2))),searchNavigationButtonStyle:(text2,hovered)=>hovered?theme.underline(text2):text2,scrollToEndIndicator:()=>{let shortcut=keyDisplayText("tui.altScreen.bottom"),label=` \u2193 Jump to latest message${shortcut?` \xB7 ${shortcut}`:""} `;return theme.bg("selectedBg",theme.fg("text",label))},openUrl:openBrowser,onRightClickPaste:options.onRightClickPaste,copyOnSelect:options.fullscreenCopyOnSelect,wheelScrollLines:options.fullscreenWheelScrollLines??"auto",copySelection:async text2=>{try{return await copyToClipboard(text2),!0}catch(error){return error instanceof Error?error.message:String(error)}}})}return new TuiMainScreen(terminal,options.showHardwareCursor,options.logDirectory)}function createInteractiveTuiReference(getTui){return new Proxy({},{get:(_target,property)=>{let tui=getTui(),value=Reflect.get(tui,property,tui);if(typeof value!="function")return value;let methodTui=tui,method=value;return(...args)=>{let currentTui=getTui();if(currentTui!==methodTui){let currentMethod=Reflect.get(currentTui,property,currentTui);if(typeof currentMethod!="function")throw new TypeError(`TUI property ${String(property)} is not callable`);methodTui=currentTui,method=currentMethod}return Reflect.apply(method,methodTui,args)}},set:(_target,property,value)=>{let tui=getTui();return Reflect.set(tui,property,value,tui)},has:(_target,property)=>Reflect.has(getTui(),property),getPrototypeOf:()=>Reflect.getPrototypeOf(getTui())})}function isWorkingStatusEditor(editor){return"embedWorkingStatus"in editor&&editor.embedWorkingStatus===!0&&"setWorkingStatusIndicator"in editor&&typeof editor.setWorkingStatusIndicator=="function"}function isExpandable(obj){return typeof obj=="object"&&obj!==null&&"setExpanded"in obj&&typeof obj.setExpanded=="function"}var ExpandableText=class extends ThemedText{constructor(getCollapsedText,getExpandedText,expanded=!1,paddingX=0,paddingY=0){let state2={expanded};super(()=>state2.expanded?getExpandedText():getCollapsedText(),paddingX,paddingY),this.state=state2}setExpanded(expanded){this.state.expanded=expanded,this.invalidate()}},BuiltInHeader=class extends ExpandableText{handleMouse(event){if(!(event.type!=="click"||event.y>1||event.x<1||event.x>4||!this.onLogoClick))return this.onLogoClick(event.screenX-event.x+1,event.screenY-event.y),{handled:!0}}};function isCustomSessionEntry(item){return"type"in item&&item.type==="custom"}function isCompactionCostNotice(item){return"type"in item&&item.type==="compaction_cost"}function isUsageSessionEntry(item){return"type"in item&&item.type==="usage"}var DEAD_TERMINAL_ERROR_CODES=new Set(["EIO","EPIPE","ENOTCONN"]);function isDeadTerminalError(error){if(!error||typeof error!="object"||!("code"in error))return!1;let code=error.code;return code!==void 0&&DEAD_TERMINAL_ERROR_CODES.has(code)}function formatCrashExtensionHint(extensionMatches){let matches=Array.isArray(extensionMatches)?extensionMatches.filter(match2=>typeof match2=="string"&&match2.length>0):[];if(matches.length===0)return;let quoted=matches.map(match2=>`\`${match2}\``),labels=quoted.length===1?quoted[0]:quoted.length===2?quoted.join(" and "):`${quoted.slice(0,-1).join(", ")}, and ${quoted[quoted.length-1]}`,noun=matches.length===1?"extension":"extensions",pronoun=matches.length===1?"it":"them";return`A stack frame came from loaded ${noun} ${labels}, which may be involved. Try disabling ${pronoun} with \`${APP_NAME} config\`, or run \`${APP_NAME} -ne\` to confirm.`}var ANTHROPIC_SUBSCRIPTION_AUTH_WARNING="Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";function isAnthropicSubscriptionAuthKey(apiKey){return typeof apiKey=="string"&&apiKey.startsWith("sk-ant-oat")}function isUnknownModel(model){return!!model&&model.provider==="unknown"&&model.id==="unknown"&&model.api==="unknown"}function quoteIfNeeded(value){return value.length>0&&!/[^a-zA-Z0-9_\-./~:@]/.test(value)?value:`'${value.replace(/'/g,"'\\''")}'`}function formatResumeCommand(sessionManager){if(!process.stdout.isTTY||!sessionManager.isPersisted())return;let sessionFile=sessionManager.getSessionFile();if(!sessionFile||!fs8.existsSync(sessionFile))return;let args=[APP_NAME];return sessionManager.usesDefaultSessionDir()||args.push("--session-dir",quoteIfNeeded(sessionManager.getSessionDir())),args.push("--session",sessionManager.getSessionId()),args.join(" ")}function hasDefaultModelProvider(providerId){return providerId in defaultModelPerProvider}function llamaCppPostLoginGuidance(actionLabel,loadedModelCount){return loadedModelCount===0?`${actionLabel}. No llama.cpp models are loaded. Use /llama to load a model, then /model to select it.`:`${actionLabel}. Use /model to select a loaded llama.cpp model, or /llama to manage models.`}var RADIUS_LOGIN_INTRO="Radius is a service crafted for Pi by the builders of Pi, Earendil Works",AUTH_TYPE_ORDER={oauth:0,api_key:1};function createFuzzyAutocompleteItems(items,prefix,getSearchText,toAutocompleteItem){let filtered=fuzzyFilter(items,prefix,getSearchText);return filtered.length===0?null:filtered.map(toAutocompleteItem)}function getLoginProviderCompletionOptions(providerOptions){let byId=new Map;for(let provider of providerOptions){let existing=byId.get(provider.id);if(existing){existing.authTypes.includes(provider.authType)||(existing.authTypes.push(provider.authType),existing.authTypes.sort((a,b2)=>AUTH_TYPE_ORDER[a]-AUTH_TYPE_ORDER[b2]));continue}byId.set(provider.id,{id:provider.id,name:provider.name,authTypes:[provider.authType],subscription:provider.subscription})}return Array.from(byId.values()).sort((a,b2)=>a.name.localeCompare(b2.name))}function getLoginProviderSearchText(provider){let authTypes=provider.authTypes.map(authType=>`${authType} ${formatAuthSelectorProviderType(authType,provider.subscription)}`).join(" ");return`${provider.id} ${provider.name} ${authTypes}`}function formatLoginProviderCompletionDescription(provider){let authTypes=provider.authTypes.map(authType=>formatAuthSelectorProviderType(authType,provider.subscription)).join("/");return provider.name===provider.id?authTypes:`${provider.name} \xB7 ${authTypes}`}var InteractiveMode=class _InteractiveMode{get session(){return this.runtimeHost.session}get agent(){return this.session.agent}get sessionManager(){return this.session.sessionManager}get settingsManager(){return this.session.settingsManager}constructor(runtimeHost,options={}){this.autocompleteProviderWrappers=[],this.isInitialized=!1,this.pendingUserInputs=[],this.activeStatusIndicator=void 0,this.activeWorkingIndicatorEmbedded=!1,this.idleStatus=new IdleStatus,this.workingMessage=void 0,this.workingVisible=!0,this.workingIndicatorOptions=void 0,this.defaultWorkingMessage="Working",this.defaultHiddenThinkingLabel="Thinking...",this.hiddenThinkingLabel=this.defaultHiddenThinkingLabel,this.lastSigintTime=0,this.lastEscapeTime=0,this.changelogMarkdown=void 0,this.startupNoticesShown=!1,this.anthropicSubscriptionWarningShown=!1,this.lastStatusSpacer=void 0,this.lastStatusText=void 0,this.lastStatusMessage="",this.managedToolStatusStarted=!1,this.streamingComponent=void 0,this.entriesRenderedByBoundaryCompaction=new Set,this.streamingMessage=void 0,this.pendingTools=new PendingToolMap,this.editorHost=new InteractiveEditorHost({isSessionCommand:name=>this.session.extensionRunner.getCommand(name)!==void 0||this.session.promptTemplates.some(template=>template.name===name)||this.skillCommands.has(name),getEditor:()=>this.editor,getFocusedComponent:()=>this.renderer.getFocusedComponent(),hasOverlay:()=>this.ui.hasOverlay(),addTerminalInputListener:handler=>this.addExtensionTerminalInputListener(handler),setEditorText:text2=>this.editor.setText(text2),requestRender:()=>this.ui.requestRender(),showError:message=>this.showError(message)}),this.toolOutputExpanded=!1,this.hideThinkingBlock=!1,this.outputPad=1,this.mermaidMarkdownTransformer=createMermaidMarkdownTransformer({getMode:()=>this.settingsManager.getMermaidRenderingMode(),theme}),this.skillCommands=new Map,this.signalCleanupHandlers=[],this.isBashMode=!1,this.bashComponent=void 0,this.pendingBashComponents=[],this.compactionQueuedMessages=[],this.shutdownRequested=!1,this.bugReportHintShown=!1,this.extensionSelector=void 0,this.extensionInput=void 0,this.extensionEditor=void 0,this.extensionTerminalInputSubscriptions=new Set,this.extensionWidgetsAbove=new Map,this.extensionWidgetsBelow=new Map,this.customFooter=void 0,this.builtInHeader=void 0,this.customHeader=void 0,this.onRightClickPaste=()=>{this.handleRightClickPaste()},this.isShuttingDown=!1,this.runtimeHost=runtimeHost,setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());let tuiMode=options.tuiMode??this.settingsManager.getTuiMode();this.options={...options,tuiMode},this.autoTrustOnReloadCwd=options.autoTrustOnReloadCwd,this.runtimeHost.setBeforeSessionInvalidate(()=>{this.tasksUI?.dispose(),this.resetExtensionUI()}),this.runtimeHost.setRebindSession(async()=>{await this.rebindCurrentSession({renderBeforeBind:!0}),this.themeController.applyFromSettings()}),this.version=VERSION,this.renderer=createInteractiveTui({tuiMode,showHardwareCursor:this.settingsManager.getShowHardwareCursor(),logDirectory:getAgentDir(),terminal:options.terminal,onRightClickPaste:this.onRightClickPaste,fullscreenCopyOnSelect:this.settingsManager.getFullscreenCopyOnSelect(),fullscreenWheelScrollLines:this.settingsManager.getFullscreenWheelScrollLines()}),this.ui=createInteractiveTuiReference(()=>this.renderer),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.headerContainer=new Container,this.loadedResourcesContainer=new Container,this.chatContainer=new ToolChatContainer,this.documentContainer=new Container,this.documentContainer.addChild(this.headerContainer),this.documentContainer.addChild(this.loadedResourcesContainer),this.documentContainer.addChild(this.chatContainer),this.pendingMessagesContainer=new Container,this.statusContainer=new Container,this.widgetContainerAbove=new Container,this.widgetContainerBelow=new Container,this.keybindings=KeybindingsManager2.create(),setKeybindings(this.keybindings);let editorPaddingX=this.settingsManager.getEditorPaddingX(),autocompleteMaxVisible=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor=new CustomEditor(this.ui,getEditorTheme(),this.keybindings,{paddingX:editorPaddingX,autocompleteMaxVisible,embedWorkingStatus:!0}),this.editor=this.defaultEditor,this.editorContainer=new Container,this.editorContainer.addChild(this.editor),this.footerDataProvider=new FooterDataProvider(this.sessionManager.getCwd()),this.footer=new FooterComponent(this.session,this.footerDataProvider),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.footerContainer=new Container,this.footerContainer.addChild(this.footer),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),this.outputPad=this.settingsManager.getOutputPad(),setRegisteredThemes(this.session.resourceLoader.getThemes().themes),this.themeController=new InteractiveThemeController(this.ui,{getSettingsManager:()=>this.settingsManager,showError:message=>this.showError(message),onChanged:()=>this.updateEditorBorderColor(),initialThemeSetting:options.initialThemeSetting})}getAutocompleteSourceTag(sourceInfo){if(!sourceInfo||sourceInfo.source==="builtin")return;let scopePrefix=sourceInfo.scope==="user"?"u":sourceInfo.scope==="project"?"p":"t",source=sourceInfo.source.trim();if(source==="auto"||source==="local"||source==="cli")return scopePrefix;if(source.startsWith("npm:"))return`${scopePrefix}:${source}`;let gitSource=parseGitUrl(source);if(gitSource){let ref=gitSource.ref?`@${gitSource.ref}`:"";return`${scopePrefix}:git:${gitSource.host}/${gitSource.path}${ref}`}return scopePrefix}prefixAutocompleteDescription(description,sourceInfo){let sourceTag=this.getAutocompleteSourceTag(sourceInfo);return sourceTag?description?`[${sourceTag}] ${description}`:`[${sourceTag}]`:description}getBuiltInCommandConflictDiagnostics(extensionRunner){let builtinNames=new Set(BUILTIN_SLASH_COMMANDS.map(command=>command.name));return extensionRunner.getRegisteredCommands().filter(command=>builtinNames.has(command.name)).map(command=>({type:"warning",message:command.invocationName===command.name?`Extension command '/${command.name}' conflicts with built-in interactive command. Skipping in autocomplete.`:`Extension command '/${command.name}' conflicts with built-in interactive command. Available as '/${command.invocationName}'.`,path:command.sourceInfo.path}))}createBaseAutocompleteProvider(){let slashCommands=BUILTIN_SLASH_COMMANDS.map(command=>({name:command.name,description:command.description,...command.argumentHint&&{argumentHint:command.argumentHint}})),modelCommand=slashCommands.find(command=>command.name==="model");modelCommand&&(modelCommand.getArgumentCompletions=prefix=>{let models=this.session.scopedModels.length>0?this.session.scopedModels.map(s=>s.model):this.session.modelRuntime.getAvailableSnapshot();if(models.length===0)return null;let items=models.map(m2=>({id:m2.id,provider:m2.provider,name:m2.name,label:`${m2.provider}/${m2.id}`}));return createFuzzyAutocompleteItems(items,prefix,getModelSearchText,item=>({value:item.label,label:item.id,description:item.provider}))});let thinkingCommand=slashCommands.find(command=>command.name==="thinking");thinkingCommand&&(thinkingCommand.getArgumentCompletions=prefix=>createFuzzyAutocompleteItems(this.session.getAvailableThinkingLevels(),prefix,level=>level,level=>({value:level,label:level})));let loginCommand=slashCommands.find(command=>command.name==="login");loginCommand&&(loginCommand.getArgumentCompletions=prefix=>{let providers=getLoginProviderCompletionOptions(this.getLoginProviderOptions());return createFuzzyAutocompleteItems(providers,prefix,getLoginProviderSearchText,provider=>({value:provider.id,label:provider.id,description:formatLoginProviderCompletionDescription(provider)}))});let templateCommands=this.session.promptTemplates.map(cmd=>({name:cmd.name,description:this.prefixAutocompleteDescription(cmd.description,cmd.sourceInfo),...cmd.argumentHint&&{argumentHint:cmd.argumentHint}})),builtinCommandNames=new Set(slashCommands.map(c=>c.name)),extensionCommands=this.session.extensionRunner.getRegisteredCommands().filter(cmd=>!builtinCommandNames.has(cmd.name)).map(cmd=>({name:cmd.invocationName,description:this.prefixAutocompleteDescription(cmd.description,cmd.sourceInfo),getArgumentCompletions:cmd.getArgumentCompletions}));this.skillCommands.clear();let skillCommandList=[];if(this.settingsManager.getEnableSkillCommands())for(let skill of this.session.resourceLoader.getSkills().skills){let commandName=`skill:${skill.name}`;this.skillCommands.set(commandName,skill.filePath),skillCommandList.push({name:commandName,description:this.prefixAutocompleteDescription(skill.description,skill.sourceInfo)})}return new CombinedAutocompleteProvider([...slashCommands,...templateCommands,...extensionCommands,...skillCommandList],this.sessionManager.getCwd(),this.fdPath)}setupAutocompleteProvider(){let provider=this.createBaseAutocompleteProvider(),triggerCharacters=[];for(let wrapProvider of this.autocompleteProviderWrappers)provider=wrapProvider(provider),triggerCharacters.push(...provider.triggerCharacters??[]);triggerCharacters.length>0&&(provider.triggerCharacters=[...new Set(triggerCharacters)]),this.autocompleteProvider=provider,this.defaultEditor.setAutocompleteProvider(provider),this.editor!==this.defaultEditor&&this.editor.setAutocompleteProvider?.(provider)}showStartupNoticesIfNeeded(){if(!this.startupNoticesShown&&(this.startupNoticesShown=!0,!!this.changelogMarkdown)){if(this.chatContainer.children.length>0&&this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new DynamicBorder),this.settingsManager.getCollapseChangelog()){let versionMatch=this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/),condensedText=`Updated to v${versionMatch?versionMatch[1]:this.version}. Use ${theme.bold("/changelog")} to view full changelog.`;this.chatContainer.addChild(new Text(condensedText,1,0))}else this.chatContainer.addChild(new ThemedText(()=>theme.bold(theme.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Markdown(this.changelogMarkdown.trim(),1,0,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new Spacer(1));this.chatContainer.addChild(new DynamicBorder)}}mountInteractiveTui(tui,components){for(let component of components)tui.addChild(component);if(isViewportTUI(tui)){if(!this.fullscreenLayoutRoot)throw new Error("Fullscreen layout is not initialized");tui.setLayoutRoot(this.fullscreenLayoutRoot)}}stopInteractiveTui(fullscreenExitOutput){if(this.renderer.mode==="fullscreen"&&fullscreenExitOutput==="transcript"){for(;this.renderer.hasOverlayEntries;)this.renderer.hideOverlay();this.switchTuiMode("regular",!1,!1),this.renderer.renderNow()}this.ui.stop({preserveScreen:this.renderer.mode==="fullscreen"})}switchTuiMode(mode,restoreProgress=!0,startRenderer=!0){let previousUi=this.renderer;if(mode===previousUi.mode)return!0;if(previousUi.hasOverlayEntries)return!1;let components=[...previousUi.children],focus=previousUi.getFocusedComponent(),terminal=previousUi.terminal,showHardwareCursor=previousUi.getShowHardwareCursor(),clearOnShrink=previousUi.getClearOnShrink(),onDebug=previousUi.onDebug;previousUi instanceof TuiMainScreen&&(this.mainScreenRenderState=previousUi.captureRenderState()),previousUi.stop({preserveScreen:!0}),previousUi.setFocus(null),previousUi.clear(),isViewportTUI(previousUi)&&previousUi.setLayoutRoot(void 0);let nextUi=createInteractiveTui({tuiMode:mode,showHardwareCursor,logDirectory:getAgentDir(),terminal,onRightClickPaste:this.onRightClickPaste,fullscreenCopyOnSelect:this.settingsManager.getFullscreenCopyOnSelect(),fullscreenWheelScrollLines:this.settingsManager.getFullscreenWheelScrollLines()});return nextUi.setClearOnShrink(clearOnShrink),nextUi.onDebug=onDebug,nextUi instanceof TuiMainScreen&&this.mainScreenRenderState&&nextUi.restoreRenderState(this.mainScreenRenderState),this.renderer=nextUi,this.options.tuiMode=mode,this.mountInteractiveTui(nextUi,components),nextUi.invalidate(),nextUi.setFocus(focus),startRenderer&&(nextUi.start(),this.themeController.rebindTui(),this.rebindExtensionTerminalInputListeners(),restoreProgress&&this.settingsManager.getShowTerminalProgress()&&(this.session.isStreaming||this.session.isCompacting)&&terminal.setProgress(!0)),!0}async init(){if(this.isInitialized)return;if(this.registerSignalHandlers(),this.changelogMarkdown=this.getChangelogForDisplay(),this.session.scopedModels.length>0&&this.shouldShowStartupDetails()){let modelList=this.session.scopedModels.map(sm=>{let thinkingStr=sm.thinkingLevel?`:${sm.thinkingLevel}`:"";return`${sm.model.id}${thinkingStr}`}).join(", "),cycleKeys=this.keybindings.getKeys("app.model.cycleForward"),cycleHint=cycleKeys.length>0?theme.fg("muted",` (${formatKeyText(cycleKeys.join("/"),{capitalize:!0})} to cycle)`):"";console.log(theme.fg("dim",`Model scope: ${modelList}${cycleHint}`))}this.renderWidgets();let viewport=createChatViewport({document:this.documentContainer,pendingMessages:this.pendingMessagesContainer,status:this.statusContainer,widgetsAbove:this.widgetContainerAbove,editor:this.editorContainer,widgetsBelow:this.widgetContainerBelow,footer:this.footerContainer,scrollbar:this.settingsManager.getFullscreenScrollbar(),scrollbarTrackStyle:text2=>theme.fg("scrollbarTrack",text2),scrollbarThumbStyle:text2=>theme.fg("scrollbarThumb",text2)});if(this.transcriptScrollView=viewport.transcript,this.fullscreenLayoutRoot=viewport.root,this.mountInteractiveTui(this.renderer,[this.documentContainer,this.pendingMessagesContainer,this.statusContainer,this.widgetContainerAbove,this.editorContainer,this.widgetContainerBelow,this.footerContainer]),this.defaultEditor.onAction("app.clear",()=>this.handleCtrlC()),this.defaultEditor.onCtrlD=()=>this.handleCtrlD(),this.defaultEditor.onSubmit=text2=>this.handleStartupSubmit(text2),this.ui.setFocus(this.editor),this.ui.start(),this.isInitialized=!0,this.ensurePngTranscoder(),this.themeController.applyFromSettings(),await this.themeController.waitForTerminalColors(),this.shouldShowStartupHeader()){let showDetails=this.shouldShowStartupDetails(),showLogo=supportsPiLogo(),withLogo=hints=>{if(!showLogo)return`${piWordmark()} ${theme.fg("dim",`v${this.version}`)}
|
|
1758
|
+
Fell back to the system theme.`),result2}queryTerminalColors(){this.terminalColorQuery=requestTerminalColors(this.ui,colors=>this.applyTerminalColors(colors))}applyTerminalColors(reported){let previous=this.terminalColors,next={foreground:reported.foreground??previous?.foreground,background:reported.background??previous?.background,palette:reported.palette??previous?.palette};previous&&sameTerminalColors(previous,next)||(this.terminalColors=next,setTerminalColors(next),this.reapplyForTerminal(),this.ui.invalidate(),this.ui.requestRender())}reapplyForTerminal(){if(this.activeThemeName==="<in-memory>")return;let themeName=this.resolveThemeName();(themeName===SYSTEM_THEME_NAME||themeName!==this.activeThemeName)&&this.applyThemeName(themeName)}setAutoSync(enabled){this.autoSyncEnabled!==enabled&&(this.autoSyncEnabled=enabled,this.ui.setTerminalColorSchemeNotifications(enabled))}bindTerminalColorSchemeListener(){this.terminalColorSchemeUnsubscribe=this.ui.onTerminalColorSchemeChange(terminalTheme=>this.applyTerminalColorSchemeChange(terminalTheme))}applyTerminalColorSchemeChange(terminalTheme){if(!this.autoSyncEnabled)return;let previous=getTerminalTheme();setTerminalColorScheme(terminalTheme),getTerminalTheme()!==previous&&this.reapplyForTerminal(),this.queryTerminalColors()}notifyChanged(){this.ui.invalidate(),this.onChanged()}};function disposeAll(components){for(let component of components){let disposable=component;typeof disposable.dispose=="function"&&disposable.dispose()}}var ToolChatContainer=class extends Container{render(width){let previous,previousHeight=0;for(let child of this.children){if(child instanceof ToolExecutionComponent){child.setLeadingGap(0);let lines=child.render(width),start=lines.findIndex(line=>stripAnsi(line).trim().length>0);if(start===-1)continue;let{afterTool,afterMultilineTool,afterOther}=toolStyle.gap;child.setLeadingGap(previous instanceof ToolExecutionComponent?previousHeight>1?afterMultilineTool:afterTool:afterOther),previousHeight=lines.length-start}previous=child}return super.render(width)}clear(){disposeAll(this.children),super.clear()}},PendingToolMap=class extends Map{clear(){disposeAll(this.values()),super.clear()}};function disposeChatRows(chat){disposeAll(chat.children)}function createInteractiveTui(options){let terminal=options.terminal??new ProcessTerminal;if(options.tuiMode==="fullscreen"){let styleSearchMatch=text2=>theme.bg("searchMatchBg",theme.fg("searchMatchText",text2));return new TuiAltScreen(terminal,options.showHardwareCursor,options.logDirectory,{searchMatchStyle:text2=>theme.underline(styleSearchMatch(text2)),searchCurrentMatchStyle:text2=>theme.bold(theme.inverse(styleSearchMatch(text2))),searchNavigationButtonStyle:(text2,hovered)=>hovered?theme.underline(text2):text2,scrollToEndIndicator:()=>{let shortcut=keyDisplayText("tui.altScreen.bottom"),label=` \u2193 Jump to latest message${shortcut?` \xB7 ${shortcut}`:""} `;return theme.bg("selectedBg",theme.fg("text",label))},openUrl:openBrowser,onRightClickPaste:options.onRightClickPaste,copyOnSelect:options.fullscreenCopyOnSelect,wheelScrollLines:options.fullscreenWheelScrollLines??"auto",copySelection:async text2=>{try{return await copyToClipboard(text2),!0}catch(error){return error instanceof Error?error.message:String(error)}}})}return new TuiMainScreen(terminal,options.showHardwareCursor,options.logDirectory)}function createInteractiveTuiReference(getTui){return new Proxy({},{get:(_target,property)=>{let tui=getTui(),value=Reflect.get(tui,property,tui);if(typeof value!="function")return value;let methodTui=tui,method=value;return(...args)=>{let currentTui=getTui();if(currentTui!==methodTui){let currentMethod=Reflect.get(currentTui,property,currentTui);if(typeof currentMethod!="function")throw new TypeError(`TUI property ${String(property)} is not callable`);methodTui=currentTui,method=currentMethod}return Reflect.apply(method,methodTui,args)}},set:(_target,property,value)=>{let tui=getTui();return Reflect.set(tui,property,value,tui)},has:(_target,property)=>Reflect.has(getTui(),property),getPrototypeOf:()=>Reflect.getPrototypeOf(getTui())})}function isWorkingStatusEditor(editor){return"embedWorkingStatus"in editor&&editor.embedWorkingStatus===!0&&"setWorkingStatusIndicator"in editor&&typeof editor.setWorkingStatusIndicator=="function"}function isExpandable(obj){return typeof obj=="object"&&obj!==null&&"setExpanded"in obj&&typeof obj.setExpanded=="function"}var ExpandableText=class extends ThemedText{constructor(getCollapsedText,getExpandedText,expanded=!1,paddingX=0,paddingY=0){let state2={expanded};super(()=>state2.expanded?getExpandedText():getCollapsedText(),paddingX,paddingY),this.state=state2}setExpanded(expanded){this.state.expanded=expanded,this.invalidate()}},BuiltInHeader=class extends ExpandableText{handleMouse(event){if(!(event.type!=="click"||event.y>1||event.x<1||event.x>4||!this.onLogoClick))return this.onLogoClick(event.screenX-event.x+1,event.screenY-event.y),{handled:!0}}};function isCustomSessionEntry(item){return"type"in item&&item.type==="custom"}function isCompactionCostNotice(item){return"type"in item&&item.type==="compaction_cost"}function isUsageSessionEntry(item){return"type"in item&&item.type==="usage"}function hotkeysTaskSection(display){let detach=KEYBINDINGS["app.tasks.detach"],detachSelected=KEYBINDINGS["app.tasks.detachSelected"];return`
|
|
1759
|
+
**Tasks**
|
|
1760
|
+
| Key | Action |
|
|
1761
|
+
|-----|--------|
|
|
1762
|
+
| \`${display("app.tasks.detach")}\` | ${detach.description} |
|
|
1763
|
+
| \`${display("app.tasks.detachSelected")}\` | ${detachSelected.description} (while /tasks is open) |
|
|
1764
|
+
`}var DEAD_TERMINAL_ERROR_CODES=new Set(["EIO","EPIPE","ENOTCONN"]);function isDeadTerminalError(error){if(!error||typeof error!="object"||!("code"in error))return!1;let code=error.code;return code!==void 0&&DEAD_TERMINAL_ERROR_CODES.has(code)}function formatCrashExtensionHint(extensionMatches){let matches=Array.isArray(extensionMatches)?extensionMatches.filter(match2=>typeof match2=="string"&&match2.length>0):[];if(matches.length===0)return;let quoted=matches.map(match2=>`\`${match2}\``),labels=quoted.length===1?quoted[0]:quoted.length===2?quoted.join(" and "):`${quoted.slice(0,-1).join(", ")}, and ${quoted[quoted.length-1]}`,noun=matches.length===1?"extension":"extensions",pronoun=matches.length===1?"it":"them";return`A stack frame came from loaded ${noun} ${labels}, which may be involved. Try disabling ${pronoun} with \`${APP_NAME} config\`, or run \`${APP_NAME} -ne\` to confirm.`}var ANTHROPIC_SUBSCRIPTION_AUTH_WARNING="Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage. Disable this warning in /settings.";function isAnthropicSubscriptionAuthKey(apiKey){return typeof apiKey=="string"&&apiKey.startsWith("sk-ant-oat")}function isUnknownModel(model){return!!model&&model.provider==="unknown"&&model.id==="unknown"&&model.api==="unknown"}function quoteIfNeeded(value){return value.length>0&&!/[^a-zA-Z0-9_\-./~:@]/.test(value)?value:`'${value.replace(/'/g,"'\\''")}'`}function formatResumeCommand(sessionManager){if(!process.stdout.isTTY||!sessionManager.isPersisted())return;let sessionFile=sessionManager.getSessionFile();if(!sessionFile||!fs8.existsSync(sessionFile))return;let args=[APP_NAME];return sessionManager.usesDefaultSessionDir()||args.push("--session-dir",quoteIfNeeded(sessionManager.getSessionDir())),args.push("--session",sessionManager.getSessionId()),args.join(" ")}function hasDefaultModelProvider(providerId){return providerId in defaultModelPerProvider}function llamaCppPostLoginGuidance(actionLabel,loadedModelCount){return loadedModelCount===0?`${actionLabel}. No llama.cpp models are loaded. Use /llama to load a model, then /model to select it.`:`${actionLabel}. Use /model to select a loaded llama.cpp model, or /llama to manage models.`}var RADIUS_LOGIN_INTRO="Radius is a service crafted for Pi by the builders of Pi, Earendil Works",AUTH_TYPE_ORDER={oauth:0,api_key:1};function createFuzzyAutocompleteItems(items,prefix,getSearchText,toAutocompleteItem){let filtered=fuzzyFilter(items,prefix,getSearchText);return filtered.length===0?null:filtered.map(toAutocompleteItem)}function getLoginProviderCompletionOptions(providerOptions){let byId=new Map;for(let provider of providerOptions){let existing=byId.get(provider.id);if(existing){existing.authTypes.includes(provider.authType)||(existing.authTypes.push(provider.authType),existing.authTypes.sort((a,b2)=>AUTH_TYPE_ORDER[a]-AUTH_TYPE_ORDER[b2]));continue}byId.set(provider.id,{id:provider.id,name:provider.name,authTypes:[provider.authType],subscription:provider.subscription})}return Array.from(byId.values()).sort((a,b2)=>a.name.localeCompare(b2.name))}function getLoginProviderSearchText(provider){let authTypes=provider.authTypes.map(authType=>`${authType} ${formatAuthSelectorProviderType(authType,provider.subscription)}`).join(" ");return`${provider.id} ${provider.name} ${authTypes}`}function formatLoginProviderCompletionDescription(provider){let authTypes=provider.authTypes.map(authType=>formatAuthSelectorProviderType(authType,provider.subscription)).join("/");return provider.name===provider.id?authTypes:`${provider.name} \xB7 ${authTypes}`}var InteractiveMode=class _InteractiveMode{get session(){return this.runtimeHost.session}get agent(){return this.session.agent}get sessionManager(){return this.session.sessionManager}get settingsManager(){return this.session.settingsManager}constructor(runtimeHost,options={}){this.autocompleteProviderWrappers=[],this.isInitialized=!1,this.pendingUserInputs=[],this.activeStatusIndicator=void 0,this.activeWorkingIndicatorEmbedded=!1,this.idleStatus=new IdleStatus,this.workingMessage=void 0,this.workingVisible=!0,this.workingIndicatorOptions=void 0,this.defaultWorkingMessage="Working",this.defaultHiddenThinkingLabel="Thinking...",this.hiddenThinkingLabel=this.defaultHiddenThinkingLabel,this.lastSigintTime=0,this.lastEscapeTime=0,this.changelogMarkdown=void 0,this.startupNoticesShown=!1,this.anthropicSubscriptionWarningShown=!1,this.lastStatusSpacer=void 0,this.lastStatusText=void 0,this.lastStatusMessage="",this.managedToolStatusStarted=!1,this.streamingComponent=void 0,this.entriesRenderedByBoundaryCompaction=new Set,this.streamingMessage=void 0,this.pendingTools=new PendingToolMap,this.editorHost=new InteractiveEditorHost({isSessionCommand:name=>this.session.extensionRunner.getCommand(name)!==void 0||this.session.promptTemplates.some(template=>template.name===name)||this.skillCommands.has(name),getEditor:()=>this.editor,getFocusedComponent:()=>this.renderer.getFocusedComponent(),hasOverlay:()=>this.ui.hasOverlay(),addTerminalInputListener:handler=>this.addExtensionTerminalInputListener(handler),setEditorText:text2=>this.editor.setText(text2),requestRender:()=>this.ui.requestRender(),showError:message=>this.showError(message)}),this.toolOutputExpanded=!1,this.hideThinkingBlock=!1,this.outputPad=1,this.mermaidMarkdownTransformer=createMermaidMarkdownTransformer({getMode:()=>this.settingsManager.getMermaidRenderingMode(),theme}),this.skillCommands=new Map,this.signalCleanupHandlers=[],this.isBashMode=!1,this.bashComponent=void 0,this.pendingBashComponents=[],this.compactionQueuedMessages=[],this.shutdownRequested=!1,this.bugReportHintShown=!1,this.extensionSelector=void 0,this.extensionInput=void 0,this.extensionEditor=void 0,this.extensionTerminalInputSubscriptions=new Set,this.extensionWidgetsAbove=new Map,this.extensionWidgetsBelow=new Map,this.customFooter=void 0,this.builtInHeader=void 0,this.customHeader=void 0,this.onRightClickPaste=()=>{this.handleRightClickPaste()},this.isShuttingDown=!1,this.runtimeHost=runtimeHost,setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());let tuiMode=options.tuiMode??this.settingsManager.getTuiMode();this.options={...options,tuiMode},this.autoTrustOnReloadCwd=options.autoTrustOnReloadCwd,this.runtimeHost.setBeforeSessionInvalidate(()=>{this.tasksUI?.dispose(),this.resetExtensionUI()}),this.runtimeHost.setRebindSession(async()=>{await this.rebindCurrentSession({renderBeforeBind:!0}),this.themeController.applyFromSettings()}),this.version=VERSION,this.renderer=createInteractiveTui({tuiMode,showHardwareCursor:this.settingsManager.getShowHardwareCursor(),logDirectory:getAgentDir(),terminal:options.terminal,onRightClickPaste:this.onRightClickPaste,fullscreenCopyOnSelect:this.settingsManager.getFullscreenCopyOnSelect(),fullscreenWheelScrollLines:this.settingsManager.getFullscreenWheelScrollLines()}),this.ui=createInteractiveTuiReference(()=>this.renderer),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.headerContainer=new Container,this.loadedResourcesContainer=new Container,this.chatContainer=new ToolChatContainer,this.documentContainer=new Container,this.documentContainer.addChild(this.headerContainer),this.documentContainer.addChild(this.loadedResourcesContainer),this.documentContainer.addChild(this.chatContainer),this.pendingMessagesContainer=new Container,this.statusContainer=new Container,this.widgetContainerAbove=new Container,this.widgetContainerBelow=new Container,this.keybindings=KeybindingsManager2.create(),setKeybindings(this.keybindings);let editorPaddingX=this.settingsManager.getEditorPaddingX(),autocompleteMaxVisible=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor=new CustomEditor(this.ui,getEditorTheme(),this.keybindings,{paddingX:editorPaddingX,autocompleteMaxVisible,embedWorkingStatus:!0}),this.editor=this.defaultEditor,this.editorContainer=new Container,this.editorContainer.addChild(this.editor),this.footerDataProvider=new FooterDataProvider(this.sessionManager.getCwd()),this.footer=new FooterComponent(this.session,this.footerDataProvider),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.footerContainer=new Container,this.footerContainer.addChild(this.footer),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),this.outputPad=this.settingsManager.getOutputPad(),setRegisteredThemes(this.session.resourceLoader.getThemes().themes),this.themeController=new InteractiveThemeController(this.ui,{getSettingsManager:()=>this.settingsManager,showError:message=>this.showError(message),onChanged:()=>this.updateEditorBorderColor(),initialThemeSetting:options.initialThemeSetting})}getAutocompleteSourceTag(sourceInfo){if(!sourceInfo||sourceInfo.source==="builtin")return;let scopePrefix=sourceInfo.scope==="user"?"u":sourceInfo.scope==="project"?"p":"t",source=sourceInfo.source.trim();if(source==="auto"||source==="local"||source==="cli")return scopePrefix;if(source.startsWith("npm:"))return`${scopePrefix}:${source}`;let gitSource=parseGitUrl(source);if(gitSource){let ref=gitSource.ref?`@${gitSource.ref}`:"";return`${scopePrefix}:git:${gitSource.host}/${gitSource.path}${ref}`}return scopePrefix}prefixAutocompleteDescription(description,sourceInfo){let sourceTag=this.getAutocompleteSourceTag(sourceInfo);return sourceTag?description?`[${sourceTag}] ${description}`:`[${sourceTag}]`:description}getBuiltInCommandConflictDiagnostics(extensionRunner){let builtinNames=new Set(BUILTIN_SLASH_COMMANDS.map(command=>command.name));return extensionRunner.getRegisteredCommands().filter(command=>builtinNames.has(command.name)).map(command=>({type:"warning",message:command.invocationName===command.name?`Extension command '/${command.name}' conflicts with built-in interactive command. Skipping in autocomplete.`:`Extension command '/${command.name}' conflicts with built-in interactive command. Available as '/${command.invocationName}'.`,path:command.sourceInfo.path}))}createBaseAutocompleteProvider(){let slashCommands=BUILTIN_SLASH_COMMANDS.map(command=>({name:command.name,description:command.description,...command.argumentHint&&{argumentHint:command.argumentHint}})),modelCommand=slashCommands.find(command=>command.name==="model");modelCommand&&(modelCommand.getArgumentCompletions=prefix=>{let models=this.session.scopedModels.length>0?this.session.scopedModels.map(s=>s.model):this.session.modelRuntime.getAvailableSnapshot();if(models.length===0)return null;let items=models.map(m2=>({id:m2.id,provider:m2.provider,name:m2.name,label:`${m2.provider}/${m2.id}`}));return createFuzzyAutocompleteItems(items,prefix,getModelSearchText,item=>({value:item.label,label:item.id,description:item.provider}))});let thinkingCommand=slashCommands.find(command=>command.name==="thinking");thinkingCommand&&(thinkingCommand.getArgumentCompletions=prefix=>createFuzzyAutocompleteItems(this.session.getAvailableThinkingLevels(),prefix,level=>level,level=>({value:level,label:level})));let loginCommand=slashCommands.find(command=>command.name==="login");loginCommand&&(loginCommand.getArgumentCompletions=prefix=>{let providers=getLoginProviderCompletionOptions(this.getLoginProviderOptions());return createFuzzyAutocompleteItems(providers,prefix,getLoginProviderSearchText,provider=>({value:provider.id,label:provider.id,description:formatLoginProviderCompletionDescription(provider)}))});let templateCommands=this.session.promptTemplates.map(cmd=>({name:cmd.name,description:this.prefixAutocompleteDescription(cmd.description,cmd.sourceInfo),...cmd.argumentHint&&{argumentHint:cmd.argumentHint}})),builtinCommandNames=new Set(slashCommands.map(c=>c.name)),extensionCommands=this.session.extensionRunner.getRegisteredCommands().filter(cmd=>!builtinCommandNames.has(cmd.name)).map(cmd=>({name:cmd.invocationName,description:this.prefixAutocompleteDescription(cmd.description,cmd.sourceInfo),getArgumentCompletions:cmd.getArgumentCompletions}));this.skillCommands.clear();let skillCommandList=[];if(this.settingsManager.getEnableSkillCommands())for(let skill of this.session.resourceLoader.getSkills().skills){let commandName=`skill:${skill.name}`;this.skillCommands.set(commandName,skill.filePath),skillCommandList.push({name:commandName,description:this.prefixAutocompleteDescription(skill.description,skill.sourceInfo)})}return new CombinedAutocompleteProvider([...slashCommands,...templateCommands,...extensionCommands,...skillCommandList],this.sessionManager.getCwd(),this.fdPath)}setupAutocompleteProvider(){let provider=this.createBaseAutocompleteProvider(),triggerCharacters=[];for(let wrapProvider of this.autocompleteProviderWrappers)provider=wrapProvider(provider),triggerCharacters.push(...provider.triggerCharacters??[]);triggerCharacters.length>0&&(provider.triggerCharacters=[...new Set(triggerCharacters)]),this.autocompleteProvider=provider,this.defaultEditor.setAutocompleteProvider(provider),this.editor!==this.defaultEditor&&this.editor.setAutocompleteProvider?.(provider)}showStartupNoticesIfNeeded(){if(!this.startupNoticesShown&&(this.startupNoticesShown=!0,!!this.changelogMarkdown)){if(this.chatContainer.children.length>0&&this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new DynamicBorder),this.settingsManager.getCollapseChangelog()){let versionMatch=this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/),condensedText=`Updated to v${versionMatch?versionMatch[1]:this.version}. Use ${theme.bold("/changelog")} to view full changelog.`;this.chatContainer.addChild(new Text(condensedText,1,0))}else this.chatContainer.addChild(new ThemedText(()=>theme.bold(theme.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new Spacer(1)),this.chatContainer.addChild(new Markdown(this.changelogMarkdown.trim(),1,0,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new Spacer(1));this.chatContainer.addChild(new DynamicBorder)}}mountInteractiveTui(tui,components){for(let component of components)tui.addChild(component);if(isViewportTUI(tui)){if(!this.fullscreenLayoutRoot)throw new Error("Fullscreen layout is not initialized");tui.setLayoutRoot(this.fullscreenLayoutRoot)}}stopInteractiveTui(fullscreenExitOutput){if(this.renderer.mode==="fullscreen"&&fullscreenExitOutput==="transcript"){for(;this.renderer.hasOverlayEntries;)this.renderer.hideOverlay();this.switchTuiMode("regular",!1,!1),this.renderer.renderNow()}this.ui.stop({preserveScreen:this.renderer.mode==="fullscreen"})}switchTuiMode(mode,restoreProgress=!0,startRenderer=!0){let previousUi=this.renderer;if(mode===previousUi.mode)return!0;if(previousUi.hasOverlayEntries)return!1;let components=[...previousUi.children],focus=previousUi.getFocusedComponent(),terminal=previousUi.terminal,showHardwareCursor=previousUi.getShowHardwareCursor(),clearOnShrink=previousUi.getClearOnShrink(),onDebug=previousUi.onDebug;previousUi instanceof TuiMainScreen&&(this.mainScreenRenderState=previousUi.captureRenderState()),previousUi.stop({preserveScreen:!0}),previousUi.setFocus(null),previousUi.clear(),isViewportTUI(previousUi)&&previousUi.setLayoutRoot(void 0);let nextUi=createInteractiveTui({tuiMode:mode,showHardwareCursor,logDirectory:getAgentDir(),terminal,onRightClickPaste:this.onRightClickPaste,fullscreenCopyOnSelect:this.settingsManager.getFullscreenCopyOnSelect(),fullscreenWheelScrollLines:this.settingsManager.getFullscreenWheelScrollLines()});return nextUi.setClearOnShrink(clearOnShrink),nextUi.onDebug=onDebug,nextUi instanceof TuiMainScreen&&this.mainScreenRenderState&&nextUi.restoreRenderState(this.mainScreenRenderState),this.renderer=nextUi,this.options.tuiMode=mode,this.mountInteractiveTui(nextUi,components),nextUi.invalidate(),nextUi.setFocus(focus),startRenderer&&(nextUi.start(),this.themeController.rebindTui(),this.rebindExtensionTerminalInputListeners(),restoreProgress&&this.settingsManager.getShowTerminalProgress()&&(this.session.isStreaming||this.session.isCompacting)&&terminal.setProgress(!0)),!0}async init(){if(this.isInitialized)return;if(this.registerSignalHandlers(),this.changelogMarkdown=this.getChangelogForDisplay(),this.session.scopedModels.length>0&&this.shouldShowStartupDetails()){let modelList=this.session.scopedModels.map(sm=>{let thinkingStr=sm.thinkingLevel?`:${sm.thinkingLevel}`:"";return`${sm.model.id}${thinkingStr}`}).join(", "),cycleKeys=this.keybindings.getKeys("app.model.cycleForward"),cycleHint=cycleKeys.length>0?theme.fg("muted",` (${formatKeyText(cycleKeys.join("/"),{capitalize:!0})} to cycle)`):"";console.log(theme.fg("dim",`Model scope: ${modelList}${cycleHint}`))}this.renderWidgets();let viewport=createChatViewport({document:this.documentContainer,pendingMessages:this.pendingMessagesContainer,status:this.statusContainer,widgetsAbove:this.widgetContainerAbove,editor:this.editorContainer,widgetsBelow:this.widgetContainerBelow,footer:this.footerContainer,scrollbar:this.settingsManager.getFullscreenScrollbar(),scrollbarTrackStyle:text2=>theme.fg("scrollbarTrack",text2),scrollbarThumbStyle:text2=>theme.fg("scrollbarThumb",text2)});if(this.transcriptScrollView=viewport.transcript,this.fullscreenLayoutRoot=viewport.root,this.mountInteractiveTui(this.renderer,[this.documentContainer,this.pendingMessagesContainer,this.statusContainer,this.widgetContainerAbove,this.editorContainer,this.widgetContainerBelow,this.footerContainer]),this.defaultEditor.onAction("app.clear",()=>this.handleCtrlC()),this.defaultEditor.onCtrlD=()=>this.handleCtrlD(),this.defaultEditor.onSubmit=text2=>this.handleStartupSubmit(text2),this.ui.setFocus(this.editor),this.ui.start(),this.isInitialized=!0,this.ensurePngTranscoder(),this.themeController.applyFromSettings(),await this.themeController.waitForTerminalColors(),this.shouldShowStartupHeader()){let showDetails=this.shouldShowStartupDetails(),showLogo=supportsPiLogo(),withLogo=hints=>{if(!showLogo)return`${piWordmark()} ${theme.fg("dim",`v${this.version}`)}
|
|
1759
1765
|
${hints}`;let[top,bottom]=piLogoLines();return`${top} ${theme.fg("dim",`v${this.version}`)}
|
|
1760
1766
|
${bottom} ${hints}`},hint=(keybinding,description)=>keyHint(keybinding,description),expandedInstructions=()=>[hint("app.interrupt","to interrupt"),hint("app.clear","to clear"),rawKeyHint(`${keyText("app.clear")} twice`,"to exit"),hint("app.exit","to exit (empty)"),hint("app.suspend","to suspend"),keyHint("tui.editor.deleteToLineEnd","to delete to end"),hint("app.thinking.cycle","to cycle thinking level"),rawKeyHint(`${keyText("app.model.cycleForward")}/${keyText("app.model.cycleBackward")}`,"to cycle models"),hint("app.model.select","to select model"),hint("app.tools.expand","to expand tools"),hint("app.thinking.toggle","to expand thinking"),hint("app.editor.external","for external editor"),rawKeyHint("/","for commands"),rawKeyHint("!","to run bash"),rawKeyHint("!!","to run bash (no context)"),hint("app.message.followUp","to queue follow-up"),hint("app.message.dequeue","to edit all queued messages"),hint("app.clipboard.pasteImage","to paste files on macOS, images, or text"),rawKeyHint("drop files","to attach")].join(`
|
|
1761
1767
|
`),compactInstructions=()=>[hint("app.interrupt","interrupt"),rawKeyHint(`${keyText("app.clear")}/${keyText("app.exit")}`,"clear/exit"),rawKeyHint("/","commands"),rawKeyHint("!","bash"),hint("app.tools.expand","more")].join(theme.fg("muted"," \xB7 ")),compactOnboarding=()=>theme.fg("dim",`Press ${keyText("app.tools.expand")} to show full startup help${showDetails?" and loaded resources":""}.`),onboarding=()=>theme.fg("dim","Pi can explain its own features and look up its docs. Ask it how to use or extend Pi."),header=new BuiltInHeader(()=>`${withLogo(compactInstructions())}
|
|
@@ -1869,7 +1875,7 @@ ${theme.fg("dim","Cache Re-billed:")} ${detail}`}}return info};this.chatContaine
|
|
|
1869
1875
|
| \`/\` | Slash commands |
|
|
1870
1876
|
| \`!\` | Run bash command |
|
|
1871
1877
|
| \`!!\` | Run bash command (excluded from context) |
|
|
1872
|
-
|
|
1878
|
+
`;hotkeys+=hotkeysTaskSection(action=>this.getAppKeyDisplay(action));let shortcuts=this.session.extensionRunner.getShortcuts(this.keybindings.getEffectiveConfig());if(shortcuts.size>0){hotkeys+=`
|
|
1873
1879
|
**Extensions**
|
|
1874
1880
|
| Key | Action |
|
|
1875
1881
|
|-----|--------|
|
|
@@ -1918,7 +1924,7 @@ ${notice}`,truncated:!0,totalPages,shownPages,truncatedChars:text2.length-kept.l
|
|
|
1918
1924
|
|
|
1919
1925
|
[DeepWiki ${action} output truncated to ${DEEPWIKI_OUTPUT_CHAR_BUDGET} characters. Use a focused page or question request for the omitted content.]`,keepLength=Math.max(0,DEEPWIKI_OUTPUT_CHAR_BUDGET-notice.length),kept=text2.slice(0,keepLength).trimEnd();return{text:`${kept}${notice}`,truncated:!0,truncatedChars:text2.length-kept.length}}async function executeDeepWiki(params,signal,onUpdate){let normalizedParams=normalizeDeepWikiParams(params),repoLabel2=Array.isArray(normalizedParams.repoName)?normalizedParams.repoName.join(", "):normalizedParams.repoName;onUpdate?.(buildResult(normalizedParams,`Querying DeepWiki for ${repoLabel2}...`));let response;try{response=await callDeepWiki(normalizedParams,signal)}catch(error){let message=error instanceof Error?error.message:String(error);throw new Error(`DeepWiki call failed: ${message}`)}let extra={toolName:response.toolName,outputLength:response.outputLength,...response.cacheHit?{cacheHit:!0}:{},...response.pageTitles?{pageCount:response.pageTitles.length,pageTitles:response.pageTitles}:{}},resultText=response.text;if(normalizedParams.action==="contents")if(normalizedParams.page!==void 0){let lookup=extractPage(response.text,normalizedParams.page);if(!lookup.found){if(lookup.titles.length===0)throw new Error(`page "${normalizedParams.page}" not found: this wiki has no page structure. Call contents without page.`);let list2=lookup.titles.slice(0,30).join("; "),more=lookup.titles.length>30?` \u2026 +${lookup.titles.length-30} more`:"";throw new Error(`page "${normalizedParams.page}" not found in ${repoLabel2} wiki (${lookup.titles.length} pages).
|
|
1920
1926
|
Available pages: ${list2}${more}`)}let truncation=truncateContentsByPages(lookup.found.text,CONTENTS_BODY_CHAR_BUDGET);resultText=truncation.text,extra.requestedPage=lookup.found.title,extra.pageIndex=lookup.found.index,truncation.truncated&&(extra.truncatedChars=truncation.truncatedChars)}else{let truncation=truncateContentsByPages(response.text,CONTENTS_BODY_CHAR_BUDGET);truncation.truncated&&(resultText=truncation.text,extra.shownPages=truncation.shownPages,extra.truncatedChars=truncation.truncatedChars)}let bounded=boundDeepWikiOutput(resultText,normalizedParams.action);return bounded.truncated&&(resultText=bounded.text,extra.truncatedChars=Math.max(extra.truncatedChars??0,bounded.truncatedChars)),buildResult(normalizedParams,resultText,extra)}function truncateText2(text2,maxLength,options){if(text2.length<=maxLength)return text2;if(options?.word){let prefix=text2.slice(0,maxLength-3),lastSpace=prefix.lastIndexOf(" ");if(lastSpace>=40)return`${prefix.slice(0,lastSpace)}...`}return`${text2.slice(0,maxLength-3)}...`}function singleLine2(text2){return typeof text2=="string"?text2.replace(/\s+/g," ").trim():""}function firstText(result2){for(let part of result2.content??[])if(part.type==="text"&&typeof part.text=="string")return part.text;return""}function firstContentLine(text2){return text2.split(`
|
|
1921
|
-
`).map(line=>line.trim()).find(line=>line.length>0)??"DeepWiki response"}function formatPageList(pages,maxItems=4){let shown=pages.slice(0,maxItems).map(singleLine2).join(", ");return pages.length>maxItems?`${shown}...`:shown}function pageTitlesFromResult(text2,details){if(Array.isArray(details?.pageTitles)){let titles=details.pageTitles.filter(title=>typeof title=="string");if(titles.length)return titles}if(Array.isArray(details?.sectionTitles)){let titles=details.sectionTitles.filter(title=>typeof title=="string");if(titles.length)return titles}let fromContent=extractContentPages(text2);return fromContent.length?fromContent:extractStructureSections(text2)}function summarizeStructure(text2,details){let pages=pageTitlesFromResult(text2,details);return pages.length===0?truncateText2(firstContentLine(text2),120):`${details?.pageCount??pages.length} pages \xB7 ${formatPageList(pages)}`}function summarizeContents(text2,details){if(typeof details?.requestedPage=="string"&&details.requestedPage.trim()){let position=details.pageIndex!==void 0&&details.pageCount?`${details.pageIndex}/${details.pageCount} \xB7 `:"",cut=details.truncatedChars?" (truncated)":"";return`Page ${position}${singleLine2(details.requestedPage)}${cut}`}let pages=pageTitlesFromResult(text2,details);if(details?.shownPages!==void 0){let total=details.pageCount??pages.length;return`Wiki \xB7 ${total>0?`${details.shownPages}/${total} pages`:"partial"} shown (truncated)`}return pages.length===0?"Wiki loaded":`Wiki \xB7 ${details?.pageCount??pages.length} pages`}function stripDeepWikiTail(text2){let tailIndex=text2.search(/\n(?:#+\s*)?(?:Wiki pages you might want to explore|View this search)/i);return tailIndex<0?text2:text2.slice(0,tailIndex)}function summarizeQuestion(text2){let cleaned=stripDeepWikiTail(text2).replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/[`*_]/g,"").replace(/\s+/g," ").trim();if(!cleaned)return"Answer ready";let sentenceMatch=cleaned.match(/^.{40,}?[.!?](?=\s|$)/);return truncateText2(sentenceMatch?.[0]??cleaned,140,{word:!0})}function summarizeCollapsed(text2,details){let summary;return details?.action==="structure"?summary=summarizeStructure(text2,details):details?.action==="contents"?summary=summarizeContents(text2,details):details?.action==="question"?summary=summarizeQuestion(text2):summary=truncateText2(firstContentLine(text2),120),truncateText2(singleLine2(summary),180,{word:!0})}function repoLabel(repoName){return Array.isArray(repoName)?repoName.length===0?"repo":repoName.length===1?repoName[0]:`${repoName.length} repos: ${repoName.slice(0,2).join(", ")}${repoName.length>2?"...":""}`:repoName??"repo"}function repoLabelForCall(repoName){if(Array.isArray(repoName))return repoLabel(repoName);if(typeof repoName=="string"){let trimmed=repoName.trim();if(trimmed.startsWith("["))try{let parsed=JSON.parse(trimmed);if(Array.isArray(parsed))return repoLabel(parsed)}catch{}return repoLabel(repoName)}return repoLabel(void 0)}function renderDeepWikiCall(args,theme2){let line=theme2.fg("toolTitle",theme2.bold(`${DEEPWIKI_LABEL} `));return line+=theme2.fg("muted",args.action),line+=` ${theme2.fg("accent",repoLabelForCall(args.repoName))}`,args.action==="question"&&args.question?line+=` ${theme2.fg("dim",truncateText2(singleLine2(args.question),64))}`:args.action==="contents"&&args.page!==void 0&&(line+=` ${theme2.fg("dim",truncateText2(singleLine2(String(args.page)),40))}`),new Text(line,0,0)}function markdownBlock(text2){let container=new Container;return container.addChild(new Spacer(1)),container.addChild(new Markdown(text2,1,0,getMarkdownTheme())),container}function renderDeepWikiResult(result2,options,theme2,isError,elapsedMs){if(options.isPartial){let repo=typeof result2.details?.repoName=="string"?singleLine2(result2.details.repoName):"",label=repo?`Querying ${repo}...`:"Querying...",suffix=elapsedMs!==void 0&&elapsedMs>=2e3?theme2.fg("muted",` (${Math.round(elapsedMs/1e3)}s)`):"";return new Text(`${theme2.fg("warning",label)}${suffix}`,0,0)}let text2=firstText(result2),errorMessage10=typeof result2.details?.errorMessage=="string"?result2.details.errorMessage:void 0;if(isError||errorMessage10){let line=truncateText2(errorMessage10??firstContentLine(text2),200);return new Text(theme2.fg("error",`failed \xB7 ${line}`),0,0)}if(!options.expanded){let summary=theme2.fg("toolOutput",summarizeCollapsed(text2,result2.details)),hint=`${theme2.fg("muted"," (")}${keyHint("app.tools.expand","to expand")}${theme2.fg("muted",")")}`;return new Text(`${summary}${hint}`,0,0)}return markdownBlock(text2)}function trackQueryElapsed(context,isPartial){let state2=context.state;if(isPartial)return state2.startedAt??=Date.now(),state2.refreshTimer===void 0&&(state2.refreshTimer=setTimeout(()=>{state2.refreshTimer=void 0,context.invalidate()},1e3),state2.refreshTimer.unref?.()),Date.now()-state2.startedAt;state2.refreshTimer!==void 0&&(clearTimeout(state2.refreshTimer),state2.refreshTimer=void 0)}function deepwiki(pi){pi.registerTool({name:DEEPWIKI_TOOL_NAME,label:DEEPWIKI_LABEL,description:DEEPWIKI_DESCRIPTION,promptSnippet:DEEPWIKI_PROMPT_SNIPPET,promptGuidelines:DEEPWIKI_PROMPT_GUIDELINES,parameters:DeepWikiParamsSchema,prepareArguments:normalizeDeepWikiParams,async execute(_toolCallId,params,signal,onUpdate){return executeDeepWiki(params,signal,onUpdate)},renderCall(args,theme2){return renderDeepWikiCall(args,theme2)},renderResult(result2,options,theme2,context){let elapsedMs=trackQueryElapsed(context,options.isPartial);return renderDeepWikiResult(result2,options,theme2,context.isError,elapsedMs)}})}function errorMessage6(payload,fallback){if(typeof payload!="object"||payload===null)return fallback;let error=payload.error;if(typeof error!="object"||error===null)return fallback;let message=error.message;return typeof message=="string"&&message?message:fallback}function isModelInfo(value){if(typeof value!="object"||value===null)return!1;let candidate=value;return typeof candidate.id=="string"&&typeof candidate.status?.value=="string"}function linkSignal(source,target){if(!source)return()=>{};if(source.aborted)return target.abort(source.reason),()=>{};let abort=()=>target.abort(source.reason);return source.addEventListener("abort",abort,{once:!0}),()=>source.removeEventListener("abort",abort)}function sleep4(ms,signal){return new Promise((resolve18,reject)=>{if(signal?.aborted){reject(signal.reason??new Error("Cancelled"));return}let abort=()=>{clearTimeout(timeout),reject(signal?.reason??new Error("Cancelled"))},timeout=setTimeout(()=>{signal?.removeEventListener("abort",abort),resolve18()},ms);signal?.addEventListener("abort",abort,{once:!0})})}function parseLoadProgress(data){if(typeof data!="object"||data===null)return;let progress=data.progress;if(typeof progress!="object"||progress===null)return;let value=progress,stage=typeof value.current=="string"?value.current:typeof value.stage=="string"?value.stage:void 0,stages=Array.isArray(value.stages)?value.stages.filter(entry=>typeof entry=="string"):[],stageRatio=typeof value.value=="number"?Math.max(0,Math.min(1,value.value)):void 0,ratio=stageRatio;if(stage&&stages.length>0){let index3=stages.indexOf(stage);index3>=0&&(ratio=(index3+(stageRatio??0))/stages.length)}return{message:stage?`Loading ${stage.replaceAll("_"," ")}`:"Loading model",ratio}}function parseDownloadProgress(data){if(typeof data!="object"||data===null)return;let nested=data.progress,files=typeof nested=="object"&&nested!==null?nested:data,done=0,total=0;for(let value of Object.values(files)){if(typeof value!="object"||value===null)continue;let entry=value;typeof entry.done!="number"||typeof entry.total!="number"||(done+=entry.done,total+=entry.total)}if(!(total<=0))return{message:"Downloading model",ratio:done/total,detail:`${formatBytes(done)} / ${formatBytes(total)}`}}function formatBytes(bytes){if(bytes<1024)return`${bytes} B`;let units=["KiB","MiB","GiB","TiB"],value=bytes/1024,unit=units[0];for(let index3=1;index3<units.length&&value>=1024;index3++)value/=1024,unit=units[index3];return`${value>=10?value.toFixed(1):value.toFixed(2)} ${unit}`}function normalizeLlamaServerUrl(value){let url=new URL(value.trim());if(url.protocol!=="http:"&&url.protocol!=="https:")throw new Error("Server URL must use http or https");return url.hash="",url.search="",url.pathname=url.pathname.replace(/\/+$/u,"").replace(/\/v1$/u,"")||"/",url.toString().replace(/\/$/u,"")}function llamaInferenceUrl(serverUrl){return`${normalizeLlamaServerUrl(serverUrl)}/v1`}var LlamaClient=class{constructor(serverUrl,apiKey){this.serverUrl=normalizeLlamaServerUrl(serverUrl),this.apiKey=apiKey}async request(path14,init={}){let headers=new Headers(init.headers);init.body!==void 0&&headers.set("Content-Type","application/json"),this.apiKey&&headers.set("Authorization",`Bearer ${this.apiKey}`);let timeout=AbortSignal.timeout(15e3),signal=init.signal?AbortSignal.any([init.signal,timeout]):timeout,response=await fetch(`${this.serverUrl}${path14}`,{...init,headers,signal}),payload;try{payload=await response.json()}catch{payload=void 0}if(!response.ok)throw new Error(errorMessage6(payload,`llama.cpp returned HTTP ${response.status}`));return payload}async list(options={}){let payload=await this.request(`/models${options.reload?"?reload=1":""}`,{signal:options.signal});if(typeof payload!="object"||payload===null||!Array.isArray(payload.data))throw new Error("llama.cpp returned an invalid model catalog");let data=payload.data;if(!data.every(isModelInfo))throw new Error("Server is not running in llama.cpp router mode");return data}async props(options={}){let query=options.model?`?${new URLSearchParams({model:options.model,autoload:"false"})}`:"",payload=await this.request(`/props${query}`,{signal:options.signal});if(typeof payload!="object"||payload===null)return{};let{models_autoload:modelsAutoload,chat_template:chatTemplate}=payload;return{...typeof modelsAutoload=="boolean"?{models_autoload:modelsAutoload}:{},...typeof chatTemplate=="string"?{chat_template:chatTemplate}:{}}}async load(model,signal){await this.request("/models/load",{method:"POST",body:JSON.stringify({model}),signal})}async unload(model,signal){await this.request("/models/unload",{method:"POST",body:JSON.stringify({model}),signal})}async unloadAndWait(model,signal){for(await this.unload(model,signal);;){let entry=(await this.list({signal})).find(candidate=>candidate.id===model);if(!entry||entry.status.value==="unloaded")return;await sleep4(100,signal)}}async download(model,signal){await this.request("/models",{method:"POST",body:JSON.stringify({model}),signal})}async watch(onEvent,signal){let headers=new Headers;this.apiKey&&headers.set("Authorization",`Bearer ${this.apiKey}`);let response=await fetch(`${this.serverUrl}/models/sse`,{headers,signal});if(!response.ok||!response.body)throw new Error(`llama.cpp SSE returned HTTP ${response.status}`);let reader=response.body.getReader(),decoder=new TextDecoder,buffer="";for(;;){let chunk=await reader.read();if(chunk.done)break;buffer+=decoder.decode(chunk.value,{stream:!0}).replaceAll(`\r
|
|
1927
|
+
`).map(line=>line.trim()).find(line=>line.length>0)??"DeepWiki response"}function formatPageList(pages,maxItems=4){let shown=pages.slice(0,maxItems).map(singleLine2).join(", ");return pages.length>maxItems?`${shown}...`:shown}function pageTitlesFromResult(text2,details){if(Array.isArray(details?.pageTitles)){let titles=details.pageTitles.filter(title=>typeof title=="string");if(titles.length)return titles}let fromContent=extractContentPages(text2);return fromContent.length?fromContent:extractStructureSections(text2)}function summarizeStructure(text2,details){let pages=pageTitlesFromResult(text2,details);return pages.length===0?truncateText2(firstContentLine(text2),120):`${details?.pageCount??pages.length} pages \xB7 ${formatPageList(pages)}`}function summarizeContents(text2,details){if(typeof details?.requestedPage=="string"&&details.requestedPage.trim()){let position=details.pageIndex!==void 0&&details.pageCount?`${details.pageIndex}/${details.pageCount} \xB7 `:"",cut=details.truncatedChars?" (truncated)":"";return`Page ${position}${singleLine2(details.requestedPage)}${cut}`}let pages=pageTitlesFromResult(text2,details);if(details?.shownPages!==void 0){let total=details.pageCount??pages.length;return`Wiki \xB7 ${total>0?`${details.shownPages}/${total} pages`:"partial"} shown (truncated)`}return pages.length===0?"Wiki loaded":`Wiki \xB7 ${details?.pageCount??pages.length} pages`}function stripDeepWikiTail(text2){let tailIndex=text2.search(/\n(?:#+\s*)?(?:Wiki pages you might want to explore|View this search)/i);return tailIndex<0?text2:text2.slice(0,tailIndex)}function summarizeQuestion(text2){let cleaned=stripDeepWikiTail(text2).replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/[`*_]/g,"").replace(/\s+/g," ").trim();if(!cleaned)return"Answer ready";let sentenceMatch=cleaned.match(/^.{40,}?[.!?](?=\s|$)/);return truncateText2(sentenceMatch?.[0]??cleaned,140,{word:!0})}function summarizeCollapsed(text2,details){let summary;return details?.action==="structure"?summary=summarizeStructure(text2,details):details?.action==="contents"?summary=summarizeContents(text2,details):details?.action==="question"?summary=summarizeQuestion(text2):summary=truncateText2(firstContentLine(text2),120),truncateText2(singleLine2(summary),180,{word:!0})}function repoLabel(repoName){return Array.isArray(repoName)?repoName.length===0?"repo":repoName.length===1?repoName[0]:`${repoName.length} repos: ${repoName.slice(0,2).join(", ")}${repoName.length>2?"...":""}`:repoName??"repo"}function repoLabelForCall(repoName){if(Array.isArray(repoName))return repoLabel(repoName);if(typeof repoName=="string"){let trimmed=repoName.trim();if(trimmed.startsWith("["))try{let parsed=JSON.parse(trimmed);if(Array.isArray(parsed))return repoLabel(parsed)}catch{}return repoLabel(repoName)}return repoLabel(void 0)}function renderDeepWikiCall(args,theme2){let line=theme2.fg("toolTitle",theme2.bold(`${DEEPWIKI_LABEL} `));return line+=theme2.fg("muted",args.action),line+=` ${theme2.fg("accent",repoLabelForCall(args.repoName))}`,args.action==="question"&&args.question?line+=` ${theme2.fg("dim",truncateText2(singleLine2(args.question),64))}`:args.action==="contents"&&args.page!==void 0&&(line+=` ${theme2.fg("dim",truncateText2(singleLine2(String(args.page)),40))}`),new Text(line,0,0)}function markdownBlock(text2){let container=new Container;return container.addChild(new Spacer(1)),container.addChild(new Markdown(text2,1,0,getMarkdownTheme())),container}function renderDeepWikiResult(result2,options,theme2,isError,elapsedMs){if(options.isPartial){let repo=typeof result2.details?.repoName=="string"?singleLine2(result2.details.repoName):"",label=repo?`Querying ${repo}...`:"Querying...",suffix=elapsedMs!==void 0&&elapsedMs>=2e3?theme2.fg("muted",` (${Math.round(elapsedMs/1e3)}s)`):"";return new Text(`${theme2.fg("warning",label)}${suffix}`,0,0)}let text2=firstText(result2),errorMessage10=typeof result2.details?.errorMessage=="string"?result2.details.errorMessage:void 0;if(isError||errorMessage10){let line=truncateText2(errorMessage10??firstContentLine(text2),200);return new Text(theme2.fg("error",`failed \xB7 ${line}`),0,0)}if(!options.expanded){let summary=theme2.fg("toolOutput",summarizeCollapsed(text2,result2.details)),hint=`${theme2.fg("muted"," (")}${keyHint("app.tools.expand","to expand")}${theme2.fg("muted",")")}`;return new Text(`${summary}${hint}`,0,0)}return markdownBlock(text2)}function trackQueryElapsed(context,isPartial){let state2=context.state;if(isPartial)return state2.startedAt??=Date.now(),state2.refreshTimer===void 0&&(state2.refreshTimer=setTimeout(()=>{state2.refreshTimer=void 0,context.invalidate()},1e3),state2.refreshTimer.unref?.()),Date.now()-state2.startedAt;state2.refreshTimer!==void 0&&(clearTimeout(state2.refreshTimer),state2.refreshTimer=void 0)}function deepwiki(pi){pi.registerTool({name:DEEPWIKI_TOOL_NAME,label:DEEPWIKI_LABEL,description:DEEPWIKI_DESCRIPTION,promptSnippet:DEEPWIKI_PROMPT_SNIPPET,promptGuidelines:DEEPWIKI_PROMPT_GUIDELINES,parameters:DeepWikiParamsSchema,prepareArguments:normalizeDeepWikiParams,async execute(_toolCallId,params,signal,onUpdate){return executeDeepWiki(params,signal,onUpdate)},renderCall(args,theme2){return renderDeepWikiCall(args,theme2)},renderResult(result2,options,theme2,context){let elapsedMs=trackQueryElapsed(context,options.isPartial);return renderDeepWikiResult(result2,options,theme2,context.isError,elapsedMs)}})}function errorMessage6(payload,fallback){if(typeof payload!="object"||payload===null)return fallback;let error=payload.error;if(typeof error!="object"||error===null)return fallback;let message=error.message;return typeof message=="string"&&message?message:fallback}function isModelInfo(value){if(typeof value!="object"||value===null)return!1;let candidate=value;return typeof candidate.id=="string"&&typeof candidate.status?.value=="string"}function linkSignal(source,target){if(!source)return()=>{};if(source.aborted)return target.abort(source.reason),()=>{};let abort=()=>target.abort(source.reason);return source.addEventListener("abort",abort,{once:!0}),()=>source.removeEventListener("abort",abort)}function sleep4(ms,signal){return new Promise((resolve18,reject)=>{if(signal?.aborted){reject(signal.reason??new Error("Cancelled"));return}let abort=()=>{clearTimeout(timeout),reject(signal?.reason??new Error("Cancelled"))},timeout=setTimeout(()=>{signal?.removeEventListener("abort",abort),resolve18()},ms);signal?.addEventListener("abort",abort,{once:!0})})}function parseLoadProgress(data){if(typeof data!="object"||data===null)return;let progress=data.progress;if(typeof progress!="object"||progress===null)return;let value=progress,stage=typeof value.current=="string"?value.current:typeof value.stage=="string"?value.stage:void 0,stages=Array.isArray(value.stages)?value.stages.filter(entry=>typeof entry=="string"):[],stageRatio=typeof value.value=="number"?Math.max(0,Math.min(1,value.value)):void 0,ratio=stageRatio;if(stage&&stages.length>0){let index3=stages.indexOf(stage);index3>=0&&(ratio=(index3+(stageRatio??0))/stages.length)}return{message:stage?`Loading ${stage.replaceAll("_"," ")}`:"Loading model",ratio}}function parseDownloadProgress(data){if(typeof data!="object"||data===null)return;let nested=data.progress,files=typeof nested=="object"&&nested!==null?nested:data,done=0,total=0;for(let value of Object.values(files)){if(typeof value!="object"||value===null)continue;let entry=value;typeof entry.done!="number"||typeof entry.total!="number"||(done+=entry.done,total+=entry.total)}if(!(total<=0))return{message:"Downloading model",ratio:done/total,detail:`${formatBytes(done)} / ${formatBytes(total)}`}}function formatBytes(bytes){if(bytes<1024)return`${bytes} B`;let units=["KiB","MiB","GiB","TiB"],value=bytes/1024,unit=units[0];for(let index3=1;index3<units.length&&value>=1024;index3++)value/=1024,unit=units[index3];return`${value>=10?value.toFixed(1):value.toFixed(2)} ${unit}`}function normalizeLlamaServerUrl(value){let url=new URL(value.trim());if(url.protocol!=="http:"&&url.protocol!=="https:")throw new Error("Server URL must use http or https");return url.hash="",url.search="",url.pathname=url.pathname.replace(/\/+$/u,"").replace(/\/v1$/u,"")||"/",url.toString().replace(/\/$/u,"")}function llamaInferenceUrl(serverUrl){return`${normalizeLlamaServerUrl(serverUrl)}/v1`}var LlamaClient=class{constructor(serverUrl,apiKey){this.serverUrl=normalizeLlamaServerUrl(serverUrl),this.apiKey=apiKey}async request(path14,init={}){let headers=new Headers(init.headers);init.body!==void 0&&headers.set("Content-Type","application/json"),this.apiKey&&headers.set("Authorization",`Bearer ${this.apiKey}`);let timeout=AbortSignal.timeout(15e3),signal=init.signal?AbortSignal.any([init.signal,timeout]):timeout,response=await fetch(`${this.serverUrl}${path14}`,{...init,headers,signal}),payload;try{payload=await response.json()}catch{payload=void 0}if(!response.ok)throw new Error(errorMessage6(payload,`llama.cpp returned HTTP ${response.status}`));return payload}async list(options={}){let payload=await this.request(`/models${options.reload?"?reload=1":""}`,{signal:options.signal});if(typeof payload!="object"||payload===null||!Array.isArray(payload.data))throw new Error("llama.cpp returned an invalid model catalog");let data=payload.data;if(!data.every(isModelInfo))throw new Error("Server is not running in llama.cpp router mode");return data}async props(options={}){let query=options.model?`?${new URLSearchParams({model:options.model,autoload:"false"})}`:"",payload=await this.request(`/props${query}`,{signal:options.signal});if(typeof payload!="object"||payload===null)return{};let{models_autoload:modelsAutoload,chat_template:chatTemplate}=payload;return{...typeof modelsAutoload=="boolean"?{models_autoload:modelsAutoload}:{},...typeof chatTemplate=="string"?{chat_template:chatTemplate}:{}}}async load(model,signal){await this.request("/models/load",{method:"POST",body:JSON.stringify({model}),signal})}async unload(model,signal){await this.request("/models/unload",{method:"POST",body:JSON.stringify({model}),signal})}async unloadAndWait(model,signal){for(await this.unload(model,signal);;){let entry=(await this.list({signal})).find(candidate=>candidate.id===model);if(!entry||entry.status.value==="unloaded")return;await sleep4(100,signal)}}async download(model,signal){await this.request("/models",{method:"POST",body:JSON.stringify({model}),signal})}async watch(onEvent,signal){let headers=new Headers;this.apiKey&&headers.set("Authorization",`Bearer ${this.apiKey}`);let response=await fetch(`${this.serverUrl}/models/sse`,{headers,signal});if(!response.ok||!response.body)throw new Error(`llama.cpp SSE returned HTTP ${response.status}`);let reader=response.body.getReader(),decoder=new TextDecoder,buffer="";for(;;){let chunk=await reader.read();if(chunk.done)break;buffer+=decoder.decode(chunk.value,{stream:!0}).replaceAll(`\r
|
|
1922
1928
|
`,`
|
|
1923
1929
|
`);let boundary=buffer.indexOf(`
|
|
1924
1930
|
|
|
@@ -1960,12 +1966,12 @@ ${body}`):DECLINE_MESSAGE;return buildToolResult(text2,{answers,outcome:"cancell
|
|
|
1960
1966
|
${body}`:""}
|
|
1961
1967
|
|
|
1962
1968
|
${CLARIFICATION_FOLLOW_UP}`;return buildToolResult(answers.length?boundedAnswers(answers,envelope):envelope(""),{answers,outcome:"needs_clarification",cancelled:!1})}var OTHER_OPTION={kind:"other",label:"Type something"};function newQuestionState(question2){return{focus:0,draft:question2.multiSelect?{kind:"multi",selected:new Set}:{kind:"single"},notes:new Map}}function displayOptions(question2){return[...question2.options.map((option,optionIndex)=>({...option,kind:"option",optionIndex})),OTHER_OPTION]}function hasAnswer(state2){let draft=state2.draft;return draft.kind==="single"?draft.choice!==void 0:draft.selected.size>0||draft.custom?.selected===!0}function customText(state2){let draft=state2.draft;return draft.kind==="multi"?draft.custom?.text:draft.choice?.kind==="custom"?draft.choice.text:void 0}function isSelected(state2,option){let draft=state2.draft;return draft.kind==="multi"?option.kind==="other"?draft.custom?.selected===!0:draft.selected.has(option.optionIndex):option.kind==="other"?draft.choice?.kind==="custom":draft.choice?.kind==="option"&&draft.choice.index===option.optionIndex}function firstUnanswered(states){let index3=states.findIndex(state2=>!hasAnswer(state2));return index3===-1?void 0:index3}function selectedNotes(question2,state2,indices){let notes=[];for(let index3 of indices){let text2=state2.notes.get(index3)?.trim();text2&¬es.push({option:question2.options[index3].label,text:text2})}return notes.length?notes:void 0}function orderedAnswers(questions,states){let answers=[];for(let questionIndex=0;questionIndex<questions.length;questionIndex++){let question2=questions[questionIndex],draft=states[questionIndex].draft,base={questionIndex,question:question2.question,header:question2.header};if(draft.kind==="single"){let choice=draft.choice;if(choice?.kind==="custom"&&answers.push({...base,kind:"custom",answer:choice.text}),choice?.kind==="option"){let option=question2.options[choice.index],notes2=selectedNotes(question2,states[questionIndex],[choice.index]);answers.push({...base,kind:"option",answer:option.label,...option.preview?{preview:option.preview}:{},...notes2?{notes:notes2}:{}})}continue}if(!hasAnswer(states[questionIndex]))continue;let indices=[...draft.selected].sort((a,b2)=>a-b2),selected=indices.map(index3=>question2.options[index3].label);draft.custom?.selected&&selected.push(draft.custom.text);let notes=selectedNotes(question2,states[questionIndex],indices);answers.push({...base,kind:"multi",answer:null,selected,...notes?{notes}:{}})}return answers}var DIALOG_MAX_FRACTION=.5,DIALOG_MIN_ROWS=16,VIEWPORT_SCROLL_STEP=4;function dialogRowBudget(terminalRows){let rows=Math.max(1,Math.floor(terminalRows));return Math.min(rows,Math.max(DIALOG_MIN_ROWS,Math.floor(rows*DIALOG_MAX_FRACTION)))}function applyVerticalViewport(lines,width,maxRows,theme2,options={}){if(lines.length<=maxRows)return{lines,start:0,maxStart:0};if(maxRows<5){let anchor=Math.max(0,Math.min(lines.length-1,options.anchorLine??0)),start2=Math.max(0,Math.min(lines.length-maxRows,anchor-Math.floor(maxRows/2)));return{lines:lines.slice(start2,start2+maxRows),start:start2,maxStart:lines.length-maxRows}}let first=lines[0]??"",last=lines[lines.length-1]??"",body=lines.slice(1,-1),contentRows=maxRows-4,maxStart=Math.max(0,body.length-contentRows),anchorInBody=Math.max(0,Math.min(body.length-1,(options.anchorLine??1)-1)),requestedStart=options.preferredStart??Math.max(0,anchorInBody-Math.floor(contentRows/2)),start=Math.max(0,Math.min(maxStart,requestedStart)),bottomHidden=Math.max(0,body.length-start-contentRows),indicator=text2=>theme2.fg("dim",truncateToWidth(text2,Math.max(1,width)));return{lines:[first,start>0?indicator(`\u2191 ${start} rows hidden`):"",...body.slice(start,start+contentRows),bottomHidden>0?indicator(`\u2193 ${bottomHidden} rows hidden`):"",last],start,maxStart}}function detailKey(snapshot){return`${snapshot.current}:${snapshot.states[snapshot.current].focus}:${snapshot.mode.kind==="chat"}`}var joinHints=(...hints)=>hints.filter(Boolean).join(" \u2022 "),QuestionDialogView=class{constructor(theme2,keybindings){this.details=new DetailPane,this.previews=new PreviewLinesCache,this.reviewScroll=0,this.reviewMaxScroll=0,this.theme=theme2,this.keybindings=keybindings}resetScroll(){this.details.reset(),this.reviewScroll=0,this.reviewMaxScroll=0}pageDetails(snapshot,direction){this.details.page(detailKey(snapshot),direction)}scrollReview(direction){this.reviewScroll=Math.max(0,Math.min(this.reviewMaxScroll,this.reviewScroll+direction*VIEWPORT_SCROLL_STEP))}render(snapshot,width,terminalRows){let theme2=this.theme,lines=[],renderWidth=Math.max(1,width),maxRows=dialogRowBudget(terminalRows);if(lines.push(ruleBorder(theme2,renderWidth)),this.renderTabs(snapshot,renderWidth,lines),snapshot.mode.kind==="review"){this.renderReview(snapshot,renderWidth,lines),lines.push(ruleBorder(theme2,renderWidth));let viewport=applyVerticalViewport(lines,renderWidth,maxRows,theme2,{preferredStart:this.reviewScroll});return this.reviewMaxScroll=viewport.maxStart,this.reviewScroll=viewport.start,viewport.lines}let{mode,options,editor}=snapshot,question2=snapshot.questions[snapshot.current],state2=snapshot.states[snapshot.current],isMulti=state2.draft.kind==="multi",chat=mode.kind==="chat",editing=mode.kind==="custom"||mode.kind==="notes";wrapWithPrefix(" ",theme2.fg("text",question2.question),renderWidth,lines);let footerLines=this.renderFooter(snapshot,renderWidth,`1-${Math.min(9,options.length)}`),areaRows=Math.max(1,maxRows-lines.length-footerLines.length),sideBySide=!editing&&renderWidth>=72,listWidth=sideBySide?Math.min(Math.floor((renderWidth-3)/2),Math.max(24,...options.map((option,index3)=>6+visibleWidth(`${index3+1}. ${option.label.replace(/\s+/gu," ")}`)+2))):renderWidth,detailWidth=sideBySide?renderWidth-listWidth-3:renderWidth,custom=customText(state2),optionLines=[],items=[],focusItem=chat?options.length-1:state2.focus;for(let index3=0;index3<options.length;index3++){let option=options[index3],focused=!chat&&index3===state2.focus,selected=isSelected(state2,option),marker=isMulti?option.kind==="other"&&custom===void 0?" ":selected?theme2.fg("success","[x]"):theme2.fg("dim","[ ]"):" ",focusArrow=focused?theme2.fg("accent","\u2192"):" ",note=option.kind==="option"&&state2.notes.has(option.optionIndex)?theme2.fg("success"," +note"):"",otherText=option.kind==="other"?custom:void 0,labelText=(otherText?`${option.label} \u270E ${otherText}`:option.label).replace(/\s+/gu," "),checkmark=selected&&!isMulti?" \u2713":"",label=`${index3+1}. ${labelText}${checkmark}${note}`,color2=focused?"accent":selected?"success":"text",row=truncateToWidth(`${focusArrow} ${marker} ${theme2.fg(color2,label)}`,listWidth);optionLines.push(focused?theme2.bg("selectedBg",row+" ".repeat(Math.max(0,listWidth-visibleWidth(row)))):row),items.push({height:1,countsAsOption:!0})}if(editing){let start=optionLines.length,label=mode.kind==="notes"?`Notes for ${question2.options[mode.option].label}:`:"Your answer:";optionLines.push(theme2.fg("muted",truncateToWidth(` ${label}`,listWidth)));for(let line of editor.render(Math.max(1,listWidth-2)))optionLines.push(` ${line}`);items.push({height:optionLines.length-start,countsAsOption:!1}),focusItem=items.length-1}let regionStart=lines.length,focusRow;if(editing){let windowed=this.windowOptionLines(optionLines,items,focusItem,areaRows,renderWidth);focusRow=windowed.focusRow,lines.push(...windowed.rows)}else{let option=options[state2.focus],content=[],hasPreview=!chat&&option.kind==="option"&&!!option.preview,title=chat?"Chat about this":`${hasPreview?"Preview":"Details"} \xB7 ${option.label}`;if(!chat&&visibleWidth(`${state2.focus+1}. ${option.label.replace(/\s+/gu," ")}`)>listWidth-6&&wrapWithPrefix(" ",theme2.fg("text",option.label),detailWidth,content),chat)wrapWithPrefix(" ",theme2.fg("muted","Discuss this question before choosing an answer."),detailWidth,content);else if(option.kind==="option"){wrapWithPrefix(" ",theme2.fg("muted",option.description),detailWidth,content);let note=state2.notes.get(option.optionIndex);note&&wrapWithPrefix(" ",theme2.fg("success",`Note: ${note}`),detailWidth,content),hasPreview&&option.preview&&content.push("",...this.previewLines(option.preview,detailWidth))}else wrapWithPrefix(" ",theme2.fg("muted",custom||"Write your own answer instead of choosing an option."),detailWidth,content);let optionRows=sideBySide?areaRows:Math.max(1,Math.min(options.length,areaRows-4)),detailRows=sideBySide?areaRows:Math.max(1,areaRows-optionRows),left=this.windowOptionLines(optionLines,items,focusItem,optionRows,listWidth),right=this.details.render(detailKey(snapshot),title,content,detailWidth,detailRows,this.keyGroupAction(["app.question.pageUp","app.question.pageDown"],"scroll"),theme2);if(focusRow=left.focusRow,sideBySide)for(let row=0;row<Math.max(left.rows.length,right.length);row++){let leftText=left.rows[row]??"",leftPadded=leftText+" ".repeat(Math.max(0,listWidth-visibleWidth(leftText)));lines.push(`${leftPadded}${theme2.fg("dim"," \u2502 ")}${right[row]??""}`)}else lines.push(...left.rows,...right)}let anchorLine=regionStart+focusRow;return lines.push(...footerLines),applyVerticalViewport(lines,renderWidth,maxRows,theme2,{anchorLine}).lines}keyAction(keybinding,action){let label=keyLabel(keybinding,{keybindings:this.keybindings});return label?`${label} ${action}`:""}keyGroupAction(bindings,action){let labels=bindings.map(binding=>keyLabel(binding,{keybindings:this.keybindings})).filter(Boolean).join("/");return labels?`${labels} ${action}`:""}previewLines(previewText,width){return this.previews.get(previewText,width,()=>new Markdown(previewText,1,0,getMarkdownTheme()).render(Math.max(1,width)))}renderTabs(snapshot,renderWidth,lines){let{questions,states,current,mode}=snapshot,theme2=this.theme;if(questions.length<2)return;let tabCount=questions.length+1,headerWidth=Math.max(4,Math.floor((renderWidth-tabCount*5)/tabCount)),reviewing=mode.kind==="review",tabs=[...questions.map((question2,index3)=>{let answered=hasAnswer(states[index3]),label=` ${answered?"\u25A0":"\u25A1"} ${truncateToWidth(question2.header,headerWidth)} `;return!reviewing&&index3===current?theme2.bg("selectedBg",theme2.fg(answered?"success":"text",label)):theme2.fg(answered?"success":"muted",label)}),reviewing?theme2.bg("selectedBg",theme2.fg("text"," \u2713 Submit ")):theme2.fg(firstUnanswered(states)===void 0?"success":"dim"," \u2713 Submit ")].join(" ");wrapWithPrefix(" ",tabs,renderWidth,lines)}renderReview(snapshot,renderWidth,lines){let theme2=this.theme;wrapWithPrefix(" ",theme2.fg("accent","Review answers"),renderWidth,lines),lines.push("");for(let answer of orderedAnswers(snapshot.questions,snapshot.states)){wrapWithPrefix(" ",theme2.fg("text",`${answer.questionIndex+1}. ${answer.question}`),renderWidth,lines),wrapWithPrefix(" ",theme2.fg("success",answerScalar(answer)),renderWidth,lines);for(let note of answer.notes??[])wrapWithPrefix(" ",theme2.fg("muted",`Note for ${note.option}: ${note.text}`),renderWidth,lines);lines.push("")}wrapWithPrefix(" ",theme2.fg("dim",joinHints(this.keyAction("tui.select.confirm","submit"),this.keyAction("tui.select.cancel","edit last question"),this.keyGroupAction(["tui.select.up","tui.select.down"],"scroll"))),renderWidth,lines)}renderFooter(snapshot,renderWidth,digitRange){let theme2=this.theme,{mode}=snapshot,state2=snapshot.states[snapshot.current],isMulti=state2.draft.kind==="multi",chat=mode.kind==="chat",lines=[];wrapWithPrefix(`${chat?theme2.fg("accent","\u2192"):" "} `,theme2.fg(chat?"accent":"text","Chat about this"),renderWidth,lines),state2.warning&&(lines.push(""),wrapWithPrefix(" ",theme2.fg("warning",state2.warning),renderWidth,lines));let submitLabel=keyLabel("tui.input.submit"),editorSubmit=action=>submitLabel?`${submitLabel} ${action}`:"",questionsHint=snapshot.questions.length>1?this.keyGroupAction(["tui.editor.cursorLeft","tui.editor.cursorRight"],"questions"):"",hints;mode.kind==="notes"?hints=joinHints(editorSubmit("save notes"),this.keyAction("tui.select.cancel","back")):mode.kind==="custom"?hints=joinHints(editorSubmit(isMulti?"save custom answer":"continue"),this.keyAction("tui.select.cancel","back")):chat?hints=joinHints(this.keyAction("tui.select.confirm","discuss"),this.keyAction("tui.select.up","return to options"),this.keyAction("tui.select.cancel","cancel")):hints=joinHints(this.keyGroupAction(["tui.select.up","tui.select.down"],"navigate"),`${digitRange} ${isMulti?"toggle":"select"}`,isMulti?this.keyAction("app.list.toggle","toggle focused"):"",this.keyAction("tui.input.tab","notes/custom"),this.keyAction("tui.select.confirm",isMulti?"continue":"select"),questionsHint,this.keyAction("tui.select.cancel","cancel"));let hintLine="";for(let hint of hints.split(" \u2022 ")){let joined=hintLine?`${hintLine} \u2022 ${hint}`:hint;hintLine&&visibleWidth(joined)>renderWidth-1?(wrapWithPrefix(" ",theme2.fg("dim",hintLine),renderWidth,lines),hintLine=hint):hintLine=joined}return hintLine&&wrapWithPrefix(" ",theme2.fg("dim",hintLine),renderWidth,lines),lines.push(ruleBorder(theme2,renderWidth)),lines}windowOptionLines(optionLines,items,focus,rows,width){let theme2=this.theme,window2=windowItems(items,focus,rows),rowsBefore=count=>items.slice(0,count).reduce((sum,item)=>sum+item.height,0),from=rowsBefore(window2.first),block=optionLines.slice(from,rowsBefore(window2.last+1)),visible=applyVerticalViewport(block,width,window2.contentRows,theme2,{anchorLine:Math.max(0,block.findIndex(line=>line.includes(CURSOR_MARKER)))}).lines;if(!window2.showAbove&&!window2.showBelow)return{rows:visible,focusRow:rowsBefore(focus)-from};let hint=(direction,count)=>theme2.fg("dim",` ${truncateToWidth(moreOptionsHint(direction,count),Math.max(1,width-1))}`),spare=Array.from({length:Math.max(0,window2.contentRows-visible.length)},()=>"");return{rows:[...window2.showAbove?[hint("up",window2.hiddenAbove)]:[],...visible,...window2.showBelow?[hint("down",window2.hiddenBelow)]:[],...spare],focusRow:(window2.showAbove?1:0)+rowsBefore(focus)-from}}};function createQuestionDialog(questions,signal){return(tui,theme2,keybindings,done)=>{let states=questions.map(newQuestionState),optionsByQuestion=questions.map(displayOptions),current=0,mode={kind:"choose"},dialogFocused=!1,finished=!1,cache=new WidthCachedRender,view=new QuestionDialogView(theme2,keybindings),editor=new Editor(tui,{borderColor:s=>theme2.fg("accent",s),selectList:{selectedPrefix:t=>theme2.fg("accent",t),selectedText:t=>theme2.fg("accent",t),description:t=>theme2.fg("muted",t),scrollInfo:t=>theme2.fg("dim",t),noMatch:t=>theme2.fg("warning",t)}}),keyMatches=(data,keybinding)=>keybindings.matches(data,keybinding),state2=()=>states[current],options=()=>optionsByQuestion[current],isEditing=()=>mode.kind==="custom"||mode.kind==="notes",snapshot=()=>({questions,states,current,options:options(),mode,editor});function refresh(){cache.invalidate(),tui.requestRender()}function setMode(next,editorText=""){mode=next,view.resetScroll(),editor.setText(editorText),editor.focused=dialogFocused&&isEditing(),refresh()}function finish(outcome){finished||(finished=!0,done({outcome,answers:orderedAnswers(questions,states)}))}function discardEdit(){let draft=state2().draft;mode.kind==="notes"&&draft.kind==="single"&&(draft.choice=mode.previous)}let onAbort=()=>{discardEdit(),finish("cancelled")};signal?.aborted?onAbort():signal?.addEventListener("abort",onAbort,{once:!0});function goTo(index3,warning){current=Math.max(0,Math.min(questions.length-1,index3)),warning&&(state2().warning=warning),setMode({kind:"choose"})}function advance(){if(questions.length===1&&state2().draft.kind==="single"){finish("answered");return}let missing=firstUnanswered(states);missing===void 0?setMode({kind:"review"}):goTo(missing)}function editCustom(){setMode({kind:"custom"},customText(state2())??"")}function editNotes(option){let target=state2(),draft=target.draft;if(option.kind==="other"){editCustom();return}if(draft.kind==="multi"&&!draft.selected.has(option.optionIndex)){target.warning="Select the option first, then add notes.",refresh();return}let previous=draft.kind==="single"?draft.choice:void 0;draft.kind==="single"&&(draft.choice={kind:"option",index:option.optionIndex},target.warning=void 0),setMode({kind:"notes",option:option.optionIndex,previous},target.notes.get(option.optionIndex)??"")}function pickSingle(option){let target=state2();if(target.draft.kind==="single"){if(option.kind==="other"){target.draft.choice?.kind==="custom"?advance():editCustom();return}target.draft.choice={kind:"option",index:option.optionIndex},target.warning=void 0,advance()}}function toggleMulti(option){let target=state2(),draft=target.draft;if(draft.kind==="multi"){if(target.warning=void 0,option.kind==="option")draft.selected.delete(option.optionIndex)||draft.selected.add(option.optionIndex);else if(draft.custom)draft.custom.selected=!draft.custom.selected;else{let tabKey=keyLabel("tui.input.tab",{keybindings});target.warning=tabKey?`Press ${tabKey} to type a custom answer.`:"Choose Type something to type a custom answer."}refresh()}}function submitMulti(){let target=state2();if(hasAnswer(target)){target.warning=void 0,advance();return}target.warning="Select at least one option, type a custom answer, or cancel the questions.",refresh()}editor.onSubmit=value=>{let target=state2(),text2=value.trim();if(text2.length>QUESTION_LIMITS.userTextChars){target.warning=`Keep notes and custom answers under ${QUESTION_LIMITS.userTextChars} characters.`,editor.setText(text2),refresh();return}target.warning=void 0;let draft=target.draft;if(mode.kind==="notes"){text2?target.notes.set(mode.option,text2):target.notes.delete(mode.option),setMode({kind:"choose"});return}if(!text2){setMode({kind:"choose"});return}if(draft.kind==="multi"){draft.custom={text:text2,selected:!0},target.focus=options().length-1,setMode({kind:"choose"});return}draft.choice={kind:"custom",text:text2},setMode({kind:"choose"}),advance()};function handleReviewInput(data){if(keyMatches(data,"tui.select.up")||keyMatches(data,"tui.select.down"))view.scrollReview(keyMatches(data,"tui.select.up")?-1:1),refresh();else if(keyMatches(data,"tui.select.confirm")){let missing=firstUnanswered(states);missing===void 0?finish("answered"):goTo(missing,"Answer this question before submitting.")}else(keyMatches(data,"tui.editor.cursorLeft")||keyMatches(data,"tui.select.cancel"))&&goTo(questions.length-1)}function handleEditorInput(data){if(keyMatches(data,"tui.select.cancel")){discardEdit(),setMode({kind:"choose"});return}editor.handleInput(data),refresh()}function handleChoiceInput(data){let chat=mode.kind==="chat",target=state2(),choices=options(),multi=target.draft.kind==="multi";if(keyMatches(data,"tui.editor.cursorLeft"))current>0&&goTo(current-1);else if(keyMatches(data,"tui.editor.cursorRight"))current<questions.length-1?goTo(current+1):firstUnanswered(states)===void 0&&setMode({kind:"review"});else if(keyMatches(data,"app.question.pageUp")||keyMatches(data,"app.question.pageDown"))view.pageDetails(snapshot(),keyMatches(data,"app.question.pageUp")?-1:1),refresh();else if(keyMatches(data,"tui.select.up")){if(target.warning=void 0,chat){target.focus=choices.length-1,setMode({kind:"choose"});return}target.focus=Math.max(0,target.focus-1),refresh()}else if(keyMatches(data,"tui.select.down")){if(chat)return;target.warning=void 0,target.focus<choices.length-1?(target.focus++,refresh()):setMode({kind:"chat"})}else if(keyMatches(data,"tui.input.tab"))chat||editNotes(choices[target.focus]);else if(data.length===1&&data>="1"&&data<="9"){let index3=data.charCodeAt(0)-49,option=choices[index3];if(!option)return;target.focus=index3,target.warning=void 0,chat&&setMode({kind:"choose"}),multi?toggleMulti(option):pickSingle(option)}else if(chat)keyMatches(data,"tui.select.confirm")?finish("needs_clarification"):keyMatches(data,"tui.select.cancel")&&finish("cancelled");else if(multi&&keyMatches(data,"app.list.toggle"))toggleMulti(choices[target.focus]);else if(keyMatches(data,"tui.select.confirm")){let option=choices[target.focus];multi?option.kind==="other"&&customText(target)===void 0?editCustom():submitMulti():pickSingle(option)}else keyMatches(data,"tui.select.cancel")&&finish("cancelled")}function render2(width){return cache.get(width,tui.terminal.rows,(renderWidth,rows)=>view.render(snapshot(),renderWidth,rows))}return{get focused(){return dialogFocused},set focused(value){dialogFocused=value,editor.focused=dialogFocused&&isEditing()},render:render2,invalidate:()=>{cache.invalidate()},handleInput(data){mode.kind==="review"?handleReviewInput(data):isEditing()?handleEditorInput(data):handleChoiceInput(data)},dispose(){signal?.removeEventListener("abort",onAbort)}}}}var MAX_RENDERED_QUESTIONS=4,MAX_RENDERED_ANSWERS=4,MAX_RENDERED_SELECTIONS=5,MAX_RENDERED_ANSWER_CHARS=400,MAX_RENDERED_NOTE_CHARS=400,MAX_RENDERED_ERROR_CHARS=400,MAX_RENDERED_VALIDATION_SUMMARY_CHARS=240,MAX_RENDERED_FALLBACK_CHARS=1e3;function safeRecord(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)?value:void 0}function safeValue(record,key){try{return record[key]}catch{return}}function truncate4(text2,limit){return text2.length>limit?`${text2.slice(0,Math.max(0,limit-1))}\u2026`:text2}function oneLine(value,limit){return typeof value=="string"?truncate4(value.replace(/\s+/gu," ").trim(),limit):""}function questionsFromArgs(args){let record=safeRecord(args);if(!record)return[];let rawQuestions=safeValue(record,"questions");if(!Array.isArray(rawQuestions))return[];let questions=[];for(let rawQuestion of rawQuestions.slice(0,MAX_RENDERED_QUESTIONS)){let question2=safeRecord(rawQuestion);if(!question2)continue;let rawHeader=safeValue(question2,"header");if(typeof rawHeader!="string")continue;let header=oneLine(rawHeader,QUESTION_LIMITS.headerChars)||`Decision ${questions.length+1}`;questions.push({header,question:oneLine(safeValue(question2,"question"),QUESTION_LIMITS.questionChars),multiSelect:safeValue(question2,"multiSelect")===!0})}return questions}function resultFallback(result2){if(!Array.isArray(result2.content))return"";let blocks=[];for(let rawBlock of result2.content.slice(0,8)){let block=safeRecord(rawBlock);if(!block||safeValue(block,"type")!=="text")continue;let text2=safeValue(block,"text");typeof text2=="string"&&blocks.push(text2)}return truncate4(blocks.join(`
|
|
1963
|
-
`),MAX_RENDERED_FALLBACK_CHARS)}function validationSummary(text2){let match2=/^Validation failed for tool\s+"question":\s*([\s\S]*?)(?:\r?\n\s*\r?\nReceived arguments:|$)/u.exec(text2.trim());if(!match2)return;let errors=match2[1].split(/\r?\n/u).map(line=>line.trim().replace(/^-\s*/u,"")).filter(Boolean);return{summary:`Invalid arguments \xB7 ${oneLine(errors[0],MAX_RENDERED_VALIDATION_SUMMARY_CHARS)||"schema validation failed"}`,hiddenErrors:Math.max(0,errors.length-1)}}function renderFallbackResult(result2,expanded,theme2){let fallback=resultFallback(result2);if(!fallback)return new Text("Question result unavailable",0,0);let validation=validationSummary(fallback);if(!validation||expanded)return new Text(fallback,0,0);let moreErrors=validation.hiddenErrors>0?` \xB7 +${validation.hiddenErrors} more`:"",expandKey=keyLabel("app.tools.expand"),hint=theme2.fg("muted",expandKey?` (${expandKey} to expand)`:" (more details available)");return new Text(`${theme2.fg("error",validation.summary)}${theme2.fg("muted",moreErrors)}${hint}`,0,0)}function normalizeAnswer(value,index3){let raw=safeRecord(value);if(!raw)return;let rawHeader=safeValue(raw,"header");if(typeof rawHeader!="string")return;let header=oneLine(rawHeader,QUESTION_LIMITS.headerChars)||`Decision ${index3+1}`,text2;if(safeValue(raw,"kind")==="multi"){let rawSelected=safeValue(raw,"selected");text2=Array.isArray(rawSelected)?rawSelected.slice(0,MAX_RENDERED_SELECTIONS).map((entry,selectedIndex)=>typeof entry!="string"?"":oneLine(entry,MAX_RENDERED_ANSWER_CHARS)||`Option ${selectedIndex+1}`).filter(Boolean).join(", "):""}else text2=oneLine(safeValue(raw,"answer"),MAX_RENDERED_ANSWER_CHARS);let rawNotes=safeValue(raw,"notes"),notes=Array.isArray(rawNotes)?rawNotes.slice(0,MAX_RENDERED_ANSWERS).map(entry=>{let note=safeRecord(entry);if(!note)return;let option=oneLine(safeValue(note,"option"),QUESTION_LIMITS.optionLabelChars),text3=oneLine(safeValue(note,"text"),MAX_RENDERED_NOTE_CHARS);return option&&text3?{option,text:text3}:void 0}).filter(note=>note!==void 0):[];return{header,text:text2||"(no input)",notes}}function normalizeDetails(value){let raw=safeRecord(value);if(!raw)return;let outcome=safeValue(raw,"outcome");if(outcome!=="answered"&&outcome!=="cancelled"&&outcome!=="needs_clarification"&&outcome!=="error")return;let rawAnswers=safeValue(raw,"answers"),answers=Array.isArray(rawAnswers)?rawAnswers.slice(0,MAX_RENDERED_ANSWERS).map((answer,index3)=>normalizeAnswer(answer,index3)).filter(answer=>answer!==void 0):[],message=oneLine(safeValue(raw,"message"),MAX_RENDERED_ERROR_CHARS);return{answers,outcome,...message?{message}:{}}}function errorMessage7(
|
|
1969
|
+
`),MAX_RENDERED_FALLBACK_CHARS)}function validationSummary(text2){let match2=/^Validation failed for tool\s+"question":\s*([\s\S]*?)(?:\r?\n\s*\r?\nReceived arguments:|$)/u.exec(text2.trim());if(!match2)return;let errors=match2[1].split(/\r?\n/u).map(line=>line.trim().replace(/^-\s*/u,"")).filter(Boolean);return{summary:`Invalid arguments \xB7 ${oneLine(errors[0],MAX_RENDERED_VALIDATION_SUMMARY_CHARS)||"schema validation failed"}`,hiddenErrors:Math.max(0,errors.length-1)}}function renderFallbackResult(result2,expanded,theme2){let fallback=resultFallback(result2);if(!fallback)return new Text("Question result unavailable",0,0);let validation=validationSummary(fallback);if(!validation||expanded)return new Text(fallback,0,0);let moreErrors=validation.hiddenErrors>0?` \xB7 +${validation.hiddenErrors} more`:"",expandKey=keyLabel("app.tools.expand"),hint=theme2.fg("muted",expandKey?` (${expandKey} to expand)`:" (more details available)");return new Text(`${theme2.fg("error",validation.summary)}${theme2.fg("muted",moreErrors)}${hint}`,0,0)}function normalizeAnswer(value,index3){let raw=safeRecord(value);if(!raw)return;let rawHeader=safeValue(raw,"header");if(typeof rawHeader!="string")return;let header=oneLine(rawHeader,QUESTION_LIMITS.headerChars)||`Decision ${index3+1}`,text2;if(safeValue(raw,"kind")==="multi"){let rawSelected=safeValue(raw,"selected");text2=Array.isArray(rawSelected)?rawSelected.slice(0,MAX_RENDERED_SELECTIONS).map((entry,selectedIndex)=>typeof entry!="string"?"":oneLine(entry,MAX_RENDERED_ANSWER_CHARS)||`Option ${selectedIndex+1}`).filter(Boolean).join(", "):""}else text2=oneLine(safeValue(raw,"answer"),MAX_RENDERED_ANSWER_CHARS);let rawNotes=safeValue(raw,"notes"),notes=Array.isArray(rawNotes)?rawNotes.slice(0,MAX_RENDERED_ANSWERS).map(entry=>{let note=safeRecord(entry);if(!note)return;let option=oneLine(safeValue(note,"option"),QUESTION_LIMITS.optionLabelChars),text3=oneLine(safeValue(note,"text"),MAX_RENDERED_NOTE_CHARS);return option&&text3?{option,text:text3}:void 0}).filter(note=>note!==void 0):[];return{header,text:text2||"(no input)",notes}}function normalizeDetails(value){let raw=safeRecord(value);if(!raw)return;let outcome=safeValue(raw,"outcome");if(outcome!=="answered"&&outcome!=="cancelled"&&outcome!=="needs_clarification"&&outcome!=="error")return;let rawAnswers=safeValue(raw,"answers"),answers=Array.isArray(rawAnswers)?rawAnswers.slice(0,MAX_RENDERED_ANSWERS).map((answer,index3)=>normalizeAnswer(answer,index3)).filter(answer=>answer!==void 0):[],message=oneLine(safeValue(raw,"message"),MAX_RENDERED_ERROR_CHARS);return{answers,outcome,...message?{message}:{}}}function errorMessage7(details){return details.message??"The question tool could not continue"}function answerLines(answers,theme2){return answers.map(answer=>{let notes=answer.notes.map(note=>`
|
|
1964
1970
|
${theme2.fg("muted",` Note for ${note.option}: ${note.text}`)}`);return`${theme2.fg("accent",answer.header)}: ${theme2.fg("text",answer.text)}${notes.join("")}`})}function renderOutcome(title,details,expanded,theme2){return!expanded||details.answers.length===0?new Text(title,0,0):new Text(`${title}
|
|
1965
1971
|
${answerLines(details.answers,theme2).join(`
|
|
1966
1972
|
`)}`,0,0)}function answerProgress(details,args){let total=questionsFromArgs(args).length;return total>0?`answered ${details.answers.length} of ${total}`:`answered ${details.answers.length}`}function renderQuestionCall(args,theme2,expanded){let questions=questionsFromArgs(args),headers=questions.map(question2=>question2.header).join(", "),count=`${questions.length} decision${questions.length===1?"":"s"}`,summary=questions.length===0?"asking for a decision":headers?`${count}: ${headers}`:count,title=`${theme2.fg("toolTitle",theme2.bold("question"))} ${theme2.fg("muted",summary)}`;if(!expanded||questions.length===0)return new Text(title,0,0);let detailLines=questions.map(question2=>{let multi=question2.multiSelect?" (multi-select)":"",body=question2.question?`: ${question2.question}`:"";return theme2.fg("dim",`${question2.header}${multi}${body}`)});return new Text(`${title}
|
|
1967
1973
|
${detailLines.join(`
|
|
1968
|
-
`)}`,0,0)}function renderQuestionResult(result2,options,theme2,args){let details=normalizeDetails(result2.details);if(!details)return renderFallbackResult(result2,options.expanded,theme2);if(details.outcome==="error")return new Text(theme2.fg("error",`Question error: ${errorMessage7(result2,details)}`),0,0);if(details.outcome==="cancelled"){let title2=theme2.fg("warning",`Cancelled \xB7 ${answerProgress(details,args)}`);return renderOutcome(title2,details,options.expanded,theme2)}if(details.outcome==="needs_clarification"){let title2=theme2.fg("warning",`Wants to discuss \xB7 ${answerProgress(details,args)}`);return renderOutcome(title2,details,options.expanded,theme2)}let title=theme2.fg("success",`\u2713 Answered ${details.answers.length} decision${details.answers.length===1?"":"s"}`);return renderOutcome(title,details,options.expanded,theme2)}var MIN_OPTIONS=2,MAX_OPTIONS=4,MAX_QUESTIONS2=4,RESERVED_LABELS=["Other","Type something","Type something.","Chat about this"],normalizeLabel=text2=>text2.trim().toLowerCase(),RESERVED_NORMALIZED=new Set(RESERVED_LABELS.map(normalizeLabel)),OptionSchema=typebox_exports.Object({label:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.optionLabelChars,description:"Short user-facing option label (1-5 words), distinct within the question. Reserved labels ('Other', 'Type something', 'Chat about this') are rejected \u2014 the UI adds the custom-answer path itself."}),description:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.optionDescriptionChars,description:"One concise sentence explaining the option's meaning, consequence, or tradeoff."}),preview:typebox_exports.Optional(typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.previewChars,description:"Optional markdown preview shown only for focused single-select options; use for concrete snippets, layouts, copy, or config comparisons."}))}),QuestionSchema=typebox_exports.Object({question:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.questionChars,description:"One clear, specific decision or preference question ending in a question mark. Ask only what is needed to proceed."}),header:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.headerChars,description:"Very short decision label shown as a chip; aim for ~12 chars, max 32. E.g. 'Auth method'."}),options:typebox_exports.Array(OptionSchema,{minItems:MIN_OPTIONS,maxItems:MAX_OPTIONS,description:"Mutually distinct options for this decision; do not include reserved custom-answer labels."}),multiSelect:typebox_exports.Optional(typebox_exports.Boolean({description:"Allow selecting multiple options only when choices can be combined. Defaults to false for mutually exclusive decisions."}))}),QuestionParams=typebox_exports.Object({questions:typebox_exports.Array(QuestionSchema,{minItems:1,maxItems:MAX_QUESTIONS2,description:"Related decisions to ask now (1-4); ask only what is needed to unblock progress."})});function normalizeQuestionArguments(raw){if(raw===null||typeof raw!="object"||Array.isArray(raw))return raw;let args={...raw};if(typeof args.questions=="string")try{let parsed=JSON.parse(args.questions);Array.isArray(parsed)&&(args.questions=parsed)}catch{}let rootQuestion=typeof args.question=="string"?args.question:void 0,onlyQuestion=Array.isArray(args.questions)&&args.questions.length===1?args.questions[0]:void 0;if(rootQuestion!==void 0&&onlyQuestion!==null&&typeof onlyQuestion=="object"&&!Array.isArray(onlyQuestion)&&onlyQuestion.question===void 0)return args.questions=[{...onlyQuestion,question:rootQuestion}],delete args.question,args;if(args.questions===void 0&&rootQuestion!==void 0&&args.options!==void 0){let question2={question:rootQuestion,options:args.options};args.header!==void 0&&(question2.header=args.header),args.multiSelect!==void 0&&(question2.multiSelect=args.multiSelect),delete args.question,delete args.options,delete args.header,delete args.multiSelect,args.questions=[question2]}return args}function validateQuestions(questions){let requireNonBlank=(value,path14)=>{if(!(typeof value=="string"&&value.trim().length>0))return{ok:!1,error:"blank_text",message:`${path14} must contain visible text`}},seenQuestions=new Set;for(let questionIndex=0;questionIndex<questions.length;questionIndex++){let q2=questions[questionIndex],questionError=requireNonBlank(q2.question,`questions[${questionIndex}].question`);if(questionError)return questionError;let headerError=requireNonBlank(q2.header,`questions[${questionIndex}].header`);if(headerError)return headerError;let questionKey=normalizeLabel(q2.question);if(seenQuestions.has(questionKey))return{ok:!1,error:"duplicate_question",message:"Question text must be unique"};seenQuestions.add(questionKey);let seenLabels=new Set;for(let optionIndex=0;optionIndex<q2.options.length;optionIndex++){let option=q2.options[optionIndex],optionPath=`questions[${questionIndex}].options[${optionIndex}]`,labelError=requireNonBlank(option.label,`${optionPath}.label`);if(labelError)return labelError;let descriptionError=requireNonBlank(option.description,`${optionPath}.description`);if(descriptionError)return descriptionError;if(option.preview!==void 0){let previewError=requireNonBlank(option.preview,`${optionPath}.preview`);if(previewError)return previewError}let labelKey=normalizeLabel(option.label);if(RESERVED_NORMALIZED.has(labelKey))return{ok:!1,error:"reserved_label",message:`Option label is reserved (${RESERVED_LABELS.join(", ")})`};if(seenLabels.has(labelKey))return{ok:!1,error:"duplicate_option_label",message:"Option labels must be unique within a question"};seenLabels.add(labelKey)}if(q2.multiSelect&&q2.options.some(option=>option.preview))return{ok:!1,error:"preview_multiselect",message:"Option previews are not supported on multiSelect questions; drop the previews or make the question single-select"}}return{ok:!0}}function question(pi){pi.registerTool({name:QUESTION_TOOL_NAME,label:QUESTION_LABEL,description:QUESTION_DESCRIPTION,promptSnippet:QUESTION_PROMPT_SNIPPET,promptGuidelines:QUESTION_PROMPT_GUIDELINES,parameters:QuestionParams,constrainedSampling:{type:"json_schema",strict:"prefer"},prepareArguments:normalizeQuestionArguments,executionMode:"sequential",renderCall(args,theme2,context){return renderQuestionCall(args,theme2,context.expanded)},renderResult(result2,options,theme2,context){return renderQuestionResult(result2,options,theme2,context.args)},async execute(_toolCallId,params,signal,_onUpdate,ctx){if(!ctx.hasUI||ctx.mode!=="tui")return errorResult("no_ui","question tool requires an interactive TUI");let validation=validateQuestions(params.questions);if(!validation.ok)return errorResult(validation.error,validation.message);let result2=await ctx.ui.custom(createQuestionDialog(params.questions,signal));return result2.outcome==="cancelled"?cancelResult(result2.answers):result2.outcome==="needs_clarification"?clarificationResult(result2.answers):successResult(result2.answers)}}),pi.on("tool_result",async event=>{if(event.toolName!==QUESTION_TOOL_NAME)return;if(event.details?.outcome==="error")return{isError:!0}})}var CONTEXT_WARNING_PERCENT=40,CONTEXT_ERROR_PERCENT=80,MIN_GAP=1;function formatWorkingDirectory(cwd,home){let homeDirectory=home.replace(/[\\/]+$/,"");if(!homeDirectory)return cwd;let normalizePath3=filePath=>filePath.replace(/\\/g,"/").replace(/\/+$/,"").toLowerCase(),normalizedHomeDirectory=normalizePath3(homeDirectory),normalizedCwd=normalizePath3(cwd);return normalizedCwd===normalizedHomeDirectory?"~":normalizedCwd.startsWith(`${normalizedHomeDirectory}/`)?`~${cwd.slice(homeDirectory.length).replace(/\\/g,"/")}`:cwd}function pathBasename(displayPath){let normalized=displayPath.replace(/\\/g,"/").replace(/\/+$/,"");if(!normalized||normalized==="~")return normalized||displayPath;let slash=normalized.lastIndexOf("/");if(slash<0)return normalized;let base=normalized.slice(slash+1);return normalized.startsWith("~/")?`~/${base}`:base}function formatTokenCount2(count){return count<1e3?`${count}`:count<1e4?`${(count/1e3).toFixed(1)}k`:count<1e6?`${Math.round(count/1e3)}k`:count<1e7?`${(count/1e6).toFixed(1)}M`:`${Math.round(count/1e6)}M`}function joinSegments(segments,separator){return segments.filter(Boolean).join(separator)}function formatContextUsage(data,theme2){let contextWindow=data.contextUsage?.contextWindow??data.model?.contextWindow,suffix=contextWindow?`/${formatTokenCount2(contextWindow)}`:"",percent=data.contextUsage?.percent,label=`CTX ${percent==null?"?":percent.toFixed(1)}%${suffix}`;return percent!=null&&percent>CONTEXT_ERROR_PERCENT?theme2.fg("error",label):percent!=null&&percent>CONTEXT_WARNING_PERCENT?theme2.fg("warning",label):theme2.fg("accent",label)}function formatUsageCandidates(summary,subscription,theme2){let tokens2=[summary.input>0?`\u2191${formatTokenCount2(summary.input)}`:"",summary.output>0?`\u2193${formatTokenCount2(summary.output)}`:""],read=summary.cacheRead>0?`R${formatTokenCount2(summary.cacheRead)}`:"",write=summary.cacheWrite>0?`W${formatTokenCount2(summary.cacheWrite)}`:"",suffix=[summary.latestCacheHitPercent===void 0?"":`CH${summary.latestCacheHitPercent.toFixed(1)}%`,summary.cost>0?`$${summary.cost.toFixed(3)}${subscription?" (sub)":""}`:""],candidates=[[read,write],[read],[]].map(cache=>joinSegments([...tokens2,...cache,...suffix]," "));return[...new Set(candidates.filter(Boolean))].map(text2=>theme2.fg("dim",text2))}function formatExtensionStatuses(statuses,theme2){return[...statuses.entries()].sort(([first],[second])=>first.localeCompare(second)).map(([,text2])=>text2.replace(/[\r\n\t]/g," ").replace(/ +/g," ").trim()).filter(Boolean).map(text2=>text2.includes("\x1B[")?text2:theme2.fg("muted",text2)).join(" ")}function fitsLeftRight(left,right,width){return visibleWidth(left)+visibleWidth(right)+(left&&right?MIN_GAP:0)<=width}function layoutLeftRight(left,right,width,ellipsis){if(width<=0)return"";if(!right)return truncateToWidth(left,width,ellipsis);let rightWidth=visibleWidth(right);if(!left)return`${" ".repeat(Math.max(0,width-rightWidth))}${truncateToWidth(right,width,ellipsis)}`;let leftWidth=visibleWidth(left);if(leftWidth+rightWidth+MIN_GAP>width){let maxRightWidth=Math.min(rightWidth,Math.max(8,Math.floor(width*.45)));right=truncateToWidth(right,maxRightWidth,ellipsis),rightWidth=visibleWidth(right);let maxLeftWidth=width-rightWidth-MIN_GAP;if(maxLeftWidth<1)return truncateToWidth(right,width,ellipsis);left=truncateToWidth(left,maxLeftWidth,ellipsis),leftWidth=visibleWidth(left)}return`${left}${" ".repeat(Math.max(MIN_GAP,width-leftWidth-rightWidth))}${right}`}function layoutSecondaryLine(left,status,right,width,ellipsis){let leftWidth=visibleWidth(left),statusWidth=visibleWidth(status),rightWidth=visibleWidth(right),free=width-leftWidth-statusWidth-rightWidth;if(!status||free<MIN_GAP*2)return layoutLeftRight(left,right,width,ellipsis);let leftPad=Math.floor((width-statusWidth)/2)-leftWidth;return(leftPad<MIN_GAP||free-leftPad<MIN_GAP)&&(leftPad=Math.floor(free/2)),`${left}${" ".repeat(leftPad)}${status}${" ".repeat(free-leftPad)}${right}`}function renderPrimaryLine(data,theme2,width,ellipsis){let{model,thinkingLevel}=data,name=theme2.fg("toolTitle",theme2.bold(model?.name??model?.id??"no-model")),provider=model?.provider?theme2.fg("muted",`(${model.provider})`):"",effort=model?.reasoning&&thinkingLevel!=="off"?theme2.getThinkingBorderColor(thinkingLevel)(thinkingLevel):"",separator=theme2.fg("dim"," \xB7 "),rich=joinSegments([joinSegments([name,provider]," "),effort],separator),plain=joinSegments([name,effort],separator),cwd=formatWorkingDirectory(data.cwd,data.home),full=theme2.fg("success",cwd),short=theme2.fg("success",pathBasename(cwd)),branch=data.gitBranch?theme2.fg("accent",data.gitBranch):"",chosen=[{left:rich,right:joinSegments([full,branch],separator)},{left:rich,right:full},{left:rich,right:joinSegments([short,branch],separator)},{left:rich,right:short},{left:plain,right:joinSegments([short,branch],separator)},{left:plain,right:short},{left:plain,right:""}].find(({left,right})=>fitsLeftRight(left,right,width))??{left:plain,right:short};return layoutLeftRight(chosen.left,chosen.right,width,ellipsis)}function renderStatusline(data,theme2,width){let ellipsis=theme2.fg("dim","..."),primary=renderPrimaryLine(data,theme2,width,ellipsis),context=formatContextUsage(data,theme2),status=formatExtensionStatuses(data.statuses,theme2),candidates=formatUsageCandidates(data.usage,data.usesSubscription,theme2),usage=candidates.find(candidate=>fitsLeftRight(context,candidate,width)),secondary=candidates.length>0&&usage===void 0?layoutLeftRight(context,candidates[0],width,ellipsis):layoutSecondaryLine(context,status,usage??"",width,ellipsis);return[primary,secondary]}var BranchUsage=class{invalidate(){this.cached=void 0}read(manager){let sessionId=manager.getSessionId(),leafId=manager.getLeafId();if(this.cached?.manager===manager&&this.cached.sessionId===sessionId&&this.cached.leafId===leafId)return this.cached.usage;let entries=manager.getBranch(),totals=createUsageTotals();for(let usage2 of getAccountedUsages(entries))addUsageToTotals(totals,usage2);let latestCacheHitPercent;for(let index3=entries.length-1;index3>=0;index3--){let entry=entries[index3];if(entry.type!=="message"||entry.message.role!=="assistant")continue;let{input:input2,cacheRead,cacheWrite}=entry.message.usage,promptTokens=input2+cacheRead+cacheWrite;(cacheRead>0||cacheWrite>0)&&promptTokens>0&&(latestCacheHitPercent=cacheRead/promptTokens*100);break}let usage={...totals,latestCacheHitPercent};return this.cached={manager,sessionId,leafId,usage},usage}};function statusline(pi){pi.on("session_start",(_event,ctx)=>{ctx.mode==="tui"&&ctx.ui.setFooter((tui,theme2,footerData)=>{let usage=new BranchUsage;return{dispose:footerData.onBranchChange(()=>tui.requestRender()),invalidate(){usage.invalidate()},render(width){let model=ctx.model;return renderStatusline({model,thinkingLevel:ctx.thinkingLevel??"off",cwd:ctx.cwd,home:process.env.USERPROFILE||process.env.HOME||"",gitBranch:footerData.getGitBranch(),contextUsage:ctx.getContextUsage(),usage:usage.read(ctx.sessionManager),usesSubscription:model?ctx.modelRegistry.isUsingOAuth(model):!1,statuses:footerData.getExtensionStatuses()},theme2,width)}}})}),pi.on("session_shutdown",(_event,ctx)=>{ctx.mode==="tui"&&ctx.ui.setFooter(void 0)})}var MINIMAX_CN_HOST="https://api.minimaxi.com",MINIMAX_GLOBAL_HOST="https://api.minimax.io";function trimValue(value){return value?.trim()||void 0}async function runtimeApiKey(modelRuntime,providerId){if(modelRuntime)try{return trimValue((await modelRuntime.getAuth(providerId))?.auth.apiKey)}catch{return}}function storedApiKey(providerId,authPath){let credential=readStoredCredential(providerId,authPath);if(!credential||credential.type!=="api_key"||typeof credential.key!="string")return;let key=isCommandConfigValue(credential.key)?resolveConfigValue(credential.key,credential.env):credential.key;return trimValue(key)}async function resolveProviderKey(modelRuntime,authPath,providerId,envVar){return await runtimeApiKey(modelRuntime,providerId)??storedApiKey(providerId,authPath)??trimValue(process.env[envVar])}async function resolveMiniMaxCredential(modelRuntime,authPath){let cnKey=await resolveProviderKey(modelRuntime,authPath,"minimax-cn","MINIMAX_CN_API_KEY");if(cnKey)return{key:cnKey,host:MINIMAX_CN_HOST};let globalKey=await resolveProviderKey(modelRuntime,authPath,"minimax","MINIMAX_API_KEY");if(globalKey)return{key:globalKey,host:trimValue(process.env.MINIMAX_API_HOST)??MINIMAX_GLOBAL_HOST}}async function resolveDeepSeekCredential(modelRuntime,authPath){let key=await resolveProviderKey(modelRuntime,authPath,"deepseek","DEEPSEEK_API_KEY");return key?{key}:void 0}function configuredEngine(credentials){return credentials.minimax&&credentials.deepseek?"dual":credentials.minimax?"minimax":credentials.deepseek?"deepseek":"none"}async function resolveSearchCredentials(modelRuntime,authPath=getAuthPath()){let[minimax,deepseek]=await Promise.all([resolveMiniMaxCredential(modelRuntime,authPath),resolveDeepSeekCredential(modelRuntime,authPath)]);return{minimax,deepseek}}var WEB_SEARCH_TOOL_NAME="web_search",WEB_SEARCH_LABEL="Web Search",WEB_SEARCH_DESCRIPTION="Search the live web through configured MiniMax and DeepSeek providers. When both are available, searches run concurrently and results are deduplicated and fused. Returns up to 12 source URLs with bounded titles and snippets, plus related searches and optional synthesis; partial provider failures still return successful results.",WEB_SEARCH_PROMPT_SNIPPET="Search the live web for current information",WEB_SEARCH_DISABLED_MESSAGE="Web search is disabled: Neither MiniMax nor DeepSeek API Key was found in auth.json or environment variables. Please add credentials via auth.json or environment variables (MINIMAX_API_KEY, DEEPSEEK_API_KEY).";function getEngineLabel(engine){return engine==="dual"?"MiniMax & DeepSeek":engine==="minimax"?"MiniMax":engine==="deepseek"?"DeepSeek":""}function getWebSearchPromptGuidelines(){return["Use `web_search` for current information, recent releases, live documentation, and other freshness-sensitive facts beyond your training cutoff.",`When using \`web_search\` for freshness-sensitive topics, account for the current date (${new Date().toISOString().slice(0,7)}) and include the year in the query when useful.`]}var TRACKING_PARAMS=new Set(["utm_source","utm_medium","utm_campaign","utm_term","utm_content","ref","fbclid","gclid","trk","gi"]);function truncateText3(text2,maxLength){return text2.length<=maxLength?text2:maxLength<=3?text2.slice(0,maxLength):`${text2.slice(0,maxLength-3).trimEnd()}...`}function boundSingleLineText(value,maxLength){if(typeof value!="string")return;let normalized=value.replace(/\s+/g," ").trim();return normalized?truncateText3(normalized,maxLength):void 0}function boundMultilineText(value,maxLength){if(typeof value!="string")return;let normalized=value.trim();return normalized?truncateText3(normalized,maxLength):void 0}function normalizeUrl(rawUrl){if(typeof rawUrl!="string")return;let trimmed=rawUrl.trim();if(!(!trimmed||trimmed.length>2048))try{let url=new URL(trimmed);if(url.protocol!=="http:"&&url.protocol!=="https:")return;url.hash="";for(let parameter of TRACKING_PARAMS)url.searchParams.has(parameter)&&url.searchParams.delete(parameter);url.pathname.length>1&&url.pathname.endsWith("/")&&(url.pathname=url.pathname.replace(/\/+$/,""));let normalized=url.toString();return normalized.length<=2048?normalized:void 0}catch{return}}function normalizeHit(hit){let url=normalizeUrl(hit.url);if(url)return{title:boundSingleLineText(hit.title,200)??url,url,snippet:boundSingleLineText(hit.snippet,200),date:boundSingleLineText(hit.date,100)}}function isUrlFallbackTitle(title,url){let normalizedTitle=normalizeUrl(title);return normalizedTitle!==void 0&&normalizedTitle===normalizeUrl(url)}function reciprocalRankScore(candidate){let score=0;for(let rank of candidate.ranks.values())score+=1/(60+rank);return score}function bestRank(candidate){return Math.min(...candidate.ranks.values())}function fuseSearchHits(results){let candidates=new Map,relatedSearches=new Set,deepseekSynthesis;for(let result2 of results){let providerRelated=Array.isArray(result2.relatedSearches)?result2.relatedSearches:[],relatedScanLimit=Math.min(providerRelated.length,64);for(let index3=0;index3<relatedScanLimit&&relatedSearches.size<8;index3++){let normalized=boundSingleLineText(providerRelated[index3],200);normalized&&relatedSearches.add(normalized)}let synthesis=boundMultilineText(result2.synthesisText,6e3);synthesis&&(deepseekSynthesis=synthesis);let providerHits=Array.isArray(result2.hits)?result2.hits:[],hitScanLimit=Math.min(providerHits.length,200);for(let index3=0;index3<hitScanLimit;index3++){let rawHit=providerHits[index3];if(!rawHit)continue;let hit=normalizeHit(rawHit);if(!hit)continue;let rank=index3+1,existing=candidates.get(hit.url);if(!existing){candidates.set(hit.url,{hit,ranks:new Map([[result2.source,rank]])});continue}let previousRank=existing.ranks.get(result2.source);(previousRank===void 0||rank<previousRank)&&existing.ranks.set(result2.source,rank),isUrlFallbackTitle(existing.hit.title,existing.hit.url)&&!isUrlFallbackTitle(hit.title,hit.url)&&(existing.hit.title=hit.title),(!existing.hit.snippet||existing.hit.snippet.length<(hit.snippet?.length??0))&&hit.snippet&&(existing.hit.snippet=hit.snippet),!existing.hit.date&&hit.date&&(existing.hit.date=hit.date)}}return{hits:[...candidates.entries()].sort(([leftUrl,left],[rightUrl,right])=>{let scoreDifference=reciprocalRankScore(right)-reciprocalRankScore(left);if(scoreDifference!==0)return scoreDifference;let rankDifference=bestRank(left)-bestRank(right);return rankDifference!==0?rankDifference:leftUrl.localeCompare(rightUrl)}).map(([,candidate])=>({...candidate.hit,sources:[...candidate.ranks.keys()]})).slice(0,12),relatedSearches:relatedSearches.size>0?[...relatedSearches]:void 0,deepseekSynthesis}}var MAX_RESPONSE_BODY_BYTES=2*1024*1024,MAX_ERROR_BODY_BYTES2=200;async function postJson(url,headers,body,signal,timeoutMs,errorLabel){let timeoutSignal=AbortSignal.timeout(timeoutMs),requestSignal=signal?AbortSignal.any([signal,timeoutSignal]):timeoutSignal,response=await fetch(url,{method:"POST",headers,body:JSON.stringify(body),signal:requestSignal});if(!response.ok){let errorText3="";try{errorText3=await readResponseTextBounded(response,{maxBytes:MAX_ERROR_BODY_BYTES2,signal:requestSignal})}catch{requestSignal.throwIfAborted()}throw new Error(`${errorLabel} returned HTTP ${response.status} ${response.statusText}: ${errorText3}`)}let responseText=await readResponseTextBounded(response,{maxBytes:MAX_RESPONSE_BODY_BYTES,overflowMessage:`${errorLabel} response exceeded ${MAX_RESPONSE_BODY_BYTES} bytes`,signal:requestSignal});try{return JSON.parse(responseText)}catch{throw new Error(`${errorLabel} returned invalid JSON`)}}var DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT="https://api.deepseek.com/anthropic/v1/messages",DEFAULT_DEEPSEEK_SEARCH_MODEL="claude-sonnet-search";function isRecord7(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function stringField(record,key){let value=record[key];return typeof value=="string"?value:void 0}function parseSearchHit(value){if(!isRecord7(value)||value.type!=="web_search_result")return;let url=stringField(value,"url")?.trim();if(!url)return;let title=stringField(value,"title")?.trim(),pageAge=stringField(value,"page_age")?.trim();return{title:title||url,url,date:pageAge||void 0}}function errorMessage8(value){if(isRecord7(value))return stringField(value,"message")||stringField(value,"type")||"Unknown error"}function searchToolErrorMessage(value){return stringField(value,"message")?.trim()||stringField(value,"error_code")?.trim()||stringField(value,"type")?.trim()||"Unknown search tool error"}function parseSearchToolContent(value){if(Array.isArray(value)){let hits=[];for(let item of value){let hit=parseSearchHit(item);if(!hit)throw new Error("DeepSeek returned malformed web_search_tool_result content");hits.length<200&&hits.push(hit)}return hits}throw isRecord7(value)?value.type==="web_search_tool_result_error"||value.error_code!==void 0||value.message!==void 0?new Error(`DeepSeek web search failed: ${searchToolErrorMessage(value)}`):new Error("DeepSeek returned malformed web_search_tool_result content"):new Error("DeepSeek returned malformed web_search_tool_result content")}async function searchDeepSeek(options){let endpoint=options.baseUrl||DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT,model=options.model||DEFAULT_DEEPSEEK_SEARCH_MODEL,rawData=await postJson(endpoint,{"Content-Type":"application/json","x-api-key":options.apiKey,Authorization:`Bearer ${options.apiKey}`,"anthropic-version":"2023-06-01"},{model,max_tokens:1024,messages:[{role:"user",content:options.query}],tools:[{type:"web_search_20250305",name:"web_search"}]},options.signal,9e4,"DeepSeek Messages search API"),data=isRecord7(rawData)?rawData:{},upstreamError=errorMessage8(data.error);if(upstreamError)throw new Error(`DeepSeek search error: ${upstreamError}`);let hits=[],synthesisParts=[],sawStructuredResult=!1,content=Array.isArray(data.content)?data.content:[];for(let value of content)if(isRecord7(value)){if(value.type==="web_search_tool_result"){sawStructuredResult=!0;for(let hit of parseSearchToolContent(value.content))hits.length<200&&hits.push(hit);continue}if(value.type==="text"){let text2=stringField(value,"text")?.trim();text2&&synthesisParts.push(text2)}}if(!sawStructuredResult)throw new Error("DeepSeek returned no web_search_tool_result block");return{source:"DeepSeek",hits,synthesisText:synthesisParts.length>0?synthesisParts.join(`
|
|
1974
|
+
`)}`,0,0)}function renderQuestionResult(result2,options,theme2,args){let details=normalizeDetails(result2.details);if(!details)return renderFallbackResult(result2,options.expanded,theme2);if(details.outcome==="error")return new Text(theme2.fg("error",`Question error: ${errorMessage7(details)}`),0,0);if(details.outcome==="cancelled"){let title2=theme2.fg("warning",`Cancelled \xB7 ${answerProgress(details,args)}`);return renderOutcome(title2,details,options.expanded,theme2)}if(details.outcome==="needs_clarification"){let title2=theme2.fg("warning",`Wants to discuss \xB7 ${answerProgress(details,args)}`);return renderOutcome(title2,details,options.expanded,theme2)}let title=theme2.fg("success",`\u2713 Answered ${details.answers.length} decision${details.answers.length===1?"":"s"}`);return renderOutcome(title,details,options.expanded,theme2)}var MIN_OPTIONS=2,MAX_OPTIONS=4,MAX_QUESTIONS2=4,RESERVED_LABELS=["Other","Type something","Type something.","Chat about this"],normalizeLabel=text2=>text2.trim().toLowerCase(),RESERVED_NORMALIZED=new Set(RESERVED_LABELS.map(normalizeLabel)),OptionSchema=typebox_exports.Object({label:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.optionLabelChars,description:"Short user-facing option label (1-5 words), distinct within the question. Reserved labels ('Other', 'Type something', 'Chat about this') are rejected \u2014 the UI adds the custom-answer path itself."}),description:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.optionDescriptionChars,description:"One concise sentence explaining the option's meaning, consequence, or tradeoff."}),preview:typebox_exports.Optional(typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.previewChars,description:"Optional markdown preview shown only for focused single-select options; use for concrete snippets, layouts, copy, or config comparisons."}))}),QuestionSchema=typebox_exports.Object({question:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.questionChars,description:"One clear, specific decision or preference question ending in a question mark. Ask only what is needed to proceed."}),header:typebox_exports.String({minLength:1,maxLength:QUESTION_LIMITS.headerChars,description:"Very short decision label shown as a chip; aim for ~12 chars, max 32. E.g. 'Auth method'."}),options:typebox_exports.Array(OptionSchema,{minItems:MIN_OPTIONS,maxItems:MAX_OPTIONS,description:"Mutually distinct options for this decision; do not include reserved custom-answer labels."}),multiSelect:typebox_exports.Optional(typebox_exports.Boolean({description:"Allow selecting multiple options only when choices can be combined. Defaults to false for mutually exclusive decisions."}))}),QuestionParams=typebox_exports.Object({questions:typebox_exports.Array(QuestionSchema,{minItems:1,maxItems:MAX_QUESTIONS2,description:"Related decisions to ask now (1-4); ask only what is needed to unblock progress."})});function normalizeQuestionArguments(raw){if(raw===null||typeof raw!="object"||Array.isArray(raw))return raw;let args={...raw};if(typeof args.questions=="string")try{let parsed=JSON.parse(args.questions);Array.isArray(parsed)&&(args.questions=parsed)}catch{}let rootQuestion=typeof args.question=="string"?args.question:void 0,onlyQuestion=Array.isArray(args.questions)&&args.questions.length===1?args.questions[0]:void 0;if(rootQuestion!==void 0&&onlyQuestion!==null&&typeof onlyQuestion=="object"&&!Array.isArray(onlyQuestion)&&onlyQuestion.question===void 0)return args.questions=[{...onlyQuestion,question:rootQuestion}],delete args.question,args;if(args.questions===void 0&&rootQuestion!==void 0&&args.options!==void 0){let question2={question:rootQuestion,options:args.options};args.header!==void 0&&(question2.header=args.header),args.multiSelect!==void 0&&(question2.multiSelect=args.multiSelect),delete args.question,delete args.options,delete args.header,delete args.multiSelect,args.questions=[question2]}return args}function validateQuestions(questions){let requireNonBlank=(value,path14)=>{if(!(typeof value=="string"&&value.trim().length>0))return{ok:!1,error:"blank_text",message:`${path14} must contain visible text`}},seenQuestions=new Set;for(let questionIndex=0;questionIndex<questions.length;questionIndex++){let q2=questions[questionIndex],questionError=requireNonBlank(q2.question,`questions[${questionIndex}].question`);if(questionError)return questionError;let headerError=requireNonBlank(q2.header,`questions[${questionIndex}].header`);if(headerError)return headerError;let questionKey=normalizeLabel(q2.question);if(seenQuestions.has(questionKey))return{ok:!1,error:"duplicate_question",message:"Question text must be unique"};seenQuestions.add(questionKey);let seenLabels=new Set;for(let optionIndex=0;optionIndex<q2.options.length;optionIndex++){let option=q2.options[optionIndex],optionPath=`questions[${questionIndex}].options[${optionIndex}]`,labelError=requireNonBlank(option.label,`${optionPath}.label`);if(labelError)return labelError;let descriptionError=requireNonBlank(option.description,`${optionPath}.description`);if(descriptionError)return descriptionError;if(option.preview!==void 0){let previewError=requireNonBlank(option.preview,`${optionPath}.preview`);if(previewError)return previewError}let labelKey=normalizeLabel(option.label);if(RESERVED_NORMALIZED.has(labelKey))return{ok:!1,error:"reserved_label",message:`Option label is reserved (${RESERVED_LABELS.join(", ")})`};if(seenLabels.has(labelKey))return{ok:!1,error:"duplicate_option_label",message:"Option labels must be unique within a question"};seenLabels.add(labelKey)}if(q2.multiSelect&&q2.options.some(option=>option.preview))return{ok:!1,error:"preview_multiselect",message:"Option previews are not supported on multiSelect questions; drop the previews or make the question single-select"}}return{ok:!0}}function question(pi){pi.registerTool({name:QUESTION_TOOL_NAME,label:QUESTION_LABEL,description:QUESTION_DESCRIPTION,promptSnippet:QUESTION_PROMPT_SNIPPET,promptGuidelines:QUESTION_PROMPT_GUIDELINES,parameters:QuestionParams,constrainedSampling:{type:"json_schema",strict:"prefer"},prepareArguments:normalizeQuestionArguments,executionMode:"sequential",renderCall(args,theme2,context){return renderQuestionCall(args,theme2,context.expanded)},renderResult(result2,options,theme2,context){return renderQuestionResult(result2,options,theme2,context.args)},async execute(_toolCallId,params,signal,_onUpdate,ctx){if(!ctx.hasUI||ctx.mode!=="tui")return errorResult("no_ui","question tool requires an interactive TUI");let validation=validateQuestions(params.questions);if(!validation.ok)return errorResult(validation.error,validation.message);let result2=await ctx.ui.custom(createQuestionDialog(params.questions,signal));return result2.outcome==="cancelled"?cancelResult(result2.answers):result2.outcome==="needs_clarification"?clarificationResult(result2.answers):successResult(result2.answers)}}),pi.on("tool_result",async event=>{if(event.toolName!==QUESTION_TOOL_NAME)return;if(event.details?.outcome==="error")return{isError:!0}})}var CONTEXT_WARNING_PERCENT=40,CONTEXT_ERROR_PERCENT=80,MIN_GAP=1;function formatWorkingDirectory(cwd,home){let homeDirectory=home.replace(/[\\/]+$/,"");if(!homeDirectory)return cwd;let normalizePath3=filePath=>filePath.replace(/\\/g,"/").replace(/\/+$/,"").toLowerCase(),normalizedHomeDirectory=normalizePath3(homeDirectory),normalizedCwd=normalizePath3(cwd);return normalizedCwd===normalizedHomeDirectory?"~":normalizedCwd.startsWith(`${normalizedHomeDirectory}/`)?`~${cwd.slice(homeDirectory.length).replace(/\\/g,"/")}`:cwd}function pathBasename(displayPath){let normalized=displayPath.replace(/\\/g,"/").replace(/\/+$/,"");if(!normalized||normalized==="~")return normalized||displayPath;let slash=normalized.lastIndexOf("/");if(slash<0)return normalized;let base=normalized.slice(slash+1);return normalized.startsWith("~/")?`~/${base}`:base}function formatTokenCount2(count){return count<1e3?`${count}`:count<1e4?`${(count/1e3).toFixed(1)}k`:count<1e6?`${Math.round(count/1e3)}k`:count<1e7?`${(count/1e6).toFixed(1)}M`:`${Math.round(count/1e6)}M`}function joinSegments(segments,separator){return segments.filter(Boolean).join(separator)}function formatContextUsage(data,theme2){let contextWindow=data.contextUsage?.contextWindow??data.model?.contextWindow,suffix=contextWindow?`/${formatTokenCount2(contextWindow)}`:"",percent=data.contextUsage?.percent,label=`CTX ${percent==null?"?":percent.toFixed(1)}%${suffix}`;return percent!=null&&percent>CONTEXT_ERROR_PERCENT?theme2.fg("error",label):percent!=null&&percent>CONTEXT_WARNING_PERCENT?theme2.fg("warning",label):theme2.fg("accent",label)}function formatUsageCandidates(summary,subscription,theme2){let tokens2=[summary.input>0?`\u2191${formatTokenCount2(summary.input)}`:"",summary.output>0?`\u2193${formatTokenCount2(summary.output)}`:""],read=summary.cacheRead>0?`R${formatTokenCount2(summary.cacheRead)}`:"",write=summary.cacheWrite>0?`W${formatTokenCount2(summary.cacheWrite)}`:"",suffix=[summary.latestCacheHitPercent===void 0?"":`CH${summary.latestCacheHitPercent.toFixed(1)}%`,summary.cost>0?`$${summary.cost.toFixed(3)}${subscription?" (sub)":""}`:""],candidates=[[read,write],[read],[]].map(cache=>joinSegments([...tokens2,...cache,...suffix]," "));return[...new Set(candidates.filter(Boolean))].map(text2=>theme2.fg("dim",text2))}function formatExtensionStatuses(statuses,theme2){return[...statuses.entries()].sort(([first],[second])=>first.localeCompare(second)).map(([,text2])=>text2.replace(/[\r\n\t]/g," ").replace(/ +/g," ").trim()).filter(Boolean).map(text2=>text2.includes("\x1B[")?text2:theme2.fg("muted",text2)).join(" ")}function fitsLeftRight(left,right,width){return visibleWidth(left)+visibleWidth(right)+(left&&right?MIN_GAP:0)<=width}function layoutLeftRight(left,right,width,ellipsis){if(width<=0)return"";if(!right)return truncateToWidth(left,width,ellipsis);let rightWidth=visibleWidth(right);if(!left)return`${" ".repeat(Math.max(0,width-rightWidth))}${truncateToWidth(right,width,ellipsis)}`;let leftWidth=visibleWidth(left);if(leftWidth+rightWidth+MIN_GAP>width){let maxRightWidth=Math.min(rightWidth,Math.max(8,Math.floor(width*.45)));right=truncateToWidth(right,maxRightWidth,ellipsis),rightWidth=visibleWidth(right);let maxLeftWidth=width-rightWidth-MIN_GAP;if(maxLeftWidth<1)return truncateToWidth(right,width,ellipsis);left=truncateToWidth(left,maxLeftWidth,ellipsis),leftWidth=visibleWidth(left)}return`${left}${" ".repeat(Math.max(MIN_GAP,width-leftWidth-rightWidth))}${right}`}function layoutSecondaryLine(left,status,right,width,ellipsis){let leftWidth=visibleWidth(left),statusWidth=visibleWidth(status),rightWidth=visibleWidth(right),free=width-leftWidth-statusWidth-rightWidth;if(!status||free<MIN_GAP*2)return layoutLeftRight(left,right,width,ellipsis);let leftPad=Math.floor((width-statusWidth)/2)-leftWidth;return(leftPad<MIN_GAP||free-leftPad<MIN_GAP)&&(leftPad=Math.floor(free/2)),`${left}${" ".repeat(leftPad)}${status}${" ".repeat(free-leftPad)}${right}`}function renderPrimaryLine(data,theme2,width,ellipsis){let{model,thinkingLevel}=data,name=theme2.fg("toolTitle",theme2.bold(model?.name??model?.id??"no-model")),provider=model?.provider?theme2.fg("muted",`(${model.provider})`):"",effort=model?.reasoning&&thinkingLevel!=="off"?theme2.getThinkingBorderColor(thinkingLevel)(thinkingLevel):"",separator=theme2.fg("dim"," \xB7 "),rich=joinSegments([joinSegments([name,provider]," "),effort],separator),plain=joinSegments([name,effort],separator),cwd=formatWorkingDirectory(data.cwd,data.home),full=theme2.fg("success",cwd),short=theme2.fg("success",pathBasename(cwd)),branch=data.gitBranch?theme2.fg("accent",data.gitBranch):"",chosen=[{left:rich,right:joinSegments([full,branch],separator)},{left:rich,right:full},{left:rich,right:joinSegments([short,branch],separator)},{left:rich,right:short},{left:plain,right:joinSegments([short,branch],separator)},{left:plain,right:short},{left:plain,right:""}].find(({left,right})=>fitsLeftRight(left,right,width))??{left:plain,right:short};return layoutLeftRight(chosen.left,chosen.right,width,ellipsis)}function renderStatusline(data,theme2,width){let ellipsis=theme2.fg("dim","..."),primary=renderPrimaryLine(data,theme2,width,ellipsis),context=formatContextUsage(data,theme2),status=formatExtensionStatuses(data.statuses,theme2),candidates=formatUsageCandidates(data.usage,data.usesSubscription,theme2),usage=candidates.find(candidate=>fitsLeftRight(context,candidate,width)),secondary=candidates.length>0&&usage===void 0?layoutLeftRight(context,candidates[0],width,ellipsis):layoutSecondaryLine(context,status,usage??"",width,ellipsis);return[primary,secondary]}var BranchUsage=class{invalidate(){this.cached=void 0}read(manager){let sessionId=manager.getSessionId(),leafId=manager.getLeafId();if(this.cached?.manager===manager&&this.cached.sessionId===sessionId&&this.cached.leafId===leafId)return this.cached.usage;let entries=manager.getBranch(),totals=createUsageTotals();for(let usage2 of getAccountedUsages(entries))addUsageToTotals(totals,usage2);let latestCacheHitPercent;for(let index3=entries.length-1;index3>=0;index3--){let entry=entries[index3];if(entry.type!=="message"||entry.message.role!=="assistant")continue;let{input:input2,cacheRead,cacheWrite}=entry.message.usage,promptTokens=input2+cacheRead+cacheWrite;(cacheRead>0||cacheWrite>0)&&promptTokens>0&&(latestCacheHitPercent=cacheRead/promptTokens*100);break}let usage={...totals,latestCacheHitPercent};return this.cached={manager,sessionId,leafId,usage},usage}};function statusline(pi){pi.on("session_start",(_event,ctx)=>{ctx.mode==="tui"&&ctx.ui.setFooter((tui,theme2,footerData)=>{let usage=new BranchUsage;return{dispose:footerData.onBranchChange(()=>tui.requestRender()),invalidate(){usage.invalidate()},render(width){let model=ctx.model;return renderStatusline({model,thinkingLevel:ctx.thinkingLevel??"off",cwd:ctx.cwd,home:process.env.USERPROFILE||process.env.HOME||"",gitBranch:footerData.getGitBranch(),contextUsage:ctx.getContextUsage(),usage:usage.read(ctx.sessionManager),usesSubscription:model?ctx.modelRegistry.isUsingOAuth(model):!1,statuses:footerData.getExtensionStatuses()},theme2,width)}}})}),pi.on("session_shutdown",(_event,ctx)=>{ctx.mode==="tui"&&ctx.ui.setFooter(void 0)})}var MINIMAX_CN_HOST="https://api.minimaxi.com",MINIMAX_GLOBAL_HOST="https://api.minimax.io";function trimValue(value){return value?.trim()||void 0}async function runtimeApiKey(modelRuntime,providerId){if(modelRuntime)try{return trimValue((await modelRuntime.getAuth(providerId))?.auth.apiKey)}catch{return}}function storedApiKey(providerId,authPath){let credential=readStoredCredential(providerId,authPath);if(!credential||credential.type!=="api_key"||typeof credential.key!="string")return;let key=isCommandConfigValue(credential.key)?resolveConfigValue(credential.key,credential.env):credential.key;return trimValue(key)}async function resolveProviderKey(modelRuntime,authPath,providerId,envVar){return await runtimeApiKey(modelRuntime,providerId)??storedApiKey(providerId,authPath)??trimValue(process.env[envVar])}async function resolveMiniMaxCredential(modelRuntime,authPath){let cnKey=await resolveProviderKey(modelRuntime,authPath,"minimax-cn","MINIMAX_CN_API_KEY");if(cnKey)return{key:cnKey,host:MINIMAX_CN_HOST};let globalKey=await resolveProviderKey(modelRuntime,authPath,"minimax","MINIMAX_API_KEY");if(globalKey)return{key:globalKey,host:trimValue(process.env.MINIMAX_API_HOST)??MINIMAX_GLOBAL_HOST}}async function resolveDeepSeekCredential(modelRuntime,authPath){let key=await resolveProviderKey(modelRuntime,authPath,"deepseek","DEEPSEEK_API_KEY");return key?{key}:void 0}function configuredEngine(credentials){return credentials.minimax&&credentials.deepseek?"dual":credentials.minimax?"minimax":credentials.deepseek?"deepseek":"none"}async function resolveSearchCredentials(modelRuntime,authPath=getAuthPath()){let[minimax,deepseek]=await Promise.all([resolveMiniMaxCredential(modelRuntime,authPath),resolveDeepSeekCredential(modelRuntime,authPath)]);return{minimax,deepseek}}var WEB_SEARCH_TOOL_NAME="web_search",WEB_SEARCH_LABEL="Web Search",WEB_SEARCH_DESCRIPTION="Search the live web through configured MiniMax and DeepSeek providers. When both are available, searches run concurrently and results are deduplicated and fused. Returns up to 12 source URLs with bounded titles and snippets, plus related searches and optional synthesis; partial provider failures still return successful results.",WEB_SEARCH_PROMPT_SNIPPET="Search the live web for current information",WEB_SEARCH_DISABLED_MESSAGE="Web search is disabled: Neither MiniMax nor DeepSeek API Key was found in auth.json or environment variables. Please add credentials via auth.json or environment variables (MINIMAX_API_KEY, DEEPSEEK_API_KEY).";function getEngineLabel(engine){return engine==="dual"?"MiniMax & DeepSeek":engine==="minimax"?"MiniMax":engine==="deepseek"?"DeepSeek":""}function getWebSearchPromptGuidelines(){return["Use `web_search` for current information, recent releases, live documentation, and other freshness-sensitive facts beyond your training cutoff.",`When using \`web_search\` for freshness-sensitive topics, account for the current date (${new Date().toISOString().slice(0,7)}) and include the year in the query when useful.`]}var TRACKING_PARAMS=new Set(["utm_source","utm_medium","utm_campaign","utm_term","utm_content","ref","fbclid","gclid","trk","gi"]);function truncateText3(text2,maxLength){return text2.length<=maxLength?text2:maxLength<=3?text2.slice(0,maxLength):`${text2.slice(0,maxLength-3).trimEnd()}...`}function boundSingleLineText(value,maxLength){if(typeof value!="string")return;let normalized=value.replace(/\s+/g," ").trim();return normalized?truncateText3(normalized,maxLength):void 0}function boundMultilineText(value,maxLength){if(typeof value!="string")return;let normalized=value.trim();return normalized?truncateText3(normalized,maxLength):void 0}function normalizeUrl(rawUrl){if(typeof rawUrl!="string")return;let trimmed=rawUrl.trim();if(!(!trimmed||trimmed.length>2048))try{let url=new URL(trimmed);if(url.protocol!=="http:"&&url.protocol!=="https:")return;url.hash="";for(let parameter of TRACKING_PARAMS)url.searchParams.has(parameter)&&url.searchParams.delete(parameter);url.pathname.length>1&&url.pathname.endsWith("/")&&(url.pathname=url.pathname.replace(/\/+$/,""));let normalized=url.toString();return normalized.length<=2048?normalized:void 0}catch{return}}function normalizeHit(hit){let url=normalizeUrl(hit.url);if(url)return{title:boundSingleLineText(hit.title,200)??url,url,snippet:boundSingleLineText(hit.snippet,200),date:boundSingleLineText(hit.date,100)}}function isUrlFallbackTitle(title,url){let normalizedTitle=normalizeUrl(title);return normalizedTitle!==void 0&&normalizedTitle===normalizeUrl(url)}function reciprocalRankScore(candidate){let score=0;for(let rank of candidate.ranks.values())score+=1/(60+rank);return score}function bestRank(candidate){return Math.min(...candidate.ranks.values())}function fuseSearchHits(results){let candidates=new Map,relatedSearches=new Set,deepseekSynthesis;for(let result2 of results){let providerRelated=Array.isArray(result2.relatedSearches)?result2.relatedSearches:[],relatedScanLimit=Math.min(providerRelated.length,64);for(let index3=0;index3<relatedScanLimit&&relatedSearches.size<8;index3++){let normalized=boundSingleLineText(providerRelated[index3],200);normalized&&relatedSearches.add(normalized)}let synthesis=boundMultilineText(result2.synthesisText,6e3);synthesis&&(deepseekSynthesis=synthesis);let providerHits=Array.isArray(result2.hits)?result2.hits:[],hitScanLimit=Math.min(providerHits.length,200);for(let index3=0;index3<hitScanLimit;index3++){let rawHit=providerHits[index3];if(!rawHit)continue;let hit=normalizeHit(rawHit);if(!hit)continue;let rank=index3+1,existing=candidates.get(hit.url);if(!existing){candidates.set(hit.url,{hit,ranks:new Map([[result2.source,rank]])});continue}let previousRank=existing.ranks.get(result2.source);(previousRank===void 0||rank<previousRank)&&existing.ranks.set(result2.source,rank),isUrlFallbackTitle(existing.hit.title,existing.hit.url)&&!isUrlFallbackTitle(hit.title,hit.url)&&(existing.hit.title=hit.title),(!existing.hit.snippet||existing.hit.snippet.length<(hit.snippet?.length??0))&&hit.snippet&&(existing.hit.snippet=hit.snippet),!existing.hit.date&&hit.date&&(existing.hit.date=hit.date)}}return{hits:[...candidates.entries()].sort(([leftUrl,left],[rightUrl,right])=>{let scoreDifference=reciprocalRankScore(right)-reciprocalRankScore(left);if(scoreDifference!==0)return scoreDifference;let rankDifference=bestRank(left)-bestRank(right);return rankDifference!==0?rankDifference:leftUrl.localeCompare(rightUrl)}).map(([,candidate])=>({...candidate.hit,sources:[...candidate.ranks.keys()]})).slice(0,12),relatedSearches:relatedSearches.size>0?[...relatedSearches]:void 0,deepseekSynthesis}}var MAX_RESPONSE_BODY_BYTES=2*1024*1024,MAX_ERROR_BODY_BYTES2=200;async function postJson(url,headers,body,signal,timeoutMs,errorLabel){let timeoutSignal=AbortSignal.timeout(timeoutMs),requestSignal=signal?AbortSignal.any([signal,timeoutSignal]):timeoutSignal,response=await fetch(url,{method:"POST",headers,body:JSON.stringify(body),signal:requestSignal});if(!response.ok){let errorText3="";try{errorText3=await readResponseTextBounded(response,{maxBytes:MAX_ERROR_BODY_BYTES2,signal:requestSignal})}catch{requestSignal.throwIfAborted()}throw new Error(`${errorLabel} returned HTTP ${response.status} ${response.statusText}: ${errorText3}`)}let responseText=await readResponseTextBounded(response,{maxBytes:MAX_RESPONSE_BODY_BYTES,overflowMessage:`${errorLabel} response exceeded ${MAX_RESPONSE_BODY_BYTES} bytes`,signal:requestSignal});try{return JSON.parse(responseText)}catch{throw new Error(`${errorLabel} returned invalid JSON`)}}var DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT="https://api.deepseek.com/anthropic/v1/messages",DEFAULT_DEEPSEEK_SEARCH_MODEL="claude-sonnet-search";function isRecord7(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function stringField(record,key){let value=record[key];return typeof value=="string"?value:void 0}function parseSearchHit(value){if(!isRecord7(value)||value.type!=="web_search_result")return;let url=stringField(value,"url")?.trim();if(!url)return;let title=stringField(value,"title")?.trim(),pageAge=stringField(value,"page_age")?.trim();return{title:title||url,url,date:pageAge||void 0}}function errorMessage8(value){if(isRecord7(value))return stringField(value,"message")||stringField(value,"type")||"Unknown error"}function searchToolErrorMessage(value){return stringField(value,"message")?.trim()||stringField(value,"error_code")?.trim()||stringField(value,"type")?.trim()||"Unknown search tool error"}function parseSearchToolContent(value){if(Array.isArray(value)){let hits=[];for(let item of value){let hit=parseSearchHit(item);if(!hit)throw new Error("DeepSeek returned malformed web_search_tool_result content");hits.length<200&&hits.push(hit)}return hits}throw isRecord7(value)?value.type==="web_search_tool_result_error"||value.error_code!==void 0||value.message!==void 0?new Error(`DeepSeek web search failed: ${searchToolErrorMessage(value)}`):new Error("DeepSeek returned malformed web_search_tool_result content"):new Error("DeepSeek returned malformed web_search_tool_result content")}async function searchDeepSeek(options){let endpoint=options.baseUrl||DEFAULT_DEEPSEEK_MESSAGES_ENDPOINT,model=options.model||DEFAULT_DEEPSEEK_SEARCH_MODEL,rawData=await postJson(endpoint,{"Content-Type":"application/json","x-api-key":options.apiKey,Authorization:`Bearer ${options.apiKey}`,"anthropic-version":"2023-06-01"},{model,max_tokens:1024,messages:[{role:"user",content:options.query}],tools:[{type:"web_search_20250305",name:"web_search"}]},options.signal,9e4,"DeepSeek Messages search API"),data=isRecord7(rawData)?rawData:{},upstreamError=errorMessage8(data.error);if(upstreamError)throw new Error(`DeepSeek search error: ${upstreamError}`);let hits=[],synthesisParts=[],sawStructuredResult=!1,content=Array.isArray(data.content)?data.content:[];for(let value of content)if(isRecord7(value)){if(value.type==="web_search_tool_result"){sawStructuredResult=!0;for(let hit of parseSearchToolContent(value.content))hits.length<200&&hits.push(hit);continue}if(value.type==="text"){let text2=stringField(value,"text")?.trim();text2&&synthesisParts.push(text2)}}if(!sawStructuredResult)throw new Error("DeepSeek returned no web_search_tool_result block");return{source:"DeepSeek",hits,synthesisText:synthesisParts.length>0?synthesisParts.join(`
|
|
1969
1975
|
|
|
1970
1976
|
`):void 0}}function isRecord8(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function stringField2(record,key){let value=record[key];return typeof value=="string"?value:void 0}function parseSearchHit2(value){if(!isRecord8(value))return;let url=stringField2(value,"link")?.trim();if(url)return{title:stringField2(value,"title")?.trim()||url,url,snippet:stringField2(value,"snippet")?.trim()||void 0,date:stringField2(value,"date")?.trim()||void 0}}async function searchMiniMax(options){let host=options.apiHost?.replace(/\/+$/,"")||"https://api.minimaxi.com",rawData=await postJson(`${host}/v1/coding_plan/search`,{"Content-Type":"application/json",Authorization:`Bearer ${options.apiKey}`},{q:options.query.trim()},options.signal,6e4,"MiniMax search API"),data=isRecord8(rawData)?rawData:{},baseResponse=isRecord8(data.base_resp)?data.base_resp:void 0,statusCode=baseResponse?.status_code;if(baseResponse&&typeof statusCode=="number"&&statusCode!==0)throw new Error(`MiniMax search failed: [${statusCode}] ${stringField2(baseResponse,"status_msg")??"Unknown error"}`);let hits=[],organic=Array.isArray(data.organic)?data.organic:[],hitScanLimit=Math.min(organic.length,200);for(let index3=0;index3<hitScanLimit;index3++){let hit=parseSearchHit2(organic[index3]);hit&&hits.push(hit)}let relatedSearches=[],related=Array.isArray(data.related_searches)?data.related_searches:[],relatedScanLimit=Math.min(related.length,64);for(let index3=0;index3<relatedScanLimit&&relatedSearches.length<8;index3++){let value=related[index3],query=isRecord8(value)?stringField2(value,"query")?.trim():void 0;query&&relatedSearches.push(query)}return{source:"MiniMax",hits,relatedSearches:relatedSearches.length>0?relatedSearches:void 0}}async function executeWebSearch(params,credentials,signal,onUpdate){let startTime=Date.now(),query=boundSingleLineText(params.query,500)??"",engine=configuredEngine(credentials);if(!query)return{query:"",durationMs:0,status:"error",engine,totalHits:0,hits:[],errorMessage:"Search query must not be empty."};if(engine==="none")return{query,durationMs:0,status:"disabled",engine:"none",totalHits:0,hits:[],errorMessage:WEB_SEARCH_DISABLED_MESSAGE};signal?.throwIfAborted(),onUpdate?.({content:[{type:"text",text:`Searching for "${query}" via ${getEngineLabel(engine)}...`}],details:{query,durationMs:0,status:"success",engine,totalHits:0,hits:[]}});let searches=[];credentials.minimax&&searches.push(searchMiniMax({query,apiKey:credentials.minimax.key,apiHost:credentials.minimax.host,signal})),credentials.deepseek&&searches.push(searchDeepSeek({query,apiKey:credentials.deepseek.key,signal}));let settledResults=await Promise.allSettled(searches);signal?.throwIfAborted();let durationMs=Date.now()-startTime,successfulResults=[],errors=[];for(let result2 of settledResults)result2.status==="fulfilled"?successfulResults.push(result2.value):errors.push(result2.reason instanceof Error?result2.reason.message:String(result2.reason));if(successfulResults.length===0)return{query,durationMs,status:"error",engine,totalHits:0,hits:[],errorMessage:boundSingleLineText(errors.join(" | "),500)??"All search engines failed"};let{hits,relatedSearches,deepseekSynthesis}=fuseSearchHits(successfulResults),respondedSources=new Set(successfulResults.map(result2=>result2.source)),contributingEngine=respondedSources.size>1?"dual":respondedSources.has("MiniMax")?"minimax":"deepseek";return{query,durationMs,status:"success",engine:contributingEngine,totalHits:hits.length,hits,relatedSearches,deepseekSynthesis}}function escapeMarkdownText(text2){return text2.replace(/\\/g,"\\\\").replace(/\[/g,"\\[").replace(/\]/g,"\\]").replace(/</g,"\\<").replace(/>/g,"\\>")}function canonicalSources(value){if(!Array.isArray(value))return[];let sources=[],scanLimit=Math.min(value.length,32);for(let index3=0;index3<scanLimit&&sources.length<2;index3++){let source=value[index3];(source==="MiniMax"||source==="DeepSeek")&&!sources.includes(source)&&sources.push(source)}return sources}function prepareHit(value){if(!value||typeof value!="object")return;let hit=value,url=normalizeUrl(hit.url);if(url)return{title:boundSingleLineText(hit.title,200)??url,url,snippet:boundSingleLineText(hit.snippet,200),sources:canonicalSources(hit.sources)}}function usableHits(details){let hits=Array.isArray(details.hits)?details.hits:[],prepared=[],scanLimit=Math.min(hits.length,240);for(let index3=0;index3<scanLimit&&prepared.length<12;index3++){let hit=prepareHit(hits[index3]);hit&&prepared.push(hit)}return prepared}function prepareResults(details){let relatedSearches=[],historicalRelated=Array.isArray(details.relatedSearches)?details.relatedSearches:[],relatedScanLimit=Math.min(historicalRelated.length,64);for(let index3=0;index3<relatedScanLimit&&relatedSearches.length<8;index3++){let related=boundSingleLineText(historicalRelated[index3],200);related&&relatedSearches.push(related)}return{engine:details.engine,hits:usableHits(details),synthesis:boundMultilineText(details.deepseekSynthesis,6e3),relatedSearches}}function formatResultsMarkdown({engine,hits,synthesis,relatedSearches}){let parts=[];return hits.length>0&&(parts.push(`## Web Sources (${hits.length} found via ${getEngineLabel(engine)})
|
|
1971
1977
|
`),hits.forEach((hit,index3)=>{let sourceTag=hit.sources.length>1?` \u2014 *(found by ${hit.sources.join(" & ")})*`:"";parts.push(`${index3+1}. **[${escapeMarkdownText(hit.title)}](<${hit.url}>)**${sourceTag}`),hit.snippet&&parts.push(` - ${escapeMarkdownText(hit.snippet)}`)}),parts.push("")),synthesis&&(parts.push(`## DeepSeek Search Synthesis
|