把这轮媒体治理沉淀成规范,核心是一张体积上限表: 静态图 300KB/500KB · SVG 500KB/1MB 3 秒内动图 WebP 500KB/1MB(严禁 GIF,超 5 秒别用 WebP) 5 秒以上动图 MP4 1MB/2MB,等效 1080p 1Mbps(录屏类 0.5Mbps) 画质对比样片放宽到 4MB;再大的传 B 站/YouTube 内嵌,不进仓库 新增三节: - MP4 按「等效 1080p 码率」衡量而不是只看文件大小。实测一个 2.2MB 的小动图折合 1080p 高达 39.6Mbps,按 1Mbps 重编后 57KB;反过来 7.7MB 的长录屏折合才 1098k,压它只会糊。先看帧率再调码率, 120fps 降 30fps 直接省 3/4。 - 不要重复存放同一张图:没有中英差异的只放中文目录一份。清理历史 重复要同时满足「文件名相同」和「不含同族两个型号」,后者防止把 lpi3a/lpi4a 这类独立产品线绑在一起。 - 批量处理素材的纪律:基线对比、以构建产物为准、保留 CRLF 行尾、 替换带定界符、通用文件名不自动匹配、删引用要删整个标记。 自检清单与坑速查表同步更新。
24 KiB
AGENTS.md — sipeed_wiki 编写指南
面向 AI 助手 / 自动化协作者。人类贡献者请先看 README.md 与 share_docs/zh/readme.md。 For AI agents working on this repo. Written in Chinese because the source language of this wiki is Chinese; English docs are translations.
0. 四条铁律
- 不编造参数。 事实只能来自:用户确认、官方 GitHub 仓库 / Release、官网、实物实测。拿不准就问,不要推测后当事实写。
- 不动别人的目录。 本仓库多个产品线共用,只改你负责的产品目录与明确授权的公共文件。
- 不写内部信息。 本仓库是公开仓库。内网地址、NAS/共享盘路径、本机绝对路径、内部工具链接、人员账号、密钥,一律不进文档、不进注释、不进示例命令。粘贴日志前先脱敏。
- 改完必须本地构建 + 浏览器截图自检。 只看代码不算验证,这里的坑大多只在构建产物里暴露。
1. 仓库结构
docs/hardware/zh/ 中文硬件文档(主语种,图片实体都放这里)
docs/hardware/en/ 英文译本(文件名必须与 zh 一一对应)
docs/hardware/{zh,en}/sidebar.yaml 左侧导航,中英各一份
docs/soft/ 软件文档(maixpy / longan / Tang ...)
pages/index/{zh,en}/ 首页、短链页、404
layout/*.html 首页与分类页模板(home.html、slogic.html、maix.html ...)
layout/locales/ babel 翻译;.po/.pot 入库,.mo 构建时生成(已 gitignore)
static/ 全站静态资源(首页卡片图、轮播 banner)
site_config.json route(路由)/ translate(双语映射)/ plugins
out/ 构建产物,gitignore
路由在 site_config.json 的 route.docs 里,例如 /hardware/zh/ → docs/hardware/zh。
新增产品目录不需要改 site_config.json,只需放进已有路由下并加侧边栏条目。
2. 本地预览与构建
在仓库根目录执行:
uv sync # 从 pyproject.toml/uv.lock 建 .venv,已含 teedoc 及全部插件
uv run teedoc serve --host 127.0.0.1 --port 2333 # http://127.0.0.1:2333
什么时候必须干净全量构建(增量构建会骗你):重命名或删除文档、改 sidebar.yaml 结构、改 layout/ 或 locales/。
pkill -f 'teedoc.*serve' # 注意别让 pattern 匹配到你自己这条命令
rm -rf out
mkdir -p /tmp/teedoc_plugin_search # 不建会报 FileNotFoundError .../index_0.json
.venv/bin/python -m teedoc build
watch 范围:teedoc serve 只可靠监听 docs/。
- 改了
layout/→ touch 一下引用它的模板,或直接全量重建; - 改了
static/下的图 → 手动cp到out/static/...,否则浏览器看到的还是旧图。
3. 产品文档的标准结构
参考 logic_analyzer/slogic16u3 与 logic_analyzer/slogic32u3,一个产品拆 5 页,不要堆成一篇长文:
| 文件 | 回答读者的哪个问题 |
|---|---|
Introduction.md |
这是什么?能干什么?给谁用?(核心特性、规格表、产品图、相关链接) |
Quick_Start.md |
我怎么把它跑起来?(开箱 → 装软件 → 驱动权限 → 连接 → 接线接地 → 第一次采集 → 查看解码 → 下一步) |
Hardware_Specification.md |
硬件上有什么?(接口与引脚、指示灯、尺寸、配件、电气参数) |
Software_User_Guide.md |
怎么用深入?(上位机使用、参数取舍、解码、进阶) |
FAQ.md |
我卡住了怎么办?(问句式小标题,一问一答,按主题分组) |
目录下建 assets/,图片按 3 个子目录归类(见 §6)。
frontmatter
每个 md 必须有,update 倒序排列(最新在最前):
---
title: SLogic32U3 简介
keywords: LogicAnalyzer, SLogic, SLogic32U3, USB3.2, sigrok, 逻辑分析仪
update:
- date: 2026-10-06
version: v0.3
author: Sipeed
content:
- 拆出独立的快速上手页,简介只保留产品与规格
- 校正数字信号带宽、探头线、ADC 模组等参数表述
- date: 2026-09-30
version: v0.1
author: Sipeed
content:
- 初始化文档
---
content 写这次改了什么,一条一句,不要写"更新文档"这种废话。
标题层级
文件开头 # 页面名,正文从 ## 起。不要手写 1.1 1.2 这类编号(teedoc 自己生成目录);只有"快速上手"这类真有先后顺序的步骤才用 ## 1. 开箱 ## 2. 安装软件。
4. 中英双语
机制
site_config.json 的 translate.docs 把 /hardware/zh/ 映射到 docs/hardware/en。
翻译状态是构建期按「相对路径同名」匹配算出来的:zh 下有 logic_analyzer/foo/Bar.md、en 下没有同名文件,英文页顶部就会出现 This page not translated yet 横幅。
规则
-
重命名中文文件时,必须同步重命名英文文件,然后干净全量构建(增量构建不重算翻译索引,横幅不会消失,会误导你以为没修好)。
-
校验中英文件是否对齐:
cd docs/hardware && comm -3 \ <(cd zh && find . -name '*.md' | sort) \ <(cd en && find . -name '*.md' | sort)输出中与你产品相关的行应为空。
-
图片只在 zh 下存一份,英文页用相对路径回引:
 -
含文字的图(流程图、接线示意图、标注图)需要出英文版,命名加
_en后缀,与中文图放同一目录:gba-channel-map.jpg/gba-channel-map_en.jpg。生成图的脚本也一并保留两份。 -
页内锚点要用目标语言的标题 slug。中文页
#采样率与通道数在英文页是#sample-rate-vs-channel-count,直接照搬会断链。 -
英文不是中文的逐句直译。中文里的口语化连接词、排比、语气词在英文里删掉;句子拆短,用主动语态。
-
sidebar.yaml两份都要改,英文那份的 label 必须是英文(最常见的漏网之鱼)。
5. 侧边栏与短链
docs/hardware/{zh,en}/sidebar.yaml 是嵌套的 label / items / file:
- label: SLogic32U3
items:
- label: 简介
file: ./logic_analyzer/slogic32u3/Introduction.md
- label: 快速上手
file: ./logic_analyzer/slogic32u3/Quick_Start.md
侧边栏顺序就是推荐阅读顺序:简介 → 快速上手 → 硬件 → 软件 → FAQ,不要按字母序排。
短链在 pages/index/zh/<product>.html,按浏览器语言跳转到简介页。
文档改名后一定要改这里的目标文件名,否则 wiki.sipeed.com/<product> 直接 404。
6. 图片
来源与质感
- 先确认是否已有正式素材:动手出图之前,先向产品 / 项目负责人确认该产品有没有现成的官方素材(六视图、透视图、爆炸图、棚拍实拍、电商切片)。有就优先用现成的,不要自己另做一套风格不一致的图。素材存放位置向负责人索取,不要把路径写进文档或注释。
- 禁用:工程样机裸板、手机随手拍、桌面/木纹等生活化背景、带水印或截图工具红字的图。
- 产品图统一白底棚拍或渲染。
体积上限(硬指标)
| 素材类型 | 建议 | 上限 | 格式 |
|---|---|---|---|
| 静态图片 | 300 KB | 500 KB | JPEG / PNG(见下方分类) |
| 矢量图 SVG | 500 KB | 1 MB | SVG,上传前先 svgo |
| 3 秒内动图 | 500 KB | 1 MB | WebP,严禁 GIF;超过 5 秒就别用 WebP |
| 5 秒以上动图 | 1 MB | 2 MB | MP4,等效 1080p 1 Mbps;录屏类大范围不动的可降到 0.5 Mbps |
| 画质对比类视频 | — | 4 MB | 仅限传感器对比、微光夜视这类画质即内容的样片 |
| 再大的视频 | — | — | 传 B 站 / YouTube,网页内嵌播放器,不要进仓库 |
# 提交前检查自己新加的素材
find docs/hardware/zh/<product> -type f -size +500k -printf '%s\t%p\n' | sort -rn
为什么要较真到 KB:git 会永久保存每张图的每个历史版本,一张没压的大图即使以后删掉,也会让之后每一个完整 clone 的人多下载一次。本仓库历史已积到约 1GB,README 因此建议贡献者用 --depth=1。你现在省下的每一 MB,是替后面所有人省的。
静态图:先分清是「照片」还是「合成图形」
这是选对压缩方式的唯一关键,两类的处理方向完全相反:
| 照片 / 渲染图 | 合成图形(截图、线稿、原理图、UI) | |
|---|---|---|
| 特征 | 连续色调、噪点、渐变 | 大片纯色、锐利边缘、文字 |
| 用 | JPEG 有损 | PNG 调色板量化(或 WebP 无损) |
| 命令 | convert in.jpg -resize '1920x>' -quality 85 -strip out.jpg |
convert in.png -colors 256 -strip -define png:compression-level=9 out.png |
| 禁忌 | 别用无损,体积会暴涨 | 别用 JPEG/有损,文字会糊且更大 |
- 照片宽度一般不需要超过 1920px。
- 带透明通道的 PNG:若透明其实没被用到(
identify -format '%[opaque]' x.png为 true),转 JPEG 零视觉损失;真有透明的,合成白底再转(-background white -alpha remove -alpha off),别用默认黑底。 - 相机样片(传感器对比、微光夜视、显微图)画质本身就是内容,不要有损压缩。
- 实测参考:11.7MB 的产品 PNG 转 JPEG 后 444KB(−96%);1.4MB 的 PulseView 截图调色板量化后 44KB(−97%)且文字依旧锐利。
动图:3 秒内用 WebP,5 秒以上用 MP4
任何情况下都不要提交 GIF。 格式按时长选,编码模式再按「照片 / 合成」二分法选。需要 sudo apt install webp(提供 gif2webp、cwebp)。
# 合成图形 / 终端录屏 —— 无损(WebP 无损模式自带调色板,全面强于 GIF)
gif2webp -min_size -m 6 in.gif -o out.webp
# 实物影像 / 摄像头回放 —— 有损
gif2webp -lossy -q 35 -m 6 in.gif -o out.webp
坑一:有损 WebP 对文字是灾难。 有损走 VP8 的 DCT 变换编码,是为照片设计的;文字和线条是高频锐利边缘,DCT 要堆大量系数才能表示,于是又大又糊。实测一个 1884KB 的终端录屏:无损 800KB(−58%),有损 q45 反而 3640KB(+93%),-mixed 更差(+131%)。
坑二:缩放要用最近邻,不能用 lanczos。 终端录屏的本质是少量字形位图重复成千上万次,无损 WebP 靠 LZ77 把这些重复整段匹配掉。lanczos 这类插值滤镜做抗锯齿,会让同一个字母在不同位置变成不同的像素图案,重复匹配全部失效。同一文件缩到 2/3:lanczos 2000KB,最近邻 570KB,差 3.5 倍。
# 录屏缩放:最近邻 + 不抖动(抖动会毁掉无损赖以生效的平坦色块)
ffmpeg -i in.gif -vf "scale=iw*2/3:-1:flags=neighbor,split[a][b];\
[a]palettegen=max_colors=256[p];[b][p]paletteuse=dither=none" out.gif
缩放尺度:桌面录屏按 2/3 缩(直接砍到 640 会糊到看不清文字);实物拍摄长边超过 512 就缩到 512。缩完务必按原尺寸看一眼文字还认不认得出。
超过 5 秒就转 MP4。 画幅大、时间长的录屏,H.264 的帧间预测碾压 WebP——实测一个 2147KB 的 GIF,WebP 最优 829KB,MP4 只要 87KB。代价是 markdown 要写成 HTML,且 muted 和 playsinline 不能省,否则 iOS 不自动播放;MP4 也不支持透明通道。
<video src="./assets/demo.mp4" autoplay loop muted playsinline></video>
MP4:按「等效 1080p 码率」衡量,不要只看文件大小
文件大小会被时长和分辨率掩盖,真正该看的是单位面积码率:
等效1080p码率 = 实际码率 × (1920×1080) ÷ (宽×高)
目标 1 Mbps;录屏类大范围不动的可降到 0.5 Mbps。按这个口径换算出目标码率再编码:
# 目标 = 1000k × 面积比;录屏类用 500
ffmpeg -i in.mp4 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
-c:v libx264 -b:v ${T}k -maxrate $((T*3/2))k -bufsize $((T*2))k \
-pix_fmt yuv420p -an -movflags +faststart out.mp4
实测:一个 338×450、6.4 秒的小动图,折合 1080p 竟高达 39.6 Mbps(文件 2.2MB 看着不大,但单位面积码率离谱),按 1Mbps 重编后 57KB,−98%。反过来,一个 7.7MB 的 156 秒录屏折合才 1098k,已经很省,压它只会糊。
先看帧率再调码率。 120fps 的演示录屏降到 30fps 直接省 3/4,画面观感没区别——这比动码率划算得多。
画质即内容的样片不要动:传感器对比、微光夜视、显微图,压了等于毁掉它存在的意义。
动图/示意图如果是 html 渲染出来的,去改源 html 的输出尺寸,不要硬压已经生成的大图。
不要重复存放同一张图
没有明确中英差异的图片 / 动图 / 视频,只放一份,默认放中文目录下,英文页用相对路径回引:

反复复制除了撑大仓库没有任何好处。判断依据很简单:图里有中文文字才需要双份(那种本来就该出 _en 版本,见 §4),纯实拍、截图、原理图、线稿一律共用。
清理历史重复时,判别「同一份素材」要同时满足两条:
- 文件名完全相同 —— 文件名不同说明是两个产品碰巧用了同一张图(
cleam.png与clean_core_board.png),不是刻意复制 - 路径里不含同一产品族的两个不同型号 ——
lpi3a/lpi4a、tang-nano/tang-nano-1k、tang-primer-20k/25k、spmod_eink/spmod_rfid这些必须保持独立
第 2 条尤其重要:合并跨产品的同图会制造耦合,以后更新一个产品的图,另一个产品的文档会悄悄跟着变。为省几十 MB 把两条独立产品线绑在一起不划算。
批量处理素材时的纪律
一次改几百个文件时,下面每一条都是真摔过的坑:
- 先用基线证明自己没搞坏。 改之前在干净检出(
git worktree add /tmp/base HEAD)上跑一遍同样的检查器,改完再跑,对比两份清单。只看"数字变少了"会骗人——曾经断链从 230 降到 234,正是基线对比才暴露出我新引入了 5 处。 - 以构建产物为准,不是源码路径。 判断一张图线上到底能不能取到,要去
out/里按<img src>解析,而不是只看 markdown 里的相对路径。 - 读写文件必须保留原始行尾。 很多老文档是 CRLF,Python 默认模式读写会把整个文件转成 LF,改动量从 42 行虚增到 1200 多行,git blame 从此没法看。一律
open(p, encoding='utf-8', newline='')。 - 字符串替换要带定界符。
/assets/x.jpg是../../assets/x.jpg的子串,直接str.replace会把本来正常的引用改坏。替换时连(...)或src="..."一起匹配。 - 通用文件名不要自动匹配。
1.jpg、11.png这种即使全仓库唯一也可能只是撞车——实测有一例被匹配到毫不相关的文档。纯数字或短于 4 字符的文件名一律留给人工。 - 删图片引用要删整个标记,
![]()和<img>两种写法都要处理;表格里只清空单元格、保留表格结构;删完检查有没有留下空的<center class="half"></center>之类空壳。
命名与归类
有意义的英文短名 + 连字符,不要 a1.jpg / IMG_2034.jpg / 1.png:
view-front-mini-hdmi.jpg、dimensions.jpg、tpm-spi-setup_en.jpg。
assets/DCIM/ 实拍与渲染产品图
assets/Screenshots/ 上位机 / 网页截图
assets/MISC/ 示意图、接线图、尺寸图、流程图
7. 叙事与可读性(图文并茂、小白友好)
默认读者是第一次拿到这个产品的人,不是已经熟悉它的工程师。他不知道缩写,不知道该先做哪一步,也不知道做对了没有。所有写法围绕这一条展开。
整站的叙事路线
5 个页面连起来要是一条完整的路:这是什么 → 怎么跑起来 → 硬件细节 → 软件深入 → 卡住了怎么办。 页与页之间显式互链,不要让读者自己在侧边栏里找:简介页末尾指向快速上手,快速上手每一步引用到硬件页/软件页的对应小节,FAQ 的每个答案链回正文。每页结尾都要有"下一步",不留死胡同。
单页内部
- 倒金字塔:开头 2~3 句说清"它是什么、能干什么、给谁用",然后才展开。不要一上来就甩参数表。
- 先结论后细节:长表格、长列表前先给一句话结论("简单说:奇数脚是 GND,偶数脚是信号"),让不想细读的人也能拿走答案。
- 术语首次出现要就地解释或链接(Stream 模式、阈值电压、annular ring 这类),不要假定读者知道。
- 面向读者用"你",步骤用动词开头。
操作类内容
-
必须是线性编号步骤,一步一个动作。
-
每步给出可验证的结果,让读者确认自己做对了:"指示灯应变为青色""设备列表里应出现 SLogic32U3"。这是小白和老手体验差别最大的地方。
-
常见失败就地给出口("如果只亮蓝灯,见 FAQ · 指示灯"),不要让他先失败一次再去翻 FAQ。
-
危险或易错操作用引用块显式告警:接线顺序、电压范围、会清空数据的动作。
> ⚠️ 接线前先接地线,且确认被测信号电压在 0~10 V 范围内。 -
措辞不要把产品写复杂。例:确认通道线序写"肉眼从第一根依次数过去即可",而不是"用软件逐根拉高电平确认"——后者让人以为产品难用。
图文并茂
- 每一两节配一张图,不要出现整屏纯文字。
- 按内容选图:概念/数据流用示意图或 mermaid 流程图;操作步骤用界面截图(关键位置加框标注);产品形态用实拍或渲染;引脚、尺寸用线稿标注图。
- 较长的流程在开头先放一张总览图,读者先看懂骨架再读细节。
- 图要有说明文字,
![]()的 alt 写清楚图里是什么,不要留空或写 "image1"。 - mermaid 用 ```mermaid 代码块(teedoc 支持)。注意边标签不要太长,否则左侧箭头会被裁掉。
8. 内容口径
-
上位机 / 软件清单写之前,先去读对应 GitHub 仓库和 Release 资产,不要凭印象列。
-
未实测的案例或教程,明确标注"方法与预期,非实测结果"。
-
定位性描述按产品负责人拍板的口径,不要自由发挥。例:ALL LOGIC 写成"基于 DSView 的社区优秀上位机,适合熟悉 DSView 的用户",不要强调"非官方出品"。
-
跨页参数必须一致。同一参数会出现在简介、规格表、对比表、首页卡片、短链页多处,改一处后全仓库 grep 一遍:
grep -rn "350 MHz\|59×51×13" docs/ layout/ pages/
9. 首页与 layout
layout/slogic.html等分类页的产品卡片 按发布时间顺序排列,不是新品优先。- 同一组卡片图必须同比例、同底色,否则图文分割线参差。
- 卡片里产品的视觉体量要符合定位:入门款不能画得比旗舰还大。
- 图片居中要按主体本身居中,不要按含投影的外接矩形(投影会把主体顶偏)。
layout/home.html的轮播与文案走 babel i18n。
babel 的坑(务必手动复查)
构建时 teedoc 会自动跑 pybabel extract/update,新增的 msgid 会被 fuzzy 匹配到无关的旧翻译(真出过商品链接、按钮文案错配到别的产品)。
而 teedoc 的 compile_catalog 不带 --use-fuzzy,所以 fuzzy 条目根本不会编进 .mo——结果是英文页直接显示中文原文。两种错都要查。
改完 layout/*.html 后:
grep -n -B3 "fuzzy" layout/locales/*/LC_MESSAGES/messages.po
逐条核对 msgstr:
- 译文正确 → 删掉
#, fuzzy这一行,译文才会生效; - 译文是乱配的(尤其商品链接)→ 不要盲目清 fuzzy,清了等于把错误链接发布出去;留着 fuzzy 至少会回退到中文原链接,然后找负责人要正确的对照链接再填。
重建后抽查英文产物里有没有中文漏出:
grep -o '[一-龥]\{2,\}' out/en/index.html | sort -u | head
.mo 是构建产物(已 gitignore),只提交 .po / .pot。
10. 提交前自检清单
- 干净全量构建通过(
.venv/bin/python -m teedoc build输出 build ok) comm -3中英文件名对齐无差异- 浏览器实际点一遍:侧边栏每个二级页、短链、页内锚点、所有图片都正常
- 英文页顶部没有
This page not translated yet横幅;英文页没有中文漏出 - 新加素材符合 §6 体积上限(静态图 ≤500KB、SVG ≤1MB、动图 ≤1MB、视频 ≤2MB)
- 没有提交任何 GIF;5 秒以上的动图已转 MP4 并按等效 1080p 码率编码
- 超过 4MB 的视频走 B 站 / YouTube 内嵌,没有进仓库
- 没有中英差异的图只存了一份(中文目录下),英文页相对路径回引
- 图片命名有意义、放对了 assets 子目录
- 含文字的图有
_en版本 python3 tools/check_image_links.py退出码为 0(没有新增断链)- 每页有"下一步"出口,操作步骤有可验证结果
- 跨页参数一致(grep 过)
- frontmatter 的
update写了这次的实际改动 - 没有内网地址、共享盘路径、本机绝对路径、账号或密钥
- 只改了自己负责的目录
11. 坑速查表
| 现象 | 原因 | 解法 |
|---|---|---|
英文页顶部 This page not translated yet |
改名/删文件后增量构建没重算翻译索引 | 中英文件名对齐 + 干净全量构建 |
| 英文页显示中文原文 | 该条目在 .po 里被标了 #, fuzzy,compile 时被跳过 |
核对译文后删掉 #, fuzzy 行再重建 |
| 首页商品链接/文案串到别的产品 | babel fuzzy 误配 | 核对后改 msgstr;拿不到正确链接就保留 fuzzy |
构建报 FileNotFoundError .../teedoc_plugin_search/index_0.json |
临时目录不存在 | mkdir -p /tmp/teedoc_plugin_search |
改了 layout/ 页面没变化 |
serve 不监听 layout | touch 引用它的模板,或全量重建 |
改了 static/ 下的图没变化 |
未同步到 out/ |
cp 到 out/static/...,或全量重建 |
| 短链 404 | 文档改名后短链目标文件名没跟着改 | 改 pages/index/zh/<product>.html |
| 访问目录路径以为 404 | readme.md 会构建成该目录的 index.html |
直接访问目录路径即可,不是 bug |
| CI 显示构建完成但线上还是 404 | build_doc_upload 在对象存储上传步失败(RequestTimeout,teedoc-upload 无重试) |
去 Actions 重跑失败的 job |
pkill 把自己的命令也杀了 |
pattern 匹配到了自身命令行 | 用 pkill -f 'teedoc.*serve' 之类不自匹配的写法 |
| 批量改完 diff 有上千行,远超预期 | 老文档是 CRLF,默认模式读写转成了 LF | 读写一律 open(p, newline='') |
| 替换路径后把原本正常的引用也改坏 | 短路径是长路径的子串 | 替换时连 (...) / src="..." 定界符一起匹配 |
| 图片名字搜得到,就以为链接没问题 | 目录名或层级写错,文件在别处 | 以 out/ 构建产物为准,或跑 tools/check_image_links.py |
| 自动修断链时匹配到了无关的图 | 1.jpg 这类通用文件名撞车 |
纯数字或短于 4 字符的文件名不自动匹配 |
12. 参考
- 本地预览:http://127.0.0.1:2333
- CI:
.github/workflows/publish.yml,push 到 main 后构建 → 推 gh-pages → 上传对象存储 - 构建工具文档:teedoc