Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ba05674
docs: add agent section to README
michaelphamcf May 4, 2026
358927f
docs: add ARCHITECTURE
michaelphamcf May 4, 2026
0bf788e
docs: add CONTRIBUTING
michaelphamcf May 4, 2026
439b243
docs: add architecture decision records
michaelphamcf May 4, 2026
f45af24
docs: add AGENTS.md
michaelphamcf May 4, 2026
35414f9
chore: add Bito review configuration
michaelphamcf May 4, 2026
7f31afa
fix: correct ADR dates, fix config.js description, remove speculative…
michaelphamcf May 4, 2026
e1abf77
fix: remove sync command reference — not registered in CLI
michaelphamcf May 4, 2026
15b54a7
docs: scaffold docs/specs directory
michaelphamcf May 4, 2026
d0b5ac4
docs: enrich golden context for newcomer simulation coverage
michaelphamcf May 4, 2026
9dd1a37
docs: close remaining newcomer simulation gaps
michaelphamcf May 4, 2026
81bd211
docs: align golden context with updated skill conventions
michaelphamcf May 4, 2026
8a3bd74
docs: remove NEEDS TEAM INPUT stubs
michaelphamcf May 4, 2026
0e9bbfa
docs: replace stale CircleCI badge with GitHub Actions
michaelphamcf May 4, 2026
590cb09
fix: correct GHA badge workflow to main.yaml
michaelphamcf May 4, 2026
6cffec1
docs: note data sensitivity risk in talkback ADR
michaelphamcf May 5, 2026
dea0675
docs: restore original CONTRIBUTING.md and append new sections additi…
michaelphamcf May 5, 2026
bace910
docs: correct stale information in original CONTRIBUTING.md
michaelphamcf May 5, 2026
1f8a5c0
docs: use npm install for local dev setup, note npm ci for CI
michaelphamcf May 5, 2026
6acd05c
docs: remove redundant npmrc paragraph from additional context
michaelphamcf May 5, 2026
bef58a8
fix: add sync command back to ARCHITECTURE.md
michaelphamcf May 5, 2026
c3557f8
fix: correct login file extension from .js to .ts
michaelphamcf May 5, 2026
5fbad05
fix: correct eslint config extension, TS target, remove nonexistent .…
michaelphamcf May 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .bito.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
suggestion_mode: comprehensive
post_description: true
post_changelist: true
exclude_files: 'package-lock.json'
exclude_draft_pr: false
secret_scanner_feedback: true
linters_feedback: true
repo_level_guidelines_enabled: true
sequence_diagram_enabled: true
custom_guidelines:
general:
- name: 'Review Posture'
path: './.bito/guidelines/review-posture.txt'
- name: 'Repo Truth And Alignment'
path: './.bito/guidelines/repo-truth-and-boundaries.txt'
- name: 'Domain Invariants'
path: './.bito/guidelines/domain-invariants.txt'
43 changes: 43 additions & 0 deletions .bito/guidelines/domain-invariants.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Critical technical invariants for the Contentful CLI:

Build and runtime:
- TypeScript compiles to dist/ via tsc. The bin/contentful.js entrypoint requires
dist/lib/cli.js — never lib/cli.ts directly. Any change to lib/ requires a
rebuild before testing the binary.
- Module system is CommonJS. Do not introduce ESM-only imports or top-level await.
- Yargs is pinned at ~13.3.2. Do not upgrade without a dedicated migration.

Satellite package alignment:
- contentful-management.js, contentful-migration, contentful-import,
contentful-export, and contentful-batch-libs must be version-aligned. A major
bump to one typically requires coordinated bumps across all of them.
- Some call sites use createPlainClient() in "legacy" mode. These are transitional
from the CMA v12 migration — do not remove without verifying the new API surface.

Testing:
- Unit tests require CONTENTFUL_INTEGRATION_TEST_CMA_TOKEN and CLI_E2E_ORG_ID
environment variables to be set, even though they shouldn't need them. This is a
known coupling — do not add more dependencies on these vars in unit tests.
- Integration tests use talkback proxy recordings. When API responses change,
recordings need updating. Run tests without the proxy first, then re-record.
- E2E tests run against standalone binaries — changes to pkg config or binary
bundling should be validated with npm run test:e2e.

