Kaynağa Gözat

chore: remove .agents from git tracking

Add .agents/ to .gitignore and untrack skill files.
master
fengsilin 1 hafta önce
ebeveyn
işleme
c64e9c0b40
9 değiştirilmiş dosya ile 1 ekleme ve 770 silme
  1. +0
    -65
      .agents/skills/cmd-add-channel/SKILL.md
  2. +0
    -142
      .agents/skills/cmd-claude-stats/SKILL.md
  3. +0
    -198
      .agents/skills/cmd-debug-prod/SKILL.md
  4. +0
    -98
      .agents/skills/cmd-deploy-local/SKILL.md
  5. +0
    -44
      .agents/skills/cmd-deploy-wsl-test/SKILL.md
  6. +0
    -34
      .agents/skills/cmd-deploy/SKILL.md
  7. +0
    -86
      .agents/skills/cmd-ob-commit/SKILL.md
  8. +0
    -103
      .agents/skills/cmd-set-channel-pricing/SKILL.md
  9. +1
    -0
      .gitignore

+ 0
- 65
.agents/skills/cmd-add-channel/SKILL.md Dosyayı Görüntüle

@@ -1,65 +0,0 @@
---
allowed-tools: mcp__plugin_chrome-devtools-mcp_chrome-devtools__*
description: 'Command: add-channel (imported from Claude Code)'
name: cmd-add-channel
---

## 添加渠道

通过 Chrome DevTools MCP 在指定环境中操作浏览器完成渠道添加。

### 参数

用户在 `$ARGUMENTS` 中传入 JSON 格式的渠道信息(字段均可选,缺失时会询问):

```
{
"base_url": "https://api.example.com",
"api_key": "sk-xxx",
"name": "渠道名称",
"type": "OpenAI",
"target": "http://localhost:23000",
"select_all_models": true
}
```

| 字段 | 说明 | 默认值 |
|------|------|--------|
| `target` | 目标环境地址 | 询问用户 |
| `base_url` | 渠道 API 地址 | 询问用户 |
| `api_key` | 渠道密钥 | 询问用户 |
| `name` | 渠道名称 | 自动从 base_url 提取域名 |
| `type` | 渠道类型 | `OpenAI` |
| `select_all_models` | 是否全选模型 | `true` |

如果 `$ARGUMENTS` 不是 JSON,则按顺序解析为 `base_url` `api_key`,其余使用默认值。

### 操作流程

1. **导航到目标页面** — `navigate_page` 到 `{target}/console/channel`
2. **检查登录状态** — `take_snapshot`,如果没有登录(看不到侧边栏菜单),提示用户先登录
3. **点击添加渠道** — 找到并点击"添加渠道"按钮
4. **填写表单** — 按 snap 快照中的元素 uid,依次 `fill`:
- 名称(名称输入框)
- 密钥(密钥输入框)
- API地址(API地址输入框)
5. **获取并选择模型**:
- 点击"填入所有模型"按钮
- 等待模型选择对话框出现
- 如果 `select_all_models` 为 true,点击全选 checkbox,然后点击 confirm
6. **提交** — 点击"提交"按钮
7. **验证** — `take_snapshot` 确认渠道列表中出现了新建的渠道

### 测试环境地址

| 环境 | 地址 | 说明 |
|------|------|------|
| 国内测试 | http://localhost:23000 | WSL 本地 |
| 国外测试 | http://localhost:13000 | WSL 本地 |
| 生产环境 | https://api.example.com | 按实际填写 |

### 要求

- 每步操作后用 `take_snapshot` 验证页面状态
- 如果某步操作失败(如获取模型列表超时),报告错误并询问用户是否继续
- 完成后向用户总结创建结果(渠道名称、类型、模型数量、状态)

+ 0
- 142
.agents/skills/cmd-claude-stats/SKILL.md Dosyayı Görüntüle

@@ -1,142 +0,0 @@
---
allowed-tools: Bash(wsl -- *)
description: 'Command: claude-stats (imported from Claude Code)'
name: cmd-claude-stats
---

## Claude 模型统计

查询 Claude 模型的**错误率**和**缓存率**,自动排除 `relay-pulse` 检测令牌。

### 参数 `$ARGUMENTS`

根据 `$ARGUMENTS` 确定日期范围:

| 传入格式 | 含义 |
|---------|------|
| (空) | 今天 |
| `2026-05-09` | 指定某一天 |
| `2026-05-01 2026-05-09` | 指定日期范围(含首尾两天) |
| `7d` | 最近 7 天 |

### 执行步骤

**第一步:根据参数计算日期过滤条件**

- `created_at` 字段是秒级 Unix 时间戳(bigint),用 `UNIX_TIMESTAMP('YYYY-MM-DD')` 转换
- 今天:`created_at >= UNIX_TIMESTAMP(CURDATE())`
- 某一天 `D`:`created_at >= UNIX_TIMESTAMP('D') AND created_at < UNIX_TIMESTAMP('D') + 86400`
- 范围 `D1` 到 `D2`:`created_at >= UNIX_TIMESTAMP('D1') AND created_at < UNIX_TIMESTAMP('D2') + 86400`
- 最近 N 天:`created_at >= UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL N-1 DAY))`

将计算好的条件替换到下面 SQL 中的 `{DATE_FILTER}` 占位符。

**第二步:上传 SQL 文件到服务器**

```bash
wsl -- bash -c "
cat > /tmp/claude_stats_error.sql << 'ENDSQL'
SELECT
model_name,
SUM(CASE WHEN type = 2 THEN 1 ELSE 0 END) as success,
SUM(CASE WHEN type = 5 THEN 1 ELSE 0 END) as errors,
COUNT(*) as total,
ROUND(SUM(CASE WHEN type = 5 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as error_rate_pct
FROM logs
WHERE {DATE_FILTER}
AND model_name LIKE '%claude%'
AND type IN (2, 5)
AND token_name != 'relay-pulse'
GROUP BY model_name
ORDER BY total DESC;
ENDSQL

cat > /tmp/claude_stats_cache.sql << 'ENDSQL'
SELECT
model_name,
COUNT(*) as total_requests,
SUM(prompt_tokens) as prompt_tokens,
SUM(completion_tokens) as completion_tokens,
SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)) as cache_read_tokens,
SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) as cache_creation_tokens,
SUM(CASE WHEN CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED) > 0 THEN 1 ELSE 0 END) as cache_hit_requests,
ROUND(
SUM(CASE WHEN CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED) > 0 THEN 1 ELSE 0 END) * 100.0 / COUNT(*),
2
) as cache_hit_rate_pct,
ROUND(
(SUM(prompt_tokens) * 1.0
+ SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)) * 0.1
+ SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) * 1.25)
* 100.0
/ NULLIF(
SUM(prompt_tokens)
+ SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED))
+ SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)),
0),
2
) as cost_pct_of_full,
ROUND(
SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_creation_tokens')), 0) AS UNSIGNED)) * 1.0
/ NULLIF(SUM(CAST(IFNULL(JSON_UNQUOTE(JSON_EXTRACT(other, '$.cache_tokens')), 0) AS UNSIGNED)), 0),
3
) as creation_to_read_ratio
FROM logs
WHERE {DATE_FILTER}
AND type = 2
AND model_name LIKE '%claude%'
AND other IS NOT NULL
AND token_name != 'relay-pulse'
GROUP BY model_name
ORDER BY total_requests DESC;
ENDSQL

cat > /tmp/claude_stats_errcode.sql << 'ENDSQL'
SELECT
model_name,
CAST(JSON_UNQUOTE(JSON_EXTRACT(other, '$.status_code')) AS UNSIGNED) as status_code,
COUNT(*) as cnt,
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (PARTITION BY model_name), 1) as pct
FROM logs
WHERE {DATE_FILTER}
AND type = 5
AND model_name LIKE '%claude%'
AND token_name != 'relay-pulse'
AND other IS NOT NULL
GROUP BY model_name, status_code
ORDER BY model_name, cnt DESC;
ENDSQL

scp /tmp/claude_stats_error.sql root@139.180.189.205:/tmp/claude_stats_error.sql
scp /tmp/claude_stats_cache.sql root@139.180.189.205:/tmp/claude_stats_cache.sql
scp /tmp/claude_stats_errcode.sql root@139.180.189.205:/tmp/claude_stats_errcode.sql
"
```

