mcp-xray-pilot 0.11.0 → 0.15.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/README.md CHANGED
@@ -30,11 +30,13 @@ a curated SNI suggester per exit-country and a multi-config merge helper.
30
30
  tun), per-transport `*Settings` schemas (raw / xhttp / grpc / ws / mkcp /
31
31
  httpupgrade / hysteria), TLS / REALITY security blocks, routing tag
32
32
  cross-references.
33
- - **Lints** ~20 best-practice rules: VLESS `decryption: "none"`, REALITY
33
+ - **Lints** ~22 best-practice rules: VLESS `decryption: "none"`, REALITY
34
34
  pubkey/shortId/target syntax, XTLS vision flow compatibility, TLS
35
35
  fingerprint enum, ALPN collisions, geosite/geoip typo catcher, protocol
36
36
  × transport × security incompatibilities, `xhttp.path` leading slash,
37
- `geoip:private` block rule, sniffing on 80/443 etc.
37
+ `geoip:private` block rule, sniffing on 80/443, **DNS-over-proxy leaks
38
+ on `.ru` direct routing** (v0.12), **`geosite:` categories absent from
39
+ xray-core release `geosite.dat`** (v0.12) etc.
38
40
  - **Geo catalogue**: search ~1500 known geoip/geosite tags by substring (full
39
41
  v2fly/domain-list-community catalogue, hydrated from `data/geocatalogue.json`).
40
42
  - **REALITY toolbelt**: `xray_generate_reality_keypair` (drop-in replacement
@@ -56,20 +58,22 @@ a curated SNI suggester per exit-country and a multi-config merge helper.
56
58
  | `xray_fetch_topic` | Fetch one topic as markdown. Network → fall back to bundled cache → update cache. |
57
59
  | `xray_search` | Full-text search over all cached docs. Returns ranked hits + snippets. |
58
60
  | `xray_validate_config` | Structural+schema validation of an xray JSON config (Zod under the hood). |
59
- | `xray_lint` | ~20 best-practice lint rules. Returns issues with severity, rule id, JSON-pointer. |
61
+ | `xray_lint` | ~22 best-practice lint rules. Returns issues with severity, rule id, JSON-pointer. |
60
62
  | `xray_geo_search` | Substring search over the embedded geosite/geoip catalogue (~1500 tags). |
61
63
  | `xray_diff_protocols` | Side-by-side feature table for two protocols. |
62
64
  | `xray_suggest_alternative` | Recommend protocol+transport+security for a goal (anti-DPI / battery / latency / …). |
63
65
  | `xray_generate_short_ids` | Cryptographically random REALITY shortIds (default `[4,8,16]` bytes, legacy empty prefix). |
64
66
  | `xray_generate_reality_keypair` | Fresh REALITY X25519 keypair, base64url 43 chars — drop-in for `xray x25519`. |
65
67
  | `xray_validate_sni_target` | Live TLS 1.3 + ALPN h2 + HTTP probe of a candidate REALITY target host. |
68
+ | `xray_test_reality_live` | Spin up real local xray server+client, run a full REALITY handshake against the target, probe HTTPS through the cascade. Strictly stronger than `xray_validate_sni_target`. |
69
+ | `xray_whitelist_sni_candidates` | Pull a public RU-traffic whitelist (default: hxehex/russia-mobile-internet-whitelist) and TLS-validate the top N hosts as REALITY SNI front candidates. Returns ranked, sorted by ok desc, latency asc. |
66
70
  | `xray_suggest_sni_for_country` | Curated REALITY SNI/target hosts per exit-country (DE/PL/NL/FR/LV/SE/FI/US/UK/JP/SG/AU/CA). |
67
71
  | `xray_merge_configs` | Merge N xray configs with tag-collision resolution and conflict warnings. |
68
72
  | `xray_github_search` | Search issues/PRs/discussions across XTLS GitHub repos (Xray-core/REALITY/docs). |
69
73
  | `xray_github_fetch_issue` | Fetch one issue/PR/discussion with full body + top comments. |
70
74
  | `xray_refresh_cache` | Bulk re-fetch cached docs (`scope: all/stale/category`). Optional `discover` for new upstream slugs. Optional `refresh_geocatalogue: true` to also re-pull the v2fly category list. |
71
75
 
72
- Total: **16 tools**.
76
+ Total: **18 tools**.
73
77
 
74
78
  ### Quick toolbelt
75
79
 
@@ -96,6 +100,74 @@ Live-check a candidate REALITY SNI:
96
100
  }
