HelomiWIKI

Розділ від ШІ: файл розділу

Файл розділу — один файл, яким ШІ (ваш ШІ-співробітник або будь-який чат: Claude, ChatGPT, Gemini) описує цілий новий розділ Helomi: записи з полями й етапами, власний вигляд сторінки і логіку, що працює сама. Людина перетягує файл у прозорий квадрат «+ Додати розділ» у «Власних розділах» (або ШІ-співробітник встановлює його сам), перевіряє, що буде створено, і вмикає розділ у лівому меню. Ця стаття — повна інструкція для ШІ: дайте її своєму ШІ разом з описом розділу, який потрібен.

21 хвОновлено 25.10.2026
Markdown для ШІ
На цій сторінці

Можливості

  • Один файл — увесь розділ: дані (поля, етапи, що є в картці, передача в інші розділи), сторінка (HTML + CSS + JS) і агент (JS за розкладом).
  • Файл .json (пакет) або один .html (сторінка, а опис і дані — у блоці <script id="sg-section">).
  • Перевірка до встановлення: що буде створено, помилки, зауваги стилю. Нічого не пишеться, доки людина не натисне «Встановити».
  • Повтор того самого файлу не створює дубль: пропонується «Оновити» наявний розділ.
  • Оновлення не видаляє даних: поля додаються й змінюються, записи лишаються; код — нова версія з поверненням попередньої.
  • Розділ можна вивантажити тим самим файлом (⋯Файл розділу«⋯ → Файл розділу»), дати ШІ доробити й завантажити назад.
  • ШІ-співробітник з правом творця встановлює файл сам; у меню зліва розділ ставить людина.

1Налаштування: отримати розділ від ШІ

  1. НалаштуванняТипи данихВласні розділи«Налаштування → Типи даних → Власні розділи». Тут галерея ваших розділів і прозорий квадрат «+ Додати розділ».
  2. Натисніть «Інструкція для ШІ» — завантажиться ця стаття файлом .md. Або «+ Додати розділ» → «Скопіювати завдання для ШІ» — у буфер ляже готове завдання.
  3. Дайте інструкцію своєму ШІ й опишіть розділ: що зберігати (поля), які етапи, що показувати, що робити самому (нагадування, підрахунки). Наприклад: Зроби розділ "Ремонти": пристрій, тип ремонту, вартість, етапи ПрийнятоДіагностикаГотово, сторінка з показниками і таблицею, щодня нагадувати про ремонти, що застрягли«Зроби розділ "Ремонти": пристрій, тип ремонту, вартість, етапи Прийнято → Діагностика → Готово, сторінка з показниками і таблицею, щодня нагадувати про ремонти, що застрягли».
  4. ШІ віддає файл <ім'я>.sgsection.json (або .html). Збережіть його.
  5. Перетягніть файл у квадрат «+ Додати розділ» (або натисніть на квадрат → «Вибрати файл»). Відкриється перевірка: що буде створено, зауваги, помилки.
  6. «Показати в меню зліва» (і відділ меню) → «Встановити». Розділ з'явиться плиткою в галереї й у лівому меню.

ШІ-співробітник з правом творця «Свої розділи» (дані) і «Свої розширення (код)» (сторінка, агент) робить кроки 3–6 сам інструментами (див. «Для ШІ-співробітників»); людина лише вмикає «У меню зліва».

2Як влаштований розділ: дані, вигляд, логіка

шару файліщо даєколи потрібен
Даніdataзаписи з полями, етапами, відповідальним, клієнтом, нотатками, файлами; список, дошка, картка, імпорт/експорт, доступ, records_* для ШІрозділ щось зберігає (ремонти, заявки, автопарк, проєкти)
Виглядpageсвоя сторінка в ізольованому вікні: показники, таблиці, форми, калькулятор, дашборд з кількох розділівпотрібен вигляд, якого нема у стандартному списку
Логікаagentfunction run(input) вручну, зі сторінки або за розкладом (не частіше ніж раз на 5 хв)щось має відбуватися саме: нагадування, підрахунки, перенесення між розділами

