Nhận tin báo ngay khi phiên training hay bản build của bạn hoàn tất

Chạy tác vụ của bạn dưới LidRun, nó sẽ báo cho bạn ngay khi tiến trình kết thúc — kèm exit code và thời gian chạy — để bạn nhận thông báo khi tác vụ trên Mac hoàn tất thay vì phải ngồi canh cửa sổ terminal. Push lên điện thoại (qua ntfy.sh hoặc Pushover) là miễn phí; Telegram, Discord, Slack và webhook tùy chỉnh thuộc bản Pro. Nếu bạn không muốn cài thêm gì cả, macOS vốn đã có sẵn vài lệnh có thể báo cho bạn khi một lệnh shell hoàn tất — bài viết này nói về cả hai cách: cách gốc miễn phí, và cách các kênh của LidRun hoạt động từ đầu đến cuối.
Vì sao bạn cứ phải ngó lại terminal
macOS không có sẵn cách nào để nói "báo tôi khi việc này xong." Terminal.app có thể nhấp nháy icon trên Dock khi một lệnh shell chạy nền hoàn tất (Preferences → Profiles → Shell → "Notify when process completes"), nhưng cách đó chỉ có tác dụng nếu bạn đang ngồi trước Mac để nhìn thấy — nó không tới được điện thoại của bạn, và cũng chẳng nói gì về việc lệnh đó có thực sự thành công hay không. Một lệnh ollama pull, một cargo build, một vòng training, hay một phiên Claude Code / Codex chạy không người canh sẽ kết thúc trong im lặng hoàn toàn nếu không có gì khác can thiệp.
Thế nên bạn hoặc ngồi kiểm tra lại liên tục, hoặc đi làm việc khác và đoán mò: quay lại quá sớm thì lại phải chờ tiếp, quá muộn thì mất thời gian lẽ ra đã dùng cho việc tiếp theo. Các app giữ máy thức chung chung — Amphetamine, Caffeine, KeepingYouAwake, Lungo — giải quyết tốt nửa đầu của vấn đề, ngăn Mac vào chế độ ngủ, nhưng không cái nào theo dõi một lệnh cụ thể hay báo cho bạn khi nó kết thúc. Đó là một việc khác hẳn so với một nút bật/tắt trên menu bar.
Cách khắc phục là một tin nhắn duy nhất ngay khoảnh khắc tiến trình kết thúc, cho biết nó có thực sự thành công hay không. Phần còn lại của bài viết này nói về hai cách để có được điều đó: tự dựng lấy bằng những gì Mac của bạn đã sẵn có, hoặc để LidRun làm việc đó.
Cách gốc, miễn phí để nhận tin báo
macOS có sẵn đủ công cụ để dựng một phiên bản thô của việc này mà không cần cài thêm gì. say "build finished" sẽ đọc to một câu — ổn nếu bạn đang ở phòng bên cạnh. osascript -e 'display notification "Build finished, exit 0" with title "Terminal"' sẽ đăng một banner Notification Center thật, cùng loại banner mà bất kỳ app nào cũng tạo ra. Bạn có thể nối một trong hai lệnh này vào sau một lệnh khác bằng ; (chạy bất kể lệnh trước thành công hay không) hoặc && (chỉ chạy nếu lệnh trước thành công): npm run build && osascript -e 'display notification "Build finished" with title "npm"'.
Nếu muốn thứ gì đó chỉn chu hơn một chút, terminal-notifier (brew install terminal-notifier) là công cụ miễn phí tiêu chuẩn cho việc này — terminal-notifier -title "Build" -message "Finished" đăng cùng loại banner nhưng với API dòng lệnh dễ dùng hơn. Tuy nhiên, cả ba công cụ này đều không tới được điện thoại của bạn; chúng chỉ hoạt động trong Notification Center, trên chính chiếc Mac bạn đang ngồi trước.
Phần mà nhiều người hay bỏ sót: cả say, osascript lẫn terminal-notifier đều không giữ Mac thức. Nếu màn hình ngủ và idle sleep kích hoạt trước khi tác vụ hoàn tất, macOS có thể tạm dừng toàn bộ tiến trình — bản build bị treo, và lệnh thông báo ở cuối chuỗi lệnh sẽ không bao giờ chạy. caffeinate -i đặt trước một lệnh sẽ trì hoãn idle sleep đúng bằng thời gian lệnh đó chạy — đây chính là phần mà các công cụ thông báo tự thân không cung cấp.
Gộp lại, đó là công thức gốc, miễn phí hoàn chỉnh — giữ máy thức trong lúc chạy tác vụ, rồi báo lại khi xong:
caffeinate -i npm run build; osascript -e 'display notification "Build finished" with title "npm"'
Chuỗi lệnh tự chế bị gãy ở đâu
Trong thực tế có ba điều dễ trục trặc với caffeinate cộng lệnh thông báo. Thứ nhất, caffeinate là một khóa giữ máy thức "mù" — nó không biết gì về mức pin hay tình trạng nhiệt của máy, và sẽ giữ MacBook thức ở bất kỳ mức pin hay nhiệt độ nào, suốt thời gian lệnh được bọc bên trong chạy. Điều đó không sao với một bản build năm phút ngồi tại bàn; nhưng với một phiên chạy dài không người canh, đó là cách thực sự có thể khiến máy cạn pin hoặc tự tắt vì quá nhiệt, nhất là khi khe tản nhiệt bị chặn bởi giá đỡ laptop hay nằm trong túi xách. Việc giữ cho Mac thông thoáng vẫn luôn là trách nhiệm của bạn — không thông báo nào, từ bất kỳ công cụ nào, làm mát được thân máy.
Thứ hai, osascript, terminal-notifier và say chỉ tới được chiếc Mac bạn đang ngồi trước. Nếu bạn đã rời đi, bạn sẽ không thấy banner đó cho tới khi tình cờ nhìn lại màn hình — chính là vấn đề bạn đang cố giải quyết ngay từ đầu.
Thứ ba, đóng nắp máy sẽ dừng toàn bộ chuỗi lệnh. Trừ khi bạn đã chạy riêng pmset disablesleep 1 — lệnh này cần xác thực quyền admin và là một công tắc nặng đô, luôn bật cho tới khi bạn nhớ tắt lại bằng 0, chứ không giới hạn trong phạm vi một lệnh — đóng nắp máy sẽ tạm dừng cả Mac, tác vụ, lẫn lệnh thông báo đi kèm.
Phiên bản miễn phí của LidRun: một lệnh được bọc lại cộng một lệnh notify
Đây chính là khoảng trống mà LidRun lấp vào, và bản miễn phí đã bao quát được phiên bản cơ bản của việc này. Quy tắc rất đơn giản: agent hay lệnh đang chạy → giữ máy thức; lệnh xong, hoặc có gì đó trở nên không an toàn → nhả ra và để Mac ngủ. Công thức CLI miễn phí:
lidrun -- npm run build; lidrun notify "Build finished" "exit $?"
lidrun -- <command> bọc lệnh của bạn trong một power assertion giữ máy thức trong suốt vòng đời của nó — tự thân đầy đủ, và phần này không cần app LidRun đang chạy. Cần nói rõ một điều: tự nó, cách bọc này chỉ là một khóa giữ máy thức đơn thuần như caffeinate, không có khả năng nhận biết pin hay nhiệt độ tích hợp sẵn, và được nhả ra ngay khi tiến trình con kết thúc. lidrun notify "<title>" "<body>" là phần thêm vào thông báo thật sự, và nó cần app LidRun đang chạy trên menu bar — nó đăng một banner cục bộ, cộng thêm, nếu bạn đã bật push điện thoại trong Notifications & Alerts, gửi tới điện thoại bạn qua ntfy.sh (miễn phí, theo topic — cài app ntfy, đăng ký một topic bạn chọn, LidRun sẽ đăng lên đó) hoặc Pushover (app trả phí một lần, không phải gói thuê bao). Cả hai lệnh đều miễn phí — không cần bản Pro.
Ngưỡng an toàn nền của LidRun — tự dừng khi pin xuống khoảng 4%, giảm cường độ khi áp lực nhiệt kéo dài — thuộc về các chế độ riêng của app: Keep Awake, Timer, và Run & Watch a Command, tất cả đều chạy dưới state machine của LidRun chứ không phải một power assertion IOKit trần trụi. Nếu bạn muốn chính tác vụ đó được theo dõi với lưới an toàn ấy, chứ không chỉ được bọc lại, thì đó là điều Keep Awake/Timer miễn phí hay Run & Watch bản Pro mang lại hơn so với cách bọc CLI thô — nó không phải một khóa giữ máy thức mù, chạy bất chấp chuyện gì đang xảy ra với Mac.
Telegram, Discord, Slack và webhook — lớp tính năng Pro
Nếu bạn muốn thông báo thoát hẳn khỏi chiếc Mac — rơi vào một kênh mà team bạn đã theo dõi sẵn, hay tới một app bạn không cần cài đặt — đó là các tích hợp Pro của LidRun: Telegram, Discord, Slack và một webhook tùy ý, tất cả được cấu hình từ cửa sổ Notifications & Alerts trên menu bar. Push điện thoại nói ở trên vẫn luôn miễn phí; bốn kênh này thuộc cùng bản trả phí mở khóa Run & Watch a Command, Closed-Lid mode và Smart Rules.
Với Telegram, bạn không cần tự tạo bot: mở bot LidRun dùng chung trên Telegram (@Libruntest_bot, hoặc nút "Open the LidRun bot" trong app) rồi bấm Start, sau đó mở @userinfobot để lấy Chat ID dạng số của riêng bạn, và dán Chat ID đó vào LidRun. Vậy là xong toàn bộ thiết lập — không cần bot token, không cần qua BotFather. Có một trường nâng cao cho phép bạn dùng bot riêng của mình thay thế; để trống nếu muốn dùng bot dùng chung.
Discord và Slack hoạt động theo cùng cách từ phía LidRun: tạo một URL incoming webhook từ phần cài đặt tích hợp của kênh (Discord: channel settings → Integrations → Webhooks → New Webhook; Slack: app Incoming Webhooks trong workspace của bạn) rồi dán URL đó vào. Tin nhắn Discord được đăng dưới dạng {"content": "..."}; Slack đăng dưới dạng {"text": "..."} — đúng cấu trúc JSON mà tài liệu webhook của mỗi dịch vụ tự mô tả, nên không có gì đặc thù của LidRun mà bạn phải học thêm.
Webhook tùy ý dành cho mọi trường hợp còn lại — Zapier, IFTTT, Home Assistant, endpoint của riêng bạn. LidRun sẽ POST nội dung này tới URL bạn cung cấp:
{"title": "Task finished ✅", "body": "npm run build (exit 0) after 2m 14s", "event": "session_finished", "app": "LidRun"}
event là một khóa ngắn dành cho máy đọc mà bạn có thể dùng để định tuyến — session_finished và all_tasks_finished cho công việc đã hoàn tất, thermal_critical và sleep_failed cho phía an toàn.
Việc gửi đi theo kiểu bắn-và-quên, kèm một lần thử lại: nếu một kênh từ chối tin nhắn, LidRun đợi 5 giây rồi thử lại một lần nữa, sau đó ghi nhận lỗi thay vì thử lại vô hạn. Mỗi request hết hạn sau 15 giây. Hãy dùng nút "Send test" cạnh mỗi kênh trước khi chạy thật, để một Chat ID hay URL webhook sai không âm thầm nuốt mất tin báo đầu tiên của bạn.
Điều gì thực sự kích hoạt một tin báo
Có hai nhóm sự kiện lớn đáng biết. Nhóm đầu tiên là một lệnh đã hoàn tất. Run & Watch a Command (Pro, trong app) chạy lệnh của bạn, giữ máy thức suốt vòng đời của nó, và khi kết thúc sẽ bắn ra một tin báo đã kèm sẵn exit code và thời lượng chạy — "Task finished" hoặc "Task failed," chứ không chỉ đơn giản là "nó đã dừng." Auto Mode (Pro) làm điều tương tự trên cả một danh sách theo dõi gồm nhiều tiến trình và báo một lần khi mọi thứ trong danh sách đã xong, nhưng chỉ khi bạn thực sự đi vắng — nắp đóng, hoặc máy rảnh vài phút — nên nó không thêm banner mỗi lần bạn đang ngồi tại bàn.
Nhóm thứ hai là sự kiện an toàn, và nó có hai tầng. Ngưỡng an toàn nền của LidRun — nhả giữ máy thức vì Mac quá nóng ở mức nguy hiểm hoặc pin chạm ngưỡng khẩn cấp, hay LidRun không khôi phục được chế độ ngủ bình thường sau closed-lid mode — sẽ push tới điện thoại bạn qua công tắc "Critical safety alerts" miễn phí, không phụ thuộc vào giấy phép. Watchdog (Pro) bổ sung thêm phát hiện cụ thể hơn: một agent có vẻ như đang kẹt chờ bạn phản hồi, một kết nối mạng bị rớt, và cùng những điều kiện nhiệt độ/pin nguy hiểm nói trên nhưng được bắt sớm hơn và báo cáo chi tiết hơn.
Có một quy tắc gói gọn tất cả: push điện thoại — một banner cục bộ cộng ntfy hoặc Pushover — miễn phí cho mọi sự kiện mà LidRun có thể phát ra. Telegram, Discord, Slack và webhook là lớp Pro thêm vào trên đó, tỏa đúng những sự kiện ấy ra nhiều nơi hơn.
Nếu bạn cũng bật "Away notifications" (miễn phí), việc đóng nắp máy khi có gì đó đang chạy sẽ gửi một tin ngắn cho biết cái gì đang chạy và LidRun sẽ làm gì với pin và nhiệt độ, rồi một bản tóm tắt ngắn khi bạn mở nắp lại — một tin nhắn cho mỗi thời điểm, không phải một luồng cập nhật liên tục.
LidRun giữ công việc của bạn chạy tiếp khi đóng nắp, với cơ chế bảo vệ pin và nhiệt tích hợp sẵn.
Đã có LidRun? Đọc hướng dẫn thiết lập →
Mới biết đến LidRun? Xem bảng giá →
Câu hỏi thường gặp
Không. Mở bot LidRun dùng chung (@Libruntest_bot) trong Telegram, bấm Start, rồi dán Chat ID dạng số mà @userinfobot cung cấp vào cửa sổ Notifications & Alerts của LidRun. Không cần tạo bot token, không cần đăng ký gì với BotFather. Có một trường nâng cao cho phép bạn dùng bot riêng thay thế — để trống nếu muốn dùng bot dùng chung.
Push điện thoại — một banner cục bộ cộng ntfy.sh hoặc Pushover — là miễn phí, bao quát tin báo tác vụ hoàn tất, ngưỡng an toàn nền của LidRun (pin yếu, quá nhiệt), và Away notifications. Telegram, Discord, Slack và webhook tùy chỉnh thuộc bản Pro, cùng với Run & Watch a Command (chế độ tự động dựng tin báo kèm exit code và thời lượng), Auto Mode và Watchdog.
Webhook tùy ý POST một JSON: {"title": "...", "body": "...", "event": "...", "app": "LidRun"}, trong đó event là một khóa ngắn dành cho máy đọc như session_finished mà bạn có thể dùng để định tuyến. Discord nhận {"content": "..."} và Slack nhận {"text": "..."} — đúng cấu trúc chuẩn mà tài liệu incoming-webhook của mỗi dịch vụ tự mô tả.
Có, với Run & Watch a Command (Pro): tiêu đề sẽ ghi "Task finished" hoặc "Task failed," và nội dung kèm exit code cùng thời gian chạy. Cách bọc CLI miễn phí lidrun -- <command> không tự dựng tin báo đó — hãy nối thêm lidrun notify "title" "exit $?" để có cùng thông tin đó mà không mất phí.
Với các lượt gửi Telegram/Discord/Slack/webhook: một lần. Nếu một kênh từ chối tin nhắn, LidRun đợi 5 giây rồi thử lại, sau đó ghi nhận lỗi thay vì thử lại vô hạn. Banner cục bộ và push điện thoại qua ntfy/Pushover là một request bắn-và-quên đơn lẻ, không được thử lại theo cách tương tự.
Có. caffeinate -i your-command; osascript -e 'display notification "Done" with title "Job"' giữ cho Mac không rơi vào idle sleep trong lúc lệnh chạy, rồi đăng một banner Notification Center khi xong. Cách này chỉ hoạt động cục bộ — sẽ không tới điện thoại bạn nếu bạn đã rời đi, và nó không biết gì về việc mức pin hay tình trạng nhiệt của máy có còn an toàn để tiếp tục hay không.
Có. Khi ngưỡng an toàn nền của LidRun nhả giữ máy thức — quá nóng ở mức nguy hiểm, hoặc pin gần chạm ngưỡng khẩn cấp — điều đó sẽ push tới điện thoại bạn qua công tắc "Critical safety alerts" miễn phí, độc lập với tin báo tác vụ hoàn tất. Watchdog (Pro) bổ sung thêm các cảnh báo cụ thể hơn, như một agent có vẻ đang kẹt chờ bạn phản hồi hoặc một kết nối mạng bị rớt.