**第三步:执行查询并展示结果**

```bash
wsl -- bash -c "ssh -o ConnectTimeout=20 -o ServerAliveInterval=10 root@139.180.189.205 'echo \"=== 错误率 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_error.sql; echo; echo \"=== 缓存 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_cache.sql; echo; echo \"=== 错误状态码分布 ===\"; docker exec -i mysql mysql -uroot -pLanqi123456 new-api < /tmp/claude_stats_errcode.sql' 2>&1 | grep -v 'Warning'"
```

### 字段说明

**错误率表:**
- `success` — 正常请求数(type=2)
- `errors` — 错误请求数(type=5)
- `error_rate_pct` — 错误率 %

**缓存率表:**
- `cache_hit_rate_pct` — **次数缓存率** = 有缓存命中的请求数 / 总请求数(最能反映缓存策略是否生效)
- `cost_pct_of_full` — **实际成本占比** = `(prompt × 1 + cache_read × 0.1 + cache_creation × 1.25) / (全量按原价计费)`,越低越省钱(Anthropic 标准定价:cache_read 是原价 10%,cache_creation 是原价 125%)
- `creation_to_read_ratio` — **缓存创建/读取比** = `cache_creation_tokens / cache_read_tokens`,比值高说明缓存频繁失效再重建,命中复用差

**错误状态码分布表:**
- `status_code` — HTTP 状态码(504=上游超时,429=限流,400=请求参数错误)
- `cnt` — 该状态码的错误次数
- `pct` — 占该模型全部错误的百分比

### 注意事项

- 日期以 OV 服务器(UTC+0)的时区为准,北京时间当天 08:00 后才对应同一自然日
- `relay-pulse` 是自动探活令牌,已从统计中排除

+ 0
- 198
.agents/skills/cmd-debug-prod/SKILL.md Dosyayı Görüntüle

@@ -1,209 +0,0 @@
---
allowed-tools: Bash(wsl -- *)
description: 'Command: debug-prod (imported from Claude Code)'
name: cmd-debug-prod
---

## 线上排查命令

用户要求排查线上问题。根据 `$ARGUMENTS` 确定目标服务器,然后根据问题类型选择合适的操作。

### 参数

`$ARGUMENTS` 中可能传入:
- (空) — 默认排查国外服务器(OV,主节点)
- `cn` — 只排查国内服务器
- `ov` — 只排查国外服务器
- `all` — 排查两台服务器

如果用户没有明确指定,**默认排查 OV 服务器**(因为 MySQL 主库在 OV)。

---

### 服务器配置

| 节点 | SSH | docker-compose 目录 | new-api 容器名 | MySQL 容器名 |
|------|-----|---------------------|---------------|-------------|
| 🇨🇳 国内 CN | `root@123.57.74.135` | `/root/new-api/` | `cn-new-api` | `ov-mysql` |
| 🌏 国外 OV | `root@139.180.189.205` | `/root/new-api/new-api/` | `ov-new-api` | `mysql` |

**重要**:两台服务器的 MySQL 实际都在 OV(国外节点)。CN 的 SQL_DSN 指向 `ov-mysql:3306`。所以查数据库统一用 OV 的 MySQL 容器 `mysql`。

MySQL 连接:`docker exec mysql mysql -uroot -pLanqi123456 new-api -e "SQL语句"`

---

### 所有命令执行方式

**必须通过 WSL 执行**(SSH 密钥在 WSL 中):

```bash
# 单条命令
wsl -- bash -c "ssh root@HOST '命令'"

# 多条命令(引号嵌套复杂时用 heredoc)
wsl -- bash -c "ssh root@HOST 'cmd1 && cmd2 && cmd3'"
```

---

### 操作指南

根据用户描述的问题,选择合适的排查步骤。**不要一次性执行所有操作**,应该根据问题逐步排查。

#### 1. 服务状态检查

```bash
# 查看所有容器状态
wsl -- bash -c "ssh root@HOST 'cd COMPOSE_DIR && docker compose ps'"

# 健康检查
wsl -- bash -c "ssh root@HOST 'curl -s http://localhost:3000/api/status'"

# 系统资源(CPU/内存/磁盘)
wsl -- bash -c "ssh root@HOST 'free -h && df -h / && docker stats --no-stream'"
```

#### 2. 应用日志

```bash
# 最近 N 行容器日志
wsl -- bash -c "ssh root@HOST 'docker logs --tail 100 CONTAINER_NAME'"

# 实时跟踪日志(带超时,避免阻塞)
wsl -- bash -c "ssh root@HOST 'timeout 5 docker logs --tail 50 --since 5m CONTAINER_NAME'"

# 搜索特定关键词(如错误、某用户、某模型)
wsl -- bash -c "ssh root@HOST 'docker logs --tail 500 CONTAINER_NAME 2>&1 | grep -i KEYWORD'"

# 应用日志文件(oneapi-*.log)
wsl -- bash -c "ssh root@HOST 'ls -lt COMPOSE_DIR/logs/ | head -5'"
wsl -- bash -c "ssh root@HOST 'tail -100 COMPOSE_DIR/logs/oneapi-XXXX.log'"
```

#### 3. MySQL 查询

**连接方式(在 OV 服务器上执行)**:
```bash
wsl -- bash -c "ssh root@139.180.189.205 'docker exec mysql mysql -uroot -pLanqi123456 new-api -e \"SQL语句\"'"
```

注意:SQL 语句中的双引号需要用 `\"` 转义。

**常用查询模板**:

```sql
SELECT id, username, email, role, status, quota, used_quota, \`group\`, aff_code FROM users WHERE username = 'XXX';

SELECT id, created_at, type, model_name, quota, channel_id, content FROM logs WHERE user_id = XXX ORDER BY created_at DESC LIMIT 20;

SELECT id, created_at, type, content, model_name FROM logs WHERE created_at >= '2026-04-16 00:00:00' AND type = 2 ORDER BY created_at DESC LIMIT 50;

SELECT id, name, type, status, balance, used_quota, models, \`group\`, priority FROM channels WHERE status != 3;

SELECT id, created_at, model_name, quota, content FROM logs WHERE channel_id = XXX ORDER BY created_at DESC LIMIT 20;

SELECT id, name, \`key\`, status, remain_quota, used_quota, expired_time FROM tokens WHERE user_id = XXX;

SELECT id, user_id, amount, money, trade_no, status, created_at FROM topups ORDER BY created_at DESC LIMIT 20;

SELECT id, user_id, plan_id, status, amount, created_at FROM subscription_orders ORDER BY created_at DESC LIMIT 20;

SELECT * FROM pending_sync_records ORDER BY id DESC LIMIT 20;
SELECT * FROM quota_sync_logs ORDER BY id DESC LIMIT 20;

SELECT id, user_id, action, status, progress, fail_reason, created_at FROM midjourneys ORDER BY created_at DESC LIMIT 20;

SELECT \`key\`, value FROM options WHERE \`key\` IN ('ServerAddress', 'TopUpLink', 'QuotaForNewUser', 'QuotaForInviter', 'QuotaForInvitee');
```

**日志类型 (type 字段)**:
- `1` — 消耗 (consume)
- `2` — 充值 (recharge/topup)
- `3` — 管理员操作
- `4` — 系统

#### 4. Relay 抓包日志(请求体/响应体完整记录)

对开启了 `capture_relay` 的用户,系统会将完整的请求体和响应体写入容器内文件。适用于需要查看客户端实际发送的请求体内容的场景(如验证字段是否正确、排查请求格式问题)。

**文件路径**(容器内):`/data/data/relay-capture/{YYYY-MM-DD}/{requestID}.log`

```bash
# 列出某天的抓包文件(最新 20 个)
wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME ls -lt /data/data/relay-capture/2026-05-14/ | head -20"'

# 查看特定请求的抓包内容(requestID 从日志错误行中获取)
wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME cat /data/data/relay-capture/2026-05-14/REQUEST_ID.log"'

# 文件很大时,只看请求头 + 请求体前 2000 字节
wsl -- bash -c 'ssh root@HOST "docker exec CONTAINER_NAME head -c 2000 /data/data/relay-capture/2026-05-14/REQUEST_ID.log"'
```

**抓包文件格式**:
```
=== REQUEST 2026-05-14T09:09:51.80665026Z ===
POST /v1/chat/completions
user_id: 44
X-Forwarded-For: 184.73.225.134
User-Agent: Cursor/1.0
Content-Type: application/json
...

{"stream":true,"model":"openai/gpt-5.4","messages":[...]}

=== RESPONSE ===
{"error":{"message":"field messages is required",...}}

=== END duration_ms=6 ===
```

**使用场景**:
- 客户端发送了错误格式的请求体(如用 `input` 代替 `messages`)
- 需要确认请求头、User-Agent、请求体字段
- 排查特定 request ID 的完整请求/响应链路

**注意**:
- 只有开启了 `capture_relay` 的用户才有抓包文件,未开启的用户查不到
- 请求体可能很大(100KB+),建议先用 `head -c` 限制输出大小
- 抓包文件名即 request ID,可从容器的 `[ERR]` 日志行中提取

#### 5. 容器内操作

```bash
# 进入容器执行命令(如检查网络连通性)
wsl -- bash -c "ssh root@HOST 'docker exec CONTAINER_NAME wget -qO- http://localhost:3000/api/status'"

# 重启某个服务(谨慎操作,先确认用户意图)
wsl -- bash -c "ssh root@HOST 'cd COMPOSE_DIR && docker compose restart new-api'"
```

---

### 排查流程建议

1. **先问清楚问题**:什么现象?什么时候开始的?影响哪些用户?
2. **服务状态** → 检查容器是否正常运行
3. **应用日志** → 搜索错误关键词、时间范围
4. **数据库查询** → 根据日志中的线索查相关数据
5. **Relay 抓包** → 如果日志中只有错误摘要但看不清请求体细节,检查用户是否开启了 `capture_relay`,若有则读取抓包文件查看完整请求/响应
6. **综合分析** → 给出问题原因和修复建议

### 注意事项

- **不要执行任何写入操作**(INSERT/UPDATE/DELETE),除非用户明确要求
- MySQL 查询要加 `LIMIT`,避免返回过多数据
- 查询时间范围要合理,不要全表扫描
- 如果发现需要重启服务,先告知用户再操作
- 所有输出向用户展示时,用中文解释含义

+ 0
- 98
.agents/skills/cmd-deploy-local/SKILL.md Dosyayı Görüntüle

@@ -1,98 +0,0 @@
---
allowed-tools: Bash
description: 'Command: deploy-local (imported from Claude Code)'
name: cmd-deploy-local
---

## 启动本机开发环境

在 Windows 上直接运行 `go run main.go`,数据库使用 WSL 中的 MySQL 和 Redis。

### 环境信息

| 项目 | 连接信息 |
|------|---------|
| MySQL | `localhost:33306` root/Lanqi123456 db:new-api |
| Redis | `localhost:36379` |
| 后端 | `localhost:3000` |
| 前端 | `localhost:5173`(dev server) |
| 管理员 | root / 12345678 |

### 参数

用户可能在 `$ARGUMENTS` 中传入:
- (空) — 启动全部(MySQL/Redis + 前端 + 后端)
- `--backend-only` — 只启动后端(MySQL/Redis + 后端)
- `--frontend-only` — 只启动前端 dev server
- `--stop` — 停止所有服务(后端进程 + 前端进程)

### 执行步骤

**步骤 1:确保 WSL 中 MySQL 和 Redis 运行**

```bash
wsl -- bash -c "cd /root/new-api-dev && docker compose up -d"
```

等待 MySQL 就绪(最多 30 秒):

```bash
until wsl -- bash -c "mysql -h 127.0.0.1 -P 3306 -u root -pLanqi123456 -e 'SELECT 1'" 2>/dev/null; do sleep 2; done
```

**步骤 2:杀掉旧进程(如果端口被占用)**

检查并杀掉占用 3000 端口的进程:
```bash
netstat -ano | grep ":3000 " | grep LISTENING | awk '{print $5}' | sort -u | while read pid; do taskkill //PID $pid //F 2>/dev/null; done
```

检查并杀掉占用 5173 端口的进程(如果需要启动前端):
```bash
netstat -ano | grep ":5173 " | grep LISTENING | awk '{print $5}' | sort -u | while read pid; do taskkill //PID $pid //F 2>/dev/null; done
```

**步骤 3:启动服务**

前端(后台,仅在非 `--backend-only` 时):
```bash
cd web && bun run dev
```

后端(后台,仅在非 `--frontend-only` 时),带环境变量:
```bash
export SQL_DSN="root:Lanqi123456@tcp(localhost:33306)/new-api"
export REDIS_CONN_STRING="redis://localhost:36379"
export SESSION_SECRET="dev-secret-do-not-use-in-prod"
export SESSION_NAME="session_dev"
export DEBUG=1
export ERROR_LOG_ENABLED=true
export BATCH_UPDATE_ENABLED=true
export TZ=Asia/Shanghai
go run main.go
```

**步骤 4:等待就绪并验证**

等待后端就绪:
```bash
until curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/status | grep -q "200"; do sleep 2; done
```

**步骤 5:报告状态**

向用户报告:
- 各服务状态(MySQL/Redis/后端/前端)
- 访问地址
- 如果有服务启动失败,报告具体错误

### 停止服务(`--stop`)

杀掉 3000 和 5173 端口上的进程即可。MySQL/Redis 容器保持运行(数据持久化)。

### 要求

- 所有服务使用 `run_in_background` 启动
- 等待后端就绪后再报告
- 如果编译失败,报告具体错误
- 启动完成后提示用户可以使用 `curl` 或浏览器访问

+ 0
- 44
.agents/skills/cmd-deploy-wsl-test/SKILL.md Dosyayı Görüntüle

@@ -1,44 +0,0 @@
---
allowed-tools: Bash(wsl -- *)
description: 'Command: deploy-wsl-test (imported from Claude Code)'
name: cmd-deploy-wsl-test
---

## 部署到测试环境

将镜像构建并部署到 WSL 本地的国内/国外测试节点。

### 测试环境信息

| 项目 | 国内节点 | 国外节点 |
|------|---------|---------|
| 目录 | /root/new-api-cn | /root/new-api-ov |
| 端口 | 23000:3000 | 13000:3000 |
| MySQL | 23306 | 13306 |
| 容器名 | cn-new-api | ov-new-api |
| SESSION | session_m (Master) | session_slave (Slave) |

### 参数

用户可能在 `$ARGUMENTS` 中传入:
- (空) — 构建镜像 + 推送 + 部署到两个测试节点
- `cn` — 只部署到国内测试节点
- `ov` — 只部署到国外测试节点
- `--no-build` — 跳过构建推送,使用本地最新镜像
- 可以组合,如 `--no-build cn`

### 执行

使用以下命令在 WSL 中执行部署:

```bash
wsl -- bash -c "cd /root && bash //mnt/d/code/new-api/scripts/deploy-test.sh $ARGUMENTS"
```

**注意**:路径必须使用 `//mnt/d/...`(双斜杠),否则 Git Bash 会将其转换为 Windows 路径导致 WSL 找不到脚本。

### 要求

- 等待命令完成,实时向用户报告进度
- 如果失败,报告具体错误信息
- 完成后向用户总结部署结果(镜像 tag、各节点状态)

+ 0
- 34
.agents/skills/cmd-deploy/SKILL.md Dosyayı Görüntüle

@@ -1,34 +0,0 @@
---
allowed-tools: Bash(wsl -- *)
description: 'Command: deploy (imported from Claude Code)'
name: cmd-deploy
---

## 部署命令

通过 WSL 执行 `scripts/deploy.sh` 完成自动部署。

