Skip to content

feat(web): split sidebar sessions into My sessions / Shared with me tabs - #2156

Merged
serena-ruan merged 3 commits into
mainfrom
shared_sessions_group
Jul 8, 2026
Merged

feat(web): split sidebar sessions into My sessions / Shared with me tabs#2156
serena-ruan merged 3 commits into
mainfrom
shared_sessions_group

Conversation

@serena-ruan

@serena-ruan serena-ruan commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Related issue

N/A

Summary

Splits the web sidebar's session list into two tabs — My sessions and Shared with me — instead of stacking sessions-shared-with-you in an inline collapsible section under the owned list.

  • My sessions keeps the existing Pinned / Projects / Sessions structure. Shared with me is a flat, headerless list of every non-archived session the viewer doesn't own, with its own infinite scroll. "New session" snaps back to My sessions.
  • Pinning and project folders are My-sessions-only tools — both are built from owned-only sessions, so a shared session that's pinned or filed into a project renders only on the Shared tab (each session lives in exactly one place).
  • The shared list is computed from notArchived (not rest), so a shared session isn't dropped by the owned tab's pin/file filtering.
  • The tab strip only renders on a multi-user server — gated on !isCurrentServerLocal(), the same predicate AppShell uses to disable the Share affordance (serverOrigin.ts: "Sharing a session from a loopback-only server produces links nobody else can open"). A loopback-only local server has a single user and can't share sessions, so the split is meaningless there and the list falls back to the owned sessions.
  • Keyboard nav and shift-select are tab-aware; on the shared tab they ignore the collapsed set (the list always renders expanded), so a stale persisted "Shared with me" collapse from the old inline section can't silently empty them.
  • Pagination is one stream (owned + shared mixed, updated_at desc); the sentinel stays mounted even when the current tab is empty on the loaded window but more pages exist, so a tab whose sessions live on a later page keeps loading instead of showing a false "empty" state.

Test Plan

  • cd web && npm test — full suite green.
  • cd web && npm run buildtsc -b && vite build clean.
  • npx tsc --noEmit — clean.
  • Sidebar unit tests (63 across the 3 Sidebar suites), including:
    • owned/shared split across the two tabs,
    • projects/pinning are My-sessions-only (incl. pinned-shared and filed-shared regression tests),
    • New session snapping back to My sessions,
    • tabs hidden on a single-user (local) server, falling back to the owned list,
    • empty tab keeps paginating when more pages exist.

Demo

Screen.Recording.2026-07-08.at.5.30.22.PM.mov

Type of change

  • Bug fix
  • Feature
  • UI / frontend change
  • Refactor / chore
  • Docs
  • Test / CI
  • Breaking change

Test coverage

  • Unit tests added / updated
  • Integration tests added / updated
  • E2E tests added / updated
  • Manual verification completed
  • Existing tests cover this change
  • Not applicable

Coverage notes

Manual verification: unit-level via the Sidebar suites (mocking @/lib/serverOrigin to toggle multi-user vs local). The multiUser gate, per-tab keyboard-nav/shift-select ordering, owned-only pin/project construction, and empty-tab pagination are exercised by the tests. The e2e-ui runner has no workspace so the tab UI isn't covered there.

Changelog

Sessions shared with you now live in a dedicated "Shared with me" sidebar tab (multi-user servers only)

This pull request and its description were written by Isaac.

@github-actions github-actions Bot added the size/L Pull request size: L label Jul 8, 2026
@omnigent-ci

omnigent-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Polly AI Review

Review: split sidebar sessions into My sessions / Shared with me tabs

1. Blocking issues

None. The core logic is sound and well-verified:

  • The multiUser gate (!isCurrentServerLocal()) correctly mirrors the existing Share-affordance predicate, and activeTab={multiUser ? activeTab : "mine"} guarantees the fallback list is always the owned set on a local server.
  • The shared list is computed from notArchived rather than rest, so a pinned/filed shared session correctly stays on the Shared tab — the diff comment matches the code.
  • Keyboard-nav (orderedConversationIds) and shift-select (getVisibleIdsRef) both short-circuit to sections.shared on the shared tab and skip the collapsed-set lookup, so a stale persisted "Shared with me" collapse can't empty them. Verified against the source.
  • The badge predicate (!isOwnerLevel(c.permission_level)) is consistent with isOwnedByViewer used to build the list.

