dsh-rss 0.3.1 → 0.4.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/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
@@ -4,11 +4,11 @@
4
4
 
5
5
  [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com)
6
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 seven model-facing tools.
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
8
 
9
9
  ## Compatibility
10
10
 
11
- Adapted to the tool execution contracts in `@deepseek-ai/dsh@0.1.3-alpha.1`. Built for the cordis patch-bundle plugin model (`cordis.patch.yml` + `dsh.bundle.patch`). No runtime imports of `@deepseek-ai/*` internals.
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
12
 
13
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
14
 
@@ -20,7 +20,7 @@ Fetches honor the Harness cancellation signal through DNS, response streaming, a
20
20
  dsh plugin --profile web add dsh-rss
21
21
  ```
22
22
 
23
- Restart the web service after installing.
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
24
 
25
25
  ## Uninstall
26
26
 
@@ -61,6 +61,9 @@ Override the plugin row in your profile's `cordis.patch.yml` (the plugin also lo
61
61
  | `rss_opml_export` | Export subscriptions as OPML 2.0 text (optionally write a file) | `path` optional |
62
62
  | `rss_opml_import` | Bulk-import subscriptions from OPML 2.0 text | `opml` required |
63
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
+
64
67
  ### Examples
65
68
 
66
69
  ```text
@@ -73,7 +76,7 @@ rss_opml_import { opml: "<?xml version=\"1.0\"?>..." }
73
76
 
74
77
  ## Subscriptions
75
78
 
76
- Subscriptions live in the settings namespace `dsh-rss` (the `feedsYaml` field): `rss_add` / `rss_remove` read and write it automatically and changes persist across restarts. You can also pre-seed subscriptions via the `feedsYaml` config field. Use `url` to distinguish feeds that share a name.
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.
77
80
 
78
81
  ## Proxy
79
82
 
package/README.md CHANGED
@@ -13,7 +13,7 @@ DSH(DeepSeek Harness)的 RSS/Atom 订阅工具插件:管理订阅源,抓
13
13
 
14
14
  ## 兼容性
15
15
 
16
- 按 `@deepseek-ai/dsh@0.1.3-alpha.1` 的工具执行接口适配。遵循 cordis 组合包补丁模型(`cordis.patch.yml` + `dsh.bundle.patch`),运行时不 import 任何 `@deepseek-ai/*` 内部模块。
16
+ 0.4.0 适配官方源码构建的 Harness **0.1.7-alpha.2**(2026-09-23,含本地工具调度器 `Symbol.for` 修复)。18 个插件同载、工具契约、订阅读写与重启持久化通过隔离验证;真实外部订阅源需要正常网络连接。Node 要求为 22.19 及以上的 22.x,或 24 及以上。
17
17
 
18
18
  抓取接收 Harness 的取消信号,取消 DNS、网络读取或跨源搜索时保留原始取消原因。默认预检域名解析结果并拒绝回环、私网和链路本地地址;每次重定向都重新校验。可信内网源可显式配置 `allowPrivateNetwork: true`。
19
19
 
@@ -25,7 +25,7 @@ DSH(DeepSeek Harness)的 RSS/Atom 订阅工具插件:管理订阅源,抓
25
25
  dsh plugin --profile web add dsh-rss
26
26
  ```
27
27
 
28
- 安装后重启 Web 服务即可。
28
+ 安装后重启 Web 服务即可。直接对助手说「订阅这个 RSS 地址,命名为技术资讯」或「列出我的订阅」即可使用,日常增删订阅不需要编辑配置文件。
29
29
 
30
30
  ## 卸载
31
31
 
@@ -80,7 +80,7 @@ rss_opml_import { opml: "<?xml version=\"1.0\"?>..." }
80
80
 
81
81
  ## 订阅存储
82
82
 
83
- 订阅列表保存在 settings 的 `dsh-rss` 命名空间(`feedsYaml` 字段)里:`rss_add` / `rss_remove` 会自动读写并持久化,重启后仍在;也可以在配置里用 `feedsYaml` 预置初始订阅。同名订阅请用 `url` 区分。
83
+ Harness 0.1.7 把订阅列表和读取游标保存在当前 profile 的 `rss` 配置行;增删后立即生效,重启仍保留。默认安装会自动导入旧 `settings.yaml` 或 `settings.yaml.imported` 的 `dsh-rss` 数据一次,保留原文件,且不覆盖已有 profile 值。旧版宿主继续使用原 settings 存储。同名订阅请用 URL 区分。
84
84
 
85
85
  ## 特殊代理(梯子)
86
86
 
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/config.d.ts CHANGED
@@ -11,6 +11,7 @@ export interface RssConfig {
11
11
  maxBodyBytes?: number;
12
12
  userAgent?: string;
13
13
  feedsYaml?: string;
14
+ cursorsJson?: string;
14
15
  allowPrivateNetwork?: boolean;
15
16
  opmlWriteApproval?: boolean;
16
17
  }
package/lib/index.d.ts CHANGED
@@ -28,10 +28,18 @@ type RssPreExecuteListener = (exec: RssPendingToolExecution, next: () => Promise
28
28
  /** 插件所需的最小 ctx 面(社区插件不依赖宿主内部类型)。 */
29
29
  export interface RssPluginContext {
30
30
  settings: {
31
- register(ns: string, schema: unknown, options?: {
31
+ register?(ns: string, schema: unknown, options?: {
32
32
  base?: Record<string, unknown>;
33
33
  applies?: string;
34
34
  }): RssSettingsScope;
35
+ update?(ns: string, patch: Record<string, unknown>): Promise<void>;
36
+ };
37
+ fiber?: {
38
+ entry?: {
39
+ options: {
40
+ id: string;
41
+ };
42
+ };
35
43
  };
36
44
  tools: {
37
45
  register(definition: RssToolDefinition): () => void;
package/lib/index.js CHANGED
@@ -7,8 +7,9 @@
7
7
  * @module dsh-rss
8
8
  */
9
9
  import { resolveConfig } from './config.js';
10
- import { RSS_SETTINGS_NAMESPACE, RssSettingsSchema } from './settings.js';
10
+ import { RSS_SETTINGS_NAMESPACE, RssSettingsSchema, liveConfig } from './settings.js';
11
11
  import { buildRssTools } from './tools.js';
12
+ import { installLegacySettingsImport } from './legacy-settings.js';
12
13
  /** cordis 服务注入:apply 里要用 ctx.settings 与 ctx.tools,必须显式声明,否则宿主会抛 cannot get property without inject。 */
13
14
  export const name = 'rss';
14
15
  export const inject = ['settings', 'tools'];
@@ -18,11 +19,20 @@ export const inject = ['settings', 'tools'];
18
19
  * @param config - 插件配置(可缺省)。
19
20
  */
20
21
  export function apply(ctx, config) {
22
+ config = liveConfig(config ?? {});
21
23
  const cfg = resolveConfig(config);
22
- const settingsScope = ctx.settings.register(RSS_SETTINGS_NAMESPACE, RssSettingsSchema, {
24
+ installLegacySettingsImport(ctx, config, RSS_SETTINGS_NAMESPACE, 'rss', ['feedsYaml', 'cursorsJson']);
25
+ const settingsScope = typeof ctx.settings.register === 'function' ? ctx.settings.register(RSS_SETTINGS_NAMESPACE, RssSettingsSchema, {
23
26
  base: { feedsYaml: cfg.feedsYaml },
24
27
  applies: 'live',
25
- });
28
+ }) : {
29
+ get: () => ({ feedsYaml: config?.feedsYaml ?? '', cursorsJson: config?.cursorsJson ?? '' }),
30
+ update: async (patch) => {
31
+ if (!ctx.settings.update)
32
+ throw new Error('当前宿主不支持保存 RSS 配置');
33
+ await ctx.settings.update(ctx.fiber?.entry?.options.id ?? 'rss', patch);
34
+ },
35
+ };
26
36
  const disposers = [];
27
37
  for (const definition of buildRssTools(cfg, settingsScope)) {
28
38
  disposers.push(ctx.tools.register(definition));
@@ -0,0 +1,4 @@
1
+ /** No backup is edited or deleted; the completion marker lives beside imported values. */
2
+ export declare function importLegacySettings(ctx: any, config: Record<string, any>, namespace: string, entryId: string, fields: readonly string[], home?: string): Promise<boolean>;
3
+ /** Defer persistence until the entry and settings provider are active. */
4
+ export declare function installLegacySettingsImport(ctx: any, config: Record<string, any>, namespace: string, entryId: string, fields: readonly string[]): void;
@@ -0,0 +1,64 @@
1
+ /** Import only this plugin's retired settings section, preserving profile overrides. */
2
+ import { readFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join, resolve } from 'node:path';
5
+ import { parse } from 'yaml';
6
+ function plain(value) {
7
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
8
+ }
9
+ function missing(legacy, current) {
10
+ const patch = {};
11
+ for (const [key, value] of Object.entries(legacy)) {
12
+ if (current[key] === undefined)
13
+ patch[key] = value;
14
+ else if (plain(value) && plain(current[key])) {
15
+ const nested = missing(value, current[key]);
16
+ if (Object.keys(nested).length)
17
+ patch[key] = nested;
18
+ }
19
+ }
20
+ return patch;
21
+ }
22
+ /** No backup is edited or deleted; the completion marker lives beside imported values. */
23
+ export async function importLegacySettings(ctx, config, namespace, entryId, fields, home) {
24
+ if (typeof ctx.settings.register === 'function' || config.legacySettingsImported === true)
25
+ return false;
26
+ // Old namespaces were global. Do not copy credentials into unrelated custom instances.
27
+ if (ctx.fiber?.entry?.options.id !== entryId)
28
+ return false;
29
+ let base = home ?? (process.env.DSH_HOME?.trim() || join(homedir(), '.dsh'));
30
+ if (base === '~')
31
+ base = homedir();
32
+ else if (base.startsWith('~/') || base.startsWith('~\\'))
33
+ base = join(homedir(), base.slice(2));
34
+ let document;
35
+ for (const file of ['settings.yaml.imported', 'settings.yaml']) {
36
+ try {
37
+ document = parse(readFileSync(resolve(base, file), 'utf8'));
38
+ break;
39
+ }
40
+ catch (error) {
41
+ if (error.code !== 'ENOENT')
42
+ throw new Error('Cannot read legacy settings; original file preserved');
43
+ }
44
+ }
45
+ if (!plain(document) || !plain(document[namespace]))
46
+ return false;
47
+ const section = Object.fromEntries(fields.filter(key => Object.hasOwn(document[namespace], key)).map(key => [key, document[namespace][key]]));
48
+ if (Object.keys(section).length === 0)
49
+ return false;
50
+ await ctx.settings.update(entryId, { ...missing(section, { ...config }), legacySettingsImported: true });
51
+ return true;
52
+ }
53
+ /** Defer persistence until the entry and settings provider are active. */
54
+ export function installLegacySettingsImport(ctx, config, namespace, entryId, fields) {
55
+ if (typeof ctx.settings.register === 'function' || typeof ctx.inject !== 'function')
56
+ return;
57
+ ctx.inject(['appReady'], (readyCtx) => {
58
+ readyCtx.effect(() => readyCtx.appReady.onReady(() => {
59
+ void importLegacySettings(ctx, config, namespace, entryId, fields).catch(() => {
60
+ ctx.logger?.warn?.(namespace + ': legacy settings could not be imported; the original settings file is preserved.');
61
+ });
62
+ }));
63
+ });
64
+ }
package/lib/settings.d.ts CHANGED
@@ -1,19 +1,36 @@
1
- /**
2
- * settings 命名空间:订阅列表(feedsYaml)存在这里,供设置页与工具共同读写。
3
- *
4
- * @module dsh-rss/settings
5
- */
6
- import z from 'schemastery';
1
+ import modern from '@deepseek-ai/schemastery';
2
+ export declare const Config: modern<Schemastery.ObjectS<NoInfer<{
3
+ feedsYaml: modern<string, string, "volatile">;
4
+ cursorsJson: modern<string, string, "volatile">;
5
+ proxyUrl: modern<string, string, "plain">;
6
+ timeoutMs: modern<number, number, "plain">;
7
+ maxBodyBytes: modern<number, number, "plain">;
8
+ userAgent: modern<string, string, "plain">;
9
+ allowPrivateNetwork: modern<boolean, boolean, "plain">;
10
+ opmlWriteApproval: modern<boolean, boolean, "plain">;
11
+ legacySettingsImported: modern<boolean, boolean, "volatile">;
12
+ }>>, Schemastery.ObjectT<NoInfer<{
13
+ feedsYaml: modern<string, string, "volatile">;
14
+ cursorsJson: modern<string, string, "volatile">;
15
+ proxyUrl: modern<string, string, "plain">;
16
+ timeoutMs: modern<number, number, "plain">;
17
+ maxBodyBytes: modern<number, number, "plain">;
18
+ userAgent: modern<string, string, "plain">;
19
+ allowPrivateNetwork: modern<boolean, boolean, "plain">;
20
+ opmlWriteApproval: modern<boolean, boolean, "plain">;
21
+ legacySettingsImported: modern<boolean, boolean, "volatile">;
22
+ }>>, "plain">;
23
+ export declare function liveConfig<T extends object>(config: T): T;
7
24
  /** 本插件拥有的 settings 文档命名空间。 */
8
25
  export declare const RSS_SETTINGS_NAMESPACE = "dsh-rss";
9
26
  /** settings 页形状:目前只有订阅列表(YAML 文本)。 */
10
- export declare const RssSettingsSchema: z<Schemastery.ObjectS<{
11
- feedsYaml: z<string, string>;
12
- cursorsJson: z<string, string>;
13
- }>, Schemastery.ObjectT<{
14
- feedsYaml: z<string, string>;
15
- cursorsJson: z<string, string>;
16
- }>>;
27
+ export declare const RssSettingsSchema: modern<Schemastery.ObjectS<NoInfer<{
28
+ feedsYaml: modern<string, string, Mode extends "volatile-defined" | "volatile" ? "volatile-defined" : "defined">;
29
+ cursorsJson: modern<string, string, Mode extends "volatile-defined" | "volatile" ? "volatile-defined" : "defined">;
30
+ }>>, Schemastery.ObjectT<NoInfer<{
31
+ feedsYaml: modern<string, string, Mode extends "volatile-defined" | "volatile" ? "volatile-defined" : "defined">;
32
+ cursorsJson: modern<string, string, Mode extends "volatile-defined" | "volatile" ? "volatile-defined" : "defined">;
33
+ }>>, "plain">;
17
34
  /** settings 解析后的值。 */
18
35
  export interface RssSettingsValue {
19
36
  feedsYaml: string;
package/lib/settings.js CHANGED
@@ -4,6 +4,19 @@
4
4
  * @module dsh-rss/settings
5
5
  */
6
6
  import z from 'schemastery';
7
+ import modern from '@deepseek-ai/schemastery';
8
+ export const Config = modern.object({
9
+ feedsYaml: modern.string().volatile(), cursorsJson: modern.string().volatile(),
10
+ proxyUrl: modern.string(), timeoutMs: modern.number(), maxBodyBytes: modern.number(),
11
+ userAgent: modern.string(), allowPrivateNetwork: modern.boolean(), opmlWriteApproval: modern.boolean(),
12
+ legacySettingsImported: modern.boolean().volatile(),
13
+ });
14
+ export function liveConfig(config) {
15
+ return new Proxy(config, { get(target, key, receiver) {
16
+ const value = Reflect.get(target, key, receiver);
17
+ return value !== null && typeof value === 'object' && typeof value.get === 'function' ? value.get() : value;
18
+ } });
19
+ }
7
20
  /** 本插件拥有的 settings 文档命名空间。 */
8
21
  export const RSS_SETTINGS_NAMESPACE = 'dsh-rss';
9
22
  /** settings 页形状:目前只有订阅列表(YAML 文本)。 */
package/package.json CHANGED
@@ -1,65 +1,66 @@
1
- {
2
- "name": "dsh-rss",
3
- "version": "0.3.1",
4
- "description": "DSH RSS 订阅工具插件:管理订阅源、OPML 导入导出、抓取解析 RSS/Atom 并保留正文(rss_list / rss_add / rss_remove / rss_fetch / rss_check / rss_opml_export / rss_opml_import)",
5
- "type": "module",
6
- "main": "lib/index.js",
7
- "types": "lib/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./lib/index.d.ts",
11
- "default": "./lib/index.js"
12
- },
13
- "./cordis.patch.yml": "./cordis.patch.yml",
14
- "./package.json": "./package.json"
15
- },
16
- "files": [
17
- "lib",
18
- "cordis.patch.yml",
19
- "README.md",
20
- "README.en.md"
21
- ],
22
- "scripts": {
23
- "build": "tsc -p tsconfig.json",
24
- "typecheck": "tsc -p tsconfig.json --noEmit",
25
- "test": "pnpm run build && node --test \"test/*.test.mjs\"",
26
- "prepublishOnly": "pnpm run build"
27
- },
28
- "dsh": {
29
- "bundle": {
30
- "patch": "./cordis.patch.yml"
31
- }
32
- },
33
- "keywords": [
34
- "dsh",
35
- "deepseek-harness",
36
- "plugin",
37
- "rss",
38
- "atom",
39
- "feed"
40
- ],
41
- "license": "MIT",
42
- "engines": {
43
- "node": ">=22"
44
- },
45
- "dependencies": {
46
- "fast-xml-parser": "^5.0.0",
47
- "schemastery": "^3.18.0",
48
- "undici": "^8.10.0",
49
- "yaml": "^2.9.0"
50
- },
51
- "devDependencies": {
52
- "@types/node": "^24.0.0",
53
- "typescript": "^5.6.0"
54
- },
55
- "repository": {
56
- "type": "git",
57
- "url": "git+https://github.com/STARDUSTLC666/dsh-rss.git"
58
- },
59
- "bugs": {
60
- "url": "https://github.com/STARDUSTLC666/dsh-rss/issues"
61
- },
62
- "homepage": "https://github.com/STARDUSTLC666/dsh-rss#readme",
63
- "author": "stardustlc",
64
- "packageManager": "pnpm@11.7.0"
65
- }
1
+ {
2
+ "name": "dsh-rss",
3
+ "version": "0.4.0",
4
+ "description": "DSH RSS 插件:订阅源管理、OPML 导入导出、抓取解析 RSS/Atom 并保留正文。",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "types": "lib/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./lib/index.d.ts",
11
+ "default": "./lib/index.js"
12
+ },
13
+ "./cordis.patch.yml": "./cordis.patch.yml",
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "lib",
18
+ "cordis.patch.yml",
19
+ "README.md",
20
+ "README.en.md"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.json",
24
+ "typecheck": "tsc -p tsconfig.json --noEmit",
25
+ "test": "pnpm run build && node --test \"test/*.test.mjs\"",
26
+ "prepublishOnly": "pnpm run build"
27
+ },
28
+ "dsh": {
29
+ "bundle": {
30
+ "patch": "./cordis.patch.yml"
31
+ }
32
+ },
33
+ "keywords": [
34
+ "dsh",
35
+ "deepseek-harness",
36
+ "plugin",
37
+ "rss",
38
+ "atom",
39
+ "feed"
40
+ ],
41
+ "license": "MIT",
42
+ "engines": {
43
+ "node": "^22.19.0 || >=24.0.0"
44
+ },
45
+ "dependencies": {
46
+ "fast-xml-parser": "^5.0.0",
47
+ "schemastery": "^3.18.0",
48
+ "undici": "^8.10.0",
49
+ "yaml": "^2.9.0",
50
+ "@deepseek-ai/schemastery": "^3.18.3"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^24.0.0",
54
+ "typescript": "^5.6.0"
55
+ },
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "git+https://github.com/STARDUSTLC666/dsh-rss.git"
59
+ },
60
+ "bugs": {
61
+ "url": "https://github.com/STARDUSTLC666/dsh-rss/issues"
62
+ },
63
+ "homepage": "https://github.com/STARDUSTLC666/dsh-rss#readme",
64
+ "author": "stardustlc",
65
+ "packageManager": "pnpm@11.7.0"
66
+ }