Files
Bill 5602949a4f
CI / typecheck + test + build (windows) (push) Waiting to run
Deploy website to GitHub Pages / deploy (push) Waiting to run
website: dark-first redesign + SFTP 面板截图
- 全站深色(#0b0e12 + 终端绿),右上角可切浅色;两套主题共用 CSS 令牌
- 自托管字体:Space Grotesk(展示)+ JetBrains Mono(等宽),不再依赖系统栈
- 「核心能力」改为横向滚动卡片轨道(箭头翻页 / 拖拽 / 键盘方向键)
- 新增 SFTP 文件面板截图(含空白处右键菜单),IP 已打码
- 补 og:image / theme-color / skip-link / 焦点环 / 导航当前位置高亮
2026-10-09 00:46:35 +08:00

473 lines
22 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OpenTerminal - 本地终端 / SSH / SFTP 桌面终端,开源 Windows 终端工具</title>
<meta name="description" content="OpenTerminal 是开源的 Windows 桌面终端:本地终端、SSH 远程会话、SFTP 文件管理、分屏与广播输入、主题定制。MIT 协议,支持自动更新。" />
<link rel="icon" type="image/png" href="assets/icon.png" />
<link rel="preload" href="assets/fonts/space-grotesk-600.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="assets/fonts/jetbrains-mono-500.woff2" as="font" type="font/woff2" crossorigin />
<meta property="og:title" content="OpenTerminal - 本地终端 / SSH / SFTP 桌面终端" />
<meta property="og:description" content="开源的 Windows 桌面终端:本地终端、SSH 远程会话、SFTP 文件管理、分屏与广播输入。MIT 协议,支持自动更新。" />
<meta property="og:image" content="assets/shot-terminal.jpg" />
<meta name="theme-color" content="#0b0e12" />
<link rel="stylesheet" href="assets/style.css" />
<script>
// 主题必须在首帧前定好,避免闪白/闪黑;默认深色,只有用户显式切过才用保存值
(function () {
var theme = 'dark';
try {
if (localStorage.getItem('openterminal.theme') === 'light') theme = 'light';
} catch (e) {}
document.documentElement.dataset.theme = theme;
})();
</script>
</head>
<body>
<a class="skip-link" href="#main">跳到主要内容</a>
<header class="site-nav">
<div class="container nav-inner">
<a class="brand" href="#top">
<img src="assets/icon.png" alt="OpenTerminal 图标" width="24" height="24" />
<span>OpenTerminal</span>
</a>
<div class="nav-right">
<nav class="nav-links" aria-label="站内导航">
<a href="#features">功能</a>
<a href="#download">下载</a>
<a href="#changelog">更新日志</a>
<a href="https://github.com/billowliu2/OpenTerminal" target="_blank" rel="noopener">GitHub</a>
</nav>
<button class="theme-toggle" id="theme-toggle" type="button" aria-label="切换明暗主题" title="切换明暗主题">
<svg class="icon-moon" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z" />
</svg>
<svg class="icon-sun" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="4" />
<path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" />
</svg>
</button>
</div>
</div>
</header>
<main id="main">
<section class="hero" id="top">
<div class="container hero-grid">
<div class="hero-copy">
<p class="hero-kicker">开源桌面终端 · MIT 协议</p>
<h1>本地终端、SSH 与 SFTP<br />装进<span class="accent">同一个</span>桌面应用</h1>
<p class="hero-sub">
OpenTerminal 面向开发和运维场景:WebGL 加速的终端渲染、可分屏的 SSH 会话、
内置 SFTP 文件管理与广播输入。安装即用,支持自动更新。
</p>
<div class="hero-actions">
<a class="btn btn-primary" id="dl-exe" href="https://github.com/billowliu2/OpenTerminal/releases/download/v1.0.22/OpenTerminal-1.0.22-setup.exe">
下载 Windows 安装包
</a>
<a class="btn btn-ghost" href="https://github.com/billowliu2/OpenTerminal" target="_blank" rel="noopener">
查看源码
</a>
</div>
<p class="hero-note">当前版本 <span class="mono">v1.0.22</span> · NSIS exe 安装包,支持应用内自动更新。</p>
</div>
<figure class="hero-shot">
<img src="assets/shot-terminal.jpg" alt="OpenTerminal 主界面:三路分屏并行运行 Kimi Code、Claude Code 与 Codex" width="1739" height="870" />
<figcaption>三路分屏并行运行 AI 编程 Agent,背景图与压暗层可自定义</figcaption>
</figure>
</div>
<div class="container spec-strip">
<span>当前版本 <strong class="mono">v1.0.22</strong></span>
<span>Windows 10 / 11 · x64</span>
<span>MIT 开源协议</span>
<span>exe 支持应用内自动更新</span>
</div>
</section>
<section class="features grid-bg" id="features">
<div class="container">
<div class="section-head">
<div>
<p class="section-eyebrow">Capabilities</p>
<h2>核心能力</h2>
<p class="section-sub">按使用场景划分的能力组,左右拖动或用箭头浏览;完整清单见仓库 README。</p>
</div>
<div class="cap-controls">
<button class="track-btn" type="button" data-dir="-1" aria-label="向左浏览能力卡片">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg>
</button>
<button class="track-btn" type="button" data-dir="1" aria-label="向右浏览能力卡片">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 6l6 6-6 6" /></svg>
</button>
</div>
</div>
<div class="cap-track" id="cap-track" tabindex="0" aria-label="核心能力,可横向滚动">
<article class="cap-card">
<p class="cap-num">01</p>
<h3>终端核心</h3>
<ul>
<li>node-pty 本地会话,自动探测 PowerShell / zsh / bash</li>
<li>xterm.js WebGL 渲染,声明 256 色与真彩,异常自动降级</li>
<li>内嵌搜索(Ctrl+F)、命令历史、粘贴风险确认</li>
<li>关键词高亮 22 条内置规则,支持自定义正则与三档强度</li>
<li>字体、字重、字距、行高、光标样式实时生效</li>
</ul>
</article>
<article class="cap-card">
<p class="cap-num">02</p>
<h3>SSH 会话</h3>
<ul>
<li>ssh2 实现:密码、私钥(文件或粘贴内容)、SSH Agent</li>
<li>多路分屏与广播输入,一次操作下发到多台主机</li>
<li>主机指纹校验、首次连接确认、变更告警</li>
<li>ZMODEM 传输支持(sz / rz)</li>
<li>OSC 7 上报工作目录,新会话按上次位置恢复</li>
</ul>
</article>
<article class="cap-card">
<p class="cap-num">03</p>
<h3>SFTP 文件面板</h3>
<ul>
<li>列表头列分明:名称、大小、修改时间、权限、用户/组</li>
<li>点击列头排序;文件名解析为真实用户与组名</li>
<li>字体缩放 80%–180%,Ctrl+滚轮或工具栏按钮</li>
<li>上传下载、同名覆盖确认、chmod / chown 编辑</li>
<li>大目录虚拟滚动,上万条目不卡窗口</li>
</ul>
</article>
<article class="cap-card">
<p class="cap-num">04</p>
<h3>工作区与布局</h3>
<ul>
<li>dockview 分屏:任意拆分、拖拽、合并与浮动</li>
<li>布局模板保存与一键套用</li>
<li>启动恢复上次会话布局</li>
<li>界面缩放 50% 至 150%</li>
</ul>
</article>
<article class="cap-card">
<p class="cap-num">05</p>
<h3>主题与外观</h3>
<ul>
<li>主题编辑器:22 个颜色位逐项调整,实时预览</li>
<li>内置 11 套主题,跟随系统明暗自动切换</li>
<li>自定义背景图片、不透明度与压暗层</li>
<li>标签强调色、高亮配色跟随主题</li>
</ul>
</article>
<article class="cap-card">
<p class="cap-num">06</p>
<h3>效率工具</h3>
<ul>
<li>命令库:保存常用命令片段,跨会话发送到指定终端</li>
<li>高亮规则集按主机绑定,不同服务器不同配色</li>
<li>规则导入导出、实时预览与命中统计</li>
<li>会话快照与恢复、终端标签自动命名</li>
</ul>
</article>
<article class="cap-card">
<p class="cap-num">07</p>
<h3>系统监控</h3>
<ul>
<li>CPU、负载、内存、磁盘、网络实时面板</li>
<li>每核占用与磁盘分区明细</li>
<li>运行时长与网络速率曲线</li>
<li>随会话打开,不额外占用通道</li>
</ul>
</article>
<article class="cap-card">
<p class="cap-num">08</p>
<h3>锁屏与安全</h3>
<ul>
<li>Ctrl+L 一键锁屏,支持闲置自动锁定与启动即锁</li>
<li>密码经 scrypt 加盐哈希存储,不落盘明文</li>
<li>输错触发递增冷却;锁定期间禁用菜单与刷新快捷键</li>
<li>锁屏只是遮罩:背后会话与传输不中断</li>
</ul>
</article>
</div>
<p class="cap-hint">← 拖动浏览 · 共 8 组能力</p>
<div class="feature-row">
<figure class="feature-shot reveal">
<img src="assets/shot-agents.png" alt="OpenTerminal 多路分屏运行 Kimi Code、Claude Code、Codex 等 AI 编程 Agent" width="1296" height="870" />
</figure>
<div class="feature-copy reveal">
<p class="eyebrow">Workbench</p>
<h3>AI Agent 工作台</h3>
<ul>
<li>多路分屏并行运行 Kimi Code、Claude Code、Codex 等 AI 编程工具</li>
<li>为高频刷新的 TUI 界面优化:终端尺寸去抖同步,避免反复重绘</li>
<li>中文输入法候选窗紧贴光标,TUI 内输入中文不再漂移</li>
<li>关键词高亮自动标出错误、警告、HTTP 状态码与百分比</li>
</ul>
</div>
</div>
<div class="feature-row">
<figure class="feature-shot reveal">
<img src="assets/shot-sftp.png" alt="OpenTerminal SFTP 文件面板:列表头、可排序列、完整修改时间与用户/组" width="1282" height="801" />
<img class="narrow" src="assets/shot-sftp-menu.png" alt="OpenTerminal 在文件列表空白处右键弹出同款文件菜单" width="1282" height="801" />
<figcaption>列表空白处右键同样是完整文件菜单,行内右键则作用于所选条目</figcaption>
</figure>
<div class="feature-copy reveal">
<p class="eyebrow">SFTP</p>
<h3>远程文件面板</h3>
<ul>
<li>列表头列分明:名称、大小、修改时间、权限、用户/组,点击列头排序</li>
<li>文件名解析为真实用户与组名(root/root、eveuser/eveuser),不再只有数字</li>
<li>字体缩放 80%–180%:Ctrl+滚轮或工具栏按钮,行高与字号联动并记忆</li>
<li>上传 / 下载、同名覆盖确认、chmod 权限与 chown 属主编辑</li>
<li>大目录虚拟滚动,上万条目不卡窗口</li>
</ul>
</div>
</div>
<div class="feature-row">
<figure class="feature-shot reveal">
<img src="assets/shot-themes.jpg" alt="OpenTerminal 主题设置:背景图片、不透明度、压暗层与主题画廊" width="1739" height="870" />
</figure>
<div class="feature-copy reveal">
<p class="eyebrow">Customize</p>
<h3>定制与效率</h3>
<ul>
<li>主题编辑器:22 个颜色位逐项调整,实时预览;支持自定义背景图片、不透明度与压暗层</li>
<li>内置 11 套主题,跟随系统明暗自动切换</li>
<li>命令库:保存常用命令片段,跨会话发送到指定终端</li>
<li>启动恢复上次会话布局;界面缩放 50% 至 150%</li>
<li>四语言界面:简体中文、繁体中文、English、日本語</li>
</ul>
</div>
</div>
<div class="feature-row">
<figure class="feature-shot reveal">
<img src="assets/shot-lock.png" alt="OpenTerminal 锁屏界面:不透明遮罩与密码解锁" width="1739" height="870" />
</figure>
<div class="feature-copy reveal">
<p class="eyebrow">Security</p>
<h3>锁屏与安全</h3>
<ul>
<li>Ctrl+L 一键锁屏,支持闲置自动锁定与启动即锁</li>
<li>锁定期间禁用应用菜单、页面刷新与开发者工具快捷键</li>
<li>密码经 scrypt 加盐哈希存储,不落盘明文;输错触发递增冷却</li>
<li>锁屏只是遮罩:背后的终端会话与文件传输保持运行不中断</li>
</ul>
</div>
</div>
</div>
</section>
<section class="download" id="download">
<div class="container">
<p class="section-eyebrow">Download</p>
<h2>下载</h2>
<p class="section-sub">
从 GitHub Releases 下载;全部历史版本在同一页面。
<!-- 发新版本时更新下方 exe 直链与 hero 的 id=dl-exe 链接 -->
</p>
<table class="dl-table">
<thead>
<tr><th>安装包</th><th>适用场景</th><th>大小</th><th>链接</th></tr>
</thead>
<tbody>
<tr>
<td class="mono">OpenTerminal-1.0.22-setup.exe</td>
<td>NSIS 安装包,支持应用内自动更新(推荐)</td>
<td class="mono">109 MB</td>
<td>
<a href="https://github.com/billowliu2/OpenTerminal/releases/download/v1.0.22/OpenTerminal-1.0.22-setup.exe">下载</a>
</td>
</tr>
<tr>
<td class="mono">历史版本</td>
<td>全部发布记录与更新说明</td>
<td class="mono">-</td>
<td>
<a href="https://github.com/billowliu2/OpenTerminal/releases" target="_blank" rel="noopener">releases 列表</a>
</td>
</tr>
</tbody>
</table>
<div class="update-note">
<h3>自动更新说明</h3>
<p>
应用内检查更新优先访问 GitHub Releases(跟随系统代理),失败时自动回退国内 git.codingplan.site 更新通道(直连)。
更新包经 SHA-512 校验后安装。更新说明文字从发布通道的 release-notes.md 读取,与每次发布同步更新。
自 v1.0.22 起不再提供 MSI 安装包,统一使用 NSIS exe。
</p>
</div>
</div>
</section>
<section class="changelog" id="changelog">
<div class="container">
<p class="section-eyebrow">Changelog</p>
<h2>近期更新</h2>
<div class="changelog-list">
<article>
<h3><span class="mono">1.0.22</span><span class="rel-date">2026-10-08</span></h3>
<ul>
<li>修复中文输入法候选窗不跟随光标(v1.0.21 回归)</li>
<li>不再提供 MSI 安装包,统一使用 NSIS exe</li>
<li>打包流程新增依赖一致性校验,防止旧依赖混入安装包</li>
</ul>
</article>
<article>
<h3><span class="mono">1.0.21</span><span class="rel-date">2026-10-07</span></h3>
<ul>
<li>背景图体验:任意主题下调透明度均为压暗、文字自动提亮到 WCAG AA、新增背景压暗滑杆</li>
<li>性能:设置热更不再触发全窗格重排,SFTP 大目录虚拟滚动,面板独立错误边界</li>
<li>安装包精简约 90MB;SFTP/ZMODEM 本地路径准入与多处安全加固</li>
</ul>
</article>
<article>
<h3><span class="mono">1.0.20</span><span class="rel-date">2026-10-01</span></h3>
<ul>
<li>修复中文输入法候选窗不跟随光标</li>
<li>锁屏加固:锁定期间移除应用菜单,Ctrl+L 按键判定重构并补测试</li>
</ul>
</article>
</div>
<p class="changelog-more">
完整日志见仓库 <a href="https://github.com/billowliu2/OpenTerminal/blob/main/CHANGELOG.md" target="_blank" rel="noopener">CHANGELOG.md</a>。
</p>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container footer-inner">
<span>© 2026 CodingPlan.Site · OpenTerminal 以 MIT 协议开源</span>
<span class="mono">更新通道:git.codingplan.site</span>
</div>
</footer>
<script>
(function () {
var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
// 滚动进场
var revealables = document.querySelectorAll('.reveal');
if (reduce || !('IntersectionObserver' in window)) {
revealables.forEach(function (el) { el.classList.add('is-in'); });
} else {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) { e.target.classList.add('is-in'); io.unobserve(e.target); }
});
}, { rootMargin: '0px 0px -8% 0px', threshold: 0.05 });
revealables.forEach(function (el) { io.observe(el); });
}
// 导航当前位置
var links = Array.prototype.slice.call(document.querySelectorAll('.nav-links a[href^="#"]'));
var sections = links
.map(function (a) { return document.querySelector(a.getAttribute('href')); })
.filter(Boolean);
function syncNav() {
var pos = scrollY + 130;
var current = null;
sections.forEach(function (s) { if (s.offsetTop <= pos) current = s; });
links.forEach(function (a) {
a.classList.toggle('is-current', !!current && a.getAttribute('href') === '#' + current.id);
});
}
addEventListener('scroll', syncNav, { passive: true });
syncNav();
// 能力卡片横向轨道:箭头翻页 + 按住拖动
var track = document.getElementById('cap-track');
if (!track) return;
var buttons = document.querySelectorAll('.track-btn');
function step() {
var card = track.querySelector('.cap-card');
return card ? card.getBoundingClientRect().width + 20 : track.clientWidth * 0.8;
}
function syncButtons() {
var max = track.scrollWidth - track.clientWidth - 1;
buttons.forEach(function (b) {
var dir = Number(b.getAttribute('data-dir'));
b.disabled = dir < 0 ? track.scrollLeft <= 0 : track.scrollLeft >= max;
});
}
buttons.forEach(function (b) {
b.addEventListener('click', function () {
track.scrollBy({ left: Number(b.getAttribute('data-dir')) * step(), behavior: reduce ? 'auto' : 'smooth' });
});
});
track.addEventListener('scroll', syncButtons, { passive: true });
addEventListener('resize', syncButtons);
syncButtons();
var dragging = false;
var startX = 0;
var startScroll = 0;
track.addEventListener('pointerdown', function (e) {
if (e.pointerType === 'mouse' && e.button !== 0) return;
dragging = true;
startX = e.clientX;
startScroll = track.scrollLeft;
track.classList.add('is-dragging');
track.setPointerCapture(e.pointerId);
});
track.addEventListener('pointermove', function (e) {
if (!dragging) return;
var delta = e.clientX - startX;
if (Math.abs(delta) > 3) e.preventDefault();
track.scrollLeft = startScroll - delta;
});
function endDrag(e) {
if (!dragging) return;
dragging = false;
track.classList.remove('is-dragging');
if (e && e.pointerId !== undefined && track.hasPointerCapture(e.pointerId)) {
track.releasePointerCapture(e.pointerId);
}
syncButtons();
}
track.addEventListener('pointerup', endDrag);
track.addEventListener('pointercancel', endDrag);
track.addEventListener('dragstart', function (e) { e.preventDefault(); });
track.addEventListener('keydown', function (e) {
if (e.key === 'ArrowRight') { track.scrollBy({ left: step(), behavior: 'smooth' }); e.preventDefault(); }
if (e.key === 'ArrowLeft') { track.scrollBy({ left: -step(), behavior: 'smooth' }); e.preventDefault(); }
});
// 明暗主题切换
var toggle = document.getElementById('theme-toggle');
var meta = document.querySelector('meta[name="theme-color"]');
function applyTheme(theme) {
document.documentElement.dataset.theme = theme;
if (meta) meta.setAttribute('content', theme === 'light' ? '#fafbf9' : '#0b0e12');
if (toggle) toggle.setAttribute('aria-label', theme === 'light' ? '切换到深色主题' : '切换到浅色主题');
}
if (toggle) {
toggle.addEventListener('click', function () {
var next = document.documentElement.dataset.theme === 'light' ? 'dark' : 'light';
applyTheme(next);
try { localStorage.setItem('openterminal.theme', next); } catch (e) {}
});
}
applyTheme(document.documentElement.dataset.theme === 'light' ? 'light' : 'dark');
})();
</script>
</body>
</html>