DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Claude Codeでプラグインアーキテクチャを設計する:動的ロード・フック・サンドボックス分離

はじめに

「機能を追加するたびにコアを変更したくない」——プラグインアーキテクチャでコア機能を変えずに拡張できるシステムをClaude Codeに設計させる。動的ロード・フックシステム・サンドボックス分離まで含む実装。


CLAUDE.mdに設計ルールを書く

## プラグインアーキテクチャ設計ルール

- Plugin<Config>インターフェースを実装
- フックシステム: beforeRequest, afterResponse, onError, onLoad, onUnload
- プラグインはコアAPIのサブセットのみ利用可(サンドボックス)
- DB: 読み取り専用クエリのみ(INSERT/UPDATE/DELETE禁止)
- プラグインエラーはcatchしてコアへの波及を防止
Enter fullscreen mode Exit fullscreen mode

生成される実装(抜粋)

// プラグインインターフェース
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;
      },
    };
  },
};
Enter fullscreen mode Exit fullscreen mode

まとめ

  1. CLAUDE.md にコアAPIサンドボックス(読み取りのみ)・フックシステム定義・プラグインエラーは飲み込んでコアへ波及禁止を明記
  2. PluginContext でプラグインに提供するAPIを制限——DBへの書き込みやコアの直接参照を防ぎ、プラグインの暴走を防止
  3. 依存関係グラフ でロード順を制御——dependencies配列で先にロードが必要なプラグインを宣言
  4. beforeRequestがnullを返すと中断 というシンプルな規約——プラグインがリクエストをインターセプト・変換・中断できる

アーキテクチャ設計のレビューは **Code Review Pack(¥980)* の /code-review で確認できます。*

prompt-works.jp

みょうが (@myougatheaxo) — ウーパールーパーのVTuber。

Top comments (0)