rss-agent-discovery 0.1.0 → 0.1.2
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 +55 -18
- package/bin/rss-agent-discovery +12 -0
- package/dist/find-rss-feeds.d.ts +14 -0
- package/dist/find-rss-feeds.d.ts.map +1 -1
- package/dist/find-rss-feeds.js +122 -44
- package/dist/find-rss-feeds.js.map +1 -1
- package/dist/find-rss-feeds.test.d.ts +2 -0
- package/dist/find-rss-feeds.test.d.ts.map +1 -0
- package/dist/find-rss-feeds.test.js +215 -0
- package/dist/find-rss-feeds.test.js.map +1 -0
- package/package.json +19 -5
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ npm run build
|
|
|
27
27
|
|
|
28
28
|
### Basic usage:
|
|
29
29
|
```bash
|
|
30
|
-
|
|
30
|
+
node dist/find-rss-feeds.js https://vercel.com
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
Or via CLI (after `npm link`):
|
|
@@ -37,32 +37,58 @@ rss-discover https://vercel.com
|
|
|
37
37
|
|
|
38
38
|
### Multiple URLs (parallel processing):
|
|
39
39
|
```bash
|
|
40
|
-
|
|
40
|
+
node dist/find-rss-feeds.js https://vercel.com https://news.ycombinator.com https://stripe.com
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
### Parse with jq:
|
|
44
44
|
```bash
|
|
45
|
-
|
|
45
|
+
node dist/find-rss-feeds.js https://vercel.com | jq '.results[0].feeds'
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
### Custom timeout:
|
|
49
49
|
```bash
|
|
50
|
-
|
|
50
|
+
node dist/find-rss-feeds.js --timeout 15000 https://example.com
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
### Skip blog scanning:
|
|
54
54
|
```bash
|
|
55
|
-
|
|
55
|
+
node dist/find-rss-feeds.js --skip-blogs https://example.com
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Limit blog scans:
|
|
59
|
+
```bash
|
|
60
|
+
node dist/find-rss-feeds.js --max-blogs 3 https://example.com
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Custom blog paths:
|
|
64
|
+
```bash
|
|
65
|
+
node dist/find-rss-feeds.js --blog-paths '/blog,/news' https://example.com
|
|
66
|
+
# or with pipe separator
|
|
67
|
+
node dist/find-rss-feeds.js --blog-paths '/blog|/updates' https://example.com
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Verbose mode (debug logging):
|
|
71
|
+
```bash
|
|
72
|
+
node dist/find-rss-feeds.js --verbose https://example.com
|
|
56
73
|
```
|
|
57
74
|
|
|
58
75
|
### Show help:
|
|
59
76
|
```bash
|
|
60
|
-
|
|
77
|
+
node dist/find-rss-feeds.js --help
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Show version:
|
|
81
|
+
```bash
|
|
82
|
+
node dist/find-rss-feeds.js --version
|
|
83
|
+
# or
|
|
84
|
+
rss-discover --version
|
|
61
85
|
```
|
|
62
86
|
|
|
63
87
|
### Run tests:
|
|
64
88
|
```bash
|
|
65
|
-
npm test
|
|
89
|
+
npm test # Run all tests (unit + smoke)
|
|
90
|
+
npm run test:unit # Run unit tests only
|
|
91
|
+
npm run test:smoke # Run smoke tests (integration)
|
|
66
92
|
```
|
|
67
93
|
|
|
68
94
|
## Output Schema
|
|
@@ -70,6 +96,7 @@ npm test
|
|
|
70
96
|
```json
|
|
71
97
|
{
|
|
72
98
|
"success": true,
|
|
99
|
+
"partialResults": false,
|
|
73
100
|
"results": [
|
|
74
101
|
{
|
|
75
102
|
"url": "https://vercel.com",
|
|
@@ -86,9 +113,17 @@ npm test
|
|
|
86
113
|
}
|
|
87
114
|
```
|
|
88
115
|
|
|
116
|
+
**Fields:**
|
|
117
|
+
- `success` (boolean): `true` if no URLs had errors, `false` if at least one URL had an error
|
|
118
|
+
- `partialResults` (boolean, optional): `true` if `success === false` but some feeds were still found
|
|
119
|
+
- `results` (array): One entry per input URL
|
|
120
|
+
- `url` (string): The scanned URL
|
|
121
|
+
- `feeds` (array): Discovered feed objects with `url`, `title`, and `type` ('rss' | 'atom' | 'unknown')
|
|
122
|
+
- `error` (string | null): Error message if scanning failed, `null` otherwise
|
|
123
|
+
|
|
89
124
|
## Exit Codes
|
|
90
125
|
|
|
91
|
-
- `0` - One or more feeds found
|
|
126
|
+
- `0` - One or more feeds found (or `--help` / `--version` used)
|
|
92
127
|
- `1` - No feeds found
|
|
93
128
|
- `2` - Error occurred
|
|
94
129
|
|
|
@@ -108,7 +143,7 @@ npm test
|
|
|
108
143
|
|
|
109
144
|
### Find feeds for Vercel:
|
|
110
145
|
```bash
|
|
111
|
-
|
|
146
|
+
node dist/find-rss-feeds.js https://vercel.com
|
|
112
147
|
```
|
|
113
148
|
|
|
114
149
|
Output:
|
|
@@ -129,19 +164,19 @@ Output:
|
|
|
129
164
|
|
|
130
165
|
### Check exit code:
|
|
131
166
|
```bash
|
|
132
|
-
|
|
167
|
+
node dist/find-rss-feeds.js https://vercel.com 2>/dev/null
|
|
133
168
|
echo $? # Outputs: 0
|
|
134
169
|
```
|
|
135
170
|
|
|
136
171
|
### No feeds found:
|
|
137
172
|
```bash
|
|
138
|
-
|
|
173
|
+
node dist/find-rss-feeds.js https://example.com 2>/dev/null
|
|
139
174
|
echo $? # Outputs: 1
|
|
140
175
|
```
|
|
141
176
|
|
|
142
177
|
### Parallel scan:
|
|
143
178
|
```bash
|
|
144
|
-
|
|
179
|
+
node dist/find-rss-feeds.js https://vercel.com https://news.ycombinator.com | jq
|
|
145
180
|
```
|
|
146
181
|
|
|
147
182
|
## Integration Example
|
|
@@ -181,7 +216,7 @@ This tool is designed to work seamlessly with AI coding agents:
|
|
|
181
216
|
### Opencode / Claude Code
|
|
182
217
|
```bash
|
|
183
218
|
# Opencode can call this tool directly
|
|
184
|
-
npx rss-agent-discovery https://example.com | jq '.results[0].feeds[].url'
|
|
219
|
+
npx -y rss-agent-discovery https://example.com | jq '.results[0].feeds[].url'
|
|
185
220
|
```
|
|
186
221
|
|
|
187
222
|
### Cursor
|
|
@@ -189,7 +224,7 @@ Cursor can integrate this as a custom tool:
|
|
|
189
224
|
```json
|
|
190
225
|
{
|
|
191
226
|
"name": "rss_discovery",
|
|
192
|
-
"command": "npx rss-agent-discovery {url}",
|
|
227
|
+
"command": "npx -y rss-agent-discovery {url}",
|
|
193
228
|
"description": "Discover RSS feeds from a website"
|
|
194
229
|
}
|
|
195
230
|
```
|
|
@@ -199,7 +234,7 @@ Cursor can integrate this as a custom tool:
|
|
|
199
234
|
// Use in GitHub Actions or workflows
|
|
200
235
|
const { execSync } = require('child_process');
|
|
201
236
|
const result = JSON.parse(
|
|
202
|
-
execSync('npx rss-agent-discovery https://github.com/blog').toString()
|
|
237
|
+
execSync('npx -y rss-agent-discovery https://github.com/blog').toString()
|
|
203
238
|
);
|
|
204
239
|
```
|
|
205
240
|
|
|
@@ -209,7 +244,7 @@ const result = JSON.parse(
|
|
|
209
244
|
import { spawn } from 'child_process';
|
|
210
245
|
|
|
211
246
|
async function discoverRSS(url: string) {
|
|
212
|
-
const proc = spawn('npx', ['rss-agent-discovery', url]);
|
|
247
|
+
const proc = spawn('npx', ['-y', 'rss-agent-discovery', url]);
|
|
213
248
|
const chunks: Buffer[] = [];
|
|
214
249
|
|
|
215
250
|
for await (const chunk of proc.stdout) {
|
|
@@ -222,7 +257,7 @@ async function discoverRSS(url: string) {
|
|
|
222
257
|
|
|
223
258
|
### Why AI Agents Need This Tool
|
|
224
259
|
|
|
225
|
-
AI agents (Claude, Cursor,
|
|
260
|
+
AI agents (Claude, Cursor, ChatGPT Codex) struggle with RSS discovery because:
|
|
226
261
|
- They rely on web search which may miss feeds
|
|
227
262
|
- They don't systematically parse HTML `<link>` tags
|
|
228
263
|
- They give up after trying 2-3 common paths
|
|
@@ -239,7 +274,9 @@ npm run build
|
|
|
239
274
|
|
|
240
275
|
### Test:
|
|
241
276
|
```bash
|
|
242
|
-
npm test
|
|
277
|
+
npm test # Run all tests (unit + smoke)
|
|
278
|
+
npm run test:unit # Run unit tests only
|
|
279
|
+
npm run test:smoke # Run smoke tests (integration)
|
|
243
280
|
```
|
|
244
281
|
|
|
245
282
|
### Lint:
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
import { readFileSync } from 'fs';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
|
|
9
|
+
const packageDir = dirname(dirname(__filename));
|
|
10
|
+
const mainPath = join(packageDir, 'dist', 'find-rss-feeds.js');
|
|
11
|
+
|
|
12
|
+
await import(mainPath);
|
package/dist/find-rss-feeds.d.ts
CHANGED
|
@@ -1,2 +1,16 @@
|
|
|
1
|
+
interface CLIOptions {
|
|
2
|
+
help: boolean;
|
|
3
|
+
version: boolean;
|
|
4
|
+
verbose: boolean;
|
|
5
|
+
skipBlogs: boolean;
|
|
6
|
+
maxBlogs: number;
|
|
7
|
+
customBlogPaths: string[] | null;
|
|
8
|
+
timeout: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const cliOptions: CLIOptions;
|
|
11
|
+
export declare const COMMON_BLOG_PATHS: string[];
|
|
12
|
+
export declare function parseArgs(args: string[]): string[];
|
|
13
|
+
export declare function extractBlogLinksFromHTML(html: string, baseUrl: string): string[];
|
|
14
|
+
export declare function discoverBlogSubdirectories(baseUrl: string, html?: string | null): string[];
|
|
1
15
|
export {};
|
|
2
16
|
//# sourceMappingURL=find-rss-feeds.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-rss-feeds.d.ts","sourceRoot":"","sources":["../find-rss-feeds.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"find-rss-feeds.d.ts","sourceRoot":"","sources":["../find-rss-feeds.ts"],"names":[],"mappings":"AAkBA,UAAU,UAAU;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAmBD,eAAO,MAAM,UAAU,EAAE,UAQxB,CAAC;AASF,eAAO,MAAM,iBAAiB,UAkB7B,CAAC;AAEF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAwClD;AAkDD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAmDhF;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,IAAW,GAAG,MAAM,EAAE,CAiBhG"}
|
package/dist/find-rss-feeds.js
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import * as cheerio from 'cheerio';
|
|
2
|
-
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
// Load version from package.json at runtime
|
|
6
|
+
let CLI_VERSION = '0.0.0';
|
|
7
|
+
try {
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
const packageJsonPath = join(__dirname, '..', 'package.json');
|
|
11
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
12
|
+
CLI_VERSION = packageJson.version || '0.0.0';
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Fallback if package.json can't be read
|
|
16
|
+
CLI_VERSION = '0.0.0';
|
|
17
|
+
}
|
|
18
|
+
export const cliOptions = {
|
|
3
19
|
help: false,
|
|
20
|
+
version: false,
|
|
21
|
+
verbose: false,
|
|
4
22
|
skipBlogs: false,
|
|
5
23
|
maxBlogs: 5,
|
|
6
24
|
customBlogPaths: null,
|
|
@@ -12,7 +30,7 @@ const BLOG_KEYWORDS = [
|
|
|
12
30
|
'substack', 'the-edge', 'engineering-blog', 'dev',
|
|
13
31
|
'engineering', 'developers', 'community'
|
|
14
32
|
];
|
|
15
|
-
const COMMON_BLOG_PATHS = [
|
|
33
|
+
export const COMMON_BLOG_PATHS = [
|
|
16
34
|
'/blog',
|
|
17
35
|
'/news',
|
|
18
36
|
'/articles',
|
|
@@ -31,24 +49,47 @@ const COMMON_BLOG_PATHS = [
|
|
|
31
49
|
'/dev',
|
|
32
50
|
'/community'
|
|
33
51
|
];
|
|
34
|
-
function parseArgs(args) {
|
|
52
|
+
export function parseArgs(args) {
|
|
35
53
|
const urls = [];
|
|
36
54
|
for (let i = 0; i < args.length; i++) {
|
|
37
55
|
const arg = args[i];
|
|
38
56
|
if (arg === '--help' || arg === '-h') {
|
|
39
57
|
cliOptions.help = true;
|
|
40
58
|
}
|
|
59
|
+
else if (arg === '--version' || arg === '-V') {
|
|
60
|
+
cliOptions.version = true;
|
|
61
|
+
}
|
|
62
|
+
else if (arg === '--verbose' || arg === '-v') {
|
|
63
|
+
cliOptions.verbose = true;
|
|
64
|
+
}
|
|
41
65
|
else if (arg === '--no-blogs' || arg === '--skip-blogs') {
|
|
42
66
|
cliOptions.skipBlogs = true;
|
|
43
67
|
}
|
|
44
68
|
else if (arg === '--max-blogs') {
|
|
45
|
-
|
|
69
|
+
if (i + 1 >= args.length) {
|
|
70
|
+
throw new Error('--max-blogs requires a value');
|
|
71
|
+
}
|
|
72
|
+
const value = parseInt(args[++i], 10);
|
|
73
|
+
if (Number.isNaN(value) || value <= 0) {
|
|
74
|
+
throw new Error(`--max-blogs requires a positive number, got: ${args[i]}`);
|
|
75
|
+
}
|
|
76
|
+
cliOptions.maxBlogs = value;
|
|
46
77
|
}
|
|
47
78
|
else if (arg === '--blog-paths') {
|
|
48
|
-
|
|
79
|
+
if (i + 1 >= args.length || !args[i + 1].trim()) {
|
|
80
|
+
throw new Error('--blog-paths requires a value');
|
|
81
|
+
}
|
|
82
|
+
cliOptions.customBlogPaths = args[++i].split(/[,|]/).map(p => p.trim()).filter(Boolean);
|
|
49
83
|
}
|
|
50
84
|
else if (arg === '--timeout') {
|
|
51
|
-
|
|
85
|
+
if (i + 1 >= args.length) {
|
|
86
|
+
throw new Error('--timeout requires a value');
|
|
87
|
+
}
|
|
88
|
+
const value = parseInt(args[++i], 10);
|
|
89
|
+
if (Number.isNaN(value) || value <= 0) {
|
|
90
|
+
throw new Error(`--timeout requires a positive number, got: ${args[i]}`);
|
|
91
|
+
}
|
|
92
|
+
cliOptions.timeout = value;
|
|
52
93
|
}
|
|
53
94
|
else if (arg.startsWith('http://') || arg.startsWith('https://')) {
|
|
54
95
|
urls.push(arg);
|
|
@@ -70,12 +111,14 @@ Options:
|
|
|
70
111
|
Skip blog subdirectory scanning
|
|
71
112
|
--max-blogs <num> Maximum number of blog subdirectories to scan (default: 5)
|
|
72
113
|
--blog-paths <paths>
|
|
73
|
-
Comma-separated custom blog paths to try (e.g., '/blog,/news')
|
|
114
|
+
Comma- or pipe-separated custom blog paths to try (e.g., '/blog,/news' or '/blog|/news')
|
|
74
115
|
--timeout <ms> Timeout per URL in milliseconds (default: 10000)
|
|
116
|
+
--verbose, -v Log debug info to stderr
|
|
117
|
+
--version, -V Print version and exit
|
|
75
118
|
--help, -h Show this help message
|
|
76
119
|
|
|
77
120
|
Exit codes:
|
|
78
|
-
0 One or more feeds found
|
|
121
|
+
0 One or more feeds found (or --help/--version)
|
|
79
122
|
1 No feeds found
|
|
80
123
|
2 Error occurred
|
|
81
124
|
|
|
@@ -101,7 +144,7 @@ Output schema:
|
|
|
101
144
|
}
|
|
102
145
|
`);
|
|
103
146
|
}
|
|
104
|
-
function extractBlogLinksFromHTML(html, baseUrl) {
|
|
147
|
+
export function extractBlogLinksFromHTML(html, baseUrl) {
|
|
105
148
|
const $ = cheerio.load(html);
|
|
106
149
|
const blogPaths = new Set();
|
|
107
150
|
const linkTextAndUrls = [];
|
|
@@ -127,9 +170,8 @@ function extractBlogLinksFromHTML(html, baseUrl) {
|
|
|
127
170
|
for (const link of linkTextAndUrls) {
|
|
128
171
|
if (seenPaths.has(link.path))
|
|
129
172
|
continue;
|
|
130
|
-
const lowerText = link.text.toLowerCase();
|
|
131
173
|
const lowerPath = link.path.toLowerCase();
|
|
132
|
-
const foundKeyword = BLOG_KEYWORDS.find(keyword =>
|
|
174
|
+
const foundKeyword = BLOG_KEYWORDS.find(keyword => link.text.includes(keyword) ||
|
|
133
175
|
lowerPath.includes(keyword));
|
|
134
176
|
if (foundKeyword) {
|
|
135
177
|
if (link.path.startsWith('/') && link.path !== '/') {
|
|
@@ -147,7 +189,7 @@ function extractBlogLinksFromHTML(html, baseUrl) {
|
|
|
147
189
|
}
|
|
148
190
|
return Array.from(blogPaths);
|
|
149
191
|
}
|
|
150
|
-
function discoverBlogSubdirectories(baseUrl, html = null) {
|
|
192
|
+
export function discoverBlogSubdirectories(baseUrl, html = null) {
|
|
151
193
|
let blogPaths = [];
|
|
152
194
|
if (html) {
|
|
153
195
|
blogPaths = extractBlogLinksFromHTML(html, baseUrl);
|
|
@@ -162,11 +204,12 @@ function discoverBlogSubdirectories(baseUrl, html = null) {
|
|
|
162
204
|
}
|
|
163
205
|
return blogPaths.slice(0, cliOptions.maxBlogs);
|
|
164
206
|
}
|
|
165
|
-
async function scanURLForFeeds(url) {
|
|
207
|
+
async function scanURLForFeeds(url, signal) {
|
|
166
208
|
const discoveredFeeds = new Map();
|
|
167
209
|
try {
|
|
168
210
|
const res = await fetch(url, {
|
|
169
|
-
|
|
211
|
+
signal,
|
|
212
|
+
headers: { 'User-Agent': `rss-agent-discovery/${CLI_VERSION}` }
|
|
170
213
|
});
|
|
171
214
|
if (!res.ok) {
|
|
172
215
|
throw new Error(`Failed to fetch ${url}: ${res.status}`);
|
|
@@ -186,7 +229,10 @@ async function scanURLForFeeds(url) {
|
|
|
186
229
|
discoveredFeeds.set(fullHref, { url: fullHref, title, type: feedType });
|
|
187
230
|
}
|
|
188
231
|
}
|
|
189
|
-
catch {
|
|
232
|
+
catch (e) {
|
|
233
|
+
if (cliOptions.verbose) {
|
|
234
|
+
console.error(`Skipping invalid feed href: ${href}`, e.message);
|
|
235
|
+
}
|
|
190
236
|
}
|
|
191
237
|
}
|
|
192
238
|
}
|
|
@@ -207,25 +253,36 @@ async function scanURLForFeeds(url) {
|
|
|
207
253
|
});
|
|
208
254
|
}
|
|
209
255
|
}
|
|
210
|
-
catch {
|
|
256
|
+
catch (e) {
|
|
257
|
+
if (cliOptions.verbose) {
|
|
258
|
+
console.error(`Skipping invalid candidate URL: ${path}`, e.message);
|
|
259
|
+
}
|
|
211
260
|
}
|
|
212
261
|
}
|
|
213
262
|
const validFeeds = [];
|
|
214
263
|
for (const [feedUrl, feed] of Array.from(discoveredFeeds)) {
|
|
215
264
|
try {
|
|
216
265
|
const res = await fetch(feedUrl, {
|
|
217
|
-
|
|
266
|
+
signal,
|
|
267
|
+
headers: { 'User-Agent': `rss-agent-discovery/${CLI_VERSION}` }
|
|
218
268
|
});
|
|
219
269
|
if (res.ok) {
|
|
220
270
|
const contentType = res.headers.get('content-type') || '';
|
|
221
271
|
const text = await res.text();
|
|
222
|
-
|
|
223
|
-
|
|
272
|
+
// Stricter validation: require XML declaration or XML content-type, and root-level RSS/Atom element
|
|
273
|
+
const hasXmlDeclaration = text.trimStart().startsWith('<?xml') || text.includes('<?xml');
|
|
274
|
+
const hasXmlContentType = contentType.includes('xml') || contentType.includes('rss') || contentType.includes('atom');
|
|
275
|
+
const hasRssOrFeed = text.includes('<rss') || text.includes('<feed');
|
|
276
|
+
const isHtml = contentType.includes('text/html');
|
|
277
|
+
if (hasRssOrFeed && (hasXmlDeclaration || hasXmlContentType) && !isHtml) {
|
|
224
278
|
validFeeds.push(feed);
|
|
225
279
|
}
|
|
226
280
|
}
|
|
227
281
|
}
|
|
228
|
-
catch {
|
|
282
|
+
catch (e) {
|
|
283
|
+
if (cliOptions.verbose) {
|
|
284
|
+
console.error(`Failed to validate feed ${feedUrl}:`, e.message);
|
|
285
|
+
}
|
|
229
286
|
}
|
|
230
287
|
}
|
|
231
288
|
return { html, feeds: validFeeds };
|
|
@@ -237,14 +294,9 @@ async function scanURLForFeeds(url) {
|
|
|
237
294
|
}
|
|
238
295
|
async function findRSSFeeds(baseUrl) {
|
|
239
296
|
const timeoutMs = cliOptions.timeout;
|
|
240
|
-
const
|
|
241
|
-
setTimeout(() => reject(new Error('Timeout')), timeoutMs);
|
|
242
|
-
});
|
|
297
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
243
298
|
try {
|
|
244
|
-
const scanResult = await
|
|
245
|
-
scanURLForFeeds(baseUrl),
|
|
246
|
-
timeoutPromise
|
|
247
|
-
]);
|
|
299
|
+
const scanResult = await scanURLForFeeds(baseUrl, signal);
|
|
248
300
|
const allFeeds = new Map();
|
|
249
301
|
scanResult.feeds.forEach(feed => {
|
|
250
302
|
if (!allFeeds.has(feed.url)) {
|
|
@@ -262,10 +314,7 @@ async function findRSSFeeds(baseUrl) {
|
|
|
262
314
|
return null;
|
|
263
315
|
}
|
|
264
316
|
}).filter((url) => url !== null);
|
|
265
|
-
const blogResults = await Promise.allSettled(blogURLs.map(blogUrl =>
|
|
266
|
-
scanURLForFeeds(blogUrl),
|
|
267
|
-
timeoutPromise
|
|
268
|
-
])));
|
|
317
|
+
const blogResults = await Promise.allSettled(blogURLs.map(blogUrl => scanURLForFeeds(blogUrl, signal)));
|
|
269
318
|
blogResults.forEach((result) => {
|
|
270
319
|
if (result.status === 'fulfilled') {
|
|
271
320
|
result.value.feeds.forEach((feed) => {
|
|
@@ -284,7 +333,14 @@ async function findRSSFeeds(baseUrl) {
|
|
|
284
333
|
};
|
|
285
334
|
}
|
|
286
335
|
catch (e) {
|
|
287
|
-
|
|
336
|
+
let errorMessage = e.message;
|
|
337
|
+
// Handle abort/timeout errors
|
|
338
|
+
if (e instanceof DOMException && e.name === 'AbortError') {
|
|
339
|
+
errorMessage = 'Timeout';
|
|
340
|
+
}
|
|
341
|
+
else if (errorMessage === 'Timeout') {
|
|
342
|
+
errorMessage = 'Timeout';
|
|
343
|
+
}
|
|
288
344
|
console.error(`Error processing ${baseUrl}: ${errorMessage}`);
|
|
289
345
|
return {
|
|
290
346
|
url: baseUrl,
|
|
@@ -295,10 +351,21 @@ async function findRSSFeeds(baseUrl) {
|
|
|
295
351
|
}
|
|
296
352
|
async function main() {
|
|
297
353
|
const args = process.argv.slice(2);
|
|
298
|
-
|
|
354
|
+
let urls;
|
|
355
|
+
try {
|
|
356
|
+
urls = parseArgs(args);
|
|
357
|
+
}
|
|
358
|
+
catch (e) {
|
|
359
|
+
console.error(`Error: ${e.message}`);
|
|
360
|
+
return 2;
|
|
361
|
+
}
|
|
362
|
+
if (cliOptions.version) {
|
|
363
|
+
console.log(CLI_VERSION);
|
|
364
|
+
return 0;
|
|
365
|
+
}
|
|
299
366
|
if (cliOptions.help) {
|
|
300
367
|
showHelp();
|
|
301
|
-
return
|
|
368
|
+
return 0;
|
|
302
369
|
}
|
|
303
370
|
if (urls.length === 0) {
|
|
304
371
|
console.error('Error: No URLs provided. Use --help for usage information.');
|
|
@@ -321,6 +388,9 @@ async function main() {
|
|
|
321
388
|
success: !hasError,
|
|
322
389
|
results: results
|
|
323
390
|
};
|
|
391
|
+
if (hasError && totalFeedsFound > 0) {
|
|
392
|
+
output.partialResults = true;
|
|
393
|
+
}
|
|
324
394
|
console.log(JSON.stringify(output, null, 2));
|
|
325
395
|
if (hasError) {
|
|
326
396
|
return 2;
|
|
@@ -332,14 +402,22 @@ async function main() {
|
|
|
332
402
|
return 0;
|
|
333
403
|
}
|
|
334
404
|
}
|
|
335
|
-
main
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
})
|
|
405
|
+
// Only run main if this file is executed directly or imported by the bin script
|
|
406
|
+
// Skip if imported by test files (they have .test.js in the caller)
|
|
407
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
408
|
+
const isMainModule = process.argv[1] === currentFile ||
|
|
409
|
+
process.argv[1]?.endsWith('find-rss-feeds.js') ||
|
|
410
|
+
(process.argv[1]?.includes('rss-agent-discovery') && !process.argv[1]?.includes('.test.'));
|
|
411
|
+
if (isMainModule) {
|
|
412
|
+
main().then(exitCode => {
|
|
413
|
+
process.exit(exitCode);
|
|
414
|
+
}).catch(e => {
|
|
415
|
+
console.error(JSON.stringify({
|
|
416
|
+
success: false,
|
|
417
|
+
error: e.message,
|
|
418
|
+
results: []
|
|
419
|
+
}, null, 2));
|
|
420
|
+
process.exit(2);
|
|
421
|
+
});
|
|
422
|
+
}
|
|
345
423
|
//# sourceMappingURL=find-rss-feeds.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-rss-feeds.js","sourceRoot":"","sources":["../find-rss-feeds.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"find-rss-feeds.js","sourceRoot":"","sources":["../find-rss-feeds.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-rss-feeds.test.d.ts","sourceRoot":"","sources":["../find-rss-feeds.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
// Note: This file tests the compiled code in dist/
|
|
4
|
+
// Import will be resolved to dist/find-rss-feeds.js after build
|
|
5
|
+
import { parseArgs, extractBlogLinksFromHTML, discoverBlogSubdirectories, cliOptions, COMMON_BLOG_PATHS } from './find-rss-feeds.js';
|
|
6
|
+
// Reset cliOptions before each test
|
|
7
|
+
function resetCliOptions() {
|
|
8
|
+
cliOptions.help = false;
|
|
9
|
+
cliOptions.version = false;
|
|
10
|
+
cliOptions.verbose = false;
|
|
11
|
+
cliOptions.skipBlogs = false;
|
|
12
|
+
cliOptions.maxBlogs = 5;
|
|
13
|
+
cliOptions.customBlogPaths = null;
|
|
14
|
+
cliOptions.timeout = 10000;
|
|
15
|
+
}
|
|
16
|
+
test('parseArgs - valid flags and URLs', () => {
|
|
17
|
+
resetCliOptions();
|
|
18
|
+
const urls = parseArgs(['https://example.com', 'https://test.com']);
|
|
19
|
+
assert.strictEqual(urls.length, 2);
|
|
20
|
+
assert.strictEqual(urls[0], 'https://example.com');
|
|
21
|
+
assert.strictEqual(urls[1], 'https://test.com');
|
|
22
|
+
});
|
|
23
|
+
test('parseArgs - --help sets help flag', () => {
|
|
24
|
+
resetCliOptions();
|
|
25
|
+
parseArgs(['--help']);
|
|
26
|
+
assert.strictEqual(cliOptions.help, true);
|
|
27
|
+
});
|
|
28
|
+
test('parseArgs - --version / -V sets version flag', () => {
|
|
29
|
+
resetCliOptions();
|
|
30
|
+
parseArgs(['--version']);
|
|
31
|
+
assert.strictEqual(cliOptions.version, true);
|
|
32
|
+
resetCliOptions();
|
|
33
|
+
parseArgs(['-V']);
|
|
34
|
+
assert.strictEqual(cliOptions.version, true);
|
|
35
|
+
});
|
|
36
|
+
test('parseArgs - --verbose / -v sets verbose flag', () => {
|
|
37
|
+
resetCliOptions();
|
|
38
|
+
parseArgs(['--verbose']);
|
|
39
|
+
assert.strictEqual(cliOptions.verbose, true);
|
|
40
|
+
resetCliOptions();
|
|
41
|
+
parseArgs(['-v']);
|
|
42
|
+
assert.strictEqual(cliOptions.verbose, true);
|
|
43
|
+
});
|
|
44
|
+
test('parseArgs - --timeout missing value throws error', () => {
|
|
45
|
+
resetCliOptions();
|
|
46
|
+
assert.throws(() => {
|
|
47
|
+
parseArgs(['--timeout']);
|
|
48
|
+
}, /--timeout requires a value/);
|
|
49
|
+
});
|
|
50
|
+
test('parseArgs - --timeout invalid number throws error', () => {
|
|
51
|
+
resetCliOptions();
|
|
52
|
+
assert.throws(() => {
|
|
53
|
+
parseArgs(['--timeout', 'invalid']);
|
|
54
|
+
}, /--timeout requires a positive number/);
|
|
55
|
+
resetCliOptions();
|
|
56
|
+
assert.throws(() => {
|
|
57
|
+
parseArgs(['--timeout', '0']);
|
|
58
|
+
}, /--timeout requires a positive number/);
|
|
59
|
+
resetCliOptions();
|
|
60
|
+
assert.throws(() => {
|
|
61
|
+
parseArgs(['--timeout', '-5']);
|
|
62
|
+
}, /--timeout requires a positive number/);
|
|
63
|
+
});
|
|
64
|
+
test('parseArgs - --timeout valid value sets timeout', () => {
|
|
65
|
+
resetCliOptions();
|
|
66
|
+
parseArgs(['--timeout', '15000']);
|
|
67
|
+
assert.strictEqual(cliOptions.timeout, 15000);
|
|
68
|
+
});
|
|
69
|
+
test('parseArgs - --max-blogs missing value throws error', () => {
|
|
70
|
+
resetCliOptions();
|
|
71
|
+
assert.throws(() => {
|
|
72
|
+
parseArgs(['--max-blogs']);
|
|
73
|
+
}, /--max-blogs requires a value/);
|
|
74
|
+
});
|
|
75
|
+
test('parseArgs - --max-blogs invalid number throws error', () => {
|
|
76
|
+
resetCliOptions();
|
|
77
|
+
assert.throws(() => {
|
|
78
|
+
parseArgs(['--max-blogs', 'invalid']);
|
|
79
|
+
}, /--max-blogs requires a positive number/);
|
|
80
|
+
});
|
|
81
|
+
test('parseArgs - --max-blogs valid value sets maxBlogs', () => {
|
|
82
|
+
resetCliOptions();
|
|
83
|
+
parseArgs(['--max-blogs', '10']);
|
|
84
|
+
assert.strictEqual(cliOptions.maxBlogs, 10);
|
|
85
|
+
});
|
|
86
|
+
test('parseArgs - --blog-paths missing value throws error', () => {
|
|
87
|
+
resetCliOptions();
|
|
88
|
+
assert.throws(() => {
|
|
89
|
+
parseArgs(['--blog-paths']);
|
|
90
|
+
}, /--blog-paths requires a value/);
|
|
91
|
+
});
|
|
92
|
+
test('parseArgs - --blog-paths with comma separator', () => {
|
|
93
|
+
resetCliOptions();
|
|
94
|
+
parseArgs(['--blog-paths', '/blog,/news']);
|
|
95
|
+
assert.deepStrictEqual(cliOptions.customBlogPaths, ['/blog', '/news']);
|
|
96
|
+
});
|
|
97
|
+
test('parseArgs - --blog-paths with pipe separator', () => {
|
|
98
|
+
resetCliOptions();
|
|
99
|
+
parseArgs(['--blog-paths', '/blog|/news']);
|
|
100
|
+
assert.deepStrictEqual(cliOptions.customBlogPaths, ['/blog', '/news']);
|
|
101
|
+
});
|
|
102
|
+
test('parseArgs - --blog-paths with mixed separators', () => {
|
|
103
|
+
resetCliOptions();
|
|
104
|
+
parseArgs(['--blog-paths', '/blog,/news|/updates']);
|
|
105
|
+
assert.deepStrictEqual(cliOptions.customBlogPaths, ['/blog', '/news', '/updates']);
|
|
106
|
+
});
|
|
107
|
+
test('extractBlogLinksFromHTML - finds blog links', () => {
|
|
108
|
+
const html = `
|
|
109
|
+
<html>
|
|
110
|
+
<body>
|
|
111
|
+
<a href="/blog">Blog</a>
|
|
112
|
+
<a href="/news">News</a>
|
|
113
|
+
<a href="/articles">Articles</a>
|
|
114
|
+
<a href="https://external.com/blog">External</a>
|
|
115
|
+
</body>
|
|
116
|
+
</html>
|
|
117
|
+
`;
|
|
118
|
+
const paths = extractBlogLinksFromHTML(html, 'https://example.com');
|
|
119
|
+
assert.ok(paths.length > 0, 'Should find blog paths');
|
|
120
|
+
assert.ok(paths.includes('/blog'), 'Should include /blog');
|
|
121
|
+
});
|
|
122
|
+
test('extractBlogLinksFromHTML - only same-origin links', () => {
|
|
123
|
+
const html = `
|
|
124
|
+
<html>
|
|
125
|
+
<body>
|
|
126
|
+
<a href="/blog">Blog</a>
|
|
127
|
+
<a href="https://external.com/blog">External</a>
|
|
128
|
+
</body>
|
|
129
|
+
</html>
|
|
130
|
+
`;
|
|
131
|
+
const paths = extractBlogLinksFromHTML(html, 'https://example.com');
|
|
132
|
+
assert.ok(!paths.includes('https://external.com/blog'), 'Should not include external links');
|
|
133
|
+
});
|
|
134
|
+
test('extractBlogLinksFromHTML - keyword matching', () => {
|
|
135
|
+
const html = `
|
|
136
|
+
<html>
|
|
137
|
+
<body>
|
|
138
|
+
<a href="/blog">Blog</a>
|
|
139
|
+
<a href="/random">Random</a>
|
|
140
|
+
</body>
|
|
141
|
+
</html>
|
|
142
|
+
`;
|
|
143
|
+
const paths = extractBlogLinksFromHTML(html, 'https://example.com');
|
|
144
|
+
assert.ok(paths.includes('/blog'), 'Should find /blog via keyword');
|
|
145
|
+
});
|
|
146
|
+
test('discoverBlogSubdirectories - uses custom paths when provided', () => {
|
|
147
|
+
resetCliOptions();
|
|
148
|
+
cliOptions.customBlogPaths = ['/custom1', '/custom2'];
|
|
149
|
+
cliOptions.maxBlogs = 10;
|
|
150
|
+
const paths = discoverBlogSubdirectories('https://example.com');
|
|
151
|
+
assert.ok(paths.includes('/custom1'));
|
|
152
|
+
assert.ok(paths.includes('/custom2'));
|
|
153
|
+
});
|
|
154
|
+
test('discoverBlogSubdirectories - respects maxBlogs limit', () => {
|
|
155
|
+
resetCliOptions();
|
|
156
|
+
cliOptions.maxBlogs = 3;
|
|
157
|
+
const paths = discoverBlogSubdirectories('https://example.com');
|
|
158
|
+
assert.strictEqual(paths.length, 3);
|
|
159
|
+
});
|
|
160
|
+
test('discoverBlogSubdirectories - falls back to COMMON_BLOG_PATHS when no HTML', () => {
|
|
161
|
+
resetCliOptions();
|
|
162
|
+
cliOptions.customBlogPaths = null;
|
|
163
|
+
const paths = discoverBlogSubdirectories('https://example.com', null);
|
|
164
|
+
assert.ok(paths.length > 0);
|
|
165
|
+
assert.ok(paths.some(p => COMMON_BLOG_PATHS.includes(p)));
|
|
166
|
+
});
|
|
167
|
+
test('feed validation logic - valid RSS should pass', () => {
|
|
168
|
+
const validRSS = `<?xml version="1.0"?>
|
|
169
|
+
<rss version="2.0">
|
|
170
|
+
<channel>
|
|
171
|
+
<title>Test Feed</title>
|
|
172
|
+
</channel>
|
|
173
|
+
</rss>`;
|
|
174
|
+
const contentType = 'application/rss+xml';
|
|
175
|
+
const hasXmlDeclaration = validRSS.trimStart().startsWith('<?xml') || validRSS.includes('<?xml');
|
|
176
|
+
const hasXmlContentType = contentType.includes('xml') || contentType.includes('rss') || contentType.includes('atom');
|
|
177
|
+
const hasRssOrFeed = validRSS.includes('<rss') || validRSS.includes('<feed');
|
|
178
|
+
const isHtml = contentType.includes('text/html');
|
|
179
|
+
assert.ok(hasXmlDeclaration);
|
|
180
|
+
assert.ok(hasXmlContentType);
|
|
181
|
+
assert.ok(hasRssOrFeed);
|
|
182
|
+
assert.ok(!isHtml);
|
|
183
|
+
assert.ok(hasRssOrFeed && (hasXmlDeclaration || hasXmlContentType) && !isHtml);
|
|
184
|
+
});
|
|
185
|
+
test('feed validation logic - HTML with <rss> should be rejected', () => {
|
|
186
|
+
const htmlWithRss = `<html>
|
|
187
|
+
<body>
|
|
188
|
+
<p>Check out our <rss> feed!</p>
|
|
189
|
+
</body>
|
|
190
|
+
</html>`;
|
|
191
|
+
const contentType = 'text/html';
|
|
192
|
+
const hasXmlDeclaration = htmlWithRss.trimStart().startsWith('<?xml') || htmlWithRss.includes('<?xml');
|
|
193
|
+
const hasXmlContentType = contentType.includes('xml') || contentType.includes('rss') || contentType.includes('atom');
|
|
194
|
+
const hasRssOrFeed = htmlWithRss.includes('<rss') || htmlWithRss.includes('<feed');
|
|
195
|
+
const isHtml = contentType.includes('text/html');
|
|
196
|
+
assert.ok(isHtml, 'Should detect HTML content type');
|
|
197
|
+
assert.ok(!(hasRssOrFeed && (hasXmlDeclaration || hasXmlContentType) && !isHtml), 'Should reject HTML');
|
|
198
|
+
});
|
|
199
|
+
test('feed validation logic - valid Atom should pass', () => {
|
|
200
|
+
const validAtom = `<?xml version="1.0"?>
|
|
201
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
|
202
|
+
<title>Test Feed</title>
|
|
203
|
+
</feed>`;
|
|
204
|
+
const contentType = 'application/atom+xml';
|
|
205
|
+
const hasXmlDeclaration = validAtom.trimStart().startsWith('<?xml') || validAtom.includes('<?xml');
|
|
206
|
+
const hasXmlContentType = contentType.includes('xml') || contentType.includes('rss') || contentType.includes('atom');
|
|
207
|
+
const hasRssOrFeed = validAtom.includes('<rss') || validAtom.includes('<feed');
|
|
208
|
+
const isHtml = contentType.includes('text/html');
|
|
209
|
+
assert.ok(hasXmlDeclaration);
|
|
210
|
+
assert.ok(hasXmlContentType);
|
|
211
|
+
assert.ok(hasRssOrFeed);
|
|
212
|
+
assert.ok(!isHtml);
|
|
213
|
+
assert.ok(hasRssOrFeed && (hasXmlDeclaration || hasXmlContentType) && !isHtml);
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=find-rss-feeds.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-rss-feeds.test.js","sourceRoot":"","sources":["../find-rss-feeds.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rss-agent-discovery",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "AI agent-focused RSS feed discovery. JSON output, semantic exit codes.",
|
|
5
5
|
"main": "dist/find-rss-feeds.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"rss-agent-discovery": "
|
|
9
|
-
"rss-discover": "
|
|
8
|
+
"rss-agent-discovery": "bin/rss-agent-discovery",
|
|
9
|
+
"rss-discover": "bin/rss-agent-discovery"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
|
-
"dist"
|
|
12
|
+
"dist",
|
|
13
|
+
"bin"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
15
16
|
"build": "tsc",
|
|
16
17
|
"start": "node dist/find-rss-feeds.js",
|
|
17
18
|
"dev": "tsc && node dist/find-rss-feeds.js",
|
|
18
|
-
"test": "npm run
|
|
19
|
+
"test": "npm run test:unit && npm run test:smoke",
|
|
20
|
+
"test:unit": "npm run build && node --test dist/find-rss-feeds.test.js",
|
|
21
|
+
"test:smoke": "npm run build && node dist/find-rss-feeds.js https://vercel.com https://news.ycombinator.com | jq",
|
|
19
22
|
"prepublishOnly": "npm run build"
|
|
20
23
|
},
|
|
21
24
|
"keywords": [
|
|
@@ -29,6 +32,17 @@
|
|
|
29
32
|
"json"
|
|
30
33
|
],
|
|
31
34
|
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/brooksy4503/rss-agent-discovery.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/brooksy4503/rss-agent-discovery/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/brooksy4503/rss-agent-discovery#readme",
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
},
|
|
32
46
|
"dependencies": {
|
|
33
47
|
"cheerio": "^1.0.0"
|
|
34
48
|
},
|