97
101
  ```
98
102
 
103
+ Live REALITY handshake (catches what `xray_validate_sni_target` cannot):
104
+
105
+ ```jsonc
106
+ // xray_test_reality_live { "target_host": "2gis.ru" }
107
+ {
108
+ "ok": true,
109
+ "target": "2gis.ru:443",
110
+ "reality_handshake_complete": true,
111
+ "client_received_real_cert": false,
112
+ "http_probe_status": 200,
113
+ "latency_ms": 824,
114
+ "issues": [],
115
+ "used_keypair": { "privateKey": "...", "publicKey": "...", "shortId": "a1b2c3d4" },
116
+ "cached": false,
117
+ "cached_at": "2026-05-06T12:30:00.000Z"
118
+ }
119
+ ```
120
+
121
+ > Verdicts are persisted to `data/reality-verdicts.json` (LRU cap 50, TTL 24h,
122
+ > key `host:port`). Subsequent calls with the same target return instantly with
123
+ > `cached: true`. Pass `force_refresh: true` to bypass the cache and rerun xray.
124
+
125
+ Compare a list of candidates in one shot — runs sequentially, each entry hits
126
+ the cache, results are sorted by `ok desc, latency_ms asc`:
127
+
128
+ ```jsonc
129
+ // xray_test_reality_live {
130
+ // "multi_targets": ["2gis.ru", "yandex.ru", "vk.com", "mail.ru"]
131
+ // }
132
+ {
133
+ "results": [
134
+ { "target": "2gis.ru:443", "ok": true, "latency_ms": 824, "cached": true, "cached_at": "..." },
135
+ { "target": "mail.ru:443", "ok": true, "latency_ms": 1102, "cached": false, "cached_at": "..." },
136
+ { "target": "yandex.ru:443", "ok": false, "latency_ms": 0, "cached": false, "cached_at": "...", "issues": ["client received a real certificate ..."] },
137
+ { "target": "vk.com:443", "ok": false, "latency_ms": 0, "cached": false, "cached_at": "...", "issues": ["target unreachable"] }
138
+ ],
139
+ "summary": { "ok_count": 2, "total": 4 }
140
+ }
141
+ ```
142
+
143
+ Pull a public RU-traffic whitelist and rank live SNI candidates for an
144
+ inbound RU-relay node:
145
+
146
+ ```jsonc
147
+ // xray_whitelist_sni_candidates { "max_candidates": 10 }
148
+ {
149
+ "source_url": "https://raw.githubusercontent.com/hxehex/russia-mobile-internet-whitelist/main/whitelist.txt",
150
+ "fetched_at": "2026-05-06T12:34:00.000Z",
151
+ "total_domains": 412,
152
+ "tested": 10,
153
+ "candidates": [
154
+ { "host": "ya.ru", "ok": true, "tls_version": "TLSv1.3", "alpn": "h2", "http_status": 200, "latency_ms": 41, "cert_subject": "ya.ru", "issues": [] },
155
+ { "host": "vk.com", "ok": true, "tls_version": "TLSv1.3", "alpn": "h2", "http_status": 200, "latency_ms": 78, "cert_subject": "*.vk.com", "issues": [] },
156
+ { "host": "ozon.ru", "ok": false, "tls_version": "TLSv1.3", "alpn": "h2", "http_status": 200, "latency_ms": 134, "cert_subject": "*.ozon.ru", "issues": [] }
157
+ ],
158
+ "summary": { "ok_count": 8, "failed_count": 2 },
159
+ "cache": { "used": false, "age_seconds": null },
160
+ "notes": ["latency_ms is measured from the MCP host (your laptop), not from the relay node — re-test from the node for geo-accurate values"]
161
+ }
162
+ ```
163
+
164
+ > The whitelist body is cached on disk in `data/whitelist-cache.json`
165
+ > (default TTL 24h, override via `cache_ttl_hours`). Verdicts are NOT cached
166
+ > — every call re-probes its slice live so latency numbers stay fresh.
167
+ > NB: the probe runs from your laptop, not from the РФ relay; for
168
+ > geo-accurate latency, use `xray_test_reality_live` from the actual
169
+ > node (or ssh + curl on it).
170
+
99
171
  It also exposes a single MCP **resource**: `xray://docs/index` — the raw
100
172
  `_index.json` of cached topics.
101
173
 
@@ -293,6 +365,58 @@ $env:GITHUB_TOKEN = "ghp_xxx" # PowerShell
293
365
  When `X-RateLimit-Remaining` drops below 10, the tool surfaces an inline
294
366
  warning in the response.
295
367
 
368
+ ## Security model
369
+
370
+ This package runs entirely in the MCP host's process and the only
371
+ "interesting" thing it does on disk/network is `xray_test_reality_live`,
372
+ which downloads the official **xray-core** binary from
373
+ [XTLS/Xray-core releases](https://github.com/XTLS/Xray-core/releases/latest)
374
+ into `~/.cache/mcp-xray-pilot/xray-bin/` and spawns it locally on
375
+ ephemeral ports.
376
+
377
+ **Approvals.** There is no in-package permission prompt by design — all
378
+ tool invocations are gated by the MCP host (Claude Code / Claude Desktop
379
+ / Cursor). Each host has its own permission UX (per-call confirm,
380
+ allowlist, etc.). Pin a specific version in your MCP config
381
+ (`mcp-xray-pilot@0.15.0`, not `mcp-xray-pilot`) so a malicious npm
382
+ release cannot silently roll in.
383
+
384
+ **Integrity of the xray binary.** Since v0.15:
385
+
386
+ 1. The matching `<asset>.zip.dgst` from the same GitHub release is
387
+ downloaded alongside the zip, and the zip is verified against its
388
+ `SHA2-256=` line **before** extraction. Mismatched payloads are
389
+ renamed to `xray.rejected-<timestamp>.zip` for inspection and the
390
+ tool aborts.
391
+ 2. If you want a stronger guarantee than "trust whatever XTLS ships
392
+ right now", set `XRAY_PILOT_PINNED_HASH` to a known SHA-256 — the
393
+ `.dgst` is then ignored and the pinned value is enforced. This
394
+ defends against a hypothetical compromised XTLS release that ships a
395
+ matching `.dgst`.
396
+
397
+ ```bash
398
+ # Linux / macOS — read the hash once, then pin it.
399
+ curl -sL https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-64.zip.dgst \
400
+ | awk '/^SHA2-256=/ {print $2}'
401
+ export XRAY_PILOT_PINNED_HASH=23cd9af9...
402
+ ```
403
+
404
+ ```powershell
405
+ $env:XRAY_PILOT_PINNED_HASH = "23cd9af9..."
406
+ ```
407
+
408
+ **What this does NOT do.** XTLS does not GPG-sign `.dgst` files, so an
409
+ attacker with write access to the releases page can ship a coherent
410
+ zip+dgst pair. The pinned-hash path is your defense against that. The
411
+ package does not sandbox the spawned xray binary — it runs with the
412
+ permissions of the MCP host process. If you need stronger isolation,
413
+ run the MCP host inside a container or a dedicated user account.
414
+
415
+ **`GITHUB_TOKEN`.** Optional, used only by `xray_github_search` /
416
+ `xray_github_fetch_issue`. A **fine-grained PAT with read-only public
417
+ repo scope** is recommended over classic PATs. The token is read from
418
+ the process env at call time and never persisted by the package.
419
+
296
420
  ## Roadmap
297
421
 
298
422
  See [ROADMAP.md](./ROADMAP.md). All v0.1–v0.11 milestones are checked off.
@@ -327,11 +451,13 @@ MCP-сервер, дающий LLM офлайн-доступ к официаль
327
451
  tun), per-transport `*Settings` (raw / xhttp / grpc / ws / mkcp /
328
452
  httpupgrade / hysteria), security блоки TLS/REALITY, routing tag
329
453
  cross-references.
330
- - **Lint** ~20 правил: VLESS `decryption: "none"`, REALITY pubkey/shortId/
454
+ - **Lint** ~22 правил: VLESS `decryption: "none"`, REALITY pubkey/shortId/
331
455
  target syntax, XTLS vision flow compatibility, TLS fingerprint enum,
332
456
  ALPN collisions, geo typo catcher, protocol × transport × security
333
457
  несовместимости, `xhttp.path` слеш, `geoip:private` block, sniffing на
334
- 80/443 и т.д.
458
+ 80/443, **утечка DNS через прокси ломает `.ru` direct routing** (v0.12),
459
+ **`geosite:` категории, которых нет в xray-core release `geosite.dat`**
460
+ (v0.12) и т.д.
335
461
  - **Geo catalogue**: поиск по ~1500 известным geoip/geosite тегам (полный
336
462
  v2fly/domain-list-community каталог, гидратируется из `data/geocatalogue.json`).
337
463
  - **REALITY toolbelt**: `xray_generate_reality_keypair` (drop-in замена
@@ -360,13 +486,15 @@ MCP-сервер, дающий LLM офлайн-доступ к официаль
360
486
  | `xray_generate_short_ids` | Криптослучайные REALITY shortIds (default `[4,8,16]` байт, с empty-prefix для легаси). |
361
487
  | `xray_generate_reality_keypair` | Свежая X25519 пара REALITY, base64url 43 chars — drop-in для `xray x25519`. |
362
488
  | `xray_validate_sni_target` | Live проба TLS 1.3 + ALPN h2 + HTTP кандидата на REALITY target. |
489
+ | `xray_test_reality_live` | Поднимает локальную пару xray (server+client), реально гоняет REALITY handshake к target, probe HTTPS сквозь каскад. Строго сильнее `xray_validate_sni_target`. |
490
+ | `xray_whitelist_sni_candidates` | Тянет публичный whitelist РФ-трафика (default: hxehex/russia-mobile-internet-whitelist), TLS-валидирует топ-N как REALITY SNI-кандидаты. Сортировка ok desc, latency asc. |
363
491
  | `xray_suggest_sni_for_country` | Курируемые REALITY-фронты по стране exit'а (DE/PL/NL/FR/LV/SE/FI/US/UK/JP/SG/AU/CA). |
364
492
  | `xray_merge_configs` | Слить N конфигов с разрешением коллизий тегов. |
365
493
  | `xray_github_search` | Поиск issues/PR/discussions по XTLS GitHub репозиториям. |
366
494
  | `xray_github_fetch_issue` | Получить одну issue/PR/discussion с полным body + топ комментариев. |
367
495
  | `xray_refresh_cache` | Bulk перезатяжка кеша доков (`scope: all/stale/category`). Опц. `discover` + `refresh_geocatalogue: true` (заодно перетянет v2fly категории). |
368
496
 
369
- Всего: **16 тулов**.
497
+ Всего: **18 тулов**.
370
498
 
371
499
  ### Quick toolbelt
372
500
 
@@ -395,6 +523,71 @@ Live-проверить кандидата на REALITY SNI:
395
523
 
396
524
  > ⚠️ Проба идёт с локальной машины, где запущен `mcp-xray-pilot`. Для решения «работает ли SNI из РФ» — гоняй с РФ-IP отдельно.
397
525
 
526
+ Реальный REALITY handshake (ловит то, что `xray_validate_sni_target` пропускает):
527
+
528
+ ```jsonc
529
+ // xray_test_reality_live { "target_host": "2gis.ru" }
530
+ {
531
+ "ok": true,
532
+ "target": "2gis.ru:443",
533
+ "reality_handshake_complete": true,
534
+ "client_received_real_cert": false,
535
+ "http_probe_status": 200,
536
+ "latency_ms": 824,
537
+ "issues": [],
538
+ "used_keypair": { "privateKey": "...", "publicKey": "...", "shortId": "a1b2c3d4" },
539
+ "cached": false,
540
+ "cached_at": "2026-05-06T12:30:00.000Z"
541
+ }
542
+ ```
543
+
544
+ > При первом вызове скачивает xray-binary в `~/.cache/mcp-xray-pilot/xray-bin/` (~30MB), дальше переиспользует. Если REALITY несовместим с target (как `outlook.live.com` или `www.ozon.ru` — реальные кейсы Flare VPN), `client_received_real_cert: true` и `ok: false`.
545
+
546
+ > Вердикты пишутся на диск в `data/reality-verdicts.json` (LRU 50, TTL 24h, ключ `host:port`). Повторный вызов на тот же таргет возвращается мгновенно с `cached: true`. Чтобы прогнать заново — `force_refresh: true`.
547
+
548
+ Сравнить пачку кандидатов одним вызовом — запускаются последовательно, каждый через кэш, сорт `ok desc, latency_ms asc`:
549
+
550
+ ```jsonc
551
+ // xray_test_reality_live {
552
+ // "multi_targets": ["2gis.ru", "yandex.ru", "vk.com", "mail.ru"]
553
+ // }
554
+ {
555
+ "results": [
556
+ { "target": "2gis.ru:443", "ok": true, "latency_ms": 824, "cached": true },
557
+ { "target": "mail.ru:443", "ok": true, "latency_ms": 1102, "cached": false },
558
+ { "target": "yandex.ru:443", "ok": false, "issues": ["client received a real certificate ..."] },
559
+ { "target": "vk.com:443", "ok": false, "issues": ["target unreachable"] }
560
+ ],
561
+ "summary": { "ok_count": 2, "total": 4 }
562
+ }
563
+ ```
564
+
565
+ Затянуть публичный whitelist РФ-трафика и проранжировать кандидатов на REALITY SNI для inbound РФ-relay-ноды:
566
+
567
+ ```jsonc
568
+ // xray_whitelist_sni_candidates { "max_candidates": 10 }
569
+ {
570
+ "source_url": "https://raw.githubusercontent.com/hxehex/russia-mobile-internet-whitelist/main/whitelist.txt",
571
+ "fetched_at": "2026-05-06T12:34:00.000Z",
572
+ "total_domains": 412,
573
+ "tested": 10,
574
+ "candidates": [
575
+ { "host": "ya.ru", "ok": true, "tls_version": "TLSv1.3", "alpn": "h2", "http_status": 200, "latency_ms": 41, "cert_subject": "ya.ru", "issues": [] },
576
+ { "host": "vk.com", "ok": true, "tls_version": "TLSv1.3", "alpn": "h2", "http_status": 200, "latency_ms": 78, "cert_subject": "*.vk.com", "issues": [] }
577
+ ],
578
+ "summary": { "ok_count": 8, "failed_count": 2 },
579
+ "cache": { "used": false, "age_seconds": null },
580
+ "notes": ["latency_ms is measured from the MCP host (your laptop), not from the relay node — re-test from the node for geo-accurate values"]
581
+ }
582
+ ```
583
+
584
+ > Тело whitelist кешируется на диск в `data/whitelist-cache.json` (TTL по
585
+ > умолчанию 24h, переопределение через `cache_ttl_hours`). Verdicts НЕ
586
+ > кешируются — каждый вызов делает свежие пробы на своём срезе. NB:
587
+ > latency меряется с тачки где запущен MCP, а НЕ с РФ-relay-ноды; для
588
+ > гео-релевантной задержки используй `xray_test_reality_live` прямо с
589
+ > ноды (или ssh + curl на ней).
590
+
398
591
  Также один MCP **ресурс**: `xray://docs/index`.
399
592
 
400
593
  ## Примеры
@@ -573,6 +766,56 @@ $env:GITHUB_TOKEN = "ghp_xxx" # PowerShell
573
766
  Когда `X-RateLimit-Remaining` падает ниже 10, тул возвращает inline-warning
574
767
  в ответе.
575
768
 
769
+ ## Модель безопасности
770
+
771
+ Пакет крутится внутри процесса MCP-хоста, и единственное «опасное»
772
+ действие на диск/сеть — `xray_test_reality_live`, который скачивает
773
+ официальный бинарь **xray-core** из
774
+ [XTLS/Xray-core releases](https://github.com/XTLS/Xray-core/releases/latest)
775
+ в `~/.cache/mcp-xray-pilot/xray-bin/` и запускает его локально на
776
+ ephemeral портах.
777
+
778
+ **Approvals.** Встроенного permission-prompt'а в пакете нет — это by
779
+ design. Все тулколлы гейтятся MCP-хостом (Claude Code / Claude Desktop /
780
+ Cursor) — у каждого хоста свой UX (per-call confirm, allowlist и т.д.).
781
+ Пиньте конкретную версию в MCP-конфиге (`mcp-xray-pilot@0.15.0`, а не
782
+ просто `mcp-xray-pilot`), чтобы вредоносный npm-релиз не подкатился
783
+ тихо.
784
+
785
+ **Целостность бинаря xray.** Начиная с v0.15:
786
+
787
+ 1. Рядом со скачиванием zip-а тянется `<asset>.zip.dgst` из того же
788
+ GitHub-релиза, и **до** распаковки zip проверяется против строки
789
+ `SHA2-256=`. Если хэши не совпали — payload переименовывается в
790
+ `xray.rejected-<timestamp>.zip` для разбора, и тул abort'ится.
791
+ 2. Если хочется жёстче чем «доверяю тому что XTLS залил прямо сейчас» —
792
+ задайте `XRAY_PILOT_PINNED_HASH` с известным SHA-256. Тогда `.dgst`
793
+ игнорируется, проверяется ваше захардкоженное значение. Это защищает
794
+ от гипотетического compromised XTLS-релиза, где злоумышленник залил
795
+ согласованную пару zip+dgst.
796
+
797
+ ```bash
798
+ # Linux / macOS — снять хэш один раз, потом пиннуть.
799
+ curl -sL https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-64.zip.dgst \
800
+ | awk '/^SHA2-256=/ {print $2}'
801
+ export XRAY_PILOT_PINNED_HASH=23cd9af9...
802
+ ```
803
+
804
+ ```powershell
805
+ $env:XRAY_PILOT_PINNED_HASH = "23cd9af9..."
806
+ ```
807
+
808
+ **Чего пакет НЕ делает.** XTLS не GPG-подписывает `.dgst`, поэтому
809
+ атакер с правами на releases-страницу может выкатить согласованную пару
810
+ zip+dgst. Защита от этого — pinned-hash. Sandbox для запущенного xray
811
+ пакет не делает — бинарь работает с правами процесса MCP-хоста. Хотите
812
+ жёстче — запускайте MCP-хост в контейнере или под отдельным юзером.
813
+
814
+ **`GITHUB_TOKEN`.** Опционально, используется только
815
+ `xray_github_search` / `xray_github_fetch_issue`. Рекомендуется
816
+ **fine-grained PAT с read-only scope для публичных репо** вместо
817
+ classic PAT. Токен читается из env при вызове и пакетом не сохраняется.
818
+
576
819
  ## Roadmap
577
820
 
578
821
  См. [ROADMAP.md](./ROADMAP.md) — все вехи v0.1–v0.11 закрыты.
@@ -1,5 +1,5 @@
1
1
  {
2
- "fetched_at": "2026-05-04T23:52:15.069Z",
2
+ "fetched_at": "2026-05-05T01:29:27.654Z",
3
3
  "source": "github.com/v2fly/domain-list-community/tree/master/data",
4
4
  "count": 1464,
5
5
  "names": [
@@ -1467,5 +1467,166 @@
1467
1467
  "zto-express",
1468
1468
  "zuoyebang",
1469
1469
  "zynga"
1470
+ ],
1471
+ "release_source": "hand-curated fallback (network fetch failed)",
1472
+ "release_count": 157,
1473
+ "release_names": [
1474
+ "1c",
1475
+ "alfabank",
1476
+ "alibaba",
1477
+ "amazon",
1478
+ "amazon-aws",
1479
+ "amazon-cn",
1480
+ "anthropic",
1481
+ "apple",
1482
+ "apple-cn",
1483
+ "archive",
1484
+ "atlassian",
1485
+ "baidu",
1486
+ "bilibili",
1487
+ "binance",
1488
+ "bitbucket",
1489
+ "blizzard",
1490
+ "bybit",
1491
+ "category-ads",
1492
+ "category-ads-all",
1493
+ "category-ads-ir",
1494
+ "category-ai-!cn",
1495
+ "category-ai-chat-!cn",
1496
+ "category-ai-chat-cn",
1497
+ "category-anticn",
1498
+ "category-banks-ru",
1499
+ "category-bittorrent",
1500
+ "category-cdn",
1501
+ "category-cryptocurrency",
1502
+ "category-cryptocurrency-!cn",
1503
+ "category-cryptocurrency-cn",
1504
+ "category-dev",
1505
+ "category-forums",
1506
+ "category-game-platforms",
1507
+ "category-game-platforms-download",
1508
+ "category-games-cn",
1509
+ "category-gov-ru",
1510
+ "category-ir",
1511
+ "category-kp",
1512
+ "category-media-ru",
1513
+ "category-porn",
1514
+ "category-public-cdn",
1515
+ "category-public-tracker",
1516
+ "category-ru",
1517
+ "category-scholar-!cn",
1518
+ "category-scholar-cn",
1519
+ "category-social",
1520
+ "category-social-!cn",
1521
+ "category-social-cn",
1522
+ "claude",
1523
+ "cloudflare",
1524
+ "cloudfront",
1525
+ "cn",
1526
+ "coinbase",
1527
+ "discord",
1528
+ "docker",
1529
+ "dropbox",
1530
+ "ea",
1531
+ "ea-games",
1532
+ "epicgames",
1533
+ "ethereum",
1534
+ "facebook",
1535
+ "fastly",
1536
+ "figma",
1537
+ "geolocation-!cn",
1538
+ "geolocation-cn",
1539
+ "geolocation-ir",
1540
+ "gfw",
1541
+ "github",
1542
+ "gitlab",
1543
+ "golang",
1544
+ "google",
1545
+ "google-cn",
1546
+ "googleads",
1547
+ "googleapis",
1548
+ "googlefcm",
1549
+ "googleplay",
1550
+ "googlescholar",
1551
+ "gosuslugi",
1552
+ "greatfire",
1553
+ "habr",
1554
+ "huggingface",
1555
+ "icloud",
1556
+ "imgur",
1557
+ "instagram",
1558
+ "jetbrains",
1559
+ "kinopoisk",
1560
+ "kucoin",
1561
+ "linkedin",
1562
+ "mail-ru",
1563
+ "medium",
1564
+ "meta",
1565
+ "metamask",
1566
+ "microsoft",
1567
+ "microsoft-cn",
1568
+ "miscellaneous",
1569
+ "netflix",
1570
+ "nicovideo",
1571
+ "nintendo",
1572
+ "nodejs",
1573
+ "notion",
1574
+ "npmjs",
1575
+ "okx",
1576
+ "onedrive",
1577
+ "openai",
1578
+ "ozon",
1579
+ "pinterest",
1580
+ "pixiv",
1581
+ "playstation",
1582
+ "private",
1583
+ "pypi",
1584
+ "python",
1585
+ "qq",
1586
+ "reddit",
1587
+ "riot-games",
1588
+ "rockstargames",
1589
+ "rust-lang",
1590
+ "rutracker",
1591
+ "rutube",
1592
+ "sberbank",
1593
+ "slack",
1594
+ "snapchat",
1595
+ "speedtest",
1596
+ "spotify",
1597
+ "stackexchange",
1598
+ "steam",
1599
+ "steam@cn",
1600
+ "substack",
1601
+ "taobao",
1602
+ "telegram",
1603
+ "test",
1604
+ "tiktok",
1605
+ "tinkoff",
1606
+ "tld-!cn",
1607
+ "tld-cn",
1608
+ "tld-net",
1609
+ "tld-proxy",
1610
+ "tron",
1611
+ "twitch",
1612
+ "twitter",
1613
+ "ubisoft",
1614
+ "vk",
1615
+ "vscode",
1616
+ "vtb",
1617
+ "wechat",
1618
+ "weibo",
1619
+ "whatsapp",
1620
+ "wikipedia",
1621
+ "wildberries",
1622
+ "win-extra",
1623
+ "win-spy",
1624
+ "win-update",
1625
+ "windowsupdate",
1626
+ "xboxlive",
1627
+ "yandex",
1628
+ "yapomogu",
1629
+ "youtube",
1630
+ "zoom"
1470
1631
  ]
1471
1632
  }
@@ -18,6 +18,7 @@
18
18
  import { readFileSync } from "node:fs";
19
19
  import path from "node:path";
20
20
  import { fileURLToPath } from "node:url";
21
+ import { RELEASE_FALLBACK_NAMES } from "../tools_impl/geocatalogue_fetch.js";
21
22
  /* All ISO 3166-1 alpha-2 country codes (lowercase). Most are valid geoip:* /
22
23
  * geosite:geolocation-* tags. */
23
24
  export const ISO_COUNTRY_CODES = [
@@ -155,7 +156,7 @@ for (const code of ISO_COUNTRY_CODES) {
155
156
  const human = COUNTRY_NAMES[code] ?? code.toUpperCase();
156
157
  entries.push(geosite(`geolocation-${code}`, `Domains geolocated to ${human}`));
157
158
  }
158
- function loadFullGeositeNames() {
159
+ function loadCataloguePayload() {
159
160
  /* Resolve relative to this module's filesystem location.
160
161
  * - source (tsx): src/data/geocatalogue.ts → ../../data/geocatalogue.json
161
162
  * - dist (node): dist/data/geocatalogue.js → ../../data/geocatalogue.json
@@ -165,18 +166,16 @@ function loadFullGeositeNames() {
165
166
  const here = path.dirname(fileURLToPath(import.meta.url));
166
167
  const jsonPath = path.resolve(here, "..", "..", "data", "geocatalogue.json");
167
168
  const raw = readFileSync(jsonPath, "utf8");
168
- const data = JSON.parse(raw);
169
- if (Array.isArray(data.names))
170
- return data.names;
171
- return [];
169
+ return JSON.parse(raw);
172
170
  }
173
171
  catch {
174
172
  /* No JSON yet → fall back to curated list only. Silent: the lint warning
175
173
  * "geo_unknown_category" still works, just with a smaller corpus. */
176
- return [];
174
+ return {};
177
175
  }
178
176
  }
179
- const fullNames = loadFullGeositeNames();
177
+ const payload = loadCataloguePayload();
178
+ const fullNames = Array.isArray(payload.names) ? payload.names : [];
180
179
  const seenGeosite = new Set(GEOSITE_NAMES);
181
180
  for (const code of ISO_COUNTRY_CODES)
182
181
  seenGeosite.add(`geolocation-${code}`);
@@ -202,6 +201,35 @@ export function isKnownGeoTag(tag) {
202
201
  return GEOSITE_SET.has(name);
203
202
  return false;
204
203
  }
204
+ /* ---- v0.12: which categories actually ship in xray-core's geosite.dat ----
205
+ *
206
+ * v2fly source has ~1500 categories, but the published xray-core release
207
+ * geosite.dat only carries a curated subset (~150). Routing rules that
208
+ * reference a v2fly-source-only category will make xray refuse to start.
209
+ *
210
+ * Source priority:
211
+ * 1. data/geocatalogue.json's release_names[] (kept fresh by
212
+ * `npm run fetch-geocatalogue` from Loyalsoldier release asset).
213
+ * 2. RELEASE_FALLBACK_NAMES — hand-curated whitelist used when the JSON
214
+ * lacks the field (older format, or fetch failed in the past).
215
+ */
216
+ const releaseNamesFromJson = Array.isArray(payload.release_names)
217
+ ? payload.release_names
218
+ : [];
219
+ const RELEASE_GEOSITE_SET = new Set((releaseNamesFromJson.length > 0 ? releaseNamesFromJson : RELEASE_FALLBACK_NAMES).map((s) => s.toLowerCase()));
220
+ export const releaseCatalogueSize = () => RELEASE_GEOSITE_SET.size;
221
+ /* "geosite:category-ru" → known to ship in xray release? Returns false for
222
+ * geoip:* (release vs source distinction doesn't apply there), and for
223
+ * tags whose category is missing from the release set. */
224
+ export function isGeositeInXrayRelease(tag) {
225
+ if (!tag.startsWith("geosite:"))
226
+ return false;
227
+ const raw = tag.slice("geosite:".length);
228
+ /* Strip "@cn" attribute suffix (steam@cn) for matching, treat negation
229
+ * "geolocation-!cn" as-is — it is its own category in the dat file. */
230
+ const name = raw.split("@")[0].toLowerCase();
231
+ return RELEASE_GEOSITE_SET.has(name);
232
+ }
205
233
  export function searchGeoCatalogue(query, limit = 30) {
206
234
  const q = query.toLowerCase().trim();
207
235
  if (!q)
@@ -226,6 +254,8 @@ export function searchGeoCatalogue(query, limit = 30) {
226
254
  name: e.name,
227
255
  description: e.description,
228
256
  tag: `${e.prefix}:${e.name}`,
257
+ in_v2fly_source: true,
258
+ in_xray_release: e.prefix === "geosite" && RELEASE_GEOSITE_SET.has(e.name.split("@")[0].toLowerCase()),
229
259
  }));
230
260
  }
231
261
  //# sourceMappingURL=geocatalogue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"geocatalogue.js","sourceRoot":"","sources":["../../src/data/geocatalogue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;iCACiC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,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"}
1
+ {"version":3,"file":"geocatalogue.js","sourceRoot":"","sources":["../../src/data/geocatalogue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAE7E;iCACiC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAClF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,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"}