feat(app): pin sessions to the top of Home by LikwunCheung · Pull Request #57788 · anomalyco/opencode · GitHub
Skip to content

feat(app): pin sessions to the top of Home - #57788

Open
LikwunCheung wants to merge 1 commit into
anomalyco:devfrom
LikwunCheung:pin-sessions
Open

LikwunCheung wants to merge 1 commit into
anomalyco:devfrom
LikwunCheung:pin-sessions

Conversation

@LikwunCheung

@LikwunCheung LikwunCheung commented Oct 21, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #57738

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds a pin to Home sessions. The session row menu gets Pin / Unpin; pinned sessions move into a Pinned group above Today, in the order they were pinned, and are excluded from the dated groups. session.pin in the command palette toggles the same state for the open session, so it can also be bound in Settings → Shortcuts.

  • packages/app/src/home/sessions/pins.tsx owns the store: Persist.global("home.sessions.pinned"), a Record<serverKey, sessionID[]>, so pins survive restarts and are per server.
  • createHomeSessionsController merges pinned sessions into the record list before the HOME_SESSION_LIMIT slice and sorts them first by pin order, so a pin cannot be pushed out of the 64-row window. A pinned session outside the fetched index is loaded with session.get.
  • groupSessions takes the pinned ID set and emits the Pinned group first.
  • Deleting a session drops its pins, including child sessions removed with it. Pinning a subagent session is disabled because Home does not list those.
  • home/sessions/view.tsx replaces typeof navigator === "object" with "navigator" in globalThis; bun run lint:changed flags the older form once the file is touched.

Limits: pins are local to the app and do not follow the user to another machine. There is no server field for them.

This was opened before design review of #57738 has happened. Happy to hold it, or change the interaction (pin from the tab menu, a server-side pinned flag) if that is what you prefer.

How did you verify your code works?

  • packages/app: bun run typecheck, bun run test:unit (762 pass), bun run lint:changed clean.
  • e2e/regression/home.spec.ts and e2e/regression/command-palette.spec.ts, --project chromium, 21 tests pass locally. The new cases pin from the row menu (session moves first, still first after a reload, unpin removes the group) and pin from the palette (the command then reads "Unpin session" and the session shows under Pinned on Home).

Screenshots / recordings

Before Session row menu
Before Menu
After pinning the older session Palette command
After Palette

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Added by the opencode bot (AI-generated).

Fixes #55764

Related: #36193

Right-click a Home session and choose Pin to keep it above the dated
sessions in a Pinned group, in the order it was pinned. Pins persist per
server in local storage and survive restarts.

The command palette exposes the same toggle as `session.pin`, titled
Unpin session once the open session is pinned. Subagent sessions are
skipped because Home does not list them.

Co-Authored-By: DeepSeek V4.1 Flash 1017 <noreply@opencode.ai>
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent Bot 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.

Pinning works as described. I ran the Home and command-palette e2e tests in Chromium (21 pass, including both new pin tests). I also scripted a before/after on Home: on the base there is no Pin item; with this change the pinned session moves into a Pinned group above the recent sessions. typecheck and the Home unit tests pass.

Public API: no change. The only additions are a locally stored app setting (home.sessions.pinned) and an app command (session.pin).

The approach looks sound. Pins are stored per server, and both Home and the palette work out the server key the same way. Pinned sessions are merged in before the 64-row cut, and archived or subagent sessions are filtered out. Deleting from Home drops pins for the session and its children. Adding strings to en.ts only matches packages/app/AGENTS.md. The only ask is optional: drop pins.test.ts (see inline).

Fixes #55764
Related: #36193

Before

After

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.

This can be dropped. The new home.spec.ts case already checks pin order and that unpinning removes the group, and packages/app/AGENTS.md asks not to unit-test what an e2e keeper already proves. Without this file, withPin, withoutPins and pinnedIDs would not need to be exported from pins.tsx either.

This branch has not been deployed

No deployments
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.

[FEATURE]: Pin sessions to the top of the Home session list [FEATURE]: Session pinning in the Desktop app (TUI parity)

1 participant