Claude Code 自動化部署指南:PreToolUse Hook 權限自動裁決 + 夜間 Autopilot

← 首頁
0

這份解決什麼

痛點:本機 Mac 的 Claude Code 常卡在權限提示動不了。 每次 Bash、Edit、Write 都跳確認,互動式作業還能接受,夜間無人值守根本行不通。

這份指南提供兩層解法:

層次技術效果
A. 即時防護層PreToolUse Hook白名單自動放行、黑名單直接擋、中間地帶請求確認 — 不卡又不失控
B. 夜間自動化層claude -p + launchd人睡覺時跑任務佇列,worktree 隔離,用量監控,跑完通知

A 解決「互動時常被打斷」;B 解決「要睡覺但任務還沒跑」。兩者可以組合:Autopilot 跑的 session 同樣受 Hook 約束,雙重保護。

A

PreToolUse Hook — 權限自動裁決

PreToolUse hook 在每個工具呼叫之前執行腳本,腳本讀取 stdin JSON、輸出決定 JSON,告訴 Claude Code 要 allow / deny / ask / defer。

A1. settings.json 設定結構與欄位說明

Hook 設定寫在 settings.json,有兩個位置:

層級路徑作用範圍
Project-level.claude/settings.json(專案根目錄下)只對此專案生效
User-level~/.claude/settings.json全機器所有 session 生效
JSON — 完整 settings.json 範例(可複製)
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/bash-permission-gate.sh"
          }
        ]
      },
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/edit-protect-critical.sh"
          }
        ]
      }
    ]
  }
}
欄位說明範例
matcher要攔截的工具名,支援正規表達式(| 分隔多個)"Bash""Edit|Write""mcp__.*"
typeHook 類型,目前只有 command"command"
if(可選)執行條件,用權限規則語法"Bash(rm *)"
command腳本路徑(可用 ${CLAUDE_PROJECT_DIR} 變數)"/path/to/gate.sh"
args(可選)傳給腳本的參數陣列[]["--strict"]

A2. stdin 輸入 JSON 格式

Hook 觸發時,Claude Code 透過 stdin 傳 JSON 給腳本:

JSON — stdin 輸入範例(Bash 工具)
{
  "session_id": "abc123xyz",
  "transcript_path": "/path/to/transcript.jsonl",
  "cwd": "/home/user/project",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "rm -rf /tmp/build"
  }
}
欄位型別說明
tool_namestringBashEditWriteRead
tool_inputobject工具輸入。Bash → command;Edit/Write → file_pathcontent
cwdstring當前工作目錄絕對路徑
permission_modestring當前 session 的權限模式
session_idstring唯一 session 識別碼

A3. 輸出:permissionDecision + exit code

腳本把 JSON 輸出到 stdout,用正確的 exit code 結束:

JSON — stdout 輸出結構
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Destructive rm -rf blocked by safety policy",
    "additionalContext": "Optional context for Claude"
  }
}
permissionDecision效果使用場景
"allow" 放行跳過權限對話,直接執行安全操作白名單
"deny" 阻擋阻止工具執行,顯示 reason危險操作黑名單
"ask" 詢問彈出確認對話給使用者中間地帶人工核准
"defer" 交出使用預設流程(等同 exit 0 無輸出)Hook 無法判斷時
Exit Code行為
0成功 — 解析 JSON 輸出的 permissionDecision
2阻擋錯誤 — 直接阻止工具執行;stderr 作為原因顯示
其他非零非阻擋錯誤 — 工具繼續執行,JSON 不被解析

A4. 三個可直接複製的範例腳本

範例 1:Bash 安全閘門(推薦入門,白名單/黑名單/詢問三段式)

bash — .claude/hooks/bash-permission-gate.sh
#!/bin/bash
# .claude/hooks/bash-permission-gate.sh
# 三段式:黑名單 deny → 白名單 allow → 其餘 ask

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('command',''))" 2>/dev/null)

# ── 黑名單:直接拒絕 ──
DENY_PATTERNS=(
  "rm -rf"
  "git push origin main"
  "git push.*--force"
  "dd if="
  "chmod 777"
  "curl.*|.*sh"
)

