qa.log
66 subscribers
18 photos
8 videos
45 links
Feedback -> @wlasadd
Download Telegram
qa.log
🆕 Возможно, многие уже видели новость о том, что JetBrains добавили Codex в свою IDE Использовать Codex возможно с подпиской JetBrains AI и своей учетной записью ChatGPT (или ключом API OpenAI). Никаких дополнительных приседаний - доступ прямо из чата AI…
Commit contains problems

При открытии вкладки Code Analysis для изучения проблем коммита бегущей строкой возникает потребность в предложении AI-ассистентом моментальных in-place правок.

🔹Топ-1 Feature Request🔹

Видим проблему на строке 10: “Переменная нигде не используется” и мгновенно по кнопке с предложением стереть такую переменную избавляемся от неисправностей коммита.
Please open Telegram to view this post
VIEW IN TELEGRAM
🖥 Новая задача Valid Palindrome

ОПИСАНИЕ:
Фраза является палиндромом, если после преобразования всех заглавных букв в строчные и удаления всех неалфавитно-цифровых символов она читается одинаково в прямом и обратном направлении. Алфавитно-цифровые символы включают буквы и цифры.

Для заданной строки s верните true, если она является палиндромом, или false в противном случае.


ПРИМЕРЫ 🔽:

Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.

Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.

Input: s = " "
Output: true
Explanation: s is an empty string "" after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.
Please open Telegram to view this post
VIEW IN TELEGRAM
В рейтинге опенсорсных проектов github набирает популярность новый инструмент - openclaw

👍 400к звезд на независимом бесплатном проекте, 65к ответвлений и более 5к мр-ов в репозиторий.

OpenClaw — это шлюз для самостоятельной установки, который связывает ваши любимые мессенджеры — WhatsApp, Telegram, Discord, iMessage и другие — с ИИ-агентами для программирования, такими как Pi. Вы запускаете один процесс шлюза на своем компьютере (или сервере), и он становится мостом между вашими мессенджерами и всегда доступным ИИ-помощником.


На деле openclaw - это карманный ai-ассистент, который не просто дает ответы на вопросы, заданные в чате, а решает вполне интеграционные задачи взаимодействия с большим количеством сервисов.

Теперь, чтобы, к примеру, создать встречу с коллегами с текстовым и визуальным сопровождением, отправить приглашение на почтовые ящики и уведомить о ней в публичном рабочем канале достаточно “входа” через одну из предлагаемых точек: мессенджер, веб-клиент или ios-приложение и короткой команды, выражающей суть.
Далее инструмент самостотельно проведет многоступенчатую интеграцию и уведомит о результате.

Подробное описание фичей тут.

Независимо от выбранного пути, при первоначальной настройке конфигурируются:

• Поставщик модели и аутентификация — ключ API, OAuth или токен настройки для выбранного поставщика
• Рабочая область — каталог для файлов агента, шаблонов начальной настройки и памяти
• Шлюз — порт, адрес привязки, режим аутентификации
• Каналы (опционально) — WhatsApp, Telegram, Discord и другие
• Демон (опционально) — фоновый сервис, благодаря которому шлюз запускается автоматически


Варианты подключений описаны тут в разделе Quick Start через one-liner/nmp и напрямую macOS установочник.
Please open Telegram to view this post
VIEW IN TELEGRAM
RE-usable Claude Code Skills для автотестирования

Чаты уходят в прошлое, и на замену им приходят полноценные агенты со скиллами. Это вызвано в первую очередь возможностью экономии ресурсов на поддержание контекста.

Создаем агента под генерацию данных для автотестов, наполняем контекст короткой понятной паттерн-инструкцией и на выходе получаем структурировано обработанные тестовые объекты, генерация которых не затребовала обработку всего контекста проекта, а работала в рамках предоставленных шаблонов.

Далее создаем скилл с инструкцией по сборке таких данных в паттернизированные тестовые сценарии с соблюдением иерархии. Далее - скилл под рефакторинг. Далее - обработка ошибок. И так далее.

