Py Rig
mudrii/hermesd
A skill your agent uses when building, reviewing, or refactoring Python code that requires strong maintainability discipline: SRP, DRY, OCP, explicit dependency injection, TDD/ATDD workflow, strict…
Python design patterns for CLI scripts and utilities — type-first development, deep modules, complexity management, and red flags.
$ npx skills add mindfold-ai/Trellis --skill python-design -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mindfold-ai/Trellis python-design --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/python-design .claude/skills/python-design && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "python-design" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/python-design into .claude/skills/python-design/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-design", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/python-designType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mindfold-ai/Trellis --skill python-design -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mindfold-ai/Trellis python-design --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/python-design .agents/skills/python-design && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "python-design" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/python-design into .agents/skills/python-design/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-design", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mindfold-ai/Trellis --skill python-design -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mindfold-ai/Trellis python-design --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/python-design .cursor/skills/python-design && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "python-design" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/python-design into .cursor/skills/python-design/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-design", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mindfold-ai/Trellis.git --path .agents/skills/python-design--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mindfold-ai/Trellis --skill python-design -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mindfold-ai/Trellis python-design --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/python-design .gemini/skills/python-design && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "python-design" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/python-design into .gemini/skills/python-design/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-design", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mindfold-ai/Trellis python-designInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mindfold-ai/Trellis --skill python-design -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/python-design .github/skills/python-design && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "python-design" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/python-design into .github/skills/python-design/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-design", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mindfold-ai/Trellis --skill python-design -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mindfold-ai/Trellis python-design --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/python-design .opencode/skills/python-design && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "python-design" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/python-design into .opencode/skills/python-design/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "python-design", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
python-designPython design patterns for CLI scripts and utilities — type-first development, deep modules, complexity management, and red flags.
Python Design is an agent skill from mindfold-ai/Trellis. Python design patterns for CLI scripts and utilities — type-first development, deep modules, complexity management, and red flags. Use when reading, writing, reviewing, or refactoring Python files, especially in .trellis/scripts/ or any CLI/scripting context. Also activate when planning module structure, deciding where to put new code, or doing code review.
Its SKILL.md is about 4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Design patterns and Refactoring. It works with Python. The repository describes itself as: The best agent harness. The licence is AGPL-3.0.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit f089cb3. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Python Design loads about 4k tokens when it runs. Until then it costs about 93 tokens; SKILL.md has 1,140 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from mindfold-ai/Trellis at commit f089cb3, republished under its AGPL-3.0 licence (© mindfold-ai). 1,140 words, ~3,951 tokens.
.claude/skills/python-design/SKILL.md (or your agent's skills folder).Design patterns and principles for writing maintainable Python CLI tools and utilities. Based on A Philosophy of Software Design (Ousterhout), adapted for scripting contexts.
The central challenge is managing complexity, not adding features.
Complexity is anything that makes code hard to understand or modify. It has three symptoms:
Complexity is incremental. It accumulates through hundreds of small decisions, not one catastrophic mistake. Therefore: sweat the small stuff.
A module's value is the ratio of functionality hidden vs. interface exposed.
Deep module (good): Shallow module (bad):
┌──────────┐ ┌──────────────────────────┐
│ simple │ │ complex interface │
│ interface│ │ many params, many methods │
├──────────┤ ├──────────────────────────┤
│ │ │ │
│ rich │ │ thin implementation │
│ impl │ │ │
│ │ └──────────────────────────┘
│ │
└──────────┘Practical test: If a caller must understand how the module works internally to use it correctly, the module is too shallow.
# Shallow — caller must know JSON structure, file paths, error handling
def _read_json_file(path: Path) -> dict:
with open(path, encoding="utf-8") as f:
return json.load(f)
# Every caller does this independently:
task_path = tasks_dir / name / "task.json"
data = _read_json_file(task_path)
title = data.get("title") or data.get("name", "")
status = data.get("status", "planning")
assignee = data.get("assignee", "")# Deep — caller gets what they need, module hides JSON/path/parsing
@dataclass(frozen=True)
class TaskInfo:
name: str
title: str
status: str
assignee: str
priority: str
directory: Path
def load_task(tasks_dir: Path, name: str) -> TaskInfo | None:
"""Load task by directory name. Returns None if not found."""
...
def list_active_tasks(tasks_dir: Path) -> list[TaskInfo]:
"""List all non-archived tasks, sorted by priority."""
...The deep version absorbs complexity: JSON parsing, field defaults, directory scanning, archive filtering. Callers just work with typed data.
Types define contracts before implementation. This workflow catches design problems early:
from dataclasses import dataclass
from typing import Literal
@dataclass(frozen=True)
class AgentRecord:
agent_id: str
task_name: str
worktree_path: Path
platform: Literal["Codex", "codex", "cursor"]
status: Literal["running", "done", "failed"]
branch: strFrozen dataclasses are immutable — no accidental mutation, safe to pass around.
When the data comes from a file (task.json, config.yaml, registry.json), use TypedDict to document the expected shape:
from typing import TypedDict, Required, NotRequired
class TaskData(TypedDict):
title: Required[str]
status: Required[str]
assignee: NotRequired[str]
priority: NotRequired[str]
parent: NotRequired[str]
children: NotRequired[list[str]]This eliminates scattered .get("field", default) calls — the shape is documented once.
When two strings mean different things, make the type system enforce it:
from typing import NewType
TaskName = NewType("TaskName", str) # directory name like "03-10-v040"
BranchName = NewType("BranchName", str) # git branch like "feat/v0.4.0"
def create_branch(task: TaskName) -> BranchName:
return BranchName(f"task/{task}")When an entity can be in distinct states with different data:
@dataclass(frozen=True)
class Pending:
status: Literal["pending"] = "pending"
@dataclass(frozen=True)
class Running:
status: Literal["running"] = "running"
pid: int
worktree: Path
@dataclass(frozen=True)
class Completed:
status: Literal["completed"] = "completed"
branch: str
commit: str
AgentState = Pending | Running | Completed
def handle(state: AgentState) -> None:
match state:
case Running(pid=pid, worktree=wt):
check_process(pid)
case Completed(branch=br):
create_pr(br)
case Pending():
passThe type checker ensures every state is handled. No more if data.get("status") == "running" with forgotten branches.
Each module should encapsulate design decisions. When the same knowledge appears in multiple modules, information has leaked.
JSON schema knowledge scattered everywhere:
# BAD — 9 files all know how to iterate tasks and parse task.json
for d in sorted(tasks_dir.iterdir()):
if d.name == "archive" or not d.is_dir():
continue
task_json = d / "task.json"
if task_json.exists():
data = json.loads(task_json.read_text())
title = data.get("title") or data.get("name", "")
...# GOOD — one module owns task iteration
# common/tasks.py
def iter_active_tasks(tasks_dir: Path) -> Iterator[TaskInfo]:
"""Yield all active (non-archived) tasks."""
for d in sorted(tasks_dir.iterdir()):
if d.name == "archive" or not d.is_dir():
continue
info = _load_task_json(d)
if info:
yield infoFile format details leaking through layers:
# BAD — caller knows it's JSON, knows the path convention
registry_path = trellis_dir / "registry.json"
data = json.loads(registry_path.read_text())
data["agents"][agent_id] = {...}
registry_path.write_text(json.dumps(data, indent=2))
# GOOD — module hides storage format
registry = AgentRegistry(trellis_dir)
registry.add(agent_id, task=task_name, platform="Codex")When complexity is unavoidable, the module should absorb it internally rather than pushing it to callers. A module has few developers but many users — it's better for the module author to handle complexity once than for every caller to handle it independently.
# BAD — pushes complexity to every caller
def run_git(args: list[str]) -> subprocess.CompletedProcess:
return subprocess.run(["git"] + args, capture_output=True, text=True)
# Every caller must: check returncode, decode stderr, handle encoding,
# strip whitespace, handle repo not found, etc.
# GOOD — absorbs complexity
def run_git(args: list[str], *, cwd: Path | None = None) -> str:
"""Run git command, return stdout. Raises GitError on failure."""
result = subprocess.run(
["git"] + args,
capture_output=True, text=True, encoding="utf-8",
errors="replace", cwd=cwd,
)
if result.returncode != 0:
raise GitError(args[0], result.stderr.strip())
return result.stdout.strip()subprocess.CompletedProcess and letting callers check .returncodedict when a typed object would let callers skip validationException handling is a major source of complexity. The best strategy is to design semantics so error conditions simply aren't errors.
# BAD — raises if key doesn't exist
def remove_agent(registry: dict, agent_id: str) -> None:
if agent_id not in registry["agents"]:
raise KeyError(f"Agent {agent_id} not found")
del registry["agents"][agent_id]
# GOOD — guarantees postcondition: agent is not in registry
def remove_agent(registry: dict, agent_id: str) -> None:
"""Ensure agent_id is not in the registry after this call."""
registry["agents"].pop(agent_id, None)# BAD — raises if directory already exists
def init_workspace(path: Path) -> None:
if path.exists():
raise FileExistsError(f"{path} already exists")
path.mkdir()
# GOOD — guarantees postcondition: directory exists
def ensure_workspace(path: Path) -> Path:
"""Ensure workspace directory exists. Returns the path."""
path.mkdir(parents=True, exist_ok=True)
return pathThe key insight: define the operation by its postcondition ("after this call, X is true") rather than its precondition ("X must be true before calling").
Choose the simplest solution that works. Complexity must be justified by concrete (not hypothetical) requirements.
# Over-engineered — registry pattern for 3 formatters
class FormatterRegistry:
_registry: dict[str, type] = {}
@classmethod
def register(cls, name: str): ...
@classmethod
def create(cls, name: str): ...
# Simple — just a dictionary
FORMATTERS = {"json": format_json, "text": format_text, "table": format_table}
def format_output(fmt: str, data: Any) -> str:
formatter = FORMATTERS.get(fmt)
if not formatter:
raise ValueError(f"Unknown format: {fmt}")
return formatter(data)Wait until you have three instances of a pattern before extracting an abstraction. Two is coincidence; three is a pattern. Premature abstraction is worse than duplication because:
However: when you do hit three, extract immediately. Don't let it reach nine.
Each module should have one reason to change. When a module grows beyond ~300 lines, check if it has multiple responsibilities.
Split when:
Split by information hiding (what knowledge is encapsulated), not by execution order (what runs when).
# BAD — split by execution order (temporal decomposition)
# step1_parse_args.py, step2_validate.py, step3_execute.py
# All three must know the command structure
# GOOD — split by responsibility
# task_store.py — owns task.json read/write, schema, iteration
# task_cli.py — owns argparse, subcommand routing
# task_display.py — owns formatting, colors, table outputWhen multiple scripts need the same capability, provide it once in common/.
| Capability | Should Live In | Not In |
|---|---|---|
| JSON file read/write | common/io.py | Each script's _read_json_file |
| Terminal colors + logging | common/log.py | Each script's Colors class |
| Git command execution | common/git.py | _run_git_command prefixed private |
| Task data access | common/tasks.py | Ad-hoc task.json parsing |
| Path constants | common/paths.py (existing) | Hardcoded strings |
Naming: If a function is used by other modules, it's public API — don't prefix it with _.
When parsing output from shell commands (git, grep, etc.), respect semantic whitespace:
# BAD — .strip() destroys semantic whitespace
# git submodule status prefix: ' ' = initialized, '-' = uninitialized, '+' = changed
line = output_line.strip() # Loses the prefix character!
# GOOD — strip only trailing newlines
line = output_line.rstrip("\n\r")
prefix = line[0] if line else " "Always document what each field position means when parsing structured command output.
Use during code review and self-review:
| Signal | What It Means |
|---|---|
| Shallow Module | Interface is nearly as complex as implementation |
| Information Leakage | Same JSON schema / file format knowledge in multiple modules |
| Duplicated Utility | Same helper function copied to multiple files |
| God Module | File > 500 lines with multiple unrelated responsibilities |
| Pass-Through Function | Function just forwards args to another with similar signature |
Magic .get() Chains | data.get("x") or data.get("y", "") — missing type definition |
| sys.path Hacking | sys.path.insert(0, ...) — fix package structure instead |
| Private-Named Public API | _function imported by 3+ external modules |
| Raw Dict Threading | Passing dict through 4+ function calls — use a dataclass |
| Repeated Iteration | Same directory scan / file parse pattern in 3+ locations |
| Broad Exception Catch | except Exception: without re-raising — hides bugs |
| Temporal Decomposition | Modules split by "what runs when" instead of "what knows what" |
grep -r "pattern" . before creating new utilitiesSpend roughly 10-20% of each change improving surrounding design.
Working code is necessary but not sufficient. The increments of software development should be abstractions, not just features. Each change should leave the codebase slightly better than you found it.
This is not perfectionism — it's compound interest. Small design improvements accumulate into a system that's dramatically easier to work with over time.
© mindfold-ai, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/python-design of mindfold-ai/Trellis.
Open the folder on GitHubat commit f089cb3
Python Design next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Python Design this skillmindfold-ai/Trellis | 15k | — | ~4k | Automated safety check: Pass | AGPL-3.0 | |
| Py Rigmudrii/hermesd | 119 | — | ~6.3k | Automated safety check: Pass | MIT | |
| Python Architecturemicrosoft/apm | 4k | — | ~347 | Automated safety check: Pass | MIT | |
| Python Design Patternswshobson/agents | 40k | — | ~1.2k | Automated safety check: Pass | MIT | |
| Python Design Patternsaiskillstore/marketplace | 430 | 1 repos | ~3.1k | Automated safety check: Pass | None | |
| Swiftui View RefactorDimillian/Skills | 4k | 5 repos | ~2k | Automated safety check: Pass | MIT |
mudrii/hermesd
A skill your agent uses when building, reviewing, or refactoring Python code that requires strong maintainability discipline: SRP, DRY, OCP, explicit dependency injection, TDD/ATDD workflow, strict…
microsoft/apm
Activate when creating new modules, refactoring class hierarchies, introducing design patterns, or making changes spanning 3+ files in the APM CLI codebase.
wshobson/agents
Python design patterns including KISS, Separation of Concerns, Single Responsibility, and composition over inheritance.
aiskillstore/marketplace
Python design patterns including KISS, Separation of Concerns, Single Responsibility, and composition over inheritance.
Dimillian/Skills
Refactor and review SwiftUI view files with strong defaults for small dedicated subviews, MV-over-MVVM data flow, stable view trees, explicit dependency injection, and correct Observation usage.
rtk-ai/rtk
Describes seven Rust design patterns for the RTK CLI filter modules, with when to use each, RTK examples, and notes on when a pattern is overkill.
mindfold-ai/Trellis
Reach into past AI conversation history through the trellis mem CLI.
mindfold-ai/Trellis
Use Trellis channel for live multi-agent collaboration, spawned workers, cross-agent review, progress inspection, forum channels, and channel log debugging.
mindfold-ai/Trellis
Systematic first principles thinking for any problem domain.
mindfold-ai/Trellis
Understand and customize the local Trellis architecture inside a user project.
mindfold-ai/Trellis
Guide for contributing to Trellis documentation and marketplace.
mindfold-ai/Trellis
Create a Trellis migration manifest and matching docs-site changelogs for a target release by analyzing commits since the previous release.
Works with
Categories
Python design patterns for CLI scripts and utilities — type-first development, deep modules, complexity management, and red flags. Python Design is an agent skill from mindfold-ai/Trellis. Python design patterns for CLI scripts and utilities — type-first development, deep modules, complexity management, and red flags.
Python Design fits situations like: refactoring Python files; especially in .trellis/scripts/; any CLI/scripting context.
Run `npx skills add mindfold-ai/Trellis --skill python-design -a claude-code`. Or copy the skill folder (.agents/skills/python-design in mindfold-ai/Trellis) into .claude/skills/python-design in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mindfold-ai/Trellis --skill python-design -a codex`. Or copy the skill folder (.agents/skills/python-design in mindfold-ai/Trellis) into .agents/skills/python-design in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mindfold-ai/Trellis --skill python-design -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/python-design, .gemini/skills/python-design, .github/skills/python-design and .opencode/skills/python-design in your project.
SKILL.md names no scripts, command-line tools or credentials: Python Design is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Python Design is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Python Design: Py Rig (mudrii/hermesd, 119 stars), Python Architecture (microsoft/apm, 4k stars), Python Design Patterns (wshobson/agents, 40k stars) and Python Design Patterns (aiskillstore/marketplace, 430 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mindfold-ai (a GitHub organization) maintains it in mindfold-ai/Trellis, which has 14,883 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on September 29, 2026.
Source: mindfold-ai/Trellis on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.