Skip to content

Fix shell-opened titles and recover task-only conversations - #1667

Merged
AbirAbbas merged 9 commits into
devfrom
zeropoint95/shell-conversation-titles
Sep 29, 2026
Merged

AbirAbbas merged 9 commits into
devfrom
zeropoint95/shell-conversation-titles

Conversation

@ZeroPoint95

@ZeroPoint95 ZeroPoint95 commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Changelog

  • Keep shell-command previews literal; wait for the first ordinary answer before naming shell-opened chats.
  • Keep /senior-dev and /task conversations in /resume and Home after abrupt exits, using their saved task brief.
  • Protect saved tasks from empty-conversation cleanup; add regressions and update the manual.

Fixes #1663. Also addresses review item 5 on #1674.

@ZeroPoint95
ZeroPoint95 marked this pull request as ready for review September 29, 2026 00:23
AbirAbbas added a commit that referenced this pull request Sep 29, 2026
The live Home row and the tab still fold repeated spaces in a shell
command; only saved rows keep them. And the namer uses the first ordinary
message, not an exchange, because naming starts before the reply exists.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AbirAbbas

Copy link
Copy Markdown
Collaborator

Taking over: I pushed two doc commits. There's also one decision for you before this closes #1663.

I checked this by hand in the real binary on both roads, plain codeaf and codeaf chat --no-host, against a dev build for comparison:

  • A conversation that has only run ! commands now shows the command exactly as typed on Home and in /resume, including after a restart. Dev drew ! Ls -La.
  • Turns that only run shell commands make no title call.
  • After an ordinary message, the shell line no longer feeds the name. Dev named ! echo sk-test-123 plus a question "testing echo command with prefix sk".
  • Titles saved by a dev build still load.

Pushed:

  • 0d3df4d43 manual: the /resume section still said every name is title-cased and cut to seven words, and the naming page said naming starts with the first message. Both now describe how a ! opening is named.
  • dd20031e5 change entry: the live Home row and the tab still fold repeated spaces; only saved rows keep them. The name comes from the first ordinary message, not from the exchange.

Decision for you: #1663's acceptance says the name comes from "that message and its answer". But naming starts the moment the ordinary message is sent, so the namer only ever sees the question. After a shell opening, that question usually refers to the output, and the names came out vague or wrong:

  • In one short sentence, what did that command print? was named "generated first message response" on the engine road and "command print output question" with --no-host.
  • Summarize that git status output in one sentence. was named "git status shows modified tracked files", while both the output and the answer said the tree was clean.

You could make startTitleLocked wait when the opening skipped ! turns and no reply exists yet, and name at the end of that turn instead, as the maybeTitle path already does. The cost is that the reply may quote shell output. Or ship as is and track this in a follow-up. Your call.

Smaller, optional:

  • A pasted tab in a ! command is stored raw in meta.json. The row still draws fine, but mapping control characters to spaces in the shell branch of placeholderTitle would keep the file clean.
  • TestShellOpeningNamesStayLiteralOnHomeAndResume checks chatTabName, but the tab is drawn through conversationName → promptName, which folds spaces.
  • The comments above placeholderTitle and openingName still describe the old seven-word rule. openingName also returns a long shell line unclipped, so the "resumed ·" line wraps.
  • resume.go puts the session import in the standard-library group.

CI was green on 9b171a066. The push adds only Markdown.

ZeroPoint95 pushed a commit that referenced this pull request Sep 29, 2026
The live Home row and the tab still fold repeated spaces in a shell
command; only saved rows keep them. And the namer uses the first ordinary
message, not an exchange, because naming starts before the reply exists.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ZeroPoint95
ZeroPoint95 force-pushed the zeropoint95/shell-conversation-titles branch from dd20031 to e5579fb Compare September 29, 2026 16:35
ZeroPoint95 and others added 6 commits September 29, 2026 12:53
…page

