Shared guidance for coding agents in this repository. Tool-specific files should import or point
to this file instead of duplicating it. If AGENTS.local.md exists, read it before work because it
contains host-only setup.
Watchman is a self-hosted dashboard that polls home-lab services and exposes status, metrics, and controls. It is an npm-workspaces monorepo using React 18, TypeScript, Vite, Tailwind and shadcn/ui; Node, TypeScript and Fastify 5; REST and WebSocket transport; DuckDB configuration; Vitest; and Electron. License: AGPL-3.0-only.
| Workspace | Path |
|---|---|
@watchman/frontend |
apps/frontend/ |
@watchman/backend |
apps/backend/ |
| desktop | apps/desktop/ |
| shared | packages/* |
Search docs/ before changing code. Treat docs as intent and code as current behavior.
- Architectural change: read
docs/adr/; add the next numbered ADR instead of rewriting history. - Service integration: read
docs/guides/adding-services.mdand the relevantdocs/integrations/page, then use theadd-serviceskill. - Entry points:
docs/INDEX.md,docs/common-tasks.md,docs/architecture/index.md, anddocs/reference/code-patterns.md.
npm run deps:ci:portable
npm run dev
npm run dev:backend
npm run dev:frontend
npm run build
npm run typecheck
npm run lint
npm run lint:backend
npm run test
npm run test:frontend
npm run test:e2e
npm run generate:types
npm run dist
# from a workspace directory:
npx vitest run src/path/to/x.test.ts
npx vitest run --testNamePattern="name"These obligations are tracked here because Codex does not auto-load AGENTS.local.md when this
root file exists. AGENTS.local.md may add machine-specific convenience, but it cannot weaken or
replace these rules.
- In the devcontainer, Codex uses isolated container state. Codex authentication and configuration
do not synchronize with the host. Never copy
~/.codex/auth.jsoninto the container. Treat changes under container~/.codex/as ephemeral and report them before the session ends; tracked repository files under.agents/and.codex/persist through the workspace mount. - Codex browser tooling is the supported replacement for Claude's Playwright plugin. There is no
Codex TypeScript-LSP plugin in this project;
npm run typecheckand the relevant build/test commands are the authoritative diagnostics and must not be skipped because editor diagnostics appear clean.
- Backend entry:
apps/backend/src/index.ts. - Each monitored service extends
BaseService, implementscheckHealth()andgetStats(), and is registered throughbootstrap/registerServices.tsandServiceLifecycle. - Reuse transport, cache, circuit-breaker, and scheduler code under
apps/backend/src/infra/. - Service and multi-instance configuration belongs in the DuckDB store through
/configor the UI. Legacy{SERVICE}_{N}_*variables are imported once and then ignored. apps/backend/openapi.yamlis the API source of truth. After changing it, runnpm run generate:types. Until the client migration is complete, also keepapps/frontend/src/services/apiClient/types.tsaligned.- Backend uses ES2022+ ESM and
undefinedrather thannull. Prefer functions; service classes are the deliberate exception. - Frontend uses functional components, React Query, React Router v7, Tailwind, and
class-variance-authority. Its TypeScript configuration is intentionally relaxed.
This is a single-user trusted-network application. It intentionally has no authentication, CSRF
protection, or rate limiting; see ADR-017 and ADR-025. Do not expose the backend outside the trusted
network. Preserve the shared HTTP and WebSocket origin allowlist. Keep secrets in .env.local and
encrypted in DuckDB. Never log tokens or personal data; preserve Pino redaction.
- Before implementation, search the relevant project documentation and verify it against code.
- During an API change, update OpenAPI and route docs with the implementation, generate types, keep the hand-maintained client types aligned, and state compatibility.
- Once the implementation diff is stable and before final validation, use the
update-watchman-docsskill for any behavior, API, architecture, service, configuration, security, package, build, or workflow change that could make project knowledge stale. Change size does not determine whether documentation is required. - Update every affected documentation surface, or explicitly report why no documentation change
is warranted. Before any direct
docs/edit, readdocs/AGENTS.md. - After documentation and generated files are synchronized, run the checks appropriate to the changed surfaces below, plus applicable generated-artifact and documentation checks. If validation changes the implementation, repeat the documentation check. Instruction-only and documentation-only edits need relevant content and link checks, not the application suite.
- Service change: verify health, timeout, retry, circuit-breaker behavior, secret handling, and multi-instance behavior.
- Isolated edit: targeted test and lint.
- Cross-module edit: targeted tests, workspace lint, and typecheck.
- Security, persistence, or destructive edit: tests, lint, typecheck, build, and focused safety checks.
- Explain destructive or irreversible commands and get confirmation first.
Keep scope focused. Finish with changed files, checks run, skipped checks, residual risk, and
follow-ups. In regular local development sessions, leave the reviewed working-tree diff for the
LockBox git-agent; do not stage, sign, commit, or push. Only an explicitly authorized LockBox
git-agent publication session may commit directly to main unless the user asks for a branch.
Cloud publication follows the rules below.
Validate every external input with server-side Zod schemas. Use least-privilege service configuration, preserve the configured Pino secret redaction, and audit new dependencies before adding them.
Create a session note in docs/ only when it adds durable decisions, rationale, unresolved issues,
or operational lessons that are not already captured in the updated project documentation, or
when the user requests one. Do not duplicate the change summary merely because multiple files or
modules changed. Follow docs/AGENTS.md and use the update-watchman-docs skill for the note.
Run bash .codex/cloud/setup.sh as the Codex cloud environment setup command. Keep cloud secrets
disposable and non-production. Cloud sessions cannot validate host containers, macOS integration,
hardware-backed signing, or local service state; report those checks as skipped and leave them for
a local session. In cloud sessions, do not publish with shell Git commands, configure Git
credentials, or create a pull request with gh. The platform-managed Open pull request action
may create a pull request, and the connected GitHub integration may update the same branch for
pull-request-linked follow-ups. When the user explicitly requests it, that integration may merge
the pull request after all required checks and approvals pass and no blocking review remains. Do
not use an admin bypass or directly update a default or protected branch outside that approved
merge.