docx-processing-lawvable について
SuperDoc 拡張機能を使い、VS Code で DOCX を編集するスキルです。変更をライブプレビューで確認でき、変更履歴やコメントを扱う文書作業に適しています。
主な機能
- 01テキスト、HTML、文書構造の取得
- 02変更履歴付きの検索と置換
- 03テキスト、表、コメントの挿入
- 04テキストと段落の書式設定
- 05リンク付き目次の作成
活用シーン
- 01契約書のプレースホルダーを変更履歴付きで置換
- 02段落、表、レビューコメントの追加
- 03DOCX の段落と表の構造確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lawve-ai/ awesome-legal-skills --skill docx-processing-lawvableインストール後、Claude Code で/docx-processing-lawvableを入力して読み込まれたか確認します。
同梱ファイルLICENSE.txt
詳細
DOCX ライブエディター
SuperDoc extension を使って、VS Code で Word ドキュメントをライブプレビューしながら編集し、変更履歴を記録できます。
仕組み
- カスタムコマンドを
path/to/.superdoc/{docname}.jsonに書き込みます - 拡張機能がコマンドを実行し、ファイルを応答で上書きします
- 変更内容が SuperDoc のウェブビューにリアルタイムで表示されます。
状態: "command" フィールド = 保留中 | "success" フィールド = 応答の準備完了
前提条件
-
SuperDoc 拡張機能がインストールされていること。 次のコマンドで確認します。
code --profile "Lawvable" --list-extensions | grep -i superdoc -
編集する前に、VS Code でドキュメントを開いておく必要があります。
code --profile "Lawvable" path/to/doc.docx -
新しい空のドキュメントを作成する:
code --open-url "vscode://superdoc.superdoc-vscode-extension/create?path=./new-document.docx"パスには相対パスまたは絶対パスを指定できます。
.docx拡張子がない場合は、自動的に追加されます。
code コマンドが見つからない場合: 代わりにフルパス /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code を使用してください。
ファイル構成
.superdoc/ フォルダーは、DOCX ファイルと同じディレクトリに置く必要があります。JSON ファイルには、DOCX ファイルと同じベース名を使用します。
project/
├── contract.docx ← document at root
├── .superdoc/
│ └── contract.json ← commands for contract.docx
└── subfolder/
├── report.docx ← document in subfolder
└── .superdoc/
└── report.json ← commands for subfolder/report.docx
ワークフロー
重要なルール:
- 前のコマンドから
{"success": ...}を受け取るまで、次のコマンドを絶対に送信しないでください - 結果ではなく生のコマンド JSON が応答に表示された場合、ドキュメントはアクティブではありません。まず再度開いてください
コマンドのパターン
コマンドを書き込み、応答に "success" が含まれるまでポーリングしてから読み取ります。
echo '{"command":"...","args":{...}}' > path/to/.superdoc/doc.json && until grep -q '"success"' path/to/.superdoc/doc.json; do sleep 0.1; done && cat path/to/.superdoc/doc.json
ステップ 1:作成者を確認する(セッションごとに 1 回)
編集を行う前に、必ず AskUserQuestion を使って、変更の作成者としてユーザーとエージェントのどちらを記録するかを尋ねてください。ユーザーの名前を使う場合は、すべての replaceText、insertContent、insertTable、addComment コマンドに "author":{"name":"Their Name"} を指定してください。
ステップ 2:最初に読み取る(ドキュメントがアクティブであることを確認)
mkdir -p path/to/.superdoc && echo '{"command":"getText","args":{"format":"text"}}' > path/to/.superdoc/doc.json && until grep -q '"success"' path/to/.superdoc/doc.json; do sleep 0.1; done && cat path/to/.superdoc/doc.json
ドキュメントがアクティブかどうかを確認する: 応答には必ず {"success": true, "result": ...} が含まれていなければなりません。次の表示がある場合:
- 生のコマンド JSON が返された → ドキュメントが開いていません。
code --profile "Lawvable" path/to/doc.docxで再度開いてください {"success": false, "error": "No active editor"}→ ドキュメントにフォーカスがありません。再度開いてください
ドキュメントの内容を含む成功応答を受け取るまで、ステップ 3 に進まないでください。
ステップ 3:編集する
echo '{"command":"replaceText","args":{"search":"2024","replacement":"2025"}}' > path/to/.superdoc/doc.json && until grep -q '"success"' path/to/.superdoc/doc.json; do sleep 0.1; done && cat path/to/.superdoc/doc.json
ステップ 4:応答を信頼する
getText を使って編集内容を再確認しないでください。 コマンドの応答 {"success": true, "replacedCount": N} が正しい結果です。
理由: 変更履歴が有効な場合、getText は削除されたテキストと挿入されたテキストを連結して返します(例:"Jamie" ではなく "LawvableJamie")。これは想定された動作です。削除されたテキストは取り消し線で表示されますが、プレーンテキストの抽出結果には残ります。
複数編集のパターン
編集ごとにステップ 2~4 を繰り返します。それぞれ別々の bash 呼び出しとして実行してください。
コマンドの使い分け(変更履歴ガイド)
基本原則: 既存のテキストを変更する場合にのみ replaceText を使います。新しいテキストを追加する場合は insertContent を使います。
| タスク | コマンド | 変更履歴の表示 |
|---|---|---|
| 値を変更する | replaceText | |
| プレースホルダーを埋める | replaceText | |
| 誤字を修正する | replaceText | |
| 単語を変更する | replaceText | |
| 文に単語を追加する | insertContent | 既存のテキスト added word |
| 段落を追加する | insertContent | 新しい段落全体 |
| セクションを追加する | insertContent | 新しいセクション全体 |
| 免責事項を追加する | insertContent | 免責事項のテキスト |
| レビューコメントを追加する | addComment | (コメントの吹き出し。変更履歴には記録されません) |
検索とベストプラクティス
検索では書式をすべて無視し、プレーンテキストのみを抽出します。
- ✅ 太字/通常テキスト、変更履歴、段落をまたいで一致します
- ✅ 空白は柔軟に扱われます(余分なスペース、タブ、改行があっても問題ありません)
- 最初に一致した箇所が返されます。n 番目の一致には
occurrenceパラメーターを使用するか、パターンが一意になるようにコンテキストを追加してください。
一意なフレーズ(5 語以上)を使用してください。
- ❌
"the"や"Agreement"(よく使われすぎています) - ✅
"agrees to pay the sum of"や"Section 3.2 Confidentiality"
検索時に書式を気にする必要はありません。太字や変更履歴などをまたいで一致します。
一致箇所が曖昧な場合はoccurrenceを使用してください(1 始まり)。
{"command":"replaceText","args":{"search":"the","replacement":"that","occurrence":3}}
挿入する場合は、近くにある一意なアンカーテキストを見つけてください。
コマンド
getText - ドキュメントの内容を読み取る
// Get both text and HTML (default)
{"command":"getText","args":{}}
// Get only plain text (fewer tokens)
{"command":"getText","args":{"format":"text"}}
// Get only HTML (preserves structure)
{"command":"getText","args":{"format":"html"}}
形式: text(段落区切りのプレーンテキスト)、html(完全な HTML)、both(デフォルト)
getNodes - ドキュメントの構造を取得する
指定した種類のすべてのノードと位置を取得します。編集前にドキュメントの構造を把握するのに役立ちます。
// Get all paragraphs (use to identify section titles for TOC)
{"command":"getNodes","args":{"type":"paragraph"}}
// Get all tables
{"command":"getNodes","args":{"type":"table"}}
有効な種類: paragraph、table、tableRow、tableCell、bulletList、orderedList、listItem、image、blockquote
返される内容:
{
"nodes": [
{"index": 0, "type": "paragraph", "from": 0, "to": 31, "text": "Non-Disclosure Agreement", "textLength": 24},
{"index": 1, "type": "paragraph", "from": 227, "to": 241, "text": "Background", "textLength": 10},
{"index": 2, "type": "paragraph", "from": 586, "to": 601, "text": "Definitions", "textLength": 11, "marker": "1."}
],
"count": 3
}
replaceText - 検索と置換(削除+挿入)
使用する場合: 既存のテキストを別の内容に変更するとき。見つかったテキストは削除され、置き換えられます。
変更履歴への影響: 削除されたテキスト + 新しいテキスト(取り消し線+下線)として表示されます。
対象範囲: デフォルトではすべての一致箇所を置き換えます。N 番目の一致箇所のみを置き換えるにはoccurrenceパラメーターを使用してください。
// Change a value: "2024" → "2025"
{"command":"replaceText","args":{"search":"2024","replacement":"2025"}}
// Change a placeholder: "[ORG_NAME]" → "Lawvable"
{"command":"replaceText","args":{"search":"[ORG_NAME]","replacement":"Lawvable"}}
// Change a word: "shall" → "must"
{"command":"replaceText","args":{"search":"shall","replacement":"must","occurrence":1}}
// Add formatting to existing text (text is replaced with formatted version)
{"command":"replaceText","args":{"search":"Important Notice","replacement":"<strong>Important Notice</strong>"}}
insertContent - 新しい内容を挿入(挿入のみ)
使用する場合: アンカーテキストをそのまま残して、新しいテキストや要素を追加するとき。アンカーテキストはそのまま残り、新しい内容が前後に追加されます。 変更履歴への影響: 新しいテキストのみ(下線、取り消し線なし)として表示されます。
重要: 既存の語句を変更せずに文に語句を追加する必要がある場合は、必ずreplaceTextではなくinsertContentを使用してください。replaceTextを使うと、文全体が削除されて書き直されたように表示され、変更履歴が見づらくなります。
// CORRECT: Add a word after existing text - shows only the addition as tracked
// Original: "The party agrees to pay" → Result: "The party agrees to pay promptly"
{"command":"insertContent","args":{"content":" promptly","position":{"after":"agrees to pay"}}}
// WRONG: Using replaceText to add a word - shows entire phrase as deleted + rewritten
// This would show: "~~agrees to pay~~" + "agrees to pay promptly" (ugly track changes!)
// {"command":"replaceText","args":{"search":"agrees to pay","replacement":"agrees to pay promptly"}}
// Add a new section after a heading
{"command":"insertContent","args":{"content":"<h2>New Section</h2><p>Content here.</p>","position":{"after":"Introduction"}}}
// Add a disclaimer before signatures
{"command":"insertContent","args":{"content":"<p>By signing below, parties confirm agreement.</p>","position":{"before":"Signatures"}}}
// Add a clause after a section
{"command":"insertContent","args":{"content":"<p>Additional clause text.</p>","position":{"after":"Section 2."},"author":{"name":"Jane Smith"}}}
insertTable - 表を作成する
// Insert 3x4 table after specific text
{"command":"insertTable","args":{"rows":3,"cols":4,"position":{"after":"Introduction"}}}
// Insert 2x2 table (default) before specific text
{"command":"insertTable","args":{"position":{"before":"Signatures"}}}
// Pre-populated table with headers and data (dimensions inferred)
{"command":"insertTable","args":{"data":[["Name","Role"],["Alice","Engineer"]],"position":{"after":"Team:"}}}
// Cells support HTML formatting
{"command":"insertTable","args":{"data":[["<strong>Header</strong>"],["Value"]]}}
// With custom author for track changes
{"command":"insertTable","args":{"rows":2,"cols":3,"author":{"name":"John"}}}
パラメーター:
rows、cols- サイズ(デフォルトは 2。dataから推定される場合もあります)data- セルの内容を格納した 2 次元配列(行優先)。プレーンテキストまたは HTML に対応します。空のセルには空文字列を指定します。position- アンカーベースの位置指定には{"after": "text"}または{"before": "text"}を指定しますauthor- 変更履歴の作成者を示す任意の項目です
addComment - テキストにコメントを追加する
// Add a comment on specific text
{"command":"addComment","args":{"search":"confidential information","comment":"This clause needs legal review"}}
// Comment on nth occurrence
{"command":"addComment","args":{"search":"Party","comment":"Verify party name","occurrence":2}}
パラメーター:
search(必須) - コメントを付けるテキストcomment(必須) - コメントの内容occurrence- 一致箇所(1 始まり)。デフォルトは最初の一致箇所ですauthor- 作成者を示す任意の{name, email}
formatText - 書式を適用する
テキストのスタイル、段落のプロパティ、見出しへの変換を適用します。変更履歴には記録されません(パフォーマンス向上のため、直接適用されます)。
// Multiple text formats on entire document
{"command":"formatText","args":{"fontFamily":"Arial","fontSize":"12pt","color":"#333333","scope":"document"}}
// Bold + highlight on specific range (use getNodes to find positions)
{"command":"formatText","args":{"bold":true,"highlight":"#FFEB3B","scope":{"from":100,"to":200}}}
// Remove formatting (false removes, omit leaves unchanged)
{"command":"formatText","args":{"bold":false,"highlight":false,"scope":{"from":100,"to":200}}}
// Add hyperlink to text range
{"command":"formatText","args":{"link":"https://example.com","scope":{"from":100,"to":120}}}
// Remove hyperlink
{"command":"formatText","args":{"link":false,"scope":{"from":100,"to":120}}}
// Set line height on entire document
{"command":"formatText","args":{"lineHeight":"1.5","scope":"document"}}
// Set spacing + indent
{"command":"formatText","args":{"spacingBefore":"12pt","spacingAfter":"6pt","indent":36,"scope":"document"}}
// Align text right (use with scope from getNodes)
{"command":"formatText","args":{"textAlign":"right","scope":{"from":0,"to":25}}}
テキストレベルのパラメーター:
fontFamily- フォント名(例:"Arial"、"Times New Roman")fontSize- 単位付きのサイズ(例:"12pt"、"14px")color- CSS 形式の文字色(例:"#ff0000"、"red")highlight- 背景色。削除する場合はfalsebold、italic、underline、strikethrough- 適用する場合はtrue、削除する場合はfalse、変更しない場合は省略しますlink- ハイパーリンクを作成する URL 文字列。削除する場合はfalse
ブロックレベルのパラメーター:
textAlign- 段落の配置:left、center、right、justifylineHeight- 行間(例:"1.0"、"1.5"、"2.0")indent- 左インデント(ポイント単位。例:0.5 インチの場合は 36、1 インチの場合は 72)。削除する場合は 0 を指定します。spacingBefore- 段落前の間隔(例:"12pt"、"6pt")spacingAfter- 段落後の間隔(例:"12pt"、"6pt")
対象範囲: ドキュメント全体の場合は"document"、範囲を指定する場合は{"from": N, "to": M}を使用します。位置の確認にはgetNodesを使用してください。
insertTableOfContents - ブックマーク付きの目次を作成
内部ナビゲーションリンク付きの適切な目次を挿入します。見出し項目(位置+レベル)を特定すると、コマンドがブックマークと目次ノードを作成します。
ワークフロー:
getNodesをparagraphタイプで使用して、すべての段落の位置を取得します- テキストの内容、太字のスタイル、番号付けなどから、セクションタイトルとなる段落を特定します。番号付きの段落には
markerフィールド(例:"marker": "1.")が含まれ、目次では項目のテキストの前に自動的に追加されます。 - 位置と見出しレベルを
insertTableOfContentsに渡します
// TOC matching document font (always pass style with fontFamily + fontSize)
{"command":"insertTableOfContents","args":{"entries":[{"level":1,"from":227,"to":241},{"level":2,"from":586,"to":601}],"position":{"after":"Non-Disclosure Agreement"},"style":{"fontFamily":"Arial","fontSize":"10pt"}}}
// Custom title
{"command":"insertTableOfContents","args":{"entries":[{"level":2,"from":229,"to":243}],"style":{"fontFamily":"Arial","fontSize":"10pt"},"title":"Contents"}}
// No title
{"command":"insertTableOfContents","args":{"entries":[{"level":2,"from":229,"to":243}],"style":{"fontFamily":"Arial","fontSize":"10pt"},"title":""}}
パラメーター:
entries(必須) -{level: 1-6, from: N, to: M}の配列です。位置にはgetNodesの出力を使用します。コマンドがテキストを自動的に読み取ります。position-{"after": "text"}または{"before": "text"}(デフォルト:文書の先頭)title- 目次のタイトル(デフォルト:"Table of Contents"、タイトルなしの場合は"")style(必須) - 文書のフォント規則に合わせるための{fontFamily, fontSize}です。html形式のgetTextから文書のフォントファミリーとサイズを必ず検出し、ここに渡してください。デフォルトで太字と黒(#000000)が適用されます。タイトルは項目より自動的に 2pt 大きくなります。オプション:デフォルトの黒を上書きするcolor。author- 変更履歴の記録に使用する任意の作成者
コマンドは各見出しに非表示のブックマークを挿入し、それらを指す内部リンク付きの目次項目を作成します。すべての項目は level に基づいて自動的に左インデントされます(レベルごとに 0.5")。既存のテキストとスタイルは変更されません。
deleteTableOfContents - 目次を削除
文書から目次を削除します。
// Remove TOC only
{"command":"deleteTableOfContents","args":{}}
// Remove TOC and its bookmarks
{"command":"deleteTableOfContents","args":{"removeBookmarks":true}}
undo / redo - 履歴の移動
// Undo the last action
{"command":"undo","args":{}}
// Redo the last undone action
{"command":"redo","args":{}}
戻り値: 操作を元に戻す/やり直した場合は {"success": true}、元に戻す/やり直す操作がない場合は {"success": false} です。
acceptAllChanges / rejectAllChanges - 変更履歴を確定
文書内の変更履歴をすべて承諾または拒否します。編集が完了し、確認した後に使用してください。
// Accept all tracked changes (removes strikethroughs, keeps insertions)
{"command":"acceptAllChanges","args":{}}
// Reject all tracked changes (removes insertions, restores deleted text)
{"command":"rejectAllChanges","args":{}}
注: すべての変更を承諾すると、getText は削除された内容が連結されていない、整理済みのテキストを返します。
ヘッダー/フッターの編集
編集モードを切り替えて、文書のヘッダーとフッターを編集します。ヘッダー/フッターモードでは、すべてのコマンド(getText、replaceText、insertContent など)が本文ではなくヘッダー/フッターの内容に対して動作します。
focusHeader / focusFooter - ヘッダー/フッターモードに切り替え
{"command":"focusHeader","args":{}}
{"command":"focusFooter","args":{}}
exitHeaderFooter - 本文モードに戻る
{"command":"exitHeaderFooter","args":{}}
ヘッダー/フッターのワークフロー
# 1. Focus header
echo '{"command":"focusHeader","args":{}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
# 2. Read current header content
echo '{"command":"getText","args":{"format":"text"}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
# 3. Insert content (no position needed for empty header/footer)
echo '{"command":"insertContent","args":{"content":"<p>CONFIDENTIAL</p>"}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
# 4. Exit back to body
echo '{"command":"exitHeaderFooter","args":{}}' > .superdoc/doc.json && until grep -q '"success"' .superdoc/doc.json; do sleep 0.1; done && cat .superdoc/doc.json
注:
- ヘッダー/フッターは DOCX 構造内に定義されている必要があります(新規作成はできませんが、空のものは編集できます)
- ヘッダー/フッターが空の場合、
position引数を指定せずにinsertContentを実行すると先頭に挿入されます - 本文の編集に戻るため、作業が終わったら必ず
exitHeaderFooterを実行してください
HTML の書式設定
| 形式 | HTML |
|---|---|
| 見出し | <h1>、<h2>、<h3> |
| 段落 | <p>Text</p> |
| 太字/斜体/下線 | <strong>、<em>、<u> |
| 色 | <span style="color: red">text</span> |
| リスト | <ul><li>...</li></ul>、<ol><li>...</li></ol> |
| リンク | <a href="url">text</a> |
既存のテキストにリンクを追加する:
link パラメーターと位置スコープを指定して formatText を使用します:
// Step 1: Get paragraph positions
{"command":"getNodes","args":{"type":"paragraph"}}
// Step 2: Apply link to the target range
{"command":"formatText","args":{"link":"https://example.com","scope":{"from":218,"to":230}}}
重要: 置換文字列は、<tag> で始まり </tag> で終わる場合にのみ HTML として解析されます。前後にテキストが含まれている場合(例:(<a>text</a>))、文字列全体がリテラルテキストとして扱われます。
insertContent でリストを作成する:
// Bullet list
{"command":"insertContent","args":{"content":"<ul><li>First</li><li>Second</li></ul>","position":{"after":"Key points:"}}}
// Numbered list with nested items and formatting
{"command":"insertContent","args":{"content":"<ol><li><strong>Step one</strong><ul><li>Sub-item</li></ul></li><li>Step two</li></ol>","position":{"after":"Instructions:"}}}
一括編集(複数の文書)
編集対象が複数の文書にわたる場合は、順番に処理します。各文書を開き、編集し、確認してから次の文書に進んでください。サブエージェントは使用しないでください。順次処理のほうが簡単で、競合状態も回避できます。
パターン:
for each document:
1. Open: code --profile "Lawvable" path/to/doc.docx
2. Read: getText
3. Edit: replaceText / insertContent
4. Verify response shows success
文書はタブで開いたままにしてください。編集のたびに閉じる必要はありません。
トラブルシューティング
- コマンドが実行されない/生の JSON が返される:ドキュメントが開かれていません。
code --profile "Lawvable" path/to/doc.docxで開き直してから、再試行してください。 codeコマンドが見つからない:代わりに、フルパス/Applications/Visual Studio Code.app/Contents/Resources/app/bin/codeを使用してください。- 「テキストが見つかりません」エラー:まず
getTextを使用して実際の内容を確認し、検索文字列に前後の文脈をさらに含めてください。 - 置換内容が壊れる:応答を待たずにコマンドが送信されています。次のコマンドを送信する前に、必ず
{"success": ...}を待ってください。