# What your agent can do

The Squiggle server has ninety tools. Your agent doesn’t need to learn them one by one: they fall into a few jobs, and the kit tells it which to reach for.

## The tools, by job

| Job | Tools |
| --- | --- |
| Start | status (what is connected and what works), target (pick the app), briefs (problems the app already found, each with a recording and a source line). |
| Look | describe, find, query, assert, wait_for, inspect, renders, legibility, and screenshot when nothing else will do. |
| Act | tap, hover, input_text, swipe, scroll, scroll_until_visible, back, launch_app, run_flow, and batch to send several at once. tune sets a value the app declared tunable. |
| Run a journey | run_intent and the tools that follow a run: intent_wait, resume_intent, steer, intent_stop, intent_continue, approve_action. branch tries several continuations from one point and ranks them. |
| Remember | library_list, library_save, route, predict, what_if, interface, crawl, invariants, diff_runs, affected_by_diff. |
| Set up a run | fixture (save and restore a named starting point, the same slots as squiggle save and load), deterministic_session (pin the network, animations, clock and locale). |
| Check your work | report_card, after building a feature: runs the flows that cover the screens you changed and checks their budgets, findings and legibility. It runs offline against recorded stubs unless you pass live: true. |
| Record | record_start, record_stop, replay_recording, filmstrip. |
| Explain | explain, verify_citations, publish_evidence. |
| Read the data | Every perf_ and product_ tool, propose_fix, and probe_read. |

## Look before acting, cheaply

`describe` lists what is on screen, controls first, and gives each one a short reference like `n42` that `tap` accepts. After the first look, `describe { sinceLastLook: true }` returns only what changed. `find` says whether a selector matches one control, several or none before your agent acts on it, and `tap` refuses a selector that matches several.

Every acting tool waits for the app to settle and returns what changed on screen in the same reply, so your agent doesn’t need a second look. A successful `tap` means the tap was sent; to prove it worked, `assert` the result.

These are the server’s real replies from a checklist screen. Tick an item to see what a `tap` returns, and compare its size with a full look:

## From the screen to your code

In a development build, `describe { fields: "source" }` gives each control’s `callSite`: the line that renders it, such as `src/screens/Login.tsx:42:7`. Your agent opens that line instead of searching for a label, and after editing it, `find { callSite: "Login.tsx:42" }` shows what the line renders now. `inspect` shows a component’s live props, hooks and state by the names in your source. It only reads; editing props and state is for you, in the [Inspector](https://squiggle.sh/docs/inspector).

## Find what re-renders

`renders` returns the components that re-render most, with the same counts, speeds, times and reasons as Studio’s Renders tab. To measure one interaction, your agent calls `renders { reset: true }`, uses the app, then calls `renders` again: counting continues for two minutes after each call. A selector narrows it to one part of the app.

The reply also has `cascades` (what started each burst of re-renders), `loops` (components held at `loopRate` renders a second, 20 unless you set it, for three seconds) and `providers` (context providers that hand down a new value with the same contents, and the component that renders each one). `trends: true` adds each component’s last 30 seconds. See [Find what re-renders](https://squiggle.sh/docs/inspector/renders).

## Hover a desktop or web app

`hover` moves an invisible pointer onto a selector, so the element’s hover card, tooltip or highlight appears without your cursor moving. `hover { leave: true }` moves it off. Read what appeared from the reply’s `observed` change, or a screenshot. A selector that matches several elements is refused, and so is an element nothing hovers. On macOS, see [React Native macOS](https://squiggle.sh/docs/macos).

## Ask the data a question

`probe_read` runs a short script against the performance and product data and returns only its result, so your agent doesn’t pull a large table into the conversation to search it:

```ts
// probe_read: filter on the server, return only what you need
const slow = await perf.sql(`
  select name, avg(dur_us) as avg from spans
  where kind = 1 group by name order by avg desc limit 5`);
const insights = await perf.insights();
return { slow, errors: insights.filter((i) => i.severity === 'error').length };
```

The script can only read. It has no network, no file access and no way to touch the app.

## What each tool needs

| Class | Tools |
| --- | --- |
| Free | 1: status, so your agent can always find out why another tool refused. |
| Drive | 28: everything that touches the simulator. |
| Analyze | 34: everything that reads stored data or a recording. |
| Agent | 27: programs, escalations, approvals, probe_read and propose_fix. |

Without a licence, the tools stay listed and refuse when called, with a message your agent can pass on. There is no tool to activate a licence, so a key never ends up in a conversation; see [Licence and trial](https://squiggle.sh/docs/licence).

## Prompts and resources

Two prompts, `squiggle-drive-mode` and `squiggle-perf-mode`, hold the working rules for driving and for performance work; a client can pin one instead of your agent fetching it. Resources include `squiggle://screen` (the current screen, updated as it changes), `squiggle://insights/latest`, each run as `squiggle://run/{runId}`, and the eleven kit documents as `squiggle://skill/…`.

> **No call hangs forever**
>
> A tool that hasn’t answered in 90 seconds returns an error saying so. Tools whose job is to take long, such as `run_flow`, `crawl` and `intent_wait`, get 15 minutes. The next call reconnects to the app instead of waiting behind the stuck one.
