
У червні я додав до OwlMeans Common команду create-app. Мені хотілося мати невеликий проєкт, який можна віддати агентові для програмування, не пояснюючи спершу фреймворк із нуля.
Common — це фундамент на TypeScript, на якому стоять проєкти OwlMeans. Команда дає тобі відправну точку, яку можна одразу запустити, і настанови, які описують її домовленості. А от скеровувати агента й переглядати, що він змінює, доведеться тобі.
У цьому покроковому розборі лишилися червневий приклад і закріплені версії з тексту, який ми підтримуємо на сайті. Структура настанов нижче вже враховує пізніший перехід на .agents/.
Стартовий проєкт
Вибери одну з команд:
bun create @owlmeans/app my-app
# or
npm create @owlmeans/app@latest my-app
# or
npx @owlmeans/create-app@^0.1.18 my-app
Потім запусти сервери для розробки:
cd my-app
bun run dev # API on :3000, web on :3001
Відкрий вебзастосунок і спробуй додавати й видаляти елементи на екрані Session. Демо зʼєднує фронтенд з API через спільний контракт. Дані зберігаються в памʼяті. Досить перезапустити процес, щоб згадати, чому це важливо.
Каркас складається з трьох робочих просторів:
commonмістить спільні оголошення маршрутів, схеми валідації й типи.apiзапускає бекенд на@owlmeans/server-app.webвідповідає за фронтенд на@owlmeans/web-panel.
Це мінімальний каркас, який створює CLI. Проєкти, згенеровані в OwlMeans, можуть містити ще й спільну бекенд-бібліотеку та воркер. Ні їх, ні бази даних приклад із CLI для тебе не створює.
Контракт застосунку
Я хочу, щоб агент знаходив оголошення маршруту пошуком за псевдонімом. Та й сам хочу простежити те саме оголошення.
Для цього контракту в Common є точки входу. Точка входу повʼязує псевдонім, шлях, метод і валідацію:
entrypoint(
route(session.add, '/:sid/items', { parent: session.base, method: RouteMethod.POST }),
filter(params(SessionParamsSchema), body(AddItemSchema)),
)
Бекенд приєднує обробник через elevate. Фронтенд додає поведінку свого екрана й викликає точку входу через ctx.entrypoint(session.add).call({ params, body }).
Маршрут і схема — спільний вихідний код. Окремого згенерованого API-клієнта в цьому патерні немає. Якщо змінюєш оголошення, все одно треба перевірити і місця виклику, і обробник. Спільні типи не вирішать, чи слід було дозволяти цю операцію.
У сервісів шлях так само прозорий. Фабрика створює сервіс, застосунок реєструє його під псевдонімом, а код отримує його через context.service('alias').
Я віддаю перевагу такому звʼязуванню, бо можу його прочитати. А в скільки разів це заощаджує токени порівняно з іншим фреймворком, я не вимірював, і цей приклад такої цифри не дає.

Збереження даних
Деморесурс має методи на зразок create, list і delete. Ресурси, що працюють із базою даних, мають той самий інтерфейс, тож обробники зберігають звичну форму.
Але перехід на базу даних від цього не стає справою одного пакета. Тобі ще знадобляться налаштування підключення, індекси, валідація й рішення щодо наявних даних. Правила доступу теж треба покрити тестами.
Для нової функції нотаток агентові корисно дати такий запит:
Додай нотатки, які зберігаються в MongoDB. Використай
@owlmeans/mongoі@owlmeans/mongo-resource. Оголоси схему й точки входу вsources/common, зареєструй ресурс і обробники вsources/api, а екран додай уsources/web. Дотримуйся настанов щодо ресурсів і повторного використання коду, встановлених у проєкті.
Тоді виклики ресурсу можуть бути такими:
const notes = context.resource<NotesResource>(RES_NOTES)
await notes.create({ id, text, createdAt })
const { items } = await notes.list({ criteria: { ... } })
Це фрагменти інтерфейсу, а не готовий застосунок. Псевдонім ресурсу, схему й підключення треба зареєструвати в проєкті.
Після зміни перезапусти застосунок і переконайся, що нотатка нікуди не зникла. Спробуй також некоректні вхідні дані й збій підключення. Якщо нотатки належать різним користувачам, перевір, що один користувач не може прочитати нотатки іншого.
Вебчастина побудована на shadcn UI і Tailwind. Документація shadcn пояснює підхід так: ти отримуєш вихідний код компонентів і працюєш із ним. У цьому проєкті агент може переглядати й редагувати цей код. А оцінити, якою вийшла взаємодія, все одно мусиш ти.
Настанови в пакетах
Червнева версія копіювала настанови в окремі каталоги для різних агентів. Згодом ми прибрали ці паралельні джерела. Тепер канонічні настанови проєкту лежать у .agents/, у корені є AGENTS.md, а де треба, і місток для Claude.
Пакети OwlMeans поширюють свої настанови через agent-meta/. Інсталятор читає ці метадані й записує навички для пакетів, які є в проєкті. Навичка для ресурсу може пояснити фреймворк, а от для чого потрібні твої нотатки, мають пояснити інструкції твого проєкту.
Після оновлення відповідних пакетів актуальна для цього розбору команда така:
npx @owlmeans/agent-skills@^0.1.18
Переглянь, що вивів інсталятор. Керовані файли з локальними правками можуть конфліктувати, а примусовий перезапис — це рішення щодо твоїх власних змін. Інсталятор призначений для проєктів-споживачів; у повʼязаних монорепозиторіїв фреймворку свій процес супроводу.

На ілюстрації — червнева структура каталогів. Для оновленого робочого процесу використовуй спільну структуру .agents, описану вище.
Ні AGENTS.md, ні формат Agent Skills не гарантують, що кожен інструмент автоматично завантажить кожен файл. Перш ніж покладатися на інструкції, перевір, як із ними працює інтеграція твого агента.
Що лишається тобі
create-app дає тобі каркас Common. OwlMeans додає довкола цього фундаменту конвеєр ролей розробки. Це різні способи почати роботу з тим самим фреймворком.
Команда не визначить за тебе модель даних, не протестує дозволи й не обслуговуватиме твій сервіс у виробничому середовищі. Успішна збірка свідчить про небагато: у цьому каркасі запускай bun run typecheck окремо від bun run build.
Я зробив цей каркас, щоб не повторювати початкове звʼязування. Мені лишається та частина, над якою й треба думати: чи доречна там ця функція й чи вона працює.
Уперше опубліковано 17 червня 2026 року. Переглянуто 15 жовтня 2026 року: тепер тут актуальні закріплені версії в командах і спільна структура настанов для агентів.