3.2 KiB
3.2 KiB
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 othersrc/module.src/utils/— utilities. Must not import from any othersrc/module.src/core/— business logic. May import fromcontracts/andutils/only.src/foundry/—FoundryAdapter.jsis the sole gateway togame.*APIs. Same import restriction ascore/.src/core/↔src/foundry/— never cross-import. Enforced by ESLintimport/no-restricted-paths.- Constructor side-effect-free — no hooks/socket registration in constructors; call
init()fromHooks.once('ready')inmodule.js.
Testing
- Vitest with
happy-dom,globals: false— always importdescribe,it,expect,viexplicitly. - Path aliases (vitest only):
@src,@contracts,@utils,@tests. - Mock factory — always use
createFoundryAdapterMock()fromtests/helpers/foundryAdapterMock.js. No ad-hoc stubs. - Hooks is stubbed globally via
vi.stubGlobal('Hooks', ...)in each test'sbeforeEach. - E2E tests live in
tests/e2e/with separatepackage.json. Need live FoundryVTT athttps://localhost:31000(user:gamemaster). Not run in CI. @ts-nocheckis 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 ESLintreadonlyglobals. - Type checking (
tsc --noEmit) only coversmodule.js. Source files are NOT typechecked. - Type defs from
@league-of-foundry-developers/foundry-vtt-types(9.x) + localsrc/types/foundry-globals.d.ts. - CSS scoped under
.scrying-pool, token vars prefixed--sp-*, compiled from LESS vianpm run build.
CI & releases
- Gitea (not GitHub) at
uberwald.me/gitea/. CI usesRouxAntoine/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.jsonURLs, createsmodule.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.