From db0c1dede96909f4ff4dcd528bcc0cf07f0f52d6 Mon Sep 17 00:00:00 2001 From: Dokril Date: Thu, 9 Jul 2026 11:19:10 +0300 Subject: [PATCH] Expand AGENTS.md with current repo and reporting rules --- .agent/README.md | 61 +++++ .agent/checklists/change-safety.md | 30 +++ .agent/checklists/communication.md | 37 +++ .agent/checklists/explanation-quality.md | 41 +++ .agent/checklists/release.md | 30 +++ .agent/checklists/security.md | 36 +++ .agent/checklists/ui.md | 24 ++ .../skills/communication-reporting/SKILL.md | 248 +++++++++++++++++ .agent/skills/react-typescript-ui/SKILL.md | 93 +++++++ .agent/skills/repository-orientation/SKILL.md | 78 ++++++ .agent/skills/rust-tauri-backend/SKILL.md | 106 ++++++++ .agent/skills/security-hardening/SKILL.md | 138 ++++++++++ .agent/skills/subscriptions-routing/SKILL.md | 87 ++++++ .agent/skills/testing-ci-release/SKILL.md | 104 ++++++++ .../windows-services-powershell/SKILL.md | 94 +++++++ .agent/templates/change-report.md | 29 ++ .agent/templates/concise-change-summary.md | 30 +++ .agent/templates/file-impact-map.md | 20 ++ .agent/templates/investigation-report.md | 27 ++ .agent/templates/pr-description.md | 32 +++ .agent/templates/user-facing-summary.md | 27 ++ .agent/templates/work-plan.md | 23 ++ .cursor/rules/proxywarden.mdc | 32 +++ .github/copilot-instructions.md | 26 ++ AGENTS.md | 249 ++++++++++++++---- docs/agent/ARCHITECTURE-NOTES.md | 60 +++++ 26 files changed, 1708 insertions(+), 54 deletions(-) create mode 100644 .agent/README.md create mode 100644 .agent/checklists/change-safety.md create mode 100644 .agent/checklists/communication.md create mode 100644 .agent/checklists/explanation-quality.md create mode 100644 .agent/checklists/release.md create mode 100644 .agent/checklists/security.md create mode 100644 .agent/checklists/ui.md create mode 100644 .agent/skills/communication-reporting/SKILL.md create mode 100644 .agent/skills/react-typescript-ui/SKILL.md create mode 100644 .agent/skills/repository-orientation/SKILL.md create mode 100644 .agent/skills/rust-tauri-backend/SKILL.md create mode 100644 .agent/skills/security-hardening/SKILL.md create mode 100644 .agent/skills/subscriptions-routing/SKILL.md create mode 100644 .agent/skills/testing-ci-release/SKILL.md create mode 100644 .agent/skills/windows-services-powershell/SKILL.md create mode 100644 .agent/templates/change-report.md create mode 100644 .agent/templates/concise-change-summary.md create mode 100644 .agent/templates/file-impact-map.md create mode 100644 .agent/templates/investigation-report.md create mode 100644 .agent/templates/pr-description.md create mode 100644 .agent/templates/user-facing-summary.md create mode 100644 .agent/templates/work-plan.md create mode 100644 .cursor/rules/proxywarden.mdc create mode 100644 .github/copilot-instructions.md create mode 100644 docs/agent/ARCHITECTURE-NOTES.md diff --git a/.agent/README.md b/.agent/README.md new file mode 100644 index 0000000..40b3b4c --- /dev/null +++ b/.agent/README.md @@ -0,0 +1,61 @@ +# ProxyWarden Agent Kit + +Этот каталог содержит инструкции для кодовых агентов, которые работают с ProxyWarden. + +Главный файл — `AGENTS.md` в корне репозитория. Он задает инварианты и общие правила. Файлы в `.agent/skills` описывают конкретные режимы работы: backend, UI, security, Windows services, subscriptions/routing, testing/release и понятные отчеты. + +## Как использовать + +1. Прочитать корневой `AGENTS.md`. +2. Выбрать skill под задачу. +3. Перед изменением проверить релевантные чек-листы из `.agent/checklists`. +4. После изменения выполнить минимальные проверки. +5. Для любого нетривиального ответа использовать `communication-reporting`: коротко, по файлам, с проверками и рисками. +6. В финальном отчете явно указать, что было и не было проверено. + +## Как агент должен писать ответы + +По умолчанию агент пишет не техническую простыню, а короткий отчет: + +```text +Коротко +Что изменилось по файлам +Важные места +Проверено +Не проверено +Риски +``` + +Для 2+ файлов желательно использовать таблицу `Файл / Что изменилось / Зачем`. В ответе должны быть конкретные пути файлов и человеческая причина изменения. Не надо пересказывать каждую строку diff, если пользователь не попросил. + +Подробные правила лежат в `.agent/skills/communication-reporting/SKILL.md`, чек-лист — в `.agent/checklists/communication.md`. Да, это нужно отдельно прописывать, иначе агент опять напишет роман о своем внутреннем мире и двух переименованных переменных. + +## Skill index + +- `repository-orientation` — вход в проект, карта файлов, где искать source of truth. +- `rust-tauri-backend` — Tauri commands, Rust models, validation, storage, adapters. +- `react-typescript-ui` — React UI, typed invoke facade, readiness, components. +- `security-hardening` — CSP, секреты, elevated boundary, storage corruption, SSRF. +- `windows-services-powershell` — scripts, UAC, services, ProxiFyre/sing-box operations. +- `subscriptions-routing` — external SOCKS5, sing-box subscriptions, config generation, ping. +- `testing-ci-release` — build/test matrix, CI recommendations, release hygiene. +- `communication-reporting` — короткие планы, понятные сводки по файлам, отчеты без текстовой каши. + +## Communication defaults + +Перед длинным ответом или отчетом использовать: + +- `.agent/skills/communication-reporting/SKILL.md` +- `.agent/checklists/communication.md` +- `.agent/checklists/explanation-quality.md` +- `.agent/templates/change-report.md` или `.agent/templates/user-facing-summary.md` +- `.agent/templates/file-impact-map.md`, если надо заранее показать, какие файлы будут затронуты + +Главная идея: сначала короткая сводка, потом таблица файлов, потом проверки и риски. Не наоборот, потому что пользователь не обязан добывать смысл киркой. + +## Что не является целью + +- Перевод проекта в SaaS/gateway/server. +- Добавление облачного backend. +- Замена ProxiFyre без отдельной архитектурной задачи. +- Коммерциализация, telemetry-first подход или рекламная шелуха, этот вид пластика уже и так в океане. diff --git a/.agent/checklists/change-safety.md b/.agent/checklists/change-safety.md new file mode 100644 index 0000000..cdf35a9 --- /dev/null +++ b/.agent/checklists/change-safety.md @@ -0,0 +1,30 @@ +# Change Safety Checklist + +Use this before and after non-trivial changes. + +## Scope + +- [ ] I identified whether this touches backend, UI, security, Windows service, subscription/routing, testing/release. +- [ ] I read the matching skill file. +- [ ] I avoided unrelated rewrites. +- [ ] I did not introduce a second source of truth. + +## Tauri boundary + +- [ ] New/changed Rust command has matching TypeScript wrapper. +- [ ] DTOs are synchronized between Rust and TypeScript. +- [ ] Error shape is structured and actionable. +- [ ] Blocking work is not run on async runtime thread. + +## UX + +- [ ] User-visible actions are explicit. +- [ ] Disabled states have reasons. +- [ ] Pending changes are visible before apply. +- [ ] Secrets are redacted. + +## Validation + +- [ ] Relevant frontend build/test was run or explicitly not run with reason. +- [ ] Relevant Rust fmt/clippy/test was run or explicitly not run with reason. +- [ ] Windows-specific behavior was not claimed unless tested on Windows. diff --git a/.agent/checklists/communication.md b/.agent/checklists/communication.md new file mode 100644 index 0000000..ce3bd80 --- /dev/null +++ b/.agent/checklists/communication.md @@ -0,0 +1,37 @@ +# Communication Checklist + +Используй перед финальным ответом по любой нетривиальной задаче. + +## Структура + +- [ ] Ответ начинается с `Коротко` или с такой же короткой сводки на 2-4 пункта. +- [ ] Измененные файлы или зоны проекта перечислены в начале ответа, а не спрятаны в конце. +- [ ] Для каждого важного файла понятно: что изменилось и зачем. +- [ ] Важные изменения поведения, безопасности или состояния отделены от мелких деталей. +- [ ] Проверки разделены на `Проверено` и `Не проверено`. +- [ ] Риски написаны явно. + +## Понятность + +- [ ] Нет плотных абзацев длиннее 4-5 строк. +- [ ] Нет терминов и аббревиатур без пользы или краткого объяснения. +- [ ] Нет полных логов, если они не нужны для вывода. +- [ ] Нет пересказа каждой строки diff, если пользователь не просил. +- [ ] Нет мутных фраз вроде `улучшена архитектура` без объяснения, что стало проще, безопаснее или понятнее. + +## Честность + +- [ ] Windows/service/elevation поведение не названо проверенным, если оно не тестировалось на Windows. +- [ ] У пропущенных проверок есть простая причина. +- [ ] Ответ не говорит `готово`, если важные проверки пропущены. + +## Быстрая самопроверка + +Перед отправкой ответ должен отвечать на вопросы: + +1. Что изменилось или найдено? +2. В каких файлах? +3. Зачем это нужно? +4. Что реально проверено? +5. Что не проверено? +6. Где остался риск? diff --git a/.agent/checklists/explanation-quality.md b/.agent/checklists/explanation-quality.md new file mode 100644 index 0000000..737a215 --- /dev/null +++ b/.agent/checklists/explanation-quality.md @@ -0,0 +1,41 @@ +# Checklist: Explanation Quality + +Используй перед финальным ответом или PR summary. + +## Обязательное + +- [ ] В начале есть короткий итог на 2–4 пункта. +- [ ] Есть список файлов или таблица `файл / что / зачем`. +- [ ] Термины объяснены простыми словами, если они важны. +- [ ] Нет длинных полотен без заголовков. +- [ ] Нет пересказа каждой строки diff. +- [ ] Указано, что проверено. +- [ ] Указано, что не проверено. +- [ ] Риски написаны прямо, без «должно работать». + +## Хороший формат + +```md +## Коротко +- ... + +## Файлы +| Файл | Что | Зачем | +|---|---|---| + +## Проверки +- Выполнено: ... +- Не выполнено: ... + +## Риски +- ... +``` + +## Плохие признаки + +- Один огромный абзац. +- Много терминов без пользы. +- «Исправлена логика» без указания файла и эффекта. +- «Проверено» без команды или способа проверки. +- «Не проверял Windows, но всё готово». +- Список из 25 пунктов одинаковой важности. diff --git a/.agent/checklists/release.md b/.agent/checklists/release.md new file mode 100644 index 0000000..7596aa7 --- /dev/null +++ b/.agent/checklists/release.md @@ -0,0 +1,30 @@ +# Release Checklist + +## Build + +- [ ] `npm ci` +- [ ] `npm run build` +- [ ] `cargo fmt --all -- --check` +- [ ] `cargo clippy --all-targets --all-features -- -D warnings` +- [ ] `cargo test --all-targets` +- [ ] `npm run tauri -- build` + +## Windows smoke + +- [ ] Fresh Windows VM smoke test. +- [ ] ProxiFyre install plan and real install. +- [ ] sing-box install plan and real install. +- [ ] External SOCKS5 route works. +- [ ] Local sing-box subscription route works. +- [ ] Start/stop/restart service controls work. +- [ ] Uninstall does not delete unmanaged paths. + +## Security/release hygiene + +- [ ] CSP enabled. +- [ ] Capabilities minimal. +- [ ] No raw secrets in repo/logs. +- [ ] Subscription redaction checked. +- [ ] Generated config writes are safe. +- [ ] Artifact version is correct. +- [ ] Large assets reviewed/compressed if practical. diff --git a/.agent/checklists/security.md b/.agent/checklists/security.md new file mode 100644 index 0000000..9bbdd04 --- /dev/null +++ b/.agent/checklists/security.md @@ -0,0 +1,36 @@ +# Security Checklist + +## Secrets + +- [ ] Subscription URLs are redacted through parser-based logic. +- [ ] Proxy credentials are not logged. +- [ ] Outbound configs with secrets are not printed in diagnostics. +- [ ] Error messages do not include tokens/passwords/userinfo. + +## Tauri/webview + +- [ ] CSP is enabled. +- [ ] No broad shell permissions added. +- [ ] No direct command execution from UI input. +- [ ] No `dangerouslySetInnerHTML` or equivalent unsafe HTML rendering without sanitization. + +## Network fetch + +- [ ] Subscription fetch has timeout. +- [ ] URL scheme is restricted. +- [ ] Local/private/link-local/metadata address behavior is explicit. +- [ ] Redirect behavior does not bypass blocked address checks. + +## Filesystem + +- [ ] Critical writes are atomic where practical. +- [ ] Corrupt config handling does not silently discard user state. +- [ ] Recursive delete has strict path/marker checks. +- [ ] Temp elevated scripts use unpredictable names and safe directory/ACL when practical. + +## Windows services + +- [ ] Managed service is verified by name and PathName/metadata. +- [ ] Fuzzy candidates are not automatically controlled. +- [ ] UAC cancellation has clear error. +- [ ] Plan-only remains side-effect-free. diff --git a/.agent/checklists/ui.md b/.agent/checklists/ui.md new file mode 100644 index 0000000..85f0e6c --- /dev/null +++ b/.agent/checklists/ui.md @@ -0,0 +1,24 @@ +# UI Checklist + +## Structure + +- [ ] No direct `invoke(...)` outside `src/api/tauriCommands.ts`. +- [ ] New reusable UI uses `src/ui/*` components or extends them. +- [ ] New business/display logic is not buried in JSX if it can be tested separately. +- [ ] `App.tsx` was not made worse without justification. + +## Accessibility and behavior + +- [ ] Buttons have accessible names. +- [ ] Toggle state uses `aria-pressed` or equivalent. +- [ ] Tabs/popovers preserve keyboard and screen-reader behavior. +- [ ] Reduced motion preference is respected where animation is added. +- [ ] Errors are visible and readable. + +## ProxyWarden-specific + +- [ ] External SOCKS5 route does not require sing-box. +- [ ] Local sing-box route requires selected server and readiness. +- [ ] Route chain matches actual backend state. +- [ ] Apply readiness gives a clear reason. +- [ ] Summary remains read-only. diff --git a/.agent/skills/communication-reporting/SKILL.md b/.agent/skills/communication-reporting/SKILL.md new file mode 100644 index 0000000..8674180 --- /dev/null +++ b/.agent/skills/communication-reporting/SKILL.md @@ -0,0 +1,248 @@ +# Skill: Communication Reporting + +## Когда использовать + +Используй этот skill в каждом ответе пользователю после анализа, правки кода, ревью, аудита, планирования рефакторинга или подготовки PR. Особенно если задача затрагивает несколько файлов, backend/frontend boundary, security, Windows services или UI. + +## Цель + +Писать так, чтобы человек с опытом разработки быстро понял суть без чтения технической простыни. Не упрощать до детского сада, но объяснять по-человечески: что поменялось, где, зачем, как проверить, где риск. + +Пользователь не обязан продираться через внутренний монолог агента и каталог аббревиатур. У него есть жизнь, возможно даже вне репозитория, страшно представить. + +## Базовый формат ответа + +Для нетривиальных изменений используй такую структуру: + +```text +Коротко +- 2-4 пункта: главный результат, важный риск, что проверить. + +Что изменилось по файлам +| Файл | Что изменилось | Зачем | +|---|---|---| +| src/... | Кратко | Человеческая причина | + +Важные места +- 3-6 конкретных мест: файл + функция/секция + смысл. + +Как проверить +- Команды или ручные шаги. + +Что не проверено +- Честно и коротко. + +Риски +- Только реальные риски, не философия. +``` + +Если изменение маленькое, можно сократить до: + +```text +Коротко: ... + +Файлы: +- `path`: что и зачем. + +Проверка: ... +``` + +## Правила ясности + +- Сначала вывод, потом детали. +- Не писать длиннее, чем нужно для решения задачи. +- Не перечислять каждую строку diff. Указывать только смысловые изменения. +- Всегда называть конкретные файлы. +- Для сложных мест указывать функцию, модуль или секцию, если это помогает найти код. +- Если используешь термин, рядом дать короткое человеческое объяснение. +- Не использовать аббревиатуры без расшифровки при первом упоминании, кроме очевидных: UI, JSON, URL, API. +- Не писать «улучшена архитектура» без объяснения, что именно стало проще или безопаснее. +- Не писать «всё готово», если часть проверок не запускалась. +- Не скрывать ошибки окружения. Если `cargo` или Windows недоступны, так и сказать. + +## Как объяснять технические изменения + +Плохо: + +```text +Refactored orchestration layer and extracted imperative use-case side effects into composable boundaries. +``` + +Хорошо: + +```text +Вынес запуск service-команд из большого `commands.rs` в отдельный модуль. Теперь Tauri command только принимает запрос и возвращает ошибку, а вся Windows-логика лежит отдельно. Так проще тестировать и меньше шанс сломать соседние команды. +``` + +Плохо: + +```text +Added CSP hardening. +``` + +Хорошо: + +```text +Включил CSP в `src-tauri/tauri.conf.json`. Это ограничивает, какие скрипты/ресурсы может загрузить webview, и снижает ущерб, если в UI когда-нибудь появится XSS. +``` + +## Уровни детализации + +По умолчанию — средний уровень: + +- достаточно конкретно, чтобы разработчик понял diff; +- без пересказа каждой строки; +- без внутренних рассуждений агента; +- без длинной теории. + +Если пользователь просит глубже, добавь раздел: + +```text +Детальнее +- ... +``` + +Если пользователь просит совсем кратко, оставь только: + +```text +Коротко +Файлы +Проверка +``` + +## Таблица файлов + +Для 2+ файлов почти всегда используй таблицу: + +| Файл | Тип изменения | Смысл | +|---|---|---| +| `src/api/tauriCommands.ts` | API boundary | Добавлен typed wrapper для новой Tauri command | +| `src-tauri/src/commands.rs` | Backend | Добавлена команда, которая вызывает уже существующую service-логику | + +Правила: + +- Не вставлять огромные таблицы на 30 строк. Группировать мелкие файлы. +- В колонке `Смысл` писать человеческую причину, не только «обновлено». +- Если файл опасный, отметить это: `security-sensitive`, `Windows/elevation`, `storage`, `routing`. + +## Как писать про риски + +Риск должен быть конкретным: + +Плохо: + +```text +Есть некоторые риски. +``` + +Хорошо: + +```text +Риск: я не запускал real Windows service flow, поэтому install/start/stop надо проверить на Windows 10/11 с UAC. +``` + +Плохо: + +```text +Может быть несовместимость. +``` + +Хорошо: + +```text +Риск: если у пользователя уже стоит чужая служба с похожим именем ProxiFyre, fuzzy detection может показать ее кандидатом. Управлять ей нельзя без проверки `PathName`. +``` + +## Как писать про проверки + +Разделяй выполненное и невыполненное: + +```text +Проверено +- `npm run build` — прошел. +- Markdown-файлы открываются, битых путей не нашел. + +Не проверено +- `cargo test` — не запускал, в среде нет Rust toolchain. +- Windows service flow — не проверял, нужна Windows-машина с UAC. +``` + +Не объединять это в мутное «тесты частично пройдены». Машины и люди заслуживают хотя бы грамм конкретики. + +## Запрещенный стиль + +Не писать: + +- огромные абзацы без заголовков; +- «магия», «оптимизировано», «улучшено» без конкретики; +- внутренний дневник действий агента; +- цепочки мыслей; +- список всех строк diff; +- рекламный тон; +- уверенные заявления о непроверенных Windows/elevation сценариях; +- «как вы и просили, я с радостью...» — репозиторий от этого лучше не станет. + +## Мини-шаблоны + +### Для bugfix + +```text +Коротко +- Исправил ... +- Основной риск был ... +- Проверка: ... + +Что изменилось по файлам +| Файл | Что изменилось | Зачем | +|---|---|---| + +Важные места +- `file`: ... + +Проверено +- ... + +Не проверено +- ... +``` + +### Для ревью без правок + +```text +Коротко +- Самая важная проблема: ... +- Второй приоритет: ... +- Быстрый выигрыш: ... + +Что я смотрел +- ... + +Проблемы по важности +1. Critical/High: ... +2. Medium: ... +3. Low: ... + +Что бы я сделал первым +- ... +``` + +### Для плана изменений + +```text +Коротко +- Цель: ... +- Затронет: ... +- Не трогаем: ... + +План по файлам +| Файл/зона | Что сделать | Почему | +|---|---|---| + +Порядок работ +1. ... +2. ... +3. ... + +Проверка +- ... +``` diff --git a/.agent/skills/react-typescript-ui/SKILL.md b/.agent/skills/react-typescript-ui/SKILL.md new file mode 100644 index 0000000..305d8f8 --- /dev/null +++ b/.agent/skills/react-typescript-ui/SKILL.md @@ -0,0 +1,93 @@ +# Skill: React / TypeScript UI + +## Когда использовать + +Используй этот skill при изменениях в `src`, UI, state management, typed Tauri wrappers, readiness logic, route visualization, forms, logs, buttons, popovers, service panels. + +## Главная цель + +UI должен ясно объяснять, что будет сделано с сетью пользователя, не прятать опасные действия и не превращаться в панель управления космической станцией ради одной прокси-кнопки. + +## Инварианты + +- `src/api/tauriCommands.ts` — единственное место для `invoke(...)`. +- `src/domain/types.ts` должен отражать backend DTO. +- Apply-readiness logic живет в `src/app/readiness.ts`. +- Presentational UI должен переиспользовать `src/ui/*`. +- Summary panel read-only. +- Install/start/stop/uninstall/apply actions must be explicit. +- Secrets must be redacted. + +## App.tsx rule + +`src/app/App.tsx` уже слишком большой. Новую логику не добавлять туда, если можно вынести: + +```text +src/app/hooks/useStartupSnapshot.ts +src/app/hooks/useApplyFlow.ts +src/app/hooks/useServiceControl.ts +src/app/hooks/useSubscription.ts +src/app/lib/parseProxy.ts +src/app/lib/snapshots.ts +src/app/components/RouteChain.tsx +src/app/components/ChangesDock.tsx +src/app/components/ProxyPanel.tsx +src/app/components/SingBoxWorkspace.tsx +``` + +Если изменение маленькое и локальное, допустимо править `App.tsx`, но не расширять его архитектурную роль. + +## UI behavior rules + +- Disabled button must explain why. +- Loading/busy state must prevent double submit. +- Errors must be human-readable and actionable. +- Long paths, service names and tags must not break layout. +- Do not use native `title` as main tooltip UX. Use existing popover/tooltip pattern. +- Use `aria-*` for tabs, toggle buttons, popovers, service controls. +- Honor reduced motion where relevant. + +## Proxy/routing UI + +When editing route UI: + +- External SOCKS5 mode must not require sing-box. +- Local sing-box mode must require selected server and sing-box readiness. +- App list must clearly distinguish process, folder, exe/path if those are different target kinds. +- Route chain should reflect actual backend target/profile state. +- Pending changes should be visible before apply. + +## Tests/checks + +Minimum: + +```powershell +npm run build +``` + +Recommended for extracted pure logic: + +- Unit tests for proxy parsing. +- Unit tests for readiness states. +- Unit tests for snapshot diff/change dock model. +- UI smoke checks for desktop and narrow layout. + +## Do not + +- Do not call backend commands from random components. +- Do not store secrets in React state longer than needed if display value can be redacted. +- Do not duplicate Rust validation as the only validation. Frontend validation is UX, backend validation is authority. +- Do not add a visual state that implies a service is running unless backend confirmed it. + +## Как отчитываться + +Перед финальным ответом применить `.agent/skills/communication-reporting/SKILL.md` и `.agent/checklists/communication.md`. + +Минимум для нетривиальной задачи: + +- короткая сводка; +- таблица файлов `Файл / Что изменилось / Зачем`; +- важные места без пересказа каждой строки; +- что проверено; +- что не проверено; +- конкретные риски. diff --git a/.agent/skills/repository-orientation/SKILL.md b/.agent/skills/repository-orientation/SKILL.md new file mode 100644 index 0000000..3b48062 --- /dev/null +++ b/.agent/skills/repository-orientation/SKILL.md @@ -0,0 +1,78 @@ +# Skill: Repository Orientation + +## Когда использовать + +Используй этот skill в начале любой нетривиальной задачи по ProxyWarden: аудит, рефакторинг, bugfix, изменение UI, изменение Windows service flow, изменение subscription/routing. + +## Цель + +Быстро понять, где находится нужная логика, какие инварианты нельзя нарушать и какие проверки нужны перед финальным ответом. + +## Карта проекта + +```text +src/api/tauriCommands.ts typed frontend API boundary +src/domain/types.ts TypeScript DTO/domain mirror +src/app/App.tsx current UI orchestration, large file +src/app/readiness.ts apply readiness/gating +src/app/viewModel.ts view helpers +src/ui/* reusable UI components +src/styles/app.css global/component CSS + +src-tauri/src/models.rs Rust domain models +src-tauri/src/validation.rs input normalization/validation +src-tauri/src/storage.rs JSON config/state storage +src-tauri/src/activity.rs activity log +src-tauri/src/subscription.rs subscription fetch/parse +src-tauri/src/component_detection.rs component status detection +src-tauri/src/adapters/* ProxiFyre/sing-box/proxy router adapters +src-tauri/src/commands.rs Tauri command layer, currently too large +src-tauri/tests/* Rust tests +scripts/*.ps1 Windows install/control scripts +``` + +## Source of truth + +- Persistent app config/state: `C:\ProgramData\ProxyWarden\config` and `state`. +- Generated artifacts: `C:\ProgramData\ProxyWarden\generated`. +- Frontend state is not source of truth. It should represent backend state and pending UI edits. +- Component detection/runtime status should come from backend, not guessed in UI. + +## First-pass procedure + +1. Identify whether the task is backend, UI, security, Windows service, subscription/routing, or testing/release. +2. Read the matching skill file. +3. Inspect the relevant source files listed above. +4. Determine whether the change crosses the Tauri boundary. If yes, update both Rust DTO/command and TypeScript wrapper/types. +5. Determine whether the change touches secrets, service control, generated configs, process execution, filesystem deletion, or network fetch. If yes, apply security checklist. +6. Prefer small, isolated changes over broad rewrites. + +## Do not + +- Do not treat `App.tsx` or `commands.rs` as the correct permanent architecture just because they currently contain lots of logic. +- Do not introduce a second storage system. +- Do not move service/install logic into frontend. +- Do not claim Windows service/elevation behavior is verified unless it was actually tested on Windows. + +## Output expectations + +For code changes, final report should include: + +- Changed files. +- User-visible behavior changes. +- Internal behavior changes. +- Tests/checks run. +- Known unverified areas. + +## Как отчитываться + +Перед финальным ответом применить `.agent/skills/communication-reporting/SKILL.md` и `.agent/checklists/communication.md`. + +Минимум для нетривиальной задачи: + +- короткая сводка; +- таблица файлов `Файл / Что изменилось / Зачем`; +- важные места без пересказа каждой строки; +- что проверено; +- что не проверено; +- конкретные риски. diff --git a/.agent/skills/rust-tauri-backend/SKILL.md b/.agent/skills/rust-tauri-backend/SKILL.md new file mode 100644 index 0000000..bec7d5c --- /dev/null +++ b/.agent/skills/rust-tauri-backend/SKILL.md @@ -0,0 +1,106 @@ +# Skill: Rust / Tauri Backend + +## Когда использовать + +Используй этот skill при изменениях в `src-tauri`, Tauri commands, Rust models, validation, storage, adapters, component detection, subscription fetching, config generation или service orchestration. + +## Главная цель + +Держать backend надежным, типизированным и безопасным. Backend управляет системой пользователя, поэтому «ну вроде работает» здесь примерно как инструкция по посадке самолета, написанная на салфетке. + +## Инварианты + +- Tauri command layer должен быть thin boundary, а не склад всей бизнес-логики. +- Долгие/blocking операции не должны выполняться на async runtime thread. +- Все ошибки, которые видит UI, должны быть structured and actionable. +- Validation должна происходить на backend даже если UI уже проверяет input. +- Generated config writes должны быть atomic where practical. +- Secrets never logged or fully displayed. + +## Preferred command pattern + +Для тяжелых операций: + +```rust +#[tauri::command] +pub async fn some_command(input: SomeInput) -> Result { + tauri::async_runtime::spawn_blocking(move || some_command_impl(input)) + .await + .map_err(background_task_error)? +} +``` + +Implementation function должна быть тестируемой без Tauri runtime, если возможно. + +## DTO boundary + +При добавлении или изменении command: + +1. Rust input/output DTO. +2. TypeScript DTO in `src/domain/types.ts`. +3. Wrapper in `src/api/tauriCommands.ts`. +4. UI usage. +5. Tests for pure logic. + +Не использовать `serde_json::Value` как permanent API, если структура известна. + +## Error handling + +- Не использовать `unwrap()`/`expect()` в production path. +- Возвращать `CommandError { code, message, details }`. +- Для validation использовать список проблем, а не первую попавшуюся ошибку. +- Internal error text не должен раскрывать secrets. +- Если операция partial, вернуть partial state/result where possible. + +## Storage + +При изменении `storage.rs`: + +- Keep tmp + bak write pattern. +- Не превращать invalid JSON в default молча. Prefer corruption backup/restore path. +- Для critical writes использовать same-directory temp file and rename. +- Не хранить derived artifacts как source of truth. +- Не хранить raw subscription/proxy secrets в activity log. + +## Refactoring guidance + +`src-tauri/src/commands.rs` слишком большой. Новую логику по возможности выносить: + +```text +commands/dto.rs +commands/status.rs +commands/profiles.rs +commands/targets.rs +commands/components.rs +commands/subscription.rs +commands/proxifyre.rs +commands/singbox.rs +services/elevated.rs +services/powershell.rs +services/proxifyre_service.rs +services/singbox_service.rs +``` + +При рефакторинге сохранять external command names, чтобы UI не ломался без причины. + +## Validation checklist + +- `cargo fmt --all -- --check` +- `cargo clippy --all-targets --all-features -- -D warnings` +- `cargo test --all-targets` +- Relevant Windows/manual check if touching service/install/elevation. + +Если `cargo` недоступен в среде, честно написать, что backend проверен только статически. Не изображать компилятор, у него и так тяжелая жизнь. + +## Как отчитываться + +Перед финальным ответом применить `.agent/skills/communication-reporting/SKILL.md` и `.agent/checklists/communication.md`. + +Минимум для нетривиальной задачи: + +- короткая сводка; +- таблица файлов `Файл / Что изменилось / Зачем`; +- важные места без пересказа каждой строки; +- что проверено; +- что не проверено; +- конкретные риски. diff --git a/.agent/skills/security-hardening/SKILL.md b/.agent/skills/security-hardening/SKILL.md new file mode 100644 index 0000000..7c2b089 --- /dev/null +++ b/.agent/skills/security-hardening/SKILL.md @@ -0,0 +1,138 @@ +# Skill: Security Hardening + +## Когда использовать + +Используй этот skill при изменениях, связанных с Tauri security, CSP, secrets, subscription fetching, process execution, PowerShell, temporary files, install/uninstall, file writes, generated configs, service control, logs, diagnostics. + +## Threat model + +ProxyWarden — desktop app that can influence network routing and run elevated Windows operations. Главные риски: + +- leaking proxy/subscription credentials; +- unsafe local/network fetches; +- unsafe generated elevated PowerShell scripts; +- unscoped process execution; +- corrupting generated/service configs; +- deleting wrong directories; +- stale component status causing wrong actions; +- XSS/webview compromise amplified by privileged backend commands. + +## Non-negotiables + +- `tauri.conf.json` must not use `"csp": null` as final state. +- Do not add broad Tauri shell permissions. +- Do not execute user-controlled strings as commands. +- Do not log full subscription URLs, proxy passwords, userinfo, access tokens, or outbound configs with credentials. +- Do not recursively delete directories based only on fuzzy name matching. +- Do not treat fuzzy-detected services as managed without verification. + +## CSP guidance + +Prefer a restrictive CSP such as: + +```json +"security": { + "csp": "default-src 'self'; img-src 'self' asset: data:; style-src 'self' 'unsafe-inline'; script-src 'self'" +} +``` + +Tighten further when possible. If inline styles are removed, remove `'unsafe-inline'`. + +## Secret redaction + +For URLs use a parser, not string splitting. Redacted display should include only: + +- scheme; +- host; +- port if useful; +- generic path marker if necessary. + +Never show: + +- username; +- password; +- query string; +- fragment; +- subscription token path; +- full proxy credentials. + +Bad: + +```text +https://user:password@example.com/... +``` + +Good: + +```text +https://example.com/... +``` + +## Subscription fetch hardening + +- Add connect/read timeout. +- Accept only `http` and `https` unless explicitly designed otherwise. +- Consider blocking loopback/private/link-local/multicast/metadata addresses by default. +- Add explicit allow-local option only if needed. +- Do not follow redirects into blocked address ranges without re-check. +- Avoid storing remote body in logs. + +## Temp/elevated script hardening + +Runtime-generated elevated scripts must: + +- use unpredictable names, preferably UUID/random; +- be written to a safe controlled directory where possible; +- set restrictive ACL when practical; +- be generated from static templates with escaped parameters; +- avoid including secrets in command line args; +- be cleaned up best-effort; +- fail closed if path validation fails. + +Timestamp-only temp names are not enough. + +## Atomic writes + +For config files used by services: + +1. Write to temp file in same directory. +2. Validate temp file if validator exists. +3. Backup current file. +4. Rename temp to final. +5. On failure, preserve backup and return actionable error. + +## Safe delete checklist + +Before recursive delete: + +- Is path absolute? +- Is it under expected managed root? +- Does it contain ProxyWarden marker metadata? +- Does service PathName point inside this directory? +- Is it not drive root, user profile root, Desktop, ProgramData root, Windows directory, temp root? +- Is user action explicit? + +If answer is unclear, do not delete. + +## Final report expectations + +When touching security-sensitive code, report: + +- what threat was addressed; +- what was hardened; +- what remains unverified; +- whether any secrets could appear in logs/UI; +- whether Windows elevated path was tested. + +## Как отчитываться + +Перед финальным ответом применить `.agent/skills/communication-reporting/SKILL.md` и `.agent/checklists/communication.md`. + +Минимум для нетривиальной задачи: + +- короткая сводка; +- таблица файлов `Файл / Что изменилось / Зачем`; +- важные места без пересказа каждой строки; +- что проверено; +- что не проверено; +- конкретные риски. diff --git a/.agent/skills/subscriptions-routing/SKILL.md b/.agent/skills/subscriptions-routing/SKILL.md new file mode 100644 index 0000000..697b463 --- /dev/null +++ b/.agent/skills/subscriptions-routing/SKILL.md @@ -0,0 +1,87 @@ +# Skill: Subscriptions and Routing + +## Когда использовать + +Используй этот skill при изменениях в external SOCKS5 flow, Local sing-box flow, subscription fetching/parsing, server selection, ping/check route, ProxiFyre config generation или sing-box config generation. + +## Mental model + +Supported route shapes: + +```text +selected Windows apps -> ProxiFyre -> external SOCKS5 proxy +``` + +```text +selected Windows apps -> ProxiFyre -> 127.0.0.1:1080 Local sing-box -> selected subscription server +``` + +ProxiFyre is the per-app router. Sing-box is optional local outbound runtime. + +## Invariants + +- External SOCKS5 must work without Local sing-box. +- Local sing-box route requires installed/configured/running sing-box and selected server. +- UI route chain must match generated backend config. +- Subscription URL is secret. +- Server identity should not rely only on non-unique human tag forever. +- Generated config should be validated before apply/start where possible. + +## Subscription rules + +When changing subscription parsing: + +- Preserve JSON outbound support. +- Do not claim support for link formats that parser does not implement. +- If adding VMess/Trojan/Shadowsocks link parsing, add tests for each. +- Keep unsupported outbound types visible as unsupported, not silently dropped if this affects user expectation. +- Redact subscription URL and outbound secrets in logs/UI. + +## Ping/check rules + +- Network checks should have timeout. +- Checks should be cancel-safe where possible. +- Do not make route check mutate config/service state. +- Do not store external IP probe result as secret, but avoid over-logging. +- Make it clear if check verifies local sing-box only, external proxy only, or full route. + +## Config generation + +For ProxiFyre: + +- Respect selected app targets. +- Deduplicate carefully, preferably case-insensitive where Windows semantics apply. +- Validate target kind semantics: process name vs exe path vs folder. +- Write config atomically. + +For sing-box: + +- Validate selected server/outbound exists. +- Avoid duplicate tag ambiguity by introducing stable id if needed. +- Run `sing-box check` when binary is available. +- Avoid writing secrets to temp files outside safe app directories. + +## Tests to add for changes + +- External route without sing-box. +- Local route with selected server. +- Missing ProxiFyre blocks apply. +- Missing sing-box blocks local route apply. +- Duplicate server tags. +- Redacted subscription display. +- Unsupported subscription formats. +- Timeout/fetch failure. +- Config generation produces expected route chain. + +## Как отчитываться + +Перед финальным ответом применить `.agent/skills/communication-reporting/SKILL.md` и `.agent/checklists/communication.md`. + +Минимум для нетривиальной задачи: + +- короткая сводка; +- таблица файлов `Файл / Что изменилось / Зачем`; +- важные места без пересказа каждой строки; +- что проверено; +- что не проверено; +- конкретные риски. diff --git a/.agent/skills/testing-ci-release/SKILL.md b/.agent/skills/testing-ci-release/SKILL.md new file mode 100644 index 0000000..3351cb6 --- /dev/null +++ b/.agent/skills/testing-ci-release/SKILL.md @@ -0,0 +1,104 @@ +# Skill: Testing, CI and Release + +## Когда использовать + +Используй этот skill при добавлении CI, release scripts, build fixes, test changes, dependency updates, packaging changes или перед финальным отчетом по крупной задаче. + +## Minimal local checks + +Frontend: + +```powershell +npm ci +npm run build +``` + +Rust: + +```powershell +cd src-tauri +cargo fmt --all -- --check +cargo clippy --all-targets --all-features -- -D warnings +cargo test --all-targets +``` + +Tauri: + +```powershell +npm run tauri -- info +npm run tauri -- build +``` + +PowerShell plan-only: + +```powershell +& .\scripts\install-control-app.ps1 -PlanOnly +& .\scripts\install-proxyfier.ps1 -PlanOnly +& .\scripts\install-singbox.ps1 -PlanOnly +``` + +## CI recommendation + +Add GitHub Actions with at least: + +- frontend build on Windows and Ubuntu if practical; +- Rust fmt/clippy/test; +- PowerShell syntax/plan-only smoke on Windows; +- Tauri build on Windows for release branches/tags; +- artifact upload only for trusted release workflow. + +## Dependency updates + +When changing dependencies: + +- Update lockfiles. +- Check Tauri v2 compatibility. +- Avoid adding large UI/runtime dependencies for tiny tasks. +- Avoid adding shell/process libraries that bypass existing backend boundaries. +- Note why dependency is needed. + +## Release hygiene + +Before release: + +- Verify app version in `package.json` and Tauri config if applicable. +- Verify icons/assets size. +- Verify CSP and capabilities. +- Verify no raw secrets/test URLs in repo. +- Verify installer scripts with `-PlanOnly`. +- Verify clean install on Windows VM. +- Verify external SOCKS5 flow. +- Verify local sing-box subscription flow. +- Verify uninstall/safe cleanup behavior. + +## Final report format + +```text +Changed: +- ... + +Verified: +- npm run build +- cargo test + +Not verified: +- Windows elevated install/uninstall, because ... + +Risks: +- ... +``` + +Do not write “all tests pass” unless all listed relevant tests actually ran. Humanity has enough fictional dashboards. + +## Как отчитываться + +Перед финальным ответом применить `.agent/skills/communication-reporting/SKILL.md` и `.agent/checklists/communication.md`. + +Минимум для нетривиальной задачи: + +- короткая сводка; +- таблица файлов `Файл / Что изменилось / Зачем`; +- важные места без пересказа каждой строки; +- что проверено; +- что не проверено; +- конкретные риски. diff --git a/.agent/skills/windows-services-powershell/SKILL.md b/.agent/skills/windows-services-powershell/SKILL.md new file mode 100644 index 0000000..42bbe77 --- /dev/null +++ b/.agent/skills/windows-services-powershell/SKILL.md @@ -0,0 +1,94 @@ +# Skill: Windows Services / PowerShell / Elevation + +## Когда использовать + +Используй этот skill при изменениях в `scripts/*.ps1`, ProxiFyre install/start/stop/uninstall, sing-box service control, UAC/admin checks, helper/elevation boundary, component detection. + +## Цель + +Сохранять service/install operations явными, безопасными и проверяемыми. Пользователь должен понимать, что приложение собирается менять в системе. Компьютер пользователя — не песочница для творческих экспериментов агента, как ни печально. + +## Инварианты + +- Install/start/stop/uninstall are explicit user actions. +- `apply` must not silently install/uninstall/start/stop components unless that behavior is clearly designed and surfaced. +- `-PlanOnly` scripts must be side-effect-free. +- PowerShell output intended for UI/backend must be structured JSON. +- Service detection must distinguish managed service from fuzzy candidate. +- Never relax safe-path checks to make uninstall easier. + +## Script rules + +PowerShell scripts should: + +- use `Set-StrictMode -Version Latest` where practical; +- set `$ErrorActionPreference = 'Stop'`; +- return structured JSON for plan/status paths; +- avoid localized text parsing for control flow; +- avoid writing secrets to host output; +- have clear exit codes; +- support `-PlanOnly` for dry-run/status checks; +- avoid downloading/executing arbitrary remote scripts. + +## Elevation rules + +When launching elevated PowerShell: + +- keep command fixed and parameters escaped; +- avoid user-controlled script text; +- avoid predictable temp script names; +- do not pass secrets via command line; +- verify script path before launch; +- clean up temp artifacts best-effort; +- return clear error if user cancels UAC. + +## Service detection + +Preferred approach: + +1. Search known managed service names first. +2. Read service `PathName` through WMI/CIM. +3. Verify binary path and managed install metadata. +4. Only then mark as managed/controllable. +5. Fuzzy matches should be shown as candidates, not automatically controlled. + +## Testing + +Pure logic can be tested cross-platform with mocks. + +Real verification requires Windows: + +```powershell +& .\scripts\install-control-app.ps1 -PlanOnly +& .\scripts\install-proxyfier.ps1 -PlanOnly +& .\scripts\install-singbox.ps1 -PlanOnly +npm run tauri -- dev +``` + +For real service tests: + +- Windows 10/11. +- Admin/UAC path. +- Fresh machine or VM snapshot. +- Existing ProxiFyre/sing-box absent. +- Existing fuzzy ProxiFyre-like service present, if testing safety. + +## Do not + +- Do not claim actual service operations were tested unless they were run on Windows. +- Do not parse human-localized `sc.exe` output if structured WMI/CIM data is available. +- Do not delete paths from fuzzy discovery alone. +- Do not make scripts silently modify firewall/proxy/system settings outside their stated purpose. + +## Как отчитываться + +Перед финальным ответом применить `.agent/skills/communication-reporting/SKILL.md` и `.agent/checklists/communication.md`. + +Минимум для нетривиальной задачи: + +- короткая сводка; +- таблица файлов `Файл / Что изменилось / Зачем`; +- важные места без пересказа каждой строки; +- что проверено; +- что не проверено; +- конкретные риски. diff --git a/.agent/templates/change-report.md b/.agent/templates/change-report.md new file mode 100644 index 0000000..a7cfe42 --- /dev/null +++ b/.agent/templates/change-report.md @@ -0,0 +1,29 @@ +# Change Report + +## Коротко + +- +- +- + +## Файлы + +| Файл | Что изменилось | Зачем | +|---|---|---| +| `path/file` | | | + +## Важные детали + +- + +## Проверки + +- ✅/⚠️ `command` — результат простыми словами. + +## Не проверено + +- + +## Риски / что потом + +- diff --git a/.agent/templates/concise-change-summary.md b/.agent/templates/concise-change-summary.md new file mode 100644 index 0000000..4e2795e --- /dev/null +++ b/.agent/templates/concise-change-summary.md @@ -0,0 +1,30 @@ +# Concise Change Summary Template + +## Коротко + +- +- +- + +## Что изменилось по файлам + +| Файл | Что изменилось | Зачем | +|---|---|---| +| `path/to/file` | | | + +## Важные места + +- `path/to/file`, функция/секция: +- `path/to/file`, функция/секция: + +## Проверено + +- + +## Не проверено + +- + +## Риски + +- diff --git a/.agent/templates/file-impact-map.md b/.agent/templates/file-impact-map.md new file mode 100644 index 0000000..d1cfb3b --- /dev/null +++ b/.agent/templates/file-impact-map.md @@ -0,0 +1,20 @@ +# File Impact Map Template + +Используй для плана или ревью, когда нужно заранее показать, какие файлы будут затронуты. + +| Зона | Файлы | Что будет сделано | Почему это нужно | Риск | +|---|---|---|---|---| +| Frontend API | `src/api/tauriCommands.ts` | | | Low/Medium/High | +| Frontend UI | `src/app/...` | | | Low/Medium/High | +| Backend command | `src-tauri/src/...` | | | Low/Medium/High | +| Storage/config | `src-tauri/src/storage.rs` | | | Low/Medium/High | +| Windows/elevation | `scripts/*.ps1` | | | Low/Medium/High | +| Docs/agent | `.agent/...` | | | Low/Medium/High | + +## Что не трогаем + +- + +## Как проверить после изменений + +- diff --git a/.agent/templates/investigation-report.md b/.agent/templates/investigation-report.md new file mode 100644 index 0000000..e3c9262 --- /dev/null +++ b/.agent/templates/investigation-report.md @@ -0,0 +1,27 @@ +# Investigation Report + +## Коротко + +- Главный вывод: +- Где проблема: +- Что делать первым: + +## Что смотрел + +| Файл / зона | Зачем смотрел | Вывод | +|---|---|---| +| `path/file` | | | + +## Находки + +| Приоритет | Где | Что не так | Как исправить | +|---|---|---|---| +| Критично / Важно / Можно потом / Косметика | `path/file` | | | + +## Проверки + +- + +## Ограничения анализа + +- diff --git a/.agent/templates/pr-description.md b/.agent/templates/pr-description.md new file mode 100644 index 0000000..ad7b06d --- /dev/null +++ b/.agent/templates/pr-description.md @@ -0,0 +1,32 @@ +## Коротко + +- +- +- + +## Файлы / зоны + +| Файл / зона | Что изменилось | Зачем | +|---|---|---| +| `path/file` | | | + +## Пользовательское поведение + +- Что пользователь увидит: +- Что не должно измениться: + +## Технические детали + +- + +## Проверки + +- [ ] `npm run build` +- [ ] `cargo fmt --all -- --check` +- [ ] `cargo clippy --all-targets --all-features -- -D warnings` +- [ ] `cargo test --all-targets` +- [ ] Windows manual smoke, если затронуты service/elevation/install/routing + +## Не проверено / риски + +- diff --git a/.agent/templates/user-facing-summary.md b/.agent/templates/user-facing-summary.md new file mode 100644 index 0000000..eaa3a12 --- /dev/null +++ b/.agent/templates/user-facing-summary.md @@ -0,0 +1,27 @@ +# User-facing Summary + +## Коротко + +- +- +- + +## Что изменилось простыми словами + +- + +## Файлы + +| Файл | Что изменилось | Зачем | +|---|---|---| +| `path/file` | | | + +## Что важно знать + +- + +## Проверки и риски + +- ✅ Проверено: +- ⚠️ Не проверено: +- Риск: diff --git a/.agent/templates/work-plan.md b/.agent/templates/work-plan.md new file mode 100644 index 0000000..d0d66d8 --- /dev/null +++ b/.agent/templates/work-plan.md @@ -0,0 +1,23 @@ +# Work Plan + +## Коротко + +Сделаю так: + +1. +2. +3. + +## Какие файлы, вероятно, затрону + +| Файл / зона | Что планируется | Зачем | +|---|---|---| +| `path/file` | | | + +## Что проверю + +- + +## Что может остаться непроверенным + +- diff --git a/.cursor/rules/proxywarden.mdc b/.cursor/rules/proxywarden.mdc new file mode 100644 index 0000000..67a47a0 --- /dev/null +++ b/.cursor/rules/proxywarden.mdc @@ -0,0 +1,32 @@ +--- +description: ProxyWarden repository rules for Cursor agents +alwaysApply: true +--- + +# ProxyWarden Cursor Rules + +Read `AGENTS.md` before editing. Use `.agent/skills/*/SKILL.md` for task-specific guidance. + +## Core rules + +- Keep ProxyWarden a standalone Windows desktop utility: Tauri 2 + React/TypeScript + Rust. +- Preserve separation between Control App, ProxiFyre and Local sing-box. +- External SOCKS5 route must work without sing-box. +- UI must call backend through `src/api/tauriCommands.ts`, not direct random `invoke(...)` calls. +- Backend must validate all inputs even if UI validates them. +- Do not leak subscription URLs, proxy credentials or outbound secrets. +- Keep install/start/stop/uninstall explicit. +- Do not relax safe deletion or elevated script rules. +- Prefer shrinking `src-tauri/src/commands.rs` and `src/app/App.tsx` over adding more logic there. +- Run relevant checks and state unverified Windows/elevation behavior honestly. + +## Communication rules + +Before non-trivial answers, follow `.agent/skills/communication-reporting/SKILL.md` and `.agent/checklists/communication.md`. + +- Write final answers in short, structured Russian unless the user asks otherwise. +- Start with `Коротко` for nontrivial work. +- For 2+ files, use a table with `Файл / Что изменилось / Зачем`. +- Do not dump every diff line. Mention important functions/sections only. +- Clearly split `Проверено` and `Не проверено`. +- Do not claim Windows/UAC/service checks were done unless they actually ran. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..9514d83 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,26 @@ +# Copilot Instructions for ProxyWarden + +Read `AGENTS.md` first. Follow the repo invariants there. + +## Key reminders + +- This is a standalone Windows Tauri 2 + React/TypeScript + Rust app. +- Do not turn it into a SaaS, gateway, server or cloud control plane. +- Do not call `invoke(...)` outside `src/api/tauriCommands.ts`. +- Do not make Local sing-box required for external SOCKS5 routing. +- Do not hide install/start/stop/uninstall behind apply. +- Do not log or display full subscription URLs, proxy credentials or outbound secrets. +- Keep Tauri capabilities minimal and CSP enabled. +- Treat `commands.rs` and `App.tsx` as large legacy orchestration files that should shrink over time. +- For security-sensitive changes, read `.agent/skills/security-hardening/SKILL.md`. +- For Windows service/elevation changes, read `.agent/skills/windows-services-powershell/SKILL.md`. + +## Reporting style + +Before non-trivial answers, follow `.agent/skills/communication-reporting/SKILL.md` and `.agent/checklists/communication.md`. + +- Start with `Коротко`: 2-4 main points. +- For code changes, include a `Файл / Что изменилось / Зачем` table. +- Explain only important behavior, safety, UX and risk points. Do not retell every line. +- Split checks into `Проверено` and `Не проверено`. +- State unverified Windows/UAC/service behavior honestly. diff --git a/AGENTS.md b/AGENTS.md index 0fddaa6..cf509aa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,72 +1,198 @@ -# Инструкции для агентов +# AGENTS.md -## Контекст проекта +## Назначение -ProxyWarden - standalone Windows desktop client в корне репозитория. Это Tauri 2 + React/TypeScript UI + Rust backend для маршрутизации выбранных Windows-приложений через внешний SOCKS5-прокси или опциональный Local sing-box. +ProxyWarden — standalone Windows desktop-приложение для удобного per-app proxy routing. Стек: Tauri 2, Rust backend, React/TypeScript frontend, Vite, PowerShell installer/control scripts. Приложение управляет выбранными Windows-приложениями через ProxiFyre и, опционально, через локальный sing-box runtime. -Не возвращать старую идею `APP_MODE=windows` и не подключать Windows-клиент к отдельному Node gateway/server. Текущий рабочий путь - `src`, `src-tauri`, `scripts` в корне репозитория. +Этот файл — главный контракт для кодового агента. Любой агент, который меняет репозиторий, обязан соблюдать эти правила. Да, даже если ему очень хочется «быстренько поправить одну кнопочку» и случайно переписать половину сетевого стека. Особенно тогда. -## Основные инварианты +## Продуктовая рамка -- Три компонента должны оставаться разделенными: Control App, ProxiFyre, Local sing-box. -- ProxiFyre - обязательный слой для per-app routing; Local sing-box - необязательный runtime. -- Внешний SOCKS5 flow должен работать без установленного Local sing-box. -- Profile apply не должен скрыто устанавливать, удалять, запускать или чинить компоненты. Install/start/stop/uninstall - только явные действия пользователя. -- Source of truth - JSON под `C:\ProgramData\ProxyWarden\config` и `state`. -- `C:\ProgramData\ProxyWarden\generated\proxifyre-app-config.json` и `sing-box-config.json` - derived artifacts, их можно пересоздать. -- Subscription URL и другие секреты нельзя показывать полностью в UI, diagnostics или логах. -- Summary panel должен оставаться read-only: без apply/install/start/stop/delete/input/subscription mutations. +Проект не должен превращаться в коммерческий SaaS, Node gateway, VPN-провайдер, proxy server или облачный control plane. Это локальная Windows-утилита для себя и друзей. + +Цель: надежно и понятно конфигурировать маршрутизацию выбранных приложений через внешний SOCKS5 proxy или через локальный sing-box, не ломая системную сеть и не пряча опасные действия за безобидными кнопками. + +## Архитектурные инварианты + +- Control App, ProxiFyre и Local sing-box — разные компоненты. Не смешивать их ответственность. +- ProxiFyre — обязательный слой для per-app routing. +- Local sing-box — optional runtime. Внешний SOCKS5 flow обязан работать без sing-box. +- React UI не пишет generated config напрямую. UI вызывает typed Tauri commands. +- `src/api/tauriCommands.ts` — единственная TypeScript-обертка над `invoke(...)`. +- Rust backend отвечает за storage, validation, config generation, component detection, service/install orchestration и structured errors. +- `C:\ProgramData\ProxyWarden\config` и `C:\ProgramData\ProxyWarden\state` — source of truth. +- `C:\ProgramData\ProxyWarden\generated\proxifyre-app-config.json` и `sing-box-config.json` — derived artifacts. Их можно пересоздавать. +- Install/start/stop/uninstall — только явные действия пользователя. `apply` не должен скрыто устанавливать, удалять или «чинить» компоненты. +- Subscription URL, credentials, proxy passwords и userinfo нельзя выводить полностью в UI, logs, diagnostics, crash text или activity. +- Summary panel должен оставаться read-only: без install/start/stop/apply/delete/input/subscription mutations. +- Любые elevated операции должны быть максимально явными и проверяемыми. + +## Основная структура + +```text +src/ + api/tauriCommands.ts # typed invoke facade + app/App.tsx # текущая UI orchestration зона, слишком крупная + app/readiness.ts # apply gating logic + app/viewModel.ts # display/view helpers + domain/types.ts # TypeScript DTO mirror + ui/* # reusable presentational components + styles/app.css # основной CSS + +src-tauri/ + tauri.conf.json # Tauri config, security, window config + capabilities/default.json # Tauri permissions/capabilities + src/models.rs # Rust domain models/defaults + src/validation.rs # normalization/validation + src/storage.rs # JSON storage, tmp/bak writes + src/activity.rs # activity log + src/subscription.rs # subscription fetch/parse + src/component_detection.rs # ProxiFyre/sing-box detection + src/singbox_service.rs # sing-box Windows service logic + src/process.rs # process/system helpers + src/helper.rs # helper/elevation boundary + src/adapters/* # ProxiFyre/sing-box/proxy-router adapters + src/commands.rs # Tauri command handlers; currently too large + tests/* # Rust integration/domain tests + +scripts/ + install-control-app.ps1 + install-proxyfier.ps1 + install-singbox.ps1 + prepare-release.ps1 +``` + +## Агентские skill-модули + +Подробные инструкции лежат в `.agent/skills`: + +- `.agent/skills/repository-orientation/SKILL.md` — как быстро понять репозиторий. +- `.agent/skills/rust-tauri-backend/SKILL.md` — Rust/Tauri backend changes. +- `.agent/skills/react-typescript-ui/SKILL.md` — frontend/UI changes. +- `.agent/skills/security-hardening/SKILL.md` — CSP, секреты, temp files, storage, SSRF, elevated boundary. +- `.agent/skills/windows-services-powershell/SKILL.md` — Windows service/install/PowerShell изменения. +- `.agent/skills/subscriptions-routing/SKILL.md` — subscription, sing-box, ProxiFyre routing. +- `.agent/skills/testing-ci-release/SKILL.md` — проверки, CI, release hygiene. +- `.agent/skills/communication-reporting/SKILL.md` — короткие понятные планы, ревью и отчеты с таблицами файлов. + +Перед сложным изменением прочитать релевантный skill. Перед любым нетривиальным ответом владельцу проекта — прочитать `communication-reporting`. Да, инструкция про то, как не писать кашу, теперь тоже инструкция. Так мы и живем. + +## Стиль общения агента + +Пользователь — разработчик, но ему не нужен роман о каждом `match`, `useState` и переименованном импорте. Писать надо как для человека, которому нужно быстро принять решение: что изменилось, где изменилось, зачем и что проверить. + +Перед любым нетривиальным ответом прочитать `.agent/skills/communication-reporting/SKILL.md` и перед финальным сообщением пройти `.agent/checklists/communication.md`. + +### Обязательные правила + +- Сначала результат, потом детали. +- Короткие абзацы, списки и таблицы вместо полотна текста. +- Для нетривиальных изменений использовать таблицу `Файл / Что изменилось / Зачем`. +- Не объяснять каждую строку. Объяснять важные места, решения, риски и поведение. +- Технические термины использовать только когда они помогают. Сложный термин объяснять одной простой фразой. +- Проверки делить на выполненные, не выполненные и требующие Windows/manual check. +- Для ревью группировать находки по приоритетам: `Критично`, `Важно`, `Можно потом`, `Косметика`. +- Не писать корпоративный туман вроде «улучшена архитектура» без указания, что именно стало проще, безопаснее или понятнее. +- Не заявлять “всё проверено”, если Rust tests, Windows service flow, Tauri build или UAC сценарии не запускались. + +### Минимальный формат финального ответа + +```md +## Коротко + +- 1-3 главных результата. + +## Файлы + +| Файл | Что изменилось | Зачем | +|---|---|---| +| `path/file` | простое описание | практическая причина | + +## Проверки + +| Проверка | Статус | Комментарий | +|---|---|---| +| `command` | выполнено / не выполнено | почему | + +## Риски + +- Что осталось проверить или почему риска нет. +``` + +Если задача маленькая, формат можно сжать до нескольких строк. Если задача security/service/storage/routing-sensitive, детали обязательны, потому что «ну вроде работает» — это не инженерный метод, а жанр народного фольклора. -## Структура -- `src/app/App.tsx` - основная React-оркестрация, вкладки `Сводка`, `ProxiFyre`, `VPN / Прокси`, вызовы Tauri-команд и transient UI state. -- `src/app/readiness.ts` - gating применимости маршрута. Не обходить его локальными проверками в JSX. -- `src/app/viewModel.ts` - маленькие display/view-model helpers. -- `src/ui/*` - общие presentational-компоненты. Для новых кнопок, вкладок, service rows, pills, полей и лог-дока сначала расширять эти компоненты. -- `src/api/tauriCommands.ts` - единственная TypeScript-обертка над `invoke(...)`; держать DTO в синхронизации с Rust. -- `src/domain/types.ts` - TypeScript-зеркало доменных DTO. -- `src-tauri/src/models.rs` - Rust-модели и default values. -- `src-tauri/src/validation.rs` - нормализация входов. -- `src-tauri/src/storage.rs` и `activity.rs` - JSON storage, backup/tmp writes, activity cap/sort. -- `src-tauri/src/adapters/proxy_router.rs` - adapter boundary для proxy-router. -- `src-tauri/src/adapters/proxifyre.rs` - первый adapter, генерирует ProxiFyre `app-config.json`. -- `src-tauri/src/adapters/singbox.rs` - генерация локального `sing-box` конфига из subscription cache и выбранного сервера. -- `src-tauri/src/component_detection.rs` - detection ProxiFyre/Proxifier/Local sing-box. -- `src-tauri/src/commands.rs` - Tauri command handlers, installer/service orchestration, structured errors. -- `src-tauri/src/main.rs` - реальная Tauri entrypoint-регистрация команд. -- `src-tauri/src/lib.rs` сейчас scaffold/stale; не считать его источником регистрации команд без отдельной cleanup-задачи. -- `scripts/*.ps1` - явные installer entrypoints. `-PlanOnly` должен возвращать structured JSON без side effects. ## Правила изменений -- Не создавать второй источник правды для профилей, targets, components, subscription или activity. -- Не писать generated config напрямую из React. -- Не парсить raw PowerShell/stdout в UI. Backend/helper boundary должен возвращать structured JSON/error DTO. -- Не привязывать UI напрямую к деталям ProxiFyre, если изменение относится к общему proxy-router поведению. -- Не делать Local sing-box обязательным для external target. -- Для service/install операций сохранять UAC/admin boundary и человекочитаемые ошибки. -- При удалении install folders сохранять safe-path checks; не ослаблять рекурсивное удаление. -- В UI держать стиль компактной Windows-утилиты, а не landing/dashboard. Использовать existing `Button`, `Tabs`, `ServiceControlRow`, `StatusPill`, `Field`, `ActionMenu`, `LogDock`. -- Всплывающие подсказки при наведении делать быстрыми, кастомными и читаемыми: темная compact-плашка с мягкой рамкой/тенью, появление ~120ms, без нативного browser `title` как основного UI. Для иконок расширять общий `IconButton`/tooltip-паттерн, а не дублировать JSX/CSS локально. -- Apply actions должны быть disabled с объяснением, когда нет приложений, ProxiFyre отсутствует, proxy input неверный или local route не готов. -- Не оставлять dev-серверы (`npm run dev`, `npm run tauri -- dev`, preview-серверы) запущенными после проверки. Если сервер был поднят агентом, остановить его перед финальным ответом. +### Backend -## Проверка +- Не добавлять новую Tauri command без typed wrapper в `src/api/tauriCommands.ts` и соответствующего TypeScript DTO в `src/domain/types.ts`, если command используется UI. +- Не возвращать raw strings для сложных ошибок. Использовать structured error DTO: `code`, `message`, `details`. +- Тяжелые или блокирующие операции должны быть `async` command + `tauri::async_runtime::spawn_blocking`. +- Не вызывать network/process/service/file-heavy logic прямо из async runtime thread. +- Не использовать `unwrap()`/`expect()` в production path, кроме очевидно невозможных bootstrap cases с комментарием. +- Не писать generated configs неатомарно. Использовать temp + backup + rename where practical. +- Не расширять `commands.rs` без необходимости. Для новой логики предпочитать отдельные модули и thin command wrapper. -Минимум для frontend/UI: +### Frontend + +- Не увеличивать `App.tsx`, если можно вынести hook/helper/component. +- Не вызывать `invoke(...)` напрямую вне `src/api/tauriCommands.ts`. +- Не дублировать apply-readiness проверки в JSX. Расширять `src/app/readiness.ts`. +- Для UI использовать существующие компоненты из `src/ui`. +- Apply/start/install/delete buttons должны иметь disabled state и понятную причину. +- Не показывать secrets. Для subscription/proxy URL использовать redacted display values. +- UI должен оставаться compact Windows utility, а не SaaS dashboard с иллюзией корпоративной важности. + +### Security + +- Не отключать CSP. Если CSP мешает, исправлять source policy, а не ставить `csp: null`. +- Не добавлять Tauri shell permissions без жесткого scope и отдельного обоснования. +- Не запускать произвольные команды из UI input. +- Runtime-generated elevated scripts должны использовать непредсказуемые имена, safe directory/ACL и cleanup best-effort. +- Удаление директорий допускается только после safe-path/marker/service-path checks. +- Subscription fetch должен иметь timeout и защиту от очевидно опасных/local metadata адресов либо explicit allow-mode. + +### Windows/service boundary + +- `-PlanOnly` у PowerShell scripts должен оставаться side-effect-free и возвращать structured JSON. +- Install/start/stop/uninstall должны быть явными user actions. +- Fuzzy-detected service не считать managed service без проверки `PathName`/metadata. +- В Linux/macOS CI не пытаться «проверить» Windows service operations как реальные. Тестировать pure logic/mocks. + +## Известный технический долг + +- `src-tauri/src/commands.rs` слишком большой. Главная цель рефакторинга: разрезать на модули по use-case. +- `src/app/App.tsx` слишком большой. Главная цель frontend-рефакторинга: hooks/components/view-model helpers. +- `tauri.conf.json` сейчас требует security review, особенно CSP и window resize settings. +- JSON storage молча возвращает default при invalid JSON. Нужен corruption recovery через `.bak` и user-visible warning. +- ProxiFyre config apply должен стать atomic. +- Subscription URL redaction должен исключать userinfo/password. +- Link subscription parser сейчас ориентирован на VLESS; не обещать больше, чем реально поддерживается. +- Ping/select по server tag может ломаться при duplicate tags. Нужен stable server id. + +## Минимальная проверка перед ответом + +Для docs-only изменений достаточно проверить структуру файлов и отсутствие очевидных Markdown/JSON ошибок. + +Для frontend изменений: ```powershell +npm ci npm run build ``` -Rust/backend: +Для Rust/backend изменений: ```powershell -cd D:\repos\ProxyWarden\src-tauri -cargo test +cd src-tauri +cargo fmt --all -- --check +cargo clippy --all-targets --all-features -- -D warnings +cargo test --all-targets ``` -Tauri/toolchain: +Для Tauri/toolchain: ```powershell npm run tauri -- info @@ -74,7 +200,7 @@ npm run tauri -- dev npm run tauri -- build ``` -Installer boundaries: +Для installer boundaries: ```powershell & .\scripts\install-control-app.ps1 -PlanOnly @@ -82,10 +208,25 @@ Installer boundaries: & .\scripts\install-singbox.ps1 -PlanOnly ``` -Для UI-изменений проверять browser-preview на desktop и narrow viewport. Browser-preview не доказывает native Tauri commands или elevated service lane. +Не оставлять dev/preview/Tauri dev servers запущенными после проверки. -## Известные риски +## Формат отчета агента -- Реальные elevated install/start/stop/uninstall операции для ProxiFyre и Local sing-box считаются `implemented but unproven`, пока они не проверены на Windows с UAC/admin confirmation. -- Исторические planning/evidence файлы лежат в ignored `docs`-папках и не должны попадать в коммиты. -- Старые документы могут ссылаться на `apps/windows-client`; текущая структура репозитория - standalone client в корне. +Использовать один из шаблонов: + +- `.agent/templates/work-plan.md` — короткий план перед работой. +- `.agent/templates/change-report.md` — отчет после изменения кода. +- `.agent/templates/investigation-report.md` — аудит, расследование, разбор проблемы. +- `.agent/templates/user-facing-summary.md` — краткая сводка для владельца проекта. +- `.agent/templates/pr-description.md` — описание PR. + +Каждый нетривиальный ответ должен отвечать на вопросы: + +1. Что поменялось или найдено? +2. В каких файлах? +3. Зачем это нужно? +4. Что проверено? +5. Что не проверено? +6. Где остался риск? + +Не писать «всё готово», если Windows/elevated/service flow не проверялся на Windows. Эта фраза и так слишком много навредила миру. diff --git a/docs/agent/ARCHITECTURE-NOTES.md b/docs/agent/ARCHITECTURE-NOTES.md new file mode 100644 index 0000000..4a9ac29 --- /dev/null +++ b/docs/agent/ARCHITECTURE-NOTES.md @@ -0,0 +1,60 @@ +# ProxyWarden Architecture Notes for Agents + +## Current design + +ProxyWarden is a local Windows control app. It does not proxy traffic by itself. It orchestrates: + +1. ProxiFyre for per-app routing. +2. Optional local sing-box for subscription-based outbound routing. +3. External SOCKS5 target for direct proxy routing. + +## Route modes + +External SOCKS5: + +```text +selected Windows apps -> ProxiFyre -> external SOCKS5 +``` + +Local sing-box: + +```text +selected Windows apps -> ProxiFyre -> 127.0.0.1:1080 -> sing-box selected outbound +``` + +## Main risks + +- Large orchestration files: `commands.rs` and `App.tsx`. +- Security-sensitive elevated operations. +- Secrets in subscription/proxy config. +- Non-atomic writes to generated configs. +- Stale component status. +- Duplicate sing-box server tags. +- UI/business logic entanglement. + +## Desired direction + +Backend: + +- Thin Tauri command handlers. +- Use-case modules. +- Testable pure functions. +- Structured errors. +- Atomic writes and hardened temp/elevation handling. + +Frontend: + +- Smaller `App.tsx`. +- Extracted hooks/components. +- Typed API boundary. +- Testable readiness/snapshot/proxy parsing logic. +- Clear UX for pending changes and service state. + +Security: + +- CSP enabled. +- Minimal Tauri capabilities. +- No broad shell permission. +- Redacted secrets. +- Safe deletion. +- Explicit Windows service control.