@optima-chat/dev-skills 0.16.2 → 0.16.4

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.
Files changed (37) hide show
  1. package/.claude/commands/logs.md +60 -3
  2. package/.claude/commands/trace-user.md +18 -6
  3. package/.claude/skills/cn-deploy/SKILL.md +5 -3
  4. package/.claude/skills/gateway-admin/SKILL.md +15 -0
  5. package/.claude/skills/logs/SKILL.md +10 -2
  6. package/.claude/skills/reset-onboarding/SKILL.md +116 -0
  7. package/.claude/skills/yzsgo-e2e/SKILL.md +51 -0
  8. package/.claude/skills/yzsgo-e2e/SYNC.md +10 -0
  9. package/.claude/skills/yzsgo-e2e/chat_driver.py +659 -0
  10. package/.claude/skills/yzsgo-e2e/judge_outcome.js +11 -0
  11. package/.claude/skills/yzsgo-e2e/judge_workflow.js +100 -0
  12. package/.claude/skills/yzsgo-e2e/preflight.py +44 -0
  13. package/.claude/skills/yzsgo-e2e/prep_conversation.py +21 -0
  14. package/.claude/skills/yzsgo-e2e/pull_wire.py +312 -0
  15. package/.claude/skills/yzsgo-e2e/run_e2e.py +122 -0
  16. package/.claude/skills/yzsgo-e2e/verify_drift.py +42 -0
  17. package/.codex/skills/cn-deploy/SKILL.md +5 -3
  18. package/.codex/skills/reset-onboarding/SKILL.md +116 -0
  19. package/.codex/skills/yzsgo-e2e/SKILL.md +51 -0
  20. package/.codex/skills/yzsgo-e2e/SYNC.md +10 -0
  21. package/.codex/skills/yzsgo-e2e/chat_driver.py +659 -0
  22. package/.codex/skills/yzsgo-e2e/judge_outcome.js +11 -0
  23. package/.codex/skills/yzsgo-e2e/judge_workflow.js +100 -0
  24. package/.codex/skills/yzsgo-e2e/preflight.py +44 -0
  25. package/.codex/skills/yzsgo-e2e/prep_conversation.py +21 -0
  26. package/.codex/skills/yzsgo-e2e/pull_wire.py +312 -0
  27. package/.codex/skills/yzsgo-e2e/run_e2e.py +122 -0
  28. package/.codex/skills/yzsgo-e2e/verify_drift.py +42 -0
  29. package/AGENTS.md +12 -6
  30. package/README.md +74 -61
  31. package/bin/helpers/cn-deploy.ts +44 -37
  32. package/bin/helpers/logs.ts +464 -31
  33. package/dist/bin/helpers/cn-deploy.js +43 -37
  34. package/dist/bin/helpers/logs.js +410 -31
  35. package/docs/superpowers/plans/2026-08-31-yzsgo-e2e.md +969 -0
  36. package/docs/superpowers/specs/2026-08-31-yzsgo-e2e-design.md +154 -0
  37. package/package.json +1 -1
