setup-ts-deep-modules:mattpocock/skills 方法论: in-progress/setup-ts-deep-m,适用于工程实践、代码质量与开发流程优化。
setup-ts-deep-modules:mattpocock/skills 方法论: in-progress/setup-ts-deep-m,适用于工程实践、代码质量与开发流程优化。
> 来源: mattpocock/skills (141k stars) — Total TypeScript 创始人 Matt Pocock
> 类目: 实验性
> 原文件: skills/in-progress/setup-ts-deep-modules/SKILL.md
> 模型推荐: gpt-4.1 (代码工程)
Matt Pocock (Total TypeScript, 141k stars) 沉淀下来的"日常代码工程动作"skill 模板。
每一个对应一个具体动作(代码评审 / TDD / 重构 / 文档对齐 / 任务交接),不是工具,是"该怎么干这件事"的工作流模板。
michael 强调"skill 要有相应的指导功能,指导用户使用",所以这里加了下面两节让 Agent 和用户对接。
---
1. 接到任务后先按这个 skill 的检查清单走一遍
2. 清单里如果出现"先做 X 才能做 Y"的红线 → 必须先完成 X
3. 跑完清单后开始动手(改代码 / 写文档 / 评审)
4. 完工前用 `verification-before-completion`(superpowers) 或 `verification` 类 step 自检
5. 任务量大时考虑用 `dispatching-parallel-agents`(superpowers) 或 `wayfinder`(mattpocock) 拆解
1. 告诉 Agent 你要做什么(一句话即可)
2. Agent 跑 skill 清单时不要打断 — 它可能在收集上下文
3. 如果 Agent 主动问你"代码评审要不要安排一个 reviewer"等决策点 → 直接回答
4. 完工后让 Agent 跑一遍自检再交回
5. 整个过程 Agent 自动化,不需要手工介入
---
---
name: setup-ts-deep-modules
description: Wire dependency-cruiser into a TypeScript repo so each package is a deep module — implementation hidden in subfolders, reachable only through its entry-point files. User-invoked.
disable-model-invocation: true
---
Make every package in this repo a **deep module**: a lot of behaviour behind a small interface. A package's public surface is its **entry points** — the files at the package root — and everything in its subfolders is hidden. This skill installs [dependency-cruiser](https://github.com/sverweij/dependency-cruiser) and the rules that make the entry points the only way in, then proves the rules bite.
For the vocabulary (deep module, interface, seam, depth), call the Skill tool with "codebase-design" — use its language throughout.
src/packages/
<name>/
index.ts ← an entry point (public). Import this from outside.
client.ts ← another entry point. Packages may expose SEVERAL.
lib/ ← implementation: hidden from outside, free to import each other.
tests/ ← co-located tests + fixtures (a subfolder, so private).
The public surface is the package's **root files** — not one designated `index.ts`. By convention implementation lives in `lib/` and tests in `tests/`, giving every package the same two-folder shape. The rule itself is general, though: *anything* in *any* subfolder is private, so you never extend the config to add a folder.
Four rules, all `error`:
1. **Entry-point boundary** — code outside a package (app code or another package) may import only that package's entry points (its root files), never anything in its subfolders.
2. **Intra-package freedom** — a package's own files import each other freely.
3. **Tests through the entry points** — files under `<pkg>/tests/` may import any package's entry points and their own `tests/` fixtures, but never any package's subfolder internals (not even their own). Integration tests across packages are fine; deep imports are not.
4. **No cycles** — no dependency cycles.
**Entry points, not a barrel.** Because the public surface is *every* root file, a package can expose several small entry points (`index.ts`, `client.ts`, `server.ts`) instead of funnelling everything through one giant `index.ts`. Barrel files that re-export a whole subtree are discouraged — keep entry points small and hide implementation in subfolders.
Layering (which packages may depend on which) is a *different* concern and is left as a commented stub in the config for this repo to fill in.
**Done when:** package manager, packages root, and existing-config status are all known.
Install `dependency-cruiser` as a devDependency with the detected package manager.
**Done when:** `dependency-cruiser` is in `devDependencies`.
Copy [`dependency-cruiser.config.cjs`](./dependency-cruiser.config.cjs) to the repo root as `.dependency-cruiser.cjs`. Set `PACKAGES_ROOT` to the root detected in step 1. The rules are path-depth based and extension-agnostic, so nothing else needs adapting.
**Done when:** `.dependency-cruiser.cjs` exists with the correct `PACKAGES_ROOT`, and the four forbidden rules are present.
**Done when:** `lint:boundaries` exists and runs as part of the same command as typecheck.
Create a committed `<packages-root>/example/` as a copy-me template:
Tell the user this is a starter template to copy or delete.
**Done when:** the example package exists, exposes its behaviour through a root entry point, and hides `impl` in a subfolder.
This is the completion criterion for the whole skill — a config that doesn't fail on a violation is worthless.
1. Run `lint:boundaries`. It must **pass** on the clean example.
2. Temporarily add a deep import to `tests/example.test.ts` (e.g. `import { thing } from "../lib/impl"`). Run `lint:boundaries` again — it must **fail** with `tests-through-entrypoints`.
3. Revert the deep import. Run once more — it must **pass**.
**Done when:** you have observed a pass, then a fail on the deep import, then a pass again. If step 2 does not fail, the rules are not wired correctly — fix before finishing.
Write a `README.md` **in the packages folder** (`<packages-root>/README.md`) — next to the packages it governs — covering: the `src/packages/<name>/` layout (entry points at the root, `lib/` for implementation, `tests/` for tests), "import only through a package's entry points (its root files)", and how to run `lint:boundaries`. **Discourage barrel files** explicitly — expose several small entry points instead of re-exporting a whole subtree through one index. Keep it to the copy-me snippet plus the four rules in one paragraph each.
Then add a **context pointer** to it from the repo's agent-instructions file — `CLAUDE.md` if present, else `AGENTS.md` (create `AGENTS.md` if neither exists). One line is enough, e.g. `Packages are deep modules — see [src/packages/README.md](./src/packages/README.md) before adding or importing one.` This is what makes an agent discover the boundary rule instead of tripping over it.
**Done when:** `<packages-root>/README.md` exists and discourages barrels, and the repo's `CLAUDE.md`/`AGENTS.md` links to it.
本 skill 专注于setup-ts-deep-,mattpocock/skills 方法论: in-progress/setup-ts-deep-modules。它将相关流程标准化,帮助用户更快拿到可靠结果,减少重复手工操作。
当你需要在setup-ts-deep-modules相关工作中获得稳定、可复用的产出时最适合——无论是单次任务还是纳入日常工作流,都能直接调用。
需要一个具体的项目或任务上下文,最好带有代码仓库或需求文档。
1. 告诉 Agent 你要做什么(一句话即可)
2. Agent 跑 skill 清单时不要打断 — 它可能在收集上下文
3. 如果 Agent 主动问你"代码评审要不要安排一个 reviewer"等决策点 → 直接回答
4. 完工后让 Agent 跑一遍自检再交回
5. 整个过程 Agent 自动化,不需要手工介入
---
本 skill 专注于setup-ts-deep-,mattpocock/skills 方法论: in-progress/setup-ts-deep-modules。它将相关流程标准化,帮助用户更快拿到可靠结果,减少重复手工操作。
当你需要在setup-ts-deep-modules相关工作中获得稳定、可复用的产出时最适合——无论是单次任务还是纳入日常工作流,都能直接调用。
需要一个具体的项目或任务上下文,最好带有代码仓库或需求文档。