From c938916fd884a654c82cad5e11ca4fe126d4ee60 Mon Sep 17 00:00:00 2001 From: ARIA Date: Sun, 12 Jul 2026 17:03:37 +0200 Subject: [PATCH] Fixes #18: Update README & AGENTS.md documentation - README: Add Equipment System feature, Code Quality, Performance, Memory Management, Testing, Development Commands, and Tech Stack sections - AGENTS.md: Update source tree with CSS modules, equipment constants, renderUtils, settings consolidation; add development commands, performance optimizations, memory management notes, validator factory; update file reference table Based on PRs: #1 #3 #6 #8 #10 #12 #14 #17 --- AGENTS.md | 124 ++++++++++++++++++++++++++++++++++++++++++------------ README.md | 44 +++++++++++++++++++ 2 files changed, 141 insertions(+), 27 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 02a2a58..2ef3ea4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,18 +2,19 @@ ## What this is -A **browser extension for SillyTavern** (AI roleplay frontend). It is NOT a standalone Node.js application. All JavaScript runs in the browser context inside SillyTavern. There is **no build step** — files are loaded directly by SillyTavern's extension loader. +A **browser extension for SillyTavern** (AI roleplay frontend). It is NOT a standalone Node.js application. All JavaScript runs in the browser context inside SillyTavern. There is **no bundler** — JS files are loaded directly by SillyTavern's extension loader. CSS modules are concatenated via a build script. --- ## Quick start - **Entry point**: `index.js` (loaded by SillyTavern via `manifest.json`) -- **CSS**: `style.css` (single file, ~12,300 lines) +- **CSS**: Modular — 28 files in `src/styles/`, concatenated via `npm run build:css` (or `npm run build:css:min` for production) - **HTML templates**: `template.html` (main panel), `settings.html` (Extensions tab settings drawer) - **Runtime**: Browser only. All code executes inside SillyTavern's page context. - **jQuery**: Available globally as `$` / `jQuery`. Used extensively for DOM manipulation. - **ES modules**: All `src/` files use `import`/`export` (browser ES module syntax). +- **Testing**: Jest + Babel ESM support — 78 tests (`npm test`) --- @@ -76,11 +77,12 @@ The deeper relative imports in `src/` files (e.g., `../../../../../../script.js` ``` src/ ├── core/ # Core infrastructure -│ ├── config.js # Extension name, folder path, default settings -│ ├── state.js # Centralized state variables + getters/setters +│ ├── config.js # Extension name, folder path, default settings (single source of truth) +│ ├── state.js # Centralized state variables + getters/setters (imports defaults from config.js) │ ├── persistence.js # Save/load settings, chat data, migrations │ ├── events.js # SillyTavern event system wrapper -│ └── i18n.js # Translation system (fetches JSON, applies data-i18n-key) +│ ├── i18n.js # Translation system (fetches JSON, applies data-i18n-key) +│ └── settingsPanel.js # Extracted settings panel UI (from index.js refactor) ├── i18n/ # Translation JSON files │ ├── en.json # English (reference, 513 lines) │ ├── fr.json # French @@ -88,10 +90,39 @@ src/ │ ├── zh-cn.json # Simplified Chinese │ ├── zh-tw.json # Traditional Chinese │ └── validator.js # Node.js script to validate translation consistency +├── styles/ # CSS modules (28 files, concatenated via build script) +│ ├── _01_variables.css # CSS custom properties +│ ├── _02_panel.css # Main panel layout +│ ├── _03_components.css # Buttons, inputs, common components +│ ├── _04_user-stats.css # User stats panel +│ ├── _05_info-box.css # Info box dashboard +│ ├── _06_thoughts.css # Character thoughts +│ ├── _07_settings.css # Settings modal +│ ├── _08_themes.css # Theme definitions (extended custom properties) +│ ├── _09_dice-modal.css # Dice roller modal +│ ├── _10_tracker-editor.css # Tracker configuration editor +│ ├── _11_settings-modal.css # Settings modal styles +│ ├── _12_thought-bubbles.css # Floating thought bubbles +│ ├── _13_mobile.css # Mobile responsive styles +│ ├── _14_inventory.css # Inventory views +│ ├── _15_inventory-views.css # Inventory detail views +│ ├── _16_desktop-tabs.css # Desktop tab navigation +│ ├── _17_quests.css # Quest tracking +│ ├── _18_equipment.css # Equipment grid +│ ├── _19_encounters.css # Combat encounters +│ ├── _20_plot-buttons.css # Plot progression buttons +│ ├── _21_music-player.css # Spotify music player +│ ├── _22_weather.css # Weather effects +│ ├── _23_holiday-promo.css # Holiday promotions +│ ├── _24_feature-toggles.css # Feature toggle switches +│ ├── _25_import-dialog.css # Import/export dialog +│ ├── _26_fab-widgets.css # Mobile FAB widgets +│ ├── _27_strip-widgets.css # Collapsed panel strip widgets +│ └── _28_equipment-modal.css # Equipment edit modal ├── systems/ # Feature systems (organized by concern) │ ├── generation/ # AI prompt generation, parsing, API calls -│ │ ├── promptBuilder.js # Builds tracker prompts for AI -│ │ ├── parser.js # Parses AI responses to extract tracker data +│ │ ├── promptBuilder.js # Builds tracker prompts for AI (refactored with focused helpers) +│ │ ├── parser.js # Parses AI responses (~50 pre-compiled regex patterns) │ │ ├── apiClient.js # Makes API calls for separate/external generation │ │ ├── injector.js # Injects tracker prompts into generation context │ │ ├── lockManager.js # Manages locked tracker fields @@ -106,7 +137,8 @@ src/ │ │ ├── inventory.js # Renders inventory section │ │ ├── equipment.js # Renders equipment section │ │ ├── quests.js # Renders quests section -│ │ └── musicPlayer.js # Renders Spotify music player +│ │ ├── musicPlayer.js # Renders Spotify music player +│ │ └── renderUtils.js # Rendering utilities (updateIfChanged cache, rAF batching) │ ├── ui/ # UI components and helpers │ │ ├── theme.js # Theme system (default, sci-fi, fantasy, cyberpunk, custom) │ │ ├── modals.js # Settings modal, dice modal, deprecation modal @@ -119,7 +151,10 @@ src/ │ │ ├── encounterUI.js # Combat encounter modal │ │ ├── snowflakes.js # Snowflake animation effect │ │ ├── weatherEffects.js # Dynamic weather visual effects -│ │ └── alternatePresentCharacters.js # Below-chat character panel +│ │ ├── alternatePresentCharacters.js # Below-chat character panel +│ │ └── settingsListeners.js # Settings event listeners (extracted from index.js) +│ ├── equipment/ # Equipment system +│ │ └── constants.js # Equipment slot definitions, type limits, stat config │ ├── integration/ # SillyTavern event integration │ │ ├── sillytavern.js # Event handlers: message sent/received, swipe, etc. │ │ └── thoughtBasedExpressions.js # Integrates with ST Character Expressions @@ -144,11 +179,11 @@ src/ ├── imageUrls.js # Image URL utilities ├── itemParser.js # Item string parsing ├── jsonMigration.js # v2 to v3 JSON format migration - ├── jsonRepair.js # JSON repair for malformed AI responses + ├── jsonRepair.js # JSON repair for malformed AI responses (14 pre-compiled regex) ├── migration.js # Settings migration helpers ├── presentCharacters.js # Present character data helpers ├── responseExtractor.js # Extract tracker data from AI responses - ├── security.js # Input validation and sanitization + ├── security.js # Input validation and sanitization (validator factory) ├── sillyTavernExpressions.js # ST expression mapping ├── thoughtBasedExpressionPortraits.js # Expression-to-portrait mapping └── transformations.js # Data transformation utilities @@ -163,7 +198,7 @@ src/ 5. **External API mode**: Uses user-configured external API endpoint 6. **AI responds** → `MESSAGE_RECEIVED` event fires 7. **Extension hooks** `onMessageReceived` → `parser.js` extracts tracker data -8. **Rendering**: `renderUserStats()`, `renderInfoBox()`, `renderThoughts()`, etc. update the UI +8. **Rendering**: `renderUserStats()`, `renderInfoBox()`, `renderThoughts()`, etc. update the UI (batched via rAF) 9. **Persistence**: Tracker data is saved to `chat_metadata` per chat, and per-swipe ### State management @@ -178,6 +213,8 @@ All extension state lives in `src/core/state.js` as module-level `let` variables - `pendingDiceRoll` — dice roll result to inject into next generation - DOM element caches: `$panelContainer`, `$userStatsContainer`, etc. +**Settings consolidation**: `config.js` is the single source of truth for default settings. `state.js` imports defaults from `config.js` (~300 lines eliminated from duplication). + ### Persistence `src/core/persistence.js` handles: @@ -187,20 +224,35 @@ All extension state lives in `src/core/state.js` as module-level `let` variables - Settings versioning: automatic migration via `CURRENT_SETTINGS_VERSION` (currently 7) - Deferred saves: batches chat data saves to avoid excessive writes +### Memory management + +- `clearDomCache()`: Invalidates jQuery object cache on panel rebuild +- Event tracking: All `on()`/`once()` handlers tracked for cleanup via `unregisterAllEvents()` +- `clearDebugLogs()`: Called on `CHAT_CHANGED` to prevent unbounded debug log growth + +### Performance optimizations + +- **Rendering**: `requestAnimationFrame` batching in `rerenderRpgState()`, `updateIfChanged()` cache comparison in `renderUtils.js`, CSS `content-visibility: auto` on inventory/equipment containers +- **Parser**: ~64 regex patterns pre-compiled as module-level constants, format detection caching with `lastDetectedFormat` (3-hit threshold) +- **CSS**: Minification via `--minify` flag, extended CSS custom properties, theme refactoring (379 → ~220 lines) + --- ## Development commands ```bash -# Validate translation files (check missing keys, type mismatches, empty values) -npm run validate_locale_once +# Build CSS from modular sources +npm run build:css # Concatenate CSS modules into style.css +npm run build:css:min # Minified production build (~50% smaller) -# Watch mode: re-validate on file changes -npm run validate_locale +# Testing +npm test # Run Jest test suite (78 tests) + +# Translation validation +npm run validate_locale # Watch mode: re-validate on file changes +npm run validate_locale_once # Single validation run ``` -No build, lint, test, or typecheck commands exist. The code runs directly in the browser. - --- ## i18n system @@ -256,6 +308,14 @@ All CSS classes use `rpg-` prefix to avoid conflicts with SillyTavern and other - `.rpg-panel`, `.rpg-section`, `.rpg-stat-bar`, `.rpg-btn-primary`, etc. - CSS custom properties: `--rpg-bg`, `--rpg-accent`, `--rpg-text`, `--rpg-highlight`, `--rpg-border`, `--rpg-shadow` +### CSS build pipeline + +CSS modules in `src/styles/` are concatenated in numeric order by `scripts/build-css.js`. Modules follow the naming convention `_NN_name.css` where NN is the load order. After modifying any CSS module, run `npm run build:css` to regenerate `style.css`. + +### Validator factory + +Input sanitization uses `createStringValidator()` from `src/utils/security.js` — a factory pattern that unifies `sanitizeLocationName`/`sanitizeItemName` with configurable rules (max length, allowed characters, etc.). + ### Panel structure The main panel (`template.html`) has these sections in order: @@ -290,7 +350,7 @@ The `skipInjectionsForGuided` setting controls tracker injection behavior during 2. **Relative import depth matters**: Files in `src/` use deeper relative paths (`../../../../../../script.js`) than `index.js` (`../../../../script.js`). When moving files between directories, adjust accordingly. -3. **Settings merge**: On load, saved settings are deep-merged with defaults from `src/core/state.js`. New settings fields should be added to both the state module (runtime defaults) AND `src/core/config.js` (documentation defaults). +3. **Settings merge**: On load, saved settings are deep-merged with defaults. `config.js` is the single source of truth for default settings — `state.js` imports from it. New settings fields should be added to `config.js`. 4. **Chat metadata**: Per-chat tracker data lives in `chat_metadata.rpg_companion`. Per-swipe data lives on individual chat message objects in the `swipe_store`. @@ -302,9 +362,13 @@ The `skipInjectionsForGuided` setting controls tracker injection behavior during 8. **External API key**: Stored in `localStorage` as `rpg_companion_external_api_key`, NOT in extension settings (for security). -9. **The `package.json` has no runtime dependencies**. The `devDependencies` (chokidar, fs-extra, glob) are only for the i18n validator. +9. **Dev dependencies**: `package.json` has devDependencies (Jest, Babel, chokidar, fs-extra, glob, execa) for testing and i18n validation. No runtime dependencies — the extension runs entirely in the browser. -10. **Deprecation status**: The README states this extension is deprecated in favor of Marinara Engine. The code shows a deprecation modal that displays on first load. +10. **CSS rebuild required**: After modifying any file in `src/styles/`, run `npm run build:css` to regenerate `style.css`. SillyTavern loads `style.css`, not the individual modules. + +11. **Deprecation status**: The README states this extension is deprecated in favor of Marinara Engine. The code shows a deprecation modal that displays on first load. + +12. **ESM testing**: Jest uses Babel for ESM transformation (`babel.config.json` + `jest.config.cjs`). All test files use ES module syntax. --- @@ -312,19 +376,25 @@ The `skipInjectionsForGuided` setting controls tracker injection behavior during | File | Purpose | |------|---------| -| `index.js` | Main entry point. All imports, UI init, event registration, startup logic. | +| `index.js` | Main entry point. Imports, UI init, event registration, startup logic (~456 lines after refactor). | | `manifest.json` | SillyTavern extension manifest (name, loading order, JS/CSS files). | -| `style.css` | All CSS (~12,300 lines). Themes, animations, responsive breakpoints. | +| `style.css` | Built CSS output (concatenated from `src/styles/` modules). Do not edit directly. | | `template.html` | Main panel HTML template. Rendered by SillyTavern's `renderExtensionTemplateAsync`. | | `settings.html` | Extensions tab settings drawer. Minimal — most settings are in the panel modal. | -| `src/core/state.js` | Central state module. All extension-wide variables live here. | +| `scripts/build-css.js` | CSS build script. Concatenates modules, supports `--minify` flag. | +| `src/core/state.js` | Central state module. Imports defaults from config.js. All extension-wide variables. | | `src/core/persistence.js` | Settings/chat data save/load, version migrations. | -| `src/core/config.js` | Extension name, path detection, default settings documentation. | +| `src/core/config.js` | Extension name, path detection, default settings (single source of truth). | | `src/core/events.js` | SillyTavern event system wrapper with bulk register/unregister. | | `src/core/i18n.js` | Translation loader and DOM applier. | +| `src/core/settingsPanel.js` | Extracted settings panel UI (from index.js refactor, PR #6). | | `src/systems/integration/sillytavern.js` | All SillyTavern event handlers (message lifecycle, swipes, chat changes). | -| `src/systems/generation/promptBuilder.js` | Builds AI prompts for tracker generation. | -| `src/systems/generation/parser.js` | Parses AI responses to extract tracker JSON. | +| `src/systems/generation/promptBuilder.js` | Builds AI prompts for tracker generation (refactored with focused helpers). | +| `src/systems/generation/parser.js` | Parses AI responses to extract tracker JSON (~50 pre-compiled regex patterns). | | `src/systems/generation/apiClient.js` | API client for separate/external generation modes. | | `src/systems/generation/injector.js` | Injects tracker prompts into SillyTavern's generation context. | +| `src/systems/rendering/renderUtils.js` | Rendering utilities: `updateIfChanged()` cache, rAF batching. | +| `src/systems/equipment/constants.js` | Equipment slot definitions, type limits, stat configuration. | +| `src/utils/security.js` | Input validation, sanitization, validator factory (`createStringValidator()`). | +| `src/utils/jsonRepair.js` | JSON repair for malformed AI responses (14 pre-compiled regex patterns). | | `src/i18n/validator.js` | Node.js script for validating translation consistency. | diff --git a/README.md b/README.md index 831214a..091c11d 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Moving on to developing the Marinara Engine frontend, the extension will now be - **🎭 Floating Thought Bubbles**: Optional thought bubbles positioned next to character avatars in chat - **🎲 Classic RPG Stats**: STR, DEX, CON, INT, WIS, CHA attributes with dice roll support - **📦 Advanced Inventory System**: Multi-location storage (On Person, Stored locations, Assets) with v2 format +- **⚔️ Equipment System**: 19 equipment slots (Helmet, Necklace, Body Armor, Gloves, Pants, Shoes, 10 Rings, 3 Accessories) with slot-type validation, stat bonuses (+99 max), and automatic slot assignment - **🎯 Character Stats**: Track health, energy, or any custom stats for each present character with color interpolation - **📜 Immersive HTML**: Enhance the immersion by including creative HTML/CSS/JS elements in your roleplay - **➡️ Plot Progression**: Progress the plot with randomized events or natural progression with a click of a button @@ -226,6 +227,49 @@ Choose from 6 beautiful themes: If you ever have an awesome idea to do your own SillyTavern extension, don't. +### Code Quality + +- **index.js refactored**: 1567 lines → 456 lines (73% reduction) through modular extraction +- **CSS modularized**: 28 logical modules in `src/styles/` with automated build script +- **Settings consolidation**: `config.js` as single source of truth — state.js imports from it (~300 lines eliminated) +- **Validator factory pattern**: `createStringValidator()` unifies `sanitizeLocationName`/`sanitizeItemName` +- **Prompt builder refactored**: `getCharacterCardsInfo` extracted into focused helper functions +- **Error visibility**: `jsonRepair.js` silent failures now log to `console.debug` + +### Performance + +- **Rendering**: `requestAnimationFrame` batching in `rerenderRpgState()`, `updateIfChanged()` cache in `renderUtils.js`, CSS `content-visibility: auto` on inventory/equipment containers +- **Parser**: Regex pre-compilation (~64 patterns in `parser.js` + `jsonRepair.js` as module-level constants), format detection caching (`lastDetectedFormat` with 3-hit threshold), `clearFormatCache()` for invalidation +- **CSS**: Minification support (`--minify` flag in build script), extended CSS custom properties, theme refactoring (379 → ~220 lines), `style.css` reduced from 305.4 KB → 293.9 KB (3.8%), minified build adds ~50%+ further reduction + +### Memory Management + +- **`clearDomCache()`**: Invalidates jQuery object cache on panel rebuild to prevent stale references +- **Event tracking**: All `on()`/`once()` handlers tracked for cleanup via `unregisterAllEvents()` +- **`clearDebugLogs()`**: Called on `CHAT_CHANGED` to prevent unbounded debug log growth + +### Testing + +- **78 tests passing** (up from 54) using Jest with Babel ESM support +- ESM compatibility via `babel.config.json` + `jest.config.cjs` transform configuration +- Security-focused test suite (`security.test.js`, 24 tests) + +### Development Commands + +```bash +npm run build:css # Concatenate CSS modules +npm run build:css:min # Minified production build +npm test # Run Jest test suite +npm run validate_locale # Watch mode translation validation +npm run validate_locale_once +``` + +### Tech Stack + +- `"type": "module"` — ES modules throughout +- Jest + Babel for testing with full ESM support +- Modular CSS build pipeline with minification support + ## 🐛 Troubleshooting ### Extension doesn't appear -- 2.54.0