朝、未コミットの作業を見たら昨日のyomitoku-kindleがStep 10まで書きかけで止まっていた。今日は「URLを渡したら最後まで通す」をゴールに据えて手を動かした。最終的に、Chrome拡張でKindle Cloud Readerを巡回スクショ→yomitokuでOCR→Turso book-knowledge-base DBに投入、最後に/restructure-bookで章節整形まで通る/yomitoku-kindleスラッシュコマンドが完成した。
やったこと
/yomitoku-kindle <ASIN>で巡回スクショ→OCR→Turso投入→/restructure-bookチェーン実行までを1コマンドで完走させた- Chrome拡張のUIをポップアップからFloating Panelに移し、拡張アイコンを毎回クリックする運用を捨てた
- 撮影の瞬間だけFloating Panelを
display:noneでDOMから外し、OCRノイズを消した - read.amazon.co.jp/notebookの内部APIからハイライトとメモを取得し、
kindle_library/kindle_highlightsテーブルにUPSERTで投入した - KU(Kindle Unlimited)絞り込み27件をkindle_libraryに反映した
- コミック157件に
comicタグを付与し、星評価ランキングから除外運用に切り替えた - ビューアー側に表紙画像を追加、グローバルナビでbooks / shelves / highlightsへ全ページから1クリック遷移できるようにした
Floating Panel化で「拡張アイコンを毎回クリックする」運用を捨てる
最初の壁はChrome拡張のUI形態だった。MV3のポップアップはアイコンクリックがないと開かないので、自動化と相性が悪い。content.jsの中でKindleページにfloating panelを直接埋め込む構造に書き換えた。これでClaude Codeからevaluate_scriptで#kindle-capturer-startをclick()するだけで巡回が始まる。
ところがpanel経由で起動した瞬間、captureVisibleTabがEither the '<all_urls>' or 'activeTab' permission is required.で落ちた。MV3のactiveTabはユーザーのアイコンクリック起点でしか降りない仕様だった。manifestの権限を<all_urls>を持つ形に切り替えて回避した。昨日まで動いていたのに今朝動かなかったのは、起動経路がポップアップからfloating panelに変わったからだった。
撮影瞬間のpanel非表示——OCRノイズを消す
巡回を回しはじめて、ユーザーから「panelが画面に映り込んでる」と指摘された。captureVisibleTabはChromeのビューポート全体を撮るのでFloating Panel自体が黒背景の上に重なって入る。OCRノイズになる。
最初はvisibility:hiddenで逃がしたが、それでも領域が残る。完全に消すためにdisplay:noneに切り替え、撮影直後に復元する方式に変えた。さらに、keepalive用のsetIntervalが撮影中に新しいpanelを再注入する競合があったので、巡回中はkeepalive自体を止めた。134枚撮り終えて確認したら、Floating Panelの映り込みは一切なし。OCR精度の文脈で「白背景+黒文字」を意識してKindleのReader設定を反転させる運用も追加した。
// 撮影直前にpanelをDOMから外す
const panel = document.getElementById('kindle-capturer-panel')
const parent = panel?.parentNode
panel?.remove()
await chrome.runtime.sendMessage({ type: 'CAPTURE_VISIBLE_TAB' })
if (panel && parent) parent.appendChild(panel)
/restructure-bookのチェーン実行を組み込む
/yomitoku-kindleの末尾で/restructure-bookを必ず呼ぶように直した。マークダウンのスラッシュコマンドはチェーン実行を明示的に書かないと走らないので、Step 16として/restructure-book <book_id>をinline実行する手順を末尾に追加した。コミット履歴で追えるよう、book-knowledge-base・chrome-extension-kindle・~/.claudeの3リポジトリそれぞれにコミットを切った。
「目次照準が逆」バグ——画像順を反転して再OCR
別の本(東洋経済の和書)を流したら、章番号が第7章→第1章の降順で並ぶ妙な構造になった。最初は「目次ページがある変な本」と思って章名割り当てで凌いだが、ユーザーから「いや、照準なんでこれ逆なんですか」と一言。原因はKindleメタのpage-progression-direction: rtl。横書きビジネス書でもKindle側は「和書」扱いで、ページ送りキーがltrと逆向きに作用していた。
ここで「再撮影せず、画像の順序をプログラムで反転して再OCRすればいい」とユーザーから案を貰った。page_0001.png〜page_0124.pngをリネームで逆順に並べ替え、yomitokuに再投入。DB側の旧チャンクを削除して再投入したら、第1章→第7章の論理順に並んだ。/restructure-bookもセクション単位で全部走らせ、87→68チャンクに統合できた。
この学びは/yomitoku-kindleのStep 5「方向判定」と、末尾の「方向誤判定リカバリ」セクションに書き残した。次から「論理順がおかしい」と気づいた瞬間、撮り直しではなくスクリプトで反転すれば数分で復旧できる。
「画像が全部Xタブだった」事件——別ウィンドウ分離
別の本(新書)で巡回を回したら、撮れていた100枚が全部XのタブUIだった。原因は単純で、撮影中に元ウィンドウでX(Twitter)タブをアクティブにしたから。captureVisibleTab(windowId)は「指定ウィンドウのアクティブタブ」を撮るので、別タブに切り替えた瞬間そっちが入る。
対策として、background.jsに「Kindleタブを新ウィンドウに分離して撮影する」ハンドラを追加し、content.jsには**「別ウィンドウで開始」ボタン**を新設した。これで撮影専用ウィンドウは独立して動き、元ウィンドウではTwitterでも調べ物でも自由にできる。新書98ページを再撮影したら、まえがき→第1章→と論理順で揃った。
Kindleノートブックの内部API——2,801件のハイライトを取り込む
別セッションでread.amazon.co.jp/notebookの内部APIを観察した。/notebook?asin=...&contentLimitState= がハイライト本体(HTML 116KB)を返し、annotation IDと位置・色・本文・メモが全部DOMから取れる。Chrome DevTools MCP経由でログイン済みChromeから叩いて、ASIN 196冊分のハイライトをfetchしてTursoのkindle_library / kindle_highlightsテーブルにUPSERTで投入した。
最初の取り込みでcp932エンコーディングのprintで落ちて0件になったが、出力をUTF-8固定&書籍ごとcommitに変えて、196冊・2,801件のハイライトをDBに収めた。
-- kindle_highlights テーブル設計(差分判定用にlast_annotated_atを持つ)
CREATE TABLE kindle_highlights (
annotation_id TEXT PRIMARY KEY,
asin TEXT NOT NULL,
location INTEGER,
color TEXT,
highlight TEXT,
note TEXT,
annotated_at TEXT
);
ビューアー側——表紙画像とグローバルナビ
mdx-playgroundではなくbook-knowledge-baseのNuxt側ビューアーに、amazon_metadata.image_url_largeから表紙画像を引っ張る修正を入れた。258冊中233冊に画像URLがあったので、/booksの4カラムグリッドが一気に華やかになった。
そのあとユーザーから「ヘッダーのどこかからbooks/shelves/highlightsに直接遷移できるようにして」と指示。Nuxtのレイアウトで全ページ共通のグローバルナビバーを追加し、Kindleハイライトページの独自topbarが重ならないようtop: 100pxにずらした。
コミック除外
KU・全468冊の星評価を取り終わって★順ランキングを見たら、トップ10がほぼコミックで埋まっていた。ユーザーから「コミックは星が高くなりがちだからcomicタグで除外して」と指示。タイトル・著者・カテゴリ・amazon_categoriesからヒューリスティック判定して157件にcomicタグを付与した。誤判定1件(橘玲の評論本がWPB eBooksレーベルでヒット)はユーザー目視で除外。
学びメモ
- MV3のactiveTabは起動経路で挙動が変わる。Floating Panel化で動かなくなった原因はここだった。ポップアップ起動と同じ感覚で進めると黙って落ちる
- OCR元画像にUI要素を映さない。
display:none+keepalive停止までやって、ようやく黒背景に本文だけの画像が撮れる - 論理順が逆だと気づいたら撮り直さない。リネームで反転して再OCRすれば数分で済む。今回これに30分かけたが、次は5分で復旧できる
captureVisibleTabはアクティブタブを撮る。撮影専用ウィンドウを別に分離するのが唯一の正解。撮影中は元ウィンドウで自由に作業できるメリットも大きい- チェーン実行はマークダウンに書き残す。
/yomitoku-kindle末尾に「最後に/restructure-bookを必ず呼ぶ」を明文化して、未来の自分が忘れない構造にした
明日やること
- kindle_libraryの467冊から、まだOCR未取り込みの本を優先順位順にOCR投入する運用フローを書く
- ハイライトとOCR本文を横断検索できる
/kindle-searchコマンドを設計する - /yomitoku-kindleの巡回中に「Oops... Something Went Wrong」が出たら自動でdone.jsonにerror記録する処理を実機で確認する