{"owner":"usememos","repo":"memos","hasSkills":true,"totalSkillsCount":1,"totalTokensCount":2638,"categories":["root-instruction"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nRepository instructions for AI coding agents. Keep this file short, concrete, and tied to commands that actually work in this\nrepo. If a fact here conflicts with source files or CI config, trust the source file and update this guide.\n\n## Project Snapshot\n\nMemos is a self-hosted note-taking app.\n\n- Backend: Go 1.27.2, net/http, Connect RPC, gRPC-Gateway, Protocol Buffers.\n- Frontend: React 19, TypeScript 7, Vite 8, Tailwind CSS v4, React Query v5.\n- Storage: SQLite, MySQL, PostgreSQL.\n- Generated API outputs: `proto/gen/` for Go/OpenAPI, `web/src/types/proto/` for TypeScript.\n\n## Working Rules\n\n- Read relevant code before editing; prefer local patterns over new abstractions.\n- Keep diffs scoped. Do not do repo-wide cleanup, dependency churn, or generated-file rewrites unless the task requires it.\n- Do not hand-edit generated proto outputs. Change `.proto` files, then run `buf generate`.\n- Add migrations for all database drivers when schema changes, and update each driver's `LATEST.sql`.\n- Add public API endpoints to `server/api/acl_config.go`.\n- Ask before adding heavy dependencies, changing auth/token behavior, or altering Docker/release workflows.\n\n## Documentation\n\n- ADRs and their companion glossary have been retired. Do not recreate them unless explicitly requested.\n- Design documents in `docs/design/` stay editable until the feature ships in a tagged release; keep a merged-but-unreleased design in step\n  with its implementation. After release the body is frozen: record later design changes in a dated `## Amendments` section at the end, never by\n  rewriting the body. See `docs/design/README.md`. Verify current behavior in source code and tests, not in design documents.\n- Brand copy (tagline, descriptions, README intro) comes verbatim from [`BRAND.md`](https://github.com/usememos/.github/blob/main/BRAND.md) in `usememos/.github`. Change it there first; do not keep brand guidelines in this repo.\n- Keep contributor guidance in this file and package-local `README.md` or `doc.go` files current when relevant code changes.\n\n## Commands\n\nRun from the repository root unless a command starts with `cd`.\n\n```bash\n# Backend\ngo run -buildvcs=true ./cmd/memos --port 8081 # Start backend with commit-derived CalVer\ngo test ./...                      # Run all Go tests\ngo test -v ./store/...             # Store tests, including DB drivers via TestContainers\ngo test -v -race ./server/...      # Server tests with race detector\ngo test -v -race ./internal/...    # Internal package tests with race detector\ngo test -v -run TestFoo ./core/... # Run matching Go tests in one tree\ngo mod tidy -go=1.27.2             # Match CI tidy check\ngo fix ./...                      # Apply Go modernization fixes\ngo fix -diff ./...                 # Match CI modernization check\ngolangci-lint run                  # Go lint, config: .golangci.yaml (includes depguard layering rules)\ngolangci-lint run --fix            # Auto-fix lint, including goimports\n\n# Frontend\ncd web && pnpm install             # Install dependencies\ncd web && pnpm dev                 # Dev server on :3001, proxying API to :8081\ncd web && pnpm lint                # Type check + Biome lint\ncd web && pnpm test                # Vitest unit tests\ncd web && pnpm build               # Production build\ncd web && pnpm release             # Build SPA into server/frontend/dist\n\n# Protocol Buffers\ncd proto && buf generate           # Regenerate Go + TypeScript + OpenAPI\ncd proto && buf lint               # Lint proto files\ncd proto && buf format -w          # Format proto files\n```\n\n## Repository Layout\n\nEvery root folder is named for what it holds. Read the folder's `doc.go` or `README.md` before adding to it.\n\n| Path | Holds | May import |\n| --- | --- | --- |\n| `cmd/memos/` | Cobra/Viper CLI setup and server startup | anything |\n| `server/` | The HTTP process: net/http bootstrap, graceful shutdown, every transport | core, store, provider, markdown, filter, internal |\n| `server/api/` | Connect/gRPC-Gateway services, ACL config, SSE hub. Thin handlers; rules go to `core/` | |\n| `server/fileserver/` | Native HTTP file serving, thumbnails, range requests | |\n| `server/frontend/` | Static SPA serving; `dist/` is the built SPA baked in by `go:embed` | |\n| `server/mcp/` | Model Context Protocol server | |\n| `server/auth/` | JWT access tokens, refresh tokens, PAT handling | |\n| `core/` | Business rules with no HTTP and no SQL: `access`, `notification`, `memopayload`, `memoexport`, `usagelimit` | store, provider, markdown, filter, internal |\n| `store/` | Store facade, cache, migrations, `Driver` interface; `store/db/{sqlite,mysql,postgres}/` implement it | provider, markdown, filter, internal |\n| `markdown/` | Markdown engine: parser, AST, memos syntax extensions, renderer, memo payload | proto/gen, internal |\n| `filter/` | CEL filter compiler: parse to IR, render to SQL per driver, filterable field schema | internal |\n| `provider/` | Backends configured by instance settings: `ai`, `idp`, `storage` | proto/gen, internal |\n| `internal/` | Private plumbing with no memos vocabulary (`identifier`, `email`, `webhook`, `ratelimit`, …) | third party only |\n| `proto/api/`, `proto/store/` | Public API and internal storage proto sources; `proto/gen/` is generated | |\n| `web/src/` | React SPA: `connect.ts` clients, `auth-state.ts`, `hooks/`, `contexts/`, `components/`, `themes/` | |\n\nLayering rules, enforced by `depguard` in `.golangci.yaml`:\n\n- Imports point downward only: `cmd` → `server` → `core` → `store` → {`provider`, `markdown`, `filter`} → `internal`.\n- `internal/` packages import nothing from this module (except `internal/testutil`, which may import `proto/gen`).\n- A package goes in `internal/` only if it could be published as a standalone module unchanged. If it knows what a Memo, Space, or instance setting is, it is a root package.\n- Never create `util`, `common`, `base`, `helpers`, `misc`, or `pkg` packages. Name a package for the one thing it does, or put the code next to its only caller.\n- New business rules extracted from `server/api` go to `core/<resource>/`, one package per resource.\n\nFile convention inside `server/api/`: `<resource>_service.go` holds the RPC handlers, `<resource>_service_converters.go` the\nstore↔proto conversion, and `<resource>_service_<topic>.go` further splits. Extend the matching file; do not add `*_helpers2.go`.\nBlack-box service tests live in `server/api/test/`, unit tests next to the code.\n\n## Change Routing\n\n| Change | Update | Verify |\n| --- | --- | --- |\n| Go service or router behavior | Handlers under `server/`, rules under `core/`, tests near package | `go test -v -race ./server/... ./core/...` |\n| Store or migration behavior | `store/`, all three DB driver migrations, `LATEST.sql` | `go test -v ./store/...` |\n| Markdown, filter, or provider logic | `markdown/`, `filter/`, `provider/` | `go test -v -race ./markdown/... ./filter/... ./provider/...` |\n| Internal package logic | Relevant `internal/` package tests | `go test -v -race ./internal/...` |\n| Frontend behavior | Components/hooks/contexts under `web/src/` | `cd web && pnpm lint && pnpm test` |\n| Frontend production output | Vite config or release-sensitive UI | `cd web && pnpm build` or `pnpm release` |\n| Proto API | `.proto` source, generated outputs, `proto/api/CHANGELOG.md` for breaks | `cd proto && buf generate && buf lint` |\n| Public unauthenticated route | `server/api/acl_config.go` | Targeted server test or manual route check |\n\n## Go Conventions\n\n- Wrap errors with `errors.Wrap(err, \"context\")` from `github.com/pkg/errors`; do not use `fmt.Errorf`.\n- Return service errors with `status.Errorf(codes.X, \"message\")`.\n- Keep imports grouped as stdlib, third-party, then `github.com/usememos/memos`; goimports is run by golangci-lint.\n- Add doc comments for exported identifiers; godot enforces exported comment punctuation.\n- Avoid package-level mutable state unless the surrounding package already uses that pattern.\n\n## Frontend Conventions\n\n- Use `@/` for absolute imports.\n- Follow Biome formatting: 2-space indent, double quotes, semicolons, 140-character line width.\n- Put server data in React Query hooks under `web/src/hooks/`; keep UI-only state in contexts or component state.\n- Show, edit and compose memos through `web/src/components/MemoEditor` (a name or draft seed plus a mode); see its `README.md`.\n- Use Tailwind CSS v4 utilities, `cn()` for class merging, and CVA for variants.\n- Reuse Base UI primitives and existing components before adding new UI primitives.\n- Keep generated proto TypeScript under `web/src/types/proto/` out of manual edits and Biome rewrites.\n\n## Database And Proto Rules\n\n- Schema changes require SQLite, MySQL, and PostgreSQL migrations plus `LATEST.sql` updates.\n- Fresh-install SQL and incremental migrations must stay equivalent.\n- Proto field changes must preserve compatibility unless the task explicitly allows a breaking API change. Record every\n  allowed break in `proto/api/CHANGELOG.md`; compatibility is checked during review.\n- Regenerate after proto edits and include both Go/OpenAPI and TypeScript generated outputs.\n\n## Verification Policy\n\n- Run the narrowest relevant checks while iterating.\n- Before finishing, run the checks that match the changed surface from \"Change Routing\".\n- For docs-only changes, `git diff --check` is sufficient unless the docs include runnable examples that should be tested.\n- If a required check cannot run locally, report the reason and the exact command that remains.\n\n## CI Reference\n\n- Releases are cut by pushing a `YY.MM.N[-rc.K]` tag. To cut, promote, or check a release, follow\n  `.agents/skills/release/SKILL.md`.\n- Development builds use the HEAD committer date in UTC as `YY.MM.D-dev.<sha7>`; release builds inject the CalVer tag.\n- `go build` embeds Git metadata automatically; `go run` needs `-buildvcs=true`. Builds without Git metadata must inject\n  `github.com/usememos/memos/internal/version.Version` through `-ldflags`.\n- Docker excludes `.git`; pass `--build-arg VERSION=\"$(bash scripts/release_version.sh development-version)\"` and\n  `--build-arg COMMIT=\"$(git rev-parse HEAD)\"` when building locally (build frontend assets first).\n\n- Backend CI: Go 1.27.2, `go mod tidy -go=1.27.2`, `go fix -diff ./...`, golangci-lint v2.14.0 (including goimports), test groups\n  `store`, `server`, `internal`, `other` (`cmd`, `core`, `markdown`, `filter`, `provider`, `proto`).\n- Frontend CI: Node 24, pnpm 11.0.1, `pnpm lint`, `pnpm test`, `pnpm build`.\n- Proto CI: `buf lint` and `buf format` check.\n- Docker: `scripts/Dockerfile`, Alpine 3.21 runtime, non-root user, port 5230, multi-arch amd64/arm64/arm/v7.\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nRepository instructions for AI coding agents. Keep this file short, concrete, and tied to commands that actually work in this\nrepo. If a fact here conflicts with source files or CI config, trust the source file and update this guide.\n\n## Project Snapshot\n\nMemos is a self-hosted note-taking app.\n\n- Backend: Go 1.27.2, net/http, Connect RPC, gRPC-Gateway, Protocol Buffers.\n- Frontend: React 19, TypeScript 7, Vite 8, Tailwind CSS v4, React Query v5.\n- Storage: SQLite, MySQL, PostgreSQL.\n- Generated API outputs: `proto/gen/` for Go/OpenAPI, `web/src/types/proto/` for TypeScript.\n\n## Working Rules\n\n- Read relevant code before editing; prefer local patterns over new abstractions.\n- Keep diffs scoped. Do not do repo-wide cleanup, dependency churn, or generated-file rewrites unless the task requires it.\n- Do not hand-edit generated proto outputs. Change `.proto` files, then run `buf generate`.\n- Add migrations for all database drivers when schema changes, and update each driver's `LATEST.sql`.\n- Add public API endpoints to `server/api/acl_config.go`.\n- Ask before adding heavy dependencies, changing auth/token behavior, or altering Docker/release workflows.\n\n## Documentation\n\n- ADRs and their companion glossary have been retired. Do not recreate them unless explicitly requested.\n- Design documents in `docs/design/` stay editable until the feature ships in a tagged release; keep a merged-but-unreleased design in step\n  with its implementation. After release the body is frozen: record later design changes in a dated `## Amendments` section at the end, never by\n  rewriting the body. See `docs/design/README.md`. Verify current behavior in source code and tests, not in design documents.\n- Brand copy (tagline, descriptions, README intro) comes verbatim from [`BRAND.md`](https://github.com/usememos/.github/blob/main/BRAND.md) in `usememos/.github`. Change it there first; do not keep brand guidelines in this repo.\n- Keep contributor guidance in this file and package-local `README.md` or `doc.go` files current when relevant code changes.\n\n## Commands\n\nRun from the repository root unless a command starts with `cd`.\n\n```bash\n# Backend\ngo run -buildvcs=true ./cmd/memos --port 8081 # Start backend with commit-derived CalVer\ngo test ./...                      # Run all Go tests\ngo test -v ./store/...             # Store tests, including DB drivers via TestContainers\ngo test -v -race ./server/...      # Server tests with race detector\ngo test -v -race ./internal/...    # Internal package tests with race detector\ngo test -v -run TestFoo ./core/... # Run matching Go tests in one tree\ngo mod tidy -go=1.27.2             # Match CI tidy check\ngo fix ./...                      # Apply Go modernization fixes\ngo fix -diff ./...                 # Match CI modernization check\ngolangci-lint run                  # Go lint, config: .golangci.yaml (includes depguard layering rules)\ngolangci-lint run --fix            # Auto-fix lint, including goimports\n\n# Frontend\ncd web && pnpm install             # Install dependencies\ncd web && pnpm dev                 # Dev server on :3001, proxying API to :8081\ncd web && pnpm lint                # Type check + Biome lint\ncd web && pnpm test                # Vitest unit tests\ncd web && pnpm build               # Production build\ncd web && pnpm release             # Build SPA into server/frontend/dist\n\n# Protocol Buffers\ncd proto && buf generate           # Regenerate Go + TypeScript + OpenAPI\ncd proto && buf lint               # Lint proto files\ncd proto && buf format -w          # Format proto files\n```\n\n## Repository Layout\n\nEvery root folder is named for what it holds. Read the folder's `doc.go` or `README.md` before adding to it.\n\n| Path | Holds | May import |\n| --- | --- | --- |\n| `cmd/memos/` | Cobra/Viper CLI setup and server startup | anything |\n| `server/` | The HTTP process: net/http bootstrap, graceful shutdown, every transport | core, store, provider, markdown, filter, internal |\n| `server/api/` | Connect/gRPC-Gateway services, ACL config, SSE hub. Thin handlers; rules go to `core/` | |\n| `server/fileserver/` | Native HTTP file serving, thumbnails, range requests | |\n| `server/frontend/` | Static SPA serving; `dist/` is the built SPA baked in by `go:embed` | |\n| `server/mcp/` | Model Context Protocol server | |\n| `server/auth/` | JWT access tokens, refresh tokens, PAT handling | |\n| `core/` | Business rules with no HTTP and no SQL: `access`, `notification`, `memopayload`, `memoexport`, `usagelimit` | store, provider, markdown, filter, internal |\n| `store/` | Store facade, cache, migrations, `Driver` interface; `store/db/{sqlite,mysql,postgres}/` implement it | provider, markdown, filter, internal |\n| `markdown/` | Markdown engine: parser, AST, memos syntax extensions, renderer, memo payload | proto/gen, internal |\n| `filter/` | CEL filter compiler: parse to IR, render to SQL per driver, filterable field schema | internal |\n| `provider/` | Backends configured by instance settings: `ai`, `idp`, `storage` | proto/gen, internal |\n| `internal/` | Private plumbing with no memos vocabulary (`identifier`, `email`, `webhook`, `ratelimit`, …) | third party only |\n| `proto/api/`, `proto/store/` | Public API and internal storage proto sources; `proto/gen/` is generated | |\n| `web/src/` | React SPA: `connect.ts` clients, `auth-state.ts`, `hooks/`, `contexts/`, `components/`, `themes/` | |\n\nLayering rules, enforced by `depguard` in `.golangci.yaml`:\n\n- Imports point downward only: `cmd` → `server` → `core` → `store` → {`provider`, `markdown`, `filter`} → `internal`.\n- `internal/` packages import nothing from this module (except `internal/testutil`, which may import `proto/gen`).\n- A package goes in `internal/` only if it could be published as a standalone module unchanged. If it knows what a Memo, Space, or instance setting is, it is a root package.\n- Never create `util`, `common`, `base`, `helpers`, `misc`, or `pkg` packages. Name a package for the one thing it does, or put the code next to its only caller.\n- New business rules extracted from `server/api` go to `core/<resource>/`, one package per resource.\n\nFile convention inside `server/api/`: `<resource>_service.go` holds the RPC handlers, `<resource>_service_converters.go` the\nstore↔proto conversion, and `<resource>_service_<topic>.go` further splits. Extend the matching file; do not add `*_helpers2.go`.\nBlack-box service tests live in `server/api/test/`, unit tests next to the code.\n\n## Change Routing\n\n| Change | Update | Verify |\n| --- | --- | --- |\n| Go service or router behavior | Handlers under `server/`, rules under `core/`, tests near package | `go test -v -race ./server/... ./core/...` |\n| Store or migration behavior | `store/`, all three DB driver migrations, `LATEST.sql` | `go test -v ./store/...` |\n| Markdown, filter, or provider logic | `markdown/`, `filter/`, `provider/` | `go test -v -race ./markdown/... ./filter/... ./provider/...` |\n| Internal package logic | Relevant `internal/` package tests | `go test -v -race ./internal/...` |\n| Frontend behavior | Components/hooks/contexts under `web/src/` | `cd web && pnpm lint && pnpm test` |\n| Frontend production output | Vite config or release-sensitive UI | `cd web && pnpm build` or `pnpm release` |\n| Proto API | `.proto` source, generated outputs, `proto/api/CHANGELOG.md` for breaks | `cd proto && buf generate && buf lint` |\n| Public unauthenticated route | `server/api/acl_config.go` | Targeted server test or manual route check |\n\n## Go Conventions\n\n- Wrap errors with `errors.Wrap(err, \"context\")` from `github.com/pkg/errors`; do not use `fmt.Errorf`.\n- Return service errors with `status.Errorf(codes.X, \"message\")`.\n- Keep imports grouped as stdlib, third-party, then `github.com/usememos/memos`; goimports is run by golangci-lint.\n- Add doc comments for exported identifiers; godot enforces exported comment punctuation.\n- Avoid package-level mutable state unless the surrounding package already uses that pattern.\n\n## Frontend Conventions\n\n- Use `@/` for absolute imports.\n- Follow Biome formatting: 2-space indent, double quotes, semicolons, 140-character line width.\n- Put server data in React Query hooks under `web/src/hooks/`; keep UI-only state in contexts or component state.\n- Show, edit and compose memos through `web/src/components/MemoEditor` (a name or draft seed plus a mode); see its `README.md`.\n- Use Tailwind CSS v4 utilities, `cn()` for class merging, and CVA for variants.\n- Reuse Base UI primitives and existing components before adding new UI primitives.\n- Keep generated proto TypeScript under `web/src/types/proto/` out of manual edits and Biome rewrites.\n\n## Database And Proto Rules\n\n- Schema changes require SQLite, MySQL, and PostgreSQL migrations plus `LATEST.sql` updates.\n- Fresh-install SQL and incremental migrations must stay equivalent.\n- Proto field changes must preserve compatibility unless the task explicitly allows a breaking API change. Record every\n  allowed break in `proto/api/CHANGELOG.md`; compatibility is checked during review.\n- Regenerate after proto edits and include both Go/OpenAPI and TypeScript generated outputs.\n\n## Verification Policy\n\n- Run the narrowest relevant checks while iterating.\n- Before finishing, run the checks that match the changed surface from \"Change Routing\".\n- For docs-only changes, `git diff --check` is sufficient unless the docs include runnable examples that should be tested.\n- If a required check cannot run locally, report the reason and the exact command that remains.\n\n## CI Reference\n\n- Releases are cut by pushing a `YY.MM.N[-rc.K]` tag. To cut, promote, or check a release, follow\n  `.agents/skills/release/SKILL.md`.\n- Development builds use the HEAD committer date in UTC as `YY.MM.D-dev.<sha7>`; release builds inject the CalVer tag.\n- `go build` embeds Git metadata automatically; `go run` needs `-buildvcs=true`. Builds without Git metadata must inject\n  `github.com/usememos/memos/internal/version.Version` through `-ldflags`.\n- Docker excludes `.git`; pass `--build-arg VERSION=\"$(bash scripts/release_version.sh development-version)\"` and\n  `--build-arg COMMIT=\"$(git rev-parse HEAD)\"` when building locally (build frontend assets first).\n\n- Backend CI: Go 1.27.2, `go mod tidy -go=1.27.2`, `go fix -diff ./...`, golangci-lint v2.14.0 (including goimports), test groups\n  `store`, `server`, `internal`, `other` (`cmd`, `core`, `markdown`, `filter`, `provider`, `proto`).\n- Frontend CI: Node 24, pnpm 11.0.1, `pnpm lint`, `pnpm test`, `pnpm build`.\n- Proto CI: `buf lint` and `buf format` check.\n- Docker: `scripts/Dockerfile`, Alpine 3.21 runtime, non-root user, port 5230, multi-arch amd64/arm64/arm/v7.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/usememos/memos/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\nRepository instructions for AI coding agents. Keep this file short, concrete, and tied to commands that actually work in this\nrepo. If a fact here conflicts with source files or CI config, trust the source file and update this guide.\n\n## Project Snapshot\n\nMemos is a self-hosted note-taking app.\n\n- Backend: Go 1.27.2, net/http, Connect RPC, gRPC-Gateway, Protocol Buffers.\n- Frontend: React 19, TypeScript 7, Vite 8, Tailwind CSS v4, React Query v5.\n- Storage: SQLite, MySQL, PostgreSQL.\n- Generated API outputs: `proto/gen/` for Go/OpenAPI, `web/src/types/proto/` for TypeScript.\n\n## Working Rules\n\n- Read relevant code before editing; prefer local patterns over new abstractions.\n- Keep diffs scoped. Do not do repo-wide cleanup, dependency churn, or generated-file rewrites unless the task requires it.\n- Do not hand-edit generated proto outputs. Change `.proto` files, then run `buf generate`.\n- Add migrations for all database drivers when schema changes, and update each driver's `LATEST.sql`.\n- Add public API endpoints to `server/api/acl_config.go`.\n- Ask before adding heavy dependencies, changing auth/token behavior, or altering Docker/release workflows.\n\n## Documentation\n\n- ADRs and their companion glossary have been retired. Do not recreate them unless explicitly requested.\n- Design documents in `docs/design/` stay editable until the feature ships in a tagged release; keep a merged-but-unreleased design in step\n  with its implementation. After release the body is frozen: record later design changes in a dated `## Amendments` section at the end, never by\n  rewriting the body. See `docs/design/README.md`. Verify current behavior in source code and tests, not in design documents.\n- Brand copy (tagline, descriptions, README intro) comes verbatim from [`BRAND.md`](https://github.com/usememos/.github/blob/main/BRAND.md) in `usememos/.github`. Change it there first; do not keep brand guidelines in this repo.\n- Keep contributor guidance in this file and package-local `README.md` or `doc.go` files current when relevant code changes.\n\n## Commands\n\nRun from the repository root unless a command starts with `cd`.\n\n```bash\n# Backend\ngo run -buildvcs=true ./cmd/memos --port 8081 # Start backend with commit-derived CalVer\ngo test ./...                      # Run all Go tests\ngo test -v ./store/...             # Store tests, including DB drivers via TestContainers\ngo test -v -race ./server/...      # Server tests with race detector\ngo test -v -race ./internal/...    # Internal package tests with race detector\ngo test -v -run TestFoo ./core/... # Run matching Go tests in one tree\ngo mod tidy -go=1.27.2             # Match CI tidy check\ngo fix ./...                      # Apply Go modernization fixes\ngo fix -diff ./...                 # Match CI modernization check\ngolangci-lint run                  # Go lint, config: .golangci.yaml (includes depguard layering rules)\ngolangci-lint run --fix            # Auto-fix lint, including goimports\n\n# Frontend\ncd web && pnpm install             # Install dependencies\ncd web && pnpm dev                 # Dev server on :3001, proxying API to :8081\ncd web && pnpm lint                # Type check + Biome lint\ncd web && pnpm test                # Vitest unit tests\ncd web && pnpm build               # Production build\ncd web && pnpm release             # Build SPA into server/frontend/dist\n\n# Protocol Buffers\ncd proto && buf generate           # Regenerate Go + TypeScript + OpenAPI\ncd proto && buf lint               # Lint proto files\ncd proto && buf format -w          # Format proto files\n```\n\n## Repository Layout\n\nEvery root folder is named for what it holds. Read the folder's `doc.go` or `README.md` before adding to it.\n\n| Path | Holds | May import |\n| --- | --- | --- |\n| `cmd/memos/` | Cobra/Viper CLI setup and server startup | anything |\n| `server/` | The HTTP process: net/http bootstrap, graceful shutdown, every transport | core, store, provider, markdown, filter, internal |\n| `server/api/` | Connect/gRPC-Gateway services, ACL config, SSE hub. Thin handlers; rules go to `core/` | |\n| `server/fileserver/` | Native HTTP file serving, thumbnails, range requests | |\n| `server/frontend/` | Static SPA serving; `dist/` is the built SPA baked in by `go:embed` | |\n| `server/mcp/` | Model Context Protocol server | |\n| `server/auth/` | JWT access tokens, refresh tokens, PAT handling | |\n| `core/` | Business rules with no HTTP and no SQL: `access`, `notification`, `memopayload`, `memoexport`, `usagelimit` | store, provider, markdown, filter, internal |\n| `store/` | Store facade, cache, migrations, `Driver` interface; `store/db/{sqlite,mysql,postgres}/` implement it | provider, markdown, filter, internal |\n| `markdown/` | Markdown engine: parser, AST, memos syntax extensions, renderer, memo payload | proto/gen, internal |\n| `filter/` | CEL filter compiler: parse to IR, render to SQL per driver, filterable field schema | internal |\n| `provider/` | Backends configured by instance settings: `ai`, `idp`, `storage` | proto/gen, internal |\n| `internal/` | Private plumbing with no memos vocabulary (`identifier`, `email`, `webhook`, `ratelimit`, …) | third party only |\n| `proto/api/`, `proto/store/` | Public API and internal storage proto sources; `proto/gen/` is generated | |\n| `web/src/` | React SPA: `connect.ts` clients, `auth-state.ts`, `hooks/`, `contexts/`, `components/`, `themes/` | |\n\nLayering rules, enforced by `depguard` in `.golangci.yaml`:\n\n- Imports point downward only: `cmd` → `server` → `core` → `store` → {`provider`, `markdown`, `filter`} → `internal`.\n- `internal/` packages import nothing from this module (except `internal/testutil`, which may import `proto/gen`).\n- A package goes in `internal/` only if it could be published as a standalone module unchanged. If it knows what a Memo, Space, or instance setting is, it is a root package.\n- Never create `util`, `common`, `base`, `helpers`, `misc`, or `pkg` packages. Name a package for the one thing it does, or put the code next to its only caller.\n- New business rules extracted from `server/api` go to `core/<resource>/`, one package per resource.\n\nFile convention inside `server/api/`: `<resource>_service.go` holds the RPC handlers, `<resource>_service_converters.go` the\nstore↔proto conversion, and `<resource>_service_<topic>.go` further splits. Extend the matching file; do not add `*_helpers2.go`.\nBlack-box service tests live in `server/api/test/`, unit tests next to the code.\n\n## Change Routing\n\n| Change | Update | Verify |\n| --- | --- | --- |\n| Go service or router behavior | Handlers under `server/`, rules under `core/`, tests near package | `go test -v -race ./server/... ./core/...` |\n| Store or migration behavior | `store/`, all three DB driver migrations, `LATEST.sql` | `go test -v ./store/...` |\n| Markdown, filter, or provider logic | `markdown/`, `filter/`, `provider/` | `go test -v -race ./markdown/... ./filter/... ./provider/...` |\n| Internal package logic | Relevant `internal/` package tests | `go test -v -race ./internal/...` |\n| Frontend behavior | Components/hooks/contexts under `web/src/` | `cd web && pnpm lint && pnpm test` |\n| Frontend production output | Vite config or release-sensitive UI | `cd web && pnpm build` or `pnpm release` |\n| Proto API | `.proto` source, generated outputs, `proto/api/CHANGELOG.md` for breaks | `cd proto && buf generate && buf lint` |\n| Public unauthenticated route | `server/api/acl_config.go` | Targeted server test or manual route check |\n\n## Go Conventions\n\n- Wrap errors with `errors.Wrap(err, \"context\")` from `github.com/pkg/errors`; do not use `fmt.Errorf`.\n- Return service errors with `status.Errorf(codes.X, \"message\")`.\n- Keep imports grouped as stdlib, third-party, then `github.com/usememos/memos`; goimports is run by golangci-lint.\n- Add doc comments for exported identifiers; godot enforces exported comment punctuation.\n- Avoid package-level mutable state unless the surrounding package already uses that pattern.\n\n## Frontend Conventions\n\n- Use `@/` for absolute imports.\n- Follow Biome formatting: 2-space indent, double quotes, semicolons, 140-character line width.\n- Put server data in React Query hooks under `web/src/hooks/`; keep UI-only state in contexts or component state.\n- Show, edit and compose memos through `web/src/components/MemoEditor` (a name or draft seed plus a mode); see its `README.md`.\n- Use Tailwind CSS v4 utilities, `cn()` for class merging, and CVA for variants.\n- Reuse Base UI primitives and existing components before adding new UI primitives.\n- Keep generated proto TypeScript under `web/src/types/proto/` out of manual edits and Biome rewrites.\n\n## Database And Proto Rules\n\n- Schema changes require SQLite, MySQL, and PostgreSQL migrations plus `LATEST.sql` updates.\n- Fresh-install SQL and incremental migrations must stay equivalent.\n- Proto field changes must preserve compatibility unless the task explicitly allows a breaking API change. Record every\n  allowed break in `proto/api/CHANGELOG.md`; compatibility is checked during review.\n- Regenerate after proto edits and include both Go/OpenAPI and TypeScript generated outputs.\n\n## Verification Policy\n\n- Run the narrowest relevant checks while iterating.\n- Before finishing, run the checks that match the changed surface from \"Change Routing\".\n- For docs-only changes, `git diff --check` is sufficient unless the docs include runnable examples that should be tested.\n- If a required check cannot run locally, report the reason and the exact command that remains.\n\n## CI Reference\n\n- Releases are cut by pushing a `YY.MM.N[-rc.K]` tag. To cut, promote, or check a release, follow\n  `.agents/skills/release/SKILL.md`.\n- Development builds use the HEAD committer date in UTC as `YY.MM.D-dev.<sha7>`; release builds inject the CalVer tag.\n- `go build` embeds Git metadata automatically; `go run` needs `-buildvcs=true`. Builds without Git metadata must inject\n  `github.com/usememos/memos/internal/version.Version` through `-ldflags`.\n- Docker excludes `.git`; pass `--build-arg VERSION=\"$(bash scripts/release_version.sh development-version)\"` and\n  `--build-arg COMMIT=\"$(git rev-parse HEAD)\"` when building locally (build frontend assets first).\n\n- Backend CI: Go 1.27.2, `go mod tidy -go=1.27.2`, `go fix -diff ./...`, golangci-lint v2.14.0 (including goimports), test groups\n  `store`, `server`, `internal`, `other` (`cmd`, `core`, `markdown`, `filter`, `provider`, `proto`).\n- Frontend CI: Node 24, pnpm 11.0.1, `pnpm lint`, `pnpm test`, `pnpm build`.\n- Proto CI: `buf lint` and `buf format` check.\n- Docker: `scripts/Dockerfile`, Alpine 3.21 runtime, non-root user, port 5230, multi-arch amd64/arm64/arm/v7.\n","isInternal":false,"tokens":2638,"sizeBytes":10690}],"systemPromptSnippet":"<yakaai_skills repo=\"usememos/memos\">\n<!-- File: AGENTS.md (Tokens: ~2638 | Category: root-instruction) -->\n# AGENTS.md\n\nRepository instructions for AI coding agents. Keep this file short, concrete, and tied to commands that actually work in this\nrepo. If a fact here conflicts with source files or CI config, trust the source file and update this guide.\n\n## Project Snapshot\n\nMemos is a self-hosted note-taking app.\n\n- Backend: Go 1.27.2, net/http, Connect RPC, gRPC-Gateway, Protocol Buffers.\n- Frontend: React 19, TypeScript 7, Vite 8, Tailwind CSS v4, React Query v5.\n- Storage: SQLite, MySQL, PostgreSQL.\n- Generated API outputs: `proto/gen/` for Go/OpenAPI, `web/src/types/proto/` for TypeScript.\n\n## Working Rules\n\n- Read relevant code before editing; prefer local patterns over new abstractions.\n- Keep diffs scoped. Do not do repo-wide cleanup, dependency churn, or generated-file rewrites unless the task requires it.\n- Do not hand-edit generated proto outputs. Change `.proto` files, then run `buf generate`.\n- Add migrations for all database drivers when schema changes, and update each driver's `LATEST.sql`.\n- Add public API endpoints to `server/api/acl_config.go`.\n- Ask before adding heavy dependencies, changing auth/token behavior, or altering Docker/release workflows.\n\n## Documentation\n\n- ADRs and their companion glossary have been retired. Do not recreate them unless explicitly requested.\n- Design documents in `docs/design/` stay editable until the feature ships in a tagged release; keep a merged-but-unreleased design in step\n  with its implementation. After release the body is frozen: record later design changes in a dated `## Amendments` section at the end, never by\n  rewriting the body. See `docs/design/README.md`. Verify current behavior in source code and tests, not in design documents.\n- Brand copy (tagline, descriptions, README intro) comes verbatim from [`BRAND.md`](https://github.com/usememos/.github/blob/main/BRAND.md) in `usememos/.github`. Change it there first; do not keep brand guidelines in this repo.\n- Keep contributor guidance in this file and package-local `README.md` or `doc.go` files current when relevant code changes.\n\n## Commands\n\nRun from the repository root unless a command starts with `cd`.\n\n```bash\n# Backend\ngo run -buildvcs=true ./cmd/memos --port 8081 # Start backend with commit-derived CalVer\ngo test ./...                      # Run all Go tests\ngo test -v ./store/...             # Store tests, including DB drivers via TestContainers\ngo test -v -race ./server/...      # Server tests with race detector\ngo test -v -race ./internal/...    # Internal package tests with race detector\ngo test -v -run TestFoo ./core/... # Run matching Go tests in one tree\ngo mod tidy -go=1.27.2             # Match CI tidy check\ngo fix ./...                      # Apply Go modernization fixes\ngo fix -diff ./...                 # Match CI modernization check\ngolangci-lint run                  # Go lint, config: .golangci.yaml (includes depguard layering rules)\ngolangci-lint run --fix            # Auto-fix lint, including goimports\n\n# Frontend\ncd web && pnpm install             # Install dependencies\ncd web && pnpm dev                 # Dev server on :3001, proxying API to :8081\ncd web && pnpm lint                # Type check + Biome lint\ncd web && pnpm test                # Vitest unit tests\ncd web && pnpm build               # Production build\ncd web && pnpm release             # Build SPA into server/frontend/dist\n\n# Protocol Buffers\ncd proto && buf generate           # Regenerate Go + TypeScript + OpenAPI\ncd proto && buf lint               # Lint proto files\ncd proto && buf format -w          # Format proto files\n```\n\n## Repository Layout\n\nEvery root folder is named for what it holds. Read the folder's `doc.go` or `README.md` before adding to it.\n\n| Path | Holds | May import |\n| --- | --- | --- |\n| `cmd/memos/` | Cobra/Viper CLI setup and server startup | anything |\n| `server/` | The HTTP process: net/http bootstrap, graceful shutdown, every transport | core, store, provider, markdown, filter, internal |\n| `server/api/` | Connect/gRPC-Gateway services, ACL config, SSE hub. Thin handlers; rules go to `core/` | |\n| `server/fileserver/` | Native HTTP file serving, thumbnails, range requests | |\n| `server/frontend/` | Static SPA serving; `dist/` is the built SPA baked in by `go:embed` | |\n| `server/mcp/` | Model Context Protocol server | |\n| `server/auth/` | JWT access tokens, refresh tokens, PAT handling | |\n| `core/` | Business rules with no HTTP and no SQL: `access`, `notification`, `memopayload`, `memoexport`, `usagelimit` | store, provider, markdown, filter, internal |\n| `store/` | Store facade, cache, migrations, `Driver` interface; `store/db/{sqlite,mysql,postgres}/` implement it | provider, markdown, filter, internal |\n| `markdown/` | Markdown engine: parser, AST, memos syntax extensions, renderer, memo payload | proto/gen, internal |\n| `filter/` | CEL filter compiler: parse to IR, render to SQL per driver, filterable field schema | internal |\n| `provider/` | Backends configured by instance settings: `ai`, `idp`, `storage` | proto/gen, internal |\n| `internal/` | Private plumbing with no memos vocabulary (`identifier`, `email`, `webhook`, `ratelimit`, …) | third party only |\n| `proto/api/`, `proto/store/` | Public API and internal storage proto sources; `proto/gen/` is generated | |\n| `web/src/` | React SPA: `connect.ts` clients, `auth-state.ts`, `hooks/`, `contexts/`, `components/`, `themes/` | |\n\nLayering rules, enforced by `depguard` in `.golangci.yaml`:\n\n- Imports point downward only: `cmd` → `server` → `core` → `store` → {`provider`, `markdown`, `filter`} → `internal`.\n- `internal/` packages import nothing from this module (except `internal/testutil`, which may import `proto/gen`).\n- A package goes in `internal/` only if it could be published as a standalone module unchanged. If it knows what a Memo, Space, or instance setting is, it is a root package.\n- Never create `util`, `common`, `base`, `helpers`, `misc`, or `pkg` packages. Name a package for the one thing it does, or put the code next to its only caller.\n- New business rules extracted from `server/api` go to `core/<resource>/`, one package per resource.\n\nFile convention inside `server/api/`: `<resource>_service.go` holds the RPC handlers, `<resource>_service_converters.go` the\nstore↔proto conversion, and `<resource>_service_<topic>.go` further splits. Extend the matching file; do not add `*_helpers2.go`.\nBlack-box service tests live in `server/api/test/`, unit tests next to the code.\n\n## Change Routing\n\n| Change | Update | Verify |\n| --- | --- | --- |\n| Go service or router behavior | Handlers under `server/`, rules under `core/`, tests near package | `go test -v -race ./server/... ./core/...` |\n| Store or migration behavior | `store/`, all three DB driver migrations, `LATEST.sql` | `go test -v ./store/...` |\n| Markdown, filter, or provider logic | `markdown/`, `filter/`, `provider/` | `go test -v -race ./markdown/... ./filter/... ./provider/...` |\n| Internal package logic | Relevant `internal/` package tests | `go test -v -race ./internal/...` |\n| Frontend behavior | Components/hooks/contexts under `web/src/` | `cd web && pnpm lint && pnpm test` |\n| Frontend production output | Vite config or release-sensitive UI | `cd web && pnpm build` or `pnpm release` |\n| Proto API | `.proto` source, generated outputs, `proto/api/CHANGELOG.md` for breaks | `cd proto && buf generate && buf lint` |\n| Public unauthenticated route | `server/api/acl_config.go` | Targeted server test or manual route check |\n\n## Go Conventions\n\n- Wrap errors with `errors.Wrap(err, \"context\")` from `github.com/pkg/errors`; do not use `fmt.Errorf`.\n- Return service errors with `status.Errorf(codes.X, \"message\")`.\n- Keep imports grouped as stdlib, third-party, then `github.com/usememos/memos`; goimports is run by golangci-lint.\n- Add doc comments for exported identifiers; godot enforces exported comment punctuation.\n- Avoid package-level mutable state unless the surrounding package already uses that pattern.\n\n## Frontend Conventions\n\n- Use `@/` for absolute imports.\n- Follow Biome formatting: 2-space indent, double quotes, semicolons, 140-character line width.\n- Put server data in React Query hooks under `web/src/hooks/`; keep UI-only state in contexts or component state.\n- Show, edit and compose memos through `web/src/components/MemoEditor` (a name or draft seed plus a mode); see its `README.md`.\n- Use Tailwind CSS v4 utilities, `cn()` for class merging, and CVA for variants.\n- Reuse Base UI primitives and existing components before adding new UI primitives.\n- Keep generated proto TypeScript under `web/src/types/proto/` out of manual edits and Biome rewrites.\n\n## Database And Proto Rules\n\n- Schema changes require SQLite, MySQL, and PostgreSQL migrations plus `LATEST.sql` updates.\n- Fresh-install SQL and incremental migrations must stay equivalent.\n- Proto field changes must preserve compatibility unless the task explicitly allows a breaking API change. Record every\n  allowed break in `proto/api/CHANGELOG.md`; compatibility is checked during review.\n- Regenerate after proto edits and include both Go/OpenAPI and TypeScript generated outputs.\n\n## Verification Policy\n\n- Run the narrowest relevant checks while iterating.\n- Before finishing, run the checks that match the changed surface from \"Change Routing\".\n- For docs-only changes, `git diff --check` is sufficient unless the docs include runnable examples that should be tested.\n- If a required check cannot run locally, report the reason and the exact command that remains.\n\n## CI Reference\n\n- Releases are cut by pushing a `YY.MM.N[-rc.K]` tag. To cut, promote, or check a release, follow\n  `.agents/skills/release/SKILL.md`.\n- Development builds use the HEAD committer date in UTC as `YY.MM.D-dev.<sha7>`; release builds inject the CalVer tag.\n- `go build` embeds Git metadata automatically; `go run` needs `-buildvcs=true`. Builds without Git metadata must inject\n  `github.com/usememos/memos/internal/version.Version` through `-ldflags`.\n- Docker excludes `.git`; pass `--build-arg VERSION=\"$(bash scripts/release_version.sh development-version)\"` and\n  `--build-arg COMMIT=\"$(git rev-parse HEAD)\"` when building locally (build frontend assets first).\n\n- Backend CI: Go 1.27.2, `go mod tidy -go=1.27.2`, `go fix -diff ./...`, golangci-lint v2.14.0 (including goimports), test groups\n  `store`, `server`, `internal`, `other` (`cmd`, `core`, `markdown`, `filter`, `provider`, `proto`).\n- Frontend CI: Node 24, pnpm 11.0.1, `pnpm lint`, `pnpm test`, `pnpm build`.\n- Proto CI: `buf lint` and `buf format` check.\n- Docker: `scripts/Dockerfile`, Alpine 3.21 runtime, non-root user, port 5230, multi-arch amd64/arm64/arm/v7.\n</yakaai_skills>"}