@openadapter/koda 1.0.0-beta.3 → 1.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modes/interactive/components/settings-selector.d.ts +1 -0
- package/dist/modes/interactive/components/settings-selector.js +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -1
- package/dist/modes/interactive/interactive-mode.js +27 -27
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -56,6 +56,7 @@ export interface SettingsCallbacks {
|
|
|
56
56
|
onClearOnShrinkChange: (enabled: boolean) => void;
|
|
57
57
|
onShowTerminalProgressChange: (enabled: boolean) => void;
|
|
58
58
|
onWarningsChange: (warnings: WarningSettings) => void;
|
|
59
|
+
onImportSessions: () => void;
|
|
59
60
|
onCancel: () => void;
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var E=Object.defineProperty;var l=(h,e)=>E(h,"name",{value:e,configurable:!0});import{Container as g,getCapabilities as M,SelectList as P,SettingsList as f,Spacer as b,Text as C}from"@openadapter/koda-tui";import{formatHttpIdleTimeoutMs as A,HTTP_IDLE_TIMEOUT_CHOICES as k}from"../../../core/http-dispatcher.js";import{getSelectListTheme as H,getSettingsListTheme as w,theme as c}from"../theme/theme.js";import{DynamicBorder as I}from"./dynamic-border.js";import{keyDisplayText as
|
|
1
|
+
var E=Object.defineProperty;var l=(h,e)=>E(h,"name",{value:e,configurable:!0});import{Container as g,getCapabilities as M,SelectList as P,SettingsList as f,Spacer as b,Text as C}from"@openadapter/koda-tui";import{formatHttpIdleTimeoutMs as A,HTTP_IDLE_TIMEOUT_CHOICES as k}from"../../../core/http-dispatcher.js";import{getSelectListTheme as H,getSettingsListTheme as w,theme as c}from"../theme/theme.js";import{DynamicBorder as I}from"./dynamic-border.js";import{keyDisplayText as O}from"./keybinding-hints.js";const D={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},U={off:"No reasoning",minimal:"Very brief reasoning (~1k tokens)",low:"Light reasoning (~2k tokens)",medium:"Moderate reasoning (~8k tokens)",high:"Deep reasoning (~16k tokens)",xhigh:"Maximum reasoning (~32k tokens)"};class z extends g{static{l(this,"WarningSettingsSubmenu")}settingsList;state;constructor(e,t,n){super(),this.state={...e};const d=[{id:"anthropic-extra-usage",label:"Anthropic extra usage",description:"Warn when Anthropic subscription auth may use paid extra usage",currentValue:this.state.anthropicExtraUsage??!0?"true":"false",values:["true","false"]}];this.settingsList=new f(d,Math.min(d.length,10),w(),(u,a)=>{u==="anthropic-extra-usage"&&(this.state={...this.state,anthropicExtraUsage:a==="true"},t({...this.state}))},n),this.addChild(this.settingsList)}handleInput(e){this.settingsList.handleInput(e)}}class S extends g{static{l(this,"SelectSubmenu")}selectList;constructor(e,t,n,d,u,a,m){super(),this.addChild(new C(c.bold(c.fg("accent",e)),0,0)),t&&(this.addChild(new b(1)),this.addChild(new C(c.fg("muted",t),0,0))),this.addChild(new b(1)),this.selectList=new P(n,Math.min(n.length,10),H(),D);const p=n.findIndex(o=>o.value===d);p!==-1&&this.selectList.setSelectedIndex(p),this.selectList.onSelect=o=>{u(o.value)},this.selectList.onCancel=a,m&&(this.selectList.onSelectionChange=o=>{m(o.value)}),this.addChild(this.selectList),this.addChild(new b(1)),this.addChild(new C(c.fg("dim"," Enter to select \xB7 Esc to go back"),0,0))}handleInput(e){this.selectList.handleInput(e)}}class q extends g{static{l(this,"SettingsSelectorComponent")}settingsList;constructor(e,t){super();const n=M().images,d=O("app.message.followUp");let u={...e.warnings};const a=[{id:"autocompact",label:"Auto-compact",description:"Automatically compact context when it gets too large",currentValue:e.autoCompact?"true":"false",values:["true","false"]},{id:"steering-mode",label:"Steering mode",description:"Enter while streaming queues steering messages. 'one-at-a-time': deliver one, wait for response. 'all': deliver all at once.",currentValue:e.steeringMode,values:["one-at-a-time","all"]},{id:"follow-up-mode",label:"Follow-up mode",description:`${d} queues follow-up messages until agent stops. 'one-at-a-time': deliver one, wait for response. 'all': deliver all at once.`,currentValue:e.followUpMode,values:["one-at-a-time","all"]},{id:"transport",label:"Transport",description:"Preferred transport for providers that support multiple transports",currentValue:e.transport,values:["sse","websocket","websocket-cached","auto"]},{id:"http-idle-timeout",label:"HTTP idle timeout",description:"Maximum idle gap while waiting for HTTP headers or body chunks. Disable for local models that pause longer than five minutes.",currentValue:A(e.httpIdleTimeoutMs),values:k.map(s=>s.label)},{id:"hide-thinking",label:"Hide thinking",description:"Hide thinking blocks in assistant responses",currentValue:e.hideThinkingBlock?"true":"false",values:["true","false"]},{id:"collapse-changelog",label:"Collapse changelog",description:"Show condensed changelog after updates",currentValue:e.collapseChangelog?"true":"false",values:["true","false"]},{id:"quiet-startup",label:"Quiet startup",description:"Disable verbose printing at startup",currentValue:e.quietStartup?"true":"false",values:["true","false"]},{id:"install-telemetry",label:"Install telemetry",description:"Send an anonymous version/update ping after changelog-detected updates",currentValue:e.enableInstallTelemetry?"true":"false",values:["true","false"]},{id:"double-escape-action",label:"Double-escape action",description:"Action when pressing Escape twice with empty editor",currentValue:e.doubleEscapeAction,values:["tree","fork","none"]},{id:"tree-filter-mode",label:"Tree filter mode",description:"Default filter when opening /tree",currentValue:e.treeFilterMode,values:["default","no-tools","user-only","labeled-only","all"]},{id:"warnings",label:"Warnings",description:"Enable or disable individual warnings",currentValue:"configure",submenu:l((s,i)=>new z(u,r=>{u=r,t.onWarningsChange(r)},()=>i()),"submenu")},{id:"thinking",label:"Thinking level",description:"Reasoning depth for thinking-capable models",currentValue:e.thinkingLevel,submenu:l((s,i)=>new S("Thinking Level","Select reasoning depth for thinking-capable models",e.availableThinkingLevels.map(r=>({value:r,label:r,description:U[r]})),s,r=>{t.onThinkingLevelChange(r),i(r)},()=>i()),"submenu")},{id:"theme",label:"Theme",description:"Color theme for the interface",currentValue:e.currentTheme,submenu:l((s,i)=>new S("Theme","Select color theme",e.availableThemes.map(r=>({value:r,label:r})),s,r=>{t.onThemeChange(r),i(r)},()=>{t.onThemePreview?.(s),i()},r=>{t.onThemePreview?.(r)}),"submenu")},{id:"import-sessions",label:"Import past sessions",description:"Bring your Claude Code + OpenCode history into Koda (Enter to run; already-imported are skipped)",currentValue:"Claude Code + OpenCode",values:["Claude Code + OpenCode"]}];n&&(a.splice(1,0,{id:"show-images",label:"Show images",description:"Render images inline in terminal",currentValue:e.showImages?"true":"false",values:["true","false"]}),a.splice(2,0,{id:"image-width-cells",label:"Image width",description:"Preferred inline image width in terminal cells",currentValue:String(e.imageWidthCells),values:["60","80","120"]})),a.splice(n?3:1,0,{id:"auto-resize-images",label:"Auto-resize images",description:"Resize large images to 2000x2000 max for better model compatibility",currentValue:e.autoResizeImages?"true":"false",values:["true","false"]});const m=a.findIndex(s=>s.id==="auto-resize-images");a.splice(m+1,0,{id:"block-images",label:"Block images",description:"Prevent images from being sent to LLM providers",currentValue:e.blockImages?"true":"false",values:["true","false"]});const p=a.findIndex(s=>s.id==="block-images");a.splice(p+1,0,{id:"skill-commands",label:"Skill commands",description:"Register skills as /skill:name commands",currentValue:e.enableSkillCommands?"true":"false",values:["true","false"]});const o=a.findIndex(s=>s.id==="skill-commands");a.splice(o+1,0,{id:"show-hardware-cursor",label:"Show hardware cursor",description:"Show the terminal cursor while still positioning it for IME support",currentValue:e.showHardwareCursor?"true":"false",values:["true","false"]});const v=a.findIndex(s=>s.id==="show-hardware-cursor");a.splice(v+1,0,{id:"editor-padding",label:"Editor padding",description:"Horizontal padding for input editor (0-3)",currentValue:String(e.editorPaddingX),values:["0","1","2","3"]});const T=a.findIndex(s=>s.id==="editor-padding");a.splice(T+1,0,{id:"autocomplete-max-visible",label:"Autocomplete max items",description:"Max visible items in autocomplete dropdown (3-20)",currentValue:String(e.autocompleteMaxVisible),values:["3","5","7","10","15","20"]});const x=a.findIndex(s=>s.id==="autocomplete-max-visible");a.splice(x+1,0,{id:"clear-on-shrink",label:"Clear on shrink",description:"Clear empty rows when content shrinks (may cause flicker)",currentValue:e.clearOnShrink?"true":"false",values:["true","false"]});const L=a.findIndex(s=>s.id==="clear-on-shrink");a.splice(L+1,0,{id:"terminal-progress",label:"Terminal progress",description:"Show OSC 9;4 progress indicators in the terminal tab bar",currentValue:e.showTerminalProgress?"true":"false",values:["true","false"]}),this.addChild(new I),this.settingsList=new f(a,10,w(),(s,i)=>{switch(s){case"autocompact":t.onAutoCompactChange(i==="true");break;case"show-images":t.onShowImagesChange(i==="true");break;case"image-width-cells":t.onImageWidthCellsChange(parseInt(i,10));break;case"auto-resize-images":t.onAutoResizeImagesChange(i==="true");break;case"block-images":t.onBlockImagesChange(i==="true");break;case"skill-commands":t.onEnableSkillCommandsChange(i==="true");break;case"steering-mode":t.onSteeringModeChange(i);break;case"follow-up-mode":t.onFollowUpModeChange(i);break;case"transport":t.onTransportChange(i);break;case"http-idle-timeout":{const r=k.find(y=>y.label===i);r&&t.onHttpIdleTimeoutMsChange(r.timeoutMs);break}case"hide-thinking":t.onHideThinkingBlockChange(i==="true");break;case"collapse-changelog":t.onCollapseChangelogChange(i==="true");break;case"quiet-startup":t.onQuietStartupChange(i==="true");break;case"install-telemetry":t.onEnableInstallTelemetryChange(i==="true");break;case"double-escape-action":t.onDoubleEscapeActionChange(i);break;case"tree-filter-mode":t.onTreeFilterModeChange(i);break;case"show-hardware-cursor":t.onShowHardwareCursorChange(i==="true");break;case"editor-padding":t.onEditorPaddingXChange(parseInt(i,10));break;case"autocomplete-max-visible":t.onAutocompleteMaxVisibleChange(parseInt(i,10));break;case"clear-on-shrink":t.onClearOnShrinkChange(i==="true");break;case"terminal-progress":t.onShowTerminalProgressChange(i==="true");break;case"import-sessions":t.onImportSessions();break}},t.onCancel,{enableSearch:!0}),this.addChild(this.settingsList),this.addChild(new I)}getSettingsList(){return this.settingsList}}export{q as SettingsSelectorComponent};
|
|
@@ -332,7 +332,9 @@ export declare class InteractiveMode {
|
|
|
332
332
|
clearEditor(): void;
|
|
333
333
|
showError(errorMessage: string): void;
|
|
334
334
|
showWarning(warningMessage: string): void;
|
|
335
|
-
|
|
335
|
+
private showResumeHintForCwd;
|
|
336
|
+
private runImportFromSettings;
|
|
337
|
+
showNewVersionNotification(release: LatestPiRelease, autoUpdating?: boolean): void;
|
|
336
338
|
showPackageUpdateNotification(packages: string[]): void;
|
|
337
339
|
/**
|
|
338
340
|
* Get all queued messages (read-only).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var He=Object.defineProperty;var h=(p,e)=>He(p,"name",{value:e,configurable:!0});import*as Fe from"node:crypto";import*as v from"node:fs";import*as F from"node:os";import*as E from"node:path";import{getProviders as qe}from"@openadapter/koda-ai";import{CombinedAutocompleteProvider as Be,Container as A,fuzzyFilter as Ue,getCapabilities as Oe,hyperlink as _e,Loader as D,Markdown as q,matchesKey as Ne,ProcessTerminal as Ke,Spacer as g,setKeybindings as je,Text as f,TruncatedText as K,TUI as ze,visibleWidth as Ge}from"@openadapter/koda-tui";import Ve from"chalk";import{spawn as j,spawnSync as Qe}from"child_process";import{APP_NAME as z,APP_TITLE as te,getAgentDir as Xe,getAuthPath as se,getDebugLogPath as Je,getDocsPath as Ye,getShareViewerUrl as Ze,KODA_VERSION as et,VERSION as L}from"../../config.js";import{parseSkillBlock as tt}from"../../core/agent-session.js";import{SessionImportFileNotFoundError as st}from"../../core/agent-session-runtime.js";import{FooterDataProvider as it}from"../../core/footer-data-provider.js";import{configureHttpDispatcher as G,formatHttpIdleTimeoutMs as nt}from"../../core/http-dispatcher.js";import{KeybindingsManager as ot}from"../../core/keybindings.js";import{createCompactionSummaryMessage as rt}from"../../core/messages.js";import{defaultModelPerProvider as ie,findExactModelReferenceMatch as at,resolveModelScope as ne}from"../../core/model-resolver.js";import{DefaultPackageManager as ht}from"../../core/package-manager.js";import{BUILT_IN_PROVIDER_DISPLAY_NAMES as dt}from"../../core/provider-display-names.js";import{formatMissingSessionCwdPrompt as lt,MissingSessionCwdError as oe}from"../../core/session-cwd.js";import{SessionManager as B}from"../../core/session-manager.js";import{BUILTIN_SLASH_COMMANDS as re}from"../../core/slash-commands.js";import{isInstallTelemetryEnabled as ct}from"../../core/telemetry.js";import{runBackgroundSelfUpdate as ut}from"../../utils/auto-update.js";import{getChangelogPath as ae,getNewEntries as gt,parseChangelog as he}from"../../utils/changelog.js";import{copyToClipboard as pt}from"../../utils/clipboard.js";import{extensionForImageMimeType as mt,readClipboardImage as ft}from"../../utils/clipboard-image.js";import{parseGitUrl as de}from"../../utils/git.js";import{getKodaUserAgent as Ct}from"../../utils/koda-user-agent.js";import{getCwdRelativePath as wt}from"../../utils/paths.js";import{killTrackedDetachedChildren as V}from"../../utils/shell.js";import{ensureTool as le}from"../../utils/tools-manager.js";import{checkForNewPiVersion as St}from"../../utils/version-check.js";import{ArminComponent as yt}from"./components/armin.js";import{AssistantMessageComponent as U}from"./components/assistant-message.js";import{BashExecutionComponent as Q}from"./components/bash-execution.js";import{BorderedLoader as Et}from"./components/bordered-loader.js";import{BranchSummaryMessageComponent as kt}from"./components/branch-summary-message.js";import{CompactionSummaryMessageComponent as bt}from"./components/compaction-summary-message.js";import{CountdownTimer as xt}from"./components/countdown-timer.js";import{CustomEditor as Mt}from"./components/custom-editor.js";import{CustomMessageComponent as Tt}from"./components/custom-message.js";import{DaxnutsComponent as $t}from"./components/daxnuts.js";import{DynamicBorder as k}from"./components/dynamic-border.js";import{EarendilAnnouncementComponent as Pt}from"./components/earendil-announcement.js";import{ExtensionEditorComponent as At}from"./components/extension-editor.js";import{ExtensionInputComponent as Rt}from"./components/extension-input.js";import{ExtensionSelectorComponent as X}from"./components/extension-selector.js";import{FooterComponent as vt}from"./components/footer.js";import{formatKeyText as ce,keyDisplayText as ue,keyHint as ge,keyText as P,rawKeyHint as R}from"./components/keybinding-hints.js";import{LoginDialogComponent as J}from"./components/login-dialog.js";import{ModelSelectorComponent as It}from"./components/model-selector.js";import{OAuthSelectorComponent as pe}from"./components/oauth-selector.js";import{ScopedModelsSelectorComponent as Dt}from"./components/scoped-models-selector.js";import{SessionSelectorComponent as Lt}from"./components/session-selector.js";import{SettingsSelectorComponent as Wt}from"./components/settings-selector.js";import{SkillInvocationMessageComponent as Ht}from"./components/skill-invocation-message.js";import{ToolExecutionComponent as W}from"./components/tool-execution.js";import{TreeSelectorComponent as Ft}from"./components/tree-selector.js";import{UserMessageComponent as me}from"./components/user-message.js";import{UserMessageSelectorComponent as qt}from"./components/user-message-selector.js";import{getAvailableThemes as Bt,getAvailableThemesWithPaths as Ut,getEditorTheme as fe,getMarkdownTheme as Ot,getThemeByName as _t,initTheme as Nt,onThemeChange as Kt,setRegisteredThemes as Y,setTheme as O,setThemeInstance as jt,stopThemeWatcher as zt,Theme as Gt,theme as a}from"./theme/theme.js";function H(p){return typeof p=="object"&&p!==null&&"setExpanded"in p&&typeof p.setExpanded=="function"}h(H,"isExpandable");class Ce extends f{static{h(this,"ExpandableText")}getCollapsedText;getExpandedText;constructor(e,s,t=!1,i=0,n=0){super(t?s():e(),i,n),this.getCollapsedText=e,this.getExpandedText=s}setExpanded(e){this.setText(e?this.getExpandedText():this.getCollapsedText())}}const Vt=new Set(["EIO","EPIPE","ENOTCONN"]);function Qt(p){if(!p||typeof p!="object"||!("code"in p))return!1;const e=p.code;return e!==void 0&&Vt.has(e)}h(Qt,"isDeadTerminalError");const we="Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";function Xt(p){return typeof p=="string"&&p.startsWith("sk-ant-oat")}h(Xt,"isAnthropicSubscriptionAuthKey");function Jt(p){return!!p&&p.provider==="unknown"&&p.id==="unknown"&&p.api==="unknown"}h(Jt,"isUnknownModel");function Yt(p){return p.length>0&&!/[^a-zA-Z0-9_\-./~:@]/.test(p)?p:`'${p.replace(/'/g,"'\\''")}'`}h(Yt,"quoteIfNeeded");function Zt(p){if(!process.stdout.isTTY||!p.isPersisted())return;const e=p.getSessionFile();if(!e||!v.existsSync(e))return;const s=[z];return p.usesDefaultSessionDir()||s.push("--session-dir",Yt(p.getSessionDir())),s.push("--session",p.getSessionId()),s.join(" ")}h(Zt,"formatResumeCommand");function es(p){return p in ie}h(es,"hasDefaultModelProvider");const ts="amazon-bedrock",ss=new Set(qe());function is(p,e,s=ss){return dt[p]?!0:s.has(p)?!1:!e.has(p)}h(is,"isApiKeyLoginProvider");class _{static{h(this,"InteractiveMode")}runtimeHost;ui;chatContainer;pendingMessagesContainer;statusContainer;defaultEditor;editor;editorComponentFactory;autocompleteProvider;autocompleteProviderWrappers=[];fdPath;editorContainer;footer;footerDataProvider;keybindings;version;isInitialized=!1;onInputCallback;pendingUserInputs=[];loadingAnimation=void 0;workingMessage=void 0;workingVisible=!0;workingIndicatorOptions=void 0;defaultWorkingMessage="Koda is working\u2026";_workStartTs=0;_workWord="Working";_workTicker;static WORK_WORDS=["Flummoxing","Cogitating","Noodling","Percolating","Conjuring","Wrangling","Finagling","Cookifying","Flibbertigibbeting","Discombobulating","Hornswoggling","Bamboozling","Marinating","Concocting","Spelunking","Tinkering","Befuddling","Whirring","Schlepping","Razzledazzling","Confabulating","Snazzifying","Galumphing","Kerfuffling","Bedazzling","Vibing","Churning","Brewing"];defaultHiddenThinkingLabel="Thinking...";hiddenThinkingLabel=this.defaultHiddenThinkingLabel;lastSigintTime=0;lastEscapeTime=0;changelogMarkdown=void 0;startupNoticesShown=!1;anthropicSubscriptionWarningShown=!1;lastStatusSpacer=void 0;lastStatusText=void 0;streamingComponent=void 0;streamingMessage=void 0;pendingTools=new Map;toolOutputExpanded=!1;hideThinkingBlock=!1;skillCommands=new Map;unsubscribe;signalCleanupHandlers=[];isBashMode=!1;bashComponent=void 0;pendingBashComponents=[];autoCompactionLoader=void 0;autoCompactionEscapeHandler;overseerEscapeHandler;compactionStartMs=0;compactionReason=void 0;compactionCancelHint="";compactionTicker=void 0;_kodaTitleBase="idle";_kodaReviewing=!1;retryLoader=void 0;overseerLoader=void 0;retryCountdown=void 0;retryEscapeHandler;compactionQueuedMessages=[];shutdownRequested=!1;extensionSelector=void 0;extensionInput=void 0;extensionEditor=void 0;extensionTerminalInputUnsubscribers=new Set;extensionWidgetsAbove=new Map;extensionWidgetsBelow=new Map;widgetContainerAbove;widgetContainerBelow;customFooter=void 0;headerContainer;builtInHeader=void 0;customHeader=void 0;options;get session(){return this.runtimeHost.session}get agent(){return this.session.agent}get sessionManager(){return this.session.sessionManager}get settingsManager(){return this.session.settingsManager}constructor(e,s={}){this.runtimeHost=e,this.options=s,this.runtimeHost.setBeforeSessionInvalidate(()=>{this.resetExtensionUI()}),this.runtimeHost.setRebindSession(async()=>{await this.rebindCurrentSession()}),this.version=L,this.ui=new ze(new Ke,this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.headerContainer=new A,this.chatContainer=new A,this.pendingMessagesContainer=new A,this.statusContainer=new A,this.widgetContainerAbove=new A,this.widgetContainerBelow=new A,this.keybindings=ot.create(),je(this.keybindings);const t=this.settingsManager.getEditorPaddingX(),i=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor=new Mt(this.ui,fe(),this.keybindings,{paddingX:t,autocompleteMaxVisible:i}),this.defaultEditor.title=this.kodaTitleText(),this.editor=this.defaultEditor,this.editorContainer=new A,this.editorContainer.addChild(this.editor),this.footerDataProvider=new it(this.sessionManager.getCwd()),this.footer=new vt(this.session,this.footerDataProvider),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),Y(this.session.resourceLoader.getThemes().themes),Nt(this.settingsManager.getTheme(),!0)}getAutocompleteSourceTag(e){if(!e)return;const s=e.scope==="user"?"u":e.scope==="project"?"p":"t",t=e.source.trim();if(t==="auto"||t==="local"||t==="cli")return s;if(t.startsWith("npm:"))return`${s}:${t}`;const i=de(t);if(i){const n=i.ref?`@${i.ref}`:"";return`${s}:git:${i.host}/${i.path}${n}`}return s}prefixAutocompleteDescription(e,s){const t=this.getAutocompleteSourceTag(s);return t?e?`[${t}] ${e}`:`[${t}]`:e}getBuiltInCommandConflictDiagnostics(e){const s=new Set(re.map(t=>t.name));return e.getRegisteredCommands().filter(t=>s.has(t.name)).map(t=>({type:"warning",message:t.invocationName===t.name?`Extension command '/${t.name}' conflicts with built-in interactive command. Skipping in autocomplete.`:`Extension command '/${t.name}' conflicts with built-in interactive command. Available as '/${t.invocationName}'.`,path:t.sourceInfo.path}))}createBaseAutocompleteProvider(){const e=re.map(r=>({name:r.name,description:r.description})),s=e.find(r=>r.name==="model");s&&(s.getArgumentCompletions=r=>{const d=this.session.scopedModels.length>0?this.session.scopedModels.map(u=>u.model):this.session.modelRegistry.getAvailable();if(d.length===0)return null;const l=d.map(u=>({id:u.id,provider:u.provider,label:`${u.provider}/${u.id}`})),m=Ue(l,r,u=>`${u.id} ${u.provider}`);return m.length===0?null:m.map(u=>({value:u.label,label:u.id,description:u.provider}))});const t=this.session.promptTemplates.map(r=>({name:r.name,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo),...r.argumentHint&&{argumentHint:r.argumentHint}})),i=new Set(e.map(r=>r.name)),n=this.session.extensionRunner.getRegisteredCommands().filter(r=>!i.has(r.name)).map(r=>({name:r.invocationName,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo),getArgumentCompletions:r.getArgumentCompletions}));this.skillCommands.clear();const o=[];if(this.settingsManager.getEnableSkillCommands())for(const r of this.session.resourceLoader.getSkills().skills){const d=`skill:${r.name}`;this.skillCommands.set(d,r.filePath),o.push({name:d,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo)})}return new Be([...e,...t,...n,...o],this.sessionManager.getCwd(),this.fdPath)}setupAutocompleteProvider(){let e=this.createBaseAutocompleteProvider();for(const s of this.autocompleteProviderWrappers)e=s(e);this.autocompleteProvider=e,this.defaultEditor.setAutocompleteProvider(e),this.editor!==this.defaultEditor&&this.editor.setAutocompleteProvider?.(e)}showStartupNoticesIfNeeded(){if(!this.startupNoticesShown&&(this.startupNoticesShown=!0,!!this.changelogMarkdown)){if(this.chatContainer.children.length>0&&this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.settingsManager.getCollapseChangelog()){const e=this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/),t=`Updated to v${e?e[1]:this.version}. Use ${a.bold("/changelog")} to view full changelog.`;this.chatContainer.addChild(new f(t,1,0))}else this.chatContainer.addChild(new f(a.bold(a.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new q(this.changelogMarkdown.trim(),1,0,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new g(1));this.chatContainer.addChild(new k)}}async init(){if(this.isInitialized)return;this.registerSignalHandlers(),this.changelogMarkdown=this.getChangelogForDisplay();const[e]=await Promise.all([le("fd"),le("rg")]);if(this.fdPath=e,this.session.scopedModels.length>0&&(this.options.verbose||!this.settingsManager.getQuietStartup())){const s=this.session.scopedModels.map(n=>{const o=n.thinkingLevel?`:${n.thinkingLevel}`:"";return`${n.model.id}${o}`}).join(", "),t=this.keybindings.getKeys("app.model.cycleForward"),i=t.length>0?a.fg("muted",` (${ce(t.join("/"),{capitalize:!0})} to cycle)`):"";console.log(a.fg("dim",`Model scope: ${s}${i}`))}if(this.ui.addChild(this.headerContainer),this.options.verbose||!this.settingsManager.getQuietStartup()){const s=["\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557","\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557","\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551","\u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551","\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D"].join(`
|
|
1
|
+
var He=Object.defineProperty;var h=(m,e)=>He(m,"name",{value:e,configurable:!0});import*as Fe from"node:crypto";import*as v from"node:fs";import*as q from"node:os";import*as E from"node:path";import{getProviders as qe}from"@openadapter/koda-ai";import{CombinedAutocompleteProvider as Be,Container as A,fuzzyFilter as Ue,getCapabilities as Oe,hyperlink as _e,Loader as D,Markdown as B,matchesKey as Ne,ProcessTerminal as Ke,Spacer as g,setKeybindings as je,Text as f,TruncatedText as K,TUI as ze,visibleWidth as Ge}from"@openadapter/koda-tui";import Ve from"chalk";import{spawn as j,spawnSync as Qe}from"child_process";import{detectImportable as Xe,importExternalSessions as Je}from"../../cli/import-sessions.js";import{APP_NAME as z,APP_TITLE as te,getAgentDir as Ye,getAuthPath as se,getDebugLogPath as Ze,getDocsPath as et,getShareViewerUrl as tt,KODA_VERSION as st,VERSION as L}from"../../config.js";import{parseSkillBlock as it}from"../../core/agent-session.js";import{SessionImportFileNotFoundError as nt}from"../../core/agent-session-runtime.js";import{FooterDataProvider as ot}from"../../core/footer-data-provider.js";import{configureHttpDispatcher as G,formatHttpIdleTimeoutMs as rt}from"../../core/http-dispatcher.js";import{KeybindingsManager as at}from"../../core/keybindings.js";import{createCompactionSummaryMessage as ht}from"../../core/messages.js";import{defaultModelPerProvider as ie,findExactModelReferenceMatch as dt,resolveModelScope as ne}from"../../core/model-resolver.js";import{DefaultPackageManager as lt}from"../../core/package-manager.js";import{BUILT_IN_PROVIDER_DISPLAY_NAMES as ct}from"../../core/provider-display-names.js";import{formatMissingSessionCwdPrompt as ut,MissingSessionCwdError as oe}from"../../core/session-cwd.js";import{SessionManager as W}from"../../core/session-manager.js";import{BUILTIN_SLASH_COMMANDS as re}from"../../core/slash-commands.js";import{isInstallTelemetryEnabled as gt}from"../../core/telemetry.js";import{runBackgroundSelfUpdate as pt}from"../../utils/auto-update.js";import{getChangelogPath as ae,getNewEntries as mt,parseChangelog as he}from"../../utils/changelog.js";import{copyToClipboard as ft}from"../../utils/clipboard.js";import{extensionForImageMimeType as Ct,readClipboardImage as wt}from"../../utils/clipboard-image.js";import{parseGitUrl as de}from"../../utils/git.js";import{getKodaUserAgent as St}from"../../utils/koda-user-agent.js";import{getCwdRelativePath as yt}from"../../utils/paths.js";import{killTrackedDetachedChildren as V}from"../../utils/shell.js";import{ensureTool as le}from"../../utils/tools-manager.js";import{checkForNewPiVersion as Et}from"../../utils/version-check.js";import{ArminComponent as kt}from"./components/armin.js";import{AssistantMessageComponent as U}from"./components/assistant-message.js";import{BashExecutionComponent as Q}from"./components/bash-execution.js";import{BorderedLoader as bt}from"./components/bordered-loader.js";import{BranchSummaryMessageComponent as Mt}from"./components/branch-summary-message.js";import{CompactionSummaryMessageComponent as xt}from"./components/compaction-summary-message.js";import{CountdownTimer as Tt}from"./components/countdown-timer.js";import{CustomEditor as $t}from"./components/custom-editor.js";import{CustomMessageComponent as Pt}from"./components/custom-message.js";import{DaxnutsComponent as At}from"./components/daxnuts.js";import{DynamicBorder as k}from"./components/dynamic-border.js";import{EarendilAnnouncementComponent as Rt}from"./components/earendil-announcement.js";import{ExtensionEditorComponent as vt}from"./components/extension-editor.js";import{ExtensionInputComponent as It}from"./components/extension-input.js";import{ExtensionSelectorComponent as X}from"./components/extension-selector.js";import{FooterComponent as Dt}from"./components/footer.js";import{formatKeyText as ce,keyDisplayText as ue,keyHint as ge,keyText as P,rawKeyHint as R}from"./components/keybinding-hints.js";import{LoginDialogComponent as J}from"./components/login-dialog.js";import{ModelSelectorComponent as Lt}from"./components/model-selector.js";import{OAuthSelectorComponent as pe}from"./components/oauth-selector.js";import{ScopedModelsSelectorComponent as Wt}from"./components/scoped-models-selector.js";import{SessionSelectorComponent as Ht}from"./components/session-selector.js";import{SettingsSelectorComponent as Ft}from"./components/settings-selector.js";import{SkillInvocationMessageComponent as qt}from"./components/skill-invocation-message.js";import{ToolExecutionComponent as H}from"./components/tool-execution.js";import{TreeSelectorComponent as Bt}from"./components/tree-selector.js";import{UserMessageComponent as me}from"./components/user-message.js";import{UserMessageSelectorComponent as Ut}from"./components/user-message-selector.js";import{getAvailableThemes as Ot,getAvailableThemesWithPaths as _t,getEditorTheme as fe,getMarkdownTheme as Nt,getThemeByName as Kt,initTheme as jt,onThemeChange as zt,setRegisteredThemes as Y,setTheme as O,setThemeInstance as Gt,stopThemeWatcher as Vt,Theme as Qt,theme as a}from"./theme/theme.js";function F(m){return typeof m=="object"&&m!==null&&"setExpanded"in m&&typeof m.setExpanded=="function"}h(F,"isExpandable");class Ce extends f{static{h(this,"ExpandableText")}getCollapsedText;getExpandedText;constructor(e,s,t=!1,i=0,n=0){super(t?s():e(),i,n),this.getCollapsedText=e,this.getExpandedText=s}setExpanded(e){this.setText(e?this.getExpandedText():this.getCollapsedText())}}const Xt=new Set(["EIO","EPIPE","ENOTCONN"]);function Jt(m){if(!m||typeof m!="object"||!("code"in m))return!1;const e=m.code;return e!==void 0&&Xt.has(e)}h(Jt,"isDeadTerminalError");const we="Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";function Yt(m){return typeof m=="string"&&m.startsWith("sk-ant-oat")}h(Yt,"isAnthropicSubscriptionAuthKey");function Zt(m){return!!m&&m.provider==="unknown"&&m.id==="unknown"&&m.api==="unknown"}h(Zt,"isUnknownModel");function es(m){return m.length>0&&!/[^a-zA-Z0-9_\-./~:@]/.test(m)?m:`'${m.replace(/'/g,"'\\''")}'`}h(es,"quoteIfNeeded");function ts(m){const e=Math.floor((Date.now()-m.getTime())/6e4);if(e<1)return"just now";if(e<60)return`${e}m ago`;const s=Math.floor(e/60);return s<24?`${s}h ago`:`${Math.floor(s/24)}d ago`}h(ts,"formatRelativeAge");function ss(m){if(!process.stdout.isTTY||!m.isPersisted())return;const e=m.getSessionFile();if(!e||!v.existsSync(e))return;const s=[z];return m.usesDefaultSessionDir()||s.push("--session-dir",es(m.getSessionDir())),s.push("--session",m.getSessionId()),s.join(" ")}h(ss,"formatResumeCommand");function is(m){return m in ie}h(is,"hasDefaultModelProvider");const ns="amazon-bedrock",os=new Set(qe());function rs(m,e,s=os){return ct[m]?!0:s.has(m)?!1:!e.has(m)}h(rs,"isApiKeyLoginProvider");class _{static{h(this,"InteractiveMode")}runtimeHost;ui;chatContainer;pendingMessagesContainer;statusContainer;defaultEditor;editor;editorComponentFactory;autocompleteProvider;autocompleteProviderWrappers=[];fdPath;editorContainer;footer;footerDataProvider;keybindings;version;isInitialized=!1;onInputCallback;pendingUserInputs=[];loadingAnimation=void 0;workingMessage=void 0;workingVisible=!0;workingIndicatorOptions=void 0;defaultWorkingMessage="Koda is working\u2026";_workStartTs=0;_workWord="Working";_workTicker;static WORK_WORDS=["Flummoxing","Cogitating","Noodling","Percolating","Conjuring","Wrangling","Finagling","Cookifying","Flibbertigibbeting","Discombobulating","Hornswoggling","Bamboozling","Marinating","Concocting","Spelunking","Tinkering","Befuddling","Whirring","Schlepping","Razzledazzling","Confabulating","Snazzifying","Galumphing","Kerfuffling","Bedazzling","Vibing","Churning","Brewing"];defaultHiddenThinkingLabel="Thinking...";hiddenThinkingLabel=this.defaultHiddenThinkingLabel;lastSigintTime=0;lastEscapeTime=0;changelogMarkdown=void 0;startupNoticesShown=!1;anthropicSubscriptionWarningShown=!1;lastStatusSpacer=void 0;lastStatusText=void 0;streamingComponent=void 0;streamingMessage=void 0;pendingTools=new Map;toolOutputExpanded=!1;hideThinkingBlock=!1;skillCommands=new Map;unsubscribe;signalCleanupHandlers=[];isBashMode=!1;bashComponent=void 0;pendingBashComponents=[];autoCompactionLoader=void 0;autoCompactionEscapeHandler;overseerEscapeHandler;compactionStartMs=0;compactionReason=void 0;compactionCancelHint="";compactionTicker=void 0;_kodaTitleBase="idle";_kodaReviewing=!1;retryLoader=void 0;overseerLoader=void 0;retryCountdown=void 0;retryEscapeHandler;compactionQueuedMessages=[];shutdownRequested=!1;extensionSelector=void 0;extensionInput=void 0;extensionEditor=void 0;extensionTerminalInputUnsubscribers=new Set;extensionWidgetsAbove=new Map;extensionWidgetsBelow=new Map;widgetContainerAbove;widgetContainerBelow;customFooter=void 0;headerContainer;builtInHeader=void 0;customHeader=void 0;options;get session(){return this.runtimeHost.session}get agent(){return this.session.agent}get sessionManager(){return this.session.sessionManager}get settingsManager(){return this.session.settingsManager}constructor(e,s={}){this.runtimeHost=e,this.options=s,this.runtimeHost.setBeforeSessionInvalidate(()=>{this.resetExtensionUI()}),this.runtimeHost.setRebindSession(async()=>{await this.rebindCurrentSession()}),this.version=L,this.ui=new ze(new Ke,this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.headerContainer=new A,this.chatContainer=new A,this.pendingMessagesContainer=new A,this.statusContainer=new A,this.widgetContainerAbove=new A,this.widgetContainerBelow=new A,this.keybindings=at.create(),je(this.keybindings);const t=this.settingsManager.getEditorPaddingX(),i=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor=new $t(this.ui,fe(),this.keybindings,{paddingX:t,autocompleteMaxVisible:i}),this.defaultEditor.title=this.kodaTitleText(),this.editor=this.defaultEditor,this.editorContainer=new A,this.editorContainer.addChild(this.editor),this.footerDataProvider=new ot(this.sessionManager.getCwd()),this.footer=new Dt(this.session,this.footerDataProvider),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),Y(this.session.resourceLoader.getThemes().themes),jt(this.settingsManager.getTheme(),!0)}getAutocompleteSourceTag(e){if(!e)return;const s=e.scope==="user"?"u":e.scope==="project"?"p":"t",t=e.source.trim();if(t==="auto"||t==="local"||t==="cli")return s;if(t.startsWith("npm:"))return`${s}:${t}`;const i=de(t);if(i){const n=i.ref?`@${i.ref}`:"";return`${s}:git:${i.host}/${i.path}${n}`}return s}prefixAutocompleteDescription(e,s){const t=this.getAutocompleteSourceTag(s);return t?e?`[${t}] ${e}`:`[${t}]`:e}getBuiltInCommandConflictDiagnostics(e){const s=new Set(re.map(t=>t.name));return e.getRegisteredCommands().filter(t=>s.has(t.name)).map(t=>({type:"warning",message:t.invocationName===t.name?`Extension command '/${t.name}' conflicts with built-in interactive command. Skipping in autocomplete.`:`Extension command '/${t.name}' conflicts with built-in interactive command. Available as '/${t.invocationName}'.`,path:t.sourceInfo.path}))}createBaseAutocompleteProvider(){const e=re.map(r=>({name:r.name,description:r.description})),s=e.find(r=>r.name==="model");s&&(s.getArgumentCompletions=r=>{const d=this.session.scopedModels.length>0?this.session.scopedModels.map(u=>u.model):this.session.modelRegistry.getAvailable();if(d.length===0)return null;const l=d.map(u=>({id:u.id,provider:u.provider,label:`${u.provider}/${u.id}`})),p=Ue(l,r,u=>`${u.id} ${u.provider}`);return p.length===0?null:p.map(u=>({value:u.label,label:u.id,description:u.provider}))});const t=this.session.promptTemplates.map(r=>({name:r.name,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo),...r.argumentHint&&{argumentHint:r.argumentHint}})),i=new Set(e.map(r=>r.name)),n=this.session.extensionRunner.getRegisteredCommands().filter(r=>!i.has(r.name)).map(r=>({name:r.invocationName,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo),getArgumentCompletions:r.getArgumentCompletions}));this.skillCommands.clear();const o=[];if(this.settingsManager.getEnableSkillCommands())for(const r of this.session.resourceLoader.getSkills().skills){const d=`skill:${r.name}`;this.skillCommands.set(d,r.filePath),o.push({name:d,description:this.prefixAutocompleteDescription(r.description,r.sourceInfo)})}return new Be([...e,...t,...n,...o],this.sessionManager.getCwd(),this.fdPath)}setupAutocompleteProvider(){let e=this.createBaseAutocompleteProvider();for(const s of this.autocompleteProviderWrappers)e=s(e);this.autocompleteProvider=e,this.defaultEditor.setAutocompleteProvider(e),this.editor!==this.defaultEditor&&this.editor.setAutocompleteProvider?.(e)}showStartupNoticesIfNeeded(){if(!this.startupNoticesShown&&(this.startupNoticesShown=!0,!!this.changelogMarkdown)){if(this.chatContainer.children.length>0&&this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.settingsManager.getCollapseChangelog()){const e=this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/),t=`Updated to v${e?e[1]:this.version}. Use ${a.bold("/changelog")} to view full changelog.`;this.chatContainer.addChild(new f(t,1,0))}else this.chatContainer.addChild(new f(a.bold(a.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new B(this.changelogMarkdown.trim(),1,0,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new g(1));this.chatContainer.addChild(new k)}}async init(){if(this.isInitialized)return;this.registerSignalHandlers(),this.changelogMarkdown=this.getChangelogForDisplay();const[e]=await Promise.all([le("fd"),le("rg")]);if(this.fdPath=e,this.session.scopedModels.length>0&&(this.options.verbose||!this.settingsManager.getQuietStartup())){const s=this.session.scopedModels.map(n=>{const o=n.thinkingLevel?`:${n.thinkingLevel}`:"";return`${n.model.id}${o}`}).join(", "),t=this.keybindings.getKeys("app.model.cycleForward"),i=t.length>0?a.fg("muted",` (${ce(t.join("/"),{capitalize:!0})} to cycle)`):"";console.log(a.fg("dim",`Model scope: ${s}${i}`))}if(this.ui.addChild(this.headerContainer),this.options.verbose||!this.settingsManager.getQuietStartup()){const s=["\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557","\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557","\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551","\u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551","\u2588\u2588\u2551 \u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551","\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D"].join(`
|
|
2
2
|
`),t=a.bold(a.fg("accent",s))+`
|
|
3
|
-
`+a.fg("dim",`v${
|
|
3
|
+
`+a.fg("dim",`v${st} \xB7 built for OpenAdapter`),i=h((l,p)=>ge(l,p),"hint"),n=[i("app.interrupt","to interrupt"),i("app.clear","to clear"),R(`${P("app.clear")} twice`,"to exit"),i("app.exit","to exit (empty)"),i("app.suspend","to suspend"),ge("tui.editor.deleteToLineEnd","to delete to end"),i("app.thinking.cycle","to cycle thinking level"),R(`${P("app.model.cycleForward")}/${P("app.model.cycleBackward")}`,"to cycle models"),i("app.model.select","to select model"),i("app.tools.expand","to expand tools"),i("app.thinking.toggle","to expand thinking"),i("app.editor.external","for external editor"),R("/","for commands"),R("!","to run bash"),R("!!","to run bash (no context)"),i("app.message.followUp","to queue follow-up"),i("app.message.dequeue","to edit all queued messages"),i("app.clipboard.pasteImage","to paste image"),R("drop files","to attach")].join(`
|
|
4
4
|
`),o=[i("app.interrupt","interrupt"),R(`${P("app.clear")}/${P("app.exit")}`,"clear/exit"),R("/","commands"),R("!","bash"),i("app.tools.expand","more")].join(a.fg("muted"," \xB7 ")),r=a.fg("dim",`Press ${P("app.tools.expand")} to show full startup help and loaded resources.`),d=a.fg("dim","Koda can explain its own features and look up its docs. Ask it how to use or extend Koda.");this.builtInHeader=new Ce(()=>`${t}
|
|
5
5
|
${o}
|
|
6
6
|
${r}
|
|
@@ -8,26 +8,26 @@ ${r}
|
|
|
8
8
|
${d}`,()=>`${t}
|
|
9
9
|
${n}
|
|
10
10
|
|
|
11
|
-
${d}`,this.getStartupExpansionState(),1,0),this.headerContainer.addChild(new g(1)),this.headerContainer.addChild(this.builtInHeader),this.headerContainer.addChild(new g(1))}else this.builtInHeader=new f("",0,0),this.headerContainer.addChild(this.builtInHeader);this.ui.addChild(this.chatContainer),this.ui.addChild(this.pendingMessagesContainer),this.ui.addChild(this.statusContainer),this.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(),this.ui.start(),this.isInitialized=!0,await this.rebindCurrentSession(),this.renderInitialMessages(),
|
|
11
|
+
${d}`,this.getStartupExpansionState(),1,0),this.headerContainer.addChild(new g(1)),this.headerContainer.addChild(this.builtInHeader),this.headerContainer.addChild(new g(1))}else this.builtInHeader=new f("",0,0),this.headerContainer.addChild(this.builtInHeader);this.ui.addChild(this.chatContainer),this.ui.addChild(this.pendingMessagesContainer),this.ui.addChild(this.statusContainer),this.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(),this.ui.start(),this.isInitialized=!0,await this.rebindCurrentSession(),this.renderInitialMessages(),zt(()=>{this.ui.invalidate(),this.updateEditorBorderColor(),this.ui.requestRender()}),this.footerDataProvider.onBranchChange(()=>{this.ui.requestRender()}),await this.updateAvailableProviderCount()}updateTerminalTitle(){const e=E.basename(this.sessionManager.getCwd()),s=this.sessionManager.getSessionName();s?this.ui.terminal.setTitle(`${te} - ${s} - ${e}`):this.ui.terminal.setTitle(`${te} - ${e}`)}async run(){await this.init(),Et(this.version).then(r=>{if(!r)return;const d=process.env.KODA_NO_AUTO_UPDATE!=="1";this.showNewVersionNotification(r,d),d&&pt().then(l=>{l?this.showStatus(`Updated to ${r.version} \u2014 restart koda to apply.`):this.showStatus(`Auto-update didn't finish \u2014 run \`koda update\` to get ${r.version}.`)})}),this.checkForPackageUpdates().then(r=>{r.length>0&&this.showPackageUpdateNotification(r)}),this.showResumeHintForCwd(),this.checkTmuxKeyboardSetup().then(r=>{r&&this.showWarning(r)});const{migratedProviders:e,modelFallbackMessage:s,initialMessage:t,initialImages:i,initialMessages:n}=this.options;e&&e.length>0&&this.showWarning(`Migrated credentials to auth.json: ${e.join(", ")}`);const o=this.session.modelRegistry.getError();if(o&&this.showError(`models.json error: ${o}`),s&&this.showWarning(s),this.maybeWarnAboutAnthropicSubscriptionAuth(),t)try{await this.session.prompt(t,{images:i})}catch(r){const d=r instanceof Error?r.message:"Unknown error occurred";this.showError(d)}if(n)for(const r of n)try{await this.session.prompt(r)}catch(d){const l=d instanceof Error?d.message:"Unknown error occurred";this.showError(l)}for(;;){const r=await this.getUserInput();try{await this.session.prompt(r)}catch(d){const l=d instanceof Error?d.message:"Unknown error occurred";this.showError(l)}}}async checkForPackageUpdates(){if(process.env.KODA_OFFLINE)return[];try{return(await new lt({cwd:this.sessionManager.getCwd(),agentDir:Ye(),settingsManager:this.settingsManager}).checkForAvailableUpdates()).map(t=>t.displayName)}catch{return[]}}async checkTmuxKeyboardSetup(){if(!process.env.TMUX)return;const e=h(i=>new Promise(n=>{const o=j("tmux",["show","-gv",i],{stdio:["ignore","pipe","ignore"]});let r="";const d=setTimeout(()=>{o.kill(),n(void 0)},2e3);o.stdout?.on("data",l=>{r+=l.toString()}),o.on("error",()=>{clearTimeout(d),n(void 0)}),o.on("close",l=>{clearTimeout(d),n(l===0?r.trim():void 0)})}),"runTmuxShow"),[s,t]=await Promise.all([e("extended-keys"),e("extended-keys-format")]);if(s!==void 0){if(s!=="on"&&s!=="always")return"tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.";if(t==="xterm")return"tmux extended-keys-format is xterm. Koda works best with csi-u. Add `set -g extended-keys-format csi-u` to ~/.tmux.conf and restart tmux."}}getChangelogForDisplay(){if(this.session.state.messages.length>0)return;const e=this.settingsManager.getLastChangelogVersion(),s=ae(),t=he(s);if(!e){this.settingsManager.setLastChangelogVersion(L),this.reportInstallTelemetry(L);return}const i=mt(t,e);if(i.length>0)return this.settingsManager.setLastChangelogVersion(L),this.reportInstallTelemetry(L),i.map(n=>n.content).join(`
|
|
12
12
|
|
|
13
|
-
`)}reportInstallTelemetry(e){process.env.KODA_OFFLINE||
|
|
14
|
-
${r} ${a.fg("muted",`${i}%`)} ${a.fg("dim",this.compactionCancelHint)}`}kodaTitleText(){const e=a;return this._kodaReviewing?e.bold(e.fg("accent","koda"))+e.fg("muted"," \xB7 reviewing\u2026"):this._kodaTitleBase==="beefed"?e.bold(e.fg("error","KODA \u2191 BEEFED UP")):this._kodaTitleBase==="rerouted"?e.bold(e.fg("warning","koda \xBB REROUTED")):e.bold(e.fg("accent","koda"))}updateKodaTitle(){this.defaultEditor.title=this.kodaTitleText(),this.ui.requestRender()}getCompactPathLabel(e,s){const t=this.getShortPath(e,s),n=t.replace(/\\/g,"/").split("/").filter(o=>o.length>0&&o!=="~");return n.length>0?n[n.length-1]:t}getCompactPackageSourceLabel(e){const s=e?.source??"";if(s.startsWith("npm:"))return s.slice(4)||s;const t=de(s);return t&&t.path||s}getCompactExtensionLabel(e,s){if(!this.isPackageSource(s))return this.getCompactPathLabel(e,s);const t=this.getCompactPackageSourceLabel(s);if(!t)return this.getCompactPathLabel(e,s);const i=this.getShortPath(e,s).replace(/\\/g,"/"),n=i.startsWith("extensions/")?i.slice(11):i,o=E.posix.parse(n);return o.name==="index"?!o.dir||o.dir==="."?t:`${t}:${o.dir}`:`${t}:${n}`}getCompactDisplayPathSegments(e){return this.formatDisplayPath(e).replace(/\\/g,"/").split("/").filter(s=>s.length>0&&s!=="~")}getCompactNonPackageExtensionLabel(e,s,t){const i=t[s]?.segments;if(!i||i.length===0)return this.getCompactPathLabel(e);for(let n=1;n<=i.length;n+=1){const o=i.slice(-n).join("/");if(t.every((d,l)=>l===s?!0:d.segments.slice(-n).join("/")!==o))return o}return i.join("/")}getCompactExtensionLabels(e){const s=e.map(t=>{const i=this.getCompactDisplayPathSegments(t.path),n=i[i.length-1];return i.length>1&&(n==="index.ts"||n==="index.js")&&i.pop(),{path:t.path,sourceInfo:t.sourceInfo,segments:i}}).filter(t=>!this.isPackageSource(t.sourceInfo));return e.map(t=>{if(this.isPackageSource(t.sourceInfo))return this.getCompactExtensionLabel(t.path,t.sourceInfo);const i=s.findIndex(n=>n.path===t.path);return i===-1?this.getCompactPathLabel(t.path,t.sourceInfo):this.getCompactNonPackageExtensionLabel(t.path,i,s)})}getDisplaySourceInfo(e){const s=e?.source??"local",t=e?.scope??"project";return s==="local"?t==="user"?{label:"user",color:"muted"}:t==="project"?{label:"project",color:"muted"}:t==="temporary"?{label:"path",scopeLabel:"temp",color:"muted"}:{label:"path",color:"muted"}:s==="cli"?{label:"path",scopeLabel:t==="temporary"?"temp":void 0,color:"muted"}:{label:s,scopeLabel:t==="user"?"user":t==="project"?"project":t==="temporary"?"temp":void 0,color:"accent"}}getScopeGroup(e){const s=e?.source??"local",t=e?.scope??"project";return s==="cli"||t==="temporary"?"path":t==="user"?"user":t==="project"?"project":"path"}isPackageSource(e){const s=e?.source??"";return s.startsWith("npm:")||s.startsWith("git:")}buildScopeGroups(e){const s={user:{scope:"user",paths:[],packages:new Map},project:{scope:"project",paths:[],packages:new Map},path:{scope:"path",paths:[],packages:new Map}};for(const t of e){const i=this.getScopeGroup(t.sourceInfo),n=s[i],o=t.sourceInfo?.source??"local";if(this.isPackageSource(t.sourceInfo)){const r=n.packages.get(o)??[];r.push(t),n.packages.set(o,r)}else n.paths.push(t)}return[s.project,s.user,s.path].filter(t=>t.paths.length>0||t.packages.size>0)}formatScopeGroups(e,s){const t=[];for(const i of e){t.push(` ${a.fg("accent",i.scope)}`);const n=[...i.paths].sort((r,d)=>r.path.localeCompare(d.path));for(const r of n)t.push(a.fg("dim",` ${s.formatPath(r)}`));const o=Array.from(i.packages.entries()).sort(([r],[d])=>r.localeCompare(d));for(const[r,d]of o){t.push(` ${a.fg("mdLink",r)}`);const l=[...d].sort((
|
|
13
|
+
`)}reportInstallTelemetry(e){process.env.KODA_OFFLINE||gt(this.settingsManager)&&fetch(`https://openadapter.in/api/report-install?version=${encodeURIComponent(e)}`,{headers:{"User-Agent":St(e)},signal:AbortSignal.timeout(5e3)}).then(()=>{}).catch(()=>{})}getMarkdownThemeWithSettings(){return{...Nt(),codeBlockIndent:this.settingsManager.getCodeBlockIndent()}}formatDisplayPath(e){const s=q.homedir();let t=e;return t.startsWith(s)&&(t=`~${t.slice(s.length)}`),t}formatExtensionDisplayPath(e){let s=this.formatDisplayPath(e);return s=s.replace(/\/index\.ts$/,"").replace(/\/index\.js$/,""),s}formatContextPath(e){const s=E.resolve(this.sessionManager.getCwd()),t=E.isAbsolute(e)?E.resolve(e):E.resolve(s,e),i=yt(t,s);return i!==void 0?i:this.formatDisplayPath(t)}getStartupExpansionState(){return this.options.verbose||this.toolOutputExpanded}getShortPath(e,s){const t=s?.baseDir;if(t&&this.isPackageSource(s)){const r=E.relative(E.resolve(t),E.resolve(e));if(r&&r!=="."&&!r.startsWith("..")&&!r.startsWith(`..${E.sep}`)&&!E.isAbsolute(r))return r.replace(/\\/g,"/")}const i=s?.source??"",n=e.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);if(n&&i.startsWith("npm:"))return n[2];const o=e.match(/git\/[^/]+\/[^/]+\/(.*)/);return o&&i.startsWith("git:")?o[1]:this.formatDisplayPath(e)}formatCompactElapsed(e){const s=Math.max(0,Math.floor(e/1e3)),t=Math.floor(s/60);return t>0?`${t}m ${s%60}s`:`${s}s`}buildCompactionLabel(){const e=this.compactionStartMs?Date.now()-this.compactionStartMs:0,s=this.formatCompactElapsed(e),t=e/1e3,i=Math.min(95,Math.round(95*(1-Math.exp(-t/11)))),n=24,o=Math.max(0,Math.min(n,Math.round(i/100*n))),r=a.fg("accent","\u25B0".repeat(o))+a.fg("dim","\u25B1".repeat(n-o)),d=this.compactionReason==="overflow"?"Context overflow \u2014 compacting":this.compactionReason==="manual"?"Compacting context":"Auto-compacting context";return`${a.fg("muted",`${d} (${s})`)}
|
|
14
|
+
${r} ${a.fg("muted",`${i}%`)} ${a.fg("dim",this.compactionCancelHint)}`}kodaTitleText(){const e=a;return this._kodaReviewing?e.bold(e.fg("accent","koda"))+e.fg("muted"," \xB7 reviewing\u2026"):this._kodaTitleBase==="beefed"?e.bold(e.fg("error","KODA \u2191 BEEFED UP")):this._kodaTitleBase==="rerouted"?e.bold(e.fg("warning","koda \xBB REROUTED")):e.bold(e.fg("accent","koda"))}updateKodaTitle(){this.defaultEditor.title=this.kodaTitleText(),this.ui.requestRender()}getCompactPathLabel(e,s){const t=this.getShortPath(e,s),n=t.replace(/\\/g,"/").split("/").filter(o=>o.length>0&&o!=="~");return n.length>0?n[n.length-1]:t}getCompactPackageSourceLabel(e){const s=e?.source??"";if(s.startsWith("npm:"))return s.slice(4)||s;const t=de(s);return t&&t.path||s}getCompactExtensionLabel(e,s){if(!this.isPackageSource(s))return this.getCompactPathLabel(e,s);const t=this.getCompactPackageSourceLabel(s);if(!t)return this.getCompactPathLabel(e,s);const i=this.getShortPath(e,s).replace(/\\/g,"/"),n=i.startsWith("extensions/")?i.slice(11):i,o=E.posix.parse(n);return o.name==="index"?!o.dir||o.dir==="."?t:`${t}:${o.dir}`:`${t}:${n}`}getCompactDisplayPathSegments(e){return this.formatDisplayPath(e).replace(/\\/g,"/").split("/").filter(s=>s.length>0&&s!=="~")}getCompactNonPackageExtensionLabel(e,s,t){const i=t[s]?.segments;if(!i||i.length===0)return this.getCompactPathLabel(e);for(let n=1;n<=i.length;n+=1){const o=i.slice(-n).join("/");if(t.every((d,l)=>l===s?!0:d.segments.slice(-n).join("/")!==o))return o}return i.join("/")}getCompactExtensionLabels(e){const s=e.map(t=>{const i=this.getCompactDisplayPathSegments(t.path),n=i[i.length-1];return i.length>1&&(n==="index.ts"||n==="index.js")&&i.pop(),{path:t.path,sourceInfo:t.sourceInfo,segments:i}}).filter(t=>!this.isPackageSource(t.sourceInfo));return e.map(t=>{if(this.isPackageSource(t.sourceInfo))return this.getCompactExtensionLabel(t.path,t.sourceInfo);const i=s.findIndex(n=>n.path===t.path);return i===-1?this.getCompactPathLabel(t.path,t.sourceInfo):this.getCompactNonPackageExtensionLabel(t.path,i,s)})}getDisplaySourceInfo(e){const s=e?.source??"local",t=e?.scope??"project";return s==="local"?t==="user"?{label:"user",color:"muted"}:t==="project"?{label:"project",color:"muted"}:t==="temporary"?{label:"path",scopeLabel:"temp",color:"muted"}:{label:"path",color:"muted"}:s==="cli"?{label:"path",scopeLabel:t==="temporary"?"temp":void 0,color:"muted"}:{label:s,scopeLabel:t==="user"?"user":t==="project"?"project":t==="temporary"?"temp":void 0,color:"accent"}}getScopeGroup(e){const s=e?.source??"local",t=e?.scope??"project";return s==="cli"||t==="temporary"?"path":t==="user"?"user":t==="project"?"project":"path"}isPackageSource(e){const s=e?.source??"";return s.startsWith("npm:")||s.startsWith("git:")}buildScopeGroups(e){const s={user:{scope:"user",paths:[],packages:new Map},project:{scope:"project",paths:[],packages:new Map},path:{scope:"path",paths:[],packages:new Map}};for(const t of e){const i=this.getScopeGroup(t.sourceInfo),n=s[i],o=t.sourceInfo?.source??"local";if(this.isPackageSource(t.sourceInfo)){const r=n.packages.get(o)??[];r.push(t),n.packages.set(o,r)}else n.paths.push(t)}return[s.project,s.user,s.path].filter(t=>t.paths.length>0||t.packages.size>0)}formatScopeGroups(e,s){const t=[];for(const i of e){t.push(` ${a.fg("accent",i.scope)}`);const n=[...i.paths].sort((r,d)=>r.path.localeCompare(d.path));for(const r of n)t.push(a.fg("dim",` ${s.formatPath(r)}`));const o=Array.from(i.packages.entries()).sort(([r],[d])=>r.localeCompare(d));for(const[r,d]of o){t.push(` ${a.fg("mdLink",r)}`);const l=[...d].sort((p,u)=>p.path.localeCompare(u.path));for(const p of l)t.push(a.fg("dim",` ${s.formatPackagePath(p,r)}`))}}return t.join(`
|
|
15
15
|
`)}findSourceInfoForPath(e,s){const t=s.get(e);if(t)return t;let i=e;for(;i.includes("/");){i=i.substring(0,i.lastIndexOf("/"));const n=s.get(i);if(n)return n}}formatPathWithSource(e,s){if(s){const t=this.getShortPath(e,s),{label:i,scopeLabel:n}=this.getDisplaySourceInfo(s);return`${n?`${i} (${n})`:i} ${t}`}return this.formatDisplayPath(e)}formatDiagnostics(e,s){const t=[],i=new Map,n=[];for(const o of e)if(o.type==="collision"&&o.collision){const r=i.get(o.collision.name)??[];r.push(o),i.set(o.collision.name,r)}else n.push(o);for(const[o,r]of i){const d=r[0]?.collision;if(d){t.push(a.fg("warning",` "${o}" collision:`)),t.push(a.fg("dim",` ${a.fg("success","\u2713")} ${this.formatPathWithSource(d.winnerPath,this.findSourceInfoForPath(d.winnerPath,s))}`));for(const l of r)l.collision&&t.push(a.fg("dim",` ${a.fg("warning","\u2717")} ${this.formatPathWithSource(l.collision.loserPath,this.findSourceInfoForPath(l.collision.loserPath,s))} (skipped)`))}}for(const o of n)if(o.path){const r=this.formatPathWithSource(o.path,this.findSourceInfoForPath(o.path,s));t.push(a.fg(o.type==="error"?"error":"warning",` ${r}`)),t.push(a.fg(o.type==="error"?"error":"warning",` ${o.message}`))}else t.push(a.fg(o.type==="error"?"error":"warning",` ${o.message}`));return t.join(`
|
|
16
16
|
`)}showLoadedResources(e){const s=e?.force||this.options.verbose||!this.settingsManager.getQuietStartup(),t=s||e?.showDiagnosticsWhenQuiet===!0;if(!s&&!t)return;const i=h((c,y="mdHeading")=>a.fg(y,`[${c}]`),"sectionHeader"),n=h((c,y)=>{const S=c.map(b=>b.trim()).filter(b=>b.length>0);return y?.sort!==!1&&S.sort((b,$)=>b.localeCompare($)),a.fg("dim",` ${S.join(", ")}`)},"formatCompactList"),o=h((c,y,S=y,b="mdHeading")=>{const $=new Ce(()=>`${i(c,b)}
|
|
17
17
|
${y}`,()=>`${i(c,b)}
|
|
18
|
-
${S}`,this.getStartupExpansionState(),0,0);this.chatContainer.addChild($),this.chatContainer.addChild(new g(1))},"addLoadedSection"),r=this.session.resourceLoader.getSkills(),d=this.session.resourceLoader.getPrompts(),l=this.session.resourceLoader.getThemes(),
|
|
19
|
-
`),
|
|
18
|
+
${S}`,this.getStartupExpansionState(),0,0);this.chatContainer.addChild($),this.chatContainer.addChild(new g(1))},"addLoadedSection"),r=this.session.resourceLoader.getSkills(),d=this.session.resourceLoader.getPrompts(),l=this.session.resourceLoader.getThemes(),p=e?.extensions??this.session.resourceLoader.getExtensions().extensions.map(c=>({path:c.path,sourceInfo:c.sourceInfo})),u=new Map;for(const c of p)c.sourceInfo&&u.set(c.path,c.sourceInfo);for(const c of r.skills)c.sourceInfo&&u.set(c.filePath,c.sourceInfo);for(const c of d.prompts)c.sourceInfo&&u.set(c.filePath,c.sourceInfo);for(const c of l.themes)c.sourcePath&&c.sourceInfo&&u.set(c.sourcePath,c.sourceInfo);if(s){const c=this.session.resourceLoader.getAgentsFiles().agentsFiles;if(c.length>0){this.chatContainer.addChild(new g(1));const M=c.map(w=>a.fg("dim",` ${this.formatDisplayPath(w.path)}`)).join(`
|
|
19
|
+
`),x=n(c.map(w=>this.formatContextPath(w.path)),{sort:!1});o("Context",x,M)}const y=r.skills;if(y.length>0){const M=this.buildScopeGroups(y.map(C=>({path:C.filePath,sourceInfo:C.sourceInfo}))),x=this.formatScopeGroups(M,{formatPath:h(C=>this.formatDisplayPath(C.path),"formatPath"),formatPackagePath:h(C=>this.getShortPath(C.path,C.sourceInfo),"formatPackagePath")}),w=n(y.map(C=>C.name));o("Skills",w,x)}const S=this.session.promptTemplates;if(S.length>0){const M=this.buildScopeGroups(S.map(T=>({path:T.filePath,sourceInfo:T.sourceInfo}))),x=new Map(S.map(T=>[T.filePath,T])),w=this.formatScopeGroups(M,{formatPath:h(T=>{const I=x.get(T.path);return I?`/${I.name}`:this.formatDisplayPath(T.path)},"formatPath"),formatPackagePath:h(T=>{const I=x.get(T.path);return I?`/${I.name}`:this.formatDisplayPath(T.path)},"formatPackagePath")}),C=n(S.map(T=>`/${T.name}`));o("Prompts",C,w)}if(p.length>0){const M=this.buildScopeGroups(p),x=this.formatScopeGroups(M,{formatPath:h(C=>this.formatExtensionDisplayPath(C.path),"formatPath"),formatPackagePath:h(C=>this.formatExtensionDisplayPath(this.getShortPath(C.path,C.sourceInfo)),"formatPackagePath")}),w=n(this.getCompactExtensionLabels(p));o("Extensions",w,x,"mdHeading")}const $=l.themes.filter(M=>M.sourcePath);if($.length>0){const M=this.buildScopeGroups($.map(C=>({path:C.sourcePath,sourceInfo:C.sourceInfo}))),x=this.formatScopeGroups(M,{formatPath:h(C=>this.formatDisplayPath(C.path),"formatPath"),formatPackagePath:h(C=>this.getShortPath(C.path,C.sourceInfo),"formatPackagePath")}),w=n($.map(C=>C.name??this.getCompactPathLabel(C.sourcePath,C.sourceInfo)));o("Themes",w,x)}}if(t){const c=r.diagnostics;if(c.length>0){const w=this.formatDiagnostics(c,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Skill conflicts]")}
|
|
20
20
|
${w}`,0,0)),this.chatContainer.addChild(new g(1))}const y=d.diagnostics;if(y.length>0){const w=this.formatDiagnostics(y,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Prompt conflicts]")}
|
|
21
|
-
${w}`,0,0)),this.chatContainer.addChild(new g(1))}const S=[],b=this.session.resourceLoader.getExtensions().errors;if(b.length>0)for(const w of b)S.push({type:"error",message:w.error,path:w.path});const $=this.session.extensionRunner.getCommandDiagnostics();S.push(...$),S.push(...this.getBuiltInCommandConflictDiagnostics(this.session.extensionRunner));const
|
|
22
|
-
${w}`,0,0)),this.chatContainer.addChild(new g(1))}const
|
|
23
|
-
${w}`,0,0)),this.chatContainer.addChild(new g(1))}}}async bindCurrentSessionExtensions(){const e=this.createExtensionUIContext();await this.session.bindExtensions({uiContext:e,mode:"tui",abortHandler:h(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"abortHandler"),commandContextActions:{waitForIdle:h(()=>this.session.agent.waitForIdle(),"waitForIdle"),newSession:h(async t=>{this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{const i=await this.runtimeHost.newSession(t);return i.cancelled||(this.renderCurrentSessionState(),this.ui.requestRender()),i}catch(i){return this.handleFatalRuntimeError("Failed to create session",i)}},"newSession"),fork:h(async(t,i)=>{try{const n=await this.runtimeHost.fork(t,i);return n.cancelled||(this.renderCurrentSessionState(),this.editor.setText(n.selectedText??""),this.showStatus("Forked to new session")),{cancelled:n.cancelled}}catch(n){return this.handleFatalRuntimeError("Failed to fork session",n)}},"fork"),navigateTree:h(async(t,i)=>{const n=await this.session.navigateTree(t,{summarize:i?.summarize,customInstructions:i?.customInstructions,replaceInstructions:i?.replaceInstructions,label:i?.label});return n.cancelled?{cancelled:!0}:(this.chatContainer.clear(),this.renderInitialMessages(),n.editorText&&!this.editor.getText().trim()&&this.editor.setText(n.editorText),this.showStatus("Navigated to selected point"),this.flushCompactionQueue({willRetry:!1}),{cancelled:!1})},"navigateTree"),switchSession:h(async(t,i)=>this.handleResumeSession(t,i),"switchSession"),reload:h(async()=>{await this.handleReloadCommand()},"reload")},shutdownHandler:h(()=>{this.shutdownRequested=!0,this.session.isStreaming||this.shutdown()},"shutdownHandler"),onError:h(t=>{this.showExtensionError(t.extensionPath,t.error,t.stack)},"onError")}),Y(this.session.resourceLoader.getThemes().themes),this.setupAutocompleteProvider();const s=this.session.extensionRunner;this.setupExtensionShortcuts(s),this.showLoadedResources({force:!1,showDiagnosticsWhenQuiet:!0}),this.showStartupNoticesIfNeeded()}applyRuntimeSettings(){G(this.settingsManager.getHttpIdleTimeoutMs()),this.footer.setSession(this.session),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.footerDataProvider.setCwd(this.sessionManager.getCwd()),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());const e=this.settingsManager.getEditorPaddingX(),s=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(e),this.defaultEditor.setAutocompleteMaxVisible(s),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(e),this.editor.setAutocompleteMaxVisible?.(s))}async rebindCurrentSession(){this.unsubscribe?.(),this.unsubscribe=void 0,this.applyRuntimeSettings(),await this.bindCurrentSessionExtensions(),this.subscribeToAgent(),await this.updateAvailableProviderCount(),this.updateEditorBorderColor(),this.updateTerminalTitle()}async handleFatalRuntimeError(e,s){const t=s instanceof Error?s.message:String(s);this.showError(`${e}: ${t}`),zt(),this.stop(),process.exit(1)}renderCurrentSessionState(){this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.compactionQueuedMessages=[],this.streamingComponent=void 0,this.streamingMessage=void 0,this.pendingTools.clear(),this.renderInitialMessages()}getRegisteredToolDefinition(e){return this.session.getToolDefinition(e)}setupExtensionShortcuts(e){const s=e.getShortcuts(this.keybindings.getEffectiveConfig());if(s.size===0)return;const t=h(()=>({ui:this.createExtensionUIContext(),mode:"tui",hasUI:!0,cwd:this.sessionManager.getCwd(),sessionManager:this.sessionManager,modelRegistry:this.session.modelRegistry,model:this.session.model,isIdle:h(()=>!this.session.isStreaming,"isIdle"),signal:this.session.agent.signal,abort:h(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"abort"),hasPendingMessages:h(()=>this.session.pendingMessageCount>0,"hasPendingMessages"),shutdown:h(()=>{this.shutdownRequested=!0},"shutdown"),getContextUsage:h(()=>this.session.getContextUsage(),"getContextUsage"),compact:h(i=>{(async()=>{try{const n=await this.session.compact(i?.customInstructions);i?.onComplete?.(n)}catch(n){const o=n instanceof Error?n:new Error(String(n));i?.onError?.(o)}})()},"compact"),getSystemPrompt:h(()=>this.session.systemPrompt,"getSystemPrompt")}),"createContext");this.defaultEditor.onExtensionShortcut=i=>{for(const[n,o]of s)if(Ne(i,n))return Promise.resolve(o.handler(t())).catch(r=>{this.showError(`Shortcut handler error: ${r instanceof Error?r.message:String(r)}`)}),!0;return!1}}setExtensionStatus(e,s){this.footerDataProvider.setExtensionStatus(e,s),this.ui.requestRender()}getWorkingLoaderMessage(){return this.workingMessage??this._workStatusText()}_pickWorkWord(){const e=_.WORK_WORDS;return e[Math.floor(Math.random()*e.length)]??"Working"}_workStatusText(){this._workStartTs||(this._workStartTs=Date.now());const e=Math.max(0,Math.floor((Date.now()-this._workStartTs)/1e3)),s=Math.floor(e/60),t=s>0?`${s}m ${e%60}s`:`${e}s`;let i="";try{const n=this.session.getContextUsage?.()?.tokens;n&&n>0&&(i=` \xB7 \u2191 ${n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)} tokens`)}catch{}return`${this._workWord}\u2026 (${t}${i})`}_startWorkTicker(){this._clearWorkTicker(),!this.workingMessage&&(this._workTicker=setInterval(()=>{if(!this.loadingAnimation){this._clearWorkTicker();return}const e=Math.floor((Date.now()-this._workStartTs)/1e3);e>0&&e%10===0&&(this._workWord=this._pickWorkWord()),this.loadingAnimation.setMessage(this._workStatusText()),this.ui.requestRender()},1e3))}_clearWorkTicker(){this._workTicker&&(clearInterval(this._workTicker),this._workTicker=void 0)}createWorkingLoader(){this._workStartTs=Date.now(),this._workWord=this._pickWorkWord();const e=new D(this.ui,s=>a.fg("accent",s),s=>a.fg("muted",s),this.getWorkingLoaderMessage(),this.workingIndicatorOptions);return this._startWorkTicker(),e}stopWorkingLoader(){this._clearWorkTicker(),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear()}setWorkingVisible(e){if(this.workingVisible=e,!e){this.stopWorkingLoader(),this.ui.requestRender();return}this.session.isStreaming&&!this.loadingAnimation&&(this.statusContainer.clear(),this.loadingAnimation=this.createWorkingLoader(),this.statusContainer.addChild(this.loadingAnimation)),this.ui.requestRender()}setWorkingIndicator(e){this.workingIndicatorOptions=e,this.loadingAnimation?.setIndicator(e),this.ui.requestRender()}setHiddenThinkingLabel(e){this.hiddenThinkingLabel=e??this.defaultHiddenThinkingLabel;for(const s of this.chatContainer.children)s instanceof U&&s.setHiddenThinkingLabel(this.hiddenThinkingLabel);this.streamingComponent&&this.streamingComponent.setHiddenThinkingLabel(this.hiddenThinkingLabel),this.ui.requestRender()}setExtensionWidget(e,s,t){const i=t?.placement??"aboveEditor",n=h(d=>{const l=d.get(e);l?.dispose&&l.dispose(),d.delete(e)},"removeExisting");if(n(this.extensionWidgetsAbove),n(this.extensionWidgetsBelow),s===void 0){this.renderWidgets();return}let o;if(Array.isArray(s)){const d=new A;for(const l of s.slice(0,_.MAX_WIDGET_LINES))d.addChild(new f(l,1,0));s.length>_.MAX_WIDGET_LINES&&d.addChild(new f(a.fg("muted","... (widget truncated)"),1,0)),o=d}else o=s(this.ui,a);(i==="belowEditor"?this.extensionWidgetsBelow:this.extensionWidgetsAbove).set(e,o),this.renderWidgets()}clearExtensionWidgets(){for(const e of this.extensionWidgetsAbove.values())e.dispose?.();for(const e of this.extensionWidgetsBelow.values())e.dispose?.();this.extensionWidgetsAbove.clear(),this.extensionWidgetsBelow.clear(),this.renderWidgets()}resetExtensionUI(){this.extensionSelector&&this.hideExtensionSelector(),this.extensionInput&&this.hideExtensionInput(),this.extensionEditor&&this.hideExtensionEditor(),this.ui.hideOverlay(),this.clearExtensionTerminalInputListeners(),this.setExtensionFooter(void 0),this.setExtensionHeader(void 0),this.clearExtensionWidgets(),this.footerDataProvider.clearExtensionStatuses(),this.footer.invalidate(),this.autocompleteProviderWrappers=[],this.setCustomEditorComponent(void 0),this.setupAutocompleteProvider(),this.defaultEditor.onExtensionShortcut=void 0,this.updateTerminalTitle(),this.workingMessage=void 0,this.workingVisible=!0,this.setWorkingIndicator(),this.loadingAnimation&&this.loadingAnimation.setMessage(`${this.defaultWorkingMessage} (${P("app.interrupt")} to interrupt)`),this.setHiddenThinkingLabel()}static MAX_WIDGET_LINES=10;renderWidgets(){!this.widgetContainerAbove||!this.widgetContainerBelow||(this.renderWidgetContainer(this.widgetContainerAbove,this.extensionWidgetsAbove,!0,!0),this.renderWidgetContainer(this.widgetContainerBelow,this.extensionWidgetsBelow,!1,!1),this.ui.requestRender())}renderWidgetContainer(e,s,t,i){if(e.clear(),s.size===0){t&&e.addChild(new g(1));return}i&&e.addChild(new g(1));for(const n of s.values())e.addChild(n)}setExtensionFooter(e){this.customFooter?.dispose&&this.customFooter.dispose(),this.customFooter?this.ui.removeChild(this.customFooter):this.ui.removeChild(this.footer),e?(this.customFooter=e(this.ui,a,this.footerDataProvider),this.ui.addChild(this.customFooter)):(this.customFooter=void 0,this.ui.addChild(this.footer)),this.ui.requestRender()}setExtensionHeader(e){if(!this.builtInHeader)return;this.customHeader?.dispose&&this.customHeader.dispose();const s=this.customHeader||this.builtInHeader,t=this.headerContainer.children.indexOf(s);e?(this.customHeader=e(this.ui,a),H(this.customHeader)&&this.customHeader.setExpanded(this.toolOutputExpanded),t!==-1?this.headerContainer.children[t]=this.customHeader:this.headerContainer.children.unshift(this.customHeader)):(this.customHeader=void 0,H(this.builtInHeader)&&this.builtInHeader.setExpanded(this.toolOutputExpanded),t!==-1&&(this.headerContainer.children[t]=this.builtInHeader)),this.ui.requestRender()}addExtensionTerminalInputListener(e){const s=this.ui.addInputListener(e);return this.extensionTerminalInputUnsubscribers.add(s),()=>{s(),this.extensionTerminalInputUnsubscribers.delete(s)}}clearExtensionTerminalInputListeners(){for(const e of this.extensionTerminalInputUnsubscribers)e();this.extensionTerminalInputUnsubscribers.clear()}createExtensionUIContext(){return{select:h((e,s,t)=>this.showExtensionSelector(e,s,t),"select"),confirm:h((e,s,t)=>this.showExtensionConfirm(e,s,t),"confirm"),input:h((e,s,t)=>this.showExtensionInput(e,s,t),"input"),notify:h((e,s)=>this.showExtensionNotify(e,s),"notify"),onTerminalInput:h(e=>this.addExtensionTerminalInputListener(e),"onTerminalInput"),setStatus:h((e,s)=>this.setExtensionStatus(e,s),"setStatus"),setWorkingMessage:h(e=>{this.workingMessage=e,this.loadingAnimation&&this.loadingAnimation.setMessage(e??this.defaultWorkingMessage)},"setWorkingMessage"),setWorkingVisible:h(e=>this.setWorkingVisible(e),"setWorkingVisible"),setWorkingIndicator:h(e=>this.setWorkingIndicator(e),"setWorkingIndicator"),setHiddenThinkingLabel:h(e=>this.setHiddenThinkingLabel(e),"setHiddenThinkingLabel"),setWidget:h((e,s,t)=>this.setExtensionWidget(e,s,t),"setWidget"),setFooter:h(e=>this.setExtensionFooter(e),"setFooter"),setHeader:h(e=>this.setExtensionHeader(e),"setHeader"),setTitle:h(e=>this.ui.terminal.setTitle(e),"setTitle"),custom:h((e,s)=>this.showExtensionCustom(e,s),"custom"),pasteToEditor:h(e=>this.editor.handleInput(`\x1B[200~${e}\x1B[201~`),"pasteToEditor"),setEditorText:h(e=>this.editor.setText(e),"setEditorText"),getEditorText:h(()=>this.editor.getExpandedText?.()??this.editor.getText(),"getEditorText"),editor:h((e,s)=>this.showExtensionEditor(e,s),"editor"),addAutocompleteProvider:h(e=>{this.autocompleteProviderWrappers.push(e),this.setupAutocompleteProvider()},"addAutocompleteProvider"),setEditorComponent:h(e=>this.setCustomEditorComponent(e),"setEditorComponent"),getEditorComponent:h(()=>this.editorComponentFactory,"getEditorComponent"),get theme(){return a},getAllThemes:h(()=>Ut(),"getAllThemes"),getTheme:h(e=>_t(e),"getTheme"),setTheme:h(e=>{if(e instanceof Gt)return jt(e),this.ui.requestRender(),{success:!0};const s=O(e,!0);return s.success&&(this.settingsManager.getTheme()!==e&&this.settingsManager.setTheme(e),this.ui.requestRender()),s},"setTheme"),getToolsExpanded:h(()=>this.toolOutputExpanded,"getToolsExpanded"),setToolsExpanded:h(e=>this.setToolsExpanded(e),"setToolsExpanded")}}showExtensionSelector(e,s,t){return new Promise(i=>{if(t?.signal?.aborted){i(void 0);return}const n=h(()=>{this.hideExtensionSelector(),i(void 0)},"onAbort");t?.signal?.addEventListener("abort",n,{once:!0}),this.extensionSelector=new X(e,s,o=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionSelector(),i(o)},()=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionSelector(),i(void 0)},{tui:this.ui,timeout:t?.timeout,onToggleToolsExpanded:h(()=>this.toggleToolOutputExpansion(),"onToggleToolsExpanded")}),this.editorContainer.clear(),this.editorContainer.addChild(this.extensionSelector),this.ui.setFocus(this.extensionSelector),this.ui.requestRender()})}hideExtensionSelector(){this.extensionSelector?.dispose(),this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.extensionSelector=void 0,this.ui.setFocus(this.editor),this.ui.requestRender()}async showExtensionConfirm(e,s,t){return await this.showExtensionSelector(`${e}
|
|
24
|
-
${s}`,["Yes","No"],t)==="Yes"}async promptForMissingSessionCwd(e){return await this.showExtensionConfirm("Session cwd not found",
|
|
21
|
+
${w}`,0,0)),this.chatContainer.addChild(new g(1))}const S=[],b=this.session.resourceLoader.getExtensions().errors;if(b.length>0)for(const w of b)S.push({type:"error",message:w.error,path:w.path});const $=this.session.extensionRunner.getCommandDiagnostics();S.push(...$),S.push(...this.getBuiltInCommandConflictDiagnostics(this.session.extensionRunner));const M=this.session.extensionRunner.getShortcutDiagnostics();if(S.push(...M),S.length>0){const w=this.formatDiagnostics(S,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Extension issues]")}
|
|
22
|
+
${w}`,0,0)),this.chatContainer.addChild(new g(1))}const x=l.diagnostics;if(x.length>0){const w=this.formatDiagnostics(x,u);this.chatContainer.addChild(new f(`${a.fg("warning","[Theme conflicts]")}
|
|
23
|
+
${w}`,0,0)),this.chatContainer.addChild(new g(1))}}}async bindCurrentSessionExtensions(){const e=this.createExtensionUIContext();await this.session.bindExtensions({uiContext:e,mode:"tui",abortHandler:h(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"abortHandler"),commandContextActions:{waitForIdle:h(()=>this.session.agent.waitForIdle(),"waitForIdle"),newSession:h(async t=>{this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{const i=await this.runtimeHost.newSession(t);return i.cancelled||(this.renderCurrentSessionState(),this.ui.requestRender()),i}catch(i){return this.handleFatalRuntimeError("Failed to create session",i)}},"newSession"),fork:h(async(t,i)=>{try{const n=await this.runtimeHost.fork(t,i);return n.cancelled||(this.renderCurrentSessionState(),this.editor.setText(n.selectedText??""),this.showStatus("Forked to new session")),{cancelled:n.cancelled}}catch(n){return this.handleFatalRuntimeError("Failed to fork session",n)}},"fork"),navigateTree:h(async(t,i)=>{const n=await this.session.navigateTree(t,{summarize:i?.summarize,customInstructions:i?.customInstructions,replaceInstructions:i?.replaceInstructions,label:i?.label});return n.cancelled?{cancelled:!0}:(this.chatContainer.clear(),this.renderInitialMessages(),n.editorText&&!this.editor.getText().trim()&&this.editor.setText(n.editorText),this.showStatus("Navigated to selected point"),this.flushCompactionQueue({willRetry:!1}),{cancelled:!1})},"navigateTree"),switchSession:h(async(t,i)=>this.handleResumeSession(t,i),"switchSession"),reload:h(async()=>{await this.handleReloadCommand()},"reload")},shutdownHandler:h(()=>{this.shutdownRequested=!0,this.session.isStreaming||this.shutdown()},"shutdownHandler"),onError:h(t=>{this.showExtensionError(t.extensionPath,t.error,t.stack)},"onError")}),Y(this.session.resourceLoader.getThemes().themes),this.setupAutocompleteProvider();const s=this.session.extensionRunner;this.setupExtensionShortcuts(s),this.showLoadedResources({force:!1,showDiagnosticsWhenQuiet:!0}),this.showStartupNoticesIfNeeded()}applyRuntimeSettings(){G(this.settingsManager.getHttpIdleTimeoutMs()),this.footer.setSession(this.session),this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled),this.footerDataProvider.setCwd(this.sessionManager.getCwd()),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock(),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());const e=this.settingsManager.getEditorPaddingX(),s=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(e),this.defaultEditor.setAutocompleteMaxVisible(s),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(e),this.editor.setAutocompleteMaxVisible?.(s))}async rebindCurrentSession(){this.unsubscribe?.(),this.unsubscribe=void 0,this.applyRuntimeSettings(),await this.bindCurrentSessionExtensions(),this.subscribeToAgent(),await this.updateAvailableProviderCount(),this.updateEditorBorderColor(),this.updateTerminalTitle()}async handleFatalRuntimeError(e,s){const t=s instanceof Error?s.message:String(s);this.showError(`${e}: ${t}`),Vt(),this.stop(),process.exit(1)}renderCurrentSessionState(){this.chatContainer.clear(),this.pendingMessagesContainer.clear(),this.compactionQueuedMessages=[],this.streamingComponent=void 0,this.streamingMessage=void 0,this.pendingTools.clear(),this.renderInitialMessages()}getRegisteredToolDefinition(e){return this.session.getToolDefinition(e)}setupExtensionShortcuts(e){const s=e.getShortcuts(this.keybindings.getEffectiveConfig());if(s.size===0)return;const t=h(()=>({ui:this.createExtensionUIContext(),mode:"tui",hasUI:!0,cwd:this.sessionManager.getCwd(),sessionManager:this.sessionManager,modelRegistry:this.session.modelRegistry,model:this.session.model,isIdle:h(()=>!this.session.isStreaming,"isIdle"),signal:this.session.agent.signal,abort:h(()=>{this.restoreQueuedMessagesToEditor({abort:!0})},"abort"),hasPendingMessages:h(()=>this.session.pendingMessageCount>0,"hasPendingMessages"),shutdown:h(()=>{this.shutdownRequested=!0},"shutdown"),getContextUsage:h(()=>this.session.getContextUsage(),"getContextUsage"),compact:h(i=>{(async()=>{try{const n=await this.session.compact(i?.customInstructions);i?.onComplete?.(n)}catch(n){const o=n instanceof Error?n:new Error(String(n));i?.onError?.(o)}})()},"compact"),getSystemPrompt:h(()=>this.session.systemPrompt,"getSystemPrompt")}),"createContext");this.defaultEditor.onExtensionShortcut=i=>{for(const[n,o]of s)if(Ne(i,n))return Promise.resolve(o.handler(t())).catch(r=>{this.showError(`Shortcut handler error: ${r instanceof Error?r.message:String(r)}`)}),!0;return!1}}setExtensionStatus(e,s){this.footerDataProvider.setExtensionStatus(e,s),this.ui.requestRender()}getWorkingLoaderMessage(){return this.workingMessage??this._workStatusText()}_pickWorkWord(){const e=_.WORK_WORDS;return e[Math.floor(Math.random()*e.length)]??"Working"}_workStatusText(){this._workStartTs||(this._workStartTs=Date.now());const e=Math.max(0,Math.floor((Date.now()-this._workStartTs)/1e3)),s=Math.floor(e/60),t=s>0?`${s}m ${e%60}s`:`${e}s`;let i="";try{const n=this.session.getContextUsage?.()?.tokens;n&&n>0&&(i=` \xB7 \u2191 ${n>=1e6?`${(n/1e6).toFixed(1)}M`:n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n)} tokens`)}catch{}return`${this._workWord}\u2026 (${t}${i})`}_startWorkTicker(){this._clearWorkTicker(),!this.workingMessage&&(this._workTicker=setInterval(()=>{if(!this.loadingAnimation){this._clearWorkTicker();return}const e=Math.floor((Date.now()-this._workStartTs)/1e3);e>0&&e%10===0&&(this._workWord=this._pickWorkWord()),this.loadingAnimation.setMessage(this._workStatusText()),this.ui.requestRender()},1e3))}_clearWorkTicker(){this._workTicker&&(clearInterval(this._workTicker),this._workTicker=void 0)}createWorkingLoader(){this._workStartTs=Date.now(),this._workWord=this._pickWorkWord();const e=new D(this.ui,s=>a.fg("accent",s),s=>a.fg("muted",s),this.getWorkingLoaderMessage(),this.workingIndicatorOptions);return this._startWorkTicker(),e}stopWorkingLoader(){this._clearWorkTicker(),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear()}setWorkingVisible(e){if(this.workingVisible=e,!e){this.stopWorkingLoader(),this.ui.requestRender();return}this.session.isStreaming&&!this.loadingAnimation&&(this.statusContainer.clear(),this.loadingAnimation=this.createWorkingLoader(),this.statusContainer.addChild(this.loadingAnimation)),this.ui.requestRender()}setWorkingIndicator(e){this.workingIndicatorOptions=e,this.loadingAnimation?.setIndicator(e),this.ui.requestRender()}setHiddenThinkingLabel(e){this.hiddenThinkingLabel=e??this.defaultHiddenThinkingLabel;for(const s of this.chatContainer.children)s instanceof U&&s.setHiddenThinkingLabel(this.hiddenThinkingLabel);this.streamingComponent&&this.streamingComponent.setHiddenThinkingLabel(this.hiddenThinkingLabel),this.ui.requestRender()}setExtensionWidget(e,s,t){const i=t?.placement??"aboveEditor",n=h(d=>{const l=d.get(e);l?.dispose&&l.dispose(),d.delete(e)},"removeExisting");if(n(this.extensionWidgetsAbove),n(this.extensionWidgetsBelow),s===void 0){this.renderWidgets();return}let o;if(Array.isArray(s)){const d=new A;for(const l of s.slice(0,_.MAX_WIDGET_LINES))d.addChild(new f(l,1,0));s.length>_.MAX_WIDGET_LINES&&d.addChild(new f(a.fg("muted","... (widget truncated)"),1,0)),o=d}else o=s(this.ui,a);(i==="belowEditor"?this.extensionWidgetsBelow:this.extensionWidgetsAbove).set(e,o),this.renderWidgets()}clearExtensionWidgets(){for(const e of this.extensionWidgetsAbove.values())e.dispose?.();for(const e of this.extensionWidgetsBelow.values())e.dispose?.();this.extensionWidgetsAbove.clear(),this.extensionWidgetsBelow.clear(),this.renderWidgets()}resetExtensionUI(){this.extensionSelector&&this.hideExtensionSelector(),this.extensionInput&&this.hideExtensionInput(),this.extensionEditor&&this.hideExtensionEditor(),this.ui.hideOverlay(),this.clearExtensionTerminalInputListeners(),this.setExtensionFooter(void 0),this.setExtensionHeader(void 0),this.clearExtensionWidgets(),this.footerDataProvider.clearExtensionStatuses(),this.footer.invalidate(),this.autocompleteProviderWrappers=[],this.setCustomEditorComponent(void 0),this.setupAutocompleteProvider(),this.defaultEditor.onExtensionShortcut=void 0,this.updateTerminalTitle(),this.workingMessage=void 0,this.workingVisible=!0,this.setWorkingIndicator(),this.loadingAnimation&&this.loadingAnimation.setMessage(`${this.defaultWorkingMessage} (${P("app.interrupt")} to interrupt)`),this.setHiddenThinkingLabel()}static MAX_WIDGET_LINES=10;renderWidgets(){!this.widgetContainerAbove||!this.widgetContainerBelow||(this.renderWidgetContainer(this.widgetContainerAbove,this.extensionWidgetsAbove,!0,!0),this.renderWidgetContainer(this.widgetContainerBelow,this.extensionWidgetsBelow,!1,!1),this.ui.requestRender())}renderWidgetContainer(e,s,t,i){if(e.clear(),s.size===0){t&&e.addChild(new g(1));return}i&&e.addChild(new g(1));for(const n of s.values())e.addChild(n)}setExtensionFooter(e){this.customFooter?.dispose&&this.customFooter.dispose(),this.customFooter?this.ui.removeChild(this.customFooter):this.ui.removeChild(this.footer),e?(this.customFooter=e(this.ui,a,this.footerDataProvider),this.ui.addChild(this.customFooter)):(this.customFooter=void 0,this.ui.addChild(this.footer)),this.ui.requestRender()}setExtensionHeader(e){if(!this.builtInHeader)return;this.customHeader?.dispose&&this.customHeader.dispose();const s=this.customHeader||this.builtInHeader,t=this.headerContainer.children.indexOf(s);e?(this.customHeader=e(this.ui,a),F(this.customHeader)&&this.customHeader.setExpanded(this.toolOutputExpanded),t!==-1?this.headerContainer.children[t]=this.customHeader:this.headerContainer.children.unshift(this.customHeader)):(this.customHeader=void 0,F(this.builtInHeader)&&this.builtInHeader.setExpanded(this.toolOutputExpanded),t!==-1&&(this.headerContainer.children[t]=this.builtInHeader)),this.ui.requestRender()}addExtensionTerminalInputListener(e){const s=this.ui.addInputListener(e);return this.extensionTerminalInputUnsubscribers.add(s),()=>{s(),this.extensionTerminalInputUnsubscribers.delete(s)}}clearExtensionTerminalInputListeners(){for(const e of this.extensionTerminalInputUnsubscribers)e();this.extensionTerminalInputUnsubscribers.clear()}createExtensionUIContext(){return{select:h((e,s,t)=>this.showExtensionSelector(e,s,t),"select"),confirm:h((e,s,t)=>this.showExtensionConfirm(e,s,t),"confirm"),input:h((e,s,t)=>this.showExtensionInput(e,s,t),"input"),notify:h((e,s)=>this.showExtensionNotify(e,s),"notify"),onTerminalInput:h(e=>this.addExtensionTerminalInputListener(e),"onTerminalInput"),setStatus:h((e,s)=>this.setExtensionStatus(e,s),"setStatus"),setWorkingMessage:h(e=>{this.workingMessage=e,this.loadingAnimation&&this.loadingAnimation.setMessage(e??this.defaultWorkingMessage)},"setWorkingMessage"),setWorkingVisible:h(e=>this.setWorkingVisible(e),"setWorkingVisible"),setWorkingIndicator:h(e=>this.setWorkingIndicator(e),"setWorkingIndicator"),setHiddenThinkingLabel:h(e=>this.setHiddenThinkingLabel(e),"setHiddenThinkingLabel"),setWidget:h((e,s,t)=>this.setExtensionWidget(e,s,t),"setWidget"),setFooter:h(e=>this.setExtensionFooter(e),"setFooter"),setHeader:h(e=>this.setExtensionHeader(e),"setHeader"),setTitle:h(e=>this.ui.terminal.setTitle(e),"setTitle"),custom:h((e,s)=>this.showExtensionCustom(e,s),"custom"),pasteToEditor:h(e=>this.editor.handleInput(`\x1B[200~${e}\x1B[201~`),"pasteToEditor"),setEditorText:h(e=>this.editor.setText(e),"setEditorText"),getEditorText:h(()=>this.editor.getExpandedText?.()??this.editor.getText(),"getEditorText"),editor:h((e,s)=>this.showExtensionEditor(e,s),"editor"),addAutocompleteProvider:h(e=>{this.autocompleteProviderWrappers.push(e),this.setupAutocompleteProvider()},"addAutocompleteProvider"),setEditorComponent:h(e=>this.setCustomEditorComponent(e),"setEditorComponent"),getEditorComponent:h(()=>this.editorComponentFactory,"getEditorComponent"),get theme(){return a},getAllThemes:h(()=>_t(),"getAllThemes"),getTheme:h(e=>Kt(e),"getTheme"),setTheme:h(e=>{if(e instanceof Qt)return Gt(e),this.ui.requestRender(),{success:!0};const s=O(e,!0);return s.success&&(this.settingsManager.getTheme()!==e&&this.settingsManager.setTheme(e),this.ui.requestRender()),s},"setTheme"),getToolsExpanded:h(()=>this.toolOutputExpanded,"getToolsExpanded"),setToolsExpanded:h(e=>this.setToolsExpanded(e),"setToolsExpanded")}}showExtensionSelector(e,s,t){return new Promise(i=>{if(t?.signal?.aborted){i(void 0);return}const n=h(()=>{this.hideExtensionSelector(),i(void 0)},"onAbort");t?.signal?.addEventListener("abort",n,{once:!0}),this.extensionSelector=new X(e,s,o=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionSelector(),i(o)},()=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionSelector(),i(void 0)},{tui:this.ui,timeout:t?.timeout,onToggleToolsExpanded:h(()=>this.toggleToolOutputExpansion(),"onToggleToolsExpanded")}),this.editorContainer.clear(),this.editorContainer.addChild(this.extensionSelector),this.ui.setFocus(this.extensionSelector),this.ui.requestRender()})}hideExtensionSelector(){this.extensionSelector?.dispose(),this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.extensionSelector=void 0,this.ui.setFocus(this.editor),this.ui.requestRender()}async showExtensionConfirm(e,s,t){return await this.showExtensionSelector(`${e}
|
|
24
|
+
${s}`,["Yes","No"],t)==="Yes"}async promptForMissingSessionCwd(e){return await this.showExtensionConfirm("Session cwd not found",ut(e.issue))?e.issue.fallbackCwd:void 0}showExtensionInput(e,s,t){return new Promise(i=>{if(t?.signal?.aborted){i(void 0);return}const n=h(()=>{this.hideExtensionInput(),i(void 0)},"onAbort");t?.signal?.addEventListener("abort",n,{once:!0}),this.extensionInput=new It(e,s,o=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionInput(),i(o)},()=>{t?.signal?.removeEventListener("abort",n),this.hideExtensionInput(),i(void 0)},{tui:this.ui,timeout:t?.timeout}),this.editorContainer.clear(),this.editorContainer.addChild(this.extensionInput),this.ui.setFocus(this.extensionInput),this.ui.requestRender()})}hideExtensionInput(){this.extensionInput?.dispose(),this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.extensionInput=void 0,this.ui.setFocus(this.editor),this.ui.requestRender()}showExtensionEditor(e,s){return new Promise(t=>{this.extensionEditor=new vt(this.ui,this.keybindings,e,s,i=>{this.hideExtensionEditor(),t(i)},()=>{this.hideExtensionEditor(),t(void 0)}),this.editorContainer.clear(),this.editorContainer.addChild(this.extensionEditor),this.ui.setFocus(this.extensionEditor),this.ui.requestRender()})}hideExtensionEditor(){this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.extensionEditor=void 0,this.ui.setFocus(this.editor),this.ui.requestRender()}setCustomEditorComponent(e){this.editorComponentFactory=e;const s=this.editor.getText();if(this.editorContainer.clear(),e){const t=e(this.ui,fe(),this.keybindings);t.onSubmit=this.defaultEditor.onSubmit,t.onChange=this.defaultEditor.onChange,t.setText(s),t.borderColor!==void 0&&(t.borderColor=this.defaultEditor.borderColor),t.setPaddingX!==void 0&&t.setPaddingX(this.defaultEditor.getPaddingX()),t.setAutocompleteProvider&&this.autocompleteProvider&&t.setAutocompleteProvider(this.autocompleteProvider);const i=t;if("actionHandlers"in i&&i.actionHandlers instanceof Map){i.onEscape||(i.onEscape=()=>this.defaultEditor.onEscape?.()),i.onCtrlD||(i.onCtrlD=()=>this.defaultEditor.onCtrlD?.()),i.onPasteImage||(i.onPasteImage=()=>this.defaultEditor.onPasteImage?.()),i.onExtensionShortcut||(i.onExtensionShortcut=n=>this.defaultEditor.onExtensionShortcut?.(n));for(const[n,o]of this.defaultEditor.actionHandlers)i.actionHandlers.set(n,o)}this.editor=t}else this.defaultEditor.setText(s),this.editor=this.defaultEditor;this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()}showExtensionNotify(e,s){s==="error"?this.showError(e):s==="warning"?this.showWarning(e):this.showStatus(e)}async showExtensionCustom(e,s){const t=this.editor.getText(),i=s?.overlay??!1,n=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.editor.setText(t),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");return new Promise((o,r)=>{let d,l=!1;const p=h(u=>{if(!l){l=!0,i?this.ui.hideOverlay():n(),o(u);try{d?.dispose?.()}catch{}}},"close");Promise.resolve(e(this.ui,a,this.keybindings,p)).then(u=>{if(!l)if(d=u,i){const c=h(()=>{if(s?.overlayOptions)return typeof s.overlayOptions=="function"?s.overlayOptions():s.overlayOptions;const S=d.width;return S?{width:S}:void 0},"resolveOptions"),y=this.ui.showOverlay(d,c());s?.onHandle?.(y)}else this.editorContainer.clear(),this.editorContainer.addChild(d),this.ui.setFocus(d),this.ui.requestRender()}).catch(u=>{l||(i||n(),r(u))})})}showExtensionError(e,s,t){const i=`Extension "${e}" error: ${s}`,n=new f(a.fg("error",i),1,0);if(this.chatContainer.addChild(n),t){const o=t.split(`
|
|
25
25
|
`).slice(1).map(r=>a.fg("dim",` ${r.trim()}`)).join(`
|
|
26
|
-
`);o&&this.chatContainer.addChild(new f(o,1,0))}this.ui.requestRender()}setupKeyHandlers(){this.defaultEditor.onEscape=()=>{if(this.session.isStreaming)this.restoreQueuedMessagesToEditor({abort:!0});else if(this.session.isBashRunning)this.session.abortBash();else if(this.isBashMode)this.editor.setText(""),this.isBashMode=!1,this.updateEditorBorderColor();else if(!this.editor.getText().trim()){const e=this.settingsManager.getDoubleEscapeAction();if(e!=="none"){const s=Date.now();s-this.lastEscapeTime<500?(e==="tree"?this.showTreeSelector():this.showUserMessageSelector(),this.lastEscapeTime=0):this.lastEscapeTime=s}}},this.defaultEditor.onAction("app.clear",()=>this.handleCtrlC()),this.defaultEditor.onCtrlD=()=>this.handleCtrlD(),this.defaultEditor.onAction("app.suspend",()=>this.handleCtrlZ()),this.defaultEditor.onAction("app.thinking.cycle",()=>this.cycleThinkingLevel()),this.defaultEditor.onAction("app.model.cycleForward",()=>this.cycleModel("forward")),this.defaultEditor.onAction("app.model.cycleBackward",()=>this.cycleModel("backward")),this.ui.onDebug=()=>this.handleDebugCommand(),this.defaultEditor.onAction("app.model.select",()=>this.showModelSelector()),this.defaultEditor.onAction("app.tools.expand",()=>this.toggleToolOutputExpansion()),this.defaultEditor.onAction("app.thinking.toggle",()=>this.toggleThinkingBlockVisibility()),this.defaultEditor.onAction("app.editor.external",()=>this.openExternalEditor()),this.defaultEditor.onAction("app.message.followUp",()=>this.handleFollowUp()),this.defaultEditor.onAction("app.message.dequeue",()=>this.handleDequeue()),this.defaultEditor.onAction("app.session.new",()=>this.handleClearCommand()),this.defaultEditor.onAction("app.session.tree",()=>this.showTreeSelector()),this.defaultEditor.onAction("app.session.fork",()=>this.showUserMessageSelector()),this.defaultEditor.onAction("app.session.resume",()=>this.showSessionSelector()),this.defaultEditor.onChange=e=>{const s=this.isBashMode;this.isBashMode=e.trimStart().startsWith("!"),s!==this.isBashMode&&this.updateEditorBorderColor()},this.defaultEditor.onPasteImage=()=>{this.handleClipboardImagePaste()}}async handleClipboardImagePaste(){try{const e=await ft();if(!e)return;const s=F.tmpdir(),t=mt(e.mimeType)??"png",i=`pi-clipboard-${Fe.randomUUID()}.${t}`,n=E.join(s,i);v.writeFileSync(n,Buffer.from(e.bytes)),this.editor.insertTextAtCursor?.(n),this.ui.requestRender()}catch{}}setupEditorSubmitHandler(){this.defaultEditor.onSubmit=async e=>{if(e=e.trim(),!!e){if(e==="/settings"){this.showSettingsSelector(),this.editor.setText("");return}if(e==="/scoped-models"){this.editor.setText(""),await this.showModelsSelector();return}if(e==="/model"||e.startsWith("/model ")){const s=e.startsWith("/model ")?e.slice(7).trim():void 0;this.editor.setText(""),await this.handleModelCommand(s);return}if(e==="/export"||e.startsWith("/export ")){await this.handleExportCommand(e),this.editor.setText("");return}if(e==="/import"||e.startsWith("/import ")){await this.handleImportCommand(e),this.editor.setText("");return}if(e==="/share"){await this.handleShareCommand(),this.editor.setText("");return}if(e==="/copy"){await this.handleCopyCommand(),this.editor.setText("");return}if(e==="/name"||e.startsWith("/name ")){this.handleNameCommand(e),this.editor.setText("");return}if(e==="/session"){this.handleSessionCommand(),this.editor.setText("");return}if(e==="/changelog"){this.handleChangelogCommand(),this.editor.setText("");return}if(e==="/hotkeys"){this.handleHotkeysCommand(),this.editor.setText("");return}if(e==="/fork"){this.showUserMessageSelector(),this.editor.setText("");return}if(e==="/clone"){this.editor.setText(""),await this.handleCloneCommand();return}if(e==="/tree"){this.showTreeSelector(),this.editor.setText("");return}if(e==="/login"){this.showOAuthSelector("login"),this.editor.setText("");return}if(e==="/logout"){this.showOAuthSelector("logout"),this.editor.setText("");return}if(e==="/new"||e==="/clear"){this.editor.setText(""),await this.handleClearCommand();return}if(e==="/goal"||e.startsWith("/goal ")){this.editor.setText(""),await this.handleGoalCommand(e.startsWith("/goal ")?e.slice(6).trim():"");return}if(e==="/use"||e.startsWith("/use ")){this.editor.setText(""),this.handleUseCommand(e.startsWith("/use ")?e.slice(5).trim():"");return}if(e==="/trace"){this.editor.setText(""),this.handleTraceCommand();return}if(e==="/compact"||e.startsWith("/compact ")){const s=e.startsWith("/compact ")?e.slice(9).trim():void 0;this.editor.setText(""),await this.handleCompactCommand(s);return}if(e==="/reload"){this.editor.setText(""),await this.handleReloadCommand();return}if(e==="/debug"){this.handleDebugCommand(),this.editor.setText("");return}if(e==="/arminsayshi"){this.handleArminSaysHi(),this.editor.setText("");return}if(e==="/dementedelves"){this.handleDementedDelves(),this.editor.setText("");return}if(e==="/resume"){this.showSessionSelector(),this.editor.setText("");return}if(e==="/quit"){this.editor.setText(""),await this.shutdown();return}if(e.startsWith("!")){const s=e.startsWith("!!"),t=s?e.slice(2).trim():e.slice(1).trim();if(t){if(this.session.isBashRunning){this.showWarning("A bash command is already running. Press Esc to cancel it first."),this.editor.setText(e);return}this.editor.addToHistory?.(e),await this.handleBashCommand(t,s),this.isBashMode=!1,this.updateEditorBorderColor();return}}if(this.session.isCompacting){this.isExtensionCommand(e)?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e)):this.queueCompactionMessage(e,"steer");return}if(this.session.isStreaming){this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e,{streamingBehavior:"steer"}),this.updatePendingMessagesDisplay(),this.ui.requestRender();return}this.flushPendingBashComponents(),this.onInputCallback?this.onInputCallback(e):this.pendingUserInputs.push(e),this.editor.addToHistory?.(e)}}}subscribeToAgent(){this.unsubscribe=this.session.subscribe(async e=>{await this.handleEvent(e)})}async handleEvent(e){switch(this.isInitialized||await this.init(),this.footer.invalidate(),e.type){case"agent_start":this.pendingTools.clear(),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.retryCountdown&&(this.retryCountdown.dispose(),this.retryCountdown=void 0),this.retryLoader&&(this.retryLoader.stop(),this.retryLoader=void 0),this.stopWorkingLoader(),this.workingVisible&&(this.loadingAnimation=this.createWorkingLoader(),this.statusContainer.addChild(this.loadingAnimation)),this.ui.requestRender();break;case"queue_update":this.updatePendingMessagesDisplay(),this.ui.requestRender();break;case"session_info_changed":this.updateTerminalTitle(),this.footer.invalidate(),this.ui.requestRender();break;case"thinking_level_changed":this.footer.invalidate(),this.updateEditorBorderColor();break;case"message_start":e.message.role==="custom"?(this.addMessageToChat(e.message),this.ui.requestRender()):e.message.role==="user"?(this.addMessageToChat(e.message),this.updatePendingMessagesDisplay(),this.ui.requestRender()):e.message.role==="assistant"&&(this.streamingComponent=new U(void 0,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel),this.streamingMessage=e.message,this.chatContainer.addChild(this.streamingComponent),this.streamingComponent.updateContent(this.streamingMessage),this.ui.requestRender());break;case"message_update":if(this.streamingComponent&&e.message.role==="assistant"){this.streamingMessage=e.message,this.streamingComponent.updateContent(this.streamingMessage);for(const s of this.streamingMessage.content)if(s.type==="toolCall")if(this.pendingTools.has(s.id)){const t=this.pendingTools.get(s.id);t&&t.updateArgs(s.arguments)}else{const t=new W(s.name,s.id,s.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(s.name),this.ui,this.sessionManager.getCwd());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t),this.pendingTools.set(s.id,t)}this.ui.requestRender()}break;case"message_end":if(e.message.role==="user")break;if(this.streamingComponent&&e.message.role==="assistant"){this.streamingMessage=e.message;let s;if(this.streamingMessage.stopReason==="aborted"){const t=this.session.retryAttempt;s=t>0?`Aborted after ${t} retry attempt${t>1?"s":""}`:"Operation aborted",this.streamingMessage.errorMessage=s}if(this.streamingComponent.updateContent(this.streamingMessage),this.streamingMessage.stopReason==="aborted"||this.streamingMessage.stopReason==="error"){s||(s=this.streamingMessage.errorMessage||"Error");for(const[,t]of this.pendingTools.entries())t.updateResult({content:[{type:"text",text:s}],isError:!0});this.pendingTools.clear()}else for(const[,t]of this.pendingTools.entries())t.setArgsComplete();this.streamingComponent=void 0,this.streamingMessage=void 0,this.footer.invalidate()}this.ui.requestRender();break;case"tool_execution_start":{let s=this.pendingTools.get(e.toolCallId);s||(s=new W(e.toolName,e.toolCallId,e.args,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(e.toolName),this.ui,this.sessionManager.getCwd()),s.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(s),this.pendingTools.set(e.toolCallId,s)),s.markExecutionStarted(),this.ui.requestRender();break}case"tool_execution_update":{const s=this.pendingTools.get(e.toolCallId);s&&(s.updateResult({...e.partialResult,isError:!1},!0),this.ui.requestRender());break}case"tool_execution_end":{const s=this.pendingTools.get(e.toolCallId);s&&(s.updateResult({...e.result,isError:e.isError}),this.pendingTools.delete(e.toolCallId),this.ui.requestRender());break}case"agent_end":this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0,this.statusContainer.clear()),this.streamingComponent&&(this.chatContainer.removeChild(this.streamingComponent),this.streamingComponent=void 0,this.streamingMessage=void 0),this.pendingTools.clear(),await this.checkShutdownRequested(),this.ui.requestRender();break;case"compaction_start":{this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.autoCompactionEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortCompaction()},this.statusContainer.clear(),this.compactionStartMs=Date.now(),this.compactionReason=e.reason,this.compactionCancelHint=`(${P("app.interrupt")} to cancel)`,this.autoCompactionLoader=new D(this.ui,s=>a.fg("accent",s),s=>s,this.buildCompactionLabel()),this.statusContainer.addChild(this.autoCompactionLoader),this.compactionTicker&&clearInterval(this.compactionTicker),this.compactionTicker=setInterval(()=>{this.autoCompactionLoader?.setMessage(this.buildCompactionLabel())},250),this.ui.requestRender();break}case"compaction_end":{this.compactionTicker&&(clearInterval(this.compactionTicker),this.compactionTicker=void 0),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.autoCompactionEscapeHandler&&(this.defaultEditor.onEscape=this.autoCompactionEscapeHandler,this.autoCompactionEscapeHandler=void 0),this.autoCompactionLoader&&(this.autoCompactionLoader.stop(),this.autoCompactionLoader=void 0,this.statusContainer.clear()),e.aborted?e.reason==="manual"?this.showError("Compaction cancelled"):this.showStatus("Auto-compaction cancelled"):e.result?(this.chatContainer.clear(),this.rebuildChatFromMessages(),this.addMessageToChat(rt(e.result.summary,e.result.tokensBefore,new Date().toISOString())),this.footer.invalidate()):e.errorMessage&&(e.reason==="manual"?this.showError(e.errorMessage):(this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("error",e.errorMessage),1,0)))),this.flushCompactionQueue({willRetry:e.willRetry}),this.ui.requestRender();break}case"auto_retry_start":{this.retryEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortRetry()},this.statusContainer.clear(),this.retryCountdown?.dispose();const s=h(t=>`Retrying (${e.attempt}/${e.maxAttempts}) in ${t}s... (${P("app.interrupt")} to cancel)`,"retryMessage");this.retryLoader=new D(this.ui,t=>a.fg("warning",t),t=>a.fg("muted",t),s(Math.ceil(e.delayMs/1e3))),this.retryCountdown=new xt(e.delayMs,this.ui,t=>{this.retryLoader?.setMessage(s(t))},()=>{this.retryCountdown=void 0}),this.statusContainer.addChild(this.retryLoader),this.ui.requestRender();break}case"auto_retry_end":{this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.retryCountdown&&(this.retryCountdown.dispose(),this.retryCountdown=void 0),this.retryLoader&&(this.retryLoader.stop(),this.retryLoader=void 0,this.statusContainer.clear()),e.success||this.showError(`Retry failed after ${e.attempt} attempts: ${e.finalError||"Unknown error"}`),this.ui.requestRender();break}case"overseer_start":{this.overseerLoader?.stop(),this.statusContainer.clear();const s=`(${P("app.interrupt")} to skip)`;this.overseerLoader=new D(this.ui,t=>a.fg("accent",t),t=>a.fg("muted",t),`Koda is reviewing the result\u2026 ${s}`),this.statusContainer.addChild(this.overseerLoader),this.overseerEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortOverseer()},this._kodaReviewing=!0,this.updateKodaTitle(),this.ui.requestRender();break}case"overseer_end":{this.overseerLoader&&(this.overseerLoader.stop(),this.overseerLoader=void 0,this.statusContainer.clear()),this.overseerEscapeHandler!==void 0&&(this.defaultEditor.onEscape=this.overseerEscapeHandler,this.overseerEscapeHandler=void 0),this._kodaReviewing=!1,this.updateKodaTitle(),e.outcome==="nudging"?this.showStatus(`Overseer: not done yet \u2014 ${e.detail??"continuing"}`):e.outcome==="skipped"?this.showStatus(`Overseer: review skipped (${e.detail??"unavailable"})`):this.showStatus("Overseer: looks complete \u2713"),this.ui.requestRender();break}case"model_switch_notice":{const s=e.message;s.startsWith("\u2191")||s.startsWith("\u25B2")?this._kodaTitleBase="beefed":s.startsWith("\xBB")?this._kodaTitleBase="rerouted":s.startsWith("\u2190")&&(this._kodaTitleBase="idle"),this.updateKodaTitle(),!s.startsWith("\xBB")&&!s.startsWith("\u2190")&&this.showStatus(e.message),this.ui.requestRender();break}case"goal_set":{this._goalAchievedShown=!1,this.renderGoalBlock({text:e.text,milestones:e.milestones});break}case"goal_progress":{const s=e.milestones.filter(i=>i.done).length,t=e.milestones.length;if(e.achieved&&!this._goalAchievedShown)this._goalAchievedShown=!0,this.renderGoalBlock({text:e.text,milestones:e.milestones,achieved:!0});else if(!e.achieved){const i=e.drift?` \xB7 drifting: ${e.drift}`:"";this.showStatus(`Goal: ${s}/${t} milestones${i}`)}break}case"goal_cleared":{this.showStatus("Goal cleared.");break}case"suggest_feature":{const s=e.message.split(/(\/[a-z_]+|run_background)/);let t=a.fg("warning",a.bold("\xBB tip "));s.forEach((i,n)=>{i&&(t+=n%2===1?a.fg("accent",a.bold(i)):a.fg("muted",i))}),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(t,1,0)),this.ui.requestRender();break}case"task_recap":{const s=e.elapsedMs,t=Math.max(0,Math.floor(s/1e3)),i=Math.floor(t/60),n=i>0?`${i}m ${t%60}s`:`${t}s`;this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("accent","\u273B ")+a.fg("dim",`Churned for ${n}`),1,0)),e.recap&&this.chatContainer.addChild(new f(a.fg("dim","\u203B recap: ")+a.fg("muted",e.recap),1,0)),this.ui.requestRender();break}}}getUserMessageText(e){return e.role!=="user"?"":(typeof e.content=="string"?[{type:"text",text:e.content}]:e.content.filter(t=>t.type==="text")).map(t=>t.text).join("")}showStatus(e){const s=this.chatContainer.children,t=s.length>0?s[s.length-1]:void 0,i=s.length>1?s[s.length-2]:void 0;if(t&&i&&t===this.lastStatusText&&i===this.lastStatusSpacer){this.lastStatusText.setText(a.fg("dim",e)),this.ui.requestRender();return}const n=new g(1),o=new f(a.fg("dim",e),1,0);this.chatContainer.addChild(n),this.chatContainer.addChild(o),this.lastStatusSpacer=n,this.lastStatusText=o,this.ui.requestRender()}addMessageToChat(e,s){switch(e.role){case"bashExecution":{const t=new Q(e.command,this.ui,e.excludeFromContext);e.output&&t.appendOutput(e.output),t.setComplete(e.exitCode,e.cancelled,e.truncated?{truncated:!0}:void 0,e.fullOutputPath),this.chatContainer.addChild(t);break}case"custom":{if(e.display){const t=this.session.extensionRunner.getMessageRenderer(e.customType),i=new Tt(e,t,this.getMarkdownThemeWithSettings());i.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(i)}break}case"compactionSummary":{this.chatContainer.addChild(new g(1));const t=new bt(e,this.getMarkdownThemeWithSettings());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t);break}case"branchSummary":{this.chatContainer.addChild(new g(1));const t=new kt(e,this.getMarkdownThemeWithSettings());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t);break}case"user":{const t=this.getUserMessageText(e);if(t){this.chatContainer.children.length>0&&this.chatContainer.addChild(new g(1));const i=tt(t);if(i){const n=new Ht(i,this.getMarkdownThemeWithSettings());if(n.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(n),i.userMessage){const o=new me(i.userMessage,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(o)}}else{const n=new me(t,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(n)}s?.populateHistory&&this.editor.addToHistory?.(t)}break}case"assistant":{const t=new U(e,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel);this.chatContainer.addChild(t);break}case"toolResult":break;default:{const t=e}}}renderSessionContext(e,s={}){this.pendingTools.clear();const t=new Map;s.updateFooter&&(this.footer.invalidate(),this.updateEditorBorderColor());for(const i of e.messages)if(i.role==="assistant"){this.addMessageToChat(i);for(const n of i.content)if(n.type==="toolCall"){const o=new W(n.name,n.id,n.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(n.name),this.ui,this.sessionManager.getCwd());if(o.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(o),i.stopReason==="aborted"||i.stopReason==="error"){let r;if(i.stopReason==="aborted"){const d=this.session.retryAttempt;r=d>0?`Aborted after ${d} retry attempt${d>1?"s":""}`:"Operation aborted"}else r=i.errorMessage||"Error";o.updateResult({content:[{type:"text",text:r}],isError:!0})}else t.set(n.id,o)}}else if(i.role==="toolResult"){const n=t.get(i.toolCallId);n&&(n.updateResult(i),t.delete(i.toolCallId))}else this.addMessageToChat(i,s);for(const[i,n]of t)this.pendingTools.set(i,n);this.ui.requestRender()}renderInitialMessages(){const e=this.sessionManager.buildSessionContext();this.renderSessionContext(e,{updateFooter:!0,populateHistory:!0});const t=this.sessionManager.getEntries().filter(i=>i.type==="compaction").length;if(t>0){const i=t===1?"1 time":`${t} times`;this.showStatus(`Session compacted ${i}`)}}async getUserInput(){const e=this.pendingUserInputs.shift();return e!==void 0?e:new Promise(s=>{this.onInputCallback=t=>{this.onInputCallback=void 0,s(t)}})}rebuildChatFromMessages(){this.chatContainer.clear();const e=this.sessionManager.buildSessionContext();this.renderSessionContext(e)}handleCtrlC(){const e=Date.now();e-this.lastSigintTime<500?this.shutdown():(this.clearEditor(),this.lastSigintTime=e)}handleCtrlD(){this.shutdown()}isShuttingDown=!1;async shutdown(e){if(this.isShuttingDown)return;this.isShuttingDown=!0,this.unregisterSignalHandlers(),e?.fromSignal&&(await this.runtimeHost.dispose(),await this.ui.terminal.drainInput(1e3),this.stop(),process.exit(0)),await this.ui.terminal.drainInput(1e3),this.stop(),await this.runtimeHost.dispose();const s=Zt(this.sessionManager);s&&process.stdout.write(`${Ve.dim("To resume this session:")} ${s}
|
|
27
|
-
`),process.exit(0)}emergencyTerminalExit(){this.isShuttingDown=!0,this.unregisterSignalHandlers(),V(),process.exit(129)}uncaughtCrash(e){this.isShuttingDown&&process.exit(1),this.isShuttingDown=!0;try{this.unregisterSignalHandlers()}catch{}try{V()}catch{}try{this.ui.stop()}catch{}console.error("koda exiting due to uncaughtException:"),console.error(e),process.exit(1)}async checkShutdownRequested(){this.shutdownRequested&&await this.shutdown()}registerSignalHandlers(){this.unregisterSignalHandlers();const e=["SIGTERM"];process.platform!=="win32"&&e.push("SIGHUP");for(const i of e){const n=h(()=>{V(),this.shutdown({fromSignal:!0})},"handler");process.prependListener(i,n),this.signalCleanupHandlers.push(()=>process.off(i,n))}const s=h(i=>{throw
|
|
26
|
+
`);o&&this.chatContainer.addChild(new f(o,1,0))}this.ui.requestRender()}setupKeyHandlers(){this.defaultEditor.onEscape=()=>{if(this.session.isStreaming)this.restoreQueuedMessagesToEditor({abort:!0});else if(this.session.isBashRunning)this.session.abortBash();else if(this.isBashMode)this.editor.setText(""),this.isBashMode=!1,this.updateEditorBorderColor();else if(!this.editor.getText().trim()){const e=this.settingsManager.getDoubleEscapeAction();if(e!=="none"){const s=Date.now();s-this.lastEscapeTime<500?(e==="tree"?this.showTreeSelector():this.showUserMessageSelector(),this.lastEscapeTime=0):this.lastEscapeTime=s}}},this.defaultEditor.onAction("app.clear",()=>this.handleCtrlC()),this.defaultEditor.onCtrlD=()=>this.handleCtrlD(),this.defaultEditor.onAction("app.suspend",()=>this.handleCtrlZ()),this.defaultEditor.onAction("app.thinking.cycle",()=>this.cycleThinkingLevel()),this.defaultEditor.onAction("app.model.cycleForward",()=>this.cycleModel("forward")),this.defaultEditor.onAction("app.model.cycleBackward",()=>this.cycleModel("backward")),this.ui.onDebug=()=>this.handleDebugCommand(),this.defaultEditor.onAction("app.model.select",()=>this.showModelSelector()),this.defaultEditor.onAction("app.tools.expand",()=>this.toggleToolOutputExpansion()),this.defaultEditor.onAction("app.thinking.toggle",()=>this.toggleThinkingBlockVisibility()),this.defaultEditor.onAction("app.editor.external",()=>this.openExternalEditor()),this.defaultEditor.onAction("app.message.followUp",()=>this.handleFollowUp()),this.defaultEditor.onAction("app.message.dequeue",()=>this.handleDequeue()),this.defaultEditor.onAction("app.session.new",()=>this.handleClearCommand()),this.defaultEditor.onAction("app.session.tree",()=>this.showTreeSelector()),this.defaultEditor.onAction("app.session.fork",()=>this.showUserMessageSelector()),this.defaultEditor.onAction("app.session.resume",()=>this.showSessionSelector()),this.defaultEditor.onChange=e=>{const s=this.isBashMode;this.isBashMode=e.trimStart().startsWith("!"),s!==this.isBashMode&&this.updateEditorBorderColor()},this.defaultEditor.onPasteImage=()=>{this.handleClipboardImagePaste()}}async handleClipboardImagePaste(){try{const e=await wt();if(!e)return;const s=q.tmpdir(),t=Ct(e.mimeType)??"png",i=`pi-clipboard-${Fe.randomUUID()}.${t}`,n=E.join(s,i);v.writeFileSync(n,Buffer.from(e.bytes)),this.editor.insertTextAtCursor?.(n),this.ui.requestRender()}catch{}}setupEditorSubmitHandler(){this.defaultEditor.onSubmit=async e=>{if(e=e.trim(),!!e){if(e==="/settings"){this.showSettingsSelector(),this.editor.setText("");return}if(e==="/scoped-models"){this.editor.setText(""),await this.showModelsSelector();return}if(e==="/model"||e.startsWith("/model ")){const s=e.startsWith("/model ")?e.slice(7).trim():void 0;this.editor.setText(""),await this.handleModelCommand(s);return}if(e==="/export"||e.startsWith("/export ")){await this.handleExportCommand(e),this.editor.setText("");return}if(e==="/import"||e.startsWith("/import ")){await this.handleImportCommand(e),this.editor.setText("");return}if(e==="/share"){await this.handleShareCommand(),this.editor.setText("");return}if(e==="/copy"){await this.handleCopyCommand(),this.editor.setText("");return}if(e==="/name"||e.startsWith("/name ")){this.handleNameCommand(e),this.editor.setText("");return}if(e==="/session"){this.handleSessionCommand(),this.editor.setText("");return}if(e==="/changelog"){this.handleChangelogCommand(),this.editor.setText("");return}if(e==="/hotkeys"){this.handleHotkeysCommand(),this.editor.setText("");return}if(e==="/fork"){this.showUserMessageSelector(),this.editor.setText("");return}if(e==="/clone"){this.editor.setText(""),await this.handleCloneCommand();return}if(e==="/tree"){this.showTreeSelector(),this.editor.setText("");return}if(e==="/login"){this.showOAuthSelector("login"),this.editor.setText("");return}if(e==="/logout"){this.showOAuthSelector("logout"),this.editor.setText("");return}if(e==="/new"||e==="/clear"){this.editor.setText(""),await this.handleClearCommand();return}if(e==="/goal"||e.startsWith("/goal ")){this.editor.setText(""),await this.handleGoalCommand(e.startsWith("/goal ")?e.slice(6).trim():"");return}if(e==="/use"||e.startsWith("/use ")){this.editor.setText(""),this.handleUseCommand(e.startsWith("/use ")?e.slice(5).trim():"");return}if(e==="/trace"){this.editor.setText(""),this.handleTraceCommand();return}if(e==="/compact"||e.startsWith("/compact ")){const s=e.startsWith("/compact ")?e.slice(9).trim():void 0;this.editor.setText(""),await this.handleCompactCommand(s);return}if(e==="/reload"){this.editor.setText(""),await this.handleReloadCommand();return}if(e==="/debug"){this.handleDebugCommand(),this.editor.setText("");return}if(e==="/arminsayshi"){this.handleArminSaysHi(),this.editor.setText("");return}if(e==="/dementedelves"){this.handleDementedDelves(),this.editor.setText("");return}if(e==="/resume"){this.showSessionSelector(),this.editor.setText("");return}if(e==="/quit"){this.editor.setText(""),await this.shutdown();return}if(e.startsWith("!")){const s=e.startsWith("!!"),t=s?e.slice(2).trim():e.slice(1).trim();if(t){if(this.session.isBashRunning){this.showWarning("A bash command is already running. Press Esc to cancel it first."),this.editor.setText(e);return}this.editor.addToHistory?.(e),await this.handleBashCommand(t,s),this.isBashMode=!1,this.updateEditorBorderColor();return}}if(this.session.isCompacting){this.isExtensionCommand(e)?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e)):this.queueCompactionMessage(e,"steer");return}if(this.session.isStreaming){this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e,{streamingBehavior:"steer"}),this.updatePendingMessagesDisplay(),this.ui.requestRender();return}this.flushPendingBashComponents(),this.onInputCallback?this.onInputCallback(e):this.pendingUserInputs.push(e),this.editor.addToHistory?.(e)}}}subscribeToAgent(){this.unsubscribe=this.session.subscribe(async e=>{await this.handleEvent(e)})}async handleEvent(e){switch(this.isInitialized||await this.init(),this.footer.invalidate(),e.type){case"agent_start":this.pendingTools.clear(),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.retryCountdown&&(this.retryCountdown.dispose(),this.retryCountdown=void 0),this.retryLoader&&(this.retryLoader.stop(),this.retryLoader=void 0),this.stopWorkingLoader(),this.workingVisible&&(this.loadingAnimation=this.createWorkingLoader(),this.statusContainer.addChild(this.loadingAnimation)),this.ui.requestRender();break;case"queue_update":this.updatePendingMessagesDisplay(),this.ui.requestRender();break;case"session_info_changed":this.updateTerminalTitle(),this.footer.invalidate(),this.ui.requestRender();break;case"thinking_level_changed":this.footer.invalidate(),this.updateEditorBorderColor();break;case"message_start":e.message.role==="custom"?(this.addMessageToChat(e.message),this.ui.requestRender()):e.message.role==="user"?(this.addMessageToChat(e.message),this.updatePendingMessagesDisplay(),this.ui.requestRender()):e.message.role==="assistant"&&(this.streamingComponent=new U(void 0,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel),this.streamingMessage=e.message,this.chatContainer.addChild(this.streamingComponent),this.streamingComponent.updateContent(this.streamingMessage),this.ui.requestRender());break;case"message_update":if(this.streamingComponent&&e.message.role==="assistant"){this.streamingMessage=e.message,this.streamingComponent.updateContent(this.streamingMessage);for(const s of this.streamingMessage.content)if(s.type==="toolCall")if(this.pendingTools.has(s.id)){const t=this.pendingTools.get(s.id);t&&t.updateArgs(s.arguments)}else{const t=new H(s.name,s.id,s.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(s.name),this.ui,this.sessionManager.getCwd());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t),this.pendingTools.set(s.id,t)}this.ui.requestRender()}break;case"message_end":if(e.message.role==="user")break;if(this.streamingComponent&&e.message.role==="assistant"){this.streamingMessage=e.message;let s;if(this.streamingMessage.stopReason==="aborted"){const t=this.session.retryAttempt;s=t>0?`Aborted after ${t} retry attempt${t>1?"s":""}`:"Operation aborted",this.streamingMessage.errorMessage=s}if(this.streamingComponent.updateContent(this.streamingMessage),this.streamingMessage.stopReason==="aborted"||this.streamingMessage.stopReason==="error"){s||(s=this.streamingMessage.errorMessage||"Error");for(const[,t]of this.pendingTools.entries())t.updateResult({content:[{type:"text",text:s}],isError:!0});this.pendingTools.clear()}else for(const[,t]of this.pendingTools.entries())t.setArgsComplete();this.streamingComponent=void 0,this.streamingMessage=void 0,this.footer.invalidate()}this.ui.requestRender();break;case"tool_execution_start":{let s=this.pendingTools.get(e.toolCallId);s||(s=new H(e.toolName,e.toolCallId,e.args,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(e.toolName),this.ui,this.sessionManager.getCwd()),s.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(s),this.pendingTools.set(e.toolCallId,s)),s.markExecutionStarted(),this.ui.requestRender();break}case"tool_execution_update":{const s=this.pendingTools.get(e.toolCallId);s&&(s.updateResult({...e.partialResult,isError:!1},!0),this.ui.requestRender());break}case"tool_execution_end":{const s=this.pendingTools.get(e.toolCallId);s&&(s.updateResult({...e.result,isError:e.isError}),this.pendingTools.delete(e.toolCallId),this.ui.requestRender());break}case"agent_end":this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0,this.statusContainer.clear()),this.streamingComponent&&(this.chatContainer.removeChild(this.streamingComponent),this.streamingComponent=void 0,this.streamingMessage=void 0),this.pendingTools.clear(),await this.checkShutdownRequested(),this.ui.requestRender();break;case"compaction_start":{this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!0),this.autoCompactionEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortCompaction()},this.statusContainer.clear(),this.compactionStartMs=Date.now(),this.compactionReason=e.reason,this.compactionCancelHint=`(${P("app.interrupt")} to cancel)`,this.autoCompactionLoader=new D(this.ui,s=>a.fg("accent",s),s=>s,this.buildCompactionLabel()),this.statusContainer.addChild(this.autoCompactionLoader),this.compactionTicker&&clearInterval(this.compactionTicker),this.compactionTicker=setInterval(()=>{this.autoCompactionLoader?.setMessage(this.buildCompactionLabel())},250),this.ui.requestRender();break}case"compaction_end":{this.compactionTicker&&(clearInterval(this.compactionTicker),this.compactionTicker=void 0),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.autoCompactionEscapeHandler&&(this.defaultEditor.onEscape=this.autoCompactionEscapeHandler,this.autoCompactionEscapeHandler=void 0),this.autoCompactionLoader&&(this.autoCompactionLoader.stop(),this.autoCompactionLoader=void 0,this.statusContainer.clear()),e.aborted?e.reason==="manual"?this.showError("Compaction cancelled"):this.showStatus("Auto-compaction cancelled"):e.result?(this.chatContainer.clear(),this.rebuildChatFromMessages(),this.addMessageToChat(ht(e.result.summary,e.result.tokensBefore,new Date().toISOString())),this.footer.invalidate()):e.errorMessage&&(e.reason==="manual"?this.showError(e.errorMessage):(this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("error",e.errorMessage),1,0)))),this.flushCompactionQueue({willRetry:e.willRetry}),this.ui.requestRender();break}case"auto_retry_start":{this.retryEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortRetry()},this.statusContainer.clear(),this.retryCountdown?.dispose();const s=h(t=>`Retrying (${e.attempt}/${e.maxAttempts}) in ${t}s... (${P("app.interrupt")} to cancel)`,"retryMessage");this.retryLoader=new D(this.ui,t=>a.fg("warning",t),t=>a.fg("muted",t),s(Math.ceil(e.delayMs/1e3))),this.retryCountdown=new Tt(e.delayMs,this.ui,t=>{this.retryLoader?.setMessage(s(t))},()=>{this.retryCountdown=void 0}),this.statusContainer.addChild(this.retryLoader),this.ui.requestRender();break}case"auto_retry_end":{this.retryEscapeHandler&&(this.defaultEditor.onEscape=this.retryEscapeHandler,this.retryEscapeHandler=void 0),this.retryCountdown&&(this.retryCountdown.dispose(),this.retryCountdown=void 0),this.retryLoader&&(this.retryLoader.stop(),this.retryLoader=void 0,this.statusContainer.clear()),e.success||this.showError(`Retry failed after ${e.attempt} attempts: ${e.finalError||"Unknown error"}`),this.ui.requestRender();break}case"overseer_start":{this.overseerLoader?.stop(),this.statusContainer.clear();const s=`(${P("app.interrupt")} to skip)`;this.overseerLoader=new D(this.ui,t=>a.fg("accent",t),t=>a.fg("muted",t),`Koda is reviewing the result\u2026 ${s}`),this.statusContainer.addChild(this.overseerLoader),this.overseerEscapeHandler=this.defaultEditor.onEscape,this.defaultEditor.onEscape=()=>{this.session.abortOverseer()},this._kodaReviewing=!0,this.updateKodaTitle(),this.ui.requestRender();break}case"overseer_end":{this.overseerLoader&&(this.overseerLoader.stop(),this.overseerLoader=void 0,this.statusContainer.clear()),this.overseerEscapeHandler!==void 0&&(this.defaultEditor.onEscape=this.overseerEscapeHandler,this.overseerEscapeHandler=void 0),this._kodaReviewing=!1,this.updateKodaTitle(),e.outcome==="nudging"?this.showStatus(`Overseer: not done yet \u2014 ${e.detail??"continuing"}`):e.outcome==="skipped"?this.showStatus(`Overseer: review skipped (${e.detail??"unavailable"})`):this.showStatus("Overseer: looks complete \u2713"),this.ui.requestRender();break}case"model_switch_notice":{const s=e.message;s.startsWith("\u2191")||s.startsWith("\u25B2")?this._kodaTitleBase="beefed":s.startsWith("\xBB")?this._kodaTitleBase="rerouted":s.startsWith("\u2190")&&(this._kodaTitleBase="idle"),this.updateKodaTitle(),!s.startsWith("\xBB")&&!s.startsWith("\u2190")&&this.showStatus(e.message),this.ui.requestRender();break}case"goal_set":{this._goalAchievedShown=!1,this.renderGoalBlock({text:e.text,milestones:e.milestones});break}case"goal_progress":{const s=e.milestones.filter(i=>i.done).length,t=e.milestones.length;if(e.achieved&&!this._goalAchievedShown)this._goalAchievedShown=!0,this.renderGoalBlock({text:e.text,milestones:e.milestones,achieved:!0});else if(!e.achieved){const i=e.drift?` \xB7 drifting: ${e.drift}`:"";this.showStatus(`Goal: ${s}/${t} milestones${i}`)}break}case"goal_cleared":{this.showStatus("Goal cleared.");break}case"suggest_feature":{const s=e.message.split(/(\/[a-z_]+|run_background)/);let t=a.fg("warning",a.bold("\xBB tip "));s.forEach((i,n)=>{i&&(t+=n%2===1?a.fg("accent",a.bold(i)):a.fg("muted",i))}),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(t,1,0)),this.ui.requestRender();break}case"task_recap":{const s=e.elapsedMs,t=Math.max(0,Math.floor(s/1e3)),i=Math.floor(t/60),n=i>0?`${i}m ${t%60}s`:`${t}s`;this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("accent","\u273B ")+a.fg("dim",`Churned for ${n}`),1,0)),e.recap&&this.chatContainer.addChild(new f(a.fg("dim","\u203B recap: ")+a.fg("muted",e.recap),1,0)),this.ui.requestRender();break}}}getUserMessageText(e){return e.role!=="user"?"":(typeof e.content=="string"?[{type:"text",text:e.content}]:e.content.filter(t=>t.type==="text")).map(t=>t.text).join("")}showStatus(e){const s=this.chatContainer.children,t=s.length>0?s[s.length-1]:void 0,i=s.length>1?s[s.length-2]:void 0;if(t&&i&&t===this.lastStatusText&&i===this.lastStatusSpacer){this.lastStatusText.setText(a.fg("dim",e)),this.ui.requestRender();return}const n=new g(1),o=new f(a.fg("dim",e),1,0);this.chatContainer.addChild(n),this.chatContainer.addChild(o),this.lastStatusSpacer=n,this.lastStatusText=o,this.ui.requestRender()}addMessageToChat(e,s){switch(e.role){case"bashExecution":{const t=new Q(e.command,this.ui,e.excludeFromContext);e.output&&t.appendOutput(e.output),t.setComplete(e.exitCode,e.cancelled,e.truncated?{truncated:!0}:void 0,e.fullOutputPath),this.chatContainer.addChild(t);break}case"custom":{if(e.display){const t=this.session.extensionRunner.getMessageRenderer(e.customType),i=new Pt(e,t,this.getMarkdownThemeWithSettings());i.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(i)}break}case"compactionSummary":{this.chatContainer.addChild(new g(1));const t=new xt(e,this.getMarkdownThemeWithSettings());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t);break}case"branchSummary":{this.chatContainer.addChild(new g(1));const t=new Mt(e,this.getMarkdownThemeWithSettings());t.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(t);break}case"user":{const t=this.getUserMessageText(e);if(t){this.chatContainer.children.length>0&&this.chatContainer.addChild(new g(1));const i=it(t);if(i){const n=new qt(i,this.getMarkdownThemeWithSettings());if(n.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(n),i.userMessage){const o=new me(i.userMessage,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(o)}}else{const n=new me(t,this.getMarkdownThemeWithSettings());this.chatContainer.addChild(n)}s?.populateHistory&&this.editor.addToHistory?.(t)}break}case"assistant":{const t=new U(e,this.hideThinkingBlock,this.getMarkdownThemeWithSettings(),this.hiddenThinkingLabel);this.chatContainer.addChild(t);break}case"toolResult":break;default:{const t=e}}}renderSessionContext(e,s={}){this.pendingTools.clear();const t=new Map;s.updateFooter&&(this.footer.invalidate(),this.updateEditorBorderColor());for(const i of e.messages)if(i.role==="assistant"){this.addMessageToChat(i);for(const n of i.content)if(n.type==="toolCall"){const o=new H(n.name,n.id,n.arguments,{showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells()},this.getRegisteredToolDefinition(n.name),this.ui,this.sessionManager.getCwd());if(o.setExpanded(this.toolOutputExpanded),this.chatContainer.addChild(o),i.stopReason==="aborted"||i.stopReason==="error"){let r;if(i.stopReason==="aborted"){const d=this.session.retryAttempt;r=d>0?`Aborted after ${d} retry attempt${d>1?"s":""}`:"Operation aborted"}else r=i.errorMessage||"Error";o.updateResult({content:[{type:"text",text:r}],isError:!0})}else t.set(n.id,o)}}else if(i.role==="toolResult"){const n=t.get(i.toolCallId);n&&(n.updateResult(i),t.delete(i.toolCallId))}else this.addMessageToChat(i,s);for(const[i,n]of t)this.pendingTools.set(i,n);this.ui.requestRender()}renderInitialMessages(){const e=this.sessionManager.buildSessionContext();this.renderSessionContext(e,{updateFooter:!0,populateHistory:!0});const t=this.sessionManager.getEntries().filter(i=>i.type==="compaction").length;if(t>0){const i=t===1?"1 time":`${t} times`;this.showStatus(`Session compacted ${i}`)}}async getUserInput(){const e=this.pendingUserInputs.shift();return e!==void 0?e:new Promise(s=>{this.onInputCallback=t=>{this.onInputCallback=void 0,s(t)}})}rebuildChatFromMessages(){this.chatContainer.clear();const e=this.sessionManager.buildSessionContext();this.renderSessionContext(e)}handleCtrlC(){const e=Date.now();e-this.lastSigintTime<500?this.shutdown():(this.clearEditor(),this.lastSigintTime=e)}handleCtrlD(){this.shutdown()}isShuttingDown=!1;async shutdown(e){if(this.isShuttingDown)return;this.isShuttingDown=!0,this.unregisterSignalHandlers(),e?.fromSignal&&(await this.runtimeHost.dispose(),await this.ui.terminal.drainInput(1e3),this.stop(),process.exit(0)),await this.ui.terminal.drainInput(1e3),this.stop(),await this.runtimeHost.dispose();const s=ss(this.sessionManager);s&&process.stdout.write(`${Ve.dim("To resume this session:")} ${s}
|
|
27
|
+
`),process.exit(0)}emergencyTerminalExit(){this.isShuttingDown=!0,this.unregisterSignalHandlers(),V(),process.exit(129)}uncaughtCrash(e){this.isShuttingDown&&process.exit(1),this.isShuttingDown=!0;try{this.unregisterSignalHandlers()}catch{}try{V()}catch{}try{this.ui.stop()}catch{}console.error("koda exiting due to uncaughtException:"),console.error(e),process.exit(1)}async checkShutdownRequested(){this.shutdownRequested&&await this.shutdown()}registerSignalHandlers(){this.unregisterSignalHandlers();const e=["SIGTERM"];process.platform!=="win32"&&e.push("SIGHUP");for(const i of e){const n=h(()=>{V(),this.shutdown({fromSignal:!0})},"handler");process.prependListener(i,n),this.signalCleanupHandlers.push(()=>process.off(i,n))}const s=h(i=>{throw Jt(i)&&this.emergencyTerminalExit(),i},"terminalErrorHandler");process.stdout.on("error",s),process.stderr.on("error",s),this.signalCleanupHandlers.push(()=>process.stdout.off("error",s)),this.signalCleanupHandlers.push(()=>process.stderr.off("error",s));const t=h(i=>this.uncaughtCrash(i),"uncaughtExceptionHandler");process.prependListener("uncaughtException",t),this.signalCleanupHandlers.push(()=>process.off("uncaughtException",t))}unregisterSignalHandlers(){for(const e of this.signalCleanupHandlers)e();this.signalCleanupHandlers=[]}handleCtrlZ(){if(process.platform==="win32"){this.showStatus("Suspend to background is not supported on Windows");return}const e=setInterval(()=>{},2**30),s=h(()=>{},"ignoreSigint");process.on("SIGINT",s),process.once("SIGCONT",()=>{clearInterval(e),process.removeListener("SIGINT",s),this.ui.start(),this.ui.requestRender(!0)});try{this.ui.stop(),process.kill(0,"SIGTSTP")}catch(t){throw clearInterval(e),process.removeListener("SIGINT",s),t}}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.session.prompt(e)):this.queueCompactionMessage(e,"followUp");return}this.session.isStreaming?(this.editor.addToHistory?.(e),this.editor.setText(""),await this.session.prompt(e,{streamingBehavior:"followUp"}),this.updatePendingMessagesDisplay(),this.ui.requestRender()):this.editor.onSubmit&&(this.editor.setText(""),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`)}updateEditorBorderColor(){if(this.isBashMode)this.editor.borderColor=a.getBashModeBorderColor();else{const e=this.session.thinkingLevel||"off";this.editor.borderColor=a.getThinkingBorderColor(e)}this.ui.requestRender()}cycleThinkingLevel(){const e=this.session.cycleThinkingLevel();e===void 0?this.showStatus("Current model does not support thinking"):(this.footer.invalidate(),this.updateEditorBorderColor(),this.showStatus(`Thinking level: ${e}`))}async cycleModel(e){try{const s=await this.session.cycleModel(e);if(s===void 0){const t=this.session.scopedModels.length>0?"Only one model in scope":"Only one model available";this.showStatus(t)}else{this.footer.invalidate(),this.updateEditorBorderColor();const t=s.model.reasoning&&s.thinkingLevel!=="off"?` (thinking: ${s.thinkingLevel})`:"";this.showStatus(`Switched to ${s.model.name||s.model.id}${t}`),this.maybeWarnAboutAnthropicSubscriptionAuth(s.model)}}catch(s){this.showError(s instanceof Error?s.message:String(s))}}toggleToolOutputExpansion(){this.setToolsExpanded(!this.toolOutputExpanded)}setToolsExpanded(e){this.toolOutputExpanded=e;const s=this.customHeader??this.builtInHeader;F(s)&&s.setExpanded(e);for(const t of this.chatContainer.children)F(t)&&t.setExpanded(e);this.ui.requestRender()}toggleThinkingBlockVisibility(){this.hideThinkingBlock=!this.hideThinkingBlock,this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock),this.chatContainer.clear(),this.rebuildChatFromMessages(),this.streamingComponent&&this.streamingMessage&&(this.streamingComponent.setHideThinkingBlock(this.hideThinkingBlock),this.streamingComponent.updateContent(this.streamingMessage),this.chatContainer.addChild(this.streamingComponent)),this.showStatus(`Thinking blocks: ${this.hideThinkingBlock?"hidden":"visible"}`)}async openExternalEditor(){const e=process.env.VISUAL||process.env.EDITOR;if(!e){this.showWarning("No editor configured. Set $VISUAL or $EDITOR environment variable.");return}const s=this.editor.getExpandedText?.()??this.editor.getText(),t=E.join(q.tmpdir(),`pi-editor-${Date.now()}.pi.md`);try{v.writeFileSync(t,s,"utf-8"),this.ui.stop();const[i,...n]=e.split(" ");if(process.stdout.write(`Launching external editor: ${e}
|
|
28
28
|
Pi will resume when the editor exits.
|
|
29
|
-
`),await new Promise(r=>{const d=j(i,[...n,t],{stdio:"inherit",shell:process.platform==="win32"});d.on("error",()=>r(null)),d.on("close",l=>r(l))})===0){const r=v.readFileSync(t,"utf-8").replace(/\n$/,"");this.editor.setText(r)}}finally{try{v.unlinkSync(t)}catch{}this.ui.start(),this.ui.requestRender(!0)}}clearEditor(){this.editor.setText(""),this.ui.requestRender()}showError(e){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("error",`Error: ${e}`),1,0)),this.chatContainer.addChild(new g(1)),this.ui.requestRender()}showWarning(e){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("warning",`Warning: ${e}`),1,0)),this.ui.requestRender()}
|
|
30
|
-
${
|
|
29
|
+
`),await new Promise(r=>{const d=j(i,[...n,t],{stdio:"inherit",shell:process.platform==="win32"});d.on("error",()=>r(null)),d.on("close",l=>r(l))})===0){const r=v.readFileSync(t,"utf-8").replace(/\n$/,"");this.editor.setText(r)}}finally{try{v.unlinkSync(t)}catch{}this.ui.start(),this.ui.requestRender(!0)}}clearEditor(){this.editor.setText(""),this.ui.requestRender()}showError(e){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("error",`Error: ${e}`),1,0)),this.chatContainer.addChild(new g(1)),this.ui.requestRender()}showWarning(e){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("warning",`Warning: ${e}`),1,0)),this.ui.requestRender()}async showResumeHintForCwd(){if(process.env.KODA_NO_RESUME_HINT!=="1")try{const e=this.sessionManager.getCwd(),s=this.sessionManager.getSessionFile(),t=(await W.list(e)).filter(p=>p.path!==s&&p.messageCount>0);if(t.length===0)return;const i=t[0],n=(i.name||i.firstMessage||"").replace(/^\[imported from \w+\]\s*/i,"").replace(/\s+/g," ").trim().slice(0,56),o=ts(i.modified),r=a,d=t.length===1?"1 past session":`${t.length} past sessions`;let l=`${r.fg("accent","\u21A9 ")}${r.fg("muted",`${d} in this folder`)}`;n&&(l+=r.fg("muted",` \xB7 latest: "${n}"`)),o&&(l+=r.fg("dim",` (${o})`)),l+=r.fg("muted"," \u2014 ")+r.fg("accent","/resume")+r.fg("muted"," to pick one, or ")+r.fg("accent","koda --continue")+r.fg("muted"," for the latest."),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(l,1,0)),this.ui.requestRender()}catch{}}async runImportFromSettings(){try{const e=await Xe(),s=e.claude+e.opencode;if(s===0){this.showStatus("No new sessions to import from Claude Code or OpenCode.");return}this.showStatus(`Importing ${s} session(s) from Claude Code + OpenCode\u2026`);const t=await Je({onProgress:h((i,n)=>this.showStatus(`Importing\u2026 ${i}/${n}`),"onProgress")});this.showStatus(`Imported ${t.imported} session(s) (${t.perSource.claude} Claude Code, ${t.perSource.opencode} OpenCode). Use /resume to open them.`)}catch(e){this.showError(`Import failed: ${e.message}`)}}showNewVersionNotification(e,s=!1){const t=a.fg("accent",`${z} update`),i=s?"Updating Koda":"Update Available",n=s?a.fg("muted",`Updating to ${e.version} in the background \u2014 you'll get a restart prompt when it's ready.`):a.fg("muted",`New version ${e.version} is available. Run `)+t,o="https://openadapter.in/changelog",r=Oe().hyperlinks?_e(a.fg("accent","open changelog"),o):a.fg("accent",o),d=a.fg("muted","Changelog: ")+r,l=e.note?.trim();this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k(p=>a.fg("warning",p))),this.chatContainer.addChild(new f(`${a.bold(a.fg("warning",i))}
|
|
30
|
+
${n}`,1,0)),l&&(this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new B(l,1,0,this.getMarkdownThemeWithSettings(),{color:h(p=>a.fg("muted",p),"color")})),this.chatContainer.addChild(new g(1))),this.chatContainer.addChild(new f(d,1,0)),this.chatContainer.addChild(new k(p=>a.fg("warning",p))),this.ui.requestRender()}showPackageUpdateNotification(e){const s=a.fg("accent",`${z} update`),t=a.fg("muted","Package updates are available. Run ")+s,i=e.map(n=>`- ${n}`).join(`
|
|
31
31
|
`);this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k(n=>a.fg("warning",n))),this.chatContainer.addChild(new f(`${a.bold(a.fg("warning","Package Updates Available"))}
|
|
32
32
|
${t}
|
|
33
33
|
${a.fg("muted","Packages:")}
|
|
@@ -35,10 +35,10 @@ ${i}`,1,0)),this.chatContainer.addChild(new k(n=>a.fg("warning",n))),this.ui.req
|
|
|
35
35
|
|
|
36
36
|
`),o=e?.currentText??this.editor.getText(),r=[n,o].filter(d=>d.trim()).join(`
|
|
37
37
|
|
|
38
|
-
`);return this.editor.setText(r),this.updatePendingMessagesDisplay(),e?.abort&&this.agent.abort(),i.length}queueCompactionMessage(e,s){this.compactionQueuedMessages.push({text:e,mode:s}),this.editor.addToHistory?.(e),this.editor.setText(""),this.updatePendingMessagesDisplay(),this.showStatus("Queued message for after compaction")}isExtensionCommand(e){if(!e.startsWith("/"))return!1;const s=this.session.extensionRunner,t=e.indexOf(" "),i=t===-1?e.slice(1):e.slice(1,t);return!!s.getCommand(i)}async flushCompactionQueue(e){if(this.compactionQueuedMessages.length===0)return;const s=[...this.compactionQueuedMessages];this.compactionQueuedMessages=[],this.updatePendingMessagesDisplay();const t=h(i=>{this.session.clearQueue(),this.compactionQueuedMessages=s,this.updatePendingMessagesDisplay(),this.showError(`Failed to send queued message${s.length>1?"s":""}: ${i instanceof Error?i.message:String(i)}`)},"restoreQueue");try{if(e?.willRetry){for(const l of s)this.isExtensionCommand(l.text)?await this.session.prompt(l.text):l.mode==="followUp"?await this.session.followUp(l.text):await this.session.steer(l.text);this.updatePendingMessagesDisplay();return}const i=s.findIndex(l=>!this.isExtensionCommand(l.text));if(i===-1){for(const l of s)await this.session.prompt(l.text);return}const n=s.slice(0,i),o=s[i],r=s.slice(i+1);for(const l of n)await this.session.prompt(l.text);const d=this.session.prompt(o.text).catch(l=>{t(l)});for(const l of r)this.isExtensionCommand(l.text)?await this.session.prompt(l.text):l.mode==="followUp"?await this.session.followUp(l.text):await this.session.steer(l.text);this.updatePendingMessagesDisplay()}catch(i){t(i)}}flushPendingBashComponents(){for(const e of this.pendingBashComponents)this.pendingMessagesContainer.removeChild(e),this.chatContainer.addChild(e);this.pendingBashComponents=[]}showSelector(e){const s=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor)},"done"),{component:t,focus:i}=e(s);this.editorContainer.clear(),this.editorContainer.addChild(t),this.ui.setFocus(i),this.ui.requestRender()}showSettingsSelector(){this.showSelector(e=>{const s=new
|
|
39
|
-
Fell back to dark theme.`)},"onThemeChange"),onThemePreview:h(t=>{O(t,!0).success&&(this.ui.invalidate(),this.ui.requestRender())},"onThemePreview"),onHideThinkingBlockChange:h(t=>{this.hideThinkingBlock=t,this.settingsManager.setHideThinkingBlock(t);for(const i of this.chatContainer.children)i instanceof U&&i.setHideThinkingBlock(t);this.chatContainer.clear(),this.rebuildChatFromMessages()},"onHideThinkingBlockChange"),onCollapseChangelogChange:h(t=>{this.settingsManager.setCollapseChangelog(t)},"onCollapseChangelogChange"),onEnableInstallTelemetryChange:h(t=>{this.settingsManager.setEnableInstallTelemetry(t)},"onEnableInstallTelemetryChange"),onQuietStartupChange:h(t=>{this.settingsManager.setQuietStartup(t)},"onQuietStartupChange"),onDoubleEscapeActionChange:h(t=>{this.settingsManager.setDoubleEscapeAction(t)},"onDoubleEscapeActionChange"),onTreeFilterModeChange:h(t=>{this.settingsManager.setTreeFilterMode(t)},"onTreeFilterModeChange"),onShowHardwareCursorChange:h(t=>{this.settingsManager.setShowHardwareCursor(t),this.ui.setShowHardwareCursor(t)},"onShowHardwareCursorChange"),onEditorPaddingXChange:h(t=>{this.settingsManager.setEditorPaddingX(t),this.defaultEditor.setPaddingX(t),this.editor!==this.defaultEditor&&this.editor.setPaddingX!==void 0&&this.editor.setPaddingX(t)},"onEditorPaddingXChange"),onAutocompleteMaxVisibleChange:h(t=>{this.settingsManager.setAutocompleteMaxVisible(t),this.defaultEditor.setAutocompleteMaxVisible(t),this.editor!==this.defaultEditor&&this.editor.setAutocompleteMaxVisible!==void 0&&this.editor.setAutocompleteMaxVisible(t)},"onAutocompleteMaxVisibleChange"),onClearOnShrinkChange:h(t=>{this.settingsManager.setClearOnShrink(t),this.ui.setClearOnShrink(t)},"onClearOnShrinkChange"),onShowTerminalProgressChange:h(t=>{this.settingsManager.setShowTerminalProgress(t)},"onShowTerminalProgressChange"),onWarningsChange:h(t=>{this.settingsManager.setWarnings(t)},"onWarningsChange"),onCancel:h(()=>{e(),this.ui.requestRender()},"onCancel")});return{component:s,focus:s.getSettingsList()}})}async handleModelCommand(e){if(!e){this.showModelSelector();return}const s=await this.findExactModelMatch(e);if(s){try{await this.session.setModel(s),this.footer.invalidate(),this.updateEditorBorderColor(),this.showStatus(`Model: ${s.id}`),this.maybeWarnAboutAnthropicSubscriptionAuth(s),this.checkDaxnutsEasterEgg(s)}catch(t){this.showError(t instanceof Error?t.message:String(t))}return}this.showModelSelector(e)}async findExactModelMatch(e){const s=await this.getModelCandidates();return at(e,s)}async getModelCandidates(){if(this.session.scopedModels.length>0)return this.session.scopedModels.map(e=>e.model);this.session.modelRegistry.refresh();try{return await this.session.modelRegistry.getAvailable()}catch{return[]}}async updateAvailableProviderCount(){const e=await this.getModelCandidates(),s=new Set(e.map(t=>t.provider));this.footerDataProvider.setAvailableProviderCount(s.size)}async maybeWarnAboutAnthropicSubscriptionAuth(e=this.session.model){if(this.settingsManager.getWarnings().anthropicExtraUsage===!1||this.anthropicSubscriptionWarningShown||!e||e.provider!=="anthropic")return;if(this.session.modelRegistry.authStorage.get("anthropic")?.type==="oauth"){this.anthropicSubscriptionWarningShown=!0,this.showWarning(we);return}try{const t=await this.session.modelRegistry.getApiKeyForProvider(e.provider);if(!Xt(t))return;this.anthropicSubscriptionWarningShown=!0,this.showWarning(we)}catch{}}showModelSelector(e){this.showSelector(s=>{const t=new It(this.ui,this.session.model,this.settingsManager,this.session.modelRegistry,this.session.scopedModels,async i=>{try{await this.session.setModel(i),this.footer.invalidate(),this.updateEditorBorderColor(),s(),this.showStatus(`Model: ${i.id}`),this.maybeWarnAboutAnthropicSubscriptionAuth(i),this.checkDaxnutsEasterEgg(i)}catch(n){s(),this.showError(n instanceof Error?n.message:String(n))}},()=>{s(),this.ui.requestRender()},e);return{component:t,focus:t}})}async showModelsSelector(){this.session.modelRegistry.refresh();const e=this.session.modelRegistry.getAvailable();if(e.length===0){this.showStatus("No models available");return}const s=this.session.scopedModels,t=s.length>0;let i=null;if(t)i=s.map(o=>`${o.model.provider}/${o.model.id}`);else{const o=this.settingsManager.getEnabledModels();o!==void 0&&o.length>0&&(i=(await ne(o,this.session.modelRegistry)).map(d=>`${d.model.provider}/${d.model.id}`))}const n=h(async o=>{if(i=o===null?null:[...o],o&&o.length>0&&o.length<e.length){const r=await ne(o,this.session.modelRegistry);this.session.setScopedModels(r.map(d=>({model:d.model,thinkingLevel:d.thinkingLevel})))}else this.session.setScopedModels([]);await this.updateAvailableProviderCount(),this.ui.requestRender()},"updateSessionModels");this.showSelector(o=>{const r=new Dt({allModels:e,enabledModelIds:i},{onChange:h(async d=>{await n(d)},"onChange"),onPersist:h(d=>{const l=d===null||d.length===e.length?void 0:d;this.settingsManager.setEnabledModels(l?[...l]:void 0),this.showStatus("Model selection saved to settings")},"onPersist"),onCancel:h(()=>{o(),this.ui.requestRender()},"onCancel")});return{component:r,focus:r}})}showUserMessageSelector(){const e=this.session.getUserMessagesForForking();if(e.length===0){this.showStatus("No messages to fork from");return}const s=e[e.length-1]?.entryId;this.showSelector(t=>{const i=new qt(e.map(n=>({id:n.entryId,text:n.text})),async n=>{try{const o=await this.runtimeHost.fork(n);if(o.cancelled){t(),this.ui.requestRender();return}this.renderCurrentSessionState(),this.editor.setText(o.selectedText??""),t(),this.showStatus("Forked to new session")}catch(o){t(),this.showError(o instanceof Error?o.message:String(o))}},()=>{t(),this.ui.requestRender()},s);return{component:i,focus:i.getMessageList()}})}async handleCloneCommand(){const e=this.sessionManager.getLeafId();if(!e){this.showStatus("Nothing to clone yet");return}try{if((await this.runtimeHost.fork(e,{position:"at"})).cancelled){this.ui.requestRender();return}this.renderCurrentSessionState(),this.editor.setText(""),this.showStatus("Cloned to new session")}catch(s){this.showError(s instanceof Error?s.message:String(s))}}showTreeSelector(e){const s=this.sessionManager.getTree(),t=this.sessionManager.getLeafId(),i=this.settingsManager.getTreeFilterMode();if(s.length===0){this.showStatus("No entries in session");return}this.showSelector(n=>{const o=new Ft(s,t,this.ui.terminal.rows,async r=>{if(r===t){n(),this.showStatus("Already at this point");return}n();let d=!1,l;if(!this.settingsManager.getBranchSummarySkipPrompt())for(;;){const c=await this.showExtensionSelector("Summarize branch?",["No summary","Summarize","Summarize with custom prompt"]);if(c===void 0){this.showTreeSelector(r);return}if(d=c!=="No summary",!(c==="Summarize with custom prompt"&&(l=await this.showExtensionEditor("Custom summarization instructions"),l===void 0)))break}let m;const u=this.defaultEditor.onEscape;d&&(this.defaultEditor.onEscape=()=>{this.session.abortBranchSummary()},this.chatContainer.addChild(new g(1)),m=new D(this.ui,c=>a.fg("accent",c),c=>a.fg("muted",c),`Summarizing branch... (${P("app.interrupt")} to cancel)`),this.statusContainer.addChild(m),this.ui.requestRender());try{const c=await this.session.navigateTree(r,{summarize:d,customInstructions:l});if(c.aborted){this.showStatus("Branch summarization cancelled"),this.showTreeSelector(r);return}if(c.cancelled){this.showStatus("Navigation cancelled");return}this.chatContainer.clear(),this.renderInitialMessages(),c.editorText&&!this.editor.getText().trim()&&this.editor.setText(c.editorText),this.showStatus("Navigated to selected point"),this.flushCompactionQueue({willRetry:!1})}catch(c){this.showError(c instanceof Error?c.message:String(c))}finally{m&&(m.stop(),this.statusContainer.clear()),this.defaultEditor.onEscape=u}},()=>{n(),this.ui.requestRender()},(r,d)=>{this.sessionManager.appendLabelChange(r,d),this.ui.requestRender()},e,i);return{component:o,focus:o}})}showSessionSelector(){this.showSelector(e=>{const s=new Lt(t=>B.list(this.sessionManager.getCwd(),this.sessionManager.getSessionDir(),t),t=>this.sessionManager.usesDefaultSessionDir()?B.listAll(t):B.listAll(this.sessionManager.getSessionDir(),t),async t=>{e(),await this.handleResumeSession(t)},()=>{e(),this.ui.requestRender()},()=>{this.shutdown()},()=>this.ui.requestRender(),{renameSession:h(async(t,i)=>{const n=(i??"").trim();if(!n)return;B.open(t).appendSessionInfo(n)},"renameSession"),showRenameHint:!0,keybindings:this.keybindings},this.sessionManager.getSessionFile());return{component:s,focus:s}})}async handleResumeSession(e,s){this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{const t=await this.runtimeHost.switchSession(e,{withSession:s?.withSession});return t.cancelled||(this.renderCurrentSessionState(),this.showStatus("Resumed session")),t}catch(t){if(t instanceof oe){const i=await this.promptForMissingSessionCwd(t);if(!i)return this.showStatus("Resume cancelled"),{cancelled:!0};const n=await this.runtimeHost.switchSession(e,{cwdOverride:i,withSession:s?.withSession});return n.cancelled||(this.renderCurrentSessionState(),this.showStatus("Resumed session in current cwd")),n}return this.handleFatalRuntimeError("Failed to resume session",t)}}getLoginProviderOptions(e){const t=this.session.modelRegistry.authStorage.getOAuthProviders(),i=new Set(t.map(d=>d.id)),n=t.map(d=>({id:d.id,name:d.name,authType:"oauth"})),o=new Set(this.session.modelRegistry.getAll().map(d=>d.provider));for(const d of o)is(d,i)&&n.push({id:d,name:this.session.modelRegistry.getProviderDisplayName(d),authType:"api_key"});return(e?n.filter(d=>d.authType===e):n).sort((d,l)=>d.name.localeCompare(l.name))}getLogoutProviderOptions(){const e=this.session.modelRegistry.authStorage,s=[];for(const t of e.list()){const i=e.get(t);i&&s.push({id:t,name:this.session.modelRegistry.getProviderDisplayName(t),authType:i.type})}return s.sort((t,i)=>t.name.localeCompare(i.name))}showLoginAuthTypeSelector(){const e="Use a subscription",s="Use an API key";this.showSelector(t=>{const i=new X("Select authentication method:",[e,s],n=>{t();const o=n===e?"oauth":"api_key";this.showLoginProviderSelector(o)},()=>{t(),this.ui.requestRender()});return{component:i,focus:i}})}showLoginProviderSelector(e){const s=this.getLoginProviderOptions(e);if(s.length===0){this.showStatus(e==="oauth"?"No subscription providers available.":"No API key providers available.");return}this.showSelector(t=>{const i=new pe("login",this.session.modelRegistry.authStorage,s,async n=>{t();const o=s.find(r=>r.id===n);o&&(o.authType==="oauth"?await this.showLoginDialog(o.id,o.name):o.id===ts?this.showBedrockSetupDialog(o.id,o.name):await this.showApiKeyLoginDialog(o.id,o.name))},()=>{t(),this.showLoginAuthTypeSelector()},n=>this.session.modelRegistry.getProviderAuthStatus(n));return{component:i,focus:i}})}async showOAuthSelector(e){if(e==="login"){this.showLoginAuthTypeSelector();return}const s=this.getLogoutProviderOptions();if(s.length===0){this.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");return}this.showSelector(t=>{const i=new pe(e,this.session.modelRegistry.authStorage,s,async n=>{t();const o=s.find(r=>r.id===n);if(o)try{this.session.modelRegistry.authStorage.logout(o.id),this.session.modelRegistry.refresh(),await this.updateAvailableProviderCount();const r=o.authType==="oauth"?`Logged out of ${o.name}`:`Removed stored API key for ${o.name}. Environment variables and models.json config are unchanged.`;this.showStatus(r)}catch(r){this.showError(`Logout failed: ${r instanceof Error?r.message:String(r)}`)}},()=>{t(),this.ui.requestRender()});return{component:i,focus:i}})}async completeProviderAuthentication(e,s,t,i){this.session.modelRegistry.refresh();const n=t==="oauth"?`Logged in to ${s}`:`Saved API key for ${s}`;let o,r;if(Jt(i)){const l=this.session.modelRegistry.getAvailable().filter(m=>m.provider===e);if(!es(e))r=`${n}, but no default model is configured for provider "${e}". Use /model to select a model.`;else if(l.length===0)r=`${n}, but no models are available for that provider. Use /model to select a model.`;else{const m=ie[e];if(o=l.find(u=>u.id===m),!o)r=`${n}, but its default model "${m}" is not available. Use /model to select a model.`;else try{await this.session.setModel(o)}catch(u){o=void 0;const c=u instanceof Error?u.message:String(u);r=`${n}, but selecting its default model failed: ${c}. Use /model to select a model.`}}}await this.updateAvailableProviderCount(),this.footer.invalidate(),this.updateEditorBorderColor(),o?(this.showStatus(`${n}. Selected ${o.id}. Credentials saved to ${se()}`),this.maybeWarnAboutAnthropicSubscriptionAuth(o),this.checkDaxnutsEasterEgg(o)):(this.showStatus(`${n}. Credentials saved to ${se()}`),r?this.showError(r):this.maybeWarnAboutAnthropicSubscriptionAuth())}showBedrockSetupDialog(e,s){const t=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor"),i=new J(this.ui,e,()=>t(),s,"Amazon Bedrock setup");i.showInfo([a.fg("text","Amazon Bedrock uses AWS credentials instead of a single API key."),a.fg("text","Configure an AWS profile, IAM keys, bearer token, or role-based credentials."),a.fg("muted","See:"),a.fg("accent",` ${E.join(Ye(),"providers.md")}`)]),this.editorContainer.clear(),this.editorContainer.addChild(i),this.ui.setFocus(i),this.ui.requestRender()}async showApiKeyLoginDialog(e,s){const t=this.session.model,i=new J(this.ui,e,(o,r)=>{},s);this.editorContainer.clear(),this.editorContainer.addChild(i),this.ui.setFocus(i),this.ui.requestRender();const n=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");try{const o=(await i.showPrompt("Enter API key:")).trim();if(!o)throw new Error("API key cannot be empty.");this.session.modelRegistry.authStorage.set(e,{type:"api_key",key:o}),n(),await this.completeProviderAuthentication(e,s,"api_key",t)}catch(o){n();const r=o instanceof Error?o.message:String(o);r!=="Login cancelled"&&this.showError(`Failed to save API key for ${s}: ${r}`)}}showOAuthLoginSelect(e,s){return new Promise(t=>{const i=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(e),this.ui.setFocus(e),this.ui.requestRender()},"restoreDialog"),n=s.options.map(r=>r.label),o=new X(s.message,n,r=>{i(),t(s.options.find(d=>d.label===r)?.id)},()=>{i(),t(void 0)});this.editorContainer.clear(),this.editorContainer.addChild(o),this.ui.setFocus(o),this.ui.requestRender()})}async showLoginDialog(e,s){const t=this.session.modelRegistry.authStorage.getOAuthProviders().find(u=>u.id===e),i=this.session.model,n=t?.usesCallbackServer??!1,o=new J(this.ui,e,(u,c)=>{},s);this.editorContainer.clear(),this.editorContainer.addChild(o),this.ui.setFocus(o),this.ui.requestRender();let r,d;const l=new Promise((u,c)=>{r=u,d=c}),m=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");try{await this.session.modelRegistry.authStorage.login(e,{onAuth:h(u=>{o.showAuth(u.url,u.instructions),n&&o.showManualInput("Paste redirect URL below, or complete login in browser:").then(c=>{c&&r&&(r(c),r=void 0)}).catch(()=>{d&&(d(new Error("Login cancelled")),d=void 0)})},"onAuth"),onDeviceCode:h(u=>{o.showDeviceCode(u),o.showWaiting("Waiting for authentication...")},"onDeviceCode"),onPrompt:h(async u=>o.showPrompt(u.message,u.placeholder),"onPrompt"),onProgress:h(u=>{o.showProgress(u)},"onProgress"),onSelect:h(u=>this.showOAuthLoginSelect(o,u),"onSelect"),onManualCodeInput:h(()=>l,"onManualCodeInput"),signal:o.signal}),m(),await this.completeProviderAuthentication(e,s,"oauth",i)}catch(u){m();const c=u instanceof Error?u.message:String(u);c!=="Login cancelled"&&this.showError(`Failed to login to ${s}: ${c}`)}}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 A,s=h(n=>a.fg("border",n),"borderColor");e.addChild(new k(s)),e.addChild(new g(1)),e.addChild(new f(a.fg("muted","Reloading keybindings, extensions, skills, prompts, themes..."),1,0)),e.addChild(new g(1)),e.addChild(new k(s));const t=this.editor;this.editorContainer.clear(),this.editorContainer.addChild(e),this.ui.setFocus(e),this.ui.requestRender(!0),await new Promise(n=>process.nextTick(n));const i=h(n=>{this.editorContainer.clear(),this.editorContainer.addChild(n),this.ui.setFocus(n),this.ui.requestRender()},"dismissReloadBox");try{await this.session.reload(),G(this.settingsManager.getHttpIdleTimeoutMs()),this.keybindings.reload();const n=this.customHeader??this.builtInHeader;H(n)&&n.setExpanded(this.toolOutputExpanded),Y(this.session.resourceLoader.getThemes().themes),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock();const o=this.settingsManager.getTheme(),r=o?O(o,!0):{success:!0};r.success||this.showError(`Failed to load theme "${o}": ${r.error}
|
|
40
|
-
Fell back to dark theme.`);const d=this.settingsManager.getEditorPaddingX(),l=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(d),this.defaultEditor.setAutocompleteMaxVisible(l),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(d),this.editor.setAutocompleteMaxVisible?.(l)),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.setupAutocompleteProvider();const
|
|
41
|
-
Gist: ${o}`)}catch(n){s.signal.aborted||(t(),this.showError(`Failed to create gist: ${n instanceof Error?n.message:"Unknown error"}`))}}async handleCopyCommand(){const e=this.session.getLastAssistantText();if(!e){this.showError("No agent messages to copy yet.");return}try{await
|
|
38
|
+
`);return this.editor.setText(r),this.updatePendingMessagesDisplay(),e?.abort&&this.agent.abort(),i.length}queueCompactionMessage(e,s){this.compactionQueuedMessages.push({text:e,mode:s}),this.editor.addToHistory?.(e),this.editor.setText(""),this.updatePendingMessagesDisplay(),this.showStatus("Queued message for after compaction")}isExtensionCommand(e){if(!e.startsWith("/"))return!1;const s=this.session.extensionRunner,t=e.indexOf(" "),i=t===-1?e.slice(1):e.slice(1,t);return!!s.getCommand(i)}async flushCompactionQueue(e){if(this.compactionQueuedMessages.length===0)return;const s=[...this.compactionQueuedMessages];this.compactionQueuedMessages=[],this.updatePendingMessagesDisplay();const t=h(i=>{this.session.clearQueue(),this.compactionQueuedMessages=s,this.updatePendingMessagesDisplay(),this.showError(`Failed to send queued message${s.length>1?"s":""}: ${i instanceof Error?i.message:String(i)}`)},"restoreQueue");try{if(e?.willRetry){for(const l of s)this.isExtensionCommand(l.text)?await this.session.prompt(l.text):l.mode==="followUp"?await this.session.followUp(l.text):await this.session.steer(l.text);this.updatePendingMessagesDisplay();return}const i=s.findIndex(l=>!this.isExtensionCommand(l.text));if(i===-1){for(const l of s)await this.session.prompt(l.text);return}const n=s.slice(0,i),o=s[i],r=s.slice(i+1);for(const l of n)await this.session.prompt(l.text);const d=this.session.prompt(o.text).catch(l=>{t(l)});for(const l of r)this.isExtensionCommand(l.text)?await this.session.prompt(l.text):l.mode==="followUp"?await this.session.followUp(l.text):await this.session.steer(l.text);this.updatePendingMessagesDisplay()}catch(i){t(i)}}flushPendingBashComponents(){for(const e of this.pendingBashComponents)this.pendingMessagesContainer.removeChild(e),this.chatContainer.addChild(e);this.pendingBashComponents=[]}showSelector(e){const s=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor)},"done"),{component:t,focus:i}=e(s);this.editorContainer.clear(),this.editorContainer.addChild(t),this.ui.setFocus(i),this.ui.requestRender()}showSettingsSelector(){this.showSelector(e=>{const s=new Ft({autoCompact:this.session.autoCompactionEnabled,showImages:this.settingsManager.getShowImages(),imageWidthCells:this.settingsManager.getImageWidthCells(),autoResizeImages:this.settingsManager.getImageAutoResize(),blockImages:this.settingsManager.getBlockImages(),enableSkillCommands:this.settingsManager.getEnableSkillCommands(),steeringMode:this.session.steeringMode,followUpMode:this.session.followUpMode,transport:this.settingsManager.getTransport(),httpIdleTimeoutMs:this.settingsManager.getHttpIdleTimeoutMs(),thinkingLevel:this.session.thinkingLevel,availableThinkingLevels:this.session.getAvailableThinkingLevels(),currentTheme:this.settingsManager.getTheme()||"dark",availableThemes:Ot(),hideThinkingBlock:this.hideThinkingBlock,collapseChangelog:this.settingsManager.getCollapseChangelog(),enableInstallTelemetry:this.settingsManager.getEnableInstallTelemetry(),doubleEscapeAction:this.settingsManager.getDoubleEscapeAction(),treeFilterMode:this.settingsManager.getTreeFilterMode(),showHardwareCursor:this.settingsManager.getShowHardwareCursor(),editorPaddingX:this.settingsManager.getEditorPaddingX(),autocompleteMaxVisible:this.settingsManager.getAutocompleteMaxVisible(),quietStartup:this.settingsManager.getQuietStartup(),clearOnShrink:this.settingsManager.getClearOnShrink(),showTerminalProgress:this.settingsManager.getShowTerminalProgress(),warnings:this.settingsManager.getWarnings()},{onAutoCompactChange:h(t=>{this.session.setAutoCompactionEnabled(t),this.footer.setAutoCompactEnabled(t)},"onAutoCompactChange"),onShowImagesChange:h(t=>{this.settingsManager.setShowImages(t);for(const i of this.chatContainer.children)i instanceof H&&i.setShowImages(t)},"onShowImagesChange"),onImageWidthCellsChange:h(t=>{this.settingsManager.setImageWidthCells(t);for(const i of this.chatContainer.children)i instanceof H&&i.setImageWidthCells(t)},"onImageWidthCellsChange"),onAutoResizeImagesChange:h(t=>{this.settingsManager.setImageAutoResize(t)},"onAutoResizeImagesChange"),onBlockImagesChange:h(t=>{this.settingsManager.setBlockImages(t)},"onBlockImagesChange"),onEnableSkillCommandsChange:h(t=>{this.settingsManager.setEnableSkillCommands(t),this.setupAutocompleteProvider()},"onEnableSkillCommandsChange"),onSteeringModeChange:h(t=>{this.session.setSteeringMode(t)},"onSteeringModeChange"),onFollowUpModeChange:h(t=>{this.session.setFollowUpMode(t)},"onFollowUpModeChange"),onTransportChange:h(t=>{this.settingsManager.setTransport(t),this.session.agent.transport=t},"onTransportChange"),onHttpIdleTimeoutMsChange:h(t=>{this.settingsManager.setHttpIdleTimeoutMs(t),G(t),this.showStatus(`HTTP idle timeout: ${rt(t)}`)},"onHttpIdleTimeoutMsChange"),onThinkingLevelChange:h(t=>{this.session.setThinkingLevel(t),this.footer.invalidate(),this.updateEditorBorderColor()},"onThinkingLevelChange"),onThemeChange:h(t=>{const i=O(t,!0);this.settingsManager.setTheme(t),this.ui.invalidate(),i.success||this.showError(`Failed to load theme "${t}": ${i.error}
|
|
39
|
+
Fell back to dark theme.`)},"onThemeChange"),onThemePreview:h(t=>{O(t,!0).success&&(this.ui.invalidate(),this.ui.requestRender())},"onThemePreview"),onHideThinkingBlockChange:h(t=>{this.hideThinkingBlock=t,this.settingsManager.setHideThinkingBlock(t);for(const i of this.chatContainer.children)i instanceof U&&i.setHideThinkingBlock(t);this.chatContainer.clear(),this.rebuildChatFromMessages()},"onHideThinkingBlockChange"),onCollapseChangelogChange:h(t=>{this.settingsManager.setCollapseChangelog(t)},"onCollapseChangelogChange"),onEnableInstallTelemetryChange:h(t=>{this.settingsManager.setEnableInstallTelemetry(t)},"onEnableInstallTelemetryChange"),onQuietStartupChange:h(t=>{this.settingsManager.setQuietStartup(t)},"onQuietStartupChange"),onDoubleEscapeActionChange:h(t=>{this.settingsManager.setDoubleEscapeAction(t)},"onDoubleEscapeActionChange"),onTreeFilterModeChange:h(t=>{this.settingsManager.setTreeFilterMode(t)},"onTreeFilterModeChange"),onShowHardwareCursorChange:h(t=>{this.settingsManager.setShowHardwareCursor(t),this.ui.setShowHardwareCursor(t)},"onShowHardwareCursorChange"),onEditorPaddingXChange:h(t=>{this.settingsManager.setEditorPaddingX(t),this.defaultEditor.setPaddingX(t),this.editor!==this.defaultEditor&&this.editor.setPaddingX!==void 0&&this.editor.setPaddingX(t)},"onEditorPaddingXChange"),onAutocompleteMaxVisibleChange:h(t=>{this.settingsManager.setAutocompleteMaxVisible(t),this.defaultEditor.setAutocompleteMaxVisible(t),this.editor!==this.defaultEditor&&this.editor.setAutocompleteMaxVisible!==void 0&&this.editor.setAutocompleteMaxVisible(t)},"onAutocompleteMaxVisibleChange"),onClearOnShrinkChange:h(t=>{this.settingsManager.setClearOnShrink(t),this.ui.setClearOnShrink(t)},"onClearOnShrinkChange"),onShowTerminalProgressChange:h(t=>{this.settingsManager.setShowTerminalProgress(t)},"onShowTerminalProgressChange"),onWarningsChange:h(t=>{this.settingsManager.setWarnings(t)},"onWarningsChange"),onImportSessions:h(()=>{e(),this.ui.requestRender(),this.runImportFromSettings()},"onImportSessions"),onCancel:h(()=>{e(),this.ui.requestRender()},"onCancel")});return{component:s,focus:s.getSettingsList()}})}async handleModelCommand(e){if(!e){this.showModelSelector();return}const s=await this.findExactModelMatch(e);if(s){try{await this.session.setModel(s),this.footer.invalidate(),this.updateEditorBorderColor(),this.showStatus(`Model: ${s.id}`),this.maybeWarnAboutAnthropicSubscriptionAuth(s),this.checkDaxnutsEasterEgg(s)}catch(t){this.showError(t instanceof Error?t.message:String(t))}return}this.showModelSelector(e)}async findExactModelMatch(e){const s=await this.getModelCandidates();return dt(e,s)}async getModelCandidates(){if(this.session.scopedModels.length>0)return this.session.scopedModels.map(e=>e.model);this.session.modelRegistry.refresh();try{return await this.session.modelRegistry.getAvailable()}catch{return[]}}async updateAvailableProviderCount(){const e=await this.getModelCandidates(),s=new Set(e.map(t=>t.provider));this.footerDataProvider.setAvailableProviderCount(s.size)}async maybeWarnAboutAnthropicSubscriptionAuth(e=this.session.model){if(this.settingsManager.getWarnings().anthropicExtraUsage===!1||this.anthropicSubscriptionWarningShown||!e||e.provider!=="anthropic")return;if(this.session.modelRegistry.authStorage.get("anthropic")?.type==="oauth"){this.anthropicSubscriptionWarningShown=!0,this.showWarning(we);return}try{const t=await this.session.modelRegistry.getApiKeyForProvider(e.provider);if(!Yt(t))return;this.anthropicSubscriptionWarningShown=!0,this.showWarning(we)}catch{}}showModelSelector(e){this.showSelector(s=>{const t=new Lt(this.ui,this.session.model,this.settingsManager,this.session.modelRegistry,this.session.scopedModels,async i=>{try{await this.session.setModel(i),this.footer.invalidate(),this.updateEditorBorderColor(),s(),this.showStatus(`Model: ${i.id}`),this.maybeWarnAboutAnthropicSubscriptionAuth(i),this.checkDaxnutsEasterEgg(i)}catch(n){s(),this.showError(n instanceof Error?n.message:String(n))}},()=>{s(),this.ui.requestRender()},e);return{component:t,focus:t}})}async showModelsSelector(){this.session.modelRegistry.refresh();const e=this.session.modelRegistry.getAvailable();if(e.length===0){this.showStatus("No models available");return}const s=this.session.scopedModels,t=s.length>0;let i=null;if(t)i=s.map(o=>`${o.model.provider}/${o.model.id}`);else{const o=this.settingsManager.getEnabledModels();o!==void 0&&o.length>0&&(i=(await ne(o,this.session.modelRegistry)).map(d=>`${d.model.provider}/${d.model.id}`))}const n=h(async o=>{if(i=o===null?null:[...o],o&&o.length>0&&o.length<e.length){const r=await ne(o,this.session.modelRegistry);this.session.setScopedModels(r.map(d=>({model:d.model,thinkingLevel:d.thinkingLevel})))}else this.session.setScopedModels([]);await this.updateAvailableProviderCount(),this.ui.requestRender()},"updateSessionModels");this.showSelector(o=>{const r=new Wt({allModels:e,enabledModelIds:i},{onChange:h(async d=>{await n(d)},"onChange"),onPersist:h(d=>{const l=d===null||d.length===e.length?void 0:d;this.settingsManager.setEnabledModels(l?[...l]:void 0),this.showStatus("Model selection saved to settings")},"onPersist"),onCancel:h(()=>{o(),this.ui.requestRender()},"onCancel")});return{component:r,focus:r}})}showUserMessageSelector(){const e=this.session.getUserMessagesForForking();if(e.length===0){this.showStatus("No messages to fork from");return}const s=e[e.length-1]?.entryId;this.showSelector(t=>{const i=new Ut(e.map(n=>({id:n.entryId,text:n.text})),async n=>{try{const o=await this.runtimeHost.fork(n);if(o.cancelled){t(),this.ui.requestRender();return}this.renderCurrentSessionState(),this.editor.setText(o.selectedText??""),t(),this.showStatus("Forked to new session")}catch(o){t(),this.showError(o instanceof Error?o.message:String(o))}},()=>{t(),this.ui.requestRender()},s);return{component:i,focus:i.getMessageList()}})}async handleCloneCommand(){const e=this.sessionManager.getLeafId();if(!e){this.showStatus("Nothing to clone yet");return}try{if((await this.runtimeHost.fork(e,{position:"at"})).cancelled){this.ui.requestRender();return}this.renderCurrentSessionState(),this.editor.setText(""),this.showStatus("Cloned to new session")}catch(s){this.showError(s instanceof Error?s.message:String(s))}}showTreeSelector(e){const s=this.sessionManager.getTree(),t=this.sessionManager.getLeafId(),i=this.settingsManager.getTreeFilterMode();if(s.length===0){this.showStatus("No entries in session");return}this.showSelector(n=>{const o=new Bt(s,t,this.ui.terminal.rows,async r=>{if(r===t){n(),this.showStatus("Already at this point");return}n();let d=!1,l;if(!this.settingsManager.getBranchSummarySkipPrompt())for(;;){const c=await this.showExtensionSelector("Summarize branch?",["No summary","Summarize","Summarize with custom prompt"]);if(c===void 0){this.showTreeSelector(r);return}if(d=c!=="No summary",!(c==="Summarize with custom prompt"&&(l=await this.showExtensionEditor("Custom summarization instructions"),l===void 0)))break}let p;const u=this.defaultEditor.onEscape;d&&(this.defaultEditor.onEscape=()=>{this.session.abortBranchSummary()},this.chatContainer.addChild(new g(1)),p=new D(this.ui,c=>a.fg("accent",c),c=>a.fg("muted",c),`Summarizing branch... (${P("app.interrupt")} to cancel)`),this.statusContainer.addChild(p),this.ui.requestRender());try{const c=await this.session.navigateTree(r,{summarize:d,customInstructions:l});if(c.aborted){this.showStatus("Branch summarization cancelled"),this.showTreeSelector(r);return}if(c.cancelled){this.showStatus("Navigation cancelled");return}this.chatContainer.clear(),this.renderInitialMessages(),c.editorText&&!this.editor.getText().trim()&&this.editor.setText(c.editorText),this.showStatus("Navigated to selected point"),this.flushCompactionQueue({willRetry:!1})}catch(c){this.showError(c instanceof Error?c.message:String(c))}finally{p&&(p.stop(),this.statusContainer.clear()),this.defaultEditor.onEscape=u}},()=>{n(),this.ui.requestRender()},(r,d)=>{this.sessionManager.appendLabelChange(r,d),this.ui.requestRender()},e,i);return{component:o,focus:o}})}showSessionSelector(){this.showSelector(e=>{const s=new Ht(t=>W.list(this.sessionManager.getCwd(),this.sessionManager.getSessionDir(),t),t=>this.sessionManager.usesDefaultSessionDir()?W.listAll(t):W.listAll(this.sessionManager.getSessionDir(),t),async t=>{e(),await this.handleResumeSession(t)},()=>{e(),this.ui.requestRender()},()=>{this.shutdown()},()=>this.ui.requestRender(),{renameSession:h(async(t,i)=>{const n=(i??"").trim();if(!n)return;W.open(t).appendSessionInfo(n)},"renameSession"),showRenameHint:!0,keybindings:this.keybindings},this.sessionManager.getSessionFile());return{component:s,focus:s}})}async handleResumeSession(e,s){this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{const t=await this.runtimeHost.switchSession(e,{withSession:s?.withSession});return t.cancelled||(this.renderCurrentSessionState(),this.showStatus("Resumed session")),t}catch(t){if(t instanceof oe){const i=await this.promptForMissingSessionCwd(t);if(!i)return this.showStatus("Resume cancelled"),{cancelled:!0};const n=await this.runtimeHost.switchSession(e,{cwdOverride:i,withSession:s?.withSession});return n.cancelled||(this.renderCurrentSessionState(),this.showStatus("Resumed session in current cwd")),n}return this.handleFatalRuntimeError("Failed to resume session",t)}}getLoginProviderOptions(e){const t=this.session.modelRegistry.authStorage.getOAuthProviders(),i=new Set(t.map(d=>d.id)),n=t.map(d=>({id:d.id,name:d.name,authType:"oauth"})),o=new Set(this.session.modelRegistry.getAll().map(d=>d.provider));for(const d of o)rs(d,i)&&n.push({id:d,name:this.session.modelRegistry.getProviderDisplayName(d),authType:"api_key"});return(e?n.filter(d=>d.authType===e):n).sort((d,l)=>d.name.localeCompare(l.name))}getLogoutProviderOptions(){const e=this.session.modelRegistry.authStorage,s=[];for(const t of e.list()){const i=e.get(t);i&&s.push({id:t,name:this.session.modelRegistry.getProviderDisplayName(t),authType:i.type})}return s.sort((t,i)=>t.name.localeCompare(i.name))}showLoginAuthTypeSelector(){const e="Use a subscription",s="Use an API key";this.showSelector(t=>{const i=new X("Select authentication method:",[e,s],n=>{t();const o=n===e?"oauth":"api_key";this.showLoginProviderSelector(o)},()=>{t(),this.ui.requestRender()});return{component:i,focus:i}})}showLoginProviderSelector(e){const s=this.getLoginProviderOptions(e);if(s.length===0){this.showStatus(e==="oauth"?"No subscription providers available.":"No API key providers available.");return}this.showSelector(t=>{const i=new pe("login",this.session.modelRegistry.authStorage,s,async n=>{t();const o=s.find(r=>r.id===n);o&&(o.authType==="oauth"?await this.showLoginDialog(o.id,o.name):o.id===ns?this.showBedrockSetupDialog(o.id,o.name):await this.showApiKeyLoginDialog(o.id,o.name))},()=>{t(),this.showLoginAuthTypeSelector()},n=>this.session.modelRegistry.getProviderAuthStatus(n));return{component:i,focus:i}})}async showOAuthSelector(e){if(e==="login"){this.showLoginAuthTypeSelector();return}const s=this.getLogoutProviderOptions();if(s.length===0){this.showStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");return}this.showSelector(t=>{const i=new pe(e,this.session.modelRegistry.authStorage,s,async n=>{t();const o=s.find(r=>r.id===n);if(o)try{this.session.modelRegistry.authStorage.logout(o.id),this.session.modelRegistry.refresh(),await this.updateAvailableProviderCount();const r=o.authType==="oauth"?`Logged out of ${o.name}`:`Removed stored API key for ${o.name}. Environment variables and models.json config are unchanged.`;this.showStatus(r)}catch(r){this.showError(`Logout failed: ${r instanceof Error?r.message:String(r)}`)}},()=>{t(),this.ui.requestRender()});return{component:i,focus:i}})}async completeProviderAuthentication(e,s,t,i){this.session.modelRegistry.refresh();const n=t==="oauth"?`Logged in to ${s}`:`Saved API key for ${s}`;let o,r;if(Zt(i)){const l=this.session.modelRegistry.getAvailable().filter(p=>p.provider===e);if(!is(e))r=`${n}, but no default model is configured for provider "${e}". Use /model to select a model.`;else if(l.length===0)r=`${n}, but no models are available for that provider. Use /model to select a model.`;else{const p=ie[e];if(o=l.find(u=>u.id===p),!o)r=`${n}, but its default model "${p}" is not available. Use /model to select a model.`;else try{await this.session.setModel(o)}catch(u){o=void 0;const c=u instanceof Error?u.message:String(u);r=`${n}, but selecting its default model failed: ${c}. Use /model to select a model.`}}}await this.updateAvailableProviderCount(),this.footer.invalidate(),this.updateEditorBorderColor(),o?(this.showStatus(`${n}. Selected ${o.id}. Credentials saved to ${se()}`),this.maybeWarnAboutAnthropicSubscriptionAuth(o),this.checkDaxnutsEasterEgg(o)):(this.showStatus(`${n}. Credentials saved to ${se()}`),r?this.showError(r):this.maybeWarnAboutAnthropicSubscriptionAuth())}showBedrockSetupDialog(e,s){const t=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor"),i=new J(this.ui,e,()=>t(),s,"Amazon Bedrock setup");i.showInfo([a.fg("text","Amazon Bedrock uses AWS credentials instead of a single API key."),a.fg("text","Configure an AWS profile, IAM keys, bearer token, or role-based credentials."),a.fg("muted","See:"),a.fg("accent",` ${E.join(et(),"providers.md")}`)]),this.editorContainer.clear(),this.editorContainer.addChild(i),this.ui.setFocus(i),this.ui.requestRender()}async showApiKeyLoginDialog(e,s){const t=this.session.model,i=new J(this.ui,e,(o,r)=>{},s);this.editorContainer.clear(),this.editorContainer.addChild(i),this.ui.setFocus(i),this.ui.requestRender();const n=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");try{const o=(await i.showPrompt("Enter API key:")).trim();if(!o)throw new Error("API key cannot be empty.");this.session.modelRegistry.authStorage.set(e,{type:"api_key",key:o}),n(),await this.completeProviderAuthentication(e,s,"api_key",t)}catch(o){n();const r=o instanceof Error?o.message:String(o);r!=="Login cancelled"&&this.showError(`Failed to save API key for ${s}: ${r}`)}}showOAuthLoginSelect(e,s){return new Promise(t=>{const i=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(e),this.ui.setFocus(e),this.ui.requestRender()},"restoreDialog"),n=s.options.map(r=>r.label),o=new X(s.message,n,r=>{i(),t(s.options.find(d=>d.label===r)?.id)},()=>{i(),t(void 0)});this.editorContainer.clear(),this.editorContainer.addChild(o),this.ui.setFocus(o),this.ui.requestRender()})}async showLoginDialog(e,s){const t=this.session.modelRegistry.authStorage.getOAuthProviders().find(u=>u.id===e),i=this.session.model,n=t?.usesCallbackServer??!1,o=new J(this.ui,e,(u,c)=>{},s);this.editorContainer.clear(),this.editorContainer.addChild(o),this.ui.setFocus(o),this.ui.requestRender();let r,d;const l=new Promise((u,c)=>{r=u,d=c}),p=h(()=>{this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor),this.ui.requestRender()},"restoreEditor");try{await this.session.modelRegistry.authStorage.login(e,{onAuth:h(u=>{o.showAuth(u.url,u.instructions),n&&o.showManualInput("Paste redirect URL below, or complete login in browser:").then(c=>{c&&r&&(r(c),r=void 0)}).catch(()=>{d&&(d(new Error("Login cancelled")),d=void 0)})},"onAuth"),onDeviceCode:h(u=>{o.showDeviceCode(u),o.showWaiting("Waiting for authentication...")},"onDeviceCode"),onPrompt:h(async u=>o.showPrompt(u.message,u.placeholder),"onPrompt"),onProgress:h(u=>{o.showProgress(u)},"onProgress"),onSelect:h(u=>this.showOAuthLoginSelect(o,u),"onSelect"),onManualCodeInput:h(()=>l,"onManualCodeInput"),signal:o.signal}),p(),await this.completeProviderAuthentication(e,s,"oauth",i)}catch(u){p();const c=u instanceof Error?u.message:String(u);c!=="Login cancelled"&&this.showError(`Failed to login to ${s}: ${c}`)}}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 A,s=h(n=>a.fg("border",n),"borderColor");e.addChild(new k(s)),e.addChild(new g(1)),e.addChild(new f(a.fg("muted","Reloading keybindings, extensions, skills, prompts, themes..."),1,0)),e.addChild(new g(1)),e.addChild(new k(s));const t=this.editor;this.editorContainer.clear(),this.editorContainer.addChild(e),this.ui.setFocus(e),this.ui.requestRender(!0),await new Promise(n=>process.nextTick(n));const i=h(n=>{this.editorContainer.clear(),this.editorContainer.addChild(n),this.ui.setFocus(n),this.ui.requestRender()},"dismissReloadBox");try{await this.session.reload(),G(this.settingsManager.getHttpIdleTimeoutMs()),this.keybindings.reload();const n=this.customHeader??this.builtInHeader;F(n)&&n.setExpanded(this.toolOutputExpanded),Y(this.session.resourceLoader.getThemes().themes),this.hideThinkingBlock=this.settingsManager.getHideThinkingBlock();const o=this.settingsManager.getTheme(),r=o?O(o,!0):{success:!0};r.success||this.showError(`Failed to load theme "${o}": ${r.error}
|
|
40
|
+
Fell back to dark theme.`);const d=this.settingsManager.getEditorPaddingX(),l=this.settingsManager.getAutocompleteMaxVisible();this.defaultEditor.setPaddingX(d),this.defaultEditor.setAutocompleteMaxVisible(l),this.editor!==this.defaultEditor&&(this.editor.setPaddingX?.(d),this.editor.setAutocompleteMaxVisible?.(l)),this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor()),this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink()),this.setupAutocompleteProvider();const p=this.session.extensionRunner;this.setupExtensionShortcuts(p),this.rebuildChatFromMessages(),i(this.editor),this.showLoadedResources({force:!1,showDiagnosticsWhenQuiet:!0});const u=this.session.modelRegistry.getError();u&&this.showError(`models.json error: ${u}`),this.showStatus("Reloaded keybindings, extensions, skills, prompts, themes")}catch(n){i(t),this.showError(`Reload failed: ${n instanceof Error?n.message:String(n)}`)}}async handleExportCommand(e){const s=this.getPathCommandArgument(e,"/export");try{if(s?.endsWith(".jsonl")){const t=this.session.exportToJsonl(s);this.showStatus(`Session exported to: ${t}`)}else{const t=await this.session.exportToHtml(s);this.showStatus(`Session exported to: ${t}`)}}catch(t){this.showError(`Failed to export session: ${t instanceof Error?t.message:"Unknown error"}`)}}getPathCommandArgument(e,s){if(e===s||!e.startsWith(`${s} `))return;const t=e.slice(s.length+1).trimStart();if(!t)return;const i=t[0];if(i==='"'||i==="'"){const o=t.indexOf(i,1);return o<0?void 0:t.slice(1,o)}const n=t.search(/\s/);return n<0?t:t.slice(0,n)}async handleImportCommand(e){const s=this.getPathCommandArgument(e,"/import");if(!s){this.showError("Usage: /import <path.jsonl>");return}if(!await this.showExtensionConfirm("Import session",`Replace current session with ${s}?`)){this.showStatus("Import cancelled");return}try{if(this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear(),(await this.runtimeHost.importFromJsonl(s)).cancelled){this.showStatus("Import cancelled");return}this.renderCurrentSessionState(),this.showStatus(`Session imported from: ${s}`)}catch(i){if(i instanceof oe){const n=await this.promptForMissingSessionCwd(i);if(!n){this.showStatus("Import cancelled");return}if((await this.runtimeHost.importFromJsonl(s,n)).cancelled){this.showStatus("Import cancelled");return}this.renderCurrentSessionState(),this.showStatus(`Session imported from: ${s}`);return}if(i instanceof nt){this.showError(`Failed to import session: ${i.message}`);return}await this.handleFatalRuntimeError("Failed to import session",i)}}async handleShareCommand(){try{if(Qe("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=E.join(q.tmpdir(),"session.html");try{await this.session.exportToHtml(e)}catch(n){this.showError(`Failed to export session: ${n instanceof Error?n.message:"Unknown error"}`);return}const s=new bt(this.ui,a,"Creating gist...");this.editorContainer.clear(),this.editorContainer.addChild(s),this.ui.setFocus(s),this.ui.requestRender();const t=h(()=>{s.dispose(),this.editorContainer.clear(),this.editorContainer.addChild(this.editor),this.ui.setFocus(this.editor);try{v.unlinkSync(e)}catch{}},"restoreEditor");let i=null;s.onAbort=()=>{i?.kill(),t(),this.showStatus("Share cancelled")};try{const n=await new Promise(l=>{i=j("gh",["gist","create","--public=false",e]);let p="",u="";i.stdout?.on("data",c=>{p+=c.toString()}),i.stderr?.on("data",c=>{u+=c.toString()}),i.on("close",c=>l({stdout:p,stderr:u,code:c}))});if(s.signal.aborted)return;if(t(),n.code!==0){const l=n.stderr?.trim()||"Unknown error";this.showError(`Failed to create gist: ${l}`);return}const o=n.stdout?.trim(),r=o?.split("/").pop();if(!r){this.showError("Failed to parse gist ID from gh output");return}const d=tt(r);this.showStatus(`Share URL: ${d}
|
|
41
|
+
Gist: ${o}`)}catch(n){s.signal.aborted||(t(),this.showError(`Failed to create gist: ${n instanceof Error?n.message:"Unknown error"}`))}}async handleCopyCommand(){const e=this.session.getLastAssistantText();if(!e){this.showError("No agent messages to copy yet.");return}try{await ft(e),this.showStatus("Copied last agent message to clipboard")}catch(s){this.showError(s instanceof Error?s.message:String(s))}}handleNameCommand(e){const s=e.replace(/^\/name\s*/,"").trim();if(!s){const t=this.sessionManager.getSessionName();t?(this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("dim",`Session name: ${t}`),1,0))):this.showWarning("Usage: /name <name>"),this.ui.requestRender();return}this.session.setSessionName(s),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(a.fg("dim",`Session name set: ${s}`),1,0)),this.ui.requestRender()}handleSessionCommand(){const e=this.session.getSessionStats(),s=this.sessionManager.getSessionName();let t=`${a.bold("Session Info")}
|
|
42
42
|
|
|
43
43
|
`;s&&(t+=`${a.fg("dim","Name:")} ${s}
|
|
44
44
|
`),t+=`${a.fg("dim","File:")} ${e.sessionFile??"In-memory"}
|
|
@@ -61,7 +61,7 @@ Gist: ${o}`)}catch(n){s.signal.aborted||(t(),this.showError(`Failed to create gi
|
|
|
61
61
|
${a.bold("Cost")}
|
|
62
62
|
`,t+=`${a.fg("dim","Total:")} ${e.cost.toFixed(4)}`),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(t,1,0)),this.ui.requestRender()}handleChangelogCommand(){const e=ae(),s=he(e),t=s.length>0?s.reverse().map(i=>i.content).join(`
|
|
63
63
|
|
|
64
|
-
`):"No changelog entries found.";this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new
|
|
64
|
+
`):"No changelog entries found.";this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","What's New")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new B(t,1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new k),this.ui.requestRender()}getAppKeyDisplay(e){return ue(e)}getEditorKeyDisplay(e){return ue(e)}handleHotkeysCommand(){const e=this.getEditorKeyDisplay("tui.editor.cursorUp"),s=this.getEditorKeyDisplay("tui.editor.cursorDown"),t=this.getEditorKeyDisplay("tui.editor.cursorLeft"),i=this.getEditorKeyDisplay("tui.editor.cursorRight"),n=this.getEditorKeyDisplay("tui.editor.cursorWordLeft"),o=this.getEditorKeyDisplay("tui.editor.cursorWordRight"),r=this.getEditorKeyDisplay("tui.editor.cursorLineStart"),d=this.getEditorKeyDisplay("tui.editor.cursorLineEnd"),l=this.getEditorKeyDisplay("tui.editor.jumpForward"),p=this.getEditorKeyDisplay("tui.editor.jumpBackward"),u=this.getEditorKeyDisplay("tui.editor.pageUp"),c=this.getEditorKeyDisplay("tui.editor.pageDown"),y=this.getEditorKeyDisplay("tui.input.submit"),S=this.getEditorKeyDisplay("tui.input.newLine"),b=this.getEditorKeyDisplay("tui.editor.deleteWordBackward"),$=this.getEditorKeyDisplay("tui.editor.deleteWordForward"),M=this.getEditorKeyDisplay("tui.editor.deleteToLineStart"),x=this.getEditorKeyDisplay("tui.editor.deleteToLineEnd"),w=this.getEditorKeyDisplay("tui.editor.yank"),C=this.getEditorKeyDisplay("tui.editor.yankPop"),T=this.getEditorKeyDisplay("tui.editor.undo"),I=this.getEditorKeyDisplay("tui.input.tab"),Se=this.getAppKeyDisplay("app.interrupt"),ye=this.getAppKeyDisplay("app.clear"),Ee=this.getAppKeyDisplay("app.exit"),ke=this.getAppKeyDisplay("app.suspend"),be=this.getAppKeyDisplay("app.thinking.cycle"),Me=this.getAppKeyDisplay("app.model.cycleForward"),xe=this.getAppKeyDisplay("app.model.select"),Te=this.getAppKeyDisplay("app.tools.expand"),$e=this.getAppKeyDisplay("app.thinking.toggle"),Pe=this.getAppKeyDisplay("app.editor.external"),Ae=this.getAppKeyDisplay("app.model.cycleBackward"),Re=this.getAppKeyDisplay("app.message.followUp"),ve=this.getAppKeyDisplay("app.message.dequeue"),Ie=this.getAppKeyDisplay("app.clipboard.pasteImage");let N=`
|
|
65
65
|
**Navigation**
|
|
66
66
|
| Key | Action |
|
|
67
67
|
|-----|--------|
|
|
@@ -70,7 +70,7 @@ ${a.bold("Cost")}
|
|
|
70
70
|
| \`${r}\` | Start of line |
|
|
71
71
|
| \`${d}\` | End of line |
|
|
72
72
|
| \`${l}\` | Jump forward to character |
|
|
73
|
-
| \`${
|
|
73
|
+
| \`${p}\` | Jump backward to character |
|
|
74
74
|
| \`${u}\` / \`${c}\` | Scroll by page |
|
|
75
75
|
|
|
76
76
|
**Editing**
|
|
@@ -80,8 +80,8 @@ ${a.bold("Cost")}
|
|
|
80
80
|
| \`${S}\` | New line${process.platform==="win32"?" (Ctrl+Enter on Windows Terminal)":""} |
|
|
81
81
|
| \`${b}\` | Delete word backwards |
|
|
82
82
|
| \`${$}\` | Delete word forwards |
|
|
83
|
-
| \`${
|
|
84
|
-
| \`${
|
|
83
|
+
| \`${M}\` | Delete to start of line |
|
|
84
|
+
| \`${x}\` | Delete to end of line |
|
|
85
85
|
| \`${w}\` | Paste the most-recently-deleted text |
|
|
86
86
|
| \`${C}\` | Cycle through the deleted text after pasting |
|
|
87
87
|
| \`${T}\` | Undo |
|
|
@@ -95,8 +95,8 @@ ${a.bold("Cost")}
|
|
|
95
95
|
| \`${Ee}\` | Exit (when editor is empty) |
|
|
96
96
|
| \`${ke}\` | Suspend to background |
|
|
97
97
|
| \`${be}\` | Cycle thinking level |
|
|
98
|
-
| \`${
|
|
99
|
-
| \`${
|
|
98
|
+
| \`${Me}\` / \`${Ae}\` | Cycle models |
|
|
99
|
+
| \`${xe}\` | Open model selector |
|
|
100
100
|
| \`${Te}\` | Toggle tool output expansion |
|
|
101
101
|
| \`${$e}\` | Toggle thinking block visibility |
|
|
102
102
|
| \`${Pe}\` | Edit message in external editor |
|
|
@@ -111,6 +111,6 @@ ${a.bold("Cost")}
|
|
|
111
111
|
| Key | Action |
|
|
112
112
|
|-----|--------|
|
|
113
113
|
`;for(const[De,ee]of Z){const Le=ee.description??ee.extensionPath,We=ce(De,{capitalize:!0});N+=`| \`${We}\` | ${Le} |
|
|
114
|
-
`}}this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","Keyboard Shortcuts")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new
|
|
114
|
+
`}}this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","Keyboard Shortcuts")),1,0)),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new B(N.trim(),1,1,this.getMarkdownThemeWithSettings())),this.chatContainer.addChild(new k),this.ui.requestRender()}_goalAchievedShown=!1;renderGoalBlock(e){const s=e.milestones.filter(n=>n.done).length,t=e.milestones.length;this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k);const i=e.achieved?a.bold(a.fg("success",`\u2713 Goal achieved \u2014 ${e.text}`)):a.bold(a.fg("accent",`Goal \u2014 ${e.text}`))+a.fg("dim",` ${s}/${t}`);this.chatContainer.addChild(new f(i,1,0));for(const n of e.milestones){const o=n.done?a.fg("success","\u2713"):a.fg("dim","\u25CB"),r=n.done?a.fg("success",n.text):a.fg("text",n.text);this.chatContainer.addChild(new f(` ${o} ${r}`,1,0))}this.chatContainer.addChild(new k),this.ui.requestRender()}async handleGoalCommand(e){if(e==="clear"){this.session.clearSessionGoal();return}if(e){this._goalAchievedShown=!1,this.statusContainer.clear();const t=new D(this.ui,i=>a.fg("accent",i),i=>a.fg("muted",i),"Setting goal \u2014 breaking it into milestones\u2026");this.statusContainer.addChild(t),this.ui.requestRender();try{await this.session.setSessionGoal(e)}finally{t.stop(),this.statusContainer.clear(),this.ui.requestRender()}return}const s=this.session.getSessionGoal();if(!s){this.showStatus("No session goal set. Use /goal <what you want to accomplish this session>.");return}this.renderGoalBlock(s)}handleTraceCommand(){const e=this.session.getHarnessTrace();if(e.length===0){this.showStatus("No harness activity yet (no model switches, verification, or escalation this session).");return}this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new k),this.chatContainer.addChild(new f(a.bold(a.fg("accent","Harness trace")),1,0));for(const s of e.slice(-25)){const t=new Date(s.ts).toLocaleTimeString();this.chatContainer.addChild(new f(` ${a.fg("dim",t)} ${a.fg("accent",s.kind.padEnd(9))} ${a.fg("text",s.detail)}`,1,0))}this.chatContainer.addChild(new k),this.ui.requestRender()}handleUseCommand(e){const s=this.session.getPinnedSkills(),t=this.session.listSkillNames();if(!e){if(t.length===0){this.showStatus("No skills installed. Drop SKILL.md folders in ~/.koda/agent/skills.");return}const i=t.map(n=>s.includes(n)?`${n} (active)`:n).join(", ");this.showStatus(`Skills: ${i}. /use <name> to toggle on/off (no chat).`);return}if(e==="clear"||e==="none"){for(const i of s)this.session.unpinSkill(i);this.showStatus(s.length?`Skills off: ${s.join(", ")}.`:"No skills were active.");return}s.includes(e)?(this.session.unpinSkill(e),this.showStatus(`Skill "${e}" off.`)):this.session.pinSkill(e)?this.showStatus(`\u25B8 Skill "${e}" active for this session \u2014 it'll guide every task until /use ${e} again.`):this.showStatus(`No skill named "${e}". Available: ${t.join(", ")||"(none)"}.`)}async handleClearCommand(){this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{if((await this.runtimeHost.newSession()).cancelled)return;this.renderCurrentSessionState(),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(`${a.fg("accent","\u2713 New session started")}`,1,1)),this.ui.requestRender()}catch(e){await this.handleFatalRuntimeError("Failed to create session",e)}}handleDebugCommand(){const e=this.ui.terminal.columns,s=this.ui.terminal.rows,t=this.ui.render(e),i=Ze(),n=[`Debug output at ${new Date().toISOString()}`,`Terminal: ${e}x${s}`,`Total lines: ${t.length}`,"","=== All rendered lines with visible widths ===",...t.map((o,r)=>{const d=Ge(o),l=JSON.stringify(o);return`[${r}] (w=${d}) ${l}`}),"","=== Agent messages (JSONL) ===",...this.session.messages.map(o=>JSON.stringify(o)),""].join(`
|
|
115
115
|
`);v.mkdirSync(E.dirname(i),{recursive:!0}),v.writeFileSync(i,n),this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new f(`${a.fg("accent","\u2713 Debug log written")}
|
|
116
|
-
${a.fg("muted",i)}`,1,1)),this.ui.requestRender()}handleArminSaysHi(){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new
|
|
116
|
+
${a.fg("muted",i)}`,1,1)),this.ui.requestRender()}handleArminSaysHi(){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new kt(this.ui)),this.ui.requestRender()}handleDementedDelves(){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new Rt),this.ui.requestRender()}handleDaxnuts(){this.chatContainer.addChild(new g(1)),this.chatContainer.addChild(new At(this.ui)),this.ui.requestRender()}checkDaxnutsEasterEgg(e){e.provider==="opencode"&&e.id.toLowerCase().includes("kimi-k2.5")&&this.handleDaxnuts()}async handleBashCommand(e,s=!1){const i=await this.session.extensionRunner.emitUserBash({type:"user_bash",command:e,excludeFromContext:s,cwd:this.sessionManager.getCwd()});if(i?.result){const o=i.result;this.bashComponent=new Q(e,this.ui,s),this.session.isStreaming?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),o.output&&this.bashComponent.appendOutput(o.output),this.bashComponent.setComplete(o.exitCode,o.cancelled,o.truncated?{truncated:!0,content:o.output}:void 0,o.fullOutputPath),this.session.recordBashResult(e,o,{excludeFromContext:s}),this.bashComponent=void 0,this.ui.requestRender();return}const n=this.session.isStreaming;this.bashComponent=new Q(e,this.ui,s),n?(this.pendingMessagesContainer.addChild(this.bashComponent),this.pendingBashComponents.push(this.bashComponent)):this.chatContainer.addChild(this.bashComponent),this.ui.requestRender();try{const o=await this.session.executeBash(e,r=>{this.bashComponent&&(this.bashComponent.appendOutput(r),this.ui.requestRender())},{excludeFromContext:s,operations:i?.operations});this.bashComponent&&this.bashComponent.setComplete(o.exitCode,o.cancelled,o.truncated?{truncated:!0,content:o.output}:void 0,o.fullOutputPath)}catch(o){this.bashComponent&&this.bashComponent.setComplete(void 0,!1),this.showError(`Bash command failed: ${o instanceof Error?o.message:"Unknown error"}`)}this.bashComponent=void 0,this.ui.requestRender()}async handleCompactCommand(e){if(this.sessionManager.getEntries().filter(i=>i.type==="message").length<2){this.showWarning("Nothing to compact (no messages yet)");return}this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.statusContainer.clear();try{await this.session.compact(e)}catch{}}stop(){this.unregisterSignalHandlers(),this.settingsManager.getShowTerminalProgress()&&this.ui.terminal.setProgress(!1),this.loadingAnimation&&(this.loadingAnimation.stop(),this.loadingAnimation=void 0),this.clearExtensionTerminalInputListeners(),this.footer.dispose(),this.footerDataProvider.dispose(),this.unsubscribe&&this.unsubscribe(),this.isInitialized&&(this.ui.stop(),this.isInitialized=!1)}}export{_ as InteractiveMode,ss as formatResumeCommand,rs as isApiKeyLoginProvider};
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openadapter/koda",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.5",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openadapter/koda",
|
|
9
|
-
"version": "1.0.0-beta.
|
|
9
|
+
"version": "1.0.0-beta.5",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@openadapter/koda-agent-core": "1.0.0-beta.
|
|
13
|
-
"@openadapter/koda-ai": "1.0.0-beta.
|
|
14
|
-
"@openadapter/koda-tui": "1.0.0-beta.
|
|
12
|
+
"@openadapter/koda-agent-core": "1.0.0-beta.5",
|
|
13
|
+
"@openadapter/koda-ai": "1.0.0-beta.5",
|
|
14
|
+
"@openadapter/koda-tui": "1.0.0-beta.5",
|
|
15
15
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
16
16
|
"chalk": "5.6.2",
|
|
17
17
|
"cross-spawn": "7.0.6",
|
|
@@ -699,11 +699,11 @@
|
|
|
699
699
|
]
|
|
700
700
|
},
|
|
701
701
|
"node_modules/@openadapter/koda-agent-core": {
|
|
702
|
-
"version": "1.0.0-beta.
|
|
703
|
-
"resolved": "https://registry.npmjs.org/@openadapter/koda-agent-core/-/koda-agent-core-1.0.0-beta.
|
|
702
|
+
"version": "1.0.0-beta.5",
|
|
703
|
+
"resolved": "https://registry.npmjs.org/@openadapter/koda-agent-core/-/koda-agent-core-1.0.0-beta.5.tgz",
|
|
704
704
|
"license": "MIT",
|
|
705
705
|
"dependencies": {
|
|
706
|
-
"@openadapter/koda-ai": "1.0.0-beta.
|
|
706
|
+
"@openadapter/koda-ai": "1.0.0-beta.5",
|
|
707
707
|
"ignore": "7.0.5",
|
|
708
708
|
"typebox": "1.1.38",
|
|
709
709
|
"yaml": "2.9.0"
|
|
@@ -713,8 +713,8 @@
|
|
|
713
713
|
}
|
|
714
714
|
},
|
|
715
715
|
"node_modules/@openadapter/koda-ai": {
|
|
716
|
-
"version": "1.0.0-beta.
|
|
717
|
-
"resolved": "https://registry.npmjs.org/@openadapter/koda-ai/-/koda-ai-1.0.0-beta.
|
|
716
|
+
"version": "1.0.0-beta.5",
|
|
717
|
+
"resolved": "https://registry.npmjs.org/@openadapter/koda-ai/-/koda-ai-1.0.0-beta.5.tgz",
|
|
718
718
|
"license": "MIT",
|
|
719
719
|
"dependencies": {
|
|
720
720
|
"@anthropic-ai/sdk": "0.91.1",
|
|
@@ -736,8 +736,8 @@
|
|
|
736
736
|
}
|
|
737
737
|
},
|
|
738
738
|
"node_modules/@openadapter/koda-tui": {
|
|
739
|
-
"version": "1.0.0-beta.
|
|
740
|
-
"resolved": "https://registry.npmjs.org/@openadapter/koda-tui/-/koda-tui-1.0.0-beta.
|
|
739
|
+
"version": "1.0.0-beta.5",
|
|
740
|
+
"resolved": "https://registry.npmjs.org/@openadapter/koda-tui/-/koda-tui-1.0.0-beta.5.tgz",
|
|
741
741
|
"license": "MIT",
|
|
742
742
|
"dependencies": {
|
|
743
743
|
"get-east-asian-width": "1.6.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openadapter/koda",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.5",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"piConfig": {
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"postbuild": "node ../../scripts/minify-pkg-dist.mjs"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@openadapter/koda-agent-core": "1.0.0-beta.
|
|
46
|
-
"@openadapter/koda-ai": "1.0.0-beta.
|
|
47
|
-
"@openadapter/koda-tui": "1.0.0-beta.
|
|
45
|
+
"@openadapter/koda-agent-core": "1.0.0-beta.5",
|
|
46
|
+
"@openadapter/koda-ai": "1.0.0-beta.5",
|
|
47
|
+
"@openadapter/koda-tui": "1.0.0-beta.5",
|
|
48
48
|
"@silvia-odwyer/photon-node": "0.3.4",
|
|
49
49
|
"chalk": "5.6.2",
|
|
50
50
|
"cross-spawn": "7.0.6",
|