Skip to content

feat: 并发修复 + 中文FM + 视频下载 + 全面审计#2

Open
AchengBusiness wants to merge 48 commits into
izscc:mainfrom
AchengBusiness:main
Open

feat: 并发修复 + 中文FM + 视频下载 + 全面审计#2
AchengBusiness wants to merge 48 commits into
izscc:mainfrom
AchengBusiness:main

Conversation

@AchengBusiness

Copy link
Copy Markdown
Contributor

Summary

基于 Issue #1 的讨论,提交全面的功能增强和 Bug 修复 PR。

核心修复

  • 并发卡死修复HTTPServer 改为 ThreadingHTTPServer,支持多标签页同时保存
  • 线程安全_config_lock / _save_lock 双锁保护配置和文件写入
  • 视频下载修复:video_tasks 使用 download_video_async 而非错误地走图片下载
  • _normalize_publish_time:使用 fromisoformat 替代错误的切片逻辑,支持 +08:00 时区

Front Matter 中文化

标题: "..."
tags: []        # 保持英文,OB生态兼容
: "..."
作者主页: "..."
创建时间: "..."
发布时间: "..."
平台: "..."
类别: "[[剪报]]"
阅读状态: false
整理: false

Extension 修复

  • background.js:所有 handler 快照 SERVER_BASE,防止并发修改
  • background.js:GraphQL discovery 去重(_graphqlInflight Map)
  • content.js:所有 Twitter/X 消息添加 platform 字段
  • options.jsfilename_format 默认值对齐 server、sync 默认开启
  • popup.js:动态端口显示
  • discourse.js:平台名 "LinuxDo" 统一

其他修复

  • setup_wizard.py:Windows 文件对话框缩小问题(parent=self.root
  • {handle} / {timestamp} 文件名变量实现
  • feishu-image:// 协议跳过下载
  • author_url 空字符串处理
  • download_images / enable_platform_folders 默认值修正为 True

测试

  • 66 个测试全部通过(23 基础 + 43 OB渲染)
  • 覆盖所有平台(Twitter/X、LinuxDo、Feishu、WeChat)
  • 覆盖边界情况(空推文、超长文本、特殊字符、并发)

Test plan

  • python3 test_full.py — 23/23 PASS
  • python3 test_obsidian_render.py — 43/43 PASS
  • 并发测试:5 个同时请求 325ms 完成
  • 实际浏览器测试(需要安装扩展)

Generated with Claude Code

izscc and others added 24 commits March 24, 2026 03:34
Root cause: ensureFloatingSaveButton() modifies DOM (creates/updates
the floating MD button), which triggers MutationObserver, which calls
bindAll() again → infinite loop. X/Twitter pages were unaffected
because detectFloatingSaveSite() returns null for x.com.

Fixes:
- Skip button update if it already exists with the correct siteKey
- Debounce MutationObserver callback (200ms) to prevent high-frequency
  DOM mutations from causing repeated expensive querySelectorAll calls
Root cause: scrollHeight was captured once at start, but grows as
virtual blocks render. The loop ended at the old maxPos, missing
content beyond it.

Fix: replace fixed-maxPos loop with dynamic bottom detection -
keep scrolling until scrollTop reaches (scrollHeight - clientHeight)
3 consecutive times, dynamically tracking scrollHeight growth.
关键修复:
- x2md.spec: Python DLL 加入 UPX 排除列表,禁用 strip,修复 Windows 启动崩溃
- server.py: CORS 白名单替代通配符、配置字段白名单校验、10MB 请求体上限、视频去重逻辑修正
- extension/background.js: 移除重复 importScripts
- extension/options.js: 移除硬编码开发者路径
- extension/popup.js: 修复 XSS (innerHTML -> createElement+textContent)
- extension/content.js: 替换全页 innerHTML 扫描为精准 DOM 查询
- tray_app.py: 修复开发模式下向导子进程路径
- config.json: 清理开发者个人路径,改为空默认值

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
新功能:
- chrome.storage.sync 跨设备同步偏好设置(文件命名、视频下载等)
- 设置页新增同步开关卡片,同步状态实时显示
- 端口配置持久化到 chrome.storage.local,自定义端口重启后生效

Windows 修复:
- APPDATA 环境变量为空字符串时回退到用户目录
- StreamHandler 强制 UTF-8 编码,修复 emoji 日志导致的崩溃
- 托盘图标字体使用 Windows 完整路径 (C:\Windows\Fonts\arial.ttf)
- pystray hiddenimport 增加 Linux (_xorg) 分支

扩展 bug 修复:
- XSS: showToast 改用 textContent 替代 innerHTML
- 硬编码端口: SERVER_BASE 改为动态,从 storage 读取
- manifest host_permissions 放宽为 http://127.0.0.1/*
- popup.js/options.js 添加 chrome.runtime.lastError 检查
- like 按钮保存增加 500ms 防抖,防止重复触发

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
修复内容:
- [High] abs.twimg.com 加入 host_permissions,修复 GraphQL Operation ID 发现功能静默失败
- [Medium] tabs.onUpdated 监听器增加超时自动清理和 error 状态处理,防止内存泄漏
- [Medium] 端口缓存逻辑修复:改回 9527 时正确清除缓存
- [Medium] config fetch 增加 resp.ok 检查,防止非 JSON 错误体导致崩溃
- [Medium] discourse.js 和 article_markdown.js 修复有序列表渲染,<ol> 内 <li> 正确输出 1. 2. 3.
- [Low] options.js saveConfig 回调增加 lastError 检查

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PyInstaller 以 windowed 模式打包时无控制台窗口,sys.stdout 为 None,
调用 sys.stdout.fileno() 触发 AttributeError: 'NoneType' object has no attribute 'fileno'。
现在先检查 sys.stdout 是否存在,不存在时只用文件日志。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 字体改为 Microsoft YaHei UI,修复 bold 字重下中文字符损坏("开"显示为"++")
- emoji 渲染使用 Segoe UI Emoji 字体并减小字号,避免渲染异常

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
窗口从 720x580 增加到 720x680,确保步骤3(扩展安装指引)
的5个卡片和底部导航按钮都能完整显示。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
移除 resizable(False, False),改为可自由调整窗口大小,
最小尺寸 600x500,支持最大化按钮。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Critical:
- discourse.js: 修复 `element` 未定义变量导致有序列表崩溃(应为 `node`)

High:
- wechat.js: 微信内部相对链接 `/s?__biz=...` 转为绝对 URL
- wechat.js: 新增 GFM pipe table 支持,表格不再渲染为乱文
- server.py: sanitize_filename 清理 Windows 禁止的尾部 `.` 和空格
- server.py: 组装后文件名增加最终长度限制
- server.py: 修复视频重复追加 bug(替换后占位符检测失效)

Medium:
- discourse.js: 新增斜体 `<em>/<i>` 和删除线 `<del>/<s>` 支持
- discourse.js: 图片保留 alt 文本
- discourse.js + article_markdown.js: h5/h6 不再错误地映射为 h4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… rendering fixes

New features:
- Platform folder classification: auto-save to Twitter/, WeChat/, LinuxDo/, Feishu/ subfolders
- Image local download: download remote images to assets/ subfolder for Obsidian offline access
- Video relative paths: videos now saved alongside markdown in assets/ for Obsidian compatibility
- Options UI: new settings cards for platform folders, image download, subfolder naming

Bug fixes:
- WeChat: nested list indentation, video/voice/mini-program placeholders, h5/h6 headings
- Discourse: GFM table support, <details> spoiler blocks, onebox quotes, poll widgets
- Feishu: todo/checkbox blocks, h5-h9 headings, italic/strikethrough/inline code
- Server: fixed UnboundLocalError for image_subfolder in video download path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 飞书:新增 JSON API 直接读取文档内容,不再需要滚动收集懒加载块
  (3 层降级策略:JSON API → DOM 提取 → 滚动收集)
- 飞书:支持所有块类型转换(标题/列表/代码/表格/待办/引用/分割线/图片等)
- Twitter:修复 GraphQL operation ID 与 URL 去重混用 bug
- Twitter:修复 background.js 双超时竞态条件
- Twitter:修复 video_confirmed 分支 download_video 未定义
- Twitter:修复 force_save_tweet 未填充视频占位符
- Twitter:新增 Article 斜体/删除线 Markdown 支持
- 新增:设置页"重复文件处理"选项(默认不覆盖,可选覆盖)
- 新增:URL 去重查找 — 覆盖模式下通过源 URL 匹配已有文件
- 新增:test_full.py 全面测试(23 项覆盖各平台、去重、Windows 兼容)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- background.js: 修复 noteResultVideos 死代码,正确合并长文视频到 data.videos
- feishu.js: 修复嵌套列表子节点丢失 (text || convertChildren 短路问题)
- feishu.js: 修复 document.head 为 null 时的崩溃
- content.js: 修复飞书三层策略 collectedBlocks null TypeError + Promise 缺少 catch
- server.py: front matter 扫描行限制从 15 提升到 30
- build.yml: 修正默认版本号为 1.2.1
- x2md.spec: 修正 Mac app 版本号为 1.2.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
当推文内容包含 [MEDIA_VIDEO_URL:xxx] 占位符时,这些占位符会泄漏到
Front Matter 的 title 字段和生成的文件名中。修复方法是在构建 title
和文件名之前,先用正则清理掉所有视频/媒体占位符。

同时新增 43 个 Obsidian 渲染测试覆盖所有平台和边界场景。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 更新 badge 指向 AchengBusiness fork
- 添加 upstream badge 链接到原仓库
- 添加致谢声明感谢原作者 @izscc
- 更新下载链接到 v1.2.3
- 添加新功能配置字段说明
- 完整更新日志从 v1.0.9 到 v1.2.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
根本原因:HTTPServer 是单线程的,同一时间只能处理一个请求。
当 /save 正在执行(扫描目录、写文件)时,其他所有请求
(/ping 心跳、其他页面的 /save)全部排队等待,导致扩展
超时,页面表现为卡死。

修复:
- HTTPServer -> ThreadingHTTPServer(每个请求独立线程)
- 添加 _config_lock 保护配置读写的线程安全
- 添加 _save_lock 保护文件查找+写入的原子性
- daemon_threads=True 确保服务关闭时线程不阻塞

效果(5 个并发请求测试):
- 修复前:串行处理 ~800ms,/ping 被阻塞
- 修复后:并发处理 325ms,/ping 响应 85ms

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
### 扩展并发修复 (background.js)
- 所有 async handler 入口快照 SERVER_BASE,防止并发修改端口
  导致请求发到错误地址
- GraphQL discovery 增加 inflight 去重(_graphqlInflight Map),
  避免多个 Twitter 标签页同时触发相同的重复 HTML+JS 请求
- 清理死代码(unreachable return)

### 设置向导弹窗修复 (setup_wizard.py)
- filedialog.askdirectory 增加 parent=self.root 参数,
  防止 Windows 下对话框关闭后父窗口被最小化或丢失 geometry
- 对话框关闭后自动恢复窗口尺寸 + deiconify + lift

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Front Matter:
- tags 保持英文,其他字段改为中文(标题/源/作者主页/创建时间/发布时间/平台/类别/阅读状态/整理)
- 修复 _normalize_publish_time 使用 fromisoformat 替代错误的切片逻辑
- 支持 ISO 8601 带时区偏移格式(+08:00)

Server 核心修复:
- 视频下载任务使用 download_video_async 而非 download_image_async(修复视频从未正确下载的bug)
- build_markdown 返回 4 元组(image_tasks, video_tasks 分离)
- _handle_config_update 加锁深拷贝,修复线程安全竞态

Extension 修复:
- background.js save_tweet 中 /config 请求使用 serverBase 快照而非全局变量
- options.js filename_format 默认值与 server DEFAULT_CONFIG 对齐
- content.js 所有 Twitter/X 消息添加 platform 字段

测试:
- 66 个测试全部通过(23 + 43)
- 更新所有 build_markdown 调用为 4 返回值解包

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
新增功能:
- 评论/回复提取: LinuxDo (Discourse JSON API) + Twitter/X 回复
  - 支持 details 折叠 / heading 标题两种显示模式
  - 支持楼层范围过滤 (如 "1-10" 或 "2,5,8")
  - 默认关闭,需手动启用
- iframe 嵌入模式: YouTube/Bilibili 视频可选 iframe 嵌入或本地下载
  - embed_mode 配置: "iframe" / "local"
  - 自动识别 youtube.com/youtu.be/bilibili.com 链接
- Discourse 可配置域名: 支持添加任意 Discourse 论坛
  - 动态注册 content scripts (chrome.scripting API)
  - optional_host_permissions 按需申请权限
  - 自动检测站点类型 (Discourse/非Discourse)
- 设置面板新增: 评论设置卡片 + Discourse 域名管理 + 嵌入模式选择

测试覆盖:
- test_new_features.py: 57 项新增功能测试 (全通过)
- test_full.py: 44 项核心功能测试 (全通过)
- test_obsidian_render.py: 51 项 Obsidian 渲染测试 (全通过)
- 总计 152 项测试全部通过

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AchengBusiness and others added 5 commits March 29, 2026 04:00
新增飞书文档一键复制功能(opt-in),支持只读/禁止复制的飞书文档:
- 三策略内容提取:API → 滚动收集 → DOM兜底
- 输出 Obsidian 兼容 Markdown(图片URL链接、视频iframe嵌入)
- 剪贴板写入双重降级(Clipboard API → execCommand)
- 自动解除飞书CSS/JS复制保护
- 标题#字符转义防止Markdown格式破坏
- URL括号编码防止图片链接断裂

扩展 site_actions 浮动保存按钮支持微信公众号页面

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
单击点赞按钮:拦截点赞行为,自动保存帖子到OB
双击点赞按钮:恢复原始点赞功能,不保存

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
同一帖子/评论在当前会话内只保存一次,重复点击会提示"已保存过"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 点赞主帖:保存主帖 + 全部评论(不变)
- 点赞评论:保存主帖 + 该评论 + 回复该评论的所有内容
- 不再保存不相关的评论

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AchengBusiness and others added 18 commits March 29, 2026 04:25
- server.py: _normalize_publish_time 支持ISO8601/RFC2822/通用格式转北京时间
- 平台名: Feishu→飞书, WeChat→微信公众号, LinuxDo→LINUX DO
- options.html: 平台文件夹配置同步更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Twitter/X: 从GraphQL API提取推文#hashtags
- LINUX DO/Discourse: 从topic JSON提取帖子标签(tags)
- 微信公众号: 从og:article:tag meta标签提取
- server.py: 合并tags+hashtags去重,写入frontmatter tags字段

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
新增功能:
- 飞书多维表格保存(含附件上传 MD/HTML)
- Notion Database 保存(含内容块批量写入)
- HTML 文件导出(Markdown 转 HTML,GitHub 风格样式)
- 三套主题的 Options 设置页重构
- manifest v1.5.0,新增 downloads/飞书/Notion host 权限

架构重构:
- 提取 dispatchMultiTargetSave() 共享函数,save_tweet 和 force_save_tweet 统一调用
- dispatchMultiTargetSave 支持传入已获取的 cfg,避免重复网络请求
- 显式传递 cfg 字段到各 handler,防止 Object spread 键冲突
- content.js handleSaveResponse 支持多目标结果格式

错误处理审计修复(10项):
- [HIGH] 修复飞书 Token 过期重试死代码(classifyFeishuError 返回中文但匹配英文)
- [MED] get_config 增加 resp.ok 检查,防止非 JSON 响应 SyntaxError
- [MED] dispatchMultiTargetSave 使用浅拷贝 enriched,不再原地污染调用方 data
- [MED] 所有目标禁用时返回明确错误信息而非静默 success:false
- [MED] handleSaveToFeishu/Notion 增加必填字段前置验证
- [LOW] handleDownloadHtml 空文件名回退 untitled
- [LOW] convertMarkdownToHtml 未关闭代码块自动补全 + 500KB 截断保护
- [LOW] HTML 导出 btoa 超 2MB data URL 安全检查
- [LOW] 消息 handler 清理 message.data||message 为 message.data||{}
- [LOW] Notion page.id 创建后 null 检查

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CRITICAL安全修复:
- sender验证: onMessage添加sender.id检查,阻止第三方扩展消息
- XSS防护: DOMParser替代innerHTML写入(discourse.js)
- XSS防护: popup.js全部改用textContent/DOM API
- postMessage origin: feishu.js改用location.origin替代"*"
- SSRF防护: options.js Discourse域名禁止内网地址
- 数据结构: fetchDiscourseReplies返回结构化对象(非数组属性)

HIGH修复:
- SYNC_FIELDS去重: 移除重复定义,统一到顶层常量
- 表格转换去重: 提取共享convertTableToGfm到dom_utils.js
- convertMarkdownToHtml重写: 支持Obsidian任务列表、修复列表排序

MEDIUM修复:
- Markdown链接转义: 新增escapeMdLinkText/escapeMdLinkUrl共享函数
  所有转换器(discourse/feishu/wechat/article_markdown)统一使用
- 运算符优先级: 添加括号明确逻辑(3处)
- async关键字: 移除options.js中无await的async声明

LOW修复:
- 日志管理: 23处console.log替换为debugLog(X2MD_DEBUG开关控制)
- debugLog递归修复: 函数体正确调用console.log而非自身
- bold+italic重叠: feishu.js支持***text***格式

全部35个测试通过,0失败。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
server.py 的 ALLOWED_CONFIG_KEYS 白名单缺少这些字段,
导致 options 页面保存时这些配置被服务端静默丢弃。

新增白名单字段:
- enable_copy_unlock(一键复制按钮)
- feishu_* 系列(飞书 Bitable 配置)
- notion_* 系列(Notion Database 配置)
- html_export_folder(HTML 导出目录)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
X/Twitter 推文中常见 hashtag(如 #山东 #高中语文老师),这些 # 号
会保留在文件名中,导致 Markdown 图片引用路径被解析为 anchor fragment,
Obsidian 找不到对应的图片文件。

修复:
- sanitize_filename 增加过滤 #、%、[、] 等 Markdown/URL 特殊字符
- 图片路径含空格时用尖括号包裹,确保解析正确

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
上次修改误判了问题根因,实际问题不是 # 号导致路径断裂,
而是图片附件的目录层级引用问题。先还原,后续针对真实问题修复。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Obsidian 对标准 Markdown 链接路径的解析规则:
- 附件/xxx.jpg → 从仓库根目录解析(错误)
- ./附件/xxx.jpg → 从当前文件位置解析(正确)

开启平台分类文件夹后,.md 文件在 Twitter/ 子目录下,
图片也保存在 Twitter/附件/ 下,但不带 ./ 前缀时 Obsidian
会去根目录的 附件/ 文件夹找图片,导致引用断裂。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
核心改动:
- 新增微信视频号视频保存开关(默认关闭),可在选项面板勾选启用
- 选项面板从13+卡片重构为9个逻辑分组,减少臃肿
- 修复 PyInstaller 打包缺少 zoneinfo/tzdata 导致 Win/Mac 构建崩溃
- 飞书 feishu-image:// 协议图片替换为说明文本(避免 Obsidian 渲染失败)
- HTML 导出支持 [MEDIA_VIDEO_URL] 占位符和 ![[]] wiki-link 渲染
- CI Python 从 3.13 降级到 3.12 提升 PyInstaller 兼容性
- config.json 移除硬编码 Linux 路径
- 北京时间处理增加 timezone(timedelta) 回退方案
- 5轮回归测试通过(187测试/0失败)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
主要变更:
- 修复 PyInstaller 打包后 ZoneInfo 时区数据缺失导致保存失败
- get_config 改用 getCachedConfig() 缓存优先策略
- 飞书表格 GFM + HTML 双格式渲染 (renderTableDualFormat)
- 飞书 API 模式智能列表合并(连续列表项紧凑排列)
- 微信公众号增强:视频号开关、媒体占位符清理
- 标题截断后空标题 fallback 处理
- config.json 补全所有选项面板字段默认值
- build_markdown 异常增加完整 traceback 日志

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 修复版本升级后设置向导不弹出的问题(config合并新增字段)
- 修复版本升级后扩展文件不更新的问题(版本检测+自动替换)
- 更新设置向导描述:反映多平台+多目标保存能力
- 更新 README:v1.5.x 完整更新日志、下载链接、配置说明
- 更新 Release 模板:新增功能介绍和升级须知
- 统一版本号到 1.5.2(server/manifest/spec/build.yml)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 为 discoverGraphQLOperationIdsFromPage 的页面和脚本请求添加 8s/5s 超时
- 为 fetchViaGraphQL 的 GraphQL API 请求添加 10s 超时
- 为 fetchViaOEmbed 的 oEmbed 请求添加 5s 超时
- 为 save_tweet 处理器的 config 获取添加 3s 超时
- 为 dispatchMultiTargetSave 的 config/save 请求添加 3s/30s 超时
- 为 update_config/reset_config 请求添加 5s/3s 超时
- 为飞书图片上传的图片获取添加 10s 超时
- 为 save_tweet 处理器添加 60s 整体超时保护,防止 MV3 worker 被杀后永远不返回

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. 飞书多维表格:测试连接时完整验证 7 个必需字段(名称+类型),
   缺失字段自动调用 API 创建,无需手动配置
2. 微信公众号:付费文章保存前自动移除付费遮罩层(CSS覆盖+DOM清理),
   尝试提取完整内容而非仅保存截断预览
3. Discourse/LINUX DO:fetchDiscourseReplies 添加 15s AbortSignal.timeout,
   防止 JSON API 请求无限挂起
4. 选项页面:飞书测试连接结果展示增强,显示字段验证详情和自动创建结果

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
对齐 FEISHU-FIELD-VALIDATION.md 的 9 个必需字段:
标题、链接、作者、分类、标签、保存时间、评论数、附件、正文

handleSaveToFeishu 新增写入:
- 分类:使用 platform 字段(微信公众号/LINUX DO/飞书等)
- 标签:使用 tags 数组拼接
- 评论数:使用 comments 数组长度

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
按照阿成确认的字段配置:
标题(文本)、链接(超链接)、作者(单选)、分类(文本)、
标签(文本)、保存时间(日期)、评论数(数字)

移除附件和正文两个必需字段(保存时仍会写入,但不作为必需验证项)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v1.6.0 新功能与修复:
- 新增飞书 messenger 聊天记录提取(双策略:内部API注入 + DOM兜底)
- 修复 handleFloatingSave 缺少 discourse case 导致自定义 Discourse 域名点击无响应
- 修复 setSiteDiscourseDomains 未调用导致浮动按钮在自定义 Discourse 域名不显示
- 增加 sendToBackground 诊断日志,便于排查 URL 传递问题
- manifest.json 添加 feishu.cn/messenger 和 larksuite.com/messenger 权限
- site_actions.js 添加 feishu_chat 浮动按钮配置

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- README: add feishu chat, Discourse multi-domain to platform table
- README: add v1.6.0 changelog entry, update download links
- x2md.spec: bump CFBundleShortVersionString to 1.6.0
- build.yml: bump default version to 1.6.0, update description
- server.py: bump /ping version to 1.6.0
- manifest.json: update description text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extension修复:
- X2MD命名空间统一(media_helpers/twitter_graphql/article_markdown/wechat)
- 飞书chatId提取增强+诊断日志
- background.js safeSendResponse防重复响应
- content.js WeakSet/WeakMap防重复注入+聊天阈值
- dom_utils.js GFM表格colspan/rowspan支持
- site_actions.js Discourse域名委托给discourse.js
- discourse.js分页获取所有回复(fetchDiscourseReplies)

Python EXE修复:
- tray_app.py: 崩溃弹窗+crash.log双兜底, DEBUG级日志, 4阶段启动诊断
- server.py: 请求/配置/保存全链路DEBUG日志
- setup_wizard.py: 向导步骤/完成/异常全程日志

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
P0 严重问题:
1. permissions.request 在 background.js (service worker) 中 → 移至 options.js(用户手势上下文)
2. DEFAULT_CONFIG 浅拷贝(.copy())→ 改为 copy.deepcopy() 防嵌套字典污染

配置补全:
- platform_folder_names 添加 Discourse / 飞书聊天 映射
- 补充 theme / notion_prop_comment_count 默认值

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants