Skip to content

Fixed diff dialog appearing as orphan tab when Claude edits outside cwd - #92

Merged
oleg68 merged 1 commit into
nbplugins:mainfrom
oleg68:bugfix/orphan-diff-when-cwd-is-subdir
Apr 25, 2026
Merged

oleg68 merged 1 commit into
nbplugins:mainfrom
oleg68:bugfix/orphan-diff-when-cwd-is-subdir

Conversation

@oleg68

@oleg68 oleg68 commented Apr 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fixed diff dialog opening as a detached top-level tab (instead of embedded in session) when Claude cd's into a subdirectory mid-session and then edits a file outside that subdirectory
  • Root cause: session tab lookup used abs.equals(hookCwd) — failed because tab's startup dir (project root) ≠ hook's cwd (subdir Claude cd'd into), leaving sessionTab = null
  • Fix: changed condition to isFileUnderDirectory(hookCwd, abs) (tab matches when its startup dir is an ancestor of hookCwd); outsideProject now uses the tab's startup dir, not hookCwd; renamed parameter confirmedDir → hookCwd

Test plan

  • Open a Claude session with the project root as the working directory
  • In the session, run cd <subdirectory> (e.g. claude-launch-tests)
  • Ask Claude to edit a file in the project root (e.g. src/main/java/...)
  • Confirm: diff opens embedded in the session tab, Cancel and Accept-All buttons are active, no "outside project" warning
  • Confirm: warning still appears when Claude edits a file truly outside the project (e.g. /tmp/file.txt)

🤖 Generated with Claude Code

When Claude cd's into a subdirectory mid-session, the PreToolUse hook
fires with cwd = that subdirectory. The session tab lookup used
abs.equals(hookCwd), which failed because the tab's startup dir is the
project root — not the subdir Claude cd'd into.

This left sessionTab = null, causing:
- diff opening as a detached top-level tab instead of embedded in session
- Cancel and Accept-All buttons disabled
- false "outside project" warning for files in the project root

Fix: change lookup condition to isFileUnderDirectory(hookCwd, abs) so a
tab matches when its startup dir is an ancestor of hookCwd.
Also compute outsideProject against the tab's startup dir (project root)
rather than hookCwd, and rename the parameter confirmedDir → hookCwd.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@oleg68
oleg68 merged commit 37f8f06 into nbplugins:main Apr 25, 2026
3 checks passed
@oleg68
oleg68 deleted the bugfix/orphan-diff-when-cwd-is-subdir branch April 25, 2026 16:49
oleg68 added a commit that referenced this pull request Apr 25, 2026
…wd (#93)

Backport of #92 to release/0.21.

## Summary

- Fixed diff dialog opening as a detached top-level tab (instead of
embedded in session) when Claude `cd`'s into a subdirectory mid-session
and then edits a file outside that subdirectory
- Root cause: session tab lookup used `abs.equals(hookCwd)` — failed
because tab's startup dir (project root) ≠ hook's `cwd` (subdir Claude
cd'd into), leaving `sessionTab = null`
- Fix: changed condition to `isFileUnderDirectory(hookCwd, abs)`;
outsideProject now uses the tab's startup dir; renamed parameter
`confirmedDir` → `hookCwd`

## Test plan

- [ ] Open a Claude session with the project root as the working
directory
- [ ] In the session, run `cd <subdirectory>`
- [ ] Ask Claude to edit a file in the project root
(`src/main/java/...`)
- [ ] Confirm: diff opens **embedded** in the session tab, Cancel and
Accept-All buttons are active, no "outside project" warning
- [ ] Confirm: warning still appears for a file truly outside the
project

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Oleg Samarin <osamarin@openintegration.inc>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
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