create-dwy 0.25.2 → 0.26.0

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/package.json +1 -1
  3. package/src/sync-plan.js +1 -1
  4. package/src/sync.js +1 -0
  5. package/src/tab-multiselect.js +2 -2
  6. package/templates/ai-tools/CHANGELOG.md +10 -0
  7. package/templates/ai-tools/VERSION +1 -1
  8. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-commercial-sdk/SKILL.md +20 -0
  9. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-github-action-publish/SKILL.md +1 -1
  10. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/SKILL.md +6 -2
  11. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/android.md +2 -2
  12. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/backend-deploy.md +1 -1
  13. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/frontend-deploy.md +1 -1
  14. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/generic-release.md +2 -2
  15. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/harmony.md +2 -2
  16. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-publish/references/ios.md +2 -2
  17. package/templates/ai-tools/skills//351/200/232/347/224/250/dwy-dependency-choice/SKILL.md +2 -2
  18. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/SKILL.md +0 -244
  19. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/files-whitelist-snippet.json +0 -22
  20. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/js-commercial.npmignore +0 -76
  21. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/python-commercial-MANIFEST.in +0 -37
  22. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/assets/python-commercial.gitignore +0 -62
  23. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/js-commercial-guide.md +0 -133
  24. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/publish-blacklist.md +0 -106
  25. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/python-commercial-guide.md +0 -147
  26. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/references/sensitive-patterns.md +0 -112
  27. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/check_comments.py +0 -260
  28. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/check_js_publish.sh +0 -110
  29. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/check_python_publish.sh +0 -171
  30. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/detect_sdk.sh +0 -71
  31. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-sdk-spec/scripts/init_config.sh +0 -91
  32. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/SKILL.md +0 -136
  33. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/references/semver-spec.md +0 -70
  34. package/templates/ai-tools/skills//345/217/221/345/270/203/345/217/221/347/211/210/dwy-semver/scripts/bump.py +0 -137
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # create-dwy
2
2
 
3
+ ## [0.26.0] - 2026-11-06
4
+
5
+ ### Changed
6
+
7
+ - `dwy-publish` 独立判断发版版本,移除 `dwy-semver`;已有安装需改用 `dwy-publish`。
8
+ - `dwy-sdk-spec` 改为 `dwy-commercial-sdk`,依据项目实际商业 SDK 保护要求检查,不再缓存项目配置;已有安装需选择新 skill,旧入口需自行移除。
9
+ - 模板详情见 ai-tools 0.33.0。
10
+
11
+ ---
12
+
13
+ ## [0.25.3] - 2026-11-06
14
+
15
+ ### Patch Changes
16
+
17
+ - 修复项目中全局 Skills 禁选后,已启用分类 Tab 失去颜色区分的问题。包含项目已勾选或全局已启用 Skills 的非当前分类保持青色,当前分类保持青色底;禁选逻辑和可勾选项计数保持不变。
18
+ - 补充部分/全部全局覆盖状态以及真实交互输出的颜色回归。
19
+
20
+ ---
21
+
3
22
  ## [0.25.2] - 2026-11-06
4
23
 
5
24
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-dwy",
3
- "version": "0.25.2",
3
+ "version": "0.26.0",
4
4
  "description": "项目脚手架与多平台 AI 配置同步工具",
5
5
  "type": "module",
6
6
  "bin": {
package/src/sync-plan.js CHANGED
@@ -39,7 +39,7 @@ export async function projectSkillChoices(skills, platforms, { homeDir, codexHom
39
39
  const disabled = applicable.length > 0 && covered.length === applicable.length
40
40
  const missing = applicable.filter(platform => !covered.includes(platform))
41
41
  const status = disabled ? '全局已启用' : covered.length ? `${missing.map(p => PLATFORM_LABELS[p]).join('、')} 可安装到项目` : ''
42
- return { ...skill, disabled, label: status ? `${skill.name}(${status})` : skill.name,
42
+ return { ...skill, disabled, inherited: covered.length > 0, label: status ? `${skill.name}(${status})` : skill.name,
43
43
  description: [covered.length ? `全局已提供:${covered.map(p => PLATFORM_LABELS[p]).join('、')}` : '', skill.description].filter(Boolean).join(';') }
44
44
  }))
45
45
  }
package/src/sync.js CHANGED
@@ -198,6 +198,7 @@ export function buildCategoryTabs(items, type) {
198
198
  label: item.label || item.name,
199
199
  description: item.description,
200
200
  disabled: item.disabled,
201
+ inherited: item.inherited,
201
202
  type,
202
203
  })
203
204
  }
@@ -264,7 +264,7 @@ class TabMultiSelectPrompt extends Prompt {
264
264
  }
265
265
 
