Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ node_modules/
/app/gradle.properties
package-lock.json
.idea/
# OpenSpec 为本地智能体生成的上游工作流指令
.agents/skills/
# Kotlin 2.0
.kotlin/
94 changes: 94 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# AGENTS.md

## 适用范围

- 本文件适用于整个仓库;子目录若有更具体的 `AGENTS.md`,以更深层文件为准。
- 修改前先查看 `git status --short`,保留用户已有的未提交改动,不要顺手重排或清理无关文件。
- 变更应小而聚焦;除非任务明确要求,不要同时升级依赖、重构代码或改写生成文件。

## 项目概览

Legado(开源阅读)是一款不内置内容的 Android 阅读器。主工程是使用 Kotlin、Java 17
和 Gradle 构建的多模块 Android 项目,最低支持 Android 5.0(API 21)。仓库还包含一个
独立的 Vue 3 Web 子项目。

## 文档语言

- 仓库内新建或维护的项目文档一律使用简体中文,包括 `README`、`AGENTS.md`、开发说明、
设计记录以及 OpenSpec 的提案、设计、规范和任务文件。
- 文档中的说明、标题、验收条件和提交给维护者的总结必须使用中文,不要中英文混写。
- 代码标识符、命令、文件路径、协议字段、依赖坐标和无法准确翻译的专有名词可以保留原文,
但相关解释必须使用中文。
- `English.md` 等明确面向其他语言用户的翻译文件可以保留对应语言;中文文档是内容基准,
中文内容发生实质变化时应同步维护翻译版本。

## 目录与职责

- `app/`:Android 应用、资源、Room 数据库、单元测试和设备测试。
- `modules/book/`:书籍解析与阅读相关的 Android 库。
- `modules/rhino/`:Rhino JavaScript 执行支持。
- `modules/web/`:Vue 3、TypeScript、Vite 和 pnpm 管理的 Web 书架与源编辑器。
- `gradle/libs.versions.toml`:Gradle 依赖与插件版本目录。
- `app/schemas/`:Room 导出的数据库结构快照,数据库结构变化时必须同步更新。
- `app/src/main/assets/`:内置帮助、默认数据和 Web 静态资源;修改时注意格式与向后兼容。
- `openspec/`:OpenSpec 的规范、变更提案及归档。

## 开发约定

### Android

- 沿用相邻代码的 Kotlin 风格:4 空格缩进、官方 Kotlin 代码风格、清晰的空安全处理,避免无必要的 `!!`。
- UI 文案放在字符串资源中,并同步考虑已有的多语言资源;不要在业务代码中新增可见硬编码文案。
- 网络、数据库和文件操作不得阻塞主线程;协程应绑定合适的生命周期和调度器。
- 修改 Room 实体、DAO 或数据库版本时,同步迁移逻辑、`app/schemas/` 和相关迁移测试。
- 书源、订阅源、规则解析、备份恢复和导入 URI 属于兼容性敏感接口。除非提案明确要求,不要破坏已有 JSON 字段、规则语义或 URI path。
- 遵守 `gradle/libs.versions.toml` 中的固定版本说明。带有“不要更新版本”或兼容性注释的依赖不得顺手升级。
- 不要提交本地签名文件、凭据、`local.properties`、构建产物或 IDE 状态。不要改动 CI 中的签名配置,除非任务明确要求且已确认安全边界。

### 网页端

- `modules/web/` 使用 Node.js 20+、pnpm 9+、Vue 3 和 TypeScript。
- 遵循 `modules/web/.editorconfig`、ESLint 和 Prettier 配置;优先延续现有 Composition API 与目录组织。
- `pnpm lint:fix` 和 `pnpm format` 会写文件。仅检查时使用 `pnpm exec eslint .`,不要在无关任务中批量格式化。
- 网页端构建脚本会把产物同步到 Android 静态资源;提交前检查同步结果,避免混入无关生成差异。

## OpenSpec 工作流

- 新功能、用户可见行为变化、数据格式或兼容性变化,以及跨模块重构,应先在 `openspec/changes/` 建立变更并通过评审,再实现代码。
- 纯文档、注释和机械格式修复通常无需新建变更;如果它们改变了对外承诺或行为规范,仍应走 OpenSpec。
- 开始工作前运行 `openspec list` 并查看相关现有规范或变更,避免重复或冲突。
- 提案必须写明范围、非目标、受影响模块、兼容性与迁移风险,以及可验证的验收条件。
- 实现过程中保持提案、设计、规范和任务与代码一致;不要把未验证事项标记为完成。
- 完成后运行 `openspec validate --all --strict`。只有实现与验证均完成后才能归档变更。

