@optima-chat/dev-skills 0.7.3 → 0.7.5

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.
@@ -127,15 +127,24 @@ aws logs get-log-events --log-group-name /ecs/commerce-backend-stage --log-strea
127
127
 
128
128
  ### 2. Prod 环境(environment = "prod")
129
129
 
130
- **日志路径格式**: `/optima/prod/{service}`
130
+ **日志路径格式**: `/optima/prod/{service}` 或 `/optima/prod/ec2-1az/{service}`
131
131
 
132
- **步骤**:
132
+ **IMPORTANT**: Prod 环境必须指定 `--region ap-southeast-1`
133
+
134
+ **推荐方式(使用 aws logs tail)**:
135
+ ```bash
136
+ # 查看最近 1 小时的日志
137
+ aws logs tail /optima/prod/commerce-backend --since 1h --region ap-southeast-1
138
+
139
+ # 查看 MCP 服务日志(ec2-1az 路径)
140
+ aws logs tail /optima/prod/ec2-1az/commerce-mcp --since 1h --region ap-southeast-1
141
+ ```
142
+
143
+ **备用方式(使用 get-log-events)**:
133
144
  ```bash
134
145
  # 获取日志内容(纯文本)
135
- # 注意:Prod 环境的 log stream 通常是固定的 "backend"
136
- # 使用 --no-start-from-head 从最新日志开始读取
137
146
  # IMPORTANT: 必须使用单行命令,不要使用反斜杠换行
138
- aws logs get-log-events --log-group-name /optima/prod/commerce-backend --log-stream-name backend --limit 50 --no-start-from-head | jq -r '.events[] | .message'
147
+ aws logs get-log-events --log-group-name /optima/prod/commerce-backend --log-stream-name backend --limit 50 --no-start-from-head --region ap-southeast-1 | jq -r '.events[] | .message'
139
148
  ```
140
149
 
141
150
  **服务映射**:
@@ -145,13 +154,20 @@ aws logs get-log-events --log-group-name /optima/prod/commerce-backend --log-str
145
154
  - `agentic-chat` → `/optima/prod/agentic-chat`
146
155
  - `commerce-mcp` → `/optima/prod/ec2-1az/commerce-mcp`
147
156
  - `comfy-mcp` → `/optima/prod/ec2-1az/comfy-mcp`
157
+ - `fetch-mcp` → `/optima/prod/ec2-1az/fetch-mcp`
158
+ - `shopify-mcp` → `/optima/prod/ec2-1az/shopify-mcp`
159
+ - `perplexity-mcp` → `/optima/prod/ec2-1az/perplexity-mcp`
160
+ - `google-ads-mcp` → `/optima/prod/ec2-1az/google-ads-mcp`
148
161
 
149
162
  **Log Stream 名称**:
150
- - `backend` - 主服务日志(核心服务和 commerce-mcp 使用)
163
+ - `backend` - 主服务日志
151
164
  - `rq-worker` - 后台任务日志
152
165
  - `rq-scheduler` - 调度器日志
153
166
 
154
- **注意**: MCP 服务(commerce-mcp、comfy-mcp 等)部署在 ec2-1az,日志路径为 `/optima/prod/ec2-1az/{service}`
167
+ **注意**:
168
+ - MCP 服务部署在 EC2 (ec2-1az),日志路径为 `/optima/prod/ec2-1az/{service}`
169
+ - 核心服务(commerce-backend、user-auth 等)日志路径为 `/optima/prod/{service}`
170
+ - **必须指定 `--region ap-southeast-1`**
155
171
 
156
172
  ## 完整示例脚本
157
173
 
@@ -168,12 +184,15 @@ aws logs get-log-events --log-group-name /ecs/${SERVICE}-stage --log-stream-name
168
184
 
169
185
  ### Prod 环境
