Skip to content

feat(mobile): add tap-to-copy action to session code blocks - #6098

Merged
iscekic merged 1 commit into
mainfrom
kwf/surface-the-mobile-app-apps-mobile-65e8
Sep 14, 2026
Merged

feat(mobile): add tap-to-copy action to session code blocks#6098
iscekic merged 1 commit into
mainfrom
kwf/surface-the-mobile-app-apps-mobile-65e8

Conversation

@iscekic

@iscekic iscekic commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Changelog for users

  • Tapping a rendered code block on the session page reveals an inline "Copy" action.
  • The action is placed at the tapped position, so it stays visible on code blocks taller than the screen.
  • Tapping "Copy" copies the whole code block, including text hidden behind the display cap.
  • A "Copied to clipboard" confirmation appears after a successful copy.
  • Empty code blocks never offer the copy action.
  • Long-pressing a code block opens message details and dismisses any revealed copy action.
  • Screen readers get a "copy code" action on the code text.

Changelog for maintainers

  • MarkdownText and MarkdownRenderer take optional onCopyCode and onLongPressCode handlers; omitting them keeps fences static, as tool cards do.
  • CodeBlock reserves a right gutter from the rendered copy label width, so the pill never covers source glyphs in any locale.
  • The copy trigger is the block's only pressable wrapper; a long press forwards to the host instead of revealing the action.
  • The value handed to the caller is the full source before the display cap, not the truncated slice.
  • chat-markdown-text routes copies through performCopy, so haptic and toast feedback matches every other copy action.
  • message-bubble, part-renderer, and text-part-renderer forward the details long-press into code fences.
  • The success toast now lasts 8000 ms because Android's system clipboard preview covers the default-length toast.
  • Review first: the tap-anchored positioning and gutter measurement in code-block.tsx; companion test files cover reveal, dismissal, empty fences, and long-press forwarding.

E2E proof

