## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - People enter that work through the workspace, agent conversations, and tasks. > - Coordinator and Agent Chat still require experimental enrollment. > - Task link prefetches do not warm the compact queries used by the default task view. Chat also waits for a request when its navigation list already holds the conversation. > - This pull request makes Coordinator and Agent Chat standard and reuses the reads needed for navigation. > - People can choose Classic workspace in Experimental settings. Cached work can appear while fresh data loads. ## Linked Issues or Issue Description **What existing behavior does this improve?** Workspace selection, Agent Chat availability, and navigation between Chat, Tasks, and task details. **Subsystem affected** Cross-cutting: UI, workspace preferences, instance settings, and the database migration. **Current behavior** People must enable Coordinator and Agent Chat in Experimental settings. Opening a task can repeat requests because prefetch warms the full detail and comment queries, while the default view reads compact task data and a recent comment window. Opening Chat waits for a detail request even when the current person's conversation list contains it. **Proposed behavior** Coordinator is the standard workspace for everyone. Experimental settings offer Classic workspace, off by default. Old Coordinator experiment values do not select Classic. Agent Chat is available to everyone, including instances with an old saved or managed off value. Task link intent warms the queries used by the mounted view. Chat can use the current person's company-scoped conversation list during refresh. **Reason and benefit** People can use the standard workspace without setup. Repeat navigation can show cached content while the server refreshes it. **Breaking changes** Existing Coordinator experiment and Agent Chat off values no longer disable these surfaces. Classic requires an explicit new opt-in. The workspace API keeps its existing response shape and audit checks. The migration retains legacy values and adds a separate Classic preference. Execution permissions, company access, and chat privacy checks still apply. **Additional context** Roadmap check: this graduates existing surfaces and improves their navigation. It does not add a new agent execution capability. Duplicate searches found no open Coordinator workspace PR. Related server cache work, Refs: #17828, addresses compact issue-list invalidation; this PR addresses client navigation queries. ## What Changed - Add a default-off Classic workspace preference. Derive the existing workspace API response from that choice. Keep personal persistence, account isolation, and audited writes in the workspace preference service. - Replace the Coordinator experiment control with Classic workspace. Use Coordinator while preferences load. Update the existing settings examples and navigation recipe. - Retire the Agent Chat experiment control. Ignore old stored and managed off values. Retain the compatibility key and the existing execution and access checks. - Reuse account- and company-scoped chat list data with its original freshness timestamp. - Share compact task and recent-comment query options between prefetch and the task view. Keep full-history prefetch for Classic tasks and expanded history. - Add upgrade, replay, cache, account isolation, and browser switching regressions. Update product, database, development, and roadmap documentation. ## Verification - Targeted preference, settings, migration, cache, and UI regression tests passed during implementation. The cache tests hold refresh requests pending and check that content still renders. They also check account isolation and stale refresh behavior. - A real browser test verified fresh Coordinator defaults, Classic opt-in persistence, and return to Coordinator. It used an isolated source checkout with fresh data on macOS. - Token, migration numbering and safety, map, and Storybook catalog checks pass after the rebase. - Repository typecheck and build pass. Typecheck and token gates also pass after review repairs. The broad local run passed all six chat integration shards (1,931 tests). It then found the host-CLI-dependent recovery fixture described below. Its remaining duplicate work was stopped after the full current-head CI matrix passed; this is not a claim that the broad local command completed green. - Review repairs passed 419 UI/migration fixture tests, 19 Coordinator navigation tests, and all 214 tests in the five affected server suites. The 24 Chat/workspace browser tests pass, including standard Coordinator switching and explicit Classic persistence. - The broader browser repair run passed 85 tests. It retained two failed assertions and skipped five later serial cases. The affected files then passed all 11 tests after the fixes: reopen the desktop panel after reload and open More for Audit and Connectors. This includes the five serial cases that had not run. - The broad local suite exposed a recovery fixture that executed the host Codex CLI during a simulated remote probe. On a host with Codex 0.154.0, model fallback broke its fixed-model assertion. The fake sandbox now reports Codex 0.160.0. All 20 selected recovery/provider compatibility cases pass after the repair. - A CLI company import/export suite timed out during server startup in the second CI run. The port fallback is intentional in that fixture. No root cause was established. That suite passes on the final commit in CI. This records recovery, not a claimed product fix for the earlier timeout. - The first CI run exposed remaining assumptions about the retired flags and Classic UI. The repair commit updates those fixtures and navigation steps. It also restores the missing enabled Cases destination in Coordinator. Earlier local recovery attempts used the wrong fixture notification and advanced fake time during live execution; the corrected tests use the subscribed recovery queue and wall time during execution. - Greptile reviewed commit `98972b030d4505d838427a2fca6b196b8cad6d47` at **5/5** with no new comments. The original finding is resolved. - Current-head CI is green: **56 successful checks**, with three checks skipped by workflow filters. This includes typecheck, build, the complete Vitest matrix, all eight browser shards, Runner verification, release checks, and security checks. [Final CI run](https://github.com/paperclipai/paperclip/actions/runs/42132651414). - Typecheck caught missing `pid` and `startedAt` fields in the simulated command result. The fixture now returns the complete process contract, and the server test-layer typecheck passes. - Storybook catalog alignment was checked. Storybook play tests were not run. Hosted latency and cold bundle loading were not measured. ## Risks - The new default changes the workspace for people who previously left the Coordinator experiment off. They can opt into Classic in Experimental settings. - The additive migration must run before the new server code. It is safe to replay and preserves explicit Classic choices. - Cached content can be stale during background refresh. Existing query invalidation and source timestamps still control freshness. - These changes reduce avoidable loading waits. They do not establish a measured improvement in hosted request latency or initial bundle download time. ## Model Used OpenAI Codex, based on GPT-6, with reasoning, repository tools, code execution, and browser automation. The exact serving revision and context-window size are not exposed in this session. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Scott Tong <scott@scottsmbpm5max.lan> Co-authored-by: Paperclip <noreply@paperclip.ing>
9.8 KiB
navigation
| navigation | ||||||
|---|---|---|---|---|---|---|
|
Navigation, profile, and announcements
People organize their sidebar, move between company resources, maintain their profile, and dismiss product announcements with the correct persistence and identity scope.
Feature ID: navigation-preferences.
Implementation: sidebar, profile, announcements.
Agent access: companion.
Sub-features
navigation:navigation-preferences/navigation— use current sidebar links, favorites, recents, and available layout controls.preferences:navigation-preferences/preferences— persist supported ordering/collapse choices for the intended user/company, and the personal experimental workspace choice.profile:navigation-preferences/profile— edit personal identity and inspect public profile links.announcements:navigation-preferences/announcements— inspect and dismiss an announcement with its intended instance-wide user scope.fallbacks:navigation-preferences/fallbacks— handle missing resources and old deep links without presenting another resource as the target.command-palette:navigation-preferences/command-palette— open quick search and creation actions with keyboard shortcuts, then carry query/filter intent into full search.
How to get to it (user POV)
sidebar-deep-links
Use starred/recent/sidebar links and direct company-prefixed URLs.
profile-announcements
Use Settings → Profile, /u/:userSlug, and the announcement well when a publication is available.
palette-shortcuts
Press Cmd/Ctrl+K to open the command palette. / focuses the current page search or opens quick search; ? opens shortcut help. Outside an input or modal, c starts New task and g then i opens Inbox/My work. In the palette, use Search all or Cmd/Ctrl+Enter for the full results page.
Driving it with Playwright and the Paperclip CLI
Preconditions: follow the baseline. Use two test users and companies; record the selected UI shell and any client-local preference storage.
sidebar-deep-links
Automated: sidebar and sidebar preference routes cover UI/server behavior.
Manual: Star and reorder supported resources, collapse a section, navigate and reload. Switch company/user and inspect the intended preference scope. Open an unavailable resource and a legacy route; verify clear fallback or correct redirect without leaking another company’s state.
Record persistence separately: section collapse is in-memory and reopens after reload; global sidebar collapse is disabled. Streamlined starred projects sort alphabetically. Recents are browser-local by user/company; stars and supported ordering are saved server-side. Local-trusted mode does not prove two-user isolation.
profile-announcements
Automated: profile page, announcement hook, and announcement routes cover separate UI/persistence layers.
Manual: Change a disposable user’s display details, reload, and inspect an attributed profile link. Dismiss a fixture announcement, switch companies, and verify it remains dismissed for that user; check another user still has their own dismissal state.
palette-shortcuts
Automated: Command palette, shortcut hook, shortcut rules, and cheatsheet test components and keyboard rules. Company search covers search contracts; browser focus and identity transitions still need a live check.
Manual: Use uniquely named visible and private task/project fixtures. Open the palette, find a permitted result, follow it, and reload the destination. Enter text with quick-filter chips such as assignee:me, is:open, and updated:>7d; use Search all and Cmd/Ctrl+Enter in separate attempts and verify the resulting query and filters. Switch person/company and confirm private results do not leak. Test / on a page with search and a page without it; inspect ?, c, and g i. Type those keys inside an editor and a modal: they must not unexpectedly navigate or create work. Test a create action through its normal dialog and inspect the actual saved resource separately.
Sources: Command palette, shortcut hook, query parser, and search routes.
Gotchas
-
Cmd/Ctrl+B is not a supported global sidebar shortcut. Use the current shortcut help and verify that typing and modal focus suppress navigation chords.
-
Announcement dismissals are intentionally instance-wide user preferences, unlike company-scoped domain data.
-
Legacy/production shells need their own navigation check when affected.
-
A route redirect is part of the journey; do not document a removed screen as if it still renders.
Storybook verification
preferences
Capability ID: navigation-preferences/preferences.
Scope: ui Storybook: Mount Sidebar using real preference boundary with stars/order/collapse/recents state. Clearly distinguish in-memory section collapse, browser-local recents and server-saved stars/order. Production: GET/PUT /sidebar-preferences/me and /companies/{id}/sidebar-preferences/me plus stars must retain intended user/company isolation across reload and switch. Section collapse reopens after reload; global collapse is disabled. Sources: Source: Sidebar.tsx, sidebar-preferences.ts, sidebar-preferences.ts. Tests: Sidebar.test.tsx, sidebar-preferences-routes.test.ts
fallbacks
Capability ID: navigation-preferences/fallbacks.
Scope: browser Storybook: A NotFound rendering story can help polish, but missing-resource/legacy-deep-link capability principally needs real App/router/browser scenarios preserving company and query intent. Production: Cold-open invalid company/resource and retired URL; verify explicit fallback or correct canonical redirect without silently targeting a different resource/company. Sources: Source: NotFound.tsx, App.tsx, company-routes.ts. Tests: App.activity-routing.test.tsx, App.cases-routing.test.tsx, App.test.tsx, company-routes.test.ts
Recent task refresh performance
Saved recent tasks render immediately. One summary batch refreshes at most five IDs per company/account without passive full-detail or workspace inspection. Successful omissions remove unavailable entries; failed reads preserve history. Verify rename, inbox archive, pause/restart, reload, cross-tab updates and account switches. Inbox archive does not remove the task from recent history.
Personal workspace choice
Coordinator is the standard workspace. Settings → Experimental → Classic workspace opts the current person into the previous workspace; it defaults off. Historical Coordinator experiment values do not enable Classic. The server saves the choice by user across companies, separate from instance feature flags. The local-trusted identity is shared Local Board, not evidence of multi-user isolation. Agent Chat is available to everyone independently of this personal workspace choice. Its retired instance flag and historical managed off values are ignored.
Automated: preference hook, Classic settings card, authorization, and database persistence. Manual: toggle on/off, reload, switch companies/accounts, and simulate failed reads and saves. Confirm existing work is unchanged and a failed save keeps the current choice. The Settings card story uses the production component with simulated API responses; it does not establish real persistence or permission behavior.
Coordinator More exposes a pin/unpin button beside every destination. Pinned pages appear above More in pinning order and retain the existing company-aware routes. Unpin from either the flyout or the pinned row. The list is personal to the current user in this browser, shared across companies; it does not sync across devices. Only known route names are rendered. Storage failures show a save error. The pin hook owns browser persistence; sidebar tests cover pin/unpin, remount persistence, account separation, unknown routes and cross-tab updates. Manual: pin with mouse and keyboard, reload, follow a pinned link, unpin from both locations, and check the mobile drawer. Local-trusted checks do not prove two-user authenticated browser isolation.