Skills and commands
The nine Fixtureframe skills, their agent prompts, and the CLI commands they use.
Each skill is invoked as a slash command in hosts that support them, or read from
.fixtureframe/skills/ by hosts that do not. They share the CLI's own vocabulary: /ff-script
wraps ff script.
For a complete command-by-command example, follow From sign-in to a published flow.
A skill is not its command. /ff-script interviews for beats, writes the brief, generates the script and lints it
— and only then proposes ff script. The skill is the workflow around the command.
You can just ask
The slash commands are a shortcut, not the interface. Every skill below is reachable by saying what you want in a sentence, and the agent picks the right one.
| Instead of | You can say |
|---|---|
/ff-suggest | "What walkthroughs are missing for the app in ~/code/acme?" |
/ff-context | "Create APP_CONTEXT.md from the staging survey and this product's source." |
/ff-adapter | "Check whether sign-in works against staging." |
/ff-script | "Turn e2e/team.spec.ts into a customer-facing walkthrough." |
/ff-diagnose | "Run 4f2a failed — what broke, and can you fix it?" |
/ff-deck | "Narrate board-update.pptx for internal review, no video." |
Prose is often the better choice, for a practical reason: in most hosts the command menu runs the highlighted entry when you press Enter, so typing arguments after it takes a deliberate Tab first. A sentence carries the same information with nothing to remember — and it can carry things no flag expresses, like which folder is the product and which is the workspace.
A worked conversation
You — Have a look at the repo in
~/code/acmeand tell me what we should be documenting.
The agent runs ff suggest against that directory, reads what the command could not, and comes back
with a gap analysis rather than a list. Then it asks the one thing it must not assume:
Agent — 22 candidates. Where should the catalogue live: the workspace's
.fixtureframe/CATALOG.md, ordocs/flows/in the repo so it is reviewed as a diff?
You — In the repo. Start with the three a new customer hits first.
Agent — Accepted those three. There is no saved session yet. Run
ff session init --environment stagingin your terminal, sign in to the app, then press Enter in the terminal while the browser is still open.
You — Done. Use that session for the walkthroughs.
Agent — The survey now reaches the app. I will use
/ff-contextto organize the evidence, identify missing detail screens, and propose coverage for the first walkthrough.
That last exchange is the shape to expect throughout: it states what it found, names the evidence, and asks before doing the thing that costs something or leaves state behind.
Conversing changes nothing about the guarantees. The agent still runs the same commands, still refuses to invent beats, and keeps captures, vendor calls and publication within the agreed authorization.
Anything you type after a slash command reaches the skill too, so
/ff-suggest ~/code/acme --catalog docs/flows/CATALOG.md and the sentence above do the same work.
Press Tab to complete a command without running it; Enter runs it as it stands.
CLI switches in that text are instructions for the agent to interpret, not automatically forwarded arguments. See Passing CLI switches through an agent prompt for exact-command examples and the different saved-session defaults of recording, scripting and replay.
/ff — the router
Picks the front door and confirms the brief before anything runs. Start here if you are not sure which of the others you want.
It uses the context and answers already supplied, asks only consequential missing questions, and proposes the viewer outcome, visible proof and beats for agreement.
/ff-context — reusable app knowledge
Creates or updates .fixtureframe/APP_CONTEXT.md from the environment, cached survey, optional
source/docs and intended users. It connects navigation and controls to user jobs, representative
detail screens and feature relationships, and records missing evidence or demo-data requirements.
/ff-context Use staging and the cached survey to create APP_CONTEXT.md for new
operators. The source is C:/work/acme-app. Keep uncertain behavior explicit.The file is agent-readable Markdown, not CLI configuration. There is no terminal ff context
command, and app context does not replace a particular flow's confirmed brief.
See App context for the optional template.
/ff-suggest → ff suggest
Building a catalogue of what your product does that nothing documents.
ff suggest gathers deterministically from two places: the end-to-end tests in your repository, and
the screens in the cached survey — minus the flows the control plane already publishes, plus the
decisions in an existing catalogue. The skill ranks, names and writes.
A test is the strongest evidence there is, because somebody drove that path and asserted the result.
A control the survey found is proven reachable, which is weaker and is not nothing — so the output
ranks them apart rather than dropping one. Run ff survey first: without it, a product with no
browser tests has nothing to gather from.
It produces a gap analysis, not an inventory. Four classes, and the second is the one people act on:
| Documented, matches the product | nothing to do |
| Documented, but the product moved | the article describes UI that no longer exists |
| Undocumented | a new flow |
| Documented, no flow behind it | a baseline to replay against |
Name a persona — "for a sales engineer", "for support" — to change what it ranks by and which outputs it suggests. That is something you tell the agent, not a flag the CLI takes. Persona never changes what is true, and never lowers the governance bar: prospect-facing is customer-facing.
Two directories matter here and they are usually different: the product's code, which is read,
and the workspace holding .fixtureframe, which supplies the survey and the environment. Say
which is which — "the app is in ~/code/acme, the workspace is here" — and the agent passes
--source and --directory accordingly.
Rejections are durable. A candidate you delete stays deleted, and entries you wrote by hand are left entirely alone.
/ff-script → ff script
The main loop: coverage → brief → script → checks → local capture → artifact review and replay → publish.
The agent reads app context, distinguishes an orientation from a task walkthrough, and selects
enough representative proof to answer the viewer's questions. Ten sections can be ten chapters with
different amounts of depth. Capture with --session --local-only when using saved authentication
and reviewing before publication. A matched narration pattern is not proof that a question was answered.
The agent writes a Playwright script that drives your product. The recorder produces the flow. Four things the format enforces, each paid for once:
- the browser is already open at the base URL — a relative
page.goto("/")kills the walk on line one pause()around anything unfilmed, sign-in above all: a recorded password travels with the flowvalue("name")rather than a literal, so the flow keeps{{name}}and the credential stays out- wait for a heading, never a timeout
With saved-session authentication, the script does not need to repeat login. Inspect content readiness as well as headings, and review the generated flow's actual replay artifacts: arbitrary Playwright waits and scrolling do not automatically survive recording.
/ff-record → ff record
For a walk easier shown than written. The one thing the agent cannot do itself: a person uses the product while the recorder watches.
The agent's work is before and after — confirm the beats and declare the outputs first (outputs are decided at record time, because they change what has to be captured), then write the narration against the recorded steps and report anything that matched nothing.
/ff-deck → ff deck
A .pptx, .pdf or Google Slides deck into a narrated draft. One step per slide, speaker notes
kept as narration word for word. Slides without notes are narrated in a second pass.
The skill will tell you something you may not want to hear: a deck import is a static flow. It re-composes on demand, so it cannot go stale — and cannot be refreshed either. If you want content that tracks the product, you want a recorded or scripted flow.
/ff-adapter → ff adapter
How your product signs in, and when it is ready to capture.
For interactive sign-in, start with ff session init; an adapter is optional. Use this skill when
you deliberately need an unattended authentication method or must diagnose an existing adapter.
It starts by checking what you already have, because everything downstream is blocked behind sign-in:
ff adapter check form-login --url https://app.example.comExit 0 and sign-in works. Exit 2 and either a credential is missing — reported by name, before a
browser is launched — or a stage threw, in which case the page as it stood is saved to
.fixtureframe/discovery/. The agent reads that frame before theorising, and asks before writing
an adapter: the frame often shows a rejected password or the wrong URL rather than a login it
cannot drive.
So the next step is usually deciding not to write one. An application with a recordable login needs no adapter; they exist for SSO, MFA, OAuth redirects, magic links and token exchange.
Credentials never pass through the agent. The adapter declares them by name and resolves them from the environment at call time, so what the agent sees is a stage, a message and a frame — never a value.
The best evidence is your own e2e sign-in helper — that is the adapter in another form. And the half
people get wrong is waitForReady: a capture taken during hydration is a screenshot of a skeleton,
published.
/ff-diagnose → ff diagnose
Reading a failed run into something actionable. The counts are the diagnosis:
| What you see | What it means | The fix |
|---|---|---|
role matched 3 | the name now fits several controls | scope it, or match exactly |
everything matched 0 | screen never reached, or control renamed | the failure frame settles which |
css matched 1, semantics 0 | role or accessible name moved | update the semantic locator |
Whose repair it is depends on where the source lives. A scripted flow is the agent's — the .mjs
is in your repository. A recorded flow is not: repairing it needs the lint rules, the last-good
version and the run history, so the diagnosis is handed back and Studio proposes the fix.
/ff-cli
Setup, layout, costs and exit codes. What is committed and what is gitignored, which environment variables the CLI reads, and the exit-code convention:
0 | clean |
2 | the thing being checked has problems |
1 | the command did not run |
The distinction between 2 and 1 matters: a gate in front of a capture has to tell "this walk is wrong" from "this command did not run", and of the two, the one never to wave through is the first.