Name sessions from the CLI, rename them in the app, and fix the team audit key - #165
Merged
Merged
Conversation
added 5 commits
September 15, 2026 17:40
shell --name <name> labels a session as it starts. The name is published to the account, kept in the local record, and shown on the start card and in shell list, beside the command it runs. shell ls lists the sessions in the account from every linked machine, which shell list cannot: it only knows this one. Ended sessions are counted and hidden until --all, and --json prints the records without passwords. The auto-close pre-parser learns --name so a value of its own is not mistaken for the command.
The pencil beside the name on the session page opens it for editing; a blank name falls back to the command. The owner, an assignee, or a team admin may rename, which is the same rule the service applies. A name is no longer lost when the machine re-registers the session: a restart that sends none keeps the one it has, so a persistent session does not undo a rename on every restart.
The bordered dark panel is gone: the pane is transparent, the emulator's canvas is clear, and its palette follows the app's own light and dark themes, including a change while a session is open. The standard ANSI colors assume a dark background, so the light palette darkens each one to the app's ink weights rather than leaving them illegible on paper. The renderer choice moves out of the tab strip into a tab hanging from the tab line over the terminal's top-right corner, where it covers padding rather than text, and is shown only while a terminal is.
A member who opened the copy of the team's audit key a teammate sealed for them re-sealed it to themselves by deleting the stored copy and adding it back. The service takes copies only from a member who holds one, so the second step was refused and the error swallowed: on the next check the member held nothing, the audit log went back to sealed, and they never passed the key on. Only the key's maker kept a working copy. The copy is now replaced in one step, so the key spreads to everyone and opens the log by itself once a vault is unlocked, with nothing to paste. The vault on the Account page lists teammates still waiting for a copy, and asks before sealing the key to a teammate whose vault key has changed, since sealing to a swapped key would hand over the whole log. The audit log itself now says when a locked vault, or no vault, is what stands between the reader and the log, and offers to unlock it there.
An ordinary command brings the machine daemon up by running this executable again with "daemon". Under go test that executable is the test binary, which runs the whole suite instead, whose tests start daemons of their own. A test that reached run() without pointing SHELL_ONLINE_CONFIG somewhere of its own read the developer's real credentials and set that going: hundreds of processes, and a machine too busy to type into. ensureDaemon and restartDaemon now refuse to launch a .test executable, and the package's TestMain exits at once when the test binary is started as a subcommand and points credentials at a file that does not exist.
Alexgodoroja
force-pushed
the
session-names-and-audit-key
branch
from
September 16, 2026 00:41
b17ded5 to
3b60184
Compare
The renderer tab overlapped the first row of terminal output at its right end, which the comment beside it said it would not: measured at the browser, the tab reached 3px into the row across the last 29px of it. The tab is shorter and the grid starts below it, with 5px to spare. shell ls asked for every session an account has ever published. Nothing prunes that table, and the CLI reads a bounded body, so an account with a few thousand sessions would have got a truncated reply and a decode error for every call from then on, with nothing to say why. The newest 500 are sent. A name is cleaned of the controls that would rewrite the row it is printed in: a name ending in U+202E reverses everything after it, so a finished session could read in a list as something else. The service and the CLI now agree on what a name may contain, and a name chosen in the browser is cleaned rather than refused: validating it on the machine meant a browser could queue a session that could never start. Accepting a teammate's changed vault key pins the key whose fingerprint was shown, not whatever the service reports by the time the button is pressed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Naming sessions
shell --name <name> <command>labels a session as it starts. The name is published to the account, kept in the local record, and shown on the start card, inshell list, and in the web app. A persistent session that restarts without--namekeeps the name it has, so a rename made in the browser is no longer undone on every restart.shell lslists the sessions in your account from every linked machine, whichshell listcannot: it only knows this one. It shows name, status, uptime, machine, and command. Ended sessions are counted and hidden until--all;--jsonprints the complete records and never a password. It needs a linked machine, and to share a program calledls, put--first.The terminal
The bordered dark panel is gone. The pane is transparent, the emulator's canvas is clear, and its palette follows the app's light and dark themes, including a change while a session is open. The standard ANSI colors assume a dark background, so the light palette darkens each one to the app's ink weights rather than leaving them illegible on paper. The renderer choice moves out of the tab strip into a tab hanging from the tab line over the terminal's top-right corner, where it covers padding rather than text.
The team audit key
Every member of a team can now read the audit log without pasting anything.
A member who opened the copy of the key a teammate sealed for them re-sealed it to themselves by deleting the stored copy and adding it back. The service takes copies only from a member who holds one, so the second step was refused and the error swallowed. On the next check that member held nothing, the log went back to sealed, and they never passed the key on; only the key's maker kept a working copy.
PUT /api/team-key/sharenow replaces a member's own copy in one step, so the key reaches everyone and an unlocked vault opens the log by itself.The vault on the Account page lists teammates still waiting for a copy, and asks before sealing the key to a teammate whose vault key has changed, since sealing to a swapped key would hand over the whole log. The audit log says when a locked vault, or no vault, is what stands between the reader and the log, and offers to unlock it there.
Not starting a daemon from a test binary
An ordinary command brings the machine daemon up by running this executable again with
daemon. Undergo testthat executable is the test binary, which runs the whole suite instead, whose tests start daemons of their own. A test that reachedrun()without credentials of its own read the developer's real ones and set that going: hundreds of processes and a machine too busy to type into.ensureDaemonandrestartDaemonnow refuse to launch a.testexecutable, and the package'sTestMainexits at once when the test binary is started as a subcommand and points credentials at a file that does not exist.Checks
go test ./...,npm run typecheck, the app's 918 tests, the root suite, and the landing/formula checks all pass. The UI was driven in a browser against a local relay with realshellsessions: naming from the CLI, renaming from the session page, the terminal in light mode with a full ANSI color sample, and the audit and account pages.