@kolisachint/hoocode-agent 0.5.55 → 0.5.57

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.
Files changed (80) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/dist/core/keybindings.d.ts +12 -12
  3. package/dist/core/keybindings.d.ts.map +1 -1
  4. package/dist/core/keybindings.js +17 -16
  5. package/dist/core/keybindings.js.map +1 -1
  6. package/dist/core/session-identity.d.ts +11 -0
  7. package/dist/core/session-identity.d.ts.map +1 -1
  8. package/dist/core/session-identity.js +16 -0
  9. package/dist/core/session-identity.js.map +1 -1
  10. package/dist/core/settings-defaults.d.ts +1 -1
  11. package/dist/core/settings-defaults.d.ts.map +1 -1
  12. package/dist/core/settings-defaults.js +1 -1
  13. package/dist/core/settings-defaults.js.map +1 -1
  14. package/dist/core/settings-manager.d.ts +1 -1
  15. package/dist/core/settings-manager.d.ts.map +1 -1
  16. package/dist/core/settings-manager.js +1 -1
  17. package/dist/core/settings-manager.js.map +1 -1
  18. package/dist/core/settings-types.d.ts +1 -1
  19. package/dist/core/settings-types.d.ts.map +1 -1
  20. package/dist/core/settings-types.js.map +1 -1
  21. package/dist/core/tool-output-view.d.ts +28 -10
  22. package/dist/core/tool-output-view.d.ts.map +1 -1
  23. package/dist/core/tool-output-view.js +24 -9
  24. package/dist/core/tool-output-view.js.map +1 -1
  25. package/dist/core/tools/bash.d.ts.map +1 -1
  26. package/dist/core/tools/bash.js +2 -2
  27. package/dist/core/tools/bash.js.map +1 -1
  28. package/dist/core/tools/plugins.d.ts.map +1 -1
  29. package/dist/core/tools/plugins.js +2 -1
  30. package/dist/core/tools/plugins.js.map +1 -1
  31. package/dist/core/tools/read.d.ts.map +1 -1
  32. package/dist/core/tools/read.js +2 -1
  33. package/dist/core/tools/read.js.map +1 -1
  34. package/dist/core/tools/search.d.ts.map +1 -1
  35. package/dist/core/tools/search.js +2 -1
  36. package/dist/core/tools/search.js.map +1 -1
  37. package/dist/core/tools/webfetch.d.ts.map +1 -1
  38. package/dist/core/tools/webfetch.js +2 -1
  39. package/dist/core/tools/webfetch.js.map +1 -1
  40. package/dist/core/tools/websearch.d.ts.map +1 -1
  41. package/dist/core/tools/websearch.js +2 -1
  42. package/dist/core/tools/websearch.js.map +1 -1
  43. package/dist/core/tools/write.d.ts.map +1 -1
  44. package/dist/core/tools/write.js +2 -1
  45. package/dist/core/tools/write.js.map +1 -1
  46. package/dist/modes/interactive/command-executor.d.ts.map +1 -1
  47. package/dist/modes/interactive/command-executor.js +5 -5
  48. package/dist/modes/interactive/command-executor.js.map +1 -1
  49. package/dist/modes/interactive/components/footer.d.ts +1 -1
  50. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  51. package/dist/modes/interactive/components/footer.js +3 -2
  52. package/dist/modes/interactive/components/footer.js.map +1 -1
  53. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  54. package/dist/modes/interactive/components/settings-selector.js +1 -1
  55. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  56. package/dist/modes/interactive/components/tool-chain-summary.d.ts +2 -1
  57. package/dist/modes/interactive/components/tool-chain-summary.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/tool-chain-summary.js +2 -1
  59. package/dist/modes/interactive/components/tool-chain-summary.js.map +1 -1
  60. package/dist/modes/interactive/components/tool-chain.d.ts +2 -9
  61. package/dist/modes/interactive/components/tool-chain.d.ts.map +1 -1
  62. package/dist/modes/interactive/components/tool-chain.js +3 -20
  63. package/dist/modes/interactive/components/tool-chain.js.map +1 -1
  64. package/dist/modes/interactive/components/tool-execution.d.ts +16 -20
  65. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  66. package/dist/modes/interactive/components/tool-execution.js +38 -37
  67. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  68. package/dist/modes/interactive/components/tool-signal.d.ts.map +1 -1
  69. package/dist/modes/interactive/components/tool-signal.js +1 -1
  70. package/dist/modes/interactive/components/tool-signal.js.map +1 -1
  71. package/dist/modes/interactive/interactive-mode.d.ts +39 -20
  72. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  73. package/dist/modes/interactive/interactive-mode.js +77 -69
  74. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  75. package/docs/keybindings.md +5 -1
  76. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  77. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  78. package/examples/extensions/sandbox/package.json +1 -1
  79. package/examples/extensions/with-deps/package.json +1 -1
  80. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"command-executor.js","sourceRoot":"","sources":["../../../src/modes/interactive/command-executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extracted command handlers from InteractiveMode.\n * All methods receive dependencies via CommandContext rather than\n * reaching back into the parent class.\n */\n\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { Model } from \"@kolisachint/hoocode-ai\";\nimport type { EditorComponent, MarkdownTheme, TUI } from \"@kolisachint/hoocode-tui\";\nimport { type Container, Markdown, Spacer, Text, visibleWidth } from \"@kolisachint/hoocode-tui\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { getDebugLogPath, getShareViewerUrl } from \"../../config.js\";\nimport { loadAgentRegistry } from \"../../core/agent-registry.js\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.js\";\nimport { ChangeDirectoryError, SessionImportFileNotFoundError } from \"../../core/agent-session-runtime.js\";\nimport type { KeybindingsManager } from \"../../core/keybindings.js\";\nimport { MissingSessionCwdError } from \"../../core/session-cwd.js\";\nimport {\n\tparseSessionColorSlot,\n\tSESSION_COLOR_NAME_LIST,\n\tSESSION_COLOR_SLOTS,\n\tsessionColorName,\n} from \"../../core/session-identity.js\";\nimport type { SessionManager } from \"../../core/session-manager.js\";\nimport { getSubagentPool } from \"../../core/subagent-pool-instance.js\";\nimport type { SubagentResultFile } from \"../../core/subagent-result.js\";\nimport { getChangelogPath, parseChangelog } from \"../../utils/changelog.js\";\nimport { copyToClipboard } from \"../../utils/clipboard.js\";\nimport { BorderedLoader } from \"./components/bordered-loader.js\";\nimport { DynamicBorder } from \"./components/dynamic-border.js\";\nimport type { FooterComponent } from \"./components/footer.js\";\nimport { formatKeyText, keyDisplayText } from \"./components/keybinding-hints.js\";\nimport { renderSessionChip } from \"./components/session-chip.js\";\nimport { theme } from \"./theme/theme.js\";\n\nexport interface CommandContext {\n\t// Core dependencies\n\tsession: AgentSession;\n\tsessionManager: SessionManager;\n\truntimeHost: AgentSessionRuntime;\n\tui: TUI;\n\teditor: EditorComponent;\n\teditorContainer: Container;\n\tchatContainer: Container;\n\tstatusContainer: Container;\n\tfooter: FooterComponent;\n\tkeybindings: KeybindingsManager;\n\n\t// UI callbacks\n\tshowStatus: (message: string) => void;\n\tshowError: (message: string) => void;\n\tshowWarning: (message: string) => void;\n\tupdateEditorBorderColor: () => void;\n\trenderCurrentSessionState: () => void;\n\trebuildChatFromMessages: () => void;\n\tgetMarkdownThemeWithSettings: () => MarkdownTheme;\n\tstopLoadingAnimation: () => void;\n\n\t// Auth/model helpers\n\tfindExactModelMatch: (searchTerm: string) => Promise<Model<any> | undefined>;\n\tmaybeWarnAboutAnthropicSubscriptionAuth: (model?: Model<any>) => Promise<void>;\n\n\t// Dialog callbacks\n\tshowModelSelector: (searchTerm?: string) => void;\n\tshowExtensionConfirm: (title: string, message: string) => Promise<boolean>;\n\tpromptForMissingSessionCwd: (error: MissingSessionCwdError) => Promise<string | undefined>;\n\n\t// Fatal error handler\n\thandleFatalRuntimeError: (prefix: string, error: unknown) => Promise<never>;\n}\n\nexport class CommandExecutor {\n\t/** Where `/cd -` returns to. Set on every successful move, session-local. */\n\tprivate previousCwd?: string;\n\n\tconstructor(private readonly ctx: CommandContext) {}\n\n\t// =========================================================================\n\t// Slash command handlers\n\t// =========================================================================\n\n\tasync handleModel(searchTerm?: string): Promise<void> {\n\t\tif (!searchTerm) {\n\t\t\tthis.ctx.showModelSelector();\n\t\t\treturn;\n\t\t}\n\n\t\tconst model = await this.ctx.findExactModelMatch(searchTerm);\n\t\tif (model) {\n\t\t\ttry {\n\t\t\t\tawait this.ctx.session.setModel(model);\n\t\t\t\tthis.ctx.footer.invalidate();\n\t\t\t\tthis.ctx.updateEditorBorderColor();\n\t\t\t\tthis.ctx.showStatus(`Model: ${model.id}`);\n\t\t\t\tvoid this.ctx.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\t} catch (error) {\n\t\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.showModelSelector(searchTerm);\n\t}\n\n\tasync handleClone(): Promise<void> {\n\t\tconst leafId = this.ctx.sessionManager.getLeafId();\n\t\tif (!leafId) {\n\t\t\tthis.ctx.showStatus(\"Nothing to clone yet\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.ctx.runtimeHost.fork(leafId, { position: \"at\" });\n\t\t\tif (result.cancelled) {\n\t\t\t\tthis.ctx.ui.requestRender();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.editor.setText(\"\");\n\t\t\tthis.ctx.showStatus(\"Cloned to new session\");\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\tasync handleSubagent(text: string): Promise<void> {\n\t\tconst prefix = \"/subagent \";\n\t\tconst args = text.startsWith(prefix) ? text.slice(prefix.length).trim() : \"\";\n\t\tif (!args) {\n\t\t\tthis.ctx.showStatus(\"Usage: /subagent <mode> <task>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst firstSpace = args.indexOf(\" \");\n\t\tif (firstSpace === -1) {\n\t\t\tthis.ctx.showStatus(\"Usage: /subagent <mode> <task>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst mode = args.slice(0, firstSpace).trim();\n\t\tconst task = args.slice(firstSpace + 1).trim();\n\t\tif (!task) {\n\t\t\tthis.ctx.showStatus(\"Usage: /subagent <mode> <task>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst validModes = loadAgentRegistry({ cwd: this.ctx.sessionManager.getCwd() })\n\t\t\t.list()\n\t\t\t.map((a) => a.name);\n\t\tif (!validModes.includes(mode)) {\n\t\t\tthis.ctx.showStatus(`Unknown subagent_type: ${mode}. Available: ${validModes.join(\", \")}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.showStatus(`Spawning ${mode} subagent...`);\n\t\ttry {\n\t\t\tconst pool = getSubagentPool(this.ctx.sessionManager.getCwd(), this.ctx.session.modelRegistry.getAvailable());\n\t\t\tconst dispatchResult = await pool.dispatch(task, {\n\t\t\t\tforceAgent: mode,\n\t\t\t\tmodel: this.ctx.session.model?.id,\n\t\t\t\tprovider: this.ctx.session.model?.provider,\n\t\t\t});\n\t\t\tconst result = dispatchResult.result;\n\t\t\tconst resultData = result?.result_data as SubagentResultFile | undefined;\n\t\t\tif (result?.ok) {\n\t\t\t\tthis.ctx.showStatus(`${mode} subagent completed`);\n\t\t\t\t// Inject the subagent answer as a custom message so the user can see it in the chat\n\t\t\t\tthis.ctx.sessionManager.appendMessage({\n\t\t\t\t\trole: \"custom\",\n\t\t\t\t\tcustomType: \"subagent\",\n\t\t\t\t\tcontent: resultData?.summary || \"(no output)\",\n\t\t\t\t\tdisplay: true,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.ctx.showError(`Subagent (${mode}) failed: ${result?.error ?? \"unknown error\"}`);\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\tasync handleExport(text: string): Promise<void> {\n\t\tconst outputPath = this.getPathArgument(text, \"/export\");\n\n\t\ttry {\n\t\t\tif (outputPath?.endsWith(\".jsonl\")) {\n\t\t\t\tconst filePath = this.ctx.session.exportToJsonl(outputPath);\n\t\t\t\tthis.ctx.showStatus(`Session exported to: ${filePath}`);\n\t\t\t} else {\n\t\t\t\tconst filePath = await this.ctx.session.exportToHtml(outputPath);\n\t\t\t\tthis.ctx.showStatus(`Session exported to: ${filePath}`);\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\t}\n\n\tprivate getPathArgument(text: string, command: \"/export\" | \"/import\"): string | undefined {\n\t\tif (text === command) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (!text.startsWith(`${command} `)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst argsString = text.slice(command.length + 1).trimStart();\n\t\tif (!argsString) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst firstChar = argsString[0];\n\t\tif (firstChar === '\"' || firstChar === \"'\") {\n\t\t\tconst closingQuoteIndex = argsString.indexOf(firstChar, 1);\n\t\t\tif (closingQuoteIndex < 0) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn argsString.slice(1, closingQuoteIndex);\n\t\t}\n\n\t\tconst firstWhitespaceIndex = argsString.search(/\\s/);\n\t\tif (firstWhitespaceIndex < 0) {\n\t\t\treturn argsString;\n\t\t}\n\t\treturn argsString.slice(0, firstWhitespaceIndex);\n\t}\n\n\tasync handleImport(text: string): Promise<void> {\n\t\tconst inputPath = this.getPathArgument(text, \"/import\");\n\t\tif (!inputPath) {\n\t\t\tthis.ctx.showError(\"Usage: /import <path.jsonl>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst confirmed = await this.ctx.showExtensionConfirm(\n\t\t\t\"Import session\",\n\t\t\t`Replace current session with ${inputPath}?`,\n\t\t);\n\t\tif (!confirmed) {\n\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tthis.ctx.stopLoadingAnimation();\n\t\t\tthis.ctx.statusContainer.clear();\n\t\t\tconst result = await this.ctx.runtimeHost.importFromJsonl(inputPath);\n\t\t\tif (result.cancelled) {\n\t\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.showStatus(`Session imported from: ${inputPath}`);\n\t\t} catch (error: unknown) {\n\t\t\tif (error instanceof MissingSessionCwdError) {\n\t\t\t\tconst selectedCwd = await this.ctx.promptForMissingSessionCwd(error);\n\t\t\t\tif (!selectedCwd) {\n\t\t\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = await this.ctx.runtimeHost.importFromJsonl(inputPath, selectedCwd);\n\t\t\t\tif (result.cancelled) {\n\t\t\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\t\tthis.ctx.showStatus(`Session imported from: ${inputPath}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (error instanceof SessionImportFileNotFoundError) {\n\t\t\t\tthis.ctx.showError(`Failed to import session: ${error.message}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.ctx.handleFatalRuntimeError(\"Failed to import session\", error);\n\t\t}\n\t}\n\n\tasync handleShare(): Promise<void> {\n\t\t// Check if gh is available and logged in\n\t\ttry {\n\t\t\tconst authResult = spawnSync(\"gh\", [\"auth\", \"status\"], { encoding: \"utf-8\" });\n\t\t\tif (authResult.status !== 0) {\n\t\t\t\tthis.ctx.showError(\"GitHub CLI is not logged in. Run 'gh auth login' first.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {\n\t\t\tthis.ctx.showError(\"GitHub CLI (gh) is not installed. Install it from https://cli.github.com/\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Export to a temp file\n\t\tconst tmpFile = path.join(os.tmpdir(), \"session.html\");\n\t\ttry {\n\t\t\tawait this.ctx.session.exportToHtml(tmpFile);\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\n\t\t// Show cancellable loader, replacing the editor\n\t\tconst loader = new BorderedLoader(this.ctx.ui, theme, \"Creating gist...\");\n\t\tthis.ctx.editorContainer.clear();\n\t\tthis.ctx.editorContainer.addChild(loader);\n\t\tthis.ctx.ui.setFocus(loader);\n\t\tthis.ctx.ui.requestRender();\n\n\t\tconst restoreEditor = () => {\n\t\t\tloader.dispose();\n\t\t\tthis.ctx.editorContainer.clear();\n\t\t\tthis.ctx.editorContainer.addChild(this.ctx.editor);\n\t\t\tthis.ctx.ui.setFocus(this.ctx.editor);\n\t\t\ttry {\n\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t} catch {\n\t\t\t\t// Ignore cleanup errors\n\t\t\t}\n\t\t};\n\n\t\t// Create a secret gist asynchronously\n\t\tlet proc: ReturnType<typeof spawn> | null = null;\n\n\t\tloader.onAbort = () => {\n\t\t\tproc?.kill();\n\t\t\trestoreEditor();\n\t\t\tthis.ctx.showStatus(\"Share cancelled\");\n\t\t};\n\n\t\ttry {\n\t\t\tconst result = await new Promise<{ stdout: string; stderr: string; code: number | null }>((resolve) => {\n\t\t\t\tproc = spawn(\"gh\", [\"gist\", \"create\", \"--public=false\", tmpFile]);\n\t\t\t\tlet stdout = \"\";\n\t\t\t\tlet stderr = \"\";\n\t\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\t\tstdout += data.toString();\n\t\t\t\t});\n\t\t\t\tproc.stderr?.on(\"data\", (data) => {\n\t\t\t\t\tstderr += data.toString();\n\t\t\t\t});\n\t\t\t\tproc.on(\"close\", (code) => resolve({ stdout, stderr, code }));\n\t\t\t});\n\n\t\t\tif (loader.signal.aborted) return;\n\n\t\t\trestoreEditor();\n\n\t\t\tif (result.code !== 0) {\n\t\t\t\tconst errorMsg = result.stderr?.trim() || \"Unknown error\";\n\t\t\t\tthis.ctx.showError(`Failed to create gist: ${errorMsg}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Extract gist ID from the URL returned by gh\n\t\t\t// gh returns something like: https://gist.github.com/username/GIST_ID\n\t\t\tconst gistUrl = result.stdout?.trim();\n\t\t\tconst gistId = gistUrl?.split(\"/\").pop();\n\t\t\tif (!gistId) {\n\t\t\t\tthis.ctx.showError(\"Failed to parse gist ID from gh output\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Create the preview URL\n\t\t\tconst previewUrl = getShareViewerUrl(gistId);\n\t\t\tthis.ctx.showStatus(`Share URL: ${previewUrl}\\nGist: ${gistUrl}`);\n\t\t} catch (error: unknown) {\n\t\t\tif (!loader.signal.aborted) {\n\t\t\t\trestoreEditor();\n\t\t\t\tthis.ctx.showError(`Failed to create gist: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync handleCopy(): Promise<void> {\n\t\tconst text = this.ctx.session.getLastAssistantText();\n\t\tif (!text) {\n\t\t\tthis.ctx.showError(\"No agent messages to copy yet.\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait copyToClipboard(text);\n\t\t\tthis.ctx.showStatus(\"Copied last agent message to clipboard\");\n\t\t} catch (error) {\n\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\t/** The session's chip as it currently renders, for echoing back after a change. */\n\tprivate currentChip(): string {\n\t\tconst chip = renderSessionChip(\n\t\t\tthis.ctx.sessionManager.getDisplayName(),\n\t\t\tthis.ctx.sessionManager.getSessionColorSlot(),\n\t\t);\n\t\treturn chip?.styled ?? this.ctx.sessionManager.getDisplayName();\n\t}\n\n\thandleName(text: string): void {\n\t\tconst name = text.replace(/^\\/name\\s*/, \"\").trim();\n\t\tif (!name) {\n\t\t\t// Every session has a name now — an auto-assigned slug until someone\n\t\t\t// picks one — so there is always something to report, and the reply\n\t\t\t// shows the chip rather than describing it.\n\t\t\tconst chosen = this.ctx.sessionManager.getSessionName();\n\t\t\tconst label = chosen ? \"Session name:\" : \"Session name (auto):\";\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\t`${theme.fg(\"dim\", label)} ${this.currentChip()} ${theme.fg(\"dim\", \"/name <name> to change\")}`,\n\t\t\t\t\t1,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.ctx.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.session.setSessionName(name);\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Text(`${theme.fg(\"dim\", \"Session name set:\")} ${this.currentChip()}`, 1, 0));\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\t/**\n\t * `/color <slot>` sets the session's chip colour directly, where a slot is a\n\t * number, a name (`green`), or a name's initial (`g`). Bare `/color` is\n\t * handled by the caller, which opens the swatch picker instead — the names\n\t * describe a hue family rather than the exact colour a theme fills the slot\n\t * with, so which one reads best here is still a thing you look at.\n\t *\n\t * The confirmation names the slot it landed on, because the aliases fold\n\t * neighbouring hues together: `/color red` answering with \"magenta\" is how\n\t * you learn the palette has no red of its own.\n\t */\n\thandleColor(text: string): boolean {\n\t\tconst arg = text.replace(/^\\/color\\s*/, \"\").trim();\n\t\tif (!arg) return false;\n\t\tconst slot = parseSessionColorSlot(arg);\n\t\tif (slot === undefined) {\n\t\t\tthis.ctx.showWarning(\n\t\t\t\t`Usage: /color <1-${SESSION_COLOR_SLOTS}> or /color <${SESSION_COLOR_NAME_LIST.join(\"|\")}> ` +\n\t\t\t\t\t\"(first letter works too), or /color on its own to pick one\",\n\t\t\t);\n\t\t\treturn true;\n\t\t}\n\t\tthis.ctx.session.setSessionColor(slot);\n\t\tconst name = sessionColorName(slot);\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(\n\t\t\tnew Text(\n\t\t\t\t`${theme.fg(\"dim\", \"Session color set:\")} ${this.currentChip()}${name ? ` ${theme.fg(\"dim\", name)}` : \"\"}`,\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.ctx.ui.requestRender();\n\t\treturn true;\n\t}\n\n\thandleSession(): void {\n\t\tconst stats = this.ctx.session.getSessionStats();\n\t\tconst sessionName = this.ctx.sessionManager.getSessionName();\n\n\t\tlet info = `${theme.bold(\"Session Info\")}\\n\\n`;\n\t\tinfo += `${theme.fg(\"dim\", sessionName ? \"Name:\" : \"Name (auto):\")} ${this.currentChip()}\\n`;\n\t\tconst branch = this.ctx.sessionManager.getSessionBranch();\n\t\tif (branch) {\n\t\t\tinfo += `${theme.fg(\"dim\", \"Branch:\")} ${branch}\\n`;\n\t\t}\n\t\tinfo += `${theme.fg(\"dim\", \"File:\")} ${stats.sessionFile ?? \"In-memory\"}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"ID:\")} ${stats.sessionId}\\n\\n`;\n\t\tinfo += `${theme.bold(\"Messages\")}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"User:\")} ${stats.userMessages}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Assistant:\")} ${stats.assistantMessages}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Tool Calls:\")} ${stats.toolCalls}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Tool Results:\")} ${stats.toolResults}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.totalMessages}\\n\\n`;\n\t\tinfo += `${theme.bold(\"Tokens\")}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Input:\")} ${stats.tokens.input.toLocaleString()}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Output:\")} ${stats.tokens.output.toLocaleString()}\\n`;\n\t\tif (stats.tokens.cacheRead > 0) {\n\t\t\tinfo += `${theme.fg(\"dim\", \"Cache Read:\")} ${stats.tokens.cacheRead.toLocaleString()}\\n`;\n\t\t}\n\t\tif (stats.tokens.cacheWrite > 0) {\n\t\t\tinfo += `${theme.fg(\"dim\", \"Cache Write:\")} ${stats.tokens.cacheWrite.toLocaleString()}\\n`;\n\t\t}\n\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.tokens.total.toLocaleString()}\\n`;\n\n\t\tif (stats.cost > 0) {\n\t\t\tinfo += `\\n${theme.bold(\"Cost\")}\\n`;\n\t\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.cost.toFixed(4)}`;\n\t\t}\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Text(info, 1, 0));\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\thandleChangelog(): void {\n\t\tconst changelogPath = getChangelogPath();\n\t\tconst allEntries = parseChangelog(changelogPath);\n\n\t\tif (allEntries.length === 0) {\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(new Text(theme.fg(\"dim\", \"No changelog entries found.\"), 1, 0));\n\t\t\tthis.ctx.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tconst changelogMarkdown = allEntries\n\t\t\t.slice()\n\t\t\t.reverse()\n\t\t\t.map((e) => e.content)\n\t\t\t.join(\"\\n\\n\");\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.chatContainer.addChild(new Text(theme.bold(theme.fg(\"accent\", \"What's New\")), 1, 0));\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 0, this.ctx.getMarkdownThemeWithSettings()));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\thandleHotkeys(): void {\n\t\t// Navigation keybindings\n\t\tconst cursorUp = keyDisplayText(\"tui.editor.cursorUp\");\n\t\tconst cursorDown = keyDisplayText(\"tui.editor.cursorDown\");\n\t\tconst cursorLeft = keyDisplayText(\"tui.editor.cursorLeft\");\n\t\tconst cursorRight = keyDisplayText(\"tui.editor.cursorRight\");\n\t\tconst cursorWordLeft = keyDisplayText(\"tui.editor.cursorWordLeft\");\n\t\tconst cursorWordRight = keyDisplayText(\"tui.editor.cursorWordRight\");\n\t\tconst cursorLineStart = keyDisplayText(\"tui.editor.cursorLineStart\");\n\t\tconst cursorLineEnd = keyDisplayText(\"tui.editor.cursorLineEnd\");\n\t\tconst jumpForward = keyDisplayText(\"tui.editor.jumpForward\");\n\t\tconst jumpBackward = keyDisplayText(\"tui.editor.jumpBackward\");\n\t\tconst pageUp = keyDisplayText(\"tui.editor.pageUp\");\n\t\tconst pageDown = keyDisplayText(\"tui.editor.pageDown\");\n\n\t\t// Editing keybindings\n\t\tconst submit = keyDisplayText(\"tui.input.submit\");\n\t\tconst newLine = keyDisplayText(\"tui.input.newLine\");\n\t\tconst deleteWordBackward = keyDisplayText(\"tui.editor.deleteWordBackward\");\n\t\tconst deleteWordForward = keyDisplayText(\"tui.editor.deleteWordForward\");\n\t\tconst deleteToLineStart = keyDisplayText(\"tui.editor.deleteToLineStart\");\n\t\tconst deleteToLineEnd = keyDisplayText(\"tui.editor.deleteToLineEnd\");\n\t\tconst yank = keyDisplayText(\"tui.editor.yank\");\n\t\tconst yankPop = keyDisplayText(\"tui.editor.yankPop\");\n\t\tconst undo = keyDisplayText(\"tui.editor.undo\");\n\t\tconst tab = keyDisplayText(\"tui.input.tab\");\n\n\t\t// App keybindings\n\t\tconst interrupt = keyDisplayText(\"app.interrupt\");\n\t\tconst clear = keyDisplayText(\"app.clear\");\n\t\tconst exit = keyDisplayText(\"app.exit\");\n\t\tconst suspend = keyDisplayText(\"app.suspend\");\n\t\tconst cycleThinkingLevel = keyDisplayText(\"app.thinking.cycle\");\n\t\tconst cycleModelForward = keyDisplayText(\"app.model.cycleForward\");\n\t\tconst selectModel = keyDisplayText(\"app.model.select\");\n\t\tconst expandTools = keyDisplayText(\"app.tools.expand\");\n\t\tconst toggleThinking = keyDisplayText(\"app.thinking.toggle\");\n\t\tconst cycleTaskView = keyDisplayText(\"app.tasks.cycleView\");\n\t\tconst externalEditor = keyDisplayText(\"app.editor.external\");\n\t\tconst cycleModelBackward = keyDisplayText(\"app.model.cycleBackward\");\n\t\tconst followUp = keyDisplayText(\"app.message.followUp\");\n\t\tconst dequeue = keyDisplayText(\"app.message.dequeue\");\n\t\tconst pasteImage = keyDisplayText(\"app.clipboard.pasteImage\");\n\t\tconst viewForward = keyDisplayText(\"app.view.cycleForward\");\n\t\tconst unfoldOne = keyDisplayText(\"app.tools.unfoldOne\");\n\t\tconst foldOne = keyDisplayText(\"app.tools.foldOne\");\n\t\tconst viewBackward = keyDisplayText(\"app.view.cycleBackward\");\n\t\tconst voice = keyDisplayText(\"app.input.voiceTranscribe\");\n\t\tconst changeDirectory = keyDisplayText(\"app.session.changeDirectory\");\n\t\tconst openSettings = keyDisplayText(\"app.settings.open\");\n\t\tconst openHotkeys = keyDisplayText(\"app.hotkeys.open\");\n\t\tconst cycleMode = keyDisplayText(\"app.mode.cycle\");\n\t\tconst sessionTree = keyDisplayText(\"app.session.tree\");\n\t\tconst sessionResume = keyDisplayText(\"app.session.resume\");\n\n\t\tlet hotkeys = `\n**Navigation**\n| Key | Action |\n|-----|--------|\n| \\`${cursorUp}\\` / \\`${cursorDown}\\` / \\`${cursorLeft}\\` / \\`${cursorRight}\\` | Move cursor / browse history (Up when empty) |\n| \\`${cursorWordLeft}\\` / \\`${cursorWordRight}\\` | Move by word |\n| \\`${cursorLineStart}\\` | Start of line |\n| \\`${cursorLineEnd}\\` | End of line |\n| \\`${jumpForward}\\` | Jump forward to character |\n| \\`${jumpBackward}\\` | Jump backward to character |\n| \\`${pageUp}\\` / \\`${pageDown}\\` | Scroll by page |\n\n**Editing**\n| Key | Action |\n|-----|--------|\n| \\`${submit}\\` | Send message |\n| \\`${newLine}\\` | New line${process.platform === \"win32\" ? \" (Ctrl+Enter on Windows Terminal)\" : \"\"} |\n| \\`${deleteWordBackward}\\` | Delete word backwards |\n| \\`${deleteWordForward}\\` | Delete word forwards |\n| \\`${deleteToLineStart}\\` | Delete to start of line |\n| \\`${deleteToLineEnd}\\` | Delete to end of line |\n| \\`${yank}\\` | Paste the most-recently-deleted text |\n| \\`${yankPop}\\` | Cycle through the deleted text after pasting |\n| \\`${undo}\\` | Undo |\n\n**Flow** — the keys you hit without thinking\n| Key | Action |\n|-----|--------|\n| \\`${tab}\\` | Path completion / accept autocomplete |\n| \\`${interrupt}\\` | Cancel autocomplete / abort streaming |\n| \\`${clear}\\` | Clear editor (first) / exit (second) |\n| \\`${exit}\\` | Exit (when editor is empty) |\n| \\`${suspend}\\` | Suspend to background |\n| \\`${followUp}\\` | Queue follow-up message |\n| \\`${dequeue}\\` | Restore queued messages |\n| \\`${pasteImage}\\` | Paste image from clipboard |\n| \\`/\\` | Slash commands |\n| \\`!\\` | Run bash command |\n| \\`!!\\` | Run bash command (excluded from context) |\n\n**View** — what is on screen right now (\\`Ctrl\\`)\n| Key | Action |\n|-----|--------|\n| \\`${expandTools}\\` | Expand or collapse every tool block at once |\n| \\`${unfoldOne}\\` / \\`${foldOne}\\` | Open / re-fold one thing, newest first — a chain in radar, a tool body otherwise |\n| \\`${viewForward}\\` / \\`${viewBackward}\\` | Cycle tool output: radar → glance → full |\n| \\`${toggleThinking}\\` | Toggle thinking block visibility |\n| \\`${cycleTaskView}\\` | Cycle task panel view (tasks → subagents → teams) |\n| \\`${cycleModelForward}\\` / \\`${cycleModelBackward}\\` | Cycle models |\n| \\`${cycleThinkingLevel}\\` | Cycle thinking level |\n\n**Cockpit** — what the agent is, and where it works (\\`Alt\\`)\n| Key | Action |\n|-----|--------|\n| \\`${cycleMode}\\` | Cycle agent mode (ask → plan → build → debug) |\n| \\`${selectModel}\\` | Open model selector |\n| \\`${changeDirectory}\\` | Change working directory (\\`/cd\\`) |\n| \\`${sessionTree}\\` | Open session tree |\n| \\`${sessionResume}\\` | Resume a session from history |\n| \\`${openSettings}\\` | Open settings |\n| \\`${openHotkeys}\\` | Show this list |\n| \\`${externalEditor}\\` | Edit message in external editor |\n| \\`${voice}\\` | Record voice and transcribe |\n\nInside a picker, every \\`Ctrl\\` key still edits the query — the picker's own\nverbs are on \\`Alt\\`, and its hint line names them.\n`;\n\n\t\t// Add extension-registered shortcuts\n\t\tconst extensionRunner = this.ctx.session.extensionRunner;\n\t\tconst shortcuts = extensionRunner.getShortcuts(this.ctx.keybindings.getEffectiveConfig());\n\t\tif (shortcuts.size > 0) {\n\t\t\thotkeys += `\n**Extensions**\n| Key | Action |\n|-----|--------|\n`;\n\t\t\tfor (const [key, shortcut] of shortcuts) {\n\t\t\t\tconst description = shortcut.description ?? shortcut.extensionPath;\n\t\t\t\tconst keyDisplay = formatKeyText(key, { capitalize: true });\n\t\t\t\thotkeys += `| \\`${keyDisplay}\\` | ${description} |\\n`;\n\t\t\t}\n\t\t}\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.chatContainer.addChild(new Text(theme.bold(theme.fg(\"accent\", \"Keyboard Shortcuts\")), 1, 0));\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Markdown(hotkeys.trim(), 1, 0, this.ctx.getMarkdownThemeWithSettings()));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\tasync handleClear(): Promise<void> {\n\t\tthis.ctx.stopLoadingAnimation();\n\t\tthis.ctx.statusContainer.clear();\n\t\ttry {\n\t\t\tconst result = await this.ctx.runtimeHost.newSession();\n\t\t\tif (result.cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(new Text(`${theme.fg(\"accent\", \"✓ New session started\")}`, 1, 0));\n\t\t\tthis.ctx.ui.requestRender();\n\t\t} catch (error: unknown) {\n\t\t\tawait this.ctx.handleFatalRuntimeError(\"Failed to create session\", error);\n\t\t}\n\t}\n\n\t/**\n\t * `/cd [path]` — move the whole session to another directory.\n\t *\n\t * Written for the case it exists to serve: you are done in one repo and want\n\t * to work in the next one without losing the process, its provider auth, or\n\t * its warmed model list. Bare `/cd` goes home, `/cd -` goes back to where you\n\t * came from, `~` and relative paths resolve as a shell would.\n\t *\n\t * The move starts a fresh session rooted in the target — see\n\t * `AgentSessionRuntime.changeDirectory` for why the whole runtime is rebuilt\n\t * rather than a cwd string reassigned.\n\t */\n\tasync handleChangeDirectory(text: string): Promise<void> {\n\t\tconst prefix = \"/cd\";\n\t\tconst rawArg = text.startsWith(prefix) ? text.slice(prefix.length).trim() : text.trim();\n\t\tconst previousCwd = this.ctx.sessionManager.getCwd();\n\n\t\tlet target: string;\n\t\tif (!rawArg || rawArg === \"~\") {\n\t\t\ttarget = os.homedir();\n\t\t} else if (rawArg === \"-\") {\n\t\t\tif (!this.previousCwd) {\n\t\t\t\tthis.ctx.showWarning(\"No previous directory to return to\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget = this.previousCwd;\n\t\t} else {\n\t\t\tconst expanded = rawArg.startsWith(\"~/\") ? path.join(os.homedir(), rawArg.slice(2)) : rawArg;\n\t\t\ttarget = path.resolve(previousCwd, expanded);\n\t\t}\n\n\t\tif (path.resolve(target) === path.resolve(previousCwd)) {\n\t\t\tthis.ctx.showStatus(`Already in ${target}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.stopLoadingAnimation();\n\t\tthis.ctx.statusContainer.clear();\n\t\ttry {\n\t\t\tconst result = await this.ctx.runtimeHost.changeDirectory(target);\n\t\t\tif (result.cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.previousCwd = previousCwd;\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\t`${theme.fg(\"accent\", \"✓ Working directory\")} ${theme.fg(\"muted\", result.cwd)}\\n` +\n\t\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t\t`New session started here. ${keyDisplayText(\"app.session.resume\")} reopens the session you left in ${previousCwd}.`,\n\t\t\t\t\t\t),\n\t\t\t\t\t1,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.ctx.ui.requestRender();\n\t\t} catch (error: unknown) {\n\t\t\tif (error instanceof ChangeDirectoryError) {\n\t\t\t\tthis.ctx.showError(error.message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.ctx.handleFatalRuntimeError(`Failed to change directory to ${target}`, error);\n\t\t}\n\t}\n\n\t/** Directory completions for `/cd <prefix>`, plus the two shell shorthands. */\n\tgetChangeDirectoryCompletions(argumentPrefix: string): Array<{ value: string; label: string }> {\n\t\tconst cwd = this.ctx.sessionManager.getCwd();\n\t\tconst expanded = argumentPrefix.startsWith(\"~/\")\n\t\t\t? path.join(os.homedir(), argumentPrefix.slice(2))\n\t\t\t: argumentPrefix;\n\t\t// A prefix ending in a separator names the directory to list; otherwise the\n\t\t// last segment is a partial name to filter its parent by.\n\t\tconst endsWithSep = expanded.endsWith(\"/\") || expanded.endsWith(path.sep);\n\t\tconst base = endsWithSep ? expanded : path.dirname(expanded);\n\t\tconst partial = endsWithSep ? \"\" : path.basename(expanded);\n\t\tconst searchDir = path.isAbsolute(base) ? base : path.resolve(cwd, base || \".\");\n\n\t\tconst completions: Array<{ value: string; label: string }> = [];\n\t\tif (!argumentPrefix) {\n\t\t\tif (this.previousCwd) completions.push({ value: \"-\", label: `- (${this.previousCwd})` });\n\t\t\tcompletions.push({ value: \"~\", label: `~ (${os.homedir()})` });\n\t\t}\n\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = fs.readdirSync(searchDir, { withFileTypes: true });\n\t\t} catch {\n\t\t\treturn completions;\n\t\t}\n\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory()) continue;\n\t\t\tif (partial && !entry.name.startsWith(partial)) continue;\n\t\t\tif (!partial && entry.name.startsWith(\".\")) continue;\n\t\t\tconst joined =\n\t\t\t\tbase && !endsWithSep\n\t\t\t\t\t? path.join(path.dirname(argumentPrefix), entry.name)\n\t\t\t\t\t: `${argumentPrefix}${entry.name}`;\n\t\t\tcompletions.push({ value: `${joined}/`, label: `${entry.name}/` });\n\t\t}\n\t\treturn completions.slice(0, 50);\n\t}\n\n\thandleDebug(): void {\n\t\tconst width = this.ctx.ui.terminal.columns;\n\t\tconst height = this.ctx.ui.terminal.rows;\n\t\tconst allLines = this.ctx.ui.render(width);\n\n\t\tconst debugLogPath = getDebugLogPath();\n\t\tconst debugData = [\n\t\t\t`Debug output at ${new Date().toISOString()}`,\n\t\t\t`Terminal: ${width}x${height}`,\n\t\t\t`Total lines: ${allLines.length}`,\n\t\t\t\"\",\n\t\t\t\"=== All rendered lines with visible widths ===\",\n\t\t\t...allLines.map((line, idx) => {\n\t\t\t\tconst vw = visibleWidth(line);\n\t\t\t\tconst escaped = JSON.stringify(line);\n\t\t\t\treturn `[${idx}] (w=${vw}) ${escaped}`;\n\t\t\t}),\n\t\t\t\"\",\n\t\t\t\"=== Agent messages (JSONL) ===\",\n\t\t\t...this.ctx.session.messages.map((msg) => JSON.stringify(msg)),\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\n\t\tfs.mkdirSync(path.dirname(debugLogPath), { recursive: true });\n\t\tfs.writeFileSync(debugLogPath, debugData);\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(\n\t\t\tnew Text(`${theme.fg(\"accent\", \"✓ Debug log written\")}\\n${theme.fg(\"muted\", debugLogPath)}`, 1, 0),\n\t\t);\n\t\tthis.ctx.ui.requestRender();\n\t}\n}\n"]}
