Skip to content

feat: rename a session from the command line and from an agent's tools - #343

Merged
omartelo merged 1 commit into
mainfrom
session-rename
Aug 21, 2026
Merged

omartelo merged 1 commit into
mainfrom
session-rename

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

Renaming a card was the one session operation only the window could do. This adds it to the two surfaces outside it.

$ lich rename auth-fix "the login bug"
Renamed "auth-fix" to "the login bug".

What is new

  • spawn.Rename — resolves a session by either of the names it answers to (the resolver close already had), writes through store.RenameSession, and emits the event the auto-applied ai-title already emits. That last part is why the card relabels live with no new frontend handler: the window's answer to both is the same, so a second event name would have bought a second handler saying it again.
  • lich rename [--project <name>] [--json] [<session>] <label> — one argument renames the session the command runs in, two rename another one. The one-argument form is what an agent has: sessions shows it every session but its own, so it knows what it is doing long before it knows what its card is called.
  • rename_session — the same call as an MCP tool, session optional.
  • The name becomes the user's on every surface: renaming clears the row's label_auto, so the provider's own auto-title never overwrites it again.

One rule the window does not have

A name another session in that project already holds is refused rather than written. Two sessions under one label is the one thing lich send cannot resolve, and the guard is also what turns a forgotten second argument (lich rename docs meaning to rename docs) into an error instead of a silent self-rename. The window keeps no such rule — the user is pointing at the card they mean, and can see the other one.

Along the way

findSession is now a plain resolver. Whether the caller's own session is a legal answer belongs to the caller — a close refuses it, a rename is mostly asked for it — so the refusal moved into Close, which is where it finally got a test.

Provider symmetry

Claude Code, Codex, Crush and omp are handed lich's own MCP server, so the tool is in their list on the next spawn. opencode defines each tool itself in omartelo/lich-plugin (it cannot register an MCP server from a plugin), so there the tool arrives with that repo's next release — implemented in lichdotdev/lich-plugin#19, and written down as a ceiling here. lich rename works on opencode like anywhere else; it is discovery that lags.

Test plan

  • gofmt -l . and go vet ./... clean
  • go test ./... green — new: spawn.Rename (target, self, taken label, recased own label, empty name, no session to fall back on, a failed write announcing nothing, ambiguity narrowed by project), Close refusing the session it was asked from, the argv order over the real dispatcher for both lich rename forms, the rename_session tool's arguments and its no-target form, and the arity guard
  • pnpm check, pnpm test (1034), tsc + vite build clean
  • lich help lists the command

Renaming a card was the one session operation only the window could do.
spawn.Rename is the same rename from outside it: it resolves a session by
either of the names it answers to (the resolver close already had), writes
through store.RenameSession — so the row's label_auto is cleared and the
provider's auto-title never overwrites the name again — and emits the event
the auto-title already emits, which is the whole reason the card relabels
live with no new frontend handler.

`lich rename "the login bug"` renames the session the command runs in;
`lich rename auth-fix "the login bug"` renames another one. The one-argument
form is what an agent has: `sessions` shows it every session but its own, so
it knows what it is doing long before it knows what its card is called. The
`rename_session` tool is the same call.

A name another session in that project already holds is refused rather than
written: two sessions under one label is the one thing `lich send` cannot
resolve, and the guard is what makes a forgotten second argument an error
instead of a silent self-rename. The window keeps no such rule — the user is
pointing at the card they mean.

findSession is now a plain resolver: whether the caller's own session is a
legal answer belongs to the caller, so the refusal to close it moved into
Close, which is also where it finally got a test.
@omartelo
omartelo merged commit 0094a94 into main Aug 21, 2026
4 checks passed
@omartelo
omartelo deleted the session-rename branch August 21, 2026 22:35
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.

1 participant