Розширення: свій розділ і свій агент кодом
Розширення — це ваш код усередині Helomi: сторінка (HTML + CSS + JavaScript) з'являється плиткою в «Власних розділах» (а перемикачем — пунктом лівого меню) і відкривається всередині програми, а агент (JavaScript, function run(input)) працює на сервері вручну, зі сторінки або за розкладом. Ядро Helomi ви не змінюєте: сторінка живе в ізольованому iframe, агент — в ізольованому рушії, і з даними обидва працюють лише через міст sg, тими самими маршрутами й правами, що й люди, тож сторінку не можна відрізнити від рідного розділу — лише стиль NeoHelomi.
На цій сторінці
Можливості
- Найпростіше — файлом розділу: дані + сторінка + агент одним файлом, який ШІ пише за статтею Розділ від ШІ, а людина перетягує в «+ Додати розділ» у «Власних розділах». Розширення — та сама сторінка й агент, що там встановлюються.
- Сторінка (адреса
/crm/x/ext/<slug>) в ізольованому iframe, з мостомsg.*; плитка — у галереї «Власні розділи», у меню зліва — перемикачем «У меню зліва» на плитці. - Якщо в розділу є свої дані (файл розділу з
data),sg.records.list/get/create/updateпрацює з ними без окремого дозволу. - Читання будь-якого розділу CRM у межах прав людини, яка відкрила сторінку; запис — лише інструментами з дозволів розширення.
- Власне сховище розширення (JSON).
- Агент на сервері: вручну, зі сторінки або за розкладом (не частіше ніж раз на 5 хвилин), без мережі й файлів.
- Кожна зміна — нова версія з описом; повернення будь-якої версії.
- Розширення пише людина в налаштуваннях або ШІ з правом творця.
1Налаштування
- Людина — Налаштування›Типи даних›Розширення«Налаштування → Типи даних → Розширення» (потрібен доступ до «Налаштувань CRM»): список розширень з автором («написав ШІ» для створених ШІ), «Нове розширення», редактор «Код сторінки» і «Код агента», «Плитка на сторінці /crm/x» (назва, іконка, опис), «Агент за розкладом, хвилин», «Що змінено», «Версії», «Запуски агента», «Інструкція для авторів (і для ШІ)» — ця стаття.
- ШІ-співробітник пише розширення лише з правом творця «Свої розширення (код)» у «Доступах» його пульта (видає адміністратор) і змінює лише свої розширення.
- Агент розширення працює від імені свого ШІ-співробітника («<назва> · агент»): його розділи, ліміти й «спочатку запитати» налаштовуються в пульті ШІ-співробітників.
2Створити розширення
extensions_guide— ця інструкція і перелік інструментів.extensions_createзtitle,icon(folder, clipboard, briefcase, calendar, tasks, documents, products, warehouse, deliveries, clients, structure, star, flag, bulb, gift, card, receipt, map, phone, mail, camera, scale, flask, spark, book),page_htmlі/абоagent_js,permissions(інструменти ЗАПИСУ, які сторінці дозволено: напр.["deals_create", "tasks_create"]; читати сторінка може й так),schedule_minutes(агент за розкладом, не частіше ніж раз на 5 хв),note— що зроблено.- Відкрийте результат:
/crm/x/ext/<slug>. Виправлення —extensions_update(кожна зміна — нова версія,extensions_rollbackповертає попередню). Агента перевіряйтеextensions_run— у відповіді результат,logsі помилка.
Людина робить те саме в Налаштування›Типи даних›Розширення«Налаштування → Типи даних → Розширення» → «Нове розширення» → «Створити»; відкрити сторінку — «Відкрити», плитка в «Власних розділах» або пункт меню зліва.
3Стиль NeoHelomi — обов'язково
У сторінку вже підключено шрифт Onest, токени --sg-* і базові класи sg-*. Не пишіть своїх кольорів, тіней, радіусів і рамок — лише var(--sg-…) і класи нижче. Без смайликів (іконки — sg.icon()), без градієнтів, без темних панелей, без браузерних alert/confirm (є sg.confirm, sg.toast).
- Шари. Тло дає програма. Ваш вміст — у листі
.sg-sheet(padding 20–24) → групи.sg-group(padding 14–16) → картки.sg-card/ рядки.sg-row. Не більше трьох рівнів. - Шапка сторінки.
<h1 class="sg-title">Назва</h1>+<span class="sg-muted">підзаголовок; справа — одна головна дія<button class="sg-btn sg-btn--black">. Чорне на екрані одне (головна дія або активна вкладка). - Кнопки: головна
.sg-btn.sg-btn--black; другорядні.sg-btn.sg-btn--whiteабо.sg-btn.sg-btn--line; дрібні —.sg-btn--sm. Кругла іконка-кнопка —.sg-circ(44 px) /.sg-circ.sg-circ--sm(34 px), всерединіsg.icon(...). - Вкладки й перемикачі:
.sg-tabsз.sg-tab(активна —.is-active, чорна пігулка); дрібний перемикач —.sg-segз кнопками (.is-activeбіла). - Форми:
.sg-field→<label>+.sg-input/select.sg-select/textarea.sg-input.sg-textarea; прапорець —input.sg-check. Поля 40 px заввишки, пігулки. - Таблиці:
.sg-table-wrap→table.sg-table(щільні рядки, липка шапка). Числа — клас.sg-num. - Статуси:
.sg-pill+ колір--blue | --violet | --green | --yellow | --red | --gray, дрібні —.sg-pill--sm. - Текст: заголовки
.sg-title/.sg-h2/.sg-h3; підпис групи.sg-cap(великі літери); другорядне.sg-muted,.sg-faint. Показники —.sg-kpiз<small>(підпис) і<b>(число). - Порожньо / завантаження:
.sg-emptyз одним реченням, що робити; скелет —.sg-skeleton. - Телефон: сторінка має працювати від 390 px: сітки —
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)), на@media (max-width: 768px)рядки таблиць → картки, кнопки й поля на всю ширину, зони торкання ≥ 44 px.
Свій CSS — у <style> вашої сторінки, з префіксом класів (.my-…) і лише значеннями var(--sg-…).
4Міст sg (сторінка)
Усе асинхронне (await). Помилка → throw Error з реченням українською.
| виклик | що робить |
|---|---|
sg.user | {id, name, admin} — хто відкрив сторінку |
sg.section | {slug, title, data_slug} — цей розділ і його дані |
await sg.records.list({q, stage, per_page}) / get(id) / meta() / kanban() / create({title, custom}) / update(id, {stage_key, custom}) | записи даних свого розділу (файл розділу з data); запис — без окремого дозволу |
await sg.read("/api/crm/deals", {q: "Петро", per_page: 20}) | читання будь-якого розділу CRM у межах прав цієї людини: угоди, клієнти, задачі, склад, фінанси, документи, доставки, власні розділи (/api/crm/x/<slug>) |
await sg.call("deals_create", {values: {...}}) | інструмент (ті самі, що в ШІ): читання — завжди, запис — лише з permissions розширення |
await sg.data.get(col, key) / set(col, key, value) / list(col) / del(col, key) | власне сховище розширення (JSON, до 64 КБ на запис) |
await sg.runAgent(input) | запустити агента цього розширення → {ok, result, error, logs} |
sg.navigate("/crm/deals/123") | перейти в розділ Helomi |
sg.toast("Збережено") | коротке повідомлення внизу |
await sg.confirm("Видалити?") | підтвердження в стилі програми → true/false |
sg.icon("plus", 18) | SVG-рядок фірмової іконки (вставляйте в innerHTML) |
Інструменти й їхні аргументи — extensions_guide.tools або describe_section. Основні: deals_list/get/create/update/ change_stage/close/add_item/add_note/add_task, clients_list/get/create/update/add_note, tasks_list/get/create/update, products_list/get, records_meta/list/get/create/update (власні розділи). Обов'язкові поля, воронки, доступи й журнал діють так само, як для людини.
5Агент (agent_js)
function run(input) { // input: {trigger: "schedule"} або те, що передала сторінка
var deals = sg.call("deals_list", { overdue: true, per_page: 50 });
deals.items.forEach(function (d) {
sg.call("deals_add_task", { deal_id: d.id, values: { title: "Нагадати клієнту" } });
});
sg.data.set("stats", "last", { count: deals.items.length });
sg.log("оброблено", deals.items.length);
return { processed: deals.items.length };
}У агента виклики синхронні (без await): sg.call, sg.data.get/set/list/delete, sg.log. Мережі, файлів, таймерів нема; 30 секунд і 300 викликів на прогін. Агент працює від імені свого ШІ-співробітника («<назва> · агент»): його розділи, ліміти й «спочатку запитати» (видалення, гроші, масові, відправки) — у пульті ШІ-співробітників. Розширень, агентів і розділів агент не створює.
6Приклад сторінки
<div class="sg-sheet my-page">
<header class="my-head">
<div><h1 class="sg-title">Прострочені угоди</h1><span class="sg-muted">де минув термін етапу</span></div>
<button class="sg-btn sg-btn--black" id="run">Нагадати всім</button>
</header>
<div class="sg-group"><div class="sg-table-wrap"><table class="sg-table"><thead><tr><th>Угода</th><th>Клієнт</th><th class="sg-num">Сума</th></tr></thead>
<tbody id="rows"><tr><td colspan="3" class="sg-empty">Завантаження…</td></tr></tbody></table></div></div>
</div>
<style>
.my-page { padding: 24px; display: grid; gap: 14px; }
.my-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
@media (max-width: 768px) { .my-page { padding: 16px; } .my-head .sg-btn { width: 100%; } }
</style>
<script>
async function load() {
const res = await sg.read("/api/crm/deals", { overdue: true, per_page: 50 });
document.getElementById("rows").innerHTML = res.items.length ? res.items.map((d) =>
`<tr><td><a href="#" data-id="${d.id}">${d.title || "#" + d.id}</a></td><td>${d.client?.company || ""}</td>` +
`<td class="sg-num">${d.total_amount ?? ""}</td></tr>`).join("") : `<tr><td colspan="3" class="sg-empty">Прострочених нема</td></tr>`;
}
document.addEventListener("click", (e) => { const a = e.target.closest("[data-id]"); if (a) { e.preventDefault(); sg.navigate("/crm/deals/" + a.dataset.id); } });
document.getElementById("run").onclick = async () => { const r = await sg.runAgent({}); sg.toast(r.ok ? "Готово" : r.error); load(); };
load();
</script>7Версії, відкат, запуск агента
- Кожне збереження — нова версія з приміткою «Що змінено»; «Версії» в налаштуваннях або
extensions_versionsпоказують історію, «повернути» —extensions_rollback. - «Запустити агента» на сторінці розширення («Дії з розширенням») або в налаштуваннях; результат, журнал
sg.logі помилка — у «Запуски агента» або у відповідіextensions_run. - «Код і версії» в «⋮» сторінки веде до налаштувань розширення.
Можливі помилки
| Що ви бачите | Чому | Що зробити |
|---|---|---|
| «Розширенню потрібен код сторінки або агента» | Порожнє розширення | Додайте page_html або agent_js |
| «Код агента має оголосити function run(input) { … }» | Нема функції run | Оголосіть function run(input) |
| «Код сторінки довший за … символів» / «Код агента довший за … символів» | Ліміт 400 000 / 120 000 символів | Скоротіть код |
| «Розклад — не частіше ніж раз на 5 хвилин» | Замалий інтервал | Вкажіть 5 хвилин або більше |
| «Невідомий інструмент у дозволах: …» | Такого інструмента нема | Візьміть назву з extensions_guide.tools |
| «Іконку обирають з набору: …» | Іконка не з переліку | Виберіть іконку з переліку в розділі 2 |
| «Міст читає лише розділи CRM (/api/crm/…), довідку й каталог» | sg.read на інший шлях | Читайте лише /api/crm/… |
| «Запис сховища більший за 64000 символів» / «У сховищі розширення вже 20000 записів» | Ліміти сховища | Розбийте дані або приберіть старі записи |
| «Розширення пише ШІ з правом творця «Свої розширення» …» | ШІ без права творця | Попросіть адміністратора видати право |
| «Розширення налаштовує людина з доступом до «Налаштувань CRM»» | Людина без доступу | Попросіть адміністратора |
Для ШІ-співробітників
Інструменти творця (потрібне право «Свої розширення (код)»):
| Інструмент | Що робить |
|---|---|
extensions_guide | СПОЧАТКУ ПРОЧИТАЙТЕ: ця інструкція і перелік інструментів для permissions |
extensions_list | Розширення організації (made_by — автор; змінювати можна лише свої) |
extensions_get | Моє розширення з кодом сторінки й агента |
extensions_create | Нове розширення: title, icon, page_html, agent_js, schedule_minutes, permissions, note |
extensions_update | Змінити моє розширення (нова версія; note — що змінилося) |
extensions_versions | Версії мого розширення |
extensions_rollback | Повернути версію |
extensions_run | Запустити агента: результат, logs, помилка |
extensions_delete | Видалити моє розширення. Спочатку запитати (вид delete) |
Сторінки розширень відкривають люди; ШІ працює з даними через інструменти.
Чого не можна: ходити в інтернет зі сторінки (заборонено політикою безпеки), читати токени й паролі, змінювати ядро Helomi, налаштування організації, чужі розширення й агентів людей. Порушення стилю (свої кольори, смайлики, друге чорне) вважається помилкою — виправляйте наступною версією.
Додаткова інформація
- Пов'язані статті: Розділ від ШІ: файл розділу, Власні розділи, ШІ-творець (
ai-creator.md), ШІ-співробітники (ai-employees.md).
Цю саму статтю читають ШІ-співробітники Helomi: help("extensions")