Skip to content

feat(sidebar): open projects in a new browser tab - #1208

Merged
agegr merged 3 commits into
agegr:mainfrom
wowayou:feat/project-open-new-tab
Oct 15, 2026
Merged

agegr merged 3 commits into
agegr:mainfrom
wowayou:feat/project-open-new-tab

Conversation

@wowayou

@wowayou wowayou commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Add Open in new tab (T) to a project group's ⋯ menu, immediately after Open in Files. It opens a fresh composer for that project without switching the original browser tab or selecting an arbitrary previous conversation.

  • Current project: use the sidebar's selected directory/worktree.
  • Another project, including a pinned project without sessions: use its root.
  • The original tab retains its selected session, directory, draft, file preview and group expansion.
  • The action creates, copies, prompts and stops no session. Project-header expand/collapse and same-tab + keep their existing behavior.

Closes #1207

Reuse and scope

Only three production files change:

  • components/SessionSidebar.tsx reuses SidebarMenu, the existing sidebar.openInNewTab translations, OpenInNewTabIcon, shortcut handling and the session menu's synchronous window.open(..., "_blank", "noopener,noreferrer") pattern.
  • lib/new-session-context.ts extracts the existing group's + target rule into newSessionTargetForProject(), shared by + and the new menu action.
  • lib/session-links.ts adds the cwd counterpart to its session link: newSessionDeepLink(). The existing ?cwd= validation, fresh-composer initialization and per-tab restore behavior are unchanged. The relative link keeps origin/path and removes stale query parameters and fragments.

No new navigation framework, app-internal tabs, session state store, backend API, dependency, or setting. Browser Back/Forward, changes to New, project filtering and the broader conversation-finding discussion (#1201) are outside this PR. The separate static demo is unchanged.

Tests

  • node_modules/.bin/tsc --noEmit: PASS.
  • npm run lint: PASS.
  • npm test: PASS — 2630 tests, 2629 passed, 1 skipped, 0 failures on the full rerun.
  • PI_OFFLINE=1 PI_WEB_SKIP_VERSION_CHECK=1 npm run test:e2e: PASS — 36 checks on the full rerun (27 existing + 9 new).
  • A focused run of the new project-navigation browser checks also passed.
  • git diff --check: PASS.

The new browser checks are integrated into the existing e2e/run.mjs server lifecycle and temporary agent directory, and reuse the existing HTML file-panel fixture and sidebar helpers. They cover desktop and mobile Chromium, a real linked worktree with spaces/non-ASCII/&/# in its path, another project, an empty pinned project, click and keyboard activation, reload vs remembered sessions, source draft and file-preview preservation, the unchanged + action, and an unavailable directory. Requests and session IDs are checked to rule out session creation/copying/prompting/stopping. Unit tests also cover Windows/UNC path encoding and sub-path URL resolution.

Initial-run failures, retained for transparency

  • The first unit-suite run, alongside lint and type checking, failed in the unchanged lib/project-command-env.test.mjs timeout test because its descendant's survivor.pid had not been written. Running the entire unmodified suite again on its own passed.
  • The first full browser run stopped with Chromium net::ERR_NETWORK_CHANGED during an existing session-load step, before the new checks. The entire unmodified browser suite rerun passed.

No assertions were relaxed or retry logic added to address either failure. All browser runs used temporary fixture sessions; no real sessions or inference requests were used. The existing installed Pi Web service was left running untouched.

Documentation

Updated docs/agents/sessions.md, the English/Chinese worktree guides, and e2e/README.md to describe the new entry point, its directory rule and regression coverage.

Verification limits

Verified on Linux with headless Chromium, including a mobile viewport/touch emulation. Real mobile devices, macOS, Windows, Firefox and Safari were not exercised; Windows path handling is unit-tested only. No development build was run.

@agegr

agegr commented Oct 14, 2026

Copy link
Copy Markdown
Owner

Thanks @wowayou, this fits as the project counterpart of #1169 and reuses the existing pieces well.

What I checked, on a merge with main:

  • tsc, lint and the unit suite pass, and project-navigation.mjs passes 9/9 against a local dev server with headless Chrome.
  • I opened a linked worktree, a renamed project and a pinned project without sessions from the menu. Each new tab showed an empty new chat with the right project and branch in the bar and no session selected, also after a reload.
  • The source tab kept its session and draft, and window.opener was null. No request created, prompted or stopped a session.
  • ?cwd= is the URL the same-tab + already writes, so the new tab goes through an existing path. T is the only shortcut in the group menu, and the item is not first.

I pushed two small docs commits:

  • 4976205: AGENTS.md's file map now mentions the ?cwd= link in session-links.ts and the group's target in new-session-context.ts.
  • 41e7628: docs/worktrees.md says "a new chat" instead of "a fresh composer", as the rest of the guide does.

Good to merge from my side.

@agegr
agegr merged commit 5e286a9 into agegr:main Oct 15, 2026
2 checks passed
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.

feat(sidebar): open a project's new-session page in a new browser tab

2 participants