Skip to content

UX changes: home navigation and consistent message-box controls - #1071

Draft
ZeroPoint95 wants to merge 25 commits into
devfrom
claude/codeaf-autonomy-control-2f07c4
Draft

ZeroPoint95 wants to merge 25 commits into
devfrom
claude/codeaf-autonomy-control-2f07c4

Conversation

@ZeroPoint95

@ZeroPoint95 ZeroPoint95 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Home and conversation screens used different message-box layouts, and home mixed navigation targets with information-only panels. This change gives them consistent controls and makes home clearer to scan and navigate.

UX changes

  • Clearer home panels: threads lists conversations; tasks combines live work with root tasks begun or finished in the last 24 hours, newest first. Task rows open their task page. Needs-you descriptions identify their thread and retain visible answer controls even when the field has few rows.
  • Predictable home navigation: arrows stay in the field, Right opens row actions, and Left closes them. Up no longer walks onto the tab bar. Projects and spend rows are read-only; headings that open a place underline under the pointer, while informational headings remain dim.
  • Consistent message boxes: only home and conversation/task surfaces retain their appropriate boxes. The seam carries model, effort and approvals; conversation telemetry sits on its right, while home shows project: <path>. Model names stay bold and bright, provider names sit beside them, and effort uses model:effort without a badge. Project paths preserve their absolute root or home-directory tilde and truncate on the right.
  • Simpler hints: shared controls follow effort, approvals, chats and commands. Home also names its project control; conversations put space space home last. Home omits pick, Enter, Ctrl+O and Tab hints, conversations omit Tab, and home model selection uses /model or a click rather than Alt+O. The task panel's hide control sits above + /task.
  • Live approvals and accurate provider context: Alt+Y or the approvals chip cycles asks, guardian and YOLO; /approvals and /yolo also set named postures. Conversation choices persist and work over remote connections. Home draft choices carry into the conversation they open. Reattaching to an engine replays the last serving provider instead of leaving the seam blank until another answer.

Modifiers display as Option on macOS. Manuals and the change entry describe the resulting behavior.

Validation

  • make test-quick: build, vet, formatting, packed manual, change-entry validation, manual gates and repository laws.
  • 553 focused UI tests covering home panels/navigation, message-box controls and task-panel behavior.
  • 14 focused session tests covering approvals and provider replay.
  • TMPDIR=/private/tmp go test ./cmd/codeaf/; go test ./internal/remote/.
  • Tagged terminal suite compiles with go test -tags=e2e -run '^$' ./internal/e2e/; live-model terminal tests were not run.
  • make build; merged binary reports 67639fba2.

The launch suite's two existing /var versus /private/var path assertions also fail on the incoming branch with the default macOS temp path. A short canonical temp directory avoids that fixture mismatch and the Unix socket path-length limit.

ZeroPoint95 and others added 3 commits September 16, 2026 17:13
… a control on the seam

The gate had an install scope (the settings rows) and a launch scope (--yolo)
and nothing a person standing in a conversation could move. The conversation
has its own posture now: `alt+y` walks asks → guardian → YOLO → asks, a press on
the ◇ cell after the thinking rung is the same step, and /approvals (alias
/yolo) prints the stops or sets one by name — ask, guardian, yolo, deny, auto.
The posture is live and sticky in meta.json, so it survives /resume;
`codeaf resume --yolo` outranks the saved word for that launch.

internal/session holds the word ([Agent.SetApprovalPosture]) and asks
cmd/codeaf's v3ApprovalGate for the finished policy, so every stop is the same
v3PolicyMode the flag builds through: exceptions, shell rules and both floors
are identical at every posture. `guardian` folds the guardian row into the
ladder; `deny` is never a stop on the wheel.

