chore: AGENTS.md
This commit is contained in:
parent
4f49599527
commit
f4649e0dac
|
|
@ -0,0 +1,70 @@
|
||||||
|
# AGENTS.md - boardgame-core
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
Prefer `bash.exe`(C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps\bash.exe) over Powershell.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build # Build ESM bundle + declarations to dist/
|
||||||
|
npm run test # Run vitest in watch mode
|
||||||
|
npm run test:run # Run vitest once (no watch)
|
||||||
|
npm run typecheck # Type-check without emitting (tsc --noEmit)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running a single test file
|
||||||
|
```bash
|
||||||
|
npx vitest run tests/samples/tic-tac-toe.test.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running a single test by name
|
||||||
|
```bash
|
||||||
|
npx vitest run -t "should detect horizontal win for X"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
### Imports
|
||||||
|
- Use **double quotes** for local imports, **single quotes** for npm packages
|
||||||
|
- No path aliases — use relative `../` and `./` paths
|
||||||
|
|
||||||
|
### Formatting
|
||||||
|
- **4-space indentation**
|
||||||
|
- **Semicolons** at statement ends
|
||||||
|
- **Arrow functions** for callbacks; `function` keyword for methods needing `this` (e.g. command handlers)
|
||||||
|
- No trailing whitespace
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
- **Types/Interfaces**: `PascalCase` — `Part`, `Region`, `Command`, `IGameContext`
|
||||||
|
- **Classes**: `PascalCase` — `Entity`, `AsyncQueue`, `Mulberry32RNG`
|
||||||
|
- **Functions**: `camelCase`, verb-first — `createGameContext`, `parseCommand`, `isValidMove`
|
||||||
|
- **Variables**: `camelCase`
|
||||||
|
- **Constants**: `UPPER_SNAKE_CASE` — `BOARD_SIZE`, `WINNING_LINES`
|
||||||
|
- **Test files**: `*.test.ts` mirroring `src/` structure under `tests/`
|
||||||
|
|
||||||
|
### Types
|
||||||
|
- **Strict TypeScript** is enabled — no `any`
|
||||||
|
- Use **generics** heavily: `Entity<T>`, `CommandRunner<TContext, TResult>`
|
||||||
|
- Use **type aliases** for object shapes (not interfaces)
|
||||||
|
- Use **discriminated unions** for results: `{ success: true; result: T } | { success: false; error: string }`
|
||||||
|
- Use `unknown` for untyped values, narrow with type guards or `as`
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
- Prefer **result objects** over throwing: return `{ success, result/error }`
|
||||||
|
- When catching: `const error = e as Error;` then use `error.message`
|
||||||
|
- Use `throw new Error(...)` only for truly exceptional cases
|
||||||
|
- Validation error messages are in Chinese (e.g. `"参数不足"`)
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- **Vitest** with globals enabled (`describe`, `it`, `expect` available without import)
|
||||||
|
- Use `async/await` for async tests
|
||||||
|
- Narrow result types with `if (result.success)` before accessing `result.result`
|
||||||
|
- Define inline helper functions in test files when needed
|
||||||
|
- No mocking — use real implementations
|
||||||
|
- Test helpers: `createTestContext()`, `createTestRegion()`
|
||||||
|
|
||||||
|
## Architecture Notes
|
||||||
|
|
||||||
|
- **Reactivity**: `Entity<T>` extends Preact Signal — access state via `.value`, mutate via `.produce(draft => ...)`
|
||||||
|
- **Command system**: CLI-style parsing with schema validation via `inline-schema`
|
||||||
|
- **Prompt system**: Commands prompt for input via `PromptEvent` with `resolve`/`reject`
|
||||||
|
- **Barrel exports**: `src/index.ts` is the single public API surface
|
||||||
Loading…
Reference in New Issue