[p3] Session page: long-press a code block inside a tool card (e.g. — Android emulator-5606, live re-run on head 0d86de5f (clean tree): on the 'Mobile sheet fixtures' session page that renders the read/task tool cards, long-press on the console.log("Hello World"); fenced code block opened the message-details sheet — p3-live2.log line 1 'SCENE p3 OK' and line 4 'android.view.View Message details tappable [37,183][858,248]'; same-commit reviewed artifacts p3-verify.log and p3-lp-inline.log carry the identical digest (collection 2026-09-12), captures for the visual reviewer are p3.png and p3.mp4. Gap: the New-session model picker lists no 'Fake Deterministic'…

p3.mp4.trim.mp4

[p1] Session page: tap a code block in an assistant message -> an inline 'Copy' pill appears; tapping it copies the full source (including text past the display cap) and shows 'Copied to clipboard'. — Re-ran live on android emulator-5554 (HEAD 0d86de5; identical to prior pass): session.sh enter ses_000000000001RootFixture001 (Mobile sheet fixtures, 50000 display cap), tap at (541,1045) on the assistant-message fence [69,360][1013,1730] -> p1-reveal-run.log 'SCENE p1-reveal OK' + 'android.widget.Button Copy tappable [907,1045][1013,1106]' (no reflow: fence bounds unchanged); tap Copy -> p1-copyrun.log 'SCENE p1 OK' (absent Copy) and p1-clipboard-proof-run.log '{"clipboardLength":61253,"displayCap":50000,"beyondDisplayCap":true,"endsWithFullSourceMarker":true,...}', written onto an empty…

p1-run.mp4.trim.mp4

[p1] Session page: tap a code block in an assistant message -> an inline 'Copy' pill appears; tapping it copies the full source (including text past the display cap) and shows 'Copied to clipboard'. — android emulator-5554, session ses_000000000001RootFixture001: one scripted run 'SCENE p1 OK' (p1-run.log:1) asserted 'Content truncated', tapped the fence and tapped 'Copy'; independently p1-tap.log:10 shows 'android.widget.Button Copy tappable [907,1045][1013,1106]' (pill anchored to the real tap at (541,1045)); copy proof p1-clipboard-fullsource.log quotes '{"clipboardLength":61253,"displayCap":50000,"beyondDisplayCap":true,"endsWithFullSourceMarker":true}', i.e. the full source past the 50k display cap; p1-lp.log confirms the fence is in an assistant message (long-press -> 'Message…

p1-copy-flow.mp4.trim.mp4

[p1] Session page: tap a code block in an assistant message -> an inline 'Copy' pill appears; tapping it copies the full source (including text past the display cap) and shows 'Copied to clipboard'. — android emulator-5604, worktree head d86532b0e9e499ffda025fb232074460141ddc14; setup was the read-only fixture session via session.sh enter emulator-5604 ses_000000000001RootFixture001 (the CLI fixture session is not listed on Home/Agents, so the deep link is the only path), then one scripted call. p1-behavior.log:1 'SCENE p1-reveal OK' with :11 'android.widget.Button Copy tappable [907,1215][1013,1276]' (single tap reveals the inline pill; fence bounds :10 'code-block-copy-trigger tappable [69,360][1013,1730]' unchanged, and :13 'Content truncated' marks the 50000 display cap) and :45…

p1-toast.mp4.trim.mp4

[p1] Session page: tap a code block in an assistant message -> an inline 'Copy' pill appears; tapping it copies the full source (including text past the display cap) and shows 'Copied to clipboard'. — prior/p1-toast-6s.png

[p1] Session page: tap a code block in an assistant message -> an inline 'Copy' pill appears; tapping it copies the full source (including text past the display cap) and shows 'Copied to clipboard'. — prior/p1-copy-toast.png

E2E proof — log excerpts

[e1] Session page: tap a code block in an assistant message -> an inline 'Copy'  -> pass :: android emulator-5554; single tap revealed the pill ('SCENE e1 OK', 'android.widget.Button Copy tappable [907,1215][1013,1276]' in e1-scene.log); after wiping the clipboard to a 20-char sentinel, tapping the pill wrote the full 61253-char source past the 50000 display cap (on-screen text lacks END_OF_FULL_SOURCE_MARKER) per e1-clipboard-fresh.log; the app committed 'Copied to clipboard' to its React tree (e1-toast.log) and the assistant role is proved in e1-role.log; no UX-DEFECT (trigger bounds unchanged after reveal).
[e2] Session page: long-press a code block in an assistant or user message -> th -> pass :: android/emulator-5604: scripted-e2.log line 1 'SCENE e2 OK' proves scene e2 (scripts-shard2.json: longPress the fence, assert 'Message details', tap Done, absent 'Copy') opened the message-details sheet with no copy pill; digest line 14 'code-block-copy-trigger tappable' is present and no Copy element remains. Owner-request single-tap check: e2-tap2.log line 1 'SCENE e2-tap-reveal OK' with digest line 15 'android.widget.Button Copy tappable [874,1530][980,1590]' proves a single tap reveals the inline Copy action, and 'Preparation complete tappable [40,1643][1042,1744]' keeps identical bounds before/after reveal (no layout shift). Replay banked at e2.replay.json.
[e3] Session page: long-press a code block inside a tool card (e.g. Read tool ou -> pass :: android emulator-5606; independent replay logged 'SCENE e3 OK' and the message-details sheet digest 'android.view.View Message details tappable [37,183][858,248]' (e3-longpress.log), matching the pre-run scripted-e3.log; the long-press was not swallowed by the new code-block copy trigger.
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/e1-scene.log
android.widget.TextView direct-fixture.txt tappable [128,1857][366,1903]
android.view.ViewGroup User message tappable [0,2071][1080,2090]
android.widget.TextView This is a read-only session tappable [36,2141][1044,2187]
android.widget.Button Continue tappable [37,2215][1043,2309]
android.widget.TextView Continue tappable [473,2239][606,2285]
SCENE e1-pill OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.Button Go back tappable [0,163][101,264]
android.widget.Button Rename session: Mobile sheet fixtures tappable [111,149][746,278]
android.view.View Mobile sheet fixtures tappable [111,180][746,245]
android.widget.Button Context 1,375 of 1,000,000 tokens, 0% used, cost 1 cent. Tap to view context details. tappable [773,156][1043,271]
android.widget.TextView 0% tappable [895,195][932,232]
android.widget.TextView $0.01 tappable [941,195][1013,232]
android.view.ViewGroup code-block-copy-trigger tappable [69,360][1013,1730]
android.widget.Button Copy tappable [907,1215][1013,1276]
android.widget.TextView Copy tappable [928,1226][992,1263]
android.widget.TextView Content truncated tappable [69,1739][1013,1776]
android.widget.Button direct-fixture.txt tool, completed tappable [40,1839][1042,1922]
android.widget.TextView direct-fixture.txt tappable [128,1857][366,1903]
android.view.ViewGroup User message tappable [0,2071][1080,2090]
android.widget.TextView This is a read-only session tappable [36,2141][1044,2187]
android.widget.Button Continue tappable [37,2215][1043,2309]
android.widget.TextView Continue tappable [473,2239][606,2285]
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/e1-clipboard-fresh.log
e1 clipboard proof — 2026-09-12 — android emulator-5554 (RN inspector target 3d56ddb19be6ce5dca1bff1113b7151b9d545159)
setup: session.sh enter emulator-5554 ses_000000000001RootFixture001  (session "Mobile sheet fixtures"; the code fence is in an assistant message, proved by long-press -> Message details ROLE=Assistan
session.sh: link delivered on emulator-5554
freshness: before the UI copy the device clipboard is overwritten with a 20-char sentinel:
  proving command: cdp-eval.sh <ws> Runtime.evaluate 'expo.modules.ExpoClipboard.setStringAsync("SENTINEL_KWF_E1_2026",{})'
  read back: {"id":1,"result":{"result":{"type":"string","value":"ok | len=20;val=SENTINEL_KWF_E1_2026"}}}
copy: appium.sh emulator-5554 script scenes-e1-final.json --out <OUT>
  steps: tap code block; assert Copy; tap Copy pill
  SCENE e1 OK
  android.widget.Button Copy tappable [907,1215][1013,1276]
after the UI copy, read the device clipboard again:
  proving command: cdp-eval.sh <ws> Runtime.evaluate 'expo.modules.ExpoClipboard.getStringAsync({})'
  {"len":61253,"beyondCap":true,"sourceRole":"assistant","hasMarker":true,"head":"console.log(\"Hello World\");\n001xxxxxxxxxxx","tail":"xxxxxxxxxxxxxxxxxxx\nEND_OF_FULL_SOURCE_MARKER"}
the on-screen code text is truncated and does NOT contain the source tail marker:
  grep -c END_OF_FULL_SOURCE_MARKER e1-state.xml  ->  0
so the 61253-char clipboard value (ending END_OF_FULL_SOURCE_MARKER) is the full source,
not the truncated slice the transcript displays.
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/e1-toast.log
e1 copy-feedback proof — 2026-09-12 — android emulator-5554 (RN inspector target 3d56ddb19be6ce5dca1bff1113b7151b9d545159)
proving command: cdp-eval.sh <ws> Runtime.evaluate  (installs a 150 ms poll over the React fiber tree
  that records any committed node whose text contains 'Copied')
  {"id":1,"result":{"result":{"type":"string","value":"installed"}}}
copy: appium.sh emulator-5554 script scenes-e1-toastfiber.json --out <OUT>
  steps: tap code block; assert Copy; tap Copy pill
  SCENE e1-toastfiber OK
fiber poll result read right after the copy:
  {"id":1,"result":{"result":{"type":"string","value":"[\"Copied to clipboard\"]"}}}
so the copy action commits the feedback text "Copied to clipboard" to the running app's
React tree; the toast's on-screen appearance is left to the visual reviewer
(capture: e1.png, recording: e1-copy-recording.mp4).
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/e1-role.log
android.widget.TextView Select text tappable [94,479][985,535]
android.widget.Button Report AI response tappable [55,621][1025,737]
android.widget.TextView Report AI response tappable [94,651][985,707]
android.widget.TextView ROLE tappable [55,792][1025,829]
android.widget.TextView Assistant tappable [55,838][1025,894]
android.widget.TextView SENT tappable [55,931][1025,968]
android.widget.TextView Nov 14, 2023, 10:13 PM tappable [55,977][1025,1033]
android.widget.TextView MODEL tappable [55,1070][1025,1107]
android.widget.TextView Claude Sonnet 4 tappable [55,1116][1025,1172]
android.widget.TextView Cost &amp; tokens tappable [55,1246][1025,1292]
android.widget.TextView COST tappable [55,1329][1025,1366]
android.widget.TextView $0.0100 tappable [55,1375][1025,1431]
android.widget.TextView Input tappable [55,1468][131,1514]
android.widget.TextView 1,000 tappable [941,1468][1024,1514]
android.widget.TextView Output tappable [55,1542][155,1588]
android.widget.TextView 200 tappable [967,1542][1024,1588]
android.widget.TextView Reasoning tappable [55,1615][211,1661]
android.widget.TextView 100 tappable [967,1615][1024,1661]
android.widget.TextView Cache read tappable [55,1689][222,1735]
android.widget.TextView 50 tappable [986,1689][1024,1735]
android.widget.TextView Cache write tappable [55,1762][229,1808]
android.widget.TextView 25 tappable [986,1762][1024,1808]
android.widget.TextView Total tappable [55,1836][129,1882]
android.widget.TextView 1,375 tappable [941,1836][1024,1882]
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/scripted-e2.log
SCENE e2 OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.Button Go back tappable [0,163][101,265]
android.widget.Button Rename session: TypeScript code fence comparison tappable [111,149][714,279]
android.view.View TypeScript code fence comparison tappable [111,149][714,279]
android.widget.Button Context 11,079 of 1,000,000 tokens, 1% used, cost 0.09 cents. Tap to view context details. tappable [741,156][1043,272]
android.widget.TextView 1% tappable [863,195][900,232]
android.widget.TextView $0.0009 tappable [909,195][1013,232]
android.widget.TextView 8:13 AM tappable [476,1110][604,1149]
android.view.ViewGroup fake:echo:Empty fence below:, Non-empty fence below:, User message tappable [0,1167][1080,1623]
android.widget.TextView fake:echo:Empty fence below: tappable [250,1204][1012,1267]
android.widget.TextView Non-empty fence below: tappable [250,1400][1012,1463]
android.view.ViewGroup code-block-copy-trigger tappable [282,1511][980,1549]
android.widget.Button Preparation complete tappable [40,1643][1042,1744]
android.widget.TextView Preparation complete tappable [188,1670][506,1716]
android.widget.Button Thought tappable [40,1777][1042,1850]
android.widget.TextView THOUGHT tappable [68,1795][206,1832]
android.widget.Button Add attachment tappable [28,2214][101,2288]
android.widget.EditText Message tappable [126,2191][800,2311]
android.widget.Button Start voice input tappable [835,2205][926,2297]
android.widget.Button Send message [926,2188][1052,2314]
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/e2-tap2.log
android.widget.Button Start voice input tappable [835,2205][926,2297]
android.widget.Button Send message [926,2188][1052,2314]
SCENE e2-tap-hide OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.Button Go back tappable [0,163][101,265]
android.widget.Button Rename session: TypeScript code fence comparison tappable [111,149][714,279]
android.view.View TypeScript code fence comparison tappable [111,149][714,279]
android.widget.Button Context 11,079 of 1,000,000 tokens, 1% used, cost 0.09 cents. Tap to view context details. tappable [741,156][1043,272]
android.widget.TextView 1% tappable [863,195][900,232]
android.widget.TextView $0.0009 tappable [909,195][1013,232]
android.widget.TextView 8:13 AM tappable [476,1110][604,1149]
android.view.ViewGroup fake:echo:Empty fence below:, Non-empty fence below:, User message tappable [0,1167][1080,1622]
android.widget.TextView fake:echo:Empty fence below: tappable [250,1204][1012,1267]
android.widget.TextView Non-empty fence below: tappable [250,1400][1012,1463]
android.view.ViewGroup code-block-copy-trigger tappable [282,1511][980,1549]
android.widget.Button Preparation complete tappable [40,1643][1042,1744]
android.widget.TextView Preparation complete tappable [188,1670][506,1716]
android.widget.Button Thought tappable [40,1777][1042,1850]
android.widget.TextView THOUGHT tappable [68,1795][206,1832]
android.widget.Button Add attachment tappable [28,2214][101,2288]
android.widget.EditText Message tappable [126,2191][800,2311]
android.widget.Button Start voice input tappable [835,2205][926,2297]
android.widget.Button Send message [926,2188][1052,2314]
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/e3-longpress.log
android.widget.TextView Select text tappable [94,479][985,535]
android.widget.Button Report AI response tappable [55,621][1025,737]
android.widget.TextView Report AI response tappable [94,651][985,707]
android.widget.TextView ROLE tappable [55,792][1025,829]
android.widget.TextView Assistant tappable [55,838][1025,894]
android.widget.TextView SENT tappable [55,931][1025,968]
android.widget.TextView Nov 14, 2023, 10:13 PM tappable [55,977][1025,1033]
android.widget.TextView MODEL tappable [55,1070][1025,1107]
android.widget.TextView Claude Sonnet 4 tappable [55,1116][1025,1172]
android.widget.TextView Cost &amp; tokens tappable [55,1246][1025,1292]
android.widget.TextView COST tappable [55,1329][1025,1366]
android.widget.TextView $0.0100 tappable [55,1375][1025,1431]
android.widget.TextView Input tappable [55,1468][131,1514]
android.widget.TextView 1,000 tappable [941,1468][1024,1514]
android.widget.TextView Output tappable [55,1542][155,1588]
android.widget.TextView 200 tappable [967,1542][1024,1588]
android.widget.TextView Reasoning tappable [55,1615][211,1661]
android.widget.TextView 100 tappable [967,1615][1024,1661]
android.widget.TextView Cache read tappable [55,1689][222,1735]
android.widget.TextView 50 tappable [986,1689][1024,1735]
android.widget.TextView Cache write tappable [55,1762][229,1808]
android.widget.TextView 25 tappable [986,1762][1024,1808]
android.widget.TextView Total tappable [55,1836][129,1882]
android.widget.TextView 1,375 tappable [941,1836][1024,1882]
/home/igor_kilocode_ai/.local/share/kwf/sections/surface-the-mobile-app-apps-mobile-65e8/e2e-mobile-app/scripted-e3.log
android.widget.TextView Select text tappable [94,479][985,535]
android.widget.Button Report AI response tappable [55,621][1025,737]
android.widget.TextView Report AI response tappable [94,651][985,707]
android.widget.TextView ROLE tappable [55,792][1025,829]
android.widget.TextView Assistant tappable [55,838][1025,894]
android.widget.TextView SENT tappable [55,931][1025,968]
android.widget.TextView Nov 14, 2023, 10:13 PM tappable [55,977][1025,1033]
android.widget.TextView MODEL tappable [55,1070][1025,1107]
android.widget.TextView Claude Sonnet 4 tappable [55,1116][1025,1172]
android.widget.TextView Cost &amp; tokens tappable [55,1246][1025,1292]
android.widget.TextView COST tappable [55,1329][1025,1366]
android.widget.TextView $0.0100 tappable [55,1375][1025,1431]
android.widget.TextView Input tappable [55,1468][131,1514]
android.widget.TextView 1,000 tappable [941,1468][1024,1514]
android.widget.TextView Output tappable [55,1542][155,1588]
android.widget.TextView 200 tappable [967,1542][1024,1588]
android.widget.TextView Reasoning tappable [55,1615][211,1661]
android.widget.TextView 100 tappable [967,1615][1024,1661]
android.widget.TextView Cache read tappable [55,1689][222,1735]
android.widget.TextView 50 tappable [986,1689][1024,1735]
android.widget.TextView Cache write tappable [55,1762][229,1808]
android.widget.TextView 25 tappable [986,1762][1024,1808]
android.widget.TextView Total tappable [55,1836][129,1882]
android.widget.TextView 1,375 tappable [941,1836][1024,1882]
Owner request

Surface: the mobile app (apps/mobile).

When markdown renders a code block on the session page, a single tap on the code block should spawn an inline (or popover, or tooltip, or similar) "copy code" action.

Owner manual verification

The workflow skipped these checks. Owner verification is pending; these checks did not pass automatically.

  • owner-manual: none.

Comment thread apps/mobile/src/components/agents/chat-markdown-text.tsx
Comment thread apps/mobile/src/components/agents/markdown-text.tsx
@kilo-code-bot

kilo-code-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change resolves both prior findings: the Kilo Chat code-fence long-press is now forwarded through message-bubble -> message-bubble-content -> message-markdown -> ChatMarkdownText, and the transcript handleLongPress handlers are memoized so the markdown renderer is no longer rebuilt on every bubble render. No new issues found in the changed code.

Files Reviewed (7 files)
  • apps/mobile/src/components/agents/message-bubble-longpress-stability.mounted.test.tsx
  • apps/mobile/src/components/agents/message-bubble.test.ts
  • apps/mobile/src/components/agents/message-bubble.tsx
  • apps/mobile/src/components/kilo-chat/message-bubble-content.tsx
  • apps/mobile/src/components/kilo-chat/message-bubble.tsx
  • apps/mobile/src/components/kilo-chat/message-markdown-longpress.mounted.test.tsx
  • apps/mobile/src/components/kilo-chat/message-markdown.tsx
Previous Review Summary (commit 4d96809)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 4d96809)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

ChatMarkdownText now always supplies onCopyCode, so code fences in Kilo Chat messages mount a copy-trigger Pressable that swallows the enclosing message long-press gesture.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 1
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/agents/chat-markdown-text.tsx 138 Unconditional onCopyCode mounts the copy trigger without onLongPressCode, so the inner Pressable swallows the wrapping message long-press (opens actions) for code fences in Kilo Chat.

SUGGESTION

File Line Issue
apps/mobile/src/components/agents/markdown-text.tsx 200 The unstable inline handleLongPress from message-bubble.tsx is now a renderer useMemo dependency, rebuilding the renderer/parse on every parent render rather than only on value changes.
Files Reviewed (13 files)
  • apps/mobile/src/components/agents/chat-markdown-text.tsx - 1 issue
  • apps/mobile/src/components/agents/code-block.test.ts - no issues
  • apps/mobile/src/components/agents/code-block.tsx - no issues
  • apps/mobile/src/components/agents/markdown-renderer.test.ts - no issues
  • apps/mobile/src/components/agents/markdown-renderer.ts - no issues
  • apps/mobile/src/components/agents/markdown-table.test.ts - no issues
  • apps/mobile/src/components/agents/markdown-text.tsx - 1 issue
  • apps/mobile/src/components/agents/message-bubble.test.ts - no issues
  • apps/mobile/src/components/agents/message-bubble.tsx - no issues
  • apps/mobile/src/components/agents/part-renderer.tsx - no issues
  • apps/mobile/src/components/agents/text-part-renderer.tsx - no issues
  • apps/mobile/src/components/agents/use-message-copy.test.ts - no issues
  • apps/mobile/src/components/agents/use-message-copy.ts - no issues

No memory leaks were found: the new state is bounded (copyActionTop, copyActionMetrics), the track effect keeps its unregister cleanup, and no timers, listeners, or subscriptions were added.

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic marked this pull request as draft September 12, 2026 18:52
@iscekic
iscekic force-pushed the kwf/surface-the-mobile-app-apps-mobile-65e8 branch from 4d96809 to cf09867 Compare September 13, 2026 03:39
@iscekic
iscekic marked this pull request as ready for review September 13, 2026 04:03
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 13, 2026
@iscekic
iscekic requested a review from eshurakov September 13, 2026 04:29
@iscekic iscekic self-assigned this Sep 13, 2026
@iscekic
iscekic requested a review from pandemicsyn September 13, 2026 22:10
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.

2 participants