Skip to content

Commit 2669f30

Browse files
committed
docs(claude-code): add unattended-mode example for template admins
The most common template-admin use case is 'make Claude just work for an agent or headless workspace without human interaction.' The existing README shows envs, MCP, and a one-liner pre_install_script, but never walks through how to skip the first-run wizard and the bypass-mode consent banner. Add a dedicated section documenting: - settings.json with permissions.defaultMode = bypassPermissions, permissions.deny allowlist, and skipDangerousModePermissionPrompt (verified live against Claude Code CLI v2.1.117 on a workspace). - ~/.claude.json hasCompletedOnboarding merged via jq so installer keys (userID, firstStartTime, installMethod, autoUpdates, migrationVersion) are preserved. - A runtime-flag alternative for one-off 'claude -p' runs. Verified the complete example end-to-end on dev.coder.com: fresh workspace lands with the expected settings.json keys, onboarding skipped, and installer-managed state intact.
1 parent 615d41a commit 2669f30

1 file changed

Lines changed: 65 additions & 0 deletions

File tree

registry/coder/modules/claude-code/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,71 @@ module "claude-code" {
225225
}
226226
```
227227

228+
## Unattended mode (skip setup wizard and permission prompts)
229+
230+
For template-admin setups where Claude Code should just work — CI agents, headless workspaces, AI coding agents that do not have a human to click through the first-run wizard or confirm bypass-permissions mode — pre-write `settings.json` and `~/.claude.json` via `pre_install_script`.
231+
232+
```tf
233+
module "claude-code" {
234+
source = "registry.coder.com/coder/claude-code/coder"
235+
version = "5.0.0"
236+
agent_id = coder_agent.main.id
237+
238+
env = {
239+
ANTHROPIC_API_KEY = var.anthropic_api_key
240+
}
241+
242+
pre_install_script = <<-EOT
243+
#!/bin/bash
244+
set -euo pipefail
245+
246+
# Settings: default to bypassPermissions so tool calls do not prompt,
247+
# silence the "dangerous mode" consent banner, and keep a deny list for
248+
# anything the agent must never read.
249+
mkdir -p "$HOME/.claude"
250+
cat > "$HOME/.claude/settings.json" <<'JSON'
251+
{
252+
"permissions": {
253+
"defaultMode": "bypassPermissions",
254+
"deny": ["Read(./.env)", "Read(./secrets/**)", "Read(**/*.pem)"]
255+
},
256+
"skipDangerousModePermissionPrompt": true
257+
}
258+
JSON
259+
260+
# User config: skip the theme and first-run onboarding flow. The official
261+
# installer creates ~/.claude.json before this pre_install_script runs,
262+
# so merge rather than overwrite to preserve installer-managed keys
263+
# (userID, autoUpdates, migrationVersion, firstStartTime).
264+
if [ -f "$HOME/.claude.json" ]; then
265+
tmp=$(mktemp)
266+
jq '. + {hasCompletedOnboarding: true}' "$HOME/.claude.json" > "$tmp" \
267+
&& mv "$tmp" "$HOME/.claude.json"
268+
else
269+
printf '%s\n' '{"hasCompletedOnboarding": true}' > "$HOME/.claude.json"
270+
fi
271+
EOT
272+
}
273+
```
274+
275+
Keys verified live against Claude Code CLI v2.1.117:
276+
277+
| File | Key | Effect |
278+
| ------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------- |
279+
| `~/.claude/settings.json` | `permissions.defaultMode` | `"bypassPermissions"`, `"acceptEdits"`, `"plan"`, `"auto"`, `"default"`, `"dontAsk"`. |
280+
| `~/.claude/settings.json` | `permissions.allow` / `deny` | Per-tool allowlist / denylist (e.g. `"Bash(git *)"`, `"Read(./secrets/**)"`). |
281+
| `~/.claude/settings.json` | `skipDangerousModePermissionPrompt` | Silences the one-time "enable bypassPermissions mode" consent banner. |
282+
| `~/.claude.json` | `hasCompletedOnboarding` | Skips the first-run theme picker and welcome screens. |
283+
284+
> [!NOTE]
285+
> Pre-writing these files makes sense for automation and agents. Human users who expect the usual onboarding and per-project trust dialog should not use this pattern.
286+
287+
For one-off non-interactive runs, prefer the runtime flag instead of pre-writing config:
288+
289+
```bash
290+
claude -p "$PROMPT" --dangerously-skip-permissions --permission-mode bypassPermissions
291+
```
292+
228293
## Outputs
229294

230295
| Output | Type | Description |

0 commit comments

Comments
 (0)