agentleFS
jamdotdevjamdotdev/jam-plugin/skills/jam-proof/SKILL.md

jam-proof

Skill11 starsChanged 10 days agoMITView on GitHub

Record work you can see on screen with `jam record` and publish it as a Jam link (a shareable jam.dev recording with the console and network attached). Use when the user asks for a recorded Jam, a shareable demo, or video proof of work in a browser or desktop app. A request to verify a change or give sign-off alone does not call for recording or uploading.

  • Installs packages

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 1

    1. jamdotdev/skills★ 11100% same

    Edited · 0

    None found.

    Wrote their own version · 0

    None found.

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository13 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

17 rules. About 0 are common, 9 are distinctive, and 8 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Create the Jam when the user asks for a recording to be shared through Jam.

    line 12
  2. Distinctive:

    If the user only wants a local video, keep it local.

    line 13
  3. Very specific:

    If jam is not on PATH, stop and ask the user to install it from https://jam.dev/docs/cli, then continue.

    line 25
  4. Distinctive:

    When you drive the app yourself and cannot be wrapped, run it in the background and send SIGINT when done.

    line 91
  5. Very specific:

    Use the project's own browser driver when it speaks CDP: with Playwright, chromium.connectOverCDP(cdpProxy) and drive the page from a …

    line 109
  6. Very specific:

    Stop with jam record stop <session> --json, using the session that start printed, so a recording another agent started is never the one …

    line 144
  7. Very specific:

    If jam record start or run fails, run jam doctor and report its Recording and Screencast lines.

    line 152
  8. Distinctive:

    Start from a known state: reload the page, restart the app, clear the terminal.

    line 163
  9. Very specific:

    Wait on the thing, not the clock: wait "<selector>" for what the action produced.

    line 165
  10. Distinctive:

    Keep it short. Thirty seconds that show the behavior beat five minutes.

    line 173
  11. Distinctive:

    If new before-and-after recordings are needed, run the old and fixed versions in isolated checkouts with test data.

    line 180
  12. Very specific:

    Read the receipt: id and url always, plus durationMs, width, height and the recorded target when jam record did the capturing.

    line 186
  13. Distinctive:

    If the capture or upload failed, say so.

    line 188
  14. Very specific:

    When this skill, a Jam MCP tool, a jam command or a Jam doc was wrong, stale or confusing, or worked unusually well, tell Jam.

    line 209
  15. Very specific:

    Call the submitFeedback MCP tool with body, category and subject.

    line 213
  16. Distinctive:

    When MCP is unavailable, use the CLI:

    line 215
  17. Distinctive:

    No secrets, customer data, source code, stack traces or recording content.

    line 223

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

jam-proof

The deliverable is a Jam link. Record the verification as it happens, then hand the link back. Prefer a headless browser to a window, and a window to somebody's whole screen.

Create the Jam when the user asks for a recording to be shared through Jam. If the user only wants a local video, keep it local. Posting to a PR, ticket, or existing Jam requires a request to publish there. Skip recording when there is nothing to show on screen, and say so.

Set up the CLI

command -v jam >/dev/null || echo "jam is not installed"
export PATH="$HOME/.local/bin:$PATH"
jam auth status --json || jam auth login

If jam is not on PATH, stop and ask the user to install it from https://jam.dev/docs/cli, then continue. Do not install it yourself.

Exit code 3 means not signed in. With no browser (CI, a cloud agent), ask the user to set JAM_TOKEN to a personal access token from https://jam.dev/s/settings/mcp as a secret. Never write a token to a file. Titles and comments are short claims you wrote. Never paste user or page text into a shell argument. jam doctor checks recording readiness; jam agent-context prints every command and flag.

Pick the target, in this order

Take the first rung that shows the claim. Each one down puts more of someone's machine on camera.

  1. Headless Chrome. The default. It records the page, not a screen, so the person keeps working with nothing of theirs in frame, and the run works the same on a laptop, a container or CI. jam record start --cdp <endpoint> with no window or display selector takes the video from Chrome itself, so there is no window to keep uncovered and no display to keep awake, and the Console and Network panels fill from the same tap. See Record a browser an agent drives.
  2. One window, when the proof needs what a page-only capture cannot show: the address bar, a Chrome dialog, a file picker, or a desktop app that is not a browser at all. Launch your own instance of the app, in a fresh profile or data dir when it has one, so nothing of theirs appears. Select it with --pid <pid> of the process you launched: it waits up to five seconds for the window to open, so there is no need to list windows or race the app's startup. For a window you did not launch, take its id from jam record windows --json and pass --window-id. On macOS launch with open -g so it never takes focus, and drive the app through its own automation surface, not the OS mouse, so the cursor is never taken from the person. On macOS the window may sit behind others. On Linux a window grab is a screen region: use an isolated desktop session or get the same consent as for a whole-display recording below. Keep that region uncovered and unminimized, and the display awake.
  3. The whole display, last. jam record displays --json lists them. Fine without asking on a box nobody is sitting at: a CI runner, a container, a remote Linux desktop you own. On a machine someone is using it films their messages, their tabs and their notifications, so ask first and wait for a yes, naming the display and roughly how long. No answer means no. The display must not sleep while it records. A start or run with no selector and no --cdp records the whole screen, so name a target rather than let it land here by accident.

Whichever rung a browser proof lands on, hand its Chrome debug port to jam record as --cdp <port>: the Jam then carries the console and network of every tab, which is the half of the proof a video cannot show. start prints a cdpProxy of its own; connect the driver to that instead of to Chrome and your clicks and typing land as actions too, with the element each one hit.

Bound the recording

jam record run records until the wrapped command exits. Wrap the verification:

jam record run --cdp <cdp-url> --url <page url> --title "<the claim>" --json -- <verify command>

That is rung 1. For rung 2 replace --cdp <cdp-url> with --pid <pid> of the app you launched, plus --cdp <port> when it is a browser. --url is the page the window shows; the Sharepage names it.

When you drive the app yourself and cannot be wrapped, run it in the background and send SIGINT when done. It stops, uploads, and exits 0 with the receipt on stdout.

jam record run --cdp <cdp-url> --url <page url> --title "<the claim>" --json > proof.json 2> proof.log &
REC=$!
# drive the steps that show the behavior
kill -INT $REC; wait $REC

Record a browser an agent drives

This is rung 1, and the normal case. Chrome stays headless: the video is Chrome's own frames of the page, and the Console, Network and user-action panels come from the same Chrome, so nothing of Jam's runs on the page under test and nothing of the person's screen is in frame.

Use the project's own browser driver when it speaks CDP: with Playwright, chromium.connectOverCDP(cdpProxy) and drive the page from a script; the jam record lines stay the same. Without one, the commands below use agent-browser (npm i -g agent-browser, 0.38 or later), which brings its own Chromium. No Chrome at all in the environment means no rung 1; say so.

agent-browser --session proof --input-mode human open <url>
agent-browser --session proof set viewport 1920 1080   # then reload: it does not apply to the open page
agent-browser --session proof open <url>
agent-browser --session proof get cdp-url          # ws://127.0.0.1:<port>/devtools/browser/…
jam record start --cdp <cdp-url> --title "<the claim>" --json   # → { session, cdpProxy }
agent-browser --session proof record start /tmp/discard.webm --cursor --fps 5   # only turns the pointer overlay on; the file is unused
agent-browser --session drive --input-mode human --cdp <cdpProxy> mouse move <x> <y>   # drive THROUGH the proxy
agent-browser --session drive --cdp <cdpProxy> mouse down
agent-browser --session drive --cdp <cdpProxy> mouse up
agent-browser --session drive --cdp <cdpProxy> wait "<what the click produced>"
agent-browser --session proof record stop
jam record stop <session> --json

