Compare commits

..

2 Commits

Author SHA1 Message Date
nntrivi2001 890cd08f57 chore: v2.8.76 — four new colour themes: Sunset Cloud, Terminal, Night Sea and Sakura 2026-11-05 13:54:01 +07:00
nntrivi2001 aabc95768c feat(appearance): Sunset Cloud, Terminal, Night Sea and Sakura colour themes
Four named themes from ai-chat-themes (MIT; colours only — no wallpapers,
fonts or custom CSS): three dark ones beside Darcula / Apple Dark / Orca
Dark and Sakura beside the light ones. Each theme's background, text and
accent colour become the full token ramp, held to the existing contrast
bar (text and fg-muted >= 4.5:1 on every surface, accent on its /15 chip,
white on accent-solid, status labels on their /20 chip). Old Paper was
left out.

The terminal took its ANSI blue from --accent, which would print blue as
green (Terminal) or coral next to red (Sunset Cloud); a theme can now set
--ansi-blue, which lib/terminalTheme.ts prefers.
2026-11-05 12:15:21 +07:00
12 changed files with 140 additions and 11 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# Claude Code Working Guide
_Last synced: v2.8.74 (2026-11-05) — a page published from its session's scratchpad keeps a viewable copy._ A change that makes any statement in this file, `AGENTS.md`, or a README wrong — a moved path, a new or changed extension point, a retired rule — updates that file in the same change-set and bumps this marker. **Bump = replace the version/date and a ≤ 1-line summary; never append a changelog here** — details belong in the commit message and `docs/`, because this whole file is loaded into every session.
_Last synced: v2.8.76 (2026-11-05) — four colour themes (Sunset Cloud, Terminal, Night Sea, Sakura); `--ansi-blue` for a non-blue accent._ A change that makes any statement in this file, `AGENTS.md`, or a README wrong — a moved path, a new or changed extension point, a retired rule — updates that file in the same change-set and bumps this marker. **Bump = replace the version/date and a ≤ 1-line summary; never append a changelog here** — details belong in the commit message and `docs/`, because this whole file is loaded into every session.
## Project mission
- Maintain a reliable local-first dashboard for Claude Code session monitoring.
@@ -60,6 +60,10 @@ export const THEME_LABELS: Record<string, string> = {
canvas: "Canvas",
"orca-dark": "Orca Dark",
"orca-light": "Orca Light",
"sunset-cloud": "Sunset Cloud",
terminal: "Terminal",
"night-sea": "Night Sea",
sakura: "Sakura",
};
const MODES: { mode: ThemeMode; Icon: typeof Moon }[] = [
@@ -53,6 +53,10 @@ describe("AppearanceSettings", () => {
"Apple Light",
"Canvas",
"Orca Light",
"Sunset Cloud",
"Terminal",
"Night Sea",
"Sakura",
]) {
expect(screen.getByText(name)).toBeInTheDocument();
}
@@ -103,6 +103,19 @@ describe("useTheme", () => {
expect(document.documentElement.dataset.theme).toBe("orca-light");
});
it("applies the ai-chat-themes palettes by id, each in its own mode only", () => {
const { result } = renderHook(() => useTheme());
for (const name of ["sunset-cloud", "terminal", "night-sea"]) {
act(() => result.current.setThemeFor("dark", name));
expect(document.documentElement.dataset.theme).toBe(name);
}
act(() => result.current.setThemeFor("dark", "sakura"));
expect(result.current.themeFor.dark).toBe("night-sea");
act(() => result.current.setThemeFor("light", "sakura"));
act(() => result.current.toggleTheme());
expect(document.documentElement.dataset.theme).toBe("sakura");
});
it("the default theme carries no data-theme attribute", () => {
const { result } = renderHook(() => useTheme());
act(() => result.current.setThemeFor("dark", "darcula"));
+2 -2
View File
@@ -22,8 +22,8 @@ export type ThemeMode = Theme | "system";
/** Named themes per mode, in picker order. `default` is the stock palette. */
export const THEMES = {
dark: ["default", "darcula", "apple-dark", "orca-dark"],
light: ["default", "canvas", "apple-light", "orca-light"],
dark: ["default", "darcula", "apple-dark", "orca-dark", "sunset-cloud", "terminal", "night-sea"],
light: ["default", "canvas", "apple-light", "orca-light", "sakura"],
} as const satisfies Record<Theme, readonly string[]>;
const MODE_KEY = "theme";
+100
View File
@@ -350,6 +350,106 @@
--syn-del: 197 0 15; /* #c5000f */
}
/* Sunset Cloud, Terminal, Night Sea (dark) and Sakura (light) — the colour
* themes of ai-chat-themes (github.com/Aohkne/ai-chat-themes, MIT), which
* gives only a background, a text and an accent colour per theme. Every
* other token is derived from those three and held to the bar above: text
* ≥ 4.5:1 on a card and on its hover lift, the text accent ≥ 4.5:1 on a card
* and on its own /15 chip (Sakura's #e0567f and Sunset's #ff8a6b darkened /
* lightened to get there), white ≥ 4.5:1 on `--accent-solid`, each status
* label ≥ 4.5:1 on its /20 chip. Their fonts (a monospace UI, Georgia) are
* not taken; syntax, diff and `--kept` colours are their mode's defaults.
* `--ansi-blue` (read only by `lib/terminalTheme.ts`) keeps a terminal's
* blue blue where the accent is green or coral. */
.dark[data-theme="sunset-cloud"] {
--surface-0: 32 24 36; /* #201824 */
--surface-1: 48 37 52; /* #302534 */
--surface-2: 54 43 58; /* #362b3a */
--surface-3: 60 49 63; /* #3c313f */
--surface-4: 67 56 69; /* #433845 */
--surface-5: 75 63 76; /* #4b3f4c */
--border: 76 64 76; /* #4c404c */
--border-light: 88 76 87; /* #584c57 */
--accent: 255 159 134; /* #ff9f86 */
--accent-hover: 255 188 170; /* #ffbcaa */
--accent-solid: 173 94 73; /* #ad5e49 */
--accent-solid-hover: 149 81 63; /* #95513f */
--fg-primary: 247 232 226; /* #f7e8e2 */
--fg-secondary: 214 203 203; /* #d6cbcb */
--fg-muted: 176 165 168; /* #b0a5a8 */
--status-success: 88 220 156; /* #58dc9c */
--status-danger: 255 176 173; /* #ffb0ad */
--status-warning: 255 202 22; /* #ffca16 */
/* ANSI blue in the terminal: the accent is not blue here. */
--ansi-blue: 112 184 255; /* #70b8ff */
}
.dark[data-theme="terminal"] {
--surface-0: 8 13 9; /* #080d09 */
--surface-1: 14 23 17; /* #0e1711 */
--surface-2: 20 30 22; /* #141e16 */
--surface-3: 25 36 28; /* #19241c */
--surface-4: 31 44 34; /* #1f2c22 */
--surface-5: 37 52 41; /* #253429 */
--border: 38 54 42; /* #26362a */
--border-light: 49 67 53; /* #314335 */
--accent: 57 232 122; /* #39e87a */
--accent-hover: 116 239 162; /* #74efa2 */
--accent-solid: 32 132 70; /* #208446 */
--accent-solid-hover: 28 114 60; /* #1c723c */
--fg-primary: 185 246 198; /* #b9f6c6 */
--fg-secondary: 147 196 157; /* #93c49d */
--fg-muted: 117 154 125; /* #759a7d */
--status-success: 61 214 140; /* #3dd68c */
--status-danger: 255 149 146; /* #ff9592 */
--status-warning: 255 202 22; /* #ffca16 */
/* ANSI blue in the terminal: the accent is not blue here. */
--ansi-blue: 112 184 255; /* #70b8ff */
}
.dark[data-theme="night-sea"] {
--surface-0: 11 20 33; /* #0b1421 */
--surface-1: 20 31 49; /* #141f31 */
--surface-2: 26 37 55; /* #1a2537 */
--surface-3: 32 43 62; /* #202b3e */
--surface-4: 40 50 69; /* #283245 */
--surface-5: 47 58 76; /* #2f3a4c */
--border: 48 59 77; /* #303b4d */
--border-light: 60 71 89; /* #3c4759 */
--accent: 92 175 255; /* #5cafff */
--accent-hover: 141 199 255; /* #8dc7ff */
--accent-solid: 62 120 176; /* #3e78b0 */
--accent-solid-hover: 53 103 151; /* #356797 */
--fg-primary: 220 230 250; /* #dce6fa */
--fg-secondary: 183 192 210; /* #b7c0d2 */
--fg-muted: 146 155 173; /* #929bad */
--status-success: 61 214 140; /* #3dd68c */
--status-danger: 255 155 153; /* #ff9b99 */
--status-warning: 255 202 22; /* #ffca16 */
}
[data-mode="light"][data-theme="sakura"] {
--surface-0: 242 230 232; /* #f2e6e8 */
--surface-1: 247 235 237; /* #f7ebed */
--surface-2: 251 240 242; /* #fbf0f2 */
--surface-3: 255 249 250; /* #fff9fa */
--surface-4: 255 252 253; /* #fffcfd */
--surface-5: 255 255 255; /* #ffffff */
--border: 224 210 213; /* #e0d2d5 */
--border-light: 237 224 227; /* #ede0e3 */
--accent: 167 64 95; /* #a7405f */
--accent-hover: 137 52 78; /* #89344e */
--accent-solid: 195 75 110; /* #c34b6e */
--accent-solid-hover: 168 65 95; /* #a8415f */
--fg-primary: 75 42 53; /* #4b2a35 */
--fg-secondary: 107 80 89; /* #6b5059 */
--fg-muted: 120 97 105; /* #786169 */
--status-success: 23 105 45; /* #17692d */
--status-danger: 173 28 38; /* #ad1c26 */
--status-warning: 124 82 0; /* #7c5200 */
--shadow-card: 0 1px 2px rgb(75 42 53 / 0.06), 0 2px 6px rgb(75 42 53 / 0.07);
}
@layer base {
body {
font-weight: 500;
@@ -39,6 +39,11 @@ describe("buildTerminalTheme", () => {
expect(t.brightWhite).toBe("#edeef0");
});
it("takes ANSI blue from --ansi-blue when a theme's accent is not blue", () => {
const t = buildTerminalTheme((n) => ({ ...vars, "--ansi-blue": "112 184 255" })[n] ?? "");
expect(t.blue).toBe("#70b8ff");
});
it("makes each bright twin lighter than its base colour", () => {
const t = buildTerminalTheme((n) => vars[n] ?? "");
const sum = (hex: string) =>
+4 -2
View File
@@ -40,7 +40,9 @@ function lighten(hex: string | undefined, amount: number): string | undefined {
/**
* Build an xterm theme from a theme's CSS variables. red/green/yellow come from
* `--status-*`, blue from `--accent`, black/white from the surface/fg ramp.
* `--status-*`, blue from `--ansi-blue` when a theme sets one (its accent is
* not blue: Terminal's green, Sunset Cloud's coral) else `--accent`,
* black/white from the surface/fg ramp.
* Magenta and cyan stay the classic ANSI hues: no token keeps that hue in every
* theme (darcula's keyword is orange), and a program printing "magenta" should
* get magenta.
@@ -50,7 +52,7 @@ export function buildTerminalTheme(read: VarReader): ITheme {
const red = v("--status-danger");
const green = v("--status-success");
const yellow = v("--status-warning");
const blue = v("--accent");
const blue = v("--ansi-blue") ?? v("--accent");
const magenta = "#c678dd";
const cyan = "#56b6c2";
return {
@@ -7316,7 +7316,7 @@ exports[`screen snapshots > Settings — about 1`] = `
<span
class="text-status-warning/90"
>
UI build v2.8.75 (rebuild client to match)
UI build v2.8.76 (rebuild client to match)
</span>
</p>
</div>
+3 -2
View File
@@ -84,8 +84,9 @@ Internal build — all rights reserved.
- **Updates.** Release-based update detection with an in-UI **Update all**
(marketplaces → every plugin → AgentHub last → one session reload).
- **Appearance.** Settings → Appearance picks Dark / Light / System (follows the
OS live) and a theme per mode — dark: Default, Darcula, Apple Dark, Orca Dark;
light: Default, Apple Light, Canvas, Orca Light. Each mode
OS live) and a theme per mode — dark: Default, Darcula, Apple Dark, Orca Dark,
Sunset Cloud, Terminal, Night Sea; light: Default, Apple Light, Canvas, Orca
Light, Sakura (the four last from ai-chat-themes, colours only). Each mode
remembers its own theme, so the sidebar's quick toggle swaps between the two.
It also picks the workspace terminals' font: JetBrains Mono (default), the
rounded Maple Mono, or the browser's own fixed-width
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "agenthub",
"version": "2.8.75",
"version": "2.8.76",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "agenthub",
"version": "2.8.75",
"version": "2.8.76",
"hasInstallScript": true,
"license": "UNLICENSED",
"dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "agenthub",
"version": "2.8.75",
"version": "2.8.76",
"bin": {
"agenthub": "bin/agenthub.js"
},