ARIA snapshot of the page or a scoped element. Returns a tree with refs (e1, e2, ...) and a refs map.
Use refs in interaction tools: selector "e1" or "@e1" to click/fill that element. Output includes URL, title, and YAML tree.
Refs are valid until next snapshot or navigation. interactiveOnly: only interactive elements get refs; omit for content roles (headings, etc.) too.
cursorInteractive: true adds refs for clickable elements without ARIA (e.g. div with cursor:pointer/onclick).
Use with a11y_take-ax-tree-snapshot for full UI analysis.

Omit structural nodes without content.

Include cursor:pointer / onclick elements.

Only interactive elements get refs.

Max tree depth; 0 = root only.

Scope to this element; omit for full page. If it matches nothing, the full page is returned with a note.

Includes the page URL, title, and a YAML-formatted accessibility tree with [ref=e1] etc.

Map of ref id to { role, name?, selector, nth? }. Use selector "e1" or "@e1" in interaction tools.

Combines Chromium AX tree with runtime visual diagnostics (bounding box, visibility, viewport).
Use to detect: elements with role/name but hidden or off-screen; layout/geometry issues; overlap/occlusion (enable checkOcclusion).
When investigating UI/layout or when clicks fail on seemingly visible elements, set checkOcclusion:true—it uses elementFromPoint()
at center+corners to find what is actually on top. boundingBox is from getBoundingClientRect() (viewport coords; layout box only).
selectorHint is best-effort (data-testid/data-selector/id). Use with a11y_take-aria-snapshot for full UI analysis.

Use elementFromPoint to detect what is on top.

Include bounding box and visibility.

ARIA/AX role names to include; omit for default set. Standard roles: ARIA https://w3c.github.io/aria/#role_definitions, Chromium AX https://chromium.googlesource.com/chromium/src/+/main/ui/accessibility/ax_enum_util.cc (e.g. button, heading, staticText, image, main, navigation). Matching is case-insensitive; "text" also matches staticText, "img" matches image.

display visibility opacity pointer-events position z-index color background-color border-color border-width border-style font-family font-size font-weight line-height letter-spacing text-align text-decoration-line white-space overflow overflow-x overflow-y transform cursor

CSS property names when includeStyles.

Total number of nodes returned by Chromium Accessibility.getFullAXTree before filtering.

Number of DOM-backed AX nodes that passed role filtering before enrichment.

Number of nodes included in the final enriched snapshot output.

List of enriched DOM-backed AX nodes combining accessibility metadata with visual diagnostics.

Unique identifier of the accessibility node within the AX tree.

Chromium backend DOM node identifier used to map AX nodes to DOM elements.

Child AX node ids in the full AX tree (may include nodes not present in the filtered output).

DOM class attribute of the mapped element.

Raw AX description payload associated with the node, if present.

Resolved DOM nodeId from CDP if available; may be null because nodeId is not guaranteed to be stable/resolved.

Frame identifier if the node belongs to an iframe or subframe.

DOM id attribute of the mapped element.

Whether the accessibility node is marked as ignored.

Lowercased DOM tag name of the mapped element (e.g. div, button, input).

Accessible name computed by the browser accessibility engine.

Parent AX node id in the full AX tree. Null if this node is a root.

Additional AX properties exposed by the accessibility tree.

ARIA role of the accessibility node (e.g. button, link, textbox).

Runtime-derived visual information representing how the element is actually rendered.

Height of the element in CSS pixels.

Width of the element in CSS pixels.

X coordinate of the element relative to the viewport.

Y coordinate of the element relative to the viewport.

Bounding box computed at runtime using getBoundingClientRect.

Whether the element intersects the current viewport.

Whether the element is considered visually visible (display, visibility, opacity, and size).

Occlusion detection results. Only present when checkOcclusion=true.

Intersection rect area in CSS pixels squared.

Intersection rect height.

Intersection rect width.

Intersection rect X.

Intersection rect Y.

Intersection box between this element and the occluding element. Null if not occluded or cannot compute.

True if at least one sample point is covered by another element.

Sample points used for occlusion detection (center + corners).

True if elementFromPoint at this point returned a different element that is not a descendant.

Sample point X (viewport coordinates) used for occlusion testing.

Sample point Y (viewport coordinates) used for occlusion testing.

Height of the occluding element bounding box.

Width of the occluding element bounding box.

X coordinate of the occluding element bounding box.

Y coordinate of the occluding element bounding box.

Bounding box of the occluding element (if available).

DOM class of the occluding element (may be null if none).

DOM id of the occluding element (may be null if none).

Tag name of the occluding element.

Best-effort selector hint for the occluding element.

localName id className selectorHint boundingBox

Identity and geometry of the occluding element. Null when not occluded.

samplePoints isOccluded topElement intersection

Best-effort selector hint for targeting this element (prefers data-testid/data-selector/id).

Subset of computed CSS styles for the element as string key-value pairs.

Short preview of rendered text content or aria-label, truncated to the configured maximum length.

Raw AX value payload associated with the node, if present.

axNodeId parentAxNodeId childAxNodeIds role name ignored backendDOMNodeId domNodeId frameId localName id className selectorHint textPreview properties

The document title of the page at the time of the snapshot.

Indicates whether the result set was truncated by an internal safety cap to prevent excessive output size.

The current page URL at the time the AX snapshot was captured.

url title axNodeCount candidateCount enrichedCount truncatedBySafetyCap nodes

Gets the HTML content of the current page.
By default, all <script> tags are removed from the output unless "removeScripts" is explicitly set to "false".

Selector or ref; omit for full document.

The requested HTML content of the page.

Gets the visible text content of the current page.

Truncate after this many characters.

Limit text to this container; omit for full page.

The requested text content of the page.

Saves the current page as a PDF file.

Page size.

Margin (e.g. 1cm).

Background.

Full path of the saved PDF file.

Starts video recording of the browser page.
Recording captures all page interactions until content_stop-recording is called.
Uses Playwright's native screencast API — works in all modes (headless, headed, persistent, CDP attach).
Only supported on Chromium-based browsers.

Name for the video file (without extension). Defaults to "recording".

Directory where the video file will be saved.

Status message.

Wall-clock time (ms since epoch) of the video's first frame. Use this to align video time with other timestamps (logs, network events). A given event's position in the video is `(eventTimestampMs - startTimestamp) / 1000` seconds.

Stops video recording of the browser page and saves the video file.
Must be called after content_start-recording. The video is saved as a WebM file.

Full path of the saved video file.

Takes a screenshot of the current page or a specific element.
Do NOT use for page structure—use ARIA/AX snapshots instead.
Use only for visual verification (design check, visual bug, contrast, layout).
Screenshot is saved to disk; use includeBase64 only when the file cannot be read from the returned path (e.g. remote, container).

Overlay ARIA ref labels.

Annotate headings.

Annotate cursor:pointer elements.

Base64 fallback.

JPEG quality 0–100.

Selector/ref; omit=viewport.

When annotate is true, list of refs and bounding boxes. When selector is set: only annotations overlapping the element, box relative to that element. When fullPage is true: box is document-relative (matches the full-page image). Otherwise: viewport-relative.

Full path of the saved screenshot file.

Image data included only when "includeBase64" input parameter is set to true.

Base64-encoded image data.

MIME type of the image.

Adds a watch expression to be evaluated at every breakpoint hit.
Watch expression results are included in the snapshot's watchResults field.

Examples:
- "user.name"
- "this.state"
- "items.length"
- "JSON.stringify(config)"

Watch expressions are evaluated in the context of the paused frame.

Expression evaluated at every tracepoint hit (e.g. user.name).

The watch expression

Watch expression ID

Status message

Clears snapshots captured by tracepoints, logpoints, and/or exceptionpoints.
Optional `types`: array of `tracepoint`, `logpoint`, `exceptionpoint`. If omitted or empty, clears all.
Optional `probeId`: clear only snapshots for this probe (for tracepoint/logpoint).

Clear only this probe (tracepoint/logpoint).

Clear only these types; omit for all.

Exceptionpoint snapshots cleared

Logpoint snapshots cleared

Status message

Tracepoint snapshots cleared

tracepointCleared logpointCleared exceptionpointCleared message

Removes tracepoints, logpoints, and/or watch expressions. Optional `types`: array of `tracepoint`, `logpoint`, `watches`. If omitted or empty, clears all.

Which probe types to clear: tracepoint, logpoint, watches. If omitted or empty, all are cleared.

Number of logpoints cleared

Status message

Number of tracepoints cleared

Number of watch expressions cleared

tracepointsCleared logpointsCleared watchesCleared message

Retrieves snapshots captured by tracepoints, logpoints, and/or exceptionpoints.
Optional `types`: array of `tracepoint`, `logpoint`, `exceptionpoint`. If omitted or empty, returns all.
Response fields: `tracepointSnapshots`, `logpointSnapshots`, `exceptionpointSnapshots`.
Optional `probeId` filters tracepoint or logpoint snapshots; `fromSequence` and `limit` apply per type.
Output trimming: by default only the top 5 call stack frames are returned, only `local` scope(s) are included, and variables per scope are capped at 20. Override with maxCallStackDepth, includeScopes, maxVariablesPerScope.

Snapshots with sequence > this (polling).

Scope types to include. Default [local] (local only to keep payload small).

global local with closure catch block script eval module wasm-expression-stack

Max call stack frames per snapshot. Default 5.

Max variables per scope. Default 20.

Filter by this probe ID (tracepoint/logpoint).

Return only these types; omit for all.

Exceptionpoint snapshots

Async stack trace

Call stack at exception

Exception information

Exception message

Exception name/class

Stack trace string

Exception type

Watch expression results

id probeId timestamp sequenceNumber url lineNumber captureTimeMs callStack

Logpoint snapshots

Result of log expression evaluation

id probeId timestamp sequenceNumber url lineNumber captureTimeMs

