@optima-chat/dev-skills 0.5.3 → 0.6.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.
@@ -0,0 +1,172 @@
1
+ # /generate-test-token - 生成测试 Access Token
2
+
3
+ 快速生成一个可用的测试 Access Token,包含完整的账户注册、token 获取和 merchant 设置。
4
+
5
+ **版本**: v0.5.4
6
+
7
+ ## 使用场景
8
+
9
+ **API 测试**: 快速获取可用的 access token 进行 API 调用测试
10
+ **开发调试**: 生成测试账户用于功能开发和调试
11
+ **集成测试**: 在 CI/CD 中自动生成测试账户
12
+
13
+ ## 🎯 使用方式:CLI 工具
14
+
15
+ 使用 `optima-generate-test-token` CLI 工具,它会自动完成所有设置:
16
+
17
+ ```bash
18
+ # Development 环境(默认)
19
+ optima-generate-test-token
20
+
21
+ # Production 环境
22
+ optima-generate-test-token --env production
23
+
24
+ # 自定义商户名称
25
+ optima-generate-test-token --business-name "我的测试店铺" --env production
26
+
27
+ # 完全自定义
28
+ optima-generate-test-token \
29
+ --email "custom@example.com" \
30
+ --password "MyPass123" \
31
+ --business-name "Custom Shop" \
32
+ --phone "+1234567890" \
33
+ --env production
34
+ ```
35
+
36
+ ## 工作流程
37
+
38
+ 该工具会自动完成以下步骤:
39
+
40
+ 1. **注册商家账户** - 在 Auth API 注册 merchant 角色用户
41
+ 2. **获取 Access Token** - 通过 OAuth 2.0 password grant 获取 token
42
+ 3. **设置 Merchant Profile** - 在 Commerce API 创建 merchant 资料
43
+ 4. **保存 Token 到文件** - 将 token 保存到临时文件,避免复制粘贴错误
44
+
45
+ ## 输出内容
46
+
47
+ 工具执行成功后会输出:
48
+
49
+ - 账户邮箱和密码
50
+ - User ID 和 Merchant ID
51
+ - **Token 文件路径**(token 已保存到该文件)
52
+ - 使用示例(包括 commerce CLI 和 curl)
53
+
54
+ ## 使用生成的 Token
55
+
56
+ ### 方式 1: 使用 commerce CLI(推荐)
57
+
58
+ ```bash
59
+ # 读取 token 并使用
60
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
61
+ OPTIMA_ENV=development \
62
+ commerce product list
63
+
64
+ # 创建商品
65
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
66
+ OPTIMA_ENV=development \
67
+ commerce product create \
68
+ --title "测试商品" \
69
+ --price 99.99 \
70
+ --stock 100
71
+ ```
72
+
73
+ ### 方式 2: 使用 curl
74
+
75
+ ```bash
76
+ # 查询商品
77
+ curl -H "Authorization: Bearer $(cat /tmp/optima-test-token-xxx.txt)" \
78
+ https://api.optima.chat/api/products
79
+
80
+ # 查询用户信息
81
+ curl -H "Authorization: Bearer $(cat /tmp/optima-test-token-xxx.txt)" \
82
+ https://auth.optima.chat/api/v1/users/me
83
+ ```
84
+
85
+ ## 命令参数
86
+
87
+ - `--email <email>` - 用户邮箱(默认:自动生成)
88
+ - `--password <password>` - 用户密码(默认:TestPassword123!)
89
+ - `--business-name <name>` - 商户名称(默认:自动生成)
90
+ - `--phone <phone>` - 联系电话(可选)
91
+ - `--address <address>` - 地址(可选)
92
+ - `--env <environment>` - 环境:development(默认)或 production
93
+ - `--help, -h` - 显示帮助信息
94
+
95
+ ## 示例
96
+
97
+ ### 示例 1:快速生成
98
+
99
+ ```bash
100
+ optima-generate-test-token
101
+ ```
102
+
103
+ 输出:
104
+ ```
105
+ ✅ Test token generated successfully!
106
+
107
+ 📋 Details:
108
+ Email: test_1763996983959_wnjt4y@example.com
109
+ Password: TestPassword123!
110
+ User ID: 14bb1340-0ffc-41c8-aac6-c8b7a6bbb1a0
111
+ Role: merchant
112
+ Business Name: Test Merchant 1763996983959
113
+ Merchant ID: 14bb1340-0ffc-41c8-aac6-c8b7a6bbb1a0
114
+
115
+ 📁 Token File Path:
116
+ /tmp/optima-test-token-1763997011780.txt
117
+ ```
118
+
119
+ ### 示例 2:自定义商户信息
120
+
121
+ ```bash
122
+ optima-generate-test-token \
123
+ --business-name "Claude 测试商店" \
124
+ --phone "+8613800138000"
125
+ ```
126
+
127
+ ### 示例 3:使用 token 创建商品
128
+
129
+ ```bash
130
+ # 生成 token
131
+ optima-generate-test-token
132
+
133
+ # 使用 token(复制上面输出的文件路径)
134
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
135
+ OPTIMA_ENV=development \
136
+ commerce product create \
137
+ --title "陶瓷杯" \
138
+ --price 89 \
139
+ --stock 20
140
+ ```
141
+
142
+ ## ⚠️ 注意事项
143
+
144
+ 1. **支持两个环境** - Development(默认)和 Production,通过 `--env` 参数指定
145
+ 2. **Token 有效期** - Token 默认有效期 15 分钟,请及时使用
146
+ 3. **临时文件** - Token 保存在系统临时目录,重启后可能被清理
147
+ 4. **环境变量** - 使用 commerce CLI 时需要设置对应的 `OPTIMA_ENV`(development 或 production)
148
+
149
+ ## 🔗 相关资源
150
+
151
+ - Commerce CLI: https://github.com/Optima-Chat/commerce-cli
152
+ - Auth API Docs: https://auth.optima.chat/docs
153
+ - Commerce API Docs: https://api.optima.chat/docs
154
+
155
+ ## 技术细节
156
+
157
+ **API 调用流程**:
158
+ 1. `POST /api/v1/auth/register/merchant` - 注册商家用户
159
+ 2. `POST /api/v1/oauth/token` - 获取 access token(password grant)
160
+ 3. `POST /api/merchants/me` - 设置 merchant profile
161
+
162
+ **环境配置**:
163
+
164
+ | 环境 | Auth API | Commerce API | Client ID |
165
+ |------|----------|--------------|-----------|
166
+ | Development(默认) | auth.optima.chat | api.optima.chat | dev-skill-cli-he7fjmsp |
167
+ | Production | auth.optima.shop | api.optima.shop | dev-skill-cli-0cyyqxox |
168
+
169
+ **默认 Merchant 信息**:
170
+ - 发货地址:中国深圳南山区科技园
171
+ - 联系电话:+8613800138000
172
+ - 联系邮箱:test@example.com
@@ -22,13 +22,14 @@
22
22
  "Bash(aws logs get-log-events:*)",
