docs: scaffold agent instruction tree
Add AGENTS.md, CLAUDE.md, and the agents-docs/ tree (workflow, lessons, engineering standards, context map, ADR seed, feature template) plus a domain-bearing CONTEXT.md for each of the six subdomains: toju-app, electron, server, e2e, website, docs-site. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
222
agents-docs/ENGINEERING.md
Normal file
222
agents-docs/ENGINEERING.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# Engineering Standards & Workflows
|
||||
|
||||
This document defines shared engineering practices for **MetoYou / Toju**.
|
||||
|
||||
---
|
||||
|
||||
## Root README.md policy
|
||||
|
||||
`README.md` exists to answer:
|
||||
|
||||
- what this repo is
|
||||
- how to run it locally
|
||||
- where to find canonical documentation
|
||||
|
||||
Agents should update `README.md` when dev commands change, ports or startup steps change, or links to docs move.
|
||||
|
||||
Agents should **not** describe feature behavior, list API endpoints, or include request/response schemas. Canonical documentation lives under `agents-docs/` and (for product-client bounded contexts) under `toju-app/src/app/domains/<name>/README.md`.
|
||||
|
||||
---
|
||||
|
||||
## Testing standards
|
||||
|
||||
This repo runs two test stacks. Choose by what you're verifying.
|
||||
|
||||
### Unit / component tests — Vitest
|
||||
|
||||
- **Framework:** Vitest 4.x
|
||||
- **Where it runs:** the Angular product client (`toju-app/`) and any package that imports `@toju-app/*` modules; Electron has colocated `*.spec.ts` files that are wired through the same root Vitest config.
|
||||
- **Test suffix:** `*.spec.ts`
|
||||
- **Location:** colocated with source (`message-rules.ts` ↔ `message-rules.spec.ts`)
|
||||
- **Run all:** `npm run test` (from repo root — runs `cd toju-app && vitest run`)
|
||||
- **Watch:** `cd toju-app && npx vitest`
|
||||
- **Single file:** `cd toju-app && npx vitest run <relative-path>`
|
||||
- **Setup file:** `toju-app/src/test-setup.ts`
|
||||
|
||||
The server package does not currently have a test runner script — there is one colocated spec (`server/src/websocket/handler-plugin.spec.ts`) but no `test` script in `server/package.json`. If you add server-side tests, wire a `test` script and update this section.
|
||||
|
||||
### End-to-end — Playwright
|
||||
|
||||
- **Framework:** Playwright 1.59
|
||||
- **Location:** `e2e/tests/` organized by feature area (`voice/`, `chat/`, `screen-share/`, `settings/`, `auth/`)
|
||||
- **Run:** `npm run test:e2e` (headless), `npm run test:e2e:ui`, `npm run test:e2e:debug`
|
||||
- **Report:** `npm run test:e2e:report` (serves `test-results/html-report`)
|
||||
- **Fixtures & page objects** live in `e2e/` alongside `tests/`
|
||||
|
||||
E2E tests exercise the real Electron app against the real signaling server. The `.agents/skills/playwright-e2e/SKILL.md` describes the convention this repo uses for E2E test design — read it before adding new tests.
|
||||
|
||||
### TDD discipline
|
||||
|
||||
Write the failing test first. Run it, watch it fail, then write the smallest code that makes it pass. This rule is non-negotiable (see `/AGENTS.md` § CRITICAL).
|
||||
|
||||
Integration / cross-package work that needs a real database can rely on Electron's TypeORM + sql.js setup (in-memory by default) — no Testcontainers required.
|
||||
|
||||
---
|
||||
|
||||
## TypeScript standards
|
||||
|
||||
- Strict mode is enabled across all packages
|
||||
- Avoid `any` unless absolutely necessary; document why if used
|
||||
- Prettier (`.prettierrc.json`: `printWidth: 150`, single quotes, no trailing commas) handles formatting of Angular HTML templates only — ESLint stylistic rules handle TypeScript/JavaScript formatting
|
||||
- Angular CLI / `tsc -p tsconfig.electron.json` / `cd server && tsc` perform the actual type checks; there is no single repo-wide `typecheck` script
|
||||
- The repository uses npm workspaces (`npm@10.9.2`); cross-package imports go through workspace package names, not relative `../../` paths
|
||||
|
||||
---
|
||||
|
||||
## Naming conventions
|
||||
|
||||
Files and folders are predominantly **kebab-case**, with a few well-established suffixes:
|
||||
|
||||
- Angular components: `chat-messages.component.ts`, `user-list.component.html`, `*.component.scss`
|
||||
- Angular services: `link-metadata.service.ts`
|
||||
- Angular directives: `chat-image-proxy-fallback.directive.ts`
|
||||
- Domain rules (pure functions): `message.rules.ts`, `link-embed.rules.ts`
|
||||
- Domain models: `chat-messages.model.ts`
|
||||
- NgRx slices: `chat.actions.ts`, `chat.reducer.ts`, `chat.effects.ts`, `chat.selectors.ts`
|
||||
- CQRS handlers (server and electron): `registerUser.ts`, `deleteServer.ts`, `upsertServer.ts` — **camelCase** for handler files (mirrors the command/query name)
|
||||
- Test files: `<name>.spec.ts` (Vitest), `<feature>.spec.ts` (Playwright)
|
||||
- Migrations (TypeORM): `<timestamp>-<name>.ts` in `electron/migrations/` and `server/migrations/`
|
||||
|
||||
Types, interfaces, classes, and Angular component classes: `PascalCase`. Functions, variables, NgRx action props: `camelCase`. Constants: `SCREAMING_SNAKE_CASE`.
|
||||
|
||||
When in doubt, mimic the closest existing file in the same folder.
|
||||
|
||||
---
|
||||
|
||||
## Error handling
|
||||
|
||||
- Use typed errors. Never `throw 'string literal'`
|
||||
- Never swallow errors silently — at minimum, log with enough context to find the call site
|
||||
- Centralize cross-cutting error handling: Express error middleware on the server, NgRx effect `catchError` in the product client, and IPC error envelopes in Electron handlers
|
||||
- Surfacing errors to the user is a UX concern — degrade gracefully (toast, retry button, offline banner) rather than crashing the renderer
|
||||
|
||||
---
|
||||
|
||||
## Database guidelines
|
||||
|
||||
Persistence uses **TypeORM 0.3** with **sql.js / SQLite** in both the Electron desktop shell and the signaling server.
|
||||
|
||||
- **Electron data source:** `electron/data-source.ts` — entities in `electron/entities/`, migrations in `electron/migrations/`
|
||||
- **Server data source:** wired up under `server/src/db/` — entities in `server/src/entities/`, migrations in `server/src/migrations/`
|
||||
- Always write a migration for schema changes. Generate with `npm run migration:generate` (Electron) or the equivalent inside `server/`
|
||||
- Run pending migrations: `npm run migration:run` (Electron)
|
||||
- Never edit a migration after it has shipped — write a new one
|
||||
- Entity classes use TypeORM decorators; keep persistence concerns out of domain `*.rules.ts` files
|
||||
- Schema changes are usually **hard to reverse** and **surprising without context** — see `agents-docs/AGENTS_ADRS.md` for when to also write an ADR
|
||||
|
||||
---
|
||||
|
||||
## Realtime, IPC, and plugins
|
||||
|
||||
These are the three cross-context contracts that change most often. Treat each as a public contract that requires `agents-docs/features/` updates when it changes:
|
||||
|
||||
- **WebSocket messages** between client and server — schemas live under `server/src/websocket/` and `toju-app/src/app/infrastructure/realtime/`
|
||||
- **IPC channels** between Electron preload and renderer — surface defined in `electron/preload.ts` and the `api/` directory
|
||||
- **Plugin manifests** consumed by `electron/plugin-library.ts` — the runtime contract that third-party plugins depend on
|
||||
|
||||
Behavioral changes to any of these qualify as a feature-doc update under the rule in `/AGENTS.md`.
|
||||
|
||||
---
|
||||
|
||||
## CI/CD
|
||||
|
||||
- CI runs on **Gitea Workflows** (a GitHub Actions–compatible runner) — workflow files in `.gitea/workflows/`:
|
||||
- `release-draft.yml` — queues release builds on push to `main` / `master`
|
||||
- `publish-draft-release.yml` — publishes draft releases
|
||||
- `deploy-web-apps.yml` — deploys the marketing site and Docusaurus docs
|
||||
- All checks must pass before merging a PR
|
||||
- Workflow status is visible in the Gitea PR view; use the web UI or `tea` CLI to inspect runs
|
||||
|
||||
There is **no pre-commit hook** configured (no Husky, no pre-commit, no lefthook). Lint/build are enforced by CI, not by local hooks.
|
||||
|
||||
---
|
||||
|
||||
## Commit message conventions
|
||||
|
||||
Use **Conventional Commits** with no scope. The recent history is consistent on this:
|
||||
|
||||
```
|
||||
feat: Update how messages load and sync, allow plugins to import messages
|
||||
fix: Mobile style fixes and other small ui fixes
|
||||
perf: server navigation
|
||||
refactor: Remove hardcoded values
|
||||
test: Ensure tests work after latest changes
|
||||
```
|
||||
|
||||
Allowed prefixes (observed across the last 100 commits): `feat`, `fix`, `chore`, `docs`, `perf`, `refactor`, `test`. Subject is sentence case with no trailing period.
|
||||
|
||||
If your change resolves a Gitea issue, add `Fixes #<n>` (or `Relates to #<n>`) in the PR body — Gitea supports the same auto-close keywords as GitHub.
|
||||
|
||||
---
|
||||
|
||||
## Issue linking
|
||||
|
||||
- Issues live in the Gitea instance at `git.azaaxin.com/myxelium/Toju`
|
||||
- Reference them in PR bodies with `Fixes #<n>` (auto-closes on merge) or `Relates to #<n>` (cross-reference only)
|
||||
- Commits themselves do not need issue numbers — keep subjects clean and Conventional
|
||||
|
||||
---
|
||||
|
||||
## Commands reference
|
||||
|
||||
Run these from the repository root unless otherwise noted.
|
||||
|
||||
```bash
|
||||
# --- setup ---
|
||||
npm install # install root + workspaces
|
||||
cd server && npm install # server has its own lockfile
|
||||
cd website && npm install # only if working on the marketing site
|
||||
cd docs-site && npm install # only if working on app/plugin docs
|
||||
|
||||
# --- common dev flows ---
|
||||
npm run dev # full stack: server + Angular client + Electron (via dev.sh)
|
||||
npm run start # Angular product client only (ng serve on :4200)
|
||||
npm run electron:dev # Angular client + Electron, no signaling server
|
||||
npm run server:dev # signaling server only (ts-node-dev)
|
||||
|
||||
# --- testing ---
|
||||
npm run test # toju-app Vitest suite
|
||||
npm run test:e2e # Playwright (headless)
|
||||
npm run test:e2e:ui # Playwright UI mode
|
||||
npm run test:e2e:debug # Playwright debug
|
||||
npm run test:e2e:report # serve last Playwright HTML report
|
||||
|
||||
# --- type / build (also serves as typecheck) ---
|
||||
npm run build # Angular product client → dist/client
|
||||
npm run build:electron # tsc -p tsconfig.electron.json → dist/electron
|
||||
npm run build:docs # Docusaurus → docs-site/build
|
||||
cd server && npm run build # server tsc
|
||||
npm run build:all # all of the above
|
||||
|
||||
# --- lint / format ---
|
||||
npm run lint # eslint .
|
||||
npm run lint:fix # format + sort:props + eslint --fix
|
||||
npm run format # prettier on Angular HTML templates only
|
||||
npm run format:check # prettier --check on HTML templates
|
||||
|
||||
# --- database migrations (Electron) ---
|
||||
npm run migration:generate # autogenerate from entity diff
|
||||
npm run migration:create # empty migration scaffold
|
||||
npm run migration:run # apply pending
|
||||
npm run migration:revert # roll back last
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Completion checklist
|
||||
|
||||
Before marking work complete:
|
||||
|
||||
- [ ] Tests written before implementation
|
||||
- [ ] All tests passing (`npm run test`, plus `npm run test:e2e` if behavior is user-visible)
|
||||
- [ ] `npm run lint` passes
|
||||
- [ ] Affected package builds: `npm run build` / `npm run build:electron` / `cd server && npm run build`
|
||||
- [ ] Naming conventions followed
|
||||
- [ ] Errors handled
|
||||
- [ ] Security considered (no secrets in code, no plaintext token logging, no IPC handler accepting arbitrary file paths)
|
||||
- [ ] Feature docs updated if contract/schema/invariant changed (see `agents-docs/AGENTS_FEATURES.md`)
|
||||
- [ ] `CONTEXT.md` updated if a domain term was resolved or introduced (see `agents-docs/AGENTS_CONTEXT.md`)
|
||||
- [ ] ADR written if a hard-to-reverse decision was made (see `agents-docs/AGENTS_ADRS.md`)
|
||||
- [ ] Lesson recorded in `agents-docs/LESSONS.md` if this session produced a correction, revert, or hidden constraint (see triggers in `agents-docs/AGENT_WORKFLOW.md`)
|
||||
- [ ] PR opened with summary and linked issues
|
||||
- [ ] Gitea Workflows checks passing
|
||||
Reference in New Issue
Block a user