{
  "schemaVersion": "1.0",
  "item": {
    "slug": "snake-rodeo",
    "name": "Snake Rodeo",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/okwme/snake-rodeo",
    "canonicalUrl": "https://clawhub.ai/okwme/snake-rodeo",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/snake-rodeo",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=snake-rodeo",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "clawdhub.json",
      "daemon/autoplay.mjs",
      "lib/api.mjs",
      "lib/config.mjs",
      "lib/process.mjs"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/snake-rodeo"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/snake-rodeo",
    "agentPageUrl": "https://openagent3.xyz/skills/snake-rodeo/agent",
    "manifestUrl": "https://openagent3.xyz/skills/snake-rodeo/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/snake-rodeo/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Snake Rodeo Skill",
        "body": "Play the Trifle Snake Rodeo automatically with a persistent daemon and modular strategy system. Built on the snake-rodeo-agents library."
      },
      {
        "title": "How It Works",
        "body": "The game is a multiplayer snake on a grid (hex or cartesian). Teams bid on directions each round — the highest bidder's direction wins. All bids go into a prize pool that the winning team splits. The daemon watches the game via SSE, picks optimal directions using a strategy, and submits votes automatically."
      },
      {
        "title": "Prerequisites",
        "body": "Authenticated via trifle-auth skill\nNode.js 18+\nBall balance (earned from games, auth bonuses, etc.)"
      },
      {
        "title": "Daemon Commands",
        "body": "# Start/stop\nnode snake.mjs start [--detach] [--strategy NAME]\nnode snake.mjs stop\nnode snake.mjs status\nnode snake.mjs attach [-f]\n\n# Pause/resume voting (daemon keeps running)\nnode snake.mjs pause\nnode snake.mjs resume\n\n# Configuration\nnode snake.mjs config [key] [value]\nnode snake.mjs strategies\nnode snake.mjs server [live|staging]\nnode snake.mjs telegram [chat_id|off]\n\n# Manual play\nnode snake.mjs state\nnode snake.mjs vote <direction> <team> [amount]\nnode snake.mjs strategy    # Analyze current game\nnode snake.mjs balance"
      },
      {
        "title": "Strategies",
        "body": "Five built-in strategies are available. Each extends BaseStrategy from snake-rodeo-agents.\n\nStrategyAliasDescriptionexpected-valueev, defaultBFS pathfinding, dead-end avoidance, game-theoretic team selection, probabilistic defection in multi-agent scenarios. Balanced.aggressiveaggBacks leading teams, counter-bids aggressively.underdogundBacks small pools for bigger payouts.conservativeconMinimum bids, prioritizes safety.randomrandRandom valid moves.\n\nSwitch strategy:\n\nnode snake.mjs config strategy aggressive\n# or\nnode snake.mjs start --strategy aggressive"
      },
      {
        "title": "Creating Custom Strategies",
        "body": "Extend BaseStrategy from snake-rodeo-agents:\n\nimport { BaseStrategy } from 'snake-rodeo-agents';\n\nexport class MyStrategy extends BaseStrategy {\n  constructor(options = {}) {\n    super('my-strategy', 'My custom strategy', options);\n  }\n\n  computeVote(parsed, balance, state) {\n    // parsed: ParsedGameState — hex grid, teams, scores, valid directions\n    // balance: number — current ball balance\n    // state: AgentState — round tracking, team assignment, vote history\n\n    // Return a vote:\n    return { direction: 'ne', team: 'A', amount: 1, reason: 'chasing fruit' };\n\n    // Or skip:\n    return { skip: true, reason: 'too risky' };\n  }\n\n  // Optional: counter-bid when outbid\n  shouldCounterBid(parsed, balance, state, ourVote) {\n    return null; // or return a new VoteAction\n  }\n}\n\nKey types for strategy development:\n\nParsedGameState — Parsed game with head, teams[], validDirections[], gridRadius, prizePool, minBid, fruitsToWin\nAgentState — { currentTeam, roundSpend, roundVoteCount, lastRound, gamesPlayed, votesPlaced, wins }\nVoteAction — { direction, team, amount, reason }"
      },
      {
        "title": "snake-rodeo-agents Library",
        "body": "The core logic lives in snake-rodeo-agents, a standalone TypeScript library. This skill wraps it with daemon management, config persistence, and OpenClaw integration."
      },
      {
        "title": "API Client",
        "body": "import { SnakeClient, createAndAuthenticate, parseGameState, getStrategy } from 'snake-rodeo-agents';\n\n// Auth (creates a throwaway wallet, no real ETH needed)\nconst { token, privateKey, address } = await createAndAuthenticate('https://bot.trifle.life');\n\n// Create client\nconst client = new SnakeClient('https://bot.trifle.life', token);\n\n// Play\nconst rawState = await client.getGameState();\nconst parsed = parseGameState(rawState);\nconst strategy = getStrategy('expected-value');\nconst vote = strategy.computeVote(parsed, balance, agentState);\n\nif (vote && !vote.skip) {\n  await client.submitVote(vote.direction, vote.team, vote.amount);\n}\n\nSnakeClient methods:\n\nMethodDescriptiongetGameState()Current game state (snake, fruits, scores, votes)getBalance()Current ball balancesubmitVote(dir, team, amount)Submit a direction votegetRodeos()List active rodeo gamesgetUserStatus()User profile and stats"
      },
      {
        "title": "Wallet Authentication",
        "body": "SIWE (Sign In With Ethereum) auth with throwaway wallets:\n\nimport { createAndAuthenticate, reauthenticate, checkToken } from 'snake-rodeo-agents';\n\n// New wallet\nconst { token, privateKey, address } = await createAndAuthenticate(serverUrl);\n\n// Reuse saved wallet\nconst { token } = await reauthenticate(serverUrl, savedPrivateKey);\n\n// Check token validity\nconst user = await checkToken(serverUrl, token);"
      },
      {
        "title": "Game State Utilities",
        "body": "The library provides hex grid utilities for strategy development:\n\nimport { parseGameState, hexDistance, bfsDistance, floodFillSize, getValidDirections } from 'snake-rodeo-agents';\n\nconst parsed = parseGameState(rawState);\n\n// BFS shortest path to a target (respects snake body, grid bounds)\nconst { distance, firstDir } = bfsDistance(head, target, rawState);\n\n// Flood-fill reachable area (dead-end detection)\nconst reachable = floodFillSize(head, rawState);\n\n// Hex distance between two positions\nconst dist = hexDistance(posA, posB);"
      },
      {
        "title": "Tournament Simulator",
        "body": "Run offline tournaments to compare strategies at high speed:\n\n# CLI\nnpm run simulate -- ev,aggressive --games 100 --seed 42\nnpm run simulate -- ev,aggressive,conservative --config small --verbose\nnpm run simulate -- ev,aggressive --json   # machine-readable output\n\n// Library\nimport { SimAgent, runTournament, RODEO_CYCLES, getStrategy } from 'snake-rodeo-agents';\n\nconst agents = [\n  new SimAgent('a', 'ev-agent', getStrategy('ev')),\n  new SimAgent('b', 'agg-agent', getStrategy('aggressive')),\n];\n\nconst results = runTournament(agents, RODEO_CYCLES, 100, { seed: 42 });\nconsole.log(results.agentStats);\n// Same seed = identical results for reproducibility\n\nSimulator options:\n\nFlagDescription-g, --games NGames per config (default: 100)-c, --config NAMEsmall|medium|large|all (default: all)-s, --seed NRNG seed for reproducibility-v, --verbosePrint per-round details--jsonMachine-readable JSON output"
      },
      {
        "title": "Telegram Logging",
        "body": "Send game events to a Telegram group:\n\nimport { TelegramLogger } from 'snake-rodeo-agents';\n\nconst tg = new TelegramLogger({\n  botToken: process.env.TELEGRAM_BOT_TOKEN,\n  chatId: process.env.TELEGRAM_CHAT_ID,\n});\n\nawait tg.send('<b>Hello</b> from the snake agent!');\n\nConfigure in the daemon:\n\nnode snake.mjs telegram <chat_id>   # enable\nnode snake.mjs telegram off          # disable"
      },
      {
        "title": "Configuration",
        "body": "Settings are stored in ~/.config/snake-rodeo/settings.json (XDG-compliant, isolated from any host agent).\n\nKeyDefaultDescriptionstrategyexpected-valueActive strategy nameserverlivelive or stagingminBalance5Minimum balance to place votestelegramChatIdnullTelegram chat ID for loggingtelegramBotTokennullTelegram bot token (or set TELEGRAM_BOT_TOKEN env var)"
      },
      {
        "title": "File Locations",
        "body": "PurposePathSettings~/.config/snake-rodeo/settings.jsonAuth token~/.config/snake-rodeo/auth.json or TRIFLE_AUTH_TOKEN env varDaemon state~/.local/state/snake-rodeo/daemon.stateDaemon PID~/.local/state/snake-rodeo/daemon.pidDaemon log~/.local/share/snake-rodeo/daemon.log"
      },
      {
        "title": "Authentication",
        "body": "The skill resolves your Trifle auth token in this order:\n\nTRIFLE_AUTH_TOKEN environment variable (recommended for automation)\n~/.config/snake-rodeo/auth.json — { \"token\": \"your-jwt-here\" }\n\nTo set up auth, run snake auth login (uses trifle-auth skill) or set the env var directly."
      },
      {
        "title": "Architecture",
        "body": "snake-game/                             # OpenClaw skill wrapper\n├── SKILL.md                            # This file\n├── snake.mjs                           # CLI entry point\n├── clawdhub.json                       # ClawHub registry metadata\n├── package.json                        # Dependencies (snake-rodeo-agents)\n├── lib/\n│   ├── config.mjs                      # Settings/paths\n│   ├── api.mjs                         # Token-based API (uses OpenClaw auth)\n│   ├── process.mjs                     # Daemon PID management\n│   └── telegram.mjs                    # Telegram bridge\n├── daemon/\n│   └── autoplay.mjs                    # Game loop: SSE → strategy → vote\n└── node_modules/\n    └── snake-rodeo-agents/             # Core library (TypeScript)\n        └── dist/\n            ├── lib/game-state.js       # Hex grid, BFS, flood-fill\n            ├── lib/strategies/         # Strategy implementations\n            ├── lib/client.js           # Standalone API client\n            ├── lib/auth.js             # Wallet SIWE auth\n            ├── lib/simulator.js        # Offline game simulator\n            ├── lib/telegram.js         # Telegram logger\n            └── bin/play.js             # Standalone CLI runner"
      },
      {
        "title": "Upgrading",
        "body": "node snake.mjs stop\ncd ~/.openclaw/workspace/skills/snake-rodeo\nnpm install github:trifle-labs/snake-rodeo-agents\nnode snake.mjs start --detach"
      }
    ],
    "body": "Snake Rodeo Skill\n\nPlay the Trifle Snake Rodeo automatically with a persistent daemon and modular strategy system. Built on the snake-rodeo-agents library.\n\nHow It Works\n\nThe game is a multiplayer snake on a grid (hex or cartesian). Teams bid on directions each round — the highest bidder's direction wins. All bids go into a prize pool that the winning team splits. The daemon watches the game via SSE, picks optimal directions using a strategy, and submits votes automatically.\n\nPrerequisites\nAuthenticated via trifle-auth skill\nNode.js 18+\nBall balance (earned from games, auth bonuses, etc.)\nDaemon Commands\n# Start/stop\nnode snake.mjs start [--detach] [--strategy NAME]\nnode snake.mjs stop\nnode snake.mjs status\nnode snake.mjs attach [-f]\n\n# Pause/resume voting (daemon keeps running)\nnode snake.mjs pause\nnode snake.mjs resume\n\n# Configuration\nnode snake.mjs config [key] [value]\nnode snake.mjs strategies\nnode snake.mjs server [live|staging]\nnode snake.mjs telegram [chat_id|off]\n\n# Manual play\nnode snake.mjs state\nnode snake.mjs vote <direction> <team> [amount]\nnode snake.mjs strategy    # Analyze current game\nnode snake.mjs balance\n\nStrategies\n\nFive built-in strategies are available. Each extends BaseStrategy from snake-rodeo-agents.\n\nStrategy\tAlias\tDescription\nexpected-value\tev, default\tBFS pathfinding, dead-end avoidance, game-theoretic team selection, probabilistic defection in multi-agent scenarios. Balanced.\naggressive\tagg\tBacks leading teams, counter-bids aggressively.\nunderdog\tund\tBacks small pools for bigger payouts.\nconservative\tcon\tMinimum bids, prioritizes safety.\nrandom\trand\tRandom valid moves.\n\nSwitch strategy:\n\nnode snake.mjs config strategy aggressive\n# or\nnode snake.mjs start --strategy aggressive\n\nCreating Custom Strategies\n\nExtend BaseStrategy from snake-rodeo-agents:\n\nimport { BaseStrategy } from 'snake-rodeo-agents';\n\nexport class MyStrategy extends BaseStrategy {\n  constructor(options = {}) {\n    super('my-strategy', 'My custom strategy', options);\n  }\n\n  computeVote(parsed, balance, state) {\n    // parsed: ParsedGameState — hex grid, teams, scores, valid directions\n    // balance: number — current ball balance\n    // state: AgentState — round tracking, team assignment, vote history\n\n    // Return a vote:\n    return { direction: 'ne', team: 'A', amount: 1, reason: 'chasing fruit' };\n\n    // Or skip:\n    return { skip: true, reason: 'too risky' };\n  }\n\n  // Optional: counter-bid when outbid\n  shouldCounterBid(parsed, balance, state, ourVote) {\n    return null; // or return a new VoteAction\n  }\n}\n\n\nKey types for strategy development:\n\nParsedGameState — Parsed game with head, teams[], validDirections[], gridRadius, prizePool, minBid, fruitsToWin\nAgentState — { currentTeam, roundSpend, roundVoteCount, lastRound, gamesPlayed, votesPlaced, wins }\nVoteAction — { direction, team, amount, reason }\nsnake-rodeo-agents Library\n\nThe core logic lives in snake-rodeo-agents, a standalone TypeScript library. This skill wraps it with daemon management, config persistence, and OpenClaw integration.\n\nAPI Client\nimport { SnakeClient, createAndAuthenticate, parseGameState, getStrategy } from 'snake-rodeo-agents';\n\n// Auth (creates a throwaway wallet, no real ETH needed)\nconst { token, privateKey, address } = await createAndAuthenticate('https://bot.trifle.life');\n\n// Create client\nconst client = new SnakeClient('https://bot.trifle.life', token);\n\n// Play\nconst rawState = await client.getGameState();\nconst parsed = parseGameState(rawState);\nconst strategy = getStrategy('expected-value');\nconst vote = strategy.computeVote(parsed, balance, agentState);\n\nif (vote && !vote.skip) {\n  await client.submitVote(vote.direction, vote.team, vote.amount);\n}\n\n\nSnakeClient methods:\n\nMethod\tDescription\ngetGameState()\tCurrent game state (snake, fruits, scores, votes)\ngetBalance()\tCurrent ball balance\nsubmitVote(dir, team, amount)\tSubmit a direction vote\ngetRodeos()\tList active rodeo games\ngetUserStatus()\tUser profile and stats\nWallet Authentication\n\nSIWE (Sign In With Ethereum) auth with throwaway wallets:\n\nimport { createAndAuthenticate, reauthenticate, checkToken } from 'snake-rodeo-agents';\n\n// New wallet\nconst { token, privateKey, address } = await createAndAuthenticate(serverUrl);\n\n// Reuse saved wallet\nconst { token } = await reauthenticate(serverUrl, savedPrivateKey);\n\n// Check token validity\nconst user = await checkToken(serverUrl, token);\n\nGame State Utilities\n\nThe library provides hex grid utilities for strategy development:\n\nimport { parseGameState, hexDistance, bfsDistance, floodFillSize, getValidDirections } from 'snake-rodeo-agents';\n\nconst parsed = parseGameState(rawState);\n\n// BFS shortest path to a target (respects snake body, grid bounds)\nconst { distance, firstDir } = bfsDistance(head, target, rawState);\n\n// Flood-fill reachable area (dead-end detection)\nconst reachable = floodFillSize(head, rawState);\n\n// Hex distance between two positions\nconst dist = hexDistance(posA, posB);\n\nTournament Simulator\n\nRun offline tournaments to compare strategies at high speed:\n\n# CLI\nnpm run simulate -- ev,aggressive --games 100 --seed 42\nnpm run simulate -- ev,aggressive,conservative --config small --verbose\nnpm run simulate -- ev,aggressive --json   # machine-readable output\n\n// Library\nimport { SimAgent, runTournament, RODEO_CYCLES, getStrategy } from 'snake-rodeo-agents';\n\nconst agents = [\n  new SimAgent('a', 'ev-agent', getStrategy('ev')),\n  new SimAgent('b', 'agg-agent', getStrategy('aggressive')),\n];\n\nconst results = runTournament(agents, RODEO_CYCLES, 100, { seed: 42 });\nconsole.log(results.agentStats);\n// Same seed = identical results for reproducibility\n\n\nSimulator options:\n\nFlag\tDescription\n-g, --games N\tGames per config (default: 100)\n-c, --config NAME\tsmall|medium|large|all (default: all)\n-s, --seed N\tRNG seed for reproducibility\n-v, --verbose\tPrint per-round details\n--json\tMachine-readable JSON output\nTelegram Logging\n\nSend game events to a Telegram group:\n\nimport { TelegramLogger } from 'snake-rodeo-agents';\n\nconst tg = new TelegramLogger({\n  botToken: process.env.TELEGRAM_BOT_TOKEN,\n  chatId: process.env.TELEGRAM_CHAT_ID,\n});\n\nawait tg.send('<b>Hello</b> from the snake agent!');\n\n\nConfigure in the daemon:\n\nnode snake.mjs telegram <chat_id>   # enable\nnode snake.mjs telegram off          # disable\n\nConfiguration\n\nSettings are stored in ~/.config/snake-rodeo/settings.json (XDG-compliant, isolated from any host agent).\n\nKey\tDefault\tDescription\nstrategy\texpected-value\tActive strategy name\nserver\tlive\tlive or staging\nminBalance\t5\tMinimum balance to place votes\ntelegramChatId\tnull\tTelegram chat ID for logging\ntelegramBotToken\tnull\tTelegram bot token (or set TELEGRAM_BOT_TOKEN env var)\nFile Locations\nPurpose\tPath\nSettings\t~/.config/snake-rodeo/settings.json\nAuth token\t~/.config/snake-rodeo/auth.json or TRIFLE_AUTH_TOKEN env var\nDaemon state\t~/.local/state/snake-rodeo/daemon.state\nDaemon PID\t~/.local/state/snake-rodeo/daemon.pid\nDaemon log\t~/.local/share/snake-rodeo/daemon.log\nAuthentication\n\nThe skill resolves your Trifle auth token in this order:\n\nTRIFLE_AUTH_TOKEN environment variable (recommended for automation)\n~/.config/snake-rodeo/auth.json — { \"token\": \"your-jwt-here\" }\n\nTo set up auth, run snake auth login (uses trifle-auth skill) or set the env var directly.\n\nArchitecture\nsnake-game/                             # OpenClaw skill wrapper\n├── SKILL.md                            # This file\n├── snake.mjs                           # CLI entry point\n├── clawdhub.json                       # ClawHub registry metadata\n├── package.json                        # Dependencies (snake-rodeo-agents)\n├── lib/\n│   ├── config.mjs                      # Settings/paths\n│   ├── api.mjs                         # Token-based API (uses OpenClaw auth)\n│   ├── process.mjs                     # Daemon PID management\n│   └── telegram.mjs                    # Telegram bridge\n├── daemon/\n│   └── autoplay.mjs                    # Game loop: SSE → strategy → vote\n└── node_modules/\n    └── snake-rodeo-agents/             # Core library (TypeScript)\n        └── dist/\n            ├── lib/game-state.js       # Hex grid, BFS, flood-fill\n            ├── lib/strategies/         # Strategy implementations\n            ├── lib/client.js           # Standalone API client\n            ├── lib/auth.js             # Wallet SIWE auth\n            ├── lib/simulator.js        # Offline game simulator\n            ├── lib/telegram.js         # Telegram logger\n            └── bin/play.js             # Standalone CLI runner\n\nUpgrading\nnode snake.mjs stop\ncd ~/.openclaw/workspace/skills/snake-rodeo\nnpm install github:trifle-labs/snake-rodeo-agents\nnode snake.mjs start --detach"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/okwme/snake-rodeo",
    "publisherUrl": "https://clawhub.ai/okwme/snake-rodeo",
    "owner": "okwme",
    "version": "3.2.1",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/snake-rodeo",
    "downloadUrl": "https://openagent3.xyz/downloads/snake-rodeo",
    "agentUrl": "https://openagent3.xyz/skills/snake-rodeo/agent",
    "manifestUrl": "https://openagent3.xyz/skills/snake-rodeo/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/snake-rodeo/agent.md"
  }
}