Claude-skill-registry add-module
Create a new core infrastructure module with standard API, lazy init, and proper structure
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/add-module" ~/.claude/skills/majiayu000-claude-skill-registry-add-module && rm -rf "$T"
manifest:
skills/data/add-module/SKILL.mdsource content
Add Module Skill
Usage
/add-module <ModuleName>
Note: Modules are core infrastructure (always-on). For toggleable functionality, use
/add-feature instead.
Step 1: Ask Questions
1. Module Purpose
What infrastructure does this module provide? Brief description:
2. Data Source
Where does the module get its data? A) Game runtime - Hooks into game code B) Network - Captures WebSocket/HTTP C) Assets - Game assets (sprites, audio, etc.) D) Computed - Derives from other modules E) Other: ___
3. Dependencies
Which existing modules does it depend on? [ ] MGData [ ] MGSprite [ ] MGTile [ ] MGPixi [ ] MGAudio [ ] MGCosmetic [ ] MGVersion [ ] MGAssets [ ] MGManifest [ ] MGEnvironment [ ] MGCalculators [ ] None
4. State Type
Does it need runtime state? A) Yes - Caches data in memory (needs state.ts) B) No - Stateless utilities only
5. Public API Methods
What methods should the module expose? (Besides required init/isReady) Examples: - get(key) - Get data by key - calculate(params) - Perform calculation - render(target) - Render something
Step 2: Create Structure
src/modules/<moduleName>/ ├── index.ts # Public façade (MG<ModuleName>) ├── types.ts # Type definitions ├── state.ts # Runtime state (if needed) └── logic/ └── core.ts # Business logic
No
- Import directly from logic files.logic/index.ts
Step 3: File Templates
types.ts
/** * <ModuleName> Module Types */ // ───────────────────────────────────────────────────────────────────────────── // Types // ───────────────────────────────────────────────────────────────────────────── export interface <ModuleName>Data { // Define data structures } // ───────────────────────────────────────────────────────────────────────────── // Constants // ───────────────────────────────────────────────────────────────────────────── export const <MODULE_NAME>_CONSTANTS = { // Define constants } as const;
state.ts (if needed)
/** * <ModuleName> Module State * * Runtime cache/state management. */ import type { <ModuleName>Data } from './types'; // ───────────────────────────────────────────────────────────────────────────── // State // ───────────────────────────────────────────────────────────────────────────── let cache: <ModuleName>Data | null = null; let ready = false; // ───────────────────────────────────────────────────────────────────────────── // Accessors // ───────────────────────────────────────────────────────────────────────────── export function getCache(): <ModuleName>Data | null { return cache; } export function setCache(data: <ModuleName>Data): void { cache = data; ready = true; } export function isReady(): boolean { return ready; } export function reset(): void { cache = null; ready = false; }
logic/core.ts
/** * <ModuleName> Core Logic */ import { setCache, getCache } from '../state'; import type { <ModuleName>Data } from '../types'; // ───────────────────────────────────────────────────────────────────────────── // Initialization // ───────────────────────────────────────────────────────────────────────────── export async function initialize(): Promise<void> { // Initialization logic // Capture data, setup hooks, etc. const data: <ModuleName>Data = { // ... }; setCache(data); } // ───────────────────────────────────────────────────────────────────────────── // Public Methods // ───────────────────────────────────────────────────────────────────────────── export function getData(): <ModuleName>Data | null { return getCache(); }
index.ts
/** * <ModuleName> Module * * <Brief description> * * @example * ```typescript * await MG<ModuleName>.init(); * const data = MG<ModuleName>.get(); * ``` */ import { initialize, getData } from './logic/core'; import { isReady as checkReady } from './state'; // ───────────────────────────────────────────────────────────────────────────── // State // ───────────────────────────────────────────────────────────────────────────── let initialized = false; // ───────────────────────────────────────────────────────────────────────────── // Public API // ───────────────────────────────────────────────────────────────────────────── /** * Initialize the module * Idempotent - safe to call multiple times */ async function init(): Promise<void> { if (initialized) return; initialized = true; await initialize(); console.log('[<ModuleName>] Initialized'); } /** * Check if module is ready */ function isReady(): boolean { return checkReady(); } /** * Get module data */ function get() { return getData(); } // ───────────────────────────────────────────────────────────────────────────── // Export // ───────────────────────────────────────────────────────────────────────────── export const MG<ModuleName> = { // Required (standard API) init, isReady, // Module-specific get, // Add other public methods }; export type { <ModuleName>Data } from './types';
Step 4: Register
Export → src/modules/index.ts
src/modules/index.tsexport { MG<ModuleName> } from './<moduleName>'; export type { <ModuleName>Data } from './<moduleName>';
API → src/api/index.ts
src/api/index.tsimport { MG<ModuleName> } from '../modules/<moduleName>'; Modules: { // ... existing <ModuleName>: MG<ModuleName>, }
Bootstrap → src/ui/loader/bootstrap.ts
src/ui/loader/bootstrap.tsimport { MG<ModuleName> } from '../../modules/<moduleName>'; // In initModules(): await MG<ModuleName>.init();
Step 5: Validate
Structure
-
exportsindex.tsMG<ModuleName> -
defines types/constantstypes.ts -
exists (if stateful)state.ts -
folder for business logiclogic/ - No
barrel filelogic/index.ts
API
-
- Required, idempotentinit() -
- Required, returns booleanisReady() - Other methods are module-specific
Rules
- No toggles (modules are always-on)
- No UI rendering (DOM in src/ui/ only)
- No direct WS sends (use websocket/api.ts)
- No side effects on import
Registration
- Exported from
src/modules/index.ts - Exposed in
src/api/index.ts - Initialized in bootstrap
Module vs Feature
| Aspect | Module | Feature |
|---|---|---|
| Toggle | Always on | |
| Location | | |
| Purpose | Infrastructure | Enhancement |
| API | | |
| Storage | (rare) | |
References
- Rules:
.claude/rules/modules.md - Existing modules:
src/modules/*/