Skip to content

feat(desktop): remember recently used sites in the Browser panel - #5270

Merged
maria-rcks merged 3 commits into
pingdotgg:mainfrom
chrisdeeming:browser-recently-used
Aug 7, 2026
Merged

feat(desktop): remember recently used sites in the Browser panel#5270
maria-rcks merged 3 commits into
pingdotgg:mainfrom
chrisdeeming:browser-recently-used

Conversation

@chrisdeeming

@chrisdeeming chrisdeeming commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Closes #4746

What Changed

Adds a Recently used group to the Browser panel splash, above the existing Local servers list. URLs opened in the panel are remembered per project and persist across restarts.

History is recorded after successful URL-bar navigation, local-server opens, terminal links, and chat preview links. Each row shows the page title when available, the URL, relative visit time, and a remove action.

Local servers is unchanged.

Why

The splash only knew about listening localhost ports, so it surfaced things that are not web servers while missing custom domains such as app.test and main.app.local. Reopening a site after a restart also meant typing the URL again.

Recording sites that were actually opened handles custom domains without broadening port discovery and keeps the list relevant to each project.

History is stored in localStorage with the existing Zustand persistence pattern. There is no server involvement and no new dependency.

UI Changes

Before After
Browser panel before Recently used Browser panel with Recently used

Roadmap

I've reduced the scope of this PR down so it is no longer XXL. If merged, I have a further (smaller) submission which is to add favicons to the "Recently used" section and browser tabs.

CleanShot 2026-08-03 at 11 46 56@2x

I would also like to do more work here. The Local servers section displaying servers that do not serve web content doesn't make a lot of sense. It currently displays things for me such as localhost:1025 which is a MailHog SMTP server and localhost:3306 which is a MySQL server.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for the UI change
  • I included a video for animation/interaction changes

Built with Claude and GPT-5.6 through T3 Code.


Note

Low Risk
Client-only localStorage UI state with no auth or server changes; broad test coverage limits regression risk in preview and chat link flows.

Overview
Adds per-project browser history persisted in localStorage via a new Zustand store, keyed to the same logical project grouping as the sidebar (not just the active physical project row).

The Browser panel empty state gains a Recently used section above Local servers: each row shows title (when known), URL, relative visit time, and remove. Visits are recorded only after successful navigation from the URL bar, discovered local servers (storing the pre-resolution requestedUrl), terminal links, chat preview links, and discovered-port opens. Page titles are applied update-only to existing history entries after load.

History normalizes and sanitizes URLs (scheme, credentials, length), deduplicates localhost / environment-host aliases, and caps entries per project and projects overall. Persisted state is migrated and re-sanitized on every rehydrate; visits/titles before thread registration are queued and drained on project registration.

Reviewed by Cursor Bugbot for commit 487681d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

[!NOTE]

Add recently used site history to the Browser panel

  • Introduces useBrowserHistoryStore, a persisted Zustand store that tracks per-project browser history entries (URL, title, last-visited time), keyed by a logical project grouping consistent with the sidebar.
  • Visits are recorded when users submit a URL, open a discovered local server, or open a link from the terminal or chat markdown; titles are updated after successful navigation.
  • The Browser panel empty state now renders a 'Recently used' section via the new PreviewRecentUrlCard component, with relative timestamps and a remove action.
  • Local and loopback host aliases are canonicalized to a single history entry, and requestedUrl is preserved on discovered servers so the pre-resolution URL is recorded in history.
  • Persisted state is sanitized and migrated on every rehydrate: malformed entries are dropped, lists are capped, and excess projects are evicted.

Macroscope summarized 487681d.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 11bb7511-57fc-43e7-aee4-5f11dca2e588

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 3, 2026
Comment thread apps/web/src/browserHistoryStore.ts
Comment thread apps/web/src/browserHistoryStore.ts Outdated
Comment thread apps/web/src/components/preview/usePreviewBridge.ts Outdated
Comment thread apps/web/src/components/preview/PreviewView.tsx
Comment thread apps/desktop/src/preview/Manager.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (browser history tracking with UI) that adds new user-facing behavior, new state management, and new components. New features of this scope warrant human review to validate the intended behavior and integration points.

You can customize Macroscope's approvability policy. Learn more.

@chrisdeeming

Copy link
Copy Markdown
Contributor Author

Just a note on the size, the entire feature itself is ~900 lines. There is, I feel, a somewhat generous test coverage. I am, however, assured they are "load-bearing" 🙄

Happy to trim those down. I have been through them and most of them are defensible to be fair. At the very least, I'd recommend reviewing the non-test code if you'd like to avoid some of the noise.

Acting on review feedback now.

@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch from 7aae674 to 8b92eed Compare August 3, 2026 12:59
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 3, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One finding: favicon dedupe state is held in a module-level global inside the PreviewManager service module rather than in the service's own state, with a test-only reset export to compensate. Everything else in the Effect-facing changes matches the conventions (namespace effect/* imports, Effect.fn operations, PreviewOperationError with structured operation/tabId/webContentsId plus preserved cause, runFork derived from the captured context).

Posted via Macroscope — Effect Service Conventions

Comment thread apps/desktop/src/preview/Manager.ts Outdated
Comment thread apps/web/src/browserFaviconStore.ts Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch from 8b92eed to 2372eee Compare August 3, 2026 13:14
Comment thread apps/web/src/browserHistoryStore.ts
Comment thread apps/web/src/components/preview/PreviewRecentUrlCard.tsx
Comment thread apps/web/src/browserFaviconStore.ts Outdated
Comment thread apps/web/src/components/ChatView.tsx Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch from 2372eee to d182c5d Compare August 3, 2026 13:54
Comment thread apps/web/src/previewStateStore.ts
Comment thread apps/web/src/components/preview/PreviewView.tsx
Comment thread apps/web/src/components/RightPanelTabs.tsx Outdated
Comment thread apps/web/src/components/preview/usePreviewBridge.ts Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch from d182c5d to 92998aa Compare August 3, 2026 14:35
Comment thread apps/web/src/browserHistoryStore.ts Outdated
Comment thread apps/web/src/components/preview/usePreviewBridge.ts Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch from 92998aa to cb2ed59 Compare August 3, 2026 15:17
Comment thread apps/web/src/browserHistoryStore.ts Outdated
Comment thread apps/desktop/src/preview/Manager.ts Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch 2 times, most recently from af95d02 to 6173162 Compare August 4, 2026 15:21
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:XXL 1,000+ changed lines (additions + deletions). labels Aug 4, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed the new favicon capture/store code against the Effect service conventions. The layer-scoped capturedFaviconsRef (previously a module global) now looks correct, and the new modules use subpath namespace imports and the existing PreviewOperationError shape. Two smaller items below.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/web/src/components/preview/previewConstants.ts
Comment thread apps/desktop/src/preview/Manager.ts Outdated
Comment thread apps/web/src/components/ChatMarkdown.tsx Outdated
@chrisdeeming

chrisdeeming commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

I'm going to call this finished at this point, outside of keeping the branch up-to-date with upstream.

Note for reviewers

This PR originally had a wider scope, but I decided to split it into two in order to make reviewing easier.

This PR focuses on the browser history portion only so it gives us an appropriately scoped "Recently used" section on the browser panel splash screen.

A future PR will add a bit of visual polish in the shape of favicon storage and display, with a sneak peek available below.

CleanShot 2026-08-03 at 11 46 56@2x

I have some more improvements in mind too.

@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch from e6b7a3f to 6e04fd5 Compare August 4, 2026 18:16
Comment thread apps/web/src/components/preview/PreviewView.tsx
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch 2 times, most recently from 204ecf3 to d9787f2 Compare August 5, 2026 13:09
Comment thread apps/web/src/browserHistoryStore.ts Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch 2 times, most recently from 04b1b39 to 681152f Compare August 6, 2026 14:08
Comment thread apps/web/src/components/ChatView.tsx Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch 3 times, most recently from cf10cca to 1ad7415 Compare August 6, 2026 19:24

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1ad7415. Configure here.

Comment thread apps/web/src/components/ChatView.tsx Outdated
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch 3 times, most recently from 868bea0 to b78032b Compare August 7, 2026 01:20
Records urls navigated in the Browser panel and persists them to
localStorage, keyed by logical project so history follows a repository
across worktrees. Only intentional navigations are recorded -- address
bar, splash cards, chat links and terminal links -- so agent-driven
browsing and reconnect echoes stay out of history.

Stores the requested url rather than the resolved one, since resolution
can bake in a volatile environment host. Bounded to 50 urls per project
across 20 projects.
Shows recently visited sites above the existing Local servers list, with
page title, relative time and a remove control. Local servers keeps its
current scanner, behaviour and position.

