npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zurab/mdmanager

v0.3.0

Published

MDManager — Nx-плагин и CLI для сборки распределённых *.ai.md в единый markdown/PDF/HTML/DOCX-паспорт с группировкой, фильтрами и валидацией frontmatter через JSON Schema

Readme

@zurab/mdmanager

MDManager — инструмент, который собирает разрозненные markdown-файлы в дерево связанных документов, а не в один длинный файл.

Вместо того чтобы складывать всё в один монолитный README.md, вы пишете много маленьких *.md-файлов с понятными заголовками. MDManager собирает их в компактный навигационный документ, где каждый раздел — это короткое название и ссылка на отдельный markdown с деталями. Открыли оглавление — увидели, о чём документация. Захотели глубже — кликнули по ссылке.

Текущая версия: 0.3.0. Поддерживается формат markdown (другие форматы — за рамками первой версии).


Зачем это нужно

Боль первая: монолитный markdown — ад для чтения

Любая документация любого продукта рано или поздно превращается в один из двух anti-patterns:

  • Один длинный markdown на 3000–10 000 строк, который никто не читает целиком, который страшно ревьюить и в котором новые правки гарантированно ломаются о merge-conflicts на чужих абзацах.
  • Куча отдельных файлов в папке без оглавления, без связей, без принципа сборки. Каждый автор пишет «как Бог на душу положит», и никакой целостной документации не получается.

Боль вторая: AI-агенту нужна навигация, а не «всё сразу»

Когда документацию читает AI-агент (Claude Code, Cursor, Copilot), он не может «съесть» 10 000 строк за один запрос — это и неэффективно по токенам, и бесполезно: 95% контента не нужно для текущей задачи. Агенту нужен верхнеуровневый обзор со ссылками, чтобы он сам решил, в какие разделы нырять глубже.

Что даёт MDManager

MDManager превращает набор маленьких *.md-файлов в связанное дерево:

  • На верхнем уровне — короткий навигационный документ: заголовки разделов, описания в одну строку, ссылки на детали.
  • На уровне ниже — отдельный markdown по каждой теме, версионируемый в git, ревьюимый отдельным PR-ом.
  • Между ними — автоматически расставленные относительные ссылки, которые продолжают работать после публикации на любом markdown-рендерере (GitHub, GitLab, статический сайт, Obsidian).

AI-агент читает верхнеуровневый файл (короткий, помещается в контекст), видит структуру и идёт за деталями только в нужные разделы. Человек открывает тот же файл и навигирует по ссылкам, а не скроллит километровый markdown.


Как это работает: постфикс-based сборка

MDManager не привязан ни к какому конкретному имени или расширению. Пользователь задаёт свой постфикс — это уникальный суффикс имени файла, по которому библиотека находит документы для сборки. Постфикс может быть любым:

  • .ai.md — документация продукта для AI-агентов
  • .adr.md — Architecture Decision Records
  • .product.md — продуктовые описания
  • .runbook.md — оперативные инструкции дежурным
  • .changelog.md — журнал изменений
  • любой другой суффикс, удобный для вашего проекта

В одном репозитории могут параллельно жить несколько разных постфиксов для разных типов документации. Один конфиг .mdmanager.json отвечает за один постфикс.

Что библиотека делает с найденными файлами

  1. Сканирует дерево от заданного searchDir рекурсивно или нет.
  2. Находит все файлы с заданным постфиксом.
  3. Парсит YAML-frontmatter каждого файла (категория, weight, теги, флаги).
  4. Группирует по категории, сортирует по weight + имени.
  5. Собирает один итоговый markdown или несколько (через outputs[] с фильтрами по тегам).
  6. Применяет compact-режим: файлы с compact: true во frontmatter превращаются в строку «Заголовок → ссылка на оригинальный файл», вместо вставки всего тела.
  7. Опционально копирует все источники в mirrorSourcesTo — папку, пригодную для прямой публикации на статический хостинг.

Результат — markdown-документ или набор документов с автоматически расставленными ссылками на отдельные файлы. Никакого длинного простыни-текста: каждый раздел — это компактная карточка с переходом «вглубь».


Ключевые возможности

| Возможность | Что даёт | | ----------- | -------- | | Постфикс-based сбор | Пользователь сам определяет, какие файлы собирать (любой суффикс). Несколько постфиксов = несколько типов документации в одном репо. | | Compact-режим | Файл с compact: true превращается в карточку «Заголовок + ссылка на оригинал» вместо вставки тела. Документ остаётся обозримым. | | More-links | Автоматически добавляет блок «Подробнее» со ссылкой на отдельный файл (или на more.md рядом с источником). | | Группировка по категориям | YAML-поле category определяет секцию, groupWeights — порядок секций. | | Сортировка по весу | YAML-поле weight управляет порядком файлов внутри секции. | | Теги и фильтры | Frontmatter-поле tags, селекторы select-by-tag / select-by-category / and / or / select-by-field. | | Separated outputs | Один и тот же набор источников → несколько результирующих markdown через outputs[] с разными фильтрами. Например: «полный паспорт» + «только public-документация» + «только runbook'и». | | Шаблон с placeholder'ом | template-файл с [$GENERATED] оборачивает сгенерированный контент в произвольную обвязку (header, подпись, лицензия). | | Bundle ссылок | copyReferencesTo — копирует ссылаемые файлы в поддиректорию и переписывает ссылки в результирующем markdown'е. | | Self-contained mirror | mirrorIncludeMainOutput — итоговый документ + все источники + все ссылки попадают в одну папку, готовую к публикации на хостинг 1-в-1. | | JSON Schema валидация frontmatter | Привязка схем к категориям/тегам/файлам через schemaBindings. Опечатки во frontmatter ловятся валидатором, не на ревью. | | Custom runners (preprocessor) | Code-блоки в источниках могут вызывать пользовательские скрипты, которые подставляют живые данные в сгенерированный документ (см. ниже). | | Bundled Claude skill | AI-агент устанавливает skill одной командой и сразу понимает контракт продукта без чтения всей документации. |


Установка / запуск

Все примеры ниже используют npx -p @zurab/mdmanager mdmanager … — пакет скачивается из npm-реестра при первом запуске. Локальная установка не требуется.

# Проверка установки и версии.
npx -p @zurab/mdmanager mdmanager --version

Quickstart

# 1. Создать паспорт продукта (скелет директории + .mdmanager.json).
npx -p @zurab/mdmanager mdmanager init --passport my-product

# 2. Добавить раздел документации (создаст файл с правильным постфиксом).
npx -p @zurab/mdmanager mdmanager spec add my-product overview --title "Обзор"

# 3. Собрать связанный markdown-документ.
npx -p @zurab/mdmanager mdmanager build docs/product-passports/products/my-product/.mdmanager.json

После сборки вы получаете один компактный markdown с оглавлением и ссылками на отдельные *.md-файлы. Каждый раздел — отдельная карточка, каждая ссылка ведёт в свой файл с деталями.


Минимальный конфиг

{
  "postfix": ".my-product.md",
  "output": "docs/my-product/index.md",
  "searchDir": "docs/my-product",
  "recursive": true,
  "enableCompactMode": true
}
  • postfixваш суффикс имён файлов. Может быть любым.
  • searchDir — где искать.
  • output — куда писать собранный документ.
  • enableCompactMode — превращать файлы с compact: true в карточки-ссылки.

В исходных файлах (*.my-product.md) — frontmatter:

---
title: "Архитектура"
category: spec
weight: 1
compact: true
compactTitle: "Архитектура продукта"
---

# Архитектура

Подробное описание...

Файл с compact: true появится в итоговом документе как короткая карточка-ссылка. Файл без compact — вставится целиком.


Несколько выходов из одного источника (separated outputs)

Один и тот же набор *.md-файлов можно собирать в разные документы для разных аудиторий через outputs[] с фильтрами по тегам:

{
  "postfix": ".my-product.md",
  "output": "docs/my-product/index.md",
  "searchDir": "docs/my-product",
  "outputs": [
    {
      "path": "docs/my-product/public.md",
      "filter": { "type": "select-by-tag", "tags": ["public"] }
    },
    {
      "path": "docs/my-product/runbook.md",
      "filter": { "type": "select-by-tag", "tags": ["runbook"] }
    },
    {
      "path": "docs/my-product/architecture.md",
      "filter": {
        "type": "and",
        "value": [
          { "type": "select-by-category", "category": "spec" },
          { "type": "select-by-tag", "tags": ["architecture"] }
        ]
      }
    }
  ]
}
npx -p @zurab/mdmanager mdmanager build docs/my-product/.mdmanager.json

Результат — четыре связанных markdown-документа из одного дерева источников: общий, публичный, runbook, архитектурный.


Self-contained папка для публикации на хостинг

Чтобы получившийся документ можно было одной командой загрузить на статический хостинг (GitHub Pages, S3, Netlify), включите mirrorIncludeMainOutput:

{
  "postfix": ".my-product.md",
  "output": "site/index.md",
  "searchDir": ".",
  "recursive": true,
  "enableCompactMode": true,
  "mirrorSourcesTo": "site",
  "mirrorIncludeMainOutput": true
}
npx -p @zurab/mdmanager mdmanager build path/to/.mdmanager.json

После сборки папка site/ содержит:

  • index.md — главный документ с переписанными ссылками
  • все источники в 1:1 структуре относительно searchDir
  • никаких внешних ссылок «вверх» — папка самодостаточна
# Локальная проверка перед публикацией:
cd site && python3 -m http.server 8000

Custom runners — один из вариантов применения

Помимо обычной сборки markdown, MDManager даёт механизм пользовательских обработчиков code-блоков. Внутри *.md-файлов вы можете писать code-блоки с произвольным prefix'ом, которые при сборке заменяются на результат выполнения вашего скрипта.

Это один из вариантов использования — не основная фича. Возможные сценарии:

  • Подстановка живых данных в документацию — блок apirunner дёргает ваш API и подставляет актуальный список endpoint'ов.
  • Self-executable acceptance criteria — блок jestrunner запускает jest-тест и подставляет PASS/FAIL прямо в документ.
  • Валидация конфигов — блок lintrunner проверяет yaml/json в documentation и подставляет результат.
  • Snapshot-тестирование документации — блок snaprunner сравнивает текущий output с зафиксированным.
  • Любой другой случай, где документ должен содержать актуальный результат выполнения кода.

Контракт runner-скрипта

Любой исполняемый файл (Node, Bash, Python). Получает на stdin JSON:

{
  "blockBody": "...",
  "blockLanguage": "myrunner",
  "sourcePath": "/path/to/source.md",
  "outputPath": "/path/to/output.md",
  "frontmatter": { "title": "..." },
  "prefix": "myrunner"
}

Возвращает на stdout JSON:

{ "ok": true, "mode": "replace", "payload": "<markdown to replace block with>" }

или

{ "ok": false, "error": { "code": "X", "message": "..." } }

Регистрация runner'а

В .mdmanager.json:

{
  "preprocessor": [
    {
      "type": "codeblock",
      "prefix": "myrunner",
      "pathToRun": "scripts/runners/my-runner.sh",
      "schemaInput": { "type": "object", "required": ["fr"] },
      "timeoutMs": 30000
    }
  ]
}

В исходном файле:

```myrunner
{ "fr": "FR-X", "command": "..." }
```

При сборке блок заменится на то, что вернёт ваш скрипт.

Bundled runners

Из коробки идут готовые runners для популярных задач (устанавливаются вместе со skill через mdmanager install-skill):

| Prefix | Назначение | | ------ | ---------- | | jestrunner | Запуск Jest-теста с подстановкой PASS/FAIL | | vitestrunner | То же для Vitest | | bashrunner | Произвольный shell-скрипт или команда | | pytestrunner | Pytest | | playwrightrunner | Playwright-сценарий | | cypressrunner | Cypress component test |

Управление активностью runner'ов через токены

Runner-блок может иметь суффикс <prefix>@<token>. Токен фильтруется по activeRunnerTokens в конфиге:

{ "activeRunnerTokens": ["current"] }
\`\`\`myrunner@current
{ ... }
\`\`\`        ← исполнится (current — активный)

\`\`\`myrunner@beta
{ ... }
\`\`\`        ← пропустится

\`\`\`myrunner@deprecated
{ ... }
\`\`\`        ← пропустится (deprecated — зарезервирован, никогда не активен)

Это позволяет помечать runner-блоки как «устаревшие» без удаления — историческая информация остаётся в документации, но при прогоне не запускается. Удобно при рефакторингах.

Запуск runner'ов

# Запустить все активные runner-блоки одного источника:
npx -p @zurab/mdmanager mdmanager preprocess run --source path/to/file.md --json

# Проверить runner-конфиг без запуска скриптов (валидация схем, проверка пути, runtime):
npx -p @zurab/mdmanager mdmanager preprocess validate --config .mdmanager.json --json

# Drift-detection: сравнить текущий результат с lock-файлом предыдущего прогона:
npx -p @zurab/mdmanager mdmanager preprocess check --source file.md --json

# Strict-режим: упасть, если есть skipped-блоки (для CI после рефакторингов):
npx -p @zurab/mdmanager mdmanager preprocess check --source file.md --strict-tokens --json

CLI-команды

Базовые

# Собрать документ:
npx -p @zurab/mdmanager mdmanager build path/to/.mdmanager.json

# Валидация конфига и frontmatter:
npx -p @zurab/mdmanager mdmanager validate path/to/.mdmanager.json

# Создать новый паспорт (скелет директории + конфиг):
npx -p @zurab/mdmanager mdmanager passport create my-product --title "Мой продукт"

# Список существующих паспортов:
npx -p @zurab/mdmanager mdmanager passport list --json

# Добавить новый раздел:
npx -p @zurab/mdmanager mdmanager spec add my-product overview --title "Обзор"

# Инициализация в текущей директории:
npx -p @zurab/mdmanager mdmanager init --passport my-product --non-interactive

# Диагностика окружения:
npx -p @zurab/mdmanager mdmanager doctor --json

Установка bundled Claude skill

Skill — набор инструкций для AI-агента (Claude Code, Cursor, Codex и других), который содержит контракт продукта. Установка — в любую вашу директорию без хардкода subpath:

# Установить:
npx -p @zurab/mdmanager mdmanager install-skill --install-path ./.cursor/skills/mdmanager

# Повторный запуск той же версии — idempotent (no-op):
# stdout: "Skill актуален (0.3.0): ./.cursor/skills/mdmanager"

# Удалить:
npx -p @zurab/mdmanager mdmanager install-skill --uninstall --install-path ./.cursor/skills/mdmanager

Debug-команды

# Распарсенный YAML-frontmatter одного файла:
npx -p @zurab/mdmanager mdmanager dump-meta path/to/file.my-product.md

# Привязанная JSON Schema для одного файла:
npx -p @zurab/mdmanager mdmanager dump-schema-binding path/to/file.my-product.md

Preprocessor (custom runners)

# Запустить runner-блоки на одном источнике (с записью mirror+lock):
npx -p @zurab/mdmanager mdmanager preprocess run --source path/to/spec.md --json

# Запуск во временной директории, без записи на диск:
npx -p @zurab/mdmanager mdmanager preprocess dry-run --config .mdmanager.json --json

# Drift-check: текущий результат vs зафиксированный lock:
npx -p @zurab/mdmanager mdmanager preprocess check --source path/to/spec.md --json

# Валидация runner-конфига без запуска скриптов:
npx -p @zurab/mdmanager mdmanager preprocess validate --config .mdmanager.json --json

Nx-интеграция

Для проектов на Nx (peer-dependency @nx/devkit ^22) все возможности доступны как Nx-цели. После pnpm i @zurab/mdmanager:

# Сборка одного паспорта:
pnpm nx run my-passport:build-passport

# Сборка всех паспортов в монорепо:
pnpm nx run-many --target=build-passport

# Установка skill в произвольный путь:
pnpm nx run my-passport:install-skill --installPath ./tools/skills/mdmanager

# Generators:
pnpm nx g @zurab/mdmanager:passport my-product --title "Мой продукт"
pnpm nx g @zurab/mdmanager:spec --passport my-product --slug overview --title "Обзор"
pnpm nx g @zurab/mdmanager:install-skill --installPath ./tools/skills/mdmanager

Полный справочник полей конфига

JSON Schema конфига публикуется внутри пакета. После установки:

cat node_modules/@zurab/mdmanager/src/config/schema.json

Основные поля (минимально документированы выше):

  • postfix — суффикс имён файлов для сборки.
  • output — путь итогового markdown.
  • searchDir, recursive, includeHiddenFiles — что и где искать.
  • categories, groupWeights, groupingBy — группировка.
  • enableCompactMode, enableMoreLinks, moreFilename — управление compact-карточками и more-links.
  • template, generateToc, separator, minify — оформление итогового документа.
  • outputs[] — несколько результирующих файлов с фильтрами.
  • copyReferencesTo — bundle ссылок.
  • mirrorSourcesTo, mirrorIncludeMainOutput — self-contained mirror для хостинга.
  • schemas, schemaBindings, defaultSchema, strictValidation — JSON Schema валидация frontmatter.
  • preprocessor[] — регистрация custom runners.
  • activeRunnerTokens — фильтрация runner-блоков по токену.
  • input — режим явного списка файлов (взаимоисключающий с postfix).

Зависимости

Runtime (внутри пакета): commander, yaml, ajv + ajv-formats, fast-glob, tslib, @inquirer/prompts.

Peer: @nx/devkit ^22 (только если используются Nx executors/generators).

Системные (опционально, только для соответствующих runners): node ≥ 18.17, bash, python3, npx vitest — каждое нужно только если вы регистрируете соответствующий runner. Для базовой markdown-сборки достаточно node.


Документация (спеки)

Все спецификации — в docs/product-passports/products/mdmanager/docs/specs/1-spec/:

  • 1-overview — обзор продукта
  • 2-feature-parity — контракт сборки markdown
  • 3-schema-validation — JSON Schema валидация frontmatter
  • 4-cli-commands — команды CLI
  • 5-nx-executors — Nx executors
  • 6-nx-generators — Nx generators
  • 7-skill-bundling — упаковка Claude skill (FR-610..630 заменены FR-1010..1017 спеки 10)
  • 8-npx-distribution — npx-формы запуска и backward-compat
  • 9-preprocessor-mirror — preprocessor pipeline + mirror-режим
  • 10-self-contained-mirror — self-contained mirror + flexible install-skill + runner tokens