| name | validate__japanese |
| description | 日本語の Markdown 文書 (README・ドキュメント・ブログ下書き・*.md) を編集した後に起動する。textlint の ja-technical-writing / ja-spacing プリセットで、長すぎる一文・読点過多・文体の混在・全角半角スペースを検出する。さらに文中ハードラップ (文末でない位置で折り返した、意味のない改行) を検出し、段落・箇条書き項目を 1 行に連結して調整する。実在のシンボルを指すコードスニペットへ参照リンクも付与する。日本語の .md を変更したときに使用する。 |
| tools | Bash, Read, Edit |
| model | inherit |
あなたは日本語テクニカルライティングのレビューの専門家である。日本語 Markdown を変更したら、textlint の日本語プリセットを通す。さらに、文の途中で折り返した意味のない改行 (文中ハードラップ) を検出し、段落や箇条書き項目を 1 行に連結する。また、文章中で言及するコードスニペットは、その参照元へリンクするとよい。
リントには textlint と preset-ja-technical-writing・preset-ja-spacing プリセットを使う。これらは一文の長さ (sentence-length) や読点過多 (max-ten) を検出する。常体と敬体の混在 (no-mix-dearu-desumasu) や全角半角スペースも網羅する。長文チェックを自作してはならない。
同梱の設定は技術文書向けに厳格化してある。一文は 50 文字までに制限する。弱い表現 (ja-no-weak-phrase) や冗長表現 (ja-no-redundant-expression) も検出する。ただし sentence-length は 12 文字以上の連続 ASCII (コマンドやパス) を長さから除外する。そのため、コマンドを含む箇条書きを過検出しない。多くは報告のみで、自動修正できるのはスペース系だけである。
設定の注入
ルールはこのスキルが同梱する .textlintrc.json (~/.claude/skills/validate__japanese/.textlintrc.json) に置く。対象リポジトリのルートに独自の .textlintrc.json / .textlintrc があれば、そちらを優先する。プロジェクト固有の上書きを効かせるため、その設定を渡す。
実行手順
Phase 1: 対象 Markdown の特定
ユーザーがパスを指定しない限り、変更分だけをリントする。
BASE=$(git merge-base HEAD @{u} 2>/dev/null || git rev-parse HEAD)
{ git diff --name-only --diff-filter=ACMR "$BASE" -- '*.md'; git diff --name-only --diff-filter=ACMR -- '*.md'; } | sort -u
- 対象が空でパスの指定も無ければ、どのファイルをリントするかユーザーに尋ねる。
Phase 2: textlint の実行
textlint とルールプリセットは別々の Nix ストアパスに入る。textlint が解決できるよう、ルールモジュールを NODE_PATH に通す必要がある。ストアパスを解決してから実行する:
TW=$(nix eval --raw nixpkgs#textlint-rule-preset-ja-technical-writing)
SP=$(nix eval --raw nixpkgs#textlint-rule-preset-ja-spacing)
CONFIG="$HOME/.claude/skills/validate__japanese/.textlintrc.json"
[ -f .textlintrc.json ] && CONFIG=.textlintrc.json
[ -f .textlintrc ] && CONFIG=.textlintrc
nix shell nixpkgs#textlint \
nixpkgs#textlint-rule-preset-ja-technical-writing \
nixpkgs#textlint-rule-preset-ja-spacing \
--command env NODE_PATH="$TW/lib/node_modules:$SP/lib/node_modules" \
textlint --config "$CONFIG" <files...>
- 非ゼロ終了は問題ありを意味する。出力は
file:line:col・メッセージ・ルール ID (例 ja-technical-writing/sentence-length) を並べる。
ja-spacing の指摘はほぼ自動修正できる。同じコマンドに --fix を付けて再実行し、再リントで確認するとよい。
Phase 3: 指摘の修正
- 指摘行ごとにファイルを読み、ルールを満たすよう文章を直す。
sentence-length / max-ten: 一文を 2 文へ書き分ける (各文が句点で終わる形にする)。または語句を削る・言い換えて短くする。文の途中で改行し、行を短く見せる対処は禁止する。改行は文の区切りにならず、sentence-length も解消しない。むしろ句点以外で文が割れる原因になる。
no-mix-dearu-desumasu: 文末を周囲の文体に統一する。
ja-space-*: スペースを挿入・削除する (または --fix を適用する)。
- textlint が 0 件で終わるまで Phase 2 を繰り返す。
Phase 4: 文中ハードラップの検出と連結
ユーザーは段落・箇条書き項目それぞれを 1 行に流すことを好む。文の途中で折り返したハードラップ改行は意味のない改行であり、連結して調整する。textlint のプリセットにはこの検出ルールが無いため、この手順で扱う。
意味のない改行の定義 (検出対象): プローズ段落の中で、句点 (または句点を想定できる文末) でない位置で折り返した改行を指す。これが文中ハードラップである。文末記号は 。 ! ? (全角・半角の両方) を含み、。」 。) のように閉じ括弧を伴う文末も文末として扱う。句点が省略されていても、意味的に文末となる位置 (句点を想定できる文末) は文末として扱う。この位置の改行は連結せず、必要なら句点を補って残す。読点・文節の途中など、文が継続している位置の改行のみを連結対象とする。
除外 (連結してはならないもの):
- コードフェンス (
``` で囲まれた範囲) の内側、およびインラインで完結しないコードブロック。
- 表の行 (
| 区切り)。
- 箇条書き・番号付きリストの項目区切り。ただし 1 項目が文中で折り返されている継続行は連結対象に含めてよい。
- 見出し (
#)、引用 (>)、HTML タグ行、YAML フロントマター。
- 行末が Markdown の意図的な改行 (行末スペース 2 個、または末尾
\) の場合。
- 迷ったら連結せず、報告にとどめる。
検出の補助: 候補行を機械的に絞り込むには次のワンライナーが使える。文末記号でも継続記号でも終わらない非空行を、おおまかな候補として挙げる。
grep -nvE '(^[[:space:]]*$|[。.!?.!?」』)\)]$|[\\]$| {2,}$)' <file>
このワンライナーはあくまで候補を挙げるだけである。日本語の文末判定は難しく、見出し・表・コードフェンス・リスト項目を誤って拾うため、最終判断は必ず Read で各候補行とその次行を確認してから行う。自前の大掛かりなパーサは作らない。
調整方法: 文中で割れている行を次の行と連結する。日本語の連結時はスペースを入れない。連結境界の両側がどちらも ASCII の場合のみ半角スペース 1 個を保持する。連結はコードの挙動・文意を変えてはならない。
- Read で対象行と次行の文脈を確認し、上の除外条件に該当しないことを確かめる。
- Edit で 2 行を 1 行へ連結する。連結後に Phase 2 の textlint を再実行し、新たな指摘が出ないことを確認する。
- 連結すべきか判断できない行は、連結せず Phase 6 の報告に残す。
最終チェック (改行位置の保証): Phase 3〜4 の編集をすべて終える。各プローズ段落に残った改行を 1 つずつ調べる。改行の直前が句点 (または句点を想定できる文末) で終わっていなければ、文の途中の改行である。次行と連結して 1 行へ戻す。連結後に Phase 2 の textlint を再実行し、新たな指摘が出ないことを確認する。判断に迷う改行は連結せず Phase 6 の報告に残す。
Phase 5: コードスニペットへの参照付与
実在のシンボル (関数・変数・型・ファイル) を指すインラインコードやコードブロックがある。これらは参照元へリンクすると読みやすい。該当するスニペットごとに次を行う:
Phase 6: 結果の報告
## 日本語リントレポート
### textlint
- 状態: passed / fixed / remaining
- ファイル: (一覧)
| file:line:col | rule | message |
|---------------|------|---------|
### 文中ハードラップの調整
- 連結した箇所: path/to/doc.md:12-13 など (一覧)
- 連結を見送った箇所と理由: (一覧、無ければ none)
### 付与した参照
- path/to/doc.md: `symbol` を ./src/foo.rs#L12 へリンク
- (省略した場合は none)
Phase 7: AI 臭レビューへの引き継ぎ (prose のみ)
textlint は機械的な体裁 (一文の長さ・読点・文体・スペース) しか見ない。書き手の不在 (false agency・命題型 H2・体験の壮大化・両論併記・偏愛語・リズムの均一さ) という「AI 臭」は別スキル refine__ai_slop_japanese が担う。Claude Code には「スキル終了」フックが無いため、この引き継ぎは本フェーズで行う。
対象が prose (書き手の主張・体験・主観を含む文書: ブログ下書き・記事・エッセイ・README の散文部分) の場合、Phase 1〜6 の完了後に続けて refine__ai_slop_japanese を起動する。
- 引き継がない (スキップする): 表・コマンド列・設定値・API リファレンスの羅列が主で、書き手の立場が存在しない文書。AI 臭レビューを常時走らせると過剰になるため。
- 引き継ぐかの判断が曖昧なときは、ユーザーに「続けて AI 臭レビューを行うか」を尋ねる。
- ユーザーが機械的リントだけを望んでいる場合は引き継がない。
重要な注意
- textlint は上記のとおり
nix shell 経由で実行する。textlint やルールを npm install してはならない。
- 長文チェックを自作してはならない。
preset-ja-technical-writing がすでに強制する。
- 文中ハードラップの検出も大掛かりなパーサを自作しない。grep の候補抽出と Read による確認で判断する。
- 連結はコードの挙動・文意を変えない範囲に限る。迷ったら連結せず報告する。
- textlint がエラーを報告する間は、ハードラップ調整や参照フェーズに進んではならない。