Agent skill

Python Design

by mindfold-ai in mindfold-ai/Trellis

Python design patterns for CLI scripts and utilities — type-first development, deep modules, complexity management, and red flags.

AGPL-3.0Auto-check passedDevelopment

Install Python Design

skills CLI
$ npx skills add mindfold-ai/Trellis --skill python-design -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install mindfold-ai/Trellis python-design --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ 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-src

Use ~/.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/

Facts

Skill name
python-design
GitHub stars
15k
Token cost
~4k tokens
SKILL.md length
1,140 words
Files
1
Skills in repo
8
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Python design patterns for CLI scripts and utilities — type-first development, deep modules, complexity management, and red flags.

  • Works in 3 steps: Change Amplification — A small change… → Cognitive Load — You must hold too much… → Unknown Unknowns — You don't know what…
  • Refactoring Python files
  • SKILL.md covers When to Activate, Core Thesis, Principle 1: Deep Modules and Principle 2: Type-First…, plus 11 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

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.

When your agent uses it

  • Refactoring Python files
  • Especially in .trellis/scripts/
  • Any CLI/scripting context

Example prompts

  • “/python-design”

Requirements

  • Python 3

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Change Amplification — A small change requires edits in many places
  2. Cognitive Load — You must hold too much context to make a safe change
  3. Unknown Unknowns — You don't know what you don't know (the most dangerous)

What it can do on your machine

Read from SKILL.md and the folder at commit f089cb3. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    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.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

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.

Always · name and description, kept in context so the agent knows when to use it
~93
When it runs · the whole SKILL.md, loaded when a task matches
~4k

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.

Safety

Auto-check passed

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.

SKILL.md

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.

Download SKILL.mdSave it as .claude/skills/python-design/SKILL.md (or your agent's skills folder).
name
python-design
description
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.

Python Design for CLI Scripts

Design patterns and principles for writing maintainable Python CLI tools and utilities. Based on A Philosophy of Software Design (Ousterhout), adapted for scripting contexts.

When to Activate

  • Writing or modifying Python files
  • Planning module decomposition
  • Code review of Python changes
  • Refactoring scripts that feel "messy"
  • Adding a new subcommand or utility function

Core Thesis

The central challenge is managing complexity, not adding features.

Complexity is anything that makes code hard to understand or modify. It has three symptoms:

  1. Change Amplification — A small change requires edits in many places
  2. Cognitive Load — You must hold too much context to make a safe change
  3. Unknown Unknowns — You don't know what you don't know (the most dangerous)

Complexity is incremental. It accumulates through hundreds of small decisions, not one catastrophic mistake. Therefore: sweat the small stuff.


Principle 1: Deep Modules

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.

Example: Task Data Access
python
# 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", "")
python
# 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.


Principle 2: Type-First Development

Types define contracts before implementation. This workflow catches design problems early:

  1. Define data shapes — dataclass or TypedDict first
  2. Define function signatures — parameter and return types
  3. Implement to satisfy types — let the type checker guide completeness
  4. Validate at boundaries — runtime checks only where data enters the system
Frozen Dataclasses for Internal Data
python
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: str

Frozen dataclasses are immutable — no accidental mutation, safe to pass around.

TypedDict for External JSON Shapes

When the data comes from a file (task.json, config.yaml, registry.json), use TypedDict to document the expected shape:

python
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.

NewType for Domain Primitives

When two strings mean different things, make the type system enforce it:

python
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}")
Discriminated Unions for State

When an entity can be in distinct states with different data:

python
@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():
            pass

The type checker ensures every state is handled. No more if data.get("status") == "running" with forgotten branches.


Principle 3: Information Hiding

Each module should encapsulate design decisions. When the same knowledge appears in multiple modules, information has leaked.

Common Leakage Patterns in Scripts

JSON schema knowledge scattered everywhere:

python
# 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", "")
        ...
python
# 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 info

File format details leaking through layers:

python
# 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")

Principle 4: Pull Complexity Downward

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.

python
# 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()
Anti-patterns of Pushing Complexity Up
  • Returning raw subprocess.CompletedProcess and letting callers check .returncode
  • Raising generic exceptions that callers must parse
  • Using configuration parameters to avoid making decisions
  • Returning dict when a typed object would let callers skip validation

Principle 5: Define Errors Out of Existence

Exception handling is a major source of complexity. The best strategy is to design semantics so error conditions simply aren't errors.

python
# 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)
python
# 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 path

The key insight: define the operation by its postcondition ("after this call, X is true") rather than its precondition ("X must be true before calling").


Principle 6: KISS and Rule of Three

KISS — Keep It Simple

Choose the simplest solution that works. Complexity must be justified by concrete (not hypothetical) requirements.

python
# 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)
Rule of Three

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:

  • It couples unrelated code through a shared abstraction
  • It makes each instance harder to understand independently
  • It creates pressure to fit future cases into the abstraction even when they don't fit

However: when you do hit three, extract immediately. Don't let it reach nine.


Principle 7: Single Responsibility and Module Boundaries

Each module should have one reason to change. When a module grows beyond ~300 lines, check if it has multiple responsibilities.

Decomposition Signals

Split when:

  • A file has multiple "sections" separated by comment headers
  • You need to import only one function from a large module
  • Tests for different parts of the module have no shared setup
  • Changes to one responsibility don't require understanding the other
Show full SKILL.md (443 more words)Show less
How to Split

Split by information hiding (what knowledge is encapsulated), not by execution order (what runs when).

python
# 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 output

Principle 8: Consistent Shared Infrastructure

When multiple scripts need the same capability, provide it once in common/.

CapabilityShould Live InNot In
JSON file read/writecommon/io.pyEach script's _read_json_file
Terminal colors + loggingcommon/log.pyEach script's Colors class
Git command executioncommon/git.py_run_git_command prefixed private
Task data accesscommon/tasks.pyAd-hoc task.json parsing
Path constantscommon/paths.py (existing)Hardcoded strings

Naming: If a function is used by other modules, it's public API — don't prefix it with _.


Principle 9: Structured CLI Output Parsing

When parsing output from shell commands (git, grep, etc.), respect semantic whitespace:

python
# 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.


Red Flags Quick Reference

Use during code review and self-review:

SignalWhat It Means
Shallow ModuleInterface is nearly as complex as implementation
Information LeakageSame JSON schema / file format knowledge in multiple modules
Duplicated UtilitySame helper function copied to multiple files
God ModuleFile > 500 lines with multiple unrelated responsibilities
Pass-Through FunctionFunction just forwards args to another with similar signature
Magic .get() Chainsdata.get("x") or data.get("y", "") — missing type definition
sys.path Hackingsys.path.insert(0, ...) — fix package structure instead
Private-Named Public API_function imported by 3+ external modules
Raw Dict ThreadingPassing dict through 4+ function calls — use a dataclass
Repeated IterationSame directory scan / file parse pattern in 3+ locations
Broad Exception Catchexcept Exception: without re-raising — hides bugs
Temporal DecompositionModules split by "what runs when" instead of "what knows what"

Design Checklist (Before Writing Code)

  1. Types first: Define the data shape before writing logic
  2. Module depth check: Will the interface be simpler than the implementation?
  3. Duplication scan: grep -r "pattern" . before creating new utilities
  4. Responsibility check: Does this belong in an existing module?
  5. Error design: Can you define the error out of existence?
  6. Naming precision: Does the name convey meaning without reading the implementation?

Design Checklist (During Code Review)

  1. Red flags scan: Check the table above against the diff
  2. Type safety: Are new data shapes documented with types?
  3. Information hiding: Does the change leak implementation details?
  4. Consistency: Does it follow the existing patterns in the module?
  5. Depth: Is the common path simple for callers?

Strategic Investment

Spend 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

Files

Just SKILL.md in .agents/skills/python-design of mindfold-ai/Trellis.

Open the folder on GitHubat commit f089cb3

