Typed command core

Version 0.1.0 Updated Jan 30, 2026

Cuprum provides sh.make to build typed SafeCmd instances from curated programs. Builders enforce the catalogue allowlist up front and carry project metadata alongside argv, so downstream services can apply noise rules or link to documentation without a second lookup.

  • sh.make raises UnknownProgramError when the program is not in the current catalogue.
  • Positional arguments are stringified with str().
  • Keyword arguments become --flag=value entries with underscores in flag names converted to hyphens.
  • None is rejected; decide whether to skip or substitute a flag before calling the builder.
from cuprum import ECHO, sh

echo = sh.make(ECHO)
cmd = echo("-n", "hello world")
print(cmd.argv_with_program)  # ('echo', '-n', 'hello world')
print(cmd.project.noise_rules)  # metadata for downstream loggers

Writing project-specific builders

Wrap sh.make in project modules to centralize validation and expose a clear API for callers:

from pathlib import Path

from cuprum import Program, SafeCmd, sh

SAFE_CAT = Program("cat")


def _safe_path(path: Path) -> str:
    path = path.resolve()
    if not path.is_file():
        msg = f"{path} is not a readable file"
        raise ValueError(msg)
    return path.as_posix()


def cat_file(path: Path, numbered: bool = False) -> SafeCmd:
    args: list[str] = []
    if numbered:
        args.append("-n")
    args.append(_safe_path(path))
    return sh.make(SAFE_CAT)(*args)

Builders keep argv construction in one place, making it easier to validate inputs, document behaviour, and reuse the same allowlisted program across a codebase.