Знаю, такие заголовки сейчас повсюду и мне казалось, что вайб‑кодинг это инструмент для реальных программистов. Когда я был программистом (уже прошло более 10 лет, как я не писал код) нашим вайб‑кодингом был stackoverflow. Заходишь на него, ищешь там нужный тебе кусок кода или просишь помощи у сообщества и вставляешь себе. У меня на github даже была библиотека разных кусков, например как сделать запись в бд, как открыть файл, различные циклы и так далее
Когда впервые услышал о вайб‑кодинге, то решил, что это некая «автоматизированная библиотека» из которой ИИ‑модель берет код и вставляет его. Но когда я начал погружаться в эту тему, и пока я погружался уже появились полноценные агенты, понял, что он не просто подставляет код, а сам пишет, решает проблемы и чинит ошибки.
И тут я решил попробовать вспомнить свое прошлое, только без погружения в современный код, так как я думаю это делать уже бесполезно, слишком много воды утекло с того времени. Провел эксперимент в котором решился полностью довериться агенту и выпустить свой плагин для Obsidian.
Идея плагина
Не буду сильно вдаваться в подробности логики работы плагина, ибо не о том речь в данной публикации. Поэтому расскажу вкратце.
С недавнего времени у меня настолько стало много файлов по различным проектам, что искать их в файловой системе стало долго и неудобно. Особенно когда в пылу работы всё сваливается в одну папку и потом ее разбирать то ещё мучение.
Я работаю с Obsidian уже давно и решил почему бы не хранить информацию о файлах в хранилище, там можно и базу настроить для быстрого и удобного поиска. Но проблема была в том, что когда кладешь файл в хранилище, то у тебя есть только его название. Найти, например «Договор № 542-Д‑ШТОД-32-1.docx» сложно. Вспомнить, как он называется, ещё сложнее. А вспомнить, о чём он и какую редакцию брать в работу, — практически невозможно.
Так родилась идея: плагин, который сам следит за всеми файлами в хранилище и сразу предлагает заполнить описание. И теперь у файла «Договор № 542-Д‑ШТОД-32-1.docx» было описание: «Договор подряда, обсудили то‑то, согласовали моменты А, Б, В. Действует до 31.12.2030». Согласитесь, такое найти куда проще — и по ключевым словам, и по смыслу.
Инструменты
Работал в OpenCode на модели DeepSeek v4 Flash — она бесплатная из коробки, не хотелось тратить свои кровные ради попробовать. И плюс было интересно как справиться относительно маломощная модель с таким «проектом».
Процесс разработки
Тут описывать особо нечего. Я дал ему описание того, что я хочу получить на выходе.
Главное условие состояло в том, что я:
не проверял, не читал код который он пишет, все на усмотрение агента.
не подсказывал агенту, не искал решения проблем сам
И с самой первой строчки кода он сам все написал, создал необходимую структуру проекта, сам все билдил. Я только тестировал с точки зрения пользователя то что он мне отдавал. Отправлял на доработку, снова тестировал, снова на доработку и так далее пока плагин не был готов. Сам только создал репозиторий на github, дальше я отдал ему ссылку и снова «убрал руки от клавиатуры», дальше он сам все туда залил, настроил автоматическую сборку релизов.
Процесс публикации в каталог Obsidian
Начало
Начнем с того, что я даже примерно не представлял как это сделать. Я не знал, где находиться каталог, как в него публиковать и вообще с чего начать. Но помним про эксперимент, мне этого и не нужно было знать, ведь у нас есть агент. Поэтому я ему так и написал: «Теперь наш плагин нужно выложить в каталог». Он собрал всю информацию по этому вопросу и составил план действий.
Первая проблема
Агент нашел устаревшую информацию, что плагин публикуется через репозиторий github. Мы начали отдавать свой плагин туда, но нам постоянно возвращались ошибки доступа к репозиторию. По итогу агент начал грешить на мой аккаунт github, предполагая, что я из России и поэтому нам нельзя публиковаться.
Я строго следовал правилу и не стал искать сам решение проблемы и даже не гуглил, в чём проблема. Т.е. я весь процесс шёл «вслепую», не разбираясь ни с одной возникшей ошибкой/проблемой.
Поэтому я написал, чтобы он выдохнул и провел исследование, как все‑таки выложить плагин в каталог. Тут агент наконец‑то решил пойти в интернет и поискать информацию там. Оказалось, что через github уже давно плагины не публикуются и нужно сделать аккаунт на https://community.obsidian.md/ и уже через него публиковать.
Как и в случае с github, от меня потребовалось зайти, куда мне сказал агент, создать аккаунт и всё, дальше он сам.
Первая попытка публикации
К первой публикации мы пришли с релизом 1.0.1.
Obsidian проверяет все плагины и темы автоматическим чекером. Какие у него были правила и пункты проверки я естественно не представлял.
Он берет с вашего репозитория github последний свежий релиз и отправляет его на проверку. Это делал я, нажимал целую одну кнопку «Проверить релиз».
И тут пошёл процесс))
Проверка релиза 1.0.1 — естественно выдала просто огромное полотно из ошибок.
Начну не по порядку, а с того, что съело больше всего времени.
1. UTF-8 BOM в JSON — главный затык
Чекер падал на парсинге manifest.json и versions.json. При этом файлы открывались в редакторе и выглядели совершенно нормально. Валидный JSON, никаких опечаток.
Причина — BOM (Byte Order Mark), невидимые байты в начале файла, которые дописал редактор при сохранении. Парсер Obsidian их не переваривает.
Проверить наличие:
head -c 3 manifest.json | xxd
Если видно efbb bf — BOM на месте.
Лечится пересохранением в UTF-8 без BOM. В VS Code: нижняя панель → кодировка → Save with Encoding → UTF-8.
Почему это заняло столько времени: ошибка не воспроизводится локально, файл выглядит корректным, а текст ошибки указывает на парсинг — то есть, будто бы на синтаксис. Мы ходили кругами, переписывая содержимое файла, которое было в порядке.
Если у вас чекер ругается на JSON, а JSON визуально идеален — проверяйте BOM первым делом.
2. Deprecated API и строгая типизация
Код был написан по примерам, которые модель знала по обучающим данным — то есть, по устаревшим. Часть API уже помечена deprecated.
Плюс чекер требует строгий режим TypeScript. Включили tsc --strict, вычистили unsafe-assignment и лишние приведения типов.
3. Лишние файлы в релизе
Сначала в релиз попал package.json — по логике «пусть проверка соберёт проект».
Оказалось, в релизе должны быть ровно три файла: main.js, manifest.json, styles.css. Всё остальное — ошибка.
4. “type”: “module” в package.json
Плагины Obsidian живут в CommonJS‑окружении. Это поле переводит проект в ESM и ломает сборку при проверке.
Решение: удалить строку.
5. Аттестация артефактов
Obsidian требует, чтобы релизные ассеты имели подтверждённую GitHub‑аттестацию. Без неё чекер пишет release asset has no verified attestation.
Значит, релиз обязан собираться через GitHub Actions с шагом attest-build-provenance:
permissions: id-token: write contents: write attestations: write steps: - uses: actions/attest-build-provenance@v1 with: subject-path: | main.js manifest.json styles.css
Права в permissions обязательны. И перечислить нужно все три файла — сначала был указан только main.js, получили очередной отказ.
6. Нестабильный релиз из CI
Отдельная история на несколько итераций. Перепробовали: gh CLI → прямые вызовы GitHub API → парсинг через jq → grep → softprops/action-gh-release. Каждый вариант ломался по‑своему.
Остановились на ncipollo/release-action@v1 — работает стабильно.
Итоговая схема:
push тега → checkout → npm ci → npm run build → attest-build-provenance (main.js, manifest.json, styles.css) → ncipollo/release-action (ассеты + описание)
По итогу первой публикации
Весь процесс занял, наверное, часа два. Чекер возвращал ошибки → я отдавал их агенту → он исправлял → делал новый релиз → я запускал проверку релиза на сайте obsidian и так все два часа.
И какова была радость, когда чекер, наконец‑то, пропустил, и я увидел заветный «Completed».