Tracepoint snapshots

Async stack trace

Chain of async segments

Frames in this segment

1-based column number

Function name

1-based line number

Original source location

Script URL

Async boundary (Promise.then, setTimeout, etc.)

Call stack with local variables

1-based column number

Function name

1-based line number

Original source location

Variable scopes

Scope name

Scope type (global, local, closure, etc.)

Variables in this scope

Variable name

Variable type

Variable value

V8 script ID

Script URL

functionName url lineNumber scriptId scopes

Time taken to capture snapshot (ms)

1-based column number

Snapshot ID

1-based line number

Original source location

1-based column number

1-based line number

Original identifier name

Original source file path

Probe ID that triggered this snapshot

Monotonic sequence number for ordering

Unix timestamp (ms)

Script URL where snapshot was taken

Watch expression results

Lists tracepoints, logpoints, and/or watch expressions. Optional `types`: array of `tracepoint`, `logpoint`, `watch`. If omitted or empty, returns all.

List only these types; omit for all.

Logpoints

id urlPattern lineNumber logExpression enabled resolvedLocations hitCount

Tracepoints

id urlPattern lineNumber enabled resolvedLocations hitCount

Watch expressions

Sets the exception tracepoint state:
- "none": Don't capture on exceptions
- "uncaught": Capture only on uncaught exceptions
- "all": Capture on all exceptions (caught and uncaught)

When an exception occurs, a snapshot is captured with exception details.

Current state

Status message

Previous state

Puts a logpoint at the specified location.
When the logpoint is hit, the logExpression is evaluated and the result
is captured in the snapshot's logResult field.

Logpoints are lightweight - they only capture the log expression result,
NOT call stack or watch expressions. Use tracepoints for full debug context.

urlPattern matches script URLs (e.g., "app.js"). Auto-escaped, do not add backslashes.

logExpression: a single JavaScript expression (e.g. "user.name", "JSON.stringify({ a, b })", or "{ discountAmount, finalAmount, n }"). Object literals are supported; for maximum compatibility prefer a single variable or JSON.stringify(...).

Returns resolvedLocations: 0 means pattern didn't match any loaded scripts.

1-based column.

Only log when this expression is true.

Hit-count condition (e.g. > 5).

1-based line in script.

JS expression to evaluate and log (e.g. user.name, JSON.stringify({ a, b }), or { x, y }).

Glob pattern for script URL (e.g. **/app.js).

Column number

Condition expression

Hit count condition

Debug point ID

Line number

Log expression

Number of locations where logpoint was resolved

URL pattern

id urlPattern lineNumber logExpression resolvedLocations

Puts a non-blocking tracepoint at the specified location.
When hit, a snapshot of the call stack and local variables is captured
automatically without pausing execution.

The urlPattern matches script URLs. Special characters are auto-escaped.
Examples:
- "app.js" matches scripts containing "app.js"
- "bundle.min.js" matches scripts containing "bundle.min.js"

DO NOT escape characters yourself (e.g., don't use "app\.js").

Returns resolvedLocations: number of scripts where the tracepoint was set.
If 0, the pattern didn't match any loaded scripts.

1-based column.

Only trigger when this expression is true.

Hit count (e.g. == 5, >= 10, % 10 == 0).

1-based line.

Column number

Condition expression

Hit count condition

Tracepoint ID

Line number

Number of locations where tracepoint was resolved

URL pattern

id urlPattern lineNumber resolvedLocations

Removes a tracepoint, logpoint, or watch expression by ID.
`type`: `tracepoint`, `logpoint`, or `watch`. `id`: the probe or watch ID (from list-probes).

Probe or watch ID from list-probes.

Status message

Whether the probe or watch was removed

Resolves a generated/bundled code location to its original source via source maps.
Useful for translating minified stack traces or bundle line numbers to original TypeScript/JavaScript source.

Requires a page with debugging context (debugging is auto-enabled on first use).
Input: generated script URL, line, column (1-based).
Output: original source path, line, column when a source map is available.

1-based column; default 1.

1-based line in generated code.

Generated script URL (bundle).

Column number in original source (1-based)

Line number in original source (1-based)

Original identifier name if available

Whether the location was resolved to original source

Original source file path

Returns the current debugging status including:
- Whether debugging is enabled
- Source map status
- Exceptionpoint state
- Count of tracepoints, logpoints, and watches
- Snapshot statistics

Whether debugging is enabled

Exceptionpoint state (none, uncaught, all)

Whether source maps are loaded

Number of logpoints

Snapshot statistics

Number of tracepoints

Number of watch expressions

enabled hasSourceMaps exceptionBreakpoint tracepointCount logpointCount watchExpressionCount snapshotStats

execute

Batch-execute multiple tool calls in a single request via custom JavaScript. Reduces round-trips and token usage.

**IMPORTANT**
- The code is already run inside an async function. Pass only the body (statements).
  Do NOT wrap in `async function() { ... }` or `async () => { ... }` — that causes a syntax error.
  Write `await callTool(...); return x;` directly.

**IMPORTANT:**
- `page` (Playwright Page) is available in the VM — use it for navigation or `page.evaluate()`.
- Prefer interaction tools with refs (e1, e2 from a11y_take-aria-snapshot); use raw Playwright only as last resort.
- `document`/`window` are not in the VM — use `page.evaluate(() => { ... })` to run code in the browser.
- Use `waitForNavigation: true` on interaction_click when the click navigates.
- After navigation, do not continue with refs from the previous page — take fresh refs with a11y_take-aria-snapshot first.

Bindings:
- await callTool(name, input, returnOutput?): async — always use with await. Returns the tool output for in-code use.
  Every callTool invocation is listed in the response toolCalls array (name, in order), whether or not returnOutput is set.
  returnOutput=true additionally attaches that call's full output to its toolCalls entry; false (default) lists the call by name only.
  Throws on failure — execution stops at the first error; calls that ran before the failure are still listed in toolCalls (partial), with logs.
  On failure, failedTool in the response identifies which tool caused the error.
  Max 50 callTool invocations per execution.
- console.log/warn/error: captured in the response logs array.
- sleep(ms): async delay.
- args: the parameterization object passed in the `args` input (default {}). Read values via plain JS, e.g. `const { baseUrl } = args;`.

Built-ins: Math, JSON, Date, RegExp, Number, String, Boolean, Array, Object, Promise, Map, Set, WeakMap, WeakSet,
           Symbol, Proxy, Reflect, URL, URLSearchParams, TextEncoder/Decoder, structuredClone,
           crypto.randomUUID(), AbortController, setTimeout/clearTimeout.
NOT available: require, import, process, fs, Buffer, fetch.

**Example** — fill form, submit (with navigation wait), then snapshot and screenshot:
  await callTool('interaction_fill', { selector: 'e3', value: 'user@test.com' });
  await callTool('interaction_fill', { selector: 'e5', value: 'secret123' });
  await callTool('interaction_click', { selector: 'e7', waitForNavigation: true });
  // Or with page.locator: await page.locator('button').click();
  // Or with page.evaluate: await page.evaluate(() => document.querySelector('button').click());
  await callTool('a11y_take-aria-snapshot', {}, true);
  await callTool('content_take-screenshot', {}, true);

Optional parameterization object exposed to the code as the `args` binding (default {}). Opaque — not validated. Read via plain JS, e.g. `const { baseUrl } = args;`.

JavaScript code: the body only (no async function wrapper). Use await callTool(name, input, returnOutput?) and return for result. Do NOT wrap in async function() { ... }.

Wall-clock timeout for the entire execution in ms, including awaited tool calls and sleep (default: 30000, max: 120000).

Error message on failure. Partial toolCalls/logs are still returned.

Present when a callTool invocation caused the error.

Error message from the failed tool.

Tool name that failed.

Captured console.log/warn/error calls.

Return value of the code (JSON-safe). Undefined on error or when nothing is returned.

Complete, ordered list of every nested callTool invocation. Each entry always has `name`; `output` is present only when the call used returnOutput=true; composite calls (scenario-run) expose the inner run as `children`.

Composite calls (scenario-run) expose the inner run's toolCalls here, recursively.

endTime - startTime (ms).

Epoch ms when the call settled.

Tool name (every nested call, in execution order).

Tool output — present only when callTool used returnOutput=true.

Epoch ms when the call started.

Execution id of the scenario STEP this call ran inside, when a scenario-run threaded it via _metadata.stepId. Lets a consumer correlate an internal call to its step.

flush

Waits until this session's async background work (collector events, artifact uploads, scenario step
events) has settled. Call before ending a run or handing off, so everything reported has actually
been sent. Instant no-op when idle.

Max total time to wait before giving up.

Time actually spent waiting.

True when the timeout hit while work was still pending.

Number of background tasks that were in flight.

Clicks an element. Accepts selector or ref (e.g. e1, @e1). Set waitForNavigation: true when the click opens a new page — waits for navigation then for network idle so snapshot/screenshot see full content.

Draw a ripple at the click point so the click is visible in recordings. Defaults to whether a screen recording is running.

CSS selector or ref from a11y snapshot (e.g. e1, @e1).

Wait for element, ms. Default 10000.

Wait for navigation triggered by click (parallel with click). Use when click opens a new page.

Timeout for navigation and for network idle wait (ms). Only when waitForNavigation is true. Default 30000.

Drags an element to a target location. Accepts CSS selectors or refs (e.g. e1, @e1) from the last ARIA snapshot.

Draw a box around the element so the action is visible in recordings. Defaults to whether a screen recording is running.

CSS selector or ref for the element to drag.

CSS selector or ref for the drop target.

Wait for elements, ms. Default 10000.

Fills out an input field. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).

CSS selector or ref from a11y snapshot for the input.

Wait for element, ms. Default 10000.

Hovers an element on the page. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).

CSS selector or ref from a11y snapshot.

Wait for element, ms. Default 10000.

Presses a keyboard key with optional "hold" and auto-repeat behavior.

Key facts:
- keyboard.press(key, { delay }) does NOT trigger OS-style auto-repeat.
- Some UI behaviors (especially scrolling) require repeated keydown events.
- Use repeat=true + holdMs to approximate real keyboard holding.

Execution logic:
- If selector is provided, the element is focused first.
- If holdMs is omitted or repeat=false:
  → a single keyboard.press() is executed.
- If holdMs is provided AND repeat=true:
  → keyboard.press() is called repeatedly until holdMs elapses.

Ms between keydown and keyup.

Key name (e.g. Enter, ArrowDown, Space).

Repeat key while holdMs (e.g. for scroll).

Focus this element first; omit for page focus.

Resizes the PAGE VIEWPORT using Playwright viewport emulation (page.setViewportSize).

This affects:
- window.innerWidth / window.innerHeight
- CSS media queries (responsive layouts)
- Layout, rendering and screenshots

Notes:
- This does NOT resize the OS-level browser window.
- Runtime switching to viewport=null (binding to real window size) is not supported by Playwright.
  If you need real window-driven responsive behavior, start the BrowserContext with viewport: null
  and use the window resize tool instead.

Requested viewport configuration.

Requested viewport height (CSS pixels).

Requested viewport width (CSS pixels).

Viewport metrics observed inside the page after resizing.

window.devicePixelRatio after resize.

window.innerHeight after resize (CSS pixels).

window.innerWidth after resize (CSS pixels).

window.outerHeight after resize (CSS pixels).

window.outerWidth after resize (CSS pixels).

innerWidth innerHeight outerWidth outerHeight devicePixelRatio

Resizes the REAL BROWSER WINDOW (OS-level window) for the current page using Chrome DevTools Protocol (CDP).

This tool works best on Chromium-based browsers (Chromium/Chrome/Edge).
It is especially useful in headful sessions when you run with viewport emulation disabled (viewport: null),
so the page layout follows the OS window size.

Important:
- If Playwright viewport emulation is enabled (viewport is NOT null), resizing the OS window may not change page layout.
- On non-Chromium browsers (Firefox/WebKit), CDP is not available and this tool will fail.

Required when state=normal.

When not normal, width/height may be ignored.

Required when state=normal.

Window bounds after resizing.

Window height after resizing.

Window left position after resizing.

Window state after resizing.

Window top position after resizing.

Window width after resizing.

CDP window id for the current target.

Window bounds before resizing.

Window height before resizing.

Window left position before resizing.

Window state before resizing.

Window top position before resizing.

Window width before resizing.

CDP window id for the current target.

Requested window change parameters.

Requested window height (pixels). Null if not provided.

Requested window state.

Requested window width (pixels). Null if not provided.

Page viewport metrics after resizing (helps verify responsive behavior).

window.devicePixelRatio after resizing.

window.innerHeight after resizing (CSS pixels).

window.innerWidth after resizing (CSS pixels).

window.outerHeight after resizing (CSS pixels).

window.outerWidth after resizing (CSS pixels).

Scrolls the page viewport or a specific scrollable element.

Modes:
- 'by': Scrolls by a relative delta (dx/dy) from the current scroll position.
- 'to': Scrolls to an absolute scroll position (x/y).
- 'top': Scrolls to the very top.
- 'bottom': Scrolls to the very bottom.
- 'left': Scrolls to the far left.
- 'right': Scrolls to the far right.

Use this tool to:
- Reveal content below the fold
- Jump to the top/bottom without knowing exact positions
- Bring elements into view before clicking
- Inspect lazy-loaded content that appears on scroll

by=dx,dy; to=x,y; or edge (top/bottom/left/right).

Scrollable container: ref (e.g. from latest <a11y_take-aria-snapshot>), getBy… expression, or CSS. Omit for viewport.

Scroll metrics after the scroll action.

Viewport/container client height after scrolling.

Viewport/container client width after scrolling.

Total scrollable height after scrolling.

Total scrollable width after scrolling.

ScrollLeft after scrolling.

ScrollTop after scrolling.

x y scrollWidth scrollHeight clientWidth clientHeight

Scroll metrics before the scroll action.

Viewport/container client height before scrolling.

Viewport/container client width before scrolling.

Total scrollable height before scrolling.

Total scrollable width before scrolling.

ScrollLeft before scrolling.

ScrollTop before scrolling.

The scroll behavior used.

Whether horizontal scrolling is possible (scrollWidth > clientWidth).

Whether vertical scrolling is possible (scrollHeight > clientHeight).

Whether the scroll position is at the very bottom.

Whether the scroll position is at the far left.

Whether the scroll position is at the far right.

Whether the scroll position is at the very top.

Maximum horizontal scrollLeft (scrollWidth - clientWidth).

Maximum vertical scrollTop (scrollHeight - clientHeight).

The scroll mode used.

The selector of the scroll container if provided; otherwise null (document viewport).

mode selector behavior before after canScrollX canScrollY maxScrollX maxScrollY isAtLeft isAtRight isAtTop isAtBottom

Select an option in a dropdown. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).

Draw a box around the element so the action is visible in recordings. Defaults to whether a screen recording is running.

CSS selector or ref from a11y snapshot for the dropdown.

Wait for element, ms. Default 10000.

Navigates to the previous or next page in history.
- `direction: "back"` — previous page in history.
- `direction: "forward"` — next page in history.

In case of multiple redirects, the navigation will resolve with the response of the last redirect.
If cannot go back/forward, returns empty response.

By default (includeSnapshot: true), an ARIA snapshot with refs is returned. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false), same as a11y_take-aria-snapshot.

When `includeScreenshot: true`, the screenshot is always saved to disk; `screenshotFilePath` is returned. By default `outputPath` is the OS temp dir and `name` is "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the returned path (e.g. remote, container).

Take a screenshot after navigation; saved to disk (default: OS temp dir). Use includeBase64 only when file cannot be read from path.

Return ARIA snapshot with refs.

Options when includeScreenshot is true. Same semantics as <content_take-screenshot> (outputPath/name default to tmp and "screenshot").

Overlay ARIA ref labels on the screenshot. Default: true.

Capture full scrollable page. Default: true.

Include base64 image in response; use only when file cannot be read from path (e.g. remote, container).

Base name for the screenshot file. Default: "screenshot".

Directory to save the screenshot. Default: OS temp dir.

Image format. Default: png.

Options when includeSnapshot is true. Same as <a11y_take-aria-snapshot>.

Include cursor:pointer / onclick elements. Default false.

Only interactive elements get refs. Default false (content roles like headings also included).

Max wait ms. 0=no timeout.

Wait for navigation then for network idle before snapshot/screenshot. Default true.

Timeout for navigation and network idle wait (ms). Only when waitForNavigation is true. Default 30000.

Playwright navigation lifecycle: when the main frame reaches this state. Does not use Playwright networkidle; use waitForNavigation for session network-idle after history navigation.

When includeScreenshot and screenshotOptions.includeBase64 are true: image sent as separate image content part.

Base64-encoded image data.

MIME type of the image.

Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.

When includeScreenshot is true: full path of the saved screenshot file.

Contains the status code of the navigated page (e.g., 200 for a success).

Contains the status text of the navigated page (e.g. usually an "OK" for a success).

Contains the URL of the navigated page.

Navigates to the given URL.
**NOTE**: The tool either throws an error or returns a main resource response.
The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash,
which would succeed and return empty response.

**By default** (`includeSnapshot: true`), an ARIA snapshot with refs is taken after navigation and returned in `output` and `refs`; you can use refs (e1, e2, ...) in interaction tools without calling a11y_take-aria-snapshot separately. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false). Set `includeSnapshot: false` to get only url/status/ok.

When `includeScreenshot: true`, the screenshot is always saved to disk; `screenshotFilePath` is returned. By default `outputPath` is the OS temp dir and `name` is "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the returned path (e.g. remote, container).

Return ARIA snapshot with refs after nav.

Image format. Default: png.

Max wait ms. 0=no timeout.

Playwright navigation lifecycle: when the main frame reaches this state. Does not use Playwright networkidle; use waitForNavigation for session network-idle after navigation.

When includeScreenshot and screenshotOptions.includeBase64 are true: image sent as separate image content part.

Base64-encoded image data.

MIME type of the image.

Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.

When includeSnapshot is true: page URL, title, and ARIA tree with refs.

When includeSnapshot is true: map of ref id (e1, e2, ...) to role/name/selector for use in interaction tools.

When includeScreenshot is true: full path of the saved screenshot file.

Contains the status code of the navigated page (e.g., 200 for a success).

Contains the status text of the navigated page (e.g. usually an "OK" for a success).

Contains the URL of the navigated page.

Reloads the current page.
In case of multiple redirects, the navigation resolves with the response of the last redirect.
If the reload does not produce a response, returns empty response.

By default (includeSnapshot: true), an ARIA snapshot with refs is returned. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false), same as a11y_take-aria-snapshot.

When `includeScreenshot: true`, the screenshot is saved to disk; `screenshotFilePath` is returned. Default path/name: OS temp dir and "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the path.

Take a screenshot after reload; saved to disk (default: OS temp dir).

Return ARIA snapshot with refs.

Options when includeScreenshot is true. Same semantics as <content_take-screenshot> (outputPath/name default to tmp and "screenshot").

Overlay ARIA ref labels on the screenshot. Default: true.

Capture full scrollable page. Default: true.

Include base64 image in response; use only when file cannot be read from path (e.g. remote, container).

Base name for the screenshot file. Default: "screenshot".

Directory to save the screenshot. Default: OS temp dir.

Image format. Default: png.

Options when includeSnapshot is true. Same as <a11y_take-aria-snapshot>.

Include cursor:pointer / onclick elements. Default false.

Only interactive elements get refs. Default false (content roles like headings also included).

Max wait ms.

Wait for reload then for network idle before snapshot/screenshot. Default true.

Timeout for reload and network idle wait (ms). Only when waitForNavigation is true. Default 30000.

Playwright navigation lifecycle: when the main frame reaches this state. Does not use Playwright networkidle; use waitForNavigation for session network-idle after reload.

When includeScreenshot and screenshotOptions.includeBase64 are true: image sent as separate image content part.

Base64-encoded image data.

MIME type of the image.

Contains a boolean stating whether the reloaded page was successful (status in the range 200-299) or not.

When includeScreenshot is true: full path of the saved screenshot file.

Contains the status code of the reloaded page (e.g., 200 for a success).

Contains the status text of the reloaded page (e.g. usually an "OK" for a success).

Contains the URL of the reloaded page.

Retrieves console messages/logs from the browser with filtering options.

Keep from start or end when truncating.

Filter by message text.

Incremental: only messages with sequence > this.

Only messages at or after this Unix ms.

Filter by level (this level or higher).

Retrieved console messages.

Console message item.

Location of the console message in the resource.

0-based column number in the resource.

0-based line number in the resource.

URL of the resource.

A monotonically increasing sequence number assigned to each console message.
It reflects the order in which messages were captured and can be used by clients
to retrieve messages incrementally by requesting only those with a higher sequence
number than the last one received.

Text of the console message.

Unix epoch timestamp (in milliseconds) of the console message.

Type of the console message.

Retrieves HTTP requests from the browser with filtering options.

Include request headers in each item. Default false.

Include response body in each item. Default false.

Include response headers in each item. Default false.

Keep from start or end when truncating.

2xx only.

Type filter.

document stylesheet image media font script texttrack xhr fetch eventsource websocket manifest other

Incremental: only requests with sequence > this.

HTTP status range.

Only requests at or after this Unix ms.

Retrieved HTTP requests.

HTTP request item.

HTTP request body if available. Secret JSON keys are redacted; truncated to BROWSER_HTTP_CAPTURE_BODY_MAX_BYTES.

HTTP request duration in milliseconds. "-1" if not available (no response).

Error message of the HTTP request if failed.

HTTP request headers as key-value pairs. Present when includeRequestHeaders was true.

HTTP request method. Valid values are: GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS

Flag to represent whether the HTTP request successful or failed.
An HTTP request is considered successful only if its status code is 2XX.
Otherwise (non-2XX status code or no response at all because of timeout, network failure, etc ...) it is considered as failed.

HTTP request resource type as it was perceived by the rendering engine.
Valid values are: document,stylesheet,image,media,font,script,texttrack,xhr,fetch,eventsource,websocket,manifest,other

HTTP response.

HTTP response body if available. Present when includeResponseBody was true. Secret JSON keys are redacted; truncated to BROWSER_HTTP_CAPTURE_BODY_MAX_BYTES.

HTTP response headers. Present when includeResponseHeaders was true.

HTTP response status code.

HTTP response status text.

A monotonically increasing sequence number assigned to each HTTP request.
It reflects the order in which requests were captured and can be used by clients
to retrieve requests incrementally by requesting only those with a higher sequence
number than the last one received.

Unix epoch timestamp (in milliseconds) of the HTTP request.

HTTP request url.

url method resourceType timestamp sequenceNumber

Reads every log record recorded under an IronBee session back from the platform — across all its
traces — optionally narrowed to one activity and then one verification. Ids default to the current
session / activity / verification, so the usual call takes no arguments. Use <o11y_get-trace-logs>
for a single correlated request, <o11y_get-session-traces> for the spans of the same scope.

Narrow to one activity of that session.

Keep records whose body contains this (case-insensitive).

summary: time/severity/body/service (+ spanId when present). attributes: + the record attributes (log.source, console.method, …). full: + resourceAttributes and instrumentationScope.

Page size, 1-1000. Server default 1000.

Keep records at or above this OTLP severity (9=INFO, 13=WARN, 17=ERROR).

Records to skip.

Keep records whose service name contains this (case-insensitive).

Session id (UUID). Defaults to the current session.

Narrow further to one verification — requires `activityId`.

Keep polling (1s interval) for up to this long while nothing is found — records are ingested asynchronously. Max 120000.

Records returned. 0 with hasMore=false means nothing matched (records not ingested yet read the same way).

Records at ERROR severity or above (>= 17).

More records exist past this page.

Ordered by time.

`offset` for the next page; present only when hasMore.

sessionId count hasMore services errorCount logs

Reads every span recorded under an IronBee session back from the platform — across all its traces —
optionally narrowed to one activity and then one verification. Ids default to the current session /
activity / verification, so the usual call takes no arguments. Use <o11y_get-trace> for a single
correlated request instead.

Narrow to one activity of that session.

summary: identity/timing/status (+ traceState/links when present). attributes: + the span attributes, status message, events. full: + resourceAttributes and instrumentationScope.

Page size, 1-1000. Server default 1000.

Keep spans at least this long.

Spans to skip.

Keep spans whose service name contains this (case-insensitive).

error: keep only failed spans.

Keep polling (1s interval) for up to this long while nothing is found — spans are ingested asynchronously. Max 120000.

Spans returned. 0 with hasMore=false means nothing matched (a trace that has not been ingested yet reads the same way).

More spans exist past this page.

Ordered by start time. Flat by design — a filtered/paged page is missing parents, so nesting it would invent roots; use `parentSpanId` to rebuild the tree.

spanId name startTimeUnixNano endTimeUnixNano durationMs

sessionId count hasMore services errorCount spans

Reads one distributed trace back from the IronBee platform: every span every service recorded under
`traceId`, as a waterfall tree. Defaults to the trace this call is already correlated to, then to the
one pinned by <o11y_new-trace-id> / <o11y_set-trace-context> — so the usual flow is pin -> drive the app
-> call this with no arguments.
Spans are ingested asynchronously; use `waitMs` right after an action.

Page size, 1-1000. Server default 1000.

Keep spans at least this long.

Spans to skip.

error: keep only failed spans.

32-hex trace id. Defaults to the correlated trace, then the session pin.

More spans exist past this page.

traceId count hasMore services errorCount spans

Returns the session's currently pinned W3C trace context: the pinned `traceId` / `traceState` (each
present only when set — a trace is pinned iff at least one is returned). Pin one with <o11y_new-trace-id>
or <o11y_set-trace-context>.

Pinned W3C trace id, when set.

Pinned W3C tracestate, when set.

Reads the log records of one distributed trace back from the IronBee platform: browser console output
and app logs recorded under `traceId`. Defaults to the trace this call is already correlated to, then
to the pinned one — the usual call takes no arguments. Use <o11y_get-trace> for the spans of the same
trace. Records are ingested asynchronously; use `waitMs` right after an action.

Keep records whose body contains this (case-insensitive).

summary: time/severity/body/service (+ spanId when present). attributes: + the record attributes (log.source, console.method, …). full: + resourceAttributes and instrumentationScope.

Page size, 1-1000. Server default 1000.

Keep records at or above this OTLP severity (9=INFO, 13=WARN, 17=ERROR).

Records to skip.

Keep records whose service name contains this (case-insensitive).

Keep polling (1s interval) for up to this long while nothing is found — records are ingested asynchronously. Max 120000.

Records returned. 0 with hasMore=false means nothing matched (records not ingested yet read the same way).

Records at ERROR severity or above (>= 17).

More records exist past this page.

Ordered by time.

`offset` for the next page; present only when hasMore.

traceId count hasMore services errorCount logs

Collects Web Vitals (LCP, INP, CLS, TTFB, FCP) with Google thresholds and recommendations.
Call after navigation or user actions; use waitMs for more stable LCP/CLS/INP.
Some metrics may be unavailable depending on browser and interactions.

Include entry counts and LCP element hint.

Ms to wait before reading (e.g. let LCP settle).

Optional debug details.

Counts of PerformanceEntry types used to compute metrics.

Count of event timing entries.

Count of layout-shift entries.

Count of largest-contentful-paint entries.

Count of navigation entries.

Count of paint entries.

navigation paint lcp layoutShift eventTiming

Best-effort selector hint for the last LCP element (if available).

Tag name of the last LCP element (if available).

Actual wait duration used before reading metrics.

waitMs entries lastLcpSelectorHint lastLcpTagName

Raw metric values (null if unavailable).

Cumulative Layout Shift score.

First Contentful Paint in milliseconds.

Interaction to Next Paint in milliseconds (best-effort approximation).

Largest Contentful Paint in milliseconds.

Time to First Byte in milliseconds.

Notes about metric availability, browser limitations, and interpretation.

Ratings computed from Google thresholds.

CLS rating.

FCP rating.

INP rating.

LCP rating.

Rating based on Google thresholds.

Thresholds used for rating.

Upper bound for the "good" rating.

Lower bound for the "poor" rating.

Unit of the metric.

Metric value (null if unavailable).

TTFB rating.

Recommendations based on the measured values and their ratings.

Recommendations for improving CLS.

True if all Core Web Vitals are rated "good".

Recommendations for improving FCP.

General measurement and debugging notes.

Recommendations for improving INP.

Recommendations for improving LCP.

High-level summary and prioritization guidance.

Recommendations for improving TTFB.

coreWebVitalsPassed summary lcp inp cls ttfb fcp general

Unix epoch timestamp (ms) when the metrics were captured.

Current page title.

Current page URL.

url title timestampMs metrics ratings recommendations notes

Generates a fresh W3C / OpenTelemetry-compatible trace id (32 hex chars) and pins it on the session so
subsequent calls share one correlation root — the platform propagates it into outgoing requests. Use
<o11y_set-trace-context> to pin a specific id / tracestate, or <o11y_get-trace-context> to inspect the
current pin.

The newly generated, now-pinned 32-hex W3C trace id.

Sets or clears the session-pinned W3C trace context. Two independent slots:

  - `traceId`: hex string up to 32 chars (short ids are zero-padded by the platform). Empty string clears
    the pinned trace id. Must not be all-zero.
  - `traceState`: opaque W3C `tracestate` value (comma-separated key=value list). Empty string clears.

At least one of `traceId` / `traceState` must be supplied; omitted fields are left untouched. Use
<o11y_new-trace-id> to generate one, or <o11y_get-trace-context> to inspect the current pin.

Hex string up to 32 chars to pin, or empty string to clear. Omit to leave unchanged.

W3C tracestate value to pin, or empty string to clear. Omit to leave unchanged.

The resulting pinned trace id (post-set), if any.

The resulting pinned tracestate (post-set), if any.

Finds React component(s) for a DOM element via React Fiber (best-effort). Give selector or (x,y); we resolve the element,
find __reactFiber$ on it or ancestors, then build the component stack from the host fiber that owns that node.
Fiber is not a public API—results vary by dev/prod build; names can be displayName, wrappers, or minified.
wrappersDetected/wrapperFrames help with memo/forwardRef/context. If hostMapping.strategy is ancestor-fallback,
use a more specific selector or deeper node for better accuracy.

If true, includes a best-effort, truncated props preview for the nearest component.

Maximum characters for props preview (after safe stringification).

Target element; takes precedence over x/y.

Viewport X when selector omitted.

Viewport Y when selector omitted.

DOM hint of the element where fiber pointer was found (target or ancestor).

Whether the initial fiber pointer was found directly on the target element.

Whether we found the exact host fiber for target element (fiber.stateNode === targetEl) via subtree scan.

Mapping strategy used to produce the final stack.

Maximum fiber nodes allowed to scan (safety cap).

Number of fiber nodes scanned during subtree search.

DOM hint of the actual target element.

fiberOnTargetElement anchorDomHint targetDomHint hostFiberMatchedTarget subtreeScanNodesScanned subtreeScanMaxNodes strategy

detected detectionReason fiberKey hostMapping nearestComponent componentStack componentStackText wrappersDetected wrapperFrames notes

selector point found domHint elementPath

Maps a React component instance to the DOM elements it renders (DOM footprint) by traversing the Fiber graph.
Prefer an anchor (anchorSelector or anchorX/anchorY) to target the instance; optionally add a query
(componentName, fileNameHint, lineNumber) to search Fiber. With both, we rank candidates and pick the best match near the anchor.
React DevTools hook gives reliable root discovery (getFiberRoots); without it we fall back to DOM scan for __reactFiber$ (best-effort).
For more reliable roots in a persistent browser, install the React Developer Tools Chrome extension.
Debug source is best-effort and may be missing in some builds.

Anchor selector/ref.

Viewport X when anchorSelector omitted.

Viewport Y when anchorSelector omitted.

File hint.

Ranked candidate matches (best-first).

score nameMatched debugSourceMatched anchorRelated

name displayName debugSource componentStack selection domFootprintCount

name displayName debugSource componentStack selection

tagName id className selectorHint textPreview boundingBox isVisible isInViewport

True if DOM appears to contain React Fiber pointers (__reactFiber$...).

True if __REACT_DEVTOOLS_GLOBAL_HOOK__ looks available.

How roots were discovered.

reactDetected fiberDetected rootDiscovery component candidates elements notes

scenario-add

Adds a new scenario. A scenario is a reusable JS script (like execute) that can call tools via callTool().
Scenarios are stored on disk as one file per scenario (project-level by default, or global with scope="global").
Optionally declare a params contract (name + optional description/type/default/example/required): the script reads each param via the args binding, defaults are applied when a run omits the arg, and declared types are shallow-validated by <scenario-run>. Without params, args stays fully opaque.
An optional free-form metadata object is persisted and returned verbatim (devtools never interprets it).
The store also stamps createdAt / updatedAt timestamps automatically.

The scenario itself — the steps that run between `setup` and `teardown`. When present this is the authoritative run form and the legacy `script` field is ignored. On update, a provided body replaces the stored one wholesale; omit to keep it.

Ordered steps (script/command/llm-action/include). Each llm-action needs a unique name.

REQUIRED and unique among siblings — a group exists to be named, and its name is what a reader sees in the path.

Any step kind, groups included.

Sandbox JS: callTool/console/sleep/args/ctx/assert available.

Optional stable, unique name (else the index).

When set, the tool's output is stored at ctx[assignTo]. Without it the output is not kept (outputs are routinely tens of KB).

Tool input. Values may carry {{args.<path>}} / {{ctx.<path>}} references, resolved at run time: a whole-value reference preserves type, an embedded one stringifies, an unresolved one fails the step.

Bare tool name, exactly what callTool takes (e.g. bdt_navigation_go-to). Never templated.

When true a non-zero exit does not fail the step.

Store the {stdout,stderr,exitCode} result at ctx[assignTo].

Host shell command (build/migrate/seed).

Natural-language intent handed to the agent.

Required stable name — its cache is keyed by it (unique within the scenario).

Args for the ref's params — literal or `{{args.x}}` from parent args.

Optional ctx namespace: the part's ctx roots at ctx[as].

Scenario name to include (project→global).

Description of what this scenario does.

Step-schema version (forward-compat guard). A value beyond what this build supports is rejected on write.

Opaque free-form metadata, persisted and returned verbatim (devtools never interprets it). On update it is applied as a JSON Merge Patch (RFC 7386) — send ONLY the keys that change: objects merge recursively, a null value DELETES that key, an array or scalar replaces it, and any key you omit is left untouched. So you never need to read-then-resend the whole object, and you cannot accidentally drop keys another writer owns (this field is shared space).

Unique scenario name (used as key).

Optional declared parameter contract. Each entry: name (the arg key) plus optional description/type/default/example/required. Defaults are applied when the caller omits an arg; a required param with no value and no default rejects the run; object/array are shallow-validated (kind only). On update, a provided array replaces the stored one wholesale; omit to keep the existing params. Declaring params is opt-in — a scenario with no params keeps fully-opaque args passthrough.

Applied when the caller omits this arg; for object/array it also doubles as the concrete shape example.

Documentation-only concrete example (never validated/injected).

Arg key read inside the script.

Reject the run when no value and no default. Default false.

Declared kind (string/number/boolean/object/array). Absent → no type check. object/array are shallow-validated (top-level kind only).

Platforms this scenario needs to run at all (browser / backend / node / python / android / terminal). Checked BEFORE any step — including setup — so a scenario that cannot work on this server says so up front instead of failing mid-run with "tool not found". Declare every platform any phase touches; an included scenario's requirements are unioned in automatically.

Storage scope (default: project).

Legacy single-script form. Same sandbox as <execute>: use await callTool(name, input, returnOutput?). Omit when providing `steps`.

Steps run BEFORE the body to establish what the scenario needs (app up, fixture seeded). Requires `steps`. Background a long-running process with its output REDIRECTED (`npm start > app.log 2>&1 &`) — an inherited stdout pipe keeps the step open until it times out.

Ordered script/tool-call/command steps. llm-action and include are not allowed here.

Whether this section runs when the scenario is REUSED (included, or invoked by a nested scenario-run). Default "skip" — two scenarios that both want the app up would otherwise start it twice. Ignored on the entry scenario.

Steps run AFTER the body however it ended, to undo what the run created. Does not fail fast: every step runs even if an earlier one failed, and a failure here is reported without changing the run verdict.

Arg key read inside the script.

name description script createdAt updatedAt

scenario-delete

Deletes a scenario by name.

Name of the scenario to delete.

Storage scope (default: project).

Whether the scenario was found and deleted.

scenario-list

Lists scenarios. When scope is omitted, returns scenarios from both project and global scopes (project overrides global for same name).
Optionally filter by metadataMatch: a subset/containment filter over the opaque metadata (a partial template the stored metadata must contain). Objects match recursively (extra sibling keys are ignored), arrays require the stored array to contain all listed elements, a scalar against a stored array uses membership, and scalars use equality. Keys are never interpreted (devtools-agnostic). Use this to find scenarios by what they cover, e.g. metadataMatch={"ironbee":{"coveredPaths":["src/auth/login.ts"]}}.

Subset/containment filter over the opaque metadata — a partial template the stored metadata must contain. Objects match recursively (a query key must exist; extra sibling keys are ignored), so { "ironbee": { "coveredPaths": ["src/auth/login.ts"] } } matches metadata that also has other ironbee.* keys. Arrays require the stored array to contain all listed elements; a scalar against a stored array uses membership; scalars use equality. All top-level keys must match (AND); keys are never interpreted. Omit for no filter.

Filter by scope. Omit to list from both (project overrides global).

Arg key read inside the script.

scenario-recorded-actions

Returns the platform tool calls recorded since the current <scenario-run> llm-action pause began ([{seq,toolName,input}], _metadata stripped).
Use it while resolving an llm-action to reconstruct a clean, deterministic cache script (drop exploration/failed attempts, keep order). Empty when no llm-action pause is active. Only platform calls are recorded — scenario-* / execute / this tool are excluded.

Optional scenario name (advisory).

Recorded platform calls, in order.

scenario-run

Runs a saved scenario by name (project scope first, then global).

A scenario is either a single legacy JS script or an ordered list of steps
(script / command / llm-action / include). Script steps run in the same sandbox as
execute (callTool/console/sleep/args), share a mutable ctx object, and can use
an assert binding for mechanical checks. command steps run a host shell command.
include steps expand another scenario inline. An llm-action step is a natural-language
intent the agent resolves: the run PAUSES (status:'paused', with pendingStep + ctxSnapshot),
the agent performs the intent with its own tools, then calls scenario-run again with
resume:true (+ resumeOutput / cache) to continue. Once resolved, the realization is
cached in a sibling <name>.cache.json and future runs replay it without pausing (warm);
a broken cache self-heals by pausing again.

