Attach an intent protocol to every prompt: restate the goal, separate confirmed from assumed, ask before acting on vague input.

Claude Code Mod:让模型动工前先搞清用户到底要什么,不瞎猜、不瞎扩。
外部钩子逼不出真正的内心循环,能做的是给每轮指令加协议。本 Mod 在 prompt.submit 处贴一份意图协议(模型看得到,用户看不到):
confirmFirst: true 则每轮都按强的来。误伤代价只是一次追问, 比猜错开工便宜。
claude --plugin-dir mods/clear-intent
claude plugin test mods/clear-intent
claude plugin install plus@claudecode-plus-mod --scope userhooks/register.ts 41 lines1import type { On } from 'claude-code'
2
3import { intentNote } from './intent'
4
5type IntentOptions = {
6 confirmFirst?: boolean
7 verbose?: boolean
8}
9
10function report($: unknown, message: string, verbose: boolean): void {
11 const ui = ($ as { ui: { log: (text: string, opts?: object) => void } }).ui
12 if (verbose) {
13 ui.log(message)
14 } else {
15 ui.log(message, { to: 'debug' })
16 }
17}
18
19/**
20 * Attaches the intent protocol beside every submitted prompt, where the
21 * model reads it and the user never sees it. Vague input earns the strong
22 * note: restate, wait for confirmation, read-only until then.
23 *
24 * @param on the engine's registrar
25 * @param options `confirmFirst` upgrades every prompt to the strong note
26 */
27export function register(on: On, options: IntentOptions = {}): void {
28 const confirmFirst = options.confirmFirst === true
29 const verbose = options.verbose === true
30
31 on('session.start', ($, e, next) => {
32 report($, '[clear-intent] active, intent protocol armed for prompt.submit', verbose)
33 return next(e)
34 })
35
36 on('prompt.submit', (_$, e, next) => {
37 const { note } = intentNote(e.text, confirmFirst)
38 return next({ ...e, context: [...(e.context ?? []), note] })
39 })
40}
41hooks/intent.ts 38 lines1/**
2 * Intent protocol: a short confirmation-first note attached beside every
3 * prompt. The model cannot be forced into an inner loop from outside, so the
4 * lever is the instruction it reads: restate the goal, mark what is assumed,
5 * and stop before load-bearing actions on vague input.
6 */
7
8export type IntentLevel = 'strong' | 'standard'
9
10const STANDARD_NOTE = [
11 '意图协议:动工前先用一句话说清用户到底要什么。',
12 '严格区分【已确认】和【脑补】;靠脑补才能成立的关键步骤,先问一句再动手。',
13 '禁止过度解读:没说的需求不许自行脑补实现。',
14].join('\n')
15
16const STRONG_NOTE = [
17 '意图协议(本次输入模糊):必须先用一句话复述你的理解并等用户确认。',
18 '确认之前只做只读操作,不写文件、不跑会产生副作用的命令。',
19 '禁止按自己的猜测直接开工,猜错比追问贵。',
20].join('\n')
21
22const VAGUE_PATTERNS = [/随便/, /看着办/, /都可以/, /都行/, /帮我(一下)?$/, /^(hi|hello|在吗|你好)[!!.。]*$/i]
23
24/**
25 * @param text the prompt as typed
26 * @param confirmFirst when true, every prompt gets the strong note
27 * @returns the note level and text to attach beside the prompt
28 */
29export function intentNote(text: string, confirmFirst = false): { level: IntentLevel; note: string } {
30 const trimmed = text.trim()
31 const short = [...trimmed].length < 12
32 const vague = VAGUE_PATTERNS.some((pattern) => pattern.test(trimmed))
33 if (confirmFirst || short || vague) {
34 return { level: 'strong', note: STRONG_NOTE }
35 }
36 return { level: 'standard', note: STANDARD_NOTE }
37}
38