Skip to content

[FEATURE]: Pin messages and selected text in the Desktop chat #55195

Open

Description

@Nekspert

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Summary

In long sessions important answers and decisions quickly scroll out of view. I would like to "pin" (bookmark) a specific message in the chat — at minimum an assistant response, and ideally also a user message or an arbitrary selected text range. A small pin (📌) affordance on the message would toggle the state, and pinned items would be listed in a compact "Pinned" area/panel so I can jump straight back to them without scrolling.

Motivation / use case

  • Long threads with large answers; a key answer scrolls away while the agent keeps working.
  • Keeping a shortlist of decisions / open questions visible while continuing the conversation.
  • Pinning only a selected fragment of a long answer instead of the whole message.

Proposed behavior

  1. A pin affordance appears on message hover (or in the message action row) for both user and assistant messages.
  2. Clicking it toggles the pinned state; pinned messages show a persistent marker.
  3. A collapsible "Pinned" panel/section lists pinned messages with one-click jump to the original message in the transcript.
  4. Optionally, pinning a selected text range stores only that snippet.
  5. Pinned state is persisted per session, ideally on the shared backend so Desktop and Web behave consistently.

Scope note / related requests

This is about pinning messages or text inside a session, not pinning whole sessions to the sidebar.

This request targets the Desktop (and Web) app chat UI specifically: a pin control on individual messages / selected text.

Environment (for context)

  • opencode version: 2.0.28
  • Install/channel: Desktop app (BETA), latest
  • App: OpenCode Desktop 2.0.28.0
  • OS: Windows (win32 x64)

Activity

  1. opencode-agent commented on Oct 13, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed request, @Nekspert! You'd like to pin individual messages (user or assistant), and ideally selected text, in the Desktop/Web chat. Pinned items would get a persistent marker and be listed in a collapsible "Pinned" panel that jumps back to them, with pins saved per session.

    The Desktop app doesn't have anything like this today. It also can't be added as a plugin yet, because the app's extension API has no way to add actions to individual messages or to jump to a specific message in the timeline. Maintainers will consider it.

    Related issues (none of them is open):

  2. Nekspert commented on Oct 13, 2026

    @Nekspert
    Author

    Design proposal for this feature (pin a message / assistant answer)

    I looked through the code to scope a minimal first version. Note per CONTRIBUTING.md that UI features need design review before implementation, so opening this here first to agree on the shape before any PR.

    Target

    Pin/unpin a whole message (either a user message or an assistant answer) inside a session. Pins are per session, stored client-side, and shown in a small "Pinned" list that jumps to the message. Works in both web and desktop because the chat UI is shared (packages/session-ui consumed by packages/app).

    Deliberately out of scope for v1 (happy to extend if wanted):

    • pinning an arbitrary text selection (selection capture + line ranges)
    • server-side sync / cross-device pins
    • pinning to the session list

    Where it plugs in

    • Message action rows already exist and are the natural home for a pin button:
      • user message copy/revert row: packages/session-ui/src/message/message-content.tsx (user-message-copy-wrapper)
      • assistant answer copy row: same file (text-part-copy-wrapper)
    • Action contract to extend: packages/session-ui/src/actions.ts (SessionUserActions), provided from packages/app/src/session/composer/region.tsx.
    • An existing message list to reuse for the pinned view: packages/session-ui/src/components/message-nav.tsx.
    • Client persistence already available via packages/app/src/runtime/persistence/storage.ts.
    • i18n keys live in packages/ui/src/i18n/en.ts; add a pin icon to packages/ui/src/icons/catalog.ts.

    Proposed v1

    1. New client store: pinned message IDs keyed by session, persisted in localStorage (e.g. opencode.pinned-messages, shape { [sessionID]: string[] }, newest first).
    2. Extend SessionUserActions with optional pin / unpin / isPinned (optional → no change for other consumers such as TUI/storybook).
    3. Pin toggle button next to Copy on both action rows; pin / pin-filled icon.
    4. A "Pinned" list (reusing the MessageNav presentation), reachable from the session header (with a count badge, hidden when empty); clicking an entry scrolls to the message.
    5. i18n keys: ui.message.pinMessage, ui.message.unpinMessage, ui.message.pinned, plus pinned-list title/empty state.
    6. Tests: unit tests for the store (add/remove/dedupe/persist) and a component test for the toggle.

    Questions before I write code

    • Is client-local persistence acceptable for v1, or do you want pins to be shared/persisted server-side?
    • Pin the whole message, or is a text selection the desired granularity?
    • Where should the pinned list live — a session-header toggle, or inside the existing message navigation panel?
    • Icon convention: pin vs bookmark?

    Happy to adjust the scope based on your preference.

  3. zhejingxu commented on Nov 3, 2026

    @zhejingxu

    I built a version of this in my fork. It may help answer the questions in the design proposal above:

    • It pins a whole Q&A turn (the user message plus its response), not a text selection. The pin button is on both the user message and the response.
    • Pins are stored client-side, per session, in the existing layout store. No server changes.
    • Pinned turns open in a resizable panel left of the timeline, with one tab per pinned turn, jump to message, unpin, and clear all. I chose a panel over a header toggle so a pinned answer stays readable while the chat continues.
    • The icon is a pin / pin-active pair.

    Patch: https://github.com/zhejingxu/opencode-plugins/blob/main/patches/0002-feat-app-pin-Q-A-turns-to-a-left-side-panel.patch

    I'd rather ship this as a GUI plugin, but it needs the extension point I asked for in #61385.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions