Metadata-Version: 2.5
Name: agentknit-tui
Version: 0.4.0
Summary: Textual TUI front-end for agentknit coding agents.
Project-URL: Homepage, https://github.com/monperrus/agentknit-tui
Project-URL: Repository, https://github.com/monperrus/agentknit-tui
Project-URL: Issues, https://github.com/monperrus/agentknit-tui/issues
Project-URL: Changelog, https://github.com/monperrus/agentknit-tui/blob/main/CHANGELOG.md
Author: agentknit contributors
License: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console :: Curses
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Requires-Dist: agentknit<1,>=0.2.0
Requires-Dist: rich>=13
Requires-Dist: textual>=0.86
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
Requires-Dist: pytest-cov>=4; extra == 'test'
Requires-Dist: pytest>=7; extra == 'test'
Description-Content-Type: text/markdown

# agentknit-tui

A [Textual](https://textual.textualize.io/) TUI front-end for
[agentknit](https://github.com/monperrus/agentknit) coding agents.

Features: 
- one always-visible conversation pane
- a multiline prompt at the bottom, 
- tool calls / results / token accounting rendered
inline
- a live status bar. 

the TUI is a pure subscriber to the event stream from agentknit.

## Install

```
pip install agentknit-tui
```

It depends on `agentknit`, `textual`, and `rich`.

## Usage

```
agentknit-tui                       # default: glm-5.2 via z.ai
agentknit-tui glm-5.2
agentknit-tui "qwen3-8b" "https://openrouter.ai/api/v1"
agentknit-tui --session <id>        # resume a previous trajectory
agentknit-tui --non-interactive     # drop ask_user* tools from the schema
agentknit-tui --no-strict-cache-proof
```

### Key bindings

| key                  | action                          |
| -------------------- | ------------------------------- |
| `Enter`              | submit the prompt               |
| `Shift/Ctrl/Alt+Enter` | insert a newline              |
| `↑` / `↓`            | recall past prompts (same folder, shared with the REPL) |
| `Esc` / `Ctrl+C`     | cancel the running turn (or quit when idle) |
| `Ctrl+Shift+C`       | copy the mouse selection in the log          |
| `Ctrl+L`             | clear the on-screen conversation log only |

### Mouse

- **Drag** over the conversation log selects text in place (highlighted as
  you drag); `Ctrl+Shift+C` then copies the selection (plain `Ctrl+C` also
  works when your terminal delivers it). `Esc` clears the selection.
- Paste into the prompt with the terminal's own paste (`Ctrl+Shift+V`,
  `Shift+Insert`, or middle-click) — `Ctrl+V` inside the TUI only reads
  text copied *within* the TUI.
- Copying tries the platform clipboard tool first (`xclip`/`xsel`, `wl-copy`,
  `pbcopy`, `clip.exe`) and also emits OSC 52; one of the two reaches the
  system clipboard even in VTE terminals that ignore OSC 52 (Terminator,
  older gnome-terminal).
- Copying out of a bordered block (your prompt, replies, tool output) strips
  the Rich panel chrome first, so the clipboard gets the payload text — no
  leading `│` gutter, no border rows.

`Ctrl+L` (and the TUI's built-in `/clear` alias) wipes the displayed log
and zeroes the token counters in the status bar; the agent's message
history — the context sent to the model — is untouched, and `/usage`
still reports the session's full totals.

### Status bar

The line under the prompt shows the model, session id, token usage, and —
while a turn is running — the task the agent is working on, wrapped over
two terminal-width lines so long prompts stay readable.
To reset the LLM context (session history, keeping the system prompt), run
`/reset-context` in the TUI; it forwards to agentknit's `/clear` handler.

Slash commands (`/help`, `/usage`, `/clear`, `/compact`, `/model`, `/reset-context`, `/exit`)
are forwarded to agentknit's command registry; their printed output is
captured and shown inline.

On exit the TUI prints the command to resume the session on the console,
exactly like the end of the agentknit REPL:

```
Resume: agentknit-tui glm-5.2 --session <session-id>
```

Set `AGENTKNIT_RESUME_COMMAND` to override the program prefix (wrappers
embedding the model already do this); the `--session <id>` suffix is always
appended.

## Design notes

- The agent loop (`agentknit.run_turn`) is synchronous and blocking and
  emits typed events through a session `on_event` callback. The TUI runs
  each turn in a Textual worker thread and forwards every event onto a
  thread-safe queue; a 50 ms UI-thread timer drains the queue and renders
  each event's pre-formatted ANSI string into a Rich renderable.
- agentknit's `fmt` strings are raw `\033[…]` ANSI escapes (not Rich
  markup), so they are decoded with `rich.ansi.AnsiDecoder` for faithful
  colour/style reproduction.
- Multi-line input uses `TextArea`, so users can paste and edit freely.
  A `CancelToken` is wired to the cancel bindings so a turn can be
  interrupted cooperatively, exactly like Ctrl+C in the REPL.
- Prompt history is per-folder and shared with the REPL: both read and
  write agentknit's readline history file
  (`~/.local/share/agent_probe/repl_history/<md5(cwd)>.hist`), so arrow-up
  recalls instructions typed in either front-end, scoped to the folder they
  were typed in. `↑` on the first prompt line walks back, `↓` forward, and
  any edit drops back to normal typing.
- On exit the TUI mirrors the REPL's teardown: the trajectory snapshot is
  saved (if the session has any messages), a `session_end` record is
  appended to the session log, and — after Textual restores the plain
  console — the same dim `Resume: …` line the REPL prints is echoed so the
  session can be continued with `--session <id>`.
- agentknit installs a module-level SIGINT handler (meant for the
  foreground REPL) that kills the active tool subprocess. The TUI
  neutralises it for each turn's duration and drives cancellation through
  the `CancelToken` instead.

## License

MIT.
