`##auto web`: autonomous browser recipes in one markdown file
Write a browser chore down once — YAML budget, markdown task — and it becomes a command you can run, schedule, and trust.
Every recurring browser chore has the same shape: browse → judge → collect → merge → repeat next week. Competitor watching. Speaker sourcing. Listing hunting. Docs auditing. You do it in twenty tabs, paste fragments into a doc, lose the doc, start over.
In rysh, that chore becomes a file. ##auto web turns a markdown recipe into a reusable, budgeted browser automation:
##auto web run competitor-watch "ai terminals"
One command sends an agent into a real, logged-in browser, under hard limits it cannot exceed, and it saves its findings as dated files when it's done. This post is the anatomy of a recipe — and the leash that makes "let it run unattended" a reasonable sentence.
The recipe is a file
##auto web save <name> "<prompt>" is the quick way in, but the real form of an automation is a markdown file with YAML frontmatter under .rysh/automations/webs/. Versionable, reviewable, PR-able:
# .rysh/automations/webs/competitor-watch.md
---
description: Watch competitor changelogs and pricing pages for a topic area.
Read-only; saves a dated findings file.
web_profile: research # persistent, pre-authenticated browser profile
url: https://example.com/start
args: [topic] # run as: ##auto web run competitor-watch "ai terminals"
output_dir: competitor-watch/results
loop:
do: # the INNER loop — one working session
interval: 30
max_iterations: 300
max_duration: 7m
auto_continue: true
budget:
size: 3b # 3 "books" = 600k tokens, hard ceiling
watch:
takeover_when: 90 # at 90% consumed, switch to the wrap-up leg
takeover_prompt: >
Budget is nearly gone — stop browsing now. Save findings as-is,
mark the file PARTIAL at the top, print the path and what to
cover next time.
while: # the OUTER loop — repeat sessions until the GOAL holds
enabled: true
max_iterations: 5
max_duration: 40m
budget: 15b
prompts:
until: >
The findings file covers every competitor on the list, each with a
source URL, a what-changed line, and a date — no duplicates.
iterate_with: >
Continue the watch for {{args}}, same rules. The current findings
are seeded above: cover what's MISSING, merge, save back to the
same file.
---
You are researching public pages about: **{{args}}**.
This is **read-only research** — do not post, message, or interact. If you
hit a login wall you don't own, a captcha, or a rate limit: STOP and report.
For each source collect: URL, what changed since the last file, why it
matters, and a quote or number that backs it up.
When done, write the findings as Markdown to {{output_dir}}/<topic>-<date>.md
and print the saved file path here.
Everything about the job lives next to the goal it protects. The body is the task. The frontmatter is the contract: which browser identity, which start page, what "done" means, how much it may spend, how to stop gracefully. {{args}} templating makes one file a family of automations — competitor-watch "ai terminals" today, competitor-watch "support chatbots" next quarter.
One-time setup: a browser identity that persists
The agent drives a real Chromium, not an HTTP scraper — so it should be logged in the way you are. That's web_profile. You authenticate once, by hand, in a headed browser:
##web headless login research https://example.com/
# a visible browser opens on the "research" profile — log in like a human, close it
The session now lives in that profile, and every future run reuses it — including fully headless runs on a machine with no display:
##auto web run --headless competitor-watch "ai terminals"
Two things worth appreciating about this split: the agent never sees your password (you typed it, once, into a real browser), and the identity is scoped — the research profile is only for research, not your personal everything-browser.
The leash
The reason this can run while you sleep, and not as a horror-story opener:
- Hard budgets. Token budgets use units of pages, books, shelves — a page is 1,000 tokens, a book 200 pages, a shelf 20 books.
size: 3b= 600k tokens per session. A ceiling, not a vibe. Iteration and wall-clock caps stack on top, and flags override per-run:--budget-size 50p --max-duration 10m. - A graceful takeover, not a wall. At
takeover_when: 90, the run switches to thetakeover_promptwith the remaining budget: save partial results, mark them PARTIAL, report what's left. The agent lands the plane instead of hitting one. - An LLM judge decides "done." The outer
whileloop re-enters only if theuntilcondition — checked against the actual saved output — doesn't hold, under its own budget (15b) and session cap. The judge is an LLM: a strong signal, not a proof. Review before you act. - Interruptions are cheap.
##auto web stop competitor-watchmid-run;##auto web continueresumes from the last checkpoint, budget re-armed — not from zero. (How resumption grounds itself on saved state is its own post.) - Behavioral guardrails live in the prompt, where the agent obeys them per step: read-only, stop at walls, stop at rate limits.
And before trusting any of it, rehearse:
##auto web check competitor-watch # lint the recipe
##auto web run --dry-run competitor-watch "x" # print the resolved plan, dispatch nothing
From chore to infrastructure
Once a recipe works, the machinery composes:
# fan out over topics, sequentially
##auto web run --each "ai terminals,support chatbots,agent frameworks" competitor-watch
# put it on a schedule — add `schedule: "0 2 * * 1"` to the frontmatter, then:
##auto web schedule competitor-watch # registers it as a ##cron job
##cron logs # what happened last night?
A notify: block pings a channel when a run ends — via a rysh humanoid, so the "your Monday watch finished, 3 changes found" message lands in Slack or email. And on_success: chains recipes: the watch finishes, a summarizer takes the findings file and drafts the digest for you to review. Drafts. Always drafts.
Results are files, not chat scrollback:
##auto web results competitor-watch # list saved runs
##auto web results competitor-watch ai-terminals-2026-07-13.md
Dated markdown you can diff, review, and commit.
The ethics section (read before you build one)
- Read-only by design. Recipes for other people's platforms forbid messaging, following, posting. The step where a human gets contacted stays human — you read, you decide, you reach out yourself. Automating outreach is how you become spam.
- It stops at walls. Login walls, captchas, rate-limit notices are stop conditions, not puzzles to defeat. The agent reads public pages on sessions you own, at a human-ish pace, under a session cap.
- Your account, your responsibility. Platform terms apply to you, not your tooling. This is a research assistant on your own logged-in browser — treat it that way.
Honest scope
- rysh runs on Claude — bring your own Anthropic key. Provider layer pluggable; Claude is what's wired today.
- rysh is self-hostable (your machine, your keys, your data) — it is not open source.
- Headless works on a server; the one-time
loginneeds a display somewhere, once. ##autois an umbrella — the same save/run/budget/schedule machinery drivestask,agent, andcodeautomations. This post coveredwebonly.
Got a chore shaped like browse → judge → collect → merge? It's probably one recipe file away from being a command. We're recruiting design partners — tell us what you'd point this at and we'll tell you honestly whether it works today. → rysh.ai/design-partner
Companions: Grounded resumption: when a browser agent gets interrupted · Pages, books, and shelves: budget your agents like a library