Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver
, '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

Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver
, '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

Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver
, '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

Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver
, '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

Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver
, '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

Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver
, '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

Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver
, '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

Make large archives easier to manage across web and mobile - #7387

Closed
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux
Closed

Make large archives easier to manage across web and mobile#7387
Quicksaver wants to merge 175 commits into
pingdotgg:mainfrom
Quicksaver:split/archive-settings-ux

Conversation

@Quicksaver

@QuicksaverQuicksaver commented Aug 18, 2026

Copy link
Copy Markdown

Summary

The old Archive settings view did not hold up once an archive got large. Web used a flat list, native offered a different set of controls, and archived-only workspaces could disappear because snapshots were tied to environments with active projects.

This turns Archive into a dense project browser on both clients. Threads are grouped by project and environment, searchable with ranked multi-term matching, sortable by archive or creation time, and manageable one at a time or in project-sized batches. It also loads every configured environment, keeps successful results visible when another environment fails, and applies the same confirmation, locking, and partial-failure rules across row and bulk actions.

The practical result is that large archives stay scannable, archived-only work remains reachable, and destructive or overlapping actions cannot quietly misreport what happened. Native Settings now exposes Archived Threads in both local-only and T3 Connect modes without folding the legacy waitlist route into the new Archive route.

Reopened

This reopens #3552. That PR was closed because its connection to #2829 was only tangential. The archive work itself is independent. The branch continues to follow main, and #2829 can merge here later if it lands first.

Alongside #7386 and #4384, this delivers useful behavior that does not need to wait for orchestration v2.

What changed

  • Replaced the flat web Archive panel with collapsed project groups, compact rows, project favicons, context-aware environment labels, and hover or keyboard-focus actions. Archive context menus follow the shared restore, destructive-action, and separator conventions. Native uses matching project sections with platform-native swipe and long-press actions.
  • Added persistent, case-insensitive archive search on both clients. Multi-term results rank exact phrases first, then titles matching every term, then partial matches. Search opens matching groups, scopes project actions to visible rows, and updates the native list without remounting it.
  • Added archived and created-time sorting, invalid archive-date fallback, relative age columns, and native project ordering that follows the selected field and direction.
  • Load archived snapshots from every configured environment, including archived-only workspaces. Active rows are excluded, while partial failures remain visible with their error and retry action above the environments that loaded successfully.
  • Added per-thread and project-level unarchive and delete actions. Confirmations follow the shared web delete preference and native guarded flows, and web delete dialogs use the destructive theme.
  • Prevented overlapping row and bulk mutations with collision-safe per-thread reservations. Bulk work uses bounded concurrency, stops scheduling after unexpected exceptions, waits for active workers, refreshes once after each attempt, and reports successes, failures, and already-running skips separately.
  • Exposed Archived Threads in local-only and T3 Connect Settings through one shared settings tail and route contract. Archive stays in the header-owning content stack, while the legacy waitlist alias remains a separate auth route.
  • Moved grouping, ranking, sorting, and bulk-action logic out of the React components into focused web and native modules, with regression coverage for archive behavior and archived-only project deletion safeguards.
  • Added an Archive user guide and updated the documentation index and glossary to distinguish settled, archived, restored, and permanently deleted threads.

Validation

  • Focused archive context-menu checks passed with 2 files and 33 tests after the latest upstream merge.
  • Focused web and mobile test runs passed with 4 files and 49 tests, 2 files and 44 tests, 3 files and 32 tests, 2 files and 29 tests, 1 file and 9 tests, 1 file and 10 tests, and 1 file and 12 tests. These runs covered grouping, search ranking, sorting, timestamp fallback, action reservations, concurrency and partial outcomes, row rejection feedback, focus behavior, and archive-load errors.
  • Focused formatting, type-aware lint, and git diff --check passed for the files affected by the review follow-ups.
  • Playwright verified active-row filtering, invalid timestamp fallback, search ranking, sorting, confirmation and overlapping-action states, Settings search and focus, row alignment and pointer behavior, single-row unarchive, mouse and keyboard focus behavior, and partial and total environment-load error retries.
  • Two iOS runs verified incremental search without a list remount and long-press unarchive of one archived row. A separate sort-control attempt reached Archive but could not render its fixture rows. The requested serve-sim stream registered the framebuffer but failed to encode frames with encodingFailed, so native evidence used semantic UI snapshots and screenshots.
  • Android verification on emulator-5554 loaded the disposable archive fixture and opened the native Unarchive and Delete actions from a row long press. Metro later exited with an unrelated watcher ENOENT after the affected flow completed.
  • Package typechecks were attempted but remain blocked by unrelated existing errors elsewhere in the web and mobile packages.