for pattern in "${DENY_PATTERNS[@]}"; do
  if [[ $COMMAND =~ $pattern ]]; then
    python3 -c "
import json
print(json.dumps({
  'hookSpecificOutput': {
    'hookEventName': 'PreToolUse',
    'permissionDecision': 'deny',
    'permissionDecisionReason': 'Dangerous pattern blocked: $pattern'
  }
}))"
    exit 0
  fi
done

# ── 白名單:直接放行 ──
ALLOW_PATTERNS=(
  "^git (status|log|diff|branch|fetch|pull)"
  "^ls( |$)"
  "^cat "
  "^grep "
  "^echo "
  "^pwd$"
  "^npm test"
  "^npm run build"
  "^python3? -m pytest"
  "^find "
  "^wc "
)

for pattern in "${ALLOW_PATTERNS[@]}"; do
  if [[ $COMMAND =~ $pattern ]]; then
    python3 -c "
import json
print(json.dumps({
  'hookSpecificOutput': {
    'hookEventName': 'PreToolUse',
    'permissionDecision': 'allow',
    'permissionDecisionReason': 'Safe pattern'
  }
}))"
    exit 0
  fi
done

# ── 預設:請求確認 ──
python3 -c "
import json
print(json.dumps({
  'hookSpecificOutput': {
    'hookEventName': 'PreToolUse',
    'permissionDecision': 'ask',
    'permissionDecisionReason': 'Manual approval required'
  }
}))"
exit 0

範例 2:Edit/Write 保護關鍵檔案

bash — .claude/hooks/edit-protect-critical.sh
#!/bin/bash
# .claude/hooks/edit-protect-critical.sh
# 禁止修改 .env、secrets、credentials、私鑰等敏感檔案

INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))" 2>/dev/null)

DENY_PATTERNS=(
  "\.env$"
  "\.env\."
  "secrets"
  "credentials"
  "\.git/config"
  "private_key"
  "prod[-_]config"
  "\.pem$"
  "\.key$"
)

for pattern in "${DENY_PATTERNS[@]}"; do
  if [[ $FILE_PATH =~ $pattern ]]; then
    python3 -c "
import json
print(json.dumps({
  'hookSpecificOutput': {
    'hookEventName': 'PreToolUse',
    'permissionDecision': 'deny',
    'permissionDecisionReason': 'Protected file: $FILE_PATH'
  }
}))"
    exit 0
  fi
done

# 其他檔案交給預設流程
python3 -c "
import json
print(json.dumps({
  'hookSpecificOutput': {
    'hookEventName': 'PreToolUse',
    'permissionDecision': 'defer'
  }
}))"
exit 0

範例 3:Python 版完整閘門(邏輯更清晰,推薦進階使用)

python3 — .claude/hooks/permission_gate.py
#!/usr/bin/env python3
# .claude/hooks/permission_gate.py
import json, sys, re

try:
    data = json.load(sys.stdin)
except json.JSONDecodeError:
    sys.exit(0)

tool_name  = data.get('tool_name', '')
tool_input = data.get('tool_input', {})
command    = tool_input.get('command', '')
file_path  = tool_input.get('file_path', '')

def respond(decision, reason=""):
    print(json.dumps({
        "hookSpecificOutput": {
            "hookEventName": "PreToolUse",
            "permissionDecision": decision,
            "permissionDecisionReason": reason
        }
    }))
    sys.exit(0)

# ── Bash 工具 ──
if tool_name == "Bash":
    DANGEROUS = [
        r'rm\s+-rf',
        r'git\s+push\s+origin\s+main',
        r'git\s+push.*--force',
        r'dd\s+if=',
        r'chmod\s+777',
        r'curl\s+.*\|\s*(ba)?sh',
    ]
    SAFE = [
        r'^git\s+(status|log|diff|branch|fetch|pull)',
        r'^ls(\s|$)',
        r'^cat\s',
        r'^grep\s',
        r'^echo\s',
        r'^pwd$',
        r'^npm\s+test',
        r'^npm\s+run\s+build',
        r'^python3?\s+-m\s+pytest',
        r'^find\s',
        r'^wc\s',
    ]
    for p in DANGEROUS:
        if re.search(p, command):
            respond("deny", f"Dangerous pattern: {p}")
    for p in SAFE:
        if re.match(p, command):
            respond("allow", "Safe command")
    respond("ask", f"Needs approval: {command[:100]}")

