@optima-chat/dev-skills 0.7.15 → 0.7.17

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,196 @@
1
+ # /restart-ecs - 重启 ECS 服务
2
+
3
+ 快速重启 ECS 集群中的服务,支持 Stage/Prod 两个环境。
4
+
5
+ **版本**: v0.1.0
6
+
7
+ ## 使用场景
8
+
9
+ **后端开发者**: 代码更新后需要重启服务使配置生效
10
+ **DevOps**: 服务异常需要快速恢复
11
+ **排查问题**: 服务状态异常,需要重启清理缓存或连接
12
+
13
+ ## 用法
14
+
15
+ ```
16
+ /restart-ecs <service> [environment]
17
+ ```
18
+
19
+ ## 参数
20
+
21
+ - `service` (必需): 服务简称
22
+ - `user-auth` - 用户认证服务
23
+ - `user-auth-admin` - 用户认证管理后台
24
+ - `commerce-backend` - 电商后端 API
25
+ - `commerce-rq-worker` - RQ 后台任务
26
+ - `commerce-rq-scheduler` - RQ 定时调度
27
+ - `agentic-chat` - AI 聊天服务
28
+ - `session-gateway` - AI Shell 网关
29
+ - `bi-backend` - BI 后端
30
+ - `bi-dashboard` - BI 仪表板
31
+ - `optima-scout` - 产品研究工具
32
+ - `ai-shell-web-ui` - Shell Web UI
33
+ - `optima-store` - 商城前端(仅 Stage)
34
+ - `pgbouncer` - 连接池(仅 Stage)
35
+ - `environment` (可选): 环境,默认 stage
36
+ - `stage` - Stage 预发布环境(默认,更安全)
37
+ - `prod` - 生产环境(需确认)
38
+
39
+ ## 示例
40
+
41
+ ```bash
42
+ /restart-ecs session-gateway # 重启 Stage 环境的 session-gateway(默认)
43
+ /restart-ecs session-gateway prod # 重启 Prod 环境的 session-gateway
44
+ /restart-ecs user-auth stage # 重启 Stage 环境的 user-auth
45
+ /restart-ecs list # 列出 Stage 环境所有可用服务
46
+ /restart-ecs list prod # 列出 Prod 环境所有可用服务
47
+ ```
48
+
49
+ ## 特殊参数处理
50
+
51
+ - 如果用户输入 `/restart-ecs` 或 `/restart-ecs --help` 或 `/restart-ecs help`,显示此帮助文档
52
+ - 如果用户输入 `/restart-ecs list [env]`,列出指定环境的所有服务
53
+
54
+ ## Claude Code 执行步骤
55
+
56
+ ### 0. 列出服务(service = "list")
57
+
58
+ ```bash
59
+ # 列出 Stage 环境服务
60
+ aws ecs list-services --cluster optima-stage-cluster --region ap-southeast-1 --query 'serviceArns[*]' --output text | tr '\t' '\n' | sed 's/.*service\/optima-stage-cluster\///'
61
+
62
+ # 列出 Prod 环境服务
63
+ aws ecs list-services --cluster optima-prod-cluster --region ap-southeast-1 --query 'serviceArns[*]' --output text | tr '\t' '\n' | sed 's/.*service\/optima-prod-cluster\///'
64
+ ```
65
+
66
+ ### 1. Stage 环境重启(environment = "stage" 或默认)
67
+
68
+ **集群名**: `optima-stage-cluster`
69
+ **服务名格式**: `{service}-stage`
70
+
71
+ **步骤**:
72
+ ```bash
73
+ # 重启服务(强制重新部署)
74
+ aws ecs update-service \
75
+ --cluster optima-stage-cluster \
76
+ --service {service}-stage \
77
+ --force-new-deployment \
78
+ --region ap-southeast-1 \
79
+ --query 'service.{serviceName:serviceName,desiredCount:desiredCount,runningCount:runningCount,status:status}' \
80
+ --output table
81
+ ```
82
+
83
+ **可用服务**:
84
+ - `user-auth-stage`
85
+ - `user-auth-admin-stage`
86
+ - `commerce-backend-stage`
87
+ - `commerce-rq-worker-stage`
88
+ - `commerce-rq-scheduler-stage`
89
+ - `agentic-chat-stage`
90
+ - `session-gateway-stage`
91
+ - `bi-backend-stage`
92
+ - `bi-dashboard-stage`
93
+ - `optima-scout-stage`
94
+ - `ai-shell-web-ui-stage`
95
+ - `optima-store-stage`
96
+ - `pgbouncer-stage`
97
+
98
+ ### 2. Prod 环境重启(environment = "prod")
99
+
100
+ **集群名**: `optima-prod-cluster`
101
+ **服务名格式**: `{service}-prod`
102
+
103
+ **⚠️ 安全提醒**: 重启 Prod 服务前,Claude 应主动向用户确认是否继续。
104
+
105
+ **步骤**:
106
+ ```bash
107
+ # 重启服务(强制重新部署)
108
+ aws ecs update-service \
109
+ --cluster optima-prod-cluster \
110
+ --service {service}-prod \
111
+ --force-new-deployment \
112
+ --region ap-southeast-1 \
113
+ --query 'service.{serviceName:serviceName,desiredCount:desiredCount,runningCount:runningCount,status:status}' \
114
+ --output table
115
+ ```
116
+
117
+ **可用服务**:
118
+ - `user-auth-prod`
119
+ - `user-auth-admin-prod`
120
+ - `commerce-backend-prod`
121
+ - `commerce-rq-worker-prod`
122
+ - `commerce-rq-scheduler-prod`
123
+ - `agentic-chat-prod`
124
+ - `session-gateway-prod`
125
+ - `bi-backend-prod`
126
+ - `bi-dashboard-prod`
127
+ - `optima-scout-prod`
128
+ - `ai-shell-web-ui-prod`
129
+
130
+ **注意**: `optima-store` 和 `pgbouncer` 仅在 Stage 环境部署
131
+
132
+ ## 查看重启进度
133
+
134
+ 重启触发后,可以查看部署进度:
135
+
136
+ ```bash
137
+ # 查看服务部署状态
138
+ aws ecs describe-services \
139
+ --cluster optima-{env}-cluster \
140
+ --services {service}-{env} \
141
+ --region ap-southeast-1 \
142
+ --query 'services[0].{serviceName:serviceName,status:status,runningCount:runningCount,desiredCount:desiredCount,deployments:deployments[*].{status:status,runningCount:runningCount,desiredCount:desiredCount}}' \
143
+ --output yaml
144
+
145
+ # 查看服务事件(最近的部署事件)
146
+ aws ecs describe-services \
147
+ --cluster optima-{env}-cluster \
148
+ --services {service}-{env} \
149
+ --region ap-southeast-1 \
150
+ --query 'services[0].events[:5]' \
151
+ --output table
152
+ ```
153
+
154
+ ## 常见错误处理
155
+
156
+ ### 错误:ServiceNotFoundException
157
+
158
+ **原因**: 服务名不存在
159
+
160
+ **解决**:
161
+ ```bash
162
+ # 列出所有服务
163
+ aws ecs list-services --cluster optima-stage-cluster --region ap-southeast-1
164
+ ```
165
+
166
+ ### 错误:ClusterNotFoundException
167
+
168
+ **原因**: 集群名错误
169
+
170
+ **解决**: 确认使用正确的集群名:
171
+ - Stage: `optima-stage-cluster`
172
+ - Prod: `optima-prod-cluster`
173
+
174
+ ### 错误:AccessDeniedException
175
+
176
+ **原因**: AWS 凭证无权限
177
+
178
+ **解决**: 确认 AWS CLI 配置了正确的凭证,且有 ECS 操作权限
179
+
180
+ ## 重启原理
181
+
182
+ `--force-new-deployment` 参数会:
183
+ 1. 使用**当前**的 Task Definition(版本号不变)
184
+ 2. 启动新的 Task 实例
185
+ 3. 新 Task 健康检查通过后注册到 ALB
186
+ 4. 旧 Task 优雅停止
187
+
188
+ 这是一个零停机的滚动更新过程。
189
+
190
+ ## 注意事项
191
+
192
+ 1. **默认 Stage 环境**: 为避免误操作生产环境,默认重启 Stage
193
+ 2. **Prod 需确认**: 重启 Prod 服务时 Claude 会主动确认
194
+ 3. **版本不变**: 重启不会改变 Task Definition 版本号
195
+ 4. **零停机**: ECS 会确保新 Task 健康后才停止旧 Task
196
+ 5. **权限要求**: 需要 AWS CLI 配置了正确的凭证和 ECS 操作权限
@@ -0,0 +1,160 @@
1
+ ---
2
+ name: "restartEcs"
3
+ description: "当用户请求重启 ECS 服务、重启服务、restart service、重新部署服务、重启 session-gateway、重启 user-auth、重启后端服务时,使用此技能。支持 Stage、Prod 两个环境的 ECS 服务重启。"
4
+ allowed-tools: ["Bash"]
5
+ ---
6
+
7
+ # 重启 ECS 服务
8
+
9
+ 当你需要重启 ECS 集群中的服务时,使用这个场景。
10
+
11
+ ## 适用情况
12
+
13
+ - 代码更新后需要使配置生效
14
+ - 服务异常需要快速恢复
15
+ - 服务状态异常,需要清理缓存或连接
16
+ - 内存泄漏等问题需要重启服务
17
+
18
+ ## 快速操作
19
+
20
+ ### 1. 重启 Stage 环境服务(默认,更安全)
21
+
22
+ ```
23
+ /restart-ecs session-gateway
24
+ /restart-ecs user-auth
25
+ /restart-ecs commerce-backend
26
+ ```
27
+
28
+ **说明**:
29
+ - 默认重启 Stage 环境,避免误操作生产环境
30
+ - 使用 ECS `force-new-deployment` 实现零停机重启
31
+ - Task Definition 版本号不变
32
+
33
+ ### 2. 重启 Prod 环境服务
34
+
35
+ ```
36
+ /restart-ecs session-gateway prod
37
+ /restart-ecs user-auth prod
38
+ ```
39
+
40
+ **说明**:
41
+ - 重启生产环境服务
42
+ - Claude 会主动确认是否继续
43
+ - 同样是零停机滚动更新
44
+
45
+ ### 3. 列出可用服务
46
+
47
+ ```
48
+ /restart-ecs list # 列出 Stage 环境服务
49
+ /restart-ecs list prod # 列出 Prod 环境服务
50
+ ```
51
+
52
+ ## 环境信息
53
+
54
+ ### Stage 环境
55
+
56
+ **集群名**: `optima-stage-cluster`
57
+
58
+ **可用服务**:
59
+ | 服务简称 | 完整服务名 | 说明 |
60
+ |---------|-----------|------|
61
+ | user-auth | user-auth-stage | 用户认证服务 |
62
+ | user-auth-admin | user-auth-admin-stage | 认证管理后台 |
63
+ | commerce-backend | commerce-backend-stage | 电商后端 API |
64
+ | commerce-rq-worker | commerce-rq-worker-stage | RQ 后台任务 |
65
+ | commerce-rq-scheduler | commerce-rq-scheduler-stage | RQ 定时调度 |
66
+ | agentic-chat | agentic-chat-stage | AI 聊天服务 |
67
+ | session-gateway | session-gateway-stage | AI Shell 网关 |
68
+ | bi-backend | bi-backend-stage | BI 后端 |
69
+ | bi-dashboard | bi-dashboard-stage | BI 仪表板 |
70
+ | optima-scout | optima-scout-stage | 产品研究工具 |
71
+ | ai-shell-web-ui | ai-shell-web-ui-stage | Shell Web UI |
72
+ | optima-store | optima-store-stage | 商城前端 |
73
+ | pgbouncer | pgbouncer-stage | 数据库连接池 |
74
+
75
+ ### Prod 环境
76
+
77
+ **集群名**: `optima-prod-cluster`
78
+
79
+ **可用服务**:
80
+ | 服务简称 | 完整服务名 | 说明 |
81
+ |---------|-----------|------|
82
+ | user-auth | user-auth-prod | 用户认证服务 |
83
+ | user-auth-admin | user-auth-admin-prod | 认证管理后台 |
84
+ | commerce-backend | commerce-backend-prod | 电商后端 API |
85
+ | commerce-rq-worker | commerce-rq-worker-prod | RQ 后台任务 |
86
+ | commerce-rq-scheduler | commerce-rq-scheduler-prod | RQ 定时调度 |
87
+ | agentic-chat | agentic-chat-prod | AI 聊天服务 |
88
+ | session-gateway | session-gateway-prod | AI Shell 网关 |
89
+ | bi-backend | bi-backend-prod | BI 后端 |
90
+ | bi-dashboard | bi-dashboard-prod | BI 仪表板 |
91
+ | optima-scout | optima-scout-prod | 产品研究工具 |
92
+ | ai-shell-web-ui | ai-shell-web-ui-prod | Shell Web UI |
93
+
94
+ **注意**: `optima-store` 和 `pgbouncer` 仅在 Stage 环境部署
95
+
96
+ ## 重启原理
97
+
98
+ ECS `--force-new-deployment` 的工作流程:
99
+
100
+ 1. **启动新 Task** - 使用当前 Task Definition 创建新实例
101
+ 2. **健康检查** - 新 Task 通过 ALB 健康检查
102
+ 3. **注册到 ALB** - 新 Task 开始接收流量
103
+ 4. **停止旧 Task** - 旧 Task 优雅停止
104
+
105
+ 这是一个**零停机**的滚动更新过程,用户请求不会中断。
106
+
107
+ ## 常见使用场景
108
+
109
+ ### 场景 1:服务配置更新后重启
110
+
111
+ 当修改了 Infisical 中的环境变量后,需要重启服务使配置生效:
112
+
113
+ ```
114
+ /restart-ecs commerce-backend stage
115
+ ```
116
+
117
+ ### 场景 2:服务异常恢复
118
+
119
+ 服务出现内存泄漏或连接池耗尽等问题:
120
+
121
+ ```
122
+ /restart-ecs session-gateway prod
123
+ ```
124
+
125
+ ### 场景 3:批量重启多个服务
126
+
127
+ 需要重启多个相关服务:
128
+
129
+ ```
130
+ # 依次重启
131
+ /restart-ecs user-auth stage
132
+ /restart-ecs commerce-backend stage
133
+ /restart-ecs agentic-chat stage
134
+ ```
135
+
136
+ ## 查看重启进度
137
+
138
+ 重启触发后,可以查看部署状态:
139
+
140
+ ```bash
141
+ # 查看服务部署状态
142
+ aws ecs describe-services \
143
+ --cluster optima-stage-cluster \
144
+ --services session-gateway-stage \
145
+ --region ap-southeast-1 \
146
+ --query 'services[0].deployments' \
147
+ --output table
148
+ ```
149
+
150
+ ## 安全提醒
151
+
152
+ 1. **Stage 优先**: 默认重启 Stage 环境,降低误操作风险
153
+ 2. **Prod 确认**: 重启 Prod 服务前会主动确认
154
+ 3. **版本不变**: 重启不会改变 Task Definition 版本号
155
+ 4. **可恢复**: 如果新 Task 启动失败,旧 Task 会继续运行
156
+
157
+ ## 相关命令
158
+
159
+ - `/restart-ecs` - 重启 ECS 服务(详细使用方法请查看 `/restart-ecs --help`)
160
+ - `/logs` - 查看服务日志,可用于确认重启后服务状态
@@ -0,0 +1,185 @@
1
+ ---
2
+ name: "show-env"
3
+ description: "当用户请求查看环境变量、查看配置、查看服务配置、环境变量是什么、env 变量、服务环境变量、查看 Infisical 配置时,使用此技能。支持查看当前 shell 环境变量,以及 Stage、Prod 环境的服务配置。"
4
+ allowed-tools: ["Bash", "SlashCommand"]
5
+ ---
6
+
7
+ # 查看环境变量
8
+
9
+ 当你需要查看环境变量或服务配置时,使用这个场景。
10
+
11
+ ## 适用情况
12
+
13
+ - 查看当前 shell 的环境变量
14
+ - 查看服务的环境变量配置(从 Infisical)
15
+ - 排查环境配置问题
16
+ - 确认某个环境变量是否设置正确
17
+ - 对比不同环境的配置差异
18
+
19
+ ## 快速操作
20
+
21
+ ### 1. 查看当前 shell 环境变量
22
+
23
+ ```bash
24
+ # 查看所有环境变量
25
+ env
26
+
27
+ # 查看特定环境变量
28
+ echo $OPTIMA_TOKEN
29
+ echo $OPTIMA_ENV
30
+
31
+ # 搜索包含特定关键字的环境变量
32
+ env | grep -i optima
33
+ env | grep -i aws
34
+ env | grep -i database
35
+ ```
36
+
37
+ ### 2. 查看 Infisical 中的服务配置
38
+
39
+ 使用 `optima-show-env` CLI 工具查看存储在 Infisical 中的服务配置:
40
+
41
+ ```bash
42
+ # 查看 Stage 环境的 commerce-backend 配置
43
+ optima-show-env commerce-backend stage
44
+
45
+ # 查看 Prod 环境的 user-auth 配置
46
+ optima-show-env user-auth prod
47
+
48
+ # 查看 Stage 环境的 agentic-chat 配置
49
+ optima-show-env agentic-chat stage
50
+ ```
51
+
52
+ **支持的服务**:
53
+ - `commerce-backend` - 电商后端 API
54
+ - `user-auth` - 用户认证服务
55
+ - `agentic-chat` - AI 聊天服务
56
+ - `bi` - BI 后端
57
+ - `session-gateway` - AI Shell 网关
58
+ - `optima-store` - 商城前端
59
+ - `optima-scout` - 产品研究工具
60
+ - `mcp-host` - MCP 主机
61
+
62
+ **支持的环境**:
63
+ - `stage` - Stage 预发布环境
64
+ - `prod` - Prod 生产环境
65
+
66
+ ### 3. 使用过滤和选项
67
+
68
+ ```bash
69
+ # 只查看数据库相关配置
70
+ optima-show-env commerce-backend stage --filter DATABASE
71
+
72
+ # 只查看 STRIPE 相关配置
73
+ optima-show-env commerce-backend stage --filter STRIPE
74
+
75
+ # 只显示变量名(不显示值)
76
+ optima-show-env user-auth prod --keys-only
77
+ ```
78
+
79
+ ## 常见场景
80
+
81
+ ### 场景 1:确认环境变量是否设置
82
+
83
+ **用户请求**:"帮我看看 OPTIMA_TOKEN 环境变量设置了没有"
84
+
85
+ **步骤**:
86
+ ```bash
87
+ # 检查是否设置
88
+ if [ -n "$OPTIMA_TOKEN" ]; then
89
+ echo "OPTIMA_TOKEN 已设置"
90
+ echo "长度: ${#OPTIMA_TOKEN} 字符"
91
+ else
92
+ echo "OPTIMA_TOKEN 未设置"
93
+ fi
94
+ ```
95
+
96
+ ### 场景 2:排查服务配置问题
97
+
98
+ **用户请求**:"commerce-backend 连接不上数据库,帮我看看配置"
99
+
100
+ **步骤**:
101
+ 1. 查看数据库相关配置:
102
+ ```bash
103
+ optima-show-env commerce-backend stage --filter DATABASE
104
+ ```
105
+ 2. 确认连接字符串格式
106
+ 3. 检查密码是否包含特殊字符需要转义
107
+
108
+ ### 场景 3:对比不同环境配置
109
+
110
+ **用户请求**:"对比一下 Stage 和 Prod 环境的配置差异"
111
+
112
+ **步骤**:
113
+ ```bash
114
+ # 导出两个环境的配置(只看变量名)
115
+ optima-show-env commerce-backend stage --keys-only > /tmp/env-stage.txt
116
+ optima-show-env commerce-backend prod --keys-only > /tmp/env-prod.txt
117
+
118
+ # 对比差异
119
+ diff /tmp/env-stage.txt /tmp/env-prod.txt
120
+ ```
121
+
122
+ ### 场景 4:查看特定类型配置
123
+
124
+ **用户请求**:"帮我看看 Stripe 相关配置"
125
+
126
+ **步骤**:
127
+ ```bash
128
+ optima-show-env commerce-backend stage --filter STRIPE
129
+ optima-show-env commerce-backend prod --filter STRIPE
130
+ ```
131
+
132
+ ## 环境变量分类
133
+
134
+ ### 常见环境变量类型
135
+
136
+ | 类型 | 示例变量 | 说明 |
137
+ |------|----------|------|
138
+ | 数据库 | `DATABASE_URL`, `DB_HOST`, `DB_PASSWORD` | 数据库连接配置 |
139
+ | Redis | `REDIS_URL`, `REDIS_HOST`, `REDIS_DB` | 缓存配置 |
140
+ | AWS/S3 | `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`, `MINIO_BUCKET` | 对象存储配置 |
141
+ | Auth | `JWT_SECRET_KEY`, `OAUTH_CLIENT_ID`, `SECRET_KEY` | 认证相关配置 |
142
+ | Stripe | `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET` | 支付配置 |
143
+ | 应用 | `DEBUG`, `LOG_LEVEL`, `NODE_ENV` | 应用运行配置 |
144
+
145
+ ## CLI 选项说明
146
+
147
+ | 选项 | 说明 |
148
+ |------|------|
149
+ | `--filter <pattern>` | 按变量名过滤(不区分大小写) |
150
+ | `--keys-only` | 只显示变量名,不显示值 |
151
+ | `--help` | 显示帮助信息 |
152
+
153
+ ## 故障排查
154
+
155
+ ### 问题 1:optima-show-env 命令不存在
156
+
157
+ **解决方案**:
158
+ ```bash
159
+ # 安装或更新工具
160
+ npm install -g @optima-chat/dev-skills@latest
161
+ ```
162
+
163
+ ### 问题 2:无法访问 Infisical
164
+
165
+ **可能原因**:
166
+ - GitHub CLI 未登录
167
+ - 无权访问 Optima-Chat/optima-dev-skills 仓库的 Variables
168
+
169
+ **解决方案**:
170
+ - 运行 `gh auth login` 登录 GitHub
171
+ - 确认有仓库访问权限
172
+
173
+ ### 问题 3:服务不存在
174
+
175
+ **错误信息**: "Unknown service 'xxx'"
176
+
177
+ **解决方案**:
178
+ - 检查服务名称拼写
179
+ - 运行 `optima-show-env --help` 查看支持的服务列表
180
+
181
+ ## 相关命令
182
+
183
+ - `/show-env` - 查看环境变量
184
+ - `/logs` - 查看服务日志
185
+ - `/query-db` - 查询数据库
package/README.md CHANGED
@@ -23,12 +23,13 @@ Optima Dev Skills 让 Claude Code 能够直接在 **CI、Stage、Prod** 三个
23
23
  - **任务驱动** - 基于具体任务场景(查看日志、调用 API),不是抽象分类
24
24
  - **跨环境协作** - 统一的命令在 CI、Stage、Prod 三个环境中使用
25
25
 
26
- ## 📋 任务场景(5 个)
26
+ ## 📋 任务场景(6 个)
27
27
 
28
28
  当 Claude Code 识别到以下任务时,会自动加载对应的 Skill:
29
29
 
30
30
  - **logs** - 查看 CI/Stage/Prod 的服务器日志
31
31
  - **query-db** - 查询 CI/Stage/Prod 的数据库
32
+ - **show-env** - 查看 Stage/Prod 的服务环境变量(从 Infisical)
32
33
  - **generate-test-token** - 生成测试 Access Token 用于 API 测试
33
34
  - **use-commerce-cli** - 使用 Commerce CLI 管理电商店铺
34
35
  - **read-code** - 阅读 Optima-Chat 组织下任意仓库的代码
@@ -91,10 +92,12 @@ Claude:
91
92
  | 工具 | 说明 | 示例 |
92
93
  |------|------|------|
93
94
  | `optima-query-db` | 数据库查询工具 | `optima-query-db user-auth "SELECT COUNT(*) FROM users" prod` |
95
+ | `optima-show-env` | 查看服务环境变量 | `optima-show-env commerce-backend stage --filter DATABASE` |
94
96
  | `optima-generate-test-token` | 生成测试 token | `optima-generate-test-token --business-name "测试店铺"` |
