{"owner":"redis","repo":"node-redis","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"files":{"AGENTS.md":"# AGENTS.md\n\nGuidance for agents working in this repo.\n\n## What this is\n\n`node-redis` — modern Redis client for Node.js. A **monorepo** (npm workspaces) of\npublishable packages. Requires Node `>= 20`. TypeScript throughout.\n\n## Packages (`packages/`)\n\n| Package | Purpose |\n| --- | --- |\n| `redis` | \"All-in-one\" meta-package re-exporting client + all modules |\n| `client` (`@redis/client`) | Core: `RedisClient`, `RedisCluster`, `RedisSentinel`, pool, RESP codec, command framework |\n| `bloom` (`@redis/bloom`) | Probabilistic commands (bloom, cuckoo, count-min, t-digest, top-k) |\n| `json` (`@redis/json`) | RedisJSON commands |\n| `search` (`@redis/search`) | RediSearch commands |\n| `time-series` (`@redis/time-series`) | Time-series commands |\n| `entraid` (`@redis/entraid`) | Microsoft Entra ID token auth |\n| `test-utils` (`@redis/test-utils`) | Shared test harness; spins up Redis via docker |\n\nModule packages depend on `@redis/client` and follow the same command structure.\n\n## Core layout — `packages/client/lib/`\n\n- `client/` — connection internals: `index.ts` (RedisClient), `socket.ts`, `commands-queue.ts`, `parser.ts`, `pool.ts`, `pub-sub.ts`, `cache.ts`\n- `cluster/`, `sentinel/` — cluster & sentinel clients\n- `commands/` — one file per Redis command (e.g. `GET.ts`) + `index.ts` registry\n- `RESP/` — RESP2/RESP3 protocol: `encoder.ts`, `decoder.ts`, `types.ts`\n- `authx/` — auth/credential providers\n\n## Command pattern\n\nEach command is `<NAME>.ts` exporting a `Command` object:\n\n```typescript\nexport default {\n  CACHEABLE: true,\n  IS_READ_ONLY: true,\n  parseCommand(parser: CommandParser, key: RedisArgument) {\n    parser.push('GET');\n    parser.pushKey(key);\n  },\n  transformReply: undefined as unknown as () => BlobStringReply | NullReply\n} as const satisfies Command;\n```\n\n- `parseCommand` builds wire args via `CommandParser` (`push`, `pushKey`, ...).\n- `transformReply` maps reply to JS type; `undefined` = pass-through. Can be keyed by RESP version `{ 2: ..., 3: ... }`.\n- Register new command in the package's `commands/index.ts` (import + map entry). RESP3 is default — no extra RESP3 test needed for new commands.\n- JSDoc on commands is checked: `npm run check:command-jsdoc`.\n\n## Tests\n\n- Co-located `<NAME>.spec.ts` next to source. Mocha + `tsx`, `node:assert`.\n- `testUtils.testAll(name, fn, { client, cluster })` runs same test across server + cluster topologies (see `test-utils.ts`, `GLOBAL`).\n- **Docker required** — test-utils starts real Redis containers.\n- Pure arg/reply tests use `parseArgs(COMMAND, ...args)`.\n\nCommands:\n- `npm test` — full suite, all workspaces (runs `cleanup` first).\n- `npm test -w @redis/client` — one package.\n- Single file from root: `npm run test-single -- <path-to-spec>`.\n- `npm run build` — `tsc --build` (project references; build before cross-package work).\n- Build can break on stale `dist/` from project references. Clean rebuild:\n  ```bash\n  find packages -type d -name \"dist\" -exec rm -rf {} + && npm run build\n  ```\n- `npm run lint` — lint changed files only; `npm run lint:all` for everything.\n\n## Conventions\n\n- TypeScript strict mode; `noUnusedLocals` on. Target ES2022 / NodeNext modules.\n- Raw command names (`HSET`) and camelCase aliases (`hSet`) both exposed.\n- Conventional Commits. Per-package releases via `release-it` (`npm run release`).\n- Keep company-internal refs (Jira/Confluence IDs, internal links) out of OSS commits, branches, PRs, code.\n\n## Docs\n\nDeep-dive guides in `docs/` (client-configuration, clustering, sentinel, pool, RESP, transactions, programmability, pub-sub, scan-iterators, migration guides). Runnable examples in `examples/`, `doctests/`.\n"}}