Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/changes/unreleased/1893-quiet-completions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
kind: changed
title: task and process endings group inside worked disclosures
pr: 1893
surface: [chat, engine, docs]
invalidates:
- "Task endings and crew receipts used to accumulate in chat and return on tab switches. Routine completions now settle under their original request’s worked disclosure with links to results and logs, while decisions and actionable stops stay visible."
- "The sidebar used to list completed tasks and processes. It now shows active work and decisions; click Tasks for retained results or use /processes for process history and logs."
- "Crew models, estimated and actual spend, and the stronger retry action used to live in a separate transcript receipt. They now live with the selected task result, including restored routed runs."
- "Runtime completion notes used to replay as extra conversation rows. New receipts carry their presentation audience through compaction and reopen; exact standalone older receipts are grouped without rewriting their journal; uncertain ownership stays in a background-work disclosure and ambiguous mixed messages remain visible."
- "A focused terminal previously had no temporary completion signal for work out of sight. A six-second coalesced notification now offers View work and dismiss using existing screen space, without replaying notifications for restored history."
---
8 changes: 8 additions & 0 deletions internal/e2e/chatclean_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,11 @@ func cleanChatHasAnswer(screen, want string) bool {
line = before
}
}
// An open sidebar is outside the conversation too. Only the padded
// layout seam qualifies; an answer containing a literal rule does not.
if seam := strings.Index(line, " │"); seam >= 0 {
line = line[:seam]
}
line = strings.Trim(strings.ReplaceAll(strings.TrimSpace(line), " / ", " "), ". ")
if line == want {
return true
Expand All @@ -428,6 +433,9 @@ func TestCleanChatAnswerIgnoresOnlyTheRailGutter(t *testing.T) {
}{
{" Still ready for review", true},
{" Still ready for review. ❮", true},
{" Still ready for review. │ Tasks", true},
{" Still ready for review│", false},
{" Still ready for review │ quoted separator", false},
{" Still ready for review❮", false},
{" Still ready for review but not yet", false},
{" › Still ready for review", false},
Expand Down
17 changes: 12 additions & 5 deletions internal/manual/chat/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -2226,8 +2226,15 @@ tabs included, and opening a row brings the tab and its draft back too.

## Dismiss task notifications

`/dismiss` hides settled task notifications in the current conversation window.
`/dismiss undo` restores them. With an empty message box, select a task
notification and press `delete` to dismiss just that notification. Pending
`your call` decisions stay visible. Dismissal does not stop work, accept a
result, delete a task, or remove its output from Sessions.
Routine task completions stay in Tasks automatically, including older conversations.
`/dismiss` hides manually dismissible settled notifications; `/dismiss undo` restores
those dismissals without making routine task completions appear in chat. Pending
`your call` decisions stay visible. Dismissal does not stop work, accept a result,
delete a task, or remove its output. Open Tasks to read results and run details.

## Process history and logs — /processes

`/processes` opens this conversation's running and finished processes. Click a row or
select it with the arrow keys and press Enter to read its log. `/processes <id>` opens
a known process directly. Escape returns from a log to the list, then back to chat.
The sidebar itself only shows running processes, without a completed count.
10 changes: 10 additions & 0 deletions internal/manual/chat/how-tasks-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -3406,3 +3406,13 @@ a failed observation, never evidence that a page was read.
A child reads the overall ask for requirements it owns. Delegation instructions
for the parent remain the parent's coordination work; a child repeats them only
when its own work order assigns coordination.

## Where does my task work

An ordinary code task works in its own copy of the repository the work is about,
on its own branch, so you can continue editing your working copy. Its task page
and history record show the resolved folder. A quick task instead works in the
conversation's own folder, with file reservations rather than a separate branch.
If the request explicitly names a plain folder outside a repository, that exact
folder is used. The resolved place is a fact on the task, not guessed from your
terminal's current folder after the task has started.
17 changes: 17 additions & 0 deletions internal/manual/chat/keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -3706,3 +3706,20 @@ Press `alt+k` (`opt+k` on macOS) to open the chats menu from a conversation.
It lists the same open tabs as Home, in the tab strip's order. Select one and press
Enter. Closed conversations are behind the menu's fold; Home also keeps up to
three recently closed conversations dimmed below the open list.

## How do I make this one chat think harder

Press `alt+e` (`opt+e` on a Mac) or click the effort word beside the model above
the message box. It cycles `auto`, `low`, `medium`, `high`, `xhigh`, `max`, then
back to `auto`, without changing your draft. `/effort high` sets a rung directly.
This changes the current conversation's effort; it does not move other chats or
a task that has already started.

## How do I stop a task from the chat without opening it

With an empty message box, press `x` when exactly one stoppable task row is
visible. With more than one, press `alt+t` (`opt+t` on a Mac), select the task
in the roster, and press `x`. Neither route opens the task room. The stop card
opens on `keep going`: choose `stop it` and press Enter to confirm, or click
that answer. Escape cancels the card. A half-typed message is preserved; with
text in the box, an ordinary `x` types the letter instead.
19 changes: 13 additions & 6 deletions internal/manual/chat/models-and-cost.md
Original file line number Diff line number Diff line change
Expand Up @@ -1105,10 +1105,9 @@ A task you hand off does not run on it. Each task gets a **crew** — a worker,
a checker — picked for each task from what kind of work it is; `/crew` shows the seats and
`/crew pin` fixes one.

What a task costs is on its crew line. When it starts, the line gives the estimate —
`task 2 crew · bugfix · worker glm-5.3-flash (openrouter) · checker glm-5.3-flash · est $0.013`
— and when it lands the line moves to the end of the conversation with what it actually
cost beside the estimate. Every task is held to the per-task limit, and all crews together
What a task costs is on its result page in Tasks, together with the routed crew,
its estimate and actual spending. Starting or finishing does not append a separate
crew receipt to chat. Every task is held to the per-task limit, and all crews together
to the crew daily cap when one is set (both on `/crew`'s cap row). `/cost` says what this
conversation has spent, and `/spend` the whole machine.

Expand All @@ -1121,8 +1120,8 @@ conversation has spent, and `/spend` the whole machine.
3. the crew's **worker** — your pin, or the model the crew picked for this task;
4. the model you are talking to, only when nothing above answers.

The task's crew line, its row on the roster, its room's status line and its finished card
all name the model it actually ran on. The seats are settled when the task starts, so
The task's result details, its row on the roster and its room's status line
name the model it actually ran on. The seats are settled when the task starts, so
changing the crew — or `/model` — half way through does not move work already going. A
second task handed off while one is still running joins it and rides its crew.

Expand Down Expand Up @@ -4286,3 +4285,11 @@ the earlier call and its result are carried as readable conversation text. The
model can discuss that result, but it cannot make a new tool call itself.
Switching back to a tool-capable model restores the original tool-call history
on its request.

## Where are the logs

The model-call log is `~/.codeaf/logs/calls.jsonl`, under `CODEAF_PROFILE_DIR` if
you moved the profile. Run `codeaf logs` to read recent calls, `codeaf logs --follow`
to follow them, or `codeaf logs --path` to print the exact path. Each call records
its model, timing, token use and cost. Background process output is separate: open
`/processes` in the conversation and choose a process to read its log.
11 changes: 11 additions & 0 deletions internal/manual/chat/running-from-the-terminal.md
Original file line number Diff line number Diff line change
Expand Up @@ -1379,3 +1379,14 @@ its final totals. With no receipt outstanding, it adds no receipt wait to the
ending. Otherwise it waits at most the provider's existing receipt deadline and keeps
the figures already received when a receipt cannot be settled. An incomplete
receipt therefore reports the work's paid calls as well as its failure reason.

## What background processes are still running

Run `codeaf services` in the terminal to list long-running services started here
and not yet stopped, with each name, status, age, health check and log path.
`codeaf services stop <name>` stops a named service. If none are running, the
command says `nothing is being kept running.`

For the current chat's background commands, watches or renders, use `/processes`
in that chat. Click a process to open its log. The sidebar shows only running
processes; finished logs remain available on demand without an ended count.
52 changes: 18 additions & 34 deletions internal/manual/chat/screen.md
Original file line number Diff line number Diff line change
Expand Up @@ -3159,28 +3159,26 @@ quiet ones. This is its Tasks view; *What is that column on the right* has the w
and the team manager page has its Traffic view.

```
Tasks 14 · Traffic 3 new alt+l
Tasks · Traffic 3 new alt+l
? Port the parser · your call · nobod…
✕ parser bench incomplete
──────────────────────────────────────
Running 4
⠙ rebase the parser onto dev 2m
⠙ bench the lexer at p99
Queued 3 ▸
Done 6 ▸
+ /task
```

- **The header** is the column's two words in a chat in a team, one word elsewhere. The
word in front is bold ink and the other is dim, and each keeps its count; a count of `0`
is dim, and a count of new traffic, `3 new`, is in ink. The `alt+l` at the right is dim.
word in front is bold ink and the other is dim. Tasks opens history on demand, without
a completed count; new traffic, `3 new`, is in ink. The `alt+l` at the right is dim.
- **The needs-you band** is the one place with colour of its own: what is waiting on you
leads with its `?` in the needs-you amber, and a failure nobody has opened leads with its
`✕` in ordinary ink. A thin dim rule closes it. With nothing waiting it is not drawn.
- **Group headings** (`Running 4`, `Done 6 ▸`) are muted with a dim count; the `▸` of a
leads with its `?` in the needs-you amber. A key or credit stop keeps its concrete remedy
visible; ordinary failures stay in task history. A thin dim rule closes it. With nothing waiting it is not drawn.
- **Group headings** (`Running 4`, `Queued 3 ▸`) are muted with a dim count; the `▸` of a
folded group and the `▾` of an open one are muted too. `Running` wears no mark, because
it does not fold.
- A **running** task's name is in ink, the body colour. **Queued, waiting and finished**
- A **running** task's name is in ink, the body colour. **Queued and waiting**
names are muted, a step quieter, and the room you are standing in is the one name in the
accent and bold, with a colour band across its whole row. The time at the right of a row
is dim.
Expand All @@ -3190,7 +3188,7 @@ Done 6 ▸
**The header and the band never scroll**, however long the list gets: they are pinned to
the top of the column and everything under them scrolls.

**Every task is one line**, running or finished. What a row used to carry underneath
**Every active task is one line**. What a row used to carry underneath
(what it is doing, what it is costing, what it waits on, the reason it is your call, the
merge word, the branch) is on the hint line while the pointer is on the row, with the whole
name first. So the column's height goes to rows rather than to a day's history. Nothing is
Expand Down Expand Up @@ -3228,22 +3226,12 @@ colour the band leans on, and where there is none the `?` still says it.

## Opening a finished row on the task column: how to see the log path of a job that already finished, and where the merge word, price or branch went

A finished task's row is one line, and the line it used to carry underneath is **on the hint
line, not deleted**. Point at the row and the hint line under the message box says the
whole of it: the whole name, then that task's own last word (`merged · $0.42` for work that
came home clean, the branch it kept, the reason it is your call), then `click opens it`.
There is no fold on a task row and no `▸` in its state cell; the cell is the task's state,
and a press on it opens the task's room like the rest of the row.
Finished tasks leave the sidebar. Click its `Tasks` heading to open their results and
history on demand. Existing outputs, reports, branches and run details remain there.
The sidebar has no Done or Ended fold and no completed-work total.

With the keyboard, `alt+t` hands the column the keyboard and `↑` `↓` walk to the row; the
room behind `enter` has everything the row does and more.

Finished work sits under `Done`, which starts folded to its heading: press `Done 6 ▸`, or
`enter` on it, to open it, and it stays open for the session.

A background job is not a finished task row: it lives in the `jobs` section, and its log
path is on the job's page. The full record of any task is on the activity page (`ctrl+.`,
`/history`).
Background processes stay in the `jobs` section while running. Use `/processes` to
open running and finished processes on demand; click a row to read its log.

## Scrolling the task column: the mouse wheel over the sidebar, and the keys that walk it

Expand Down Expand Up @@ -3286,12 +3274,11 @@ untouched empty conversation has no column until the first keystroke or a task;
empty screen* page says why.)

