Skip to content

fix(app): every left-nav section changes the main area (0388) - #617

Merged
crs48 merged 12 commits into
mainfrom
claude/left-nav-sections-audit-4e7075
Jul 21, 2026
Merged

fix(app): every left-nav section changes the main area (0388)#617
crs48 merged 12 commits into
mainfrom
claude/left-nav-sections-audit-4e7075

Conversation

@crs48

@crs48 crs48 commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Implements exploration 0388.

The report

"When I click on People or Views or a lot of the sections, nothing happens. The main screen should pretty much change for every section, I think."

Accurate, and not a rendering bug. Five of eleven sections were kind: 'lens', and the lens branch of useActivateSection called setActiveLens(...) and returned — no navigate(). activeLensId was read only inside the sidebar; nothing in the main region ever subscribed to it.

Two of those five were regressions from the 0353 nav rewrite: People used to be a route to /crm, and Views' natural home /data lost its entry. Both routes still rendered fine — they were simply unreachable from the nav.

Two further findings while auditing:

  • The whole kind: 'panel' surface class lost its entry point in 0353. AI was the casualty with no successor.
  • The floating Assistant's send handler called setActiveSurface('ai') and cleared the input. Under unified nav nothing reads activeSurface, so every question typed into the dock since 0353 was silently destroyed.

The rule

Every primary nav row changes the main area. No exceptions.

A lens is now a destination as well as a filter — SidebarLens carries a route, so the mapping lives with the lens instead of in a switch.

Section Goes to
All / Docs / Chats /, which renders that projection
People /crm — restored
Views /data — restored
AI /ai — restored
Inbox / Tasks / Meetings / Discover / Finance unchanged
Companion / Experiments / Import no longer URL-only
Analytics absent unless VITE_TELEMETRY_DASHBOARD is set

Active state now derives from the route, so exactly one row is ever lit — the old predicate could light none (a non-pinned lens) or leave the sidebar claiming "Views" while the main area showed Meetings. A route owned by one lens restores that lens on load, so reloading /crm comes back with People selected.

Two supporting fixes: the 0166 startup-surface redirect now fires once per session (otherwise clicking Docs would bounce straight back out of /), and SavedView gets a Tier-1 seeder — it had only Tier-2 coverage, which the demo profile skips, so Views read "Nothing here yet." on first contact.

Verification

  • apps/web/src/workbench/sidebar/sections.test.ts — 12 tests; fails if a section is added without a destination, or if any location lights more than one row
  • tests/e2e/src/left-nav.spec.ts — 5 tests clicking every section in the real shell, wired into the required editor-ux lane as a chromium-only step (the mobile shell renders no sections)
  • 1101 unit tests pass; pnpm lint 0 errors
  • Manually verified in the app: all 14 sections change the main area, Views shows seeded rows in a fresh ?demo=1 workspace, Analytics absent, reload on /crm restores the People lens, /finance → Docs returns home without stranding

Known-adjacent, deliberately out of scope

/tasks still renders its own VIEWS / PROJECTS nav inside the main area — the second-nav pattern 0353 set out to remove. Tracked as a follow-up rather than smuggled into this change. MobileShell renders no sections at all, so none of this reaches mobile; noted as an open question in the exploration.

🤖 Generated with Claude Code

xNet Test and others added 8 commits July 21, 2026 13:07
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
The AI chat surface was a `kind: 'panel'` entry in the legacy SURFACES list.
The 0353 unified-nav rewrite kept only lens/route/node sections and made the
bottom island render the tree unconditionally, so every panel surface lost its
entry point — AiChatPanel stayed registered and fully functional with no way in.

Worse, the dock's compact Assistant handed off via setActiveSurface('ai'), which
under unified nav opened nothing and cleared the input: every question typed
into the dock since 0353 was silently discarded.

- add /ai, rendering AiChatPanel in the main area (capped measure)
- add the AI section, so it obeys the one rule this nav is held to:
  every primary row changes the main area
