Skip to content
Agentmart
Submit a tool

setup-ts-deep-modules

Wire dependency-cruiser into a TypeScript repo so each package is a deep module — implementation hidden in subfolders, reachable only through its entry-point…

Skill by leandrocfe

IndexedMIT★ 40
Write a review

Chalk Labs

Need help deploying setup-ts-deep-modules?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/leandrocfe-setup-ts-deep-modules

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

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.

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/setup-ts-deep-modules

What's inside

Skill 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.
License
MIT
Instructions
98 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Files (3)

  • SKILL.md
  • openai.yaml · agents/
  • dependency-cruiser.config.cjs

SKILL.md (first lines)

# Setup TS Deep Modules

Faça de cada package deste repo um **módulo profundo** (deep module): muito comportamento atrás de uma interface pequena. A superfície pública de um package são seus **entry points** — os arquivos na raiz do package — e tudo nas subpastas fica escondido. Esta skill instala o [dependency-cruiser](https://github.com/sverweij/dependency-cruiser) e as regras que tornam os entry points o único caminho de entrada, depois prova que as regras mordem.

Para o vocabulário (deep module, interface, seam, profundidade), rode a skill `/codebase-design` — use a linguagem dela em todo o processo.

## O formato que isto impõe

```
src/packages/
  <name>/
    index.ts        ← um entry point (público). Importe este de fora.
    client.ts       ← outro entry point. Packages podem expor VÁRIOS.
    lib/            ← implementação: escondida de fora, livre pra importar entre si.
    tests/          ← testes co-localizados + fixtures (uma subpasta, então privada).
```

A superfície pública são os **arquivos de raiz** do package — não um `index.ts` designado. Por convenção a implementação vive em `lib/` e os testes em `tests/`, dando a todo package o mesmo formato de duas pastas. A regra em si é geral, porém: *qualquer coisa* em *qualquer* subpasta é privada, então você nunca estende a config pra adicionar uma pasta.

Quatro regras, todas `error`:

1. **Entry-point boundary** — código fora de um package (código da app ou outro package) só pode importar os entry points daquele package (seus arquivos de raiz), nunca nada em suas subpastas.
2. **Intra-package freedom** — os arquivos do próprio package se importam livremente.
3. **Tests through the entry points** — arquivos sob `<pkg>/tests/` podem importar os entry points de qualquer package e as fixtures do próprio `tests/`, mas nunca os internos de subpasta de nenhum package (nem os seus próprios). Testes de integração entre packages são ok; deep imports não.
4. **No cycles** — nenhum ciclo de dependência.

**Entry points, não um barrel.** Porque a superfície pública é *todo* arquivo de raiz, um package pode expor vários entry points pequenos (`index.ts`, `client.ts`, `server.ts`) em vez de afunilar tudo por um `index.ts` gigante. Barrel files que re-exportam uma subárvore inteira são desencorajados — mantenha os entry points pequenos e esconda a implementação em subpastas.

Layering (quais packages podem depender de quais) é uma preocupação *diferente* e fica como stub comentado na config, pra este repo preencher.

## Passos

### 1. Detectar o ambiente

- **Package manager** — `pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `bun.lockb` → bun, senão npm. Use-o em todo comando abaixo (`pnpm`/`yarn`/`npm run`/`bunx`).
- **Raiz dos packages** — se `src/` existe use `src/packages`, senão `packages`. Confirme a escolha com o usuário se o repo já tiver outra convenção óbvia.
- **Config existente** — cheque por um arquivo `.dependency-cruiser.*`. Se existir, **não** sobrescreva: mescle as quatro regras e as opções, e diga ao usuário o que você adicionou.

**Pronto quando:** package manager, raiz dos packages e status de config existente estiverem todos conhecidos.

### 2. Instalar o dependency-cruiser

Instale `dependency-cruiser` como devDependency com o package manager detectado.

**Pronto quando:** `dependency-cruiser` estiver em `devDependencies`.

### 3. Escrever a config

Copie [`dependency-cruiser.config.cjs`](./dependency-cruiser.config.cjs) para a raiz do repo como `.dependency-cruiser.cjs`. Ajuste `PACKAGES_ROOT` para a raiz detectada no passo 1. As regras são baseadas em profundidade de path e agnósticas de extensão, então nada mais precisa ser adaptado.

**Pronto quando:** `.dependency-cruiser.cjs` existir com o `PACKAGES_ROOT` correto, e as quatro regras `forbidden` estiverem presentes.

### 4. Ligar nos checks

- Adicione um script `lint:boundaries`: `depcruise <packages-root>` (ou `depcruise src`).
- Encaixe-o no comando guarda-chuva do repo — aquele que já roda typecheck (ex.: um script `check` / `ci` / `validate`). **Não** toque no `tsconfig` nem adicione path aliases.
- Se não houver script guarda-chuva, adicione `lint:boundaries` e diga ao usuário pra incluí-lo no CI.

**Pronto quando:** `lint:boundaries` existir e rodar como parte do mesmo comando que o typecheck.

### 5. Fazer o scaffold do package de exemplo

Crie um `<packages-root>/example/` commitado como template copie-me:

- `index.ts` — um entry point. Exporte uma função que delega para um arquivo interno (pra o package ser visivelmente *profundo*, não um pass-through).
- `lib/impl.ts` — um arquivo interno numa **subpasta**, importado por `index.ts`, inalcançável de fora.
- `tests/example.test.ts` — importa **só** `../index` (um entry point), e faz asserções contra a função pública.

Diga ao usuário que isto é um template inicial pra copiar ou deletar.

**Pronto quando:** o package de exemplo existir, expor seu comportamento por um entry point de raiz, e esconder `impl` numa subpasta.

### 6. Provar que as regras mordem

Este é o critério de conclusão da skill inteira — uma config que não falha numa violação não vale nada.

1. Rode `lint:boundaries`. Deve **passar** no exemplo limpo.
2. Adicione temporariamente um deep import a `tests/example.test.ts` (ex.: `import { thing } from "../lib/impl"`). Rode `lint:boundaries` de novo — deve **falhar** com `tests-through-entrypoints`.
3. Reverta o deep import. Rode mais uma vez — deve **passar**.

**Pronto quando:** você tiver observado um pass, depois um fail no deep import, depois um pass de novo. Se o passo 2 não falhar, as regras não estão ligadas corretamente — corrija antes de terminar.

### 7. Documentar a convenção

Escreva um `README.md` **na pasta dos packages** (`<packages-root>/README.md`) — ao lado dos packages que ele governa — cobrindo: o layout `src/packages/<name>/` (entry points na raiz, `lib/` pra implementação, `tests/` pra testes), "importe só pelos entry points de um package (seus arquivos de raiz)", e como rodar `lint:boundaries`. **Desencoraje barrel files** explicitamente — exponha vários entry points pequenos em vez de re-exportar uma subárvore inteira por um index. Mantenha no snippet copie-me mais as quatro regras em um parágrafo cada.

Depois adicione um **context pointer** a ele a partir do arquivo de instruções de agente do repo — `CLAUDE.md` se presente, senão `AGENTS.md` (crie `AGENTS.md` se nenhum existir). Uma linha basta, ex.: `Packages são deep modules — veja [src/packages/README.md](./src/packages/README.md) antes de adicionar ou importar um.` Isto é o que faz um agente descobrir a regra de boundary em vez de tropeçar nela.

**Pronto quando:** `<packages-root>/README.md` existir e desencorajar barrels, e o `CLAUDE.md`/`AGENTS.md` do repo linkar pra ele.

## Notes

- As back-references `$1` da config (group matching do dependency-cruiser) são o que deixa um package alcançar os próprios internos enquanto os de fora não podem — não achate isso em regras separadas por package.
- Público vs privado é decidido por **profundidade**: os arquivos de raiz de um package são entry points; qualquer coisa numa subpasta é privada. As subpastas convencionais são `lib/` (implementação) e `tests/`, mas a regra não as hardcoda — qualquer subpasta é privada, então uma pasta nova nunca precisa de mudança na config. Adicionar um entry point é só adicionar um arquivo de raiz — sem barrel.
- Packages são **flat**: um nível de filhos imediatos sob a raiz. Os internos de um package podem aninhar quão fundo você quiser; um package não pode conter outro package.
- Use `.cjs` (não `.js`) pra o `module.exports` da config funcionar mesmo em repos `"type": "module"`.

From leandrocfe/skills, MIT.

More from leandrocfe/skills

Signals

Stars
40
Forks
2
Open issues
1
Last commit (this folder)
Aug 10, 2026 (2 months ago)
Last release
Aug 10, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

Same skill elsewhere

Copies of this SKILL.md published by others; search shows only one of them.

More from leandrocfe

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get setup-ts-deep-modules running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying setup-ts-deep-modules?

CallGet help
Cite this page

setup-ts-deep-modules skill. Agent Mart. https://agentmart.dev/skills/leandrocfe-setup-ts-deep-modules (last updated 2026-10-24)