Skip to content

✨ feat: 🚸 claude asks before starting a second session in the same directory - #99

Merged
hadees merged 2 commits into
mainfrom
feat/claude-second-session-warning
Oct 10, 2026
Merged

hadees merged 2 commits into
mainfrom
feat/claude-second-session-warning

Conversation

@hadees

@hadees hadees commented Oct 10, 2026

Copy link
Copy Markdown
Owner

What

Typing claude in a directory where a session is already running starts a second writer on the same tree, with no sign the first is there. The claude() wrapper now lists the live sessions in that directory and asks Start another here anyway? [y/N] — a warning with a way past it, never a refusal.

claude: already running in ~/code/<repo>:
  <session name>  pid 12345  idle  (.claude)
Start another here anyway? [y/N]

How

  • claude_sessions_here reads the registry each profile keeps in <config dir>/sessions/<pid>.json (the files postbox already reads), across every mapped profile plus the directory this launch resolved to. A match is the same real directory with a live pid.
  • Only a launch somebody is sitting at is asked. No terminal, -p/--print, a help or version flag, or a first argument shaped like a subcommand all pass untouched, so hooks, the postbox courier and pipes never block.
  • It fails open, and git config claude.second-session-check false turns it off.
  • claude-doctor gains a running: line and covers the new helper in defined:.

Known limits

  • The match is the exact directory: a session started in a subdirectory of the same checkout is not seen.
  • A one-word prompt (claude fix) has the shape of a subcommand and is not asked.
  • A stale registry file whose pid has been reused would warn about a session that is gone; Claude Code removes its own files on exit, so this was left alone.

Also in this PR

tests/claude-profiles.bats now resolves the real python3 before HOME is sandboxed. Where python3 is an asdf shim, the existing deny-guard doctor test failed locally at the interpreter lookup (exit 126); CI never showed it.

Verified

  • bats tests — 607 tests, no failures (run with a real python3 first on PATH; several other test files hit the same asdf-shim failure in a shell where it is not)
  • bats tests/claude-profiles.bats — 66 tests pass after the review fixes
  • Prompt driven on a pseudo-terminal in the tests: n launches nothing and returns 1, y launches
  • public-clone-advocate and /code-review on the diff; findings applied or listed under Known limits
  • Live: a new tab in a directory with a running session shows the warning

🤖 Generated with Claude Code

hadees and others added 2 commits October 9, 2026 21:09
On a machine where python3 is an asdf shim, the shim resolves its tool
version relative to $HOME and exits 126 the moment a test overrides it.
The deny-guard doctor test looked the interpreter up after setup() had
already sandboxed HOME, so it failed at the lookup itself — locally only,
which is why CI never showed it.

setup() now resolves the interpreter first and re-exposes it under a stub
on PATH, the way tests/denyguard.bats does, so every test in the file can
use python3. The next commit's pseudo-terminal helper needs the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rectory

Typing `claude` where a session is already running starts a second writer
on the same tree, and a fresh prompt gives no sign the first is there.
The wrapper now lists the live sessions in the directory and asks
`Start another here anyway? [y/N]` — a warning with a way past it, never
a refusal.

claude_sessions_here reads the registry each profile keeps in
<config dir>/sessions/<pid>.json (the files postbox already reads),
across every mapped profile plus the directory this launch resolved to,
since a literal CLAUDE_PROFILE or per-repo pin can sit outside every
mapping. A match is the same real directory with a live pid.

Only a launch somebody is sitting at is asked: no terminal, print mode,
a help or version flag, or a first argument shaped like a subcommand all
pass untouched, so hooks, the postbox courier and pipes never block. It
fails open. `git config claude.second-session-check false` turns it off
for anyone who runs several sessions in one checkout on purpose, and
claude-doctor's new `running:` line shows what the wrapper would ask
about.

Testing the prompt needs a pseudo-terminal. zsh's zpty returns short
reads on macOS and pty.spawn before Python 3.10 never returns there once
the child exits, so the test helper forks one by hand.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hadees hadees self-assigned this Oct 10, 2026
@hadees
hadees merged commit 413397e into main Oct 10, 2026
5 checks passed
@hadees
hadees deleted the feat/claude-second-session-warning branch October 10, 2026 20:24
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.

1 participant