polka
by artkruglov
README.md
<p align="center">
<a href="https://polochka.app">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/logo-dark.svg">
<img src="docs/assets/logo.svg" alt="Полка" width="257" height="80">
</picture>
</a>
</p>
<h3 align="center">Разложите ИИ по полочкам.</h3>
<p align="center">
Общее место для всего, что люди делают с ИИ-агентами: Claude, ChatGPT, Claude Code, Codex.<br>
Агент кладёт работу на Полку — она открывается по ссылке, команда её обсуждает, другой агент продолжает.
</p>
<p align="center">
<a href="https://polochka.app"><b>polochka.app</b></a> ·
<a href="https://polochka.app/discover">Лента</a> ·
<a href="docs/README.md">Документация</a> ·
<a href="https://polochka.app/enterprise">Для компаний</a> ·
<a href="README_EN.md"><b>English</b></a>
</p>
<p align="center">
<a href="https://github.com/artkruglov/polka/actions/workflows/verify.yml"><img src="https://github.com/artkruglov/polka/actions/workflows/verify.yml/badge.svg" alt="Проверки CI"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0-1f4fff" alt="Лицензия AGPL-3.0"></a>
<a href="https://github.com/artkruglov/polka/releases/latest"><img src="https://img.shields.io/github/v/release/artkruglov/polka?label=версия&color=0f1420" alt="Последняя версия"></a>
<a href="docs/status.md"><img src="https://img.shields.io/badge/статус-prerelease-f59e0b" alt="Статус: prerelease"></a>
<a href="docs/connect-agents.md"><img src="https://img.shields.io/badge/MCP-Streamable_HTTP-0f1420" alt="MCP"></a>
</p>
<p align="center">
<a href="https://polochka.app"><img src="docs/screenshots/landing.png" alt="Главная Полки и фраза для агента" width="880"></a>
</p>
- **Полка для работ агентов.** Страница, прототип, дашборд или целая папка проекта — агент сохраняет её одной фразой. Работа открывается по ссылке без аккаунта и работает в песочнице; каждая правка — новая неизменяемая версия; другой чат или агент находит работу по словам из текста и продолжает.
- **Память сессий.** На своей установке сессии Claude Code и Codex уходят на Полку: что делал агент, какие команды запускал, к какому пулл-реквесту пришёл. Секреты скрываются ещё на машине ([AGENT_SESSIONS](docs/specs/AGENT_SESSIONS.md)).
- **Для компаний.** Своя установка на одной VM, полки отделов с ролями, вход через IdP. Коммерческая редакция добавляет центр управления агентами для службы ИБ: секреты, адреса и MCP-серверы, опасные команды, расход ([COMMERCIAL.md](COMMERCIAL.md)).
## Быстрый старт
Работу на Полку сохраняет ваш агент. Подключите его один раз — дальше просто скажите в чате «Сохрани это на Полку», и в ответе будет ссылка.
**Claude** (claude.ai и Claude Desktop): Settings → Connectors → **Add custom connector**, адрес
```text
https://polochka.app/mcp
```
→ Add → Connect → «Разрешить» в Полке.
**Claude Code** — плагин: MCP-сервер и скиллы Полки одной командой.
```sh
claude plugin marketplace add artkruglov/polka-plugin && claude plugin install polka@polka
```
Затем в Claude Code: `/mcp` → `plugin:polka:polka` → Authenticate.
**Codex** — тот же плагин для Codex.
```sh
codex plugin marketplace add artkruglov/polka-plugin && codex plugin add polka@polka
codex mcp login polka
```
**Другой MCP-клиент** (Cursor, Gemini CLI, Windsurf…): удалённый сервер `https://polochka.app/mcp` (Streamable HTTP, вход OAuth) и скилл `npx skills add artkruglov/polka-plugin`.
Везде откроется Полка: войдите в свою полку (или «Начать без регистрации») и нажмите «Разрешить» — токены и пароли через агента не проходят. Или просто скажите агенту в терминале: `Подключи Полку: https://polochka.app/connect`. Файл с компьютера можно загрузить и без агента. Подробно — [подключение агентов](docs/connect-agents.md).
## Что умеет
<table>
<tr>
<td width="33%" valign="top">
<h4>Агент кладёт результат сам</h4>
В Claude (claude.ai и Desktop) Полка — коннектор: «сохрани на Полку», и ссылка в ответе. ChatGPT подключается тем же адресом, но с ним сохранение ещё не проверено. Claude Code и Codex ставят плагин одной командой, без токена; другие MCP-клиенты — по адресу <code>/mcp</code>, скрипты и CI — через HTTP API.
</td>
<td width="33%" valign="top">
<h4>Интерактив у получателя</h4>
React/JSX-артефакты из чата собираются в одну самодостаточную страницу: библиотеки встроены, сети нет. Страница открывается в песочнице на отдельном домене <code>polochka.page</code>.
</td>
<td width="33%" valign="top">
<h4>Точные версии</h4>
Каждое сохранение неизменяемо и имеет SHA-256. Ссылка показывает ту версию, которую вы опубликовали, а не последний черновик.
</td>
</tr>
<tr>
<td valign="top">
<h4>Ссылки с отзывом</h4>
Срок 1, 7 или 30 дней, отзыв в любой момент, жалоба от получателя. Приватные работы не попадают в каталог и поисковые индексы.
</td>
<td valign="top">
<h4>Полка, папки и поиск</h4>
Обложки с заголовком и началом текста, поиск по тексту работ, корзина. Агент раскладывает полку по папкам сам — «разложи полку» — и сохраняет новое в подходящую папку. Библиотеки шаблонов для команды.
</td>
<td valign="top">
<h4>Данные в России</h4>
polochka.app работает в Yandex Cloud: база, файлы, резервные копии и письма хранятся и обрабатываются в России (<a href="docs/legal/privacy.md">политика</a>). Или поставьте Полку у себя.
</td>
</tr>
<tr>
<td valign="top">
<h4>Проекты</h4>
Папка связанных страниц — HTML, Markdown и React-компоненты — становится одной работой: дерево, переходы по ссылкам внутри проекта и одна ссылка на всё.
</td>
<td valign="top">
<h4>Полки отделов</h4>
У отдела своя полка: участники и роли, агент при подключении выбирает полку, ссылки и обсуждения, страница администратора компании. Включается настройкой <code>TEAM_SHELVES=on</code>. На polochka.app полки отделов есть с 12.10.2026: у каждой компании своя организация, администратор компании видит только её полки. Чтобы получить полку отдела в облаке, напишите на hello@polochka.app — назначим администратора компании.
</td>
<td valign="top">
<h4>Спокойная модерация</h4>
Правила и модели проверяют каждую ссылку. Прототип с экраном входа или исследование с сотнями источников не задерживаются; получатель видит предупреждение, только если страница просит пароль, код или данные карты.
</td>
</tr>
</table>
## Как это выглядит
<table>
<tr>
<td width="50%"><a href="https://polochka.app/discover"><img src="docs/screenshots/recipient.png" alt="Интерактивный материал «Контраст в руках» у получателя ссылки"></a><br><sub><b>Получатель ссылки.</b> Интерактивная страница работает в песочнице, без аккаунта.</sub></td>
<td width="50%"><img src="docs/screenshots/shelf.png" alt="Полка: папки, обложки работ, сортировка и фильтры"><br><sub><b>Полка.</b> Папки, обложки с заголовком и началом текста, поиск и сортировка по всей полке.</sub></td>
</tr>
<tr>
<td><a href="https://polochka.app/discover"><img src="docs/screenshots/discover.png" alt="Лента"></a><br><sub><b>Лента.</b> Интерактивные материалы Редакции Полки.</sub></td>
<td><a href="https://polochka.app/pricing"><img src="docs/screenshots/pricing.png" alt="Страница «Для компаний»: облако, своя установка, коммерческая лицензия"></a><br><sub><b>Для компаний.</b> Облако, своя установка или коммерческая лицензия.</sub></td>
</tr>
</table>
## Как это работает
```mermaid
flowchart LR
A["Агент<br/>Claude.ai · ChatGPT<br/>Claude Code · Codex"] -- "MCP /mcp<br/>(OAuth 2.1 или токен)" --> P
S["Скрипт, CI"] -- "POST /api/v1/publish" --> P
U["Вы в браузере"] -- "загрузка, «Вставить код»" --> P
P["Полка · polochka.app<br/>версии, ссылки, шаблоны"] --> DB[("PostgreSQL")]
P --> S3[("Versioned S3")]
P -- "ссылка /s#…" --> R["Получатель"]
R -. "iframe, песочница без сети" .-> V["Просмотр · polochka.page"]
```
Агент передаёт код работы сам — Полка ничего не забирает из чата. Каждое сохранение становится неизменяемой версией; ссылка привязана к версии. Чужой HTML считается враждебным: интерактивная страница открывается на отдельном домене, без cookies, API Полки и сети. Подробно: [архитектура](docs/architecture.md), [модель угроз](SECURITY.md#модель-угроз-вкратце).
## Пять способов сохранить работу
| Откуда | Как | Подробно |
|---|---|---|
| Claude (claude.ai, Claude Desktop), ChatGPT (проверка идёт) | Коннектор `https://polochka.app/mcp` со входом через OAuth 2.1. Модель вызывает `polka_publish` и возвращает ссылку | [Коннектор](docs/MCP_CONNECTOR.md) |
| Claude Code, Codex | Плагин Полки одной командой: MCP-сервер и скиллы. Вход и «Разрешить» в браузере — без токена | [Подключение агентов](docs/connect-agents.md#плагин-полки-для-claude-code-и-codex) |
| Другие MCP-клиенты | Токен со страницы «Агенты», Streamable HTTP на `/mcp` | [Подключение агентов](docs/connect-agents.md) |
| Скрипты, CI, внутренние агенты | `POST /api/v1/publish` или CLI `scripts/polka-publish.mjs` без зависимостей | [HTTP API](docs/PUBLISH_API.md) |
| Вручную | Загрузка файла (HTML, текст, PNG/JPEG/WebP до 5 МБ) или «Вставить код» на странице «Сохранить» | [FAQ](docs/faq.md) |
С Claude.ai сохранение и ссылка проверены вручную, с ChatGPT — ещё нет ([состояние](docs/status.md)). Сохранения по ссылке на артефакт Claude или ChatGPT нет: сервер не может забрать его сам ([FAQ](docs/faq.md#почему-нельзя-вставить-ссылку-на-артефакт-claude-или-chatgpt)), поэтому работу передаёт агент.
**Для разработчиков агентов:** плагин Claude Code и Codex (`.claude-plugin/`, `.codex-plugin/`, `.mcp.json`, `skills/`) лежит здесь, а ставится из лёгкой копии [artkruglov/polka-plugin](https://github.com/artkruglov/polka-plugin), её собирает `scripts/plugin-repo.mjs`, скилл отдельно — `npx skills add artkruglov/polka-plugin`, справка для агентов — [/llms.txt](https://polochka.app/llms.txt), HTTP API — [/openapi.json](https://polochka.app/openapi.json).
## Быстрый запуск
Нужны Node.js ≥ 22.16, npm и запущенный Docker.
```bash
git clone https://github.com/artkruglov/polka.git && cd polka
npm ci
npm run local:setup # .env с уникальными секретами и локальным интерактивным просмотром (HTML_LIVE_MODE=local)
npm run infra:up # PostgreSQL 16 + MinIO, только 127.0.0.1; первый раз MinIO собирается из исходников, ~10 минут
npm run db:migrate
npm run storage:bootstrap-local # versioned bucket и проверка его возможностей
npm run admin -- account create demo --generate # логин и пароль в .local/demo-account.txt
npm run build
npm run dev # http://127.0.0.1:4390
```
`local:setup` в конце печатает эту же последовательность. Если порты по умолчанию заняты (или это второй клон), задайте свои при создании `.env`: `POLKA_LOCAL_PROJECT=polka-two POLKA_LOCAL_PG_PORT=55432 POLKA_LOCAL_S3_PORT=9138 PORT=4490 VIEWER_PORT=4491 npm run local:setup`.
> [!WARNING]
> Если `db:migrate` падает с ошибкой аутентификации, остались volumes от прошлой установки со старым паролем. Сброс с удалением локальных данных: `docker compose --env-file=.env -f deploy/compose.local.yml down -v`, затем снова с `npm run infra:up` ([подробнее](docs/local-development.md)).
Интерактивный просмотр, вход по коду и отдельные наборы тестов описаны в [docs/local-development.md](docs/local-development.md).
<details>
<summary><b>Проверки</b></summary>
```bash
npm run check # слои frontend + TypeScript
npm run build
npm test # временные БД и bucket, после прогона удаляются
npm test -- --live # наборы с включённым локальным viewer
npm run verify # всё перед push; то же проверяет GitHub Actions на каждый pull request
```
</details>
## Своя установка
Поставка состоит из одного Docker-образа и внешних PostgreSQL и versioned S3. Образ собирается из исходников (`docker build`), опубликованного образа пока нет. Интерактивный viewer должен работать на отдельном registrable domain. Рекомендуемый путь — [deploy/hosted/README.md](deploy/hosted/README.md) (одна VM с Caddy, как на polochka.app; там же [обновление и откат](deploy/hosted/README.md#обновление)). [deploy/BASE.md](deploy/BASE.md), [deploy/RESTORE.md](deploy/RESTORE.md) и [deploy/VIEWER_STAGING.md](deploy/VIEWER_STAGING.md) — черновики для опытных операторов. Как устроена система: [docs/architecture.md](docs/architecture.md).
## Для компаний
| | Облако polochka.app | Своя установка (открытое ядро) | Коммерческая редакция (не в этом репозитории) |
|---|---|---|---|
| Цена | Бесплатно на время пилота | Бесплатно по AGPL-3.0 | По договору |
| Где данные | Yandex Cloud, Россия | На ваших серверах | На ваших серверах |
| Что есть | Открытое ядро: полки отделов с ролями (администратора компании назначаем по письму на hello@polochka.app), сервисные доступы для cron и CI | Всё открытое ядро: полки отделов, роли, агенты по полкам, администратор компании, вход через IdP | Ядро и закрытое расширение для организаций: центр управления агентами (сессии сотрудников, секреты, адреса и MCP, опасные команды, расход), ссылки только для сотрудников, политика ссылок, агент только к папке, журнал агентов с выгрузкой в SIEM, комментарии в Jira и Битрикс24, выгрузка принятых версий; дальше — SAML и SCIM, установка без интернета |
| Свои изменения кода | — | Даёте пользоваться изменённой Полкой — публикуете их по AGPL-3.0 | Можно не публиковать |
| Поддержка и SLA | — | — | По договору |
Подробнее — на странице [«Для компаний»](https://polochka.app/enterprise) и в [COMMERCIAL.md](COMMERCIAL.md): открытое ядро, коммерческая редакция и коммерческая лицензия на ядро. Вход через OpenID Connect (IdP компании), Яндекс ID, VK ID и Google и доступ к библиотеке шаблонов по домену почты уже есть; SAML, SCIM и командных аккаунтов пока нет ([дорожная карта](docs/roadmap.md)).
## Ограничения
- **Страница до 5 МБ, без сети.** Всё нужное должно быть внутри одного HTML или пакета: стили, картинки и шрифты в `data:`. Внешние скрипты, `fetch` и формы у получателя не работают.
- **Интерактивный режим требует отдельного домена для viewer.** Без него (`HTML_LIVE_MODE=disabled`) получатель видит статичную страницу без скриптов.
- **Ссылки Claude/ChatGPT не импортируются.** Нужно сохранить работу через коннектор, скачать файл или вставить код.
- **Скачанные копии нельзя отозвать.** Отзыв закрывает ссылку, но не удаляет то, что получатель уже скачал.
- **Вход — по коду из письма** (нужен SMTP), по паролю от оператора, через Яндекс ID, VK ID, Google или IdP компании по OpenID Connect ([SIGN_IN_PROVIDERS](docs/specs/SIGN_IN_PROVIDERS.md)). Регистрацию можно открыть, ограничить списком адресов, почтовыми доменами или суточным потолком. SAML и SCIM нет.
- **Импорт по URL** (`URL_IMPORT_ENABLED`) и **удаление аккаунта** (`ACCOUNT_DELETION_ENABLED`) по умолчанию выключены.
Подробнее: [docs/faq.md](docs/faq.md).
## Статус
> [!NOTE]
> **Текущий релиз — `v0.15.1`** ([CHANGELOG](CHANGELOG.md)). Hosted-пилот работает на https://polochka.app; регистрация по почте открыта для любого адреса, до 50 новых полок в сутки. API, схема БД и интерфейс ещё могут меняться.
Что сделано и что нет — [docs/status.md](docs/status.md); что дальше — [docs/roadmap.md](docs/roadmap.md): эксплуатация пилота (проверка восстановления на отдельной VM, алерты мониторинга), публикация расширения браузера и проверка коннектора ChatGPT, затем варианты работы, снимок полки на дату и `polka pull/push`; позже — Telegram-бот, SAML и SCIM.
## Документация
[Карта документов](docs/README.md) · [Архитектура](docs/architecture.md) · [Подключение агентов](docs/connect-agents.md) · [Коннектор](docs/MCP_CONNECTOR.md) · [HTTP API](docs/PUBLISH_API.md) · [FAQ](docs/faq.md) · [Состояние](docs/status.md) · [Дорожная карта](docs/roadmap.md) · [Изменения](CHANGELOG.md)
## Участие
Issues и pull requests принимаются на русском и на английском. Как запустить проект, какие проверки нужны и какие правила действуют — в [CONTRIBUTING.md](CONTRIBUTING.md). Pull requests принимаются по [CLA](CLA.md): достаточно один раз написать в описании «Я принимаю CLA (CLA.md)». Участники следуют [кодексу поведения](CODE_OF_CONDUCT.md). Где задать вопрос — [SUPPORT.md](SUPPORT.md).
## Безопасность
Об уязвимостях сообщайте приватно через [GitHub Security Advisories](https://github.com/artkruglov/polka/security/advisories/new), не в публичном issue. Порядок и модель угроз — в [SECURITY.md](SECURITY.md).
## Лицензия
[GNU AGPL-3.0](LICENSE) или [коммерческая лицензия](COMMERCIAL.md) (двойное лицензирование). **С версии 0.1.0 — AGPL-3.0; версии до v0.1.0-rc.5 включительно — Apache-2.0**, и для них это не меняется.
Пользоваться Полкой без изменений, в том числе как сервисом для своей команды, и дорабатывать её открыто можно бесплатно по AGPL-3.0. Кто даёт пользоваться изменённой Полкой по сети, должен предложить пользователям её исходный код: укажите ссылку на него в настройке `SOURCE_URL` ([deploy/hosted](deploy/hosted/README.md#исходный-код-изменённой-версии)). Коммерческая лицензия нужна, чтобы не публиковать свои изменения, встроить Полку в закрытый продукт или получить поддержку и SLA; подробности в [COMMERCIAL.md](COMMERCIAL.md).
См. также [NOTICE](NOTICE) и [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). Проект вырос из опыта [Lanka](https://github.com/artkruglov/lanka), подробнее в [ACKNOWLEDGEMENTS.md](ACKNOWLEDGEMENTS.md).
<p align="center">
<a href="https://star-history.com/#artkruglov/polka&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=artkruglov/polka&type=Date&theme=dark">
<img src="https://api.star-history.com/svg?repos=artkruglov/polka&type=Date" alt="История звёзд" width="560">
</picture>
</a>
</p>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessResponsive