Правила фільтрування команд

From docs/uk/cmd-rules.md at cc732c3 View on GitHub

rtok run (а також rtok filter --stdin і переписування Bash на PreToolUse, яке викликає rtok run) скорочує вивід команд за правилами для кожного сімейства, перш ніж його побачить модель. Сирий вивід завжди спершу архівується, тож кожен скорочений результат можна отримати через rtok expand <id> (типово без втрат, D4). Правила ніколи нічого не приховують: рядок, що містить помилку, попередження чи секрет, проходить без змін.

Три рівні об'єднуються в такому порядку; пізніший рівень перемагає для кожного сімейства команд:

  1. Вбудовані — rules/default.toml у репозиторії (grep, rg, sed, cat, make, curl, npm, pnpm, node, а також форматувальники cargo/git/test/tree у коді).
  2. Файл користувача — [plugins.cmd] rules (типово ~/.rtok/rules.toml).
  3. Drop-in-файли — кожен *.toml у [plugins.cmd] rules_dir (типово ~/.rtok/rules.d/), об'єднані в порядку назв файлів.

Відсутній файл чи каталог — не помилка: цей рівень пропускається. Некоректний файл пропускається під час виконання (fail open), а rtok config validate повідомляє про нього, називаючи кожен поганий файл.

Схема

Одна таблиця TOML на сімейство команд. Назва таблиці — перше слово команди ([grep], [pytest]); для невідомих сімейств використовується типове правило (max_lines = 40, head = 10, tail = 10, дедуплікацію увімкнено). Один виняток: один рядок Bash, що з'єднує 2+ РІЗНІ програми через &&, ; або новий рядок (T177), — це не вивід одного сімейства: його зіставляють із [script]. Ланцюжок однієї програми (cargo build && cargo test або з початковим cd/export) і далі використовує власний форматувальник/правило цієї програми.

Той самий рушій обрізає результати сторонніх MCP-серверів за rtok mcp -- <server argv> (T59.4): розділ [mcp] — це правило для текстового блоку tools/call кожного обгорнутого сервера, а якщо його немає — типове правило. Змінюються лише текстові блоки результату без isError, довші за max_lines; сирий блок спершу архівується, а обрізаний текст закінчується тим самим рядком [rtok <id> · N lines · expand: rtok expand <id>], який друкує rtok run. Економія записується як вимірювання cmd / wrap з ref_id = <server>/<tool>:<id>.

ПолеТипТиповоЗначення
max_linesціле ≥ 040обмеження рядків виводу; решта стає одним рядком … N lines omitted (expand <id>)
headціле ≥ 010рядки, які завжди зберігаються з початку
tailціле ≥ 010рядки, які завжди зберігаються з кінця
dropмасив рядків[]підрядки без урахування регістру, які треба видалити (| розділяє альтернативи)
keepмасив рядків[]підрядки, які ніколи не видаляються й не обрізаються обмеженням; вбудовані keep — error, warning, panic, fail, traceback
dedupebool або "normalized"truetrue згортає сусідні ідентичні рядки в line (×N); "normalized" порівнює рядки із заміненими на заповнювачі мітками часу, id, pid і тривалостями та згортає несусідні збіги в line (×N, also lines k, l, …)
group"dir" | "diag"вимкненоdir переписує вивід «шлях на рядок» як dir/ (N files): a, b, c …; diag переписує діагностику з кодами як E0308 ×N: first message (file:line, …); виконується до обрізання head/tail (T64.1)
json_itemsціле ≥ 020масиви JSON зберігають стільки елементів; решта — один … +K more (T65.2)
json_stringціле ≥ 0200рядки JSON, довші за це, обрізаються із зазначенням їхньої довжини в символах (T65.2)

Будь-яке інше поле, неправильний тип чи зламаний TOML — це некоректний файл. Ненульовий код виходу скасовує все це: останні [plugins.cmd] fail_tail_lines рядків (типово 80) друкуються дослівно, бо помилка команди, що впала, — це і є корисні дані.

Розібраний приклад

~/.rtok/rules.d/pytest.toml — зводити тихі запуски pytest до вказівника, але ніколи не втрачати збій:

[pytest]
max_lines = 30
head = 5
tail = 15
drop = ["PASSED", "passed"]
keep = ["FAILED|failed|ERROR|error"]
dedupe = true

До (212 рядків крапок і пройдених тестів), після (12 рядків):

tests/test_auth.py::test_login PASSED
tests/test_auth.py::test_refresh FAILED
… 200 lines omitted (expand abc123)
E   assert False is True

Перевірте, перш ніж на нього покладатися:

rtok config validate   # називає файли rules.d/*.toml, які не розбираються

validate перевіряє файл, названий у командному рядку (або конфігурацію користувача), плюс окремий файл rules і кожен rules.d/*.toml, до якого вона веде. Файл, про який повідомлено, пропускається під час виконання, доки його не виправлять; усе інше й далі фільтрується.

Сімейства (T50.1)

Виміряно на golden-фікстурах у tests/cmd_golden/ (rtok filter --stdin, Rule проти Rule::default() на тому самому тексті; оцінка токенів = байти/4).

СімействоОсновне в keepдо, Бпісля, Боцінка економії
gherror, HTTP 4, gh:32527712
pipERROR, Could not38934112
uverror, Failed29224412
python / python3Traceback, Error36729917
goerror, panic, cannot29024212
awsAn error occurred, AccessDenied34930112
mvnBUILD FAILURE, [ERROR]4193956
gradleBUILD FAILED, What went wrong35730213
dotneterror CS, Build FAILED28523712
tscerror TS, Found N error37332512
eslinterror, warning, problems29825012
brewError:, failed31026212
apt^E:, Unable to29324512
cmakeCMake Error, FAILED31725515

Форматувальники (T58.5)

Виміряно на тих самих golden-текстах (formatters::compress, Measurement.kind = formatter проти Rule::default() на тій самій фікстурі; оцінка токенів = байти/4). Кожен форматувальник зберігає один рядок на об'єкт і повертає None для нерозпізнаного виводу, тож шлях правил лишається запасним варіантом.

Сімействозберігаєдо, Бпісля правила, Бпісля форматувальника, Боцінка економії порівняно з правилом
docker psодин рядок на контейнер31471311119030
kubectl getодин рядок на об'єкт (NAME READY STATUS IP)4542177017319
ps auxодин рядок на процес234199087030

Групування (T64.1)

Виміряно на golden-фікстурах у tests/cmd_golden/ (formatters::compress із вбудованим правилом проти того самого правила з вимкненим group; оцінка токенів = байти/4). Для сімейства групування вмикається, лише коли згрупований текст менший. tree, git status, pytest і python лишаються як є: псевдографіка tree і форматувальники git/pytest — це не потоки «шлях на рядок» чи діагностики з кодами, а traceback python з T50.1 не стискається у вигляді NameError ×1.

Сімействоgroupбез групування, Бз групуванням, Боцінка економії
lsdir2484949
finddir53983114
rg (-l)dir4598394
tscdiag1619107378
eslintdiag74948175
cargo (check)diag74934178
dotnetdiag84971194

JSON (T65.2)

Текст, який serde_json розбирає як об'єкт або масив, переписується після групування й до обрізання head/tail: поля з null / порожнім рядком / порожнім контейнером видаляються, елементи масивів понад json_items показуються як … +K more, ключі об'єктів зберігаються, рядки, довші за json_string, обрізаються із зазначенням довжини, один рядок на ключ верхнього рівня. Тексти, що не розбираються, лишаються недоторканими. Табличні форматувальники (kubectl get, docker ps) поступаються, коли текст — JSON, тож kubectl get -o json доходить до цього проходу. toon лишається поза шляхом хука. Сирі байти лишаються в архіві; скорочений результат і далі несе завершальний рядок expand.

Виміряно на tests/cmd_golden/{gh,aws,kubectl}_json.in (formatters::compress проти обрізання head/tail того самого відформатованого тексту; оцінка токенів = байти/4).

Джерелосирий, Бобрізання рядків, Бкомпактний, Боцінка економії порівняно із сирим
gh pr list --json1027590845301436
aws ec2 describe-instances1951651958903406
kubectl get pods -o json2627135382974493