Эволюция по принуждению
Все видят обстановку, которая в настоящее время складывается в Российском интернет-сегменте. Я думаю, не стоит пересказывать все новости, которые и так через день мелькают абсолютно на всех информационных ресурсах. Лично я смотрю на ситуацию двояко: с одной стороны это полнейший хаос, с другой — технологическая перспектива. Хочу копнуть глубже и разобрать, как именно этот хаос заставляет технологии мутировать и к чему это нас готовит.
На первый взгляд ситуация носит исключительно негативный характер. Пользователей насильственно изолируют от зарубежных сервисов под предлогом безопасности. Ранее я уже разбирал ситуацию с MAX — там всё было прозрачнее: классическая монополизация и административный протекционизм с целью контроля.
Попытки навязать «импортозамещение» в сфере глобальных платформ обнажают глубокое непонимание природы современных сервисов. Ошибка здесь в том, что продукт (сервис) воспринимают лишь как набор строк кода и серверных мощностей, которые можно скопировать административным ресурсом. Однако вся ценность заключается именно в содержании — накопленном за долгие годы интеллектуальном капитале.
Именно здесь начинается самое интересное. Любое действие порождает противодействие. Когда привычные инструменты перестают работать, технологии начинают мутировать. Мы уходим от эпохи простых VPN-сервисов к эре сложной маскировки и мимикрии трафика. Если раньше связность была чем-то само собой разумеющимся, то сегодня она становится результатом инженерного творчества. Разработчики вынуждены проектировать системы, которые не просто работают, а умеют выживать в агрессивной среде.
Многие любят приводить параллели с КНДР, но это сравнение в корне ошибочно. Северная Корея строила свою сеть изолированной изначально — стерильный аквариум, который никогда не знал мирового океана. У нас же ситуация уникальна: мы пытаемся изолировать сформировавшийся организм, который десятилетиями прорастал в глобальную инфраструктуру миллионами связей. Это попытка хирургически вырезать фрагмент из единого целого. Сопротивление «организма» этому вмешательству заставляет технологии эволюционировать и мутировать.
Это и есть та самая перспектива, о которой я говорил выше: мы учимся строить архитектуру, которая по своей живучести на голову выше всего, что создавалось в среде «свободного» интернета.
Но главная мутация происходит не в коде, а в людях. Побочным, но мощным эффектом этой ситуации стал резкий скачок цифровой грамотности. Когда «одна кнопка» перестает работать, пользователю приходится брать ответственность за свой доступ в сеть на себя. Люди поднимают свои серверы, изучают работу протоколов и учатся находить нестандартные решения там, где раньше был тупик. Мы наблюдаем, как из потребителей контента пользователи превращаются в архитекторов собственной связности. И этот навык мыслить вопреки ограничениям — пожалуй, самый ценный актив, который останется с нами, как бы ни изменились правила игры.
@diominvdev
Все видят обстановку, которая в настоящее время складывается в Российском интернет-сегменте. Я думаю, не стоит пересказывать все новости, которые и так через день мелькают абсолютно на всех информационных ресурсах. Лично я смотрю на ситуацию двояко: с одной стороны это полнейший хаос, с другой — технологическая перспектива. Хочу копнуть глубже и разобрать, как именно этот хаос заставляет технологии мутировать и к чему это нас готовит.
На первый взгляд ситуация носит исключительно негативный характер. Пользователей насильственно изолируют от зарубежных сервисов под предлогом безопасности. Ранее я уже разбирал ситуацию с MAX — там всё было прозрачнее: классическая монополизация и административный протекционизм с целью контроля.
Попытки навязать «импортозамещение» в сфере глобальных платформ обнажают глубокое непонимание природы современных сервисов. Ошибка здесь в том, что продукт (сервис) воспринимают лишь как набор строк кода и серверных мощностей, которые можно скопировать административным ресурсом. Однако вся ценность заключается именно в содержании — накопленном за долгие годы интеллектуальном капитале.
Именно здесь начинается самое интересное. Любое действие порождает противодействие. Когда привычные инструменты перестают работать, технологии начинают мутировать. Мы уходим от эпохи простых VPN-сервисов к эре сложной маскировки и мимикрии трафика. Если раньше связность была чем-то само собой разумеющимся, то сегодня она становится результатом инженерного творчества. Разработчики вынуждены проектировать системы, которые не просто работают, а умеют выживать в агрессивной среде.
Многие любят приводить параллели с КНДР, но это сравнение в корне ошибочно. Северная Корея строила свою сеть изолированной изначально — стерильный аквариум, который никогда не знал мирового океана. У нас же ситуация уникальна: мы пытаемся изолировать сформировавшийся организм, который десятилетиями прорастал в глобальную инфраструктуру миллионами связей. Это попытка хирургически вырезать фрагмент из единого целого. Сопротивление «организма» этому вмешательству заставляет технологии эволюционировать и мутировать.
Это и есть та самая перспектива, о которой я говорил выше: мы учимся строить архитектуру, которая по своей живучести на голову выше всего, что создавалось в среде «свободного» интернета.
Но главная мутация происходит не в коде, а в людях. Побочным, но мощным эффектом этой ситуации стал резкий скачок цифровой грамотности. Когда «одна кнопка» перестает работать, пользователю приходится брать ответственность за свой доступ в сеть на себя. Люди поднимают свои серверы, изучают работу протоколов и учатся находить нестандартные решения там, где раньше был тупик. Мы наблюдаем, как из потребителей контента пользователи превращаются в архитекторов собственной связности. И этот навык мыслить вопреки ограничениям — пожалуй, самый ценный актив, который останется с нами, как бы ни изменились правила игры.
@diominvdev
👍2🔥2
Хочу немного актуализировать вектор канала. Главный вопрос: что для вас сейчас в приоритете — техническая база (гайды, софт, практика), разбор реальных кейсов (в том числе личных) или больше дискуссионных постов о том, куда всё катится?
Напишите пару слов о том, какой контент заставляет вас задерживаться на канале. Это поможет мне не писать «в пустоту».
@diominvdev
Напишите пару слов о том, какой контент заставляет вас задерживаться на канале. Это поможет мне не писать «в пустоту».
@diominvdev
❤4🔥1
В продолжение вчерашних мыслей о блокировках: рекомендую всегда держать под рукой несколько рабочих VPN-сервисов.
Один из таких — Krusofiya. Умеет обходить белые списки и отличается высокой стабильностью. Тот случай, когда качество софта полностью соответствует цене 👍
https://t.me/krusofiyabot?start=ref_348914384
@diominvdev
Один из таких — Krusofiya. Умеет обходить белые списки и отличается высокой стабильностью. Тот случай, когда качество софта полностью соответствует цене 👍
https://t.me/krusofiyabot?start=ref_348914384
@diominvdev
Telegram
Krusofiya VPN
Низкие цены и обход любых глушилок 💎
Сообщество: @krusofiyacom
ТГК: @krusofiyavpn
ТП: @krusofiya
Сообщество: @krusofiyacom
ТГК: @krusofiyavpn
ТП: @krusofiya
❤3🔥3
Наверное developer pinned «Хочу немного актуализировать вектор канала. Главный вопрос: что для вас сейчас в приоритете — техническая база (гайды, софт, практика), разбор реальных кейсов (в том числе личных) или больше дискуссионных постов о том, куда всё катится? Напишите пару слов…»
Костыль, который работает идеально
Поиск идеальной клавиатуры — это всегда компромисс. Я убедился, что оптимальный вариант «с завода» найти практически невозможно. В каждом случае будет то, что захочется поменять. И в какой-то момент понимаешь: чтобы получить инструмент, который не бесит, его нужно собрать самому.
Мой опыт работы на «механике» составляет около двух лет. За это время я перепробовал три «заводских» решения: Aula F75, Nuphy Air 75 V2, Dark Project CM81 Zeno. Как оказалось — каждая по своему хороша настолько, насколько имеет недостатки.
Из всего этого опыта и получился «Франкенштейн», которого вы видите на фото. Это осознанный гибрид, где каждая деталь отвечает за свой аспект комфорта:
• База: Корпус и «внутрянка» от Dark Project. Алюминиевый корпус создаёт чувство монолитности и веса.
• Эргономика: Кейкапы от низкопрофильной Nuphy с идельаным для меня форм-фактором.
• Тактильность: Мой фаворит — свитчи Keypro Kailh Box Jade. После слишком мягких заводских решений, эти кликающие переключатели ощущаются как печатная машинка. Громкий, четкий клик и ощутимое сопротивление.
Для кого-то некоторые решени покажутся странными — ставить низкопрофильные кепки на стандартную базу и втыкать туда кликающие свитчи. Но для меня это тот самый инструмент, который смог закрыть все мои потребности. В этом и есть смысл кастома: сделать так, как удобно тебе.
@diominvdev
Поиск идеальной клавиатуры — это всегда компромисс. Я убедился, что оптимальный вариант «с завода» найти практически невозможно. В каждом случае будет то, что захочется поменять. И в какой-то момент понимаешь: чтобы получить инструмент, который не бесит, его нужно собрать самому.
Мой опыт работы на «механике» составляет около двух лет. За это время я перепробовал три «заводских» решения: Aula F75, Nuphy Air 75 V2, Dark Project CM81 Zeno. Как оказалось — каждая по своему хороша настолько, насколько имеет недостатки.
Из всего этого опыта и получился «Франкенштейн», которого вы видите на фото. Это осознанный гибрид, где каждая деталь отвечает за свой аспект комфорта:
• База: Корпус и «внутрянка» от Dark Project. Алюминиевый корпус создаёт чувство монолитности и веса.
• Эргономика: Кейкапы от низкопрофильной Nuphy с идельаным для меня форм-фактором.
• Тактильность: Мой фаворит — свитчи Keypro Kailh Box Jade. После слишком мягких заводских решений, эти кликающие переключатели ощущаются как печатная машинка. Громкий, четкий клик и ощутимое сопротивление.
Для кого-то некоторые решени покажутся странными — ставить низкопрофильные кепки на стандартную базу и втыкать туда кликающие свитчи. Но для меня это тот самый инструмент, который смог закрыть все мои потребности. В этом и есть смысл кастома: сделать так, как удобно тебе.
Для особых ценителей в комментариях оставил запись со звуком тайпинга.
@diominvdev
🔥5👍4
Проект «loom»
Хочу поделиться идеей, которую я долго и мучительно вынашиваю в голове уже около полугода.
loom — self-hosted платформа, которая позволяет проектировать различные сценарии автоматизации через простой web-интерфейс. Главная проблема существующих решений в том, что они закрыты для «кастомизации» и вынуждают работать с готовым набором инструментов.
Уникальность loom заключается в языковой независимости. Модули для платформы могут быть написаны на любом языке и работать независимо от окружения хоста благодаря изолированному запуску через контейнеры.
Представим, что нужно автоматизировать простую, но специфичную задачу:
Решения вроде n8n могут просто не иметь в своем «арсенале» инструментов для работы с таким контроллером. Loom позволяет написать софт на подходящем языке, «обернуть» его в модуль и поделиться им через общую библиотеку с другими пользователями. Такой подход позволяет непроизвольно закрыть сразу два важных аспекта — безопасность софта (за счёт открытости кода) и обогащение инструментария.
Платформа спроектирована как self-hosted решение для работы в изолированном контуре. Контейнеризированный runtime гарантирует безопасность основной системы и «чистоту» хоста, а использование общих слоев для базовых образов модулей позволяет экономить место на диске.
Управление логикой вынесено в web-интерфейс на базе бесконечного рабочего поля. Данная абстракция позволяет визуализировать связи между узлами, превращая проектирование сценариев в наглядный процесс работы с потоками данных.
Сейчас я сосредоточен на проектировании архитектуры в целом. Это критический этап: необходимо заложить фундамент, который обеспечит предсказуемую оркестрацию и гибкость системы при масштабировании.
По мере работы буду вести devlog: показывать, как продвигаются дела, разбирать архитектурные решения и ошибки, на которых спотыкаюсь.
@diominvdev
Хочу поделиться идеей, которую я долго и мучительно вынашиваю в голове уже около полугода.
loom — self-hosted платформа, которая позволяет проектировать различные сценарии автоматизации через простой web-интерфейс. Главная проблема существующих решений в том, что они закрыты для «кастомизации» и вынуждают работать с готовым набором инструментов.
Уникальность loom заключается в языковой независимости. Модули для платформы могут быть написаны на любом языке и работать независимо от окружения хоста благодаря изолированному запуску через контейнеры.
Представим, что нужно автоматизировать простую, но специфичную задачу:
Ежедневный сбор данных о погоде с редкого контроллера через API с последующим анализом через ИИ, формированием отчёта в формате CSV, и рассылкой его в Telegram.
Решения вроде n8n могут просто не иметь в своем «арсенале» инструментов для работы с таким контроллером. Loom позволяет написать софт на подходящем языке, «обернуть» его в модуль и поделиться им через общую библиотеку с другими пользователями. Такой подход позволяет непроизвольно закрыть сразу два важных аспекта — безопасность софта (за счёт открытости кода) и обогащение инструментария.
Платформа спроектирована как self-hosted решение для работы в изолированном контуре. Контейнеризированный runtime гарантирует безопасность основной системы и «чистоту» хоста, а использование общих слоев для базовых образов модулей позволяет экономить место на диске.
Управление логикой вынесено в web-интерфейс на базе бесконечного рабочего поля. Данная абстракция позволяет визуализировать связи между узлами, превращая проектирование сценариев в наглядный процесс работы с потоками данных.
Сейчас я сосредоточен на проектировании архитектуры в целом. Это критический этап: необходимо заложить фундамент, который обеспечит предсказуемую оркестрацию и гибкость системы при масштабировании.
По мере работы буду вести devlog: показывать, как продвигаются дела, разбирать архитектурные решения и ошибки, на которых спотыкаюсь.
P.S. Отдельное спасибо @tatarskisamurai за помощь и исчерпывающую обратную связь.
@diominvdev
🔥6👍3❤2
Интерфейс - это признак слабости
Я огромный фанат терминала. Если задачу можно решить, не вылезая из консоли — я обязательно выберу именно такой путь. И дело тут не в желании казаться «хакером». Это способ держать систему в чистоте и понимать, что в ней происходит под капотом.
Настройка VPN на моём Arch — как раз такая история. В поисках лучшего решения я сделал выбор в пользу ядра mihomo и панели управления mihomo-tui. Всё выглядело логично и удобно, пока не выяснилось что мой провайдер не может подружиться с ядром.
Посетив сайт провайдера, я увидел список поддерживаемых клиентов. На каждом из них стояла верификация с пометкой HWID (Hardware ID). Смысл простой: привязка подключения к конкретному железу для идентификации устройства в системе.
Проверка теории началась с простого запроса: я постучался к провайдеру через curl. В ответ прилетела base64-строка. После декодирования внутри оказался пустой конфиг, состоящий из заглушек:
Данный ответ подтвердил мою догадку: провайдер просто не отдаст данные без HWID — уникального отпечатка устройства, который сервер ожидает увидеть в заголовках запроса.
Вычислить нужные заголовки было делом техники — достаточно подсмотреть, что отправляют одобренные клиенты. В итоге рабочий запрос через curl оброс кастомным User-Agent и тем самым идентификатором:
Цель достигнута — на руках заветный JSON. Но возник нюанс: mihomo понимает только формат Clash, так что скормить ему сырые данные напрямую не вышло. Впрочем, парсер писать не пришлось. Я заметил, что среди «одобренных» клиентов есть те, кто работает именно с Clash-конфигами. Значит, сервер умеет отдавать нужный формат сам — достаточно просто подставить правильный User-Agent в заголовок:
Рабочий туннель стал логичным завершением этой цепочки действий. В этом и заключается суть моего подхода к системе: не соглашаться на готовые, навязанные решения, а докапываться до сути. Теперь VPN интегрирована в моё окружение именно так, как я этого хотел — без лишнего софта и визуального шума.
В очередной раз убеждаюсь: не бывает закрытых дверей, бывают лишь плохо изученные замки.
@diominvdev
Я огромный фанат терминала. Если задачу можно решить, не вылезая из консоли — я обязательно выберу именно такой путь. И дело тут не в желании казаться «хакером». Это способ держать систему в чистоте и понимать, что в ней происходит под капотом.
Настройка VPN на моём Arch — как раз такая история. В поисках лучшего решения я сделал выбор в пользу ядра mihomo и панели управления mihomo-tui. Всё выглядело логично и удобно, пока не выяснилось что мой провайдер не может подружиться с ядром.
Посетив сайт провайдера, я увидел список поддерживаемых клиентов. На каждом из них стояла верификация с пометкой HWID (Hardware ID). Смысл простой: привязка подключения к конкретному железу для идентификации устройства в системе.
Проверка теории началась с простого запроса: я постучался к провайдеру через curl. В ответ прилетела base64-строка. После декодирования внутри оказался пустой конфиг, состоящий из заглушек:
vless://0000...
vless://0000...
vless://0000...(e.g., Happ, V2RayTun, Karing, FlClashX)
Данный ответ подтвердил мою догадку: провайдер просто не отдаст данные без HWID — уникального отпечатка устройства, который сервер ожидает увидеть в заголовках запроса.
Вычислить нужные заголовки было делом техники — достаточно подсмотреть, что отправляют одобренные клиенты. В итоге рабочий запрос через curl оброс кастомным User-Agent и тем самым идентификатором:
curl -s [URL] -H "User-Agent: Happ/2.14.0" -H "x-hwid: $(cat /etc/machine-id)" -o config.json
Цель достигнута — на руках заветный JSON. Но возник нюанс: mihomo понимает только формат Clash, так что скормить ему сырые данные напрямую не вышло. Впрочем, парсер писать не пришлось. Я заметил, что среди «одобренных» клиентов есть те, кто работает именно с Clash-конфигами. Значит, сервер умеет отдавать нужный формат сам — достаточно просто подставить правильный User-Agent в заголовок:
curl -s [URL] -H "User-Agent: ClashMeta/2.11.27" -H "x-hwid: $(cat /etc/machine-id)" -o config.yaml
Рабочий туннель стал логичным завершением этой цепочки действий. В этом и заключается суть моего подхода к системе: не соглашаться на готовые, навязанные решения, а докапываться до сути. Теперь VPN интегрирована в моё окружение именно так, как я этого хотел — без лишнего софта и визуального шума.
В очередной раз убеждаюсь: не бывает закрытых дверей, бывают лишь плохо изученные замки.
@diominvdev
2❤6👍2🔥2
HR настолько «преисполнился», что решил бахнуть quicksort на Питоне. Понимаю, рутина душит.
UPD: Алгоритм, конечно, рабочий, но за выделение памяти на каждом шаге рекурсии — HR-у незачёт. Пускай переписывает in-place на Go, иначе никакого оффера.
@diominvdev
UPD: Алгоритм, конечно, рабочий, но за выделение памяти на каждом шаге рекурсии — HR-у незачёт. Пускай переписывает in-place на Go, иначе никакого оффера.
@diominvdev
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Ничего кроме звука
Моё окружение полностью построено вокруг терминала — такой подход учит видеть избыточность. На этот раз под нож попала Яндекс Музыка с её официальным клиентом для Linux.
Для реализации был выбран довольно спартанский стек: mpd, mpc и сам плеер ncmpcpp. Архитектура простая: mpd работает в фоне и просто воспроизводит звук, mpc позволяет управлять mpd извне, ncmpcpp отвечает за визуализацию. Роль связующего звена между Яндекс Музыкой и данным стеком выполняет небольшая CLI-утилита, написанная на Python.
Downloader отвечает за синхронизацию локальной библиотеки с Яндекс Музыкой. Вместо СУБД — плоский state.json с маппингом ID треков Яндекса на локальные файлы: {"id": {"index", "file"}}. Он сверяет кэш с актуальным списком лайков: удалённые в облаке треки стираются с диска, новые встают в очередь на загрузку.
Ключевая деталь — защита от обрыва связи. Очередь отсекает уже скачанные ID, а state.json переписывается после каждого успешно скачанного трека, так что прогресс не теряется:
После загрузки имена файлов очищаются регуляркой, а через mutagen в MP3 вшиваются метаданные, индекс лайка (index/total).
Manager служит «панелью управления». Он управляет демоном mpd (запущенным на unix-сокете) через mpc, координирует запуск downloader и отвечает за интеграцию с ncmpcpp.
Главная задача менеджера — правильно выстроить очередь воспроизведения. Для сортировки скрипт парсит тот самый state.json и располагает треки строго по оригинальным индексам лайков:
CLI-интерфейс для утилиты построен на основе декларативного словаря — ключи это флаги, значения — функции:
Теперь вместо официального клиента — четыре инструмента, которые делают ровно то, что нужно и ничего сверх. MPD играет, ncmpcpp показывает, два скрипта держат библиотеку в порядке. Терминал учит не накапливать лишнее, и музыка тут не исключение.
Репозиторий: https://github.com/diominvd/yandex-music-cli
@diominvdev
Моё окружение полностью построено вокруг терминала — такой подход учит видеть избыточность. На этот раз под нож попала Яндекс Музыка с её официальным клиентом для Linux.
Для реализации был выбран довольно спартанский стек: mpd, mpc и сам плеер ncmpcpp. Архитектура простая: mpd работает в фоне и просто воспроизводит звук, mpc позволяет управлять mpd извне, ncmpcpp отвечает за визуализацию. Роль связующего звена между Яндекс Музыкой и данным стеком выполняет небольшая CLI-утилита, написанная на Python.
Downloader отвечает за синхронизацию локальной библиотеки с Яндекс Музыкой. Вместо СУБД — плоский state.json с маппингом ID треков Яндекса на локальные файлы: {"id": {"index", "file"}}. Он сверяет кэш с актуальным списком лайков: удалённые в облаке треки стираются с диска, новые встают в очередь на загрузку.
Ключевая деталь — защита от обрыва связи. Очередь отсекает уже скачанные ID, а state.json переписывается после каждого успешно скачанного трека, так что прогресс не теряется:
queue = [(i + 1, t) for i, t in enumerate(tracks) if str(t.id) not in state]
for i, (index, track) in enumerate(queue, 1):
if download(track, index, total):
state[str(track.id)] = {"index": index, "file": f"{slug(track)}.mp3"}
save_state(state)
time.sleep(0.3)
После загрузки имена файлов очищаются регуляркой, а через mutagen в MP3 вшиваются метаданные, индекс лайка (index/total).
Manager служит «панелью управления». Он управляет демоном mpd (запущенным на unix-сокете) через mpc, координирует запуск downloader и отвечает за интеграцию с ncmpcpp.
Главная задача менеджера — правильно выстроить очередь воспроизведения. Для сортировки скрипт парсит тот самый state.json и располагает треки строго по оригинальным индексам лайков:
if STATE_FILE.exists():
state = json.loads(STATE_FILE.read_text()).get("ids", {})
file_index = {
meta["file"]: meta["index"]
for meta in state.values()
}
tracks = sorted(
MUSIC_DIR.glob("*.mp3"),
key=lambda p: file_index.get(p.name, 9999)
)
else:
tracks = sorted(MUSIC_DIR.glob("*.mp3"))
CLI-интерфейс для утилиты построен на основе декларативного словаря — ключи это флаги, значения — функции:
COMMANDS = {
"--start": lambda: systemd("start"),
"--stop": lambda: systemd("stop"),
"--update": lambda: (subprocess.run(["uv", "run", str(DOWNLOADER)]), mpc("update", "--wait")),
"--init": init,
"--next": lambda: mpc_print("next"),
"--random": random_toggle,
}Теперь вместо официального клиента — четыре инструмента, которые делают ровно то, что нужно и ничего сверх. MPD играет, ncmpcpp показывает, два скрипта держат библиотеку в порядке. Терминал учит не накапливать лишнее, и музыка тут не исключение.
Репозиторий: https://github.com/diominvd/yandex-music-cli
@diominvdev
❤4👍2🔥2
Совершил прыжок веры и взял Galaxy S26. Оказывается, на Android тоже есть жизнь.
Может напишу обзор. А может и не напишу. Очередь из постов и так уже как в поликлинике.
@diominvdev
Может напишу обзор. А может и не напишу. Очередь из постов и так уже как в поликлинике.
@diominvdev
❤7
По результатам опроса (8:7) темой для следующего поста был выбран подробный обзор на мою конфигурацию Neovim. Материал уже в работе, поэтому рассчитываю опубликовать его в самое ближайшее время.
Обзор Galaxy S26 обязательно выйдет, но немного позже.
@diominvdev
Обзор Galaxy S26 обязательно выйдет, но немного позже.
@diominvdev
❤3👍2🥱1
Анатомия моего Neovim
Современные IDE приучили нас к ленивому потреблению: тыкаешь одну кнопку «Установить», а взамен получаешь гигабайты скрытых процессов, телеметрии и какого-то чужого кода. Я удалил все графические редакторы и ушёл в монастырь под названием Neovim. Но спойлер: внутри статьи не будет очередной священной войны в духе «Vim против JetBrains» и унылых списков плагинов.
Это скорее история о том, как перестать копировать чужие сборки и собрать с нуля подконтрольную систему, где каждая строчка кода выстрадана лично.
В общем, если вы тоже устали от тяжеловесных комбайнов и хотите вернуть контроль над своими руками и мыслями — залетайте.
https://teletype.in/@diominvd/Quc2pHvtA1N
@diominvdev
Современные IDE приучили нас к ленивому потреблению: тыкаешь одну кнопку «Установить», а взамен получаешь гигабайты скрытых процессов, телеметрии и какого-то чужого кода. Я удалил все графические редакторы и ушёл в монастырь под названием Neovim. Но спойлер: внутри статьи не будет очередной священной войны в духе «Vim против JetBrains» и унылых списков плагинов.
Это скорее история о том, как перестать копировать чужие сборки и собрать с нуля подконтрольную систему, где каждая строчка кода выстрадана лично.
В общем, если вы тоже устали от тяжеловесных комбайнов и хотите вернуть контроль над своими руками и мыслями — залетайте.
https://teletype.in/@diominvd/Quc2pHvtA1N
@diominvdev
Teletype
Радикальная осознанность: почему я собрал свой Neovim с нуля
Я давно удалил все графические редакторы кода и перешёл на Neovim. Ранее я уже писал об этом «нишевом» редакторе и почему он не является...
❤2👍2
Сил моих больше нет
Почти каждый новостной IT-канал превратился в помойку постов про ИИ. Буквально. Пропала та самая идентичность, когда каждый канал был своей мини-планеткой со своей атмосферой. Теперь же почти каждый пост это "ВЫШЛА НОВАЯ ИИ-УБИЙЦА". Потерялась сама суть — инженерная эстетика и радость от простых, приземленных, но изящных технологических решений.
Уверен, что для кого-то подобные посты действительно актуальны, но тогда и канал надо позиционировать иначе.
Скучаю по тем временам, когда выход новой либы был действительно событием в IT-сообществе, пусть даже и в узком кругу.
@diominvdev
Почти каждый новостной IT-канал превратился в помойку постов про ИИ. Буквально. Пропала та самая идентичность, когда каждый канал был своей мини-планеткой со своей атмосферой. Теперь же почти каждый пост это "ВЫШЛА НОВАЯ ИИ-УБИЙЦА". Потерялась сама суть — инженерная эстетика и радость от простых, приземленных, но изящных технологических решений.
Уверен, что для кого-то подобные посты действительно актуальны, но тогда и канал надо позиционировать иначе.
Скучаю по тем временам, когда выход новой либы был действительно событием в IT-сообществе, пусть даже и в узком кругу.
@diominvdev
👍3❤1🔥1
Обновил свой конфиг Neovim: пофиксил баги, почистил лишнее, унифицировал структуру, добавил пару плагинов. Ничего революционного, просто стало чище и приятнее в работе.
В будущем, для удобства, возможно введу версионирование — пока думаю над этим.
Все изменения в репозитории: https://github.com/diominvd/neovim
@diominvdev
В будущем, для удобства, возможно введу версионирование — пока думаю над этим.
Все изменения в репозитории: https://github.com/diominvd/neovim
@diominvdev
GitHub
GitHub - diominvd/neovim: A clean, highly tailored Neovim environment built from scratch with a focus on absolute control, engineering…
A clean, highly tailored Neovim environment built from scratch with a focus on absolute control, engineering aesthetics, and minimal friction. - diominvd/neovim
1👍2❤1
VPN без GUI, без клиентов, только терминал — писал про это раньше. Скрипт с тех пор дорос до полноценной cli-утилиты.
Сам менеджер делает две вещи: обновляет конфиги подписок (
Про сервис отдельно:
Единственное место, где вообще нужны привилегии — это сам mihomo, а не менеджер: создание TUN-интерфейса и биндинг на 53-й порт для DNS. Вместо root — точечные capabilities на бинарник:
Из интересного в самом коде — никакого ручного управления зависимостями: manager.py объявляет
Отдельно про подписки — они вынесены в
Заголовки в
Сам
Получился ровно тот минимализм, который я люблю: один бинарник, один конфиг, одна команда — без лишних абстракций. Так что продолжаем GUI-протест и остаёмся в своём болоте под названием "терминал".
Репозиторий: https://github.com/diominvd/vpn-manager-cli
@diominvdev
Сам менеджер делает две вещи: обновляет конфиги подписок (
vpn --update подтягивает актуальный конфиг от провайдера через curl) и управляет systemd user-сервисом mihomo — старт/стоп/рестарт/статус одной командой вместо ручного systemctl --user ... каждый раз.Про сервис отдельно:
manager.py дёргает именно systemctl --user, а не системный демон. Юзер-сервис живёт в рамках сессии, не требует root ни на каком этапе управления и не лезет в /etc/systemd/system. Для личного VPN на одной машине — это избыточность в правильную сторону.Единственное место, где вообще нужны привилегии — это сам mihomo, а не менеджер: создание TUN-интерфейса и биндинг на 53-й порт для DNS. Вместо root — точечные capabilities на бинарник:
cap_net_admin,cap_net_bind_service. Без этого никак. Менеджер и всё остальное работает от обычного пользователя.Из интересного в самом коде — никакого ручного управления зависимостями: manager.py объявляет
requests прямо в шапке файла через PEP 723, и uv сам разворачивает окружение при первом запуске. CLI-диспетчер — буквально словарь {флаг: функция}, без сторонних библиотек для разбора аргументов и лишних абстракций ради пяти команд.COMMANDS = {
"--start": lambda: systemd("start"),
"--stop": lambda: systemd("stop"),
"--restart": lambda: systemd("restart"),
"--status": lambda: systemd("status"),
"--update": update,
}Отдельно про подписки — они вынесены в
subscriptions.json, который в репозиторий не попадает (git-ignored), а рядом лежит subscriptions.json.example с плейсхолдерами."subscriptions": [
{
"name": "provider-name",
"url": "https://example.com/YOUR_TOKEN",
"path": "~/.config/mihomo/providers/provider-name.yaml",
"decode": false
}
]
Заголовки в
headers подделывают User-Agent под официальный клиент ClashMeta и передают x-hwid — так провайдер отдаёт конфиг только тем запросам, что выглядят как настоящий клиент, а не любому curl с токеном в URL."headers": {
"User-Agent": "ClashMeta/2.11.27",
"x-hwid": "YOUR_HARDWARE_ID"
}Сам
manager.py при отсутствии файла не падает молча, а прямо подсказывает, что делать: скопировать пример и заполнить своими данными.Получился ровно тот минимализм, который я люблю: один бинарник, один конфиг, одна команда — без лишних абстракций. Так что продолжаем GUI-протест и остаёмся в своём болоте под названием "терминал".
Репозиторий: https://github.com/diominvd/vpn-manager-cli
@diominvdev
1🔥4
Давно не писал фронт, и тут снова сел за React, Vite, TypeScript — пилю необычный с точки зрения концепции сайт/SPA. Открыл neovim — и сразу почувствовал нехватку: ни LSP, ни formatter, ни treesitter для фронтОвых файлов не настроены.
Начал добавлять всё по одному — и поймал момент, когда понял, к чему это ведёт. Каждый язык тянет за собой правки в четырёх разных местах: список для mason, список для lspconfig, список для conform, список для treesitter. Конфиг на глазах превращался в мусорку, где непонятно, что и зачем добавлено.
Решение — вынести язык в одну точку. Теперь
Добавить язык — значит добавить одну запись и перезапустить nvim. Отключить — поставить
Заодно закрыл вопрос, который откладывал давно: версионирование самого конфига. Коммиты — это история изменений, но не история релизов, а ориентироваться по хэшам неудобно. Теперь версия лежит в
Получился первый релиз — v0.1.0, с прозрачным конфигом языков и понятной точкой отсчёта в истории. Конфиг растёт, но теперь хотя бы не превращается в мусорку.
Репозиторий: https://github.com/diominvd/neovim
@diominvdev
Начал добавлять всё по одному — и поймал момент, когда понял, к чему это ведёт. Каждый язык тянет за собой правки в четырёх разных местах: список для mason, список для lspconfig, список для conform, список для treesitter. Конфиг на глазах превращался в мусорку, где непонятно, что и зачем добавлено.
Решение — вынести язык в одну точку. Теперь
lua/config/languages.lua — единственное место, где описывается язык: LSP-сервер, форматтер, парсер. Mason, lspconfig, conform и treesitter просто читают из этой таблицы, а не хранят собственные списки:["TypeScript / React"] = {
enabled = true,
ft = { "javascript", "typescript", "typescriptreact" },
lsp = { "ts_ls" },
formatter = { "prettierd", "prettier" },
parsers = { "javascript", "typescript", "tsx" },
},Добавить язык — значит добавить одну запись и перезапустить nvim. Отключить — поставить
enabled = false, ничего не удаляя вручную с диска.Заодно закрыл вопрос, который откладывал давно: версионирование самого конфига. Коммиты — это история изменений, но не история релизов, а ориентироваться по хэшам неудобно. Теперь версия лежит в
lua/config/version.lua, история — в CHANGELOG.md с секциями Unreleased и датированными релизами, а scripts/bump.sh patch/minor/major сам переносит незалогированные изменения в релиз, бампает версию и ставит git-тег:scripts/bump.sh minor
# Released v0.1.0 (was v0.0.0)
# Push with: git push && git push --tags
Получился первый релиз — v0.1.0, с прозрачным конфигом языков и понятной точкой отсчёта в истории. Конфиг растёт, но теперь хотя бы не превращается в мусорку.
Репозиторий: https://github.com/diominvd/neovim
@diominvdev
👍2🔥2
Наверное developer
Давно не писал фронт, и тут снова сел за React, Vite, TypeScript — пилю необычный с точки зрения концепции сайт/SPA. Открыл neovim — и сразу почувствовал нехватку: ни LSP, ни formatter, ни treesitter для фронтОвых файлов не настроены. Начал добавлять всё…
У neovim-конфига теперь есть релизы, семвер и changelog. У сайта — только темплейт. Есть ненавязчивое ощущение, что я в очередной раз занимаюсь какой-то ерундой вместо кода — но зато очень системно 🤓
1👍5

