@weotro/dx 0.1.21 → 0.2.1

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 (75) hide show
  1. package/README.md +78 -766
  2. package/bin/dx.js +100 -182
  3. package/example/.env.development +1 -0
  4. package/example/README.md +24 -0
  5. package/example/dx/scripts/build +2 -0
  6. package/example/dx/scripts/db +2 -0
  7. package/example/dx/scripts/deploy +2 -0
  8. package/example/dx/scripts/setup +2 -0
  9. package/example/dx/scripts/start +12 -0
  10. package/example/dx/scripts/test +2 -0
  11. package/lib/env.js +40 -257
  12. package/lib/logger.js +5 -238
  13. package/lib/setup.js +72 -0
  14. package/package.json +27 -13
  15. package/skills/ask_3th/SKILL.md +2 -0
  16. package/skills/delegate_3th/SKILL.md +4 -2
  17. package/skills/delegate_3th/scripts/delegate_3th.py +37 -41
  18. package/skills/delegate_3th/scripts/test_delegate_3th.py +43 -17
  19. package/skills/dx-adopt/SKILL.md +88 -0
  20. package/skills/dx-adopt/agents/openai.yaml +2 -0
  21. package/skills/dx-adopt/references/dx-0.2-contract.md +95 -0
  22. package/skills/dx-adopt/references/migrate-0.1.md +48 -0
  23. package/bin/dx-with-version-env.js +0 -8
  24. package/lib/artifact-deploy/artifact-builder.js +0 -144
  25. package/lib/artifact-deploy/config.js +0 -180
  26. package/lib/artifact-deploy/remote-script.js +0 -301
  27. package/lib/artifact-deploy/remote-transport.js +0 -86
  28. package/lib/artifact-deploy.js +0 -70
  29. package/lib/backend-artifact-deploy/artifact-builder.js +0 -267
  30. package/lib/backend-artifact-deploy/config.js +0 -218
  31. package/lib/backend-artifact-deploy/path-utils.js +0 -18
  32. package/lib/backend-artifact-deploy/remote-phases.js +0 -14
  33. package/lib/backend-artifact-deploy/remote-result.js +0 -44
  34. package/lib/backend-artifact-deploy/remote-script.js +0 -507
  35. package/lib/backend-artifact-deploy/remote-transport.js +0 -123
  36. package/lib/backend-artifact-deploy/rollback.js +0 -5
  37. package/lib/backend-artifact-deploy/runtime-package.js +0 -46
  38. package/lib/backend-artifact-deploy.js +0 -91
  39. package/lib/backend-package.js +0 -674
  40. package/lib/cli/args.js +0 -38
  41. package/lib/cli/command-result.js +0 -1
  42. package/lib/cli/commands/contracts.js +0 -60
  43. package/lib/cli/commands/core.js +0 -533
  44. package/lib/cli/commands/db.js +0 -231
  45. package/lib/cli/commands/deploy.js +0 -175
  46. package/lib/cli/commands/env.js +0 -120
  47. package/lib/cli/commands/export.js +0 -39
  48. package/lib/cli/commands/package.js +0 -22
  49. package/lib/cli/commands/release.js +0 -55
  50. package/lib/cli/commands/stack.js +0 -427
  51. package/lib/cli/commands/start.js +0 -58
  52. package/lib/cli/commands/worktree.js +0 -145
  53. package/lib/cli/dx-cli.js +0 -1098
  54. package/lib/cli/flags.js +0 -123
  55. package/lib/cli/help-model.js +0 -234
  56. package/lib/cli/help-renderer.js +0 -137
  57. package/lib/cli/help-schema.js +0 -552
  58. package/lib/cli/help.js +0 -141
  59. package/lib/cli/index.js +0 -4
  60. package/lib/cli/nx-command.js +0 -13
  61. package/lib/confirm.js +0 -213
  62. package/lib/env-policy.js +0 -134
  63. package/lib/env-profile.js +0 -531
  64. package/lib/exec.js +0 -698
  65. package/lib/nx-ignore.js +0 -45
  66. package/lib/run-with-version-env.js +0 -163
  67. package/lib/sdk-build.js +0 -424
  68. package/lib/start-dev.js +0 -401
  69. package/lib/telegram-webhook.js +0 -431
  70. package/lib/validate-env.js +0 -317
  71. package/lib/vercel-deploy.js +0 -549
  72. package/lib/worktree.js +0 -1052
  73. package/skills/delegate_3th/scripts/__pycache__/delegate_3th.cpython-314.pyc +0 -0
  74. package/skills/delegate_3th/scripts/__pycache__/delegate_cc.cpython-314.pyc +0 -0
  75. package/skills/delegate_3th/scripts/__pycache__/test_delegate_cc.cpython-314.pyc +0 -0
package/README.md CHANGED
@@ -1,827 +1,139 @@
1
1
  # @weotro/dx
2
2
 
3
- `@weotro/dx` 是一个可安装的 Node.js CLI,安装后提供 `dx` 命令,用于管理符合约定的 pnpm + Nx monorepo 项目的构建、启动、数据库和部署等流程。
4
-
5
- 本工具通过项目内的 `dx/config/*` 配置文件来驱动命令执行:你可以把它理解成「带环境变量分层 + 校验 + 命令编排能力的脚本系统」。
6
-
7
- ## 当前规范
8
-
9
- 当前版本的 `dx` 已收敛到 strict 配置规范。
10
-
11
- 这意味着:
12
-
13
- - 配置写错时直接报错,不再自动兼容旧写法
14
- - `help` 输出由 `dx/config/commands.json` 动态生成,不再依赖代码中的大段硬编码文案
15
- - 命令配置中的环境分支必须使用完整环境键
16
-
17
- 当前推荐且受支持的环境键:
18
-
19
- - `development`
20
- - `staging`
21
- - `production`
22
- - `test`
23
- - `e2e`
24
-
25
- 当前推荐且受支持的 CLI 环境标志:
26
-
27
- - `--dev`
28
- - `--staging`
29
- - `--prod`
30
- - `--test`
31
- - `--e2e`
32
-
33
- 不再建议写法:
34
-
35
- - `dev` / `prod` 作为配置节点名
36
- - `--development` / `--production` / `--stage`
37
- - 任何旧配置回退、旧命令别名或自动输入修正
3
+ 面向 macOS/Linux 的薄命令入口。dx 根据约定找到应用脚本,加载环境、传递参数并返回执行结果;具体工程行为由应用实现。
38
4
 
39
5
  ## 安装
40
6
 
41
- 包名是 `@weotro/dx`。必须全局安装,并始终使用最新版本:
7
+ 需要 Node.js >= 20.11.0,以及应用脚本指定的解释器。
42
8
 
43
9
  ```bash
44
- pnpm add -g @weotro/dx@latest
10
+ npm install -g @weotro/dx
45
11
  ```
46
12
 
47
- 安装后即可在任意目录使用:
48
-
49
- ```bash
50
- dx --help
51
- dx --version
52
- dx status
53
- ```
13
+ 全局安装后,clone 或新 worktree 中无需先安装应用依赖就能运行 `dx setup`;setup 自身需要的工具由应用说明。
54
14
 
