56 lines
3.2 KiB
Markdown
56 lines
3.2 KiB
Markdown
# Scrying Pool — Agent Instructions
|
|
|
|
FoundryVTT v14 module for GM camera visibility control. Ships as raw ES modules (no bundler). Entry: `module.js` → `module.json:esmodules`.
|
|
|
|
## Commands (run in order: lint → typecheck → test → build)
|
|
|
|
| Intent | Command |
|
|
|--------|---------|
|
|
| Lint | `npm run lint` |
|
|
| Typecheck | `npm run typecheck` |
|
|
| Test (unit) | `npm run test` |
|
|
| Test (watch) | `npm run test:watch` |
|
|
| Build CSS | `npm run build` |
|
|
| Release | `npm run release` |
|
|
| E2E test | `npm test` in `tests/e2e/` |
|
|
|
|
**Watch is broken** — `npm run watch` outputs to `dist/styles/` (gitignored) instead of `styles/`. Use `npm run build` manually.
|
|
|
|
Version source of truth: `package.json`; `scripts/package.mjs` copies it to `module.json` at release.
|
|
|
|
## Architecture
|
|
|
|
- **`module.js`** — wiring diagram ONLY. Imports, constructs with DI, registers hooks. Zero business logic. Never add logic here.
|
|
- **`src/contracts/`** — data contracts/DTOs. Must not import from any other `src/` module.
|
|
- **`src/utils/`** — utilities. Must not import from any other `src/` module.
|
|
- **`src/core/`** — business logic. May import from `contracts/` and `utils/` only.
|
|
- **`src/foundry/`** — `FoundryAdapter.js` is the sole gateway to `game.*` APIs. Same import restriction as `core/`.
|
|
- **`src/core/` ↔ `src/foundry/`** — never cross-import. Enforced by ESLint `import/no-restricted-paths`.
|
|
- **Constructor side-effect-free** — no hooks/socket registration in constructors; call `init()` from `Hooks.once('ready')` in `module.js`.
|
|
|
|
## Testing
|
|
|
|
- **Vitest** with `happy-dom`, `globals: false` — always import `describe`, `it`, `expect`, `vi` explicitly.
|
|
- **Path aliases** (vitest only): `@src`, `@contracts`, `@utils`, `@tests`.
|
|
- **Mock factory** — always use `createFoundryAdapterMock()` from `tests/helpers/foundryAdapterMock.js`. No ad-hoc stubs.
|
|
- **Hooks** is stubbed globally via `vi.stubGlobal('Hooks', ...)` in each test's `beforeEach`.
|
|
- **E2E tests** live in `tests/e2e/` with separate `package.json`. Need live FoundryVTT at `https://localhost:31000` (user: `gamemaster`). Not run in CI.
|
|
- **`@ts-nocheck`** is used at top of many test files — this is normal for this repo.
|
|
|
|
## FoundryVTT specifics
|
|
|
|
- Globals injected at runtime: `Hooks`, `game`, `ui`, `canvas`, `foundry`, `CONFIG`, `CONST` — listed as ESLint `readonly` globals.
|
|
- Type checking (`tsc --noEmit`) only covers `module.js`. Source files are NOT typechecked.
|
|
- Type defs from `@league-of-foundry-developers/foundry-vtt-types` (9.x) + local `src/types/foundry-globals.d.ts`.
|
|
- CSS scoped under `.scrying-pool`, token vars prefixed `--sp-*`, compiled from LESS via `npm run build`.
|
|
|
|
## CI & releases
|
|
|
|
- **Gitea** (not GitHub) at `uberwald.me/gitea/`. CI uses `RouxAntoine/checkout@v3.5.4`.
|
|
- CI: `npm ci` → `npm audit --production` → `npm run lint` → `npm run typecheck` → `npm run test` → `npm run build`.
|
|
- Release: triggered on tag publish, substitutes `module.json` URLs, creates `module.zip`, uploads via curl + Gitea API token.
|
|
|
|
## Design docs
|
|
|
|
Full project history in `_bmad-output/` — PRDs, architecture specs, epics, deferred work tracking. For deep context start with `_bmad-output/planning-artifacts/architecture.md` and `_bmad-output/planning-artifacts/epics.md`.
|