Skip to main content

xdog-tui

Platform scope: Linux only. Non-Linux adapters and native-platform support are outside the current product scope; historical audit evidence is not a support promise.

Terminal UI library with differential rendering.

A small terminal UI toolkit that redraws owned rows in the main terminal buffer while preserving native scrollback. No curses dependency.

InputPanel supplies shared Unicode editing, undo/redo, history and atomic paste. InlineLayout budgets the editor and prioritized auxiliary panels from terminal height. The renderer uses cursor reports at startup, resize and resume. Ctrl+L repaints visible owned rows without clearing native scrollback or focus. Focused editor markers position and show the terminal cursor; panels without a marker hide it. Overlays restore base focus and composite by display cells. Clearing a scrolled transcript re-anchors the owned tail without erasing history. Confirmation panels reject unshown/clipped actions and unpainted resize states. EventQueue.drain() processes bounded FIFO batches so sustained producer output does not monopolize a UI tick (defaults: 64 events or 8 ms between callbacks).

Standalone panels are available from xdog.tui.components:

Component Responsibility
PermissionPanel Summary scrolling, choices, selection and cancellation callbacks
DetailsPanel Full detail records, entry navigation, scrolling and explicit output following
InputPanel Multiline editing, history, completion and submit/cancel callbacks
StatusLine One bounded row of plain status or prioritized activity/context/model fields

Panels accept data, theme functions and callbacks; they do not import Coding or Claw policy. Applications own permission decisions and lifecycle state, while InlineLayout only positions panels and allocates height. PromptEditor and BoundedDetails remain compatible aliases at their original import paths.

See terminal stability and verification for scope, test commands, and platform limitations. Fullscreen applications and remote coding are outside this stability work.

Part of xdog

This package is one piece of xdog, a local-first toolkit for building, running and scheduling LLM workflows. The centrepiece is xdog-flow — a typed workflow format and compiler.

Documentation: https://xdog.942295.xyz

Licence

Copyright (c) 2026 HugeMan <942295.xyz>

GNU Affero General Public License v3.0 or later — see LICENSE. Output compiled by xdog-flow is exempt; see the Generated Output Exception.

Non-blocking prompt path completion

InputPanel.set_autocomplete_provider(provider) now connects live prompt completion. Call poll_autocomplete() from the host's UI tick and request a repaint only when it returns True. Providers must return without blocking; WorkspaceFileCompletionProvider(root) provides a coalescing filesystem worker for fuzzy @ references and explicit paths. Close owned providers during host shutdown. Results never mutate the editor from a worker thread.

Selecting a file replaces only its cursor-local token and never submits the draft; slash commands retain their existing Enter behavior. Focused details and permissions suppress background suggestions. max_entries/scan_seconds bound worker batches, not total discovery. Names are held in a private SQLite index; root search and large directory scans resume until complete. Git supplies ignore semantics for repositories and non-repositories through private metadata; no workspace Git state or hooks are changed/executed. Missing/failing Git is a visible basic-exclusion fallback. CompletionStatusProvider optionally supplies non-blocking progress text; InputPanel clamps it to the existing menu budget and never treats status as a selectable path. See docs/agent-ui-gap-plan.md for the full application goal and verification.

Prompt keymaps and foreground terminal handoff

PromptKeymap is the immutable, validated map used by the live Coding/Claw editors and host action handlers. InputPanel.set_keymap() remaps actions without falling back to replaced chords; dialog confirmation remains independent. help_text() and label() expose effective bindings for help and hints.

TUI.run_outside_terminal(callback) schedules one foreground callback after protocol cleanup and raw-mode restoration. The callback runs on the UI thread; polling/painting pauses, while external workers may keep publishing events. Modes are preserved around the callback in case its process leaves them changed. Return re-enters negotiation and appends a new owned transient tail without replaying durable history. Pending handoffs and stopped/suspending TUIs reject new handoffs; coalesced input after a handoff request is not executed.

edit_draft() provides the standard private-file external-editor round trip. Only user environment preferences select its executable; returned text must be applied by the host, not submitted automatically. Helpers are exported from xdog.tui as well as their modules. Approval policies remain application-owned.

Queue control vocabulary

The shared queue_controls module supplies immutable queue views, stable local ID bookkeeping and /queue command parsing; it does not route agent work or choose application permissions. Hosts show bounded previews and own queue locks, worker-loop acknowledgements, transport generations and draft recovery. The live prompt keymap exposes steer (Alt+S), follow_up (Alt+F) and queue (Ctrl+Q). This vocabulary serves the primary composer/run; ChildQueuePanel below is a separate read-only child-input inspector.

