はじめに
「機能を追加するたびにコアを変更したくない」——プラグインアーキテクチャでコア機能を変えずに拡張できるシステムをClaude Codeに設計させる。動的ロード・フックシステム・サンドボックス分離まで含む実装。
CLAUDE.mdに設計ルールを書く
## プラグインアーキテクチャ設計ルール
- Plugin<Config>インターフェースを実装
- フックシステム: beforeRequest, afterResponse, onError, onLoad, onUnload
- プラグインはコアAPIのサブセットのみ利用可(サンドボックス)
- DB: 読み取り専用クエリのみ(INSERT/UPDATE/DELETE禁止)
- プラグインエラーはcatchしてコアへの波及を防止
生成される実装(抜粋)
// プラグインインターフェース
export interface Plugin<Config = {}> {
name: string;
version: string;
dependencies?: string[];
configSchema?: ZodSchema<Config>;
setup(ctx: PluginContext): PluginHooks;
}
// サンドボックスコンテキスト(コアAPIの制限されたサブセット)
private createContext(pluginName, config): PluginContext {
return {
logger: logger.child({ plugin: pluginName }),
cache: {
get: (key) => redis.get(`plugin:${pluginName}:${key}`),
set: (key, value, ttl) => redis.set(`plugin:${pluginName}:${key}`, value, { EX: ttl }),
},
db: {
query: async (sql, params) => {
if (/^\s*(INSERT|UPDATE|DELETE|DROP)/i.test(sql)) throw new Error('Write queries not allowed');
return prisma.$queryRawUnsafe(sql, ...params);
},
},
config,
};
}
// 監査ログプラグインの実装例
const auditLogPlugin: Plugin<{ retentionDays: number }> = {
name: 'audit-log',
setup(ctx) {
return {
afterResponse: async (req, res) => {
if (['POST', 'PUT', 'DELETE'].includes(req.method)) {
await ctx.cache.set(`audit:${req.requestId}`,
JSON.stringify({ method: req.method, userId: req.userId }),
ctx.config.retentionDays * 86400
);
}
return res;
},
};
},
};
// beforeRequestでnullを返すとリクエスト中断
const ipBlockPlugin: Plugin<{ blockedIPs: string[] }> = {
name: 'ip-block',
setup(ctx) {
return {
beforeRequest: async (req) => {
if (ctx.config.blockedIPs.includes(req.ip)) return null; // 中断
return req;
},
};
},
};
まとめ
- CLAUDE.md にコアAPIサンドボックス(読み取りのみ)・フックシステム定義・プラグインエラーは飲み込んでコアへ波及禁止を明記
- PluginContext でプラグインに提供するAPIを制限——DBへの書き込みやコアの直接参照を防ぎ、プラグインの暴走を防止
-
依存関係グラフ でロード順を制御——
dependencies配列で先にロードが必要なプラグインを宣言 - beforeRequestがnullを返すと中断 というシンプルな規約——プラグインがリクエストをインターセプト・変換・中断できる
アーキテクチャ設計のレビューは **Code Review Pack(¥980)* の /code-review で確認できます。*
みょうが (@myougatheaxo) — ウーパールーパーのVTuber。
Top comments (0)