setup-ts-deep-modules
在 TypeScript 仓库中接入 dependency-cruiser,使每个 package 成为 deep module:实现隐藏在子目录中,只能通过根目录的 entry-point files 访问。由用户调用。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
在 TypeScript 仓库中接入 dependency-cruiser,使每个 package 成为 deep module:实现隐藏在子目录中,只能通过根目录的 entry-point files 访问。由用户调用。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
使用并行 sub-agents 为一个 module 生成多套差异显著的 interface 设计。适用于用户希望设计 API、探索 interface 选项、比较 module 形态,或提到“design it twice”的场景。
运行交互式 QA session:用户通过对话报告 bugs 或 issues,agent 随后创建 GitHub issues;同时在后台探索 codebase,获取上下文和 domain language。适用于用户希望报告 bugs、开展 QA、通过对话创建 issues,或提到“QA session”的场景。
通过用户访谈创建一份由微小 commits 组成的详细 refactor plan,并将其提交为 GitHub issue。适用于用户希望规划 refactor、创建 refactoring RFC,或将 refactor 拆分为安全的增量步骤。
从当前对话中提取一份 DDD 风格的 ubiquitous language glossary,标出歧义并提出规范术语,保存到 UBIQUITOUS_LANGUAGE.md。适用于用户希望定义 domain terms、建立 glossary、收紧术语、创建 ubiquitous language,或提到“domain model”或“DDD”的场景。
询问当前情境适合使用哪个 Skill 或工作流。本 Skill 是仓库内其他 Skills 的路由入口。
从用户指定的固定点(commit、branch、tag 或 merge-base)开始,从两个维度审查代码变更:Standards 检查代码是否遵守仓库记录的编码规范,Spec 检查实现是否符合原始 Issue、PRD 或规格。两个审查由并行子 Agent 分别完成,再并列汇报。适用于用户希望审查分支、PR、开发中的改动,或要求“审查自 X 以来的变更”时。
| name | setup-ts-deep-modules |
| description | 在 TypeScript 仓库中接入 dependency-cruiser,使每个 package 成为 deep module:实现隐藏在子目录中,只能通过根目录的 entry-point files 访问。由用户调用。 |
| disable-model-invocation | true |
让仓库中的每个 package 都成为 deep module:用较小的 interface 承载大量 behavior。Package 的公开表面由它的 entry points 构成,也就是 package 根目录下的文件;子目录中的所有内容都保持隐藏。本 skill 会安装 dependency-cruiser,配置只允许通过 entry points 进入 package 的规则,并证明这些规则确实能够拦截违规依赖。
有关 deep module、interface、seam、depth 等词汇,请运行 /codebase-design skill,并在整个过程中使用其中定义的语言。
src/packages/
<name>/
index.ts ← 一个公开 entry point,外部代码从这里导入
client.ts ← 另一个 entry point;一个 package 可以公开多个
lib/ ← implementation:对外隐藏,内部文件可自由相互导入
tests/ ← 同位置 tests 与 fixtures;位于子目录,因此属于私有内容
公开表面是 package 的根目录文件,不限定为某一个 index.ts。按照约定,implementation 放在 lib/,tests 放在 tests/,让每个 package 保持相同的双目录结构。不过规则本身更加通用:任何子目录中的任何内容都属于 private,因此新增目录时无须扩展配置。
四条规则全部使用 error:
<pkg>/tests/ 下的文件可以导入任何 package 的 entry points,以及自身 tests/ 目录中的 fixtures;不得导入任何 package 子目录中的 internals,包括自身 package 的 internals。允许跨 package 的 integration tests,禁止 deep imports。Entry points,不是单一 barrel。 公开表面由所有根目录文件构成,因此 package 可以公开多个小型 entry points(index.ts、client.ts、server.ts),无须把所有内容汇总到一个巨大的 index.ts。不鼓励使用 barrel file 重新导出整个子树;保持 entry points 精简,把 implementation 隐藏在子目录中。
Layering(哪些 packages 可以依赖哪些 packages)属于另一项独立问题。配置文件会留下已注释的占位区域,由当前仓库自行填写。
pnpm-lock.yaml 时使用 pnpm;存在 yarn.lock 时使用 yarn;存在 bun.lockb 时使用 bun;否则使用 npm。下文所有命令都使用检测到的包管理器(pnpm/yarn/npm run/bunx)。src/ 时使用 src/packages,否则使用 packages。仓库已经有另一套明显约定时,先向用户确认。.dependency-cruiser.* 文件。已经存在配置时,不得覆盖;把四条规则和 options 合并进去,并告诉用户新增了哪些内容。完成条件: 已经确定包管理器、packages root,以及是否存在现有配置。
使用检测到的包管理器,将 dependency-cruiser 安装为 devDependency。
完成条件: dependency-cruiser 已出现在 devDependencies 中。
把 dependency-cruiser.config.cjs 复制到仓库根目录,并命名为 .dependency-cruiser.cjs。将 PACKAGES_ROOT 设置为步骤 1 检测到的根目录。规则根据路径深度判断,且不依赖文件扩展名,因此其他部分无须调整。
完成条件: .dependency-cruiser.cjs 已存在,PACKAGES_ROOT 正确,并包含四条 forbidden rules。
lint:boundaries script:depcruise <packages-root>(也可以是 depcruise src)。check / ci / validate script)。不要修改 tsconfig,也不要添加 path aliases。lint:boundaries,并告知用户需要将其纳入 CI。完成条件: lint:boundaries 已存在,并与 typecheck 通过同一个命令运行。
创建并提交 <packages-root>/example/,作为可复制的模板:
index.ts——一个 entry point。导出一个委托给内部文件的函数,让 package 明显具备 depth,而不是 pass-through。lib/impl.ts——位于子目录中的 internal file,由 index.ts 导入,外部无法访问。tests/example.test.ts——只导入 ../index(entry point),并通过公开函数进行断言。告诉用户,该目录是可以复制或删除的起始模板。
完成条件: 示例 package 已存在,通过根目录 entry point 公开 behavior,并把 impl 隐藏在子目录中。
这是整个 skill 的完成标准。无法在违规时失败的配置没有价值。
lint:boundaries。干净的示例必须通过。tests/example.test.ts 中加入 deep import(例如 import { thing } from "../lib/impl")。再次运行 lint:boundaries;它必须因 tests-through-entrypoints 失败。完成条件: 已经亲自观察到一次通过、deep import 导致的一次失败,以及撤销后的再次通过。步骤 2 没有失败时,说明规则未正确接入;修好后才能结束。
在 packages 目录内写入 README.md(<packages-root>/README.md),与它所约束的 packages 放在一起。内容包括:src/packages/<name>/ 结构(根目录为 entry points,lib/ 放 implementation,tests/ 放 tests)、“只通过 package 的 entry points(根目录文件)进行导入”,以及运行 lint:boundaries 的方式。必须明确不鼓励 barrel files:公开多个小型 entry points,不要通过一个 index 重新导出整个子树。文档只需包含可复制的目录片段,以及四条各用一段说明的规则。
随后,从仓库的 agent instructions 文件添加指向该文档的 context pointer:存在 CLAUDE.md 时编辑它,否则编辑 AGENTS.md;两个文件都不存在时创建 AGENTS.md。一行即可,例如:Packages are deep modules — see [src/packages/README.md](./src/packages/README.md) before adding or importing one. 这个指针能让 agent 主动发现边界规则,避免先违规再从报错中得知规则。
完成条件: <packages-root>/README.md 已存在并明确不鼓励 barrels,仓库的 CLAUDE.md/AGENTS.md 已链接到该文档。
$1 反向引用(dependency-cruiser 的 group matching)允许 package 访问自身 internals,同时阻止外部访问。不要把它们展开成每个 package 一套的独立规则。lib/(implementation)和 tests/,但规则没有硬编码这些名称;任何子目录都是 private,因此新增目录无须修改配置。添加 entry point 只需新增根目录文件,不需要 barrel。.cjs(不要使用 .js),确保配置中的 module.exports 在 "type": "module" 仓库中也能工作。