T0: absorb shared/ into backend — cot_logger→src/core, CotJsonFormatter→src/core/cot_formatter.py, _llm_http/_llm_health/ssl→src/core/utils; imports rewritten (26 prod + tests, patch targets); run.sh/backend.Dockerfile/requirements/.axiom source_dirs/semantic_health/AGENTS/INSTALL cleaned; ADR-0022 supersedes ADR-0015; fixed latent CI defects (ss_tools ImportError, record.message in logger tests, same-name test-module collision). ADR-0021 wire enrichment (additive): contract_id/claim/error_code/loc fields; _contract_id ContextVar + resolve_contract_id (explicit > belief_scope > declared-src mirror, derived src never mirrors); EXPLORE auto-loc via single frame walk; facade error auto-fill; 2KB payload cap with payload_truncated/payload_bytes markers; migrated 85 error="CODE" sites to error_code= (12 files); pilot editor/load.py; superset preview payload-bomb inlined bodies removed. Analytics SSOT src/core/log_stats.py (bond transition matrix, orphan-EXPLORE ratio, REFLECT pairing, intent families, coverage, insufficient-sample flag); pretty_cot.py --stats/--digest/--trajectory/--story over one engine; log_gap_service three-tier ground-truth triangulation (FAILED w/o EXPLORE etc.) + GET /api/reports/log-stats|task-log-gaps (polling-suppressed); scripts/cot_audit.py CLI; enriched fields persisted into task_logs.payload for tier queries. Frontend: ReportsAnalyticsModel + AnalyticsStatsPanel (Logs tab) + TaskGapPanel and per-row T1/T2/T3 gap badges (Tasks tab); cot-logger.ts ADR-0021 opts; i18n en/ru. Scheduler console spam fixed: apscheduler logger demoted to WARNING via LoggingConfig.scheduler_log_level. .axiom belief patterns -> $OBJ.* (alias undercount). molecular-cot-logging skill updated (fields, decision rules, tie-break, CLI) and synced. Reviewed orthogonally: F1 cot_span contract pollution, F2 cap boundary accounting, F3 digest over-dedup, F4 trace-state bound, F5 tier metadata — fixed with regression tests. Validation: backend 11287 passed + ruff + compileall; frontend 3446 passed + lint + build; CLI smoke on live app.log.
445 lines
21 KiB
Markdown
445 lines
21 KiB
Markdown
# Установка и настройка superset-tools
|
||
|
||
## Содержание
|
||
|
||
- [Требования](#требования)
|
||
- [Архитектура](#архитектура)
|
||
- [Технологический стек](#технологический-стек)
|
||
- [Docker (рекомендуется)](#docker-рекомендуется)
|
||
- [Локальная разработка](#локальная-разработка)
|
||
- [Конфигурация](#конфигурация)
|
||
- [Система сборки](#система-сборки)
|
||
- [Тестирование](#тестирование)
|
||
- [Покрытие кода](#покрытие-кода)
|
||
- [SSL/TLS конфигурация](#ssltls-конфигурация)
|
||
- [Enterprise Clean Deployment](#enterprise-clean-deployment)
|
||
- [Спецификации](#спецификации)
|
||
- [Утилиты](#утилиты)
|
||
- [Исследования](#исследования)
|
||
|
||
## Требования
|
||
|
||
- **Docker (рекомендуется):** Docker Engine 24+, Docker Compose v2, 4 GB RAM
|
||
- **Локальная разработка:** Python 3.9+, Node.js 18+, npm, 2 GB RAM, 5 GB диска
|
||
|
||
## Архитектура
|
||
|
||
Проект состоит из двух сервисов (внешние ассистенты подключаются через MCP — spec 050):
|
||
|
||
| Сервис | Технологии | Назначение |
|
||
|---|---|---|
|
||
| **backend/** | Python FastAPI, SQLAlchemy 2.0, APScheduler, PostgreSQL | REST API, бизнес-логика, плагины, MCP-сервер |
|
||
| **frontend/** | Svelte 5 (Runes), SvelteKit, Vite, Tailwind CSS | SPA-клиент |
|
||
|
||
```
|
||
superset-tools/
|
||
├── backend/ # REST API (FastAPI)
|
||
│ ├── src/
|
||
│ │ ├── api/routes/ # 30+ роутов (admin, auth, translate, git, agent...)
|
||
│ │ ├── core/
|
||
│ │ │ ├── auth/ # JWT, OAuth, API Keys, RBAC
|
||
│ │ │ ├── migration/ # Dry-run, risk assessment
|
||
│ │ │ ├── task_manager/ # Async jobs, event bus, persistence
|
||
│ │ │ ├── superset_client/
|
||
│ │ │ ├── logger/ # Structured logging, belief state
|
||
│ │ │ └── ...
|
||
│ │ ├── models/ # SQLAlchemy модели
|
||
│ │ ├── plugins/ # Реализации плагинов
|
||
│ │ ├── schemas/ # Pydantic схемы
|
||
│ │ ├── services/ # Бизнес-логика
|
||
│ │ └── scripts/ # CLI/TUI админ-скрипты
|
||
│ └── tests/
|
||
├── frontend/ # SvelteKit SPA
|
||
│ ├── src/
|
||
│ │ ├── routes/ # 20+ групп страниц
|
||
│ │ ├── lib/
|
||
│ │ │ ├── api/ # API клиент
|
||
│ │ │ ├── auth/ # Auth store, permissions
|
||
│ │ │ ├── components/ # UI компоненты
|
||
│ │ │ ├── stores/ # Svelte stores
|
||
│ │ │ ├── i18n/ # Мультиязычность
|
||
│ │ │ └── ...
|
||
│ │ └── ...
|
||
│ └── tests/
|
||
├── docker/ # Dockerfile, entrypoint, nginx
|
||
├── docs/ # Документация, ADR
|
||
├── specs/ # 40+ feature specifications
|
||
├── scripts/ # Утилиты (coverage, security, build)
|
||
├── research/ # Исследования (mcp-superset)
|
||
├── semantics/ # Семантическая карта кода
|
||
├── dist/ # Релизные бандлы
|
||
├── storage/ # Runtime данные (backups, repos)
|
||
├── certs/ # SSL-сертификаты
|
||
└── examples/ # Примеры интеграции
|
||
```
|
||
|
||
## Технологический стек
|
||
|
||
**Backend:** Python 3.9+ (FastAPI 0.126, SQLAlchemy 2.0, APScheduler 3.11), PostgreSQL 16, Authlib, JWT, OpenAI API, GitPython, Playwright, lingua-language-detector
|
||
|
||
**Frontend:** Svelte 5 (Runes), SvelteKit 2.49, Vite 7, Tailwind CSS 3, Vitest 4.1, Playwright 1.60
|
||
|
||
**DevOps:** Docker & Docker Compose (3 профиля + E2E), GitHub Actions (CI), Nginx (опциональный SSL)
|
||
|
||
## Docker (рекомендуется)
|
||
|
||
### Профили окружения
|
||
|
||
Система поддерживает несколько профилей через `.env` файлы:
|
||
|
||
| Профиль | Файл | Команда |
|
||
|---|---|---|
|
||
| **current** | `.env.current` | `docker compose --profile current up --build` |
|
||
| **master** | `.env.master` | `docker compose --profile master up --build` |
|
||
| **enterprise-clean** | `.env` | `docker compose -f docker-compose.enterprise-clean.yml up --build` |
|
||
| **e2e** | `.env.e2e` | `docker compose -f docker-compose.e2e.yml up --build` |
|
||
|
||
```bash
|
||
git clone <repository-url>
|
||
cd superset-tools
|
||
cp .env.example .env
|
||
docker compose --profile current up --build
|
||
```
|
||
|
||
После запуска:
|
||
- Frontend: http://localhost:8000
|
||
- Backend API: http://localhost:8001
|
||
- PostgreSQL: localhost:5432
|
||
|
||
### Offline-бандл
|
||
|
||
```bash
|
||
xz -dc dist/docker/superset-tools.20260517.tar.xz | docker load
|
||
export POSTGRES_PASSWORD="my-strong-password"
|
||
docker compose -f dist/docker/docker-compose.light.yml up -d
|
||
```
|
||
|
||
## Локальная разработка
|
||
|
||
### Backend
|
||
|
||
```bash
|
||
cd backend
|
||
python3 -m venv .venv
|
||
source .venv/bin/activate
|
||
pip install -r requirements-backend.txt
|
||
python3 -m uvicorn src.app:app --reload --port 8000
|
||
```
|
||
|
||
### Frontend
|
||
|
||
```bash
|
||
cd frontend
|
||
npm install
|
||
npm run dev -- --port 5173
|
||
```
|
||
|
||
### Начальная настройка
|
||
|
||
```bash
|
||
# Переменные окружения
|
||
cp .env.example backend/.env
|
||
|
||
# Инициализация БД
|
||
cd backend && source .venv/bin/activate
|
||
python src/scripts/init_auth_db.py
|
||
|
||
# Создание администратора
|
||
python src/scripts/create_admin.py --username admin --password '<temporary-secret>'
|
||
```
|
||
|
||
## Конфигурация
|
||
|
||
Полный список переменных — в каждом `.env.*.example` файле.
|
||
|
||
### Основные категории
|
||
|
||
| Категория | Переменные | Описание |
|
||
|---|---|---|
|
||
| **Security** | `AUTH_SECRET_KEY`, `ENCRYPTION_KEY`, `SERVICE_JWT` | JWT-подпись, шифрование данных, сервисный токен для сервисных принципалов |
|
||
| **Database** | `DATABASE_URL` | Единственное PostgreSQL подключение |
|
||
| **Admin bootstrap** | `INITIAL_ADMIN_CREATE`, `INITIAL_ADMIN_USERNAME`, `INITIAL_ADMIN_PASSWORD`, `INITIAL_ADMIN_EMAIL` | Автосоздание admin при первом запуске |
|
||
| **LLM** | `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `LLM_BASE_URL`, `LLM_MODEL` | Провайдеры и модели |
|
||
| **Features** | `FEATURES__DATASET_REVIEW`, `FEATURES__HEALTH_MONITOR` | Включение фич |
|
||
| **SSO** | `ADFS_CLIENT_ID`, `ADFS_CLIENT_SECRET`, `ADFS_METADATA_URL` | Active Directory Federation Services |
|
||
| **Certificates** | `CERTS_PATH`, `SSL_KEY_PASSPHRASE`, `LLM_CA_CERT_URLS` | PKI для корпоративных сетей |
|
||
| **CORS** | `ALLOWED_ORIGINS`, `FORCE_HTTPS`, `APP_TIMEZONE` | Безопасность и регион |
|
||
| **Logging** | `ENABLE_BELIEF_STATE_LOGGING`, `TASK_LOG_LEVEL` | Структурированное логирование |
|
||
| **Ports** | `BACKEND_HOST_PORT`, `FRONTEND_HOST_PORT`, `POSTGRES_HOST_PORT` | Проброс портов Docker |
|
||
|
||
## MCP клиент (внешние ассистенты)
|
||
|
||
Единая точка подключения внешних MCP-клиентов — Streamable HTTP `/mcp` внутри backend
|
||
(spec 050). Каталог из 47 инструментов фильтруется по live-RBAC; мутирующие операции
|
||
проходят через durable approval-гейты.
|
||
|
||
```bash
|
||
# 1. Discovery (RFC 9728) — метаданные защищённого ресурса и authorization server
|
||
curl http://<host>:8001/.well-known/oauth-protected-resource/mcp
|
||
curl http://<host>:8001/.well-known/oauth-authorization-server
|
||
|
||
# 2. Dynamic Client Registration (нужен Bearer веб-сессии пользователя-владельца)
|
||
# public-клиент (browser PKCE) или confidential (machine, выдаётся client_secret одноразово)
|
||
curl -X POST http://<host>:8001/oauth/register \
|
||
-H "Authorization: Bearer <web-jwt>" -H "Content-Type: application/json" \
|
||
-d '{"client_name":"my-mcp","redirect_uris":["http://localhost:9999/cb"],"scope":"mcp:read","client_type":"confidential"}'
|
||
|
||
# 3a. Machine-клиент: client_credentials → сервисный токен (только read-поверхность каталога)
|
||
curl -X POST http://<host>:8001/oauth/token \
|
||
-d "grant_type=client_credentials&client_id=<id>&client_secret=<secret>"
|
||
|
||
# 3b. Пользовательский клиент: authorization code + PKCE (S256)
|
||
# GET /oauth/authorize?... с Bearer веб-сессии (SPA-mediated consent) → 302 code
|
||
# POST /oauth/token grant_type=authorization_code + code_verifier
|
||
# 4. MCP сессия: POST /mcp с Authorization: Bearer <mcp-token>
|
||
# initialize → notifications/initialized → tools/list → tools/call
|
||
```
|
||
|
||
Альтернатива для доверенных машинных интеграций внутри периметра — `SERVICE_JWT`
|
||
(задаётся в `.env`; композ намеренно падает без него). Gated-инструменты
|
||
(`deploy_dashboard`, `execute_migration`, `run_backup`, superset-writes,
|
||
`consume_baseline_approval`) возвращают `approval_required` и исполняются только
|
||
после `decide_approval` тем же принципалом через серверный поллер.
|
||
PRODUCTION SQL (`superset_execute_sql` на PROD-окружении) отклоняется терминально.
|
||
|
||
## Локальный периметр (LLM/VLM/MCP endpoints)
|
||
|
||
Spec 050 (MCPX-FR-020, T008b): MCP-клиенты и все LLM/VLM-провайдеры по умолчанию
|
||
расположены внутри enterprise-периметра. PII (дашборды, сэмплы датасетов, маскированные
|
||
скриншоты) допускается только к локальным провайдерам; credentials/cookies/токены/секреты
|
||
и raw-пути хранения отвергаются везде (typed secret-exposure rejection, E13).
|
||
|
||
**Deny-by-default на конфигурации провайдера** (Admin → LLM Settings): `base_url`,
|
||
не являющийся локальным, отклоняется типизированной ошибкой
|
||
`400 endpoint_not_local:<reason>` ДО сохранения. Локальными считаются:
|
||
|
||
- host-литералы `localhost`, `127.*`, `[::1]`, `0.0.0.0`, `host.docker.internal`;
|
||
- IP из private/loopback/link-local диапазонов (RFC1918 `10/8`, `172.16/12`,
|
||
`192.168/16`, ULA/loopback IPv6);
|
||
- DNS-имена с enterprise-суффиксами `.local`, `.internal`, `.lan`, `.corp`, `.intranet`
|
||
(split-horizon DNS не требует резолва);
|
||
- DNS-имена, у которых ВСЕ резолвимые адреса приватные;
|
||
- пустой `base_url` отклоняется (SDK-дефолт указывает на публичное облако).
|
||
|
||
Нерезолвимое имя = отказ (fail closed). Substring-эвристики не используются:
|
||
`https://api.openai.com/localhost` отклоняется по hostname.
|
||
|
||
Escape hatches (явные, задокументированные, по умолчанию закрыты):
|
||
|
||
```bash
|
||
# Полный opt-out периметровой проверки (только для непод perimeter-развёртываний!):
|
||
LLM_ALLOW_NONLOCAL_ENDPOINTS=true
|
||
# Точечный allowlist публичных хостов (через запятую):
|
||
LLM_NONLOCAL_ENDPOINT_ALLOWED_HOSTS=llm.partner.example
|
||
# Дополнительные enterprise-суффиксы:
|
||
LLM_LOCAL_HOST_SUFFIXES=.enterprise
|
||
```
|
||
|
||
MCP-транспорт держит свой локальный контур independently: DNS-rebinding protection с
|
||
локальными дефолтами `MCP_ALLOWED_HOSTS`/`MCP_ALLOWED_ORIGINS`, server-owned лимиты
|
||
тела запроса (4 MiB), JSON-глубины (`json_depth_limit=32`, typed `400 json_depth_exceeded`
|
||
до dispatch) и per-session rate limit (`120 req/60s`, typed `429 rate_limited` +
|
||
стандартный `Retry-After`). Исполнимые пины: `tests/test_endpoint_locality.py`,
|
||
`tests/test_mcp_transport_limits.py`.
|
||
|
||
## Система сборки
|
||
|
||
`build.sh` — унифицированная CLI-утилита:
|
||
|
||
```bash
|
||
# Сборка и запуск
|
||
./build.sh compose # docker compose up --build (current profile)
|
||
./build.sh compose:master # docker compose up (master profile)
|
||
|
||
# Индивидуальные сборки
|
||
./build.sh backend # backend image only
|
||
./build.sh frontend # frontend image only
|
||
|
||
# Offline-бандлы
|
||
./build.sh bundle v1.0.0 # полный бандл (все сервисы)
|
||
./build.sh bundle:light v1.0.0 # light (backend + frontend)
|
||
```
|
||
|
||
Артефакты: `dist/docker/superset-tools.<version>.tar.xz` + sha256sum + manifest.
|
||
|
||
## Тестирование
|
||
|
||
### Makefile (tiered test system)
|
||
|
||
```bash
|
||
make test # Tier 1: быстрые unit-тесты backend + frontend (<30с)
|
||
make test-unit # Backend unit-тесты с SQLite (без Docker)
|
||
make test-frontend # Frontend vitest-тесты
|
||
make test-related F=path # Tier 2: умный выбор тестов для изменённого файла
|
||
make test-integration # Tier 3: backend integration с testcontainers
|
||
make test-e2e # Tier 3: Playwright E2E (требуется запущенное приложение)
|
||
make test-all # Все тесты (без установки зависимостей)
|
||
|
||
make lint # Все линтеры
|
||
make lint-backend # ruff check
|
||
make lint-frontend # eslint
|
||
|
||
make coverage # coverage обоих стеков
|
||
```
|
||
|
||
### Самостоятельный запуск
|
||
|
||
```bash
|
||
# Backend тесты
|
||
cd backend && source .venv/bin/activate && pytest
|
||
|
||
# Frontend тесты
|
||
cd frontend && npm run test
|
||
|
||
# Конкретный тест
|
||
pytest backend/tests/test_auth.py::test_create_user
|
||
```
|
||
|
||
### E2E тестирование
|
||
|
||
```bash
|
||
docker compose -f docker-compose.e2e.yml up --build
|
||
cd frontend && npm run test:e2e
|
||
```
|
||
|
||
## Покрытие кода
|
||
|
||
Сводный отчёт — `scripts/coverage-summary.sh`:
|
||
|
||
```bash
|
||
./scripts/coverage-summary.sh # Полный запуск (integration + frontend)
|
||
./scripts/coverage-summary.sh --unit # Backend unit (SQLite) + frontend
|
||
./scripts/coverage-summary.sh --frontend-only # Только frontend
|
||
./scripts/coverage-summary.sh --backend-only --unit # Только backend
|
||
./scripts/coverage-summary.sh --output-dir ./reports/coverage
|
||
```
|
||
|
||
Результат: `coverage-summary/index.html`.
|
||
|
||
### Текущие показатели
|
||
|
||
| Стек | Тип тестов | Процент | Покрытие (Stmts) |
|
||
|---|---|---|---|
|
||
| Backend (unit) | 1723 | 1721/2 ✅ | 48% |
|
||
| Backend (integration) | 167 | 167/0 ✅ | 12% |
|
||
| Frontend | 2443 | 2442/1 ✅ | 99.25% |
|
||
|
||
## SSL/TLS конфигурация
|
||
|
||
### Сертификаты для HTTPS (nginx)
|
||
|
||
Поместите файлы в `./certs/`:
|
||
|
||
**Вариант A — отдельные файлы:**
|
||
```
|
||
./certs/server.crt # SSL сертификат
|
||
./certs/server.key # Приватный ключ
|
||
```
|
||
|
||
**Вариант B — зашифрованный ключ + пароль:**
|
||
```
|
||
./certs/server.crt # SSL сертификат
|
||
./certs/server.key # Приватный ключ (зашифрован, с DEK-Info)
|
||
SSL_KEY_PASSPHRASE=my-passphrase
|
||
```
|
||
|
||
**Вариант C — PKCS#12 контейнер:**
|
||
```
|
||
./certs/server.p12 # Контейнер с сертификатом + ключом
|
||
SSL_KEY_PASSPHRASE=my-passphrase
|
||
```
|
||
|
||
Entrypoint автоматически извлекает `.crt` и `.key` из `.p12`, расшифровывает ключ и передаёт nginx (ключ остаётся в tmpfs контейнера).
|
||
|
||
### Корпоративные CA-сертификаты
|
||
|
||
Положите `.crt`/`.pem` в `./certs/` — entrypoint установит их в системное хранилище Alpine и NSS (Chromium/Playwright). Поддерживаются цепочки (Root → Intermediate).
|
||
|
||
### LLM CA-сертификаты
|
||
|
||
```bash
|
||
LLM_CA_CERT_URLS="http://pki.company.com/root-ca.crt http://pki.company.com/intermediate-ca.crt"
|
||
```
|
||
|
||
Сертификаты скачиваются на старте контейнеров, конвертируются из DER в PEM при необходимости, устанавливаются в системное хранилище.
|
||
|
||
### Диагностика SSL
|
||
|
||
```bash
|
||
scripts/check_llm_certs.py # Полная проверка цепочки доверия
|
||
scripts/diag_container.py --target your-llm-provider.com:443 # Контейнерная диагностика
|
||
```
|
||
|
||
Подробнее — [ADR-0009](docs/adr/ADR-0009-ssl-certificate-management.md).
|
||
`LLM_SSL_VERIFY` удалён в 0.2.x — TLS verify всегда включён.
|
||
|
||
## Enterprise Clean Deployment
|
||
|
||
Разворот в корпоративной сети с очищенным дистрибутивом (без тестовых данных, запрет внешних источников, compliance-проверка):
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
docker compose --profile enterprise-clean up --build
|
||
```
|
||
|
||
Поддерживаются CLI, API и TUI flows. Подробнее — [docs/enterprise-clean.md](docs/enterprise-clean.md).
|
||
|
||
## Авторизация
|
||
|
||
Два метода аутентификации:
|
||
|
||
1. **Локальная** (username/password) — JWT-токены, RBAC (admin/analyst/viewer)
|
||
2. **ADFS SSO** — Active Directory Federation Services
|
||
|
||
Управление: `POST /api/admin/users`, `POST /api/admin/roles`.
|
||
|
||
## Мониторинг
|
||
|
||
- **Dashboard Hub** — управление дашбордами с Git-статусом
|
||
- **Dataset Hub** — управление датасетами с прогрессом маппинга
|
||
- **Task Drawer** — мониторинг фоновых задач (WebSocket real-time)
|
||
- **Unified Reports** — `GET /api/reports?page=1&page_size=20` (фильтры по статусу, типу, дате)
|
||
- **Health Monitor** — мониторинг здоровья системы (через `FEATURES__HEALTH_MONITOR`)
|
||
- **Semantic Map** — автоматически генерируемая семантическая карта кода (`semantics/semantic_map.json`)
|
||
|
||
## Спецификации
|
||
|
||
В `specs/` ведётся 40+ feature specifications. Каждая включает: `spec.md`, `research.md`, `plan.md`, `contracts/modules.md`, `data-model.md`, `checklists/requirements.md`, `tasks.md`.
|
||
|
||
| # | Название | Описание |
|
||
|---|---|---|
|
||
| 011 | `git-integration-dashboard` | Git-интеграция дашбордов |
|
||
| 017 | `llm-analysis-plugin` | LLM-аналитика и валидация |
|
||
| 022 | `sync-id-cross-filters` | Sync ID cross-filters |
|
||
| 023 | `clean-repo-enterprise` | Чистый репозиторий для enterprise |
|
||
| 033 | `gradio-agent-chat` | Gradio/LangGraph AI-агент |
|
||
| 034 | `task-status-center` | Центр статуса задач |
|
||
| 038 | `dashboard-scenario-model` | Сценарная модель дашбордов |
|
||
| 041 | `dataset-lineage-blast-radius` | Lineage и blast radius датасетов |
|
||
|
||
## Примеры скриптов
|
||
|
||
Примеры интеграции с внешними системами (Airflow, CI/CD, cron) — в [`examples/`](./examples/):
|
||
|
||
- [Python](examples/maintenance-api-python.py)
|
||
- [Bash](examples/maintenance-api-bash.sh)
|
||
|
||
Аутентификация через API Key (`X-API-Key`), запуск и завершение maintenance-событий.
|
||
|
||
## Утилиты
|
||
|
||
| Скрипт | Назначение |
|
||
|---|---|
|
||
| `coverage-summary.sh` | Сводный отчёт покрытия |
|
||
| `scan_secrets.sh` | Сканирование секретов |
|
||
| `check_llm_certs.py` | Проверка SSL-сертификатов LLM |
|
||
| `diag_container.py` | SSL-диагностика |
|
||
| `find-related-tests.py` | Поиск тестов по изменённому файлу |
|
||
| `pretty_cot.py` | Форматирование CoT-логов |
|
||
| `gen_semantics.py` | Семантическая карта кода |
|
||
| `build_offline_docker_bundle.sh` | Сборка offline-бандлов |
|
||
|
||
## Исследования
|
||
|
||
- **mcp-superset** — MCP-сервер для Apache Superset (137 инструментов, PyPI). Streamable HTTP, SSE, stdio транспорты. Подробнее — [`research/mcp-superset/`](research/mcp-superset/).
|