Attaches hidden clarify-or-proceed guidance to short or vague prompts

A collection of plugins (mods) that extend the local Claude Code harness.
| Plugin | Purpose |
|---|---|
prompt-optimizer | Attaches a hidden "clarify or proceed" instruction to short or vague prompts: if a key decision is missing, Claude asks at most 3 questions first; otherwise it proceeds and states its assumptions on the first line of the reply |
session-picker | Control panel (Traditional Chinese UI): a button band above the prompt and a docked pane with Session (10 most recent unfinished sessions, click to /resume), Tool, MCP (enable/disable), 流程 (plan progress + live tool/agent/MCP activity, secrets masked) and 記憶 (loaded memory files: view or copy path) tabs, plus copy buttons for paths/URLs under each reply |
| Launcher | Purpose |
|---|---|
start-claude | Windows double-click launcher: choose billing before Claude Code starts — 1 subscription (OAuth; clears the API key for that window only and requires authMethod claude.ai) or 2 API key (--bare, re-loads CLAUDE.md with --add-dir). Set the user environment variable CLAUDE_WORKDIR to your work folder. Details (Traditional Chinese): launchers/start-claude/README.md |
These plugins use Claude Code's function hooks (hooks/register.ts), which is an early access API.
git clone https://github.com/bai-collab/claude_code_mod
claude --plugin-dir ./claude_code_mod/plugins/prompt-optimizer
You can also try the marketplace route (not yet verified for function-hook plugins):
/plugin marketplace add bai-collab/claude_code_mod
/plugin install prompt-optimizer@claude-code-mod
| Usage | Effect |
|---|---|
| Type a prompt as usual | In short-only mode, prompts under 80 characters get the guidance |
Start the prompt with * (asterisk + space) | Skips the guidance for that one prompt. The * is removed only when the guidance would otherwise apply |
/prompt-optimizer | Pauses or resumes the plugin for the current session |
/config | Change mode (short-only / always / off) and minLength |
context that the model reads but you never see, so your prompt text is not rewritten.PO: on.Details (Traditional Chinese): plugins/session-picker/README.md.
cd <your work folder> # the Session tab lists this folder's sessions
claude --plugin-dir <clone>/plugins/session-picker
On Windows you can double-click plugins/session-picker/open-claude-with-panel.cmd. After a fresh clone, first set the user environment variable CLAUDE_WORKDIR to your work folder (otherwise it uses the folder two levels above the plugin). The launcher also expects ANTHROPIC_API_KEY at user level.
| Entry | Effect | |
|---|---|---|
Band buttons Session Tool MCP 流程 記憶 | Open the panel on that tab (mouse clicks need the fullscreen layout) | |
/sessions, /panel | Open the panel | |
| `/panel auto on\ | off` | Auto-open the panel on session start |
| `/panel copybar on\ | off` | Show/hide copy buttons under replies |
planned/*.md, memory files, and ~/.claude.json (only the disabled-MCP name lists). Writes nothing; runs only its own read-only Node script and /resume, /mcp enable|disable when you press those buttons..claude-plugin/types/ is generated locally by /plugin-types and is not committed.claude plugin validate plugins/prompt-optimizer
claude plugin test plugins/prompt-optimizerhooks/register.ts 69 lines1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4const COMMAND = 'prompt-optimizer'
5const BYPASS = '* '
6
7// Origins typed by the person; notifications, peers and schedules are left alone.
8const HUMAN_ORIGINS = new Set(['composer', 'bridge'])
9
10export const GUIDANCE = [
11 '[prompt-optimizer] Before acting, check whether this prompt states its goal, scope and what "done" looks like.',
12 '- If a decision only the user can make is missing and cannot be inferred from the code or a sensible default, ask at most 3 short clarifying questions first.',
13 '- Otherwise proceed directly, and open your reply with one line naming the assumptions you made.',
14].join('\n')
15
16const isPaused = atom({ plugin: 'prompt-optimizer', key: 'isPaused' } as const, false)
17
18export const register: Register = (on, options) => {
19 const mode = String(options.mode ?? 'short-only')
20 const minLength = Number(options.minLength ?? 80)
21
22 on('session.start', async ($, e, next) => {
23 await $.command.register({
24 name: COMMAND,
25 description: 'Pause or resume prompt-optimizer for this session',
26 })
27 // A /config change reloads the module and re-fires this; the pause survives it.
28 const paused = await read($, isPaused)
29 $.ui.status(mode === 'off' || paused ? undefined : 'PO: on')
30
31 return next(e)
32 })
33
34 on('command.run', { command: COMMAND }, async $ => {
35 const paused = await update($, isPaused, was => !was)
36 $.ui.status(mode === 'off' || paused ? undefined : 'PO: on')
37
38 return {
39 text: paused
40 ? 'prompt-optimizer paused for this session.'
41 : 'prompt-optimizer resumed for this session.',
42 }
43 })
44
45 on('prompt.submit', async ($, e, next) => {
46 if (!HUMAN_ORIGINS.has(e.origin.kind)) {
47 return next(e)
48 }
49
50 const text = e.text.trimStart()
51 const isWanted =
52 mode === 'always' || (mode === 'short-only' && text.length < minLength)
53
54 if (!isWanted || text.startsWith('/') || (await read($, isPaused))) {
55 return next(e)
56 }
57
58 // A leading "* " skips the guidance for one prompt; only stripped when
59 // guidance would otherwise apply, and never down to an empty prompt.
60 if (text.startsWith(BYPASS)) {
61 const rest = text.slice(BYPASS.length).trimStart()
62
63 return rest === '' ? next(e) : next({ ...e, text: rest })
64 }
65
66 return next({ ...e, context: [...(e.context ?? []), GUIDANCE] })
67 })
68}
69types/index.d.ts 8 lines1export type Paused = boolean
2
3declare module 'claude-code' {
4 interface PluginState {
5 'prompt-optimizer': { isPaused: Paused }
6 }
7}
8