chore(skills): remove maintainer skills from public repo

This commit is contained in:
digua committed 2026-06-07 14:38:50 +08:00
1 parent 4347c596ca
commit 093fdd1f2d
14 files changed
-820

No files matched your search

-225
View File
@@ -1,225 +0,0 @@
---
name: generate-assistant-config
description: Use when 用户希望根据一句自然语言需求创建新的 ChatLab assistant 配置、assistant Markdown、分析助手模板,或需要为群聊/私聊场景整理可写入 assistant/<locale>/<assistant-id>.md 的多语言助手文件。
---
# generate-assistant-config
为 ChatLab 生成 assistant Markdown。先动态追问补齐关键信息,只输出中文预览;用户确认后,再生成 `zh / en / ja` 三份本地化版本并写入 `assistant/`。
## 使用前先确认
- `skills/` 是开发代理技能目录;本技能自身放这里
- `assistant/` 是 assistant Markdown 产物目录;最终 assistant 文件写这里
- 当前仓库里的 `assistant/*.md` 可视为历史参考样例;新生成的多语言 assistant 写入 `assistant/<locale>/`
- 当前项目 assistant 的真实格式以运行时代码为准,不以过期文档为准
- 如 `.docs/ai/assistantSystem.md` 与运行时代码冲突,以以下文件为准:
- `apps/desktop/main/ai/assistant/parser.ts`
- `apps/desktop/main/ai/assistant/types.ts`
- `apps/desktop/main/ai/assistant/manager.ts`
- `apps/desktop/main/ai/tools/definitions/index.ts`
- `apps/desktop/main/ai/tools/definitions/sql-analysis.ts`
## 必读上下文
开始前读取这些文件,只读满足任务所需的最小内容:
1. 项目与 AI 总体上下文
- `.docs/README.md`
- `.docs/ai/README.md`
- `.docs/ai/assistantSystem.md`
2. assistant 真实格式与落地约束
- `apps/desktop/main/ai/assistant/parser.ts`
- `apps/desktop/main/ai/assistant/types.ts`
- `apps/desktop/main/ai/assistant/manager.ts`
3. 默认骨架与工具来源
- `apps/desktop/main/ai/assistant/builtins/general_cn.md`
- `apps/desktop/main/ai/tools/definitions/index.ts`
- `apps/desktop/main/ai/tools/definitions/sql-analysis.ts`
## 硬规则
- 不要直接套用旧文档中的 `version`、`order`、`customSqlTools` 等已过期字段
- frontmatter 只允许使用当前 parser 支持的字段:
- `id`
- `name`
- `presetQuestions`
- `allowedBuiltinTools`
- `builtinId`
- `applicableChatTypes`
- `supportedLocales`
- 生成普通 assistant 文件时,不要写 `builtinId`
- 如果角色无需分析工具,优先省略 `allowedBuiltinTools`(默认仅核心工具可用)
- `allowedBuiltinTools` 仅填写分析工具名(核心工具始终可用,无需列出),不得臆造、不得引用旧名字
- 最终写入路径固定为 `assistant/<locale>/<assistant-id>.md`
- 目标语言固定为 `zh`、`en`、`ja`
- 三个语言版本保持同一角色定位,但允许按语言做自然的本地化调整,不做机械直译
- 任一目标文件已存在时,必须停止并征求用户确认,不能直接覆盖
## 动态追问规则
- 用户通常会给一句自然语言需求,例如“帮我生成一个适用于群聊的社群分析助手”
- 先从用户原话中提取已有信息,不要重复问已经明确的内容
- 只追问缺失且会影响 assistant 行为边界的关键信息
- 追问应当动态,不使用固定问卷
- 每轮只问一个当前最关键的问题,通常总问题数控制在 3 到 5 个
- 优先补齐以下信息:
- 角色核心目标:主要解决什么问题
- 使用场景:`group`、`private` 或通用
- 语气与回答风格:专业、温暖、轻松、克制等
- 输出偏好:更偏总结、排行、建议、证据引用、结构化呈现
- 明显不该给的工具边界
- 如果用户一句话已经足够清楚,可以少问;不要为了凑问题数而发问
## 工作流
### 阶段一:中文预览,不落盘
1. 读完必读上下文后,先总结已知信息和仍然缺失的关键点
2. 动态追问,直到信息足够生成 assistant
3. 先生成一份中文 assistant Markdown 预览
4. 此阶段只在对话中输出 Markdown,不写文件
5. 预览完成后,明确等待用户确认,不要提前生成多语言文件
### 阶段二:确认后生成多语言文件
仅在用户明确确认中文预览后执行:
1. 为 `zh`、`en`、`ja` 各生成一份 assistant Markdown
2. 三份文件使用同一个 `assistant-id`
3. `name`、`presetQuestions`、正文语气允许按语言本地化
4. `supportedLocales` 分别写为:
- `zh` 文件:`- zh`
- `en` 文件:`- en`
- `ja` 文件:`- ja`
5. 写入前检查以下目标是否已存在:
- `assistant/zh/<assistant-id>.md`
- `assistant/en/<assistant-id>.md`
- `assistant/ja/<assistant-id>.md`
6. 任一已存在则停止,并把已存在路径明确告诉用户,等待是否覆盖的确认
7. 用户确认允许覆盖后,才写入全部目标文件
## assistant-id 规则
- 使用英文小写短横线命名
- 不带语言后缀
- 不带无意义的 `assistant` 冗余词,除非不带会造成歧义
- 尽量根据角色核心定位提炼为 2 到 4 个词
示例:
- 社群运营分析助手 -> `community-analyst`
- 客服复盘助手 -> `customer-service-reviewer`
- 关系洞察助手 -> `relationship-insight`
如果用户给了明确名称:
- 尊重用户命名语义
- 自动规范化为合法 id
- 如名称过泛,例如“分析助手”,先追问收窄再定 id
## 工具选择规则
工具分为两类:
- **核心工具(core)**:始终启用,无需在 `allowedBuiltinTools` 中列出。包括:get_chat_overview, search_messages, get_recent_messages, get_message_context, search_sessions, get_session_messages, get_members
- **分析工具(analysis)**:需在 `allowedBuiltinTools` 中显式列出才会启用
`allowedBuiltinTools` 仅用于控制分析工具,核心工具始终可用:
- 若角色不需要分析工具,可省略 `allowedBuiltinTools`(默认仅核心工具可用)
- 若角色需要特定分析能力,列出所需的分析工具名称
- 仅在角色明显聚焦时选择对应的分析工具,例如:
- 强运营分析:get_member_stats, get_time_stats, member_activity_trend, silent_members
- 强情感洞察:mutual_interaction_pairs, reply_interaction_ranking, get_conversation_between
- 强客服分析:unanswered_messages, message_type_breakdown, get_conversation_between
生成前做一次自检:
- 是否引用了不存在的工具名
- `allowedBuiltinTools` 中是否误放了核心工具(核心工具无需列出)
- 是否包含明显与场景冲突的工具
## 输出模板
中文预览与最终落盘文件都使用同一结构:
```md
---
id: assistant-id
name: 助手名称
applicableChatTypes:
- group
supportedLocales:
- zh
allowedBuiltinTools:
- get_member_stats
- get_time_stats
presetQuestions:
- 示例问题 1
- 示例问题 2
---
你是一位……
你的核心能力是:
- …
- …
你的回答风格应该……
## 回答要求
1. …
2. …
3. …
```
## frontmatter 细则
- `id`:所有语言版本保持一致
- `name`:允许本地化,不必逐字对应
- `applicableChatTypes`:仅在能明确判断时写入;通用角色可省略
- `supportedLocales`:按文件所属语言写单元素数组
- `allowedBuiltinTools`:仅填写需要的分析工具名(核心工具无需列出,始终可用)
- `presetQuestions`:建议 3 到 5 条,贴近该语言用户的自然表达
## 正文写法规则
- 第一段:一句话定义角色与任务
- 第二段:列出“核心能力”
- 第三段:定义回答风格
- 最后使用 `## 回答要求`
- 回答要求应强调:
- 基于工具结果,不编造
- 数据不足时明确说明
- 输出结构和证据引用方式
- 该角色独有的风格约束
## 确认前后的响应要求
用户确认前:
- 只输出中文预览 Markdown
- 不写文件
- 不提前生成 `en` 或 `ja`
- 在 Markdown 后用一句话请求确认
用户确认后:
- 先检查目标路径是否存在
- 若不存在,再生成并写入三份文件
- 完成后向用户汇报:
- 实际写入的 3 个路径
- 是否做了工具白名单限制
- 是否有任何本地化调整
## 常见错误
- 把 assistant 产物写到 `skill/` 或 `skills/`,而不是 `assistant/`
- 机械照抄 `.docs/ai/assistantSystem.md` 的旧字段
- 在未确认中文预览前就直接落盘
- 把核心工具名塞进 `allowedBuiltinTools`(核心工具始终可用,不需要列出)
- 多语言版本仅做逐字翻译,导致预设问题和语气不自然
- 发现同名文件已存在,却直接覆盖
@@ -1,4 +0,0 @@
interface:
display_name: '生成 Assistant 配置'
short_description: '根据自然语言需求动态追问,先给中文预览,再生成 zh/en/ja assistant Markdown'
default_prompt: 'Use $generate-assistant-config to turn a natural-language assistant idea into a ChatLab assistant Markdown. Ask dynamic follow-up questions, preview the Chinese version first, and only after approval generate localized zh/en/ja files under assistant/<locale>/<assistant-id>.md without overwriting existing files.'
-175
View File
@@ -1,175 +0,0 @@
---
name: generate-changelog
description: 根据当前项目 package.json 版本与 Git 提交记录生成中文版本日志。用于用户提出"生成版本日志""生成 changelog""发布新版本并生成更新记录"等请求时,自动读取当前版本号、定位上一版本、汇总版本区间 commit,并更新 changelogs/cn.json(新增版本、生成中文 summary、按类型归类变更)。
---
# generate-changelog
按以下流程更新 `changelogs/cn.json`。
## 0. 发布预检(Pre-release Checks)
**在执行任何 changelog 相关操作前,必须先完成以下预检。任意一项失败则立即停止,报告错误并提示用户修复后再重试。**
### 0.1 TypeScript 类型检查
运行全量类型检查(同时覆盖 Web 与 Node/Electron 主进程):
```bash
pnpm run type-check:all
```
- 成功:输出 `[预检 ✓] 类型检查通过`,继续下一步。
- 失败:输出完整错误信息,停止并提示 `[预检 ✗] 类型检查失败,请修复后重新执行 generate-changelog`。
### 0.2 Vite 构建检查
运行桌面端完整构建(electron-vite build),验证 Rollup 打包不会因模块导出缺失等问题而报错:
```bash
pnpm run build:desktop
```
- 成功:输出 `[预检 ✓] 构建检查通过`,继续下一步。
- 失败:输出完整错误信息,停止并提示 `[预检 ✗] 构建失败,请修复后重新执行 generate-changelog`。
> **说明**:`type-check:all` 覆盖导出缺失、类型错误等静态问题;`build:desktop` 覆盖 Rollup 打包层面的模块解析问题(如本次漏写 re-export 导致的报错),两者互补。
### 0.3 报告预检结论
两项全部通过后输出:
```
[预检完成] 类型检查 ✓ 构建检查 ✓,开始生成 changelog...
```
---
## 1. 读取版本与日志现状
1. 读取 `package.json` 中的 `version` 作为 `currentVersion`。
2. 读取 `changelogs/cn.json`,确认是否已存在 `currentVersion`。
3. 若已存在:停止新增流程,改为"就地更新该版本内容"。
4. 计算 `previousVersion`:
- 若 `currentVersion` 已存在于 changelog:取它的下一条记录版本号。
- 若 `currentVersion` 不存在于 changelog:取第一条记录版本号。
5. 若无法读取 `previousVersion`,报错并停止。
## 2. 确定 commit 区间
优先按以下规则确定区间:
1. 若存在 tag `v{currentVersion}`:使用 `v{previousVersion}..v{currentVersion}`。
2. 若不存在 tag `v{currentVersion}`:使用 `v{previousVersion}..HEAD`。
3. 若 `v{previousVersion}` 不存在:回退为从首个提交到 `HEAD`,并在结果中明确标注"缺少上一版本 tag,采用全量范围"。
使用命令:
```bash
git log --no-merges --pretty=format:'%h%x09%s' <RANGE>
```
必要时读取正文:
```bash
git show -s --format='%B' <commit>
```
## 3. 归类与清洗
将 commit 按以下类型归类到 `changes[].type`:
- `feat`
- `fix`
- `refactor`
- `perf`
- `style`
- `docs`
- `test`
- `build`
- `ci`
- `chore`
- `revert`
- `other`(无法识别前缀时)
归类规则:
1. 优先从 Conventional Commit 前缀识别(如 `feat:`, `fix(scope):`)。
2. 无前缀时,根据语义判断;无法判断放入 `other`。
3. 忽略纯发布噪音提交(如仅版本号、仅锁文件且无业务影响的提交),除非用户明确要求保留。
4. 将每条 item 改写为简洁中文短句,避免直接照搬英文标题。
端标记规则:
1. 只有某个端或某个集成入口专属的变更,才在 item 前加中文全角前缀。
2. 跨端共享、用户感知一致或底层统一能力的变更不加前缀,保持自然描述。
3. 推荐前缀:
- `【桌面端】`:仅 Electron 桌面端可见或仅影响桌面端。
- `【CLI Web】`:仅通过 CLI 启动的 Web UI 可见或仅影响 Web 模式。
- `【CLI】`:仅命令行、npm 包、CLI 启动/发布链路相关。
- `【MCP】`:仅 MCP Server、MCP 设置或 MCP 工具集相关。
4. 如果同一能力在多端都有入口,但实现或体验不同,可拆成多条专属 item;如果重点是统一后的共享能力,则写成不带前缀的跨端 item。
5. `summary` 可概括提及端名,但不使用前缀格式。
6. 同一个 `type` 下的 `items` 排序:先放不带端前缀的通用/跨端变更,再放带端前缀的专属变更;专属变更内部按影响范围和用户可感知程度排序。
## 4. 生成 summary
为本版本生成 1 句中文 summary:
1. 优先覆盖用户可感知变化(功能、修复、性能、体验)。
2. 保持与历史风格一致(简洁、非营销语气)。
3. 长度控制在 18-60 字。
## 5. 更新 JSON 文件
目标文件:`changelogs/cn.json`
更新规则:
1. 构造新对象:
- `version`: `currentVersion`
- `date`: 当前日期(`YYYY-MM-DD`)
- `summary`: 新生成摘要
- `changes`: 分类后的数组(每个元素为 `{ "type": string, "items": string[] }`)
2. 若不存在当前版本,插入到数组首位。
3. 若已存在当前版本,替换该版本对象,但保持其在数组中的原位置。
4. 保持 JSON 可读格式(2 空格缩进,UTF-8,无注释)。
5. 写入后必须执行格式化,优先使用项目 Prettier,确保与"手动保存"风格一致:
```bash
npx prettier --write changelogs/cn.json
```
6. 若环境没有 Prettier,回退为 `JSON.stringify(..., null, 2)` 的最小格式保证,并在输出中明确提示"未执行 Prettier 格式化"。
## 6. 自检
写入后执行以下检查:
1. JSON 语法合法。
2. `version` 无重复。
3. `changes` 中每个 `items` 至少 1 条。
4. 与 commit 区间相比,无明显遗漏的关键变更(特别是 `feat` / `fix`)。
若自检失败,修复后再输出结果。
补充检查:
5. 确认 `changelogs/cn.json` 已经过 Prettier(若可用)。
## 7. 任务完成后询问
自检通过并输出结果后,必须询问用户:
> "changelog 已生成完毕。是否继续执行 sync-changelog 技能,将本版本日志同步为多语言版本并提交?"
- 若用户确认,立即读取并执行同目录下的 `../sync-changelog/SKILL.md`。
- 若用户拒绝或未明确回应,结束当前任务。
## 参考文件
需要查看项目格式细节时,读取:
- `references/changelog-format.md`
- `scripts/extract_commits_for_changelog.sh`
- `scripts/format_changelog.sh`
@@ -1,4 +0,0 @@
interface:
display_name: '生成版本日志'
short_description: '按版本区间提取提交并自动生成项目中文 changelog 文件'
default_prompt: 'Use $generate-changelog to read package.json version, collect commits since the previous version, and update changelogs/cn.json.'
@@ -1,30 +0,0 @@
# changelog-format
本项目中文更新日志文件:`changelogs/cn.json`
## 顶层结构
- 顶层为数组
- 每个元素代表一个版本对象
- 版本按时间倒序(最新在前)
## 版本对象字段
- `version`: 版本号字符串(示例:`0.9.3`)
- `date`: 发布日期(`YYYY-MM-DD`)
- `summary`: 中文一句话摘要
- `changes`: 分类变更数组
## changes 子项结构
- `type`: 分类类型(如 `feat`、`fix`、`refactor`、`chore`)
- `items`: 该分类下的中文要点数组
## 风格约束
- 保持简洁叙述,避免营销语。
- `summary` 聚焦用户可感知变化。
- `items` 使用短句,尽量一条表达一个改动。
- 若某分类无条目,不写该分类。
- 仅端特有或入口特有的 item 加前缀,如 `【桌面端】`、`【CLI Web】`、`【CLI】`、`【MCP】`;跨端共享或统一能力不加前缀。
- 同一分类下先写通用/跨端变更,再写带端前缀的专属变更。
@@ -1,62 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# 读取项目根目录(默认取当前目录,可通过第一个参数覆盖)
ROOT_DIR="${1:-$(pwd)}"
# 读取 package.json 中的当前版本号
CURRENT_VERSION="$(node -e "const fs=require('fs');const p=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));process.stdout.write(p.version||'');" "$ROOT_DIR/package.json")"
if [[ -z "$CURRENT_VERSION" ]]; then
echo "错误: 无法从 package.json 读取 version" >&2
exit 1
fi
# 基于 changelog 计算上一版本号:
# - 若当前版本已存在于 changelog 中,取其后一条作为上一版本
# - 若当前版本不存在,取首条作为上一版本
CHANGELOG_META="$(
node -e "
const fs=require('fs');
const arr=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));
const current=process.argv[2];
const idx=arr.findIndex(i=>i?.version===current);
const exists=idx!==-1;
const prev=exists ? (arr[idx+1]?.version||'') : (arr?.[0]?.version||'');
process.stdout.write(JSON.stringify({exists, prev}));
" "$ROOT_DIR/changelogs/cn.json" "$CURRENT_VERSION"
)"
PREVIOUS_VERSION="$(node -e "const m=JSON.parse(process.argv[1]);process.stdout.write(m.prev||'');" "$CHANGELOG_META")"
CURRENT_EXISTS="$(node -e "const m=JSON.parse(process.argv[1]);process.stdout.write(String(Boolean(m.exists)));" "$CHANGELOG_META")"
if [[ -z "$PREVIOUS_VERSION" ]]; then
echo "错误: 无法从 changelogs/cn.json 读取上一版本" >&2
exit 1
fi
CURRENT_TAG="v${CURRENT_VERSION}"
PREVIOUS_TAG="v${PREVIOUS_VERSION}"
RANGE=""
# 优先使用当前版本 tag;若不存在,则使用上一版本到 HEAD 的区间
if git -C "$ROOT_DIR" rev-parse --verify "$CURRENT_TAG" >/dev/null 2>&1; then
RANGE="${PREVIOUS_TAG}..${CURRENT_TAG}"
else
RANGE="${PREVIOUS_TAG}..HEAD"
fi
# 若上一版本 tag 不存在,回退为全量提交并提示原因
if ! git -C "$ROOT_DIR" rev-parse --verify "$PREVIOUS_TAG" >/dev/null 2>&1; then
echo "WARN: 缺少上一版本 tag(${PREVIOUS_TAG}),回退为全量范围" >&2
RANGE="$(git -C "$ROOT_DIR" rev-list --max-parents=0 HEAD | tail -n 1)..HEAD"
fi
# 输出版本和区间,便于技能调用方记录上下文
printf 'current_version=%s\n' "$CURRENT_VERSION"
printf 'previous_version=%s\n' "$PREVIOUS_VERSION"
printf 'current_exists=%s\n' "$CURRENT_EXISTS"
printf 'range=%s\n' "$RANGE"
echo "commits:"
# 输出提交哈希与标题,使用制表符分隔便于后续解析
# shellcheck disable=SC2016
git -C "$ROOT_DIR" log --no-merges --pretty=format:'%h%x09%s' "$RANGE"
@@ -1,22 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# 读取项目根目录(默认当前目录,可通过参数覆盖)
ROOT_DIR="${1:-$(pwd)}"
TARGET_FILE="$ROOT_DIR/changelogs/cn.json"
if [[ ! -f "$TARGET_FILE" ]]; then
echo "错误: 未找到 $TARGET_FILE" >&2
exit 1
fi
# 优先使用 Prettier,保证与本地保存时格式一致
if command -v npx >/dev/null 2>&1; then
npx --yes prettier --write "$TARGET_FILE" >/dev/null
echo "formatted_by=prettier"
exit 0
fi
# 兜底:若无 npx,则仅做最小 JSON 格式化保证
node -e "const fs=require('fs');const p=process.argv[1];const j=JSON.parse(fs.readFileSync(p,'utf8'));fs.writeFileSync(p,JSON.stringify(j,null,2)+'\n');" "$TARGET_FILE"
echo "formatted_by=json_stringify_fallback"
-94
View File
@@ -1,94 +0,0 @@
---
name: sync-changelog
description: 将 changelogs/cn.json 的当前版本日志同步为多语言版本:生成适合英文母语者阅读的英文版、适合繁体中文用户阅读的繁中版、适合日语母语者阅读的日文版,分别更新 changelogs/en.json、changelogs/tw.json、changelogs/ja.json,并在当前项目创建 release 提交(包含 package.json 与四种语言 changelog)。用于用户提出"同步版本日志""生成并同步 changelog""发布前同步多语言日志"等请求。仅创建 commit,不执行 push。
---
# sync-changelog
按以下流程执行,任何一步失败都立即停止,不做 push。
## 1. 前置检查(必须)
1. 当前仓库必须工作区干净:
- 执行 `git status --porcelain`。
- 允许白名单改动:`package.json`、`changelogs/cn.json`(这两个文件可作为本次任务前置输入)。
- 若存在白名单外改动(包含已暂存/未暂存/未跟踪),立即退出并提示用户手动处理。
2. 当前仓库必须在 `main`:
- 若不在 `main`,仅在工作区干净时执行 `git checkout main`。
可复用脚本:`scripts/preflight_main_clean.sh` 当前仓库建议调用:
```bash
scripts/preflight_main_clean.sh . "package.json,changelogs/cn.json"
```
## 2. 读取当前版本并校验文件
1. 从 `changelogs/cn.json` 读取第一个对象作为当前版本。
2. 读取版本号 `version`(例如 `0.9.6`)。
3. **在开始翻译前,必须重新读取一次该版本的完整中文内容(`summary` 与 `changes`),并以这次读取结果作为唯一翻译源。**
4. **严禁复用之前由 `generate-changelog` 或任意草稿步骤产出的缓存文案;若用户在生成后手动修改过中文日志,必须以用户修改后的文件内容为准。**
5. 检查以下文件是否存在:
- `changelogs/en.json`
- `changelogs/tw.json`
- `changelogs/ja.json`
6. 任一目标文件不存在都立即退出,不允许自动创建。
## 3. 生成多语言 changelog(AI 翻译)
1. 将当前版本中文内容分别转写为英文、繁体中文、日文,统一要求:
- 不做逐字直译。
- 保持原始结构:`version/date/summary/changes(type/items)`。
- 不改动 `version`、`date`、`changes.type`。
2. 语言要求:
- 英文:使用自然、简洁、适合英文母语用户的 release notes 语气。
- 繁体中文:以台湾常见产品文案口吻重写,避免简体直转。
- 日文:使用自然、简洁、适合日本用户阅读的产品更新说明语气,避免中文式表达。
3. 分别更新:
- `changelogs/en.json`
- `changelogs/tw.json`
- `changelogs/ja.json`
4. 每个目标文件都遵循相同规则:
- 若已存在该版本,替换该版本对象。
- 若不存在,插入到数组首位。
5. 翻译时必须逐条对应当前中文条目:`summary` 与 `changes.items` 的语义都应来自最新中文文件内容,不得沿用旧版本措辞。
6. 写入后执行格式化(若项目有 Prettier,优先使用 Prettier)。
## 4. 生成多语言 Markdown
在提交前,将 4 个 JSON 渲染为可读的 Markdown 文件:
```bash
node scripts/changelog-to-markdown.mjs
prettier --write changelogs/*.md
```
生成结果:`changelogs/cn.md`、`en.md`、`tw.md`、`ja.md`(全量幂等,每次重写)。
## 5. 在当前仓库创建发布提交
1. 提交文件必须包含:
- `package.json`
- `changelogs/cn.json`、`en.json`、`tw.json`、`ja.json`
- `changelogs/cn.md`、`en.md`、`tw.md`、`ja.md`
2. commit message:`release: v<version>`(示例:`release: v0.9.6`)。
3. 仅创建 commit,不 push。
可复用脚本:`scripts/commit_release_changelogs.sh`
## 6. 输出结果
输出以下信息给用户:
1. 当前版本号。
2. 当前仓库 release commit hash。
3. 明确声明"未执行 push"。
## 参考
- `references/english-release-style.md`
- `references/traditional-chinese-release-style.md`
- `references/japanese-release-style.md`
- `scripts/preflight_main_clean.sh`
- `scripts/commit_release_changelogs.sh`
- `scripts/changelog-to-markdown.mjs`
-4
View File
@@ -1,4 +0,0 @@
interface:
display_name: '同步版本日志'
short_description: '生成英/繁中/日文 changelog 并创建 release 提交(不推送)'
default_prompt: 'Use $sync-changelog to turn the latest Chinese changelog entry into natural English, Traditional Chinese, and Japanese release notes, and commit all localized changelog files in this repo.'
@@ -1,15 +0,0 @@
# English Release Style
将中文版本日志转成英文时,遵循以下风格:
1. 面向英文母语用户,自然表达,不逐字翻译。
2. summary 控制在 1 句,简洁清晰,突出用户可感知变化。
3. items 使用短句,动词开头优先(例如:"Improve...", "Fix...", "Add...")。
4. 保留技术准确性,不夸大功能,不引入原文没有的信息。
5. 保留原分类结构(feat/fix/docs/chore 等),仅改写文本。
## 示例(仅风格参考)
中文:"优化 AI 对话底部配置状态展示"
推荐英文:"Improve the configuration status display in the AI chat footer."
@@ -1,33 +0,0 @@
# japanese-release-style
用于将 `changelogs/cn.json` 当前版本条目改写为日文版本。
## 目标
- 面向日本用户,写成自然的产品更新说明
- 避免中文式表达和逐字直译
- 保持简洁、可信、易扫读
## 规则
1. 保留原有结构:
- `summary`
- `changes[].type`
- `changes[].items[]`
2. `summary` 使用简短版本概述,不写成长段解释
3. `changes.items` 每条只写一个变化点
4. 语气以产品 release notes 为准:
- 简洁
- 说明明确
- 不夸张宣传
5. 优先使用常见 UI / 产品文案表达,避免:
- 中文语序
- 生硬片假名堆砌
- “〜を実現しました” 一类过度宣传句式
6. 可以适度意译,但不能新增原文没有的承诺或结论
## 自检
- 是否像日本软件产品的更新说明
- 是否比中文直译更自然
- 是否忠实保留原始改动
@@ -1,31 +0,0 @@
# traditional-chinese-release-style
用于将 `changelogs/cn.json` 当前版本条目改写为繁体中文版本。
## 目标
- 面向繁体中文用户,优先采用台湾常见产品文案口吻
- 比简体原文更顺口,但不改变事实
- 保持 release notes 风格:短句、直白、便于扫读
## 规则
1. 不做简体直接替换,要根据语境重写
2. 保留原有结构:
- `summary`
- `changes[].type`
- `changes[].items[]`
3. `summary` 要像版本摘要,不要写成长段说明
4. `changes.items` 每条只表达一个改动点
5. 使用常见繁体产品词汇,例如:
- 配置 -> 設定
- 查看 -> 檢視
- 生成 -> 產生
- 返回 -> 返回上一頁 / 回到...
6. 避免中国大陆口语化表达、生硬技术直译、过长句子
## 自检
- 是否读起来像台湾产品更新说明
- 是否保留了原始改动含义
- 是否比简体更简洁顺口
@@ -1,60 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# 在当前项目提交多语言 changelog,提交信息为 release: v<version>
# 用法:commit_release_changelogs.sh <repo_path>
REPO_PATH="${1:-}"
if [[ -z "$REPO_PATH" ]]; then
echo "错误: 缺少仓库路径参数" >&2
exit 1
fi
CN_FILE="$REPO_PATH/changelogs/cn.json"
EN_FILE="$REPO_PATH/changelogs/en.json"
TW_FILE="$REPO_PATH/changelogs/tw.json"
JA_FILE="$REPO_PATH/changelogs/ja.json"
CN_MD="$REPO_PATH/changelogs/cn.md"
EN_MD="$REPO_PATH/changelogs/en.md"
TW_MD="$REPO_PATH/changelogs/tw.md"
JA_MD="$REPO_PATH/changelogs/ja.md"
PKG_FILE="$REPO_PATH/package.json"
if [[ ! -f "$CN_FILE" || ! -f "$EN_FILE" || ! -f "$TW_FILE" || ! -f "$JA_FILE" || ! -f "$PKG_FILE" ]]; then
echo "错误: 多语言 changelog 或 package.json 不存在,无法提交" >&2
exit 1
fi
if [[ ! -f "$CN_MD" || ! -f "$EN_MD" || ! -f "$TW_MD" || ! -f "$JA_MD" ]]; then
echo "错误: Markdown 文件不完整,请先运行 node scripts/changelog-to-markdown.mjs" >&2
exit 1
fi
VERSION="$(node -e "const fs=require('fs');const arr=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));process.stdout.write(arr?.[0]?.version||'');" "$CN_FILE")"
if [[ -z "$VERSION" ]]; then
echo "错误: 无法从 $CN_FILE 读取当前版本" >&2
exit 1
fi
# 仅暂存发布必需文件,避免误提交其他改动。
# 注意:package.json 中的版本号需要和 release 提交一起落盘。
git -C "$REPO_PATH" add \
package.json \
changelogs/cn.json \
changelogs/en.json \
changelogs/tw.json \
changelogs/ja.json \
changelogs/cn.md \
changelogs/en.md \
changelogs/tw.md \
changelogs/ja.md
# 若没有差异则不提交,避免空提交失败。
if git -C "$REPO_PATH" diff --cached --quiet; then
echo "错误: 没有可提交的 changelog 变更" >&2
exit 1
fi
MSG="release: v${VERSION}"
git -C "$REPO_PATH" commit -m "$MSG" >/dev/null
git -C "$REPO_PATH" rev-parse --short HEAD
@@ -1,61 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# 检查指定仓库是否干净,并确保位于 main 分支。
# 用法:preflight_main_clean.sh <repo_path> [allowlist_csv]
REPO_PATH="${1:-}"
ALLOWLIST_CSV="${2:-}"
if [[ -z "$REPO_PATH" ]]; then
echo "错误: 缺少仓库路径参数" >&2
exit 1
fi
if [[ ! -d "$REPO_PATH/.git" ]]; then
echo "错误: $REPO_PATH 不是 git 仓库" >&2
exit 1
fi
# 支持白名单:仅允许白名单内文件有改动,其他改动一律报错退出。
STATUS_OUTPUT="$(git -C "$REPO_PATH" status --porcelain)"
if [[ -n "$STATUS_OUTPUT" ]]; then
if [[ -z "$ALLOWLIST_CSV" ]]; then
echo "错误: $REPO_PATH 存在未提交或已暂存改动,请手动处理后重试" >&2
exit 1
fi
ALLOWLIST_NL=""
IFS=',' read -ra ALLOW_PATHS <<<"$ALLOWLIST_CSV"
for allowed in "${ALLOW_PATHS[@]}"; do
# 清理参数中可能出现的空格,避免调用时误传格式。
cleaned="$(echo "$allowed" | xargs)"
if [[ -n "$cleaned" ]]; then
ALLOWLIST_NL+="$cleaned"$'\n'
fi
done
# 遍历所有改动路径,存在任意非白名单路径则失败。
while IFS= read -r line; do
path="${line:3}"
if [[ "$path" == *" -> "* ]]; then
path="${path##* -> }"
fi
if ! printf '%s' "$ALLOWLIST_NL" | grep -Fxq "$path"; then
echo "错误: $REPO_PATH 存在白名单外改动: $path" >&2
exit 1
fi
done <<<"$STATUS_OUTPUT"
fi
CURRENT_BRANCH="$(git -C "$REPO_PATH" rev-parse --abbrev-ref HEAD)"
if [[ "$CURRENT_BRANCH" != "main" ]]; then
# 仅在工作区干净时允许切换到 main。
git -C "$REPO_PATH" checkout main >/dev/null
fi
FINAL_BRANCH="$(git -C "$REPO_PATH" rev-parse --abbrev-ref HEAD)"
if [[ "$FINAL_BRANCH" != "main" ]]; then
echo "错误: 无法切换到 main 分支" >&2
exit 1
fi
echo "ok: $REPO_PATH on main and clean"