0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Codex 用 Plugin を作る `plugin-creator` を徹底解説してみた

0
Posted at

はじめに

Codex 系の開発で Plugin を扱うとき、最初につまずきやすいのが
「最低限どんな構造で作ればよいのか」 です。

たとえば、次のような疑問が出てきます。

  • Plugin のディレクトリはどう切るべきか
  • .codex-plugin/plugin.json には何を書くべきか
  • skills/ hooks/ scripts/ assets/ はいつ作るべきか
  • .mcp.json.app.json はどう扱うべきか
  • marketplace.json にどう登録するべきか
  • Plugin 名の命名規則はどうするべきか

こうした「Plugin を作るときの土台」を、自動で安全に整えてくれるのが今回の plugin-creator です。

このコードは一見すると小さな scaffold ツールです。
ですが、実際にはかなりよく考えられています。

  • Plugin 名の正規化
  • 必須 manifest の生成
  • optional 構造の追加
  • marketplace.json の自動更新
  • 既存データとの衝突回避
  • 規約を壊しにくい CLI 設計

まで、コンパクトにまとまっています。

この記事では、この plugin-creator を題材にして、
コードを読みながら「Plugin をどう設計し、どう生成するのか」をきちんと理解することを目指します。


この記事で分かること

この記事を読み終えると、次のことが分かるようになります。

  • plugin-creator が何を自動化しているのか
  • Codex Plugin の基本構造はどうあるべきか
  • .codex-plugin/plugin.json の役割
  • marketplace.json の役割
  • create_basic_plugin.py の処理の流れ
  • Python で小さな scaffold CLI をどう設計すると読みやすくなるか

対象読者

この記事は、次のような方に向いています。

  • Codex 用 Plugin の基本構造をちゃんと理解したい方
  • plugin.jsonmarketplace.json の違いを整理したい方
  • Python で scaffold ツールを書く実例を見たい方
  • 小さいけれど筋の良い CLI コードを読みたい方
  • Plugin 開発を始めるためのたたき台が欲しい方

まず結論:plugin-creator は何をするツールなのか

一言でいうと、plugin-creator は次のためのツールです。

Codex 用 Plugin のディレクトリ構造と必須 manifest を安全に scaffold するツール

さらにもう少し具体的に言うと、主に次の 3 つを担当しています。


1. Plugin の基本ディレクトリを作る

たとえば、

  • plugins/my-plugin/
  • plugins/my-plugin/.codex-plugin/plugin.json

のような構造を生成します。

ここで重要なのは、.codex-plugin/plugin.json必須として扱われていることです。


2. 必要に応じて optional 構造を作る

必要なら次のようなものも一緒に作れます。

  • skills/
  • hooks/
  • scripts/
  • assets/
  • .mcp.json
  • .app.json

つまり、「最小構成」から「少し本格的な Plugin 構成」まで段階的に作れます。


3. marketplace.json を作成・更新する

Plugin を Codex UI の ordering や availability に出したい場合、
marketplace.json を更新する必要があります。

plugin-creator はここも面倒を見ます。

  • まだ marketplace.json が存在しないなら初期化
  • 既存なら plugins[] にエントリ追加
  • 同名 Plugin があれば --force なしでは上書きしない

という安全な挙動です。


ディレクトリ構成を見てみる

まずは、今回の plugin-creator 自体の構成を見てみます。

plugin-creator/
├── SKILL.md
├── agents/
│   └── openai.yaml
├── assets/
│   ├── plugin-creator-small.svg
│   └── plugin-creator.png
├── references/
│   └── plugin-json-spec.md
└── scripts/
    └── create_basic_plugin.py

この構成だけでも、かなり整理されています。


この構成の役割

SKILL.md

この Skill が何をするのか、どう使うのか、どんなルールがあるのかを書いています。

agents/openai.yaml

UI 用の metadata です。

references/plugin-json-spec.md

plugin.jsonmarketplace.json のサンプル仕様がまとまっています。

scripts/create_basic_plugin.py

今回の主役です。
Plugin scaffold の実処理はこの 1 本に集約されています。


SKILL.md を読むと、この Skill の思想が見える

まず SKILL.md の frontmatter を見ると、こうなっています。

