Turns a voice brain dump into clarifying questions, then a polished prompt in a proven framework.

A Claude Code mod that turns a rambling voice brain dump into a clean, structured prompt.
You dictate with your own voice tool. The mod wraps what you said so that Claude does not start the task right away. Claude first asks a short batch of clarifying questions. After you answer, it rewrites everything into one prompt with these sections: Role, Context, Task, Inputs, Constraints, Steps, Output format, Success criteria, Assumptions. It only runs the prompt after you say go.
/plugin install brain-dump --marketplace leowei31/brain-dump-mod
Then start a new session.
/dump arms your next message as a brain dump. Dictate it and send it.dump: <text> at the start of a message makes just that message a brain dump, with no /dump first./dump on makes every message a brain dump until you run /dump off.The status line shows brain-dump: armed or brain-dump: always while a mode is active.
After Claude asks its questions, answer them and say go when you are happy with the rewritten prompt. Use /dump or dump: for the dump itself and leave the mode off for the replies. With /dump on active, your answers and your "go" are wrapped as brain dumps too.
/dump followed by other text does not submit it. It shows a reminder to use dump: for a one-message dump.
The mod does not record audio. It works on whatever your dictation tool types into the prompt box. It needs a Claude Code build that supports mods. Mode state lives in memory and resets when the mod reloads.
To change the question style or the prompt framework, edit the wrap text in brain-dump/hooks/register.tsx.
hooks/register.tsx 118 lines1import type { Register } from 'claude-code'
2
3type Mode = 'off' | 'next' | 'always'
4
5const PREFIX = /^\s*dump\s*:\s*/i
6
7const USER_ORIGINS = ['composer', 'sdk', 'bridge', 'unclassified']
8
9const statusFor = (mode: Mode) =>
10 mode === 'off' ? undefined : mode === 'always' ? 'brain-dump: always' : 'brain-dump: armed'
11
12const wrap = (raw: string) => `You are a prompt-engineering partner. The text in <brain_dump> is a raw voice transcript, so expect filler words, false starts, repetition, mis-heard words and jumping between topics. Do NOT carry out the task yet. Work in three phases.
13
14PHASE 1 - Understand
15Silently extract: the real goal, the deliverable, any context, constraints and preferences stated, and what is ambiguous or missing. Where the transcript looks mis-heard (names, technical terms), read the project for the likely correct term before asking.
16
17PHASE 2 - Clarify
18Use the AskUserQuestion tool to ask the 3 to 6 questions whose answers would most change the final prompt. Batch them in one call. Offer concrete options with your recommended one first. Skip anything you can infer or look up in the codebase. Ask nothing the dump already answered.
19
20PHASE 3 - Rewrite
21After I answer, produce one final prompt in a fenced block using this framework, omitting sections that do not apply:
22- Role: who the model should act as
23- Context: background, project facts, why this matters
24- Task: the goal in one or two precise sentences
25- Inputs: files, data and links to use
26- Constraints: must / must not, style, scope limits, tools allowed
27- Steps: the approach, only if order matters
28- Output format: exactly what to return and how
29- Success criteria: how to tell it is done and correct
30- Assumptions: anything you decided without confirmation, flagged for me to veto
31
32Write it in clear, direct, specific language, in my voice, with no filler. Then ask whether to run it, edit it, or save it. Only execute after I say go.
33
34<brain_dump>
35${raw.trim()}
36</brain_dump>`
37
38export const register: Register = on => {
39 let mode: Mode = 'off'
40 let isRegistered = false
41
42 on('session.start', async ($, e, next) => {
43 if (!isRegistered) {
44 isRegistered = true
45 await $.command.register({
46 name: 'dump',
47 description: 'Brain dump mode: clarify, then rewrite as a structured prompt',
48 argumentHint: '[on | off]',
49 })
50 }
51
52 return next(e)
53 })
54
55 // A mod enabled mid-session never sees session.start, so register on first draw too.
56 on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
57 if (!isRegistered) {
58 isRegistered = true
59 await $.command.register({
60 name: 'dump',
61 description: 'Brain dump mode: clarify, then rewrite as a structured prompt',
62 argumentHint: '[on | off]',
63 })
64 }
65
66 return next(e)
67 })
68
69 on('command.run', { command: 'dump' }, async ($, e) => {
70 const arg = e.args.trim()
71
72 if (arg === 'off') {
73 mode = 'off'
74 $.ui.status(statusFor(mode))
75
76 return { text: 'Brain dump mode off.' }
77 }
78
79 if (arg === 'on' || arg === 'always') {
80 mode = 'always'
81 $.ui.status(statusFor(mode))
82
83 return { text: 'Brain dump mode on: every prompt is clarified and rewritten. /dump off to stop.' }
84 }
85
86 if (arg === '') {
87 mode = 'next'
88 $.ui.status(statusFor(mode))
89
90 return { text: 'Armed: your next prompt (dictate it now) is treated as a brain dump.' }
91 }
92
93 return { text: 'To dump in one message, start it with "dump:". Or run /dump, then send your message.' }
94 })
95
96 on('prompt.submit', async ($, e, next) => {
97 // The desktop app delivers the person's text as sdk, bridge or unclassified, not only composer.
98 const kind = e.origin?.kind
99 const isUser = kind === undefined || USER_ORIGINS.includes(kind)
100 if (e.command || e.isMeta || !isUser) {
101 return next(e)
102 }
103
104 const hasPrefix = PREFIX.test(e.text)
105 if (mode === 'off' && !hasPrefix) {
106 return next(e)
107 }
108
109 const raw = e.text.replace(PREFIX, '')
110 if (mode === 'next') {
111 mode = 'off'
112 $.ui.status(statusFor(mode))
113 }
114
115 return next({ ...e, text: wrap(raw) })
116 })
117}
118