Skip to content

feat(chat): highlight-to-chat — reference file/table selections in Chat - #6087

Open
mzxchandra wants to merge 3 commits into
stagingfrom
feat/highlight-to-chat
Open

feat(chat): highlight-to-chat — reference file/table selections in Chat#6087
mzxchandra wants to merge 3 commits into
stagingfrom
feat/highlight-to-chat

Conversation

@mzxchandra

Copy link
Copy Markdown
Contributor

Summary

IDE-style highlight → "Add to chat" for Files and Tables: select a passage in a file (Monaco or the Tiptap markdown editor) or rows/cells in a table, and it becomes a scoped reference chip the Sim agent can read, instead of attaching the whole resource. Cmd+C / Cmd+V works too: copy a selection and paste it into the chat as the same reference.

Adding a selection from a standalone Files/Tables page opens the Chat in the split layout (chat left, resource right) with the chip already in the input; adding it while a resource is already open in Chat drops the chip into the current conversation.

Type of Change

  • New feature

How it works

  • New ChatContext kinds file_selection / table_selection. File selections carry the literal text + line range inline; table selections carry authoritative row/column ids and are re-fetched server-side by id (never trusting client cell values), scoped to the table + workspace.
  • Producers use the Sim Chat block's Blimp icon in the Monaco context menu, the Tiptap bubble menu, and the table context menu.
  • Copy rides a custom text/x-sim-selection clipboard type alongside text/plain (bubble-phase listener so it survives the editors' own clearData()), read back by the chat paste handler.
  • Server resolves file selections to an inline citable snippet and table selections to a markdown table.

Testing

  • bunx tsc --noEmit: 0 errors. Biome clean. check:api-validation passes (new context fields live only on the domain validator + the ChatContext union — no boundary violation).
  • Unit tests: server resolution branches (process-contents), label/bounds helpers (selection-context), and the clipboard codec round-trip/validation (selection-clipboard, new).
  • Manual E2E in a headless browser: file selection → split view with the file open + chip; table selection → table tab + chip; copy → paste rebuilds the chip.
  • Pre-landing review (2 specialists): fixed a P2 where a >20k-char selection could overflow the server schema and reject the whole chat POST; hardened clipboard validation; extracted a shared copy hook; added clipboard tests.

Reviewers: focus on lib/copilot/chat/process-contents.ts (server row re-fetch + bounds) and the merge with staging's nuqs ?resource= refactor in home.tsx.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced

🤖 Generated with Claude Code

@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 30, 2026 4:53am

Request Review

@cursor

cursor Bot commented Jul 30, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches copilot context processing, chat POST validation, clipboard handling, and home navigation/slideover lifecycle; server-side row re-fetch is bounded but is new data-path logic.

Overview
Adds highlight → Add to chat (and copy/paste) so file passages and table row/cell selections become scoped file_selection / table_selection chips instead of whole-resource attachments.

Producers: Monaco context menu, Tiptap bubble menu, and table context menu call useAddToChat, which dispatches mothership-add-context to a mounted input or persists via MothershipPendingContextStorage and hard-navigates to Chat. Copy uses text/x-sim-selection on top of text/plain (useSelectionCopyBridge, table copy handler, chat paste/copy).

Chat input: insertContextChip, custom-MIME paste, and selection-chip clipboard round-trip; onContextRemove now receives remaining contexts so slideover tabs stay open when another chip still references the same file/table.

Server: process-contents resolves file selections to fenced snippets and table selections by re-fetching rows by id (with column scope); API validation and persistence include the new fields.

Reviewed by Cursor Bugbot for commit 1551f96. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Highlight-to-chat adds scoped file_selection / table_selection chips from editor and table selections, with clipboard MIME round-trip and server-side table row re-fetch.

  • New chat context kinds resolve file snippets inline and table selections via authoritative row ids.
  • Table multi-row and column-header copy use sync clipboard writes so text/x-sim-selection survives when the selection is fully loaded and within caps.
  • Standalone Files/Tables “Add to chat” navigates to home and drains pending context into the chat input and slideover.

Confidence Score: 5/5

This PR appears safe to merge; the previously reported multi-row copy MIME drop is fixed for the loaded in-cap path.

No blocking failure remains. Multi-row kind === 'some' copy now writes text/x-sim-selection on the event clipboard when all selected rows are loaded and within the selection cap, then returns without replacing the clipboard via ClipboardItem.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/table-grid.tsx Multi-row and column-header copy paths attach table_selection MIME synchronously when loaded and within caps; async paged path remains plain-text only for oversized/partial loads.
apps/sim/lib/copilot/chat/selection-clipboard.ts Custom MIME attach/read with validation for file_selection and table_selection payloads.
apps/sim/lib/copilot/chat/process-contents.ts Server resolves file_selection to fenced snippets and table_selection via workspace-scoped getRowsByIds.
apps/sim/hooks/use-add-to-chat.ts Live mothership insert or pending-context storage plus hard navigate to chat home.
apps/sim/app/workspace/[workspaceId]/home/home.tsx Drains pending selection contexts, maps selection kinds to resources, and avoids closing shared tabs while other chips still reference them.

Reviews (10): Last reviewed commit: "fix(chat): carry the selection chip on a..." | Re-trigger Greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread apps/sim/lib/copilot/chat/process-contents.ts Outdated
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread apps/sim/lib/copilot/chat/selection-context.ts
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread apps/sim/lib/copilot/chat/selection-context.ts
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread apps/sim/app/workspace/[workspaceId]/home/home.tsx
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread apps/sim/lib/copilot/chat/process-contents.ts Outdated
Adds an IDE-style "add to chat" affordance so the Sim agent can reference an
exact passage of a file or a specific set of table rows/cells instead of a whole
resource.

- Two new ChatContext kinds: file_selection (inline selected text + line range)
  and table_selection (authoritative row ids, optional column ids; the server
  re-fetches current rows by id). Chip registry, client serializer, boundary
  contract, and server resolver all extend along their existing switch(kind)
  seams.
- Producers: Monaco context menu, Tiptap bubble menu, and the table grid context
  menu, all using the Sim Chat block icon. Adding a selection opens the split
  slideover (chat + resource) with the chip dropped straight into the input; from
  a standalone Files/Tables page the context is stashed and drained on chat mount.
- Cmd+C / Cmd+V: a selection copied from a file/table rides a custom
  text/x-sim-selection clipboard MIME and pastes into chat as the same reference
  chip; the chat input round-trips a sole selection chip on copy/cut too.
- Guards: selection payloads are length/row/column bounded and truncated within
  the schema bound; labels carry a deterministic key so distinct same-size
  selections don't collide; a shared resource tab closes only once no remaining
  chip references it; stale cell-range column ids drop the context rather than
  dumping the full table.
@mzxchandra
mzxchandra force-pushed the feat/highlight-to-chat branch from 84081de to 5c4454b Compare July 30, 2026 04:45
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

…ncate it

Cursor: resolveFileSelectionResource wrapped the selected passage in a fixed ```
fence, so a selection that itself contained a fenced code block closed the outer
fence early and the agent received a truncated snippet. The fence is now one
backtick longer than the longest backtick run in the content (floored at three),
matching CommonMark's close rule.
@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile review

Cursor: a column-header Cmd+C always took the async paged clipboard path, which
replaces the whole clipboard with text/plain only and can't carry a custom MIME
- so pasting a column copy into Chat couldn't rebuild the table_selection chip
that Add-to-chat produces for the same selection. When every row is loaded and
within the chat-selection cap, the column copy now does a synchronous event
write so the scoped table_selection rides alongside text/plain (mirroring the
row-'some' and cell-range paths); oversized/partially-loaded columns keep the
async plain-text path.

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

1 issue from previous review remains unresolved.

Fix All in Cursor

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 3dac5a8. Configure here.

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@cursor review

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@greptile

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 1551f96. Configure here.

@mzxchandra

Copy link
Copy Markdown
Contributor Author

@waleedlatif1

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