95
97
 
96
98
  **特点**:
97
99
  - ✅ 支持 CI、Stage、Prod 三个环境(query-db)
100
+ - ✅ 支持 Stage、Prod 环境(show-env)
98
101
  - ✅ 自动管理 SSH 隧道和密钥
99
102
  - ✅ 可在任何终端直接使用
100
103
  - ✅ 自动注册账户、获取 token、设置 merchant profile(generate-test-token)
@@ -114,6 +117,7 @@ optima-dev-skills/
114
117
  │ └── skills/
115
118
  │ ├── logs/ # 日志查看 skill
116
119
  │ ├── query-db/ # 数据库查询 skill
120
+ │ ├── show-env/ # 环境变量查看 skill
117
121
  │ ├── generate-test-token/ # 测试 token 生成 skill
118
122
  │ ├── use-commerce-cli/ # Commerce CLI 使用 skill
119
123
  │ └── read-code/ # 代码阅读 skill
@@ -121,6 +125,7 @@ optima-dev-skills/
121
125
  ├── bin/
122
126
  │ └── helpers/
123
127
  │ ├── query-db.ts # CLI: 数据库查询
128
+ │ ├── show-env.ts # CLI: 查看环境变量
124
129
  │ └── generate-test-token.ts # CLI: 生成测试 token
125
130
 
126
131
  └── docs/
@@ -228,16 +233,16 @@ $ optima-query-db commerce-backend "SELECT id, title FROM products LIMIT 5" stag
228
233
 
229
234
  ## 🛠️ 开发状态
230
235
 
231
- **当前版本**: 0.7.4
236
+ **当前版本**: 0.7.16
232
237
 
233
238
  **已完成**:
234
239
  - ✅ 4 个命令:`/logs`、`/query-db`、`/generate-test-token`、`/read-code`
235
- - ✅ 5 个任务场景:`logs`、`query-db`、`generate-test-token`、`use-commerce-cli`、`read-code`
240
+ - ✅ 6 个任务场景:`logs`、`query-db`、`show-env`、`generate-test-token`、`use-commerce-cli`、`read-code`
236
241
  - ✅ 支持 CI、Stage、Prod 三个环境
237
242
  - ✅ CI 环境通过 SSH + Docker 访问
238
243
  - ✅ Stage/Prod 通过 SSH 隧道访问 RDS
239
- - ✅ TypeScript CLI 工具:`optima-query-db`、`optima-generate-test-token`
240
- - ✅ 通过 Infisical 动态获取密钥
244
+ - ✅ TypeScript CLI 工具:`optima-query-db`、`optima-show-env`、`optima-generate-test-token`
245
+ - ✅ 通过 Infisical 动态获取密钥和环境变量
241
246
  - ✅ 自动生成测试 token 并设置 merchant profile