23
23
  "Bash(npm install:*)",
24
24
  "Bash(optima-dev-skills:*)",
25
+ "Bash(optima-generate-test-token:*)",
26
+ "Bash(optima-query-db:*)",
25
27
  "Bash(gh variable set:*)",
26
28
  "Bash(npm publish:*)",
27
- "Bash(curl -s \"https://secrets.optima.onl/api/v3/secrets/raw?workspaceId=f2415dc2-f79d-4e41-90bb-cd3d2631ec71&environment=staging&secretPath=/infrastructure\" -H \"Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eUlkIjoiMjZiNmYxMmItZjNjYy00OTE2LTliMTItNWFiYzZhMTlmNGI0IiwiY2xpZW50U2VjcmV0SWQiOiIxZjRhM2I0Ni03NTZmLTQwNmItOGQ1OS0yODI0YjUzOGFlMmMiLCJpZGVudGl0eUFjY2Vzc1Rva2VuSWQiOiJlMDQ1Y2MyOC02Nzk5LTRhODYtYWEwNy02YTQ4NmZkYzczODgiLCJhdXRoVG9rZW5UeXBlIjoiaWRlbnRpdHlBY2Nlc3NUb2tlbiIsImlhdCI6MTc2MzkxMzAxNywiZXhwIjoxNzY2NTA1MDE3fQ.xkPyv9MwXKLg3t-h1C_6mHSV5-cFuuvHnrkOoaGtuaQ\")",
28
29
  "Bash(python3:*)",
29
- "Bash(curl -s \"https://secrets.optima.onl/api/v1/folders?workspaceId=f2415dc2-f79d-4e41-90bb-cd3d2631ec71&environment=prod\" -H \"Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eUlkIjoiMjZiNmYxMmItZjNjYy00OTE2LTliMTItNWFiYzZhMTlmNGI0IiwiY2xpZW50U2VjcmV0SWQiOiIxZjRhM2I0Ni03NTZmLTQwNmItOGQ1OS0yODI0YjUzOGFlMmMiLCJpZGVudGl0eUFjY2Vzc1Rva2VuSWQiOiJlMDQ1Y2MyOC02Nzk5LTRhODYtYWEwNy02YTQ4NmZkYzczODgiLCJhdXRoVG9rZW5UeXBlIjoiaWRlbnRpdHlBY2Nlc3NUb2tlbiIsImlhdCI6MTc2MzkxMzAxNywiZXhwIjoxNzY2NTA1MDE3fQ.xkPyv9MwXKLg3t-h1C_6mHSV5-cFuuvHnrkOoaGtuaQ\")",
30
- "Bash(curl -s \"https://secrets.optima.onl/api/v3/secrets/raw?workspaceId=f2415dc2-f79d-4e41-90bb-cd3d2631ec71&environment=prod&secretPath=/infrastructure\" -H \"Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eUlkIjoiMjZiNmYxMmItZjNjYy00OTE2LTliMTItNWFiYzZhMTlmNGI0IiwiY2xpZW50U2VjcmV0SWQiOiIxZjRhM2I0Ni03NTZmLTQwNmItOGQ1OS0yODI0YjUzOGFlMmMiLCJpZGVudGl0eUFjY2Vzc1Rva2VuSWQiOiJlMDQ1Y2MyOC02Nzk5LTRhODYtYWEwNy02YTQ4NmZkYzczODgiLCJhdXRoVG9rZW5UeXBlIjoiaWRlbnRpdHlBY2Nlc3NUb2tlbiIsImlhdCI6MTc2MzkxMzAxNywiZXhwIjoxNzY2NTA1MDE3fQ.xkPyv9MwXKLg3t-h1C_6mHSV5-cFuuvHnrkOoaGtuaQ\")",
31
- "Bash(gh api:*)"
30
+ "Bash(gh api:*)",
31
+ "Bash(curl -s http://auth.optima.chat/openapi.json)",
32
+ "Bash(curl -s https://auth.optima.chat/openapi.json)"
32
33
  ],
33
34
  "deny": [],
34
35
  "ask": []
