Problem
`aps` can launch a Claude session from the wrong directory when a transcript starts in the original project but later records move into a Claude worktree.
Observed failure:
```text
Resuming claude session: a60e87e2-eb65-4b92-bd29-204dc165d47c
Directory: /Users/sd/projects/aps/.claude/worktrees/fix+18-metacache-reload
No conversation found with session ID: a60e87e2-eb65-4b92-bd29-204dc165d47c
exit status 1
```
Evidence
The transcript exists under the original project namespace:
```text
~/.claude/projects/-Users-sd-projects-aps/a60e87e2-eb65-4b92-bd29-204dc165d47c.jsonl
```
The corresponding worktree namespace does not exist:
```text
~/.claude/projects/-Users-sd-projects-aps--claude-worktrees-fix-18-metacache-reload
```
The transcript tail contains records whose `cwd` is the worktree path:
```text
/Users/sd/projects/aps/.claude/worktrees/fix+18-metacache-reload
```
`aps` currently parses the last non-empty `cwd` and passes that value to `launcher.Claude`, which runs `cd && claude --resume `. Claude Code appears to resolve resume storage from the launch directory namespace, so launching from the worktree makes Claude search a namespace that does not contain the transcript.
Plan
See `docs/agent/plan-issue-62-claude-launch-dir.md`.
Expected behavior
`aps` should resume Claude sessions from a launch directory that maps to the transcript's storage namespace, while still displaying the latest working directory when useful.
Implementation notes
Consider separating these concepts in `source.Session`:
- display/working directory: latest transcript `cwd`, used for UI context and path filtering
- launch directory: directory derived from the Claude project namespace or initial transcript project path, used by `launcher.Claude`
The fix should preserve current behavior for normal non-worktree sessions.
Acceptance criteria
- A Claude transcript stored under the original project namespace but whose tail `cwd` points to `.claude/worktrees/...` resumes successfully.
- The picker preview/list can still show the latest worktree directory where appropriate.
- Non-worktree Claude sessions still launch from their expected directory.
- Tests cover the launch directory selection separately from displayed/current `cwd`.
Problem
`aps` can launch a Claude session from the wrong directory when a transcript starts in the original project but later records move into a Claude worktree.
Observed failure:
```text
Resuming claude session: a60e87e2-eb65-4b92-bd29-204dc165d47c
Directory: /Users/sd/projects/aps/.claude/worktrees/fix+18-metacache-reload
No conversation found with session ID: a60e87e2-eb65-4b92-bd29-204dc165d47c
exit status 1
```
Evidence
The transcript exists under the original project namespace:
```text
~/.claude/projects/-Users-sd-projects-aps/a60e87e2-eb65-4b92-bd29-204dc165d47c.jsonl
```
The corresponding worktree namespace does not exist:
```text
~/.claude/projects/-Users-sd-projects-aps--claude-worktrees-fix-18-metacache-reload
```
The transcript tail contains records whose `cwd` is the worktree path:
```text
/Users/sd/projects/aps/.claude/worktrees/fix+18-metacache-reload
```
`aps` currently parses the last non-empty `cwd` and passes that value to `launcher.Claude`, which runs `cd && claude --resume `. Claude Code appears to resolve resume storage from the launch directory namespace, so launching from the worktree makes Claude search a namespace that does not contain the transcript.
Plan
See `docs/agent/plan-issue-62-claude-launch-dir.md`.
Expected behavior
`aps` should resume Claude sessions from a launch directory that maps to the transcript's storage namespace, while still displaying the latest working directory when useful.
Implementation notes
Consider separating these concepts in `source.Session`:
The fix should preserve current behavior for normal non-worktree sessions.
Acceptance criteria