/ai-fluency-check と入力されたときだけ起動するAIフルーエンシー自己評価スキル。Anthropicの4D AI Fluency Framework(Delegation / Description / Discernment / Diligence)に基づく18項目のルーブリックを使い、対話的に自己評価する。過去の評価記録と比較して成長を可視化し、研究根拠にもとづく改善アドバイスと参考文献を提供する。ユーザーが /ai-fluency-check と明示的に入力した場合のみ使用すること。自動起動・推測起動は一切しない。
substack-quick-fix
Substackの編集画面(Tiptap/ProseMirror)で、指摘済みの誤字脱字などの修正リストをスクリーンショット操作なしで高速に反映するスキル。jp-checkの校正結果をSubstack下書きに適用するときなどに使う。
インストール方法を見る含まれるファイル(1)
- SKILL.md7.0 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Substack Quick Fix
Substackの編集画面はTiptap/ProseMirrorベースのcontenteditableエディタです。修正箇所を1件ずつ「スクリーンショットを撮る→文字を目視で探す→座標をクリック→入力する」というループで直すのは遅く、トークン消費も大きくなります。代わりに、JavaScriptで編集領域のDOMを直接操作し、ブラウザの標準的なテキスト入力コマンドを使って修正を反映します。この方法はProseMirrorの内部状態(トランザクション)ときちんと同期し、Substackの自動保存にも正しく反映されることを実機で検証済みです。
前提条件
- 対象のブラウザタブがSubstackの編集画面(URLが
https://<subdomain>.substack.com/publish/post/<id>の形)であること mcp__claude-in-chrome__javascript_tool(およびナビゲーション確認用にmcp__claude-in-chrome__navigateやmcp__claude-in-chrome__computerのscreenshot)が使えること- 適用したい「誤字→修正後」のペアのリストがあること(jp-checkの校正レポートなど)
手順
1. 編集領域を確認する
まず対象タブで編集領域(contenteditable要素)が存在し、想定した内容を含んでいることを確認する。
const editables = Array.from(document.querySelectorAll('[contenteditable="true"]'));
editables.map(el => ({
tag: el.tagName,
cls: el.className.slice(0, 120),
textLen: el.textContent.length
}));
Substackの本文編集領域は通常 class="tiptap ProseMirror" を持つ div[contenteditable="true"]。これをセレクタ .tiptap.ProseMirror[contenteditable="true"] で取得する。
2. 修正リストを整理する
各修正について、本文中で一意にマッチする検索文字列(search)と置換後の文字列(replace)を用意する。
- 検索文字列は前後の文字を含めて、本文中で1箇所にしか出現しないようにする(例: 単に「点」ではなく「残せる点が魅力」のように文脈を含める)
- 重要: 検索文字列は「1つのテキストノード内」に収まっていなければならない。太字(
<strong>)やリンクなどの書式タグの境界をまたぐ文字列(例: 装飾の終わりと直後のスペースを含む範囲)は同じテキストノードにないことがあり、その場合は置換が失敗する(execCommandがfalseを返す)。- 対処法: 失敗したら、まず対象付近のテキストノード構造を調べる。
const editor = document.querySelector('.tiptap.ProseMirror[contenteditable="true"]'); const walker = document.createTreeWalker(editor, NodeFilter.SHOW_TEXT); let node, all = []; while (node = walker.nextNode()) all.push({text: node.nodeValue, parent: node.parentElement.tagName}); // 対象キーワードを含む/前後のノードを確認し、ノード境界をまたがない範囲に検索文字列を狭める - 境界をまたぐ場合は、修正を「ノードA側の一部を直す操作」と「ノードB側の一部を直す操作」に分割する(例: 前のノード末尾のみ、後ろのノード先頭のみ、といった具合に)。
- 対処法: 失敗したら、まず対象付近のテキストノード構造を調べる。
3. 置換を実行する
以下の関数を使い、修正リストを順番に適用する。1回のJS実行でまとめて処理してよい。
function replaceOnce(root, search, replace) {
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
let node;
while (node = walker.nextNode()) {
const idx = node.nodeValue.indexOf(search);
if (idx !== -1) {
const range = document.createRange();
range.setStart(node, idx);
range.setEnd(node, idx + search.length);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
return document.execCommand('insertText', false, replace);
}
}
return false; // 見つからなかった、またはノード境界をまたいでいる
}
const editor = document.querySelector('.tiptap.ProseMirror[contenteditable="true"]');
editing: editor.focus();
const fixes = [
['誤字を含む一意な文脈', '修正後の一意な文脈'],
// ... 続けて追加
];
const results = fixes.map(([search, replace]) => ({ search, replace, ok: replaceOnce(editor, search, replace) }));
results;
ok: false が返った項目は手順4の方法で個別に調査し、検索文字列を調整して再実行する。
4. 保存とページ内容の検証
Substackは自動保存だが、確実性のためページをリロードして修正が保持されているか確認する。
// リロード後
const editor = document.querySelector('.tiptap.ProseMirror[contenteditable="true"]');
const text = editor.textContent;
// 各修正について「修正後の文字列が含まれる」かつ「誤字が含まれない」ことをチェック
併せて mcp__claude-in-chrome__computer の screenshot アクションで見た目(太字などの書式が壊れていないか)を1回だけ確認する。全箇所を screenshot でいちいち探す必要はない — 検証は最後にまとめて1回でよい。
5. 完了報告
ユーザーには、何件中何件成功したか、失敗があれば原因(ノード境界をまたいだ等)と対応を簡潔に報告する。全文を貼り直す必要はない。
注意点・既知の制約
document.execCommandは非推奨APIだが、2026年時点の主要ブラウザ(Chrome)では引き続き動作し、contenteditable系エディタ(Tiptap/ProseMirror、Slate等)が期待するbeforeinput/inputイベントを正しく発火させるため、DOM直接書き換え(textContent代入など)より信頼性が高い。- この技術はTiptap/ProseMirror系のエディタ全般に応用できるが、編集領域のセレクタ(
.tiptap.ProseMirror[contenteditable="true"])はSubstack向け。他のサービスに使う場合は手順1でセレクタを調べ直すこと。 - 検索文字列が本文中に複数回出現する場合、最初に見つかったノードのみが置換される点に注意(
replaceOnceは最初の一致のみ処理する)。曖昧な場合は前後の文脈を増やして一意にする。 - 記事本文以外(タイトル、Description、タグなど)を編集する場合は、それぞれ別のcontenteditable/input要素になっているため、対象要素を都度確認すること。
レビュー
まだレビューはありません。使ってみた感想をお寄せください。
同じリポジトリのスキル
概要と使いどころ
/coach-me と入力されたときだけ起動する、Learning by Doing コーチングスキル。現在の会話を分析し、Anthropicの4D AIフルーエンシーフレームワーク(Delegation / Description / Discernment / Diligence)に基づいて「うまくできていた点」「改善できる点」「次回に使えるプロンプト例」をフィードバックする。オプションで /coach-me 詳細 または /coach-me --detail と入力すると次元ごとの深掘りフィードバックを提供。自動起動は一切しない。ユーザーが /coach-me と明示的に入力した場合のみ使用すること。
/context-builder と入力されたときだけ起動する、コンテキストドキュメント作成インタビュースキル。人・プロジェクト・プロダクトなどの対象について、1問ずつ掘り下げる対話を通じて情報を集め、今後 Claude との対話の冒頭に貼り付けるための context.md(自分についてなら aboutme.md)を作り上げる。/context-builder me(自分=aboutme)/ project / product のように対象を指定できる。「aboutme を作りたい」「プロジェクトのコンテキストをまとめたい」「プロダクトの前提情報を用意したい」ときに使う。自動起動はせず、ユーザーが /context-builder と明示的に入力した場合のみ使用すること。
セールスレターを書き始める前に、素材(読者・約束・抵抗・証拠・価格や保証などの確定事項)を一問ずつ執拗に聞き出すスキル。「セールスレターについて質問攻めして」「レターを書く前にヒアリングして」「素材を聞き出して」「grillして」、または具体性の乏しいブリーフのままセールスレター執筆を依頼されたときに使う。コピーライティングの「構想メモ」を、書く前に埋めるための対話手順。このスキル自体はレター本文を書かない。
Craft のホワイトボードに Excalidraw 要素を追加・描画するときに必ず使うスキル。 whiteboardElements_add を使う場面、Craft ホワイトボードに図を描く場面、 Excalidraw の JSON を Craft に反映させる場面では常にこのスキルを参照すること。 label 内包記法や cameraUpdate を使うと Craft でテキストが消えるため、 このスキルの互換フォーマットに従う必要がある。
5歳の子どもにもわかるように、要望されたテーマを説明します。ユーザーが /eli5 "テーマ" と入力したとき、または何かの仕組みをとても簡単な図解で説明してほしいと頼んだときに使います