The row's YOLO badge is off the status row while the seam carries the chip and
back on it — only when the gate is open — on the frames whose seam has no chip
(the welcome, a task's page). The phone sheet says the posture at every
posture. The door crosses the wire: MethodResolvedApproval, MethodSetApproval,
Welcome.Approval and Facts.Approval, with an old engine leaving the cell a
reading and every door saying whose rules decide.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, once

#1063 gave /status and the phone sheet an `approvals` row read off the
profile's word, and the approvals chip gave them one read off the
conversation's dial; rebased together the page said the gate twice. One row
now, in the ladder's words — ask, guardian, allow, deny, what /approvals takes
— from the same resolver the chip draws from, so the cell, the badge and the
page cannot disagree. The manual says so, and the task page's heading names
the `guardian allowed` line so that question still lands there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ZeroPoint95
ZeroPoint95 force-pushed the claude/codeaf-autonomy-control-2f07c4 branch from 731dbd1 to 6372adb Compare September 16, 2026 21:17
…engine has a door

A session assembled without an approval gate has the rebuild method and refuses
it, and that refusal silenced the plain push — the person was asked twice for
one banked command (TestABankedBashRuleReachesTheRunningEngineBeforeTheAnswer).
The door is asked first now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@CLAassistant

CLAassistant commented Sep 16, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

…model, the rung and the gate

The rule above the box was three different lines. Home's said the folder
and the model; the other places said a note or a bare rule, with a
`here ~/codeaf` chip on the box row; a conversation's seam said the model,
the thinking rung and the approvals chip, each a door. `alt+y` and `ctrl+v`
did nothing outside a conversation, and the gate's word was a chip on one
screen and a badge on another.

Every place with a draft now draws the conversation's own seam over its
box: `◎ new conversation in ~/x · <model> · ⠿ <rung> · ◇ <gate>`, spelled
by the same functions the seam uses, with the same doors — `alt+o`/press
on the model, `ctrl+v`/press on the rung, `alt+y`/press on the gate,
`alt+w`/press on the folder. The pins are the draft's and ride onto the
conversation `enter` opens from any place, through the session's own
doors, off the loop. The model and the rung last as long as the window;
the folder and the gate are spent, because an open gate is a safety claim
about one conversation. The unpinned cells say what a fresh conversation
on this install would run at — the install's row folded with the model's
level, and the rows as they stand or `--yolo` — read through
session.Agent.StandingApprovalPosture and carried over the wire once at
the welcome. A place's own note takes the rule from the chords, whole,
and the draft's cells give way before it, so the foot keeps one height.

The scope chip is gone from every box row: the rule says the folder, and
the composer layer opens its task in the same folder the rule names.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ZeroPoint95 ZeroPoint95 changed the title tui3: the approvals chip — what a conversation runs without asking is a control on the seam tui3: the approvals chip, and one seam over every box Sep 17, 2026
ZeroPoint95 and others added 20 commits September 17, 2026 11:16
…d gate over its box

The room's seam said `room · esc/←← main` and nothing else; the node's
model and machine sat on the status row's identity cluster as a door, its
rung was on the panel, and the conversation's YOLO badge was drawn on a
row about work the gate does not govern. The one box a person opens to
correct running work was the one that looked least like the others.

The room's seam is the box seam now — `room · esc/←← main · task glm-5.2
· ⠿ high · ◇ on its own · via friendli` — laid out by the seam's own
ladder. The model and the rung are doors on the node while it can still
be moved (a press, or ctrl+v), through the doors the panel already used.
`◇ on its own` is a reading: a node runs every tool without asking and
has no wheel, so alt+y inside a room says so instead of moving the
conversation's gate behind a page that does not draw it. The status row
names the task alone and never the badge; the rider rides the seam.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…er come off the other places

Every place had a message box at its foot, saying `say what you want done`
under a hint that said `enter talk about it · alt+enter send it off as a
task`. On six of the seven it was a box in a slot: `enter` opened the row
under the cursor, typing on tasks went to the filter at the top of the
list, on spend the words went nowhere, and a task could be sent from a
page that could not show its answer. The owner's ruling: one box, on home.

Tasks, standing, memory, spend and search now end in their note on the
rule and their hint, with no box, no `new conversation in`, no alt+enter
and no task clause on the map. Typing still filters tasks on its control
row, searches on search (the query is the first row of the body while
there is one) and filters memory (the head row echoes the words); spend
and standing take no text. Two bare spaces still open home from a place
with nothing to type into. The shared composer, the resting-sentence and
box-on-body hooks and the tasks type-word are deleted; the foot-height
law is two shapes, home's and everyone else's.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The rule under the tasks list read `9 finished today · 191 earlier`, and
the section headings a few rows up already say what the page holds — one
figure on one frame twice. The rule is bare now and carries only
`nothing matches` while a filter has emptied the page. The reading's
tally stays as the count the headings are held against in the tests;
nothing draws it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The welcome box has no seam over it, and the status row's badge was the one
thing on that otherwise empty frame saying the gate was open: a red word in the
bottom-left corner. The owner asked for it to go. The row says nothing while
the greeting is up, at every posture; the seam and its gate cell come up the
moment the greeting goes (the first keystroke, or on the very first
conversation the first message). A frame with no greeting and no cell — an
engine with no approvals door — still carries the badge when the gate is open.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…on home and in a conversation alike

Home's foot was the rule (the draft's facts, its chords on the right), the box
and a hint; a conversation's was the rule (name, model, rung, gate, the keys on
the right), the box and the status row of numbers. The owner ruled the two
boxes should end the same way: the last row is the keys, and nothing else.

So the seam carries the facts on the left and the numbers on the right — the
bill, the meter, the state word, every law they had — and the row under the box
is the keys: the state's own, the doors at rest, and on home the draft's chords
beside its sentence. The bill and the meter are pressed on the rule now, the
home door on the keys row. The numbers never wrap: they climb the old ladder,
then the link, the badge and the question chip, and the state word is the last
thing standing; the name and the model give way only when not even that fits
beside them, and a via machine outlasts the cheap figures but not the dear
ones. A room's status-row chip is gone (the breadcrumb bar names the task);
the greeting and a frame with no rule put the state word on the keys row's
right; the phone tier keeps its deck.

The ladder is climbed lazily from one set of pieces per frame and only the
rung drawn is painted, which takes the one-screen scroll from 229 allocations
to 206.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the machine beside the model

Home's box row is `› type to search or start something new` and its foot is
keys only (`↑↓ pick · enter open · …`): the promise about typing belongs where
the typing lands, and the lowest line is for keys. The phone tier's box row
says the same sentence.

The conversation's seam no longer carries the conversation's name — it took
the room the numbers need, and the tab strip and the breadcrumb bar say it —
and nothing stands in for it. The `via <machine>` rider now rides the model
(`glm-5.3-flash · via deepinfra · ⠿ high · ◇ asks · main*`), in a room too,
so the two halves of "who is answering" read as one cell; the rung's door is
measured past the rider. The ladder's name-cutting rungs are skipped where
there is no name.

Owner rulings of 2026-09-17. Manual, change entry and the e2e word table
follow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lash (baidu)` — and stays

The seam's `· via baidu` segment becomes brackets on the model itself, whole
or nothing, in a room too: `task glm-5.2 (friendli)`. It no longer ages out
ten minutes after the last answer — who answered last is a fact until
somebody else answers — while the sheet's `served` row keeps its window,
since the figures beside its name are about one answer.

The direct-service check is asked of the conversation's own model (the node's
in a room) rather than of the empty id the seam passes as the row's spelled
name. Two regression tests pin the two rulings. Manual and change entry follow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…swered last

