What an extension can contribute

Extension API v1 has two security layers. Declarative contributions are validated as bounded data and require no code trust. A package may also declare compiled JavaScript runtime entrypoints, but Autohand activates them only after installation with --trust.

  • Tools expose a name, description, JSON Schema parameters, and a handler template.
  • Agents provide a focused system prompt, description, optional model, and tool allowlist.
  • Skills contribute portable SKILL.md instruction packages to $ suggestions and /skills.
  • Trusted runtime entrypoints can register slash commands, Ink views, status/help lines, keybindings, CLI flags, hooks, providers, and permission policy.
  • Provenance records the owning extension id, version, scope, package root, and contribution file.

Trusted runtime code is not sandboxed. It runs inside the Autohand process with the same operating-system access. Autohand never transpiles TypeScript or installs dependencies for an extension; declare compiled .js, .mjs, or .cjs files and review their bundled dependencies before trusting them.

Validate before installing

Validation is read-only. It parses the manifest, resolves every declared path, validates each contribution, checks handler safety, and reports the package identity and contribution counts without copying or executing anything.

autohand extensions validate ./path/to/extension
autohand extensions validate ./path/to/extension --json

Use JSON output in CI or packaging scripts. A validation failure exits non-zero and returns an actionable reason, such as an unknown manifest field, unsafe handler, missing contribution, duplicate name, path traversal, or incompatible API version.

Install at user or project scope

ScopeCommandStorageUse it when
Userautohand extensions install ./pkg$AUTOHAND_HOME/extensions, normally ~/.autohand/extensionsThe capability should follow you across workspaces
Projectautohand --path . extensions install ./pkg --scope project.autohand/extensions in the workspaceThe repository owns the capability or needs a pinned team setup

A normal install copies the entire package through a staging directory, validates the staged copy, and atomically renames it into place. Reinstalling identical content is idempotent. Replacing different installed content requires --replace.

autohand extensions install ./my-extension
autohand extensions install ./my-extension --scope project
autohand extensions install ./my-extension --replace

# Required when contributes.runtime is non-empty:
autohand extensions install ./my-runtime-extension --trust

Validation never imports a runtime entrypoint. Installing a runtime package without --trust fails closed. The trust decision is stored outside the package, survives disable/enable, and is removed with the installed extension.

Link during development

Use --link to install an explicit developer link instead of copying the package. Autohand records linked state under the selected extension root. Disabling or removing the extension removes only the registered link and state; it never deletes the source directory.

autohand extensions install ./my-extension --link
# Add --trust when the linked package declares runtime entrypoints:
autohand extensions install ./my-runtime-extension --link --trust
autohand extensions show company.my-extension
autohand extensions doctor

Development loop: edit the linked source, validate it, then use an interactive lifecycle mutation such as disable/enable to refresh the current session—or start a fresh session for release-grade verification.

Inspect and manage installed packages

autohand extensions list
autohand extensions list --scope project --json
autohand extensions show autohand.code-health
autohand extensions doctor
autohand extensions disable autohand.code-health
autohand extensions enable autohand.code-health
autohand extensions remove autohand.code-health --yes

show reports id, version, description, scope, state, linked/copied status, trust, package root, and active tools, agents, skills, and runtime entrypoints. doctor reports invalid state, manifests, contributions, package directories, unreadable roots, name conflicts, missing trust, and runtime activation failures.

Removal prompts in a top-level interactive terminal. Non-interactive removal must include --yes. The remove command also accepts the uninstall alias.

Use the same lifecycle inside a session

/extensions list
/extensions show autohand.code-health
/extensions validate ./path/to/extension --json
/extensions install ./path/to/extension --scope project --link --trust
/extensions doctor
/extensions disable autohand.code-health
/extensions enable autohand.code-health
/extensions remove autohand.code-health --yes

The slash command calls the same extension service as the top-level CLI. Successful mutations refresh declarative and runtime registrations in the active session, so stale tools, agents, skills, commands, UI, hooks, providers, and policy do not survive disable or removal.

Precedence and failure behavior

  1. Built-in tools, agents, skills, commands, providers, CLI flags, and reserved keybindings cannot be replaced.
  2. Existing standalone meta-tools and user or external agents remain ahead of declarative extension contributions.
  3. A project package replaces the same user extension id as one whole package.
  4. Package ids and contribution names are processed deterministically.
  5. Invalid, incompatible, unsafe, or conflicting packages contribute nothing and appear in doctor.
  6. Disabled packages remain inspectable but contribute no declarative or runtime capabilities.

One broken extension does not stop Autohand Code from starting. Discovery fails closed at the package boundary, so a partially valid extension never partially activates.

Authorization is never bypassed

Declarative tools run only when an agent or user invokes them. Parameter values are shell escaped and execution passes through tool availability checks, immutable security rules, the permission manager, pre-tool hooks, approval handling, lifecycle events, and usage accounting. An agent's tool list is only an allowlist resolved against the active, filtered registry.

A trusted runtime may contribute ordinary permission policy and hook/provider behavior, but it cannot replace the session permission mode, decision cache, built-in registrations, or immutable security blacklist. Those controls apply to actions routed through Autohand; they do not sandbox arbitrary code inside the trusted entrypoint.

For the authoring contract, continue to Extension API v1.