원클릭으로
rule-validator
Validate code compliance with Gemini mod rules (core, modules, features, UI, WebSocket, state)
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Validate code compliance with Gemini mod rules (core, modules, features, UI, WebSocket, state)
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Create a new card part within a section with factory/class pattern, Card wrapper, and proper cleanup
Add a new Jotai atom to the state system with type definitions, registry, and Store API access
Create a reusable UI component with factory pattern, theme compatibility, and proper cleanup
Scaffold a new toggleable feature with full structure, storage, API exposure, and bootstrap registration
Create a reactive global variable that derives from atoms with subscription support
Create a game UI injection that modifies existing game elements with proper cleanup
| name | rule-validator |
| description | Validate code compliance with Gemini mod rules (core, modules, features, UI, WebSocket, state) |
| aliases | ["validate","check-rules","lint-rules"] |
When you want to validate code compliance:
/rule-validator src/features/myFeature
/rule-validator <file-or-folder>
/validate # Validate current selection
Applies to all code in the repo.
Forbidden patterns:
'Carrot', 'Tomato', etc.Check for:
// ❌ BAD
const plantName = 'Carrot';
const itemId = 42;
const spriteName = 'plant_carrot_lvl1';
// ✅ GOOD
const plant = MGData.get('plants')['carrot'];
const item = MGData.get('items')[itemId];
const sprite = await MGSprite.show('plant', plantName);
What to report:
Forbidden:
src/ui/websocket.send() outside src/websocket/api.ts)window.myGlobal = ... as second source of truth)Check for:
// ❌ BAD - in src/features/myFeature/index.ts
document.createElement('div'); // DOM in features
websocket.send(message); // Direct WS send
window.myState = value; // Ad-hoc global
atom.value = newValue; // Direct mutation
// ✅ GOOD
// In src/ui/components/...
const root = document.createElement('div');
// In src/websocket/api.ts
export function sendAction(...) { websocket.send(...) }
// In src/features/...
const unsub = await Store.subscribe('myAtom', callback);
What to report:
Forbidden on import:
Check for:
// ❌ BAD - at module level
window.addEventListener('click', handler); // No cleanup
setInterval(() => {...}, 1000); // Runs forever
const unsub = Store.subscribe(...); // Unsub lost
// ✅ GOOD
let unsub: (() => void) | null = null;
export function init() {
window.addEventListener('click', handler);
unsub = () => window.removeEventListener('click', handler);
}
export function destroy() {
unsub?.();
unsub = null;
}
What to report:
Forbidden:
GM_getValue/GM_setValue callsCheck for:
// ❌ BAD
GM_setValue('myKey', value);
const key = 'random-key';
// ✅ GOOD
import { KEYS } from 'src/utils/storage';
GM_setValue(KEYS.MY_FEATURE, value); // Prefixed with gemini:
What to report:
Check for:
What to report:
any)Forbidden:
any type usageCheck for:
// ❌ BAD
function handle(data: any) {}
// ✅ GOOD
function handle(data: unknown) {
if (typeof data === 'object' && data !== null) { ... }
}
What to report:
any usageunknown + type narrowing"Expected files:
src/features/myFeature/
├── types.ts # ✅ Required
├── index.ts # ✅ Required
├── state.ts # ⚠️ If persistent state
├── ui.ts # ⚠️ If visual elements
├── middleware.ts # ⚠️ If WS outgoing
├── handler.ts # ⚠️ If WS incoming
└── logic/ # 📁 Recommended
├── core.ts
└── helpers.ts
Check for:
types.ts or index.tsenabled: booleanCheck in src/features/index.ts:
// ✅ GOOD
export { MGMyFeature } from './myFeature';
export type { MyFeatureConfig } from './myFeature';
Check in src/api/index.ts:
// ✅ GOOD
Features: {
MyFeature: MGMyFeature,
}
Check in src/ui/loader/bootstrap.ts:
// ✅ GOOD
{ name: "MyFeature", init: MGMyFeature.init.bind(MGMyFeature) }
What to report:
Modules MUST:
Check for:
enabled config (should be modules, not features)Check for factory violations:
// ❌ BAD
export function MyButton() { return <JSX>... }
// ✅ GOOD
export interface Options { label: string; onClick?: () => void }
export interface Handle { root: HTMLElement; destroy(): void }
export function create(options: Options): Handle { ... }
What to report:
Check for:
Check locations:
protocol.tsconnection.tsapi.tshandlers/middlewares/What to report:
Check for:
// ❌ BAD
if (type === 'plant_action') { ... }
// ✅ GOOD
import { WS_TYPES } from './protocol';
if (type === WS_TYPES.PLANT_ACTION) { ... }
When violations are found, report as:
🚨 RULE VIOLATIONS FOUND (Gemini Mod)
[File: src/features/myFeature/index.ts]
├─ ❌ Rule 1: Hardcoded Game Data (line 42)
│ └─ Found: const plantName = 'Carrot'
│ └─ Fix: Use MGData.get('plants')['carrot']
│
├─ ⚠️ Rule 5: Code Quality (lines: 312)
│ └─ File exceeds 500 lines (actual: 612)
│ └─ Suggestion: Split by responsibility
│
└─ ❌ Rule 2: Boundaries (line 89)
└─ Found: Direct WebSocket send
└─ Fix: Use websocket/api.ts actions instead
✅ PASSED CHECKS:
├─ Feature structure (types.ts, index.ts present)
├─ Storage keys namespaced correctly
├─ TypeScript strict (no `any` found)
└─ Side effect cleanup present
📋 SUMMARY: 3 violations, 4 checks passed
💡 Next steps: Review suggested fixes above
/rule-validator src/ # Validate entire src/
/rule-validator dist/ # Skip dist builds
/rule-validator src/features/newFeature
/rule-validator src/ui/components/NewComponent
/rule-validator . # Entire project
Can skip certain paths:
dist/ — Build outputnode_modules/ — DependenciesGameSourceFiles/ — Reference onlyGameFilesExample/ — Examples only| Detection | Reality | Action |
|---|---|---|
'Carrot' in comment | Actually just documentation | Ignore |
any in test file | Test-only, acceptable | Allow |
| 600-line file | Truly complex, can't split | Document why |
| WS send in tests | Mock data, OK | Allow |
When reporting: Flag but don't block if edge case is justified.
any)When you /clear before starting a new task:
/rule-validator src/ # Run full validation
→ Fix any violations
→ Commit with pre-commit-gate skill
→ Proceed with clean slate
This ensures you never accumulate debt across task boundaries.