# ── Edit / Write 工具 ──
elif tool_name in ("Edit", "Write"):
    PROTECTED = [
        r'\.env(\.|$)', r'secrets', r'credentials',
        r'private_key', r'\.git/config', r'\.(pem|key)$'
    ]
    for p in PROTECTED:
        if re.search(p, file_path):
            respond("deny", f"Protected file: {file_path}")
    respond("defer")

# ── 其他工具:不干預 ──
else:
    respond("defer")

A5. 測試與啟用

Step 1:建立腳本並賦予執行權限

bash
mkdir -p .claude/hooks

# bash 版
chmod +x .claude/hooks/bash-permission-gate.sh
chmod +x .claude/hooks/edit-protect-critical.sh

# python 版
chmod +x .claude/hooks/permission_gate.py

Step 2:直接測試腳本輸出(不用開 Claude)

bash — 測試黑名單(應回傳 deny)
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /tmp/test"}}' \
  | .claude/hooks/bash-permission-gate.sh
# 預期輸出:{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny",...}}
bash — 測試白名單(應回傳 allow)
echo '{"tool_name":"Bash","tool_input":{"command":"git status"}}' \
  | .claude/hooks/bash-permission-gate.sh
# 預期輸出:{"hookSpecificOutput":{"permissionDecision":"allow",...}}
bash — Python 版測試
echo '{"tool_name":"Edit","tool_input":{"file_path":"/home/user/.env"}}' \
  | python3 .claude/hooks/permission_gate.py
# 預期輸出:{"hookSpecificOutput":{"permissionDecision":"deny",...}}

Step 3:設定 settings.json,然後重啟 session

把上面的 settings.json 內容存入 .claude/settings.json(project-level)或 ~/.claude/settings.json(user-level),然後用 /exit 重啟 Claude Code。

!

重點提醒:改 settings.json 必須重啟 Session

⚠ WT 已知雷點 — 改了但 Hook 不生效 = 沒重啟
  • 修改 .claude/settings.json~/.claude/settings.json 的 hooks 設定後,必須完全退出 Claude Code(用 /exit 或關閉終端機視窗)再重新開啟,新設定才會載入生效。
  • Hook 腳本本身修改後(不改 settings.json)也建議重啟確保生效。
  • ~/.claude/settings.json(user-level)的修改影響所有新開的 session,但現有 session 不會自動套用。

判斷 Hook 是否生效(兩段,都不必下危險指令):

不要拿 rm -rfgit push 這類指令當測試樣本。雖然 rm -rf /nonexistent 打到不存在的路徑其實不會造成傷害,但用「危險指令」測「擋危險的機制」會養成壞習慣 — 哪天 /nonexistent 手滑打成真路徑就出事了。測試樣本要選「就算洩漏也零傷害」的哨兵字串。

B

夜間 Autopilot — 無人值守自動 Loop

核心技術:claude -p headless 模式。不開互動 UI,直接下指令、跑完輸出結果、退出。配合 launchd 排程就成了夜間自動 loop。

B1. claude -p Headless 基礎用法

bash — 基本語法
# 最簡形式
claude -p "找出 auth.py 的 bug 並修復"

# 預核准特定工具
claude -p "跑測試並修復失敗的 case" \
  --allowedTools "Bash,Read,Edit"

# 搭配權限模式
claude -p "套用 lint 自動修正" \
  --permission-mode acceptEdits

# 輸出 JSON(含 total_cost_usd)
claude -p "分析程式碼品質" \
  --output-format json
Flag說明範例值
--allowedTools預核准的工具清單(逗號分隔),支援 glob 限制指令範圍"Read,Edit,Bash""Bash(git *)"
--permission-mode全域權限模式(見 B2)"acceptEdits""bypassPermissions"
--output-format輸出格式"text"(預設)、"json""stream-json"
--bare精簡模式:不載入 hooks/MCP/skills,節省 token 和啟動時間(無值)
--append-system-prompt附加系統提示詞,限縮行為"不要執行任何刪除操作"
--continue繼續最新 session(無值)
--resume恢復指定 session ID"session-id-here"

B2. 權限模式(--permission-mode)

模式行為Autopilot 建議用途
"default"首次使用時提示確認互動式(Headless 會失敗)
"acceptEdits"自動接受檔案編輯和常見 fs 操作(mkdir/mv/cp…)推薦:日常 Autopilot
"plan"唯讀探索:讀檔 + 唯讀 shell,不寫入分析、診斷、只產報告
"dontAsk"自動拒絕未在 allowedTools 的工具嚴格 CI(只允許白名單)
"bypassPermissions"跳過所有權限提示(除 rm -rf / 和 rm -rf ~)隔離 worktree / 容器專用
"auto" research preview後台安全檢查,自動核准符合請求的操作生產前評估穩定性
關於 --dangerously-skip-permissions 這個 flag

網路上偶有提到 --dangerously-skip-permissions(也是某些文件或舊版本的寫法)。現行官方建議使用 --permission-mode bypassPermissions。這兩者效果等同 — 跳過所有提示,只在完全隔離的環境使用。請以你實際執行 claude --help 顯示的輸出為準(以實際版本為準)。

bash — 三種組合範例
# 組合 1:日常任務(改 bug、格式化、跑測試)
claude -p "修復失敗的測試" \
  --bare \
  --allowedTools "Bash,Read,Edit" \
  --permission-mode acceptEdits

# 組合 2:嚴格 CI(只跑測試,禁止寫入)
claude -p "執行測試並回報結果" \
  --bare \
  --permission-mode dontAsk \
  --allowedTools "Bash(npm test),Read"

# 組合 3:唯讀分析(只讀不改)
claude -p "分析程式碼品質並回傳 JSON 報告" \
  --bare \
  --permission-mode plan \
  --output-format json

B3. Headless 碰到未授權工具的行為

核心原則:Headless 不能交互,任何卡關 = 任務失敗
場景行為結果
未設 --allowedTools,命令需要確認提示被轉換為 exit 1任務失敗
設了 --allowedTools,命令符合自動執行(無提示)繼續執行
設了 --allowedTools,命令不符合拒絕執行,exit 1任務失敗
--permission-mode dontAsk自動拒絕未在 allow rules 的工具任務失敗(除非明確允許)

結論:設定 Autopilot 任務前,先在互動模式跑一遍確認用到哪些工具,再把它們全列進 --allowedTools

B4. 用量監控

--output-format json 的輸出包含 total_cost_usd 欄位,可用來追蹤每次任務成本:

bash — 抓單次任務成本
RESULT=$(claude -p "修復 bug" \
  --allowedTools "Bash,Read,Edit" \
  --permission-mode acceptEdits \
  --output-format json 2>&1)