Pass args to parameterize the run; declared params are validated. stepByStep pauses
after every step; refresh ignores cache; persistCache:false skips writing the cache.
Scenarios can compose others via callTool('scenario-run', ...) (no pausing when nested;
an unresolved llm-action there is a hard error). Max recursion depth: 5.

Parameterization exposed to script steps as `args`. Validated against the scenario's declared params. Latched at fresh-run start; ignored on resume.

Freeze the just-resolved llm-action's realization script into the sibling cache file.

The llm-action's deterministic realization (sandbox JS).

Name of the scenario to run.

CLI ergonomics: repeatable key=value pairs (the --param flag), coerced to declared param types and merged over `args`.

Write the authored cache to disk (default true).

Ignore cache: true → all llm-actions; [name,…] → matching source names.

Resume this scenario's paused run in this session (continues from the pending step).

The completed llm-action's output — merged into ctx (plain object, or a JSON-object string, → shallow merge; anything else → ctx._resume).

Pause after every step (default false).

Wall-clock timeout in ms (default: 30000).

The absolute open-step stack after this call (outermost → innermost); [] on a terminal run.

Applied when the caller omits this arg; for object/array it also doubles as the concrete shape example.

Documentation-only concrete example (never validated/injected).

Arg key read inside the script.

Reject the run when no value and no default. Default false.

Declared kind (string/number/boolean/object/array). Absent → no type check. object/array are shallow-validated (top-level kind only).

Screen recordings captured for this run (file paths). Present only on the terminal response of a recorded run.

Per-execution run id (stable across pauses/resumes); read by ironbee-cli to correlate and finalize the run. Top-level step runs only.

Per-call step-timeline delta (step_start/step_end transitions since the last response), replayed by ironbee-cli. Each lifecycle phase's steps hang under a synthetic phase ROOT span named <setup> / <main> / <teardown> — the only parentless steps of a run. Top-level step runs only.

Why teardown steps failed, if any did. Separate from `error` on purpose: a failed cleanup does not mean the scenario failed.

Nested calls made by script/warm-cache steps in THIS response (ordered).

Composite calls (scenario-run) expose the inner run's toolCalls here, recursively.

endTime - startTime (ms).

Epoch ms when the call settled.

Tool name (every nested call, in execution order).

Tool output — present only when callTool used returnOutput=true.

Epoch ms when the call started.

Execution id of the scenario STEP this call ran inside, when a scenario-run threaded it via _metadata.stepId. Lets a consumer correlate an internal call to its step.

scenario-search

Full-text search over scenario name + description across both project and global scopes.
Uses configurable search strategy (SEARCH_STRATEGY or SCENARIO_SEARCH_STRATEGY env var).
Returns matching scenarios (including their metadata) ranked by relevance.
Optionally narrow the corpus with metadataMatch (subset/containment over the opaque metadata) before ranking — e.g. text-search only among scenarios that cover a given path. For a pure metadata lookup with no text query, use scenario-list with metadataMatch.

Maximum number of results (default: 10).

Search query.

Arg key read inside the script.

name description script createdAt updatedAt score

scenario-update

Updates an existing scenario's description, script, params, and/or metadata.
Write semantics differ between the two, deliberately. params is a wholesale replace: a provided array replaces the stored one (that is how you reorder or drop an entry); omit it to keep the current contract. metadata is a JSON Merge Patch (RFC 7386): send only the keys that change — objects merge recursively, a null value deletes that key, an array/scalar replaces it, omitted keys survive. Metadata is shared space (IronBee's ironbee.* keys alongside the user's own), so patching is what keeps one writer from silently dropping another's. The store refreshes updatedAt automatically.

Ordered steps (script/command/llm-action/include). Each llm-action needs a unique name.

REQUIRED and unique among siblings — a group exists to be named, and its name is what a reader sees in the path.

Any step kind, groups included.

Sandbox JS: callTool/console/sleep/args/ctx/assert available.

Optional stable, unique name (else the index).

When set, the tool's output is stored at ctx[assignTo]. Without it the output is not kept (outputs are routinely tens of KB).

Tool input. Values may carry {{args.<path>}} / {{ctx.<path>}} references, resolved at run time: a whole-value reference preserves type, an embedded one stringifies, an unresolved one fails the step.

Bare tool name, exactly what callTool takes (e.g. bdt_navigation_go-to). Never templated.

When true a non-zero exit does not fail the step.

Store the {stdout,stderr,exitCode} result at ctx[assignTo].

Host shell command (build/migrate/seed).

Natural-language intent handed to the agent.

Required stable name — its cache is keyed by it (unique within the scenario).

Args for the ref's params — literal or `{{args.x}}` from parent args.

Optional ctx namespace: the part's ctx roots at ctx[as].

Scenario name to include (project→global).

New description (omit to keep current).

Step-schema version (forward-compat guard). A value beyond what this build supports is rejected on write.

Name of the scenario to update.

Applied when the caller omits this arg; for object/array it also doubles as the concrete shape example.

Documentation-only concrete example (never validated/injected).

Arg key read inside the script.

Reject the run when no value and no default. Default false.

Declared kind (string/number/boolean/object/array). Absent → no type check. object/array are shallow-validated (top-level kind only).

Storage scope (default: project).

New script (omit to keep current).

Ordered script/tool-call/command steps. llm-action and include are not allowed here.

Steps run AFTER the body however it ended, to undo what the run created. Does not fail fast: every step runs even if an earlier one failed, and a failure here is reported without changing the run verdict.

Arg key read inside the script.

Clears stubs installed.

- If stubId is provided, clears only that stub.
- If stubId is omitted, clears all stubs for the current session/context.

Remove this stub; omit to clear all.

Number of stubs removed.

Installs a request interceptor stub that can modify outgoing requests before they are sent.

Use cases:
- A/B testing / feature flags (inject headers)
- Security testing (inject malformed headers / payload)
- Edge cases (special characters, large payload)
- Auth simulation (add API keys / tokens in headers)

Notes:
- pattern is a glob matched against the full request URL (picomatch).
- This modifies requests; it does not change responses.
- times limits how many times the interceptor applies (-1 means infinite).

Changes to apply to the request.

Override method (e.g. GET, POST).

URL glob (picomatch).

Max applications; -1 = infinite.

Applied artificial delay in milliseconds.

Whether the stub is enabled.

Stub kind.

Glob pattern.

Unique id of the installed stub.

Max applications (-1 means infinite).

stubId kind pattern enabled delayMs times

Lists currently installed stubs for the active browser context/session.
Useful to debug why certain calls are being mocked/intercepted.

For mock_response: fulfill/abort.

Artificial delay in ms.

Whether stub is enabled.

Stub id.

Stub kind.

Glob pattern (picomatch).

For mock_response: HTTP status (if set).

Max applications (-1 means infinite).

How many times it has been applied.

id kind enabled pattern delayMs times usedCount

Installs a response stub for matching requests using glob patterns (picomatch).

Use cases:
- Offline testing (return 200 with local JSON)
- Error scenarios (force 500/404 or abort with timedout)
- Edge cases (empty data / huge payload / special characters)
- Flaky API testing (chance < 1.0)
- Performance testing (delayMs)

Notes:
- pattern is a glob matched against the full request URL.
- stubs are evaluated in insertion order; first match wins.
- times limits how many times the stub applies (-1 means infinite).

Probability 0–1; omit=always.

URL glob.

Response.

Error code when action=abort.

Max times to apply; -1=infinite.

Applied action.

Apply probability (omit means always).

Whether the stub is enabled.

Stub kind.

Glob pattern.

HTTP status (present when action=fulfill).

Unique id of the installed stub (use it to clear later).

Max applications (-1 means infinite).

stubId kind pattern enabled delayMs times action

Waits until the page is network-idle: in-flight requests <= maxConnections for at least idleTimeMs (server-side tracking, no page globals).
Use before SPAs, screenshots, or AX snapshots for stable results. With long-polling, increase maxConnections or use shorter idleTimeMs.

Network must stay idle for this many ms to resolve.

Idle when in-flight requests <= this.

Polling interval ms.

Max wait ms before failing.

The last observed number of in-flight requests at the moment the tool returned.

Idle duration required for success (milliseconds).

Idle threshold used: in-flight requests must be <= this value.

How long the in-flight request count stayed <= maxConnections right before returning (milliseconds).

Polling interval used to sample the in-flight request count (milliseconds).

Maximum allowed wait time (milliseconds).

Total time waited until the network became idle or the tool timed out (milliseconds).

waitedMs idleTimeMs timeoutMs maxConnections pollIntervalMs finalInFlightRequests observedIdleMs


get-current-date

获取当前日期，以上海时区（Asia/Shanghai, UTC+8）为准，返回格式为 "yyyy-MM-dd"。主要用于解析用户提到的相对日期（如“明天”、“下周三”），提供准确的日期输入。

get-interline-tickets

查询12306中转余票信息。尚且只支持查询前十条。

查询日期，格式为 "yyyy-MM-dd"。如果用户提供的是相对日期（如“明天”），请务必先调用 `get-current-date` 接口获取当前日期，并计算出目标日期。

最早出发时间（0-24），默认为0。

返回结果格式，默认为text，建议使用text。可选标志：[text, json]

出发地的中文名或站点的 `station_code`（可通过 `get-station-code-by-names` 或 `get-station-code-of-citys` 接口查询得到）

最迟出发时间（0-24），默认为24。

返回的中转余票数量限制，默认为10。

中转地的中文或站点的 `station_code`（可通过 `get-station-code-by-names` 或 `get-station-code-of-citys` 接口查询得到）。该参数可选。

是否显示无座车，默认不显示无座车。

排序方式，默认为空，即不排序。仅支持单一标识。可选标志：[startTime(出发时间从早到晚), arriveTime(抵达时间从早到晚), duration(历时从短到长)]

是否逆向排序结果，默认为false。仅在设置了sortFlag时生效。

