Repository navigation
Release v2.3.9
Downloads
macOS (Universal) - Supports both Apple Silicon and Intel
Option 1: Installation Script (Recommended)
Install with a single command (version v2.3.9):
curl -fsSL https://raw.githubusercontent.com/Leadaxe/singbox-launcher/develop/scripts/install-macos.sh | bash -s -- v2.3.9The 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-v2.3.9-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)
Option 1: Installer (Recommended)
- Download:
singbox-launcher-v2.3.9-win64-setup.exe - Run it and confirm the administrator prompt once. The launcher goes to
C:\Program Files\singbox-launcher, your data to%LOCALAPPDATA%\singbox-launcher;sing-box.exe,wintun.dll, the config template and Mesa3D are included, nothing is downloaded on first launch- Tasks: desktop shortcut, Start with Windows, software OpenGL (Mesa3D) for RDP / VMs without a GPU
- Installing over a previous version keeps your data; uninstall from Settings → Apps asks whether to remove the data too
- The installer is not code-signed yet: if SmartScreen shows "Windows protected your PC", click More info → Run anyway
Option 2: Portable ZIP
- Download:
singbox-launcher-v2.3.9-win64.zip- or
singbox-launcher-v2.3.9-win64-full.zip— full bundle:sing-box.exe,wintun.dll, the config template and Mesa3D (mesa3d/, used only when no hardware OpenGL — RDP, VMs) are already inside, nothing is downloaded on first launch
- or
- Extract the ZIP file to a folder your account can write to, for example
D:\Tools\singbox-launcher\— settings stay next to the program (portable.txt)- Under
C:\Program Files\the launcher keeps its data in%LOCALAPPDATA%\singbox-launcherinstead
- Under
- Run
singbox-launcher.exefrom that folder — no administrator rights, no UAC prompt- TUN needs administrator rights: Start offers Restart as administrator or Switch to proxy mode
- The regular archive downloads
sing-boxandwintun.dllon first launch
Windows 7 (x86, legacy)
- Download:
singbox-launcher-v2.3.9-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
- Runs as administrator (UAC prompt on every start), settings stay next to the program (
portable.txt); no installer and no daemon service
Linux Support
Checksums
See checksums.txt for SHA256 checksums of all files.
Release notes — v2.3.9 (2026-10-13)
EN
A patch release after v2.3.8. Core sing-box-lx 1.14.3-lx.18 (was 1.14.3-lx.14), contract 1.1.119 (was 1.1.116).
New
- Remote machines: subscriptions keep themselves fresh on the machine. A new checkbox in a machine's Edit window — Auto-deploy subscription updates (off by default) — lets the launcher refresh that machine's subscriptions on its hourly auto-update tick, rebuild its config and send it, so a provider that rotates node addresses no longer leaves the machine on dead nodes until someone presses Deploy. It deploys only when the change came from the subscriptions alone (the built config matched the one running on the machine before the refresh and differs after it) and the machine is quiet — core started on its last-good config, no interrupted apply, core not older than required. Anything else stays a manual Deploy with the orange dot and the reason in ⓘ (new Auto-deploy / Last auto-deploy rows). Each outcome shows up as a system notification. The launcher must be running; a deploy restarts the machine's core for a moment, and only when the nodes really changed. SPEC 164.
- Remote machines: is my config on the machine? The machine row now shows it at a glance. An orange dot on Deploy (renamed from "Deploy config") means the config saved here differs from the one running on the machine (sha256 of the built
config.jsonvs the daemon's active SHA, checked on every 5-second poll). A red dot on Configure means the last deploy did not start and the core rolled back to the last-good config. The ⓘ window also lists the local built-config sha256 next to the machine's active and last-good hashes. - Service window: keeping the daemon running, here and on every machine. A new ⚙ next to ⓘ in a machine's row (and Servers → ⚙ → Local for this computer) opens one runbook with four sections — Not running (status → restart → log → boot the last working config once → reinstall), Core (running vs required version; for a Linux machine: download the core for its platform into
~/Downloads, checked againstSHA256SUMS, stream it over ssh —scpdoes not work on OpenWrt — check it with the new binary, back up, swap, restart, roll back), Pairing (mint an invite on the machine, paste, Pair; who is trusted, revoke) and Reference (binary, service, state dir,daemon.json, last-good and log paths as the daemon reported them, or markeddefault; thedaemon.jsonkeys; a live log window). Every command uses the machine's own paths; ⧉ copies it, ▶ opens Terminal withssh <target> '…'. The window opens on the section that needs attention and its header turns green by itself once the daemon answers. The machine row gets a yellow dot on ⚙ and a⚠ Core lx.11 is older than required (lx.14)line (full versions such as1.14.0-lx.30vs1.14.3-lx.15when the upstream base differs) when its core is too old, a red dot and a✖ …line when the daemon does not answer. Deploy to an older core now warns first (How to update / Deploy anyway, with "Don't ask again for this version"). The machine's Edit window has an SSH field (root@<host>by default); the init system (procd/systemd) is picked in the Service header. Locally the Status/Install tabs became the same view plus Uninstall, and the service can now be restarted from the launcher. New guide: TROUBLESHOOTING → Daemon. SPEC 161. - Service window: the daemon updates itself, and tells the launcher what it runs on. With a core that has
/admin/commands(sing-box-lx with SPEC 127–129, after lx.15), the Service header gets a Daemon command row: pick a named command from the daemon'sdaemon.json(update,check-update,restart, …), see its text and last outcome, press Run, watch its log.updaterunssing-box lxd updateon the machine itself — download, checksum, swap, restart, rollback if the new core does not come up — and the window waits through the restart and reportsUpdated lx.15 → lx.16,Already up to date, orrolled back. The launcher never passes anything to a command: no arguments, no body. Without the key the row saysnot availableand the new Suggested commands section gives a ready"commands": {…}fragment to paste intodaemon.json. The daemon's passport now carries the machine's platform (linux/arm64, the release asset suffix) and init system (procd/systemd/…): the machine record is corrected from it (a wrongamd64picked by hand becomesarm64), Download core fetches the right asset, and the init selector disappears once the daemon names it. The former tabs became a Troubleshooting accordion under the header — one section open, the one the diagnosis picked (✖ Not running — connection refused,⚠ Core — lx.15 is older than required lx.16); a healthy daemon shows a short window with everything folded. A core version with an unknown suffix (1.14.3-lx.15-test128) is now "cannot compare" instead of a false "older than required". SPEC 162. - DNS tab: "Never serve stale answers for node hostnames" (on by default). A new checkbox under Default domain resolver. With it on, the core resolves a node's hostname again once the cached answer's TTL has expired instead of dialing the stale address from its optimistic cache, so nodes of providers that rotate addresses stay reachable after the old address is gone. The config now writes
route.default_domain_resolveras an object —{"server": "<resolver>", "disable_optimistic_cache": true}(with the box off the field isfalse); the resolver choice itself is unchanged. The setting travels with backups (template vardns_resolver_no_stale, contract 1.1.119). It applies to every hostname the core resolves through the default resolver (node servers and other outbound targets), not to DNS queries from apps — those keep the Serve stale answers setting. - Edit Rule: the preset's own definition. A preset's edit window gets a third tab, Preset, next to Form and JSON: the preset entry exactly as it is written in the wizard template (
for_each_node,vars,#if/#tplbodies,dns_servers), read-only. The JSON tab keeps showing what the preset emits with the current values. - macOS install script: the core download now shows a progress bar, like the launcher download (it used to run silently).
Fixed
- Remote nodes no longer show up on the Local tab. After a Deploy (or any restart of a machine's core) while Local was open, the machine's node list landed in the Local list and stayed there under "core stopped". Each tab's list now writes only its own state and widgets. A stopped local core also no longer clears the node list of a connected machine on the Remote tab.
- Refresh of a subscription in a machine's Configurator no longer writes to the local state. The fetched nodes used to be persisted into the local
state.json(the path ignored the Configurator's target); with a source ID shared between profiles — machine profiles are copies — it overwrote the local source and marked the local config stale, otherwise it silently skipped. The result now lands in the state file of the Configurator's own target under that file's lock. SPEC 165. - macOS app icon: transparent rounded corners on macOS 11–15 (it showed white corners there; macOS 26 was unaffected).
Template defaults
- Encrypted DNS goes direct by default. The template's DoT/DoH servers (
google_dot,cloudflare_dot,quad9_doh) no longer route their queries throughproxy-outout of the box: the default outbound isdirect-out(the Outbound parameter of each server stays editable). Reason: when the proxy's current node dies, a resolver that itself goes through the proxy can no longer resolve the other nodes' hostnames, and a provider that rotates node addresses took the whole group down withcontext deadline exceeded. Existing profiles that never set the parameter pick up the new default on the next rebuild; machines get it with the next Deploy. - Template node loops (SPEC 166, contract 1.1.119). Preset
for_eachis replaced byfor_each_nodeandfor_each_node_do; thetailscalepreset moved tofor_each_node+#filter. A custom template that still usesfor_eachfails to load that preset (it is skipped) — see Technical below.
Core
- Core pinned to sing-box-lx 1.14.3-lx.18 (base sing-box v1.14.3; was 1.14.3-lx.14).
- lx.15:
urltestprobes everyintervalinstead of every 2×interval;failoveralso leaves a node that answers but is more than 2× slower than the others;fingerprint: random/randomizedno longer leave REALITY nodes on Xray ≥ v26.9.8 dead until a restart; each uTLS/REALITY connection holds 18–25 KB less memory after the handshake;lxd --service=install/copyno longer fail on a clean macOS where/Library/PrivilegedHelperToolsis missing; gRPC updated for a critical advisory. - lx.16:
sing-box lxd update, namedcommandsindaemon.json, platform and init system in/admin/info(SPEC 127–129); the Windows 7 build starts again. - lx.17: the daemon retries a TUN still held by the previous process for up to 10 s at boot, and
lxd updatewaits for the core itself to reportstarted(rolls back otherwise) — the race seen in the first liveupdateon a router. - lx.18: the legacy
networkkey of themasqueoutbound is removed (it aliasedvhttp). Launcher-built configs are unaffected: the launcher emitsvhttpand stripsnetworkbefore the core (contract 1.1.118, D-129). - Daemon stubs unchanged (
SYNC_REV→ tag commit 729f1acf).
- lx.15:
Technical
- Template language, contract 1.1.119 (SPEC 166): the preset key
for_eachis replaced byfor_each_node(body per node, as before) andfor_each_node_do(walk the nodes only to collect values, body expanded once); the node is always@node, nodes are selected by#filter(an#ifcondition),#do: {"@var": {"#append": …}}collects into the preset's owntext_listvars,#finalapplies#unique→#sort→#limit;for_each,node_type,asare load errors (the preset is skipped). New var declaration fields:unique(onlytext_list; dedup of user input, default and collected values) andwizard_ui: "internal"(build-only: no form row, stored/backup value ignored, not exported, import reportsbackup_var_skipped {reason: internal}). An empty collected list substitutes as[]; a rule left with no conditions is dropped by the fragment gate. Corpus sectionstemplate/for_each_node/(wasfor_each/) andtemplate/for_each_node_do/. Missing@node.*paths in a filter no longer log a warning per node. - Contract 1.1.118 (SPEC 163, LxBox audit §591): a dangling
detourin an imported sing-box config is now fail-closed — the node is dropped askind=unsupportedwithdetour_target_missing/detour_to_group/detour_cycle_broken(severity error) instead of connecting directly with a cut chain; a hop that did not parse counts as a missing target, a loop drops every participant with its own record (a 3-node ring used to hide one member as a chain target, silently). masque:networkis no longer a legacy name ofvhttp— old?network=links are not migrated (the one-time state rewrite is removed), the key is reserved for the sing-box tcp/udp meaning and simply not read.tls.fragment/record_fragment/fragment_fallback_delayare forbidden on hysteria, hysteria2 and tuic (tls_not_applicable_quic), so the global TLS-fragmentation vars no longer touch QUIC nodes. New codeprotocol_extension_unsupported+extension_alternative(hysteria → hysteria2) for the mobile side.body.core→ 1.14.3-lx.17; uTLS presetchrome_155added to the allowlist. - Contract 1.1.117: LX Backup declares the LxBox-side
tlsfield ({fragment?, record_fragment?, fallback_delay?, mixed_case_sni?}) on subscriptions, folders, root servers and folder members — LxBox's per-node / per-source TLS-fragmentation settings (LxBox §636) now travel in a cross-platform backup instead of being reported asbackup_local_only_dropped. The launcher ignores the field silently (no state, no warning, not written on export); the unknown-key scan of folder members gained its own table of LxBox-side fields. New corpus casev10_lxbox_tls. - SPEC 164 (auto-deploy):
RemoteDaemon+=auto_deploy_subscriptions,last_auto_deploy {at, result, sha?, note?};core/machine_auto_deploy.go(sweep after the local one on startup/heartbeat, pure table-testedautoDeployDecision,AutoDeployMachineshared by the loop and the API);ConfigService.refreshStaleSubscriptionsAtwalks one state file underAppController.MachineStateLock(id), now shared with the debug API's/remote/machines/{id}/state/*mutex;AppController.MachineConfigRebuildFuncis thecore → ui/configuratorrebuild hook;events.MachineAutoDeploy+StateSourceAutoUpdate. Debug API: machine entry += the two fields,PATCHacceptsauto_deploy_subscriptions, newPOST /remote/machines/{id}/auto-deploy/run[?force_refresh=1]. - SPEC 165:
RefreshSourceInPlaceFor; the Configurator adapter carriesTarget/MachineID; covered by a two-profile test. - SPEC 162 (daemon commands):
lxdclient.InfoData+=goos,goarch,platform,init_system,service; newlxdclient/commands.go(CommandsCtx/CommandCtx/RunCommandCtx, 404 →ErrCommandsUnsupported, 409 →ErrCommandRunning); the machine registry caches the five passport fields and rewritesgoos/goarch/init_systemfrom them;core.CommandsRecipebuilds thedaemon.jsonfragment; the release asset is named by the passport'splatformwith the goos/goarch table as the fallback;parseCoreBuildaccepts only-rc<K>afterlx.N. The Service window is awidget.Accordion(ui/service_commands.goholds the command bar and theupdatestate machine). Features are gated by the daemon's answer, not by version;RequiredCoreVersionunchanged. - SPEC 161 (Service window), debug API:
/daemon/status+=log_path,executable,listen,tls,uptime_seconds,passport_seen_at,passport_cached,reach_error;/daemon/commands+=restart,client_list; a machine entry +=ssh,init_system,core_warn_ack,passport(sshandinit_systemwritable viaPATCH /remote/machines/{id});/remote/machines/{id}/health+=executable,log_path,listen,tls,uptime_seconds,core_required,core_outdated. Core-version comparison and the service recipes (procd/systemd/launchd/SCM, ssh wrapping, error classification) are untagged pure functions incore(core_build.go,service_recipes.go), covered by one table test; the machine registry gainsssh,init_system,core_warn_ackand a cachedpassport(no migration, not part of LX Backup or the contract).
RU
Патч-релиз после v2.3.8. Ядро sing-box-lx 1.14.3-lx.18 (было 1.14.3-lx.14), контракт 1.1.119 (был 1.1.116).
Новое
- Удалённые машины: подписки обновляются на машине сами. Новая галка в окне правки машины — Авто-деплой обновлений подписок (по умолчанию выключена) — разрешает лаунчеру на часовом тике автообновления обновить подписки этой машины, пересобрать её конфиг и отправить его: провайдер, который ротирует адреса узлов, больше не оставляет машину на мёртвых узлах до нажатия Deploy. Отправка идёт только когда изменение пришло от подписок (собранный конфиг совпадал с работающим на машине до обновления и отличается после) и машина спокойна — ядро запущено на last-good, применение не прерывалось, ядро не старее требуемого. Всё остальное остаётся ручным Deploy с оранжевой точкой и причиной в ⓘ (новые строки Авто-деплой / Последний авто-деплой). Каждый исход — уведомление системы. Лаунчер должен быть запущен; отправка на мгновение перезапускает ядро машины, и только когда узлы действительно сменились. SPEC 164.
- Удалённые машины: доехал ли конфиг. Строка машины теперь показывает это сразу. Оранжевая точка на Отправить (бывшее «Отправить конфиг»): сохранённый здесь конфиг не тот, что работает на машине (sha256 собранного
config.jsonпротив active SHA демона, сверка на каждом опросе раз в 5 с). Красная точка на Настроить: последняя отправка не завелась, ядро откатилось на прежний удачный конфиг. В окне ⓘ рядом с хешами машины добавлен sha256 собранного здесь конфига. - Окно Service: обслуживание демона здесь и на каждой машине. Новая ⚙ рядом с ⓘ в строке машины (и Servers → ⚙ → Local для этого компьютера) открывает один раннбук с четырьмя разделами — Not running (статус → перезапуск → лог → один раз загрузить последний рабочий конфиг → переустановка), Core (работающая версия против требуемой; для Linux-машины: скачать ядро под её платформу в
~/Downloadsсо сверкой сSHA256SUMS, залить потоком через ssh —scpна OpenWrt не работает, — проверить новым бинарём, бэкап, замена, перезапуск, откат), Pairing (выпустить приглашение на машине, вставить, Pair; кому доверяет демон, отзыв) и Reference (пути бинаря, службы, state dir,daemon.json, last-good и лога — как их сообщил демон или с пометкойdefault; ключиdaemon.json; окно живого лога). Все команды — с путями самой машины; ⧉ копирует, ▶ открывает Терминал сssh <цель> '…'. Окно открывается на разделе, где есть что чинить, а шапка сама зеленеет, когда демон снова отвечает. В строке машины — жёлтая точка на ⚙ и строка⚠ Core lx.11 is older than required (lx.14)(при разной базе апстрима — полные версии, например1.14.0-lx.30против1.14.3-lx.15), когда ядро старее нужного, красная точка и строка✖ …, когда демон не отвечает. Deploy на старое ядро теперь сначала предупреждает (How to update / Deploy anyway, с «больше не спрашивать для этой версии»). В окне Edit машины — поле SSH (по умолчаниюroot@<хост>); init-система (procd/systemd) выбирается в шапке Service. Локально вкладки Status/Install стали тем же видом плюс Uninstall, а службу теперь можно перезапустить из лаунчера. Новый раздел: TROUBLESHOOTING → Демон. SPEC 161. - Окно Service: демон обновляется сам и сообщает, на чём работает. С ядром, у которого есть
/admin/commands(sing-box-lx со SPEC 127–129, после lx.15), в шапке Service появляется строка Daemon command: выбрать именованную команду изdaemon.jsonдемона (update,check-update,restart, …), увидеть её текст и последний исход, нажать Run, смотреть лог.updateвыполняетsing-box lxd updateна самой машине — скачивание, контрольная сумма, замена, перезапуск, откат, если новое ядро не поднялось, — а окно пережидает перезапуск и пишетUpdated lx.15 → lx.16,Already up to dateилиrolled back. Лаунчер ничего не передаёт команде: ни аргументов, ни тела. Без ключа строка показываетnot available, а новый раздел Suggested commands даёт готовый фрагмент"commands": {…}для вставки вdaemon.json. Паспорт демона теперь несёт платформу машины (linux/arm64, суффикс релизного ассета) и init-систему (procd/systemd/…): запись машины исправляется по нему (выбранный рукамиamd64становитсяarm64), Download core качает нужный ассет, а селектор init исчезает, как только демон его назвал. Прежние вкладки стали аккордеоном Troubleshooting под шапкой — раскрыта одна секция, та, что выбрал диагноз (✖ Not running — connection refused,⚠ Core — lx.15 is older than required lx.16); у здорового демона окно короткое, всё свёрнуто. Версия ядра с неизвестным суффиксом (1.14.3-lx.15-test128) теперь «cannot compare», а не ложное «older than required». SPEC 162. - Вкладка DNS: «Never serve stale answers for node hostnames» (включено по умолчанию). Новая галка под Default domain resolver. Когда она включена, ядро после истечения TTL резолвит имя узла заново, а не подключается к устаревшему адресу из оптимистичного кэша, — узлы провайдеров, которые меняют адреса, остаются доступны, когда старый адрес уже не работает. В конфиге
route.default_domain_resolverтеперь объект —{"server": "<резолвер>", "disable_optimistic_cache": true}(с выключенной галкой полеfalse); выбор резолвера не меняется. Настройка переносится бэкапом (переменная шаблонаdns_resolver_no_stale, контракт 1.1.119). Действует на все имена, которые ядро резолвит резолвером по умолчанию (серверы узлов и прочие адреса исходящих), а не на DNS-запросы приложений — для них остаётся настройка Serve stale answers. - Edit Rule: определение пресета. В окне правки пресета третья вкладка Preset рядом с Form и JSON: запись пресета ровно так, как она написана в шаблоне визарда (
for_each_node,vars, тела#if/#tpl,dns_servers), только чтение. Вкладка JSON по-прежнему показывает, что пресет выдаёт с текущими значениями. - Скрипт установки на macOS: скачивание ядра теперь показывает прогресс, как и скачивание лаунчера (раньше шло молча).
Исправлено
- Узлы удалённой машины больше не попадают на вкладку Local. После Deploy (или любого перезапуска ядра машины) при открытой Local список узлов машины ложился в список своего ядра и висел там под «ядро остановлено». Теперь список каждой вкладки пишет только в своё состояние и свои виджеты. И остановленное своё ядро больше не чистит список подключённой машины на Remote.
- Refresh подписки в Конфигураторе машины больше не пишет в локальное состояние. Скачанные узлы закреплялись в локальном
state.json(путь не учитывал цель Конфигуратора); при общем ID источника между профилями — а профили машин суть копии — перезаписывался локальный источник и поднималось «локальный конфиг устарел», иначе молча пропускалось. Теперь результат ложится в файл состояния цели Конфигуратора под его мьютексом. SPEC 165. - Иконка приложения на macOS: прозрачные скруглённые углы на macOS 11–15 (там были видны белые углы; на macOS 26 проблемы не было).
Умолчания шаблона
- Шифрованный DNS по умолчанию идёт напрямую. DoT/DoH-серверы шаблона (
google_dot,cloudflare_dot,quad9_doh) больше не гонят запросы черезproxy-outиз коробки: исходящий по умолчанию —direct-out(параметр Outbound у каждого сервера по-прежнему можно поменять). Причина: когда текущий узел прокси умирает, резолвер, который сам ходит через прокси, не может разрешить имена остальных узлов, и провайдер с ротацией адресов узлов ронял всю группу сcontext deadline exceeded. Профили, где параметр не задавали, получают новый дефолт при следующей пересборке; машины — со следующим Deploy. - Циклы по узлам в шаблоне (SPEC 166, контракт 1.1.119). Ключ пресета
for_eachзаменён наfor_each_nodeиfor_each_node_do; пресетtailscaleпереведён наfor_each_node+#filter. Пресет своего шаблона, где осталсяfor_each, не загружается (пропускается) — подробности в «Техническом».
Ядро
- Ядро — sing-box-lx 1.14.3-lx.18 (база sing-box v1.14.3; было 1.14.3-lx.14).
- lx.15:
urltestпробует каждыйinterval, а не раз в 2×interval;failoverвдобавок уходит с узла, который отвечает, но больше чем вдвое медленнее остальных;fingerprint: random/randomizedбольше не оставляют узлы REALITY к Xray ≥ v26.9.8 мёртвыми до рестарта; каждое uTLS/REALITY-соединение держит после рукопожатия на 18–25 КБ меньше памяти;lxd --service=install/copyбольше не падают на чистой macOS без/Library/PrivilegedHelperTools; gRPC обновлён по критической уязвимости. - lx.16:
sing-box lxd update, именованныеcommandsвdaemon.json, платформа и init-система в/admin/info(SPEC 127–129); сборка для Windows 7 снова запускается. - lx.17: демон при загрузке до 10 с повторяет открытие TUN, который ещё держит прежний процесс, а
lxd updateждёт, пока само ядро не сообщитstarted(иначе откат) — гонка из первого живогоupdateна роутере. - lx.18: у outbound
masqueснят устаревший ключnetwork(алиасvhttp). Конфиги лаунчера не затронуты: он пишетvhttpи снимаетnetworkдо ядра (контракт 1.1.118, D-129). - Стабы демона без изменений (
SYNC_REV→ коммит тега 729f1acf).
- lx.15:
Техническое
- Язык шаблонов, контракт 1.1.119 (SPEC 166): ключ пресета
for_eachзаменён наfor_each_node(тело на каждый узел, как раньше) иfor_each_node_do(обход только ради сбора значений, тело раскрывается один раз); узел всегда@node, отбор —#filter(условие языка#if),#do: {"@var": {"#append": …}}собирает вtext_list-переменные своего пресета,#finalприменяет#unique→#sort→#limit;for_each,node_type,as— ошибка загрузки (пресет пропускается). Новые поля объявления переменной:unique(толькоtext_list; дедуп ввода, умолчания и собранного) иwizard_ui: "internal"(только для сборки: строки в форме нет, значение из состояния и бэкапа игнорируется, не экспортируется, импорт сообщаетbackup_var_skipped {reason: internal}). Пустой собранный список подставляется как[]; правило, у которого не осталось условий, снимает гейт фрагментов. Разделы корпусаtemplate/for_each_node/(бывшийfor_each/) иtemplate/for_each_node_do/. Отсутствующий путь@node.*в фильтре больше не пишет предупреждение в лог на каждый узел. - Контракт 1.1.118 (SPEC 163, аудит LxBox §591): висячий
detourв импортируемом sing-box конфиге теперь fail-closed — узел отбраковывается какkind=unsupportedсdetour_target_missing/detour_to_group/detour_cycle_broken(severity error), а не ходит напрямую с обрезанной цепочкой; неразобранный хоп = отсутствующая цель, кольцо роняет всех участников, каждого своей записью (в кольце из трёх узлов один прятался как цель цепи и пропадал молча). masque:networkбольше не legacy-имяvhttp— старые ссылки?network=не мигрируются (разовая перезапись состояния удалена), ключ зарезервирован под tcp/udp как в sing-box и просто не читается.tls.fragment/record_fragment/fragment_fallback_delayзапрещены у hysteria, hysteria2, tuic (tls_not_applicable_quic), глобальные ручки TLS-фрагментации QUIC-узлы больше не трогают. Новый кодprotocol_extension_unsupported+extension_alternative(hysteria → hysteria2) для мобильной стороны.body.core→ 1.14.3-lx.17; uTLS-пресетchrome_155в allowlist. - Контракт 1.1.117: в LX Backup объявлено поле
tlsстороны LxBox ({fragment?, record_fragment?, fallback_delay?, mixed_case_sni?}) у подписки, папки, корневого сервера и члена папки — настройки TLS-фрагментации LxBox по узлу / источнику (LxBox §636) теперь едут в межплатформенном бэкапе, а не отбрасываются какbackup_local_only_dropped. Лаунчер поле игнорирует молча (не в состояние, без предупреждения, на экспорте не пишет); у проверки неизвестных ключей членов папки появилась своя таблица полей стороны LxBox. Новый кейс корпусаv10_lxbox_tls. - SPEC 164 (авто-деплой):
RemoteDaemon+=auto_deploy_subscriptions,last_auto_deploy {at, result, sha?, note?};core/machine_auto_deploy.go(обход после локального на startup/heartbeat, чистаяautoDeployDecisionс табличным тестом,AutoDeployMachineобщая для петли и API);ConfigService.refreshStaleSubscriptionsAtобходит один файл состояния подAppController.MachineStateLock(id), который теперь делит мьютекс/remote/machines/{id}/state/*Debug API;AppController.MachineConfigRebuildFunc— хукcore → ui/configuratorна пересборку;events.MachineAutoDeploy+StateSourceAutoUpdate. Debug API: запись машины += два поля,PATCHпринимаетauto_deploy_subscriptions, новыйPOST /remote/machines/{id}/auto-deploy/run[?force_refresh=1]. - SPEC 165:
RefreshSourceInPlaceFor; адаптер Конфигуратора несётTarget/MachineID; покрыто тестом на два профиля. - SPEC 162 (команды демона):
lxdclient.InfoData+=goos,goarch,platform,init_system,service; новыйlxdclient/commands.go(CommandsCtx/CommandCtx/RunCommandCtx, 404 →ErrCommandsUnsupported, 409 →ErrCommandRunning); реестр машин кэширует пять полей паспорта и переписывает по нимgoos/goarch/init_system;core.CommandsRecipeсобирает фрагментdaemon.json; релизный ассет именуется поplatformиз паспорта, таблица goos/goarch — запасной путь;parseCoreBuildпослеlx.Nпринимает только-rc<K>. Окно Service —widget.Accordion(ui/service_commands.go— строка команд и машина состоянийupdate). Фичи включаются по ответу демона, не по версии;RequiredCoreVersionне менялась. - SPEC 161 (окно Service), Debug API:
/daemon/status+=log_path,executable,listen,tls,uptime_seconds,passport_seen_at,passport_cached,reach_error;/daemon/commands+=restart,client_list; запись машины +=ssh,init_system,core_warn_ack,passport(sshиinit_systemпишутся черезPATCH /remote/machines/{id});/remote/machines/{id}/health+=executable,log_path,listen,tls,uptime_seconds,core_required,core_outdated. Сравнение версий ядра и рецепты службы (procd/systemd/launchd/SCM, ssh-обёртка, классификация ошибок связи) — нетегированные чистые функции вcore(core_build.go,service_recipes.go) под одним табличным тестом; в реестре машин —ssh,init_system,core_warn_ackи кэшpassport(без миграции, не входят ни в LX Backup, ни в контракт).