Теперь работа с кодом может выглядеть, как короткий императив к агентам, который, используя экономичный контекст инструкций, соберет подходящее решение, не затратив на это много ресурсов и времени.

Шаблоны скилов могут быть универсальными и дополняемыми в соответствии с потребностями.

Клонируем к себе базовый набор инструментов (в моем случае под Kotlin & JUnit5) из моего репозитория на github и адаптируем под свои нужды.
👍1
qa.log
RE-usable Claude Code Skills для автотестирования Чаты уходят в прошлое, и на замену им приходят полноценные агенты со скиллами. Это вызвано в первую очередь возможностью экономии ресурсов на поддержание контекста. Создаем агента под генерацию данных для…
upd: git commit -m "Add event-streaming skill”

Добавлена логика по работе с распределенными системами и асинхронным получением данных от брокеров.

Хочется не просто вызывать метод и проверять ответ, а убедиться, что нужное событие появилось в брокере с правильными данными в правильный момент. Это retry-логика, сравнение с допуском по времени, отдельная обработка генерируемых полей.

Скилл задаёт универсальную архитектуру слоями Test → Steps → Manager → Client, паттерн checkEvent прямо в тест-классе, шаблоны createExpectedEvent и compareEvents с готовой логикой сравнения. Секции [НАСТРОИТЬ] под брокер, доменную модель, статусы.
Работает с любым стеком на JVM: Kafka, RabbitMQ, любой другой брокер. Проект на Kotlin + JUnit5, но паттерны переносятся на Java без изменений.

Доработка в репо https://github.com/wlasadd/claude-autotest-skills
👍1
Claude skills с инструкциями по прикладной работе с автоматизацией могут быть так же дополнены шаблонами по непосредственной экономии памяти.

GitHub - JuliusBrussee/caveman

- решает проблему лимитов токенов на лету.

Храним отдельные инструкции по шаблонизированию проекта + caveman скилл по оптимизации наполнения контекста. На выходе получаем агента, который не только структурировано, но и дешево воспроизводит и дополняет логику проекта.
Новая задача Valid Palindrome

ОПИСАНИЕ:
Фраза является палиндромом, если после преобразования всех заглавных букв в строчные и удаления всех неалфавитно-цифровых символов она читается одинаково как в прямом, так и в обратном направлении. К алфавитно-цифровым символам относятся буквы и цифры.

Для заданной строки s верните true, если она является палиндромом, иначе верните false.


ПРИМЕРЫ:

Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.

Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.

Input: s = " "
Output: true
Explanation: s is an empty string "" after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.
СОБЕСЕДОВАНИЕ:

Раздел: Сериализация, десериализация
Вопрос: Популярные библиотеки и причины их выбора.
Jackson - библиотека, по умолчанию интегрированная во многие HTTP-клиенты, популярна для работы с JSON в Kotlin.

• Умеет автоматически сериализовать и десериализовать data class по именам полей
• Поддерживается в большинстве API-клиентов (Feign, RestTemplate и др.)
• Позволяет кастомизировать процесс через аннотации

Аннотации Jackson:
@JsonProperty - задаёт явное имя ключа в JSON:

data class Product(
val productId: UUID,
@JsonProperty("brandInfo")
val brand: Brand?
)
// JSON: { "brandInfo": "Nike" }


@JsonIgnore - исключает поле из сериализации и десериализации. Поле присутствует в объекте, но не попадает в JSON:

data class Product(
val productId: UUID,
@JsonIgnore
val brand: Brand?
)
// brand не попадёт в JSON


@JsonInclude - указывает какие поля включать в JSON. Удобно для отправки «чистых» запросов без лишних полей:

@JsonInclude(JsonInclude.Include.NON_NULL)
data class Pet(
val name: String,
val description: String? = null
)
// если description == null — поле не попадёт в JSON


@JsonProperty на enum - переименовывает конкретные константы в JSON:

enum class Status {
@JsonProperty("available") AVAILABLE,
@JsonProperty("pending") PENDING,
@JsonProperty("sold") SOLD
}
// JSON вернёт "available" вместо "AVAILABLE"


