dsh-rss 0.4.0 → 0.4.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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 stardustlc
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 stardustlc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md CHANGED
@@ -1,103 +1,109 @@
1
- # dsh-rss
2
-
3
- ![npm](https://img.shields.io/npm/v/dsh-rss) ![downloads](https://img.shields.io/npm/dm/dsh-rss) ![license](https://img.shields.io/github/license/STARDUSTLC666/dsh-rss) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-rss?style=social)
4
-
5
- [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
6
-
7
- DSH (DeepSeek Harness) plugin for RSS/Atom subscriptions: manage feeds, fetch and parse RSS 0.9x / 1.0 / 2.0 and Atom, with OPML bulk import/export, exposing nine model-facing tools.
8
-
9
- ## Compatibility
10
-
11
- Version 0.4.0 supports official-source Harness **0.1.7-alpha.2** (2026-09-23, with a local `Symbol.for` tool-scheduler fix). All 18 plugins load together; tool contracts, subscription updates and restart persistence pass in isolation. Live feeds require working network access. Requires Node 22.19 or later within 22.x, or 24 or later.
12
-
13
- Fetches honor the Harness cancellation signal through DNS, response streaming, and cross-feed searches. Hostname preflight checks reject loopback, private, and link-local addresses by default, including redirect destinations. Set `allowPrivateNetwork: true` for trusted internal feeds.
14
-
15
- `rss_opml_export.path` is relative to the calling session's workspace, with an existing parent directory. Absolute paths, traversal, and links outside the workspace are rejected; the result returns the absolute written path. File writes request Harness approval by default (`opmlWriteApproval: false` disables this gate). Omit `path` to return only OPML text.
16
-
17
- ## Installation
18
-
19
- ```bash
20
- dsh plugin --profile web add dsh-rss
21
- ```
22
-
23
- Restart the web service after installing. Ask your assistant to subscribe to an RSS URL or list your subscriptions; ordinary subscription management needs no configuration-file editing.
24
-
25
- ## Uninstall
26
-
27
- ```bash
28
- dsh plugin --profile web remove dsh-rss
29
- ```
30
-
31
- Then restart the web service. To clean up fully, also remove the plugin entry from your profile `cordis.patch.yml` if you overrode it.
32
-
33
-
34
- ## Configuration
35
-
36
- Override the plugin row in your profile's `cordis.patch.yml` (the plugin also loads with all defaults when absent):
37
-
38
- ```yaml
39
- - id: rss
40
- name: 'dsh-rss'
41
- config:
42
- # proxyUrl: http://127.0.0.1:7890 # enable when a feed needs a special proxy
43
- timeoutMs: 15000 # fetch timeout in ms (default 15000)
44
- # maxBodyBytes: 5242880 # response size cap (default 5MB, guards oversized responses)
45
- # userAgent: 'dsh-rss/0.2.0' # custom fetch UA
46
- # feedsYaml: | # optional: pre-seed subscriptions (or use the rss_add tool)
47
- # - url: https://example.com/feed.xml
48
- # name: My feed
49
- # category: tech
50
- ```
51
-
52
- ## Tools
53
-
54
- | Tool | Purpose | Key parameters |
55
- | :-- | :-- | :-- |
56
- | `rss_list` | List subscribed feeds | none |
57
- | `rss_add` | Add a subscription (fetches and validates the URL first) | `url` required; `name`/`category` optional |
58
- | `rss_remove` | Remove a subscription | `url` or `name`, at least one |
59
- | `rss_fetch` | Fetch and parse a feed, returning feed info and entries (with full `content`) | `url` or `name`, at least one; `limit` 1-100, default 20 |
60
- | `rss_check` | Validate that a URL is a parseable feed | `url` required |
61
- | `rss_opml_export` | Export subscriptions as OPML 2.0 text (optionally write a file) | `path` optional |
62
- | `rss_opml_import` | Bulk-import subscriptions from OPML 2.0 text | `opml` required |
63
-
64
- | `rss_search` | Search across feeds | `query` required; optional feed, date and limit filters |
65
- | `rss_health` | Check configuration, feeds and cursors offline | none |
66
-
67
- ### Examples
68
-
69
- ```text
70
- rss_add { url: https://example.com/feed.xml, name: my-feed }
71
- rss_fetch { name: my-feed, limit: 10 }
72
- rss_check { url: https://example.com/feed.xml }
73
- rss_opml_export { path: subscriptions.opml }
74
- rss_opml_import { opml: "<?xml version=\"1.0\"?>..." }
75
- ```
76
-
77
- ## Subscriptions
78
-
79
- On Harness 0.1.7, subscriptions and read cursors are stored in the current profile’s `rss` entry. Changes apply immediately and survive restart. Default installations automatically import the retired `dsh-rss` section from `settings.yaml` or `settings.yaml.imported` once, preserving the original file and existing profile values. Older hosts retain their original settings storage. Use a URL to distinguish feeds with identical names.
80
-
81
- ## Proxy
82
-
83
- Most feeds are reachable directly; a few require a special proxy from your network. When you hit a `fetch failed` error suggesting a proxy, set `proxyUrl` to your local proxy address (e.g. `http://127.0.0.1:7890`) and restart. The proxy only routes this plugin's fetch requests and does not affect other plugins in the same process.
84
-
85
- ## Parsing capabilities
86
-
87
- - RSS 2.0 / RSS 1.0 (RDF) / Atom, normalized to one output shape
88
- - Entity decoding, CDATA, `content:encoded`, `dc:creator` and other common fields
89
- - RFC 822 / ISO 8601 dates normalized to ISO 8601 UTC (`pubDate`); the raw text stays in `pubDateRaw`
90
- - Relative links resolved against the feed URL
91
- - Summaries stripped of HTML tags and truncated at 500 chars; RSS `content:encoded` / Atom `content` is preserved as a `content` field (tags stripped, up to 20000 chars)
92
- - Safety: no DTD / external entity parsing; 5MB body cap; configurable fetch timeout
93
-
94
- ## Development
95
-
96
- ```bash
97
- pnpm install
98
- pnpm test # build + offline tests with explicit fetch and DNS fixtures
99
- ```
100
-
101
- ## License
102
-
103
- MIT
1
+ # dsh-rss
2
+
3
+ ## 0.4.1 update (2026-09-27)
4
+
5
+ Explains feed resolution failures caused by proxy Fake-IP DNS and suggests using a real DNS address while keeping reserved-address protection enabled.
6
+
7
+ Validation host: Harness `0.2.0-rc.1` built from official sources (commit `407e65c8`) with Node `24.16.0` on 2026-09-28. All 77 plugin tests pass in an isolated environment; all 18 plugins mount together in one host registering 9 tools, with tool schemas and health-check contracts passing. No live ports or external services were exercised in this round.
8
+
9
+ ![npm](https://img.shields.io/npm/v/dsh-rss) ![downloads](https://img.shields.io/npm/dm/dsh-rss) ![license](https://img.shields.io/github/license/STARDUSTLC666/dsh-rss) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-rss?style=social)
10
+
11
+ [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
12
+
13
+ DSH (DeepSeek Harness) plugin for RSS/Atom subscriptions: manage feeds, fetch and parse RSS 0.9x / 1.0 / 2.0 and Atom, with OPML bulk import/export, exposing nine model-facing tools.
14
+
15
+ ## Compatibility
16
+
17
+ Version 0.4.0 supports official-source Harness **0.1.7-alpha.2** (2026-09-23, with a local `Symbol.for` tool-scheduler fix). All 18 plugins load together; tool contracts, subscription updates and restart persistence pass in isolation. Live feeds require working network access. Requires Node 22.19 or later within 22.x, or 24 or later.
18
+
19
+ Fetches honor the Harness cancellation signal through DNS, response streaming, and cross-feed searches. Hostname preflight checks reject loopback, private, and link-local addresses by default, including redirect destinations. Set `allowPrivateNetwork: true` for trusted internal feeds.
20
+
21
+ `rss_opml_export.path` is relative to the calling session's workspace, with an existing parent directory. Absolute paths, traversal, and links outside the workspace are rejected; the result returns the absolute written path. File writes request Harness approval by default (`opmlWriteApproval: false` disables this gate). Omit `path` to return only OPML text.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ dsh plugin --profile web add dsh-rss
27
+ ```
28
+
29
+ Restart the web service after installing. Ask your assistant to subscribe to an RSS URL or list your subscriptions; ordinary subscription management needs no configuration-file editing.
30
+
31
+ ## Uninstall
32
+
33
+ ```bash
34
+ dsh plugin --profile web remove dsh-rss
35
+ ```
36
+
37
+ Then restart the web service. To clean up fully, also remove the plugin entry from your profile `cordis.patch.yml` if you overrode it.
38
+
39
+
40
+ ## Configuration
41
+
42
+ Override the plugin row in your profile's `cordis.patch.yml` (the plugin also loads with all defaults when absent):
43
+
44
+ ```yaml
45
+ - id: rss
46
+ name: 'dsh-rss'
47
+ config:
48
+ # proxyUrl: http://127.0.0.1:7890 # enable when a feed needs a special proxy
49
+ timeoutMs: 15000 # fetch timeout in ms (default 15000)
50
+ # maxBodyBytes: 5242880 # response size cap (default 5MB, guards oversized responses)
51
+ # userAgent: 'dsh-rss/0.2.0' # custom fetch UA
52
+ # feedsYaml: | # optional: pre-seed subscriptions (or use the rss_add tool)
53
+ # - url: https://example.com/feed.xml
54
+ # name: My feed
55
+ # category: tech
56
+ ```
57
+
58
+ ## Tools
59
+
60
+ | Tool | Purpose | Key parameters |
61
+ | :-- | :-- | :-- |
62
+ | `rss_list` | List subscribed feeds | none |
63
+ | `rss_add` | Add a subscription (fetches and validates the URL first) | `url` required; `name`/`category` optional |
64
+ | `rss_remove` | Remove a subscription | `url` or `name`, at least one |
65
+ | `rss_fetch` | Fetch and parse a feed, returning feed info and entries (with full `content`) | `url` or `name`, at least one; `limit` 1-100, default 20 |
66
+ | `rss_check` | Validate that a URL is a parseable feed | `url` required |
67
+ | `rss_opml_export` | Export subscriptions as OPML 2.0 text (optionally write a file) | `path` optional |
68
+ | `rss_opml_import` | Bulk-import subscriptions from OPML 2.0 text | `opml` required |
69
+
70
+ | `rss_search` | Search across feeds | `query` required; optional feed, date and limit filters |
71
+ | `rss_health` | Check configuration, feeds and cursors offline | none |
72
+
73
+ ### Examples
74
+
75
+ ```text
76
+ rss_add { url: https://example.com/feed.xml, name: my-feed }
77
+ rss_fetch { name: my-feed, limit: 10 }
78
+ rss_check { url: https://example.com/feed.xml }
79
+ rss_opml_export { path: subscriptions.opml }
80
+ rss_opml_import { opml: "<?xml version=\"1.0\"?>..." }
81
+ ```
82
+
83
+ ## Subscriptions
84
+
85
+ On Harness 0.1.7, subscriptions and read cursors are stored in the current profile’s `rss` entry. Changes apply immediately and survive restart. Default installations automatically import the retired `dsh-rss` section from `settings.yaml` or `settings.yaml.imported` once, preserving the original file and existing profile values. Older hosts retain their original settings storage. Use a URL to distinguish feeds with identical names.
86
+
87
+ ## Proxy
88
+
89
+ Most feeds are reachable directly; a few require a special proxy from your network. When you hit a `fetch failed` error suggesting a proxy, set `proxyUrl` to your local proxy address (e.g. `http://127.0.0.1:7890`) and restart. The proxy only routes this plugin's fetch requests and does not affect other plugins in the same process.
90
+
91
+ ## Parsing capabilities
92
+
93
+ - RSS 2.0 / RSS 1.0 (RDF) / Atom, normalized to one output shape
94
+ - Entity decoding, CDATA, `content:encoded`, `dc:creator` and other common fields
95
+ - RFC 822 / ISO 8601 dates normalized to ISO 8601 UTC (`pubDate`); the raw text stays in `pubDateRaw`
96
+ - Relative links resolved against the feed URL
97
+ - Summaries stripped of HTML tags and truncated at 500 chars; RSS `content:encoded` / Atom `content` is preserved as a `content` field (tags stripped, up to 20000 chars)
98
+ - Safety: no DTD / external entity parsing; 5MB body cap; configurable fetch timeout
99
+
100
+ ## Development
101
+
102
+ ```bash
103
+ pnpm install
104
+ pnpm test # build + offline tests with explicit fetch and DNS fixtures
105
+ ```
106
+
107
+ ## License
108
+
109
+ MIT
package/README.md CHANGED
@@ -1,109 +1,115 @@
1
- [English](README.en.md)
2
-
3
- # dsh-rss
4
-
5
- > **agent 的资讯雷达**:订阅管理 + RSS/Atom 抓取解析。
6
-
7
- ![npm version](https://img.shields.io/npm/v/dsh-rss?label=npm&color=blue) ![npm downloads](https://img.shields.io/npm/dm/dsh-rss) ![license](https://img.shields.io/npm/l/dsh-rss) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-rss?style=social)
8
-
9
- [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
10
-
11
-
12
- DSH(DeepSeek Harness)的 RSS/Atom 订阅工具插件:管理订阅源,抓取并解析 RSS 0.9x / 1.0 / 2.0 与 Atom,支持 OPML 批量导入导出,给模型提供九个可直接调用的工具。
13
-
14
- ## 兼容性
15
-
16
- 0.4.0 适配官方源码构建的 Harness **0.1.7-alpha.2**(2026-09-23,含本地工具调度器 `Symbol.for` 修复)。18 个插件同载、工具契约、订阅读写与重启持久化通过隔离验证;真实外部订阅源需要正常网络连接。Node 要求为 22.19 及以上的 22.x,或 24 及以上。
17
-
18
- 抓取接收 Harness 的取消信号,取消 DNS、网络读取或跨源搜索时保留原始取消原因。默认预检域名解析结果并拒绝回环、私网和链路本地地址;每次重定向都重新校验。可信内网源可显式配置 `allowPrivateNetwork: true`。
19
-
20
- `rss_opml_export.path` 必须相对本次调用的会话工作区,父目录须已存在;工具拒绝绝对路径、目录穿越和指向工作区外的链接,并返回实际写入文件的绝对路径。文件写入默认通过 Harness 审批门,`opmlWriteApproval: false` 可关闭该门;省略 `path` 时仅返回 OPML 文本。
21
-
22
- ## 安装
23
-
24
- ```bash
25
- dsh plugin --profile web add dsh-rss
26
- ```
27
-
28
- 安装后重启 Web 服务即可。直接对助手说「订阅这个 RSS 地址,命名为技术资讯」或「列出我的订阅」即可使用,日常增删订阅不需要编辑配置文件。
29
-
30
- ## 卸载
31
-
32
- ```bash
33
- dsh plugin --profile web remove dsh-rss
34
- ```
35
-
36
- 卸载后重启 Web 服务。如需彻底清理,可再手动删除自己 profile `cordis.patch.yml` 中覆盖的插件行。
37
-
38
-
39
- ## 配置
40
-
41
- 在你自己的 profile 的 `cordis.patch.yml` 里覆盖本插件行(缺省时插件也能加载,只是全部用默认值):
42
-
43
- ```yaml
44
- - id: rss
45
- name: 'dsh-rss'
46
- config:
47
- # proxyUrl: http://127.0.0.1:7890 # 部分订阅源需要特殊代理(梯子)才能访问时启用
48
- timeoutMs: 15000 # 抓取超时(毫秒,默认 15000)
49
- # maxBodyBytes: 5242880 # 订阅源体积上限(默认 5MB,防超大响应)
50
- # userAgent: 'dsh-rss/0.2.0' # 自定义抓取 UA
51
- # feedsYaml: | # 可选:预置订阅列表(也可用 rss_add 工具添加)
52
- # - url: https://example.com/feed.xml
53
- # name: 示例订阅
54
- # category: 技术
55
- ```
56
-
57
- ## 工具一览
58
-
59
- | 工具 | 作用 | 关键参数 |
60
- | :-- | :-- | :-- |
61
- | `rss_list` | 列出已订阅源 | 无 |
62
- | `rss_add` | 添加订阅(先抓取校验地址) | `url` 必填;`name`/`category` 可选 |
63
- | `rss_remove` | 删除订阅 | `url` 或 `name` 至少一个 |
64
- | `rss_fetch` | 抓取解析订阅源,返回源信息与条目(含正文 content) | `url` 或 `name` 至少一个;`limit` 1-100 默认 20 |
65
- | `rss_check` | 校验地址是否为可解析的订阅源 | `url` 必填 |
66
- | `rss_opml_export` | 导出订阅列表为 OPML 2.0 文本(可写入文件) | `path` 可选 |
67
- | `rss_opml_import` | 从 OPML 2.0 文本批量导入订阅源 | `opml` 必填 |
68
- | `rss_search` | 跨订阅源关键词搜索条目(标题/摘要/正文/作者) | `query` 必填;`name`/`url`/`since`/`limit` 可选 |
69
- | `rss_health` | 插件自检(配置/订阅/游标/解析器,离线) | 无 |
70
-
71
- ### 示例
72
-
73
- ```text
74
- rss_add { url: https://example.com/feed.xml, name: 我的订阅 }
75
- rss_fetch { name: 我的订阅, limit: 10 }
76
- rss_check { url: https://example.com/feed.xml }
77
- rss_opml_export { path: subscriptions.opml }
78
- rss_opml_import { opml: "<?xml version=\"1.0\"?>..." }
79
- ```
80
-
81
- ## 订阅存储
82
-
83
- Harness 0.1.7 把订阅列表和读取游标保存在当前 profile 的 `rss` 配置行;增删后立即生效,重启仍保留。默认安装会自动导入旧 `settings.yaml` 或 `settings.yaml.imported` 的 `dsh-rss` 数据一次,保留原文件,且不覆盖已有 profile 值。旧版宿主继续使用原 settings 存储。同名订阅请用 URL 区分。
84
-
85
- ## 特殊代理(梯子)
86
-
87
- 大部分订阅源可以直接访问;少数订阅源需要特殊代理(梯子)才能连通。遇到 `抓取失败` 且提示需要代理时,把 `proxyUrl` 配成你的本地代理地址(如 `http://127.0.0.1:7890`)并重启即可。代理只作用于本插件的抓取请求,不影响同进程其他插件。
88
-
89
- ## 解析能力
90
-
91
- - RSS 2.0 / RSS 1.0(RDF)/ Atom 三种格式,统一归一化输出
92
- - 实体解码、CDATA、`content:encoded`、`dc:creator`、`itunes` 等常见字段
93
- - RFC 822 / ISO 8601 日期统一转 ISO 8601 UTC(`pubDate`),原始文本保留在 `pubDateRaw`
94
- - 相对链接按订阅源地址解析成绝对链接
95
- - 摘要去 HTML 标签并截断到 500 字符;RSS `content:encoded` / Atom `content` 作为 `content` 字段保留(去标签后最多 20000 字符)
96
- - 安全:不解析 DTD/外部实体,内容只做文本抽取;响应体积上限 5MB;抓取超时可配
97
-
98
- ## 开发
99
-
100
- ```bash
101
- pnpm install
102
- pnpm test # 构建 + 离线测试(fetch 与 DNS 均使用夹具)
103
- ```
104
-
105
- 发布前门禁:危险模式扫描、manifest 自检、`pnpm audit --prod`、全量测试,以及全新 profile 的真实启动冒烟测试。
106
-
107
- ## License
108
-
109
- MIT
1
+ [English](README.en.md)
2
+
3
+ # dsh-rss
4
+
5
+ ## 0.4.1 更新(2026-09-27)
6
+
7
+ 识别代理 Fake-IP 造成的订阅源解析问题,提示使用真实 DNS 地址;继续拒绝保留地址,无需放开内网访问。
8
+
9
+ 验证宿主:官方源码构建的 Harness `0.2.0-rc.1`(commit `407e65c8`)+ Node `24.16.0`(2026-09-28)。77 项插件测试在隔离环境全部通过;同一个宿主里 18 个插件共同加载,注册 9 个工具,工具 schema 与健康检查契约通过。本轮未启用真实端口与外部服务。
10
+
11
+ > **agent 的资讯雷达**:订阅管理 + RSS/Atom 抓取解析。
12
+
13
+ ![npm version](https://img.shields.io/npm/v/dsh-rss?label=npm&color=blue) ![npm downloads](https://img.shields.io/npm/dm/dsh-rss) ![license](https://img.shields.io/npm/l/dsh-rss) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-rss?style=social)
14
+
15
+ [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
16
+
17
+
18
+ DSH(DeepSeek Harness)的 RSS/Atom 订阅工具插件:管理订阅源,抓取并解析 RSS 0.9x / 1.0 / 2.0 与 Atom,支持 OPML 批量导入导出,给模型提供九个可直接调用的工具。
19
+
20
+ ## 兼容性
21
+
22
+ 0.4.0 起适配官方源码构建的 Harness **0.1.7 及以上的声明式设置接口**;当前基线为 **0.2.0-rc.1**,18 个插件同载、工具契约、订阅读写与重启持久化在隔离环境通过验证;真实外部订阅源需要正常网络连接。Node 要求为 22.19 及以上的 22.x,或 24 及以上。
23
+
24
+ 抓取接收 Harness 的取消信号,取消 DNS、网络读取或跨源搜索时保留原始取消原因。默认预检域名解析结果并拒绝回环、私网和链路本地地址;每次重定向都重新校验。可信内网源可显式配置 `allowPrivateNetwork: true`。
25
+
26
+ `rss_opml_export.path` 必须相对本次调用的会话工作区,父目录须已存在;工具拒绝绝对路径、目录穿越和指向工作区外的链接,并返回实际写入文件的绝对路径。文件写入默认通过 Harness 审批门,`opmlWriteApproval: false` 可关闭该门;省略 `path` 时仅返回 OPML 文本。
27
+
28
+ ## 安装
29
+
30
+ ```bash
31
+ dsh plugin --profile web add dsh-rss
32
+ ```
33
+
34
+ 安装后重启 Web 服务即可。直接对助手说「订阅这个 RSS 地址,命名为技术资讯」或「列出我的订阅」即可使用,日常增删订阅不需要编辑配置文件。
35
+
36
+ ## 卸载
37
+
38
+ ```bash
39
+ dsh plugin --profile web remove dsh-rss
40
+ ```
41
+
42
+ 卸载后重启 Web 服务。如需彻底清理,可再手动删除自己 profile `cordis.patch.yml` 中覆盖的插件行。
43
+
44
+
45
+ ## 配置
46
+
47
+ 在你自己的 profile 的 `cordis.patch.yml` 里覆盖本插件行(缺省时插件也能加载,只是全部用默认值):
48
+
49
+ ```yaml
50
+ - id: rss
51
+ name: 'dsh-rss'
52
+ config:
53
+ # proxyUrl: http://127.0.0.1:7890 # 部分订阅源需要特殊代理(梯子)才能访问时启用
54
+ timeoutMs: 15000 # 抓取超时(毫秒,默认 15000)
55
+ # maxBodyBytes: 5242880 # 订阅源体积上限(默认 5MB,防超大响应)
56
+ # userAgent: 'dsh-rss/0.2.0' # 自定义抓取 UA
57
+ # feedsYaml: | # 可选:预置订阅列表(也可用 rss_add 工具添加)
58
+ # - url: https://example.com/feed.xml
59
+ # name: 示例订阅
60
+ # category: 技术
61
+ ```
62
+
63
+ ## 工具一览
64
+
65
+ | 工具 | 作用 | 关键参数 |
66
+ | :-- | :-- | :-- |
67
+ | `rss_list` | 列出已订阅源 | 无 |
68
+ | `rss_add` | 添加订阅(先抓取校验地址) | `url` 必填;`name`/`category` 可选 |
69
+ | `rss_remove` | 删除订阅 | `url` 或 `name` 至少一个 |
70
+ | `rss_fetch` | 抓取解析订阅源,返回源信息与条目(含正文 content) | `url` 或 `name` 至少一个;`limit` 1-100 默认 20 |
71
+ | `rss_check` | 校验地址是否为可解析的订阅源 | `url` 必填 |
72
+ | `rss_opml_export` | 导出订阅列表为 OPML 2.0 文本(可写入文件) | `path` 可选 |
73
+ | `rss_opml_import` | 从 OPML 2.0 文本批量导入订阅源 | `opml` 必填 |
74
+ | `rss_search` | 跨订阅源关键词搜索条目(标题/摘要/正文/作者) | `query` 必填;`name`/`url`/`since`/`limit` 可选 |
75
+ | `rss_health` | 插件自检(配置/订阅/游标/解析器,离线) | 无 |
76
+
77
+ ### 示例
78
+
79
+ ```text
80
+ rss_add { url: https://example.com/feed.xml, name: 我的订阅 }
81
+ rss_fetch { name: 我的订阅, limit: 10 }
82
+ rss_check { url: https://example.com/feed.xml }
83
+ rss_opml_export { path: subscriptions.opml }
84
+ rss_opml_import { opml: "<?xml version=\"1.0\"?>..." }
85
+ ```
86
+
87
+ ## 订阅存储
88
+
89
+ Harness 0.1.7 把订阅列表和读取游标保存在当前 profile 的 `rss` 配置行;增删后立即生效,重启仍保留。默认安装会自动导入旧 `settings.yaml` 或 `settings.yaml.imported` 的 `dsh-rss` 数据一次,保留原文件,且不覆盖已有 profile 值。旧版宿主继续使用原 settings 存储。同名订阅请用 URL 区分。
90
+
91
+ ## 特殊代理(梯子)
92
+
93
+ 大部分订阅源可以直接访问;少数订阅源需要特殊代理(梯子)才能连通。遇到 `抓取失败` 且提示需要代理时,把 `proxyUrl` 配成你的本地代理地址(如 `http://127.0.0.1:7890`)并重启即可。代理只作用于本插件的抓取请求,不影响同进程其他插件。
94
+
95
+ ## 解析能力
96
+
97
+ - RSS 2.0 / RSS 1.0(RDF)/ Atom 三种格式,统一归一化输出
98
+ - 实体解码、CDATA、`content:encoded`、`dc:creator`、`itunes` 等常见字段
99
+ - RFC 822 / ISO 8601 日期统一转 ISO 8601 UTC(`pubDate`),原始文本保留在 `pubDateRaw`
100
+ - 相对链接按订阅源地址解析成绝对链接
101
+ - 摘要去 HTML 标签并截断到 500 字符;RSS `content:encoded` / Atom `content` 作为 `content` 字段保留(去标签后最多 20000 字符)
102
+ - 安全:不解析 DTD/外部实体,内容只做文本抽取;响应体积上限 5MB;抓取超时可配
103
+
104
+ ## 开发
105
+
106
+ ```bash
107
+ pnpm install
108
+ pnpm test # 构建 + 离线测试(fetch 与 DNS 均使用夹具)
109
+ ```
110
+
111
+ 发布前门禁:危险模式扫描、manifest 自检、`pnpm audit --prod`、全量测试,以及全新 profile 的真实启动冒烟测试。
112
+
113
+ ## License
114
+
115
+ MIT
package/cordis.patch.yml CHANGED
@@ -1,20 +1,20 @@
1
- # dsh-rss 组合包补丁:把 RSS 订阅工具插件行插入 profile。
2
- # 本补丁按 id 覆盖;用户应在自己 profile 的 cordis.patch.yml 里覆盖本行的整个
3
- # config(见 README 的配置示例)。配置缺失时插件仍会加载,但每个工具在调用时
4
- # 会抛出带中文指引的错误,提示补全配置后重启。
5
- #
6
- # 示例(用户 profile 的 cordis.patch.yml):
7
- # - id: rss
8
- # name: 'dsh-rss'
9
- # config:
10
- # # proxyUrl: http://127.0.0.1:7890 # 部分订阅源需要特殊代理(梯子)时启用
11
- # timeoutMs: 15000 # 抓取超时(毫秒)
12
- # # feedsYaml: | # 可选:预置订阅列表(也可用 rss_add 工具添加)
13
- # # - url: https://example.com/feed.xml
14
- # # name: 示例订阅
15
- #
16
- - insert:
17
- - id: rss
18
- name: 'dsh-rss'
19
- config:
20
- timeoutMs: 15000
1
+ # dsh-rss 组合包补丁:把 RSS 订阅工具插件行插入 profile。
2
+ # 本补丁按 id 覆盖;用户应在自己 profile 的 cordis.patch.yml 里覆盖本行的整个
3
+ # config(见 README 的配置示例)。配置缺失时插件仍会加载,但每个工具在调用时
4
+ # 会抛出带中文指引的错误,提示补全配置后重启。
5
+ #
6
+ # 示例(用户 profile 的 cordis.patch.yml):
7
+ # - id: rss
8
+ # name: 'dsh-rss'
9
+ # config:
10
+ # # proxyUrl: http://127.0.0.1:7890 # 部分订阅源需要特殊代理(梯子)时启用
11
+ # timeoutMs: 15000 # 抓取超时(毫秒)
12
+ # # feedsYaml: | # 可选:预置订阅列表(也可用 rss_add 工具添加)
13
+ # # - url: https://example.com/feed.xml
14
+ # # name: 示例订阅
15
+ #
16
+ - insert:
17
+ - id: rss
18
+ name: 'dsh-rss'
19
+ config:
20
+ timeoutMs: 15000
package/lib/network.js CHANGED
@@ -126,6 +126,10 @@ async function assertPublicUrl(url, cfg, lookupImpl, signal) {
126
126
  throw new Error('无法安全解析订阅源域名 ' + hostname + ':DNS 未返回地址。');
127
127
  const blocked = addresses.find((entry) => isBlockedNetworkAddress(entry.address));
128
128
  if (blocked !== undefined) {
129
+ const v4 = ipv4Bytes(blocked.address);
130
+ if (v4 !== null && v4[0] === 198 && (v4[1] === 18 || v4[1] === 19)) {
131
+ throw new Error('订阅源域名 ' + hostname + ' 被解析为保留地址 ' + blocked.address + ',可能是代理软件的 Fake-IP,已拒绝访问。请在代理 DNS 设置中让该域名返回真实 IP(如加入 fake-ip-filter),然后重试。无需开启内网访问。');
132
+ }
129
133
  throw new Error('出于安全原因,域名 ' + hostname + ' 解析到了非公网地址 ' + blocked.address + ',已拒绝访问。若确需访问可信内网源,请显式配置 allowPrivateNetwork: true。');
130
134
  }
131
135
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-rss",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "DSH RSS 插件:订阅源管理、OPML 导入导出、抓取解析 RSS/Atom 并保留正文。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",