hermes-shop

/home/avalon/.hermes/skills/software-development/hermes-shop/SKILL.md · raw

Hermes Shop

Overview

Hermes Shop is a standalone shop app that Hermes can operate conversationally. It should help a user create products, edit products, upload product images, configure site copy, and manage per-shop Stripe checkout plus Shippo shipping/labels.

Important reference:

Current test deployment:

This skill is for operating Hermes Shop directly and for shaping the future Hermes Spawn optional shop add-on.

Conversational Rule

Be short and practical. If the user did not provide enough information, ask only for the missing fields needed for the next action. For setup/onboarding flows, use one clear next step at a time and avoid long explanatory checklists unless Alex asks for a plan.

Good:

I can add it. I need the product name, price, and whether it ships.

Good for Stripe:

I can connect Stripe. I need the Stripe account or permission to start a new Connect onboarding link.

Bad:

To create a comprehensive commerce object, please provide...

Product Model

A product can include:

UI rule: product cards must expose readable model details in the app, not only JSON/API output. At minimum show type, status, SKU, inventory, Stripe product/price state, Shippo state, fulfillment state, and optional raw JSON.

Required Fields by Action

Create simple draft product

Need:

If missing, ask:

What should I call it, and what price should it be?

Publish / activate product

Need:

If missing, ask one compact question listing only missing pieces.

Upload product image

Need:

Use:

curl -fsS -X POST http://127.0.0.1:4039/api/products/<id>/images \
  -H 'Content-Type: application/json' \
  --data-binary '{"dataUrl":"data:image/jpeg;base64,...","alt":"Front of product"}'

Edit product info

Need:

Use PUT /api/products/:id with only changed fields.

API Quick Reference

GET    /api/health
GET    /api/shop
GET    /api/products
GET    /api/products/:id
PUT    /api/site
GET    /api/stripe/config
PUT    /api/stripe/config
POST   /api/stripe/onboarding-link
POST   /api/products
PUT    /api/products/:id
DELETE /api/products/:id
POST   /api/products/:id/images

Base URL:

http://127.0.0.1:4039

Recipes

Inspect current shop

curl -fsS http://127.0.0.1:4039/api/shop | jq .

Create or update a product

curl -fsS -X POST http://127.0.0.1:4039/api/products \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "title":"Example Product",
    "type":"physical",
    "status":"draft",
    "priceCents":2500,
    "currency":"USD",
    "inventory":5,
    "shipping":{"requiresShipping":true,"weightValue":8,"weightUnit":"oz"}
  }' | jq .product

Archive a product

curl -fsS -X PUT http://127.0.0.1:4039/api/products/<id> \
  -H 'Content-Type: application/json' \
  --data-binary '{"status":"archived"}' | jq .product

Update site config

curl -fsS -X PUT http://127.0.0.1:4039/api/site \
  -H 'Content-Type: application/json' \
  --data-binary '{"headline":"New headline","statusText":"Live"}' | jq .site

Site Hero / Storefront Copy

The storefront hero is intentionally minimal and image-led. Site config supports:

Current frontend fallback order for the hero background:

  1. site.heroImage
  2. first available product primary image
  3. /shop-hero.svg

For “clean up the hero” requests, prefer one big background image, a short eyebrow/title, and a single product-scroll CTA. Avoid restoring multiple parallel CTAs or verbose descriptive subcopy in the hero unless asked. If Alex asks for “featured product” language, set the hero title to a concise product feature label such as Feature product one instead of repeating Hermes Shop.

Shop Navigation and Modal UI Pattern

Hermes Shop should separate customer-facing browsing from operator/configuration screens:

Reusable modal direction:

Performance and motion rules for reusable overlays:

Product grid sizing rules:

Stripe Direction

Stripe is a payment processor, not the catalog source of truth. Each Hermes Shop gets its own Stripe configuration under integrations.stripe; never treat Stripe as one global account for all tenant shops.

Current config operations:

curl -fsS http://127.0.0.1:4039/api/stripe/config | jq .

curl -fsS -X PUT http://127.0.0.1:4039/api/stripe/config \
  -H 'Content-Type: application/json' \
  --data-binary '{"mode":"test","businessName":"Example Shop","accountId":"acct_...","publishableKey":"pk_test_...","onboardingComplete":true}' | jq .

The UI has a Stripe onboarding panel. Stripe Connect Standard OAuth is wired through POST /api/stripe/onboarding-link and GET /api/stripe/oauth/callback. It requires platform env vars STRIPE_SECRET_KEY and STRIPE_CONNECT_CLIENT_ID (or STRIPE_CLIENT_ID).

Current live operations when env is configured:

Do not claim live checkout is enabled unless the Stripe account is connected and a checkout/session endpoint is verified.

Shippo Direction

Shippo handles shipping rates, labels, and tracking.

Planned operations:

For physical products, ask for package weight/dimensions before enabling shipping automation.

Spawn Add-on Direction

When this becomes a Spawn add-on:

  1. Provision a shop per tenant or a multi-tenant shop service.
  2. Seed site config from tenant name/brand.
  3. Give tenant Hermes this skill with its own base URL/data path.
  4. Keep shop app separate from the Spawn control plane UI.
  5. Store provider secrets in tenant env/config, not in product JSON.
  6. Let Hermes manage catalog and site config through APIs.

Scoped Spawn Broker Artifact

When packaging a standalone Hermes Shop build for the scoped Spawn deployment broker:

  1. Put the compiled dist/, tenant data/shop.json, product uploads, and a dependency-free server.js at the artifact root.
  2. The broker starts exactly node server.js; if server.js uses ESM imports, include a root package.json with {"private":true,"type":"module"}.
  3. Include a root deployment-manifest.json with all required identity/runtime fields:
{
  "tenantId": "tenant-id",
  "appName": "shop-app-name",
  "runtime": "node",
  "start": "node server.js",
  "healthPath": "/healthz",
  "hostnames": ["shop.example.com"]
}
  1. The submit request needs matching appName, artifact path, SHA-256, verification.healthPath, and requested hostnames. Manifest hostnames may be a superset, but every requested hostname must be declared.
  2. Verify the checksum after copying the archive into the tenant container, then submit from inside the tenant with /data/hermes/bin/spawn-deploy <request.json>.
  3. A successful application deployment may return dns_pending; that means PM2/local nginx are live but authoritative DNS/TLS is not ready. Verify localHealth, every localNginx result, PM2 status, and authoritative DNS separately.

Build / Deploy

cd /home/avalon/apps/hermes-shop
npm run build
pm2 restart /home/avalon/apps/ecosystem.config.js --only hermes-shop --update-env
pm2 save
npm run smoke
curl -fsS https://shop.apps.poofc.com/api/health

Pitfall: restarting by bare PM2 process name (pm2 restart hermes-shop --update-env) can pick up the caller's current environment instead of the ecosystem file and may drop the configured PORT=4039. Use the ecosystem restart form above for deploys.

Verification Checklist