Skip to content

feat(english): add Novelito source - #2770

Open
RibatTRW wants to merge 5 commits into
lnreader:masterfrom
RibatTRW:fm/lnreader-novelito-plugin-2759
Open

RibatTRW wants to merge 5 commits into
lnreader:masterfrom
RibatTRW:fm/lnreader-novelito-plugin-2759

Conversation

@RibatTRW

@RibatTRW RibatTRW commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a Novelito (https://noveli.to) source for English novels, requested in #2759. The site exposes a public JSON API for its catalogue, novel details, chapter lists and chapter text, so no account, bot challenge or browser is needed; browser-like headers are sent because the chapter endpoint rejects bare clients. Closes #2759.

Screenshots (plugin playground, live results)

Popular listing
Novel detail with chapter list
Chapter text
Search

What Changed

  • Add a standalone plugins/english/novelito.ts plugin (id novelito, v1.0.0) for https://noveli.to/. It reads the site's JSON API (/api/novels, /api/novels/<id>, /api/novels/<id>/chapters, /api/novels/<id>/chapters/<cid>) with a browser User-Agent and site Referer, and retries on HTTP 429.
  • Implement popularNovels (with sort, status and genre filters, plus a latest-novels mode), searchNovels, parseNovel (metadata and the full chapter list) and parseChapter. Chapter paragraphs are HTML-escaped after decoding numeric and named character references, and bare Noveli.to notices are removed from the chapter body.
  • Add the plugin icon at public/static/src/en/novelito/icon.png.

Closes #2759

🤖 Generated with Claude Code

Risk Assessment

✅ Low: A single self-contained standalone plugin plus a valid 96x96 icon. The recorded review fixes (429 retry, parsePage removal, chrome and notice filtering, entity decoding) are all present and correct on trace, and I found no new defects.

Testing

I ran the repo's live check on the plugin and got all four checks passing. I then bundled the plugin and called it directly against noveli.to for each case named in the round-1 decisions. Chapter 1 of novel 63983 no longer starts with reader-chrome labels. Martial Peak chapter 64875 shows &amp; once, not double-escaped. Chapter 25937207 of novel 33388 has no "Provided by" or "support more free releases" lines. A burst of 12 back-to-back chapter fetches all succeeded. That burst did not show whether a 429 occurred or whether the retry logic ran, so retry behavior is unconfirmed. I did not check parsePage removal or capture PR screenshots in this phase.

  • Live validation: ✅ go - 5 of 5 scenarios driven live against the product
Scenario Result Live Evidence
Run the live check: popular list, search, novel detail and a chapter all load without account or browser ✅ pass live npm run check:plugin output: 36 novels, 1 search result, 1178 chapters, 6981 chars
Open chapter 1 of novel 63983 and see story text, not Settings/Font Size UI labels ✅ pass live drive1.txt
Open Martial Peak chapter 64875 and see 'Silavin &amp; Tia' rendered once, not double-escaped ✅ pass live drive1.txt
Open novel 33388 chapter 25937207 and see no bare 'Provided by Noveli.to' or support-line paragraphs ✅ pass live drive2.txt
Fetch 12 chapters back-to-back and see every fetch succeed despite the site's burst limit ✅ pass live drive2.txt: ok 12, no errors, about 25s
Evidence: chapter chrome and entity output
novel63983 chapters 1178 {
== chrome novel63983 ch1 
 <p>1: Chapter 1; Pairing day   1: Chapter 1; Pairing day                              It was finally the Pairing day.</p>
<p>The most anticipated and hated day of the year.</p>
<p>At exactly eight o’clock in the morning, every digital screen across the country flickered once and then faded to black.</p>
<p>The change was so sudden that conversations died almost at once.</p>
<p>Giant billboards overlooking crowded intersections went dark, televisions mounted inside cafés interrupted their morning 
... h word landed with crushing weight, stripping away every certainty she had walked into the building with.</p>
<p>For a long moment, Lena simply stood there, unable to speak, as the future she had spent years believing in quietly began to unravel.</p>
6016 {
== martial peak 64875 
 <p>Chapter 3007 – Cooked</p>
<p>Translator: Silavin &amp; Tia</p>
<p>Translation Checker: PewPewLazerGun</p>
<p>Editor and Proofreader: Leo of Zion Mountain &amp; Dhael Ligerkeys</p>
<p>[Wait… An iron wok?] Li Jiao’s eyes narrowed as he suddenly recalled a dusty memory in a corner of his mind and brought it to the surface again, and the next thought that popped into his mind terrified him out of his wits.</p>
<p>“That treasure…” Hua Xing clearly recognized the origin of that iron wok too and a h 
... <p>In response, Li Jiao nodded, “She has indeed cleaned it.​‍‌ I’ve also stored all the sword artifacts that she absorbed previously in one of the Space Rings.”</p>
<p>[It looks like Lin Yun’er really did process it to be eaten while I was gone.]</p>
Evidence: notice filter and burst output
<p>Chapter 2: Please Wait For Esteemed Me To Divinate</p>
<p>Chapter 2: Please Wait For Esteemed Me To Divinate</p>
<p>People always say that the second year of middle school is a rebellious age.</p>
 
... right, you guys continue chatting, I have an urgent matter so I’ll leave first.”</p>
<p>Finishing his words, he rapidly went offline leaving behind the bewildered North River’s Loose Practitioner.</p>
has notices: false
burst ok 12 errs [] secs 24.914

Pipeline

Updates from git push no-mistakes

✅ **Intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 5 of 5 scenarios driven live against the product
Scenario Result Live Evidence
Run the live check: popular list, search, novel detail and a chapter all load without account or browser ✅ pass live npm run check:plugin output: 36 novels, 1 search result, 1178 chapters, 6981 chars
Open chapter 1 of novel 63983 and see story text, not Settings/Font Size UI labels ✅ pass live drive1.txt
Open Martial Peak chapter 64875 and see 'Silavin &amp; Tia' rendered once, not double-escaped ✅ pass live drive1.txt
Open novel 33388 chapter 25937207 and see no bare 'Provided by Noveli.to' or support-line paragraphs ✅ pass live drive2.txt
Fetch 12 chapters back-to-back and see every fetch succeed despite the site's burst limit ✅ pass live drive2.txt: ok 12, no errors, about 25s
  • npm run check:plugin -- plugins/english/novelito.ts (popularNovels, searchNovels, parseNovel, parseChapter all PASS)
  • esbuild-bundled plugin driven live: parseChapter on novel 63983 chapter 1 (chrome stripped)
  • parseChapter on novel 83 chapter 64875 (entity decoded once)
  • parseChapter on novel 33388 chapter 25937207 (bare notices removed)
  • 12 sequential chapter fetches (all succeeded)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

RibatTRW and others added 4 commits October 25, 2026 13:58
Adds the Novelito (noveli.to) plugin with popular browsing, search, novel details, the full chapter list and chapter text from the site's JSON API.

Co-Authored-By: OpenCode <noreply@opencode.ai>
@greptile-apps

greptile-apps Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes reach one new novel-reading source and its users.

The PR appears safe to merge, with a non-blocking improvement to character-reference decoding.

Findings

  1. P2 Character codes remain visible ▶

Summary

Adds a standalone Novelito source and its icon.

  • Novelito listings can be browsed, filtered, and searched.
  • Novelito novels open with their details and chapter list.
  • Novelito chapters show cleaned story text.
  • Novelito requests retry rate limits and cap response size.

Live access was not independently tested during this review. The icon's path was checked, but this model could not view the image. Rendered PR screenshots were not verified.

RibatTRW explicitly described returning a title-only chapter as intentional because it matches the source response.

Reviews (1) · Last reviewed commit: "no-mistakes(review): filter bare Noveli...." · Reviewed by Greptile

Comment thread plugins/english/novelito.ts Outdated
Comment on lines +111 to +118
function decodeEntities(text: string): string {
return text
.replace(/&nbsp;/gi, ' ')
.replace(/&amp;/gi, '&')
.replace(/&lt;/gi, '<')
.replace(/&gt;/gi, '>')
.replace(/&quot;/gi, '"')
.replace(/&#0?39;/gi, "'");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Character codes remain visible

If chapter text contains references such as &#8217; or &rsquo;, decodeEntities leaves them unchanged. parseChapterBody then escapes their ampersands, so readers see literal codes instead of punctuation. Extend the decoder to handle decimal, hexadecimal, and common named references before escaping the text. Add examples that pass through the full chapter conversion.

Knowledge Base Used: Plugin authoring contract

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 83341fd: decodeEntities now decodes decimal (&#8217;), hex (&#x2019;) and common named references (&rsquo;, &ldquo;, &hellip;, &nbsp;, &mdash; and more) in a single pass, so &amp;lt; decodes only once, before the text is escaped. Unknown names and invalid code points are left as-is.

This branch has not been deployed

No deployments
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.

Plugin Request (EN): Novelito

1 participant