From 093fdd1f2d994572413f003b6b16e07906c55309 Mon Sep 17 00:00:00 2001 From: digua Date: Sun, 7 Jun 2026 14:38:50 +0800 Subject: [PATCH] chore(skills): remove maintainer skills from public repo --- skills/generate-assistant-config/SKILL.md | 225 ------------------ .../agents/openai.yaml | 4 - skills/generate-changelog/SKILL.md | 175 -------------- skills/generate-changelog/agents/openai.yaml | 4 - .../references/changelog-format.md | 30 --- .../scripts/extract_commits_for_changelog.sh | 62 ----- .../scripts/format_changelog.sh | 22 -- skills/sync-changelog/SKILL.md | 94 -------- skills/sync-changelog/agents/openai.yaml | 4 - .../references/english-release-style.md | 15 -- .../references/japanese-release-style.md | 33 --- .../traditional-chinese-release-style.md | 31 --- .../scripts/commit_release_changelogs.sh | 60 ----- .../scripts/preflight_main_clean.sh | 61 ----- 14 files changed, 820 deletions(-) delete mode 100644 skills/generate-assistant-config/SKILL.md delete mode 100644 skills/generate-assistant-config/agents/openai.yaml delete mode 100644 skills/generate-changelog/SKILL.md delete mode 100644 skills/generate-changelog/agents/openai.yaml delete mode 100644 skills/generate-changelog/references/changelog-format.md delete mode 100755 skills/generate-changelog/scripts/extract_commits_for_changelog.sh delete mode 100755 skills/generate-changelog/scripts/format_changelog.sh delete mode 100644 skills/sync-changelog/SKILL.md delete mode 100644 skills/sync-changelog/agents/openai.yaml delete mode 100644 skills/sync-changelog/references/english-release-style.md delete mode 100644 skills/sync-changelog/references/japanese-release-style.md delete mode 100644 skills/sync-changelog/references/traditional-chinese-release-style.md delete mode 100755 skills/sync-changelog/scripts/commit_release_changelogs.sh delete mode 100755 skills/sync-changelog/scripts/preflight_main_clean.sh diff --git a/skills/generate-assistant-config/SKILL.md b/skills/generate-assistant-config/SKILL.md deleted file mode 100644 index f471e59a..00000000 --- a/skills/generate-assistant-config/SKILL.md +++ /dev/null @@ -1,225 +0,0 @@ ---- -name: generate-assistant-config -description: Use when 用户希望根据一句自然语言需求创建新的 ChatLab assistant 配置、assistant Markdown、分析助手模板,或需要为群聊/私聊场景整理可写入 assistant//.md 的多语言助手文件。 ---- - -# generate-assistant-config - -为 ChatLab 生成 assistant Markdown。先动态追问补齐关键信息,只输出中文预览;用户确认后,再生成 `zh / en / ja` 三份本地化版本并写入 `assistant/`。 - -## 使用前先确认 - -- `skills/` 是开发代理技能目录;本技能自身放这里 -- `assistant/` 是 assistant Markdown 产物目录;最终 assistant 文件写这里 -- 当前仓库里的 `assistant/*.md` 可视为历史参考样例;新生成的多语言 assistant 写入 `assistant//` -- 当前项目 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//.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/.md` - - `assistant/en/.md` - - `assistant/ja/.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`(核心工具始终可用,不需要列出) -- 多语言版本仅做逐字翻译,导致预设问题和语气不自然 -- 发现同名文件已存在,却直接覆盖 diff --git a/skills/generate-assistant-config/agents/openai.yaml b/skills/generate-assistant-config/agents/openai.yaml deleted file mode 100644 index 9dd8c4fb..00000000 --- a/skills/generate-assistant-config/agents/openai.yaml +++ /dev/null @@ -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//.md without overwriting existing files.' diff --git a/skills/generate-changelog/SKILL.md b/skills/generate-changelog/SKILL.md deleted file mode 100644 index b2b76933..00000000 --- a/skills/generate-changelog/SKILL.md +++ /dev/null @@ -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' -``` - -必要时读取正文: - -```bash -git show -s --format='%B' -``` - -## 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` diff --git a/skills/generate-changelog/agents/openai.yaml b/skills/generate-changelog/agents/openai.yaml deleted file mode 100644 index fc05cf78..00000000 --- a/skills/generate-changelog/agents/openai.yaml +++ /dev/null @@ -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.' diff --git a/skills/generate-changelog/references/changelog-format.md b/skills/generate-changelog/references/changelog-format.md deleted file mode 100644 index 2bce1a89..00000000 --- a/skills/generate-changelog/references/changelog-format.md +++ /dev/null @@ -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】`;跨端共享或统一能力不加前缀。 -- 同一分类下先写通用/跨端变更,再写带端前缀的专属变更。 diff --git a/skills/generate-changelog/scripts/extract_commits_for_changelog.sh b/skills/generate-changelog/scripts/extract_commits_for_changelog.sh deleted file mode 100755 index 5e1f56bf..00000000 --- a/skills/generate-changelog/scripts/extract_commits_for_changelog.sh +++ /dev/null @@ -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" diff --git a/skills/generate-changelog/scripts/format_changelog.sh b/skills/generate-changelog/scripts/format_changelog.sh deleted file mode 100755 index b4284af8..00000000 --- a/skills/generate-changelog/scripts/format_changelog.sh +++ /dev/null @@ -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" diff --git a/skills/sync-changelog/SKILL.md b/skills/sync-changelog/SKILL.md deleted file mode 100644 index a3282458..00000000 --- a/skills/sync-changelog/SKILL.md +++ /dev/null @@ -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`(示例:`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` diff --git a/skills/sync-changelog/agents/openai.yaml b/skills/sync-changelog/agents/openai.yaml deleted file mode 100644 index fba2a972..00000000 --- a/skills/sync-changelog/agents/openai.yaml +++ /dev/null @@ -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.' diff --git a/skills/sync-changelog/references/english-release-style.md b/skills/sync-changelog/references/english-release-style.md deleted file mode 100644 index 4fa959c2..00000000 --- a/skills/sync-changelog/references/english-release-style.md +++ /dev/null @@ -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." diff --git a/skills/sync-changelog/references/japanese-release-style.md b/skills/sync-changelog/references/japanese-release-style.md deleted file mode 100644 index 32ec387d..00000000 --- a/skills/sync-changelog/references/japanese-release-style.md +++ /dev/null @@ -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. 可以适度意译,但不能新增原文没有的承诺或结论 - -## 自检 - -- 是否像日本软件产品的更新说明 -- 是否比中文直译更自然 -- 是否忠实保留原始改动 diff --git a/skills/sync-changelog/references/traditional-chinese-release-style.md b/skills/sync-changelog/references/traditional-chinese-release-style.md deleted file mode 100644 index e5a9f93c..00000000 --- a/skills/sync-changelog/references/traditional-chinese-release-style.md +++ /dev/null @@ -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. 避免中国大陆口语化表达、生硬技术直译、过长句子 - -## 自检 - -- 是否读起来像台湾产品更新说明 -- 是否保留了原始改动含义 -- 是否比简体更简洁顺口 diff --git a/skills/sync-changelog/scripts/commit_release_changelogs.sh b/skills/sync-changelog/scripts/commit_release_changelogs.sh deleted file mode 100755 index 6abf2d79..00000000 --- a/skills/sync-changelog/scripts/commit_release_changelogs.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# 在当前项目提交多语言 changelog,提交信息为 release: v -# 用法:commit_release_changelogs.sh -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 diff --git a/skills/sync-changelog/scripts/preflight_main_clean.sh b/skills/sync-changelog/scripts/preflight_main_clean.sh deleted file mode 100755 index 1b0eedbb..00000000 --- a/skills/sync-changelog/scripts/preflight_main_clean.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# 检查指定仓库是否干净,并确保位于 main 分支。 -# 用法:preflight_main_clean.sh [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"