---
name: plugin-creator
description: Create and scaffold plugin directories for Codex with a required `.codex-plugin/plugin.json`, optional plugin folders/files, and baseline placeholders you can edit before publishing or testing. Use when Codex needs to create a new local plugin, add optional plugin structure, or generate or update repo-root `.agents/plugins/marketplace.json` entries for plugin ordering and availability metadata.
---

ここでまず分かるのは、この Skill の対象範囲です。

  • local plugin を作る
  • optional 構造を追加する
  • marketplace.json を作る / 更新する

つまりこの Skill は、
「Plugin の最初の土台を整える」ことに特化しているわけです。


Quick Start がかなり実用的

本文の冒頭では、すぐ使える形で CLI 実行例が示されています。

たとえば最小の作成例はこうです。

python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py <plugin-name>

marketplace.json も作るならこうです。

python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin --with-marketplace

さらに optional 構造まで一気に作るならこうです。

python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin \
  --with-skills --with-hooks --with-scripts --with-assets --with-mcp --with-apps --with-marketplace

これだけでも、使い方がかなり明確です。


plugin-creator が作るものを整理する

SKILL.md に書かれている内容を整理すると、このツールが作るものは次の通りです。


必須で作るもの

必ず作るのはこの 2 つです。

<parent-plugin-directory>/<plugin-name>/
<parent-plugin-directory>/<plugin-name>/.codex-plugin/plugin.json

つまり、.codex-plugin/plugin.json は常に存在させる設計です。

これはとても大事です。

Plugin の本体 manifest がない Plugin は成立しないので、
最初からそこを必須にしているのは正しい判断です。


オプションで作るもの

必要に応じて、次を追加できます。

skills/
hooks/
scripts/
assets/
.mcp.json
.app.json

つまりこのツールは、

  • ただ manifest だけ欲しい最小構成
  • 将来的に Skill や Hook や MCP を持つ構成

の両方に対応できます。


Marketplace エントリも作れる

さらに、--with-marketplace を付けると
marketplace.json 側にもエントリを作れます。

生成されるエントリの形は、概ね次のようになります。

{
  "name": "plugin-name",
  "source": {
    "source": "local",
    "path": "./plugins/plugin-name"
  },
  "policy": {
    "installation": "AVAILABLE",
    "authentication": "ON_INSTALL"
  },
  "category": "Productivity"
}

この形を毎回手で書くのは意外と面倒なので、自動化の価値が高いです。


plugin.jsonmarketplace.json の違いを先に整理しておく

ここは混乱しやすいので、先に整理しておきます。


.codex-plugin/plugin.json とは

これは Plugin 自身の manifest です。

つまり、

  • Plugin 名
  • バージョン
  • 説明
  • author
  • skills / hooks / mcpServers / apps への参照
  • interface 情報

など、Plugin 本体の定義を持っています。


marketplace.json とは

こちらは Plugin 一覧側の定義です。

つまり、

  • どの Plugin が並ぶか
  • どの順番で並ぶか
  • install policy
  • authentication policy
  • category
  • source.path

など、Plugin を UI 側でどう扱うか を持っています。


役割の違いを一言でいうと

  • plugin.jsonPlugin の自己紹介
  • marketplace.jsonPlugin の陳列棚

です。

この 2 つを分けて考えると、かなり理解しやすくなります。


references/plugin-json-spec.md がとても大事

references/plugin-json-spec.md には、plugin.jsonmarketplace.json のサンプル仕様がまとまっています。

たとえば plugin.json のサンプルはこうです。

{
  "name": "plugin-name",
  "version": "1.2.0",
  "description": "Brief plugin description",
  "author": {
    "name": "Author Name",
    "email": "author@example.com",
    "url": "https://github.com/author"
  },
  "homepage": "https://docs.example.com/plugin",
  "repository": "https://github.com/author/plugin",
  "license": "MIT",
  "keywords": ["keyword1", "keyword2"],
  "skills": "./skills/",
  "hooks": "./hooks.json",
  "mcpServers": "./.mcp.json",
  "apps": "./.app.json",
  "interface": {
    "displayName": "Plugin Display Name",
    "shortDescription": "Short description for subtitle",
    "longDescription": "Long description for details page",
    "developerName": "OpenAI",
    "category": "Productivity"
  }
}

これがあることで、create_basic_plugin.py の placeholder 設計がどこから来ているかが分かります。


ここからコードを読む

この plugin-creator の実装の中心は、次の 1 本です。

scripts/create_basic_plugin.py

このファイルは、役割が非常に明確です。

Plugin の scaffold を作り、必要なら marketplace も更新する

では中身を順に見ていきます。


1. 定数定義を見るだけで、ツールの方針が分かる

冒頭には次のような定数があります。

MAX_PLUGIN_NAME_LENGTH = 64
DEFAULT_PLUGIN_PARENT = Path.cwd() / "plugins"
DEFAULT_MARKETPLACE_PATH = Path.cwd() / ".agents" / "plugins" / "marketplace.json"
DEFAULT_INSTALL_POLICY = "AVAILABLE"
DEFAULT_AUTH_POLICY = "ON_INSTALL"
DEFAULT_CATEGORY = "Productivity"
DEFAULT_MARKETPLACE_DISPLAY_NAME = "[TODO: Marketplace Display Name]"
VALID_INSTALL_POLICIES = {"NOT_AVAILABLE", "AVAILABLE", "INSTALLED_BY_DEFAULT"}
VALID_AUTH_POLICIES = {"ON_INSTALL", "ON_USE"}

この定数群から、かなり多くのことが読み取れます。


読み取れる設計方針

Plugin 名は 64 文字以内

長すぎる名前を最初から防ぎます。

デフォルトでは <cwd>/plugins 配下に作る

repo-local plugin を基本にしていることが分かります。

marketplace は <cwd>/.agents/plugins/marketplace.json

repo-root 基準の marketplace を想定しています。

install policy / auth policy / category に default がある

毎回全部を指定しなくても、最低限まともな marketplace entry を作れるようにしています。


2. Plugin 名の正規化がきれい

まず重要なのが normalize_plugin_name() です。

def normalize_plugin_name(plugin_name: str) -> str:
    normalized = plugin_name.strip().lower()
    normalized = re.sub(r"[^a-z0-9]+", "-", normalized)
    normalized = normalized.strip("-")
    normalized = re.sub(r"-{2,}", "-", normalized)
    return normalized

これは skill-creator とよく似た設計です。


何をしているのか

  • 前後の空白を削除
  • 小文字化
  • 英数字以外を - に変換
  • 先頭末尾の - を削除
  • --- のような連続ハイフンを 1 個に圧縮

実際の変換例

normalize_plugin_name("My Plugin")
# "my-plugin"

normalize_plugin_name("My__Plugin!!")
# "my-plugin"

normalize_plugin_name("  Plugin Creator Tool ")
# "plugin-creator-tool"

このように、多少雑な入力でも
規約に沿った kebab-case 名に自動で寄せるようになっています。

CLI ツールとして非常に親切です。


3. validate では「空」と「長すぎる」を止める

続いて validate_plugin_name() です。

def validate_plugin_name(plugin_name: str) -> None:
    if not plugin_name:
        raise ValueError("Plugin name must include at least one letter or digit.")
    if len(plugin_name) > MAX_PLUGIN_NAME_LENGTH:
        raise ValueError(
            f"Plugin name '{plugin_name}' is too long ({len(plugin_name)} characters). "
            f"Maximum is {MAX_PLUGIN_NAME_LENGTH} characters."
        )

ここではシンプルに、

  • 空になっていないか
  • 長すぎないか

を見ています。

重要なのは、
正規化できるものは normalize し、どうしてもダメなものだけ validate で止める
という設計になっていることです。

これはツール設計として非常に良いバランスです。


4. build_plugin_json() は placeholder 付きの manifest を作る

この関数が、生成される .codex-plugin/plugin.json の中身を定義しています。

def build_plugin_json(plugin_name: str) -> dict:
    return {
        "name": plugin_name,
        "version": "[TODO: 1.2.0]",
        "description": "[TODO: Brief plugin description]",
        "author": {
            "name": "[TODO: Author Name]",
            "email": "[TODO: author@example.com]",
            "url": "[TODO: https://github.com/author]",
        },
        ...
    }

ここで大事なのは、空欄ではなく placeholder を入れていることです。


なぜ placeholder が良いのか

もし空文字や空 object だけを入れると、
何を埋めるべきかが分かりにくくなります。

一方でこのコードは、次のようにしています。

{
  "version": "[TODO: 1.2.0]",
  "description": "[TODO: Brief plugin description]"
}

これなら、作ったあとに人が見たとき、

  • 何を埋めるべきか
  • どんな形式が期待されているか

がすぐ分かります。

scaffold ツールとして非常に良い設計です。