### 参数

用户可能在 `$ARGUMENTS` 中传入:
- (空) — 构建镜像 + 推送 + 部署到两台服务器
- `cn` — 只部署到国内服务器 (123.57.74.135)
- `ov` — 只部署到国外服务器 (139.180.189.205)
- `--no-build` — 跳过构建推送,使用本地最新镜像
- 可以组合,如 `--no-build cn`

### 执行

使用以下命令调用部署脚本:

```bash
wsl -- bash -c "bash //mnt/d/code/new-api/scripts/deploy.sh $ARGUMENTS"
```

**注意**:路径必须使用 `//mnt/d/...`(双斜杠),否则 Git Bash 会将其转换为 Windows 路径导致 WSL 找不到脚本。

### 要求

- 等待命令完成,实时向用户报告进度
- 如果失败,报告具体错误信息
- 完成后向用户总结部署结果(镜像 tag、各节点状态)

+ 0
- 86
.agents/skills/cmd-ob-commit/SKILL.md Dosyayı Görüntüle

@@ -1,86 +0,0 @@
---
allowed-tools: >-
Bash(git add:*), Bash(git status:*), Bash(git diff:*), Bash(git log:*),
Bash(git commit:*), Bash(mkdir:*), Read, Write, Edit, Glob, Grep
description: 'Command: ob-commit (imported from Claude Code)'
name: cmd-ob-commit
---

## Context

- Current git status: !`git status`
- Current git diff (staged and unstaged changes): !`git diff HEAD`
- Current branch: !`git branch --show-current`
- Recent commits: !`git log --oneline -10`

## Task

Based on the above changes, create a git commit AND write a development log to Obsidian.

### Step 1: Create the commit

1. Analyze the changes and draft a commit message following conventional commits format.
2. Stage the relevant files and create the commit.

### Step 2: Write Obsidian dev log (MANDATORY)

After the commit succeeds, you MUST write a development log. Follow these rules exactly:

**Directory**: `D:\markdown\workspace-lanqi\new-api\{YYYY-MM-DD}\` (create if not exists)

**File naming**: `{YYYY-MM-DD} {commit message short summary}.md`
- If multiple commits on the same day, append a brief distinguishing suffix
- Example: `2026-04-16 fix: 修复支付回调签名验证.md`

**Log template** — write in Chinese:

```markdown
---
created: YYYY-MM-DD
tags:
- dev-log
- new-api
branch: {branch name}
commit: {short hash}
---

# {commit message}

> 分支:`{branch}` | Commit:`{short hash}` | 日期:YYYY-MM-DD

## 变更概述

{1-3 sentences summarizing purpose and impact}

## 新增文件

| 文件 | 说明 |
|------|------|
| `{path}` | {description} |

## 修改文件

| 文件 | 变更内容 |
|------|---------|
| `{path}` | {what changed and why} |

## 关键代码变更

{Detailed description of core logic changes, including function signature changes, new key functions, algorithm logic. Use code blocks for key snippets.}

## 数据库变更

{If table structure changed, list new tables, columns, indexes. Delete this section if none.}

## 备注

{Additional notes, design decisions, known issues. Delete this section if none.}
```

### Rules

- Delete sections with no content (数据库变更, 备注)
- All log content in Chinese
- Frontmatter MUST include: `created`, `tags` (at least `dev-log` and `new-api`), `branch`, `commit`
- Include enough detail for someone unfamiliar with the change to understand it
- You MUST use multiple tools in a single response. Stage, commit, then write the log file.

+ 0
- 103
.agents/skills/cmd-set-channel-pricing/SKILL.md Dosyayı Görüntüle

@@ -1,103 +0,0 @@
---
allowed-tools: mcp__plugin_chrome-devtools-mcp_chrome-devtools__*
description: 'Command: set-channel-pricing (imported from Claude Code)'
name: cmd-set-channel-pricing
---

## 设置渠道定价

通过 Chrome DevTools MCP 在指定环境中操作浏览器,为模型配置渠道定价并设置默认通道。

### 参数

用户在 `$ARGUMENTS` 中传入 JSON 格式的参数(字段均可选,缺失时会询问):

```
{
"target": "http://localhost:23000",
"model_name": "deepseek-ai/DeepSeek-V3-0324",
"default_channel": "AtlasCloud",
"channels": {
"AtlasCloud": { "model_ratio": 1, "completion_ratio": 1 },
"atlascloud": { "model_ratio": 1, "completion_ratio": 1 }
}
}
```

| 字段 | 说明 | 默认值 |
|------|------|--------|
| `target` | 目标环境地址 | 询问用户 |
| `model_name` | 要配置定价的模型名称 | 询问用户 |
| `default_channel` | 设为默认的渠道名称 | 不设置默认 |
| `channels` | 各渠道的定价配置 | 所有渠道统一设置 model_ratio=1, completion_ratio=1 |

如果 `$ARGUMENTS` 不是 JSON,按顺序解析为 `model_name`,其余使用默认值。

### 操作流程

1. **导航到渠道定价页面**
- `navigate_page` 到 `{target}/console/setting?tab=ratio`

2. **切换到渠道定价视图**
- `take_snapshot` 确认页面加载
- 找到并点击"分组与模型定价设置"标签页(如果 URL 未直接跳转)
- 点击"可视化倍率设置"子标签
- 点击"渠道定价"单选按钮

3. **搜索目标模型**
- 在搜索框中输入 `model_name`
- 等待列表过滤出目标模型

4. **展开模型行**
- 点击目标模型行的展开按钮(chevron_right)

5. **为每个渠道设置定价**
- 对展开后每个未配置的渠道行,点击编辑按钮(edit icon)
- 在弹出的编辑对话框中:
- 确认模型名称正确
- 选择计费类型(默认"按量计费")
- 填写模型倍率(`model_ratio`)
- 填写补全倍率(`completion_ratio`)
- 点击确认(confirm)保存
- 如果渠道已有定价但需要修改,同样点击编辑按钮更新

6. **设置默认通道**
- 在展开的模型行中,找到 `default_channel` 对应的渠道
- 点击该渠道行的星标按钮(star icon)
- 验证出现"已设为默认通道"提示和"默认"文字标签

7. **验证结果**
- `take_snapshot` 确认:
- 所有渠道都显示正确的倍率
- 默认渠道旁显示黄色星标 + "默认"标签
- 非默认渠道的星标为灰色
- 向用户总结配置结果

### 关键 UI 元素识别

| 元素 | 识别方式 |
|------|---------|
| 分组与模型定价设置 tab | 文本匹配 "分组与模型定价设置" |
| 可视化倍率设置 tab | 文本匹配 "可视化倍率设置" |
| 渠道定价 radio | 文本匹配 "渠道定价" |
| 模型行展开按钮 | 模型名称旁的 chevron_right 按钮 |
| 渠道编辑按钮 | 渠道行操作列的 edit 按钮 |
| 模型倍率输入框 | spinbutton,label 含 "模型倍率" |
| 补全倍率输入框 | spinbutton,label 含 "补全倍率" |
| 确认按钮 | 对话框底部的 confirm 按钮 |
| 默认星标按钮 | 渠道行"默认"列的 star 按钮 |

### 测试环境地址

| 环境 | 地址 | 说明 |
|------|------|------|
| 国内测试 | http://localhost:23000 | WSL 本地 |
| 国外测试 | http://localhost:13000 | WSL 本地 |
| 生产环境 | https://api.example.com | 按实际填写 |

### 要求

- 每步操作后用 `take_snapshot` 验证页面状态
- 如果模型不存在于列表中,报告错误并询问用户是否需要先添加渠道
- 如果渠道未在列表中显示(模型未关联到该渠道),提示用户该渠道不支持此模型
- 完成后向用户总结配置结果(模型名称、各渠道倍率、默认通道)

+ 1
- 0
.gitignore Dosyayı Görüntüle

@@ -23,6 +23,7 @@ plans
docs/plans/
CLAUDE.md
.claude
.agents/
.worktrees/
logs/
docs/superpowers


Yükleniyor…
İptal
Kaydet