coinagerie-configure について
coinagerie-configureは、coinagerieの単語スキャン設定を記述するスキルです。対象ファイル、除外語、見出し語への統合、用語集の出力先を定義し、厳密な検証とCLIによる一時上書きに対応します。
主な機能
- 01スキャン対象と除外パスの設定
- 02単語を見出し語に統合
- 03MarkdownまたはJSONの用語集出力
- 04設定項目の厳密な検証
- 05CLIフラグによる項目の上書き
活用シーン
- 01フォルダーの用語集生成を設定
- 02言語キーワードやプロジェクト語を除外
- 03複数フォルダーで共通設定を共有
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ organizzolini/ codebase --skill coinagerie-configureインストール後、Claude Code で/coinagerie-configureを入力して読み込まれたか確認します。
詳細
coinagerie 設定ファイルの作成
設定は、coinagerie.config.ts(または .mts、.cts、.js、.mjs、.cjs)でデフォルトエクスポートされる プレーンオブジェクト です。jiti で読み込まれるため、TypeScript が使え、どのフィールドも計算できます。すべてのフィールドは省略可能で、設定ファイルがなくても有効です。その場合、実行時に作業ディレクトリをスキャンして結果を出力します。
スキーマはすべての階層で厳密です。キーのスペルを間違えると無視されるのではなく、ファイル名を示して実行が失敗します。関数のエクスポートは拒否されます。
import { typescriptKeywords } from "@coinagerie/languages";
import type { CoinagerieConfiguration } from "@coinagerie/configuration";
export default {
include: ["src/**", "scripts/**"],
exclude: {
paths: ["**/*.test.ts", "**/generated/**", "coinagerie.config.ts"],
words: [...typescriptKeywords, "src", "index"],
},
fold: (word) => (word === "configuration" ? "configure" : word),
outputs: [
{
description: "Words this project uses. Regenerate with `coinagerie --write`.",
path: "README.md",
type: "markdown",
},
],
} satisfies CoinagerieConfiguration;
型のインポートは省略可能で、読み込み時に消去されます。@coinagerie/languages は設定ファイルと同じ場所にインストールする必要があります。インポートを解決できない場合、「Cannot find module」として実行が失敗します。
フォルダーがルートです
すべてのパスとグロブは、設定ファイルが置かれているフォルダーを基準とします。このフォルダーは、実行時にスキャンされるルートでもあります。共有ベースに記述されたパスは、ベースのフォルダーではなく、読み込まれた設定ファイルのフォルダーを基準に解決されます。
includeは、ドットファイルも含め、デフォルトですべてのファイルを対象にします。グロブの照合にはpath.matchesGlobが使われます。*と**は、ドットで始まる名前には決して一致しません。そのため、カスタムのincludeでは.github/**などを明示的に指定する必要があります。exclude.pathsにはグロブを指定します。フォルダーに一致するグロブは、フォルダー全体を除外します。グロブはスキャン対象のフォルダーを基準に照合されるため、["dist"]で除外されるのはトップレベルのdistのみです。階層を問わず除外するには**/distと記述してください。.gitignoreは上記の両方に加えて適用されます。リポジトリルート(.gitを含む最も近い祖先)から順に適用され、否定パターンも反映されます。- 用語集の出力先はスキャンされませんが、設定ファイルはスキャンされます。設定ファイル内のキー自体が単語として扱われます。パスで除外するか、そのまま許容してください。
exclude.words
単語のリスト、または単語のリストを返す同期関数または非同期関数です。設定で別のファイル、親の用語集、JSON ファイルを読み込む場合は、この関数を使います。coinagerie はそれ自体では別の用語集を読み込まないためです。
import { readFile } from "node:fs/promises";
import path from "node:path";
const parentWords = async (): Promise<string[]> =>
Object.keys(
JSON.parse(await readFile(path.join(__dirname, "../glossary.json"), "utf8")),
);
export default { exclude: { words: parentWords } };
- デフォルトでは、言語のキーワードも含め、何も除外されません。
@coinagerie/languagesがエクスポートするリストをプレーン配列として展開してください。typescriptKeywords、pythonKeywords、sqlKeywords、shellKeywords、cssKeywords、hclKeywords、tomlKeywords、jsonKeywords、yamlKeywordsがあります。 - 除外は 折りたたみ処理の後 に行われます。各項目は小文字に変換され、コード内の単語と同じ方法で折りたたまれます。
serviceを除外するとservicesも対象になり、implementsを除外すると、それが折りたたまれるimplementも対象になります。 - 各項目は1つの単語です。分割されることはないため、
"fooBar"でfooやbarが除外されることはありません。それぞれをリストに追加してください。 - 除外された単語は用語集から削除され、次の
--writeでその定義も削除されます。単語自体に意味がない場合に除外してください。定義が欠けているという理由で除外しないでください。
fold
fold(word) => headword は、レマタイザーが分けたままにした単語をまとめたり、誤った見出し語を修正したりします。複数形や語形変化の折りたたみ処理の後に実行されるため、受け取るのはレマです。その結果が最終的な見出し語になります。
fold: (word) =>
({ configuration: "configure", set: "setting" })[word] ?? word,
同期処理で、空白や * を含まない空でない文字列を返す必要があります。例外の発生、空または文字列以外の結果、Promise の返却があった場合は、設定ファイル名を示して実行が失敗します。
出力
出力先の配列です。出力先がない場合、実行時には結果が表示されるだけで、--check と
--write は実行できません。
| 出力先 | 内容 |
|---|---|
{ type: "markdown", path, description? } | coinagerie:start と coinagerie:end のアンカー間のブロック |
{ type: "json", path } | 単語順に並べたフラットオブジェクト形式のファイル全体 |
- Markdown ファイルが存在しない場合は作成され、アンカーがまだない場合は末尾にブロックが追加されます。そのため、セクションを追加する場合は README を指定するか、専用ファイルを指定してください。
descriptionは見出しの下に置く自由形式の文章です。箇条書きとして解析されるため、リスト項目(-、*、+)や HTML コメント行を含めることはできません。設定しない場合は、最初の箇条書きより前にある文章がそのまま残ります。- 1 つのファイルに 2 つの出力先を指定することはできません。
- 出力先はそれぞれ独立して判定されます。JSON と Markdown の用語集の間で定義がコピーされることはないため、スコープごとに正規の出力先を 1 つ指定してください。
複数のフォルダーで 1 つのベースを共有する
共通の設定を 1 つのモジュールにまとめて展開し、各フォルダーのファイルでは異なる設定だけを追加します。展開は浅いため、exclude を上書きすると全体が置き換わります。
import base from "../coinagerie.base";
export default {
...base,
exclude: { ...base.exclude, paths: [...(base.exclude?.paths ?? []), "fixtures"] },
outputs: [{ path: "README.md", type: "markdown" }],
};
フォルダーの exclude.words が親の用語集を参照する場合、子で定義する必要のない語は親が決めます。親から語が削除されると、それを除外していたすべての子で未定義に戻るため、その定義を子に移す変更は意図的に行う必要があります。Nx を使う場合は、各子のターゲットの入力として親の用語集を宣言してください。そうしないと、親の用語集を変更しても子のチェックは再実行されません。
編集前に試す
exclude.words と fold を除くすべてのフィールドには、1 回の実行でその値を置き換えるコマンドラインフラグがあります:--include、--exclude-paths、--output-json、--output-markdown、--description。一覧は
coinagerie-collect スキルにあります。引数なしで coinagerie を実行すると、変更結果が表示されますが、何も書き込まれません。
実行時に設定が拒否された場合
| 症状 | 原因と対処 |
|---|---|
expected object, received function | ファイルが関数をエクスポートしています。プレーンなオブジェクトをエクスポートしてください |
Unrecognized key: "<name>" | フィールド名の誤り、または配置場所が間違っています。キーを修正してください |
Invalid input at exclude.words | リストまたは関数以外が指定されています |
fold must return a non-empty string... | 関数が ""、空白、*、Promise、または文字列以外を返しました |
exclude.words boom | 関数が例外をスローしました。エラーには設定ファイルのパスが含まれます |
Cannot find module | 設定ファイルと同じ場所にパッケージをインストールしてください |
Two outputs name a.json | 出力先ごとに別のファイルを指定してください |
A description may not hold a list item... | description に -、*、+、または <!-- の行があります。表現を変更してください |
fold threw on "<word>" | fold 関数が例外をスローしました。その単語に対する処理を修正してください |
Configuration file not found | 指定した --config は作業ディレクトリからの相対パスです |
設定が拒否されたのではなくチェックに失敗した場合の対処については、
coinagerie-triage スキルを参照してください。