2. Security vulnerabilities

None. This is a client-side presentation change over already-fetched rows; ownership is still derived from the server-provided permission_level, and no permission/authorization boundary is altered. No new dependencies, no lockfile changes, no extras.

3. Non-blocking notes

  • Empty Shared tab won't paginate. The InfiniteScrollSentinel for the shared list lives inside the showShared non-empty branch; when totalVisible === 0 only the "No sessions shared with you" message renders (no sentinel). If a viewer's shared sessions all sit on an as-yet-unloaded page, opening the Shared tab shows an empty state and never triggers fetchNextPage. Previously the combined list always carried the global sentinel, so this is a mild regression for that edge case. Worth considering rendering the sentinel even in the empty-shared state (or when hasMorePages).
  • Badge vs. list source divergence. sharedCount is derived from loadedRows (no pinnedBackfill), while the list uses notArchived (which includes pinnedBackfill). A shared session that is pinned and lives outside the loaded window could appear in the list but not the count. Both are documented as best-effort, so low impact — just noting the two counts can disagree by one.
  • Selection mode on the Shared tab. The tab strip is hidden during selection mode but activeTab persists, so bulk operations continue to range over the shared list. That appears intentional and correct; flagging only so it stays covered if selection-mode behavior changes later.

4. Summary

Clean, well-scoped frontend change with strong test coverage (owned/shared split, projects/pinning as My-sessions-only, count badge, New-session snap-back, and the single-user fallback). No correctness or security blockers. The only substantive follow-up is the empty-Shared-tab pagination gap, which is a minor UX edge case rather than a blocker. Approve pending the author's judgment on that note; also complete the TODO demo media before merge as the description flags.


Automated review by Polly · workflow run

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

UI Preview for this PR has been removed.

Sessions shared with the viewer previously sat in an inline collapsible
"Shared with me" section below the owned-session list. Move them to a
dedicated tab so the two scopes are visually distinct and the shared list
gets its own space (flat, headerless, with its own infinite scroll).

The "My sessions" tab keeps the full Pinned / Projects / Sessions
structure; "Shared with me" is a flat list of every non-archived session
the viewer doesn't own (computed from notArchived, so a pinned/filed
shared session never drops off it). New session snaps back to My sessions.

The tab strip only renders on a multi-user server — gated on
!isCurrentServerLocal(), the same predicate AppShell uses to disable the
Share affordance. A loopback-only local server has a single user and
can't share sessions, so the split is meaningless there; the list falls
back to the owned sessions. Keyboard nav and shift-select are tab-aware
and, on the shared tab, ignore the collapsed set (the list always renders
expanded), so a stale persisted "Shared with me" collapse can't empty them.

Co-authored-by: Isaac
@serena-ruan
serena-ruan force-pushed the shared_sessions_group branch from 00a81fb to 4f9e9ec Compare July 8, 2026 06:31
@serena-ruan

Copy link
Copy Markdown
Collaborator Author

/review

@omnigent-ci

omnigent-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Polly AI Review

Review: split sidebar sessions into My sessions / Shared with me tabs

1. Blocking issues

a. Shared tab shows a false "empty" state and stalls its own pagination. In ConversationList the render is gated totalVisible === 0 ? <empty> : showShared ? <list + sentinel> : <owned>. On the shared tab totalVisible = sections.shared.length. Pagination is a single list ordered by updated_at desc across all sessions (owned + shared mixed), so it's entirely normal for page 1 to contain only owned sessions while shared ones live on later pages. When that happens sections.shared.length === 0, the component renders only "No sessions shared with you", and — because the shared-branch InfiniteScrollSentinel lives inside the non-empty branch — the sentinel never mounts, so later pages that do contain shared sessions are never fetched. Result: a user with shared sessions can see a permanently-empty Shared tab. Fix: mount a pagination sentinel (or keep loading) even when the current tab's totalVisible === 0 but hasMorePages is true.

b. Pinned / project-filed shared sessions leak onto "My sessions", breaking the PR's stated contract. sections.shared is now built from notArchived.filter(c => !isOwnedByViewer(c)) (correct, intentional). But sections.pinned and sections.projectGroups are also built from notArchived and are not filtered by isOwnedByViewer — only sections.sessions is owned-only. Pins are localStorage and ownership-agnostic, and an editable shared session (permission level 2/3) can be filed into a project. So a shared session that is pinned or filed then renders both under Pinned / a Project folder on the My sessions tab and on the Shared tab. This directly contradicts the PR's stated design ("projects/pinning are My-sessions-only", "shared sessions live on the shared tab") and is a regression: pre-PR, shared = rest.filter(...) where rest already excluded pinned+filed, so each session lived in exactly one place. It does not cause duplicate React keys or a crash (the two tabs render in mutually exclusive branches), but it breaks the explicit contract the PR sets out. Fix: also exclude !isOwnedByViewer from pinned and projectGroups, or consciously revise the stated intent.

2. Security vulnerabilities

None. This is a client-side presentation change; ownership/permission enforcement is server-side and untouched. isCurrentServerLocal() is a synchronous pure read of window.location.origin, so multiUser is stable and there's no new trust boundary weakened. No lockfile or dependency/extras changes in the diff.

3. Non-blocking notes

  • Count badge is claimed but absent. The PR description ("best-effort count badge") and its Test Plan bullet reference a count badge on the Shared tab, but the TabsTrigger renders only the literal text "Shared with me" — no badge element anywhere in the diff. Either drop the claim or add it (and the asserted test).
  • Selection-mode "stranded tab" is coherent, not a dead-end. When selection mode starts on the shared tab, the tab strip hides but ConversationList still receives the real activeTab="shared". This is intended: bulk-select operates on the shared list the user was already viewing, and the strip returns on exit. No reset needed.
  • Draggable shared rows are harmless no-ops. An editable shared row is still useDraggable-grabbable on the Shared tab, but that branch renders no drop zones, so a drag does nothing. Not worth addressing.
  • Keyboard nav / shift-select are correctly tab-aware; an activeId sitting on the hidden tab doesn't break hotkey nav (off-list active id enters from top/bottom).

4. Summary

The tab split is well-structured and the single-user gating, keyboard-nav tab-awareness, and mutually-exclusive rendering are all sound. Two real issues should be resolved before merge: (a) the Shared tab can render a false empty state and never paginate when shared sessions live only on later pages, and (b) pinned/filed shared sessions leak onto the My sessions tab, contradicting the PR's own stated "shared-only-on-shared-tab" contract and regressing prior behavior. The absent-but-claimed count badge should also be reconciled. None of these are security concerns.


Automated review by Polly · workflow run

… empty tabs

Address two issues in the sidebar tab split:

- Pinned and project folders drew from all non-archived sessions, so a
  shared session the viewer pinned (localStorage is ownership-agnostic) or
  filed into a project (editable share) rendered under Pinned / a project
  folder on My sessions AND on the Shared tab. Build both from owned-only
  sessions so non-owned sessions stay on the Shared tab exclusively.

- The list is one paginated stream (owned + shared mixed, updated_at desc),
  so a tab can be empty on the loaded window while its sessions live on a
  later page. The pagination sentinel lived inside the non-empty render
  branch, so an empty tab stopped fetching and stranded the user on a false
  "empty" state (e.g. Shared tab when page 1 is all owned). Keep the
  sentinel mounted in the empty branch when more pages exist.

Co-authored-by: Isaac
@serena-ruan

Copy link
Copy Markdown
Collaborator Author

Thanks Polly — both blocking findings were valid and are fixed in ce5e7df:

(a) False-empty + stalled pagination — the pagination sentinel lived inside the non-empty render branch, so an empty tab (Shared tab when page 1 is all-owned, or vice versa) stopped fetching. Now the sentinel stays mounted in the totalVisible === 0 branch whenever hasMorePages, so the stream keeps loading until the tab's sessions arrive.

