Extract a reusable skill from real sessions with an LLM, review it, and install it into an agent's skills directory.
A session where the agent got something right is a pattern worth keeping. The
skills cassette turns selected sessions into a SKILL.md: it drafts one
candidate per session, has the evaluator score them, synthesizes the best into
a new private revision, and leaves publishing to you.
There is no built-in skill verb. tapesctl builds the cassettes skills
commands from the cassette’s own OpenAPI document at invocation time, so the
surface below is whatever the server you point at serves; --help on any of
them is authoritative.
Before you start
Section titled “Before you start”A server with the skills cassette mounted and at least one captured session. The Docker Compose guide brings up that stack; confirm the cassette is there:
tapesctl cassettestapesctl cassettes skills --helpGeneration calls an LLM through the evaluator, configured on the server side.
Nothing in this guide needs a provider key on your machine. Building the
request body below uses jq; any JSON editor
works as well.
Name the skill
Section titled “Name the skill”A skill is a stable identity with a slug. Resolving one is idempotent: the same slug returns the same id.
tapesctl cassettes skills resolve-skill-identity --body '{"slug":"diagnose-flaky-tests"}'{ "skillId": "2c9f7a1e-…", "slug": "diagnose-flaky-tests"}Keep the skillId; every other command takes it as its first positional.
Pick the sessions
Section titled “Pick the sessions”Search prints session ids in a pipe-friendly form, and the generation body
takes them as selectedSessionIds. Build the body once, in a file:
tapesctl search "flaky tests" --quiet --top 3 \ | jq -R . | jq -s '{ input: { name: "Diagnose flaky tests", description: "Turn session evidence into a reusable workflow.", type: "workflow" }, authorContext: "Prefer reproducible evidence.", selectedSessionIds: . }' > generation.jsoninput.type is workflow, domain-knowledge, or prompt-template. The
session ids are tapes session ids, the ones sessions list shows, not the
harness id start prints on exit.
Generate
Section titled “Generate”tapesctl cassettes skills create-skill-generation <skill-id> --body @generation.jsonThe server answers 202 with a generation id once the inputs are durable.
Generation runs in the background; read its progress with the id:
tapesctl cassettes skills get-skill-generation <skill-id> <generation-id>Status moves through queued, generating_candidates,
evaluating_candidates, and synthesizing to completed, failed, or
canceled. A completed generation names a resultRevisionId: one new
private revision of the skill. Nothing has been published yet.
Review and publish
Section titled “Review and publish”Read the revision before anyone else can see it; a session captured in one project can carry that project’s assumptions:
tapesctl cassettes skills get-skill-revision <skill-id> <revision-id>Publishing is two separate steps, and the second implies the first:
tapesctl cassettes skills set-skill-revision-visibility <skill-id> <revision-id> --body '{"isPublic":true}'tapesctl cassettes skills set-skill-latest-revision <skill-id> --body '{"revisionId":"<revision-id>"}'Once a revision is public, the skill’s effective SKILL.md is a download:
tapesctl cassettes skills get-skill-markdown <skill-id> > SKILL.mdCopy it into whichever skills directory your agent reads, for example
~/.claude/skills/diagnose-flaky-tests/SKILL.md. Installing is a file copy;
nothing on the server changes.
Next steps
Section titled “Next steps”- Search captured sessions by meaning — find the
sessions worth extracting;
--quietoutput pipes straight into the generation body. - Skills cassette API — every route, the revision and visibility model, and the generation statuses.