create-dwy 0.13.1 → 0.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/bin/index.js +18 -0
- package/package.json +6 -2
- package/src/sync-all.js +154 -0
- package/src/sync-codex.js +27 -8
- package/src/sync.js +25 -8
- package/templates/claude-global/hooks/Git/pre-git-commit-backtick-check.sh +76 -0
- package/templates/claude-global/hooks/Git/pre-git-commit-sensitive-check.sh +23 -27
- package/templates/claude-global/rules/iOS/dwy-swift-style.md +96 -0
- package/templates/claude-global/rules//345/274/200/345/217/221/346/265/201/347/250/213/dwy-git-commit-safe.md +66 -0
- package/templates/claude-global/settings.json +4 -0
- package/templates/claude-global/skills//345/205/203/345/267/245/345/205/267/dwy-claude-code-features/scripts/lint.py +0 -0
- package/templates/claude-global/skills//345/205/203/345/267/245/345/205/267/dwy-claude-code-features/scripts/refresh_docs.py +0 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/SKILL.md +225 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates/README.md +55 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//344/270/252/344/272/272/346/204/237/346/202/237.md +21 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//345/267/245/345/205/267/350/265/204/346/272/220/345/256/211/345/210/251.md +26 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//346/212/200/346/234/257/346/225/231/347/250/213.md +46 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//346/226/271/346/241/210/351/200/211/345/236/213/345/257/271/346/257/224.md +28 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//346/246/202/345/277/265/347/247/221/346/231/256.md +28 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//350/241/214/344/270/232/350/247/202/345/257/237/350/257/204/350/256/272.md +21 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//350/270/251/345/235/221/346/216/222/351/224/231/345/256/236/345/275/225.md +28 -0
- package/templates/claude-global/skills//345/206/205/345/256/271/345/210/233/344/275/234/dwy-article/templates//351/241/271/347/233/256/345/244/215/347/233/230.md +26 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/SKILL.md +4 -2
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/check_comments.py +0 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/check_js_publish.sh +0 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/check_python_publish.sh +0 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/detect_sdk.sh +0 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/init_config.sh +0 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-0to1/SKILL.md +113 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-0to1/templates/STATE.md +56 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-market-analysis/SKILL.md +92 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-prd-coarse/SKILL.md +72 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-prd-coarse/templates/prd-coarse.md +61 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-prd-detailed/SKILL.md +76 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-prd-detailed/templates/prd-detailed.md +119 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-prototype/SKILL.md +104 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-spike/SKILL.md +81 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-tdd-dev/SKILL.md +212 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-tdd-dev/templates/impl-plan.md +115 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-tech-feasibility/SKILL.md +105 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-version-plan/SKILL.md +64 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-version-plan/templates/version-plan.md +72 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-cibuildwheel/SKILL.md +3 -1
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_base.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_capacity.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_db.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_docker.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_env.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_https.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_logs.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_nginx.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_resilience.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_secrets.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_services.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/check_ssh.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-deploy-audit/scripts/run_all.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker/scripts/query_dockerhub.py +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-docker/scripts/scan_images.sh +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source/scripts/apply_mirrors.py +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-mirror-source/scripts/check_mirrors.py +0 -0
- package/templates/claude-global/skills//350/277/220/347/273/264/345/217/221/345/270/203/dwy-publish/SKILL.md +8 -0
- package/templates/codex-global/hooks/Git/pre-git-commit-backtick-check.sh +75 -0
- package/templates/codex-global/hooks/Git/pre-git-commit-sensitive-check.sh +1 -1
- package/templates/codex-global/hooks.json +5 -0
- package/templates/claude-global/skills//346/225/260/346/215/256/345/272/223/dwy-dolphindb/scripts/__pycache__/scrape_docs.cpython-311.pyc +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-version-plan
|
|
3
|
+
description: 产品版本规划:基于细 PRD 把产品切成可交付版本(v1 最小闭环 → v2 → v3…),每版写包含功能、依赖、可验证的验收标准,按价值增量切不按技术层切。涉及以下场景使用此 skill(即使没点名 'dwy-version-plan'):用户说『帮我规划版本/迭代』『这个产品先做哪些功能、怎么分版本』『切个 v1 最小可用版本』『排个版本路线』。区分:本 skill 切版本+定验收;具体某版本的 TDD 实现用 dwy-tdd-dev;完整 0→1 流水线用 dwy-0to1。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dwy-version-plan · 版本规划
|
|
7
|
+
|
|
8
|
+
基于细 PRD 把产品切成若干可交付版本:v1 最小可用闭环 → v2 → v3…,每个版本是一个能独立交付的增量。
|
|
9
|
+
|
|
10
|
+
## 运行模式
|
|
11
|
+
|
|
12
|
+
上下文自适应,两种调用方式:
|
|
13
|
+
|
|
14
|
+
- **单独调用(默认)**:用户直接让你规划版本。从用户给的 PRD/功能清单或描述起步;产物落 `./version-plan.md` 或用户指定位置;**不读写 STATE.md、不依赖 `docs/0to1/`**。做完跑下方「门」即结束。
|
|
15
|
+
- **流水线调用**:`dwy-0to1` 调用,指令含「流水线模式」+ 前序产物路径(细 PRD)+ 落盘路径(如 `docs/0to1/06-version-plan.md`)。**STATE 记账(含选定版本、版本进度表)由 dwy-0to1 负责,本 skill 不碰 STATE.md**。
|
|
16
|
+
|
|
17
|
+
## 输入(切版本的依据)
|
|
18
|
+
|
|
19
|
+
- **细 PRD 是切版本的唯一依据**:每个版本包含哪些功能,必须能映射回 PRD 的具体页面 / 功能,不能凭空加。
|
|
20
|
+
- 看目标端和产品定位,版本节奏按端和定位定。
|
|
21
|
+
- 单独模式:用户没给细 PRD 就先问清有哪些功能/页面、核心价值是什么,再切。
|
|
22
|
+
|
|
23
|
+
## 怎么做(具体步骤)
|
|
24
|
+
|
|
25
|
+
套 `templates/version-plan.md`,按下面思路切:
|
|
26
|
+
|
|
27
|
+
0. **先勾勒全局数据模型 + 架构骨架(跨版本一次性)** — 切版本前先定核心实体、实体间关系、2-3 句架构方向(分层 / 存储 / 关键边界)。这是所有版本共用的地基,先定好才能避免 v1 把表结构 / 架构画死、v2 被迫 DB 迁移。轻量草图即可,不下到字段类型级(那是 Step9 实施计划的事)。
|
|
28
|
+
1. **找 v1 最小闭环** — 从 PRD 里挑出「能跑通核心价值的最小一条路径」。用户能完整走完一次主流程、拿到核心价值,就是 v1。砍掉一切锦上添花。
|
|
29
|
+
- ✅ 笔记 App v1 = 新建 / 编辑 / 列表 / 删除,一条闭环
|
|
30
|
+
- ❌ v1 塞进多端同步、协作、AI 摘要、主题皮肤——这些进 v2+
|
|
31
|
+
2. **后续版本按价值增量切** — v2、v3 每个加一组**能独立交付**的功能。不要按技术层切(「v1 做后端、v2 做前端」是错的,那不是可交付增量)。
|
|
32
|
+
3. **大胆切大版本** — AI 写代码效率高,单版本可以比传统排期装更多。判据是「这一版能不能独立交付、独立验收」,不是「工时够不够一个 sprint」。能合并成一个能交付的闭环就别拆碎。
|
|
33
|
+
4. **写清依赖** — 哪个版本依赖前序版本的产物 / 数据结构。一般 v2 依赖 v1,但要显式写出来依赖的是什么(如「v2 的搜索依赖 v1 已落地的笔记表结构」)。
|
|
34
|
+
5. **每版写验收标准** — 这一版做完,怎么算「真的做完了」。要可验证:列出用户能完成的动作 + 可观测的结果,开发的完成前验证就照这个核对。
|
|
35
|
+
|
|
36
|
+
每个版本一节,写全:**目标(一句话)/ 包含功能(对应 PRD 哪些页面 / 功能)/ 依赖前序版本 / 验收标准**。
|
|
37
|
+
|
|
38
|
+
## 产物
|
|
39
|
+
|
|
40
|
+
落盘版本规划(单独默认 `./version-plan.md`;流水线按编排器给的路径)。套 `templates/version-plan.md`(含版本总览 + 每版本一节 + 一个填好的示例)。frontmatter:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
---
|
|
44
|
+
status: done
|
|
45
|
+
updated: <date +%Y-%m-%d>
|
|
46
|
+
---
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
成稿要件:全局数据模型 / 架构骨架已勾勒;每个版本的「包含功能」都能映射回细 PRD 的具体页面 / 功能;v1 是最小可用闭环;依赖关系写清;每版有可验证的验收标准。落盘后核对:把版本里列的功能逐条回查细 PRD,确认没有 PRD 里没有的功能、也没把核心闭环拆散到多个版本,再声称完成(先验证再声称)。
|
|
50
|
+
|
|
51
|
+
## 门(过门确认)
|
|
52
|
+
|
|
53
|
+
用 `AskUserQuestion` 把版本建议摆给用户:
|
|
54
|
+
- 摆什么:各版本一句话目标 + 包含的主要功能 + 依赖关系(建议方案)。
|
|
55
|
+
- 问什么:「**这次做哪几个版本?(可多选)**」选项给 v1 / v2 / v3… 让用户勾选要一起做的版本,外加「调整切法」。
|
|
56
|
+
|
|
57
|
+
用户选定后,要改切法就改,直到确认。
|
|
58
|
+
|
|
59
|
+
## 边界 / 禁止
|
|
60
|
+
|
|
61
|
+
- **禁止脱离细 PRD 凭空加功能**——版本里每个功能都要能指回 PRD 某页 / 某功能。
|
|
62
|
+
- **禁止按技术层切版本**(后端版 / 前端版)——每个版本必须是能独立交付、独立验收的增量。
|
|
63
|
+
- **禁止把核心闭环拆碎**——v1 必须自己就能跑通核心价值,不能「v1 只有界面没逻辑」。
|
|
64
|
+
- **禁止漏依赖和验收标准**——每版都要写清依赖什么、怎么算做完。
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
status: draft # draft | done
|
|
3
|
+
updated: <YYYY-MM-DD>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# <产品名> · 版本规划
|
|
7
|
+
|
|
8
|
+
> 基于细 PRD 把产品切成可交付版本。v1 = 最小可用闭环,往后每版是能独立交付、独立验收的增量。每个版本的功能都要能映射回细 PRD 的具体页面 / 功能。
|
|
9
|
+
|
|
10
|
+
## 全局数据模型 / 架构骨架
|
|
11
|
+
|
|
12
|
+
> 跨版本一次性定的地基,避免 v1 把结构画死、v2 被迫迁移。轻量草图,不下到字段类型级。
|
|
13
|
+
|
|
14
|
+
- **核心实体**:<实体 A、实体 B…,各一句话职责>
|
|
15
|
+
- **实体关系**:<A 1:N B、B M:N C… 关键关系>
|
|
16
|
+
- **架构方向**:<2-3 句:分层 / 存储选型 / 关键边界,如「前端 SPA + REST 后端 + Postgres;鉴权走 JWT;文件走对象存储」>
|
|
17
|
+
|
|
18
|
+
## 版本总览
|
|
19
|
+
|
|
20
|
+
| 版本 | 一句话目标 | 依赖 |
|
|
21
|
+
|------|-----------|------|
|
|
22
|
+
| v1 | <最小可用闭环目标> | 无 |
|
|
23
|
+
| v2 | <在 v1 上加的价值增量> | v1 |
|
|
24
|
+
| v3 | <下一个增量> | v2 |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 示例(填好的样板,照这个颗粒度写每一版)
|
|
29
|
+
|
|
30
|
+
### v1:能写能看的笔记闭环
|
|
31
|
+
|
|
32
|
+
- **目标**:用户能新建、编辑、查看、删除笔记,一条完整可用闭环。
|
|
33
|
+
- **包含功能**(对应细 PRD 页面 / 功能):
|
|
34
|
+
- 笔记列表页(PRD 页面 1):列表展示、空态、下拉刷新
|
|
35
|
+
- 新建 / 编辑页(PRD 页面 2):标题 + 正文输入(含前后端长度上限)、保存
|
|
36
|
+
- 删除(PRD 页面 1 的滑动删除 + 二次确认)
|
|
37
|
+
- **依赖前序版本**:无(首版)。
|
|
38
|
+
- **验收标准**:
|
|
39
|
+
- [ ] 新建一条笔记 → 列表出现该笔记
|
|
40
|
+
- [ ] 编辑后 → 列表与详情内容同步更新
|
|
41
|
+
- [ ] 删除 + 确认 → 列表移除该笔记
|
|
42
|
+
- [ ] 正文超 5000 字 → 前端截断 + 提示,后端拒绝返回 422
|
|
43
|
+
- [ ] 全量测试通过、构建 exit 0
|
|
44
|
+
|
|
45
|
+
### v2:搜索 + 标签
|
|
46
|
+
|
|
47
|
+
- **目标**:笔记多起来后能快速找到。
|
|
48
|
+
- **包含功能**(对应细 PRD 页面 / 功能):
|
|
49
|
+
- 搜索页(PRD 页面 3):关键词搜索、结果高亮、零结果态
|
|
50
|
+
- 标签(PRD 页面 2 的标签选择 + 页面 1 的标签筛选)
|
|
51
|
+
- **依赖前序版本**:v1(依赖 v1 已落地的笔记表结构与列表页)。
|
|
52
|
+
- **验收标准**:
|
|
53
|
+
- [ ] 输入关键词 → 匹配的笔记按相关度返回,命中词高亮
|
|
54
|
+
- [ ] 无匹配 → 显示零结果态文案
|
|
55
|
+
- [ ] 给笔记打标签 → 列表可按标签筛选
|
|
56
|
+
- [ ] 全量测试通过、构建 exit 0
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 空白版本模板(每个真实版本复制一份填)
|
|
61
|
+
|
|
62
|
+
### vN:<版本名>
|
|
63
|
+
|
|
64
|
+
- **目标**:<一句话,这一版让用户能完成什么>
|
|
65
|
+
- **包含功能**(对应细 PRD 页面 / 功能):
|
|
66
|
+
- <功能 A>(PRD 页面 X)
|
|
67
|
+
- <功能 B>(PRD 页面 Y)
|
|
68
|
+
- **依赖前序版本**:<无 / vM,依赖 vM 的什么产物或数据结构>
|
|
69
|
+
- **验收标准**(可验证、对得上「用户能完成的动作 + 可观测结果」):
|
|
70
|
+
- [ ] <动作 → 可观测结果>
|
|
71
|
+
- [ ] <用户输入的长度上限边界 → 预期行为>
|
|
72
|
+
- [ ] 全量测试通过、构建 exit 0
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dwy-cibuildwheel
|
|
3
|
-
description: "
|
|
3
|
+
description: "用 GitHub Actions + cibuildwheel 把【含 C 扩展 / Cython / .so 编译产物】的 Python 包跨平台 build wheel(linux/macos/windows × x86_64/arm64)并通过 PyPI Trusted Publisher (OIDC) 发布到 PyPI 的避坑指南。仅适用于需要编译 .so 的包;纯 Python 包发 PyPI 不需要本 skill(走 dwy-publish + dwy-sdk-spec)。涵盖 PEP 639 license / cibuildwheel 版本 tag / YAML 冒号转义 / {package} 占位符 / 跨平台 shell 引号 / manylinux 镜像 / 测试阶段 binary 强制 / GitHub runner image 退役(macos-13 已死)等 8 类高频坑。触发条件:编辑或新建含 cibuildwheel 的 .github/workflows/*.yml、pyproject.toml 含 Cython / ext_modules、用户说 'cibuildwheel' / 'build wheel' / '跨平台 wheel' / '.so 跨平台打包' / 'wheel build 失败' / 'macos runner 一直 queued',或要把含 C 扩展的 Python 包发 PyPI 时。"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# dwy-cibuildwheel — Python Cython SDK 跨平台 PyPI 发布避坑
|
|
7
7
|
|
|
8
8
|
适用场景:含 Cython 编译扩展的 Python 包、跨平台 wheel 分发(linux x86_64/aarch64 + macos x86_64/arm64 + windows AMD64)、GitHub Actions + cibuildwheel + PyPI Trusted Publisher OIDC 发版。
|
|
9
9
|
|
|
10
|
+
> 定位:本 skill 只解决「含 C 扩展的包怎么用 GitHub Actions 跨平台打 wheel 发 PyPI」的 CI 避坑。通用发版流程(测试 / bump / changelog / tag)走 `dwy-publish`;发布前接口脱敏 / 源码泄露 / 产物审计走 `dwy-sdk-spec`;纯 Python 包不需要本 skill。
|
|
11
|
+
|
|
10
12
|
**实战来源**:quant-sdk (quantzone) 0.4.0 首发到 PyPI 过程中暴露的 8 类坑,全部沉淀于此。
|
|
11
13
|
|
|
12
14
|
---
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -46,6 +46,14 @@ description: "发布版本:测试 → bump → changelog → build → publish
|
|
|
46
46
|
- 工具:changelogen
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
## 发版前置检查(按项目类型)
|
|
50
|
+
|
|
51
|
+
正式发版前,先按项目类型过对应的前置 skill:
|
|
52
|
+
|
|
53
|
+
- **SDK 类项目(对外发布的库 / SDK,不限 PyPI / npm / 私有源)** → 先用 `dwy-sdk-spec` 做发布安全检查(接口注释脱敏、商业版源码保护、发布产物审计),通过后再发版。
|
|
54
|
+
- **含 C 扩展 / Cython / .so、需跨平台 wheel** → 用 `dwy-cibuildwheel` 配 GitHub Actions + cibuildwheel 打跨平台 wheel 发 PyPI(此时下方第 4、6 步的 build / publish 由 CI workflow 承担)。
|
|
55
|
+
- **版本号该升哪一位拿不准** → 用 `dwy-semver` 决策(见下方第 2 步)。
|
|
56
|
+
|
|
49
57
|
## 发版前确认
|
|
50
58
|
|
|
51
59
|
询问用户:
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Codex PreToolUse Hook
|
|
3
|
+
# 拦截 git commit message 中会被 shell 命令替换的反引号 / $(...)
|
|
4
|
+
#
|
|
5
|
+
# 背景:AI 生成的 commit message 爱用 Markdown 风格反引号包代码标识符,
|
|
6
|
+
# git commit -m "fix: support `bun install` on windows"
|
|
7
|
+
# 经 shell 执行时,双引号内的 `bun install` 会被当成命令替换 $(bun install) 实际执行,
|
|
8
|
+
# 输出塞进 message,甚至误执行破坏性命令导致丢代码。
|
|
9
|
+
# 单引号内 '...`...`...' 不展开,安全。
|
|
10
|
+
# 安全写法:git commit -F <file> / --file=- / 单引号。
|
|
11
|
+
# Codex 与 Claude Code 同样通过 stdin 传 JSON,从 .tool_input.command 取命令
|
|
12
|
+
|
|
13
|
+
# 从 stdin 读 JSON 取待执行命令
|
|
14
|
+
CMD=$(python3 -c 'import sys,json; print(json.load(sys.stdin).get("tool_input",{}).get("command",""))')
|
|
15
|
+
|
|
16
|
+
# 只在含 git commit 的命令上检查
|
|
17
|
+
printf '%s' "$CMD" | grep -q 'git commit' || exit 0
|
|
18
|
+
|
|
19
|
+
# 逐字符做轻量 shell 词法扫描:跟踪引号状态,
|
|
20
|
+
# 只在「非单引号上下文」里出现裸反引号或 $( 时判危险(这些会被 shell 求值)。
|
|
21
|
+
# 命令经环境变量传入(stdin 已被 heredoc 脚本占用,不能再走管道)。
|
|
22
|
+
DANGER=$(CMD="$CMD" python3 <<'PY'
|
|
23
|
+
import os
|
|
24
|
+
|
|
25
|
+
s = os.environ.get("CMD", "")
|
|
26
|
+
in_single = False # 单引号内:所有字符字面,反引号安全
|
|
27
|
+
in_double = False # 双引号内:反引号 / $() 仍会命令替换
|
|
28
|
+
i, n = 0, len(s)
|
|
29
|
+
danger = False
|
|
30
|
+
|
|
31
|
+
while i < n:
|
|
32
|
+
c = s[i]
|
|
33
|
+
if c == '\\' and not in_single:
|
|
34
|
+
i += 2
|
|
35
|
+
continue
|
|
36
|
+
if c == "'" and not in_double:
|
|
37
|
+
in_single = not in_single
|
|
38
|
+
i += 1
|
|
39
|
+
continue
|
|
40
|
+
if c == '"' and not in_single:
|
|
41
|
+
in_double = not in_double
|
|
42
|
+
i += 1
|
|
43
|
+
continue
|
|
44
|
+
if not in_single:
|
|
45
|
+
if c == '`':
|
|
46
|
+
danger = True
|
|
47
|
+
break
|
|
48
|
+
if c == '$' and i + 1 < n and s[i + 1] == '(':
|
|
49
|
+
danger = True
|
|
50
|
+
break
|
|
51
|
+
i += 1
|
|
52
|
+
|
|
53
|
+
print("DANGER" if danger else "OK")
|
|
54
|
+
PY
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
[ "$DANGER" = "DANGER" ] || exit 0
|
|
58
|
+
|
|
59
|
+
echo "========================================"
|
|
60
|
+
echo " WARNING: 危险的 commit message 写法"
|
|
61
|
+
echo "========================================"
|
|
62
|
+
echo ""
|
|
63
|
+
echo "检测到 git commit message 中含会被 shell 命令替换的反引号 \` 或 \$(...)。"
|
|
64
|
+
echo "双引号内的 \`...\` 会被当成命令替换实际执行,可能误执行命令甚至丢代码。"
|
|
65
|
+
echo ""
|
|
66
|
+
echo "改用以下任一安全写法:"
|
|
67
|
+
echo " 1. 文件提交(推荐多行 / 含特殊字符):"
|
|
68
|
+
echo " git commit -F <msg-file>"
|
|
69
|
+
echo " printf '%s\\n' \"\$MSG\" | git commit --file=-"
|
|
70
|
+
echo " 2. 单引号包裹(单引号内反引号不展开):"
|
|
71
|
+
echo " git commit -m 'fix: support \`bun install\` on windows'"
|
|
72
|
+
echo " 3. 转义反引号:"
|
|
73
|
+
echo " git commit -m \"fix: support \\\`bun install\\\` on windows\""
|
|
74
|
+
echo "========================================"
|
|
75
|
+
exit 2 # 暂停等待人工审批
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Codex PreToolUse Hook
|
|
3
3
|
# 在 git commit 前检查暂存文件中是否包含敏感数据
|
|
4
|
-
# 与 Claude
|
|
4
|
+
# Codex 与 Claude Code 同样通过 stdin 传 JSON,从 .tool_input.command 取命令
|
|
5
5
|
|
|
6
6
|
# 从 stdin 读 JSON 并取出待执行命令
|
|
7
7
|
CMD=$(python3 -c 'import sys,json; print(json.load(sys.stdin).get("tool_input",{}).get("command",""))')
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
"type": "command",
|
|
9
9
|
"command": "bash \"$(git rev-parse --show-toplevel)\"/.codex/hooks/pre-git-commit-sensitive-check.sh",
|
|
10
10
|
"timeout": 30
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "command",
|
|
14
|
+
"command": "bash \"$(git rev-parse --show-toplevel)\"/.codex/hooks/pre-git-commit-backtick-check.sh",
|
|
15
|
+
"timeout": 30
|
|
11
16
|
}
|
|
12
17
|
]
|
|
13
18
|
}
|