Skip to content

New utility? Use the /scaffold-util skill. It handles the decision, scaffolding, and boilerplate for you.


WSL UtilitiesWindows Utilities
Root/home/ta/utils/D:\FSS\Software\Utils\PythonUtils\
LanguagePython (uv tool install) or BashPython via uv run
Installuv tool install . → global CLI binaryuv sync once, then run from project dir
Runutility-name [args] from anywhere in WSLuv run utility-name from project folder
SchedulerWSL cron (if needed)Windows Task Scheduler or WSL cron

WSL utility subdirectories:

SubdirPurposeExisting
ai/AI-assisted processing, content pipelinespdf-to-md (production) · source_summarizer (incomplete) · medium_digest (incomplete)
web/Web deployment, site toolingweb-deploy
system/WSL/Linux system management
shell-scripts/Bash/shell automation

Existing Windows utilities: my_backup


Build a WSL utility when:

  • It runs naturally in WSL/Linux (CLI tools, Bash, Python scripts)
  • It calls Gemini, Claude, or another AI API → place in ai/
  • It relates to web deployment or site tooling → place in web/
  • It manages WSL/Linux system configuration → place in system/
  • It’s a Bash/shell script for automation → place in shell-scripts/

Build a Windows utility when:

  • It needs Windows-native access (Task Scheduler, wbAdmin, Robocopy, Windows Defender, registry)
  • It backs up or mirrors files across Windows drives
  • It must be scheduled via Task Scheduler (not just cron)
  • It integrates with Windows apps (Kopia, 7-Zip, EspoCRM)

Either works when:

  • Pure Python logic (file transforms, data processing, reporting)
  • Decide based on where it will run most naturally

For one-off scripts or utilities you’ll use a handful of times.

Artifacts:

  • src/<util_name>/cli.py — main script
  • pyproject.toml — entry point + dependencies
  • README.md — short: purpose, install, usage examples
  • .env.example — if it needs secrets (ASCII-only comments)

For utilities you’ll rely on daily, share, or extend over time.

Artifacts (all of quick-and-dirty, plus):

  • config.yaml — runtime SSOT for all configurable settings
  • src/<util_name>/ — modular package (cli.py, core.py, config.py, ui.py)
  • tests/ — pytest suite
  • logs/ — rotational text logs (committed as empty dir via .gitkeep)
  • docs/ — extended docs (RESTORE.md, architecture notes)
  • config/ — static config files (ignore patterns, templates)

ConcernToolNotes
Package managementuvAlways — never pip, poetry, or venv directly
CLI outputrichConsole, Panel, status spinners, ✓/✗ indicators
CLI parsingargparse or typerargparse for simple; typer for complex multi-command
Configurationconfig.yaml + pyyamlSSOT for all settings; secrets stay in .env
Secretspython-dotenv + .envNever committed; .env.example has placeholder values
AI (Gemini)google-genaiDedicate a separate GEMINI_API_KEY per utility (quota isolation)
AI (Claude)anthropicUse claude-sonnet-4-6 or claude-haiku-4-5-20251001
LoggingloguruFor production utilities; print + Rich acceptable for quick-and-dirty
TestingpytestProduction tier only

CLI always uses Rich. No raw print for status output. Every CLI must show:

  • Progress/status (spinner or progress bar for long ops)
  • ✓ / ✗ indicators per step
  • Clean error messages — no raw tracebacks to the user

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "utility-name"
version = "0.1.0"
description = "One-line description of what it does"
requires-python = ">=3.10"
dependencies = [
"rich>=13.0.0",
"pyyaml>=6.0",
"python-dotenv>=1.0.0",
# add AI deps if needed:
# "google-genai>=1.0.0",
# "anthropic>=0.84.0",
]
[project.scripts]
utility-name = "utility_name.cli:main"
[tool.hatch.build.targets.wheel]
packages = ["src/utility_name"]

WSL AI utility install: uv tool install . → binary available globally as utility-name

Windows utility install: uv sync → run as uv run utility-name from project directory


# API Keys
# Get your Gemini API key from: https://aistudio.google.com/
GEMINI_API_KEY=your_gemini_api_key_here
# Optional: override defaults
# OUTPUT_DIR=/path/to/output

Rules:

  • ASCII-only comments (no Unicode, no emoji in .env.example)
  • Placeholder values only — never real credentials
  • Write .env files from WSL, not Windows (Windows clipboard embeds invisible Unicode)

defaults:
provider: gemini # or 'claude'
gemini_model: gemini-2.5-flash
claude_model: claude-sonnet-4-6
output_dir: /path/to/output
# Source-specific or feature-specific sections below
sources:
source_name:
key: value

Modelled on my_backup — the gold standard. Every README must include these sections in this order:

  1. Tagline + one-line description (H1 title)
  2. Features list — bullet points, concrete capabilities, not abstract goals
  3. Quick Start (CLI) — most common command first; all flags with examples
  4. Installation — exact commands:
    • WSL AI: uv tool install .
    • Windows: uv sync, then uv run utility-name
  5. Where to run — WSL or Windows? Why?
  6. API Key Setup (if AI) — where to get keys, what to put in .env
  7. Configurationconfig.yaml structure and key settings
  8. File Locations — table of: input dirs, output dirs, logs, config
  9. Development — how to run from source, run tests, contribute

Location: /home/ta/utils/ai/pdf2md/

Structure:

pdf2md/
├── src/pdf2md/
│ ├── cli.py # Entry point: pdf-to-md
│ ├── processor.py # Core logic
│ └── config.py # Config loader
├── config.yaml # SSOT: provider, models, output dirs, tag vocab
├── pyproject.toml # Entry points + deps
├── README.md
└── .env # GEMINI_API_KEY (not committed)

Key patterns:

  • config.yaml drives all runtime settings (model, output path, tag vocabulary)
  • Dedicated GEMINI_API_KEY — not shared with other utilities
  • uv tool install . makes pdf-to-md available as a global CLI
  • Rich Console for all output

Location: D:\FSS\Software\Utils\PythonUtils\my_backup\

Structure:

my_backup/
├── src/my_backup/
│ ├── main.py # Entry point: uv run my_backup
│ ├── config.py # PROJECT_ROOT + config loader
│ ├── context.py # Pipeline state (ctx object)
│ ├── pipeline.py # Execution orchestration
│ ├── tasks.py # Business logic
│ ├── ui.py # Rich terminal dashboard
│ └── utils.py # Shell, logging infrastructure
├── tests/
├── docs/
├── config/
├── hooks/ # Pre-backup scripts
├── logs/ # Rotational text logs
├── config.yaml
├── pyproject.toml
└── README.md

Key patterns:

  • Context object (ctx) passed to every task — accumulates failures/warnings
  • config.yaml is SSOT; secrets in .env
  • Multiple entry points (one per subcommand/script)
  • Comprehensive pytest suite with restore verification

  • Type hints required on all non-trivial functions
  • PEP 8 — use Ruff for linting
  • Error handling: clean user-facing messages via Rich; no raw tracebacks
  • Logging: hierarchical text format with timestamps; rotate logs (keep last 5)
  • No hardcoded paths — all paths via config.yaml or resolved relative to PROJECT_ROOT
  • Naming: lowercase with hyphens for CLI commands; verb-noun-detail format

Full dev rules: D:\FSS\KB\Business\03_Processes\Software Dev\GlobalDevRules.md