-
Notifications
You must be signed in to change notification settings - Fork 0
Browser Recipe System
A recipe is a stored sequence of browser tool calls — navigate, wait, click, type, etc. — that you can replay deterministically. Useful for login flows, daily report downloads, repeated form submissions, anything the AI would otherwise re-figure-out every time.
Source: src/main/browser-recipes.ts. Tool: browser_run_recipe.
interface Recipe {
id: string
name: string
description?: string
steps: RecipeStep[]
createdAt: number
updatedAt: number
}
interface RecipeStep {
tool: string // any browser_* tool name
args: Record<string, unknown> // tool-specific arguments
description?: string // free-form annotation
stopOnError?: boolean // default: true
}Steps run sequentially. By default, a failed step aborts the recipe; set stopOnError: false on a step to continue past it (useful for optional steps).
{
"id": "daily-report-download",
"name": "Daily report download",
"description": "Log into dashboard, navigate to today's report, save as CSV",
"steps": [
{
"tool": "browser_navigate",
"args": { "url": "https://dashboard.example/reports/today" },
"description": "Open today's report page"
},
{
"tool": "browser_wait_for_selector",
"args": { "selector": "#download-csv-button", "timeout_ms": 10000 }
},
{
"tool": "browser_click",
"args": { "selector": "#download-csv-button" },
"description": "Trigger CSV download"
},
{
"tool": "browser_wait_for_text",
"args": { "text": "Download complete", "timeout_ms": 30000 },
"stopOnError": false
}
],
"createdAt": 1718000000000,
"updatedAt": 1718000000000
}pane_id is not in the recipe — it's supplied at runtime when the recipe is run. This lets the same recipe target any browser pane.
The model can call:
browser_run_recipe(pane_id, recipe_name)
or inline:
browser_run_recipe(pane_id, steps_json)
For each step:
- Resolve
toolto a registered tool name - Merge
{pane_id}into the step'sargs - Dispatch via
toolRegistry.dispatch(tool, args, ctx) - If error and
stopOnError !== false, halt and return all results so far - Otherwise continue
Returns:
{
success: boolean,
steps: Array<{
index: number,
tool: string,
ok: boolean,
result?: unknown,
error?: string
}>,
stoppedAt?: number // step index that halted the recipe
}Two paths:
Write the JSON by hand, save to <userData>/clusterspace-data/config/recipes/<id>.json (or wherever your recipe store points). Reload.
Use the AI: "Do X step by step, then save it as a recipe called 'daily-report-download'."
The AI executes the actions normally (each tool call gets logged in the AI-Tools-Reference). At the end, it can read the action log and synthesize a recipe from the successful steps:
browser_get_action_log(pane_id, limit=30)
→ AI distills into steps array → calls a save_recipe plugin tool (you'd author)
Currently there's no built-in save_recipe tool — write one as a Plugin-Authoring if you want recording in-app. The simpler manual path is fine for most users.
Recipes are not idempotent by default. If you click "Submit" twice, you submit twice. Build idempotency into the recipe with guard steps:
{
"tool": "browser_query",
"args": { "selector": ".already-submitted-banner" },
"stopOnError": false,
"description": "Skip submit if already done"
}The model can branch on the result, but recipe execution itself is linear — there's no built-in conditional. For complex branching, use the model to drive (a Goal-Runner-Overview with a sequence in its prompt) rather than a recipe.
<userData>/clusterspace-data/clusterspace-recipes.json
One JSON file holds all recipes (keyed by id). Loaded by getRecipeStore() in browser-recipes.ts.
Replace the file to bulk-import; back it up to preserve recipes across machines.
- No conditionals — every step runs unless an earlier step halts
- No loops — for "click N times" use a goal that drives the model
-
No variables / placeholders — args are static JSON. Workaround: have the model construct the recipe inline (
steps_jsonarg) with computed values - No nested recipes — one recipe can't include another. Inline the steps.
- Page state assumed — recipes assume the page is in a known state (e.g., logged in). If preconditions aren't met, steps fail and you stop.
Compared with Goal-Runner-Overview
| Recipe | Goal | |
|---|---|---|
| Execution | Linear, deterministic | Adaptive, model-driven |
| Best for | Repeated identical flows | Outcomes that may require many paths |
| Failure | Halts (default) | Loops, replans |
| Cost | One call per step | Many model + tool calls |
| Verification | Per-step stopOnError
|
End-to-end success criterion |
Use recipes for "do exactly this." Use goals for "achieve this; figure it out."
- Browser-Panes — the panes recipes operate on
- AI-Tools-Reference — the tools recipes can call
-
Plugin-Authoring — add a
save_recipeor other recipe-management tool - Goal-Runner-Overview — for non-linear outcomes
ClusterSpace · Issues · Releases · MIT License · Edit any page via the Edit button (top right of the wiki).
- Workspaces-and-Layout
- Terminal-Panes
- Per-Pane-Tabs
- SSH-and-tmux
- Browser-Panes
- Saved-Logins
- Command-Palette
- Broadcast-Mode
- Settings-and-Configuration
- AI-Overview
- AI-Providers
- AI-Chat-Panel
- AI-Tools-Reference
- Personas
- Skills
- Task-Templates
- Agent-Orchestration
- Fleet-Dashboard
- Goal-Runner-Overview
- Starting-a-Goal
- Success-Criteria
- Goal-Policy-and-Risk-Levels
- Critic-and-Replan
- Vision-Verification
- Goal-Dashboard