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
25 changes: 15 additions & 10 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: Deploy docs to GitHub Pages
name: Deploy VitePress to GitHub Pages

on:
push:
branches: [main]
paths:
- "docs/**"
- "README.md"
- "_config.yml"
- "package.json"
- ".github/workflows/pages.yml"
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
Expand All @@ -26,17 +26,22 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Setup Pages
uses: actions/configure-pages@v5

- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
- name: Setup Node.js
uses: actions/setup-node@v4
with:
source: ./docs
destination: ./_site
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Build VitePress
run: npm run docs:build

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: .vitepress-dist

deploy:
environment:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules/
dist/
.worktree/
.vitepress-dist/
140 changes: 140 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { defineConfig } from 'vitepress'
import { readdirSync, statSync } from 'node:fs'
import { join } from 'node:path'
import type { DefaultTheme } from 'vitepress'

function getSidebar(): DefaultTheme.Sidebar {
const docsDir = join(import.meta.dirname, '..')
const sidebar: DefaultTheme.Sidebar = {}

const dirLabels: Record<string, string> = {
guides: '使用指南',
adr: '架构决策记录',
dev: '开发文档',
prd: '产品需求文档',
}

for (const dir of ['guides', 'adr', 'dev', 'prd']) {
const fullDir = join(docsDir, dir)
const items: DefaultTheme.SidebarItem[] = []
const entries = readdirSync(fullDir).sort()
for (const entry of entries) {
if (entry.startsWith('.')) continue
const fullPath = join(fullDir, entry)
if (entry.endsWith('.md')) {
const name = entry.replace('.md', '')
items.push({
text: name.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
link: `/${dir}/${name}`,
})
} else if (statSync(fullPath).isDirectory()) {
const subEntries = readdirSync(fullPath).sort().filter(e => e.endsWith('.md'))
if (subEntries.length > 0) {
items.push({
text: entry.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
collapsed: dir === 'dev' && entry === 'tasks',
items: subEntries.map(e => ({
text: e.replace('.md', '').replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
link: `/${dir}/${entry}/${e.replace('.md', '')}`,
})),
})
}
}
}
if (items.length > 0) {
sidebar[`/${dir}/`] = [{ text: dirLabels[dir] || dir, items }]
}
}

return sidebar
}

export default defineConfig({
title: 'opencode-cabbage',
description: '全流程开发 OpenCode 插件 — 需求→设计→任务→编码→测试→审查→自动合并',
srcDir: '.',
outDir: '../.vitepress-dist',
lastUpdated: true,
cleanUrls: true,

themeConfig: {
nav: [
{ text: '首页', link: '/' },
{ text: '快速开始', link: '/guides/quickstart' },
{
text: '使用指南',
items: [
{ text: '快速开始', link: '/guides/quickstart' },
{ text: '配置指南', link: '/guides/configuration' },
{ text: '使用指南', link: '/guides/usage' },
{ text: '架构概览', link: '/guides/architecture' },
],
},
{
text: '开发',
items: [
{ text: '贡献指南', link: '/dev/guides/contributing' },
{ text: '技术方案', link: '/dev/specs/opencode-cabbage-docs-and-pages' },
{ text: 'VitePress 迁移', link: '/dev/specs/vitepress-docs-migration' },
{ text: 'Out of Scope', link: '/dev/out-of-scope' },
],
},
{
text: 'ADR',
items: [
{ text: '0001 - 替换 OpenSpec', link: '/adr/0001-replace-openspec-with-full-flow' },
{ text: '0002 - Jekyll 文档站', link: '/adr/2026-07-10-jekyll-github-pages-docs' },
{ text: '0003 - 迁移 VitePress', link: '/adr/2026-07-10-jekyll-to-vitepress' },
],
},
{
text: 'PRD',
items: [
{ text: 'Docs & Pages', link: '/prd/opencode-cabbage-docs-and-pages' },
{ text: 'VitePress 迁移', link: '/prd/vitepress-docs-migration' },
],
},
],

sidebar: getSidebar(),

search: {
provider: 'local',
options: {
translations: {
button: {
buttonText: '搜索',
buttonAriaLabel: '搜索文档',
},
modal: {
displayDetails: '显示详情',
noResultsText: '未找到相关结果',
resetButtonTitle: '清除搜索',
footer: {
selectText: '选择',
navigateText: '切换',
closeText: '关闭',
},
},
},
},
},

socialLinks: [
{ icon: 'github', link: 'https://github.com/devcxl/opencode-cabbage' },
],

editLink: {
pattern: 'https://github.com/devcxl/opencode-cabbage/edit/main/docs/:path',
},

lastUpdated: {
text: '最后更新',
},

docFooter: {
prev: '上一页',
next: '下一页',
},
},
})
18 changes: 0 additions & 18 deletions docs/_config.yml

This file was deleted.

2 changes: 1 addition & 1 deletion docs/adr/2026-07-10-jekyll-github-pages-docs.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ADR 0002: 使用 Jekyll + GitHub Pages 部署文档站点

