diff --git a/AGENTS.md b/AGENTS.md index 564309c..1b4d362 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,6 +2,17 @@ Applies to every change in this repo, by any agent or human. +## Architecture + +- npm workspace monorepo, three packages under `packages/`: + - `@dbmole/core` — shared Manager/registry/SSH-tunnel/MCP plumbing. `private`, + never published; each leaf bundles it via tsup (`noExternal`). + - `dbmole-mcp` — PostgreSQL + MySQL server + - `esmole-mcp` — Elasticsearch server +- Backends spread `baseConnectionShape`, add engine fields + `type`, call `.strict()`. +- Run workspace commands from the root, they fan out across packages: + `npm run typecheck` / `build` / `test:unit` / `test:int` / `coverage` / `lint`. + ## Code style - 4-space indentation @@ -29,8 +40,8 @@ Applies to every change in this repo, by any agent or human. - No `as unknown as X` double-casts anywhere - No `@ts-ignore` / `@ts-expect-error` / `any` in `src/` -- In tests prefer typed fakes (see `test/unit/helpers.ts`); a single `as` cast is - a last resort, only when there is genuinely no typed way +- In tests prefer typed fakes (see `packages/dbmole-mcp/test/unit/helpers.ts`); a + single `as` cast is a last resort, only when there is genuinely no typed way - Types must line up by construction — if they don't, fix the design, not the cast ## Testing @@ -55,8 +66,14 @@ Applies to every change in this repo, by any agent or human. - ESM with NodeNext resolution: relative imports need the `.js` extension - MCP SDK v1 (`@modelcontextprotocol/sdk`): `registerTool` accepts a ZodRawShape (plain object of zod fields) OR a full Zod object (verified on 1.29: AnySchema, - `.strict()` honored at runtime). Use a strict `z.object` where unknown-key - rejection matters (add_connection); raw shapes are fine elsewhere. Subpath + `.strict()` honored at runtime). The advertised `inputSchema` MUST expose + `.shape` — pass a ZodRawShape or a plain `z.object`/`.strict()`, NEVER a + `.superRefine`/`.refine` (ZodEffects has no `.shape`, so the SDK publishes an + empty `{ properties: {} }` and clients see no fields). Keep cross-field + refinements on a separate parse schema: `registerConnectionTools` takes + `fullSchema` (strict object, advertised) plus optional `parseSchema` (refined, + applied in the handler) — see esmole `add_connection`. Use a strict `z.object` + where unknown-key rejection matters; raw shapes are fine elsewhere. Subpath imports (`server/mcp.js`, `server/stdio.js`, `client/index.js`, `inMemory.js`, `types.js`) - zod 3 (`import * as z from 'zod'`)