Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ CanvasTTY is a spatial Electron desktop for real local terminals and AI-agent CL
| [Built-in browser and audit log](browser.md) | Canvas controls, settings, agent access, website/file boundaries, activity, and persistent redacted audit files |
| [Installing, releases, and local data](installing-and-security.md) | Installer formats, unsigned-preview caveats, credential boundaries, and release checks |
| [Widget authoring](widget-authoring.md) | Source-level extension paths, visual grammar, process boundaries, and an AI-agent brief |
| [Pixel terminal themes (Russian)](pixel-skin-packs.ru.md) | Ten-PNG ZIP layout, terminal apertures, app import, and local agent CLI |
| [Create a pixel theme with an agent](pixel-skin-agent-start.md) | Zero-context agent brief, exact install ZIP, visual checks, and validation |
| [Runtime plugins](plugins.md) | Manifest v1, permissions, HOME widgets, canvas apps, separate windows, player media/playlist APIs, SDK, and install flow |
| [Metrics and telemetry](metrics-and-telemetry.md) | Subscription limits, session token usage, source priority, privacy, stale states, and tests |
| [Security policy](../SECURITY.md) | Supported release, vulnerability reporting, local data boundaries, plugins, media grants, browser storage, and audit logs |
Expand Down
2 changes: 2 additions & 0 deletions docs/README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ CanvasTTY — пространственный Electron-десктоп для н
| [Встроенный браузер и журнал аудита](browser.ru.md) | Управление на канвасе, настройки, доступ агентов, границы сайтов/файлов, activity и постоянные очищенные audit-файлы |
| [Установка, релизы и локальные данные](installing-and-security.ru.md) | Форматы установщиков, оговорки про неподписанное превью, границы доступа к credentials и релизные проверки |
| [Создание виджетов](widget-authoring.ru.md) | Способы расширения через исходный код, визуальная грамматика, границы процессов и бриф для AI-агента |
| [Пиксельные темы терминала](pixel-skin-packs.ru.md) | Десять PNG, ZIP, прозрачный проём, импорт и управление агентом |
| [Инструкция агенту по созданию темы](pixel-skin-agent-start.md) | Задание с нулевого контекста, проверка архива и визуальная приёмка |
| [Runtime-плагины](plugins.ru.md) | Manifest v1, permissions, HOME widgets, canvas apps, отдельные окна, media/playlist API для плееров, SDK и установка |
| [Метрики и телеметрия](metrics-and-telemetry.ru.md) | Лимиты подписок, расход токенов за сессию, приоритет источников, приватность, stale-состояния и тесты |
| [Политика безопасности](../SECURITY.ru.md) | Поддерживаемый релиз, сообщения об уязвимостях, локальные данные, плагины, медиапапки, browser storage и audit log |
Expand Down
33 changes: 33 additions & 0 deletions docs/pixel-skin-agent-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Create a CanvasTTY pixel theme with an agent

