-
Notifications
You must be signed in to change notification settings - Fork 6
feat: shell sessions — open terminal in session directory #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
2496766
4ea66b3
dd89c9b
6e9274f
b77101e
df439f8
acae560
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../CLAUDE.md |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| type: added | ||
| --- | ||
|
|
||
| Shell sessions: press `x` to open a terminal in any session's working directory, with real-time status indicators (green dot for running command, dim circle for idle, red X for non-zero exit). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # Shell Sessions | ||
|
|
||
| Open a plain terminal in any session's working directory without leaving brizz-code. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update legacy This doc still points users to the old app/config namespace, which can send them to the wrong location when troubleshooting shell status files. Suggested patch-Open a plain terminal in any session's working directory without leaving brizz-code.
+Open a plain terminal in any session's working directory without leaving fleet.
@@
-**Exit code tracking** uses a `precmd` (zsh) / `PROMPT_COMMAND` (bash) hook injected when the shell session starts. After each command completes, the hook writes `{"exit_code": N}` to `~/.config/brizz-code/hooks/<session_id>_exit.json`. The status poller reads this file to detect non-zero exit codes.
+**Exit code tracking** uses a `precmd` (zsh) / `PROMPT_COMMAND` (bash) hook injected when the shell session starts. After each command completes, the hook writes `{"exit_code": N}` to `~/.config/fleet/hooks/<session_id>_exit.json`. The status poller reads this file to detect non-zero exit codes.Based on learnings, hook status files are stored under Also applies to: 42-42 🤖 Prompt for AI AgentsSource: Learnings |
||
|
|
||
| ## Usage | ||
|
|
||
| 1. Select a session in the sidebar | ||
| 2. Press **`x`** to open a shell in that session's `ProjectPath` | ||
| 3. Use the terminal normally (full shell with colors, aliases, environment) | ||
| 4. Press **Ctrl+Q** to detach back to the TUI | ||
|
|
||
| The shell session appears in the sidebar like any other session, titled `shell: <dirname>`. | ||
|
|
||
| ## Lifecycle | ||
|
|
||
| Shell sessions are first-class sessions: | ||
|
|
||
| | Action | Key | Behavior | | ||
| |--------|-----|----------| | ||
| | Open | `x` | Spawns shell in selected session's directory | | ||
| | Attach | `Enter` | Re-attach to an existing shell session | | ||
| | Restart | `r` | Kill and recreate the shell session | | ||
| | Delete | `d` | Kill the tmux session and remove from sidebar | | ||
| | Detach | `Ctrl+Q` | Return to TUI, shell stays alive | | ||
|
|
||
| Sessions are persisted in SQLite and survive app restarts. | ||
|
|
||
| ## Status Indicators | ||
|
|
||
| Shell sessions show real-time status in the sidebar: | ||
|
|
||
| | Icon | Status | Meaning | | ||
| |------|--------|---------| | ||
| | `●` (green) | Running | A foreground command is actively executing | | ||
| | `○` (dim) | Idle | At shell prompt, last command succeeded | | ||
| | `✕` (red) | Error | At shell prompt, last command had non-zero exit code | | ||
|
|
||
| ### How detection works | ||
|
|
||
| **Running vs idle** is detected by comparing tmux's `pane_current_command` against the user's `$SHELL`. When the foreground process differs from the shell (e.g., `make` running in a `zsh` session), the session shows as running. Polled every 500ms via the preview tick. | ||
|
|
||
| **Exit code tracking** uses a `precmd` (zsh) / `PROMPT_COMMAND` (bash) hook injected when the shell session starts. After each command completes, the hook writes `{"exit_code": N}` to `~/.config/brizz-code/hooks/<session_id>_exit.json`. The status poller reads this file to detect non-zero exit codes. | ||
|
|
||
|
|
||
| ## Implementation | ||
|
|
||
| ### Key files | ||
|
|
||
| | File | Role | | ||
| |------|------| | ||
| | `internal/ui/app.go` | `x` key handler, `shellStatusDoneMsg`, preview tick polling | | ||
| | `internal/session/session.go` | `Command` field, `IsShellSession()`, `updateShellStatus()` | | ||
| | `internal/session/storage.go` | `command` column in SQLite | | ||
| | `internal/tmux/tmux.go` | `PaneCurrentCommand()`, `SetupShellExitHook()` | | ||
| | `internal/ui/keybindings.go` | `x` keybinding entry | | ||
|
|
||
| ### Session model | ||
|
|
||
| The `Session` struct has a `Command` field. When non-empty, the session is a shell session: | ||
|
|
||
| - `Start()` opens the user's shell without sending a command (vs Claude sessions which send `claude`) | ||
| - `Restart()` and `RespawnClaude()` respect the `Command` field | ||
| - `UpdateStatus()` delegates to `updateShellStatus()` for shell sessions | ||
|
|
||
| ### Status polling | ||
|
|
||
| Shell sessions bypass the hook-based status detection used by Claude sessions. Instead, `updateShellSessionStatuses()` runs every 500ms (piggybacked on the preview tick) and checks `PaneCurrentCommand()` for each live shell session. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create
~/.local/binbefore install to avoid first-run failure.installwill fail if the destination directory doesn’t exist on a fresh setup.Suggested patch
install: build + mkdir -p ~/.local/bin install -m 755 $(BUILD_DIR)/$(BINARY) ~/.local/bin/$(BINARY)📝 Committable suggestion
🤖 Prompt for AI Agents