Зачем
ACH Remote Sync связывает папку проекта в VS Code с папкой на сервере. Вы правите файлы локально, расширение отправляет их на сервер по SFTP, FTP или FTPS. Открываете файл, и расширение сверяет его с серверной копией. Если копии разные, сразу открывается сравнение.
Расширение задумано для работы прямо на сервере разработки, где крутится сборщик в режиме наблюдения, работает PHP или любой другой код. Главная задача: файл на сервере всегда совпадает с тем, что вы сохранили, и ни одна загрузка не портит данные молча.
Ключевые возможности
- Протоколы SFTP, FTP и FTPS. Для FTPS доступны оба режима TLS: явный (
AUTH TLS) и неявный. - Вход через SSH-агент, файл ключа (ed25519, RSA, ECDSA, в том числе зашифрованный), пароль или режим
auto. - Загрузка при сохранении файла. Три режима: выключено, всегда, только для файлов, которые уже есть на сервере.
- Сравнение с сервером при открытии файла. Совпадает: ничего не происходит. Различается: открывается сравнение и окно с выбором «Upload local» или «Download remote».
- Удаление на сервере вслед за локальным удалением. Режимы: выключено, с вопросом, всегда. Удаление папки расширение подтверждает всегда.
- Ручные команды Sync Up и Sync Down в палитре, в контекстном меню проводника и вкладки.
- Исключения в синтаксисе
.gitignore. Служебные папки (.git,.vscode,node_modulesи другие) исключены по умолчанию. - Строка состояния с текущим действием и числом операций в очереди. Значки состояния файлов в проводнике.
- Несколько папок рабочей области, у каждой свой сервер.
- Подробный журнал в панели Output. Пароли и парольные фразы в журнале скрыты.
Чем отличается
Запись на месте, без временного файла
Многие клиенты сначала пишут временный файл, потом удаляют старый и переименовывают новый. Вотчер сборки (webpack, vite, rollup) видит удаление, начинает пересборку и падает с ошибкой «Module not found». ACH Remote Sync открывает сам целевой файл на запись и перезаписывает его содержимое. Файл сохраняет inode, права и владельца. Вотчер видит одно событие изменения, и сборка идёт штатно.
Проверка размера после каждой загрузки
После записи расширение запрашивает у сервера размер файла и сравнивает его с локальным. Расхождение превращается в явную ошибку. Недописанный файл не останется на сервере незамеченным.
Отказ от нулевой перезаписи
Пустой локальный файл не затрёт непустой файл на сервере. Такая загрузка останавливается с понятной ошибкой. Так же работает скачивание: пустая серверная копия не затрёт ваш непустой локальный файл. Это защита от сбоя редактора, который иногда оставляет файл нулевой длины.
Сравнение при открытии
Вы открываете файл, и расширение в фоне скачивает его серверную копию и сравнивает по SHA-256. Сравнение открывается только при реальной разнице. Слева серверная версия, справа ваша. Ctrl+S в окне сравнения сохраняет локальный файл.
Безопасное скачивание и снимки
Sync Down скачивает файл во временный файл рядом, проверяет размер и только потом заменяет локальный. Перед заменой расширение сохраняет копию прежнего файла в .vscode/.ach-remote-sync-cache/. Для каждого файла хранятся три последние копии.
Автоподключение и повторы
Соединение открывается само при первой операции. Если связь оборвалась, расширение переподключается перед следующей операцией. Сетевые сбои (тайм-аут, сброс, отказ в соединении) повторяются до трёх попыток с растущей паузой. Ошибки входа и прав доступа расширение не повторяет и сразу показывает.
Одна загрузка на файл в каждый момент
Операции идут через общую очередь по одной. Если файл меняется, пока он отправляется, расширение дождётся конца загрузки и отправит итоговую версию один раз. Двойное уведомление об одном сохранении расширение распознаёт по времени изменения и размеру файла, поэтому повторная правка в ту же секунду не потеряется.
SSH-агент на Windows
Расширение само находит агент OpenSSH, встроенный в Windows, через канал \.pipeopenssh-ssh-agent. Если его нет, расширение обращается к Pageant. На macOS и Linux используется $SSH_AUTH_SOCK. Путь к агенту можно задать вручную.
Проверка ключа хоста
Расширение читает ~/.ssh/known_hosts, в том числе хэшированные записи. При первом подключении к новому серверу оно показывает отпечаток SHA-256 и предлагает доверять навсегда или один раз. Если ключ сервера сменился, подключение отклоняется. Отпечаток можно закрепить прямо в настройках.
Внешние изменения только по вашему выбору
По умолчанию на сервер уходят только сохранения из редактора. Файлы, которые изменили сборка, git или другой редактор, остаются локальными. Отправку внешних изменений включает отдельный параметр.
Файл настроек
Все настройки подключения лежат в файле .vscode/ach-remote-sync.json в корне папки проекта. Расширение запускается, когда видит этот файл в рабочей области. В файле можно писать комментарии // и /* … */.
Минимальный файл для SFTP через SSH-агент:
{
"protocol": "sftp",
"host": "example.com",
"username": "deploy",
"auth": { "type": "agent" },
"remotePath": "/var/www/example.com"
}
Расширение читает файл при запуске окна. После создания файла и после каждой правки выполните в палитре команду Developer: Reload Window. Без перезагрузки окна изменения в уже загруженном файле не применяются.
Если в файле ошибка, расширение покажет сообщение ACH Remote Sync — config error in <папка>: … с описанием. Неизвестные ключи расширение пропускает без ошибки. Опечатка в имени параметра значит, что параметр просто возьмёт значение по умолчанию. Сверяйте имена с таблицей ниже.
Сам файл настроек и вся папка .vscode исключены из синхронизации по умолчанию. Хост, логин и пароль на сервер не попадут.
Все параметры
| Параметр | Тип | По умолчанию | Что делает |
|---|---|---|---|
protocol |
строка | обязательный | Протокол: "sftp", "ftp" или "ftps". |
host |
строка | обязательный | Имя сервера или IP-адрес. |
port |
целое 1–65535 | 22 для sftp, 21 для ftp и ftps |
Порт сервера. Для неявного FTPS обычно нужен 990, его задают вручную. |
username |
строка | обязательный | Имя пользователя на сервере. |
auth |
объект | обязательный | Способ входа. Поле type обязательно: "agent", "key", "password" или "auto". Остальные поля зависят от типа, см. раздел «Аутентификация». |
remotePath |
строка | обязательный | Папка на сервере, которая соответствует корню проекта. Путь к серверному файлу получается так: remotePath плюс путь файла от корня проекта. Саму папку создайте на сервере заранее. |
localPath |
строка | корень папки рабочей области | Локальная папка, которая соответствует remotePath. Нужна, если синхронизировать надо только подпапку проекта. Указывайте абсолютный путь. Файлы вне этой папки расширение не трогает. |
strictHostKey |
логический | true |
Только SFTP. Политика для неизвестного ключа сервера в проверочных командах Smoke: true отклоняет подключение, false принимает его с предупреждением в журнале. В обычной работе неизвестный ключ всегда вызывает окно подтверждения, см. раздел «Ключ хоста». |
hostFingerprint |
строка | нет | Только SFTP. Ожидаемый отпечаток ключа сервера в формате SHA256:…. Префикс SHA256: можно не писать. Когда параметр задан, расширение не читает known_hosts и не показывает окон: совпал отпечаток, подключение идёт, не совпал, подключение отклоняется. |
knownHostsFile |
строка | ~/.ssh/known_hosts |
Только SFTP. Файл, из которого расширение читает известные ключи серверов. Поддерживаются хэшированные записи и записи вида [host]:port. |
keepaliveIntervalMs |
число, мс | 20000 |
Только SFTP. Интервал служебных пакетов, которые держат соединение живым. 0 отключает их. |
connectTimeoutMs |
число, мс | 15000 |
Только FTP и FTPS. Тайм-аут соединения с сервером. |
readyTimeoutMs |
число, мс | 20000 |
Только SFTP. Сколько ждать, пока соединение и SSH-рукопожатие завершатся. |
watch |
логический | true |
Главный выключатель автоматики. При false не работают загрузка при сохранении, удаление на сервере, сравнение при открытии и значок несохранённых изменений. Ручные команды работают. |
ignore |
массив строк | [] |
Шаблоны исключений в синтаксисе .gitignore. Добавляются к встроенному списку. См. раздел «Исключения». |
automation |
объект | см. ниже | Поведение при событиях редактора и диска. Четыре поля ниже. |
automation.uploadOnSave |
строка | "off" |
"off", "always" или "onlyExisting". Отправка файла на сервер при сохранении. |
automation.diffOnOpen |
строка | "always" |
"off" или "always". Сравнение с серверной копией при открытии файла. |
automation.deleteOnLocalDelete |
строка | "off" |
"off", "ask" или "always". Удаление на сервере вслед за локальным удалением. |
automation.watchExternalChanges |
логический | false |
Отправлять ли на сервер изменения, сделанные вне редактора: сборкой, git, терминалом, проводником. |
cleanOrphansOnConnect |
логический | false |
При каждом подключении искать в remotePath временные файлы .ach-tmp-* старше 24 часов и удалять их. Работает в фоне и уступает очередь вашим операциям. |
logLevel |
строка | "info" |
Подробность журнала: "debug", "info", "warn" или "error". Журнал общий для всех папок. Если папок несколько, действует самый подробный уровень. |
ftps.secure |
строка | "explicit" |
Только FTPS. "explicit": подключение на обычный порт и переход на TLS командой AUTH TLS. "implicit": TLS с первого байта, обычно порт 990. |
ftps.rejectUnauthorized |
логический | true |
Только FTPS. Отклонять сертификат сервера, который не прошёл проверку. false ставьте только для самоподписанного сертификата, который вы проверили сами. |
Протоколы
sftp. Передача файлов поверх SSH. Шифрование, вход по ключу или через агент, одно соединение на одном порту. Выбирайте его, если сервер это позволяет.ftps. FTP с шифрованием TLS. Вход только по паролю. Режим задаётftps.secure.ftp. FTP без шифрования. Пароль и содержимое файлов идут по сети открытым текстом. Используйте только в доверенной локальной сети.
Для FTP и FTPS расширение работает в пассивном режиме. Защита загрузки (запись на месте, проверка размера, отказ от нулевой перезаписи) одинакова для всех трёх протоколов.
Пример FTPS с явным TLS:
{
"protocol": "ftps",
"host": "ftp.example.com",
"port": 21,
"username": "deploy",
"auth": { "type": "password", "password": "••••" },
"remotePath": "/var/www/example.com",
"ftps": {
"secure": "explicit",
"rejectUnauthorized": true
}
}
Аутентификация
| Тип | Поля | Протоколы | Как работает |
|---|---|---|---|
agent |
agentPath (необязательно) |
SFTP | Ключ берётся из запущенного SSH-агента. Без agentPath расширение ищет агент само. |
key |
keyPath (обязательно), passphrase (необязательно) |
SFTP | Ключ читается из файла. Поддерживаются ed25519, RSA и ECDSA. Для зашифрованного ключа нужна passphrase. |
password |
password (обязательно) |
SFTP, FTP, FTPS | Вход по паролю. |
auto |
keyPath, passphrase, password (все необязательны) |
SFTP, FTP, FTPS | Для SFTP расширение передаёт серверу все доступные способы сразу: агент (если он найден), ключ из keyPath и пароль. Для FTP и FTPS используется только password. |
Для FTP и FTPS подходят только password и auto. С типами agent и key подключение завершится ошибкой CONFIG_INVALID.
Путь keyPath может начинаться с ~/, тогда он отсчитывается от домашней папки. Абсолютный путь берётся как есть. Относительный путь считается от рабочей папки процесса VS Code, поэтому его лучше не использовать.
Пароль и парольная фраза хранятся в файле настроек открытым текстом. Не добавляйте такой файл в репозиторий. Надёжнее держать ключ в агенте и указать "auth": { "type": "agent" }.
SSH-агент на Windows
Включите встроенную службу OpenSSH Agent и добавьте в неё ключ. Команды для PowerShell от имени администратора:
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
ssh-add -l
Последняя команда должна показать ключ. Расширение находит агент по каналу \\.\pipe\openssh-ssh-agent. Если этого канала нет, расширение обращается к Pageant.
Git Bash приносит свой ssh-add, который работает с другим агентом. Если ключ виден в Git Bash, а расширение его не находит, добавьте ключ из PowerShell командой C:\Windows\System32\OpenSSH\ssh-add.exe.
Pageant
Запустите Pageant и добавьте в него ключ .ppk через значок в трее. Укажите "auth": { "type": "agent" }. Расширение перейдёт на Pageant, если служба OpenSSH Agent не запущена.
SSH-агент на macOS
Агент в macOS уже запущен. Добавьте ключ и сохраните парольную фразу в связке ключей:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
SSH-агент на Linux
Расширение берёт адрес агента из переменной $SSH_AUTH_SOCK. Она должна быть задана в среде, из которой запущен VS Code. Обычно агент запускает графическая сессия (gnome-keyring, KWallet). Если агента нет, добавьте в ~/.bashrc или ~/.zshrc:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Свой путь к агенту
Параметр agentPath задаёт агент вручную: путь к сокету на macOS и Linux или имя канала на Windows.
"auth": { "type": "agent", "agentPath": "/run/user/1000/ssh-agent.socket" }
Ключ хоста и known_hosts
При подключении по SFTP расширение сверяет ключ сервера с файлом ~/.ssh/known_hosts или с файлом из knownHostsFile.
- Ключ найден и совпадает. Подключение идёт без вопросов.
- Ключа нет в файле. Появляется окно с именем сервера, алгоритмом и отпечатком
SHA256:…. Кнопка «Trust Permanently» дописывает ключ в~/.ssh/known_hosts. Кнопка «Trust Once» доверяет ключу только в этом подключении, при следующем окно появится снова. Отмена прерывает подключение. - Для сервера в файле записан другой ключ. Подключение отклоняется, в журнале появляется строка
HOST KEY MISMATCH for <host>:<port>. Refusing to connect.
Перед тем как нажать «Trust Permanently», сверьте отпечаток с администратором сервера. Узнать отпечаток можно так:
ssh-keyscan -t ed25519 example.com | ssh-keygen -lf -
Кнопка «Trust Permanently» всегда пишет в ~/.ssh/known_hosts, даже если задан knownHostsFile. Если вы используете свой файл, перенесите запись в него вручную.
Для серверов, у которых ключ меняется при каждом развёртывании, задайте hostFingerprint. Тогда known_hosts не используется.
Исключения
Параметр ignore принимает список шаблонов в синтаксисе .gitignore. Пути считаются от корня папки рабочей области, разделитель всегда /.
*.log: шаблон без косой черты совпадает на любой глубине./build: косая черта в начале привязывает шаблон к корню проекта.dist/: косая черта в конце означает только папку.wp-content/uploads/**: всё содержимое папки.**/coverage/**: папкаcoverageна любой глубине.!.vscode/launch.json: восклицательный знак возвращает файл, который исключён раньше.
Встроенный список действует всегда, ваши шаблоны добавляются после него:
.git
.git/**
.vscode/**
.claude/**
.idea/**
.cursor/**
node_modules
node_modules/**
.DS_Store
Thumbs.db
.ach-tmp-*
**/.ach-tmp-*
.ach-trash
.ach-trash/**
Исключения действуют на загрузку при сохранении, удаление на сервере, сравнение при открытии и значок несохранённых изменений. Ручные команды Sync Up и Sync Down работают с любым файлом, даже исключённым.
Пример для сайта на WordPress:
"ignore": [
"wp-content/uploads/**",
"wp-content/cache/**",
"*.log"
]
Автоматика
Все параметры автоматики по умолчанию безопасны: без вашей команды сервер не меняется. По умолчанию включено только сравнение при открытии. Оно лишь читает файлы с сервера. Параметр "watch": false выключает всю автоматику разом.
automation.uploadOnSave
| Значение | Поведение |
|---|---|
"off" |
Ничего не отправляется. Файлы отправляют командой Sync Up. |
"always" |
Каждое сохранение отправляется на сервер. Недостающие папки на сервере создаются. При включённом watchExternalChanges на сервере появляются и новые пустые папки. |
"onlyExisting" |
Сохранение отправляется, только если файл уже есть на сервере. Новые файлы остаются локальными, пока вы не отправите их командой Sync Up. |
automation.watchExternalChanges
| Значение | Поведение |
|---|---|
false |
На сервер уходят только сохранения из редактора VS Code. Изменения от сборки, git, терминала и других программ остаются локальными. |
true |
Любое изменение файла на диске уходит на сервер по правилам uploadOnSave. События одного файла объединяются за 75 мс. |
Этот параметр влияет только на загрузку. Без uploadOnSave он ничего не отправляет. Переключение ветки git при true отправит на сервер все изменённые файлы.
automation.diffOnOpen
| Значение | Поведение |
|---|---|
"off" |
Сравнения нет. |
"always" |
При открытии файла во вкладке расширение скачивает серверную копию и сравнивает. Подробности в разделе «Сравнение при открытии». |
automation.deleteOnLocalDelete
| Значение | Поведение |
|---|---|
"off" |
Сервер не трогается. |
"ask" |
Перед каждым удалением появляется окно с кнопкой «Delete». |
"always" |
Файлы удаляются на сервере без вопроса. Папки удаляются только после подтверждения кнопкой «Delete recursively», потому что удаление идёт со всем содержимым. |
Расширение замечает удаление в VS Code и вне его: в проводнике, в терминале, при git rm и при переключении ветки git. Параметр watchExternalChanges на удаление не влияет. Если на сервере файла уже нет, расширение ничего не делает.
Временные файлы
Ранние версии расширения писали на сервер временные файлы .ach-tmp-*. После сбоя такие файлы могли остаться. Текущая версия на сервер временных файлов не пишет. Убрать старые помогают два средства:
- команда
ACH Remote Sync: Clean Up Orphan Temp Files, запуск вручную; - параметр
"cleanOrphansOnConnect": true, проверка при каждом подключении.
Обход идёт по всей папке remotePath, поэтому на большом сайте занимает время. Папки .ach-trash от старых версий расширение не трогает, удалите их на сервере сами.
Несколько серверов
Один файл настроек описывает одно подключение. Профилей и переключения окружений внутри файла нет. Чтобы работать с несколькими серверами, откройте рабочую область из нескольких папок (multi-root) и положите в каждую свой .vscode/ach-remote-sync.json.
У каждой папки своё соединение, своя очередь и свой элемент в строке состояния. Команды Connect, Disconnect и Clean Up Orphan Temp Files спрашивают, с какой папкой работать. Sync Up и Sync Down выбирают папку по файлу.
Команды
Все команды доступны в палитре (Ctrl+Shift+P) с префиксом ACH Remote Sync:.
| Команда | Что делает |
|---|---|
ACH Remote Sync: Connect |
Подключается к серверу. Вызывать её не обязательно: любая операция подключается сама. |
ACH Remote Sync: Disconnect |
Закрывает соединение и сбрасывает запомненные сведения о сервере. |
ACH Remote Sync: Sync Up (current file) |
Отправляет на сервер открытый файл или файл, выбранный в контекстном меню. Создаёт недостающие папки на сервере. Работает с файлами, папку целиком не отправляет. |
ACH Remote Sync: Sync Down (current file) |
Скачивает серверную копию открытого или выбранного файла и заменяет локальный. Перед заменой сохраняет снимок локального файла. |
ACH Remote Sync: Cancel All Pending Operations |
Убирает из очереди все операции, которые ещё не начались, во всех папках. Текущая операция доводится до конца. |
ACH Remote Sync: Clean Up Orphan Temp Files |
Спрашивает минимальный возраст в часах (по умолчанию 24), обходит remotePath и удаляет файлы .ach-tmp-* старше этого возраста. Ход работы виден в уведомлении, там же её можно отменить. |
ACH Remote Sync: Show Log |
Открывает журнал в панели Output. |
ACH Remote Sync: Hello |
Показывает короткое сообщение, что расширение запущено. |
ACH Remote Sync: Smoke: Test Connection |
Подключается по профилю achRemoteSync.testProfile, читает список файлов в remotePath и отключается. Файлы не меняет. |
ACH Remote Sync: Smoke: Test Upload |
По профилю achRemoteSync.testProfile отправляет в remotePath маленький файл .ach-smoke-<время>.txt, проверяет размер и удаляет файл. |
ACH Remote Sync: Smoke: Test Session Queue |
По профилю achRemoteSync.testProfile ставит в очередь пять чтений папки и проверяет, что они выполнились по порядку. |
Команды Sync Up (current file) и Sync Down (current file) есть также в контекстном меню проводника и в контекстном меню заголовка вкладки.
Проверочный профиль
Команды Smoke работают без файла в проекте. Они берут настройки из пользовательского параметра achRemoteSync.testProfile. Это единственная настройка расширения в settings.json. Формат тот же, что у .vscode/ach-remote-sync.json:
"achRemoteSync.testProfile": {
"protocol": "sftp",
"host": "example.com",
"username": "deploy",
"auth": { "type": "agent" },
"remotePath": "/var/www/example.com"
}
Команды Smoke не показывают окно доверия ключу. Неизвестный ключ сервера они отклоняют при "strictHostKey": true и принимают при false.
Строка состояния
Для каждой настроенной папки справа в строке состояния есть свой элемент. Щелчок по нему открывает журнал.
| Текст | Вид | Значение |
|---|---|---|
ACH: idle |
значок вилки, жёлтый фон | Соединения нет. Оно откроется при первой операции. |
ACH: connecting to deploy@example.com… |
вращение, жёлтый фон | Идёт подключение. |
ACH: deploy@example.com |
галочка, зелёный текст | Соединение открыто, очередь пуста. |
ACH: auto-upload (3) |
вращение, зелёный текст | Идёт операция. Число в скобках показывает, сколько операций в работе, если их больше одной. |
ACH: error — … |
красный фон | Последняя операция завершилась ошибкой. Текст ошибки есть в журнале. Следующая успешная операция вернёт обычный вид. |
Названия операций в строке: sync up, sync down, auto-upload, auto-mkdir, auto-delete, diff-on-open, fetch remote, stat, cleanup orphans. После ручной загрузки или скачивания на несколько секунд появляется сообщение с именем файла, серверным путём и размером.
Значки в проводнике
| Значок | Цвет | Значение |
|---|---|---|
● |
жёлтый | Файл изменён в редакторе и ещё не отправлен. |
⬆ |
синий | Файл отправляется. |
✓ |
зелёный | Файл отправлен или совпадает с серверной копией. Значок исчезает через 3 секунды. |
! |
красный | Загрузка при сохранении не удалась. Текст ошибки виден во всплывающей подсказке. |
При "uploadOnSave": "always" значок проходит путь ●, ⬆, ✓ сам. В ручном режиме ● остаётся после сохранения и напоминает, что файл не отправлен. Расширение помнит хэш последней отправленной или скачанной версии. Если после сохранения содержимое совпадает с ней, значок сменится на ✓.
Сравнение при открытии
Когда вы открываете файл во вкладке, расширение в фоне скачивает его серверную копию и сравнивает содержимое по SHA-256.
- Копии совпадают. Ничего не происходит.
- Копии различаются. Открывается окно сравнения
Remote ↔ Local — <имя файла>. Слева серверная версия, только для чтения. Справа ваш локальный файл. - Файла на сервере нет. Ничего не происходит.
Вместе со сравнением появляется окно <имя> differs from remote. с размерами обеих версий и тремя вариантами:
- «Upload local» отправляет локальный файл на сервер и закрывает сравнение;
- «Download remote» заменяет локальный файл серверной копией, сохраняет снимок прежней версии и закрывает сравнение;
- отмена закрывает только окно. Сравнение остаётся открытым, его можно изучить и поправить вручную.
В правой части сравнения можно править текст. Ctrl+S сохраняет локальный файл. Текст окна упоминает резервную копию на сервере. Начиная с версии 2.0.11 расширение её не создаёт.
Ограничения:
- файлы больше 5 МБ не сравниваются;
- исключённые файлы не сравниваются;
- каждый файл сравнивается один раз, пока открыта его вкладка. Закройте и откройте вкладку, чтобы сравнить заново;
- после перезагрузки окна расширение проверяет все вкладки, которые остались открытыми.
Sync Up, Sync Down и снимки
Sync Up отправляет файл тем же способом, что и загрузка при сохранении:
- проверяет, что локальный файл существует;
- проверяет серверную копию. Если на сервере непустой файл, а локальный пустой, загрузка останавливается с ошибкой
TRANSFER_ZERO_BYTE_OVERWRITE; - создаёт недостающие папки на сервере;
- перезаписывает содержимое серверного файла на месте. Inode, права и владелец сохраняются;
- запрашивает размер файла на сервере. Расхождение даёт ошибку
TRANSFER_SIZE_MISMATCH.
Sync Down работает так:
- проверяет, что файл есть на сервере;
- отказывается заменять непустой локальный файл пустым серверным;
- скачивает файл во временный
.ach-tmp-…в той же папке и сверяет размер; - копирует прежний локальный файл в снимок;
- заменяет локальный файл скачанным.
Снимки лежат в папке .vscode/.ach-remote-sync-cache/. Для каждого файла там своя папка с тем же относительным путём, имя снимка состоит из имени файла и метки времени. Для каждого файла хранятся три последних снимка, старые удаляются. Команды восстановления нет: нужный снимок скопируйте на место файла вручную. Папка .vscode исключена из синхронизации, поэтому снимки на сервер не попадают.
Очередь, повторы и подключение
- Все операции одной папки идут через общую очередь по одной.
- Соединение открывается при первой операции и остаётся открытым.
- Если соединение оборвалось, расширение подключается заново перед следующей операцией.
- Сетевые сбои повторяются до трёх попыток. Пауза начинается с 0,5 секунды и растёт вдвое. Ошибки входа, прав доступа и проверки размера не повторяются.
- Если файл меняется во время его загрузки, расширение дождётся конца и отправит итоговую версию один раз.
- Команда Cancel All Pending Operations очищает очередь.
Журнал
Команда ACH Remote Sync: Show Log или щелчок по строке состояния открывает канал «ACH Remote Sync» в панели Output. В журнал попадают подключения, загрузки, ошибки и причины, по которым файл пропущен. При "logLevel": "debug" видна каждая операция очереди с временем выполнения. Пароли и парольные фразы в журнале заменяются на [redacted].
Типовые сценарии
Сервер разработки со сборкой в режиме наблюдения
На сервере работает webpack --watch или похожий сборщик. Вы правите исходники локально, сервер собирает их сам.
{
"protocol": "sftp",
"host": "example.com",
"username": "deploy",
"auth": { "type": "agent" },
"remotePath": "/var/www/example.com",
"automation": {
"uploadOnSave": "always",
"diffOnOpen": "always",
"deleteOnLocalDelete": "ask",
"watchExternalChanges": false
},
"ignore": [
"dist/**",
"*.log"
]
}
- Запись на месте даёт вотчеру одно событие изменения, сборка не видит пропавший файл.
node_modulesисключена по умолчанию, зависимости ставятся на сервере.- Папку с результатом сборки (здесь
dist) добавьте вignore. Тогда локальная сборка не затрёт серверную, а сравнение при открытии не будет срабатывать на собранных файлах. watchExternalChangesвыключен: файлы, которые меняет локальная сборка или git, на сервер не уходят.
Собираете локально и отправляете результат
Если сборка идёт на вашей машине и собранные файлы нужны на сервере, уберите папку сборки из ignore и включите "watchExternalChanges": true. Тогда на сервер уходит всё, что меняется на диске. Помните, что переключение ветки git тоже отправит изменённые файлы.
Ручной режим
Оставьте uploadOnSave и deleteOnLocalDelete в значении "off". Сравнение при открытии покажет расхождения, а файлы вы отправите командой Sync Up или кнопкой «Upload local». Жёлтый значок ● напомнит о неотправленных правках.
Сайт с пользовательскими файлами
Папки, куда пишет сам сайт, добавьте в ignore. Например wp-content/uploads/** и wp-content/cache/** для WordPress. Тогда расширение не будет их сравнивать и не удалит их на сервере.
Осторожно с удалением
При "deleteOnLocalDelete": "always" сервер повторяет любое локальное удаление, включая удаление при переключении ветки git. Для общего или боевого сервера выбирайте "ask".
Решение проблем
Начинайте с журнала: ACH Remote Sync: Show Log. Для подробностей поставьте "logLevel": "debug" и перезагрузите окно.
Расширение не реагирует на сохранение
- Проверьте
automation.uploadOnSave: по умолчанию стоит"off". - Проверьте, что
watchне равенfalse. - Проверьте, не попадает ли файл под
ignoreили встроенные исключения. В режимеdebugжурнал пишет строкуautoUpload[save]: … ignored. - При
"onlyExisting"новые файлы не отправляются, пока их нет на сервере. - После правки файла настроек перезагрузите окно.
«no workspace has .vscode/ach-remote-sync.json configured»
Расширение не нашло файл настроек. Проверьте, что файл лежит в .vscode в корне папки, открытой в VS Code, и перезагрузите окно.
«… is not inside a configured workspace»
Файл лежит вне папки проекта или вне папки из localPath.
AUTH_FAILED
Сервер отклонил вход. Проверьте username. Проверьте вход из терминала: ssh -v deploy@example.com. Убедитесь, что открытый ключ есть в ~/.ssh/authorized_keys на сервере, а агент предлагает нужный ключ (ssh-add -l).
AUTH_AGENT_UNAVAILABLE
Агент не найден. На Windows запустите службу ssh-agent или Pageant. На macOS и Linux проверьте, что $SSH_AUTH_SOCK задана в среде, из которой запущен VS Code.
AUTH_KEY_ENCRYPTED
Ключ зашифрован, а парольной фразы в настройках нет, или она неверна. Укажите passphrase или загрузите ключ в агент и перейдите на "type": "agent".
AUTH_KEY_INVALID
Файл ключа не найден, не читается или не распознан. Проверьте путь. На macOS и Linux у файла ключа должны быть права 600.
CONFIG_INVALID при подключении по FTP
Для FTP и FTPS подходят только "type": "password" и "type": "auto" с паролем.
Подключение отклонено, в журнале HOST KEY MISMATCH
Ключ сервера отличается от записанного в known_hosts. Это бывает после переустановки сервера и при атаке посредника. Уточните новый отпечаток у администратора. Если смена ключа законна, удалите старую запись и подключитесь снова:
ssh-keygen -R example.com
Для нестандартного порта: ssh-keygen -R "[example.com]:2222".
NETWORK_REFUSED, NETWORK_TIMEOUT, NETWORK_UNREACHABLE
NETWORK_REFUSED: сервер доступен, но на порту никто не слушает. Проверьтеportи что служба SSH или FTP запущена.NETWORK_TIMEOUT: сервер не ответил. Проверьте адрес, брандмауэр и VPN. Для медленного соединения увеличьтеreadyTimeoutMs(SFTP) илиconnectTimeoutMs(FTP).NETWORK_UNREACHABLE: имя сервера не найдено. Проверьтеhostили подключитесь по IP-адресу.
TRANSFER_ZERO_BYTE_OVERWRITE
Локальный файл пустой, а серверный нет. Расширение отказалось затирать серверную копию. Обычно это сбой редактора. Восстановите файл из локальной истории: правый щелчок по файлу в проводнике, раздел «Timeline». Если пустой файл нужен на самом деле, удалите серверный файл, затем отправьте локальный.
TRANSFER_SIZE_MISMATCH
После загрузки сервер сообщил другой размер. Частые причины: закончилось место на диске сервера или квота. Файл на сервере мог остаться недописанным. Освободите место и отправьте файл ещё раз.
Сравнение не открывается, хотя файлы разные
- Файл больше 5 МБ.
- Файл исключён через
ignore. diffOnOpenравен"off"илиwatchравенfalse.- Файла нет на сервере.
- Файл уже сравнивался в этой вкладке. Закройте вкладку и откройте снова.
- Соединение в ошибке. Откройте журнал щелчком по строке состояния.
Часть файлов не доехала после серии быстрых правок
Эта ошибка была в версиях до 2.0.14 и исправлена. Обновите расширение. На старой версии сохраните пропущенный файл ещё раз.
На сервере остались файлы .ach-tmp-* или папки .ach-trash
Их оставили старые версии. Файлы .ach-tmp-* удалит команда ACH Remote Sync: Clean Up Orphan Temp Files. Папки .ach-trash удалите на сервере вручную.
На сервере лежат файлы из .vscode или .claude
До версии 2.0.7 эти папки не были исключены и могли попасть на сервер. Сейчас они исключены, но уже отправленное расширение не удаляет. Удалите их на сервере вручную.
Требования
- Visual Studio Code 1.96 или новее. Подходят Windows, macOS и Linux.
- Сервер с доступом по SFTP (любой сервер с SSH), FTP или FTPS.
- Для входа по ключу через агент: запущенный SSH-агент с добавленным ключом. На Windows подходит встроенная служба OpenSSH Agent или Pageant.
Node.js ставить не нужно. Расширение собрано в один файл вместе со всеми библиотеками и работает на среде, которая уже встроена в VS Code. Внешние программы ssh и sftp расширение тоже не вызывает: протоколы реализованы внутри него.
Установка из файла .vsix
Скачайте файл ach-remote-sync-<версия>.vsix с этой страницы.
Через интерфейс VS Code
- Откройте панель расширений:
Ctrl+Shift+X, на macOSCmd+Shift+X. - Нажмите «…» в правом верхнем углу панели.
- Выберите «Install from VSIX…».
- Укажите скачанный файл.
- Если VS Code предложит перезагрузить окно, согласитесь.
Тот же пункт есть в палитре команд: Extensions: Install from VSIX….
Из командной строки
code --install-extension ach-remote-sync-2.0.15.vsix
Подставьте имя скачанного файла. Если команда code не найдена, на macOS выполните в палитре VS Code Shell Command: Install 'code' command in PATH. На Windows и Linux она обычно доступна после установки VS Code.
После установки расширение появится в списке под именем «ACH Remote Sync — SFTP/FTP for VS Code». Оно включается только в проектах, где есть файл .vscode/ach-remote-sync.json.
Первый конфиг
Создайте в корне проекта файл .vscode/ach-remote-sync.json:
{
"protocol": "sftp",
"host": "example.com",
"port": 22,
"username": "deploy",
"auth": { "type": "agent" },
"remotePath": "/var/www/example.com",
"automation": {
"uploadOnSave": "off",
"diffOnOpen": "always",
"deleteOnLocalDelete": "off"
}
}
remotePath: папка на сервере, которая соответствует корню проекта.auth: способ входа. Пример использует SSH-агент. Вход по файлу ключа или паролю описан на вкладке «Использование».automation: в примере автоматическая загрузка выключена. Включите"uploadOnSave": "always", когда убедитесь, что подключение и исключения настроены верно.
Сохраните файл и выполните в палитре Developer: Reload Window. Расширение читает настройки при запуске окна, поэтому перезагрузка нужна и после каждой правки файла.
Проверка подключения
- Посмотрите в строку состояния справа внизу. Там должен появиться элемент
ACH: idle. - Выполните в палитре
ACH Remote Sync: Connect. - При первом подключении по SFTP появится окно с отпечатком ключа сервера. Сверьте отпечаток и нажмите «Trust Permanently».
- В строке состояния появится
ACH: deploy@example.com, а в углу сообщение об успешном подключении. - Откройте любой файл проекта. Если он отличается от серверной копии, откроется сравнение.
- Щёлкните правой кнопкой по файлу в проводнике и выберите
ACH Remote Sync: Sync Up (current file). Внизу на несколько секунд появится сообщение с серверным путём и размером файла.
Если что-то пошло не так, выполните ACH Remote Sync: Show Log. Журнал покажет причину. Разбор частых ошибок есть на вкладке «Использование», раздел «Решение проблем».
Обновления
VS Code обновляет расширения автоматически только из маркетплейса. Расширение, установленное из файла, само не обновится. Новую версию ставят так же: скачайте свежий .vsix с этой страницы и установите его поверх старого через «Install from VSIX…» или code --install-extension. Настройки проектов сохранятся, они лежат в файлах .vscode/ach-remote-sync.json. История версий есть на вкладке «Изменения».
Переход со старого ach-sftp
Если у вас стоит прежнее расширение ACH SFTP, переходите так:
- Отключите ACH SFTP в панели расширений. Удалять его сразу не обязательно.
- Установите ACH Remote Sync из файла
.vsix. - Для каждого проекта создайте новый файл
.vscode/ach-remote-sync.json. Старый.vscode/ach-sftp.jsonновое расширение не читает. - Перезагрузите окно и проверьте подключение.
- Когда всё работает, удалите ACH SFTP.
Соответствие основных параметров:
| ach-sftp.json | ach-remote-sync.json |
|---|---|
"protocol", "host", "port", "username", "remotePath", "ignore" |
без изменений |
"agent": true |
"auth": { "type": "agent" } |
"privateKey": "~/.ssh/id" |
"auth": { "type": "key", "keyPath": "~/.ssh/id" } |
"password": "…" |
"auth": { "type": "password", "password": "…" } |
"keepaliveInterval" |
"keepaliveIntervalMs" |
"connectionTimeout" |
"connectTimeoutMs" |
"readyTimeout" |
"readyTimeoutMs" |
"autoUpload": true |
"automation": { "uploadOnSave": "always" } |
"autoDelete": true |
"automation": { "deleteOnLocalDelete": "always" } |
"autoDownload" |
замены нет. Вместо тихого скачивания работает сравнение "diffOnOpen": "always" |
"strictHostKey" |
"strictHostKey", логическое значение |
Параметры persistentConnection, passive, concurrency и fileNameEncoding больше не нужны. Соединение держится открытым, FTP работает в пассивном режиме, операции идут по одной, имена файлов передаются в UTF-8.
Оба расширения могут работать одновременно, но тогда автоматику включайте только в одном из них. Иначе каждое сохранение и удаление выполнится дважды.
Файлы старого расширения .vscode/ach-sftp.json, .vscode/ach-sftp.sync.cache.json и .vscode/ach-sftp.diff.* после перехода можно удалить.
-
v2.0.15 последняя
Изменено 2
- Автозагрузка теперь идёт по одному файлу за раз: пока файл загружается, новые правки копятся, и после загрузки уходит одна итоговая версия. Серия быстрых сохранений больше не порождает пачку лишних загрузок устаревшего содержимого.
- Если загрузка сорвалась или устарела, следом всегда уходит чистая загрузка последней версии файла — сервер приходит к тому же состоянию, что и локальная копия.