14 Commits
Author SHA1 Message Date
Teknium aa28a71341 fix(cli): the glyph layout's reasoning summary never repeats the start of the thought
The "∴ Thought for Ns" line that closes a reasoning block appended the
reasoning's first bold heading, or — with no heading — its first sentence.
Models whose reasoning has no headings (e.g. Claude) therefore got their
opening sentence printed twice: once in the reasoning body streamed above the
line, and again as the summary's title. Drop the title entirely; the reasoning
is already shown in full right above, so the summary is just the duration.

Removes the now-dead _full_title/thought_title/_TITLE_MAX helpers and the
write-only _reasoning_full_text buffer in the stream mixin.
2026-11-02 07:54:35 -08:00
Teknium bb6d5464c6 fix: a skill_manage batch whose rollback failed stays a visible failure
Review finding: exempting every skill_manage failure also hid a batch whose
rollback failed ("ROLLBACK FAILED ... snapshot preserved"), which leaves
partial changes on disk. agent/display.py::is_neutral_failure (and the
Desktop isNeutralFailure mirror) now neutralizes only refusals: a result
carrying the rollback-failure marker keeps the red row, the failed count
and the answer-only force-show.
2026-10-21 00:14:33 -07:00
Teknium 74cc8a105f fix: a refused skill_manage write reads neutral, not as a red failure
skill_manage refusals (size cap, stale old_string, guards) are the agent's
own retry loop, but every surface painted them as failures: the glyph CLI
led the row with a red ✗ and red reason, Desktop showed the destructive
error glyph and counted it in "N tool calls failed", and answer-only mode
force-surfaced it on TUI/Desktop as a failure the user must see.

One display-only list, agent/display.py::NEUTRAL_FAILURE_TOOLS (mirrored in
Desktop's fallback-model/format.ts), now keeps those rows neutral: the CLI
row keeps its emoji with a dim reason, Desktop renders the existing
"notice" status and leaves it out of the failed count, and tool.complete is
no longer forced through when tool progress is off. The failure still
reaches the model and the loop guardrail unchanged.
2026-10-21 00:14:33 -07:00
Teknium 3b15d2800b fix(cli): a long one-sentence reasoning is not repeated as a shortened title
The title is capped at 72 chars before display, so comparing the shortened
title with the full reasoning missed a long single sentence: it streamed
and then came back as its own truncated title. Compare the full title.
2026-10-20 10:45:50 -07:00
Teknium a3537b6f04 fix(cli): one-sentence reasoning is not repeated as its own summary title
The glyph layout streams reasoning live and closes the block with
"∴ Thought for Ns · <title>", where the title is the first bold heading or
first sentence. Since live streaming came back (2aef21193c), a reasoning
block that is a single sentence shows that sentence twice: once streamed,
once as the title. The terminal transcript E2E caught it on the v0.22.3
release attempt ("[cli/turns] reasoning rendered 2x").

The summary drops the title when the title is the whole reasoning text.
Multi-line reasoning keeps its heading title as before.
2026-10-20 10:45:50 -07:00
Teknium dfe787496a fix(cli): frame every block with bars and blank lines
Tek: user messages, reasoning and answers each read as blank line, bar,
content, bar, blank line. closing_separator() prints the closing bar and
leaves the blank line owed; the next row (tool row, turn footer) pays it and
an opening bar pays it with its own leading blank, so gaps never double. The
post-hoc reasoning path (thought_rows) opens with its own blank line too.
2026-10-19 22:33:18 -07:00
Teknium 197c21195d fix(cli): a blank line between the user message and the first tool row
In the glyph layout reasoning and answers open under a blank line + bar, but
a turn that starts with a tool call printed its first row straight under the
user message. The first tool row after a user message now opens with the same
blank line; later rows stay tight, and a reasoning bar that already opened the
turn settles the gap so it is never doubled.
2026-10-19 22:33:18 -07:00
Teknium fa10b9cb24 fix(cli): glyph layout tool rows keep the classic tool emoji
The glyph layout replaced every finished tool row's emoji (📖 read, 💻 terminal,
🐍 exec...) with a plain ●, and its "preparing" spinner text dropped the emoji too.
Rows now lead with the same emoji the classic ┊ row shows (skin tool_emojis
overrides included); a failed entry still swaps it for the red ✗.
2026-10-19 09:50:06 -07:00
Teknium 2aef21193c fix(cli): glyph layout keeps classic parity for the status line, spinner and reasoning
The glyph layout had dropped things the classic CLI shows:

