# Changelog

What’s new in Squiggle: every feature, every fix and every speed-up, newest first. The desktop app, the CLI, the MCP server and the SDK all ship on one version number, so a release here is a release everywhere — update once and you have all of it.

## [0.3.0](https://squiggle.sh/changelog/0.3.0)24 October 2026

### Desktop app

- **New**: save the app's current screen and data from the device panel's Capture menu, and load it back in under a second
- **New**: a Tunings screen shows what `squiggle flow --tune` and `--repair` measured and what they propose
- **New**: Performance has a Probes section: write a rule, install it on the connected app, and see when it held
- **New**: Product has a State section, showing what your app held on each screen
- **New**: Analytics names the control each touch landed on, and what each drag was meant to do
- **New**: the tour has 25 chapters, folds its sections and shows how much you've read. Every chapter has a hint
- **New**: menu items show their keyboard shortcut, such as Show all devices (⌘G)
- **New**: Settings are grouped into sections, and the simulator stays in view while you change them
- **New**: a healed step shows how close the match was, and warns when it was close to failing
- **Fix**: Studio checks for updates on every launch, and Check for Updates opens the update card
- **Fix**: Studio's Replay goes to the flow's start screen first, as `squiggle flow` does
- **Fix**: zooming into a live timeline no longer jumps when the session grows, and a timeline parked at the end follows it
- **Fix**: hover cards on graphs stay above everything and inside the window, and close with the session they describe
- **Fix**: the inspector's selection box stays inside the device screen and follows a scroll
- **Fix**: the Renders table keeps the Component column in view while it scrolls sideways
- **Fix**: a popover over the device preview scrolls instead of the device
- **Fix**: Studio no longer reloads an app that another tool is driving
- **Fix**: Studio removes a recent project whose folder is gone
- **Perf**: Studio's JS thread idles with an app connected: live performance analysis reads only what changed

### CLI

- **Breaking**: Squiggle saves an app's runs, recordings and performance data only into the project that owns it: the app is listed under `apps` in `.squiggle/config.jsonc`, or its development build was built inside the project. Any other app still works live, but nothing about it is saved. If an app's data stops appearing, add it to `apps`
- **Breaking**: with more than one simulator booted, a command that drives a device refuses to pick one and lists them (`E_DEVICE_AMBIGUOUS`). Name one with `--udid`, `SQUIGGLE_UDID` or `udid` in your config. Your agent's tools refuse the same way
- **New**: `squiggle card` checks whether a change is done: it runs the flows that reach the screens you changed, checks what they measured, and lists each problem with the line to fix
- **New**: `squiggle add screen` writes a new screen from one of six templates, with a flow that drives it and a renders budget it meets
- **New**: `squiggle save` and `squiggle load` keep the screen the app is on, with the data behind it, and put it back in under a second instead of tapping through screens
- **New**: `squiggle bisect` finds the commit that slowed a flow, without rebuilding the app. `--hunks` says how much of the slowdown each change in that commit accounts for
- **New**: `squiggle bakeoff` runs one flow against several revisions and compares pass rate, duration, renders, dropped frames, memory growth and startup in one table
- **New**: `squiggle motion` records how a view moves after a tap and gives you the `withSpring` config that reproduces it
- **New**: `squiggle contracts propose` turns what your passing runs always showed into asserts in your flows, and proposes removing an assert that stopped holding
- **New**: `squiggle perf budget` checks each screen's budget against the newest session, with the margin to each limit. `--changed` checks only the screens your branch changed
- **New**: `squiggle perf labels` exports every run with its outcome, heals and app state, as JSONL
- **New**: `squiggle probe when` runs a rule inside your app and reports when it held. `squiggle probe export` keeps the rule as a detector
- **New**: `squiggle store audit` lists data in your project that came from an app the project doesn't own. `--purge` removes it
- **New**: the first `squiggle up` in a project saves a baseline named `first`
- **Fix**: `squiggle up` gets a development build past the Expo launcher, and reports ready only once the app's JS has connected
- **Fix**: every command uses the port from your config or `SQUIGGLE_PORT`, not always 7777
- **Fix**: a YAML syntax error in a flow is reported as one, not as "a bug in Squiggle"
- **Fix**: a Ctrl-C during `--matrix` or `--repair` puts the simulator's appearance and text size back
- **Fix**: a `squiggle bench` series with a failed run records the failed run and exits 1

### Agents & MCP

- **New**: `report_card` gives your agent the report card
- **New**: `bisect_state` finds the store values that make a flow fail, from two save slots
- **New**: `what_if` tells your agent what a flow did under a repeated tap, a Back press or a bad network, from runs already recorded, without touching the app
- **New**: `tune` lists and sets the values your app declared tunable
- **New**: `product_state` shows what your app held on each screen
- **New**: `branch` can start from a save slot, and tries the likeliest alternative first
- **New**: `propose_fix` turns a `--tune` or `--repair` result into a code change
- **Fix**: an idle `squiggle mcp` no longer uses a quarter of a CPU core
- **Fix**: `launch_app` gets past the development launcher and an "Open in …?" alert, and returns once the first screen is up

### Flows & device

- **New**: flows drive the photo picker, the document picker, the share sheet and permission prompts that iOS shows over your app. Select their controls by the text they show
- **New**: `squiggle flow --twin` runs a flow on a working network and again on a slow, flaky, cut-off or offline one, and reports what your app did differently, such as a spinner that never goes away or an empty state shown for a server error
- **New**: `--fuzz` breaks each endpoint the flow called, one at a time
- **New**: `--race` finds a repeated tap or a Back press, made while a request is in flight, that sends a change twice or navigates after the user left. It writes the shortest flow that reproduces each
- **New**: `--chaos` runs a flow on a bad network, and `--stubs` answers the network from an earlier run. A flow can declare `chaos` in its config
- **New**: `--cache-twins <cold>,<warm>` shows which requests a warm app answered from its cache and which it fetched again
- **New**: `--bisect-state <green>,<failing>` finds the few store values that make a flow fail, and names the lines that write them and the components that read them
- **New**: `--matrix` runs a flow in each simulator setup, such as dark mode and the largest text size, and lists the layout problems each one adds. `--repair` searches the values you declared tunable for a layout with no problem in any setup
- **New**: `--tune <name>` picks a tunable value, such as a list's `windowSize`, by measuring dropped frames at each one
- **New**: `--cliff VAR=lo..hi` finds the list size where dropped frames start to climb, and what rendered most there
- **New**: `--boundaries` checks the edges of every control and reports an edge whose touches land on something else
- **New**: `--ax-only` finds every control through the accessibility tree alone, the way VoiceOver reaches it
- **New**: three asserts: `scroll` (frame rate, dropped frames, blank cells), `smooth` (how a region moves through a transition) and `memoryDelta` (memory growth since the previous step). Thresholds you leave out come from the screen's budget
- **New**: `waitFor` waits for a control to appear or go away, so opening a sheet needs no retry
- **New**: `swipe` takes a `duration` to drag slowly, and a `hold` to long-press before dragging, so a flow can reorder a list
- **New**: `softKeyboard: true` keeps the on-screen keyboard up while a flow types
- **New**: a near miss says which part of the selector scored what, and how far under the threshold it fell
- **Fix**: a selector with a `testID` and `text` needs both to match
- **Fix**: a `type` step waits for the text to land in the field, and checks it
- **Fix**: a control whose `testID`, label or press handler changes in place is found under its new name
- **Fix**: a scroll longer than its list is several drags inside the list
- **Fix**: a held drag starts on the control it holds
- **Perf**: the wait before each step is 41% shorter, and a relaunch finishes as soon as the app shows its screen

### Performance

- **New**: set a performance budget per screen in your config
- **New**: startup is split into phases, each timed by the module that owns it
- **New**: a JS stall comes with its CPU profile, including the first stall after a fresh launch
- **New**: a wait that runs long names the component still animating, with its file and line
- **New**: the `js-driven-motion` finding catches an animation that moves only while JS runs
- **Fix**: capturing a stall profile can no longer crash your app
- **Fix**: one app launch is one session, whether Studio, the CLI or both watch it
- **Fix**: samples follow a relaunched app into its new session
- **Fix**: a run that opens the performance store while another is writing to it no longer loses its session
- **Fix**: a long task that repeats is one finding per cause, grouped across sessions

### Product analytics

- **New**: split any report by a state sessions reached, with `--where`
- **New**: see which app states friction happens in, the states real sessions reach that no flow tests, and how states drift across releases
- **New**: an abandoned drag is a friction finding

### SDK

- **New**: declare values Squiggle may tune, such as a list's `windowSize`, with `defineTunable` and `useTunable`
- **New**: save slots capture your Zustand, Legend State and MMKV stores without setup
- **New**: state analytics samples what your app held on each screen, as shapes rather than values. It needs a build variable and the user's consent, set with `setStateAnalyticsConsent`
- **Fix**: gestures in your app run as worklets again with the published SDK
- **Fix**: upgrading Squiggle no longer needs `--clear` on Metro
- **Fix**: Zustand stores appear under their own names, such as `useCart`
- **Fix**: a slow drag keeps its interaction until the finger lifts

### Website

- **New**: every docs and changelog page has a Markdown copy at its URL plus `.md`, and each docs page has Copy as Markdown and View as Markdown, for your coding agent
- **New**: the templates page runs each template on the demo device and shows its report card
- **New**: on a phone, the menu and the search can be dragged away

[Open 0.3.0](https://squiggle.sh/changelog/0.3.0)

## [0.2.1](https://squiggle.sh/changelog/0.2.1)16 October 2026

### Desktop app

- **New**: a tour of Studio, offered when you finish onboarding
- **New**: the Renders tab shows what re-renders, what caused it, and which providers trigger extra renders, and warns you about render loops. The Inspector's Perf tab is now Renders too, and the component tree highlights each re-render
- **New**: Studio checks performance while you use the app, and tells you about each new problem once
- **New**: Insights can group recent sessions, so a problem that keeps coming back is one card
- **New**: the Performance screen opens on a dashboard
- **New**: Compare puts several metrics on one chart, with presets. Hover a metric to see what it measures
- **New**: Replay charts show CPU per thread, dropped frames, garbage-collection pauses and network
- **New**: Replay draws a recording's touches over the device, and the heatmap follows the playhead
- **New**: capture a CPU profile from the Flamegraph panel with one button
- **New**: the device menu lists running Mac apps
- **New**: notifications survive a restart, and clicking one takes you to what it's about
- **New**: Hardware → Shake shakes the simulator
- **Fix**: Studio uses less CPU, and animations and tooltips run at the right speed
- **Fix**: the Inspector no longer shows "0 nodes" for a connected device after an agent session
- **Fix**: hovering a row in the component tree outlines that component on the device
- **Fix**: expanding a row in the Network panel no longer shows an error
- **Fix**: a restarted run's charts no longer start with a sample from the previous run
- **Fix**: taps made by a flow or an agent no longer count as rage taps or dead zones

### CLI

- **Breaking**: `install-macos-agent.sh` is gone. Squiggle adds the agent to your Mac app's Debug build for you, so remove any build step that runs the script
- **New**: `squiggle init` finishes setting up an Expo app, adding the Babel config and entry file if they're missing. Anything it can't change safely, it lists for you to do
- **New**: `squiggle init` no longer creates a `.env` file. Your iOS app finds Squiggle without one
- **New**: `squiggle init --agent claude` also installs the Squiggle agent kit into `.claude/`
- **New**: `squiggle doctor` also checks your licence and the Babel plugin, and says how to fix either
- **New**: when your trial or licence expires, Squiggle tells you where to buy a key
- **Fix**: `squiggle perf diff --assert` exits with code 1 when a threshold is breached
- **Fix**: `squiggle crawl` exits with code 1, not 2, when it finds a crash
- **Fix**: two runs started at the same moment no longer merge into one history entry

### Agents & MCP

- **New**: `renders` gives your agent what Studio's Renders tab shows
- **New**: `propose_fix` turns a performance finding into a plan of code changes
- **Fix**: `batch` checks every step before it runs any, so a malformed step no longer runs the steps before it
- **Fix**: after a filtered `describe`, the next action no longer reports elements that were already on screen as new
- **Fix**: a tap by `ref` hits that element, even when another one has the same label
- **Fix**: the agent kit's Claude Code hooks run

### Flows & device

- **Breaking**: a misspelt key at the top of a flow file, such as `healng:`, is an error that lists the valid keys. It used to be ignored
- **New**: test an iOS app and a Mac app from one project: list both under `apps` in the config, and pick one with `--platform`. `squiggle init` fills them in
- **New**: results are kept per platform, so a flow that passes on iOS isn't counted as passing on macOS
- **New**: `squiggle flow --record` works for Mac apps
- **New**: Mac apps with App Sandbox turned on work too
- **Fix**: a run for your iOS app no longer connects to your Mac app, or the other way round
- **Fix**: scrolling works in Mac apps, sideways too
- **Fix**: a Mac app left open no longer slows down the start of a run
- **Fix**: `expectRoute` on a tap no longer shows an error in your editor

### Performance

- **New**: findings link to the line that declares the component
- **New**: when a context value is recreated on every render, the finding names the context and the component that provides it
- **New**: memo-miss also catches props that are new objects or arrays with the same contents
- **New**: `nav-loop` flags navigation loops your users don't usually take
- **New**: `squiggle perf insights` lists a session's findings, and `squiggle perf watch` shows them as they happen
- **New**: `perf diff --assert` can fail when a finding you name appears, with `failOnDetectors`
- **New**: `perf diff` and product analytics compare sessions from one platform at a time. Choose which with `--platform`

### SDK

- **New**: rage taps and dead zones are detected on every control, not only gesture-handler ones
- **New**: components wrapped in `memo()` or `forwardRef()` show up under their own names
- **Fix**: a button with no label or testID appears once in `describe`, not once for each component wrapping it
- **Fix**: Mac apps no longer report an impossible JS FPS

### Website

- **New**: the docs are rewritten, and cover every MCP tool, agent command and Performance panel
- **New**: more docs pages have live demos you can try
- **New**: search (⌘K) finds entries in reference tables
- **New**: Get Squiggle walks you from install to your first flow
- **Fix**: tooltips no longer stay open after you tap on a phone
- **Fix**: the phone menu lists every section of Why, Pricing and Download
- **Perf**: squiggle.sh pages load faster and jump around less while they load

[Open 0.2.1](https://squiggle.sh/changelog/0.2.1)

## [0.2.0](https://squiggle.sh/changelog/0.2.0)11 October 2026

### Desktop app

- **New**: agentic flows: a step can be a goal an agent drives. Flows has Scripted and Agentic tabs, shows how many agent steps each flow has recorded, and edits an agent step's prompt, verifier and recording. Intent runs moved here too, replacing the Agents screen
- **New**: the Runtime Inspector: a component tree beside four views of the selection — Details, Graph, Perf and Screen map
- **New**: Inspector Details: a component's props, hooks and state, its context and stores, renders, accessibility, style and structure, read live from the app
- **New**: edit a prop or a hook's state from the Inspector and the app on the simulator changes with it, until it reloads
- **New**: pick a component by pointing at it on the device mirror; where several are stacked under the pointer, the scroll wheel walks through them and a click lists them all
- **New**: Follow in app: selecting a component in the tree or the graph brings it on screen, navigating to its screen and scrolling it into view
- **New**: open the line that writes an element, or where its component is defined, in your editor
- **New**: the Inspector's Graph draws the live component graph as a tree or a force layout, with pan, zoom and the lineage of whatever you hover
- **New**: the Screen map: your app's screens and the taps between them, drawn as a roadmap with each navigator's screens grouped under its name, the screen the app is on ringed, and every screen's picture
- **New**: Crawl the app from the Screen map: it presses each control in turn, maps every screen a press opens and photographs it, signing in with the values your flows type. Crawl from here starts on one screen, and the map fills in as it goes
- **New**: Go to screen: pick a screen from the map or the menu, and Go there drives the app along the known path to it
- **New**: from any screen on the map, start a scripted flow that taps its way there, or an agentic flow that starts there
- **New**: the Screen map shows which screens no flow reaches, filters to the screens reachable from where the app is, and adds the screens you open yourself
- **New**: Replay, redesigned around what went wrong: Studio keeps the five seconds before a crash, error, stall or spike as an incident, and the player opens on it with a screenshot and a report you can copy
- **New**: from an incident, explain the component it blames, open the run in Performance or Analytics, or make a regression flow from it
- **New**: Replay's event list says what was tapped, swiped or scrolled, where, and what it led to, and its timeline has metric lanes for frames, activity, memory and latency, each with a legend
- **New**: Drive device: scrubbing a recording, pressing an event or playing it drives the app on the simulator to the same moment
- **New**: recordings are named the way you would describe them, and you switch between them without leaving the player
- **New**: a gallery for screenshots and screen recordings, with a swipeable, zoomable viewer. Screen recordings are H.264 or HEVC video
- **New**: simulator tools and real device skins
- **New**: compact mode: a small simulator-only window with its own toolbar, which you customise and reorder, and a row of live graphs
- **New**: installing the app installs the `squiggle` command too: it links itself into your terminal, and offers to add it to your PATH when your shell cannot find it. Settings → Command line removes it
- **Fix**: Studio no longer runs out of memory while the device mirror streams
- **Fix**: clicks on a menu or tooltip land on it rather than the control underneath, overlays open beside their control, and buttons keep working after compact mode
- **Fix**: the simulator mirror takes input with no app connected, and an overlay over it no longer passes clicks through to the simulator
- **Fix**: re-running a flow from History uses the settings the run was recorded with
- **Fix**: the notification bell reports failed runs (flows, benches, crawls, recordings, agent runs) and stays quiet about a command you typed in a terminal, which already showed its error
- **Perf**: Studio's idle CPU dropped from 22% to 6% of a core, and the device mirror costs about 20 points of a core less
- **Perf**: flows run from Studio at the same speed as from the terminal
- **Perf**: a 2,000-node graph pans and zooms at 60 fps, and switching tree and force layouts takes a tenth of the time
- **Perf**: memory stays flat in a long session: an hour at 60 renders a second holds 11.6 MB instead of 90.7 MB, and a two-hour recording writes 130 MB instead of 968 MB
- **Perf**: Studio uses 43% less CPU while other tools read the app through it

### CLI

- **New**: drive react-native-macos apps as well as iOS: `--platform macos` on every device command, and `install-macos-agent.sh`, shipped beside the binary, puts the agent in your app
- **New**: `squiggle flow --record` saves the run as a video, and an agent can attach it to a pull request
- **New**: `squiggle probe` reads live values from the running app's JavaScript over Metro
- **New**: `squiggle crawl` writes screen memory as it goes, and `crawl --changed` revisits only the screens a change touches
- **New**: a failed step says why and what to do next, and `--log <level>` streams the run's events as it goes
- **New**: `squiggle init --agent claude|copilot|codex` registers the MCP server with the agent you use, for Claude Code, Copilot or Codex
- **New**: `squiggle bench --pr <N>` posts the result as a sticky comment on the pull request
- **Fix**: `scroll` no longer crashes the simulator, and it actually scrolls
- **Fix**: a tap on an element off screen is refused instead of landing on whatever is there
- **Fix**: back-to-back flow runs pass: no screens left open by the previous run, and each run starts from where its flow expects to
- **Fix**: a run that launched your app gives up on one that never connects, and says why
- **Fix**: `squiggle flows` takes flow files as well as directories, and `squiggle agent run <name>` finds a program by name
- **Fix**: a react-native-macos app is driven in the background, and an action that did nothing is reported as a failure rather than a success
- **Perf**: `squiggle --version` answers in about 20 ms

### Agents & MCP

- **Breaking**: tool names drop the `squiggle_` prefix your client already adds, so `mcp__squiggle__squiggle_tap` is now `mcp__squiggle__tap`. Update any permission grant that names a tool. `squiggle_exec` is now `probe_read`
- **New**: `run_flow` runs agentic flows: your agent drives each agent step once, and every run after that replays it without a model
- **New**: `filmstrip` reads a recording's frames, for defects the graph cannot see
- **New**: `describe` and `find` see native views, such as an Expo Router native tab bar, that `tap` could already reach
- **New**: an action returns the screen it just changed, so the next step needs no second look
- **New**: every tool has a display title in your client
- **New**: every element knows the line that writes it: `describe {fields: 'source'}` shows it, and `find {callSite}` shows what a line renders
- **New**: `inspect` reads a component's live props, hooks and state
- **Fix**: no tool call waits forever, and one that hangs no longer blocks the rest
- **Fix**: `input_text` waits for the field to take focus, so the tap after it lands
- **Fix**: Studio and the CLI take port 7777 back from an idle MCP server
- **Fix**: a flow's secrets never reach the model, the run report or the recording
- **Fix**: the agent kit's hooks and slash commands run your installed `squiggle`, and its `plugin.json` starts the server with `squiggle mcp`. The kit no longer carries a `Stop` hook that only applied to Squiggle's own repository. Regenerate the kit after upgrading
- **Perf**: a tap with its observation returns in 110–185 ms, and choosing the target takes 7 ms instead of 300
- **Perf**: `perf_sql` and saved queries answer within a 24 KB budget with a truncation note, instead of reading the whole table first

### Flows & device

- **Breaking**: a step key that nothing reads is a parse error with its line number. It used to be ignored, and surfaced later as a selector that would not match
- **New**: `agent:` steps: a goal an agent drives, checked by a verifier you write, recorded beside the flow as `.agent.json` and replayed from then on
- **New**: declared routes, with route hints for agent steps
- **New**: a flow can declare that it fails by design, or that it runs some other way
- **New**: a flow's `config:` block carries the run settings it needs (scroll mode, settle and step timing, `autoScroll`, `strictAssert`), so a suite runs every flow the way it was written to run
- **New**: a recorded tap names the control it pressed
- **Fix**: an app launched without the agent is relaunched with it before a run, instead of running slower without it
- **Fix**: "keep software keyboard: off" keeps it off, and a run never takes over another app on its device
- **Perf**: a login flow runs in about a quarter of the time: the median went from 10.9 s at 0.1.0 to 2.7 s, and 2.3 s with `--direct-scroll`
- **Perf**: `squiggle flow` starts about 1.4 s sooner, and reconnects after a relaunch in 1.0 s instead of 6.2 s
- **Perf**: a suite spends less time resetting between flows, and its shards pull from one queue ordered by each flow's last duration

### Performance

- **New**: what Studio derives live (dead zones, scrolls, gesture tracks, the touch heatmap) is stored in `perf.db`, so your agent can query it
- **Perf**: the metric store keeps older samples at coarser resolution, so a store that had grown to 1.5 GB now takes about 30 MB. Product reads take under 2 ms, and writes are 4× cheaper

### SDK

- **New**: Legend State stores are instrumented by the Babel plugin, alongside Zustand, MMKV, AsyncStorage and SQLite
- **Perf**: the SDK does less work on your app's JavaScript thread, and sends about 31% fewer bytes per frame. Encoding a frame takes 122 ns instead of 360, and an app nobody connects to no longer holds 2.3 MB of memory for it

### Website

- **New**: try Studio in your browser at squiggle.sh/studio, against a live demo app, with a guided tour of 21 chapters across every screen
- **New**: docs pages open on live slices of it, and every page's header opens Studio over the page you are on
- **New**: on a phone, Studio plays its own tour, sized to read, with a chapter menu

### Everything else

- **Perf**: a crawl of the example app's 18 screens takes 46 s instead of 94 s, and never leaves the app
- **Perf**: checking the assertions of 421 recordings takes 3.9 s instead of 209 s, and seeking a recording is about 3.4× faster

[Open 0.2.0](https://squiggle.sh/changelog/0.2.0)

Public beta

## [0.1.0](https://squiggle.sh/changelog/0.1.0)16 August 2026

**Welcome to Squiggle.** This is the first public release, and the whole idea fits in a sentence: your app already knows what it is doing — its component tree, its state, its navigation, its network, its frame times — and until now nothing was asking. Squiggle puts a small SDK inside the running app, streams all of that into one queryable model, and then QA, performance, product analytics and agents stop being four tools that disagree and become four views over the same thing.

That model is the design, not a feature of it. A flow selector resolves against it, so a renamed button re-resolves instead of going red. A slow frame and the render that caused it are two queries over the same data. An agent reads it instead of screenshots — which is why a login journey runs end to end at zero model turns, and why every claim it makes carries the session and event it came from, for you to check rather than believe.

**What you install.** Six pieces, one version number, one licence. Start with the SDK: everything else is a view over the graph, and nothing produces a graph until the app is instrumented.

- **`@squiggle.sh/react-native`**: the SDK, and the only Squiggle code that goes inside your app. `bun add @squiggle.sh/react-native`, then one side-effecting import at the top of `index.js`. No provider, no config file, no account: the native accelerator and its single peer come along with it, idle cost is approximately zero while nothing is attached, and it checks no licence — the thing that has to be trusted enough to ship in your bundle asks nothing of you.
- **`@squiggle.sh/babel-plugin`**: a devDependency, and strictly optional. It is the difference between a component name and a clickable source location, and — with MMKV v4 — between storage spans and none.
- **`@squiggle.sh/cli`**: `npm install -g @squiggle.sh/cli`. Sixty-three commands from one typed tree, with an exit-code contract CI can branch on: `squiggle init` wires the SDK into an existing app, `squiggle up` relaunches it with the agent attached and proves it, `squiggle flow` runs a journey, and `--json` is on everything that returns data.
- **The desktop app**: the DMG on the download page, for Apple Silicon. The Studio, the Runtime Inspector, the Performance Center and the Agent Center, plus the same `squiggle` binary bundled inside the app, so installing one installs both. One licence and one project store across the two.
- **The MCP server**: already in the CLI, so there is nothing else to install. `squiggle init --mcp` merges the entry into your `.mcp.json` — your other servers survive untouched — and your agent gets seventy-five tools over one warm session, where a second question costs almost nothing.
- **The agent kit**: `squiggle agent kit --install` writes skills, a subagent per mode, hooks and slash commands into your agent, so it learns how to drive your app once instead of being told each time.
- **A licence**: `squiggle activate --trial` gives you fourteen days with no card. After that a licence verifies offline, on the machine, and CI takes a token instead.

**What beta means here.** Everything below this line works and is being used daily; beta is about the shape, not the parts. The SDK's public API is what we will be slowest to change, because it lives in your bundle. The CLI's flags, the MCP tool names and the flow vocabulary are where a breaking change is most likely before 1.0 — and every one of them will land here, on this page, with the version that made it.

### Desktop app

- **New**: one-click simulator bring-up, and a live canvas you can drive your app from
- **New**: the Runtime Inspector — eleven node kinds, the causality edges between them, and a render-flame tree you can scrub
- **New**: six overlay modes on the canvas, and a grid that watches several devices at once
- **New**: the Performance Center: flamegraphs, heap diffs, network waterfalls and baselines, side by side
- **New**: interaction analytics — a heatmap that knows which component was under the finger, not just where the pixel was

### CLI

- **New**: sixty-three commands from one typed tree, with an exit-code contract CI can branch on
- **New**: `squiggle init` wires the SDK into an existing Expo or bare app in one step, and is safe to run twice
- **New**: `squiggle up` relaunches your app with the agent attached — and proves it, rather than hoping
- **New**: `--json` on every command that returns data, so a run is pipeable into whatever you already have

### Agents & MCP

- **New**: an MCP server with seventy-five tools over one warm session, so a second question costs almost nothing
- **New**: a runtime that executes a compiled plan and wakes the model only at the decisions that need one — a login journey runs end to end at zero model turns
- **New**: every claim an agent makes carries the session and event it came from, so you can check it instead of believing it
- **New**: `squiggle agent kit --install` drops the skills into your agent, so it knows how to drive the app without being told each time

### Flows & device

- **New**: flows in YAML, with selectors that name what a control _means_ rather than where it sits — a moved button re-resolves instead of going red
- **New**: record a session and replay it offline, as many times as you like, against the same assertions
- **New**: three delivery planes, chosen per step, so a run is as fast as it can safely be

### Product analytics

- **New**: funnels with time-to-convert, cohort retention, feature affinity and release annotations — over the same events everything else reads

### SDK

- **New**: one install and one import. A Babel plugin and an Expo config plugin do the rest, and nothing ships to your users

### Licensing

- **New**: a fourteen-day trial with no card, and a licence that verifies offline once activated

[Open 0.1.0](https://squiggle.sh/changelog/0.1.0)