到达地的中文名或站点的 `station_code`（可通过 `get-station-code-by-names` 或 `get-station-code-of-citys` 接口查询得到）

车次筛选条件，默认为空。从以下标志中选取多个条件组合[G(高铁/城际),D(动车),Z(直达特快),T(特快),K(快速),O(其他),F(复兴号),S(智能动车组)]

get-station-by-telecode

通过车站的 `station_telecode` 查询车站的详细信息，包括名称、拼音、所属城市等。此接口主要用于在已知 `telecode` 的情况下获取更完整的车站数据，或用于特殊查询及调试目的。一般用户对话流程中较少直接触发。

车站的 `station_telecode` (3位字母编码)

get-station-code-by-names

通过具体的中文车站名查询其 `station_code` 和车站名。

具体的中文车站名称，例如："北京南", "上海虹桥"。若要查询多个站点，请用|分割，比如"北京南|上海虹桥"。

get-station-code-of-citys

通过中文城市名查询代表该城市的 `station_code`。

要查询的城市，比如"北京"。若要查询多个城市，请用|分割，比如"北京|上海"。

get-stations-code-in-city

通过中文城市名查询该城市 **所有** 火车站的名称及其对应的 `station_code`，结果是一个包含多个车站信息的列表。

中文城市名称，例如："北京", "上海"

get-tickets

查询12306余票信息。

最早出发时间（0-24），默认为0。

返回结果格式，默认为text，建议使用text与csv。可选标志：[text, csv, json]

最迟出发时间（0-24），默认为24。

返回的余票数量限制，默认为0，即不限制。

是否逆向排序结果，默认为false。仅在设置了sortFlag时生效。

车次筛选条件，默认为空，即不筛选。支持多个标志同时筛选。例如用户说“高铁票”，则应使用 "G"。可选标志：[G(高铁/城际),D(动车),Z(直达特快),T(特快),K(快速),O(其他),F(复兴号),S(智能动车组)]

get-train-route-stations

查询特定列车车次在指定区间内的途径车站、到站时间、出发时间及停留时间等详细经停信息。当用户询问某趟具体列车的经停站时使用此接口。

列车出发的日期 (格式: yyyy-MM-dd)。如果用户提供的是相对日期，请务必先调用 `get-current-date` 解析。

要查询的车次 `train_code`，例如"G1033"。


Delete Confluence resources. Returns TOON format by default.

**Output format:** TOON (default) or JSON (`outputFormat: "json"`)

**Common operations:**
- `/wiki/api/v2/pages/{id}` - Delete page
- `/wiki/api/v2/blogposts/{id}` - Delete blog post
- `/wiki/api/v2/pages/{id}/labels/{label-id}` - Remove label
- `/wiki/api/v2/footer-comments/{id}` - Delete comment
- `/wiki/api/v2/attachments/{id}` - Delete attachment

Note: Most DELETE endpoints return 204 No Content on success.

API reference: https://developer.atlassian.com/cloud/confluence/rest/v2/

JMESPath expression to filter/transform the response. IMPORTANT: Always use this to extract only needed fields and reduce token costs. Examples: "results[*].{id: id, title: title}" (extract specific fields), "results[0]" (first result), "results[*].id" (IDs only). See https://jmespath.org

Output format: "toon" (default, 30-60% fewer tokens) or "json". TOON is optimized for LLMs with tabular arrays and minimal syntax.

The Confluence API endpoint path (without base URL). Must start with "/". Examples: "/wiki/api/v2/spaces", "/wiki/api/v2/pages", "/wiki/api/v2/pages/{id}"

Optional query parameters as key-value pairs. Examples: {"limit": "25", "cursor": "...", "space-id": "123", "body-format": "storage"}

Confluence DELETE Request

Read any Confluence data. Returns TOON format by default (30-60% fewer tokens than JSON).

**IMPORTANT - Cost Optimization:**
- ALWAYS use `jq` param to filter response fields. Unfiltered responses are very expensive!
- Use `limit` query param to restrict result count (e.g., `limit: "5"`)
- If unsure about available fields, first fetch ONE item with `limit: "1"` and NO jq filter to explore the schema, then use jq in subsequent calls

**Schema Discovery Pattern:**
1. First call: `path: "/wiki/api/v2/spaces", queryParams: {"limit": "1"}` (no jq) - explore available fields
2. Then use: `jq: "results[*].{id: id, key: key, name: name}"` - extract only what you need

**Output format:** TOON (default, token-efficient) or JSON (`outputFormat: "json"`)

**Common paths:**
- `/wiki/api/v2/spaces` - list spaces
- `/wiki/api/v2/pages` - list pages (use `space-id` query param)
- `/wiki/api/v2/pages/{id}` - get page details
- `/wiki/api/v2/pages/{id}/body` - get page body (`body-format`: storage, atlas_doc_format, view)
- `/wiki/rest/api/search` - search content (`cql` query param)

**JQ examples:** `results[*].id`, `results[0]`, `results[*].{id: id, title: title}`

API reference: https://developer.atlassian.com/cloud/confluence/rest/v2/

Confluence GET Request

Partially update Confluence resources. Returns TOON format by default.

**IMPORTANT - Cost Optimization:** Use `jq` param to filter response fields.

**Output format:** TOON (default) or JSON (`outputFormat: "json"`)

**Common operations:**

1. **Update space:** `/wiki/api/v2/spaces/{id}`
   body: `{"name": "New Name", "description": {"plain": {"value": "Desc", "representation": "plain"}}}`

2. **Update comment:** `/wiki/api/v2/footer-comments/{id}`

Note: Confluence v2 API primarily uses PUT for updates.

API reference: https://developer.atlassian.com/cloud/confluence/rest/v2/

