{
  "id": "playwright-e2e-tests",
  "type": "loadout",
  "title": "Playwright end-to-end tests agents don't make flaky",
  "summary": "Rules for agents writing and healing Playwright tests, including Playwright's test agents: role locators, web-first assertions, no sleeps, never weaken a test to pass.",
  "description": "Playwright now ships its own planner, generator and healer agents, and every coding agent writes Playwright tests on request. Left alone they reach for the same shortcuts: waitForTimeout, CSS chains, force clicks, expect(await isVisible()) that never retries, and a healer that makes a red test green by deleting the assertion. This loadout gives your agent Playwright's own best practices as rules, a healing procedure that decides whether the app or the test is wrong before touching anything, and a linter for the anti-patterns. The verifier runs the example spec twice over in real Chrome against a page that renders late, and lints a flaky spec.\n",
  "highlights": [
    "Works alongside npx playwright init-agents (planner, generator, healer)",
    "getByRole first; web-first assertions only; no fixed waits",
    "Healing rule: if the app regressed, report it, never edit the test to match",
    "Linter for waitForTimeout, force clicks, test.only and non-retrying assertions",
    "Example passes repeat runs in Chrome against a deliberately slow page"
  ],
  "version": "1.0.0",
  "license": "MIT",
  "author": {
    "name": "Agent Loadout",
    "url": "https://loadout.jnw-it.com"
  },
  "credits": [
    {
      "title": "Playwright docs: best practices",
      "url": "https://playwright.dev/docs/best-practices"
    },
    {
      "title": "Playwright docs: test agents (planner, generator, healer)",
      "url": "https://playwright.dev/docs/test-agents"
    },
    {
      "title": "Playwright docs: locators",
      "url": "https://playwright.dev/docs/locators"
    },
    {
      "title": "Playwright docs: auto-retrying assertions",
      "url": "https://playwright.dev/docs/test-assertions"
    }
  ],
  "categories": [
    "web-app",
    "workflow"
  ],
  "stacks": [
    "playwright",
    "typescript"
  ],
  "files": [
    {
      "path": "AGENTS.md",
      "role": "instructions",
      "description": "Rules for writing, running and healing Playwright end-to-end tests.",
      "skill": null,
      "agent": null,
      "install_to": {
        "claude-code": "AGENTS.md",
        "codex": "AGENTS.md",
        "cursor": "AGENTS.md",
        "gemini-cli": "AGENTS.md",
        "antigravity-cli": "AGENTS.md",
        "copilot": "AGENTS.md"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/AGENTS.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/latest/AGENTS.md",
      "bytes": 2359,
      "lang": "markdown",
      "content": "# AGENTS.md: Playwright end-to-end tests\n\nEnd-to-end tests with Playwright Test (`@playwright/test`). These rules apply when you write tests by hand and when\nyou use Playwright's own test agents (planner, generator, healer from `npx playwright init-agents`).\n\n## Commands\n- Run: `npx playwright test`. One file: `npx playwright test tests/todo.spec.ts`. List without running:\n  `npx playwright test --list`.\n- Debug a failure: `npx playwright show-trace test-results/<test>/trace.zip`. Do not guess from the error alone.\n- Before finishing, run the `write-e2e-test` skill's linter (`scripts/lint_specs.mjs` in the skill folder) over the\n  test folder. It must report no findings.\n\n## Writing tests\n- Locate by what the user sees: `getByRole` with a name first, then `getByLabel`, `getByPlaceholder`, `getByText`.\n  `getByTestId` when there is nothing better. No CSS chains, XPath or `nth-child`.\n- Web-first assertions only: `await expect(locator).toBeVisible()`, `toHaveText`, `toHaveCount`, `toHaveURL`.\n  Never `expect(await locator.isVisible()).toBe(true)`: it does not retry.\n- No fixed waits: no `page.waitForTimeout`, no `waitForLoadState(\"networkidle\")`. Wait for the thing you need.\n- No `force: true` on clicks. If an element is covered, that is a bug or a wrong locator.\n- Each test sets up its own state and runs alone and in any order. Share setup with fixtures or `beforeEach`, and\n  authentication with a setup project and `storageState`.\n- Never commit `test.only`. Use `test.skip` with a reason, or `test.fixme` and an issue link.\n- Test data and accounts are test-only. Never use production credentials; read secrets from the environment.\n\n## Healing failing tests\n- First decide whether the test or the app is wrong. Read the trace. If the app regressed, report it; do not change\n  the test to match a bug.\n- Never make a test pass by deleting assertions, loosening them to `toBeTruthy`, adding timeouts or retries, or\n  skipping it without saying so.\n- Locator changed because the UI changed on purpose: update the locator to a role-based one and say what changed.\n\n## Configuration\n- `retries` only in CI (`process.env.CI ? 2 : 0`), with `trace: \"on-first-retry\"`.\n- `webServer` starts the app; do not assume a server is already running.\n- Ask before adding browsers, projects or dependencies. Pin `@playwright/test` to an exact version.\n"
    },
    {
      "path": "CLAUDE.md",
      "role": "adapter",
      "description": "Imports AGENTS.md for Claude Code.",
      "skill": null,
      "agent": "claude-code",
      "install_to": {
        "claude-code": "CLAUDE.md",
        "codex": null,
        "cursor": null,
        "gemini-cli": null,
        "antigravity-cli": null,
        "copilot": null
      },
      "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/CLAUDE.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/latest/CLAUDE.md",
      "bytes": 406,
      "lang": "markdown",
      "content": "# CLAUDE.md\n\n@AGENTS.md\n\n## Claude Code notes\n- Skills from this loadout live in `.claude/skills/`: `write-e2e-test`. Use them when their description matches the task.\n- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.\n\n<!-- From the Agent Loadout \"Playwright end-to-end tests agents don't make flaky\" v1.0.0 — https://loadout.jnw-it.com/loadouts/playwright-e2e-tests/ -->\n"
    },
    {
      "path": "GEMINI.md",
      "role": "adapter",
      "description": "Imports AGENTS.md for Gemini CLI.",
      "skill": null,
      "agent": "gemini-cli",
      "install_to": {
        "claude-code": null,
        "codex": null,
        "cursor": null,
        "gemini-cli": "GEMINI.md",
        "antigravity-cli": null,
        "copilot": null
      },
      "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/GEMINI.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/latest/GEMINI.md",
      "bytes": 407,
      "lang": "markdown",
      "content": "# GEMINI.md\n\n@./AGENTS.md\n\n## Gemini CLI notes\n- Skills from this loadout live in `.agents/skills/`: `write-e2e-test`. Use them when their description matches the task.\n- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.\n\n<!-- From the Agent Loadout \"Playwright end-to-end tests agents don't make flaky\" v1.0.0 — https://loadout.jnw-it.com/loadouts/playwright-e2e-tests/ -->\n"
    },
    {
      "path": "skills/write-e2e-test/SKILL.md",
      "role": "skill",
      "description": "Write or repair a test, lint it and run it three times.",
      "skill": "write-e2e-test",
      "agent": null,
      "install_to": {
        "claude-code": ".claude/skills/write-e2e-test/SKILL.md",
        "codex": ".agents/skills/write-e2e-test/SKILL.md",
        "cursor": ".agents/skills/write-e2e-test/SKILL.md",
        "gemini-cli": ".agents/skills/write-e2e-test/SKILL.md",
        "antigravity-cli": ".agents/skills/write-e2e-test/SKILL.md",
        "copilot": ".agents/skills/write-e2e-test/SKILL.md"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/SKILL.md",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/latest/skills/write-e2e-test/SKILL.md",
      "bytes": 1443,
      "lang": "markdown",
      "content": "---\nname: write-e2e-test\ndescription: Write or repair a Playwright end-to-end test with role-based locators, web-first assertions and no fixed waits, then lint it and run it. Use for new user flows and for failing or flaky tests.\n---\n\n# Write or repair an end-to-end test\n\nExample: `references/todo.spec.ts`.\n\n## New test\n1. Write the flow as steps a user takes and what they should see. One behaviour per test.\n2. Open the page and find each element the way a user would: `page.getByRole(\"button\", { name: \"Add\" })`.\n   If you cannot find a good role or label, ask whether the app should have one before reaching for a test id.\n3. Assert with web-first assertions after every meaningful step (`toBeVisible`, `toHaveText`, `toHaveCount`,\n   `toHaveURL`).\n4. Set up state inside the test or a fixture. Do not depend on another test having run.\n5. Lint: `node scripts/lint_specs.mjs tests`. Fix every finding.\n6. Run it three times in a row (`npx playwright test <file> --repeat-each 3`). Flaky means wrong, not unlucky.\n\n## Failing or flaky test\n1. Run it once with tracing: `npx playwright test <file> --trace on`, then open the trace.\n2. Decide: is the app wrong, or the test? Write down which and why.\n3. App wrong: stop and report the regression with the trace path. Do not edit the test.\n4. Test wrong: fix the locator or the setup. Never add sleeps, never loosen assertions, never add `force: true`.\n5. Lint and run three times as above.\n"
    },
    {
      "path": "skills/write-e2e-test/references/todo.spec.ts",
      "role": "reference",
      "description": "Example spec with role locators and web-first assertions.",
      "skill": "write-e2e-test",
      "agent": null,
      "install_to": {
        "claude-code": ".claude/skills/write-e2e-test/references/todo.spec.ts",
        "codex": ".agents/skills/write-e2e-test/references/todo.spec.ts",
        "cursor": ".agents/skills/write-e2e-test/references/todo.spec.ts",
        "gemini-cli": ".agents/skills/write-e2e-test/references/todo.spec.ts",
        "antigravity-cli": ".agents/skills/write-e2e-test/references/todo.spec.ts",
        "copilot": ".agents/skills/write-e2e-test/references/todo.spec.ts"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/references/todo.spec.ts",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/latest/skills/write-e2e-test/references/todo.spec.ts",
      "bytes": 1281,
      "lang": "markdown",
      "content": "import { expect, test, type Page } from \"@playwright/test\";\n\nasync function addTodo(page: Page, text: string) {\n  await page.getByRole(\"textbox\", { name: \"New todo\" }).fill(text);\n  await page.getByRole(\"button\", { name: \"Add\" }).click();\n}\n\ntest.beforeEach(async ({ page }) => {\n  await page.goto(\"/\");\n  await expect(page.getByRole(\"heading\", { name: \"Todos\" })).toBeVisible();\n});\n\ntest(\"adds a todo and updates the counter\", async ({ page }) => {\n  await addTodo(page, \"Buy milk\");\n  await expect(page.getByRole(\"listitem\")).toHaveText([\"Buy milk\"]);\n  await expect(page.getByRole(\"status\")).toHaveText(\"1 item left\");\n});\n\ntest(\"completing a todo moves it out of the active count\", async ({ page }) => {\n  await addTodo(page, \"Write tests\");\n  await addTodo(page, \"Ship it\");\n  await page.getByRole(\"checkbox\", { name: \"Write tests\" }).check();\n  await expect(page.getByRole(\"status\")).toHaveText(\"1 item left\");\n  await expect(page.getByRole(\"checkbox\", { name: \"Write tests\" })).toBeChecked();\n});\n\ntest(\"rejects an empty todo with a visible message\", async ({ page }) => {\n  await page.getByRole(\"button\", { name: \"Add\" }).click();\n  await expect(page.getByRole(\"alert\")).toHaveText(\"Write something first.\");\n  await expect(page.getByRole(\"listitem\")).toHaveCount(0);\n});\n"
    },
    {
      "path": "skills/write-e2e-test/scripts/lint_specs.mjs",
      "role": "reference",
      "description": "Linter for Playwright test anti-patterns.",
      "skill": "write-e2e-test",
      "agent": null,
      "install_to": {
        "claude-code": ".claude/skills/write-e2e-test/scripts/lint_specs.mjs",
        "codex": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
        "cursor": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
        "gemini-cli": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
        "antigravity-cli": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
        "copilot": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs"
      },
      "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/scripts/lint_specs.mjs",
      "raw_latest_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/latest/skills/write-e2e-test/scripts/lint_specs.mjs",
      "bytes": 2180,
      "lang": "markdown",
      "content": "#!/usr/bin/env node\n// Flags Playwright test anti-patterns: fixed waits, non-retrying assertions, brittle selectors, force clicks, test.only.\n// Usage: node lint_specs.mjs <dir-or-file> [...]. Exit 1 on any finding. Reads files only.\nimport { readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst RULES = [\n  [/\\bwaitForTimeout\\s*\\(/, \"fixed wait: wait for a locator or assertion instead\"],\n  [/waitForLoadState\\(\\s*[\"']networkidle[\"']/, \"networkidle is discouraged: wait for the element you need\"],\n  [/expect\\(\\s*await\\s+.*\\.(?:isVisible|isHidden|isChecked|isEnabled|textContent|innerText|count)\\(\\)\\s*\\)/, \"non-retrying assertion: use a web-first assertion such as toBeVisible() or toHaveText()\"],\n  [/\\bforce\\s*:\\s*true/, \"force: true hides real problems: fix the locator or the app\"],\n  [/\\btest\\.only\\(|\\bdescribe\\.only\\(/, \"test.only must not be committed\"],\n  [/\\bpage\\.\\$\\$?\\(|\\bpage\\.\\$eval\\(/, \"page.$ is the old API: use page.locator or getByRole\"],\n  [/locator\\(\\s*[\"'`][^\"'`]*(?::nth-child|:nth-of-type|\\/\\/|>>|\\.[a-z][\\w-]*\\s+\\.[a-z])/i, \"brittle selector: prefer getByRole, getByLabel or getByTestId\"],\n  [/\\bsetTimeout\\s*\\(/, \"setTimeout in a test: wait for state instead\"],\n  [/\\.toBeTruthy\\(\\)/, \"toBeTruthy proves little: assert the actual value or state\"],\n];\n\nfunction files(p, out = []) {\n  if (statSync(p).isDirectory()) {\n    for (const n of readdirSync(p)) if (n !== \"node_modules\") files(join(p, n), out);\n  } else if (/\\.(?:spec|test)\\.[cm]?[jt]sx?$/.test(p)) out.push(p);\n  return out;\n}\n\nconst targets = process.argv.slice(2);\nif (!targets.length) {\n  console.error(\"usage: node lint_specs.mjs <dir-or-file> [...]\");\n  process.exit(2);\n}\nconst findings = [];\nconst all = targets.flatMap((t) => files(t));\nfor (const f of all) {\n  readFileSync(f, \"utf8\").split(\"\\n\").forEach((line, i) => {\n    for (const [re, msg] of RULES) if (re.test(line)) findings.push(`${f}:${i + 1}: ${msg}`);\n  });\n}\nfor (const x of findings) console.log(x);\nconsole.log(findings.length ? `${findings.length} finding(s) in ${all.length} file(s)` : `ok: ${all.length} spec file(s), no findings`);\nprocess.exit(findings.length ? 1 : 0);\n"
    }
  ],
  "requires": {
    "tools": [
      "node",
      "npm"
    ],
    "env": [],
    "mcp": []
  },
  "tested": {
    "status": "untested",
    "last_run": null,
    "fixture": null,
    "per_agent": {
      "claude-code": "untested",
      "codex": "untested",
      "cursor": "untested",
      "gemini-cli": "untested",
      "antigravity-cli": "untested",
      "copilot": "untested"
    }
  },
  "security": {
    "scanned": true,
    "scanner": "intake-precheck/1",
    "verdict": "clean",
    "network": true,
    "scripts": [
      "lint_specs.mjs"
    ],
    "notes": "npm installs @playwright/test; npx playwright install downloads browsers if you do not use a system browser. The linter only reads spec files. The rules forbid production credentials in tests."
  },
  "featured": false,
  "deprecated": false,
  "last_checked": "2026-10-17",
  "published": "2026-10-17",
  "updated": "2026-10-17",
  "compatibility": {
    "claude-code": "native",
    "codex": "native",
    "cursor": "native",
    "gemini-cli": "native",
    "antigravity-cli": "native",
    "copilot": "native"
  },
  "counts": {
    "rules": 1,
    "skills": 1,
    "mcp": 0
  },
  "url": "https://loadout.jnw-it.com/loadouts/playwright-e2e-tests/",
  "api_url": "https://loadout.jnw-it.com/api/loadouts/playwright-e2e-tests.json",
  "verification": {
    "level": "verified-install",
    "status": "verified",
    "label": "Verified install",
    "verified": true,
    "checked_at": "2026-10-17T09:35:26Z",
    "commit": "021470d33f1f82ab91e12f0c64c43ad15bac6118",
    "content_current": true,
    "agent_tests": "not-run",
    "counts": {
      "pass": 9,
      "fail": 0,
      "skip": 0,
      "not_applicable": 1
    },
    "meaning": "Level 1: automated checks on the files (parse, install paths, MCP config, safety scan, references, size, licence, starter build). No AI agent was run.",
    "checks": [
      {
        "id": "listing",
        "name": "Listing",
        "status": "pass",
        "summary": "Schema valid; 6 files declared, none missing or extra",
        "details": [
          "tested.status: untested (agent tests are separate from Level 1)"
        ]
      },
      {
        "id": "parse",
        "name": "Files parse",
        "status": "pass",
        "summary": "All 6 files parse; front matter valid",
        "details": []
      },
      {
        "id": "adapters",
        "name": "Adapters",
        "status": "pass",
        "summary": "CLAUDE.md and GEMINI.md import AGENTS.md and are up to date",
        "details": [
          "CLAUDE.md: matches the generator",
          "GEMINI.md: matches the generator"
        ]
      },
      {
        "id": "install-paths",
        "name": "Install paths",
        "status": "pass",
        "summary": "Correct paths for all 6 agents; layouts re-discovered",
        "details": [
          "Claude Code: 5 files, 1 skill in .claude/skills/",
          "Codex CLI: 4 files, 1 skill in .agents/skills/",
          "Cursor: 4 files, 1 skill in .agents/skills/",
          "Gemini CLI: 5 files, 1 skill in .agents/skills/",
          "Antigravity CLI: 4 files, 1 skill in .agents/skills/",
          "GitHub Copilot: 4 files, 1 skill in .agents/skills/"
        ]
      },
      {
        "id": "mcp",
        "name": "MCP config",
        "status": "n/a",
        "summary": "No MCP servers in this loadout",
        "details": []
      },
      {
        "id": "safety",
        "name": "Safety scan",
        "status": "pass",
        "summary": "Clean: no credentials, risky shell or hidden text",
        "details": [
          "Scanner intake-precheck/1: verdict clean; network no (listing says yes)"
        ]
      },
      {
        "id": "references",
        "name": "References",
        "status": "pass",
        "summary": "1 reference between files resolves for every agent",
        "details": []
      },
      {
        "id": "size",
        "name": "Size limits",
        "status": "pass",
        "summary": "6 files, 7.9 KB total; largest AGENTS.md 2.3 KB",
        "details": [
          "Limits: 30 files, 32 KB per file, 128 KB total, 500 lines per skill or rule"
        ]
      },
      {
        "id": "licence",
        "name": "Licence",
        "status": "pass",
        "summary": "MIT, by Agent Loadout; text in the repository LICENSE",
        "details": []
      },
      {
        "id": "starter-build",
        "name": "Starter build",
        "status": "pass",
        "summary": "The write-e2e-test skill's example spec passes twice over (--repeat-each 2) in real Chrome against a todo page that renders late, the spec linter passes it, and the linter reports all seven anti-patterns in a flaky spec",
        "details": [
          "Applied 9 loadout files at every agent's paths",
          "✓ place the example spec: bash -c mkdir -p tests && cp .agents/skills/write-e2e-test/references/todo.spec.ts tests/ && echo placed",
          "✓ install @playwright/test (system Chrome, no browser download): npm ci --no-audit --no-fund",
          "✓ list tests: npx playwright test --list",
          "✓ run in Chrome, twice each: npx playwright test --repeat-each 2",
          "✓ linter passes the example: node .agents/skills/write-e2e-test/scripts/lint_specs.mjs tests",
          "✓ linter catches a flaky spec: bash -c node .claude/skills/write-e2e-test/scripts/lint_specs.mjs bad; test $? -eq 1 && echo caught",
          "Covers: getByRole locators and web-first assertions survive a 150 ms delayed render",
          "Covers: webServer starts the app; retries and traces only in CI",
          "Covers: Linter: fixed waits, non-retrying assertions, brittle selectors, force clicks, test.only, page.$, toBeTruthy"
        ]
      }
    ]
  },
  "install": {
    "claude-code": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "CLAUDE.md",
          "target": "CLAUDE.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/CLAUDE.md",
          "role": "adapter"
        },
        {
          "path": "skills/write-e2e-test/SKILL.md",
          "target": ".claude/skills/write-e2e-test/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/write-e2e-test/references/todo.spec.ts",
          "target": ".claude/skills/write-e2e-test/references/todo.spec.ts",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/references/todo.spec.ts",
          "role": "reference"
        },
        {
          "path": "skills/write-e2e-test/scripts/lint_specs.mjs",
          "target": ".claude/skills/write-e2e-test/scripts/lint_specs.mjs",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/scripts/lint_specs.mjs",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/playwright-e2e-tests/claude-code.zip"
    },
    "codex": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/write-e2e-test/SKILL.md",
          "target": ".agents/skills/write-e2e-test/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/write-e2e-test/references/todo.spec.ts",
          "target": ".agents/skills/write-e2e-test/references/todo.spec.ts",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/references/todo.spec.ts",
          "role": "reference"
        },
        {
          "path": "skills/write-e2e-test/scripts/lint_specs.mjs",
          "target": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/scripts/lint_specs.mjs",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/playwright-e2e-tests/codex.zip"
    },
    "cursor": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/write-e2e-test/SKILL.md",
          "target": ".agents/skills/write-e2e-test/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/write-e2e-test/references/todo.spec.ts",
          "target": ".agents/skills/write-e2e-test/references/todo.spec.ts",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/references/todo.spec.ts",
          "role": "reference"
        },
        {
          "path": "skills/write-e2e-test/scripts/lint_specs.mjs",
          "target": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/scripts/lint_specs.mjs",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/playwright-e2e-tests/cursor.zip"
    },
    "gemini-cli": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "GEMINI.md",
          "target": "GEMINI.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/GEMINI.md",
          "role": "adapter"
        },
        {
          "path": "skills/write-e2e-test/SKILL.md",
          "target": ".agents/skills/write-e2e-test/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/write-e2e-test/references/todo.spec.ts",
          "target": ".agents/skills/write-e2e-test/references/todo.spec.ts",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/references/todo.spec.ts",
          "role": "reference"
        },
        {
          "path": "skills/write-e2e-test/scripts/lint_specs.mjs",
          "target": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/scripts/lint_specs.mjs",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/playwright-e2e-tests/gemini-cli.zip"
    },
    "antigravity-cli": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/write-e2e-test/SKILL.md",
          "target": ".agents/skills/write-e2e-test/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/write-e2e-test/references/todo.spec.ts",
          "target": ".agents/skills/write-e2e-test/references/todo.spec.ts",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/references/todo.spec.ts",
          "role": "reference"
        },
        {
          "path": "skills/write-e2e-test/scripts/lint_specs.mjs",
          "target": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/scripts/lint_specs.mjs",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/playwright-e2e-tests/antigravity-cli.zip"
    },
    "copilot": {
      "files": [
        {
          "path": "AGENTS.md",
          "target": "AGENTS.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/AGENTS.md",
          "role": "instructions"
        },
        {
          "path": "skills/write-e2e-test/SKILL.md",
          "target": ".agents/skills/write-e2e-test/SKILL.md",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/SKILL.md",
          "role": "skill"
        },
        {
          "path": "skills/write-e2e-test/references/todo.spec.ts",
          "target": ".agents/skills/write-e2e-test/references/todo.spec.ts",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/references/todo.spec.ts",
          "role": "reference"
        },
        {
          "path": "skills/write-e2e-test/scripts/lint_specs.mjs",
          "target": ".agents/skills/write-e2e-test/scripts/lint_specs.mjs",
          "raw_url": "https://loadout.jnw-it.com/raw/playwright-e2e-tests/1.0.0/skills/write-e2e-test/scripts/lint_specs.mjs",
          "role": "reference"
        }
      ],
      "manual_steps": [],
      "zip_url": "https://loadout.jnw-it.com/download/playwright-e2e-tests/copilot.zip"
    }
  },
  "source_zip_url": "https://loadout.jnw-it.com/download/playwright-e2e-tests/source.zip"
}