[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-82183":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":12,"openIssues":13,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":13,"stars30d":15,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":16,"rankGlobal":8,"rankLanguage":8,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":8,"pushedAt":8,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":14,"starSnapshotCount":14,"syncStatus":15,"lastSyncTime":25,"discoverSource":26},82183,"rule","xream\u002Frule","xream",null,"JavaScript",23,7,21,1,0,2,2.71,"GNU General Public License v3.0",false,"main",true,[],"2026-06-12 02:04:24","# rule\n\n`rule` 是 xream 的 Mihomo rule-provider 构建仓库。它从 `source\u002F` 下的 YAML 配置拉取、读取或内联规则源，按 Mihomo `domain` \u002F `ipcidr` \u002F `classical` 能力拆分后，生成可直接引用的 `.mrs`、`.txt`、`.yaml` 产物和每个目录的使用说明。\n\n`main` 分支维护 source 配置、构建脚本和测试；生成结果发布到 `release` 分支。\n\n## 使用入口\n\n- Release 分支：[xream\u002Frule@release](https:\u002F\u002Fgithub.com\u002Fxream\u002Frule\u002Ftree\u002Frelease)\n- 每个 `source\u002F\u003Csource-name>\u002F` 会生成对应的 `release\u002F\u003Csource-name>\u002F`\n- 每个 release 目录里的 `README.md` 会生成可复制的 Mihomo 配置、source 链接和 raw URL\n\n通用 raw URL 形式：\n\n```text\nhttps:\u002F\u002Fraw.githubusercontent.com\u002Fxream\u002Frule\u002Frelease\u002F\u003Csource-name>\u002F\u003Cartifact-name>\n```\n\n普通路由规则会固定生成 `domain`、`ipcidr`、`classical YAML` 三类 provider，并生成 `rules`、`rule-providers` 和对应的 `proxy-groups`：\n\n如果 release 产物在 GitHub private repo，可用 `github-token-header` 给 raw URL 请求加 GitHub token。\n\n```yaml\nproxy-groups:\n  - name: \"\u003Crule-set-name>\"\n    type: select\n    proxies: []\n\nrules:\n  - RULE-SET,\u003Crule-set-name>_Domain,\u003Crule-set-name>\n  - RULE-SET,\u003Crule-set-name>,\u003Crule-set-name>\n  - RULE-SET,\u003Crule-set-name>_IP,\u003Crule-set-name>,no-resolve\n\nrule-anchor:\n  github-token-header: &github-token-header { Authorization: [\"Bearer \u003CYOUR_GITHUB_TOKEN>\"] }\n  ip: &ip { type: http, behavior: ipcidr, format: mrs, interval: 86400, header: *github-token-header }\n  domain: &domain { type: http, behavior: domain, format: mrs, interval: 86400, header: *github-token-header }\n  yaml: &yaml { type: http, behavior: classical, format: yaml, interval: 86400, header: *github-token-header }\n\nrule-providers:\n  \u003Crule-set-name>_Domain: { \u003C\u003C: *domain, url: https:\u002F\u002Fraw.githubusercontent.com\u002Fxream\u002Frule\u002Frelease\u002F\u003Csource-name>\u002F\u003Crule-set-name>_Domain.mrs }\n  \u003Crule-set-name>: { \u003C\u003C: *yaml, url: https:\u002F\u002Fraw.githubusercontent.com\u002Fxream\u002Frule\u002Frelease\u002F\u003Csource-name>\u002F\u003Crule-set-name>.yaml }\n  \u003Crule-set-name>_IP: { \u003C\u003C: *ip, url: https:\u002F\u002Fraw.githubusercontent.com\u002Fxream\u002Frule\u002Frelease\u002F\u003Csource-name>\u002F\u003Crule-set-name>_IP.mrs }\n```\n\n如果上游当前没有某一类规则，对应 provider 会写入一个不可命中的占位规则，release README 会在对应 `rules` \u002F `rule-providers` 行追加 `placeholder` 注释，并把占位项排在同组真实规则后面。明确知道自己只需要某些 provider 时，可以不复制带 `placeholder` 注释的项。\n\n`mihomo: fake-ip-filter` 会生成 `dns.fake-ip-filter` 用法：\n\n```yaml\ndns:\n  fake-ip-filter-mode: blacklist\n  fake-ip-filter:\n    - \"rule-set:\u003Crule-set-name>_Domain\"\n\nrule-anchor:\n  github-token-header: &github-token-header { Authorization: [\"Bearer \u003CYOUR_GITHUB_TOKEN>\"] }\n  domain: &domain { type: http, behavior: domain, format: mrs, interval: 86400, header: *github-token-header }\n\nrule-providers:\n  \u003Crule-set-name>_Domain: { \u003C\u003C: *domain, url: https:\u002F\u002Fraw.githubusercontent.com\u002Fxream\u002Frule\u002Frelease\u002F\u003Csource-name>\u002F\u003Crule-set-name>_Domain.mrs }\n```\n\n实际 provider 名、group 名和文件名以 release 目录生成的 `README.md` 为准。\n\n## 产物规则\n\n- `\u003Cstem>_Domain.mrs`：Mihomo `domain` behavior rule-provider\n- `\u003Cstem>_Domain.txt`：从 domain `.mrs` 反导出的可读文本\n- `\u003Cstem>_IP.mrs`：Mihomo `ipcidr` behavior rule-provider\n- `\u003Cstem>_IP.txt`：从 IP `.mrs` 反导出的可读文本，会补回 `IP-CIDR,` \u002F `IP-CIDR6,` 前缀方便检查\n- `\u003Cstem>.yaml`：不能安全转换为 `domain` \u002F `ipcidr` 的剩余 classical 规则\n- `\u003Centry>.original.\u003Cext>`：本次拉取、读取或内联得到的上游原始内容\n- `artifacts-manifest.json`：provider 产物清单，记录三类 provider artifact 是否为占位\n- `README.md`：该 release 目录的 source、Mihomo 配置和 artifact 链接\n\n同一个 config YAML 内的 enabled 条目默认合并成同一组产物，并按输出 bucket 去重，保留首次出现顺序。设置 `separate: true` 后，该条目会单独生成一组产物。\n\n默认产物 stem 来自 config 文件名；`separate: true` 时来自条目 `name`。不适合文件名或 provider key 的字符会替换为 `_`，domain \u002F ipcidr 产物会分别追加 `_Domain` \u002F `_IP`。\n\n普通路由规则即使某个 bucket 为空也会生成对应产物，避免上游之后新增类型时还要重新补 Mihomo provider 配置。占位规则使用：\n\n- `domain`：`blackhole.invalid`\n- `ipcidr`：`203.0.113.1\u002F32`\n- `yaml(remaining)`：`DOMAIN,blackhole.invalid`\n\n## Source 配置\n\n配置文件放在：\n\n```text\nsource\u002F\u003Csource-name>\u002F\u003Crule-set-name>.yaml\n```\n\n构建脚本会扫描每个 source 目录下所有 `.yaml` \u002F `.yml` 文件，只处理看起来像 source entry 数组的配置文件。配置文件必须是顶层数组，每一项表示一个规则源：\n\n```yaml\n- name: Example\n  description: Example rules\n  type: http\n  behavior: classical\n  format: yaml\n  url: https:\u002F\u002Fexample.com\u002Frules.yaml\n\n- name: LocalExample\n  type: file\n  behavior: domain\n  format: text\n  path: local-rules.txt\n\n- name: InlineExample\n  type: inline\n  behavior: ipcidr\n  format: text\n  payload:\n    - 192.0.2.0\u002F24\n```\n\n字段说明：\n\n| field | required | description |\n| --- | --- | --- |\n| `name` | enabled entry 必填 | 上游条目名称，也用于原始文件名。 |\n| `description` | no | release README 的 source 表格说明。 |\n| `enabled` | no | 默认 `true`；只有显式 `false` 才会禁用。 |\n| `type` | yes | `http`、`file`、`inline`。 |\n| `url` | `type: http` | 绝对 URL。 |\n| `headers` | no | `type: http` 时的请求 headers，必须是 scalar mapping。 |\n| `path` | `type: file` | 本地规则文件路径；相对当前 source 目录解析，且不能指向项目外。 |\n| `payload` | `type: inline` | 内联规则内容；可以是 string、array 或 YAML object。 |\n| `behavior` | `format: mrs` 时必填 | `domain`、`ipcidr`、`classical`；`format: mrs` 不能使用 `classical`。 |\n| `format` | no | `yaml`、`text`、`mrs`；默认 `yaml`。 |\n| `mihomo` | no | 默认 `rules`；可设为 `fake-ip-filter`。 |\n| `separate` | no | 默认 `false`；设为 `true` 时该条目单独生成产物。 |\n\n`mihomo: fake-ip-filter` 只会生成以 config 文件名为 stem 的 domain `.mrs`，并写入 `dns.fake-ip-filter` 示例。同一个 YAML 中只要出现 enabled 的 `mihomo: fake-ip-filter`，非 `fake-ip-filter` 条目会被忽略；普通路由规则应放到另一个 YAML。\n\n## 分类逻辑\n\n构建时会把普通路由规则拆成三类，并固定输出三类产物：\n\n- `mrs(domain)`：可安全转换成 Mihomo `domain` behavior 的规则\n- `mrs(ipcidr)`：可安全转换成 Mihomo `ipcidr` behavior 的规则\n- `yaml(remaining)`：不能等价转换的规则，保留为 classical YAML\n\n`mihomo: fake-ip-filter` 是例外，只输出 domain `.mrs` \u002F `.txt`，不会生成 IP 或 remaining YAML provider。\n\n常见转换：\n\n- `DOMAIN,example.com` -> `example.com`\n- `DOMAIN-SUFFIX,example.com` -> `+.example.com`\n- plain domain payload -> domain\n- `IP-CIDR,192.0.2.0\u002F24` -> `192.0.2.0\u002F24`\n- `IP-CIDR6,2001:db8::\u002F32` -> `2001:db8::\u002F32`\n- `IP-CIDR,192.0.2.0\u002F24,no-resolve` -> `192.0.2.0\u002F24`\n- `IP-CIDR,192.0.2.0\u002F24,src` -> remaining YAML\n- plain IP payload -> `\u002F32` 或 `\u002F128`\n- `PROCESS-NAME,Example.app` -> remaining YAML\n\n`DOMAIN-WILDCARD,*.example.com`、`DOMAIN-WILDCARD,stun*.example.com`、`DOMAIN,*`、`DOMAIN,+.example.com`、`DOMAIN-SUFFIX,*.example.com`、带 `src` 参数的 `IP-CIDR` \u002F `IP-CIDR6`、尾部带 `.` 或含有不安全通配符语义的 classical 规则不会强行转换成 MRS，会留在 remaining YAML。Mihomo MRS 的 `domain` behavior 使用 DomainTrie payload；classical `DOMAIN-WILDCARD` 使用 glob 语义，两者不能等价直转。\n\n`MATCH`、`RULE-SET`、`SUB-RULE` 不能放在 Mihomo `behavior: classical` rule-provider 内；如果源里出现这些 top-level 规则，构建会输出 warning 并忽略这些规则。\n\n## 本地开发\n\n安装依赖：\n\n```bash\nbun install\n```\n\n运行测试：\n\n```bash\nbun test\n```\n\n生成 release 产物：\n\n```bash\nbun run build:release -- --repo xream\u002Frule\n```\n\n检查三类 provider 产物的逻辑新增 \u002F 减少，并在有变化时发送 Telegram 通知：\n\n```bash\nTELEGRAM_BOT_TOKEN=... TELEGRAM_CHAT_ID=... bun run notify:artifact-changes\n```\n\n通知只比较 `domain-mrs`、`ipcidr-mrs`、`remaining-yaml` 是否从占位变成真实，或从真实变回占位；规则内容变化、`.txt`、原始文件和 README 变化不会触发通知。消息使用 Telegram HTML 格式。默认比较当前 `.release\u002Fartifacts-manifest.json` 和 `origin\u002Frelease`；可用 `--previous-manifest`、`--previous-release-dir` 或 `--previous-ref` 指定对比基线，`--dry-run` 可只打印消息不发送，`--out \u003Cpath>` 可先写出 HTML 消息，`--message-file \u003Cpath>` 可在发布成功后发送已写出的消息。\n\n默认输出目录是 `.release`，临时工作目录是 `.release-work`。可用参数：\n\n```bash\nbun run build:release -- \\\n  --source source \\\n  --out .release \\\n  --work .release-work \\\n  --repo xream\u002Frule \\\n  --mihomo-channel release \\\n  --mihomo \u002Fpath\u002Fto\u002Fmihomo\n```\n\n不传 `--mihomo` 时，构建脚本会按 `--mihomo-channel` 下载 Mihomo 二进制。默认是 `release`，下载最新正式版到 `.tools\u002Fmihomo-release`；也可以设为 `alpha`，下载 Alpha 版到 `.tools\u002Fmihomo-alpha`。\n\n## 发布流程\n\nGitHub Actions 会在手动触发，或 `source\u002F**`、`scripts\u002F**`、`package.json`、`bun.lock`、`.github\u002Fworkflows\u002Frelease.yml` 这些路径推送到 `main` 后运行：\n\n1. 安装 Bun 依赖\n2. 运行 `bun test`\n3. 执行 `bun run build:release`\n4. 对比 `origin\u002Frelease` 和本次 `.release\u002Fartifacts-manifest.json`，有三类 provider 产物新增 \u002F 减少时先写出 Telegram HTML 消息\n5. 将 `.release` 以 orphan commit 强制发布到 `release` 分支\n6. 发布成功后发送 Telegram 通知\n\nTelegram 通知需要在 GitHub Actions secrets 中配置 `TELEGRAM_BOT_TOKEN` 和 `TELEGRAM_CHAT_ID`。未配置时步骤会跳过发送并打印将要发送的 HTML 消息。\n","`rule` 是一个用于生成 Mihomo 规则提供者的构建仓库，支持从 YAML 配置中提取规则源并按 `domain`、`ipcidr` 和 `classical` 类型拆分，最终生成可直接引用的 `.mrs`、`.txt` 和 `.yaml` 文件。项目使用 JavaScript 编写，并通过自动化脚本处理规则转换与发布。核心功能包括自动化的规则拆分、格式转换及文档生成，支持私有 GitHub 仓库访问时的 token 认证机制。适合需要为 Mihomo 定制或更新网络代理规则集的场景，特别是对于维护复杂的多类型规则配置文件的情况。","2026-06-11 04:08:00","CREATED_QUERY"]