A window opened onto a conversation the host was already holding drew the
model and no machine until the next answer: the lane desk lives in the host's
process and only live news crossed. The host now keeps each conversation's
last landed sighting and puts it first on every new news outbox, with its
age on the frame (`LaneWire.AgeMS`, omitted when zero, ignored by older
peers), so the seam names the machine at once and the sheet's `served` row
files it at its true age. Rescues in flight and withdrawals are not kept.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… for it

The engine host replays a conversation's last sighting during the welcome,
which is before the surface has registered its lane reader, so the replay
was dropped and a window attaching to a held conversation still named no
machine. The desk holds the last landed sighting told while nobody was
listening and hands it to the next reader, once; a rescue in flight is not
held. Verified with the stub model over a real engine host: the second
window's seam reads `deepseek-v4-flash-latest (stub)` before any typing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nd not stood on, and no heading opens the search

`where you were` is headed `threads` and `running` is headed `tasks`, on the
grid and on the phone lane. The `threads` heading no longer opens the search
place — the box under home already searches, and /search and alt+7 still reach
the place. Nothing under `spend` is a cursor stop or answers a press: its three
lines are a new [homeReadout] row kind, so the arrows step over them and a
click on one does nothing; the heading still opens the spend place.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A panel heading that names a place — needs you, tasks, since you left, spend,
scheduled — underlines its word while the mouse is over it, so a person can
tell it is a door before pressing. The underline is on the word alone, never
the count, the explainer or the clause; projects and threads, which open
nothing, never wear it; and the pointer on a heading moves neither the cursor
nor the marked heading, which still follows the keyboard alone. The press and
the hover share one lookup of the headings the frame drew.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… needs-you rows drop the enter word, and a heading that opens nothing is dim

