|
| 1 | +# Millennium Plugin Database |
| 2 | + |
| 3 | +This repository contains community plugins for [Millennium](https://steambrew.app/), a Steam client modding platform. Each subdirectory under `plugins/` is an independent plugin. |
| 4 | + |
| 5 | +## PR Review Instructions |
| 6 | + |
| 7 | +When reviewing pull requests that add or update plugins, perform the following checks thoroughly. Be direct and specific in your feedback. |
| 8 | + |
| 9 | +### Security Review |
| 10 | + |
| 11 | +- Audit all network requests (fetch, XMLHttpRequest, WebSocket) for data exfiltration, SSRF, or connections to suspicious/hardcoded external endpoints. |
| 12 | +- Check for unsafe use of `eval()`, `Function()`, `innerHTML`, `dangerouslySetInnerHTML`, or any other code injection vectors. |
| 13 | +- Look for credential/token leakage -- secrets hardcoded in source, logged to console, or sent to third parties. |
| 14 | +- Inspect `callable` RPC declarations and their backend counterparts for input validation issues. |
| 15 | +- Flag any use of `document.cookie`, `localStorage`/`sessionStorage` access that reads data unrelated to the plugin's own scope. |
| 16 | +- Check for prototype pollution, unsafe deserialization, or any DOM-based injection risks. |
| 17 | +- Review file system access patterns in Lua backends for path traversal or arbitrary file read/write. |
| 18 | + |
| 19 | +### Bug Review (Priority) |
| 20 | + |
| 21 | +This is the most important part of the review. Drill deep into logic and correctness: |
| 22 | + |
| 23 | +- Trace every code path -- look for unhandled edge cases, off-by-one errors, null/undefined dereferences, race conditions, and incorrect async/await usage. |
| 24 | +- Check for missing cleanup: event listeners not removed, intervals/timeouts not cleared, subscriptions not unsubscribed. These cause memory leaks and ghost behavior in a long-running Steam client. |
| 25 | +- Verify state management correctness: stale closures, missing dependency arrays in `useEffect`/`useMemo`/`useCallback`, state updates on unmounted components. |
| 26 | +- Check error handling: uncaught promise rejections, missing try/catch around `callable` RPC calls, network requests without error handling. |
| 27 | +- Look for incorrect type coercion, string/number confusion, and comparisons that should use strict equality. |
| 28 | +- Verify that `plugin.json` schema is correct: required fields present (`name`, `common_name`, `description`, `version`), version format is valid, `backendType` matches actual backend usage. |
| 29 | +- Check for hardcoded Steam AppIDs, user IDs, or other magic values that should be dynamic. |
| 30 | +- Look for infinite loops, infinite re-renders, or expensive operations inside render cycles. |
| 31 | + |
| 32 | +### Breaking Changes |
| 33 | + |
| 34 | +Always flag the following as breaking changes when they occur in plugin updates: |
| 35 | + |
| 36 | +- Changes to `plugin.json` fields: `name`, `backendType`, `data` schema changes (renamed/removed keys). |
| 37 | +- Removed or renamed `callable` backend function signatures. |
| 38 | +- Changed settings storage keys (causes users to lose their settings on update). |
| 39 | +- Bumped minimum Millennium version requirements. |
| 40 | +- Removed features or changed default behavior. |
| 41 | + |
| 42 | +Clearly label these as **Breaking Change** in your review. |
| 43 | + |
| 44 | +### UI/Component Standards |
| 45 | + |
| 46 | +Plugins must use the component library from `@steambrew/client` and Steam's built-in components. Review settings panels and UI for compliance: |
| 47 | + |
| 48 | +**Settings panels** are defined in `definePlugin()`'s return object via the `content` prop (in the plugin's `index.tsx`): |
| 49 | +```tsx |
| 50 | +export default definePlugin(() => { |
| 51 | + return { |
| 52 | + title: "Plugin Name", |
| 53 | + icon: <IconsModule.Something />, |
| 54 | + content: <SettingsPanel />, |
| 55 | + }; |
| 56 | +}); |
| 57 | +``` |
| 58 | + |
| 59 | +**Required component usage:** |
| 60 | +- Use `Field` for settings rows (with `label`, `description`, and `bottomSeparator` props). |
| 61 | +- Use `Toggle`, `TextField`, `Dropdown`, `Slider` for input controls inside `Field`. |
| 62 | +- Use `DialogButton` or `Button` for actions. |
| 63 | +- Use `showModal`/`ModalRoot`/`ConfirmModal` for dialogs. |
| 64 | +- Use `showContextMenu`/`Menu`/`MenuItem` for context menus. |
| 65 | +- Use `Focusable` for keyboard/controller navigation support. |
| 66 | +- Use `Spinner` for loading states. |
| 67 | + |
| 68 | +**Flag these anti-patterns:** |
| 69 | +- Raw HTML elements (`<input>`, `<select>`, `<button>`, `<table>`) used where a `@steambrew/client` or Steam component exists. |
| 70 | +- Direct DOM manipulation (`document.createElement`, `element.innerHTML`, `element.appendChild`) for UI that could be React components. |
| 71 | +- Inline `style` attributes or `<style>` tags for layout/styling that Steam's existing CSS classes handle. Custom styles are acceptable only when Steam provides no equivalent. |
| 72 | +- Using `window.SP_REACT.createElement` directly instead of JSX. |
| 73 | +- Building settings UI outside of the `definePlugin` `content` pattern without good reason. |
| 74 | + |
| 75 | +**Acceptable exceptions:** |
| 76 | +- DOM manipulation for injecting into parts of Steam's UI that aren't exposed via React (e.g., patching existing Steam pages via `Millennium.findElement`). |
| 77 | +- Custom CSS for genuinely novel UI that has no Steam equivalent. |
| 78 | +- Plugins that don't have user-facing settings don't need a settings panel. |
| 79 | + |
| 80 | +### Backend Language Policy |
| 81 | + |
| 82 | +Python backends are no longer accepted. All plugins must use Lua for their backend (`"backendType": "lua"` in `plugin.json`). |
| 83 | + |
| 84 | +- Reject any plugin with `"backendType": "python"` or that ships `.py` files as part of the plugin backend. |
| 85 | +- Python helper scripts used only for development (build scripts, code generation, tooling) are acceptable and should NOT be flagged -- these are not shipped with the plugin. |
| 86 | +- If a PR updates an existing plugin that currently uses Python, it must migrate to Lua. Do not approve Python backend additions or modifications. |
| 87 | + |
| 88 | +### General Quality |
| 89 | + |
| 90 | +- Check that the plugin does what its description claims. |
| 91 | +- Flag dead code, unused imports, and unreachable branches. |
| 92 | +- Note overly complex code that could be simplified. |
| 93 | +- Verify consistent error messaging (user-facing errors should be helpful, not raw stack traces). |
0 commit comments