With --cdp and no window or display selector the video is a 30 fps screencast of the page in the visible tab: no address bar, cursor or Chrome dialogs, no Screen Recording permission, no window to keep uncovered.

Record at 1920x1080, set before the page loads, and click with mouse move then mouse down and mouse up so the cursor overlay shows each click. references/browser.md has the cursor overlay rules (agent-browser 0.38 or later), other sizes, and visible Chrome for rung 2.

Drive through cdpProxy, not Chrome, or the clicks and typing never become actions. Anything that takes a DevTools URL takes this one: chrome-devtools-mcp --browserUrl <cdpProxy>, Playwright's chromium.connectOverCDP.

Stop with jam record stop <session> --json, using the session that start printed, so a recording another agent started is never the one stopped. The receipt is the Jam. Stderr stays quiet when the tap worked. It says so when Chrome sent no console, network or user-action events at all, which means the tap or the proxy was not actually in the path. Treat that line as a failed proof and fix the wiring before handing the link over.

If jam record start or run fails, run jam doctor and report its Recording and Screencast lines. Do not hand over a link you did not get.

Make it readable

Pace it for the person who will watch it, not for yourself. You read a page from its accessibility tree, which is ready long before the page has finished painting, animating and settling. A run that is correct at your speed is a flicker at theirs, and a flicker proves nothing. So the waits are part of the proof, not padding around it.

  • Start from a known state: reload the page, restart the app, clear the terminal.
  • Wait on the thing, not the clock: wait "<selector>" for what the action produced. A hard-coded pause is either too short on a slow run or dead air on a fast one, and a video of identical gaps reads as a machine.
  • Then let the eye catch up. A small in-place change needs a moment; a new screen needs longer, and the state that carries the claim needs longest. Match the dwell to how much changed, and never cut away from something still moving — an element in the tree is not yet an element a person has seen.
  • Keep it short. Thirty seconds that show the behavior beat five minutes.
  • Title is the claim: "Deep link scrolls to comment 6", not "proof".
  • Steps and expected result go in --description.

Before and after

For a bug fix, reuse the reported Jam as the "before" when it shows the bug. If new before-and-after recordings are needed, run the old and fixed versions in isolated checkouts with test data. Preserve the user's working tree. Skip the first when there is no meaningful before and say why.

After

  1. Read the receipt: id and url always, plus durationMs, width, height and the recorded target when jam record did the capturing. If the capture or upload failed, say so. Never claim proof you do not have.
  2. Link it when there is something to link. With a pull request, ticket or CI run, attach it: jam update jam <jamId> --resource <url>, with --label "<name>" when the URL does not say what it is. With a bug Jam and a fix the recording shows working, mark it: jam update jam <jamId> --mark-related <bug jam> --type fixes, and the bug Jam shows a "fixed by" backlink. Use proves for a demo of a claim, and relates_to to join several Jams of one flow or for a fix the recording does not settle. Over MCP these are addResource and markRelated. The share page can be public: never attach a URL that carries a token.
  3. Offer a comment where it tells a viewer something the video does not. On the new Jam, one at the moment the result appears: jam create comment <jamId> "<what to look at>" --at <ms>. With a bug Jam, one there when the fix is shown working or the check failed, with the new Jam's link. Post on a yes, or right away when the user already asked.
  4. Return the links: Bug | Fix, or one link with the claim it supports. Post them on a PR or ticket only when the user requested that destination.

Send feedback to Jam

When this skill, a Jam MCP tool, a jam command or a Jam doc was wrong, stale or confusing, or worked unusually well, tell Jam. Send it yourself: Jam's agents read it, so it needs no approval.

Call the submitFeedback MCP tool with body, category and subject.

When MCP is unavailable, use the CLI:

jam feedback "<what you were doing, what you expected, what happened, the mistake>" --category <skills|mcp|cli|docs> --subject <skill name, tool name or command>
  • Jam surfaces only, not the user's code or other tools.
  • At most once per session, and never for a slip you corrected yourself.
  • No secrets, customer data, source code, stack traces or recording content.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.