fix(coding-agent): resume sessions after a worktree move/rename
When a session's working directory is moved or renamed (e.g. `git worktree move`), the session file stays under the old cwd-encoded bucket while the new directory is empty. Resuming was lossy: - `--continue` rejected the terminal breadcrumb purely on cwd mismatch and then found nothing in the new bucket, silently starting a fresh empty session. - cross-project `--resume <id>` only offered to *fork* (duplicate) the session into the new directory, forcing manual id selection and leaving a stale copy. Detect relocation via the strong, low-false-positive signal "recorded cwd no longer exists on disk" and re-root in place with the existing `moveTo()`: - `continueRecent` re-roots the terminal's last session into the current directory when its recorded cwd is gone and the new location has no sessions of its own (otherwise behavior is unchanged). `readTerminalBreadcrumb` is refactored into `readTerminalBreadcrumbEntry` returning the raw cwd + session file so callers can interpret a cwd mismatch. - cross-project `--resume <id>` offers "Move (re-root)" instead of fork when the source directory is gone; a still-existing different project still forks. Tests: continue-relocation (re-root on move, no-hijack on plain cd, prefer local recent) and cross-project move-vs-fork routing.
This commit is contained in:
@@ -24,8 +24,8 @@ This document describes operator-visible behavior for session export/share/fork/
|
||||
| `--fork <id\|path>` | CLI startup | Yes after session creation | Creates a new session fork from the selected source into current cwd/session dir | None |
|
||||
| `/resume` | Interactive slash command | Yes (active in-memory state replaced) | Switches to selected existing session file | None |
|
||||
| `--resume` | CLI startup picker | Yes after session creation | Opens selected existing session file | None |
|
||||
| `--resume <id\|path>` | CLI startup | Yes after session creation | Opens existing session; global cross-project match can fork into current project | None |
|
||||
| `--continue` | CLI startup | Yes after session creation | Opens terminal breadcrumb or most-recent session; creates new one if none exists | None |
|
||||
| `--resume <id\|path>` | CLI startup | Yes after session creation | Opens existing session; global cross-project match re-roots (moved dir) or forks into current project | None |
|
||||
| `--continue` | CLI startup | Yes after session creation | Opens terminal breadcrumb (re-roots it if its dir was moved) or most-recent session; creates new one if none exists | None |
|
||||
|
||||
## Export and dump
|
||||
|
||||
@@ -215,19 +215,23 @@ Notes:
|
||||
|
||||
Cross-project id match behavior:
|
||||
|
||||
- If matched session cwd differs from current cwd, CLI asks:
|
||||
- `Session found in different project ... Fork into current directory? [y/N]`
|
||||
- On yes: `SessionManager.forkFrom(match.path, cwd, sessionDir)` creates a new local forked file.
|
||||
- On no/non-TTY default: command errors.
|
||||
- If matched session cwd differs from current cwd, behavior depends on whether the matched session's recorded directory still exists:
|
||||
- **Directory gone (moved/renamed, e.g. `git worktree move`)**: CLI asks `Session's directory no longer exists (...). Move (re-root) it into the current directory? [Y/n]`.
|
||||
- On yes (default): `SessionManager.open(match.path)` then `manager.moveTo(cwd)` re-roots the existing session into the current directory (no duplicate file).
|
||||
- On no: command cancels (returns no session). On non-TTY: command errors.
|
||||
- **Directory still exists (genuinely different project)**: CLI asks `Session found in different project ... Fork into current directory? [y/N]`.
|
||||
- On yes: `SessionManager.forkFrom(match.path, cwd, sessionDir)` creates a new local forked file.
|
||||
- On no: command cancels. On non-TTY: command errors.
|
||||
|
||||
## CLI `--continue`
|
||||
|
||||
`SessionManager.continueRecent(cwd, sessionDir)`:
|
||||
|
||||
1. Resolves session dir for current cwd.
|
||||
2. Reads terminal-scoped breadcrumb first.
|
||||
3. Falls back to most recently modified session file.
|
||||
4. Opens found session; if none exists, creates new session.
|
||||
2. Reads the terminal-scoped breadcrumb.
|
||||
3. If the breadcrumb points at a session recorded under a different cwd whose directory no longer exists (moved/renamed) **and** the current directory has no sessions of its own, re-roots that session into the current directory via `moveTo` instead of starting fresh.
|
||||
4. Otherwise, if the breadcrumb's cwd matches the current cwd, uses the breadcrumb session; else falls back to the most recently modified session file.
|
||||
5. Opens the found session; if none exists, creates a new session.
|
||||
|
||||
This is startup-only behavior; there is no interactive `/continue` slash command.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user