claude-code-notifier
cách hoạt động hướng dẫn câu hỏi thường gặp
◐Tiếng Việt
English العربية Deutsch Español Français עברית Italiano 日本語 한국어 Nederlands Polski Português (Brasil) Русский Türkçe Tiếng Việt 简体中文 繁體中文
Bắt đầu
Tất cả hướng dẫn

Stop hook của Claude Code: chạy lệnh khi Claude làm xong

Cập nhật ngày 31 tháng 10 năm 2026 · 6 phút đọc
trong trang này 01Khi nào Stop được kích hoạt và khi nào không 02Stop hook đơn giản nhất 03Hook nhận được gì 04Đưa tin nhắn cuối của Claude vào thông báo 05Để Claude tiếp tục làm việc 06Thông báo cả khi gặp lỗi 07Claude Code Notifier nằm ở đâu trong bức tranh này 08Câu hỏi thường gặp

Hook Stop của Claude Code chạy một lệnh mỗi khi agent chính của Claude trả lời xong, nên đây là chỗ phù hợp để gửi thông báo "đã xong", ghi log kết quả hoặc chạy kiểm tra. Hook không chạy khi bạn ngắt Claude, còn lượt kết thúc do lỗi API sẽ kích hoạt StopFailure thay thế. Hook nhận tin nhắn cuối cùng của Claude trong last_assistant_message, và có thể trả về decision: "block" kèm reason để Claude tiếp tục thay vì dừng lại.

01Khi nào Stop được kích hoạt và khi nào không

Stop được kích hoạt ở cuối mỗi lượt, chứ không chỉ khi cả task hoàn tất. Claude Code không có khái niệm "task"; nó chỉ biết Claude đã ngừng trả lời và đang chờ bạn. Một câu hỏi ngắn cho ra một Stop, và một đợt refactor hai tiếng cũng vậy.

Hook không được kích hoạt:

  • khi bạn nhấn Esc hoặc ngắt lượt theo cách khác;
  • khi lượt kết thúc do lỗi API như rate limit, quá tải hoặc lỗi xác thực. Với các trường hợp này, Claude Code kích hoạt StopFailure, kèm trường error mà bạn có thể so khớp (rate_limit, overloaded, server_error và các giá trị khác);
  • khi một subagent làm xong. Trường hợp đó là SubagentStop.

Stop không hỗ trợ matcher, nên mọi matcher bạn thêm vào đều bị bỏ qua và hook chạy ở mọi lượt.

02Stop hook đơn giản nhất

Thêm đoạn này vào ~/.claude/settings.json để chạy một lệnh mỗi khi Claude làm xong. Ví dụ này phát âm thanh trên macOS:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ]
  }
}

Để xem các lệnh thông báo desktop trên Mac, Windows và Linux, hãy xem cách nhận thông báo khi Claude Code làm xong. Phần còn lại của hướng dẫn này nói về những gì bạn có thể làm với input và output của hook.

03Hook nhận được gì

Ngoài các trường chung (session_id, transcript_path, cwd, permission_mode, hook_event_name), hook Stop còn nhận được:

TrườngNội dung
last_assistant_messageNội dung câu trả lời cuối cùng của Claude trong lượt này
stop_hook_activetrue nếu Claude đang tiếp tục vì một Stop hook đã chặn
background_tasksCác task vẫn đang chạy, như shell chạy nền hoặc subagent
session_cronsCác lần đánh thức đã lên lịch trong session này, ví dụ từ /loop

Hãy dùng last_assistant_message thay vì đọc file transcript. Transcript được ghi bất đồng bộ nên có thể chưa chứa tin nhắn cuối khi hook chạy.

background_tasks và session_crons cho bạn biết session đã thực sự xong hay chỉ tạm dừng cho đến khi tác vụ nền đánh thức nó lại. Script thông báo có thể kiểm tra cả hai đều rỗng trước khi báo "đã xong".

04Đưa tin nhắn cuối của Claude vào thông báo

Script này (macOS và Linux, cần jq) hiển thị phần đầu câu trả lời của Claude và im lặng nếu tác vụ nền vẫn đang chạy:

#!/bin/bash
# ~/.claude/hooks/notify-done.sh
input=$(cat)

# Skip if background tasks are still in flight
busy=$(jq '(.background_tasks // []) | length' <<<"$input")
[ "$busy" -gt 0 ] && exit 0

