
Service Registry
Run registered AI coding services safely from templates with timeouts, captured output, and retry logic.
Overview
Service Registry is an agent skill most often used in Build (also Ship review automation, Operate iteration) that defines safe command-building and subprocess execution for multi-service agent registries.
Install
npx skills add https://github.com/athola/claude-night-market --skill service-registryWhat is this skill?
- build_command expands ServiceConfig templates with @file prompts and default models
- execute_safely runs shlex-split subprocess with timeout and stdout/stderr capture
- ExecutionResult bundles success, exit code, duration, and estimated tokens
- TimeoutExpired returns structured failure instead of hanging agents
- Retry patterns section for resilient multi-service execution (advanced)
- estimated_tokens: 400 in skill frontmatter
Adoption & trust: 1 installs on skills.sh; 304 GitHub stars; 2/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
What problem does it solve?
You registered several AI CLI services but ad-hoc shell strings time out, leak stderr, and give agents no structured success signal.
Who is it for?
Builders running a custom agent registry or night-market style router across Claude, Codex, or other CLIs with Python glue.
Skip if: Single-tool Cursor-only workflows with no programmatic multi-service dispatch, or teams forbidden from subprocess execution on developer machines.
When should I use this skill?
Implementing or extending a service registry that launches external AI CLIs from Python templates.
What do I get? / Deliverables
Commands are built from typed configs, executed with timeouts and captured I/O, and summarized as ExecutionResult for downstream retry or routing logic.
- build_command and execute_safely helpers
- ExecutionResult records for agent routing and retries
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Night-market-style orchestration is built when you wire multiple agent backends; Build / agent-tooling is the canonical shelf before you rely on it in Ship and Operate. Command templates, subprocess execution, and retries are core to a service registry layer—not a one-off API integration or a user-facing frontend task.
Where it fits
Expand night-market ServiceConfig into a shlex-safe command before the first orchestrated run.
Dispatch a registered review service with file @-references and cap wall time so CI-like loops do not hang.
Retry a timed-out agent job using structured ExecutionResult instead of parsing raw terminal scrollback.
How it compares
Skill package for registry execution semantics—not an MCP server catalog entry or a hosted CI runner product.
Common Questions / FAQ
Who is service-registry for?
Solo developers and tiny teams building multi-model agent runners who need consistent, safe shell execution around registered services.
When should I use service-registry?
In Build while wiring agent-tooling registries, in Ship when automating review or test commands across services, and in Operate when retrying failed agent jobs with bounded timeouts.
Is service-registry safe to install?
The patterns execute shell commands you configure—treat templates as trusted code and review the Security Audits panel on this Prism page before enabling in production agents.
SKILL.md
READMESKILL.md - Service Registry
# Execution Patterns ## Command Building ### Template Expansion ```python def build_command( config: ServiceConfig, prompt: str, files: list[str], model: str = None ) -> str: """Build command from template.""" file_args = " ".join(f"@{f}" for f in files) model = model or config.default_model return config.command_template.format( command=config.command, prompt=prompt, files=file_args, model=model ) ``` ### Safe Execution ```python import subprocess import shlex def execute_safely(command: str, timeout: int = 60) -> ExecutionResult: """Execute command with safety measures.""" start = time.time() try: result = subprocess.run( shlex.split(command), capture_output=True, text=True, timeout=timeout ) return ExecutionResult( success=(result.returncode == 0), stdout=result.stdout, stderr=result.stderr, exit_code=result.returncode, duration=time.time() - start, tokens_used=estimate_tokens(result.stdout) ) except subprocess.TimeoutExpired: return ExecutionResult( success=False, stderr="Command timed out", exit_code=-1, duration=timeout ) ``` ## Retry Patterns ### Exponential Backoff ```python def execute_with_retry( registry: ServiceRegistry, service: str, prompt: str, max_retries: int = 3 ) -> ExecutionResult: """Execute with exponential backoff retry.""" for attempt in range(max_retries): result = registry.execute(service, prompt) if result.success: return result if "rate limit" in result.stderr.lower(): wait_time = 2 ** attempt # 1, 2, 4 seconds time.sleep(wait_time) else: break # Non-retryable error return result ``` ### Circuit Breaker ```python class CircuitBreaker: def __init__(self, failure_threshold: int = 5, reset_timeout: int = 60): self.failures = 0 self.threshold = failure_threshold self.reset_timeout = reset_timeout self.last_failure = 0 self.state = "closed" # closed, open, half-open def can_execute(self) -> bool: if self.state == "closed": return True if self.state == "open": if time.time() - self.last_failure > self.reset_timeout: self.state = "half-open" return True return False return True # half-open allows one attempt def record_result(self, success: bool): if success: self.failures = 0 self.state = "closed" else: self.failures += 1 self.last_failure = time.time() if self.failures >= self.threshold: self.state = "open" ``` ## Parallel Execution ### Multi-Service Query ```python import asyncio async def execute_parallel( registry: ServiceRegistry, services: list[str], prompt: str ) -> dict[str, ExecutionResult]: """Execute same prompt across multiple services.""" tasks = { service: asyncio.create_task( registry.execute_async(service, prompt) ) for service in services } results = {} for service, task in tasks.items(): results[service] = await task return results ``` --- name: service-config description: Service configuration patterns and options estimated_tokens: 400 --- # Service Configuration ## Configuration Schema ### Full Configuration ```python @dataclass class ServiceConfig: # Identity name: str display_name: str = "" # Execution command: str # CLI command or endpoint command_template: str = "{command} -p {prompt}" # Authentic