- AiChatPanel takes an optional initialPrompt
- the dock now navigates to /ai?q=<question> instead of dropping it

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
Five of eleven sections were kind: 'lens' and only re-filtered the sidebar —
in a vertical list of otherwise-navigating rows, a click indistinguishable
from a broken button. Two of them (People, Views) had lost real destinations
in the 0353 rewrite: /crm and /data still render and were unreachable.

A lens is now a destination as well as a filter:

- SidebarLens gains `route`; useActivateSection navigates on every branch
- people -> /crm and views -> /data recover their pre-0353 surfaces
- '/' renders the active projection (Everything / All Documents / Chats),
  with chats built from the same sidebar sources the tree uses
- active state derives from the route, so exactly one row is ever lit and
  the sidebar can't claim Views while the main area shows Meetings
- a route that one lens owns restores that lens on load (/crm -> people)
- the startup-surface redirect fires once per session, so navigating to '/'
  on purpose no longer bounces back out
- Analytics is absent unless VITE_TELEMETRY_DASHBOARD is set, rather than
  present and always dead-ending
- Companion, Experiments and Import stop being URL-only
- dead route:/today and route:/crm icon keys removed

sections.test.ts guards the rule: every section resolves to a destination,
and exactly one section is active at any location.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
SavedView had only Tier-2 auto-generator coverage, and the landing demo
profile runs with includeAuto: false — so the Views section of the left nav
read "Nothing here yet." in every demo and every fresh workspace.

Adds a Tier-1 saved-views seeder (descriptors built with
defineSavedViewDescriptor, so they validate like user-authored views) and
puts its domain in the landing profile. A test asserts the demo profile
covers the schemas the nav has sections for.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
…388)

Unit tests cover the resolution logic; this covers what they can't — that
clicking the real row in the real shell repaints the main region. Wired into
the required editor-ux lane as its own chromium-only step, since the mobile
shell renders no sections.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-617 July 21, 2026 21:20 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

🖼️ UI changes in this PR

Screens

✏️ Data _(SSIM 0.997)_
before after diff
before after diff
✏️ Home _(SSIM 0.982)_
before after diff
before after diff

Interactions

🎬 Create a page and use the editor

Create a page and use the editor

▶ Watch MP4

Auto-captured by CI · run. Informational — not a blocking check.

Three CI failures, all mine:

- prettier: two files unformatted
- devtools typecheck: mapping defineNodeQueryAST over a heterogeneous
  schema array collapsed the generic to a union it can't accept, so each
  descriptor is now built at its own call site
- editor-ux: the home heading now names the active lens, and the default
  lens is All, so six specs waiting on /all documents/i as their shell-
  neutral readiness gate timed out. The gate matches either heading.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-617 July 21, 2026 21:33 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #617.

github-actions Bot added a commit that referenced this pull request Jul 21, 2026
The electron-parity gate requires every top-level web route to be either
COVERED or WAIVED. /ai is waived for the same reason as companion: the
desktop renderer has no AI surface wired.

home-lens.tsx was never a route — it is the home surface's lens
projections — so it moves to components/HomeLens.tsx rather than being
waived as a route it isn't.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-617 July 21, 2026 21:47 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
The file-attachments work (#614) added BlobService raw-blob / thumbnail /
transfer methods and the BlobTransferQueue class without regenerating the
public API report, so the api-report gate was red on main. This records
that surface. Purely additive — no exports removed.

Not part of 0388; folded in here to unblock the required typecheck lane
(the drift pre-existed on main and blocks any PR).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-617 July 21, 2026 21:57 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
@crs48
crs48 temporarily deployed to pr-617 July 21, 2026 22:19 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
@crs48
crs48 merged commit 6702958 into main Jul 21, 2026
22 checks passed
@crs48
crs48 deleted the claude/left-nav-sections-audit-4e7075 branch July 21, 2026 22:28
github-actions Bot added a commit that referenced this pull request Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant