Release v0.8.8.3
Downloads
macOS (Universal) - Supports both Apple Silicon and Intel
Option 1: Installation Script (Recommended)
Install with a single command (version v0.8.8.3):
curl -fsSL https://raw.githubusercontent.com/Leadaxe/singbox-launcher/develop/scripts/install-macos.sh | bash -s -- v0.8.8.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-v0.8.8.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-v0.8.8.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-v0.8.8.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.
What's New from 0.8.6
Version 0.8.8.3 Release Notes — Cumulative
This document rolls up everything that landed since v0.8.6 — across v0.8.7, v0.8.8, v0.8.8.1 (hotfix), and v0.8.8.3 (hotfix follow-up). Inline tags [v0.8.7] / [v0.8.8] / [v0.8.8.1] / [v0.8.8.3] mark which sub-release introduced or changed each item.
Note: version v0.8.8.2 was used internally during work on the v0.8.8.3 hotfix and never reached a published release — the third override-loader bug (wrong JSON key) was surfaced on review before the tag was created. v0.8.8.3 is the first follow-up published after v0.8.8.1.
Version timeline at a glance
| Version | Theme |
|---|---|
| v0.8.7 | Big release: Debug API, Settings tab, subscription source toggle, atomic writes, keyboard shortcuts, Linux/Windows wake-from-sleep, URLTest as template vars |
| v0.8.8 | NaïveProxy support, macOS wake-from-sleep, honest Update toast, shortcut tooltips, URLTest object-form fix |
| v0.8.8.1 | Hotfix: @urltest_* placeholders no longer leak into config.json (sing-box couldn't start on fresh installs)
|
| v0.8.8.3 | Hotfix follow-up: Settings-tab user override now actually applies; path invariants consolidated |
EN
Highlights
-
NaïveProxy (
naive+https:///naive+quic://) support in subscription parser and share-URI encoder.[v0.8.8]Parses user/pass,extra-headers, and QUIC vs HTTP/2 transport per the de-facto DuckSoft URI spec; emits sing-box"type": "naive"outbound with TLS block limited toserver_name.padding=URI param is logged and ignored. Right-click → Copy link round-trips back to a valid URI (extra-headerskeys sorted lexicographically). Requires sing-box ≥ 1.13.0 built withwith_naive_proxy. See SPEC 044. -
Debug API (localhost-only).
[v0.8.7]Optional HTTP server on127.0.0.1:9269. Off by default. Read endpoints/ping,/version,/state,/proxies; action endpoints/action/{start,stop,update-subs,ping-all}(POST-only). Bearer-token auth (32-bytecrypto/rand, constant-time compare). Toggle + "Copy token" button on the Diagnostics tab. Listener strictly127.0.0.1. Primary use-case: backing service for MCP wrappers so AI agents (Claude / Cursor / etc.) can read and drive the launcher. See SPEC 038. -
New ⚙️ Settings tab between Servers and Diagnostics.
[v0.8.7]Consolidates launcher-wide preferences: language selector + "Download locales" (moved from Help), Auto-update subscriptions, Auto-ping on connect. Fixes a latent data-loss bug in the old language handler — previouslySaveSettings({Lang: code})wiped every other settings field. See SPEC 039. -
Subscription source toggle.
[v0.8.7]Per-row on/off in Wizard → Sources. Disabled sources are skipped by the parser (no fetch, no parse) but stay in the file.ProxySource.Disabledwithomitemptykeeps legacy configs compatible. See SPEC 037. -
Auto-ping after VPN connect (default ON).
[v0.8.7]5 seconds after sing-box enters running state, the Servers tab auto-pings all proxies. Cancelled if you stop sing-box inside the window. Persisted asauto_ping_after_connect_disabledinsettings.json. -
Subscription auto-update global toggle (default ON).
[v0.8.7]Off skips all scheduled refreshes; manual Update always works. Re-enabling from UI also resets the consecutive-failure counter. -
URLTest parameters as template vars.
[v0.8.7]auto-proxy-out.url / interval / tolerancehoisted to@urltest_url / @urltest_interval / @urltest_tolerance; editable in Wizard → Settings. Object-form options (with display titles distinct from values) added. See SPEC 040. (See Fixed section for the substitution-related hotfixes that followed.) -
Keyboard shortcuts.
[v0.8.7]Cmd/Ctrl+Rreconnect,Cmd/Ctrl+Uupdate subscriptions,Cmd/Ctrl+Pping-all. Modifier resolves automatically per platform. Tooltips on Update / Restart buttons (hover shows the shortcut symbol) added in[v0.8.8]. See SPEC 042. -
Wake-from-sleep re-sync — closes SPEC 011 on all platforms. After resume the launcher resets the Clash API HTTP transport, refreshes the proxies list, and re-pings nodes if auto-ping is on.
[v0.8.7]Windows + Linux. Linux uses systemd-logindPrepareForSleepover system DBus (no new dependencies); on systems without logind the listener silently no-ops.[v0.8.8]macOS. Newinternal/platform/power_darwin.goregisters with IOKit viaIORegisterForSystemPower; CFRunLoop runs on aruntime.LockOSThread-pinned goroutine. Sleep transitions auto-acknowledged viaIOAllowPowerChangeso the system doesn't stall.
-
Atomic writes for
config.jsonandsettings.json.[v0.8.7]Stage to.tmp/.swapthen atomicos.Rename— a crash, kill -9, or power loss mid-write can no longer truncate your live config. Wizard keeps its existing.bakfor manual recovery. See SPEC 041.
Added — Resilience & observability
- 100 MB download cap on sing-box core downloads.
[v0.8.7]Pre-flightContent-Lengthcheck + mid-stream cumulative counter. Legitimate sing-box archives are < 20 MB. - HTTP status humanization in subscription-fetch errors.
[v0.8.7]401 → "unauthorized — token may have expired",403 → "forbidden — provider blocked",404 / 410 / 429 / 5xxeach with a hint. - "(subs: Xh ago)" freshness hint next to
config.jsonon Core Dashboard.[v0.8.7]How long since the last successful subscription update. Session-scoped. - Dirty-config marker (
*) on Update button when wizard saved changes the parser hasn't applied.[v0.8.7]See SPEC 043. Current implementation is minimal — fires on any wizard save; semantic split tracked in SPEC 045. - Per-source counts in the Update toast.
[v0.8.8]When at least one source returned an error or zero nodes, the toast readsConfig updated: 2/3 source(s) succeeded (1 failed)instead of a blanket "successfully". Silent-empty is treated as failure.
Added — Security hygiene
- Clash API token redaction in debug logs.
[v0.8.7]LoadClashAPIConfigused to log the full bearer token on every start; now logstoken=ab***89. Token still visible in Settings UI via Copy button. Pasting debug logs no longer leaks the secret.
Fixed
-
@urltest_*placeholders no longer leak into config.json.[v0.8.8.1]v0.8.7's SPEC 040 introduced template variables@urltest_url / @urltest_interval / @urltest_tolerancein the auto-proxy-out URLTest selector — but the parser code path that copies these options into the finalconfig.jsonnever ran the substitution. sing-box failedoutbounds[1].interval: time: invalid duration "@urltest_interval". Fresh installs of v0.8.7 / v0.8.8 couldn't start at all. Fix:core/config/SubstituteParserConfigPlaceholdersis invoked at the entry ofGenerateOutboundsFromParserConfig, walks all option maps underparser_config.outbounds[]andparser_config.proxies[].outbounds[], replaces@varnamestrings via a 3-level resolver (state-override → template default → hard-coded fallback). Existing brokenstate.jsonfiles are healed transparently — no manual action required. -
@varnameSettings-tab override now actually applies.[v0.8.8.3]v0.8.8.1'sBuildVarSubstituterFromDiskhad three independent bugs in the override branch (loadStateSettingsVars) that together silently dropped user overrides —urltest_interval = 1mset in the UI never made it into the generated config. The other two resolution levels (templatedefault_value, hard-coded fallback) were intact, so sing-box still got valid values; users who didn't customize URLTest saw no breakage. But anyone who did customize quietly got the template default. The three bugs:- Wrong file path. v0.8.8.1 looked at
bin/state.json; actual path isbin/wizard_states/state.json. - Wrong JSON shape. The list was decoded as
map[string]string; on disk it's[{name, value}, ...]. - Wrong JSON key. The block was looked up under
"settings_vars"/"SettingsVars"; the wizard writes it under"vars"(seeWizardStateFile.Varswithjson:"vars"inui/wizard/models/wizard_state_file.go).
See SPEC 048 for the full retrospective.
- Wrong file path. v0.8.8.1 looked at
-
Wizard template object-form
optionsno longer corrupts substituted values.[v0.8.8]Previously,type: "text"+ object-form options rendered as a free-text combo widget. Picking "5m (default)" forurltest_intervalended up writing"interval": "5m (default)"instead of"5m", and sing-box rejected the config. Fix: at JSON-unmarshal time, anyoptionselement in object form forcesType = "enum"regardless of the declared type. Strict dropdowns can't be typed into. Legacy plain-string options (["a","b"]) are unaffected. -
STUN settings dialog clipping on Windows (issue #54).
[v0.8.7]Auto-size collapsed the URL entry below placeholder width. Dialog now explicitly sized to ≥ 520 px. -
CI red since 2026-04-16.
[v0.8.7]internal/locale.TestAllKeysPresentwas failing because commit2f77bf7added 4 new English context-menu keys without Russian counterparts. Parity restored.
Changed — Template defaults
-
Russian & Cyrillic TLDs expanded in
ru-domains.[v0.8.7]Was.ru / .xn--p1ai / .su. Added.рус / .москва / moscow / tatar / .дети / .сайт / .орг / .ком. -
URLTest vars in
bin/wizard_template.jsonrewired.[v0.8.8]urltest_urlkeepstype: "text"with plain-string URL options (combo with editable presets).urltest_intervalandurltest_tolerancenow explicitlytype: "enum"with object-form{title, value}(strict dropdowns showing "5m (default)" / "100 ms (twitchy)" labels).
Technical / Internal
StateServiceextensions.[v0.8.7]AutoPingAfterConnect,TemplateDirty,LastUpdateError / LastUpdateErrorAt / LastUpdateSucceededAt.ProxySource.Disabled bool json:"disabled,omitempty".[v0.8.7]Omit-default preserves legacy configs.OutboundGenerationResultcounters populated.[v0.8.8]TotalSources / SucceededSources / FailedSourcesfilled byGenerateOutboundsFromParserConfig.UpdateConfigFromSubscriptionsreturns(*OutboundGenerationResult, error).TemplateVarcustomUnmarshalJSON.[v0.8.7]Three JSON forms foroptions.[v0.8.8]Object-form auto-degrades totype: "enum"regardless of declared type.- New package
core/debugapi/.[v0.8.7]Isolated HTTP surface with narrowControllerFacade. AdapterdebugAPIFacadeincore/debugapi_wiring.go. internal/platform/power_linux.go.[v0.8.7]New file.[v0.8.8]power_darwin.goadded.power_stub.gobuild tag tightened.- CI: per-version release-notes file required.
[v0.8.8]Release job now readsdocs/release_notes/<slug>.md. If missing, workflow fails before creating the release. Prereleases get an automatic> ⚠️ Pre-release buildbanner. - New runbook
docs/RELEASE_PROCESS.md.[v0.8.8]Canonical procedure for stable and prerelease cuts. Linked fromAGENTS.md. FallbackVersionbumped 1.13.6 → 1.13.11 incore/core_version.go.[v0.8.8]- SPEC groundwork for v0.9.x.
[v0.8.8]Two planning artifacts without code changes:- SPEC 045 — State / Config Decoupling. Split Wizard Save (writes
state.jsononly) from Build Config (writesconfig.jsonfrom state + outbounds cache), modelled after the LxBox mobile client. - SPEC 046 — Pinned Core and Template. Pin a specific sing-box version and
wizard_template.jsoncommit per launcher version.
- SPEC 045 — State / Config Decoupling. Split Wizard Save (writes
core/config/varsubst.go.[v0.8.8.1]Self-contained — no new dependencies, no UI imports.VarSubstitutertype,SubstituteParserConfigPlaceholders,BuildVarSubstituterFromDisk, hard-coded fallback table for the three URLTest placeholders. Hooked into both wizard preview/save and parser auto-update paths.- Path invariants consolidated.
[v0.8.8.3]internal/constants/constants.gogainsWizardTemplateFileName,WizardStateFileName,WizardStatesDirName.internal/platform/platform_common.gogainsGetWizardTemplatePath(execDir),GetWizardStatesDir(execDir),GetWizardStatePath(execDir). Code that needs to locate these files MUST go through them — no more hand-rollingfilepath.Join(execDir, "bin", "wizard_states", "state.json")per call site. - Real-fixture canary test.
[v0.8.8.3]core/config/testdata/state-real.jsoncaptured from an actual install;TestBuildVarSubstituterFromDisk_RealFixtureasserts overrides apply via the real on-disk schema. If the JSON tag breaks again, this test fails loudly. - SPEC 048 —
PARSER_CONFIG_VAR_SUBSTITUTION(retrospective).[v0.8.8.3]Documents the v0.8.8.1 hotfix architecture, the three bugs in the override loader, the path-invariant refactor, and process lessons.
Migration notes
bin/settings.jsongainssubscription_auto_update_disabled,auto_ping_after_connect_disabled,debug_api_enabled,debug_api_token,debug_api_port.[v0.8.7]Missing fields = zero (enabled / empty / 9269), so existing installs behave as before until you toggle.wizard_template.json—auto-proxy-outoptions now reference@urltest_url / @urltest_interval / @urltest_tolerance.[v0.8.7]Custom templates: either merge the three newvarsdefinitions, or keep your literal values (both forms work after v0.8.8.1).- Custom
wizard_template.jsonfiles usingtype: "text"+ object-formoptions: [{title, value}]are silently normalized totype: "enum"at load.[v0.8.8]Want a free-text combo with presets — switch options to plain strings. - Language selector moved from Help to the new Settings tab.
[v0.8.7] - Existing broken
state.jsonfiles (v0.8.7 / v0.8.8 fresh installs) heal automatically on first wizard save under v0.8.8.1+. No manual intervention required.
Known issues / deferred for redesign
These items are not in 0.8.8.3 and are tracked for v0.9+:
- State / Config decoupling (SPEC 045) — dirty marker on Update is still semantically smeared (fires on any wizard save, not just source-list edits).
- Auto-update event-driven model — the polling loop in
core/auto_update.gois still the old "wake every minute, check timestamp" pattern. Documented redesign: typed triggers through a single dispatcher. - Right-click context menu on the Update button —
SecondaryTapWrapdoesn't route secondary taps intowidget.Button; needs a customRightClickableButton. - Last-auto-update failure pill on Core Dashboard — wired but not visible in practice; layout / flag-path diagnosis pending.
- Ping-all button cancel — current design fully disables the button during a run; click-to-cancel redesign tracked.
- Pinned core + template (SPEC 046) — currently fetches latest sing-box and HEAD of
wizard_template.json. Pinning eliminates floating drift.
RU
Основное
-
Поддержка NaïveProxy (
naive+https:///naive+quic://) в парсере подписок и share-URI энкодере.[v0.8.8]Парсятся user/pass,extra-headers, выбор транспорта (HTTP/2 vs QUIC) по де-факто спеке DuckSoft; собирается sing-box outbound"type": "naive"с TLS-блоком толькоserver_name. Параметрpadding=логируется и игнорируется. ПКМ → «Copy link» корректно round-trip-ит обратно в валидный URI. Требует sing-box ≥ 1.13.0 со сборкойwith_naive_proxy. См. SPEC 044. -
Debug API (только localhost).
[v0.8.7]Опциональный HTTP-сервер на127.0.0.1:9269. По умолчанию выключен. Read-эндпоинты/ping,/version,/state,/proxies; action-эндпоинты/action/{start,stop,update-subs,ping-all}(только POST). Bearer-токен (32 байтаcrypto/rand, constant-time compare). Чекбокс + «Копировать токен» на вкладке Диагностика. Listener строго127.0.0.1. Основной use-case — backing-service для MCP-обёрток, чтобы AI-агенты (Claude / Cursor / …) могли читать и дёргать лаунчер. См. SPEC 038. -
Новая вкладка ⚙️ «Настройки» между Servers и Diagnostics.
[v0.8.7]Собирает launcher-wide preferences: селектор языка + «Скачать переводы» (перенесены из Help), автообновление подписок, автопинг после подключения. Попутно починен data-loss баг старого language-handler-а — раньшеSaveSettings({Lang: code})затирал все остальные поля. См. SPEC 039. -
Переключатель подписки в Wizard → Sources.
[v0.8.7]Чекбокс в каждой строке. Отключённые источники полностью пропускаются парсером (no fetch, no parse), но остаются в файле.ProxySource.Disabledсomitempty— legacy-конфиги совместимы. См. SPEC 037. -
Автопинг после подключения VPN (по умолчанию ВКЛ).
[v0.8.7]Через 5 секунд после перехода sing-box в running вкладка Servers авто-пингует все прокси. Отменяется при остановке sing-box внутри окна. Сохраняется вauto_ping_after_connect_disabled. -
Глобальный выключатель автообновления подписок (по умолчанию ВКЛ).
[v0.8.7]OFF пропускает плановые обновления; ручной Update всегда работает. Включение через UI сбрасывает счётчик последовательных ошибок. -
Параметры URLTest как шаблонные vars.
[v0.8.7]auto-proxy-out.url / interval / toleranceвынесены в@urltest_url / @urltest_interval / @urltest_tolerance; редактируются в Wizard → Settings. Object-форма options (с подписями, отличными от значений) добавлена. См. SPEC 040. (См. секцию «Исправлено» — там описаны связанные хотфиксы.) -
Горячие клавиши.
[v0.8.7]Cmd/Ctrl+Rreconnect,Cmd/Ctrl+Uupdate подписок,Cmd/Ctrl+Pping-all. Модификатор маппится на платформу автоматически.[v0.8.8]Tooltip-подсказки на кнопках Update / Restart показывают шорткат при наведении. См. SPEC 042. -
Wake-from-sleep re-sync — закрывает SPEC 011 на всех платформах. После резюма лаунчер сбрасывает HTTP-транспорт Clash API, перечитывает список прокси и re-пингует ноды (если включён автопинг).
[v0.8.7]Windows + Linux. Linux — нативно через systemd-logindPrepareForSleepпо system DBus (новых зависимостей нет); на системах без logind listener молча no-op-ит.[v0.8.8]macOS. Новыйinternal/platform/power_darwin.goрегистрируется в IOKit черезIORegisterForSystemPower; CFRunLoop крутится на goroutine сruntime.LockOSThread. Sleep-транзишены авто-подтверждаютсяIOAllowPowerChange, чтобы система не залипала.
-
Атомарные записи
config.jsonиsettings.json.[v0.8.7]Сначала.tmp/.swap, затем атомарныйos.Rename— падение, kill -9 или обесточивание посреди записи не могут обнулить живой конфиг. Визард сохраняет свой.bakдля ручного восстановления. См. SPEC 041.
Устойчивость и наблюдаемость
- Лимит 100 МБ на загрузку sing-box core.
[v0.8.7]Pre-flight Content-Length + кумулятивный счётчик. Легитимные архивы < 20 МБ. - Расшифровка HTTP-статусов в ошибках subscription-fetch.
[v0.8.7]401 → "token may have expired",403 → "provider blocked",404 / 410 / 429 / 5xx— каждый с подсказкой. - Подсказка «(подписки: X ч назад)» рядом с
config.jsonна Core Dashboard.[v0.8.7]В рамках сессии. - Маркер
*на кнопке Update, когда визард сохранил изменения, а парсер не отработал.[v0.8.7]См. SPEC 043. Текущая реализация минимальная — фиксится в SPEC 045. - Счётчик источников в тосте Update.
[v0.8.8]Если хотя бы один источник упал или вернул ноль нод —Config updated: 2/3 source(s) succeeded (1 failed)вместо общего «successfully». «Молчаливый ноль» считается failure.
Безопасность
- Редакция токена Clash API в debug-логах.
[v0.8.7]РаньшеLoadClashAPIConfigписал полный bearer на каждом старте; теперьtoken=ab***89. Токен по-прежнему виден в Settings UI через Copy. Debug-логи можно безопасно шерить.
Исправлено
-
Плейсхолдеры
@urltest_*больше не утекают в config.json.[v0.8.8.1]SPEC 040 в v0.8.7 ввёл шаблонные переменные@urltest_url / @urltest_interval / @urltest_toleranceв auto-proxy-out, но путь генерации outbound-ов в парсере копировал их дословно — sing-box падал сoutbounds[1].interval: time: invalid duration "@urltest_interval". Свежие установки v0.8.7 / v0.8.8 вообще не запускались. Фикс:core/config/SubstituteParserConfigPlaceholdersвызывается на входеGenerateOutboundsFromParserConfig, обходит все Options подparser_config.outbounds[]иparser_config.proxies[].outbounds[], заменяет строки@varnameчерез 3-уровневый резолвер (state-override → template default → hardcoded fallback). Существующие сломанныеstate.jsonлечатся автоматически — никаких ручных действий. -
Override
@varnameиз Settings tab теперь действительно применяется.[v0.8.8.3]v0.8.8.1'sBuildVarSubstituterFromDiskимел три независимых бага в override-ветке (loadStateSettingsVars), и кастомизация из UI молча игнорировалась —urltest_interval = 1mиз Settings tab не доезжал до сгенерированного конфига. Остальные два уровня резолюции (templatedefault_value, hardcoded fallback) работали, поэтому sing-box получал валидные значения; ~99% юзеров (которые не трогают URLTest defaults) не пострадали. Но любой, кто кастомизировал, тихо получал template default. Три бага:- Неправильный путь к файлу. v0.8.8.1 искал
bin/state.json; реальный путь —bin/wizard_states/state.json. - Неправильный формат JSON. Список декодировался как
map[string]string; на диске — массив[{name, value}, ...]. - Неправильный JSON-ключ. Блок искался под
"settings_vars"/"SettingsVars"; wizard пишет под"vars"(см.WizardStateFile.Varsс тегомjson:"vars").
Полная ретроспектива — SPEC 048.
- Неправильный путь к файлу. v0.8.8.1 искал
-
Шаблон визарда — object-форма
optionsбольше не портит подставляемые значения.[v0.8.8]Раньшеtype: "text"+ object-form options рендерился как combo-виджет со свободным вводом. Выбор «5m (default)» дляurltest_intervalприводил к"interval": "5m (default)"вместо"5m", и sing-box ругался. Фикс: на этапе JSON-unmarshal любая object-форма вoptionsпринудительно даётType = "enum". Строгий дропдаун невозможно ввести вручную. Legacy plain-string options (["a","b"]) не затронуты. -
STUN settings dialog обрезался на Windows (issue #54).
[v0.8.7]Auto-size сжимал URL-entry под placeholder-ширину. Диалог теперь явно ≥ 520 px. -
CI был красный с 2026-04-16.
[v0.8.7]internal/locale.TestAllKeysPresentпадал — английские ключи «Copy jump server link» без русских пар. Паритет восстановлен.
Шаблон по умолчанию
-
Список русских и кириллических TLD расширен в
ru-domains.[v0.8.7]Было.ru / .xn--p1ai / .su. Добавлены.рус / .москва / moscow / tatar / .дети / .сайт / .орг / .ком. -
URLTest-vars в
bin/wizard_template.jsonпереразведены.[v0.8.8]urltest_urlосталсяtype: "text"с plain-string URL-options (combo с editable пресетами).urltest_intervalиurltest_toleranceтеперь явноtype: "enum"с object-form{title, value}(строгий дропдаун с подписями типа «5m (default)» / «100 ms (twitchy)»).
Техническое / Внутреннее
- Расширения
StateService.[v0.8.7]AutoPingAfterConnect,TemplateDirty,LastUpdateError / LastUpdateErrorAt / LastUpdateSucceededAt. ProxySource.Disabled bool json:"disabled,omitempty".[v0.8.7]Omit-default — legacy-совместимость.- Счётчики
OutboundGenerationResult.[v0.8.8]TotalSources / SucceededSources / FailedSourcesпишутся вGenerateOutboundsFromParserConfig.UpdateConfigFromSubscriptionsвозвращает(*OutboundGenerationResult, error). - Кастомный
UnmarshalJSONнаTemplateVar.[v0.8.7]Поддерживает три JSON-формы options.[v0.8.8]Object-форма автоматически даётtype: "enum"независимо от заявленного типа. - Новый пакет
core/debugapi/.[v0.8.7]Изолированная HTTP-поверхность с узкимControllerFacade. АдаптерdebugAPIFacadeвcore/debugapi_wiring.go. internal/platform/power_linux.go.[v0.8.7]Новый файл.[v0.8.8]power_darwin.goдобавлен. Build tagpower_stub.goсужен.- CI: per-version release-notes файл обязателен.
[v0.8.8]Release-job читаетdocs/release_notes/<slug>.md. Если файла нет — workflow падает до создания релиза. Пререлизы получают баннер> ⚠️ Pre-release build. - Новый runbook
docs/RELEASE_PROCESS.md.[v0.8.8]Канонная процедура для stable и prerelease. Ссылки вAGENTS.md. FallbackVersion1.13.6 → 1.13.11 вcore/core_version.go.[v0.8.8]- Спеки-задел на v0.9.x.
[v0.8.8]Без правок кода:- SPEC 045 — State / Config Decoupling. Развести Wizard Save (только
state.json) и Build Config (config.jsonиз state + кэш outbounds), по образцу мобильного клиента LxBox. - SPEC 046 — Pinned Core and Template. Жёсткое закрепление версии sing-box и коммита
wizard_template.jsonза версией лаунчера.
- SPEC 045 — State / Config Decoupling. Развести Wizard Save (только
core/config/varsubst.go.[v0.8.8.1]Self-contained — без новых зависимостей и UI-импортов. ТипVarSubstituter,SubstituteParserConfigPlaceholders,BuildVarSubstituterFromDisk, hardcoded fallback для трёх URLTest-плейсхолдеров. Внедрено в оба пути (wizard preview/save + parser auto-update).- Path-инварианты сведены.
[v0.8.8.3]internal/constants/constants.goполучилWizardTemplateFileName,WizardStateFileName,WizardStatesDirName.internal/platform/platform_common.goполучилGetWizardTemplatePath(execDir),GetWizardStatesDir(execDir),GetWizardStatePath(execDir). Код, которому нужны эти файлы, ОБЯЗАН ходить через них — никаких больше самосборокfilepath.Join(execDir, "bin", "wizard_states", "state.json")на каждом callsite. - Canary-тест с реальной фикстурой.
[v0.8.8.3]core/config/testdata/state-real.jsonсобран с реальной установки;TestBuildVarSubstituterFromDisk_RealFixtureпроверяет применение override через реальную on-disk схему. Если JSON-тег снова сломают — тест упадёт громко. - SPEC 048 —
PARSER_CONFIG_VAR_SUBSTITUTION(ретроспектива).[v0.8.8.3]Документирует архитектуру v0.8.8.1 hotfix-а, три бага в override-loader, path-invariant рефакторинг и process-уроки.
Миграция
- В
bin/settings.jsonдобавленыsubscription_auto_update_disabled,auto_ping_after_connect_disabled,debug_api_enabled,debug_api_token,debug_api_port.[v0.8.7]Отсутствие = zero (enabled / пусто / 9269), существующие установки ведут себя как раньше. wizard_template.json— параметрыauto-proxy-outчерез@urltest_url / @urltest_interval / @urltest_tolerance.[v0.8.7]Кастомные шаблоны: смерджить три новыхvarsили оставить литералы (обе формы работают начиная с v0.8.8.1).- Кастомные
wizard_template.jsonсtype: "text"+ object-form options тихо нормализуются вtype: "enum"при загрузке.[v0.8.8]Если хочется combo со свободным вводом — переключить options в plain-string форму. - Селектор языка переехал из Help в новую вкладку Settings.
[v0.8.7] - Существующие сломанные
state.json(свежие установки v0.8.7 / v0.8.8) лечатся автоматически на первом wizard save под v0.8.8.1+. Никаких ручных действий не требуется.
Known issues / отложено на редизайн
Не входит в 0.8.8.3, отслеживается для v0.9+:
- State / Config decoupling (SPEC 045) — dirty-маркер
*всё ещё семантически размазан (срабатывает на любое сохранение, не только на правки источников). - Event-driven автообновление подписок — polling loop в
core/auto_update.goстарого образца. Запланированный редизайн: типизированные триггеры через единый dispatcher. - Правый клик по кнопке Update —
SecondaryTapWrapне маршрутизирует secondary-тапы вwidget.Button; нужен кастомныйRightClickableButton. - Плитка «Last auto-update failed» на Core Dashboard — реализована, но в практике не показывается; диагностика отложена.
- Кнопка Ping-all → Cancel — сейчас полностью disable во время теста; редизайн на click-to-cancel запланирован.
- Pinned core + template (SPEC 046) — лаунчер тащит latest sing-box и HEAD ветки
wizard_template.json. Жёсткое закрепление избавит от drift.