Request body as a JSON object. Structure depends on the endpoint. Example for page: {"spaceId": "123", "title": "Page Title", "body": {"representation": "storage", "value": "
Content
"}}

Confluence PATCH Request

Create Confluence resources. Returns TOON format by default (token-efficient).

**IMPORTANT - Cost Optimization:**
- Use `jq` param to extract only needed fields from response (e.g., `jq: "{id: id, title: title}"`)
- Unfiltered responses include all metadata and are expensive!

**Output format:** TOON (default) or JSON (`outputFormat: "json"`)

**Common operations:**

1. **Create page:** `/wiki/api/v2/pages`
   body: `{"spaceId": "123456", "status": "current", "title": "Page Title", "parentId": "789", "body": {"representation": "storage", "value": "<p>Content</p>"}}`

2. **Create blog post:** `/wiki/api/v2/blogposts`
   body: `{"spaceId": "123456", "status": "current", "title": "Blog Title", "body": {"representation": "storage", "value": "<p>Content</p>"}}`

3. **Add label:** `/wiki/api/v2/pages/{id}/labels` - body: `{"name": "label-name"}`

4. **Add comment:** `/wiki/api/v2/pages/{id}/footer-comments`

API reference: https://developer.atlassian.com/cloud/confluence/rest/v2/

Confluence POST Request

Replace Confluence resources (full update). Returns TOON format by default.

**IMPORTANT - Cost Optimization:**
- Use `jq` param to extract only needed fields from response
- Example: `jq: "{id: id, version: version.number}"`

**Output format:** TOON (default) or JSON (`outputFormat: "json"`)

**Common operations:**

1. **Update page:** `/wiki/api/v2/pages/{id}`
   body: `{"id": "123", "status": "current", "title": "Updated Title", "spaceId": "456", "body": {"representation": "storage", "value": "<p>Content</p>"}, "version": {"number": 2}}`
   Note: version.number must be incremented

2. **Update blog post:** `/wiki/api/v2/blogposts/{id}`

Note: PUT replaces entire resource. Version number must be incremented.

API reference: https://developer.atlassian.com/cloud/confluence/rest/v2/

Confluence PUT Request


Bump the SemVer spec_version field of a spec's frontmatter and record a history entry. Use "patch" for typos/formatting, "minor" for new criteria or scope expansion, "major" for breaking interpretatio…

Actor identifier (session id, plugin id, username). Defaults to a session token.

Bump kind: patch (typo/format), minor (new criterion/scope expansion), major (breaking change).

Project ID (hash). Required if projectPath is not provided.

Absolute path to the project root. Takes precedence over projectId.

Free-text reason for the bump (min 5 chars). Recorded in history.

Spec ID to bump, e.g. SPEC-042.

Stress-test a plan by simulating failures, high traffic, and edge cases. Finds weak spots before you start building — like a fire drill for your feature design.…

Focus areas for the challenge

Challenge focus: failures | concurrency | scale | security | data-consistency

failures concurrency scale security data-consistency

Project ID hash. Prefer projectPath — stays correct after context compaction.

Absolute path to project root. Derives projectId automatically — always correct even after context c…

Spec ID to challenge

Check if a plan has enough detail to start building. Verifies that the description is complete, acceptance criteria are clear, and all dependencies are met.…

Evaluation mode: strict (default) requires score >=70; lenient requires >=60

Project ID hash. Prefer projectPath.

Absolute path to project root. Derives projectId automatically.

Spec ID to evaluate

total completeness testability ambiguity risk grade

Create a full SDD spec from a description. Call this directly — no need to run clarify_requirements first.…

SPEC-224: Format for acceptance criteria in spec.md.…

SPEC-697: Agent team findings from parallel domain-expert agents.…

Markdown findings from the agent. Max 300 words.

Role identifier matching one of the agentTeamPlan roles (e.g. "react-expert")

SPEC-584: Answers to pending interactiveQuestions from the previous call.…

Detailed description of the feature or change. Max 10000 chars.…

Feature group tag (e.g. "Authentication", "Billing"). Added to tags for categorization.…

[SPEC-722] Host/agent platform identifier (e.g. "claude-code", "cursor").…

Stable caller key. Retries return the exact committed create_spec result.

[SPEC-722] Model ID of the planner (e.g. "claude-opus-4-5").

Explicit user-confirmed out-of-scope items for this spec.

Absolute path to the project root. Auto-detected from git root when omitted.

Spec scope (default: feature)

trivial feature cross-module architectural

[SPEC-722] Session ID of the current LLM session. Used to issue a planner token that a reviewer sess…

SPEC-697: Spec ID for agent team findings synthesis. Required when agentTeamFindings is provided.

Tags for categorization

Target area: frontend, backend, shared, fullstack, infrastructure, database

frontend backend shared fullstack infrastructure database ios android

Title of the spec / user story

Spec type (default: feature)

feature refactor bugfix infra docs project agent tech-debt

estimate

Calculate how much time, effort, and cost it will take to build a feature based on its plan. Gives you hours of development work, estimated AI token costs, and a confidence level based on similar past…

Project ID

Spec ID to estimate

devHours reviewHours totalHours recommendedModel tokensOpus tokensSonnet apiCostUsd humanCostUsd totalCostUsd tokenOptimization

specId difficulty estimation tokenStrategy historyUsed

facilitate

Universal SDD workflow entry point (SPEC-037 + SPEC-264). Classifies intent, loads project context, routes intelligently: trivial/exploration → direct answer; feature → create_spec; in-progress → resu…

Human-readable new app name

Safe folder name for the new app; must not contain path separators

Explicitly declare a new session objective

Check whether this request is aligned with the current session focus

Answers to interactiveQuestions emitted by facilitate

Answers collected in previous steps

When true in new_project flow, create only the resolved child project folder

User-confirmed database, null for no database

Free-form description: what you want to build, your problem, or your request

User-confirmed framework, null for no framework

User-confirmed programming language

Parent workspace path that should contain a new project folder

Plan Mode output to convert into a spec. Paste the plan markdown here to extract ACs and route to cr…

Runtime or deployment platform

Project ID or project path (used for context loading and focus persistence)

Kind of project to create

Override auto-detected scenario. Valid values: new_project, existing_project, concrete_problem

Session ID (overrides projectId for focus tracking)

Current step index for new_project flow (0–2)

Planu tool name to check ambiguity for before calling it

Get Durable Job

Read the durable state and latest checkpoint or result for a local Planu job.

Initialize a project — detects language, framework, architecture, and stores project knowledge. IMPORTANT: Only call this tool if planu/ does NOT exist in the project directory.…

Human-readable app name for new_project

Safe folder slug for new_project; must not contain path separators

Explicit named authorization for repository-content migration during an update.…

Auto-install recommended skills into .claude/skills/ during init (default: true).…

SPEC-584: Answers to pending interactiveQuestions from the previous call.…

When true with mode=new_project, create only the resolved projectPath directory

User-confirmed database

Developer experience level: beginner, intermediate, or expert

User-confirmed framework

Developer hourly rate in USD for cost estimation

User-confirmed language

Preferred locale for this project

Onboarding mode. Defaults to existing_project for backwards compatibility.

Parent workspace path for explicit new_project onboarding

SPEC-594: Opt-in — configure .claude/settings.json permissions during init.…

Runtime/deployment platform

SPEC-596: Opt-in — register Anthropic marketplace + install plugins during init.…

Absolute path to the project root

Type of project being initialized

Approved TechnologySelectionContract returned by facilitate new_project flow

User profile type — determines how detailed and technical Planu interactions will be.…

developer product-owner designer non-technical

Preferred interaction style: guided (step-by-step hints for SDD newcomers) | standard (normal workfl…

List Specs

Show all the plans (specs) in your project. You can filter by status — for example, only show plans that are still in draft, or only the ones already approved and ready to build.…

Response detail level: summary (default, returns id/title/status/type/tags as markdown table) | full…

Project ID (hash). Prefer projectPath if unknown.

Absolute path to the project root. Used to derive projectId automatically.

Filter by spec status

draft review approved implementing done discarded

Filter by spec type

specId specTitle specContext criterionText score reason

specId currentStatus releasedInVersion commitSha suggestedAction

byStatus byType totalDevHours totalReviewHours totalCostUsd

projectId filters count totalCount specs summary message

Migrate Legacy Spec

Persist a host-LLM-synthesized spec.md body and retire the legacy files it replaces: each retired file/directory is backed up with a timestamped .bak copy, deleted, and git-untracked.…

Paths relative to the spec folder to back up, delete, and git-untrack (files or directories)

Full replacement content for spec.md, synthesized by the host LLM from the retired content-bearing l…

Absolute path to the project root containing planu/specs

Spec identifier, e.g. "SPEC-1570"

Submit Durable Handoff Packaging

Submit a durable job that builds a complete instruction package so an AI agent can implement a feature.…

Project ID hash. Prefer projectPath.

Absolute path to project root. Derives projectId automatically.

Spec ID to generate handoff package for

When this request attached to the job.

Content-derived observation cursor.

Tool to poll for job progress and result.

Tool to reactivate a terminal-failed job.

Deterministic durable job id, form handoff-<sha256 hex>.

Canonical project identity.

Jobs ahead of this one in the same scope.

Worker concurrency capacity for this scope.

1-based queue position, null once terminal.

Remaining execution budget in ms.

Queue lifecycle bucket.

status position aheadCount capacity remainingBudgetMs

Present when the reused job ended terminal-failed/cancelled/dead-letter and needs restart_job.

Result payload schema id once completed.

True when this request attached to an existing job instead of inserting a new one.

Ack schema version.

Current durable job state at submission or reuse time.

accepted running checkpointed completed failed cancelled dead-letter

When this job was first accepted.

The states get_job should treat as terminal.

Durable job workspace scope.

schemaVersion operationId projectId workspaceId state submittedAt attachedAt reused cursor queue terminalStates resultSchema observation

Get a compact world-snapshot of the current Planu project state in one call: active spec (in-progress), next recommended spec (highest-priority approved), queue count, git state (staged/modified files…

Project ID (optional — derived from projectPath if omitted)

Absolute path to project root

Update a plan to match what was actually built. When the code changes during development, this tool brings the plan back in sync with reality.…

Auto-detect changes from implementation (default: true)

Manual changes to apply

section originalValue newValue reason approved

When the spec is implementing, routes reconcile_spec into the existing implementing→review reconcili…

Drift kind. Only "architectural-premise" is supported: an orchestrator-declared premise contradictio…

Why the implementation drifted from the approved architectural premise.…

Enable living spec mode: compare acceptance criteria against codebase, auto-mark criteria as met/pen…

Project ID hash. Prefer projectPath.

Absolute path to project root. Derives projectId automatically.

Spec ID to reconcile

Request Changes

Request changes on a spec. The spec is moved back to draft and prior approvals are cleared. A comment explaining the required changes is mandatory.

Required explanation of what needs to change before re-approval.

Absolute path to the project root.

Name, email, or username of the reviewer requesting changes.

Role of the reviewer (e.g. "tech-lead", "qa").

Spec ID to request changes on (e.g. SPEC-042).

Restart Durable Job

Restart a cancelled or failed durable job and schedule its typed executor.

Session Checkpoint

Persist a compact, bounded session checkpoint to planu/session-context.md for the next session.

Move a plan forward in its lifecycle. Plans go through these stages: draft (work in progress) → review (ready for someone to check) → approved (ready to build) → implementing (being built) → done (fin…

Actual metrics for status = done. All fields optional (SPEC-1356): missing numeric fields default to…

Arbiter identity/evidence required before status=done.

SHA-256 hash of the persisted context package used to prove context continuity across agents.

SPEC-731: Non-destructive preview mode. Runs all gates but does NOT write to disk, append to transit…

Force transition to done bypassing DoD gates. Use when validate already confirmed the spec is ready…

SPEC-769: Force-approve a spec that scored below 70 on the readiness gate.…

Bypass auto-validate score check when marking a spec as done.…

SPEC-721: Required when forceStatus=true. ≥100 characters explaining why validate gate is bypassed.

External handoff artifact ID when the host stores handoff evidence outside the filesystem.

Path to the persisted handoff package generated by package_handoff.…

SHA-256 of the exact validation-report.json bytes. Required implementation evidence for status=done;…

Concrete model ID used for this transition. Can satisfy SDD model-routing evidence when it maps to t…

SDD model tier evidence for this phase: max for approval/arbitration, implementation for coding, rev…

Project ID (hash). Prefer projectPath if unknown.

Absolute path to the project root. Used to derive projectId automatically.

SPEC-733: Required for reverse transitions (done→implementing, discarded→draft).…

Set true when implementation drift requires reconcile_spec before status=done; true blocks done.

Trusted local MCP only: lowercase UUID idempotency key for implementing to review reconciliation.

Feedback or observations when sending a spec back (e.g., review→draft).…

Reviewer identity/evidence required before status=done.

Agent/session ID performing this lifecycle transition.

Spec ID to update

New status

Batch update many specs to the same status in one MCP execution. Uses the same transition rules as update_status and reports updated/skipped/failed per spec.

Preview the batch without mutating any spec.

Arbitrator identity for this spec.

Context hash for this spec.

Handoff artifact ID for this spec.

Handoff artifact path for this spec.

Model ID used for this spec.

Model tier used for this spec.

Reviewer identity for this spec.

Per-spec model-routing evidence keyed by spec ID. Required for status approved or implementing: each…

Project ID, if known

Absolute project root. Preferred when projectId is unknown.

Optional notes for each transition.

Spec IDs to update

New status for all specs. Batch supports draft, review, approved, implementing, and discarded; close…

draft review approved implementing discarded

validate

Submit Durable Validation

Check how much of a plan has actually been built. Compares the blueprint (spec) with the real code and tells you: what percentage is done, what files are missing, and whether the code matches the plan…

Persist validation as a durable background job.

Spec ID to validate

True when this request attached to an already-running validation job instead of dispatching new work.