From 2415d7af8c91007a7b6aeae0c4c3333afe959107 Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Mon, 29 Jun 2026 19:24:30 +0200 Subject: [PATCH 1/2] docs: add CLI agent guide (AGENTS.md) --- AGENTS.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..dcf3ef4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,97 @@ +# Seamless CLI Agent Guide + +This repository is the Seamless Auth command-line tool (published as `seamless-cli`, invoked as +`seamless` or `npx create-seamless`). It does two things: + +- **Scaffold** a working Seamless Auth project (`seamless init`): generates a React frontend, an + Express adapter, the auth server, a Docker Compose file, and config. +- **Verify** the whole auth surface (`seamless verify`): a cross-package conformance harness that + runs an api / adapter / react matrix against the ecosystem. + +Use this file as the fast path. The verify harness has its own moving parts under +[verify/](verify) (a Docker Compose stack plus a Playwright harness). + +## Start Here + +- Install dependencies: `npm install` +- Build (type-check and emit): `npm run build` (`tsc`, output in `dist/`) +- Run from source: `npm run dev -- ` (`tsx`); or after building, `node dist/index.js ` +- Commands: `init [name]`, `check`, `bootstrap-admin `, `verify [flags]` + +The entry point is [src/index.ts](src/index.ts), which dispatches to a command module in +`src/commands/`. + +## Commands + +- **init** ([src/commands/init.ts](src/commands/init.ts)) scaffolds a project from the generators in + `src/generators/*` (frontend, backend, auth, docker, config), driven by `src/prompts/`. +- **check** health-checks a running stack. +- **bootstrap-admin** mints the first admin invite. +- **verify** ([src/commands/verify.ts](src/commands/verify.ts)) runs the conformance harness (below). + +## The verify harness + +`seamless verify` stands up the ecosystem with Docker Compose and runs a Playwright matrix, then +prints a flow x layer pass/fail grid (plus JUnit and HTML reports). + +- [verify/docker-compose.verify.yml](verify/docker-compose.verify.yml): postgres, the auth API, and + the adapter, plus the React starter behind the `react` compose profile. The mock OIDC provider runs + in-process in `global-setup` (it is not a container). +- [verify/adapter-app](verify/adapter-app): a minimal `@seamless-auth/express` adopter backend with a + capture transport, so the harness can read OTP / magic-link codes the adapter would otherwise strip. +- [verify/harness](verify/harness): the Playwright projects (`api`, `adapter`, `react`), `lib/` + helpers, `mock-oidc.ts`, `global-setup.ts`, and `lib/matrixReporter.ts` (the printed grid). It has + its own `node_modules` and browsers. + +Modes and sibling repos: + +- `--local` builds the `@seamless-auth/*` packages from source (pre-publish contract testing); the + default uses the published packages. +- The sibling repos are resolved relative to this repo, overridable with `SEAMLESS_API_DIR`, + `SEAMLESS_SERVER_DIR`, `SEAMLESS_REACT_SDK_DIR` (the React SDK), and `SEAMLESS_REACT_DIR` (the + starter app). +- Useful flags: `--api-only`, `--no-react`, `--filter `, `--keep-up`. + +## Important Folders + +- [src/commands](src/commands): one file per CLI command +- [src/generators](src/generators): project scaffolding (frontend, backend, auth, docker, config) +- [src/core](src/core): shared helpers (exec, env, fetch, secrets, paths, package manager, output) +- [src/prompts](src/prompts): interactive setup prompts (`@clack/prompts`) +- [src/utils](src/utils): repo and env-file helpers +- [verify](verify): the conformance harness (shipped with the package) +- [templates](templates): static template assets + +## Conventions + +- **TypeScript, ESM** (`"type": "module"`). Local imports use `.js` extensions (NodeNext resolution). +- **Releases use Changesets.** A user-facing change needs a changeset (`npm run changeset`). A push to + `main` opens a "version packages" PR that bumps the version and writes `CHANGELOG.md`; merging that + PR publishes to npm. Do not hand-edit the version or `CHANGELOG.md`. +- **Commits**: Conventional Commits (`feat:`, `fix:`, `chore:`, `ci:`, `test:`, `docs:`). +- **Do not use em dashes** in public-facing text: commit messages, code comments, PR and issue + descriptions, changesets, and docs. Use a comma, parentheses, or a separate sentence instead. +- Keep comments minimal. Comment only when the code genuinely needs explaining (a non-obvious reason + or a gotcha); do not narrate what the code plainly does. + +## Before You Finish A Change + +- Run `npm run build` (the root package's only build step). +- If you touched the harness: `cd verify/harness && npx tsc --noEmit`, then run `seamless verify` + (`--local` to exercise local SDK source, or `--api-only` for a fast pass). +- Add a changeset for any user-facing change. + +## Known Maintenance Traps + +- **Sibling-repo branches**: the server's integration branch is `dev` (its `main` lags), so the verify + CI workflow defaults the server checkout to `dev`. The api, react, and starter use `main`. +- **`--local` needs SDK dependencies**: it builds the server (pnpm) and the React SDK (npm) from source + on the host, so those repos must have their dependencies installed first. CI installs them explicitly. +- **OAuth mock networking**: the in-process mock OIDC is reached by the browser and harness via + `localhost`, but by the API container via `host.docker.internal`, so the provider config splits the + authorize URL from the token / userinfo URLs. +- **Adapter OTP limiter**: the adapter funnels all OTP through one client IP, so the API's per-IP OTP + limiter (10 per 15 minutes, hardcoded) bounds adapter / react OTP traffic. Keep specs off it where + possible (for example, magic-link login instead of a second email-OTP round trip). +- **Version pins**: [verify/adapter-app](verify/adapter-app) pins a specific `@seamless-auth/express` + version and the starter pins `@seamless-auth/react`. Bump these when new versions publish. From fbcc17e51796763bea4aa6c57b6fd3cccb1879d9 Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Mon, 29 Jun 2026 19:24:30 +0200 Subject: [PATCH 2/2] chore(verify): pin adapter to @seamless-auth/express ^0.6.0 (stable) --- .changeset/bump-adapter-express-pin.md | 7 +++++++ AGENTS.md | 4 ++-- verify/adapter-app/package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 .changeset/bump-adapter-express-pin.md diff --git a/.changeset/bump-adapter-express-pin.md b/.changeset/bump-adapter-express-pin.md new file mode 100644 index 0000000..875a36e --- /dev/null +++ b/.changeset/bump-adapter-express-pin.md @@ -0,0 +1,7 @@ +--- +"seamless-cli": patch +--- + +Bump the verify adapter to `@seamless-auth/express@^0.6.0` (the stable release that includes the +registration-session and non-JSON-response fixes), so the released conformance run tests against +the current published packages. diff --git a/AGENTS.md b/AGENTS.md index dcf3ef4..7c07d8f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -93,5 +93,5 @@ Modes and sibling repos: - **Adapter OTP limiter**: the adapter funnels all OTP through one client IP, so the API's per-IP OTP limiter (10 per 15 minutes, hardcoded) bounds adapter / react OTP traffic. Keep specs off it where possible (for example, magic-link login instead of a second email-OTP round trip). -- **Version pins**: [verify/adapter-app](verify/adapter-app) pins a specific `@seamless-auth/express` - version and the starter pins `@seamless-auth/react`. Bump these when new versions publish. +- **Version pins**: [verify/adapter-app](verify/adapter-app) pins `@seamless-auth/express` and the + starter pins `@seamless-auth/react`. Bump these when new versions publish. diff --git a/verify/adapter-app/package.json b/verify/adapter-app/package.json index 97c7381..ce0e884 100644 --- a/verify/adapter-app/package.json +++ b/verify/adapter-app/package.json @@ -5,7 +5,7 @@ "type": "module", "description": "Minimal adopter backend for the conformance harness — real @seamless-auth/express with a capture transport.", "dependencies": { - "@seamless-auth/express": "0.6.0-beta.20260629083811", + "@seamless-auth/express": "^0.6.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", "express": "^4.19.2"