Skip to content

feat: add open-shell-in-worktree action - #319

Open
dietghardev wants to merge 1 commit into
kbwo:mainfrom
dietghardev:feat/open-shell-in-worktree
Open

feat: add open-shell-in-worktree action#319
dietghardev wants to merge 1 commit into
kbwo:mainfrom
dietghardev:feat/open-shell-in-worktree

Conversation

@dietghardev

Copy link
Copy Markdown

What

Adds an "Open shell in this directory" action (key O) to the Session Actions menu, so you can open a plain shell in a worktree's directory without leaving ccmanager.

Closes #229.

How

A shell is just another command spawned into the worktree, so it reuses the existing PTY session pipeline rather than introducing a second PTY per session (the approach explored in the earlier #22):

  • SessionManager.createShellSession(worktreePath) spawns $SHELL (falling back to /bin/sh) with no args via the same spawn() used for agent sessions, as a non-primary session that coexists with any agent session in the same worktree.
  • New 'openShell' entry in SessionActions (menu item + O key), routed through a new case in App.tsx's handleSessionAction that navigates into the normal session view — same flow as newSession.
  • A 'shell' state-detection strategy whose detector always reports idle, since a plain shell has no agent output to parse (avoids false busy/waiting icons in the worktree list).

Tests

  • New shell.test.ts (4 cases) covering always-idle behaviour, empty terminal, agent-like output, and zero background/team counts.
  • bun run lint, bun run typecheck, and the full bun run test suite (1792 passing) all green.

Design note

Because StateDetectionStrategy is enforced via Record<StateDetectionStrategy, …> in ConfigureCommand.tsx, adding the shell strategy also surfaces it in the preset detection-strategy picker (labelled "Shell (no agent detection)"). That's harmless and arguably useful for making a shell preset, but if you'd prefer to keep it out of the agent-strategy picker I'm happy to hide it there in a follow-up.

Adds an "Open shell in this directory" action (key: O) to the Session
Actions menu, spawning the user's $SHELL in the worktree via the existing
PTY session pipeline. Introduces a 'shell' detection strategy whose
detector always reports idle, since a plain shell has no agent output to
parse.

Closes kbwo#229

@kbwo kbwo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

This review was drafted by Claude Code (model: Opus 5). I (@kbwo) have gone through it myself and verified the content before posting.

Thanks for the PR! Reusing the existing PTY session pipeline instead of introducing a second PTY per session is the right call, and isPrimaryCommand: false is a good catch — it keeps the exit-code-1 fallback retry from re-spawning a shell that the user deliberately exited. Two things I would like changed before merging.

1. O for "Open" is too generic a mnemonic — it will collide with the next "open X" action

The shortcut is keyed on the verb ("Open") rather than on the thing being opened:

The problem is that "open" is not a distinguishing property of this action. The originating issue #229 already asks for a second one in the same breath — "there could be a shortcut to spawn your default IDE in that dir as well" — and "Open in file manager" is an equally natural follow-up. All of them are equally "O", so whichever one lands first squats on the key and the rest have to settle for arbitrary leftovers. That is a menu that gets worse as it grows.

The existing keys in this menu already avoid that trap by keying on the noun rather than the verb: S = Session, R = Rename. Could you pick a key on the same basis and propose it here? I do not have a specific one in mind — I would rather leave the choice to you, as long as it identifies what is being opened rather than the act of opening.

Whichever key you land on, please update the label, the switch case, and the S/O/R/X hint line together.

2. The default shell is defined twice, with two different values

This PR introduces two independent answers to "what is the user's shell?":

The second one is not dead config: DEFAULT_COMMANDS is read at ConfigureCommand.tsx#L315 to prefill the command field when a user picks a detection strategy while adding a preset. So a fish or zsh user gets their real shell via the new action, but a hardcoded bash when they build a preset around the same new shell strategy — same concept, two answers, and the divergence is invisible until someone hits it.

Could you extract a single resolver — e.g. resolveDefaultShell() in src/utils/ — and have both call sites reference it? That also gives one place to fix two robustness gaps that the current duplication hides:

  • ?? only falls back on null/undefined, so a SHELL='' environment (common in cron and some container images) reaches spawn(''). || is what you want here.
  • /bin/sh does not exist on Windows, and SHELL is normally unset there, so this action can never work on Windows. The repo does carry Windows handling elsewhere (src/utils/terminalCapabilities.ts#L27) and documents Windows config paths (docs/command-config.md#L70), so a process.env.COMSPEC branch for win32 belongs in that helper. CI only runs ubuntu-latest (ci.yml#L12), so this will not surface on its own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: open terminal for worktree

2 participants