Skip to content

Latest commit

 

History

History
939 lines (721 loc) · 42.4 KB

tools-reference.md

File metadata and controls

939 lines (721 loc) · 42.4 KB

Tools Reference

Victauri exposes 35 MCP tools organized into standalone tools (one action per call) and compound tools (multiple actions via an action parameter).

All tools are accessible via MCP at /mcp or REST at POST /api/tools/{tool_name}.

Common parameters. Every tool that touches a webview accepts webview_label (aliases window, window_label) to pick the window; without it the default window is used (main, else the first visible one). Every compound tool takes a required action string naming the operation.

Backend Tools

These tools access the Rust backend directly — no webview proxy, no JavaScript evaluation.

app_info

Get application configuration, directory paths, environment, discovered databases, and process info.

Parameters: None required.

Returns: {config, paths, databases, process, environment}


list_app_dir

Browse files in app backend directories (data, config, log, local_data).

Parameters:

Name Type Required Description
directory string no One of: data, config, log, local_data (default: data)
path string no Subdirectory to list within the chosen directory
pattern string no Glob to filter entries (e.g. *.db)
max_depth number no Recursion depth (default: 1)

Returns: {root, entries: [{name, path, is_dir, size, modified}]}

A listing stops (and reports truncated) at 10,000 returned entries, 100,000 examined entries, or 5 s — whichever comes first — so a pattern that matches nothing in a huge tree still returns.


read_app_file

Read a file from one of the app's backend directories.

Parameters:

Name Type Required Description
path string yes File path relative to the directory root
directory string no One of: data, config, log, local_data (default: data)
max_bytes number no Max bytes to read (default: 1 MB)
binary boolean no Return base64 instead of UTF-8 text

Returns: UTF-8 text, or base64-encoded bytes when binary is true. Path-traversal-guarded. A read truncated at max_bytes in the middle of a multi-byte character drops the partial character and stays UTF-8 text.


query_db

Execute a read-only SQL query against a SQLite database in the app's data directory.

Parameters:

Name Type Required Description
query string yes SQL query — SELECT/PRAGMA(read)/EXPLAIN/WITH only
path string no Path to the database file (auto-discovers if omitted)
params array no Positional bind parameters
max_rows number no Max rows to return (default 100)

Examples:

{"query": "SELECT * FROM users WHERE active = ?", "params": [true]}
{"query": "SELECT count(*) FROM items", "path": "app.db"}

Returns: {columns, rows, row_count, truncated, max_rows}

Limits: a 5 MB result budget charged cell by cell (the result is truncated rather than built past it), at most 256 result columns, 1 MB per value, LIKE/GLOB patterns up to 1000 bytes, a 5 s CPU deadline, a 1 s wait for a lock held by the app, and at most two database calls (query_db / db_health) running at once — a third gets a "busy" error. Duplicate result column names get :N keys (a, a:1) so no value is lost; columns lists exactly the keys each row carries. A single string function (LIKE, replace, instr) is one uninterruptible SQLite step, so a pathological call can overrun the deadline by seconds on its worker thread; the tool call itself returns at the deadline.

Read-only and path-traversal-guarded: writes (INSERT/UPDATE/…), stacked queries, ATTACH, and the write form of PRAGMA (PRAGMA x = y) are rejected. By default only the OS app-data directories are searched; if your app stores its DB elsewhere (a project/working dir or custom path), register the directory via VictauriBuilder::db_search_paths(["../data", "/abs/path"]) — then relative names and absolute paths within those roots become reachable.


Webview & IPC Tools

eval_js

Evaluate JavaScript in the webview and return the result.

Parameters:

Name Type Required Description
code string yes JavaScript code to evaluate (expressions, statements, or async/await)
webview_label string no Target webview (defaults to "main" or first visible)

Examples:

{"code": "document.title"}
{"code": "document.querySelectorAll('button').length"}
{"code": "await fetch('/api/data').then(r => r.json())"}

Auto-return: a single bare expression is auto-wrapped with return (document.title → return document.title). Multi-statement code must include an explicit return — e.g. localStorage.setItem('k','v'); return localStorage.getItem('k') — or be wrapped in an IIFE; otherwise only the first statement runs. async/await is supported.

JavaScript errors (thrown exceptions) return an MCP error with isError: true. undefined returns "undefined", null returns null. A syntax error is reported at once as a JavaScript parse error ("the code did not begin executing") — code reported that way never runs later. A result JSON cannot represent (a circular object, a BigInt, a function) is reported as "the code ran, but its result could not be serialized", never as a JavaScript error. A page reload under the call fails it promptly. Targeting a hidden or unresponsive window fails fast (~2s); and if a prior eval timed out, the next call re-probes and fails fast if the webview reloaded or the app stopped responding.


dom_snapshot

Capture a full accessible DOM tree with ref handles for every element.

Parameters:

Name Type Required Description
webview_label string no Target webview
format string no compact (default, accessible text, ~70-80% fewer tokens) or json (full tree)

Returns: Tree of elements with ref, role, name, children, and bounding box data. Descends into open shadow DOM and same-origin iframes (cross-origin frames are marked and skipped).


find_elements

Search for elements by CSS selector or text content. Returns an MCP error for invalid CSS selectors. Searches into open shadow roots and same-origin iframes — frame elements get ref handles and are fully interactable.

Parameters:

Name Type Required Description
selector string no CSS selector (alias: css). Invalid selectors return an error.
text string no Text content to search for
role string no ARIA role to filter by
webview_label string no Target webview
test_id string no Exact data-testid value
name string no Accessible name (aria-label, title, placeholder; case-insensitive substring)
tag string no Tag name, e.g. button
placeholder string no Placeholder text (case-insensitive substring)
alt string no Alt text (case-insensitive substring)
title_attr string no title attribute (case-insensitive substring)
label string no Associated <label> text (finds inputs by their label)
exact boolean no Exact instead of substring text matching
enabled boolean no Filter by enabled state
max_results integer no Maximum results (default 10)

Examples:

{"selector": "button.primary"}
{"text": "Submit"}
{"role": "heading"}

invoke_command

Invoke a Tauri command from the backend.

Parameters:

Name Type Required Description
command string yes Command name
args object no Arguments to pass
timeout_ms integer no How long to wait for the result (default: the plugin eval timeout, 30 s; max 300000). Raise it for legitimately slow commands. victauri-test: invoke_command_with_timeout

Example:

{"command": "get_settings", "args": {}}
{"command": "search_context", "args": {"query": "hello"}}

screenshot

Capture a PNG screenshot of the application window.

Parameters:

Name Type Required Description
window_label string no Target window (defaults to main)

Returns: Base64-encoded PNG image data.

Linux: capture requires X11 or XWayland (the common case, including CI under xvfb). A pure-Wayland session exposes no safe per-window capture path, so screenshot returns a clear error there rather than a wrong or blank image. Windows and macOS capture natively.


verify_state

Compare frontend and backend state to detect drift.

Parameters:

Name Type Required Description
frontend_expr string no JS expression for frontend state
backend_state object no Expected backend state to compare
backend_command string no Tauri command whose result is the backend state (instead of backend_state)
backend_args object no Arguments for backend_command

Example:

{
  "frontend_expr": "document.title",
  "backend_state": {"title": "My App"}
}

detect_ghost_commands

Classify every command the frontend invoked by its observed outcome: a command that succeeded at least once provably has a handler (counted in verified_handlers); one that only ever failed with "not found" is listed in confirmed_ghosts; plugin:* built-ins are excluded_builtins; frontend_only is the weak tier (absent from the #[inspectable] registry, which is a subset of the real handler set). Read reliability and note before treating frontend_only as a bug list.

Parameters:

Name Type Required Description
since_ms integer no Only consider commands invoked within the last N ms (scopes detection to the current test without clearing the IPC log)

Returns: confirmed_ghosts (each {name, error}), verified_handlers (a count), frontend_only, excluded_builtins, registry_only, total_frontend_commands, total_registry_commands, reliability (none/low/high) and note.


check_ipc_integrity

Verify the health of IPC communication.

Parameters:

Name Type Required Description
stale_threshold_ms integer no Age after which a pending IPC call counts as stale (default 5000)

Returns: {healthy, total_calls, pending_count, stale_count, error_count, stale_calls, errored_calls, warning}


wait_for

Wait for a condition to become true, polling until timeout. Use the expression and event conditions to await async backend work to true completion instead of guessing with a fixed sleep.

Parameters:

Name Type Required Description
condition string yes One of: selector, selector_gone, text, text_gone, url, ipc_idle, network_idle, expression, event
value string no Selector/text/URL to match; the JS expression (expression); or the Tauri event name (event). Not needed for ipc_idle/network_idle
expected any no For expression: the JSON value the expression must equal. Omit to wait for the expression to become truthy
since_ms number no For event: how far back (ms) to accept an already-fired event when the wait begins (default: 2000)
timeout_ms number no Max wait time in ms (default: 10000)
poll_ms number no Poll interval in ms (default: 200)

Conditions for async completion:

  • expression — polls a JS expression until truthy (or == expected). It may await, so you can await a fire-and-forget command's status directly. Level-triggered and race-free; needs no app changes. Returns { ok, value, elapsed_ms }.
  • event — blocks until a named Tauri event fires (evaluated against the captured event bus, with a since_ms look-back). The app must emit the event and Victauri must capture it via VictauriBuilder::listen_events. Returns { ok, event, elapsed_ms }.

Example:

{"condition": "selector", "value": ".modal.open", "timeout_ms": 3000}
{"condition": "url", "value": "/dashboard"}
{"condition": "expression", "value": "(await window.__TAURI_INTERNALS__.invoke('get_status')).running === false", "timeout_ms": 30000}
{"condition": "event", "value": "analysis-complete", "timeout_ms": 30000}

The robust async pattern is invoke_command(...) then wait_for(expression|event, ...).


app_state

Read application-defined backend state through a registered probe. Probes give an agent first-class, discoverable access to domain state (a scoring pipeline's version and stale-item count, a queue's depth, cache stats) that would otherwise require query_db + log-grepping. A probe runs in the Rust process with no IPC round-trip and no frontend involvement — direct-backend introspection a browser-external tool cannot do.

Apps register probes via VictauriBuilder::probe("name", || serde_json::json!({ … })) (build your shared state as an Arc once, clone it into both .manage() and the probe).

Parameters:

Name Type Required Description
probe string no Name of the probe to run. Omit to list all available probe names

Example:

{}                       // → { "probes": ["scoring", "queue"] }
{"probe": "scoring"}     // → { "pipeline_version": 5, "stale_items": 0 }

assert_semantic

Assert a condition about the application state using JS expressions.

Parameters:

Name Type Required Description
expression string yes JS expression to evaluate
condition string yes One of: equals, not_equals, contains, greater_than, less_than, truthy, falsy
expected any no Expected value (not needed for truthy/falsy)
label string no Human-readable name for the assertion (default empty)

Example:

{
  "expression": "document.title",
  "condition": "equals",
  "expected": "My App"
}

resolve_command

Resolve a natural language description to registered commands.

Parameters:

Name Type Required Description
query string yes Natural language description
limit integer no Maximum results (default 5)

Example:

{"query": "show settings"}

get_registry

List all registered commands with their metadata.

Parameters:

Name Type Required Description
query string no Filter commands by name or description

Each argument lists its Rust name, and — when it differs — the key the frontend invokes it by: Tauri camelCases argument names by default (size_kb → sizeKb), so pass key (or name when there is no key) in invoke_command's args.


get_memory_stats

Get real OS process memory usage.

Parameters: None.

Returns: {working_set_bytes, peak_working_set_bytes, page_fault_count, page_file_bytes}


get_plugin_info

Get plugin version, uptime, configuration, and capabilities.

Parameters: None.


get_diagnostics

Environment diagnostics for a webview: service workers, closed shadow DOM, iframes, DOM size, CSP, and IPC capture completeness.

Parameters: webview_label (optional).

info.ipc_capture says which Tauri IPC transport the page uses and how much of it Victauri sees:

Field Values
transport fetch (custom protocol, desktop default) · post_message_fallback (Tauri switched after a custom-protocol failure) · post_message (always postMessage, e.g. Android) · unknown (no IPC yet)
capture full · requests_only (responses unobservable; calls logged with status unknown) · none (switch detected, traffic invisible) · unknown
fetch_calls, post_message_calls, post_message_responses counters for this page
fallback_detected_via, fallback_at console_warning / custom_protocol_blocked, and when
note plain-language explanation

When Tauri has switched to postMessage, warnings includes ipc-postmessage-fallback. The same object is attached as ipc_capture to detect_ghost_commands, check_ipc_integrity, and introspect coverage / command_catalog / command_timings.


Compound Tools

Compound tools use an action parameter to select the specific operation.

interact

Element interactions with Playwright-grade actionability checks. Works on elements inside same-origin iframes too (refs from a snapshot/find resolve across frame boundaries).

An action the page refuses — element covered, disabled, hidden, detached, not a <select>, or ref not found — is a tool error (MCP isError: true; REST {"error": …}) whose text is the reason followed by [hint: RETRY_LATER] (the UI may still settle) or [hint: CHECK_INPUT] (wrong target). The same applies to input, inspect (e.g. get_styles on an unknown ref) and route add. (Before 0.9.0 these came back as a successful {"ok": false, "error": …} result.)

Action Parameters Description
click ref_id Click an element
double_click ref_id Double-click an element
hover ref_id Hover over an element
focus ref_id Focus an element
scroll_into_view ref_id Scroll element into viewport
select_option ref_id, value or values Select option(s) in a <select>
trusted boolean no
x number no
y number no

Trusted (OS-level) clicks: add "trusted": true to click to deliver a real OS mouse event (isTrusted: true) at the element's center, instead of a synthetic DOM event — for app handlers that gate on event.isTrusted or browser features needing user activation. Implemented on Windows (Win32 SendInput); on macOS/Linux it returns a clear "not implemented" error so you fall back to the default synthetic click. The window is brought to the foreground first.

Example:

{"action": "click", "ref_id": "e3"}
{"action": "click", "ref_id": "e3", "trusted": true}
{"action": "select_option", "ref_id": "e9", "value": "us"}

input

Text input and keyboard operations.

Action Parameters Description
fill ref_id, value Set input value directly
type_text ref_id, text Type character-by-character
press_key key Press a keyboard key
trusted boolean no

Trusted (OS-level) input: add "trusted": true to type_text or press_key to deliver real OS keystrokes (isTrusted: true) into the focused element instead of synthetic DOM events. The target element (ref_id) is focused first. Implemented on Windows (Win32 SendInput); macOS/Linux fall back to synthetic input with a clear error.

Example:

{"action": "fill", "ref_id": "e5", "value": "hello@example.com"}
{"action": "type_text", "ref_id": "e5", "text": "Hello"}
{"action": "type_text", "ref_id": "e5", "text": "Hello", "trusted": true}
{"action": "press_key", "key": "Enter"}

Supported keys: Tab, Escape, Enter, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, F1-F12, and any single character.


window

Window management operations.

Action Parameters Description
get_state label Get window state (position, size, visibility)
list — List all window labels
manage label, manage_action minimize, unminimize, maximize, unmaximize, close, focus, show, hide, fullscreen, unfullscreen, always_on_top, not_always_on_top
resize label, width, height Resize a window
move_to label, x, y Move a window
set_title label, title Change window title
introspectability — Probe every window's JS bridge and report which are introspectable vs. blind

introspectability answers "which windows can Victauri actually see?" A window that returns introspectable: false while visible: true is almost always missing the victauri:default capability — Tauri's per-window permission ACL silently blocks the bridge's callback IPC, so eval_js/dom_snapshot/animation/find_elements see nothing with no error. The diagnostic names the exact capability file to edit. Required per window (not just main).

Example:

{"action": "list"}
{"action": "get_state", "label": "main"}
{"action": "resize", "label": "main", "width": 1200, "height": 800}
{"action": "introspectability"}

storage

Browser storage operations.

Action Parameters Description
get key, storage_type Get a value (storage_type: local (default) or session)
set key, value, storage_type Set a value
delete key, storage_type Delete a key
get_cookies — Get the page's cookies (non-httpOnly only — read via document.cookie)

Example:

{"action": "set", "key": "theme", "value": "dark"}
{"action": "get", "key": "theme"}

navigate

Navigation and history operations.

Action Parameters Description
go_to url Navigate to a URL (http/https only)
go_back — Go back in history
get_history — Get navigation history log
set_dialog_response dialog_type, dialog_action, text Auto-respond to future alert/confirm/prompt dialogs (accept / dismiss)
get_dialog_log — Get dialog log (alerts, confirms, prompts)

Example:

{"action": "go_to", "url": "https://example.com"}
{"action": "get_history"}
{"action": "set_dialog_response", "dialog_type": "confirm", "dialog_action": "accept"}

recording

Time-travel recording for session capture and replay.

Action Parameters Description
start session_id (optional) Start recording events
stop — Stop recording and return session
checkpoint checkpoint_id (optional, auto-generated), checkpoint_label (alias: label), state Create a checkpoint
list_checkpoints — List checkpoints
get_events since_index Get recorded events
events_between from, to (checkpoint ids) Events between two checkpoints
get_replay — The recorded IPC call sequence
export — Export full session data (works after stop)
import session_json Import a session (becomes the active recording; refused while one is in progress)
replay webview_label Re-invoke recorded IPC commands (see below; works after stop)
flush webview_label Pull pending bridge events into the active recording now

replay semantics. Recordings do not capture call arguments, so replay re-invokes only calls that succeeded with no arguments. Calls that had arguments, failed, or never completed are reported as skipped with a reason; commands blocked by the privacy allow/blocklist are reported as blocked. passed means the re-invocation succeeded — the response is not diffed against the original (only its JSON type is reported). Re-invoked commands run for real, so their side effects happen again.

Each call is re-invoked in the window that recorded it — a window's Tauri capabilities are its own — and is skipped if that window no longer exists (it never falls back to main); webview_label only filters which recorded calls are replayed. Calls that were fulfilled or blocked by a network route (route add, which page script can also use) are recorded as mocked and never replayed: they never reached the backend. (Script in the recording window can still rewrite what the recording captures from that window — see Security.)

Example:

{"action": "start"}
{"action": "checkpoint", "label": "after-login"}
{"action": "get_events", "since_index": 0}
{"action": "stop"}
{"action": "replay"}

inspect

CSS inspection, accessibility, and performance profiling.

Action Parameters Description
get_styles ref_id, properties Get computed CSS styles
get_bounding_boxes ref_ids Get bounding boxes with box model
highlight ref_id, color, highlight_label Draw debug overlay on element
clear_highlights — Remove all debug overlays
audit_accessibility — Run WCAG accessibility audit
get_performance — Get performance metrics
label string no

Example:

{"action": "get_styles", "ref_id": "e3", "properties": ["color", "font-size"]}
{"action": "get_bounding_boxes", "ref_ids": ["e1", "e2", "e3"]}
{"action": "audit_accessibility"}
{"action": "get_performance"}

The accessibility audit checks: missing alt text, unlabeled form inputs, empty buttons/links, heading hierarchy, color contrast (WCAG AA), ARIA role validity, positive tabindex, and missing document language/title.

Performance metrics include: navigation timing, resource summary, paint timing (FP/FCP), JS heap usage, long task count, and DOM statistics.


css

CSS injection for debugging and prototyping.

Action Parameters Description
inject css Inject custom CSS (replaces previous)
remove — Remove injected CSS
allow_remote boolean no

Example:

{"action": "inject", "css": "* { outline: 1px solid red; }"}
{"action": "remove"}

logs

Access all captured logs from the application.

Action Parameters Description
console since, level Console log entries
network since Network request log
ipc since, limit IPC command log (calls captured on Tauri's postMessage fallback carry transport: "post_message")
navigation — Navigation history
dialogs — Dialog interactions
events since Event stream
slow_ipc threshold_ms IPC calls slower than threshold
clear — Clear the IPC + network logs (per-test isolation)
filter string no
wait_for_capture boolean no

Example:

{"action": "console", "level": "error"}
{"action": "network"}
{"action": "slow_ipc", "threshold_ms": 100}

ipc/network/slow_ipc return at most 100 entries by default and truncate large per-entry bodies (4 KB) — pass an explicit limit for more.


route

Network request interception — the Playwright route() equivalent, implemented purely in the JS bridge (no CDP; the same behaviour on all three Tauri webviews, within the fetch/XHR limits below). Matches webview fetch/XHR by URL and blocks, mocks, or delays them. Rules are page-scoped (cleared on reload).

Action Parameters Description
add pattern, behavior, … Add a rule (see below)
list — List active rules
clear id Remove a rule by id
clear_all — Remove all rules
matches limit Log of intercepted requests
status_text string no

add parameters:

Name Type Required Description
pattern string yes URL pattern to match. Tested against the request's absolute URL (resolved against the page's base URL), its path + query + fragment when same-origin, and the URL string as the app passed it — so a rule hits the same request whether the app calls fetch('/api/x'), fetch(new URL(…)) or fetch(new Request(…)), and likewise for XHR
match_type string no substring (default), glob (* matches any run of characters; every other character, including ?, is literal), regex, exact
method string no Restrict to one HTTP method
behavior string no block (abort), fulfill (mock — default), delay
status number no Mock response status (fulfill, default 200)
headers object no Mock response headers (fulfill)
body any no Mock response body (fulfill)
content_type string no Mock content-type (fulfill, default application/json)
delay_ms number no Latency to inject (delay; also delays a fulfill)
times number no Max times the rule fires (0 = unlimited)

Example:

{"action": "add", "pattern": "/api/users", "behavior": "fulfill", "status": 200, "body": {"users": []}}
{"action": "add", "pattern": "analytics", "behavior": "block"}
{"action": "add", "pattern": "*/slow", "match_type": "glob", "behavior": "delay", "delay_ms": 2000}
{"action": "matches"}

Scope: fetch supports all behaviors; XHR supports block/delay (fulfill is fetch-only). Top-level navigation, sub-resources (img/css), and WebSocket frames are not intercepted.

Tauri IPC is observe-only. The app's real invoke traffic (http://ipc.localhost/… on Windows, ipc://localhost/… on macOS/Linux) is logged (logs ipc, and a rule may even show up in matches), but a rule does not control it — Tauri serves real IPC below the JS fetch layer the bridge can reach, so the call still goes through, undelayed. The fault tool does not touch the app's real frontend IPC either: it only applies to commands you drive through invoke_command. Neither tool can reproduce a failure a user clicking the UI would hit.

A block rule on a Tauri IPC URL switches the page to postMessage IPC. The blocked fetch rejects, which Tauri treats as a broken custom protocol: it retries that call over window.ipc.postMessage and uses postMessage for the rest of the page's life (until a reload). Victauri still captures those calls (transport: "post_message") and get_diagnostics reports the switch.


trace

Screencast / visual timeline — captures the window at a fixed interval into a ring buffer via the native screenshot path (no CDP). Pairs with recording (events) and logs (network/console) to form a Playwright-trace-style bundle.

Action Parameters Description
start interval_ms, max_frames, with_events Begin capturing
stop — Stop and return a summary
status — Active flag + buffered frame count
frames limit Return captured frames as base64 PNGs

start defaults: interval_ms 500 (min 50, max 60000), max_frames 60 (max 600). Set with_events: true to also start the event recorder so the trace bundles the IPC/DOM/console timeline alongside the screencast.

Limits and lifecycle:

  • A trace auto-stops after 30 minutes (an abandoned trace must not capture forever).
  • The frame buffer is a ring (max_frames) and is also capped at 256 MB total; the oldest frames are dropped first.
  • frames returns the newest frames that fit a 25 MB response cap (with a note when it had to drop older ones) — pass a smaller limit to page.
  • Hidden windows are skipped: a frame is only captured while the target window is visible (a native capture of a hidden window would return stale or another window's pixels), so a hidden period shows up as a gap, not a wrong image.
  • stop (or the 30-minute auto-stop) also ends the recording that with_events started; a recording you started separately with recording start is left alone. The stopped session stays readable via recording get_events / export.
  • Frames come from the native screenshot path, so the platform limits of screenshot apply (Linux needs X11/XWayland).

Example:

{"action": "start", "interval_ms": 250, "max_frames": 40, "with_events": true}
{"action": "status"}
{"action": "stop"}
{"action": "frames", "limit": 10}

Backend Introspection (Victauri-Exclusive)

These tools exploit Victauri's position inside the Rust process to provide insights and control that browser-external tools like CDP cannot access.

introspect

Deep backend introspection — command performance profiling, IPC contract testing, coverage analysis, startup timing, capability auditing, process enumeration, and event bus monitoring.

Action Parameters Description
command_timings slow_threshold_ms Per-command execution timing stats (min/max/avg/p95)
coverage — Which registered commands have been called this session
command_catalog — Per-command argument + result shapes mined from the live IPC log, merged with the registry — real call/return schemas even when the app doesn't use #[inspectable] (where get_registry is names-only)
contract_record command, args Record a command's response shape as baseline
contract_check — Check all recorded contracts for schema drift
contract_list — List all recorded contract baselines
contract_clear — Clear all recorded contract baselines
startup_timing — Victauri plugin initialization phase-by-phase timing breakdown
capabilities — Tauri v2 capabilities, security config (CSP, freeze_prototype), plugins, and window definitions
db_health db_path Bounded, read-only SQLite diagnostics (see below)
plugin_state — Victauri plugin internal state: event counts, registry, recording, faults, timings, uptime
processes — Host process + child processes (sidecars, background workers) with PID, name, and memory
plugin_tasks — Victauri's spawned async tasks (MCP server, event drain) with active/finished counts
event_bus — All captured Tauri events (automatically intercepted) + app events from EventLog
event_bus_clear — Clear both event bus and event log

db_health report. Opens the database read-only and returns: journal_mode, page_count, page_size, db_size_mb, freelist_count; the table list with per-table row_count (counted under a 5 s budget — tables not reached get row_count: null and row_counts_complete: false; the listing is capped and flagged by tables_truncated); and integrity_check from SQLite PRAGMA quick_check under its own 5 s budget. When the file may contain virtual tables and the host app has registered a non-built-in virtual-table module, the check runs table by table over ordinary tables only (integrity_check_kind: "quick_check (per table)", reason in integrity_check_note), so no app-registered module code runs; otherwise integrity_check_note is null. On a large database quick_check may report "not completed: … exceeded its budget …" — that means unknown, not corrupt. It never checkpoints or inspects the -wal file (wal_checkpoint is reported as "not run (read-only diagnostics)" in WAL mode).

Examples:

{"action": "command_timings", "slow_threshold_ms": 100}
{"action": "coverage"}
{"action": "command_catalog"}
{"action": "contract_record", "command": "get_settings"}
{"action": "contract_check"}
{"action": "startup_timing"}
{"action": "capabilities"}
{"action": "db_health"}
{"action": "plugin_state"}
{"action": "processes"}
{"action": "plugin_tasks"}
{"action": "event_bus"}

fault

Probe a backend command handler under failure for chaos engineering.

Scope: faults apply only to commands you run via the invoke_command tool — they do not intercept the app's real user-driven IPC (window.__TAURI_INTERNALS__.invoke), which Tauri serves below the JS layer Victauri can reach. Use fault to test a handler's error path when you drive it (e.g. "does my error branch return the right shape on a DB failure?"). It does not reproduce a failure a user clicking the UI would experience — that path is not interceptable cross-platform without CDP.

Action Parameters Description
inject command, fault_type, delay_ms, error_message, max_triggers Add a fault rule
list — List all active fault injection rules
clear command Remove a specific fault rule
clear_all — Remove all fault rules

Fault types:

  • delay — sleep delay_ms (max 120 000), then run the command normally.
  • error — return [FAULT INJECTED] command '<name>': <error_message> without running the command.
  • drop — return {} without running the command.
  • corrupt — run the command for real (side effects happen), then return a fixed marker instead of its result: {"__corrupted":true,"original_length":<n>,"fault":"corrupt"}.

Rules auto-expire 15 minutes after they are injected (so a forgotten fault cannot sabotage a later run — re-inject to refresh) or after max_triggers hits (0 = unlimited).

Examples:

{"action": "inject", "command": "get_settings", "fault_type": "delay", "delay_ms": 2000}
{"action": "inject", "command": "save_data", "fault_type": "error", "error_message": "disk full"}
{"action": "inject", "command": "fetch_feed", "fault_type": "drop", "max_triggers": 3}
{"action": "list"}
{"action": "clear_all"}

explain

Natural-language narration of what happened in the app. Aggregates recent events over a time window and produces human-readable summaries, causal chains, or diffs.

Event source. While a recording is active, explain reads the recorder-fed event log. When nothing is recording, it reads the JS bridge's own event stream on demand (IPC, DOM mutations, console, network, navigation) for the requested window — without storing it, so a later recording never double-counts. Victauri's own internal traffic is filtered out. Network requests are counted as state changes and navigations as window events in the tallies.

Action Parameters Description
summary seconds Aggregate events over N seconds (default: 30) into a narrative with type counts
last_action seconds Map recent events to a causal chain with " → " separators (default: 5s)
diff seconds Count IPC calls, DOM changes, errors, and interactions over N seconds (default: 10)

Parameters:

Name Type Required Description
action string yes One of: summary, last_action, diff
seconds integer no How many seconds to look back
webview_label string no Target webview window

Examples:

{"action": "summary"}
{"action": "summary", "seconds": 60}
{"action": "last_action"}
{"action": "diff", "seconds": 15}

animation

Quantitative, deterministic, cross-platform access to the webview's animation engine via the Web Animations API. Works identically on WebView2 / WKWebView / WebKitGTK with no CDP. Closes the last blind spot in agent perception — screenshots are frozen instants; this lets an agent perceive time-based behaviour.

Action Parameters Description
list webview_label getAnimations() introspection: declared timing (duration/delay/easing/iterations), computed progress, keyframes, play state, and the animating target. An animation only appears while running/pending — trigger it first.
scrub selector, points, capture, webview_label Pauses the target's animation and seeks it to N evenly-spaced points (await animation.ready + double-rAF freezes each frame), returning the exact geometry curve (rect + transform + opacity per point). With capture: true, also returns a single contact-sheet filmstrip PNG of the whole arc plus a manifest. CSS-driven animations only (JS/rAF animations are not seekable — errors clearly and suggests sample).
sample record, selector, webview_label Real-time requestAnimationFrame recorder, decoupled from the blocking eval so event-triggered sweeps are catchable: record: true arms a watcher, trigger the animation, then record: false reads the measured per-frame curve, jank stats (dropped frames, max frame gap), and declared-vs-measured duration. Works for any animation including JS/rAF-driven ones.
restore boolean no
cols integer no
clear boolean no

Parameters:

Name Type Required Description
action string yes One of: list, scrub, sample
selector string for scrub/sample CSS selector of the animating element
points integer no Number of evenly-spaced seek points for scrub (default: 6)
capture boolean no For scrub: also return a filmstrip PNG of the arc
record boolean for sample true to arm the recorder, false to read results
webview_label string no Target webview window

Filmstrip + transparent windows: scrub's filmstrip uses native window capture, which cannot see transparent / GPU-composited windows (no DWM redirection surface). On such a window the capture now fails with an actionable error rather than returning a blank frame — use an opaque window, or list / sample / scrub without capture.

Examples:

{"action": "list"}
{"action": "scrub", "selector": "#sweep-toast", "points": 6, "capture": true}
{"action": "sample", "selector": "#sweep-toast", "record": true}
{"action": "sample", "record": false}