1
+ {"version":3,"file":"command-executor.js","sourceRoot":"","sources":["../../../src/modes/interactive/command-executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extracted command handlers from InteractiveMode.\n * All methods receive dependencies via CommandContext rather than\n * reaching back into the parent class.\n */\n\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { Model } from \"@kolisachint/hoocode-ai\";\nimport type { EditorComponent, MarkdownTheme, TUI } from \"@kolisachint/hoocode-tui\";\nimport { type Container, Markdown, Spacer, Text, visibleWidth } from \"@kolisachint/hoocode-tui\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { getDebugLogPath, getShareViewerUrl } from \"../../config.js\";\nimport { loadAgentRegistry } from \"../../core/agent-registry.js\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.js\";\nimport { ChangeDirectoryError, SessionImportFileNotFoundError } from \"../../core/agent-session-runtime.js\";\nimport type { KeybindingsManager } from \"../../core/keybindings.js\";\nimport { MissingSessionCwdError } from \"../../core/session-cwd.js\";\nimport {\n\tparseSessionColorSlot,\n\tSESSION_COLOR_NAME_LIST,\n\tSESSION_COLOR_SLOTS,\n\tsessionColorName,\n} from \"../../core/session-identity.js\";\nimport type { SessionManager } from \"../../core/session-manager.js\";\nimport { getSubagentPool } from \"../../core/subagent-pool-instance.js\";\nimport type { SubagentResultFile } from \"../../core/subagent-result.js\";\nimport { getChangelogPath, parseChangelog } from \"../../utils/changelog.js\";\nimport { copyToClipboard } from \"../../utils/clipboard.js\";\nimport { BorderedLoader } from \"./components/bordered-loader.js\";\nimport { DynamicBorder } from \"./components/dynamic-border.js\";\nimport type { FooterComponent } from \"./components/footer.js\";\nimport { formatKeyText, keyDisplayText } from \"./components/keybinding-hints.js\";\nimport { renderSessionChip } from \"./components/session-chip.js\";\nimport { theme } from \"./theme/theme.js\";\n\nexport interface CommandContext {\n\t// Core dependencies\n\tsession: AgentSession;\n\tsessionManager: SessionManager;\n\truntimeHost: AgentSessionRuntime;\n\tui: TUI;\n\teditor: EditorComponent;\n\teditorContainer: Container;\n\tchatContainer: Container;\n\tstatusContainer: Container;\n\tfooter: FooterComponent;\n\tkeybindings: KeybindingsManager;\n\n\t// UI callbacks\n\tshowStatus: (message: string) => void;\n\tshowError: (message: string) => void;\n\tshowWarning: (message: string) => void;\n\tupdateEditorBorderColor: () => void;\n\trenderCurrentSessionState: () => void;\n\trebuildChatFromMessages: () => void;\n\tgetMarkdownThemeWithSettings: () => MarkdownTheme;\n\tstopLoadingAnimation: () => void;\n\n\t// Auth/model helpers\n\tfindExactModelMatch: (searchTerm: string) => Promise<Model<any> | undefined>;\n\tmaybeWarnAboutAnthropicSubscriptionAuth: (model?: Model<any>) => Promise<void>;\n\n\t// Dialog callbacks\n\tshowModelSelector: (searchTerm?: string) => void;\n\tshowExtensionConfirm: (title: string, message: string) => Promise<boolean>;\n\tpromptForMissingSessionCwd: (error: MissingSessionCwdError) => Promise<string | undefined>;\n\n\t// Fatal error handler\n\thandleFatalRuntimeError: (prefix: string, error: unknown) => Promise<never>;\n}\n\nexport class CommandExecutor {\n\t/** Where `/cd -` returns to. Set on every successful move, session-local. */\n\tprivate previousCwd?: string;\n\n\tconstructor(private readonly ctx: CommandContext) {}\n\n\t// =========================================================================\n\t// Slash command handlers\n\t// =========================================================================\n\n\tasync handleModel(searchTerm?: string): Promise<void> {\n\t\tif (!searchTerm) {\n\t\t\tthis.ctx.showModelSelector();\n\t\t\treturn;\n\t\t}\n\n\t\tconst model = await this.ctx.findExactModelMatch(searchTerm);\n\t\tif (model) {\n\t\t\ttry {\n\t\t\t\tawait this.ctx.session.setModel(model);\n\t\t\t\tthis.ctx.footer.invalidate();\n\t\t\t\tthis.ctx.updateEditorBorderColor();\n\t\t\t\tthis.ctx.showStatus(`Model: ${model.id}`);\n\t\t\t\tvoid this.ctx.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\t} catch (error) {\n\t\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.showModelSelector(searchTerm);\n\t}\n\n\tasync handleClone(): Promise<void> {\n\t\tconst leafId = this.ctx.sessionManager.getLeafId();\n\t\tif (!leafId) {\n\t\t\tthis.ctx.showStatus(\"Nothing to clone yet\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.ctx.runtimeHost.fork(leafId, { position: \"at\" });\n\t\t\tif (result.cancelled) {\n\t\t\t\tthis.ctx.ui.requestRender();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.editor.setText(\"\");\n\t\t\tthis.ctx.showStatus(\"Cloned to new session\");\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\tasync handleSubagent(text: string): Promise<void> {\n\t\tconst prefix = \"/subagent \";\n\t\tconst args = text.startsWith(prefix) ? text.slice(prefix.length).trim() : \"\";\n\t\tif (!args) {\n\t\t\tthis.ctx.showStatus(\"Usage: /subagent <mode> <task>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst firstSpace = args.indexOf(\" \");\n\t\tif (firstSpace === -1) {\n\t\t\tthis.ctx.showStatus(\"Usage: /subagent <mode> <task>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst mode = args.slice(0, firstSpace).trim();\n\t\tconst task = args.slice(firstSpace + 1).trim();\n\t\tif (!task) {\n\t\t\tthis.ctx.showStatus(\"Usage: /subagent <mode> <task>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst validModes = loadAgentRegistry({ cwd: this.ctx.sessionManager.getCwd() })\n\t\t\t.list()\n\t\t\t.map((a) => a.name);\n\t\tif (!validModes.includes(mode)) {\n\t\t\tthis.ctx.showStatus(`Unknown subagent_type: ${mode}. Available: ${validModes.join(\", \")}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.showStatus(`Spawning ${mode} subagent...`);\n\t\ttry {\n\t\t\tconst pool = getSubagentPool(this.ctx.sessionManager.getCwd(), this.ctx.session.modelRegistry.getAvailable());\n\t\t\tconst dispatchResult = await pool.dispatch(task, {\n\t\t\t\tforceAgent: mode,\n\t\t\t\tmodel: this.ctx.session.model?.id,\n\t\t\t\tprovider: this.ctx.session.model?.provider,\n\t\t\t});\n\t\t\tconst result = dispatchResult.result;\n\t\t\tconst resultData = result?.result_data as SubagentResultFile | undefined;\n\t\t\tif (result?.ok) {\n\t\t\t\tthis.ctx.showStatus(`${mode} subagent completed`);\n\t\t\t\t// Inject the subagent answer as a custom message so the user can see it in the chat\n\t\t\t\tthis.ctx.sessionManager.appendMessage({\n\t\t\t\t\trole: \"custom\",\n\t\t\t\t\tcustomType: \"subagent\",\n\t\t\t\t\tcontent: resultData?.summary || \"(no output)\",\n\t\t\t\t\tdisplay: true,\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.ctx.showError(`Subagent (${mode}) failed: ${result?.error ?? \"unknown error\"}`);\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\tasync handleExport(text: string): Promise<void> {\n\t\tconst outputPath = this.getPathArgument(text, \"/export\");\n\n\t\ttry {\n\t\t\tif (outputPath?.endsWith(\".jsonl\")) {\n\t\t\t\tconst filePath = this.ctx.session.exportToJsonl(outputPath);\n\t\t\t\tthis.ctx.showStatus(`Session exported to: ${filePath}`);\n\t\t\t} else {\n\t\t\t\tconst filePath = await this.ctx.session.exportToHtml(outputPath);\n\t\t\t\tthis.ctx.showStatus(`Session exported to: ${filePath}`);\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\t}\n\n\tprivate getPathArgument(text: string, command: \"/export\" | \"/import\"): string | undefined {\n\t\tif (text === command) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (!text.startsWith(`${command} `)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst argsString = text.slice(command.length + 1).trimStart();\n\t\tif (!argsString) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst firstChar = argsString[0];\n\t\tif (firstChar === '\"' || firstChar === \"'\") {\n\t\t\tconst closingQuoteIndex = argsString.indexOf(firstChar, 1);\n\t\t\tif (closingQuoteIndex < 0) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn argsString.slice(1, closingQuoteIndex);\n\t\t}\n\n\t\tconst firstWhitespaceIndex = argsString.search(/\\s/);\n\t\tif (firstWhitespaceIndex < 0) {\n\t\t\treturn argsString;\n\t\t}\n\t\treturn argsString.slice(0, firstWhitespaceIndex);\n\t}\n\n\tasync handleImport(text: string): Promise<void> {\n\t\tconst inputPath = this.getPathArgument(text, \"/import\");\n\t\tif (!inputPath) {\n\t\t\tthis.ctx.showError(\"Usage: /import <path.jsonl>\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst confirmed = await this.ctx.showExtensionConfirm(\n\t\t\t\"Import session\",\n\t\t\t`Replace current session with ${inputPath}?`,\n\t\t);\n\t\tif (!confirmed) {\n\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tthis.ctx.stopLoadingAnimation();\n\t\t\tthis.ctx.statusContainer.clear();\n\t\t\tconst result = await this.ctx.runtimeHost.importFromJsonl(inputPath);\n\t\t\tif (result.cancelled) {\n\t\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.showStatus(`Session imported from: ${inputPath}`);\n\t\t} catch (error: unknown) {\n\t\t\tif (error instanceof MissingSessionCwdError) {\n\t\t\t\tconst selectedCwd = await this.ctx.promptForMissingSessionCwd(error);\n\t\t\t\tif (!selectedCwd) {\n\t\t\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = await this.ctx.runtimeHost.importFromJsonl(inputPath, selectedCwd);\n\t\t\t\tif (result.cancelled) {\n\t\t\t\t\tthis.ctx.showStatus(\"Import cancelled\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\t\tthis.ctx.showStatus(`Session imported from: ${inputPath}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (error instanceof SessionImportFileNotFoundError) {\n\t\t\t\tthis.ctx.showError(`Failed to import session: ${error.message}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.ctx.handleFatalRuntimeError(\"Failed to import session\", error);\n\t\t}\n\t}\n\n\tasync handleShare(): Promise<void> {\n\t\t// Check if gh is available and logged in\n\t\ttry {\n\t\t\tconst authResult = spawnSync(\"gh\", [\"auth\", \"status\"], { encoding: \"utf-8\" });\n\t\t\tif (authResult.status !== 0) {\n\t\t\t\tthis.ctx.showError(\"GitHub CLI is not logged in. Run 'gh auth login' first.\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {\n\t\t\tthis.ctx.showError(\"GitHub CLI (gh) is not installed. Install it from https://cli.github.com/\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Export to a temp file\n\t\tconst tmpFile = path.join(os.tmpdir(), \"session.html\");\n\t\ttry {\n\t\t\tawait this.ctx.session.exportToHtml(tmpFile);\n\t\t} catch (error: unknown) {\n\t\t\tthis.ctx.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\treturn;\n\t\t}\n\n\t\t// Show cancellable loader, replacing the editor\n\t\tconst loader = new BorderedLoader(this.ctx.ui, theme, \"Creating gist...\");\n\t\tthis.ctx.editorContainer.clear();\n\t\tthis.ctx.editorContainer.addChild(loader);\n\t\tthis.ctx.ui.setFocus(loader);\n\t\tthis.ctx.ui.requestRender();\n\n\t\tconst restoreEditor = () => {\n\t\t\tloader.dispose();\n\t\t\tthis.ctx.editorContainer.clear();\n\t\t\tthis.ctx.editorContainer.addChild(this.ctx.editor);\n\t\t\tthis.ctx.ui.setFocus(this.ctx.editor);\n\t\t\ttry {\n\t\t\t\tfs.unlinkSync(tmpFile);\n\t\t\t} catch {\n\t\t\t\t// Ignore cleanup errors\n\t\t\t}\n\t\t};\n\n\t\t// Create a secret gist asynchronously\n\t\tlet proc: ReturnType<typeof spawn> | null = null;\n\n\t\tloader.onAbort = () => {\n\t\t\tproc?.kill();\n\t\t\trestoreEditor();\n\t\t\tthis.ctx.showStatus(\"Share cancelled\");\n\t\t};\n\n\t\ttry {\n\t\t\tconst result = await new Promise<{ stdout: string; stderr: string; code: number | null }>((resolve) => {\n\t\t\t\tproc = spawn(\"gh\", [\"gist\", \"create\", \"--public=false\", tmpFile]);\n\t\t\t\tlet stdout = \"\";\n\t\t\t\tlet stderr = \"\";\n\t\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\t\tstdout += data.toString();\n\t\t\t\t});\n\t\t\t\tproc.stderr?.on(\"data\", (data) => {\n\t\t\t\t\tstderr += data.toString();\n\t\t\t\t});\n\t\t\t\tproc.on(\"close\", (code) => resolve({ stdout, stderr, code }));\n\t\t\t});\n\n\t\t\tif (loader.signal.aborted) return;\n\n\t\t\trestoreEditor();\n\n\t\t\tif (result.code !== 0) {\n\t\t\t\tconst errorMsg = result.stderr?.trim() || \"Unknown error\";\n\t\t\t\tthis.ctx.showError(`Failed to create gist: ${errorMsg}`);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Extract gist ID from the URL returned by gh\n\t\t\t// gh returns something like: https://gist.github.com/username/GIST_ID\n\t\t\tconst gistUrl = result.stdout?.trim();\n\t\t\tconst gistId = gistUrl?.split(\"/\").pop();\n\t\t\tif (!gistId) {\n\t\t\t\tthis.ctx.showError(\"Failed to parse gist ID from gh output\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Create the preview URL\n\t\t\tconst previewUrl = getShareViewerUrl(gistId);\n\t\t\tthis.ctx.showStatus(`Share URL: ${previewUrl}\\nGist: ${gistUrl}`);\n\t\t} catch (error: unknown) {\n\t\t\tif (!loader.signal.aborted) {\n\t\t\t\trestoreEditor();\n\t\t\t\tthis.ctx.showError(`Failed to create gist: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync handleCopy(): Promise<void> {\n\t\tconst text = this.ctx.session.getLastAssistantText();\n\t\tif (!text) {\n\t\t\tthis.ctx.showError(\"No agent messages to copy yet.\");\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait copyToClipboard(text);\n\t\t\tthis.ctx.showStatus(\"Copied last agent message to clipboard\");\n\t\t} catch (error) {\n\t\t\tthis.ctx.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\t/** The session's chip as it currently renders, for echoing back after a change. */\n\tprivate currentChip(): string {\n\t\tconst chip = renderSessionChip(\n\t\t\tthis.ctx.sessionManager.getDisplayName(),\n\t\t\tthis.ctx.sessionManager.getSessionColorSlot(),\n\t\t);\n\t\treturn chip?.styled ?? this.ctx.sessionManager.getDisplayName();\n\t}\n\n\thandleName(text: string): void {\n\t\tconst name = text.replace(/^\\/name\\s*/, \"\").trim();\n\t\tif (!name) {\n\t\t\t// Every session has a name now — an auto-assigned slug until someone\n\t\t\t// picks one — so there is always something to report, and the reply\n\t\t\t// shows the chip rather than describing it.\n\t\t\tconst chosen = this.ctx.sessionManager.getSessionName();\n\t\t\tconst label = chosen ? \"Session name:\" : \"Session name (auto):\";\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\t`${theme.fg(\"dim\", label)} ${this.currentChip()} ${theme.fg(\"dim\", \"/name <name> to change\")}`,\n\t\t\t\t\t1,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.ctx.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.session.setSessionName(name);\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Text(`${theme.fg(\"dim\", \"Session name set:\")} ${this.currentChip()}`, 1, 0));\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\t/**\n\t * `/color <slot>` sets the session's chip colour directly, where a slot is a\n\t * number, a name (`green`), or a name's initial (`g`). Bare `/color` is\n\t * handled by the caller, which opens the swatch picker instead — the names\n\t * describe a hue family rather than the exact colour a theme fills the slot\n\t * with, so which one reads best here is still a thing you look at.\n\t *\n\t * The confirmation names the slot it landed on, because the aliases fold\n\t * neighbouring hues together: `/color red` answering with \"magenta\" is how\n\t * you learn the palette has no red of its own.\n\t */\n\thandleColor(text: string): boolean {\n\t\tconst arg = text.replace(/^\\/color\\s*/, \"\").trim();\n\t\tif (!arg) return false;\n\t\tconst slot = parseSessionColorSlot(arg);\n\t\tif (slot === undefined) {\n\t\t\tthis.ctx.showWarning(\n\t\t\t\t`Usage: /color <1-${SESSION_COLOR_SLOTS}> or /color <${SESSION_COLOR_NAME_LIST.join(\"|\")}> ` +\n\t\t\t\t\t\"(first letter works too), or /color on its own to pick one\",\n\t\t\t);\n\t\t\treturn true;\n\t\t}\n\t\tthis.ctx.session.setSessionColor(slot);\n\t\tconst name = sessionColorName(slot);\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(\n\t\t\tnew Text(\n\t\t\t\t`${theme.fg(\"dim\", \"Session color set:\")} ${this.currentChip()}${name ? ` ${theme.fg(\"dim\", name)}` : \"\"}`,\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tthis.ctx.ui.requestRender();\n\t\treturn true;\n\t}\n\n\thandleSession(): void {\n\t\tconst stats = this.ctx.session.getSessionStats();\n\t\tconst sessionName = this.ctx.sessionManager.getSessionName();\n\n\t\tlet info = `${theme.bold(\"Session Info\")}\\n\\n`;\n\t\tinfo += `${theme.fg(\"dim\", sessionName ? \"Name:\" : \"Name (auto):\")} ${this.currentChip()}\\n`;\n\t\tconst branch = this.ctx.sessionManager.getSessionBranch();\n\t\tif (branch) {\n\t\t\tinfo += `${theme.fg(\"dim\", \"Branch:\")} ${branch}\\n`;\n\t\t}\n\t\tinfo += `${theme.fg(\"dim\", \"File:\")} ${stats.sessionFile ?? \"In-memory\"}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"ID:\")} ${stats.sessionId}\\n\\n`;\n\t\tinfo += `${theme.bold(\"Messages\")}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"User:\")} ${stats.userMessages}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Assistant:\")} ${stats.assistantMessages}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Tool Calls:\")} ${stats.toolCalls}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Tool Results:\")} ${stats.toolResults}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.totalMessages}\\n\\n`;\n\t\tinfo += `${theme.bold(\"Tokens\")}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Input:\")} ${stats.tokens.input.toLocaleString()}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Output:\")} ${stats.tokens.output.toLocaleString()}\\n`;\n\t\tif (stats.tokens.cacheRead > 0) {\n\t\t\tinfo += `${theme.fg(\"dim\", \"Cache Read:\")} ${stats.tokens.cacheRead.toLocaleString()}\\n`;\n\t\t}\n\t\tif (stats.tokens.cacheWrite > 0) {\n\t\t\tinfo += `${theme.fg(\"dim\", \"Cache Write:\")} ${stats.tokens.cacheWrite.toLocaleString()}\\n`;\n\t\t}\n\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.tokens.total.toLocaleString()}\\n`;\n\n\t\tif (stats.cost > 0) {\n\t\t\tinfo += `\\n${theme.bold(\"Cost\")}\\n`;\n\t\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.cost.toFixed(4)}`;\n\t\t}\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Text(info, 1, 0));\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\thandleChangelog(): void {\n\t\tconst changelogPath = getChangelogPath();\n\t\tconst allEntries = parseChangelog(changelogPath);\n\n\t\tif (allEntries.length === 0) {\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(new Text(theme.fg(\"dim\", \"No changelog entries found.\"), 1, 0));\n\t\t\tthis.ctx.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\tconst changelogMarkdown = allEntries\n\t\t\t.slice()\n\t\t\t.reverse()\n\t\t\t.map((e) => e.content)\n\t\t\t.join(\"\\n\\n\");\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.chatContainer.addChild(new Text(theme.bold(theme.fg(\"accent\", \"What's New\")), 1, 0));\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 0, this.ctx.getMarkdownThemeWithSettings()));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\thandleHotkeys(): void {\n\t\t// Navigation keybindings\n\t\tconst cursorUp = keyDisplayText(\"tui.editor.cursorUp\");\n\t\tconst cursorDown = keyDisplayText(\"tui.editor.cursorDown\");\n\t\tconst cursorLeft = keyDisplayText(\"tui.editor.cursorLeft\");\n\t\tconst cursorRight = keyDisplayText(\"tui.editor.cursorRight\");\n\t\tconst cursorWordLeft = keyDisplayText(\"tui.editor.cursorWordLeft\");\n\t\tconst cursorWordRight = keyDisplayText(\"tui.editor.cursorWordRight\");\n\t\tconst cursorLineStart = keyDisplayText(\"tui.editor.cursorLineStart\");\n\t\tconst cursorLineEnd = keyDisplayText(\"tui.editor.cursorLineEnd\");\n\t\tconst jumpForward = keyDisplayText(\"tui.editor.jumpForward\");\n\t\tconst jumpBackward = keyDisplayText(\"tui.editor.jumpBackward\");\n\t\tconst pageUp = keyDisplayText(\"tui.editor.pageUp\");\n\t\tconst pageDown = keyDisplayText(\"tui.editor.pageDown\");\n\n\t\t// Editing keybindings\n\t\tconst submit = keyDisplayText(\"tui.input.submit\");\n\t\tconst newLine = keyDisplayText(\"tui.input.newLine\");\n\t\tconst deleteWordBackward = keyDisplayText(\"tui.editor.deleteWordBackward\");\n\t\tconst deleteWordForward = keyDisplayText(\"tui.editor.deleteWordForward\");\n\t\tconst deleteToLineStart = keyDisplayText(\"tui.editor.deleteToLineStart\");\n\t\tconst deleteToLineEnd = keyDisplayText(\"tui.editor.deleteToLineEnd\");\n\t\tconst yank = keyDisplayText(\"tui.editor.yank\");\n\t\tconst yankPop = keyDisplayText(\"tui.editor.yankPop\");\n\t\tconst undo = keyDisplayText(\"tui.editor.undo\");\n\t\tconst tab = keyDisplayText(\"tui.input.tab\");\n\n\t\t// App keybindings\n\t\tconst interrupt = keyDisplayText(\"app.interrupt\");\n\t\tconst clear = keyDisplayText(\"app.clear\");\n\t\tconst exit = keyDisplayText(\"app.exit\");\n\t\tconst suspend = keyDisplayText(\"app.suspend\");\n\t\tconst cycleThinkingLevel = keyDisplayText(\"app.thinking.cycle\");\n\t\tconst cycleModelForward = keyDisplayText(\"app.model.cycleForward\");\n\t\tconst selectModel = keyDisplayText(\"app.model.select\");\n\t\tconst expandTools = keyDisplayText(\"app.tools.expand\");\n\t\tconst toggleThinking = keyDisplayText(\"app.thinking.toggle\");\n\t\tconst cycleTaskView = keyDisplayText(\"app.tasks.cycleView\");\n\t\tconst externalEditor = keyDisplayText(\"app.editor.external\");\n\t\tconst cycleModelBackward = keyDisplayText(\"app.model.cycleBackward\");\n\t\tconst followUp = keyDisplayText(\"app.message.followUp\");\n\t\tconst dequeue = keyDisplayText(\"app.message.dequeue\");\n\t\tconst pasteImage = keyDisplayText(\"app.clipboard.pasteImage\");\n\t\tconst viewForward = keyDisplayText(\"app.view.cycleForward\");\n\t\tconst viewBackward = keyDisplayText(\"app.view.cycleBackward\");\n\t\tconst voice = keyDisplayText(\"app.input.voiceTranscribe\");\n\t\tconst changeDirectory = keyDisplayText(\"app.session.changeDirectory\");\n\t\tconst openSettings = keyDisplayText(\"app.settings.open\");\n\t\tconst openHotkeys = keyDisplayText(\"app.hotkeys.open\");\n\t\tconst cycleMode = keyDisplayText(\"app.mode.cycle\");\n\t\tconst sessionTree = keyDisplayText(\"app.session.tree\");\n\t\tconst sessionResume = keyDisplayText(\"app.session.resume\");\n\t\tconst cycleSessionColor = keyDisplayText(\"app.session.color.cycleForward\");\n\t\tconst cycleSessionColorBackward = keyDisplayText(\"app.session.color.cycleBackward\");\n\n\t\tlet hotkeys = `\n**Navigation**\n| Key | Action |\n|-----|--------|\n| \\`${cursorUp}\\` / \\`${cursorDown}\\` / \\`${cursorLeft}\\` / \\`${cursorRight}\\` | Move cursor / browse history (Up when empty) |\n| \\`${cursorWordLeft}\\` / \\`${cursorWordRight}\\` | Move by word |\n| \\`${cursorLineStart}\\` | Start of line |\n| \\`${cursorLineEnd}\\` | End of line |\n| \\`${jumpForward}\\` | Jump forward to character |\n| \\`${jumpBackward}\\` | Jump backward to character |\n| \\`${pageUp}\\` / \\`${pageDown}\\` | Scroll by page |\n\n**Editing**\n| Key | Action |\n|-----|--------|\n| \\`${submit}\\` | Send message |\n| \\`${newLine}\\` | New line${process.platform === \"win32\" ? \" (Ctrl+Enter on Windows Terminal)\" : \"\"} |\n| \\`${deleteWordBackward}\\` | Delete word backwards |\n| \\`${deleteWordForward}\\` | Delete word forwards |\n| \\`${deleteToLineStart}\\` | Delete to start of line |\n| \\`${deleteToLineEnd}\\` | Delete to end of line |\n| \\`${yank}\\` | Paste the most-recently-deleted text |\n| \\`${yankPop}\\` | Cycle through the deleted text after pasting |\n| \\`${undo}\\` | Undo |\n\n**Flow** — the keys you hit without thinking\n| Key | Action |\n|-----|--------|\n| \\`${tab}\\` | Path completion / accept autocomplete |\n| \\`${interrupt}\\` | Cancel autocomplete / abort streaming |\n| \\`${clear}\\` | Clear editor (first) / exit (second) |\n| \\`${exit}\\` | Exit (when editor is empty) |\n| \\`${suspend}\\` | Suspend to background |\n| \\`${followUp}\\` | Queue follow-up message |\n| \\`${dequeue}\\` | Restore queued messages |\n| \\`${pasteImage}\\` | Paste image from clipboard |\n| \\`/\\` | Slash commands |\n| \\`!\\` | Run bash command |\n| \\`!!\\` | Run bash command (excluded from context) |\n\n**View** — what is on screen right now (\\`Ctrl\\`)\n| Key | Action |\n|-----|--------|\n| \\`${expandTools}\\` | Jump to the full view and back |\n| \\`${viewForward}\\` / \\`${viewBackward}\\` | Cycle tool output: radar → peek → full |\n| \\`${toggleThinking}\\` | Toggle thinking block visibility |\n| \\`${cycleTaskView}\\` | Cycle task panel view (tasks → subagents → teams) |\n| \\`${cycleModelForward}\\` / \\`${cycleModelBackward}\\` | Cycle models |\n| \\`${cycleThinkingLevel}\\` | Cycle thinking level |\n\n**Cockpit** — what the agent is, and where it works (\\`Alt\\`)\n| Key | Action |\n|-----|--------|\n| \\`${cycleMode}\\` | Cycle agent mode (ask → plan → build → debug) |\n| \\`${selectModel}\\` | Open model selector |\n| \\`${changeDirectory}\\` | Change working directory (\\`/cd\\`) |\n| \\`${sessionTree}\\` | Open session tree |\n| \\`${sessionResume}\\` | Resume a session from history |\n| \\`${cycleSessionColor}\\` / \\`${cycleSessionColorBackward}\\` | Cycle the session chip's color (\\`/color\\` to pick one) |\n| \\`${openSettings}\\` | Open settings |\n| \\`${openHotkeys}\\` | Show this list |\n| \\`${externalEditor}\\` | Edit message in external editor |\n| \\`${voice}\\` | Record voice and transcribe |\n\nInside a picker, every \\`Ctrl\\` key still edits the query — the picker's own\nverbs are on \\`Alt\\`, and its hint line names them.\n`;\n\n\t\t// Add extension-registered shortcuts\n\t\tconst extensionRunner = this.ctx.session.extensionRunner;\n\t\tconst shortcuts = extensionRunner.getShortcuts(this.ctx.keybindings.getEffectiveConfig());\n\t\tif (shortcuts.size > 0) {\n\t\t\thotkeys += `\n**Extensions**\n| Key | Action |\n|-----|--------|\n`;\n\t\t\tfor (const [key, shortcut] of shortcuts) {\n\t\t\t\tconst description = shortcut.description ?? shortcut.extensionPath;\n\t\t\t\tconst keyDisplay = formatKeyText(key, { capitalize: true });\n\t\t\t\thotkeys += `| \\`${keyDisplay}\\` | ${description} |\\n`;\n\t\t\t}\n\t\t}\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.chatContainer.addChild(new Text(theme.bold(theme.fg(\"accent\", \"Keyboard Shortcuts\")), 1, 0));\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(new Markdown(hotkeys.trim(), 1, 0, this.ctx.getMarkdownThemeWithSettings()));\n\t\tthis.ctx.chatContainer.addChild(new DynamicBorder());\n\t\tthis.ctx.ui.requestRender();\n\t}\n\n\tasync handleClear(): Promise<void> {\n\t\tthis.ctx.stopLoadingAnimation();\n\t\tthis.ctx.statusContainer.clear();\n\t\ttry {\n\t\t\tconst result = await this.ctx.runtimeHost.newSession();\n\t\t\tif (result.cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(new Text(`${theme.fg(\"accent\", \"✓ New session started\")}`, 1, 0));\n\t\t\tthis.ctx.ui.requestRender();\n\t\t} catch (error: unknown) {\n\t\t\tawait this.ctx.handleFatalRuntimeError(\"Failed to create session\", error);\n\t\t}\n\t}\n\n\t/**\n\t * `/cd [path]` — move the whole session to another directory.\n\t *\n\t * Written for the case it exists to serve: you are done in one repo and want\n\t * to work in the next one without losing the process, its provider auth, or\n\t * its warmed model list. Bare `/cd` goes home, `/cd -` goes back to where you\n\t * came from, `~` and relative paths resolve as a shell would.\n\t *\n\t * The move starts a fresh session rooted in the target — see\n\t * `AgentSessionRuntime.changeDirectory` for why the whole runtime is rebuilt\n\t * rather than a cwd string reassigned.\n\t */\n\tasync handleChangeDirectory(text: string): Promise<void> {\n\t\tconst prefix = \"/cd\";\n\t\tconst rawArg = text.startsWith(prefix) ? text.slice(prefix.length).trim() : text.trim();\n\t\tconst previousCwd = this.ctx.sessionManager.getCwd();\n\n\t\tlet target: string;\n\t\tif (!rawArg || rawArg === \"~\") {\n\t\t\ttarget = os.homedir();\n\t\t} else if (rawArg === \"-\") {\n\t\t\tif (!this.previousCwd) {\n\t\t\t\tthis.ctx.showWarning(\"No previous directory to return to\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttarget = this.previousCwd;\n\t\t} else {\n\t\t\tconst expanded = rawArg.startsWith(\"~/\") ? path.join(os.homedir(), rawArg.slice(2)) : rawArg;\n\t\t\ttarget = path.resolve(previousCwd, expanded);\n\t\t}\n\n\t\tif (path.resolve(target) === path.resolve(previousCwd)) {\n\t\t\tthis.ctx.showStatus(`Already in ${target}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.ctx.stopLoadingAnimation();\n\t\tthis.ctx.statusContainer.clear();\n\t\ttry {\n\t\t\tconst result = await this.ctx.runtimeHost.changeDirectory(target);\n\t\t\tif (result.cancelled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.previousCwd = previousCwd;\n\t\t\tthis.ctx.renderCurrentSessionState();\n\t\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.ctx.chatContainer.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\t`${theme.fg(\"accent\", \"✓ Working directory\")} ${theme.fg(\"muted\", result.cwd)}\\n` +\n\t\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t\t`New session started here. ${keyDisplayText(\"app.session.resume\")} reopens the session you left in ${previousCwd}.`,\n\t\t\t\t\t\t),\n\t\t\t\t\t1,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t\tthis.ctx.ui.requestRender();\n\t\t} catch (error: unknown) {\n\t\t\tif (error instanceof ChangeDirectoryError) {\n\t\t\t\tthis.ctx.showError(error.message);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait this.ctx.handleFatalRuntimeError(`Failed to change directory to ${target}`, error);\n\t\t}\n\t}\n\n\t/** Directory completions for `/cd <prefix>`, plus the two shell shorthands. */\n\tgetChangeDirectoryCompletions(argumentPrefix: string): Array<{ value: string; label: string }> {\n\t\tconst cwd = this.ctx.sessionManager.getCwd();\n\t\tconst expanded = argumentPrefix.startsWith(\"~/\")\n\t\t\t? path.join(os.homedir(), argumentPrefix.slice(2))\n\t\t\t: argumentPrefix;\n\t\t// A prefix ending in a separator names the directory to list; otherwise the\n\t\t// last segment is a partial name to filter its parent by.\n\t\tconst endsWithSep = expanded.endsWith(\"/\") || expanded.endsWith(path.sep);\n\t\tconst base = endsWithSep ? expanded : path.dirname(expanded);\n\t\tconst partial = endsWithSep ? \"\" : path.basename(expanded);\n\t\tconst searchDir = path.isAbsolute(base) ? base : path.resolve(cwd, base || \".\");\n\n\t\tconst completions: Array<{ value: string; label: string }> = [];\n\t\tif (!argumentPrefix) {\n\t\t\tif (this.previousCwd) completions.push({ value: \"-\", label: `- (${this.previousCwd})` });\n\t\t\tcompletions.push({ value: \"~\", label: `~ (${os.homedir()})` });\n\t\t}\n\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = fs.readdirSync(searchDir, { withFileTypes: true });\n\t\t} catch {\n\t\t\treturn completions;\n\t\t}\n\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory()) continue;\n\t\t\tif (partial && !entry.name.startsWith(partial)) continue;\n\t\t\tif (!partial && entry.name.startsWith(\".\")) continue;\n\t\t\tconst joined =\n\t\t\t\tbase && !endsWithSep\n\t\t\t\t\t? path.join(path.dirname(argumentPrefix), entry.name)\n\t\t\t\t\t: `${argumentPrefix}${entry.name}`;\n\t\t\tcompletions.push({ value: `${joined}/`, label: `${entry.name}/` });\n\t\t}\n\t\treturn completions.slice(0, 50);\n\t}\n\n\thandleDebug(): void {\n\t\tconst width = this.ctx.ui.terminal.columns;\n\t\tconst height = this.ctx.ui.terminal.rows;\n\t\tconst allLines = this.ctx.ui.render(width);\n\n\t\tconst debugLogPath = getDebugLogPath();\n\t\tconst debugData = [\n\t\t\t`Debug output at ${new Date().toISOString()}`,\n\t\t\t`Terminal: ${width}x${height}`,\n\t\t\t`Total lines: ${allLines.length}`,\n\t\t\t\"\",\n\t\t\t\"=== All rendered lines with visible widths ===\",\n\t\t\t...allLines.map((line, idx) => {\n\t\t\t\tconst vw = visibleWidth(line);\n\t\t\t\tconst escaped = JSON.stringify(line);\n\t\t\t\treturn `[${idx}] (w=${vw}) ${escaped}`;\n\t\t\t}),\n\t\t\t\"\",\n\t\t\t\"=== Agent messages (JSONL) ===\",\n\t\t\t...this.ctx.session.messages.map((msg) => JSON.stringify(msg)),\n\t\t\t\"\",\n\t\t].join(\"\\n\");\n\n\t\tfs.mkdirSync(path.dirname(debugLogPath), { recursive: true });\n\t\tfs.writeFileSync(debugLogPath, debugData);\n\n\t\tthis.ctx.chatContainer.addChild(new Spacer(1));\n\t\tthis.ctx.chatContainer.addChild(\n\t\t\tnew Text(`${theme.fg(\"accent\", \"✓ Debug log written\")}\\n${theme.fg(\"muted\", debugLogPath)}`, 1, 0),\n\t\t);\n\t\tthis.ctx.ui.requestRender();\n\t}\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { type Component } from "@kolisachint/hoocode-tui";
2
2
  import type { AgentSession } from "../../../core/agent-session.js";
3
3
  import type { ReadonlyFooterDataProvider } from "../../../core/footer-data-provider.js";
4
- import type { ToolOutputView } from "../../../core/tool-output-view.js";
4
+ import { type ToolOutputView } from "../../../core/tool-output-view.js";
5
5
  /**
6
6
  * Footer component that shows pwd, token stats, and context usage.
7
7
  * Computes token/context stats from session, gets git branch and extension statuses from provider.
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,0BAA0B,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAIxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAiFxE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAM/C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IANnB,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,gBAAgB,CAAS;IAEjC,YACS,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B,EAC3C;IAEJ,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAEtC;IAED,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5C;IAED,4EAA4E;IAC5E,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAE5C;IAED;;;;OAIG;IACH,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAExC;IAED;;;OAGG;IACH,UAAU,IAAI,IAAI,CAEjB;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI,CAEd;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAyK9B;CACD","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@kolisachint/hoocode-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport { sumAssistantUsage } from \"../../../core/agent-session-stats.js\";\nimport { BRAND_MARK, GIT_BRANCH_GLYPH } from \"../../../core/brand.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { formatTokens } from \"../../../core/format-tokens.js\";\nimport { type StartupProgress, startupProgress } from \"../../../core/startup-progress.js\";\nimport { taskStore } from \"../../../core/task-store.js\";\nimport type { ToolOutputView } from \"../../../core/tool-output-view.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { renderDownloadProgress, renderProgressBar } from \"./progress-bar.js\";\nimport { sessionChipFits } from \"./session-chip.js\";\n\n/**\n * Assemble one footer line: `left` flush left, `right` flush right when it fits\n * (≥2 cols between), padded to the full width. When it doesn't fit, drop `right`\n * and pad; when even `left` overflows, truncate it. Width math runs on the plain\n * strings; the styled strings carry the colour. Every returned line is exactly\n * `width` cells or fewer — the invariant the footer-width tests hold us to.\n */\nfunction assembleLine(width: number, leftPlain: string, leftStyled: string, rightPlain = \"\", rightStyled = \"\"): string {\n\tconst lw = visibleWidth(leftPlain);\n\tif (rightPlain && lw + 2 + visibleWidth(rightPlain) <= width) {\n\t\treturn leftStyled + \" \".repeat(width - lw - visibleWidth(rightPlain)) + rightStyled;\n\t}\n\tif (lw <= width) return leftStyled + \" \".repeat(width - lw);\n\treturn truncateToWidth(leftStyled, width, theme.fg(\"dim\", \"…\"));\n}\n\n/** A compact context-fill gauge, coloured by proximity to the auto-compact trip point. */\nfunction contextGauge(percent: number, errorLevel: number, warnLevel: number): { plain: string; styled: string } {\n\tconst CELLS = 8;\n\tconst filled = Math.max(0, Math.min(CELLS, Math.round((percent / 100) * CELLS)));\n\tconst fill = \"▰\".repeat(filled);\n\tconst track = \"▱\".repeat(CELLS - filled);\n\tconst color = percent >= errorLevel ? \"error\" : percent >= warnLevel ? \"warning\" : \"accent\";\n\t// The unfilled track takes `halftone`, which falls back to `dim` — the tone it\n\t// used before the token existed. The point of separating them is that `dim` is\n\t// body-weight text: a track drawn in it reads as writing rather than as the\n\t// space the fill has yet to reach.\n\treturn { plain: fill + track, styled: theme.fg(color, fill) + theme.fg(\"halftone\", track) };\n}\n\n/**\n * The view dial's glyph, filling up as the view widens — so the footer shows\n * where the dial sits on its three-stop scale, not just its name.\n */\nconst TOOL_OUTPUT_VIEW_GLYPHS: Record<ToolOutputView, string> = {\n\tradar: \"◌\",\n\tglance: \"◍\",\n\tfull: \"◉\",\n};\n\n/** Count subagent runs currently in flight, for the footer's live delegation cue. */\nfunction activeSubagentCount(): number {\n\treturn taskStore.list().filter((t) => t.source === \"subagent\" && t.status === \"in_progress\").length;\n}\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\t// Replace newlines, tabs, carriage returns with space, then collapse multiple spaces\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\n/**\n * One footer line for a transient progress entry (tool download, index build,\n * `/learn` reading transcripts). The bar comes from the shared progress-bar\n * component, so this line and the voice panel's cannot drift apart again. An\n * error entry renders as a dim message instead. Returns a styled string; the\n * caller width-clamps it.\n */\nfunction renderStartupLine(entry: StartupProgress): string {\n\tif (entry.kind === \"error\") {\n\t\treturn theme.fg(\"dim\", `${entry.label}: ${entry.message}`);\n\t}\n\tconst label = theme.fg(\"text\", entry.label);\n\tif (entry.kind === \"download\") {\n\t\treturn `${label} ${renderDownloadProgress(entry.receivedBytes, entry.totalBytes)}`;\n\t}\n\tconst ratio = entry.total > 0 ? entry.done / entry.total : 0;\n\treturn `${label} ${renderProgressBar(ratio, `${entry.done}/${entry.total} ${entry.unit}`)}`;\n}\n\n/**\n * Footer component that shows pwd, token stats, and context usage.\n * Computes token/context stats from session, gets git branch and extension statuses from provider.\n */\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate toolOutputView: ToolOutputView = \"glance\";\n\tprivate sessionChipShown = false;\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetSession(session: AgentSession): void {\n\t\tthis.session = session;\n\t}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\t/** The view dial's current stop, shown so `alt+o` has somewhere to land. */\n\tsetToolOutputView(view: ToolOutputView): void {\n\t\tthis.toolOutputView = view;\n\t}\n\n\t/**\n\t * Whether the input box is carrying a session chip. When it is, line 1 drops\n\t * its own copy of the name: saying it twice, six rows apart, teaches the eye\n\t * to ignore both, and line 1 is the line that runs out of width first.\n\t */\n\tsetSessionChipShown(shown: boolean): void {\n\t\tthis.sessionChipShown = shown;\n\t}\n\n\t/**\n\t * No-op: git branch caching now handled by provider.\n\t * Kept for compatibility with existing call sites in interactive-mode.\n\t */\n\tinvalidate(): void {\n\t\t// No-op: git branch is cached/invalidated by provider\n\t}\n\n\t/**\n\t * Clean up resources.\n\t * Git watcher cleanup now handled by provider.\n\t */\n\tdispose(): void {\n\t\t// Git watcher cleanup handled by provider\n\t}\n\n\trender(width: number): string[] {\n\t\tconst state = this.session.state;\n\n\t\t// Cumulative usage across ALL session entries (not just post-compaction\n\t\t// messages). Shares sumAssistantUsage with the per-request cost line the\n\t\t// transcript prints at agent_end, so the footer total and that line are always\n\t\t// derived from the same accounting.\n\t\tconst {\n\t\t\tinput: totalInput,\n\t\t\toutput: totalOutput,\n\t\t\tcacheRead: totalCacheRead,\n\t\t\tcacheWrite: totalCacheWrite,\n\t\t\tcost: totalCost,\n\t\t} = sumAssistantUsage(this.session.sessionManager.getEntries());\n\n\t\t// Calculate context usage from session (handles compaction correctly).\n\t\t// After compaction, tokens are unknown until the next LLM response.\n\t\tconst contextUsage = this.session.getContextUsage();\n\t\tconst contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n\t\t// Replace home directory with ~\n\t\tlet pwd = this.session.sessionManager.getCwd();\n\t\tconst home = process.env.HOME || process.env.USERPROFILE;\n\t\tif (home && pwd.startsWith(home)) {\n\t\t\tpwd = `~${pwd.slice(home.length)}`;\n\t\t}\n\t\tconst branch = this.footerData.getGitBranch();\n\t\t// The name is shown here only when the chip is not carrying it — either no\n\t\t// chip is set, or the terminal is too narrow for one, in which case the\n\t\t// footer is the only place left that says which session this is.\n\t\tconst sessionName =\n\t\t\tthis.sessionChipShown && sessionChipFits(width) ? undefined : this.session.sessionManager.getDisplayName();\n\t\tconst modeLabel = this.footerData.getActiveMode();\n\n\t\t// ── Line 1 — identity & location ────────────────────────────────────────\n\t\t// Lead with the brand mark + MODE (the agent's guardrail: Ask/Plan/Build/\n\t\t// Debug) in bold accent so it is the first thing the eye lands on, then the\n\t\t// path, git branch, and session name in descending emphasis. The live\n\t\t// subagent count sits flush right — present only while work is delegated.\n\t\tconst modeUp = modeLabel.toUpperCase();\n\t\t// Themes that define the brandBg/brandText pair paint the mark as a filled\n\t\t// chip; the padding lives in the plain string too so width math and\n\t\t// truncation stay honest. Themes without the pair keep accent-coloured text.\n\t\tconst chip = theme.hasBg(\"brandBg\") && theme.has(\"brandText\");\n\t\tconst brand = chip ? ` ${BRAND_MARK} ${modeUp} ` : `${BRAND_MARK} ${modeUp}`;\n\t\tlet l1Plain = `${brand} ${pwd}`;\n\t\tconst brandStyled = chip\n\t\t\t? theme.bg(\"brandBg\", theme.bold(theme.fg(\"brandText\", brand)))\n\t\t\t: theme.bold(theme.fg(\"accent\", brand));\n\t\tlet l1Styled = `${brandStyled} ${theme.fg(\"muted\", pwd)}`;\n\t\tif (branch) {\n\t\t\tl1Plain += ` ${GIT_BRANCH_GLYPH} ${branch}`;\n\t\t\tl1Styled += ` ${theme.fg(\"dim\", GIT_BRANCH_GLYPH)} ${theme.fg(\"muted\", branch)}`;\n\t\t}\n\t\tif (sessionName) {\n\t\t\tl1Plain += ` • ${sessionName}`;\n\t\t\tl1Styled += theme.fg(\"dim\", ` • ${sessionName}`);\n\t\t}\n\t\tconst nSub = activeSubagentCount();\n\t\t// Right cluster: the view dial always, the live subagent count when there\n\t\t// is one. The dial's glyph fills up as the view widens, so its position on\n\t\t// the three-stop scale reads without parsing the word.\n\t\tconst viewGlyph = TOOL_OUTPUT_VIEW_GLYPHS[this.toolOutputView];\n\t\tconst rightParts: Array<{ plain: string; styled: string }> = [];\n\t\tif (nSub > 0) {\n\t\t\trightParts.push({\n\t\t\t\tplain: `◇${nSub} running`,\n\t\t\t\tstyled: theme.fg(\"accent\", `◇${nSub}`) + theme.fg(\"dim\", \" running\"),\n\t\t\t});\n\t\t}\n\t\trightParts.push({\n\t\t\tplain: `${viewGlyph} ${this.toolOutputView}`,\n\t\t\tstyled: theme.fg(\"dim\", `${viewGlyph} ${this.toolOutputView}`),\n\t\t});\n\t\tconst l1RightPlain = rightParts.map((p) => p.plain).join(\" \");\n\t\tconst l1RightStyled = rightParts.map((p) => p.styled).join(\" \");\n\t\tconst line1 = assembleLine(width, l1Plain, l1Styled, l1RightPlain, l1RightStyled);\n\n\t\t// ── Line 2 — session vitals ─────────────────────────────────────────────\n\t\t// A context-fill gauge (coloured by proximity to the auto-compact trip\n\t\t// point) leads, then token/cost deltas, with the model + thinking level\n\t\t// flush right. Numbers read in muted, labels/arrows in dim — a legible\n\t\t// hierarchy in place of the old uniform grey.\n\t\tlet thresholdPercent: number | undefined;\n\t\tif (this.autoCompactEnabled && contextWindow > 0) {\n\t\t\tconst reserveTokens = this.session.settingsManager.getCompactionSettings().reserveTokens;\n\t\t\tconst effective = contextWindow - reserveTokens;\n\t\t\tif (effective > 0) thresholdPercent = (effective / contextWindow) * 100;\n\t\t}\n\t\tconst errorLevel = thresholdPercent !== undefined ? thresholdPercent - 3 : 90;\n\t\tconst warnLevel = thresholdPercent !== undefined ? thresholdPercent - 10 : 70;\n\t\tconst autoIndicator =\n\t\t\tthresholdPercent !== undefined\n\t\t\t\t? ` auto@${thresholdPercent.toFixed(0)}%`\n\t\t\t\t: this.autoCompactEnabled\n\t\t\t\t\t? \" auto\"\n\t\t\t\t\t: \"\";\n\n\t\tconst gauge = contextGauge(contextPercentValue, errorLevel, warnLevel);\n\t\tconst pctText = contextPercent === \"?\" ? \"?\" : `${contextPercent}%`;\n\t\tconst pctColor =\n\t\t\tcontextPercentValue >= errorLevel ? \"error\" : contextPercentValue >= warnLevel ? \"warning\" : \"muted\";\n\t\tconst winText = `${formatTokens(contextWindow)}${autoIndicator}`;\n\n\t\tconst segs: Array<{ plain: string; styled: string }> = [\n\t\t\t{\n\t\t\t\tplain: `${gauge.plain} ${pctText} ${winText}`,\n\t\t\t\tstyled: `${gauge.styled} ${theme.fg(pctColor, pctText)} ${theme.fg(\"dim\", winText)}`,\n\t\t\t},\n\t\t];\n\t\tconst arrow = (a: string, n: number) => ({\n\t\t\tplain: `${a}${formatTokens(n)}`,\n\t\t\tstyled: theme.fg(\"dim\", a) + theme.fg(\"muted\", formatTokens(n)),\n\t\t});\n\t\tif (totalInput) segs.push(arrow(\"↑\", totalInput));\n\t\tif (totalOutput) segs.push(arrow(\"↓\", totalOutput));\n\t\tif (totalCacheRead) segs.push(arrow(\"R\", totalCacheRead));\n\t\tif (totalCacheWrite) segs.push(arrow(\"W\", totalCacheWrite));\n\t\tconst usingSubscription = state.model ? this.session.modelRegistry.isUsingOAuth(state.model) : false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tsegs.push({ plain: costStr, styled: theme.fg(\"muted\", costStr) });\n\t\t}\n\t\tconst l2Plain = segs.map((s) => s.plain).join(\" \");\n\t\tconst l2Styled = segs.map((s) => s.styled).join(\" \");\n\n\t\t// Right: model, thinking level, and provider (when several are configured).\n\t\tconst modelName = state.model?.id || \"no-model\";\n\t\tlet r2Plain = modelName;\n\t\tlet r2Styled = theme.fg(\"muted\", modelName);\n\t\tif (state.model?.reasoning) {\n\t\t\tconst tl = state.thinkingLevel || \"off\";\n\t\t\tconst tstr = tl === \"off\" ? \"thinking off\" : tl;\n\t\t\tr2Plain += ` • ${tstr}`;\n\t\t\tr2Styled += theme.fg(\"dim\", ` • ${tstr}`);\n\t\t}\n\t\tif (this.footerData.getAvailableProviderCount() > 1 && state.model) {\n\t\t\t// Prepend the provider only when the whole right cluster still fits.\n\t\t\tconst withProv = `(${state.model.provider}) ${r2Plain}`;\n\t\t\tif (visibleWidth(l2Plain) + 2 + visibleWidth(withProv) <= width) {\n\t\t\t\tr2Plain = withProv;\n\t\t\t\tr2Styled = theme.fg(\"dim\", `(${state.model.provider}) `) + r2Styled;\n\t\t\t}\n\t\t}\n\t\tconst line2 = assembleLine(width, l2Plain, l2Styled, r2Plain, r2Styled);\n\n\t\tconst lines = [line1, line2];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\t// Truncate to terminal width with dim ellipsis for consistency with footer style\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\t// Transient startup progress (first-run tool downloads, index build): one\n\t\t// determinate bar per entry, cleared as each settles. Width-clamped like the\n\t\t// status line so the footer never overflows.\n\t\tfor (const entry of startupProgress.list()) {\n\t\t\tlines.push(truncateToWidth(renderStartupLine(entry), width, theme.fg(\"dim\", \"…\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAiC,MAAM,0BAA0B,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AAIxF,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAiFlG;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAM/C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IANnB,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,cAAc,CAA4C;IAClE,OAAO,CAAC,gBAAgB,CAAS;IAEjC,YACS,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,0BAA0B,EAC3C;IAEJ,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAEtC;IAED,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE5C;IAED,4EAA4E;IAC5E,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAE5C;IAED;;;;OAIG;IACH,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAExC;IAED;;;OAGG;IACH,UAAU,IAAI,IAAI,CAEjB;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI,CAEd;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAyK9B;CACD","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@kolisachint/hoocode-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport { sumAssistantUsage } from \"../../../core/agent-session-stats.js\";\nimport { BRAND_MARK, GIT_BRANCH_GLYPH } from \"../../../core/brand.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { formatTokens } from \"../../../core/format-tokens.js\";\nimport { type StartupProgress, startupProgress } from \"../../../core/startup-progress.js\";\nimport { taskStore } from \"../../../core/task-store.js\";\nimport { DEFAULT_TOOL_OUTPUT_VIEW, type ToolOutputView } from \"../../../core/tool-output-view.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { renderDownloadProgress, renderProgressBar } from \"./progress-bar.js\";\nimport { sessionChipFits } from \"./session-chip.js\";\n\n/**\n * Assemble one footer line: `left` flush left, `right` flush right when it fits\n * (≥2 cols between), padded to the full width. When it doesn't fit, drop `right`\n * and pad; when even `left` overflows, truncate it. Width math runs on the plain\n * strings; the styled strings carry the colour. Every returned line is exactly\n * `width` cells or fewer — the invariant the footer-width tests hold us to.\n */\nfunction assembleLine(width: number, leftPlain: string, leftStyled: string, rightPlain = \"\", rightStyled = \"\"): string {\n\tconst lw = visibleWidth(leftPlain);\n\tif (rightPlain && lw + 2 + visibleWidth(rightPlain) <= width) {\n\t\treturn leftStyled + \" \".repeat(width - lw - visibleWidth(rightPlain)) + rightStyled;\n\t}\n\tif (lw <= width) return leftStyled + \" \".repeat(width - lw);\n\treturn truncateToWidth(leftStyled, width, theme.fg(\"dim\", \"…\"));\n}\n\n/** A compact context-fill gauge, coloured by proximity to the auto-compact trip point. */\nfunction contextGauge(percent: number, errorLevel: number, warnLevel: number): { plain: string; styled: string } {\n\tconst CELLS = 8;\n\tconst filled = Math.max(0, Math.min(CELLS, Math.round((percent / 100) * CELLS)));\n\tconst fill = \"▰\".repeat(filled);\n\tconst track = \"▱\".repeat(CELLS - filled);\n\tconst color = percent >= errorLevel ? \"error\" : percent >= warnLevel ? \"warning\" : \"accent\";\n\t// The unfilled track takes `halftone`, which falls back to `dim` — the tone it\n\t// used before the token existed. The point of separating them is that `dim` is\n\t// body-weight text: a track drawn in it reads as writing rather than as the\n\t// space the fill has yet to reach.\n\treturn { plain: fill + track, styled: theme.fg(color, fill) + theme.fg(\"halftone\", track) };\n}\n\n/**\n * The view dial's glyph, filling up as the view widens — so the footer shows\n * where the dial sits on its three-stop scale, not just its name.\n */\nconst TOOL_OUTPUT_VIEW_GLYPHS: Record<ToolOutputView, string> = {\n\tradar: \"◌\",\n\tpeek: \"◍\",\n\tfull: \"◉\",\n};\n\n/** Count subagent runs currently in flight, for the footer's live delegation cue. */\nfunction activeSubagentCount(): number {\n\treturn taskStore.list().filter((t) => t.source === \"subagent\" && t.status === \"in_progress\").length;\n}\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\t// Replace newlines, tabs, carriage returns with space, then collapse multiple spaces\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\n/**\n * One footer line for a transient progress entry (tool download, index build,\n * `/learn` reading transcripts). The bar comes from the shared progress-bar\n * component, so this line and the voice panel's cannot drift apart again. An\n * error entry renders as a dim message instead. Returns a styled string; the\n * caller width-clamps it.\n */\nfunction renderStartupLine(entry: StartupProgress): string {\n\tif (entry.kind === \"error\") {\n\t\treturn theme.fg(\"dim\", `${entry.label}: ${entry.message}`);\n\t}\n\tconst label = theme.fg(\"text\", entry.label);\n\tif (entry.kind === \"download\") {\n\t\treturn `${label} ${renderDownloadProgress(entry.receivedBytes, entry.totalBytes)}`;\n\t}\n\tconst ratio = entry.total > 0 ? entry.done / entry.total : 0;\n\treturn `${label} ${renderProgressBar(ratio, `${entry.done}/${entry.total} ${entry.unit}`)}`;\n}\n\n/**\n * Footer component that shows pwd, token stats, and context usage.\n * Computes token/context stats from session, gets git branch and extension statuses from provider.\n */\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate toolOutputView: ToolOutputView = DEFAULT_TOOL_OUTPUT_VIEW;\n\tprivate sessionChipShown = false;\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetSession(session: AgentSession): void {\n\t\tthis.session = session;\n\t}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\t/** The view dial's current stop, shown so `alt+o` has somewhere to land. */\n\tsetToolOutputView(view: ToolOutputView): void {\n\t\tthis.toolOutputView = view;\n\t}\n\n\t/**\n\t * Whether the input box is carrying a session chip. When it is, line 1 drops\n\t * its own copy of the name: saying it twice, six rows apart, teaches the eye\n\t * to ignore both, and line 1 is the line that runs out of width first.\n\t */\n\tsetSessionChipShown(shown: boolean): void {\n\t\tthis.sessionChipShown = shown;\n\t}\n\n\t/**\n\t * No-op: git branch caching now handled by provider.\n\t * Kept for compatibility with existing call sites in interactive-mode.\n\t */\n\tinvalidate(): void {\n\t\t// No-op: git branch is cached/invalidated by provider\n\t}\n\n\t/**\n\t * Clean up resources.\n\t * Git watcher cleanup now handled by provider.\n\t */\n\tdispose(): void {\n\t\t// Git watcher cleanup handled by provider\n\t}\n\n\trender(width: number): string[] {\n\t\tconst state = this.session.state;\n\n\t\t// Cumulative usage across ALL session entries (not just post-compaction\n\t\t// messages). Shares sumAssistantUsage with the per-request cost line the\n\t\t// transcript prints at agent_end, so the footer total and that line are always\n\t\t// derived from the same accounting.\n\t\tconst {\n\t\t\tinput: totalInput,\n\t\t\toutput: totalOutput,\n\t\t\tcacheRead: totalCacheRead,\n\t\t\tcacheWrite: totalCacheWrite,\n\t\t\tcost: totalCost,\n\t\t} = sumAssistantUsage(this.session.sessionManager.getEntries());\n\n\t\t// Calculate context usage from session (handles compaction correctly).\n\t\t// After compaction, tokens are unknown until the next LLM response.\n\t\tconst contextUsage = this.session.getContextUsage();\n\t\tconst contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n\t\t// Replace home directory with ~\n\t\tlet pwd = this.session.sessionManager.getCwd();\n\t\tconst home = process.env.HOME || process.env.USERPROFILE;\n\t\tif (home && pwd.startsWith(home)) {\n\t\t\tpwd = `~${pwd.slice(home.length)}`;\n\t\t}\n\t\tconst branch = this.footerData.getGitBranch();\n\t\t// The name is shown here only when the chip is not carrying it — either no\n\t\t// chip is set, or the terminal is too narrow for one, in which case the\n\t\t// footer is the only place left that says which session this is.\n\t\tconst sessionName =\n\t\t\tthis.sessionChipShown && sessionChipFits(width) ? undefined : this.session.sessionManager.getDisplayName();\n\t\tconst modeLabel = this.footerData.getActiveMode();\n\n\t\t// ── Line 1 — identity & location ────────────────────────────────────────\n\t\t// Lead with the brand mark + MODE (the agent's guardrail: Ask/Plan/Build/\n\t\t// Debug) in bold accent so it is the first thing the eye lands on, then the\n\t\t// path, git branch, and session name in descending emphasis. The live\n\t\t// subagent count sits flush right — present only while work is delegated.\n\t\tconst modeUp = modeLabel.toUpperCase();\n\t\t// Themes that define the brandBg/brandText pair paint the mark as a filled\n\t\t// chip; the padding lives in the plain string too so width math and\n\t\t// truncation stay honest. Themes without the pair keep accent-coloured text.\n\t\tconst chip = theme.hasBg(\"brandBg\") && theme.has(\"brandText\");\n\t\tconst brand = chip ? ` ${BRAND_MARK} ${modeUp} ` : `${BRAND_MARK} ${modeUp}`;\n\t\tlet l1Plain = `${brand} ${pwd}`;\n\t\tconst brandStyled = chip\n\t\t\t? theme.bg(\"brandBg\", theme.bold(theme.fg(\"brandText\", brand)))\n\t\t\t: theme.bold(theme.fg(\"accent\", brand));\n\t\tlet l1Styled = `${brandStyled} ${theme.fg(\"muted\", pwd)}`;\n\t\tif (branch) {\n\t\t\tl1Plain += ` ${GIT_BRANCH_GLYPH} ${branch}`;\n\t\t\tl1Styled += ` ${theme.fg(\"dim\", GIT_BRANCH_GLYPH)} ${theme.fg(\"muted\", branch)}`;\n\t\t}\n\t\tif (sessionName) {\n\t\t\tl1Plain += ` • ${sessionName}`;\n\t\t\tl1Styled += theme.fg(\"dim\", ` • ${sessionName}`);\n\t\t}\n\t\tconst nSub = activeSubagentCount();\n\t\t// Right cluster: the view dial always, the live subagent count when there\n\t\t// is one. The dial's glyph fills up as the view widens, so its position on\n\t\t// the three-stop scale reads without parsing the word.\n\t\tconst viewGlyph = TOOL_OUTPUT_VIEW_GLYPHS[this.toolOutputView];\n\t\tconst rightParts: Array<{ plain: string; styled: string }> = [];\n\t\tif (nSub > 0) {\n\t\t\trightParts.push({\n\t\t\t\tplain: `◇${nSub} running`,\n\t\t\t\tstyled: theme.fg(\"accent\", `◇${nSub}`) + theme.fg(\"dim\", \" running\"),\n\t\t\t});\n\t\t}\n\t\trightParts.push({\n\t\t\tplain: `${viewGlyph} ${this.toolOutputView}`,\n\t\t\tstyled: theme.fg(\"dim\", `${viewGlyph} ${this.toolOutputView}`),\n\t\t});\n\t\tconst l1RightPlain = rightParts.map((p) => p.plain).join(\" \");\n\t\tconst l1RightStyled = rightParts.map((p) => p.styled).join(\" \");\n\t\tconst line1 = assembleLine(width, l1Plain, l1Styled, l1RightPlain, l1RightStyled);\n\n\t\t// ── Line 2 — session vitals ─────────────────────────────────────────────\n\t\t// A context-fill gauge (coloured by proximity to the auto-compact trip\n\t\t// point) leads, then token/cost deltas, with the model + thinking level\n\t\t// flush right. Numbers read in muted, labels/arrows in dim — a legible\n\t\t// hierarchy in place of the old uniform grey.\n\t\tlet thresholdPercent: number | undefined;\n\t\tif (this.autoCompactEnabled && contextWindow > 0) {\n\t\t\tconst reserveTokens = this.session.settingsManager.getCompactionSettings().reserveTokens;\n\t\t\tconst effective = contextWindow - reserveTokens;\n\t\t\tif (effective > 0) thresholdPercent = (effective / contextWindow) * 100;\n\t\t}\n\t\tconst errorLevel = thresholdPercent !== undefined ? thresholdPercent - 3 : 90;\n\t\tconst warnLevel = thresholdPercent !== undefined ? thresholdPercent - 10 : 70;\n\t\tconst autoIndicator =\n\t\t\tthresholdPercent !== undefined\n\t\t\t\t? ` auto@${thresholdPercent.toFixed(0)}%`\n\t\t\t\t: this.autoCompactEnabled\n\t\t\t\t\t? \" auto\"\n\t\t\t\t\t: \"\";\n\n\t\tconst gauge = contextGauge(contextPercentValue, errorLevel, warnLevel);\n\t\tconst pctText = contextPercent === \"?\" ? \"?\" : `${contextPercent}%`;\n\t\tconst pctColor =\n\t\t\tcontextPercentValue >= errorLevel ? \"error\" : contextPercentValue >= warnLevel ? \"warning\" : \"muted\";\n\t\tconst winText = `${formatTokens(contextWindow)}${autoIndicator}`;\n\n\t\tconst segs: Array<{ plain: string; styled: string }> = [\n\t\t\t{\n\t\t\t\tplain: `${gauge.plain} ${pctText} ${winText}`,\n\t\t\t\tstyled: `${gauge.styled} ${theme.fg(pctColor, pctText)} ${theme.fg(\"dim\", winText)}`,\n\t\t\t},\n\t\t];\n\t\tconst arrow = (a: string, n: number) => ({\n\t\t\tplain: `${a}${formatTokens(n)}`,\n\t\t\tstyled: theme.fg(\"dim\", a) + theme.fg(\"muted\", formatTokens(n)),\n\t\t});\n\t\tif (totalInput) segs.push(arrow(\"↑\", totalInput));\n\t\tif (totalOutput) segs.push(arrow(\"↓\", totalOutput));\n\t\tif (totalCacheRead) segs.push(arrow(\"R\", totalCacheRead));\n\t\tif (totalCacheWrite) segs.push(arrow(\"W\", totalCacheWrite));\n\t\tconst usingSubscription = state.model ? this.session.modelRegistry.isUsingOAuth(state.model) : false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tsegs.push({ plain: costStr, styled: theme.fg(\"muted\", costStr) });\n\t\t}\n\t\tconst l2Plain = segs.map((s) => s.plain).join(\" \");\n\t\tconst l2Styled = segs.map((s) => s.styled).join(\" \");\n\n\t\t// Right: model, thinking level, and provider (when several are configured).\n\t\tconst modelName = state.model?.id || \"no-model\";\n\t\tlet r2Plain = modelName;\n\t\tlet r2Styled = theme.fg(\"muted\", modelName);\n\t\tif (state.model?.reasoning) {\n\t\t\tconst tl = state.thinkingLevel || \"off\";\n\t\t\tconst tstr = tl === \"off\" ? \"thinking off\" : tl;\n\t\t\tr2Plain += ` • ${tstr}`;\n\t\t\tr2Styled += theme.fg(\"dim\", ` • ${tstr}`);\n\t\t}\n\t\tif (this.footerData.getAvailableProviderCount() > 1 && state.model) {\n\t\t\t// Prepend the provider only when the whole right cluster still fits.\n\t\t\tconst withProv = `(${state.model.provider}) ${r2Plain}`;\n\t\t\tif (visibleWidth(l2Plain) + 2 + visibleWidth(withProv) <= width) {\n\t\t\t\tr2Plain = withProv;\n\t\t\t\tr2Styled = theme.fg(\"dim\", `(${state.model.provider}) `) + r2Styled;\n\t\t\t}\n\t\t}\n\t\tconst line2 = assembleLine(width, l2Plain, l2Styled, r2Plain, r2Styled);\n\n\t\tconst lines = [line1, line2];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\t// Truncate to terminal width with dim ellipsis for consistency with footer style\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\t// Transient startup progress (first-run tool downloads, index build): one\n\t\t// determinate bar per entry, cleared as each settles. Width-clamped like the\n\t\t// status line so the footer never overflows.\n\t\tfor (const entry of startupProgress.list()) {\n\t\t\tlines.push(truncateToWidth(renderStartupLine(entry), width, theme.fg(\"dim\", \"…\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
@@ -4,6 +4,7 @@ import { BRAND_MARK, GIT_BRANCH_GLYPH } from "../../../core/brand.js";
4
4
  import { formatTokens } from "../../../core/format-tokens.js";
5
5
  import { startupProgress } from "../../../core/startup-progress.js";
6
6
  import { taskStore } from "../../../core/task-store.js";
7
+ import { DEFAULT_TOOL_OUTPUT_VIEW } from "../../../core/tool-output-view.js";
7
8
  import { theme } from "../theme/theme.js";
8
9
  import { renderDownloadProgress, renderProgressBar } from "./progress-bar.js";
9
10
  import { sessionChipFits } from "./session-chip.js";
@@ -42,7 +43,7 @@ function contextGauge(percent, errorLevel, warnLevel) {
42
43
  */
43
44
  const TOOL_OUTPUT_VIEW_GLYPHS = {
44
45
  radar: "◌",
45
- glance: "◍",
46
+ peek: "◍",
46
47
  full: "◉",
47
48
  };
48
49
  /** Count subagent runs currently in flight, for the footer's live delegation cue. */
@@ -86,7 +87,7 @@ export class FooterComponent {
86
87
  session;
87
88
  footerData;
88
89
  autoCompactEnabled = true;
89
- toolOutputView = "glance";
90
+ toolOutputView = DEFAULT_TOOL_OUTPUT_VIEW;
90
91
  sessionChipShown = false;
91
92
  constructor(session, footerData) {
92
93
  this.session = session;
@@ -1 +1 @@
1
- {"version":3,"file":"footer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@kolisachint/hoocode-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport { sumAssistantUsage } from \"../../../core/agent-session-stats.js\";\nimport { BRAND_MARK, GIT_BRANCH_GLYPH } from \"../../../core/brand.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { formatTokens } from \"../../../core/format-tokens.js\";\nimport { type StartupProgress, startupProgress } from \"../../../core/startup-progress.js\";\nimport { taskStore } from \"../../../core/task-store.js\";\nimport type { ToolOutputView } from \"../../../core/tool-output-view.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { renderDownloadProgress, renderProgressBar } from \"./progress-bar.js\";\nimport { sessionChipFits } from \"./session-chip.js\";\n\n/**\n * Assemble one footer line: `left` flush left, `right` flush right when it fits\n * (≥2 cols between), padded to the full width. When it doesn't fit, drop `right`\n * and pad; when even `left` overflows, truncate it. Width math runs on the plain\n * strings; the styled strings carry the colour. Every returned line is exactly\n * `width` cells or fewer — the invariant the footer-width tests hold us to.\n */\nfunction assembleLine(width: number, leftPlain: string, leftStyled: string, rightPlain = \"\", rightStyled = \"\"): string {\n\tconst lw = visibleWidth(leftPlain);\n\tif (rightPlain && lw + 2 + visibleWidth(rightPlain) <= width) {\n\t\treturn leftStyled + \" \".repeat(width - lw - visibleWidth(rightPlain)) + rightStyled;\n\t}\n\tif (lw <= width) return leftStyled + \" \".repeat(width - lw);\n\treturn truncateToWidth(leftStyled, width, theme.fg(\"dim\", \"…\"));\n}\n\n/** A compact context-fill gauge, coloured by proximity to the auto-compact trip point. */\nfunction contextGauge(percent: number, errorLevel: number, warnLevel: number): { plain: string; styled: string } {\n\tconst CELLS = 8;\n\tconst filled = Math.max(0, Math.min(CELLS, Math.round((percent / 100) * CELLS)));\n\tconst fill = \"▰\".repeat(filled);\n\tconst track = \"▱\".repeat(CELLS - filled);\n\tconst color = percent >= errorLevel ? \"error\" : percent >= warnLevel ? \"warning\" : \"accent\";\n\t// The unfilled track takes `halftone`, which falls back to `dim` — the tone it\n\t// used before the token existed. The point of separating them is that `dim` is\n\t// body-weight text: a track drawn in it reads as writing rather than as the\n\t// space the fill has yet to reach.\n\treturn { plain: fill + track, styled: theme.fg(color, fill) + theme.fg(\"halftone\", track) };\n}\n\n/**\n * The view dial's glyph, filling up as the view widens — so the footer shows\n * where the dial sits on its three-stop scale, not just its name.\n */\nconst TOOL_OUTPUT_VIEW_GLYPHS: Record<ToolOutputView, string> = {\n\tradar: \"◌\",\n\tglance: \"◍\",\n\tfull: \"◉\",\n};\n\n/** Count subagent runs currently in flight, for the footer's live delegation cue. */\nfunction activeSubagentCount(): number {\n\treturn taskStore.list().filter((t) => t.source === \"subagent\" && t.status === \"in_progress\").length;\n}\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\t// Replace newlines, tabs, carriage returns with space, then collapse multiple spaces\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\n/**\n * One footer line for a transient progress entry (tool download, index build,\n * `/learn` reading transcripts). The bar comes from the shared progress-bar\n * component, so this line and the voice panel's cannot drift apart again. An\n * error entry renders as a dim message instead. Returns a styled string; the\n * caller width-clamps it.\n */\nfunction renderStartupLine(entry: StartupProgress): string {\n\tif (entry.kind === \"error\") {\n\t\treturn theme.fg(\"dim\", `${entry.label}: ${entry.message}`);\n\t}\n\tconst label = theme.fg(\"text\", entry.label);\n\tif (entry.kind === \"download\") {\n\t\treturn `${label} ${renderDownloadProgress(entry.receivedBytes, entry.totalBytes)}`;\n\t}\n\tconst ratio = entry.total > 0 ? entry.done / entry.total : 0;\n\treturn `${label} ${renderProgressBar(ratio, `${entry.done}/${entry.total} ${entry.unit}`)}`;\n}\n\n/**\n * Footer component that shows pwd, token stats, and context usage.\n * Computes token/context stats from session, gets git branch and extension statuses from provider.\n */\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate toolOutputView: ToolOutputView = \"glance\";\n\tprivate sessionChipShown = false;\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetSession(session: AgentSession): void {\n\t\tthis.session = session;\n\t}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\t/** The view dial's current stop, shown so `alt+o` has somewhere to land. */\n\tsetToolOutputView(view: ToolOutputView): void {\n\t\tthis.toolOutputView = view;\n\t}\n\n\t/**\n\t * Whether the input box is carrying a session chip. When it is, line 1 drops\n\t * its own copy of the name: saying it twice, six rows apart, teaches the eye\n\t * to ignore both, and line 1 is the line that runs out of width first.\n\t */\n\tsetSessionChipShown(shown: boolean): void {\n\t\tthis.sessionChipShown = shown;\n\t}\n\n\t/**\n\t * No-op: git branch caching now handled by provider.\n\t * Kept for compatibility with existing call sites in interactive-mode.\n\t */\n\tinvalidate(): void {\n\t\t// No-op: git branch is cached/invalidated by provider\n\t}\n\n\t/**\n\t * Clean up resources.\n\t * Git watcher cleanup now handled by provider.\n\t */\n\tdispose(): void {\n\t\t// Git watcher cleanup handled by provider\n\t}\n\n\trender(width: number): string[] {\n\t\tconst state = this.session.state;\n\n\t\t// Cumulative usage across ALL session entries (not just post-compaction\n\t\t// messages). Shares sumAssistantUsage with the per-request cost line the\n\t\t// transcript prints at agent_end, so the footer total and that line are always\n\t\t// derived from the same accounting.\n\t\tconst {\n\t\t\tinput: totalInput,\n\t\t\toutput: totalOutput,\n\t\t\tcacheRead: totalCacheRead,\n\t\t\tcacheWrite: totalCacheWrite,\n\t\t\tcost: totalCost,\n\t\t} = sumAssistantUsage(this.session.sessionManager.getEntries());\n\n\t\t// Calculate context usage from session (handles compaction correctly).\n\t\t// After compaction, tokens are unknown until the next LLM response.\n\t\tconst contextUsage = this.session.getContextUsage();\n\t\tconst contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n\t\t// Replace home directory with ~\n\t\tlet pwd = this.session.sessionManager.getCwd();\n\t\tconst home = process.env.HOME || process.env.USERPROFILE;\n\t\tif (home && pwd.startsWith(home)) {\n\t\t\tpwd = `~${pwd.slice(home.length)}`;\n\t\t}\n\t\tconst branch = this.footerData.getGitBranch();\n\t\t// The name is shown here only when the chip is not carrying it — either no\n\t\t// chip is set, or the terminal is too narrow for one, in which case the\n\t\t// footer is the only place left that says which session this is.\n\t\tconst sessionName =\n\t\t\tthis.sessionChipShown && sessionChipFits(width) ? undefined : this.session.sessionManager.getDisplayName();\n\t\tconst modeLabel = this.footerData.getActiveMode();\n\n\t\t// ── Line 1 — identity & location ────────────────────────────────────────\n\t\t// Lead with the brand mark + MODE (the agent's guardrail: Ask/Plan/Build/\n\t\t// Debug) in bold accent so it is the first thing the eye lands on, then the\n\t\t// path, git branch, and session name in descending emphasis. The live\n\t\t// subagent count sits flush right — present only while work is delegated.\n\t\tconst modeUp = modeLabel.toUpperCase();\n\t\t// Themes that define the brandBg/brandText pair paint the mark as a filled\n\t\t// chip; the padding lives in the plain string too so width math and\n\t\t// truncation stay honest. Themes without the pair keep accent-coloured text.\n\t\tconst chip = theme.hasBg(\"brandBg\") && theme.has(\"brandText\");\n\t\tconst brand = chip ? ` ${BRAND_MARK} ${modeUp} ` : `${BRAND_MARK} ${modeUp}`;\n\t\tlet l1Plain = `${brand} ${pwd}`;\n\t\tconst brandStyled = chip\n\t\t\t? theme.bg(\"brandBg\", theme.bold(theme.fg(\"brandText\", brand)))\n\t\t\t: theme.bold(theme.fg(\"accent\", brand));\n\t\tlet l1Styled = `${brandStyled} ${theme.fg(\"muted\", pwd)}`;\n\t\tif (branch) {\n\t\t\tl1Plain += ` ${GIT_BRANCH_GLYPH} ${branch}`;\n\t\t\tl1Styled += ` ${theme.fg(\"dim\", GIT_BRANCH_GLYPH)} ${theme.fg(\"muted\", branch)}`;\n\t\t}\n\t\tif (sessionName) {\n\t\t\tl1Plain += ` • ${sessionName}`;\n\t\t\tl1Styled += theme.fg(\"dim\", ` • ${sessionName}`);\n\t\t}\n\t\tconst nSub = activeSubagentCount();\n\t\t// Right cluster: the view dial always, the live subagent count when there\n\t\t// is one. The dial's glyph fills up as the view widens, so its position on\n\t\t// the three-stop scale reads without parsing the word.\n\t\tconst viewGlyph = TOOL_OUTPUT_VIEW_GLYPHS[this.toolOutputView];\n\t\tconst rightParts: Array<{ plain: string; styled: string }> = [];\n\t\tif (nSub > 0) {\n\t\t\trightParts.push({\n\t\t\t\tplain: `◇${nSub} running`,\n\t\t\t\tstyled: theme.fg(\"accent\", `◇${nSub}`) + theme.fg(\"dim\", \" running\"),\n\t\t\t});\n\t\t}\n\t\trightParts.push({\n\t\t\tplain: `${viewGlyph} ${this.toolOutputView}`,\n\t\t\tstyled: theme.fg(\"dim\", `${viewGlyph} ${this.toolOutputView}`),\n\t\t});\n\t\tconst l1RightPlain = rightParts.map((p) => p.plain).join(\" \");\n\t\tconst l1RightStyled = rightParts.map((p) => p.styled).join(\" \");\n\t\tconst line1 = assembleLine(width, l1Plain, l1Styled, l1RightPlain, l1RightStyled);\n\n\t\t// ── Line 2 — session vitals ─────────────────────────────────────────────\n\t\t// A context-fill gauge (coloured by proximity to the auto-compact trip\n\t\t// point) leads, then token/cost deltas, with the model + thinking level\n\t\t// flush right. Numbers read in muted, labels/arrows in dim — a legible\n\t\t// hierarchy in place of the old uniform grey.\n\t\tlet thresholdPercent: number | undefined;\n\t\tif (this.autoCompactEnabled && contextWindow > 0) {\n\t\t\tconst reserveTokens = this.session.settingsManager.getCompactionSettings().reserveTokens;\n\t\t\tconst effective = contextWindow - reserveTokens;\n\t\t\tif (effective > 0) thresholdPercent = (effective / contextWindow) * 100;\n\t\t}\n\t\tconst errorLevel = thresholdPercent !== undefined ? thresholdPercent - 3 : 90;\n\t\tconst warnLevel = thresholdPercent !== undefined ? thresholdPercent - 10 : 70;\n\t\tconst autoIndicator =\n\t\t\tthresholdPercent !== undefined\n\t\t\t\t? ` auto@${thresholdPercent.toFixed(0)}%`\n\t\t\t\t: this.autoCompactEnabled\n\t\t\t\t\t? \" auto\"\n\t\t\t\t\t: \"\";\n\n\t\tconst gauge = contextGauge(contextPercentValue, errorLevel, warnLevel);\n\t\tconst pctText = contextPercent === \"?\" ? \"?\" : `${contextPercent}%`;\n\t\tconst pctColor =\n\t\t\tcontextPercentValue >= errorLevel ? \"error\" : contextPercentValue >= warnLevel ? \"warning\" : \"muted\";\n\t\tconst winText = `${formatTokens(contextWindow)}${autoIndicator}`;\n\n\t\tconst segs: Array<{ plain: string; styled: string }> = [\n\t\t\t{\n\t\t\t\tplain: `${gauge.plain} ${pctText} ${winText}`,\n\t\t\t\tstyled: `${gauge.styled} ${theme.fg(pctColor, pctText)} ${theme.fg(\"dim\", winText)}`,\n\t\t\t},\n\t\t];\n\t\tconst arrow = (a: string, n: number) => ({\n\t\t\tplain: `${a}${formatTokens(n)}`,\n\t\t\tstyled: theme.fg(\"dim\", a) + theme.fg(\"muted\", formatTokens(n)),\n\t\t});\n\t\tif (totalInput) segs.push(arrow(\"↑\", totalInput));\n\t\tif (totalOutput) segs.push(arrow(\"↓\", totalOutput));\n\t\tif (totalCacheRead) segs.push(arrow(\"R\", totalCacheRead));\n\t\tif (totalCacheWrite) segs.push(arrow(\"W\", totalCacheWrite));\n\t\tconst usingSubscription = state.model ? this.session.modelRegistry.isUsingOAuth(state.model) : false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tsegs.push({ plain: costStr, styled: theme.fg(\"muted\", costStr) });\n\t\t}\n\t\tconst l2Plain = segs.map((s) => s.plain).join(\" \");\n\t\tconst l2Styled = segs.map((s) => s.styled).join(\" \");\n\n\t\t// Right: model, thinking level, and provider (when several are configured).\n\t\tconst modelName = state.model?.id || \"no-model\";\n\t\tlet r2Plain = modelName;\n\t\tlet r2Styled = theme.fg(\"muted\", modelName);\n\t\tif (state.model?.reasoning) {\n\t\t\tconst tl = state.thinkingLevel || \"off\";\n\t\t\tconst tstr = tl === \"off\" ? \"thinking off\" : tl;\n\t\t\tr2Plain += ` • ${tstr}`;\n\t\t\tr2Styled += theme.fg(\"dim\", ` • ${tstr}`);\n\t\t}\n\t\tif (this.footerData.getAvailableProviderCount() > 1 && state.model) {\n\t\t\t// Prepend the provider only when the whole right cluster still fits.\n\t\t\tconst withProv = `(${state.model.provider}) ${r2Plain}`;\n\t\t\tif (visibleWidth(l2Plain) + 2 + visibleWidth(withProv) <= width) {\n\t\t\t\tr2Plain = withProv;\n\t\t\t\tr2Styled = theme.fg(\"dim\", `(${state.model.provider}) `) + r2Styled;\n\t\t\t}\n\t\t}\n\t\tconst line2 = assembleLine(width, l2Plain, l2Styled, r2Plain, r2Styled);\n\n\t\tconst lines = [line1, line2];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\t// Truncate to terminal width with dim ellipsis for consistency with footer style\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\t// Transient startup progress (first-run tool downloads, index build): one\n\t\t// determinate bar per entry, cleared as each settles. Width-clamped like the\n\t\t// status line so the footer never overflows.\n\t\tfor (const entry of startupProgress.list()) {\n\t\t\tlines.push(truncateToWidth(renderStartupLine(entry), width, theme.fg(\"dim\", \"…\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"footer.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/footer.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, truncateToWidth, visibleWidth } from \"@kolisachint/hoocode-tui\";\nimport type { AgentSession } from \"../../../core/agent-session.js\";\nimport { sumAssistantUsage } from \"../../../core/agent-session-stats.js\";\nimport { BRAND_MARK, GIT_BRANCH_GLYPH } from \"../../../core/brand.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../../core/footer-data-provider.js\";\nimport { formatTokens } from \"../../../core/format-tokens.js\";\nimport { type StartupProgress, startupProgress } from \"../../../core/startup-progress.js\";\nimport { taskStore } from \"../../../core/task-store.js\";\nimport { DEFAULT_TOOL_OUTPUT_VIEW, type ToolOutputView } from \"../../../core/tool-output-view.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { renderDownloadProgress, renderProgressBar } from \"./progress-bar.js\";\nimport { sessionChipFits } from \"./session-chip.js\";\n\n/**\n * Assemble one footer line: `left` flush left, `right` flush right when it fits\n * (≥2 cols between), padded to the full width. When it doesn't fit, drop `right`\n * and pad; when even `left` overflows, truncate it. Width math runs on the plain\n * strings; the styled strings carry the colour. Every returned line is exactly\n * `width` cells or fewer — the invariant the footer-width tests hold us to.\n */\nfunction assembleLine(width: number, leftPlain: string, leftStyled: string, rightPlain = \"\", rightStyled = \"\"): string {\n\tconst lw = visibleWidth(leftPlain);\n\tif (rightPlain && lw + 2 + visibleWidth(rightPlain) <= width) {\n\t\treturn leftStyled + \" \".repeat(width - lw - visibleWidth(rightPlain)) + rightStyled;\n\t}\n\tif (lw <= width) return leftStyled + \" \".repeat(width - lw);\n\treturn truncateToWidth(leftStyled, width, theme.fg(\"dim\", \"…\"));\n}\n\n/** A compact context-fill gauge, coloured by proximity to the auto-compact trip point. */\nfunction contextGauge(percent: number, errorLevel: number, warnLevel: number): { plain: string; styled: string } {\n\tconst CELLS = 8;\n\tconst filled = Math.max(0, Math.min(CELLS, Math.round((percent / 100) * CELLS)));\n\tconst fill = \"▰\".repeat(filled);\n\tconst track = \"▱\".repeat(CELLS - filled);\n\tconst color = percent >= errorLevel ? \"error\" : percent >= warnLevel ? \"warning\" : \"accent\";\n\t// The unfilled track takes `halftone`, which falls back to `dim` — the tone it\n\t// used before the token existed. The point of separating them is that `dim` is\n\t// body-weight text: a track drawn in it reads as writing rather than as the\n\t// space the fill has yet to reach.\n\treturn { plain: fill + track, styled: theme.fg(color, fill) + theme.fg(\"halftone\", track) };\n}\n\n/**\n * The view dial's glyph, filling up as the view widens — so the footer shows\n * where the dial sits on its three-stop scale, not just its name.\n */\nconst TOOL_OUTPUT_VIEW_GLYPHS: Record<ToolOutputView, string> = {\n\tradar: \"◌\",\n\tpeek: \"◍\",\n\tfull: \"◉\",\n};\n\n/** Count subagent runs currently in flight, for the footer's live delegation cue. */\nfunction activeSubagentCount(): number {\n\treturn taskStore.list().filter((t) => t.source === \"subagent\" && t.status === \"in_progress\").length;\n}\n\n/**\n * Sanitize text for display in a single-line status.\n * Removes newlines, tabs, carriage returns, and other control characters.\n */\nfunction sanitizeStatusText(text: string): string {\n\t// Replace newlines, tabs, carriage returns with space, then collapse multiple spaces\n\treturn text\n\t\t.replace(/[\\r\\n\\t]/g, \" \")\n\t\t.replace(/ +/g, \" \")\n\t\t.trim();\n}\n\n/**\n * One footer line for a transient progress entry (tool download, index build,\n * `/learn` reading transcripts). The bar comes from the shared progress-bar\n * component, so this line and the voice panel's cannot drift apart again. An\n * error entry renders as a dim message instead. Returns a styled string; the\n * caller width-clamps it.\n */\nfunction renderStartupLine(entry: StartupProgress): string {\n\tif (entry.kind === \"error\") {\n\t\treturn theme.fg(\"dim\", `${entry.label}: ${entry.message}`);\n\t}\n\tconst label = theme.fg(\"text\", entry.label);\n\tif (entry.kind === \"download\") {\n\t\treturn `${label} ${renderDownloadProgress(entry.receivedBytes, entry.totalBytes)}`;\n\t}\n\tconst ratio = entry.total > 0 ? entry.done / entry.total : 0;\n\treturn `${label} ${renderProgressBar(ratio, `${entry.done}/${entry.total} ${entry.unit}`)}`;\n}\n\n/**\n * Footer component that shows pwd, token stats, and context usage.\n * Computes token/context stats from session, gets git branch and extension statuses from provider.\n */\nexport class FooterComponent implements Component {\n\tprivate autoCompactEnabled = true;\n\tprivate toolOutputView: ToolOutputView = DEFAULT_TOOL_OUTPUT_VIEW;\n\tprivate sessionChipShown = false;\n\n\tconstructor(\n\t\tprivate session: AgentSession,\n\t\tprivate footerData: ReadonlyFooterDataProvider,\n\t) {}\n\n\tsetSession(session: AgentSession): void {\n\t\tthis.session = session;\n\t}\n\n\tsetAutoCompactEnabled(enabled: boolean): void {\n\t\tthis.autoCompactEnabled = enabled;\n\t}\n\n\t/** The view dial's current stop, shown so `alt+o` has somewhere to land. */\n\tsetToolOutputView(view: ToolOutputView): void {\n\t\tthis.toolOutputView = view;\n\t}\n\n\t/**\n\t * Whether the input box is carrying a session chip. When it is, line 1 drops\n\t * its own copy of the name: saying it twice, six rows apart, teaches the eye\n\t * to ignore both, and line 1 is the line that runs out of width first.\n\t */\n\tsetSessionChipShown(shown: boolean): void {\n\t\tthis.sessionChipShown = shown;\n\t}\n\n\t/**\n\t * No-op: git branch caching now handled by provider.\n\t * Kept for compatibility with existing call sites in interactive-mode.\n\t */\n\tinvalidate(): void {\n\t\t// No-op: git branch is cached/invalidated by provider\n\t}\n\n\t/**\n\t * Clean up resources.\n\t * Git watcher cleanup now handled by provider.\n\t */\n\tdispose(): void {\n\t\t// Git watcher cleanup handled by provider\n\t}\n\n\trender(width: number): string[] {\n\t\tconst state = this.session.state;\n\n\t\t// Cumulative usage across ALL session entries (not just post-compaction\n\t\t// messages). Shares sumAssistantUsage with the per-request cost line the\n\t\t// transcript prints at agent_end, so the footer total and that line are always\n\t\t// derived from the same accounting.\n\t\tconst {\n\t\t\tinput: totalInput,\n\t\t\toutput: totalOutput,\n\t\t\tcacheRead: totalCacheRead,\n\t\t\tcacheWrite: totalCacheWrite,\n\t\t\tcost: totalCost,\n\t\t} = sumAssistantUsage(this.session.sessionManager.getEntries());\n\n\t\t// Calculate context usage from session (handles compaction correctly).\n\t\t// After compaction, tokens are unknown until the next LLM response.\n\t\tconst contextUsage = this.session.getContextUsage();\n\t\tconst contextWindow = contextUsage?.contextWindow ?? state.model?.contextWindow ?? 0;\n\t\tconst contextPercentValue = contextUsage?.percent ?? 0;\n\t\tconst contextPercent = contextUsage?.percent !== null ? contextPercentValue.toFixed(1) : \"?\";\n\n\t\t// Replace home directory with ~\n\t\tlet pwd = this.session.sessionManager.getCwd();\n\t\tconst home = process.env.HOME || process.env.USERPROFILE;\n\t\tif (home && pwd.startsWith(home)) {\n\t\t\tpwd = `~${pwd.slice(home.length)}`;\n\t\t}\n\t\tconst branch = this.footerData.getGitBranch();\n\t\t// The name is shown here only when the chip is not carrying it — either no\n\t\t// chip is set, or the terminal is too narrow for one, in which case the\n\t\t// footer is the only place left that says which session this is.\n\t\tconst sessionName =\n\t\t\tthis.sessionChipShown && sessionChipFits(width) ? undefined : this.session.sessionManager.getDisplayName();\n\t\tconst modeLabel = this.footerData.getActiveMode();\n\n\t\t// ── Line 1 — identity & location ────────────────────────────────────────\n\t\t// Lead with the brand mark + MODE (the agent's guardrail: Ask/Plan/Build/\n\t\t// Debug) in bold accent so it is the first thing the eye lands on, then the\n\t\t// path, git branch, and session name in descending emphasis. The live\n\t\t// subagent count sits flush right — present only while work is delegated.\n\t\tconst modeUp = modeLabel.toUpperCase();\n\t\t// Themes that define the brandBg/brandText pair paint the mark as a filled\n\t\t// chip; the padding lives in the plain string too so width math and\n\t\t// truncation stay honest. Themes without the pair keep accent-coloured text.\n\t\tconst chip = theme.hasBg(\"brandBg\") && theme.has(\"brandText\");\n\t\tconst brand = chip ? ` ${BRAND_MARK} ${modeUp} ` : `${BRAND_MARK} ${modeUp}`;\n\t\tlet l1Plain = `${brand} ${pwd}`;\n\t\tconst brandStyled = chip\n\t\t\t? theme.bg(\"brandBg\", theme.bold(theme.fg(\"brandText\", brand)))\n\t\t\t: theme.bold(theme.fg(\"accent\", brand));\n\t\tlet l1Styled = `${brandStyled} ${theme.fg(\"muted\", pwd)}`;\n\t\tif (branch) {\n\t\t\tl1Plain += ` ${GIT_BRANCH_GLYPH} ${branch}`;\n\t\t\tl1Styled += ` ${theme.fg(\"dim\", GIT_BRANCH_GLYPH)} ${theme.fg(\"muted\", branch)}`;\n\t\t}\n\t\tif (sessionName) {\n\t\t\tl1Plain += ` • ${sessionName}`;\n\t\t\tl1Styled += theme.fg(\"dim\", ` • ${sessionName}`);\n\t\t}\n\t\tconst nSub = activeSubagentCount();\n\t\t// Right cluster: the view dial always, the live subagent count when there\n\t\t// is one. The dial's glyph fills up as the view widens, so its position on\n\t\t// the three-stop scale reads without parsing the word.\n\t\tconst viewGlyph = TOOL_OUTPUT_VIEW_GLYPHS[this.toolOutputView];\n\t\tconst rightParts: Array<{ plain: string; styled: string }> = [];\n\t\tif (nSub > 0) {\n\t\t\trightParts.push({\n\t\t\t\tplain: `◇${nSub} running`,\n\t\t\t\tstyled: theme.fg(\"accent\", `◇${nSub}`) + theme.fg(\"dim\", \" running\"),\n\t\t\t});\n\t\t}\n\t\trightParts.push({\n\t\t\tplain: `${viewGlyph} ${this.toolOutputView}`,\n\t\t\tstyled: theme.fg(\"dim\", `${viewGlyph} ${this.toolOutputView}`),\n\t\t});\n\t\tconst l1RightPlain = rightParts.map((p) => p.plain).join(\" \");\n\t\tconst l1RightStyled = rightParts.map((p) => p.styled).join(\" \");\n\t\tconst line1 = assembleLine(width, l1Plain, l1Styled, l1RightPlain, l1RightStyled);\n\n\t\t// ── Line 2 — session vitals ─────────────────────────────────────────────\n\t\t// A context-fill gauge (coloured by proximity to the auto-compact trip\n\t\t// point) leads, then token/cost deltas, with the model + thinking level\n\t\t// flush right. Numbers read in muted, labels/arrows in dim — a legible\n\t\t// hierarchy in place of the old uniform grey.\n\t\tlet thresholdPercent: number | undefined;\n\t\tif (this.autoCompactEnabled && contextWindow > 0) {\n\t\t\tconst reserveTokens = this.session.settingsManager.getCompactionSettings().reserveTokens;\n\t\t\tconst effective = contextWindow - reserveTokens;\n\t\t\tif (effective > 0) thresholdPercent = (effective / contextWindow) * 100;\n\t\t}\n\t\tconst errorLevel = thresholdPercent !== undefined ? thresholdPercent - 3 : 90;\n\t\tconst warnLevel = thresholdPercent !== undefined ? thresholdPercent - 10 : 70;\n\t\tconst autoIndicator =\n\t\t\tthresholdPercent !== undefined\n\t\t\t\t? ` auto@${thresholdPercent.toFixed(0)}%`\n\t\t\t\t: this.autoCompactEnabled\n\t\t\t\t\t? \" auto\"\n\t\t\t\t\t: \"\";\n\n\t\tconst gauge = contextGauge(contextPercentValue, errorLevel, warnLevel);\n\t\tconst pctText = contextPercent === \"?\" ? \"?\" : `${contextPercent}%`;\n\t\tconst pctColor =\n\t\t\tcontextPercentValue >= errorLevel ? \"error\" : contextPercentValue >= warnLevel ? \"warning\" : \"muted\";\n\t\tconst winText = `${formatTokens(contextWindow)}${autoIndicator}`;\n\n\t\tconst segs: Array<{ plain: string; styled: string }> = [\n\t\t\t{\n\t\t\t\tplain: `${gauge.plain} ${pctText} ${winText}`,\n\t\t\t\tstyled: `${gauge.styled} ${theme.fg(pctColor, pctText)} ${theme.fg(\"dim\", winText)}`,\n\t\t\t},\n\t\t];\n\t\tconst arrow = (a: string, n: number) => ({\n\t\t\tplain: `${a}${formatTokens(n)}`,\n\t\t\tstyled: theme.fg(\"dim\", a) + theme.fg(\"muted\", formatTokens(n)),\n\t\t});\n\t\tif (totalInput) segs.push(arrow(\"↑\", totalInput));\n\t\tif (totalOutput) segs.push(arrow(\"↓\", totalOutput));\n\t\tif (totalCacheRead) segs.push(arrow(\"R\", totalCacheRead));\n\t\tif (totalCacheWrite) segs.push(arrow(\"W\", totalCacheWrite));\n\t\tconst usingSubscription = state.model ? this.session.modelRegistry.isUsingOAuth(state.model) : false;\n\t\tif (totalCost || usingSubscription) {\n\t\t\tconst costStr = `$${totalCost.toFixed(3)}${usingSubscription ? \" (sub)\" : \"\"}`;\n\t\t\tsegs.push({ plain: costStr, styled: theme.fg(\"muted\", costStr) });\n\t\t}\n\t\tconst l2Plain = segs.map((s) => s.plain).join(\" \");\n\t\tconst l2Styled = segs.map((s) => s.styled).join(\" \");\n\n\t\t// Right: model, thinking level, and provider (when several are configured).\n\t\tconst modelName = state.model?.id || \"no-model\";\n\t\tlet r2Plain = modelName;\n\t\tlet r2Styled = theme.fg(\"muted\", modelName);\n\t\tif (state.model?.reasoning) {\n\t\t\tconst tl = state.thinkingLevel || \"off\";\n\t\t\tconst tstr = tl === \"off\" ? \"thinking off\" : tl;\n\t\t\tr2Plain += ` • ${tstr}`;\n\t\t\tr2Styled += theme.fg(\"dim\", ` • ${tstr}`);\n\t\t}\n\t\tif (this.footerData.getAvailableProviderCount() > 1 && state.model) {\n\t\t\t// Prepend the provider only when the whole right cluster still fits.\n\t\t\tconst withProv = `(${state.model.provider}) ${r2Plain}`;\n\t\t\tif (visibleWidth(l2Plain) + 2 + visibleWidth(withProv) <= width) {\n\t\t\t\tr2Plain = withProv;\n\t\t\t\tr2Styled = theme.fg(\"dim\", `(${state.model.provider}) `) + r2Styled;\n\t\t\t}\n\t\t}\n\t\tconst line2 = assembleLine(width, l2Plain, l2Styled, r2Plain, r2Styled);\n\n\t\tconst lines = [line1, line2];\n\n\t\t// Add extension statuses on a single line, sorted by key alphabetically\n\t\tconst extensionStatuses = this.footerData.getExtensionStatuses();\n\t\tif (extensionStatuses.size > 0) {\n\t\t\tconst sortedStatuses = Array.from(extensionStatuses.entries())\n\t\t\t\t.sort(([a], [b]) => a.localeCompare(b))\n\t\t\t\t.map(([, text]) => sanitizeStatusText(text));\n\t\t\tconst statusLine = sortedStatuses.join(\" \");\n\t\t\t// Truncate to terminal width with dim ellipsis for consistency with footer style\n\t\t\tlines.push(truncateToWidth(statusLine, width, theme.fg(\"dim\", \"...\")));\n\t\t}\n\n\t\t// Transient startup progress (first-run tool downloads, index build): one\n\t\t// determinate bar per entry, cleared as each settles. Width-clamped like the\n\t\t// status line so the footer never overflows.\n\t\tfor (const entry of startupProgress.list()) {\n\t\t\tlines.push(truncateToWidth(renderStartupLine(entry), width, theme.fg(\"dim\", \"…\")));\n\t\t}\n\n\t\treturn lines;\n\t}\n}\n"]}