From dec43c483d333f95169d2617220a67ce8ade488c Mon Sep 17 00:00:00 2001 From: Gabriel Stein Date: Thu, 25 Jun 2026 13:41:08 -0700 Subject: [PATCH] chore(context): preserve personal CLAUDE.md as CLAUDE.local.md chore(context): add canonical AGENTS.md with SDK architectural context chore(context): convert CLAUDE.md to @AGENTS.md import chore(context): add GEMINI.md redirect and un-ignore from gitignore chore(context): convert copilot-instructions.md to AGENTS.md redirect chore(context): move CLAUDE.local.md exclusion from .gitignore to .git/info/exclude chore(context): sharpen effects.ts vs micros.ts distinction in AGENTS.md chore(context): enumerate all redirect files in AGENTS.md note chore(context): use @./AGENTS.md import in GEMINI.md for proper context injection chore(context): document Copilot include limitation and add read instruction chore(context): remove inaccurate "one-line" from redirect notes --- .github/copilot-instructions.md | 5 ++ .gitignore | 5 +- AGENTS.md | 139 ++++++++++++++++++++++++++++++++ CLAUDE.md | 3 + GEMINI.md | 3 + package.json | 2 +- 6 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 .github/copilot-instructions.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 GEMINI.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000..cb6a01a2b7 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,5 @@ +See [AGENTS.md](../AGENTS.md) for full agent context and architectural guidance for this repository. + +> **Note:** GitHub Copilot has no file-include directive syntax. This file cannot automatically inject `AGENTS.md` content. Read `AGENTS.md` at the repository root and apply all guidance found there. + +> **Edit AGENTS.md only** — not this file. diff --git a/.gitignore b/.gitignore index 89d5955ee8..9830032f4d 100644 --- a/.gitignore +++ b/.gitignore @@ -88,16 +88,13 @@ test-output .cursor/rules/nx-rules.mdc .github/instructions/nx.instructions.md -# Gemini local knowledge base files -GEMINI.md -**/GEMINI.md - .claude/worktrees .claude/settings.local.json .claude/skills .claude/CLAUDE.md .opensource + # Polaris .polaris-setup-progress.json .playwright-mcp diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..0963453141 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,139 @@ +# AGENTS.md + +This file provides guidance to AI coding agents (Claude Code, Cursor, GitHub Copilot, Gemini, etc.) when working with code in this repository. It follows the open AGENTS.md convention. + +> **Note:** CLAUDE.md, GEMINI.md, and `.github/copilot-instructions.md` in this repository are redirects to AGENTS.md. Edit AGENTS.md only. + +## Development Commands + +```sh +# Install dependencies +pnpm install --frozen-lockfile + +# Full repo checks (affected projects only) +pnpm build +pnpm lint +pnpm test +pnpm test:e2e + +# CI-parity (build + lint + test + e2e on affected) +pnpm exec nx affected -t build lint test e2e-ci + +# Build all publishable packages +pnpm nx run-many -t build --no-agents + +# Package-scoped commands (preferred for focused work) +pnpm --filter @forgerock/davinci-client build +pnpm --filter @forgerock/davinci-client lint +pnpm --filter @forgerock/davinci-client test + +# Single test file +pnpm --filter @forgerock/davinci-client test -- --run src/lib/.test.ts + +# Single e2e suite +pnpm nx e2e + +# Keep TS project references in sync +pnpm nx sync:check +``` + +## Architecture Overview + +### Module Structure + +The SDK is an **Nx + pnpm monorepo** with a strictly unidirectional dependency hierarchy. Higher layers may depend on lower layers — never the reverse. Enforced via Nx module boundary rules in `eslint.config.mjs`. + +**Types layer** (`scope:sdk-types`): + +- `@forgerock/sdk-types` — shared TypeScript contracts used across all packages + +**Utilities / Effects layer** (`scope:sdk-utilities`, `scope:sdk-effects`): + +- `@forgerock/sdk-utilities` — pure, stateless helpers shared across packages +- `packages/sdk-effects/logger` — structured logging +- `packages/sdk-effects/oidc` — OIDC session effects +- `packages/sdk-effects/storage` — storage abstraction +- `packages/sdk-effects/sdk-request-middleware` — request pipeline middleware +- `packages/sdk-effects/iframe-manager` — iframe lifecycle management + +**Product client layer** (`scope:package`): + +- `@forgerock/oidc-client` — OIDC/OAuth2 authentication +- `@forgerock/journey-client` — PingAM/ForgeRock Journey orchestration +- `@forgerock/davinci-client` — PingOne DaVinci flow orchestration +- `@forgerock/device-client` — device binding and attestation +- `@forgerock/protect` — Ping Protect fraud detection integration + +### Key Directory Structure + +``` +packages/ +├── sdk-types/ # Shared TypeScript types (no runtime code) +├── sdk-utilities/ # Pure helper functions +├── sdk-effects/ +│ ├── logger/ +│ ├── oidc/ +│ ├── storage/ +│ ├── sdk-request-middleware/ +│ └── iframe-manager/ +├── davinci-client/src/lib/ +│ ├── client.store.ts # Public client facade (factory function) +│ ├── davinci.api.ts # Network layer (RTK Query) +│ ├── client.store.effects.ts # Side-effect orchestration +│ ├── node.reducer.ts # Redux state transitions +│ ├── node.slice.ts # Redux slice +│ ├── davinci.utils.ts # Pure helpers +│ └── davinci.types.ts # Type contracts +├── oidc-client/ +├── journey-client/ +├── device-client/ +└── protect/ + +e2e/ +├── davinci-suites/ # Playwright e2e for DaVinci flows +├── journey-suites/ # Playwright e2e for Journey flows +├── oidc-suites/ # Playwright e2e for OIDC flows +├── protect-suites/ +├── am-mock-api/ # Mock AM server for journey e2e +└── mock-api-v2/ # Mock API v2 +``` + +### Internal File Conventions + +Architecture is encoded in file names — this is a constraint mechanism, not cosmetic: + +| File suffix | Responsibility | +| ----------------------------- | --------------------------------------------------------------------------- | +| `store.ts` | Public client facade and network orchestration entrypoint | +| `*.api.ts` | Network/request boundary (RTK Query, middleware, error handling) | +| `*.effects.ts` | Single isolated side-effect — non-network async, storage, logging | +| `*.micros.ts` | Side-effectful workflows — multi-step async orchestration, polling, retries | +| `*.utils.ts` | Pure helpers and transformations — no side-effects, no state | +| `*.reducer.ts` / `*.slice.ts` | Redux state transitions and mapping | +| `*.types.ts` | Type contracts — no runtime code | + +**Key rules:** + +- Never put effectful logic in `*.utils.ts` — utils must be pure and stateless; side-effects belong in `*.effects.ts` (single isolated effect) or `*.micros.ts` (multi-step workflow) +- `*.types.ts` files have no runtime code — `type` and `interface` only, no `enum` +- Client packages are initialized via factory functions, never classes or singletons + +## Development Notes + +### Key Conventions + +- **pnpm only.** `preinstall` enforces with `only-allow pnpm`. +- Workspace dependency versions are centralized via **pnpm catalogs** in `pnpm-workspace.yaml`. +- Releases are Changesets-driven (`pnpm ci:version`, `pnpm ci:release`), published from `main`. +- PRs target `main`, pass `pnpm run lint/build/test`, and use Conventional Commit style. + +### Branch Strategy + +- `main`: production branch, all releases published from here +- Feature branches target `main` via PR + +### CI/CD + +- GitHub Actions runs `pnpm exec nx affected -t build lint test e2e-ci` on PR/push +- E2E suites are Playwright projects — they start workspace apps via `pnpm nx serve` and, for journey flows, also start `am-mock-api` +- Releases are automated via Changesets on merge to `main` diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000000..3c57daf418 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,3 @@ +@AGENTS.md + +> **Note:** This file is a redirect to AGENTS.md. Edit AGENTS.md only. diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000000..16c19b357e --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,3 @@ +@./AGENTS.md + +> **Note:** This file is a redirect to AGENTS.md. Edit AGENTS.md only. diff --git a/package.json b/package.json index 276cd4db39..0d316ab399 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "ci:release": "pnpm nx run-many -t build --no-agents --skip-nx-cache && pnpm publish -r --no-git-checks && changeset tag", "ci:version": "changeset version && pnpm install --no-frozen-lockfile && pnpm nx format:write --uncommitted", "circular-dep-check": "madge --circular .", - "clean": "shx rm -rf ./{coverage,dist,docs,node_modules,tmp}/ ./{packages,e2e}/*/{dist,node_modules}/ ./e2e/node_modules/ && git clean -fX -e \"!.env*,nx-cloud.env\" -e \"!**/GEMINI.md\"", + "clean": "shx rm -rf ./{coverage,dist,docs,node_modules,tmp}/ ./{packages,e2e}/*/{dist,node_modules}/ ./e2e/node_modules/ && git clean -fX -e \"!.env*,nx-cloud.env\"", "commit": "git cz", "commitlint": "commitlint --edit", "create-package": "nx g @nx/js:library",