What your agent can do
For AI agents: this page is Markdown at https://squiggle.sh/docs/agents/tools.md. Every docs page is listed at https://squiggle.sh/llms.txt, and all of them are one file at https://squiggle.sh/llms-full.txt.
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:
describe {}{ "ok": true, "data": { "route": "checklist", "nodes": [ {"ref":"n42","name":"AXGenericElement","testID":"Checklist","role":"AXGenericElement","native":true}, {"ref":"n43","name":"AXStaticText","role":"AXStaticText","label":"Checklist","native":true}, {"ref":"n44","name":"AXButton","testID":"BackButton","role":"AXButton","label":"(tabs)","native":true,"routerInternal":true,"hint":"router-group segment, not a written label — prefer `back` to navigate back"}, {"ref":"n45","name":"ThemedText","testID":"signed-in-email","text":"guest@acme.com"}, {"ref":"n46","name":"ThemedText","testID":"checklist-progress","text":"0 / 20 done"}, {"ref":"n47","name":"Button","testID":"logout","label":"Log out"}, {"ref":"n48","name":"Pressable","testID":"item-0","role":"checkbox","label":"Item 1"}, {"ref":"n49","name":"Pressable","testID":"item-1","role":"checkbox","label":"Item 2"}, {"ref":"n50","name":"Pressable","testID":"item-2","role":"checkbox","label":"Item 3"}, {"ref":"n51","name":"Pressable","testID":"item-3","role":"checkbox","label":"Item 4"}, {"ref":"n52","name":"Pressable","testID":"item-4","role":"checkbox","label":"Item 5"}, {"ref":"n53","name":"Pressable","testID":"item-5","role":"checkbox","label":"Item 6"}, {"ref":"n54","name":"Pressable","testID":"item-6","role":"checkbox","label":"Item 7"}, {"ref":"n55","name":"Pressable","testID":"item-7","role":"checkbox","label":"Item 8"}, {"ref":"n56","name":"Pressable","testID":"item-8","role":"checkbox","label":"Item 9"}, {"ref":"n57","name":"Pressable","testID":"item-9","role":"checkbox","label":"Item 10"}, {"ref":"n58","name":"Pressable","testID":"item-10","role":"checkbox","label":"Item 11"}, {"ref":"n59","name":"Pressable","testID":"item-11","role":"checkbox","label":"Item 12"}, {"ref":"n60","name":"Pressable","testID":"item-12","role":"checkbox","label":"Item 13"}, {"ref":"n61","name":"Pressable","testID":"item-13","role":"checkbox","label":"Item 14"}, {"ref":"n62","name":"Pressable","testID":"item-14","role":"checkbox","label":"Item 15","offscreen":true}, {"ref":"n63","name":"Pressable","testID":"item-15","role":"checkbox","label":"Item 16","offscreen":true}, {"ref":"n64","name":"Pressable","testID":"item-16","role":"checkbox","label":"Item 17","offscreen":true}, {"ref":"n65","name":"Pressable","testID":"item-17","role":"checkbox","label":"Item 18","offscreen":true}, {"ref":"n66","name":"Pressable","testID":"item-18","role":"checkbox","label":"Item 19","offscreen":true}, {"ref":"n67","name":"Pressable","testID":"item-19","role":"checkbox","label":"Item 20","offscreen":true}, {"ref":"n8","name":"main(RootComponent)"}, {"ref":"n9","name":"AppContainer"}, {"ref":"n10","name":"View"}, {"ref":"n11","name":"View"}, {"ref":"n12","name":"withDevTools(App)"}, {"ref":"n13","name":"App"}, {"ref":"n14","name":"ExpoRoot"}, {"ref":"n15","name":"ContextNavigator"}, {"ref":"n16","name":"NavigationContainerInner"}, {"ref":"n17","name":"BaseNavigationContainer"}, {"ref":"n18","name":"EnsureSingleNavigator"}, {"ref":"n19","name":"ThemeProvider"}, {"ref":"n20","name":"LinkPreviewContextProvider"}, {"ref":"n21","name":"SafeAreaProvider"} ], "total": 182, "omitted": 142, "evidence": { "sessionId": "01a137c1-a7af-7fac-9af2-0611f9abc37c", "eventId": 3350, "wallMs": 1791939131661 } }}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.
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.
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.
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:
// probe_read: filter on the server, return only what you needconst 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.
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/….