msg=$(jq -r '(.last_assistant_message // "Claude has finished")
             | gsub("\\s+"; " ") | .[0:140]' <<<"$input")

if command -v osascript >/dev/null 2>&1; then
  osascript -e 'on run argv' \
            -e 'display notification (item 1 of argv) with title "Claude has finished"' \
            -e 'end run' "$msg"
elif command -v notify-send >/dev/null 2>&1; then
  notify-send "Claude has finished" "$msg"
fi
exit 0

Lưu lại, chạy chmod +x ~/.claude/hooks/notify-done.sh, rồi trỏ hook tới nó:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-done.sh" }]
      }
    ]
  }
}

Script luôn thoát với mã 0. Điều này quan trọng: với Stop, exit code 2 nghĩa là "đừng dừng", nên một script thông báo vô tình thoát với mã 2 sẽ khiến Claude tiếp tục làm việc.

05Để Claude tiếp tục làm việc

Stop là một trong những event có thể chặn. Chặn việc dừng nghĩa là Claude tiếp tục lượt hiện tại, dùng lý do của bạn làm chỉ dẫn tiếp theo. Có hai cách:

  • thoát với mã 2, và Claude nhận stderr của bạn làm lý do; hoặc
  • thoát với mã 0 và in ra JSON:
{
  "decision": "block",
  "reason": "The test suite is failing. Run npm test, fix the failures, then finish."
}

Nếu hook đưa ra hướng dẫn thay vì báo lỗi, hookSpecificOutput.additionalContext cũng giữ cho cuộc hội thoại tiếp tục, nhưng transcript sẽ ghi nhận nó là phản hồi từ Stop hook thay vì lỗi hook:

{
  "hookSpecificOutput": {
    "hookEventName": "Stop",
    "additionalContext": "Please run the test suite before finishing"
  }
}

Tránh vòng lặp vô hạn

Một Stop hook luôn chặn sẽ không bao giờ cho Claude dừng. Có hai cơ chế bảo vệ bạn:

  1. stop_hook_active là true khi Claude đang tiếp tục do một Stop hook. Hãy kiểm tra nó và thoát sớm.
  2. Claude Code vẫn sẽ kết thúc lượt sau khi các Stop hook đã chặn tám lần liên tiếp mà không có tool call nào xen giữa. Biến môi trường CLAUDE_CODE_STOP_HOOK_BLOCK_CAP cho phép nâng giới hạn đó.

Đây là một hook khiến Claude sửa các test bị fail một lần, rồi cho phép nó dừng:

#!/bin/bash
# ~/.claude/hooks/tests-must-pass.sh
input=$(cat)
[ "$(jq -r '.stop_hook_active' <<<"$input")" = "true" ] && exit 0

if ! npm test --silent >/dev/null 2>&1; then
  jq -nc '{decision: "block", reason: "npm test is failing. Fix the failures, then finish."}'
fi
exit 0

Hook chạy trong thư mục làm việc của session, nên npm test sẽ chạy trong project của bạn. Hãy giữ cho các bước kiểm tra thật nhanh: mặc định một command hook có thể chạy tối đa 600 giây, và Claude sẽ chờ nó.

Nếu bạn chỉ muốn Claude tiếp tục làm việc hướng tới một mục tiêu mà không cần viết script, lệnh /goal có sẵn của Claude Code sẽ thiết lập giúp bạn một Stop hook trong phạm vi session.

06Thông báo cả khi gặp lỗi

Vì lỗi API sẽ bỏ qua Stop, thông báo "đã xong" sẽ không cho bạn biết Claude đã dừng do dính rate limit. Nếu muốn được báo trường hợp này, hãy thêm cùng script đó vào StopFailure. Output và exit code của nó bị bỏ qua, nên nó chỉ có thể thông báo hoặc ghi log. Với StopFailure, last_assistant_message chứa nội dung lỗi, ví dụ "API Error: Rate limit reached".

07Claude Code Notifier nằm ở đâu trong bức tranh này

Một Stop hook gọi tới dịch vụ push là cách hoàn toàn ổn để biết Claude đã xong khi bạn không ngồi ở máy. Nếu muốn tự làm, hướng dẫn ntfy là điểm khởi đầu tốt.

Claude Code Notifier dùng cùng Stop hook đó, chỉ khác một điểm: nó có thể gửi phản hồi ngược lại. Công cụ dòng lệnh miễn phí của nó, ccn, chạy trên Mac, Windows và Linux, và tự hiển thị thông báo trên desktop. Khi đã ghép nối app iPhone hoặc Android, bạn sẽ nhận push "Claude đã xong" ngay khi một lượt kết thúc, và có thể gõ chỉ dẫn tiếp theo trên điện thoại. ccn trả nó về từ Stop hook làm chỉ dẫn tiếp theo cho Claude, nên session vẫn tiếp tục dù bạn không ngồi trước bàn phím. Nếu bạn vừa gõ phím trong 30 giây gần nhất, sẽ không có gì chờ điện thoại cả. Đây là sản phẩm độc lập, không phải do Anthropic làm. Xem rời máy khi chạy tác vụ dài để biết quy trình này và trang ccn để cài đặt.

08Câu hỏi thường gặp

Stop hook chạy khi Claude hoàn thành toàn bộ tác vụ, hay sau mỗi câu trả lời?

Sau mỗi câu trả lời. Stop kích hoạt mỗi khi agent chính trả lời xong, bất kể yêu cầu lớn hay nhỏ. Nếu cần biết còn việc nào đang được lên lịch không, hãy kiểm tra background_tasks và session_crons trong input.

Tại sao Stop hook của tôi không chạy?

Có thể bạn đã ngắt lượt đó, vốn sẽ bỏ qua Stop, hoặc lượt kết thúc bằng lỗi API, khi đó StopFailure sẽ chạy thay thế. Nếu không phải vậy, hãy kiểm tra /hooks có liệt kê hook của bạn không và script đã có quyền thực thi chưa. Danh sách kiểm tra khắc phục sự cố sẽ giúp bạn phần còn lại.

Tại sao Claude vẫn tiếp tục làm việc sau khi Stop hook chạy?

Hook của bạn đang chặn việc dừng, bằng cách thoát với code 2 hoặc in ra decision: "block". Hãy đảm bảo hook chỉ dùng để thông báo luôn thoát với 0, và mọi hook có chặn đều kiểm tra stop_hook_active trước.

Làm sao lấy câu trả lời cuối cùng của Claude trong hook?

Đọc last_assistant_message từ JSON trên stdin, ví dụ bằng jq -r '.last_assistant_message'. Đừng dựa vào transcript_path: lúc Stop chạy, file có thể chưa chứa tin nhắn cuối.

Stop và SubagentStop khác nhau thế nào?

Stop dành cho agent chính. SubagentStop chạy khi một subagent hoàn thành, match theo loại agent và hỗ trợ cùng các trường chặn. Thông báo "Claude đã xong" nên đặt ở Stop.

Claude Code Notifier Nhận push trên điện thoại khi Claude Code chạy xong hoặc cần bạn, rồi duyệt, từ chối hoặc trả lời ngay tại đó. Công cụ dòng lệnh ccn miễn phí trên Mac, Windows và Linux.
Tải cho iOS Tải cho Android Cài đặt ccn

Hướng dẫn liên quan

  • Cách nhận thông báo khi Claude Code chạy xongDùng Stop hook cho trạng thái "đã xong" và Notification hook cho "cần bạn nhập". Cấu hình copy-paste cho Mac, Windows và Linux, kèm cảnh báo trên điện thoại.
  • Giải thích hook trong Claude Code: mọi sự kiện và công dụng của chúngHook trong Claude Code là gì, đặt ở đâu trong settings.json, matcher, input và exit code hoạt động thế nào, và mỗi sự kiện hook dùng để làm gì.
  • Notification hook của Claude Code: khi nào kích hoạt và cách dùngKhi nào Notification hook của Claude Code kích hoạt, permission_prompt và idle_prompt nghĩa là gì, input nó nhận được, và vì sao nó chờ một lúc mới kích hoạt.
  • Để Claude Code tự chạy rồi rời máy: một quy trìnhQuy trình thực tế cho các tác vụ dài với Claude Code: giữ máy không ngủ, bớt các prompt không cần thiết, nhận thông báo trên điện thoại và trả lời ngay từ đó.
claude-code-notifier

Claude Code Notifier là ứng dụng độc lập của bên thứ ba. Ứng dụng không liên kết với, không được chứng thực hay tài trợ bởi Anthropic, PBC. "Claude" và "Claude Code" là nhãn hiệu của Anthropic, PBC.

ứng dụng Ứng dụng iOS Ứng dụng Android ccn cho macOS, Windows & Linux Tất cả hướng dẫn
pháp lý Chính sách quyền riêng tư Điều khoản dịch vụ Ngôn ngữ khác © 2026 touchtap. Bảo lưu mọi quyền. TouchTap Ltd được đăng ký tại Anh và xứ Wales, số công ty 13942589.