55
- 升级到最新版本:
15
+ ## 技能初始化
56
16
 
57
17
  ```bash
58
- pnpm update -g @weotro/dx
18
+ dx initial
19
+ dx initial --help
59
20
  ```
60
21
 
61
- ## 使用条件(必须满足)
62
-
63
- - Node.js:>= 20
64
- - 包管理器:pnpm(dx 内部会调用 `pnpm`)
65
- - 构建系统:Nx(dx 默认命令配置里大量使用 `npx nx ...`)
66
- - 环境加载:建议项目依赖 `dotenv-cli`(dx 会用 `pnpm exec dotenv ...` 包裹命令来注入 `.env.*`)
67
- - 项目结构:推荐按 `apps/backend` / `apps/front` / `apps/admin-front` 这类布局组织;如有自定义目录结构,请通过 `dx/config/commands.json` 适配
68
-
69
- 如果你的 monorepo 不完全一致,也能用:关键是你在 `dx/config/commands.json` 里把命令写成适配你项目的形式。
22
+ `initial` 是 dx 自身的内置命令,无需应用工程、环境文件或 `dx/scripts/initial`。它使用安装包随附的 `skills/` 资源,更新 `~/.agents/skills` 中的托管技能,并在 `~/.claude/skills` 建立对应链接;沿用原先的托管旧副本与历史已删除技能清理规则,其他技能保留。Codex 使用共享的 agents 技能目录,其托管旧副本从 `~/.codex/skills` 清理。
70
23
 
71
- ## 项目配置(必须)
24
+ `initial` 用于安装和更新技能,`setup` 用于当前项目的准备;两者独立,不互相自动调用。自定义应用命令不得使用保留名称 `initial`。技能中的外部工具需另行安装和认证,initial 只同步技能文件。
72
25
 
73
- dx 会从当前目录向上查找 `dx/config/commands.json` 来定位项目根目录。
26
+ 首次接入或从 0.1.x 升级的应用可使用随包的 [dx-adopt](skills/dx-adopt/SKILL.md) 技能,例如“使用 $dx-adopt 为当前项目接入 dx 0.2.1,并完成验证”。技能会区分新项目与旧版迁移,生成项目自己的脚本并适配环境、setup 和调用方。
74
27
 
75
- 你需要在项目根目录提供:
28
+ ## 应用提供脚本
76
29
 
30
+ ```text
31
+ dx/scripts/
32
+ setup
33
+ start
34
+ build
35
+ test
36
+ db
37
+ deploy
77
38
  ```
78
- dx/
79
- config/
80
- commands.json
81
- env-layers.json
82
- env-policy.jsonc
83
- ```
84
-
85
- 可选覆盖:
86
-
87
- - 环境变量:`DX_CONFIG_DIR=/abs/path/to/config`
88
- - 参数:`dx --config-dir /abs/path/to/config ...`
89
-
90
- 全局安装场景下,如果你不在项目目录内执行,也可以通过 `DX_CONFIG_DIR` / `--config-dir` 显式指定配置目录(目录下需要存在 `commands.json`)。
91
-
92
- 示例:
93
-
94
- ```bash
95
- # 在任意目录执行
96
- dx --config-dir /path/to/your-repo/dx/config status
97
-
98
- # 或
99
- DX_CONFIG_DIR=/path/to/your-repo/dx/config dx status
100
- ```
101
-
102
- ## 配置文件写法
103
-
104
- ### 1) dx/config/commands.json
105
39
 
106
- #### 自定义命令参数透传
107
-
108
- 在选中的可执行叶节点声明 `allowPassthrough: true`,然后用第一个独立的 `--`
109
- 分开 DX 选项和子命令参数:
40
+ 每个入口都是无扩展名的可执行文件,用 shebang 指定解释器绝对路径;首行不超过 255 字节(不含换行),避免系统截断或回退执行。按需提供入口,不要求实现全部命令。
110
41
 
111
42
  ```sh
112
- dx release plan --prod -- --brands zh --targets backend --ref v0.2.205
113
- ```
114
-
115
- 最小 `commands.json`(脚本由目标项目提供):
116
-
117
- ```json
118
- {
119
- "release": {
120
- "plan": {
121
- "production": {
122
- "command": "node scripts/release/cli.mjs plan --environment production",
123
- "allowPassthrough": true
124
- }
125
- }
126
- }
127
- }
128
- ```
129
-
130
- 字段契约:
131
-
132
- | 字段 | 类型 / 默认值 | 作用 |
133
- | --- | --- | --- |
134
- | `allowPassthrough` | boolean / `false` | 只有严格的 `true` 开启透传;必须放在环境选择后的 `command` 叶节点,父节点不继承 |
135
- | `command` | string | 现有 Bash 命令;用户参数逐项转义后追加在末尾,固定参数在前 |
136
-
137
- 适用于通用配置处理器执行的自定义命令,包括 `release plan/run` 这类内置命令族的扩展 action,
138
- 以及任意非内置顶层命令。`concurrent`、`sequential`、`internal` 配置暂不支持透传,
139
- 即使声明 `allowPassthrough: true` 也会拒绝非空参数;不会向多个子任务广播。
140
- 内置 `test/db/env` 等仍使用各自已有的参数契约,此字段不会覆盖内置处理器。
141
-
142
- 迁移时,为确实需要接收参数的叶节点增加该字段,并将业务参数移到 `--` 后。
143
- 未开启或不支持透传的配置收到非空子参数时会非零退出,不再静默丢弃后执行默认命令。
144
- 没有子参数或仅有末尾 `--` 时保留旧行为;省略分隔符的未知选项继续报错。
145
-
146
- 第一个 `--` 后的顺序、重复项、空字符串、特殊字符和第二个 `--` 均保留。
147
- 其中的 `--prod`、`-Y`、`--help`、`--version`、`--config-dir` 不影响 DX 自身。
148
- 危险操作仍须通过原确认流程;子命令退出失败时 DX 非零退出。
149
- DX 不校验业务参数含义,拼错的 key、品牌、目标、ref 由子脚本严格校验。
150
-
151
- 建议 `command` 只调用一个脚本;包含管道、多个语句或末尾注释的 shell 文本应先移入脚本,
152
- 确保追加参数由明确的入口接收。不要在命令中自行拼接用户输入。
153
-
154
- 回归验证:`pnpm test --runInBand test/configured-passthrough.test.js`,测试使用真实
155
- `bin/dx.js` 和临时 probe,校验实际子进程 argv、拒绝时未启动子进程及失败退出。
156
-
157
- 这是核心文件,定义了 dx 各命令要执行的 shell 命令,也承载帮助信息配置。
158
-
159
- 它支持:
160
-
161
- - 单命令:`{ "command": "..." }`
162
- - 并发:`{ "concurrent": true, "commands": ["build.front.development", "build.admin.development"] }`
163
- - 串行:`{ "sequential": true, "commands": ["build.backend.production", "build.sdk"] }`
164
- - 环境分支:如 `build.backend.development` / `build.backend.production`(dx 会根据 `--dev/--prod/--staging/...` 选择)
165
- - dotenv 包裹:配置里带 `"app": "backend"` 时,dx 会按 `env-layers.json` 拼出 dotenv 层并用 `pnpm exec dotenv ... -- <command>` 执行
166
-
167
- 常见字段(单命令配置):
168
-
169
- ```jsonc
170
- {
171
- "command": "npx nx build backend --configuration=production",
172
- "app": "backend", // 可选:用于选择 dotenv 层,并决定需要校验的 env 变量组
173
- "ports": [3000], // 可选:用于 start 类命令,冲突时自动清理
174
- "description": "构建后端(生产环境)",
175
- "dangerous": true, // 可选:危险操作需要确认
176
- "skipEnvValidation": true, // 可选:跳过 env 校验(仍可加载 dotenv 层)
177
- "env": { "NX_CACHE": "false" } // 可选:注入额外环境变量
178
- }
179
- ```
180
-
181
- 命令路径引用(并发/串行的 commands 数组)使用点号字符串,例如:
182
-
183
- ```json
184
- { "concurrent": true, "commands": ["build.shared", "build.front.development"] }
185
- ```
186
-
187
- 帮助配置示例:
188
-
189
- ```json
190
- {
191
- "help": {
192
- "summary": "统一开发环境管理工具",
193
- "globalOptions": [
194
- { "flags": ["--dev"], "description": "使用 development 环境" },
195
- { "flags": ["--prod"], "description": "使用 production 环境" }
196
- ],
197
- "commands": {
198
- "start": {
199
- "summary": "启动/桥接服务",
200
- "notes": ["未指定 service 时默认使用开发套件,仅允许 --dev"],
201
- "examples": [
202
- { "command": "dx start backend --dev", "description": "启动后端开发服务" }
203
- ]
204
- }
205
- }
206
- }
207
- }
208
- ```
209
-
210
- 约束:
211
-
212
- - 命令级帮助推荐放在 `help.commands.<command>`
213
- - target 级帮助推荐放在 `help.targets.<command>.<target>`
214
- - 帮助示例必须与真实命令树一致,不能写配置里不存在的 target
215
- - 运行时会校验 help 配置结构;坏配置会直接报错
216
-
217
- ### 2) dx/config/env-layers.json
218
-
219
- 用于定义不同环境下加载哪些 `.env.*` 文件(顺序 = 覆盖优先级)。格式:
220
-
221
- ```json
222
- {
223
- "development": [".env.development", ".env.development.local"],
224
- "staging": [".env.staging", ".env.staging.local"],
225
- "production": [".env.production", ".env.production.local"],
226
- "test": [".env.test", ".env.test.local"],
227
- "e2e": [".env.e2e", ".env.e2e.local"]
228
- }
229
- ```
230
-
231
- ### 3) dx/config/env-policy.jsonc
232
-
233
- 统一的 env 策略配置(jsonc),同时覆盖:
234
-
235
- - env 文件布局约束(禁用 `.env` / `.env.local`;禁止子目录散落 `.env*`,仅允许少数特例路径)
236
- - 机密键策略:机密 key 只能在 `.env.<env>.local` 放真实值;对应的 `.env.<env>` 必须存在同名 key 且为占位符 `__SET_IN_env.local__`
237
- - 必填校验:按环境 + 按 target(端)定义 required keys,执行命令前校验是否缺失/仍为占位符
238
-
239
- target(端)不写死,由 `env-policy.jsonc.targets` 定义;`commands.json` 里的 `app` 通过 `env-policy.jsonc.appToTarget` 映射到某个 target。
240
-
241
- 注:`env-policy.jsonc` 为必需配置;未提供时 dx 将直接报错。
242
-
243
- ### 4) 可选的品牌环境 profile
244
-
245
- 多品牌项目可以增加 `dx/config/env-profiles.json`,声明允许运维使用的 profile、环境和必须直接
246
- 存在于私有 profile 中的键:
247
-
248
- ```json
249
- {
250
- "version": 1,
251
- "environments": ["staging", "production"],
252
- "profiles": {
253
- "primary": { "label": "Primary brand" },
254
- "secondary": { "label": "Secondary brand" }
255
- },
256
- "committedRuntime": {
257
- "target": "backend",
258
- "keys": ["SENTRY_ORG"]
259
- },
260
- "requiredLocalKeys": {
261
- "staging": ["DATABASE_URL"],
262
- "production": ["DATABASE_URL"]
263
- }
264
- }
265
- ```
266
-
267
- 私有文件固定放在 `dx/env/templates/<profile>/<environment>.local`,与对应的
268
- `<environment>.local.example` 模板同目录。真实文件必须被 Git 忽略且权限为 `0600`;模板不含真实值。
269
-
270
- ```bash
271
- dx env status
272
- dx env validate secondary --staging
273
- dx env exec secondary --staging -- dx deploy backend
43
+ #!/bin/sh
44
+ # dx/scripts/build:具体构建策略属于应用。
45
+ exec pnpm exec nx build "$@"
274
46
  ```
275
47
 
276
- `committedRuntime` 是可选的公开 runtime allowlist。`target` 必须指向 `env-policy.jsonc.targets`
277
- 中的 target;`keys` 只会从该 target 当前环境的 committed 文件读取。未配置时默认空 allowlist,
278
- 行为与旧版本一致。allowlist 不接受 secret/localOnly 键、空值或机密占位符,也不允许 committed
279
- 文件越出项目根目录。合并优先级为调用进程环境 < private profile < committed allowlist,因此仓库
280
- 已审查的 committed 公共值最终生效,未列入 allowlist 的 committed 字段不会被导出。
281
-
282
- `dx env exec` 会加锁、原子装配 `.env.<environment>.local`、把合并后的值注入直接子进程,并在成功、
283
- 失败或中断后删除临时文件。根目录不允许持久保存 staging/production `.local`;发现旧文件时命令
284
- 会直接报错,必须先迁移到品牌 profile。内部 `dx` 命令未指定环境时会自动补齐;指定冲突环境时
285
- 直接拒绝。该命令只操作本机文件和子进程,不包含上传、同步或修改 GitHub Environment 的能力。
286
-
287
- ## 示例工程
288
-
289
- 查看 `example/`:包含一个最小可读的 `dx/config` 配置示例,以及如何在一个 pnpm+nx monorepo 中接入 dx。
290
-
291
- ## 命令
292
-
293
- dx 的命令由 `dx/config/commands.json` 驱动,并且内置了一些 internal runner(避免项目侧依赖任何 `scripts/lib/*.js`):
294
-
295
- - `internal: sdk-build`:SDK 生成/构建
296
- - `internal: backend-package`:后端打包
297
- - `internal: backend-artifact-deploy`:后端制品构建、上传与远端部署
298
- - `internal: artifact-deploy`:技术栈无关的制品构建、上传、原子切换与服务启动
299
- - `internal: start-dev`:开发环境一键启动
300
- - `internal: pm2-stack`:PM2 交互式服务栈(支持端口清理/缓存清理配置)
301
-
302
- 内置命令入口速览:
303
-
304
- - `dx start [target]`:启动开发服务;未指定 target 时默认使用 `start.development`
305
- - `dx build [target]`:按当前环境构建;未指定 target 时默认 `all`
306
- - `dx test [unit|e2e] <target> [path...]`:运行测试;unit 自动使用 `--test` 环境,e2e 自动使用 `--e2e` 环境
307
- - `dx db <generate|migrate|deploy|reset|seed|format|script>`:数据库相关命令;`migrate` 仅允许 `--dev`
308
- - `dx deploy <target>`:部署目标;普通 Vercel target 默认 `--staging`,artifact target 默认 `--dev`
309
- - `dx lint [--fix]`:运行 lint;`--fix` 会透传给下游 runner
310
- - `dx install`:执行项目配置的安装命令
311
- - `dx clean [target]` / `dx cache clear`:执行清理类命令,危险操作会要求确认
312
- - `dx package backend [--skip-build]`:使用内置后端打包 runner
313
- - `dx worktree <make|del|list|clean>`:管理 issue worktree;这是 dx 封装,不等同于原生 `git worktree`
314
- - `dx export <target>`:执行配置化导出命令
315
- - `dx contracts [generate|pull]`:导出 OpenAPI 并生成 `packages/api-contracts` 下的 Zod 合约(需要目标工程具备对应结构)
316
- - `dx release version <version>`:同步更新常见 app 包版本号
317
- - `dx env status|validate|exec`:安全校验并临时装配多品牌私有环境 profile(需 `env-profiles.json`)
318
- - 内置命令族支持项目扩展:例如项目可在 `commands.json.release.plan/run` 中声明
319
- `dx release plan --prod` 和 `dx release run --prod`,同时保留内置的 `release version`
320
- - `dx initial`:同步包内 skills 到本机 agent 目录
321
-
322
- 常用示例:
323
-
324
48
  ```bash
325
- dx start backend --dev
326
- dx start all --dev
327
- dx build backend --prod
328
- dx build sdk --dev
329
- dx db generate
330
- dx db migrate --dev --name init
331
- dx db deploy --prod -Y
332
- dx deploy front --staging
333
- dx deploy backend --prod
334
- dx install
335
- dx lint
336
- dx lint --fix
337
- dx test unit backend apps/backend/src/modules/user/user.service.spec.ts
338
- dx test e2e backend apps/backend/e2e/auth
339
- dx test e2e quantify apps/quantify/e2e/health/health.e2e-spec.ts
340
- dx db script fix-email-verified-status --dev -- --dry-run
341
- dx package backend --prod --skip-build
342
- dx worktree make 88 --base main
343
- dx cache clear -Y
49
+ chmod +x dx/scripts/build
50
+ dx build admin
344
51
  ```
345
52
 
346
- 测试命令默认并行度:
53
+ Node、Shell 或其他语言均可使用同一接口。新增合法名称的脚本即可增加命令,例如 `dx/scripts/lint` 对应 `dx lint`;名称须匹配 `[a-z][a-z0-9-]*`。
347
54
 
348
- - `dx test unit ...` 会自动追加 `--maxWorkers=8`
349
- - `dx test e2e ...` 会自动追加 `--workers=8`
350
- - 如果命令配置或 `--` 透传参数里已经指定了对应 worker 参数,dx 不会重复追加;例如 `dx test e2e backend apps/backend/e2e/auth -- --workers=2`
351
- - 如果 unit 命令或对应 `apps/<target>/package.json` 的 `scripts.test` 已使用 Jest `--runInBand`,dx 不会追加 `--maxWorkers=8`,避免触发 Jest 互斥参数错误
55
+ ## 标准命令语义
352
56
 
353
- 关于 `dx initial`:
57
+ | 命令 | 应用脚本的职责 |
58
+ | --- | --- |
59
+ | `dx setup` | dx 基础 setup 完成后,执行应用准备,例如安装依赖、生成文件 |
60
+ | `dx start stack` | 启动 monorepo 定义的全部服务,默认 dev 环境 |
61
+ | `dx start admin` | 只启动指定应用,默认 dev 环境 |
62
+ | `dx build ...` | 构建指定目标 |
63
+ | `dx test ...` | 执行测试 |
64
+ | `dx db ...` | 数据库操作 |
65
+ | `dx deploy ...` | 部署 |
354
66
 
355
- - `dx initial` 会把 npm 包内置的 `skills/` 覆盖同步到 `~/.agents/skills`。
356
- - 技能的流程、运行时引用和脚本都放在各自目录内,随整个技能一同同步。
357
- - `~/.claude/skills` 中包内管理的同名非软链接 skill 会先删除,再创建指向 `~/.agents/skills` 的软链接。
358
- - `~/.codex/skills` 中包内管理的同名非软链接 skill 会被清理;已有软链接不会按旧副本删除。
359
- - 从包内移除的历史 skill 会在 `~/.agents/skills`、`~/.claude/skills`、`~/.codex/skills` 中一并清理。
360
- - 不属于包内管理的其他用户自有 skill 目录会保留。
361
- - `ask_3th` 用于向第三方咨询,`delegate_3th` 用于委托第三方执行。可显式调用,也可由已授权的 `ship-issue-pr` 流程调用。
362
- - 运行时判断由这两个技能内部完成:Codex 宿主调用 Claude,Claude Code 宿主调用 Codex。调用失败后立即使用 fresh sub-agent 接续,返回结果时说明实际执行者与回退原因。
363
- - `dx initial` 不安装 Python、Claude CLI 或 Codex 插件,也不修改认证配置。
67
+ `start` 的目标清单由应用脚本定义,dx 不解析 `stack` 或 `admin`。环境文件由 dx 统一加载。`setup` 需要显式执行,其他命令不会自动触发它。
364
68
 
365
- 从 `ask_cc` / `delegate-cc` 升级:运行 `dx initial` 后旧技能目录会被清理,请将技能调用改为 `ask_3th` / `delegate_3th`。Claude 通道的脚本路径分别改为 `~/.agents/skills/ask_3th/scripts/ask_3th.py` 和 `~/.agents/skills/delegate_3th/scripts/delegate_3th.py`。脚本调用失败统一返回 `fallback_required`,不再自动轮换模型或返回 `continuation_required` / `next_model`;由技能执行者启动 fresh sub-agent 并等待完成。`--timeout` 仍是无活动告警阈值。
69
+ ## 基础 setup
366
70
 
367
- Issue/PR 交付统一使用 `ship-issue-pr`:在 Codex 中调用 `$ship-issue-pr`,在 Claude Code 中调用 `/ship-issue-pr`。该技能只调用咨询或委托接口、验收结果并记录执行说明,运行时和回退决策封装在依赖技能内部。
71
+ 每次 `dx setup` 都按顺序执行:
368
72
 
369
- 升级 dx 后再次运行 `dx initial`,会整体更新 `~/.agents/skills/ship-issue-pr/`,并清理已移除的技能和独立引用文件。现有调用统一改为 `ship-issue-pr`。Claude 的软链接直接读取同一份更新;入口同时声明 Codex 和 Claude 的显式调用策略。外部 Claude CLI 或 Codex 插件仍需自行安装并完成认证,目录兼容不代表外部通道已可用。
73
+ 1. dx 定位当前 Git worktree 根目录及主 Git 工作目录。
74
+ 2. 若当前是 linked worktree,递归将主工作目录中所有以 `.local` 结尾的普通文件复制到当前 worktree 根目录,保留相对路径和文件权限;包含隐藏文件和被 Git 忽略的文件,例如 `.env.local`、`.env.development.local`、`apps/admin/config.local`。
75
+ 3. dx 加载环境文件,再运行应用 `dx/scripts/setup`,因此应用能立即使用刚复制的环境值。
370
76
 
371
- 默认安装根目录固定为当前用户的 `~/.agents` 和 `~/.claude`;`dx initial` 当前不读取 `AGENTS_HOME` 或 `CLAUDE_CONFIG_DIR`。引用文件使用技能目录内的相对路径。需要从本仓库验证当前修改时,使用 `node ./bin/dx.js --config-dir ./example/dx/config initial`;日常 `dx initial` 同步的是当前安装的 npm 包内容。
77
+ 目标已存在的文件、目录或链接均跳过,重复执行不会覆盖本地修改。从主工作目录的子目录调用时仍视为主工作目录,不进行复制。非 Git 工程或没有主 checkout 的 bare 仓库跳过复制,继续应用 setup。
372
78
 
373
- 关于 `help`:
79
+ 复制不跟随源符号链接,不进入 `.git` 元数据和主目录内的其他 worktree;目标父路径必须是实际目录。复制失败会停止应用 setup,修正路径或权限后可重新执行。Git 需要已安装。此公共步骤由 dx 自动调用,应用无需继承类或主动调用;`start/build/test/db/deploy` 不触发它。
374
80
 
375
- - `dx --help`
376
- - `dx help <command>`
81
+ ## 环境文件
377
82
 
378
- 现在都优先从 `commands.json` 的 `help` 区域动态生成。
83
+ 所有应用入口(包括 setup 和自定义命令)执行前,dx 使用 dotenv 解析工程根的两层文件,并使用 dotenv-expand 展开变量。优先级从低到高:
379
84
 
380
- 如果某个命令还没有补充足够的 `help` 元数据,输出会回退到配置结构推导出的最小帮助,而不是旧的手写兼容文案。
381
-
382
- 命令约束摘要:
383
-
384
- - 对声明了 `requiresPath: true` 的 E2E target,`dx test e2e <target>` 必须提供文件或目录路径,禁止无路径或 `all` 全量执行
385
- - `dx test e2e all` 不受支持,必须显式指定 target 和路径
386
- - `dx test unit ...` 默认使用 8 个 worker;`dx test e2e ...` 默认使用 8 个 worker;可通过 `--` 透传参数覆盖;unit 检测到 Jest `--runInBand` 时不会追加 `--maxWorkers`
387
- - `dx db migrate --dev` 必须通过 `--name` 或 `-n` 指定迁移名,禁止依赖 Prisma 交互式输入
388
- - `dx db migrate` 仅允许在 `--dev` 环境创建迁移;非开发环境请使用 `dx db deploy`
389
- - `dx db generate/migrate/deploy/reset/seed/script` 会禁用 Nx 缓存,避免命中缓存后未实际执行
390
- - `dx deploy` 仅支持 `--dev`、`--staging`、`--prod`,不支持 `--test` / `--e2e`
391
- - `dx start` 未指定服务时默认是开发套件,仅允许 `--dev`
392
- - `dx start` 下的单层目标(如 `stagewise-front`)默认仅支持 `--dev`
393
- - `dx build` 显式传入环境标志时,必须是该 target 实际支持的环境
394
- - `dx worktree` 是 dx 的 issue worktree 封装,与原生 `git worktree` 行为不同,不要混用
395
-
396
- ### `dx start stack` 配置详解(PM2 交互式服务栈)
397
-
398
- 从 `0.1.78` 起,`dx start stack` 推荐完全由 `dx/config/commands.json` 配置驱动,不再依赖硬编码服务列表。
399
-
400
- 最小可用配置:
401
-
402
- ```json
403
- {
404
- "start": {
405
- "stack": {
406
- "internal": "pm2-stack",
407
- "interactive": true,
408
- "description": "PM2 交互式服务栈",
409
- "stack": {
410
- "ecosystemConfig": "ecosystem.config.cjs",
411
- "services": ["backend", "front", "admin"],
412
- "preflight": {
413
- "killPorts": [3000, 3001, 3500],
414
- "pm2Reset": true
415
- }
416
- }
417
- }
418
- }
419
- }
85
+ ```text
86
+ 调用者环境变量 < .env.<环境> < .env.<环境>.local
420
87
  ```
421
88
 
422
- 完整字段说明:
423
-
424
- - `start.stack.internal`
425
- - 固定为 `pm2-stack`,表示启用内置 PM2 交互式 runner。
426
- - `start.stack.interactive`
427
- - 建议设为 `true`,用于标记这是交互式命令(便于团队识别)。
428
- - `start.stack.stack.ecosystemConfig`
429
- - PM2 配置文件路径;支持相对路径(相对项目根目录)或绝对路径。
430
- - 默认值:`ecosystem.config.cjs`。
431
- - `start.stack.stack.pm2Bin`
432
- - PM2 命令前缀,默认 `pnpm pm2`。如果团队使用全局 pm2,可改为 `pm2`。
433
- - `start.stack.stack.services`
434
- - 交互命令(`r/l/s`)可操作的服务名单。
435
- - 示例:`["backend", "front", "admin"]`。
436
- - `start.stack.stack.preflight.killPorts`
437
- - 启动前自动清理占用端口列表。
438
- - 这就是“某些端口被占用时自动处理”的核心配置。
439
- - `start.stack.stack.preflight.forcePortCleanup`
440
- - 是否强制清理端口占用,默认 `true`。
441
- - `start.stack.stack.preflight.pm2Reset`
442
- - 启动前是否执行 PM2 状态重置(`delete all` / `kill` / 状态文件清理),默认 `true`。
443
- - `start.stack.stack.preflight.cleanPaths`
444
- - 启动前需要删除的缓存路径列表(相对项目根目录)。
445
- - 适合清理 `.next`、`dist`、`.vite` 等缓存,避免脏状态。
446
- - `start.stack.stack.preflight.cleanTsBuildInfo`
447
- - 是否清理 `*.tsbuildinfo`,默认 `true`。
448
- - `start.stack.stack.preflight.cleanTsBuildInfoDirs`
449
- - 扫描 `*.tsbuildinfo` 的目录列表。
450
-
451
- 交互命令保持不变:
452
-
453
- - `r <service>` 重启服务
454
- - `l <service>` 查看日志
455
- - `s <service>` 停止服务
456
- - `list` 查看状态
457
- - `monit` 打开 PM2 监控
458
- - `q` 停止所有服务并退出
459
-
460
- 推荐实践:
461
-
462
- - 将 `services` 与 `ecosystem.config.cjs` 里的 app 名保持一致,避免交互命令找不到服务。
463
- - `killPorts` 只配置开发态常驻端口,避免误杀不相关进程。
464
- - 如果项目不是 `apps/front` / `apps/admin-front` 结构,请按实际目录改 `cleanPaths` 与 `cleanTsBuildInfoDirs`。
465
-
466
- ## deploy 行为说明
467
-
468
- 从 `0.1.9` 起,`dx deploy <target>` 不再在 dx 内部硬编码执行任何 `nx build`/`sdk build` 等前置步骤。
469
-
470
- - 需要的前置构建(例如 `shared`、`api-contracts`、OpenAPI 导出、后端构建等)应由项目自己的 Nx 依赖图(`dependsOn`/项目依赖)或 Vercel 的 `buildCommand` 负责。
471
- - 这样 dx deploy 不会强依赖 `apps/sdk` 等目录结构,更容易适配不同 monorepo。
472
-
473
- ### 配置化 Vercel target
474
-
475
- Vercel target 不再限于 dx 内置名称。项目可以在 `commands.json` 声明任意 target,适合多品牌分别绑定配置文件和 Project ID:
476
-
477
- ```json
478
- {
479
- "deploy": {
480
- "front-br": {
481
- "description": "部署 br front",
482
- "vercel": {
483
- "configFile": "vercel.front.br.json",
484
- "projectIdEnvVar": "VERCEL_PROJECT_ID_FRONT",
485
- "deployCwd": ".",
486
- "prebuiltCwd": "."
487
- }
488
- }
489
- }
490
- }
491
- ```
89
+ 不加载通用 `.env`、`.env.local` 或旧 `dx/config/env-layers.json`。文件缺失时跳过,读取失败时停止执行并提示文件路径;帮助和版本查询不加载文件。
492
90
 
493
- ```bash
494
- dx deploy front-br --prod
495
- ```
91
+ 环境选择依次使用:
496
92
 
497
- Project ID 的值仍由当前环境层或 CI Environment 注入;`commands.json` 只声明变量名,不保存凭据或具体 ID。
498
-
499
- ### 通用制品发布(非 Node / systemd)
500
-
501
- 当 target 配置为 `internal: "artifact-deploy"` 时,`dx deploy <target>` 使用技术栈无关的制品发布流程。远端不要求 Node、pnpm、dotenv、PM2;安装、启动和验活都由 target 自己声明。
502
-
503
- ```json
504
- {
505
- "deploy": {
506
- "comfyui-mulerouter": {
507
- "internal": "artifact-deploy",
508
- "artifactDeploy": {
509
- "build": {
510
- "command": "python scripts/build_comfyui_mulerouter.py",
511
- "sourceDir": "dist/comfyui-mulerouter",
512
- "versionCommand": "python scripts/read_comfyui_mulerouter_version.py"
513
- },
514
- "artifact": {
515
- "outputDir": "release/comfyui-mulerouter",
516
- "bundleName": "comfyui-mulerouter-bundle",
517
- "releaseName": "comfyui-mulerouter"
518
- },
519
- "remote": {
520
- "production": {
521
- "host": "gpu-prod",
522
- "port": 22,
523
- "user": "deploy",
524
- "baseDir": "/srv/comfyui-mulerouter"
525
- }
526
- },
527
- "deploy": {
528
- "keepReleases": 5,
529
- "installCommand": "python -m pip install -r requirements.txt"
530
- },
531
- "startup": {
532
- "mode": "systemd",
533
- "serviceName": "comfyui-mulerouter.service"
534
- },
535
- "verify": {
536
- "command": "sudo systemctl is-active --quiet comfyui-mulerouter.service",
537
- "healthCheck": {
538
- "url": "http://127.0.0.1:8188/health",
539
- "timeoutSeconds": 10,
540
- "maxWaitSeconds": 30,
541
- "retryIntervalSeconds": 2
542
- }
543
- }
544
- }
545
- }
546
- }
547
- }
548
- ```
93
+ 1. 命令后、首个 `--` 前的 `--prod`、`--staging`、`--dev`、`--test`、`--e2e`。同时出现多个时,按此顺序取第一个,沿用旧版优先级。
94
+ 2. 调用者的 `APP_ENV`,其次 `NODE_ENV`;都未设置时为 `development`。`dev` / `local` 归一为 `development`。
549
95
 
550
- 常用命令:
96
+ 支持 development、staging、production、test、e2e;其他名称明确报错。应用收到的 `APP_ENV` 固定为选定环境,`NODE_ENV` 映射为 development / production / test(staging → production,e2e → test),这两个选择变量不被文件覆盖。dx 不根据 build/test 等命令名强制切换环境。
551
97
 
552
98
  ```bash
553
- dx deploy comfyui-mulerouter --prod
554
- dx deploy comfyui-mulerouter --build-only
555
- dx deploy comfyui-mulerouter --prod --artifact release/comfyui-mulerouter/comfyui-mulerouter-bundle-v1.2.3-20260809-120000.tgz
99
+ dx start stack # 默认 development
100
+ dx start admin --prod # 加载 .env.production 和 .env.production.local
101
+ APP_ENV=staging dx deploy # 加载 staging 两层
102
+ dx start admin -- --prod # -- 后的标志仅交给应用
556
103
  ```
557
104
 
558
- 配置约定:
559
-
560
- - `build.sourceDir` 是构建完成后要打入 release 的目录。
561
- - 默认按纯技术栈命令执行构建;只有显式配置 `build.app` 时才加载 dx 的应用环境层。
562
- - 版本可来自 `artifact.version`、JSON 文件 `build.versionFile` 的 `version` 字段,或输出版本字符串的 `build.versionCommand`。
563
- - `deploy.installCommand` 可省略;配置后在新 release 目录内执行。
564
- - `startup.mode` 支持 `systemd` 和 `command`。`systemd` 默认执行 `sudo systemctl restart <serviceName>`;也可以用 `startup.command` 完全覆盖。
565
- - `startup.rollbackCommand` 可覆盖回滚后的重启命令;未配置时复用正常启动命令。
566
- - `verify.command` 会重试到成功或超过 `verify.maxWaitSeconds`(默认 24 秒);`verify.retryIntervalSeconds` 默认 2 秒。`verify.healthCheck` 可选,用于额外执行 HTTP 探测。
567
- - 生命周期命令可读取 `DX_RELEASE_DIR`、`DX_CURRENT_LINK`、`DX_PREVIOUS_RELEASE`、`DX_ENVIRONMENT`、`DX_SERVICE_NAME`。
568
- - 通用 artifact target 不触发目标工程的 pnpm 依赖安装,也不套用 backend 环境变量校验。
105
+ `dx start admin --prod` 表示在当前机器加载项目根的 `.env.production` 和 `.env.production.local`,并在当前机器启动 admin;环境标志选择配置及 APP_ENV / NODE_ENV,不会把执行位置切换到生产服务器,也不会自动部署。`--staging` 等同理。应用 start 应保持本机启动语义,远程部署由应用 deploy 等明确入口实现;连接的数据库或 API 在哪里,则由配置中的地址决定。
569
106
 
570
- 远端目录与发布语义:
107
+ 参数仍逐项原样传给脚本,包含用于选择环境的标志。只有子进程收到合并环境,dx 自身环境不被修改。变量展开遵循 dotenv-expand 语法,可引用同层之前定义的变量、前层和调用者变量;文件中的引号、注释和多行值由 dotenv 解析。
571
108
 
572
- - `<baseDir>/releases/<release-name>-v<version>-<timestamp>`
573
- - `<baseDir>/current` 原子切换到本次 release
574
- - `<baseDir>/uploads/<bundle-file>`
575
- - 成功后只保留最新的 `keepReleases` 个 release
576
- - 启动或验活失败时,`current` 切回上一 release,并执行回滚启动命令
109
+ ## 调用契约
577
110
 
578
- 打包阶段仍会拒绝任何 `.env*` 文件进入制品,并对内层归档生成 SHA-256 校验文件。已有制品可通过 `--artifact` 直接部署;该路径不要求目标工程存在 Node/pnpm 依赖。
579
-
580
- ### backend 制品发布
581
-
582
- 当 `dx/config/commands.json` 的 `deploy.backend.internal` 配置为 `backend-artifact-deploy` 时,`dx deploy backend` 走内置的后端制品发布流程,而不是 Vercel 部署。
583
-
584
- 常用命令:
111
+ - 从当前目录逐级向上寻找最近的 `dx/scripts` 目录,以对应工程根目录作为脚本 cwd。
112
+ - 最近目录缺少所请求脚本时直接报错,不运行外层同名脚本。内层完全没有这个标记时,仍会继续向上查找。
113
+ - 命令后的参数逐项原样传递,包括空字符串、`--`、`--prod`、`--help`。dx 仅识别约定的环境标志,不拼接 shell 命令。
114
+ - 将按环境契约合并的变量传给应用,标准输入输出直接继承;只有显式 `setup` 运行前述基础文件复制,安装和生成由应用负责。
115
+ - 返回脚本退出码。脚本保留前台终端;dx 转发收到的 SIGINT/SIGTERM,并传递脚本最终退出状态。
116
+ - 终端 Ctrl-C 会向前台组广播,应用应幂等处理信号并清理自己的子进程;dx 不监督任意后代或后台服务。Shell 入口可以使用 `exec` 将进程交给实际程序。
585
117
 
586
118
  ```bash
587
- dx deploy backend --prod
588
- dx deploy backend --build-only
589
- dx deploy backend --prod --artifact release/backend/backend-bundle-v1.2.3-20260719-120000.tgz
590
- dx deploy backend --prod --skip-migration
119
+ dx --help # 查看入口和实际可用脚本
120
+ dx --version # 无需目标工程
121
+ dx deploy --help # 由应用 deploy 脚本提供帮助
591
122
  ```
592
123
 
593
- `--build-only` 只生成制品;`--artifact <path>` 跳过本地构建并直接部署指定制品。artifact-only 发布也会跳过目标工程依赖安装,因此两者可用于 CI 跨 job 传递同一个、已经验证过的 backend artifact。
594
-
595
- 最小示例配置:
596
-
597
- ```json
598
- {
599
- "deploy": {
600
- "backend": {
601
- "internal": "backend-artifact-deploy",
602
- "backendDeploy": {
603
- "build": {
604
- "app": "backend",
605
- "distDir": "dist/backend",
606
- "versionFile": "apps/backend/package.json",
607
- "commands": {
608
- "development": "npx nx build backend --configuration=development",
609
- "staging": "npx nx build backend --configuration=production",
610
- "production": "npx nx build backend --configuration=production"
611
- }
612
- },
613
- "runtime": {
614
- "appPackage": "apps/backend/package.json",
615
- "rootPackage": "package.json",
616
- "lockfile": "pnpm-lock.yaml",
617
- "prismaSchemaDir": "apps/backend/prisma/schema",
618
- "prismaConfig": "apps/backend/prisma.config.ts",
619
- "ecosystemConfig": "ecosystem.config.cjs"
620
- },
621
- "artifact": {
622
- "outputDir": "release/backend",
623
- "bundleName": "backend-bundle"
624
- },
625
- "remote": {
626
- "host": "deploy.example.com",
627
- "port": 22,
628
- "user": "deploy",
629
- "baseDir": "/srv/example-app"
630
- },
631
- "startup": {
632
- "mode": "pm2",
633
- "serviceName": "backend"
634
- },
635
- "deploy": {
636
- "keepReleases": 5,
637
- "installCommand": "pnpm install --prod --no-frozen-lockfile --ignore-workspace",
638
- "prismaGenerate": true,
639
- "prismaMigrateDeploy": true
640
- },
641
- "verify": {
642
- "healthCheck": {
643
- "url": "http://127.0.0.1:3005/api/v1/health",
644
- "timeoutSeconds": 10,
645
- "maxWaitSeconds": 24,
646
- "retryIntervalSeconds": 2
647
- }
648
- }
649
- }
650
- }
651
- }
652
- }
653
- ```
124
+ 无命令时显示帮助。帮助列举不会执行应用脚本。缺少工程目录、脚本、执行权限或解释器时,按错误提示修正对应路径或权限。
654
125
 
655
- 固定远端目录协议:
126
+ ## 从旧版硬切换
656
127
 
657
- - `<baseDir>/releases/<version-name>`
658
- - `<baseDir>/current`
659
- - `<baseDir>/shared/.env.<environment>`
660
- - `<baseDir>/shared/.env.<environment>.local`
661
- - `<baseDir>/uploads/<bundle-file>`
128
+ 0.2.0 删除旧工程实现。旧 `dx/config/*`、internal runners、环境策略校验、部署/回滚、SDK、PM2、worktree 管理命令和 `dx-with-version-env` 不再提供,也不读取 `DX_CONFIG_DIR` 或顶层 `--config-dir`。技能资源与 `dx initial` 保留;公共两层环境加载和 setup 的 worktree 文件准备由 dx 提供。
662
129
 
663
- 运行时制品约束:
130
+ 应用在 `dx/scripts/` 实现需要的入口,将确认、启动编排和部署安全等逻辑放入自身脚本,直接使用 dx 注入的环境,然后显式执行 `dx setup`。dx 不自动把旧配置转换为脚本。
664
131
 
665
- - 生成的 release `package.json` 默认只保留运行时依赖;如果应用把 `prisma` 放在 `devDependencies`,dx 会自动把它提升进 release 依赖,保证远端 `prisma generate` / `prisma migrate deploy` 可执行。
666
- - 打包前会递归扫描整个 staged payload;任意层级出现 `.env*` 文件都会直接失败,避免把环境文件误打进制品。
667
- - 所有本地路径字段都会被解析为相对项目根目录,并且必须留在项目根目录内;例如 `build.distDir`、`runtime.prismaSchemaDir`、`artifact.outputDir` 不能通过 `../` 逃逸到仓库外。
668
- - `remote.baseDir` 必须是绝对路径,并且只能包含 `/`、字母、数字、`.`、`_`、`-`;不要使用空格或 shell 特殊字符。
669
-
670
- 部署后验活与成功摘要:
671
-
672
- - `dx deploy backend` 在远端启动完成后,会继续校验 `current` 软链接是否切到本次 release。
673
- - 如果 `startup.mode` 是 `pm2`,还会校验 PM2 进程是否存在,以及 PM2 中的 `APP_ENV` / `NODE_ENV` 是否与部署环境一致。
674
- - 如果配置了 `verify.healthCheck`,dx 会在远端对健康检查地址做重试探测;适合处理不同项目启动时间不一致的问题。
675
- - 成功后,dx 会在本地 CLI 回显一段摘要,默认包含:
676
- - release 版本名
677
- - current 当前指向的 release 目录
678
- - service/status
679
- - APP_ENV / NODE_ENV
680
- - health 地址
681
-
682
- 示例成功输出:
683
-
684
- ```text
685
- ✅ 后端部署成功: backend-v0.0.24-20260313-174425
686
- 🚀 [deploy-summary] current=/opt/work/noveai/releases/backend-v0.0.24-20260313-174425
687
- 🚀 [deploy-summary] service=noveai-backend status=online
688
- 🚀 [deploy-summary] APP_ENV=staging NODE_ENV=production
689
- 🚀 [deploy-summary] health=http://127.0.0.1:3005/api/v1/health
690
- ```
691
-
692
- `verify.healthCheck` 配置说明:
693
-
694
- - `url`:健康检查地址。未配置时,dx 会跳过 health check,但仍会执行 `current` / PM2 验活。
695
- - `timeoutSeconds`:单次 `curl` 请求超时。
696
- - `maxWaitSeconds`:从启动后开始,health check 最长等待多久;超过这个时间仍未成功则失败。
697
- - `retryIntervalSeconds`:两次 health check 之间的等待间隔。
698
-
699
- 推荐配置:
700
-
701
- ```json
702
- {
703
- "verify": {
704
- "healthCheck": {
705
- "url": "http://127.0.0.1:3005/api/v1/health",
706
- "timeoutSeconds": 10,
707
- "maxWaitSeconds": 24,
708
- "retryIntervalSeconds": 2
709
- }
710
- }
711
- }
712
- ```
713
-
714
- 说明:
715
-
716
- - `timeoutSeconds` 控制“单次请求能等多久”。
717
- - `maxWaitSeconds` 控制“服务从启动到 ready 最多允许多久”。
718
- - `retryIntervalSeconds` 越小,ready 后越快通过;越大,请求频率越低。
719
-
720
- SSH 认证说明:
721
-
722
- - `dx deploy backend` 当前直接调用系统 `ssh` / `scp`,不会单独解析 `sshKey`、`identityFile` 之类的 dx 配置项。
723
- - 因此,发布使用哪把私钥,取决于本机 OpenSSH 的默认认证行为,例如 `ssh-agent`、`~/.ssh/config`、默认私钥文件等。
724
- - 如果你已经在 `~/.ssh/config` 中配置了主机别名(例如 `Host ai-staging`),推荐直接把 `backendDeploy.remote.host` 写成这个别名,让 OpenSSH 自动匹配对应的 `HostName`、`User`、`Port`、`IdentityFile`。
725
- - `backendDeploy.remote` 可以保持旧的单远端对象;也可以按环境拆成 `remote.staging` / `remote.production`,此时 `dx deploy backend --staging` 与 `dx deploy backend --prod` 会选择对应环境的远端。
726
-
727
- 例如本机 `~/.ssh/config`:
728
-
729
- ```sshconfig
730
- Host ai-staging
731
- HostName 1.2.3.4
732
- User deploy
733
- Port 22
734
- IdentityFile ~/.ssh/your_staging_key
735
- ```
736
-
737
- 对应的 `dx/config/commands.json`:
738
-
739
- ```json
740
- {
741
- "deploy": {
742
- "backend": {
743
- "internal": "backend-artifact-deploy",
744
- "backendDeploy": {
745
- "remote": {
746
- "host": "ai-staging",
747
- "port": 22,
748
- "user": "deploy",
749
- "baseDir": "/srv/example-app"
750
- }
751
- }
752
- }
753
- }
754
- }
755
- ```
756
-
757
- 按环境区分远端时:
758
-
759
- ```json
760
- {
761
- "deploy": {
762
- "backend": {
763
- "internal": "backend-artifact-deploy",
764
- "backendDeploy": {
765
- "remote": {
766
- "staging": {
767
- "host": "ai-staging",
768
- "port": 22,
769
- "user": "deploy",
770
- "baseDir": "/srv/example-app"
771
- },
772
- "production": {
773
- "host": "ai-ubuntu-prod",
774
- "port": 22,
775
- "user": "deploy",
776
- "baseDir": "/srv/example-app"
777
- }
778
- }
779
- }
780
- }
781
- }
782
- }
783
- ```
784
-
785
- 注意:
786
-
787
- - `remote.host` 写成别名后,dx 仍会显式传入 `remote.user` 和 `remote.port`;如果这两个值与 `~/.ssh/config` 中的 `User` / `Port` 不一致,命令行参数会覆盖 SSH config。
788
- - 最稳妥的做法是让 `remote.user`、`remote.port` 与 `~/.ssh/config` 保持一致,或者都统一以 SSH config 中的值为准后再同步到 dx 配置。
789
-
790
- ## 依赖关系约定
791
-
792
- dx 不负责管理「工程之间的构建依赖关系」。如果多个工程之间存在依赖(例如 `front/admin` 依赖 `shared` 或 `api-contracts`),必须由 Nx 的依赖图来表达并自动拉起:
793
-
794
- - 使用 Nx 的项目依赖(基于 import graph 或 `implicitDependencies`)
795
- - 使用 `nx.json` 的 `targetDefaults.dependsOn` / `targetDependencies`
796
-
797
- dx 只会执行你在 `dx/config/commands.json` 中配置的命令,不会在执行过程中额外硬编码插入依赖构建。
798
-
799
- ## 给 Nx target 注入版本信息(可选)
800
-
801
- 本包提供 `dx-with-version-env`,用于在 `nx:run-commands` 中注入版本/sha/构建时间等环境变量:
802
-
803
- ```json
804
- {
805
- "command": "dx-with-version-env --app front -- next build"
806
- }
807
- ```
808
-
809
- 支持的 app:`backend` / `front` / `admin`。
810
-
811
- ## 约束与假设
812
-
813
- 当前版本面向 pnpm + nx 的 monorepo,默认假设:
814
-
815
- - 使用 pnpm + nx
816
- - 项目布局包含 `apps/backend`、`apps/front`、`apps/admin-front`(如有差异,通过 `dx/config/commands.json` 适配)
817
- - 版本注入脚本 `dx-with-version-env` 默认支持 app: `backend` / `front` / `admin`
818
-
819
- ## 发布到 npm
820
-
821
- 本项目以公开 scope 包 `@weotro/dx` 发布。发布前确认 `package.json` 中的版本尚未存在于 npm,并保持 Git 工作区干净。
822
-
823
- 仓库提供的发布脚本会校验 token、版本、Git 工作区和 `private` 标志,并以 public access 发布:
132
+ ## 开发与示例
824
133
 
825
134
  ```bash
826
- ./publish.sh --token "npm_xxx"
135
+ pnpm install --frozen-lockfile
136
+ pnpm test
827
137
  ```
138
+
139
+ [最小示例](example/README.md)仅展示调用契约,不实际安装、启动服务或部署。[开发约定](ruler/development.md)说明本仓库的验证与发布流程。