Expand local_machine docs and automation for connectivity, games, and ops.
Add proxy/VPN/telegram launchd and emergency runbooks; reorganize apps docs; document JA3 CrossOver runbook and Wine troubleshooting; add GOG/HoMM game scripts, disk cleanup guides, and gitea push-via-proxy helper. Ignore temp/. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
164
docs/apps/anytype/README.md
Normal file
164
docs/apps/anytype/README.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Anytype (macOS) — чёрный экран после загрузки, пустое окно
|
||||
|
||||
> **Проверенный кейс (2026-04):** интерфейс успевает показать контент, затем окно уходит в чёрный/пустой экран.
|
||||
> **Что сработало:** обновление клиента до актуальной стабильной версии через Homebrew Cask; данные в `~/Library/Application Support/anytype/data/` не трогались.
|
||||
|
||||
**Связано:** безопасная очистка кэшей и структура каталогов — [ANYTYPE_WORKSPACE_FIX.md](../../disk_cleanup/ANYTYPE_WORKSPACE_FIX.md). Официально про графику — [Troubleshooting (Anytype Docs)](https://doc.anytype.io/anytype-docs/advanced/troubleshooting).
|
||||
|
||||
---
|
||||
|
||||
## Содержание
|
||||
|
||||
1. [Симптомы](#1-симптомы)
|
||||
2. [Диагностика](#2-диагностика)
|
||||
3. [Что нельзя удалять (данные)](#3-что-нельзя-удалять-данные)
|
||||
4. [Шаг 1 (опционально): только кэши UI](#4-шаг-1-опционально-только-кэши-ui)
|
||||
5. [Шаг 2 (основной): обновить приложение](#5-шаг-2-основной-обновить-приложение)
|
||||
6. [Если после обновления снова IncompatibleVersion](#6-если-после-обновления-снова-incompatibleversion)
|
||||
7. [Сброс профиля Electron с сохранением vault](#7-сброс-профиля-electron-с-сохранением-vault)
|
||||
8. [Ссылки](#8-ссылки)
|
||||
|
||||
---
|
||||
|
||||
## 1. Симптомы
|
||||
|
||||
- Окно Anytype **сначала отрисовывается**, затем **чёрный или пустой** экран.
|
||||
- Несколько окон / фон / сон Mac — иногда усугубляют (Electron), но **не всегда** являются первопричиной.
|
||||
- В логах ядра при работе с сетью возможны ошибки **`IncompatibleVersion`** (несовпадение версии клиента с ожиданиями координации Anytype).
|
||||
|
||||
---
|
||||
|
||||
## 2. Диагностика
|
||||
|
||||
### Версия установленного приложения
|
||||
|
||||
```bash
|
||||
/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' /Applications/Anytype.app/Contents/Info.plist
|
||||
```
|
||||
|
||||
### Логи клиента (Electron)
|
||||
|
||||
```bash
|
||||
tail -n 200 "$HOME/Library/Application Support/anytype/logs/log.log"
|
||||
```
|
||||
|
||||
### Логи middleware («сердце» / синхронизация)
|
||||
|
||||
```bash
|
||||
grep -n 'IncompatibleVersion' "$HOME/Library/Application Support/anytype/common/logs/anytype.log" | tail -20
|
||||
```
|
||||
|
||||
Если **`IncompatibleVersion`** повторяется на свежем запуске — в первую очередь **обновите клиент** до версии не старше рекомендуемой сетью (стабильный cask Homebrew обычно достаточен).
|
||||
|
||||
### Место на диске
|
||||
|
||||
Переполненный том ломает **автообновление** (обрыв загрузки, checksum mismatch, `ENOSPC` в логах). Перед установкой DMG/ZIP оставьте запас свободного места на томе с `/Users` (ориентир: не держать системный том постоянно **>~95%** занятым).
|
||||
|
||||
---
|
||||
|
||||
## 3. Что нельзя удалять (данные)
|
||||
|
||||
Локальный vault и ключи лежат под:
|
||||
|
||||
```text
|
||||
~/Library/Application Support/anytype/data/
|
||||
```
|
||||
|
||||
Внутри каталога аккаунта — как минимум `localstore`, `spaceStoreNew`, `objectstore`, `config.json`, `device.key` и т.д. Подробная схема — в [ANYTYPE_WORKSPACE_FIX.md](../../disk_cleanup/ANYTYPE_WORKSPACE_FIX.md).
|
||||
|
||||
**Страховка перед любыми действиями:**
|
||||
|
||||
```bash
|
||||
mkdir -p "$HOME/Desktop/anytype-backups"
|
||||
cp -a "$HOME/Library/Application Support/anytype/data" \
|
||||
"$HOME/Desktop/anytype-backups/data-$(date +%Y%m%d_%H%M%S)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Шаг 1 (опционально): только кэши UI
|
||||
|
||||
Пока Anytype **полностью закрыт** (`Anytype` → Quit или `killall Anytype`), можно удалить **только** кэши Chromium/Electron — **не** трогая `data/`. Готовый набор команд — в [ANYTYPE_WORKSPACE_FIX.md § Безопасная очистка](../../disk_cleanup/ANYTYPE_WORKSPACE_FIX.md#-безопасная-очистка-кэша-anytype).
|
||||
|
||||
Официальная подсказка для графики (Linux-путь в доке; на macOS аналог — те же папки под `Application Support/anytype`): удалить **`GPUCache`** — см. [Troubleshooting](https://doc.anytype.io/anytype-docs/advanced/troubleshooting).
|
||||
|
||||
---
|
||||
|
||||
## 5. Шаг 2 (основной): обновить приложение
|
||||
|
||||
Рекомендуемый способ на macOS — **Homebrew Cask** (версия совпадает с тем, что проверяет сообщество; URL — официальный CDN Anytype в формуле cask).
|
||||
|
||||
### 5.1. Закрыть приложение
|
||||
|
||||
```bash
|
||||
killall Anytype 2>/dev/null || true
|
||||
sleep 1
|
||||
```
|
||||
|
||||
### 5.2. Установка / обновление
|
||||
|
||||
```bash
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install --cask anytype
|
||||
```
|
||||
|
||||
Если Brew сообщает, что **`Anytype.app` уже есть в `/Applications`** и установка **прерывается**, старое приложение нужно **убрать из пути** (переименовать — безопасно, это не данные):
|
||||
|
||||
```bash
|
||||
killall Anytype 2>/dev/null || true
|
||||
sleep 1
|
||||
ts=$(date +%Y%m%d_%H%M%S)
|
||||
mv /Applications/Anytype.app "/Applications/Anytype.app.backup-$ts"
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install --cask anytype
|
||||
```
|
||||
|
||||
Проверка версии:
|
||||
|
||||
```bash
|
||||
/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' /Applications/Anytype.app/Contents/Info.plist
|
||||
```
|
||||
|
||||
Запуск:
|
||||
|
||||
```bash
|
||||
open -a Anytype
|
||||
```
|
||||
|
||||
После проверки резервную копию `Anytype.app.backup-*` можно удалить.
|
||||
|
||||
**Важно:** установка/замена **`.app`** не удаляет `~/Library/Application Support/anytype/data/` — локальные пространства и объекты сохраняются.
|
||||
|
||||
---
|
||||
|
||||
## 6. Если после обновления снова IncompatibleVersion
|
||||
|
||||
1. Убедиться, что действительно запускается **новый** бинарь (версия в Info.plist, один экземпляр в `/Applications`).
|
||||
2. Освободить место на диске и повторить обновление.
|
||||
3. При необходимости поставить более свежую ветку (**alpha**), если она доступна отдельным cask и не конфликтует со стабильным (см. `brew search anytype` и описание cask’ов).
|
||||
|
||||
---
|
||||
|
||||
## 7. Сброс профиля Electron с сохранением vault
|
||||
|
||||
Если обновление **помогло по версии**, но UI всё ещё «ломается», можно пересоздать кэш/Local Storage **всего каталога поддержки**, оставив только `data/` (как и раньше — **сначала полная копия** `data/` в безопасное место).
|
||||
|
||||
Пока Anytype **закрыт**:
|
||||
|
||||
```bash
|
||||
killall Anytype 2>/dev/null || true
|
||||
BASE="$HOME/Library/Application Support/anytype"
|
||||
cp -a "$BASE/data" "$HOME/Desktop/anytype-backups/data-manual-$(date +%Y%m%d_%H%M%S)"
|
||||
mv "$BASE" "${BASE}_profile_backup_$(date +%Y%m%d_%H%M%S)"
|
||||
mkdir -p "$BASE"
|
||||
mv "${BASE}_profile_backup_"*/data "$BASE/"
|
||||
open -a Anytype
|
||||
```
|
||||
|
||||
Не удаляйте каталог `*_profile_backup_*`, пока не убедитесь, что приложение снова стабильно открывается.
|
||||
|
||||
---
|
||||
|
||||
## 8. Ссылки
|
||||
|
||||
- [Anytype — Troubleshooting](https://doc.anytype.io/anytype-docs/advanced/troubleshooting)
|
||||
- [anytype-ts releases (GitHub)](https://github.com/anyproto/anytype-ts/releases)
|
||||
- [Homebrew Cask `anytype`](https://formulae.brew.sh/cask/anytype)
|
||||
225
docs/apps/cursor/README.md
Normal file
225
docs/apps/cursor/README.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Cursor IDE — работа из РФ и обход PING timeout
|
||||
|
||||
> **Проблема:** из России Cursor показывает `PING timed out`, Agent не отвечает.
|
||||
> **Временный обход:** Disable Http2 в настройках — помогает, но всё сильно замедляется.
|
||||
> **Рекомендуемое решение:** SOCKS-прокси через SSH-туннель на сервер с нормальным доступом (DO / RU VPS), без отключения HTTP/2.
|
||||
|
||||
**Связанные гайды:** [PROXY_GUIDE.md](../connectivity/PROXY_GUIDE.md), [BUILD_AAB_FROM_RUSSIA_GUIDE.md](../connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md) — тот же паттерн «туннель через прокси-сервер». **Выход через DO (как VPN на 209.38.32.21):** [docs/connectivity/vpn/README.md](../connectivity/vpn/README.md). **Windows:** [WINDOWS_CURSOR_TUNNEL.md](../connectivity/WINDOWS_CURSOR_TUNNEL.md) и скрипт `scripts/cursor-socks-tunnel.ps1`.
|
||||
|
||||
---
|
||||
|
||||
## Содержание
|
||||
|
||||
1. [Симптомы и причина](#-симптомы-и-причина)
|
||||
2. [Обход 1: Disable Http2 (простой, но медленный)](#-обход-1-disable-http2-простой-но-медленный)
|
||||
3. [Обход 2: SOCKS через SSH-туннель (рекомендуется)](#-обход-2-socks-через-ssh-туннель-рекомендуется)
|
||||
4. [Проверка и диагностика](#-проверка-и-диагностика)
|
||||
5. [Troubleshooting](#-troubleshooting)
|
||||
6. [Ссылки](#-ссылки)
|
||||
|
||||
---
|
||||
|
||||
## Симптомы и причина
|
||||
|
||||
### Что видно в Cursor
|
||||
|
||||
- В чате с Agent: **Request ID: … [unavailable] PING timed out**, `_he: [unavailable] PING timed out`.
|
||||
- Стек указывает на `workbench.desktop.main.js`, `streamFromAgentBackend` / `getAgentStreamResponse` — обрыв связи с бэкендом агента.
|
||||
|
||||
### Почему так происходит
|
||||
|
||||
1. **HTTP/2 и маршрутизация**
|
||||
Cursor использует HTTP/2 для стриминга к `*.cursor.sh` (в т.ч. `agent.api5.cursor.sh`). В части сетей (в т.ч. из РФ) запросы уходят в CDN (например Cloudflare) с неудачной конфигурацией SSL/HTTP2 или блокировкой по DPI, из‑за чего соединение обрывается или уходит в таймаут.
|
||||
|
||||
2. **Disable Http2**
|
||||
Отключение HTTP/2 переводит трафик на HTTP/1.1 и часто убирает обрывы, но увеличивает нагрузку и задержки — «всё становится медленным», возможны дополнительные таймауты агента.
|
||||
|
||||
3. **Идея нормального обхода**
|
||||
Пропускать только трафик Cursor через сервер с хорошим доступом к Cursor API (VPS в DO, РФ и т.п.). До этого сервера — SSH (обычно не режется). От сервера до `*.cursor.sh` — уже «нормальный» канал, HTTP/2 работает без костылей.
|
||||
|
||||
---
|
||||
|
||||
## Обход 1: Disable Http2 (простой, но медленный)
|
||||
|
||||
Если нужно быстро восстановить работу без настройки туннеля:
|
||||
|
||||
1. **Cursor → Settings** (Cmd+, / Ctrl+,).
|
||||
2. Поиск: **HTTP**.
|
||||
3. Включить **Cursor > General: Disable Http2**.
|
||||
|
||||
Минус: выше задержки и нагрузка, возможны таймауты агента при длинных ответах. Для постоянной работы из РФ предпочтительно [Обход 2](#-обход-2-socks-через-ssh-туннель-рекомендуется).
|
||||
|
||||
---
|
||||
|
||||
## Обход 2: SOCKS через SSH-туннель (рекомендуется)
|
||||
|
||||
Трафик Cursor идёт в интернет через ваш VPS. До VPS — SSH (один порт), с VPS — обычный доступ к Cursor API, HTTP/2 остаётся включённым.
|
||||
|
||||
### Схема
|
||||
|
||||
```
|
||||
Cursor → SOCKS 127.0.0.1:10809 → SSH → RU hsites-ahau → DO 209.38.32.21
|
||||
↓
|
||||
HTTPS/HTTP2 → *.cursor.sh
|
||||
```
|
||||
|
||||
При **`CURSOR_SOCKS_VIA_DO=1`** (по умолчанию) — **только** цепочка **Mac → RU → DO** (`telegram-socks-via-do`). Если **`hsites-ahau`** недоступен, скрипт **завершается с ошибкой** (прямой Mac→DO для SOCKS не поднимается). Публичный IP снаружи — **DO** (шаблон `Host telegram-socks-via-do` в [PROXY_GUIDE.md](../connectivity/PROXY_GUIDE.md)).
|
||||
|
||||
На стороне DO не нужен отдельный прокси-сервис — только SSH и те же `Host`, что для Telegram.
|
||||
|
||||
### Предположения
|
||||
|
||||
- В **`~/.ssh/config`** задан **`telegram-socks-via-do`** с **`ProxyJump hsites-ahau`** (шаблон в [PROXY_GUIDE.md](../connectivity/PROXY_GUIDE.md)).
|
||||
- Локально свободен порт **10809** (не путать с **1081** для Telegram).
|
||||
|
||||
### Шаг 1: Поднять SOCKS-туннель
|
||||
|
||||
Рекомендуется скрипт (выход через DO по умолчанию):
|
||||
|
||||
```bash
|
||||
./docs/cursor/scripts/cursor-socks-tunnel.sh start
|
||||
```
|
||||
|
||||
Переменные: **`CURSOR_SOCKS_PORT`** (по умолчанию 10809), **`CURSOR_SOCKS_VIA_DO=0`** — только RU (`CURSOR_TUNNEL_HOST`, по умолчанию `hsites-ahau`).
|
||||
|
||||
Вручную (выход с DO, как у скрипта):
|
||||
|
||||
```bash
|
||||
pkill -f "ssh.*-D 10809" 2>/dev/null
|
||||
ssh -D 10809 -f -N -o ServerAliveInterval=60 -o ServerAliveCountMax=4 telegram-socks-via-do
|
||||
```
|
||||
|
||||
Только RU (без DO в цепочке выхода):
|
||||
|
||||
```bash
|
||||
CURSOR_SOCKS_VIA_DO=0 ./docs/cursor/scripts/cursor-socks-tunnel.sh start
|
||||
# или: ssh -D 10809 -f -N hsites-ahau
|
||||
```
|
||||
|
||||
Проверка: туннель держится, пока сессия не разорвана; см. [Проверка и диагностика](#-проверка-и-диагностика).
|
||||
|
||||
### Шаг 2: Настроить Cursor на использование SOCKS
|
||||
|
||||
1. **Cursor → Settings** (Cmd+, / Ctrl+,), поиск: **proxy**.
|
||||
2. Заполнить:
|
||||
- **Http: Proxy** — `socks5://127.0.0.1:10809`
|
||||
- **Http: Proxy Strict SSL** — при необходимости отключить только если заведомо знаете, что за прокси (для одного своего VPS обычно не требуется).
|
||||
|
||||
Или в `settings.json` (Cursor: Open User Settings (JSON)):
|
||||
|
||||
```json
|
||||
{
|
||||
"http.proxy": "socks5://127.0.0.1:10809",
|
||||
"https.proxy": "socks5://127.0.0.1:10809"
|
||||
}
|
||||
```
|
||||
|
||||
### Шаг 3: Не отключать HTTP/2
|
||||
|
||||
**Cursor > General: Disable Http2** — выключить (оставить HTTP/2 включённым). Трафик к Cursor API идёт с DO (или с RU, если включён только RU-туннель).
|
||||
|
||||
### Шаг 4: Запуск Cursor при уже поднятом туннеле
|
||||
|
||||
Порядок каждый раз:
|
||||
|
||||
1. В терминале: `./docs/cursor/scripts/cursor-socks-tunnel.sh start` (или ручная команда из шага 1).
|
||||
2. Запуск Cursor как обычно.
|
||||
|
||||
Чтобы не забывать туннель, можно завести скрипт запуска (см. [Скрипт запуска с туннелем](#скрипт-запуска-с-туннелем)).
|
||||
|
||||
---
|
||||
|
||||
## Проверка и диагностика
|
||||
|
||||
### Туннель поднят
|
||||
|
||||
```bash
|
||||
# Должен слушать 10809
|
||||
lsof -i :10809
|
||||
# или
|
||||
nc -z 127.0.0.1 10809 && echo "OK"
|
||||
```
|
||||
|
||||
### Доступ к Cursor API через SOCKS (curl)
|
||||
|
||||
```bash
|
||||
curl -x socks5h://127.0.0.1:10809 -sI https://agent.api5.cursor.sh 2>&1 | head -5
|
||||
```
|
||||
|
||||
Успех: в ответе есть HTTP/2 или заголовки от сервера. Ошибка соединения или таймаут — туннель не работает или порт занят.
|
||||
|
||||
### Логи Cursor
|
||||
|
||||
При проблемах с подключением:
|
||||
|
||||
- **macOS:** `~/Library/Application Support/Cursor/logs/main.log`
|
||||
- Искать по `ERROR`, `PING`, `timeout`, `HTTP2`, `ECONNREFUSED`, `ETIMEDOUT`.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### После включения прокси Cursor вообще не подключается
|
||||
|
||||
- Убедиться, что туннель запущен: `lsof -i :10809`.
|
||||
- Проверить доступ через SOCKS: `curl -x socks5h://127.0.0.1:10809 -sI https://agent.api5.cursor.sh`.
|
||||
- Временно в настройках Cursor убрать `http.proxy` / `https.proxy` и проверить без прокси (например, с Disable Http2) — если так работает, проблема в туннеле или порте.
|
||||
|
||||
### PING timed out остаётся даже через прокси
|
||||
|
||||
- Перезапустить туннель и Cursor (полностью закрыть приложение и открыть снова).
|
||||
- В настройках Cursor убедиться, что **Disable Http2** выключен (HTTP/2 включён).
|
||||
- Проверить, что в настройках указан именно `socks5://127.0.0.1:10809` (без опечаток, порт совпадает с `-D 10809`).
|
||||
|
||||
### Порт 10809 занят
|
||||
|
||||
Выбрать другой порт, например 10810:
|
||||
|
||||
```bash
|
||||
ssh -D 10810 -f -N hsites-ahau
|
||||
```
|
||||
|
||||
И в настройках Cursor указать `socks5://127.0.0.1:10810`.
|
||||
|
||||
### Туннель рвётся при долгой неактивности
|
||||
|
||||
Поддерживать соединение помогут опции SSH:
|
||||
|
||||
```bash
|
||||
ssh -D 10809 -f -N -o ServerAliveInterval=30 -o ServerAliveCountMax=6 hsites-ahau
|
||||
```
|
||||
|
||||
При необходимости можно вынести эту команду в скрипт или systemd/supervisor на стороне клиента.
|
||||
|
||||
---
|
||||
|
||||
## Скрипт запуска туннеля
|
||||
|
||||
В репозитории есть скрипт для поднятия/остановки SOCKS-туннеля:
|
||||
|
||||
```bash
|
||||
# Из корня репо
|
||||
./docs/cursor/scripts/cursor-socks-tunnel.sh start # поднять туннель
|
||||
./docs/cursor/scripts/cursor-socks-tunnel.sh status # проверить
|
||||
./docs/cursor/scripts/cursor-socks-tunnel.sh stop # остановить
|
||||
```
|
||||
|
||||
Переменные окружения: `CURSOR_SOCKS_PORT` (10809), **`CURSOR_SOCKS_VIA_DO`** (по умолчанию **1** — выход через DO), при **`CURSOR_SOCKS_VIA_DO=0`** — `CURSOR_TUNNEL_HOST` (по умолчанию `hsites-ahau`).
|
||||
|
||||
**Запуск Cursor после туннеля (macOS):** после `./docs/cursor/scripts/cursor-socks-tunnel.sh start` откройте Cursor как обычно; при настроенных `http.proxy`/`https.proxy` трафик пойдёт через SOCKS.
|
||||
|
||||
---
|
||||
|
||||
## Ссылки
|
||||
|
||||
| Документ | Назначение |
|
||||
|----------|------------|
|
||||
| [PROXY_GUIDE.md](../connectivity/PROXY_GUIDE.md) | Прокси ru.hunab.app, SSH ProxyCommand для scp/ssh на прод |
|
||||
| [WINDOWS_CURSOR_TUNNEL.md](../connectivity/WINDOWS_CURSOR_TUNNEL.md) | Cursor из РФ на **Windows**: туннель, скрипт .ps1, автозапуск |
|
||||
| [BUILD_AAB_FROM_RUSSIA_GUIDE.md](../connectivity/BUILD_AAB_FROM_RUSSIA_GUIDE.md) | Сборка AAB из РФ через Maven proxy + SSH-туннель |
|
||||
| [Cursor Forum — HTTP/2 network error](https://forum.cursor.com/t/http2-network-error-with-cursor-ide-and-cursor-cli/147318) | Обсуждение ошибок HTTP/2 и региональной маршрутизации |
|
||||
| [Cursor Forum — Agent timeouts when HTTP2 disabled](https://forum.cursor.com/t/agent-timeouts-much-more-when-http2-disabled/76517) | Таймауты агента при отключённом HTTP/2 |
|
||||
|
||||
---
|
||||
|
||||
*Последнее обновление: 2026-04-08*
|
||||
107
docs/apps/cursor/scripts/cursor-socks-tunnel.ps1
Normal file
107
docs/apps/cursor/scripts/cursor-socks-tunnel.ps1
Normal file
@@ -0,0 +1,107 @@
|
||||
# SOCKS5-туннель для Cursor (обход PING timeout из РФ).
|
||||
# Использование: .\cursor-socks-tunnel.ps1 [start|stop|status]
|
||||
# См. docs/cursor/README.md и docs/connectivity/WINDOWS_CURSOR_TUNNEL.md
|
||||
|
||||
param(
|
||||
[Parameter(Position = 0)]
|
||||
[ValidateSet("start", "stop", "status")]
|
||||
[string]$Command = "start"
|
||||
)
|
||||
|
||||
$CURSOR_SOCKS_PORT = if ($env:CURSOR_SOCKS_PORT) { $env:CURSOR_SOCKS_PORT } else { "10809" }
|
||||
$SSH_HOST = if ($env:CURSOR_TUNNEL_HOST) { $env:CURSOR_TUNNEL_HOST } else { "ahau@149.154.64.19" }
|
||||
$CursorViaDo = ($env:CURSOR_SOCKS_VIA_DO -ne "0")
|
||||
|
||||
function Test-PortListening {
|
||||
$conn = Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue
|
||||
return $null -ne $conn
|
||||
}
|
||||
|
||||
function Get-SshTunnelPids {
|
||||
# Найти процессы ssh.exe, у которых в командной строке есть -D и наш порт
|
||||
Get-CimInstance Win32_Process -Filter "Name = 'ssh.exe'" -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.CommandLine -match "-D\s+$CURSOR_SOCKS_PORT" } |
|
||||
ForEach-Object { $_.ProcessId }
|
||||
}
|
||||
|
||||
function Start-Tunnel {
|
||||
if (Test-PortListening) {
|
||||
Write-Host "SOCKS already listening on 127.0.0.1:$CURSOR_SOCKS_PORT"
|
||||
return
|
||||
}
|
||||
$targetHost = $SSH_HOST
|
||||
$stableOpts = @(
|
||||
"-o", "TCPKeepAlive=yes",
|
||||
"-o", "IPQoS=throughput",
|
||||
"-o", "ServerAliveInterval=60",
|
||||
"-o", "ServerAliveCountMax=4"
|
||||
)
|
||||
$ruOpts = @(
|
||||
"-o", "ServerAliveInterval=30",
|
||||
"-o", "ServerAliveCountMax=6"
|
||||
)
|
||||
if ($CursorViaDo) {
|
||||
& ssh -o BatchMode=yes -o ConnectTimeout=6 -o ConnectionAttempts=1 hsites-ahau "exit 0" 2>$null
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "hsites-ahau недоступен: SOCKS только по цепочке Mac→RU→DO (без прямого Mac→DO). Восстановите SSH до RU или задайте CURSOR_SOCKS_VIA_DO=0."
|
||||
exit 1
|
||||
}
|
||||
$targetHost = "telegram-socks-via-do"
|
||||
}
|
||||
$sshArgs = @(
|
||||
"-D", $CURSOR_SOCKS_PORT,
|
||||
"-f", "-N"
|
||||
)
|
||||
if ($CursorViaDo) {
|
||||
$sshArgs += $stableOpts
|
||||
} else {
|
||||
$sshArgs += $ruOpts
|
||||
}
|
||||
$sshArgs += $targetHost
|
||||
& ssh @sshArgs
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
if ($CursorViaDo) {
|
||||
Write-Host "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $targetHost (DO exit)"
|
||||
} else {
|
||||
Write-Host "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $targetHost (RU exit, CURSOR_SOCKS_VIA_DO=0)"
|
||||
}
|
||||
} else {
|
||||
Write-Error "Failed to start tunnel (exit code $LASTEXITCODE). Check SSH config (telegram-socks-via-do) or host: $targetHost"
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
}
|
||||
|
||||
function Stop-Tunnel {
|
||||
$pids = Get-SshTunnelPids
|
||||
if ($pids) {
|
||||
foreach ($pid in $pids) {
|
||||
Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
Write-Host "Tunnel stopped (killed SSH process(es): $($pids -join ', '))."
|
||||
} else {
|
||||
# Fallback: убить процесс, занимающий порт 10809
|
||||
$conn = Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue
|
||||
if ($conn) {
|
||||
$conn | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }
|
||||
Write-Host "Tunnel stopped (killed process on port $CURSOR_SOCKS_PORT)."
|
||||
} else {
|
||||
Write-Host "No SOCKS tunnel found on port $CURSOR_SOCKS_PORT."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-Status {
|
||||
if (Test-PortListening) {
|
||||
Write-Host "SOCKS listening on 127.0.0.1:$CURSOR_SOCKS_PORT"
|
||||
Get-NetTCPConnection -LocalPort $CURSOR_SOCKS_PORT -State Listen -ErrorAction SilentlyContinue |
|
||||
Format-Table LocalAddress, LocalPort, State, OwningProcess -AutoSize
|
||||
} else {
|
||||
Write-Host "No SOCKS listener on port $CURSOR_SOCKS_PORT"
|
||||
}
|
||||
}
|
||||
|
||||
switch ($Command) {
|
||||
"start" { Start-Tunnel }
|
||||
"stop" { Stop-Tunnel }
|
||||
"status" { Get-Status }
|
||||
}
|
||||
45
docs/apps/cursor/scripts/cursor-socks-tunnel.sh
Executable file
45
docs/apps/cursor/scripts/cursor-socks-tunnel.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# Поднимает SOCKS5-туннель для Cursor (обход PING timeout из РФ).
|
||||
# Использование: ./cursor-socks-tunnel.sh [start|stop|status]
|
||||
# См. docs/cursor/README.md
|
||||
|
||||
set -e
|
||||
CURSOR_SOCKS_PORT="${CURSOR_SOCKS_PORT:-10809}"
|
||||
SSH_HOST="${CURSOR_TUNNEL_HOST:-hsites-ahau}"
|
||||
|
||||
start() {
|
||||
if lsof -i :"$CURSOR_SOCKS_PORT" -sTCP:LISTEN -t >/dev/null 2>&1; then
|
||||
echo "SOCKS already listening on 127.0.0.1:$CURSOR_SOCKS_PORT"
|
||||
return 0
|
||||
fi
|
||||
ssh -D "$CURSOR_SOCKS_PORT" -f -N \
|
||||
-o ServerAliveInterval=30 \
|
||||
-o ServerAliveCountMax=6 \
|
||||
"$SSH_HOST"
|
||||
echo "SOCKS tunnel started: 127.0.0.1:$CURSOR_SOCKS_PORT -> $SSH_HOST"
|
||||
}
|
||||
|
||||
stop() {
|
||||
pkill -f "ssh.*-D $CURSOR_SOCKS_PORT.*$SSH_HOST" 2>/dev/null || true
|
||||
echo "Tunnel stopped (if it was running)."
|
||||
}
|
||||
|
||||
status() {
|
||||
if lsof -i :"$CURSOR_SOCKS_PORT" -sTCP:LISTEN -t >/dev/null 2>&1; then
|
||||
echo "SOCKS listening on 127.0.0.1:$CURSOR_SOCKS_PORT"
|
||||
lsof -i :"$CURSOR_SOCKS_PORT" -sTCP:LISTEN
|
||||
else
|
||||
echo "No SOCKS listener on port $CURSOR_SOCKS_PORT"
|
||||
fi
|
||||
}
|
||||
|
||||
case "${1:-start}" in
|
||||
start) start ;;
|
||||
stop) stop ;;
|
||||
status) status ;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status}"
|
||||
echo "Env: CURSOR_SOCKS_PORT=$CURSOR_SOCKS_PORT, CURSOR_TUNNEL_HOST=$SSH_HOST"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
48
docs/apps/launch/ALLOWED.md
Normal file
48
docs/apps/launch/ALLOWED.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Допустимые объекты автозапуска (Launch Agents/Daemons)
|
||||
|
||||
Список того, что **допустимо** оставлять в автозапуске. Всё, чего нет в этом списке, при необходимости можно отключить.
|
||||
|
||||
---
|
||||
|
||||
## Пользовательские LaunchAgents (`~/Library/LaunchAgents`)
|
||||
|
||||
| ID | Назначение |
|
||||
|----|------------|
|
||||
| `com.google.GoogleUpdater.wake` | Обновления Google (Chrome и др.) |
|
||||
| `com.google.keystone.agent` | Служба обновлений Google |
|
||||
| `com.google.keystone.xpcservice` | Служба обновлений Google (XPC) |
|
||||
| `com.infoprotector.NetCacheCleaner` | Очистка кэша (NetCacheCleaner) |
|
||||
| `com.qiuyuzhou.shadowsocksX-NG.local` | ShadowsocksX-NG (прокси) |
|
||||
| `com.shadowsocks.local` | Shadowsocks |
|
||||
| `homebrew.mxcl.syncthing` | Syncthing (синхронизация файлов) |
|
||||
| `yanue.v2rayu.v2ray-core` | V2RayU (прокси) |
|
||||
|
||||
---
|
||||
|
||||
## Системные LaunchAgents (`/Library/LaunchAgents`)
|
||||
|
||||
| ID | Назначение |
|
||||
|----|------------|
|
||||
| `at.obdev.littlesnitch.agent` | Little Snitch (сетевой файрвол) |
|
||||
| `com.google.keystone.agent` | Обновления Google |
|
||||
| `com.google.keystone.xpcservice` | Обновления Google (XPC) |
|
||||
| `com.malwarebytes.mbam.frontend.agent` | Malwarebytes |
|
||||
|
||||
---
|
||||
|
||||
## Системные LaunchDaemons (`/Library/LaunchDaemons`)
|
||||
|
||||
| ID | Назначение |
|
||||
|----|------------|
|
||||
| `at.obdev.littlesnitch.daemon` | Little Snitch (демон) |
|
||||
| `com.google.GoogleUpdater.wake.system` | Обновления Google (системный) |
|
||||
| `com.google.keystone.daemon` | Обновления Google (демон) |
|
||||
| `com.malwarebytes.mbam.rtprotection.daemon` | Malwarebytes (защита в реальном времени) |
|
||||
| `com.malwarebytes.mbam.settings.daemon` | Malwarebytes (настройки) |
|
||||
| `com.metacubex.ClashX.ProxyConfigHelper` | ClashX (прокси) |
|
||||
| `com.objective-see.blockblock` | BlockBlock (мониторинг автозапуска) |
|
||||
| `com.wireguard.wg-ru` | WireGuard (VPN) |
|
||||
|
||||
---
|
||||
|
||||
Список **запрещённых** (отключённых) пунктов — см. [DISALLOWED.md](./DISALLOWED.md).
|
||||
65
docs/apps/launch/DISALLOWED.md
Normal file
65
docs/apps/launch/DISALLOWED.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Запрещённые объекты автозапуска (Launch Agents/Daemons)
|
||||
|
||||
Список того, что **не должно** запускаться при старте. Эти пункты отключены (plist переименованы в `.disabled`). При появлении снова — отключать.
|
||||
|
||||
---
|
||||
|
||||
## Объекты входа (Login Items) — отключить
|
||||
|
||||
| Приложение | Действие |
|
||||
|------------|----------|
|
||||
| **Notion** | Запустить скрипт ниже или: Системные настройки → Основные → Объекты входа → убрать Notion |
|
||||
| **MEGA (MEGAsync)** | То же: скрипт или Объекты входа → убрать MEGA |
|
||||
|
||||
**Скрипт (запускать в Terminal.app, не в Cursor):**
|
||||
```bash
|
||||
/Users/eternal/code/local_machine/docs/launch/disable_login_items_notion_mega.sh
|
||||
```
|
||||
При первом запуске может понадобиться: Системные настройки → Конфиденциальность и безопасность → Доступ к управлению компьютером — включить для **Terminal**.
|
||||
|
||||
MEGA также отключён как LaunchAgent (`mega.mac.megaupdater.plist.disabled`). Если снова автозапускается — проверить Объекты входа.
|
||||
|
||||
---
|
||||
|
||||
## Пользовательские LaunchAgents (`~/Library/LaunchAgents`)
|
||||
|
||||
| ID | Назначение |
|
||||
|----|------------|
|
||||
| `homebrew.mxcl.postgresql@15` | PostgreSQL 15 — запускать вручную при необходимости |
|
||||
| `homebrew.mxcl.redis` | Redis — запускать вручную при необходимости |
|
||||
| `mega.mac.megaupdater` | MEGA (обновления) |
|
||||
| `org.freedownloadmanager.fdm6` | Free Download Manager |
|
||||
| `org.virtualbox.vboxwebsrv` | VirtualBox Web Service |
|
||||
|
||||
---
|
||||
|
||||
## Системные LaunchAgents (`/Library/LaunchAgents`)
|
||||
|
||||
| ID | Назначение |
|
||||
|----|------------|
|
||||
| `com.philandro.anydesk.Frontend` | AnyDesk (удалённый доступ) |
|
||||
| `us.zoom.updater` | Zoom (проверка обновлений) |
|
||||
| `us.zoom.updater.login.check` | Zoom (проверка при входе) |
|
||||
|
||||
---
|
||||
|
||||
## Системные LaunchDaemons (`/Library/LaunchDaemons`)
|
||||
|
||||
| ID | Назначение |
|
||||
|----|------------|
|
||||
| `jp.co.canon.MasterInstaller` | Canon (драйверы/утилиты) |
|
||||
| `us.zoom.ZoomDaemon` | Zoom (демон) |
|
||||
|
||||
---
|
||||
|
||||
## Как отключить, если снова появятся
|
||||
|
||||
- **Объекты входа (Notion, MEGA и др.):**
|
||||
**Системные настройки → Основные → Объекты входа** — удалить приложение из списка или выключить переключатель.
|
||||
|
||||
- **Пользовательские LaunchAgents:**
|
||||
`launchctl unload ~/Library/LaunchAgents/<ID>.plist`
|
||||
затем переименовать plist в `<ID>.plist.disabled`.
|
||||
|
||||
- **Системные:**
|
||||
запустить `./docs/launch/disable_system_launch_items.sh` с правами root (`sudo`).
|
||||
18
docs/apps/launch/disable_login_items_notion_mega.sh
Executable file
18
docs/apps/launch/disable_login_items_notion_mega.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
# Удаляет Notion и MEGA (MEGAsync) из «Объекты входа».
|
||||
# Запустить в Terminal.app (не в Cursor): ./disable_login_items_notion_mega.sh
|
||||
# При первом запуске: Системные настройки → Конфиденциальность и безопасность → Доступ к управлению компьютером — включить для Terminal.
|
||||
|
||||
osascript << 'APPLESCRIPT'
|
||||
tell application "System Events"
|
||||
set loginItems to get the name of every login item
|
||||
set toRemove to {"Notion", "MEGAsync", "MEGA"}
|
||||
repeat with appName in toRemove
|
||||
if loginItems contains appName then
|
||||
delete login item appName
|
||||
log "Removed from Login Items: " & appName
|
||||
end if
|
||||
end repeat
|
||||
end tell
|
||||
APPLESCRIPT
|
||||
echo "Done. Notion and MEGA removed from Login Items (if they were there)."
|
||||
25
docs/apps/launch/disable_system_launch_items.sh
Executable file
25
docs/apps/launch/disable_system_launch_items.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
# Отключает системные LaunchAgents/LaunchDaemons (требуется sudo).
|
||||
# Запуск: sudo ./disable_system_launch_items.sh
|
||||
|
||||
set -e
|
||||
|
||||
LA="/Library/LaunchAgents"
|
||||
LD="/Library/LaunchDaemons"
|
||||
|
||||
unload_and_rename() {
|
||||
local path="$1"
|
||||
if [[ -f "$path" ]]; then
|
||||
launchctl unload "$path" 2>/dev/null || true
|
||||
mv "$path" "${path}.disabled"
|
||||
echo "Disabled: $path"
|
||||
fi
|
||||
}
|
||||
|
||||
unload_and_rename "$LA/com.philandro.anydesk.Frontend.plist"
|
||||
unload_and_rename "$LA/us.zoom.updater.plist"
|
||||
unload_and_rename "$LA/us.zoom.updater.login.check.plist"
|
||||
unload_and_rename "$LD/us.zoom.ZoomDaemon.plist"
|
||||
unload_and_rename "$LD/jp.co.canon.MasterInstaller.plist"
|
||||
|
||||
echo "Done."
|
||||
Reference in New Issue
Block a user