This is the starting point for an agent with no prior CanvasTTY context. Give the agent [the design-kit repository](https://github.com/teo-nex/CanvasTTY-design-for-agents) or [its offline ZIP](https://github.com/teo-nex/CanvasTTY-design-for-agents/raw/refs/heads/main/CanvasTTY_Agent_Theme_Kit_v1.zip), plus a visual reference. The deliverable is a separate **install ZIP**, not the source-kit ZIP. Read [the full pack specification](pixel-skin-packs.ru.md) and confirm the current contract in `src/main/services/PixelSkinPackRegistry.ts` before generating art.

## Inputs and output

- Input: a visual reference or a written art direction, plus optional theme name. The reference is not a ready-to-import frame unless it satisfies the requirements below.
- Output: one ZIP containing **exactly ten final PNG files**. The nine frame files are `minimal_idle.png`, `minimal_working.png`, `minimal_completed.png`, `detailed_idle.png`, `detailed_working.png`, `detailed_completed.png`, `master_idle.png`, `master_working.png`, and `master_completed.png`. The tenth is `background.png`.
- A single containing folder is permitted, but there must be exactly one file for each name. Do not include drafts, alternate versions, nested source/output copies, instructions, or `apertures.json` in the install ZIP. A separate source kit is optional.
- Use `completed`, **not** `done`, in filenames. Completed covers a finished agent turn, whether it succeeded or failed.

## Artwork contract

1. Make all nine frames 1536 x 1024 px, PNG RGBA, on the same 3:2 canvas. Keep exterior geometry fixed across levels and states. Do not shift, crop, or rotate the frame between states.
2. The terminal output is live UI underneath the art. Leave a transparent central opening large enough for readable text. Do not bake terminal text, a black terminal panel, the cursor, title, controls, or screenshots into the image. Keep the top-right button plaque clear for native search and close buttons.
3. `minimal` is restrained; `detailed` adds visible decoration; `master` is a distinct, richer F4 view. Every level has three **visually distinguishable** states: calm `idle`, active `working`, and resolved `completed`. Maintain identical geometry within a level. Do not represent state solely with a barely visible dot or a tiny color change.
4. `background.png` is separate wallpaper for the canvas. It is not a replacement for the transparent terminal opening. Do not duplicate it under source and output paths in the install ZIP.
5. For each level report `left`, `right`, `top`, and `bottom` aperture insets as percentages of the full 1536 x 1024 frame. Check that all three states of that level use the same safe opening. The user can enter these values in the import dialog; an agent can pass them in a separate `apertures.json` via `skin-install --apertures`. Do not assume the ZIP auto-configures apertures.

## Build and verify

1. Inspect the reference and decide the level/state differences before rendering. Generate or edit the art, then examine all ten final images at their actual resolution. Inspect a contact sheet too, to catch geometry drift and indistinguishable states.
2. Package only the final ten PNGs. Validate the archive from the repository root:

```sh
node scripts/validate-pixel-skin-zip.mjs /absolute/path/theme-install.zip
```

This invokes the same ZIP importer as CanvasTTY in an isolated temporary profile. It checks the exact file set and new-theme frame dimensions. A successful structural check does **not** prove the art looks good.
3. Compare the nine frames overlaid, check the transparent opening and button plaque, and preview with live terminal text in CanvasTTY when possible. Report any visual check that could not be done.
4. Deliver the install ZIP, a small preview/contact sheet, the three aperture presets, and a concise description of what changes in each state. Say whether the theme was actually installed and tested in the app; do not infer that from ZIP validation.

For agent-driven installation in a running CanvasTTY instance, see [the local Agent Control commands](pixel-skin-packs.ru.md#установка-агентом). Installing or changing a theme affects the current user's app; verify the target instance and preserve other installed themes.
61 changes: 61 additions & 0 deletions docs/pixel-skin-packs.ru.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Пиксельные темы терминала

Агенту без контекста проекта передайте [инструкцию по созданию темы](pixel-skin-agent-start.md) и визуальный референс. В настройках CanvasTTY → **Создать пиксельную тему** можно скопировать готовое задание агенту.

Тема состоит из десяти PNG. Девять изображений образуют матрицу из трёх уровней детализации и трёх состояний; десятое служит фоном CanvasTTY.

## Геометрия новых тем

- Все девять рамок: **ровно 1536 × 1024 px, PNG RGBA, пропорция 3:2**. Один и тот же холст без сдвига, обрезки и поворота между состояниями. Не добавляйте вокруг рамки дополнительные поля.
- На CanvasTTY каждой рамке соответствует **фиксированная карточка 1200 × 800 логических px**. Масштаб камеры меняет её размер на экране, но не уровень картинки: настройка выбирает `minimal` или `detailed`, F4 временно включает `master`.
- В каждом уровне координаты внешней рамки, прозрачного проёма, таблички под кнопки и всех неподвижных предметов должны совпадать во всех трёх состояниях. Между уровнями сохраняйте одинаковую внешнюю посадку рамки; меняйте насыщенность декора, а не размер холста.
- Центр проёма должен быть **прозрачным**, чтобы текст настоящего терминала был виден под изображением. Не рисуйте в PNG текст, курсор, чёрный экран терминала или готовые кнопки. Не закрывайте декором проём и зону кнопок.
- `background.png` остаётся отдельным фоном рабочего поля; он не определяет геометрию терминала. Для контрольной проверки накладывайте все девять рамок друг на друга: внешний контур, проём и табличка не должны прыгать.

Старые ZIP другого разрешения импортируются для совместимости, но могут искажаться при приведении к 1200 × 800. Новые темы готовьте строго по указанному холсту.

| Уровень | Ожидание | Работа | Завершено |
| --- | --- | --- | --- |
| Минимальный | `minimal_idle.png` | `minimal_working.png` | `minimal_completed.png` |
| Детальный | `detailed_idle.png` | `detailed_working.png` | `detailed_completed.png` |
| Мастер, F4 | `master_idle.png` | `master_working.png` | `master_completed.png` |

Дополнительный файл: `background.png`. Размещайте десять PNG в ZIP с этими точными именами; вложенная папка допустима. Импорт технически допускает PNG от 320 × 200 до 4096 × 4096, каждый не более 20 МБ; ZIP не более 150 МБ. Для новых рамок применяйте геометрию выше.

**Установочный ZIP и набор исходников — разные артефакты.** В установочном ZIP оставляйте ровно десять финальных PNG. Не складывайте туда одновременно `source/background.png` и `output/background.png`: импортёр увидит повтор. Имя состояния — только `completed`, не `done`. Исходники, промежуточные рендеры, промпты и скрипты можно отдавать отдельным ZIP.

Перед передачей архива проверьте его из корня репозитория:

```sh
node scripts/validate-pixel-skin-zip.mjs /absolute/path/theme-install.zip
```

Проверка запускает реальный импортёр в отдельном временном профиле и не устанавливает тему в вашу CanvasTTY. Визуальную посадку проёма и различимость состояний нужно проверить отдельно.

`idle` означает, что агент сейчас не выполняет ход. `working` включается во время хода. `completed` показывается после явного завершения хода, в том числе при ошибке; следующая работа снова переводит рамку в `working`. Настройка выбирает минимальную или детальную рамку, F4 временно показывает мастер-рамку выбранной темы.

## Установка в приложении

В настройках оформления нажмите **Создать пиксельную тему**. Можно выбрать ZIP целиком или назначить десять PNG по отдельности. При необходимости задайте отступы проёма для каждого уровня: `left`, `right`, `top`, `bottom` в процентах изображения. Все три состояния одного уровня используют одни отступы; декор не должен заходить в этот прямоугольник. После установки тема появляется в списке и сохраняется в профиле CanvasTTY.

## Установка агентом

Включите локальный Agent Control в CanvasTTY. CLI подключается к локальному дескриптору и не требует управления мышью. Для точной геометрии создайте JSON-файл:

```json
{
"minimal": { "left": 10, "right": 10, "top": 16, "bottom": 16 },
"detailed": { "left": 14, "right": 14, "top": 18, "bottom": 19 },
"master": { "left": 15, "right": 15, "top": 21, "bottom": 22 }
}
```

Из корня проекта:

```sh
node scripts/canvastty-control.mjs skin-install --archive /absolute/path/theme.zip --name "My theme" --apertures /absolute/path/apertures.json --activate --detail detailed
node scripts/canvastty-control.mjs skin-list
node scripts/canvastty-control.mjs skin-select pixel:THEME-ID --detail minimal
```

`--apertures` необязателен; без него применяются консервативные отступы. ID установленной темы возвращается при импорте и доступен через `skin-list`. Команды принимают `--connection` и `--client-file` для выбора конкретного экземпляра CanvasTTY; файлы доступа должны оставаться локальными и приватными. Темы сохраняются между перезапусками. Не кладите в ZIP секреты или личные данные: его содержимое становится частью локальной темы.
5 changes: 5 additions & 0 deletions examples/terminal-skins/foundry-seven/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Foundry Seven

A dark, instrument-grade bezel in graphite and aged bronze. Brushed metal edges, a fine calibration rail, and enamel-like controls add depth while keeping the terminal surface clear. The treatment is static, so reduced-motion settings need no override; keyboard focus remains visible.

Skin ID: `custom:foundry-seven` (`foundry-seven` in the manifest).
6 changes: 6 additions & 0 deletions examples/terminal-skins/foundry-seven/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"schemaVersion": 1,
"id": "foundry-seven",
"name": "Foundry Seven",
"kind": "terminal-border"
}
49 changes: 49 additions & 0 deletions examples/terminal-skins/foundry-seven/skin.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* Foundry Seven: a warm, instrument-grade graphite and bronze bezel. */
.terminal-card {
border: 3px solid transparent;
border-radius: 7px;
background: linear-gradient(var(--terminal-background, #202430), var(--terminal-background, #202430)) padding-box,
repeating-linear-gradient(135deg, #ead5a2 0 1px, #987547 1px 2px, #57442c 2px 4px, #b48d53 4px 6px) border-box;
box-shadow: inset 0 1px #fff0c655, inset 0 0 0 1px #17191a,
0 0 0 1px #322719, 0 4px 0 #211a12, 0 14px 28px #000a;
}

.terminal-card .terminal-card__header {
color: #f1e5cd;
background: repeating-linear-gradient(90deg, #fff0c514 0 1px, transparent 1px 11px) top left / 100% 2px no-repeat,
repeating-linear-gradient(90deg, #d4ad6c 0 1px, transparent 1px 9px) bottom left / 100% 3px no-repeat,
linear-gradient(180deg, #655239 0, #37332b 12%, #242624 28%, #171b1c 78%, #111312 96%, #947044 100%);
box-shadow: inset 0 1px #f7e4bd77, inset 0 -1px #090b0b;
}

.terminal-card .terminal-card__surface {
border-top: 1px solid #735632;
box-shadow: inset 0 1px #0d1011;
}

.terminal-card .terminal-card__actions button {
color: #f4dfb4;
border: 1px solid #a17b45;
border-radius: 4px;
background: linear-gradient(145deg, #716044 0, #40382b 42%, #1b1e1e 100%);
box-shadow: inset 0 1px #f5dda078, inset 0 -1px #111312, 0 1px 2px #000a;
}

.terminal-card .terminal-card__actions button:hover {
color: #fff3d6;
border-color: #e1bd7b;
background: linear-gradient(145deg, #907347 0, #51432e 42%, #242625 100%);
}

.terminal-card .terminal-card__actions button:focus-visible {
outline: 2px solid #ffe3a2;
outline-offset: 1px;
box-shadow: 0 0 0 3px #17191a, inset 0 1px #f5dda078;
}

.terminal-card:is(:focus-within, .terminal-card--selected) {
outline: 2px solid #f3d28e;
outline-offset: 3px;
box-shadow: 0 0 0 1px #17130e, 0 0 0 5px #aa8048,
0 4px 0 #211a12, 0 14px 28px #000a;
}
Loading
Loading