```
Tasks 3 alt+l
Tasks alt+l
? Port the parser · your call · nobo…
──────────────────────────────────────
Running 1
⠙ Fix the nil-map 4m
Done 1 ▸
+ /task

automations
Expand All @@ -3304,16 +3291,13 @@ automations
ctrl+. earlier
```

- **`jobs`** is this conversation's background work (a server, a build, a watch, a
render), one line — `jobs · 2 running`, `jobs · 1 running · 4m12s`, `jobs · 6 ran` —
that enter or a click opens and closes. Open, running jobs come first, then finished
ones, newest first, with an `N earlier` line counting what did not fit; a row opens that
job's page, not a chat. Zero jobs draws nothing (*Background jobs on the column*, on the
tasks page).
- **`jobs`** is this conversation's running background work: a server, build, watch
or render. Enter or a click expands it; a row opens that process's page. Finished
processes leave the sidebar, with no ended count. Their logs remain accessible.
- **The roster scrolls; the sections under it do not.** It is given what is left after
the doors, the automations rows and the jobs section are reserved.
- **An idle column draws nothing to mark an absence**: no `none` rows, no empty group
headings, no band. The header keeps its words with a dim `0`, and `+ /task` and
headings, no band. The Tasks header remains a clickable door to task history, and `+ /task` and
`+ /automations` remain as the doors. Jobs have no `+` door; a tool starts a job.
- **The `+` rows type, they do not arm.** Pressing one puts that command and a space at
the head of your message box and hands the keyboard back: plain text you can edit or
Expand Down
Loading
Loading