От нуля до вашего модуля в вашей песочнице
От пустой папки до вашего модуля внутри Building OS, привязанной к песочнице, которая принадлежит только вам. В первый раз — около 30 минут. Шаги идут по порядку, потому что каждому нужен предыдущий, и каждый ссылается на страницу, где он разобран подробно.
Перед началом
Вам нужны четыре вещи. Если чего-то не хватает, напишите на developers@tango.vision, прежде чем идти дальше.
- Учётная запись разработчика в реалме
developers. Регистрация только по приглашениям: учётную запись создаём мы, а пароль задаёте вы. С ней вы выпускаете API-ключи на портале. См. Учётная запись разработчика. - Токен реестра для
npm.k8s.tangovision.dev. SDK лежит в закрытом реестре, токен выдаётся лично вам. Никогда не коммитьте его. - Вход в песочницу — выдаётся после того, как песочница создана (шаг 3). Приглашённые разработчики получают имя пользователя и временный пароль, отдельные от учётной записи разработчика. Сотрудники Tango Vision входят под корпоративной учётной записью — после того как их включили в группу
/sandbox-developers, а оператор связал их вход в песочницу; пароля у них нет. См. Войдите. - Node 24 и pnpm ровно 10.18.2. Для последнего шага — Chrome или Firefox: Safari не может загрузить модуль с вашей машины.
Однократная настройка
# ~/.npmrc — токен из письма о регистрации
@tv:registry=https://npm.k8s.tangovision.dev/
//npm.k8s.tangovision.dev/:_authToken=${TV_NPM_TOKEN}export TV_NPM_TOKEN=... # храните в профиле оболочки или в менеджере секретов
npm view @tv/extension-sdk version # ожидается 1.15.0 или новееИспользуйте @tv/extension-sdk 1.15.0. 1.14.1 — самая старая версия, каркас которой собирается: проект, созданный версией 1.14.0, не собирается. Кроме того, 1.14.1 и более ранние версии называют контейнер федерации tv-module-<slug>, а не slug в camelCase, как ожидает платформа; если каркас создан одной из них, задайте name в vite.config.ts равным slug в camelCase (hello для hello, workOrders для work-orders). Подробности, включая передачу токена в сборку Docker как секрета: Начало работы.
1. Создайте каркас модуля
npx @tv/extension-sdk init-module hello --category=operations --external
cd tv-module-hello
pnpm install--external генерирует CI, который работает на раннерах GitHub с вашим собственным секретом TV_NPM_TOKEN. Без него сгенерированный workflow вызывает actions из закрытого репозитория Tango Vision и вне нашей организации падает.
Вы получаете module-manifest.json (контракт: id, разрешения, события, куда монтируется UI), src/Shell.tsx (компонент, который рисует оболочка), vite.config.ts (remote федерации, экспортирующий ./Shell) и README с портами и URL, которые встретятся ниже.
pnpm dev # автономный просмотр с фиктивным контекстом платформы, http://localhost:5001
pnpm test
npx @tv/extension-sdk validate module-manifest.json
npx @tv/extension-sdk check-exposes module-manifest.json --config=./vite.config.tsПравьте Shell.tsx и locales/, пока автономный просмотр не покажет то, что нужно. Внутри настоящей оболочки работают только определённые вызовы SDK: useSelectedBuildingId() из @tv/extension-sdk/react для выбранного здания и getAccessToken() или authorizationHeader() из @tv/extension-sdk/context для аутентификации ваших запросов к API — на каждый запрос. Никогда не читайте localStorage['access_token']. React-контекст не пересекает границу федерации, поэтому usePlatformContext() внутри оболочки бросает исключение.
Подробно: Ваш первый модуль и Вызов API из модуля.
2. Получите API-ключ песочницы
Откройте портал разработчика, войдите с учётной записью разработчика и выпустите ключ. Он показывается один раз. По умолчанию у ключа область действия sandbox, он истекает через 90 дней, отозвать его можно там же.
export TV_API_TOKEN=tvk_... # ключ с портала; или: npx @tv/extension-sdk loginВ Windows используйте ключ. login в SDK 1.15.0 и более ранних не может сохранить там сессию: она больше, чем вмещает диспетчер учётных данных Windows. Если login всё же нужен, сначала задайте TV_SDK_TOKEN_STORE=file и не снимайте эту переменную для последующих команд.
Подробно: Получить API-ключ песочницы, API-ключи и Вход через CLI.
3. Создайте песочницу
npx @tv/extension-sdk sandbox create \
--name=hello-dev --type=office --storeys=2 --area-sqm=5000Создание занимает от одной до нескольких минут; команда опрашивает сервис, пока песочница не станет ready. Вы получаете:
| Поле | Значение |
|---|---|
id | sbx_… — идентификатор песочницы, он нужен на шаге 5 |
apiUrl | https://<slug>.sandbox.k8s.tangovision.dev |
consoleUrl | Тот же хост: оболочка песочницы |
organizationId | Идентификатор арендатора песочницы, уникальный для неё |
apiToken | Администратор только этой песочницы |
Внутри: наполненное офисное здание с этажами, помещениями и оборудованием, собственная база PostgreSQL и собственный tv-api. По умолчанию песочница истекает через 14 дней (продлить можно дважды, по 7 дней). Данные синтетические, и ничего из сохранённого вами не переживает истечения. Типы: office, mall, university. Не больше 3 песочниц одновременно.
Теперь пришлите нам slug и organizationId
Мы регистрируем хост песочницы для входа и создаём (для сотрудников — связываем) ваш вход в оболочку песочницы с tenant_id, равным вашему organizationId. Пока мы этого не сделали, оболочка не сможет вас впустить. Каждый раз, когда вы пересоздаёте песочницу, этот шаг повторяется.
Подробно: Песочницы по запросу — что изолировано, а что общее, квоты и API, на котором работает эта команда.
4. Отдавайте remote со своей машины
Remote федерации существует только в сборке; pnpm dev не создаёт remoteEntry.js. Два терминала:
pnpm dev:remote # vite build --watch
pnpm serve:remote # vite preview --port 6001 --strictPort, CORS включёнВаш remote доступен по адресу http://localhost:6001/assets/remoteEntry.js. Порт зафиксирован намеренно: если 6001 занят, команда падает, а не переезжает молча на другой порт, из-за чего реестр указывал бы в пустоту.
Подробно: Отдавайте remote со своей машины.
5. Установите модуль в свою песочницу
npx @tv/extension-sdk sandbox connect sbx_... # печатает export TV_API_URL=... TV_API_TOKEN=...
npx @tv/extension-sdk sandbox install module-manifest.json \
--sandbox=sbx_... \
--remote-entry=http://localhost:6001/assets/remoteEntry.jssbx_… — идентификатор вашей песочницы из шага 3, а не slug из её URL. Потеряли его? npx @tv/extension-sdk sandbox list показывает идентификаторы всех ваших песочниц; портал показывает песочницы только по имени.
Команда регистрирует манифест в реестре вашей песочницы с remote entry на localhost и выдаёт модулю лицензию на наполненное здание. Она печатает URL, который нужно открыть. Запускайте её заново при каждом изменении манифеста; изменения кода переустановки не требуют — оболочка каждый раз загружает ваш remote заново.
Подробно: Установите модуль в свою песочницу.
6. Откройте его в оболочке песочницы
https://<slug>.sandbox.k8s.tangovision.dev/sandbox/hello- Используйте Chrome или Firefox. Приглашённые разработчики входят с логином песочницы, который мы прислали; при первом входе нужно задать новый пароль. Сотрудники нажимают Tango Vision staff и входят под корпоративной учётной записью.
- Вы попадаете в Building OS как Administrator, с выбранным наполненным зданием.
- Откройте
/sandbox/hello. Chrome может один раз спросить разрешение на доступ к локальной сети — разрешите. ВашShell.tsxотрисуется внутри оболочки.
Правьте, сохраняйте, перезагружайте. dev:remote пересобирает, и оболочка подхватывает новый бандл при следующей загрузке.
Правила, которые объясняют пустые страницы
- Модуль с localhost загружает только оболочка песочницы. Продуктивная оболочка не загрузит его никогда; к клиентам ваш модуль попадает только после того, как мы проверим исходный код и соберём его в нашем CI.
- Только loopback:
localhostили127.0.0.1. Адрес в локальной сети или туннель будут отклонены. - Модуль отрисовывается только в вашем браузере. Коллега, открывший тот же URL, получит ошибку загрузки: localhost — это его машина.
- Ваш бэкенд работает на вашей машине, и браузер может к нему обращаться, а платформа — нет: у песочницы нет выхода в интернет, поэтому Copilot не достанет до MCP-эндпоинта на localhost, а Copilot песочницы не может вызвать внешнюю LLM.
- Делите
i18nextиreact-i18nextвvite.config.tsлибо оба, либо ни одного, и сохраните aliasuse-sync-external-store/shim, который записал каркас. Нарушение любого из правил ломается только внутри оболочки, где ваш CI этого не видит.
Полный список: Правила загрузки модуля с localhost.
Если что-то не так
| Что вы видите | Причина | Что делать |
|---|---|---|
"useQuery" is not exported при сборке | Каркас SDK 1.14.0 | Используйте 1.15.0 или pnpm add -w @tanstack/react-query@^5 |
Missing required argument: <id> или 404 от sandbox connect | Нет идентификатора песочницы или он не тот | npx @tv/extension-sdk sandbox list показывает ваши идентификаторы (sbx_…) |
sandbox list или create падают после sandbox connect | Напечатанные им TV_API_URL / TV_API_TOKEN теперь направляют CLI в вашу песочницу, а не в сервис, который управляет песочницами | Откройте новый терминал или добавьте --api=https://sandbox-api.k8s.tangovision.dev |
login падает: longer than the platform limit of 2560 chars | Диспетчер учётных данных Windows не вмещает сессию (SDK 1.15.0 и более ранние) | Используйте ключ с портала в TV_API_TOKEN или задайте TV_SDK_TOKEN_STORE=file и войдите заново |
401 от sandbox install | Не тот токен | Используйте apiToken песочницы (из sandbox connect), а не ключ с портала |
| При входе ошибка invalid redirect | Хост ещё не зарегистрирован | Пришлите нам slug (шаг 3) и дождитесь подтверждения |
| Сотруднику отказано во входе сразу после кнопки staff | Нет в группе /sandbox-developers или вход ещё не связан | Попросите включить вас в группу, а нас — связать ваш вход в песочницу |
| Вход выполнен, но оболочка пишет, что арендатора нет | У вашего входа не задан tenant_id | Сообщите нам; мы зададим его равным вашему organizationId |
| Модуль не найден или 404 | Не установлен или slug не совпадает | Запустите sandbox install заново; slug в URL — часть id манифеста после module- |
| Пустой модуль, в консоли CORS или 404 | Remote не раздаётся | Оба терминала запущены? curl http://localhost:6001/assets/remoteEntry.js |
| Скрипт заблокирован в Safari | HTTPS-страница загружает HTTP с loopback | Используйте Chrome или Firefox |
| Внутри модуля каждый вызов API — 401 | Чтение localStorage['access_token'] | Вызывайте getAccessToken() из @tv/extension-sdk/context на каждый запрос; оболочка песочницы этот ключ не пишет |
| Песочница пропала | Истекла (по умолчанию через 14 дней) | Создайте заново и пришлите нам новый slug |
Ещё: Если страница пустая.
Что можно и чего нельзя
- Можно создавать, сбрасывать, продлевать и удалять свои песочницы и устанавливать в них модули. Токен песочницы администрирует только её.
- Нельзя добраться до другой песочницы или до продуктивного арендатора. Между пространством имён песочниц и продакшеном стоят NetworkPolicy, а роль базы данных вашей песочницы не может открыть базу другой песочницы или базу
postgresна сервере. См. Что изолировано, а что общее. - Нельзя публиковать в реестр платформы или клиентам. Такого пути пока нет; продвижение — ручная проверка со стороны Tango Vision.
- Песочницы — общая инфраструктура с фиксированной квотой. Считайте их одноразовыми и используйте только для разработки.
Платформа для разработчиков находится в режиме preview, и песочницы не сопровождаются гарантиями доступности. Вопросы: developers@tango.vision.