feat: costabs — stable tab addressing (numbers as identity labels, not positions) - #67
Conversation
…ot positions) baseline stamps user.cosTab=N + visible tab title 'N·hint' on each session and writes a session_id-keyed registry; list/peek/send resolve by live variable first, registry second — numbers survive tab reordering and window changes. send does the codex bracketed-paste double-CR submit. Born from repeated position-drift misaddressing on 2026-08-15. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzK8G6r2KLZ48fbcjn7jmZ
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzK8G6r2KLZ48fbcjn7jmZ
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5dc9e9743d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| async def iter_sessions(app): | ||
| """Yield (window_idx, tab_idx, tab, session) in visible order.""" | ||
| for w_i, window in enumerate(app.windows): |
There was a problem hiding this comment.
Use app.terminal_windows here; the iTerm2 App integrations elsewhere in this repository all expose terminal windows through that property, not app.windows. As written, every costabs subcommand reaches iter_sessions() and fails with AttributeError before it can baseline, list, peek, or send.
Useful? React with 👍 / 👎.
| async for w_i, t_i, tab, session in aiter_wrap(iter_sessions(app)): | ||
| live_by_sid[str(session.session_id)] = (w_i, t_i, session) |
There was a problem hiding this comment.
Include inactive split-pane sessions in the live map
Traverse every session in each tab when building live_by_sid. If a tab was baselined while pane A was active and the user later focuses pane B, iter_sessions() yields only B, so list reports A's still-live registry entry as DEAD; this directly breaks the advertised behavior after a window split or pane-focus change.
Useful? React with 👍 / 👎.
| echo "FATAL: iTerm2 venv python not found" >&2 | ||
| exit 78 | ||
| fi | ||
| exec "$VENV" "$HOME/code/iterm2-tab-status-codex/scripts/cos_tab_dispatch.py" "$@" |
There was a problem hiding this comment.
Resolve the dispatcher relative to the wrapper
Derive cos_tab_dispatch.py from this wrapper's directory instead of assuming the repository is checked out at $HOME/code/iterm2-tab-status-codex. For marketplace/plugin installs and ordinary clones in any other directory, the wrapper finds the iTerm2 interpreter but exec then fails because this hard-coded source path does not exist, even though the dispatcher is adjacent to the wrapper.
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzK8G6r2KLZ48fbcjn7jmZ
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzK8G6r2KLZ48fbcjn7jmZ
Tab numbers become identity labels stamped onto sessions (user.cosTab variable + visible tab title N·hint), riding iTerm's stable session_id — surviving tab reorder, window changes, and restarts. Subcommands: baseline / list / peek / send (with the codex bracketed-paste double-CR submit built in). Plus the cosdispatch stable-path wrapper. Born from repeated position-drift misaddressing on 2026-08-15; operator-requested.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UzK8G6r2KLZ48fbcjn7jmZ