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.

NeedContributionDesign question
Collect deterministic repository evidenceToolCan a bounded shell command express it safely?
Apply a review rubric or synthesize evidenceAgentWhich exact tools are necessary?
Teach a reusable workflow with referencesAgent SkillCan the user invoke it explicitly with $name?
React automatically after a lifecycle eventConfigured hook or trusted runtime hookDoes this need package-owned code or only a shell command?
Call a remote authenticated serviceMCP, Agent SDK tool, or trusted runtime providerWould a separate service boundary be easier to isolate and operate?
Add a new slash command, Ink view, shortcut, or CLI flagTrusted runtime entrypointCan users safely review and explicitly trust the emitted code?

Choose the trust boundary deliberately

LayerUse it forInstall decision
DeclarativeTools, agents, and Agent Skills expressible as bounded data and instructionsNormal validated install; no package code executes
Trusted runtimeSlash commands, Ink UI, line segments, shortcuts, flags, hooks, providers, and permission policyReview 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.

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

PhaseProof
ValidateGood package succeeds; an intentionally broken fixture fails without side effects.
InstallCopied and linked modes report the expected id, version, scope, trust, and state.
DiscoverA fresh process sees exact declarative and runtime identities with correct provenance.
AuthorizeEach handler shows expected prompts; denial prevents execution.
UseTools return bounded evidence, agents and skills use intended capabilities, and every runtime surface behaves as documented.
OperateDisable, enable, project precedence, doctor, and remove behave truthfully.
PublishA clean checkout installs locally without unpublished dependencies.