The tasks panel is the tasks place in miniature: every task and adaptive
run that started or landed inside the last twenty-four hours, from every
conversation, plus anything still running, newest first — a title and a
time like a row of threads, up to ten rows and then N more. Enter or a
click on a row opens the task itself through the door the tasks place's
own list takes: the live page for work this window runs, the record
inside the tasks place otherwise; since you left's task lines take the
same door. Background jobs and firing watches are not tasks and left the
panel; a firing watch keeps its row on scheduled, and its card, ctrl+e,
ctrl+x and ctrl+v follow the item there rather than the row's kind.

No row of needs you says enter (or enter on standing) at the right of its
description any more, and a question's answers are cut at three with
nothing after them. A heading that opens no place — projects, threads — is
painted dim, word and explainer alike, so it does not read as a door.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…der the pointer, and the thread named in them

The tasks heading carries no count and no explainer, and threads no
explainer: both are the bare word. A needs-you row is its amber mark, its
title and its wait at rest; what it is asking, with its answers, shows
only while the row is being read — under the pointer, or under the cursor
when nothing is pointed at — like every other description on the field.
A digit still answers the top question from anywhere. A landing's line
and a watch's line lead with the thread they belong to, spelled as
threads spells that conversation; a question's title already is its
thread. A growing row draws its second line under the pointer as well as
the cursor now, on every panel.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every needs-you description is headed by the thread the row belongs to —
thread: <name>, spelled as threads spells it — then a blank line, then the
question or the landing's files and sentence with the answers at the right,
in the description column and under the row alike. The cdot prefix is
gone. A row that names its thread grows three lines under itself; a
column too short for that gives up the two extra reserved lines before it
gives up a row, and lets the rows under a read row move down for the
moment instead.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…projects is read and not pressed

← and → no longer cross home's columns: → opens the row's own strip and ←
closes it, on every column as at one, and the foot is the design's
sentence alone (it named ctrl+o open folder while the strip was out of
the arrow's reach; the chord still works). ↑ off the top row of home stays
there rather than climbing onto the tab bar, which is reached by a press,
tab or a chord; every other place keeps the walk. The projects heading
carries no explainer, and the panel has no interactivity left: its rows
are not cursor stops, a press on one does nothing, and the enter that
started a conversation in the folder and the strip that offered its chats
and its folder are gone — ctrl+t on a row is the way to a new chat in a
folder.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ZeroPoint95 ZeroPoint95 changed the title tui3: the approvals chip, and one seam over every box UX changes: home navigation and consistent message-box controls Sep 18, 2026
@ZeroPoint95
ZeroPoint95 marked this pull request as draft September 18, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants