{
  "schemaVersion": "1.0",
  "item": {
    "slug": "supermarket",
    "name": "Supermarket",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/niemesrw/supermarket",
    "canonicalUrl": "https://clawhub.ai/niemesrw/supermarket",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/supermarket",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=supermarket",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "CLAUDE.md",
      "README.md",
      "SKILL.md",
      "_meta.json",
      "cmd/krocli/main.go",
      "firebase/firebase.json"
    ],
    "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. Then review README.md for any prerequisites, environment setup, or post-install checks. 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. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-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/supermarket"
    },
    "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/supermarket",
    "agentPageUrl": "https://openagent3.xyz/skills/supermarket/agent",
    "manifestUrl": "https://openagent3.xyz/skills/supermarket/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/supermarket/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. Then review README.md for any prerequisites, environment setup, or post-install checks. 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. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Supermarket Skill",
        "body": "Search grocery products, find stores, add to cart, and view your profile across all Kroger-family stores (Kroger, Ralphs, Fred Meyer, Harris Teeter, King Soopers, Fry's, QFC, Mariano's, Pick 'n Save, and more) — all through the Kroger API via a hosted OAuth proxy. No API keys or developer accounts needed."
      },
      {
        "title": "How This Works (Transparency)",
        "body": "This skill uses a hosted OAuth proxy at us-central1-krocli.cloudfunctions.net to handle Kroger API authentication. Here's what it does and doesn't do:\n\nWhat the proxy handles:\n\nStores the Kroger client_id/client_secret (as Firebase secrets — never exposed to the agent)\nExchanges authorization codes for tokens during login\nRefreshes expired user tokens\n\nPrivacy guarantees (verifiable in source):\n\nUser tokens are deleted from Firestore immediately after being returned to the agent (tokenUser.ts:44)\nLogin sessions expire after 5 minutes (callback.ts:10)\nFirestore rules deny all direct client access — only server-side Cloud Functions can read/write\nNo tokens are logged — only errors use console.error\nThe proxy never sees your Kroger username or password (that goes directly to Kroger's OAuth page)\n\nFull source code: The proxy is open source at firebase/functions/src/ in the krocli repository. You can audit every function: authorize.ts, callback.ts, tokenClient.ts, tokenUser.ts, tokenRefresh.ts.\n\nIf you don't trust the hosted proxy, see \"Self-Hosting\" at the bottom of this document."
      },
      {
        "title": "Architecture",
        "body": "All API calls go through the hosted proxy which handles OAuth credentials. The agent never needs a client_id or client_secret.\n\nTwo token types:\n\nClient token — for public data (products, locations). Obtained automatically.\nUser token — for personal data (cart, profile). Requires one-time browser login."
      },
      {
        "title": "Getting a Client Token",
        "body": "Before searching products or locations, obtain a client token:\n\ncurl -s -X POST https://us-central1-krocli.cloudfunctions.net/tokenClient\n\nResponse:\n\n{\"access_token\": \"eyJ...\", \"expires_in\": 1800, \"token_type\": \"bearer\"}\n\nCache the access_token for subsequent requests. It expires in 30 minutes."
      },
      {
        "title": "Searching Products",
        "body": "curl -s -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/products?filter.term=milk&filter.limit=10\"\n\nQuery parameters:\n\nParameterRequiredDescriptionfilter.termYesSearch term (e.g. \"milk\", \"organic eggs\")filter.locationIdNoStore ID for local pricing/availabilityfilter.limitNoMax results (default 10, max 50)\n\nResponse fields to show the user:\n\ndata[].productId — UPC code\ndata[].description — Product name\ndata[].brand — Brand name\ndata[].items[].price.regular — Price (when locationId provided)\ndata[].items[].price.promo — Sale price (when available)\ndata[].items[].size — Package size"
      },
      {
        "title": "Finding Store Locations",
        "body": "curl -s -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/locations?filter.zipCode.near=45202&filter.limit=5\"\n\nQuery parameters:\n\nParameterRequiredDescriptionfilter.zipCode.nearYesZIP code to search nearfilter.radiusInMilesNoSearch radius (default 10)filter.limitNoMax results (default 10)\n\nResponse fields to show the user:\n\ndata[].locationId — Store ID (use for product pricing)\ndata[].name — Store name\ndata[].address.addressLine1, city, state, zipCode\ndata[].phone — Phone number\ndata[].hours — Operating hours"
      },
      {
        "title": "User Authentication (for Cart & Profile)",
        "body": "When the user wants to add items to their cart or view their profile, they need to authenticate with Kroger. This is a one-time browser flow."
      },
      {
        "title": "Step 1: Generate a session ID and send the login link",
        "body": "Generate a random hex session ID (16-32 characters) and present the login URL to the user as a clickable link:\n\nhttps://us-central1-krocli.cloudfunctions.net/authorize?session_id=SESSION_ID\n\nTell the user: \"Click this link to log in to your Kroger account. Once you see 'Login successful', come back here and let me know.\""
      },
      {
        "title": "Step 2: Poll for tokens",
        "body": "After the user says they've logged in, poll for their tokens:\n\ncurl -s \"https://us-central1-krocli.cloudfunctions.net/tokenUser?session_id=SESSION_ID\"\n\nIf {\"status\": \"pending\"} with HTTP 202: user hasn't finished yet. Wait and retry.\nIf HTTP 200: tokens are returned. Cache access_token and refresh_token.\n\n{\n  \"access_token\": \"eyJ...\",\n  \"refresh_token\": \"abc...\",\n  \"expires_in\": 1800,\n  \"token_type\": \"bearer\"\n}"
      },
      {
        "title": "Step 3: Use the user token",
        "body": "The user token is needed for cart and profile endpoints."
      },
      {
        "title": "Adding to Cart",
        "body": "Requires user token from authentication above.\n\ncurl -s -X PUT \\\n  -H \"Authorization: Bearer USER_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/cart/add\" \\\n  -d '{\"items\": [{\"upc\": \"0011110838049\", \"quantity\": 1}]}'\n\nRequest body:\n\n{\n  \"items\": [\n    {\"upc\": \"PRODUCT_ID\", \"quantity\": 1}\n  ]\n}\n\nHTTP 204 means success (no response body)."
      },
      {
        "title": "Viewing Profile",
        "body": "Requires user token.\n\ncurl -s -H \"Authorization: Bearer USER_ACCESS_TOKEN\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/identity/profile\""
      },
      {
        "title": "Refreshing an Expired User Token",
        "body": "If a user token returns 401, refresh it:\n\ncurl -s -X POST \\\n  -H \"Content-Type: application/json\" \\\n  \"https://us-central1-krocli.cloudfunctions.net/tokenRefresh\" \\\n  -d '{\"refresh_token\": \"REFRESH_TOKEN\"}'\n\nResponse includes new access_token and refresh_token. Cache both."
      },
      {
        "title": "Token Management Summary",
        "body": "TokenHow to getExpiresRefreshClientPOST /tokenClient30 minJust request a new oneUserBrowser login flow30 minPOST /tokenRefresh with refresh_token"
      },
      {
        "title": "Error Handling",
        "body": "HTTP StatusMeaningAction401Token expiredRefresh or re-obtain token403ForbiddenToken lacks required scope429Rate limitedWait and retry400Bad requestCheck parameters"
      },
      {
        "title": "\"Search for milk near me\"",
        "body": "Get client token via POST /tokenClient\nAsk user for ZIP code (or use a previously known one)\nFind nearest store via locations API\nSearch products with filter.locationId for local pricing"
      },
      {
        "title": "\"Add bananas to my Kroger cart\"",
        "body": "Check if user token is cached; if not, start login flow\nSearch for \"bananas\" to get the UPC\nConfirm product with user\nPUT /cart/add with the UPC"
      },
      {
        "title": "\"What Kroger stores are near 90210?\"",
        "body": "Get client token\nSearch locations with filter.zipCode.near=90210\nFormat results with name, address, hours"
      },
      {
        "title": "Token Persistence",
        "body": "After a successful user login, save the refresh token and preferred ZIP code to your long-term memory so the user doesn't have to log in again next session.\n\nAfter login, remember:\n\nkroger_refresh_token: the refresh_token from the login flow\nkroger_zip_code: the user's preferred ZIP code (if provided)\nkroger_store_id: the user's preferred store locationId (if identified)\n\nAt the start of a session, check your memory for a saved kroger_refresh_token. If found:\n\nCall POST /tokenRefresh with the saved refresh_token\nIf it succeeds, use the new access_token — no login needed\nIf it fails (e.g. token revoked), clear the saved token and start a fresh login flow\n\nImportant: Only save the refresh_token, never the access_token (it expires in 30 minutes and is useless to persist)."
      },
      {
        "title": "Self-Hosting the Proxy",
        "body": "If you prefer not to use the hosted proxy, you can run your own. The full source is in the krocli repo under firebase/."
      },
      {
        "title": "Option 1: Deploy your own Firebase proxy",
        "body": "Create a Kroger developer app at developer.kroger.com\n\nScopes: product.compact, cart.basic:write, profile.compact\nRedirect URI: https://YOUR-PROJECT.cloudfunctions.net/callback\n\n\nClone the repo and set up Firebase:\ngit clone https://github.com/BLANXLAIT/krocli.git\ncd krocli/firebase\nfirebase init\nfirebase functions:secrets:set KROGER_CLIENT_ID\nfirebase functions:secrets:set KROGER_CLIENT_SECRET\n\n\nUpdate CALLBACK_URL in callback.ts and authorize.ts to point to your project\nDeploy:\nfirebase deploy --only functions,firestore:rules\n\n\nReplace all us-central1-krocli.cloudfunctions.net URLs in this skill with your own project URL"
      },
      {
        "title": "Option 2: Use the krocli CLI directly (no proxy at all)",
        "body": "If you have Go installed, you can skip the proxy entirely:\n\ngo install github.com/blanxlait/krocli/cmd/krocli@latest\nkrocli auth credentials set /path/to/your/kroger-creds.json\nkrocli products search --term \"milk\"\nkrocli auth login   # browser OAuth, tokens stored in OS keyring\nkrocli cart add --upc 0011110838049\n\nIn this mode, all API calls go directly to api.kroger.com using your own credentials. No proxy involved. Tokens are stored locally in your OS keyring."
      }
    ],
    "body": "Supermarket Skill\n\nSearch grocery products, find stores, add to cart, and view your profile across all Kroger-family stores (Kroger, Ralphs, Fred Meyer, Harris Teeter, King Soopers, Fry's, QFC, Mariano's, Pick 'n Save, and more) — all through the Kroger API via a hosted OAuth proxy. No API keys or developer accounts needed.\n\nHow This Works (Transparency)\n\nThis skill uses a hosted OAuth proxy at us-central1-krocli.cloudfunctions.net to handle Kroger API authentication. Here's what it does and doesn't do:\n\nWhat the proxy handles:\n\nStores the Kroger client_id/client_secret (as Firebase secrets — never exposed to the agent)\nExchanges authorization codes for tokens during login\nRefreshes expired user tokens\n\nPrivacy guarantees (verifiable in source):\n\nUser tokens are deleted from Firestore immediately after being returned to the agent (tokenUser.ts:44)\nLogin sessions expire after 5 minutes (callback.ts:10)\nFirestore rules deny all direct client access — only server-side Cloud Functions can read/write\nNo tokens are logged — only errors use console.error\nThe proxy never sees your Kroger username or password (that goes directly to Kroger's OAuth page)\n\nFull source code: The proxy is open source at firebase/functions/src/ in the krocli repository. You can audit every function: authorize.ts, callback.ts, tokenClient.ts, tokenUser.ts, tokenRefresh.ts.\n\nIf you don't trust the hosted proxy, see \"Self-Hosting\" at the bottom of this document.\n\nArchitecture\n\nAll API calls go through the hosted proxy which handles OAuth credentials. The agent never needs a client_id or client_secret.\n\nTwo token types:\n\nClient token — for public data (products, locations). Obtained automatically.\nUser token — for personal data (cart, profile). Requires one-time browser login.\nGetting a Client Token\n\nBefore searching products or locations, obtain a client token:\n\ncurl -s -X POST https://us-central1-krocli.cloudfunctions.net/tokenClient\n\n\nResponse:\n\n{\"access_token\": \"eyJ...\", \"expires_in\": 1800, \"token_type\": \"bearer\"}\n\n\nCache the access_token for subsequent requests. It expires in 30 minutes.\n\nSearching Products\ncurl -s -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/products?filter.term=milk&filter.limit=10\"\n\n\nQuery parameters:\n\nParameter\tRequired\tDescription\nfilter.term\tYes\tSearch term (e.g. \"milk\", \"organic eggs\")\nfilter.locationId\tNo\tStore ID for local pricing/availability\nfilter.limit\tNo\tMax results (default 10, max 50)\n\nResponse fields to show the user:\n\ndata[].productId — UPC code\ndata[].description — Product name\ndata[].brand — Brand name\ndata[].items[].price.regular — Price (when locationId provided)\ndata[].items[].price.promo — Sale price (when available)\ndata[].items[].size — Package size\nFinding Store Locations\ncurl -s -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/locations?filter.zipCode.near=45202&filter.limit=5\"\n\n\nQuery parameters:\n\nParameter\tRequired\tDescription\nfilter.zipCode.near\tYes\tZIP code to search near\nfilter.radiusInMiles\tNo\tSearch radius (default 10)\nfilter.limit\tNo\tMax results (default 10)\n\nResponse fields to show the user:\n\ndata[].locationId — Store ID (use for product pricing)\ndata[].name — Store name\ndata[].address.addressLine1, city, state, zipCode\ndata[].phone — Phone number\ndata[].hours — Operating hours\nUser Authentication (for Cart & Profile)\n\nWhen the user wants to add items to their cart or view their profile, they need to authenticate with Kroger. This is a one-time browser flow.\n\nStep 1: Generate a session ID and send the login link\n\nGenerate a random hex session ID (16-32 characters) and present the login URL to the user as a clickable link:\n\nhttps://us-central1-krocli.cloudfunctions.net/authorize?session_id=SESSION_ID\n\n\nTell the user: \"Click this link to log in to your Kroger account. Once you see 'Login successful', come back here and let me know.\"\n\nStep 2: Poll for tokens\n\nAfter the user says they've logged in, poll for their tokens:\n\ncurl -s \"https://us-central1-krocli.cloudfunctions.net/tokenUser?session_id=SESSION_ID\"\n\nIf {\"status\": \"pending\"} with HTTP 202: user hasn't finished yet. Wait and retry.\nIf HTTP 200: tokens are returned. Cache access_token and refresh_token.\n{\n  \"access_token\": \"eyJ...\",\n  \"refresh_token\": \"abc...\",\n  \"expires_in\": 1800,\n  \"token_type\": \"bearer\"\n}\n\nStep 3: Use the user token\n\nThe user token is needed for cart and profile endpoints.\n\nAdding to Cart\n\nRequires user token from authentication above.\n\ncurl -s -X PUT \\\n  -H \"Authorization: Bearer USER_ACCESS_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/cart/add\" \\\n  -d '{\"items\": [{\"upc\": \"0011110838049\", \"quantity\": 1}]}'\n\n\nRequest body:\n\n{\n  \"items\": [\n    {\"upc\": \"PRODUCT_ID\", \"quantity\": 1}\n  ]\n}\n\n\nHTTP 204 means success (no response body).\n\nViewing Profile\n\nRequires user token.\n\ncurl -s -H \"Authorization: Bearer USER_ACCESS_TOKEN\" \\\n  -H \"Accept: application/json\" \\\n  \"https://api.kroger.com/v1/identity/profile\"\n\nRefreshing an Expired User Token\n\nIf a user token returns 401, refresh it:\n\ncurl -s -X POST \\\n  -H \"Content-Type: application/json\" \\\n  \"https://us-central1-krocli.cloudfunctions.net/tokenRefresh\" \\\n  -d '{\"refresh_token\": \"REFRESH_TOKEN\"}'\n\n\nResponse includes new access_token and refresh_token. Cache both.\n\nToken Management Summary\nToken\tHow to get\tExpires\tRefresh\nClient\tPOST /tokenClient\t30 min\tJust request a new one\nUser\tBrowser login flow\t30 min\tPOST /tokenRefresh with refresh_token\nError Handling\nHTTP Status\tMeaning\tAction\n401\tToken expired\tRefresh or re-obtain token\n403\tForbidden\tToken lacks required scope\n429\tRate limited\tWait and retry\n400\tBad request\tCheck parameters\nTypical Workflows\n\"Search for milk near me\"\nGet client token via POST /tokenClient\nAsk user for ZIP code (or use a previously known one)\nFind nearest store via locations API\nSearch products with filter.locationId for local pricing\n\"Add bananas to my Kroger cart\"\nCheck if user token is cached; if not, start login flow\nSearch for \"bananas\" to get the UPC\nConfirm product with user\nPUT /cart/add with the UPC\n\"What Kroger stores are near 90210?\"\nGet client token\nSearch locations with filter.zipCode.near=90210\nFormat results with name, address, hours\nToken Persistence\n\nAfter a successful user login, save the refresh token and preferred ZIP code to your long-term memory so the user doesn't have to log in again next session.\n\nAfter login, remember:\n\nkroger_refresh_token: the refresh_token from the login flow\nkroger_zip_code: the user's preferred ZIP code (if provided)\nkroger_store_id: the user's preferred store locationId (if identified)\n\nAt the start of a session, check your memory for a saved kroger_refresh_token. If found:\n\nCall POST /tokenRefresh with the saved refresh_token\nIf it succeeds, use the new access_token — no login needed\nIf it fails (e.g. token revoked), clear the saved token and start a fresh login flow\n\nImportant: Only save the refresh_token, never the access_token (it expires in 30 minutes and is useless to persist).\n\nSelf-Hosting the Proxy\n\nIf you prefer not to use the hosted proxy, you can run your own. The full source is in the krocli repo under firebase/.\n\nOption 1: Deploy your own Firebase proxy\nCreate a Kroger developer app at developer.kroger.com\nScopes: product.compact, cart.basic:write, profile.compact\nRedirect URI: https://YOUR-PROJECT.cloudfunctions.net/callback\nClone the repo and set up Firebase:\ngit clone https://github.com/BLANXLAIT/krocli.git\ncd krocli/firebase\nfirebase init\nfirebase functions:secrets:set KROGER_CLIENT_ID\nfirebase functions:secrets:set KROGER_CLIENT_SECRET\n\nUpdate CALLBACK_URL in callback.ts and authorize.ts to point to your project\nDeploy:\nfirebase deploy --only functions,firestore:rules\n\nReplace all us-central1-krocli.cloudfunctions.net URLs in this skill with your own project URL\nOption 2: Use the krocli CLI directly (no proxy at all)\n\nIf you have Go installed, you can skip the proxy entirely:\n\ngo install github.com/blanxlait/krocli/cmd/krocli@latest\nkrocli auth credentials set /path/to/your/kroger-creds.json\nkrocli products search --term \"milk\"\nkrocli auth login   # browser OAuth, tokens stored in OS keyring\nkrocli cart add --upc 0011110838049\n\n\nIn this mode, all API calls go directly to api.kroger.com using your own credentials. No proxy involved. Tokens are stored locally in your OS keyring."
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/niemesrw/supermarket",
    "publisherUrl": "https://clawhub.ai/niemesrw/supermarket",
    "owner": "niemesrw",
    "version": "1.1.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/supermarket",
    "downloadUrl": "https://openagent3.xyz/downloads/supermarket",
    "agentUrl": "https://openagent3.xyz/skills/supermarket/agent",
    "manifestUrl": "https://openagent3.xyz/skills/supermarket/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/supermarket/agent.md"
  }
}