[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GEVDSD2H0HPXG3V1D3SHTV":3,"skill-same:01M6GEVDSD2H0HPXG3V1D3SHTV":99},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":77,"commitSha":78,"skillDirectory":79,"forksCount":80,"repositoryHtmlUrl":81,"repositoryHomepageUrl":6,"ownerHtmlUrl":82,"ownerBlogUrl":6,"ownerDescription":83,"updatedAt":84,"install":85,"resources":98},"01M6GEVDSD2H0HPXG3V1D3SHTV","shopify",null,"Shopify Admin & Storefront GraphQL APIs via curl. Products, orders, customers, inventory, metafields.","zapabob\u002FSkills","zapabob","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F130830376?v=4","01M6DBMYZAGRTFQDSQYW3W764P","峯岸 亮","01M6DBMZ3GKDSJ01NZ9XTZD7JD",2,"MIT","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Farchive\u002Fskill-md-reviewed\u002Fsha256\u002Fce\u002Fce43ba40d2935d29c70093f1751b412468251ccde7fabc28356ef951080a8473\u002FSKILL.md",[],[5,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"community","my","you","Custom Domain","commerce","e-commerce","apps","app","token","orders","create","default","airtable","subdomain","install","access","api","credentials","inventory","2026-11-10 10:12:30",false,"---\r\nname: shopify\r\ndescription: Shopify Admin & Storefront GraphQL APIs via curl. Products, orders, customers, inventory, metafields.\r\nversion: 1.0.0\r\nauthor: community\r\nlicense: MIT\r\nplatforms: [linux, macos, windows]\r\nprerequisites:\r\n  env_vars: [SHOPIFY_ACCESS_TOKEN, SHOPIFY_STORE_DOMAIN]\r\n  commands: [curl, jq]\r\nrequired_environment_variables:\r\n  - name: SHOPIFY_ACCESS_TOKEN\r\n    prompt: Shopify Admin API access token (starts with shpat_)\r\n    help: \"Shopify admin → Settings → Apps and sales channels → Develop apps → Create an app → API credentials. Token shown ONCE on install.\"\r\n  - name: SHOPIFY_STORE_DOMAIN\r\n    prompt: Your shop subdomain without protocol (e.g. my-store.myshopify.com)\r\n    help: \"The permanent myshopify.com domain, not your custom domain.\"\r\n  - name: SHOPIFY_API_VERSION\r\n    prompt: Shopify API version (default 2026-01)\r\n    help: \"Stable quarterly version. Override if you need an older one.\"\r\nmetadata:\r\n  hermes:\r\n    tags: [Shopify, E-commerce, Commerce, API, GraphQL]\r\n    related_skills: [airtable, xurl]\r\n    homepage: https:\u002F\u002Fshopify.dev\u002Fdocs\u002Fapi\u002Fadmin-graphql\r\n---\r\n\r\n# Shopify — Admin & Storefront GraphQL APIs\r\n\r\nWork with Shopify stores directly through `curl`: list products, manage inventory, pull orders, update customers, read metafields. No SDK, no app framework — just the GraphQL endpoint and a custom-app access token.\r\n\r\nThe REST Admin API is legacy since 2024-04 and only receives security fixes. **Use GraphQL Admin** for all admin work. Use **Storefront GraphQL** for read-only customer-facing queries (products, collections, cart).\r\n\r\n## Prerequisites\r\n\r\n1. In Shopify admin: **Settings → Apps and sales channels → Develop apps → Create an app**.\r\n2. Click **Configure Admin API scopes**, select what you need (examples below), save.\r\n3. **Install app** → the Admin API access token appears ONCE. Copy it immediately — Shopify will never show it again. Tokens start with `shpat_`.\r\n4. Save to `~\u002F.hermes\u002F.env`:\r\n   ```\r\n   SHOPIFY_ACCESS_TOKEN=[REDACTED]\r\n   SHOPIFY_STORE_DOMAIN=my-store.myshopify.com\r\n   SHOPIFY_API_VERSION=2026-01\r\n   ```\r\n\r\n> **Heads up:** As of January 1, 2026, new \"legacy custom apps\" created in the Shopify admin are gone. New setups should use the **Dev Dashboard** (`shopify.dev\u002Fdocs\u002Fapps\u002Fbuild\u002Fdev-dashboard`). Existing admin-created apps keep working. If the user's shop has no existing custom app and it's after 2026-01-01, direct them to Dev Dashboard instead of the admin flow.\r\n\r\nCommon scopes by task:\r\n- Products \u002F collections: `read_products`, `write_products`\r\n- Inventory: `read_inventory`, `write_inventory`, `read_locations`\r\n- Orders: `read_orders`, `write_orders` (30 most recent without `read_all_orders`)\r\n- Customers: `read_customers`, `write_customers`\r\n- Draft orders: `read_draft_orders`, `write_draft_orders`\r\n- Fulfillments: `read_fulfillments`, `write_fulfillments`\r\n- Metafields \u002F metaobjects: covered by the matching resource scopes\r\n\r\n## API Basics\r\n\r\n- **Endpoint:** `https:\u002F\u002F$SHOPIFY_STORE_DOMAIN\u002Fadmin\u002Fapi\u002F$SHOPIFY_API_VERSION\u002Fgraphql.json`\r\n- **Auth header:** `X-Shopify-Access-Token:[REDACTED] (NOT `Authorization: Bearer`)\r\n- **Method:** always `POST`, always `Content-Type: application\u002Fjson`, body is `{\"query\": \"...\", \"variables\": {...}}`\r\n- **HTTP 200 does not mean success.** GraphQL returns errors in a top-level `errors` array and per-field `userErrors`. Always check both.\r\n- **IDs are GID strings:** `gid:\u002F\u002Fshopify\u002FProduct\u002F10079467700516`, `gid:\u002F\u002Fshopify\u002FVariant\u002F...`, `gid:\u002F\u002Fshopify\u002FOrder\u002F...`. Pass these verbatim — don't strip the prefix.\r\n- **Rate limit:** calculated via query cost (leaky bucket). Each response has `extensions.cost` with `requestedQueryCost`, `actualQueryCost`, `throttleStatus.{currentlyAvailable, maximumAvailable, restoreRate}`. Back off when `currentlyAvailable` drops below your next query's cost. Standard shops = 100 points bucket, 50\u002Fs restore; Plus = 1000\u002F100.\r\n\r\nBase curl pattern (reusable):\r\n\r\n```bash\r\nshop_gql() {\r\n  local query=\"$1\"\r\n  local variables=\"${2:-{}}\"\r\n  curl -sS -X POST \\\r\n    \"https:\u002F\u002F${SHOPIFY_STORE_DOMAIN}\u002Fadmin\u002Fapi\u002F${SHOPIFY_API_VERSION:-2026-01}\u002Fgraphql.json\" \\\r\n    -H \"Content-Type: application\u002Fjson\" \\\r\n    -H \"X-Shopify-Access-Token:[REDACTED]\" \\\r\n    --data \"$(jq -nc --arg q \"$query\" --argjson v \"$variables\" '{query: $q, variables: $v}')\"\r\n}\r\n```\r\n\r\nPipe through `jq` for readable output. `-sS` keeps errors visible but hides the progress bar.\r\n\r\n## Discovery\r\n\r\n### Shop info + current API version\r\n```bash\r\nshop_gql '{ shop { name myshopifyDomain primaryDomain { url } currencyCode plan { displayName } } }' | jq\r\n```\r\n\r\n### List all supported API versions\r\n```bash\r\nshop_gql '{ publicApiVersions { handle supported } }' | jq '.data.publicApiVersions[] | select(.supported)'\r\n```\r\n\r\n## Products\r\n\r\n### Search products (first 20 matching query)\r\n```bash\r\nshop_gql '\r\nquery($q: String!) {\r\n  products(first: 20, query: $q) {\r\n    edges { node { id title handle status totalInventory variants(first: 5) { edges { node { id sku price inventoryQuantity } } } } }\r\n    pageInfo { hasNextPage endCursor }\r\n  }\r\n}' '{\"q\":\"hoodie status:active\"}' | jq\r\n```\r\n\r\nQuery syntax supports `title:`, `sku:`, `vendor:`, `product_type:`, `status:active`, `tag:`, `created_at:>2025-01-01`. Full grammar: https:\u002F\u002Fshopify.dev\u002Fdocs\u002Fapi\u002Fusage\u002Fsearch-syntax\r\n\r\n### Paginate products (cursor)\r\n```bash\r\nshop_gql '\r\nquery($cursor: String) {\r\n  products(first: 100, after: $cursor) {\r\n    edges { cursor node { id handle } }\r\n    pageInfo { hasNextPage endCursor }\r\n  }\r\n}' '{\"cursor\":null}'\r\n# subsequent calls: pass the previous endCursor\r\n```\r\n\r\n### Get a product with variants + metafields\r\n```bash\r\nshop_gql '\r\nquery($id: ID!) {\r\n  product(id: $id) {\r\n    id title handle descriptionHtml tags status\r\n    variants(first: 20) { edges { node { id sku price compareAtPrice inventoryQuantity selectedOptions { name value } } } }\r\n    metafields(first: 20) { edges { node { namespace key type value } } }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F10079467700516\"}' | jq\r\n```\r\n\r\n### Create a product with one variant\r\n```bash\r\nshop_gql '\r\nmutation($input: ProductCreateInput!) {\r\n  productCreate(product: $input) {\r\n    product { id handle }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"input\":{\"title\":\"Test Hoodie\",\"status\":\"DRAFT\",\"vendor\":\"Hermes\",\"productType\":\"Apparel\",\"tags\":[\"test\"]}}'\r\n```\r\n\r\nVariants now have their own mutations in recent versions:\r\n\r\n```bash\r\n# Add variants after creating the product\r\nshop_gql '\r\nmutation($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {\r\n  productVariantsBulkCreate(productId: $productId, variants: $variants) {\r\n    productVariants { id sku price }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"productId\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\",\"variants\":[{\"optionValues\":[{\"optionName\":\"Size\",\"name\":\"M\"}],\"price\":\"49.00\",\"inventoryItem\":{\"sku\":\"HD-M\",\"tracked\":true}}]}'\r\n```\r\n\r\n### Update price \u002F SKU\r\n```bash\r\nshop_gql '\r\nmutation($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {\r\n  productVariantsBulkUpdate(productId: $productId, variants: $variants) {\r\n    productVariants { id sku price }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"productId\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\",\"variants\":[{\"id\":\"gid:\u002F\u002Fshopify\u002FProductVariant\u002F...\",\"price\":\"55.00\"}]}'\r\n```\r\n\r\n## Orders\r\n\r\n### List recent orders (last 30 by default without `read_all_orders`)\r\n```bash\r\nshop_gql '\r\n{\r\n  orders(first: 20, reverse: true, query: \"financial_status:paid\") {\r\n    edges { node {\r\n      id name createdAt displayFinancialStatus displayFulfillmentStatus\r\n      totalPriceSet { shopMoney { amount currencyCode } }\r\n      customer { id displayName email }\r\n      lineItems(first: 10) { edges { node { title quantity sku } } }\r\n    } }\r\n  }\r\n}' | jq\r\n```\r\n\r\nUseful order query filters: `financial_status:paid|pending|refunded`, `fulfillment_status:unfulfilled|fulfilled`, `created_at:>2025-01-01`, `tag:gift`, `email:foo@example.com`.\r\n\r\n### Fetch a single order with shipping address\r\n```bash\r\nshop_gql '\r\nquery($id: ID!) {\r\n  order(id: $id) {\r\n    id name email\r\n    shippingAddress { name address1 address2 city province country zip phone }\r\n    lineItems(first: 50) { edges { node { title quantity variant { sku } originalUnitPriceSet { shopMoney { amount currencyCode } } } } }\r\n    transactions { id kind status amountSet { shopMoney { amount currencyCode } } }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FOrder\u002F....\"}' | jq\r\n```\r\n\r\n## Customers\r\n\r\n```bash\r\n# Search\r\nshop_gql '\r\n{\r\n  customers(first: 10, query: \"email:*@example.com\") {\r\n    edges { node { id email displayName numberOfOrders amountSpent { amount currencyCode } } }\r\n  }\r\n}'\r\n\r\n# Create\r\nshop_gql '\r\nmutation($input: CustomerInput!) {\r\n  customerCreate(input: $input) {\r\n    customer { id email }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"input\":{\"email\":\"test@example.com\",\"firstName\":\"Test\",\"lastName\":\"User\",\"tags\":[\"api-created\"]}}'\r\n```\r\n\r\n## Inventory\r\n\r\nInventory lives on **inventory items** tied to variants, quantities tracked per **location**.\r\n\r\n```bash\r\n# Get inventory for a variant across all locations\r\nshop_gql '\r\nquery($id: ID!) {\r\n  productVariant(id: $id) {\r\n    id sku\r\n    inventoryItem {\r\n      id tracked\r\n      inventoryLevels(first: 10) {\r\n        edges { node { location { id name } quantities(names: [\"available\",\"on_hand\",\"committed\"]) { name quantity } } }\r\n      }\r\n    }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FProductVariant\u002F...\"}'\r\n```\r\n\r\nAdjust stock (delta) — uses `inventoryAdjustQuantities`:\r\n\r\n```bash\r\nshop_gql '\r\nmutation($input: InventoryAdjustQuantitiesInput!) {\r\n  inventoryAdjustQuantities(input: $input) {\r\n    inventoryAdjustmentGroup { reason changes { name delta } }\r\n    userErrors { field message }\r\n  }\r\n}' '{\r\n  \"input\": {\r\n    \"reason\": \"correction\",\r\n    \"name\": \"available\",\r\n    \"changes\": [{\"delta\": 5, \"inventoryItemId\": \"gid:\u002F\u002Fshopify\u002FInventoryItem\u002F...\", \"locationId\": \"gid:\u002F\u002Fshopify\u002FLocation\u002F...\"}]\r\n  }\r\n}'\r\n```\r\n\r\nSet absolute stock (not delta) — `inventorySetQuantities`:\r\n\r\n```bash\r\nshop_gql '\r\nmutation($input: InventorySetQuantitiesInput!) {\r\n  inventorySetQuantities(input: $input) {\r\n    inventoryAdjustmentGroup { id }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"input\":{\"reason\":\"correction\",\"name\":\"available\",\"ignoreCompareQuantity\":true,\"quantities\":[{\"inventoryItemId\":\"gid:\u002F\u002Fshopify\u002FInventoryItem\u002F...\",\"locationId\":\"gid:\u002F\u002Fshopify\u002FLocation\u002F...\",\"quantity\":100}]}}'\r\n```\r\n\r\n## Metafields & Metaobjects\r\n\r\nMetafields attach custom data to resources (products, customers, orders, shop).\r\n\r\n```bash\r\n# Read\r\nshop_gql '\r\nquery($id: ID!) {\r\n  product(id: $id) {\r\n    metafields(first: 10, namespace: \"custom\") {\r\n      edges { node { key type value } }\r\n    }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\"}'\r\n\r\n# Write (works for any owner type)\r\nshop_gql '\r\nmutation($metafields: [MetafieldsSetInput!]!) {\r\n  metafieldsSet(metafields: $metafields) {\r\n    metafields { id key namespace }\r\n    userErrors { field message code }\r\n  }\r\n}' '{\"metafields\":[{\"ownerId\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\",\"namespace\":\"custom\",\"key\":\"care_instructions\",\"type\":\"multi_line_text_field\",\"value\":\"Wash cold. Tumble dry low.\"}]}'\r\n```\r\n\r\n## Storefront API (public read-only)\r\n\r\nDifferent endpoint, different token, used for customer-facing apps\u002Fhydrogen-style headless setups. Headers differ:\r\n\r\n- **Endpoint:** `https:\u002F\u002F$SHOPIFY_STORE_DOMAIN\u002Fapi\u002F$SHOPIFY_API_VERSION\u002Fgraphql.json`\r\n- **Auth header (public):** `X-Shopify-Storefront-Access-Token: \u003Cpublic token>` — embeddable in browser\r\n- **Auth header (private):** `Shopify-Storefront-Private-Token: \u003Cprivate token>` — server-only\r\n\r\n```bash\r\ncurl -sS -X POST \\\r\n  \"https:\u002F\u002F${SHOPIFY_STORE_DOMAIN}\u002Fapi\u002F${SHOPIFY_API_VERSION:-2026-01}\u002Fgraphql.json\" \\\r\n  -H \"Content-Type: application\u002Fjson\" \\\r\n  -H \"X-Shopify-Storefront-Access-Token:[REDACTED]\" \\\r\n  -d '{\"query\":\"{ shop { name } products(first: 5) { edges { node { id title handle } } } }\"}' | jq\r\n```\r\n\r\n## Bulk Operations\r\n\r\nFor dumps larger than rate limits allow (full product catalog, all orders for a year):\r\n\r\n```bash\r\n# 1. Start bulk query\r\nshop_gql '\r\nmutation {\r\n  bulkOperationRunQuery(query: \"\"\"\r\n    { products { edges { node { id title handle variants { edges { node { sku price } } } } } } }\r\n  \"\"\") {\r\n    bulkOperation { id status }\r\n    userErrors { field message }\r\n  }\r\n}'\r\n\r\n# 2. Poll status\r\nshop_gql '{ currentBulkOperation { id status errorCode objectCount fileSize url partialDataUrl } }'\r\n\r\n# 3. When status=COMPLETED, download the JSONL file\r\ncurl -sS \"$URL\" > products.jsonl\r\n```\r\n\r\nEach JSONL line is a node, and nested connections are emitted as separate lines with `__parentId`. Reassemble client-side if needed.\r\n\r\n## Webhooks\r\n\r\nSubscribe to events so you don't have to poll:\r\n\r\n```bash\r\nshop_gql '\r\nmutation($topic: WebhookSubscriptionTopic!, $sub: WebhookSubscriptionInput!) {\r\n  webhookSubscriptionCreate(topic: $topic, webhookSubscription: $sub) {\r\n    webhookSubscription { id topic endpoint { __typename ... on WebhookHttpEndpoint { callbackUrl } } }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"topic\":\"ORDERS_CREATE\",\"sub\":{\"callbackUrl\":\"https:\u002F\u002Fexample.com\u002Fwebhook\",\"format\":\"JSON\"}}'\r\n```\r\n\r\nVerify incoming webhook HMAC using the app's client secret (not the access token):\r\n\r\n```bash\r\necho -n \"$REQUEST_BODY\" | openssl dgst -sha256 -hmac \"$APP_SECRET\" -binary | base64\r\n# Compare to X-Shopify-Hmac-Sha256 header\r\n```\r\n\r\n## Pitfalls\r\n\r\n- **REST endpoints still exist but are frozen.** Don't write new integrations against `\u002Fadmin\u002Fapi\u002F...\u002Fproducts.json`. Use GraphQL.\r\n- **Token format check.** Admin tokens start with `shpat_`. Storefront public tokens with `shpua_`. If you have one and the wrong header, every request returns 401 without a useful error body.\r\n- **403 with a valid token = missing scope.** Shopify returns `{\"errors\":[{\"message\":\"Access denied for ...\"}]}`. Re-configure Admin API scopes on the app, then reinstall to regenerate the token.\r\n- **`userErrors` is empty != success.** Also check `data.\u003Cmutation>.\u003Cresource>` is non-null. Some failures populate neither — inspect the whole response.\r\n- **GID vs numeric ID.** Legacy REST gave numeric IDs; GraphQL wants full GID strings. To convert: `gid:\u002F\u002Fshopify\u002FProduct\u002F\u003Cnumeric>`.\r\n- **Rate limit surprise.** A single `products(first: 250)` with deep nesting can cost 1000+ points and throttle immediately on a standard-plan shop. Start narrow, read `extensions.cost`, adjust.\r\n- **Pagination order.** `products(first: N, reverse: true)` sorts by `id DESC`, not `created_at`. Use `sortKey: CREATED_AT, reverse: true` for \"newest first.\"\r\n- **`read_all_orders` for historical data.** Without it, `orders(...)` silently caps at the 60-day window. You won't get an error, just fewer results than expected. For Shopify Plus merchants with many orders, request this scope via the app's protected-data settings.\r\n- **Currencies are strings.** Amounts come back as `\"49.00\"` not `49.0`. Don't `jq tonumber` blindly if you care about zero-padding.\r\n- **Multi-currency Money fields** have `shopMoney` (store's currency) AND `presentmentMoney` (customer's). Pick one consistently.\r\n\r\n## Safety\r\n\r\nMutations in Shopify are real — they create products, charge refunds, cancel orders, ship fulfillments. Before running `productDelete`, `orderCancel`, `refundCreate`, or any bulk mutation: state clearly what the change is, on which shop, and confirm with the user. There is no staging clone of production data unless the user has a separate dev store.\r\n","# Shopify — Admin & Storefront GraphQL APIs\r\n\r\nWork with Shopify stores directly through `curl`: list products, manage inventory, pull orders, update customers, read metafields. No SDK, no app framework — just the GraphQL endpoint and a custom-app access token.\r\n\r\nThe REST Admin API is legacy since 2024-04 and only receives security fixes. **Use GraphQL Admin** for all admin work. Use **Storefront GraphQL** for read-only customer-facing queries (products, collections, cart).\r\n\r\n## Prerequisites\r\n\r\n1. In Shopify admin: **Settings → Apps and sales channels → Develop apps → Create an app**.\r\n2. Click **Configure Admin API scopes**, select what you need (examples below), save.\r\n3. **Install app** → the Admin API access token appears ONCE. Copy it immediately — Shopify will never show it again. Tokens start with `shpat_`.\r\n4. Save to `~\u002F.hermes\u002F.env`:\r\n   ```\r\n   SHOPIFY_ACCESS_TOKEN=[REDACTED]\r\n   SHOPIFY_STORE_DOMAIN=my-store.myshopify.com\r\n   SHOPIFY_API_VERSION=2026-01\r\n   ```\r\n\r\n> **Heads up:** As of January 1, 2026, new \"legacy custom apps\" created in the Shopify admin are gone. New setups should use the **Dev Dashboard** (`shopify.dev\u002Fdocs\u002Fapps\u002Fbuild\u002Fdev-dashboard`). Existing admin-created apps keep working. If the user's shop has no existing custom app and it's after 2026-01-01, direct them to Dev Dashboard instead of the admin flow.\r\n\r\nCommon scopes by task:\r\n- Products \u002F collections: `read_products`, `write_products`\r\n- Inventory: `read_inventory`, `write_inventory`, `read_locations`\r\n- Orders: `read_orders`, `write_orders` (30 most recent without `read_all_orders`)\r\n- Customers: `read_customers`, `write_customers`\r\n- Draft orders: `read_draft_orders`, `write_draft_orders`\r\n- Fulfillments: `read_fulfillments`, `write_fulfillments`\r\n- Metafields \u002F metaobjects: covered by the matching resource scopes\r\n\r\n## API Basics\r\n\r\n- **Endpoint:** `https:\u002F\u002F$SHOPIFY_STORE_DOMAIN\u002Fadmin\u002Fapi\u002F$SHOPIFY_API_VERSION\u002Fgraphql.json`\r\n- **Auth header:** `X-Shopify-Access-Token:[REDACTED] (NOT `Authorization: Bearer`)\r\n- **Method:** always `POST`, always `Content-Type: application\u002Fjson`, body is `{\"query\": \"...\", \"variables\": {...}}`\r\n- **HTTP 200 does not mean success.** GraphQL returns errors in a top-level `errors` array and per-field `userErrors`. Always check both.\r\n- **IDs are GID strings:** `gid:\u002F\u002Fshopify\u002FProduct\u002F10079467700516`, `gid:\u002F\u002Fshopify\u002FVariant\u002F...`, `gid:\u002F\u002Fshopify\u002FOrder\u002F...`. Pass these verbatim — don't strip the prefix.\r\n- **Rate limit:** calculated via query cost (leaky bucket). Each response has `extensions.cost` with `requestedQueryCost`, `actualQueryCost`, `throttleStatus.{currentlyAvailable, maximumAvailable, restoreRate}`. Back off when `currentlyAvailable` drops below your next query's cost. Standard shops = 100 points bucket, 50\u002Fs restore; Plus = 1000\u002F100.\r\n\r\nBase curl pattern (reusable):\r\n\r\n```bash\r\nshop_gql() {\r\n  local query=\"$1\"\r\n  local variables=\"${2:-{}}\"\r\n  curl -sS -X POST \\\r\n    \"https:\u002F\u002F${SHOPIFY_STORE_DOMAIN}\u002Fadmin\u002Fapi\u002F${SHOPIFY_API_VERSION:-2026-01}\u002Fgraphql.json\" \\\r\n    -H \"Content-Type: application\u002Fjson\" \\\r\n    -H \"X-Shopify-Access-Token:[REDACTED]\" \\\r\n    --data \"$(jq -nc --arg q \"$query\" --argjson v \"$variables\" '{query: $q, variables: $v}')\"\r\n}\r\n```\r\n\r\nPipe through `jq` for readable output. `-sS` keeps errors visible but hides the progress bar.\r\n\r\n## Discovery\r\n\r\n### Shop info + current API version\r\n```bash\r\nshop_gql '{ shop { name myshopifyDomain primaryDomain { url } currencyCode plan { displayName } } }' | jq\r\n```\r\n\r\n### List all supported API versions\r\n```bash\r\nshop_gql '{ publicApiVersions { handle supported } }' | jq '.data.publicApiVersions[] | select(.supported)'\r\n```\r\n\r\n## Products\r\n\r\n### Search products (first 20 matching query)\r\n```bash\r\nshop_gql '\r\nquery($q: String!) {\r\n  products(first: 20, query: $q) {\r\n    edges { node { id title handle status totalInventory variants(first: 5) { edges { node { id sku price inventoryQuantity } } } } }\r\n    pageInfo { hasNextPage endCursor }\r\n  }\r\n}' '{\"q\":\"hoodie status:active\"}' | jq\r\n```\r\n\r\nQuery syntax supports `title:`, `sku:`, `vendor:`, `product_type:`, `status:active`, `tag:`, `created_at:>2025-01-01`. Full grammar: https:\u002F\u002Fshopify.dev\u002Fdocs\u002Fapi\u002Fusage\u002Fsearch-syntax\r\n\r\n### Paginate products (cursor)\r\n```bash\r\nshop_gql '\r\nquery($cursor: String) {\r\n  products(first: 100, after: $cursor) {\r\n    edges { cursor node { id handle } }\r\n    pageInfo { hasNextPage endCursor }\r\n  }\r\n}' '{\"cursor\":null}'\r\n# subsequent calls: pass the previous endCursor\r\n```\r\n\r\n### Get a product with variants + metafields\r\n```bash\r\nshop_gql '\r\nquery($id: ID!) {\r\n  product(id: $id) {\r\n    id title handle descriptionHtml tags status\r\n    variants(first: 20) { edges { node { id sku price compareAtPrice inventoryQuantity selectedOptions { name value } } } }\r\n    metafields(first: 20) { edges { node { namespace key type value } } }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F10079467700516\"}' | jq\r\n```\r\n\r\n### Create a product with one variant\r\n```bash\r\nshop_gql '\r\nmutation($input: ProductCreateInput!) {\r\n  productCreate(product: $input) {\r\n    product { id handle }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"input\":{\"title\":\"Test Hoodie\",\"status\":\"DRAFT\",\"vendor\":\"Hermes\",\"productType\":\"Apparel\",\"tags\":[\"test\"]}}'\r\n```\r\n\r\nVariants now have their own mutations in recent versions:\r\n\r\n```bash\r\n# Add variants after creating the product\r\nshop_gql '\r\nmutation($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {\r\n  productVariantsBulkCreate(productId: $productId, variants: $variants) {\r\n    productVariants { id sku price }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"productId\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\",\"variants\":[{\"optionValues\":[{\"optionName\":\"Size\",\"name\":\"M\"}],\"price\":\"49.00\",\"inventoryItem\":{\"sku\":\"HD-M\",\"tracked\":true}}]}'\r\n```\r\n\r\n### Update price \u002F SKU\r\n```bash\r\nshop_gql '\r\nmutation($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {\r\n  productVariantsBulkUpdate(productId: $productId, variants: $variants) {\r\n    productVariants { id sku price }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"productId\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\",\"variants\":[{\"id\":\"gid:\u002F\u002Fshopify\u002FProductVariant\u002F...\",\"price\":\"55.00\"}]}'\r\n```\r\n\r\n## Orders\r\n\r\n### List recent orders (last 30 by default without `read_all_orders`)\r\n```bash\r\nshop_gql '\r\n{\r\n  orders(first: 20, reverse: true, query: \"financial_status:paid\") {\r\n    edges { node {\r\n      id name createdAt displayFinancialStatus displayFulfillmentStatus\r\n      totalPriceSet { shopMoney { amount currencyCode } }\r\n      customer { id displayName email }\r\n      lineItems(first: 10) { edges { node { title quantity sku } } }\r\n    } }\r\n  }\r\n}' | jq\r\n```\r\n\r\nUseful order query filters: `financial_status:paid|pending|refunded`, `fulfillment_status:unfulfilled|fulfilled`, `created_at:>2025-01-01`, `tag:gift`, `email:foo@example.com`.\r\n\r\n### Fetch a single order with shipping address\r\n```bash\r\nshop_gql '\r\nquery($id: ID!) {\r\n  order(id: $id) {\r\n    id name email\r\n    shippingAddress { name address1 address2 city province country zip phone }\r\n    lineItems(first: 50) { edges { node { title quantity variant { sku } originalUnitPriceSet { shopMoney { amount currencyCode } } } } }\r\n    transactions { id kind status amountSet { shopMoney { amount currencyCode } } }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FOrder\u002F....\"}' | jq\r\n```\r\n\r\n## Customers\r\n\r\n```bash\r\n# Search\r\nshop_gql '\r\n{\r\n  customers(first: 10, query: \"email:*@example.com\") {\r\n    edges { node { id email displayName numberOfOrders amountSpent { amount currencyCode } } }\r\n  }\r\n}'\r\n\r\n# Create\r\nshop_gql '\r\nmutation($input: CustomerInput!) {\r\n  customerCreate(input: $input) {\r\n    customer { id email }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"input\":{\"email\":\"test@example.com\",\"firstName\":\"Test\",\"lastName\":\"User\",\"tags\":[\"api-created\"]}}'\r\n```\r\n\r\n## Inventory\r\n\r\nInventory lives on **inventory items** tied to variants, quantities tracked per **location**.\r\n\r\n```bash\r\n# Get inventory for a variant across all locations\r\nshop_gql '\r\nquery($id: ID!) {\r\n  productVariant(id: $id) {\r\n    id sku\r\n    inventoryItem {\r\n      id tracked\r\n      inventoryLevels(first: 10) {\r\n        edges { node { location { id name } quantities(names: [\"available\",\"on_hand\",\"committed\"]) { name quantity } } }\r\n      }\r\n    }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FProductVariant\u002F...\"}'\r\n```\r\n\r\nAdjust stock (delta) — uses `inventoryAdjustQuantities`:\r\n\r\n```bash\r\nshop_gql '\r\nmutation($input: InventoryAdjustQuantitiesInput!) {\r\n  inventoryAdjustQuantities(input: $input) {\r\n    inventoryAdjustmentGroup { reason changes { name delta } }\r\n    userErrors { field message }\r\n  }\r\n}' '{\r\n  \"input\": {\r\n    \"reason\": \"correction\",\r\n    \"name\": \"available\",\r\n    \"changes\": [{\"delta\": 5, \"inventoryItemId\": \"gid:\u002F\u002Fshopify\u002FInventoryItem\u002F...\", \"locationId\": \"gid:\u002F\u002Fshopify\u002FLocation\u002F...\"}]\r\n  }\r\n}'\r\n```\r\n\r\nSet absolute stock (not delta) — `inventorySetQuantities`:\r\n\r\n```bash\r\nshop_gql '\r\nmutation($input: InventorySetQuantitiesInput!) {\r\n  inventorySetQuantities(input: $input) {\r\n    inventoryAdjustmentGroup { id }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"input\":{\"reason\":\"correction\",\"name\":\"available\",\"ignoreCompareQuantity\":true,\"quantities\":[{\"inventoryItemId\":\"gid:\u002F\u002Fshopify\u002FInventoryItem\u002F...\",\"locationId\":\"gid:\u002F\u002Fshopify\u002FLocation\u002F...\",\"quantity\":100}]}}'\r\n```\r\n\r\n## Metafields & Metaobjects\r\n\r\nMetafields attach custom data to resources (products, customers, orders, shop).\r\n\r\n```bash\r\n# Read\r\nshop_gql '\r\nquery($id: ID!) {\r\n  product(id: $id) {\r\n    metafields(first: 10, namespace: \"custom\") {\r\n      edges { node { key type value } }\r\n    }\r\n  }\r\n}' '{\"id\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\"}'\r\n\r\n# Write (works for any owner type)\r\nshop_gql '\r\nmutation($metafields: [MetafieldsSetInput!]!) {\r\n  metafieldsSet(metafields: $metafields) {\r\n    metafields { id key namespace }\r\n    userErrors { field message code }\r\n  }\r\n}' '{\"metafields\":[{\"ownerId\":\"gid:\u002F\u002Fshopify\u002FProduct\u002F...\",\"namespace\":\"custom\",\"key\":\"care_instructions\",\"type\":\"multi_line_text_field\",\"value\":\"Wash cold. Tumble dry low.\"}]}'\r\n```\r\n\r\n## Storefront API (public read-only)\r\n\r\nDifferent endpoint, different token, used for customer-facing apps\u002Fhydrogen-style headless setups. Headers differ:\r\n\r\n- **Endpoint:** `https:\u002F\u002F$SHOPIFY_STORE_DOMAIN\u002Fapi\u002F$SHOPIFY_API_VERSION\u002Fgraphql.json`\r\n- **Auth header (public):** `X-Shopify-Storefront-Access-Token: \u003Cpublic token>` — embeddable in browser\r\n- **Auth header (private):** `Shopify-Storefront-Private-Token: \u003Cprivate token>` — server-only\r\n\r\n```bash\r\ncurl -sS -X POST \\\r\n  \"https:\u002F\u002F${SHOPIFY_STORE_DOMAIN}\u002Fapi\u002F${SHOPIFY_API_VERSION:-2026-01}\u002Fgraphql.json\" \\\r\n  -H \"Content-Type: application\u002Fjson\" \\\r\n  -H \"X-Shopify-Storefront-Access-Token:[REDACTED]\" \\\r\n  -d '{\"query\":\"{ shop { name } products(first: 5) { edges { node { id title handle } } } }\"}' | jq\r\n```\r\n\r\n## Bulk Operations\r\n\r\nFor dumps larger than rate limits allow (full product catalog, all orders for a year):\r\n\r\n```bash\r\n# 1. Start bulk query\r\nshop_gql '\r\nmutation {\r\n  bulkOperationRunQuery(query: \"\"\"\r\n    { products { edges { node { id title handle variants { edges { node { sku price } } } } } } }\r\n  \"\"\") {\r\n    bulkOperation { id status }\r\n    userErrors { field message }\r\n  }\r\n}'\r\n\r\n# 2. Poll status\r\nshop_gql '{ currentBulkOperation { id status errorCode objectCount fileSize url partialDataUrl } }'\r\n\r\n# 3. When status=COMPLETED, download the JSONL file\r\ncurl -sS \"$URL\" > products.jsonl\r\n```\r\n\r\nEach JSONL line is a node, and nested connections are emitted as separate lines with `__parentId`. Reassemble client-side if needed.\r\n\r\n## Webhooks\r\n\r\nSubscribe to events so you don't have to poll:\r\n\r\n```bash\r\nshop_gql '\r\nmutation($topic: WebhookSubscriptionTopic!, $sub: WebhookSubscriptionInput!) {\r\n  webhookSubscriptionCreate(topic: $topic, webhookSubscription: $sub) {\r\n    webhookSubscription { id topic endpoint { __typename ... on WebhookHttpEndpoint { callbackUrl } } }\r\n    userErrors { field message }\r\n  }\r\n}' '{\"topic\":\"ORDERS_CREATE\",\"sub\":{\"callbackUrl\":\"https:\u002F\u002Fexample.com\u002Fwebhook\",\"format\":\"JSON\"}}'\r\n```\r\n\r\nVerify incoming webhook HMAC using the app's client secret (not the access token):\r\n\r\n```bash\r\necho -n \"$REQUEST_BODY\" | openssl dgst -sha256 -hmac \"$APP_SECRET\" -binary | base64\r\n# Compare to X-Shopify-Hmac-Sha256 header\r\n```\r\n\r\n## Pitfalls\r\n\r\n- **REST endpoints still exist but are frozen.** Don't write new integrations against `\u002Fadmin\u002Fapi\u002F...\u002Fproducts.json`. Use GraphQL.\r\n- **Token format check.** Admin tokens start with `shpat_`. Storefront public tokens with `shpua_`. If you have one and the wrong header, every request returns 401 without a useful error body.\r\n- **403 with a valid token = missing scope.** Shopify returns `{\"errors\":[{\"message\":\"Access denied for ...\"}]}`. Re-configure Admin API scopes on the app, then reinstall to regenerate the token.\r\n- **`userErrors` is empty != success.** Also check `data.\u003Cmutation>.\u003Cresource>` is non-null. Some failures populate neither — inspect the whole response.\r\n- **GID vs numeric ID.** Legacy REST gave numeric IDs; GraphQL wants full GID strings. To convert: `gid:\u002F\u002Fshopify\u002FProduct\u002F\u003Cnumeric>`.\r\n- **Rate limit surprise.** A single `products(first: 250)` with deep nesting can cost 1000+ points and throttle immediately on a standard-plan shop. Start narrow, read `extensions.cost`, adjust.\r\n- **Pagination order.** `products(first: N, reverse: true)` sorts by `id DESC`, not `created_at`. Use `sortKey: CREATED_AT, reverse: true` for \"newest first.\"\r\n- **`read_all_orders` for historical data.** Without it, `orders(...)` silently caps at the 60-day window. You won't get an error, just fewer results than expected. For Shopify Plus merchants with many orders, request this scope via the app's protected-data settings.\r\n- **Currencies are strings.** Amounts come back as `\"49.00\"` not `49.0`. Don't `jq tonumber` blindly if you care about zero-padding.\r\n- **Multi-currency Money fields** have `shopMoney` (store's currency) AND `presentmentMoney` (customer's). Pick one consistently.\r\n\r\n## Safety\r\n\r\nMutations in Shopify are real — they create products, charge refunds, cancel orders, ship fulfillments. Before running `productDelete`, `orderCancel`, `refundCreate`, or any bulk mutation: state clearly what the change is, on which shop, and confirm with the user. There is no staging clone of production data unless the user has a separate dev store.\r\n",{"name":5,"author":19,"license":15,"version":43,"metadata":44,"platforms":55,"description":7,"prerequisites":59,"required_environment_variables":66},"1.0.0",{"hermes":45},{"tags":46,"homepage":52,"related_skills":53},[47,48,49,50,51],"Shopify","E-commerce","Commerce","API","GraphQL","https:\u002F\u002Fshopify.dev\u002Fdocs\u002Fapi\u002Fadmin-graphql",[31,54],"xurl",[56,57,58],"linux","macos","windows",{"commands":60,"env_vars":63},[61,62],"curl","jq",[64,65],"SHOPIFY_ACCESS_TOKEN","SHOPIFY_STORE_DOMAIN",[67,70,73],{"help":68,"name":64,"prompt":69},"Shopify admin → Settings → Apps and sales channels → Develop apps → Create an app → API credentials. Token shown ONCE on install.","Shopify Admin API access token (starts with shpat_)",{"help":71,"name":65,"prompt":72},"The permanent myshopify.com domain, not your custom domain.","Your shop subdomain without protocol (e.g. my-store.myshopify.com)",{"help":74,"name":75,"prompt":76},"Stable quarterly version. Override if you need an older one.","SHOPIFY_API_VERSION","Shopify API version (default 2026-01)","main","0d1434f89f4bc6b07e9d272accd8c1013768820f","archive\u002Fskill-md-reviewed\u002Fsha256\u002Fce\u002Fce43ba40d2935d29c70093f1751b412468251ccde7fabc28356ef951080a8473",0,"https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills","https:\u002F\u002Fgithub.com\u002Fzapabob","The Open University of JAPAN　2019-now\r\n\r\nTokyo University of Science　2007-2010","2026-10-26 16:29:01",{"source":8,"skillName":5,"commands":86,"prompt":96,"zipAvailable":97},[87,90,93],{"tool":88,"command":89},"npx","npx skills add zapabob\u002FSkills --skill shopify",{"tool":91,"command":92},"bunx","bunx skills add zapabob\u002FSkills --skill shopify",{"tool":94,"command":95},"pnpm","pnpm dlx skills add zapabob\u002FSkills --skill shopify","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Farchive\u002Fskill-md-reviewed\u002Fsha256\u002Fce\u002Fce43ba40d2935d29c70093f1751b412468251ccde7fabc28356ef951080a8473\u002FSKILL.md",true,[],[100,133,168,195,222,239],{"skillNo":101,"name":54,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":118,"publishedAt":38},"01M6GJTE1GESGGF9K028Y7753E","X\u002FTwitter via xurl CLI: post, search, DM, media, v2 API.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fxurl\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[105,110,113],{"categoryNo":106,"categoryName":107,"taxonomyType":108,"taxonomyTypeDesc":109},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":111,"categoryName":112,"taxonomyType":108,"taxonomyTypeDesc":109},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":114,"categoryName":115,"taxonomyType":116,"taxonomyTypeDesc":117},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[54,119,57,120,121,56,58,122,123,124,125,35,126,127,128,129,77,130,131,132],"openclaw","cli","github","official","search","https","social-media","Media","hermes","hermes agent","twitter","social","via","post",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":150,"publishedAt":38},"01M6GJT8S1PXQ8WPXT1HSNBWH2","writing-plans","Write implementation plans: bite-sized tasks, paths, code.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwriting-plans\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[139,142,145,146,147],{"categoryNo":140,"categoryName":141,"taxonomyType":108,"taxonomyTypeDesc":109},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":143,"categoryName":144,"taxonomyType":108,"taxonomyTypeDesc":109},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":111,"categoryName":112,"taxonomyType":108,"taxonomyTypeDesc":109},{"categoryNo":114,"categoryName":115,"taxonomyType":116,"taxonomyTypeDesc":117},{"categoryNo":148,"categoryName":149,"taxonomyType":116,"taxonomyTypeDesc":117},"01JBSEEDCAT000000000000036","内容创作者",[151,152,153,154,57,155,56,156,58,157,158,159,160,161,162,163,164,165,166,167],"writing","writing plans","plans","design","review","workflow","documentation","tasks","development","code","planning","code-review","subagent","write","superpowers","paths","test-driven-development",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":177,"publishedAt":38},"01M6GJST0H5X7WHBJ3BZK0DVKH","whisper","OpenAI's general-purpose speech recognition model. Supports 99 languages, transcription, translation to English, and language identification. Six model sizes from tiny (39M params) to large (1550M params). Use for speech-to-text, podcast transcription, or multilingual audio processing. Best for robust, multilingual ASR.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwhisper\u002Fvariants\u002Fhermes-agent-optional\u002FSKILL.md",[174],{"categoryNo":175,"categoryName":176,"taxonomyType":108,"taxonomyTypeDesc":109},"01JBSEEDCAT000000000000016","图像与多媒体",[170,57,56,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194],"openai","speech","multimodal","Transformers","ASR","Audio","text","model","speech recognition","use","general","multilingual","translation","english","identification","processing","Audio Processing",{"skillNo":196,"name":197,"nameZh":6,"description":198,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":199,"categories":200,"keywords":204,"publishedAt":38},"01M6GJSMRQ8EETZTYMG72P70EA","weights-and-biases","W&B: log ML experiments, sweeps, model registry, dashboards.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fweights-and-biases\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[201],{"categoryNo":202,"categoryName":203,"taxonomyType":108,"taxonomyTypeDesc":109},"01JBSEEDCAT000000000000013","分析与可视化",[205,57,206,207,58,208,209,210,211,212,213,185,214,215,216,217,218,219,220,221],"weights and biases","tensorflow","experiments","pytorch","visualization","registry","real-time","tuning","dashboards","experiment","log","time","Experiment Tracking","Model Registry","Hyperparameter Tuning","WandB","Real-Time Visualization",{"skillNo":223,"name":224,"nameZh":6,"description":225,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":226,"categories":227,"keywords":229,"publishedAt":38},"01M6GJS19KDPRY112JTR326S06","watchers","Poll RSS, JSON APIs, and GitHub with watermark dedup.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fwatchers\u002Fvariants\u002Fhermes-agent-optional\u002FSKILL.md",[228],{"categoryNo":111,"categoryName":112,"taxonomyType":108,"taxonomyTypeDesc":109},[224,57,230,121,56,231,232,233,234,235,236,127,128,237,238],"terminal","automation","http","monitoring","cron","json","rss","devops","with",{"skillNo":240,"name":241,"nameZh":6,"description":242,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":243,"categories":244,"keywords":247,"publishedAt":38},"01M6GJRHJD2A6Q830SWF9W48BC","serving-llms-vllm","vLLM: high-throughput LLM serving, OpenAI API, quantization.","https:\u002F\u002Fgithub.com\u002Fzapabob\u002FSkills\u002Fblob\u002Fmain\u002Fregistry\u002Fskills\u002Fvllm\u002Fvariants\u002Fhermes-agent\u002FSKILL.md",[245,246],{"categoryNo":106,"categoryName":107,"taxonomyType":108,"taxonomyTypeDesc":109},{"categoryNo":114,"categoryName":115,"taxonomyType":116,"taxonomyTypeDesc":117},[248,249,250,56,251,178,252,253,254,181,255,35,256,257,258,259,260,261,262,263],"llms","vLLM","serving llms vllm","research","openai api","tensor","Inference Serving","Production","llm serving","High Throughput","PagedAttention","Continuous Batching","Quantization","Tensor Parallelism","high-throughput","throughput"]