170
186
  ```bash
171
- # IMPORTANT: 使用单行命令
172
- SERVICE="commerce-backend"
173
- LINES=50
187
+ # 推荐方式:使用 aws logs tail
188
+ # 核心服务
189
+ aws logs tail /optima/prod/commerce-backend --since 1h --region ap-southeast-1
190
+
191
+ # MCP 服务(ec2-1az 路径)
192
+ aws logs tail /optima/prod/ec2-1az/commerce-mcp --since 1h --region ap-southeast-1
174
193
 
175
- # 显示主服务日志(从最新开始)
176
- aws logs get-log-events --log-group-name /optima/prod/${SERVICE} --log-stream-name backend --limit $LINES --no-start-from-head | jq -r '.events[] | .message'
194
+ # 备用方式:使用 get-log-events
195
+ aws logs get-log-events --log-group-name /optima/prod/commerce-backend --log-stream-name backend --limit 50 --no-start-from-head --region ap-southeast-1 | jq -r '.events[] | .message'
177
196
  ```
178
197
 
179
198
  ## 常见错误处理
package/README.md CHANGED
@@ -228,7 +228,7 @@ $ optima-query-db commerce-backend "SELECT id, title FROM products LIMIT 5" stag
228
228
 
229
229
  ## 🛠️ 开发状态
230
230
 
231
- **当前版本**: 0.7.3
231
+ **当前版本**: 0.7.4
232
232
 
233
233
  **已完成**:
234
234
  - ✅ 4 个命令:`/logs`、`/query-db`、`/generate-test-token`、`/read-code`
@@ -102,16 +102,59 @@ function setupSSHTunnel(ec2Host: string, dbHost: string, localPort: number): voi
102
102
  console.log(`✓ SSH tunnel established on port ${localPort}`);
103
103
  }
104
104
 
