บทที่ 19 — การตั้งเวลา (Scheduling)
ฟีเจอร์ Scheduling ช่วยให้คุณรัน prompt ของ thClaws ตามตารางเวลาแบบ cron — ทุกเช้าวันจันทร์-ศุกร์ ทุกคืนวันอาทิตย์ หรือทุก 5 นาที — โดยไม่ต้องจำว่าจะต้องพิมพ์ prompt เอง แต่ละงานที่ตั้งเวลาไว้จะ spawn เป็น subprocess thclaws --print ของตัวเองในไดเรกทอรีที่กำหนด ดังนั้น 2 schedule ใน 2 โปรเจกต์จึงเป็นอิสระจากกันโดยสมบูรณ์
ฟีเจอร์นี้แบ่งเป็น 3 ชั้น แต่ละชั้นใช้งานได้เดี่ยว ๆ:
| ชั้น | ทำอะไร | จะยิงเมื่อไหร่ |
|---|---|---|
| Store + manual run | Schedule ที่มีชื่อจะถูกบันทึกไว้ในไฟล์ JSON ระดับผู้ใช้ และ thclaws schedule run <id> จะยิงงานหนึ่งครั้งแบบ synchronous |
เฉพาะตอนที่คุณ (หรือ cron / launchd) เรียก run เท่านั้น |
| In-process scheduler | Background tokio task จะ tick ทุก 30 วินาทีขณะที่ surface ของ thclaws เปิดอยู่ และยิงงานที่ถึงเวลาแบบอัตโนมัติ | ขณะที่ thclaws --gui, --cli, หรือ --serve กำลังรันอยู่ |
| Native daemon | Process ที่รันยาวภายใต้ supervisor (launchd บน macOS, systemd-user บน Linux) host scheduler โดยไม่ต้องมีคนดูแล | ตลอดเวลา — แม้ไม่มี GUI/CLI session ใดเปิดอยู่ |
เลือกชั้นที่ตรงกับว่าคุณต้องการให้งานยิงโดยไม่มีคนเฝ้ามากแค่ไหน: in-process tick พอเพียงถ้าคุณมัก ๆ เปิด thclaws --gui ทิ้งไว้ระหว่างวัน, daemon เหมาะกับสถานการณ์ “ยิงขณะที่ปิดฝา laptop”
เริ่มต้นใช้งาน
$ thclaws schedule add morning-brief \
--cron "30 8 * * MON-FRI" \
--cwd ~/projects/web \
--prompt "สรุป commit วันนี้และ PR ที่เปิดอยู่ลงไฟล์ ~/Desktop/brief.md" \
--timeout 600
added schedule 'morning-brief'
$ thclaws schedule list
on morning-brief 30 8 * * MON-FRI never /Users/jimmy/projects/web
$ thclaws schedule run morning-brief
[schedule] 'morning-brief' ran in 38.412s, log: /Users/jimmy/.local/share/thclaws/logs/morning-brief/2026-05-06T08-30-04Z.log
นี่คือ workflow ทั้งหมด: เพิ่ม, รันด้วยมือเพื่อทดสอบถ้าต้องการ, จากนั้นปล่อยให้ in-process tick ยิง หรือ install daemon เพื่อให้ยิงโดยไม่ต้องมีคนเฝ้า
ฟิลด์ของ schedule
แต่ละ schedule เก็บข้อมูลตามฟิลด์ต่อไปนี้ มีเฉพาะ id, cron, และ prompt ที่จำเป็นต้องระบุ
| ฟิลด์ | ต้องระบุ | ค่าดีฟอลต์ | ทำอะไร |
|---|---|---|---|
id |
✅ | — | คีย์สำหรับค้นหา ใช้เป็นชื่อโฟลเดอร์ log ด้วย |
cron |
✅ | — | Cron expression แบบ POSIX 5 ฟิลด์ ตรวจสอบความถูกต้องตอน add |
prompt |
✅ | — | ข้อความที่จะส่งให้ thclaws --print หลายบรรทัดได้ |
cwd |
— | ไดเรกทอรีปัจจุบัน | Working directory ที่งานจะรัน เป็นตัวกำหนดว่าจะใช้ .thclaws/settings.json, sandbox, memory, และ MCP config ระดับโปรเจกต์ของไดเรกทอรีไหน |
model |
— | ตามที่ cwd กำหนด |
Override ชื่อโมเดล (gpt-4o, claude-sonnet-4-6 ฯลฯ) |
maxIterations |
— | ตามที่ cwd กำหนด |
จำกัดรอบการเรียก tool ของ agent loop |
timeoutSecs |
— | 600 (10 นาที) | Timeout แบบ hard ถ้าเกินจะ kill งานและบันทึกเป็น timed_out ใส่ --timeout 0 ตอน add ถ้าไม่ต้องการ timeout |
enabled |
— | true |
ถ้าเป็น false scheduler จะข้าม และ schedule run จะปฏิเสธไม่ยิง |
watchWorkspace |
— | false |
ถ้า true daemon จะยิงงานเมื่อมีไฟล์ใน cwd เปลี่ยนแปลง (debounce ~2 วินาที) — ดู Trigger เมื่อ workspace เปลี่ยนแปลง ด้านล่าง รองรับเฉพาะ daemon เท่านั้น in-process scheduler จะข้าม flag นี้ |
lastRun / lastExit |
— | ไม่มี | ตั้งค่าอัตโนมัติหลังการยิงครั้งแรก |
Cron expression
POSIX แบบ 5 ฟิลด์มาตรฐาน: minute hour day-of-month month day-of-week
| Expression | ความหมาย |
|---|---|
*/5 * * * * |
ทุก 5 นาที |
0 * * * * |
นาที 0 ของทุกชั่วโมง |
30 8 * * MON-FRI |
08:30 ของวันจันทร์-ศุกร์ |
0 21 * * SUN |
21:00 ของทุกวันอาทิตย์ |
0 0 1 * * |
เที่ยงคืนของวันที่ 1 ทุกเดือน |
0 9,13,17 * * * |
09:00, 13:00, 17:00 ทุกวัน |
รองรับ syntax แบบ range/list (MON-FRI, 1,15) Cron expression จะถูกตรวจสอบตอนรัน schedule add — พิมพ์ผิดจะแสดง error ที่อ่านง่ายแทนที่จะล้มเหลวเงียบ ๆ ตอนงานยิง
Trigger เมื่อ workspace เปลี่ยนแปลง
นอกเหนือจาก (หรือแทนที่) cron แล้ว schedule สามารถถูกยิงเมื่อมีไฟล์ใน working directory เปลี่ยนแปลงได้ ตั้ง watchWorkspace: true ใน JSON, ใส่ --watch ในคำสั่ง thclaws schedule add, หรือติ๊กช่องที่เขียนว่า “Run when file in workspace changes” ใน modal ของ GUI
thclaws schedule add doc-summary \
--cron "0 9 * * *" \
--cwd ~/projects/blog \
--prompt "สรุป diff ของวันนี้ลงไฟล์ ~/Desktop/blog-changes.md" \
--watch
Schedule นี้จะยิงทุกวันเวลา 09:00 และ ทุกครั้งที่มีไฟล์ใน ~/projects/blog เปลี่ยน — ทั้ง 2 trigger ใช้เส้นทาง run_once เดียวกัน
Debounce + cooldown การ save ไฟล์ในโปรแกรมแก้ไขทั่วไป (Vim/VS Code) มักจะปล่อย event ของระบบไฟล์ 3-5 ครั้งภายใน 100 ms (เนื่องจากการใช้ atomic-rename + swap-file) ตัว watcher จะรวบ event เหล่านี้ภายในกรอบ debounce 2 วินาทีและส่งออกเป็น 1 event หลังจาก fire เริ่ม จะมี cooldown 60 วินาทีที่ดูดกลืน event ที่เข้ามา — นานพอที่ --print ที่ถูก spawn ออกไปจะเขียนไฟล์ลงใน workspace โดยไม่ trigger ตัวเองซ้ำทันที
รายการที่ ignore แบบตายตัว Watcher จะมองข้าม path ใดก็ตามที่มี segment ต่อไปนี้อยู่ระหว่าง cwd กับไฟล์ปลายทาง:
| Segment | เหตุผลที่ ignore |
|---|---|
.thclaws/ |
ที่ที่ thclaws --print เขียน session JSONL ของงานที่ถูก spawn — ถ้าไม่ ignore จะ loop ไม่จบ |
.git/ |
มีการเปลี่ยนแปลงตลอดเวลาขณะใช้ git ปกติ (git status, git fetch, git checkout) |
node_modules/, target/, dist/, build/, .next/, .cache/ |
Build output ที่ไม่ได้ขอให้ agent ตอบสนอง |
.DS_Store |
Metadata ของ Finder บน macOS ที่ไม่มีประโยชน์ |
รายการนี้ hardcode ไว้ใน v1 — ยังไม่อ่าน .gitignore ถ้าต้องการ control แบบละเอียดกว่านี้ ให้ใช้ watchWorkspace: false แล้วใช้ cron อย่างเดียว
Daemon-only Trigger แบบ workspace-change ถูก wire-up โดย daemon (Step 3) เท่านั้น — thclaws schedule install คือคำสั่งที่เปิดใช้งาน in-process scheduler (Step 2) จะข้าม watchWorkspace เพราะจุดประสงค์ทั้งหมดของการยิงด้วย filesystem โดยอัตโนมัติคือไม่มีคนคอยดูแล
อะไรนับเป็น “การเปลี่ยนแปลง” Recursive ทั่วทั้ง cwd — file create, write, rename, delete (ตาม semantic ของแต่ละ OS ที่ notify exposes ออกมา) การเปลี่ยนแปลงในโฟลเดอร์ย่อยก็นับด้วย ยกเว้น path จะผ่าน segment ที่ ignore ไว้
Layout ของ storage
| Path | เนื้อหา |
|---|---|
~/.config/thclaws/schedules.json |
Schedule store แก้ด้วยมือได้ |
~/.local/share/thclaws/logs/<id>/<ts>.log |
ไฟล์ log 1 ไฟล์ต่อการยิง 1 ครั้ง — รวม stdout + stderr ของ thclaws --print ที่ spawn ออกมา |
~/.local/state/thclaws/scheduler.pid |
PID file ของ daemon ใช้โดย schedule status และตัวกัน double-daemon |
~/Library/LaunchAgents/sh.thclaws.scheduler.plist (macOS) |
ไฟล์ supervisor ของ launchd เขียนโดย schedule install |
~/.config/systemd/user/thclaws-scheduler.service (Linux) |
Unit ของ systemd-user เขียนโดย schedule install |
~/.local/share/thclaws/daemon.log |
Log ของตัว daemon เอง (แยกจาก log ของแต่ละงาน) |
ไฟล์ store เป็น JSON เล็ก ๆ ที่อ่านง่าย — แก้ด้วยมือได้สบาย:
{
"version": 1,
"schedules": [
{
"id": "morning-brief",
"cron": "30 8 * * MON-FRI",
"cwd": "/Users/jimmy/projects/web",
"prompt": "สรุป commit วันนี้และ PR ที่เปิดอยู่",
"timeoutSecs": 600,
"enabled": true,
"lastRun": "2026-05-06T08:30:04Z",
"lastExit": 0
}
]
}
การแก้ไขจะมีผลภายใน 30 วินาที (in-process scheduler อ่าน store ใหม่ทุก tick) — ไม่ต้องสั่ง reload daemon
ชั้นที่ 1 — รันด้วยมือเท่านั้น
หลัง schedule add คุณหยุดที่ตรงนี้ก็ได้ เชื่อม thclaws schedule run <id> เข้ากับ scheduler ที่คุณใช้อยู่แล้ว (crontab, launchd, GitHub Actions, …) แล้วให้ตัวนั้นจัดการเรื่องเวลาเอง
# crontab -e
30 8 * * 1-5 /usr/local/bin/thclaws schedule run morning-brief
แนวทางนี้เหมาะถ้าคุณมี crontab ที่ชอบใช้อยู่แล้ว หรืออยากให้ตรรกะเรื่องเวลาอยู่นอก thclaws ทั้งหมด
ชั้นที่ 2 — In-process scheduler
ถ้าคุณเปิด thclaws --gui หรือ thclaws --cli ทิ้งไว้ระหว่างวันเป็นปกติ in-process scheduler จะทำงานอัตโนมัติ เมื่อ surface ของ thclaws (ยกเว้น --print) เริ่มทำงาน คุณจะเห็นบรรทัดประกาศบน stderr:
[schedule] in-process scheduler running (tick 30s)
จากนั้นมันจะ tick ทุก 30 วินาที เมื่อ schedule ถึงเวลา มันจะ spawn subprocess และพิมพ์:
[schedule] 'morning-brief' fired — exit=0 duration=38.412s log=/Users/jimmy/.local/share/thclaws/logs/morning-brief/2026-05-06T08-30-04Z.log
หากต้องการปิด in-process scheduler (เช่น คุณใช้ daemon อยู่แล้วและไม่อยากให้มีอันที่ 2 ใน CLI session):
thclaws --cli --no-scheduler
โหมด --print ไม่ spawn scheduler เลย เพราะ print เป็น short-lived และเสียงรบกวนจาก subprocess ก็ไม่ได้มีประโยชน์อะไร
Cursor semantics: ข้าม catch-up เป็นค่าดีฟอลต์
เมื่อ scheduler เห็น schedule ครั้งแรก มันจะ seed cursor ที่อยู่ใน memory เป็น lastRun ของ schedule (ถ้ามี) หรือเป็น “ตอนนี้” (ถ้าไม่มี) แต่ละ tick จะถามตัว parser ของ cron ว่า fire ครั้งแรกหลัง cursor คือเมื่อไหร่ และยิงถ้าเวลานั้นผ่านมาแล้ว
ผลที่เกิดในทางปฏิบัติ: schedule ที่เพิ่งเพิ่มจะ ไม่ ยิงย้อนหลังสำหรับ cron event ที่ “พลาด” ก่อนถูกเพิ่ม ถ้าต้องการบังคับให้ยิงย้อนหลัง ให้แก้ lastRun ใน schedules.json เป็น timestamp ก่อน event ที่ต้องการ replay
ถ้างานก่อนหน้ายังรันค้างอยู่ตอน next fire time มาถึง scheduler จะข้ามครั้งนั้น (ตรงกับ --no-overlap ของ cron) การยิงพร้อมกันของ schedule เดียวกันจะไม่ถูก queue ไว้
ชั้นที่ 3 — Native daemon
หากต้องการให้ schedule ยิงแม้ไม่มี GUI หรือ CLI session เปิดอยู่ — รวมถึงข้ามคืน ระหว่างประชุม หรือตอนล็อกหน้าจอ — ให้ install daemon
$ thclaws schedule install
wrote /Users/jimmy/Library/LaunchAgents/sh.thclaws.scheduler.plist
daemon bootstrapped — `thclaws schedule status` to verify
$ thclaws schedule status
daemon: running (pid 88294)
recent fires:
ok morning-brief 2026-05-06T08:30:04Z
— deps-audit never
install ทำอะไรบ้าง:
- macOS: เขียน
~/Library/LaunchAgents/sh.thclaws.scheduler.plistแล้วรันlaunchctl bootstrap gui/$UIDเพื่อให้ daemon เริ่มทันทีและทุกครั้งที่ loginKeepAlive=trueและRunAtLoad=trueทำให้มัน restart เองอัตโนมัติถ้า crash - Linux: เขียน
~/.config/systemd/user/thclaws-scheduler.serviceและพิมพ์คำสั่ง next-step (systemctl --user daemon-reload && systemctl --user enable --now thclaws-scheduler.service) ให้ดูก่อนเปิดใช้งาน
หากต้องการหยุดและลบ supervisor entry:
$ thclaws schedule uninstall
daemon uninstalled
Schedule ใน store จะถูกเก็บไว้แม้จะ install/uninstall — คุณแค่เปิด/ปิดกลไก auto-fire เท่านั้น
สถานะของ daemon
$ thclaws schedule status
daemon: running (pid 88294)
มี 3 สถานะ:
| สถานะ | ความหมาย |
|---|---|
running (pid X) |
Daemon มีชีวิตอยู่ |
stale PID file (last pid Y not alive) |
Daemon ก่อนหน้าตายโดยไม่ได้ cleanup ตัวต่อไปจะเก็บ PID file คืนอัตโนมัติ |
not running |
ไม่มี PID file รัน schedule install (สำหรับยิงโดยไม่มีคนเฝ้า) หรือ thclaws daemon (foreground สำหรับทดสอบ) |
โหมด foreground (ทดสอบโดยไม่ต้อง install)
$ thclaws daemon
[daemon] thclaws scheduler started (pid 12345, pid file ~/.local/state/thclaws/scheduler.pid)
[schedule] in-process scheduler running (tick 30s)
[schedule] 'morning-brief' fired — exit=0 duration=38.412s log=...
^C
[daemon] SIGINT received — shutting down
[daemon] stopped cleanly
ใช้โหมดนี้ตรวจว่า schedule ยิงจริงก่อน install เป็น launchd/systemd entry
Preset สำเร็จรูปสำหรับการดูแล KMS
template schedule สี่ตัวพร้อมใช้ติดมาในตัว ครอบคลุม cadence การดูแล KMS ที่เจอบ่อย ๆ ได้แรงบันดาลใจมาจาก scheduled agent สี่ตัวของ obsidian-second-brain (nightly close, weekly review, contradiction sweep, vault-health) packaging มาให้ instantiate ตรง ๆ
❯ /schedule preset list
schedule presets:
ID CRON DESCRIPTION
nightly-close 0 23 * * * Wrap up the day — lint + auto-fix + stale-marker review (KMS '{kms}')
weekly-review 0 9 * * SUN Sunday-morning consolidation across active KMSes
contradiction-sweep 0 12 * * * Daily noon reconcile — auto-resolve clear-winner contradictions in '{kms}'
vault-health 0 6 * * * Morning lint summary at 06:00 for KMS '{kms}'
add via: /schedule preset add <id> --kms <name> [--cwd <path>]
แต่ละ preset เป็น cron expression รวมกับ prompt template ที่อ้าง {kms} (ระบบ substitute ตอน instantiate) ตัวอย่าง nightly-close รัน /kms wrap-up <name> --fix; contradiction-sweep รัน /kms reconcile <name> --apply
❯ /schedule preset add nightly-close --kms mynotes
✓ schedule 'nightly-close-mynotes' created from preset 'nightly-close' (cron: 0 23 * * *)
Wrap up the day — lint + auto-fix + stale-marker review (KMS 'mynotes')
format ของ schedule id คือ <preset-id>-<kms> ดังนั้น preset เดียวกัน target หลาย KMS ได้ไม่ชน (nightly-close-foo, nightly-close-bar) หลัง instantiate แล้ว ตัวที่ได้คือ schedule ปกติ — แก้ cwd / cron / model ผ่าน /schedule คำสั่งทั่วไปได้ หรือ /schedule rm <id> เพื่อลบ
| Preset | เมื่อไหร่ | ทำอะไร |
|---|---|---|
nightly-close |
ทุกวัน 23:00 | เดิน pages, แก้ broken markdown link, append index entry ที่ขาด, refresh STALE page |
weekly-review |
อาทิตย์ 09:00 | consolidate page ที่ overlap เข้าเป็น canonical (ใส่ pointer ไม่ใช่ลบ) + ทำ hygiene pass |
contradiction-sweep |
ทุกวันเที่ยง | สแกน 4 pass (claims / entities / decisions / source-freshness), auto-resolve clear winner พร้อม ## History, ทำ Conflict — <topic>.md สำหรับเคส ambiguous |
vault-health |
ทุกวัน 06:00 | health report read-only — broken link, orphan, missing-from-index, missing frontmatter, STALE marker |
[!IMPORTANT] prompt ของ preset เป็น คำสั่งภาษาธรรมชาติ ที่บอก agent ให้ใช้ KMS tools (KmsRead/Search/Write/Append) ตรง ๆ scheduler ยิง preset ผ่าน
thclaws --printซึ่งไม่ run slash-command dispatch — preset prompt จึงใช้ slash command (เช่น/kms reconcile) ไม่ได้.thclaws/settings.jsonของ cwd ต้องมี KMS เป้าหมายอยู่ในkms_activeเพื่อให้ KMS tools register ก่อน agent เริ่ม
สูตรการใช้งานจริง
Briefing ตอนเช้าทุกวันทำงาน
thclaws schedule add morning-brief \
--cron "30 8 * * MON-FRI" \
--cwd ~/projects/web \
--prompt "อ่าน git log ตั้งแต่เมื่อวาน ระบุ PR ที่ต้องรีวิว ตรวจ CI status เขียนลง ~/Desktop/morning-brief.md" \
--timeout 600
งานวิจัยระยะยาว สะสมข้ามคืน
ตั้ง lastRun ครั้งแรกผ่าน JSON แล้ว prompt แบบ resume-aware จะสะสมความคืบหน้าข้ามการยิงแต่ละครั้ง:
thclaws schedule add research-harness \
--cron "0 * * * *" \
--cwd ~/research \
--prompt "ทำงานต่อใน harness-engineering.md หาแหล่งข้อมูลใหม่ 1 แหล่ง ผนวกเข้าเอกสาร และบันทึกความคืบหน้า" \
--timeout 1800
สแกน hygiene ทุกคืน
thclaws schedule add nightly-hygiene \
--cron "0 2 * * *" \
--cwd ~/projects/myapp \
--prompt "สแกนหา TODO เก่ากว่า 30 วัน, clippy warning ที่เพิ่มเข้ามาสัปดาห์นี้, doc drift เขียนลง dev-log/hygiene-{date}.md" \
--timeout 1200
Auto-summarize-on-save (workspace watch ไม่ใช้ cron)
เฝ้าดูโฟลเดอร์ docs; ทุกครั้งที่มีไฟล์เปลี่ยน ให้ regenerate summary ใหม่ ตั้ง cron expression เป็นค่าในอนาคตไกลๆ เพื่อให้ trigger เฉพาะ watch ทำงาน — daemon-only, in-process scheduler จะข้าม flag นี้
thclaws schedule add docs-summary \
--cron "0 0 1 1 *" \
--cwd ~/projects/docs \
--prompt "อ่านทุกอย่างใต้ . แล้วอัปเดต SUMMARY.md ด้วยภาพรวม 200 คำ" \
--watch \
--timeout 600
Cooldown 60 วินาทีหลังแต่ละ fire กันไม่ให้การเขียน SUMMARY.md ของ agent เอง re-trigger ทันที Debounce 2 วินาทีรวบ atomic-rename burst ของ editor ให้กลายเป็น 1 fire
CI babysitter (ทุก 5 นาทีในเวลาทำงาน)
thclaws schedule add ci-watch \
--cron "*/5 9-18 * * MON-FRI" \
--cwd ~/projects/myapp \
--prompt "ตรวจว่า CI ของ PR #42 ผ่านหรือไม่ ถ้าล้มเหลว ดึง log มาดู ระบุ test ที่ fail เขียน triage note ลง /tmp/ci-triage.md" \
--timeout 300
Slash command ภายใน thClaws
การจัดการ schedule ส่วนใหญ่สามารถทำได้โดยไม่ต้องออกจาก thClaws ไปที่ shell จาก CLI REPL หรือแท็บ Chat ของ GUI พิมพ์ /schedule (หรือใช้ตัวย่อ /sched):
| Slash | พฤติกรรม |
|---|---|
/schedule หรือ /schedule list |
แสดงรายการ schedule ทั้งหมดพร้อม flag on/off และข้อมูลการยิงล่าสุด |
/schedule show <id> |
พิมพ์รายละเอียดของ schedule หนึ่งรายการเป็น JSON |
/schedule run <id> |
ยิง schedule หนึ่งครั้งแบบ synchronous (ไม่ block — REPL ยังตอบสนองได้) |
/schedule status |
สถานะ daemon + สรุปการยิงล่าสุดของทุก schedule |
/schedule pause <id> / /schedule resume <id> |
เปลี่ยนค่า enabled โดยไม่ต้องลบ entry |
/schedule rm <id> (หรือ remove / delete) |
ลบ schedule ออกจาก store |
/schedule install |
Install daemon (launchd plist บน macOS, systemd-user unit บน Linux) |
/schedule uninstall |
หยุด daemon และลบ supervisor entry |
/schedule add |
GUI: เปิด modal สำหรับกรอกข้อมูล (อธิบายด้านล่าง) CLI: พิมพ์คำแนะนำว่าควรใช้ shell subcommand |
/schedule add เป็นคำสั่งเดียวที่ทำงานต่างกันในแต่ละ surface เพราะ prompt หลายบรรทัดและ flag หลายตัวไม่เหมาะกับการพิมพ์บน REPL บรรทัดเดียว ดังนั้น:
- ในแท็บ Chat ของ GUI
/schedule addจะเปิด form modal ที่เติม cwd ปัจจุบันและตัวอย่าง cron ไว้ให้ก่อน มีตัวช่วย 3 อย่างที่ลดการพิมพ์: - Cron preset chips (
Every 5 min,Hourly,Daily 9am,Weekdays 8:30,Weekly Mon 9am,Monthly 1st) เติมค่า cron ในคลิกเดียว Chip ที่ตรงกับค่าใน field จะถูกไฮไลต์ด้วยสี accent - Live next-fire preview ตรวจสอบ cron 300 ms หลังหยุดพิมพ์และแสดง 3 ครั้งถัดไปที่จะยิง (เช่น
next fires: Tue, May 6 9:00 AM · Wed, May 7 9:00 AM · …) ถ้าพิมพ์ผิด จะแสดง error inline — ไม่มี surprise ตอน submit - Checkbox “Run when file in workspace changes” ตั้งค่า
watchWorkspace: trueใน entry เพื่อให้ daemon ยิงงานเมื่อมีการเปลี่ยนแปลงไฟล์ในcwdไม่ใช่แค่ตามตาราง cron (ดู Trigger เมื่อ workspace เปลี่ยนแปลง) กรอกid,cron,promptและฟิลด์อื่น ๆ ที่ต้องการ จากนั้นคลิก Save Backend จะตรวจสอบ field ที่จำเป็น, syntax ของ cron, และว่าcwdมีอยู่จริง — ข้อผิดพลาดจะแสดง inline ใน form ถ้าสำเร็จ modal จะแสดงข้อความยืนยันสีเขียวและปิดอัตโนมัติ - ใน CLI REPL
/schedule addจะพิมพ์ syntax ของ shell subcommand พร้อม flag ทั้งหมดให้คัดลอกไปวางใน terminal ได้
Slash และ CLI surface ใช้ store เดียวกัน — schedule ที่เพิ่มผ่านเส้นทางใดก็ตามจะปรากฏใน list ของอีกฝั่ง, ยิงจาก daemon ตัวเดียวกัน, และเขียนลง ~/.config/thclaws/schedules.json ไฟล์เดียวกัน
การตรวจสอบการยิง
Log ของแต่ละงานอยู่ที่ ~/.local/share/thclaws/logs/<id>/:
ls -lt ~/.local/share/thclaws/logs/morning-brief/ | head -5
tail -f ~/.local/share/thclaws/logs/morning-brief/$(ls -t ~/.local/share/thclaws/logs/morning-brief | head -1)
Log ของตัว daemon (ข้อความตอน startup, การประกาศ tick ของ scheduler) อยู่ที่ ~/.local/share/thclaws/daemon.log
การแก้ปัญหา
Schedule ไม่ยิงทั้งที่ควรจะยิง
1. ตรวจ thclaws schedule status — daemon รันอยู่ไหม?
2. ดู ~/.local/share/thclaws/daemon.log มี error อะไรไหม
3. ตรวจ enabled: true ใน store
4. จำไว้ว่า: skip-catch-up เป็นค่าดีฟอลต์ schedule ที่เพิ่มตอน 09:00 ด้วย cron 30 8 * * * จะไม่ยิง 08:30 ของวันนี้ย้อนหลัง — มันจะยิงพรุ่งนี้ 08:30
Daemon ปฏิเสธไม่ยอม start: “another daemon is already running”
มี daemon ก่อนหน้าที่ยังมีชีวิต thclaws schedule status จะแสดง PID จะปล่อยให้รันต่อก็ได้ หรือ kill <pid> แล้วลองใหม่
PID file ค้างหลังจาก crash
thclaws schedule status จะรายงาน thclaws daemon ครั้งต่อไปจะเก็บไฟล์คืนอัตโนมัติ — ไม่ต้อง cleanup ด้วยมือ
Laptop sleep
บน macOS LaunchAgent จะไม่ยิงขณะ laptop sleep (ปิดฝา) Schedule ที่ควรจะยิงระหว่าง sleep ต้องการ plumbing แบบ WakeMonitor (เลื่อนไว้ — ยังไม่รองรับ) ตอนนี้ให้คาดหวัง semantics แบบ “ยิงตอนใช้งาน laptop”
มี scheduler 2 ตัวรันพร้อมกัน
ถ้าคุณ install daemon และเปิด thclaws --cli โดยไม่ใช้ --no-scheduler ทั้ง 2 surface จะ tick store เดียวกัน ทั้งคู่ใช้ guard skip-overlap เดียวกัน ดังนั้นการยิงซ้ำจึงเกิดได้น้อยมาก แต่ setup ที่สะอาดกว่าคือใช้ --no-scheduler ทุกครั้งที่ install daemon
ข้อจำกัดที่ควรทราบ
- ยังไม่รองรับ daemon บน Windows
schedule installจะแสดง error “not yet supported on this platform” บน Windows ชั้นที่ 1 และ 2 (manual run + in-process scheduler) ใช้งานข้ามแพลตฟอร์มได้ มีเฉพาะ daemon (และwatchWorkspaceที่ผูกกับ daemon) ที่รองรับ macOS/Linux ในตอนนี้ - ไม่มี IPC Daemon และ CLI สื่อสารกันผ่าน store บนดิสก์ + PID file เท่านั้น
schedule logs --tailแบบ live,schedule reload, และ metric ฝั่ง daemon ถูกเลื่อนไว้ การแก้ไขschedules.jsonจะมีผลภายใน 30 วินาทีผ่าน polling tick (ตัว reconciler ของ watcher ก็ใช้ cadence เดียวกันสำหรับการ togglewatchWorkspace) - ไม่มีฟิลด์ catch-up policy Skip-catch-up เป็น policy เดียวที่ใช้ การ catch-up แบบ manual ผ่านการแก้
lastRunคือ workaround - ไม่มี log rotation
~/.local/share/thclaws/daemon.logและ~/.local/share/thclaws/logs/<id>/*.logจะโตขึ้นเรื่อย ๆ ตอนนี้ให้ตัดทิ้งด้วยมือ หรือเขียน cron entry ของคุณเอง - รายการ ignore ของ workspace watch ถูก hardcode
.thclaws/,.git/,node_modules/,target/,dist/,build/,.next/,.cache/,.DS_Storeยังไม่อ่าน.gitignoreถ้าต้องการ control ละเอียดกว่านี้ ให้ใช้ cron อย่างเดียว - ข้อจำกัดของ OS watch
inotifyของ Linux ค่าเริ่มต้นรองรับ 8192 watches ต่อ user; recursive watch บน tree ขนาดใหญ่อาจทะลุได้ Daemon จะ log error และข้าม watcher ตัวนั้น schedule อื่นยังทำงานต่อได้