全部產品
Search
文件中心

AI Coding Assistant Lingma:鉤子

更新時間:May 20, 2026

Hooks 允許在 Qoder CN CLI 的關鍵節點接入 Agent 的主執行流,同時與 CLI 保持解耦。常見用途包括:工具執行前攔截危險操作、任務完成後發送案頭通知、寫檔案後自動跑 lint 等。

Hooks 通過 JSON 設定檔定義,不需要修改代碼,編輯設定檔即可生效。

快速開始

以下樣本示範如何用 Hook 攔截危險命令——當 Agent 嘗試執行 rm -rf 時自動阻止。

第一步:建立指令碼

mkdir -p ~/.qodercn/hooks

cat > ~/.qodercn/hooks/block-rm.sh << 'EOF'
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command')
if echo "$command" | grep -q 'rm -rf'; then
  echo "危險命令已被阻止: $command" >&2
  exit 2
fi
exit 0
EOF

chmod +x ~/.qodercn/hooks/block-rm.sh

第二步:編輯設定檔

~/.qodercn/settings.json 中添加:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.qodercn/hooks/block-rm.sh"
          }
        ]
      }
    ]
  }
}

第三步:驗證效果

啟動 Qoder CN CLI,讓 Agent 執行包含 rm -rf 的命令,Hook 會阻止執行並提示 Agent。

配置

設定檔位置

Hook 配置從以下三個檔案載入,三級配置會被合并執行:

~/.qodercn/settings.json                    # 使用者級,對所有專案生效
${project}/.qodercn/settings.json           # 專案級,對當前專案生效,可提交 git 共用給團隊
${project}/.qodercn/settings.local.json     # 專案級(本地),優先順序最高,建議加到 .gitignore

配置格式

