@ashdev/codex-plugin-sync-anilist 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -0
- package/dist/index.js +1095 -0
- package/dist/index.js.map +7 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# @ashdev/codex-plugin-sync-anilist
|
|
2
|
+
|
|
3
|
+
A Codex plugin for syncing manga reading progress between Codex and [AniList](https://anilist.co). Supports push/pull of reading status, volumes/chapters read, scores, dates, and notes.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Two-way sync of manga reading progress with AniList
|
|
8
|
+
- Push reading status, progress, scores, dates, and notes to AniList
|
|
9
|
+
- Pull updates from AniList back to Codex
|
|
10
|
+
- Configurable progress unit (volumes or chapters)
|
|
11
|
+
- Auto-pause/auto-drop stale series based on reading inactivity
|
|
12
|
+
- Rate limit handling with automatic retry
|
|
13
|
+
- Highest-progress-wins conflict resolution (progress only moves forward)
|
|
14
|
+
- External ID matching via AniList API IDs (`api:anilist`)
|
|
15
|
+
|
|
16
|
+
## Authentication
|
|
17
|
+
|
|
18
|
+
This plugin supports two authentication methods:
|
|
19
|
+
|
|
20
|
+
### OAuth (Recommended)
|
|
21
|
+
|
|
22
|
+
If your Codex administrator has configured OAuth:
|
|
23
|
+
|
|
24
|
+
1. Go to **Settings** > **Integrations**
|
|
25
|
+
2. Click **Connect with AniList Sync**
|
|
26
|
+
3. Authorize Codex on AniList
|
|
27
|
+
4. You're connected!
|
|
28
|
+
|
|
29
|
+
### Personal Access Token
|
|
30
|
+
|
|
31
|
+
If OAuth is not configured by the admin:
|
|
32
|
+
|
|
33
|
+
1. Go to [AniList Developer Settings](https://anilist.co/settings/developer)
|
|
34
|
+
2. Click **Create New Client**
|
|
35
|
+
3. Set the redirect URL to `https://anilist.co/api/v2/oauth/pin`
|
|
36
|
+
4. Click **Save**, then **Authorize** your new client
|
|
37
|
+
5. Copy the token shown on the pin page
|
|
38
|
+
6. In Codex, go to **Settings** > **Integrations**
|
|
39
|
+
7. Paste the token in the access token field and click **Save Token**
|
|
40
|
+
|
|
41
|
+
## Admin Setup
|
|
42
|
+
|
|
43
|
+
### Adding the Plugin to Codex
|
|
44
|
+
|
|
45
|
+
1. Log in to Codex as an administrator
|
|
46
|
+
2. Navigate to **Settings** > **Plugins**
|
|
47
|
+
3. Click **Add Plugin**
|
|
48
|
+
4. Fill in the form:
|
|
49
|
+
- **Name**: `sync-anilist`
|
|
50
|
+
- **Display Name**: `AniList Sync`
|
|
51
|
+
- **Command**: `npx`
|
|
52
|
+
- **Arguments**: `-y @ashdev/codex-plugin-sync-anilist@1.9.3`
|
|
53
|
+
5. Click **Save**
|
|
54
|
+
6. Click **Test Connection** to verify the plugin works
|
|
55
|
+
|
|
56
|
+
### Configuring OAuth (Optional)
|
|
57
|
+
|
|
58
|
+
To enable OAuth login for your users:
|
|
59
|
+
|
|
60
|
+
1. Go to [AniList Developer Settings](https://anilist.co/settings/developer)
|
|
61
|
+
2. Click **Create New Client**
|
|
62
|
+
3. Set the redirect URL to `{your-codex-url}/api/v1/user/plugins/oauth/callback`
|
|
63
|
+
4. Save and copy the **Client ID**
|
|
64
|
+
5. In Codex, go to **Settings** > **Plugins** > click the gear icon on AniList Sync
|
|
65
|
+
6. Go to the **OAuth** tab
|
|
66
|
+
7. Paste the **Client ID** (and optionally the **Client Secret**)
|
|
67
|
+
8. Click **Save Changes**
|
|
68
|
+
|
|
69
|
+
Without OAuth configured, users can still connect by pasting a personal access token.
|
|
70
|
+
|
|
71
|
+
### npx Options
|
|
72
|
+
|
|
73
|
+
| Configuration | Arguments | Description |
|
|
74
|
+
|--------------|-----------|-------------|
|
|
75
|
+
| Latest version | `-y @ashdev/codex-plugin-sync-anilist` | Always uses latest |
|
|
76
|
+
| Pinned version | `-y @ashdev/codex-plugin-sync-anilist@1.9.3` | Recommended for production |
|
|
77
|
+
| Fast startup | `-y --prefer-offline @ashdev/codex-plugin-sync-anilist@1.9.3` | Skips version check if cached |
|
|
78
|
+
|
|
79
|
+
## Configuration
|
|
80
|
+
|
|
81
|
+
### Codex Sync Settings
|
|
82
|
+
|
|
83
|
+
These settings are managed in the **Sync Settings** section of the plugin settings modal. They control which data the Codex server sends to the plugin and are shared across all sync plugins.
|
|
84
|
+
|
|
85
|
+
| Setting | Default | Description |
|
|
86
|
+
|---------|---------|-------------|
|
|
87
|
+
| Include completed series | On | Include series where all local books are read |
|
|
88
|
+
| Include in-progress series | On | Include series where at least one book has been started |
|
|
89
|
+
| Count partially-read books | Off | Whether partially-read books count toward the progress number |
|
|
90
|
+
| Sync ratings & notes | On | Include user ratings and notes in sync |
|
|
91
|
+
|
|
92
|
+
### Plugin-Specific Settings
|
|
93
|
+
|
|
94
|
+
These settings are specific to the AniList plugin and appear under **Plugin Settings** in the settings modal.
|
|
95
|
+
|
|
96
|
+
| Setting | Type | Default | Description |
|
|
97
|
+
|---------|------|---------|-------------|
|
|
98
|
+
| Progress Unit | string | `volumes` | Whether each Codex book counts as a "volume" or "chapter" on AniList. Use "volumes" to avoid misleading "Read chapter X" activity on AniList. |
|
|
99
|
+
| Auto-Pause After Days | number | `0` (disabled) | Number of days without reading activity before an in-progress series is set to Paused on AniList |
|
|
100
|
+
| Auto-Drop After Days | number | `0` (disabled) | Number of days without reading activity before an in-progress series is set to Dropped on AniList |
|
|
101
|
+
|
|
102
|
+
## Using the Plugin
|
|
103
|
+
|
|
104
|
+
Once connected, the sync plugin works automatically:
|
|
105
|
+
|
|
106
|
+
1. Go to **Settings** > **Integrations**
|
|
107
|
+
2. Click **Sync Now** to trigger a manual sync
|
|
108
|
+
3. View sync status including pulled/pushed/applied counts
|
|
109
|
+
|
|
110
|
+
The plugin matches Codex series to AniList entries using external IDs stored in the `series_external_ids` table with the `api:anilist` source.
|
|
111
|
+
|
|
112
|
+
## Sync Behavior
|
|
113
|
+
|
|
114
|
+
### Sync Modes
|
|
115
|
+
|
|
116
|
+
You can configure which direction data flows in **Settings** > **Integrations** > **Settings**:
|
|
117
|
+
|
|
118
|
+
| Mode | Description |
|
|
119
|
+
|------|-------------|
|
|
120
|
+
| **Pull & Push** (default) | Import progress from AniList, then export Codex progress to AniList |
|
|
121
|
+
| **Pull Only** | Import progress from AniList without writing anything back |
|
|
122
|
+
| **Push Only** | Export Codex progress to AniList without importing |
|
|
123
|
+
|
|
124
|
+
### How Sync Works
|
|
125
|
+
|
|
126
|
+
When sync runs in **Pull & Push** mode, it executes two phases in order:
|
|
127
|
+
|
|
128
|
+
1. **Pull** — Fetches your reading list from AniList, matches entries to Codex series via external IDs, and marks the corresponding books as read in Codex.
|
|
129
|
+
2. **Push** — Reads your current Codex reading progress and sends it to AniList, overwriting the remote entry.
|
|
130
|
+
|
|
131
|
+
### Conflict Resolution
|
|
132
|
+
|
|
133
|
+
Codex uses a **highest progress wins** strategy. There is no manual conflict resolution — instead, progress can only move forward:
|
|
134
|
+
|
|
135
|
+
| Scenario | Result |
|
|
136
|
+
|----------|--------|
|
|
137
|
+
| AniList ahead (e.g., 5 vols read) and Codex behind (3 vols read) | Pull marks books 4–5 as read in Codex. Push sends 5 to AniList. Both agree. |
|
|
138
|
+
| Codex ahead (5 vols read) and AniList behind (3 vols read) | Pull tries to mark first 3 as read — already completed, skipped. Push sends 5 to AniList. **Codex wins.** |
|
|
139
|
+
| Both changed differently | Pull applies remote progress first (additive only), then Push sends local state to AniList. Effectively **Codex wins** because push runs last. |
|
|
140
|
+
|
|
141
|
+
Key behaviors:
|
|
142
|
+
|
|
143
|
+
- **Pull is additive only** — it marks unread books as read but never un-reads a book. If you lower your chapter count on AniList, that change is ignored.
|
|
144
|
+
- **Push overwrites the remote** — after pulling, Codex sends its current state to AniList, which may overwrite changes made directly on AniList.
|
|
145
|
+
- **Progress is monotonic** — once a book is marked as read, sync will not undo it. Progress only moves forward.
|
|
146
|
+
|
|
147
|
+
### Completed Status
|
|
148
|
+
|
|
149
|
+
The plugin is conservative about marking series as "Completed" on AniList:
|
|
150
|
+
|
|
151
|
+
- A series is pushed as **Completed** only when all local books are read **and** the series metadata includes a `total_book_count` that matches.
|
|
152
|
+
- Otherwise, the series is pushed as **Reading** — even if all local books are read — because Codex can't be sure the library contains the full series.
|
|
153
|
+
|
|
154
|
+
### Rating & Notes Sync
|
|
155
|
+
|
|
156
|
+
When **Sync Ratings & Notes** is enabled in plugin settings:
|
|
157
|
+
|
|
158
|
+
- **Push**: Codex ratings (1-100 scale) and notes are sent to AniList, converted to the user's chosen AniList score format (auto-detected from their profile).
|
|
159
|
+
- **Pull**: AniList scores and notes are imported into Codex, but only when Codex has **no existing rating** for that series. Existing Codex ratings are never overwritten (**Codex wins**).
|
|
160
|
+
- Notes without a score are skipped on pull (Codex requires a rating to store notes).
|
|
161
|
+
|
|
162
|
+
### Auto-Pause & Auto-Drop
|
|
163
|
+
|
|
164
|
+
You can configure automatic status changes for series you haven't read in a while:
|
|
165
|
+
|
|
166
|
+
| Configuration | Behavior |
|
|
167
|
+
|--------------|----------|
|
|
168
|
+
| Pause=5, Drop=0 | Not read in 5 days -> Paused |
|
|
169
|
+
| Pause=5, Drop=7 | Not read in 5 days -> Paused; not read in 7 days -> Dropped |
|
|
170
|
+
| Pause=5, Drop=3 | Not read in 3 days -> Dropped (drop fires first since threshold is shorter) |
|
|
171
|
+
| Pause=0, Drop=4 | Not read in 4 days -> Dropped (no pause step) |
|
|
172
|
+
| Pause=0, Drop=0 | Disabled (default) |
|
|
173
|
+
|
|
174
|
+
Key behaviors:
|
|
175
|
+
|
|
176
|
+
- **Only affects in-progress series** — completed series are never auto-paused or auto-dropped.
|
|
177
|
+
- **Based on last reading activity** — the timer resets every time you read any book in the series.
|
|
178
|
+
- **Drop takes priority** — if both pause and drop thresholds are met, the series is dropped (not paused).
|
|
179
|
+
|
|
180
|
+
## Development
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
# Install dependencies
|
|
184
|
+
npm install
|
|
185
|
+
|
|
186
|
+
# Build the plugin
|
|
187
|
+
npm run build
|
|
188
|
+
|
|
189
|
+
# Type check
|
|
190
|
+
npm run typecheck
|
|
191
|
+
|
|
192
|
+
# Run tests
|
|
193
|
+
npm test
|
|
194
|
+
|
|
195
|
+
# Lint
|
|
196
|
+
npm run lint
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Project Structure
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
plugins/sync-anilist/
|
|
203
|
+
├── src/
|
|
204
|
+
│ ├── index.ts # Plugin entry point & staleness logic
|
|
205
|
+
│ ├── index.test.ts # Staleness logic tests
|
|
206
|
+
│ ├── manifest.ts # Plugin manifest
|
|
207
|
+
│ ├── anilist.ts # AniList API client & utility functions
|
|
208
|
+
│ └── anilist.test.ts # API client & utility tests
|
|
209
|
+
├── dist/
|
|
210
|
+
│ └── index.js # Built bundle (excluded from git)
|
|
211
|
+
├── package.json
|
|
212
|
+
├── tsconfig.json
|
|
213
|
+
└── README.md
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT
|