105
- function queryDatabase(host: string, port: number, user: string, password: string, database: string, sql: string): string {
106
- const psqlPath = '/usr/local/opt/postgresql@16/bin/psql';
105
+ function findPsqlPath(): string {
106
+ // 1. 优先从 PATH 中查找
107
+ const whichCmd = process.platform === 'win32' ? 'where psql' : 'which psql';
108
+ try {
109
+ const result = execSync(whichCmd, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
110
+ const foundPath = result.trim().split(/\r?\n/)[0]; // Windows where 可能返回 \r\n
111
+ if (foundPath && fs.existsSync(foundPath)) {
112
+ return foundPath;
113
+ }
114
+ } catch {
115
+ // which/where 失败,继续尝试常见路径
116
+ }
107
117
 
108
- if (!fs.existsSync(psqlPath)) {
109
- throw new Error('PostgreSQL client not found. Install with: brew install postgresql@16');
118
+ // 2. 回退到常见安装路径
119
+ const fallbackPaths = process.platform === 'win32'
120
+ ? [
121
+ 'C:\\Program Files\\PostgreSQL\\16\\bin\\psql.exe',
122
+ 'C:\\Program Files\\PostgreSQL\\15\\bin\\psql.exe',
123
+ 'C:\\Program Files\\PostgreSQL\\14\\bin\\psql.exe',
124
+ ]
125
+ : [
126
+ '/usr/local/opt/postgresql@16/bin/psql', // macOS Homebrew
127
+ '/usr/local/opt/postgresql@15/bin/psql',
128
+ '/opt/homebrew/bin/psql', // macOS ARM Homebrew
129
+ '/usr/bin/psql', // Linux
130
+ '/usr/local/bin/psql',
131
+ ];
132
+
133
+ for (const p of fallbackPaths) {
134
+ if (fs.existsSync(p)) {
135
+ return p;
136
+ }
110
137
  }
111
138
 
139
+ // 3. 未找到
140
+ const installHint = process.platform === 'darwin'
141
+ ? 'brew install postgresql@16'
142
+ : process.platform === 'win32'
143
+ ? 'Download from https://www.postgresql.org/download/windows/'
144
+ : 'sudo apt install postgresql-client';
145
+
146
+ throw new Error(`PostgreSQL client (psql) not found. Install with: ${installHint}`);
147
+ }
148
+
149
+ function queryDatabase(host: string, port: number, user: string, password: string, database: string, sql: string): string {
150
+ const psqlPath = findPsqlPath();
151
+
112
152
  const result = execSync(
113
- `PGPASSWORD="${password}" ${psqlPath} -h ${host} -p ${port} -U ${user} -d ${database} -c "${sql}"`,
114
- { encoding: 'utf-8' }
153
+ `"${psqlPath}" -h ${host} -p ${port} -U ${user} -d ${database} -c "${sql}"`,
154
+ {
155
+ encoding: 'utf-8',
156
+ env: { ...process.env, PGPASSWORD: password }
157
+ }
115
158
  );
116
159
  return result;
117
160
  }
@@ -104,12 +104,52 @@ function setupSSHTunnel(ec2Host, dbHost, localPort) {
104
104
  (0, child_process_1.execSync)(`ssh -i ${sshKeyPath} -f -N -o StrictHostKeyChecking=no -L ${localPort}:${dbHost}:5432 ec2-user@${ec2Host}`, { stdio: 'inherit' });
105
105
  console.log(`✓ SSH tunnel established on port ${localPort}`);
106
106
  }
107
- function queryDatabase(host, port, user, password, database, sql) {
108
- const psqlPath = '/usr/local/opt/postgresql@16/bin/psql';
109
- if (!fs.existsSync(psqlPath)) {
110
- throw new Error('PostgreSQL client not found. Install with: brew install postgresql@16');
107
+ function findPsqlPath() {
108
+ // 1. 优先从 PATH 中查找
109
+ const whichCmd = process.platform === 'win32' ? 'where psql' : 'which psql';
110
+ try {
111
+ const result = (0, child_process_1.execSync)(whichCmd, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
112
+ const foundPath = result.trim().split(/\r?\n/)[0]; // Windows where 可能返回 \r\n
113
+ if (foundPath && fs.existsSync(foundPath)) {
114
+ return foundPath;
115
+ }
116
+ }
117
+ catch {
118
+ // which/where 失败,继续尝试常见路径
111
119
  }
112
- const result = (0, child_process_1.execSync)(`PGPASSWORD="${password}" ${psqlPath} -h ${host} -p ${port} -U ${user} -d ${database} -c "${sql}"`, { encoding: 'utf-8' });
120
+ // 2. 回退到常见安装路径
121
+ const fallbackPaths = process.platform === 'win32'
122
+ ? [
123
+ 'C:\\Program Files\\PostgreSQL\\16\\bin\\psql.exe',
124
+ 'C:\\Program Files\\PostgreSQL\\15\\bin\\psql.exe',
125
+ 'C:\\Program Files\\PostgreSQL\\14\\bin\\psql.exe',
126
+ ]
127
+ : [
128
+ '/usr/local/opt/postgresql@16/bin/psql', // macOS Homebrew
129
+ '/usr/local/opt/postgresql@15/bin/psql',
130
+ '/opt/homebrew/bin/psql', // macOS ARM Homebrew
131
+ '/usr/bin/psql', // Linux
132
+ '/usr/local/bin/psql',
133
+ ];
134
+ for (const p of fallbackPaths) {
135
+ if (fs.existsSync(p)) {
136
+ return p;
137
+ }
138
+ }
139
+ // 3. 未找到
140
+ const installHint = process.platform === 'darwin'
141
+ ? 'brew install postgresql@16'
142
+ : process.platform === 'win32'
143
+ ? 'Download from https://www.postgresql.org/download/windows/'
144
+ : 'sudo apt install postgresql-client';
145
+ throw new Error(`PostgreSQL client (psql) not found. Install with: ${installHint}`);
146
+ }
147
+ function queryDatabase(host, port, user, password, database, sql) {
148
+ const psqlPath = findPsqlPath();
149
+ const result = (0, child_process_1.execSync)(`"${psqlPath}" -h ${host} -p ${port} -U ${user} -d ${database} -c "${sql}"`, {
150
+ encoding: 'utf-8',
151
+ env: { ...process.env, PGPASSWORD: password }
152
+ });
113
153
  return result;
114
154
  }
115
155
  async function main() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optima-chat/dev-skills",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "Claude Code Skills for Optima development team - cross-environment collaboration tools",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,39 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "WebSearch",
5
- "WebFetch(domain:code.claude.com)",
6
- "WebFetch(domain:platform.claude.com)",
7
- "WebFetch(domain:github.com)",
8
- "Bash(gh repo view:*)",
9
- "Bash(gh repo clone:*)",
10
- "Bash(gh repo list:*)",
11
- "Read(//private/tmp/optima-docs/**)",
12
- "Read(//tmp/optima-docs/**)",
13
- "Bash(git init:*)",
14
- "Bash(gh repo create:*)",
15
- "Read(//private/tmp/optima-workspace/**)",
16
- "Read(//tmp/optima-workspace/**)",
17
- "Read(//tmp/optima-workspace/.claude/commands/**)",
18
- "Bash(git add:*)",
19
- "Bash(git push:*)",
20
- "Bash(find:*)",
21
- "Bash(git commit:*)",
22
- "Bash(aws logs get-log-events:*)",
23
- "Bash(npm install:*)",
24
- "Bash(optima-dev-skills:*)",
25
- "Bash(optima-generate-test-token:*)",
26
- "Bash(optima-query-db:*)",
27
- "Bash(gh variable set:*)",
28
- "Bash(npm publish:*)",
29
- "Bash(python3:*)",
30
- "Bash(gh api:*)",
31
- "Bash(curl -s http://auth.optima.chat/openapi.json)",
32
- "Bash(curl -s https://auth.optima.chat/openapi.json)",
33
- "Bash(cat:*)",
34
- "Bash(node /Users/verypro/optima-dev-skills/scripts/install.js:*)"
35
- ],
36
- "deny": [],
37
- "ask": []
38
- }
39
- }
@@ -1,188 +0,0 @@
1
- ---
2
- name: "logs"
3
- description: "当用户请求查看日志、查看服务日志、排查问题、看看日志、检查日志、商品服务日志、后端日志、API日志、正式环境日志、生产环境日志、CI环境日志、开发环境日志、MCP日志时,使用此技能。支持 CI、Stage、Prod 三个环境的 commerce-backend、user-auth、mcp-host、agentic-chat、commerce-mcp、comfy-mcp 服务。"
4
- allowed-tools: ["Bash", "SlashCommand"]
5
- ---
6
-
7
- # 查看服务器日志
8
-
9
- 当你需要查看服务日志排查问题时,使用这个场景。
10
-
11
- ## 🎯 适用情况
12
-
13
- - API 返回错误,需要查看详细错误信息
14
- - 服务行为异常,需要查看运行日志
15
- - 监控服务状态,查看日志输出
16
- - 排查数据库连接、配置问题
17
-
18
- ## 🚀 快速操作
19
-
20
- ### 1. 查看 CI 环境日志(默认)
21
-
22
- ```
23
- /logs commerce-backend
24
- /logs user-auth 100
25
- ```
26
-
27
- **说明**:
28
- - 查看 CI 开发环境(dev.optima.chat)
29
- - 默认环境,不需要指定 `ci` 参数
30
- - 通过 SSH + Docker Compose 访问
31
- - 从 GitHub Variables 获取认证信息
32
-
33
- ### 2. 查看 Stage 环境日志
34
-
35
- ```
36
- /logs commerce-backend 50 stage
37
- ```
38
-
39
- **说明**:
40
- - 查看 Stage 预发布环境
41
- - 使用 AWS CloudWatch Logs
42
-
43
- **常用服务**:
44
- - `commerce-backend` - 电商 API
45
- - `user-auth` - 用户认证
46
- - `mcp-host` - MCP 协调器
47
- - `agentic-chat` - AI 聊天服务
48
- - `commerce-mcp` - 电商 MCP 服务
49
- - `comfy-mcp` - ComfyUI MCP 服务
50
-
51
- ### 3. 查看更多日志行数
52
-
53
- ```
54
- /logs commerce-backend 200
55
- ```
56
-
57
- 查看最近 200 行日志,用于排查历史问题。
58
-
59
- ### 4. 查看 Prod 环境日志
60
-
61
- ```
62
- /logs commerce-backend 100 prod
63
- ```
64
-
65
- 查看生产环境日志(通过 AWS CloudWatch)。
66
-
67
- ## 📋 常见问题排查
68
-
69
- ### 问题 1:API 返回 500 错误
70
-
71
- **步骤**:
72
- 1. 查看日志:`/logs commerce-backend 100`
73
- 2. 搜索 ERROR 关键字
74
- 3. 查看完整错误堆栈
75
- 4. 定位问题代码或数据
76
-
77
- **示例日志**:
78
- ```
79
- ERROR - 2025-01-23 10:30:45 - Exception in /products endpoint
80
- Traceback:
81
- File "app/routes/products.py", line 45
82
- merchant = db.query(Merchant).filter(id == product.merchant_id).first()
83
- MerchantNotFound: Merchant with id 'xxx' not found
84
- ```
85
-
86
- ### 问题 2:服务启动失败
87
-
88
- **步骤**:
89
- 1. 查看启动日志:`/logs commerce-backend 200`
90
- 2. 查找启动错误信息
91
- 3. 检查环境变量、数据库连接
92
-
93
- **常见错误**:
94
- - 数据库连接失败
95
- - Redis 连接失败
96
- - 环境变量缺失
97
-
98
- **示例日志**:
99
- ```
100
- redis.exceptions.ConnectionError: Error connecting to localhost:8285.
101
- Multiple exceptions: [Errno 111] Connection refused
102
- ERROR: Application startup failed. Exiting.
103
- ```
104
-
105
- ### 问题 3:性能问题(响应慢)
106
-
107
- **步骤**:
108
- 1. 查看日志:`/logs commerce-backend`
109
- 2. 查找 "response_time" 或包含毫秒数的日志
110
- 3. 识别慢查询或慢接口
111
-
112
- **示例**:
113
- ```
114
- INFO - GET /products - response_time: 3500ms (SLOW)
115
- INFO - Database query took 3200ms: SELECT * FROM products WHERE...
116
- ```
117
-
118
- ## 🔍 日志分析技巧
119
-
120
- ### 过滤关键信息
121
-
122
- 查看日志后,可以使用 grep 过滤:
123
-
124
- ```bash
125
- # 只看错误
126
- /logs commerce-backend 200 | grep -i error
127
-
128
- # 只看特定 API
129
- /logs commerce-backend 200 | grep "GET /products"
130
-
131
- # 查看 Redis 相关日志
132
- /logs commerce-backend 200 | grep -i redis
133
- ```
134
-
135
- ### 日志级别
136
-
137
- 日志级别说明:
138
- - **ERROR** - 错误,需要立即处理
139
- - **WARNING** - 警告,可能有问题
140
- - **INFO** - 信息,正常运行日志
141
- - **DEBUG** - 调试信息,详细输出
142
-
143
- ## 🌐 环境对比
144
-
145
- ### CI 环境
146
-
147
- ```
148
- /logs user-auth 100 ci
149
- ```
150
-
151
- **特点**:
152
- - CI 开发环境,适合开发调试
153
- - 实时性最好
154
- - 查看 Docker Compose 日志
155
-
156
- ### Stage 环境
157
-
158
- ```
159
- /logs commerce-backend 100 stage
160
- ```
161
-
162
- **特点**:
163
- - 预发布环境
164
- - AWS ECS 运行
165
- - 通过 CloudWatch Logs 查看
166
-
167
- ### Prod 环境
168
-
169
- ```
170
- /logs commerce-backend 100 prod
171
- ```
172
-
173
- **特点**:
174
- - 生产环境
175
- - EC2 + Docker Compose
176
- - 通过 CloudWatch Logs 查看
177
-
178
- ## 💡 最佳实践
179
-
180
- 1. **先查日志,再动手修** - 不要猜测,看日志确认问题
181
- 2. **查足够多的行数** - 有时错误原因在更早的日志里
182
- 3. **关注启动日志** - 服务启动时的错误最关键
183
- 4. **保留错误日志** - 复制错误信息,方便分享讨论
184
- 5. **对比环境差异** - Stage 出错、Prod 正常?对比日志差异
185
-
186
- ## 🔗 相关命令
187
-
188
- - `/logs` - 查看服务日志(详细使用方法和技术细节请查看 `/logs --help`)