{
  "manifest_version": "0.4",
  "name": "jank",
  "display_name": "Jank — AI quality checks",
  "version": "1.8.4",
  "description": "Quality checks for AI coding agents — six slash commands (/jank, /jank_light, /jank_test, /jank_explore, /jank_cloud, /jank_clean) that catch the bugs Claude/Cursor/Codex ship most often.",
  "long_description": "Jank adds six slash commands to your AI coding agent: /jank runs a full sweep with 10 testers in real Chrome (headless, your real cookies); /jank_light is a code-only static scan with zero setup; /jank_test '<feature>' surgically tests one thing in plain English; /jank_explore spawns 5 user-style agents (cautious shopper, power user, mobile-only, etc.) with realistic data; /jank_cloud audits any URL via reports.jank.ai (3 free); /jank_clean reaps zombie Chrome from cancelled runs. Catches GenAI-typical bugs — leaked secrets, hallucinated APIs, mock data left in prod, dead handlers, mobile breaks, accessibility regressions. Runs locally on your machine; uses your Anthropic/OpenAI/Gemini key for analysis. See https://jank.ai.",
  "author": {
    "name": "Jason Arbon",
    "email": "jason@testers.ai",
    "url": "https://jank.ai"
  },
  "homepage": "https://jank.ai",
  "documentation": "https://jank.ai",
  "support": "mailto:jason@testers.ai",
  "icon": "icon.png",
  "server": {
    "type": "node",
    "entry_point": "dist/jank-mcp-server.js",
    "mcp_config": {
      "command": "node",
      "args": [
        "${__dirname}/dist/jank-mcp-server.js"
      ],
      "env": {
        "JANK_EMAIL": "${user_config.email}",
        "JANK_API_KEY": "${user_config.api_key}",
        "JANK_ADMIN_TOKEN": "${user_config.admin_token}",
        "JANK_BRAND": "${user_config.brand}",
        "JANK_VISIBILITY": "${user_config.visibility}",
        "JANK_PROVIDER": "${user_config.provider}",
        "JANK_MODEL": "${user_config.model}",
        "JANK_NOTIFY_EMAILS": "${user_config.notify_emails}",
        "JANK_TUNNEL": "${user_config.tunnel}",
        "OPENAI_API_KEY": "${user_config.openai_api_key}",
        "ANTHROPIC_API_KEY": "${user_config.anthropic_api_key}",
        "GEMINI_API_KEY": "${user_config.gemini_api_key}",
        "AZURE_OPENAI_API_KEY": "${user_config.azure_api_key}",
        "JANK_DEFAULT_PROVIDER": "${user_config.default_provider}"
      }
    }
  },
  "tools": [
    {
      "name": "jank_launch",
      "description": "Open the Jank config UI in your browser"
    },
    {
      "name": "jank_run",
      "description": "Run a full quality-check pass against a URL"
    },
    {
      "name": "jank_results",
      "description": "Retrieve the latest findings from a run"
    },
    {
      "name": "jank_stop",
      "description": "Cancel a running check"
    },
    {
      "name": "jank_detect_url",
      "description": "Auto-detect locally-running dev servers"
    },
    {
      "name": "jank_quick_test",
      "description": "Quick-test based on files you've recently edited"
    },
    {
      "name": "jank_feedback",
      "description": "Collect persona feedback on a page"
    },
    {
      "name": "jank_links",
      "description": "Check links in your recently-changed files"
    },
    {
      "name": "jank_cloud_report",
      "description": "Kick off a cloud-hosted Jank report on reports.jank.ai"
    },
    {
      "name": "jank_session_start",
      "description": "Start a multi-persona browser session"
    },
    {
      "name": "jank_explore_session_start",
      "description": "Start an exploratory session with user-style explorer personas (Kelly/Greg/Maria/Sam/Robin)"
    },
    {
      "name": "jank_open_tabs",
      "description": "Open one Chrome tab per persona session via CDP and inject the bridge"
    },
    {
      "name": "jank_close_tabs",
      "description": "Close persona tabs opened by jank_open_tabs"
    },
    {
      "name": "jank_spider_run",
      "description": "Run Spider's parallel reachability sweep — fan-fetches every same-origin link"
    },
    {
      "name": "jank_progress_snapshot",
      "description": "Compact markdown progress block for inline-chat rendering"
    },
    {
      "name": "jank_clean",
      "description": "Reap zombie Chrome processes from cancelled or crashed runs"
    },
    {
      "name": "jank_parallel_eval",
      "description": "Evaluate JS in multiple persona tabs simultaneously"
    },
    {
      "name": "jank_parallel_plan",
      "description": "Ask all personas to plan their next step in parallel"
    },
    {
      "name": "jank_parallel_screenshot",
      "description": "Capture screenshots from every persona tab in parallel"
    },
    {
      "name": "jank_bridge_eval",
      "description": "Evaluate JS in a single persona tab"
    },
    {
      "name": "jank_bridge_screenshot",
      "description": "Capture a screenshot from a single persona tab"
    },
    {
      "name": "jank_save_screenshot",
      "description": "Save a base64 JPEG screenshot to the active run's artifact folder"
    },
    {
      "name": "jank_record_step",
      "description": "Record a plan/action/result step for a persona session"
    },
    {
      "name": "jank_session_end",
      "description": "Finalize a session and write its report"
    },
    {
      "name": "jank_config",
      "description": "Get/set saved Jank credentials and defaults"
    }
  ],
  "tools_generated": false,
  "prompts": [
    {
      "name": "jank",
      "description": "Full quality sweep — code + live browser, every category",
      "text": "The user invoked /jank. The playbook for this command is bundled inside the `jank-ai` MCP server.\n\n**Step 1 — Fetch the playbook:**\n\nCall `mcp__jank-ai__jank_get_playbook` with `name=\"jank\"`.\n\n**Step 2 — Follow the returned instructions exactly.**\n\nThe user's typed arguments (URL, options, target file, etc.) are in `$ARGUMENTS` — pass them to the playbook tools as the returned instructions describe.\n\nIf `jank_get_playbook` returns an error, the `jank-ai` MCP server isn't loaded — the user's plugin install is incomplete. Tell them to verify the install and restart Claude Desktop fully (⌘Q + relaunch).\n"
    },
    {
      "name": "jank_light",
      "description": "Pure static scan — no browser, no setup, instant",
      "text": "The user invoked /jank_light. The playbook for this command is bundled inside the `jank-ai` MCP server.\n\n**Step 1 — Fetch the playbook:**\n\nCall `mcp__jank-ai__jank_get_playbook` with `name=\"jank_light\"`.\n\n**Step 2 — Follow the returned instructions exactly.**\n\nThe user's typed arguments (URL, options, target file, etc.) are in `$ARGUMENTS` — pass them to the playbook tools as the returned instructions describe.\n\nIf `jank_get_playbook` returns an error, the `jank-ai` MCP server isn't loaded — the user's plugin install is incomplete. Tell them to verify the install and restart Claude Desktop fully (⌘Q + relaunch).\n"
    },
    {
      "name": "jank_test",
      "description": "Surgical: type a feature/flow after the command in plain English",
      "text": "The user invoked /jank_test. The playbook for this command is bundled inside the `jank-ai` MCP server.\n\n**Step 1 — Fetch the playbook:**\n\nCall `mcp__jank-ai__jank_get_playbook` with `name=\"jank_test\"`.\n\n**Step 2 — Follow the returned instructions exactly.**\n\nThe user's typed arguments (URL, options, target file, etc.) are in `$ARGUMENTS` — pass them to the playbook tools as the returned instructions describe.\n\nIf `jank_get_playbook` returns an error, the `jank-ai` MCP server isn't loaded — the user's plugin install is incomplete. Tell them to verify the install and restart Claude Desktop fully (⌘Q + relaunch).\n"
    },
    {
      "name": "jank_explore",
      "description": "5 user-style agents act in your app — find functional breaks",
      "text": "The user invoked /jank_explore. The playbook for this command is bundled inside the `jank-ai` MCP server.\n\n**Step 1 — Fetch the playbook:**\n\nCall `mcp__jank-ai__jank_get_playbook` with `name=\"jank_explore\"`.\n\n**Step 2 — Follow the returned instructions exactly.**\n\nThe user's typed arguments (URL, options, target file, etc.) are in `$ARGUMENTS` — pass them to the playbook tools as the returned instructions describe.\n\nIf `jank_get_playbook` returns an error, the `jank-ai` MCP server isn't loaded — the user's plugin install is incomplete. Tell them to verify the install and restart Claude Desktop fully (⌘Q + relaunch).\n"
    },
    {
      "name": "jank_cloud",
      "description": "Free hosted audit — type a URL after the command",
      "text": "The user invoked /jank_cloud. The playbook for this command is bundled inside the `jank-ai` MCP server.\n\n**Step 1 — Fetch the playbook:**\n\nCall `mcp__jank-ai__jank_get_playbook` with `name=\"jank_cloud\"`.\n\n**Step 2 — Follow the returned instructions exactly.**\n\nThe user's typed arguments (URL, options, target file, etc.) are in `$ARGUMENTS` — pass them to the playbook tools as the returned instructions describe.\n\nIf `jank_get_playbook` returns an error, the `jank-ai` MCP server isn't loaded — the user's plugin install is incomplete. Tell them to verify the install and restart Claude Desktop fully (⌘Q + relaunch).\n"
    },
    {
      "name": "jank_clean",
      "description": "Reap zombie Chrome from a cancelled run",
      "text": "The user invoked /jank_clean. The playbook for this command is bundled inside the `jank-ai` MCP server.\n\n**Step 1 — Fetch the playbook:**\n\nCall `mcp__jank-ai__jank_get_playbook` with `name=\"jank_clean\"`.\n\n**Step 2 — Follow the returned instructions exactly.**\n\nThe user's typed arguments (URL, options, target file, etc.) are in `$ARGUMENTS` — pass them to the playbook tools as the returned instructions describe.\n\nIf `jank_get_playbook` returns an error, the `jank-ai` MCP server isn't loaded — the user's plugin install is incomplete. Tell them to verify the install and restart Claude Desktop fully (⌘Q + relaunch).\n"
    }
  ],
  "keywords": [
    "testing",
    "quality",
    "jank",
    "qa",
    "playwright",
    "personas",
    "ai-testing",
    "accessibility",
    "security",
    "performance"
  ],
  "license": "Proprietary",
  "repository": {
    "type": "git",
    "url": "https://github.com/testers-ai/jank-plugin"
  },
  "user_config": {
    "email": {
      "type": "string",
      "title": "Email",
      "description": "Your email — used for /jank_cloud reports and to identify your account on reports.jank.ai. Free tier (3 reports/month) needs no further setup. Required for /jank_cloud; optional for the local-only commands.",
      "default": "",
      "required": false
    },
    "api_key": {
      "type": "string",
      "title": "API Key (optional)",
      "description": "Your jank.ai API key. Only needed if you've upgraded past the free tier. Get one at https://jank.ai/account.",
      "sensitive": true,
      "default": "",
      "required": false
    },
    "admin_token": {
      "type": "string",
      "title": "Admin Token (paid tier)",
      "description": "Bearer token for paid-tier features (poll private reports, bypass rate limits). Leave empty for free tier.",
      "sensitive": true,
      "default": "",
      "required": false
    },
    "brand": {
      "type": "string",
      "title": "Brand theme",
      "description": "Visual brand applied to your /jank_cloud report pages and emails. Default: jank. Use your own brand slug if you've set one up at jank.ai/brands.",
      "default": "",
      "required": false
    },
    "visibility": {
      "type": "string",
      "title": "Default report visibility",
      "description": "private = only you can view (requires email or admin token). public = anyone with the URL. Leave empty to use the cloud default (private).",
      "default": "",
      "required": false
    },
    "provider": {
      "type": "string",
      "title": "Default LLM provider (cloud-side)",
      "description": "Which LLM the cloud uses for analysis. openai | anthropic | gemini | azure. Leave empty for cloud default.",
      "default": "",
      "required": false
    },
    "model": {
      "type": "string",
      "title": "Default LLM model (cloud-side)",
      "description": "Specific model name (e.g. gpt-5.4-mini, claude-sonnet-4-6). Pairs with the provider above. Leave empty for cloud default.",
      "default": "",
      "required": false
    },
    "notify_emails": {
      "type": "string",
      "title": "Notify emails (comma-separated)",
      "description": "Extra emails CC'd when a /jank_cloud run finishes. Your account email is auto-included. Comma-separate multiple addresses.",
      "default": "",
      "required": false
    },
    "tunnel": {
      "type": "string",
      "title": "Tunnel mode for private targets",
      "description": "cloudflared = auto-spin a Cloudflare tunnel so the cloud can reach localhost. none = direct (target must be public). Default: auto-detected.",
      "default": "",
      "required": false
    },
    "openai_api_key": {
      "type": "string",
      "title": "OpenAI API key",
      "description": "Used by /jank, /jank_test, /jank_explore for persona reasoning. Get one at https://platform.openai.com/api-keys.",
      "sensitive": true,
      "default": "",
      "required": false
    },
    "anthropic_api_key": {
      "type": "string",
      "title": "Anthropic API key",
      "description": "Alternative to OpenAI for persona reasoning. Get one at https://console.anthropic.com/settings/keys.",
      "sensitive": true,
      "default": "",
      "required": false
    },
    "gemini_api_key": {
      "type": "string",
      "title": "Gemini API key",
      "description": "Alternative to OpenAI for persona reasoning. Get one at https://aistudio.google.com/app/apikey.",
      "sensitive": true,
      "default": "",
      "required": false
    },
    "azure_api_key": {
      "type": "string",
      "title": "Azure OpenAI API key",
      "description": "For users on Azure OpenAI. Pair with the AZURE_OPENAI_ENDPOINT env var.",
      "sensitive": true,
      "default": "",
      "required": false
    },
    "default_provider": {
      "type": "string",
      "title": "Default LLM provider (local persona reasoning)",
      "description": "Which provider /jank, /jank_test and /jank_explore use by default. openai | anthropic | gemini | azure. Leave empty to fall back to whichever key is set.",
      "default": "",
      "required": false
    }
  },
  "compatibility": {
    "claude_desktop": ">=0.10.0",
    "platforms": [
      "darwin",
      "win32",
      "linux"
    ],
    "runtimes": {
      "node": ">=22.0.0"
    }
  },
  "prompts_generated": false
}