266
266
  /**
267
- * 画 Tab 栏。当前 Tab 反底;有勾选的其它 Tab 用青色,空的变暗。
267
+ * 当前 Tab 反底;项目已勾选或全局已启用的分类用青色,不把禁选状态当成未启用。
268
268
  *
269
269
  * @param {string[]} segments
270
270
  * @param {number} activeIndex
@@ -284,7 +284,7 @@ function renderTabBar(segments, activeIndex, win, tabs, selectedValues) {
284
284
  const { selected } = tabSelectionStats(tabs[i], set)
285
285
  if (i === activeIndex) {
286
286
  parts.push(styleText(['bgCyan', 'black'], ` ${text} `))
287
- } else if (selected > 0) {
287
+ } else if (selected > 0 || tabs[i].options.some(option => option.inherited)) {
288
288
  parts.push(styleText('cyan', text))
289
289
  } else {
290
290
  parts.push(styleText('dim', text))
@@ -52,6 +52,16 @@
52
52
 
53
53
  ---
54
54
 
55
+ ## 0.33.0 — 2026-11-06
56
+
57
+ ### Changed
58
+ - `skills/发布发版/dwy-publish`:内置发版版本决策,不再依赖 `dwy-semver`。
59
+ - `skills/发布发版/dwy-commercial-sdk`:替代 `dwy-sdk-spec`,按项目商业 SDK 的实际保护要求检查,不再使用项目配置缓存或强制指定编译方案。
60
+ - 迁移:发版版本判断改用 `dwy-publish`;商业 SDK 检查选择 `dwy-commercial-sdk`。已安装的旧 skill 不会自动删除,按需移除旧入口。
61
+
62
+ ### Removed
63
+ - `skills/发布发版/dwy-semver` 和 `skills/发布发版/dwy-sdk-spec` 及其专用脚本和模板。
64
+
55
65
  ## 0.32.0 — 2026-10-29
56
66
 
57
67
  ### Changed
@@ -1 +1 @@
1
- 0.32.0
1
+ 0.33.0
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: dwy-commercial-sdk
3
+ description: 商业 SDK 的接口、源码保护和交付产物检查。用户要求检查商业 SDK、商业 SDK 打包或检查其源码泄露风险时使用;不执行发布。
4
+ ---
5
+
6
+ # 商业 SDK 发布前检查
7
+
8
+ 本 skill 适用于有商业保密或源码保护要求的 SDK,覆盖公开仓库、私有源和直接交付等分发方式。发版编排按项目约定执行;本检查不自行发布。
9
+
10
+ ## 确定范围
11
+
12
+ 1. 根据用户要求、项目文档、许可证、仓库公开状态、包配置和实际分发渠道识别 SDK、公开内容和需要保护的部分。不能根据“商业”二字推断源码必须保密;证据不足时询问用户。保护要求和交付范围存在歧义时先确认,再进行依赖该判断的检查。
13
+ 2. 每次依据当前项目上下文判断,不创建或读取 `.dwy/sdk-spec/config.json`,也不修改用户的全局配置或凭据。
14
+
15
+ ## 检查
16
+
17
+ - 检查公开接口、文档、注释及示例是否包含不应公开的内部地址、凭据、个人信息或实现细节;结合上下文判断误报,不输出完整秘密。
18
+ - 按确认的保护目标检查源码仓库、构建配置和分发渠道是否一致。编译、混淆和压缩只能提高还原成本,不能保证源码或算法无法恢复;公开仓库中的代码无法靠发布包配置保密。不要固定要求 Cython、minify 或排除所有源码。
19
+ - 检查实际拟交付的包或文件清单,核对源码、source map、调试文件、环境配置、凭据、许可证和运行必需资源是否符合交付范围。使用项目现有构建和检查工具;明确区分已有产物检查与实际发布产物验证。构建或打包前检查脚本副作用,不执行发布。
20
+ - 对发现的问题给出位置、风险、依据和修复建议;区分已验证、未验证和受环境限制的项目。按用户授权修复并重新检查,不把检查通过表述为绝对安全。
@@ -7,7 +7,7 @@ description: "GitHub Actions 打包分发避坑指南。先判断场景,再读
7
7
 
8
8
  定位:使用 GitHub Actions 做跨平台构建、打包、发布时,先判定产物类型,再查对应配置避坑。
9
9
 
10
- 本 skill 只处理 CI 打包分发链路。通用发版流程(测试 / bump / changelog / tag)走 `dwy-publish`;SDK 发布前安全审计走 `dwy-sdk-spec`;纯 Python 包不需要 cibuildwheel。
10
+ 本 skill 只处理 CI 打包分发链路。通用发版流程(测试 / bump / changelog / tag)走 `dwy-publish`;纯 Python 包不需要 cibuildwheel。
11
11
 
12
12
  实战来源:
13
13
 
@@ -11,9 +11,9 @@ description: "Use when 用户要求整理工程版本、更新 changelog、打
11
11
 
12
12
  1. 读取仓库指令、结构、构建配置、版本来源、changelog、Git 状态和历史 tag,识别独立工程及共享版本边界。依据实际依赖判断共享代码影响;不要把每个子目录当成独立工程。优先遵循用户指定范围,分不清边界时询问。
13
13
  2. 逐工程列出变更、版本来源、changelog 路径、tag 命名、版本类型、是否需要发布和 tag 触发器。检查上次对应 tag 后的提交及本次相关的未提交变更;不要把不属于本次的改动纳入提交。
14
- 3. 对本次需要更新的工程,按 `../dwy-semver` 确定版本级别、beta/rc 或正式版,按 `references/version-sync.md` 同步版本;按 `references/changelog.md` 更新该工程 changelog,每个版本条目必须包含明确版本号和日期,禁止使用 `Unreleased` 或“未发布”等占位标题,与是否发布无关;再按 `references/git-tag.md` 提交和打 tag。无变更工程不创建空版本。已覆盖本次代码的现有版本可复用,不重复升版或打 tag。
14
+ 3. 对本次需要更新的工程,按版本决策规则确定版本级别、beta/rc 或正式版,按 `references/version-sync.md` 同步版本;按 `references/changelog.md` 更新该工程 changelog,每个版本条目必须包含明确版本号和日期,禁止使用 `Unreleased` 或“未发布”等占位标题,与是否发布无关;再按 `references/git-tag.md` 提交和打 tag。无变更工程不创建空版本。已覆盖本次代码的现有版本可复用,不重复升版或打 tag。
15
15
  4. 确定是否发布:仅版本管理时结束;需要发布或部署时,读取项目约定及现有 CI、构建和部署配置,判断渠道和命令。遵守仓库的发布和授权规则,不套用固定发布方式;证据不足时询问。不根据分支判断版本类型或发布流程。
16
- 5. **部署上线闸门**:有新代码要上线,AI 自动检查并补齐对应工程的版本更新、changelog 和 tag,不逐项要求用户确认。自动校验 tag 指向包含全部拟部署代码、版本和 changelog 的提交,构建或部署使用该提交或其已验证产物。补齐并校验通过后继续部署;无法补齐或校验失败时停止部署并说明原因,不能以赶时间或已有构建替代。先完成项目要求的测试和适用的安全检查;SDK 对外发布前读取 `../dwy-sdk-spec`。
16
+ 5. **部署上线闸门**:有新代码要上线,AI 自动检查并补齐对应工程的版本更新、changelog 和 tag,不逐项要求用户确认。自动校验 tag 指向包含全部拟部署代码、版本和 changelog 的提交,构建或部署使用该提交或其已验证产物。补齐并校验通过后继续部署;无法补齐或校验失败时停止部署并说明原因,不能以赶时间或已有构建替代。先完成项目要求的测试和适用的安全检查。
17
17
  6. 推送 tag 前检查远端工作流及其他自动触发器:若推送会发布,先完成所有发布闸门并确认本次已获发布授权。仅要求版本管理而推送会触发未经授权的发布时,保留本地 tag 并报告,不能推送或擅自更改 workflow。
18
18
  7. 已获授权且满足闸门时,按项目实际配置执行发布;需要 GitHub Actions 打包时读取 `../dwy-github-action-publish` 和相应平台参考文件。按 `references/monitor-notify.md` 监控并验证实际结果。
19
19
 
@@ -26,3 +26,7 @@ description: "Use when 用户要求整理工程版本、更新 changelog、打
26
26
  - 平台:`references/frontend-deploy.md`、`references/backend-deploy.md`、`references/ios.md`、`references/android.md`、`references/harmony.md`、`references/generic-release.md`。
27
27
 
28
28
  版本、tag 或发布目标存在歧义时先核实;不可识别时询问。删除或覆盖远端 tag / release 前必须获得用户明确授权。输出各工程的版本、changelog、tag、是否推送和实际发布验证结果。
29
+
30
+ ## 版本决策
31
+
32
+ 按项目版本约定和公开接口兼容性确定版本:不兼容变更升 major,向后兼容的新功能升 minor,向后兼容的问题修复升 patch;同时包含多类变更时取最高级别。升级某一位时将其右侧数字归零。0.x 阶段及预发布版本按项目已有约定处理;约定不明时与用户确认。根据发布用途选择正式版或预发布版,不依据分支判断。
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## 版本(通用步,固化)
11
11
 
12
- - `versionName` = 语义版本号,走 `../dwy-semver` 决策 + bump.py。
12
+ - `versionName` = 语义版本号,按发布 skill 的版本决策规则确定。
13
13
  - 新上传构建的 `versionCode` 遵循渠道及项目的递增要求。
14
14
  - 多文件同步见 `version-sync.md`。
15
15
 
@@ -28,5 +28,5 @@
28
28
 
29
29
  - changelog → `changelog.md`(使用该工程既有路径和格式)
30
30
  - tag → `git-tag.md`(每次 bump 必打;版本串与 changelog 标题一致)
31
- - 安全检查 → `../dwy-sdk-spec`
31
+ - 按项目要求检查发布产物和敏感信息。
32
32
  - 监控 + 结果 → `monitor-notify.md`
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 版本(通用步,固化)
6
6
 
7
- - 走 `../dwy-semver` 决策 + bump.py;按 `version-sync.md` 同步工程实际维护的版本来源。
7
+ - 按发布 skill 的版本决策规则确定版本;按 `version-sync.md` 同步工程实际维护的版本来源。
8
8
  - 部署新代码必须先完成入口规定的版本、changelog 和 tag 闸门;仅重发或回滚相同已记录产物可复用原版本。
9
9
 
10
10
  ## build / deploy(项目步,不写死命令)
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 版本(通用步,固化)
6
6
 
7
- - 走 `../dwy-semver` 决策 + bump.py;多文件同步见 `version-sync.md`(前端改 `package.json` 的 `version`)。
7
+ - 按发布 skill 的版本决策规则确定版本;多文件同步见 `version-sync.md`(前端改 `package.json` 的 `version`)。
8
8
  - 部署新代码必须先完成入口规定的版本、changelog 和 tag 闸门;仅重发或回滚相同已记录产物可复用原版本。
9
9
 
10
10
  ## build / deploy(项目步,不写死命令)
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 版本(通用步,固化)
6
6
 
7
- - 走 `../dwy-semver` 决策 + bump.py;按 `version-sync.md` 同步工程实际维护的版本来源。
7
+ - 按发布 skill 的版本决策规则确定版本;按 `version-sync.md` 同步工程实际维护的版本来源。
8
8
  - 发布新代码必须先完成入口规定的版本、changelog 和 tag 闸门;仅重发或回滚相同已记录产物可复用原版本。
9
9
 
10
10
  ## build / publish(项目步,不写死命令)
@@ -24,5 +24,5 @@
24
24
 
25
25
  - changelog → `changelog.md`(使用该工程既有路径和格式)
26
26
  - tag → `git-tag.md`(每次 bump 必打;版本串与 changelog 标题一致;monorepo 例:`@dwydev/eui@2.2.3`、`create-dwy@0.16.1`)
27
- - 安全检查 → `../dwy-sdk-spec`(对外包必查泄露/产物)
27
+ - 按项目要求检查发布产物和敏感信息。
28
28
  - 监控 + verify → `monitor-notify.md`(包仓库版本查询 / GitHub Release)
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 版本(通用步,固化)
6
6
 
7
- - `oh-package.json5` 的 `version` = 语义版本号,走 `../dwy-semver` 决策 + bump.py。
7
+ - `oh-package.json5` 的 `version` = 语义版本号,按发布 skill 的版本决策规则确定。
8
8
  - 多文件同步见 `version-sync.md`。
9
9
 
10
10
  ## build / publish(项目步,不写死命令)
@@ -22,5 +22,5 @@
22
22
 
23
23
  - changelog → `changelog.md`(使用该工程既有路径和格式)
24
24
  - tag → `git-tag.md`(每次 bump 必打;版本串与 changelog 标题一致)
25
- - 安全检查 → `../dwy-sdk-spec`
25
+ - 按项目要求检查发布产物和敏感信息。
26
26
  - 监控 + 结果 → `monitor-notify.md`
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## 版本(通用步,固化)
11
11
 
12
- - 语义版本号 `CFBundleShortVersionString`,走 `../dwy-semver` 决策 + bump.py。
12
+ - 语义版本号 `CFBundleShortVersionString`,按发布 skill 的版本决策规则确定。
13
13
  - 构建号 `CFBundleVersion` 遵循项目及发布渠道约定;重新上传构建时满足渠道的递增要求。
14
14
  - 多文件同步见 `version-sync.md`。
15
15
 
@@ -29,5 +29,5 @@
29
29
 
30
30
  - changelog → `changelog.md`(使用该工程既有路径和格式)
31
31
  - tag → `git-tag.md`(每次 bump 必打;版本串与 changelog 标题一致)
32
- - 安全检查 → `../dwy-sdk-spec`(SDK 发布尤其要查泄露)
32
+ - 按项目要求检查发布产物和敏感信息。
33
33
  - 监控 + 结果 → `monitor-notify.md`
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: dwy-dependency-choice
3
- description: "新增或升级运行时依赖、选版本、选基础镜像 / SDK、检查开源许可证时必须使用(即使用户没说 skill 名)。只选发布满 7 天的正式版;闭源商用禁止 GPL / AGPL / SSPL / 非商业许可。各栈查发布时间和隐私协议附录模板在本 skill。不负责本包自己的 SemVer(那是 dwy-semver)。已安装的旧版本不用为此升级。"
3
+ description: "新增或升级运行时依赖、选版本、选基础镜像 / SDK、检查开源许可证时必须使用(即使用户没说 skill 名)。只选发布满 7 天的正式版;闭源商用禁止 GPL / AGPL / SSPL / 非商业许可。各栈查发布时间和隐私协议附录模板在本 skill。不负责本包自己的 SemVer。已安装的旧版本不用为此升级。"
4
4
  ---
5
5
 
6
6
  # 依赖选型(版本 + 许可)
7
7
 
8
- 新装或新选依赖、base 镜像、SDK、字体、图标、素材、模型权重时读本 skill。已安装的旧版本不用为此升级。本包自己的版本号走 `dwy-semver`。
8
+ 新装或新选依赖、base 镜像、SDK、字体、图标、素材、模型权重时读本 skill。已安装的旧版本不用为此升级。本包自己的发版版本号按 `dwy-publish` 决策。
9
9
 
10
10
  没有 skill 的工具只看这两份短 rule,和本 skill 冲突时以本 skill 为准:`rules/开发流程/dwy-dependency-freshness.md`、`rules/开发流程/dwy-oss-commercial-license.md`。
11
11
 
@@ -1,244 +0,0 @@
1
- ---
2
- name: dwy-sdk-spec
3
- description: "通用 SDK 发布前安全检查——任何 SDK 对外发布(PyPI / npm / 私有源 / 直接交付,渠道不限)前都应先过这一关。查三类风险:①接口注释是否泄露后端实现(内网域名、数据库表名、Redis key、内部服务名、员工邮箱、JIRA 链接、SQL 语句);②商业版 SDK 源码是否被保护(Python 用 Cython 编译 .so、JS 用 tsup/rollup minify + files 白名单);③发布产物是否夹带隐藏敏感文件(.py 源码 / .map source map / .env / .npmrc / tsbuildinfo / __pycache__ 等)。跨项目复用:首次进入新项目用 AskUserQuestion 问商业版还是开源版,缓存到 <project_root>/.dwy/sdk-spec/config.json,下次自动按规则检查。涉及以下任何场景必须使用此 skill:用户说「检查 SDK」「SDK 发版前检查」「SDK 注释脱敏」「SDK 接口规范」「发布前安全检查」「SDK 源码泄露检查」「商业版 SDK 打包」「Cython 编译 .so」「打包前体检」「.gitignore 漏了什么」「npm pack 看看包里有什么」「重设 SDK 版本类型」时。注:本 skill 只做发布前安全检查闸门,不执行发版流程(发版编排走 dwy-publish,会在发布前主动调用本检查)。"
4
- ---
5
-
6
- # dwy-sdk-spec — SDK 接口规范与发布安全检查
7
-
8
- 防三类风险:接口注释泄露后端实现 / 商业版 SDK 源码被还原 / 发布产物夹带隐藏敏感文件。
9
-
10
- **适用范围**:任何 SDK 对外发布前的通用安全闸门,与发布渠道无关——PyPI / npm / 私有源 / 直接打包交付都先过这一关。发 PyPI 只是其中一种渠道,不是触发前提。检查通过后,通用发版流程(测试 / bump / changelog / tag / publish)走 `dwy-publish`;含 C 扩展需跨平台 wheel 的走 `dwy-github-action-publish`。
11
-
12
- ## 何时触发
13
-
14
- 下列任何场景**必须**用此 skill,不要直接 `npm publish` / `python -m build` / `twine upload`:
15
-
16
- - 用户说「检查 SDK」「SDK 发版前检查」「SDK 接口规范」
17
- - 用户说「准备发布 SDK」(PyPI / npm / 私有源等任意渠道)「发布前体检」「打包前检查」
18
- - 用户说「SDK 注释脱敏」「SDK 源码泄露检查」「.gitignore 漏了什么」
19
- - 用户说「商业版 SDK 打包」「Cython 编译 .so」「npm 包混淆」
20
- - 用户说「npm pack 看看包里有什么」「dist 目录看一下」
21
- - 用户说「重设 SDK 版本类型」「换商业 / 开源版本」
22
-
23
- ## 工作流程 0:项目识别与配置(必走)
24
-
25
- skill 跨项目复用。每次执行流程 A/B/C 前先确保当前项目的配置就绪。
26
-
27
- ### 缓存文件格式
28
-
29
- 路径:`<project_root>/.dwy/sdk-spec/config.json`(写项目内,扁平结构,不存绝对路径)
30
-
31
- ```json
32
- {
33
- "version": "1",
34
- "edition": "commercial",
35
- "languages": ["python", "js"],
36
- "sdk_paths": {
37
- "python": ["backend"],
38
- "js": ["frontend/eui", "frontend/ekit"]
39
- },
40
- "configured_at": "2026-05-18T12:34:56Z"
41
- }
42
- ```
43
-
44
- - `edition` 必填,只能是 `commercial` 或 `opensource`
45
- - `languages` / `sdk_paths` 自动探测,`sdk_paths` 是**相对项目根的相对路径**
46
- - 配置随项目走、不存绝对路径;`.dwy/` 是本机判断缓存,提醒用户加进 `.gitignore`
47
-
48
- ### 读取流程
49
-
50
- ```bash
51
- SKILL_DIR="$(dirname "$0")" # 实际跑时 Claude 用 SKILL.md 所在目录拼 scripts/
52
- PROJECT_PATH=$(pwd)
53
- CONFIG=$(bash "$SKILL_DIR/scripts/init_config.sh" get "$PROJECT_PATH")
54
- ```
55
-
56
- - 输出非 `null` → 已配置,提取 `edition` / `languages` / `sdk_paths`,先做**路径校验**(见下),再跳到对应流程
57
- - 输出 `null` → 走「首次配置」
58
-
59
- ### 路径校验(应对 SDK 目录改名)
60
-
61
- `sdk_paths` 存相对路径,SDK 子目录改名(如 `backend`→`core`)后缓存会指向已不存在的目录。get 返回非 `null` 后,逐个检查 `sdk_paths` 里的相对目录在 `$PROJECT_PATH` 下是否存在:
62
-
63
- ```bash
64
- for d in $(jq -r '.sdk_paths[][]' <<< "$CONFIG"); do
65
- [[ -d "$PROJECT_PATH/$d" ]] || echo "MISSING: $d"
66
- done
67
- ```
68
-
69
- - 全部存在 → 直接用缓存
70
- - 有 `MISSING` → 警告用户「缓存的 SDK 路径已失效」,跑 `detect_sdk.sh` 重新探测,再用 `init_config.sh set` 覆盖更新(`edition` 沿用旧值),然后继续
71
-
72
- ### 首次配置流程
73
-
74
- 1. 跑 `bash scripts/detect_sdk.sh "$PROJECT_PATH"` 探测语言:
75
- - 看到 `pyproject.toml`(含 `[project]` 段)或 `setup.py` → Python SDK
76
- - 看到 `package.json`(含 `main` / `exports` / `module` 字段)→ JS SDK
77
- - monorepo 递归找子包(限 2 层深度),输出 JSON:
78
-
79
- ```json
80
- {"python": ["backend"], "js": ["frontend/eui", "frontend/ekit"]}
81
- ```
82
-
83
- - 都没找到 → 报错「当前目录不是 SDK 项目」,让用户确认 `pwd` 是否在项目根
84
-
85
- 2. **AskUserQuestion 问商业 / 开源**(必问,不能默认):
86
-
87
- - 标题:「当前项目 SDK 是商业版还是开源版?」
88
- - header:「SDK 版本」
89
- - 选项:
90
- - 「商业版(严格检查)」— 必须 Cython 编译 .so / npm 必须 minify + 白名单 files / 注释脱敏 + 打包白名单
91
- - 「开源版(宽松检查)」— 仅做注释脱敏 + 打包黑名单(防 .env / .npmrc / .map 漏出)
92
- - 不提供默认值,等用户选
93
-
94
- 3. 写入缓存:
95
-
96
- ```bash
97
- bash "$SKILL_DIR/scripts/init_config.sh" set "$PROJECT_PATH" "$EDITION" "$LANGUAGES_JSON" "$SDK_PATHS_JSON"
98
- ```
99
-
100
- ### 重设配置流程
101
-
102
- 用户说「换商业 / 开源版本」「重设 SDK 版本类型」:
103
-
104
- ```bash
105
- bash "$SKILL_DIR/scripts/init_config.sh" reset "$PROJECT_PATH"
106
- ```
107
-
108
- 然后重新走首次配置。
109
-
110
- ## 工作流程 A:接口注释脱敏检查(商业版+开源版都跑)
111
-
112
- ### 目的
113
-
114
- SDK 对外的 docstring / JSDoc / TSDoc **只写功能含义、入参格式、返回值、异常**,不写实现细节。常见泄露:内网域名、数据库表名、Redis key、内部服务名、SQL 语句、员工邮箱、JIRA 工单号。
115
-
116
- ### 执行
117
-
118
- ```bash
119
- bash "$SKILL_DIR/scripts/check_comments.py" "$PROJECT_PATH" --sdk-paths "$SDK_PATHS_JSON"
120
- ```
121
-
122
- 脚本输出 JSON 数组,每项:
123
-
124
- ```json
125
- {"file": "backend/src/dwyeapi/security.py", "line": 42, "pattern": "internal-domain", "match": "api.internal.corp.com", "context": "Connect to https://api.internal.corp.com/v2"}
126
- ```
127
-
128
- ### 违规处理
129
-
130
- 逐项展示给用户:
131
- - 引用 `references/sensitive-patterns.md` 给出正例 / 反例对照
132
- - 建议修复方案(删除 / 替换为公开描述)
133
- - 误报场景 → 在该行后加 `# sdk-spec: ignore` 注释豁免(脚本会跳过)
134
-
135
- **禁止**直接帮用户改源码,只输出修复建议清单让用户决策。
136
-
137
- ## 工作流程 B:商业版打包配置检查(仅 edition=commercial)
138
-
139
- ### Python SDK 分支
140
-
141
- 跑下面 4 项静态检查(不打包):
142
-
143
- ```bash
144
- # 1. pyproject.toml 是否含 Cython ext_modules
145
- grep -q 'cython\|ext_modules' "$PROJECT_PATH/pyproject.toml"
146
-
147
- # 2. 核心模块(_ 开头)是否已编译为 .so
148
- find "$PROJECT_PATH/<python_sdk_path>" -name '_*.so' -type f
149
-
150
- # 3. MANIFEST.in 是否含全局排除
151
- grep -E 'global-exclude.*\*\.py' "$PROJECT_PATH/MANIFEST.in"
152
-
153
- # 4. .gitignore 是否含必要项
154
- grep -E '^\*\.so$|^build/$|^dist/$|^\*\.egg-info' "$PROJECT_PATH/.gitignore"
155
- ```
156
-
157
- 缺哪条 → 引用 `references/python-commercial-guide.md` 给修复片段,提供 `assets/python-commercial.gitignore` 和 `assets/python-commercial-MANIFEST.in` 让用户 cp 到项目根(用 AskUserQuestion 让用户确认)。
158
-
159
- ### JS SDK 分支
160
-
161
- 跑下面 4 项静态检查:
162
-
163
- ```bash
164
- # 1. package.json 有 files 白名单且不含 src/ tests/
165
- jq -e '.files | length > 0 and (contains(["src/"]) or contains(["src"])) | not' "$PROJECT_PATH/<js_sdk_path>/package.json"
166
-
167
- # 2. 打包工具配置 minify + 无 sourcemap
168
- grep -E 'minify.*true|legalComments.*none|sourcemap.*false' "$PROJECT_PATH/<js_sdk_path>/tsup.config.*"
169
-
170
- # 3. dist/ 下没有 .map 文件
171
- find "$PROJECT_PATH/<js_sdk_path>/dist" -name '*.map' -type f 2>/dev/null
172
-
173
- # 4. .gitignore 含 .env / *.tsbuildinfo
174
- grep -E '\.env|\.tsbuildinfo' "$PROJECT_PATH/.gitignore"
175
- ```
176
-
177
- 缺哪条 → 引用 `references/js-commercial-guide.md`,提供 `assets/js-commercial.npmignore` 和 `assets/files-whitelist-snippet.json`。
178
-
179
- ## 工作流程 C:发布前文件清单审计
180
-
181
- **商业版严格 / 开源版宽松**,规则不同:
182
-
183
- | 版本 | Python 策略 | JS 策略 |
184
- |---|---|---|
185
- | commercial | 白名单:只允许 `.so` `.dist-info/` `.pyi` `.typed` `LICENSE` `README.md` 与必要资源 | 白名单:只允许 `dist/` `README.md` `LICENSE` `package.json` |
186
- | opensource | 黑名单:禁 `__pycache__/` `*.pyc` `.mypy_cache` `*.egg-info/` `.env*` `*.pdb` | 黑名单:禁 `.env*` `.npmrc` `*.map` `*.tsbuildinfo` `tsconfig.json` `.git*` `node_modules` |
187
-
188
- ### Python 执行
189
-
190
- ```bash
191
- bash "$SKILL_DIR/scripts/check_python_publish.sh" "$PROJECT_PATH/<python_sdk_path>" --edition "$EDITION"
192
- ```
193
-
194
- 脚本内部跑 `python -m build`(生成 wheel 到临时目录),`unzip -l dist/*.whl` 列文件,按 edition 白名单 / 黑名单断言。结束自动清理临时 dist。
195
-
196
- ### JS 执行
197
-
198
- ```bash
199
- bash "$SKILL_DIR/scripts/check_js_publish.sh" "$PROJECT_PATH/<js_sdk_path>" --edition "$EDITION"
200
- ```
201
-
202
- 脚本内部跑 `npm pack --dry-run --json` 拿包内文件列表,按 edition 断言。不实际产生 .tgz。
203
-
204
- ### 输出
205
-
206
- 每项违规:`<文件名> [规则: <白/黑名单条目>] → 建议: <修复方案>`
207
-
208
- 修复方案:
209
- - 多余文件 → 加到 `package.json` `files` 白名单外,或加到 `MANIFEST.in` `global-exclude`
210
- - 缺少文件 → 检查打包脚本是否漏跑
211
-
212
- **禁止**直接帮用户改配置文件,输出建议清单让用户决策。
213
-
214
- ## 错误处理速查
215
-
216
- | 情况 | 处理 |
217
- |---|---|
218
- | 脚本说命中敏感词但是误报 | 该行后加 `# sdk-spec: ignore`(Python)或 `// sdk-spec: ignore`(JS/TS)行内豁免 |
219
- | 商业版但项目特殊不用 Cython(如纯接口包) | 跟用户确认;要长期跳过 Python 商业打包检查 → `bash scripts/init_config.sh reset "$(pwd)"` 重选「开源版」,或单次跳过流程 B |
220
- | 想换商业 / 开源版本 | `bash scripts/init_config.sh reset "$(pwd)"` 然后重触发 skill 重问 |
221
- | `detect_sdk.sh` 没找到 SDK 但项目确实是 | 让用户手动指定 `--sdk-paths '{"python":["src/mypkg"]}'`,跳过自动探测 |
222
- | `python -m build` 失败 | 报告原因给用户,建议先 `pip install build`;不强制执行流程 C,可仅做流程 A+B |
223
- | `npm pack --dry-run` 失败 | 多半是 `npm install` 没跑或 `package.json` 缺字段,让用户先修复,重跑 |
224
- | 缓存文件损坏(jq 解析失败) | 提示用户备份原文件后删除 `<project_root>/.dwy/sdk-spec/config.json`,重新走首次配置 |
225
- | 缓存的 SDK 路径失效(目录改名/删除) | 走「路径校验」:警告后跑 `detect_sdk.sh` 重探测 + `set` 覆盖更新 |
226
-
227
- ## 跨项目约束
228
-
229
- skill 文件**零绝对路径**。装到任何机器上首次用时自动走流程 0。
230
-
231
- 需要用户机器满足:
232
- 1. 装了 `jq`(解析缓存 JSON)
233
- 2. Python 项目:装了 `python` 与 `build` 包(流程 C 用)
234
- 3. JS 项目:装了 `npm` 与 `node`(流程 C 用)
235
- 4. 缓存文件写项目内 `<project_root>/.dwy/sdk-spec/config.json`,是本机判断缓存,提醒用户加进 `.gitignore`,不入版本库
236
-
237
- ## 安全约束
238
-
239
- - skill 不存任何 token / 凭证 / 私钥
240
- - skill 不动 `~/.pypirc` / `~/.npmrc`
241
- - 脚本只做本地读 + 本地写 `<project_root>/.dwy/sdk-spec/`
242
- - 不静默修改任何源文件 / 配置文件,所有改动建议输出给用户决策
243
- - 不实际发布到 PyPI / npm,流程 C 全部使用 `--dry-run` 或临时目录
244
- - 检查通过 ≠ 安全保证,最终发布前用户必须人工 review `npm pack --dry-run` 输出
@@ -1,22 +0,0 @@
1
- {
2
- "_comment": "复制 main / module / types / exports / files / publishConfig 到 package.json,按实际包名/路径调整",
3
- "main": "./dist/index.cjs",
4
- "module": "./dist/index.js",
5
- "types": "./dist/index.d.ts",
6
- "exports": {
7
- ".": {
8
- "import": "./dist/index.js",
9
- "require": "./dist/index.cjs",
10
- "types": "./dist/index.d.ts"
11
- }
12
- },
13
- "files": [
14
- "dist",
15
- "README.md",
16
- "LICENSE"
17
- ],
18
- "publishConfig": {
19
- "registry": "https://registry.npmjs.org/",
20
- "access": "public"
21
- }
22
- }
@@ -1,76 +0,0 @@
1
- # JS/TS 商业版 SDK .npmignore 模板(降级方案)
2
- # 推荐:用 package.json 的 files 白名单(优先级更高),见 files-whitelist-snippet.json
3
- # 如必须用 .npmignore 走黑名单,cp 到包根
4
-
5
- # === 源码与测试 ===
6
- src/
7
- tests/
8
- __tests__/
9
- *.test.ts
10
- *.test.tsx
11
- *.test.js
12
- *.test.jsx
13
- *.spec.ts
14
- *.spec.tsx
15
- *.spec.js
16
- *.spec.jsx
17
-
18
- # === 编译产物泄露源码 ===
19
- *.map
20
- *.tsbuildinfo
21
-
22
- # === 配置文件(暴露技术栈) ===
23
- tsconfig*.json
24
- vite.config.*
25
- vitest.config.*
26
- tsup.config.*
27
- rollup.config.*
28
- webpack.config.*
29
- jest.config.*
30
- .eslintrc*
31
- eslint.config.*
32
- .prettierrc*
33
- prettier.config.*
34
- commitlint.config.*
35
-
36
- # === 凭证 / 环境(致命) ===
37
- .env
38
- .env.*
39
- .npmrc
40
- .yarnrc
41
- .pnpmrc
42
- secrets.json
43
- credentials.json
44
- *.pem
45
- *.key
46
- *.p12
47
- id_rsa
48
- id_ed25519
49
-
50
- # === 版本控制 / CI / Git hook ===
51
- .git/
52
- .gitignore
53
- .gitattributes
54
- .github/
55
- .gitlab-ci.yml
56
- .travis.yml
57
- .circleci/
58
- .husky/
59
-
60
- # === 锁文件(npm 默认忽略 package-lock,但其他可能漏) ===
61
- pnpm-lock.yaml
62
- package-lock.json
63
- yarn.lock
64
-
65
- # === IDE / 系统 ===
66
- .vscode/
67
- .idea/
68
- *.swp
69
- *.swo
70
- .DS_Store
71
- Thumbs.db
72
-
73
- # === 构建临时 ===
74
- coverage/
75
- .nyc_output/
76
- node_modules/
@@ -1,37 +0,0 @@
1
- # Python 商业版 SDK MANIFEST.in 模板
2
- # 作用:控制 sdist / wheel 内含什么文件
3
- # 用法:cp 到项目根,按需调整 graft 路径
4
-
5
- # 收录 src/ 下整棵树
6
- graft src
7
-
8
- # 包含许可证 + README + 类型存根 + py.typed 标记
9
- include LICENSE LICENCE LICENSE.* README README.* py.typed
10
- include src/*/py.typed
11
- include src/*/*.pyi
12
- include src/*/**/*.pyi
13
-
14
- # 业务必要资源(按需取消注释)
15
- # include src/*/templates/*.html
16
- # include src/*/data/*.json
17
-
18
- # === 关键:全局排除源码与中间产物 ===
19
- # 排除以 _ 开头的内部 .py(已编译为 .so,不发源码)
20
- global-exclude _*.py
21
-
22
- # 排除 Cython / C 中间文件
23
- global-exclude *.pyx *.pxd *.c
24
-
25
- # 排除字节码与缓存
26
- global-exclude *.pyc *.pyo __pycache__
27
- global-exclude .mypy_cache .pytest_cache .ruff_cache .tox
28
-
29
- # 排除版本控制 / 系统 / 编辑器文件
30
- global-exclude .git .gitignore .gitattributes
31
- global-exclude .DS_Store Thumbs.db
32
- global-exclude *.swp *.swo *~
33
-
34
- # 排除凭证(致命,再保险一道)
35
- global-exclude .env .env.*
36
- global-exclude .pypirc secrets.json credentials.json
37
- global-exclude *.pem *.key *.p12