The /resume section still said every name is title-cased and cut to seven
words, and the naming section still said naming starts with the first
message. A `!` command is now shown exactly as typed and skipped by the
namer, so both pages say so, and the shell section states that naming
starts before any reply, so a follow-up such as "what did that print?" is
named from its own words.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The live Home row and the tab still fold repeated spaces in a shell
command; only saved rows keep them. And the namer uses the first ordinary
message, not an exchange, because naming starts before the reply exists.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ZeroPoint95 ZeroPoint95 changed the title Fix conversation titles after opening shell commands Fix shell-opened titles and recover task-only conversations Sep 29, 2026
@ZeroPoint95
ZeroPoint95 force-pushed the zeropoint95/shell-conversation-titles branch from e5579fb to 8d87494 Compare September 29, 2026 17:01
AbirAbbas and others added 2 commits September 29, 2026 13:12
Since naming after a `!` opening waits for an answered question, every
later user-role message replaced the question. The memory, volatile and
team notes land in that role between the person's question and the
answer, and a wake's `while you worked:` delivery lands there on a
shell-only conversation, so either one became what the conversation was
named from. firstExchangeLocked now skips them with the predicate the
compacted summary already used to find the person's own messages, shared
as sessionNoteLocked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d preview

A partly answered, interrupted question names the conversation from that
exchange when the next message is sent; only a question with no answer at
all is skipped for the next answered one. The /resume paragraph said a
shell name is shown exactly as typed while it is clipped to fit, and two
long lines are rewrapped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AbirAbbas

Copy link
Copy Markdown
Collaborator

Taking over (round 2): I checked the naming change (447436ed7) by hand in the real binary on both roads. After ! git status or ! ls, a follow-up like "summarize that output" is now named from the question and its answer. The names match the output: dev gave "git status shows modified tracked files" on a clean tree, and this branch gives "clean working tree on master". A normal chat is still named from the first message right away, a !-only conversation stays literal, and an interrupted first turn followed by a completed one still gets named.

Pushed:

  • ae3582c0b session: after a shell opening, every later user-role message replaced the question, including codeaf's own memory and work notes and while you worked: deliveries. One real --no-host run sent a "work you handed off landed done" note to the namer as the question. firstExchangeLocked now skips notes codeaf wrote, using the same check the compaction summary uses (shared as sessionNoteLocked). Tests were added, and they fail on the previous head.
  • dae7691f1 manual: a partly answered, interrupted question names the chat from that exchange at the next message, and the /resume shell name is shown as typed, clipped only to fit.

For you:

  • The answer can quote shell output, and it did: ! echo sk-test-123 plus "what did that print?" was named "user asks about command output sk-test-123". The manual documents it. Your call whether that's acceptable.
  • 8d8749485 (task-only conversations in /resume and Home) is new scope. It's being reviewed now before merge.

The /resume page said the list never writes and never creates a file.
Reading a task-only conversation's saved brief opens its plan store
read-only, and on a store that was closed cleanly that leaves
plandb.db-wal and plandb.db-shm beside it. The paragraph on task-only
conversations also said a title replaces the brief as the preview, but
the brief stays the row's description until the person sends a message.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AbirAbbas

Copy link
Copy Markdown
Collaborator

Taking over (round 3): I checked 8d8749485 by hand on both roads. After a /task and an abrupt exit, dev drops the conversation from Home and the sessions list, and this head lists it. The cleanup change also fixes a real loss on dev: a task-only folder could be removed along with its plandb.db, or reused as the next launch.

Pushed:

  • bab38b20d manual: the /resume page said listing "never writes and never creates a file". But reading a task-only conversation's brief leaves plandb.db-wal and plandb.db-shm beside a cleanly closed store (reproduced). The page also now says a title replaces the row's name, while the brief stays as its description.

Follow-ups for you, not blocking:

  • Listing now opens SQLite once per task-only conversation every time the list is read. That happens on the launch path and on every Home refresh. With 200 empty and 20 task-only folders, Home's walk goes from 2.3 ms to 11.5 ms and /resume's from 3.3 ms to 16.9 ms, and no perf test pins it. Stamping the brief and start time into meta.json when the task starts (or caching by the store's mtime) would keep listing out of the store and remove the side files too.
  • Nit: a dangling tasks symlink keeps an empty launch folder forever, because HasSavedTasks treats any Lstat error as saved work.

@AbirAbbas AbirAbbas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed and hand-verified over three rounds; see the comments above.

@AbirAbbas
AbirAbbas merged commit 7b8b69a into dev Sep 29, 2026
4 checks passed
@AbirAbbas
AbirAbbas deleted the zeropoint95/shell-conversation-titles branch September 29, 2026 18:23
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.

A conversation opened with a ! command is named after the shell line, title-cased

2 participants