mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 02:29:33 +01:00
fix: address the release-prep review of #688
Give a client that fails the M-1..M-9 guard its key back (send-keys <key> as the if-shell else argument), so a browser tab's Esc then digit reaches its pane instead of being eaten, also after a TUI killed before restore(); only M-1..M-9 are accepted since the key is now interpolated into that command Test it: the unit test pins the else argument and the key check, and the real-tmux test runs cat -v in alpha and waits for the other client's Esc 2 to echo there, both before and after the TUI dies Say so in docs/architecture-invariants.md and docs/tui.md, and reword the killed-TUI and failed-arm notes that said the keys do nothing Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
311d01c52b
commit
46774b71f9
5 files changed
+39
-9
No files matched your search
+15
-2
@@ -459,6 +459,9 @@ export const TUI_SWITCH_CLIENT_PID = '@codeman-tui-pid';
|
||||
*/
|
||||
export const TUI_SWITCH_ATTACH_HOOK = 'client-attached[90]';
|
||||
|
||||
/** The keys `bindSwitchKey` binds. The key is interpolated into the binding's `send-keys` else command. */
|
||||
const TUI_SWITCH_KEY = /^M-[1-9]$/;
|
||||
|
||||
/** Linux `/dev/pts/N` and macOS `/dev/ttysNNN`. Anything else is not a client tty we will interpolate into a format. */
|
||||
const TUI_CLIENT_TTY = /^\/dev\/(?:pts\/[0-9]+|ttys[0-9]+)$/;
|
||||
|
||||
@@ -1049,6 +1052,14 @@ export class TuiClient {
|
||||
* the same `M-<digit>` inside `escape-time`, does not match. An unsafe tty
|
||||
* refuses the bind rather than falling back to an unscoped `switch-client`.
|
||||
*
|
||||
* A client that fails the guard gets the key back: the if-shell else
|
||||
* argument is `send-keys <key>`, which writes it into that client's own pane
|
||||
* exactly as an unbound key would arrive. Without it the root binding ate
|
||||
* the key, so a browser tab's vim `<Esc>2j` lost its Esc and its digit for
|
||||
* the whole attach, and for good after a TUI killed before `restore()`. The
|
||||
* key is interpolated into that command string, so only `M-1`..`M-9` are
|
||||
* accepted.
|
||||
*
|
||||
* The two commands live in the if-shell argument, where `;` is a separator
|
||||
* inside that string. A bare `;` as its own argv element would end the
|
||||
* `bind-key` and run `window-size latest` immediately, which is the bug the
|
||||
@@ -1058,7 +1069,7 @@ export class TuiClient {
|
||||
* that session follows this terminal.
|
||||
*/
|
||||
async bindSwitchKey(key: string, target: string, clientTty: string): Promise<boolean> {
|
||||
if (!MUX_NAME_PATTERN.test(target) || !isTuiClientTty(clientTty)) return false;
|
||||
if (!TUI_SWITCH_KEY.test(key) || !MUX_NAME_PATTERN.test(target) || !isTuiClientTty(clientTty)) return false;
|
||||
try {
|
||||
await this.exec('tmux', [
|
||||
'-L',
|
||||
@@ -1071,6 +1082,7 @@ export class TuiClient {
|
||||
'-F',
|
||||
tuiSwitchGuard(clientTty),
|
||||
`switch-client -t ${target} ; set-window-option -t ${target} window-size latest`,
|
||||
`send-keys ${key}`,
|
||||
]);
|
||||
return true;
|
||||
} catch {
|
||||
@@ -1081,7 +1093,8 @@ export class TuiClient {
|
||||
/**
|
||||
* Record this TUI's client pid when it attaches, then drop the hook so a
|
||||
* later client on a reused pty does not take the binding over. Best effort:
|
||||
* a failure means Alt+1..9 do nothing, which is the closed direction.
|
||||
* a failure means Alt+1..9 never switch (they reach the pane as Esc then
|
||||
* the digit), which is the closed direction.
|
||||
*/
|
||||
async armTuiSwitchGuard(clientTty: string): Promise<boolean> {
|
||||
if (!isTuiClientTty(clientTty)) return false;
|
||||
|
||||
Reference in new issue
Block a user