-
Notifications
You must be signed in to change notification settings - Fork 29
Add AGENTS.md files to guide AI coding assistants #1032
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jimbojw
wants to merge
6
commits into
PAIR-code:main
Choose a base branch
from
jimbojw:1020-add-agents-md-files
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
c15b5a2
docs: Add AGENTS.md files
jimbojw 01b5531
docs: Add backlinks, common pitfalls and other details to AGENTS.md f…
jimbojw cf2f87f
build: Mark generated types.py file as AUTO-GENERATED to discourage d…
jimbojw bc91e82
docs: Add missing details in AGENTS.md files
jimbojw ae7557d
docs: Add information revealed by git history analysis as useful for …
jimbojw 98e9e48
docs: Add common pitfalls, instructions on adding callable endpoints,…
jimbojw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| # AGENTS.md — Deliberate Lab (root) | ||
|
|
||
| Deliberate Lab is a platform for running online research experiments on | ||
| human + LLM group dynamics. This file orients AI coding assistants to the | ||
| monorepo structure, conventions, and workflows. | ||
|
|
||
| ## Keeping AGENTS.md in sync | ||
|
|
||
| These `AGENTS.md` files document conventions that should be followed by | ||
| default. If a user request conflicts with the guidance here, **raise the | ||
| concern** — ask which takes precedence (their idea or the documented | ||
| convention) before proceeding. Whichever direction is chosen, update the | ||
| relevant `AGENTS.md` file(s) to match so documentation and code stay in | ||
| sync. | ||
|
|
||
| ## Architecture | ||
|
|
||
| This is an npm workspaces monorepo with three packages: | ||
|
|
||
| | Workspace | Path | Purpose | | ||
| |-----------|------|---------| | ||
| | `@deliberation-lab/utils` | `utils/` | Shared TypeScript types, validation, and utilities | | ||
| | `functions` | `functions/` | Firebase Cloud Functions (HTTP endpoints + Firestore triggers) | | ||
| | `deliberate-lab` | `frontend/` | Lit Element + MobX single-page app (Webpack) | | ||
|
|
||
| Other top-level directories: | ||
|
|
||
| - `firestore/` — Firestore security rules, database rules, and indexes | ||
| - `docs/` — Jekyll documentation site (GitHub Pages) | ||
| - `scripts/` — pip-installable Python API client (`deliberate_lab`) with auto-generated Pydantic types + a Node.js doctor script (see `scripts/AGENTS.md`) | ||
| - `emulator_test_config/` — Static config for Firebase emulator imports | ||
|
|
||
| ### Dependency graph | ||
|
|
||
| ``` | ||
| utils ──► frontend | ||
| │ | ||
| └────► functions | ||
| · | ||
| ·····► scripts/types.py (auto-generated via npm run update-schemas) | ||
| ``` | ||
|
|
||
| `utils` is a shared library consumed by both `frontend` and `functions`. | ||
| **Always build `utils` first** — the other two workspaces depend on it. | ||
|
|
||
| ## Getting started | ||
|
|
||
| - **Node ≥22** is required (see `.nvmrc`) | ||
| - Install all dependencies from the repo root: `npm ci` | ||
| - Run everything locally: `./run_locally.sh` | ||
| - Diagnose setup problems: `npm run doctor` | ||
|
|
||
| `run_locally.sh` copies required config files (`.firebaserc`, | ||
| `firebase_config.ts`, `index.html`) if they are missing, builds `utils` and | ||
| `functions`, starts file watchers for both, launches the Firebase emulators | ||
| (with seed data from `emulator_test_config/`), and serves the frontend at | ||
| `http://localhost:4201`. | ||
|
|
||
| > [!IMPORTANT] | ||
| > Always run **npm** commands from the **repository root** using the | ||
| > `--workspace` (or `-w`) flag. Do **not** `cd` into subdirectories for | ||
| > npm operations. | ||
| > | ||
| > ```sh | ||
| > npm run build -w utils | ||
| > npm test -w functions | ||
| > npm run start -w frontend | ||
| > ``` | ||
| > | ||
| > This matches the convention used in `cloudbuild.yaml` and ensures | ||
| > consistent dependency resolution via npm workspaces. | ||
| > | ||
| > Python tooling (`uv`, `pyright`) in `scripts/` is the exception — those | ||
| > commands expect to run from the `scripts/` directory where | ||
| > `pyproject.toml` lives. | ||
|
|
||
| ## Linting & formatting | ||
|
|
||
| - **Prettier** formats `.json`, `.ts`, `.html`, `.scss`, and `.css` files | ||
| - **ESLint** uses the **flat config** format (`eslint.config.mjs`); the | ||
| project does **not** have a `.eslintrc.*` file | ||
| - `@typescript-eslint/no-explicit-any` is set to `error` — do not use `any` | ||
| - **Husky** + **lint-staged** runs both Prettier and ESLint on pre-commit | ||
| for the same file set (`*.{json,ts,html,scss,css}`) | ||
| - Frontend files get browser globals; everything else gets Node globals | ||
|
|
||
| ## CI | ||
|
|
||
| `cloudbuild.yaml` drives all builds. The `_DEPLOYMENT_TYPE` substitution | ||
| variable controls which steps run: | ||
|
|
||
| | Value | What it does | | ||
| |-------|-------------| | ||
| | `test` | Lint, format check, and unit tests for all workspaces (no deploy) | | ||
| | `functions` | Build + deploy Cloud Functions | | ||
| | `frontend` | Build + deploy frontend to App Engine | | ||
| | `rules` | Deploy Firestore security rules | | ||
| | `indexes` | Deploy Firestore indexes | | ||
| | `all` | All of the above | | ||
|
|
||
| GitHub Actions (`.github/workflows/ci.yaml`) also runs a **schema sync | ||
| check**: if types in `utils` change, `docs/assets/api/schemas.json` and | ||
| `scripts/deliberate_lab/types.py` must be regenerated or CI will fail. | ||
| Run `npm run update-schemas` from the repo root to fix this (requires | ||
| Python 3.12+ and `uv` — see `scripts/AGENTS.md` for setup). | ||
|
|
||
| ## Testing | ||
|
|
||
| Each workspace has its own `npm test`: | ||
|
|
||
| ```sh | ||
| npm test -w utils # Jest; unit tests colocated with source | ||
| npm test -w functions # Jest; requires Java 21 for Firebase emulator | ||
| npm test -w frontend # Jest | ||
| ``` | ||
|
|
||
| Functions tests run against the Firebase emulator using | ||
| `firebase-test.json`. The integration test in | ||
| `cohort_definitions.integration.test.ts` is large and slow. | ||
|
|
||
| ## Firebase config | ||
|
|
||
| | File | Purpose | | ||
| |------|---------| | ||
| | `firebase.json` | Local dev emulator config | | ||
| | `firebase-test.json` | Emulator config for CI / test runs | | ||
| | `.firebaserc.example` | Template for project aliases (copy to `.firebaserc`) | | ||
| | `firestore/firestore.rules` | Firestore security rules | | ||
| | `firestore/database.rules.json` | Realtime Database rules | | ||
| | `firestore/storage.rules` | Cloud Storage rules | | ||
| | `firestore/indexes.json` | Firestore composite indexes | | ||
|
|
||
| ## Import convention | ||
|
|
||
| Both `frontend` and `functions` import from `utils` using the npm workspace | ||
| package name: | ||
|
|
||
| ```ts | ||
| import {StageKind, ExperimentConfig} from '@deliberation-lab/utils'; | ||
| ``` | ||
|
|
||
| Do **not** use relative paths to reach into `utils/src/` — always import | ||
| from `@deliberation-lab/utils`. | ||
|
|
||
| ## Stage system | ||
|
|
||
| Experiments are composed of ordered **stages** (chat, survey, chip | ||
| negotiation, ranking, etc.). The `StageKind` enum in | ||
| `utils/src/stages/stage.ts` lists all stage types. | ||
|
|
||
| Adding a new stage type touches **all three workspaces**: | ||
|
|
||
| 1. **`utils/src/stages/`** — types, validation, manager, prompts | ||
| 2. **`functions/src/stages/`** — backend endpoint + trigger logic | ||
| 3. **`frontend/src/components/stages/`** — config, preview, and answer UI components | ||
|
|
||
| See each workspace's `AGENTS.md` for detailed guidance. | ||
|
|
||
| ## Common pitfalls | ||
|
|
||
| 1. **Forgetting to rebuild `utils`** — `frontend` and `functions` consume | ||
| the compiled output in `utils/dist/`. After changing `utils` source, | ||
| rebuild it (`npm run build -w utils`) before testing downstream | ||
| workspaces, or changes won't be picked up. | ||
| 2. **Running `npm` from a subdirectory** — always run from the repo root | ||
| with `-w <workspace>` (see above). | ||
| 3. **Editing `scripts/deliberate_lab/types.py` by hand** — this file is | ||
| auto-generated and will be overwritten by `npm run update-schemas`. | ||
| 4. **Missing Java 21 for `functions` tests** — the Firebase emulator | ||
| requires Java 21. Unit-only tests can be run without it via | ||
| `npm run test:unit -w functions`. | ||
| 5. **Forgetting to run `npm run update-schemas`** — if you change types | ||
| in `utils`, CI will fail the schema sync check until schemas are | ||
| regenerated. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| # AGENTS.md — `frontend` | ||
|
|
||
| Lit Element + MobX single-page application built with Webpack. | ||
| See also `frontend/README.md` for additional context on routing, | ||
| Firebase setup, and experiment configuration. | ||
|
|
||
| > See also: [root AGENTS.md](../AGENTS.md) for monorepo-wide conventions. | ||
|
|
||
| ## Build & test | ||
|
|
||
| From the **repository root**: | ||
|
|
||
| ```sh | ||
| npm run start -w frontend # Build + serve (dev, localhost:4201) | ||
| npm run build -w frontend # Dev build only | ||
| npm run build:prod -w frontend # Production build | ||
| npm test -w frontend # Run Jest tests | ||
| ``` | ||
|
|
||
| For local dev, copy config files first (or use `run_locally.sh` which | ||
| handles this automatically): | ||
|
|
||
| ```sh | ||
| cp frontend/firebase_config.example.ts frontend/firebase_config.ts | ||
| cp frontend/index.example.html frontend/index.html | ||
| ``` | ||
|
|
||
| ## Component architecture | ||
|
|
||
| ### `src/components/` — Feature components | ||
|
|
||
| Organized into 17 subdirectories by feature area: | ||
|
|
||
| | Directory | Purpose | | ||
| |-----------|---------| | ||
| | `stages/` | Stage config, preview, and answer components (largest subdirectory) | | ||
| | `experiment_builder/` | Experiment creation/editing UI | | ||
| | `experiment_dashboard/` | Experiment monitoring dashboard | | ||
| | `experimenter/` | Experimenter-facing views | | ||
| | `participant_view/` | Participant-facing experiment UI | | ||
| | `chat/` | Chat interface components | | ||
| | `header/` | App header (includes routing logic) | | ||
| | `sidenav/` | Side navigation (includes routing logic) | | ||
| | `login/` | Authentication UI | | ||
| | `settings/` | App settings | | ||
| | `gallery/` | Experiment gallery/templates | | ||
| | `progress/` | Progress indicators | | ||
| | `popup/` | Modal/popup components | | ||
| | `participant_profile/` | Participant profile display | | ||
| | `avatar_picker/` | Avatar selection UI | | ||
| | `admin/` | Admin panel | | ||
| | `shared/` | Shared component utilities | | ||
|
|
||
| ### `src/pair-components/` — Reusable primitives | ||
|
|
||
| Standalone UI primitives: `button`, `icon`, `icon_button`, `textarea`, | ||
| `textarea_template`, `tooltip`, `menu`, `info_popup`. Also contains | ||
| `types.ts` (shared primitive types) and `utils.ts` (helper functions). | ||
| These are general-purpose and not tied to project state. | ||
|
|
||
| `shared.css` in this directory provides base styles used across primitives. | ||
|
|
||
| > [!NOTE] | ||
| > Primitives use a **mix** of `.css` and `.scss` for styles. `button`, | ||
| > `icon`, `icon_button`, `textarea`, `textarea_template`, and `tooltip` | ||
| > use plain `.css`; `menu` and `info_popup` use `.scss`. Follow the | ||
| > existing pattern when modifying a primitive. | ||
|
|
||
| ## Service layer | ||
|
|
||
| MobX-based services in `src/services/`: | ||
|
|
||
| | Service | Role | | ||
| |---------|------| | ||
| | `service.ts` | Abstract `Service` base class (all services extend this) | | ||
| | `initialization.service.ts` | Orchestrates app startup (initializes analytics, Firebase, routing) | | ||
| | `firebase.service.ts` | Firebase connection (Firestore, Auth) | | ||
| | `auth.service.ts` | Authentication and login state | | ||
| | `experiment.manager.ts` | Experiment data management (largest service) | | ||
| | `experiment.editor.ts` | Experiment editing state | | ||
| | `experiment.service.ts` | Current experiment subscription | | ||
| | `participant.service.ts` | Participant state and stage progress | | ||
| | `participant.answer.ts` | Participant answer management | | ||
| | `cohort.service.ts` | Cohort management | | ||
| | `router.service.ts` | App routing and page definitions | | ||
| | `home.service.ts` | Home page experiment list | | ||
| | `settings.service.ts` | App settings | | ||
| | `admin.service.ts` | Admin operations | | ||
| | `analytics.service.ts` | Google Analytics | | ||
| | `presence.service.ts` | Participant online/offline presence | | ||
|
|
||
| Services are wired together via `src/service_provider.ts`, which | ||
| creates all service instances and injects dependencies. Components access | ||
| services through the service provider — see existing components for the | ||
| pattern. | ||
|
|
||
| ## Stage components | ||
|
|
||
| Stage UI components live in `src/components/stages/`. Each stage type | ||
| typically has three components: | ||
|
|
||
| | Pattern | Purpose | | ||
| |---------|---------| | ||
| | `<stage_type>_config.ts` | Experimenter-facing configuration editor | | ||
| | `<stage_type>_preview.ts` | Participant-facing stage view | | ||
| | `<stage_type>_answer.ts` | Answer/response display component | | ||
|
|
||
| ## Styling | ||
|
|
||
| - **Material 3 Design** via SASS variables in `src/sass/`: | ||
| - `_colors.scss` — color palettes and theme tokens | ||
| - `_common.scss` — shared mixins and layout utilities | ||
| - `_typescale.scss` — typography scale definitions | ||
| - `src/pair-components/shared.css` — base styles for primitives | ||
| - Use SASS variables and mixins — **do not hardcode** colors, spacing, or | ||
| font values | ||
|
|
||
| ## Key files | ||
|
|
||
| | File | Role | | ||
| |------|------| | ||
| | `src/app.ts` | Root app component and page rendering | | ||
| | `src/index.ts` | App entry point | | ||
| | `src/service_provider.ts` | MobX service dependency injection | | ||
| | `src/shared/callables.ts` | Typed wrappers for **all** Cloud Function calls — every new callable endpoint in `functions` needs a corresponding wrapper here or it is unreachable from the UI | | ||
| | `src/shared/` | Shared config, constants, and utilities | | ||
|
|
||
| ## Common pitfalls | ||
|
|
||
| 1. **Hardcoding colors or spacing** — use SASS variables and mixins from | ||
| `src/sass/`. Do not hardcode hex colors, pixel sizes, or font values. | ||
| 2. **Mixing CSS formats in pair-components** — check the existing style file | ||
| format (`.css` vs `.scss`) before editing a primitive's styles. | ||
| 3. **Forgetting to register a new service** — new services must be | ||
| instantiated in `src/service_provider.ts` and extend the `Service` base | ||
| class. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In docs/developers/run-locally.md and run_locally.sh, we do cd into subdirectories for npm. Probably good to move those over - I wouldn't be surprised if a model followed those over an AGENTS.md file.
(Also, more of a personal opinion, but I feel like it's good to limit the degree of "IMPORTANT" flags in AGENTS.md, since the whole thing is always in the prompt whether or not the agent is doing anything relevant. This doesn't feel that important to me, and I'm not sure it'll need a separate callout at all once we get rid of the old pattern.)