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/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: open-webui
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.7.5] - 2026-07-02

### Added

- 🎨 **Appearance controls.** Added a new Appearance settings page so you can adjust how Computer looks and feels without leaving the app.
- 🌳 **Git worktrees.** View, search, open, and create worktrees from the Git panel so you can keep separate branches in separate folders.

### Changed

- 🌍 **More complete language support.** Expanded translations across settings, chat, files, previews, and admin screens so the interface feels more consistent in every supported language.
- 🧩 **Cleaner everyday interface.** Polished menus, dialogs, chat controls, file previews, terminal views, and setup screens for a more consistent experience across desktop and mobile.
- 🌐 **Easier web setup.** Search providers and browser tools now show their keys, base URLs, and helper text in a cleaner layout.

## [0.7.4] - 2026-06-30

### Added
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
![GitHub top language](https://img.shields.io/github/languages/top/open-webui/computer)
![GitHub last commit](https://img.shields.io/github/last-commit/open-webui/computer?color=red)
[![Discord](https://img.shields.io/badge/Discord-Open_WebUI-blue?logo=discord&logoColor=white)](https://discord.gg/5rJgQTnV4s)
[![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/tjbck)
[![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/open-webui)

![Open WebUI Computer Demo](./demo.png)

Expand All @@ -31,6 +31,8 @@ The Docker image includes all optional feature groups.

Or with [uv](https://docs.astral.sh/uv/): `uvx cptr@latest run`

On Windows, if opening a terminal reports a missing `VCRUNTIME140.dll` or Universal CRT DLL, install Microsoft's [Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist) and restart `cptr`.

Opens in your browser at `http://localhost:8000`.

### Access from your phone
Expand Down
192 changes: 185 additions & 7 deletions cptr/frontend/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,26 @@
--color-gray-950: oklch(0.16 0 0);
}

:root {
--app-text-scale: 1;
--app-bg: #ffffff;
--app-fg: #525252;
--app-fg-muted: color-mix(in oklab, var(--app-fg) 62%, var(--app-bg));
--app-fg-subtle: color-mix(in oklab, var(--app-fg) 48%, var(--app-bg));
--app-border: color-mix(in oklab, var(--app-fg) 10%, transparent);
--app-divider: color-mix(in oklab, var(--app-fg) 8%, transparent);
--app-hover: color-mix(in oklab, var(--app-fg) 6%, transparent);
--app-active: color-mix(in oklab, var(--app-fg) 7%, transparent);
--app-ui-font: var(--font-sans);
}

@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
border-color: var(--app-border, var(--color-gray-200, currentColor));
}

html,
Expand All @@ -40,6 +53,9 @@
overscroll-behavior: none;
scrollbar-width: none;
-ms-overflow-style: none;
background: var(--app-bg);
color: var(--app-fg);
font-family: var(--app-ui-font);
}

html::-webkit-scrollbar,
Expand All @@ -50,6 +66,7 @@
html {
color-scheme: dark light;
touch-action: manipulation;
font-size: calc(1rem * var(--app-text-scale, 1));
}

button {
Expand All @@ -62,7 +79,7 @@
--tw-border-opacity: 1;
background-color: rgba(215, 215, 215, 0.6);
border-color: rgba(255, 255, 255, var(--tw-border-opacity));
border-radius: 9999px;
border-radius: 624.9375rem;
border-width: 1px;
}

Expand All @@ -79,7 +96,7 @@

::-webkit-scrollbar-track {
background-color: transparent;
border-radius: 9999px;
border-radius: 624.9375rem;
}

.scrollbar-hidden,
Expand All @@ -99,6 +116,167 @@
visibility: visible;
}

.app-theme {
background: var(--app-bg);
color: var(--app-fg);
}

.app-surface {
background: var(--app-bg);
color: var(--app-fg);
border-color: var(--app-border);
}

.app-subtle-surface {
background: var(--app-bg);
color: var(--app-fg);
border-color: var(--app-border);
}

.app-divider {
background: var(--app-divider);
}

.app-muted {
color: var(--app-fg-muted);
}

.app-icon-muted {
color: var(--app-fg-subtle);
}

.app-interactive:hover {
background: var(--app-hover);
color: var(--app-fg);
}

.app-interactive-active {
background: var(--app-active);
color: var(--app-fg);
}

.app-theme:where([class*='border-gray-'], [class*='border-black/'], [class*='border-white/']),
.app-theme :where([class*='border-gray-'], [class*='border-black/'], [class*='border-white/']) {
border-color: var(--app-border);
}

.dark .app-theme:where([class*='dark:border-gray-'], [class*='dark:border-white/']),
.dark .app-theme :where([class*='dark:border-gray-'], [class*='dark:border-white/']) {
border-color: var(--app-border);
}

.app-theme
:where(
[class*='divide-gray-'] > :not(:last-child),
[class*='divide-black/'] > :not(:last-child),
[class*='divide-white/'] > :not(:last-child)
) {
border-color: var(--app-border);
}

.dark .app-theme :where([class*='dark:divide-gray-'] > :not(:last-child)),
.dark .app-theme :where([class*='dark:divide-white/'] > :not(:last-child)) {
border-color: var(--app-border);
}

.app-theme :where([class~='h-px'][class*='bg-gray-'], [class~='h-px'][class*='bg-black/']) {
background: var(--app-divider);
}

.dark .app-theme :where([class~='h-px'][class*='dark:bg-white/']) {
background: var(--app-divider);
}

.app-theme
:where(
[class~='bg-gray-50'],
[class~='bg-gray-50/50'],
[class~='bg-gray-100'],
[class~='bg-gray-200/50']
) {
background: var(--app-hover);
}

.dark
.app-theme
:where(
[class~='dark:bg-white/3'],
[class~='dark:bg-white/4'],
[class~='dark:bg-white/5'],
[class~='dark:bg-white/6'],
[class~='dark:bg-white/8'],
[class~='dark:bg-white/10']
) {
background: var(--app-hover);
}

.app-theme
:where(
[class~='hover:bg-gray-50']:hover,
[class~='hover:bg-gray-100']:hover,
[class~='hover:bg-gray-200']:hover,
[class~='hover:bg-gray-200/60']:hover,
[class~='hover:bg-gray-200/70']:hover
) {
background: var(--app-active);
}

.dark
.app-theme
:where(
[class~='dark:hover:bg-white/3']:hover,
[class~='dark:hover:bg-white/4']:hover,
[class~='dark:hover:bg-white/5']:hover,
[class~='dark:hover:bg-white/6']:hover,
[class~='dark:hover:bg-white/8']:hover,
[class~='dark:hover:bg-white/10']:hover,
[class~='dark:hover:bg-white/12']:hover
) {
background: var(--app-active);
}

.app-theme
:where(
[class~='text-gray-950'],
[class~='text-gray-900'],
[class~='text-gray-800'],
[class~='text-gray-700']
) {
color: var(--app-fg);
}

.dark
.app-theme
:where(
[class~='dark:text-white'],
[class~='dark:text-gray-100'],
[class~='dark:text-gray-200'],
[class~='dark:text-gray-300']
) {
color: var(--app-fg);
}

.app-theme
:where(
[class~='text-gray-600'],
[class~='text-gray-500'],
[class~='text-gray-400'],
[class~='text-gray-300']
) {
color: var(--app-fg-muted);
}

.dark
.app-theme
:where(
[class~='dark:text-gray-400'],
[class~='dark:text-gray-500'],
[class~='dark:text-gray-600'],
[class~='dark:text-gray-700']
) {
color: var(--app-fg-muted);
}

/* CodeMirror - match Open WebUI */
.cm-editor {
height: 100%;
Expand Down Expand Up @@ -197,9 +375,9 @@
.tippy-box[data-theme~='cptr'] {
background: #1a1a1a;
color: #e0e0e0;
font-size: 11px;
font-size: 0.6875rem;
font-weight: 500;
padding: 2px 4px;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
padding: 0.125rem 0.25rem;
border-radius: 0.375rem;
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.3);
}
6 changes: 6 additions & 0 deletions cptr/frontend/src/lib/apis/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ export const getGitShow = (root: string, ref: string) =>
export const getGitBranches = (root: string) =>
fetchJSON(`/api/git/branches?root=${encodeURIComponent(root)}`);

export const getGitWorktrees = (root: string) =>
fetchJSON(`/api/git/worktrees?root=${encodeURIComponent(root)}`);

export const createGitWorktree = (root: string, branch: string, path?: string) =>
fetchJSON('/api/git/worktrees', jsonBody({ root, branch, path }));

export const getGitStashes = (root: string) =>
fetchJSON(`/api/git/stashes?root=${encodeURIComponent(root)}`);

Expand Down
3 changes: 1 addition & 2 deletions cptr/frontend/src/lib/apis/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ export const updateMemory = (
scope: MemoryScope,
workspace: string,
operations: MemoryOperation[]
) =>
fetchJSON('/api/memory/update', jsonBody({ scope, workspace, operations }));
) => fetchJSON('/api/memory/update', jsonBody({ scope, workspace, operations }));

export const searchMemory = (body: {
query?: string;
Expand Down
Loading
Loading