242
247
  - ✅ `generate-test-token` 支持 development 和 production 环境
243
248
 
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execSync } from 'child_process';
4
+
5
+ interface InfisicalConfig {
6
+ url: string;
7
+ clientId: string;
8
+ clientSecret: string;
9
+ projectId: string;
10
+ }
11
+
12
+ // 支持的服务列表(Infisical 路径为 /services/<service-name>)
13
+ const SUPPORTED_SERVICES = [
14
+ 'commerce-backend',
15
+ 'user-auth',
16
+ 'agentic-chat',
17
+ 'bi',
18
+ 'session-gateway',
19
+ 'optima-store',
20
+ 'optima-scout',
21
+ 'mcp-host'
22
+ ];
23
+
24
+ // 环境到 Infisical environment 的映射
25
+ const ENV_MAP: Record<string, string> = {
26
+ stage: 'staging',
27
+ prod: 'prod'
28
+ };
29
+
30
+ function getGitHubVariable(name: string): string {
31
+ return execSync(`gh variable get ${name} -R Optima-Chat/optima-dev-skills`, { encoding: 'utf-8' }).trim();
32
+ }
33
+
34
+ function getInfisicalConfig(): InfisicalConfig {
35
+ return {
36
+ url: getGitHubVariable('INFISICAL_URL'),
37
+ clientId: getGitHubVariable('INFISICAL_CLIENT_ID'),
38
+ clientSecret: getGitHubVariable('INFISICAL_CLIENT_SECRET'),
39
+ projectId: getGitHubVariable('INFISICAL_PROJECT_ID')
40
+ };
41
+ }
42
+
43
+ function getInfisicalToken(config: InfisicalConfig): string {
44
+ const response = execSync(
45
+ `curl -s -X POST "${config.url}/api/v1/auth/universal-auth/login" -H "Content-Type: application/json" -d '{"clientId": "${config.clientId}", "clientSecret": "${config.clientSecret}"}'`,
46
+ { encoding: 'utf-8' }
47
+ );
48
+ return JSON.parse(response).accessToken;
49
+ }
50
+
51
+ function getInfisicalSecrets(config: InfisicalConfig, token: string, environment: string, secretPath: string): Record<string, string> {
52
+ const response = execSync(
53
+ `curl -s "${config.url}/api/v3/secrets/raw?workspaceId=${config.projectId}&environment=${environment}&secretPath=${encodeURIComponent(secretPath)}" -H "Authorization: Bearer ${token}"`,
54
+ { encoding: 'utf-8' }
55
+ );
56
+ const data = JSON.parse(response);
57
+ const secrets: Record<string, string> = {};
58
+ for (const secret of data.secrets || []) {
59
+ secrets[secret.secretKey] = secret.secretValue;
60
+ }
61
+ return secrets;
62
+ }
63
+
64
+
65
+ function printHelp() {
66
+ console.log(`
67
+ Usage: optima-show-env <service> <environment> [options]
68
+
69
+ Arguments:
70
+ service Service name (${SUPPORTED_SERVICES.join(', ')})
71
+ environment Environment (stage, prod)
72
+
73
+ Options:
74
+ --filter Filter by key pattern (e.g., --filter DATABASE)
75
+ --keys-only Show only key names, not values
76
+ --help Show this help message
77
+
78
+ Examples:
79
+ optima-show-env commerce-backend stage
80
+ optima-show-env user-auth prod --filter DATABASE
81
+ optima-show-env bi stage --keys-only
82
+ `);
83
+ }
84
+
85
+ async function main() {
86
+ const args = process.argv.slice(2);
87
+
88
+ if (args.includes('--help') || args.includes('-h')) {
89
+ printHelp();
90
+ process.exit(0);
91
+ }
92
+
93
+ // 解析参数
94
+ const positionalArgs: string[] = [];
95
+ let filter = '';
96
+ let keysOnly = false;
97
+
98
+ for (let i = 0; i < args.length; i++) {
99
+ if (args[i] === '--filter' && args[i + 1]) {
100
+ filter = args[i + 1];
101
+ i++;
102
+ } else if (args[i] === '--keys-only') {
103
+ keysOnly = true;
104
+ } else if (!args[i].startsWith('-')) {
105
+ positionalArgs.push(args[i]);
106
+ }
107
+ }
108
+
109
+ if (positionalArgs.length < 2) {
110
+ console.error('Error: Missing required arguments');
111
+ printHelp();
112
+ process.exit(1);
113
+ }
114
+
115
+ const [service, environment] = positionalArgs;
116
+
117
+ // 验证服务
118
+ if (!SUPPORTED_SERVICES.includes(service)) {
119
+ console.error(`Error: Unknown service '${service}'`);
120
+ console.error('Available services:', SUPPORTED_SERVICES.join(', '));
121
+ process.exit(1);
122
+ }
123
+
124
+ // 验证环境
125
+ if (!ENV_MAP[environment]) {
126
+ console.error(`Error: Unknown environment '${environment}'`);
127
+ console.error('Available environments: stage, prod');
128
+ process.exit(1);
129
+ }
130
+
131
+ // Infisical 路径为 /services/<service-name>
132
+ const secretPath = `/services/${service}`;
133
+
134
+ console.log(`\n🔍 Fetching environment variables for ${service} (${environment.toUpperCase()})...\n`);
135
+
136
+ try {
137
+ const infisicalConfig = getInfisicalConfig();
138
+ console.log('✓ Loaded Infisical config from GitHub Variables');
139
+
140
+ const token = getInfisicalToken(infisicalConfig);
141
+ console.log('✓ Obtained Infisical access token');
142
+
143
+ const infisicalEnv = ENV_MAP[environment];
144
+ const secrets = getInfisicalSecrets(infisicalConfig, token, infisicalEnv, secretPath);
145
+ console.log(`✓ Retrieved secrets from Infisical (path: ${secretPath})\n`);
146
+
147
+ const keys = Object.keys(secrets).sort();
148
+
149
+ if (keys.length === 0) {
150
+ console.log('No environment variables found.');
151
+ return;
152
+ }
153
+
154
+ // 过滤
155
+ const filteredKeys = filter
156
+ ? keys.filter(key => key.toUpperCase().includes(filter.toUpperCase()))
157
+ : keys;
158
+
159
+ if (filteredKeys.length === 0) {
160
+ console.log(`No environment variables matching '${filter}' found.`);
161
+ return;
162
+ }
163
+
164
+ console.log(`📋 Environment Variables (${filteredKeys.length} items):\n`);
165
+ console.log('─'.repeat(60));
166
+
167
+ for (const key of filteredKeys) {
168
+ if (keysOnly) {
169
+ console.log(key);
170
+ } else {
171
+ console.log(`${key}=${secrets[key]}`);
172
+ }
173
+ }
174
+
175
+ console.log('─'.repeat(60));
176
+
177
+ } catch (error: any) {
178
+ console.error('\n❌ Error:', error.message);
179
+ process.exit(1);
180
+ }
181
+ }
182
+
183
+ main();
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const child_process_1 = require("child_process");
5
+ // 支持的服务列表(Infisical 路径为 /services/<service-name>)
6
+ const SUPPORTED_SERVICES = [
7
+ 'commerce-backend',
8
+ 'user-auth',
9
+ 'agentic-chat',
10
+ 'bi',
11
+ 'session-gateway',
12
+ 'optima-store',
13
+ 'optima-scout',
14
+ 'mcp-host'
15
+ ];
16
+ // 环境到 Infisical environment 的映射
17
+ const ENV_MAP = {
18
+ stage: 'staging',
19
+ prod: 'prod'
20
+ };
21
+ function getGitHubVariable(name) {
22
+ return (0, child_process_1.execSync)(`gh variable get ${name} -R Optima-Chat/optima-dev-skills`, { encoding: 'utf-8' }).trim();
23
+ }
24
+ function getInfisicalConfig() {
25
+ return {
26
+ url: getGitHubVariable('INFISICAL_URL'),
27
+ clientId: getGitHubVariable('INFISICAL_CLIENT_ID'),
28
+ clientSecret: getGitHubVariable('INFISICAL_CLIENT_SECRET'),
29
+ projectId: getGitHubVariable('INFISICAL_PROJECT_ID')
30
+ };
31
+ }
32
+ function getInfisicalToken(config) {
33
+ const response = (0, child_process_1.execSync)(`curl -s -X POST "${config.url}/api/v1/auth/universal-auth/login" -H "Content-Type: application/json" -d '{"clientId": "${config.clientId}", "clientSecret": "${config.clientSecret}"}'`, { encoding: 'utf-8' });
34
+ return JSON.parse(response).accessToken;
35
+ }
36
+ function getInfisicalSecrets(config, token, environment, secretPath) {
37
+ const response = (0, child_process_1.execSync)(`curl -s "${config.url}/api/v3/secrets/raw?workspaceId=${config.projectId}&environment=${environment}&secretPath=${encodeURIComponent(secretPath)}" -H "Authorization: Bearer ${token}"`, { encoding: 'utf-8' });
38
+ const data = JSON.parse(response);
39
+ const secrets = {};
40
+ for (const secret of data.secrets || []) {
41
+ secrets[secret.secretKey] = secret.secretValue;
42
+ }
43
+ return secrets;
44
+ }
45
+ function printHelp() {
46
+ console.log(`
47
+ Usage: optima-show-env <service> <environment> [options]
48
+
49
+ Arguments:
50
+ service Service name (${SUPPORTED_SERVICES.join(', ')})
51
+ environment Environment (stage, prod)
52
+
53
+ Options:
54
+ --filter Filter by key pattern (e.g., --filter DATABASE)
55
+ --keys-only Show only key names, not values
56
+ --help Show this help message
57
+
58
+ Examples:
59
+ optima-show-env commerce-backend stage
60
+ optima-show-env user-auth prod --filter DATABASE
61
+ optima-show-env bi stage --keys-only
62
+ `);
63
+ }
64
+ async function main() {
65
+ const args = process.argv.slice(2);
66
+ if (args.includes('--help') || args.includes('-h')) {
67
+ printHelp();
68
+ process.exit(0);
69
+ }
70
+ // 解析参数
71
+ const positionalArgs = [];
72
+ let filter = '';
73
+ let keysOnly = false;
74
+ for (let i = 0; i < args.length; i++) {
75
+ if (args[i] === '--filter' && args[i + 1]) {
76
+ filter = args[i + 1];
77
+ i++;
78
+ }
79
+ else if (args[i] === '--keys-only') {
80
+ keysOnly = true;
81
+ }
82
+ else if (!args[i].startsWith('-')) {
83
+ positionalArgs.push(args[i]);
84
+ }
85
+ }
86
+ if (positionalArgs.length < 2) {
87
+ console.error('Error: Missing required arguments');
88
+ printHelp();
89
+ process.exit(1);
90
+ }
91
+ const [service, environment] = positionalArgs;
92
+ // 验证服务
93
+ if (!SUPPORTED_SERVICES.includes(service)) {
94
+ console.error(`Error: Unknown service '${service}'`);
95
+ console.error('Available services:', SUPPORTED_SERVICES.join(', '));
96
+ process.exit(1);
97
+ }
98
+ // 验证环境
99
+ if (!ENV_MAP[environment]) {
100
+ console.error(`Error: Unknown environment '${environment}'`);
101
+ console.error('Available environments: stage, prod');
102
+ process.exit(1);
103
+ }
104
+ // Infisical 路径为 /services/<service-name>
105
+ const secretPath = `/services/${service}`;
106
+ console.log(`\n🔍 Fetching environment variables for ${service} (${environment.toUpperCase()})...\n`);
107
+ try {
108
+ const infisicalConfig = getInfisicalConfig();
109
+ console.log('✓ Loaded Infisical config from GitHub Variables');
110
+ const token = getInfisicalToken(infisicalConfig);
111
+ console.log('✓ Obtained Infisical access token');
112
+ const infisicalEnv = ENV_MAP[environment];
113
+ const secrets = getInfisicalSecrets(infisicalConfig, token, infisicalEnv, secretPath);
114
+ console.log(`✓ Retrieved secrets from Infisical (path: ${secretPath})\n`);
115
+ const keys = Object.keys(secrets).sort();
116
+ if (keys.length === 0) {
117
+ console.log('No environment variables found.');
118
+ return;
119
+ }
120
+ // 过滤
121
+ const filteredKeys = filter
122
+ ? keys.filter(key => key.toUpperCase().includes(filter.toUpperCase()))
123
+ : keys;
124
+ if (filteredKeys.length === 0) {
125
+ console.log(`No environment variables matching '${filter}' found.`);
126
+ return;
127
+ }
128
+ console.log(`📋 Environment Variables (${filteredKeys.length} items):\n`);
129
+ console.log('─'.repeat(60));
130
+ for (const key of filteredKeys) {
131
+ if (keysOnly) {
132
+ console.log(key);
133
+ }
134
+ else {
135
+ console.log(`${key}=${secrets[key]}`);
136
+ }
137
+ }
138
+ console.log('─'.repeat(60));
139
+ }
140
+ catch (error) {
141
+ console.error('\n❌ Error:', error.message);
142
+ process.exit(1);
143
+ }
144
+ }
145
+ main();
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@optima-chat/dev-skills",
3
- "version": "0.7.15",
3
+ "version": "0.7.17",
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
8
  "optima-query-db": "./dist/bin/helpers/query-db.js",
9
- "optima-generate-test-token": "./dist/bin/helpers/generate-test-token.js"
9
+ "optima-generate-test-token": "./dist/bin/helpers/generate-test-token.js",
10
+ "optima-show-env": "./dist/bin/helpers/show-env.js"
10
11
  },
11
12
  "scripts": {
12
13
  "postinstall": "node scripts/install.js",