package/AGENTS.md CHANGED
@@ -20,18 +20,24 @@ For code-reading tasks across Optima repositories, use `gh` commands against `Op
20
20
 
21
21
  ## Installed Codex Skills
22
22
 
23
- After `npm install -g @optima-chat/dev-skills`, this package installs skills under `~/.codex/skills/optima-dev/`:
23
+ After `npm install -g @optima-chat/dev-skills`, this package installs skills under `~/.codex/skills/optima-dev/`. `scripts/install.js` copies every directory it finds, so the list below mirrors `.codex/skills/` exactly and is pinned by `tests/service-matrix-alignment.test.js` — adding a skill without updating this list turns the test red.
24
24
 
25
+ - `account`
26
+ - `cn-deploy`
27
+ - `entitlement`
28
+ - `generate-test-token`
29
+ - `grant-credits`
30
+ - `grant-subscription`
25
31
  - `logs`
26
32
  - `query-db`
27
- - `show-env`
28
- - `generate-test-token`
29
33
  - `read-code`
30
- - `grant-subscription`
31
- - `grant-credits`
34
+ - `reset-onboarding`
32
35
  - `restart-ecs`
36
+ - `show-env`
33
37
  - `use-commerce-cli`
34
- - `cn-deploy`
38
+ - `yzsgo-e2e`
39
+
40
+ `discount-codes` and `gateway-admin` exist under `.claude/skills/` only, so they are not installed for Codex.
35
41
 
36
42
  ## Tooling Assumptions
37
43
 
package/README.md CHANGED
@@ -25,24 +25,33 @@ npm install -g @optima-chat/dev-skills@latest
25
25
 
26
26
  ## 🎯 核心理念
27
27
 
28
- Optima Dev Skills 让 Claude Code 能够直接在 **CIStageProd** 三个环境中执行开发任务。
28
+ Optima Dev Skills 让 Claude Code 能够直接在 **cistageprod、cn-stage、cn-prod** 五个环境中执行开发任务(后两个是阿里云侧,与 AWS 侧完全独立;并非每个 skill 都覆盖全部五个,逐个见下)。
29
29
 
30
30
  **核心价值**:
31
31
  - **即时执行** - Claude 直接执行操作,开发者零手动操作
32
32
  - **任务驱动** - 基于具体任务场景(查看日志、调用 API),不是抽象分类
33
- - **跨环境协作** - 统一的命令在 CI、Stage、Prod 三个环境中使用
34
-
35
- ## 📋 任务场景(6 个)
36
-
37
- 当 Claude Code 识别到以下任务时,会自动加载对应的 Skill
38
-
39
- - **logs** - 查看 CI/Stage/Prod 的服务器日志
40
- - **query-db** - 查询 CI/Stage/Prod 的数据库
41
- - **show-env** - 查看 Stage/Prod 的服务环境变量(从 Infisical
42
- - **generate-test-token** - 生成测试 Access Token 用于 API 测试
43
- - **use-commerce-cli** - 使用 Commerce CLI 管理电商店铺
33
+ - **跨环境协作** - 统一的命令在 AWS 侧(ci / stage / prod)与阿里云侧(cn-stage / cn-prod)通用
34
+
35
+ ## 📋 任务场景
36
+
37
+ 当 Claude Code 识别到以下任务时,会自动加载对应的 Skill。按目录字母序,与 `.claude/skills/` 一一对应(由 `tests/service-matrix-alignment.test.js` 校验,加 skill 漏更本清单会红):
38
+
39
+ - **account** - 查账号状态/订阅/权益,封禁与解封(stage / prod / cn-stage / cn-prod)
40
+ - **cn-deploy** - 把服务发布到 cn-stage,走云效流水线一条龙(cn-stage)
41
+ - **discount-codes** - 创建/生成/查看/停用 billing 优惠码(stage / prod
42
+ - **entitlement** - 授予、撤销、查看产品权益(stage / prod / cn-stage / cn-prod)
43
+ - **gateway-admin** - gateway 管理面:COO kill、warm-pool、credits adjust、config 读写(cn-stage / cn-prod)
44
+ - **generate-test-token** - 生成测试 Access Token 并配好 merchant,用于 API 测试
45
+ - **grant-credits** - 赠送、发放积分(stage / prod / cn-stage / cn-prod)
46
+ - **grant-subscription** - 开通、赠送、升级订阅(stage / prod / cn-stage / cn-prod)
47
+ - **logs** - 查看服务日志(stage / prod 走 CloudWatch,cn-stage / cn-prod 走 SLS;CI 走 SSH + Docker Compose,不经 `optima-logs`)
48
+ - **query-db** - 查询数据库、执行 SQL(ci / stage / prod / cn-stage / cn-prod)
44
49
  - **read-code** - 阅读 Optima-Chat 组织下任意仓库的代码
45
- - **discount-codes** - 创建/生成/查看/停用 billing 优惠码(Stage/Prod
50
+ - **reset-onboarding** - 重置账号的 onboarding 资格,让它重新触发新手引导问卷(cn-stage / cn-prod
51
+ - **restart-ecs** - 重启 ECS 服务(stage / prod)
52
+ - **show-env** - 查看服务环境变量,从 Infisical 取(stage / prod / cn-stage / cn-prod)
53
+ - **use-commerce-cli** - 用 Commerce CLI 管理电商店铺(商品、订单、库存、运费、集合、首页、国际化)
54
+ - **yzsgo-e2e** - 鸭嘴兽通用端到端测试:浏览器真机驱对话 + 拉 wire + 语义判定 + 提 issue(cn-prod;cn-stage 待核实)
46
55
 
47
56
  ## 👤 用户故事
48
57
 
@@ -71,29 +80,34 @@ Claude:
71
80
 
72
81
  | 环境 | 部署方式 | 服务器 | 访问地址示例 |
73
82
  |------|---------|--------|------------|
74
- | **CI** | Docker Compose | dev.optima.chat | api.optima.chat<br>auth.optima.chat<br>mcp.optima.chat |
75
- | **Stage** | AWS ECS | AWS ECS | api.stage.optima.onl<br>auth.stage.optima.onl<br>mcp.stage.optima.onl |
76
- | **Prod** | EC2 + Docker | AWS EC2 | api.optima.shop<br>auth.optima.shop<br>mcp.optima.shop |
83
+ | **ci** | Docker Compose | dev.optima.chat | api.optima.chat<br>auth.optima.chat<br>mcp.optima.chat |
84
+ | **stage** | AWS ECS | AWS ECS | api.stage.optima.onl<br>auth.stage.optima.onl |
85
+ | **prod** | AWS ECS | AWS ECS | api.optima.onl<br>auth.optima.onl |
86
+ | **cn-stage** | 阿里云 SAE(云效流水线发布) | 阿里云 SAE + RDS(经 buildbox ECS 跳板) | auth.stage.optima.chat<br>commerce.stage.optima.chat |
87
+ | **cn-prod** | 阿里云 SAE | 阿里云 SAE + RDS(经 buildbox ECS 跳板) | auth.yzsgo.com<br>commerce.yzsgo.com |
77
88
 
78
89
  **说明**:
79
- - **CI** - 团队共享的持续集成测试环境,部署在 dev.optima.chat 服务器
80
- - **Stage** - 预发布环境,用于上线前的最终验证
81
- - **Prod** - 生产环境,服务真实用户
90
+ - **ci** - 团队共享的持续集成测试环境,部署在 dev.optima.chat 服务器
91
+ - **stage** - 预发布环境,用于上线前的最终验证
92
+ - **prod** - 生产环境,服务真实用户
93
+ - **cn-stage / cn-prod** - 阿里云侧独立部署,与 AWS 侧完全无关(独立 Infisical 实例、独立 RDS 实例);cn-prod 服务境内真实用户
82
94
 
83
95
  ## 🚀 Claude Code 命令
84
96
 
85
97
  | 命令 | 说明 | 示例 | 跨环境 |
86
98
  |------|------|------|--------|
87
- | `/logs` | 查看服务日志 | `/logs commerce-backend 100` | |
88
- | `/query-db` | 查询数据库 | `/query-db user-auth "SELECT COUNT(*) FROM users"` | |
89
- | `/generate-test-token` | 生成测试 token | `/generate-test-token` | 🔧 Development |
99
+ | `/generate-test-token` | 生成测试 token | `/generate-test-token` | ci / stage / prod / cn-stage / cn-prod |
100
+ | `/logs` | 查看服务日志 | `/logs commerce-backend 100` | ci / stage / prod / cn-stage / cn-prod |
101
+ | `/query-db` | 查询数据库 | `/query-db user-auth "SELECT COUNT(*) FROM users"` | ci / stage / prod / cn-stage / cn-prod |
90
102
  | `/read-code` | 阅读代码 | `/read-code commerce-backend app/main.py` | - |
91
- | `/cn-deploy` | 发布服务到 cn-stage(云效流水线一条龙) | 「把 billing 发到 cn-stage | cn-stage |
103
+ | `/restart-ecs` | 重启 ECS 服务 | `/restart-ecs user-auth stage` | stage / prod |
104
+ | `/trace-user` | 用户链路追踪:按账号把全链路行为拼成时间线 | `/trace-user user@example.com` | stage / prod / cn-stage / cn-prod |
92
105
 
93
106
  **说明**:
94
- - 命令支持 CI、Stage、Prod 三个环境
95
- - 默认使用 CI 环境,适合日常开发
96
- - `/generate-test-token` 生成的账户用于 development 环境(api.optima.chat)
107
+ - 本表与 `.claude/commands/` 一一对应(由 `tests/service-matrix-alignment.test.js` 校验,加命令漏更本表会红)。
108
+ - 上方「任务场景」里的 skill 同样可以用 `/<skill 名>` 直接唤起(例如 cn-deploy、gateway-admin),但它们是 skill、不在 `.claude/commands/` 里,因此不列进本表。
109
+ - 各命令支持的环境不同,见「跨环境」列。默认环境也不统一:`/logs`、`/query-db`、`/generate-test-token` 默认 `ci`,**`/restart-ecs`、`/trace-user` 默认 `stage`**(别当成 ci —— `/restart-ecs session-gateway` 不带环境重启的是 stage)。
110
+ - `/generate-test-token` 默认生成 `ci` 环境的账户(api.optima.chat);`--env` 可切到 stage / prod / cn-stage / cn-prod。**注意 `development` / `production` 不是合法取值**,CLI 只认上面五个(`bin/helpers/generate-test-token.ts:27`)
97
111
  - Claude Code 会根据上下文自动选择环境和执行方式
98
112
 
99
113
  ## 🛠️ CLI 工具
@@ -111,13 +125,20 @@ Claude:
111
125
  | `optima-entitlement` | 产品权益 grant/revoke/list | `optima-entitlement grant 18898654855 --product-key scout-gift --justification "..." --env cn-prod` |
112
126
  | `optima-account` | 账号 status/ban/unban | `optima-account ban user@example.com --reason "abuse" --env prod` |
113
127
  | `optima-cn-deploy` | 云效 Flow 发布到 cn-stage(构建→DB迁移→SAE 发布→sha 校验,20 服务) | `optima-cn-deploy billing` / `optima-cn-deploy user-auth --branch feat/xxx` |
128
+ | `optima-logs` | 查看服务日志(stage / prod 走 CloudWatch,cn 两侧直连 SLS;默认 `cn-prod`) | `optima-logs gateway-core --env cn-stage --since 2h` |
129
+ | `optima-verify-health` | 上线健康探针,L1 DNS → L5 依赖逐层探 | `optima-verify-health user-auth --env prod` |
130
+ | `optima-gateway-admin` | gateway-core `/admin/*` 直调(写操作需确认,默认 `cn-stage`) | `optima-gateway-admin GET /admin/llm-rates --env cn-stage` |
131
+ | `optima-plugin` | 插件市场态 show/set-paid/set-default/set-status | `optima-plugin show --slug <slug> --env stage` |
132
+ | `optima-product` | Product 的 create/update/add-channel/toggle-channel/show | `optima-product show --key <productKey> --env stage` |
133
+
134
+ 本表与 `package.json` 的 `bin` 一一对应(同样由 `tests/service-matrix-alignment.test.js` 校验)。包自身的入口 `optima-dev-skills`(只提供 `version` / `help`)与 `optima-grant-credits` 的废弃别名 `optima-grant-balance` 有意不单独列行。
114
135
 
115
136
  > **4 环境 + 标识符**:`grant-subscription` / `grant-credits` / `entitlement` / `account` 均支持 `stage` / `prod` / `cn-prod` / `cn-stage`。标识符 `<email\|phone\|userId>`——**cn-prod / cn-stage 用户多为手机号注册**,三种均可;AWS stage/prod 仅 email。`ban`/`unban` 及 `account status` 的禁用态读取需 admin-用户凭证(Infisical `/shared-secrets/credentials`;cn 另需 `INFISICAL_CN_EMAIL/PASSWORD`)。
116
137
 
117
138
  **特点**:
118
- - ✅ 支持 CI、Stage、Prod 三个环境(query-db
119
- - ✅ 支持 Stage、Prod 环境(show-env)
120
- - ✅ 自动管理 SSH 隧道和密钥
139
+ - ✅ 支持 ci / stage / prod / cn-stage / cn-prod(query-db,见 `bin/helpers/query-db.ts` 的 `VALID_ENVS`)
140
+ - ✅ 支持 stage / prod / cn-stage / cn-prod(show-env)
141
+ - ✅ 自动管理 DB 隧道与密钥(stage / prod 默认 AWS SSM 端口转发,cn 两侧经 buildbox ECS 跳板 SSH
121
142
  - ✅ 可在任何终端直接使用
122
143
  - ✅ 自动注册账户、获取 token、设置 merchant profile(generate-test-token)
123
144
  - ✅ Claude Code 的命令内部也使用这些工具
@@ -128,28 +149,21 @@ Claude:
128
149
  ```
129
150
  optima-dev-skills/
130
151
  ├── .claude/
131
- │ ├── commands/
132
- │ ├── logs.md # /logs - 查看服务日志
133
- │ ├── query-db.md # /query-db - 查询数据库
134
- │ │ ├── generate-test-token.md # /generate-test-token - 生成测试 token
135
- └── read-code.md # /read-code - 阅读代码
136
- │ │
137
- │ └── skills/
138
- │ ├── logs/ # 日志查看 skill
139
- │ ├── query-db/ # 数据库查询 skill
140
- │ ├── show-env/ # 环境变量查看 skill
141
- │ ├── generate-test-token/ # 测试 token 生成 skill
142
- │ ├── use-commerce-cli/ # Commerce CLI 使用 skill
143
- │ └── read-code/ # 代码阅读 skill
152
+ │ ├── commands/ # /<name> 斜杠命令,一个命令一个 .md
153
+ └── skills/ # Claude Code skills,一个 skill 一个目录(清单见上方「任务场景」)
154
+
155
+ ├── .codex/
156
+ │ └── skills/ # Codex skills,是 .claude/skills 的镜像子集(清单见 AGENTS.md)
144
157
 
145
158
  ├── bin/
146
- │ └── helpers/
147
- ├── query-db.ts # CLI: 数据库查询
148
- ├── show-env.ts # CLI: 查看环境变量
149
- └── generate-test-token.ts # CLI: 生成测试 token
159
+ │ └── helpers/ # optima-* CLI 的 TypeScript 实现(清单见上方「CLI 工具」)
160
+
161
+ ├── scripts/
162
+ └── install.js # postinstall:按 readdir 把上面各目录全量装到 ~/.claude 与 ~/.codex
163
+
164
+ ├── tests/ # node --test;service-matrix-alignment 校验文档清单与实际目录一致
150
165
 
151
166
  └── docs/
152
- └── COMMANDS_DESIGN.md
153
167
  ```
154
168
 
155
169
  ## 💡 使用示例
@@ -171,17 +185,17 @@ Claude:
171
185
  ### 示例 2:生成测试 token 并管理店铺
172
186
 
173
187
  ```bash
174
- # 1. 生成 production 环境测试 token
175
- $ optima-generate-test-token --env production
188
+ # 1. 生成 prod 环境测试 token
189
+ $ optima-generate-test-token --env prod
176
190
 
177
- Environment: production
178
- Auth API: https://auth.optima.shop
191
+ Environment: prod
192
+ Auth API: https://auth.optima.onl
179
193
  ✅ Test token generated successfully!
180
194
  📁 Token File Path: /tmp/optima-test-token-xxx.txt
181
195
 
182
- # 2. 使用 token 创建商品
196
+ # 2. 使用 token 创建商品(OPTIMA_ENV 取 generate-test-token 回显的那个 envName)
183
197
  $ OPTIMA_TOKEN=$(cat /tmp/optima-test-token-xxx.txt) \
184
- OPTIMA_ENV=production \
198
+ OPTIMA_ENV=prod \
185
199
  commerce product create --title "测试商品" --price 99.99 --stock 100
186
200
 
187
201
  {
@@ -208,7 +222,7 @@ $ optima-query-db commerce-backend "SELECT id, title FROM products LIMIT 5" stag
208
222
 
209
223
  ### dev-skills 提供什么?
210
224
 
211
- - ✅ **跨环境命令** - 在 CI/Stage/Prod 统一执行
225
+ - ✅ **跨环境命令** - 在 ci / stage / prod / cn-stage / cn-prod 统一执行
212
226
  - ✅ **任务场景指导** - 完整的操作流程(不是零散命令)
213
227
  - ✅ **团队协作工具** - 跨仓库、跨环境的共享知识
214
228
 
@@ -253,18 +267,17 @@ $ optima-query-db commerce-backend "SELECT id, title FROM products LIMIT 5" stag
253
267
 
254
268
  ## 🛠️ 开发状态
255
269
 
256
- **当前版本**: 0.7.16
270
+ **当前版本**:见 [package.json](package.json),或 `npm view @optima-chat/dev-skills version`(不在此写死——写死的数字正是本节此前一路过期到 0.7.16 的原因)
257
271
 
258
272
  **已完成**:
259
- - ✅ 4 个命令:`/logs`、`/query-db`、`/generate-test-token`、`/read-code`
260
- - ✅ 6 个任务场景:`logs`、`query-db`、`show-env`、`generate-test-token`、`use-commerce-cli`、`read-code`
261
- - ✅ 支持 CI、Stage、Prod 三个环境
273
+ - ✅ 命令、任务场景、CLI 工具三份清单见上方对应章节,此处不再重复计数(重复一次就多一处会漂的地方)
274
+ - ✅ 支持 ci、stage、prod、cn-stage、cn-prod 五个环境
262
275
  - ✅ CI 环境通过 SSH + Docker 访问
263
- - ✅ Stage/Prod 通过 SSH 隧道访问 RDS
264
- - ✅ TypeScript CLI 工具:`optima-query-db`、`optima-show-env`、`optima-generate-test-token`
276
+ - ✅ stage / prod 默认经共享 bastion 的 **AWS SSM 端口转发**访问 RDS(需 `session-manager-plugin`;`OPTIMA_DB_TUNNEL=ssh` 可回退 legacy SSH 隧道)
277
+ - ✅ cn-stage / cn-prod 经 buildbox ECS 跳板的 **SSH 隧道**访问内网 RDS
265
278
  - ✅ 通过 Infisical 动态获取密钥和环境变量
266
279
  - ✅ 自动生成测试 token 并设置 merchant profile
267
- - ✅ `generate-test-token` 支持 development production 环境
280
+ - ✅ `generate-test-token` 支持 ci / stage / prod / cn-stage / cn-prod 五个环境
268
281
 
269
282
  **设计原则**:
270
283
  - 命令提供信息(URL、路径、凭证位置),不实现复杂逻辑
@@ -20,11 +20,17 @@
20
20
  * optima-cn-deploy --list # 列出全部可发服务
21
21
  * optima-cn-deploy billing --vtag cn-v1.2.3 # stage 按版本 tag 构建(发版前验证)
22
22
  * optima-cn-deploy billing --env prod --vtag cn-v1.2.3
23
- * # cn-prod vtag 发版:构建→停在人工卡点(云效控制台审批)→迁移→digest 钉死部署
23
+ * # cn-prod vtag 发版:构建→迁移→digest 钉死部署。🔴 **中间没有人工卡点**——
24
+ * # 触发即一路跑到 cn-prod 部署完,没有"到云效控制台再审批一次"这一步。
25
+ * # 实测 2026-08-09:gateway-core / billing / user-auth / commerce-backend /
26
+ * # optima-scout 五条 *-cn-prod 流水线 stages 均为 build→migrate→deploy,
27
+ * # 无任何审批任务(aliyun devops GetPipeline 查 pipelineConfig.flow 可复核)。
28
+ * # ⇒ 唯一的决策点是敲下这条命令之前。
24
29
  *
25
30
  * 前置: aliyun CLI(profile 默认 aliyun-optima,可用 OPTIMA_ALIYUN_PROFILE 覆盖)+ gh 已登录。
26
- * 流水线定义的单一信源在 optima-terraform yunxiao/(gen-pipelines.py);本表为其快照,
27
- * 新增服务后同步(pipelineId 稳定,不常变)。
31
+ * 流水线定义的单一信源在 optima-terraform yunxiao/(gen-pipelines.py)。本表只快照
32
+ * repo / SAE appId;pipelineId 不在此表 —— stage/prod 均按流水线名 ${svc}-cn-${env}
33
+ * 从云效 ListPipelines 实时解析,不再手工同步(见 #84)。
28
34
  */
