Commit Graph
67 Commits
Author SHA1 Message Date
Dushnilin c432220af5 feat(updates): добавить локальный бэкап и оффлайн-откат компонентов 2026-09-01 12:24:58 +03:00
Dushnilin 706b35328c feat(ruleset): auto-assign download_detour for remote rulesets & add watchdog self-heal for ruleset DNS stalls 2026-08-30 21:22:23 +03:00
Dushnilin dfb32722bf release: 1.3.8 - OpenWrt network interfaces for WARP generator, DoH doctor URL normalization & doctor lock fixes 2026-08-30 20:05:16 +03:00
Dushnilin 16ffc9f91f fix(diagnostics): check both ca-certificates.crt and ca-bundle.crt paths
On apk-based OpenWrt the file is ca-certificates.crt, not ca-bundle.crt.
Check both paths so the CA bundle detection works on opkg and apk.
2026-08-28 10:41:32 +03:00
Dushnilin 1a314147a9 fix(ai-doctor): debug-логирование LLM запросов + HTTP-Referer для OpenRouter
- Добавлен warn-вывод при ошибках LLM: статус curl,/raw response, отсутствие
  choices — теперь видно в logread почему AI Chat молча отдаёт оффлайн
- Добавлены HTTP-Referer и X-Title заголовки для OpenRouter (рекомендация
  провайдера для rate-limit ranking)
2026-08-27 17:54:27 +03:00
Dushnilin 2c6a1a7343 feat(tailscale): watchdog нативного режима и панель пиров тейлнета
- watchdog: проверка native-секции в slow-тире, авторестарт демона после 2 сбоев, TG-алерт раз в час
- AI Doctor: узел Tailscale (готов/не установлен/упал) только при настроенном native
- провайдер: режим peers — парсинг status --json через per-section socket
- RPC get_tailscale_status/get_tailscale_peers/tailscale_restart
- дашборд: карточка Tailscale (состояние, IP роутера, до 5 пиров с онлайн-статусом)
2026-08-26 13:43:23 +03:00
Dushnilin 7f0b085a07 feat(tailscale): нативный режим tailscaled и компонент Tailscale
- новый компонент Tailscale: установка пакета из фида, карточка в Обновлениях
- режим native для секций Tailscale: системный tailscaled вместо sing-box endpoint
- доступ к тейлнету с LAN без клиента: маршруты 100.64.0.0/10 и MagicDNS через dnsmasq
- masquerade и exit-node (opt-in) с обходом tproxy по зарезервированной маске
- validator: требование tailscaled и auth-key для native; bypass-правила в mangle
- тесты: генерация конфига, смоук рантайма с моками, обновлена сигнатура состояния
2026-08-26 11:30:52 +03:00
Dushnilin 77e8cdaad0 feat: AI доктор — 5 багфиксов + Telegram кнопка
Багфиксы:
- rag.uc: исправлен порядок аргументов push() — RAG-эмбеддинги снова строятся
- fix_uci_config: правильный путь бэкапа (/etc/backup/tachyon_config + fallback)
- apply_quick_fix: честные exit codes для всех 23 фиксов
- doctor(): прокидывается busy flag в JSON-вывод
- diagnose_json: строится из checks[] вместо парсинга эмодзи из текста

UI:
- Кнопка Telegram канал (https://t.me/tachyon_proxy) на странице диагностики

Тесты:
- 5 новых проверок в ai_doctor_local.sh (uci_backup, exit codes, busy, structured checks, rag push)
2026-08-25 21:37:15 +03:00
Dushnilin c3172dd82d refactor: remove hardcoded port 4534 — dynamic port from config
- Added get_mixed_port() to core/common.uc (reads sing-box config.json)
- agent_api.uc, api.uc: use common.get_mixed_port()
- warp_generator.uc: use config port instead of hardcoded fallback
- watchdog.uc: use mixed_ports_from_config() for Clash API calls
- runtime.uc: dynamic port in conflict checks and proxy probe
2026-08-25 15:46:03 +03:00
Dushnilin 0241e1898f feat(doctor): честный вердикт по мёртвым WireGuard/AWG-туннелям
Жалобы вида «AWG не работает» (#39, #42) почти всегда означают: конфиг
секции применён корректно, но пир не отвечает (сервер лежит, провайдер
режет UDP до эндпоинта). Раньше доктор об этом молчал, и виноватым
выглядел Tachyon.

Новый чек 6c сканирует свежий лог ядра на ошибки outbound/wireguard
(operation timed out / handshake timeout): при свидетельствах мёртвого
туннеля - явный вердикт «проблема вне Tachyon» с подсказкой проверить
сервер и UDP-порт у провайдера. Если wireguard-трафика в логе нет вовсе,
чек не выдаёт ни одной строки - без шума для пользователей без AWG.
2026-08-22 10:46:36 +03:00
Dushnilin ca21eb2202 feat(doctor): новые проверки и журнал исходов диагностики
Пять проверок, которых раньше не было, все read-only:

- место на диске: /tmp и overlay при >=90% молча ломают запись кэша,
  загрузку подписок и коммиты конфигов
- системные часы: неверный год валит все TLS-соединения (DoH, подписки,
  LLM API) после холодной загрузки без NTP
- наличие ca-bundle: HTTPS-проверки падают с SSL-ошибками без пакета;
  код уже ссылался на него в вердиктах, но не проверял
- конфликты порта 53: другой DNS-демон на :53 конкурирует с dnsmasq и даёт
  плавающие сбои резолвинга
- возраст кэша подписки: sing-box может гонять трафик через списки узлов
  многодневной давности, хотя сам URL подписки доступен

Плюс журнал исходов (/tmp/tachyon_doctor_history.json, максимум 50 записей):
повторные сбои за 24 часа помечаются как повторяющиеся, а не как уникальный
инцидент.
2026-08-21 19:24:20 +03:00
Dushnilin 7d222fbfe1 feat(doctor): диагностика в dry-run по умолчанию, ремонты по явному запросу
Доктор мутировал систему при каждом диагностическом запуске: отключал
rebind protection dnsmasq, делал kill -9 процессу на портах 4534/9090,
стирал syslog во время OOM-аудита и подменял resolv.conf на 1.1.1.1 как
побочный эффект "проверки".

- run_doctor_checks() теперь только диагностирует в dry-run: каждая мутация
  идёт через обёртки doc_set/doc_commit/doc_run/doc_unlink, которые
  записывают планируемое действие и сообщают "WILL FIX (doctor --fix)";
  ремонты выполняются только через "tachyon doctor --fix" или repair=true
- recovery-проверки (сервис остановлен) следуют тому же правилу
- параллельные запуски доктора из LuCI, Telegram и cron сериализуются
  mkdir-локом со взятием устаревшего лока через 15 минут тишины
- трекер применённых фиксов пишется атомарно (tmp+mv)
- OOM-проверка больше не стирает logread (это форензика) и атрибутирует
  kill именно sing-box
- ai_doctor прогонял весь набор проверок дважды (внутри local_rule_doctor и
  напрямую); результаты считаются один раз и переиспользуются
- curl к LLM/Clash/подпискам получили connect + total таймауты, зависший
  эндпоинт больше не подвешивает доктора
2026-08-21 19:20:05 +03:00
Dushnilin 421a4fd796 feat: add RAG (Retrieval-Augmented Generation) for AI Doctor
New files:
- tools/rag_build_index.sh: build-time ingestion pipeline
  Chunks docs/knowledge-base/*.md into 2000-char chunks with 200-char overlap
  Produces rag_index.json (39 chunks, ~74KB) for runtime embedding
- tachyon/files/usr/lib/diagnostics/rag.uc: runtime RAG module
  Embeds chunks via same LLM provider API (OpenAI-compatible /v1/embeddings)
  Cosine similarity search, top-3 retrieval, 24h cache in /tmp
  Graceful fallback if embedding API unavailable
- tachyon/files/usr/lib/tachyon/rag_index.json: pre-built chunk index

Modified files:
- runtime.uc: integrated RAG into ai_doctor() function
  Retrieves relevant docs based on user query or diagnostic context
  Injects 'Relevant Documentation' section into LLM prompt
- renderAdvancedSettings.ts: added 'Enable RAG' toggle in AI Doctor settings
- tachyon config: added enable_rag option (default '1')
- build.sh: added rag_build_index.sh step

Architecture:
- Provider-agnostic: uses same API key/provider as LLM for embeddings
- Embedding model: text-embedding-3-small (OpenAI), nomic-embed-text (Ollama),
  local-model (LMStudio), deepseek-embedding (DeepSeek)
- Cache: embeddings cached in /tmp/tachyon_rag_embeddings.json (24h TTL)
- Fallback: if embedding fails, AI Doctor works without RAG (as before)
- 39 chunks from 14 docs, ~66K chars, cosine search <1ms

623 tests pass (101 backend + 522 frontend)
2026-08-20 10:27:56 +03:00
Dushnilin 1137e96b0d de-AI phase 3: inline redundant variables and null checks
TypeScript:
- getDashboardSections.ts: value === undefined || value === null -> value == null
- renderAdvancedSettings.ts: remove redundant Boolean() on boolean

ucode (10 inlined variables):
- helpers.uc: inline trailing_dot
- runtime.uc: inline ping_ok, enable_watchdog
- nft/apply.uc: inline rtmtu_ok, qos_enabled
- byedpi/runtime.uc: inline matched
- api.uc: inline deleted, added
- subscription.uc: inline has_source_markers
- watchdog.uc: inline is_healthy

522 frontend tests pass
2026-08-19 22:38:26 +03:00
Dushnilin 4094a41b5d de-AI: remove AI comments and boolean theater across TypeScript + ucode 2026-08-19 18:15:35 +03:00
Dushnilin 0964b79171 fix(ai-chat): fix AI Chat and Assistant to work with LM Studio
- Fix response parsing: check report field, not just message
- Pass user query text to LLM instead of ignoring it
- Append user question to diagnostic prompt with system context
- Increase timeout to 120s for LM Studio responses
- Add command_status_from_args to core/common.uc exports

Closes #38
2026-08-19 15:57:42 +03:00
Dushnilin c35380200f fix(tailscale, ai): исправить скрытие полей Tailscale-сервера и добавить готовый пресет провайдера OpenRouter 2026-08-17 11:18:36 +03:00
Dushnilin 528bc7b9db feat(doctor): расширенная офлайн-диагностика (NTP, conntrack, deadlock, MTU) и аварийный возврат интернета 2026-08-15 17:18:23 +03:00
Dushnilin 4dd882f276 fix(core): объявление default_gateway_exists до wan_has_ip и видимость URLTest по умолчанию 2026-08-15 16:06:22 +03:00
Dushnilin e02e9169d4 fix(core): исправление forward-reference в AI Doctor и фильтрации селектора 2026-08-15 16:02:31 +03:00
Dushnilin 85ae733787 feat(doctor): расширенная локальная диагностика DPI, нод, конфликтов и фикс зависимостей CI 2026-08-15 15:58:40 +03:00
Dushnilin d81d9fd077 fix(ci): fix forward function declaration in runtime.uc and harden tests for multi-call coreutils/alpine 2026-08-15 12:28:49 +03:00
Dushnilin e0828eb53a fix(diagnostics): fix false-positive sing-box DNS check on busybox nslookup and auto-fetch LAN clients in support report 2026-08-15 12:12:59 +03:00
Dushnilin 6fdf24723e fix(diagnostics): use core.uci for WAN interface detection instead of shell uci 2026-08-15 10:58:20 +03:00
Dushnilin 57c04c71e8 feat(doctor): add 1-click anonymized support report and LAN device inspector 2026-08-15 10:05:09 +03:00
Dushnilin c8d02a917e Улучшение ИИ-Доктора: экспертная скриптовая система диагностики и самовосстановления 2026-08-15 09:48:40 +03:00
Dushnilin b9c0f72518 fix(doctor): вернуть require core.common и порядок функций в runtime.uc 2026-08-14 17:30:39 +03:00
Dushnilin 455c67c0a7 fix(diagnostic): install servicecheck_profiles.json + guard doctor/ai_doctor (#33)
Makefile was missing the install rule for servicecheck_profiles.json — the community service probe profiles were never copied to /usr/share/tachyon/ on the router, so Service Health Check had zero targets to probe and showed an empty modal.
2026-08-14 16:06:48 +03:00
Dushnilin 7bd373c392 fix(diagnostics): убрать крокозябры в Глобальной проверке и разорвать цикл повторных фиксов AI Doctor (issue #31) 2026-08-14 09:31:31 +03:00
Dushnilin b099b26a68 feat(doctor): режим восстановления при остановленном сервисе и реальная верификация AI Doctor 2026-08-13 21:59:54 +03:00
Dushnilin 5b372f5572 v1.2.75: Add Service Check mode switcher (Active Sections / All Profiles), restore AI Chat Assistant, harmonize action button styles, and fix dark theme compatibility 2026-08-12 12:22:52 +03:00
Dushnilin 1a1fd7f4c3 fix(settings): add Ollama & LM Studio to CBI settings tab options and make API key optional for local LLMs 2026-08-11 22:27:57 +03:00
Dushnilin da199c236a feat(ai-doctor): super-upgrade with Live Stepper, Root Cause Graph, Smart Fix Badges, Deep Log Inspection & Local LLM Presets 2026-08-11 22:00:20 +03:00
Dushnilin 2ef7092810 feat: Add local heuristic AI Doctor engine, DPI block analyzer, and offline fallback 2026-08-11 17:26:53 +03:00
Dushnilin 180c52ecde test: fix BusyBox portability issues in backend test suite 2026-08-11 16:33:46 +03:00
Dushnilin be5f41a52e feat(ai-stack-2026): add OpenAPI 3.0.3 schema, Telegram /ai_doctor & /fix integration, AI language selector, and log deduplication
- Agent REST API (agent_api.uc): Added GET /openapi.json returning OpenAPI 3.0.3 spec for ChatGPT Custom GPTs, N8N, Dify, and LLM Agents
- AI Doctor (runtime.uc): Added compress_log_snippet() for deduplicating repeated log entries and ai_doctor_lang support (ru/en prompt selection)
- Telegram Bot (telegram.uc): Added /ai_doctor and /fix commands with Inline Keyboards for instant quick-fix execution
- Settings (renderAdvancedSettings.ts, settings.js): Added AI Doctor Language selector (ru/en)
- Documentation: Updated README.md and README.en.md with 2026 AI features
2026-08-11 16:10:31 +03:00
Dushnilin 6dd085b777 feat(ai-doctor): supercharge AI Doctor with multi-fix, log context, history, and 13 quick fix codes
Backend (runtime.uc, agent_api.uc, tachyon CLI):
- Enrich AI Doctor LLM context with Watchdog state (OOM, streaks, active repairs) and last 15 critical log lines
- Support multi-fix parsing (quick_fixes array) and comma-separated FIX tags
- Add persistent history saving to /tmp/ai_doctor_last.json and ai_doctor_last endpoint
- Expand quick fix codes from 9 to 13 (added clear_dns_cache, update_subscriptions, reset_firewall, restart_network)
- Implement apply_quick_fix CLI command and REST API endpoint

Frontend (fe-app-tachyon, LuCI main.js):
- Add AI Doctor action button in Diagnostics tab
- Add shell methods aiDoctor, aiDoctorLast, applyQuickFix
- Render AI Doctor modal with Multi-Fix buttons and 'Fix All' option
- Integrate toast notifications and state updates
2026-08-11 16:06:19 +03:00
Dushnilin 3d48a22e3c feat(ai-doctor): add model selection per provider
Backend (runtime.uc):
- query_llm() accepts model_override (5th param), falls back to provider default
- ai_doctor() reads ai_doctor_model from UCI and passes to query_llm

Frontend (renderAdvancedSettings.ts):
- aiDoctorModel state field (type / init / load / save)
- Model dropdown per provider with sensible defaults:
  openai: gpt-4o-mini(default)/gpt-4o/gpt-4.1-mini/gpt-4.1/o4-mini
  anthropic: claude-3-5-haiku(default)/claude-3-5-sonnet/claude-3-7-sonnet
  deepseek: deepseek-chat(default)/deepseek-reasoner
  custom: free-text input
- Switching provider resets model to '' (use new provider default)

Legacy LuCI (settings.js):
- ai_doctor_model Value field with placeholder '(provider default)'
2026-08-11 12:37:31 +03:00
Dushnilin c930c15dc3 feat(ai): добавить поддержку Anthropic Claude API в AI Doctor
- В query_llm (runtime.uc) добавлена интеграция с Anthropic Messages API (https://api.anthropic.com/v1/messages) с заголовком x-api-key
- В настройки Settings и Dashboard добавлен выпадающий выбор провайдера 'Anthropic (Claude API)'
- Добавлен русский перевод для опций AI Doctor
2026-08-10 19:16:19 +03:00
Dushnilin 23f3c8c587 feat: AI Agent API — HTTP REST + CLI for external LLM agents
Adds a self-healing infrastructure accessible via HTTP REST and CLI:

## New files
- tachyon/files/usr/lib/service/agent_api.uc
  Full REST API handler for /tachyon/agent/v1/* endpoints
  READ (no auth): /health /snapshot /diagnose /logs /config /tools
  WRITE (Bearer): /heal /restart /reload /config/set /section/toggle /domain/add

- tachyon/files/usr/lib/cgi-bin/tachyon-agent
  CGI shell wrapper — installed into /www/cgi-bin by postinst
  Exposes agent API via uhttpd at http://<router>/cgi-bin/tachyon-agent/<endpoint>

- AGENT.md
  Full documentation: curl examples, SSH usage, Claude/Open-WebUI integration

## Modified files
- tachyon/files/usr/bin/tachyon
  + diagnose_json command -> diagnostics/runtime.uc diagnose-json
  + agent_cgi command -> service/agent_api.uc __cgi
  + agent subcommand with special arg-passing (path method body bearer)
  + show_help() updated

- tachyon/files/usr/lib/diagnostics/runtime.uc
  + diagnose_json() — structured JSON output of doctor checks for LLM agents
  + Registered in CLI dispatch as 'diagnose-json'
  Fix: UTF-8 byte offset for arrow character U+2192 (+3 not +2)

- tachyon/Makefile
  + INSTALL_BIN for usr/lib/cgi-bin/tachyon-agent
  + postinst: symlink CGI into /www/cgi-bin on install
2026-08-10 13:14:30 +03:00
Dushnilin dce098ff7c feat(doctor): проверка наличия скачанных community lists в секциях
Добавлена проверка 15b в run_doctor_checks():
- Итерирует все включённые секции через uci_core.section_objects()
- Для каждого community_list проверяет существование .srs-файла
  в TMP_RULESET_FOLDER (/tmp/sing-box/rulesets/)
- При наличии пропущенных файлов запускает tachyon list_update и
  перепроверяет результат (FIXED / остались отсутствующие)
- Правильно использует section_objects() вместо get_all() который
  всегда возвращает null при вызове без section_name
2026-08-09 22:55:42 +03:00
Dushnilin 26d67506a4 fix(ui): report the live sing-box version for plain extended installs
The dashboard showed a sing-box version that never changed. build_system_info()
preferred /etc/tachyon/sing-box-version for every "extended" variant, and that
state file is written by the component action alone — a sing-box installed via
install.sh, opkg or by hand leaves it pinned at whatever was recorded last. The
UI then reported the stale version indefinitely, and the update badge compared
the release against it rather than against the binary actually on disk.

The state file only exists for variants whose binary cannot be executed to print
a version: extended-compressed is a self-extracting stub, and lx needs a runtime
that may be absent. Plain extended answers `sing-box version` fine — singbox
/runtime.uc:259 and subscription/cache.uc:1482 both gate on the compressed
variants only. Covering plain extended was a regression from 46ef97fe.

Both call sites now share sing_box_resolved_version(), which also falls through
to the live probe when the state file is missing or empty instead of reporting
"unknown".

Verified on a router: with the state file still holding 1.13.16-extended-2.6.2,
system-info now reports the installed 1.13.18-extended-2.6.3.
2026-08-09 21:56:44 +03:00
Dushnilin 3d84d96e49 feat(ui): display short commit SHA alongside release version across LuCI UI 2026-08-09 08:50:38 +03:00
Dushnilin 106ce9352a fix(memory): ограничить чтения неограниченного вывода в память
На роутере со 128 МБ несколько мест читали в память вывод, размер которого
ничем не ограничен. Распаковка gzip подписки шла через пайп с чтением целиком:
скачивание curl ограничено 15 МБ, но коэффициент сжатия base64-текста высокий,
так что пик доходил до десятков мегабайт. Оба вызывающих места передают файл и
ждут файл, поэтому распакованный поток теперь уходит редиректом сразу в
выходной файл, а успех определяется по коду возврата и ненулевому размеру.

Таблица nftables содержит сеты с десятками тысяч элементов из списков, и
`nft list table` печатает их все. Проба контроллера делала это каждый тик,
хотя ищет только имена цепочек и правил; четыре проверки доктора и вывод
чужих меток из полного рулесета — то же самое. Везде добавлен grep на
источнике, отбирающий только те строки, которые код потом и разбирает.

Два просмотра логов читали кольцевой буфер syslog целиком, чтобы показать
несколько сотен строк; теперь количество строк ограничено на стороне logread.
2026-08-08 23:02:18 +03:00
Dushnilin e6e3853f05 fix(errors): перестать глотать сбои записи состояния в пустых catch
Пустых catch в кодовой базе около полусотни, и они не одинаковые. Большинство
выражает намерение: fs.unlink бросает на ENOENT, а вызывающий говорит «пусть
этого файла не будет», и отсутствующий файл это условие уже выполняет; разбор
json в цикле пропускает мусорную строку и берёт следующую. Такие места теперь
несут пояснение, почему пустое тело здесь и есть правильный ответ.

Семь мест к этому классу не относились: там сбой означал потерю состояния, а
дальше код шёл так, будто всё получилось.

Watchdog писал через пустой catch файл лока перезапуска прокси, шкалу
GOMEMLIMIT после OOM, бэкап конфига и метку keepalive. Не лёгший лок означает,
что следующий тик перезапустит прокси заново, а счётчик rate-limit об этом не
узнает; не записанная метка keepalive заставляет init.d считать watchdog мёртвым
и перезапускать его. Все четыре теперь идут через write_state_file, который
логирует отказ. Метка пишется на каждом тике uloop, поэтому безусловная строка
залила бы syslog именно при переполненной файловой системе — там, где лог нужнее
всего; вместо этого каждый путь сообщает о первом отказе и молчит до следующего
успеха, что заодно делает видимым восстановление.

Контроллер разбирал /etc/sing-box/config.json ради портов http и tproxy и при
неудаче молча брал 4534 и 4530. Watchdog после этого опрашивает не тот порт,
вечно считает прокси нерабочим и лечит его по кругу — при том, что в логе нет
ничего, что связало бы это с конфигом. Разбор вынесен в общую функцию, которая
сообщает о непарсящемся конфиге один раз на процесс.

Telegram молча терял карту callback-токенов: токен уже вшит в клавиатуру к
моменту записи, поэтому провал отдаёт пользователю кнопку, которая на нажатие
ответит «кнопка устарела». Обновление списков молча теряло маркер отложенного
применения nft — списки обновлены на диске и до nftables не доехали никогда,
а строкой выше в лог написано, что маркер сохраняется. urltest молча выкидывал
битое регулярное выражение из конфига пользователя, отчего группа тихо
подхватывала меньше outbound-ов, чем сказано в конфиге.

tests/heal_escalation.sh проверял порядок строк по литералу fs.writefile для
лока и обновлён под новый вызов.
2026-08-08 22:32:09 +03:00
Dushnilin 488bbfefd5 fix: комплексный аудит и исправление ucode кодовой базы
Критические исправления:
- safe_proxy_restart: удаление lock-файла после фонового перезапуска
  с защитой от stale lock (>300 сек)
- write_json_file: атомарная запись через tmp+mv вместо прямой
- write_reload_state: атомарная запись через tmp+mv
- state_add_list: отклонение значений с пробелами

Исправления безопасности:
- killall logread заменён на pkill -f 'logread -f'
- SIGTERM→SIGKILL для Telegram и sing-box при остановке
- Recover OOM scale: инкремент +0.05 каждые 10 минут
- nfqueue и byedpi: trap для корректного завершения дочерних процессов
- nfqueue: валидация стратегий и откат при ошибке запуска
- nfqueue: flush mangle_output перед добавлением правил
- Исправлен парсинг exit code в 14 файлах (status & 127)

Улучшения стабильности:
- init.d: trap для start_service/stop_service
- watchdog: signal traps для legacy fallback loop
- lifecycle: логирование ошибок при остановке компонентов
- singbox/priority: SIGTERM→SIGKILL при остановке
- telegram: exponential backoff (1x→300s) при ошибках API
- telegram: process_updates возвращает boolean для отслеживания успеха
- watchdog: кэш proxy port для уменьшения чтения конфига sing-box
- singbox/generator: упрощён atomic_write_json_file
- packages.uc: переупорядочивание apk_version (лёгкие запросы первыми)
- dns/apply: проверка PID sing-box перед настройкой dnsmasq
- server/service: cleanup_orphaned_server_certs перед вызовом
2026-08-06 00:03:51 +03:00
Dushnilin 56480443b4 feat: dynamic sing-box repo links + expanded README
- runtime.uc: add sing_box_repo_url to build_system_info() based on
  installed variant (extended→shtorm-7, lx→Leadaxe, stable→SagerNet)
- main.js: use systemInfo.sing_box_repo_url instead of hardcoded URL
- README.md / README.en.md: expanded Watchdog section with all 14 fixes,
  atomic operations, restart protection, data correctness, Telegram
  rate limits, firewall improvements, dynamic repo links, commit-level
  update tracking
2026-08-03 21:52:49 +03:00
Dushnilin 5f5031e4db fix: watchdog remaining bugs + atomic writes across 6 files
watchdog.uc:
- H-8: keepalive timestamp for init.d supervision
- H-14: save config backup after successful start
- M-1: empty_sections check domain/domain_suffix/ip_cidr
- M-2: dns_loop re-enable cooldown (5 min)
- M-11: reload_firewall always dedup
- M-12: merge wan+gateway heal into one function
- M-13: telegram rate limit (max 10 per 5 min)

nft/apply.uc: background reload_firewall to avoid blocking
subscription/cache.uc: write_text → write_text_if_changed (atomic)
dns_prefetch.uc: blocking sleep 10 → poll with early exit
diagnostics/runtime.uc: atomic uci_backup_save/restore, atomic scale writes, nslookup -port fix
wan-monitor: rate limit notifications (60s cooldown)
2026-08-03 19:54:50 +03:00
Dushnilin 3752439895 Tachyon Doctor: новые проверки, авто-фиксы, расширенный AI Doctor 2026-08-01 09:24:44 +03:00
Dushnilin 448267335b feat: добавлена поддержка TUIC протокола и DNS over QUIC (DoQ) с ECH 2026-07-31 16:49:55 +03:00