Skip to content

🤖 feat: pin chats to the top of the sidebar#3683

Merged
ibetitsmike merged 3 commits into
mainfrom
chat-pins-weq9
Jul 6, 2026
Merged

🤖 feat: pin chats to the top of the sidebar#3683
ibetitsmike merged 3 commits into
mainfrom
chat-pins-weq9

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds chat pinning: workspaces can be pinned to the top of the project sidebar in a stable, user-controlled order that is immune to recency reshuffling.

Background

Sidebar ordering is recency-based, so long-running or reference chats constantly drift down as other workspaces see activity. Pinning gives important chats a fixed spot at the top of their project.

Implementation

  • pinnedAt timestamp on WorkspaceConfigSchema / WorkspaceMetadataSchema; shared isWorkspacePinned / isWorkspacePinnable helpers (src/common/utils/pin.ts). Only root chats can be pinned; sub-agents and archived workspaces cannot.
  • WorkspaceService.setPinned with a server-generated monotonic timestamp (max(now, maxPinInProject + 1ms)) so pin order is append-only and stable even with client clock skew; exposed via workspace.setPinned ORPC route. Archiving clears pinnedAt; unarchive does not restore it.
  • Sorting: pinned roots sort first by pinnedAt ascending (id tie-break) in buildSortedWorkspacesByProject; partitionWorkspacesByAge treats pinned roots (and their children via tier inheritance) as recent so pins never fall into the aged bucket.
  • Frontend applies an optimistic pinnedAt on click (mirroring the server's append-only ordering) so rows reorder instantly; the metadata subscription reconciles and failures revert.
  • UI: Pin/Unpin chat item in the sidebar row menu and workspace menu bar, pin icon on pinned rows, Ctrl/Cmd+Alt+P keybind, and a Pin/Unpin Current Chat palette action.

Validation

Full UAT against a dev-server-sandbox instance driven with agent-browser (16 scenarios): pin/unpin via row menu, menu bar, keybind, and palette; stable append-below-existing-pins order; new workspaces landing below pins; persistence across reload; pinnedAt cleared on archive and not restored on unarchive; two-client live sync (pin in client A instantly reorders client B); pin icon rendering at 375px mobile width with no overflow. Rapid-pinning four chats via the row menu reorders the sidebar immediately on each click (verified with no-wait DOM snapshots) and converges with the server's persisted order.

Risks

Low. Sorting changes are scoped to buildSortedWorkspacesByProject / partitionWorkspacesByAge and covered by new unit tests (pin ordering vs recency, stale-pin child attachment, archived-pin ignore, age bucketing). Unpinned workspaces keep the existing recency order; workspaces without pinnedAt are unaffected.


Generated with mux • Model: anthropic:claude-fable-5 • Thinking: max • Cost: $75.72

Adds pinnedAt to workspace config/metadata schemas, a setPinned ORPC
mutation with monotonic server timestamps, pin-aware sidebar sorting and
age bucketing, and UI affordances (menu toggle, row icon, Ctrl/Cmd+Alt+P
keybind, palette action). Archiving clears the pin; sub-agents and
archived chats are not pinnable.

---

_Generated with `mux` • Model: `anthropic:claude-fable-5` • Thinking: `off` • Cost: $

<!-- mux-attribution: model=anthropic:claude-fable-5 thinking=off costs=63.56 -->
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e716de47f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/components/ProjectSidebar/ProjectSidebar.tsx Outdated
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0f2d9cd797

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/browser/components/AgentListItem/AgentListItem.tsx Outdated
…Context

- setWorkspacePinned applies an optimistic pinnedAt locally (mirroring the
  server's append-only monotonic ordering) so the sidebar reorders on click;
  the metadata subscription reconciles, and failures revert.
- AgentListItem row menu now uses the context wrapper instead of calling
  api.workspace.setPinned directly, fixing delayed reorder and the mock-client
  crash Codex flagged (optional hook keeps provider-less stories working).
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: b88bb0edd5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike merged commit 3770152 into main Jul 6, 2026
23 checks passed
@ibetitsmike ibetitsmike deleted the chat-pins-weq9 branch July 6, 2026 22:21
@mux-bot mux-bot Bot mentioned this pull request Jul 7, 2026
mux-bot Bot added a commit that referenced this pull request Jul 7, 2026
Extract parseTimestampMs helper for the repeated
Date.parse(x ?? '') / Number.isFinite fallback pattern used as
sort keys in buildSortedWorkspacesByProject. The pinnedAt keys
(added by #3683) and the pre-existing createdAt keys now share
one helper. Behavior-preserving.
mux-bot Bot added a commit that referenced this pull request Jul 7, 2026
Extract parseTimestampMs helper for the repeated
Date.parse(x ?? '') / Number.isFinite fallback pattern used as
sort keys in buildSortedWorkspacesByProject. The pinnedAt keys
(added by #3683) and the pre-existing createdAt keys now share
one helper. Behavior-preserving.
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.

1 participant