Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 34 additions & 2 deletions .husky/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ package_tarballs_exist() {
find pkgs -maxdepth 1 -name "contentful-*.tgz" -print -quit 2>/dev/null | grep -q .
}

is_documentation_file() {
local file=$1

case "$file" in
*.md | *.mdx | *.markdown | documentation/* | docs/* | */documentation/* | */docs/*)
return 0
;;
*)
return 1
;;
esac
}

# Collect changed files for each pushed ref from pre-push hook input
# Input rows: <local ref> <local sha> <remote ref> <remote sha>
changed_files=""
Expand Down Expand Up @@ -46,6 +59,25 @@ done

changed_files=$(printf "%s" "$changed_files" | sed '/^$/d' | sort -u)

if [ -z "$changed_files" ]; then
echo "No changed files detected for checks."
exit 0
fi

substantive_changed_files=""
while IFS= read -r changed_file; do
if ! is_documentation_file "$changed_file"; then
substantive_changed_files+="$changed_file"$'\n'
fi
done <<<"$changed_files"

substantive_changed_files=$(printf "%s" "$substantive_changed_files" | sed '/^$/d' | sort -u)

if [ -z "$substantive_changed_files" ]; then
echo "Only documentation-related changes detected; skipping build and check hook."
exit 0
fi

# List workspaces (relative paths)
workspaces=$(pnpm ls -r --depth -1 --json | jq -r ".[].path" | sed "s|^$REPO_ROOT/||")

Expand All @@ -55,7 +87,7 @@ implementations=$(find implementations -mindepth 1 -maxdepth 1 -type d -exec bas
# Find changed workspaces with tsconfig.json
changed_workspaces=()
for workspace in $workspaces; do
if echo "$changed_files" | grep -q "^$workspace/"; then
if echo "$substantive_changed_files" | grep -q "^$workspace/"; then
[ -f "$workspace/tsconfig.json" ] && changed_workspaces+=("$workspace")
fi
done
Expand All @@ -64,7 +96,7 @@ done
changed_implementations=()
for implementation in $implementations; do
implementation_path="implementations/$implementation"
if echo "$changed_files" | grep -q "^$implementation_path/"; then
if echo "$substantive_changed_files" | grep -q "^$implementation_path/"; then
[ -f "$implementation_path/tsconfig.json" ] && changed_implementations+=("$implementation")
fi
done
Expand Down
85 changes: 57 additions & 28 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# AGENTS.md

This file defines repository-wide rules only. For any change, read this file first, then read the
nearest `AGENTS.md` in the subtree you are editing.
This file defines repository-wide rules only. For any change, read this file first, then read each
applicable child `AGENTS.md` from outermost to nearest in the subtree you are editing.

## Hierarchy

- The root `AGENTS.md` owns stable repo-wide policy.
- `lib/*/AGENTS.md`, `packages/**/AGENTS.md`, and `implementations/*/AGENTS.md` own local
instructions, commands, and gotchas.
- `packages/AGENTS.md` and `implementations/AGENTS.md` own shared policy for all packages and
reference implementations.
- `lib/*/AGENTS.md`, `packages/**/AGENTS.md`, and `implementations/*/AGENTS.md` own more specific
local instructions, commands, and gotchas.
- If local guidance conflicts with this file, follow the more specific `AGENTS.md` for that subtree.
- When adding a new workspace package or implementation, add a sibling `AGENTS.md` in the same
change.
Expand Down Expand Up @@ -106,14 +108,7 @@ Do not hand-edit generated or local-only artifacts unless the task is explicitly
before finishing if the change grew.
- For `implementations/` edits, prefer `pnpm implementation:lint` after the first meaningful patch
and again before finishing if the change grew.
- For a single workspace package, prefer targeted `typecheck`, `test:unit`, and `build`.
- For built workspace packages, run the package `size:check` script when runtime code, published
dependencies, bundler config, exports, or bundle shape changes.
- For cross-cutting changes, broaden validation to affected downstream packages or implementations.
- For package changes used by implementations, run `pnpm build:pkgs` before reinstalling or running
implementation tests.
- For implementation-only changes, use `pnpm implementation:lint`, targeted implementation
`typecheck`, and targeted E2E as needed.
- If you skip a relevant check because of time or environment constraints, say exactly what was not
run and why.

Expand Down Expand Up @@ -175,32 +170,66 @@ High-signal repo-wide commands:
- what you already tried
- the smallest next action, user input, or approval needed

Common repo-specific failure modes:

- An implementation does not reflect a package change: run `pnpm build:pkgs`, then rerun the
relevant `pnpm implementation:run -- <implementation> implementation:install`.
- If the goal is E2E setup rather than the narrowest possible refresh step, prefer the combined root
wrapper `pnpm setup:e2e:<implementation>`. For a full E2E run, prefer
`pnpm test:e2e:<implementation>`.
- Implementation-specific runtime failures such as Docker availability, Playwright browser setup,
emulator requirements, `.env` drift, PM2 state, and local port conflicts belong in the relevant
implementation `AGENTS.md`, not here.

## Docs, Specs, And CI

- When public SDK behavior changes, update the relevant TSDoc or JSDoc and the affected package
`README.md` in the same change.
- Authored supporting docs live in `documentation/`; generated TypeDoc output lives in `docs/`.
- If a package includes a package-local dev harness or other meaningful local dev surface, keep that
surface relevant to the current SDK behavior and update it in the same change when the package's
developer-facing flows, configuration, or core capabilities change.
- If the repository later adds any replacement design, architecture, or specification artifacts for
the changed area, keep them aligned in the same change.
- `docs/` is generated by TypeDoc and is gitignored.
- Implementation E2E in `.github/workflows/main-pipeline.yaml` is intentionally path-filtered. If a
change should alter E2E coverage, update the workflow and keep it aligned with
[CONTRIBUTING.md](./CONTRIBUTING.md).

## README And Markdown Standards

- Treat README files as maintained source-of-truth orientation for humans. Keep them aligned with
package exports, implementation scripts, local `.env.example` files, and authored documentation in
the same change as behavior or workflow updates.
- Preserve the README family already used by the target directory:
- root, published package, and reference implementation READMEs use the centered Contentful logo
header, `Contentful Personalization & Analytics` title, subtype `<h3>`, navigation links, and
pre-release warning.
- `documentation/**/README.md` files are navigation indexes with frontmatter.
- placeholder and internal-only README files may use a plain Markdown `#` title plus explicit
status or internal-use admonitions.
- Use title case for Markdown headings, preserving official product, package, API, component, hook,
and file casing.
- Lead with reader intent and scope: what to use, when to use it, and what belongs elsewhere. Prefer
concrete implementation guidance over marketing language.
- Keep terminology consistent: "Optimization SDK Suite", "Personalization", "Analytics", "Experience
API", "Insights API", "reference implementation", and exact package names such as
`@contentful/optimization-web`.
- Use fenced code blocks with language tags (`sh`, `ts`, `tsx`, `json`, `html`) and prefer `pnpm`
commands. Do not introduce npm, yarn, or undocumented global-tool instructions.
- Use GitHub admonitions intentionally: warning/caution for pre-release, internal, destructive, or
unsafe flows; important for required contracts; note for helpful context that is not required.
- Match README depth to the README category, not to the amount of available detail:
- application-facing package READMEs orient the integrator, preserve common setup options, and
link to authored guides or generated reference docs for deep workflows and exhaustive API
details
- lower-level package READMEs orient SDK maintainers and package authors, explain the layer's
role, and avoid application-integration tutorial depth
- reference implementation READMEs stay procedural and point readers to the code being
demonstrated instead of duplicating package API tutorials
- internal and placeholder READMEs stay short, explicit, and status-oriented
- Move step-by-step implementation material into `documentation/guides/` when an existing guide is
the right home; create a new guide only when no existing guide covers that reader goal. Use
generated TypeDoc reference for exhaustive signatures, method catalogs, callback payload shapes,
and exported type details.
- Before changing README navigation or cross-document links, account for every render target that
consumes that README: GitHub source browsing, TypeDoc project documents, and npmjs package README
rendering for published packages.
- Keep relative links pointed at source-of-truth files in this repository when the README is only
consumed in-repo or by TypeDoc, or when the package README publish rewrite flow is known to
rewrite that link for npm. Use stable absolute URLs for links that must work unchanged across
GitHub, TypeDoc, and npm.
- Link to generated reference docs for API reference and shared README header navigation that needs
to work in all render targets, not as a replacement for source README guidance.
- When a README has a collapsible table of contents, preserve the exact `<!-- mtoc-start -->` and
`<!-- mtoc-end -->` markers and keep entries synchronized with headings.
- For Markdown edits, run Prettier on touched files when practical and at least run
`git diff --check` before finishing.

## Safety Rules

- Never overwrite or delete ignored local files just to get a clean run.
Expand All @@ -211,7 +240,7 @@ Common repo-specific failure modes:
## Preferred Workflow

1. Read the root `AGENTS.md`.
2. Read the nearest `AGENTS.md` in the subtree you will edit.
2. Read each applicable child `AGENTS.md` from outermost to nearest in the subtree you will edit.
3. Make the narrowest source-of-truth change in the correct layer.
4. Run the smallest meaningful validation set.
5. Broaden validation only when exports, build tooling, mocks, or shared behavior changed.
Expand Down
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ gotchas.
- [Validation Matrix](#validation-matrix)
- [Code Style and Local Hooks](#code-style-and-local-hooks)
- [Documentation](#documentation)
- [README Depth and Render Targets](#readme-depth-and-render-targets)
- [Local Troubleshooting](#local-troubleshooting)
- [Troubleshooting CI Issues](#troubleshooting-ci-issues)
- [E2E Coverage and Environment](#e2e-coverage-and-environment)
Expand Down Expand Up @@ -325,6 +326,27 @@ keep these artifacts aligned:
`documentation/` contains source markdown that TypeDoc publishes. `docs/` is generated output. Do
not hand-edit generated TypeDoc output.

### README Depth and Render Targets

READMEs are orientation surfaces, not the only place every detail should live. Match depth to the
README category:

- Application-facing package READMEs keep purpose, install, minimal setup, common options, critical
caveats, and links to guides, reference implementations, and generated API reference.
- Lower-level package READMEs explain the package's role in the SDK stack, who should use it
directly, common setup options where useful, and where exhaustive API details live.
- Reference implementation READMEs stay procedural: what the implementation demonstrates,
prerequisites, setup, run/test commands, environment notes, and related package links.
- Internal and placeholder READMEs stay short, explicit, and status-oriented.

Move step-by-step implementation material into the existing guide for that runtime when one exists.
Create a new guide only when no existing guide covers the reader goal. Keep exhaustive method
catalogs, callback payload shapes, and exported type details in TypeDoc.

Package README links must work in GitHub source browsing, generated TypeDoc project documents, and
npmjs README rendering. Use canonical generated-doc URLs for shared header navigation and verify
repo-relative links before relying on package README publish rewriting.

## Local Troubleshooting

- An implementation is not reflecting your latest package change: run `pnpm build:pkgs`, then
Expand Down
38 changes: 27 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ enables developers and content creators to ship their products faster.

- [Choosing a Package](#choosing-a-package)
- [Published Packages](#published-packages)
- [Planned SDKs](#planned-sdks)
- [Native and Planned SDKs](#native-and-planned-sdks)
- [Reference Implementations](#reference-implementations)
- [Repository Layout](#repository-layout)
- [Get Involved](#get-involved)
Expand All @@ -55,9 +55,11 @@ enables developers and content creators to ship their products faster.
If you are deciding which SDK or library belongs in your application, start with
[Choosing the Right SDK](./documentation/guides/choosing-the-right-sdk.md).

For additional narrative documentation, see the [Guides](./documentation/README.md) section.
For step-by-step implementation docs, start with the [Guides](./documentation/guides/README.md)
index. For behavior explanations, start with the [Concepts](./documentation/concepts/README.md)
index.

Package README files listed below are package-level overviews. Generated
Package README files listed below are package-level guides and API surface summaries. Generated
[reference documentation](https://contentful.github.io/optimization) remains the source of truth for
exported API signatures.

Expand All @@ -84,11 +86,20 @@ General selection rules:
- `@contentful/optimization-api-client` and `@contentful/optimization-api-schemas` are lower-level
building blocks.

## Planned SDKs
## Native and Planned SDKs

These packages or layers are planned, but are not currently published from this repository:
React Native support is available today through
[`@contentful/optimization-react-native`](./packages/react-native-sdk/README.md).

Native iOS work is also present in this repository as a pre-release Swift Package under
[`packages/ios`](./packages/ios/README.md), backed by the
[`@contentful/optimization-ios-bridge`](./packages/ios/ios-jsc-bridge/README.md) JavaScriptCore
adapter and the [iOS reference app](./implementations/ios-sdk/README.md). Treat this surface as
alpha implementation work rather than a stable public native SDK.

The following native and framework SDKs are still planned and are not currently published from this
repository:

- iOS Swift SDK
- Android Kotlin SDK
- Android Java SDK
- Nest.js SDK
Expand All @@ -101,14 +112,19 @@ These packages or layers are planned, but are not currently published from this
Reference implementations exist to exercise critical flows end to end and to document common usage
patterns with intentionally minimal application code.

- [Web Vanilla](./implementations/web-sdk/README.md): static browser integration for the Web SDK
- [React Web](./implementations/web-sdk_react/README.md): React-based browser integration
- [Node SSR Only](./implementations/node-sdk/README.md): server-rendered integration using the Node
- [Web Vanilla](./implementations/web-sdk/README.md) - static browser integration for the Web SDK
- [React Web](./implementations/react-web-sdk/README.md) - primary React browser integration using
the official React Web SDK package
- [Web SDK React Adapter](./implementations/web-sdk_react/README.md) - adapter-based React example
built directly on top of the Web SDK
- [Node SSR Only](./implementations/node-sdk/README.md) - server-rendered integration using the Node
SDK
- [Node SSR + Web Vanilla](./implementations/node-sdk+web-sdk/README.md): split server/browser flow
- [Node SSR + Web Vanilla](./implementations/node-sdk+web-sdk/README.md) - split server/browser flow
using Node and Web SDKs together
- [React Native](./implementations/react-native-sdk/README.md): mobile application integration for
- [React Native](./implementations/react-native-sdk/README.md) - mobile application integration for
Android and iOS targets
- [iOS Reference App](./implementations/ios-sdk/README.md) - native app and XCUITest surface for
current iOS bridge and preview-panel scenarios; this is not a published iOS SDK package

## Repository Layout

Expand Down
Loading
Loading