Proof

Archive settings grouped project browserNative archived threads screen

🤖 Generated by GPT-5 in Codex via T3 Code


Note

Medium Risk
Touches permanent thread deletion, bulk mutations, and multi-environment archive loading; behavior is heavily tested but mistakes could delete data or misreport partial failures.

Overview
Replaces flat archive lists with a project-grouped browser on web settings and native Archived Threads, aligned on grouping, ranked search, sortable Archived / Created columns, favicons, and environment labeling.

Data and discovery: Snapshots load from all configured environments (including archived-only workspaces), with partial load errors shown above successful groups. Web settings search can jump to Archive and focus the search field. Multi-term title search ranks phrase and all-token matches; active search expands matching groups and scopes project bulk actions to visible rows.

Actions: Row and project unarchive / delete use collision-safe per-thread locks, guarded confirmations (destructive delete on web where applicable), bounded-concurrency bulk runners with partial-outcome messaging, and a single refresh after bulk attempts. Native adds swipe, long-press menus, environment filter, and list updates that avoid remounting on every keystroke.

Structure: Logic moves into ArchiveSettings.logic.ts and archivedThreadList.ts with expanded tests. Mobile settings share a General → Appearance → Legacy → Archive → App tail and register Archive via settingsRouteScreens while keeping the waitlist deep link on auth. Server test coverage adds project.delete rejection when only archived threads remain without force.

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

Note

Add archive management panel with search, sorting, and bulk actions

  • Introduces ArchivedThreadsPanel on web and refactored ArchivedThreadsScreen on mobile with search, multi-field sorting (archivedAt/createdAt, asc/desc), per-thread context menus, and project-level bulk unarchive/delete scoped to matching or all threads
  • Shared logic in archivedThreadList.ts handles tiered search scoring, grouping, sorting, and bounded-concurrency bulk actions via runArchivedThreadActions
  • useThreadActionExecutor now returns tri-state results (succeeded/failed/skipped) and accepts ThreadActionOptions to suppress failure alerts and archive refresh on a per-call basis
  • Thread identity keys switched to JSON tuple (environmentId, id) in threadActionKey, archivedThreadActionKey, and archivedProjectGroupKey, replacing scopedThreadKey/scopedProjectKey to avoid collisions when ids contain separators
  • Behavioral Change: useArchivedThreadListActions no longer accepts onCompleted callback; unarchiveThread/deleteThread return Promise<ThreadListActionResult>; useThreadActions.unarchiveThread/deleteThread accept { refreshArchivedThreads: false } (default true unchanged)

Macroscope summarized f2b1cdc.