@JsonValue - говорит Jackson использовать значение конкретного поля для сериализации всего объекта. В отличие от @JsonProperty на константах, здесь значение берётся из поля, переданного в конструктор:

enum class Status(@JsonValue val value: String) {
AVAILABLE("available"),
PENDING("pending"),
SOLD("sold")
}
// Jackson сериализует enum как строку "available", беря значение из поля value


К популярным библиотекам относятся так же: Kotlinx Serialization, Moshi, Gson.
Вектор разработки все больше смещается с написания кода в сторону умения работать с настройками конфигов агентов.

Claude Code, Codex, Cursor и тп - успешные коммерческие продукты, которые уже успели себя зарекомендовать.

Попробуем разобраться с мультимодельными опенсорсными провайдерами, например, opencode (установка описана внутри), и настроить конфиг для него.

Что обещано:
Что такое OpenCode?
OpenCode — это агент с открытым исходным кодом, который помогает писать код в терминале, IDE или на рабочем столе.

[*] Поддержка LSP Автоматическая загрузка подходящих LSP для LLM
[*] Многосессионность Параллельный запуск нескольких агентов в рамках одного проекта
[*] Поделиться ссылкой Поделитесь ссылкой на любую сессию для справки или отладки
[*] GitHub Copilot Войдите через GitHub, чтобы использовать свою учетную запись Copilot
[*] ChatGPT Plus/Pro Войдите через OpenAI, чтобы использовать свою учетную запись ChatGPT Plus или Pro
[*] Любая модель Более 75 поставщиков LLM через Models.dev, включая локальные модели
[*] Любой редактор Доступно в виде интерфейса терминала, настольного приложения и расширения IDE


Минимальные требования:
- opencode.json - машинная конфигурация инструмента. Здесь: какие модели использовать, какие MCP-серверы подключить, какие права давать агенту, какие под-агенты создать. Это аналог settings.json в Claude Code.
- AGENTS.md - текстовые инструкции для модели на естественном языке. Это системный промпт проекта: правила кодстайла, поведение, формат ответов. Аналог CLAUDE.md.

Далее разберем каждый из файлов подробно и достаточно для первого запуска.
Блок 1. opencode.json: верхнеуровневые параметры

По ссылке расположен универсальный конфиг-шаблон, предоставляемый самим провайдером для более гибкой настройки.

Это поля на корневом уровне объекта, которые задают общее поведение инструмента до того, как дело дойдёт до моделей и агентов.


"$schema": "https://opencode.ai/config.json", // схема конфигурации
"lsp": true, // включает Language Server Protocol. opencode поднимает языковые серверы (для Kotlin/Java и т.д.) и за счёт этого «видит» ошибки компиляции, типы, определения символов.
"formatter": true, // разрешает авто-форматирование изменённых файлов через настроенные форматтеры
"default_agent": "plan", // какой из под-агентов запускается по умолчанию при старте сессии. plan - это read-only агент без права менять файлы и запускать команды.
"shell": "/bin/zsh", // какой shell использовать для bash-команд
"logLevel": "INFO", // уровень логирования самого opencode. INFO - стандартный
"share": "disabled", // запрещает шаринг сессий (выгрузку диалога в облако opencode по ссылке)
"autoupdate": "notify", // при выходе новой версии opencode только уведомляет, но не обновляется сам
"snapshot": true, // включает снапшоты состояния файлов перед изменениями, чтобы можно было откатить правки агента
Блок 2. opencode.json - providers, model, small_model, disabled_providers

Это сердце конфига: какие LLM использовать. Тут две связанные части - отключение «чужих» провайдеров и подключение своих, внутренних.

disabled_providers:

"disabled_providers": [ // opencode «из коробки» знает кучу провайдеров (Anthropic, OpenAI, Google, OpenRouter и тп. Это нужно, чтобы агент не мог случайно уйти во внешний публичный провайдер (данные не должны утекать наружу); чтобы в списке выбора моделей остались только свои, внутренние модели
"openrouter",
"opencode",
"anthropic",
"openai",
"github-copilot",
"google"
],