(b) Pinned/filed shared sessions leaking onto My sessionspinned and projectGroups now build from an owned-only (isOwnedByViewer) set instead of all notArchived, so a shared session that's pinned or filed renders only on the Shared tab. Restores the pre-PR "each session in exactly one place" invariant.

Added 3 regression tests (pinned-shared stays off Pinned, filed-shared stays off Projects, empty Shared tab keeps paginating). 63 Sidebar tests pass, tsc clean.

Count badge (non-blocking note) — already removed in an earlier commit; the description was stale. Dropped the badge claim from the PR body.

…ebar tabs

Rather than rendering the Shared tab as a bespoke flat list, scope the
section-building to the active tab's conversations and render the same
Pinned / Projects / Sessions tree for both tabs. "mine" is the sessions
the viewer owns; "shared" is the ones others shared with them.

- Pins are localStorage and ownership-agnostic, so a pinned shared session
  now floats to a Pinned section on the Shared tab, matching My sessions.
- Projects stay a My-sessions-only tool: filing into a project is now
  gated on ownership (the row's "Add to project" / "Move session" menu
  item is hidden for non-owned sessions), and the Shared tab renders no
  Projects group. A shared session that already carries a project label
  just lands in the flat Sessions list there.
- Collapses the special-case `showShared` render branch and the shared
  special cases in keyboard-nav / shift-select ordering, since `sections`
  is now tab-scoped.

Co-authored-by: Isaac
@serena-ruan

Copy link
Copy Markdown
Collaborator Author

/review

@omnigent-ci

omnigent-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Polly AI Review

Review: split sidebar sessions into My sessions / Shared with me tabs

1. Blocking issues

None. The tab split is implemented cleanly: sections is scoped to the active tab via tabScoped before the Pinned/Projects/Sessions walk is built, so pinning, project folders, keyboard-nav order (orderedConversationIds), shift-select order (getVisibleIdsRef), and the totalVisible empty-state count are all consistently derived from the same tab-scoped slice. The multiUser gate correctly forces activeTab="mine" when passing down, so a stale persisted activeTab can't leak the shared view onto a local server. The empty-tab pagination fix (mounting InfiniteScrollSentinel inside the totalVisible === 0 branch when hasMorePages) is real and matches the mixed owned+shared single-stream pagination model. I traced each PR claim against the post-diff source and found no correctness bug, broken contract, or data-loss path.

2. Security vulnerabilities

None. This is a frontend-only presentation change. The one authorization-adjacent change — gating the "Move to project" affordance on canEdit && isOwnertightens an existing boundary (filing is owner-only), it doesn't weaken one. Ownership derivation (isOwnedByViewer / permission_level) is unchanged and remains a display concern; server-side enforcement is untouched. No injection, secret, deserialization, or traversal surface.

3. Non-blocking notes

  • Shared collapse key is shared with the owned "Sessions" section. On the Shared tab the flat list renders as a ConversationSection title="Sessions" using the "Chats" collapse key — the same key the owned tab's Sessions section uses. So collapsing/expanding Sessions on one tab silently mirrors to the other. More notably, the non-empty pagination sentinel is still gated on !effectiveCollapsedSections.includes("Chats"), so if a user collapses Sessions (on either tab), a non-empty Shared tab stops paginating. The empty-tab path is unaffected (its sentinel is ungated), so this is a narrow edge case, but the shared key coupling is worth a follow-up.
  • Shared sessions become invisible on a local server. With multiUser false the tabs are hidden and the list is forced to owned-only, so any session with a non-owner permission_level present in the data would no longer render anywhere (previously it appeared under the inline "Shared with me" section). The PR's premise (a loopback server can't share) makes this acceptable, but it's a genuine behavior change if that invariant is ever violated.
  • allSelected count spans both tabs. In the selection bar, allSelected = count === allConversations.length compares selected ids against all conversations while selection is tab-scoped to the visible rows — so an "all selected" state is unreachable within a single tab. Pre-existing shape, but the tab split makes the mismatch more pronounced.
  • Rapid page fetches on a persistently-empty tab. When a tab is empty on the loaded window, the sentinel can immediately intersect and fetch the next page repeatedly until hasNextPage is false. Bounded and intended, but on a large all-owned history the Shared tab could fire several back-to-back fetches on open.

4. Summary

Solid, well-scoped frontend refactor with strong test coverage (owned/shared split, owner-only pinning/projects with pinned-shared and filed-shared regressions, local-server fallback, and empty-tab pagination are all exercised). The core logic — tab-scoping the section builder and threading it through nav/selection/empty-count — is coherent and I found no blocking correctness or security issues. The only real follow-ups are the shared "Chats" collapse key coupling (which can halt pagination on a collapsed non-empty Shared tab) and the cross-tab allSelected count; both are non-blocking. The PR is missing its Demo (the template still has the author TODO) — worth attaching the two-tab / local-fallback screenshots before merge per the repo PR guidance. Approve pending that.


Automated review by Polly · workflow run

@serena-ruan
serena-ruan merged commit 1aca7bc into main Jul 8, 2026
30 of 31 checks passed
@serena-ruan
serena-ruan deleted the shared_sessions_group branch July 8, 2026 10:11
@github-actions github-actions Bot added the needs-doc-update Merged PR needs a user-facing docs update label Jul 8, 2026
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🏷️ Doc impact: needs-doc-update

The sidebar now splits sessions into "My sessions" and "Shared with me" tabs (hidden on single-user servers), changing how users navigate and see their sessions in the web UI, which affects the core user-journey docs.

Drafting a docs PR to omnigent-ai/omnigent-site (staged on 0.5-docs until release)…

Auto-classified on merge. Set the label manually before merging to override. · run

serena-ruan added a commit to omnigent-ai/omnigent-site that referenced this pull request Jul 8, 2026
* docs: document omnigent-ai/omnigent#2156

* Apply suggestion from @serena-ruan

* Apply suggestions from code review

Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>
dhruv0811 added a commit to omnigent-ai/omnigent-site that referenced this pull request Jul 10, 2026
* docs: document omnigent-ai/omnigent#1722 (#261)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2018 (#265)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1386 (#272)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2156 (#278)

* docs: document omnigent-ai/omnigent#2156

* Apply suggestion from @serena-ruan

* Apply suggestions from code review

Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2022 (#268)

* docs: document omnigent-ai/omnigent#2022

* docs: add steering gif and simplify message queue section

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@3c7a558 (#274)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#526 (#279)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: rename hindsight extra to memory (omnigent[memory]) (#282)

The memory tools ship under the `memory` extra (omnigent[memory]), not
`hindsight`. Update the install instruction and extra name to match.
The Hindsight product name and the hindsight_* tool names are unchanged.

* docs: document default base branch for new worktrees (#284)

* docs: document default base branch for new worktrees

* docs: condense worktree branches section and add setting demo gif

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@7fb779f (#281)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* chore(api): sync openapi.json from omnigent@60e775a (#288)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2152 (#280)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1859 (#277)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2135 (#276)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>
Co-authored-by: Pat Sukprasert <pattara.sk127@gmail.com>
Co-authored-by: Dhruv Gupta <dhruv.gupta@databricks.com>
yours-aditya pushed a commit to yours-aditya/omnigent that referenced this pull request Jul 16, 2026
…abs (omnigent-ai#2156)

* feat(web): split sidebar sessions into My sessions / Shared with me tabs

Sessions shared with the viewer previously sat in an inline collapsible
"Shared with me" section below the owned-session list. Move them to a
dedicated tab so the two scopes are visually distinct and the shared list
gets its own space (flat, headerless, with its own infinite scroll).

The "My sessions" tab keeps the full Pinned / Projects / Sessions
structure; "Shared with me" is a flat list of every non-archived session
the viewer doesn't own (computed from notArchived, so a pinned/filed
shared session never drops off it). New session snaps back to My sessions.

The tab strip only renders on a multi-user server — gated on
!isCurrentServerLocal(), the same predicate AppShell uses to disable the
Share affordance. A loopback-only local server has a single user and
can't share sessions, so the split is meaningless there; the list falls
back to the owned sessions. Keyboard nav and shift-select are tab-aware
and, on the shared tab, ignore the collapsed set (the list always renders
expanded), so a stale persisted "Shared with me" collapse can't empty them.

Co-authored-by: Isaac

* fix(web): keep pinned/filed shared sessions off My sessions; paginate empty tabs

Address two issues in the sidebar tab split:

- Pinned and project folders drew from all non-archived sessions, so a
  shared session the viewer pinned (localStorage is ownership-agnostic) or
  filed into a project (editable share) rendered under Pinned / a project
  folder on My sessions AND on the Shared tab. Build both from owned-only
  sessions so non-owned sessions stay on the Shared tab exclusively.

- The list is one paginated stream (owned + shared mixed, updated_at desc),
  so a tab can be empty on the loaded window while its sessions live on a
  later page. The pagination sentinel lived inside the non-empty render
  branch, so an empty tab stopped fetching and stranded the user on a false
  "empty" state (e.g. Shared tab when page 1 is all owned). Keep the
  sentinel mounted in the empty branch when more pages exist.

Co-authored-by: Isaac

* refactor(web): reuse Pinned / Projects / Sessions layout for both sidebar tabs

Rather than rendering the Shared tab as a bespoke flat list, scope the
section-building to the active tab's conversations and render the same
Pinned / Projects / Sessions tree for both tabs. "mine" is the sessions
the viewer owns; "shared" is the ones others shared with them.

- Pins are localStorage and ownership-agnostic, so a pinned shared session
  now floats to a Pinned section on the Shared tab, matching My sessions.
- Projects stay a My-sessions-only tool: filing into a project is now
  gated on ownership (the row's "Add to project" / "Move session" menu
  item is hidden for non-owned sessions), and the Shared tab renders no
  Projects group. A shared session that already carries a project label
  just lands in the flat Sessions list there.
- Collapses the special-case `showShared` render branch and the shared
  special cases in keyboard-nav / shift-select ordering, since `sections`
  is now tab-scoped.

Co-authored-by: Isaac
Signed-off-by: Aditya Devarapalli <adityareddyd2@gmail.com>
daniellok-db added a commit to omnigent-ai/omnigent-site that referenced this pull request Jul 17, 2026
* docs: document omnigent-ai/omnigent#1722 (#261)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2018 (#265)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1386 (#272)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2156 (#278)

* docs: document omnigent-ai/omnigent#2156

* Apply suggestion from @serena-ruan

* Apply suggestions from code review

Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2022 (#268)

* docs: document omnigent-ai/omnigent#2022

* docs: add steering gif and simplify message queue section

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@3c7a558 (#274)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#526 (#279)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: rename hindsight extra to memory (omnigent[memory]) (#282)

The memory tools ship under the `memory` extra (omnigent[memory]), not
`hindsight`. Update the install instruction and extra name to match.
The Hindsight product name and the hindsight_* tool names are unchanged.

* docs: document default base branch for new worktrees (#284)

* docs: document default base branch for new worktrees

* docs: condense worktree branches section and add setting demo gif

Co-authored-by: Isaac

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>

* chore(api): sync openapi.json from omnigent@7fb779f (#281)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* chore(api): sync openapi.json from omnigent@60e775a (#288)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2152 (#280)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#1859 (#277)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document omnigent-ai/omnigent#2135 (#276)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

* docs: document official kubernetes server image variant (#285)

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>

---------

Co-authored-by: omnigent-ci[bot] <294685417+omnigent-ci[bot]@users.noreply.github.com>
Co-authored-by: Serena Ruan <82044803+serena-ruan@users.noreply.github.com>
Co-authored-by: Serena Ruan <serena.rxy@gmail.com>
Co-authored-by: Pat Sukprasert <pattara.sk127@gmail.com>
Co-authored-by: Dhruv Gupta <dhruv.gupta@databricks.com>
Co-authored-by: Daniel Lok <daniel.lok@databricks.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-doc-update Merged PR needs a user-facing docs update size/L Pull request size: L ui-preview

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant