SDK карточек

Сделайте карточку.Поставьте её на любой холст.

Карточка — это маленькое веб-приложение, которое живёт на холсте NeuroSquad рядом с агентами. Опубликуйте её на GitHub — и любой поставит её, вставив адрес. Она умеет слушать агентов, давать им инструменты, отправлять им промпты и обмениваться типизированными данными с другими карточками по стрелкам — ровно с теми разрешениями, которые дал пользователь.

Обычный HTML и JS или React с Vite. У SDK нет зависимостей во время работы, лицензия MIT.

Вставили owner/repo

Агенты

Карточка работает вместе с агентами

Карточка видит, какие агенты есть на холсте и чем они заняты. Соедините её с агентом стрелкой — и она сможет реагировать на его ходы, дать ему инструмент или выдать следующую задачу.

Реагирует, когда агент закончил

Карточка подписывается на события агентов: смена статуса, начало и конец хода, новый вывод. Здесь радар тестов заново гоняет тесты каждый раз, когда подключённый агент заканчивает ход.

card.agents.onTurn(({ agentId, phase }) => {  if (phase === 'end') runTests()})
Стрелки

Карточки говорят по стрелкам — типизированными данными

Карточка объявляет свои входы и выходы с типом: текст, Markdown, задачи, таблицы, события — или свой тип со схемой. Проведите стрелку, и значение пойдёт. Приложение проверяет его с обеих сторон и само конвертирует, если встроенная карточка ждёт другой формат.

ns:tasks

Включайте и выключайте стрелки, потом прогоните тесты.

Встроенные карточки тоже в деле

Заметка дописывает Markdown, чек-лист добавляет задачи, доска — карточки задач, агент принимает промпт, терминал выполняет команду. Ваша карточка говорит со всеми одинаково.

Типы, а не догадки

Общие типы (ns:text, ns:markdown, ns:tasks, ns:table, ns:event…) или свой your-card/your-type со схемой JSON. Приложение проверяет каждое значение до доставки.

Не только поток, но и запрос

Вход умеет отвечать: ports.request спрашивает подключённую карточку и ждёт ответа. Сохраняемый выход отдаёт последнее значение карточке в момент подключения.

Песочница

Код сообщества — на коротком поводке

До установки вы видите, кто сделал карточку, откуда она и с какого коммита, и простыми словами — что она сможет делать. После этого приложение следит ровно за этим.

Установить Радар тестов?

СообществоВерсия 1.0.0автор: Acme (со слов автора)
Источникacme/test-radar @ 3f9c2e1

Код сообщества, NeuroSquad его не писал и не проверял. Ставьте карточки только от тех, кому доверяете.

Всё внутри карточки принадлежит самой карточке. NeuroSquad никогда не спрашивает там пароли или ключи.

Карточка сможет

Запускать команды в подключённых к ней терминалах

Высокий риск

Набирать и выполнять команды в карточках терминалов, соединённых с ней стрелкой, — всё, что могли бы запустить вы сами.

Читать и менять подключённые к ней карточки

Средний

Заметки, чек-листы, доски задач и стикеры, соединённые с ней стрелкой.

Даёт инструменты агентам, которых вы к ней подключите: run_tests

Обменивается данными по стрелкам: 1 вх., 1 вых.

Заперта в своём фрейме

Каждая карточка работает в изолированном фрейме со своим происхождением. Нет доступа к приложению, к Node, к другим карточкам и к вашим файлам сверх разрешённого.

Не выходит за холст

Никаких всплывающих окон, новых окон, диалогов поверх приложения и загрузок. Карточка рисует только внутри своей рамки и масштабируется вместе с холстом.

Только то, что вы разрешили

Каждый вызов приложение сверяет с разрешением. Необязательные разрешения карточка просит позже, прямо на себе, а любое можно отозвать.

Стрелка — это согласие

Карточка дотягивается до другой карточки, агента или терминала, только если вы провели между ними стрелку, и только с нужным разрешением.

Сеть — через прокси

Только к адресам, которые карточка объявила. Секреты, которые вы ввели, подставляет в запросы приложение; карточка их не видит.

Привязка к коммиту, без автообновлений

Установка привязана к коммиту. Новая версия показывает, что изменилось и какие разрешения добавились, и ждёт вашего клика.

Код

Целая карточка в одном коротком файле

Это готовая карточка. Она гоняет тесты в подключённом терминале, отправляет упавшие по стрелке, даёт агентам инструмент run_tests и перезапускает прогон, когда подключённый агент закончил. Рядом — манифест, где сказано, что ей нужно.

1import { connect } from '@neurosquad/card-sdk'2 3const card = await connect()4 5/** Runs the suite in the terminal this card is wired to and sends out what broke. */6async function runTests(filter = ''): Promise<string[]> {7  const shell = card.ports.peers.find((peer) => peer.kind === 'terminal')8  if (!shell) throw new Error('Draw an arrow from this card to a terminal')9 10  await card.setStatus('Running tests…', { busy: true })11  const { output } = await card.terminals.run(shell.cardId, `npm test -- ${filter}`)12  const failed = output.split('\n').filter((line) => line.includes('✗'))13 14  const tone = failed.length ? 'danger' : 'success'15  await card.setStatus(failed.length ? `${failed.length} failed` : 'Passing', { tone })16  // ns:tasks: a checklist adds them, a note gets a Markdown list17  await card.ports.emit('failures', failed.map((text) => ({ text, status: 'error' })))18  return failed19}20 21// Connected agents see this as test_radar_run_tests over MCP22card.tools.handle<{ filter?: string }>('run_tests', async ({ filter }, call) => {23  call.progress('running…')24  const failed = await runTests(filter)25  return failed.length ? failed.join('\n') : 'All tests passed'26})27 28// A connected agent finished its turn: check its work29card.agents.onTurn(({ agentId, phase }) => {30  const wired = card.ports.peers.some((peer) => peer.cardId === agentId)31  if (phase === 'end' && wired) runTests().catch((error) => card.log.error(error))32})33 34// Anything on the "run" input (a button, a schedule) starts a run35card.ports.onMessage(() => void runTests(), { input: 'run' })
Этот код проходит строгую проверку типов против SDK, а манифест — собственный валидатор SDK.

Один connect()

Дожидается рукопожатия с приложением и возвращает типизированный клиент: у каждого метода, события и данных есть тип.

Манифест — это договор

Разрешения, порты, инструменты и настройки объявлены заранее — именно их и показывает окно установки.

Тесты без приложения

createMockHost() запускает карточку против хоста в памяти, который делает те же проверки, что и приложение, в том же порядке.

Что умеет клиент

  • card.setStatus()Заголовок, статус, бейдж, плитка обзора, внимание
  • card.uiВсплывашки, подтверждения и меню карточки
  • card.storageХранилище на карточку и на пакет
  • card.settingsФорма настроек, которую рисует приложение, включая секреты
  • card.agentsСписок агентов, слежение, чтение экрана, промпты
  • card.terminalsКоманды в подключённых терминалах
  • card.portsТипизированные входы и выходы по стрелкам
  • card.toolsИнструменты для подключённых агентов
  • card.netЗапросы через прокси приложения, с потоками
  • card.fsФайлы в папке воркспейса
  • card.lifecycleВидимость, пауза, изменение размера
  • createTranslator()Английский, русский и китайский, с живым переключением
Старт

Первая карточка — за три команды

Нужны Node.js 18.17 или новее и NeuroSquad с включённым режимом разработчика в «Настройки → Свои карточки».

  1. 1

    Создайте

    $npx @neurosquad/card-sdk create my-card

    Рабочая заготовка: живые статусы агентов, черновик с сохранением, порт и инструмент. Добавьте --template react, чтобы взять React и Vite.

  2. 2

    Запустите вживую

    $cd my-card && npx @neurosquad/card-sdk dev

    Подключает папку к приложению после вашего подтверждения, перезагружает карточку на каждое сохранение и показывает её лог.

  3. 3

    Проверьте

    $npx @neurosquad/card-sdk validate

    Прогоняет собственные валидаторы приложения и печатает окно установки, которое увидят ваши пользователи.

Потом поделитесь

Залейте папку на GitHub. Любой поставит карточку, вставив owner/repo в «Настройки → Свои карточки». Обновления никогда не ставятся сами: каждый новый коммит показывается с изменениями разрешений и применяется по клику.

Внешний вид

Выглядит так, как вы захотите

Шапка, рамка и меню — от приложения. Всё внутри — ваше: любой HTML, CSS, холст или 3D. Если нужен родной вид, есть необязательный набор стилей, который следует живой теме приложения.

Родной наборНеобязательные классы на теме самого приложения
ТерминалМоноширинный шрифт и зелёный люминофор
Ваш брендВаши шрифты, цвета и раскладка
Вопросы

Перед стартом

Сделайте карточку, которой не хватает вашему холсту

Начните с шаблона, запустите вживую в приложении, опубликуйте на GitHub.