Skip to content

(MOT-4174) feat(console,database): chat copy + open-in-editor on file changes; executeBatch as sole batch id - #569

Merged
andersonleal merged 17 commits into
mainfrom
feat/console-chat-copy-editor
Jul 22, 2026
Merged

(MOT-4174) feat(console,database): chat copy + open-in-editor on file changes; executeBatch as sole batch id#569
andersonleal merged 17 commits into
mainfrom
feat/console-chat-copy-editor

Conversation

@andersonleal

@andersonleal andersonleal commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Console chat copy affordances

  • Copy button on user and assistant messages (hover-revealed, PaneShell copy idiom). An assistant turn's copy includes the function calls it made (ƒ id + arguments), with turn-scoped attribution that handles the canonical thought → calls → summarizing prose ordering (leading call runs attach forward to the turn's assistant message; thoughts are transparent; tool-only turns still get the button).
  • Function-call cards: hover copy of the ƒ function id in the header (works collapsed, in group children, and in the TracesV2 span tab); the header is restructured so the copy control never nests inside the collapse toggle.
  • Request/response pane copy now works on insecure origins (http://<LAN-IP>) via a clipboard helper with an execCommand fallback — fixes MOT-4174.

Open in editor on coder file-change cards

  • Settled successful create-file / update-file / move results get an "open in editor" menu: cursor / vs code / zed via URL schemes (cursor://file/<abs-path>[:line]), plus a copy-path fallback for LAN browsing. Frontend-only by design — no backend exec endpoint, since the console port is LAN-exposed.
  • Editor links percent-encode per path segment, so filenames containing #, ?, or spaces deep-link correctly.

Database

  • database::executeBatch is now the sole registration for atomic batch writes; the snake_case database::execute_batch duplicate is removed to match the worker's camelCase ids (prepareStatement, beginTransaction, …). README, SKILL.md, e2e surface cases, and the sqlite MULTI_STATEMENT hint follow.

BREAKING CHANGE: external callers of database::execute_batch must switch to database::executeBatch (no in-repo callers existed).

Fixes MOT-4174

Verification

  • console/web: 1096 vitest tests / 86 files green, tsc -b clean, biome clean on all changed files
  • database: cargo test — 225 passed, 0 failed
  • Live browser audit (Storybook playground scenarios, driven headless): copy payloads (single + multi-call turns), always-open editor menu, cursor://file/... deep-link wiring, copy-path canonical absolute paths, pointer cursors, aria/toggle structure — all verified at HEAD

Summary by CodeRabbit

  • New Features

    • Added copy controls for chat messages and function-call details, with confirmation feedback.
    • Added options to open completed file changes directly in Cursor, VS Code, or Zed.
    • Added the ability to copy file paths from the editor menu.
  • Updates

    • Renamed the database batch execution API to database::executeBatch across the product and documentation.
  • Bug Fixes

    • Improved clipboard copying with a fallback for unsupported or restricted browser APIs.

The open-in-editor control no longer launches a default editor (Cursor)
on click — every click opens the menu so the choice (cursor / vs code /
zed) or copy-path is explicit. Drops the now-unused persisted editor
preference (getPreferredEditor/setPreferredEditor).
An assistant turn's copy button now appends the function call(s) it made
(ƒ id + arguments) beneath the prose. Calls are their own messages, so
MessageList associates each assistant turn with the call run that
follows it and passes a lazy copy thunk (built on click, so streaming
re-renders stay free).
Hover a function-call card header (standalone, group child, or TracesV2
span tab) to reveal a copy icon right after the function name; the
collapse caret stays at the row's right edge. The header is restructured
because the copy control can't nest inside the toggle button (invalid
HTML): the labeled toggle carries the title, and the caret strip is a
pointer-only duplicate target so the whole row still collapses on click.
CopyMessageButton gains a label prop for the accessible name. Also fixes
the pre-existing fp/harness import ordering picked up by organizeImports.
Buttons default to the arrow cursor here (no global override), so the
small icon buttons — message/function-id copy, function-call pane copy,
and the open-in-editor trigger — read as inert on hover.
encodeURI leaves # and ? raw — legal filename bytes that would truncate
the path into a fragment/query — so encode per path segment with
encodeURIComponent, keeping only the slashes literal.
A turn that emits only function calls has empty prose, and the copy
button was gated on content — hiding it even though the copy payload
(the calls) exists. MessageList now passes the copy thunk only when the
turn has prose or calls, and the assistant header gates on that payload
instead of prose alone.
…stant

The canonical agent flow is thought → calls → summarizing prose, so the
calls usually PRECEDE the assistant message that talks about them — and
trailing-only adjacency missed them (found live in the happy-agent
playground: copy produced prose with no ƒ block). A call run with no
assistant before it now attaches forward to the turn's next assistant
message; thoughts are transparent, user/system messages reset both
directions, and trailing attribution still wins between two assistants.
The parent-supplied transition-opacity displaced the base
transition-colors via tailwind-merge (one transition-* group), snapping
the ghost→ink hover color. transition-[opacity,color] keeps both eased.
database::execute_batch was registered twice — once snake_case, once as
a camelCase alias. Every other multi-word function id in this worker is
camelCase (prepareStatement, beginTransaction, transactionQuery, …), so
keep database::executeBatch as the sole id and drop the snake_case
registration outright (no alias left behind). Function count log line,
README, SKILL.md, and the e2e surface cases follow. The sqlite
MULTI_STATEMENT hint now names database::executeBatch as the remedy
instead of the cryptic 'execute_batch via DDL'.

BREAKING CHANGE: callers using database::execute_batch must switch to
database::executeBatch (no in-repo callers existed).
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
workers Ready Ready Preview, Comment Jul 22, 2026 8:33pm
workers-tech-spec Ready Ready Preview, Comment Jul 22, 2026 8:33pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The PR adds reusable clipboard and editor-link controls to chat and coder views, composes assistant copy text with related function calls, and standardizes the database batch SQL API on database::executeBatch.

Chat copy and editor actions

Layer / File(s) Summary
Clipboard and copy payload foundations
console/web/src/lib/clipboard.ts, console/web/src/lib/function-call-copy.ts, console/web/src/components/chat/CopyMessageButton.tsx, tests
Clipboard writes use an async API with an execCommand fallback; function-call text serialization and reusable copy-button feedback are added with tests.
Chat and function-call copy integration
console/web/src/components/chat/Message.tsx, console/web/src/components/chat/MessageList.tsx, console/web/src/components/function-call/FunctionCallCard.tsx
Messages and function-call cards render copy controls, while assistant copy text includes associated function calls.
Editor links and coder-view wiring
console/web/src/lib/editor-links.ts, console/web/src/components/chat/coder/OpenInEditorButton.tsx, console/web/src/components/chat/coder/*View.tsx, tests
Editor deep links, path copying, and optional line anchors are wired into create, move, and update result views.

Canonical executeBatch API name

Layer / File(s) Summary
Canonical batch API registration
database/src/main.rs, database/src/handlers/execute_batch.rs, database/src/driver/sqlite.rs
The worker registers database::executeBatch, removes the former alias, updates the function count, and revises related guidance.
Documentation and transaction harness alignment
database/README.md, database/skills/SKILL.md, database/tests/e2e/workers/harness/src/cases-transaction.ts
Documentation and transaction cases use the camelCase API name while retaining existing behavior assertions.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant MessageList
  participant Message
  participant CopyMessageButton
  participant Clipboard
  User->>MessageList: click message copy control
  MessageList->>Message: provide assistant copy text
  Message->>CopyMessageButton: render resolved copy source
  CopyMessageButton->>Clipboard: copy text
  Clipboard-->>CopyMessageButton: return success
  CopyMessageButton-->>User: show copied feedback
Loading

Suggested reviewers: sergiofilhowz

Poem

I’m a rabbit with buttons that shimmer and hop,
Copying words with a crisp little pop.
Paths leap to editors, lines point the way,
Batch names turn camel by close of day.
I twitch my nose: the diff is okay!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 56.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main console and database changes, including chat copy, open-in-editor actions, and the executeBatch migration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/console-chat-copy-editor

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

skill-check — worker

0 verified, 47 skipped (no docs/).

Layer Result
structure
vale
ai
render

Four for four. Nicely done.

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

🧹 Nitpick comments (1)
console/web/src/components/function-call/FunctionCallCard.tsx (1)

600-654: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate copy-button implementation — reuse CopyMessageButton.

PaneShell's inline copy button re-implements the exact same className, icon-flip, and copy/timeout logic already extracted into CopyMessageButton (console/web/src/components/chat/CopyMessageButton.tsx). Since CopyMessageButton already supports a custom label, it can replace this block directly.

♻️ Proposed refactor
-  const [copied, setCopied] = useState(false)
-
-  const copy = () => {
-    void copyTextToClipboard(copyText).then((ok) => {
-      if (!ok) return
-      setCopied(true)
-      window.setTimeout(() => setCopied(false), 1200)
-    })
-  }
-
   return (
     <div className={cn(bordered && 'border-t border-rule-2')}>
       <div className="flex items-center gap-2 bg-paper-2 px-3 py-1.5 border-b border-rule-2 font-mono text-[11px] uppercase tracking-[0.06em] text-ink-faint">
         <span className="min-w-0 flex-1 truncate">
           {label}
           {(hints ?? []).map((hint) => (
             <span
               key={hint}
               className="text-ink-ghost normal-case tracking-normal"
             >
               {' '}
               · {hint}
             </span>
           ))}
         </span>
-        <button
-          type="button"
-          onClick={copy}
-          className="shrink-0 cursor-pointer text-ink-ghost hover:text-ink transition-colors"
-          aria-label={copied ? 'copied' : `copy ${label}`}
-          title={copied ? 'copied' : 'copy'}
-        >
-          {copied ? (
-            <Check size={12} aria-hidden />
-          ) : (
-            <Copy size={12} aria-hidden />
-          )}
-        </button>
+        <CopyMessageButton text={copyText} label={`copy ${label}`} />
       </div>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@console/web/src/components/function-call/FunctionCallCard.tsx` around lines
600 - 654, Replace PaneShell’s inline copy button and its copied state/copy
handler with the existing CopyMessageButton component from
chat/CopyMessageButton.tsx. Pass copyText as the copied content and label as the
custom label, preserving the current copy behavior and accessible labeling while
removing the duplicate implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@console/web/src/components/function-call/FunctionCallCard.tsx`:
- Around line 600-654: Replace PaneShell’s inline copy button and its copied
state/copy handler with the existing CopyMessageButton component from
chat/CopyMessageButton.tsx. Pass copyText as the copied content and label as the
custom label, preserving the current copy behavior and accessible labeling while
removing the duplicate implementation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2580810d-b4cd-447e-8c8b-3a9011417a67

📥 Commits

Reviewing files that changed from the base of the PR and between 89b4a7a and 50d3b31.

📒 Files selected for processing (21)
  • console/web/src/components/chat/CopyMessageButton.tsx
  • console/web/src/components/chat/Message.tsx
  • console/web/src/components/chat/MessageList.tsx
  • console/web/src/components/chat/coder/CreateFileView.tsx
  • console/web/src/components/chat/coder/MoveView.tsx
  • console/web/src/components/chat/coder/OpenInEditorButton.tsx
  • console/web/src/components/chat/coder/UpdateFileView.tsx
  • console/web/src/components/chat/coder/__tests__/UpdateFileView.test.ts
  • console/web/src/components/function-call/FunctionCallCard.tsx
  • console/web/src/lib/clipboard.test.ts
  • console/web/src/lib/clipboard.ts
  • console/web/src/lib/editor-links.test.ts
  • console/web/src/lib/editor-links.ts
  • console/web/src/lib/function-call-copy.test.ts
  • console/web/src/lib/function-call-copy.ts
  • database/README.md
  • database/skills/SKILL.md
  • database/src/driver/sqlite.rs
  • database/src/handlers/execute_batch.rs
  • database/src/main.rs
  • database/tests/e2e/workers/harness/src/cases-transaction.ts

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