(MOT-4174) feat(console,database): chat copy + open-in-editor on file changes; executeBatch as sole batch id - #569
Conversation
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).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughChangesThe 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 Chat copy and editor actions
Canonical executeBatch API name
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
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
skill-check — worker0 verified, 47 skipped (no docs/).
Four for four. Nicely done. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
console/web/src/components/function-call/FunctionCallCard.tsx (1)
600-654: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate copy-button implementation — reuse
CopyMessageButton.
PaneShell's inline copy button re-implements the exact same className, icon-flip, and copy/timeout logic already extracted intoCopyMessageButton(console/web/src/components/chat/CopyMessageButton.tsx). SinceCopyMessageButtonalready supports a customlabel, 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
📒 Files selected for processing (21)
console/web/src/components/chat/CopyMessageButton.tsxconsole/web/src/components/chat/Message.tsxconsole/web/src/components/chat/MessageList.tsxconsole/web/src/components/chat/coder/CreateFileView.tsxconsole/web/src/components/chat/coder/MoveView.tsxconsole/web/src/components/chat/coder/OpenInEditorButton.tsxconsole/web/src/components/chat/coder/UpdateFileView.tsxconsole/web/src/components/chat/coder/__tests__/UpdateFileView.test.tsconsole/web/src/components/function-call/FunctionCallCard.tsxconsole/web/src/lib/clipboard.test.tsconsole/web/src/lib/clipboard.tsconsole/web/src/lib/editor-links.test.tsconsole/web/src/lib/editor-links.tsconsole/web/src/lib/function-call-copy.test.tsconsole/web/src/lib/function-call-copy.tsdatabase/README.mddatabase/skills/SKILL.mddatabase/src/driver/sqlite.rsdatabase/src/handlers/execute_batch.rsdatabase/src/main.rsdatabase/tests/e2e/workers/harness/src/cases-transaction.ts
Summary
Console chat copy affordances
ƒ id+ arguments), with turn-scoped attribution that handles the canonicalthought → calls → summarizing proseordering (leading call runs attach forward to the turn's assistant message; thoughts are transparent; tool-only turns still get the button).ƒ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.http://<LAN-IP>) via a clipboard helper with anexecCommandfallback — fixes MOT-4174.Open in editor on coder file-change cards
create-file/update-file/moveresults 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.#,?, or spaces deep-link correctly.Database
database::executeBatchis now the sole registration for atomic batch writes; the snake_casedatabase::execute_batchduplicate 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_batchmust switch todatabase::executeBatch(no in-repo callers existed).Fixes MOT-4174
Verification
console/web: 1096 vitest tests / 86 files green,tsc -bclean, biome clean on all changed filesdatabase:cargo test— 225 passed, 0 failedcursor://file/...deep-link wiring, copy-path canonical absolute paths, pointer cursors, aria/toggle structure — all verified at HEADSummary by CodeRabbit
New Features
Updates
database::executeBatchacross the product and documentation.Bug Fixes