Как видно из изображения, до заветного «Completed» мы добрались с версией релиза 1.0.15 )), то есть, для первой публикации нам понадобилось 15 релизов.
Чтобы не мучиться так каждый раз с публикацией, я сказал агенту проанализировать весь путь, собрать все ошибки и их решения и сделать себе инструкцию на будущее, чтобы не решать одни и те же ошибки каждый раз.
Обновленная версия плагина и снова публикация
Я поработал с плагином две недели, и мне показалось неудобным, когда система смотрит за изменениями файлов только в одной папке. Я решил сделать так, чтобы, куда бы вы не положили файл в хранилище, он бы его регистрировал.
Сделали обновление, это было недолго, полчаса — и всё готово. Полчаса с моими тестами. Ну и я, преисполненный тем, что сейчас обновление со свистом залетит в каталог, получил очередную порцию «проблем».
За эти две недели вышла новая версия самого Obsidian (1.13.4), и конечно же, обновились правила у чекера.
Я решил, что мое обновление плагина «достаточно крупное», поэтому я с гордостью повысил версию с 1.0.15 до 1.1.0
И конечно же, ошибка.

Из‑за обновления самого Obsidian и правил чекера, мы решали следующие проблемы:
1. Заголовки в настройках
Запрещено создавать заголовки через containerEl.createEl('h3', ...). Только штатным способом:
new Setting(containerEl).setName('Название секции').setHeading();
2. Хардкод.obsidian
Системная папка проверялась так:
path.startsWith('.obsidian/')
Чекер справедливо возразил: конфигурационную папку пользователь может переименовать. Нужно:
this.app.vault.configDir
3. require('electron')
Кнопка «Открыть папку» в напоминании использовала require('electron'). Чекер запрещает require‑стиль импортов и any.
Решение: import { shell } from 'electron' плюс локальный файл типов src/electron.d.ts.
4. Декларативный API настроек
Obsidian 1.13.0 ввёл новый API — getSettingDefinitions(). Без него настройки плагина не находятся через поиск по настройкам. Формально не ошибка, но плагин становится неудобным.
Настройки переписали на декларативные типизированные определения.
5. no‑unsupported‑api
Добавили декларативный API — получили новую ошибку: используются API новее, чем заявленный minAppVersion.
Стояло minAppVersion: 1.7.0, а getSettingDefinitions() и update() требуют 1.13.0.
Логика чекера здесь такая: он сверяет каждый вызов API с версией, которую вы обещаете поддерживать. Заявил 1.7.0 — значит, у пользователя с 1.7.0 плагин обязан работать. А он бы упал.
Решение: поднять minAppVersion до 1.13.0.
6. Deprecated display()
Метод display() для настроек официально устарел с 1.13.0. После поднятия minAppVersion он превратился в мёртвый код — удалили полностью.
По итогу публикации обновления
Агент стал уже умнее и не совершал старых ошибок, учел все новые и мы снова обновили файл инструкции. Поэтому даже с учетом обновления Obsidian для успешной публикации нам понадобилось уже 2 релиза.

