Skip to content

Releases: viktordanov/uah

v1.16.0

Choose a tag to compare

@viktordanov viktordanov released this 27 Oct 12:34
1eaf157

Faster and smaller requests on openai-codex

  • Requests go over the Responses WebSocket (#8), as Codex does. A session keeps one connection, and after the first request each one sends only what is new: the tool results and messages since the last response, not the whole history. On a resumed session, one turn of 4 requests uploaded 0.63 MB instead of 2.1 MB; each request after the first sent 6.4 KB instead of 528 KB, its first byte came back in about 140 ms instead of 2 s, and it finished in 2.6–3.6 s instead of 5.7–7.5 s. A failed or cancelled response, a compaction, a rewind, or a model change sends the full history again. If the upgrade is refused or fails 3 times in a row, the session goes on over HTTP. responses_websocket = false turns it off.
  • Request bodies are zstd-compressed over HTTP, as Codex does: 1.4–2.6× smaller on real sessions (images and encrypted reasoning are already compressed). If the server refuses a compressed body, uah sends it uncompressed and stops compressing.
  • The turn state is sent back. The first x-codex-turn-state the backend returns in a run goes with the run's later requests, as Codex does.
  • Diagnostics for each model request now name the transport, whether the send was full or only the new items and why, the bytes on the wire, and the size before compression.

Requires uah-core v0.10.0.

v1.15.0

Choose a tag to compare

@viktordanov viktordanov released this 27 Oct 02:02
1eaf756

Faster

  • Scrolling back in a long session. Scrolled up, each redraw built every line below the window. It now builds only the rows you see: on a session of 8,000 runs, a redraw went from 4.7 to 0.97 ms and from 20 MB to 13 KB.
  • The @ file menu in a big repo. The menu searched every file on each key, arrow, and redraw. It now searches once per change to what you typed: an arrow key in a repo of 20,000 files went from 17 ms to 2 µs, and typing a character from 16 to 5 ms.
  • Opening and resuming long sessions. Replaying a session's history no longer slows down with the square of its runs (16,000 runs: 1,004 to 73 ms). Loading one session reads only that session's runs from the index, not every run summary in the state directory (2,000 runs: 36 to 8 ms). This covers resume, uah sessions show, and opening a subagent's view.
  • Less work before each request. uah-core v0.9.3 decodes each line of the session file once: on an 80 MB session, resuming went from 169 to 136 ms and 296 to 223 MiB. uagent v0.9.1 finds a run's leftover tools without decoding every line: 75 to 36 ms and 128 to 7 MiB on an 88 MB session, at each run's start and end.

Fixes

  • uah exec --last continues your session, never a newer subagent's or reviewer's session.
  • Subagents no longer stay "running" after they end. A message sent while a subagent closed, or a steer into a run that ended at once, could leave it running until a 20-minute check failed it.
  • /config shows the open session's settings. After uah resume from another directory, it showed that directory's project settings. Model, effort, fast, adaptive, and permission now show session as their source.
  • [agents] max_threads follows file precedence like max_concurrent_threads_per_session, which it is another name for.
  • TOML role files accept what Markdown roles do: tools as a comma-separated string and service_tier as a boolean. Such a role was dropped. In a Markdown role, service_tier: true now means priority.
  • uah stats --by workspace shows one row for a directory reached by two paths, as -C already matched it.
  • Docs: the configuration reference marks the keys a project file can turn off with false or 0, and says a thread limit of 0 is an error.

v1.14.2

Choose a tag to compare

@viktordanov viktordanov released this 23 Oct 12:00
1eaf5d9

Fixes

  • The question picker shows the whole option (#7). When the agent asks a question, the selected option's description now wraps onto as many rows as it needs instead of ending in …. The other options keep one row each, so the list stays short. On a narrow screen the description goes under the option.
  • The whole question shows too. A long question used to be cut at four rows.
  • The panel fits the screen. On a short terminal, the question and the description give up rows so the title and the start of the question stay in view.

v1.14.1

Choose a tag to compare

@viktordanov viktordanov released this 21 Oct 21:52
1eaf3db

Fixes

  • Code blocks wrap. A code line longer than the window used to be cut off. Now it wraps and keeps its highlighting, and each continuation row starts with a dim ↪ in the padding column.

  • Copying code gives the code as written. Selecting a wrapped code line copies it as one line:

    • no break where it wrapped;
    • the spaces at a break kept;
    • no padding cell where a wide character didn't fit;
    • dedented like the block's other lines.

    Copying a very long line, such as minified JSON, stays fast. Prose still copies as drawn.

v1.14.0

Choose a tag to compare

@viktordanov viktordanov released this 21 Oct 17:03
1eaf1cf

Work in your home directory

uah now runs in ~, and in ~/.uah itself, with a warning. Before, every message failed there with "state dir … is inside the workspace".

  • Why it was blocked: the agent's own searches could read uah's session files back.
  • The safety net: uah now writes ~/.uah/.ignore, so rg, fd, and ag skip sessions, runs, logs, the sandbox, images, the index, and the prompt history, even with --hidden. Your config, prompts, rules, and skills stay searchable. uah rewrites the file only while it carries uah's first line, so your own edits are kept. grep -r and find don't read it.
  • The old refusal: set block_state_in_workspace = true to get it back.
  • Requires uagent v0.9.0 (Request.AllowStateInWorkspace).

A stalled response retries after 90 seconds

A model stream that stops sending data is now retried after 90 seconds instead of 5 minutes. Before, a stall sat at "Thinking · no data for …" until you sent a message.

  • Dead connections: HTTP/2 pings already drop them within 45 s. This catches a live connection whose stream stopped.
  • Why 90 s: healthy streams never went quiet for more than 34 s in 12,000 requests at any effort.
  • Changing it: stream_idle_timeout_ms (Codex's key) sets the timeout.
  • Logging: each request's line in stderr.log adds trailing_gap_ms, the silence before the stream ended.

Fixes

  • Option+← and Option+→ move by a word in the message box. They used to switch agents even with text typed, so the cursor jumped to the end. In an empty box they still switch agents.

v1.13.2

Choose a tag to compare

@viktordanov viktordanov released this 20 Oct 16:56
1eaf137

Security

uah is now built with Go 1.27.3. The earlier releases were built with Go 1.27.1, so their binaries carried 12 standard-library vulnerabilities that govulncheck reports. Go 1.27.2 fixed them:

  • net/http, including its HTTP/2 server and transport: GO-2026-6617, GO-2026-6613, GO-2026-6612, GO-2026-6611, GO-2026-6610, GO-2026-6609, GO-2026-6605, and GO-2026-6603.
  • crypto/tls: GO-2026-6607.
  • net/textproto: GO-2026-6608.
  • html/template: GO-2026-6600 and GO-2026-6599.

Go 1.27.3 adds a security fix to crypto/x509.

With Go 1.27.3, govulncheck finds no vulnerability in uah or its dependencies. Building from source now needs Go 1.27.3 or later.

v1.13.1

Choose a tag to compare

@viktordanov viktordanov released this 16 Oct 22:41
1eafde1

Sessions another program wrote

uah now finds a session that has history but no run record. One example is a conversation another program converted from another harness into a session file, with or without a sidecar.

  • Listed: uah sessions (and --json) shows it with 0 runs, its workspace, its first message, and the conversation's own times.
  • Shown: uah sessions show prints it as the history from before uah ran it, and --json puts it under history.
  • Resumed: uah resume <id> and --session <id> continue it, and the model receives the whole conversation. The resume picker, --last, and shell completion offer it.
  • After its first run: it's listed once, from its runs, and the converted history still shows first, in the TUI too.
  • Removed: uah sessions rm deletes it.

A session that never got a message still stays out of the picker and --last. --search finds a converted session only once it has a run.

v1.13.0

Choose a tag to compare

@viktordanov viktordanov released this 16 Oct 19:39
1eafa14

Token statistics: uah stats

uah stats adds up the tokens of every uah session, in every workspace. It includes subagent runs, /review's reviewers, and compaction calls.

uah stats                        # the last 7 days by day, compared with the 7 before, and all time
uah stats --by week              # day, week, month, model, workspace, or source
uah stats --since 2026-10-01 --until 2026-10-15
uah stats -C ~/src/app           # one workspace
uah stats --wide                 # input, cached, output, and reasoning too
uah stats --heatmap              # tokens per day as a grid of weeks
uah stats --json                 # exact counts for scripts
  • Headline: the range's tokens, runs, sessions, and share of input served from the cache. Under it, a comparison with the range before and the busiest day.
  • Rows: dates as people read them, a bar per total, and today marked.
  • Summary:
    • all time;
    • median, mean, and 90th percentile per active day;
    • the streak of active days;
    • tokens per run and per session;
    • the top models and workspaces.
  • Days: days are local, and weeks start on Monday. A run counts on the day it started.
  • Not counted yet: auto-review calls aren't recorded anywhere yet.

Fixes

  • /status heatmap: it's now scaled by the days it shows, so a busy day outside the grid no longer pales the rest.

v1.12.2

Choose a tag to compare

@viktordanov viktordanov released this 15 Oct 22:00
1eaf329

Fixes

  • Program status waits for subagents. In OSC 7501, a run that finished while subagents still worked reported done. The session's own record now stays working until they end, with Waiting for Ada or Waiting for 2 subagents as its message.
    • A failed run, or an expired login, still shows first.
    • A resumed subagent that hasn't been sent a message yet doesn't count.
  • A hung subagent is stopped. Before, a subagent that hung kept its record, and the parent's wait_agent, running forever.
    • A subagent that's working sends events at least every 10 minutes. One that runs for 20 minutes with no event now ends as errored ("stopped: no activity for 20 minutes") and is interrupted, so the parent's waits and status end.
    • A subagent waiting on your approval, or running its SubagentStop hooks, is exempt.
    • The first message sent to a stopped subagent runs once its interrupted run has ended.

v1.12.1

Choose a tag to compare

@viktordanov viktordanov released this 14 Oct 17:54
1eaf589

Colors in the CLI

On a terminal, the CLI's listings use the TUI's colors. A pipe, a file, or NO_COLOR still gets plain text.

  • uah context: a module that applies stays plain, with on and yes in green. One that doesn't apply is grayed out. untrusted is yellow and error red.
  • uah config: default values are grayed out, so the ones you set stand out.
  • uah sessions: ok is green, interrupted yellow, and a failure red. Subagent rows are grayed out.
  • uah hooks: runs is green and untrusted yellow.
  • uah mcp list: enabled is green. A disabled server is grayed out.
  • uah doctor: ✓, ! and ✗ are green, yellow and red.
  • uah models: the default model is bold.
  • uah usage: the bar is green, yellow under 50% left, and red under 20%.
  • uah exec: the progress times are grayed out, errors red, and warnings yellow.

Fixes

  • uah config:
    • A long value, such as a hook's command, no longer pads every row to its width. It runs past its column in its own row.
    • Line breaks and tabs in a value show as \n and \t.
  • uah usage: the credit balance drops its trailing zeros: 62500, not 62500.0000000000.