create-dwy 0.12.1 → 0.12.2
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/package.json +1 -1
- package/src/sync.js +13 -6
- package/templates/claude-global/rules/Python/dwy-python-core.md +105 -7
- package/templates/claude-global/skills//345/205/203/345/267/245/345/205/267/dwy-shared/SKILL.md +255 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/SKILL.md +232 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/assets/files-whitelist-snippet.json +22 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/assets/js-commercial.npmignore +76 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/assets/python-commercial-MANIFEST.in +37 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/assets/python-commercial.gitignore +62 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/references/js-commercial-guide.md +133 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/references/publish-blacklist.md +106 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/references/python-commercial-guide.md +147 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/references/sensitive-patterns.md +112 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/check_comments.py +260 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/check_js_publish.sh +110 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/check_python_publish.sh +171 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/detect_sdk.sh +71 -0
- package/templates/claude-global/skills//345/256/211/345/205/250/dwy-sdk-spec/scripts/init_config.sh +97 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-code-flow-docs/SKILL.md +170 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-code-flow-docs/examples//351/205/215/351/242/235/350/256/241/347/256/227.md +64 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-code-flow-docs/templates/INDEX.md +7 -0
- package/templates/claude-global/skills//345/274/200/345/217/221/346/265/201/347/250/213/dwy-code-flow-docs/templates/logic-doc.md +49 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dwy-sdk-spec
|
|
3
|
+
description: "SDK 接口规范与发布安全检查。检查 SDK 接口注释是否泄露后端实现(内网域名、数据库表名、Redis key、内部服务名、员工邮箱、JIRA 链接、SQL 语句),检查商业版 Python SDK 是否用 Cython 编译成 .so 隐藏源码,检查商业版 JS SDK 是否用 tsup/rollup minify + files 白名单,检查 PyPI/npm 发布产物是否含 .py 源文件 / .map source map / .env / .npmrc / tsbuildinfo / __pycache__ 等隐藏泄露文件。跨项目复用:首次进入新项目用 AskUserQuestion 问商业版还是开源版,缓存到 ~/.config/dwy-sdk-spec/projects.json,下次自动按规则检查。涉及以下任何场景必须使用此 skill:用户说「检查 SDK」「SDK 发版前检查」「SDK 注释脱敏」「SDK 接口规范」「准备发 PyPI」「准备发 npm」「商业版 SDK 打包」「Cython 编译 .so」「打包前体检」「.gitignore 漏了什么」「npm pack 看看包里有什么」「发布前安全检查」「SDK 源码泄露检查」「重设 SDK 版本类型」。"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dwy-sdk-spec — SDK 接口规范与发布安全检查
|
|
7
|
+
|
|
8
|
+
防三类风险:接口注释泄露后端实现 / 商业版 SDK 源码被还原 / 发布产物夹带隐藏敏感文件。
|
|
9
|
+
|
|
10
|
+
## 何时触发
|
|
11
|
+
|
|
12
|
+
下列任何场景**必须**用此 skill,不要直接 `npm publish` / `python -m build` / `twine upload`:
|
|
13
|
+
|
|
14
|
+
- 用户说「检查 SDK」「SDK 发版前检查」「SDK 接口规范」
|
|
15
|
+
- 用户说「准备发 PyPI / npm」「发布前体检」「打包前检查」
|
|
16
|
+
- 用户说「SDK 注释脱敏」「SDK 源码泄露检查」「.gitignore 漏了什么」
|
|
17
|
+
- 用户说「商业版 SDK 打包」「Cython 编译 .so」「npm 包混淆」
|
|
18
|
+
- 用户说「npm pack 看看包里有什么」「dist 目录看一下」
|
|
19
|
+
- 用户说「重设 SDK 版本类型」「换商业 / 开源版本」
|
|
20
|
+
|
|
21
|
+
## 工作流程 0:项目识别与配置(必走)
|
|
22
|
+
|
|
23
|
+
skill 跨项目复用。每次执行流程 A/B/C 前先确保当前项目的配置就绪。
|
|
24
|
+
|
|
25
|
+
### 缓存文件格式
|
|
26
|
+
|
|
27
|
+
路径:`~/.config/dwy-sdk-spec/projects.json`
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"version": "1",
|
|
32
|
+
"projects": {
|
|
33
|
+
"/绝对/路径/到/项目根": {
|
|
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
|
+
```
|
|
45
|
+
|
|
46
|
+
- `edition` 必填,只能是 `commercial` 或 `opensource`
|
|
47
|
+
- `languages` / `sdk_paths` 自动探测
|
|
48
|
+
- key 是项目**绝对路径**(`pwd` 取),跨机器迁移自动失效
|
|
49
|
+
|
|
50
|
+
### 读取流程
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
SKILL_DIR="$(dirname "$0")" # 实际跑时 Claude 用 SKILL.md 所在目录拼 scripts/
|
|
54
|
+
PROJECT_PATH=$(pwd)
|
|
55
|
+
CONFIG=$(bash "$SKILL_DIR/scripts/init_config.sh" get "$PROJECT_PATH")
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- 输出非 `null` → 已配置,提取 `edition` / `languages` / `sdk_paths`,跳到对应流程
|
|
59
|
+
- 输出 `null` → 走「首次配置」
|
|
60
|
+
|
|
61
|
+
### 首次配置流程
|
|
62
|
+
|
|
63
|
+
1. 跑 `bash scripts/detect_sdk.sh "$PROJECT_PATH"` 探测语言:
|
|
64
|
+
- 看到 `pyproject.toml`(含 `[project]` 段)或 `setup.py` → Python SDK
|
|
65
|
+
- 看到 `package.json`(含 `main` / `exports` / `module` 字段)→ JS SDK
|
|
66
|
+
- monorepo 递归找子包(限 2 层深度),输出 JSON:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{"python": ["backend"], "js": ["frontend/eui", "frontend/ekit"]}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- 都没找到 → 报错「当前目录不是 SDK 项目」,让用户确认 `pwd` 是否在项目根
|
|
73
|
+
|
|
74
|
+
2. **AskUserQuestion 问商业 / 开源**(必问,不能默认):
|
|
75
|
+
|
|
76
|
+
- 标题:「当前项目 SDK 是商业版还是开源版?」
|
|
77
|
+
- header:「SDK 版本」
|
|
78
|
+
- 选项:
|
|
79
|
+
- 「商业版(严格检查)」— 必须 Cython 编译 .so / npm 必须 minify + 白名单 files / 注释脱敏 + 打包白名单
|
|
80
|
+
- 「开源版(宽松检查)」— 仅做注释脱敏 + 打包黑名单(防 .env / .npmrc / .map 漏出)
|
|
81
|
+
- 不提供默认值,等用户选
|
|
82
|
+
|
|
83
|
+
3. 写入缓存:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
bash "$SKILL_DIR/scripts/init_config.sh" set "$PROJECT_PATH" "$EDITION" "$LANGUAGES_JSON" "$SDK_PATHS_JSON"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 重设配置流程
|
|
90
|
+
|
|
91
|
+
用户说「换商业 / 开源版本」「重设 SDK 版本类型」:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
bash "$SKILL_DIR/scripts/init_config.sh" reset "$PROJECT_PATH"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
然后重新走首次配置。
|
|
98
|
+
|
|
99
|
+
## 工作流程 A:接口注释脱敏检查(商业版+开源版都跑)
|
|
100
|
+
|
|
101
|
+
### 目的
|
|
102
|
+
|
|
103
|
+
SDK 对外的 docstring / JSDoc / TSDoc **只写功能含义、入参格式、返回值、异常**,不写实现细节。常见泄露:内网域名、数据库表名、Redis key、内部服务名、SQL 语句、员工邮箱、JIRA 工单号。
|
|
104
|
+
|
|
105
|
+
### 执行
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
bash "$SKILL_DIR/scripts/check_comments.py" "$PROJECT_PATH" --sdk-paths "$SDK_PATHS_JSON"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
脚本输出 JSON 数组,每项:
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{"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"}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 违规处理
|
|
118
|
+
|
|
119
|
+
逐项展示给用户:
|
|
120
|
+
- 引用 `references/sensitive-patterns.md` 给出正例 / 反例对照
|
|
121
|
+
- 建议修复方案(删除 / 替换为公开描述)
|
|
122
|
+
- 误报场景 → 在该行后加 `# sdk-spec: ignore` 注释豁免(脚本会跳过)
|
|
123
|
+
|
|
124
|
+
**禁止**直接帮用户改源码,只输出修复建议清单让用户决策。
|
|
125
|
+
|
|
126
|
+
## 工作流程 B:商业版打包配置检查(仅 edition=commercial)
|
|
127
|
+
|
|
128
|
+
### Python SDK 分支
|
|
129
|
+
|
|
130
|
+
跑下面 4 项静态检查(不打包):
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# 1. pyproject.toml 是否含 Cython ext_modules
|
|
134
|
+
grep -q 'cython\|ext_modules' "$PROJECT_PATH/pyproject.toml"
|
|
135
|
+
|
|
136
|
+
# 2. 核心模块(_ 开头)是否已编译为 .so
|
|
137
|
+
find "$PROJECT_PATH/<python_sdk_path>" -name '_*.so' -type f
|
|
138
|
+
|
|
139
|
+
# 3. MANIFEST.in 是否含全局排除
|
|
140
|
+
grep -E 'global-exclude.*\*\.py' "$PROJECT_PATH/MANIFEST.in"
|
|
141
|
+
|
|
142
|
+
# 4. .gitignore 是否含必要项
|
|
143
|
+
grep -E '^\*\.so$|^build/$|^dist/$|^\*\.egg-info' "$PROJECT_PATH/.gitignore"
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
缺哪条 → 引用 `references/python-commercial-guide.md` 给修复片段,提供 `assets/python-commercial.gitignore` 和 `assets/python-commercial-MANIFEST.in` 让用户 cp 到项目根(用 AskUserQuestion 让用户确认)。
|
|
147
|
+
|
|
148
|
+
### JS SDK 分支
|
|
149
|
+
|
|
150
|
+
跑下面 4 项静态检查:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# 1. package.json 有 files 白名单且不含 src/ tests/
|
|
154
|
+
jq -e '.files | length > 0 and (contains(["src/"]) or contains(["src"])) | not' "$PROJECT_PATH/<js_sdk_path>/package.json"
|
|
155
|
+
|
|
156
|
+
# 2. 打包工具配置 minify + 无 sourcemap
|
|
157
|
+
grep -E 'minify.*true|legalComments.*none|sourcemap.*false' "$PROJECT_PATH/<js_sdk_path>/tsup.config.*"
|
|
158
|
+
|
|
159
|
+
# 3. dist/ 下没有 .map 文件
|
|
160
|
+
find "$PROJECT_PATH/<js_sdk_path>/dist" -name '*.map' -type f 2>/dev/null
|
|
161
|
+
|
|
162
|
+
# 4. .gitignore 含 .env / *.tsbuildinfo
|
|
163
|
+
grep -E '\.env|\.tsbuildinfo' "$PROJECT_PATH/.gitignore"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
缺哪条 → 引用 `references/js-commercial-guide.md`,提供 `assets/js-commercial.npmignore` 和 `assets/files-whitelist-snippet.json`。
|
|
167
|
+
|
|
168
|
+
## 工作流程 C:发布前文件清单审计
|
|
169
|
+
|
|
170
|
+
**商业版严格 / 开源版宽松**,规则不同:
|
|
171
|
+
|
|
172
|
+
| 版本 | Python 策略 | JS 策略 |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| commercial | 白名单:只允许 `.so` `.dist-info/` `.pyi` `.typed` `LICENSE` `README.md` 与必要资源 | 白名单:只允许 `dist/` `README.md` `LICENSE` `package.json` |
|
|
175
|
+
| opensource | 黑名单:禁 `__pycache__/` `*.pyc` `.mypy_cache` `*.egg-info/` `.env*` `*.pdb` | 黑名单:禁 `.env*` `.npmrc` `*.map` `*.tsbuildinfo` `tsconfig.json` `.git*` `node_modules` |
|
|
176
|
+
|
|
177
|
+
### Python 执行
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
bash "$SKILL_DIR/scripts/check_python_publish.sh" "$PROJECT_PATH/<python_sdk_path>" --edition "$EDITION"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
脚本内部跑 `python -m build`(生成 wheel 到临时目录),`unzip -l dist/*.whl` 列文件,按 edition 白名单 / 黑名单断言。结束自动清理临时 dist。
|
|
184
|
+
|
|
185
|
+
### JS 执行
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
bash "$SKILL_DIR/scripts/check_js_publish.sh" "$PROJECT_PATH/<js_sdk_path>" --edition "$EDITION"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
脚本内部跑 `npm pack --dry-run --json` 拿包内文件列表,按 edition 断言。不实际产生 .tgz。
|
|
192
|
+
|
|
193
|
+
### 输出
|
|
194
|
+
|
|
195
|
+
每项违规:`<文件名> [规则: <白/黑名单条目>] → 建议: <修复方案>`
|
|
196
|
+
|
|
197
|
+
修复方案:
|
|
198
|
+
- 多余文件 → 加到 `package.json` `files` 白名单外,或加到 `MANIFEST.in` `global-exclude`
|
|
199
|
+
- 缺少文件 → 检查打包脚本是否漏跑
|
|
200
|
+
|
|
201
|
+
**禁止**直接帮用户改配置文件,输出建议清单让用户决策。
|
|
202
|
+
|
|
203
|
+
## 错误处理速查
|
|
204
|
+
|
|
205
|
+
| 情况 | 处理 |
|
|
206
|
+
|---|---|
|
|
207
|
+
| 脚本说命中敏感词但是误报 | 该行后加 `# sdk-spec: ignore`(Python)或 `// sdk-spec: ignore`(JS/TS)行内豁免 |
|
|
208
|
+
| 商业版但项目特殊不用 Cython(如纯接口包) | 跟用户确认;要长期跳过 Python 商业打包检查 → `bash scripts/init_config.sh reset` 重选「开源版」,或单次跳过流程 B |
|
|
209
|
+
| 想换商业 / 开源版本 | `bash scripts/init_config.sh reset "$(pwd)"` 然后重触发 skill 重问 |
|
|
210
|
+
| `detect_sdk.sh` 没找到 SDK 但项目确实是 | 让用户手动指定 `--sdk-paths '{"python":["src/mypkg"]}'`,跳过自动探测 |
|
|
211
|
+
| `python -m build` 失败 | 报告原因给用户,建议先 `pip install build`;不强制执行流程 C,可仅做流程 A+B |
|
|
212
|
+
| `npm pack --dry-run` 失败 | 多半是 `npm install` 没跑或 `package.json` 缺字段,让用户先修复,重跑 |
|
|
213
|
+
| 缓存文件损坏(jq 解析失败) | 提示用户备份原文件后删除 `~/.config/dwy-sdk-spec/projects.json`,重新走首次配置 |
|
|
214
|
+
|
|
215
|
+
## 跨项目约束
|
|
216
|
+
|
|
217
|
+
skill 文件**零绝对路径**。装到任何机器上首次用时自动走流程 0。
|
|
218
|
+
|
|
219
|
+
需要用户机器满足:
|
|
220
|
+
1. 装了 `jq`(解析缓存 JSON)
|
|
221
|
+
2. Python 项目:装了 `python` 与 `build` 包(流程 C 用)
|
|
222
|
+
3. JS 项目:装了 `npm` 与 `node`(流程 C 用)
|
|
223
|
+
4. 缓存文件 `~/.config/dwy-sdk-spec/projects.json` 是本机配置,**不**随 skill 同步出去
|
|
224
|
+
|
|
225
|
+
## 安全约束
|
|
226
|
+
|
|
227
|
+
- skill 不存任何 token / 凭证 / 私钥
|
|
228
|
+
- skill 不动 `~/.pypirc` / `~/.npmrc`
|
|
229
|
+
- 脚本只做本地读 + 本地写 `~/.config/dwy-sdk-spec/`
|
|
230
|
+
- 不静默修改任何源文件 / 配置文件,所有改动建议输出给用户决策
|
|
231
|
+
- 不实际发布到 PyPI / npm,流程 C 全部使用 `--dry-run` 或临时目录
|
|
232
|
+
- 检查通过 ≠ 安全保证,最终发布前用户必须人工 review `npm pack --dry-run` 输出
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
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/
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Python 商业版 SDK .gitignore 模板
|
|
2
|
+
# 用法: cp 到项目根,按需追加项目自有忽略项
|
|
3
|
+
|
|
4
|
+
# 源码编译产物
|
|
5
|
+
*.so
|
|
6
|
+
*.so.c
|
|
7
|
+
*.c
|
|
8
|
+
*.dylib
|
|
9
|
+
*.dll
|
|
10
|
+
build/
|
|
11
|
+
dist/
|
|
12
|
+
*.egg-info/
|
|
13
|
+
.eggs/
|
|
14
|
+
|
|
15
|
+
# Cython 中间文件
|
|
16
|
+
*.pyx.c
|
|
17
|
+
|
|
18
|
+
# Python 缓存
|
|
19
|
+
__pycache__/
|
|
20
|
+
*.pyc
|
|
21
|
+
*.pyo
|
|
22
|
+
*.pyd
|
|
23
|
+
.Python
|
|
24
|
+
|
|
25
|
+
# 类型检查 / lint / 测试缓存
|
|
26
|
+
.mypy_cache/
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
.ruff_cache/
|
|
29
|
+
.tox/
|
|
30
|
+
.nox/
|
|
31
|
+
htmlcov/
|
|
32
|
+
.coverage
|
|
33
|
+
.coverage.*
|
|
34
|
+
|
|
35
|
+
# 虚拟环境
|
|
36
|
+
.venv/
|
|
37
|
+
venv/
|
|
38
|
+
env/
|
|
39
|
+
ENV/
|
|
40
|
+
|
|
41
|
+
# 凭证 / 配置(致命,绝不能进仓库)
|
|
42
|
+
.env
|
|
43
|
+
.env.*
|
|
44
|
+
.pypirc
|
|
45
|
+
secrets.json
|
|
46
|
+
credentials.json
|
|
47
|
+
*.pem
|
|
48
|
+
*.key
|
|
49
|
+
*.p12
|
|
50
|
+
id_rsa
|
|
51
|
+
id_ed25519
|
|
52
|
+
|
|
53
|
+
# IDE
|
|
54
|
+
.vscode/
|
|
55
|
+
.idea/
|
|
56
|
+
*.swp
|
|
57
|
+
*.swo
|
|
58
|
+
*~
|
|
59
|
+
|
|
60
|
+
# OS
|
|
61
|
+
.DS_Store
|
|
62
|
+
Thumbs.db
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# JS/TS 商业版 SDK 完整打包指南
|
|
2
|
+
|
|
3
|
+
目标:发布到 npm 的 `.tgz` 内**不含 src/、不含 sourcemap、不含 tsconfig**,只含压缩后的 `dist/` 与 `.d.ts` 类型定义。
|
|
4
|
+
|
|
5
|
+
## 关键原则
|
|
6
|
+
|
|
7
|
+
- `package.json` 的 `files` 字段是**白名单**,优先级高于 `.npmignore`
|
|
8
|
+
- 用 `tsup` 或 `rollup` 打包,强制 `minify: true` + `sourcemap: false` + `legalComments: 'none'`
|
|
9
|
+
- `.d.ts` 单独生成(用户要类型提示),但不能带 `.d.ts.map`(会映射回源码)
|
|
10
|
+
|
|
11
|
+
## 工具选择
|
|
12
|
+
|
|
13
|
+
| 工具 | 优势 | 推荐场景 |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **tsup** | 零配置、内置 dts + 多格式 | **默认选择** |
|
|
16
|
+
| rollup + rollup-plugin-dts | 配置灵活、生态成熟 | 复杂 bundle 拆分 |
|
|
17
|
+
| esbuild | 最快、最小 | 简单单文件 SDK |
|
|
18
|
+
|
|
19
|
+
下面以 tsup 为准。
|
|
20
|
+
|
|
21
|
+
## 项目结构示例
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
mysdk/
|
|
25
|
+
├── package.json
|
|
26
|
+
├── tsup.config.ts
|
|
27
|
+
├── tsconfig.json # 仅本地用,不发
|
|
28
|
+
├── .gitignore
|
|
29
|
+
├── .npmignore # 可选(files 优先)
|
|
30
|
+
├── src/
|
|
31
|
+
│ ├── index.ts # 入口
|
|
32
|
+
│ ├── client.ts # 公开 API
|
|
33
|
+
│ └── _internal/ # 内部模块
|
|
34
|
+
│ └── engine.ts
|
|
35
|
+
└── dist/ # 构建产物(唯一发布内容)
|
|
36
|
+
├── index.js # ESM,minified
|
|
37
|
+
├── index.cjs # CJS,minified
|
|
38
|
+
└── index.d.ts # 类型定义(无 .map)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## tsup.config.ts
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { defineConfig } from 'tsup'
|
|
45
|
+
|
|
46
|
+
export default defineConfig({
|
|
47
|
+
entry: ['src/index.ts'],
|
|
48
|
+
format: ['esm', 'cjs'],
|
|
49
|
+
dts: true, // 生成 .d.ts
|
|
50
|
+
sourcemap: false, // 关键:不生成 .map(防止源码可还原)
|
|
51
|
+
minify: true, // 压缩
|
|
52
|
+
legalComments: 'none', // 去掉 /*! */ 版权注释(可能含路径)
|
|
53
|
+
splitting: false, // 不拆分(防止内部模块结构暴露)
|
|
54
|
+
clean: true, // 构建前清 dist/
|
|
55
|
+
treeshake: true,
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## package.json
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"name": "@dwydev/mysdk",
|
|
64
|
+
"version": "1.0.0",
|
|
65
|
+
"main": "./dist/index.cjs",
|
|
66
|
+
"module": "./dist/index.js",
|
|
67
|
+
"types": "./dist/index.d.ts",
|
|
68
|
+
"exports": {
|
|
69
|
+
".": {
|
|
70
|
+
"import": "./dist/index.js",
|
|
71
|
+
"require": "./dist/index.cjs",
|
|
72
|
+
"types": "./dist/index.d.ts"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"files": [
|
|
76
|
+
"dist",
|
|
77
|
+
"README.md",
|
|
78
|
+
"LICENSE"
|
|
79
|
+
],
|
|
80
|
+
"scripts": {
|
|
81
|
+
"build": "tsup",
|
|
82
|
+
"prepublishOnly": "pnpm build && npm pack --dry-run"
|
|
83
|
+
},
|
|
84
|
+
"publishConfig": {
|
|
85
|
+
"registry": "https://registry.npmjs.org/",
|
|
86
|
+
"access": "public"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`files` 白名单只列 3 项 → 其他全部不发(src/、tests/、tsconfig.json、tsup.config.ts、node_modules/ 自动不发)。
|
|
92
|
+
|
|
93
|
+
## 构建命令
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# 清理 + 打包
|
|
97
|
+
rm -rf dist/
|
|
98
|
+
pnpm build
|
|
99
|
+
|
|
100
|
+
# 验证 dist/ 无 .map
|
|
101
|
+
find dist -name '*.map' -type f && echo "FAIL: sourcemap leaked" || echo "OK: no sourcemap"
|
|
102
|
+
|
|
103
|
+
# 干跑看 .tgz 内容
|
|
104
|
+
npm pack --dry-run --json | jq '.[] | .files[] | .path'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 验收清单(流程 B 用)
|
|
108
|
+
|
|
109
|
+
| 检查项 | 命令 |
|
|
110
|
+
|---|---|
|
|
111
|
+
| package.json 有 files 白名单 | `jq '.files \| length > 0' package.json` |
|
|
112
|
+
| files 不含 src/ | `jq '.files \| any(. == "src" or . == "src/")' package.json` 应为 false |
|
|
113
|
+
| tsup 配置 minify + 无 sourcemap | `grep -E 'minify.*true' tsup.config.*` + `grep -E 'sourcemap.*false' tsup.config.*` |
|
|
114
|
+
| dist/ 下无 .map | `find dist -name '*.map'` 应为空 |
|
|
115
|
+
| .gitignore 含 .env / *.tsbuildinfo | `grep -E '\.env\\|\.tsbuildinfo' .gitignore` |
|
|
116
|
+
|
|
117
|
+
## 常见踩坑
|
|
118
|
+
|
|
119
|
+
| 现象 | 原因 | 修复 |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| 用 `.npmignore` 但 files 也定义了 | `files` 优先,`.npmignore` 被忽略 | 二选一,推荐只用 `files` |
|
|
122
|
+
| `.tgz` 里有 `.DS_Store` | macOS 系统文件,没被 ignore | `.gitignore` 加 `.DS_Store`;npm 默认会带 .gitignore 规则 |
|
|
123
|
+
| 发布后 .d.ts 含内部路径 | tsup 生成的 .d.ts 没合并 | 用 `dts: { resolve: true }` 合并所有类型,或改用 rollup-plugin-dts |
|
|
124
|
+
| 装完后用户 IDE 跳转到 minified 代码 | `.d.ts.map` 不小心发了 | 检查 `dist/` 无 `.d.ts.map`,tsup 默认不生成 |
|
|
125
|
+
| `bin` 字段指向的 CLI 被压缩后报 "no entry" | 缺 shebang `#!/usr/bin/env node` | tsup 配 `banner: { js: '#!/usr/bin/env node' }` |
|
|
126
|
+
|
|
127
|
+
## 参考 dwy-shared 内已有 SDK
|
|
128
|
+
|
|
129
|
+
`frontend/eui/` / `frontend/ekit/` 当前是**开源版**(Vite 构建,含 `vite-plugin-dts`)。若要转商业版:
|
|
130
|
+
1. 把 Vite 换成 tsup(或在 Vite 配置加 `build.minify: 'terser'` + `build.sourcemap: false`)
|
|
131
|
+
2. `package.json` 添加 `files: ["dist", "README.md", "LICENSE"]`
|
|
132
|
+
3. 删除 `dist/` 下所有 `.map` 文件
|
|
133
|
+
4. 跑 `npm pack --dry-run` 验收
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# PyPI / npm 发布黑名单
|
|
2
|
+
|
|
3
|
+
`check_python_publish.sh` / `check_js_publish.sh` 的规则源。
|
|
4
|
+
|
|
5
|
+
## Python(PyPI)
|
|
6
|
+
|
|
7
|
+
### 商业版:白名单(其他一律违规)
|
|
8
|
+
|
|
9
|
+
| 允许的文件 / 模式 | 说明 |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `*.so` | 编译产物 |
|
|
12
|
+
| `*.pyi` | 类型存根(无源) |
|
|
13
|
+
| `py.typed` | 标记包支持类型检查 |
|
|
14
|
+
| `*.dist-info/**` | wheel 元数据(METADATA / RECORD / WHEEL / entry_points.txt 等) |
|
|
15
|
+
| `LICENSE` `LICENSE.*` `LICENCE` | 许可证(可在包外) |
|
|
16
|
+
| `README` `README.*` | 仅 dist-info 内 |
|
|
17
|
+
| `<pkg>/__init__.py` | 公开入口(如果用了 re-export 模式) |
|
|
18
|
+
| `<pkg>/<public_module>.py` | 不以 `_` 开头的公开 API 模块 |
|
|
19
|
+
| 业务必要资源(图片、json、模板) | 列入 `package-data` |
|
|
20
|
+
|
|
21
|
+
### 开源版:黑名单(任意命中视为违规)
|
|
22
|
+
|
|
23
|
+
| 禁止的文件 / 模式 | 原因 |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `__pycache__/**` | 字节码缓存,可反编译 |
|
|
26
|
+
| `*.pyc` `*.pyo` | 同上 |
|
|
27
|
+
| `*.egg-info/**` | 旧式构建元数据,含本地路径 |
|
|
28
|
+
| `.mypy_cache/**` `.pytest_cache/**` `.ruff_cache/**` | 开发工具缓存 |
|
|
29
|
+
| `.pdb` `.idb` | 调试符号 |
|
|
30
|
+
| `.env` `.env.*` `.env.local` | 环境变量(凭证) |
|
|
31
|
+
| `.pypirc` | PyPI 凭证(致命) |
|
|
32
|
+
| `.git/**` `.gitignore` | 版本控制(含历史) |
|
|
33
|
+
| `.DS_Store` `Thumbs.db` | 系统文件 |
|
|
34
|
+
| `.vscode/**` `.idea/**` | IDE 配置(可能含路径) |
|
|
35
|
+
| `*.bak` `*.swp` `*.swo` `*~` | 编辑器临时文件 |
|
|
36
|
+
|
|
37
|
+
## npm
|
|
38
|
+
|
|
39
|
+
### 商业版:白名单(其他一律违规)
|
|
40
|
+
|
|
41
|
+
| 允许的文件 / 模式 | 说明 |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `dist/**` | 构建产物(minified) |
|
|
44
|
+
| `package.json` | 必有 |
|
|
45
|
+
| `README` `README.*` | 用户必读 |
|
|
46
|
+
| `LICENSE` `LICENSE.*` `LICENCE` | 许可证 |
|
|
47
|
+
| `CHANGELOG` `CHANGELOG.*` | 可选 |
|
|
48
|
+
| `bin/**` | 仅 CLI 包 |
|
|
49
|
+
| `*.d.ts` 在 dist/ 内 | 类型定义 |
|
|
50
|
+
|
|
51
|
+
### 开源版:黑名单(任意命中视为违规)
|
|
52
|
+
|
|
53
|
+
| 禁止的文件 / 模式 | 原因 |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `src/**` `tests/**` `__tests__/**` | 源码 / 测试(占体积) |
|
|
56
|
+
| `*.test.ts` `*.spec.ts` `*.test.js` `*.spec.js` | 测试文件 |
|
|
57
|
+
| `*.map` `*.js.map` `*.d.ts.map` | sourcemap(源码可还原) |
|
|
58
|
+
| `*.tsbuildinfo` | TS 增量编译信息(含路径) |
|
|
59
|
+
| `tsconfig*.json` | 编译配置 |
|
|
60
|
+
| `vite.config.*` `vitest.config.*` `tsup.config.*` `rollup.config.*` `webpack.config.*` | 打包配置 |
|
|
61
|
+
| `.eslintrc*` `.prettierrc*` `eslint.config.*` `prettier.config.*` | Lint 配置 |
|
|
62
|
+
| `.env` `.env.*` | 环境变量(凭证) |
|
|
63
|
+
| `.npmrc` `.yarnrc` `.pnpmrc` | 包管理器配置(含 token) |
|
|
64
|
+
| `.git/**` `.gitignore` `.gitattributes` | 版本控制 |
|
|
65
|
+
| `.github/**` `.gitlab-ci.yml` `.travis.yml` `.circleci/**` | CI 配置(含 secret 引用) |
|
|
66
|
+
| `.vscode/**` `.idea/**` `*.swp` | IDE / 编辑器 |
|
|
67
|
+
| `.DS_Store` `Thumbs.db` | 系统文件 |
|
|
68
|
+
| `node_modules/**` | 依赖(npm 自动忽略,但 .npmignore 错误时可能漏出) |
|
|
69
|
+
| `pnpm-lock.yaml` `package-lock.json` `yarn.lock` | 锁文件(npm 默认忽略) |
|
|
70
|
+
| `.husky/**` `commitlint.config.*` | Git hook 配置 |
|
|
71
|
+
|
|
72
|
+
## 致命级(任何版本都禁)
|
|
73
|
+
|
|
74
|
+
无论商业 / 开源,下列文件一旦发到 PyPI / npm 都视为**严重事故**,必须立即 `npm unpublish` / 联系 PyPI 删除:
|
|
75
|
+
|
|
76
|
+
| 文件 | 风险 |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `.env*` | 含 API key / DB 密码 / 第三方凭证 |
|
|
79
|
+
| `.npmrc` `.pypirc` `.git-credentials` | 仓库 / 包管理器登录凭证 |
|
|
80
|
+
| `id_rsa` `id_ed25519` `*.pem` `*.key` `*.p12` | SSH / TLS 私钥 |
|
|
81
|
+
| `secrets.json` `credentials.json` `.aws/credentials` | 云服务凭证 |
|
|
82
|
+
| `*.pdb` 含调试源 / `.dSYM` | 调试符号文件 |
|
|
83
|
+
|
|
84
|
+
`check_*_publish.sh` 命中致命级 → 输出 `[CRITICAL]` 并提示用户立即从 registry 下架。
|
|
85
|
+
|
|
86
|
+
## 校验自动化
|
|
87
|
+
|
|
88
|
+
每次 `pre-publish` 钩子建议接 skill:
|
|
89
|
+
|
|
90
|
+
**Python**(`pyproject.toml`):
|
|
91
|
+
|
|
92
|
+
```toml
|
|
93
|
+
# 暂无标准 prepublish hook,推荐 Makefile / justfile
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**npm**(`package.json`):
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"scripts": {
|
|
101
|
+
"prepublishOnly": "pnpm build && npm pack --dry-run && dwy-sdk-spec check"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
(注:`dwy-sdk-spec check` 是未来 CLI 子命令计划,当前在 Claude Code 中触发 skill)
|