Режим !active

Last updated: 2026-10-14Маркеры, ограничения, переменные окружения, секреты, подключения и подстановка — конфиг, который разрешает себя сам.

Режим !active

Перенесено из репозитория формата — docs/spec/SPECIFICATION_RU.md, SYNX 3.7.4. Правки вносятся там.

3.1 Что это такое

По умолчанию .synx файл — это статичные данные. Просто ключи и значения, как JSON.

Но если в первой строке файла написать !active, файл превращается в живой конфиг — включаются:

  • Функции (:random, :calc, :env и др.)
  • Ограничения ([min:3], [type:int] и др.)
synx
!active

порт:env PORT
приветствие:random
  - Привет!
  - Здорово!

Без !active — маркеры :random, :calc и квадратные скобки [] полностью игнорируются. Парсер читает файл как обычный текст:

synx
// Нет !active — функции НЕ работают
порт:env PORT           // ключ = "порт:env", значение = "PORT" (просто строка)
приветствие:random       // ключ = "приветствие:random", значение = {} (объект)

💡 Это сделано для безопасности: статичный файл никогда не выполнит код, не полезет в переменные окружения и не запустит команды.


3.2 Полный список функций (:)

Функции записываются через двоеточие сразу после имени ключа: ключ:функция значение.


:random — случайный выбор

Выбирает один элемент из списка при каждом парсинге.

Равные шансы (без процентов):

synx
!active

боевой_клич:random
  - Время побеждать!
  - Ва-ха-ха!
  - За Синдикат!

Каждый элемент имеет шанс 33.3%.

Взвешенный рандом (с процентами):

synx
!active

// Проценты указываются после :random через пробел
// Порядок процентов соответствует порядку элементов
награда:random 70 20 10
  - Обычный сундук
  - Редкий сундук
  - Легендарный сундук

Здесь:

  • «Обычный сундук» выпадает с шансом 70%
  • «Редкий сундук» — 20%
  • «Легендарный сундук» — 10%

Правила процентов:

СитуацияПоведение
Процентов нетВсе элементы равновероятны
Сумма = 100Используются как есть
Сумма ≠ 100Автоматически нормализуются (пропорции сохраняются)
Процентов меньше, чем элементовОстаток делится поровну между элементами без процента
Процентов больше, чем элементовЛишние проценты игнорируются

Пример нормализации:

synx
!active

// 2 + 1 = 3, нормализация: ~66.7% и ~33.3%
тип:random 2 1
  - Воин
  - Маг

Пример неполных процентов:

synx
!active

// Первому — 80%, оставшиеся 20% делятся на два: по 10%
дроп:random 80
  - Ничего
  - Меч
  - Щит

:calc — вычисление выражения

Вычисляет арифметическое выражение. Может ссылаться на другие ключи по имени.

synx
!active

цена 100
налог:calc цена * 0.2
итого:calc цена + налог

Результат:

цена 100
налог 20 // < программа получит это значение
итого 120 // < программа получит это значение

Если брать файл .json

json
{
  "цена": 100,
  "налог": 20,
  "итого": 120
}

Поддерживаемые операции: +, -, *, /, % (остаток), (, ).

⚠️ Только арифметика. Никакого произвольного кода. Парсер использует безопасный вычислитель, не eval().


:env — переменная окружения

Подставляет значение переменной окружения системы.

synx
!active

порт:env PORT
домашняя_папка:env HOME

Если переменная не найдена — значение будет null.

С дефолтом (через :default):

synx
!active

порт:env:default:8080 PORT

Если PORT не задан в системе → вернётся 8080.

Текст остаётся текстом. Значение переменной приводится как любой литерал (8080 → int). Значения, которые лишь похожи на числа — 64-битные id, коды с ведущими нулями, — сохраняют текст с подсказкой (string) или ограничением [type:string]; то же правило действует для запасного значения :default:

synx
!active

discord_app_id[type:string]:env DISCORD_APP_ID
индекс(string):env:default:007 ZIP
api_key[type:string]:secret:env API_KEY

С 3.7.4 текст сохраняет и [type:string]. Раньше это делал только (string): значение сначала приводилось к числу, и [type:string] отвергал его с CONSTRAINT_ERR. Значение :secret удовлетворяет [type:string].


:alias — ссылка на другой ключ

Копирует значение другого ключа. Не дублирует данные — ссылается.

synx
!active

главный_админ alex@mail.com
почта_для_жалоб:alias главный_админ

Результат:

json
{
  "главный_админ": "[email protected]",
  "почта_для_жалоб": "[email protected]"
}

:secret — скрытое значение

Значение читается программой, но не выводится в логи, при freeze, при сериализации в JSON. Защита от случайной утечки.

synx
!active

api_key:secret sk-1234567890abcdef
db_password:secret P@ssw0rd!

При console.log(data), print(data), JSON.stringify(data) — покажет "[SECRET]".
Чтобы получить реальное значение, используйте метод .reveal():

javascript
// JavaScript / TypeScript
const key = data.api_key;          // SynxSecret объект
console.log(String(key));           // "[SECRET]"
console.log(JSON.stringify(key));   // '"[SECRET]"'
console.log(key.reveal());          // "sk-1234567890abcdef"  ← реальное значение
python
# Python
key = data['api_key']               # SynxSecret объект
print(key)                          # [SECRET]
print(key.reveal())                 # sk-1234567890abcdef  ← реальное значение

С 3.7.2 маска держится и для util.inspect / console.log целого объекта, spread и Object.entries (TypeScript), для {:?} (Rust) и для данных, которые получают WASM-плагины маркеров.

⚠️ Важно: Никогда не логируйте результат .reveal(). Этот метод предназначен только для передачи значения в API, подключения к БД и т.д.


:default — значение по умолчанию

Задаёт fallback, если основное значение пустое или не найдено. Чаще всего комбинируется с :env.

synx
!active

// Если переменная PORT не задана — будет 3000
порт:env:default:3000 PORT

// Просто значение по умолчанию (если значение = null или пусто)
тема:default dark

:unique — убрать дубликаты из списка

Оставляет только уникальные элементы.

synx
!active

теги:unique
  - экшн
  - рпг
  - экшн
  - симулятор
  - рпг

Результат: ["экшн", "рпг", "симулятор"]


:include — подключить другой файл

Вставляет содержимое другого .synx файла в текущий. Путь относительный от текущего файла.

synx
!active

// Подтянуть настройки базы данных из отдельного файла
database:include ./db.synx

Где db.synx:

synx
host localhost
port 5432
name mydb

Результат:

json
{
  "database": {
    "host": "localhost",
    "port": 5432,
    "name": "mydb"
  }
}

:geo — значение по геолокации / региону

Выбирает значение на основе региона пользователя (определяется по IP или системной локали).

synx
!active

валюта:geo
  - RU RUB
  - US USD
  - EU EUR

Эта функция требует поддержки в рантайме. Парсер передаёт текущий регион движку.


:template — интерполяция строк

Подставляет значения из объекта в строку с использованием {placeholders}. Поддерживает точечную нотацию для доступа к вложенным полям.

synx
!active

приветствие:template Привет, {имя}!
  имя Иван

сообщение:template Сервер {server.host}:{server.port}
  server
    host localhost
    port 8080

Результат:

json
{
  "приветствие": "Привет, Иван!",
  "сообщение": "Сервер localhost:8080"
}

:split — разделение строки на массив

Преобразует строку в массив, разделяя по указанному разделителю. Поддерживает ключевые слова: space, pipe, dash, dot, semi, tab.

synx
!active

теги:split space
  Python Django Flask

координаты:split pipe
  10|20|30

части:split dash
  section-one-two-three

Результат:

json
{
  "теги": ["Python", "Django", "Flask"],
  "координаты": ["10", "20", "30"],
  "части": ["section", "one", "two", "three"]
}

Если значение выглядит как число, оно автоматически приводится к числовому типу.


:join — объединение массива в строку

Преобразует массив в строку, соединяя элементы указанным разделителем. Поддерживает те же ключевые слова: space, pipe, dash, dot, semi, tab.

synx
!active

фраза:join space
  - Hello
  - World
  - 2024

путь:join dot
  - app
  - modules
  - config

Результат:

json
{
  "фраза": "Hello World 2024",
  "путь": "app.modules.config"
}


:ref — разрешение и цепочка

Разрешает ключ по имени и передаёт значение следующим маркерам в цепочке. Похож на :alias, но предназначен для цепочек с :calc и другими преобразованиями.

synx
!active

базовая_ставка 100
итого:ref:calc:*2 базовая_ставка

Результат: итого = 200. Сокращение :ref:calc:*2 базовая_ставка разрешает базовая_ставка → 100, затем вычисляет 100 * 2.


:i18n — интернационализация

Выбирает перевод на основе текущей локали. Дочерние ключи — коды языков; движок выбирает тот, что совпадает с options.lang (по умолчанию en).

synx
!active

приветствие:i18n
  en Hello
  ru Привет
  de Hallo

Плюрализация — добавьте имя поля-счётчика: :i18n:count_field

synx
!active

метка_предметов:i18n:количество
  en
    one {count} item
    other {count} items
  ru
    one {count} предмет
    few {count} предмета
    many {count} предметов
    other {count} предметов

Категории множественного числа по CLDR (en: one/other, ru: one/few/many/other). {count} подставляется значением указанного поля.


:clamp — числовое ограничение диапазона

Ограничивает числовое значение в диапазоне min–max.

synx
!active

громкость:clamp:0:100 150
# → 100

яркость:clamp:0:255 -10
# → 0

Ошибка, если MIN > MAX.


:round — числовое округление

Округляет число до N знаков после запятой.

synx
!active

цена:round:2 19.999
# → 20.00

пи:round:4 3.14159265
# → 3.1416

целое:round:0 42.7
# → 43

По умолчанию: 0 знаков (округление до целого).


:format — форматирование в стиле printf

Форматирует значение по шаблону printf.

synx
!active

цена:format:%.2f 19.9
# → "19.90"

код:format:%04d 42
# → "0042"

Поддерживаемые шаблоны: %.Nf (дробное), %d (целое), %0Nd (с нулями). Макс. ширина/точность: 4096/1024.


:map — таблица подстановок

Подставляет значение из таблицы поиска. Дочерние элементы — пары значение_поиска результат.

synx
!active

метки_статусов
  200 OK
  404 Not Found
  500 Internal Server Error

результат:map:метки_статусов
  - 200
  - 404
  - 500

Результат: ["OK", "Not Found", "Internal Server Error"]. Если совпадений нет — возвращает null.


:once — сгенерировать один раз, кэшировать

Генерирует значение при первом парсинге и сохраняет его в файле .synx.lock для последующих чтений.

synx
!active

instance_id:once:uuid
# → "550e8400-e29b-41d4-a716-446655440000" (стабильно между парсингами)

created_at:once:timestamp
# → "2026-04-01T12:00:00Z" (замораживается при первом парсинге)

Типы: uuid, timestamp, random.


:version — сравнение версий

Сравнивает значение с ограничением семантической версии. Возвращает булево.

synx
!active

app_ok:version:>=:1.0.0 1.2.3
# → true

engine_ok:version:>=:2.0.0 1.9.5
# → false

Операторы: >=, <=, >, <, ==, !=. Разбирает semver (x.y.z…).


:watch — чтение внешнего файла

Читает внешний JSON или SYNX файл при парсинге и подставляет его содержимое как значение.

synx
!active

все_флаги:watch ./flags.synx
db_host:watch:database.host ./infra.json

Необязательный путь ключа после :watch: извлекает конкретное вложенное значение. Макс. глубина: 16, макс. размер: 10 MiB. Защита путей (path-jail).


:fallback — резервный файл

Если основной файл отсутствует, используется резервный путь.

synx
!active

config:fallback:./defaults.synx ./overrides.synx

Также применяется, если значение null или пустое.


:spam — ограничение частоты

Ограничивает количество обращений к значению за временное окно.

synx
!active

api_endpoint:spam:5:60 https://api.example.com/data
# Максимум 5 обращений за 60 секунд

Окно по умолчанию: 1 секунда. Счётчик живёт в памяти процесса и сбрасывается при перезапуске.


:prompt — метка для LLM

Форматирует поддерево как именованный block-fence для LLM.

synx
!active

config_block:prompt:AppConfig
  app_name MyCoolApp
  version 2.1.0

Выход: AppConfig (SYNX):\n\``synx\n...\n````


:vision — метаданные изображения (сквозной)

Помечает значение как ссылку на изображение для моделей компьютерного зрения. Движок не трансформирует — приложения определяют по метаданным.

synx
!active
диаграмма:vision ./docs/architecture.png

:audio — метаданные аудио (сквозной)

Помечает значение как ссылку на аудио. Движок не трансформирует — приложения определяют по метаданным.

synx
!active
запись:audio ./meetings/standup.mp3

:import — псевдоним для :include

Идентичен :include. Используйте тот, что читается лучше.

synx
!active
бд:import ./config/db.synx

:inherit — наследование объектов (mixin)

Наследует все поля из одного или нескольких родительских объектов. Дочерние поля имеют приоритет.

synx
!active

база
  host localhost
  port 8080
  debug false

продакшн:inherit база
  host prod.example.com
  debug false

Результат: продакшн = { "host": "prod.example.com", "port": 8080, "debug": false }. Родители объединяются слева направо, затем дочерние поля перезаписывают. Разрешается на предварительном проходе до других маркеров.


3.3 Сводная таблица функций

ФункцияОписаниеПример
:randomСлучайный элемент из спискафраза:random
:random N N NВзвешенный рандом (проценты)дроп:random 70 20 10
:calcАрифметическое вычислениеитого:calc цена * 1.2
:envПеременная окруженияпорт:env PORT
:aliasСсылка на другой ключкопия:alias оригинал
:secretСкрытое от логов значениепароль:secret abc123
:defaultЗначение по умолчаниютема:default dark
:default:XFallback (в комбинации)порт:env:default:8080 PORT
:uniqueДедупликация спискатеги:unique
:includeПодключить внешний файлбд:include ./db.synx
:importПсевдоним для :includeбд:import ./db.synx
:geoЗначение по регионувалюта:geo
:templateИнтерполяция строкприветствие:template Привет, {имя}!
:splitРазделение строки на массивтеги:split space
:joinОбъединение массива в строкуфраза:join space
:refРазрешение и цепочкаитого:ref:calc:*2 базовая_ставка
:i18nПеревод по локалиприветствие:i18n
:clampЧисловое ограничениегромкость:clamp:0:100 150
:roundЧисловое округлениецена:round:2 19.999
:formatФорматирование printfцена:format:%.2f 19.9
:mapТаблица подстановокрезультат:map:метки_статусов
:onceСгенерировать, кэшироватьid:once:uuid
:versionСравнение версийok:version:>=:1.0.0 1.2.3
:watchЧтение внешнего файлафлаги:watch ./flags.synx
:fallbackРезервный файлcfg:fallback:./default.synx ./custom.synx
:spamОграничение частотыapi:spam:5:60 endpoint
:promptМетка для LLMctx:prompt:system Ваш промпт
:visionМетаданные изображенияimg:vision ./photo.png
:audioМетаданные аудиоsnd:audio ./clip.mp3
:inheritНаследование объектовпрод:inherit база

Комбинирование функций — через цепочку ::

synx
!active
порт:env:default:8080 PORT

3.4 Ограничения ([]) — валидация данных

Ограничения записываются в квадратных скобках между ключом и функцией (или значением). Они работают только в режиме !active.

Общий синтаксис:

ключ[ограничение1:значение, ограничение2:значение]:функция значение

min / max — минимум и максимум

Для чисел — ограничивает диапазон значения.
Для строк — ограничивает длину (количество символов).

synx
!active

// Строка от 3 до 30 символов
имя_приложения[min:3, max:30] TotalWario

// Число от 1 до 100
громкость[min:1, max:100] 75

// Только минимум
пароль[min:8] мойпароль123

required — обязательное поле

Парсер выкинет ошибку, если значение пустое или отсутствует.

synx
!active

api_key[required]:env API_KEY
имя[required, min:1] Wario

pattern — регулярное выражение

Значение должно соответствовать regex-шаблону.

synx
!active

код_страны[pattern:^[A-Z]{2}$] RU
телефон[pattern:^\+\d{10,15}$] +79991234567

enum — допустимые значения

Значение должно быть одним из перечисленных.

synx
!active

тема[enum:light|dark|auto] dark
регион[enum:EU|US|RU|AS] RU

readonly — только для чтения

Значение нельзя изменить через API / горячую перезагрузку конфига. Только ручное редактирование файла.

synx
!active

версия[readonly] 2.0.0

3.5 Сводная таблица ограничений

ОграничениеОписаниеСинтаксис
minМинимум (длина в символах или значение)[min:3]
maxМаксимум (длина в символах или значение)[max:100]
typeТип данных[type:int]
requiredОбязательное поле[required]
patternRegex-валидация[pattern:^\d+$]
enumСписок допустимых значений[enum:a|b|c]
readonlyЗапрет на изменение[readonly]

Длина строки — число Unicode-символов (скалярных значений): у мир и 東京都 она 3, у 😀 — 1. До 3.7.4 движок на Rust считал байты UTF-8.

Нарушенное ограничение заменяет значение строкой CONSTRAINT_ERR: …. Кроме того, ограничения собираются по имени поля со всего документа — побеждает самое строгое объявление — и проверяются у каждого поля с этим именем, когда все маркеры уже разрешены. pattern, где один квантификатор вложен в другой (^(a+)+$), пропускается, а не выполняется, чтобы враждебный документ не мог подвесить парсер.

Ограничения можно комбинировать через запятую:

synx
!active
пароль[required, min:8, max:64, type:string] MyP@ssw0rd

3.6 Директивы

Директивы — строки верхнего уровня, начинающиеся с ! или #!. Они управляют режимом документа и метаданными. Директива должна стоять перед любыми парами ключ-значение.

ДирективаОписание
!activeВключить маркеры, ограничения и валидацию (см. §3.1)
!lockПометить документ как только для чтения (флаг метаданных)
!includeВключить другой SYNX-файл на уровне корня документа
!toolПерестроить вывод как конверт вызова инструмента (имя + параметры)
!schemaЭкспортировать JSON Schema Draft 2020-12 из структуры документа
!llmАннотировать документ для LLM (только метаданные)

!lock — только для чтения

Устанавливает флаг locked в результате парсинга. Дерево данных не меняется — это рекомендация для инструментов.

synx
!lock

имя Алиса
роль администратор

!include — включение на уровне документа

Включает другой SYNX-файл и объединяет его содержимое на уровне корня. Необязательный псевдоним назначает включённое дерево именованному ключу.

synx
!include ./db.synx
!include ./auth.synx auth_config

имя МоёПриложение

Максимальная глубина: 16. Защита путей запрещает .. выход.

!tool — конверт вызова инструмента

Перестраивает вывод: первый ключ становится именем инструмента, его дочерние элементы — параметрами.

synx
!tool

web_search
  query rust async
  lang en
  results 10

Выход:

json
{
  "tool": "web_search",
  "params": {
    "query": "rust async",
    "lang": "en",
    "results": 10
  }
}

!schema — экспорт JSON Schema

Заставляет парсер генерировать объект JSON Schema Draft 2020-12 на основе ключей и ограничений документа.

synx
!schema

имя[required, type:string]
порт[type:int, min:1, max:65535]

!llm — метаданные LLM

Директива-метаданные для LLM-инструментов. Не меняет дерево данных.

synx
!llm

persona Ассистент
role Вы — полезный ассистент по программированию
tone профессиональный и лаконичный
Режим !active | AS Docs