@optima-chat/dev-skills 0.7.14 → 0.7.16

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.
@@ -192,7 +192,7 @@ print(f\"COMMERCE_DB_PASSWORD={secrets['COMMERCE_DB_PASSWORD']}\")
192
192
  " > /tmp/stage_db_config.sh && source /tmp/stage_db_config.sh
193
193
 
194
194
  # 4. 建立 SSH 隧道到 Shared EC2,通过隧道访问 Stage RDS
195
- ssh -i ~/.ssh/optima-ec2-key -f -N -L 15432:optima-stage-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com:5432 ec2-user@13.251.46.219
195
+ ssh -i ~/.ssh/optima-ec2-key -f -N -L 15432:optima-stage-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com:5432 ec2-user@3.0.210.113
196
196
 
197
197
  # 5. 通过本地端口 15432 连接到 RDS
198
198
  PGPASSWORD="${COMMERCE_DB_PASSWORD}" psql -h localhost -p 15432 -U "${COMMERCE_DB_USER}" -d optima_commerce -c "SELECT COUNT(*) FROM products"
@@ -249,7 +249,7 @@ pkill -f "ssh.*15432:${DATABASE_HOST}:5432"
249
249
  - Infisical 配置从 GitHub Variables 获取
250
250
  - 数据库密钥从 Infisical 动态获取(项目: optima-secrets-v2, 环境: staging, 路径: /shared-secrets/database-users)
251
251
  - Stage RDS: `optima-stage-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com`
252
- - Shared EC2 IP: `13.251.46.219`
252
+ - Shared EC2 IP: `3.0.210.113`
253
253
  - SSH 隧道: 本地端口 `15432` → Shared EC2 → Stage RDS `5432`
254
254
  - Stage 和 Prod 有独立的 RDS 实例
255
255
  - ⚠️ session-gateway 数据库名: Stage 用 `optima_shell`, Prod 用 `optima_ai_shell`
@@ -290,7 +290,7 @@ print(f\"COMMERCE_DB_PASSWORD={secrets['COMMERCE_DB_PASSWORD']}\")
290
290
  " > /tmp/prod_db_config.sh && source /tmp/prod_db_config.sh
291
291
 
292
292
  # 4. 建立 SSH 隧道到 Shared EC2,通过隧道访问 Prod RDS
293
- ssh -i ~/.ssh/optima-ec2-key -f -N -L 15433:optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com:5432 ec2-user@13.251.46.219
293
+ ssh -i ~/.ssh/optima-ec2-key -f -N -L 15433:optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com:5432 ec2-user@3.0.210.113
294
294
 
295
295
  # 5. 通过本地端口 15433 连接到 RDS
296
296
  PGPASSWORD="${COMMERCE_DB_PASSWORD}" psql -h localhost -p 15433 -U "${COMMERCE_DB_USER}" -d optima_commerce -c "SELECT COUNT(*) FROM products"
@@ -347,7 +347,7 @@ pkill -f "ssh.*15433:${DATABASE_HOST}:5432"
347
347
  - Infisical 配置从 GitHub Variables 获取
348
348
  - 数据库密钥从 Infisical 动态获取(项目: optima-secrets-v2, 环境: prod, 路径: /shared-secrets/database-users)
349
349
  - Prod RDS: `optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com`
350
- - Shared EC2 IP: `13.251.46.219`
350
+ - Shared EC2 IP: `3.0.210.113`
351
351
  - SSH 隧道: 本地端口 `15433` → Shared EC2 → Prod RDS `5432`
352
352
  - Stage 用端口 `15432`,Prod 用端口 `15433`
353
353
  - Stage 和 Prod 有独立的 RDS 实例
@@ -203,7 +203,7 @@ optima-query-db commerce-backend "SELECT status, COUNT(*) FROM orders GROUP BY s
203
203
  | Stage | `optima-stage-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com` | 15432 |
204
204
  | Prod | `optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com` | 15433 |
205
205
 
206
- **跳板机**: `13.251.46.219` (Shared EC2)
206
+ **跳板机**: `3.0.210.113` (Shared EC2)
207
207
 
208
208
  ## 🔗 相关命令
209
209
 
@@ -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` - 查询数据库
@@ -51,8 +51,8 @@ const RDS_HOSTS = {
51
51
  prod: 'optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com'
52
52
  };
53
53
 
54
- // 统一使用 Shared EC2 作为跳板机
55
- const EC2_HOST = '13.251.46.219';
54
+ // 统一使用 BI Data ARM Host 作为跳板机
55
+ const EC2_HOST = '3.0.210.113';
56
56
 
57
57
  function getGitHubVariable(name: string): string {
58
58
  return execSync(`gh variable get ${name} -R Optima-Chat/optima-dev-skills`, { encoding: 'utf-8' }).trim();
@@ -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();
@@ -68,8 +68,8 @@ const RDS_HOSTS = {
68
68
  stage: 'optima-stage-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com',
69
69
  prod: 'optima-prod-postgres.ctg866o0ehac.ap-southeast-1.rds.amazonaws.com'
70
70
  };
71
- // 统一使用 Shared EC2 作为跳板机
72
- const EC2_HOST = '13.251.46.219';
71
+ // 统一使用 BI Data ARM Host 作为跳板机
72
+ const EC2_HOST = '3.0.210.113';
73
73
  function getGitHubVariable(name) {
74
74
  return (0, child_process_1.execSync)(`gh variable get ${name} -R Optima-Chat/optima-dev-skills`, { encoding: 'utf-8' }).trim();
75
75
  }
@@ -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.14",
3
+ "version": "0.7.16",
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",