## 常用验证命令

按改动范围选择最小充分验证;不要为了文档变更启动完整 Android 构建。

```bash
# Android 单元测试
./gradlew :app:testAppDebugUnitTest

# Android 静态检查与可安装调试包
./gradlew :app:lintAppDebug
./gradlew :app:assembleAppDebug

# 网页端类型检查、静态检查与构建
cd modules/web
pnpm install
pnpm type-check
pnpm exec eslint .
pnpm build

# OpenSpec 与补丁基础检查
openspec validate --all --strict
git diff --check
```

设备测试位于 `app/src/androidTest/`,需要可用的模拟器或真机;若未运行,交付时明确说明。

## 提交与交付

- 提交信息应简短说明意图;可参考仓库现有风格,关联 issue 时保留编号。
- 交付前检查 `git diff --stat` 和 `git diff --check`,确认没有无关改动、尾随空格或意外生成文件。
- 汇报实际执行过的验证及结果;没有运行的构建、测试或设备验证不得描述为已通过。
226 changes: 131 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,146 @@
# [English](English.md) [中文](README.md)
# Legado / 开源阅读

[![icon_android](https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/icon_android.png)](https://play.google.com/store/apps/details?id=io.legado.play.release)
<a href="https://jb.gg/OpenSourceSupport" target="_blank">
<img width="24" height="24" src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg?_gl=1*135yekd*_ga*OTY4Mjg4NDYzLjE2Mzk0NTE3MzQ.*_ga_9J976DJZ68*MTY2OTE2MzM5Ny4xMy4wLjE2NjkxNjMzOTcuNjAuMC4w&_ga=2.257292110.451256242.1669085120-968288463.1639451734" alt="idea"/>
</a>
<!-- markdownlint-disable MD013 MD033 -->

<div align="center">
<img width="125" height="125" src="https://github.com/gedoor/legado/raw/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png" alt="legado"/>

Legado / 开源阅读
<br>
<a href="https://gedoor.github.io" target="_blank">gedoor.github.io</a> / <a href="https://www.legado.top/" target="_blank">legado.top</a>
<br>
Legado is a free and open source novel reader for Android.

<img
src="https://github.com/gedoor/legado/raw/master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png"
alt="Legado 图标"
width="125"
height="125"
/>

<p>一款免费、开源的 Android 小说阅读器</p>

<p>
<a href="https://gedoor.github.io">gedoor.github.io</a>
·
<a href="https://www.legado.top/">legado.top</a>
</p>

<p>
<strong>中文</strong>
·
<a href="English.md">英文</a>
</p>

<p>
<a href="https://play.google.com/store/apps/details?id=io.legado.play.release">
<img
src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/icon_android.png"
alt="从 Google Play 下载"
width="32"
height="32"
/>
</a>
&nbsp;
<a href="https://jb.gg/OpenSourceSupport">
<img
src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg"
alt="JetBrains 开源支持计划"
width="32"
height="32"
/>
</a>
</p>

</div>

[![](https://img.shields.io/badge/-Contents:-696969.svg)](#contents) [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-主要功能-) [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-交流社区-) [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-) [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-其他-) [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-感谢-) [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-界面-)
> [!IMPORTANT]
> 软件不提供任何内容,需要您自行手动添加,例如导入书源。初次使用前请查看
> [官方帮助文档](https://www.yuque.com/legado/wiki)。

>新用户?
>
>软件不提供内容,需要您自己手动添加,例如导入书源等。
>看看 [官方帮助文档](https://www.yuque.com/legado/wiki),也许里面就有你要的答案。
## 目录

# Function-主要功能 [![](https://img.shields.io/badge/-Function-F5F5F5.svg)](#Function-主要功能-)
[English](English.md)
- [主要功能](#主要功能)
- [交流社区](#交流社区)
- [API](#api)
- [其他资源](#其他资源)
- [致谢](#致谢)
- [界面预览](#界面预览)

<details><summary>中文</summary>
1.自定义书源,自己设置规则,抓取网页数据,规则简单易懂,软件内有规则说明。<br>
2.列表书架,网格书架自由切换。<br>
3.书源规则支持搜索及发现,所有找书看书功能全部自定义,找书更方便。<br>
4.订阅内容,可以订阅想看的任何内容,看你想看<br>
5.支持替换净化,去除广告替换内容很方便。<br>
6.支持本地TXT、EPUB阅读,手动浏览,智能扫描。<br>
7.支持高度自定义阅读界面,切换字体、颜色、背景、行距、段距、加粗、简繁转换等。<br>
8.支持多种翻页模式,覆盖、仿真、滑动、滚动等。<br>
9.软件开源,持续优化,无广告。
</details>
## 主要功能

<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>
1. 支持自定义书源,可自行设置规则抓取网页数据;软件内提供规则说明。
2. 支持列表书架和网格书架自由切换。
3. 书源规则支持搜索与发现,找书、看书功能均可自定义。
4. 支持订阅自定义内容。
5. 支持替换净化,便于去除广告或替换内容。
6. 支持本地 TXT、EPUB 阅读,可手动浏览或智能扫描。
7. 阅读界面可高度自定义,包括字体、颜色、背景、行距、段距、加粗和简繁转换等。
8. 支持覆盖、仿真、滑动、滚动等多种翻页模式。
9. 软件开源、持续优化且无广告。

# Community-交流社区 [![](https://img.shields.io/badge/-Community-F5F5F5.svg)](#Community-交流社区-)
## 交流社区

### Telegram

#### Telegram
[![Telegram-group](https://img.shields.io/badge/Telegram-%E7%BE%A4%E7%BB%84-blue)](https://t.me/yueduguanfang) [![Telegram-channel](https://img.shields.io/badge/Telegram-%E9%A2%91%E9%81%93-blue)](https://t.me/legado_channels)

#### Discord
### Discord

[![Discord](https://img.shields.io/discord/560731361414086666?color=%235865f2&label=Discord)](https://discord.gg/VtUfRyzRXn)

#### Other
https://www.yuque.com/legado/wiki/community

<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# API [![](https://img.shields.io/badge/-API-F5F5F5.svg)](#API-)
* 阅读3.0 提供了2种方式的API:`Web方式`和`Content Provider方式`。您可以在[这里](api.md)根据需要自行调用。
* 可通过url唤起阅读进行一键导入,url格式: legado://import/{path}?src={url}
* path类型: bookSource,rssSource,replaceRule,textTocRule,httpTTS,theme,readConfig,dictRule,[addToBookshelf](/app/src/main/java/io/legado/app/ui/association/AddToBookshelfDialog.kt)
* path类型解释: 书源,订阅源,替换规则,本地txt小说目录规则,在线朗读引擎,主题,阅读排版,添加到书架

<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# Other-其他 [![](https://img.shields.io/badge/-Other-F5F5F5.svg)](#Other-其他-)
##### 免责声明
https://gedoor.github.io/Disclaimer

##### 阅读3.0
* [书源规则](https://mgz0227.github.io/The-tutorial-of-Legado/)
* [更新日志](/app/src/main/assets/updateLog.md)
* [帮助文档](/app/src/main/assets/web/help/md/appHelp.md)
* [web端书架](https://github.com/gedoor/legado_web_bookshelf)
* [web端源编辑](https://github.com/gedoor/legado_web_source_editor)

<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# Grateful-感谢 [![](https://img.shields.io/badge/-Grateful-F5F5F5.svg)](#Grateful-感谢-)
> * org.jsoup:jsoup
> * cn.wanghaomiao:JsoupXpath
> * com.jayway.jsonpath:json-path
> * com.github.gedoor:rhino-android
> * com.squareup.okhttp3:okhttp
> * com.github.bumptech.glide:glide
> * org.nanohttpd:nanohttpd
> * org.nanohttpd:nanohttpd-websocket
> * cn.bingoogolapple:bga-qrcode-zxing
> * com.jaredrummler:colorpicker
> * org.apache.commons:commons-text
> * io.noties.markwon:core
> * io.noties.markwon:image-glide
> * com.hankcs:hanlp
> * com.positiondev.epublib:epublib-core
<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>

# Interface-界面 [![](https://img.shields.io/badge/-Interface-F5F5F5.svg)](#Interface-界面-)
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B1.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B2.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B3.jpg" width="270">
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B4.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B5.jpg" width="270"><img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B6.jpg" width="270">

<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="#" align="right">
</a>
更多联系方式见[社区列表](https://www.yuque.com/legado/wiki/community)。

## API

- 阅读 3.0 提供网页接口(`Web`)和内容提供器(`Content Provider`)两种 API 调用方式,详见
[API 文档](api.md)。
- 可通过 URL 唤起阅读并一键导入,格式为
`legado://import/{path}?src={url}`。
- `path` 支持以下类型:

| `path` | 用途 |
| --- | --- |
| `bookSource` | 书源 |
| `rssSource` | 订阅源 |
| `replaceRule` | 替换规则 |
| `textTocRule` | 本地 TXT 小说目录规则 |
| `httpTTS` | 在线朗读引擎 |
| `theme` | 主题 |
| `readConfig` | 阅读排版 |
| `dictRule` | 字典规则 |
| [`addToBookshelf`](app/src/main/java/io/legado/app/ui/association/AddToBookshelfDialog.kt) | 添加到书架 |

## 其他资源

- [免责声明](https://gedoor.github.io/Disclaimer)
- [书源规则](https://mgz0227.github.io/The-tutorial-of-Legado/)
- [更新日志](app/src/main/assets/updateLog.md)
- [帮助文档](app/src/main/assets/web/help/md/appHelp.md)
- [网页端书架](https://github.com/gedoor/legado_web_bookshelf)
- [网页端源编辑](https://github.com/gedoor/legado_web_source_editor)

## 致谢

- `org.jsoup:jsoup`
- `cn.wanghaomiao:JsoupXpath`
- `com.jayway.jsonpath:json-path`
- `com.github.gedoor:rhino-android`
- `com.squareup.okhttp3:okhttp`
- `com.github.bumptech.glide:glide`
- `org.nanohttpd:nanohttpd`
- `org.nanohttpd:nanohttpd-websocket`
- `cn.bingoogolapple:bga-qrcode-zxing`
- `com.jaredrummler:colorpicker`
- `org.apache.commons:commons-text`
- `io.noties.markwon:core`
- `io.noties.markwon:image-glide`
- `com.hankcs:hanlp`
- `com.positiondev.epublib:epublib-core`

## 界面预览

<p align="center">
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B1.jpg" alt="Legado 界面预览 1" width="270" />
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B2.jpg" alt="Legado 界面预览 2" width="270" />
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B3.jpg" alt="Legado 界面预览 3" width="270" />
</p>

<p align="center">
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B4.jpg" alt="Legado 界面预览 4" width="270" />
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B5.jpg" alt="Legado 界面预览 5" width="270" />
<img src="https://github.com/gedoor/gedoor.github.io/blob/master/static/img/legado/%E9%98%85%E8%AF%BB%E7%AE%80%E4%BB%8B6.jpg" alt="Legado 界面预览 6" width="270" />
</p>
41 changes: 41 additions & 0 deletions openspec/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
schema: spec-driven

context: |
Legado(开源阅读)是一款免费、开源且不提供内容的 Android 阅读器。
主工程是使用 Kotlin、Java 17 和 Gradle 构建的多模块 Android 应用,编译与目标
SDK 均为 36,最低 SDK 为 21。模块包括 :app、:modules:book 和 :modules:rhino。
modules/web 中另有使用 Vue 3、TypeScript、Vite、Node.js 20+ 和 pnpm 9+ 的网页应用。

兼容性敏感区域包括书源和订阅源规则、JavaScript 执行、导入 URI 路径、JSON 数据、
备份、Room 数据库迁移以及持久化阅读数据。Room 数据库结构快照位于 app/schemas。
gradle/libs.versions.toml 中带有明确兼容性说明的依赖版本必须保持固定,除非变更本身
专门处理相应依赖。

仓库边界、编码约定和验证要求以 AGENTS.md 为准。所有项目维护文档和 OpenSpec 工件
必须使用简体中文,代码标识符、命令、路径和必要专有名词除外。面向用户的说明必须
陈述事实,并明确应用本身不提供内容。

rules:
proposal:
- 使用简体中文说明用户可感知的问题、范围和明确的非目标。
- 列出所有受影响的 Android 或网页端模块。
- 说明向后兼容、持久化、迁移和安全风险。
- 定义可观察的验收条件,不要只列实现层面的检查。
design:
- 相关时说明对最低 SDK 21、Room 数据、规则格式、导入接口和备份的影响。
- 优先沿用现有模块边界和模式;新增依赖或跨模块耦合必须说明理由。
tasks:
- 行为变化必须配套聚焦的自动化测试或明确的人工验证步骤。
- 适用时包含文档、本地化、数据库结构导出和迁移工作。
- 最后执行 OpenSpec 严格校验和最小充分的项目检查。

operations:
apply:
guidance:
- 保留工作区中的无关改动,避免大范围格式化重写。
- 不要在批准范围外修改签名材料、凭据或特意固定的依赖版本。
- 只有实际运行成功的测试和构建才能报告为通过。
archive:
guidance:
- 归档前确认所有任务和验收条件均已完成。
- 记录任何未执行的设备验证或人工验证。
Loading