Files
lemana-vpn/.understand-anything/knowledge-graph.json

2037 lines
60 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"nodes": [
{
"id": "document:AGENTS.md",
"type": "document",
"name": "AGENTS.md",
"filePath": "AGENTS.md",
"summary": "Репозиторные правила для агентов: модель системы, live VPN safety, тестовая лестница и контракт финального ответа.",
"tags": [
"agent-rules",
"documentation",
"safety"
],
"complexity": "moderate"
},
{
"id": "document:README.md",
"type": "document",
"name": "README.md",
"filePath": "README.md",
"summary": "Основная пользовательская документация Lemana VPN: установка, credential sources, модули, использование, диагностика и удаление.",
"tags": [
"documentation",
"overview",
"user-guide"
],
"complexity": "complex"
},
{
"id": "file:install.sh",
"type": "file",
"name": "install.sh",
"filePath": "install.sh",
"summary": "Installer wizard для Homebrew/pipx/openconnect-lite, CLI, config, DNS wrapper, sudoers, Touch ID helper, Swift app, launch agent и shell aliases.",
"tags": [
"installer",
"wizard",
"macos"
],
"complexity": "complex"
},
{
"id": "function:install.sh:usage",
"type": "function",
"name": "usage",
"filePath": "install.sh",
"lineRange": [
72,
106
],
"summary": "Значимая функция usage в install.sh.",
"tags": [
"function",
"runtime",
"usage"
],
"complexity": "simple"
},
{
"id": "function:install.sh:yes_no",
"type": "function",
"name": "yes_no",
"filePath": "install.sh",
"lineRange": [
304,
330
],
"summary": "Значимая функция yes_no в install.sh.",
"tags": [
"function",
"runtime",
"yes-no"
],
"complexity": "simple"
},
{
"id": "function:install.sh:choose_credential_source_interactive",
"type": "function",
"name": "choose_credential_source_interactive",
"filePath": "install.sh",
"lineRange": [
332,
382
],
"summary": "Показывает интерактивный выбор credential source и нормализует ответ пользователя.",
"tags": [
"function",
"runtime",
"choose-credential-source-interactive"
],
"complexity": "moderate"
},
{
"id": "function:install.sh:print_detected_state",
"type": "function",
"name": "print_detected_state",
"filePath": "install.sh",
"lineRange": [
400,
417
],
"summary": "Значимая функция print_detected_state в install.sh.",
"tags": [
"function",
"runtime",
"print-detected-state"
],
"complexity": "simple"
},
{
"id": "function:install.sh:choose_modules",
"type": "function",
"name": "choose_modules",
"filePath": "install.sh",
"lineRange": [
419,
514
],
"summary": "Определяет набор устанавливаемых модулей с учетом интерактивного режима и флагов installer.",
"tags": [
"function",
"runtime",
"choose-modules"
],
"complexity": "moderate"
},
{
"id": "function:install.sh:download_file",
"type": "function",
"name": "download_file",
"filePath": "install.sh",
"lineRange": [
523,
540
],
"summary": "Значимая функция download_file в install.sh.",
"tags": [
"function",
"runtime",
"download-file"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_homebrew_packages",
"type": "function",
"name": "install_homebrew_packages",
"filePath": "install.sh",
"lineRange": [
552,
578
],
"summary": "Значимая функция install_homebrew_packages в install.sh.",
"tags": [
"function",
"runtime",
"install-homebrew-packages"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_openconnect_lite",
"type": "function",
"name": "install_openconnect_lite",
"filePath": "install.sh",
"lineRange": [
580,
597
],
"summary": "Устанавливает или проверяет openconnect-lite runtime, необходимый для SAML SSO.",
"tags": [
"function",
"runtime",
"install-openconnect-lite"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_cli",
"type": "function",
"name": "install_cli",
"filePath": "install.sh",
"lineRange": [
599,
613
],
"summary": "Копирует основной CLI и uninstall helper в пользовательский bin.",
"tags": [
"function",
"runtime",
"install-cli"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_config",
"type": "function",
"name": "install_config",
"filePath": "install.sh",
"lineRange": [
615,
639
],
"summary": "Устанавливает шаблон openconnect-lite config и сохраняет локальную конфигурацию модулей.",
"tags": [
"function",
"runtime",
"install-config"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_dns_cleanup",
"type": "function",
"name": "install_dns_cleanup",
"filePath": "install.sh",
"lineRange": [
641,
654
],
"summary": "Устанавливает root-owned DNS cleanup wrapper для безопасного сброса корпоративных DNS.",
"tags": [
"function",
"runtime",
"install-dns-cleanup"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_sudoers",
"type": "function",
"name": "install_sudoers",
"filePath": "install.sh",
"lineRange": [
656,
683
],
"summary": "Пишет ограниченные sudoers правила для openconnect и DNS cleanup wrapper.",
"tags": [
"function",
"runtime",
"install-sudoers"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_touchid_helper",
"type": "function",
"name": "install_touchid_helper",
"filePath": "install.sh",
"lineRange": [
685,
708
],
"summary": "Собирает и устанавливает Touch ID helper для Bitwarden master password.",
"tags": [
"function",
"runtime",
"install-touchid-helper"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_menu_bar_app",
"type": "function",
"name": "install_menu_bar_app",
"filePath": "install.sh",
"lineRange": [
710,
769
],
"summary": "Собирает release-версию Swift menu bar app и устанавливает LemanaVPN.app.",
"tags": [
"function",
"runtime",
"install-menu-bar-app"
],
"complexity": "moderate"
},
{
"id": "function:install.sh:install_launch_agent",
"type": "function",
"name": "install_launch_agent",
"filePath": "install.sh",
"lineRange": [
771,
811
],
"summary": "Создает LaunchAgent для автозапуска menu bar app при логине.",
"tags": [
"function",
"runtime",
"install-launch-agent"
],
"complexity": "simple"
},
{
"id": "function:install.sh:restart_running_menu_bar_app",
"type": "function",
"name": "restart_running_menu_bar_app",
"filePath": "install.sh",
"lineRange": [
813,
831
],
"summary": "Перезапускает уже открытое menu bar приложение после обновления bundle.",
"tags": [
"function",
"runtime",
"restart-running-menu-bar-app"
],
"complexity": "simple"
},
{
"id": "function:install.sh:install_shell_aliases",
"type": "function",
"name": "install_shell_aliases",
"filePath": "install.sh",
"lineRange": [
833,
877
],
"summary": "Добавляет idempotent zsh aliases для CLI режимов подключения и диагностики.",
"tags": [
"function",
"runtime",
"install-shell-aliases"
],
"complexity": "simple"
},
{
"id": "function:install.sh:maybe_login_bitwarden",
"type": "function",
"name": "maybe_login_bitwarden",
"filePath": "install.sh",
"lineRange": [
879,
900
],
"summary": "Проверяет Bitwarden session и при необходимости запускает login/unlock flow.",
"tags": [
"function",
"runtime",
"maybe-login-bitwarden"
],
"complexity": "simple"
},
{
"id": "function:install.sh:main",
"type": "function",
"name": "main",
"filePath": "install.sh",
"lineRange": [
902,
941
],
"summary": "Значимая функция main в install.sh.",
"tags": [
"function",
"runtime",
"main"
],
"complexity": "simple"
},
{
"id": "file:uninstall.sh",
"type": "file",
"name": "uninstall.sh",
"filePath": "uninstall.sh",
"summary": "Uninstaller для восстановления runtime patch backups, удаления CLI/app/config/sudoers/aliases и опциональной очистки Keychain/Touch ID state.",
"tags": [
"uninstaller",
"cleanup",
"macos"
],
"complexity": "complex"
},
{
"id": "function:uninstall.sh:usage",
"type": "function",
"name": "usage",
"filePath": "uninstall.sh",
"lineRange": [
62,
79
],
"summary": "Значимая функция usage в uninstall.sh.",
"tags": [
"function",
"runtime",
"usage"
],
"complexity": "simple"
},
{
"id": "function:uninstall.sh:restore_openconnect_lite_patch",
"type": "function",
"name": "restore_openconnect_lite_patch",
"filePath": "uninstall.sh",
"lineRange": [
161,
181
],
"summary": "Возвращает backup исходника openconnect-lite, если runtime patch был установлен.",
"tags": [
"function",
"runtime",
"restore-openconnect-lite-patch"
],
"complexity": "simple"
},
{
"id": "function:uninstall.sh:remove_zshrc_block",
"type": "function",
"name": "remove_zshrc_block",
"filePath": "uninstall.sh",
"lineRange": [
183,
204
],
"summary": "Удаляет idempotent блок Lemana VPN aliases из zshrc.",
"tags": [
"function",
"runtime",
"remove-zshrc-block"
],
"complexity": "simple"
},
{
"id": "function:uninstall.sh:remove_keychain_entries",
"type": "function",
"name": "remove_keychain_entries",
"filePath": "uninstall.sh",
"lineRange": [
206,
234
],
"summary": "Опционально удаляет password, TOTP seed и username из macOS Keychain.",
"tags": [
"function",
"runtime",
"remove-keychain-entries"
],
"complexity": "simple"
},
{
"id": "function:uninstall.sh:main",
"type": "function",
"name": "main",
"filePath": "uninstall.sh",
"lineRange": [
236,
318
],
"summary": "Значимая функция main в uninstall.sh.",
"tags": [
"function",
"runtime",
"main"
],
"complexity": "moderate"
},
{
"id": "document:.agents/skills/lemana-vpn-operations/SKILL.md",
"type": "document",
"name": "Lemana VPN Operations skill",
"filePath": ".agents/skills/lemana-vpn-operations/SKILL.md",
"summary": "Инструкции для операционных задач: установка, обновление, статусы, безопасные ответы пользователю и live-connection правила.",
"tags": [
"skill",
"operations",
"documentation"
],
"complexity": "moderate"
},
{
"id": "document:.agents/skills/lemana-vpn-sso-autofill/SKILL.md",
"type": "document",
"name": "Lemana VPN SSO skill",
"filePath": ".agents/skills/lemana-vpn-sso-autofill/SKILL.md",
"summary": "Инструкции по Bitwarden, Keychain, TOTP, Keycloak SSO, autofill и runtime-патчам openconnect-lite.",
"tags": [
"skill",
"sso",
"credentials"
],
"complexity": "moderate"
},
{
"id": "document:.agents/skills/lemana-vpn-testing/SKILL.md",
"type": "document",
"name": "Lemana VPN Testing skill",
"filePath": ".agents/skills/lemana-vpn-testing/SKILL.md",
"summary": "Инструкции по non-live проверкам, status checks, live VPN safety и финальному отчету для изменений в репозитории.",
"tags": [
"skill",
"testing",
"verification"
],
"complexity": "moderate"
},
{
"id": "file:app/Package.swift",
"type": "file",
"name": "Package.swift",
"filePath": "app/Package.swift",
"summary": "Swift Package manifest для сборки executable target LemanaVPN под macOS 13+.",
"tags": [
"swift",
"build-system",
"menu-bar-app"
],
"complexity": "simple"
},
{
"id": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"type": "file",
"name": "LemanaVPNApp.swift",
"filePath": "app/Sources/LemanaVPN/LemanaVPNApp.swift",
"summary": "SwiftUI/AppKit menu bar surface: отображает состояние VPN, кнопки подключения, логи и действия пользователя.",
"tags": [
"swiftui",
"menu-bar",
"ui"
],
"complexity": "moderate"
},
{
"id": "class:app/Sources/LemanaVPN/LemanaVPNApp.swift:LemanaVPNApp",
"type": "class",
"name": "LemanaVPNApp",
"filePath": "app/Sources/LemanaVPN/LemanaVPNApp.swift",
"lineRange": [
5,
16
],
"summary": "Точка входа SwiftUI menu bar app, связывает VPNManager с MenuBarExtra.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "simple"
},
{
"id": "class:app/Sources/LemanaVPN/LemanaVPNApp.swift:StatusBarLabel",
"type": "class",
"name": "StatusBarLabel",
"filePath": "app/Sources/LemanaVPN/LemanaVPNApp.swift",
"lineRange": [
17,
51
],
"summary": "Компактный status bar label с иконкой и оставшимся временем сессии.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "simple"
},
{
"id": "class:app/Sources/LemanaVPN/LemanaVPNApp.swift:VPNMenuView",
"type": "class",
"name": "VPNMenuView",
"filePath": "app/Sources/LemanaVPN/LemanaVPNApp.swift",
"lineRange": [
52,
191
],
"summary": "Основной menu UI с командами auto/manual/manual-full connect, disconnect, logs и quit.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "moderate"
},
{
"id": "file:app/Sources/LemanaVPN/VPNManager.swift",
"type": "file",
"name": "VPNManager.swift",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"summary": "Основной state manager Swift-приложения: запускает CLI в JSON mode, декодирует события, отслеживает health и управляет reconnect/disconnect.",
"tags": [
"swift",
"state-manager",
"cli-bridge"
],
"complexity": "complex"
},
{
"id": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNEvent",
"type": "class",
"name": "VPNEvent",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
4,
17
],
"summary": "Decodable-модель JSON events, которые runtime CLI отправляет в Swift app.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "simple"
},
{
"id": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNStatusResponse",
"type": "class",
"name": "VPNStatusResponse",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
18,
21
],
"summary": "Decodable envelope для ответа `vpn --status --json`.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "simple"
},
{
"id": "class:app/Sources/LemanaVPN/VPNManager.swift:ModuleStatus",
"type": "class",
"name": "ModuleStatus",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
22,
101
],
"summary": "Модель статуса модулей и вычисление summary/systemImage для menu bar app.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "moderate"
},
{
"id": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNState",
"type": "class",
"name": "VPNState",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
102,
121
],
"summary": "Finite state model для disconnected/connecting/connected/reconnecting/error состояний.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "simple"
},
{
"id": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNLaunchMode",
"type": "class",
"name": "VPNLaunchMode",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
122,
136
],
"summary": "Маппинг app launch modes на CLI flags `--auto`, `--manual`, `--manual-full`.",
"tags": [
"swift",
"type",
"menu-bar-app"
],
"complexity": "simple"
},
{
"id": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNManager",
"type": "class",
"name": "VPNManager",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
137,
698
],
"summary": "ObservableObject, который мостит Swift menu bar app с shell CLI, JSON events и health checks.",
"tags": [
"swift",
"type",
"state-manager"
],
"complexity": "complex"
},
{
"id": "function:app/Sources/LemanaVPN/VPNManager.swift:refreshStatus",
"type": "function",
"name": "refreshStatus",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
194,
248
],
"summary": "Запускает CLI status JSON и обновляет module summary в menu bar app.",
"tags": [
"function",
"runtime",
"refreshStatus"
],
"complexity": "moderate"
},
{
"id": "function:app/Sources/LemanaVPN/VPNManager.swift:connect",
"type": "function",
"name": "connect",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
249,
326
],
"summary": "Запускает CLI в JSON mode с выбранным режимом подключения и подписывается на stdout/stderr.",
"tags": [
"function",
"runtime",
"connect"
],
"complexity": "moderate"
},
{
"id": "function:app/Sources/LemanaVPN/VPNManager.swift:disconnect",
"type": "function",
"name": "disconnect",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
327,
349
],
"summary": "Отправляет SIGINT текущему CLI process и останавливает reconnect state.",
"tags": [
"function",
"runtime",
"disconnect"
],
"complexity": "simple"
},
{
"id": "function:app/Sources/LemanaVPN/VPNManager.swift:parseEvent",
"type": "function",
"name": "parseEvent",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
350,
448
],
"summary": "Декодирует JSON events из CLI и переводит их в Swift state updates.",
"tags": [
"function",
"runtime",
"parseEvent"
],
"complexity": "moderate"
},
{
"id": "function:app/Sources/LemanaVPN/VPNManager.swift:handleTermination",
"type": "function",
"name": "handleTermination",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
449,
576
],
"summary": "Обрабатывает завершение CLI process и решает, нужен ли автоматический reconnect.",
"tags": [
"function",
"runtime",
"handleTermination"
],
"complexity": "moderate"
},
{
"id": "function:app/Sources/LemanaVPN/VPNManager.swift:startHealthCheck",
"type": "function",
"name": "startHealthCheck",
"filePath": "app/Sources/LemanaVPN/VPNManager.swift",
"lineRange": [
577,
666
],
"summary": "Периодически проверяет tunnel health и запускает reconnect при повторных failures.",
"tags": [
"function",
"runtime",
"startHealthCheck"
],
"complexity": "moderate"
},
{
"id": "file:bin/vpn-lemanapro.sh",
"type": "file",
"name": "vpn-lemanapro.sh",
"filePath": "bin/vpn-lemanapro.sh",
"summary": "Главный runtime CLI: status JSON, sync credentials, Keychain/TOTP, runtime patches, SSO запуск, reconnect loop, DNS cleanup и фильтрация openconnect-lite output.",
"tags": [
"cli",
"runtime",
"sso"
],
"complexity": "complex"
},
{
"id": "function:bin/vpn-lemanapro.sh:_module_bool",
"type": "function",
"name": "_module_bool",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
197,
203
],
"summary": "Значимая функция _module_bool в bin/vpn-lemanapro.sh.",
"tags": [
"function",
"runtime",
"module-bool"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_patches_active",
"type": "function",
"name": "_patches_active",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
205,
219
],
"summary": "Значимая функция _patches_active в bin/vpn-lemanapro.sh.",
"tags": [
"function",
"runtime",
"patches-active"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_module_status_json",
"type": "function",
"name": "_module_status_json",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
225,
264
],
"summary": "Собирает машинно-читаемый JSON со статусом модулей, credentials, app, DNS и patches.",
"tags": [
"function",
"runtime",
"module-status-json"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_module_human_part",
"type": "function",
"name": "_module_human_part",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
266,
275
],
"summary": "Значимая функция _module_human_part в bin/vpn-lemanapro.sh.",
"tags": [
"function",
"runtime",
"module-human-part"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_module_status_human",
"type": "function",
"name": "_module_status_human",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
277,
311
],
"summary": "Печатает человекочитаемую строку статуса модулей перед подключением.",
"tags": [
"function",
"runtime",
"module-status-human"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_check_status",
"type": "function",
"name": "_check_status",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
313,
375
],
"summary": "Проверяет PID/status file, running process, DNS target и возвращает disconnected/connected JSON.",
"tags": [
"function",
"runtime",
"check-status"
],
"complexity": "moderate"
},
{
"id": "function:bin/vpn-lemanapro.sh:_patch_oc",
"type": "function",
"name": "_patch_oc",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
377,
604
],
"summary": "Применяет runtime patches к openconnect-lite для Keycloak autofill/manual/debug сценариев.",
"tags": [
"function",
"runtime",
"patch-oc"
],
"complexity": "complex"
},
{
"id": "function:bin/vpn-lemanapro.sh:_normalize_totp_secret",
"type": "function",
"name": "_normalize_totp_secret",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
623,
649
],
"summary": "Нормализует TOTP secret из raw secret или otpauth URI перед сохранением.",
"tags": [
"function",
"runtime",
"normalize-totp-secret"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_persist_username",
"type": "function",
"name": "_persist_username",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
675,
718
],
"summary": "Значимая функция _persist_username в bin/vpn-lemanapro.sh.",
"tags": [
"function",
"runtime",
"persist-username"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_ensure_username",
"type": "function",
"name": "_ensure_username",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
720,
745
],
"summary": "Значимая функция _ensure_username в bin/vpn-lemanapro.sh.",
"tags": [
"function",
"runtime",
"ensure-username"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_configure_keychain",
"type": "function",
"name": "_configure_keychain",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
747,
785
],
"summary": "Интерактивно сохраняет LDAP password и TOTP seed в macOS Keychain.",
"tags": [
"function",
"runtime",
"configure-keychain"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_ensure_keychain_credentials",
"type": "function",
"name": "_ensure_keychain_credentials",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
787,
814
],
"summary": "Проверяет наличие обязательных Keychain credentials перед auto/manual подключением.",
"tags": [
"function",
"runtime",
"ensure-keychain-credentials"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_bw_unlock",
"type": "function",
"name": "_bw_unlock",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
823,
889
],
"summary": "Открывает Bitwarden session с учетом Touch ID helper и fallback prompts.",
"tags": [
"function",
"runtime",
"bw-unlock"
],
"complexity": "moderate"
},
{
"id": "function:bin/vpn-lemanapro.sh:_sync_bitwarden",
"type": "function",
"name": "_sync_bitwarden",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
891,
925
],
"summary": "Синхронизирует LDAP password и TOTP seed из Bitwarden в macOS Keychain.",
"tags": [
"function",
"runtime",
"sync-bitwarden"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_sync_credentials",
"type": "function",
"name": "_sync_credentials",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
927,
936
],
"summary": "Выбирает credential source и запускает соответствующий sync/preflight путь.",
"tags": [
"function",
"runtime",
"sync-credentials"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_dns_cleanup",
"type": "function",
"name": "_dns_cleanup",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
938,
954
],
"summary": "Вызывает narrow sudo wrapper для очистки VPN DNS при завершении сессии.",
"tags": [
"function",
"runtime",
"dns-cleanup"
],
"complexity": "simple"
},
{
"id": "function:bin/vpn-lemanapro.sh:_filter_output",
"type": "function",
"name": "_filter_output",
"filePath": "bin/vpn-lemanapro.sh",
"lineRange": [
956,
1006
],
"summary": "Фильтрует поток openconnect-lite, извлекает IP/expiry, пишет status JSON и события для app.",
"tags": [
"function",
"runtime",
"filter-output"
],
"complexity": "moderate"
},
{
"id": "document:docs/goals/manual-first-auth-flow/GOAL.md",
"type": "document",
"name": "Manual-first auth goal",
"filePath": "docs/goals/manual-first-auth-flow/GOAL.md",
"summary": "Краткое описание цели manual-first authentication flow и ожидаемого пользовательского результата.",
"tags": [
"goal",
"auth-flow",
"planning"
],
"complexity": "simple"
},
{
"id": "document:docs/goals/manual-first-auth-flow/PLAN.md",
"type": "document",
"name": "Manual-first auth plan",
"filePath": "docs/goals/manual-first-auth-flow/PLAN.md",
"summary": "Подробный план изменения installer UX, CLI auth profiles, Swift menu-bar surface и smoke coverage для manual-first сценария.",
"tags": [
"plan",
"auth-flow",
"implementation"
],
"complexity": "complex"
},
{
"id": "document:docs/superpowers/plans/2026-05-24-keychain-totp-provider.md",
"type": "document",
"name": "Keychain TOTP provider plan",
"filePath": "docs/superpowers/plans/2026-05-24-keychain-totp-provider.md",
"summary": "Исторический implementation plan для разделения credential sources, нормализации TOTP и расширения smoke-проверок.",
"tags": [
"plan",
"keychain",
"totp"
],
"complexity": "complex"
},
{
"id": "file:libexec/lemana-vpn-dns-cleanup",
"type": "file",
"name": "lemana-vpn-dns-cleanup",
"filePath": "libexec/lemana-vpn-dns-cleanup",
"summary": "Узкий root-owned wrapper, который сбрасывает только корпоративные DNS и обновляет macOS resolver cache.",
"tags": [
"dns",
"sudo-wrapper",
"cleanup"
],
"complexity": "simple"
},
{
"id": "config:templates/openconnect-lite-config.toml",
"type": "config",
"name": "openconnect-lite-config.toml",
"filePath": "templates/openconnect-lite-config.toml",
"summary": "Шаблон профиля openconnect-lite: gateway, credentials mode и Keycloak auto-fill selectors для username, password и TOTP.",
"tags": [
"configuration",
"openconnect-lite",
"autofill"
],
"complexity": "simple"
},
{
"id": "file:tests/smoke.sh",
"type": "file",
"name": "smoke.sh",
"filePath": "tests/smoke.sh",
"summary": "Non-live smoke suite: shell syntax, installer/uninstaller checks, Swift wiring, SSO patch snippets, config selectors и regression assertions.",
"tags": [
"test",
"smoke",
"verification"
],
"complexity": "complex"
}
],
"edges": [
{
"source": "file:install.sh",
"target": "function:install.sh:usage",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:yes_no",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:choose_credential_source_interactive",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:print_detected_state",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:choose_modules",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:download_file",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_homebrew_packages",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_openconnect_lite",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_cli",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_config",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_dns_cleanup",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_sudoers",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_touchid_helper",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_menu_bar_app",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_launch_agent",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:restart_running_menu_bar_app",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:install_shell_aliases",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:maybe_login_bitwarden",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:install.sh",
"target": "function:install.sh:main",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:uninstall.sh",
"target": "function:uninstall.sh:usage",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:uninstall.sh",
"target": "function:uninstall.sh:restore_openconnect_lite_patch",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:uninstall.sh",
"target": "function:uninstall.sh:remove_zshrc_block",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:uninstall.sh",
"target": "function:uninstall.sh:remove_keychain_entries",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:uninstall.sh",
"target": "function:uninstall.sh:main",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"target": "class:app/Sources/LemanaVPN/LemanaVPNApp.swift:LemanaVPNApp",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"target": "class:app/Sources/LemanaVPN/LemanaVPNApp.swift:StatusBarLabel",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"target": "class:app/Sources/LemanaVPN/LemanaVPNApp.swift:VPNMenuView",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNEvent",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNStatusResponse",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "class:app/Sources/LemanaVPN/VPNManager.swift:ModuleStatus",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNState",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNLaunchMode",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "class:app/Sources/LemanaVPN/VPNManager.swift:VPNManager",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "function:app/Sources/LemanaVPN/VPNManager.swift:refreshStatus",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "function:app/Sources/LemanaVPN/VPNManager.swift:connect",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "function:app/Sources/LemanaVPN/VPNManager.swift:disconnect",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "function:app/Sources/LemanaVPN/VPNManager.swift:parseEvent",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "function:app/Sources/LemanaVPN/VPNManager.swift:handleTermination",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "function:app/Sources/LemanaVPN/VPNManager.swift:startHealthCheck",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_module_bool",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_patches_active",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_module_status_json",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_module_human_part",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_module_status_human",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_check_status",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_patch_oc",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_normalize_totp_secret",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_persist_username",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_ensure_username",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_configure_keychain",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_ensure_keychain_credentials",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_bw_unlock",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_sync_bitwarden",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_sync_credentials",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_dns_cleanup",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "function:bin/vpn-lemanapro.sh:_filter_output",
"type": "contains",
"direction": "forward",
"weight": 1
},
{
"source": "document:README.md",
"target": "file:install.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:README.md",
"target": "file:bin/vpn-lemanapro.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:README.md",
"target": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:README.md",
"target": "file:app/Sources/LemanaVPN/VPNManager.swift",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:README.md",
"target": "file:uninstall.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:README.md",
"target": "config:templates/openconnect-lite-config.toml",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:README.md",
"target": "file:libexec/lemana-vpn-dns-cleanup",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:AGENTS.md",
"target": "document:.agents/skills/lemana-vpn-operations/SKILL.md",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:AGENTS.md",
"target": "document:.agents/skills/lemana-vpn-sso-autofill/SKILL.md",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:AGENTS.md",
"target": "document:.agents/skills/lemana-vpn-testing/SKILL.md",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:.agents/skills/lemana-vpn-operations/SKILL.md",
"target": "file:install.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:.agents/skills/lemana-vpn-operations/SKILL.md",
"target": "file:bin/vpn-lemanapro.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:.agents/skills/lemana-vpn-operations/SKILL.md",
"target": "file:uninstall.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:.agents/skills/lemana-vpn-sso-autofill/SKILL.md",
"target": "file:bin/vpn-lemanapro.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:.agents/skills/lemana-vpn-sso-autofill/SKILL.md",
"target": "config:templates/openconnect-lite-config.toml",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:.agents/skills/lemana-vpn-testing/SKILL.md",
"target": "file:tests/smoke.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/goals/manual-first-auth-flow/GOAL.md",
"target": "document:docs/goals/manual-first-auth-flow/PLAN.md",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/goals/manual-first-auth-flow/PLAN.md",
"target": "file:install.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/goals/manual-first-auth-flow/PLAN.md",
"target": "file:bin/vpn-lemanapro.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/goals/manual-first-auth-flow/PLAN.md",
"target": "file:app/Sources/LemanaVPN/VPNManager.swift",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/goals/manual-first-auth-flow/PLAN.md",
"target": "file:tests/smoke.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/superpowers/plans/2026-05-24-keychain-totp-provider.md",
"target": "file:install.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/superpowers/plans/2026-05-24-keychain-totp-provider.md",
"target": "file:bin/vpn-lemanapro.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/superpowers/plans/2026-05-24-keychain-totp-provider.md",
"target": "file:app/Sources/LemanaVPN/VPNManager.swift",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "document:docs/superpowers/plans/2026-05-24-keychain-totp-provider.md",
"target": "file:tests/smoke.sh",
"type": "documents",
"direction": "forward",
"weight": 0.5
},
{
"source": "file:install.sh",
"target": "file:bin/vpn-lemanapro.sh",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:install.sh",
"target": "file:uninstall.sh",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:install.sh",
"target": "config:templates/openconnect-lite-config.toml",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:install.sh",
"target": "file:libexec/lemana-vpn-dns-cleanup",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:install.sh",
"target": "file:app/Package.swift",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:install.sh",
"target": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:install.sh",
"target": "file:app/Sources/LemanaVPN/VPNManager.swift",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:uninstall.sh",
"target": "file:bin/vpn-lemanapro.sh",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:uninstall.sh",
"target": "file:libexec/lemana-vpn-dns-cleanup",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"target": "file:app/Sources/LemanaVPN/VPNManager.swift",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "file:bin/vpn-lemanapro.sh",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "config:templates/openconnect-lite-config.toml",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "file:libexec/lemana-vpn-dns-cleanup",
"type": "depends_on",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:app/Package.swift",
"target": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"type": "configures",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:app/Package.swift",
"target": "file:app/Sources/LemanaVPN/VPNManager.swift",
"type": "configures",
"direction": "forward",
"weight": 0.6
},
{
"source": "config:templates/openconnect-lite-config.toml",
"target": "file:bin/vpn-lemanapro.sh",
"type": "configures",
"direction": "forward",
"weight": 0.6
},
{
"source": "file:install.sh",
"target": "file:tests/smoke.sh",
"type": "tested_by",
"direction": "forward",
"weight": 0.5
},
{
"source": "file:uninstall.sh",
"target": "file:tests/smoke.sh",
"type": "tested_by",
"direction": "forward",
"weight": 0.5
},
{
"source": "file:bin/vpn-lemanapro.sh",
"target": "file:tests/smoke.sh",
"type": "tested_by",
"direction": "forward",
"weight": 0.5
},
{
"source": "file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"target": "file:tests/smoke.sh",
"type": "tested_by",
"direction": "forward",
"weight": 0.5
},
{
"source": "file:app/Sources/LemanaVPN/VPNManager.swift",
"target": "file:tests/smoke.sh",
"type": "tested_by",
"direction": "forward",
"weight": 0.5
},
{
"source": "config:templates/openconnect-lite-config.toml",
"target": "file:tests/smoke.sh",
"type": "tested_by",
"direction": "forward",
"weight": 0.5
}
],
"version": "1.0.0",
"project": {
"name": "Lemana VPN",
"languages": [
"markdown",
"swift",
"shell",
"unknown",
"toml"
],
"frameworks": [
"SwiftUI",
"AppKit",
"openconnect-lite",
"Bitwarden CLI",
"macOS Keychain"
],
"description": "macOS-пакет для корпоративного VPN Lemana: installer, CLI runtime, SSO/autofill через openconnect-lite, DNS cleanup wrapper и Swift menu bar app.",
"analyzedAt": "2026-06-23T06:33:02.614Z",
"gitCommitHash": "042c4d655090e0ee334208511ec63b6d909d4354"
},
"layers": [
{
"id": "layer:documentation-and-agent-guidance",
"name": "Документация и agent guidance",
"description": "Пользовательская документация, локальные agent skills и планы, которые описывают ожидаемые операции, safety rules и будущие изменения.",
"nodeIds": [
"document:README.md",
"document:AGENTS.md",
"document:.agents/skills/lemana-vpn-operations/SKILL.md",
"document:.agents/skills/lemana-vpn-sso-autofill/SKILL.md",
"document:.agents/skills/lemana-vpn-testing/SKILL.md",
"document:docs/goals/manual-first-auth-flow/GOAL.md",
"document:docs/goals/manual-first-auth-flow/PLAN.md",
"document:docs/superpowers/plans/2026-05-24-keychain-totp-provider.md"
]
},
{
"id": "layer:installer-and-uninstaller",
"name": "Installer и uninstall слой",
"description": "Shell scripts, которые устанавливают, обновляют и удаляют локальный VPN пакет, включая dependencies, app bundle, aliases, sudoers и cleanup.",
"nodeIds": [
"file:install.sh",
"file:uninstall.sh"
]
},
{
"id": "layer:runtime-cli-and-system-integration",
"name": "Runtime CLI и системная интеграция",
"description": "Основной CLI, openconnect-lite config и DNS cleanup wrapper, которые управляют SSO, credentials, VPN session status и системной очисткой DNS.",
"nodeIds": [
"file:bin/vpn-lemanapro.sh",
"config:templates/openconnect-lite-config.toml",
"file:libexec/lemana-vpn-dns-cleanup"
]
},
{
"id": "layer:swift-menu-bar-app",
"name": "Swift menu bar app",
"description": "Swift Package и SwiftUI/AppKit код menu bar приложения, которое запускает CLI, показывает статус и предоставляет user-facing actions.",
"nodeIds": [
"file:app/Package.swift",
"file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"file:app/Sources/LemanaVPN/VPNManager.swift"
]
},
{
"id": "layer:verification",
"name": "Verification слой",
"description": "Non-live smoke suite, который закрепляет синтаксис, installer/runtime/app wiring и SSO patch/config expectations.",
"nodeIds": [
"file:tests/smoke.sh"
]
}
],
"tour": [
{
"order": 1,
"title": "Назначение проекта",
"description": "Начните с README и AGENTS, чтобы понять пользовательский контракт, состав пакета и правила безопасной работы с live VPN.",
"nodeIds": [
"document:README.md",
"document:AGENTS.md"
],
"languageLesson": "Markdown здесь используется как операционный runbook: таблицы путей, shell blocks и safety sections важнее обычного prose."
},
{
"order": 2,
"title": "Установка и удаление",
"description": "Разберите installer и uninstaller: они определяют, какие артефакты попадают в систему и как их безопасно откатить.",
"nodeIds": [
"file:install.sh",
"file:uninstall.sh"
],
"languageLesson": "Shell strict-mode и idempotent функции помогают повторять установку без ручной чистки состояния."
},
{
"order": 3,
"title": "Runtime CLI",
"description": "Основной runtime находится в `vpn-lemanapro.sh`: он синхронизирует credentials, применяет patches, запускает SSO и публикует JSON events.",
"nodeIds": [
"file:bin/vpn-lemanapro.sh",
"config:templates/openconnect-lite-config.toml",
"file:libexec/lemana-vpn-dns-cleanup"
]
},
{
"order": 4,
"title": "SSO, credentials и autofill",
"description": "SSO skill и historical plans объясняют, почему runtime разделяет Bitwarden sync, Keychain-only flow, TOTP normalization и manual/full-manual режимы.",
"nodeIds": [
"document:.agents/skills/lemana-vpn-sso-autofill/SKILL.md",
"document:docs/superpowers/plans/2026-05-24-keychain-totp-provider.md",
"file:bin/vpn-lemanapro.sh"
]
},
{
"order": 5,
"title": "Menu bar app",
"description": "Swift layer показывает user-facing поверхность: `LemanaVPNApp` строит меню, а `VPNManager` мостит app с CLI JSON events и health checks.",
"nodeIds": [
"file:app/Package.swift",
"file:app/Sources/LemanaVPN/LemanaVPNApp.swift",
"file:app/Sources/LemanaVPN/VPNManager.swift"
],
"languageLesson": "SwiftUI state flow здесь строится вокруг `ObservableObject` и `@Published`: изменения CLI events автоматически обновляют меню."
},
{
"order": 6,
"title": "Проверка без live VPN",
"description": "Закончите smoke suite и testing skill: они показывают, какие проверки можно делать до любого реального подключения.",
"nodeIds": [
"file:tests/smoke.sh",
"document:.agents/skills/lemana-vpn-testing/SKILL.md"
]
}
]
}