Release v1.5.3
Downloads
macOS (Universal) - Supports both Apple Silicon and Intel
Option 1: Installation Script (Recommended)
Install with a single command (version v1.5.3):
curl -fsSL https://raw.githubusercontent.com/Leadaxe/singbox-launcher/develop/scripts/install-macos.sh | bash -s -- v1.5.3The script will:
- Download the release archive
- Extract and install to
/Applications/ - Fix macOS quarantine attributes and permissions
- Launch the application automatically
Option 2: Manual Installation
- Download:
singbox-launcher-v1.5.3-macos.zip - Extract the ZIP file
- Remove quarantine attribute (required):
xattr -cr "singbox-launcher.app" && chmod +x "singbox-launcher.app/Contents/MacOS/singbox-launcher"
- Double-click
singbox-launcher.appto run- If macOS blocks the app, go to System Settings → Privacy & Security and click "Open Anyway"
- Alternatively, right-click the app and select "Open" (first time only)
Windows (amd64)
- Download:
singbox-launcher-v1.5.3-win64.zip - Extract the ZIP file to a folder, for example:
C:\Program Files\singbox-launcher\ - Run
singbox-launcher.exefrom that folder- You may need administrator rights to install to Program Files
- The launcher will automatically download
sing-boxandwintun.dllon first launch
Windows 7 (x86, legacy)
- Download:
singbox-launcher-v1.5.3-win7-32.zip - Extract the ZIP file to a folder and run
singbox-launcher-win7-32.exe- For Windows 7 / 32-bit or legacy compatibility only
Linux Support
⚠️ Linux build temporarily unavailable - мы ищем тестировщика для ручного тестирования перед включением автоматической сборки.
Checksums
See checksums.txt for SHA256 checksums of all files.
v1.5.3
Hotfix release on top of v1.5.2: a subscription-dedup regression that shipped
with the identity rework, a Stop button that could hang forever in daemon
mode, and rule drag-and-drop that never survived a Wizard reopen.
EN
Highlights
- Duplicate subscription entries collapse again (v1.5.2 regression).
A subscription that lists the same server, port and password 32 times —
differing only in the#name— yields one node again, not 32. The first
entry wins, so the name you see is the first one the provider sent. The
signature is the entry's full content minus its label, so one server with
one password behind different SNI or transports stays separate: different
DPI-evasion paths are different nodes. - Rule order survives a save/load round-trip. Dragging rules on the Rules
tab used to look right until you reopened the Config Wizard, at which point
the list "auto-sorted" back. The build always ordered rules by an order
axis, and the UI never wrote the numbers; now it does. System rules stay
pinned (traffic-processing first — sniff must extract the domain before
routing matches), template presets keep their anchors, and dragging next to
an anchor no longer pushes it. Unnamed inline rules keep their position too:
order restoration matches them by identity instead of by label. - Stop no longer hangs on "Stopping…" in daemon mode. Every Stop went
through a background path that touched widgets off the UI thread; the queue
broke and the dashboard's release timer was lost, leaving the buttons
greyed out with a live core behind them. - A source excluded from the config is no longer silent. When its detour
hop can't be resolved, the source still drops out fail-closed — but now the
Wizard → Sources row carries a ⚠ mark with the reason, and a toast appears
on the Local tab after the build.
Technical / Internal
- Dedup lives in the parse layer (
dedupSignature, a hash of the full node
emission), not in the identity model: it lasts one source parse, is never
written to state, and does not touch disabled marks, node references or
identity. The check runs before tags are stamped (SPEC 094 D3), so a
duplicate can never claim anX-2tag. The Wizard's source-node counter and
the source Preview tab go through the same rule, so preview and build agree. - The connection key
scheme|server|port|credentialremains, but only where
it started: Xray JSON-array ownership ("which element may emit this
server"). It is parse-internal and is not an identity. - Rule order (SPEC 106) is wired end to end:
NormalizeRuleOrderon load,
PlaceRuleAfterwith the lazy shift on drop,NextUserRuleNumfor new
rules,order_numemitted on save. Existing states with no numbers are
marked on first load and persisted. - Excluded-source registry lives in
core/configas an in-memory record of
the last build, rewritten by every build (including an empty one) and never
persisted.
Migration notes
- Contract 0.10.0 amendment (IDENTITY.md §1.2/§2/§4): dedup is documented as a
parse-layer mechanism with a full-emission signature. The by-design
divergence with LxBox'snodeIdentityKey(which collapses different SNI on
the same credentials) stands — an interim revision that declared it
resolved was withdrawn the same day. The Dart mirror of the tag-identity
model is still pending. - No state migration is needed beyond what v1.5.2 already does on first run.
RU
Основное
- Дубли записей подписки снова схлопываются (регресс v1.5.2). Подписка,
перечисляющая один и тот же сервер, порт и пароль 32 раза с разным только
#именем, снова даёт один узел, а не 32. Побеждает первая запись — её имя
вы и увидите. Подпись — полное содержимое записи без имени, поэтому один
сервер с одним паролем за разными SNI или транспортами остаётся разными
узлами: разные схемы обхода блокировок — разные узлы. - Порядок правил переживает сохранение и перезаход. Перетаскивание на
вкладке Rules выглядело работающим ровно до повторного открытия Мастера, где
список «автосортировался» обратно. Сборка всегда упорядочивала правила по
оси порядка, а интерфейс номера не записывал — теперь записывает. Системные
правила остаются закреплёнными (traffic-processing первым — иначе sniff не
успевает извлечь домен до матчинга роутинга), шаблонные пресеты держат свои
якоря, а перетаскивание вплотную к якорю больше его не двигает. Безымянные
inline-правила тоже сохраняют место: восстановление порядка сопоставляет их
по идентичности, а не по подписи. - Stop больше не зависает на «Stopping…» в daemon-режиме. Каждый Stop шёл
фоновым путём, который трогал виджеты мимо UI-потока; очередь ломалась, а
вместе с ней терялся таймер, возвращающий кнопки, — и панель оставалась с
погашенными кнопками при живом ядре. - Исключение источника из конфига перестало быть молчаливым. Когда
detour-хоп не находится, источник по-прежнему выпадает fail-closed — но
теперь строка в Мастере → Источники несёт пометку ⚠ с причиной, а после
сборки на вкладке Local появляется уведомление.
Техническое / Внутреннее
- Дедуп живёт на parse-слое (
dedupSignature, хеш полной эмиссии узла), а не
в модели идентичности: он существует один разбор источника, в состояние не
пишется и не трогает ни отметки выключения, ни ссылки на узлы, ни
идентичность. Проверка идёт до простановки тегов (SPEC 094 D3), поэтому
дубль не может занять тег «X-2». Счётчик узлов в Мастере и вкладка Preview
окна источника идут тем же правилом — превью и сборка совпадают. - Ключ подключения
схема|сервер|порт|креденшлостался, но только там, где
и появился: владение сервером при разборе Xray-массива («какой элемент
вправе выпустить этот сервер»). Он внутренний для разбора и идентичностью
не является. - Ось порядка правил (SPEC 106) подключена от загрузки до эмита:
NormalizeRuleOrderпри загрузке,PlaceRuleAfterс ленивым сдвигом при
перетаскивании,NextUserRuleNumдля новых правил,order_numв
сохранении. Существующие состояния без номеров размечаются при первой
загрузке и сохраняются. - Реестр исключённых источников живёт в
core/configкак in-memory снимок
последней сборки: переписывается каждой сборкой (в том числе пустой) и в
состояние не сохраняется.
Миграция
- Амендмент контракта 0.10.0 (IDENTITY.md §1.2/§2/§4): дедуп задокументирован
как parse-слой с подписью по полной эмиссии. By-design различие с
nodeIdentityKeyу LxBox (там ноды одного сервера с разными SNI
схлопываются) сохраняется — промежуточная редакция, объявлявшая его
снятым, отозвана в тот же день. Зеркало тег-идентичности на стороне Dart
по-прежнему ожидается. - Отдельной миграции состояния не требуется — всё, что нужно, v1.5.2 уже
делает при первом запуске.