И тут вы ждете хэппи‑энда? Не тут‑то было.
Релиз мы опубликовали, чекер нас пропустил, но агент исправил только те ошибки, которые не давали нам пройти. При этом оставил «Warning», так как посчитал, что они не важны и написал: «Warning не блокируют релиз, блокируют только Error».
Но они важны самому Obsidian, и поэтому наши показатеи упали, не критично, конечно, но лично я из‑за чувства эстетики решил, что всё должно быть идеально. О чем речь?
В карточке плагина есть вот эти показатели:

И у показателя «Review» не было одной зеленой риски. И это было как раз из‑за тех «Warning» которые мы не поправили.
Исправляем 21 Warning
1. prefer‑create‑el — те самые 21 Warning
Чекер флагает вызовы .createEl('div', ...) и .createEl('span', ...) и требует штатные шорткаты .createDiv() и .createSpan().
Нюанс, который стоит запомнить: правило смотрит только на div и span. Другие теги — button, h2, p, input — оно не трогает. Массово переписывать всё не нужно.
Заменили 21 вызов в трёх файлах. Чистая косметика, но рейтинг того стоил.
2. prefer‑get‑language
Язык интерфейса определялся через window.localStorage.getItem('language'). Чекер советует штатный getLanguage() из API Obsidian — доступен с 1.8.7, что совместимо с minAppVersion: 1.13.0.
Заменили, заодно ушла самописная обработка языкового кода.
Итог: 0 Errors, 0 Warnings. Полная зелёная полоска вернулась.
Bug Fix
После успешной публикации и возврата «рейтинга» я при тестировании заметил, что плагин работает не корректно. Мы пофиксили все баги и....
И ничего не случилось!! Агент шел по инструкции и не допустил ни одной ошибки, чекер нас пропустил с первого раза. И релиз залетел.
Но как мы увидели это выше Проверка пройдена ≠ проверка пройдена навсегда. Obsidian обновляется, правила меняются, и каждый ваш новый релиз «под угрозой».
Заключение
Мне данный эксперимент показался весьма увлекательным. С учетом того, что я ничего не делал сам, кроме как завел репозиторий и аккаунт на https://community.obsidian.md/, и нажимал кнопочку «Проверить релиз».
Вся «разработка» от идеи до первого полноценного релиза заняла 2 вечера с 19 до 23 часов. Т.е. по факту 8 часов.
Я был поражен, насколько это мощный и продвинутый инструмент. Не устану повторять про условия: я не программист (уже), я не настраивал каким‑то образом агента. Не прописывал ему Skills, Agents и так далее. Вот как скачал, так и пошел. Пользовался бесплатной ии‑моделью из коробки, не самой топовой. И при этих условиях я создал рабочий «продукт».
А каких результатов можно достичь, когда вы являетесь программистом, знаете стэк и так далее, и у вас под рукой такой помощник, который делает 80% вашей работы за считанные часы. Насколько сейчас улетит скорость релизов софта с таким инструментом?
По моему скромному мнению, эра разработки «мелкого софта» канула в Лету. Любой человек, независимо от его навыков, может написать для себя софт, который нужен конкретно ему, и заточенный под конкретную задачу.
Лично для себя, я уже «написал» целую пачку обработчиков файлов Excel под мою конкретную задачу. И теперь на эту задачу я трачу не 3–4 часа, а 15 минут (это если я в это время завариваю себе кофе).
P. S. Материалы и ссылки, вдруг кому‑то это окажется полезным
1. Чек‑лист перед публикацией
Список, который я держу под рукой перед каждым релизом:
minAppVersion— сразу по фактически используемым API. Декларативные настройки → 1.13.0. Документация manifest.jsonРелизные ассеты — только
main.js,manifest.json,styles.cssАттестация — релиз через GitHub Actions с
attest-build-provenanceи правамиattestations: writeJSON без BOM — проверяйте это первым делом, если чекер ругается на парсинг
Не использовать:
require(), хардкод.obsidian, deprecateddisplay(), прямыеcreateEl('div'/'span')Заголовки в настройках — только
Setting.setHeading()Warning не блокируют релиз, но копятся и роняют рейтинг
2. Ссылки
Плагин: community.obsidian.md/plugins/file‑describer
Исходники: github.com/Alexandrovdi/File‑Describer