interface セクションも最初から全部入れている

plugin.json の中には、interface ブロックも最初から含まれています。

"interface": {
    "displayName": "[TODO: Plugin Display Name]",
    "shortDescription": "[TODO: Short description for subtitle]",
    "longDescription": "[TODO: Long description for details page]",
    "developerName": "[TODO: OpenAI]",
    "category": "[TODO: Productivity]",
    "capabilities": ["[TODO: Interactive]", "[TODO: Write]"],
    ...
}

この設計の良いところは、
「最終的に必要になりそうな形」を最初から見せていることです。

つまり、

  • 最低限の manifest だけ作る
  • でも将来必要になる UI 項目も見える

という状態になります。

これは学習コストを下げます。


5. build_marketplace_entry() は marketplace 側の最小エントリを作る

Plugin 本体とは別に、marketplace entry も生成できます。

その形を定義しているのが build_marketplace_entry() です。

def build_marketplace_entry(
    plugin_name: str,
    install_policy: str,
    auth_policy: str,
    category: str,
) -> dict[str, Any]:
    return {
        "name": plugin_name,
        "source": {
            "source": "local",
            "path": f"./plugins/{plugin_name}",
        },
        "policy": {
            "installation": install_policy,
            "authentication": auth_policy,
        },
        "category": category,
    }

ここが良いのは、marketplace entry の shape を 1 か所に閉じ込めていることです。

もし後で、

  • category を追加で調整したい
  • source の形を変えたい
  • policy を増やしたい

となっても、この関数を見れば済みます。


6. marketplace 初期化の考え方もきれい

marketplace.json が存在しない場合は、
build_default_marketplace() で雛形を作ります。

def build_default_marketplace() -> dict[str, Any]:
    return {
        "name": "[TODO: marketplace-name]",
        "interface": {
            "displayName": DEFAULT_MARKETPLACE_DISPLAY_NAME,
        },
        "plugins": [],
    }

これもとても良いです。


良いポイント

  • いきなり plugins 配列だけではない
  • top-level name も placeholder で用意する
  • interface.displayName も最初から seed する

つまり、marketplace 自体も
「あとでちゃんと育てられる雛形」 として生成しています。


7. update_marketplace_json() がかなり実務的

この関数が、marketplace の更新処理の中心です。

概ね次のような流れです。

def update_marketplace_json(...):
    if marketplace_path.exists():
        payload = load_json(marketplace_path)
    else:
        payload = build_default_marketplace()

    plugins = payload.setdefault("plugins", [])
    new_entry = build_marketplace_entry(...)

    for index, entry in enumerate(plugins):
        if isinstance(entry, dict) and entry.get("name") == plugin_name:
            if not force:
                raise FileExistsError(...)
            plugins[index] = new_entry
            break
    else:
        plugins.append(new_entry)

    write_json(marketplace_path, payload, force=True)

この設計の良いところ

1. marketplace がなければ初期化する

初回実行でも困りません。

2. 既存の plugins[] を保つ

全部書き換えず、対象 plugin だけを見る設計です。

3. 同名 plugin は --force なしでは上書きしない

事故防止になります。

4. 新規なら append

SKILL.md に書かれていた「plugin order は render order」という思想に沿っています。

つまりこの処理は、
安全性と実用性のバランスがよいです。


8. write_json()create_stub_file() の責務分離も良い

ファイル出力系の処理も分かれています。

JSON を確実に上書き / 作成する write_json()

def write_json(path: Path, data: dict, force: bool) -> None:
    if path.exists() and not force:
        raise FileExistsError(f"{path} already exists. Use --force to overwrite.")
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("w") as handle:
        json.dump(data, handle, indent=2)
        handle.write("\n")

これは「必ず書きたい JSON」を扱う関数です。


既存ならそのままにする create_stub_file()

def create_stub_file(path: Path, payload: dict, force: bool) -> None:
    if path.exists() and not force:
        return
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("w") as handle:
        json.dump(payload, handle, indent=2)
        handle.write("\n")

こちらは .mcp.json.app.json のような
optional な stub 向けです。

この分離は地味ですが大事です。

  • plugin.jsonmarketplace.json は厳密に扱う
  • stub は既存なら邪魔しない

という意図が見えます。


9. CLI 設計がかなり分かりやすい

parse_args() もよくできています。

