# Contributing to `@kody/shopify` This package is designed to be **forked**, then grown in your own account. The live `@kody/shopify` listing stays a shared starting point. ## Fork and run 1. Open https://kody.codes/@kody/shopify and fork it, or call `community_fork` with this listing id. 2. Review `src/lib/client.ts` (auth, host allowlist, retries) before you adopt the fork or approve secrets. 3. Publish your copy. 4. Save `shopifyClientId` + `shopifyClientSecret` (or `shopifyAdminAccessToken`) and approve `{shop}.myshopify.com`. 5. Import and call `./smoke-test` with `{ shop: "your-store" }` (static `kody:@` import) so `kody.secretMounts` / placeholders resolve in the package runtime. After fork, prefer your scoped import (`kody:@your-user/shopify/smoke-test`). ```ts import smokeTest from 'kody:@kody/shopify/smoke-test' export default async function main() { return await smokeTest({ shop: 'your-store' }) } ``` After the fork, optional defaults: ```ts import { setDefaultShop } from 'kody:@your-user/shopify/config' await setDefaultShop({ shop: 'your-store' }) ``` Do not call `setDefaultShop` against live `@kody/shopify`. That storage belongs to the platform package, not your shop. ## Authoring lane (maintainers / large edits) Coding agents with filesystem access should use the git lane: 1. `package_get_git_remote` for this package (`kody_id: "shopify"`, `package_scope: "kody"` for the platform copy). 2. Clone into `/tmp`, edit, test locally. 3. Commit and push. 4. `package_publish_external_push`. 5. `community_publish` only when the public snapshot should move. Prefer that loop over repeated `package_save` blobs. ## Add a domain module Keep new helpers thin. Copy an existing file such as `src/orders.ts`. 1. Add `src/your-resource.ts` with named functions and a default export. 2. Use `shopifyGraphql` / `shopifyRequestRaw` from `src/lib/client.ts`. Do not open a second fetch wrapper. 3. Accept `ShopifyClientOptions` (`shop`, `apiVersion`). 4. Project slim return objects. Do not dump raw Shopify payloads unless the export is an escape hatch. 5. Mutations default to `dryRun: true`. Require `dryRun: false` to write. 6. Register the export in `package.json#exports` and `src/index.ts`. 7. Document it in the README export table and `docs/domains.md`. 8. Add any new GraphQL field selections to `src/lib/fragments.ts` when they are reused. Escape hatch first: if the resource is uncommon, document a `./graphql` example instead of wrapping it. ## Local checks you can run without a shop `src/lib/shop.ts` exports `runShopHelperSelfCheck()`. `./smoke-test` always runs it. After you change shop/id/version parsing, invoke `./smoke-test` without credentials and confirm `{ ok: true, live: false }`. ## Secrets and hosts - Never echo resolvable `{{secret:name}}` placeholders into logs or returned strings. Mention them as `{{secret:}}` in prose. - Never persist exchanged access tokens in `packageStorage()`. - Keep requests on `{shop}.myshopify.com/admin/`. - New secrets should follow the existing names unless Shopify's contract changes. Update README setup URLs in the same commit. ## Style - TypeScript ESM, tab indentation, `.ts` import specifiers. - JSDoc on every exported function, with a short `@example`. - Exhaustive `switch` over unions uses a `never` default. - No inline imports. ## License MIT. Keep `package.json#license` as `MIT` and do not set `"private": true` if this copy should stay community-publishable.