COST=$(echo "$RESULT" | python3 -c "
import sys, json
try:
    d = json.load(sys.stdin)
    print(d.get('total_cost_usd', 'N/A'))
except:
    print('N/A')
")
echo "任務成本:\$$COST USD"
bash — 每日預算監控腳本
#!/bin/bash
# check-budget.sh — 在派新任務前呼叫
DAILY_BUDGET=5  # USD

# 用 ccusage 查今日用量
TODAY_COST=$(ccusage --today 2>/dev/null | grep -oP 'USD \K[\d.]+' | tail -1 || echo "0")

python3 -c "
cost = float('$TODAY_COST')
budget = $DAILY_BUDGET
if cost >= budget:
    print(f'BUDGET_EXCEEDED: {cost:.2f} / {budget} USD')
    exit(1)
else:
    print(f'OK: {cost:.2f} / {budget} USD')
    exit(0)
"
省錢策略效果
--bare不載入 MCP/hooks/skills,減少 token
任務拆小單次 prompt 越短越省
先 plan 後 acceptEdits先唯讀分析確認方向,再給寫入權限
設每日預算上限達上限停派任務

B5. Git Worktree 隔離

多 agent 並行時,每個任務開獨立 worktree,避免互相踩檔案、衝突。

bash — 完整 worktree 工作流程
#!/bin/bash
# run-in-worktree.sh "任務描述"
TASK="$1"
REPO_DIR="/path/to/main/repo"
TASK_ID="cc-$(date +%s)"
WORKTREE_DIR="/tmp/cc-worktrees/$TASK_ID"

mkdir -p /tmp/cc-worktrees

# 1. 建立隔離 worktree(基於 main)
cd "$REPO_DIR"
git worktree add "$WORKTREE_DIR" main

# 2. 在隔離環境執行 Claude
cd "$WORKTREE_DIR"
claude -p "$TASK" \
  --bare \
  --allowedTools "Bash,Read,Edit" \
  --permission-mode acceptEdits \
  --output-format json > /tmp/${TASK_ID}-result.json 2>&1
STATUS=$?

# 3. 查看變更(人工確認再 merge)
git diff --stat

# 4. 清理
cd "$REPO_DIR"
git worktree remove "$WORKTREE_DIR" --force

exit $STATUS

B6. Mac Launchd 排程

Mac 上比 cron 更可靠的排程方式,支援睡眠補跑、環境變數注入:

xml — ~/Library/LaunchAgents/com.wt.claude-autopilot.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.wt.claude-autopilot</string>

    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>/Users/wt/scripts/autopilot-runner.sh</string>
    </array>

    <!-- 每小時執行一次 -->
    <key>StartInterval</key>
    <integer>3600</integer>

    <!-- 或改成每天凌晨 2 點(注釋掉 StartInterval,改用這個):
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key><integer>2</integer>
        <key>Minute</key><integer>0</integer>
    </dict>
    -->

    <key>StandardOutPath</key>
    <string>/tmp/claude-autopilot.log</string>

    <key>StandardErrorPath</key>
    <string>/tmp/claude-autopilot-error.log</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>
        <!-- ANTHROPIC_API_KEY 建議用 Keychain 存,不要明文寫這裡 -->
    </dict>

    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>
bash — Launchd 管理指令
# 載入(啟用排程)
launchctl load ~/Library/LaunchAgents/com.wt.claude-autopilot.plist

# 查狀態
launchctl list | grep claude-autopilot

# 手動觸發一次(測試)
launchctl start com.wt.claude-autopilot

# 停用
launchctl unload ~/Library/LaunchAgents/com.wt.claude-autopilot.plist

# 看日誌
tail -f /tmp/claude-autopilot.log

完整 Runner 腳本(含任務佇列、lock 防並行、通知)

bash — /Users/wt/scripts/autopilot-runner.sh
#!/bin/bash
# autopilot-runner.sh — 消化任務佇列,跑完通知
set -e

REPO_DIR="/path/to/repo"
TASK_QUEUE="$HOME/ralph-loop/task_queue.md"
DAILY_BUDGET=5  # USD

echo "=== Autopilot Run $(date) ==="

# 防止並行
LOCK="/tmp/claude-autopilot.lock"
[ -f "$LOCK" ] && { echo "已有任務在跑"; exit 0; }
touch "$LOCK"
trap "rm -f $LOCK" EXIT

# 預算檢查(用 ccusage,視你的安裝方式調整)
# TODAY_COST=$(ccusage ... ) — 視實際輸出格式調整

# 從 task_queue.md 撈第一個 pending 任務
# 格式:- [ ] 任務描述
TASK=$(grep -m1 '^\- \[ \]' "$TASK_QUEUE" 2>/dev/null \
       | sed 's/^\- \[ \] //' \
       | sed 's/ |.*//' \
       || echo "")

[ -z "$TASK" ] && { echo "沒有 pending 任務"; exit 0; }
echo "執行:$TASK"

# 建立隔離 worktree
WORKTREE="/tmp/cc-wt-$(date +%s)"
cd "$REPO_DIR"
git worktree add "$WORKTREE" main
cd "$WORKTREE"

# 跑任務
claude -p "$TASK" \
  --bare \
  --allowedTools "Bash,Read,Edit" \
  --permission-mode acceptEdits \
  --output-format json > /tmp/cc-latest-result.json 2>&1
CC_STATUS=$?

# 清理 worktree
cd "$REPO_DIR"
git worktree remove "$WORKTREE" --force

# 更新任務狀態
if [ $CC_STATUS -eq 0 ]; then
  STATUS_MSG="DONE"
  # 把第一個 - [ ] 改成 - [x]
  sed -i '' '0,/^\- \[ \]/s/^\- \[ \]/- [x]/' "$TASK_QUEUE"
else
  STATUS_MSG="FAILED (exit $CC_STATUS)"
fi

echo "結果:$STATUS_MSG"

# macOS 通知中心
osascript -e "display notification \"$STATUS_MSG\" with title \"Claude Autopilot\" subtitle \"$TASK\""
4

接 WT 現有架構

雲端 Hetzner 上的 Ralph Loop 已有骨架,本機只差這三塊:

雲端已有(ralph-loop)本機 Mac 要補的
patrol.sh(每 30 分鐘 cron 巡檢)Launchd plist(取代 cron,Mac 原生)
task_queue.md(任務佇列)Runner 腳本讀 ~/ralph-loop/task_queue.md(同一份或 rsync 同步)
checkpoint.md(斷點恢復)Runner 在每個任務前寫 checkpoint,用 --continue 接續
watchdog(systemd 兩層)Launchd 本身即有 KeepAlive / RunAtLoad 機制
Discord 進度回報Runner 腳本結束後呼叫 DC Webhook(或本機 MCP)

最快接法: 本機 ~/ralph-loop/task_queue.md 直接手寫,或透過 DC 說「加到本機佇列:XXX」讓雲端 Claude 寫入(若 task_queue 有 rsync 同步),Runner 每小時自動撈來跑。

本機要補的三個核心模組:

  1. 自動派 agent 消化佇列 — Runner 腳本 + Launchd(上面已提供)
  2. 用量監控 — ccusage + 每日預算上限腳本
  3. Worktree 隔離 — 每次任務 = 一個 worktree,防止互相踩
5

安全鐵律

全自動模式的安全邊界(不可妥協)
  • bypassPermissions 只在隔離環境跑: worktree 或 Docker 容器,且不含正式 API 金鑰,不能直接 push 到 main。
  • PR / 輸出階段人工把關: Autopilot 產出的 diff,人眼看完再決定是否 merge,不讓 AI 自動 push + 部署。
  • Hook 是最後一道防線: 設好 bash-permission-gate.sh 的黑名單後,就算 Autopilot 拿到 bypassPermissions,rm -rf 等危險操作仍然被 Hook 擋住。
  • 用量監控每次任務前先查: 防止 loop 失控燒完當月額度。
  • lock file 防並行: Runner 腳本一定要用 lock file,避免兩個 launchd 執行重疊踩檔案。

最小可行安全啟動流程

bash — 快速 checklist
# 1. 設定 Hook(A節),測試黑名單是否回傳 deny
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' \
  | .claude/hooks/bash-permission-gate.sh

# 2. 設定 settings.json → 重啟 session → 確認 Hook 生效

# 3. 用 --bare + acceptEdits 測試 headless
claude -p "列出 src/ 目錄的檔案" \
  --bare --allowedTools "Bash(ls *)" --permission-mode acceptEdits

# 4. 設定 launchd plist(B6節)
launchctl load ~/Library/LaunchAgents/com.wt.claude-autopilot.plist

# 5. 手動觸發一次,確認通知有收到
launchctl start com.wt.claude-autopilot
tail -f /tmp/claude-autopilot.log
資料來源 / 免責聲明

本頁內容整理自 Claude Code 官方文件、實際測試與查證(2026-06-01)。CLI flag 名稱、JSON 格式、行為細節可能隨版本更動,請以實際 claude --help 輸出和最新官方文件為準。

母本:/tmp/cc_autopilot/findings.md(838 行)| 產出:2026-06-01