# Agent Guide Read this file first. It tells you where to find context in this repo. ## Quick Reference | What you need | Where to look | |---|---| | 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/) | | What this repo does | [README.md](./README.md) | | PR review rules | [.bito/guidelines/](./.bito/guidelines/) | | Active specs/work | [docs/specs/](./docs/specs/) | ## Sharp Edges & Invariants - **Never edit `dist/` directly.** It is a Babel build artifact compiled from `lib/`. Always edit source in `lib/` and run `npm run build`. - **`types.d.ts` is hand-maintained.** It is NOT auto-generated. When changing the public API (options, return type), you must manually update `types.d.ts` to match. - **`usageParams.js` and `types.d.ts` must stay in sync.** CLI options (yargs definitions in `lib/usageParams.js`) and the TypeScript `Options` interface (`types.d.ts`) define the same option set. Changes to one must be reflected in the other. - **Webhooks and roles are master-only.** The code explicitly skips webhook and role export when `environmentId !== 'master'`. Do not change this -- it reflects a Contentful API constraint. - **The standalone CLI redirects to `contentful-cli`.** `bin/contentful-export` prints a notice that the CLI has moved to `contentful-cli`, then runs the export. Do not add new CLI-only features here. - **Integration tests require real Contentful spaces.** They are not mocked. CI provides the required secrets via environment variables. Do not commit tokens. - **`package.json` version is `0.0.0-determined-by-semantic-release`.** Never set a version manually. `semantic-release` handles all versioning. - **Babel target (Node 12) is lower than `engines.node` (>=22).** This is a known inconsistency in `babel.config.json`. The low target is harmless but confusing. - **`contentOnly` flag is a shorthand.** When set, it internally enables `skipRoles`, `skipContentModel`, and `skipWebhooks`. Do not duplicate this logic. - **ExO entities Organization entitlement-gated.** `includeExperienceOrchestration` defaults to `true`. When enabled, six ExO entity types are fetched using the `plainClient`. If the space lacks the `exo_m1` entitlement, each fetch fails silently: the entity array is set to `[]` and a warning is emitted. The export does not abort. See [docs/exo-export.md](./docs/exo-export.md). - **Asset downloads use concurrency of 6.** Both `download-assets.js` and `get-space-data.js` (editor interfaces) use Bluebird `Promise.map` with `{ concurrency: 6 }`. Be careful about changing this -- it affects API rate limiting. ## High-Traffic Areas These paths are the most critical and frequently exercised — changes here carry outsized risk: | Path | Why it's sensitive | What to watch | |---|---|---| | `lib/tasks/get-space-data.js` | Core export logic; every export invokes it | Pagination ordering (`sys.createdAt,sys.id`) is load-bearing for deterministic exports. Changing page size or concurrency affects API rate limits. | | `lib/parseOptions.js` | Validates and merges all user input | Adding/removing options here cascades to `usageParams.js`, `types.d.ts`, and all downstream consumers. | | `lib/index.js` | Listr task orchestration | Task ordering matters — e.g., `get-space-data` must complete before `download-assets` can reference fetched asset URLs. | | `lib/tasks/download-assets.js` | Network-heavy, concurrency-limited | Changing concurrency (currently 6) can trigger CMA rate limiting or exhaust memory on large spaces. | ## Key Conventions - **Commit format:** Conventional Commits enforced by Commitizen + Husky pre-commit hook - **Branch strategy:** `main` (stable releases) + `beta` (pre-releases), feature branches, squash merge - **Test location:** `test/unit/` mirrors `lib/` structure; `test/integration/` for end-to-end - **Module system:** ES modules in source, compiled to CJS via Babel for npm distribution - **Build before test:** `npm test` runs `pretest` which includes lint + build ## Integration Points **Upstream (this repo consumes):** - Contentful Management API (`api.contentful.com`) -- all entity CRUD - Contentful Delivery API (`cdn.contentful.com`) -- published-only content - `contentful-batch-libs` -- shared utilities for export/import tools **Downstream (consumes this repo):** - `contentful-cli` -- wraps this library as `contentful space export` - `contentful-mcp-server` -- uses this library for space-to-space migration - Direct npm consumers ## Build & Quality ```bash # Quick verification loop npm install && npm run build && npm run test:unit && npm run lint ```