catui-agent 1.0.0-beta.0 → 1.0.0

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/README.md CHANGED
@@ -1,29 +1,42 @@
1
1
  <div align="center">
2
2
 
3
3
  <pre>
4
- .-~~~~~~~~~-._ _.-~~~~~~~~~-.
5
- __.' ~. .~ `.__
6
- .'// \./ \\`.
7
- .'// | \\`.
8
- .'// .-~""""""""""""""-._ | _,-""""""""""""""~-. \\`.
9
- .'//.-" `-. | .-' "-.\\`.
10
- .'//______.============-.. \ | / ..-============.______\\`.
11
- .'______________________________\|/______________________________`.
12
- </pre>
4
+ * ,MMM8&&&. .
5
+ MMMM88&&&&& .
6
+ MMMM88&&&&&&&
7
+ * MMM88&&&&&&&&
8
+ MMM88&&&&&&&&
9
+ 'MMM88&&&&&&'
10
+ 'MMM8&&&' . _
11
+ |\___/| \\
12
+ ) ( |\_/| || '
13
+ =\ /= )a a '._.-""""-. //
14
+ )===( =\T_= / ~ ~ \//
15
+ / \ `"`\ ~ / ~ /
16
+ | | |~ \ | ~/
17
+ / \ \ ~/- \ ~\
18
+ \ / || | // /`
19
+ _/\_/\_ _/_/\_/\_/\_((_|\((_//\_/\_/_
20
+ | | | |( ( | | | | | | | | | |
21
+ | | | | ) ) | | | | | | | | | |
22
+ | | | |(_( | | | | | | | | | |
23
+ | | | | | | | | | | | | | | |
24
+ | | | | | | | | | | | | | | |
25
+ </pre>
13
26
 
14
27
  <h1>✎ Catui</h1>
15
28
 
16
29
  <p><strong>The AI Coding Agent That Remembers & Evolves</strong></p>
17
30
 
18
31
  <p>
19
- <a href="https://www.npmjs.com/package/catui-agent">
20
- <img src="https://img.shields.io/npm/v/catui-agent.svg?style=flat-square&color=cb3837" alt="npm version">
32
+ <a href="https://www.npmjs.com/package/catui-agent">
33
+ <img src="https://img.shields.io/npm/v/catui-agent.svg?style=flat-square&color=cb3837" alt="npm version">
21
34
  </a>
22
35
  <a href="https://nodejs.org">
23
- <img src="https://img.shields.io/node/v/catui-agent.svg?style=flat-square&color=339933" alt="Node.js">
36
+ <img src="https://img.shields.io/node/v/catui-agent.svg?style=flat-square&color=339933" alt="Node.js">
24
37
  </a>
25
- <a href="https://www.npmjs.com/package/catui-agent">
26
- <img src="https://img.shields.io/npm/dm/catui-agent.svg?style=flat-square&color=cb3837" alt="Downloads">
38
+ <a href="https://www.npmjs.com/package/catui-agent">
39
+ <img src="https://img.shields.io/npm/dm/catui-agent.svg?style=flat-square&color=cb3837" alt="Downloads">
27
40
  </a>
28
41
  <img src="https://img.shields.io/badge/TypeScript-5.0+-blue?style=flat-square&color=3178C6" alt="TypeScript">
29
42
  <img src="https://img.shields.io/badge/License-GPL--3.0-green?style=flat-square&color=brightgreen" alt="License">
@@ -117,7 +130,7 @@ Use the best model for each task.
117
130
  ### Installation
118
131
 
119
132
  ```bash
120
- npm install -g catui-agent
133
+ npm install -g catui-agent
121
134
  ```
122
135
 
123
136
  ### First Run
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.0.0-beta.0",
3
- "commitHash": "7e64df8",
2
+ "version": "1.0.0",
3
+ "commitHash": "ef67476",
4
4
  "branch": "main",
5
- "builtAt": "2026-06-13T07:59:56.421Z"
5
+ "builtAt": "2026-06-13T08:28:03.762Z"
6
6
  }
@@ -41,7 +41,7 @@ rm -rf ~/.catui/agent/teams
41
41
  npx tsc --noEmit
42
42
  ```
43
43
 
44
- The team extension must report **zero** errors. Pre-existing `presence/index.ts` errors related to `catui-mem` are unrelated and may remain until that extension is rebundled.
44
+ The team extension must report **zero** errors. Pre-existing `presence/index.ts` errors related to `catui-mem` are unrelated and may remain until that extension is rebundled.
45
45
 
46
46
  ---
47
47
 
@@ -1,37 +1,37 @@
1
- var Le=Object.defineProperty;var s=(k,e)=>Le(k,"name",{value:e,configurable:!0});import*as P from"node:fs";import*as J from"node:os";import*as D from"node:path";import{CombinedAutocompleteProvider as Be,CachedContainer as Ue,Container as v,Markdown as me,matchesKey as Oe,ProcessTerminal as qe,Spacer as u,Text as g,TruncatedText as ae,TUI as We,visibleWidth as pe}from"@catui/tui";import{spawn as Fe,spawnSync as re}from"child_process";import{APP_NAME as O,getDebugLogPath as He,getShareViewerUrl as Ne,VERSION as Ke}from"../../config.js";import{parseSkillBlock as _e}from"../../core/runtime/agent-session.js";import{FooterDataProvider as je}from"./footer-data-provider.js";import{KeybindingsManager as Qe}from"../../core/platform/keybindings.js";import{createCompactionSummaryMessage as Ge}from"../../core/messages.js";import{listMCPServers as fe,setMCPServerEnabled as Ve}from"../../core/mcp/mcp-config.js";import{getExtensionBackedBuiltinCommandNames as ze,formatSlashCommandDescription as Y,getLocalizedCommands as Xe,inferSlashCommandCategory as he}from"../../core/slash-commands.js";import{t as H}from"../../core/platform/i18n/index.js";import{getActivePersonaId as de,getPersonaDescription as Je,getPersonaDir as le,getPersonaMcpConfigPath as Ce,getPersonaMemoryDir as we,getPersonaSoulDir as ye,listPersonas as Se,setActivePersonaId as be,toAbsolutePath as I}from"../../core/persona/persona-manager.js";import{CATUI_WHATS_NEW as Ye}from"../../catui-defaults.js";import{getChangelogPath as Ze,parseChangelog as et}from"../../utils/changelog.js";import{copyToClipboard as tt}from"../utils/clipboard.js";import{ensureTool as Me,getToolPath as Te,prewarmTool as Ee}from"../../core/platform/utils/tools-manager.js";import{printTimings as st,time as N}from"../../core/platform/timings.js";import{ArminComponent as it}from"./components/armin.js";import{ImagePipelineController as nt}from"./controllers/image-pipeline-controller.js";import{SelfUpdateController as ot}from"./controllers/self-update-controller.js";import{InteractiveState as at}from"./state/interactive-state.js";import{PersistentSurfaceRegistry as rt}from"./controllers/extension-ui/persistent-surface-registry.js";import{PromptHost as ht}from"./controllers/extension-ui/prompt-host.js";import{CustomOverlayHost as dt}from"./controllers/extension-ui/custom-overlay-host.js";import{EditorComponentAdapter as lt}from"./controllers/extension-ui/editor-component-adapter.js";import{ModelOverlayController as ct}from"./controllers/model-overlay-controller.js";import{AuthProviderConfigController as ut}from"./controllers/auth-provider-config-controller.js";import{TreeOverlayController as gt}from"./controllers/tree-overlay-controller.js";import{SettingsOverlayController as mt}from"./controllers/settings-overlay-controller.js";import{SlashDispatcherController as pt}from"./controllers/slash-dispatcher-controller.js";import{InputSubmitController as ft}from"./controllers/input-submit-controller.js";import{InterruptController as Ct}from"./controllers/interrupt-controller.js";import{StreamRenderController as wt}from"./controllers/stream-render-controller.js";import{AssistantMessageComponent as xe}from"./components/assistant-message.js";import{BashExecutionComponent as ce}from"./components/bash-execution.js";import{BorderedLoader as Pe}from"./components/bordered-loader.js";import{BuddyPetComponent as yt}from"./components/buddy/pet-sprites.js";import{EditorBuddyLayout as St}from"./components/editor-buddy-layout.js";import{BranchSummaryMessageComponent as bt}from"./components/branch-summary-message.js";import{CatuiLoader as Mt}from"./components/catui-loader.js";import{NotificationQueue as Tt}from"./components/notification-queue.js";import{PersonaSelectorComponent as Et}from"./components/persona-selector.js";import{CompactionSummaryMessageComponent as xt}from"./components/compaction-summary-message.js";import{CustomEditor as Pt}from"./components/custom-editor.js";import{CustomMessageComponent as kt}from"./components/custom-message.js";import{DaxnutsComponent as $t}from"./components/daxnuts.js";import{DynamicBorder as Z}from"./components/dynamic-border.js";import{FooterComponent as At,renderContextProgressBar as Rt}from"./components/footer.js";import{appKey as L,appKeyHint as vt,editorKey as It,keyHint as Dt,rawKeyHint as q}from"./components/keybinding-hints.js";import{formatSoulStats as Lt}from"./components/soul-stats.js";import{SkillInvocationMessageComponent as Bt}from"./components/skill-invocation-message.js";import{ToolExecutionComponent as ke}from"./components/tool-execution.js";import{UserMessageComponent as $e}from"./components/user-message.js";import{RawText as Ut}from"./components/raw-text.js";import{getAvailableThemesWithPaths as Ot,getEditorTheme as qt,getMarkdownTheme as Wt,getThemeByName as Ft,initTheme as Ht,onThemeChange as Nt,setRegisteredThemes as ue,setTheme as Ae,setThemeInstance as Kt,theme as r}from"./theme/theme.js";import{getAgentLoopArgumentCompletions as _t,getLanguageArgumentCompletions as jt,getLoginArgumentCompletions as Qt,getMcpArgumentCompletions as Gt,getModelArgumentCompletions as Vt,getPersonaArgumentCompletions as zt,getThinkingArgumentCompletions as Xt}from"./slash-command-arguments.js";import{formatAgentLoopStatusLines as Jt}from"./agent-loop-status.js";function Yt(k){return typeof k=="object"&&k!==null&&"setExpanded"in k&&typeof k.setExpanded=="function"}s(Yt,"isExpandable");const Zt=process.env.CATUI_DEBUG==="1",Re=D.join(J.homedir(),".catui","agent","catui-debug.log");function ee(k){if(Zt)try{P.mkdirSync(D.dirname(Re),{recursive:!0}),P.appendFileSync(Re,`[${new Date().toISOString()}] [imode] ${k}
2
- `)}catch{}}s(ee,"_dbg");class ni{static{s(this,"InteractiveMode")}options;session;ui;chatContainer;pendingMessagesContainer;statusContainer;defaultEditor;editor;autocompleteProvider;fdPath;startupToolsPrewarmed=!1;editorContainer;footer;buddyPet=null;buddyPetSpecies=null;buddyPetResetTimer;footerDataProvider;keybindings;version;isInitialized=!1;onInputCallback;catWorkingMessages=["Purring\u2026","Meowing\u2026","Napping\u2026","Stretching\u2026","Zooming\u2026","Sneaking\u2026","Pouncing\u2026","Scratching\u2026","Yawning\u2026","Blinking\u2026","Kneading\u2026","Crouching\u2026","Spinning\u2026","Twitching\u2026","Hiding\u2026"];catMessageIndex=Math.floor(Math.random()*15);catMessageLastSwitch=0;state=new at;skillCommands=new Map;unsubscribe;isBashMode=!1;bashComponent=void 0;pendingBashComponents=[];shutdownRequested=!1;statusTimers=new Set;notificationQueue;extensionTerminalInputUnsubscribers=new Set;widgetContainerAbove;widgetContainerBelow;buddySlot;editorBuddyLayout;headerContainer;builtInHeader=void 0;attachmentsContainer=void 0;imagePipeline;selfUpdate;authProviderConfig;modelOverlay;treeOverlay;settingsOverlay;slashDispatcher;inputSubmit;interrupt;streamRender;surfaces;promptHost;customOverlay;editorAdapter;get agent(){return this.session.agent}get sessionManager(){return this.session.sessionManager}get settingsManager(){return this.session.settingsManager}constructor(e,n={}){this.options=n,this.session=e,this.version=Ke,this.ui=new We(new qe,this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.headerContainer=new v,this.chatContainer=new Ue,this.pendingMessagesContainer=new v,this.statusContainer=new v,this.widgetContainerAbove=new v,this.widgetContainerBelow=new v,this.notificationQueue=new Tt(this.ui,r),this.keybindings=Qe.create();const i=this.settingsManager.getEditorPaddingX(),o=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor=new Pt(this.ui,qt(),this.keybindings,{paddingX:i,autocompleteMaxVisible:o}),this.editor=this.defaultEditor,this.editorContainer=new v,this.attachmentsContainer=new v,this.buddySlot=new v,this.editorBuddyLayout=new St(()=>this.editor,this.buddySlot),this.editorContainer.addChild(this.attachmentsContainer),this.editorContainer.addChild(this.editorBuddyLayout),this.imagePipeline=new nt({getCwd:s(()=>this.session.cwd,"getCwd"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),showStatus:s(t=>this.showStatus(t),"showStatus"),getThemeName:s(()=>this.settingsManager.getTheme(),"getThemeName"),isEditorCursorAtTop:s(()=>this.editor.isCursorOnFirstVisualLine?.()??!this.editor.getText().includes(`
3
- `),"isEditorCursorAtTop"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getAttachmentsContainer:s(()=>this.attachmentsContainer,"getAttachmentsContainer"),getEditorBuddyLayout:s(()=>this.editorBuddyLayout,"getEditorBuddyLayout")}),this.selfUpdate=new ot({getChatContainer:s(()=>this.chatContainer,"getChatContainer"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),getAutoUpdate:s(()=>this.settingsManager.getAutoUpdate(),"getAutoUpdate"),getSkippedVersion:s(()=>this.settingsManager.getSkippedVersion(),"getSkippedVersion"),setSkippedVersion:s(t=>this.settingsManager.setSkippedVersion(t),"setSkippedVersion"),setAutoUpdate:s(t=>this.settingsManager.setAutoUpdate(t),"setAutoUpdate"),showSelector:s((t,a)=>this.promptHost.selector(t,a),"showSelector")}),this.surfaces=new rt({requestRender:s(()=>this.ui.requestRender(),"requestRender"),getUi:s(()=>this.ui,"getUi"),getWidgetContainerAbove:s(()=>this.widgetContainerAbove,"getWidgetContainerAbove"),getWidgetContainerBelow:s(()=>this.widgetContainerBelow,"getWidgetContainerBelow"),getHeaderContainer:s(()=>this.headerContainer,"getHeaderContainer"),getBuiltInHeader:s(()=>this.builtInHeader,"getBuiltInHeader"),getFooter:s(()=>this.footer,"getFooter"),getFooterDataProvider:s(()=>this.footerDataProvider,"getFooterDataProvider")}),this.promptHost=new ht({getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getUi:s(()=>this.ui,"getUi"),getEditor:s(()=>this.editor,"getEditor"),getEditorBuddyLayout:s(()=>this.editorBuddyLayout,"getEditorBuddyLayout"),getKeybindings:s(()=>this.keybindings,"getKeybindings"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")}),this.customOverlay=new dt({getEditor:s(()=>this.editor,"getEditor"),getUi:s(()=>this.ui,"getUi"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getKeybindings:s(()=>this.keybindings,"getKeybindings"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")}),this.editorAdapter=new lt({getEditor:s(()=>this.editor,"getEditor"),setEditor:s(t=>{this.editor=t},"setEditor"),getDefaultEditor:s(()=>this.defaultEditor,"getDefaultEditor"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getUi:s(()=>this.ui,"getUi"),getKeybindings:s(()=>this.keybindings,"getKeybindings"),getAutocompleteProvider:s(()=>this.autocompleteProvider,"getAutocompleteProvider"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")}),this.footerDataProvider=new je(e.cwd),this.footer=new At(e,this.footerDataProvider,this.settingsManager.getShowTokenStats()),this.footer.setAutoCompactEnabled(e.autoCompactionEnabled),this.authProviderConfig=new ut({modelRegistry:this.session.modelRegistry,surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),promptInput:s((t,a,h)=>this.promptHost.input(t,a,h),"promptInput"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),getUi:s(()=>this.ui,"getUi"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getEditor:s(()=>this.editor,"getEditor"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")},modelBridge:{getCurrentModel:s(()=>this.session.model,"getCurrentModel"),setCurrentModel:s(async t=>{await this.session.setModel(t),this.footer.invalidate(),this.updateEditorBorderColor()},"setCurrentModel"),showModelSelector:s((t,a)=>this.modelOverlay.showModelSelector(t,a),"showModelSelector"),applySelectedModel:s(t=>this.modelOverlay.applySelectedModel(t),"applySelectedModel"),updateAvailableProviderCount:s(()=>this.modelOverlay.updateAvailableProviderCount(),"updateAvailableProviderCount")}}),this.modelOverlay=new ct({modelSession:{getModel:s(()=>this.session.model,"getModel"),setModel:s(t=>this.session.setModel(t),"setModel"),cycleModel:s(t=>this.session.cycleModel(t),"cycleModel"),getThinkingLevel:s(()=>this.session.thinkingLevel,"getThinkingLevel"),setThinkingLevel:s(t=>this.session.setThinkingLevel(t),"setThinkingLevel"),cycleThinkingLevel:s(()=>this.session.cycleThinkingLevel(),"cycleThinkingLevel"),getAvailableThinkingLevels:s(()=>this.session.getAvailableThinkingLevels(),"getAvailableThinkingLevels"),getScopedModels:s(()=>this.session.scopedModels,"getScopedModels"),setScopedModels:s(t=>this.session.setScopedModels(t),"setScopedModels")},modelCatalog:{refresh:s(()=>this.session.modelRegistry.refresh(),"refresh"),getAvailable:s(()=>this.session.modelRegistry.getAvailable(),"getAvailable"),getAll:s(()=>this.session.modelRegistry.getAll(),"getAll"),find:s((t,a)=>this.session.modelRegistry.find(t,a),"find"),appendOpenRouterModel:s((t,a)=>this.session.modelRegistry.appendOpenRouterModel(t,a),"appendOpenRouterModel"),getCredentialType:s(t=>this.session.modelRegistry.authStorage.get(t)?.type,"getCredentialType"),getRegistry:s(()=>this.session.modelRegistry,"getRegistry")},modelSettings:{getEnabledModels:s(()=>this.settingsManager.getEnabledModels(),"getEnabledModels"),setEnabledModels:s(t=>this.settingsManager.setEnabledModels(t),"setEnabledModels"),setDefaultModelAndProvider:s((t,a)=>this.settingsManager.setDefaultModelAndProvider(t,a),"setDefaultModelAndProvider")},providerConfig:{ensureProviderConfiguredForSelection:s(t=>this.authProviderConfig.ensureProviderConfiguredForSelection(t),"ensureProviderConfiguredForSelection"),handleProviderSelectionFromSelector:s((t,a)=>this.authProviderConfig.handleProviderSelectionFromSelector(t,a),"handleProviderSelectionFromSelector"),promptForProviderApiKey:s((t,a)=>this.authProviderConfig.promptForProviderApiKey(t,a),"promptForProviderApiKey")},surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),promptInput:s((t,a,h)=>this.promptHost.input(t,a,h),"promptInput"),getUi:s(()=>this.ui,"getUi")},footer:{invalidate:s(()=>this.footer.invalidate(),"invalidate"),setAvailableProviderCount:s(t=>this.footerDataProvider.setAvailableProviderCount(t),"setAvailableProviderCount"),updateEditorBorderColor:s(()=>this.updateEditorBorderColor(),"updateEditorBorderColor")},playDaxnuts:s(()=>this.handleDaxnuts(),"playDaxnuts")}),this.treeOverlay=new gt({session:this.session,getSessionManager:s(()=>this.sessionManager,"getSessionManager"),surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),getUi:s(()=>this.ui,"getUi"),getChatContainer:s(()=>this.chatContainer,"getChatContainer"),getStatusContainer:s(()=>this.statusContainer,"getStatusContainer"),clearChat:s(()=>{this.clearStatusTimers(),this.chatContainer.clear()},"clearChat"),clearTransientSessionUi:s(()=>{this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear(),this.pendingMessagesContainer.clear(),this.state.compactionQueuedMessages=[],this.state.streamingComponent=void 0,this.state.streamingMessage=void 0,this.state.pendingTools.clear(),this.imagePipeline.clearAttachments()},"clearTransientSessionUi"),addSessionNavigationBanner:s(t=>this.addSessionNavigationBanner(t),"addSessionNavigationBanner"),renderInitialMessages:s(()=>this.renderInitialMessages(),"renderInitialMessages"),getEditorText:s(()=>this.editor.getText(),"getEditorText"),setEditorText:s(t=>this.editor.setText(t),"setEditorText"),getEscapeHandler:s(()=>this.defaultEditor.onEscape,"getEscapeHandler"),setEscapeHandler:s(t=>{this.defaultEditor.onEscape=t},"setEscapeHandler")},promptHost:{selector:s((t,a)=>this.promptHost.selector(t,a),"selector"),editor:s((t,a)=>this.promptHost.editor(t,a),"editor")},keybindings:this.keybindings,shutdown:s(()=>this.shutdown(),"shutdown")}),this.settingsOverlay=new mt({session:this.session,settingsManager:this.settingsManager,surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),invalidateUi:s(()=>this.ui.invalidate(),"invalidateUi"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),setShowHardwareCursor:s(t=>this.ui.setShowHardwareCursor(t),"setShowHardwareCursor"),setClearOnShrink:s(t=>this.ui.setClearOnShrink(t),"setClearOnShrink")},footer:{setAutoCompactEnabled:s(t=>this.footer.setAutoCompactEnabled(t),"setAutoCompactEnabled"),setShowTokenStats:s(t=>this.footer.setShowTokenStats(t),"setShowTokenStats"),invalidate:s(()=>this.footer.invalidate(),"invalidate")},editor:{setPaddingX:s(t=>{this.defaultEditor.setPaddingX(t),this.editor!==this.defaultEditor&&this.editor.setPaddingX!==void 0&&this.editor.setPaddingX(t)},"setPaddingX"),setAutocompleteMaxVisible:s(t=>{this.defaultEditor.setAutocompleteMaxVisible(t),this.editor!==this.defaultEditor&&this.editor.setAutocompleteMaxVisible!==void 0&&this.editor.setAutocompleteMaxVisible(t)},"setAutocompleteMaxVisible"),updateBorderColor:s(()=>this.updateEditorBorderColor(),"updateBorderColor")},render:{setToolImagesEnabled:s(t=>{for(const a of this.chatContainer.children)a instanceof ke&&a.setShowImages(t)},"setToolImagesEnabled"),setAssistantThinkingHidden:s(t=>{for(const a of this.chatContainer.children)a instanceof xe&&a.setHideThinkingBlock(t);this.clearStatusTimers(),this.chatContainer.clear()},"setAssistantThinkingHidden"),rebuildChatFromMessages:s(()=>this.rebuildChatFromMessages(),"rebuildChatFromMessages")},getHideThinkingBlock:s(()=>this.state.hideThinkingBlock,"getHideThinkingBlock"),setHideThinkingBlock:s(t=>{this.state.hideThinkingBlock=t},"setHideThinkingBlock"),rebuildAutocomplete:s(()=>this.setupAutocomplete(this.fdPath),"rebuildAutocomplete"),syncBuddyPet:s(()=>this.syncBuddyPet(),"syncBuddyPet")}),this.slashDispatcher=new pt({clearEditor:s(()=>this.editor.setText(""),"clearEditor"),settings:{showSettingsSelector:s(()=>this.settingsOverlay.showSettingsSelector(),"showSettingsSelector")},model:{showScopedModelsSelector:s(()=>this.modelOverlay.showModelsSelector(),"showScopedModelsSelector"),handleModelCommand:s(t=>this.modelOverlay.handleModelCommand(t),"handleModelCommand"),handleThinkingCommand:s(t=>this.modelOverlay.handleThinkingCommand(t),"handleThinkingCommand")},auth:{handleApiKeyCommand:s(()=>this.authProviderConfig.handleApiKeyCommand(),"handleApiKeyCommand"),handleLoginCommand:s(t=>this.authProviderConfig.handleLoginCommand(t),"handleLoginCommand"),showLogoutSelector:s(()=>this.authProviderConfig.showOAuthSelector("logout"),"showLogoutSelector")},tree:{showForkSelector:s(()=>this.treeOverlay.showForkSelector(),"showForkSelector"),showTreeSelector:s(()=>this.treeOverlay.showTreeSelector(),"showTreeSelector"),showSessionSelector:s(()=>this.treeOverlay.showSessionSelector(),"showSessionSelector")},selfUpdate:{handleUpdateCommand:s(()=>this.selfUpdate.handleUpdateCommand(),"handleUpdateCommand"),handleReinstallCommand:s(()=>this.selfUpdate.handleReinstallCommand(),"handleReinstallCommand")},commands:{isExtensionCommand:s(t=>this.isExtensionCommand(t),"isExtensionCommand"),handleAgentLoopCommand:s(t=>this.handleAgentLoopCommand(t),"handleAgentLoopCommand"),handleMcpCommand:s(t=>this.handleMcpCommand(t),"handleMcpCommand"),handleExportCommand:s(t=>this.handleExportCommand(t),"handleExportCommand"),handleShareCommand:s(()=>this.handleShareCommand(),"handleShareCommand"),handleCopyCommand:s(()=>this.handleCopyCommand(),"handleCopyCommand"),handleStatusCommand:s(()=>this.handleStatusCommand(),"handleStatusCommand"),handleUsageCommand:s(()=>this.handleUsageCommand(),"handleUsageCommand"),handleNameCommand:s(t=>this.handleNameCommand(t),"handleNameCommand"),handleSessionCommand:s(()=>this.handleSessionCommand(),"handleSessionCommand"),handleChangelogCommand:s(()=>this.handleChangelogCommand(),"handleChangelogCommand"),handleHotkeysCommand:s(()=>this.handleHotkeysCommand(),"handleHotkeysCommand"),handleShowResourcesCommand:s(()=>this.handleShowResourcesCommand(),"handleShowResourcesCommand"),handleClearCommand:s(()=>this.handleClearCommand(),"handleClearCommand"),handleCompactCommand:s(t=>this.handleCompactCommand(t),"handleCompactCommand"),handleReloadCommand:s(()=>this.handleReloadCommand(),"handleReloadCommand"),handleLanguageCommand:s(t=>this.handleLanguageCommand(t),"handleLanguageCommand"),handleSoulCommand:s(()=>this.handleSoulCommand(),"handleSoulCommand"),handlePersonaCommand:s(t=>this.handlePersonaCommand(t),"handlePersonaCommand"),handleMemoryCommand:s(()=>this.handleMemoryCommand(),"handleMemoryCommand"),handleArminSaysHi:s(()=>this.handleArminSaysHi(),"handleArminSaysHi"),handleBrowserOptInCommand:s(()=>this.handleBrowserOptInCommand(),"handleBrowserOptInCommand"),shutdown:s(()=>this.shutdown(),"shutdown")}}),this.inputSubmit=new ft({editor:{setText:s(t=>this.editor.setText(t),"setText"),addToHistory:s(t=>this.editor.addToHistory?.(t),"addToHistory"),handleExternalInput:s(t=>this.onInputCallback?(this.onInputCallback(t),this.editor.addToHistory?.(t),!0):!1,"handleExternalInput"),setBashMode:s(t=>{this.isBashMode=t},"setBashMode"),updateBorderColor:s(()=>this.updateEditorBorderColor(),"updateBorderColor")},slash:{execute:s(t=>this.slashDispatcher.execute(t),"execute")},image:{awaitPendingPaste:s(()=>this.imagePipeline.awaitPendingPaste(),"awaitPendingPaste"),extractImagesFromText:s(t=>this.imagePipeline.extractImagesFromText(t),"extractImagesFromText"),takePendingAttachments:s(()=>this.imagePipeline.takePendingAttachments(),"takePendingAttachments"),processAttachmentFiles:s(t=>this.imagePipeline.processAttachmentFiles(t),"processAttachmentFiles"),cleanupClipboardImages:s(()=>this.imagePipeline.cleanupClipboardImages(),"cleanupClipboardImages")},session:{isBashRunning:s(()=>this.session.isBashRunning,"isBashRunning"),isCompacting:s(()=>this.session.isCompacting,"isCompacting"),isStreaming:s(()=>this.session.isStreaming,"isStreaming"),getModel:s(()=>this.session.model,"getModel"),getCwd:s(()=>this.session.cwd,"getCwd"),promptAfterRender:s((t,a)=>this.promptAfterRender(t,a),"promptAfterRender"),queueCompactionMessage:s((t,a)=>this.queueCompactionMessage(t,a),"queueCompactionMessage")},commands:{isExtensionCommand:s(t=>this.isExtensionCommand(t),"isExtensionCommand"),handlePersonaCommand:s(t=>this.handlePersonaCommand(t),"handlePersonaCommand"),handleBashCommand:s((t,a)=>this.handleBashCommand(t,a),"handleBashCommand")},render:{showStatus:s(t=>this.showStatus(t),"showStatus"),showWarning:s(t=>this.showWarning(t),"showWarning"),showError:s(t=>this.showError(t),"showError"),notify:s((t,a)=>this.notify(t,a),"notify"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),flushPendingBashComponents:s(()=>this.flushPendingBashComponents(),"flushPendingBashComponents"),updatePendingMessagesDisplay:s(()=>this.updatePendingMessagesDisplay(),"updatePendingMessagesDisplay"),addOptimisticUserMessage:s((t,a)=>{this.state.optimisticUserMessages.push({text:t}),this.addMessageToChat({role:"user",content:a,timestamp:Date.now()})},"addOptimisticUserMessage"),rollbackFirstOptimisticUserMessageIfMatches:s(t=>{this.state.optimisticUserMessages.length>0&&this.state.optimisticUserMessages[0]?.text===t&&this.state.optimisticUserMessages.shift()},"rollbackFirstOptimisticUserMessageIfMatches")}}),this.interrupt=new Ct({queue:{isLoadingAnimationActive:s(()=>!!this.state.loadingAnimation,"isLoadingAnimationActive"),restoreQueuedMessagesWithAbort:s(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"restoreQueuedMessagesWithAbort")},runtime:{isStreaming:s(()=>this.session.isStreaming,"isStreaming"),isBashRunning:s(()=>this.session.isBashRunning,"isBashRunning"),abortAgent:s(()=>this.agent.abort(),"abortAgent"),abortBash:s(()=>this.session.abortBash(),"abortBash")},bash:{isBashMode:s(()=>this.isBashMode,"isBashMode"),exitBashMode:s(()=>{this.editor.setText(""),this.isBashMode=!1,this.updateEditorBorderColor()},"exitBashMode")},editor:{getText:s(()=>this.editor.getText(),"getText"),clearEditor:s(()=>this.clearEditor(),"clearEditor")},tree:{getDoubleEscapeAction:s(()=>this.settingsManager.getDoubleEscapeAction(),"getDoubleEscapeAction"),showTreeSelector:s(()=>this.treeOverlay.showTreeSelector(),"showTreeSelector"),showForkSelector:s(()=>this.treeOverlay.showForkSelector(),"showForkSelector")},lifecycle:{requestShutdown:s(()=>{this.shutdown()},"requestShutdown"),suspend:s(()=>this.suspend(),"suspend")}}),this.streamRender=new wt({state:{get:s(()=>this.state,"get")},layout:{getUi:s(()=>this.ui,"getUi"),getChatContainer:s(()=>this.chatContainer,"getChatContainer"),getStatusContainer:s(()=>this.statusContainer,"getStatusContainer"),addMessageToChat:s(t=>this.addMessageToChat(t),"addMessageToChat"),updatePendingMessagesDisplay:s(()=>this.updatePendingMessagesDisplay(),"updatePendingMessagesDisplay"),rebuildChatFromMessages:s(()=>this.rebuildChatFromMessages(),"rebuildChatFromMessages"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),invalidateFooter:s(()=>this.footer.invalidate(),"invalidateFooter")},loaders:{getSessionId:s(()=>this.sessionManager.getSessionId(),"getSessionId"),getDefaultWorkingMessage:s(()=>this.getNextCatMessage(),"getDefaultWorkingMessage"),getInterruptKeyHint:s(()=>L(this.keybindings,"interrupt"),"getInterruptKeyHint"),setBuddyPetState:s((t,a,h)=>this.setBuddyPetState(t,a,h),"setBuddyPetState"),startAgentRunTimer:s(()=>this.startAgentRunTimer(),"startAgentRunTimer"),stopAgentRunTimer:s(()=>this.stopAgentRunTimer(),"stopAgentRunTimer"),updateWorkingMessage:s(t=>this.updateWorkingMessage(t),"updateWorkingMessage"),formatElapsedSeconds:s(t=>this.formatElapsedSeconds(t),"formatElapsedSeconds"),isInPlanMode:s(()=>this.footerDataProvider.getExtensionStatuses().has("plan"),"isInPlanMode")},toolTrace:{shouldRenderToolTrace:s(t=>this.shouldRenderToolTrace(t),"shouldRenderToolTrace"),getRegisteredToolDefinition:s(t=>this.getRegisteredToolDefinition(t),"getRegisteredToolDefinition"),getShowImages:s(()=>this.settingsManager.getShowImages(),"getShowImages")},runtime:{getRetryAttempt:s(()=>this.session.retryAttempt,"getRetryAttempt"),abortCompaction:s(()=>this.session.abortCompaction(),"abortCompaction"),abortRetry:s(()=>this.session.abortRetry(),"abortRetry"),flushCompactionQueue:s(t=>{this.flushCompactionQueue(t)},"flushCompactionQueue"),checkShutdownRequested:s(()=>this.checkShutdownRequested(),"checkShutdownRequested"),clearAttachments:s(()=>this.imagePipeline.clearAttachments(),"clearAttachments"),getAgentDir:s(()=>this.session.agentDir,"getAgentDir")},escape:{getHandler:s(()=>this.defaultEditor.onEscape,"getHandler"),setHandler:s(t=>{this.defaultEditor.onEscape=t},"setHandler")},surface:{ensureInitialized:s(async()=>{this.isInitialized||await this.init()},"ensureInitialized"),restoreEditorFocusIfPossible:s(()=>this.promptHost.restoreEditorFocusIfPossible(),"restoreEditorFocusIfPossible"),getUserMessageText:s(t=>this.getUserMessageText(t),"getUserMessageText"),getMarkdownThemeWithSettings:s(()=>this.getMarkdownThemeWithSettings(),"getMarkdownThemeWithSettings"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError")}}),this.syncBuddyPet(),this.state.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),ue(this.session.resourceLoader.getThemes().themes),Ht(this.settingsManager.getTheme(),!0),this.session.setSlashCommandExecutor(t=>this.slashDispatcher.execute(t,{clearEditor:!1}))}setupAutocomplete(e){const i=Xe(H).map(l=>({name:l.name,description:Y(l.description,l.category,H)})),o=i.find(l=>l.name==="model");o&&(o.getArgumentCompletions=(l,T)=>{const $=this.session.scopedModels.length>0?this.session.scopedModels.map(A=>A.model):this.session.modelRegistry.getAvailable();return Vt(l,T,$)});const t=i.find(l=>l.name==="thinking");t&&(t.getArgumentCompletions=(l,T)=>Xt(l,T,this.session.getAvailableThinkingLevels()));const a=i.find(l=>l.name==="agent-loop");a&&(a.getArgumentCompletions=_t);const h=i.find(l=>l.name==="mcp");h&&(h.getArgumentCompletions=(l,T)=>Gt(l,T,fe()));const c=i.find(l=>l.name==="language");c&&(c.getArgumentCompletions=jt);const d=i.find(l=>l.name==="persona");d&&(d.getArgumentCompletions=(l,T)=>zt(l,T,Se(),de()));const m=i.find(l=>l.name==="login");m&&(m.getArgumentCompletions=(l,T)=>Qt(l,T,this.authProviderConfig.getLoginSelectorProviders("login")));const f=this.session.promptTemplates.map(l=>({name:l.name,description:Y(l.description,he(l.name,"prompt"),H)})),M=new Set(i.map(l=>l.name)),w=ze(),E=new Set([...M].filter(l=>!w.has(l))),S=this.session.extensionRunner?.getRegisteredCommands(E)??[],C=new Map(S.map(l=>[l.name,l]));for(const l of i){if(!w.has(l.name))continue;const T=C.get(l.name);T?.getArgumentCompletions&&(l.getArgumentCompletions=T.getArgumentCompletions)}const p=S.filter(l=>!M.has(l.name)).map(l=>({name:l.name,description:Y(l.description??"(extension command)",he(l.name,"extension"),H),getArgumentCompletions:l.getArgumentCompletions}));this.skillCommands.clear();const y=[];if(this.settingsManager.getEnableSkillCommands())for(const l of this.session.resourceLoader.getSkills().skills){const T=`skill:${l.name}`;this.skillCommands.set(T,l.filePath),y.push({name:T,description:Y(l.description,he(l.name,"skill"),H)})}this.autocompleteProvider=new Be([...i,...f,...p,...y],this.session.cwd,e),this.defaultEditor.setAutocompleteProvider(this.autocompleteProvider),this.editor!==this.defaultEditor&&this.editor.setAutocompleteProvider?.(this.autocompleteProvider);const b=new Set([...i,...f,...p,...y].map(l=>l.name));this.defaultEditor.enableSlashHighlight(()=>b,r)}prewarmStartupTools(){this.startupToolsPrewarmed||(this.startupToolsPrewarmed=!0,N("interactive.tools.prewarm.start"),Ee("fd"),Ee("rg"),Promise.all([Me("fd",!0),Me("rg",!0)]).then(([e])=>{const n=e??Te("fd")??void 0;!n||n===this.fdPath||(this.fdPath=n,this.setupAutocomplete(this.fdPath))}).finally(()=>{N("interactive.tools.prewarm.end")}))}async init(){if(!this.isInitialized){if(N("interactive.init.start"),this.imagePipeline.cleanupStaleClipboardFiles(),this.fdPath=Te("fd")??void 0,this.ui.addChild(this.headerContainer),this.options.verbose||!this.settingsManager.getQuietStartup()){const e=r.bold(r.fg("accent",O))+r.fg("dim",` v${this.version}`),n=O==="catui"||O==="catui"?`${r.fg("dim",Ye)}
4
- `:"",i=this.keybindings,o=s((a,h)=>vt(i,a,h),"hint"),t=[o("interrupt","to interrupt"),o("clear","to clear"),q(`${L(i,"clear")} twice`,"to exit"),o("exit","to exit (empty)"),o("suspend","to suspend"),Dt("deleteToLineEnd","to delete to end"),o("cycleThinkingLevel","to cycle thinking level"),q(`${L(i,"cycleModelForward")}/${L(i,"cycleModelBackward")}`,"to cycle models"),o("selectModel","to select model"),o("selectProviderThenModel","to select provider then model"),o("expandTools","to expand tools"),o("toggleThinking","to expand thinking"),o("externalEditor","for external editor"),q("/","for commands"),q("!","to run bash"),q("!!","to run bash (no context)"),o("followUp","to queue follow-up"),o("dequeue","to edit all queued messages"),o("pasteImage","to paste image"),q("drop files","to attach")].join(`
1
+ var Le=Object.defineProperty;var s=(k,e)=>Le(k,"name",{value:e,configurable:!0});import*as P from"node:fs";import*as Y from"node:os";import*as L from"node:path";import{CombinedAutocompleteProvider as Be,CachedContainer as Ue,Container as A,Markdown as me,matchesKey as Oe,ProcessTerminal as qe,Spacer as u,Text as g,TruncatedText as ae,TUI as We,visibleWidth as pe}from"@catui/tui";import{spawn as Fe,spawnSync as re}from"child_process";import{APP_NAME as W,getDebugLogPath as He,getShareViewerUrl as Ne,VERSION as Ke}from"../../config.js";import{parseSkillBlock as _e}from"../../core/runtime/agent-session.js";import{FooterDataProvider as je}from"./footer-data-provider.js";import{KeybindingsManager as Qe}from"../../core/platform/keybindings.js";import{createCompactionSummaryMessage as Ge}from"../../core/messages.js";import{listMCPServers as fe,setMCPServerEnabled as Ve}from"../../core/mcp/mcp-config.js";import{getExtensionBackedBuiltinCommandNames as ze,formatSlashCommandDescription as Z,getLocalizedCommands as Xe,inferSlashCommandCategory as he}from"../../core/slash-commands.js";import{t as K}from"../../core/platform/i18n/index.js";import{getActivePersonaId as de,getPersonaDescription as Je,getPersonaDir as le,getPersonaMcpConfigPath as Ce,getPersonaMemoryDir as we,getPersonaSoulDir as ye,listPersonas as Se,setActivePersonaId as Me,toAbsolutePath as R}from"../../core/persona/persona-manager.js";import{CATUI_WHATS_NEW as Ye}from"../../catui-defaults.js";import{getChangelogPath as Ze,parseChangelog as et}from"../../utils/changelog.js";import{copyToClipboard as tt}from"../utils/clipboard.js";import{ensureTool as be,getToolPath as Te,prewarmTool as Ee}from"../../core/platform/utils/tools-manager.js";import{printTimings as st,time as _}from"../../core/platform/timings.js";import{ArminComponent as it}from"./components/armin.js";import{ImagePipelineController as nt}from"./controllers/image-pipeline-controller.js";import{SelfUpdateController as ot}from"./controllers/self-update-controller.js";import{InteractiveState as at}from"./state/interactive-state.js";import{PersistentSurfaceRegistry as rt}from"./controllers/extension-ui/persistent-surface-registry.js";import{PromptHost as ht}from"./controllers/extension-ui/prompt-host.js";import{CustomOverlayHost as dt}from"./controllers/extension-ui/custom-overlay-host.js";import{EditorComponentAdapter as lt}from"./controllers/extension-ui/editor-component-adapter.js";import{ModelOverlayController as ct}from"./controllers/model-overlay-controller.js";import{AuthProviderConfigController as ut}from"./controllers/auth-provider-config-controller.js";import{TreeOverlayController as gt}from"./controllers/tree-overlay-controller.js";import{SettingsOverlayController as mt}from"./controllers/settings-overlay-controller.js";import{SlashDispatcherController as pt}from"./controllers/slash-dispatcher-controller.js";import{InputSubmitController as ft}from"./controllers/input-submit-controller.js";import{InterruptController as Ct}from"./controllers/interrupt-controller.js";import{StreamRenderController as wt}from"./controllers/stream-render-controller.js";import{AssistantMessageComponent as xe}from"./components/assistant-message.js";import{BashExecutionComponent as ce}from"./components/bash-execution.js";import{BorderedLoader as Pe}from"./components/bordered-loader.js";import{BuddyPetComponent as yt}from"./components/buddy/pet-sprites.js";import{EditorBuddyLayout as St}from"./components/editor-buddy-layout.js";import{BranchSummaryMessageComponent as Mt}from"./components/branch-summary-message.js";import{CatuiLoader as bt}from"./components/catui-loader.js";import{NotificationQueue as Tt}from"./components/notification-queue.js";import{PersonaSelectorComponent as Et}from"./components/persona-selector.js";import{CompactionSummaryMessageComponent as xt}from"./components/compaction-summary-message.js";import{CustomEditor as Pt}from"./components/custom-editor.js";import{CustomMessageComponent as kt}from"./components/custom-message.js";import{DaxnutsComponent as $t}from"./components/daxnuts.js";import{DynamicBorder as ee}from"./components/dynamic-border.js";import{FooterComponent as At,renderContextProgressBar as Rt}from"./components/footer.js";import{appKey as B,appKeyHint as vt,editorKey as It,keyHint as Dt,rawKeyHint as F}from"./components/keybinding-hints.js";import{formatSoulStats as Lt}from"./components/soul-stats.js";import{SkillInvocationMessageComponent as Bt}from"./components/skill-invocation-message.js";import{ToolExecutionComponent as ke}from"./components/tool-execution.js";import{UserMessageComponent as $e}from"./components/user-message.js";import{RawText as Ut}from"./components/raw-text.js";import{getAvailableThemesWithPaths as Ot,getEditorTheme as qt,getMarkdownTheme as Wt,getThemeByName as Ft,initTheme as Ht,onThemeChange as Nt,setRegisteredThemes as ue,setTheme as Ae,setThemeInstance as Kt,theme as r}from"./theme/theme.js";import{getAgentLoopArgumentCompletions as _t,getLanguageArgumentCompletions as jt,getLoginArgumentCompletions as Qt,getMcpArgumentCompletions as Gt,getModelArgumentCompletions as Vt,getPersonaArgumentCompletions as zt,getThinkingArgumentCompletions as Xt}from"./slash-command-arguments.js";import{formatAgentLoopStatusLines as Jt}from"./agent-loop-status.js";function Yt(k){return typeof k=="object"&&k!==null&&"setExpanded"in k&&typeof k.setExpanded=="function"}s(Yt,"isExpandable");const Zt=process.env.CATUI_DEBUG==="1",Re=L.join(Y.homedir(),".catui","agent","catui-debug.log");function te(k){if(Zt)try{P.mkdirSync(L.dirname(Re),{recursive:!0}),P.appendFileSync(Re,`[${new Date().toISOString()}] [imode] ${k}
2
+ `)}catch{}}s(te,"_dbg");class ni{static{s(this,"InteractiveMode")}options;session;ui;chatContainer;pendingMessagesContainer;statusContainer;defaultEditor;editor;autocompleteProvider;fdPath;startupToolsPrewarmed=!1;editorContainer;footer;buddyPet=null;buddyPetSpecies=null;buddyPetResetTimer;footerDataProvider;keybindings;version;isInitialized=!1;onInputCallback;catWorkingMessages=["Purring\u2026","Meowing\u2026","Napping\u2026","Stretching\u2026","Zooming\u2026","Sneaking\u2026","Pouncing\u2026","Scratching\u2026","Yawning\u2026","Blinking\u2026","Kneading\u2026","Crouching\u2026","Spinning\u2026","Twitching\u2026","Hiding\u2026"];catMessageIndex=Math.floor(Math.random()*15);catMessageLastSwitch=0;state=new at;skillCommands=new Map;unsubscribe;isBashMode=!1;bashComponent=void 0;pendingBashComponents=[];shutdownRequested=!1;statusTimers=new Set;notificationQueue;extensionTerminalInputUnsubscribers=new Set;widgetContainerAbove;widgetContainerBelow;buddySlot;editorBuddyLayout;headerContainer;builtInHeader=void 0;attachmentsContainer=void 0;imagePipeline;selfUpdate;authProviderConfig;modelOverlay;treeOverlay;settingsOverlay;slashDispatcher;inputSubmit;interrupt;streamRender;surfaces;promptHost;customOverlay;editorAdapter;get agent(){return this.session.agent}get sessionManager(){return this.session.sessionManager}get settingsManager(){return this.session.settingsManager}constructor(e,n={}){this.options=n,this.session=e,this.version=Ke,this.ui=new We(new qe,this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.headerContainer=new A,this.chatContainer=new Ue,this.pendingMessagesContainer=new A,this.statusContainer=new A,this.widgetContainerAbove=new A,this.widgetContainerBelow=new A,this.notificationQueue=new Tt(this.ui,r),this.keybindings=Qe.create();const i=this.settingsManager.getEditorPaddingX(),o=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor=new Pt(this.ui,qt(),this.keybindings,{paddingX:i,autocompleteMaxVisible:o}),this.editor=this.defaultEditor,this.editorContainer=new A,this.attachmentsContainer=new A,this.buddySlot=new A,this.editorBuddyLayout=new St(()=>this.editor,this.buddySlot),this.editorContainer.addChild(this.attachmentsContainer),this.editorContainer.addChild(this.editorBuddyLayout),this.imagePipeline=new nt({getCwd:s(()=>this.session.cwd,"getCwd"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),showStatus:s(t=>this.showStatus(t),"showStatus"),getThemeName:s(()=>this.settingsManager.getTheme(),"getThemeName"),isEditorCursorAtTop:s(()=>this.editor.isCursorOnFirstVisualLine?.()??!this.editor.getText().includes(`
3
+ `),"isEditorCursorAtTop"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getAttachmentsContainer:s(()=>this.attachmentsContainer,"getAttachmentsContainer"),getEditorBuddyLayout:s(()=>this.editorBuddyLayout,"getEditorBuddyLayout")}),this.selfUpdate=new ot({getChatContainer:s(()=>this.chatContainer,"getChatContainer"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),getAutoUpdate:s(()=>this.settingsManager.getAutoUpdate(),"getAutoUpdate"),getSkippedVersion:s(()=>this.settingsManager.getSkippedVersion(),"getSkippedVersion"),setSkippedVersion:s(t=>this.settingsManager.setSkippedVersion(t),"setSkippedVersion"),setAutoUpdate:s(t=>this.settingsManager.setAutoUpdate(t),"setAutoUpdate"),showSelector:s((t,a)=>this.promptHost.selector(t,a),"showSelector")}),this.surfaces=new rt({requestRender:s(()=>this.ui.requestRender(),"requestRender"),getUi:s(()=>this.ui,"getUi"),getWidgetContainerAbove:s(()=>this.widgetContainerAbove,"getWidgetContainerAbove"),getWidgetContainerBelow:s(()=>this.widgetContainerBelow,"getWidgetContainerBelow"),getHeaderContainer:s(()=>this.headerContainer,"getHeaderContainer"),getBuiltInHeader:s(()=>this.builtInHeader,"getBuiltInHeader"),getFooter:s(()=>this.footer,"getFooter"),getFooterDataProvider:s(()=>this.footerDataProvider,"getFooterDataProvider")}),this.promptHost=new ht({getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getUi:s(()=>this.ui,"getUi"),getEditor:s(()=>this.editor,"getEditor"),getEditorBuddyLayout:s(()=>this.editorBuddyLayout,"getEditorBuddyLayout"),getKeybindings:s(()=>this.keybindings,"getKeybindings"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")}),this.customOverlay=new dt({getEditor:s(()=>this.editor,"getEditor"),getUi:s(()=>this.ui,"getUi"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getKeybindings:s(()=>this.keybindings,"getKeybindings"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")}),this.editorAdapter=new lt({getEditor:s(()=>this.editor,"getEditor"),setEditor:s(t=>{this.editor=t},"setEditor"),getDefaultEditor:s(()=>this.defaultEditor,"getDefaultEditor"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getUi:s(()=>this.ui,"getUi"),getKeybindings:s(()=>this.keybindings,"getKeybindings"),getAutocompleteProvider:s(()=>this.autocompleteProvider,"getAutocompleteProvider"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")}),this.footerDataProvider=new je(e.cwd),this.footer=new At(e,this.footerDataProvider,this.settingsManager.getShowTokenStats()),this.footer.setAutoCompactEnabled(e.autoCompactionEnabled),this.authProviderConfig=new ut({modelRegistry:this.session.modelRegistry,surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),promptInput:s((t,a,h)=>this.promptHost.input(t,a,h),"promptInput"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),getUi:s(()=>this.ui,"getUi"),getEditorContainer:s(()=>this.editorContainer,"getEditorContainer"),getEditor:s(()=>this.editor,"getEditor"),remountEditorShell:s(()=>this.remountEditorShell(),"remountEditorShell")},modelBridge:{getCurrentModel:s(()=>this.session.model,"getCurrentModel"),setCurrentModel:s(async t=>{await this.session.setModel(t),this.footer.invalidate(),this.updateEditorBorderColor()},"setCurrentModel"),showModelSelector:s((t,a)=>this.modelOverlay.showModelSelector(t,a),"showModelSelector"),applySelectedModel:s(t=>this.modelOverlay.applySelectedModel(t),"applySelectedModel"),updateAvailableProviderCount:s(()=>this.modelOverlay.updateAvailableProviderCount(),"updateAvailableProviderCount")}}),this.modelOverlay=new ct({modelSession:{getModel:s(()=>this.session.model,"getModel"),setModel:s(t=>this.session.setModel(t),"setModel"),cycleModel:s(t=>this.session.cycleModel(t),"cycleModel"),getThinkingLevel:s(()=>this.session.thinkingLevel,"getThinkingLevel"),setThinkingLevel:s(t=>this.session.setThinkingLevel(t),"setThinkingLevel"),cycleThinkingLevel:s(()=>this.session.cycleThinkingLevel(),"cycleThinkingLevel"),getAvailableThinkingLevels:s(()=>this.session.getAvailableThinkingLevels(),"getAvailableThinkingLevels"),getScopedModels:s(()=>this.session.scopedModels,"getScopedModels"),setScopedModels:s(t=>this.session.setScopedModels(t),"setScopedModels")},modelCatalog:{refresh:s(()=>this.session.modelRegistry.refresh(),"refresh"),getAvailable:s(()=>this.session.modelRegistry.getAvailable(),"getAvailable"),getAll:s(()=>this.session.modelRegistry.getAll(),"getAll"),find:s((t,a)=>this.session.modelRegistry.find(t,a),"find"),appendOpenRouterModel:s((t,a)=>this.session.modelRegistry.appendOpenRouterModel(t,a),"appendOpenRouterModel"),getCredentialType:s(t=>this.session.modelRegistry.authStorage.get(t)?.type,"getCredentialType"),getRegistry:s(()=>this.session.modelRegistry,"getRegistry")},modelSettings:{getEnabledModels:s(()=>this.settingsManager.getEnabledModels(),"getEnabledModels"),setEnabledModels:s(t=>this.settingsManager.setEnabledModels(t),"setEnabledModels"),setDefaultModelAndProvider:s((t,a)=>this.settingsManager.setDefaultModelAndProvider(t,a),"setDefaultModelAndProvider")},providerConfig:{ensureProviderConfiguredForSelection:s(t=>this.authProviderConfig.ensureProviderConfiguredForSelection(t),"ensureProviderConfiguredForSelection"),handleProviderSelectionFromSelector:s((t,a)=>this.authProviderConfig.handleProviderSelectionFromSelector(t,a),"handleProviderSelectionFromSelector"),promptForProviderApiKey:s((t,a)=>this.authProviderConfig.promptForProviderApiKey(t,a),"promptForProviderApiKey")},surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),promptInput:s((t,a,h)=>this.promptHost.input(t,a,h),"promptInput"),getUi:s(()=>this.ui,"getUi")},footer:{invalidate:s(()=>this.footer.invalidate(),"invalidate"),setAvailableProviderCount:s(t=>this.footerDataProvider.setAvailableProviderCount(t),"setAvailableProviderCount"),updateEditorBorderColor:s(()=>this.updateEditorBorderColor(),"updateEditorBorderColor")},playDaxnuts:s(()=>this.handleDaxnuts(),"playDaxnuts")}),this.treeOverlay=new gt({session:this.session,getSessionManager:s(()=>this.sessionManager,"getSessionManager"),surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),getUi:s(()=>this.ui,"getUi"),getChatContainer:s(()=>this.chatContainer,"getChatContainer"),getStatusContainer:s(()=>this.statusContainer,"getStatusContainer"),clearChat:s(()=>{this.clearStatusTimers(),this.chatContainer.clear()},"clearChat"),clearTransientSessionUi:s(()=>{this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear(),this.pendingMessagesContainer.clear(),this.state.compactionQueuedMessages=[],this.state.streamingComponent=void 0,this.state.streamingMessage=void 0,this.state.pendingTools.clear(),this.imagePipeline.clearAttachments()},"clearTransientSessionUi"),addSessionNavigationBanner:s(t=>this.addSessionNavigationBanner(t),"addSessionNavigationBanner"),renderInitialMessages:s(()=>this.renderInitialMessages(),"renderInitialMessages"),getEditorText:s(()=>this.editor.getText(),"getEditorText"),setEditorText:s(t=>this.editor.setText(t),"setEditorText"),getEscapeHandler:s(()=>this.defaultEditor.onEscape,"getEscapeHandler"),setEscapeHandler:s(t=>{this.defaultEditor.onEscape=t},"setEscapeHandler")},promptHost:{selector:s((t,a)=>this.promptHost.selector(t,a),"selector"),editor:s((t,a)=>this.promptHost.editor(t,a),"editor")},keybindings:this.keybindings,shutdown:s(()=>this.shutdown(),"shutdown")}),this.settingsOverlay=new mt({session:this.session,settingsManager:this.settingsManager,surface:{showSelector:s(t=>this.showSelector(t),"showSelector"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError"),invalidateUi:s(()=>this.ui.invalidate(),"invalidateUi"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),setShowHardwareCursor:s(t=>this.ui.setShowHardwareCursor(t),"setShowHardwareCursor"),setClearOnShrink:s(t=>this.ui.setClearOnShrink(t),"setClearOnShrink")},footer:{setAutoCompactEnabled:s(t=>this.footer.setAutoCompactEnabled(t),"setAutoCompactEnabled"),setShowTokenStats:s(t=>this.footer.setShowTokenStats(t),"setShowTokenStats"),invalidate:s(()=>this.footer.invalidate(),"invalidate")},editor:{setPaddingX:s(t=>{this.defaultEditor.setPaddingX(t),this.editor!==this.defaultEditor&&this.editor.setPaddingX!==void 0&&this.editor.setPaddingX(t)},"setPaddingX"),setAutocompleteMaxVisible:s(t=>{this.defaultEditor.setAutocompleteMaxVisible(t),this.editor!==this.defaultEditor&&this.editor.setAutocompleteMaxVisible!==void 0&&this.editor.setAutocompleteMaxVisible(t)},"setAutocompleteMaxVisible"),updateBorderColor:s(()=>this.updateEditorBorderColor(),"updateBorderColor")},render:{setToolImagesEnabled:s(t=>{for(const a of this.chatContainer.children)a instanceof ke&&a.setShowImages(t)},"setToolImagesEnabled"),setAssistantThinkingHidden:s(t=>{for(const a of this.chatContainer.children)a instanceof xe&&a.setHideThinkingBlock(t);this.clearStatusTimers(),this.chatContainer.clear()},"setAssistantThinkingHidden"),rebuildChatFromMessages:s(()=>this.rebuildChatFromMessages(),"rebuildChatFromMessages")},getHideThinkingBlock:s(()=>this.state.hideThinkingBlock,"getHideThinkingBlock"),setHideThinkingBlock:s(t=>{this.state.hideThinkingBlock=t},"setHideThinkingBlock"),rebuildAutocomplete:s(()=>this.setupAutocomplete(this.fdPath),"rebuildAutocomplete"),syncBuddyPet:s(()=>this.syncBuddyPet(),"syncBuddyPet")}),this.slashDispatcher=new pt({clearEditor:s(()=>this.editor.setText(""),"clearEditor"),settings:{showSettingsSelector:s(()=>this.settingsOverlay.showSettingsSelector(),"showSettingsSelector")},model:{showScopedModelsSelector:s(()=>this.modelOverlay.showModelsSelector(),"showScopedModelsSelector"),handleModelCommand:s(t=>this.modelOverlay.handleModelCommand(t),"handleModelCommand"),handleThinkingCommand:s(t=>this.modelOverlay.handleThinkingCommand(t),"handleThinkingCommand")},auth:{handleApiKeyCommand:s(()=>this.authProviderConfig.handleApiKeyCommand(),"handleApiKeyCommand"),handleLoginCommand:s(t=>this.authProviderConfig.handleLoginCommand(t),"handleLoginCommand"),showLogoutSelector:s(()=>this.authProviderConfig.showOAuthSelector("logout"),"showLogoutSelector")},tree:{showForkSelector:s(()=>this.treeOverlay.showForkSelector(),"showForkSelector"),showTreeSelector:s(()=>this.treeOverlay.showTreeSelector(),"showTreeSelector"),showSessionSelector:s(()=>this.treeOverlay.showSessionSelector(),"showSessionSelector")},selfUpdate:{handleUpdateCommand:s(()=>this.selfUpdate.handleUpdateCommand(),"handleUpdateCommand"),handleReinstallCommand:s(()=>this.selfUpdate.handleReinstallCommand(),"handleReinstallCommand")},commands:{isExtensionCommand:s(t=>this.isExtensionCommand(t),"isExtensionCommand"),handleAgentLoopCommand:s(t=>this.handleAgentLoopCommand(t),"handleAgentLoopCommand"),handleMcpCommand:s(t=>this.handleMcpCommand(t),"handleMcpCommand"),handleExportCommand:s(t=>this.handleExportCommand(t),"handleExportCommand"),handleShareCommand:s(()=>this.handleShareCommand(),"handleShareCommand"),handleCopyCommand:s(()=>this.handleCopyCommand(),"handleCopyCommand"),handleStatusCommand:s(()=>this.handleStatusCommand(),"handleStatusCommand"),handleUsageCommand:s(()=>this.handleUsageCommand(),"handleUsageCommand"),handleNameCommand:s(t=>this.handleNameCommand(t),"handleNameCommand"),handleSessionCommand:s(()=>this.handleSessionCommand(),"handleSessionCommand"),handleChangelogCommand:s(()=>this.handleChangelogCommand(),"handleChangelogCommand"),handleHotkeysCommand:s(()=>this.handleHotkeysCommand(),"handleHotkeysCommand"),handleShowResourcesCommand:s(()=>this.handleShowResourcesCommand(),"handleShowResourcesCommand"),handleClearCommand:s(()=>this.handleClearCommand(),"handleClearCommand"),handleCompactCommand:s(t=>this.handleCompactCommand(t),"handleCompactCommand"),handleReloadCommand:s(()=>this.handleReloadCommand(),"handleReloadCommand"),handleLanguageCommand:s(t=>this.handleLanguageCommand(t),"handleLanguageCommand"),handleSoulCommand:s(()=>this.handleSoulCommand(),"handleSoulCommand"),handlePersonaCommand:s(t=>this.handlePersonaCommand(t),"handlePersonaCommand"),handleMemoryCommand:s(()=>this.handleMemoryCommand(),"handleMemoryCommand"),handleArminSaysHi:s(()=>this.handleArminSaysHi(),"handleArminSaysHi"),handleBrowserOptInCommand:s(()=>this.handleBrowserOptInCommand(),"handleBrowserOptInCommand"),shutdown:s(()=>this.shutdown(),"shutdown")}}),this.inputSubmit=new ft({editor:{setText:s(t=>this.editor.setText(t),"setText"),addToHistory:s(t=>this.editor.addToHistory?.(t),"addToHistory"),handleExternalInput:s(t=>this.onInputCallback?(this.onInputCallback(t),this.editor.addToHistory?.(t),!0):!1,"handleExternalInput"),setBashMode:s(t=>{this.isBashMode=t},"setBashMode"),updateBorderColor:s(()=>this.updateEditorBorderColor(),"updateBorderColor")},slash:{execute:s(t=>this.slashDispatcher.execute(t),"execute")},image:{awaitPendingPaste:s(()=>this.imagePipeline.awaitPendingPaste(),"awaitPendingPaste"),extractImagesFromText:s(t=>this.imagePipeline.extractImagesFromText(t),"extractImagesFromText"),takePendingAttachments:s(()=>this.imagePipeline.takePendingAttachments(),"takePendingAttachments"),processAttachmentFiles:s(t=>this.imagePipeline.processAttachmentFiles(t),"processAttachmentFiles"),cleanupClipboardImages:s(()=>this.imagePipeline.cleanupClipboardImages(),"cleanupClipboardImages")},session:{isBashRunning:s(()=>this.session.isBashRunning,"isBashRunning"),isCompacting:s(()=>this.session.isCompacting,"isCompacting"),isStreaming:s(()=>this.session.isStreaming,"isStreaming"),getModel:s(()=>this.session.model,"getModel"),getCwd:s(()=>this.session.cwd,"getCwd"),promptAfterRender:s((t,a)=>this.promptAfterRender(t,a),"promptAfterRender"),queueCompactionMessage:s((t,a)=>this.queueCompactionMessage(t,a),"queueCompactionMessage")},commands:{isExtensionCommand:s(t=>this.isExtensionCommand(t),"isExtensionCommand"),handlePersonaCommand:s(t=>this.handlePersonaCommand(t),"handlePersonaCommand"),handleBashCommand:s((t,a)=>this.handleBashCommand(t,a),"handleBashCommand")},render:{showStatus:s(t=>this.showStatus(t),"showStatus"),showWarning:s(t=>this.showWarning(t),"showWarning"),showError:s(t=>this.showError(t),"showError"),notify:s((t,a)=>this.notify(t,a),"notify"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),flushPendingBashComponents:s(()=>this.flushPendingBashComponents(),"flushPendingBashComponents"),updatePendingMessagesDisplay:s(()=>this.updatePendingMessagesDisplay(),"updatePendingMessagesDisplay"),addOptimisticUserMessage:s((t,a)=>{this.state.optimisticUserMessages.push({text:t}),this.addMessageToChat({role:"user",content:a,timestamp:Date.now()})},"addOptimisticUserMessage"),rollbackFirstOptimisticUserMessageIfMatches:s(t=>{this.state.optimisticUserMessages.length>0&&this.state.optimisticUserMessages[0]?.text===t&&this.state.optimisticUserMessages.shift()},"rollbackFirstOptimisticUserMessageIfMatches")}}),this.interrupt=new Ct({queue:{isLoadingAnimationActive:s(()=>!!this.state.loadingAnimation,"isLoadingAnimationActive"),restoreQueuedMessagesWithAbort:s(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"restoreQueuedMessagesWithAbort")},runtime:{isStreaming:s(()=>this.session.isStreaming,"isStreaming"),isBashRunning:s(()=>this.session.isBashRunning,"isBashRunning"),abortAgent:s(()=>this.agent.abort(),"abortAgent"),abortBash:s(()=>this.session.abortBash(),"abortBash")},bash:{isBashMode:s(()=>this.isBashMode,"isBashMode"),exitBashMode:s(()=>{this.editor.setText(""),this.isBashMode=!1,this.updateEditorBorderColor()},"exitBashMode")},editor:{getText:s(()=>this.editor.getText(),"getText"),clearEditor:s(()=>this.clearEditor(),"clearEditor")},tree:{getDoubleEscapeAction:s(()=>this.settingsManager.getDoubleEscapeAction(),"getDoubleEscapeAction"),showTreeSelector:s(()=>this.treeOverlay.showTreeSelector(),"showTreeSelector"),showForkSelector:s(()=>this.treeOverlay.showForkSelector(),"showForkSelector")},lifecycle:{requestShutdown:s(()=>{this.shutdown()},"requestShutdown"),suspend:s(()=>this.suspend(),"suspend")}}),this.streamRender=new wt({state:{get:s(()=>this.state,"get")},layout:{getUi:s(()=>this.ui,"getUi"),getChatContainer:s(()=>this.chatContainer,"getChatContainer"),getStatusContainer:s(()=>this.statusContainer,"getStatusContainer"),addMessageToChat:s(t=>this.addMessageToChat(t),"addMessageToChat"),updatePendingMessagesDisplay:s(()=>this.updatePendingMessagesDisplay(),"updatePendingMessagesDisplay"),rebuildChatFromMessages:s(()=>this.rebuildChatFromMessages(),"rebuildChatFromMessages"),requestRender:s(()=>this.ui.requestRender(),"requestRender"),invalidateFooter:s(()=>this.footer.invalidate(),"invalidateFooter")},loaders:{getSessionId:s(()=>this.sessionManager.getSessionId(),"getSessionId"),getDefaultWorkingMessage:s(()=>this.getNextCatMessage(),"getDefaultWorkingMessage"),getInterruptKeyHint:s(()=>B(this.keybindings,"interrupt"),"getInterruptKeyHint"),setBuddyPetState:s((t,a,h)=>this.setBuddyPetState(t,a,h),"setBuddyPetState"),startAgentRunTimer:s(()=>this.startAgentRunTimer(),"startAgentRunTimer"),stopAgentRunTimer:s(()=>this.stopAgentRunTimer(),"stopAgentRunTimer"),updateWorkingMessage:s(t=>this.updateWorkingMessage(t),"updateWorkingMessage"),formatElapsedSeconds:s(t=>this.formatElapsedSeconds(t),"formatElapsedSeconds"),isInPlanMode:s(()=>this.footerDataProvider.getExtensionStatuses().has("plan"),"isInPlanMode")},toolTrace:{shouldRenderToolTrace:s(t=>this.shouldRenderToolTrace(t),"shouldRenderToolTrace"),getRegisteredToolDefinition:s(t=>this.getRegisteredToolDefinition(t),"getRegisteredToolDefinition"),getShowImages:s(()=>this.settingsManager.getShowImages(),"getShowImages")},runtime:{getRetryAttempt:s(()=>this.session.retryAttempt,"getRetryAttempt"),abortCompaction:s(()=>this.session.abortCompaction(),"abortCompaction"),abortRetry:s(()=>this.session.abortRetry(),"abortRetry"),flushCompactionQueue:s(t=>{this.flushCompactionQueue(t)},"flushCompactionQueue"),checkShutdownRequested:s(()=>this.checkShutdownRequested(),"checkShutdownRequested"),clearAttachments:s(()=>this.imagePipeline.clearAttachments(),"clearAttachments"),getAgentDir:s(()=>this.session.agentDir,"getAgentDir")},escape:{getHandler:s(()=>this.defaultEditor.onEscape,"getHandler"),setHandler:s(t=>{this.defaultEditor.onEscape=t},"setHandler")},surface:{ensureInitialized:s(async()=>{this.isInitialized||await this.init()},"ensureInitialized"),restoreEditorFocusIfPossible:s(()=>this.promptHost.restoreEditorFocusIfPossible(),"restoreEditorFocusIfPossible"),getUserMessageText:s(t=>this.getUserMessageText(t),"getUserMessageText"),getMarkdownThemeWithSettings:s(()=>this.getMarkdownThemeWithSettings(),"getMarkdownThemeWithSettings"),showStatus:s(t=>this.showStatus(t),"showStatus"),showError:s(t=>this.showError(t),"showError")}}),this.syncBuddyPet(),this.state.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),ue(this.session.resourceLoader.getThemes().themes),Ht(this.settingsManager.getTheme(),!0),this.session.setSlashCommandExecutor(t=>this.slashDispatcher.execute(t,{clearEditor:!1}))}setupAutocomplete(e){const i=Xe(K).map(l=>({name:l.name,description:Z(l.description,l.category,K)})),o=i.find(l=>l.name==="model");o&&(o.getArgumentCompletions=(l,T)=>{const v=this.session.scopedModels.length>0?this.session.scopedModels.map($=>$.model):this.session.modelRegistry.getAvailable();return Vt(l,T,v)});const t=i.find(l=>l.name==="thinking");t&&(t.getArgumentCompletions=(l,T)=>Xt(l,T,this.session.getAvailableThinkingLevels()));const a=i.find(l=>l.name==="agent-loop");a&&(a.getArgumentCompletions=_t);const h=i.find(l=>l.name==="mcp");h&&(h.getArgumentCompletions=(l,T)=>Gt(l,T,fe()));const c=i.find(l=>l.name==="language");c&&(c.getArgumentCompletions=jt);const d=i.find(l=>l.name==="persona");d&&(d.getArgumentCompletions=(l,T)=>zt(l,T,Se(),de()));const m=i.find(l=>l.name==="login");m&&(m.getArgumentCompletions=(l,T)=>Qt(l,T,this.authProviderConfig.getLoginSelectorProviders("login")));const f=this.session.promptTemplates.map(l=>({name:l.name,description:Z(l.description,he(l.name,"prompt"),K)})),b=new Set(i.map(l=>l.name)),w=ze(),E=new Set([...b].filter(l=>!w.has(l))),S=this.session.extensionRunner?.getRegisteredCommands(E)??[],C=new Map(S.map(l=>[l.name,l]));for(const l of i){if(!w.has(l.name))continue;const T=C.get(l.name);T?.getArgumentCompletions&&(l.getArgumentCompletions=T.getArgumentCompletions)}const p=S.filter(l=>!b.has(l.name)).map(l=>({name:l.name,description:Z(l.description??"(extension command)",he(l.name,"extension"),K),getArgumentCompletions:l.getArgumentCompletions}));this.skillCommands.clear();const y=[];if(this.settingsManager.getEnableSkillCommands())for(const l of this.session.resourceLoader.getSkills().skills){const T=`skill:${l.name}`;this.skillCommands.set(T,l.filePath),y.push({name:T,description:Z(l.description,he(l.name,"skill"),K)})}this.autocompleteProvider=new Be([...i,...f,...p,...y],this.session.cwd,e),this.defaultEditor.setAutocompleteProvider(this.autocompleteProvider),this.editor!==this.defaultEditor&&this.editor.setAutocompleteProvider?.(this.autocompleteProvider);const M=new Set([...i,...f,...p,...y].map(l=>l.name));this.defaultEditor.enableSlashHighlight(()=>M,r)}prewarmStartupTools(){this.startupToolsPrewarmed||(this.startupToolsPrewarmed=!0,_("interactive.tools.prewarm.start"),Ee("fd"),Ee("rg"),Promise.all([be("fd",!0),be("rg",!0)]).then(([e])=>{const n=e??Te("fd")??void 0;!n||n===this.fdPath||(this.fdPath=n,this.setupAutocomplete(this.fdPath))}).finally(()=>{_("interactive.tools.prewarm.end")}))}async init(){if(!this.isInitialized){if(_("interactive.init.start"),this.imagePipeline.cleanupStaleClipboardFiles(),this.fdPath=Te("fd")??void 0,this.ui.addChild(this.headerContainer),this.options.verbose||!this.settingsManager.getQuietStartup()){const e=r.bold(r.fg("accent",W))+r.fg("dim",` v${this.version}`),n=W==="catui"||W==="catui"?`${r.fg("dim",Ye)}
4
+ `:"",i=this.keybindings,o=s((a,h)=>vt(i,a,h),"hint"),t=[o("interrupt","to interrupt"),o("clear","to clear"),F(`${B(i,"clear")} twice`,"to exit"),o("exit","to exit (empty)"),o("suspend","to suspend"),Dt("deleteToLineEnd","to delete to end"),o("cycleThinkingLevel","to cycle thinking level"),F(`${B(i,"cycleModelForward")}/${B(i,"cycleModelBackward")}`,"to cycle models"),o("selectModel","to select model"),o("selectProviderThenModel","to select provider then model"),o("expandTools","to expand tools"),o("toggleThinking","to expand thinking"),o("externalEditor","for external editor"),F("/","for commands"),F("!","to run bash"),F("!!","to run bash (no context)"),o("followUp","to queue follow-up"),o("dequeue","to edit all queued messages"),o("pasteImage","to paste image"),F("drop files","to attach")].join(`
5
5
  `);this.builtInHeader=new g(`${e}
6
- ${n}${t}`,1,0),this.headerContainer.addChild(new u(1)),this.headerContainer.addChild(this.builtInHeader),this.headerContainer.addChild(new u(1))}else this.builtInHeader=new g("",0,0),this.headerContainer.addChild(this.builtInHeader);this.ui.addChild(this.notificationQueue),this.ui.addChild(this.chatContainer),this.ui.addChild(this.pendingMessagesContainer),this.ui.addChild(this.statusContainer),this.surfaces.renderWidgets(),this.ui.addChild(this.widgetContainerAbove),this.ui.addChild(this.editorContainer),this.ui.addChild(this.widgetContainerBelow),this.ui.addChild(this.footer),this.ui.setFocus(this.editor),this.setupKeyHandlers(),this.setupEditorSubmitHandler(),await this.applyPersonaFromSessionIfAny(),await this.initExtensions(),this.renderInitialMessages(),this.ui.start(),N("interactive.ui.start"),this.isInitialized=!0,this.prewarmStartupTools(),this.updateTerminalTitle(),this.subscribeToAgent(),this.chatContainer.clear(),this.renderInitialMessages(),await this.session.extensionRunner?.emit({type:"session_ready"}),Nt(()=>{this.ui.invalidate(),this.updateEditorBorderColor(),this.ui.requestRender()}),this.footerDataProvider.onBranchChange(()=>{this.ui.requestRender()}),await this.modelOverlay.updateAvailableProviderCount(),N("interactive.firstInput.ready"),st(),this.session.warmupMcpTools()}}updateTerminalTitle(){const e=D.basename(this.session.cwd),n=this.sessionManager.getSessionName();n?this.ui.terminal.setTitle(`\u270E - ${n} - ${e}`):this.ui.terminal.setTitle(`\u270E - ${e}`)}async run(){await this.init();const e=s(()=>{this.shutdown()},"signalShutdown");process.once("SIGHUP",e),process.once("SIGTERM",e),await this.selfUpdate.checkAutoUpdateOnStartup(),this.settingsManager.getAutoUpdate()!=="always"&&this.selfUpdate.checkForNewVersion().then(d=>{d&&this.selfUpdate.showNewVersionNotification(d)});const{migratedProviders:i,modelFallbackMessage:o,initialMessage:t,initialImages:a,initialMessages:h}=this.options;i&&i.length>0&&this.showWarning(`Migrated credentials to auth.json: ${i.join(", ")}`);const c=this.session.modelRegistry.getError();if(c&&this.showError(`models.json error: ${c}`),o&&this.showWarning(o),t)try{await this.session.prompt(t,{images:a})}catch(d){const m=d instanceof Error?d.message:"Unknown error occurred";this.showError(m)}if(h)for(const d of h)try{await this.session.prompt(d)}catch(m){const f=m instanceof Error?m.message:"Unknown error occurred";this.showError(f)}for(;;){const d=await this.getUserInput(),m=performance.now();ee(`main loop: got input "${d.slice(0,80)}"`);try{await this.session.prompt(d),ee(`main loop: prompt returned normally (${(performance.now()-m).toFixed(0)}ms)`)}catch(f){ee(`main loop: prompt threw: ${f} (${(performance.now()-m).toFixed(0)}ms)`);const M=f instanceof Error?f.message:"Unknown error occurred";this.showError(M)}}}getMarkdownThemeWithSettings(){return{...Wt(),codeBlockIndent:this.settingsManager.getCodeBlockIndent()}}formatDisplayPath(e){const n=J.homedir();let i=e;return i.startsWith(n)&&(i=`~${i.slice(n.length)}`),i}getShortPath(e,n){const i=e.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);if(i&&n.startsWith("npm:"))return i[2];const o=e.match(/git\/[^/]+\/[^/]+\/(.*)/);return o&&n.startsWith("git:")?o[1]:this.formatDisplayPath(e)}getDisplaySourceInfo(e,n){return e==="local"?n==="user"?{label:"user",color:"muted"}:n==="project"?{label:"project",color:"muted"}:n==="temporary"?{label:"path",scopeLabel:"temp",color:"muted"}:{label:"path",color:"muted"}:e==="cli"?{label:"path",scopeLabel:n==="temporary"?"temp":void 0,color:"muted"}:{label:e,scopeLabel:n==="user"?"user":n==="project"?"project":n==="temporary"?"temp":void 0,color:"accent"}}getScopeGroup(e,n){return e==="cli"||n==="temporary"?"path":n==="user"?"user":n==="project"?"project":"path"}isPackageSource(e){return e.startsWith("npm:")||e.startsWith("git:")}buildScopeGroups(e,n){const i={user:{scope:"user",paths:[],packages:new Map},project:{scope:"project",paths:[],packages:new Map},path:{scope:"path",paths:[],packages:new Map}};for(const o of e){const t=this.findMetadata(o,n),a=t?.source??"local",h=t?.scope??"project",c=this.getScopeGroup(a,h),d=i[c];if(this.isPackageSource(a)){const m=d.packages.get(a)??[];m.push(o),d.packages.set(a,m)}else d.paths.push(o)}return[i.project,i.user,i.path].filter(o=>o.paths.length>0||o.packages.size>0)}formatScopeGroups(e,n){const i=[];for(const o of e){i.push(` ${r.fg("accent",o.scope)}`);const t=[...o.paths].sort((h,c)=>h.localeCompare(c));for(const h of t)i.push(r.fg("dim",` ${n.formatPath(h)}`));const a=Array.from(o.packages.entries()).sort(([h],[c])=>h.localeCompare(c));for(const[h,c]of a){i.push(` ${r.fg("mdLink",h)}`);const d=[...c].sort((m,f)=>m.localeCompare(f));for(const m of d)i.push(r.fg("dim",` ${n.formatPackagePath(m,h)}`))}}return i.join(`
6
+ ${n}${t}`,1,0),this.headerContainer.addChild(new u(1)),this.headerContainer.addChild(this.builtInHeader),this.headerContainer.addChild(new u(1))}else this.builtInHeader=new g("",0,0),this.headerContainer.addChild(this.builtInHeader);this.ui.addChild(this.notificationQueue),this.ui.addChild(this.chatContainer),this.ui.addChild(this.pendingMessagesContainer),this.ui.addChild(this.statusContainer),this.surfaces.renderWidgets(),this.ui.addChild(this.widgetContainerAbove),this.ui.addChild(this.editorContainer),this.ui.addChild(this.widgetContainerBelow),this.ui.addChild(this.footer),this.ui.setFocus(this.editor),this.setupKeyHandlers(),this.setupEditorSubmitHandler(),await this.applyPersonaFromSessionIfAny(),await this.initExtensions(),this.renderInitialMessages(),this.ui.start(),_("interactive.ui.start"),this.isInitialized=!0,this.prewarmStartupTools(),this.updateTerminalTitle(),this.subscribeToAgent(),this.chatContainer.clear(),this.renderInitialMessages(),await this.session.extensionRunner?.emit({type:"session_ready"}),Nt(()=>{this.ui.invalidate(),this.updateEditorBorderColor(),this.ui.requestRender()}),this.footerDataProvider.onBranchChange(()=>{this.ui.requestRender()}),await this.modelOverlay.updateAvailableProviderCount(),_("interactive.firstInput.ready"),st(),this.session.warmupMcpTools()}}updateTerminalTitle(){const e=L.basename(this.session.cwd),n=this.sessionManager.getSessionName();n?this.ui.terminal.setTitle(`\u270E - ${n} - ${e}`):this.ui.terminal.setTitle(`\u270E - ${e}`)}async run(){await this.init();const e=s(()=>{this.shutdown()},"signalShutdown");process.once("SIGHUP",e),process.once("SIGTERM",e),await this.selfUpdate.checkAutoUpdateOnStartup(),this.settingsManager.getAutoUpdate()!=="always"&&this.selfUpdate.checkForNewVersion().then(d=>{d&&this.selfUpdate.showNewVersionNotification(d)});const{migratedProviders:i,modelFallbackMessage:o,initialMessage:t,initialImages:a,initialMessages:h}=this.options;i&&i.length>0&&this.showWarning(`Migrated credentials to auth.json: ${i.join(", ")}`);const c=this.session.modelRegistry.getError();if(c&&this.showError(`models.json error: ${c}`),o&&this.showWarning(o),t)try{await this.session.prompt(t,{images:a})}catch(d){const m=d instanceof Error?d.message:"Unknown error occurred";this.showError(m)}if(h)for(const d of h)try{await this.session.prompt(d)}catch(m){const f=m instanceof Error?m.message:"Unknown error occurred";this.showError(f)}for(;;){const d=await this.getUserInput(),m=performance.now();te(`main loop: got input "${d.slice(0,80)}"`);try{await this.session.prompt(d),te(`main loop: prompt returned normally (${(performance.now()-m).toFixed(0)}ms)`)}catch(f){te(`main loop: prompt threw: ${f} (${(performance.now()-m).toFixed(0)}ms)`);const b=f instanceof Error?f.message:"Unknown error occurred";this.showError(b)}}}getMarkdownThemeWithSettings(){return{...Wt(),codeBlockIndent:this.settingsManager.getCodeBlockIndent()}}formatDisplayPath(e){const n=Y.homedir();let i=e;return i.startsWith(n)&&(i=`~${i.slice(n.length)}`),i}getShortPath(e,n){const i=e.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);if(i&&n.startsWith("npm:"))return i[2];const o=e.match(/git\/[^/]+\/[^/]+\/(.*)/);return o&&n.startsWith("git:")?o[1]:this.formatDisplayPath(e)}getDisplaySourceInfo(e,n){return e==="local"?n==="user"?{label:"user",color:"muted"}:n==="project"?{label:"project",color:"muted"}:n==="temporary"?{label:"path",scopeLabel:"temp",color:"muted"}:{label:"path",color:"muted"}:e==="cli"?{label:"path",scopeLabel:n==="temporary"?"temp":void 0,color:"muted"}:{label:e,scopeLabel:n==="user"?"user":n==="project"?"project":n==="temporary"?"temp":void 0,color:"accent"}}getScopeGroup(e,n){return e==="cli"||n==="temporary"?"path":n==="user"?"user":n==="project"?"project":"path"}isPackageSource(e){return e.startsWith("npm:")||e.startsWith("git:")}buildScopeGroups(e,n){const i={user:{scope:"user",paths:[],packages:new Map},project:{scope:"project",paths:[],packages:new Map},path:{scope:"path",paths:[],packages:new Map}};for(const o of e){const t=this.findMetadata(o,n),a=t?.source??"local",h=t?.scope??"project",c=this.getScopeGroup(a,h),d=i[c];if(this.isPackageSource(a)){const m=d.packages.get(a)??[];m.push(o),d.packages.set(a,m)}else d.paths.push(o)}return[i.project,i.user,i.path].filter(o=>o.paths.length>0||o.packages.size>0)}formatScopeGroups(e,n){const i=[];for(const o of e){i.push(` ${r.fg("accent",o.scope)}`);const t=[...o.paths].sort((h,c)=>h.localeCompare(c));for(const h of t)i.push(r.fg("dim",` ${n.formatPath(h)}`));const a=Array.from(o.packages.entries()).sort(([h],[c])=>h.localeCompare(c));for(const[h,c]of a){i.push(` ${r.fg("mdLink",h)}`);const d=[...c].sort((m,f)=>m.localeCompare(f));for(const m of d)i.push(r.fg("dim",` ${n.formatPackagePath(m,h)}`))}}return i.join(`
7
7
  `)}findMetadata(e,n){const i=n.get(e);if(i)return i;let o=e;for(;o.includes("/");){o=o.substring(0,o.lastIndexOf("/"));const t=n.get(o);if(t)return t}}formatPathWithSource(e,n){const i=this.findMetadata(e,n);if(i){const o=this.getShortPath(e,i.source),{label:t,scopeLabel:a}=this.getDisplaySourceInfo(i.source,i.scope);return`${a?`${t} (${a})`:t} ${o}`}return this.formatDisplayPath(e)}formatDiagnostics(e,n){const i=[],o=new Map,t=[];for(const a of e)if(a.type==="collision"&&a.collision){const h=o.get(a.collision.name)??[];h.push(a),o.set(a.collision.name,h)}else t.push(a);for(const[a,h]of o){const c=h[0]?.collision;if(c){i.push(r.fg("warning",` "${a}" collision:`)),i.push(r.fg("dim",` ${r.fg("success","\u2713")} ${this.formatPathWithSource(c.winnerPath,n)}`));for(const d of h)d.collision&&i.push(r.fg("dim",` ${r.fg("warning","\u2717")} ${this.formatPathWithSource(d.collision.loserPath,n)} (skipped)`))}}for(const a of t)if(a.path){const h=this.formatPathWithSource(a.path,n);i.push(r.fg(a.type==="error"?"error":"warning",` ${h}`)),i.push(r.fg(a.type==="error"?"error":"warning",` ${a.message}`))}else i.push(r.fg(a.type==="error"?"error":"warning",` ${a.message}`));return i.join(`
8
8
  `)}showLoadedResources(e){const n=e?.force||this.options.verbose||!this.settingsManager.getQuietStartup(),i=n||e?.showDiagnosticsWhenQuiet===!0;if(!n&&!i)return;const o=this.session.resourceLoader.getPathMetadata(),t=s((d,m="mdHeading")=>r.fg(m,`[${d}]`),"sectionHeader"),a=this.session.resourceLoader.getSkills(),h=this.session.resourceLoader.getPrompts(),c=this.session.resourceLoader.getThemes();if(n){const d=this.session.resourceLoader.getAgentsFiles().agentsFiles;if(d.length>0){this.chatContainer.addChild(new u(1));const S=d.map(C=>r.fg("dim",` ${this.formatDisplayPath(C.path)}`)).join(`
9
9
  `);this.chatContainer.addChild(new g(`${t("Context")}
10
- ${S}`,0,0)),this.chatContainer.addChild(new u(1))}const m=a.skills;if(m.length>0){const S=m.map(y=>y.filePath),C=this.buildScopeGroups(S,o),p=this.formatScopeGroups(C,{formatPath:s(y=>this.formatDisplayPath(y),"formatPath"),formatPackagePath:s((y,b)=>this.getShortPath(y,b),"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Skills")}
11
- ${p}`,0,0)),this.chatContainer.addChild(new u(1))}const f=this.session.promptTemplates;if(f.length>0){const S=f.map(b=>b.filePath),C=this.buildScopeGroups(S,o),p=new Map(f.map(b=>[b.filePath,b])),y=this.formatScopeGroups(C,{formatPath:s(b=>{const l=p.get(b);return l?`/${l.name}`:this.formatDisplayPath(b)},"formatPath"),formatPackagePath:s(b=>{const l=p.get(b);return l?`/${l.name}`:this.formatDisplayPath(b)},"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Prompts")}
12
- ${y}`,0,0)),this.chatContainer.addChild(new u(1))}const M=e?.extensionPaths??[];if(M.length>0){const S=this.buildScopeGroups(M,o),C=this.formatScopeGroups(S,{formatPath:s(p=>this.formatDisplayPath(p),"formatPath"),formatPackagePath:s((p,y)=>this.getShortPath(p,y),"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Extensions","mdHeading")}
13
- ${C}`,0,0)),this.chatContainer.addChild(new u(1))}const E=c.themes.filter(S=>S.sourcePath);if(E.length>0){const S=E.map(y=>y.sourcePath),C=this.buildScopeGroups(S,o),p=this.formatScopeGroups(C,{formatPath:s(y=>this.formatDisplayPath(y),"formatPath"),formatPackagePath:s((y,b)=>this.getShortPath(y,b),"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Themes")}
10
+ ${S}`,0,0)),this.chatContainer.addChild(new u(1))}const m=a.skills;if(m.length>0){const S=m.map(y=>y.filePath),C=this.buildScopeGroups(S,o),p=this.formatScopeGroups(C,{formatPath:s(y=>this.formatDisplayPath(y),"formatPath"),formatPackagePath:s((y,M)=>this.getShortPath(y,M),"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Skills")}
11
+ ${p}`,0,0)),this.chatContainer.addChild(new u(1))}const f=this.session.promptTemplates;if(f.length>0){const S=f.map(M=>M.filePath),C=this.buildScopeGroups(S,o),p=new Map(f.map(M=>[M.filePath,M])),y=this.formatScopeGroups(C,{formatPath:s(M=>{const l=p.get(M);return l?`/${l.name}`:this.formatDisplayPath(M)},"formatPath"),formatPackagePath:s(M=>{const l=p.get(M);return l?`/${l.name}`:this.formatDisplayPath(M)},"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Prompts")}
12
+ ${y}`,0,0)),this.chatContainer.addChild(new u(1))}const b=e?.extensionPaths??[];if(b.length>0){const S=this.buildScopeGroups(b,o),C=this.formatScopeGroups(S,{formatPath:s(p=>this.formatDisplayPath(p),"formatPath"),formatPackagePath:s((p,y)=>this.getShortPath(p,y),"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Extensions","mdHeading")}
13
+ ${C}`,0,0)),this.chatContainer.addChild(new u(1))}const E=c.themes.filter(S=>S.sourcePath);if(E.length>0){const S=E.map(y=>y.sourcePath),C=this.buildScopeGroups(S,o),p=this.formatScopeGroups(C,{formatPath:s(y=>this.formatDisplayPath(y),"formatPath"),formatPackagePath:s((y,M)=>this.getShortPath(y,M),"formatPackagePath")});this.chatContainer.addChild(new g(`${t("Themes")}
14
14
  ${p}`,0,0)),this.chatContainer.addChild(new u(1))}}if(i){const d=a.diagnostics;if(d.length>0){const C=this.formatDiagnostics(d,o);this.chatContainer.addChild(new g(`${r.fg("warning","[Skill conflicts]")}
15
15
  ${C}`,0,0)),this.chatContainer.addChild(new u(1))}const m=h.diagnostics;if(m.length>0){const C=this.formatDiagnostics(m,o);this.chatContainer.addChild(new g(`${r.fg("warning","[Prompt conflicts]")}
16
- ${C}`,0,0)),this.chatContainer.addChild(new u(1))}const f=[],M=this.session.resourceLoader.getExtensions().errors;if(M.length>0)for(const C of M)f.push({type:"error",message:C.error,path:C.path});const w=this.session.extensionRunner?.getCommandDiagnostics()??[];f.push(...w);const E=this.session.extensionRunner?.getShortcutDiagnostics()??[];if(f.push(...E),f.length>0){const C=this.formatDiagnostics(f,o);this.chatContainer.addChild(new g(`${r.fg("warning","[Extension issues]")}
16
+ ${C}`,0,0)),this.chatContainer.addChild(new u(1))}const f=[],b=this.session.resourceLoader.getExtensions().errors;if(b.length>0)for(const C of b)f.push({type:"error",message:C.error,path:C.path});const w=this.session.extensionRunner?.getCommandDiagnostics()??[];f.push(...w);const E=this.session.extensionRunner?.getShortcutDiagnostics()??[];if(f.push(...E),f.length>0){const C=this.formatDiagnostics(f,o);this.chatContainer.addChild(new g(`${r.fg("warning","[Extension issues]")}
17
17
  ${C}`,0,0)),this.chatContainer.addChild(new u(1))}const S=c.diagnostics;if(S.length>0){const C=this.formatDiagnostics(S,o);this.chatContainer.addChild(new g(`${r.fg("warning","[Theme conflicts]")}
18
- ${C}`,0,0)),this.chatContainer.addChild(new u(1))}}}async initExtensions(){const e=this.createExtensionUIContext();await this.session.bindExtensions({uiContext:e,commandContextActions:{waitForIdle:s(()=>this.session.agent.waitForIdle(),"waitForIdle"),newSession:s(async i=>(this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear(),await this.session.newSession(i)?(this.clearStatusTimers(),this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.state.compactionQueuedMessages=[],this.state.streamingComponent=void 0,this.state.streamingMessage=void 0,this.state.pendingTools.clear(),this.imagePipeline.clearAttachments(),this.renderInitialMessages(),{cancelled:!1}):{cancelled:!0}),"newSession"),fork:s(async i=>{const o=await this.session.fork(i);return o.cancelled?{cancelled:!0}:(this.clearStatusTimers(),this.chatContainer.clear(),this.imagePipeline.clearAttachments(),this.addSessionNavigationBanner("Forked session"),this.renderInitialMessages(),this.editor.setText(o.selectedText),this.showStatus("Forked to new session"),{cancelled:!1})},"fork"),navigateTree:s(async(i,o)=>{const t=await this.session.navigateTree(i,{summarize:o?.summarize,customInstructions:o?.customInstructions,replaceInstructions:o?.replaceInstructions,label:o?.label});return t.cancelled?{cancelled:!0}:(this.clearStatusTimers(),this.chatContainer.clear(),this.imagePipeline.clearAttachments(),this.addSessionNavigationBanner("Navigated session tree"),this.renderInitialMessages(),t.editorText&&!this.editor.getText().trim()&&this.editor.setText(t.editorText),this.showStatus("Navigated to selected point"),{cancelled:!1})},"navigateTree"),switchSession:s(async i=>(await this.treeOverlay.resumeSession(i),{cancelled:!1}),"switchSession"),reload:s(async()=>{await this.handleReloadCommand()},"reload")},shutdownHandler:s(()=>{this.shutdownRequested=!0,this.session.isStreaming||this.shutdown()},"shutdownHandler"),onError:s(i=>{this.showExtensionError(i.extensionPath,i.error,i.stack)},"onError")}),ue(this.session.resourceLoader.getThemes().themes),this.setupAutocomplete(this.fdPath);const n=this.session.extensionRunner;if(!n){this.showLoadedResources({extensionPaths:[],force:!1});return}this.setupExtensionShortcuts(n),this.showLoadedResources({extensionPaths:n.getExtensionPaths(),force:!1})}getRegisteredToolDefinition(e){return(this.session.extensionRunner?.getAllRegisteredTools()??[]).find(o=>o.definition.name===e)?.definition}setupExtensionShortcuts(e){const n=e.getShortcuts(this.keybindings.getEffectiveConfig());n.size!==0&&(this.defaultEditor.onExtensionShortcut=i=>{for(const[o,t]of n)if(Oe(i,o))return Promise.resolve(t.handler(e.createContext())).catch(a=>{this.showError(`Shortcut handler error: ${a instanceof Error?a.message:String(a)}`)}),!0;return!1})}formatElapsedSeconds(e){return`${(Math.max(0,e)/1e3).toFixed(1)}s`}getNextCatMessage(){const e=Date.now();return e-this.catMessageLastSwitch>=3e3&&(this.catMessageIndex++,this.catMessageLastSwitch=e),this.catWorkingMessages[this.catMessageIndex%this.catWorkingMessages.length]}buildWorkingMessage(){const e=this.state.workingMessageOverride||this.getNextCatMessage(),n=`${L(this.keybindings,"interrupt")} to interrupt`,i=this.state.agentRunStartMs!==void 0?this.formatElapsedSeconds(Date.now()-this.state.agentRunStartMs):void 0,o=i?`(${i}, ${n})`:`(${n})`;return{base:e,suffix:o}}updateWorkingMessage(e){if(!this.state.loadingAnimation)return;const{base:n,suffix:i}=this.buildWorkingMessage();this.state.loadingAnimation.setMessage(n,{...e,suffix:i})}stopAgentRunTimer(){this.state.agentRunTimer&&(clearInterval(this.state.agentRunTimer),this.state.agentRunTimer=void 0)}stopWelcomeBannerTimer(){this.state.welcomeBannerTimer&&(clearInterval(this.state.welcomeBannerTimer),this.state.welcomeBannerTimer=void 0)}startAgentRunTimer(){this.stopAgentRunTimer(),this.state.agentRunStartMs=Date.now(),this.state.agentRunTimer=setInterval(()=>{if(!this.state.loadingAnimation||this.state.agentRunStartMs===void 0){this.stopAgentRunTimer();return}this.updateWorkingMessage({resetStallTimer:!1})},100)}resetExtensionUI(){this.promptHost.dismiss(),this.ui.hideOverlay(),this.clearExtensionTerminalInputListeners(),this.surfaces.setFooter(void 0),this.surfaces.setHeader(void 0),this.surfaces.clearWidgets(),this.footerDataProvider.clearExtensionStatuses(),this.footer.invalidate(),this.editorAdapter.setComponent(void 0),this.defaultEditor.onExtensionShortcut=void 0,this.updateTerminalTitle(),this.state.loadingAnimation&&(this.state.workingMessageOverride=void 0,this.updateWorkingMessage())}clearBuddyPetResetTimer(){this.buddyPetResetTimer&&(clearTimeout(this.buddyPetResetTimer),this.buddyPetResetTimer=void 0)}syncBuddyPet(){const e=this.settingsManager.getBuddyEnabled(),n=this.settingsManager.getBuddySpecies();if(!e){this.clearBuddyPetResetTimer(),this.buddyPet?.dispose(),this.buddyPet=null,this.buddyPetSpecies=null,this.buddySlot.clear(),this.surfaces.renderWidgets();return}(!this.buddyPet||this.buddyPetSpecies!==n)&&(this.clearBuddyPetResetTimer(),this.buddyPet?.dispose(),this.buddyPet=new yt(this.ui,n),this.buddyPetSpecies=n,this.buddyPet.setState("idle"),this.buddyPet.setSpeechBubble("")),this.buddySlot.clear(),this.buddySlot.addChild(this.buddyPet),this.surfaces.renderWidgets()}remountEditorShell(){this.editorContainer.clear(),this.imagePipeline.hasAttachments()&&this.attachmentsContainer&&this.editorContainer.addChild(this.attachmentsContainer),this.editorContainer.addChild(this.editorBuddyLayout)}setBuddyPetState(e,n="",i){this.buddyPet&&(this.clearBuddyPetResetTimer(),this.buddyPet.setState(e),this.buddyPet.setSpeechBubble(n),i?.resetTo&&(this.buddyPetResetTimer=setTimeout(()=>{this.buddyPet&&(this.buddyPet.setState(i.resetTo??"idle"),this.buddyPet.setSpeechBubble(""),this.buddyPetResetTimer=void 0,this.ui.requestRender())},i.afterMs??1500)),this.ui.requestRender())}addExtensionTerminalInputListener(e){const n=this.ui.addInputListener(e);return this.extensionTerminalInputUnsubscribers.add(n),()=>{n(),this.extensionTerminalInputUnsubscribers.delete(n)}}clearExtensionTerminalInputListeners(){for(const e of this.extensionTerminalInputUnsubscribers)e();this.extensionTerminalInputUnsubscribers.clear()}createExtensionUIContext(){return{select:s((e,n,i)=>this.promptHost.selector(e,n,i),"select"),confirm:s((e,n,i)=>this.promptHost.confirm(e,n,i),"confirm"),input:s((e,n,i)=>this.promptHost.input(e,n,i),"input"),notify:s((e,n)=>this.showExtensionNotify(e,n),"notify"),onTerminalInput:s(e=>this.addExtensionTerminalInputListener(e),"onTerminalInput"),setStatus:s((e,n)=>this.surfaces.setStatus(e,n),"setStatus"),setWorkingMessage:s(e=>{this.state.workingMessageOverride=e||void 0,this.state.loadingAnimation?this.updateWorkingMessage():this.state.pendingWorkingMessage=e},"setWorkingMessage"),setWidget:s((e,n,i)=>this.surfaces.setWidget(e,n,i),"setWidget"),setFooter:s(e=>this.surfaces.setFooter(e),"setFooter"),setHeader:s(e=>this.surfaces.setHeader(e),"setHeader"),setTitle:s(e=>this.ui.terminal.setTitle(e),"setTitle"),custom:s((e,n)=>this.customOverlay.show(e,n),"custom"),pasteToEditor:s(e=>this.editor.handleInput(`\x1B[200~${e}\x1B[201~`),"pasteToEditor"),setEditorText:s(e=>this.editor.setText(e),"setEditorText"),getEditorText:s(()=>this.editor.getText(),"getEditorText"),editor:s((e,n)=>this.promptHost.editor(e,n),"editor"),openExternalEditor:s(e=>this.openExistingFileInExternalEditor(e),"openExternalEditor"),setEditorComponent:s(e=>this.editorAdapter.setComponent(e),"setEditorComponent"),get theme(){return r},getAllThemes:s(()=>Ot(),"getAllThemes"),getTheme:s(e=>Ft(e),"getTheme"),setTheme:s(e=>{if(typeof e!="string")return Kt(e),this.ui.requestRender(),{success:!0};const n=Ae(e,!0);return n.success&&(this.settingsManager.getTheme()!==e&&this.settingsManager.setTheme(e),this.ui.requestRender()),n},"setTheme"),getToolsExpanded:s(()=>this.state.toolOutputExpanded,"getToolsExpanded"),setToolsExpanded:s(e=>this.setToolsExpanded(e),"setToolsExpanded")}}showExtensionNotify(e,n){n==="error"?this.showError(e):n==="warning"?this.showWarning(e):this.showStatus(e)}shouldRenderToolTrace(e){return e.startsWith("nanomem_")?this.settingsManager.getShowMemoryTrace():this.settingsManager.getShowWorkingTrace()}showExtensionError(e,n,i){const o=`Extension "${e}" error: ${n}`,t=new g(r.fg("error",o),1,0);if(this.chatContainer.addChild(t),i){const a=i.split(`
18
+ ${C}`,0,0)),this.chatContainer.addChild(new u(1))}}}async initExtensions(){const e=this.createExtensionUIContext();await this.session.bindExtensions({uiContext:e,commandContextActions:{waitForIdle:s(()=>this.session.agent.waitForIdle(),"waitForIdle"),newSession:s(async i=>(this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear(),await this.session.newSession(i)?(this.clearStatusTimers(),this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.state.compactionQueuedMessages=[],this.state.streamingComponent=void 0,this.state.streamingMessage=void 0,this.state.pendingTools.clear(),this.imagePipeline.clearAttachments(),this.renderInitialMessages(),{cancelled:!1}):{cancelled:!0}),"newSession"),fork:s(async i=>{const o=await this.session.fork(i);return o.cancelled?{cancelled:!0}:(this.clearStatusTimers(),this.chatContainer.clear(),this.imagePipeline.clearAttachments(),this.addSessionNavigationBanner("Forked session"),this.renderInitialMessages(),this.editor.setText(o.selectedText),this.showStatus("Forked to new session"),{cancelled:!1})},"fork"),navigateTree:s(async(i,o)=>{const t=await this.session.navigateTree(i,{summarize:o?.summarize,customInstructions:o?.customInstructions,replaceInstructions:o?.replaceInstructions,label:o?.label});return t.cancelled?{cancelled:!0}:(this.clearStatusTimers(),this.chatContainer.clear(),this.imagePipeline.clearAttachments(),this.addSessionNavigationBanner("Navigated session tree"),this.renderInitialMessages(),t.editorText&&!this.editor.getText().trim()&&this.editor.setText(t.editorText),this.showStatus("Navigated to selected point"),{cancelled:!1})},"navigateTree"),switchSession:s(async i=>(await this.treeOverlay.resumeSession(i),{cancelled:!1}),"switchSession"),reload:s(async()=>{await this.handleReloadCommand()},"reload")},shutdownHandler:s(()=>{this.shutdownRequested=!0,this.session.isStreaming||this.shutdown()},"shutdownHandler"),onError:s(i=>{this.showExtensionError(i.extensionPath,i.error,i.stack)},"onError")}),ue(this.session.resourceLoader.getThemes().themes),this.setupAutocomplete(this.fdPath);const n=this.session.extensionRunner;if(!n){this.showLoadedResources({extensionPaths:[],force:!1});return}this.setupExtensionShortcuts(n),this.showLoadedResources({extensionPaths:n.getExtensionPaths(),force:!1})}getRegisteredToolDefinition(e){return(this.session.extensionRunner?.getAllRegisteredTools()??[]).find(o=>o.definition.name===e)?.definition}setupExtensionShortcuts(e){const n=e.getShortcuts(this.keybindings.getEffectiveConfig());n.size!==0&&(this.defaultEditor.onExtensionShortcut=i=>{for(const[o,t]of n)if(Oe(i,o))return Promise.resolve(t.handler(e.createContext())).catch(a=>{this.showError(`Shortcut handler error: ${a instanceof Error?a.message:String(a)}`)}),!0;return!1})}formatElapsedSeconds(e){return`${(Math.max(0,e)/1e3).toFixed(1)}s`}getNextCatMessage(){const e=Date.now();return e-this.catMessageLastSwitch>=3e3&&(this.catMessageIndex++,this.catMessageLastSwitch=e),this.catWorkingMessages[this.catMessageIndex%this.catWorkingMessages.length]}buildWorkingMessage(){const e=this.state.workingMessageOverride||this.getNextCatMessage(),n=`${B(this.keybindings,"interrupt")} to interrupt`,i=this.state.agentRunStartMs!==void 0?this.formatElapsedSeconds(Date.now()-this.state.agentRunStartMs):void 0,o=i?`(${i}, ${n})`:`(${n})`;return{base:e,suffix:o}}updateWorkingMessage(e){if(!this.state.loadingAnimation)return;const{base:n,suffix:i}=this.buildWorkingMessage();this.state.loadingAnimation.setMessage(n,{...e,suffix:i})}stopAgentRunTimer(){this.state.agentRunTimer&&(clearInterval(this.state.agentRunTimer),this.state.agentRunTimer=void 0)}stopWelcomeBannerTimer(){this.state.welcomeBannerTimer&&(clearInterval(this.state.welcomeBannerTimer),this.state.welcomeBannerTimer=void 0)}startAgentRunTimer(){this.stopAgentRunTimer(),this.state.agentRunStartMs=Date.now(),this.state.agentRunTimer=setInterval(()=>{if(!this.state.loadingAnimation||this.state.agentRunStartMs===void 0){this.stopAgentRunTimer();return}this.updateWorkingMessage({resetStallTimer:!1})},100)}resetExtensionUI(){this.promptHost.dismiss(),this.ui.hideOverlay(),this.clearExtensionTerminalInputListeners(),this.surfaces.setFooter(void 0),this.surfaces.setHeader(void 0),this.surfaces.clearWidgets(),this.footerDataProvider.clearExtensionStatuses(),this.footer.invalidate(),this.editorAdapter.setComponent(void 0),this.defaultEditor.onExtensionShortcut=void 0,this.updateTerminalTitle(),this.state.loadingAnimation&&(this.state.workingMessageOverride=void 0,this.updateWorkingMessage())}clearBuddyPetResetTimer(){this.buddyPetResetTimer&&(clearTimeout(this.buddyPetResetTimer),this.buddyPetResetTimer=void 0)}syncBuddyPet(){const e=this.settingsManager.getBuddyEnabled(),n=this.settingsManager.getBuddySpecies();if(!e){this.clearBuddyPetResetTimer(),this.buddyPet?.dispose(),this.buddyPet=null,this.buddyPetSpecies=null,this.buddySlot.clear(),this.surfaces.renderWidgets();return}(!this.buddyPet||this.buddyPetSpecies!==n)&&(this.clearBuddyPetResetTimer(),this.buddyPet?.dispose(),this.buddyPet=new yt(this.ui,n),this.buddyPetSpecies=n,this.buddyPet.setState("idle"),this.buddyPet.setSpeechBubble("")),this.buddySlot.clear(),this.buddySlot.addChild(this.buddyPet),this.surfaces.renderWidgets()}remountEditorShell(){this.editorContainer.clear(),this.imagePipeline.hasAttachments()&&this.attachmentsContainer&&this.editorContainer.addChild(this.attachmentsContainer),this.editorContainer.addChild(this.editorBuddyLayout)}setBuddyPetState(e,n="",i){this.buddyPet&&(this.clearBuddyPetResetTimer(),this.buddyPet.setState(e),this.buddyPet.setSpeechBubble(n),i?.resetTo&&(this.buddyPetResetTimer=setTimeout(()=>{this.buddyPet&&(this.buddyPet.setState(i.resetTo??"idle"),this.buddyPet.setSpeechBubble(""),this.buddyPetResetTimer=void 0,this.ui.requestRender())},i.afterMs??1500)),this.ui.requestRender())}addExtensionTerminalInputListener(e){const n=this.ui.addInputListener(e);return this.extensionTerminalInputUnsubscribers.add(n),()=>{n(),this.extensionTerminalInputUnsubscribers.delete(n)}}clearExtensionTerminalInputListeners(){for(const e of this.extensionTerminalInputUnsubscribers)e();this.extensionTerminalInputUnsubscribers.clear()}createExtensionUIContext(){return{select:s((e,n,i)=>this.promptHost.selector(e,n,i),"select"),confirm:s((e,n,i)=>this.promptHost.confirm(e,n,i),"confirm"),input:s((e,n,i)=>this.promptHost.input(e,n,i),"input"),notify:s((e,n)=>this.showExtensionNotify(e,n),"notify"),onTerminalInput:s(e=>this.addExtensionTerminalInputListener(e),"onTerminalInput"),setStatus:s((e,n)=>this.surfaces.setStatus(e,n),"setStatus"),setWorkingMessage:s(e=>{this.state.workingMessageOverride=e||void 0,this.state.loadingAnimation?this.updateWorkingMessage():this.state.pendingWorkingMessage=e},"setWorkingMessage"),setWidget:s((e,n,i)=>this.surfaces.setWidget(e,n,i),"setWidget"),setFooter:s(e=>this.surfaces.setFooter(e),"setFooter"),setHeader:s(e=>this.surfaces.setHeader(e),"setHeader"),setTitle:s(e=>this.ui.terminal.setTitle(e),"setTitle"),custom:s((e,n)=>this.customOverlay.show(e,n),"custom"),pasteToEditor:s(e=>this.editor.handleInput(`\x1B[200~${e}\x1B[201~`),"pasteToEditor"),setEditorText:s(e=>this.editor.setText(e),"setEditorText"),getEditorText:s(()=>this.editor.getText(),"getEditorText"),editor:s((e,n)=>this.promptHost.editor(e,n),"editor"),openExternalEditor:s(e=>this.openExistingFileInExternalEditor(e),"openExternalEditor"),setEditorComponent:s(e=>this.editorAdapter.setComponent(e),"setEditorComponent"),get theme(){return r},getAllThemes:s(()=>Ot(),"getAllThemes"),getTheme:s(e=>Ft(e),"getTheme"),setTheme:s(e=>{if(typeof e!="string")return Kt(e),this.ui.requestRender(),{success:!0};const n=Ae(e,!0);return n.success&&(this.settingsManager.getTheme()!==e&&this.settingsManager.setTheme(e),this.ui.requestRender()),n},"setTheme"),getToolsExpanded:s(()=>this.state.toolOutputExpanded,"getToolsExpanded"),setToolsExpanded:s(e=>this.setToolsExpanded(e),"setToolsExpanded")}}showExtensionNotify(e,n){n==="error"?this.showError(e):n==="warning"?this.showWarning(e):this.showStatus(e)}shouldRenderToolTrace(e){return e.startsWith("nanomem_")?this.settingsManager.getShowMemoryTrace():this.settingsManager.getShowWorkingTrace()}showExtensionError(e,n,i){const o=`Extension "${e}" error: ${n}`,t=new g(r.fg("error",o),1,0);if(this.chatContainer.addChild(t),i){const a=i.split(`
19
19
  `).slice(1).map(h=>r.fg("dim",` ${h.trim()}`)).join(`
20
- `);a&&this.chatContainer.addChild(new g(a,1,0))}this.ui.requestRender()}setupKeyHandlers(){this.defaultEditor.onEscape=()=>this.interrupt.dispatchEscape(),this.defaultEditor.onAction("clear",()=>this.interrupt.handleCtrlC()),this.defaultEditor.onAction("showResources",()=>this.handleShowResourcesCommand()),this.defaultEditor.onCtrlD=()=>this.interrupt.handleCtrlD(),this.defaultEditor.onAction("suspend",()=>this.interrupt.handleCtrlZ()),this.defaultEditor.onAction("cycleThinkingLevel",()=>this.modelOverlay.cycleThinkingLevel()),this.defaultEditor.onAction("cycleModelForward",()=>this.modelOverlay.cycleModel("forward")),this.defaultEditor.onAction("cycleModelBackward",()=>this.modelOverlay.cycleModel("backward")),this.ui.onDebug=()=>this.handleRenderDebugCommand(),this.defaultEditor.onAction("selectModel",()=>this.modelOverlay.showProviderThenModelSelector()),this.defaultEditor.onAction("selectProviderThenModel",()=>this.modelOverlay.showProviderThenModelSelector()),this.defaultEditor.onAction("expandTools",()=>this.toggleToolOutputExpansion()),this.defaultEditor.onAction("toggleThinking",()=>this.toggleThinkingBlockVisibility()),this.defaultEditor.onAction("externalEditor",()=>this.openExternalEditor()),this.defaultEditor.onAction("followUp",()=>this.handleFollowUp()),this.defaultEditor.onAction("dequeue",()=>this.handleDequeue()),this.defaultEditor.onAction("newSession",()=>this.handleClearCommand()),this.defaultEditor.onAction("tree",()=>this.treeOverlay.showTreeSelector()),this.defaultEditor.onAction("fork",()=>this.treeOverlay.showForkSelector()),this.defaultEditor.onAction("resume",()=>this.treeOverlay.showSessionSelector()),this.defaultEditor.onChange=e=>{const n=this.isBashMode;this.isBashMode=e.trimStart().startsWith("!"),n!==this.isBashMode&&this.updateEditorBorderColor()},this.defaultEditor.onPasteImage=()=>{this.imagePipeline.handleClipboardImagePaste()},this.defaultEditor.onAttachmentKey=e=>this.imagePipeline.handleAttachmentKeyNavigation(e)}setupEditorSubmitHandler(){this.defaultEditor.onSubmit=async e=>{await this.inputSubmit.handleSubmit(e)}}subscribeToAgent(){this.unsubscribe=this.session.subscribe(async e=>{await this.handleEvent(e)})}addSessionNavigationBanner(e){const n=this.sessionManager.getSessionName(),i=this.sessionManager.getSessionId(),o=n?` "${n}"`:"",t=r.fg("dim",`\u21AA ${e} \u2192 session${o} (${i})`);this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(t,1,1)),this.chatContainer.addChild(new u(1))}async handleEvent(e){if(ee(`handleEvent: ${e.type}`),e.type==="sdk:mcp_ready"){e.toolCount>0&&this.showStatus(`MCP: ${e.toolCount} tool(s) ready`);return}await this.streamRender.handle(e)}getUserMessageText(e){return e.role!=="user"?"":(typeof e.content=="string"?[{type:"text",text:e.content}]:e.content.filter(i=>i.type==="text")).map(i=>i.text).join("")}showStatus(e){const n=this.chatContainer.children,i=n.length>0?n[n.length-1]:void 0,o=n.length>1?n[n.length-2]:void 0;if(i&&o&&i===this.state.lastStatusText&&o===this.state.lastStatusSpacer){this.state.lastStatusText.setText(r.fg("dim",e)),this.scheduleStatusDismiss(this.state.lastStatusSpacer,this.state.lastStatusText),this.ui.requestRender();return}const t=new u(1),a=new g(r.fg("dim",e),1,0);this.chatContainer.addChild(t),this.chatContainer.addChild(a),this.state.lastStatusSpacer=t,this.state.lastStatusText=a,this.scheduleStatusDismiss(t,a),this.ui.requestRender()}addMessageToChat(e,n){switch(e.role){case"bashExecution":{const i=new ce(e.command,this.ui,e.excludeFromContext);e.output&&i.appendOutput(e.output),i.setComplete(e.exitCode,e.cancelled,e.truncated?{truncated:!0}:void 0,e.fullOutputPath),this.chatContainer.addChild(i);break}case"custom":{if(e.display){const i=typeof e.details=="object"&&e.details!==null?e.details:void 0;if(i?.replace&&i.streamKey){const a=this.state.customStreamComponents.get(i.streamKey);if(a){a.updateMessage(e),this.ui.requestRender();break}}const o=this.session.extensionRunner?.getMessageRenderer(e.customType),t=new kt(e,o,this.getMarkdownThemeWithSettings());t.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(t),i?.streamKey&&this.state.customStreamComponents.set(i.streamKey,t)}break}case"compactionSummary":{this.chatContainer.addChild(new u(1));const i=new xt(e,this.getMarkdownThemeWithSettings());i.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(i);break}case"branchSummary":{this.chatContainer.addChild(new u(1));const i=new bt(e,this.getMarkdownThemeWithSettings());i.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(i);break}case"user":{const i=this.getUserMessageText(e);if(i){const o=_e(i);if(o){this.chatContainer.addChild(new u(1));const t=new Bt(o,this.getMarkdownThemeWithSettings());if(t.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(t),o.userMessage){const a=new $e(o.userMessage,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(a)}}else{const t=new $e(i,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(t)}n?.populateHistory&&this.editor.addToHistory?.(i)}break}case"assistant":{const i=new xe(e,this.state.hideThinkingBlock,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(i);break}case"toolResult":break;default:{const i=e}}}renderSessionContext(e,n={}){this.state.pendingTools.clear(),this.state.customStreamComponents.clear(),n.updateFooter&&(this.footer.invalidate(),this.updateEditorBorderColor());for(const i of e.messages)if(i.role==="assistant"){this.addMessageToChat(i);for(const o of i.content)if(o.type==="toolCall"){const t=new ke(o.name,o.arguments,{showImages:this.settingsManager.getShowImages()},this.getRegisteredToolDefinition(o.name),this.ui);if(t.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(t),i.stopReason==="aborted"||i.stopReason==="error"){let a;if(i.stopReason==="aborted"){const h=this.session.retryAttempt;a=h>0?`Aborted after ${h} retry attempt${h>1?"s":""}`:"Operation aborted"}else a=i.errorMessage||"Error";t.updateResult({content:[{type:"text",text:a}],isError:!0})}else this.state.pendingTools.set(o.id,t)}}else if(i.role==="toolResult"){const o=this.state.pendingTools.get(i.toolCallId);o&&(o.updateResult(i),this.state.pendingTools.delete(i.toolCallId))}else this.addMessageToChat(i,n);this.state.pendingTools.clear(),this.ui.requestRender()}renderInitialMessages(){this.stopWelcomeBannerTimer();const e=this.sessionManager.buildSessionContext();if(this.renderSessionContext(e,{updateFooter:!0,populateHistory:!0}),e.messages.length===0){if(this.chatContainer.addChild(new u(1)),O==="catui"||O==="catui"){const o=this.session.cwd,t=this.session.model,a=t?.name??(t?.provider?`${t.provider}`:"DashScope \xB7 Ollama"),h=s(l=>{const $=[" __..--''``\\--....___ _..,_",""," //// _.-' .-/\"; ` ``<._ ``-+'~=. ////",""," ///_.-' _..--.' \\ `(^) ) //",""," // ((..-' // (< - ;_..__ ; `' //",""," ////////////// `-._,_)'//////``--...____..-' /////"," //////////////////////////////////////////////////","",l%8===5?"///CATU I///////////////////////////////////////////":"///CATUI////////////////////////////////////////////","","---------------------------------------------------"],A=Math.max(...$.map(R=>R.length));return $.map(R=>R.padEnd(A))},"buildAsciiLines"),c=s(l=>h(l).map(T=>r.fg("accent",T.slice(0,Math.max(1,this.ui.terminal.columns||80)))).join(`
21
- `),"renderAscii"),d=r.bold(r.fg("accent",`catui-agent v${this.version}`)),m=r.fg("dim",a),f=r.fg("dim",o),M=r.fg("dim"," /model to switch model"),w=this.getAppKeyDisplay("showResources"),E=this.settingsManager.getQuietStartup()?r.fg("dim",` ${w} to show context/skills/extensions`):"",S=r.fg("borderMuted","\u2500".repeat(Math.max(40,this.ui.terminal.columns||80))),C=r.fg("accent",'\u276F Try "refactor <filepath>" or type below'),p=[c(0),"",` ${d}`,` ${m}`,` ${f}`,"",M,...E?["",E]:[],"",S,C].join(`
22
- `),y=new g(p,0,0);this.chatContainer.addChild(y);let b=0;this.state.welcomeBannerTimer=setInterval(()=>{b+=1,y.setText([c(b),"",` ${d}`,` ${m}`,` ${f}`,"",M,...E?["",E]:[],"",S,C].join(`
23
- `)),this.ui.requestRender(),b>=16&&this.stopWelcomeBannerTimer()},220)}else{const t=[" \u270E"," +---------------+",` | ${O.padEnd(14).slice(0,14)} |`," +---------------+"].join(`
20
+ `);a&&this.chatContainer.addChild(new g(a,1,0))}this.ui.requestRender()}setupKeyHandlers(){this.defaultEditor.onEscape=()=>this.interrupt.dispatchEscape(),this.defaultEditor.onAction("clear",()=>this.interrupt.handleCtrlC()),this.defaultEditor.onAction("showResources",()=>this.handleShowResourcesCommand()),this.defaultEditor.onCtrlD=()=>this.interrupt.handleCtrlD(),this.defaultEditor.onAction("suspend",()=>this.interrupt.handleCtrlZ()),this.defaultEditor.onAction("cycleThinkingLevel",()=>this.modelOverlay.cycleThinkingLevel()),this.defaultEditor.onAction("cycleModelForward",()=>this.modelOverlay.cycleModel("forward")),this.defaultEditor.onAction("cycleModelBackward",()=>this.modelOverlay.cycleModel("backward")),this.ui.onDebug=()=>this.handleRenderDebugCommand(),this.defaultEditor.onAction("selectModel",()=>this.modelOverlay.showProviderThenModelSelector()),this.defaultEditor.onAction("selectProviderThenModel",()=>this.modelOverlay.showProviderThenModelSelector()),this.defaultEditor.onAction("expandTools",()=>this.toggleToolOutputExpansion()),this.defaultEditor.onAction("toggleThinking",()=>this.toggleThinkingBlockVisibility()),this.defaultEditor.onAction("externalEditor",()=>this.openExternalEditor()),this.defaultEditor.onAction("followUp",()=>this.handleFollowUp()),this.defaultEditor.onAction("dequeue",()=>this.handleDequeue()),this.defaultEditor.onAction("newSession",()=>this.handleClearCommand()),this.defaultEditor.onAction("tree",()=>this.treeOverlay.showTreeSelector()),this.defaultEditor.onAction("fork",()=>this.treeOverlay.showForkSelector()),this.defaultEditor.onAction("resume",()=>this.treeOverlay.showSessionSelector()),this.defaultEditor.onChange=e=>{const n=this.isBashMode;this.isBashMode=e.trimStart().startsWith("!"),n!==this.isBashMode&&this.updateEditorBorderColor()},this.defaultEditor.onPasteImage=()=>{this.imagePipeline.handleClipboardImagePaste()},this.defaultEditor.onAttachmentKey=e=>this.imagePipeline.handleAttachmentKeyNavigation(e)}setupEditorSubmitHandler(){this.defaultEditor.onSubmit=async e=>{await this.inputSubmit.handleSubmit(e)}}subscribeToAgent(){this.unsubscribe=this.session.subscribe(async e=>{await this.handleEvent(e)})}addSessionNavigationBanner(e){const n=this.sessionManager.getSessionName(),i=this.sessionManager.getSessionId(),o=n?` "${n}"`:"",t=r.fg("dim",`\u21AA ${e} \u2192 session${o} (${i})`);this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(t,1,1)),this.chatContainer.addChild(new u(1))}async handleEvent(e){if(te(`handleEvent: ${e.type}`),e.type==="sdk:mcp_ready"){e.toolCount>0&&this.showStatus(`MCP: ${e.toolCount} tool(s) ready`);return}await this.streamRender.handle(e)}getUserMessageText(e){return e.role!=="user"?"":(typeof e.content=="string"?[{type:"text",text:e.content}]:e.content.filter(i=>i.type==="text")).map(i=>i.text).join("")}showStatus(e){const n=this.chatContainer.children,i=n.length>0?n[n.length-1]:void 0,o=n.length>1?n[n.length-2]:void 0;if(i&&o&&i===this.state.lastStatusText&&o===this.state.lastStatusSpacer){this.state.lastStatusText.setText(r.fg("dim",e)),this.scheduleStatusDismiss(this.state.lastStatusSpacer,this.state.lastStatusText),this.ui.requestRender();return}const t=new u(1),a=new g(r.fg("dim",e),1,0);this.chatContainer.addChild(t),this.chatContainer.addChild(a),this.state.lastStatusSpacer=t,this.state.lastStatusText=a,this.scheduleStatusDismiss(t,a),this.ui.requestRender()}addMessageToChat(e,n){switch(e.role){case"bashExecution":{const i=new ce(e.command,this.ui,e.excludeFromContext);e.output&&i.appendOutput(e.output),i.setComplete(e.exitCode,e.cancelled,e.truncated?{truncated:!0}:void 0,e.fullOutputPath),this.chatContainer.addChild(i);break}case"custom":{if(e.display){const i=typeof e.details=="object"&&e.details!==null?e.details:void 0;if(i?.replace&&i.streamKey){const a=this.state.customStreamComponents.get(i.streamKey);if(a){a.updateMessage(e),this.ui.requestRender();break}}const o=this.session.extensionRunner?.getMessageRenderer(e.customType),t=new kt(e,o,this.getMarkdownThemeWithSettings());t.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(t),i?.streamKey&&this.state.customStreamComponents.set(i.streamKey,t)}break}case"compactionSummary":{this.chatContainer.addChild(new u(1));const i=new xt(e,this.getMarkdownThemeWithSettings());i.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(i);break}case"branchSummary":{this.chatContainer.addChild(new u(1));const i=new Mt(e,this.getMarkdownThemeWithSettings());i.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(i);break}case"user":{const i=this.getUserMessageText(e);if(i){const o=_e(i);if(o){this.chatContainer.addChild(new u(1));const t=new Bt(o,this.getMarkdownThemeWithSettings());if(t.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(t),o.userMessage){const a=new $e(o.userMessage,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(a)}}else{const t=new $e(i,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(t)}n?.populateHistory&&this.editor.addToHistory?.(i)}break}case"assistant":{const i=new xe(e,this.state.hideThinkingBlock,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(i);break}case"toolResult":break;default:{const i=e}}}renderSessionContext(e,n={}){this.state.pendingTools.clear(),this.state.customStreamComponents.clear(),n.updateFooter&&(this.footer.invalidate(),this.updateEditorBorderColor());for(const i of e.messages)if(i.role==="assistant"){this.addMessageToChat(i);for(const o of i.content)if(o.type==="toolCall"){const t=new ke(o.name,o.arguments,{showImages:this.settingsManager.getShowImages()},this.getRegisteredToolDefinition(o.name),this.ui);if(t.setExpanded(this.state.toolOutputExpanded),this.chatContainer.addChild(t),i.stopReason==="aborted"||i.stopReason==="error"){let a;if(i.stopReason==="aborted"){const h=this.session.retryAttempt;a=h>0?`Aborted after ${h} retry attempt${h>1?"s":""}`:"Operation aborted"}else a=i.errorMessage||"Error";t.updateResult({content:[{type:"text",text:a}],isError:!0})}else this.state.pendingTools.set(o.id,t)}}else if(i.role==="toolResult"){const o=this.state.pendingTools.get(i.toolCallId);o&&(o.updateResult(i),this.state.pendingTools.delete(i.toolCallId))}else this.addMessageToChat(i,n);this.state.pendingTools.clear(),this.ui.requestRender()}renderInitialMessages(){this.stopWelcomeBannerTimer();const e=this.sessionManager.buildSessionContext();if(this.renderSessionContext(e,{updateFooter:!0,populateHistory:!0}),e.messages.length===0){if(this.chatContainer.addChild(new u(1)),W==="catui"||W==="catui"){const o=this.session.cwd,t=this.session.model,a=t?.name??(t?.provider?`${t.provider}`:"DashScope \xB7 Ollama"),h=s(l=>{const T=l%8===5,v=l%4<2?"*":".",$=l%4>=2?"*":".",I=[` ${v} ,MMM8&&&. ${$}`," MMMM88&&&&& ."," MMMM88&&&&&&&"," * MMM88&&&&&&&&"," MMM88&&&&&&&&"," 'MMM88&&&&&&'",` 'MMM8&&&' ${$} _`," |\\___/| \\\\"," ) ( |\\_/| || '",T?` =\\ /= )- - '._.-""""-. //`:` =\\ /= )a a '._.-""""-. //`," )===( =\\T_= / ~ ~ \\//",' / \\ `"`\\ ~ / ~ /'," | | |~ \\ | ~/"," / \\ \\ ~/- \\ ~\\"," \\ / || | // /`"," _/\\_/\\_ _/_/\\_/\\_/\\_((_|\\((_//\\_/\\_/\\_"," | | | |( ( | | | | | | | | | |"," | | | | ) ) | | | | | | | | | |"," | | | |(_( | | | | | | | | | |"," | | | | | | | | | | | | | | |"," | | | | | | | | | | | | | | |"],U=Math.max(...I.map(D=>D.length));return I.map(D=>D.padEnd(U))},"buildAsciiLines"),c=s(l=>h(l).map(T=>r.fg("accent",T.slice(0,Math.max(1,this.ui.terminal.columns||80)))).join(`
21
+ `),"renderAscii"),d=r.bold(r.fg("accent",`catui-agent v${this.version}`)),m=r.fg("dim",a),f=r.fg("dim",o),b=r.fg("dim"," /model to switch model"),w=this.getAppKeyDisplay("showResources"),E=this.settingsManager.getQuietStartup()?r.fg("dim",` ${w} to show context/skills/extensions`):"",S=r.fg("borderMuted","\u2500".repeat(Math.max(40,this.ui.terminal.columns||80))),C=r.fg("accent",'\u276F Try "refactor <filepath>" or type below'),p=[c(0),"",` ${d}`,` ${m}`,` ${f}`,"",b,...E?["",E]:[],"",S,C].join(`
22
+ `),y=new g(p,0,0);this.chatContainer.addChild(y);let M=0;this.state.welcomeBannerTimer=setInterval(()=>{M+=1,y.setText([c(M),"",` ${d}`,` ${m}`,` ${f}`,"",b,...E?["",E]:[],"",S,C].join(`
23
+ `)),this.ui.requestRender(),M>=16&&this.stopWelcomeBannerTimer()},220)}else{const t=[" \u270E"," +---------------+",` | ${W.padEnd(14).slice(0,14)} |`," +---------------+"].join(`
24
24
  `),a=` ${r.fg("dim","AI coding agent. Type below to start.")}`;this.chatContainer.addChild(new g(`${r.fg("accent",t)}
25
25
  ${a}`,0,0))}this.chatContainer.addChild(new u(1))}const i=this.sessionManager.getEntries().filter(o=>o.type==="compaction").length;if(i>0){const o=i===1?"1 time":`${i} times`;this.showStatus(`Session compacted ${o}`)}this.ui.requestRender(!0)}async getUserInput(){return new Promise(e=>{this.onInputCallback=n=>{this.onInputCallback=void 0,e(n)}})}rebuildChatFromMessages(){this.clearStatusTimers(),this.chatContainer.clear();const e=this.sessionManager.buildSessionContext();this.renderSessionContext(e);for(const n of this.state.optimisticUserMessages)this.addMessageToChat({role:"user",content:[{type:"text",text:n.text}],timestamp:Date.now()});this.ui.requestRender(!0)}isShuttingDown=!1;async shutdown(){if(this.isShuttingDown)return;this.isShuttingDown=!0;const e=this.session.extensionRunner;e?.hasHandlers("session_shutdown")&&await Promise.race([e.emit({type:"session_shutdown"}),new Promise(t=>setTimeout(t,5e3))]),this.imagePipeline.cleanupClipboardImages(),await new Promise(o=>process.nextTick(o)),await this.ui.terminal.drainInput(1e3),this.stop();const n=this.sessionManager.getSessionId(),i=this.session.cwd;console.log(`
26
26
  Resume this session with: catui --session ${n} --cwd "${i}"`),process.exit(0)}async checkShutdownRequested(){this.shutdownRequested&&await this.shutdown()}suspend(){process.once("SIGCONT",()=>{this.ui.start(),this.ui.requestRender(!0)}),this.ui.stop(),process.kill(0,"SIGTSTP")}async handleFollowUp(){const e=(this.editor.getExpandedText?.()??this.editor.getText()).trim();if(e){if(this.session.isCompacting){this.isExtensionCommand(e)?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.promptAfterRender(e)):this.queueCompactionMessage(e,"followUp");return}this.session.isStreaming?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.promptAfterRender(e,{streamingBehavior:"followUp"}),this.updatePendingMessagesDisplay(),this.ui.requestRender()):this.editor.onSubmit&&this.editor.onSubmit(e)}}handleDequeue(){const e=this.restoreQueuedMessagesToEditor();e===0?this.showStatus("No queued messages to restore"):this.showStatus(`Restored ${e} queued message${e>1?"s":""} to editor`)}async promptAfterRender(e,n){const i=this.ui;typeof i.awaitRender=="function"?await i.awaitRender():await new Promise(o=>process.nextTick(o)),await this.session.prompt(e,n)}updateEditorBorderColor(){if(this.isBashMode)this.editor.borderColor=r.getBashModeBorderColor();else{const e=this.session.thinkingLevel||"off";this.editor.borderColor=r.getThinkingBorderColor(e)}this.ui.requestRender()}handleAgentLoopCommand(e){const n=e.slice(11).trim().toLowerCase(),i=["standard","weak-model-compatible"],o=n==="high-intelligence"?"standard":n==="low-intelligence"||n==="structured-adaptive"?"weak-model-compatible":n;if(!n){this.showStatus(`Agent loop: ${this.session.agentLoopFramework} (available: ${i.join(", ")})`);return}if(!i.includes(o)){this.showError(`Unknown agent loop framework: ${n}
27
- Available: ${i.join(", ")}`);return}this.session.setAgentLoopFramework(o),this.footer.invalidate(),this.showStatus(`Agent loop framework: ${this.session.agentLoopFramework}`)}toggleToolOutputExpansion(){this.setToolsExpanded(!this.state.toolOutputExpanded)}setToolsExpanded(e){this.state.toolOutputExpanded=e;for(const n of this.chatContainer.children)Yt(n)&&n.setExpanded(e);this.ui.requestRender()}toggleThinkingBlockVisibility(){this.state.hideThinkingBlock=!this.state.hideThinkingBlock,this.settingsManager.setHideThinkingBlock(this.state.hideThinkingBlock),this.chatContainer.clear(),this.rebuildChatFromMessages(),this.state.streamingComponent&&this.state.streamingMessage&&(this.state.streamingComponent.setHideThinkingBlock(this.state.hideThinkingBlock),this.state.streamingComponent.updateContent(this.state.streamingMessage),this.chatContainer.addChild(this.state.streamingComponent)),this.showStatus(`Thinking blocks: ${this.state.hideThinkingBlock?"hidden":"visible"}`)}openExternalEditor(){const e=process.env.VISUAL||process.env.EDITOR;if(!e){this.showWarning("No editor configured. Set $VISUAL or $EDITOR environment variable.");return}const n=this.editor.getExpandedText?.()??this.editor.getText(),i=D.join(J.tmpdir(),`catui-editor-${Date.now()}.catui.md`);try{P.writeFileSync(i,n,"utf-8"),this.ui.stop();const[o,...t]=e.split(" ");if(re(o,[...t,i],{stdio:"inherit"}).status===0){const h=P.readFileSync(i,"utf-8").replace(/\n$/,"");this.editor.setText(h)}}finally{try{P.unlinkSync(i)}catch{}this.ui.start(),this.ui.requestRender(!0)}}async openExistingFileInExternalEditor(e){const n=process.env.VISUAL||process.env.EDITOR;if(!n)return this.showWarning("No editor configured. Set $VISUAL or $EDITOR environment variable."),!1;try{this.ui.stop();const[i,...o]=n.split(" ");return re(i,[...o,e],{stdio:"inherit"}).status===0}finally{this.ui.start(),this.ui.requestRender(!0)}}clearEditor(){this.editor.setText(""),this.ui.requestRender()}showError(e){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("error",`Error: ${e}`),1,0)),this.setBuddyPetState("error","Oops...",{resetTo:"idle",afterMs:2200}),this.ui.requestRender()}showWarning(e){const n=new u(1),i=new g(r.fg("warning",`Warning: ${e}`),1,0);this.chatContainer.addChild(n),this.chatContainer.addChild(i),this.scheduleStatusDismiss(n,i),this.setBuddyPetState("error","Careful.",{resetTo:"idle",afterMs:1800}),this.ui.requestRender()}scheduleStatusDismiss(e,n){const i=setTimeout(()=>{this.statusTimers.delete(i),this.chatContainer.removeChild(e),this.chatContainer.removeChild(n),this.state.lastStatusText===n&&(this.state.lastStatusText=void 0,this.state.lastStatusSpacer=void 0),this.ui.requestRender()},5e3);this.statusTimers.add(i)}clearStatusTimers(){for(const e of this.statusTimers)clearTimeout(e);this.statusTimers.clear(),this.notificationQueue.clearAll()}notify(e,n){this.notificationQueue.notify(e,n)}getAllQueuedMessages(){return{steering:[...this.session.getSteeringMessages(),...this.state.compactionQueuedMessages.filter(e=>e.mode==="steer").map(e=>e.text)],followUp:[...this.session.getFollowUpMessages(),...this.state.compactionQueuedMessages.filter(e=>e.mode==="followUp").map(e=>e.text)]}}clearAllQueues(){const{steering:e,followUp:n}=this.session.clearQueue(),i=this.state.compactionQueuedMessages.filter(t=>t.mode==="steer").map(t=>t.text),o=this.state.compactionQueuedMessages.filter(t=>t.mode==="followUp").map(t=>t.text);return this.state.compactionQueuedMessages=[],{steering:[...e,...i],followUp:[...n,...o]}}updatePendingMessagesDisplay(){this.pendingMessagesContainer.clear();const{steering:e,followUp:n}=this.getAllQueuedMessages();if(e.length>0||n.length>0){this.pendingMessagesContainer.addChild(new u(1));for(const t of e){const a=r.fg("dim",`Steering: ${t}`);this.pendingMessagesContainer.addChild(new ae(a,1,0))}for(const t of n){const a=r.fg("dim",`Follow-up: ${t}`);this.pendingMessagesContainer.addChild(new ae(a,1,0))}const i=this.getAppKeyDisplay("dequeue"),o=r.fg("dim",`\u21B3 ${i} to edit all queued messages`);this.pendingMessagesContainer.addChild(new ae(o,1,0))}}restoreQueuedMessagesToEditor(e){const{steering:n,followUp:i}=this.clearAllQueues(),o=[...n,...i];if(o.length===0)return this.updatePendingMessagesDisplay(),e?.abort&&this.agent.abort(),0;const t=o.join(`
27
+ Available: ${i.join(", ")}`);return}this.session.setAgentLoopFramework(o),this.footer.invalidate(),this.showStatus(`Agent loop framework: ${this.session.agentLoopFramework}`)}toggleToolOutputExpansion(){this.setToolsExpanded(!this.state.toolOutputExpanded)}setToolsExpanded(e){this.state.toolOutputExpanded=e;for(const n of this.chatContainer.children)Yt(n)&&n.setExpanded(e);this.ui.requestRender()}toggleThinkingBlockVisibility(){this.state.hideThinkingBlock=!this.state.hideThinkingBlock,this.settingsManager.setHideThinkingBlock(this.state.hideThinkingBlock),this.chatContainer.clear(),this.rebuildChatFromMessages(),this.state.streamingComponent&&this.state.streamingMessage&&(this.state.streamingComponent.setHideThinkingBlock(this.state.hideThinkingBlock),this.state.streamingComponent.updateContent(this.state.streamingMessage),this.chatContainer.addChild(this.state.streamingComponent)),this.showStatus(`Thinking blocks: ${this.state.hideThinkingBlock?"hidden":"visible"}`)}openExternalEditor(){const e=process.env.VISUAL||process.env.EDITOR;if(!e){this.showWarning("No editor configured. Set $VISUAL or $EDITOR environment variable.");return}const n=this.editor.getExpandedText?.()??this.editor.getText(),i=L.join(Y.tmpdir(),`catui-editor-${Date.now()}.catui.md`);try{P.writeFileSync(i,n,"utf-8"),this.ui.stop();const[o,...t]=e.split(" ");if(re(o,[...t,i],{stdio:"inherit"}).status===0){const h=P.readFileSync(i,"utf-8").replace(/\n$/,"");this.editor.setText(h)}}finally{try{P.unlinkSync(i)}catch{}this.ui.start(),this.ui.requestRender(!0)}}async openExistingFileInExternalEditor(e){const n=process.env.VISUAL||process.env.EDITOR;if(!n)return this.showWarning("No editor configured. Set $VISUAL or $EDITOR environment variable."),!1;try{this.ui.stop();const[i,...o]=n.split(" ");return re(i,[...o,e],{stdio:"inherit"}).status===0}finally{this.ui.start(),this.ui.requestRender(!0)}}clearEditor(){this.editor.setText(""),this.ui.requestRender()}showError(e){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("error",`Error: ${e}`),1,0)),this.setBuddyPetState("error","Oops...",{resetTo:"idle",afterMs:2200}),this.ui.requestRender()}showWarning(e){const n=new u(1),i=new g(r.fg("warning",`Warning: ${e}`),1,0);this.chatContainer.addChild(n),this.chatContainer.addChild(i),this.scheduleStatusDismiss(n,i),this.setBuddyPetState("error","Careful.",{resetTo:"idle",afterMs:1800}),this.ui.requestRender()}scheduleStatusDismiss(e,n){const i=setTimeout(()=>{this.statusTimers.delete(i),this.chatContainer.removeChild(e),this.chatContainer.removeChild(n),this.state.lastStatusText===n&&(this.state.lastStatusText=void 0,this.state.lastStatusSpacer=void 0),this.ui.requestRender()},5e3);this.statusTimers.add(i)}clearStatusTimers(){for(const e of this.statusTimers)clearTimeout(e);this.statusTimers.clear(),this.notificationQueue.clearAll()}notify(e,n){this.notificationQueue.notify(e,n)}getAllQueuedMessages(){return{steering:[...this.session.getSteeringMessages(),...this.state.compactionQueuedMessages.filter(e=>e.mode==="steer").map(e=>e.text)],followUp:[...this.session.getFollowUpMessages(),...this.state.compactionQueuedMessages.filter(e=>e.mode==="followUp").map(e=>e.text)]}}clearAllQueues(){const{steering:e,followUp:n}=this.session.clearQueue(),i=this.state.compactionQueuedMessages.filter(t=>t.mode==="steer").map(t=>t.text),o=this.state.compactionQueuedMessages.filter(t=>t.mode==="followUp").map(t=>t.text);return this.state.compactionQueuedMessages=[],{steering:[...e,...i],followUp:[...n,...o]}}updatePendingMessagesDisplay(){this.pendingMessagesContainer.clear();const{steering:e,followUp:n}=this.getAllQueuedMessages();if(e.length>0||n.length>0){this.pendingMessagesContainer.addChild(new u(1));for(const t of e){const a=r.fg("dim",`Steering: ${t}`);this.pendingMessagesContainer.addChild(new ae(a,1,0))}for(const t of n){const a=r.fg("dim",`Follow-up: ${t}`);this.pendingMessagesContainer.addChild(new ae(a,1,0))}const i=this.getAppKeyDisplay("dequeue"),o=r.fg("dim",`\u21B3 ${i} to edit all queued messages`);this.pendingMessagesContainer.addChild(new ae(o,1,0))}}restoreQueuedMessagesToEditor(e){const{steering:n,followUp:i}=this.clearAllQueues(),o=[...n,...i];if(o.length===0)return this.updatePendingMessagesDisplay(),e?.abort&&this.agent.abort(),0;const t=o.join(`
28
28
 
29
29
  `),a=e?.currentText??this.editor.getText(),h=[t,a].filter(c=>c.trim()).join(`
30
30
 
31
31
  `);return this.editor.setText(h),this.updatePendingMessagesDisplay(),e?.abort&&this.agent.abort(),o.length}queueCompactionMessage(e,n){this.state.compactionQueuedMessages.push({text:e,mode:n}),this.editor.addToHistory?.(e),this.editor.setText(""),this.updatePendingMessagesDisplay(),this.showStatus("Queued message for after compaction")}isExtensionCommand(e){if(!e.startsWith("/"))return!1;const n=this.session.extensionRunner;if(!n)return!1;const i=e.indexOf(" "),o=i===-1?e.slice(1):e.slice(1,i);return!!n.getCommand(o)}async flushCompactionQueue(e){if(this.state.compactionQueuedMessages.length===0)return;const n=[...this.state.compactionQueuedMessages];this.state.compactionQueuedMessages=[],this.updatePendingMessagesDisplay();const i=s(o=>{this.session.clearQueue(),this.state.compactionQueuedMessages=n,this.updatePendingMessagesDisplay(),this.showError(`Failed to send queued message${n.length>1?"s":""}: ${o instanceof Error?o.message:String(o)}`)},"restoreQueue");try{if(e?.willRetry){for(const d of n)this.isExtensionCommand(d.text)?await this.promptAfterRender(d.text):d.mode==="followUp"?await this.session.followUp(d.text):await this.session.steer(d.text);this.updatePendingMessagesDisplay();return}const o=n.findIndex(d=>!this.isExtensionCommand(d.text));if(o===-1){for(const d of n)await this.promptAfterRender(d.text);return}const t=n.slice(0,o),a=n[o],h=n.slice(o+1);for(const d of t)await this.promptAfterRender(d.text);const c=this.promptAfterRender(a.text).catch(d=>{i(d)});for(const d of h)this.isExtensionCommand(d.text)?await this.promptAfterRender(d.text):d.mode==="followUp"?await this.session.followUp(d.text):await this.session.steer(d.text);this.updatePendingMessagesDisplay()}catch(o){i(o)}}flushPendingBashComponents(){for(const e of this.pendingBashComponents)this.pendingMessagesContainer.removeChild(e),this.chatContainer.addChild(e);this.pendingBashComponents=[]}showSelector(e){const n=s(()=>{this.remountEditorShell(),this.ui.setFocus(this.editor)},"done"),{component:i,focus:o}=e(n);this.editorContainer.clear(),this.editorContainer.addChild(i),this.ui.setFocus(o),this.ui.requestRender()}async handleReloadCommand(){if(this.session.isStreaming){this.showWarning("Wait for the current response to finish before reloading.");return}if(this.session.isCompacting){this.showWarning("Wait for compaction to finish before reloading.");return}this.resetExtensionUI();const e=new Pe(this.ui,r,"Reloading extensions, skills, prompts, themes...",{cancellable:!1}),n=this.editor;this.editorContainer.clear(),this.editorContainer.addChild(e),this.ui.setFocus(e),this.ui.requestRender();const i=s(o=>{e.dispose(),this.remountEditorShell(),this.ui.setFocus(this.editor),this.ui.requestRender()},"dismissLoader");try{await this.session.reload(),ue(this.session.resourceLoader.getThemes().themes),this.state.hideThinkingBlock=this.settingsManager.getHideThinkingBlock();const o=this.settingsManager.getTheme(),t=o?Ae(o,!0):{success:!0};t.success||this.showError(`Failed to load theme "${o}": ${t.error}
32
- Fell back to dark theme.`);const a=this.settingsManager.getEditorPaddingX(),h=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(a),this.defaultEditor.setAutocompleteMaxVisible(h),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(a),this.editor.setAutocompleteMaxVisible?.(h)),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.setupAutocomplete(this.fdPath);const c=this.session.extensionRunner;c&&this.setupExtensionShortcuts(c),this.rebuildChatFromMessages(),i(this.editor),this.showLoadedResources({extensionPaths:c?.getExtensionPaths()??[],force:!1,showDiagnosticsWhenQuiet:!0});const d=this.session.modelRegistry.getError();d&&this.showError(`models.json error: ${d}`),this.showStatus("Reloaded extensions, skills, prompts, themes")}catch(o){i(n),this.showError(`Reload failed: ${o instanceof Error?o.message:String(o)}`)}}async handleExportCommand(e){const n=e.split(/\s+/),i=n.length>1?n[1]:void 0;try{const o=await this.session.exportToHtml(i);this.showStatus(`Session exported to: ${o}`)}catch(o){this.showError(`Failed to export session: ${o instanceof Error?o.message:"Unknown error"}`)}}async handleShareCommand(){try{if(re("gh",["auth","status"],{encoding:"utf-8"}).status!==0){this.showError("GitHub CLI is not logged in. Run 'gh auth login' first.");return}}catch{this.showError("GitHub CLI (gh) is not installed. Install it from https://cli.github.com/");return}const e=D.join(J.tmpdir(),"session.html");try{await this.session.exportToHtml(e)}catch(t){this.showError(`Failed to export session: ${t instanceof Error?t.message:"Unknown error"}`);return}const n=new Pe(this.ui,r,"Creating gist...");this.editorContainer.clear(),this.editorContainer.addChild(n),this.ui.setFocus(n),this.ui.requestRender();const i=s(()=>{n.dispose(),this.remountEditorShell(),this.ui.setFocus(this.editor);try{P.unlinkSync(e)}catch{}},"restoreEditor");let o=null;n.onAbort=()=>{o?.kill(),i(),this.showStatus("Share cancelled")};try{const t=await new Promise(d=>{o=Fe("gh",["gist","create","--public=false",e]);let m="",f="";o.stdout?.on("data",M=>{m+=M.toString()}),o.stderr?.on("data",M=>{f+=M.toString()}),o.on("close",M=>d({stdout:m,stderr:f,code:M}))});if(n.signal.aborted)return;if(i(),t.code!==0){const d=t.stderr?.trim()||"Unknown error";this.showError(`Failed to create gist: ${d}`);return}const a=t.stdout?.trim(),h=a?.split("/").pop();if(!h){this.showError("Failed to parse gist ID from gh output");return}const c=Ne(h);this.showStatus(`Share URL: ${c}
33
- Gist: ${a}`)}catch(t){n.signal.aborted||(i(),this.showError(`Failed to create gist: ${t instanceof Error?t.message:"Unknown error"}`))}}handleCopyCommand(){const e=this.session.getLastAssistantText();if(!e){this.showError("No agent messages to copy yet.");return}try{tt(e),this.showStatus("Copied last agent message to clipboard")}catch(n){this.showError(n instanceof Error?n.message:String(n))}}async handleStatusCommand(){const e=this.session.state,n=this.sessionManager,i=s((x,F)=>{const ge=F-2,Ie=pe(x),De=Math.max(0,ge-Ie);return x+" ".repeat(De)},"padLine"),o=[],t=Math.min(this.ui.terminal.columns||80,73),a=` >_ Catui (v${this.version}) `,h=Math.max(0,t-a.length-1);o.push(r.fg("border",`\u256D${"\u2500".repeat(Math.max(1,t-2))}\u256E`)),o.push(r.fg("border","\u2502")+r.bold(a)+" ".repeat(h)+r.fg("border","\u2502")),o.push(r.fg("border","\u2502")+" ".repeat(Math.max(1,t-2))+r.fg("border","\u2502"));const c=e.model?.id||"no-model",d=e.thinkingLevel||"off",m=e.model?.reasoning?`reasoning ${d}`:"",f=` Model: ${c}${m?` (${m})`:""}`;o.push(r.fg("border","\u2502")+i(f,t)+r.fg("border","\u2502"));const M=` Agent loop: ${this.session.agentLoopFramework}`;o.push(r.fg("border","\u2502")+i(M,t)+r.fg("border","\u2502"));for(const x of Jt(e.lastResult))o.push(r.fg("border","\u2502")+i(` ${x}`,t)+r.fg("border","\u2502"));let w=this.session.cwd;const E=process.env.HOME||process.env.USERPROFILE;E&&w.startsWith(E)&&(w=`~${w.slice(E.length)}`);const S=this.footerDataProvider.getGitBranch(),C=` Directory: ${w}${S?` (${S})`:""}`;o.push(r.fg("border","\u2502")+i(C,t)+r.fg("border","\u2502"));const p=D.join(this.session.cwd,"AGENTS.md"),b=` AGENTS.md: ${P.existsSync(p)?"AGENTS.md":"not found"}`;o.push(r.fg("border","\u2502")+i(b,t)+r.fg("border","\u2502"));const l=n.getSessionId(),$=` Session: ${n.getSessionName()||l.slice(0,8)}...`;o.push(r.fg("border","\u2502")+i($,t)+r.fg("border","\u2502"));const A=this.session.modelRegistry.authStorage,R=A.list();let K="Not logged in";R.length>0&&(K=R.map(F=>A.get(F)?.type==="oauth"?`${F} (OAuth)`:`${F} (API key)`).join(", "));const te=` Account: ${K}`;o.push(r.fg("border","\u2502")+i(te,t)+r.fg("border","\u2502")),o.push(r.fg("border","\u2502")+" ".repeat(Math.max(1,t-2))+r.fg("border","\u2502"));let _=0,j=0,Q=0,G=0;for(const x of n.getBranch())x.type==="message"&&x.message.role==="assistant"&&(_+=x.message.usage.input,j+=x.message.usage.output,Q+=x.message.usage.cost.total,G++);const B=s(x=>x.toLocaleString(),"fmt"),se=s(x=>`$${x.toFixed(4)}`,"fmtCost");o.push(r.fg("border","\u2502")+r.bold(r.fg("accent"," \u2550\u2550\u2550 Session Usage \u2550\u2550\u2550"))+" ".repeat(Math.max(1,t-23))+r.fg("border","\u2502")),o.push(r.fg("border","\u2502")+" ".repeat(Math.max(1,t-2))+r.fg("border","\u2502"));const W=` Requests: ${G}`;o.push(r.fg("border","\u2502")+i(W,t)+r.fg("border","\u2502"));const V=` Input tokens: ${B(_)}`;o.push(r.fg("border","\u2502")+i(V,t)+r.fg("border","\u2502"));const z=` Output tokens: ${B(j)}`;o.push(r.fg("border","\u2502")+i(z,t)+r.fg("border","\u2502"));const ie=` Cost: ${se(Q)}`;o.push(r.fg("border","\u2502")+i(ie,t)+r.fg("border","\u2502"));const U=this.session.getContextUsage(),ne=U?.contextWindow??e.model?.contextWindow??0,X=U?.percent??0,oe=U?.tokens??0,ve=` Context: ${Rt(X)} ${X.toFixed(1)}% (${B(oe)}/${B(ne)})`;o.push(r.fg("border","\u2502")+i(ve,t)+r.fg("border","\u2502")),o.push(r.fg("border",`\u2570${"\u2500".repeat(Math.max(1,t-2))}\u256F`)),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new Ut(o.join(`
34
- `))),this.ui.requestRender()}async handleUsageCommand(){const e=new Map;let n=0,i=0,o=0,t=0,a=0,h=0,c=0;for(const C of this.sessionManager.getBranch())if(C.type==="message"&&C.message.role==="assistant"){const p=C.message,y=p.model||"unknown",b=p.usage.totalTokens||p.usage.input+p.usage.output+p.usage.cacheRead+p.usage.cacheWrite;e.has(y)||e.set(y,{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:0,requestCount:0});const l=e.get(y);l.input+=p.usage.input,l.output+=p.usage.output,l.cacheRead+=p.usage.cacheRead,l.cacheWrite+=p.usage.cacheWrite,l.totalTokens+=b,l.cost+=p.usage.cost.total,l.requestCount++,n+=p.usage.input,i+=p.usage.output,o+=p.usage.cacheRead,t+=p.usage.cacheWrite,h+=b,a+=p.usage.cost.total,c++}const d=this.session.getContextUsage(),m=d?.contextWindow??0,f=s(C=>C.toLocaleString(),"fmt"),M=s(C=>`$${C.toFixed(4)}`,"fmtCost"),w=[];if(w.push(r.bold(r.fg("accent","\u2550\u2550\u2550 Token Usage \u2550\u2550\u2550"))),w.push(""),e.size>0)for(const[C,p]of e)w.push(r.fg("accent",`\u250C\u2500 ${C} \u2500`)),w.push(""),w.push(`\u2502 Requests: ${p.requestCount}`),w.push(`\u2502 Input: ${f(p.input)} tokens`),w.push(`\u2502 Output: ${f(p.output)} tokens`),w.push(`\u2502 Cache: ${f(p.cacheRead+p.cacheWrite)} tokens`),w.push(`\u2502 Total: ${f(p.totalTokens)} tokens`),w.push(`\u2502 Cost: ${M(p.cost)}`),w.push(r.fg("accent",`\u2514${"\u2500".repeat(Math.min(50,C.length+4))}`)),w.push("");w.push(r.bold(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Total \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),w.push(` Requests: ${c}`),w.push(` Input: ${f(n)} tokens`),w.push(` Output: ${f(i)} tokens`),w.push(` Cache: ${f(o+t)} tokens`),w.push(` Total: ${f(h)} tokens`),w.push(` Cost: ${M(a)}`),w.push("");const E=d?.percent!=null?`${d.percent.toFixed(1)}%`:"?";w.push(` Context: ${E} / ${f(m)} tokens`);const S=this.session.state;S.model&&w.push(` Current: ${S.model.id}`),w.push(""),w.push(r.fg("dim"," Tip: Use /settings \u2192 Terminal \u2192 Show token stats to toggle footer display"));for(const C of w)this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(C,1,0))}handleNameCommand(e){const n=e.replace(/^\/name\s*/,"").trim();if(!n){const i=this.sessionManager.getSessionName();i?(this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("dim",`Session name: ${i}`),1,0))):this.showWarning("Usage: /name <name>"),this.ui.requestRender();return}this.sessionManager.appendSessionInfo(n),this.updateTerminalTitle(),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("dim",`Session name set: ${n}`),1,0)),this.ui.requestRender()}handleSessionCommand(){const e=this.session.getSessionStats(),n=this.sessionManager.getSessionName();let i=`${r.bold("Session Info")}
32
+ Fell back to dark theme.`);const a=this.settingsManager.getEditorPaddingX(),h=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(a),this.defaultEditor.setAutocompleteMaxVisible(h),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(a),this.editor.setAutocompleteMaxVisible?.(h)),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.setupAutocomplete(this.fdPath);const c=this.session.extensionRunner;c&&this.setupExtensionShortcuts(c),this.rebuildChatFromMessages(),i(this.editor),this.showLoadedResources({extensionPaths:c?.getExtensionPaths()??[],force:!1,showDiagnosticsWhenQuiet:!0});const d=this.session.modelRegistry.getError();d&&this.showError(`models.json error: ${d}`),this.showStatus("Reloaded extensions, skills, prompts, themes")}catch(o){i(n),this.showError(`Reload failed: ${o instanceof Error?o.message:String(o)}`)}}async handleExportCommand(e){const n=e.split(/\s+/),i=n.length>1?n[1]:void 0;try{const o=await this.session.exportToHtml(i);this.showStatus(`Session exported to: ${o}`)}catch(o){this.showError(`Failed to export session: ${o instanceof Error?o.message:"Unknown error"}`)}}async handleShareCommand(){try{if(re("gh",["auth","status"],{encoding:"utf-8"}).status!==0){this.showError("GitHub CLI is not logged in. Run 'gh auth login' first.");return}}catch{this.showError("GitHub CLI (gh) is not installed. Install it from https://cli.github.com/");return}const e=L.join(Y.tmpdir(),"session.html");try{await this.session.exportToHtml(e)}catch(t){this.showError(`Failed to export session: ${t instanceof Error?t.message:"Unknown error"}`);return}const n=new Pe(this.ui,r,"Creating gist...");this.editorContainer.clear(),this.editorContainer.addChild(n),this.ui.setFocus(n),this.ui.requestRender();const i=s(()=>{n.dispose(),this.remountEditorShell(),this.ui.setFocus(this.editor);try{P.unlinkSync(e)}catch{}},"restoreEditor");let o=null;n.onAbort=()=>{o?.kill(),i(),this.showStatus("Share cancelled")};try{const t=await new Promise(d=>{o=Fe("gh",["gist","create","--public=false",e]);let m="",f="";o.stdout?.on("data",b=>{m+=b.toString()}),o.stderr?.on("data",b=>{f+=b.toString()}),o.on("close",b=>d({stdout:m,stderr:f,code:b}))});if(n.signal.aborted)return;if(i(),t.code!==0){const d=t.stderr?.trim()||"Unknown error";this.showError(`Failed to create gist: ${d}`);return}const a=t.stdout?.trim(),h=a?.split("/").pop();if(!h){this.showError("Failed to parse gist ID from gh output");return}const c=Ne(h);this.showStatus(`Share URL: ${c}
33
+ Gist: ${a}`)}catch(t){n.signal.aborted||(i(),this.showError(`Failed to create gist: ${t instanceof Error?t.message:"Unknown error"}`))}}handleCopyCommand(){const e=this.session.getLastAssistantText();if(!e){this.showError("No agent messages to copy yet.");return}try{tt(e),this.showStatus("Copied last agent message to clipboard")}catch(n){this.showError(n instanceof Error?n.message:String(n))}}async handleStatusCommand(){const e=this.session.state,n=this.sessionManager,i=s((x,N)=>{const ge=N-2,Ie=pe(x),De=Math.max(0,ge-Ie);return x+" ".repeat(De)},"padLine"),o=[],t=Math.min(this.ui.terminal.columns||80,73),a=` >_ Catui (v${this.version}) `,h=Math.max(0,t-a.length-1);o.push(r.fg("border",`\u256D${"\u2500".repeat(Math.max(1,t-2))}\u256E`)),o.push(r.fg("border","\u2502")+r.bold(a)+" ".repeat(h)+r.fg("border","\u2502")),o.push(r.fg("border","\u2502")+" ".repeat(Math.max(1,t-2))+r.fg("border","\u2502"));const c=e.model?.id||"no-model",d=e.thinkingLevel||"off",m=e.model?.reasoning?`reasoning ${d}`:"",f=` Model: ${c}${m?` (${m})`:""}`;o.push(r.fg("border","\u2502")+i(f,t)+r.fg("border","\u2502"));const b=` Agent loop: ${this.session.agentLoopFramework}`;o.push(r.fg("border","\u2502")+i(b,t)+r.fg("border","\u2502"));for(const x of Jt(e.lastResult))o.push(r.fg("border","\u2502")+i(` ${x}`,t)+r.fg("border","\u2502"));let w=this.session.cwd;const E=process.env.HOME||process.env.USERPROFILE;E&&w.startsWith(E)&&(w=`~${w.slice(E.length)}`);const S=this.footerDataProvider.getGitBranch(),C=` Directory: ${w}${S?` (${S})`:""}`;o.push(r.fg("border","\u2502")+i(C,t)+r.fg("border","\u2502"));const p=L.join(this.session.cwd,"AGENTS.md"),M=` AGENTS.md: ${P.existsSync(p)?"AGENTS.md":"not found"}`;o.push(r.fg("border","\u2502")+i(M,t)+r.fg("border","\u2502"));const l=n.getSessionId(),v=` Session: ${n.getSessionName()||l.slice(0,8)}...`;o.push(r.fg("border","\u2502")+i(v,t)+r.fg("border","\u2502"));const $=this.session.modelRegistry.authStorage,I=$.list();let U="Not logged in";I.length>0&&(U=I.map(N=>$.get(N)?.type==="oauth"?`${N} (OAuth)`:`${N} (API key)`).join(", "));const D=` Account: ${U}`;o.push(r.fg("border","\u2502")+i(D,t)+r.fg("border","\u2502")),o.push(r.fg("border","\u2502")+" ".repeat(Math.max(1,t-2))+r.fg("border","\u2502"));let j=0,Q=0,G=0,V=0;for(const x of n.getBranch())x.type==="message"&&x.message.role==="assistant"&&(j+=x.message.usage.input,Q+=x.message.usage.output,G+=x.message.usage.cost.total,V++);const O=s(x=>x.toLocaleString(),"fmt"),se=s(x=>`$${x.toFixed(4)}`,"fmtCost");o.push(r.fg("border","\u2502")+r.bold(r.fg("accent"," \u2550\u2550\u2550 Session Usage \u2550\u2550\u2550"))+" ".repeat(Math.max(1,t-23))+r.fg("border","\u2502")),o.push(r.fg("border","\u2502")+" ".repeat(Math.max(1,t-2))+r.fg("border","\u2502"));const H=` Requests: ${V}`;o.push(r.fg("border","\u2502")+i(H,t)+r.fg("border","\u2502"));const z=` Input tokens: ${O(j)}`;o.push(r.fg("border","\u2502")+i(z,t)+r.fg("border","\u2502"));const X=` Output tokens: ${O(Q)}`;o.push(r.fg("border","\u2502")+i(X,t)+r.fg("border","\u2502"));const ie=` Cost: ${se(G)}`;o.push(r.fg("border","\u2502")+i(ie,t)+r.fg("border","\u2502"));const q=this.session.getContextUsage(),ne=q?.contextWindow??e.model?.contextWindow??0,J=q?.percent??0,oe=q?.tokens??0,ve=` Context: ${Rt(J)} ${J.toFixed(1)}% (${O(oe)}/${O(ne)})`;o.push(r.fg("border","\u2502")+i(ve,t)+r.fg("border","\u2502")),o.push(r.fg("border",`\u2570${"\u2500".repeat(Math.max(1,t-2))}\u256F`)),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new Ut(o.join(`
34
+ `))),this.ui.requestRender()}async handleUsageCommand(){const e=new Map;let n=0,i=0,o=0,t=0,a=0,h=0,c=0;for(const C of this.sessionManager.getBranch())if(C.type==="message"&&C.message.role==="assistant"){const p=C.message,y=p.model||"unknown",M=p.usage.totalTokens||p.usage.input+p.usage.output+p.usage.cacheRead+p.usage.cacheWrite;e.has(y)||e.set(y,{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:0,requestCount:0});const l=e.get(y);l.input+=p.usage.input,l.output+=p.usage.output,l.cacheRead+=p.usage.cacheRead,l.cacheWrite+=p.usage.cacheWrite,l.totalTokens+=M,l.cost+=p.usage.cost.total,l.requestCount++,n+=p.usage.input,i+=p.usage.output,o+=p.usage.cacheRead,t+=p.usage.cacheWrite,h+=M,a+=p.usage.cost.total,c++}const d=this.session.getContextUsage(),m=d?.contextWindow??0,f=s(C=>C.toLocaleString(),"fmt"),b=s(C=>`$${C.toFixed(4)}`,"fmtCost"),w=[];if(w.push(r.bold(r.fg("accent","\u2550\u2550\u2550 Token Usage \u2550\u2550\u2550"))),w.push(""),e.size>0)for(const[C,p]of e)w.push(r.fg("accent",`\u250C\u2500 ${C} \u2500`)),w.push(""),w.push(`\u2502 Requests: ${p.requestCount}`),w.push(`\u2502 Input: ${f(p.input)} tokens`),w.push(`\u2502 Output: ${f(p.output)} tokens`),w.push(`\u2502 Cache: ${f(p.cacheRead+p.cacheWrite)} tokens`),w.push(`\u2502 Total: ${f(p.totalTokens)} tokens`),w.push(`\u2502 Cost: ${b(p.cost)}`),w.push(r.fg("accent",`\u2514${"\u2500".repeat(Math.min(50,C.length+4))}`)),w.push("");w.push(r.bold(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Total \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),w.push(` Requests: ${c}`),w.push(` Input: ${f(n)} tokens`),w.push(` Output: ${f(i)} tokens`),w.push(` Cache: ${f(o+t)} tokens`),w.push(` Total: ${f(h)} tokens`),w.push(` Cost: ${b(a)}`),w.push("");const E=d?.percent!=null?`${d.percent.toFixed(1)}%`:"?";w.push(` Context: ${E} / ${f(m)} tokens`);const S=this.session.state;S.model&&w.push(` Current: ${S.model.id}`),w.push(""),w.push(r.fg("dim"," Tip: Use /settings \u2192 Terminal \u2192 Show token stats to toggle footer display"));for(const C of w)this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(C,1,0))}handleNameCommand(e){const n=e.replace(/^\/name\s*/,"").trim();if(!n){const i=this.sessionManager.getSessionName();i?(this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("dim",`Session name: ${i}`),1,0))):this.showWarning("Usage: /name <name>"),this.ui.requestRender();return}this.sessionManager.appendSessionInfo(n),this.updateTerminalTitle(),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("dim",`Session name set: ${n}`),1,0)),this.ui.requestRender()}handleSessionCommand(){const e=this.session.getSessionStats(),n=this.sessionManager.getSessionName();let i=`${r.bold("Session Info")}
35
35
 
36
36
  `;n&&(i+=`${r.fg("dim","Name:")} ${n}
37
37
  `),i+=`${r.fg("dim","File:")} ${e.sessionFile??"In-memory"}
@@ -54,7 +54,7 @@ Gist: ${a}`)}catch(t){n.signal.aborted||(i(),this.showError(`Failed to create gi
54
54
  ${r.bold("Cost")}
55
55
  `,i+=`${r.fg("dim","Total:")} ${e.cost.toFixed(4)}`),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(i,1,0)),this.ui.requestRender()}handleChangelogCommand(){const e=Ze(),n=et(e),i=n.length>0?n.reverse().map(o=>o.content).join(`
56
56
 
57
- `):"No changelog entries found.";this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new Z),this.chatContainer.addChild(new g(r.bold(r.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new me(i,1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new Z),this.ui.requestRender()}capitalizeKey(e){return e.split("/").map(n=>n.split("+").map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join("+")).join("/")}getAppKeyDisplay(e){return this.capitalizeKey(L(this.keybindings,e))}getEditorKeyDisplay(e){return this.capitalizeKey(It(e))}handleHotkeysCommand(){const e=this.getEditorKeyDisplay("cursorWordLeft"),n=this.getEditorKeyDisplay("cursorWordRight"),i=this.getEditorKeyDisplay("cursorLineStart"),o=this.getEditorKeyDisplay("cursorLineEnd"),t=this.getEditorKeyDisplay("jumpForward"),a=this.getEditorKeyDisplay("jumpBackward"),h=this.getEditorKeyDisplay("pageUp"),c=this.getEditorKeyDisplay("pageDown"),d=this.getEditorKeyDisplay("submit"),m=this.getEditorKeyDisplay("newLine"),f=this.getEditorKeyDisplay("deleteWordBackward"),M=this.getEditorKeyDisplay("deleteWordForward"),w=this.getEditorKeyDisplay("deleteToLineStart"),E=this.getEditorKeyDisplay("deleteToLineEnd"),S=this.getEditorKeyDisplay("yank"),C=this.getEditorKeyDisplay("yankPop"),p=this.getEditorKeyDisplay("undo"),y=this.getEditorKeyDisplay("tab"),b=this.getAppKeyDisplay("interrupt"),l=this.getAppKeyDisplay("showResources"),T=this.getAppKeyDisplay("clear"),$=this.getAppKeyDisplay("exit"),A=this.getAppKeyDisplay("suspend"),R=this.getAppKeyDisplay("cycleThinkingLevel"),K=this.getAppKeyDisplay("cycleModelForward"),te=this.getAppKeyDisplay("selectModel"),_=this.getAppKeyDisplay("selectProviderThenModel"),j=this.getAppKeyDisplay("expandTools"),Q=this.getAppKeyDisplay("toggleThinking"),G=this.getAppKeyDisplay("externalEditor"),B=this.getAppKeyDisplay("followUp"),se=this.getAppKeyDisplay("dequeue");let W=`
57
+ `):"No changelog entries found.";this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new ee),this.chatContainer.addChild(new g(r.bold(r.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new me(i,1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new ee),this.ui.requestRender()}capitalizeKey(e){return e.split("/").map(n=>n.split("+").map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join("+")).join("/")}getAppKeyDisplay(e){return this.capitalizeKey(B(this.keybindings,e))}getEditorKeyDisplay(e){return this.capitalizeKey(It(e))}handleHotkeysCommand(){const e=this.getEditorKeyDisplay("cursorWordLeft"),n=this.getEditorKeyDisplay("cursorWordRight"),i=this.getEditorKeyDisplay("cursorLineStart"),o=this.getEditorKeyDisplay("cursorLineEnd"),t=this.getEditorKeyDisplay("jumpForward"),a=this.getEditorKeyDisplay("jumpBackward"),h=this.getEditorKeyDisplay("pageUp"),c=this.getEditorKeyDisplay("pageDown"),d=this.getEditorKeyDisplay("submit"),m=this.getEditorKeyDisplay("newLine"),f=this.getEditorKeyDisplay("deleteWordBackward"),b=this.getEditorKeyDisplay("deleteWordForward"),w=this.getEditorKeyDisplay("deleteToLineStart"),E=this.getEditorKeyDisplay("deleteToLineEnd"),S=this.getEditorKeyDisplay("yank"),C=this.getEditorKeyDisplay("yankPop"),p=this.getEditorKeyDisplay("undo"),y=this.getEditorKeyDisplay("tab"),M=this.getAppKeyDisplay("interrupt"),l=this.getAppKeyDisplay("showResources"),T=this.getAppKeyDisplay("clear"),v=this.getAppKeyDisplay("exit"),$=this.getAppKeyDisplay("suspend"),I=this.getAppKeyDisplay("cycleThinkingLevel"),U=this.getAppKeyDisplay("cycleModelForward"),D=this.getAppKeyDisplay("selectModel"),j=this.getAppKeyDisplay("selectProviderThenModel"),Q=this.getAppKeyDisplay("expandTools"),G=this.getAppKeyDisplay("toggleThinking"),V=this.getAppKeyDisplay("externalEditor"),O=this.getAppKeyDisplay("followUp"),se=this.getAppKeyDisplay("dequeue");let H=`
58
58
  **Navigation**
59
59
  | Key | Action |
60
60
  |-----|--------|
@@ -72,7 +72,7 @@ ${r.bold("Cost")}
72
72
  | \`${d}\` | Send message |
73
73
  | \`${m}\` | New line${process.platform==="win32"?" (Ctrl+Enter on Windows Terminal)":""} |
74
74
  | \`${f}\` | Delete word backwards |
75
- | \`${M}\` | Delete word forwards |
75
+ | \`${b}\` | Delete word forwards |
76
76
  | \`${w}\` | Delete to start of line |
77
77
  | \`${E}\` | Delete to end of line |
78
78
  | \`${S}\` | Paste the most-recently-deleted text |
@@ -83,35 +83,35 @@ ${r.bold("Cost")}
83
83
  | Key | Action |
84
84
  |-----|--------|
85
85
  | \`${y}\` | Path completion / accept autocomplete |
86
- | \`${b}\` | Cancel autocomplete / abort streaming |
86
+ | \`${M}\` | Cancel autocomplete / abort streaming |
87
87
  | \`${l}\` | Show context/skills/extensions |
88
88
  | \`${T}\` | Clear editor (first) / exit (second) |
89
- | \`${$}\` | Exit (when editor is empty) |
90
- | \`${A}\` | Suspend to background |
91
- | \`${R}\` | Cycle thinking level |
92
- | \`${K}\` | Cycle models |
93
- | \`${te}\` | Open model selector |
94
- | \`${_}\` | Select provider then model |
95
- | \`${j}\` | Toggle tool output expansion |
96
- | \`${Q}\` | Toggle thinking block visibility |
97
- | \`${G}\` | Edit message in external editor |
98
- | \`${B}\` | Queue follow-up message |
89
+ | \`${v}\` | Exit (when editor is empty) |
90
+ | \`${$}\` | Suspend to background |
91
+ | \`${I}\` | Cycle thinking level |
92
+ | \`${U}\` | Cycle models |
93
+ | \`${D}\` | Open model selector |
94
+ | \`${j}\` | Select provider then model |
95
+ | \`${Q}\` | Toggle tool output expansion |
96
+ | \`${G}\` | Toggle thinking block visibility |
97
+ | \`${V}\` | Edit message in external editor |
98
+ | \`${O}\` | Queue follow-up message |
99
99
  | \`${se}\` | Restore queued messages |
100
100
  | \`Ctrl+V\` | Paste image from clipboard |
101
101
  | \`/\` | Slash commands |
102
102
  | \`!\` | Run bash command |
103
103
  | \`!!\` | Run bash command (excluded from context) |
104
- `;const V=this.session.extensionRunner;if(V){const z=V.getShortcuts(this.keybindings.getEffectiveConfig());if(z.size>0){W+=`
104
+ `;const z=this.session.extensionRunner;if(z){const X=z.getShortcuts(this.keybindings.getEffectiveConfig());if(X.size>0){H+=`
105
105
  **Extensions**
106
106
  | Key | Action |
107
107
  |-----|--------|
108
- `;for(const[ie,U]of z){const ne=U.description??U.extensionPath,X=ie.replace(/\b\w/g,oe=>oe.toUpperCase());W+=`| \`${X}\` | ${ne} |
109
- `}}}this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new Z),this.chatContainer.addChild(new g(r.bold(r.fg("accent","Keyboard Shortcuts")),1,0)),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new me(W.trim(),1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new Z),this.ui.requestRender()}async handleClearCommand(){this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear(),await this.session.newSession(),this.clearStatusTimers(),this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.state.compactionQueuedMessages=[],this.state.streamingComponent=void 0,this.state.streamingMessage=void 0,this.state.pendingTools.clear(),this.imagePipeline.clearAttachments(),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(`${r.fg("accent","\u2713 New session started")}`,1,1)),this.ui.requestRender()}handleRenderDebugCommand(){const e=this.ui.terminal.columns,n=this.ui.terminal.rows,i=this.ui.render(e),o=He(),t=[`Debug output at ${new Date().toISOString()}`,`Terminal: ${e}x${n}`,`Total lines: ${i.length}`,"","=== All rendered lines with visible widths ===",...i.map((a,h)=>{const c=pe(a),d=JSON.stringify(a);return`[${h}] (w=${c}) ${d}`}),"","=== Agent messages (JSONL) ===",...this.session.messages.map(a=>JSON.stringify(a)),""].join(`
110
- `);P.mkdirSync(D.dirname(o),{recursive:!0}),P.writeFileSync(o,t),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(`${r.fg("accent","\u2713 Debug log written")}
111
- ${r.fg("muted",o)}`,1,1)),this.ui.requestRender()}handleArminSaysHi(){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new it(this.ui)),this.ui.requestRender()}handleShowResourcesCommand(){const e=this.session.extensionRunner;this.showLoadedResources({extensionPaths:e?.getExtensionPaths()??[],force:!0,showDiagnosticsWhenQuiet:!0}),this.ui.requestRender()}handleDaxnuts(){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new $t(this.ui)),this.ui.requestRender()}async handleBashCommand(e,n=!1){const i=this.session.extensionRunner,o=i?await i.emitUserBash({type:"user_bash",command:e,excludeFromContext:n,cwd:this.session.cwd}):void 0;if(o?.result){const a=o.result;this.bashComponent=new ce(e,this.ui,n),this.session.isStreaming?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),a.output&&this.bashComponent.appendOutput(a.output),this.bashComponent.setComplete(a.exitCode,a.cancelled,a.truncated?{truncated:!0,content:a.output}:void 0,a.fullOutputPath),this.session.recordBashResult(e,a,{excludeFromContext:n}),this.bashComponent=void 0,this.ui.requestRender();return}const t=this.session.isStreaming;this.bashComponent=new ce(e,this.ui,n),t?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),this.ui.requestRender();try{const a=await this.session.executeBash(e,h=>{this.bashComponent&&(this.bashComponent.appendOutput(h),this.ui.requestRender())},{excludeFromContext:n,operations:o?.operations});this.bashComponent&&this.bashComponent.setComplete(a.exitCode,a.cancelled,a.truncated?{truncated:!0,content:a.output}:void 0,a.fullOutputPath)}catch(a){this.bashComponent&&this.bashComponent.setComplete(void 0,!1),this.showError(`Bash command failed: ${a instanceof Error?a.message:"Unknown error"}`)}this.bashComponent=void 0,this.ui.requestRender()}async handleCompactCommand(e){if(this.sessionManager.getEntries().filter(o=>o.type==="message").length<2){this.showWarning("Nothing to compact (no messages yet)");return}await this.executeCompaction(e,!1)}async executeCompaction(e,n=!1){this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear();const i=this.defaultEditor.onEscape;this.defaultEditor.onEscape=()=>{this.session.abortCompaction()},this.chatContainer.addChild(new u(1));const o=`(${L(this.keybindings,"interrupt")} to cancel)`,t=n?`Auto-compacting context... ${o}`:`Compacting context... ${o}`,a=new Mt(this.ui,r,t);this.statusContainer.addChild(a),this.ui.requestRender();let h;try{h=await this.session.compact(e),this.rebuildChatFromMessages();const c=Ge(h.summary,h.tokensBefore,new Date().toISOString());this.addMessageToChat(c),this.footer.invalidate()}catch(c){const d=c instanceof Error?c.message:String(c);d==="Compaction cancelled"||c instanceof Error&&c.name==="AbortError"?this.showError("Compaction cancelled"):this.showError(`Compaction failed: ${d}`)}finally{a.stop(),this.statusContainer.clear(),this.defaultEditor.onEscape=i}return this.flushCompactionQueue({willRetry:!1}),h}stop(){this.stopWelcomeBannerTimer(),this.clearBuddyPetResetTimer(),this.buddyPet?.dispose(),this.buddyPet=null,this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.clearExtensionTerminalInputListeners(),this.footer.dispose(),this.footerDataProvider.dispose(),this.unsubscribe&&this.unsubscribe(),this.isInitialized&&(this.ui.stop(),this.isInitialized=!1)}async applyPersonaFromSessionIfAny(){const n=this.session.sessionManager.getEntries().filter(o=>o.type==="custom"&&o.customType==="persona");let i;if(n.length>0){const o=n[n.length-1],t=o?.data?.personaId??o?.data?.id;typeof t=="string"&&t.trim()&&(i=t)}i=i??de(),i&&(process.env.NANOMEM_MEMORY_DIR=I(we(i)),process.env.SOUL_DIR=I(ye(i)),process.env.MCP_CONFIG_PATH=I(Ce(i)),process.env.NANO_PERSONA_DIR=I(le(i)),n.length>0&&be(i),!this.session.isStreaming&&!this.session.isCompacting&&await this.session.reload())}handleSoulCommand(){const e=this.session._soulManager;if(!e){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("warning","\u26A0\uFE0F Soul Not Enabled"),1,0)),this.chatContainer.addChild(new g(r.fg("dim","Soul (AI personality system) is not enabled. Please use Catui 1.3.0 or later."),1,0)),this.ui.requestRender();return}const n=Lt(e,{compact:!1});this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(n,1,0)),this.ui.requestRender()}async handlePersonaCommand(e){const n=e.trim().split(/\s+/),i=(n[1]??"list").toLowerCase(),o=n[2];if(i==="list"||i==="use"&&!o){const a=Se(),h=de();this.showSelector(c=>{const d=new Et(this.ui,a,h,Je,m=>{c(),this.switchPersona(m)},()=>{c(),this.ui.requestRender()});return{component:d,focus:d}});return}if(i!=="use"){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("dim",`Usage:
108
+ `;for(const[ie,q]of X){const ne=q.description??q.extensionPath,J=ie.replace(/\b\w/g,oe=>oe.toUpperCase());H+=`| \`${J}\` | ${ne} |
109
+ `}}}this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new ee),this.chatContainer.addChild(new g(r.bold(r.fg("accent","Keyboard Shortcuts")),1,0)),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new me(H.trim(),1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new ee),this.ui.requestRender()}async handleClearCommand(){this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear(),await this.session.newSession(),this.clearStatusTimers(),this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.state.compactionQueuedMessages=[],this.state.streamingComponent=void 0,this.state.streamingMessage=void 0,this.state.pendingTools.clear(),this.imagePipeline.clearAttachments(),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(`${r.fg("accent","\u2713 New session started")}`,1,1)),this.ui.requestRender()}handleRenderDebugCommand(){const e=this.ui.terminal.columns,n=this.ui.terminal.rows,i=this.ui.render(e),o=He(),t=[`Debug output at ${new Date().toISOString()}`,`Terminal: ${e}x${n}`,`Total lines: ${i.length}`,"","=== All rendered lines with visible widths ===",...i.map((a,h)=>{const c=pe(a),d=JSON.stringify(a);return`[${h}] (w=${c}) ${d}`}),"","=== Agent messages (JSONL) ===",...this.session.messages.map(a=>JSON.stringify(a)),""].join(`
110
+ `);P.mkdirSync(L.dirname(o),{recursive:!0}),P.writeFileSync(o,t),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(`${r.fg("accent","\u2713 Debug log written")}
111
+ ${r.fg("muted",o)}`,1,1)),this.ui.requestRender()}handleArminSaysHi(){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new it(this.ui)),this.ui.requestRender()}handleShowResourcesCommand(){const e=this.session.extensionRunner;this.showLoadedResources({extensionPaths:e?.getExtensionPaths()??[],force:!0,showDiagnosticsWhenQuiet:!0}),this.ui.requestRender()}handleDaxnuts(){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new $t(this.ui)),this.ui.requestRender()}async handleBashCommand(e,n=!1){const i=this.session.extensionRunner,o=i?await i.emitUserBash({type:"user_bash",command:e,excludeFromContext:n,cwd:this.session.cwd}):void 0;if(o?.result){const a=o.result;this.bashComponent=new ce(e,this.ui,n),this.session.isStreaming?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),a.output&&this.bashComponent.appendOutput(a.output),this.bashComponent.setComplete(a.exitCode,a.cancelled,a.truncated?{truncated:!0,content:a.output}:void 0,a.fullOutputPath),this.session.recordBashResult(e,a,{excludeFromContext:n}),this.bashComponent=void 0,this.ui.requestRender();return}const t=this.session.isStreaming;this.bashComponent=new ce(e,this.ui,n),t?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),this.ui.requestRender();try{const a=await this.session.executeBash(e,h=>{this.bashComponent&&(this.bashComponent.appendOutput(h),this.ui.requestRender())},{excludeFromContext:n,operations:o?.operations});this.bashComponent&&this.bashComponent.setComplete(a.exitCode,a.cancelled,a.truncated?{truncated:!0,content:a.output}:void 0,a.fullOutputPath)}catch(a){this.bashComponent&&this.bashComponent.setComplete(void 0,!1),this.showError(`Bash command failed: ${a instanceof Error?a.message:"Unknown error"}`)}this.bashComponent=void 0,this.ui.requestRender()}async handleCompactCommand(e){if(this.sessionManager.getEntries().filter(o=>o.type==="message").length<2){this.showWarning("Nothing to compact (no messages yet)");return}await this.executeCompaction(e,!1)}async executeCompaction(e,n=!1){this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.statusContainer.clear();const i=this.defaultEditor.onEscape;this.defaultEditor.onEscape=()=>{this.session.abortCompaction()},this.chatContainer.addChild(new u(1));const o=`(${B(this.keybindings,"interrupt")} to cancel)`,t=n?`Auto-compacting context... ${o}`:`Compacting context... ${o}`,a=new bt(this.ui,r,t);this.statusContainer.addChild(a),this.ui.requestRender();let h;try{h=await this.session.compact(e),this.rebuildChatFromMessages();const c=Ge(h.summary,h.tokensBefore,new Date().toISOString());this.addMessageToChat(c),this.footer.invalidate()}catch(c){const d=c instanceof Error?c.message:String(c);d==="Compaction cancelled"||c instanceof Error&&c.name==="AbortError"?this.showError("Compaction cancelled"):this.showError(`Compaction failed: ${d}`)}finally{a.stop(),this.statusContainer.clear(),this.defaultEditor.onEscape=i}return this.flushCompactionQueue({willRetry:!1}),h}stop(){this.stopWelcomeBannerTimer(),this.clearBuddyPetResetTimer(),this.buddyPet?.dispose(),this.buddyPet=null,this.state.loadingAnimation&&(this.state.loadingAnimation.stop(),this.state.loadingAnimation=void 0),this.clearExtensionTerminalInputListeners(),this.footer.dispose(),this.footerDataProvider.dispose(),this.unsubscribe&&this.unsubscribe(),this.isInitialized&&(this.ui.stop(),this.isInitialized=!1)}async applyPersonaFromSessionIfAny(){const n=this.session.sessionManager.getEntries().filter(o=>o.type==="custom"&&o.customType==="persona");let i;if(n.length>0){const o=n[n.length-1],t=o?.data?.personaId??o?.data?.id;typeof t=="string"&&t.trim()&&(i=t)}i=i??de(),i&&(process.env.NANOMEM_MEMORY_DIR=R(we(i)),process.env.SOUL_DIR=R(ye(i)),process.env.MCP_CONFIG_PATH=R(Ce(i)),process.env.NANO_PERSONA_DIR=R(le(i)),n.length>0&&Me(i),!this.session.isStreaming&&!this.session.isCompacting&&await this.session.reload())}handleSoulCommand(){const e=this.session._soulManager;if(!e){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("warning","\u26A0\uFE0F Soul Not Enabled"),1,0)),this.chatContainer.addChild(new g(r.fg("dim","Soul (AI personality system) is not enabled. Please use Catui 1.3.0 or later."),1,0)),this.ui.requestRender();return}const n=Lt(e,{compact:!1});this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(n,1,0)),this.ui.requestRender()}async handlePersonaCommand(e){const n=e.trim().split(/\s+/),i=(n[1]??"list").toLowerCase(),o=n[2];if(i==="list"||i==="use"&&!o){const a=Se(),h=de();this.showSelector(c=>{const d=new Et(this.ui,a,h,Je,m=>{c(),this.switchPersona(m)},()=>{c(),this.ui.requestRender()});return{component:d,focus:d}});return}if(i!=="use"){this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(r.fg("dim",`Usage:
112
112
  - /persona (open selector)
113
113
  - /persona use <personaId>`),1,0)),this.ui.requestRender();return}const t=o?o.trim():"";if(!t){this.showError("Missing personaId. Use: /persona use <personaId>");return}await this.switchPersona(t)}async switchPersona(e){const n=le(e);if(!P.existsSync(n)){this.showError(`Persona not found: ${e}
114
- Expected: ${n}`);return}const i=this.session.sessionManager.getBranch();let o;for(let t=i.length-1;t>=0;t--){const a=i[t];if(a?.type==="message"&&a?.message?.role==="user"){o=a.id;break}}o&&(await this.session.fork(o)).cancelled||(this.session.sessionManager.appendCustomEntry("persona",{personaId:e}),be(e),process.env.NANOMEM_MEMORY_DIR=I(we(e)),process.env.SOUL_DIR=I(ye(e)),process.env.MCP_CONFIG_PATH=I(Ce(e)),process.env.NANO_PERSONA_DIR=I(le(e)),process.env.CATUI_JUST_SWITCHED_PERSONA="true",await this.handleReloadCommand(),this.showStatus(`Persona switched to: ${e}`))}handleMemoryCommand(){const e=[];e.push(r.fg("accent","\u{1F4DA} Project Memory - NanoMem")),e.push(""),e.push(r.fg("dim",`Storage: ${this.session.agentDir}/memory/`)),e.push(r.fg("dim"," - knowledge.json (project knowledge)")),e.push(r.fg("dim"," - lessons.json (lessons learned)")),e.push(r.fg("dim"," - preferences.json (user preferences)")),e.push(r.fg("dim"," - patterns.json (behavior patterns)")),e.push(r.fg("dim"," - facets.json (patterns/struggles)")),e.push(""),e.push(r.fg("dim","\u{1F4A1} Tip: NanoMem automatically extracts and remembers project knowledge from conversations")),e.push(r.fg("dim"," - Remembers API endpoints, configuration options")),e.push(r.fg("dim"," - Learns error patterns and solutions")),e.push(r.fg("dim"," - Recognizes user preferences and coding style")),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(e.join(`
114
+ Expected: ${n}`);return}const i=this.session.sessionManager.getBranch();let o;for(let t=i.length-1;t>=0;t--){const a=i[t];if(a?.type==="message"&&a?.message?.role==="user"){o=a.id;break}}o&&(await this.session.fork(o)).cancelled||(this.session.sessionManager.appendCustomEntry("persona",{personaId:e}),Me(e),process.env.NANOMEM_MEMORY_DIR=R(we(e)),process.env.SOUL_DIR=R(ye(e)),process.env.MCP_CONFIG_PATH=R(Ce(e)),process.env.NANO_PERSONA_DIR=R(le(e)),process.env.CATUI_JUST_SWITCHED_PERSONA="true",await this.handleReloadCommand(),this.showStatus(`Persona switched to: ${e}`))}handleMemoryCommand(){const e=[];e.push(r.fg("accent","\u{1F4DA} Project Memory - NanoMem")),e.push(""),e.push(r.fg("dim",`Storage: ${this.session.agentDir}/memory/`)),e.push(r.fg("dim"," - knowledge.json (project knowledge)")),e.push(r.fg("dim"," - lessons.json (lessons learned)")),e.push(r.fg("dim"," - preferences.json (user preferences)")),e.push(r.fg("dim"," - patterns.json (behavior patterns)")),e.push(r.fg("dim"," - facets.json (patterns/struggles)")),e.push(""),e.push(r.fg("dim","\u{1F4A1} Tip: NanoMem automatically extracts and remembers project knowledge from conversations")),e.push(r.fg("dim"," - Remembers API endpoints, configuration options")),e.push(r.fg("dim"," - Learns error patterns and solutions")),e.push(r.fg("dim"," - Recognizes user preferences and coding style")),this.chatContainer.addChild(new u(1)),this.chatContainer.addChild(new g(e.join(`
115
115
  `),1,0)),this.ui.requestRender()}handleBrowserOptInCommand(){this.showStatus(["Browser automation is opt-in.","","Enable it by starting Catui with:"," --extension extensions/builtin/browser","","Or add that path to your extensions config, then run /browser status."].join(`
116
116
  `))}async handleMcpCommand(e){const n=e.trim().split(/\s+/),i=(n[1]||"list").toLowerCase(),o=n[2];if(i==="list"){const t=fe();if(this.chatContainer.addChild(new u(1)),t.length===0)this.chatContainer.addChild(new g(r.fg("dim","No MCP servers configured."),1,0));else{const a=[r.bold("MCP Servers"),"",...t.map(h=>{const c=h.enabled===!1?"disabled":"enabled";return`- ${h.id} (${h.name}) [${c}]`}),"",r.fg("dim","Use: /mcp enable <id> or /mcp disable <id>")];this.chatContainer.addChild(new g(a.join(`
117
117
  `),1,0))}this.ui.requestRender();return}if(i==="status"||i==="tools"){const t=this.session.getAllTools().filter(a=>a.name.startsWith("mcp_"));if(this.chatContainer.addChild(new u(1)),t.length===0)this.chatContainer.addChild(new g([r.bold("MCP Runtime Status"),"","No MCP tools are currently registered in this session.",r.fg("dim","Tip: run /reload and check startup logs for MCP errors.")].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "name": "catui-agent",
3
- "version": "1.0.0-beta.0",
2
+ "name": "catui-agent",
3
+ "version": "1.0.0",
4
4
  "description": "CLI writing agent with read, bash, edit, write tools and session management. Supports DashScope and Ali Token Plan. Soul enabled by default for AI personality evolution.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -129,9 +129,9 @@
129
129
  "@mariozechner/clipboard": "^0.3.2",
130
130
  "@mariozechner/jiti": "^2.6.2",
131
131
  "@mistralai/mistralai": "1.10.0",
132
- "catui-protocol": "^0.1.1",
133
- "catui-mem": "^1.1.2",
134
- "catui-soul": "^0.1.0",
132
+ "catui-protocol": "^0.1.1",
133
+ "catui-mem": "^1.1.2",
134
+ "catui-soul": "^0.1.0",
135
135
  "@silvia-odwyer/photon-node": "^0.3.4",
136
136
  "@sinclair/typebox": "^0.34.41",
137
137
  "ajv": "^8.17.1",