Можна будь-яку комбінацію. Лише data — розділ конструктора (той самий, що створюють вручну). data + page — свій вигляд над своїми записами (найчастіше). Лише page — сторінка-звіт, що читає інші розділи. agent без сторінки в меню не ставиться.

Як розділ працює з рештою Helomi: усе — тими самими маршрутами й перевірками, що й у людини. Обов'язкові поля, доступи, журнал змін, тригери спрацьовують самі. Записати можна лише те, що дозволено: свої записи — завжди, інші розділи — лише інструментами з permissions. Код Helomi, налаштування компанії, права людей розділ не змінює.

3Формат файлу squaregram-section/1

{
  "format": "squaregram-section/1",
  "slug": "remonty",
  "title": "Ремонти",
  "icon": "flask",
  "description": "Ремонти техніки клієнтів: прийом → діагностика → готово",
  "menu": true,
  "menu_group": "",
  "note": "перша версія",
  "data": { "record_title": "Ремонт", "stages": [], "card": {}, "fields": [], "kanban_field": null, "rules": [] },
  "page": { "html": "<div class=\"sg-sheet\">…</div><style>…</style><script>…</script>" },
  "agent": { "js": "function run(input) { … }", "schedule_minutes": 1440 },
  "permissions": ["tasks_create"]
}

3.1. Верхній рівень

полеобов'язковещо це
formatтакзавжди squaregram-section/1
titleтакназва розділу в меню й галереї: «Ремонти» (множина)
slugнікоротке ім'я в адресі: латиниця, цифри, _, до 14 символів (remonty). Без нього — з назви
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. Інша — буде folder
descriptionнідля чого розділ — бачать люди й ШІ
menuніпропозиція поставити в ліве меню (типово true); вирішує людина при встановленні
menu_groupнівідділ лівого меню, як він називається в меню («Відділ продажу»); порожньо — верхній список
noteніщо змінено в цій версії (журнал версій)
dataні*дані розділу (3.2)
pageні*сторінка (3.3)
agentні*агент (3.4)
permissionsніінструменти ЗАПИСУ в інші розділи, дозволені сторінці (3.5)

\* Хоча б одне з data, page, agent.

3.2. data — записи, поля, етапи

полещо це
record_titleназва одного запису: «Ремонт» (у кнопці «+ Ремонт»)
stagesетапи по порядку: [{"key": "new", "title": "Прийнято", "color": "blue"}, …, {"key": "done", "title": "Готово", "color": "green", "done": true}]. Кольори: blue, violet, green, yellow, red, gray. done: true — завершальний. Без поля — НовеВ роботіГотово«Нове → В роботі → Готово»; false або [] — без етапів
cardщо є в картці запису: {"responsible": true, "client": false, "deal": false, "brand": false, "notes": true, "files": true}
fieldsполя (нижче), до 60
kanban_fieldдошка за полем-списком (ключ поля select); без нього — за етапом
rulesпередача в інші розділи (нижче)

Поле: {"key": "device", "title": "Пристрій", "kind": "text", "required": true, "in_list": true, "on_create": true, "options": [], "block": "Додаткові поля"}.

  • key — латиниця, цифри, _, з літери, до 40; за ним сторінка й агент читають значення: record.custom.device.
  • kind — text, number, checkbox, date, time, select, multiselect, url, textarea. Для select потрібні options.
  • required — без значення запис не збережеться ні людиною, ні сторінкою, ні ШІ. in_list — колонка списку. on_create — поле у формі створення (обов'язкові — завжди).

Вбудовані поля запису є завжди: title (назва), stage_key (етап), responsible_id, client_id, deal_id, brand_id (якщо увімкнено в card). Окремо їх в fields не описують.

Правило передачі: {"title": "Видати клієнту", "when": "stage", "stage": "done", "target": "task", "values": {"title": "Видати клієнту: {title}"}, "link": false}.

  • when — create (новий запис) або stage (запис перейшов на етап stage).
  • target — deal (угода), client (клієнт), task (задача) або x_<slug> іншого власного розділу.
  • values — поле цілі → шаблон з полів запису: {id}, {title}, {stage}, {stage_key}, {responsible_id}, {client_id}, {custom.<ключ>}. Поля цілі: угода — title, client_id, funnel_id, stage_id, source_id, responsible_id, comment, deadline_at, important, custom.<ключ>; клієнт — company, person, phones, emails, source_id, main_responsible_id, comment, tags; задача — title, description, due_at, assignee_id, deal_id, client_id, priority, important.
  • link: true — прив'язати створену угоду чи клієнта до запису (якщо в card увімкнено deal / client).

3.3. page — сторінка

{"html": "…"} — розмітка, <style> і <script> разом, до 400 000 символів. Сторінка живе в ізольованому вікні (iframe без доступу до токена, cookies, мережі й інших сайтів). Оболонку (шрифт Onest, токени й класи NeoHelomi, міст sg) дає Helomi — <html>, <head>, шрифти й бібліотеки не підключайте. Зовнішні <script src>, fetch, XMLHttpRequest, WebSocket заблоковані: дані — лише через sg.

3.4. agent — логіка

{"js": "function run(input) { … }", "schedule_minutes": 60} — до 120 000 символів, обов'язково function run(input). schedule_minutes — запуск за розкладом (не частіше ніж раз на 5 хвилин); без нього — вручну («Запустити агента») і зі сторінки (sg.runAgent). Див. розділ 7.

3.5. permissions

Список інструментів ЗАПИСУ, які дозволено сторінці: ["tasks_create", "deals_add_note"]. Читати сторінка може й без них. Свої записи (sg.records.create/update) — без дозволу. Назви інструментів — з sections_package_guide.tools або describe_section. Основні: deals_create, deals_update, deals_change_stage, deals_add_note, deals_add_task, clients_create, clients_update, clients_add_note, tasks_create, tasks_update, records_create, records_update (записи інших власних розділів).

3.6. Один .html замість .json

Можна віддати один файл <ім'я>.html: сторінка — як є, а опис і дані — у блоці <script type="application/json" id="sg-section">{"title": "…", "icon": "…", "data": {…}, "permissions": […]}</script>, агент — у <script type="text/x-sg-agent" id="sg-agent">function run(input) { … }</script>. Обидва блоки при встановленні вирізаються зі сторінки. Повний документ (<!doctype html><html><head>…<body>…) теж приймається: беруться стилі з <head> і вміст <body>; <title> стає назвою, якщо її нема в описі. Обгортка ``` `json … ` ``` з чату теж приймається.

4Стиль NeoHelomi — обов'язково

Сторінка має виглядати як рідний розділ Helomi. Порушення стилю перевірка показує зауваженням — виправляйте наступною версією.

Головне: світле полотно дає програма; ваш вміст — шарами прозорого білого скла; тіней і рамок нема; великі радіуси; чорне на екрані одне (головна дія); червоне — лише увага (крапка, помилка); статуси — пастельні пігулки; іконки контурні; без смайликів; шрифт Onest (уже підключено).

Заборонено: свої кольори (#hex, rgb(), hsl()), свої тіні й рамки, градієнти, темні панелі, смайлики, alert/confirm/prompt, другий чорний елемент, зовнішні шрифти й бібліотеки. Колір, відступ, радіус — лише var(--sg-…).

4.1. Шари

шаркласдля чого
лист.sg-sheetодна робоча область сторінки (відступ 20–24, на телефоні 14)
група.sg-groupблок усередині листа: таблиця, форма, колонка дошки, панель фільтрів
картка.sg-cardокремий запис, показник; поле вводу вже має цей вигляд
рядок.sg-rowпласкі рядки списку всередині групи (фон з'являється при наведенні)
суцільне.sg-popвипадне меню, вікно поверх сторінки

Не більше трьох рівнів скла: лист → група → картка. Четвертий — рядок .sg-row.

4.2. Компоненти

  • Шапка: <h1 class="sg-title">Назва</h1> + <span class="sg-muted">підзаголовок</span>; праворуч одна головна дія <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> + input.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. Колір етапу запису — record.stage.color → sg-pill--<color>.
  • Текст: .sg-title (30/500), .sg-h2 (20/500), .sg-h3; підпис групи .sg-cap (великі літери); другорядне .sg-muted, .sg-faint.
  • Показники: .sg-kpi з <small> (підпис) і <b> (число); один на екрані може бути .sg-kpi--black.
  • Дошка: .sg-kanban → .sg-kanban-col (група-колонка) → .sg-cap з назвою етапу → .sg-card записів.
  • Порожньо й завантаження: .sg-empty з одним реченням, що робити; скелет — .sg-skeleton. Помилка — .sg-error.
  • Іконки: лише sg.icon("назва", розмір) — SVG-рядок у innerHTML. Назви: як у полі icon (3.1) і ще plus, minus, close, search, filter, edit, trash, check, chevron-down, chevron-right, refresh, download, export, import, copy, eye, calendar, clock, bell, link, pin, settings, deals, clients, chats, phone, mail, finance, coins, dashboard, agent, alert, more.

4.3. Токени (CSS-змінні)

Кольори тексту: --sg-ink (основний), --sg-ink-2, --sg-muted (підписи), --sg-faint. Чорне: --sg-black, текст на ньому --sg-on-black. Увага: --sg-attention. Скло: --sg-sheet, --sg-group, --sg-card, --sg-solid, розмиття --sg-blur, кромка --sg-glass-edge. Лінії: --sg-line (розділювач), --sg-outline (контур кнопки), --sg-outline-field, --sg-outline-focus. Пастелі статусів: --sg-pastel-blue|violet|green|yellow|red|gray і текст --sg-pastel-<колір>-ink. Радіуси: --sg-r-sheet 34, --sg-r-group 26, --sg-r-card 20, --sg-r-row 16, --sg-r-pill. Відступи: --sg-space-1…8. Розміри: --sg-ctl-h (40), --sg-circ (44), --sg-fs-title, --sg-fs-h2, --sg-fs-body, --sg-fs-sm, --sg-fs-xs, --sg-fs-cap. Шрифт: --sg-font.

4.4. Свій CSS і телефон

  • Свій CSS — у <style> сторінки, класи з власним префіксом (.rp-…), значення лише var(--sg-…). Розкладку (grid, flex) пишіть на своїх класах.
  • Телефон від 390 px: сітки grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); на @media (max-width: 768px) рядки таблиць стають картками, кнопки й поля — на всю ширину, зони торкання ≥ 44 px, без горизонтальної прокрутки сторінки.
  • Висоту вікна Helomi підлаштовує сам за вмістом — не задавайте height: 100vh і не робіть внутрішньої прокрутки сторінки.
  • Елемент з атрибутом hidden, якому ви задали свій display (grid, flex), браузер усе одно покаже — допишіть .ваш-клас[hidden] { display: none; }.

5Міст sg на сторінці

Усе асинхронне (await). Помилка → throw Error з реченням українською, показуйте її людині (sg.toast(e.message) або .sg-error).

викликщо робить
sg.user{id, name, admin} — хто відкрив сторінку (є після події sg:ready на document)
sg.section{slug, title, data_slug} — цей розділ; data_slug — його дані (є одразу)
await sg.records.meta()опис даних розділу: етапи, поля (key, title, kind, options, required), відповідальні
await sg.records.list({q, stage, responsible_id, client_id, archived, sort, dir, page, per_page, f_<ключ>})записи: {items, total, page, pages}; запис — {id, title, stage: {key, title, color, done}, stage_key, responsible: {id, name}, client, custom: {ключ: значення}, archived, created_at, updated_at}
await sg.records.get(id)картка запису: поля, нотатки, файли, журнал
await sg.records.kanban({q})дошка: колонки етапів (або поля-списку) з записами
await sg.records.create({title, stage_key, responsible_id, client_id, custom: {…}})новий запис (обов'язкові поля діють)
await sg.records.update(id, {stage_key, custom: {…}})змінити запис (журнал змін, правила передачі)
await sg.read("/api/crm/deals", {q: "Петро", per_page: 20})читання будь-якого розділу CRM у межах прав людини (розділ 6)
await sg.call("tasks_create", {values: {title: "…"}})інструмент (ті самі, що в ШІ): читання — завжди, запис — лише з 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-рядок фірмової іконки

6Що можна читати: адреси даних CRM

sg.read(шлях, параметри) читає лише /api/crm/…, /api/help/… і /api/ai/catalog; користувачі, ключі інтеграцій і секрети закриті. Права — того, хто відкрив сторінку: чого людина не бачить, сторінка теж не прочитає.

шляхщо повертаєпараметри
/api/crm/dealsугоди: id, title, stage, funnel, client {company, person}, total_amount, paid_amount, credit_amount, responsible, custom, ordered_at, updated_atq, funnel_id, stage_id, source_id, responsible_id, client_id, archived, overdue, date_from, date_to, page, per_page, sort, order
/api/crm/deals/{id}картка угоди з позиціями, оплатами, доставкою—
/api/crm/clientsклієнти: id, company, person, phones, emails, source, responsible, customq, source_id, responsible_id, tags, archived, page, per_page
/api/crm/tasksзадачі: id, title, status, due_at, assignee, deal, client, doneq, status, responsible_id, mine, overdue, due_from, due_to, deal_id, client_id
/api/crm/productsтовари: id, sku, title, price, cost, stock, reserved, freeq, category_id, in_stock, page, per_page
/api/crm/x/<slug>записи будь-якого власного розділуяк у sg.records.list
/api/help/<key>стаття WIKI—

Відповіді списків: {items, total, page, pages}. Не більше 200 на сторінку — для великих даних гортайте page.

7Агент: логіка за розкладом

function run(input) {                 // input: {trigger: "schedule"} або те, що передала сторінка через sg.runAgent
  var stuck = sg.records.list({ stage: "diag", per_page: 50 });
  stuck.items.forEach(function (r) {
    sg.call("tasks_create", { values: { title: "Ремонт застряг: " + r.title } });
  });
  sg.log("застрягли", stuck.items.length);
  return { stuck: stuck.items.length };
}
  • У агента виклики синхронні (без await): sg.records.list/get/meta/create/update, sg.call, sg.data.get/set/list/delete, sg.log; sg.section — як на сторінці.
  • У списках агента значення — короткі: stage — назва етапу, stage_key — ключ, client і responsible — імена, custom — словник полів.
  • Мережі, файлів, таймерів нема; 30 секунд і 300 викликів на прогін; без while(true).
  • Агент працює від імені свого ШІ-співробітника «<назва> · агент». Дані свого розділу він бачить одразу; інші розділи (задачі, угоди) людина відкриває йому в НалаштуванняКомандаШІ-співробітники<агент>Доступи«Налаштування → Команда → ШІ-співробітники → <агент> → Доступи». Видалення, гроші, масові дії й відправки чекають підтвердження людини.
  • Агент не створює розділів, агентів і розширень — лише працює з даними.

8Повний приклад: розділ «Ремонти»

Файл remonty.sgsection.json — дані, сторінка з показниками, формою й таблицею, агент щодня:

{
  "format": "squaregram-section/1",
  "slug": "remonty",
  "title": "Ремонти",
  "icon": "flask",
  "description": "Ремонти техніки клієнтів: прийом → діагностика → готово",
  "menu": true,
  "data": {
    "record_title": "Ремонт",
    "stages": [
      {"key": "new", "title": "Прийнято", "color": "blue"},
      {"key": "diag", "title": "Діагностика", "color": "yellow"},
      {"key": "done", "title": "Готово", "color": "green", "done": true}
    ],
    "card": {"responsible": true, "client": true, "deal": false, "brand": false, "notes": true, "files": true},
    "fields": [
      {"key": "device", "title": "Пристрій", "kind": "text", "required": true},
      {"key": "kind", "title": "Тип ремонту", "kind": "select", "options": ["Гарантія", "Платний"]},
      {"key": "price", "title": "Вартість", "kind": "number"}
    ],
    "rules": [
      {"title": "Видати клієнту", "when": "stage", "stage": "done", "target": "task",
       "values": {"title": "Видати клієнту: {title}"}, "link": false}
    ]
  },
  "page": {"html": "<div class=\"sg-sheet rp\"><header class=\"rp-head\"><div><h1 class=\"sg-title\">Ремонти</h1><span class=\"sg-muted\">техніка клієнтів у роботі</span></div><button class=\"sg-btn sg-btn--black\" id=\"add\">+ Ремонт</button></header><div class=\"rp-kpis\" id=\"kpis\"></div><form class=\"sg-group rp-form\" id=\"form\" hidden><div class=\"sg-field\"><label>Назва *</label><input class=\"sg-input\" name=\"title\" required placeholder=\"Ноутбук Петра\"></div><div class=\"sg-field\"><label>Пристрій *</label><input class=\"sg-input\" name=\"device\" required></div><div class=\"sg-field\"><label>Тип ремонту</label><select class=\"sg-select\" name=\"kind\"><option>Гарантія</option><option>Платний</option></select></div><div class=\"sg-field\"><label>Вартість, грн</label><input class=\"sg-input\" name=\"price\" type=\"number\" min=\"0\"></div><div class=\"rp-foot\"><button class=\"sg-btn sg-btn--white\" type=\"button\" id=\"cancel\">Скасувати</button><button class=\"sg-btn sg-btn--line\" type=\"submit\">Створити</button></div></form><div class=\"sg-group\"><div class=\"sg-table-wrap\"><table class=\"sg-table rp-table\"><thead><tr><th>Ремонт</th><th>Пристрій</th><th>Етап</th><th class=\"sg-num\">Вартість</th></tr></thead><tbody id=\"rows\"><tr><td colspan=\"4\"><div class=\"sg-skeleton\" style=\"height: 40px\"></div></td></tr></tbody></table></div></div></div><style>.rp { padding: 24px; display: grid; gap: 14px; } .rp-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; } .rp-kpis { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; } .rp-form { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; padding: 16px; } .rp-form[hidden] { display: none; } .rp-foot { display: flex; gap: 8px; align-items: end; } @media (max-width: 768px) { .rp { padding: 14px; } .rp-head .sg-btn, .rp-foot .sg-btn { flex: 1 1 auto; } .rp-table thead { display: none; } .rp-table tr { display: grid; grid-template-columns: 1fr auto; gap: 4px; padding: 10px 0; } .rp-table td { border: 0; padding: 0 10px; } }</style><script>function esc(v) { return String(v == null ? '' : v).replace(/[&<>\"']/g, function (c) { return {'&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;'}[c]; }); } async function load() { try { var r = await sg.records.list({ per_page: 100 }); var work = r.items.filter(function (x) { return !(x.stage && x.stage.done); }); var sum = work.reduce(function (s, x) { return s + (Number(x.custom.price) || 0); }, 0); document.getElementById('kpis').innerHTML = '<div class=\"sg-kpi\"><small>У роботі</small><b>' + work.length + '</b></div><div class=\"sg-kpi\"><small>Готово</small><b>' + (r.items.length - work.length) + '</b></div><div class=\"sg-kpi\"><small>Сума в роботі, грн</small><b>' + sum.toLocaleString('uk-UA') + '</b></div>'; document.getElementById('rows').innerHTML = r.items.length ? r.items.map(function (x) { return '<tr><td>' + esc(x.title) + '</td><td>' + esc(x.custom.device) + '</td><td>' + (x.stage ? '<span class=\"sg-pill sg-pill--sm sg-pill--' + esc(x.stage.color) + '\">' + esc(x.stage.title) + '</span>' : '') + '</td><td class=\"sg-num\">' + esc(x.custom.price) + '</td></tr>'; }).join('') : '<tr><td colspan=\"4\"><div class=\"sg-empty\">Ремонтів поки немає — натисніть «+ Ремонт»</div></td></tr>'; } catch (e) { sg.toast(e.message); } } var form = document.getElementById('form'); document.getElementById('add').onclick = function () { form.hidden = false; form.title.focus(); }; document.getElementById('cancel').onclick = function () { form.hidden = true; }; form.onsubmit = async function (ev) { ev.preventDefault(); try { await sg.records.create({ title: form.title.value, custom: { device: form.device.value, kind: form.kind.value, price: form.price.value ? Number(form.price.value) : null } }); form.reset(); form.hidden = true; sg.toast('Ремонт додано'); load(); } catch (e) { sg.toast(e.message); } }; load();</script>"},
  "agent": {"js": "function run(input) { var stuck = sg.records.list({ stage: 'diag', per_page: 50 }); stuck.items.forEach(function (r) { sg.call('tasks_create', { values: { title: 'Ремонт застряг: ' + r.title } }); }); sg.log('застрягли', stuck.items.length); return { stuck: stuck.items.length }; }", "schedule_minutes": 1440},
  "permissions": []
}

Агенту прикладу потрібен доступ до «Завдань»: після встановлення людина відкриває його в «Доступах» агента «Ремонти · агент».

9Те саме одним файлом .html

<div class="sg-sheet rp">
  <header class="rp-head">
    <div><h1 class="sg-title">Ремонти</h1><span class="sg-muted">техніка клієнтів у роботі</span></div>
    <button class="sg-btn sg-btn--black" id="add">+ Ремонт</button>
  </header>
  <div class="sg-group"><div class="sg-table-wrap"><table class="sg-table"><tbody id="rows"></tbody></table></div></div>
</div>
<style>.rp { padding: 24px; display: grid; gap: 14px; } .rp-head { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; }</style>
<script>
  sg.records.list({ per_page: 100 }).then(function (r) {
    document.getElementById("rows").innerHTML = r.items.map(function (x) { return "<tr><td>" + x.title + "</td></tr>"; }).join("");
  });
</script>
<script type="application/json" id="sg-section">
{"format": "squaregram-section/1", "slug": "remonty", "title": "Ремонти", "icon": "flask",
 "data": {"record_title": "Ремонт", "fields": [{"key": "device", "title": "Пристрій", "kind": "text", "required": true}]}}
</script>
<script type="text/x-sg-agent" id="sg-agent">
function run(input) { return { total: sg.records.list({}).total }; }
</script>

(У справжньому файлі екрануйте значення від людей, як esc() у розділі 8.)

10Оновити розділ

  1. «Власні розділи» → плитка → «⋯» → «Файл розділу» — завантажиться поточний файл.
  2. Дайте його ШІ: «Додай поле "Майстер" і колонку на сторінці».
  3. Перетягніть новий файл у квадрат «+ Додати розділ». Перевірка побачить, що такий розділ уже є, і запропонує «Оновити «Ремонти»» (або «Окремий розділ»).
  4. Що станеться: нові поля додаються, наявні змінюють назву й прапорці (тип поля зі значеннями не змінюється); поля, яких нема у файлі, лишаються — видаляє людина в «Типах даних»; записи не чіпаються; сторінка й агент — нова версія, попередню повертає НалаштуванняТипи данихРозширенняВерсії«Налаштування → Типи даних → Розширення → Версії».

11Меню зліва і доступ

  • Кожна плитка в галереї має перемикач «У меню зліва» і вибір відділу. Ставить і знімає лише людина з доступом до «Налаштувань CRM»; порядок пунктів — перетягуванням плиток. Кожен ще може сховати пункт лише для себе в «Моє меню».
  • Пункт бачать ті, кому розділ доступний: розділ з даними — галочка «x:<slug>», сторінка без даних — «xe:<slug>» (людям типово відкрито, ШІ — лише відкритий явно).
  • Окремого пункту «Розділи» в меню нема: розділ, якого нема в меню, відкривається з галереї, за адресою або кнопкою на панелі швидкого доступу.

12Чеклист ШІ перед тим, як віддати файл

  • [ ] format — squaregram-section/1, є title, slug латиницею до 14 символів, icon з набору.
  • [ ] Ключі полів латиницею; у select є options; обов'язкові — лише справді обов'язкові.
  • [ ] Сторінка: один .sg-sheet, групи .sg-group, одна чорна кнопка, лише var(--sg-…) і класи sg-*, без смайликів і своїх кольорів.
  • [ ] Значення від людей екрануються перед innerHTML.
  • [ ] Порожньо, завантаження (.sg-skeleton) і помилка (sg.toast(e.message)) продумані.
  • [ ] Сховані hidden елементи зі своїм display мають правило [hidden] { display: none; }.
  • [ ] Телефон 390 px: без горизонтальної прокрутки, кнопки на всю ширину, таблиця → картки.
  • [ ] Дані — лише через sg.records / sg.read / sg.call; запис в інші розділи — інструменти в permissions.
  • [ ] Агент: function run(input), без нескінченних циклів, до 300 викликів, розклад ≥ 5 хв.
  • [ ] Ви (ШІ-співробітник) спершу викликали sections_package_check і виправили помилки.

Можливі помилки

Що ви бачитеЧомуЩо зробити
«Файл не є JSON: …»Пошкоджений JSON (кома, лапки)Попросіть ШІ віддати файл заново або вставити як .html
«Не впізнаю файл: потрібен .json або .html»Інший форматПопросіть у ШІ файл розділу за цією інструкцією
«Назвіть розділ: поле title»Нема назвиДодайте title
«Файл нічого не створює…»Нема ні data, ні page, ні agentДодайте хоча б одне
«Поле «…» (список): потрібні варіанти options»select без варіантівДодайте options
«Поле «…»: тип має бути одним із …»Невідомий kindВізьміть тип з розділу 3.2
«Агент має оголосити function run(input) { … }»Нема функції runОголосіть її
«Розклад агента — не частіше ніж раз на 5 хвилин»Замалий schedule_minutes5 або більше
«Невідомий інструмент у permissions: …»Такого інструмента немаНазва з sections_package_guide.tools
«Розділ «…» уже є (e:…) — передайте update…»Такий розділ уже встановлено«Оновити» або «Окремий розділ»
«У меню зліва ставиться розділ зі сторінкою…»Лише агентДодайте сторінку або лишіть поза меню
«Дані розділу ШІ створює з правом творця «Свої розділи»» / «Сторінку й агента … «Свої розширення (код)»»У ШІ нема праваАдміністратор видає право в «Доступах» ШІ
«Цей розділ створив не цей ШІ…»ШІ оновлює чужий розділШІ змінює лише свої розділи
«Власні розділи налаштовує людина з доступом до «Налаштувань CRM»»Немає доступуПопросіть адміністратора
На сторінці «Немає доступу до розділу …»Галочку розділу закритоАдміністратор відкриває доступ
Зауваги «Стиль: …»Свої кольори, смайлики, alert, тініНе блокують; виправте наступною версією

Для ШІ-співробітників

Права: дані (data) — право творця «Свої розділи»; сторінка й агент — «Свої розширення (код)». Змінювати можна лише свої розділи. У меню зліва ставить людина.

ІнструментЩо робить
sections_package_guideСПОЧАТКУ ПРОЧИТАЙТЕ: ця стаття і живі довідники — іконки, типи полів, кольори етапів, інструменти для permissions
sections_galleryРозділи організації плитками: id (e:<n> — з кодом, t:<n> — конструктор), mine, дані, меню
sections_package_checkПеревірити файл без запису: values: {package: {…}} або {content: "<текст .json/.html>"}, update? → ok, actions, errors, warnings, conflict
sections_package_installВстановити: values: {package, file_name?, update?, as_new?} → {id, url, created, warnings}
sections_package_exportМій розділ файлом (tile_id) — доробити й встановити з update

Порядок: sections_package_guide → (sections_gallery, чи нема вже такого) → sections_package_check → виправити errors і по змозі warnings → sections_package_install → сказати людині: «Розділ «…» встановлено, увімкніть його в лівому меню: Налаштування → Типи даних → Власні розділи → «У меню зліва»». Після встановлення з даними — records_meta, records_list, records_create, records_update зі slug розділу. Конфлікт (conflict) — свій розділ оновлюйте update: "<id>", чужий не чіпайте: запропонуйте людині as_new.

Чого не робити:

  • Не вигадувати іконки, типи полів, назви інструментів — брати з sections_package_guide.
  • Не ставити update на чужий розділ і не видаляти поля через файл (поля, яких нема у файлі, лишаються).
  • Не писати своїх кольорів, смайликів, мережевих запитів; не просити людину вимкнути перевірки.

Додаткова інформація

Цю саму статтю читають ШІ-співробітники Helomi: help("section-package")