Repository navigation
Komga-compatible API with two-way progress sync - #130
Merged
Merged
Conversation
The MangaUpdates scrobbler added three fields to ScrobbleSettings, and the Storybook fixture never got them, so `tsc -b` failed on dev. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Apps that only speak Komga (the Mihon Komga extension and tracker,
Tachimanga) can now use Maki as their server at http://host:port/komga.
- Libraries are root folders, series are series with something downloaded,
books are downloaded chapters. Everything reads through the token owner's
data scope, so root-folder grants apply as they do in the app and OPDS.
- The credential is the user's OPDS token, sent as X-API-Key, as a Basic
password, or through the session cookie issued after either. The Mihon
tracker only has the cookie. Both opds.enabled and the new komga.enabled
have to be on; it is off by default.
- Reading progress goes through ReaderService: PATCH books/{id}/read-progress
and the tracker's tachiyomi endpoints (v1 and v2). One newly read chapter
from the tracker is a read; a jump of several is a silent bulk mark, so
binding the tracker does not land in Rewind as one day's reading.
- Settings: a Komga switch in the OPDS card, with the server address and,
when the token was just generated, the API key to paste.
Closes #124
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The API-key handler stays out of /komga, where X-API-Key carries the OPDS token: it logged one failure line and ran one lookup per page. - Tracker summaries and v1 updates count chapters, not language copies, so a bilingual series can complete and lastBookRead maps to chapters. - A one-chapter tracker update falls back to the next copy, then to a silent mark, when the first copy's archive cannot be opened. - The plain series browse pages in SQL and loads only the page's rows; filter lists project just their column. - Unpaged book lists are capped at the max page size, and next/previous builds the neighbour from the series it already placed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
npm 11.21 on CI refuses `npm ci` because the optional wasm runtime that oxc's wasm32 binding pulls in names @emnapi/runtime without the lockfile holding an entry for it. Regenerated with that npm; no versions changed, only the missing entry and npm's peer flags. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The field was relabelled "Paste series URL or id…" with the MangaUpdates scrobbler, and the story still looked for the old text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two runs on this branch failed different stories each time (nine, then six, none touched here), all passing locally in isolation and in a full run. In the CI log, MSW misses requests such as /api/v1/tags and /api/v1/auth/me, which reach Vite's proxy and fail the running story. Retries only apply when CI is set; a broken story still fails all three. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # frontend/vitest.config.ts
StatsPage > Admin Reader Picker and SeriesDetailPage > Pending Torrent Proposal failed on every CI run of PR 130 and passed locally. Both wait for admin-only UI, which needs /initialize.json, then /auth/me, then its own query, and on a CI runner that chain outlasts Testing Library's default one-second timeout. Delaying the /auth/me mock by 900ms locally fails exactly those two stories; with a 5s timeout they pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`Notification.extend(...)` in theme.ts is Mantine's component, not the browser API, but /\bNotification\./ matched it and failed the step. The rule now matches only the browser API's own members (permission, requestPermission, maxActions) and `new Notification(`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI extracts with --clean and fails on any diff, so the #~ entries left by earlier plain extracts (strings since removed from the source) failed the catalogue step once the Storybook step stopped failing first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Komga clients send ?convert=jpeg or png for a page whose media type they cannot decode, and the API accepted and ignored it. With pages now stored as WebP or AVIF that matters: the page is re-encoded at full size unless its bytes already are that format, an unknown value is a 400 as on Komga, and a page no permitted decoder reads is a 415. The ETag carries the format, and the book thumbnail's first-page fallback is always JPEG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ga-api # Conflicts: # .claude/rules/storybook.md
…t in the Komga card story Both branches added the MangaUpdates fields to scrobbleSettings, so the merge kept two copies and tsc -b failed with TS1117. The Komga API card story now waits for its content like the rest of the suite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #124.
What it does
Maki now answers Komga's API under
/komga, so apps that only speak Komga can use it as their server: the Mihon Komga extension, Mihon's Komga tracker, Tachimanga. The address to enter in the app ishttp://host:8990/komga.DataScope, so root-folder grants apply exactly as they do in the app and over OPDS.X-API-Key, or as the password in HTTP Basic (any username). After either one, Maki sets aMaki.Komgasession cookie. Mihon's tracker shares the source's cookie jar and sends nothing else, so two-way sync depends on that cookie. Bad credentials get a 401, not OPDS's 404, because the extension only sends Basic after a 401. AFullAPI key does not open the API. The cookie is never accepted for a POST.komga.enabledswitch sits in the OPDS card. It only takes effect while OPDS is also on, since it shares the same token. When the token was just generated, the card also shows the server address and the API key to copy.PATCH books/{id}/read-progressand from the tracker'sread-progress/tachiyomiendpoints (v1 and v2). All of them go throughReaderService, so stats, scrobbling, Kavita push-back and incognito behave as they do in the built-in reader. If the tracker moves forward by exactly one chapter, that counts as a real read. If it jumps several chapters, they are bulk-marked silently (MarkReadAsync), so binding the tracker to a series you already read in Mihon doesn't show up in Rewind as one day of reading. Fetching a page does not count as progress here, unlike OPDS.numberSort(KomgaNumbering) is what Mihon treats as the chapter number and syncs on. It never decreases alongChapterOrder. Copies of the same chapter in different languages are treated as one chapter.Every DTO field is always written, including nulls. kotlinx.serialization rejects a missing key even when the property is nullable.
Also in here
fix(storybook): the scrobble settings mock was missing the three MangaUpdates fields, which broketsc -bon dev..claude/rules/komga.md, plus entries in the README,docs/features.mdand the release checklist (7.4a).lingui extractfor the new strings. I didn't translate anything.Testing
KomgaControllerTests(12): header, Basic and cookie auth, cookie refused on POST, both switches required,Fullkey refused, root-folder visibility, book order, page numbering, the PATCH round trip, tracker step vs jump, v1 tracker update.KomgaNumberingTests(6), plus the authorization inventory and all OPDS tests, all passing.npx tsc -b,oxlintandcheck:secure-contextare clean..devconfigon :8992 using curl in the extension's request shapes: 401 without a key; libraries, series and books lists; pages and page images; thumbnails;users/me; Basic auth setting the cookie; cookie-only GET and PUT working and POST refused; a one-chapter tracker PUT stored as a real read (BulkMarked0); a jump stored as bulk-marked; a PATCH storing page 3.Not tested in a real Mihon or Tachimanga install. Release checklist item 7.4a covers that.
🤖 Generated with Claude Code