@ranger1/dx 0.1.77 → 0.1.79

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 (36) hide show
  1. package/README.md +102 -33
  2. package/bin/dx.js +3 -3
  3. package/lib/cli/commands/core.js +24 -1
  4. package/lib/cli/commands/db.js +6 -4
  5. package/lib/cli/commands/stack.js +198 -237
  6. package/lib/cli/commands/start.js +0 -6
  7. package/lib/cli/dx-cli.js +84 -1
  8. package/lib/cli/help.js +42 -9
  9. package/lib/{opencode-initial.js → codex-initial.js} +3 -82
  10. package/package.json +1 -2
  11. package/@opencode/agents/__pycache__/gh_review_harvest.cpython-314.pyc +0 -0
  12. package/@opencode/agents/__pycache__/pr_context.cpython-314.pyc +0 -0
  13. package/@opencode/agents/__pycache__/pr_precheck.cpython-314.pyc +0 -0
  14. package/@opencode/agents/__pycache__/pr_review_aggregate.cpython-314.pyc +0 -0
  15. package/@opencode/agents/__pycache__/test_pr_review_aggregate.cpython-314-pytest-9.0.2.pyc +0 -0
  16. package/@opencode/agents/__pycache__/test_pr_review_aggregate.cpython-314.pyc +0 -0
  17. package/@opencode/agents/claude-reviewer.md +0 -82
  18. package/@opencode/agents/codex-reviewer.md +0 -83
  19. package/@opencode/agents/gemini-reviewer.md +0 -82
  20. package/@opencode/agents/gh-thread-reviewer.md +0 -122
  21. package/@opencode/agents/gh_review_harvest.py +0 -292
  22. package/@opencode/agents/pr-context.md +0 -82
  23. package/@opencode/agents/pr-fix.md +0 -243
  24. package/@opencode/agents/pr-precheck.md +0 -89
  25. package/@opencode/agents/pr-review-aggregate.md +0 -151
  26. package/@opencode/agents/pr_context.py +0 -351
  27. package/@opencode/agents/pr_precheck.py +0 -505
  28. package/@opencode/agents/pr_review_aggregate.py +0 -868
  29. package/@opencode/agents/test_pr_review_aggregate.py +0 -701
  30. package/@opencode/commands/doctor.md +0 -271
  31. package/@opencode/commands/git-commit-and-pr.md +0 -282
  32. package/@opencode/commands/git-release.md +0 -642
  33. package/@opencode/commands/oh_attach.json +0 -92
  34. package/@opencode/commands/opencode_attach.json +0 -29
  35. package/@opencode/commands/opencode_attach.py +0 -142
  36. package/@opencode/commands/pr-review-loop.md +0 -211
package/README.md CHANGED
@@ -130,60 +130,50 @@ target(端)不写死,由 `env-policy.jsonc.targets` 定义;`commands.jso
130
130
 
131
131
  ## PR Review Loop(自动评审-修复闭环)
132
132
 
133
- dx 内置一套 PR 评审自动化工作流:并行评审 聚合结论 生成修复清单 自动修复 再评审,最多循环 3 轮,用于让 PR 更快收敛。
133
+ 仓库内提供了基于 Codex Skill 的 PR 评审自动化工作流:并行评审 -> 聚合结论 -> 生成修复清单 -> 自动修复 -> 再评审,最多循环 3 轮,用于让 PR 更快收敛。
134
134
 
135
135
  ### 什么时候用
136
136
 
137
137
  - PR 变更较大、想要更系统地覆盖安全/性能/可维护性问题
138
- - 希望在 CI 通过的前提下,把评审建议落成可执行的修复清单(fixFile)
139
- - 希望避免同一个问题在不同轮次被反复提出(通过 Decision Log 机制)
138
+ - 希望在 CI 通过前提下,把评审建议落成可执行修复清单(fixFile)
139
+ - 希望避免同一个问题在不同轮次被反复提出(Decision Log
140
140
 
141
141
  ### 如何运行
142
142
 
143
- 在创建 PR 后执行:
143
+ Codex 会话中触发该技能:
144
144
 
145
- ```
146
- /pr-review-loop --pr <PR_NUMBER>
145
+ ```text
146
+ 使用 $pr-review-loop PR #<PR_NUMBER> 执行审核闭环
147
147
  ```
148
148
 
149
- 更多命令说明见:`@opencode/commands/pr-review-loop.md`。
149
+ 技能入口与说明见:
150
150
 
151
- 提示:在创建 PR 的流程中也会给出快捷入口,见:`@opencode/commands/git-commit-and-pr.md`。
151
+ - `codex/skills/pr-review-loop/SKILL.md`
152
+ - `codex/skills/pr-review-loop/references/agents/*.md`
152
153
 
153
154
  ### 工作流概览
154
155
 
155
- - 预检(`pr-precheck`):先做编译/预检 gate,不通过则进入修复再预检(最多 2 次)
156
- - 获取上下文(`pr-context`):生成本轮上下文缓存 `contextFile`
157
- - 并行评审(4 reviewer):`codex-reviewer` / `claude-reviewer` / `gemini-reviewer` / `gh-thread-reviewer`
158
- - 聚合(`pr-review-aggregate`):合并各 reviewer 结果、去重、输出 `fixFile`,并发布本轮 Review Summary
159
- - 修复(`pr-fix`):按 `fixFile` 逐条修复(每条 findingId 单独 commit + push),输出 `fixReportFile`
160
- - 发布修复报告(`pr-review-aggregate` 模式 B):发布 Fix Report
161
-
162
- 备注:每轮发布到 PR 的评论都会带 `<!-- pr-review-loop-marker -->`,用于幂等与避免反复采集机器人评论。
156
+ - 预检(`pr-precheck`):先做编译/基础 gate,不通过则终止流程
157
+ - 获取上下文(`pr-context`):生成本轮上下文缓存 `contextFile` 与 `runId`
158
+ - 并行评审(reviewers):按 `./reviewer/*-reviewer.md` 并行审查并产出 reviewFile
159
+ - 聚合(`pr-review-aggregate` 模式 A):合并评审结果、去重、发布 Review Summary、生成 `fixFile`
160
+ - 修复(`fixer`):按 `fixFile` 执行修复并产出 `fixReportFile`
161
+ - 发布修复报告(`pr-review-aggregate` 模式 B
163
162
 
164
- ### 缓存文件(项目内 ./\.cache/)
163
+ ### 缓存文件(项目内 `./.cache/`)
165
164
 
166
- 该流程的中间产物都写入项目内 `./.cache/`,并在 agent/命令之间传递 repo 相对路径:
165
+ 该流程中间产物写入 `./.cache/`,并在各阶段传递相对路径:
167
166
 
168
167
  - `./.cache/pr-context-pr<PR>-r<ROUND>-<RUN_ID>.md`(contextFile)
169
- - `./.cache/review-<REVIEWER>-pr<PR>-r<ROUND>-<RUN_ID>.md`(reviewFile)
168
+ - `./.cache/review-<ROLE_CODE>-pr<PR>-r<ROUND>-<RUN_ID>.md`(reviewFile)
170
169
  - `./.cache/fix-pr<PR>-r<ROUND>-<RUN_ID>.md`(fixFile)
171
170
  - `./.cache/fix-report-pr<PR>-r<ROUND>-<RUN_ID>.md`(fixReportFile)
172
171
 
173
- ### Decision Log(跨轮次决策日志,用于收敛)
174
-
175
- 为了解决“第一轮拒绝的问题在后续轮次反复出现”的问题,PR Review Loop 使用 Decision Log 持久化每轮的决策:
172
+ ### Decision Log(跨轮次决策日志)
176
173
 
177
174
  - 文件:`./.cache/decision-log-pr<PR_NUMBER>.md`
178
- - 生成者:`pr-fix` 在修复完成后创建/追加(append-only,禁止覆盖历史)
179
- - 内容:记录每轮的 Fixed/Rejected,以及 `essence`(问题本质的一句话描述,用于后续智能匹配)
180
-
181
- 在后续轮次:
182
-
183
- - reviewers 若收到 `decisionLogFile`,必须读取并遵守:已修复不再提、已拒绝不再提(除非严重性升级)
184
- - aggregate 在模式 A 中基于 LLM 对比 `essence` 做“问题本质相同”的判断,并生成 `escalation_groups` 入参给脚本
185
-
186
- 升级质疑规则:只有当新 finding 的优先级比历史 rejected 高 ≥2 级(例如 P3→P1、P2→P0)时,才允许重新打开。
175
+ - 作用:记录每轮 Fixed/Rejected 结论,后续轮次用于过滤重复问题
176
+ - 规则:默认 append-only,保留历史决策用于收敛
187
177
 
188
178
  ## 命令
189
179
 
@@ -192,12 +182,13 @@ dx 的命令由 `dx/config/commands.json` 驱动,并且内置了一些 interna
192
182
  - `internal: sdk-build`:SDK 生成/构建
193
183
  - `internal: backend-package`:后端打包
194
184
  - `internal: start-dev`:开发环境一键启动
185
+ - `internal: pm2-stack`:PM2 交互式服务栈(支持端口清理/缓存清理配置)
195
186
 
196
187
  常用示例:
197
188
 
198
189
  ```bash
199
190
  dx start backend --dev
200
- dx start all
191
+ dx start all --dev
201
192
  dx build backend --prod
202
193
  dx build sdk --dev
203
194
  dx db generate
@@ -205,9 +196,87 @@ dx db migrate --dev --name init
205
196
  dx db deploy --prod -Y
206
197
  dx deploy front --staging
207
198
  dx lint
208
- dx test e2e backend
199
+ dx test e2e backend apps/backend/e2e/auth
209
200
  ```
210
201
 
202
+ 命令约束摘要:
203
+
204
+ - `dx test e2e backend` 必须提供文件或目录路径,禁止无路径全量执行
205
+ - `dx db migrate` 仅允许在 `--dev` 环境创建迁移;非开发环境请使用 `dx db deploy`
206
+ - `dx start` 未指定服务时默认是开发套件,仅允许 `--dev`
207
+ - `dx start` 下的单层目标(如 `stagewise-front`)默认仅支持 `--dev`
208
+ - `dx build` 显式传入环境标志时,必须是该 target 实际支持的环境
209
+
210
+ ### `dx start stack` 配置详解(PM2 交互式服务栈)
211
+
212
+ 从 `0.1.78` 起,`dx start stack` 推荐完全由 `dx/config/commands.json` 配置驱动,不再依赖硬编码服务列表。
213
+
214
+ 最小可用配置:
215
+
216
+ ```json
217
+ {
218
+ "start": {
219
+ "stack": {
220
+ "internal": "pm2-stack",
221
+ "interactive": true,
222
+ "description": "PM2 交互式服务栈",
223
+ "stack": {
224
+ "ecosystemConfig": "ecosystem.config.cjs",
225
+ "services": ["backend", "front", "admin"],
226
+ "preflight": {
227
+ "killPorts": [3000, 3001, 3500],
228
+ "pm2Reset": true
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
236
+ 完整字段说明:
237
+
238
+ - `start.stack.internal`
239
+ - 固定为 `pm2-stack`,表示启用内置 PM2 交互式 runner。
240
+ - `start.stack.interactive`
241
+ - 建议设为 `true`,用于标记这是交互式命令(便于团队识别)。
242
+ - `start.stack.stack.ecosystemConfig`
243
+ - PM2 配置文件路径;支持相对路径(相对项目根目录)或绝对路径。
244
+ - 默认值:`ecosystem.config.cjs`。
245
+ - `start.stack.stack.pm2Bin`
246
+ - PM2 命令前缀,默认 `pnpm pm2`。如果团队使用全局 pm2,可改为 `pm2`。
247
+ - `start.stack.stack.services`
248
+ - 交互命令(`r/l/s`)可操作的服务名单。
249
+ - 示例:`["backend", "front", "admin"]`。
250
+ - `start.stack.stack.preflight.killPorts`
251
+ - 启动前自动清理占用端口列表。
252
+ - 这就是“某些端口被占用时自动处理”的核心配置。
253
+ - `start.stack.stack.preflight.forcePortCleanup`
254
+ - 是否强制清理端口占用,默认 `true`。
255
+ - `start.stack.stack.preflight.pm2Reset`
256
+ - 启动前是否执行 PM2 状态重置(`delete all` / `kill` / 状态文件清理),默认 `true`。
257
+ - `start.stack.stack.preflight.cleanPaths`
258
+ - 启动前需要删除的缓存路径列表(相对项目根目录)。
259
+ - 适合清理 `.next`、`dist`、`.vite` 等缓存,避免脏状态。
260
+ - `start.stack.stack.preflight.cleanTsBuildInfo`
261
+ - 是否清理 `*.tsbuildinfo`,默认 `true`。
262
+ - `start.stack.stack.preflight.cleanTsBuildInfoDirs`
263
+ - 扫描 `*.tsbuildinfo` 的目录列表。
264
+
265
+ 交互命令保持不变:
266
+
267
+ - `r <service>` 重启服务
268
+ - `l <service>` 查看日志
269
+ - `s <service>` 停止服务
270
+ - `list` 查看状态
271
+ - `monit` 打开 PM2 监控
272
+ - `q` 停止所有服务并退出
273
+
274
+ 推荐实践:
275
+
276
+ - 将 `services` 与 `ecosystem.config.cjs` 里的 app 名保持一致,避免交互命令找不到服务。
277
+ - `killPorts` 只配置开发态常驻端口,避免误杀不相关进程。
278
+ - 如果项目不是 `apps/front` / `apps/admin-front` 结构,请按实际目录改 `cleanPaths` 与 `cleanTsBuildInfoDirs`。
279
+
211
280
  ## deploy 行为说明
212
281
 
213
282
  从 `0.1.9` 起,`dx deploy <target>` 不再在 dx 内部硬编码执行任何 `nx build`/`sdk build` 等前置步骤。
package/bin/dx.js CHANGED
@@ -117,13 +117,13 @@ async function main() {
117
117
 
118
118
  if (isInitialInvocation(rawArgs)) {
119
119
  const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..')
120
- const [{ logger }, { runOpenCodeInitial }] = await Promise.all([
120
+ const [{ logger }, { runCodexInitial }] = await Promise.all([
121
121
  import('../lib/logger.js'),
122
- import('../lib/opencode-initial.js'),
122
+ import('../lib/codex-initial.js'),
123
123
  ])
124
124
 
125
125
  try {
126
- await runOpenCodeInitial({ packageRoot })
126
+ await runCodexInitial({ packageRoot })
127
127
  return
128
128
  } catch (error) {
129
129
  logger.error('initial 执行失败')
@@ -17,6 +17,8 @@ export async function handleBuild(cli, args) {
17
17
  const target = args[0] || 'all'
18
18
  const environment = cli.determineEnvironment()
19
19
  const envKey = cli.normalizeEnvKey(environment)
20
+ const explicitEnv =
21
+ Boolean(cli.flags.dev || cli.flags.prod || cli.flags.staging || cli.flags.test || cli.flags.e2e)
20
22
 
21
23
  const buildConfig = cli.commands.build[target]
22
24
  if (!buildConfig) {
@@ -36,6 +38,27 @@ export async function handleBuild(cli, args) {
36
38
  // 处理嵌套配置
37
39
  let config = buildConfig
38
40
  if (typeof config === 'object' && !config.command) {
41
+ const supportsCurrentEnv = Boolean(
42
+ config[envKey] || (envKey === 'staging' && config.prod),
43
+ )
44
+ if (explicitEnv && !supportsCurrentEnv) {
45
+ const envFlag = cli.getEnvironmentFlagExample(envKey) || `--${envKey}`
46
+ logger.error(`构建目标 ${target} 不支持 ${envFlag} 环境`)
47
+ logger.info('显式传入环境标志时,必须是该 target 实际支持的环境。')
48
+ const available = ['dev', 'staging', 'prod', 'test', 'e2e']
49
+ .filter(key => key in config)
50
+ .map(key => cli.getEnvironmentFlagExample(key) || `--${key}`)
51
+ if (available.length > 0) {
52
+ logger.info(`支持的环境: ${available.join(', ')}`)
53
+ logger.info(`示例: ${cli.invocation} build ${target} ${available[0]}`)
54
+ if (available.length > 1) {
55
+ logger.info(`示例: ${cli.invocation} build ${target} ${available[1]}`)
56
+ }
57
+ }
58
+ process.exitCode = 1
59
+ return
60
+ }
61
+
39
62
  // 如果是嵌套配置,尝试获取环境特定的配置(兼容 dev/prod 与 development/production 命名)
40
63
  if (config[envKey]) config = config[envKey]
41
64
  else if (envKey === 'staging' && config.prod) config = config.prod
@@ -81,7 +104,7 @@ export async function handleTest(cli, args) {
81
104
 
82
105
  // 如果提供了测试文件路径,使用专门的单文件测试配置
83
106
  if (testPath && type === 'e2e' && target === 'backend') {
84
- let command = `pnpm --filter ./apps/backend run test:e2e:file ${testPath}`
107
+ let command = `npx nx test:e2e backend -- ${testPath}`
85
108
 
86
109
  // 如果指定了测试用例名称,添加 -t 参数
87
110
  if (testNamePattern) {
@@ -21,12 +21,14 @@ export async function handleDatabase(cli, args) {
21
21
  const environment = cli.determineEnvironment()
22
22
  const envKey = cli.normalizeEnvKey(environment)
23
23
 
24
- // 兼容旧用法:非 dev 环境使用 migrate 时给出明确提示,推荐改用 deploy
24
+ // 创建迁移只允许在开发环境进行,避免 AI/用户在非开发环境误执行
25
25
  if (action === 'migrate' && envKey && envKey !== 'dev') {
26
26
  const envFlag = cli.getEnvironmentFlagExample(envKey) || `--${envKey}`
27
- logger.warn(`检测到在非开发环境执行 migrate: ${environment || envKey}`)
28
- logger.info('建议仅在开发环境使用 `dx db migrate --dev --name <migration-name>` 创建迁移。')
29
- logger.info(`如需在当前环境应用已有迁移,请使用: ${cli.invocation} db deploy ${envFlag}`)
27
+ logger.error('dx db migrate 仅允许在 --dev 环境下创建迁移')
28
+ logger.info('请使用 `dx db migrate --dev --name <migration-name>` 创建新迁移。')
29
+ logger.info(`非开发环境请改用: ${cli.invocation} db deploy ${envFlag}`)
30
+ process.exitCode = 1
31
+ return
30
32
  }
31
33
 
32
34
  // 处理 script 子命令