29
35
  import { execFileSync } from 'node:child_process';
30
36
 
@@ -33,33 +39,34 @@ const ENDPOINT = 'devops.cn-hangzhou.aliyuncs.com';
33
39
  const PROFILE = process.env.OPTIMA_ALIYUN_PROFILE || 'aliyun-optima';
34
40
  const CODEUP_BASE = `https://codeup.aliyun.com/${ORG}`;
35
41
 
36
- // 服务注册表(快照自 optima-terraform services.stage.env + gen-pipelines.py,2026-07-13)
37
- interface Svc { pipelineId: number; repo: string; saeAppId?: string; prodSaeAppId?: string; buildOnly?: boolean; }
42
+ // 服务注册表:repo / SAE appId 快照自 optima-terraform services.stage.env(2026-07-13)
43
+ // pipelineId 不再硬编码 —— 按名 ${svc}-cn-${env} 从云效实时解析,根除与 cn-run.py 手工表漂移(#84)。
44
+ interface Svc { repo: string; saeAppId?: string; prodSaeAppId?: string; buildOnly?: boolean; }
38
45
  const SERVICES: Record<string, Svc> = {
39
- 'agent-portal': { pipelineId: 5118519, repo: 'optima-portals', saeAppId: 'fe757f78-d18d-4480-9402-fe59d4721055', prodSaeAppId: '9211db38-a255-4393-ae92-7a7bb41b583d' },
46
+ 'agent-portal': { repo: 'optima-portals', saeAppId: 'fe757f78-d18d-4480-9402-fe59d4721055', prodSaeAppId: '9211db38-a255-4393-ae92-7a7bb41b583d' },
40
47
  // build-only:非 SAE 常驻(gateway-core 按 session 拉起的镜像)。release 段=解析 ACR digest
41
48
  // → 回写 Infisical /services/gateway-core/ALIYUN_AGENT_RUNTIME_IMAGE(#807)→ 滚动重启 gateway-core。
42
- // 无自身 saeAppId;prod 流水线(agent-runtime-cn-prod,5124970)按名实时解析(见下方 ListPipelines 逻辑)。
43
- 'agent-runtime': { pipelineId: 5124962, repo: 'optima-gateway', buildOnly: true },
44
- 'agentic-chat': { pipelineId: 5118520, repo: 'agentic-chat', saeAppId: '6aea1ce1-f813-4e1c-8e97-d1ecb5398e37', prodSaeAppId: '6e290c73-a646-43ef-9da5-ad0b2e7eff73' },
45
- 'billing': { pipelineId: 5118521, repo: 'optima-billing', saeAppId: '09d8e292-dc64-4af8-bce5-0a56cb666921', prodSaeAppId: '6c31cf82-8802-4d45-b6a2-e9d7c83ccce9' },
46
- 'browser-backend': { pipelineId: 5118522, repo: 'optima-browser-use', saeAppId: '1fced3f6-a80a-41a4-8f23-e4d5a467f8eb', prodSaeAppId: 'eb782ed9-c468-4e81-a0fe-87e5b4264192' },
47
- 'commerce-backend': { pipelineId: 5107005, repo: 'commerce-backend', saeAppId: '49d09808-508c-471a-9560-553c49a67f72', prodSaeAppId: 'd40597b6-a98c-4063-9297-8b9fdfa8add4' },
48
- 'commerce-rq-scheduler': { pipelineId: 5118523, repo: 'commerce-backend', saeAppId: '1d2810ef-889e-4675-b6e6-a299e4722e68', prodSaeAppId: '762dd7a5-7fe8-41ed-9332-cfd31b0e087e' },
49
- 'commerce-rq-worker': { pipelineId: 5118524, repo: 'commerce-backend', saeAppId: 'd661da87-6d24-40b8-93ed-e1c967d8abe2', prodSaeAppId: '2c9ee19a-5062-4205-9f5b-6ae3f8062a23' },
50
- 'gateway-core': { pipelineId: 5118525, repo: 'optima-gateway', saeAppId: '9326b7ff-da52-48d6-86db-9c4a884be108', prodSaeAppId: 'a08ce23f-3d3e-4d89-a2cf-53c8adba614e' },
51
- 'gw-admin': { pipelineId: 5118526, repo: 'optima-gateway', saeAppId: '90e0daf7-7910-46b8-b5bf-a0b8bcc60859', prodSaeAppId: 'c6bc5a78-b27f-46e2-825a-eaa338c23645' },
52
- 'kb-backend': { pipelineId: 5118527, repo: 'kb-skills', saeAppId: 'c7f65160-9d9e-416e-9e36-5439010d2b2d', prodSaeAppId: '732dfc8c-ed78-43f7-a722-c614359ff1a1' },
53
- 'ops-portal': { pipelineId: 5118529, repo: 'optima-portals', saeAppId: '41d0ee66-8402-4e72-bfda-8eba75d1270c', prodSaeAppId: '69e513fd-29bf-4355-a275-5eba82b21136' },
54
- 'optima-generation': { pipelineId: 5118530, repo: 'optima-gen', saeAppId: '327856d5-8b18-4e15-bfd8-b8bd3b807ffa', prodSaeAppId: '868d1a69-12c9-4bb7-868b-3e89c26784b5' },
55
- 'optima-generation-worker': { pipelineId: 5118531, repo: 'optima-gen', saeAppId: 'ad75b3b0-9ff4-443d-b0ef-81886bc7aa60', prodSaeAppId: '2adc941e-374b-406a-9863-e53d40bc9500' },
56
- 'optima-scout': { pipelineId: 5117336, repo: 'optima-scout', saeAppId: 'bac2c3a4-90ce-49a6-81d5-caa38cb5c807', prodSaeAppId: 'f5bb7e82-e57c-4bd4-83ae-2c25f8d38647' },
57
- 'optima-sentinel': { pipelineId: 5118532, repo: 'optima-sentinel', saeAppId: '3759db7b-4640-4a04-8436-4f241f0ec9d9', prodSaeAppId: 'e120e70c-b2c1-49ef-a66c-9016fd2d807d' },
58
- 'optima-sentinel-worker': { pipelineId: 5118533, repo: 'optima-sentinel', saeAppId: '7c975caf-ebfb-4bb3-91c4-2a8c83d1d2e5', prodSaeAppId: 'e0f9b92c-00af-4ade-9b07-15bba48c14cc' },
59
- 'optima-skills': { pipelineId: 5118534, repo: 'optima-skills', saeAppId: '90457be3-5eb3-4efc-a362-1788dcc51921', prodSaeAppId: '55a63ee7-fb75-46e4-99f3-20854a699237' },
60
- 'user-auth': { pipelineId: 5118510, repo: 'user-auth', saeAppId: '36efc3a6-5b42-49fa-8db2-0865aa0c25d2', prodSaeAppId: 'd6fbf9de-fed6-4165-978f-7b3a0a456acc' },
61
- 'user-auth-admin': { pipelineId: 5118535, repo: 'user-auth', saeAppId: '7feb9cc3-4731-4ea8-964c-4870a9e63afb', prodSaeAppId: '54093f99-37bf-4354-abd7-f6e76abdbcb6' },
62
- 'yzsgo-api': { pipelineId: 5118536, repo: 'yzsgo', saeAppId: 'd0af7f66-ef66-4587-9e93-250d01ee3cf6', prodSaeAppId: '5a820992-e11b-404a-9e58-8f607d8e0c5f' },
49
+ // 无自身 saeAppId(build-only 不跑 SAE ImageUrl 校验)。
50
+ 'agent-runtime': { repo: 'optima-gateway', buildOnly: true },
51
+ 'agentic-chat': { repo: 'agentic-chat', saeAppId: '6aea1ce1-f813-4e1c-8e97-d1ecb5398e37', prodSaeAppId: '6e290c73-a646-43ef-9da5-ad0b2e7eff73' },
52
+ 'billing': { repo: 'optima-billing', saeAppId: '09d8e292-dc64-4af8-bce5-0a56cb666921', prodSaeAppId: '6c31cf82-8802-4d45-b6a2-e9d7c83ccce9' },
53
+ 'browser-backend': { repo: 'optima-browser-use', saeAppId: '1fced3f6-a80a-41a4-8f23-e4d5a467f8eb', prodSaeAppId: 'eb782ed9-c468-4e81-a0fe-87e5b4264192' },
54
+ 'commerce-backend': { repo: 'commerce-backend', saeAppId: '49d09808-508c-471a-9560-553c49a67f72', prodSaeAppId: 'd40597b6-a98c-4063-9297-8b9fdfa8add4' },
55
+ 'commerce-rq-scheduler': { repo: 'commerce-backend', saeAppId: '1d2810ef-889e-4675-b6e6-a299e4722e68', prodSaeAppId: '762dd7a5-7fe8-41ed-9332-cfd31b0e087e' },
56
+ 'commerce-rq-worker': { repo: 'commerce-backend', saeAppId: 'd661da87-6d24-40b8-93ed-e1c967d8abe2', prodSaeAppId: '2c9ee19a-5062-4205-9f5b-6ae3f8062a23' },
57
+ 'gateway-core': { repo: 'optima-gateway', saeAppId: '9326b7ff-da52-48d6-86db-9c4a884be108', prodSaeAppId: 'a08ce23f-3d3e-4d89-a2cf-53c8adba614e' },
58
+ 'gw-admin': { repo: 'optima-gateway', saeAppId: '90e0daf7-7910-46b8-b5bf-a0b8bcc60859', prodSaeAppId: 'c6bc5a78-b27f-46e2-825a-eaa338c23645' },
59
+ 'kb-backend': { repo: 'kb-skills', saeAppId: 'c7f65160-9d9e-416e-9e36-5439010d2b2d', prodSaeAppId: '732dfc8c-ed78-43f7-a722-c614359ff1a1' },
60
+ 'ops-portal': { repo: 'optima-portals', saeAppId: '41d0ee66-8402-4e72-bfda-8eba75d1270c', prodSaeAppId: '69e513fd-29bf-4355-a275-5eba82b21136' },
61
+ 'optima-generation': { repo: 'optima-gen', saeAppId: '327856d5-8b18-4e15-bfd8-b8bd3b807ffa', prodSaeAppId: '868d1a69-12c9-4bb7-868b-3e89c26784b5' },
62
+ 'optima-generation-worker': { repo: 'optima-gen', saeAppId: 'ad75b3b0-9ff4-443d-b0ef-81886bc7aa60', prodSaeAppId: '2adc941e-374b-406a-9863-e53d40bc9500' },
63
+ 'optima-scout': { repo: 'optima-scout', saeAppId: 'bac2c3a4-90ce-49a6-81d5-caa38cb5c807', prodSaeAppId: 'f5bb7e82-e57c-4bd4-83ae-2c25f8d38647' },
64
+ 'optima-sentinel': { repo: 'optima-sentinel', saeAppId: '3759db7b-4640-4a04-8436-4f241f0ec9d9', prodSaeAppId: 'e120e70c-b2c1-49ef-a66c-9016fd2d807d' },
65
+ 'optima-sentinel-worker': { repo: 'optima-sentinel', saeAppId: '7c975caf-ebfb-4bb3-91c4-2a8c83d1d2e5', prodSaeAppId: 'e0f9b92c-00af-4ade-9b07-15bba48c14cc' },
66
+ 'optima-skills': { repo: 'optima-skills', saeAppId: '90457be3-5eb3-4efc-a362-1788dcc51921', prodSaeAppId: '55a63ee7-fb75-46e4-99f3-20854a699237' },
67
+ 'user-auth': { repo: 'user-auth', saeAppId: '36efc3a6-5b42-49fa-8db2-0865aa0c25d2', prodSaeAppId: 'd6fbf9de-fed6-4165-978f-7b3a0a456acc' },
68
+ 'user-auth-admin': { repo: 'user-auth', saeAppId: '7feb9cc3-4731-4ea8-964c-4870a9e63afb', prodSaeAppId: '54093f99-37bf-4354-abd7-f6e76abdbcb6' },
69
+ 'yzsgo-api': { repo: 'yzsgo', saeAppId: 'd0af7f66-ef66-4587-9e93-250d01ee3cf6', prodSaeAppId: '5a820992-e11b-404a-9e58-8f607d8e0c5f' },
63
70
  };