Session/branch navigation surfaces

NavigationEntry/NavigationSnapshot, NavigationWorker and NavigationFeed provide immutable, paginated local-worker and remote-reply views. Search applies to the full metadata set before pagination. Requests coalesce and stale/closed replies are fenced; changed searches/scopes do not leave stale rows selectable. NavigationPanel owns search, paste, navigation and focus in the bounded native transient tail. Application callbacks own activation, idle gates, permission isolation, storage and gateway context synchronization; the library does not import agent/application policy or run model calls.

Explicit image composer and clipboard reads

Attachment is immutable raw image data plus stable identity/metadata. attachment()/read_attachment() validate PNG/JPEG/WebP headers and bounded size/dimensions; file reads use nonblocking open/regular-file checks to avoid FIFO hangs, not to establish a sandbox. AttachmentReader owns one off-thread read and its bounded clipboard subprocess, publishing immutable events to the host. Linux Wayland (wl-paste) and X11 (xclip) image/text helpers are explicit reads, never background polling. No non-Linux clipboard adapter is shipped.

AttachmentComposer owns add/list/preview/remove/clear/take/restore on the UI thread. Late reads after take stay editable; explicit clear fences prior reads. Recovery retains bytes even above ordinary admission caps, leaving host validation to block oversized sends. InputPanel.set_attachment_summary() reserves a bounded summary row and enables empty-text submission only while attachments are present. AttachmentPanel owns focused preview input, caps image height, and falls back to metadata on unsupported/tiny terminals. Types/helpers are exported from xdog.tui, the panel from xdog.tui.components. Provider capability, permissions, typed SDK conversion, queue ownership, persistence and transport remain application policy.

Full-source transcript browsing and temporary alternate screens

Transcript.transcript_records() projects immutable, stable-ID source strings from retained message/tool components without rendering/truncation. User/assistant source is retained before Markdown transformations. TranscriptBrowser owns one coalescing worker: full source indexing, literal Unicode-casefold search over every occurrence, source-position preservation on refresh, horizontal clipping and bounded viewport snapshots. Per-line cumulative counts avoid allocating one object for each repeated occurrence on a huge line. Old/closed results cannot be published over newer requests. Source extraction for explicit copy/export is separate and should run off the UI thread.

TranscriptPanel owns query paste/editing, occurrence and source-entry navigation, vertical/horizontal scrolling, whole-line/range/entry selection and refresh/latest controls. The host owns source/session boundaries, permissions and fullscreen policy. Inline panels are capped at 12 rows; temporary fullscreen takes the host-provided terminal-height budget. Searching/selection has no application mutation, agent, provider or clipboard dependency.

TUI.request_fullscreen(enabled) schedules an owned terminal-loop boundary transition rather than changing modes inside an input callback. A temporary alternate painter retains the native main-buffer painter; return requests CPR to handle hidden main-buffer reflow, then repaints only owned visible rows. Coalesced keys cannot submit through a pending transition. InlineLayout.fullscreen_view lets hosts provide a height-bounded alternate surface; no normal transcript/editor is painted there. Hosts must leave fullscreen for approvals/other dialogs. Stop/failure cleans temporary screen ownership; suspend retains it for re-entry. The default remains native scrollback, with no main-buffer clear/replay. Helpers are exported from xdog.tui and TranscriptPanel from xdog.tui.components.

Hosts with asynchronous remote sources can supply TranscriptPanel(on_refresh=...), set a visible loading/error status, and replace immutable records only after complete validation. Selection is disabled during loading; pending query/End intent survives old viewport and geometry receipts. Whole-entry selection is prioritized in the header even when a source-status label is present. Large sanitized ASCII lines use cell-equivalent direct slicing/panning instead of allocating a grapheme object for every offscreen character; Unicode retains grapheme-safe clipping.

Captured transcript output actions

transcript_transfer supplies immutable parsed options/prepared artifacts, source scope extraction, HTML escaping/heuristic share redaction, exclusive private atomic file creation and explicit OS clipboard writes with a visible private-file fallback. TransferWorker owns one off-thread operation; it does not replay/coalesce writes. TranscriptActions adapts immutable worker receipts into a context-fenced UI review lifecycle. Hosts retain approval, source completeness, workspace/session and focus policy. OutputPanel owns preview/path input, forbids confirmation until source and full metadata/destination are rendered, and keeps paste/modified Enter/tiny resize from saving. It imports no agent policy and performs no upload. TranscriptPanel exposes optional output callbacks for y/e/s with stable selection/entry IDs.

