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
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
artifact: canvastty-macos
runs-on: ${{ matrix.runner }}
steps:
- name: Note plugin showcase sign-in availability
if: ${{ vars.CANVASTTY_GITHUB_CLIENT_ID == '' }}
run: echo "::warning::CANVASTTY_GITHUB_CLIENT_ID is not set. The plugin showcase still works anonymously; GitHub sign-in is unavailable in this build."
- name: Check out repository
uses: actions/checkout@v7
- name: Set up Node.js
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Dependencies and generated application output
node_modules/
node_modules
bun.lock
out/
dist/
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
- Limited WebGL to the focused terminal card: one context at a time, disposed when focus leaves, with a fallback to the DOM renderer when the context is lost. Palette and transparency rendering are unchanged.
- Added a self-update section in Settings → Updates with the honest states: idle, checking, update available with the version, downloading with the percent when known, ready to install, and unavailable for dev, offline, or error. Downloading and installing are explicit user actions, install-and-restart is offered only once the update is downloaded, and in development the row reports unavailable instead of throwing.
- Hardened the repository secret audit to ignore key prefixes embedded inside identifiers, so names such as `disk-…` or `task-…` no longer produce false positives while real keys still match.
- Added Cursor, MiniMax Code, Devin and Antigravity agents (PR #63).
- Added provider API keys, API profiles and agent-to-agent delegation through the orchestration MCP (PR #64).
- The plugin showcase works without a GitHub account; signing in is optional and only raises GitHub's limits (issue #22). The HOME clock shows the date (issue #53).
- The default session denies web permissions, a crashed renderer reloads, long agent answers keep their turn, and the secret audit also checks the built bundle (from PRs #35 and #51).
## 1.5.2

- Fixed terminal history jumping to the beginning when Codex clears and redraws its history after a card resize. Readers retain their relative scroll position, while terminals at the bottom continue following new output.
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
- WebGL ограничен сфокусированной карточкой терминала: один контекст одновременно, освобождается при уходе фокуса, при потере контекста используется DOM-renderer. Отрисовка палитры и прозрачности не изменилась.
- В «Настройках → Обновления» появилась строка самообновления с честными состояниями: простой, проверка, доступно обновление (с версией), загрузка (с процентом, когда он известен), готово к установке и недоступно (dev, offline или ошибка). Загрузка и установка — явные действия пользователя, установка с перезапуском предлагается только после загрузки обновления, а в режиме разработки строка сообщает о недоступности и не выбрасывает исключение.
- Аудит секретов в репозитории больше не срабатывает на префиксы ключей внутри идентификаторов, поэтому имена вида `disk-…` и `task-…` не дают ложных срабатываний, а настоящие ключи по-прежнему находятся.
- Добавлены агенты Cursor, MiniMax Code, Devin и Antigravity (PR #63).
- Добавлены API-ключи провайдеров, API-профили и делегирование между агентами через MCP оркестрации (PR #64).
- Витрина плагинов работает без аккаунта GitHub; вход необязателен и только повышает лимиты GitHub (issue #22). Часы на HOME показывают дату (issue #53).
- Основная сессия отклоняет веб-разрешения, упавший интерфейс перезагружается, длинные ответы агентов сохраняют свой ход, а проверка секретов проверяет и собранный бандл (из PR #35 и #51).
## 1.5.2

- Исправлен прыжок терминала в начало истории, когда Codex очищает и заново рисует её после изменения размера карточки. При чтении сохраняется относительная позиция прокрутки, а терминал в конце истории продолжает следить за новым выводом.
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
- WebGL 仅用于聚焦的终端卡片:同一时间只有一个 context,焦点离开时释放;context 丢失时回退到 DOM renderer。调色板与透明度渲染保持不变。
- Settings → Updates 新增一行自更新,状态如实呈现:idle、checking、update available(含版本号)、downloading(已知时显示百分比)、ready to install 以及 unavailable(dev、offline 或 error)。下载与安装都是显式操作,只有在更新下载完成后才提供 install-and-restart;开发模式下该行报告 unavailable 而不会抛错。
- 仓库密钥审计不再把标识符内部的密钥前缀当作命中,因此 `disk-…`、`task-…` 这类名称不再产生误报,而真实密钥仍会被检出。
- 新增 Cursor、MiniMax Code、Devin 和 Antigravity 智能体(PR #63)。
- 新增提供商 API 密钥、API 配置文件,以及通过编排 MCP 在智能体之间委派任务(PR #64)。
- 插件展示页无需 GitHub 账号即可使用;登录是可选的,只会提高 GitHub 限额(issue #22)。HOME 时钟显示日期(issue #53)。
- 默认会话拒绝网页权限,渲染进程崩溃后会重新加载,较长的智能体回答会保留其轮次,密钥审计也会检查构建产物(来自 PR #35 和 #51)。
## 1.5.2

- 修复调整卡片大小后,Codex 清空并重新绘制历史时终端跳到历史开头的问题。阅读时保留相对滚动位置,位于底部的终端继续跟随新输出。
Expand Down
2 changes: 1 addition & 1 deletion docs/UI_CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ This contract preserves the approved MVP concept and prevents feature ownership
- Click focus has three explicit modes: Off, Single click, and Double click. It is off by default. Selection and its visible outline still work when camera focus is off; a double-click mode never jumps the camera on the first click. Window stacking is independent: an ordinary primary click always raises the pressed terminal, plugin, Browser, or note card.
- Selection is currently exclusive across terminals and the built-in Browser: pressing on empty canvas clears it. Input focus is tracked independently so future multi-selection does not have to redefine wheel ownership.
- Hover focus is an off-by-default input-focus mode. After a configurable delay (slow `500ms`, normal `250ms`, fast `80ms`), an input-bearing widget under the pointer receives logical focus without changing selection; terminal and native Browser keyboard input follows that focus. Pointer leave only cancels a pending transfer; assigned focus remains until another focusable widget is clicked/hovered or the user clicks outside every widget. Focusable surfaces are terminals, the native Browser, plugin iframe/canvas surfaces, and actually scrollable HOME lists; decorative and action-only tiles do not take focus.
- Go to HOME and Rename window are separate user-remappable Controls rows with their own short descriptions; there is no duplicate standalone shortcut list. Defaults are `Home` for focusing the Home zone and `F2` for renaming the selected terminal window. Either action also accepts Mouse3/Mouse4/Mouse5 with optional modifiers. Rename is an inline header edit and does not recreate the PTY. A compact passive canvas hint reflects the persisted bindings immediately, can be hidden, and can be placed in any corner from Appearance.
- Go to HOME, Toggle terminal fullscreen, and Rename window are separate user-remappable Controls rows with their own short descriptions. Defaults are `Home`, `Super+F` (`Command+F` on macOS), and `F2`. These actions also accept Mouse3/Mouse4/Mouse5 with optional modifiers. Rename is an inline header edit and does not recreate the PTY. Escape remains terminal input rather than closing fullscreen. A compact canvas hint reflects the persisted bindings immediately, can be hidden, and can be placed in any corner from Appearance. Controls and an expandable section in the hint share a reference of fixed shortcuts, including their terminal/menu context.
- Snapping is enabled by default and can be disabled without changing existing window bounds. Edge panning remains off by default and exposes slow/normal/fast speed. Wheel direction is configurable separately for terminal scrolling and canvas navigation; canvas inversion applies to both pan axes and historical wheel zoom. Fresh profiles pan on ordinary scroll, while migrated profiles retain ordinary wheel zoom, direction, and sensitivity.

## Visual system
Expand Down
44 changes: 44 additions & 0 deletions docs/fullscreen-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Fullscreen Mode for Terminal Sessions

CanvasTTY supports fullscreen mode for terminal sessions, allowing you to expand any session to fill the entire viewport for focused work.

## How to Use

### Enter Fullscreen

- **Header button:** Click the maximize icon (⛶) in the terminal card header.
- **Keyboard:** Select a terminal and press `Super+F` (`Command+F` on macOS). Change the binding in Settings → Controls → Terminal fullscreen.

### Exit Fullscreen

- **Close button:** Click the X button in the top-right corner of the fullscreen session.
- **Header button:** Click the restore icon (❐) in the terminal card header.
- **Keyboard:** Press the same fullscreen shortcut again. `Escape` remains available to the terminal application and never exits fullscreen.

## Behavior

- **Camera preserved:** When you exit fullscreen, the canvas camera (pan/zoom) stays where you left it. If you navigated during fullscreen, the camera won't snap back.
- **Single session only:** Only one session can be fullscreen at a time. Opening fullscreen for another session automatically closes the previous one.
- **No bounds persistence:** Fullscreen mode is CSS-only — it does not modify the session's saved position or size. If the app crashes during fullscreen, the session restores at its original layout on restart.
- **Header hidden:** The terminal card header and resize handles are hidden in fullscreen, maximizing the terminal surface area.

## Architecture

Fullscreen is implemented as a **CSS overlay layer** separate from the canvas camera transform:

1. `App.tsx` tracks `fullscreenSessionId` state and passes it down to `WorkspaceCanvas`.
2. `WorkspaceCanvas` splits rendering into two groups:
- **Normal layer** (`workspace__windows`): all sessions *except* the fullscreen one.
- **Fullscreen layer** (`workspace__fullscreen-layer`): only the fullscreen session, rendered outside the camera transform with `position: absolute; inset: 0`.
3. `TerminalCard` receives a `fullscreen` prop and applies the `terminal-card--fullscreen` CSS class, which overrides dimensions, removes borders/shadows, and hides the header.

This design avoids coordinate-system conflicts between the canvas pan/zoom transform and the fullscreen overlay.

## Internationalization

Fullscreen UI strings are localized in `src/renderer/src/lib/i18n.ts`:

| Key | English | Russian |
|------------------|----------------------|-------------------------------|
| `enterFullscreen`| Enter fullscreen | Развернуть на весь экран |
| `exitFullscreen` | Exit fullscreen | Свернуть из полноэкранного |
2 changes: 1 addition & 1 deletion docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ Context updates include the active CanvasTTY locale and palette. Plugins own the

The current installer intentionally rejects private repositories, GitHub `/tree/branch/subdirectory` links, and repositories that require a build step. Publish a ready-to-run static package at the repository root.

The optional showcase sign-in uses GitHub's OAuth device flow. Build maintainers can [register an OAuth App and enable Device Flow](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app), then store its public client ID in the `CANVASTTY_GITHUB_CLIENT_ID` GitHub Actions repository variable. Official builds bake in that value when configured; local builds can use `GITHUB_OAUTH_CLIENT_ID` or `CANVASTTY_GITHUB_CLIENT_ID`, and either variable can also override the bundled value at runtime. No client secret is shipped or required. Sign-in opens GitHub in CanvasTTY's built-in Browser by default and offers the system browser as an explicit fallback. Without a client ID the UI reports that OAuth is unavailable, while direct repository inspection and installation continue to work. Signing out removes the encrypted local session; revoke the OAuth grant separately under [GitHub application settings](https://github.com/settings/applications) when needed.
Browsing and searching the showcase work without an account through GitHub's public search API. Signing in is optional and only raises GitHub's search limits; when the anonymous limit is reached, CanvasTTY shows when to try again. The optional showcase sign-in uses GitHub's OAuth device flow. Build maintainers can [register an OAuth App and enable Device Flow](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app), then store its public client ID in the `CANVASTTY_GITHUB_CLIENT_ID` GitHub Actions repository variable. Official builds bake in that value when configured; local builds can use `GITHUB_OAUTH_CLIENT_ID` or `CANVASTTY_GITHUB_CLIENT_ID`, and either variable can also override the bundled value at runtime. No client secret is shipped or required. Sign-in opens GitHub in CanvasTTY's built-in Browser by default and offers the system browser as an explicit fallback. Without a client ID the UI reports that OAuth is unavailable, while direct repository inspection and installation continue to work. Signing out removes the encrypted local session; revoke the OAuth grant separately under [GitHub application settings](https://github.com/settings/applications) when needed.

## Author checklist

Expand Down
2 changes: 1 addition & 1 deletion docs/plugins.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ Context сообщает текущие locale и palette CanvasTTY. Локал

Установщик намеренно не принимает приватные репозитории, ссылки GitHub вида `/tree/branch/subdirectory` и репозитории, которым нужен build. Публикуйте готовый пакет в корне.

Опциональный вход в витрину использует GitHub OAuth Device Flow. Сопровождающий сборку может [зарегистрировать OAuth App и включить Device Flow](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app), затем сохранить его публичный client ID в repository variable GitHub Actions `CANVASTTY_GITHUB_CLIENT_ID`. Официальная сборка встраивает это значение, когда оно настроено; для локальной сборки подходят `GITHUB_OAUTH_CLIENT_ID` и `CANVASTTY_GITHUB_CLIENT_ID`, а при запуске любая из них может переопределить встроенный ID. Client secret в приложение не встраивается и не требуется. По умолчанию вход открывает GitHub во встроенном Browser CanvasTTY, а системный браузер остаётся явным fallback. Без client ID интерфейс прямо сообщает, что OAuth недоступен, но проверка и установка по прямой ссылке продолжают работать. Отключение удаляет локальную зашифрованную сессию; при необходимости отдельно отзовите доступ в [настройках приложений GitHub](https://github.com/settings/applications).
Просмотр и поиск в витрине работают без входа, через публичный поиск GitHub. Вход необязателен и только повышает лимиты поиска GitHub; когда анонимный лимит исчерпан, CanvasTTY показывает, когда можно повторить. Опциональный вход в витрину использует GitHub OAuth Device Flow. Сопровождающий сборку может [зарегистрировать OAuth App и включить Device Flow](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app), затем сохранить его публичный client ID в repository variable GitHub Actions `CANVASTTY_GITHUB_CLIENT_ID`. Официальная сборка встраивает это значение, когда оно настроено; для локальной сборки подходят `GITHUB_OAUTH_CLIENT_ID` и `CANVASTTY_GITHUB_CLIENT_ID`, а при запуске любая из них может переопределить встроенный ID. Client secret в приложение не встраивается и не требуется. По умолчанию вход открывает GitHub во встроенном Browser CanvasTTY, а системный браузер остаётся явным fallback. Без client ID интерфейс прямо сообщает, что OAuth недоступен, но проверка и установка по прямой ссылке продолжают работать. Отключение удаляет локальную зашифрованную сессию; при необходимости отдельно отзовите доступ в [настройках приложений GitHub](https://github.com/settings/applications).

## Чек-лист автора

Expand Down
Loading
Loading