Security and supply chain:
- .npmrc sets ignore-scripts=true. After npm ci, npx allow-scripts must run.
New packages that need install scripts must be added to the lavamoat.allowScripts
allowlist in package.json.
- Secrets in CI come from HashiCorp Vault, not GitHub Secrets.

Release:
- Commit messages drive releases via semantic-release. Breaking changes MUST use
the BREAKING CHANGE: footer keyword — without it, the major bump won't trigger.
- The beta branch publishes to the npm beta channel. Do not merge experimental
work directly to main.

Command interface stability:
- Command names, flag names, and output formats are a public API. Changes to these
affect downstream scripts and CI pipelines. Treat them as breaking changes unless
the change is purely additive.
- The .contentfulrc.json config file format is also part of the public contract.
Changes to config keys or resolution order affect all users.
18 changes: 18 additions & 0 deletions .bito/guidelines/repo-truth-and-boundaries.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Use the repository's written documentation as review context and check whether
the change matches the documented intent.

- Start from README.md, ARCHITECTURE.md, AGENTS.md, CONTRIBUTING.md, and docs/ADRs/
for architectural context.
- Check whether code, tests, and documentation all tell the same story. Flag
mismatches between implementation and the documented architecture or ADRs.
- Treat AGENTS.md as the authoritative guide for sharp edges and invariants. If a
change violates an invariant documented there, flag it.
- If CI or another required check already enforces a merge rule, do not ask for
duplicate PR template sections or manual checklists.
- Ask for an ADR update when a change is architecture-significant (new command,
new dependency, new integration, changed module system, framework upgrade).
- Distinguish the CLI's public command interface from internal implementation.
Public-facing changes (command names, flags, output format, exit codes) require
extra scrutiny — they are consumed by scripts and CI pipelines.
- The docs/ directory contains per-command usage documentation. If a command's
behavior changes, the corresponding docs/ file should be updated.
18 changes: 18 additions & 0 deletions .bito/guidelines/review-posture.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Review this pull request like the tech lead of the Contentful CLI project.

- Prefer a few high-signal findings to a long list of minor or style-only comments.
- Prefer behavior, contract, runtime, and documentation issues over process-only
suggestions. Do not ask for duplicate PR template sections, checklists, or manual
validation acknowledgements when CI or required checks already enforce that policy.
- Keep feedback actionable: explain why it matters, how it would surface in practice,
and the clearest next step.
- If a concern is only a risk or assumption rather than a confirmed bug, say that
clearly and explain what evidence would confirm it.
- If you find no issues, say so explicitly and call out any residual uncertainty
that still deserves human attention.
- Pay special attention to breaking changes in command interfaces — the CLI is a
public API surface used in CI/CD pipelines and scripts. Flag any change to
command names, argument names, output formats, or exit codes.
- Watch for compatibility with the satellite package ecosystem (contentful-migration,
contentful-import, contentful-export, contentful-batch-libs) — version mismatches
between these packages and contentful-management.js are a recurring pain point.
58 changes: 58 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 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) |
| Per-command usage docs | [docs/](./docs/) |
| PR review rules | [.bito/guidelines/](./.bito/guidelines/) |
| CLI entrypoint | `bin/contentful.js` → `dist/lib/cli.js` |
| Command implementations | `lib/cmds/` and `lib/cmds/<parent>_cmds/` |
| Shared utilities | `lib/utils/` |
| Configuration handling | `lib/config.js` and `lib/context.js` |

## Sharp Edges & Invariants

- **Build before run.** The CLI requires `npm run tsc` before it can execute — `bin/contentful.js` requires `dist/lib/cli.js` which is compiled output.
- **Mixed JS/TS codebase.** Older commands are `.js`, newer ones are `.ts`. Both coexist via `allowJs: true`. Do not convert existing `.js` files to `.ts` without deliberate migration scope.
- **Yargs 13.x is pinned.** The CLI uses yargs ~13.3.2, which is significantly behind current (17.x). Do not upgrade without a dedicated migration effort — command definitions will break.
- **`ignore-scripts=true` in `.npmrc`.** After `npm ci`, you must run `npx allow-scripts` to let approved packages execute their install scripts. CI workflows already do this.
- **Unit tests need integration env vars.** Even unit tests require `CONTENTFUL_INTEGRATION_TEST_CMA_TOKEN` and `CLI_E2E_ORG_ID` to be set, due to a known coupling.
- **Commit convention is enforced by semantic-release.** A `feat:` commit triggers a minor release, `fix:` a patch. Breaking changes MUST include `BREAKING CHANGE:` in the commit footer — the `{ "breaking": true }` rule in `package.json` maps this to a major release.
- **Satellite packages must be version-aligned.** `contentful-migration`, `contentful-import`, `contentful-export`, and `contentful-batch-libs` are tightly coupled to the CMA.js version. Bumping one usually means bumping all of them.
- **`createPlainClient()` legacy mode.** Some call sites use the "legacy" deprecated CMA client mode as a transitional measure from the CMA v12 migration. These should be migrated over time but must not be removed without verifying the new API surface covers the use case.

## Key Conventions

- **Commit format:** Angular Conventional Commits (`type(scope): description`) via semantic-release
- **Branch strategy:** `main` (production) + `beta` (pre-release channel), squash merge
- **Test location:** `test/unit/` mirrors `lib/`, `test/integration/` uses talkback proxy, `test/e2e/` tests binaries
- **Module system:** CommonJS (compiled from TypeScript via `tsc`)
- **Command pattern:** Files in `lib/cmds/` export yargs command objects; subcommands go in `lib/cmds/<parent>_cmds/`

## Integration Points

**Upstream (this repo consumes):**
- **Contentful Management API** — all CRUD operations via `contentful-management.js` (^12.2.0)
- **contentful-migration** (^5.0.0) — migration script execution
- **contentful-import** (v10.0.0) / **contentful-export** (v8.0.0) — space import/export
- **contentful-batch-libs** (^11.0.0) — batch processing utilities
- **Contentful OAuth Page** — browser-based token acquisition during login

**Downstream (consumes this repo):**
- **Developers** — `npm install -g contentful-cli` or `npx contentful-cli`
- **CI/CD pipelines** — migration execution, environment management
- **Standalone binary users** — macOS/Linux/Windows binaries from GitHub releases

## Build & Quality

```bash
# Quick verification loop
npm ci && npx allow-scripts && npm run tsc && npm test
```
91 changes: 91 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Architecture

## Overview