@@ -0,0 +1,316 @@
1
+ ---
2
+ name: "generate-test-token"
3
+ description: "当用户请求生成测试 token、创建测试账户、获取 access token、需要测试 API、API 测试、测试账户时,使用此技能。自动完成账户注册、token 获取和 merchant 设置。"
4
+ allowed-tools: ["Bash", "SlashCommand"]
5
+ ---
6
+
7
+ # 生成测试 Access Token
8
+
9
+ 当你需要为 API 测试生成一个可用的 access token 时,使用这个场景。
10
+
11
+ ## 🎯 执行方式:使用 CLI 工具
12
+
13
+ **重要**:无论用户使用 `/generate-test-token` 命令还是直接请求生成测试 token,都应该使用 `optima-generate-test-token` CLI 工具:
14
+
15
+ ```bash
16
+ optima-generate-test-token [options]
17
+ ```
18
+
19
+ **为什么使用 CLI 工具**:
20
+ - ✅ 自动注册商家账户(Auth API)
21
+ - ✅ 自动获取 OAuth access token
22
+ - ✅ 自动设置 merchant profile(Commerce API)
23
+ - ✅ Token 保存到文件,避免复制错误
24
+ - ✅ 一条命令完成所有设置
25
+
26
+ ## 🎯 适用情况
27
+
28
+ - 需要测试 Commerce API 或 Auth API
29
+ - 开发新功能需要测试账户
30
+ - 调试 API 调用问题
31
+ - CI/CD 集成测试
32
+ - 演示功能需要临时账户
33
+
34
+ ## 🚀 快速操作
35
+
36
+ ### 基本使用
37
+
38
+ ```bash
39
+ # Development 环境(默认)
40
+ optima-generate-test-token
41
+
42
+ # Production 环境
43
+ optima-generate-test-token --env production
44
+
45
+ # 自定义商户名称
46
+ optima-generate-test-token --business-name "我的测试店铺" --env production
47
+
48
+ # 完全自定义
49
+ optima-generate-test-token \
50
+ --email "test@example.com" \
51
+ --password "MyPassword123" \
52
+ --business-name "测试商店" \
53
+ --env production
54
+ ```
55
+
56
+ ### 使用生成的 Token
57
+
58
+ 工具执行后会输出 token 文件路径,例如:`/tmp/optima-test-token-1763997011780.txt`
59
+
60
+ **方式 1: 使用 commerce CLI**
61
+
62
+ ```bash
63
+ # 查询商品列表
64
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
65
+ OPTIMA_ENV=development \
66
+ commerce product list
67
+
68
+ # 创建商品
69
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
70
+ OPTIMA_ENV=development \
71
+ commerce product create \
72
+ --title "测试商品" \
73
+ --description "这是一个测试商品" \
74
+ --price 99.99 \
75
+ --stock 100 \
76
+ --currency USD \
77
+ --status active
78
+ ```
79
+
80
+ **方式 2: 使用 curl**
81
+
82
+ ```bash
83
+ # 查询用户信息
84
+ curl -H "Authorization: Bearer $(cat /tmp/optima-test-token-xxx.txt)" \
85
+ https://auth.optima.chat/api/v1/users/me
86
+
87
+ # 查询商品
88
+ curl -H "Authorization: Bearer $(cat /tmp/optima-test-token-xxx.txt)" \
89
+ https://api.optima.chat/api/products
90
+ ```
91
+
92
+ ## 📋 常见使用场景
93
+
94
+ ### 场景 1:快速 API 测试
95
+
96
+ **用户请求**:"我需要测试一下商品创建 API"
97
+
98
+ **步骤**:
99
+ 1. 生成 token:`optima-generate-test-token`
100
+ 2. 记录输出的 token 文件路径
101
+ 3. 使用 token 创建商品:
102
+ ```bash
103
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
104
+ OPTIMA_ENV=development \
105
+ commerce product create --title "测试商品" --price 99.99 --stock 100
106
+ ```
107
+
108
+ ### 场景 2:调试 API 调用
109
+
110
+ **用户请求**:"帮我生成一个测试账户,我要调试订单 API"
111
+
112
+ **步骤**:
113
+ 1. 生成测试账户和 token:`optima-generate-test-token --business-name "订单测试店铺"`
114
+ 2. 保存输出的账户信息(email, password, merchant_id)
115
+ 3. 使用 token 查询订单:
116
+ ```bash
117
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
118
+ OPTIMA_ENV=development \
119
+ commerce order list
120
+ ```
121
+
122
+ ### 场景 3:演示功能
123
+
124
+ **用户请求**:"创建一个演示账户,我要展示商品管理功能"
125
+
126
+ **步骤**:
127
+ 1. 生成演示账户:`optima-generate-test-token --business-name "演示商店"`
128
+ 2. 使用 token 创建演示数据:
129
+ ```bash
130
+ TOKEN_FILE=/tmp/optima-test-token-xxx.txt
131
+
132
+ # 创建多个商品
133
+ OPTIMA_TOKEN=$(cat $TOKEN_FILE) OPTIMA_ENV=development \
134
+ commerce product create --title "商品A" --price 49.99 --stock 50
135
+
136
+ OPTIMA_TOKEN=$(cat $TOKEN_FILE) OPTIMA_ENV=development \
137
+ commerce product create --title "商品B" --price 89.99 --stock 30
138
+ ```
139
+
140
+ ### 场景 4:CI/CD 集成测试
141
+
142
+ **用户请求**:"在 CI 环境中自动生成测试账户"
143
+
144
+ **步骤**:
145
+ 1. 在 CI 脚本中调用:
146
+ ```bash
147
+ # 生成 token 并保存路径
148
+ TOKEN_OUTPUT=$(optima-generate-test-token 2>&1)
149
+ TOKEN_FILE=$(echo "$TOKEN_OUTPUT" | grep "Token File Path" -A 1 | tail -1 | xargs)
150
+
151
+ # 在环境变量中设置
152
+ export OPTIMA_TOKEN=$(cat $TOKEN_FILE)
153
+ export OPTIMA_ENV=development
154
+
155
+ # 运行测试
156
+ npm run test:api
157
+ ```
158
+
159
+ ## 📋 工具输出说明
160
+
161
+ 成功执行后会输出:
162
+
163
+ ```
164
+ ✅ Test token generated successfully!
165
+
166
+ 📋 Details:
167
+ Email: test_1763996983959_wnjt4y@example.com
168
+ Password: TestPassword123!
169
+ User ID: 14bb1340-0ffc-41c8-aac6-c8b7a6bbb1a0
170
+ Role: merchant
171
+ Business Name: Test Merchant 1763996983959
172
+ Merchant ID: 14bb1340-0ffc-41c8-aac6-c8b7a6bbb1a0
173
+
174
+ 📁 Token File Path:
175
+ /tmp/optima-test-token-1763997011780.txt
176
+
177
+ 💡 Usage Examples:
178
+ # Read token from file:
179
+ TOKEN=$(cat /tmp/optima-test-token-1763997011780.txt)
180
+
181
+ # Use with commerce CLI:
182
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-1763997011780.txt) OPTIMA_ENV=development commerce product list
183
+
184
+ # Use in curl:
185
+ curl -H "Authorization: Bearer $(cat /tmp/optima-test-token-1763997011780.txt)" https://api.optima.chat/api/products
186
+ ```
187
+
188
+ **关键信息**:
189
+ - **Email/Password**: 账户登录凭证,可用于后续登录
190
+ - **Merchant ID**: 商户 ID,部分 API 可能需要
191
+ - **Token File Path**: Token 文件路径,这是最重要的信息!
192
+
193
+ ## ⚠️ 注意事项
194
+
195
+ ### 环境设置
196
+
197
+ 使用 commerce CLI 时**必须**设置环境变量:
198
+ ```bash
199
+ OPTIMA_ENV=development # 必需,指定 development 环境
200
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) # 必需,读取 token
201
+ ```
202
+
203
+ ### Token 有效期
204
+
205
+ - Token 默认有效期为 **15 分钟**
206
+ - 如果 token 过期,重新运行 `optima-generate-test-token` 即可
207
+ - 错误信息:"Invalid or expired token"
208
+
209
+ ### 文件管理
210
+
211
+ - Token 保存在系统临时目录(`/tmp/` 或 `/var/folders/...`)
212
+ - 系统重启后可能被清理
213
+ - 建议在使用完成后手动删除敏感文件
214
+
215
+ ### 只能用于开发环境
216
+
217
+ - 生成的账户注册到 **development 环境**
218
+ - API 地址:
219
+ - Auth: `https://auth.optima.chat`
220
+ - Commerce: `https://api.optima.chat`
221
+ - **不能用于** production 或 stage 环境
222
+
223
+ ## 💡 最佳实践
224
+
225
+ ### 1. Token 文件路径管理
226
+
227
+ ```bash
228
+ # 方法 1:直接从输出复制路径
229
+ optima-generate-test-token
230
+ # 复制输出中的 "Token File Path"
231
+
232
+ # 方法 2:保存到变量
233
+ TOKEN_FILE=$(optima-generate-test-token 2>&1 | grep "Token File Path" -A 1 | tail -1 | xargs)
234
+ OPTIMA_TOKEN=$(cat "$TOKEN_FILE")
235
+ ```
236
+
237
+ ### 2. 重复使用同一个 token
238
+
239
+ ```bash
240
+ # 将 token 路径保存到环境变量
241
+ export TOKEN_FILE=/tmp/optima-test-token-1763997011780.txt
242
+
243
+ # 后续使用
244
+ OPTIMA_TOKEN=$(cat $TOKEN_FILE) OPTIMA_ENV=development commerce product list
245
+ OPTIMA_TOKEN=$(cat $TOKEN_FILE) OPTIMA_ENV=development commerce order list
246
+ ```
247
+
248
+ ### 3. 自定义账户信息(可选)
249
+
250
+ 只有在需要特定账户信息时才自定义:
251
+
252
+ ```bash
253
+ # 自定义商户名称
254
+ optima-generate-test-token --business-name "我的专属测试店铺"
255
+
256
+ # 完全自定义(适合重复测试)
257
+ optima-generate-test-token \
258
+ --email "mytest@example.com" \
259
+ --password "MyStrongPassword123!" \
260
+ --business-name "固定测试店铺"
261
+ ```
262
+
263
+ ### 4. 清理测试数据
264
+
265
+ ```bash
266
+ # 测试完成后删除 token 文件
267
+ rm /tmp/optima-test-token-*.txt
268
+ ```
269
+
270
+ ## 🔧 故障排查
271
+
272
+ ### 问题 1:Token 无效
273
+
274
+ **错误信息**: "Invalid or expired token"
275
+
276
+ **解决方案**:
277
+ - Token 已过期(15分钟),重新生成
278
+ - 环境变量设置错误,检查 `OPTIMA_ENV=development`
279
+ - Token 文件路径错误,检查文件是否存在
280
+
281
+ ### 问题 2:Merchant profile 未设置
282
+
283
+ **错误信息**: "Merchant profile setup required"
284
+
285
+ **解决方案**:
286
+ - 这不应该发生,工具会自动设置
287
+ - 检查工具输出是否显示 "✓ Merchant profile setup complete"
288
+ - 如果没有,可能是网络问题,重新运行
289
+
290
+ ### 问题 3:命令不存在
291
+
292
+ **错误信息**: "command not found: optima-generate-test-token"
293
+
294
+ **解决方案**:
295
+ ```bash
296
+ # 安装或更新工具
297
+ npm install -g @optima-chat/dev-skills@latest
298
+
299
+ # 或本地使用
300
+ npx @optima-chat/dev-skills generate-test-token
301
+ ```
302
+
303
+ ## 🔗 相关命令
304
+
305
+ - `optima-generate-test-token` - CLI 生成工具(主要方式)
306
+ - `/generate-test-token` - Slash 命令(备用方式,详细使用方法请查看 `/generate-test-token --help`)
307
+ - `commerce auth login` - Commerce CLI 登录
308
+ - `commerce product create` - 创建商品
309
+ - `commerce order list` - 查询订单
310
+
311
+ ## 📚 更多资源
312
+
313
+ - **Commerce CLI**: https://github.com/Optima-Chat/commerce-cli
314
+ - **Auth API Docs**: https://auth.optima.chat/docs
315
+ - **Commerce API Docs**: https://api.optima.chat/docs
316
+ - **OAuth 2.0 文档**: https://auth.optima.chat/docs#/OAuth%202.0
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: "use-commerce-cli"
3
+ description: "当用户需要管理电商店铺(商品、订单、库存、运费、集合、首页、国际化)时,使用此技能。"
4
+ allowed-tools: ["Bash"]
5
+ ---
6
+
7
+ # 使用 Commerce CLI
8
+
9
+ ## 何时使用
10
+
11
+ 用户需要管理电商功能:商品、订单、库存、运费、集合、首页、国际化。
12
+
13
+ ## 前提
14
+
15
+ 用户已有 access token(通过 `optima-generate-test-token` 生成)。
16
+
17
+ ## Token 传递方式
18
+
19
+ **必须**同时设置 `OPTIMA_TOKEN` 和 `OPTIMA_ENV`:
20
+
21
+ ```bash
22
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
23
+ OPTIMA_ENV=development \
24
+ commerce <command>
25
+ ```
26
+
27
+ ## 示例
28
+
29
+ ```bash
30
+ # 创建商品
31
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
32
+ OPTIMA_ENV=development \
33
+ commerce product create --title "测试商品" --price 99.99 --stock 100
34
+
35
+ # 查询商品
36
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
37
+ OPTIMA_ENV=development \
38
+ commerce product list
39
+
40
+ # 查询订单
41
+ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
42
+ OPTIMA_ENV=development \
43
+ commerce order list
44
+ ```
45
+
46
+ ## 安装项目 Skills(可选)
47
+
48
+ ```bash
49
+ commerce init
50
+ ```
51
+
52
+ 在 `.claude/skills/` 安装完整 Skills,之后可用自然语言管理店铺。
53
+
54
+ ## 环境说明
55
+
56
+ `optima-generate-test-token` 支持两个环境:
57
+
58
+ **Development**(默认):
59
+ - API: `api.optima.chat`
60
+ - 环境变量:`OPTIMA_ENV=development`
61
+
62
+ **Production**(使用 `--env production`):
63
+ - API: `api.optima.shop`
64
+ - 环境变量:`OPTIMA_ENV=production`
package/README.md CHANGED
@@ -23,12 +23,14 @@ Optima Dev Skills 让 Claude Code 能够直接在 **CI、Stage、Prod** 三个
23
23
  - **任务驱动** - 基于具体任务场景(查看日志、调用 API),不是抽象分类
