Стендап Сьогодні
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
Пости з тегом #МоїПроєкти
10.05.2025
Нова версія гему Headless та ШІ для розблокування проєктів
Сьогодні випустив оновлення для Headless. За всіма вимірами, це треба було зробити вже давно, але краще пізніше, ніж ніколи — принаймні, якщо люди все ще просять. (Я вже писав), що мені він давно не потрібний. Десь з рік тому до мене зверталася людина та пропонувала зайнятися підтримкою, та я навіть доступи надав, але… в неї теж поки не знайшлося часу, напевно? Історія класична. Десь з тиждень тому мені знову нагадали, що гем не працює з сучасним Ruby, тож вирішив взятись.
Як я себе змусив це зробити. Думаю, ну мені не хочеться - Cursor зможе. Успіхи з Cursor були різного рівня.
Замінити Travis CI на Github Actions - впорався на 95%. (Чомусь запхав у виконання тестів xvfb-run
, хоча вся суть мого гему, що він заміняє xvfb-run
для програм на Ruby.) Це чудово! Я вручну б довго сидів та розбирав синтаксис.
Оновити матрицю версій Ruby для CI - впорався на 100%. Теж гарно, бо це наче просто, але довелося б бігати по сторінках завантажень Ruby та JRuby.
Прибрати ключ конфігурації та перейменувати інший — десь 90%, майже все гарно, але трохи додумав зайвого. Втім, не так багато, щоб його було складно видалити.
Додати Rubocop - тут я б сказав 30% успіху — наче щось виходило, але конфігурації забагато та rubocop-rails
намагався теж впхати.
Виправити Rubocop - цього взагалі не раджу робити, хоча в мене були великі сподівання. Бо код псує більше, ніж виправляє. Причому псує в сенсі змінює зміст. А я зрештою замінив Rubocop на Standard - це надбудова над Rubocop із переконаним набором налаштувань. Окрім іншого, Standard добре виправляє помилки та підійде навіть в ролі автоформатувальника. Навіщо ШІ, коли є спеціалізований інструмент?
Якщо підбити підсумки, то агент ШІ допоміг зсунутися з мертвої точки та навіть закрити деякі необхідні, але рутинні оновлення. Та це безумовно успіх. Проєктів багато — мене мало. З агентом мене стає більше.
13.05.2025
Вкладки браузера — в Obsidian Canvas (скрипт)
Я якось писав, що хочу браузер, який буде інтегрований з базою знань. Таке можна потрохи робити. От, наприклад, коли я навідкривав вкладок для якогось дослідження, було б гарно всі їх скинути в Obsidian Canvas на майбутнє. Але ж не вручну? Накрутив собі за пів годинки скрипт, не без помічника ШІ.
Власне, майже всі запчастини в мене вже є, Я вже писав, як отримати список вкладок з Safari та генерувати Canvas зі списку, утиліту для чого pbcopy-chromium я вже публікував. Але одне рішення — на AppleScript, друге — на Ruby. Вирішив, що найбільш елегантно буде зібрати до купи на JavaScript for Mac Automation, про який я теж вже писав. Бо інакше інтеграція буде ще складніша, ніж частини.
Отже. AppleScript у JXA перекладається 1-до-1. Це, за моїм досвідом, найкраща задача для ШІ! Замість години копирсання поганою документацією та поступового налагодження — задля, фактично, “нульового” результату, бо ми тільки перекладаємо логіку на іншу мову — одна команда. Так само вдалося й перекласти генерацію канви з Ruby на JXA - причому, ба більше, ШІ відразу її автоматично “вписав” у попередній скрипт.
Це 80% роботи. Решта 80% була менш автоматичною. Ну, згенерувати команду для виклику pbcopy-chromium
вийшло, та це гарно, бо там не одна команда, а цілий ланцюг. От тільки як в нього передати зміст? ШІ зробив через echo
. Зрозуміло, що зі складним JSON від цього буде купа проблем. Тоді спробував через тимчасовий файл. ШІ нагенерував відповідні команди — включаючи mktemp
для генерації файлу — десь на 80%.
Але тепер залишилося найцікавіше, бо запис у файл з JXA не використовує UTF-8. Поради ШІ тут були безпомічні. Тоді знайшов на SO відповідь, як то зробити… мостом в Objective C? Дико, але працює!
Нарешті, про рефакторинг. Сьогодні ШІ накидав все в одну купу; наприклад, вище згадана побудова JSON для канви відбувалася прямо в циклі по вкладках браузера. Звісно, краще ділити логіку за намірами. Зате інструкція “розбий це на дві функції для того та для того” спрацювала.
Ще з суто ШІшного ексцесу (тобто такого, що я б сам не став робити) - генерація ID вузла через хеш змісту. Це я попросив зробити, але функцію воно нагенерувало само. Нічого бібліотечного готового немає. Вирішив, нехай залишається.
Знову, таку роботу я б сам не зробив, бо часу немає. Забрати скрипт можна тут.
16.05.2025
Reminders2JSON, а також ШІ як клей
Отже, вчора в коментарях зʼясували, що Apple Reminders технічно можна було б вивантажити в JSON через фреймворк EventKit. А сьогодні я вирішив, що це гарний проєкт для того, щоб погратися з ШІ, та майже витягнув його в App Store (!)
Чому гарний для ШІ? Бо я гарно розумію, що треба зробити, але це все одно багато роботи. Це проєкт-“клей”, тобто такий, де потрібно поєднати готові частини в спеціалізоване рішення. Я люблю цитувати статтю You can’t buy integration, але — здається, ШІ чудово виконує “склейку”.
В цьому випадку, я спочатку згенерував функції читання з EventKit та генерації JSON, потім — окремо — експорт будильників та графіків. Потім конфігурацію командного рядка. Потім конвертував застосунок командного рядка у SwiftUI (!) Створив набір значків потрібного розміру. Додав файли Fastlane для публікації. Та більшу частину всього цього зробив Claude.
Але на “інші 80%” пішло набагато більше часу. Наприклад, спочатку я хотів консольну утиліту. Але в моделі безпеки macOS вони не можуть отримати дозвіл на читання Reminders. (Бо ця модель розрахована на “товсті” застосунки, із всілякими підписами.) Та мені так і не вдалося це побороти, хоча наче можливість є — невідомо тільки як до неї прийти. Локально в XCode наче працює, але на іншій машині абсолютно відмовляється.
Промучився пару годин та вирішив зробити очевидне рішення — перетворити на графічний застосунок. Та тут ШІ впорався не тільки зі створенням інтерфейсу, але й, наприклад, із відкриттям діалогу для збереження файлу (ще одна склейка).
Сам застосунок дуже нудний — бере нагадування, зберігає в JSON. А, ще деякі атрибути нагадувань недоступні з EventKit - наприклад, групи списків. Ну то вже таке. Через пару днів має зʼявитися в App Store. А ось вже й в App Store!