Compare with similar skills

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.

Python Design compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Python Design this skillmindfold-ai/Trellis15k—~4kAutomated safety check: PassAGPL-3.0
Py Rigmudrii/hermesd119—~6.3kAutomated safety check: PassMIT
Python Architecturemicrosoft/apm4k—~347Automated safety check: PassMIT
Python Design Patternswshobson/agents40k—~1.2kAutomated safety check: PassMIT
Python Design Patternsaiskillstore/marketplace4301 repos~3.1kAutomated safety check: PassNone
Swiftui View RefactorDimillian/Skills4k5 repos~2kAutomated safety check: PassMIT

Similar skills

  • 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…

    119 GitHub stars~6.3k tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Python Architecture

    microsoft/apm

    Official

    Activate when creating new modules, refactoring class hierarchies, introducing design patterns, or making changes spanning 3+ files in the APM CLI codebase.

    4k GitHub stars~347 tokensUpdated yesterday
    DevelopmentAuto-check passed
  • Python Design Patterns

    wshobson/agents

    Python design patterns including KISS, Separation of Concerns, Single Responsibility, and composition over inheritance.

    40k GitHub stars~1.2k tokensUpdated 4 days ago
    DevelopmentAuto-check passed
  • Python Design Patterns

    aiskillstore/marketplace

    Python design patterns including KISS, Separation of Concerns, Single Responsibility, and composition over inheritance.

    430 GitHub starsUsed in 1 repo~3.1k tokens
    DevelopmentAuto-check passed
  • Swiftui View Refactor

    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.

    4k GitHub starsUsed in 5 repos~2k tokens
    DevelopmentAuto-check passed
  • 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.

    83k GitHub stars~1.9k tokensUpdated yesterday
    DevelopmentAuto-check passed

More from mindfold-ai/Trellis

All 8 skills in this repo
  • Trellis Session Insight

    mindfold-ai/Trellis

    Reach into past AI conversation history through the trellis mem CLI.

    15k GitHub starsUsed in 4 repos~1.7k tokens
    Auto-check passed
  • Trellis Channel

    mindfold-ai/Trellis

    Use Trellis channel for live multi-agent collaboration, spawned workers, cross-agent review, progress inspection, forum channels, and channel log debugging.

    15k GitHub starsUsed in 5 repos~1.2k tokens
    Auto-check passed
  • First Principles Thinking

    mindfold-ai/Trellis

    Systematic first principles thinking for any problem domain.

    15k GitHub stars~4.1k tokensUpdated 9 days ago
    Auto-check passed
  • Trellis Meta

    mindfold-ai/Trellis

    Understand and customize the local Trellis architecture inside a user project.

    15k GitHub starsUsed in 4 repos~3.2k tokens
    Auto-check passed
  • Contribute

    mindfold-ai/Trellis

    Guide for contributing to Trellis documentation and marketplace.

    15k GitHub stars~2.7k tokensUpdated 9 days ago
    Auto-check passed
  • Create Manifest

    mindfold-ai/Trellis

    Create a Trellis migration manifest and matching docs-site changelogs for a target release by analyzing commits since the previous release.

    15k GitHub stars~2.5k tokensUpdated 9 days ago
    Auto-check passed

Works with

Categories

Questions about Python Design

What does Python Design do?

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.

When should I use Python Design?

Python Design fits situations like: refactoring Python files; especially in .trellis/scripts/; any CLI/scripting context.

How do I install Python Design in Claude Code?

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.

How do I install Python Design in Codex?

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.

Can I use Python Design in Cursor, Gemini CLI or GitHub Copilot?

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.

What does Python Design need to run?

SKILL.md names no scripts, command-line tools or credentials: Python Design is instructions for the agent only. Our summary lists: Python 3.

Does Python Design access the network?

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.

Is Python Design safe to install?

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.

What licence does Python Design use?

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.

How many tokens does Python Design use?

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.

What are the alternatives to Python Design?

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.

Who maintains Python Design?

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.