# General Guidelines for working with Nx - For navigating/exploring the workspace, invoke the `nx-workspace` skill first - it has patterns for querying projects, targets, and dependencies - When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly - Prefix nx commands with the workspace's package manager (e.g., `pnpm nx build`, `npm exec nx test`) - avoids using globally installed CLI - You have access to the Nx MCP server and its tools, use them to help the user - For Nx plugin best practices, check `node_modules/@nx//PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable. - NEVER guess CLI flags - always check nx_docs or `--help` first when unsure ## Scaffolding & Generators - For scaffolding tasks (creating apps, libs, project structure, setup), ALWAYS invoke the `nx-generate` skill FIRST before exploring or calling MCP tools ## When to use nx_docs - USE for: advanced config options, unfamiliar flags, migration guides, plugin configuration, edge cases - DON'T USE for: basic generator syntax (`nx g @nx/react:app`), standard commands, things you already know - The `nx-generate` skill handles generator discovery internally - don't call nx_docs just to look up generator syntax # Fog Expedition — project guidance This is a Twitch Video Overlay extension implementing an autonomous tick-based ZPG. See `PROJECT_CONTEXT.md` at the repo root for full architecture, design direction, and build stages — read it before any non-trivial work. ## Conventions - Sentence case in UI text and log messages. - Zod schemas (not just TS types) at the EBS boundary. - Pure functions for game logic. Seeded PRNG via `seedrandom`, never `Math.random()`. Persist seeds in `mission_logs`. - Migrations from day one. No "I'll add migrations later." - Round every displayed number; JS float math leaks artifacts. - Structured logging with correlation IDs (`missionId`, `tickIndex`, `channelId`, `opaqueUserId`). - Bind Nest services to `0.0.0.0`, not `127.0.0.1`. The Twitch dev rig on Windows reaches them via the WSL2/devcontainer port forwarding chain. ## Hard rules - Don’t assume. Don’t hide confusion. Surface tradeoffs. - Minimum code that solves the problem. Nothing speculative. - Touch only what you must. Clean up only your own mess. - Define success criteria. Loop until verified. - Do not use `Math.random()` anywhere in game logic. - Do not skip `nextTickAt` jitter — synchronised global ticks will thunder-herd Postgres. - Do not assume Twitch PubSub message delivery; treat as a hint to refresh, reconcile from REST. - Do not add inline scripts or inline event handlers to the overlay HTML — Twitch CSP forbids them. ## Twitch extension specifics - JWTs use HS256 with the base64-decoded shared secret. Not RS256. - `opaque_user_id` starts with `U` (logged-in viewer) or `A` (anonymous). Anonymous viewers cannot have persistent survivors — read-only view only. - PubSub limit: 1 message/sec per channel, 5KB max payload, no delivery guarantees. Batch all per-channel updates per tick into one message. ## Quality bar - Property-based tests (`fast-check`) for pure functions, especially the encounter resolver. - Monte Carlo balance snapshot test in CI for the resolver. - Type-check and lint must pass before declaring work complete. - No commented-out code. No `TODO` without a tracked issue reference. ## When stuck If a decision isn't covered by `PROJECT_CONTEXT.md` and isn't trivially derivable from convention, surface it as a question rather than guessing.