Skip to content
Back to skills

2653 Playground Builder 083c0a65

ASecurity

Задача превратить skill или апи в автономный browser-based playground. Пользователь говорит `Сделай плейграунд для [скилл], инструкция [ссылка]` — агент сам разбирается в скриптах, задаёт вопросы и собирает интерактивный UI.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentpythonapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2653-playground-builder_083c0a65 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2653 Playground Builder 083c0a65?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2653 Playground Builder 083c0a65
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2653-playground-builder-083c0a65/badge)](https://www.skillsdirectory.com/skills/tools-only-2653-playground-builder-083c0a65)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Playground Builder — инструкция для агента

## Что это

Задача превратить skill или апи в автономный browser-based playground.
Пользователь говорит `Сделай плейграунд для [скилл], инструкция [ссылка]` —
агент сам разбирается в скриптах, задаёт вопросы и собирает интерактивный UI.

## Промпт пользователя

```
/playground Сделай playground для [название скилла]
```

Всё. Дальше работает агент.

---

## Инструкция для агента

### Шаг 1: Исследование скилла

Прочитай скрипты скилла.
Найди:
- Все API-эндпоинты (URL, метод, параметры, формат ответа)
- Все параметры командной строки (--prompt, --resolution и т.д.)
- Наличие API-ключей (config/.env)
- Формат входных данных (текст, файлы, URL)
- Формат выходных данных (изображение, текст, JSON, файл)
- Есть ли queue/polling (submit → poll status → get result)

### Шаг 2: Уточнение у пользователя

Используй AskUserQuestionTool чтобы задать вопросы.
Задавай только релевантные — не спрашивай про файлы если скилл текстовый.

Возможные вопросы:
- **Режим** — если скилл поддерживает несколько (generate/edit, analyze/export)
- **Язык UI** — русский или английский
- **Папка результатов** — куда сохранять
- **Итерации** — нужна ли возможность переиспользовать результат как вход
- **Дополнительные фичи** — рисование областей, шаблоны, пресеты

### Шаг 3: Сборка playground

Собери playground как набор файлов в указанной пользователем папке.

---

## Кейсы — что делать когда

### Кейс: В скрипте есть API-ключ

Если в скрипте есть загрузка из `.env` (паттерн `KEY=...`):
- Добавить в UI текстовое поле для вставки ключа
- Добавить file picker для загрузки .env файла
  - Убрать `accept` атрибут (`.env` не имеет MIME-типа, пикер его скроет)
  - В подсказке указать путь, в зависимости от того где находится скилл, например: `~/.claude/plugins/cache/[маркетплейс]/[скилл]/[версия]/skills/[скилл]/config`
  - Добавить hint: "Cmd+Shift+G для перехода по пути"
- Парсинг: `text.match(/KEY_NAME\s*=\s*(.+)/)`
- Хранить ключ только в `state` (память вкладки), не в localStorage

### Кейс: API не поддерживает CORS

Практически все API не отдают `Access-Control-Allow-Origin` для localhost.
Даже `file://` и `http://localhost` будут заблокированы.

Создать рядом с HTML:

**server.py** — прокси на stdlib Python:
- `http.server.SimpleHTTPRequestHandler` для статики
- `do_GET/do_POST/do_PUT` — если путь `/api/*`, проксировать к реальному API
- `do_OPTIONS` — вернуть 200 + CORS headers для preflight
- Заголовки: пробрасывать `Authorization`, `Content-Type` только для POST/PUT
- GET запросы: НЕ отправлять Content-Type (некоторые API ответят 405)
- `urllib.error.HTTPError` — проксировать код и тело, а не глотать
- Логирование: `print(f"[proxy] {method} {target}")` для отладки

**start.sh**:
```sh
#!/bin/sh
PORT=8090
echo "Playground: http://localhost:$PORT/[имя].html"
open "http://localhost:$PORT/[имя].html"
cd "$(dirname "$0")" && uv run server.py $PORT
```

### Кейс: Presigned URL upload (двухшаговая загрузка)

Паттерн: POST initiate → получить `{upload_url, file_url}` → PUT файл на `upload_url`.

Presigned URL содержит query-параметры (`?signature=...&token=...`).

Проксирование:
- В HTML: `fetch('/api/put?url=' + encodeURIComponent(presignedUrl), {method: 'PUT', body: file})`
- В server.py: парсить через `urllib.parse.parse_qs`, НЕ через `split("?url=")`

```python
elif path.startswith('/api/put?'):
    qs = urllib.parse.urlparse(path).query
    target = urllib.parse.parse_qs(qs).get('url', [''])[0]
```

### Кейс: Queue-based API (длинный polling)

Паттерн: submit → получить request_id → poll status → get result.

**ВАЖНО**: URL для submit и для status/result могут отличаться.
Всегда проверять все URL в скрипте — не предполагать единый базовый путь.

В HTML:
- Прогресс-бар с анимацией
- Polling с разумным интервалом (2-5 сек)
- Таймаут
- Обработка всех статусов из скрипта (success, fail, in progress, queued и т.д.)
- При завершении — забрать результат (эндпоинт может отличаться от status)

В server.py: отдельные маршруты для submit и status, если URL различаются.

### Кейс: Скилл работает с файлами (изображения, документы)

- Drag & drop зона с превью миниатюр
- `<input type="file">` как fallback
- Для изображений: отображение на `<canvas>`
- Для canvas: возможность рисовать прямоугольные области (mousedown → mousemove → mouseup)
- Каждая область — текстовая заметка в sidebar
- Заметки включаются в промпт с координатами в процентах от размера изображения

Загрузка default-изображения (если файл рядом с HTML):
- Использовать `canvas.toBlob()` для конвертации в File, НЕ `fetch()`
- Обернуть в `try/catch` — из `file://` canvas будет tainted

### Кейс: Результат можно итерировать

Если результат того же типа что и вход (изображение → изображение):
- Сохранять URL/blob каждого результата в массив `state.history`
- Показывать миниатюры в sidebar
- Клик по миниатюре → загрузить как новый исходник
- Кнопка "Вернуть оригинал"
- После генерации: обновить `state.imageFile` из результата для следующей итерации

### Кейс: AI-обратная связь через Claude CLI

Если результат выигрывает от анализа или итерации с помощью AI:
- Добавить в server.py эндпоинт `/api/claude`
- Сервер вызывает `claude -p "prompt" --output-format json` через `subprocess.run()`
- Для сохранения контекста: `claude --resume SESSION_ID -p "prompt"`
- В HTML: кнопка "Спросить Claude" отправляет результат + вопрос на `/api/claude`

### Кейс: Язык интерфейса

Всегда спрашивать через AskUserQuestion. Не угадывать по языку промпта.

Если пользователь выбрал русский:
- Все элементы UI: заголовки, label, placeholder, hint, кнопки, статусы, ошибки
- Кнопки: "Запустить", "Скопировать", "Очистить все", "Скачать", "Вернуть оригинал"
- Статусы: "Загружаю...", "Генерация... (обычно 15-30 сек)", "Готово!", "Ошибка: ..."

---

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

### Файлы

```
output-folder/
  [имя]-playground.html   — UI, единый файл, inline CSS + JS
  server.py               — прокси (если нужен)
  start.sh                — запуск (если нужен прокси)
```

### UI-требования

- Единый HTML-файл, inline CSS + JS
- Тёмная тема
- Кнопка запуска: `disabled` пока не заполнены обязательные поля
- Прогресс/статус: пользователь должен видеть что происходит
- Лейаут подбирать под задачу скилла (sidebar + preview, полноэкранный и т.д.)

---

## Ловушки (must read)

1. **file:// не работает**. `fetch()`, `canvas.toBlob()` для cross-origin,
   чтение файлов по пути — всё заблокировано. Всегда через localhost.

2. **CORS блокирует даже localhost**. Прокси нужен почти всегда.

3. **`.env` не имеет MIME-типа**. Файловый пикер скроет его.
   Убрать `accept` атрибут с `<input type="file">`.

4. **Presigned URL содержит `?`**. Нельзя парсить простым split.

5. **Submit и status на разных URL**. Не предполагать единый базовый путь.

6. **GET + Content-Type = 405**. Некоторые API отвергнут GET с Content-Type.

---

## Пример: как выглядит диалог

**Пользователь:**
```
/playground Сделай интерфейс для [название скилла]
```

**Агент** (изучив скрипты): задаёт вопросы через AskUserQuestionTool —
только те, что релевантны конкретному скиллу.

**Пользователь:** отвечает на вопросы.

**Агент:** Создаёт файлы, запускает, playground работает.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.