provider:

"provider": {
"": { // имя провайдера
"npm": "@ai-sdk/openai-compatible", // какой драйвер использовать - любой сервис с OpenAI-совместимым /v1 подключается этим драйвером
"name": "", // отображаемое имя провайдера в UI выбора
"options": {
"baseURL": "", // эндпоинт шлюза
"apiKey": "{env:YOUR_API_KEY}", // ключ не хранится в файле, а подставляется из переменной окружения. Синтаксис {env:ИМЯ} - это подстановка opencode. Так конфиг безопасно коммитить в git
"timeout": 300000, // общий таймаут запроса, 300 сек (5 мин)
"chunkTimeout": 120000 // таймаут между чанками стрима - защита от «зависания»
},
"models": { // массив моделей внутри провайдера
"": {
"name": "", // отображаемое имя
"tool_call": true, // модель умеет вызывать инструменты (без этого агент не сможет редактировать файлы/звать MCP)
"temperature": true // управление «фантазией» модели
}
}
},
"": { ... аналогично, ... }
}


model и small_model:

"model": "", // основная модель. Используется агентами по умолчанию
"small_model": "", // «дешёвая» модель для вспомогательных задач
Блок 3. opencode.json — mcp (Allure и Atlassian)

MCP (Model Context Protocol) - это способ дать агенту доступ к внешним системам через стандартизированные «серверы инструментов».

Умеет читать задачи из jira и их описание из confluence.


"mcp": {
"allure": { // TMS
"type": "remote", // уже где-то запущен, opencode просто ходит к нему по HTTP
"enabled": true,
"url": "http:…”, // адрес MCP-эндпоинта во внутренней сети
"oauth": false, // авторизация через OAuth не используется
"timeout": 30000
},
"atlassian": { // Jira, Conflueence и тп
"type": "local", // opencode сам запускает процесс на локальной машине
"enabled": true,
"command": [
"/opt/homebrew/bin/uvx",
"mcp-atlassian==0.21.1"
], // как запускать. uvx (из пакета uv, Python) скачивает и запускает пакет mcp-atlassian строго версии 0.21.1. Версия зафиксирована, чтобы поведение не менялось при апдейтах. Путь /opt/homebrew/bin/uvx - homebrew-установка на macOS
"environment": {
"CONFLUENCE_URL": "https:…, // внутренние адреса систем
"CONFLUENCE_PERSONAL_TOKEN": "{env:CONFLUENCE_TOKEN}", // токен в окружении
"JIRA_URL": "https:…”, // внутренние адреса систем
"JIRA_PERSONAL_TOKEN": "{env:JIRA_TOKEN}" // токен в окружении
},
"timeout": 30000
}
}
Блок 4. opencode.json — tools, experimental, watcher, tool_output, compaction

Это группа «технических» настроек: что агенту доступно из инструментов, как он управляет контекстом и за какими файлами следит.

tools:

"tools": {
"webfetch": false, // запрет на скачивание страниц по URL
"websearch": false // запрет на поиск в интернете
}


experimental:

"experimental": {
"batch_tool": true, // разрешает агенту вызывать несколько инструментов одним батчем (параллельно), а не строго по одному
"continue_loop_on_deny": true // при отклонении какого-либо вызова инструментом (например, запрет на правку), агент не падает и не прерывает сессию, а продолжает работу, учтя отказ
}


watcher:

"watcher": {
"ignore": [
"build/**", ".gradle/**", ".idea/**", "out/**", "target/**",
"node_modules/**", "src/test/resources/app/**",
"*.iml", "*.class", "*.jar", "*.log", "*.apk", "*.ipa", "*.app"
]
} // не засорять контекст и не реагировать на тысячи генерируемых файлов


tool_output:

"tool_output": {
"max_lines": 10000,
"max_bytes": 500000 // защита от того, чтобы гигантский вывод команды (например, лог сборки) не забил весь контекст модели
}


compaction:

"compaction": {
"auto": true, // сжимать автоматически при заполнении окна
"prune": true, // выкидывать устаревшие/ненужные куски
"tail_turns": 8, // последние 8 ходов диалога сохранять как есть, не сжимая
"preserve_recent_tokens": 24000, // гарантированно беречь ~24k токенов недавнего контекста от сжатия
"reserved": 8000 // резерв токенов под служебные нужды/ответ
}
Блок 5. opencode.json - permission (глобальные права)

Определяет, что агент может делать сам, что - только с твоего разрешения, а что - запрещено полностью.


"permission": {
"read": "allow",
"list": "allow",
"glob": "allow",
"grep": "allow",
"edit": "ask",
"bash": {
"git status": "allow",
"git diff": "allow",
"git log*": "allow",
"ls": "allow",
"pwd": "allow",
"rg *": "allow",
"find *": "ask",
"./gradlew *": "ask",
"rm *": "deny",
"kubectl delete*": "deny",
"git push*": "deny",
"git reset --hard*": "deny",
"docker system prune*": "deny"
},
"webfetch": "deny",
"websearch": "deny",
"external_directory": "ask",
"question": "allow",
"todowrite": "allow",
"atlassian_jira_*": "ask",
"atlassian_jira_get_*": "allow",
"atlassian_jira_search*": "allow"
}


Три значения:
• "allow" (без спроса),
• “ask" (спросить),
• "deny" (запретить наглухо).


Логика всего блока:
- читать — свободно;
- менять файлы — только с подтверждением;
- деструктив — запрещён намертво;
- внешние системы — читать можно, писать только с подтверждением;
- запрет дублируется и на уровне tools, и на уровне permission.
Блок 6. opencode.json - agent (plan / build / reviewer)

Переписывает под-агентов - три профиля поведения с разными правами и промптами.

plan - безопасный анализ:

"plan": {
"model": "",
"description": "Безопасный агент для анализа, планирования и объяснения кода без изменения файлов и запуска команд",
"temperature": 0.1, // почти детерминированный, минимум «фантазии»
"steps": 30, // максимум шагов (итераций инструментов) за один прогон
"permission": {
"edit": "deny",
"bash": "deny" // вообще не может менять файлы и запускать команды. Чистый read-only режим
},
"prompt": "Всегда отвечай на русском... Анализируй задачу, код и архитектуру без изменения файлов. Давай краткий план, риски и рекомендуемый минимальный вариант решения." // личная инструкция именно этому агенту
}


build - рабочий агент:

"build": {
"model": "",
"description": "Основной рабочий агент для изменения кода, рефакторинга, исправления ошибок...",
"temperature": 0.2,
"steps": 30,
"permission": {
"read": "allow", "list": "allow", "glob": "allow", "grep": "allow",
"edit": "ask",
"bash": {
"./gradlew *": "ask",
"git status*": "allow",
"git diff*": "allow",
"ls*": "allow",
"rg *": "allow",
"pwd": "allow"
}
},
"prompt": "Всегда отвечай на русском... Перед изменением кода сначала изучи существующую архитектуру. Предпочитай минимальные безопасные изменения. Не добавляй новые библиотеки без явной необходимости."
}


reviewer - ревью изменений:

"reviewer": {
"mode": "all",
"description": "Агент для ревью изменений в ветке: анализирует git diff, ищет риски в Kotlin-автотестах и не изменяет файлы",
"model": "",
"temperature": 0.1,
"steps": 40,
"prompt": "Всегда отвечай на русском... Проводи ревью изменений относительно master. Используй git-команды для анализа diff. Не изменяй файлы. Разделяй замечания на: Критично, Важно, Можно улучшить...",
"permission": {
"read": "allow", "list": "allow", "glob": "allow", "grep": "allow",
"edit": "deny",
"task": "deny",
"bash": {
"rg *": "allow",
"git status*": "allow", "git diff*": "allow", "git log*": "allow",
"git branch*": "allow", "git rev-parse*": "allow",
"git merge-base*": "allow", "git show*": "allow", "git ls-files*": "allow"
}
}
}
Что касается второй части работы с opencode - AGENTS.md: существует огромное множество предзаполненных шаблонов инструкций для агентов в сети.

Можно использовать такой вариант wlasadd/claude-autotest-skills, а можно самостоятельно попросить подключенного агента изучить проект и сагрегировать некий набор шаблонов и практик, уже принятых за образец, и двигаться далее в том же стиле.
qa.log
Вектор разработки все больше смещается с написания кода в сторону умения работать с настройками конфигов агентов. Claude Code, Codex, Cursor и тп - успешные коммерческие продукты, которые уже успели себя зарекомендовать. Попробуем разобраться с мультимодельными…
Не одним конфигурационным файлом для использования AI-агентов единым - попробуем создать свой подключаемый mcp-сервер на примере опенсорсного продукта rocket.chat вкупе с соответсвующим файлом-инструкцией AGENTS.md

rocket.chat - мессенджер, первый неструктурированный слой, в котором можно получить сообщение/тред с “проблемой”, ссылками на требования и прогоны тестов с ошибками. И не вникать в содержимое многочисленных рассуждений коллег самостоятельно.

Какой результат мы можем получить при условии такого сервера в связке с прочими mcp (например, allure, atlassian (jira, confluence, и тп)).
1. Читай. По ссылке/артефакту вызови getThread/getMessageContext и собери связное нейтральное описание (кто, что, шаги воспроизведения, договорённости).
2. Дедуплицируй до создания. Перед заведением задачи проверь, нет ли уже похожего тикета в таск-трекере и не помечен ли тред как обработанный. Не плоди дубли.
3. Верифицируй и обогащай. Если доступны MCP системы тестирования / базы знаний — подтяни подтверждающие прогоны и релевантный регламент с требованиями; добавь ссылки на них.
4. Фиксируй со ссылкой назад. При создании задачи всегда вставляй обратный permalink на исходный тред, плюс ссылки из шага 3.
5. Замыкай контур (write-back) — только с подтверждением. Ответ в тред / маркер «обработано» делает результат видимым в чате.

Поскольку вносимые изменения необратимы и «наружу», запрашивается явное подтверждение пользователя перед любой записью. Сам rocketchat-mcp write-back не выполняет — запись идёт через соответствующий инструмент или человеком.

Более подробно Цикл разработки как замкнутый контур MCP описан тут. Берем готовый репозиторий mcp-мессенджера rocketchat-mcp и пробуем.
Классический релиз держится на негласном допущении: поведение системы живёт в коде сервиса. Поэтому мы версионируем код - теги, чарты, образы.
С появлением агентов работа над проверкой работоспособности версий сервисов становится не просто недоутилизированной, но и архаичной.

Кроме того, из-за новизны тренда и отсутствия систематизации наблюдается увеличение числа самописных вариантов инстуркций для агентов и сабагентов.

Все это наталкивает на мысль о необходимости унификации и принятии нового стандарта в отношении работы с агентами, а так же - в восприятии новой парадигмы работы над продуктом, где код больше не является предметной областью.

Выход: оркестрация - метазвено, которое само код не пишет, а декомпозирует задачу, делегирует субагентам, создаваемым на лету; а те, в свою очередь - обращаются к внешним mcp-серверам, библиотекам скиллов и RAG-ам, на версионность которых и смещается фокус.
qa.log
Классический релиз держится на негласном допущении: поведение системы живёт в коде сервиса. Поэтому мы версионируем код - теги, чарты, образы. С появлением агентов работа над проверкой работоспособности версий сервисов становится не просто недоутилизированной…
Собираем агента-оркестратора, подключаем к нему mcp-сервер и библиотеку со скиллам той или иной версии в качестве шаблона/каркаса одного из новых звеньев разработки.

Отдаем задачу и получаем готовое решение, перенаправляя усилия на создание дата-сетов, сценариев и аналитики под тестирование версий теперь уже серверов и библиотек.

И замыкаем более верхнеуровневый новый цикл работы над продуктом.

Это больше не инжиниринг, не тестирование, не архитектура в том виде, в котором это существовало ранее. И не систем дизайн, поскольку сама система изменилась.

Closed box -> Shift Right