64
71
 
65
72
  function sh(cmd: string, args: string[]): string {
@@ -104,7 +111,8 @@ async function main() {
104
111
  console.error(`✗ vtag 格式必须 cn-vX.Y.Z(得到 ${vtag});裸 v* 会误触 AWS prod,绝不放行`); process.exit(1);
105
112
  }
106
113
  if (envName === 'prod') {
107
- // prod = vtag 制:先 stage 同 tag 验证,再发 prod;流水线内还有人工卡点
114
+ // prod = vtag 制:先 stage 同 tag 验证,再发 prod。🔴 流水线内**没有**人工卡点,
115
+ // 下面这道 vtag 校验就是最后一道闸(实测见文件头注)。
108
116
  if (!vtag) { console.error('✗ --env prod 必须带 --vtag cn-vX.Y.Z(先 stage 同 tag 验证)'); process.exit(1); }
109
117
  if (branch !== 'main') { console.error('✗ prod 发布按 vtag,不接受 --branch'); process.exit(1); }
110
118
  }
@@ -130,14 +138,12 @@ async function main() {
130
138
  if (!synced) { console.error('✗ 300s 内 Codeup mirror 未追平 GitHub,中止(检查 mirror 凭证)'); process.exit(1); }
131
139
  console.log(`✓ mirror 已追平 ${svc.repo}@${ref} = ${ghSha.slice(0, 10)}`);
132
140
 
133
- // 2. 触发(凭证由云效变量组供给,无需注入)。prod 流水线 id 按名实时解析(不硬编码)。
134
- let pipelineId = svc.pipelineId;
135
- if (envName === 'prod') {
136
- const lp = devops('ListPipelines', { maxResults: '100' });
137
- const hit = (lp.pipelines || []).find((p: any) => p.pipelineName === `${svcName}-cn-prod`);
138
- if (!hit) { console.error(`✗ 云效无 ${svcName}-cn-prod 流水线`); process.exit(1); }
139
- pipelineId = hit.pipelineId;
140
- }
141
+ // 2. 触发(凭证由云效变量组供给,无需注入)。stage/prod 流水线 id 均按名 `${svc}-cn-${env}`
142
+ // 从云效实时解析、不硬编码,根除与 optima-terraform cn-run.py 手工 PIPELINES 表漂移(#84)。
143
+ const lp = devops('ListPipelines', { maxResults: '100' });
144
+ const hit = (lp.pipelines || []).find((p: any) => p.pipelineName === `${svcName}-cn-${envName}`);
145
+ if (!hit) { console.error(`✗ 云效无 ${svcName}-cn-${envName} 流水线`); process.exit(1); }
146
+ const pipelineId = hit.pipelineId;
141
147
  const kv: Record<string, string> = { pipelineId: String(pipelineId) };
142
148
  if (vtag) {
143
149
  kv.params = JSON.stringify({
@@ -153,7 +159,8 @@ async function main() {
153
159
  console.log(`▶ ${svcName} run#${runId} 已启动 (ref=${ref}, env=${envName})`);
154
160
  console.log(` https://flow.aliyun.com/pipelines/${pipelineId}/current`);
155
161
  if (envName === 'prod') {
156
- console.log(' 构建完成后会停在『发布审批』人工卡点 —— 需 xbfool/svenyang 在云效控制台通过,之后迁移+digest 部署自动走完');
162
+ console.log('🔴 cn-prod:流水线**没有**人工卡点 —— 构建→迁移→digest 部署会一路自动走完,');
163
+ console.log(' 不要去云效控制台等『发布审批』(那一步不存在)。要中止只能在上面的链接里手动取消 run。');
157
164
  }
158
165
  if (noWait) return;
159
166