---
title: "Design an Extension Package"
source: https://docs.autohand.ai/guides/extensions/design-extension-package
---

# Design an extension package

A strong extension has one coherent job, the smallest viable contribution layer, auditable inputs and code, and an acceptance test that proves its complete lifecycle.

## Define one capability boundary

Name the user outcome before naming files. “Release Assistant” is a useful boundary because its tools gather release evidence and its agent turns that evidence into a readiness plan. “Company Utilities” is not: unrelated commands create unclear permissions, ownership, and versioning.

Write a one-sentence contract:

**Template:** This extension helps *who* accomplish *outcome* by contributing *tools, agents, skills, or runtime surfaces*, while never *explicit non-goals*.

Example: “This extension helps maintainers prepare evidence-backed releases by contributing Git range and changelog tools plus a release planner, while never publishing, tagging, or pushing a release.”

## Inventory the existing Autohand feature

Before authoring, decide whether each piece is already a meta-tool, external agent, hook, skill, MCP integration, or native CLI surface. Preserve the underlying contract when packaging it. Declarative contributions stay on existing registries; trusted runtime contributions register through Extension API v1.

| Need | Contribution | Design question |
|---|---|---|
| Collect deterministic repository evidence | Tool | Can a bounded shell command express it safely? |
| Apply a review rubric or synthesize evidence | Agent | Which exact tools are necessary? |
| Teach a reusable workflow with references | Agent Skill | Can the user invoke it explicitly with $name? |
| React automatically after a lifecycle event | Configured hook or trusted runtime hook | Does this need package-owned code or only a shell command? |
| Call a remote authenticated service | MCP, Agent SDK tool, or trusted runtime provider | Would a separate service boundary be easier to isolate and operate? |
| Add a new slash command, Ink view, shortcut, or CLI flag | Trusted runtime entrypoint | Can users safely review and explicitly trust the emitted code? |

## Choose the trust boundary deliberately

| Layer | Use it for | Install decision |
|---|---|---|
| Declarative | Tools, agents, and Agent Skills expressible as bounded data and instructions | Normal validated install; no package code executes |
| Trusted runtime | Slash commands, Ink UI, line segments, shortcuts, flags, hooks, providers, and permission policy | Review compiled code and dependencies, then install with --trust |

Do not add a runtime entrypoint merely because the source project uses TypeScript. If bounded tools and a skill preserve the user-visible behavior, the declarative layer is easier to audit and distribute. When runtime behavior is essential, compile before packaging; Autohand does not transpile source or install dependencies.

## Design tool inputs before handlers

Treat the JSON Schema as the public API. Prefer explicit required inputs over interpolating broad free-form command fragments. A `base` revision or repository-relative `path` is understandable; an `args` string that lets callers inject an arbitrary shell tail defeats the package boundary.

-   Use lower snake case and action-oriented names such as `changed_files_since`.
-   Describe what the tool returns, not only which command it runs.
-   Use narrow scalar inputs. Document repository-relative or revision semantics.
-   Declare every placeholder as required so rendering cannot produce a partial command.
-   Keep mutating and read-only operations separate so permission decisions remain clear.

## Design agent prompts around evidence

An extension agent should be a specialist, not a generic replacement for the primary agent. Give it a concrete role, the smallest tool allowlist, output expectations, and explicit claims it must not make without proof.

``` markdown
---
description: Build evidence-based release notes and a readiness checklist
tools: read_file, git_status, release_range, changelog_context
---
Use the exact release range and repository evidence.
Group user-visible changes, compatibility notes, fixes, and operational risks.
Call out missing validation or migration steps.
Never claim a release is ready when required proof is absent.
```

The allowlist does not grant permission. It limits which active tools the specialist can request; Autohand still applies the runtime filter and authorization policy.

## Plan identity and versioning

Use a stable lowercase qualified id controlled by the publisher, such as `acme.release-assistant`. The install directory and state records derive from this id, so do not rename it casually. Treat contribution names as part of the public contract because agent prompts, users, and automation may refer to them.

-   **Patch** for prompt wording, descriptions, or compatible handler corrections.
-   **Minor** for additive tools, agents, or optional behavior.
-   **Major** for removed or renamed contributions, incompatible inputs, or changed outcomes.

Extension API v1 validates strict numeric semver, but your release policy supplies the compatibility meaning.

## Write the acceptance matrix first

| Phase | Proof |
|---|---|
| Validate | Good package succeeds; an intentionally broken fixture fails without side effects. |
| Install | Copied and linked modes report the expected id, version, scope, trust, and state. |
| Discover | A fresh process sees exact declarative and runtime identities with correct provenance. |
| Authorize | Each handler shows expected prompts; denial prevents execution. |
| Use | Tools return bounded evidence, agents and skills use intended capabilities, and every runtime surface behaves as documented. |
| Operate | Disable, enable, project precedence, doctor, and remove behave truthfully. |
| Publish | A clean checkout installs locally without unpublished dependencies. |