{
  "hooks": {
    "事件名": [
      {
        "matcher": "匹配條件",
        "hooks": [
          {
            "type": "command",
            "command": "要執行的命令",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

欄位說明:

欄位

必填

說明

type

固定為 "command"

command

要執行的 shell 命令

timeout

逾時時間(秒),預設 60

matcher

匹配條件,不填則匹配所有

一個事件下可以配置多個 matcher 分組,每個分組可以包含多個 hook 命令。

matcher 匹配規則

matcher 用於過濾 hook 的觸發範圍,不同事件匹配不同的欄位(見各事件說明)。

寫法

含義

樣本

不填或 "*"

匹配所有

所有工具都觸發

精確值

精確匹配

"Bash" 只匹配 Bash 工具

| 分隔

匹配多個值

"Write|Edit" 匹配 Write 或 Edit

Regex

正則匹配

"mcp__.*" 匹配所有 MCP 工具

Hook 指令碼編寫

Hook 指令碼通過 stdin 接收 JSON 輸入,通過 exit code 和 stdout 輸出來控制行為。本節說明所有事件通用的輸入輸出格式,各事件的額外欄位見"支援的事件"。

輸入

Hook 指令碼通過 stdin 接收 JSON 資料。所有事件都包含以下通用欄位:

欄位

說明

session_id

當前會話 ID

cwd

當前工作目錄

hook_event_name

觸發的事件名稱

不同事件會在此基礎上附加額外欄位(見各事件說明)。用 jq 解析輸入:

#!/bin/bash
input=$(cat)
tool_name=$(echo "$input" | jq -r '.tool_name')

輸出

Hook 通過 exit code 和 stdout 控制行為。exit code 決定基本行為:0 成功,2 阻塞(stderr 內容注入對話,僅對支援阻塞的事件生效),其他值為非阻塞錯誤。stdout JSON(僅 exit 0 時解析)可為部分事件提供精細控制,具體支援的欄位見各事件說明。exit 非 0 時 stdout 被忽略。

環境變數

Hook 指令碼執行時可以使用以下環境變數:

變數

說明

QODERCN_PROJECT_DIR

當前專案的工作目錄

支援的事件

Qoder CN CLI 支援以下 Hook 事件,覆蓋會話生命週期的各個階段。

SessionStart

會話開始時觸發。

matcher 匹配: 會話來源

matcher 值

觸發情境

startup

新會話啟動

resume

恢複已有會話

compact

上下文壓縮完成後

額外輸入欄位:

{
  "source": "startup",
  "model": "Auto"
}

SessionEnd

會話結束時觸發。

matcher 匹配: 結束原因

matcher 值

觸發情境

prompt_input_exit

使用者退出輸入(Ctrl+D 等)

other

其他原因

額外輸入欄位:

{
  "reason": "prompt_input_exit"
}

UserPromptSubmit

使用者提交 Prompt 後、Agent 處理前觸發。

額外輸入欄位:

{
  "prompt": "幫我寫一個排序函數"
}

PreToolUse

工具執行前觸發。可以阻止工具執行。

matcher 匹配: 工具名(如 BashWriteEditReadGlobGrep,MCP 工具名如 mcp__server__tool

額外輸入欄位:

{
  "tool_name": "Bash",
  "tool_input": {"command": "rm -rf /tmp/build"},
  "tool_use_id": "toolu_01ABC123"
}

阻止工具執行: exit code 2,stderr 內容作為錯誤返回給 Agent。完整樣本見"快速開始"。

PostToolUse

工具執行成功後觸發。

matcher 匹配: 工具名

額外輸入欄位:

{
  "tool_name": "Write",
  "tool_input": {"file_path": "/path/to/file.ts", "content": "..."},
  "tool_response": "File written successfully",
  "tool_use_id": "toolu_01ABC123"
}

PostToolUseFailure

工具執行失敗後觸發。

matcher 匹配: 工具名

額外輸入欄位:

{
  "tool_name": "Bash",
  "tool_input": {"command": "npm test"},
  "tool_use_id": "toolu_01ABC123",
  "error": "Command exited with non-zero status code 1",
  "is_interrupt": false
}

Stop

Agent 完成響應後觸發(主 Agent,無待執行的工具調用時)。可以阻止 Agent 停止,讓其繼續工作。

阻止 Agent 停止: exit code 2,stderr 內容作為訊息注入對話,Agent 繼續工作。

SubagentStart / SubagentStop

子 Agent 啟動和完成時觸發。SubagentStop 與 Stop 類似,可以阻止子 Agent 停止。

matcher 匹配: Agent 類型名

額外輸入欄位:

{
  "agent_id": "a1b2c3d4",
  "agent_type": "task"
}

PreCompact

上下文壓縮前觸發。

matcher 匹配: 觸發方式

matcher 值

觸發情境

manual

使用者手動執行 /compact

auto

上下文視窗滿時自動觸發

額外輸入欄位:

{
  "trigger": "manual",
  "custom_instructions": "保留所有工具調用結果"
}

Notification

通知事件觸發(許可權請求、任務完成等)。

matcher 匹配: 通知類型

matcher 值

觸發情境

permission

許可權請求通知

result

Agent 產出結果通知

額外輸入欄位:

{
  "message": "Agent is requesting permission to run: rm -rf node_modules",
  "title": "Permission Required",
  "notification_type": "permission"
}

PermissionRequest

工具執行需要使用者授權時觸發。

matcher 匹配: 工具名

額外輸入欄位:

{
  "tool_name": "Bash",
  "tool_input": {"command": "rm -rf node_modules"}
}

實用情境

案頭通知提醒

當 Agent 完成任務或需要授權時,彈出案頭通知。指令碼 ~/.qodercn/hooks/notify.sh(macOS):

#!/bin/bash
input=$(cat)
message=$(echo "$input" | jq -r '.message')
if echo "$message" | grep -q "^Agent"; then
  osascript -e 'display notification "任務執行完成" with title "Qoder CN CLI"'
else
  osascript -e 'display notification "任務需要授權" with title "Qoder CN CLI"'
fi
exit 0

配置:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.qodercn/hooks/notify.sh"
          }
        ]
      }
    ]
  }
}

寫檔案後自動 Lint

每次 Agent 寫入或編輯檔案後,自動執行 lint 檢查。指令碼 ${project}/.qodercn/hooks/auto-lint.sh

#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')

# 只檢查 JS/TS 檔案
case "$file_path" in
  *.js|*.ts|*.jsx|*.tsx)
    npx eslint "$file_path" --fix 2>/dev/null
    ;;
esac
exit 0

配置:事件 PostToolUse,matcher Write|Edit,command .qodercn/hooks/auto-lint.sh

讓 Agent 繼續工作

在 Agent 停止時檢查是否還有未完成的任務,如果有則注入訊息讓 Agent 繼續。指令碼 ~/.qodercn/hooks/check-continue.sh

#!/bin/bash
# 檢查是否有未提交的 git 變更
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
  echo "檢測到未提交的變更,請完成 git commit" >&2
  exit 2
fi
exit 0

配置:事件 Stop,command ~/.qodercn/hooks/check-continue.sh