wachi 0.1.6 → 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.
Files changed (3) hide show
  1. package/README.md +5 -37
  2. package/bin/wachi.js +15 -0
  3. package/package.json +6 -12
package/README.md CHANGED
@@ -4,12 +4,11 @@
4
4
  [![CI](https://github.com/ysm-dev/wachi/actions/workflows/release.yml/badge.svg)](https://github.com/ysm-dev/wachi/actions)
5
5
  [![license](https://img.shields.io/npm/l/wachi)](https://github.com/ysm-dev/wachi/blob/main/LICENSE)
6
6
 
7
- **Subscribe any link and get notified on change.**
7
+ **Monitor RSS feeds and get notified on new content.**
8
8
 
9
- wachi monitors any URL for new content and pushes notifications to 90+ services via [apprise](https://github.com/caronc/apprise). It auto-discovers RSS feeds when available, and uses LLM-powered CSS selector identification for everything else.
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
- # Hacker News front page (LLM identifies content selectors)
101
- wachi sub -n alerts -a "discord://webhook-id/token" "https://news.ycombinator.com"
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://news.ycombinator.com"
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/bin/wachi.js CHANGED
@@ -22,9 +22,24 @@ const runBinary = (binaryPath) => {
22
22
  const result = spawnSync(binaryPath, args, {
23
23
  stdio: "inherit",
24
24
  });
25
+
26
+ if (result.error) {
27
+ process.stderr.write(
28
+ `Error: Failed to run wachi binary at ${binaryPath}.\n` +
29
+ `${result.error.message}\n` +
30
+ "Try reinstalling wachi and its optional platform package.\n",
31
+ );
32
+ process.exit(1);
33
+ }
34
+
25
35
  if (typeof result.status === "number") {
26
36
  process.exit(result.status);
27
37
  }
38
+
39
+ if (typeof result.signal === "string") {
40
+ process.stderr.write(`Error: wachi binary terminated by signal ${result.signal}.\n`);
41
+ }
42
+
28
43
  process.exit(1);
29
44
  };
30
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wachi",
3
- "version": "0.1.6",
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.6",
58
- "@wachi-cli/darwin-x64": "0.1.6",
59
- "@wachi-cli/linux-arm64": "0.1.6",
60
- "@wachi-cli/linux-x64": "0.1.6",
61
- "@wachi-cli/win32-x64": "0.1.6"
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
  }