docs(cli): ws attach cannot hold what it claims to take

`tty7 ws attach <ws>` answers `{"attached": "<id>", "took_over_from":
null}`, and `tty7 ws ls` shows the workspace unattached a moment later.
Both are correct: an attachment belongs to the connection that made it,
and this command's connection ends with the command.

A caller has no way to tell that from the reply. An agent reading
`attached` reasonably believes it now holds the workspace, and the next
`ws ls` says otherwise with nothing to explain the difference.

So say it. The claim does not outlive the process, that is not a
failure, and what does last is the displacement: the previous holder has
been told, and a dedicated one has been hung up. `took_over_from` is the
part of the reply worth acting on.

Behaviour unchanged — this is the same reasoning the `Attachment` type
already carries ("an attachment belongs to a live connection, and one
read back at boot would name a holder that no longer exists"), said
where the person running the command can see it.

Also checked while auditing, and sound: `tty7 <PATH>` already stats the
directory and refuses a file (`resolve_gui_path`), `ws stop` says "(not
implemented yet)" in its own help rather than only when run, and repeat
`ws detach` is idempotent on purpose for wire-compatibility reasons the
handler documents.
This commit is contained in:
l0ng-ai
2026-08-16 07:37:53 +08:00
parent 9aaf8e28e0
commit 32f893b3b1
+11 -1
View File
@@ -397,7 +397,17 @@ pub enum WsCmd {
ws: String,
},
#[command(about = "Become the workspace's controlling client")]
#[command(
about = "Become the workspace's controlling client",
long_about = "Become the workspace's controlling client, and displace whoever held \
it — `took_over_from` names them.\n\n\
An attachment belongs to the connection that made it, and this \
command's connection ends with the command. So the claim itself does \
not outlive the process: `tty7 ws ls` will show the workspace \
unattached again a moment later, and that is not a failure. What \
lasts is the displacement — the previous holder has been told, and a \
dedicated one has been hung up."
)]
Attach {
#[arg(value_name = "WORKSPACE")]
ws: String,