diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index 4496928..22cb629 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -18,7 +18,9 @@
"Bash(gh api *)",
"Bash(echo \"exit: $?\")",
"Bash(rtk npx *)",
- "Bash(rtk tsc *)"
+ "Bash(rtk tsc *)",
+ "Bash(netstat -ano)",
+ "mcp__chrome-devtools__*"
]
}
}
diff --git a/index.html b/index.html
index d49a278..6034756 100644
--- a/index.html
+++ b/index.html
@@ -16,6 +16,7 @@
+
diff --git a/public/logos/app.webp b/public/logos/app.webp
new file mode 100644
index 0000000..24481d0
Binary files /dev/null and b/public/logos/app.webp differ
diff --git a/public/logos/react-docs-ui.png b/public/logos/react-docs-ui.png
new file mode 100644
index 0000000..86e3005
Binary files /dev/null and b/public/logos/react-docs-ui.png differ
diff --git a/public/screenshots/ssh-terminal/aichat-page.png b/public/screenshots/ssh-terminal/aichat-page.png
new file mode 100644
index 0000000..239d2ae
Binary files /dev/null and b/public/screenshots/ssh-terminal/aichat-page.png differ
diff --git a/public/screenshots/ssh-terminal/recording-manager.png b/public/screenshots/ssh-terminal/recording-manager.png
new file mode 100644
index 0000000..94cf5d0
Binary files /dev/null and b/public/screenshots/ssh-terminal/recording-manager.png differ
diff --git a/public/screenshots/ssh-terminal/session-manager.png b/public/screenshots/ssh-terminal/session-manager.png
new file mode 100644
index 0000000..60bf390
Binary files /dev/null and b/public/screenshots/ssh-terminal/session-manager.png differ
diff --git a/public/screenshots/ssh-terminal/setting-about.png b/public/screenshots/ssh-terminal/setting-about.png
new file mode 100644
index 0000000..e7b2306
Binary files /dev/null and b/public/screenshots/ssh-terminal/setting-about.png differ
diff --git a/public/screenshots/ssh-terminal/setting-ai.png b/public/screenshots/ssh-terminal/setting-ai.png
new file mode 100644
index 0000000..6c71643
Binary files /dev/null and b/public/screenshots/ssh-terminal/setting-ai.png differ
diff --git a/public/screenshots/ssh-terminal/setting-keybingdings.png b/public/screenshots/ssh-terminal/setting-keybingdings.png
new file mode 100644
index 0000000..e97aeb3
Binary files /dev/null and b/public/screenshots/ssh-terminal/setting-keybingdings.png differ
diff --git a/public/screenshots/ssh-terminal/setting-main.png b/public/screenshots/ssh-terminal/setting-main.png
new file mode 100644
index 0000000..2e583dc
Binary files /dev/null and b/public/screenshots/ssh-terminal/setting-main.png differ
diff --git a/public/screenshots/ssh-terminal/setting-reacording.png b/public/screenshots/ssh-terminal/setting-reacording.png
new file mode 100644
index 0000000..db36767
Binary files /dev/null and b/public/screenshots/ssh-terminal/setting-reacording.png differ
diff --git a/public/screenshots/ssh-terminal/setting-terminal.png b/public/screenshots/ssh-terminal/setting-terminal.png
new file mode 100644
index 0000000..5711e5d
Binary files /dev/null and b/public/screenshots/ssh-terminal/setting-terminal.png differ
diff --git a/public/screenshots/ssh-terminal/sftp-manager.png b/public/screenshots/ssh-terminal/sftp-manager.png
new file mode 100644
index 0000000..c5eb1cf
Binary files /dev/null and b/public/screenshots/ssh-terminal/sftp-manager.png differ
diff --git a/public/screenshots/ssh-terminal/terminal-ai-short-page.png b/public/screenshots/ssh-terminal/terminal-ai-short-page.png
new file mode 100644
index 0000000..c100bba
Binary files /dev/null and b/public/screenshots/ssh-terminal/terminal-ai-short-page.png differ
diff --git a/public/screenshots/ssh-terminal/terminal-main.png b/public/screenshots/ssh-terminal/terminal-main.png
new file mode 100644
index 0000000..c8d45d3
Binary files /dev/null and b/public/screenshots/ssh-terminal/terminal-main.png differ
diff --git a/public/screenshots/ssh-terminal/terminal-nl-to-cmd.png b/public/screenshots/ssh-terminal/terminal-nl-to-cmd.png
new file mode 100644
index 0000000..76df732
Binary files /dev/null and b/public/screenshots/ssh-terminal/terminal-nl-to-cmd.png differ
diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx
index b30bc42..a23ddb7 100644
--- a/src/components/Footer.tsx
+++ b/src/components/Footer.tsx
@@ -1,9 +1,12 @@
import { Link } from 'react-router-dom';
+import { useState } from 'react';
import { useI18n } from '../hooks/useI18n';
import { siteData } from '../data/siteData';
+import PolicyModal from './PolicyModal';
export default function Footer() {
const { t, bi, lang } = useI18n();
+ const [policyModal, setPolicyModal] = useState<'license' | 'privacy' | null>(null);
return (
@@ -43,13 +46,13 @@ export default function Footer() {
{t('footer.copyright')}
-
+ setPolicyModal('license')}>
{t('footer.license')}
-
+
{' · '}
-
+ setPolicyModal('privacy')}>
{t('footer.privacy')}
-
+
{siteData.brand.icp && (
@@ -65,6 +68,9 @@ export default function Footer() {
+ {policyModal && (
+ setPolicyModal(null)} />
+ )}
);
}
diff --git a/src/components/PolicyModal.tsx b/src/components/PolicyModal.tsx
new file mode 100644
index 0000000..3959f97
--- /dev/null
+++ b/src/components/PolicyModal.tsx
@@ -0,0 +1,204 @@
+import { useEffect } from 'react';
+import { createPortal } from 'react-dom';
+import { X, Scale, ShieldCheck } from 'lucide-react';
+import { useI18n } from '../hooks/useI18n';
+
+interface PolicyModalProps {
+ type: 'license' | 'privacy';
+ onClose: () => void;
+}
+
+export default function PolicyModal({ type, onClose }: PolicyModalProps) {
+ const { t, lang } = useI18n();
+
+ const title = type === 'license' ? t('footer.license') : t('footer.privacy');
+
+ useEffect(() => {
+ const prev = document.body.style.overflow;
+ document.body.style.overflow = 'hidden';
+ const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };
+ window.addEventListener('keydown', onKey);
+ return () => {
+ document.body.style.overflow = prev;
+ window.removeEventListener('keydown', onKey);
+ };
+ }, [onClose]);
+
+ return createPortal(
+
+
e.stopPropagation()}>
+
+
+ {type === 'license' ? : }
+
{title}
+
+
+
+
+
+
+ {type === 'license' ?
:
}
+
+
+
,
+ document.body
+ );
+}
+
+function LicenseContent() {
+ const { lang } = useI18n();
+ return (
+
+
MIT License
+
+
+ Copyright © 2026 ZUJ OL
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the “Software”),
+ to deal in the Software without restriction, including without limitation the
+ rights to use , copy , modify ,{' '}
+ merge , publish , distribute ,{' '}
+ sublicense , and/or sell copies of the Software.
+
+
+
+
+ Conditions
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+
+
+
+ Disclaimer
+
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+
+
+ );
+}
+
+function PrivacyContent({ lang }: { lang: string }) {
+ if (lang === 'zh') {
+ return (
+
+
+ 本隐私政策适用于 ZUJ OL Apps 网站。我们尊重您的隐私,致力于保护您的个人信息。
+
+
+
+ 1 信息收集
+
+ 本项目不使用 Cookie,不收集任何个人身份信息(PII)。我们可能使用
+ Vercel Analytics 等隐私优先的分析工具收集匿名访问数据(如页面浏览量、浏览器类型),
+ 以帮助改进网站体验。
+
+
+
+
+ 2 第三方链接
+
+ 本网站包含指向 GitHub、npm 等外部第三方网站的链接。我们对这些网站的隐私政策不承担任何责任。
+
+
+
+
+ 3 数据安全
+
+ 我们采取合理的安全措施保护网站的运行安全,但无法保证互联网传输的绝对安全。
+
+
+
+
+ 4 政策更新
+
+ 我们可能会不时更新本隐私政策。任何变更将在本页面公布。
+
+
+
+
+ 5 联系方式
+
+ 如对本隐私政策有任何疑问,请通过{' '}
+ GitHub Issues
+ {' '}联系我们。
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+ This privacy policy applies to the ZUJ OL Apps website. We respect your privacy
+ and are committed to protecting your personal information.
+
+
+
+ 1 Information Collection
+
+ This project does not use cookies and does not collect any personally identifiable
+ information (PII). We may use privacy-first analytics tools such as Vercel Analytics
+ to collect anonymous access data (e.g., page views, browser type) to help improve
+ the website experience.
+
+
+
+
+ 2 Third-Party Links
+
+ This website contains links to external third-party websites such as GitHub and npm.
+ We are not responsible for the privacy policies of these websites.
+
+
+
+
+ 3 Data Security
+
+ We take reasonable security measures to protect the operation of the website, but
+ cannot guarantee absolute security of internet transmissions.
+
+
+
+
+ 4 Policy Updates
+
+ We may update this privacy policy from time to time. Any changes will be posted
+ on this page.
+
+
+
+
+ 5 Contact
+
+ If you have any questions about this privacy policy, please contact us via{' '}
+ GitHub Issues .
+
+
+
+
+ Last updated: May 2026
+
+
+ );
+}
diff --git a/src/contexts/AppContext.tsx b/src/contexts/AppContext.tsx
index 3a7b817..ab310cf 100644
--- a/src/contexts/AppContext.tsx
+++ b/src/contexts/AppContext.tsx
@@ -1,5 +1,6 @@
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react';
import type { AppContextType } from '../types';
+import { siteData } from '../data/loader';
const AppContext = createContext(null);
@@ -17,6 +18,11 @@ export function AppProvider({ children }: { children: ReactNode }) {
localStorage.setItem('theme', theme);
}, [theme]);
+ useEffect(() => {
+ const { name, slogan } = siteData.brand;
+ document.title = `${name[lang]} — ${slogan[lang]}`;
+ }, [lang]);
+
const toggleTheme = useCallback(() => {
setTheme((prev) => (prev === 'dark' ? 'light' : 'dark'));
}, []);
diff --git a/src/data/brand.yaml b/src/data/brand.yaml
index 61c99ed..696f41d 100644
--- a/src/data/brand.yaml
+++ b/src/data/brand.yaml
@@ -4,7 +4,7 @@ name:
slogan:
zh: '构建轻量、高效、开源的软件工具'
en: 'Building lightweight, efficient, open-source software tools'
-logo: '/logo.svg'
+logo: '/logos/app.webp'
author: 'shenjianZ'
github: 'https://github.com/shenjianZ'
email: '15202078626@163.com'
diff --git a/src/data/i18n/en.yaml b/src/data/i18n/en.yaml
index 8b6b6b9..0aadee0 100644
--- a/src/data/i18n/en.yaml
+++ b/src/data/i18n/en.yaml
@@ -33,6 +33,7 @@ projects.sort.name: 'By Name'
projects.noResults: 'No matching projects'
projects.search: 'Search project name, description, or tags...'
detail.overview: 'Overview'
+detail.quickStart: 'Quick Start'
detail.features: 'Features'
detail.screenshots: 'Screenshots'
detail.downloads: 'Downloads'
diff --git a/src/data/i18n/zh.yaml b/src/data/i18n/zh.yaml
index 5811828..94bf1bf 100644
--- a/src/data/i18n/zh.yaml
+++ b/src/data/i18n/zh.yaml
@@ -33,6 +33,7 @@ projects.sort.name: '名称排序'
projects.noResults: '没有匹配的项目'
projects.search: '搜索项目名称、描述或标签...'
detail.overview: '概览'
+detail.quickStart: '快速开始'
detail.features: '核心功能'
detail.screenshots: '截图预览'
detail.downloads: '下载安装'
diff --git a/src/data/projects/devicedeck.yaml b/src/data/projects/devicedeck.yaml
index b11fc69..c0ac25a 100644
--- a/src/data/projects/devicedeck.yaml
+++ b/src/data/projects/devicedeck.yaml
@@ -45,6 +45,11 @@ features:
- '操作日志查看与管理'
- '环境检测(ADB / scrcpy)'
- '字号自定义(12-16px)'
+ - 'WiFi 文件传输实时事件推送(WebSocket)'
+ - '分片上传与断点续传(SHA-256 校验)'
+ - '传输历史记录追踪'
+ - '批量下载'
+ - '文件预览(扩展 MIME 识别)'
en:
- 'Android device scanning & management (USB / WiFi)'
- 'Scrcpy mirroring with multiple preset configs'
@@ -62,6 +67,11 @@ features:
- 'Operation log viewer & management'
- 'Environment check (ADB / scrcpy)'
- 'Font size customization (12-16px)'
+ - 'WiFi file transfer real-time event push (WebSocket)'
+ - 'Chunked upload with resume (SHA-256 verification)'
+ - 'Transfer history tracking'
+ - 'Batch download'
+ - 'File preview (extended MIME recognition)'
tags:
- 'Android'
- 'ADB'
@@ -76,11 +86,11 @@ logo: '/logos/devicedeck.png'
repoUrl: 'https://github.com/shenjianZ/devicedeck'
websiteUrl: 'https://shenjianz.github.io/DeviceDeck/'
docsUrl: 'https://github.com/shenjianZ/devicedeck#readme'
-latestVersion: 'v0.1.1'
-releaseDate: '2026-05-18'
+latestVersion: 'v0.1.3'
+releaseDate: '2026-05-23'
license: 'MIT'
language: 'Rust'
-lastUpdated: '2026-05-18'
+lastUpdated: '2026-05-23'
recommended: true
featured: true
order: 4
@@ -88,23 +98,23 @@ color: '#8B5CF6'
downloads:
- platform: 'Windows'
arch: 'x64'
- url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.1/DeviceDeck-v0.1.1-windows-x64.exe'
- size: '17.5 MB'
+ url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.3/DeviceDeck-v0.1.3-windows-x64.exe'
+ size: '18.31 MB'
sha256: ''
- platform: 'macOS'
arch: 'Apple Silicon'
- url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.1/DeviceDeck-v0.1.1-macos-aarch64.dmg'
- size: '35.8 MB'
+ url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.3/DeviceDeck-v0.1.3-macos-aarch64.dmg'
+ size: '34.62 MB'
sha256: ''
- platform: 'macOS'
arch: 'Intel'
- url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.1/DeviceDeck-v0.1.1-macos-x64.dmg'
- size: '36.0 MB'
+ url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.3/DeviceDeck-v0.1.3-macos-x64.dmg'
+ size: '34.9 MB'
sha256: ''
- platform: 'Linux'
arch: 'x64'
- url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.1/DeviceDeck-v0.1.1-linux-x64.AppImage'
- size: '98.8 MB'
+ url: 'https://file.shenjianl.cn/softwore/DeviceDeck/v0.1.3/DeviceDeck-v0.1.3-linux-x64.AppImage'
+ size: '99.9 MB'
sha256: ''
roadmap:
done:
@@ -123,6 +133,11 @@ roadmap:
- 'WiFi 文件传输'
- '环境检测'
- '首次启动欢迎引导'
+ - 'WiFi 文件传输实时事件推送'
+ - '分片上传与断点续传'
+ - '传输历史记录'
+ - '批量下载'
+ - '文件预览'
doing:
- '多设备同时投屏'
- '脚本录制回放'
@@ -130,6 +145,38 @@ roadmap:
- 'iOS 设备支持'
- '自动化测试集成'
changelog:
+ - version: 'v0.1.3'
+ date: '2026-05-23'
+ changes:
+ zh:
+ - '新增 WebSocket 实时文件事件通知'
+ - '新增文件预览支持,扩展 MIME 类型识别'
+ - '新增分片上传与断点续传(SHA-256 校验)'
+ - '新增传输历史记录追踪'
+ - '新增批量下载端点'
+ - '新增文件筛选/排序下拉框自定义组件'
+ - 'WiFi 传输模块大幅增强,引入 tokio broadcast channel 驱动事件广播'
+ en:
+ - 'Added WebSocket real-time file event notifications'
+ - 'Added file preview with extended MIME type recognition'
+ - 'Added chunked upload with resume (SHA-256 verification)'
+ - 'Added transfer history tracking'
+ - 'Added batch download endpoint'
+ - 'Added custom file filter/sort dropdown component'
+ - 'Major WiFi transfer module enhancement with tokio broadcast channel'
+ - version: 'v0.1.2'
+ date: '2026-05-22'
+ changes:
+ zh:
+ - '新增项目官方网站(React 19 + Vite)'
+ - '新增 WiFi 文件传输独立 Web 页面'
+ - '新增 GitHub Actions 自动部署工作流'
+ - '优化所有平台图标文件体积'
+ en:
+ - 'Added official project website (React 19 + Vite)'
+ - 'Added standalone WiFi file transfer web page'
+ - 'Added GitHub Actions auto-deploy workflow'
+ - 'Optimized all platform icon file sizes'
- version: 'v0.1.1'
date: '2026-05-18'
changes:
diff --git a/src/data/projects/react-docs-ui.yaml b/src/data/projects/react-docs-ui.yaml
index 0205321..97e9f19 100644
--- a/src/data/projects/react-docs-ui.yaml
+++ b/src/data/projects/react-docs-ui.yaml
@@ -4,11 +4,11 @@ displayName:
zh: 'React Docs UI'
en: 'React Docs UI'
slogan:
- zh: '基于 React 的文档组件库与站点生成器'
- en: 'React-based documentation component library & site generator'
+ zh: '配置驱动的 React 文档站点组件库与脚手架'
+ en: 'Configuration-driven React documentation site components & scaffolding'
description:
- zh: 'react-docs-ui 是一套用于构建文档站点的 React 组件库,配合 create-react-docs-ui 脚手架可以快速搭建类似 Nextra / Docusaurus 风格的文档网站。支持 MDX、全文搜索、版本切换和主题定制。'
- en: 'react-docs-ui is a React component library for building documentation sites. Paired with create-react-docs-ui scaffolding, it quickly sets up Nextra/Docusaurus-style docs sites. Supports MDX, full-text search, version switching, and theme customization.'
+ zh: 'react-docs-ui 是一套 React 文档站点 UI 组件库,配合 create-react-docs-ui 脚手架可快速搭建 Nextra / Docusaurus 风格的文档网站。基于 site.yaml 配置驱动,支持 MD/MDX、Shiki 代码高亮、全文搜索、版本切换、深浅主题、命令菜单、国际化、Mermaid 图表、KaTeX 数学公式、面包屑导航、RSS Feed、Sitemap 生成、PWA 支持、后端集成(认证、评论、书签、分析统计)、PDF/DOCX 导出等功能,并内置 CLI 工具链(搜索索引、llms.txt、changelog 索引生成)。'
+ en: 'react-docs-ui is a React component library for building documentation sites. Paired with create-react-docs-ui scaffolding, it quickly sets up Nextra/Docusaurus-style docs. Configuration-driven via site.yaml, supporting MD/MDX, Shiki syntax highlighting, full-text search, version switching, light/dark themes, command menu, i18n, Mermaid diagrams, KaTeX math, breadcrumbs, RSS Feed, Sitemap generation, PWA, backend integration (auth, comments, bookmarks, analytics), PDF/DOCX export, and built-in CLI toolchain (search index, llms.txt, changelog index generation).'
type:
- 'library'
- 'devtool'
@@ -17,89 +17,83 @@ platforms:
- 'web'
- 'npm'
techStack:
- - 'React'
+ - 'React 19'
- 'TypeScript'
- - 'MDX'
- - 'TailwindCSS'
- 'Vite'
+ - 'TailwindCSS 4'
+ - 'shadcn/ui'
+ - 'Radix UI'
+ - 'MDX'
+ - 'Shiki'
+ - 'react-markdown'
+ - 'Mermaid'
+ - 'KaTeX'
+ - 'FlexSearch'
+ - 'next-themes'
+ - 'cmdk'
+ - 'lucide-react'
+ - 'jsPDF'
+ - 'Docx'
features:
zh:
- - 'MDX 支持'
- - '全文搜索'
- - '版本切换'
- - '主题定制'
- - '响应式布局'
- - 'API 文档生成'
- - '代码高亮'
- - '国际化'
+ - '配置驱动(site.yaml),配套 create-react-docs-ui 一键脚手架快速搭建文档站点'
+ - 'MD/MDX 渲染(GFM 扩展语法、Tabs、自定义图片组件)+ Shiki 代码高亮(100+ 主题)'
+ - '全文搜索(FlexSearch 索引 + Cmd+K 命令菜单)'
+ - '文档多版本控制与切换'
+ - 'Mermaid 图表 + KaTeX 数学公式渲染'
+ - 'SEO 与内容发现(元标签自动注入、RSS Feed、Sitemap、llms.txt 生成)'
+ - '深色/浅色/跟随系统主题、国际化(多语言路由)、PWA 支持'
+ - '导航体验:面包屑、目录导航(TOC)、上下文菜单、阅读进度条'
+ - 'Changelog / Release Notes 页面模块与用户反馈'
+ - '后端集成:用户认证(邮箱 + OAuth)、评论系统(线程回复)、书签、分析统计'
+ - 'PDF / DOCX 文档导出'
+ - '内置 CLI 工具链(搜索索引、changelog 索引、sitemap、feed 生成)'
en:
- - 'MDX support'
- - 'Full-text search'
- - 'Version switching'
- - 'Theme customization'
- - 'Responsive layout'
- - 'API doc generation'
- - 'Code highlighting'
- - 'i18n'
+ - 'Configuration-driven (site.yaml) with create-react-docs-ui one-command scaffolding'
+ - 'MD/MDX rendering (GFM, Tabs, custom image components) + Shiki syntax highlighting (100+ themes)'
+ - 'Full-text search (FlexSearch index + Cmd+K command menu)'
+ - 'Multi-version documentation control & switching'
+ - 'Mermaid diagrams + KaTeX math formula rendering'
+ - 'SEO & content discovery (meta tag injection, RSS Feed, Sitemap, llms.txt generation)'
+ - 'Dark/Light/Follow system theme, internationalization (multi-language routing), PWA support'
+ - 'Navigation: breadcrumbs, Table of Contents (TOC), context menu, reading progress bar'
+ - 'Changelog / Release Notes page module with user feedback'
+ - 'Backend integration: auth (email + OAuth), threaded comments, bookmarks, analytics'
+ - 'PDF / DOCX document export'
+ - 'Built-in CLI toolchain (search index, changelog index, sitemap, feed generation)'
tags:
- 'Documentation'
- 'React'
- 'NPM'
- 'MDX'
+ - 'CLI'
+ - 'Component Library'
+ - 'Static Site'
+ - 'TypeScript'
+ - 'Vite'
+ - 'TailwindCSS'
icon: 'BookOpen'
logo: '/logos/react-docs-ui.png'
repoUrl: 'https://github.com/shenjianZ/react-docs-ui'
-docsUrl: 'https://github.com/shenjianZ/react-docs-ui#readme'
+websiteUrl: 'https://shenjianz.github.io/react-docs-ui'
+docsUrl: 'https://react-docs-ui.shenjianl.cn/'
npmUrl: 'https://www.npmjs.com/package/react-docs-ui'
-latestVersion: 'v0.5.2'
-releaseDate: '2026-05-10'
+latestVersion: 'v0.9.2'
+releaseDate: '2025-08-10'
license: 'MIT'
language: 'TypeScript'
-lastUpdated: '2026-05-18'
+lastUpdated: '2026-05-05'
recommended: true
featured: true
order: 5
color: '#06B6D4'
downloads: []
-roadmap:
- done:
- - '基础组件库'
- - 'MDX 渲染'
- - '侧边栏导航'
- - '搜索功能'
- - '主题系统'
- doing:
- - 'API 文档自动生成'
- - '版本切换'
- - '性能优化'
- planned:
- - '插件系统'
- - '评论集成'
- - '多语言路由'
- - 'CLI 工具'
-changelog:
- - version: 'v0.5.2'
- date: '2026-05-10'
- changes:
- zh:
- - '修复搜索索引构建错误'
- - '新增代码块复制按钮'
- - '优化移动端导航'
- en:
- - 'Fixed search index build error'
- - 'Added code copy button'
- - 'Improved mobile navigation'
- - version: 'v0.5.0'
- date: '2026-04-01'
- changes:
- zh:
- - '新增主题定制'
- - '支持 MDX 嵌入组件'
- - '新增面包屑导航'
- en:
- - 'Added theme customization'
- - 'MDX embedded components'
- - 'Breadcrumb navigation'
-architecture:
- zh: 'MDX 源文件 → Vite 构建 → React 组件渲染 → 静态文档站点'
- en: 'MDX Sources → Vite Build → React Component Rendering → Static Documentation Site'
+quickStart:
+ zh:
+ - 'pnpm create react-docs-ui@latest my-docs'
+ - 'cd my-docs && pnpm install'
+ - 'pnpm dev'
+ en:
+ - 'pnpm create react-docs-ui@latest my-docs'
+ - 'cd my-docs && pnpm install'
+ - 'pnpm dev'
diff --git a/src/data/projects/ssh-terminal.yaml b/src/data/projects/ssh-terminal.yaml
index 9f43ff2..cbc4eb1 100644
--- a/src/data/projects/ssh-terminal.yaml
+++ b/src/data/projects/ssh-terminal.yaml
@@ -84,7 +84,8 @@ tags:
icon: 'Terminal'
logo: '/logos/ssh-terminal.png'
repoUrl: 'https://github.com/shenjianZ/ssh-terminal'
-docsUrl: 'https://github.com/shenjianZ/ssh-terminal#readme'
+websiteUrl: 'https://shenjianz.github.io/ssh-terminal'
+docsUrl: 'http://st-docs.shenjianl.cn'
latestVersion: 'v1.2.1'
releaseDate: '2026-03-04'
license: 'MIT'
@@ -167,7 +168,20 @@ architecture:
zh: '前端 (React 19 + xterm.js + Zustand + shadcn/ui) → Tauri 2 Commands → Rust 服务层 (russh + r2d2_sqlite + aes-gcm) → SQLite / 远程服务器'
en: 'Frontend (React 19 + xterm.js + Zustand + shadcn/ui) → Tauri 2 Commands → Rust Service Layer (russh + r2d2_sqlite + aes-gcm) → SQLite / Remote Server'
-screenshots: []
+screenshots:
+ - '/screenshots/ssh-terminal/terminal-main.png'
+ - '/screenshots/ssh-terminal/session-manager.png'
+ - '/screenshots/ssh-terminal/aichat-page.png'
+ - '/screenshots/ssh-terminal/terminal-ai-short-page.png'
+ - '/screenshots/ssh-terminal/terminal-nl-to-cmd.png'
+ - '/screenshots/ssh-terminal/sftp-manager.png'
+ - '/screenshots/ssh-terminal/recording-manager.png'
+ - '/screenshots/ssh-terminal/setting-main.png'
+ - '/screenshots/ssh-terminal/setting-terminal.png'
+ - '/screenshots/ssh-terminal/setting-ai.png'
+ - '/screenshots/ssh-terminal/setting-keybingdings.png'
+ - '/screenshots/ssh-terminal/setting-reacording.png'
+ - '/screenshots/ssh-terminal/setting-about.png'
installGuide:
zh:
diff --git a/src/pages/ProjectDetailPage.tsx b/src/pages/ProjectDetailPage.tsx
index b21a414..99b2d4c 100644
--- a/src/pages/ProjectDetailPage.tsx
+++ b/src/pages/ProjectDetailPage.tsx
@@ -110,6 +110,21 @@ export default function ProjectDetailPage() {
{bi(p.description)}
+ {/* Quick Start */}
+ {p.quickStart && p.quickStart[lang] && p.quickStart[lang].length > 0 && (
+
+
{t('detail.quickStart')}
+
+ {p.quickStart[lang].map((cmd, i) => (
+
+ $
+ {cmd}
+
+ ))}
+
+
+ )}
+
{/* Features */}
{t('detail.features')}
diff --git a/src/styles/components/detail.css b/src/styles/components/detail.css
index 6b02dc1..db851cd 100644
--- a/src/styles/components/detail.css
+++ b/src/styles/components/detail.css
@@ -114,6 +114,10 @@
padding-bottom: 40px;
}
+.detail-body > * {
+ min-width: 0;
+}
+
.detail-sidebar {
position: sticky;
top: calc(var(--nav-height) + 32px);
@@ -288,6 +292,12 @@
background: oklch(58% 0.22 45 / 14%);
}
+@media (max-width: 767px) {
+ .feature-tag {
+ white-space: normal;
+ }
+}
+
/* Screenshot carousel */
.screenshot-carousel {
position: relative;
@@ -619,6 +629,48 @@
word-break: break-all;
}
+/* ── Quick start commands ─────────────────────────────── */
+.quickstart-commands {
+ background: oklch(12% 0.02 270);
+ border: 1px solid oklch(74% 0.2 45 / 12%);
+ border-radius: var(--radius-lg);
+ padding: 18px 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ overflow-x: auto;
+}
+
+:root.light .quickstart-commands {
+ background: oklch(97% 0.005 270);
+ border-color: oklch(58% 0.22 45 / 12%);
+}
+
+.quickstart-line {
+ display: flex;
+ align-items: baseline;
+ gap: 10px;
+ font-size: 13px;
+ line-height: 1.7;
+}
+
+.quickstart-prompt {
+ color: var(--accent);
+ font-weight: 700;
+ flex-shrink: 0;
+ user-select: none;
+}
+
+.quickstart-cmd {
+ font-family: var(--font-mono);
+ color: oklch(90% 0.01 270);
+ word-break: break-all;
+}
+
+:root.light .quickstart-cmd {
+ color: oklch(25% 0.02 270);
+}
+
/* ── Project selector (for roadmap/changelog) ────────── */
.project-selector {
display: flex;
diff --git a/src/styles/components/footer.css b/src/styles/components/footer.css
index 4525552..e6c63a5 100644
--- a/src/styles/components/footer.css
+++ b/src/styles/components/footer.css
@@ -105,4 +105,208 @@
.footer-policy-link {
color: var(--muted);
+ cursor: pointer;
+ background: none;
+ border: none;
+ font: inherit;
+ padding: 0;
+}
+
+.footer-policy-link:hover {
+ color: var(--accent);
+}
+
+/* ── Policy Modal ────────────────────────────────────── */
+.policy-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+ background: oklch(0% 0 0 / 70%);
+ backdrop-filter: blur(8px);
+ -webkit-backdrop-filter: blur(8px);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 24px;
+ animation: policy-fade-in 0.2s ease;
+}
+
+@keyframes policy-fade-in {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+.policy-modal {
+ width: 100%;
+ max-width: 600px;
+ max-height: 80vh;
+ background: var(--bg);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-lg);
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ box-shadow: 0 16px 48px oklch(0% 0 0 / 40%);
+ animation: policy-zoom-in 0.25s ease;
+}
+
+@keyframes policy-zoom-in {
+ from { transform: scale(0.95); opacity: 0; }
+ to { transform: scale(1); opacity: 1; }
+}
+
+.policy-modal-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 20px 24px;
+ border-bottom: 1px solid var(--border);
+ flex-shrink: 0;
+}
+
+.policy-modal-header-left {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ color: var(--accent);
+}
+
+.policy-modal-title {
+ font-size: 18px;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+}
+
+.policy-modal-close {
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ border: 1px solid var(--border);
+ background: transparent;
+ color: var(--muted);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all var(--transition);
+}
+
+.policy-modal-close:hover {
+ color: var(--fg);
+ background: oklch(74% 0.2 45 / 8%);
+ border-color: oklch(74% 0.2 45 / 20%);
+}
+
+.policy-modal-body {
+ padding: 24px;
+ overflow-y: auto;
+ font-size: 14px;
+ line-height: 1.8;
+ color: var(--fg);
+}
+
+.policy-modal-body p {
+ margin-bottom: 16px;
+}
+
+.policy-modal-body p:last-child {
+ margin-bottom: 0;
+}
+
+/* Structured content layout */
+.policy-content {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+}
+
+.policy-badge {
+ display: inline-flex;
+ align-self: flex-start;
+ padding: 4px 14px;
+ border-radius: 99px;
+ font-size: 13px;
+ font-weight: 600;
+ letter-spacing: 0.03em;
+ background: oklch(74% 0.2 45 / 10%);
+ color: var(--accent);
+ border: 1px solid oklch(74% 0.2 45 / 15%);
+}
+
+.policy-intro {
+ font-size: 14px;
+ line-height: 1.7;
+ color: var(--muted);
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--border);
+}
+
+.policy-section h4 {
+ font-size: 15px;
+ font-weight: 700;
+ margin-bottom: 8px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.policy-num {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 22px;
+ height: 22px;
+ border-radius: 50%;
+ background: oklch(74% 0.2 45 / 10%);
+ color: var(--accent);
+ font-size: 12px;
+ font-weight: 700;
+ flex-shrink: 0;
+}
+
+.policy-section p {
+ font-size: 14px;
+ line-height: 1.75;
+ color: var(--fg);
+}
+
+.policy-section a {
+ color: var(--accent);
+ text-decoration: underline;
+ text-underline-offset: 2px;
+}
+
+.policy-section a:hover {
+ text-decoration-thickness: 2px;
+}
+
+.policy-highlight {
+ padding: 14px 16px;
+ border-radius: var(--radius-md);
+ background: oklch(74% 0.2 45 / 5%);
+ border-left: 3px solid var(--accent);
+ font-size: 13.5px;
+ line-height: 1.75;
+}
+
+.policy-highlight strong {
+ color: var(--accent);
+ font-weight: 600;
+}
+
+.policy-muted {
+ font-size: 12.5px;
+ line-height: 1.7;
+ color: var(--muted);
+}
+
+.policy-footer {
+ font-size: 12px;
+ color: var(--muted);
+ padding-top: 12px;
+ border-top: 1px solid var(--border);
+}
+
+.policy-footer a {
+ color: var(--accent);
}
diff --git a/src/types/index.ts b/src/types/index.ts
index a77e63c..70045cf 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -102,6 +102,7 @@ export interface Project {
changelog?: ChangelogEntry[];
architecture?: BilingualText;
screenshots?: string[];
+ quickStart?: BilingualArray;
installGuide?: BilingualInstallGuide;
}
diff --git a/vite.config.ts b/vite.config.ts
index bc8a81f..cbcdf4c 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -20,6 +20,7 @@ export default defineConfig({
assetsInlineLimit: 4096,
},
server: {
+ host: true,
warmup: {
clientFiles: ['./src/data/loader.ts'],
},