24
24
  - **跨环境协作** - 统一的命令在 CI、Stage、Prod 三个环境中使用
25
25
 
26
- ## 📋 任务场景(2 个)
26
+ ## 📋 任务场景(4 个)
27
27
 
28
28
  当 Claude Code 识别到以下任务时,会自动加载对应的 Skill:
29
29
 
30
30
  - **logs** - 查看 CI/Stage/Prod 的服务器日志
31
31
  - **query-db** - 查询 CI/Stage/Prod 的数据库
32
+ - **generate-test-token** - 生成测试 Access Token 用于 API 测试
33
+ - **use-commerce-cli** - 使用 Commerce CLI 管理电商店铺
32
34
 
33
35
  ## 👤 用户故事
34
36
 
@@ -72,10 +74,12 @@ Claude:
72
74
  |------|------|------|--------|
73
75
  | `/logs` | 查看服务日志 | `/logs commerce-backend 100` | ✅ |
74
76
  | `/query-db` | 查询数据库 | `/query-db user-auth "SELECT COUNT(*) FROM users"` | ✅ |
77
+ | `/generate-test-token` | 生成测试 token | `/generate-test-token` | 🔧 Development |
75
78
 
76
79
  **说明**:
77
80
  - 命令支持 CI、Stage、Prod 三个环境
78
81
  - 默认使用 CI 环境,适合日常开发
82
+ - `/generate-test-token` 生成的账户用于 development 环境(api.optima.chat)
79
83
  - Claude Code 会根据上下文自动选择环境和执行方式
80
84
 
81
85
  ## 🛠️ CLI 工具
@@ -85,12 +89,14 @@ Claude:
85
89
  | 工具 | 说明 | 示例 |
86
90
  |------|------|------|
87
91
  | `optima-query-db` | 数据库查询工具 | `optima-query-db user-auth "SELECT COUNT(*) FROM users" prod` |
92
+ | `optima-generate-test-token` | 生成测试 token | `optima-generate-test-token --business-name "测试店铺"` |
88
93
 
89
94
  **特点**:
90
- - ✅ 支持 CI、Stage、Prod 三个环境
95
+ - ✅ 支持 CI、Stage、Prod 三个环境(query-db)
91
96
  - ✅ 自动管理 SSH 隧道和密钥
92
97
  - ✅ 可在任何终端直接使用
93
- - ✅ Claude Code `/query-db` 命令内部也使用此工具
98
+ - ✅ 自动注册账户、获取 token、设置 merchant profile(generate-test-token)
99
+ - ✅ Claude Code 的命令内部也使用这些工具
94
100
 
95
101
  ## 🏗️ 项目结构
96
102
 
@@ -98,14 +104,20 @@ Claude:
98
104
  optima-dev-skills/
99
105
  ├── .claude/
100
106
  │ ├── commands/
101
- │ │ ├── logs.md # /logs - 查看服务日志
102
- │ │ └── query-db.md # /query-db - 查询数据库
107
+ │ │ ├── logs.md # /logs - 查看服务日志
108
+ │ │ ├── query-db.md # /query-db - 查询数据库
109
+ │ │ └── generate-test-token.md # /generate-test-token - 生成测试 token
103
110
  │ │
104
111
  │ └── skills/
105
- │ ├── logs/ # 日志查看 skill
106
- │ └── SKILL.md
107
- └── query-db/ # 数据库查询 skill
108
- └── SKILL.md
112
+ │ ├── logs/ # 日志查看 skill
113
+ ├── query-db/ # 数据库查询 skill
114
+ ├── generate-test-token/ # 测试 token 生成 skill
115
+ └── use-commerce-cli/ # Commerce CLI 使用 skill
116
+
117
+ ├── bin/
118
+ │ └── helpers/
119
+ │ ├── query-db.ts # CLI: 数据库查询
120
+ │ └── generate-test-token.ts # CLI: 生成测试 token
109
121
 
110
122
  └── docs/
111
123
  └── COMMANDS_DESIGN.md
@@ -127,22 +139,35 @@ Claude:
127
139
  3. 问题定位:Stage RDS 连接配置问题
128
140
  ```
129
141
 
130
- ### 示例 2:使用 CLI 工具快速查询
142
+ ### 示例 2:生成测试 token 并管理店铺
131
143
 
132
144
  ```bash
133
- # 查询 Prod 用户数
134
- $ optima-query-db user-auth "SELECT COUNT(*) FROM users" prod
145
+ # 1. 生成测试 token
146
+ $ optima-generate-test-token
147
+
148
+ ✅ Test token generated successfully!
149
+ 📁 Token File Path: /tmp/optima-test-token-xxx.txt
150
+
151
+ # 2. 使用 token 创建商品
152
+ $ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
153
+ OPTIMA_ENV=development \
154
+ commerce product create --title "测试商品" --price 99.99 --stock 100
155
+
156
+ {
157
+ "success": true,
158
+ "data": {
159
+ "product_id": "xxx",
160
+ "name": "测试商品",
161
+ "price": "99.99"
162
+ }
163
+ }
164
+ ```
135
165
 
136
- 🔍 Querying user-auth (PROD)...
137
- ✓ Loaded Infisical config from GitHub Variables
138
- ✓ Obtained Infisical access token
139
- ✓ Retrieved database credentials from Infisical
140
- ✓ SSH tunnel established on port 15433
166
+ ### 示例 3:使用 CLI 工具快速查询
141
167
 
142
- count
143
- -------
144
- 26
145
- (1 行记录)
168
+ ```bash
169
+ # 查询 Prod 用户数
170
+ $ optima-query-db user-auth "SELECT COUNT(*) FROM users" prod
146
171
 
147
172
  # 查询 Stage 商品列表
148
173
  $ optima-query-db commerce-backend "SELECT id, title FROM products LIMIT 5" stage
@@ -197,16 +222,17 @@ $ optima-query-db commerce-backend "SELECT id, title FROM products LIMIT 5" stag
197
222
 
198
223
  ## 🛠️ 开发状态
199
224
 
200
- **当前版本**: 0.5.0
225
+ **当前版本**: 0.5.4
201
226
 
202
227
  **已完成**:
203
- - ✅ 2 个跨环境命令:`/logs`、`/query-db`
204
- - ✅ 2 个任务场景:`logs` skill、`query-db` skill
228
+ - ✅ 3 个跨环境命令:`/logs`、`/query-db`、`/generate-test-token`
229
+ - ✅ 4 个任务场景:`logs`、`query-db`、`generate-test-token`、`use-commerce-cli`
205
230
  - ✅ 支持 CI、Stage、Prod 三个环境
206
231
  - ✅ CI 环境通过 SSH + Docker 访问
207
232
  - ✅ Stage/Prod 通过 SSH 隧道访问 RDS
208
- - ✅ TypeScript CLI 工具:`optima-query-db`
233
+ - ✅ TypeScript CLI 工具:`optima-query-db`、`optima-generate-test-token`
209
234
  - ✅ 通过 Infisical 动态获取密钥
235
+ - ✅ 自动生成测试 token 并设置 merchant profile
210
236
 
211
237
  **设计原则**:
212
238
  - 命令提供信息(URL、路径、凭证位置),不实现复杂逻辑