- Group archived threads by project with collapsible sections
- Add sortable archived/created columns and inline row actions
- Support direct delete and bulk project actions with confirmation
- Replace inline project-level unarchive/delete buttons with a right-click menu
- Keep the existing confirmation flow for bulk archived-thread actions
- Add case-insensitive search across archived thread titles
- Rank exact phrase, full-term, and partial matches; auto-expand matching projects
- Update archive empty states and preserve project actions under search
- Use filtered archive rows for project actions during search
- Use the full project archive list for bulk context actions
- Keep search filtering from narrowing project-wide confirmations
- Limit project archive actions to filtered visible threads
- Add archive search ranking tests
Selective archive-settings portion of main commit 1c6f66b. Keeps the branch-local extracted search-ranking helper and tests while preserving the project header interaction cleanup.
- Move archived search and grouping into logic helpers
- Share bulk action and sort helpers with the panel
- Add tests for grouping, sorting, and bulk action concurrency
- Wait for active bulk-action workers before rethrowing
- Assert archived project bulk actions cover queued threads
- Aggregate archived bulk action errors
- Index archived threads by project
- Strengthen archived settings logic tests
- Skip local dialog confirmation when no local API is available
- Encode environment and project ids as tuple keys
- Cover colon-containing ids in archive grouping tests
- Reuse canonical archive group keys in panel state
- Cover colon-containing project key collisions in tests
- Split archived thread UI into its own component
- Re-export the panel from the settings entrypoint
- Keep archived delete confirmations when browser APIs are used
- Add an explicit project actions menu button
- Add the project action spacer column to archived thread rows
- Restore no-local-api confirmation behavior
- Share interrupted failure handling for archive menus
- Surface multiple archived bulk action errors
- Require confirmation when local API is unavailable
@coderabbitai

coderabbitaiBot commented Aug 18, 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: 4cf030e9-8341-4edb-960d-816e3013d1e2

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:XXL 1,000+ changed lines (additions + deletions). labels Aug 18, 2026
Comment threadapps/mobile/src/features/archive/ArchivedThreadsScreen.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts Outdated

@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.

UI Consistency: 3 findings

Reviewed the changed web UI surface (ArchiveSettings.tsx, ArchiveSettings.logic.ts, settingsLayout.tsx, SettingsPanels.tsx, useThreadActions.ts, routes/settings.archived.tsx). The panel composes the shared Button, Input, Tooltip, and settings-layout primitives correctly, and the removed SettingsPanels archive block has no remaining consumers. Three concrete issues below: one shared-CSS ownership gap for the new settings-search destination, one primitive-geometry override, and one invalid ARIA attribute.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/mobile/src/features/home/useThreadListActions.ts
@macroscopeapp

macroscopeappBot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial new feature for archive management including search with ranking, bulk actions, sortable columns, and project grouping across web and mobile platforms. The scope of new components, state management patterns, and user-facing behavior warrants human review.

You can add or adjust custom eligibility rules. Learn more.

- restore Android row menus and collision-safe title actions
- preserve archive ranking tiers and accessible web feedback
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/mobile/src/features/archive/archivedThreadList.ts

@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.

Reviewed the new web Archive settings surface (ArchiveSettings.tsx, settingsLayout.tsx, index.css) against the shared control system. The previously flagged items (search-target pulse selector for the input, rounded-md overrides of --control-radius, and aria-sort on a button) are all resolved. Three remaining consistency issues in the new dense archive table, all on changed lines.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- keep web partial-match tiers consistent with mobile
- restore pointer affordances and project-column alignment
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
- settle unexpected unarchive and delete rejections
- cover both single-row failure toasts
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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.

Two findings on the new Archive panel: the row action reveal deviates from the documented sidebar list-row pattern, and the new settings-search pulse rule for inputs can never take effect.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/index.css Outdated
- reveal archive actions only for keyboard-visible focus
- remove the overridden input pulse radius declaration
🤖 Co-authored by GPT-5 in Codex via T3 Code

@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 f20d7e4. Configure here.

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx
- keep successful archive groups visible beside the load warning
- expose a retry action and cover the mixed-result state
🤖 Co-authored by GPT-5 in Codex via T3 Code
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated

@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.

Reviewed the changed web UI in apps/web/src/**. Two findings on the new partial-archive-failure banner; the earlier sort-header, control-radius, cursor, focus-visible and pulse-selector findings all look addressed on this head.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Comment threadapps/web/src/components/settings/ArchiveSettings.tsx Outdated
Use the shared error alert for partial and total archive failures.
Keep retry available and align its accessible name with the visible label.
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
🤖 Co-authored by GPT-5 in Codex via T3 Code
@Quicksaver

Copy link
Copy Markdown
Author

Branch will be rebased and PR reopened at a later time.

🤖 Generated by GPT-5 in Codex via T3 Code

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.

1 participant

@Quicksaver