Entries appear even when the same host is currently listening: the two
groups answer different questions, and a recents row carries the full
path and title that a server card does not.
@chrisdeeming
chrisdeeming force-pushed the browser-recently-used branch from b78032b to 487681d Compare August 7, 2026 14:44
@maria-rcks
maria-rcks merged commit 72d673a into pingdotgg:main Aug 7, 2026
15 checks passed
@chrisdeeming
chrisdeeming deleted the browser-recently-used branch August 7, 2026 18:46
@t3-code t3-code Bot mentioned this pull request Aug 7, 2026
3 tasks
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Aug 8, 2026
## What's Changed
* chore(ci): vouch StiensWout by @t3-code[bot] in pingdotgg/t3code#5637
* feat(desktop): remember recently used sites in the Browser panel by @chrisdeeming in pingdotgg/t3code#5270
* chore: vouch chrisdeeming by @t3-code[bot] in pingdotgg/t3code#5641
* feat(web): make sidebar artwork theme-aware by @maria-rcks in pingdotgg/t3code#5636
* fix(web): reconnect the composer seam for remote non-Git projects by @caezium in pingdotgg/t3code#5633
* fix(web): show Stop button while input is pending by @ipanasenko in pingdotgg/t3code#5554
* feat(web): fold plan mode and token-by-token output into Legacy features by @t3dotgg in pingdotgg/t3code#5664

## New Contributors
* @chrisdeeming made their first contribution in pingdotgg/t3code#5270

**Full Changelog**: pingdotgg/t3code@v0.0.33-nightly.20260807.1026...v0.0.33-nightly.20260808.1029

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.33-nightly.20260808.1029
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Aug 8, 2026
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Aug 8, 2026
cursor Bot pushed a commit to aaditagrawal/t3code that referenced this pull request Aug 8, 2026
omegent-app Bot added a commit to patroza/t3code that referenced this pull request Aug 8, 2026
Adopts the thirteen upstream commits after #379. The headline is pingdotgg#5672 making
sidebar v2 the default, which is a file-level restructure: upstream renamed the
classic sidebar to LegacySidebar.tsx and moved v2's content into Sidebar.tsx,
deleting SidebarV2.tsx.

Git could not follow either rename because both sides had changed both files,
so each was merged three-way by hand:

- Sidebar.tsx = the fork's SidebarV2.tsx (multi-env and ownership filters,
  identity marks, budgeted listStatus, pin ordering, copy-thread-id, unread
  and regenerating-title chrome) with upstream's pingdotgg#5672 delta applied. That
  delta is a rename sweep — SidebarV2* → Sidebar*, group/v2-row →
  group/sidebar-row, sidebar-v2-* test ids — plus aria-busy on the rows.
- LegacySidebar.tsx = the fork's old Sidebar.tsx with upstream's rename and
  settings-nav hoist applied. AppSidebarLayout now renders SettingsSidebarNav
  for both sidebars, so the legacy one no longer renders it itself.

forkSurfaceExistence, the fork's anti-stack-drop net, was retargeted at the
renamed files and ids rather than relaxed: all 17 assertions still run, and
they are what caught LegacySidebar initially being upstream's v1 rather than
the fork's.

Other resolutions:
- GitManager: upstream's per-branch exponential backoff for rate-limited PR
  lookups (pingdotgg#5673) with the fork's terminal-state freeze helper kept.
- Composer: pingdotgg#5554 shows Stop while input is pending, which is exactly what the
  fork's shouldShowComposerInterruptAction suppressed; the predicate and its
  tests are retired rather than merged.
- PreviewView: the fork's resolveNavigableUrl (asks the environment about
  tailnet routing) keeps resolving, with upstream's browser-history recording
  (pingdotgg#5270) layered on the successful-navigation path.
- Settings: sidebarV2Enabled / sidebarV2ConfiguredByUser and
  enableAssistantStreaming are retired in favour of upstream's fresh keys
  (legacySidebarEnabled, enableLegacyTokenStreaming), which deliberately reset
  prior opt-ins; the mobile list toggle inverts the same way, so HomeScreen now
  reads through resolveThreadListV2Enabled.
- .github/VOUCHED.td stays deleted: it is upstream's contributor-vouching file.

Adversarial review caught one surface the key migration missed: the mobile
ThreadNavigationSidebar still gated v2 on the retired threadListV2Enabled, so
the iPad/split list would have stayed on the legacy layout with no setting able
to change it, disagreeing with Home. It now reads through
resolveThreadListV2Enabled like HomeScreen.

Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Browser has some rough UX edges - history/local servers enumeration

3 participants