Auto-approves every tool call and permission prompt while enabled; toggle with /auto-allow

A Claude Code mod that auto-approves every tool call and permission prompt while enabled. Toggle it with /auto-allow. State persists across sessions and is off by default. A small dog chases a ball while it is on.
Warning: while enabled, Claude can run any tool without asking. Use it only in environments you trust.
Copy this directory to ~/.claude/mods/auto-allow, then restart Claude Code.
hooks/register.tsx — the modtests/auto-allow.test.ts — testshooks/register.tsx 102 lines1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4const PANE = 'auto-allow'
5// Persisted across sessions in $.store; off until toggled on.
6const STORE_KEY = 'enabled'
7
8const enabledAtom = atom({ plugin: 'auto-allow', key: 'enabled' } as const, false)
9const frameAtom = atom({ plugin: 'auto-allow', key: 'frame' } as const, 0)
10
11// The dog chases a ball back and forth while auto-allow is on.
12const PLAY = [
13 [' o ', '(ᵔᴥᵔ) '],
14 [' o ', ' (ᵔᴥᵔ) '],
15 [' o ', ' (ᵔᴥᵔ)ノ '],
16 [' o ', ' ٩(ᵔᴥᵔ) '],
17 [' o ', ' (ᵔᴥᵔ) '],
18 [' o ', ' (ᵔᴥᵔ)ノ '],
19 [' o ', ' ٩(ᵔᴥᵔ) '],
20 [' o ', ' (ᵔᴥᵔ) '],
21]
22const SLEEP = [
23 [' z ', '(-ᴥ-) '],
24 [' zZ ', '(-ᴥ-) '],
25]
26
27async function isEnabled($: EngineInterface): Promise<boolean> {
28 return read($, enabledAtom)
29}
30
31async function setEnabled($: EngineInterface, enabled: boolean): Promise<void> {
32 await $.store.set(STORE_KEY, enabled)
33 await update($, enabledAtom, () => enabled)
34 $.ui.status(enabled ? 'auto-allow: ON' : undefined)
35}
36
37export const register: Register = on => {
38 on('session.start', async ($, e, next) => {
39 await $.command.register({
40 name: 'auto-allow',
41 description: 'Toggle auto-approving all permissions (on | off | status | show)',
42 })
43 await setEnabled($, ((await $.store.get(STORE_KEY)) ?? false) === true)
44 void $.ui.open({ id: PANE, title: 'auto-allow' })
45 $.clock.every(350, () => update($, frameAtom, f => (f + 1) % 1000))
46
47 return next(e)
48 })
49
50 on('command.run', { command: 'auto-allow' }, async ($, e) => {
51 const arg = e.args.trim().toLowerCase()
52 const current = await isEnabled($)
53
54 if (arg === 'status') {
55 return { text: `auto-allow is ${current ? 'ON' : 'OFF'}.` }
56 }
57 if (arg === 'show') {
58 await $.ui.open({ id: PANE, title: 'auto-allow' })
59 return { text: 'auto-allow pane opened.' }
60 }
61
62 const enabled = arg === 'on' ? true : arg === 'off' ? false : !current
63 await setEnabled($, enabled)
64
65 return {
66 text: enabled
67 ? 'auto-allow ON: every tool call and permission prompt is approved automatically.'
68 : 'auto-allow OFF: normal permission prompts are back.',
69 }
70 })
71
72 // Approve before the permission check runs, so no prompt is raised.
73 on('classic.PreToolUse', async ($, e, next) =>
74 (await isEnabled($)) ? { allow: true } : next(e),
75 ).catch(($, e, next) => next(e))
76
77 // Answer any permission dialog that still comes up.
78 on('classic.PermissionRequest', async ($, e, next) =>
79 (await isEnabled($)) ? { decision: { behavior: 'allow' } } : next(e),
80 ).catch(($, e, next) => next(e))
81
82 on('ui.render', { component: 'Pane', requestId: PANE }, async ($, e) => {
83 const { Box, Text } = $.ui.resolve(e)
84 const enabled = await read($, enabledAtom)
85 const frame = await read($, frameAtom)
86 const frames = enabled ? PLAY : SLEEP
87 const [ball, dog] = frames[Math.floor(frame / (enabled ? 1 : 3)) % frames.length] ?? ['', '']
88
89 return (
90 <Box flexDirection="column">
91 <Text bold>{enabled ? 'auto-allow: ON' : 'auto-allow: OFF'}</Text>
92 <Text>{ball}</Text>
93 <Text>{dog}</Text>
94 <Text dimColor>
95 {enabled ? 'approving everything' : 'prompts are back'}
96 </Text>
97 <Text dimColor>/auto-allow to toggle</Text>
98 </Box>
99 )
100 })
101}
102types/index.d.ts 8 lines1export type AutoAllowEnabled = boolean
2
3declare module 'claude-code' {
4 interface PluginState {
5 'auto-allow': { enabled: AutoAllowEnabled; frame: number }
6 }
7}
8