- the status line rendered a private default subset: context detail, cache
  hit, latency, tokens/s, duration and prompt/idle timers were gone. It now
  renders the classic segments unchanged (same fields, tiers and
  display.status_bar.fields filter) plus cwd and key hints when they fit.
- the composer rule stripped the kaomoji/tool emoji and lost the streamed
  token count (the classic spinner suffix). Both are back.
- reasoning no longer streamed: it was buffered and collapsed to a single
  summary line. It streams live again as in classic, under the dim bar,
  closed by the summary line; post-hoc reasoning keeps classic first-10-lines.
- unset busy_input_mode silently switched to steer in this layout. It is
  interrupt in both layouts again (Tab still queues).
2026-10-19 07:12:58 -07:00
Teknium 9dd4a23bbc fix(cli): bring back the separator bars in the glyph layout
The glyph transcript dropped the bars between turns, and the user message,
reasoning and answer ran together. An accent bar is back above each user
message and answer, and a dim bar above each reasoning block. They are 40
cells wide like the classic user rule, so they never re-wrap on resize.
2026-10-19 07:12:58 -07:00
Teknium e1ac43a4cc fix(cli): keep the full welcome banner in the glyph layout
The launch banner (logo, tools, skills, session) is part of the CLI identity: both layouts now
print it exactly as main does. show_banner and the /clear redraw are back to main byte-for-byte;
the two-line header is removed.
2026-10-19 07:12:58 -07:00
Teknium c5a4a20bcd fix(cli): review findings on the glyph layout
- Batch calls mark the entry that failed: tool rows come from typed (verb, detail, failure)
  parts built with the same per-entry suffix logic as the ┊ renderer.
- A fast failure keeps its reason ([exit 1]); only the timing waits for 0.1s.
- Tab-to-queue submits directly with mode="queue" instead of re-entering Enter, whose paste
  and backslash-continuation rules could turn the key into a newline.
- The footer keeps the battery reading and vim mode label.
- Non-streamed answers print with soft wrap, so the terminal re-flows them on resize.
- _Panel moves to its own cli_panel module (cli_render stays under 1,000 lines).
- busy_input_mode resolution lives in one function, tested through load_cli_config.
2026-10-19 07:12:58 -07:00
Teknium 50d5dbf834 fix(cli): keep the welcome line under the glyph header
The skin welcome line is the readiness marker the live PTY suites wait for (and skins brand it),
so the glyph layout keeps it; the header drops its now-redundant /help hint and shows no version
for an unstamped git.<sha> tree.
2026-10-19 07:12:58 -07:00
Teknium e2bb757eba feat(cli): glyph transcript, status line under the composer, two-line header
The classic CLI's scrollback was built from width-sized frames (reasoning and
answer boxes, 40-column rules around every message), so a terminal resize
re-wrapped and garbled everything already printed, and the status bar sat above
the input where the spinner row made the composer jump.

display.cli_layout (new, default "modern") switches to a grammar where every
scrollback row starts with one glyph and never depends on the width:

  ❯ user message            ∴ reasoning collapsed to "Thought for Ns · title"
  ● Verb target  0.2s       ✗ failed call in red, with its exit code
  │ diff under its row      ☤ Hermes answer label, no frame
  ─ turn summary · time

Width-dependent chrome moves into prompt_toolkit's live region: the composer's
top rule carries the spinner, current activity and elapsed time (left) and the
session title (right); the status line renders under the composer with model,
context gauge, live badges (stash, background work, goal, YOLO) and cwd/branch
on the left and the keys that work right now on the right. Launch prints a
two-line header instead of the full banner.

With busy_input_mode unset, the modern layout steers (Tab queues); classic keeps
interrupt. display.cli_layout: classic restores the previous look unchanged.

Also: panel rows wrap per source line, so a heredoc command no longer breaks the
approval panel's right border (both layouts); docs drop the stale claim that
classic chat always queues (steer and interrupt reach the gateway).
2026-10-19 07:12:58 -07:00