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:
ahauimix
2026-06-01 08:12:19 +03:00
parent a39ef89125
commit 1938b7c743
135 changed files with 9933 additions and 388 deletions

225
docs/apps/cursor/README.md Normal file
View 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*

View 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 }
}

View 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