diff --git a/docs/audit/2026-06-08-webssh-classic-terminal-theme.md b/docs/audit/2026-06-08-webssh-classic-terminal-theme.md new file mode 100644 index 00000000..5285d7ef --- /dev/null +++ b/docs/audit/2026-06-08-webssh-classic-terminal-theme.md @@ -0,0 +1,31 @@ +# 审计 — WebSSH 黑底白字 ANSI 主题(2026-06-08) + +**Changelog**: `docs/changelog/2026-06-08-webssh-classic-terminal-theme.md` + +## 审计范围 + +| 模块 | 文件 | +|------|------| +| 主题 | `frontend/src/composables/terminal/xtermTheme.ts` | +| 会话 | `frontend/src/composables/terminal/useTerminalSessions.ts` | +| 页面 | `frontend/src/pages/TerminalPage.vue` | +| 区域 | `frontend/src/components/terminal/TerminalArea.vue` | + +## Step 3 + +| H | 规则 | 结论 | +|---|------|------| +| H1 | 固定黑底白字 | PASS — 不随 Vuetify 浅色切换 | +| H2 | ANSI 16 色 | PASS — drawBoldTextInBrightColors | +| H3 | 无后端变更 | PASS — 纯前端 | + +## Closure + +| H | 判定 | +|---|------| +| H1–H3 | PASS | + +## DoD + +- [x] frontend vite build +- [x] changelog diff --git a/docs/changelog/2026-06-08-webssh-classic-terminal-theme.md b/docs/changelog/2026-06-08-webssh-classic-terminal-theme.md new file mode 100644 index 00000000..d07b8fe2 --- /dev/null +++ b/docs/changelog/2026-06-08-webssh-classic-terminal-theme.md @@ -0,0 +1,24 @@ +# 2026-06-08 — WebSSH 终端固定黑底白字 ANSI 配色 + +## 摘要 + +WebSSH xterm 不再跟随 Vuetify 浅色主题,固定经典黑底白字 + 16 色 ANSI。 + +## 动机 + +浅色模式下终端呈白底深字,不符合 SSH 终端习惯;用户要求黑底白字带字符颜色。 + +## 涉及文件 + +- `frontend/src/composables/terminal/xtermTheme.ts`(新增) +- `frontend/src/composables/terminal/useTerminalSessions.ts` +- `frontend/src/pages/TerminalPage.vue` +- `frontend/src/components/terminal/TerminalArea.vue` + +## 验证 + +```bash +cd frontend && npm run build +``` + +浏览器:终端页连接 SSH,`ls --color=auto`、`grep --color` 等应显示彩色输出。 diff --git a/frontend/src/components/terminal/TerminalArea.vue b/frontend/src/components/terminal/TerminalArea.vue index 4c17c828..df106a46 100644 --- a/frontend/src/components/terminal/TerminalArea.vue +++ b/frontend/src/components/terminal/TerminalArea.vue @@ -92,6 +92,7 @@ defineExpose({ containerRef }) position: relative; min-height: 0; overflow: hidden; + background: #000000; } .terminal-area__overlay { z-index: 4; diff --git a/frontend/src/composables/terminal/useTerminalSessions.ts b/frontend/src/composables/terminal/useTerminalSessions.ts index 73b0dffe..7b373a63 100644 --- a/frontend/src/composables/terminal/useTerminalSessions.ts +++ b/frontend/src/composables/terminal/useTerminalSessions.ts @@ -1,6 +1,5 @@ import { ref, computed, watch, nextTick, type Ref } from 'vue' import { useRoute, useRouter } from 'vue-router' -import { useTheme } from 'vuetify' import { Terminal } from '@xterm/xterm' import { FitAddon } from '@xterm/addon-fit' import { WebLinksAddon } from '@xterm/addon-web-links' @@ -25,13 +24,13 @@ import { } from './types' import { useTerminalSettings } from './useTerminalSettings' import { useTerminalCmdBar } from './useTerminalCmdBar' +import { XTERM_CLASSIC_THEME } from './xtermTheme' const MAX_TABS = 10 export function useTerminalSessions(nexusDrawer: Ref) { const route = useRoute() const router = useRouter() - const theme = useTheme() const snackbar = useSnackbar() const settings = useTerminalSettings() @@ -120,58 +119,13 @@ export function useTerminalSessions(nexusDrawer: Ref) { } function createTerminal(): Terminal { - const isDark = theme.global.current.value.dark return new Terminal({ cursorBlink: true, cursorStyle: 'bar', fontSize: settings.fontSize.value, scrollback: settings.scrollback.value, fontFamily: '"Cascadia Code","Fira Code","JetBrains Mono",Menlo,monospace', - theme: isDark - ? { - background: '#0b1120', - foreground: '#e2e8f0', - cursor: '#7c8bf4', - selectionBackground: '#334155', - black: '#1e293b', - red: '#f87171', - green: '#4ade80', - yellow: '#fbbf24', - blue: '#60a5fa', - magenta: '#c084fc', - cyan: '#22d3ee', - white: '#e2e8f0', - brightBlack: '#64748b', - brightRed: '#fca5a5', - brightGreen: '#86efac', - brightYellow: '#fde047', - brightBlue: '#93c5fd', - brightMagenta: '#d8b4fe', - brightCyan: '#67e8f9', - brightWhite: '#f8fafc', - } - : { - background: '#f8fafc', - foreground: '#0f172a', - cursor: '#4f46e5', - selectionBackground: '#bfdbfe', - black: '#1e293b', - red: '#dc2626', - green: '#16a34a', - yellow: '#ca8a04', - blue: '#2563eb', - magenta: '#9333ea', - cyan: '#0891b2', - white: '#f1f5f9', - brightBlack: '#64748b', - brightRed: '#ef4444', - brightGreen: '#22c55e', - brightYellow: '#eab308', - brightBlue: '#3b82f6', - brightMagenta: '#a855f7', - brightCyan: '#06b6d4', - brightWhite: '#ffffff', - }, + theme: XTERM_CLASSIC_THEME, allowProposedApi: true, drawBoldTextInBrightColors: true, }) diff --git a/frontend/src/composables/terminal/xtermTheme.ts b/frontend/src/composables/terminal/xtermTheme.ts new file mode 100644 index 00000000..46ac1c1a --- /dev/null +++ b/frontend/src/composables/terminal/xtermTheme.ts @@ -0,0 +1,27 @@ +import type { ITheme } from '@xterm/xterm' + +/** 经典终端:黑底白字 + 16 色 ANSI(不随 Vuetify 浅色/深色切换) */ +export const XTERM_CLASSIC_THEME: ITheme = { + background: '#000000', + foreground: '#ffffff', + cursor: '#ffffff', + cursorAccent: '#000000', + selectionBackground: '#4d4d4d', + selectionForeground: '#ffffff', + black: '#000000', + red: '#cd3131', + green: '#0dbc79', + yellow: '#e5e510', + blue: '#2472c8', + magenta: '#bc3fbc', + cyan: '#11a8cd', + white: '#e5e5e5', + brightBlack: '#666666', + brightRed: '#f14c4c', + brightGreen: '#23d18b', + brightYellow: '#f5f543', + brightBlue: '#3b8eea', + brightMagenta: '#d670d6', + brightCyan: '#29b8db', + brightWhite: '#ffffff', +} diff --git a/frontend/src/pages/TerminalPage.vue b/frontend/src/pages/TerminalPage.vue index 77dd8d2f..71035a93 100644 --- a/frontend/src/pages/TerminalPage.vue +++ b/frontend/src/pages/TerminalPage.vue @@ -1,8 +1,7 @@