wachi 0.1.7 → 0.2.1
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 +5 -37
- package/package.json +6 -12
package/README.md
CHANGED
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
[](https://github.com/ysm-dev/wachi/actions)
|
|
5
5
|
[](https://github.com/ysm-dev/wachi/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
-
**
|
|
7
|
+
**Monitor RSS feeds and get notified on new content.**
|
|
8
8
|
|
|
9
|
-
wachi monitors
|
|
9
|
+
wachi monitors RSS feeds for new content and pushes notifications to 90+ services via [apprise](https://github.com/caronc/apprise). It auto-discovers RSS feeds when available.
|
|
10
10
|
|
|
11
11
|
- **Zero config for RSS** -- point at a blog, wachi finds the feed
|
|
12
|
-
- **LLM-powered for the rest** -- no RSS? wachi uses AI to identify content selectors via accessibility tree analysis
|
|
13
12
|
- **90+ notification services** -- Slack, Discord, Telegram, email, and [more](https://github.com/caronc/apprise/wiki)
|
|
14
13
|
- **Stateless by design** -- `wachi check` is a one-shot command, perfect for cron
|
|
15
14
|
- **No interactive prompts** -- built for automation and AI agents
|
|
@@ -55,15 +54,6 @@ wachi sub -n <name> [-a <apprise-url>] <url>
|
|
|
55
54
|
▼
|
|
56
55
|
Auto-discover RSS ───found───▶ Store URL + discovered feed
|
|
57
56
|
(link tags, common paths)
|
|
58
|
-
│not found
|
|
59
|
-
▼
|
|
60
|
-
LLM identifies content via accessibility tree
|
|
61
|
-
│
|
|
62
|
-
Derive CSS selectors from DOM (deterministic)
|
|
63
|
-
│
|
|
64
|
-
Validate selectors against raw HTTP
|
|
65
|
-
│
|
|
66
|
-
Store URL + selectors + baseline
|
|
67
57
|
```
|
|
68
58
|
|
|
69
59
|
On `wachi check`, each subscription is fetched and compared against a dedup table. New items trigger notifications via apprise. Old items are skipped. That's it.
|
|
@@ -97,8 +87,8 @@ wachi upgrade Update wachi to latest version
|
|
|
97
87
|
# Blog (auto-discovers RSS)
|
|
98
88
|
wachi sub -n main -a "slack://xoxb-token/channel" "https://blog.example.com"
|
|
99
89
|
|
|
100
|
-
#
|
|
101
|
-
wachi sub -n alerts -a "discord://webhook-id/token" "https://
|
|
90
|
+
# GitHub releases RSS feed
|
|
91
|
+
wachi sub -n alerts -a "discord://webhook-id/token" "https://github.com/ysm-dev/wachi/releases.atom"
|
|
102
92
|
|
|
103
93
|
# Add another subscription to an existing channel name
|
|
104
94
|
wachi sub -n main "https://example.com/changelog"
|
|
@@ -110,7 +100,7 @@ wachi sub -n media -a "tgram://bot-token/chat-id" "https://youtube.com/@channel"
|
|
|
110
100
|
wachi sub -n main "blog.example.com"
|
|
111
101
|
|
|
112
102
|
# Send all existing items on next check (no baseline)
|
|
113
|
-
wachi sub -n alerts -e "https://
|
|
103
|
+
wachi sub -n alerts -e "https://github.com/ysm-dev/wachi/releases.atom"
|
|
114
104
|
|
|
115
105
|
# Dry-run: see what would be sent
|
|
116
106
|
wachi check -d
|
|
@@ -151,18 +141,6 @@ Config lives at `~/.config/wachi/config.yml` (XDG-compliant, default). Auto-crea
|
|
|
151
141
|
`wachi` reads config in this order: `config.yml` -> `config.jsonc` -> `config.json`.
|
|
152
142
|
|
|
153
143
|
```yaml
|
|
154
|
-
# LLM config (only needed for non-RSS sites)
|
|
155
|
-
# Also settable via WACHI_LLM_API_KEY, WACHI_LLM_MODEL env vars
|
|
156
|
-
llm:
|
|
157
|
-
api_key: "sk-..."
|
|
158
|
-
model: "gpt-4.1-mini"
|
|
159
|
-
|
|
160
|
-
# Optional: summarize articles before sending
|
|
161
|
-
summary:
|
|
162
|
-
enabled: true
|
|
163
|
-
language: "en"
|
|
164
|
-
min_reading_time: 3 # minutes
|
|
165
|
-
|
|
166
144
|
# Channels and subscriptions (managed by wachi sub/unsub)
|
|
167
145
|
channels:
|
|
168
146
|
- name: "main"
|
|
@@ -170,10 +148,6 @@ channels:
|
|
|
170
148
|
subscriptions:
|
|
171
149
|
- url: "https://blog.example.com"
|
|
172
150
|
rss_url: "https://blog.example.com/feed.xml"
|
|
173
|
-
- url: "https://news.ycombinator.com"
|
|
174
|
-
item_selector: "tr.athing"
|
|
175
|
-
title_selector: ".titleline > a"
|
|
176
|
-
link_selector: ".titleline > a"
|
|
177
151
|
```
|
|
178
152
|
|
|
179
153
|
Each channel entry requires `name`. Names must be unique (case-insensitive).
|
|
@@ -182,9 +156,6 @@ All fields are optional with sensible defaults. An empty config file is valid.
|
|
|
182
156
|
|
|
183
157
|
| Variable | Purpose |
|
|
184
158
|
|----------|---------|
|
|
185
|
-
| `WACHI_LLM_API_KEY` | LLM API key |
|
|
186
|
-
| `WACHI_LLM_MODEL` | LLM model name |
|
|
187
|
-
| `WACHI_LLM_BASE_URL` | LLM API base URL (default: OpenAI) |
|
|
188
159
|
| `WACHI_NO_AUTO_UPDATE` | Set to `1` to disable auto-update |
|
|
189
160
|
|
|
190
161
|
## Design
|
|
@@ -193,7 +164,6 @@ All fields are optional with sensible defaults. An empty config file is valid.
|
|
|
193
164
|
- **Dedup, not state** -- items tracked by `sha256(link + title + channel)`. If the hash exists, it was already sent
|
|
194
165
|
- **No interactive prompts** -- ever. Errors tell you exactly what to set and where (What / Why / Fix pattern)
|
|
195
166
|
- **Baseline seeding** -- on subscribe, all current items are pre-seeded so your channel isn't flooded
|
|
196
|
-
- **Auto-healing** -- CSS selectors go stale? After 3 consecutive failures, wachi re-identifies them automatically
|
|
197
167
|
- **SQLite WAL mode** -- safe concurrent reads. Two cron jobs won't conflict
|
|
198
168
|
- **Atomic config writes** -- write to temp, then rename. No corruption from concurrent access
|
|
199
169
|
- **JSON envelope** -- `--json` on all commands returns `{"ok": true, "data": {...}}` or `{"ok": false, "error": {"what", "why", "fix"}}`
|
|
@@ -223,9 +193,7 @@ bun run db:generate
|
|
|
223
193
|
| CLI | [citty](https://github.com/unjs/citty) |
|
|
224
194
|
| Database | [drizzle-orm](https://github.com/drizzle-team/drizzle-orm) + bun:sqlite |
|
|
225
195
|
| HTTP | [ofetch](https://github.com/unjs/ofetch) |
|
|
226
|
-
| LLM | [Vercel AI SDK](https://github.com/vercel/ai) v6 |
|
|
227
196
|
| RSS | [rss-parser](https://github.com/rbren/rss-parser) |
|
|
228
|
-
| HTML | [cheerio](https://github.com/cheeriojs/cheerio) |
|
|
229
197
|
| Notifications | [apprise](https://github.com/caronc/apprise) via uvx |
|
|
230
198
|
| Linter | [Biome](https://biomejs.dev/) v2 |
|
|
231
199
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wachi",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Subscribe any link and get notified on change",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,15 +29,11 @@
|
|
|
29
29
|
"version:bake": "bun run scripts/bake-version.ts"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@ai-sdk/openai": "3.0.30",
|
|
33
32
|
"@biomejs/biome": "2.4.2",
|
|
34
33
|
"@types/bun": "1.3.9",
|
|
35
|
-
"@types/turndown": "5.0.6",
|
|
36
34
|
"@typescript/native-preview": "7.0.0-dev.20260218.1",
|
|
37
|
-
"ai": "6.0.91",
|
|
38
35
|
"cheerio": "1.2.0",
|
|
39
36
|
"citty": "0.2.1",
|
|
40
|
-
"css-selector-generator": "3.8.0",
|
|
41
37
|
"drizzle-kit": "0.31.9",
|
|
42
38
|
"drizzle-orm": "0.45.1",
|
|
43
39
|
"drizzle-zod": "0.8.3",
|
|
@@ -46,18 +42,16 @@
|
|
|
46
42
|
"knip": "5.84.1",
|
|
47
43
|
"ofetch": "1.5.1",
|
|
48
44
|
"p-limit": "7.3.0",
|
|
49
|
-
"reading-time": "1.5.0",
|
|
50
45
|
"rss-parser": "3.13.0",
|
|
51
|
-
"turndown": "7.2.2",
|
|
52
46
|
"yaml": "2.8.2",
|
|
53
47
|
"zod": "4.3.6",
|
|
54
48
|
"zod-validation-error": "5.0.0"
|
|
55
49
|
},
|
|
56
50
|
"optionalDependencies": {
|
|
57
|
-
"@wachi-cli/darwin-arm64": "0.1
|
|
58
|
-
"@wachi-cli/darwin-x64": "0.1
|
|
59
|
-
"@wachi-cli/linux-arm64": "0.1
|
|
60
|
-
"@wachi-cli/linux-x64": "0.1
|
|
61
|
-
"@wachi-cli/win32-x64": "0.1
|
|
51
|
+
"@wachi-cli/darwin-arm64": "0.2.1",
|
|
52
|
+
"@wachi-cli/darwin-x64": "0.2.1",
|
|
53
|
+
"@wachi-cli/linux-arm64": "0.2.1",
|
|
54
|
+
"@wachi-cli/linux-x64": "0.2.1",
|
|
55
|
+
"@wachi-cli/win32-x64": "0.2.1"
|
|
62
56
|
}
|
|
63
57
|
}
|