Files
zeekay b4f8d7b2f4 feat(shopify): Hanzo AI for Shopify — embedded admin app on the shared foundation
Add packages/shopify (@hanzo/shopify): a Shopify embedded admin app that puts
Hanzo AI over the store as system of record.

- Product content: generate/rewrite descriptions + SEO title/meta from product
  attributes, then write back via the productUpdate mutation (only changed fields).
- Orders/support: summarize an order, draft a customer reply, extract issues.
- Ask: freeform question over a product or order, grounded in its data.

Server (src/server, holds the only secrets):
- oauth.ts   Shopify OAuth request shaping + OAuth-callback HMAC verify (hex over
             Shopify-canonical URLSearchParams form) + state (CSRF) check.
- shopify-api.ts  Admin GraphQL wrappers (getProduct/getOrder/updateProduct) —
                  pure request shaping + parsing + productUpdate userErrors.
- hanzo.ts   thin over the PUBLISHED @hanzo/ai createAiClient; product/order
             context assembly + prompt building. No transport reimplemented.
- actions.ts product + order AI action catalogs, one prompt each over ask.
- webhooks.ts  webhook HMAC verify (base64 over RAW body) + topic routing
               (orders/create, app/uninstalled, the 3 GDPR topics).
- server.ts  OAuth + /v1/* proxy the frontend calls + /webhooks. HMAC verified
             before any param/body is trusted; shop validated to *.myshopify.com.

Frontend (src/app): Polaris + App Bridge React panel — api.ts (proxy client,
no secrets), context.ts (launch context → GID), session-fetch.ts (App Bridge
session-token fetch), App/Assistant/main. App Bridge loaded from Shopify CDN;
public API key stamped into the app, secret never bundled.

Plus shopify.app.toml, an admin-link extension, build.js (esbuild: app bundle +
Node server), tsconfig, vitest config, README. 108 vitest tests (pure), tsc
--noEmit clean, build green. Model calls via @hanzo/ai to api.hanzo.ai/v1 only.

Register packages/shopify in pnpm-workspace.yaml.
2026-07-03 20:53:10 -07:00

24 lines
998 B
TOML

# Admin link extension — adds "Hanzo AI" to the product and order detail pages so
# a merchant opens the assistant with that resource already in context. This is
# an admin *link* (the simplest, config-only surface): it deep-links the embedded
# app with ?resource=&id=, which the app reads via parseLaunchContext and jumps
# straight to. No JS bundle to build — the target is the embedded app itself.
# Docs: shopify.dev/docs/apps/build/admin/actions-blocks/build-admin-action
api_version = "2025-01"
[[extensions]]
name = "Hanzo AI"
handle = "hanzo-ai-assistant"
type = "admin_link"
# On a product page → open the app on the Products tab with that product.
[[extensions.targeting]]
target = "admin.product-details.action.link"
url = "app://?resource=product&id={{ resource.id }}"
# On an order page → open the app on the Orders tab with that order.
[[extensions.targeting]]
target = "admin.order-details.action.link"
url = "app://?resource=order&id={{ resource.id }}"