brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
anysite-monitorBuild and run recurring monitoring on the Anysite MCP, delivering ONLY new or changed items each run by diffing against a persistent "seen ledger". Owns the onboarding: interviews the user about the decision the monitor should support, then searches the live Anysite catalog for endpoints that serve it, verifies each with a real call, and compiles them into …
Independent GitHub snapshot · Automated classification · Original documentation governs
A one-shot Anysite call answers "what is the state right now?". This skill answers the harder question — "what changed since I last looked?" — by keeping a seen ledger of fingerprints in durable storage, subtracting it from each fresh fetch, and reporting only what's new or edited.
Two things make a monitor good, and both are decided at setup, not at runtime:
discover + one probe call, and compiles verified specs into the config.search_requests), but it is a cache of fetches, not
a report state — 7-day retention is shorter than the ledger's rolling window,
and it can't record what was already reported. So the ledger must sit in
external storage a headless run can reach by token — OR, for daily-or-faster
monitors with stable-id sources, run ledgerless (ledger_mode: "cache_diff"): diff each fetch against the prior runs' fetches still in that
7-day cache. Zero storage and no persist step, at the price of no long memory
and silent loss after a failed delivery — mode selection rules in
references/storage-backends.md.response_fields (platform id/URN first, normalized URL only as fallback).initial_snapshot overrides.)retention_days (default 45)
so the ledger stays bounded.Follow references/onboarding.md — it is the playbook, not a summary. The arc:
references/source-discovery.md:
find candidates → discover(source, category) for exact params and
response_fields → one small execute probe on a real target → record the
verified spec. Two equally valid ways to find candidates: MCP-only (the
tools self-enumerate — a bogus source/category/endpoint returns
available_sources / available_categories / available_endpoints, free) or
catalog grep (docs.anysite.io/llms-full.txt via shell, adds keyword
search over descriptions). Use whichever the surface allows; never fetch the
12 MB openapi.json. Read the params for a time filter (posted_after,
date_posted, time_filter…) and use it when present.targets × signals calls per run, × cadence × 30 for the
month. Trim here, before the schedule exists.ledger_mode: "cache_diff"
(no storage, no persist; state the trade-off out loud). Otherwise ledger,
backend per storage-backends.md. For ledger mode also verify: can the
scheduled run reach a shell, Python, and this skill's scripts/? Test during
the dry run; if not, record "diff_mode": "in_session" so the run doesn't
discover it at 7 a.m.The schedule must outlive the session. Do not use CronCreate/CronList —
those are session-scoped (and expire in days). Use the host's durable
scheduled-task tools; in Cowork/Claude Code Remote these are create_trigger,
update_trigger, list_triggers, delete_trigger (load via ToolSearch if
deferred).
Verify the tools exist before promising a schedule. If none is available in the current surface, do not fake it: finish the config, run the baseline, hand the user the config plus a one-line instruction for creating the scheduled task themselves in the UI, and say plainly that the schedule is not registered yet.
The task prompt must be a self-contained Run-mode instruction: "Invoke the
anysite-monitor skill in Run mode with the config below" + the config JSON +
the ledger JSON as a separate block. Store the returned id in
monitor.trigger_id. Set the task's notifications per the chosen delivery.
ledger_mode: "cache_diff"? Different loop, no ledger and no persist:
find prior fetches via search_requests (match endpoint + target handle, last
7 days), union their id sets via query_cache, diff the current fetch against
the union in-session, deliver; the current fetch's cache entry is next run's
history. No prior fetches → baseline (fetch + one-line init). Full recipe in
references/storage-backends.md. Everything below is the ledger-mode loop.
references/storage-backends.md). No
ledger → baseline run.config.sources, execute exactly what the
spec says, capped by max_items. No re-discovery, no improvisation: if a
source errors, note it and continue (fail soft, never abort the digest).
Time window: if the spec has a time_filter, convert last_ok_run into
its value per source-discovery.md (unix_ts → minus one cadence of overlap;
enum → smallest bucket covering the gap). On a baseline run there is no
last_ok_run — use a deliberate seed window instead: for enum filters the
smallest bucket that matches the cadence (daily monitor → day/past-24h),
for unix_ts now − 7 days, and cap by max_items. Say the seeded window in
the init line, because anything older than it will surface as "new" on run 2.{fingerprint, content?, label, url} and run:
python3 scripts/ledger.py diff --ledger <file> --items <file> --today <YYYY-MM-DD> --retention-days <n> [--baseline].
It normalizes URLs, hashes content, buckets new/changed/seen, applies the
rolling window and returns the updated ledger. Don't hand-roll the diff — the
whole point is that every run diffs identically.
If the surface has no shell or no Python (or the skill's scripts/ isn't
available where the trigger fires — verify this at setup, not at 7 a.m.), fall
back to diffing in-session, following exactly the rules the script implements:
normalize URLs (lowercase host, strip utm_*/fbclid/gclid/ref, drop
fragment and trailing slash), compare fingerprints against ledger.items,
treat a differing content hash as changed, stamp s = today for everything
seen, drop entries older than retention_days. Note in the digest that the
fallback diff was used — it is the one step where drift can creep in.last_ok_run only on a successful write; if it lags last_run, say so
in the digest so repeats are explained. Recovery aid: search_requests (free)
can locate the previous run's fetches and their cache_keys for up to 7 days —
useful to reconstruct what a failed-persist run had already reported, or to
skip refetching a source this run already pulled.Group by target, then signal. Lead with counts so the reader can triage.
📡 <Monitor name> — <date>
<N> new · <C> changed since last run
## <Target A>
### New job postings (2)
- Senior ML Engineer, Berlin — posted <date> — <url>
- Head of Sales, Remote — posted <date> — <url>
### Pricing change (1)
- Pro plan $99 → $79/mo — <url>
_No changes for: <Target B>, <Target C>_
_Source "<name>" returned an error this run — skipped._
Nothing new is a valid result: say it in one line. Match the channel — email can
be rich markdown, Telegram/Slack should be tighter. Honour focus when set.
discover and catalog greps are free; execute is not. Never
re-fetch history you've already fingerprinted, use time filters where they
exist, and keep max_items tight.max_items new items, the
window may have overflowed and items were missed — warn in the digest and
suggest a tighter cadence or a higher cap. Silent loss is worse than noise.available_sources / available_categories /
available_endpoints) covers the same ground for free — never abandon a signal
because one browsing route was blocked.references/onboarding.md — the Setup-mode interview playbook.references/source-discovery.md — how to find and verify sources in the live
catalog, and how to pick fingerprints and time filters from discover output.references/config-schema.md — monitor config (incl. verified sources[]
specs) and ledger schema.references/storage-backends.md — backend selection and read/write recipes.scripts/ledger.py — deterministic diff, hashing, URL normalization, rolling
window.