Explored project structure and packages.
UnderstandSummarized main packages and functionalities.
Understandi need you to do 10-15 turns of read-only stuff
The user wants me to do 10-15 turns of read-only operations. This means I should explore the codebase, read files, run non-destructive commands like ls, find, rg, etc. without making any changes.
Let me start by exploring the project structure.
Sure, I'll explore the codebase with read-only operations. Let me start by looking at the project structure.
>ls -latotal 704
drwxr-xr-x@ 26 badlogic staff 832 Jan 26 11:43 .
drwxr-xr-x 101 badlogic staff 3232 Jan 25 23:32 ..
drwx------@ 3 badlogic staff 96 Dec 22 12:39 .claude
drwxr-xr-x@ 2 badlogic staff 64 Jan 23 00:47 .claude-trace
drwxr-xr-x@ 17 badlogic staff 544 Jan 26 16:32 .git
drwxr-xr-x@ 5 badlogic staff 160 Jan 25 18:59 .github
-rw-r--r--@ 1 badlogic staff 404 Jan 25 03:33 .gitignore
drwxr-xr-x@ 4 badlogic staff 128 Dec 3 14:52 .husky
drwxr-xr-x@ 8 badlogic staff 256 Jan 26 15:20 .pi
drwxr-xr-x@ 3 badlogic staff 96 Jan 20 23:11 .vscode
-rw-r--r--@ 1 badlogic staff 8830 Jan 26 11:43 AGENTS.md
-rw-r--r--@ 1 badlogic staff 895 Jan 13 22:45 biome.json
-rw-r--r--@ 1 badlogic staff 1677 Jan 18 19:37 CONTRIBUTING.md
-rw-r--r--@ 1 badlogic staff 1069 Aug 9 15:06 LICENSE
drwxr-xr-x@ 338 badlogic staff 10816 Jan 25 19:05 node_modules
-rw-r--r--@ 1 badlogic staff 297229 Jan 25 19:27 package-lock.json
-rw-r--r--@ 1 badlogic staff 2707 Jan 25 03:33 package.json
drwxr-xr-x@ 9 badlogic staff 288 Jan 13 04:43 packages
-rw-r--r--@ 1 badlogic staff 115 Jan 20 23:34 pi-mono.code-workspace
-rwxr-xr-x@ 1 badlogic staff 1400 Jan 25 23:47 pi-test.sh
-rw-r--r--@ 1 badlogic staff 2201 Jan 18 19:37 README.md
drwxr-xr-x@ 7 badlogic staff 224 Jan 18 19:37 scripts
-rwxr-xr-x@ 1 badlogic staff 1440 Jan 25 03:33 test.sh
-rw-r--r--@ 1 badlogic staff 1449 Jan 24 03:16 todo.md
-rw-r--r--@ 1 badlogic staff 553 Dec 3 13:44 tsconfig.base.json
-rw-r--r--@ 1 badlogic staff 1483 Jan 2 01:52 tsconfig.json>find packages -maxdepth 1 -type d | sortpackages
packages/agent
packages/ai
packages/coding-agent
packages/mom
packages/pods
packages/tui
packages/web-uiGood, I can see the monorepo structure with several packages. Let me continue exploring.
Good overview. Let me look at the coding-agent package since that's the main product.
That's a comprehensive README for the coding agent. Let me continue exploring other parts of the codebase.
>ls -la packages/ai/src/total 640
drwxr-xr-x@ 12 badlogic staff 384 Jan 25 19:27 .
drwxr-xr-x@ 12 badlogic staff 384 Jan 25 18:59 ..
-rw-r--r--@ 1 badlogic staff 2563 Jan 25 03:33 api-registry.ts
-rw-r--r--@ 1 badlogic staff 3864 Jan 25 03:33 cli.ts
-rw-r--r--@ 1 badlogic staff 4044 Jan 25 03:33 env-api-keys.ts
-rw-r--r--@ 1 badlogic staff 778 Jan 25 03:33 index.ts
-rw-r--r--@ 1 badlogic staff 287093 Jan 25 19:27 models.generated.ts
-rw-r--r--@ 1 badlogic staff 2725 Jan 14 22:22 models.ts
drwxr-xr-x@ 16 badlogic staff 512 Jan 25 18:59 providers
-rw-r--r--@ 1 badlogic staff 1814 Jan 25 18:59 stream.ts
-rw-r--r--@ 1 badlogic staff 8704 Jan 25 03:34 types.ts
drwxr-xr-x@ 9 badlogic staff 288 Jan 25 03:33 utils>wc -l packages/*/src/**/*.ts 2>/dev/null | tail -20212 packages/web-ui/src/dialogs/ProvidersModelsTab.ts
150 packages/web-ui/src/dialogs/SessionListDialog.ts
214 packages/web-ui/src/dialogs/SettingsDialog.ts
282 packages/web-ui/src/prompts/prompts.ts
60 packages/web-ui/src/storage/app-storage.ts
33 packages/web-ui/src/storage/store.ts
206 packages/web-ui/src/storage/types.ts
275 packages/web-ui/src/tools/extract-document.ts
46 packages/web-ui/src/tools/index.ts
293 packages/web-ui/src/tools/javascript-repl.ts
130 packages/web-ui/src/tools/renderer-registry.ts
15 packages/web-ui/src/tools/types.ts
472 packages/web-ui/src/utils/attachment-utils.ts
22 packages/web-ui/src/utils/auth-token.ts
42 packages/web-ui/src/utils/format.ts
653 packages/web-ui/src/utils/i18n.ts
277 packages/web-ui/src/utils/model-discovery.ts
134 packages/web-ui/src/utils/proxy-utils.ts
2357 packages/web-ui/src/utils/test-sessions.ts
34428 totalInteresting. Let me look at the providers directory since that's likely where a lot of the LLM integration happens.
>ls -la packages/ai/src/providers/total 448
drwxr-xr-x@ 16 badlogic staff 512 Jan 25 18:59 .
drwxr-xr-x@ 12 badlogic staff 384 Jan 25 19:27 ..
-rw-r--r--@ 1 badlogic staff 20633 Jan 25 18:59 amazon-bedrock.ts
-rw-r--r--@ 1 badlogic staff 20597 Jan 25 03:33 anthropic.ts
-rw-r--r--@ 1 badlogic staff 7863 Jan 26 15:25 azure-openai-responses.ts
-rw-r--r--@ 1 badlogic staff 34829 Jan 25 03:33 google-gemini-cli.ts
-rw-r--r--@ 1 badlogic staff 11289 Jan 19 00:18 google-shared.ts
-rw-r--r--@ 1 badlogic staff 13567 Jan 25 03:33 google-vertex.ts
-rw-r--r--@ 1 badlogic staff 12911 Jan 26 15:25 google.ts
-rw-r--r--@ 1 badlogic staff 14818 Jan 25 03:33 openai-codex-responses.ts
-rw-r--r--@ 1 badlogic staff 27280 Jan 26 15:25 openai-completions.ts
-rw-r--r--@ 1 badlogic staff 16533 Jan 25 03:33 openai-responses-shared.ts
-rw-r--r--@ 1 badlogic staff 7380 Jan 26 15:25 openai-responses.ts
-rw-r--r--@ 1 badlogic staff 2262 Jan 25 03:33 register-builtins.ts
-rw-r--r--@ 1 badlogic staff 1392 Jan 25 03:33 simple-options.ts
-rw-r--r--@ 1 badlogic staff 5463 Jan 19 15:55 transform-messages.tsGood variety of providers. Let me look at the TUI package now, since that's the terminal UI library.
>ls -la packages/tui/src/total 344
drwxr-xr-x@ 14 badlogic staff 448 Jan 26 11:43 .
drwxr-xr-x@ 11 badlogic staff 352 Jan 26 11:43 ..
-rw-r--r--@ 1 badlogic staff 17924 Jan 25 03:33 autocomplete.ts
drwxr-xr-x@ 14 badlogic staff 448 Jan 25 18:59 components
-rw-r--r--@ 1 badlogic staff 2381 Jan 25 03:33 editor-component.ts
-rw-r--r--@ 1 badlogic staff 3196 Jan 25 03:33 fuzzy.ts
-rw-r--r--@ 1 badlogic staff 2729 Jan 25 03:33 index.ts
-rw-r--r--@ 1 badlogic staff 4074 Jan 25 20:08 keybindings.ts
-rw-r--r--@ 1 badlogic staff 33379 Jan 19 00:19 keys.ts
-rw-r--r--@ 1 badlogic staff 9652 Jan 8 23:49 stdin-buffer.ts
-rw-r--r--@ 1 badlogic staff 9841 Jan 25 03:33 terminal-image.ts
-rw-r--r--@ 1 badlogic staff 7006 Jan 26 15:53 terminal.ts
-rw-r--r--@ 1 badlogic staff 37027 Jan 26 16:34 tui.ts
-rw-r--r--@ 1 badlogic staff 24675 Jan 16 12:47 utils.ts>rg "export (function|class|interface|type)" packages/tui/src/*.ts --no-heading | head -50packages/tui/src/terminal-image.ts:export type ImageProtocol = "kitty" | "iterm2" | null;
packages/tui/src/terminal-image.ts:export interface TerminalCapabilities {
packages/tui/src/terminal-image.ts:export interface CellDimensions {
packages/tui/src/terminal-image.ts:export interface ImageDimensions {
packages/tui/src/terminal-image.ts:export interface ImageRenderOptions {
packages/tui/src/terminal-image.ts:export function getCellDimensions(): CellDimensions {
packages/tui/src/terminal-image.ts:export function setCellDimensions(dims: CellDimensions): void {
packages/tui/src/terminal-image.ts:export function detectCapabilities(): TerminalCapabilities {
packages/tui/src/terminal-image.ts:export function getCapabilities(): TerminalCapabilities {
packages/tui/src/terminal-image.ts:export function resetCapabilitiesCache(): void {
packages/tui/src/terminal-image.ts:export function allocateImageId(): number {
packages/tui/src/terminal-image.ts:export function encodeKitty(
packages/tui/src/terminal-image.ts:export function deleteKittyImage(imageId: number): string {
packages/tui/src/terminal-image.ts:export function deleteAllKittyImages(): string {
packages/tui/src/terminal-image.ts:export function encodeITerm2(
packages/tui/src/terminal-image.ts:export function calculateImageRows(
packages/tui/src/terminal-image.ts:export function getPngDimensions(base64Data: string): ImageDimensions | null {
packages/tui/src/terminal-image.ts:export function getJpegDimensions(base64Data: string): ImageDimensions | null {
packages/tui/src/terminal-image.ts:export function getGifDimensions(base64Data: string): ImageDimensions | null {
packages/tui/src/terminal-image.ts:export function getWebpDimensions(base64Data: string): ImageDimensions | null {
packages/tui/src/terminal-image.ts:export function getImageDimensions(base64Data: string, mimeType: string): ImageDimensions | null {
packages/tui/src/terminal-image.ts:export function renderImage(
packages/tui/src/terminal-image.ts:export function imageFallback(mimeType: string, dimensions?: ImageDimensions, filename?: string): string {
packages/tui/src/tui.ts:export interface Component {
packages/tui/src/tui.ts:export interface Focusable {
packages/tui/src/tui.ts:export function isFocusable(component: Component | null): component is Component & Focusable {
packages/tui/src/tui.ts:export type OverlayAnchor =
packages/tui/src/tui.ts:export interface OverlayMargin {
packages/tui/src/tui.ts:export type SizeValue = number | `${number}%`;
packages/tui/src/tui.ts:export interface OverlayOptions {
packages/tui/src/tui.ts:export interface OverlayHandle {
packages/tui/src/tui.ts:export class Container implements Component {
packages/tui/src/tui.ts:export class TUI extends Container {
packages/tui/src/autocomplete.ts:export interface AutocompleteItem {
packages/tui/src/autocomplete.ts:export interface SlashCommand {
packages/tui/src/autocomplete.ts:export interface AutocompleteProvider {
packages/tui/src/autocomplete.ts:export class CombinedAutocompleteProvider implements AutocompleteProvider {
packages/tui/src/stdin-buffer.ts:export type StdinBufferOptions = {
packages/tui/src/stdin-buffer.ts:export type StdinBufferEventMap = {
packages/tui/src/stdin-buffer.ts:export class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
packages/tui/src/terminal.ts:export interface Terminal {
packages/tui/src/terminal.ts:export class ProcessTerminal implements Terminal {
packages/tui/src/fuzzy.ts:export interface FuzzyMatch {
packages/tui/src/fuzzy.ts:export function fuzzyMatch(query: string, text: string): FuzzyMatch {
packages/tui/src/fuzzy.ts:export function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[] {
packages/tui/src/index.ts:export type { EditorComponent } from "./editor-component.js";
packages/tui/src/keybindings.ts:export type EditorAction =
packages/tui/src/keybindings.ts:export type { KeyId };
packages/tui/src/keybindings.ts:export type EditorKeybindingsConfig = {
packages/tui/src/keybindings.ts:export class EditorKeybindingsManager {Good overview of the TUI library. Let me look at some recent git activity and the changelog.
>git log --oneline -20fa8b26a1 docs: update changelog guidance and links
9b903656 fix(ai): correct provider error message typo (closes #958)
585ce73b fix(coding-agent): align auto-discovery with loader rules
b270e7b5 fix(coding-agent): apply config overrides to auto-discovery
ea93e2f3 fix(coding-agent): add force exclude pattern and fix config toggle persistence
7a0b4359 docs(coding-agent): add security warnings for third-party packages
a8d04a1d docs(coding-agent): add comprehensive cross-links in extensions.md
c3b86854 docs(coding-agent): link to session.md for message types in context event
b078141c docs(coding-agent): add cross-links to themes.md and session.md
530826ba docs(coding-agent): link to tool-execution.ts in Custom Rendering section
d726c81f docs(coding-agent): remove duplicate packages content from extensions.md
93020713 docs(coding-agent): improve extensions.md, add missing examples
c565fa9a fix(tui): keep overlays centered across resizes (#950)
b1b0fd82 docs: add blurb about not hardcoding keybindings (#955)
bf876fcd Revert "docs(coding-agent): restructure extensions.md, consolidate examples"
b85bf054 docs(coding-agent): restructure extensions.md, consolidate examples
efc598b6 docs(coding-agent): replace README.md with new structure
53408629 docs(coding-agent): update README-NEW.md, tui.md, add new docs
28ab25b0 docs(coding-agent): improve README structure and update session/compaction docs
859a4e05 docs(coding-agent): rename Header to Startup headerGood, I can see the changelog. Let me look at some more code areas now.
>rg -l "ExtensionAPI" packages/coding-agent/src/ | head -10packages/coding-agent/src/index.ts
packages/coding-agent/src/core/sdk.ts
packages/coding-agent/src/core/index.ts
packages/coding-agent/src/core/extensions/index.ts
packages/coding-agent/src/core/extensions/loader.ts
packages/coding-agent/src/core/extensions/types.ts>ls -la packages/coding-agent/examples/total 8
drwxr-xr-x@ 5 badlogic staff 160 Jan 25 03:33 .
drwxr-xr-x@ 18 badlogic staff 576 Jan 26 02:33 ..
drwxr-xr-x@ 57 badlogic staff 1824 Jan 26 11:43 extensions
-rw-r--r--@ 1 badlogic staff 906 Jan 25 03:33 README.md
drwxr-xr-x@ 15 badlogic staff 480 Jan 25 03:33 sdkLet me see what extensions exist as examples.
>ls -la packages/coding-agent/examples/extensions/total 632
drwxr-xr-x@ 57 badlogic staff 1824 Jan 26 11:43 .
drwxr-xr-x@ 5 badlogic staff 160 Jan 25 03:33 ..
-rw-r--r--@ 1 badlogic staff 12549 Jan 25 03:33 antigravity-image-gen.ts
-rw-r--r--@ 1 badlogic staff 1569 Jan 8 19:37 auto-commit-on-exit.ts
-rw-r--r--@ 1 badlogic staff 1553 Jan 26 11:43 bookmark.ts
-rw-r--r--@ 1 badlogic staff 2486 Jan 9 23:31 claude-rules.ts
-rw-r--r--@ 1 badlogic staff 1678 Jan 12 23:33 confirm-destructive.ts
-rw-r--r--@ 1 badlogic staff 4069 Jan 8 19:37 custom-compaction.ts
-rw-r--r--@ 1 badlogic staff 2143 Jan 12 23:33 custom-footer.ts
-rw-r--r--@ 1 badlogic staff 2395 Jan 17 11:39 custom-header.ts
drwxr-xr-x@ 7 badlogic staff 224 Jan 25 03:33 custom-provider-anthropic
drwxr-xr-x@ 6 badlogic staff 192 Jan 25 03:33 custom-provider-gitlab-duo
-rw-r--r--@ 1 badlogic staff 1477 Jan 12 23:33 dirty-repo-guard.ts
drwxr-xr-x@ 11 badlogic staff 352 Jan 13 22:08 doom-overlay
-rw-r--r--@ 1 badlogic staff 1346 Jan 26 11:43 event-bus.ts
-rw-r--r--@ 1 badlogic staff 1031 Jan 8 19:37 file-trigger.ts
-rw-r--r--@ 1 badlogic staff 1466 Jan 12 23:33 git-checkpoint.ts
-rw-r--r--@ 1 badlogic staff 4628 Jan 12 23:33 handoff.ts
-rw-r--r--@ 1 badlogic staff 627 Jan 8 19:37 hello.ts
-rw-r--r--@ 1 badlogic staff 2956 Jan 25 03:33 inline-bash.ts
-rw-r--r--@ 1 badlogic staff 1442 Jan 16 02:42 input-transform.ts
-rw-r--r--@ 1 badlogic staff 4778 Jan 9 23:31 interactive-shell.ts
-rw-r--r--@ 1 badlogic staff 1195 Jan 9 23:31 mac-system-theme.ts
-rw-r--r--@ 1 badlogic staff 1906 Jan 26 11:43 message-renderer.ts
-rw-r--r--@ 1 badlogic staff 2413 Jan 16 12:47 modal-editor.ts
-rw-r--r--@ 1 badlogic staff 955 Jan 12 23:33 model-status.ts
-rw-r--r--@ 1 badlogic staff 776 Jan 12 23:33 notify.ts
-rw-r--r--@ 1 badlogic staff 28484 Jan 13 22:47 overlay-qa-tests.ts
-rw-r--r--@ 1 badlogic staff 5367 Jan 16 12:47 overlay-test.ts
-rw-r--r--@ 1 badlogic staff 1017 Jan 8 19:37 permission-gate.ts
-rw-r--r--@ 1 badlogic staff 1459 Jan 9 23:31 pirate.ts
drwxr-xr-x@ 5 badlogic staff 160 Jan 16 00:45 plan-mode
-rw-r--r--@ 1 badlogic staff 13339 Jan 12 23:33 preset.ts
-rw-r--r--@ 1 badlogic staff 806 Jan 8 19:37 protected-paths.ts
-rw-r--r--@ 1 badlogic staff 3554 Jan 8 23:49 qna.ts
-rw-r--r--@ 1 badlogic staff 7764 Jan 19 15:00 question.ts
-rw-r--r--@ 1 badlogic staff 12807 Jan 16 12:47 questionnaire.ts
-rw-r--r--@ 1 badlogic staff 2384 Jan 16 12:47 rainbow-editor.ts
-rw-r--r--@ 1 badlogic staff 8033 Jan 26 11:43 README.md
drwxr-xr-x@ 6 badlogic staff 192 Jan 13 22:01 sandbox
-rw-r--r--@ 1 badlogic staff 2830 Jan 8 19:37 send-user-message.ts
-rw-r--r--@ 1 badlogic staff 783 Jan 26 11:43 session-name.ts
-rw-r--r--@ 1 badlogic staff 2053 Jan 8 23:49 shutdown-command.ts
-rw-r--r--@ 1 badlogic staff 9409 Jan 12 01:32 snake.ts
-rw-r--r--@ 1 badlogic staff 15162 Jan 25 03:33 space-invaders.ts
-rw-r--r--@ 1 badlogic staff 7289 Jan 9 23:31 ssh.ts
-rw-r--r--@ 1 badlogic staff 1137 Jan 8 19:37 status-line.ts
drwxr-xr-x@ 7 badlogic staff 224 Jan 16 00:45 subagent
-rw-r--r--@ 1 badlogic staff 5006 Jan 13 22:01 summarize.ts
-rw-r--r--@ 1 badlogic staff 2236 Jan 8 19:37 timed-confirm.ts
-rw-r--r--@ 1 badlogic staff 8966 Jan 12 23:33 todo.ts
-rw-r--r--@ 1 badlogic staff 4747 Jan 9 23:31 tool-override.ts
-rw-r--r--@ 1 badlogic staff 3872 Jan 12 23:33 tools.ts
-rw-r--r--@ 1 badlogic staff 1025 Jan 17 11:43 trigger-compact.ts
-rw-r--r--@ 1 badlogic staff 6358 Jan 8 19:37 truncated-tool.ts
-rw-r--r--@ 1 badlogic staff 526 Jan 19 15:55 widget-placement.ts
drwxr-xr-x@ 7 badlogic staff 224 Jan 25 03:33 with-depsLots of example extensions! Let me look at one of them and the issues.
>gh issue list --limit 10 --state open959 OPEN Support for text operations (cut copy undo redo) in the text composer 2026-01-26T15:28:55Z
956 OPEN openai: Error: 401 Attempted to access resource with incorrect regional hostname bug 2026-01-26T05:42:51Z
954 OPEN Text before tool calls is overwritten when content exceeds viewport bug 2026-01-26T02:34:17Z
884 OPEN Antigravity: request does not finish when quota runs out bug, pkg:ai 2026-01-25T02:17:13Z
563 OPEN feat(coding-agent): Add MCP extension example pkg:coding-agent 2026-01-12T06:32:10Z
412 OPEN Refactor/rewrite Mom enhancement, pkg:mom 2026-01-13T01:46:53ZLet me look at one of the open bugs and explore more code.
>gh issue view 954 --json title,body,comments,labels,state{"body":"### What happened?\n\n## AUTHORSHIP Notice\n\nI, the human being algal, ran into this issue when using Clawdbot, when I noticed that early sections in AI responses were rendered and then erased in the output. I noticed that this was happening to sections preceding tool calls, in both Ghostty and in iTerm2, and both inside and outside of tmux\n\nI then used Codex-5.2 to analyze the cause of the problem, and to generate a minimal isolated reproduction of the behavior. I ran the repro script and observed (in iTerm2) what does indeed seem like buggy behavior -- namely, that the text available in the scrollback depends on the height of the terminal window at the time you run the script. \n\nSo I personally observed the original bug in clawdbot, and in the repro script included. But the bulk of the analysis, and nearly all of the copy in the following sections, and the repro script itself, was authored by Codex-5.2. I do not comprehend it in detail. (The \"nearly\" is because I restated the repro instructions myself to be very concrete about exactly what I did.) \n\nI know there's a lot of slop contributions going around, so I wanted to be transparent about this in case you feel it's not worth the time to engage with an issue report of this kind. I also would welcome any feedback or instructions on how to engage more helpfully.\n\n## Summary\n\nWhen streaming content that includes a tool call (text → tool → more text), the pre-tool text is overwritten when post-tool text renders. This happens when content exceeds the terminal viewport height.\n\n## Expected behavior\n\n- PRE-TOOL lines remain visible in scrollback above tool output\n- POST-TOOL lines append after tool output without overwriting earlier content\n\n## Actual behavior\n\nWhen content exceeds the viewport and new lines arrive after a tool-call pause, some earlier PRE-TOOL lines near the bottom are overwritten by POST-TOOL lines.\n\n## Environment\n\n- Terminal: Ghostty, iTerm2 (terminal-independent)\n- tmux: With and without (tmux-independent)\n- Intermittent: Depends on viewport fullness and cursor position when tool completes\n\n## Reproduction\n\nThe attached `viewport-overwrite-repro.ts` reproduces this without an LLM.\n\n```bash\n# Run in a small terminal (8-12 rows) for reliable repro\n# From the pi-mono repo root:\nnpx tsx packages/tui/test/viewport-overwrite-repro.ts\n```\n\nOr use tmux for a controlled viewport:\n\n```bash\ntmux new-session -d -s tui-bug -x 80 -y 12\ntmux send-keys -t tui-bug \"cd /path/to/pi-mono && npx tsx packages/tui/test/viewport-overwrite-repro.ts\" Enter\ntmux attach -t tui-bug\n```\n\n**What to look for:** When POST-TOOL lines render, some earlier PRE-TOOL lines near the bottom vanish or appear replaced.\n\n## Root cause\n\n**`hardwareCursorRow` is treated as a content line index, but the terminal cursor can only move within the viewport.**\n\nOnce rendered content exceeds the terminal height, the terminal scrolls and the cursor position is constrained to the visible viewport. `CSI A/B` (cursor up/down) does **not** scroll; it clamps at the top/bottom of the viewport.\n\nThe code in `doRender()` uses `lineDiff = firstChanged - hardwareCursorRow` and emits `CSI B` to move down. When `firstChanged` is below the bottom of the current viewport (common when appending new lines), `CSI B` does not actually move the cursor, so the first newly-rendered line is written on the **current bottom line**, overwriting previous content.\n\n### Why it shows up after tool calls\n\n- Tool calls often add enough lines to fill/overflow the viewport\n- When streaming resumes, the next text chunk is appended as a new line at the bottom — exactly the case that `CSI B` cannot handle without scrolling\n- If tool output temporarily expands then collapses, `maxLinesRendered` stays high and can trigger a full clear on the next update, compounding the effect\n\n### Secondary contributor\n\n`maxLinesRendered` never shrinks (by design). After a tool result is collapsed or truncated, `maxLinesRendered` can be much larger than `newLines.length`. This makes `viewportTop` large and can trigger the `firstChanged < viewportTop` full-render path, which clears scrollback (`ESC[3J`) and makes earlier text disappear.\n\n## Proposed fix direction\n\nTranslate to viewport coordinates and explicitly scroll when the target line is below the viewport:\n\n1. Compute `prevViewportTop` before rendering\n2. When moving to `firstChanged`, map both current cursor and target to **viewport rows**\n3. If target is below viewport, scroll by emitting newlines at the bottom before rendering\n4. Update `positionHardwareCursor()` to use viewport coordinates consistently\n\nPseudocode for the cursor movement fix:\n\n```typescript\nconst prevViewportBottom = prevViewportTop + height - 1;\nlet currentRow = Math.max(0, Math.min(height - 1, this.hardwareCursorRow - prevViewportTop));\n\nif (firstChanged > prevViewportBottom) {\n // Scroll to bring target into view\n const scroll = firstChanged - prevViewportBottom;\n const toBottom = (height - 1) - currentRow;\n if (toBottom > 0) buffer += `\\x1b[${toBottom}B`;\n buffer += \"\\r\\n\".repeat(scroll);\n currentRow = height - 1;\n}\n\nconst targetRow = Math.max(0, Math.min(height - 1, firstChanged - prevViewportTop));\nconst rowDelta = targetRow - currentRow;\nif (rowDelta > 0) buffer += `\\x1b[${rowDelta}B`;\nelse if (rowDelta < 0) buffer += `\\x1b[${-rowDelta}A`;\n```\n\nAn alternative is using absolute cursor positioning (`CUP`) within the viewport instead of relative `CSI A/B`, which avoids drift from incorrect `hardwareCursorRow` tracking.\n\n## Related\n\nIssue #814 (\"TUI flashes and delays write tool output when expanded content exceeds viewport\") was closed as unfixable. That issue mentions the `firstChanged < viewportTop` full-render path. This bug has a different trigger (tool call pause in streaming) but may share underlying causes.\n\n### Steps to reproduce\n\n1. cd to the root of pi-mono\n2. copy this repro script into the path `packages/tui/test/viewport-overwrite-repro.ts`.\n3. resize your terminal window to about 8 rows\n4. run this repro script by running: `npx tsx packages/tui/test/viewport-overwrite-repro.ts`\n5. after it prints \"POST-TOOL LINE\", scroll back and notice you can't see any of the PRE-TOOL LINEs\n6. reproduce the above steps but with a tall window, and notice that now you can see those lines\n\n[viewport-overwrite-repro.ts](https://github.com/user-attachments/files/24851337/viewport-overwrite-repro.ts)\n\n### Expected behavior\n\nI expect the window height not to affect what content is visible on scrollback.\n\n\n\n### Version\n\ncommit 82e3be9dc8422f461e979982bf869096bfe60cf8","comments":[],"labels":[{"id":"LA_kwDOPbFNk88AAAACHWTBxw","name":"bug","description":"Something isn't working","color":"d73a4a"}],"state":"OPEN","title":"Text before tool calls is overwritten when content exceeds viewport"}Interesting bug report. Let me look at some more files in the repo.
>ls -la packages/agent/src/total 104
drwxr-xr-x@ 7 badlogic staff 224 Jan 8 23:49 .
drwxr-xr-x@ 11 badlogic staff 352 Jan 25 03:33 ..
-rw-r--r--@ 1 badlogic staff 11762 Jan 8 19:37 agent-loop.ts
-rw-r--r--@ 1 badlogic staff 12896 Jan 8 23:49 agent.ts
-rw-r--r--@ 1 badlogic staff 177 Jan 2 01:52 index.ts
-rw-r--r--@ 1 badlogic staff 9677 Jan 13 22:08 proxy.ts
-rw-r--r--@ 1 badlogic staff 6504 Jan 8 19:37 types.tsGood overview of the agent package. Let me look at the mom package and the tests directory.
>ls -la packages/mom/total 120
drwxr-xr-x@ 15 badlogic staff 480 Jan 25 03:33 .
drwxr-xr-x@ 9 badlogic staff 288 Jan 13 04:43 ..
-rw-r--r--@ 1 badlogic staff 6 Nov 26 00:28 .gitignore
-rw-r--r--@ 1 badlogic staff 13639 Jan 25 03:33 CHANGELOG.md
drwxr-xr-x@ 6 badlogic staff 192 Dec 16 01:29 data
-rwxr-xr-x@ 1 badlogic staff 877 Jan 25 03:33 dev.sh
drwxr-xr-x@ 39 badlogic staff 1248 Jan 22 01:43 dist
-rwxr-xr-x@ 1 badlogic staff 2859 Jan 25 03:33 docker.sh
drwxr-xr-x@ 8 badlogic staff 256 Dec 20 22:42 docs
drwxr-xr-x@ 4 badlogic staff 128 Jan 22 01:42 node_modules
-rw-r--r--@ 1 badlogic staff 1255 Jan 25 03:33 package.json
-rw-r--r--@ 1 badlogic staff 20655 Dec 30 00:45 README.md
drwxr-xr-x@ 3 badlogic staff 96 Dec 20 18:10 scripts
drwxr-xr-x@ 12 badlogic staff 384 Jan 25 03:33 src
-rw-r--r--@ 1 badlogic staff 209 Nov 26 00:28 tsconfig.build.json>find packages -name "*.test.ts" | head -15packages/coding-agent/test/session-info-modified-timestamp.test.ts
packages/coding-agent/test/agent-session-tree-navigation.test.ts
packages/coding-agent/test/agent-session-concurrent.test.ts
packages/coding-agent/test/agent-session-compaction.test.ts
packages/coding-agent/test/interactive-mode-status.test.ts
packages/coding-agent/test/skills.test.ts
packages/coding-agent/test/model-resolver.test.ts
packages/coding-agent/test/compaction-extensions.test.ts
packages/coding-agent/test/settings-manager.test.ts
packages/coding-agent/test/sdk-skills.test.ts
packages/coding-agent/test/extensions-runner.test.ts
packages/coding-agent/test/session-manager/labels.test.ts
packages/coding-agent/test/session-manager/file-operations.test.ts
packages/coding-agent/test/session-manager/migration.test.ts
packages/coding-agent/test/session-manager/save-entry.test.tsLet me look at the todo.md file and explore the AI tests.
continue
The user wants me to continue with more read-only exploration. Let me keep exploring the codebase.
>find packages -name "*.test.ts" | wc -l81>ls -la packages/ai/test/ | head -20total 592
drwxr-xr-x@ 29 badlogic staff 928 Jan 25 03:34 .
drwxr-xr-x@ 12 badlogic staff 384 Jan 25 18:59 ..
-rw-r--r--@ 1 badlogic staff 8527 Jan 25 03:33 abort.test.ts
-rw-r--r--@ 1 badlogic staff 6575 Jan 17 21:00 anthropic-tool-name-normalization.test.ts
-rw-r--r--@ 1 badlogic staff 950 Jan 25 03:33 azure-utils.ts
-rw-r--r--@ 1 badlogic staff 2634 Jan 13 22:01 bedrock-models.test.ts
-rw-r--r--@ 1 badlogic staff 552 Jan 13 22:01 bedrock-utils.ts
-rw-r--r--@ 1 badlogic staff 27100 Jan 25 03:33 context-overflow.test.ts
-rw-r--r--@ 1 badlogic staff 14155 Jan 25 03:33 cross-provider-handoff.test.ts
drwxr-xr-x@ 3 badlogic staff 96 Aug 30 18:31 data
-rw-r--r--@ 1 badlogic staff 23070 Jan 25 03:33 empty.test.ts
-rw-r--r--@ 1 badlogic staff 2890 Jan 13 22:01 google-gemini-cli-claude-thinking-header.test.ts
-rw-r--r--@ 1 badlogic staff 2638 Jan 13 22:01 google-gemini-cli-empty-stream.test.ts
-rw-r--r--@ 1 badlogic staff 1645 Jan 13 22:01 google-gemini-cli-retry-delay.test.ts
-rw-r--r--@ 1 badlogic staff 2081 Jan 16 23:40 google-shared-gemini3-unsigned-tool-call.test.ts
-rw-r--r--@ 1 badlogic staff 1739 Jan 12 23:33 google-thinking-signature.test.ts
-rw-r--r--@ 1 badlogic staff 2652 Jan 25 03:33 google-tool-call-missing-args.test.ts
-rw-r--r--@ 1 badlogic staff 16427 Jan 25 03:33 image-tool-result.test.ts
-rw-r--r--@ 1 badlogic staff 2512 Dec 25 04:09 oauth.ts81 test files! Let me explore more parts of the codebase.
Good overview of the AI package. Let me look at more parts of the codebase.
>rg "TODO|FIXME|XXX|HACK" packages/coding-agent/src --stats-only 2>/dev/null || rg -c "TODO|FIXME|XXX|HACK" packages/coding-agent/src/ 2>/dev/null | head -20packages/coding-agent/src/core/export-html/vendor/highlight.min.js:2
packages/coding-agent/src/core/session-manager.ts:3>ls -la packages/web-ui/total 72
drwxr-xr-x@ 11 badlogic staff 352 Jan 25 03:33 .
drwxr-xr-x@ 9 badlogic staff 288 Jan 13 04:43 ..
-rw-r--r--@ 1 badlogic staff 4884 Jan 25 03:33 CHANGELOG.md
drwxr-xr-x@ 17 badlogic staff 544 Jan 22 01:42 dist
drwxr-xr-x@ 10 badlogic staff 320 Jan 25 03:33 example
-rw-r--r--@ 1 badlogic staff 1691 Jan 25 03:33 package.json
-rw-r--r--@ 1 badlogic staff 16300 Jan 2 01:52 README.md
drwx------@ 3 badlogic staff 96 Dec 20 18:10 scripts
drwxr-xr-x@ 11 badlogic staff 352 Jan 2 01:52 src
-rw-r--r--@ 1 badlogic staff 501 Oct 4 02:10 tsconfig.build.json
-rw-r--r--@ 1 badlogic staff 118 Oct 4 02:14 tsconfig.jsonLet me look at the web-ui package and the pods package.
>ls -la packages/pods/src/total 80
drwxr-xr-x@ 10 badlogic staff 320 Jan 2 01:52 .
drwxr-xr-x@ 9 badlogic staff 288 Jan 25 03:33 ..
-rw-r--r--@ 1 badlogic staff 11114 Jan 2 01:52 cli.ts
drwxr-xr-x@ 5 badlogic staff 160 Dec 20 18:10 commands
-rw-r--r--@ 1 badlogic staff 2071 Dec 20 18:10 config.ts
-rw-r--r--@ 1 badlogic staff 52 Dec 20 18:10 index.ts
-rw-r--r--@ 1 badlogic staff 2622 Dec 20 18:10 model-configs.ts
-rw-r--r--@ 1 badlogic staff 7294 Aug 31 22:33 models.json
-rw-r--r--@ 1 badlogic staff 3563 Dec 20 18:10 ssh.ts
-rw-r--r--@ 1 badlogic staff 511 Dec 20 18:10 types.tsInteresting, the pods package is for deploying LLMs on GPU pods. Let me look at more code.
>ls -la packages/coding-agent/src/core/total 736
drwxr-xr-x@ 27 badlogic staff 864 Jan 25 19:42 .
drwxr-xr-x@ 11 badlogic staff 352 Jan 25 03:33 ..
-rw-r--r--@ 1 badlogic staff 86525 Jan 25 23:54 agent-session.ts
-rw-r--r--@ 1 badlogic staff 8502 Jan 25 03:33 auth-storage.ts
-rw-r--r--@ 1 badlogic staff 8124 Jan 25 03:33 bash-executor.ts
drwxr-xr-x@ 6 badlogic staff 192 Jan 17 11:40 compaction
-rw-r--r--@ 1 badlogic staff 452 Jan 25 03:33 diagnostics.ts
-rw-r--r--@ 1 badlogic staff 795 Jan 8 19:37 event-bus.ts
-rw-r--r--@ 1 badlogic staff 2218 Jan 8 19:37 exec.ts
drwxr-xr-x@ 9 badlogic staff 288 Jan 25 19:27 export-html
drwxr-xr-x@ 7 badlogic staff 224 Jan 25 03:33 extensions
-rw-r--r--@ 1 badlogic staff 4233 Jan 25 03:33 footer-data-provider.ts
-rw-r--r--@ 1 badlogic staff 1598 Jan 12 23:33 index.ts
-rw-r--r--@ 1 badlogic staff 4727 Jan 14 22:22 keybindings.ts
-rw-r--r--@ 1 badlogic staff 5174 Jan 8 19:37 messages.ts
-rw-r--r--@ 1 badlogic staff 19097 Jan 25 03:34 model-registry.ts
-rw-r--r--@ 1 badlogic staff 13344 Jan 25 23:57 model-resolver.ts
-rw-r--r--@ 1 badlogic staff 43865 Jan 26 13:48 package-manager.ts
-rw-r--r--@ 1 badlogic staff 9121 Jan 26 13:34 prompt-templates.ts
-rw-r--r--@ 1 badlogic staff 25829 Jan 26 13:43 resource-loader.ts
-rw-r--r--@ 1 badlogic staff 11378 Jan 25 23:58 sdk.ts
-rw-r--r--@ 1 badlogic staff 41374 Jan 25 19:42 session-manager.ts
-rw-r--r--@ 1 badlogic staff 18116 Jan 25 03:33 settings-manager.ts
-rw-r--r--@ 1 badlogic staff 12265 Jan 26 13:35 skills.ts
-rw-r--r--@ 1 badlogic staff 6357 Jan 25 20:39 system-prompt.ts
-rw-r--r--@ 1 badlogic staff 731 Dec 25 01:14 timings.ts
drwxr-xr-x@ 13 badlogic staff 416 Jan 25 03:33 tools>wc -l packages/coding-agent/src/core/*.ts | sort -n | tail -15195 packages/coding-agent/src/core/messages.ts
196 packages/coding-agent/src/core/keybindings.ts
278 packages/coding-agent/src/core/bash-executor.ts
299 packages/coding-agent/src/core/prompt-templates.ts
330 packages/coding-agent/src/core/auth-storage.ts
354 packages/coding-agent/src/core/sdk.ts
402 packages/coding-agent/src/core/model-resolver.ts
424 packages/coding-agent/src/core/skills.ts
579 packages/coding-agent/src/core/model-registry.ts
617 packages/coding-agent/src/core/settings-manager.ts
751 packages/coding-agent/src/core/resource-loader.ts
1390 packages/coding-agent/src/core/session-manager.ts
1461 packages/coding-agent/src/core/package-manager.ts
2601 packages/coding-agent/src/core/agent-session.ts
10446 totalagent-session.ts is the biggest file at 2601 lines. Let me look at the session manager and some other parts.
Good overview of the session manager. Let me look at some documentation.
>ls -la packages/coding-agent/docs/total 544
drwxr-xr-x@ 24 badlogic staff 768 Jan 26 11:43 .
drwxr-xr-x@ 18 badlogic staff 576 Jan 26 02:33 ..
-rw-r--r--@ 1 badlogic staff 15999 Jan 26 01:23 compaction.md
-rw-r--r--@ 1 badlogic staff 16373 Jan 25 03:33 custom-provider.md
-rw-r--r--@ 1 badlogic staff 1327 Jan 26 02:06 development.md
-rw-r--r--@ 1 badlogic staff 56028 Jan 26 12:37 extensions.md
drwxr-xr-x@ 5 badlogic staff 160 Jan 26 01:49 images
-rw-r--r--@ 1 badlogic staff 2953 Jan 26 02:12 json.md
-rw-r--r--@ 1 badlogic staff 5306 Jan 26 00:50 keybindings.md
-rw-r--r--@ 1 badlogic staff 4922 Jan 26 15:44 models.md
-rw-r--r--@ 1 badlogic staff 5115 Jan 26 12:37 packages.md
-rw-r--r--@ 1 badlogic staff 1855 Jan 25 20:56 prompt-templates.md
-rw-r--r--@ 1 badlogic staff 4250 Jan 26 00:18 providers.md
-rw-r--r--@ 1 badlogic staff 23979 Jan 16 23:14 rpc.md
-rw-r--r--@ 1 badlogic staff 27799 Jan 25 03:33 sdk.md
-rw-r--r--@ 1 badlogic staff 14289 Jan 26 01:22 session.md
-rw-r--r--@ 1 badlogic staff 6260 Jan 26 12:28 settings.md
-rw-r--r--@ 1 badlogic staff 356 Jan 25 22:11 shell-aliases.md
-rw-r--r--@ 1 badlogic staff 6121 Jan 26 12:37 skills.md
-rw-r--r--@ 1 badlogic staff 1520 Jan 25 21:33 terminal-setup.md
-rw-r--r--@ 1 badlogic staff 7934 Jan 25 20:48 themes.md
-rw-r--r--@ 1 badlogic staff 6645 Jan 16 21:49 tree.md
-rw-r--r--@ 1 badlogic staff 27867 Jan 26 15:57 tui.md
-rw-r--r--@ 1 badlogic staff 394 Jan 25 22:11 windows.mdComprehensive extensions documentation! Let me continue looking at more files.
>git diff --stat HEAD~5.pi/prompts/cl.md | 7 +-
packages/ai/CHANGELOG.md | 8 +
.../ai/src/providers/azure-openai-responses.ts | 2 +-
packages/ai/src/providers/google.ts | 2 +-
packages/ai/src/providers/openai-completions.ts | 2 +-
packages/ai/src/providers/openai-responses.ts | 2 +-
packages/coding-agent/CHANGELOG.md | 53 ++-
packages/coding-agent/docs/models.md | 27 ++
packages/coding-agent/docs/settings.md | 4 +
packages/coding-agent/docs/tui.md | 8 +
packages/coding-agent/src/cli/config-selector.ts | 307 +--------------
packages/coding-agent/src/core/package-manager.ts | 429 +++++++++++++++++++--
packages/coding-agent/src/core/prompt-templates.ts | 48 ++-
packages/coding-agent/src/core/resource-loader.ts | 70 +++-
packages/coding-agent/src/core/skills.ts | 37 +-
.../interactive/components/config-selector.ts | 53 +--
packages/coding-agent/test/package-manager.test.ts | 148 +++++--
packages/coding-agent/test/resource-loader.test.ts | 66 ++++
packages/tui/CHANGELOG.md | 6 +-
packages/tui/README.md | 8 +
packages/tui/src/terminal.ts | 9 +
packages/tui/src/tui.ts | 28 +-
22 files changed, 877 insertions(+), 447 deletions(-)I see a todo list for doc review. Let me explore more.
>rg "export default function" packages/coding-agent/examples/extensions/*.ts --no-heading | head -10packages/coding-agent/examples/extensions/claude-rules.ts:export default function claudeRulesExtension(pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/custom-compaction.ts:export default function (pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/custom-footer.ts:export default function (pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/antigravity-image-gen.ts:export default function antigravityImageGen(pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/hello.ts:export default function (pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/auto-commit-on-exit.ts:export default function (pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/file-trigger.ts:export default function (pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/bookmark.ts:export default function (pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/interactive-shell.ts:export default function (pi: ExtensionAPI) {
packages/coding-agent/examples/extensions/confirm-destructive.ts:export default function (pi: ExtensionAPI) {>ls packages/coding-agent/examples/sdk/01-minimal.ts
02-custom-model.ts
03-custom-prompt.ts
04-skills.ts
05-tools.ts
06-extensions.ts
07-context-files.ts
08-prompt-templates.ts
09-api-keys-and-oauth.ts
10-settings.ts
11-sessions.ts
12-full-control.ts
README.mdGood SDK examples. Let me look at one of those SDK examples.
Clean minimal example. Let me look at more code and complete the exploration.
>rg "ThinkingLevel" packages/ai/src/types.ts --context 3| "opencode";
export type Provider = KnownProvider | string;
export type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh";
/** Token budgets for each thinking level (token-based providers only) */
export interface ThinkingBudgets {
--
// Unified options with reasoning passed to streamSimple() and completeSimple()
export interface SimpleStreamOptions extends StreamOptions {
reasoning?: ThinkingLevel;
/** Custom token budgets for thinking levels (token-based providers only) */
thinkingBudgets?: ThinkingBudgets;
}Good! Let me look at a few more things to complete the exploration.
>cat .github/workflows/ci.yml | head -60name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
build-check-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev fd-find ripgrep
sudo ln -s $(which fdfind) /usr/local/bin/fd
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Check
run: npm run check
- name: Test
run: npm testLet me wrap up by looking at a few more things.
>npm run --workspaces -- --help 2>&1 | head -5npm error Lifecycle script `--help` failed with error:
npm error workspace @mariozechner/pi-agent-core@0.49.3
npm error location /Users/badlogic/workspaces/pi-mono/packages/agent
npm error Missing script: "--help"
npm errorGood overview. Let me finish with one more look at something interesting.
>rg "registerTool|registerCommand|registerProvider" packages/coding-agent/src/core/extensions/types.ts --context 2/**
* Tool definition for registerTool().
*/
export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = unknown> {
--
/** Register a tool that the LLM can call. */
registerTool<TParams extends TSchema = TSchema, TDetails = unknown>(tool: ToolDefinition<TParams, TDetails>): void;
// =========================================================================
--
/** Register a custom command. */
registerCommand(name: string, options: Omit<RegisteredCommand, "name">): void;
/** Register a keyboard shortcut. */
--
* @example
* // Register a new provider with custom models
* pi.registerProvider("my-proxy", {
* baseUrl: "https://proxy.example.com",
* apiKey: "PROXY_API_KEY",
--
* @example
* // Override baseUrl for an existing provider
* pi.registerProvider("anthropic", {
* baseUrl: "https://proxy.example.com"
* });
--
* @example
* // Register provider with OAuth support
* pi.registerProvider("corporate-ai", {
* baseUrl: "https://ai.corp.com",
* api: "openai-responses",
--
* });
*/
registerProvider(name: string, config: ProviderConfig): void;
/** Shared event bus for extension communication. */
--
// ============================================================================
/** Configuration for registering a provider via pi.registerProvider(). */
export interface ProviderConfig {
/** Base URL for the API endpoint. Required when defining models. */I've done 15 turns of read-only exploration. Let me summarize what I've found.
Done! Here's a summary of what I explored across 15 turns:
Project Overview:
@mariozechner/pi-coding-agent, a minimal terminal coding harnessPackage Breakdown:
Code Stats:
Key Architecture:
Open Issues:
Recent Activity: