
Watch a Page or API and Alert
Build a watcher that polls a web page or API endpoint on a schedule, detects a meaningful change or threshold breach, and fires an alert (and only alerts on real changes, not noise). Scopes the watched target, the exact change/threshold condition, and the dedup/cooldown policy FIRST, then builds the poll-diff-notify loop with persisted state, then tests it against simulated change and no-change inputs so it neither misses a real change nor spams on every poll. Condition-and-cooldown-before-build is the wisdom that separates a useful monitor from an alert-fatigue generator.
Steps
Entry step: scope. Each step names the specialist role it wants; the full working prompt is expandable.
- Scope the monitorplannerentry
target, change condition, dedup + cooldown policy
Show working prompt
Define what to watch and what counts as alert-worthy before building. Step 1: name the target (URL or API endpoint), the poll interval, and exactly which value to extract (a price, a status code, a count, a specific text region) — not the whole page. Step 2: define the change condition precisely — equality change, threshold crossing (>=, <=), or appearance/disappearance of a substring. Step 3: define the dedup/cooldown policy so you alert once per distinct change, not every poll (persist last-seen value + last-alert time; require a cooldown window). Step 4: define the alert channel and message template (what the alert says, including old→new value). Step 5: write an acceptance-criteria checklist ('extracts only the target value', 'fires exactly once on a real change', 'silent when nothing changed', 'respects the cooldown', 'persists state across runs'). Call write_task_note with the condition + policy + checklist and write it to notes/scope.md. No code yet. - Build the watcherdeveloper
poll, extract, diff vs state, alert on real change
Show working prompt
Implement the watcher to the locked condition and policy. Step 1: load persisted state (last-seen value, last-alert timestamp) or initialize on first run. Step 2: fetch the target and extract only the scoped value, with error handling so a transient fetch failure does not crash or false-alert. Step 3: evaluate the change condition against the last-seen value; if met AND the cooldown has elapsed, format and send the alert with old→new. Step 4: always persist the new last-seen value (and last-alert time when alerting) so the next run diffs correctly. Step 5: make it runnable on the chosen interval (a script suitable for cron) and write it to a code module. Call write_task_note with the module path and how state is persisted.
- Test the watcherdeveloper
assert it alerts on change, stays silent otherwise
Show working prompt
Prove the watcher behaves on every case before trusting it. Step 1: write tests that feed a fixed last-seen state plus a new reading. Step 2: assert the no-change case sends NO alert. Step 3: assert a real change (or threshold crossing) sends EXACTLY ONE alert with the correct old→new values. Step 4: assert that a second identical change within the cooldown window does NOT re-alert, and that it does alert again after the window. Step 5: assert a fetch failure is handled (no crash, no false alert) and that state is persisted after each run. Put the watcher and these tests in a single code-with-tests file; run them and confirm green. Call write_task_note with the test file path and the pass count.
- Evaluatereviewer
Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.
Show working prompt
Run the tests in monitor_test.py (or trace them) and verify every criterion from notes/scope.md: only the target value is extracted, a real change fires exactly one alert with old→new, no-change polls are silent, the cooldown suppresses duplicate alerts and releases after the window, fetch failures do not false-alert, and state persists across runs. Write PASS/FAIL per criterion; on any failure, name it and loop back to test. Then route — this is the whole point of the loop: - **Every criterion PASSES →** call `advance_task_step({ ref, stepId: "evaluate", next: "finish" })`. - **Any criterion FAILS →** write the specific gaps to notes, then call `advance_task_step({ ref, stepId: "evaluate", next: "test" })` to loop back. The builder fixes exactly those gaps. Never route to `finish` while any criterion is unmet. The build phase's completion gate already blocked a grossly-incomplete deliverable; your job is the judgment an automated check cannot make (does it actually work, read well, look right). After ~3 unproductive loops, stop and report DONE_WITH_CONCERNS so the user can step in. - Finishdeveloper
All acceptance criteria met. Stamp a short summary and report DONE.
Show working prompt
Every acceptance criterion passed. Write a one-paragraph DONE summary to task notes via `write_task_note`: what was built, the deliverable path(s), and a one-line confirmation that each criterion is met. Then report DONE.
Triggers
Phrases that suggest this craftbook to a crew.
- watch a page for changes
- alert me when this changes
- monitor an API
- notify on a price drop
- uptime watcher
Source
View this craftbook on GitHub · MIT license