@weotro/dx 0.2.0 → 0.2.2
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.
- package/README.md +4 -0
- package/package.json +1 -1
- package/skills/dx-adopt/SKILL.md +96 -0
- package/skills/dx-adopt/agents/openai.yaml +2 -0
- package/skills/dx-adopt/references/adoption-regressions.md +100 -0
- package/skills/dx-adopt/references/dx-0.2-contract.md +95 -0
- package/skills/dx-adopt/references/migrate-0.1.md +50 -0
package/README.md
CHANGED
|
@@ -23,6 +23,8 @@ dx initial --help
|
|
|
23
23
|
|
|
24
24
|
`initial` 用于安装和更新技能,`setup` 用于当前项目的准备;两者独立,不互相自动调用。自定义应用命令不得使用保留名称 `initial`。技能中的外部工具需另行安装和认证,initial 只同步技能文件。
|
|
25
25
|
|
|
26
|
+
首次接入或从 0.1.x 升级的应用可使用随包的 [dx-adopt](skills/dx-adopt/SKILL.md) 技能,例如“使用 $dx-adopt 为当前项目接入 dx 0.2.1,并完成验证”。技能会区分新项目与旧版迁移,生成项目自己的脚本并适配环境、setup 和调用方。
|
|
27
|
+
|
|
26
28
|
## 应用提供脚本
|
|
27
29
|
|
|
28
30
|
```text
|
|
@@ -100,6 +102,8 @@ APP_ENV=staging dx deploy # 加载 staging 两层
|
|
|
100
102
|
dx start admin -- --prod # -- 后的标志仅交给应用
|
|
101
103
|
```
|
|
102
104
|
|
|
105
|
+
`dx start admin --prod` 表示在当前机器加载项目根的 `.env.production` 和 `.env.production.local`,并在当前机器启动 admin;环境标志选择配置及 APP_ENV / NODE_ENV,不会把执行位置切换到生产服务器,也不会自动部署。`--staging` 等同理。应用 start 应保持本机启动语义,远程部署由应用 deploy 等明确入口实现;连接的数据库或 API 在哪里,则由配置中的地址决定。
|
|
106
|
+
|
|
103
107
|
参数仍逐项原样传给脚本,包含用于选择环境的标志。只有子进程收到合并环境,dx 自身环境不被修改。变量展开遵循 dotenv-expand 语法,可引用同层之前定义的变量、前层和调用者变量;文件中的引号、注释和多行值由 dotenv 解析。
|
|
104
108
|
|
|
105
109
|
## 调用契约
|
package/package.json
CHANGED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dx-adopt
|
|
3
|
+
description: 为项目接入 @weotro/dx 0.2.0 及以上版本,迁移旧版、审查升级适配或精简项目命令;实现项目入口、环境和进程管理,验证 worktree setup、构建、测试及 CI。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DX 项目接入、升级与适配审查
|
|
7
|
+
|
|
8
|
+
在用户指定的应用仓库完成接入;未指定时使用当前仓库。适用于已有 monorepo 和新项目,不要求使用 Nx、Prisma 或 PM2。产出能运行的项目脚本和接入说明,不仅修改版本号。只读咨询则给出基于该项目的差异和迁移方案。
|
|
9
|
+
|
|
10
|
+
本技能随 dx 分发,引用文件均位于本技能目录,安装后无需访问 dx 源码仓库。最低接入版本为 0.2.0;契约参考记录的是 0.2.1 行为,实际包需核验,版本下限不等于对未来版本的兼容保证。
|
|
11
|
+
|
|
12
|
+
## 1. 确定项目状态
|
|
13
|
+
|
|
14
|
+
读取适用的 AGENTS.md、工作区差异、package.json、锁文件、CI 和实际任务入口。确认目标是使用 dx 的应用,而非误把 dx 工具仓库当成应用。保留现有包管理器和工具链。
|
|
15
|
+
|
|
16
|
+
核对 dx 的实际来源和版本:区分全局 `dx`、项目依赖与 CI 安装步骤。可用 `command -v dx`、`dx --version` 和项目包管理器的依赖查询核对;CLI 不存在时从依赖与调用点继续盘点,不阻塞脚本编写。不要用会自动下载其他版本的命令代替版本核验。Node 工具链保持现状,仅在实际运行或所用 API 出现兼容性证据时处理,尊重用户排除范围。
|
|
17
|
+
|
|
18
|
+
按证据选择路径:
|
|
19
|
+
|
|
20
|
+
| 项目状态 | 执行路径 |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| 依赖 0.1.x,或仍使用 dx/config、旧 internal runner、旧 CLI 参数 | 阅读 [0.1.x 迁移](references/migrate-0.1.md),建立旧能力到新脚本的对应关系后实施 |
|
|
23
|
+
| 从未接入 dx,或新建项目直接采用 >=0.2.0 | 跳过旧配置迁移,从现有工具命令生成下文应用入口 |
|
|
24
|
+
| 已是 0.2.x,但部分入口缺失或行为错误 | 对齐目标版本并对照契约只补缺口,保留已工作的脚本,避免重复生成 |
|
|
25
|
+
|
|
26
|
+
三条路径都先阅读 [0.2.1 能力与调用契约](references/dx-0.2-contract.md)。文件中说明哪些能力由 dx 提供,哪些必须由应用实现。
|
|
27
|
+
|
|
28
|
+
## 2. 落实版本与入口
|
|
29
|
+
|
|
30
|
+
沿用项目的安装方式,将依赖声明、开发说明与 CI 对齐到一致的版本策略,最低要求 >=0.2.0,不默认钉死某个补丁版本。全局安装默认使用 latest,并记录实际解析版本;项目有明确锁定策略时遵从该策略,本地依赖保留正常锁文件。全局项目不顺手引入第二套本地入口。检查 registry 是否提供可用版本,安装后核验实际契约,不把 latest 当作固定版本或兼容性证明。
|
|
31
|
+
|
|
32
|
+
全局安装示例为 `npm install -g @weotro/dx@latest`,随后执行 `dx --version`。全局 dx 可在应用尚未安装依赖时运行 setup;只放在应用 devDependencies 中的 dx 不能假定新 clone 后已可执行,必须保留安装 dx 的引导步骤。
|
|
33
|
+
|
|
34
|
+
在约定的项目根创建 `dx/scripts/`,只实现需要的命令:
|
|
35
|
+
|
|
36
|
+
| 入口 | 应用需要实现的内容 |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| setup | 基础复制完成后的依赖安装、必要文件生成等准备;可重复执行并保留用户本地配置 |
|
|
39
|
+
| start | 已存在的启动目标;monorepo 的 stack 必须映射到项目定义的全部服务,单应用只启动指定服务 |
|
|
40
|
+
| build | 根据实际目标和 APP_ENV 调用构建工具,明确需要的 NODE_ENV 与工具配置 |
|
|
41
|
+
| test | 单元、集成、E2E 的分流、路径参数和所需服务,不能靠命令名猜测 dx 的环境选择 |
|
|
42
|
+
| db | 实际数据库子命令、前置检查及确认规则 |
|
|
43
|
+
| deploy | 项目部署过程、环境检查、确认、失败处理和恢复 |
|
|
44
|
+
|
|
45
|
+
这六类是按需采用的标准入口,不是必须凑齐或只能保留六条的限制。命令接入或精简先按用户任务确定职责,再决定公开入口;有独立职责和实际消费者的扩展可以保留。精简请求不能只缩短帮助文本,还应处理重复包装和误导性别名。具体判断与验收见 [命令职责与精简](references/adoption-regressions.md#命令职责与精简)。
|
|
46
|
+
|
|
47
|
+
`lint` 表达静态检查,单测和脚本守卫测试归入 `test`。检查真实调用链,包括 Nx target、dependsOn 和 package forwarder,避免顶层已经拆开、下层仍隐式跑测试。若现有项目明确要求组合验证,保留为清楚命名的组合入口或显式命令序列;用户要求拆分时同步调整相关规则,不让旧约定覆盖当前意图。
|
|
48
|
+
|
|
49
|
+
脚本名无扩展名,带有效 shebang 并设置可执行权限。内部逻辑可放入项目自己的 `.mjs` / `.cjs` 或 Shell 文件;无扩展名 Node 脚本的模块模式应与目标项目及最低 Node 版本匹配,不能假定每个项目都是 ESM。
|
|
50
|
+
|
|
51
|
+
推荐将无扩展名公开入口放在 `dx/scripts/`,实现模块及配套测试放在 `dx/lib/`,项目仍消费的策略配置放在 `dx/config/`。后两者是项目组织建议,不是 DX 自动加载契约;现有合理布局可以保留。迁移目录时同步导入、相对根路径、Nx targets/inputs、测试 fixture、CI 和文档,并检查旧路径消费者。
|
|
52
|
+
|
|
53
|
+
若已有项目脚本可复用,使用薄包装。例如确认 `dx/lib/build.mjs` 已实现后:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
#!/bin/sh
|
|
57
|
+
exec node dx/lib/build.mjs "$@"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
包装调用实际工具或实现文件,避免 `dx build` → package script → `dx build` 的循环。不要导入 dx 私有 lib、恢复旧配置解释器,或为每个项目重建通用任务框架。原有 lint 等任务可通过同名脚本继续暴露;`initial` 是 dx 保留命令。
|
|
61
|
+
|
|
62
|
+
实现项目帮助和未知目标的明确失败。需要的入口必须调用真实实现;不需要的入口可以不创建。没有完成的构建、测试、数据库或部署步骤不能用 `echo` / `exit 0` 占位后宣称接入完成。
|
|
63
|
+
|
|
64
|
+
## 3. 接好参数、环境与准备顺序
|
|
65
|
+
|
|
66
|
+
按契约使用 dx 注入的环境,不再自行运行相同两层 dotenv 加载。项目若有额外服务专属文件,明确由哪个脚本加载及覆盖关系。
|
|
67
|
+
|
|
68
|
+
实现和说明 `start` 时,将环境选择与运行位置分开:`dx start admin --prod` 使用当前机器项目根的 `.env.production`、`.env.production.local` 在当前机器启动 admin。`--prod` / `--staging` 等只选择配置及 APP_ENV / NODE_ENV;应用 start 应保持本机启动语义,不将这些标志解释成 SSH、远程启动或部署。具体示例与资源连接边界见契约的“环境”部分。
|
|
69
|
+
|
|
70
|
+
dx 识别环境标志但不会从 argv 删除它们。应用消费首个 `--` 前属于环境选择的标志后,再把工具参数逐项传给工具;`--` 后的数据不得再次当作 dx 标志解析。明确工具是否需要保留或消费这个分隔符。禁止把 argv 重新拼成 shell 命令或用 eval。
|
|
71
|
+
|
|
72
|
+
setup 的顺序是 **dx 复制缺失的 .local 文件 → dx 加载环境 → 应用 setup**。先创建有效的应用 setup 入口,基础复制才会执行。应用 setup 不必再次调用 dx 的基类,也不能递归执行 `dx setup`。新 clone 没有本地凭据来源时,给出准备方法,不能凭空生成有效秘密。
|
|
73
|
+
|
|
74
|
+
对构建、E2E、预发和生产选择分别核对 APP_ENV / NODE_ENV。需要测试层的调用明确使用 `--test` 或 `--e2e`;需要生产构建的应用在自己的构建实现中控制工具行为。不要恢复旧 dx 对 Next/Nx 命令文本的隐式识别。
|
|
75
|
+
|
|
76
|
+
确认 `start stack` 的服务成员、依赖顺序、失败策略和停止方式。单应用也可能经包管理器、Nx、Shell 创建多层后代,所有入口都须按实际进程树收尾;Ctrl-C 与 SIGTERM 处理要幂等,不能只验证直接子进程退出。
|
|
77
|
+
|
|
78
|
+
## 4. 更新使用方并验收
|
|
79
|
+
|
|
80
|
+
更新 package scripts、CI、容器或部署调用、开发说明与相关 agent 指令,让它们使用已实现的新入口。旧项目的删除时机与覆盖表按迁移参考执行;新项目无需创建兼容文件或迁移旧功能。
|
|
81
|
+
|
|
82
|
+
升级、适配审查,以及修改命令职责、环境、参数、构建模式、进程管理或脚本目录时,阅读 [适配回归检查](references/adoption-regressions.md),按相关分支取得隔离测试与实际运行证据。只读审查输出按严重度排序的发现、文件位置和复现证据;修复请求则补齐对应回归并推进到验证完成。已有测试通过不代表未覆盖的契约正确。
|
|
83
|
+
|
|
84
|
+
使用目标项目自身的验证方式,按实际副作用选择测试环境。项目适配不自动包含生产部署、正式数据库迁移或远端发布;已有明确授权的操作继续执行,否则先用本地、隔离资源或项目已有的模拟入口验证对应链路。不要把真实部署当作通用冒烟。
|
|
85
|
+
|
|
86
|
+
验收应得到以下证据,而非仅列命令:
|
|
87
|
+
|
|
88
|
+
- `dx --version` 对应所选安装源,`dx --help` 在根和子目录发现正确入口;用 Git 文件模式确认脚本执行权限会随 clone 保留。
|
|
89
|
+
- 在隔离工程用非敏感标记值验证两层覆盖、显式环境选择及 argv 边界;不输出真实环境变量集合。
|
|
90
|
+
- 新 clone 的依赖引导能成立;linked worktree 中缺失的 .local 在应用 setup 前可用,已有本地值不覆盖。没有主 checkout 的环境单独记录,不能假定 CI 自动拥有本地文件。
|
|
91
|
+
- 应用 setup、实际构建与相关测试通过。验证 start 的单应用和 stack 成员及退出收尾;无相应服务时注明不适用。
|
|
92
|
+
- db/deploy 若属需求,其参数路由、前置校验与失败行为有测试;未获授权的生产执行记录为未执行,不写成部署验证通过。
|
|
93
|
+
|
|
94
|
+
`dx --help` 只做发现;`dx <command> --help` 会运行应用脚本,尤其 `dx setup --help` 仍会先复制文件。只有确认项目帮助处理无业务副作用后,才把它用作冒烟。不要假定 dx 提供通用 dry-run。
|
|
95
|
+
|
|
96
|
+
交付说明写清项目走哪条路径、安装源与版本、已实现命令及用法、环境文件与 setup 行为、实际验证、未完成项。升级任务同时给出旧能力的去向;首次接入只给出新增入口。未指定提交或发布时,完成本地改动与验证即可。
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# 适配回归检查
|
|
2
|
+
|
|
3
|
+
适用于 DX 升级审查及相关修复。以下来自实际迁移中“入口测试通过,但真实行为错误”的案例;按项目涉及的分支使用,不要求其他项目采用相同框架、服务名或脚本实现。
|
|
4
|
+
|
|
5
|
+
## 命令职责与精简
|
|
6
|
+
|
|
7
|
+
先从帮助与实际路由建立“入口 → 实现 → 消费者 → 副作用”的对应关系,再决定删除、合并或保留。迁移旧版不等于逐个复刻旧命令,也不等于删除所有自定义扩展。
|
|
8
|
+
|
|
9
|
+
- 相同实现的别名优先收敛为一个明确入口;安装、清理和缓存包装若没有项目特有职责,可回到项目允许的包管理器入口。`setup` 的依赖安装与必要生成仍是完整准备流程,不能仅因包含 install 就视为重复。
|
|
10
|
+
- 同类操作可收为子命令,例如将发布计划和执行收进 `deploy`、将 OpenAPI 导出收进 `build`。这些是组织示例,不是 DX 内置路由或所有项目的强制命名;品牌、翻译、私有环境管理等独立职责无需硬塞进六类入口。
|
|
11
|
+
- 目标名必须符合覆盖范围:曾有 `deploy all` 实际只部署默认后端,应改为明确 target 或真正的全量编排。帮助首页展示简短用途,目标与参数留给命令级帮助。
|
|
12
|
+
- 合并部署入口只改变路由,不绕过原适配器的环境校验、确认、产物清理、扫描及远端核验;分别保留只读 plan、远程 run、单目标部署与本地制品构建的边界。
|
|
13
|
+
|
|
14
|
+
### lint 与 test 的边界
|
|
15
|
+
|
|
16
|
+
遇到“lint 为什么必须带 --test”时,先追查是否把单测混进 lint,而不是先修改 DX 的默认环境。`--test` 选择环境,不是开启测试的开关;无环境依赖的静态检查通常可直接 `dx lint`,也无需强制 `--dev`。需要测试配置的测试仍显式选择对应环境。
|
|
17
|
+
|
|
18
|
+
一次实际拆分中,除了顶层先跑后端单测,`scripts:lint` 还执行整套 `node --test`。只删除顶层 test 调用并没有完成拆分。把脚本测试移到独立 test target,保留分类 forwarder、注册覆盖、缓存策略和明确执行入口;原来要求两类检查的后端验证与 CI 改为显式运行 lint 和 test,避免测试覆盖随改名丢失。参数也应按新职责核验,例如 `--fix` 只传给静态检查,脚本测试聚合入口若不支持过滤就明确拒绝,不能静默忽略。
|
|
19
|
+
|
|
20
|
+
### 迁移与验收
|
|
21
|
+
|
|
22
|
+
同步运行脚本、package scripts、CI、生成器内调用、帮助、开发说明及 AGENTS.md;机械替换后复核语义,避免留下“Web deploy 已被阻断”或“lint 已包含单测”等过期结论。历史执行记录保留原命令,当前操作指引使用新入口。
|
|
23
|
+
|
|
24
|
+
用隔离替身捕获实际 argv 和调用次数:普通 lint 不调用测试、fix 只影响静态检查、独立测试仍选对环境;合并入口到达原安全适配器,未知目标或不支持的参数在业务工具启动前失败。按影响范围跑已有注册表与适配回归,区分替身验证、真实工具运行和未执行的全仓检查,不因命令精简而运行真实发布。
|
|
25
|
+
|
|
26
|
+
核对根与子目录的 DX 命令发现,以及项目帮助。删除顶层命令需要处理 `dx/scripts/` 的可执行入口,只从 usage 中隐藏不能改变 `dx --help` 的发现结果。测试按 DX 的文件名、可执行权限和 shebang 规则识别公开入口;目录里的 `.mjs` 辅助文件不等于公开命令,不能直接断言全部目录项都是命令。
|
|
27
|
+
|
|
28
|
+
## 环境选择与隔离
|
|
29
|
+
|
|
30
|
+
DX 在应用入口运行前加载环境。入口发现是 E2E 后再调用 `dx ... --e2e`,会把第一次加载的 development 独有变量作为继承环境带入第二次调用,也会影响变量展开。仅覆盖 APP_ENV/NODE_ENV 或删除已知变量无法还原原始环境。
|
|
31
|
+
|
|
32
|
+
推荐调用方明确传 `--e2e` / `--test`,入口检查选定环境是否匹配测试套件;不匹配时在启动工具前失败,并给出正确命令。已通过调用者 APP_ENV 选对环境时可接受,是否强制显式标志由项目决定。同步 CI、Playwright webServer、测试内启动命令、文档和 agent 指令,避免保留隐式测试环境示例。
|
|
33
|
+
|
|
34
|
+
隔离工程用不同的非秘密标记值验证:
|
|
35
|
+
|
|
36
|
+
- development 独有变量不会由入口自动切换环境带入 E2E;错环境入口在启动测试或连接服务前失败。
|
|
37
|
+
- 显式 E2E 的展开结果仅来自调用者及 E2E 两层;`.env.test` 不再是 E2E 的前置层。
|
|
38
|
+
- 公开文件覆盖继承环境、local 覆盖公开文件;CI 的同名值和占位符也包含在覆盖测试内。
|
|
39
|
+
|
|
40
|
+
需要把旧 `.env.test.local` 的缺项迁到 `.env.e2e.local` 时,只迁测试需要的键,保留目标已有值与文件权限,不输出秘密。实际测试使用的 DSN、播种参数、Redis 和登录凭据须在独立环境中齐备。
|
|
41
|
+
|
|
42
|
+
项目将 DX 定为环境加载来源时,还要检查下游编排器是否再次加载 dotenv。使用 Nx 的项目可在调用边界设置 `NX_LOAD_DOT_ENV_FILES=false`,覆盖单应用、Stack 及其他直接启动 Nx 的路径;这不会自动关闭 Vite 等工具自身的加载行为。用下游可能读取文件中的独有标记值验证没有额外注入,仅断言开关已传递不足以证明最终环境隔离。
|
|
43
|
+
|
|
44
|
+
## 构建配置与优化模式
|
|
45
|
+
|
|
46
|
+
APP_ENV 表示应用配置,NODE_ENV/工具 mode 影响打包行为。`dx build ... --dev` 仍可能需要开发 API 地址和生产优化,默认继承 NODE_ENV=development 会把 React 开发版打进产物。
|
|
47
|
+
|
|
48
|
+
按项目要求在构建子进程显式控制优化模式,保留选定的应用配置;不要全局改变 start/test 的模式。同步 Nx 或其他构建缓存的相关 inputs、模式参数及实现文件依赖,确保修复后不会复用旧的开发版制品。
|
|
49
|
+
|
|
50
|
+
验收至少包含真实构建及产物检查:使用适合实际框架的开发版特征、构建元数据或运行行为确认优化生效,同时检查 API 等非秘密配置仍属于目标环境。构建退出 0 或模拟命令中的 NODE_ENV 正确不单独构成产物证据;已有缓存不能替代此次实际构建。
|
|
51
|
+
|
|
52
|
+
## 参数边界
|
|
53
|
+
|
|
54
|
+
先按第一个 `--` 拆分应用参数与工具参数,再处理应用侧环境标志、帮助和未知选项。为每个入口明确是否支持透传,以及下游消费还是保留分隔符;不支持时明确失败。
|
|
55
|
+
|
|
56
|
+
隔离捕获下游 argv,覆盖 `-- --help`、`-- --prod`、带空格的过滤条件、空参数及未知选项。`--` 后的内容不能触发项目帮助或改变环境。经过 Nx、JSON 环境载体等多层包装时,验证最终工具收到的数组;补一个真实过滤测试,确认只执行选定用例,避免参数被中间层丢弃。真实资源相关测试仍受项目授权边界约束。
|
|
57
|
+
|
|
58
|
+
## 单应用与 Stack 进程回收
|
|
59
|
+
|
|
60
|
+
仅向直接子进程转发信号可能留下 pnpm/Nx/Vite 等后代。单应用和多服务入口都要验证包装器退出、后代另建进程组、后代忽略 SIGTERM 的情况;正常结束、启动失败和重复信号也需要幂等收尾。
|
|
61
|
+
|
|
62
|
+
使用项目可维护的进程管理方式,保留退出码或信号状态,并在有限等待后清理仍属于本次运行的后代。归属可结合所创建进程组、记录的身份或随机运行标识判断;发信号前重新核对归属,避免 PID 复用或误伤其他 Stack。端口、进程名不能单独作为批量结束进程的依据。
|
|
63
|
+
|
|
64
|
+
回收失败须独立报告:底层已有非零退出码时保留原码,底层成功但回收失败时返回非零。覆盖“底层已退出、异步回收尚未完成时收到 SIGINT/SIGTERM”的时序;监听保留到收尾结束,最终结算中断状态,不能因提前保存成功码而把取消报告为成功。
|
|
65
|
+
|
|
66
|
+
平台陷阱:
|
|
67
|
+
|
|
68
|
+
- Linux `/proc` 查找方式不适用于 macOS;需要支持 macOS 时验证对应发现逻辑,尤其父包装器退出后的孤儿后代。
|
|
69
|
+
- macOS 对空组或仅剩僵尸的进程组可能返回 EPERM。只有成功检查并确认组内无活进程时才按已结束处理;真实权限错误及检查失败仍须报告,不能一概吞掉 EPERM。
|
|
70
|
+
- 读取进程环境用于运行标识匹配时,结果只在内部使用,避免把环境集合写进测试日志或异常。
|
|
71
|
+
|
|
72
|
+
真实冒烟应等待本地服务就绪,再向最外层 dx 发 SIGTERM,核对退出状态、端口释放和后代存活情况;Ctrl-C 路径也按改动范围验证。隔离探针用 finally 清理自身进程,测试失败也要回收。不能用“dx 已退出”替代服务已停止的证据。
|
|
73
|
+
|
|
74
|
+
## 环境文件布局保护
|
|
75
|
+
|
|
76
|
+
旧 env-policy 若约束文件位置,需逐项保留 allowRoot、allowSubdirGlobs、禁止路径、秘密占位符与 local-only 键等实际要求。DX 不加载某个文件,不表示 Vite 等下游工具也不会加载它;只检查必需变量不足以代替布局校验。
|
|
77
|
+
|
|
78
|
+
使用目标项目策略构建允许及禁止样例,例如 `.env.preview`、应用目录 `.env.local`,确认拒绝发生在工具启动前。扫描同时考虑未跟踪文件;按项目范围跳过生成目录、依赖目录和独立嵌套 worktree,避免误报其他 checkout 或遍历其秘密。用允许路径正例防止检查退化为一律拒绝。没有旧布局要求的项目按实际工具需要制定规则,不复制别的项目环境名单。
|
|
79
|
+
|
|
80
|
+
## 目录迁移与准备流程
|
|
81
|
+
|
|
82
|
+
`dx/scripts/` 是公开入口契约;`dx/lib/`(实现与配套测试)和 `dx/config/`(项目策略)是可选的集中布局。移动时核对:
|
|
83
|
+
|
|
84
|
+
- 包装入口、相对 import、基于 import.meta.url 的根定位、测试复制 fixture。
|
|
85
|
+
- Nx targets/inputs、lint glob、容器 COPY、CI、部署配置、文档与 agent 指令。
|
|
86
|
+
- 根与子目录调用、Git 可执行文件模式、至少一个真实命令;搜索旧路径确认没有活动消费者。
|
|
87
|
+
|
|
88
|
+
setup 使用隔离 Git 主 checkout、linked worktree 和独立 clone 验证:复制发生在应用 setup 前,已有 local 不覆盖、权限保留,独立 clone 不继承另一 clone 的秘密。应用 setup 保持幂等;仅存在 `dx/config/` 不等于有效的 `dx/scripts/setup`。
|
|
89
|
+
|
|
90
|
+
## 数据库、部署与失败归因
|
|
91
|
+
|
|
92
|
+
读取目标项目授权规则并核实实际连接目标。项目已授权 DEV/E2E reset、重建或迁移时,可在核实目标后处理校验和冲突等环境问题并重跑,不重复询问同一授权;这不是其他项目的默认授权。staging/production 的操作需要该项目用户针对环境及操作的明确授权,本地启动和 `--yes` 不能代替授权。
|
|
93
|
+
|
|
94
|
+
部署先用隔离替身验证参数、目标、确认、失败短路及构建次数,按实际部署工具版本核对 CLI 参数。明确区分模拟验证、帮助核对与真实发布,不为证明迁移成功自行触发远程部署。
|
|
95
|
+
|
|
96
|
+
检查部署平台能否绕过项目 deploy 包装器直接执行 buildCommand。若发布构建依赖包装器注入环境标志,缺失或空值须在构建前失败,避免默认为 development;Shell 可用 `${DX_ENV_FLAG:?DX_ENV_FLAG is required}`。用替身验证缺失、空值及合法值,确认失败时未启动构建。普通本地开发构建不因此强制使用发布环境。
|
|
97
|
+
|
|
98
|
+
部署凭据采用工具支持的非 argv 通道;例如核实所用 Vercel CLI 支持后通过 `VERCEL_TOKEN` 传递,避免 `--token` 暴露在进程参数和命令日志中。用假令牌检查最终 argv 与输出。CI 需要临时 local 凭据文件时,在创建文件前注册清理,再写入并运行命令,覆盖写入或后续步骤失败的路径。
|
|
99
|
+
|
|
100
|
+
失败按复现证据区分本次回归、既有问题与环境问题;必要时在不覆盖当前工作区的隔离基线复现。相关问题解决并复验后更新已知失败记录。纯技能或文档更新只检查结构、引用与差异,不因此重跑业务全仓测试。
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# DX 0.2.1 能力与调用契约
|
|
2
|
+
|
|
3
|
+
本文随技能发布,供应用接入时独立使用。实际安装包不同于 0.2.1 时核对行为,不将此表外推为其他版本的保证。
|
|
4
|
+
|
|
5
|
+
## 能力分界
|
|
6
|
+
|
|
7
|
+
| dx 提供 | 应用提供 |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| 最近工程发现、脚本检查、进程调用、退出状态 | 构建、测试、数据库和部署的具体实现 |
|
|
10
|
+
| dotenv 两层加载、dotenv-expand 变量展开、环境选择 | 必需变量与占位符校验、额外服务配置 |
|
|
11
|
+
| setup 前的 worktree 本地文件准备 | 安装依赖、生成文件、准备服务 |
|
|
12
|
+
| initial 的包内技能分发 | 目标项目的代码与脚本;initial 不执行接入迁移 |
|
|
13
|
+
| 帮助与版本查询 | 应用子命令帮助、目标选择、编排和恢复 |
|
|
14
|
+
|
|
15
|
+
不内置 Nx、Prisma、PM2、Vercel、SDK 构建、制品部署、回滚、端口清理、自动重试或环境策略配置。这些工具可以继续在应用中使用。
|
|
16
|
+
|
|
17
|
+
## 安装与技能
|
|
18
|
+
|
|
19
|
+
- 包名 `@weotro/dx`,Node.js 至少 20.11.0;支持 macOS/Linux,不支持 Windows。setup 的 Git 定位需要已安装 Git。
|
|
20
|
+
- 全局安装可独立于应用 node_modules 工作;本地依赖需先有安装它的引导途径。运行时依赖由 dx 包自己携带,应用不必为了 dx 的环境注入安装 dotenv CLI。
|
|
21
|
+
- `dx initial` 使用安装包中的 skills/,覆盖更新 `~/.agents/skills` 的托管技能,为 `~/.claude/skills` 建立链接,并按原规则清理托管旧副本和历史已删除技能。其他技能保留。
|
|
22
|
+
- initial 无需应用工程,不加载项目环境,不运行 setup;setup 也不会自动执行 initial。新技能随包安装后,通过 initial 同步;仅把 dx 版本写入 package.json 不等于技能已更新。
|
|
23
|
+
|
|
24
|
+
## 脚本路由
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
项目根/
|
|
28
|
+
dx/scripts/setup
|
|
29
|
+
dx/scripts/start
|
|
30
|
+
dx/scripts/build
|
|
31
|
+
dx/scripts/test
|
|
32
|
+
dx/scripts/db
|
|
33
|
+
dx/scripts/deploy
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
按需提供入口,不要求六个全部存在。自定义名称匹配 `[a-z][a-z0-9-]*`;initial 为保留命令。每个入口为可读、可执行、无扩展名的文件,shebang 解释器使用绝对路径,首行最多 255 字节,不含换行。
|
|
37
|
+
|
|
38
|
+
从调用目录向上找到最近的 `dx/scripts`,对应项目根作为应用脚本 cwd。最近标记损坏、不可读或缺少所请求入口时直接失败;不会执行外层同名命令。未发现内层标记才继续向上查找。
|
|
39
|
+
|
|
40
|
+
`dx build admin --prod` 只运行 `dx/scripts/build`,脚本仍收到 `admin`、`--prod`。没有自动的二级命令查找、app 目录推断、默认 all 或构建编排。`start stack` 与 `start admin` 也调用同一个 start 文件,由应用选择服务。
|
|
41
|
+
|
|
42
|
+
无参数和顶层 `--help` 显示帮助,`--version` 无需工程。`dx initial --help` 是内置帮助;其他命令后的 `--help` 交给应用,不由 dx 截获。
|
|
43
|
+
|
|
44
|
+
## 环境
|
|
45
|
+
|
|
46
|
+
**环境名称选择配置,执行位置是运行 dx 的当前机器。** 例如在开发电脑执行 `dx start admin --prod`,dx 读取该电脑项目根的 `.env.production`,再加载 `.env.production.local` 覆盖,设置 APP_ENV / NODE_ENV 为 production,并在该电脑调用 `dx/scripts/start` 启动 admin。它不表示到生产服务器运行,也不触发远程连接、发布或部署;`--staging` 等标志同理。在服务器执行时,当前机器就是那台服务器。
|
|
47
|
+
|
|
48
|
+
应用 start 保持本机启动语义;需要远程部署时,由应用 deploy 等明确入口实现。进程访问哪些数据库或 API 取决于配置中的地址:本机运行仍可能连接远端资源,运行位置与资源位置应分别说明。
|
|
49
|
+
|
|
50
|
+
从找到的项目根加载,优先级由低到高:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
继承环境变量 < .env.<environment> < .env.<environment>.local
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
这意味着 CI 注入的普通变量也可能被文件中的同名值覆盖。公开文件只放适合入库的默认值或明确占位符,真实值放入忽略的 local 文件或按项目方式注入;项目脚本自己校验必要值。
|
|
57
|
+
|
|
58
|
+
环境选择按下列顺序:
|
|
59
|
+
|
|
60
|
+
1. 命令后、第一个 `--` 前的环境标志;优先级依次为 `--prod`、`--staging`、`--dev`、`--test`、`--e2e`。建议调用方只使用一个。
|
|
61
|
+
2. 调用者 APP_ENV,其次 NODE_ENV;都没有时为 development。选择名称转小写,dev/local 映射为 development;不支持的名称报错。
|
|
62
|
+
|
|
63
|
+
| 选定环境 / APP_ENV | 注入的 NODE_ENV | 两层文件 |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| development | development | .env.development、.env.development.local |
|
|
66
|
+
| staging | production | .env.staging、.env.staging.local |
|
|
67
|
+
| production | production | .env.production、.env.production.local |
|
|
68
|
+
| test | test | .env.test、.env.test.local |
|
|
69
|
+
| e2e | test | .env.e2e、.env.e2e.local |
|
|
70
|
+
|
|
71
|
+
APP_ENV 和 NODE_ENV 在展开变量前确定,不允许文件重新设置。不从环境文件中读取 APP_ENV 来决定加载哪套文件。命令名本身不会改环境:未指定环境的 `dx test` 或 `dx build` 不会自动选择 test 或 production。
|
|
72
|
+
|
|
73
|
+
文件缺失跳过,读取失败则停止;只修改传给应用的子进程环境。dotenv 负责引号、注释和多行值,dotenv-expand 按其语法展开同层已定义变量、前层和调用者变量。迁移旧手写解析或 shell source 时,应使用非敏感样例复核 `$`、引号、转义及依赖顺序,不能当作 shell 脚本执行。
|
|
74
|
+
|
|
75
|
+
不加载通用 `.env` / `.env.local`、应用子目录文件或 `dx/config/env-layers.json`。`DX_CONFIG_DIR` 和顶层 `--config-dir` 不再选择工程或配置。选择环境的标志保留在 argv;`--` 后的标志只属于应用参数。
|
|
76
|
+
|
|
77
|
+
## setup 的公共步骤
|
|
78
|
+
|
|
79
|
+
必须先有合法 `dx/scripts/setup`。入口检查通过后,顺序为复制 → 环境加载 → 应用脚本。
|
|
80
|
+
|
|
81
|
+
- 当前是 linked worktree 时,从 Git 登记的主工作目录递归复制所有以 `.local` 结尾的普通文件,含隐藏与被 Git 忽略的文件,按相对路径写入当前 Git worktree 根并保留文件权限。
|
|
82
|
+
- 跳过已经存在的文件、目录和链接;不覆盖、不更新已有副本,不会在每次 start/build 时同步。
|
|
83
|
+
- 跳过源符号链接、`.git` 元数据和嵌套 worktree;目标父路径必须是实际目录。失败停止应用 setup;已成功复制的文件保留,修复后可再次执行。
|
|
84
|
+
- 主工作目录(含从其子目录调用)、非 Git 工程、bare 仓库下没有主 checkout 的 worktree 不复制。Git 不可用会报错。
|
|
85
|
+
- 项目根若是 Git 根的子目录,复制目标仍是 Git worktree 根,环境加载位置仍是项目根。
|
|
86
|
+
|
|
87
|
+
复制 `.env.local` 不代表会加载它;加载始终只认选定环境的两层文件。新 clone 不共享另一个 clone 的本地文件,也不会自动向远端下载凭据。
|
|
88
|
+
|
|
89
|
+
## 进程与操作责任
|
|
90
|
+
|
|
91
|
+
argv 逐项传递,空字符串、引号、空格、`--` 保留;dx 不拼接 shell 字符串。stdin/stdout/stderr 直接继承,应用退出码保留。
|
|
92
|
+
|
|
93
|
+
脚本保持前台终端;dx 转发 SIGINT/SIGTERM,并保留应用最终信号或退出码。终端 Ctrl-C 可能与转发同时到达,应用应幂等清理自己启动的进程。dx 不监督任意后代或后台服务。
|
|
94
|
+
|
|
95
|
+
单进程 Shell 包装优先使用 `exec`。多服务启动、端口冲突、工具版本、秘密校验、数据库确认和部署恢复均由应用完成;没有通用 `--yes`、`--dry-run` 或自动修复能力。
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# 从 0.1.x 迁移
|
|
2
|
+
|
|
3
|
+
仅用于已有旧版调用的项目。0.2.0 起采用硬切换,接入使用 >=0.2.0 的实际已核验版本:旧命令表和内部 runner 不再执行,迁移的目标是把项目实际需要的行为放入应用脚本,而非重建旧 dx。
|
|
4
|
+
|
|
5
|
+
## 先盘点,再替换
|
|
6
|
+
|
|
7
|
+
检查项目真实使用的 `dx/config/commands.json`、环境层/策略配置、包脚本、CI、容器入口、Nx 等工具目标和项目已有实现。只记录环境文件路径与变量名,避免将秘密值复制进报告。旧版本实现只有在行为无法由项目源码解释时才按实际版本查证。
|
|
8
|
+
|
|
9
|
+
建立一张迁移表,每项包含:旧入口与调用者、实际执行内容、环境、顺序/并发关系、安全条件、新入口/实现文件、验证方式与结果。不能仅把旧命令名改成新命令名;同一个 `dx build admin` 在新版本下也需要实际的 build 文件。
|
|
10
|
+
|
|
11
|
+
## 旧能力的去向
|
|
12
|
+
|
|
13
|
+
| 旧依赖或配置 | 新脚本入口应做什么 |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| commands.json 的 command、嵌套子命令和环境分支 | 对应顶层 dx/scripts 文件,内部自行解析目标与子命令,根据 APP_ENV 调用真实实现 |
|
|
16
|
+
| concurrent、commands 引用、all/development 聚合 | 在项目脚本中明确任务成员、顺序/并发、失败传播与退出收尾 |
|
|
17
|
+
| internal: pm2-stack、backend-artifact-deploy 等 | 直接使用项目工具完成原先需要的流程;不能保留 internal 字段期待 dx 执行 |
|
|
18
|
+
| app、目标别名、自动推断目录、requiresPath/fileCommand | 在项目脚本验证目标和路径并按 argv 调用;旧占位符替换不再发生 |
|
|
19
|
+
| env-layers.json、自定义环境路径、{app} 层 | 迁到标准两层,或由应用明确加载额外文件;通用 .env 和 .env.local 不参与 dx 加载 |
|
|
20
|
+
| env-policy、requiredVars、占位符检查、dangerous/确认 | 由项目入口执行必要检查与确认;包括 allowRoot/allowSubdirGlobs 等布局规则,详见适配回归检查 |
|
|
21
|
+
| ports、自动终止服务、重试、Prisma 自动生成 | 将必要准备放入 setup 或具体应用流程;启动失败不再由 dx 自动修复 |
|
|
22
|
+
| Next/Nx 构建识别、强制 NODE_ENV、轮询变量 | 核对项目工具要求,在项目实现中显式设置;不要假定 dx 仍设置 NX_DAEMON 等变量 |
|
|
23
|
+
| SDK 构建、制品上传、Vercel、回滚、版本注入 | 项目维护自己的构建/发布脚本和故障处理;dx 不再提供这些实现 |
|
|
24
|
+
| dx-with-version-env、私有 lib import、旧 bin 路径 | 改成项目自己的实现及公开 dx 脚本入口,检查 package scripts、CI 和容器调用点 |
|
|
25
|
+
| dx install、lint、clean、cache 等旧命令 | 按项目需要保留为自定义脚本,或把其调用者改成实际工具;标准安装准备可归入 setup |
|
|
26
|
+
| --config-dir、DX_CONFIG_DIR、自定义根定位 | 在目标工程建立 dx/scripts 标记,调整调用 cwd;旧配置目录不再定义工程 |
|
|
27
|
+
| 技能分发 | skills 与 dx initial 仍保留。不要把 initial 删除或误改为项目 setup |
|
|
28
|
+
|
|
29
|
+
## 实施顺序
|
|
30
|
+
|
|
31
|
+
1. 保留旧实现证据,完成迁移表。只清理已确认没有消费者的旧功能;需求不明确但仍被 CI 使用的行为先保留在项目侧。
|
|
32
|
+
2. 创建必需的应用脚本及内部实现。使用实际工具命令,避免复制整套旧 dx 私有运行时。每条分支有成功、失败及参数处理行为;项目帮助应在业务操作前处理。
|
|
33
|
+
3. 整理环境。原先的普通环境变量优先级、APP_ENV/NODE_ENV 关系、构建和测试环境逐项复核;以随技能的 [当前契约](dx-0.2-contract.md) 为准。已有 dotenv 包若仍被应用其他模块使用,应保留。
|
|
34
|
+
4. 更新安装策略与调用者,进行本地/隔离验收。CI 与本地采用一致的版本策略(如全局 latest、最低 >=0.2.0),记录各自实际版本,保证创建脚本时的可执行权限入库。仅设置 CI secret 不足以证明未被文件同名值覆盖。
|
|
35
|
+
5. 消费者和验证均切换后,删除无人使用的旧 dx 配置、包装和依赖,更新文档。保留 Prisma schema、PM2 ecosystem、Nx 配置等仍被项目脚本使用的工具文件。
|
|
36
|
+
|
|
37
|
+
## 容易漏掉的行为
|
|
38
|
+
|
|
39
|
+
- `dx build admin --prod` 中的 --prod 仍进入 build 的 argv。直接 `exec nx build "$@"` 可能把 dx 标志误传给 Nx;在项目解析层消费环境标志,正确处理 `--` 边界。
|
|
40
|
+
- `.env.<环境>.local` 中已有值不会被基础 setup 更新;旧 worktree 需要同步新增配置时明确处理缺项,不能通过再次 setup 假定全部刷新。
|
|
41
|
+
- 缺少环境文件不会让 dx 自行阻止数据库或部署。需要的变量、生产目标、不可逆操作和失败恢复须在应用中验证;不能删除原确认条件后裸调用工具。
|
|
42
|
+
- `start stack` 不再隐含 PM2 重置或端口清理。启动哪些服务、是否清理冲突端口、如何退出由项目确定。
|
|
43
|
+
- 测试文件参数不再由 dx 的 fileCommand 模板转换;验证文件和目录范围都传给了正确测试目标。
|
|
44
|
+
- 新的 NODE_ENV 映射与命令名无关。旧项目若依赖“build 一定 production”或“test 一定 test”,调整调用参数或项目工具逻辑并测试。
|
|
45
|
+
|
|
46
|
+
## 完成条件
|
|
47
|
+
|
|
48
|
+
按 [适配回归检查](adoption-regressions.md) 验证迁移涉及的分支,特别是测试层独立性、构建产物、环境布局和后代进程回收。
|
|
49
|
+
|
|
50
|
+
迁移表中每个实际使用的旧能力都已实现、替换或在用户授权下明确取消;无未解释的旧私有接口与配置消费者;根目录、子目录、fresh clone/worktree 和 CI 的安装与调用方式明确。报告实际验证结果,不能把假脚本返回成功或未执行的部署写成迁移完成。
|