cortico-world-rss 0.0.0-stage → 0.2.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/AGENTS.md ADDED
@@ -0,0 +1,83 @@
1
+ # AGENTS.md — cortico-world-rss 工程指南
2
+
3
+ Coopanion(Cortico 框架)的 RSS 订阅 World 扩展。本文件面向后续在本仓库工作的 Agent 与开发者:命令、结构、变更清单、已踩过的坑。设计背景与完整契约见 `docs/design.md`(含"实现与设计的偏差对照"一节,先读它避免被过时描述误导)。
4
+
5
+ ## 命令(本机没有全局 Node,用 DSH 运行时)
6
+
7
+ 先把 DSH 运行时的 `node/bin` 加入 PATH(路径因机器而异,位于 `~/.dsh/dsh-runtimes/<运行时>/dependencies/` 下),然后:
8
+
9
+ ```bash
10
+ node "<DSH 运行时>/dependencies/pnpm/bin/pnpm.mjs" typecheck # 两份 tsconfig:Node 侧 + webui 面板侧
11
+ node "<DSH 运行时>/dependencies/pnpm/bin/pnpm.mjs" test # esbuild 打面板 → vitest(不碰真实网络)
12
+ node "<DSH 运行时>/dependencies/pnpm/bin/pnpm.mjs" describe:local # 生成 describe.json(改工具/事件/提示词后必跑)
13
+ node "<DSH 运行时>/dependencies/pnpm/bin/pnpm.mjs" run feed-server # 本地 RSS 测试服务器 http://127.0.0.1:8787
14
+ RSS_LIVE_TEST=1 npx vitest run tests/live.test.ts # 真机集成(自起测试服务器)
15
+ ```
16
+
17
+ ## 文件职责速查
18
+
19
+ | 文件 | 职责 |
20
+ |---|---|
21
+ | `src/config.ts` | 配置段接口、默认值、JSON Schema、分组(设置页字段由此而来) |
22
+ | `src/config-save.ts` | 面板保存通道的纯校验:键白名单、数值钳制、格式校验、整单拒绝 |
23
+ | `src/store.ts` | 订阅源表 + 条目库(dataDir 双 JSON、原子写、compact 清理、基线语义) |
24
+ | `src/parse.ts` | RSS 2.0/Atom/RDF 归一化、去重键、实体解码、站点 feed 发现 |
25
+ | `src/fetcher.ts` | 条件请求、重定向逐跳校验、体积/超时上限、编码探测 |
26
+ | `src/poller.ts` | 调度、退避、合批缓冲、adoptFeed(订阅首拉 + baseline) |
27
+ | `src/extract.ts` | 文章正文抽取(rss_read full) |
28
+ | `src/chrono.ts` | 时区时间:晨报时刻、相对时间 |
29
+ | `src/opml.ts` | OPML 导入导出 |
30
+ | `src/world.ts` | 主体:7 工具、3 事件、面板数据面(invoke 按 method 分发)、事件投递、启动播报 |
31
+ | `src/definition.ts` | WorldDefinition(persist 通道在这里接 `ctx.persist`) |
32
+ | `src/strings.ts` | zh/en 全部文案,**两份结构必须对称**(`typeof zh` 约束) |
33
+ | `src/webui/client.ts` | 浏览器面板:五个标签 = 订阅源/收件箱/通知/高级/OPML |
34
+ | `src/ENV_PROMPT.md` | 环境提示词(进 system 前缀) |
35
+ | `scripts/describe.ts` | 生成 describe.json;`scripts/feed-server.mjs` 本地测试服务器 |
36
+ | `describe.json` | 自描述产物,测试逐字比对,**改声明后必须重新生成** |
37
+ | `.agents/skills/coopanion-plugin-dev/` | Coopanion 插件开发规范 skill(原 extension/panel-ui/webui-debug/restart 四个 skill 的合并版);改面板、重启、目检前先读。`.dsh/skills`、`.claude/skills` 是指向 `.agents/skills` 的软链,`CLAUDE.md` 软链到 `AGENTS.md` |
38
+
39
+ ## 改动的标准闭环
40
+
41
+ ```
42
+ 改代码 → 【bump package.json patch 版本】→ pnpm test(含面板构建)→ coopanion-plugin-dev 的重启阶段 → 同一 skill 的目检阶段
43
+ ```
44
+
45
+ **版本必须 bump**:面板产物按 `/assets/extensions/<包>/<版本>/webui.js` 以 `Cache-Control: immutable` 提供——同版本内的改动,重启进程、换源都到不了浏览器。
46
+
47
+ ## 常见变更的触点清单
48
+
49
+ ### 新增一个配置项(触点最多,缺一不可)
50
+
51
+ 1. `config.ts`:接口字段 + `RSS_DEFAULTS` + schema 属性 + `rssConfigGroups` 对应分组
52
+ 2. `config-save.ts`:加入 `RSS_CONFIG_KEYS` 白名单;数值项加 `NUMBER_RANGES`
53
+ 3. `strings.ts`:title/description,**zh 与 en 都要加**(结构对称)
54
+ 4. `webui/client.ts`:`mountSettings`/`mountNotify` 的 fields 加一行
55
+ 5. 影响运行时预算的键(如清理上限):`world.ts` 的 limits 活对象在 `config.save` 分支同步
56
+ 6. 测试计数:`world.test` 的 config.get 键数、`config-save.test` 的白名单数
57
+
58
+ ### 新增一个工具
59
+
60
+ `RSS_TOOL_DECLS`(声明)→ `world.ts` 的 `tools()` 加 handler → `RSS_SUMMARIES` 一句话 → `pnpm describe:local` 重新生成 `describe.json`(一致性测试自动守护)。
61
+
62
+ ### 改面板 UI
63
+
64
+ 遵循本仓库 skill **coopanion-plugin-dev**(`.agents/skills/coopanion-plugin-dev/`;其 `references/panel-ui-spec.md` 与 `references/ui-components.md`:组件行为、布局硬规则、对齐与缓存);目检走该 skill 的「阶段 F:受控浏览器目检」;生效走「阶段 E:重启 Coopanion」。
65
+
66
+ ## 已踩过的坑(别再踩)
67
+
68
+ - **ESM**:禁止 `require`;import 带 `.ts` 扩展名。
69
+ - **describe.json** 由代码生成,手工改无效;改了工具/事件/ENV_PROMPT 必须重跑 `describe:local`。
70
+ - **测试不碰真实网络**:fetch 全部注入(`makeWorld`/`makeEnv`);真机用例走本地测试服务器且默认 skip。
71
+ - **bash 里 `node -e` 写含反引号的模板字符串会坏文件**(bash 先展开)——改 TypeScript 一律用结构化编辑,不用内联脚本。内联 `replace` 不匹配时**静默不报错**:0.1.18 曾因此发了一个未改动的包(版本照升、代码没变,排查三轮才发现)。改完必须 grep 验证标记字符串确实落盘,再构建。
72
+ - **含中文的 .ps1 必须 UTF-8 带 BOM**(PowerShell 5.1 按 GBK 解析无 BOM 文件)。
73
+ - **Git Bash 调 Windows 工具用双斜杠**(`taskkill //IM`),且别把这类路径放在行尾(尾反斜杠转义引号)。
74
+ - **pnpm 需要 node 在 PATH 里**,直接给 node.exe 全路径跑 pnpm.mjs 会因子进程找不到 node 失败。
75
+ - **两份 tsconfig 都要过**:面板改动只挂 web 侧错误时容易漏看。
76
+ - vitest 输出中文可能乱码(GBK 控制台),看断言以英文部分为准。
77
+
78
+ ## 边界与红线
79
+
80
+ - 测试永不访问真实网络;外部行为只通过注入的 `fetchImpl` 模拟。
81
+ - 不引入遥测;网络面仅限用户配置的源地址 + `rss_read(full)` 的文章页;私网/本机地址默认允许(无开关)。
82
+ - 令牌/密钥:本扩展无;若未来需要,走 `ctx.secret()`,不进 config.json、不进日志。
83
+ - 发布由用户决定;发布前需在 Cortico 检出根跑 `describe:extension` + `check:extension`。
package/CHANGELOG.md ADDED
@@ -0,0 +1,153 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 - 2026-11-09
4
+
5
+ - 首个公开发布版本,汇总 0.1.38–0.1.43 的改动。
6
+ - 每源通知策略只保留实时/静默;晨报统计含静默源、重点只列非静默源;新增启动时播报。
7
+ - 订阅弹框重排,移除关注关键词;通知项补 `!` 悬停说明并对齐提示标记。
8
+
9
+ ## 0.1.43 - 2026-11-09
10
+
11
+ - 字段标签旁的 `!` 再上移 1px,与 11px 小字号的视觉重心对齐。
12
+
13
+ ## 0.1.42 - 2026-11-09
14
+
15
+ - 通知页 `!` 提示对齐微调:字段标签旁改用垂直居中并加大与文字的间距;勾选旁标记不再额外下沉 1px。
16
+
17
+ ## 0.1.41 - 2026-11-09
18
+
19
+ - 通知页分区标题调整:「播报时机」改「通知行为」,「合批」改「消息合批」。
20
+
21
+ ## 0.1.40 - 2026-11-09
22
+
23
+ - 移除「关注关键词」配置及对应排序逻辑;通知页合批卡片只保留窗口、条目上限与字符上限。
24
+ - 订阅弹框重排:「允许抓取原文」移到检查间隔下方单独一行靠左,名称与 User-Agent 各占一行。
25
+ - 通知页文案:「事件合批窗口」改「播报合并窗口(秒)」并加悬停说明;「每次播报最多几条」改「每次播报条目上限」,说明超限不丢弃、顺延到下一波。非布尔配置项现支持 `!` 悬停说明。
26
+
27
+ ## 0.1.39 - 2026-11-09
28
+
29
+ - 修复通知页相邻勾选项(「启动时播报最新消息」与「推送时标为已读」)挤在同一行的问题,现各占一行。
30
+
31
+ ## 0.1.38 - 2026-11-09
32
+
33
+ - 通知策略移除「晨报」:每源只剩实时/静默;旧 digest 源自动迁移为静默,静默源不参与实时、晨报重点与启动播报,条目只进收件箱。
34
+ - 晨报:统计数字包含静默源(全库),「未读重点」只列非静默源;过去 24 小时只有静默内容时仍发送仅含统计的晨报。
35
+ - 新增「启动时播报最新消息」开关(默认开):应用启动后立即拉取全部源,并把本次新内容马上播报一次。
36
+ - 通知页:「每日晨报」加悬停说明;「单条通知头条数」改名「每次播报最多几条」;「推送即标已读」改「推送时标为已读」。
37
+ - 订阅弹框重排:名称独占一行,检查间隔/通知策略/允许抓取原文同一行,User-Agent 独占一行;移除「抓取设置」标题。
38
+
39
+ ## 0.1.37 - 2026-11-09
40
+
41
+ - 订阅弹框细节:检查间隔默认留空并提示「默认读取全局配置」、标签去掉括号、数值下限 1 分钟(留空=全局默认);订阅详情底部按钮改回「保存修改、立即拉取」。
42
+
43
+ ## 0.1.36 - 2026-11-09
44
+
45
+ - 移除「允许私网地址」开关与私网/SSRF 拦截:内网与本机 RSS 默认可直接订阅(订阅表单与 `rss_add` 参数同步移除)。
46
+ - 移除「高级」里的默认 User-Agent 配置;默认 UA 改为 `Coopanion RSS Reader/<插件版本>`(随包版本自动更新),单源仍可覆盖,占位符同步显示当前默认值。
47
+ - 订阅弹框:检查间隔默认填 0;名称占位符改为「默认自动识别」;底部按钮左右交换。
48
+
49
+ ## 0.1.35 - 2026-11-08
50
+
51
+ - 面板文案与布局细化:设置标签改名「高级」;通知页「打扰时机」改为「晨报与已读」并配上贴合现配置的说明;订阅弹框表单与底部按钮之间加分割线;源地址标签/占位符、名称宽度、User-Agent 标签与占位符按反馈调整。
52
+
53
+ ## 0.1.34 - 2026-11-08
54
+
55
+ - 精简配置:移除「免打扰时段」「新源默认通知策略」「新订阅立即推送条数」「每源只推/不推关键词」四项配置及其运行时逻辑。新源固定实时推送,订阅历史默认静默,所有条目默认全推;通知标签只保留晨报与合批/关键词,订阅弹框只保留标题/策略/间隔/UA/私网/原文开关。
56
+ - 旧数据兼容:加载 `rss-feeds.json` 时清掉已移除的 `include`/`exclude` 字段;旧 `config.json` 里的遗留键被忽略且无法再由面板写回。
57
+
58
+ ## 0.1.33 - 2026-11-08
59
+
60
+ - 通知标签的时间配置改成时间选择器组件,杜绝误输入:晨报时刻用单个时间选择器;免打扰时段改为「启用」勾选框 + 开始/结束两个时间选择器(未启用时灰置),跨零点说明挪到勾选框旁的 ⓘ 提示。存储格式不变(`HH:MM-HH:MM`/空),配置校验与 schema 无改动。
61
+ - 回填时把旧配置的一位小时(`9:00`)归一化成 `09:00`:time 控件只认两位小时,不归一化会被浏览器静默拒绝、显示为空。
62
+
63
+ ## 0.1.14 - 2026-11-08
64
+
65
+ - 通知/设置与订阅弹框:勾选项与上方字段拉开 14px 间距。
66
+ - 勾选项的说明文字改为名称旁的「!」标记 + 悬停气泡(复用宿主 hover-hint 系统):订阅时历史标为已读、允许抓取原文、允许私网地址。
67
+
68
+ ## 0.1.13 - 2026-11-08
69
+
70
+ - 收件箱顶部展示清理规则与数值(保留天数/全库上限/每源上限,随配置实时刷新)。
71
+ - 清理上限做成可配置项:全库条目上限(默认 2000)、单源条目上限(默认 200),改动即时生效。
72
+ - 「订阅时历史标为已读」做成可配置项(默认开);关闭后新订阅的历史计入未读。
73
+ - OPML「导入粘贴内容」按钮改主按钮样式。
74
+
75
+ ## 0.1.12 - 2026-11-07
76
+
77
+ - 基线语义修正:新订阅的历史条目标为已见**且已读**——入库可查/可星标,但不污染未读数(对齐 Miniflux「创建后立即标为已读」的行业默认;此前历史全部计入未读)。baseline 参数不变,最新 N 条仍可推送。
78
+
79
+ ## 0.1.11 - 2026-11-07
80
+
81
+ - 概览卡片:宽度收窄(180px)、标题与数字间距加大。
82
+ - 收件箱:每页 10 条;≤10 页整表直出、隐藏分页条(>10 页才分页);空态保留 10 行高度、提示文字居中。
83
+ - 订阅源:空态不渲染表格,只留标题与「添加订阅」入口。
84
+
85
+ ## 0.1.10 - 2026-11-07
86
+
87
+ - 收件箱:每页 10 条;新增源过滤下拉(选项随订阅刷新);新增「全部已读」(红档 + 确认弹框,作用于全部源)。
88
+ - 订阅源:每页 5 条;超过 5 页才显示分页条,否则整表直出。
89
+
90
+ ## 0.1.9 - 2026-11-07
91
+
92
+ - 收件箱分页:每页 20 条,上一页/下一页 + 「共 N 条 · 第 X/Y 页」;范围切换回第一页,页码越界自动收敛。
93
+
94
+ ## 0.1.8 - 2026-11-07
95
+
96
+ - 表格全部列(含标题/操作)垂直居中;操作列行内 rowbar 清除 margin-bottom,居中重心不再被顶歪。收件箱表格同步。
97
+
98
+ ## 0.1.7 - 2026-11-07
99
+
100
+ - 源表格状态/未读/操作列垂直居中(宿主表格 td 默认顶对齐,单行内容在双行标题的行里会顶到上沿)。
101
+
102
+ ## 0.1.6 - 2026-11-07
103
+
104
+ - 操作列按钮文字与「操作」表头文字严格对齐(按钮行左拉一个按钮内边距,抵消 .btn.sm 的水平 padding)。
105
+
106
+ ## 0.1.5 - 2026-11-07
107
+
108
+ - 概览卡片改为窄而高的体量(限宽 230px、加大上下留白)。
109
+ - 源表格状态/未读列水平居中(表头与内容一致),操作列左对齐。
110
+
111
+ ## 0.1.4 - 2026-11-07
112
+
113
+ - 概览卡片补底色与边框(暗色主题下可见的盒子感)。
114
+ - 开发注记:面板产物按版本 immutable 缓存,同版本内的改动会被钉死——每次迭代必须升 patch 版本。
115
+
116
+ ## 0.1.3 - 2026-11-07
117
+
118
+ 订阅源页布局:
119
+
120
+ - 概览拆成三张独立小卡片(订阅源/未读/24h 新内容)。
121
+ - 「添加订阅」「拉取全部」移到源表格上方;拉取全部改为主按钮样式。
122
+ - 两个表格改固定列宽布局(table-layout: fixed + colgroup),任何窗口宽度下表头与内容严格对齐。
123
+
124
+ ## 0.1.2 - 2026-11-07
125
+
126
+ 订阅弹框布局重构:
127
+
128
+ - 添加订阅与订阅详情:短字段两两并排(名称/策略、间隔/UA、只推/不推关键词),弹框高度减半。
129
+ - 布尔开关与关键词归入「抓取与过滤」分组;详情弹框状态块与表单用「订阅设置」分隔。
130
+ - 详情状态只给短标签,完整错误只在「最近错误」一行,不再重复。
131
+
132
+ ## 0.1.1 - 2026-11-07
133
+
134
+ 界面打磨(经 WebUI 实机目检驱动):
135
+
136
+ - 收件箱:范围筛选(左)与批量操作(右)分离,长列表改为表头置顶的内部滚动。
137
+ - 所有布尔配置改用宿主勾选框组件;订阅弹框里「允许私网地址」「允许抓取原文」补上说明文字。
138
+ - 源表格状态 pill 只显示短标签(异常 ×N),完整错误在悬停与详情弹框。
139
+ - 详情弹框「下次检查」显示具体时刻而不是误导性的"刚刚"。
140
+
141
+ ## 0.1.0 - 2026-11-07
142
+
143
+ 首个可安装版本。
144
+
145
+ - World 扩展(id `rss`,cortico.api 6):7 个工具 + 3 类事件 + WebUI 管理面板。
146
+ - 多源订阅:RSS 2.0 / Atom / RDF 归一化解析;站点 URL 自动发现 feed;试解析通过才入库;新订阅历史静默(baseline 可选推送最新 N 条)。
147
+ - 轮询:每源间隔(下限 1 分钟)、条件请求(ETag / Last-Modified / 304)、指数退避 + Retry-After、并发上限、启动错峰、GBK/GB2312 编码探测、UA 可配、响应 2MB 上限、私网地址默认拒绝。
148
+ - 通知:20s 合批窗口、单事件 ≤8 头条 / 1200 字符、关注关键词排序;免打扰时段 piggyback + promote(flush) 一次送达;每日晨报(pushDeferred,无内容静默);源连续失败 3 次推诊断(6h 节流)。
149
+ - 收件箱:未读/全部/星标、已读标记、全文抓取 + 正文抽取(失败回落摘要)。
150
+ - 手动拉取:面板每源「拉取」与全局「拉取全部」按钮,以及对话工具 `rss_refresh`,均绕过排程立即轮询。
151
+ - WebUI 面板:概览读数卡(statgrid)、添加订阅、订阅源表(拉取/暂停/退订)、收件箱表(勾选批量标记)、OPML 导入导出;排版全部使用宿主设计系统(sheet/table/segmented)。
152
+ - 配置做成标签(参考 dsh-bridge 模式):通知 / 设置 两个表单标签替代内建「配置」页,保存走 `config.save`(白名单校验+钳制+`ctx.persist`);环境提示词文档标签更名为「环境提示词」。
153
+ - 测试:73 个单元用例(不碰真实网络)+ 9 个真机集成用例(自带本地 RSS 测试服务器,RSS_LIVE_TEST=1 启用)。