setup-python-deep-modules
Wire import-linter into a Python repo so each package is a deep module, with implementation hidden in subfolders and reachable only through its entry-point…
Skill by fderuiter
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/fderuiter-setup-python-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.
About
Reviews
Write a reviewNo 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. 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-python-deep-modules
What's inside
- Skill name
setup-python-deep-modules- Description
- Wire import-linter into a Python repo so each package is a deep module, with implementation hidden in subfolders and reachable only through its entry-point files. User-invoked.
- License
- MIT
- Instructions
- 141 lines in SKILL.md · view on GitHub
Files (2)
- SKILL.md
- importlinter.config.ini
SKILL.md (first lines)
# Setup Python Deep Modules
Make every package in this Python repo a **deep module**: a lot of behaviour behind a small interface. A package's public surface is its **entry points** (root modules such as `__init__.py` and root files), while everything in its subfolders (such as `_lib/` or `lib/`) is hidden. This skill installs [import-linter](https://import-linter.readthedocs.io/) and the contracts that make entry points the only way in, then proves the rules bite.
For vocabulary (deep module, interface, seam, depth), call the Skill tool with "codebase-design" and use its language throughout.
## The shape this enforces
```
src/packages/
<name>/
__init__.py ← primary entry point (public). Import this from outside.
client.py ← additional entry point (public). Packages may expose several.
_lib/ ← implementation: hidden from outside, free to import each other.
tests/ ← co-located tests + fixtures (private subfolder).
```
The public surface is the package's **root files**, not just one `__init__.py`. By convention implementation lives in `_lib/` (or `lib/`) and tests in `tests/`, giving every package the same clean shape. The rule itself is path-depth based: anything in subfolders is private, so you never extend the config to add a folder.
Five contracts, all enforced as errors:
1. **Entry-point boundary from app**: code outside a package (app code or root services) may import only that package's entry points (root modules), never anything in its subfolders.
2. **Entry-point boundary across packages**: a package's own internal files import each other freely, but may reach other packages only through their entry points, never their subfolder internals.
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. **Tests folder is private**: files under `<pkg>/tests/` are reachable only from test files; application code may not import test fixtures or helpers.
5. **No cycles**: no circular dependencies across packages.
**Entry points, not giant monolithic files.** Because the public surface is *every* root file, a package can expose several small entry points (`__init__.py`, `client.py`, `models.py`) instead of funnelling everything into one giant file. Keep entry points lean and hide complex implementation in `_lib/`.
## Steps
### 1. Detect the environment
- **Package manager and environment**:
- `uv.lock` or `pyproject.toml` with `[tool.uv]` → `uv` (`uv add --dev import-linter`, `uv run lint-imports`).
- `poetry.lock` → `poetry` (`poetry add --group dev import-linter`, `poetry run lint-imports`).
- `pdm.lock` → `pdm` (`pdm add -d import-linter`, `pdm run lint-imports`).
- `Pipfile.lock` → `pipenv`.
- Fallback: standard `pip` / `venv` (`pip install import-linter`).
- **Packages root**:
- If `src/packages/` exists use `src/packages/`, else `packages/` or `src/`. Confirm the choice with the user if the repo has an established convention.
- **Existing config**:
- Check for existing `[tool.importlinter]` in `pyproject.toml` or a `.importlinter` file. If present, do **not** overwrite; merge the five contracts in.
- **Upstream verification**:
- When encountering non-standard package layouts or workspace monorepos, use `search_web` and `read_url_content` to inspect upstream `import-linter` docs for custom contract syntax.
**Done when:** package manager, packages root, config location, and existing contract status are all known.
### 2. Install import-linter
Install `import-linter` as a development dependency using the detected package manager.
**Done when:** `import-linter` is installed and executable via `lint-imports --version`.
### 3. Write the config
If `pyproject.toml` exists, add the `[tool.importlinter]` configuration:
```toml
[tool.importlinter]
root_packages = ["packages"]
[[tool.importlinter.contracts]]
name = "Entry point boundary from app"
type = "forbidden"
source_modules = ["app"]
forbidden_modules = ["packages.*._lib", "packages.*.lib"]
[[tool.importlinter.contracts]]
name = "Entry point boundary across packages"
type = "forbidden"
source_modules = ["packages"]
forbidden_modules = ["packages.*._lib", "packages.*.lib"]
ignore_imports = [
"packages.$1._lib -> packages.$1._lib",
"packages.$1.lib -> packages.$1.lib"
]
[[tool.importlinter.contracts]]
name = "Tests through entry points"
type = "forbidden"
source_modules = ["packages.*.tests"]
forbidden_modules = ["packages.*._lib", "packages.*.lib"]
[[tool.importlinter.contracts]]
name = "Tests folder is private"
type = "forbidden"
source_modules = ["app", "packages"]
forbidden_modules = ["packages.*.tests"]
ignore_imports = ["packages.$1.tests -> packages.$1.tests"]
[[tool.importlinter.contracts]]
name = "No cycles"
type = "independence"
modules = ["packages"]
```
If the repo prefers standalone configuration, copy [`importlinter.config.ini`](./importlinter.config.ini) to `.importlinter`.
**Done when:** configuration exists with the correct `root_packages` and all five architectural contracts.
### 4. Wire it into the checks
- Add a `lint:boundaries` or `lint-imports` task in `pyproject.toml` / `Makefile` / `tox.ini` / task runner.
- Fold it into the repo's umbrella check command (e.g. `check`, `lint`, or `ci`).
- If there is no umbrella script, add `lint-imports` to CI workflows.
**Done when:** `lint-imports` runs as part of standard developer checks and CI.
### 5. Scaffold the example package
Create `<packages-root>/example/` as a starter template:
- `__init__.py`: Public entry point. Expose one function that delegates to an internal module (demonstrating that the package is visibly deep).
- `_lib/impl.py`: Internal implementation file in a subfolder, imported by `__init__.py`, hidden from external code.
- `tests/test_example.py`: Tests importing only `from packages.example import ...`, asserting against the public interface.
**Done when:** the example package exists, exposes its behavior through the root module, and hides implementation in `_lib/`.From fderuiter/agy-skills, MIT.
More from fderuiter/agy-skills
- 0.547score
retro
fderuiter
Analyze past Antigravity session transcripts (transcript.jsonl) to identify friction and extract systemic environment improvements: navigation pointers…
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
implement-spec
fderuiter
User-invoked.
SkillBFreshness: B★ 1Claude Code +9 - 0.544score
setup-mcp
fderuiter
Configure Model Context Protocol (MCP) servers in .agents/mcp_config.json (project-level) or ~/.gemini/config/mcp_config.json (global).
SkillBFreshness: B★ 1Claude Code +9 - 0.540score
new-skill
fderuiter
User-invoked.
SkillBFreshness: B★ 1Claude Code +9 - 0.527score
code-review
fderuiter
Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes: Standards (does the code follow this repo's documented coding…
SkillBFreshness: B★ 1Claude Code +9 - 0.527score
diagnosing-bugs
fderuiter
Diagnosis loop for hard bugs and performance regressions.
SkillBFreshness: B★ 1Claude Code +9 - 0.522score
prototype
fderuiter
Build a throwaway prototype to answer a design question.
SkillBFreshness: B★ 1Claude Code +9 - 0.522score
codebase-design
fderuiter
Shared vocabulary for designing deep modules.
SkillBFreshness: B★ 1Claude Code +9 - 0.522score
domain-modeling
fderuiter
Build and sharpen a project's domain model.
SkillBFreshness: B★ 1Claude Code +9 - 0.519score
to-spec
fderuiter
Turn the current conversation into a spec and publish it to the project issue tracker: no interview, just synthesis of what you've already discussed.
SkillBFreshness: B★ 1Claude Code +9 - 0.519score
improve-codebase-architecture
fderuiter
Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
SkillBFreshness: B★ 1Claude Code +9 - 0.519score
setup-agy-skills
fderuiter
Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout.
SkillBFreshness: B★ 1Claude Code +9
Signals
- Stars
- 1
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Aug 28, 2026 (2 months ago)
- Last release
- Aug 28, 2026 (2 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/fderuiter/agy-skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from fderuiter
- 0.547score
implement-spec
fderuiter
User-invoked.
SkillBFreshness: B★ 1Claude Code +9 - 0.547score
retro
fderuiter
Analyze past Antigravity session transcripts (transcript.jsonl) to identify friction and extract systemic environment improvements: navigation pointers…
SkillBFreshness: B★ 1Claude Code +9 - 0.544score
setup-mcp
fderuiter
Configure Model Context Protocol (MCP) servers in .agents/mcp_config.json (project-level) or ~/.gemini/config/mcp_config.json (global).
SkillBFreshness: B★ 1Claude Code +9 - 0.540score
new-skill
fderuiter
User-invoked.
SkillBFreshness: B★ 1Claude Code +9 - 0.527score
code-review
fderuiter
Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes: Standards (does the code follow this repo's documented coding…
SkillBFreshness: B★ 1Claude Code +9 - 0.527score
diagnosing-bugs
fderuiter
Diagnosis loop for hard bugs and performance regressions.
SkillBFreshness: B★ 1Claude Code +9
Cite this page
setup-python-deep-modules skill. Agent Mart. https://agentmart.dev/skills/fderuiter-setup-python-deep-modules (last updated 2026-10-24)