Use this skill when the user asks about reading highlights, book notes, annotations, or reading history from KOReader. Triggers: "what books", "show highligh...
Run this via your tool (NOT in your reply):
find ~/Dropbox/Apps -name "*.sdr.json" -maxdepth 2 2>/dev/null | head -5
MEMORY.md for future sessions.Run via tool:
ls ~/Dropbox/Apps/<APP_NAME>/*.sdr.json 2>/dev/null
Each .sdr.json file = one book. The book title is the filename without .sdr.json.
Example: Designing Data-Intensive Applications.sdr.json → book title is "Designing Data-Intensive Applications"
Reply to user like: "You have 5 books in your library: ..." (list the titles)
Run via tool:
python3 -c "
import json
with open('<FULL_PATH_TO_FILE>') as f: data=json.load(f)
for h in data: print(h.get('datetime',''), '|', h.get('chapter',''), '|', h.get('pageno',''), '|', h.get('text','')[:200])
"
Reply with the highlights formatted naturally:
Run via tool:
python3 -c "
import json, glob, os
for f in glob.glob(os.path.expanduser('~/Dropbox/Apps/<APP_NAME>/*.sdr.json')):
title = os.path.basename(f).replace('.sdr.json','')
data = json.load(open(f))
for h in data:
if '<SEARCH_TERM>'.lower() in h.get('text','').lower() or '<SEARCH_TERM>'.lower() in h.get('notes','').lower():
print(title, '|', h.get('pageno',''), '|', h.get('text','')[:200])
"
Run via tool:
python3 -c "
import json, glob, os
all_h = []
for f in glob.glob(os.path.expanduser('~/Dropbox/Apps/<APP_NAME>/*.sdr.json')):
title = os.path.basename(f).replace('.sdr.json','')
data = json.load(open(f))
for h in data:
if h.get('datetime'): all_h.append((h['datetime'], title, h.get('chapter',''), h.get('pageno',''), h.get('text','')))
all_h.sort(reverse=True)
for dt,t,ch,pg,tx in all_h[:10]: print(dt, '|', t, '|', ch, '|', pg, '|', tx[:200])
"
Each file is a flat JSON array. Here is a real example:
[{"datetime":"2026-03-06 18:42:42","chapter":"Why You Might Need a Sharded Cache","pageno":192,"page":"/body/DocFragment[25]/body/p[41]/text().0","text":"in Why You Might Need a Sharded Cache"},{"datetime":"2026-03-07 09:07:13","pageno":192,"page":"/body/DocFragment[25]/body/p[48]/text().10","drawer":"lighten","chapter":"Why You Might Need a Sharded Cache","pos0":"/body/DocFragment[25]/body/p[48]/text().10","pos1":"/body/DocFragment[25]/body/p[49]/text().33","text":"the primary reason for sharding any service is to increase the size of the\ndata being stored in the service.","color":"gray"}]
Fields you SHOW to the user: text, datetime, chapter, pageno, notes (if present).
Fields you IGNORE (internal, never show): page, drawer, color, pos0, pos1.
Notes:
drawer, color, pos0, pos1 are optional — not every entry has them.notes is optional — only present when the user wrote an annotation.text may contain \n newlines.If ANY command fails, NEVER show the error to the user. Instead say one of:
ZIP package — ready to use