`contentful-cli` is the official command-line interface for [Contentful](https://www.contentful.com). It provides subcommands for managing spaces, environments, content types, extensions, migrations, import/export, organization security checks, and the merge workflow. It is published to npm and also distributed as standalone binaries for macOS, Linux, and Windows.
Comment thread
michaelphamcf marked this conversation as resolved.

## System Context

```mermaid
graph TD
User[Developer / CI Pipeline] --> CLI[contentful-cli]
CLI --> CMA[Contentful Management API]
CLI --> OAuth[Contentful OAuth Page]
CLI -->|delegates| Migration[contentful-migration]
CLI -->|delegates| Import[contentful-import]
CLI -->|delegates| Export[contentful-export]
CLI -->|delegates| BatchLibs[contentful-batch-libs]
CLI --> CMAjs[contentful-management.js]
CMAjs --> CMA
```

The CLI is the **user-facing entry point** for content-as-code workflows. It delegates heavy lifting to satellite packages (`contentful-migration`, `contentful-import`, `contentful-export`, `contentful-batch-libs`) and uses `contentful-management.js` (CMA.js) as the API client.

## Internal Structure

| Directory | Purpose |
|---|---|
| `bin/contentful.js` | Entry point — requires compiled `dist/lib/cli.js` |
| `lib/cli.ts` | Yargs CLI setup, top-level command registration |
| `lib/cmds/` | Top-level commands (`login`, `logout`, `init`, `space`, `merge`, `organization`, etc.) |
Comment thread
michaelphamcf marked this conversation as resolved.
Outdated
| `lib/cmds/<cmd>_cmds/` | Subcommands (e.g., `space_cmds/create.ts`, `organization_cmds/sec-check.ts`) |
| `lib/utils/` | Shared utilities — API clients, error handling, proxy, pagination, merge logic |
| `lib/utils/merge/` | Merge-specific utilities (changeset rendering, content type helpers) |
| `lib/core/events/` | Internal event system for space creation and logging |
| `lib/config.js` | Configuration management (`.contentfulrc.json` read/write) |
| `lib/context.js` | Context resolution — active space, environment, token |
| `docs/` | Per-command documentation with usage examples |
| `test/unit/` | Unit tests (Jest) |
| `test/integration/` | Integration tests with talkback proxy recordings |
| `test/e2e/` | End-to-end tests against standalone binaries |
| `dist/` | Compiled output (TypeScript → CommonJS) |
| `build/` | Standalone binary output (`@yao-pkg/pkg`) |

## Data Flow

1. **Authentication**: `contentful login` opens the OAuth page in a browser, user copies CMA token back, token is stored in `~/.contentfulrc.json`.
2. **Context resolution**: Before each command, the CLI reads `.contentfulrc.json` for active space ID, environment ID, host, and management token.
3. **Command execution**: Yargs dispatches to the appropriate command handler in `lib/cmds/`. Commands use `contentful-management.js` to make API calls.
4. **Delegation**: Import, export, and migration commands delegate to their respective npm packages, passing configuration and the CMA client.
5. **Output**: Results are rendered to the terminal via `chalk`, `cli-table3`, `boxen`, and `listr` (task runner UI).

## Key Dependencies

| Dependency | Why it's here |
|---|---|
| `yargs` (~13.3.2) | CLI framework — command parsing, help generation, argument validation |
| `contentful-management` (^12.2.0) | CMA.js SDK — all API interactions ([ADR: CMA v12 migration](./docs/ADRs/2026-04-22-cma-v12-migration.md)) |
| `contentful-migration` (^5.0.0) | Migration script execution engine |
| `contentful-import` / `contentful-export` | Space import/export functionality |
| `contentful-batch-libs` (^11.0.0) | Shared batch processing utilities for import/export |
| `inquirer` (^8.2.7) | Interactive prompts (space selection, login, init) |
| `listr` | Task runner UI for multi-step operations |
| `chalk` | Terminal styling |
| `@yao-pkg/pkg` | Standalone binary compilation ([ADR: yao-pkg migration](./docs/ADRs/2026-04-10-yao-pkg-standalone-binaries.md)) |

## Configuration

| Variable / Flag | Purpose | Default |
|---|---|---|
| `~/.contentfulrc.json` | Global config — management token, active space/env, host | Created on `login` |
| `.contentfulrc.json` (local) | Per-project config — overrides global settings | None |
| `--management-token` / `--mt` | Override stored token for a single command | From config |
| `--space-id` | Override active space | From config |
| `--environment-id` | Override active environment | `master` |
| `--host` | CMA host (EU: `api.eu.contentful.com`) | `api.contentful.com` |
| `--proxy` | HTTP proxy in `user:auth@host:port` format | None |
| `http_proxy` / `https_proxy` | Environment variable proxy config | None |

## Integration Points

### Upstream (this repo consumes)

- **Contentful Management API** — all CRUD operations on spaces, environments, content types, entries, assets, extensions, organizations
- **Contentful OAuth Page** (`contentful-cli-oauth-page` repo) — browser-based token acquisition during `contentful login`

### Downstream (consumes this repo)

- **Developers** — installed globally via `npm install -g contentful-cli` or `npx contentful-cli`
- **CI/CD pipelines** — migration execution, import/export, environment management in automated workflows
- **Standalone binary users** — macOS/Linux/Windows binaries attached to GitHub releases
- **contentful/experience-design-system-sdk** — planned integration as `contentful design-system` subcommand (post-M1)
Loading
Loading