mirror of https://github.com/usememos/memos
docs: rewrite agent repository guide
parent
2a4638b332
commit
5e71c0a737
@ -1,105 +1,125 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file provides guidance to AI coding agents when working with code in this repository.
|
||||
Repository instructions for AI coding agents. Keep this file short, concrete, and tied to commands that actually work in this
|
||||
repo. If a fact here conflicts with source files or CI config, trust the source file and update this guide.
|
||||
|
||||
Self-hosted note-taking tool. Go 1.26 backend (Echo v5, Connect RPC + gRPC-Gateway), React 18 + TypeScript 6 + Vite 7 frontend, Protocol Buffers API, SQLite/MySQL/PostgreSQL.
|
||||
## Project Snapshot
|
||||
|
||||
Memos is a self-hosted note-taking app.
|
||||
|
||||
- Backend: Go 1.26.2, Echo v5, Connect RPC, gRPC-Gateway, Protocol Buffers.
|
||||
- Frontend: React 19, TypeScript 6, Vite 8, Tailwind CSS v4, React Query v5.
|
||||
- Storage: SQLite, MySQL, PostgreSQL.
|
||||
- Generated API outputs: `proto/gen/` for Go/OpenAPI, `web/src/types/proto/` for TypeScript.
|
||||
|
||||
## Working Rules
|
||||
|
||||
- Read relevant code before editing; prefer local patterns over new abstractions.
|
||||
- Keep diffs scoped. Do not do repo-wide cleanup, dependency churn, or generated-file rewrites unless the task requires it.
|
||||
- Do not hand-edit generated proto outputs. Change `.proto` files, then run `buf generate`.
|
||||
- Add migrations for all database drivers when schema changes, and update each driver's `LATEST.sql`.
|
||||
- Add public API endpoints to `server/router/api/v1/acl_config.go`.
|
||||
- Ask before adding heavy dependencies, changing auth/token behavior, or altering Docker/release workflows.
|
||||
|
||||
## Commands
|
||||
|
||||
Run from the repository root unless a command starts with `cd`.
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
go run ./cmd/memos --port 8081 # Start dev server
|
||||
go test ./... # Run all tests
|
||||
go test -v ./store/... # Run store tests (all 3 DB drivers via TestContainers)
|
||||
go test -v -race ./server/... # Run server tests with race detection
|
||||
go test -v -race ./internal/... # Run internal package tests with race detection
|
||||
go test -v -run TestFoo ./pkg/... # Run a single test
|
||||
go run ./cmd/memos --port 8081 # Start backend dev server
|
||||
go test ./... # Run all Go tests
|
||||
go test -v ./store/... # Store tests, including DB drivers via TestContainers
|
||||
go test -v -race ./server/... # Server tests with race detector
|
||||
go test -v -race ./internal/... # Internal package tests with race detector
|
||||
go test -v -run TestFoo ./pkg/... # Run matching Go tests
|
||||
go mod tidy -go=1.26.2 # Match CI tidy check
|
||||
golangci-lint run # Lint (v2, config: .golangci.yaml)
|
||||
golangci-lint run --fix # Auto-fix lint issues (includes goimports)
|
||||
|
||||
# Frontend (cd web)
|
||||
pnpm install # Install deps
|
||||
pnpm dev # Dev server (:3001, proxies API to :8081)
|
||||
pnpm lint # Type check + Biome lint
|
||||
pnpm lint:fix # Auto-fix lint issues
|
||||
pnpm format # Format code
|
||||
pnpm build # Production build
|
||||
pnpm release # Build to server/router/frontend/dist
|
||||
|
||||
# Protocol Buffers (cd proto)
|
||||
buf generate # Regenerate Go + TypeScript + OpenAPI
|
||||
buf lint # Lint proto files
|
||||
buf format -w # Format proto files
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
cmd/memos/main.go # Cobra CLI + Viper config, server init
|
||||
|
||||
server/
|
||||
├── server.go # Echo v5 HTTP server, background runners
|
||||
├── auth/ # JWT access (15min) + refresh (30d) tokens, PAT
|
||||
├── router/
|
||||
│ ├── api/v1/ # 8 gRPC services (Connect + Gateway)
|
||||
│ │ ├── acl_config.go # Public endpoints whitelist
|
||||
│ │ ├── sse_hub.go # Server-Sent Events (live updates)
|
||||
│ ├── frontend/ # SPA static file serving
|
||||
│ ├── fileserver/ # Native HTTP file server (thumbnails, range requests)
|
||||
│ └── rss/ # RSS feeds
|
||||
└── runner/ # Background: memo payload processing, S3 presign refresh
|
||||
|
||||
store/
|
||||
├── driver.go # Database driver interface
|
||||
├── store.go # Store wrapper + in-memory cache (TTL 10min, max 1000)
|
||||
├── migrator.go # Migration logic (LATEST.sql for fresh, incremental for upgrades)
|
||||
└── db/{sqlite,mysql,postgres}/ # Driver implementations
|
||||
|
||||
proto/
|
||||
├── api/v1/ # Service definitions
|
||||
├── store/ # Internal storage messages
|
||||
└── gen/ # Generated Go, TypeScript, OpenAPI
|
||||
|
||||
internal/ # app-private packages: scheduler, cron, email, filter (CEL),
|
||||
# webhook, markdown (Goldmark), httpgetter, idp (OAuth2), storage/s3
|
||||
|
||||
web/src/
|
||||
├── connect.ts # Connect RPC client + auth interceptor + token refresh
|
||||
├── auth-state.ts # Token storage (localStorage + BroadcastChannel cross-tab)
|
||||
├── contexts/ # AuthContext, InstanceContext, ViewContext, MemoFilterContext
|
||||
├── hooks/ # React Query hooks (useMemoQueries, useUserQueries, etc.)
|
||||
├── lib/query-client.ts # React Query v5 (staleTime: 30s, gcTime: 5min)
|
||||
├── router/index.tsx # Route definitions
|
||||
├── components/ # UI components (Radix UI primitives, MemoEditor, Settings, etc.)
|
||||
├── themes/ # CSS themes (default, dark, paper) — OKLch color tokens
|
||||
└── pages/ # Page components
|
||||
golangci-lint run # Go lint, config: .golangci.yaml
|
||||
golangci-lint run --fix # Auto-fix lint, including goimports
|
||||
|
||||
# Frontend
|
||||
cd web && pnpm install # Install dependencies
|
||||
cd web && pnpm dev # Dev server on :3001, proxying API to :8081
|
||||
cd web && pnpm lint # Type check + Biome lint
|
||||
cd web && pnpm test # Vitest unit tests
|
||||
cd web && pnpm build # Production build
|
||||
cd web && pnpm release # Build SPA into server/router/frontend/dist
|
||||
|
||||
# Protocol Buffers
|
||||
cd proto && buf generate # Regenerate Go + TypeScript + OpenAPI
|
||||
cd proto && buf lint # Lint proto files
|
||||
cd proto && buf format -w # Format proto files
|
||||
```
|
||||
|
||||
## Conventions
|
||||
|
||||
### Go
|
||||
- **Errors:** `errors.Wrap(err, "context")` from `github.com/pkg/errors`. Never `fmt.Errorf` (lint-enforced via forbidigo).
|
||||
- **gRPC errors:** `status.Errorf(codes.X, "message")` from service methods.
|
||||
- **Imports:** stdlib, then third-party, then local (`github.com/usememos/memos`). Enforced by goimports (runs as golangci-lint formatter).
|
||||
- **Comments:** All exported functions must have doc comments (godot enforced).
|
||||
|
||||
### Frontend
|
||||
- **Imports:** Use `@/` alias for absolute imports.
|
||||
- **Formatting:** Biome — 140 char lines, double quotes, always semicolons, 2-space indent.
|
||||
- **State:** Server data via React Query hooks (`hooks/`). Client state via React Context (`contexts/`).
|
||||
- **Styling:** Tailwind CSS v4 (`@tailwindcss/vite`), `cn()` utility (clsx + tailwind-merge), CVA for variants.
|
||||
|
||||
### Database & Proto
|
||||
- **DB changes:** Migration files for all 3 drivers + update `LATEST.sql`.
|
||||
- **Proto changes:** Run `buf generate`. Generated code: `proto/gen/` and `web/src/types/proto/`.
|
||||
- **Public endpoints:** Add to `server/router/api/v1/acl_config.go`.
|
||||
|
||||
## CI/CD
|
||||
|
||||
- **backend-tests.yml:** Go 1.26.2, `go mod tidy -go=1.26.2`, golangci-lint v2.11.3, tests parallelized by group (store, server, internal, other)
|
||||
- **build-canary-image.yml:** Builds frontend with `pnpm release`, then publishes canary multi-arch container images for linux/amd64 and linux/arm64
|
||||
- **frontend-tests.yml:** Node 24, pnpm 11, lint + build
|
||||
- **proto-linter.yml:** buf lint + format check
|
||||
- **release.yml:** On version tags, builds frontend once, packages binaries for Linux/macOS/Windows, and publishes release container images/tags
|
||||
- **Docker:** Multi-stage (`scripts/Dockerfile`), Alpine 3.21, non-root user, port 5230, multi-arch (amd64/arm64/arm/v7)
|
||||
## Code Map
|
||||
|
||||
| Path | Purpose |
|
||||
| --- | --- |
|
||||
| `cmd/memos/main.go` | Cobra/Viper CLI setup and server startup |
|
||||
| `server/server.go` | Echo HTTP server and background runner wiring |
|
||||
| `server/auth/` | JWT access tokens, refresh tokens, PAT handling |
|
||||
| `server/router/api/v1/` | Connect/gRPC-Gateway services, ACL config, SSE hub |
|
||||
| `server/router/frontend/` | Static SPA serving |
|
||||
| `server/router/fileserver/` | Native HTTP file serving, thumbnails, range requests |
|
||||
| `server/runner/` | Background memo processing and S3 presign refresh |
|
||||
| `store/` | Store facade, cache, migrations, driver interface |
|
||||
| `store/db/{sqlite,mysql,postgres}/` | Database-specific drivers and SQL |
|
||||
| `proto/api/v1/` | Public API service definitions |
|
||||
| `proto/store/` | Internal storage proto messages |
|
||||
| `internal/` | App-private packages: scheduler, cron, email, CEL filter, markdown, idp, S3 |
|
||||
| `web/src/connect.ts` | Connect RPC clients, auth interceptor, access-token refresh |
|
||||
| `web/src/auth-state.ts` | Token storage and BroadcastChannel cross-tab sync |
|
||||
| `web/src/hooks/` | React Query hooks for server state |
|
||||
| `web/src/contexts/` | React context for client/UI state |
|
||||
| `web/src/components/` | Radix/Tailwind UI components and feature components |
|
||||
| `web/src/themes/` | CSS themes using OKLch color tokens |
|
||||
|
||||
## Change Routing
|
||||
|
||||
| Change | Update | Verify |
|
||||
| --- | --- | --- |
|
||||
| Go service or router behavior | Service code under `server/`, tests near package | `go test -v -race ./server/...` |
|
||||
| Store or migration behavior | `store/`, all three DB driver migrations, `LATEST.sql` | `go test -v ./store/...` |
|
||||
| Internal package logic | Relevant `internal/` package tests | `go test -v -race ./internal/...` |
|
||||
| Frontend behavior | Components/hooks/contexts under `web/src/` | `cd web && pnpm lint && pnpm test` |
|
||||
| Frontend production output | Vite config or release-sensitive UI | `cd web && pnpm build` or `pnpm release` |
|
||||
| Proto API | `.proto` source plus generated outputs | `cd proto && buf generate && buf lint` |
|
||||
| Public unauthenticated route | `server/router/api/v1/acl_config.go` | Targeted server test or manual route check |
|
||||
|
||||
## Go Conventions
|
||||
|
||||
- Wrap errors with `errors.Wrap(err, "context")` from `github.com/pkg/errors`; do not use `fmt.Errorf`.
|
||||
- Return service errors with `status.Errorf(codes.X, "message")`.
|
||||
- Keep imports grouped as stdlib, third-party, then `github.com/usememos/memos`; goimports is run by golangci-lint.
|
||||
- Add doc comments for exported identifiers; godot enforces exported comment punctuation.
|
||||
- Avoid package-level mutable state unless the surrounding package already uses that pattern.
|
||||
|
||||
## Frontend Conventions
|
||||
|
||||
- Use `@/` for absolute imports.
|
||||
- Follow Biome formatting: 2-space indent, double quotes, semicolons, 140-character line width.
|
||||
- Put server data in React Query hooks under `web/src/hooks/`; keep UI-only state in contexts or component state.
|
||||
- Use Tailwind CSS v4 utilities, `cn()` for class merging, and CVA for variants.
|
||||
- Reuse Radix primitives and existing components before adding new UI primitives.
|
||||
- Keep generated proto TypeScript under `web/src/types/proto/` out of manual edits and Biome rewrites.
|
||||
|
||||
## Database And Proto Rules
|
||||
|
||||
- Schema changes require SQLite, MySQL, and PostgreSQL migrations plus `LATEST.sql` updates.
|
||||
- Fresh-install SQL and incremental migrations must stay equivalent.
|
||||
- Proto field changes must preserve compatibility unless the task explicitly allows a breaking API change.
|
||||
- Regenerate after proto edits and include both Go/OpenAPI and TypeScript generated outputs.
|
||||
|
||||
## Verification Policy
|
||||
|
||||
- Run the narrowest relevant checks while iterating.
|
||||
- Before finishing, run the checks that match the changed surface from "Change Routing".
|
||||
- For docs-only changes, `git diff --check` is sufficient unless the docs include runnable examples that should be tested.
|
||||
- If a required check cannot run locally, report the reason and the exact command that remains.
|
||||
|
||||
## CI Reference
|
||||
|
||||
- Backend CI: Go 1.26.2, `go mod tidy -go=1.26.2`, golangci-lint v2.11.3, test groups `store`, `server`, `internal`, `other`.
|
||||
- Frontend CI: Node 24, pnpm 11.0.1, `pnpm lint`, `pnpm test`, `pnpm build`.
|
||||
- Proto CI: `buf lint` and `buf format` check.
|
||||
- Docker: `scripts/Dockerfile`, Alpine 3.21 runtime, non-root user, port 5230, multi-arch amd64/arm64/arm/v7.
|
||||
|
||||
Loading…
Reference in New Issue