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
7 changes: 7 additions & 0 deletions .changeset/bump-adapter-express-pin.md
Original file line number Diff line number Diff line change
@@ -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.
97 changes: 97 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -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 -- <command>` (`tsx`); or after building, `node dist/index.js <command>`
- Commands: `init [name]`, `check`, `bootstrap-admin <email>`, `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 <grep>`, `--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 `@seamless-auth/express` and the
starter pins `@seamless-auth/react`. Bump these when new versions publish.
2 changes: 1 addition & 1 deletion verify/adapter-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading