Copy the prompt box to the clipboard and clear it: Ctrl+Shift+U cuts the whole draft, and a Cut button shows while the box has text.

A mod (function hooks that run inside Claude Code) that copies the prompt box to the system clipboard and clears it.
If the copy fails the draft is kept and a toast says so.
The button joins the band above the prompt instead of replacing it: it draws what the plugins beneath it drew and adds itself, so mods such as image-peek keep their own band (0.1.0 hid them; fixed in 0.1.1).
/plugin install cut-input --marketplace shdennlin/agent-plugins
Needs Claude Code 2.1.289+ (hook modules).
claude plugin validate plugins/cut-input
claude plugin test plugins/cut-input
claude --plugin-dir ./plugins/cut-input # lays .claude-plugin/types/ for tsc -p plugins/cut-inputhooks/register.tsx 82 lines1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4const hasText = atom({ plugin: 'cut-input', key: 'hasText' } as const, false)
5
6export const register: Register = on => {
7 // ctrl+shift+u cuts the whole draft, regardless of cursor position
8 on('prompt.edit', async ($, e, next) => {
9 const isKillAll = e.key?.ctrl === true && e.key.shift === true && e.key.key === 'u'
10
11 if (isKillAll && e.text !== '') {
12 const { isCopied } = await $.ui.copy({ text: e.text })
13
14 if (!isCopied) {
15 return next(e)
16 }
17
18 await update($, hasText, () => false)
19
20 return { text: '', cursor: 0 }
21 }
22
23 const result = await next(e)
24
25 await update($, hasText, () => result.text !== '')
26
27 return result
28 })
29
30 on('prompt.fill', async ($, e, next) => {
31 const result = await next(e)
32 await update($, hasText, () => result.isFilled ? e.mode !== 'replace' || e.text !== '' : false)
33
34 return result
35 })
36
37 on('prompt.submit', async ($, e, next) => {
38 update($, hasText, () => false).catch(() => {})
39
40 return next(e)
41 })
42
43 on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
44 if (e.props.hasSurvey || !(await read($, hasText))) {
45 return next(e)
46 }
47
48 const { Box, Button } = $.ui.resolve(e)
49 const below = await next(e)
50
51 return (
52 <Box flexDirection="column">
53 {below}
54 <Box justifyContent="flex-end">
55 <Button
56 key="cut"
57 label="✂ Cut input"
58 onPress={async press => {
59 const { text } = await $.prompt.read()
60
61 if (text === '') {
62 return
63 }
64
65 const { isCopied } = await $.ui.copy({ text, surface: press.surface })
66
67 if (!isCopied) {
68 $.ui.toast('Copy failed, input kept')
69 return
70 }
71
72 await $.prompt.fill({ text: '' })
73 await update($, hasText, () => false)
74 $.ui.toast('Copied and cleared')
75 }}
76 />
77 </Box>
78 </Box>
79 )
80 })
81}
82types/index.d.ts 8 lines1export type CutInputKey = 'hasText'
2
3declare module 'claude-code' {
4 interface PluginState {
5 'cut-input': { hasText: boolean }
6 }
7}
8