**状态:** Accepted
**状态:** Superseded(被 [ADR 0003](/adr/2026-07-10-jekyll-to-vitepress) 替代)
**日期:** 2026-07-10

## 背景
Expand Down
68 changes: 68 additions & 0 deletions docs/adr/2026-07-10-jekyll-to-vitepress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# ADR 0003: 从 Jekyll 迁移到 VitePress

**状态:** Accepted
**日期:** 2026-07-10
**上级:** [ADR 0002](/adr/2026-07-10-jekyll-github-pages-docs)(被替代)

## 背景

[ADR 0002](/adr/2026-07-10-jekyll-github-pages-docs) 选择了 Jekyll + GitHub Pages 作为文档站方案,理由是"零运维成本、push 即部署"。但在实际使用中暴露了以下问题:

1. **Ruby 生态割裂**:项目是 TypeScript/Vite 技术栈,Jekyll 需要 Ruby 环境和 Bundler,贡献者本地调试需要额外安装 Ruby,增加了入门门槛
2. **构建受限**:Jekyll 的 GitHub Pages 构建基于 GitHub 的托管环境,无法自定义构建流程,Gemfile 依赖受限
3. **搜索缺失**:Jekyll 默认不提供全文搜索,需要集成第三方插件(如 lunr.js),而 GitHub Pages 不运行自定义插件
4. **开发体验差**:Jekyll 的 livereload 需要额外配置,修改配置后需要重启

## 决策

将文档站从 Jekyll 迁移到 **VitePress**,使用 GitHub Actions 构建并部署到 GitHub Pages。

## 选择 VitePress 的原因

| 维度 | VitePress | Jekyll |
|------|-----------|--------|
| 技术栈 | TypeScript + Vite,与项目一致 | Ruby,与项目割裂 |
| 开发体验 | 热更新 < 1s,配置热重载 | 需手动刷新,配置需重启 |
| 搜索 | 内置 minisearch,零配置 | 需第三方插件 |
| 构建速度 | Vite 二次构建极快 | Jekyll 每次全量构建 |
| 维护方 | Vue 团队(Evan You) | 社区 |
| 导航/侧边栏 | 内置自动生成 | 需手动配置或插件 |
| 主题 | 默认主题即开即用 | 受 GitHub Pages 支持列表限制 |

## 备选方案

| 方案 | 未采纳原因 |
|------|-----------|
| 保留 Jekyll | 已暴露上述问题,且文档站有 19 个 `.md` 文件,搜索和导航需求日益迫切 |
| Docusaurus | 功能丰富但偏重,对于 19 个页面的文档站是过度设计;React 技术栈与项目 Vue 倾向不一致 |
| Nextra | 依赖 Next.js,引入额外框架依赖 |
| 纯 HTML | 维护成本高,不符合"文档站"定位 |

## 迁移范围

- **保留**:全部 19 个 `.md` 文件内容不变,目录结构不变
- **新增**:`docs/.vitepress/config.ts`(VitePress 配置)、`.github/workflows/pages.yml`(CI 构建部署)
- **删除**:`docs/_config.yml`(Jekyll 配置)
- **改造**:`docs/index.md`(从 Jekyll 首页改为 VitePress 首页布局)
- **不修改**:文档内容、目录结构、文件名

## 后果

### 正向

- 技术栈统一:贡献者无需安装 Ruby,仅需 Node.js >= 18
- 开发体验提升:`npm run docs:dev` 即可启动热更新开发服务器
- 全文搜索:内置 minisearch,用户在文档站内即可搜索全部内容
- 自动侧边栏:按目录结构自动生成,新增文档无需手动注册
- 构建可控:GitHub Actions 上自定义构建流程,不受 GitHub Pages 托管限制
- 未来扩展:VitePress 支持自定义主题、Vue 组件嵌入,为后续扩展留空间

### 风险

- 需要创建 GitHub Actions workflow(`.github/workflows/pages.yml`),而非 Jekyll 的自动构建
- 需要在仓库 Settings → Pages 中将 Build source 从 "Deploy from a branch" 改为 "GitHub Actions"
- 旧版 Jekyll 链接(如有外部引用)需要重定向(影响极小,文档站尚未广泛传播)

## 技术方案

详见 [VitePress 文档站迁移技术方案](/dev/specs/vitepress-docs-migration)。
9 changes: 9 additions & 0 deletions docs/dev/out-of-scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@
- 多语言/国际化文档 — 非必要
- 文档搜索功能 — 可通过 GitHub Pages 搜索替代
- 版本化文档(多版本切换) — 待项目成熟后再考虑

## VitePress 文档站迁移

以下需求在访谈中明确排除,记录于此供后续参考:

- 自定义 VitePress 主题 — 使用默认主题
- 自定义域名配置
- 多语言支持
- 文档内容重写/重组 — 仅迁移,不修改内容
Loading
Loading