Skip to content

fix(app): keep local sessions in the selected directory - #57358

Draft
cveld wants to merge 2 commits into
anomalyco:devfrom
cveld:selected-session-directory
Draft

cveld wants to merge 2 commits into
anomalyco:devfrom
cveld:selected-session-directory

Conversation

@cveld

@cveld cveld commented Oct 20, 2026 •

Copy link
Copy Markdown

Issue for this PR

Fixes #51191
Addresses the plain-subdirectory report in #51992.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Keep the draft's selected directory when creating a local session. The composer currently replaces it with the project's canonical directory, so selecting a folder inside a Git repository creates the session at the repository root.

Local sessions use the draft's directory, with one exception that preserves #49668: a draft opened inside an existing worktree and switched to Local still resolves to the project root. New worktrees still use the canonical project directory; explicitly selected worktrees are unchanged.

select("main") does not reset the draft's directory, so the worktree case is decided at submit time by checking whether the draft's directory is one of the project's worktrees.

Behavior by scenario

A = dev, B = this PR before the review fix, C = this PR now.

# Scenario A: dev B: first push C: now
1 Draft in a subdirectory (repo/packages/app), Local repo (#51191) repo/packages/app repo/packages/app
2 Draft in the repo root, Local repo repo repo
3 Draft in an existing worktree, Local repo worktree (regression) repo
4 Draft in a worktree, New worktree -> Local repo worktree (regression) repo
5 Draft in a subdirectory, New worktree new worktree from the project root same same
6 An existing worktree selected explicitly that worktree that worktree that worktree
7 Subdirectory added via Add project, then New session from Home or the titlebar repo repo repo

Scenario 7 is out of scope. The Add project flow stores the server project, whose worktree is the canonical root, so the picked subdirectory is lost before a draft opens (addProjects -> projects.add -> location.get; openProjectNewSession and the titlebar pass project.worktree). Fixing it means persisting the picked folder per project, which is a separate change. It is not covered by a test here.

How did you verify your code works?

  • Rebased onto dev (67139d6827).
  • App typecheck passed; oxlint and prettier are clean on the changed files.
  • New browser regressions pass against the dev server on Windows: a repository subdirectory, the repository root, a worktree directory with Local selected, and New worktree -> Local from a worktree draft.
  • The worktree row and the New worktree -> Local test fail against the first version of this PR (scenarios 3 and 4) and pass with the fix.
  • The production build hung at "rendering chunks" locally, so the e2e run used the dev server, and no performance comparison is claimed.
  • The whole new-session.spec.ts passes locally against the dev server (36 passed, no retries). The rest of the e2e suite has not been re-run since the rebase; CI on this PR is waiting for workflow approval.

Screenshots / recordings

No visual layout changes. Browser verification status is recorded above.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@aspectmoonday-create

Copy link
Copy Markdown

Heads-up: this fix is necessary but not sufficient for the plain-subdirectory case. In v2.1.2 the project card pencil, the card menu item and the titlebar new-tab handler all open the draft with project.worktree, so the draft never carries the folder picked at Add project time and resolveSessionDirectory() never sees it.

I confirmed it locally: with resolveSessionDirectory() returning the draft directory (this PR's shape), a session started from the project card still landed in the repository root. Details, entry-point list and a before/after table are in #51191 (comment) ??? the remaining pieces are packages/app/src/home/projects/view.tsx (pencil + menu item), packages/app/src/home/model.ts (openNewSession / project.add only storing project.worktree) and packages/app/src/shell/titlebar/titlebar.tsx (the home branch).

@hcalt500 hcalt500 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for the fix. The core change is directionally right: resolveSessionDirectory now returns the draft's selected directory for main, so a plain subdirectory session lands where it was opened (#51191), while explicit worktrees still resolve to the worktree and New worktree still uses the project directory.

Two things should be settled before this leaves draft, plus one testing gap.

1. This changes the behavior that #49668 deliberately introduced

#49668 (3355c93e, merged 2026-09-18, "fix(app): create local sessions in project root") made Local resolve to the project's canonical root, and covered this exact flow: open a draft at a worktree, switch New worktree -> Local, submit, expect the project root.

On this branch select("main") only updates selectedWorktree; it does not reset the draft's directory (new-session/workspace/controller.ts, select). With main now returning input.directory, that same flow submits to the worktree instead of the project root. In other words, the new a worktree directory row in new-session.spec.ts asserts the opposite of #49668's contract and will keep passing after the regression.

The old test file was renamed during later refactors, so I could not find a surviving copy of that case. Please either:

  • call out the intentional behavior change from #49668 and add the replacement regression test (New worktree -> Local -> expected destination), or
  • keep #49668 semantics and make switching to Local reset the draft directory to the project root / store a separate local destination.

Right now the PR description only mentions the nested-folder bug, not this behavioral flip.

2. Entry-point testing gap

The earlier comment says the project card, card menu and titlebar all pass project.worktree, so the draft never carries the subdirectory. That does not match this base:

  • home/projects/add.ts registers each picked directory through context.projects.open(item).
  • projects.open stores { worktree: directory, expanded: true } for that exact directory (runtime/server/registry.tsx).
  • home/model.ts (openProjectNewSession), home/projects/view.tsx (menu item and new-session button at lines 765 and 803) and titlebar.tsx all pass that local project.worktree.

For a project added as a subdirectory, those paths should already carry the subdirectory. But all three new tests call openDraft directly, so nothing verifies the Home entry path. Could you add one Home-entry e2e (open the subdirectory project from Home -> new session -> submit -> assert location.directory) before changing those call sites? If it fails, the failing entry point is the thing to fix; if it passes, changing them is unnecessary.

3. Rebase

Still a draft, head a3c0fad9 (2026-10-20), base d30e990c. Current dev is 69269e4e; please rebase and rerun the e2e suite before marking ready.

…worktree

A draft opened inside an existing worktree and switched to Local resolves to
the project root again; other folders, such as repository subdirectories, keep
their own location. Cover the worktree row and the New worktree -> Local flow.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@cveld
cveld force-pushed the selected-session-directory branch from a3c0fad to 8f51627 Compare November 3, 2026 07:53
@cveld

cveld commented Nov 3, 2026

Copy link
Copy Markdown
Author

Thanks for the review. Pushed 8f516273e1 on top of a rebase onto dev (67139d6827).

  1. fix(app): create local sessions in project root #49668: you were right. select("main") leaves the draft's directory untouched, so New worktree -> Local from a worktree draft went to the worktree. I kept fix(app): create local sessions in project root #49668's contract: at submit time a draft whose directory is one of the project's worktrees resolves to the project root for Local; any other folder (e.g. a repo subdirectory) keeps its own location. The worktree row now expects the root, and there is a new test for New worktree -> Local. Both fail against the previous head and pass now. The PR description has a before/after table covering this.
  2. Home entry: on this base I could not find the storage you describe. Add project goes through addProjects -> projects.add -> location.get and keeps the server project, whose worktree is the canonical root, so the picked subdirectory is already gone before a draft opens. openProjectNewSession and the titlebar then pass that root. I have not written a Home e2e: I expect it to fail, and fixing it means persisting the picked folder per project, which seems like a separate change. Happy to do it as a follow-up if you agree, or here if you prefer. I noted it as out of scope in the description.
  3. Rebase: done. Typecheck, oxlint and prettier pass, and the new regressions pass against the dev server. The production build hung locally at "rendering chunks", and I have not re-run the full e2e suite yet.

This branch has not been deployed

No deployments
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.

web: session in nested project folder opens at git repo root, nested .opencode/skills not discovered

3 participants