Skip to content

feat(web): searchable session picker on Android share target#986

Open
heavygee wants to merge 3 commits into
tiann:mainfrom
heavygee:feat/share-target-session-search
Open

feat(web): searchable session picker on Android share target#986
heavygee wants to merge 3 commits into
tiann:mainfrom
heavygee:feat/share-target-session-search

Conversation

@heavygee

@heavygee heavygee commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a searchable session picker to the Android Web Share Target (/share) flow.

  • Reuses sidebar session search (SessionListSearch, sessionMatchesQuery) so inactive sessions are findable by title, machine label, or path
  • Empty query: capped list of recent active sessions (same limit as sidebar preview)
  • Non-empty query: searches all sessions
  • Unit tests for filter/cap logic (sharePickerSessions.test.ts)

Builds on merged share-target work (#933, #932).

Test plan

  • bun typecheck
  • cd web && bun run test (includes sharePickerSessions.test.ts)
  • Peer-stack Playwright (e2e/peer/980-share-target-session-search.spec.ts on fork main)
  • Operator dogfood on driver soup :3006 — share sheet → /share → search inactive session

Issues

Fixes #980

heavygee and others added 3 commits June 29, 2026 16:32
Add search to the Android share-target picker so operators can attach
shared content to inactive or older sessions, not just recent actives.
Reuses sidebar search helpers; caps default active list with a search hint.

Co-authored-by: Cursor <cursoragent@cursor.com>
Peer-stack specs live on fork main under e2e/peer/ only.
Peer-stack Playwright config stays on fork main; product worktree is web/ only.

Co-authored-by: Cursor <cursoragent@cursor.com>
@heavygee

heavygee commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Peer-stack Playwright + operator dogfood on driver soup (:3006) — share sheet → /share → search finds inactive sessions. Screenshot: localdocs/playwright-runs/share-target-session-search.png on fork branch (not committed per upstream PR discipline).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • [Major] Inactive share targets can drop the pending transfer — search mode now returns inactive sessions, but selecting one still arms sessionStorage and navigates straight to /sessions/:id. ShareSeedConsumer consumes and removes that transfer id on the inactive session mount, then waits for sessionActive; if the operator reopens/resumes into a new session id, the keyed chat remount has no pending transfer left, so the shared text/files are never attached. Evidence: web/src/lib/sharePickerSessions.ts:26, related consumer behavior in web/src/components/SessionChat.tsx:205 and web/src/components/SessionChat.tsx:214.
    Suggested fix:
    useEffect(() => {
        if (!props.sessionActive) return
        if (consumedRef.current) return
        const transferId = consumeSharePendingTransfer()
        if (!transferId) return
        consumedRef.current = true
    
        void seedShareTransfer(transferId)
    }, [props.sessionActive, props.sessionId, assistantApi])

Summary

  • Review mode: initial
  • The searchable picker is mostly localized, but the newly reachable inactive-session path can lose the Web Share Target payload before the target session is active.

Testing

  • Not run (automation): bun is not available on this runner (bun: command not found).

const normalizedQuery = normalizeSearch(query)
const sorted = sortByUpdatedAtDesc(sessions)

if (normalizedQuery) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MAJOR] This branch now makes inactive sessions selectable from the share picker, but the downstream share seeding path only works after SessionChat is active. Today ShareSeedConsumer consumes and removes the pending transfer id on first mount, then returns while props.sessionActive is false; if the user reopens/resumes into a new session id, the keyed chat remount no longer has the transfer in sessionStorage, so the shared text/files are lost.

Suggested fix:

useEffect(() => {
    if (!props.sessionActive) return
    if (consumedRef.current) return
    const transferId = consumeSharePendingTransfer()
    if (!transferId) return
    consumedRef.current = true

    void seedShareTransfer(transferId)
}, [props.sessionActive, props.sessionId, assistantApi])

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.

feat(web): searchable session picker on Android share target

1 participant