Child-work presentation

ChildPanel is a policy-free bounded roster/form/transcript component used by both clients. Hosts provide validated summaries, immutable source records, operation callbacks and ownership fences. It never executes agents or grants tool permission. Child-specific start/steer/follow-up/cancel/close confirmations require a painted visible action; paste/repeat/release/tiny-frame input cannot confirm. ChildSourceWorker coalesces local conversion; child JSON conversion preserves complete retained text, redacts sensitive fields heuristically and omits binary bodies/signatures. Search, selection, fullscreen and explicit reviewed outputs reuse TranscriptPanel and TranscriptActions. Child dialogs/configuration/tool-progress policy stays in hosts.

ChildQueuePanel is a read-only metadata inspector, not a queue editor. It shows pending/selected inputs, attachment counts and stopped/uncertain recovery provenance. Up/Down selects, Enter expands metadata, r refreshes and Escape returns. There are no edit/reorder/remove/return, stopped-copy or binary-recovery controls, and pasted input cannot become a command or draft. Hosts bind list-only requests to the exact child/session/view. Main-Agent/SDK queue mutation and explicit durable recovery stay in their own backend and normal permission policy; this component grants neither. Ordinary child cancel/wait controls and transient child task editors are separate.

OAuthPanel is a policy-free bounded full-page consent/status surface composed by McpPanel. Hosts validate endpoints/URIs and own network/view leases. Every field must paint before confirmation; layout/content/visibility changes invalidate prior review. Cancel outranks polling; URL copy is explicit after full review. Wrapper budget/invalidation reaches the actual form, including zero rows. The component never launches browsers, connects tools or interprets OAuth as execution permission.

Refresh reviews use the same full-page confirmation and resize invalidation as initial consent. Their footer exposes paging until all fields paint, then Enter confirmation; pending refresh shows c cancellation, which remains available while an owner request is busy. Components dispatch auth_refresh_prepare and auth_refresh; only application hosts manage credentials and token rotation.

Child task submission can prepare a local review while a roster request is pending, without losing the input draft. Final confirmation remains blocked until that request settles; review preparation itself never starts a child or grants access.

clipboard_macos.read_macos_clipboard() supplies a static JXA/AppKit program to the reader's existing bounded subprocess runner: PNG/JPEG/WebP first, TIFF-to-PNG conversion with pixel/byte limits, then Unicode text. A change-count guard refuses mixed clipboard snapshots. Strict bounded JSON/base64 decoding rejects helper failure without reflecting contents or retrying as text. No clipboard URL/file reads, browser/app automation, clipboard polling or input submission are added. Node-based contract tests exercise the exact shipped program with an independent AppKit interface; they are not validation of Apple's real JXA bridge/pasteboard. The script-contract tests explicitly skip if Node is unavailable; Node is not a runtime dependency of the clipboard adapter or either client.

Read-only extension command display

ExtensionCommand displays a host-validated artifact's text and bounded image components, with complete detail_body and separately retained typed result data. Its transcript_role is system, not tool/model input. Existing detail expansion and transcript source ownership apply; narrow fallback text is clipped without altering graphics payloads. Hosts alone decode/gate artifacts, preserve drafts/session scope and prevent prompt submission. The component does not execute returned text/URIs, write files, grant approval or pretend textual export contains the image bytes.

Explicit typed snapshot output

TranscriptActions.start_snapshot(options, root, prepare)/TransferWorker.start_snapshot run a host-supplied pure bounded snapshot recipe off-thread and ALWAYS show the existing review, including explicit paths. Hosts supply PreparedTransfer data/text/ digest/context; the TUI adds no agent dependency or artifact-policy authority. Artifact scope is JSON-only export, not binary copy/share or textual record coercion. OutputPanel exposes no-redaction/sensitive-original-byte warnings; existing visible-path/resize/context/cancel/private-no-overwrite rules remain. Command display components carry a host-assigned owner token so clients can select only current session/connection data for lossless export.

Effective extension command bindings

ExtensionShortcuts(rows, keymap) resolves host-validated command contributions against effective built-in/user actions, reports disabled collisions and dispatches only PRESS events. A namespaced ext-ID-command keybindings override replaces that registration's defaults or explicitly unbinds it; unknown/inactive registrations cannot become callbacks from configuration alone. Conflicting extension keys are all disabled, never arbitrary winner-takes-input. Context/activation/command authority belongs to the hosts. The TUI performs no plugin loading or model/tool calls.

Canonical pre-admission input display

Shared UserMessage.set_text/Transcript.transform_user_input updates only a matching current user echo, preserving image-count labels and Markdown invalidation without terminal command execution. Hosts carry input-transformed/refused ownership receipts, update actual consumed queued text and restore owned original drafts/attachments on pre-admission refusal. The TUI itself runs no extension filter, model or permission policy. Native scrollback and existing source-role/selection semantics remain.

The live TUI now guards painting against geometry changing BETWEEN its input-loop size check and tick callbacks. A raced frame is deferred while remaining dirty, so the next loop still queries/re-anchors the cursor before repainting. Pure/offline rendering remains unchanged. A deterministic lifecycle test and the physical output review cases preserve existing native-scrollback and visible-confirmation assertions.

Handled input remains host-owned policy. Current clients show explicit system/extension feedback and retain original composer attachments without pretending the request was admitted as a model message. Child source inspection accepts separately bounded input_feedback metadata and presents it as system data, never assistant prose. No custom renderer/model/tool/permission authority is introduced by these displays.

Paged output review on narrow terminals

Export/share/artifact review no longer requires an unusually wide terminal for a long destination. When metadata, warnings and the full target do not fit together, the output panel pages them with PgUp/PgDn/Home/End. Every displayed metadata/path row must be painted under the active focus owner before Enter can save. At least 24 columns and four panel rows are required; narrower/hidden views cannot confirm. Resize, focus loss and path editing revoke that proof and restart field review.

v opens the captured payload preview without enabling save, then returns to the metadata/path review. Normal roomy layouts retain the combined preview. Tab edits the path; repeated Tab/Enter or pasted confirmation text cannot approve an export. A long Unicode path is reviewed without losing grapheme boundaries or replacing its source value. Existing private atomic writes, no-overwrite, owner/context fencing, no-upload and share-redaction policy remain authoritative.

Explicit MCP arguments

After explicitly connecting a server, prompt arguments are entered as a JSON object and resource reads use an explicitly supplied resolved URI. Submitted input stays editable after errors or cancellation. Catalog reads, multitype previews, insert/export and existing permission boundaries remain; manual named argument/opaque-resource completion pickers are removed. This does not remove the lower-level MCP completion client API or extension command argument completion.

Basic extension interaction scope

Trusted extensions can use api.input, api.confirm and api.select with normal cancellation, plus bounded notifications and simple text status. Arbitrary custom renderers, typed plugin forms, nested dialogs, extension overlays/fullscreen frames and widget layouts are removed. Private native field-review components remain for host-owned editor/navigation/queued-input confirmations; these are not a plugin layout API or permission grant. Core TUI overlays, transcript fullscreen, Unicode, clipping, cursor and tool-approval behavior remain.

Metadata

Release files for xdog-tui 2.4.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xdog-tui 2.4.2
File Size Uploaded
xdog_tui-2.4.2.tar.gz 269.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for xdog-tui 2.4.2
File Interpreter ABI Platform
xdog_tui-2.4.2-py3-none-any.whl Python 3 none any Details

Total release size: 497.2 kB

Release files / xdog_tui-2.4.2.tar.gz

Download URL xdog_tui-2.4.2.tar.gz
Size 269.0 kB
Tags Source
SHA-256 checksum
How to use checksums
891b1f92c15879f4dc4dca5d2068ed22d3fcfd95d20e06c3ed6ac169548936d6
BLAKE2b-256 checksum
How to use checksums
1b89ca454e8ff4e8de3586da0aba0a72b5ea60b795d45cbe1d9f9e26ce19c742
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release files / xdog_tui-2.4.2-py3-none-any.whl

Download URL xdog_tui-2.4.2-py3-none-any.whl
Size 228.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
027a4d74d5e6c47eb322628c3f429631642c2937162566103f08f0547287cf4a
BLAKE2b-256 checksum
How to use checksums
5d9a7daf90d3cbb30df1134e24bf1b825ab597cc27a472f612e007785858b089
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.4.2 This release

2 release files

2.4.1

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.1.2

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page