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>
11 KiB
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.tsfiles 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 — runscd 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(servestest-results/html-report) - Fixtures & page objects live in
e2e/alongsidetests/
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
anyunless 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 && tscperform the actual type checks; there is no single repo-widetypecheckscript - 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>.tsinelectron/migrations/andserver/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
catchErrorin 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 inelectron/entities/, migrations inelectron/migrations/ - Server data source: wired up under
server/src/db/— entities inserver/src/entities/, migrations inserver/src/migrations/ - Always write a migration for schema changes. Generate with
npm run migration:generate(Electron) or the equivalent insideserver/ - 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.tsfiles - Schema changes are usually hard to reverse and surprising without context — see
agents-docs/AGENTS_ADRS.mdfor 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/andtoju-app/src/app/infrastructure/realtime/ - IPC channels between Electron preload and renderer — surface defined in
electron/preload.tsand theapi/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 tomain/masterpublish-draft-release.yml— publishes draft releasesdeploy-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
teaCLI 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) orRelates 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.
# --- 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, plusnpm run test:e2eif behavior is user-visible) npm run lintpasses- 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.mdupdated if a domain term was resolved or introduced (seeagents-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.mdif this session produced a correction, revert, or hidden constraint (see triggers inagents-docs/AGENT_WORKFLOW.md) - PR opened with summary and linked issues
- Gitea Workflows checks passing