Cookbook
Multi-tool recipes — patterns that chain two or three tools to answer a question no single tool would. The entries on tools.md → What it answers are single-call examples; this page shows composition.
Each recipe lists the calls in order, the data flow between them, and what the final result tells you.
Recipe 1 — Cross-spec lookup: which ECMA-262 ops does Intl reach into?
When you want to map how the Internationalization API interacts with the core language, you want every reference from an ECMA-402 clause that resolves to an ECMA-262 abstract operation.
Calls:
// 1. Pick the 402 entry point you care about (e.g. Intl.Collator's compare).
spec.crossrefs({
id: "sec-intl.collator.prototype.compare",
spec: "402",
direction: "out",
include_cross_spec: true,
})The outgoing array now contains both 402-internal references and the 262 abstract operations the clause cites (spec: "262" rows distinguished from spec: "402" ones).
Variations:
- For the symmetric query — "every 402 clause that gets called from 262" — use
direction: "in"on a known shared op (ToNumber,RequireObjectCoercible). - To enumerate every 402 → 262 hop in one pass, run
clause.list({ spec: "402" })then loopspec.crossrefsover each id and aggregate.
Recipe 2 — Prose drift: how did ToNumber change over the past year?
Track the prose-level history of one clause across upstream commits.
Calls:
// 1. Recent edits to the clause's opening tag in main:
spec.history({ id: "sec-tonumber", limit: 50 })
// 2. For each adjacent pair of editions you care about, diff the clause:
spec.diff({ id: "sec-tonumber", from: "es2024", to: "es2025" })
spec.diff({ id: "sec-tonumber", from: "es2025", to: "main" })spec.history gives commit SHAs + dates that touched the id="sec-tonumber" token. spec.diff returns status ('modified' / 'identical' / etc.) plus per-field diffs (title, signature, step count, notes, crossrefs).
Why it matters: the history alone tells you when something changed; the per-edition diffs tell you what.
Recipe 3 — From notation to definition: what is [[Realm]]?
You see [[Realm]] mentioned in step text and want both the defining clause and the clauses that read/write that slot.
Calls:
// 1. Classify the notation and find candidate definitions.
spec.symbol_resolve({ notation: "[[Realm]]" })
// → kind: "internal-slot", name: "Realm", hits: [{ id, title, score, … }]
// 2. For the top-ranked hit, pull the full clause for context.
clause.get({ id: <hits[0].id> })
// 3. Optionally: list every clause that mentions this slot.
spec.search({ query: "Realm", search_steps: true, limit: 50 })Variations:
- Replace the notation with
%Object.prototype%to chase a well-known intrinsic;spec.symbol_resolveclassifies it asintrinsicand ranksspec.tables({ id: "table-well-known-intrinsic-objects" })rows accordingly. - For
~enumerate~-style sigil hints, the classification flips tosigil-enum.
Recipe 4 — test262 coverage for one clause
Given a clause id, find the test262 tests that target it.
Calls:
// 1. Confirm the clause exists and grab its aoid.
clause.get({ id: "sec-tonumber" })
// 2. Search the local test262 index by esid.
test262.search({ esid: "sec-tonumber", limit: 100 })
// 3. For one or two interesting hits, fetch the full source.
test262.get({ path: <hits[0].path> })test262.search's esid field is prefix-matched, so sec-tonumber will catch nested ids like sec-tonumber-applied-to-the-string-type without you specifying every variant.
Why it matters: combined with spec.diff (Recipe 2) you can spot clauses where the prose changed but no test262 case followed.
Recipe 5 — Cross-reference a non-terminal's SDOs and productions
For a syntactic non-terminal, find every Syntax-Directed Operation that implements it.
Calls:
// 1. The standalone grammar productions defining the non-terminal.
spec.grammar({ nonterminal: "BindingIdentifier" })
// 2. The SDOs covering productions of that non-terminal.
spec.sdo_index({ by: "production", filter: "BindingIdentifier" })
// 3. (Optional) Pull one SDO's full algorithm for context.
clause.get({ id: <sdo_index.groups[<production>][0].id> })The intersection tells you which SDOs every productions of the non-terminal participates in (Evaluation, BoundNames, LexicallyDeclaredNames, …). Useful for spotting an SDO that's missing a production case.
Recipe 6 — Map a Stage-3 proposal to the clauses it would touch
When triaging a proposal close to landing, you want a rough surface area of the spec it would change.
Calls:
// 1. Find the proposal metadata + slug.
proposal.list({ stage: "3" })
// 2. Pick one and read its full entry.
proposal.get({ name: <slug> })
// 3. For a hand-picked keyword from the proposal title, search the spec.
spec.search({ query: "<keyword>" })The proposal index has no machine-readable mapping back to clause ids — but the slug + name + champion list usually gives you enough of a keyword to drive spec.search against main and surface the clauses most likely to need edits.
Adding your own recipe
Recipes that recur are good candidates for promotion to single-call tools. If you find yourself running the same 3-call sequence over and over, that's a signal — open an issue. The contract for a new tool is in AGENTS.md: read-only, deterministic over pinned data, no execution, no auth.