parser.add_argument("plugin_name")
parser.add_argument("--path", default=str(DEFAULT_PLUGIN_PARENT))
parser.add_argument("--with-skills", action="store_true")
parser.add_argument("--with-hooks", action="store_true")
parser.add_argument("--with-scripts", action="store_true")
parser.add_argument("--with-assets", action="store_true")
parser.add_argument("--with-mcp", action="store_true")
parser.add_argument("--with-apps", action="store_true")
parser.add_argument("--with-marketplace", action="store_true")
parser.add_argument("--marketplace-path", default=str(DEFAULT_MARKETPLACE_PATH))
parser.add_argument("--install-policy", default=DEFAULT_INSTALL_POLICY, choices=sorted(VALID_INSTALL_POLICIES))
parser.add_argument("--auth-policy", default=DEFAULT_AUTH_POLICY, choices=sorted(VALID_AUTH_POLICIES))
parser.add_argument("--category", default=DEFAULT_CATEGORY)
parser.add_argument("--force", action="store_true")

使い方が頭の中で自然に組み立てられる

たとえば、これを見るだけで次の実行が想像できます。

最小構成

python3 create_basic_plugin.py my-plugin

skills と assets を付ける

python3 create_basic_plugin.py my-plugin --with-skills --with-assets

marketplace も作る

python3 create_basic_plugin.py my-plugin --with-marketplace

marketplace policy を変える

python3 create_basic_plugin.py my-plugin \
  --with-marketplace \
  --install-policy INSTALLED_BY_DEFAULT \
  --auth-policy ON_USE \
  --category "Developer Tools"

CLI は、読んだ瞬間に使い方が分かることが大事です。
このコードはそこが素直です。


10. main() を読むと、全体の流れが一気につかめる

最後に main() を見ると、このツールの全体像がきれいにまとまっています。

def main() -> None:
    args = parse_args()
    raw_plugin_name = args.plugin_name
    plugin_name = normalize_plugin_name(raw_plugin_name)

    if plugin_name != raw_plugin_name:
        print(f"Note: Normalized plugin name from '{raw_plugin_name}' to '{plugin_name}'.")

    validate_plugin_name(plugin_name)

    plugin_root = (Path(args.path).expanduser().resolve() / plugin_name)
    plugin_root.mkdir(parents=True, exist_ok=True)

    plugin_json_path = plugin_root / ".codex-plugin" / "plugin.json"
    write_json(plugin_json_path, build_plugin_json(plugin_name), args.force)

    ...

この後に、

  • optional directories 作成
  • .mcp.json 作成
  • .app.json 作成
  • marketplace 更新
  • 出力先表示

が続きます。


処理の流れを日本語で言うと

  1. 引数を読む
  2. Plugin 名を正規化する
  3. 妥当性を確認する
  4. Plugin root を作る
  5. .codex-plugin/plugin.json を書く
  6. 必要なら optional directory を作る
  7. 必要なら .mcp.json.app.json を作る
  8. 必要なら marketplace.json を更新する
  9. 最後に作成結果を表示する

この順番が自然なので、コードがとても読みやすいです。


実際に使うとどうなるか

ここで、いくつか具体例を見てみます。


例1: 最小構成の Plugin を作る

python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin

生成イメージ:

plugins/
└── my-plugin/
    └── .codex-plugin/
        └── plugin.json

これは最小構成です。


例2: skills と scripts と assets を持つ Plugin を作る

python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin \
  --with-skills --with-scripts --with-assets

生成イメージ:

plugins/
└── my-plugin/
    ├── .codex-plugin/
    │   └── plugin.json
    ├── skills/
    ├── scripts/
    └── assets/

例3: MCP / App 用 stub も作る

python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin \
  --with-mcp --with-apps

生成イメージ:

plugins/
└── my-plugin/
    ├── .codex-plugin/
    │   └── plugin.json
    ├── .mcp.json
    └── .app.json

例4: marketplace も同時に作る

python3 .agents/skills/plugin-creator/scripts/create_basic_plugin.py my-plugin \
  --with-marketplace

すると、Plugin 本体に加えて、次も更新されます。

.agents/
└── plugins/
    └── marketplace.json

このコード全体の設計が良い理由

ここで、設計の良さを整理します。


1. 最小構成と拡張構成の両方に対応している

  • まずは plugin.json だけ作る
  • 必要なら skills / hooks / scripts / assets を足す
  • さらに marketplace も管理する

