feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(sidebar): sync pinned thread order - #5528

Closed
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads
Closed

feat(sidebar): sync pinned thread order#5528
f-trycua wants to merge 9 commits into
pingdotgg:mainfrom
trycua:agent/reorder-pinned-threads

Conversation

@f-trycua

@f-trycuaf-trycua commented Aug 6, 2026

Copy link
Copy Markdown

Pinned threads are global, but their order was fixed by creation time. This adds manual ordering that is stored by the server and follows the user across connected clients.

What changed

  • add a version-skew-safe thread.pin.reorder command and thread.pin-reordered event
  • persist an exact rational order so moving one thread only updates that thread
  • add drag handles and keyboard drag support on web/desktop
  • add Move up / Move down actions on web and mobile
  • keep legacy clients and servers working through optional fields and a separate capability flag
  • document the sidebar behavior and cover contracts, ordering, projections, persistence, web logic, and mobile rendering with focused tests

Screenshots

BeforeAfter
Pinned threads before manual orderingPinned threads after manual ordering

The integrated browser pass moved “Review API changes” from third to first with the keyboard-accessible drag control, confirmed that only the moved thread received a persisted order, and verified the same order after a full reload.

Verification

  • 254 focused tests across 11 files
  • focused typechecks for contracts, client runtime, server, web, and mobile
  • targeted lint and formatting checks for all changed files
  • Cua Driver pass in standalone Chrome against isolated synthetic state

Related to #698.

Built with GPT-5 Codex in the Codex desktop harness.


Note

Medium Risk
Touches orchestration commands, persistence, and multi-client sync with optimistic UI and multi-thread compaction when rational gaps run out; gated by capability but mixed server versions can block reorder until updated.

Overview
Pinned threads used to sort by creation time only. This PR adds server-backed manual order that syncs across web, desktop, and mobile.

Backend: New PinnedThreadOrder rational positions, thread.pin.reorder / thread.pin-reordered, pinned_order on projections (migration 038), and a separate threadPinReordering capability so older pinning servers are not sent reorder commands. Unpin clears pinnedOrder. Client-runtime adds sortPinnedThreads and move helpers (mediant between neighbors, full-list compaction when gaps are exhausted).

Web: Sidebar v2 uses @dnd-kit drag on pinned rows (grip handle), context-menu move up/down, optimistic pending orders, parallel commands with rollback, and toasts when compaction needs all servers updated.

Mobile:Move up / Move down in the pinned thread overflow menu with the same ordering logic, in-flight guard, sequential apply/rollback, and alerts for unsupported environments.

Docs: New user guide for organizing threads; list rendering switches from creation-order sort to synced pinned order (with compatibility fallback).

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

Note

Add synced pinned thread reordering via drag-and-drop and context menu

  • Introduces a PinnedThreadOrder rational-fraction type (e.g. 3/7) stored in the projection_threads table and carried through contracts, projections, and client state to represent an explicit server-synced pin position.
  • Adds sortPinnedThreads, pinnedThreadOrderForMove, and pinnedThreadOrderUpdatesForMove utilities in threadSort.ts to compute new orders using mediants, with full-list compaction as a fallback when no representable value fits.
  • Web sidebar (SidebarV2.tsx) gains drag-and-drop reordering via dnd-kit and context-menu 'Move up/down' actions; mobile (HomeScreen.tsx, ThreadNavigationSidebar.tsx) gains equivalent context-menu actions.
  • Reordering is gated on the new threadPinReordering server capability flag; mixed-capability environments show an alert and unsupported environments return a typed ThreadPinReorderingUnsupportedError.
  • Optimistic UI updates are applied immediately and rolled back on failure; compaction-required scenarios prompt a user alert before proceeding.
  • Migration 038 adds the pinned_order column to projection_threads.

Macroscope summarized 138c1d8.

@coderabbitai

coderabbitaiBot commented Aug 6, 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: 56403cff-effa-4cdc-a733-301b3a024692

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-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026

@macroscopeappmacroscopeappBot 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: the new web reorder path reuses ThreadPinningUnsupportedError, whose caller-visible message describes pinning rather than pin reordering. Everything else (namespace subpath imports in the new migration, decider/projector event handling, contracts schema additions) follows the service conventions.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/web/src/hooks/useThreadActions.ts Outdated
@f-trycua
f-trycua marked this pull request as ready for review August 6, 2026 14:36
Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/server/src/orchestration/projector.ts
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Comment threadapps/server/src/orchestration/projector.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature (synced pinned thread order) with schema changes, new API commands/events, complex sorting algorithms, and cross-platform UI additions. An unresolved review comment also identifies a concurrency bug in the web implementation. New features of this scope warrant human review.

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

Comment threadpackages/client-runtime/src/state/threadSort.ts
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Aug 6, 2026
Comment threadapps/mobile/src/features/home/HomeScreen.tsx
Comment threadapps/mobile/src/features/home/HomeScreen.tsx Outdated
Comment threadapps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@f-trycua
f-trycuaforce-pushed the agent/reorder-pinned-threads branch from 70e50e6 to 2ae2873CompareAugust 7, 2026 09:43
Comment threadpackages/client-runtime/src/state/threadSort.ts Outdated
Comment threadapps/web/src/components/SidebarV2.tsx
Comment threadpackages/client-runtime/src/state/threadReducer.ts Outdated

@cursorcursorBot 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 138c1d8. Configure here.

})();
},
[orderedPinnedThreads, pinnedOrderingFullyVisible, reorderPinnedThread, serverConfigs],
);

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.

Web reorder lacks in-flight lock

Medium Severity

movePinnedThread never guards against overlapping reorders. Mobile blocks with pinnedReorderInFlightRef, but web can start another drag or move-up/down while prior reorderPinnedThread calls and pendingPinnedOrderByKey updates are still in flight, so concurrent moves can compute ranks from a stale list and leave the synced order wrong.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 138c1d8. Configure here.

t3dotgg added a commit that referenced this pull request Aug 7, 2026
…le Move up/down
Review fixes and cherry-picks from the parallel implementation (#5528):
- The optimistic drag override now releases on ANY pinned-membership change
(new pin, unpin, snooze/wake) instead of only exact sequence match, so a
pin landing mid-drag can no longer freeze the override and launder a
stale order into later drags.
- attemptPin anchors the new pin's key against the DISPLAYED order, and
every pin path (chat header, context menus, mobile) now sends a
top-of-run orderKey, so the same action never places differently.
- Pin-order key math moved to client-runtime (state/thread-sort) and is
shared by web and mobile instead of mirrored.
- Mobile: Move up / Move down actions in the pinned row menu, computed
against the canonical arranged order so search or project scoping never
disables or misdirects a move.
- Docs: user page on organizing threads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maria-rcks

Copy link
Copy Markdown
Collaborator

superseded by #5581

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@f-trycua@maria-rcks