@@ -0,0 +1,273 @@
1
+ #!/usr/bin/env node
2
+
3
+ import * as fs from 'fs';
4
+ import * as os from 'os';
5
+ import * as path from 'path';
6
+
7
+ interface RegisterResponse {
8
+ email: string;
9
+ user_id: string;
10
+ role: string;
11
+ is_active: boolean;
12
+ created_at: string;
13
+ updated_at: string;
14
+ }
15
+
16
+ interface TokenResponse {
17
+ access_token: string;
18
+ token_type: string;
19
+ }
20
+
21
+ interface MerchantSetupResponse {
22
+ merchant_id: string;
23
+ business_name: string;
24
+ user_id: string;
25
+ }
26
+
27
+ type Environment = 'development' | 'production';
28
+
29
+ interface EnvironmentConfig {
30
+ authUrl: string;
31
+ apiUrl: string;
32
+ clientId: string;
33
+ envName: string;
34
+ }
35
+
36
+ const ENV_CONFIG: Record<Environment, EnvironmentConfig> = {
37
+ development: {
38
+ authUrl: 'https://auth.optima.chat',
39
+ apiUrl: 'https://api.optima.chat',
40
+ clientId: 'dev-skill-cli-he7fjmsp',
41
+ envName: 'development'
42
+ },
43
+ production: {
44
+ authUrl: 'https://auth.optima.shop',
45
+ apiUrl: 'https://api.optima.shop',
46
+ clientId: 'dev-skill-cli-0cyyqxox',
47
+ envName: 'production'
48
+ }
49
+ };
50
+
51
+ async function httpRequest<T>(url: string, options: RequestInit = {}): Promise<T> {
52
+ const response = await fetch(url, {
53
+ ...options,
54
+ headers: {
55
+ 'Content-Type': 'application/json',
56
+ ...options.headers
57
+ }
58
+ });
59
+
60
+ if (!response.ok) {
61
+ const text = await response.text();
62
+ throw new Error(`HTTP ${response.status}: ${text}`);
63
+ }
64
+
65
+ return response.json() as Promise<T>;
66
+ }
67
+
68
+ async function registerMerchant(
69
+ email: string,
70
+ password: string,
71
+ businessName: string,
72
+ config: EnvironmentConfig,
73
+ phone?: string,
74
+ address?: string
75
+ ): Promise<RegisterResponse> {
76
+ console.log(`\n📝 Registering merchant: ${email}...`);
77
+
78
+ const payload: any = { email, password, business_name: businessName };
79
+ if (phone) payload.phone = phone;
80
+ if (address) payload.address = address;
81
+
82
+ try {
83
+ const result = await httpRequest<RegisterResponse>(`${config.authUrl}/api/v1/auth/register/merchant`, {
84
+ method: 'POST',
85
+ body: JSON.stringify(payload)
86
+ });
87
+
88
+ console.log(`✓ Merchant registered successfully (ID: ${result.user_id})`);
89
+ return result;
90
+ } catch (error: any) {
91
+ if (error.message.includes('409') || error.message.includes('already exists')) {
92
+ console.log(`ℹ Merchant already exists, proceeding to login...`);
93
+ return { email, user_id: '', role: 'merchant', is_active: true, created_at: '', updated_at: '' };
94
+ }
95
+ throw error;
96
+ }
97
+ }
98
+
99
+ async function getToken(email: string, password: string, config: EnvironmentConfig): Promise<string> {
100
+ console.log(`\n🔑 Obtaining access token...`);
101
+
102
+ const formData = new URLSearchParams();
103
+ formData.append('username', email);
104
+ formData.append('password', password);
105
+ formData.append('grant_type', 'password');
106
+ formData.append('client_id', config.clientId);
107
+
108
+ const result = await httpRequest<TokenResponse>(`${config.authUrl}/api/v1/oauth/token`, {
109
+ method: 'POST',
110
+ headers: {
111
+ 'Content-Type': 'application/x-www-form-urlencoded'
112
+ },
113
+ body: formData.toString()
114
+ });
115
+
116
+ console.log(`✓ Access token obtained`);
117
+ return result.access_token;
118
+ }
119
+
120
+ async function setupMerchantProfile(token: string, businessName: string, config: EnvironmentConfig): Promise<MerchantSetupResponse> {
121
+ console.log(`\n🏪 Setting up merchant profile in Commerce API...`);
122
+
123
+ const payload = {
124
+ name: businessName,
125
+ origin_country_alpha2: 'CN',
126
+ origin_city: '深圳',
127
+ origin_state: '广东省',
128
+ origin_line_1: '南山区科技园',
129
+ contact_name: '测试用户',
130
+ contact_phone: '+8613800138000',
131
+ contact_email: 'test@example.com'
132
+ };
133
+
134
+ try {
135
+ const result = await httpRequest<MerchantSetupResponse>(`${config.apiUrl}/api/merchants/me`, {
136
+ method: 'POST',
137
+ headers: {
138
+ Authorization: `Bearer ${token}`
139
+ },
140
+ body: JSON.stringify(payload)
141
+ });
142
+
143
+ console.log(`✓ Merchant profile setup complete (ID: ${result.merchant_id})`);
144
+ return result;
145
+ } catch (error: any) {
146
+ if (error.message.includes('409') || error.message.includes('already exists')) {
147
+ console.log(`ℹ Merchant profile already exists`);
148
+ return { merchant_id: '', business_name: businessName, user_id: '' };
149
+ }
150
+ throw error;
151
+ }
152
+ }
153
+
154
+ async function main() {
155
+ const args = process.argv.slice(2);
156
+
157
+ // 生成随机测试账户
158
+ const timestamp = Date.now();
159
+ const randomStr = Math.random().toString(36).substring(2, 8);
160
+ const defaultEmail = `test_${timestamp}_${randomStr}@example.com`;
161
+ const defaultPassword = 'TestPassword123!';
162
+ const defaultBusinessName = `Test Merchant ${timestamp}`;
163
+
164
+ let email = defaultEmail;
165
+ let password = defaultPassword;
166
+ let businessName = defaultBusinessName;
167
+ let phone: string | undefined;
168
+ let address: string | undefined;
169
+ let environment: Environment = 'development';
170
+
171
+ // 解析命令行参数
172
+ for (let i = 0; i < args.length; i++) {
173
+ const arg = args[i];
174
+
175
+ if (arg === '--email' && args[i + 1]) {
176
+ email = args[++i];
177
+ } else if (arg === '--password' && args[i + 1]) {
178
+ password = args[++i];
179
+ } else if (arg === '--business-name' && args[i + 1]) {
180
+ businessName = args[++i];
181
+ } else if (arg === '--phone' && args[i + 1]) {
182
+ phone = args[++i];
183
+ } else if (arg === '--address' && args[i + 1]) {
184
+ address = args[++i];
185
+ } else if (arg === '--env' && args[i + 1]) {
186
+ const envArg = args[++i];
187
+ if (envArg === 'development' || envArg === 'production') {
188
+ environment = envArg;
189
+ } else {
190
+ console.error(`❌ Invalid environment: ${envArg}. Must be 'development' or 'production'.`);
191
+ process.exit(1);
192
+ }
193
+ } else if (arg === '--help' || arg === '-h') {
194
+ console.log(`
195
+ Usage: generate-test-token [options]
196
+
197
+ Options:
198
+ --email <email> User email (default: auto-generated)
199
+ --password <password> User password (default: TestPassword123!)
200
+ --business-name <name> Merchant business name (default: auto-generated)
201
+ --phone <phone> Merchant phone number (optional)
202
+ --address <address> Merchant address (optional)
203
+ --env <environment> Environment: development (default) or production
204
+ --help, -h Show this help message
205
+
206
+ Example:
207
+ generate-test-token
208
+ generate-test-token --env production
209
+ generate-test-token --business-name "My Test Shop" --phone "+1234567890"
210
+ generate-test-token --email "custom@example.com" --password "MyPass123" --env production
211
+ `);
212
+ process.exit(0);
213
+ }
214
+ }
215
+
216
+ const config = ENV_CONFIG[environment];
217
+
218
+ try {
219
+ console.log('🚀 Starting test token generation...\n');
220
+ console.log(`Environment: ${config.envName}`);
221
+ console.log(`Auth API: ${config.authUrl}`);
222
+ console.log(`Commerce API: ${config.apiUrl}\n`);
223
+ console.log(`Using credentials:`);
224
+ console.log(` Email: ${email}`);
225
+ console.log(` Password: ${password}`);
226
+ console.log(` Business Name: ${businessName}`);
227
+
228
+ // 1. 注册 merchant(直接注册为商家)
229
+ const user = await registerMerchant(email, password, businessName, config, phone, address);
230
+
231
+ // 2. 获取 token
232
+ const token = await getToken(email, password, config);
233
+
234
+ // 3. 设置 merchant profile(Commerce API)
235
+ const merchantProfile = await setupMerchantProfile(token, businessName, config);
236
+
237
+ // 4. 保存 token 到临时文件
238
+ const tmpDir = os.tmpdir();
239
+ const tokenFileName = `optima-test-token-${Date.now()}.txt`;
240
+ const tokenFilePath = path.join(tmpDir, tokenFileName);
241
+
242
+ fs.writeFileSync(tokenFilePath, token, 'utf-8');
243
+ console.log(`\n💾 Token saved to temporary file`);
244
+
245
+ // 输出结果
246
+ console.log('\n' + '='.repeat(80));
247
+ console.log('✅ Test token generated successfully!\n');
248
+ console.log('📋 Details:');
249
+ console.log(` Environment: ${config.envName}`);
250
+ console.log(` Email: ${email}`);
251
+ console.log(` Password: ${password}`);
252
+ console.log(` User ID: ${user.user_id || 'N/A'}`);
253
+ console.log(` Role: ${user.role}`);
254
+ console.log(` Business Name: ${businessName}`);
255
+ console.log(` Merchant ID: ${merchantProfile.merchant_id || 'N/A'}\n`);
256
+ console.log('📁 Token File Path:');
257
+ console.log(` ${tokenFilePath}\n`);
258
+ console.log('💡 Usage Examples:');
259
+ console.log(` # Read token from file:`);
260
+ console.log(` TOKEN=$(cat ${tokenFilePath})\n`);
261
+ console.log(` # Use with commerce CLI:`);
262
+ console.log(` OPTIMA_TOKEN=$(cat ${tokenFilePath}) OPTIMA_ENV=${config.envName} commerce product list\n`);
263
+ console.log(` # Use in curl:`);
264
+ console.log(` curl -H "Authorization: Bearer $(cat ${tokenFilePath})" ${config.apiUrl}/api/products\n`);
265
+ console.log('='.repeat(80));
266
+
267
+ } catch (error: any) {
268
+ console.error('\n❌ Error:', error.message);
269
+ process.exit(1);
270
+ }
271
+ }
272
+
273
+ main();
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const ENV_CONFIG = {
41
+ development: {
42
+ authUrl: 'https://auth.optima.chat',
43
+ apiUrl: 'https://api.optima.chat',
44
+ clientId: 'dev-skill-cli-he7fjmsp',
45
+ envName: 'development'
46
+ },
47
+ production: {
48
+ authUrl: 'https://auth.optima.shop',
49
+ apiUrl: 'https://api.optima.shop',
50
+ clientId: 'dev-skill-cli-0cyyqxox',
51
+ envName: 'production'
52
+ }
53
+ };
54
+ async function httpRequest(url, options = {}) {
55
+ const response = await fetch(url, {
56
+ ...options,
57
+ headers: {
58
+ 'Content-Type': 'application/json',
59
+ ...options.headers
60
+ }
61
+ });
62
+ if (!response.ok) {
63
+ const text = await response.text();
64
+ throw new Error(`HTTP ${response.status}: ${text}`);
65
+ }
66
+ return response.json();
67
+ }
68
+ async function registerMerchant(email, password, businessName, config, phone, address) {
69
+ console.log(`\n📝 Registering merchant: ${email}...`);
70
+ const payload = { email, password, business_name: businessName };
71
+ if (phone)
72
+ payload.phone = phone;
73
+ if (address)
74
+ payload.address = address;
75
+ try {
76
+ const result = await httpRequest(`${config.authUrl}/api/v1/auth/register/merchant`, {
77
+ method: 'POST',
78
+ body: JSON.stringify(payload)
79
+ });
80
+ console.log(`✓ Merchant registered successfully (ID: ${result.user_id})`);
81
+ return result;
82
+ }
83
+ catch (error) {
84
+ if (error.message.includes('409') || error.message.includes('already exists')) {
85
+ console.log(`ℹ Merchant already exists, proceeding to login...`);
86
+ return { email, user_id: '', role: 'merchant', is_active: true, created_at: '', updated_at: '' };
87
+ }
88
+ throw error;
89
+ }
90
+ }
91
+ async function getToken(email, password, config) {
92
+ console.log(`\n🔑 Obtaining access token...`);
93
+ const formData = new URLSearchParams();
94
+ formData.append('username', email);
95
+ formData.append('password', password);
96
+ formData.append('grant_type', 'password');
97
+ formData.append('client_id', config.clientId);
98
+ const result = await httpRequest(`${config.authUrl}/api/v1/oauth/token`, {
99
+ method: 'POST',
100
+ headers: {
101
+ 'Content-Type': 'application/x-www-form-urlencoded'
102
+ },
103
+ body: formData.toString()
104
+ });
105
+ console.log(`✓ Access token obtained`);
106
+ return result.access_token;
107
+ }
108
+ async function setupMerchantProfile(token, businessName, config) {
109
+ console.log(`\n🏪 Setting up merchant profile in Commerce API...`);
110
+ const payload = {
111
+ name: businessName,
112
+ origin_country_alpha2: 'CN',
113
+ origin_city: '深圳',
114
+ origin_state: '广东省',
115
+ origin_line_1: '南山区科技园',
116
+ contact_name: '测试用户',
117
+ contact_phone: '+8613800138000',
118
+ contact_email: 'test@example.com'
119
+ };
120
+ try {
121
+ const result = await httpRequest(`${config.apiUrl}/api/merchants/me`, {
122
+ method: 'POST',
123
+ headers: {
124
+ Authorization: `Bearer ${token}`
125
+ },
126
+ body: JSON.stringify(payload)
127
+ });
128
+ console.log(`✓ Merchant profile setup complete (ID: ${result.merchant_id})`);
129
+ return result;
130
+ }
131
+ catch (error) {
132
+ if (error.message.includes('409') || error.message.includes('already exists')) {
133
+ console.log(`ℹ Merchant profile already exists`);
134
+ return { merchant_id: '', business_name: businessName, user_id: '' };
135
+ }
136
+ throw error;
137
+ }
138
+ }
139
+ async function main() {
140
+ const args = process.argv.slice(2);
141
+ // 生成随机测试账户
142
+ const timestamp = Date.now();
143
+ const randomStr = Math.random().toString(36).substring(2, 8);
144
+ const defaultEmail = `test_${timestamp}_${randomStr}@example.com`;
145
+ const defaultPassword = 'TestPassword123!';
146
+ const defaultBusinessName = `Test Merchant ${timestamp}`;
147
+ let email = defaultEmail;
148
+ let password = defaultPassword;
149
+ let businessName = defaultBusinessName;
150
+ let phone;
151
+ let address;
152
+ let environment = 'development';
153
+ // 解析命令行参数
154
+ for (let i = 0; i < args.length; i++) {
155
+ const arg = args[i];
156
+ if (arg === '--email' && args[i + 1]) {
157
+ email = args[++i];
158
+ }
159
+ else if (arg === '--password' && args[i + 1]) {
160
+ password = args[++i];
161
+ }
162
+ else if (arg === '--business-name' && args[i + 1]) {
163
+ businessName = args[++i];
164
+ }
165
+ else if (arg === '--phone' && args[i + 1]) {
166
+ phone = args[++i];
167
+ }
168
+ else if (arg === '--address' && args[i + 1]) {
169
+ address = args[++i];
170
+ }
171
+ else if (arg === '--env' && args[i + 1]) {
172
+ const envArg = args[++i];
173
+ if (envArg === 'development' || envArg === 'production') {
174
+ environment = envArg;
175
+ }
176
+ else {
177
+ console.error(`❌ Invalid environment: ${envArg}. Must be 'development' or 'production'.`);
178
+ process.exit(1);
179
+ }
180
+ }
181
+ else if (arg === '--help' || arg === '-h') {
182
+ console.log(`
183
+ Usage: generate-test-token [options]
184
+
185
+ Options:
186
+ --email <email> User email (default: auto-generated)
187
+ --password <password> User password (default: TestPassword123!)
188
+ --business-name <name> Merchant business name (default: auto-generated)
189
+ --phone <phone> Merchant phone number (optional)
190
+ --address <address> Merchant address (optional)
191
+ --env <environment> Environment: development (default) or production
192
+ --help, -h Show this help message
193
+
194
+ Example:
195
+ generate-test-token
196
+ generate-test-token --env production
197
+ generate-test-token --business-name "My Test Shop" --phone "+1234567890"
198
+ generate-test-token --email "custom@example.com" --password "MyPass123" --env production
199
+ `);
200
+ process.exit(0);
201
+ }
202
+ }
203
+ const config = ENV_CONFIG[environment];
204
+ try {
205
+ console.log('🚀 Starting test token generation...\n');
206
+ console.log(`Environment: ${config.envName}`);
207
+ console.log(`Auth API: ${config.authUrl}`);
208
+ console.log(`Commerce API: ${config.apiUrl}\n`);
209
+ console.log(`Using credentials:`);
210
+ console.log(` Email: ${email}`);
211
+ console.log(` Password: ${password}`);
212
+ console.log(` Business Name: ${businessName}`);
213
+ // 1. 注册 merchant(直接注册为商家)
214
+ const user = await registerMerchant(email, password, businessName, config, phone, address);
215
+ // 2. 获取 token
216
+ const token = await getToken(email, password, config);
217
+ // 3. 设置 merchant profile(Commerce API)
218
+ const merchantProfile = await setupMerchantProfile(token, businessName, config);
219
+ // 4. 保存 token 到临时文件
220
+ const tmpDir = os.tmpdir();
221
+ const tokenFileName = `optima-test-token-${Date.now()}.txt`;
222
+ const tokenFilePath = path.join(tmpDir, tokenFileName);
223
+ fs.writeFileSync(tokenFilePath, token, 'utf-8');
224
+ console.log(`\n💾 Token saved to temporary file`);
225
+ // 输出结果
226
+ console.log('\n' + '='.repeat(80));
227
+ console.log('✅ Test token generated successfully!\n');
228
+ console.log('📋 Details:');
229
+ console.log(` Environment: ${config.envName}`);
230
+ console.log(` Email: ${email}`);
231
+ console.log(` Password: ${password}`);
232
+ console.log(` User ID: ${user.user_id || 'N/A'}`);
233
+ console.log(` Role: ${user.role}`);
234
+ console.log(` Business Name: ${businessName}`);
235
+ console.log(` Merchant ID: ${merchantProfile.merchant_id || 'N/A'}\n`);
236
+ console.log('📁 Token File Path:');
237
+ console.log(` ${tokenFilePath}\n`);
238
+ console.log('💡 Usage Examples:');
239
+ console.log(` # Read token from file:`);
240
+ console.log(` TOKEN=$(cat ${tokenFilePath})\n`);
241
+ console.log(` # Use with commerce CLI:`);
242
+ console.log(` OPTIMA_TOKEN=$(cat ${tokenFilePath}) OPTIMA_ENV=${config.envName} commerce product list\n`);
243
+ console.log(` # Use in curl:`);
244
+ console.log(` curl -H "Authorization: Bearer $(cat ${tokenFilePath})" ${config.apiUrl}/api/products\n`);
245
+ console.log('='.repeat(80));
246
+ }
247
+ catch (error) {
248
+ console.error('\n❌ Error:', error.message);
249
+ process.exit(1);
250
+ }
251
+ }
252
+ main();
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@optima-chat/dev-skills",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "description": "Claude Code Skills for Optima development team - cross-environment collaboration tools",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "optima-dev-skills": "./bin/cli.js",
8
- "optima-query-db": "./dist/bin/helpers/query-db.js"
8
+ "optima-query-db": "./dist/bin/helpers/query-db.js",
9
+ "optima-generate-test-token": "./dist/bin/helpers/generate-test-token.js"
9
10
  },
10
11
  "scripts": {
11
12
  "postinstall": "node scripts/install.js",