# (de)Motivator Agent Instructions ## Project Context (de)Motivator is a set of two distinct packages. The primary package is an enormous set of insults, hand curated and split into "packs" that are grouped by theme. This is open source and published to the npm registry as the `demotivator` package. The second is our (PorkyProductions) first-party implementation of the package in a web app format with numerous features added on top of it. The app was started by request of Ryan Mullin (@hiteacheryouare) and initially created by Tristan Winata (@HedgehogDubz). Today, both packages are actively maintained by Ryan, Tristan, and the PorkyProductions community. ## Quick Overview ### Repo-Wide: - **Language**: Multiple - **Build System**: Turborepo - **Linting**: ESLint (configured in `.eslintrc.json` at repo root) ### Insult Package: - **Language/frameworks**: TypeScript (published as `demotivator` on npm) ### Web App: - **Language/frameworks**: Svelte 5 (with Runes enabled) + TypeScript - **Bundler**: Vite (config in `apps/web/vite.config.ts`) - **Hosting**: Firebase (`apps/web/firebase.json, firestore.rules, .firebaserc`, config) - **UI**: Tailwind + Bootstrap (some customized theme files) - **Insults/data**: provided by the `demotivator` npm package (dependency) - **Tools**: Lodash and PorkyProductions HAT ## Project Layout This is a monorepo. When building, the main goal for this should be maximizing future growth and extensibility. Create solutions that don't rely on hardcoding and one-off implementations that only work for this project. The insult package especially should be built with the mindset of being reusable and extensible for other projects. The web app should be built with the mindset of being easily maintainable and extensible for future features and changes. We host code-only packages in the `packages/` directory and full apps in the `apps/` directory. When building/testing run the turbo scripts from the root, as they build the packages in the correct order. - **Insult package**: `packages/demotivator/` - **Shared utilities**: `packages/shared/` (for things that could be shared across multiple packages/apps in the future) - **Web app**: `apps/web/` ## Language and Framework Rules ### Svelte Components - Use Svelte 5 (with runes) as the primary framework for the web app. - TypeScript for all helper functions and complex components - Use JavaScript (not TypeScript) for simple components that: - Don't use props - Are highly reusable - Don't need type safety ## Code Style Requirements ### Formatting (Per ESLint Config) - **Indentation**: TABS (not spaces) - **Line endings**: Windows (CRLF) - **Quotes**: Single quotes only `'like this'` - **Semicolons**: ALWAYS use semicolons; - **Line length**: No explicit limit, use common sense - **Interfaces**: Always prefer interfaces over types for object shapes. For discrepancies, always prefer the eslint config rules. ### Naming Conventions - **Everything**: camelCase - Variables: `myVariable` - Functions: `myFunction` - Constants: `myConstant` (NOT UPPER_SNAKE_CASE) - Files: `myComponent.svelte` or `myComponent.ts` ### Function Declarations ```javascript // ✅ CORRECT - Named anonymous arrow functions const myFunction = () => { // function body }; // ✅ CORRECT - Anonymous default export export default () => { // component body }; // ❌ WRONG - Never use explicit function declaration function myFunction() { } // NEVER DO THIS // ❌ WRONG - Never name default exports export default function MyComponent() { } // NEVER DO THIS ``` ### Svelte Component Rules - File name = Component name - Maximum 200 lines per component - If longer, break into smaller components with props/slots - Move non-Svelte operations to `/src/utils` folder - Exception: Reactive statements and component-critical logic stay in component - Data for `{#each}` blocks go in separate files Example structure: ```svelte