diff --git a/content/docs/api/index.mdx b/content/docs/api/index.mdx index 664d0a7..7a5e987 100644 --- a/content/docs/api/index.mdx +++ b/content/docs/api/index.mdx @@ -1,39 +1,87 @@ --- title: "API" icon: "Braces" -description: "How to reach the Stunt Double platform programmatically: the MCP server, the public docs server, versioning and discovery." +description: "Every way to reach Stunt Double from code or an agent: the MCP server for your workspace, the no-account Index and docs servers, Markdown docs and llms.txt, and the public discovery files." --- -# Stunt Double API +# API and agent access -Stunt Double exposes its platform through a **Model Context Protocol (MCP)** -server at `https://app.stuntdouble.io/api/mcp` (Streamable HTTP, OAuth 2.1). -Drive your workspace from Claude, your own agents or any MCP client, without -writing a bespoke integration. +Stunt Double has no REST API for workspaces. Code and assistants act on a +workspace through the **Model Context Protocol (MCP) server**, which covers +projects, actors, checklists, runs, interviews, automations and feedback. Around it sit a few public, read-only surfaces that +need no account: an MCP server for the Stunt Double Index, one for the docs, +and plain-text files that describe the product to agents. -- **[MCP server](/mcp)**: authentication, scopes and what a connection can reach. -- **[Connect](/mcp/connect)**: set up Claude, Cursor, ChatGPT and other clients. -- **[Tools](/mcp/tools)**: every tool, prompt and resource, grouped by what it acts on. +| Surface | Endpoint | Sign-in | +| ------------------------------------- | -------------------------------------------------------------- | --------- | +| Workspace MCP server | `https://app.stuntdouble.io/api/mcp` | OAuth 2.1 | +| Workspace MCP server, tools on demand | `https://app.stuntdouble.io/api/mcp/dynamic` | OAuth 2.1 | +| Index MCP server | `https://app.stuntdouble.io/api/mcp/index` | None | +| Docs MCP server | `https://www.stuntdouble.io/api/docs-mcp` | None | +| These docs as Markdown | `https://docs.stuntdouble.io/llms.txt` and any page with `.md` | None | +| Discovery files | `https://www.stuntdouble.io/.well-known/...` | None | -## Public docs server +## Your workspace: the MCP server -Agents that haven't signed in can still connect. A read-only MCP server at -`https://www.stuntdouble.io/api/docs-mcp` needs no authentication and exposes -the documentation as resources. It has no tools: to act on a workspace, -connect to the product server above. +The workspace server acts as the signed-in person, with OAuth 2.1 in place of +API keys, and reaches only the workspaces they belong to. Runs are +asynchronous: a client starts one and polls until it finishes. +**[Connect](/mcp/connect#endpoints)** compares the full and on-demand +endpoints, **[MCP server](/mcp)** covers scopes and what a connection can +reach, and **[Tools](/mcp/tools)** lists every tool, prompt and resource. For a +walkthrough, see **[Automate Stunt Double from Claude](/tutorials/automate-with-mcp)**. -## Versioning +## Read-only servers with no account -A client negotiates the MCP protocol version at `initialize`. Breaking changes -ship alongside the old behavior, never in place, and deprecations are announced -in the [changelog](https://www.stuntdouble.io/changelog) at least 90 days -before removal. +- **Index.** `https://app.stuntdouble.io/api/mcp/index` carries the three + [Stunt Double Index](/index-ranking) read tools (`get_index_report`, + `list_index_sessions` and `search_index_domains`) with no sign-in. See + [Index lookups with no account](/mcp/connect#index-lookups-with-no-account). +- **Docs.** `https://www.stuntdouble.io/api/docs-mcp` exposes llms.txt, the + homepage as Markdown, the OpenAPI spec and the MCP manifest as resources. + It has no tools: to act on a workspace, connect to the workspace server. -## Discovery +## These docs, for agents -| What | Where | -| --------------------- | -------------------------------------------------------- | -| MCP manifest | `https://www.stuntdouble.io/.well-known/mcp.json` | -| AI Catalog | `https://www.stuntdouble.io/.well-known/ai-catalog.json` | -| OpenAPI spec | `https://www.stuntdouble.io/openapi.json` | -| Site index for agents | [`/llms.txt`](/llms.txt) | +Every page on this site has a Markdown twin. Append `.md` to its URL +(`https://docs.stuntdouble.io/concepts.md`), or request the page with +`Accept: text/markdown`. + +| File | What it holds | +| -------------------------------------------------- | ------------------------------------------------ | +| [`/llms.txt`](https://docs.stuntdouble.io/llms.txt) | An index of every page, linked to its Markdown | +| [`/llms-full.txt`](https://docs.stuntdouble.io/llms-full.txt) | Every page in one file | +| [`/.well-known/agents.md`](https://docs.stuntdouble.io/.well-known/agents.md) | When to use these docs and how to act for a user | +| `/sitemap.xml` | Every page with its last change | + +## Discovery files on stuntdouble.io + +Agents and MCP directories find Stunt Double through these files on +`https://www.stuntdouble.io`: + +| File | What it holds | +| --------------------------------------- | --------------------------------------------------------------------------------------------- | +| `/.well-known/mcp.json` | The MCP server manifest | +| `/.well-known/ai-catalog.json` | A catalog of Stunt Double's MCP servers | +| `/.well-known/oauth-protected-resource` | OAuth metadata for the MCP server: its authorization server and scopes | +| `/.well-known/agent-skills/index.json` | The Agent Skills Stunt Double publishes | +| `/openapi.json` | An OpenAPI 3.1 description of the public endpoints, with the MCP server as a single operation | +| `/llms.txt` | What Stunt Double is, for agents | + +The Stunt Double Index publishes its own at `https://index.stuntdouble.io`: +`/llms.txt`, an MCP server card at `/.well-known/mcp/server-card.json`, each +domain's findings as a prompt for a coding agent at +`/d/{domain}/fix-prompt.md`, and the score badge at `/badge/{domain}.svg`. + +## Versioning and limits + +- **MCP.** A client negotiates the protocol version at `initialize` and sends + it back in the `MCP-Protocol-Version` header. +- **Public endpoints.** The OpenAPI spec follows semantic versioning. A + breaking change ships under a new path or header value alongside the old + one, never in place, and a deprecation is announced in the + [changelog](https://www.stuntdouble.io/changelog) at least 90 days before + removal. +- **Rate limits.** Uncached public endpoints on stuntdouble.io allow 120 + requests a minute per client, and say so in `RateLimit` and + `RateLimit-Policy` headers. A refused request gets a 429 with `Retry-After`. diff --git a/content/docs/concepts/index.mdx b/content/docs/concepts/index.mdx index 3f05f81..b79b53a 100644 --- a/content/docs/concepts/index.mdx +++ b/content/docs/concepts/index.mdx @@ -1,146 +1,146 @@ --- title: "Concepts" icon: "compass" -description: "Actors, checklists, interviews, workflows, and insights: the building blocks of Stunt Double and how they relate." +description: "Short definitions of Stunt Double's building blocks (workspaces, actors, checklists, interviews, automations, issues and more) and how they relate, with a link to the page that goes deeper on each." --- # Core concepts Stunt Double is organized around a small number of building blocks. This page -explains each one and how they fit together. +defines each one and how it relates to the others. For how to use them, follow +the link at the end of each section. -| Term | In one line | -| --- | --- | -| Workspace | Your team: members, billing and every project | -| Project | One product or surface, and everything that tests it | -| Actor | An AI user with instructions and knowledge that drives a real browser | -| Checklist | Plain-language checks an actor verifies, each with evidence | -| Interview | A structured study run with persona participants, ending in a report | -| Live session | An actor using your product in real time while you watch and steer it | -| Automation | A graph of steps that runs checklists on a schedule or an event | -| Comment | A pin a real visitor drops on your page through the feedback widget | -| Insight | A notable observation surfaced from a run | +| Term | In one line | +| ------------ | ------------------------------------------------------------------------------------ | +| Workspace | Your team: members, billing and every project | +| Project | One product or surface, and everything that tests it | +| Actor | An AI user with instructions and knowledge that drives a real browser | +| Checklist | Plain-language checks an actor verifies, each with evidence | +| Interview | A structured study run with persona participants, ending in a report | +| Live session | An actor using your product in real time while you watch and steer it (early access) | +| Automation | A graph of steps that runs checklists on a schedule or an event | +| Comment | A pin a real visitor drops on your page through the feedback widget | +| Issue | A problem a run, review or comment found, tracked until it is fixed | +| Goal | What a project is trying to achieve, with the evidence linked to it | +| Idea | A recommendation your actors write after exploring the product together | +| Topology | A map of your product's screens and the paths between them | +| Device | A Mac in your workspace that runs work against sites inside your network | ## Workspaces and projects A **workspace** is the top-level container for your team. It owns members, -billing, and every project. A **project** sits inside a workspace and groups the -actors, checklists, and runs for one product or surface. Teams working on -several products keep them separated by using a project per product. +billing and every project. A **project** sits inside a workspace and groups the +actors, checklists, interviews and runs for one product or surface, so a team +with several products keeps them apart. A project's overview leads with its +latest run, anything running now and what changed since your last visit. ## Actors -An **actor** is an AI assistant you create. It is defined by its instructions -and its knowledge: +An **actor** is an AI user you create, named by the role it stands in for +("Busy shop owner"), never as a person. Three things define it: -- **Instructions** describe the actor's role and how it should behave. -- **Knowledge** is the reference material the actor can draw on, such as facts - about your product or test credentials. +- **Instructions**: who it is and how it behaves, written to the actor. +- **Personality**: how skeptical, how technically literate and how quickly + frustrated it is, set on sliders and applied everywhere it works. +- **Knowledge**: what it can look up mid-run (expertise, processes, reference + facts and test accounts), opened only when a task needs it. -Under the hood, an actor drives a real browser and works through your product -the way a person would, observing the page, taking an action, observing the -result, and repeating until the task is done. It can also read email sent to -its own inbox, which is what makes signup and verification flows testable. -Actor inboxes, and actors that stay signed in between runs, come with the -Startup plan and above. +An actor drives a real browser and works through your product the way a +person would: observe the page, act, observe the result, repeat. On the +Startup plan and above it also gets an inbox of its own for sign-up and +verification emails. See +**[Build an actor that behaves like your audience](/tutorials/first-actor)**. ## Checklists -A **checklist** is an automated verification workflow. You describe the steps you -want checked in plain language, and an actor runs through them in a hosted -browser. Each step is reported as passed or failed, with a screenshot and a -short explanation. - - - -Checklists are the fastest way to catch regressions in flows that are tedious to -test by hand, such as signup, checkout, or onboarding. +A **checklist** is a set of checks written in plain language, each describing +an outcome that should be true. An actor runs through them in a browser and +reports each one as passed or failed, with a screenshot and a short +explanation. A check can block the run, add to a score or just record what the +actor saw. Checklists are the fastest way to catch regressions in flows that +are tedious to test by hand, such as sign-up, checkout or onboarding. See +**[Write checklists that catch real regressions](/tutorials/effective-checklists)**. ## Interviews -An **interview** is a structured conversation Stunt Double runs with your users. -You define sections and questions, the platform conducts the interview, and it -produces a report summarizing what it learned. Interviews are useful for user -research and feedback gathering at a scale that manual interviews cannot reach. +An **interview** is a structured study run with persona participants: your +actors, or personas generated for the study. You write a guide of questions +and tasks, each participant works through your product and answers in +character, and every round ends in a report of themes, quotes, the screens +behind them and a usability score. See +**[Run a user interview](/tutorials/running-an-interview)**. ## Live sessions -A **live session** puts you beside an actor while it works: the browser on one -side, the chat on the other, and the steps it takes underneath. Give it a task -or interview it in character, change direction mid-task, or take the browser -and drive it yourself. Sessions run in a cloud browser or, from the desktop -app, in a browser on your own Mac. See +A **live session** puts you beside an actor while it works, so you can steer +it, interview it in character or take over the browser. Live sessions are in +early access and switched on per workspace. See **[Run a live session](/tutorials/live-sessions)**. ## Workflows -A **workflow** (an **automation** in the dashboard) chains steps into a single repeatable automation. Where a -checklist verifies a flow, a workflow is meant to get something done end to end, -and can combine several actions into one run. +A **workflow**, called an **automation** in the dashboard, is a graph of steps +started by a trigger. Where a checklist verifies one flow, an automation +decides when checklists run and what happens with the result: post a comment +on a pull request, notify a channel, branch on a condition. See +**[Automate multi-step workflows](/tutorials/building-workflows)**. ## Comments and the feedback widget -Actors report what an AI persona experienced. **Comments** cover the other half: -what a real visitor experienced. The **feedback widget** is a small script you -add to your own site, letting visitors drop a pin anywhere on a page and leave a -comment in the place it applies to. +Actors report what an AI persona experienced. **Comments** cover the other +half: what a real visitor experienced. The **feedback widget** is a small +script you add to your own site, so visitors can drop a pin anywhere on a page +and leave a comment where it applies. Each comment arrives with a screenshot, +the page and device details, and only domains you approve can send them. See +**[Collect stakeholder feedback on a prototype](/tutorials/feedback-widget)** +and the **[feedback widget reference](/integrations/feedback-widget)**. -Each comment arrives with a screenshot, the page URL, the pin position, and -device details, and lands in the project's Comments view grouped by page. From -there you reply in the thread and move each one through **new**, **reviewed**, -**resolved**, or **dismissed**. +## Issues, goals and ideas [#insights] - - The widget is identified by a per-project API key that lives in your page source, so the real - access control is the **domain allowlist** on the project: the widget API only answers requests - from domains you have approved. Workspace admins can narrow that further, or switch the widget off - across the whole workspace, from Settings → Security. - +**Issues** are the problems a project needs to fix. Failed checks, open design +review notes and new comments show up on the project's **Issues** page on +their own, each linked to its evidence, and become tracked issues in a click. +See **[Review runs and act on them](/tutorials/reviewing-runs)**. -See **[Collect stakeholder feedback on a prototype](/tutorials/feedback-widget)** -for installation and triage. +**Goals** say what a project is trying to achieve, such as "New visitors finish +sign-up without help". Link feedback and ideas to the goal they support, so the +evidence for each goal sits in one place. -## Insights +**Ideas** come from a co-create session: say what you want to learn and pick +the actors, and each explores the product before they turn what they found into +ideas and recommendations. Problems they find become issues. -As actors work, Stunt Double surfaces **insights**: notable observations drawn -from a run, such as a confusing step, a broken link, or an unexpected result. -Insights turn raw session recordings into something you can act on without -watching every replay. +## Topology -## Issues and goals +A **topology** is a map of your product: its screens, the paths between them +and what changed since the last version. An actor crawls the site to draw it, +and pages that checklist runs and interview participants visit are added as +you test. Topology is in preview. -Each project has an **Issues** tab. Problems your runs and reviewers have -already found appear there on their own: failed checks, open design review -notes, untriaged comments and insight findings, each linked back to its -evidence. Turn one into a tracked issue in a click, then move it through open, -in progress, resolved or dismissed. The highest severity sits at the top. +## Devices -**Goals** say what a project is trying to achieve, such as "New visitors finish -sign-up without help". Link insights and feedback to the goal they support, so -the evidence for each goal sits in one place. A goal is active until you mark -it completed or archive it. +A **device** is a Mac in your workspace running the desktop app, on any paid +plan. On the Startup plan and above, runs against a site only reachable inside your network +go through a device, using that Mac's network and sign-ins. See +**[Devices](/integrations/self-hosted-workers)**. ## Recordings and replays Everything an actor does is recorded. For any run you can replay the session, -step through each action, and see the screenshot captured at that moment. This -is what makes a failed checklist or a surprising interview answer easy to +step through each action and see the screenshot captured at that moment, which +is what makes a failed check or a surprising interview answer easy to diagnose. ## Next steps -Ready to automate this? See the **[API overview](/api)** and the -**[MCP server](/mcp)**, and connect the tools your team already uses from -**[Integrations](/integrations)**. +To drive any of this from code or an assistant, see **[API and agent +access](/api)** and the **[MCP server](/mcp)**. To connect the tools your team +already uses, see **[Integrations](/integrations)**. diff --git a/content/docs/getting-started/index.mdx b/content/docs/getting-started/index.mdx index b6c5709..decde44 100644 --- a/content/docs/getting-started/index.mdx +++ b/content/docs/getting-started/index.mdx @@ -1,12 +1,14 @@ --- title: "Quickstart" icon: "rocket" -description: "Create a workspace, add your first actor, and run a checklist against your product in a few minutes." +description: "The first-run path: create a workspace, give Stunt Double your URL, watch the first checklist run and read its evidence." --- # Quickstart -This guide takes you from a new account to your first checklist run. +This is the one path from a new account to your first run and its evidence. +Everything it skips (writing actors, tuning checks, interviews) is a tutorial +of its own, linked at the end. -### Create a project +### Tell it what to test + +Enter your product's URL. Stunt Double reads the site, writes actors for the +people who use it and picks the flows worth checking first, as checklists in +your first **project**. It takes a couple of minutes, and the project also +gets a first agent readiness score from the +**[Stunt Double Index](/index-ranking)**. -Inside the workspace, create a **project** for the product or surface you -want to test. A project keeps related actors, checklists and runs together, so -a team with several products keeps them apart. +No URL yet? Choose **I don't have a URL yet** and describe the product and who +it is for instead. The checklists wait, and run as soon as you add a URL to the +project. -### Create an actor - -An **actor** is an AI user that does the work. Open **Actors** in the -sidebar, choose **Create actor**, and pick a template or start from scratch. -Then give it: +### Watch your first run -- **Instructions** that describe who it is and how it behaves. -- **Knowledge** it can draw on: facts about your product, test accounts, - conventions to follow. - -Out of the box an actor drives a real browser and reads email sent to its own -inbox, so it works through your product the way a person would. For a first -run, a one-paragraph description of your audience is plenty. - - +When setup finishes, choose **Watch your first run**. An actor opens a hosted +browser and works through the first checklist while you watch. To run any +other checklist, open it from **Checklists** and press **Run**. -### Write and run a checklist - -In the project, open **Checklists** and choose **Create checklist**. A -checklist is a set of checks written in plain language, for example: +### Read the evidence -1. Open the pricing page. -2. Confirm the Pro plan shows a monthly and an annual price. -3. Start sign-up and confirm it reaches the email step. +Every run is recorded. Open the finished run to see each check's result with +the screenshot the actor took and its explanation, then replay the session if +you need more. Failed checks also wait for you on the project's **Issues** +page. -Create the checklist, then press **Run** on its page. The actor opens a -hosted browser and works through each check. - -### Review the run +### Add a check of your own -Every run is recorded. Open it to replay the session, inspect each check's -result and screenshot, and see any **insights** the platform surfaced. +Open **Checklists**, choose **Create checklist** and pick a template or +**Start from scratch**. Write each check as a plain-language outcome, such as +"Confirm the Pro plan shows a monthly and an annual price", choose the actor +and URL, then create the checklist and press **Run**. The actor works out the +clicks. + + A hosted browser can't reach a site that is only available inside your + network. On the Startup plan and above, a Mac in your workspace runs those + checks instead. See + **[Devices](/integrations/self-hosted-workers)**. + + ## Next steps Claude, - select **Download .mcpb** and open the file with Claude Desktop (needs - Node 18 or later). -- **Claude (web or desktop), manual**: in Claude, open Settings > Connectors > - Add and paste the URL `https://app.stuntdouble.io/api/mcp`. - -See **[Claude](/mcp/clients/claude)** and **[MCP](/mcp)** for more detail. - -The first time Claude uses a Stunt Double tool, a browser window opens to sign -in and authorize. No API keys. +Add Stunt Double to Claude as a connector, either the one-click Claude Desktop +extension or the server URL in Claude's connector settings. +**[Connect a client](/mcp/connect)** has both. The first time Claude uses a +Stunt Double tool, a browser window opens to sign in and authorize. No API +keys. @@ -17,44 +17,16 @@ persona before merge, with results reported where engineers already look. ## Setup -1. **Connect your coding agent** (plugin preferred, MCP config as a fallback): +1. **Connect your coding agent.** For Claude Code, the + [Stunt Double plugin](/mcp/clients/claude-code-plugin) bundles the MCP + server with skills and agents; Cursor has a + [plugin](/mcp/clients/cursor) too. Any other MCP-capable agent takes the + server URL, as **[Connect a client](/mcp/connect)** describes. You authorize + in the browser on first use; no API keys. - **Claude Code:** install the - [official Stunt Double plugin](https://claude.ai/customize/plugins/id/9cd49c97-13c2-4844-bc3d-53ef7956c1ef%40anthropic-plugin-directory) - from Claude's plugin directory (server plus skills and agents), or add the - server, or install the plugin from the terminal: - - ```bash - claude mcp add --transport http stuntdouble https://app.stuntdouble.io/api/mcp - ``` - - ```bash - claude plugin marketplace add stunt-double/stuntdouble-mcp - claude plugin install stuntdouble@stuntdouble - ``` - - **Cursor:** install the - [Stunt Double Cursor plugin](https://github.com/stunt-double/stuntdouble-mcp) - (MCP server plus skills, rules and agents). From the - [Cursor marketplace](https://cursor.com/marketplace) once listed, or add the - repo as a team marketplace (Dashboard → Plugins → Team Marketplaces → Add - Marketplace → Import from Repo), then install `stuntdouble` from Customize. - - **MCP only** (Cursor without the plugin, Windsurf, or any other JSON-config - client): - - ```json - // .cursor/mcp.json or ~/.cursor/mcp.json - { "mcpServers": { "stuntdouble": { "url": "https://app.stuntdouble.io/api/mcp" } } } - ``` - - You authorize via browser on first use; no API keys. **[MCP](/mcp)** has - setup for more clients. - -2. **Connect GitHub** to your workspace (**Integrations** > GitHub > - **Connect GitHub**, then **Install GitHub App** for the repositories you - choose) so agents can read PRs and post results, and workflows can trigger - on GitHub events. See **[GitHub](/integrations/github)**. +2. **Connect [GitHub](/integrations/github)** for the repositories you work + in, so agents can read PRs and post results, and automations can trigger on + GitHub events. 3. **Teach your agent the habit.** Add a note to your repo's agent instructions (`CLAUDE.md`, `.cursorrules`, etc.) so verification happens by @@ -120,8 +92,8 @@ run. ## Workflow: from bug report to fix without a human repro -Feedback captured by Stunt Double (pinned to a page, with screenshot and -device info) is agent-readable: +Comments people leave through the [feedback widget](/guides/feedback-widget) +(pinned to an element, with a screenshot and device info) are agent-readable: > “Triage the new feedback on the dashboard project; reproduce anything that > looks like a bug.” diff --git a/content/docs/guides/feedback-widget.mdx b/content/docs/guides/feedback-widget.mdx index 8635026..9ed4b38 100644 --- a/content/docs/guides/feedback-widget.mdx +++ b/content/docs/guides/feedback-widget.mdx @@ -1,7 +1,7 @@ --- title: "Stakeholder feedback" icon: "feedback" -description: "Install the feedback widget so visitors pin comments in context, then triage them alongside what your actors find." +description: "When to put the feedback widget on staging, a beta or production, and how to turn what people pin into checks that run on every deploy." --- AI personas tell you what a careful, unhurried user would hit. Real visitors @@ -11,8 +11,9 @@ your own site, and anyone looking at a page can drop a pin on the exact spot that confused them and say why. What arrives is not a support ticket with "the page is broken" in it. It is a -comment anchored to a coordinate, with a screenshot of the page as that person -saw it, the URL, the viewport, and which version of the page they were on. +comment attached to the element it is about, with a screenshot of the page as +that person saw it, the URL, the viewport, and which version of the page they +were on. PMs and designers running prototype and staging reviews, founders collecting @@ -20,43 +21,35 @@ saw it, the URL, the viewport, and which version of the page they were on. Slack with no idea which page or build they came from. -## Setup, in about five minutes +## The pieces, in order Comments' }, - { label: 'Install', sub: 'One script tag' }, - { label: 'Allow', sub: 'Your domains only' }, + { label: 'Install', sub: 'One script tag per site' }, + { label: 'Decide who', sub: 'Domains and sign in' }, + { label: 'Collect', sub: 'Pins on the real page' }, { label: 'Triage', sub: 'Reply and resolve' }, + { label: 'Guard', sub: 'Checks for repeat issues' }, ]} /> -Enable **Comments** on the project, paste one script tag before `` (or -hand the install prompt to a coding agent), and the install screen flips to -**Widget detected** once a page loads it. Then set your allowed domains before -you point anyone at it. The -[integration reference](/integrations/feedback-widget) has the snippet and -every setting. - -## What a visitor does - -Press **`c`** or click the floating button, click the thing you mean, type the -comment, send. Name and email are remembered on their browser, so the second -comment is just the comment. Email is optional and only used to tell them when -someone replies or marks their comment resolved. - -If you enable **Show comments on page**, existing pins render for everyone, so a -group review turns into a shared thread rather than five people reporting the -same button. Turn it off and the widget still collects, it just does not -display. +Installing takes a few minutes and is the same everywhere: see the +[integration reference](/integrations/feedback-widget) for the snippet, every +setting and who can use it. To try one complete round first, follow +[Collect stakeholder feedback on a prototype](/tutorials/feedback-widget). The +rest of this guide is about choosing how to run it and what to do with what +comes back. - The pin is the point. A comment attached to a coordinate and a screenshot - needs no reproduction steps. + The pin is the point. A comment attached to an element and a screenshot needs + no reproduction steps. ## Three ways teams use it +The same script tag serves three quite different jobs. What changes is two +settings: **Require sign in** and **Show comments on page**. + -**Internal review on staging.** Switch on **Require sign in** and only signed-in -members of your workspace can read or leave comments. Reviewers sign in through -a popup from the widget, and their replies are badged **Team** on the page. It -is the cheapest possible design-review tool: no seats to provision, no file to -upload, and the thing under review is the actual product. - -**Prototype and beta testing.** Ship the rough version to a handful of real -users with the widget on. Where pins cluster is your friction, and you have the -screenshot to prove it. This pairs directly with persona interviews: run an -interview to find what a careful user hits, run the widget to find what a -hurried one does. +**Internal review on staging.** Turn on **Require sign in** and keep comments +shown. Only workspace members can read or leave comments, their notes are +badged **Team**, and a group review becomes one shared thread per issue rather +than five people reporting the same button. It is the cheapest possible +design-review tool: no seats to provision, no file to upload, and the thing +under review is the actual product. + +**Prototype and beta testing.** Leave sign-in off and send the link to a +handful of real users. Hide comments on the page if you want independent +reactions rather than people agreeing with the first pin. Where pins cluster is +your friction, and you have the screenshot to prove it. This pairs directly +with persona interviews: run an +[interview](/tutorials/running-an-interview) to find what a careful user hits, +run the widget to find what a hurried one does. **A standing channel on production.** Leave it installed with sign-in off and comments hidden from other visitors. People report what bothers them where it -bothers them, and it lands in a queue rather than a support inbox. - -## Triage without losing the thread - -Comments are grouped **by page**, because that is how fixes get made. Each group -shows every pin left on that page, and you collapse the ones you have handled. - - - -Open one and you get the screenshot with the pin in place, the device and -viewport, the reply thread, and the status. Reply and the visitor is notified if -they left an email, with your reply appearing on the page for them. Move it -through **new**, **reviewed**, **resolved**, or **dismissed**; resolving notifies -the author, which is the difference between collecting feedback and closing a -loop. After a round of fixes, **Resolve all** clears the open queue in one go. - -### Versions, so old comments stay readable - -Pages change, and a comment about a button you deleted is noise unless you know -which build it was about. Every comment records a hash of the page content, and -comments are grouped into **v1**, **v2**, and so on, with the newest badged -**Latest**. Select a version to see only the comments left on it. +bothers them, and it lands in a queue grouped by page and version rather than +in a support inbox. Declare a version on each release (see +[Versions](/integrations/feedback-widget#versions)) so a week of comments reads +back by build, not by guesswork. -If you would rather tie versions to your releases than to page content, set -`data-sd-version` on the script tag to a build ID, release tag, or commit SHA. -The widget then uses that verbatim. +## Close the loop with the people who commented -## Who can actually use it +Collecting feedback and going quiet is worse than not collecting it. The +**Comments** view gives you three ways to answer: reply in the thread (the +reply shows on the page, and the author is emailed if they left an address), +resolve (which notifies the author), and **Summarise**, which turns a busy +queue into themes, open questions and a brief for a coding agent. The +[tutorial](/tutorials/feedback-widget#4-triage-what-comes-back) goes through +each. -The API key in your page source is an identifier, not a secret. The domain -allowlist decides which sites the widget answers, **Require sign in** limits it -to workspace members, and workspace admins can narrow or switch it off for -every project. See -[Control who can use it](/integrations/feedback-widget#control-who-can-use-it). +The habit that keeps the queue useful: resolve as you ship, and use **Resolve +all** after a round of fixes. An open queue that reflects genuinely outstanding +work gets looked at; one that has become an archive does not. @@ -133,9 +109,11 @@ ones into checks: 4. Resolve the comment (update_feedback_status) so the author is notified ``` -All three feedback tools are on the MCP server, so an agent can work that loop -with you: "read the new comments on the pricing page, reproduce the top one with -a checklist, and tell me what you find." See the +The feedback tools are on the MCP server (see +[Use it from an agent](/integrations/feedback-widget#use-it-from-an-agent)), so +an agent can work that loop with you: "read the new comments on the pricing +page, reproduce the top one with a checklist, and tell me what you find." The +`triage_feedback` prompt packages it. See the **[codebases guide](/guides/codebases)** for the deploy-trigger side, and the **[validation playbook](/guides/validation)** for turning findings into standing checks. @@ -146,9 +124,8 @@ checks. immediately and nothing is exposed while you are still deciding. - Only ask for an email if you intend to reply. Collecting addresses and going quiet is worse than not collecting them. -- Set `data-sd-version` if you deploy several times a day. Content hashing works, - but grouping by release is unambiguous when you are reading back a week later. -- Resolve aggressively. An open queue that reflects genuinely outstanding work - gets looked at; one that has become an archive does not. +- Declare a version if you deploy several times a day. The automatic fingerprint + works, but grouping by release is unambiguous when you are reading back a + week later. - Turn off the `c` shortcut if your own page already uses it. It is one toggle, and clashing shortcuts confuse visitors more than they help. diff --git a/content/docs/guides/figma-make.mdx b/content/docs/guides/figma-make.mdx index 931e45a..555ed9c 100644 --- a/content/docs/guides/figma-make.mdx +++ b/content/docs/guides/figma-make.mdx @@ -1,7 +1,7 @@ --- title: "Figma Make" icon: "figma" -description: "Publish a Make site and have AI personas try to use it before an engineer touches it." +description: "The build, publish, test, revise loop: interview AI personas on a published Make site before an engineer touches it." --- Figma Make turns a prompt or a design into a working web app and publishes it @@ -15,14 +15,14 @@ use it, all before an engineer touches it. before committing to a build. -## Setup +## What you need -- Add the Stunt Double MCP connector to the agent you use around Make (Claude, - Claude Code, Cursor): `https://app.stuntdouble.io/api/mcp`. Sign in when - prompted the first time. **[MCP](/mcp)** covers each client. -- Optionally connect Figma from **Integrations** at - [app.stuntdouble.io](https://app.stuntdouble.io) so workflows can also react - to Figma events. See **[Figma](/integrations/figma)**. +- The Stunt Double MCP server in the agent you use around Make (Claude, Claude + Code, Cursor). **[Connect a client](/mcp/connect)** covers each one. +- Nothing in Make itself. A published Make site is a public URL, and actors + need nothing else; there is no SDK to embed. The + **[Figma connection](/integrations/figma)** is optional and only matters once + you want automations to react to Figma events. ## The loop: build, publish, test, revise @@ -39,8 +39,7 @@ use it, all before an engineer touches it. 1. **Build in Make.** Get the prototype to the point where the core flow exists, even roughly. Real (fake) content beats lorem ipsum: personas read the page like users do. -2. **Publish.** Use Make's publish action to get the live site URL. Stunt - Double needs nothing else; there is no SDK to embed. +2. **Publish.** Use Make's publish action to get the live site URL. 3. **Test with personas.** From your agent, use the `validate_design` prompt with the published URL, or be specific: @@ -82,8 +81,6 @@ validation come along: ## Tips -- Test the ugly version. The strongest signal comes before you polish; - personas are immune to embarrassment. - One flow per round. "Can they sign up" and "do they understand pricing" are separate studies; mixing them muddies the report. - Watch a session recording in the dashboard at least once per round; seeing a diff --git a/content/docs/guides/figma.mdx b/content/docs/guides/figma.mdx index 6746eb8..bcdb531 100644 --- a/content/docs/guides/figma.mdx +++ b/content/docs/guides/figma.mdx @@ -1,13 +1,13 @@ --- title: "Figma prototypes" icon: "figma" -description: "Walk prototypes with personas and re-check the built flows automatically when a file changes." +description: "Which Stunt Double piece to use with Figma for prototype testing, frame reviews and re-checking the built product when a file changes." --- Figma is where the design decisions happen; Stunt Double is how you find out -whether users can actually follow them. The integration works at two levels: -agent-driven testing of prototypes (via MCP), and event-driven automation that -re-checks work whenever a file changes (via the Figma connection). +whether users can actually follow them. Three pieces cover different moments +in a design's life, and this guide is about which to reach for and how they +combine. Designers validating flows before handoff, design-systems teams guarding @@ -15,28 +15,21 @@ re-checks work whenever a file changes (via the Figma connection). buried in a separate report. -## Setup - -1. **Connect Figma and link files to projects**, as - **[Figma](/integrations/figma#set-it-up)** describes. That turns on Figma - triggers for workflows and keeps runs, feedback and interviews attached to - the design source. -2. **For agent workflows**, add the Stunt Double MCP connector to whichever - agent you use alongside Figma (Claude, Claude Code, Cursor): - `https://app.stuntdouble.io/api/mcp` (setup per client in - **[MCP](/mcp)**). If you also run Figma's own MCP - server, the two compose well: Figma MCP reads and edits the design, Stunt - Double MCP tests it. - - -## Workflow: test a prototype with personas +None of them depends on another. Most teams start with the MCP server for +prototype testing, then add the connection once there is a built product to +keep in step with the design. Setup for each lives on its own page: +[MCP](/mcp), the [Figma plugin](/integrations/figma-plugin) and the +[Figma connection](/integrations/figma). + +## Test a prototype with personas Actors drive real browsers, so anything viewable at a URL is testable. For Figma that means: @@ -45,39 +38,66 @@ Figma that means: link can view". Good for click-through flow testing: can a persona find their way from the landing frame to the goal? - **Figma Make published sites** for anything with real interaction. See the - dedicated **[Figma Make guide](/guides/figma-make)**. + **[Figma Make guide](/guides/figma-make)**. From your agent: -> “Use the validate_design prompt on my prototype link with personas for our -> two main segments. Focus on whether the new onboarding order makes sense.” +> "Use the validate_design prompt on my prototype link with personas for our +> two main segments. Focus on whether the new onboarding order makes sense." The agent creates an interview, adds task items ("Get from the welcome screen to creating your first project"), attaches varied personas (mix devices; prototypes often fail on mobile first), launches, and returns the synthesized report with transcripts as evidence. +If you also run Figma's own MCP server, the two compose well: Figma MCP reads +and edits the design, Stunt Double MCP tests the result, and the agent carries +the findings from one to the other. + + + Personas can only follow the interactions you wired. A "could not proceed" finding sometimes means a missing hotspot rather than a design flaw; the transcript makes it obvious which. -## Workflow: re-check automatically when the design changes +## Review frames before there is a prototype -This is the predictive half. Once Figma is connected, workflows can trigger on -Figma events: +A prototype link needs wiring. Earlier than that, a static frame can still be +judged. The [Figma plugin](/integrations/figma-plugin) exports the selected +frame for actors to review, places their findings on the canvas as annotations +next to the layers they are about, and re-checks once you have fixed them. It +can also run a project's checklist against a sequence of frames, or hand a +prototype link to Stunt Double to start an interview. Use it for the quick +critique pass inside the file; use an interview when the question is whether +someone can complete a flow. -1. Create checklists for the flows the design feeds (staging or production - URLs). -2. Create a workflow with a Figma event trigger and steps that run those - checklists, plus a notification step. -3. Activate it. +## Re-check the product when the design changes + +This is the predictive half. Once a design has been built, the risk moves from +"can users follow this" to "does the product still match it". With the +[Figma connection](/integrations/figma) in place, an automation can start on a +Figma event: + +1. Create checklists for the flows the design feeds, against staging or + production URLs. +2. Create an automation with the **Figma** trigger on the design file (or the + library file), and add steps that run those checklists and send a + notification. +3. Turn it on. The [trigger settings](/integrations/figma#set-it-up) explain + which events to pick and the access the connected Figma account needs. -## Workflow: brand and design-system guardianship - -Give an actor your brand guidelines as knowledge (voice, spacing rules, color -usage, component dos and don'ts) and use it to run checklists like: - -- "Every page uses the product font stack; no default serif fallbacks - anywhere." -- "Primary CTAs use the brand primary color and sentence case." -- "Empty states show the illustration style, not stock icons." +## Guard the design system -Run these against staging on a schedule or on library publishes, and the -design system stops drifting silently. The `check_brand` and -`check_design_system` MCP prompts encode this whole workflow; the -**[validation guide](/guides/validation)** covers the pattern in depth, -including compliance and cross-surface continuity audits. +The same trigger is the natural home for a design-system audit: a reviewer +actor that holds your tokens and component rules, a checklist of visual checks +against staging, and an automation that runs it whenever the library is +published. The **[validation guide](/guides/validation#design-system-adherence)** +covers the pattern, with a complete example, and the `check_design_system` MCP +prompt sets it up. ## Tips @@ -113,6 +126,9 @@ including compliance and cross-surface continuity audits. do not have Figma accounts. - Name interviews after the design iteration ("Onboarding v3, post-crit") so before/after comparisons are easy. -- Feedback captured in Stunt Double carries page URL, pin position, and - screenshots, which maps naturally back to frames when you triage with the - `triage_feedback` prompt. +- Re-run the same interview after each iteration rather than starting a new + one. Unchanged tasks and personas make the differences attributable to the + design. +- Point the design-change automation at the file that actually changes. An + automation listens to one file, so a library and the screens built from it + need one each. diff --git a/content/docs/guides/index.mdx b/content/docs/guides/index.mdx index d6cc360..f85dd4f 100644 --- a/content/docs/guides/index.mdx +++ b/content/docs/guides/index.mdx @@ -1,11 +1,13 @@ --- title: "Guides" -description: "How Stunt Double plugs into the tools where the work already happens." +description: "Workflows that combine Stunt Double with the tools where the work already happens: when to use each, and in what order." --- # Guides -How Stunt Double plugs into the tools where the work already happens. +Workflows that combine Stunt Double with the tools where the work already +happens. Each guide covers when and why, which pieces to use and in what order, +and links to the integration and tutorial pages for setup. notification (#design-system) ``` @@ -189,7 +194,7 @@ Checklist Compliance sweep: acquisition (run by Compliance Reviewer, url: acm cookie banner, footer links, pricing, and a marketing email. Checks: - A cookie banner appears before any non-essential tracking fires. - - The banner's reject option works and is honoured. + - The banner's reject option works and is honored. - Privacy policy and terms are reachable from every page footer. - Displayed prices include GST or clearly state they exclude it. - The latest marketing email has a working unsubscribe link. @@ -218,10 +223,6 @@ Workflow Weekly continuity check -> notification (#growth) ``` -For promise-versus-product continuity, an interview is a better fit than a -checklist: attach a persona and give it the task "the homepage says setup takes -two minutes; sign up and see if that holds", then read the transcript. - ## Where this fits in the other workflows - **Codebases**: run a compliance or brand audit against the preview diff --git a/content/docs/index-ranking/improve-your-score.mdx b/content/docs/index-ranking/improve-your-score.mdx index 1499fac..3bc4ca7 100644 --- a/content/docs/index-ranking/improve-your-score.mdx +++ b/content/docs/index-ranking/improve-your-score.mdx @@ -1,7 +1,7 @@ --- title: "Improve your score" icon: "TrendingUp" -description: "Read a site's Stunt Double Index report, find what agents struggle with, fix it, and re-score, from the dashboard or through the MCP server." +description: "Go from a Stunt Double Index report to a ranked list of fixes, then re-score the site once they ship, from the Index or through the MCP server." --- # Check and improve a site's score @@ -12,7 +12,9 @@ once they ship. You can do all of it at [index.stuntdouble.io](https://index.stuntdouble.io), or ask your AI assistant to do it through the [MCP server](/mcp), which ships -the `check-agent-readiness` [skill](/mcp/skills). +the `check-agent-readiness` [skill](/mcp/skills). Reading reports needs no +account: the [Index MCP endpoint](/mcp/connect#index-lookups-with-no-account) +carries the read tools with no sign-in. @@ -21,7 +23,10 @@ the `check-agent-readiness` [skill](/mcp/skills). Open the site's report, or call `get_index_report` with its domain. If your Stunt Double project is linked to an Index domain, pass its `project_id` -instead. Start with the lowest categories and providers. +instead. If the Index doesn't track the site yet, add it from the Index or +with `request_index_score`, which runs the probes in under a minute (pass +`include_agent_sessions` for live sessions too). Start with the lowest +categories and providers. @@ -51,7 +56,9 @@ or look up named competitors, and read the reports worth contrasting. 2. Frictions that recur across providers. 3. Issues that only one provider hits. -Tie every fix to a failing check or a session friction. For legacy pages that +Tie every fix to a failing check or a session friction. The scorecard's +**Copy fix prompt** turns the frictions into a prompt for your coding agent. +For legacy pages that can't be rebuilt soon, [WAO](/stuntkit/wao) repairs the accessibility tree agents read without changing the page. @@ -60,8 +67,11 @@ agents read without changing the page. ### Re-score once the fixes ship -Re-run the domain (`request_index_rerun`) for fresh probes and about 24 agent -sessions. Only the domain's owner can re-run it. Poll +Re-run the domain (`request_index_rerun`, or from the domain's dashboard on the Index) +for fresh probes and about 24 agent sessions. Only the domain's owner can +re-run it: the account that claimed it or, while it is unclaimed, an account +with an email on that domain. A domain can be re-run once every 10 minutes. +Poll `list_index_sessions` with the returned `run_id` until no session is running, then compare the new report with the old one, category by category. @@ -70,8 +80,8 @@ then compare the new report with the old one, category by category. Before the re-run, confirm the fix on a preview deployment with a - [checklist](/concepts#checklists), then run that checklist on every deploy - with an [automation](/concepts#workflows). + [checklist](/tutorials/effective-checklists), then run that checklist on + every deploy with an [automation](/tutorials/building-workflows). ## Next steps diff --git a/content/docs/index-ranking/index.mdx b/content/docs/index-ranking/index.mdx index 0e898b3..e593240 100644 --- a/content/docs/index-ranking/index.mdx +++ b/content/docs/index-ranking/index.mdx @@ -1,7 +1,7 @@ --- title: "Stunt Double Index" icon: "Gauge" -description: "The Stunt Double Index is a public ranking of how well AI agents can find, understand and act on a website, scored from HTTP probes and live agent sessions." +description: "What the Stunt Double Index is: a public ranking of how well AI agents can use a website, how a score is made, what it measures, and how to add, claim and share a site." --- # Stunt Double Index @@ -19,29 +19,44 @@ report, including your competitors'. A score comes from two kinds of evidence: -- **Probes.** HTTP checks that look at what agents depend on, such as whether - pages are server-rendered, structured data is present and agents are allowed - in. Each failing check is listed with its weight. -- **Agent sessions.** Live sessions, one per AI provider and benchmark task, - where an agent tries a real job on the site. Each session records what the - agent tried, its rubric evidence, a summary and the frictions it hit. - -A full run is the probes plus about 24 agent sessions. Stunt Double runs the -sessions on the same [browser toolset](/stuntkit/browser-toolset) its actors -use. +- **Probes.** Quick HTTP checks that look at what agents depend on, such as + whether the site is reachable, says what agents may do, and publishes the + files and structured data agents look for. Each failing check is listed with + its weight. +- **Agent sessions.** Live sessions in a real browser, where each AI provider + tries the jobs a customer would: research the brand, its prices and + policies; go from the homepage to signing up or checking out; find how an + agent could act for a customer; and find how to reach the business. A + separate grader marks each session against a fixed rubric, and each session + records what the agent tried, its evidence, a summary and the frictions it + hit. Each model is also asked, with no browser, how the site compares with + its competitors. + +What the agents managed counts for more than the probes. The combined score is +then calibrated against every other site the Index scores, so a number reads +the same way in every sector. + +A full run is the probes plus about 24 agent sessions. The top 50 sites get a +monthly run of the main agent sessions; other sites get the probes. Stunt Double +runs the sessions on the same [browser toolset](/stuntkit/browser-toolset) its +actors use. ## What it measures -| Category | Can an agent... | -| --------------------- | -------------------------------------------------- | -| Brand awareness | Recognize the brand and what it offers | -| Discovery | Find the site and the right page for a task | -| Information retrieval | Read the facts it needs from the site | -| Market ranking | Place the site among its competitors | -| Accuracy | Report what the site says without getting it wrong | -| Checkout | Get through to buying, on a person's behalf | -| Delegated access | Act for a signed-in person | -| Support | Find help content and get an answer | +| Category | Can an agent... | +| ----------------------- | ------------------------------------------------------- | +| Brand awareness | Recognize the brand and what it offers | +| Discovery | Find and recommend the site for a person's request | +| Information retrieval | Read the facts it needs from the site | +| Market ranking | Place the site among its competitors | +| Accuracy | Report what the site says without getting it wrong | +| Task completion | Carry out a task end to end, on a person's behalf | +| Delegated access | Act for a signed-in person, safely | +| Contact & communication | Find a way to reach the business | + +Each category has a weight, and Task completion carries the most. Delegated +access is scored only for sites with a sign-in: a site with nothing to sign in +to has nothing to delegate. The report also breaks the score down by provider, so you can see when one agent struggles where the others don't. @@ -55,9 +70,30 @@ agent struggles where the others don't. Anyone signed in can add a site that isn't tracked yet at [index.stuntdouble.io](https://index.stuntdouble.io). A new site gets light -probes by default, with an option to add live agent sessions. - -Claim your domain to re-score it after you ship changes. +probes by default, with an option to add live agent sessions, and becomes +public on the leaderboard. Sites that opt out in `robots.txt` aren't scored. + +Claim your domain with an email address on that domain: `sam@acme.com` can +claim `acme.com` and its subdomains. Claiming lets you re-score the site after +you ship changes (see [Improve your score](/index-ranking/improve-your-score)), +and adds it as a project in your Stunt Double workspace, if you have one. + +## Share and look up a score + +Each scorecard has: + +- **A badge** to embed, in a full, compact or 20px README style, as HTML or + Markdown. +- **A fix prompt** to paste into your coding agent, built from the + frictions agents hit on the site. +- **An MCP prompt**: one message that asks your AI assistant about the site + and tells it how to connect to the Index's + [MCP server](/mcp/connect#index-lookups-with-no-account), which needs no + account. + +The [reports](https://index.stuntdouble.io/reports) page lists the Index's +published reports: fixed, citable snapshots of how agents experience a set of +sites, with a PDF to download once one is ready. ## Next steps diff --git a/content/docs/index.mdx b/content/docs/index.mdx index 780432a..2c1b044 100644 --- a/content/docs/index.mdx +++ b/content/docs/index.mdx @@ -1,7 +1,7 @@ --- title: "Overview" icon: "book" -description: "Authentic user insights from autonomous AI agents, backed by evidence. Learn how to set up actors, run checklists and interviews, connect your tools, and drive Stunt Double from an assistant." +description: "What Stunt Double is and where to go next: run a first check, test a design, automate re-runs, or drive it from an assistant." --- # Stunt Double documentation @@ -31,7 +31,7 @@ behind every result. { icon: "rocket", title: "Run my first check in five minutes", - description: "Create a workspace, an actor and a checklist, then read the run.", + description: "Give Stunt Double your URL, watch the first run, then write your own checklist.", href: "/getting-started", }, { @@ -74,16 +74,21 @@ actors do three kinds of work, and every run comes back as evidence. -Read **[Core concepts](/concepts)** for each building block in detail. +Each name links to its definition in **[Core concepts](/concepts)**. ## Browse by section + Choosing a local model for a session is in early access alongside live + sessions. + -| Model | Size | Notes | -| -------------- | ------ | --------------------------------------- | -| `gemma3:4b` | 3.3 GB | Small, and reads screenshots | -| `qwen2.5vl:7b` | 6 GB | Reads screenshots; better at long tasks | -| `llama3.2` | 2 GB | Small and quick. Text only | -| `qwen2.5:7b` | 4.7 GB | Good at tools. Text only | +With Ollama installed and running, **Set Up This Mac** suggests models built +for tool use and multi-step tasks, all of which read the actor's screenshots. +The list is ranked by this Mac's memory: the largest model that runs well +alongside the browser is marked **Best fit for this Mac**, and one that needs +more memory than the Mac has says so. + +| Model | Size | Memory | Notes | +| ---------------- | ------ | ------ | ---------------------------------------- | +| `qwen3.5:4b` | 3.4 GB | 8 GB | Small and quick | +| `ministral-3:8b` | 6 GB | 16 GB | Fast at tool calls | +| `qwen3.5:9b` | 6.6 GB | 16 GB | A good all-rounder for multi-step tasks | +| `gemma4:12b` | 7.7 GB | 24 GB | Reads pages and screenshots closely | +| `gemma4:26b` | 16 GB | 32 GB | Steadier on long tasks | +| `qwen3.8:27b` | 18 GB | 32 GB | The strongest here at long agentic tasks | Click **Install** on a model to download it. If you already run Ollama, the app uses yours and the models you have pulled; otherwise it starts the one it installed when it is needed, listening only on this Mac, and stops it when you quit. -When a live session's actor thinks with a model on this Mac, the model never -sees Stunt Double's credentials, and what it reads stays on your Mac. Only the -session's journey, captures and transcript are saved to your workspace, and the -end-of-session summary is built from those facts alone, without sending the -transcript to Stunt Double's model. - - - Choosing a local model for a session is in early access alongside live - sessions. A model that reads screenshots gives the actor a much better view of - the page than a text-only one. - +To use one, choose it under **Model** when you start a live session on **This +Mac**. A local model never sees Stunt Double's credentials, and what it reads +stays on your Mac. Only the session's journey, captures and transcript are +saved to your workspace. ## MCP servers on this Mac @@ -125,35 +147,18 @@ Mac. They never run in Stunt Double's cloud. Add them in the app, or import the ones you already use in Claude Desktop or Cursor from the session's **Tools**. The app asks you to approve each server, showing the exact command, before it starts, and editing a server's command switches it off until you -approve it again. See [Tools and sign-ins](/tutorials/live-sessions#tools-and-sign-ins) -for how they work in a session. +approve it again. [Tools and sign-ins](/tutorials/live-sessions#tools-and-sign-ins) +covers how they are used during a session. ## Troubleshooting -**This Device asks you to install Google Chrome.** The device drives Chrome. -Install it, then click **Set up this Mac** again. - -**The console says this Mac is paired with another workspace.** A Mac belongs -to one workspace at a time. Click **Move to** and confirm to move it here. -Runs in the other workspace stop using it. - -**The console says "This device is no longer paired".** The device was removed -from the workspace, or its key no longer works. Click **Pair again**. +Messages on **This Mac** about pairing, connection and the browser, and errors +on device runs, are covered in +[Devices troubleshooting](/integrations/self-hosted-workers#troubleshooting). -**The console says "Not reaching Stunt Double".** The app is running, but -Stunt Double has not heard from it for over a minute. Check the Mac is online, -then click **Reconnect**. - -**The console says to update the app.** That version cannot run a device yet. -Update the app and reopen **This Device**. - -**A run says the browser was suspended by security software.** Endpoint -security on the Mac froze Chrome before it could start. Ask your IT team to -allow Stunt Double to launch Google Chrome. - -**A run says the browser profile is in use.** Only one Chrome can use the -device's profile at a time. Close any Chrome window still open on that -profile, such as a sign-in window, and try again. +**This Mac says "Update the desktop app".** That version cannot run a device. +Updates install in the background, so restarting the app is usually enough. +Choose **Check for Updates…** to fetch one now. **An install in Set Up This Mac fails.** Check the Mac is online and try again. A failed install leaves any earlier version in place. @@ -161,3 +166,7 @@ A failed install leaves any earlier version in place. **A Mac MCP server will not start.** Its command may need Node or uv. The server's row in **Tools** says what is missing and links to **Set Up This Mac**. + +**A local model is not offered when you start a session.** **Model** only +appears when the browser is **This Mac** and the Mac has at least one local +model installed. Install one from **Set Up This Mac**. diff --git a/content/docs/integrations/feedback-widget.mdx b/content/docs/integrations/feedback-widget.mdx index 184d1f3..a2fd821 100644 --- a/content/docs/integrations/feedback-widget.mdx +++ b/content/docs/integrations/feedback-widget.mdx @@ -1,7 +1,7 @@ --- title: "Feedback widget" icon: "feedback" -description: "Let visitors pin comments to the exact spot on your site, with a screenshot, URL and viewport attached." +description: "Install the feedback widget, lock down who can use it, version comments and reach them from an agent: the full reference." --- # Feedback widget @@ -10,26 +10,56 @@ Add one script tag to your site and anyone looking at a page can drop a pin on the spot that confused them and say why. Each comment arrives in your project with a screenshot of the page as they saw it, the URL and the viewport. -This page is the reference for installing and locking it down. For a -walkthrough on a prototype, read the [tutorial](/tutorials/feedback-widget); for -running reviews with it, read the [guide](/guides/feedback-widget). +This page is the reference for installing, configuring and locking it down. To +run a feedback round on a prototype end to end, follow the +[tutorial](/tutorials/feedback-widget); for when and how teams use it, read the +[guide](/guides/feedback-widget). + +## What it does + +- **Pins snap to elements.** While placing a comment, the widget outlines the + element under the cursor and names it, so the comment attaches to that button + or field rather than to a coordinate. Hold **Shift** to place a free pin + instead, for whitespace or a background. A snapped pin follows its element + when the layout changes. +- **Every comment carries its context.** A screenshot with the pin marked (and, + for a snapped pin, cropped around the element), the page URL and title, the + element it was pinned to, viewport, scroll position, basic device information + and the [page version](#versions). +- **Replies and resolving happen on the page too.** Your team's replies appear + in the thread on the page under a **Team** badge. A workspace member can + resolve a comment from the page, and so can its author when they were signed + in to Stunt Double. +- **Visitors control their own view.** A gear beside the feedback button lets + each visitor edit the name and email the widget remembers, hide other + people's pins, turn off the `c` shortcut for themselves, or **Hide for this + session**. These only narrow what the project allows, never widen it. +- **Comments land in the project.** The project's **Comments** view groups them + by page and version for triage. The [tutorial](/tutorials/feedback-widget#4-triage-what-comes-back) + goes through it. ## Before you start -- **Workspace limits.** Owners and admins set a workspace-wide ceiling for - the widget under **Settings**, then **Security**. - **A site you control.** You need to add a script tag to its HTML. +- **Workspace limits.** Owners and admins can set a workspace-wide ceiling for + the widget under **Settings**, then **Security**. ## Set it up -1. Open the project and go to **Comments**. -2. Follow the install step. Copy the snippet and paste it just before - ``, or choose **With Claude** to hand the job to a coding agent. -3. Load your site. The install step shows **Widget detected** once the widget +1. Open the project and go to **Comments**. The first time, click **Enable + comments**, which switches the feature on and creates the project's API key. +2. Follow the install step. Copy the snippet from the **Code** tab and paste it + just before ``, or copy the prompt from the **With Claude** tab and + hand the job to a coding agent. +3. Load a page that carries the snippet. The install step changes from + **Waiting for widget connection** to **Widget detected** once the widget checks in. 4. If the widget also runs somewhere other than your project URL, such as a - staging or custom domain, add it under **Allowed domains** in the project's - feedback settings. Requests from anywhere else are refused. + staging, preview or custom domain, add it under **Allowed domains** in the + project's comment settings. Requests from anywhere else are refused. + +Each project has its own key and its own inbox, so feedback on one site never +mixes with another. ## The snippet @@ -44,38 +74,96 @@ running reviews with it, read the [guide](/guides/feedback-widget). the widget logs a warning and does nothing. - **`data-sd-url`** (required in practice) points at Stunt Double. It must be `https`; the widget refuses to run otherwise. -- **`data-sd-version`** (optional) pins comments to a version string you - control, such as a build ID, release tag or commit SHA. Without it, comments - are grouped by page content. +- **`data-sd-version`** (optional) declares the page version yourself. See + [Versions](#versions). -There is no package to install and no build step. Screenshot capture loads -`html2canvas` on demand from a pinned, integrity-checked URL, so one tag is -enough. +There is no package to install and no build step, so the same tag works on a +staging deploy, a preview URL or a throwaway static build. Screenshot capture +loads `html2canvas` on demand from a pinned, integrity-checked URL, so one tag +is enough. -## Control who can use it +## Settings -The API key sits in your page source, so treat it as an identifier, not a -secret. The real access control is the domain allowlist, which every widget -endpoint checks before it answers. +Open **Comments**, then the settings view. | Setting | What it does | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Toolbar visible** | Shows or hides the feedback button on your site. | +| **Show comments on page** | Draws existing comment pins for everyone. Off, the widget still collects comments but shows nobody else's. | +| **Keyboard shortcut** | Lets visitors press `c` to start placing a comment. | +| **When the page changes** | **Keep comments** leaves pins open until someone resolves them. **Auto-resolve on a new version** resolves comments left on earlier versions. See [Versions](#versions). | | **Allowed domains** | Hosts the widget may run on, beyond your project URL (always accepted). Up to 20. An entry matches an exact host; `*.example.com` covers every subdomain, such as previews. | -| **Allow local development** | Lets `localhost` and private network addresses use the widget. On by default. | -| **Require sign in** | Only signed-in members of this workspace can read or leave comments. Use it for staging and internal reviews. | -| **Toolbar visible** | Shows or hides the feedback button on your site | -| **Show comments on page** | Shows existing comment pins on the page | -| **Keyboard shortcut** | Lets visitors press `c` to start placing a comment | -| **API Key** | **Rotate** issues a new key and stops every install of the old one until its snippet is updated | +| **Require sign in** | Only signed-in members of this workspace can read or leave comments. Use it for staging and internal reviews. | +| **Allow local development** | Lets `localhost` and private network addresses use the widget. Off by default on new projects. | +| **API Key** | **Rotate** issues a new key and stops every install of the old one until its snippet is updated. | + +## Control who can use it + +The API key sits in your page source, so treat it as an identifier, not a +secret. The access control is the domain allowlist, which every widget endpoint +checks before it answers. The allowlist **fails closed**: a project with no URL and an empty allowlist serves nothing at all, and the settings page says so, so you can tell "locked down" apart from "broken". +With **Require sign in** on, visitors see **Sign in to review** instead of the +comment form. It opens a popup where they sign in to Stunt Double as normal, +and the popup hands the widget a short-lived token proving workspace +membership. Their name comes from their account, and their comments and +replies are badged **Team**. The token lasts an hour, so a long session may ask +them to sign in again. + Workspace admins hold a ceiling above every project under **Settings**, then -**Security**: a workspace-wide **allowed origins** list that projects can only -narrow, and a **Feedback widget** switch that turns the widget off for every -project, including sites where the key is already installed. +**Security**, in the **Feedback widget** section: **Enable the widget** turns +it off for every project, including sites where the key is already installed, +and **Allowed origins** is a workspace-wide list that projects can only narrow. +Leave it empty to let each project decide. + +## Versions + +Every comment is stamped with the version of the page it was left on, and the +**Comments** view numbers each page's versions **v1**, **v2** and so on, with +the newest badged **Latest**. + +By default the widget fingerprints the page's structure: the elements it is +built from, not the words on it. A changed timestamp, a personalized greeting +or one more row in a table is the same version; a page that has been rebuilt is +a new one. + +Declaring a version yourself is exact and lines the timeline up with your +releases. The widget takes the first of these it finds: + +- `data-sd-version` on the script tag +- a `` tag, which a build step or git hook can stamp +- `window.SD_FEEDBACK_VERSION`, for an app that already has its build ID in the + bundle + +Use a build ID, release tag or commit SHA. An empty or unrendered value, such +as `%VERSION%`, is ignored. The settings view has a snippet for each route and +a prompt for a coding agent. + +With **Auto-resolve on a new version**, comments left on an earlier version are +resolved when a signed-in workspace member next loads the page on the new one; +other visitors simply stop seeing the old pins. Whole threads move together, +nobody is emailed that their comment was resolved, and the comments stay in +the inbox under **Resolved**. Working from the fingerprint alone, auto-resolve +catches a rebuild rather than a small tweak, so declare a version if you want +each release to close its comments exactly. + +## Use it from an agent + +The MCP server exposes a project's comments, so an assistant can triage them +with you: + +| Tool | Scope | Does | +| ------------------------ | ----------- | ---------------------------------------------------------------------------- | +| `list_feedback` | `mcp:read` | Lists a project's comments, filterable by status | +| `get_feedback` | `mcp:read` | Reads one comment and its replies | +| `summarise_feedback` | `mcp:write` | Themes, open questions and a brief for a coding agent, shared with dashboard | +| `update_feedback_status` | `mcp:write` | Marks a comment reviewed, resolved or dismissed | + +See [MCP](/mcp) for connecting a client. ## Remove it @@ -85,8 +173,9 @@ working anywhere, rotate the API key. ## Troubleshooting **"Widget detected" never appears.** Check the snippet is on the page you -loaded, and that the domain is your project URL or under **Allowed -domains**. For `localhost`, turn on **Allow local development**. +loaded, the key matches the one in **Comments**, and the domain is your project +URL or under **Allowed domains**. For `localhost`, turn on **Allow local +development**. **The widget stopped loading after a key rotation.** Every copy of the snippet needs the new key. Copy the snippet again from **Comments**. @@ -94,3 +183,8 @@ needs the new key. Copy the snippet again from **Comments**. **The widget will not load even though the domain is allowed.** An owner or admin may have limited the widget workspace-wide under **Settings**, then **Security**. + +**Old comments did not auto-resolve after a release.** Auto-resolve waits for a +workspace member to load the page on the new version. Without a declared +version, a small change may also count as the same version; set +`data-sd-version` to close comments per release. diff --git a/content/docs/integrations/figma-plugin.mdx b/content/docs/integrations/figma-plugin.mdx index 262de3f..9a1818f 100644 --- a/content/docs/integrations/figma-plugin.mdx +++ b/content/docs/integrations/figma-plugin.mdx @@ -2,105 +2,117 @@ title: "Figma plugin" icon: "figma" status: "Preview" -description: "Review frames, run checklists, capture feedback and chat with actors without leaving Figma." +description: "Review frames, run checklists, capture feedback and ask actors about a design without leaving Figma." --- # Figma plugin The Stunt Double plugin brings actors into the Figma canvas. Select a frame -and actors review it, run a checklist against it, or talk it through with you, -and the findings land as numbered pins next to the design. +and actors review it, run a checklist against it, or answer your questions +about it, and the findings land on the canvas next to the design. - The plugin is not listed in the Figma Community yet, so there is no public - install link. This page describes how it works so you know what to expect when - it arrives. + The plugin is in early access and not listed in the Figma Community yet, so + there is no public install link. This page describes how it works so you know + what to expect when it arrives. ## What it does The plugin has four tabs: -- **Review.** Select one or more frames and ask actors for design feedback. - The plugin exports the frames and the reviewers judge the image. Click - **Place on canvas** to draw numbered pins and a findings panel beside the - frame, **Resolve** findings as you fix them, and click **Re-check frame** to - ask the reviewers what is fixed. **Open in dashboard** takes you to the full - review. -- **Checklists.** Run one of the project's checklists against the selected - frames and read the results. -- **Feedback.** Create and triage feedback on the design, filtered to **This - file only** or across the project. -- **Chat.** Talk to one of your actors about the selected frames, with - **Attach frame snapshot** to send the frame along. - -Pick a project in the plugin's header first: reviews, checklists and feedback -all belong to a project. +- **Review.** Select a frame, pick the reviewers and, if you like, **Add + instructions** to focus them. The plugin exports the frame and the actors + judge the image. When the review finishes, **Place on canvas** adds each + finding as a native Figma annotation on the layer it is about, and **Place + as layer** (under **More actions**) draws numbered pins and a findings panel + instead. **Resolve** findings as you fix them, then click **Re-check** to ask + the reviewers what is fixed. **Ask an actor** opens a conversation with one + of your actors about the reviewed frame. +- **History.** Every review in the project, newest first. Select a reviewed + frame on the canvas and the bar offers **Last review** to jump to it. +- **Checks.** Run one of the project's checklists against up to six selected + frames, taken in flow order, or click **Run on** the project's address to + run it in a real browser. **Test the prototype** takes a prototype or Make + link and opens a new interview for it in Stunt Double. +- **Feedback.** Leave a note on the selected frame or the whole file, with + **Attach a snapshot** to send the frame along, and filter the list to **This + file only** or the whole project. + +The plugin also adds **Review selection**, **Run checklist on selection**, +**Leave feedback on selection** and **Open Stunt Double** to Figma's plugin +menu. A reviewed frame gets an **Open review** button in Figma's properties +panel, so anyone can get back to its findings. ## Before you start -- **A Stunt Double account** with access to the workspace and project you want - to work in. -- **Actors in the workspace.** Reviews and chat need at least one actor. - Create one in the dashboard if the plugin says **No actors in this workspace - yet.** -- **A project.** The plugin works inside a project, so create one in the - dashboard first. +- **A Stunt Double account** with access to the workspace you want to work + in. If you have none, the plugin offers **Create workspace**. +- **Actors in the workspace.** Reviews need at least one actor. Create one in + the dashboard if the plugin says **No actors in this workspace yet.** ## Connect the plugin The plugin signs in through your browser, so it never asks for a password. -1. Open the plugin in Figma and click **Connect to Stunt Double**. A browser - tab opens and the plugin reads **Approve the request in your browser. - Waiting...** +1. In a Figma design file, open **Stunt Double** from the Plugins menu and + click **Connect**. A browser tab opens and the plugin shows a confirmation + code. 2. In the browser, sign in to Stunt Double if you are not already. The - **Connect the Figma plugin** page lists what the plugin will be able to do. -3. Click **Approve**. The plugin switches to **Connected to Stunt Double**. - -To cancel, click **Deny** in the browser or **Cancel** in the plugin. + **Connect the Stunt Double plugin** page shows the same code and lists what + the plugin will be able to do. If the codes do not match, do not approve: + the request did not come from your Figma. +3. Click **Approve**. To sign in as someone else, click **Use a different + account** first. +4. Back in Figma, link the file to a project: pick one, or create a project + for the file. A new project starts with a starter checklist and actors. + +The link is stored in the file, so everyone who opens it with the plugin +lands in the same project. To change it later, open the workspace and project +view from the plugin's header, where you can also see the project's rules, +paste the file's Figma link so findings link back to it, or unlink the file. ## What the plugin can access When you approve, the plugin can: -- See your workspaces, projects and actors -- Run checklists and view run results -- Create and triage feedback on your designs -- Chat with your actors about selected frames +- Run design reviews on frames you select +- Run checklists against your frames +- Read and leave feedback on your projects +- Ask actors about a frame Approving issues a plugin token that lasts 90 days and is stored in Figma on -your machine. The plugin can only reach `app.stuntdouble.io` and -`stuntdouble.io`. +your machine. The plugin can only reach `app.stuntdouble.io`. The plugin does not need the [Figma workspace connection](/integrations/figma), and the connection does not need the plugin. Use either or both. ## Disconnect -Click **Sign out** in the plugin. That removes the token from Figma on your -machine. The token also expires on its own after 90 days, and the plugin asks -you to connect again. +Open the account menu in the plugin and click **Sign out**. That revokes the +token and removes it from Figma on your machine. You can also revoke it from +your account settings in Stunt Double, under **Connected apps**. The token +expires on its own after 90 days, and the plugin asks you to connect again. ## Troubleshooting -**"The connect request expired. Try again."** The browser approval took too -long. Click **Connect to Stunt Double** again and approve within a few -minutes. +**"That request expired. Connect again."** The browser approval took too +long. Click **Connect** again and approve within a few minutes. -**"The request was denied."** Someone clicked **Deny** in the browser. Start -the connection again and click **Approve**. +**"You denied the connection."** Someone clicked **Deny** in the browser. +Connect again and click **Approve**. **The browser says the connect request is no longer valid.** The request was already used or has expired. Return to Figma and start the connection again. -**"Select one or more frames first."** Reviews and checklists run on frames, -not groups or pages. Select at least one frame on the canvas. +**"Text cannot be reviewed. Select the frame around it."** Reviews and +checklists run on frames, not on text, shapes or Stunt Double's own layers. +Select the frame that contains them. -**"Pick a project in the header before running a review."** Choose a project -from the plugin's header. If the list is empty, create a project in the -dashboard. +**"That frame is too large."** Select a smaller frame or a section of it. +Very tall frames reach the actors small, so a section reviews better anyway. -**"Could not reach Stunt Double."** Check your network connection. Figma only -lets the plugin talk to stuntdouble.io, so a network that blocks it will stop -the plugin. +**A banner reads "Cannot reach Stunt Double. Retrying."** The plugin lost its +connection and reconnects by itself. If it never recovers, check your +network: Figma only lets the plugin talk to `app.stuntdouble.io`, so a +network that blocks it will stop the plugin. diff --git a/content/docs/integrations/figma.mdx b/content/docs/integrations/figma.mdx index 94f969b..86840db 100644 --- a/content/docs/integrations/figma.mdx +++ b/content/docs/integrations/figma.mdx @@ -42,13 +42,25 @@ are connected, read the [Figma guide](/guides/figma). 2. On **Your account**, click **Connect Figma** and approve Stunt Double in Figma. The step changes to **Connected as** with your Figma name. 3. On the step named after your workspace, an owner or admin turns the switch - on. It reads **On. Actors, checklists and automations here can use it.** + on, which lends that workspace their Figma connection. It reads **On for + this workspace.** 4. On **Projects**, click **Choose for a project** and pick a project. Its **Settings** open on the **Integrations** tab: choose the project's design file there. Repeat for each project that works from a Figma file. -To re-check work when a file changes, create an automation, choose a Figma -trigger, then pick from **Figma Events**. +To re-check work when a file changes, create an automation and choose the +**Figma** trigger. Then: + +- Pick up to three **Figma Events**. Figma allows three webhooks per file, + one event each. +- For **Library Publish**, optionally narrow it with the **Library filter** + to components, styles or variables that were created, modified or deleted. +- Under **File**, paste the file key from the Figma file's URL. An + automation listens to one file, and it needs one. + +Stunt Double registers the file webhooks for you, using a Figma connection +that is on in the workspace and can edit the file. Events from a file reach +only the workspaces whose connections registered them. ## What Stunt Double can access @@ -67,7 +79,9 @@ Stunt Double asks Figma for these scopes: Open **Integrations**, click **Figma**, then click **Disconnect** on **Your account**. The **Disconnect Figma?** dialog lists every workspace that loses Figma. Confirm, and those workspaces stop using it until someone connects -again. +again. Disconnecting also removes the file webhooks your connection +registered, so automations that relied on it stop receiving events unless +another connection in the workspace can edit the file. To stop one workspace from using Figma and leave the rest, an owner or admin turns off the workspace switch instead. You can also remove Stunt Double from @@ -88,5 +102,13 @@ open that file, and that the file is linked on the project's **Integrations** tab. **Automations do not start on file changes.** Confirm the automation is on, -its trigger lists the right **Figma Events**, and Figma is still on for the -workspace. +its trigger lists the right **Figma Events** and the right **File**, and Figma +is still on for the workspace. Figma only lets accounts with **Can edit** on a +file listen to its events, so the connected account needs edit access, not +just view access. If it has that and events still do not arrive, disconnect +and connect Figma again to refresh what Stunt Double may do in Figma. + +**"Select up to 3 Figma events."** Figma allows three webhooks per file, one +event type each, so an automation can listen for at most three. The limit +covers the whole file: if other automations already listen to the same file +for different events, some of yours may never be registered. diff --git a/content/docs/integrations/github.mdx b/content/docs/integrations/github.mdx index c307167..03e145e 100644 --- a/content/docs/integrations/github.mdx +++ b/content/docs/integrations/github.mdx @@ -21,7 +21,7 @@ For the full loop of preview deploys, checklists and PR reports, read the - **Workflow triggers.** Pull request, review, push, issue, check suite and release events start automations automatically. - **PR comments.** Workflow results and checklist summaries post directly on - the pull request. + the pull request, including from a Vercel preview built from one. ## Before you start @@ -56,11 +56,6 @@ repositories it can see. **Settings** open on the **Integrations** tab: choose the project's repository there. -To start an automation from GitHub, create an automation, choose a GitHub -trigger, and pick the events: **PR Opened**, **PR Merged**, **PR Updated**, -**Review Requested**, **Push**, **Issue Opened**, **Check Suite Completed**, -**Release Published** and more. - ### Watched repositories versus project repositories **Watched repositories** are a workspace setting: GitHub events from these @@ -81,6 +76,30 @@ it to the organization owner who can install apps. caption="GitHub once it is set up. Choose for a project opens the project's settings, where you pick its repository." /> +## GitHub trigger reference + +Choose **GitHub** as the trigger when you create an automation. The +**Configure** step sets when it fires: + +| Group | Events | +| ------------- | ---------------------------------------------------------------------------------------- | +| Pull Requests | **PR Opened**, **PR Closed**, **PR Merged**, **PR Reopened**, **PR Updated**, **Review Requested** | +| PR Reviews | **Review Submitted**, **Review Dismissed** | +| Push | **Push** | +| Issues | **Issue Opened**, **Issue Closed**, **Issue Reopened**, **Comment Created** | +| CI/CD | **Check Suite Completed** | +| Releases | **Release Published** | + +**Repository Filter** (optional) limits it to one repository, as +`owner/repo`. Leave it empty to trigger for all of them. Either way, events +only arrive from repositories under **Watched repositories**. + +Two steps report back to GitHub: **GitHub Comment** posts on the pull request, +and **Actor PR Review** has an actor review it. Both find the pull request +from a GitHub trigger, or from a [Vercel](/integrations/vercel) deployment +built from one. [Automate multi-step workflows](/tutorials/building-workflows) +builds one end to end. + ## What Stunt Double can access GitHub access comes in two parts. diff --git a/content/docs/integrations/index.mdx b/content/docs/integrations/index.mdx index 420455d..afd13df 100644 --- a/content/docs/integrations/index.mdx +++ b/content/docs/integrations/index.mdx @@ -1,6 +1,6 @@ --- title: "Integrations" -description: "Run checks where the work already happens: on pull requests, deploys, design updates and Linear issues." +description: "Every Stunt Double integration in one place: how connections work, what each one does, and which to connect first." --- # Integrations @@ -24,19 +24,29 @@ Three mechanisms connect Stunt Double to your other tools: toolset: create and run checklists, launch persona interviews, triage feedback and comment on pull requests. Client setup lives in the [MCP section](/mcp). -2. **Connections and event triggers.** Connect GitHub, Figma, Linear, Slack or - Vercel and automations can start on pull requests, deploys, design updates, - Linear issues and Slack messages, so checks re-run without anyone asking. +2. **Connections and event triggers.** Connect GitHub, Vercel, Cursor Origin, + Figma or Slack and automations can start on pull requests, deploys, design + updates and Slack messages, so checks re-run without anyone asking. Slack + and Linear also bring an agent your team can ask directly. 3. **The dashboard** at [app.stuntdouble.io](https://app.stuntdouble.io), for anything visual: watching session recordings, reading interview reports and managing actors and integrations. ## How every connection works -Every integration lives on the **Integrations** page of your workspace. Open -the sidebar, choose **Integrations**, then click a card. Each one is set up in -the same three steps, in the same order, so learning one teaches you all of -them. +Every integration lives on the **Integrations** page of your workspace, which +you open from the sidebar. It lists them in two sections: **Plugins**, which +install Stunt Double into the tools you already work in (Claude, ChatGPT, the +Cursor plugin, the Figma plugin and other MCP clients), and **Platform +integrations**, the services the workspace connects to. **Custom MCP servers**, +your own systems for actors to use during a run, are listed below them. + +Each row shows whether it is connected. An integration you have not connected +yet has a **Connect** button right on its row, so you can start without +opening it. Click a row to open its page. Each platform integration is set up +in the same three steps, in the same order, so learning one teaches you all of +them. The exception is [Cursor Origin](#cursor-origin), which is installed +straight onto the workspace. ``` +Each takes `variant` (default `color`), `size` (`sm`, `md`, `lg` or any +length), `color` for the `mono` paint and `title`. `brandComponents` maps each +kebab-case name to its component, and the SVG files are under +`@stunt-double/icons/svg/brands/`. + Each mark below shows the `color` variant on the left and the `mono` variant on the right, with its component name. diff --git a/content/docs/stuntkit/index.mdx b/content/docs/stuntkit/index.mdx index 4f1f3c7..9031e15 100644 --- a/content/docs/stuntkit/index.mdx +++ b/content/docs/stuntkit/index.mdx @@ -1,19 +1,21 @@ --- title: "StuntKit" icon: "Package" -description: "StuntKit is the toolkit Stunt Double runs on: browser tools for AI agents with built-in guards against paying and signing up, plus icons, Americanize for spelling and agent-readiness packages." +description: "What StuntKit is and which package to use: the open source browser toolset, Web Agent Optimiser, icons and Localeizer behind Stunt Double, plus agent skills and how to contribute." --- # StuntKit -Give your AI agent a browser it can use safely. StuntKit is the toolkit Stunt -Double runs on every agent session: browser tools for your own agents, plus the -icons, spelling (Americanize) and accessibility packages behind the product. +Give your AI agent a browser it can use safely. StuntKit is the open source +toolkit behind Stunt Double: the browser tools every actor and Stunt Double +Index session runs on, plus the icons, spelling and agent-readiness packages +behind the product. It is licensed under Apache-2.0, at [github.com/stunt-double/stuntkit](https://github.com/stunt-double/stuntkit). -StuntKit packages are published to GitHub Packages, which asks for a token even -for public packages. +The packages are published to GitHub Packages, which asks for a GitHub token +with `read:packages` even for public packages. Each package page has its own +install steps. ## What's in it @@ -21,68 +23,59 @@ for public packages. columns={2} items={[ { - title: 'Browser tools for AI agents', + title: 'Browser toolset', description: - 'Let Claude or any model with function calling read and act on a real page, with guards that refuse payments, sign-ups and passwords.', + '@stunt-double/browser-toolset. Build your own browser agent: let Claude or any function-calling model read and act on a real page, with guards that refuse payments, sign-ups and passwords.', href: '/stuntkit/browser-toolset', }, { title: 'Web Agent Optimiser', description: - 'A drop-in script that repairs the accessibility tree agents read, so legacy sites work for agents without a rebuild.', + '@stunt-double/wao. Make a site work for agents: a drop-in script that repairs the accessibility tree they read, without a rebuild.', href: '/stuntkit/wao', }, { title: 'Icons', description: - 'The Continuity icon pack as geometry, SVG files and React components, plus AI provider marks.', + '@stunt-double/icons. Match the product in your own UI: the Continuity icon pack as geometry, SVG files and React components, plus AI provider marks.', href: '/stuntkit/icons', }, { - title: 'Americanize', + title: 'Localeizer', description: - 'Rewrite text into American, British, Australian or Canadian spelling, whole words only.', - href: '/stuntkit/americanize', + '@stunt-double/localeizer. Rewrite copy into American, British, Australian or Canadian spelling, whole words only.', + href: '/stuntkit/localeizer', }, ]} /> -
+## Agent skills -| Package | What it does | Source | -| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -| `@stunt-double/browser-toolset` | Browser tools for AI agents over any browser you bring, with opt-in safety guards | [GitHub](https://github.com/stunt-double/stuntkit/tree/main/packages/browser-toolset) | -| `@stunt-double/icons` | The Continuity icon pack: 235 stroked icons as geometry, standalone SVG files and React components | [GitHub](https://github.com/stunt-double/stuntkit/tree/main/packages/icons) | -| `@stunt-double/spelling` | Americanize: whole-word American, British (including Australian) and Canadian spelling, from American or British source text | [GitHub](https://github.com/stunt-double/stuntkit/tree/main/packages/spelling) | -| `@stunt-double/wao` | Web Agent Optimiser: a drop-in script that repairs the accessibility tree agents read, so legacy sites work for agents without a rebuild | [GitHub](https://github.com/stunt-double/stuntkit/tree/main/packages/wao) | +Each package has an Agent Skill that teaches a coding agent when to reach for +it, how to wire it up and the mistakes to avoid, plus skills for choosing a +package and making a site agent-ready, and agents that build and review +browser agents. Install them all in Claude Code as a plugin: -
+```sh +/plugin marketplace add stunt-double/stuntkit +/plugin install stuntkit@stuntkit +``` -## How to use it - -- **Build your own browser agent.** Add `@stunt-double/browser-toolset` to an - agent loop, connect it to Playwright, a hosted browser or a CDP client, and - turn on the guards. See [Give an AI agent a safe browser](/stuntkit/browser-toolset). -- **Run Stunt Double sessions on your own network.** A Mac running the - Stunt Double app runs actors inside your network, so they can reach staging - and internal tools. See [Test a product behind your firewall](/tutorials/self-hosted-worker). -- **Make a site work for agents.** Drop the `@stunt-double/wao` script into a - page to repair the accessibility tree agents read. -- **Match the product in your own UI.** Use `@stunt-double/icons` for the - Continuity icons and Americanize (`@stunt-double/spelling`) to localize copy. +Other agents that read `SKILL.md` folders can copy them from the repository's +[`skills`](https://github.com/stunt-double/stuntkit/tree/main/skills) folder. ## Principles - **Rules live in the tools, not the prompt.** A prompt that says "never pay or sign up" is a request a model can ignore. When a StuntKit guard refuses, the click never reaches the page. -- **Bring your own model and browser.** The tools never call a model and have - no runtime dependencies. Your agent does the reasoning; you choose the - browser. +- **Bring your own model and browser.** No package calls a model or needs a + runtime dependency. Your agent does the reasoning; you choose the browser. - **Guards are opt-in and readable.** Turn on the ones you need, and read and test every rule before an agent acts on a real site. -- **One codebase.** The packages are the same code that drives hosted Stunt - Double actors and the [Stunt Double Index](https://index.stuntdouble.io). +- **One codebase.** Stunt Double ships the same packages: hosted actors and + the [Stunt Double Index](https://index.stuntdouble.io) run on the browser + toolset, and the product uses the icons and Localeizer. ## Contribute @@ -93,13 +86,13 @@ Issues and pull requests are welcome on the repository. It has a in a public issue. - You don't need StuntKit to use Stunt Double: hosted actors already run on it. Reach for it when - you are building an agent of your own, or when you want to run Stunt Double sessions on your own - infrastructure. + You don't need StuntKit to use Stunt Double: hosted actors already run on it. + Reach for it when you are building an agent of your own, or making your own + site easier for agents to use. ## Next steps -- **[Browse StuntKit on GitHub](https://github.com/stunt-double/stuntkit)** - **[Give an AI agent a safe browser](/stuntkit/browser-toolset)** -- **[Test a product behind your firewall](/tutorials/self-hosted-worker)** +- **[Make any site readable by AI agents](/stuntkit/wao)** +- **[Browse StuntKit on GitHub](https://github.com/stunt-double/stuntkit)** diff --git a/content/docs/stuntkit/americanize/index.mdx b/content/docs/stuntkit/localeizer/index.mdx similarity index 76% rename from content/docs/stuntkit/americanize/index.mdx rename to content/docs/stuntkit/localeizer/index.mdx index e555191..6dc90f4 100644 --- a/content/docs/stuntkit/americanize/index.mdx +++ b/content/docs/stuntkit/localeizer/index.mdx @@ -1,27 +1,33 @@ --- -title: "Americanize" +title: "Localeizer" icon: "SpellCheck" -description: "Use Americanize (@stunt-double/spelling) to rewrite text into American, British, Australian or Canadian spelling, whole words only, from American or British source text." +description: "Use Localeizer (@stunt-double/localeizer) to rewrite text into American, British, Australian or Canadian spelling, whole words only, from American or British source text." --- -# Americanize +# Localeizer -Americanize rewrites text into American, British, Australian or Canadian +Localeizer rewrites text into American, British, Australian or Canadian spelling, from source written in either American or British English. It ships -as the `@stunt-double/spelling` package. Stunt Double's public sites are +as the `@stunt-double/localeizer` package. Stunt Double's public sites are written in American English and rewritten in the browser for visitors who read British, Australian or Canadian spelling. ```ts -import { localiseSpelling } from "@stunt-double/spelling"; +import { localiseSpelling } from "@stunt-double/localeizer"; localiseSpelling("Organize the color of the center.", "british"); // 'Organise the colour of the centre.' localiseSpelling("Analyse the cancelled catalogue.", "american"); // 'Analyze the canceled catalog.' + +localiseSpelling("Organise the colour of the centre.", "canadian"); +// 'Organize the colour of the centre.' ``` +Canadian spelling takes "-our", "-re" and the doubled "l" from British, and +"-ize", "-yze" and words such as "program" and "check" from American. + ## Australian English Australian English spells like British English (`colour`, `organise`, @@ -49,9 +55,15 @@ Add `@stunt-double:registry=https://npm.pkg.github.com` and a GitHub token with `read:packages` to your `.npmrc`. ```sh -npm install @stunt-double/spelling +npm install @stunt-double/localeizer ``` + + The package was published as `@stunt-double/spelling` up to 0.1.0. The API + is the same: swap the dependency and change the import path to + `@stunt-double/localeizer`. + + No dependencies. Runs anywhere JavaScript does: browsers, Node 20 or later and workers. @@ -87,7 +99,7 @@ Australia, New Zealand, Ireland and most of the Commonwealth use `'british'` ## Rewrite a page in the browser ```ts -import { localiseSpelling, type SpellingSystem } from "@stunt-double/spelling"; +import { localiseSpelling, type SpellingSystem } from "@stunt-double/localeizer"; function localisePage(root: Node, system: SpellingSystem): void { const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT); @@ -103,4 +115,4 @@ Skip `code`, `pre` and anything else where text isn't prose. ## Next steps -- **[Read the full API on GitHub](https://github.com/stunt-double/stuntkit/tree/main/packages/spelling)** +- **[Read the full API on GitHub](https://github.com/stunt-double/stuntkit/tree/main/packages/localeizer)** diff --git a/content/docs/stuntkit/meta.json b/content/docs/stuntkit/meta.json index 482b8ab..a6b1e8e 100644 --- a/content/docs/stuntkit/meta.json +++ b/content/docs/stuntkit/meta.json @@ -1,5 +1,5 @@ { "title": "StuntKit", "icon": "Package", - "pages": ["...browser-toolset", "...wao", "...icons", "...americanize"] + "pages": ["...browser-toolset", "...wao", "...icons", "...localeizer"] } diff --git a/content/docs/stuntkit/wao/index.mdx b/content/docs/stuntkit/wao/index.mdx index 10efd84..d455a7e 100644 --- a/content/docs/stuntkit/wao/index.mdx +++ b/content/docs/stuntkit/wao/index.mdx @@ -70,6 +70,26 @@ The npm entry has no side effects: nothing runs until you call `optimise`. The script build runs it once the DOM is ready and exposes the handle as `window.wao`. +In a React app, optimise once from an effect and restore on cleanup: + +```tsx +import { optimise } from "@stunt-double/wao"; +import { useEffect } from "react"; + +export function AgentReady() { + useEffect(() => { + const controller = new AbortController(); + optimise({ signal: controller.signal }); + return () => controller.abort(); + }, []); + return null; +} +``` + +Aborting the signal restores the page, as `restore()` does. The handle is also +`Disposable`, so `using wao = optimise()` restores the page when the block +ends. + ## In an agent's browser You don't need to own a site to use WAO on it. An agent harness can inject the @@ -88,7 +108,10 @@ const script = readFileSync( await context.addInitScript({ content: script }); ``` -With Puppeteer, pass the same content to `page.evaluateOnNewDocument`. Pair it +To pass options, put `window.waoOptions = {...};` at the start of the same +init script, since Playwright doesn't define the order of separate ones. The +script runs once per page, so a second injection is harmless. With Puppeteer, +pass the same content to `page.evaluateOnNewDocument`. Pair it with the [browser toolset](/stuntkit/browser-toolset), whose `read_page` reads the same tree. @@ -102,7 +125,8 @@ the same tree. Each repaired element is marked with `data-wao`, so an agent can tell inferred names from ones the page wrote. Switch a repair off with -`optimise({ repairs: { landmarks: false } })`. +`optimise({ repairs: { landmarks: false } })`, and skip shadow roots with +`shadow: false`. ## Rules @@ -128,7 +152,9 @@ With the script build, set `window.waoOptions` before the script loads. `report()` lists every change in effect and what WAO found but could not fix (`unnamed-control`, `image-without-alt`, `no-main`). Each issue is a good -candidate for a rule, or for a fix in the site itself. +candidate for a rule, or for a fix in the site itself. To hear about every +pass, including passes over content added later, pass an `onReport` callback. +An agent driving the page can read the same report with `window.wao.report()`. Inferred names are a best guess for agents. A site that people use with diff --git a/content/docs/tutorials/automate-with-mcp/index.mdx b/content/docs/tutorials/automate-with-mcp/index.mdx index a13b847..ed9edd7 100644 --- a/content/docs/tutorials/automate-with-mcp/index.mdx +++ b/content/docs/tutorials/automate-with-mcp/index.mdx @@ -1,49 +1,74 @@ --- title: "Automate from Claude" icon: "terminal" -description: "Connect the MCP server to Claude and drive actors, checklists, and interviews from a conversation." +description: "Drive actors, checklists, interviews and feedback from a conversation in Claude or any other MCP client." --- # Automate Stunt Double from Claude -This tutorial connects Claude and uses it to run your workspace from a -conversation. The **[MCP server](/mcp)** pages cover authentication and every -tool. +Once the [MCP server](/mcp) is connected, you can run most of your workspace +from a conversation instead of clicking through the dashboard. This tutorial +uses Claude, but every MCP client works the same way. -## Connect Claude to your workspace +## Before you start -Follow **[Connect](/mcp/connect)** for Claude Desktop, or the -**[Claude](/mcp/clients/claude)** and **[Claude Code](/mcp/clients/claude-code)** -pages. The first time Claude calls a tool, it runs the OAuth flow and asks you -to sign in to your workspace. Once you approve, Claude can list and call tools -on your behalf for the rest of the session. +Connect your client and sign in: pick it from the +**[client pages](/mcp/clients/claude)** (Claude, Claude Code, ChatGPT, Cursor +and more). Then ask "List my Stunt Double workspaces." If your workspaces come +back, you're ready. -## What you can ask Claude to do +## What you can ask for -With the server connected, you can drive most of the platform in plain -language instead of clicking through the dashboard: +Ask in plain language. Claude turns each request into tool calls on actors, +checklists, workflows, interviews and feedback, and reads back the result: - "Run the checklist for our signup flow and tell me if anything failed." -- "Create an actor for a first-time free-trial user and give it browser - access." +- "Create an actor for a first-time free-trial user and give it our brand + guidelines to check against." - "Launch a new round of our onboarding interview and summarize the top themes." - "List the workflows that ran in the last day and flag any failures." +- "Summarize the open feedback on the pricing page and dismiss the duplicates." +- "Run the checkout checklist against this preview and comment the result on + the pull request." +- "How well can AI agents use example.com?" For a site the + [Index](/index-ranking) does not track yet, Claude can request a score. -Claude translates each request into the appropriate tool calls, actors, -checklists, workflows, interviews, and reads back the result. +Name the workspace or project when you have more than one, and Claude searches +before it creates, so it reuses the actor or checklist that already covers a +flow. -## Scope tokens to least privilege +## Start from a recipe -Grant only the scopes a given client needs. There are three: `mcp:read` to -read a workspace, `mcp:write` to create and edit, and `mcp:run` to start runs. -A client that only reports on results needs `mcp:read`, and nothing more. A -client that requests no scope gets all three. See -**[authentication](/mcp#authentication)** for what each covers. +For the common jobs you don't have to write the request yourself: + +- **Prompts.** The server ships ready-made prompts such as `verify_change`, + `run_user_research`, `triage_feedback` and `setup_guardrails`. Each client + lists them in its own way; the client pages show where. +- **Skills.** The [skills](/mcp/skills) go further: each one teaches the agent + a full job, such as verifying a pull request preview or standing up + guardrails. The Claude Code and Cursor plugins install them for you. + +## Let runs finish + +Checklist runs, workflow runs and interviews take a few minutes. Claude starts +the run, then checks back every 30 to 60 seconds until it finishes, so you can +ask for something else in the meantime. In Claude and ChatGPT, the run comes +back as a card with the verdict, the score and each check's evidence, and the +card keeps itself up to date while the run is going. + +## Give each client only what it needs + +A connection that only reports on results needs `mcp:read`, nothing more. +Approve `mcp:write` for a client that should build checklists and actors, and +`mcp:run` only where it should start runs, since runs use your workspace's run +allowance. [Connect](/mcp/connect#what-a-connection-can-do) explains how scopes +hide tools and how a client without `mcp:run` handles automations. ## Next steps -- **[Automate multi-step workflows](/tutorials/building-workflows)**, - for automations that don't need a human in the loop at all. -- **[API overview](/api)**, for driving Stunt Double from your - own tools instead of Claude. +- **[Automate multi-step workflows](/tutorials/building-workflows)**, for + automations that don't need a human in the loop at all. +- **[Tools](/mcp/tools)**, for every tool, prompt and resource. +- **[API overview](/api)**, for driving Stunt Double from your own tools + instead of a chat client. diff --git a/content/docs/tutorials/building-workflows/index.mdx b/content/docs/tutorials/building-workflows/index.mdx index 6227fd8..771e818 100644 --- a/content/docs/tutorials/building-workflows/index.mdx +++ b/content/docs/tutorials/building-workflows/index.mdx @@ -1,59 +1,127 @@ --- title: "Build workflows" icon: "automation" -description: "Chain checklists, conditions, notifications, and PR reviews into one repeatable automation." +description: "Build one automation end to end: a pull request runs a checklist, a condition routes the result, and failures land back on the pull request." --- # Automate multi-step workflows -A checklist verifies one flow in one run. A workflow chains several steps -together into a single repeatable automation, so you can wire up a whole -process instead of a single check. +A checklist verifies one flow in one run. An automation (a workflow, in the +MCP tools) chains steps into a graph that runs on its own: a trigger starts +it, and each step hands its result to the next. In this tutorial you build a +common one for a product team: when a pull request changes, run a checklist +against it, and report the outcome. -## Step types available +## Before you start -A workflow is built from steps, each with its own configuration: +- A project with a checklist for the flow the pull request touches. If you + have none yet, the [Quickstart](/getting-started) creates some. +- [GitHub](/integrations/github) connected, with the repository under + **Watched repositories**. If your previews deploy on Vercel, you can start + from [Vercel](/integrations/vercel) instead, so the checklist runs against + the preview. -- **Run Checklist**, executes an existing checklist and carries its result - forward. -- **Condition**, branches the workflow based on the result of a previous - step. -- **Notification**, sends an alert when the workflow reaches that step. -- **Delay**, waits before continuing, useful for giving an async process time - to finish. -- **GitHub Comment**, posts a comment back to a pull request. -- **Actor PR Review**, has an actor review a pull request and report its - findings. + + -## Example: verify a pull request automatically +### Create the automation -A common workflow for a product team: +Open **Automations** and click **Create automation**. The dialog has three +steps: -1. **Run Checklist**, runs the checklist for the flow the pull request - touches. -2. **Condition**, checks whether every check in that run passed. -3. **Actor PR Review**, if the condition passes, has an actor review the - change directly. -4. **GitHub Comment**, posts the outcome back to the pull request either way, - so the result is visible without leaving GitHub. +1. **Trigger**: choose **GitHub** (or **Vercel**). An event trigger whose + integration is not set up yet says **Set up** followed by its name, and + choosing it opens the connect dialog. +2. **Configure**: pick the events that count, such as **PR Opened** and **PR + Updated**, and optionally limit it to one repository. +3. **Details**: name the automation and choose the project it runs in. -Each step only needs to know about the step before it, which is what makes it -possible to compose a whole review process out of a handful of pieces. +Click **Create automation**. It opens in the flow editor with the trigger +already in place. Later, **Edit flow** on the automation's page opens it +again. -## Toggle a workflow on when you're ready + + -A new workflow can be built and tested without affecting anything else. -Toggle it on only once you've run it a few times and are confident in the -result, since an enabled workflow runs automatically going forward rather -than waiting for you to trigger it by hand. +### Turn it off while you build + +A new automation is **Active** as soon as it is created, so the next pull +request would start it. Switch **Active** off in the automation's **Settings** +tab, or from the Automations list, until it does what you want. + + + + +### Add the steps + +Click **Add step** and add, in order: + +1. **Run Checklist**: choose the checklist. With a Vercel trigger, tick **Use + Vercel deployment URL** so it runs against the preview that started the + automation. +2. **Condition**: check the previous step, for example **Previous step → + Failed count** equals 0. A condition has two outputs, **True** and + **False**. +3. **GitHub Comment** on the **False** output, so a failing run is reported + on the pull request. From a Vercel trigger, the pull request is found from + the deployment. +4. **Notification** on the **True** output, to tell the team by email or + Slack that the change passed. Or put an **Actor PR Review** there, so an + actor reviews the change once the checklist passes. + + + + +### Try it + +Click **Run Now** to start it by hand, then open the run from the **Runs** +tab to see what each step did. Adjust and run it again until you trust the +result. + + + + +### Switch it on + +Switch **Active** back on. From now on, every matching pull request runs the +checklist and reports its outcome, without anyone starting it. + + + + +## Steps you can use + +| Step | What it does | +| ------------------- | --------------------------------------------------------------------------- | +| **Run Checklist** | Runs an existing checklist and carries its result forward | +| **Condition** | Branches on the previous step's status or its passed, failed or error count | +| **Notification** | Sends an email or Slack message to workspace members | +| **Delay** | Waits before continuing, to give an async process time to finish | +| **GitHub Comment** | Posts a comment on the triggering pull request | +| **Actor PR Review** | Has an actor review a pull request and report its findings | + +## Other triggers + +The same editor works with every trigger. **Manual** runs when you (or the +API) start it, **Schedule** runs on a recurring schedule in your timezone, and +**Webhook** runs when your CI calls its URL. The event triggers each have +their reference on the integration's page: +[GitHub](/integrations/github), [Vercel](/integrations/vercel), +[Slack](/integrations/slack), +[Figma](/integrations/figma), [Cursor Origin](/integrations#cursor-origin) and +[Webhooks](/integrations/webhooks). + +An automation created from an assistant over [MCP](/mcp) needs the `mcp:run` +scope to run unattended. Without it, a schedule, webhook or event automation is +created paused, and it cannot be switched on from that connection. ## Next steps -- **[Turn runs into insights](/tutorials/reviewing-runs)** +- **[Review runs and act on them](/tutorials/reviewing-runs)** - **[Automate Stunt Double from Claude](/tutorials/automate-with-mcp)** diff --git a/content/docs/tutorials/effective-checklists/index.mdx b/content/docs/tutorials/effective-checklists/index.mdx index 35fe988..fb5e531 100644 --- a/content/docs/tutorials/effective-checklists/index.mdx +++ b/content/docs/tutorials/effective-checklists/index.mdx @@ -1,20 +1,20 @@ --- title: "Write checklists" icon: "checklist" -description: "Structure checks around outcomes, not clicks, and read the evidence behind a pass or fail instead of trusting the badge." +description: "Write a checklist that holds up: checks around outcomes, not clicks, pass/fail, weighted and informational types, a passing score, and order and conditions." --- # Write checklists that catch real regressions A checklist is only as useful as the checks inside it. This tutorial covers -how to write checks that hold up over time, and how to read a run so a -"failed" badge tells you something you can act on. +how to write checks that hold up over time, decide what each one is worth and +order them, so a "failed" verdict tells you something you can act on. @@ -24,6 +24,16 @@ how to write checks that hold up over time, and how to read a run so a caption="Each check says what should be true. Under it: its type, when it runs, and whether a failure stops the run." /> +## Start from a template + +**Create checklist** opens on categories first: Core & reliability, Onboarding & +activation, Conversion & growth, Forms & input, Accessibility, Mobile & +responsive, Content & trust, and Navigation & findability. Pick a template to +start from its checks, or **Start from scratch** for a blank one. The next two +steps name the checklist, choose the URL and actor, then let you edit the +checks before you create it. Treat a template's checks as a first draft: the +rest of this tutorial is about making them specific to your product. + ## Write one check per outcome, not per click A check is a single description of what should be true. It's tempting to @@ -106,6 +116,13 @@ Set its run condition to: Without conditions, both shapes produce a misleading report: one failure counted twice, or a check that fails because the product worked. +A check's **On failure** setting decides what a failure does to the rest of the +run. **Fail and continue**, the default, records the failure and carries on. +**Fail and stop** ends the run there and records every check it had not reached +as skipped. Use it for a step everything after depends on, like signing in, so +one broken step does not show up as a page of knock-on failures. A check set to +stop fails the run when it fails, whatever its type. + A check whose condition is unmet is recorded as **skipped**, naming the check it depended on, and left out of the score entirely. It did not fail, and it is not inconclusive either. A condition is only unmet when the previous check's verdict @@ -117,49 +134,20 @@ One thing to know before you reach for informational checks: they need the actor to read the page, so a checklist containing one always runs the full agent rather than replaying its recorded script. -## Read the evidence, not just the pass/fail badge - -A run reports a verdict, a score for its weighted checks, and the evidence -behind every check. Each check carries its own screenshot, taken on the page -the actor was actually on when it reached its verdict. A run report has tabs -for: - -- **Results**, each check's status and a short explanation. -- **Screenshots**, the page as the actor saw it at each step. -- **Recording**, the full session if you want to watch it play out. -- **Knowledge**, which knowledge entries the actor drew on. - -When a check fails, read the explanation and screenshot before deciding -whether it's a real regression or an ambiguous instruction. A surprising -number of "failures" turn out to be a check that needs to be more specific -about what counts as success. +## Tighten a check that fails for the wrong reason - - -## Read a run against the one before it - -A finished run is compared with the previous completed run of the same -checklist, under **Since the previous run** on the report. It names what -changed rather than what is red, which is the difference between a report you -read every time and one you stop opening. Informational checks are compared as -text, so "$29 per month" becoming "$39 per month" shows up even though no -pass or fail state moved. +When a check fails, read its explanation and screenshot before deciding whether +it is a real regression or an ambiguous check. A surprising number of failures +turn out to be a check that needs to say more precisely what counts as +success: "the order total is shown" passes on a page that shows the wrong +total, while "the order total matches the cart total" does not. Editing a checklist keeps its history: checks you did not touch keep their ids -and their past results, so a comparison still has something to compare against. - -## Re-run before you trust a result - -An actor working through a hosted browser can hit a transient issue, a slow -page load, a flaky third-party script, just like a human tester can. Before -filing a bug from a single failed run, re-run the checklist once. A result -that reproduces consistently is worth acting on immediately. +and their past results, so the next run is still compared with the last one. +How to read a report, compare runs and re-run before you file a bug is +covered in **[Review runs and act on them](/tutorials/reviewing-runs)**. ## Next steps -- **[Turn runs into insights](/tutorials/reviewing-runs)** +- **[Review runs and act on them](/tutorials/reviewing-runs)** - **[Automate multi-step workflows](/tutorials/building-workflows)** diff --git a/content/docs/tutorials/feedback-widget/index.mdx b/content/docs/tutorials/feedback-widget/index.mdx index aa02a41..c265609 100644 --- a/content/docs/tutorials/feedback-widget/index.mdx +++ b/content/docs/tutorials/feedback-widget/index.mdx @@ -1,100 +1,81 @@ --- title: "Collect feedback" icon: "feedback" -description: "Let stakeholders pin comments on a prototype or staging build, then triage, reply to and resolve them from the project Comments view." +description: "Run one feedback round on a prototype: install the widget, hand it to reviewers, then triage, reply to and resolve what comes back." --- # Collect stakeholder feedback on a prototype Share a prototype and the notes come back as screenshots in Slack, with no way -to tell which page or which build they were about. The feedback widget is one -script tag on the prototype: reviewers pin a comment on the exact spot, and it -arrives with a screenshot and the page context already attached. +to tell which page or which build they were about. In this tutorial you run one +round of feedback on a prototype with the feedback widget: reviewers pin +comments on the exact spot, and you triage, answer and close them from the +project's **Comments** view. -## 1. Turn comments on for a project +You need a Stunt Double project for the prototype and a deploy of it where you +can add a script tag. + +## 1. Turn comments on for the project Open the project holding the prototype and go to **Comments**. If comments have never been enabled, you get a short explainer and an **Enable comments** button. -Enabling switches the feature on and mints the project's **API key**, which ties -the widget on your site back to this project. - -Each project has its own key and its own inbox, so a round of feedback on one -prototype never mixes with another. +Enabling switches the feature on and creates the project's **API key**, which +ties the widget on your site back to this project and its own inbox. ## 2. Add the widget to the prototype -The Comments view then shows the install step with two tabs. - -**With Claude** gives you a prompt to paste into Claude, Claude Code, or any -coding assistant. It describes both script tags and where they go, which is -usually the fastest route if an agent already has your repo open. - -**Code** gives you the snippet directly. Add it just before the closing -`` tag. Set `data-sd-version` to your build ID if you want each round of -feedback kept apart (see [Prototype versions](#prototype-versions) below). The +The Comments view now shows the install step with two tabs. **With Claude** +gives you a prompt to hand to a coding agent that has your repo open; **Code** +gives you the script tag to paste just before ``. Either way, copy it +with the **Copy** button so the key is filled in. The [integration reference](/integrations/feedback-widget#the-snippet) explains -every attribute. +each attribute. -There is no package to install and no build step, so this works on a staging -deploy, a preview URL, or a throwaway static build just as well as on your -production site. +Deploy or reload the prototype and open any page carrying the snippet. Within a +few seconds the install step flips from **Waiting for widget connection** to +**Widget detected** and moves you on to the Comments view. -### Confirming it works +If it never flips, the usual causes are a mistyped key and a host that is not +allowed yet. A prototype on a preview URL needs that host (or +`*.your-domain.com`) under **Allowed domains**; see +[Troubleshooting](/integrations/feedback-widget#troubleshooting). -The install screen polls while you work. Add the snippet, deploy or reload the -prototype, and visit any page carrying it. Within a few seconds the screen flips -from **Waiting for widget connection** to **Widget detected** and moves you on -to the Comments view. No manual verification step, and nothing to paste back. - -If it never flips, the two usual causes are a mistyped key and a domain that is -not allowed yet. Both are covered under [Control who can use -it](#control-who-can-use-it). - -## 3. Hand it to your stakeholders +## 3. Hand it to your reviewers Before you send the link, decide who should be able to comment. -For an internal review, turn on **Require sign in** under **Comments → -settings**. Only signed-in members of the workspace can then read or leave -comments, which is the right setting for an unreleased prototype on a public -staging URL. Reviewers get a **Sign in to review** button instead of an -anonymous form: it opens a popup, they sign in to Stunt Double as normal, and -the popup hands the widget a short-lived token proving workspace membership. -Their replies are badged **Team**, and their name comes from their account -rather than a form field. - -The token lasts an hour, so a long review session may ask for a fresh sign-in. -Because a cross-origin widget cannot read the Stunt Double session cookie, this -token is the only thing that unlocks gated data: the sign-in state the widget -shows is cosmetic on its own. +- **Internal review.** Turn on **Require sign in** in the comment settings. + Reviewers get a **Sign in to review** button, sign in to Stunt Double in a + popup, and their comments are badged **Team**. This is the right setting for + an unreleased prototype on a public staging URL. +- **A wider round**, with customers or people outside the workspace. Leave + sign-in off and send the link. -For a wider round, with customers or people outside the workspace, leave sign-in -off and send the link. Commenting then takes three actions: +Either way, leaving a comment takes three actions: 1. Click the floating button in the bottom-right corner, or press **`c`**. -2. Click the spot the comment is about. A pin lands there. -3. Type a name, optionally an email, and the comment, then send. **Escape** - cancels at any point. +2. Click the thing the comment is about. The widget outlines the element under + the cursor and pins the comment to it; hold **Shift** to drop a free pin + instead. +3. Type the comment (and, when not signed in, a name and optional email), then + send. **Escape** cancels at any point. The name and email are remembered in that person's browser, so their second -comment only needs the comment itself. The email is optional and only used to -notify them when someone replies to or resolves what they left. +comment only needs the comment. The email is only used to tell them when +someone replies to or resolves what they left. -Every submission carries more than the text: a screenshot of the page as it -looked, the page URL, the pin position, viewport size, scroll offset, and basic -device information. That is what makes "this bit is confusing" actionable a week -later. - -Keep **Show comments on page** enabled for a group review and existing pins are -drawn on the page, so five stakeholders discuss one thread instead of filing the +Keep **Show comments on page** on for a group review and existing pins are +drawn on the page, so five reviewers discuss one thread instead of filing the same note five times. Turn it off when you want independent reactions: the widget still collects everything, it just does not show anyone else's. ## 4. Triage what comes back The project's **Comments** view is where feedback lands. It opens on the -**Open** queue with counts across the top: total comments, how many are open, -how many pages they came from, and how many are resolved. +**Open** queue, with **New**, **Resolved** and **All** beside it, and counts +across the top: total comments, how many are open, how many pages they came +from, and how many are resolved. New comments appear as they arrive, without a +reload. +## Create the actor + +Open **Actors** in the sidebar and choose **Create actor**. Creating one takes +two steps: + +1. **Start**: pick a template for a common type of user, or **Write your own**. + A template fills in the next step rather than creating the actor straight + away, so you see everything before it is saved. +2. **Details**: a **name**, an optional **description** and the + **instructions**. Name the actor by role ("Busy shop owner"), never as a + person, so results read clearly. + +Everything here can be changed later on the actor's **Profile** tab. + ## Start with a persona, not a checklist Instructions work best when they describe who the actor is standing in for, @@ -37,19 +51,47 @@ familiarity, and a tone: > before showing you the product. An actor written this way makes the same kind of judgment calls a real -visitor would, rather than mechanically executing steps. +visitor would, rather than mechanically executing steps. Write instructions to +the actor, in the second person. They hold up to 1,000 characters, so facts it +needs to look up belong in knowledge instead. + +## Set its personality + +The **Personality** section of the Profile tab has three sliders: + +- **Skepticism**, from trusting to skeptical: how much proof it wants before + taking the product at its word. +- **Technical literacy**, from novice to expert: how comfortable it is with + software, jargon and unfamiliar interfaces. +- **Frustration**, from patient to short fuse: how quickly a struggle wears it + down, and how soon it gives up on a task. + +The personality applies everywhere the actor works: chats, checklist runs and +interviews. Leave a trait unset to let the instructions decide. An interview +can override a trait for its own participants. ## Give it knowledge to draw on -Knowledge entries are the reference material an actor can pull from mid-run: -facts about your product, test account credentials, brand or tone -guidelines, or answers to questions it might otherwise get wrong. Add a -knowledge entry for anything you would otherwise have to explain to a new +Knowledge is the reference material an actor can pull from mid-run. Add +entries on the actor's **Knowledge** tab, each as one of four kinds: + +| Kind | What it holds | Example | +| --- | --- | --- | +| Expertise | A skill or standard the actor applies | Accessibility auditing | +| Process | Steps the actor follows, in order | Reporting a bug | +| Reference | Facts to look up: an FAQ, a policy, pricing | Refund policy | +| Account | A test account to sign in with, never a real password | Staging test account | + +The actor is never handed everything at once. It sees the titles of its +expertise and processes and opens the one a task needs before starting it, +and it searches reference and account entries before guessing a fact or a +login. Add an entry for anything you would otherwise have to explain to a new team member on day one. -Keep entries short and specific. A dozen focused entries work better than one -long document, since the actor only needs to draw on what's relevant to the -step it's on. +Keep entries short and specific, with clear titles. A dozen focused entries +work better than one long document, since the actor finds entries by what they +are about. An entry holds up to 8,000 characters; split anything longer into +entries with titles of their own. ## What an actor can do @@ -57,11 +99,17 @@ Out of the box an actor works through your product the way a real visitor would: - **Drives a real browser** through your product, observing each page and - deciding what to do next. -- **Reads email** sent to its own inbox, so it can pick up verification codes - and magic links during signup and verification flows. -- **Searches the web** when it needs information beyond your product. -- **Remembers context** it has seen before, carrying useful state between runs. + deciding what to do next. The **Browser** tab sets where that browser runs + and where sites see it browsing from. +- **Reads email** sent to an inbox of its own, so it can pick up verification + codes and magic links during sign-up. Each actor gets one address, assigned + by the platform, on the Startup plan and above. +- **Stays signed in** between runs once you log in as the actor from the + Browser tab, on the Startup plan and above. +- **Searches the web** in chat when it needs information beyond your product. + +Email is the only channel an actor has. It never enters a phone number or +picks SMS verification; when a site insists, it reports the step as a blocker. You don't have to wire any of this up. Give the actor a clear persona and the knowledge it needs, and it draws on whatever is relevant to the step it's on. diff --git a/content/docs/tutorials/index.mdx b/content/docs/tutorials/index.mdx index 2a9b19e..53fadc4 100644 --- a/content/docs/tutorials/index.mdx +++ b/content/docs/tutorials/index.mdx @@ -1,97 +1,108 @@ --- title: "Tutorials" -description: "Step-by-step guides for getting the most out of every part of Stunt Double: actors, checklists, interviews, workflows, Slack, devices, live sessions, and the API." +description: "Pick a tutorial by what you want to get done: each one takes a single task in Stunt Double from start to finish." --- # Tutorials -The **[Quickstart](/getting-started)** gets you from an empty -workspace to a first checklist run, and **[Core concepts](/concepts)** -explains what each building block does. These tutorials go further: practical, -task-oriented guides for getting real value out of each part of the product as -your usage grows. +Each tutorial takes one task from start to finish and stands on its own, so +start with the one your team needs. New to Stunt Double? Do the +**[Quickstart](/getting-started)** first. -## The series +## Test your product + +## Learn how people get on + + + +## Automate it + + -## Next steps +## Not a tutorial? -Each tutorial stands on its own, so start where your team needs it most. To -connect Slack, GitHub, Linear, Figma or Vercel, see -**[Integrations](/integrations)**. To drive Stunt Double from an assistant, see -**[MCP](/mcp)**. +For a workflow that starts in a design tool (Figma, Claude Design or your +codebase), see **[Guides](/guides)**. For setup and settings of a connected +tool, see **[Integrations](/integrations)**. diff --git a/content/docs/tutorials/live-sessions/index.mdx b/content/docs/tutorials/live-sessions/index.mdx index ada4e54..1869351 100644 --- a/content/docs/tutorials/live-sessions/index.mdx +++ b/content/docs/tutorials/live-sessions/index.mdx @@ -28,7 +28,8 @@ yourself. Open a project and choose **Live sessions** under **Discover**. The page lists the project's sessions, newest first, so you can go back to any earlier one and -read what happened. +read what happened. A session that has ended opens on its summary. The latest +few also appear on the project's overview.
@@ -41,6 +42,9 @@ The dialog asks only what cannot change once the session is running: - **Start on**: the address the browser opens first. - **Session**: **Interview** or **Task** (see below). - **Browser**: **This Mac** or **Cloud browser**. +- **Model**: **Stunt Double**, or a model on this Mac. Asked only when the + browser is This Mac and the Mac already has + [local models](/integrations/desktop-app#local-models). Replies, tools and sign-ins are all changed from inside the session. @@ -62,7 +66,7 @@ message. next, or what would stop it signing up. This is a moderated usability session without recruiting anyone. - **Task**: the actor does what you ask and reports back. Use it to reproduce - a bug, walk a flow end to end, or check something quickly before a release. + a bug, try a flow end to end, or check something quickly before a release. ## Choose a browser @@ -73,6 +77,15 @@ message. behind your VPN and anything else this Mac can reach. When a session can run on this Mac, it is the default. +A project that is only reachable inside your network needs **This Mac**: the +cloud browser refuses it before the session starts. Private and internal +addresses also need the Startup plan or above. + +On This Mac, the browser follows the app's +[Where the browser runs](/integrations/desktop-app#how-the-browser-runs) +setting: inside the app by default, where you watch it in the session, or in +its own Chrome window. + You do not need to set your Mac up as a device first. If it is not one yet, starting the session pairs it for you in the background, and that pairing is removed again when its last session ends. A Mac that already belongs to @@ -126,10 +139,11 @@ browser. - **Project and actor** MCP servers you have already connected in Stunt Double. - **On this Mac**: MCP servers that run on your own Mac, in sessions using the desktop app. Turn them on for the session, then import servers from Claude - Desktop or Cursor, or add them in the app. The app asks you to approve each - server, showing the exact command, before it ever runs, and the chat asks you - before each tool call. Switch on **Run read-only tools without asking** to - skip that question for tools their server marks read-only. + Desktop or Cursor, or add them in the app (see + [MCP servers on this Mac](/integrations/desktop-app#mcp-servers-on-this-mac) + for how the app approves them). The chat asks you before each tool call. + Switch on **Run read-only tools without asking** to skip that question for + tools their server marks read-only. What a tool returns is kept in the session's transcript, which everyone in the workspace can read, so only turn on servers whose output you are happy to @@ -147,9 +161,8 @@ Sign-ins stay on your Mac, in a browser profile kept apart from your own Chrome, so an actor never sees your personal sessions. The same section lists the profiles stored on this Mac with their size, and can clear one. -A Mac MCP server that starts with `npx` or `uvx` needs Node or uv. If it is -missing, the server's row links to [Set up this Mac](/integrations/desktop-app#set-up-this-mac), -which installs it. +A Mac MCP server that starts with `npx` or `uvx` needs Node or uv, which +[Set Up This Mac](/integrations/desktop-app#set-up-this-mac) installs. ## End the session @@ -158,7 +171,10 @@ journey and captures stay where they are. Once a session ends, a summary takes the browser's place: how long it ran, the pages visited, the findings by severity and your notes, with a short -account of what happened and suggested next steps. +account of what happened and suggested next steps. A session that thought with +a model on your Mac gets the facts without the written account, since its +transcript is not sent to Stunt Double's model. Opening an ended session from +the list, or from the actor's activity, takes you straight to its summary. A session left idle closes its browser on its own after a while. When that is close, **Keep session open** appears in the header with the time it closes. diff --git a/content/docs/tutorials/reviewing-runs/index.mdx b/content/docs/tutorials/reviewing-runs/index.mdx index d9511f4..dce055f 100644 --- a/content/docs/tutorials/reviewing-runs/index.mdx +++ b/content/docs/tutorials/reviewing-runs/index.mdx @@ -1,28 +1,37 @@ --- title: "Review runs" icon: "insight" -description: "Read results, screenshots, and recordings like a teammate would, and see what surfaces automatically as an insight." +description: "Read a checklist run report, answer a run that needs you, compare it with the last run, share it, and triage what runs find from the project Issues page." --- -# Turn runs into insights +# Review runs and act on them -Every run an actor completes, whether it's a checklist, an interview round, -or a workflow, is recorded in full. This tutorial covers how to read a run -report and how to use the insights Stunt Double surfaces on top of it. +Every checklist run is recorded in full, whether you started it, an +automation did or an assistant did over MCP. This tutorial goes from a +finished run to a decision: read the report, check it against the run before, +and turn what is broken into tracked issues. Interview rounds have a report of +their own, covered in **[Run a user interview](/tutorials/running-an-interview)**. + + ## Read a run report -A run report is organized into tabs: +A run report leads with the verdict, a score for any weighted checks, and the +checks that need attention. It is organized into tabs: -- **Results**, the pass, fail, or error status for each check, with a short - explanation for each one. -- **Journey**, the pages the actor visited and the emails it read, in order. -- **Screenshots**, the page as the actor saw it at each step, useful for - spotting a visual regression that a pass or fail badge wouldn't catch. -- **Recording**, the full session, step through it in order or watch it play - out end to end. -- **Knowledge**, which knowledge entries the actor drew on for that run, - useful for checking whether it's relying on something out of date. +- **Results**: each check's status and a short explanation, with the + screenshot taken on the page the actor was on when it reached its verdict. +- **Journey**: the pages the actor visited and the emails it read, in order. +- **Screenshots**: the page as the actor saw it at each step, useful for + spotting a visual regression that a pass or fail wouldn't catch. +- **Recording**: the full session, to step through or watch end to end. +- **Knowledge**: which knowledge entries the actor drew on, useful for + checking whether it relied on something out of date. -Start with Results to get the headline, then drop into Screenshots or the -Recording when a result needs more context than the explanation gives you. +Start with Results to get the headline, then open Screenshots or the Recording +when a result needs more context than the explanation gives you. A check that +errored is **inconclusive**, not failed, and a check skipped by its run +condition says nothing about your product either. + +While a run is in progress, its report shows **Cancel run**. Cancelling a run +on a [device](/integrations/self-hosted-workers) frees that device for the +next run straight away. + +## When a run needs you + +Sometimes an actor can't get past a step on its own: a code only a person has, +or a choice between two paths that changes what is being tested. Rather than +guess, it pauses the run and asks. The run shows **Needs you**, and the person +who started it is notified. + +On the run page, **The actor needs a hand** shows the question and, for a +hosted browser, the browser live. Type an answer and choose **Send answer**, or do the step yourself in +the browser and choose **I have done it, carry on**. Anyone in the workspace +can answer. If nobody does within 15 minutes, the run carries on without an +answer, so treat its verdicts with more care. + +## Compare it with the run before + +A finished run is compared with the previous completed run of the same +checklist, under **Since the previous run**. It names what changed rather than +what is red, which is the difference between a report you read every time and +one you stop opening. Informational checks are compared as text, so "$29 per +month" becoming "$39 per month" shows up even though no pass or fail moved. + +Agentic runs also leave notes for the next run of the same checklist by the +same actor: the route that worked, what blocked it, and what it left behind +(an account it created, a password it reset). The report shows them under +**Notes between runs**. Notes never carry verdicts or passwords, so every run +still judges each check on what the page shows today. If the product is +rebuilt between runs, turn off **Learn from the last run** under +**Configuration** on the checklist's **Instructions** tab. + +## Re-run before you trust a single failure + +An actor in a hosted browser can hit a transient problem, a slow page load or +a flaky third-party script, just like a human tester can. Before filing a bug +from one failed run, choose **Re-run** on the report. A failure that +reproduces is worth acting on straight away; one that doesn't may point to a +check that needs to be more specific (see +**[Write checklists that catch real regressions](/tutorials/effective-checklists)**). + +## Share the report -While a checklist run is still in progress, its report shows **Cancel run**, -so you can stop it from where you are watching. Cancelling a run on a -[device](/integrations/self-hosted-workers) frees that device for the next run -straight away. +Under **Share**, **Copy report link** gives teammates the report itself, and +**Get share link** creates a public link that shows the checks, evidence and +screenshots without a sign-in (**Disable link** revokes it). **Email report** +sends it to a list of addresses. -## What surfaces automatically as an insight +## Triage what runs find in Issues -Not everything worth knowing fits into a pass or fail. As actors work, -Stunt Double surfaces insights: notable observations from a run that fall -outside strict pass/fail, a confusing step, a broken link, an unexpected -result the actor flagged on its own. Insights turn a pile of session -recordings into a short list of things worth your attention, without -requiring anyone to watch every replay. +You should not have to open every report to find out what is broken. A +project's **Issues** page collects it for you. Its **Detected** tab lists +checks that failed on the latest run, design review notes nobody resolved, and +feedback comments nobody has triaged, each linked to its evidence. **Create +issue** turns one into an issue you can assign, prioritize and move through +open, in progress, resolved or dismissed, and **Needs attention** shows the +open ones, highest severity first. -Review new insights on a regular cadence rather than only after something -breaks; the most useful ones are often things nobody thought to write a check -for. +Work through Detected on a regular cadence rather than only after something +breaks. A failure that keeps coming back is a sign the check, or the product, +needs a closer look. -## Share findings with your team +## Send results where your team works -Runs and insights are most useful when they reach the people who can act on -them. Connect **[Slack](/integrations/slack)**, -**[Linear](/integrations/linear)** and **[GitHub](/integrations/github)** (all -listed under **[Integrations](/integrations)**) so failed runs and new insights land where your team already works, -instead of waiting to be checked manually. +Connect **[Slack](/integrations/slack)**, **[Linear](/integrations/linear)** +and **[GitHub](/integrations/github)** so failed runs land where your team +already works, instead of waiting to be checked. ## Next steps diff --git a/content/docs/tutorials/running-an-interview/index.mdx b/content/docs/tutorials/running-an-interview/index.mdx index 2747e71..814ee65 100644 --- a/content/docs/tutorials/running-an-interview/index.mdx +++ b/content/docs/tutorials/running-an-interview/index.mdx @@ -1,19 +1,31 @@ --- title: "Run an interview" icon: "interview" -description: "Structure sections and items, recruit actor personas or real participants, and read an evidence-backed report." +description: "Run one interview end to end: set it up, write the discussion guide, recruit actors or generated personas, run a round and read and share the report." --- # Run a user interview -An interview is a structured conversation Stunt Double runs with your users -at a scale a manual research process can't match. This tutorial covers how to -structure one, who to recruit, and how to read what comes back. +An interview is a structured study Stunt Double runs with persona +participants, at a scale a manual research process can't match. This tutorial +takes one from a research question to a shareable report: set it up, write the +guide, recruit participants, run a round and read what comes back. -## Structure sections and items +## Set it up -An interview is organized into sections, and each section holds a series of -items. An item is either: +Open **Interviews** in a project and choose **New interview**. Setup has three +steps: **Details**, **Discussion guide** and **Recruitment**. + +On **Details**, give the interview a name, the URL participants should use and +a **Research brief**: what you are trying to learn and who you want to hear +from. **Generate video** (in beta, not on the Free plan) also cuts a short +video of the study once the report lands. + +## Write the discussion guide + +Choose **Draft guide with AI** to have the brief turned into a guide you then +edit, or **Write guide manually**. A guide is organized into sections, and +each section holds a series of items. An item is either: - A **question**, asked directly, useful for opinions, priorities, or recalling past experience. @@ -24,45 +36,69 @@ Mixing the two in a section works well: a task that puts the participant in a flow, followed by questions that surface what confused them or what they expected instead. -## Recruit participants: actor personas or real people +## Recruit participants + +Every participant is an AI persona standing in for a real user. On +**Recruitment**, **Add actors** brings in actors you already have in the +workspace, with their knowledge and history. **Generate audience** creates +one to five personas to match an audience you describe. Mix the two in the +same round: a panel of personas gives you a fast, repeatable read on a +direction before you take it to real customers. -Participants can be AI actor personas, real people, or a mix of both in the -same round. Actor personas give you a fast, repeatable panel for testing a -direction before you're ready to recruit, while real participants give you an -authentic voice you can't get any other way. A common pattern is to run an -actor panel first to catch obvious problems, then bring in real participants -to validate what's left. +## Measure usability -## Launch a round +After the guide, each participant answers a short **usability questionnaire** +in character, and the round reports a usability score and grade you can +compare between rounds. It is on by default with **UMUX** (four statements, +comparable with SUS scores). Switch it to **UMUX-Lite** (two statements) or +**Off** under the interview's setup. A round that ran with it off can still be +scored afterwards with **Score usability**, from the transcripts it already +has. -When the guide and participant list are ready, launch a round. Each round is -a complete pass through the guide with every recruited participant. As you -make product changes, launch another round against the same guide to see how -perception shifts, rather than starting from scratch each time. +## Run a round + +When the guide and participant list are ready, select **Run interview**. Each +round is a complete pass through the guide with every participant. As you +make product changes, select **Re-run interview** to run another round against +the same guide and see how perception shifts, rather than starting from +scratch each time. + +The pages participants visit also feed the project's topology, so an interview +fills in the map of your product the same way checklist runs do. ## Read the report Every round produces a report with: -- **Overview**: the counts and a **summary** of what the round found. -- **Findings**: the patterns that came up across participants, each backed by - evidence drawn straight from the interview. +- **Overview**: four short blocks, each opening onto its own tab. The summary + with the counts beneath it, **Highlights** (the findings that reached the + most participants), **Actions** (the highest priority recommendations) and + **Evidence** (a quote for each highlight, with the screen it was said on). +- **Findings**: the study cut, a short video of the moments behind the report, + then the patterns that came up across participants, each backed by quotes + drawn straight from the interview. - **By question**: what most participants did, where they differed, and the outliers. - **Recommendations**: ranked by priority, ready to track as goals. -- **Usability** and **Transcripts**: the questionnaire scores and every - participant's session in full. +- **Usability** and **Transcripts**: the questionnaire scores, compared with + the previous round, and every participant's session in full. -Because every finding and recommendation is tied to evidence quotes, you can -check a claim against what a participant actually said before acting on it. +Because every finding and recommendation is tied to evidence quotes, and each +quote shows the screen it was said on, you can check a claim against what a +participant actually said and saw before acting on it. + +To share a round with people outside the workspace, use **Share** on the +report and **Get share link**. The link shows the report; recordings and +transcripts stay behind sign-in. **Email report** sends it to a list of +addresses, and **Download PDF** saves a copy. ## Next steps -- **[Turn runs into insights](/tutorials/reviewing-runs)** +- **[Review runs and act on them](/tutorials/reviewing-runs)** - **[Automate multi-step workflows](/tutorials/building-workflows)** diff --git a/content/docs/tutorials/self-hosted-worker/index.mdx b/content/docs/tutorials/self-hosted-worker/index.mdx index 353eb2e..110797b 100644 --- a/content/docs/tutorials/self-hosted-worker/index.mdx +++ b/content/docs/tutorials/self-hosted-worker/index.mdx @@ -1,77 +1,118 @@ --- title: "Test behind a firewall" icon: "worker" -description: "Run actors against an internal product from a Mac on your network, no inbound firewall changes required." +description: "Run a checklist against an internal product from a Mac on your network, from setting up the Mac to reading the result." --- # Test a product behind your firewall If the product you want to test is only reachable inside your network, a -cloud browser can't reach it. A device is a Mac on your side of the firewall -running the Stunt Double app, so actors browse from there without you opening -anything up. +cloud browser can't reach it. In this tutorial you set up a Mac on your network +as a device, point a project at your internal product, run one checklist +through that Mac and read what the actor found. Nothing on your firewall +changes: the Mac dials out to Stunt Double. - Devices are on every paid plan, and testing private or internal addresses from one needs the - Startup plan or above. A workspace owner or admin switches devices on, then any member can set - up their own Mac. + Testing private or internal addresses needs the Startup plan or above. + [Devices](/integrations/self-hosted-workers#before-you-start) lists what each + plan and role can do. -## Turn devices on + + -Open **Settings > Devices** and switch on **Use devices in this workspace**. -On other plans, this page explains what devices do and how to upgrade. +### Set up a Mac on your network -## Set up a Mac +Pick a Mac that can open your internal product in its own browser: on the +office network, or with the VPN connected. Install the +[desktop app](/integrations/desktop-app#install-it) on it, sign in, then open +**Devices** and click **Set up this Mac**. Wait for **This Mac** to show +**Connected**. The [Devices](/integrations/self-hosted-workers#set-it-up) +reference covers this step in full. -1. On a Mac that can reach your internal product, download the Stunt Double - [desktop app](/integrations/desktop-app), open it and sign in. Google - Chrome needs to be installed. -2. Open **Go > This Device** (Cmd+D) and click **Set up this Mac**. -3. Wait for the device console to show **Connected**. +Keep the app open for the rest of the tutorial. A device is only online while +the app is running. -The app dials out to Stunt Double rather than waiting for an inbound -connection, so your firewall needs no changes. If your product sits behind a -VPN portal or SSO, sign in once in the device console. The sign-in persists -for later runs. If the sign-in needs a client certificate, Keychain or a smart -card, switch **How the browser runs** to **Its own window** first. + + -## Choose where each actor's browser runs +### Sign in once, if the product needs it -Open an actor, go to its **Manage** tab and find **Where this actor's browser -runs**: +If your product sits behind a VPN portal or SSO, open the browser under +**Live view** on **This Mac** and sign in the way you normally would. The +sign-in persists, so actors start every later run signed in. -- **Stunt Double cloud** for public sites. -- **Any device in this workspace** to use whichever device is online. -- **A named device** to always use that Mac. +If the sign-in asks for a client certificate, Keychain or a smart card, first +switch **Where the browser runs** to **Its own window**, so the prompt has a +real Chrome window to appear in. -An actor set to a device never falls back to the cloud: if its device is -offline, the run stops and tells you. An actor set to the cloud never opens an -internal site: if the project is marked internal, or the address only works -inside your network, the run stops and asks you to choose a device. + + -## Control what it can reach +### Point a project at the internal address -Each device has an access setting in **Settings > Devices** with three modes: +Create a project, or open an existing one, and enter the internal address as +its URL. As you type, the field checks where the address can be reached from. +For an internal one it reads **This project is internal, so actors open it on +a device in your network.** -- **Allow all domains**: no restriction. -- **Allow specific domains**: only the domains you list. -- **Block specific domains**: everything except the domains you list. +You do not need to change any actor. An actor on the cloud browser borrows +whichever device is online when its project is internal. -A new device starts on Allow all domains, so it works as soon as it connects. -To restrict it, switch to Allow specific domains and list only what your -actors need to reach. + + -## Watch status live +### Check the device can reach it -Devices show their status live everywhere they appear: Settings, the actor's -Manage tab and the device console. A Mac that stops checking in turns Offline -within a couple of minutes, so you can tell before starting a run that depends -on it. +If you are an owner or admin, open the Mac from **Devices** and enter the +address under **Test a URL**. The test opens it in the device's browser, so a +pass means actors can reach it too. A failure here is cheaper to fix than a +failed run: check the Mac's VPN, and its **Network access** setting. + + + + +### Run a checklist + +Open **Checklists** in the project, choose **Create checklist**, write one or +two checks as plain-language outcomes (for example "Sign in and open the +reports page"), then press **Run**. + +The run goes to your Mac. Switch to **This Mac** to watch it under **Live +view**: the device reads **Running a task** while the actor works, and the +activity log beside it lists what the device did. If another run is already +using the Mac, yours waits its turn. + + + + +### Read the result + +Open the finished run from the checklist. Each check has its result, the +screenshot the actor took and its explanation, the same as a run in the +cloud. [Review runs and act on them](/tutorials/reviewing-runs) covers what to +do with failures. + + + + +## Make it routine + +Once one run works, you can rely on the Mac for more: + +- **Automations** on an internal project use the device the same way, so a + schedule or a deploy trigger can re-check the product without anyone at the + Mac. Leave the app running on a Mac that stays awake. +- **Keep an actor on this Mac** for every run, public sites included, from the + actor's **Browser** tab. +- **Limit what the device can open** to the domains your actors need, under + **Network access**. + +[Devices](/integrations/self-hosted-workers) explains how runs choose a device, +how to share one Mac across the team and how to restrict it. ## Next steps - **[Devices reference and troubleshooting](/integrations/self-hosted-workers)** - **[Run a live session](/tutorials/live-sessions)** to watch and steer an actor on your Mac - **[Automate multi-step workflows](/tutorials/building-workflows)** -- **[Turn runs into insights](/tutorials/reviewing-runs)** diff --git a/content/docs/tutorials/slack-design-review/index.mdx b/content/docs/tutorials/slack-design-review/index.mdx index 3bf8044..97af7e9 100644 --- a/content/docs/tutorials/slack-design-review/index.mdx +++ b/content/docs/tutorials/slack-design-review/index.mdx @@ -1,7 +1,7 @@ --- title: "Design review in Slack" icon: "slack" -description: "Get a design review on any link your team shares in Slack: Stunt Double opens the page or Figma frame and replies in the thread with prioritized findings." +description: "Ask for a design review in Slack, steer it from the thread and turn it on in a channel, with prioritized findings in the reply." --- # Review designs from Slack @@ -31,27 +31,18 @@ workspace and starts checklists and workflows for you. ## 1. Connect Slack -Open **Integrations** > Slack and select **Install Slack agent**, then **Add** -your Slack team to the workspace (a workspace owner or admin does this step). -That is the whole setup. The Slack app already asks for the permissions it -needs, so nothing has to be wired up by hand. Review settings live under -**Design reviews > Settings**. The **[Slack](/integrations/slack)** page covers -permissions, and the difference between **Remove** (one workspace) and -**Disconnect** (your account, every workspace). +Install the Slack agent and add it to your workspace as +**[Slack](/integrations/slack#set-it-up)** describes. The first two steps there +are all a review needs: from the moment the connection exists, anyone in your +Slack team can message Stunt Double directly and ask for one. Channels are +optional and covered in [step 4](#4-turn-it-on-in-a-channel). -From the moment the connection exists, anyone in your Slack workspace can -message Stunt Double directly and ask for a review. Channels are optional and -covered in [step 4](#4-turn-it-on-in-a-channel). +Review settings live on the **Settings** tab of **Design review** in the +sidebar, beside the **Reviews** list and your **Guidelines**. -Figma is the one extra, and only for Figma links. Connect it from **Integrations** ([Figma](/integrations/figma)) -and Figma frames are rendered and reviewed. Without it, a Figma link comes back -with a **Connect Figma** button instead of feedback. Web links are reviewed -either way. - -If your workspace connected Slack before direct messages were supported, the -page shows **Reconnect Slack**. An installation keeps whatever permissions it -was granted, so Slack quietly delivers nothing rather than reporting an error. -Reconnecting grants the two permissions the direct-message surface needs. +Figma links need one extra: connect [Figma](/integrations/figma) and Figma +frames are rendered and reviewed. Without it, a Figma link comes back with a +**Connect Figma** button instead of feedback. Web links are reviewed either way. ## 2. Ask for a review @@ -143,7 +134,8 @@ come back, and the thread says which one failed and why. Direct messages work on their own. A channel is for teams that share work in the open, where nobody should have to remember to mention a bot. -Under **Design reviews > Settings**, add the channel. Every message +On the **Settings** tab of **Design review**, add the channel under +**Channels**. Every message posted there that carries a link and asks for feedback then starts a review, with no mention needed. @@ -156,7 +148,8 @@ checks both against live Slack state rather than a stored flag: - **The connection can read messages there.** Being mentioned in a channel is a different permission from reading it, and public and private channels differ again. A connection made before the permission was requested keeps its old - grant, so the page prompts for a reconnect naming the channel it affects. + grant, so the page shows **Reinstall to watch channels** and names the + channel it affects. **Try it** on the same page posts a request in the channel as the bot and reviews it, so you can watch the whole flow before asking your team to use it. @@ -165,30 +158,11 @@ Turning a channel off removes the automatic behavior, not the feature: an @mention with a link and a request still starts a review anywhere the bot has been invited. -## 5. Ask the agent for anything else - -Anything that is not a link plus a request for feedback goes to the agent. It -runs against one workspace, with the same read and dispatch surface as the -[MCP server](/mcp): - -- List the projects, actors, checklists, and workflows in the workspace. -- Start a checklist run and hand back the run it created. -- Start a workflow run. +## 5. Ask for anything else -Both surfaces work: a direct message, or an @mention in any channel it has been -invited to. Replies stream in as they are written rather than landing all at -once. - -A thread is one conversation. The first message starts a session that stays warm -for a day, and every follow-up in that thread feeds the same conversation, so -"run that one again" resolves to the checklist you were just discussing. The -direct message also pins a few starting prompts to the top of the Messages tab. - -Runs started from Slack are attributed to the person who asked, as long as they -have linked their Slack identity in their notification settings. Everyone else's -runs are attributed to whoever installed the connection, which is worth fixing -before a team leans on this: attribution is what makes a run's history legible a -month later. +Anything that is not a link plus a request for feedback, such as "run the +checkout checklist", goes to the Slack agent instead of the reviewer. What it +can do is on the [Slack](/integrations/slack#the-slack-agent) page. ## When nothing happens @@ -200,11 +174,12 @@ order: 2. **It was a reply in a thread nobody has reviewed yet.** A reply only starts a review when the thread already holds one. Post the link as a new message. 3. **The bot is not in the channel.** Run `/invite @Stunt Double` there. -4. **The connection is missing a permission.** **Design reviews > Settings** names - this against each configured channel, with a reconnect button. -5. **The workspace is over a usage limit.** The thread says which limit was hit +4. **The workspace is over a usage limit.** The thread says which limit was hit rather than going silent. +If direct messages or channels get no answer at all, the connection itself is +the problem: see [Troubleshooting](/integrations/slack#troubleshooting). + Reviews and agent runs are metered against your plan like any other browser work, plus the tokens the review spends. A review that drives the page uses one browser session for the whole thing, however many links the message carried; one that @@ -217,8 +192,9 @@ falls back to capturing screens uses one per link. - Ask for the review before the internal critique, not instead of it. It clears the obvious contrast, hierarchy, and label problems so your team spends its time on the decisions that need judgment. -- Link your Slack identity if you plan to start runs from Slack. Attribution - costs nothing to set up and cannot be backfilled. +- Link your Slack identity under your notification preferences if you plan to + start runs from Slack. Attribution costs nothing to set up and cannot be + backfilled. - Send a Figma link with a node selected. The frame you are asking about beats the first frame in the file. diff --git a/content/mcp-clients/chatgpt-and-codex.mdx b/content/mcp-clients/chatgpt-and-codex.mdx new file mode 100644 index 0000000..7a46754 --- /dev/null +++ b/content/mcp-clients/chatgpt-and-codex.mdx @@ -0,0 +1,30 @@ +--- +description: Connect ChatGPT to Stunt Double as a custom app in developer mode, with checklist runs, reports and feedback drawn as cards. +--- + +In ChatGPT, Stunt Double is an app: the hosted MCP server with its tools, plus cards that draw checklist runs, interview and Index reports, workflow runs and feedback in the conversation. The same package will install in Codex once it is in OpenAI's plugin directory. Until then, use the [Codex CLI](/mcp/clients/codex-cli) page for Codex. + +{/* setup */} + +OpenAI moves this setting around. If you don't see developer mode under **Settings**, **Apps**, **Advanced**, open the plugins page in ChatGPT, select **+** and choose **Add custom MCP server**. + +## Sign in + +When you create the app, choose OAuth as the authentication method and paste the server URL. ChatGPT registers itself with Stunt Double and opens the sign-in page: sign in, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. + +## Check it works + +- Start a new conversation, type `@` and choose Stunt Double, then ask: "List my Stunt Double workspaces." +- Ask for a checklist run's result. It comes back as a card with the verdict, score and each check's evidence, and refreshes while the run is still going. + +## Troubleshooting + +- **Tools look out of date:** open the app's connection settings in ChatGPT and select **Refresh**, then start a new conversation. +- **A tool you expected is missing:** the connection may not hold its scope. Ask ChatGPT to read the `stuntdouble://connection` resource, or reconnect and approve the scope. +- **No option to add a custom app:** your plan or workspace policy may not allow developer mode. Ask your ChatGPT workspace admin. + +## Next + +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, and which ones draw a card +- [Connect](/mcp/connect): other endpoints, and revoking access diff --git a/content/mcp-clients/claude-code-plugin.mdx b/content/mcp-clients/claude-code-plugin.mdx new file mode 100644 index 0000000..0fc5091 --- /dev/null +++ b/content/mcp-clients/claude-code-plugin.mdx @@ -0,0 +1,31 @@ +--- +description: Install the Stunt Double plugin for Claude Code to get the MCP server plus task skills and subagents in one step. +--- + +The plugin installs the same hosted MCP server as the [Claude Code](/mcp/clients/claude-code) page, plus the [skills](/mcp/skills) (such as `verify-change` and `run-user-interview`) and the [subagents](/mcp/agents) that know which tools to call for one kind of job. Pick it over the plain server when you want Claude to follow a tested recipe instead of working out each step. If you already added the server with `claude mcp add`, remove it (`claude mcp remove stuntdouble`) so the tools don't load twice. + +{/* setup */} + +You can also install it from `/plugin` inside Claude Code: add the marketplace, then pick **stuntdouble** from the **Discover** tab and choose a scope (just you, this repository, or every project). + +## Sign in + +The plugin's server signs in the same way as the plain server: run `/mcp`, choose the Stunt Double server (it is listed under the plugin) and select **Authenticate**, then approve in the browser. The consent screen lists the scopes the connection asks for; the [overview](/mcp#authentication) explains each. + +## Check it works + +- Type `/stuntdouble:` to list the skills, for example `/stuntdouble:verify-change`. Claude also picks a skill on its own when your request matches it. +- Run `/agents` to see the subagents the plugin added. +- Ask: "List my Stunt Double workspaces." + +## Troubleshooting + +- **Skills or tools missing after install:** plugins load when a session starts, so start a new one. +- **Turn it off without uninstalling:** disable it in `/plugin` or with `claude plugin disable`. +- **Re-authenticate:** in `/mcp`, choose **Clear authentication** on the Stunt Double server, then authenticate again. + +## Next + +- [Skills](/mcp/skills) and [agents](/mcp/agents): what each one does +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/claude-code.mdx b/content/mcp-clients/claude-code.mdx new file mode 100644 index 0000000..3f76458 --- /dev/null +++ b/content/mcp-clients/claude-code.mdx @@ -0,0 +1,32 @@ +--- +description: Add the Stunt Double MCP server to Claude Code from your terminal, sign in once with OAuth, and run its prompts as slash commands. +--- + +This page adds the MCP server on its own: the tools, the ready-made prompts and the resources, with nothing else installed. If you also want the skills and subagents, use the [Claude Code plugin](/mcp/clients/claude-code-plugin) instead, and don't add both, or Claude sees every tool twice. + +{/* setup */} + +The command adds the server for you in the current project only (Claude Code's default `local` scope). Add `--scope user` to use it in every project, or `--scope project` to write it to a `.mcp.json` your team commits. + +## Sign in + +Start Claude Code, run `/mcp`, choose `stuntdouble` and select **Authenticate**. Your browser opens on Stunt Double: sign in, check the scopes the consent screen lists, and approve. To sign in from the shell instead, run `claude mcp login stuntdouble`. The [scopes are explained on the overview](/mcp#authentication). + +## Check it works + +- `claude mcp list` shows `stuntdouble` as connected (it says it needs authentication until you sign in). +- In a session, ask: "List my Stunt Double workspaces." +- Type `/` to see the server's prompts, listed as `/stuntdouble:verify_change (MCP)` and so on. `/mcp__stuntdouble__verify_change` runs the same prompt. +- Type `@` to attach a resource such as `@stuntdouble:stuntdouble://guide`, the full tool catalog. + +## Troubleshooting + +- **Signed in to the wrong account, or access revoked:** in `/mcp`, choose **Clear authentication** (or run `claude mcp logout stuntdouble`), then authenticate again. +- **The browser didn't open:** Claude Code prints the sign-in URL. Open it by hand. +- **A tool isn't there:** the connection may not hold the scope that tool needs. Ask Claude to read `stuntdouble://connection`, which lists the scopes it holds and the tools each one unlocks. + +## Next + +- [Skills](/mcp/skills): install task skills alongside the server +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/claude.mdx b/content/mcp-clients/claude.mdx new file mode 100644 index 0000000..64256f3 --- /dev/null +++ b/content/mcp-clients/claude.mdx @@ -0,0 +1,30 @@ +--- +description: Add Stunt Double to Claude on the web, Claude Desktop and the mobile apps as a custom connector, with run results drawn as cards. +--- + +A custom connector gives Claude the Stunt Double tools and prompts in claude.ai, Claude Desktop and the mobile apps. Checklist runs, interview reports and Index reports come back as cards in the conversation. For Claude Code, use the [Claude Code](/mcp/clients/claude-code) page instead. To get the task skills as well, install the [Stunt Double plugin](https://claude.ai/customize/plugins/id/9cd49c97-13c2-4844-bc3d-53ef7956c1ef%40anthropic-plugin-directory) from Claude's plugin directory: it adds this connector plus the skills in one go. + +{/* setup */} + +Newer versions of Claude show Connectors under **Customize** rather than **Settings**; the steps are the same. On a Team or Enterprise plan, an owner adds the connector in **Organization settings**, **Connectors**, and each member then connects to it. For Claude Desktop there is also a one-click extension under **Integrations** in your workspace (see [Connect](/mcp/connect#claude-desktop)). + +## Sign in + +After you add the connector, select **Connect** next to it. A browser window opens on Stunt Double: sign in, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. Connectors you add on the web also work in Claude Desktop and the mobile apps. + +## Check it works + +- In a chat, open the **+** menu, choose **Connectors** and make sure Stunt Double is switched on for this conversation. +- Ask: "List my Stunt Double workspaces." + +## Troubleshooting + +- **Free plan:** Claude allows one custom connector on the Free plan. Remove another to add Stunt Double. +- **Too many tools for one chat:** use the **Search and tools** menu to turn off Stunt Double tools you don't need in that conversation. +- **Disconnect:** remove the connector in Claude's Connectors settings, and revoke it on the Stunt Double side as [Connect](/mcp/connect#revoke-access) describes. + +## Next + +- [Skills](/mcp/skills): task recipes you can add to Claude +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/codex-cli.mdx b/content/mcp-clients/codex-cli.mdx new file mode 100644 index 0000000..fc3bba9 --- /dev/null +++ b/content/mcp-clients/codex-cli.mdx @@ -0,0 +1,31 @@ +--- +description: Add the Stunt Double MCP server to the Codex CLI and sign in with codex mcp login, which also covers the Codex IDE extension and the ChatGPT desktop app. +--- + +This page gives Codex the Stunt Double tools through its MCP config. The Codex CLI, the Codex IDE extension and the ChatGPT desktop app share `~/.codex/config.toml`, so adding the server once covers all three. For the task skills, add them with the skills CLI as [Skills](/mcp/skills) describes. + +{/* setup */} + +To keep the server to one repository, put the same block in `.codex/config.toml` at the project root instead. Codex reads a project config only for projects you trust. + +## Sign in + +`codex mcp login stuntdouble` opens your browser on Stunt Double. Sign in, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. + +## Check it works + +- `codex mcp list` shows `stuntdouble` among your configured servers. +- In the `codex` TUI, run `/mcp` to see the active servers and their tools. +- Ask: "List my Stunt Double workspaces." + +## Troubleshooting + +- **Signing in over SSH or in a container:** the sign-in redirects to a listener on the machine running Codex. Set `mcp_oauth_callback_port` in `config.toml` to choose a fixed port you can forward, or `mcp_oauth_callback_url` for a remote ingress. +- **Access expired or revoked:** run `codex mcp login stuntdouble` again. +- **A tool is missing:** the connection may not hold its scope. Ask Codex to read `stuntdouble://connection`. + +## Next + +- [Skills](/mcp/skills): task recipes that drive the server +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/cursor.mdx b/content/mcp-clients/cursor.mdx new file mode 100644 index 0000000..e105b00 --- /dev/null +++ b/content/mcp-clients/cursor.mdx @@ -0,0 +1,30 @@ +--- +description: Install the Stunt Double plugin in Cursor for the MCP server plus skills, rules and agents, or add the server on its own. +--- + +The Cursor plugin installs the hosted MCP server together with the [skills](/mcp/skills), the [rules](/mcp/rules) and the [agents](/mcp/agents). Add the server on its own (the `mcp.json` block below) only if you want the tools without them. Use one or the other, not both. + +{/* setup */} + +Once Stunt Double is listed in the Cursor marketplace, install the plugin from **Customize** in Cursor's sidebar (find Stunt Double, choose **Install** and pick a scope) or from the marketplace website. On a Teams or Enterprise plan, an admin can add the repository as a team marketplace instead: **Dashboard**, **Plugins & MCPs**, **Team Marketplaces**, **Add Marketplace**, **Import from Repo**, then paste `https://github.com/stunt-double/stuntdouble-mcp`. + +## Sign in + +Cursor signs in with OAuth and PKCE. The first time Cursor uses a Stunt Double tool, your browser opens on Stunt Double: sign in, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. Stunt Double accepts whichever callback Cursor registers, so there's nothing to configure. + +## Check it works + +- Open **Customize** and check the Stunt Double server is listed with its toggle on. +- Ask the agent: "List my Stunt Double workspaces." Cursor asks for approval before it calls an MCP tool, unless you've allowed it. + +## Troubleshooting + +- **Sign-in or connection errors:** open the Output panel (Cmd+Shift+U on macOS), choose **MCP Logs** from the dropdown, and read the Stunt Double entries. +- **The server doesn't appear in chat:** a disabled server doesn't load. Turn it back on in **Customize**. +- **Tools show up twice:** you have both the plugin and a `mcp.json` entry. Remove one. + +## Next + +- [Cursor rules](/mcp/rules): what the plugin's rules tell the agent +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/gemini-cli.mdx b/content/mcp-clients/gemini-cli.mdx new file mode 100644 index 0000000..798abd5 --- /dev/null +++ b/content/mcp-clients/gemini-cli.mdx @@ -0,0 +1,31 @@ +--- +description: Add the Stunt Double MCP server to Gemini CLI over Streamable HTTP and sign in with /mcp auth. +--- + +This page gives Gemini CLI the Stunt Double tools and prompts. Gemini CLI also reads `SKILL.md` files, so you can add the task [skills](/mcp/skills) alongside. + +{/* setup */} + +`gemini mcp add` writes to the project's `.gemini/settings.json` by default. Add `--scope user` to write to `~/.gemini/settings.json` and use the server in every project. If you edit the file by hand, keep the key as `httpUrl`: Gemini CLI reads `url` as an SSE endpoint, which this server doesn't serve. + +## Sign in + +Gemini CLI notices that the server needs OAuth and finds its sign-in endpoints itself. Run `/mcp auth stuntdouble`, sign in to Stunt Double in the browser that opens, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. + +## Check it works + +- `/mcp` (or `gemini mcp list` from the shell) shows `stuntdouble` as connected, with its tools. +- Ask: "List my Stunt Double workspaces." +- The server's prompts run as slash commands, for example `/verify_change`. + +## Troubleshooting + +- **Signing in over SSH, in a container or anywhere without a browser:** Gemini CLI's OAuth needs a local browser, so sign in on a machine that has one. +- **Start over:** run `/mcp auth stuntdouble` again. Gemini CLI keeps its tokens in `~/.gemini/mcp-oauth-tokens.json`. +- **The server shows as disconnected:** check it is enabled (`/mcp enable stuntdouble`). + +## Next + +- [Skills](/mcp/skills): task recipes that drive the server +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/opencode.mdx b/content/mcp-clients/opencode.mdx new file mode 100644 index 0000000..5ab5070 --- /dev/null +++ b/content/mcp-clients/opencode.mdx @@ -0,0 +1,30 @@ +--- +description: Add the Stunt Double MCP server to OpenCode as a remote server and sign in with opencode mcp auth. +--- + +This page gives OpenCode the Stunt Double tools. OpenCode also reads `SKILL.md` files, so you can add the task [skills](/mcp/skills) alongside. + +{/* setup */} + +The project `opencode.json` and the global `~/.config/opencode/opencode.json` are merged, so a server in either is available. OpenCode prefixes each tool with the server name, so the tools show up as `stuntdouble_list_workspaces` and so on. + +## Sign in + +OpenCode starts the OAuth flow by itself the first time the server asks for it. To sign in up front, run `opencode mcp auth stuntdouble`, sign in to Stunt Double in the browser that opens, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. + +## Check it works + +- `opencode mcp list` (or `opencode mcp auth list`) shows `stuntdouble` and whether it is signed in. +- Ask: "List my Stunt Double workspaces." + +## Troubleshooting + +- **Signed in to the wrong account, or access revoked:** run `opencode mcp logout stuntdouble`, then `opencode mcp auth stuntdouble`. Tokens live in `~/.local/share/opencode/mcp-auth.json`. +- **The tools don't load:** OpenCode waits 5 seconds for a server's tool list by default. Raise it with `"timeout"` (in milliseconds) in the server's block. +- **Too many tools in context:** turn off the ones you don't need with a glob in your config's `tools` section, such as `"stuntdouble_*interview*": false`, or connect to the on-demand endpoint in [Connect](/mcp/connect#endpoints). + +## Next + +- [Skills](/mcp/skills): task recipes that drive the server +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/other-clients.mdx b/content/mcp-clients/other-clients.mdx new file mode 100644 index 0000000..cde3d7a --- /dev/null +++ b/content/mcp-clients/other-clients.mdx @@ -0,0 +1,31 @@ +--- +description: Connect any MCP client to Stunt Double over Streamable HTTP with OAuth, or bridge a stdio-only client with mcp-remote. +--- + +Use this page for a client without its own page here. What you need from the client is Streamable HTTP and OAuth 2.1 with dynamic client registration; a client that only launches local (stdio) servers can still connect through `mcp-remote`. + +{/* setup */} + +The block above is the common `mcpServers` shape; put it wherever your client keeps its MCP servers, and restart the client. + +## Sign in + +A client that speaks OAuth discovers Stunt Double's sign-in endpoints from the server, registers itself, and opens your browser. With `mcp-remote`, the bridge does this for the client the first time it starts. Either way, sign in, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. + +## Check it works + +- Ask: "List my Stunt Double workspaces." An answer with your workspaces means you're signed in. +- If your client shows MCP resources, open `stuntdouble://connection` to see the scopes the connection holds. + +## Troubleshooting + +- **mcp-remote needs Node 18 or later.** Desktop apps use the system Node, not one from a version manager in your shell. +- **Start the sign-in over:** `mcp-remote` stores its tokens in `~/.mcp-auth`. Delete that folder and restart the client. Do the same after a "Token exchange failed" error. +- **Port conflict during sign-in:** `mcp-remote` listens for the OAuth redirect on a local port. Pass a different port as the argument after the server URL. +- **Too many tools for the client:** connect to the on-demand endpoint in [Connect](/mcp/connect#endpoints) instead. + +## Next + +- [Skills](/mcp/skills): task recipes for any agent that reads `SKILL.md` files +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/vs-code.mdx b/content/mcp-clients/vs-code.mdx new file mode 100644 index 0000000..6774351 --- /dev/null +++ b/content/mcp-clients/vs-code.mdx @@ -0,0 +1,33 @@ +--- +description: Add the Stunt Double MCP server to VS Code for GitHub Copilot Chat, sign in with OAuth and use its tools in agent sessions. +--- + +This page gives GitHub Copilot Chat in VS Code the Stunt Double tools, prompts and resources. If you use Claude Code inside VS Code, follow the [Claude Code](/mcp/clients/claude-code) page instead: it has its own MCP config. + +{/* setup */} + +A server in `.vscode/mcp.json` belongs to that workspace and can be shared through version control. One in your user configuration is available in every workspace. + +## Sign in + +Start the server from the Command Palette with **MCP: List Servers**, choose `stuntdouble` and select **Start Server** (VS Code can also start it for you when you send a chat message). VS Code opens your browser on Stunt Double: sign in, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. + +## Check it works + +- In Copilot Chat, open **Configure Tools** in the chat input and check the Stunt Double tools are selected. +- Ask: "List my Stunt Double workspaces." +- Type `/stuntdouble.` to see the server's prompts, such as `/stuntdouble.verify_change`. +- Attach a resource from **Add Context**, **MCP Resources**, for example the `stuntdouble://guide` catalog. + +## Troubleshooting + +- **Nothing happens, or sign-in fails:** in **MCP: List Servers**, choose `stuntdouble` and **Show Output** to read the server's log, then **Restart Server**. +- **Copilot doesn't call the tools:** confirm the server is running and its tools are selected in **Configure Tools**. Agents only see tools that are turned on. +- **Server not allowed:** your organization can restrict MCP servers to an allowlist. Ask your administrator to add it. +- **A tool is missing:** the connection may not hold its scope. Ask Copilot to read `stuntdouble://connection`. + +## Next + +- [Skills](/mcp/skills): task recipes that drive the server +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource diff --git a/content/mcp-clients/windsurf.mdx b/content/mcp-clients/windsurf.mdx new file mode 100644 index 0000000..80c4af2 --- /dev/null +++ b/content/mcp-clients/windsurf.mdx @@ -0,0 +1,30 @@ +--- +description: Add the Stunt Double MCP server to Windsurf (now Devin Desktop) for the Cascade agent, and keep within Cascade's tool limit. +--- + +This page gives the Cascade agent in Windsurf the Stunt Double tools. Windsurf has been renamed Devin Desktop; its MCP docs now live at [docs.devin.ai](https://docs.devin.ai/desktop/cascade/mcp), and the config below is the one Cascade reads. + +{/* setup */} + +Windsurf takes `serverUrl` for a remote server. Save the file and restart Windsurf so Cascade picks the server up. + +## Sign in + +Windsurf supports OAuth for remote servers. When it connects to Stunt Double, your browser opens on the Stunt Double sign-in page: sign in, review the scopes the consent screen lists, and approve. The [overview](/mcp#authentication) explains each scope. + +## Check it works + +- Open the **...** menu in the Cascade panel and look under **MCPs**: Stunt Double should be listed with a count of its enabled tools and its toggle on. +- Ask Cascade: "List my Stunt Double workspaces." + +## Troubleshooting + +- **Tools missing because of the 100-tool limit:** Cascade can use at most 100 tools across all your servers at once, and Stunt Double brings dozens. Turn off the ones you don't need with a `disabledTools` list in the server's block, or connect to the on-demand endpoint in [Connect](/mcp/connect#endpoints), which lists only a few core tools and loads the rest as a task needs them. +- **Server blocked on a team plan:** once a team admin allowlists any MCP server, the rest are blocked. The server ID they allowlist must match the key in your config exactly (`stuntdouble`). +- **Enterprise:** MCP may be off until you turn it on in Windsurf's settings. + +## Next + +- [Automate from a conversation](/tutorials/automate-with-mcp): what to ask for once you're connected +- [Tools](/mcp/tools): every tool, prompt and resource +- [Connect](/mcp/connect): endpoints, and revoking access diff --git a/next.config.ts b/next.config.ts index 22dedaf..d3ed813 100644 --- a/next.config.ts +++ b/next.config.ts @@ -10,7 +10,8 @@ const nextConfig: NextConfig = { { source: '/reference/stuntdouble-mcp', destination: '/mcp', permanent: true }, { source: '/reference/stuntkit', destination: '/stuntkit', permanent: true }, { source: '/api/mcp', destination: '/mcp', permanent: true }, - { source: '/stuntkit/spelling', destination: '/stuntkit/americanize', permanent: true }, + { source: '/stuntkit/spelling', destination: '/stuntkit/localeizer', permanent: true }, + { source: '/stuntkit/americanize', destination: '/stuntkit/localeizer', permanent: true }, ]; }, }; diff --git a/scripts/generate.mjs b/scripts/generate.mjs index 930b081..a8356f6 100644 --- a/scripts/generate.mjs +++ b/scripts/generate.mjs @@ -38,6 +38,15 @@ const CLIENT_ICONS = { 'other-clients': 'mcp', }; +/** + * Hand-written notes for each client page, by slug: sign-in, checks and + * troubleshooting the README leaves out. The README's setup snippet goes where + * a note has the SETUP line, or first when it has none. + */ +const CLIENT_NOTES_DIR = join(ROOT, 'content/mcp-clients'); +const SETUP = '{/* setup */}'; +const CLIENT_NOTES_URL = 'https://github.com/stunt-double/docs/blob/main/content/mcp-clients'; + /** Page title and description for each source's overview. */ const PAGES = {}; @@ -174,8 +183,9 @@ function takeTitle(body) { return m ? { title: m[1].trim(), body: body.slice(m[0].length).trim() } : { title: null, body: body.trim() }; } -function editLink({ repo, tag }, paths) { +function editLink({ repo, tag }, paths, extra = []) { const url = (p) => `https://github.com/${repo}/blob/${tag}/${p}`; + if (extra.length) return `\n\n---\n\nEdit on GitHub: ${[...paths.map((p) => `[${basename(p)}](${url(p)})`), ...extra].join(', ')}\n`; return paths.length === 1 ? `\n\n---\n\n[Edit on GitHub](${url(paths[0])})\n` : `\n\n---\n\nEdit on GitHub: ${paths.map((p) => `[${basename(p)}](${url(p)})`).join(', ')}\n`; @@ -188,7 +198,7 @@ function editLink({ repo, tag }, paths) { */ export function mcpPages(src, at) { const mdx = (text, dir) => readmeToMdx(clean(text), { ...at, dir }); - const page = (data, body, paths) => clean(frontmatter(data) + body + editLink(at, paths)); + const page = (data, body, paths, extra) => clean(frontmatter(data) + body + editLink(at, paths, extra)); const out = {}; const [pre, ...sections] = splitSections(src.readme, 2); @@ -214,14 +224,18 @@ export function mcpPages(src, at) { ); for (const c of clients) { + const notes = parseFrontmatter(src.clientNotes?.[c.slug] ?? ''); + const setup = `## Add the server\n\n${mdx(c.body)}`; + const body = notes.body.includes(SETUP) ? notes.body.replace(SETUP, () => setup) : `${setup}\n\n${notes.body}`; out[`clients/${c.slug}.mdx`] = page( { title: c.heading.replace(/\s*\(.*\)$/, ''), icon: CLIENT_ICONS[c.slug], - description: `Connect ${c.heading} to the Stunt Double MCP server.`, + description: notes.data.description ?? `Connect ${c.heading} to the Stunt Double MCP server.`, }, - mdx(c.body), - ['README.md'] + body.trim(), + ['README.md'], + src.clientNotes?.[c.slug] ? [`[${c.slug}.mdx](${CLIENT_NOTES_URL}/${c.slug}.mdx)`] : [] ); } out['clients/meta.json'] = `${JSON.stringify({ title: 'Clients', icon: 'AppWindow', pages: clients.map((c) => c.slug) }, null, 2)}\n`; @@ -289,6 +303,15 @@ function readDirFiles(dir, sub, pick) { .map((file) => ({ file: `${sub}/${file}`, text: readFileSync(join(path, file), 'utf8') })); } +function readClientNotes() { + if (!existsSync(CLIENT_NOTES_DIR)) return {}; + return Object.fromEntries( + readdirSync(CLIENT_NOTES_DIR) + .filter((n) => n.endsWith('.mdx')) + .map((n) => [basename(n, '.mdx'), readFileSync(join(CLIENT_NOTES_DIR, n), 'utf8')]) + ); +} + function writeMcp(at) { const dir = join(SOURCES_DIR, MCP); const pages = mcpPages( @@ -297,6 +320,7 @@ function writeMcp(at) { skills: readDirFiles(dir, 'skills', (n) => (existsSync(join(dir, 'skills', n, 'SKILL.md')) ? `${n}/SKILL.md` : null)), rules: readDirFiles(dir, 'rules', (n) => (n.endsWith('.mdc') ? n : null)), agents: readDirFiles(dir, 'agents', (n) => (n.endsWith('.md') ? n : null)), + clientNotes: readClientNotes(), }, at ); diff --git a/scripts/generate.test.mjs b/scripts/generate.test.mjs index 8d35356..ce5b296 100644 --- a/scripts/generate.test.mjs +++ b/scripts/generate.test.mjs @@ -91,6 +91,7 @@ test('mcpPages splits the README by client and ends every page with an edit link skills: [{ file: 'skills/x/SKILL.md', text: '---\nname: x\ndescription: Do x \u2014 well\n---\n\n# Do X\n\nBody.' }], rules: [{ file: 'rules/r.mdc', text: '---\ndescription: A rule.\nalwaysApply: true\n---\n\nr:' }], agents: [{ file: 'agents/a.md', text: '---\nname: a\ndescription: An agent\n---\n\n# A\n\n## Use\n' }], + clientNotes: { 'claude-code': '---\ndescription: Use it in Claude Code.\n---\n\nIntro.\n\n{/* setup */}\n\n## Sign in\n\nRun /mcp.\n' }, }, at ); @@ -109,7 +110,9 @@ test('mcpPages splits the README by client and ends every page with an edit link assert.match(pages['index.mdx'], /description: "Tagline\."/); assert.doesNotMatch(pages['index.mdx'], /Plugin internals|Internal\./); assert.match(pages['clients/cursor-windsurf.mdx'], /title: "Cursor and Windsurf"/); - assert.match(pages['clients/claude-code.mdx'], /title: "Claude Code"\nicon: "claude-code"\n/); + assert.match(pages['clients/claude-code.mdx'], /title: "Claude Code"\nicon: "claude-code"\ndescription: "Use it in Claude Code\."/); + assert.match(pages['clients/claude-code.mdx'], /Intro\.\n\n## Add the server\n\n```bash[\s\S]*```\n\n## Sign in/); + assert.match(pages['clients/cursor-windsurf.mdx'], /^## Add the server\n\nJSON\./m); assert.doesNotMatch(pages['clients/cursor-windsurf.mdx'], /icon:/); assert.match(pages['skills/x.mdx'], /title: "Do X"\ndescription: "Do x: well"/); assert.doesNotMatch(pages['skills/index.mdx'], /\| a \|/); diff --git a/src/lib/links.test.ts b/src/lib/links.test.ts index aa8ecf4..0a063cd 100644 --- a/src/lib/links.test.ts +++ b/src/lib/links.test.ts @@ -10,6 +10,7 @@ test('maps old docs links to docs paths and other root links to marketing', () = assert.equal(docsHref('/integrations'), '/integrations'); assert.equal(docsHref('/mcp/connect#auth'), '/mcp/connect#auth'); assert.equal(docsHref('/tutorials/self-hosted-worker'), '/tutorials/self-hosted-worker'); + assert.equal(docsHref('/index-ranking/improve-your-score'), '/index-ranking/improve-your-score'); assert.equal(docsHref('/mcpx'), 'https://www.stuntdouble.io/mcpx'); assert.equal(docsHref('/pricing'), 'https://www.stuntdouble.io/pricing'); assert.equal(docsHref('/support'), 'https://www.stuntdouble.io/support'); diff --git a/src/lib/links.ts b/src/lib/links.ts index 63d6edf..30cf886 100644 --- a/src/lib/links.ts +++ b/src/lib/links.ts @@ -9,7 +9,7 @@ export const MARKETING_ORIGIN = 'https://www.stuntdouble.io'; * the marketing site. */ const DOCS_SECTIONS = - /^\/(guides|integrations|mcp|tutorials|concepts|getting-started|api|stuntkit|reference)(?=$|[/#?])/; + /^\/(guides|integrations|mcp|tutorials|concepts|getting-started|api|stuntkit|index-ranking|reference)(?=$|[/#?])/; export function docsHref(href: string): string { if (!href.startsWith('/') || href.startsWith('//')) return href;