Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to MrRSS will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Add reversible ad filtering with site exceptions, local previews and opt-in AI review using existing AI profiles. Require quoted evidence and a second audit before accepting AI suggestions; preserve original content and provide manual/automatic modes. (#1208)
- Improve the visual XPath picker with undo/redo, simplified layouts, parent/child shortcuts, paginated extraction results, missing-field diagnostics and consistent optional date/image suggestions. (#1208)

- Add a dedicated Notifications settings tab with locally bundled Telegram, Discord and Feishu/Lark logos, multiple destinations, encrypted credentials, connection tests, condition-based article alerts, scheduled briefings, quiet hours, previews and delivery history. Persist queued messages across restarts and retry transient failures with bounded backoff in desktop and server modes. (#1208)

### Fixed

- Keep settings usable on narrow screens with horizontal tab navigation and a separate search row. Protect unsaved notification drafts when closing settings or switching tabs. (#1208)

## [1.3.36] - 2026-09-20

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<strong>English</strong> | <a href="README_zh.md">简体中文</a>
</p>

[![Version](https://img.shields.io/badge/version-1.3.36-blue.svg)](https://github.com/DevXDojo/MrRSS/releases)
[![Version](https://img.shields.io/badge/version-1.3.37-blue.svg)](https://github.com/DevXDojo/MrRSS/releases)
[![License](https://img.shields.io/badge/license-GPLv3-green.svg)](LICENSE)
[![Go](https://img.shields.io/badge/Go-1.27+-00ADD8?logo=go)](https://go.dev/)
[![Wails](https://img.shields.io/badge/Wails-v3%20alpha-red)](https://wails.io/)
Expand Down
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<a href="README.md">English</a> | <strong>简体中文</strong>
</p>

[![Version](https://img.shields.io/badge/version-1.3.36-blue.svg)](https://github.com/DevXDojo/MrRSS/releases)
[![Version](https://img.shields.io/badge/version-1.3.37-blue.svg)](https://github.com/DevXDojo/MrRSS/releases)
[![License](https://img.shields.io/badge/license-GPLv3-green.svg)](LICENSE)
[![Go](https://img.shields.io/badge/Go-1.27+-00ADD8?logo=go)](https://go.dev/)
[![Wails](https://img.shields.io/badge/Wails-v3%20alpha-red)](https://wails.io/)
Expand Down
4 changes: 2 additions & 2 deletions build/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ info:
description: "A modern, standalone RSS reader" # The application description
copyright: "Copyright © 2026" # Copyright text
comments: "Built with Wails" # Comments
version: "1.3.36" # The application version
version: "1.3.37" # The application version

# iOS build configuration (uncomment to customise iOS project generation)
# Note: Keys under `ios` OVERRIDE values under `info` when set.
Expand All @@ -21,7 +21,7 @@ info:
# # The display name shown under the app icon (CFBundleDisplayName/CFBundleName)
# displayName: "MrRSS"
# # The app version to embed in Info.plist (CFBundleShortVersionString/CFBundleVersion)
# version: "1.3.36"
# version: "1.3.37"
# # The company/organisation name for templates and project settings
# company: "Ch3nyang"
# # Additional comments to embed in Info.plist metadata
Expand Down
4 changes: 2 additions & 2 deletions build/darwin/Info.dev.plist
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
<key>CFBundleIdentifier</key>
<string>com.mrrss.app</string>
<key>CFBundleVersion</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>CFBundleGetInfoString</key>
<string>Built with Wails</string>
<key>CFBundleShortVersionString</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>CFBundleIconFile</key>
<string>icons</string>
<key>LSMinimumSystemVersion</key>
Expand Down
4 changes: 2 additions & 2 deletions build/darwin/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
<key>CFBundleIdentifier</key>
<string>com.mrrss.app</string>
<key>CFBundleVersion</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>CFBundleGetInfoString</key>
<string>Built with Wails</string>
<key>CFBundleShortVersionString</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>CFBundleIconFile</key>
<string>icons</string>
<key>LSMinimumSystemVersion</key>
Expand Down
4 changes: 2 additions & 2 deletions build/darwin/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ tasks:
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>CFBundleVersion</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<key>NSHighResolutionCapable</key>
Expand Down
2 changes: 1 addition & 1 deletion build/darwin/create-dmg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ set -e

APP_NAME="MrRSS"
# Get version from frontend/package.json if available, otherwise use default
VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' frontend/package.json 2>/dev/null | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "1.3.36")
VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' frontend/package.json 2>/dev/null | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "1.3.37")
APP_PUBLISHER="Ch3nyang"
APP_URL="https://github.com/DevXDojo/MrRSS"
APP_DESCRIPTION="A Modern, Cross-Platform Desktop RSS Reader"
Expand Down
4 changes: 2 additions & 2 deletions build/ios/Info.dev.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.3.36-dev</string>
<string>1.3.37-dev</string>
<key>CFBundleVersion</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
Expand Down
4 changes: 2 additions & 2 deletions build/ios/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>CFBundleVersion</key>
<string>1.3.36</string>
<string>1.3.37</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>MinimumOSVersion</key>
Expand Down
4 changes: 2 additions & 2 deletions build/ios/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ set -e
# Build configuration
APP_NAME="MrRSS"
BUNDLE_ID="com.mrrss.app"
VERSION="1.3.36"
BUILD_NUMBER="1.3.36"
VERSION="1.3.37"
BUILD_NUMBER="1.3.37"
BUILD_DIR="build/ios"
TARGET="simulator"

Expand Down
2 changes: 1 addition & 1 deletion build/linux/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ tasks:
cmds:
- cd {{.BIN_DIR}} && tar -czf {{.APP_NAME}}-{{.VERSION}}-linux-{{.ARCH}}.tar.gz {{.APP_NAME}}
vars:
VERSION: '1.3.36'
VERSION: '1.3.37'
ARCH: '{{.ARCH | default "amd64"}}'

generate:dotdesktop:
Expand Down
2 changes: 1 addition & 1 deletion build/linux/create-appimage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ set -e

APP_NAME="MrRSS"
# Get version from frontend/package.json if available, otherwise use default
VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' frontend/package.json 2>/dev/null | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "1.3.36")
VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' frontend/package.json 2>/dev/null | head -1 | sed 's/.*"\([^"]*\)".*/\1/' || echo "1.3.37")
# Get architecture from environment variable or default to amd64
ARCH=${ARCH:-amd64}
echo "Target architecture: ${ARCH}"
Expand Down
2 changes: 1 addition & 1 deletion build/linux/nfpm/nfpm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
name: "MrRSS"
arch: ${GOARCH}
platform: "linux"
version: "1.3.36"
version: "1.3.37"
section: "default"
priority: "extra"
maintainer: ${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>
Expand Down
4 changes: 2 additions & 2 deletions build/windows/info.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"fixed": {
"file_version": "1.3.36"
"file_version": "1.3.37"
},
"info": {
"0000": {
"ProductVersion": "1.3.36",
"ProductVersion": "1.3.37",
"CompanyName": "Ch3nyang",
"FileDescription": "MrRSS",
"LegalCopyright": "Copyright © 2026",
Expand Down
4 changes: 2 additions & 2 deletions build/windows/installer.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
; All paths in this script are relative to the script directory.

!define APP_NAME "MrRSS"
!define APP_VERSION "1.3.36"
!define APP_VERSION_NUMERIC "1.3.36.0" ; NSIS requires X.X.X.X format
!define APP_VERSION "1.3.37"
!define APP_VERSION_NUMERIC "1.3.37.0" ; NSIS requires X.X.X.X format
!define APP_PUBLISHER "Ch3nyang"
!define APP_URL "https://github.com/DevXDojo/MrRSS"
!define APP_DESCRIPTION "A Modern, Cross-Platform Desktop RSS Reader"
Expand Down
2 changes: 1 addition & 1 deletion build/windows/nsis/wails_tools.nsh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
!define INFO_PRODUCTNAME "MrRSS"
!endif
!ifndef INFO_PRODUCTVERSION
!define INFO_PRODUCTVERSION "1.3.36"
!define INFO_PRODUCTVERSION "1.3.37"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "Copyright © 2026"
Expand Down
2 changes: 1 addition & 1 deletion build/windows/wails.exe.manifest
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity type="win32" name="com.mrrss.app" version="1.3.36.0" processorArchitecture="*"/>
<assemblyIdentity type="win32" name="com.mrrss.app" version="1.3.37.0" processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
Expand Down
3 changes: 3 additions & 0 deletions config/defaults.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"ad_filter_config": "{\"enabled\":true,\"allowlist\":\"\",\"rules\":\"\",\"revision\":0,\"ai_enabled\":false,\"ai_mode\":\"review\",\"include_self_promotion\":false}",
"ai_ad_filter_profile_id": "",
"ai_api_key": "",
"ai_chat_enabled": false,
"ai_chat_profile_id": "",
Expand Down Expand Up @@ -82,6 +84,7 @@
"network_bandwidth_mbps": "0",
"network_latency_ms": "0",
"network_speed": "medium",
"notification_config": "",
"notion_api_key": "",
"notion_enabled": false,
"notion_page_id": "",
Expand Down
85 changes: 85 additions & 0 deletions docs/AD_FILTERING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Advertising filtering / 广告过滤

Configure **Settings → Content → Ad filtering**. AI profile selection is also
available under **Settings → AI → AI features**. Filtering works in desktop and
server readers; no browser extension is installed.

在「设置 → 内容 → 广告过滤」配置功能,也可以在「设置 → AI → AI 功能」指定模型。
桌面版和服务端阅读器使用相同功能,不安装浏览器扩展。

## Defaults and scope / 默认行为与范围

- Basic filtering is enabled: dedicated advertising network resources, explicit
network slots and tracking pixels with both tiny dimensions and endpoint
evidence. Names such as `ad`, “sponsored”, prices or brand names alone do not
trigger removal. Ordinary links and ambiguous promotional prose remain.
- AI is off until enabled. **Review first** analyzes only when requested, shows
quoted evidence, and waits for Apply. **Automatic** analyzes while reading and
applies accepted results; the article stays readable during the request.
- AI uses existing profiles, provider protocols, proxy settings and shared usage
limits. A local Ollama profile can keep analysis on the user's machine. External
profiles receive article text, headings and link hostnames; URLs with query
strings and source HTML are not included in the segment payload.
- AI covers RSS and extracted full text. The in-app webpage proxy applies basic
resource filtering and static custom CSS rules only. Dynamic page content and
external browsers are outside AI coverage.
- Original cached content is preserved. **Show unfiltered content** restores the
sanitized original, including sections hidden by basic or AI filtering.

基础过滤默认启用,仅处理明确广告资源和有额外证据的跟踪像素,不凭关键词删除正文。
AI 默认关闭,启用后默认先审核;只有主动分析或开启自动模式才向模型发送文章文本。
AI 复用已有模型配置、代理和公共用量限制,可选择本地 Ollama。网页视图只支持基础
资源过滤与静态规则,AI 作用于 RSS 正文及提取全文;外部浏览器不受影响。
过滤属于显示操作,不修改原始缓存,可以随时显示经过安全清理的未过滤内容。

## Accuracy safeguards / 准确性保护

The model classifies numbered, non-overlapping blocks instead of generating
HTML or selectors. Editorial context accompanies candidates. Code, quotations,
headings, oversized blocks and structural containers cannot be AI removal
targets. Proposed decisions require known IDs, supported categories, an exact
evidence quote, a high model confidence score and a second confirming audit.
Broad removals (over 35% of readable text or leaving fewer than 80 characters)
are rejected. Publisher self-promotion is separately opt-in.

Each uncached document uses at most two model requests, with cancellation,
timeouts, a shared concurrency bound and a bounded in-memory decision cache.
The cache expires after 24 hours, resets on restart, and includes document,
options and model configuration in its key. Up to 120 eligible blocks / 40,000
characters are scanned; the reader indicates partial scans. Other content stays.

Two model judgments are safeguards, **not a measured accuracy guarantee**.
Model confidence is not a calibrated probability. Default review mode and the
original-content switch are therefore part of the feature, not error recovery
after deletion. Regression tests use deterministic model responses to verify
trust boundaries and preservation; they do not claim production-model accuracy.

模型只能选择编号片段,不能自行生成用于删除的 HTML 或选择器。候选片段附带正文
上下文;代码、引用、标题和结构容器不会成为 AI 删除目标。结果必须有原文证据、
有效编号、高置信度及第二次审核同意,删除范围过大会保留全文。发布者自身推广另有开关。
两次同意不代表准确率保证,模型置信度也不等于统计准确率,因此默认保留人工审核。
自动化测试验证协议与保护机制,不把模拟模型结果当作真实模型准确率评测。

## Exceptions, rules and saving / 例外、规则与保存

Site exceptions contain one hostname per line, including its subdomains. They
disable both basic and AI filtering for that site. Filtering options use an
explicit Save button with stale-write protection and an unsaved-changes prompt.
AI profile selection uses the existing settings autosave.

Advanced cosmetic rules are a restricted CSS subset, not full Adblock Plus or
uBlock list compatibility. Maximum: 100 rules / 32 KB. Example:

```text
example.org##.promotion
example.org#@#.editorial-disclosure
```

The second rule protects the element and its enclosing container from **basic**
filtering. Rules do not instruct the AI. Regex, scripts, remote lists and certain
expensive selectors are unsupported. Preview the supplied or pasted sample before
saving; AI previews consume the shared quota, while basic preview stays local.

站点例外每行一个主机名,包含子域名,同时跳过基础过滤与 AI。高级规则是受限 CSS
子集,不兼容完整的广告过滤列表;`#@#` 只保护基础过滤,不影响 AI 判断。
可在保存前试用样例,基础预览在本地执行,AI 预览计入公共用量。
Loading
Loading