# Agent Guide Read this file first. It tells you where to find context in this repo. ## Quick Reference | What you need | Where to look | |---|---| | What this repo does | [README.md](./README.md) | | How this repo is structured | [ARCHITECTURE.md](./ARCHITECTURE.md) | | How to build/test/run | [CONTRIBUTING.md](./CONTRIBUTING.md) | | Why decisions were made | [docs/ADRs/](./docs/ADRs/) | | Active specs/work | [docs/specs/](./docs/specs/) | | PR review rules | [.bito/guidelines/](./.bito/guidelines/) | ## Sharp Edges & Invariants - **Never change the dual-export pattern in `lib/index.ts`** without understanding the `cli-table3` / `esModuleInterop` constraint. The file exports via both `export default` and `module.exports = ...` simultaneously — this is intentional. See [ADR 001](./docs/ADRs/2024-04-01-tsup-dual-cjs-esm-build.md). - **Webhooks can only be imported to the `master` environment.** The `pushToSpace` task skips webhook creation for any non-master `environmentId` — this is a Contentful API constraint, not a bug. - **The default locale of the source and destination space must match.** `assertDefaultLocale` throws a hard error if they differ. Do not attempt to work around this — it is a fundamental Contentful space invariant. - **Tags are feature-gated.** If the destination space returns a 404 on `getTags`, `destinationData.tags` is deleted and all entity metadata is stripped by transformers. Never assume `destinationData.tags` is present. - **Do not run `npm install` with scripts enabled.** `.npmrc` sets `ignore-scripts=true` for security. This is intentional. - **`dist/` is generated — never hand-edit it.** Run `npm run build` to regenerate. `dist/` is committed only at release time via CI. - **Rate limit is enforced via `p-queue`.** All CMA calls go through `requestQueue`. Do not make direct `environment.*` or `space.*` calls outside the queue — this bypasses rate limiting and risks 429 errors. - **Import order matters in `pushToSpace`.** Locales → Content Types (published) → Editor Interfaces → Tags → Assets → Entries → Webhooks. This order is required by CMA API constraints (entries can't reference unpublished content types). Do not reorder task steps. - **Integration tests create real Contentful spaces.** They require org-level credentials (`MANAGEMENT_TOKEN`, `ORG_ID`) and will fail without them. Never run them without credentials set. ## Key Conventions - **Commit format:** [Conventional Commits](https://www.conventionalcommits.org/) — `type(scope): description`. `feat!` triggers a major release. - **Branch strategy:** `main` (production, auto-releases), `beta` (prerelease), feature branches from `main` - **Test location:** `test/unit/` mirrors `lib/`; `test/integration/` for end-to-end scenarios - **Module system:** Dual CJS (`dist/index.js`) + ESM (`dist/index.mjs`), built by tsup - **Build required before tests:** `npm run pretest` runs lint + build. Unit tests import from `lib/` via ts-jest; the binary uses `dist/`. ## Integration Points **Upstream (this repo consumes):** - `contentful-management` — CMA.js v12 (plain client) for all Contentful API operations - `contentful-batch-libs` — shared logging, listr task wrapper, proxy utilities, sequence header injection - Contentful Management API — target space for import operations **Downstream (consumes this repo):** - [`contentful-cli`](https://github.com/contentful/contentful-cli) — the primary user-facing CLI; delegates to `contentful-import` for the `space import` command - Direct npm consumers — developers using the library API (`runContentfulImport(opts)`) in their own scripts ## Build & Quality ```bash # Quick verification loop npm install && npm run build && npm run test:unit && npm run lint ``` Full test (including integration — requires credentials): ```bash MANAGEMENT_TOKEN= ORG_ID= npm test ```