この段階性がよいです。


2. 必須 manifest を絶対に外さない

.codex-plugin/plugin.json は常に作られます。

つまり、Plugin として最低限成立する形を必ず保つ設計です。


3. placeholder が教育的

生成される plugin.json は、空白ではなく [TODO: ...] が埋まっています。

これにより、

  • 何を直すべきか
  • どういう形式が期待されるか

が明確になります。


4. marketplace 更新が安全

  • 既存 entry は勝手に壊さない
  • 同名があれば --force を要求
  • 初回なら marketplace を seed する

この安全性は実務上かなり大事です。


5. CLI が素直

引数名がそのまま意味を表していて、初見でも使いやすいです。


改善ポイントもある

かなり良いコードですが、改善の余地もあります。
ここも学びとして大事なので挙げておきます。


1. validator がまだない

skill-creator には quick_validate.py がありましたが、
今回の plugin-creator には validator がありません。

これは少し惜しいです。

たとえば将来的には、次のようなチェックがあると便利です。

  • plugin.json が JSON として正しいか
  • name が plugin folder と一致するか
  • interface.defaultPrompt が 3 件以内か
  • marketplace.json の policy 値が allowed set に入っているか
  • source.path./plugins/<plugin-name> になっているか

2. plugin.json は全部 placeholder なので、実運用前の埋め忘れが起きうる

これは scaffold としては正しいのですが、
そのまま publish してしまう事故は起きえます。

改善案

  • validate_plugin.py を作る
  • [TODO: を含んでいたら warning を出す

3. encoding を明示するとさらに安心

path.open() に encoding 指定がありません。
多くの環境では問題ありませんが、encoding="utf-8" を入れるとさらに堅いです。


4. optional directory の中身は空のまま

これはシンプルで良い反面、初心者には少し不親切かもしれません。

改善案

  • skills/README.md のような軽い説明ファイルを optional で置く
  • あるいは .gitkeep を置く

このコードから学べること

この plugin-creator は、Plugin scaffold の実例であると同時に、
小さな CLI ツールの設計教材としても優秀です。

学べることを整理すると、次の通りです。


1. 正規化と生成をきれいに分ける

  • 名前は normalize する
  • そのあと validate する
  • そのうえで manifest を作る

流れが明確です。


2. scaffold は「空」ではなく「埋め方のヒント」を作るべき

placeholder を丁寧に入れることで、
使う人が次に何をすべきか分かります。


3. optional 構造は flag で足せると使いやすい

--with-skills のように明示的なフラグで足せる設計は、
柔軟で分かりやすいです。


4. marketplace のような共有ファイルは安全に更新するべき

  • append を基本にする
  • 上書きには --force
  • 初回生成にも対応する

この設計は実務的です。


まとめ

plugin-creator は小さなツールですが、かなりよくできています。

このツールの本質は、単に Plugin 用フォルダを作ることではありません。

本当の価値は次の点にあります。

Codex Plugin の基本構造と運用ルールを、コードと scaffold に落とし込んでいること

特に良かった点は、次の通りです。

  • .codex-plugin/plugin.json を必須にしている
  • Plugin 名の正規化がきれい
  • plugin.json の placeholder が教育的
  • optional 構造を flag で足せる
  • marketplace.json を安全に生成 / 更新できる
  • CLI が素直で分かりやすい

一方で、今後の改善余地としては次がありそうです。

  • validator の追加
  • TODO 埋め忘れ検知
  • plugin.json / marketplace.json の妥当性チェック
  • optional directory への軽い説明ファイル追加

とはいえ全体としては、
「最初の一歩をかなり滑らかにしてくれる scaffold ツール」 として、とても良い設計だと思います。


おわりに

Plugin 開発は、最初の 1 回目がいちばん面倒です。

  • どこに置くのか
  • 何が必須なのか
  • manifest をどう書くのか
  • marketplace とどうつなぐのか

この辺りで迷いやすいです。

plugin-creator は、その「最初の面倒」をかなりきれいに吸収してくれます。

しかも単に自動生成するだけでなく、

  • 規約を守りやすくする
  • 何を埋めるべきか分かるようにする
  • 共有ファイルを安全に更新する

という意味で、かなり実務的です。

Codex Plugin をこれから作る方にとってはもちろん、
Python で scaffold CLI を書いてみたい方にも、かなり参考になるコードでした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?