Skip to content

feat(cli): add Kindle SDR highlight extraction - #16

Merged
AnnatarHe merged 3 commits into
masterfrom
agent/kindle-sdr-highlights
Aug 2, 2026
Merged

AnnatarHe merged 3 commits into
masterfrom
agent/kindle-sdr-highlights

Conversation

@AnnatarHe

@AnnatarHe AnnatarHe commented Aug 1, 2026

Copy link
Copy Markdown
Member

Summary

  • add ck-cli sdr --path PATH [--json] with automatic Kindle tree, .sdr, and single-book discovery
  • decode KRDS .azw3r and .yjr annotations, APNX pages, KFX navigation pages, notes, and underlines
  • reconstruct unencrypted AZW3/KF8 and KFX text natively in Go, including Unicode and cross-fragment KFX selections
  • support uncompressed, PalmDOC, HUFF/CDIC, and KFX CONT/ENTY content with readable or ClippingItem JSON output
  • recover annotations from .yjr.bad_file when Kindle leaves the active .yjr cache empty
  • report empty local annotation caches as an actionable extraction error instead of a successful []
  • document supported formats and add deterministic unit and end-to-end fixtures without committing the supplied book or signed metadata

Why

Kindle sidecars store annotation positions rather than highlighted words. Recovering the text requires joining those positions with either the sibling KF8 markup stream or KFX text pools and compressed section position maps.

The supplied KFX snapshot exposed a false-success case: both its active .yjr and .yjr.bad_file contain a valid but empty annotation.cache.object. The command decoded the book and returned zero highlights as though extraction had succeeded, hiding that no local positions were available.

Impact

The command is read-only and offline, with no Python or KindleUnpack runtime dependency. KFX binary Ion decoding uses the Apache-2.0 Amazon Ion Go library. The existing JSON schema remains unchanged. DRM-protected books, Mobi7, and .yjf reading statistics remain unsupported.

When the active KFX annotation cache is empty, the extractor now checks a decodable .yjr.bad_file. If neither file contains annotations, it explains that the book must be opened/synced before copying or that documents/My Clippings.txt should be used. It no longer prints a misleading successful empty JSON array.

Validation

  • go test ./...
  • go test -race ./...
  • go vet ./...
  • go build -o /tmp/clippingkk-ck-cli ./cmd/ck-cli
  • generated empty-active/populated-backup fixture: highlight text and timestamp recovered from .yjr.bad_file
  • supplied real KFX snapshot: explicit empty-cache warning and non-zero exit
  • sanitized generated KFX/.yjr test: exact Chinese selection, attached note, and navigation page

golangci-lint was not available in the workspace.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@claude

claude Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


I'll analyze this and get back to you.

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.16656% with 648 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.05%. Comparing base (8518e5c) to head (619f4c1).

Files with missing lines Patch % Lines
internal/sdr/azw3.go 48.80% 202 Missing and 77 partials ⚠️
internal/sdr/kfx.go 66.02% 76 Missing and 48 partials ⚠️
internal/sdr/krds.go 64.20% 60 Missing and 32 partials ⚠️
internal/sdr/extract.go 65.78% 57 Missing and 34 partials ⚠️
internal/commands/sdr.go 13.63% 31 Missing and 7 partials ⚠️
internal/sdr/text.go 67.60% 13 Missing and 10 partials ⚠️
cmd/ck-cli/main.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master      #16       +/-   ##
===========================================
+ Coverage   22.22%   50.05%   +27.82%     
===========================================
  Files           8       14        +6     
  Lines         594     1998     +1404     
===========================================
+ Hits          132     1000      +868     
- Misses        454      782      +328     
- Partials        8      216      +208     
Flag Coverage Δ
unittests 50.05% <58.16%> (+27.82%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@claude

claude Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


I'll analyze this and get back to you.

@AnnatarHe
AnnatarHe marked this pull request as ready for review August 2, 2026 02:46
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@AnnatarHe
AnnatarHe merged commit dd5eda8 into master Aug 2, 2026
4 of 5 checks passed
@AnnatarHe
AnnatarHe deleted the agent/kindle-sdr-highlights branch August 2, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant