Stops a Claude Code session from asking you questions when nobody is at the keyboard. Type /unattended, or launch with CLAUDE_UNATTENDED=1.

A Claude Code mod that stops a session from asking you questions when nobody is at the keyboard. When it is on, Claude's question prompts and plan mode are refused with a note telling Claude to pick the most sensible option itself and carry on.
Claude sometimes stops to ask "Which option do you want?" or to get a plan approved. If you started a long job and walked away, the session just sits there waiting.
Example: you ask Claude to clean up a folder and go for lunch. Claude would normally stop and ask which of two naming styles to use. With this mod on, it picks one, tells you which one and why in its reply, and keeps going.
Paste these two lines into a terminal (not into Claude):
claude plugin marketplace add varunmoka7/unattended
claude plugin install unattended@unattended
Needs Claude Code 2.1.287 or newer (mods are on by default from that version). Works on macOS, Linux and Windows.
/unattended flips the mode on or off./unattended on turns it on./unattended off turns it off.CLAUDE_UNATTENDED=1, for example CLAUDE_UNATTENDED=1 claude./unattended or launch with CLAUDE_UNATTENDED=1.Type /unattended off, or remove it completely:
claude plugin uninstall unattended@unattended
MIT
hooks/register.ts 57 lines1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4const on = atom({ plugin: 'unattended', key: 'on' } as const, false)
5
6// What the model reads in place of the tool's result.
7const NO_QUESTIONS =
8 'Unattended mode is on: nobody is at the keyboard to answer. Do not ask again. Pick the most sensible option yourself, say in your reply which one you picked and why, and carry on.'
9
10// ponytail: plan mode ends in an approval dialog a hook cannot answer, so the only
11// safe move is to stop the model entering it. A session launched in plan mode still stops there.
12const NO_PLAN_MODE =
13 'Unattended mode is on: plan mode ends in an approval prompt nobody will answer. Write the plan in your reply instead and go straight on to doing it.'
14
15export const register: Register = hook => {
16 hook('session.start', async ($, e, next) => {
17 await $.command.register({
18 name: 'unattended',
19 description: 'Stop this session asking you questions: /unattended on, /unattended off, or /unattended to flip it',
20 immediate: true,
21 })
22
23 if ((await $.env.get('CLAUDE_UNATTENDED')) === '1') {
24 await update($, on, () => true)
25 }
26
27 return next(e)
28 })
29
30 hook('command.run', { command: 'unattended' }, async ($, e) => {
31 const arg = e.args.trim().toLowerCase()
32 if (arg !== '' && arg !== 'on' && arg !== 'off') {
33 return { text: 'Usage: /unattended on, /unattended off, or /unattended to flip it.' }
34 }
35
36 // Decide inside the update so two quick commands cannot both act on the same old value.
37 let isOn = false
38 await update($, on, current => {
39 isOn = arg === 'on' || (arg !== 'off' && !current)
40 return isOn
41 })
42
43 return { text: isOn ? 'Unattended mode on: questions and plan mode are refused.' : 'Unattended mode off.' }
44 })
45
46 // If the switch cannot be read, let the call through rather than block it.
47 hook('tool.call', { tool: 'AskUserQuestion' }, async ($, e, next) => {
48 const isOn = await read($, on).catch(() => false)
49 return isOn ? { deny: NO_QUESTIONS } : next(e)
50 })
51
52 hook('tool.call', { tool: 'EnterPlanMode' }, async ($, e, next) => {
53 const isOn = await read($, on).catch(() => false)
54 return isOn ? { deny: NO_PLAN_MODE } : next(e)
55 })
56}
57types/index.d.ts 9 lines1// Whether this session runs with nobody at the keyboard
2export type On = boolean
3
4declare module 'claude-code' {
5 interface PluginState {
6 unattended: { on: On }
7 }
8}
9