Skip to content

Add "aperture skills install" to generate agent skills - #28

Open
douglance wants to merge 1 commit into
tailscale:mainfrom
douglance:skills-install
Open

Add "aperture skills install" to generate agent skills#28
douglance wants to merge 1 commit into
tailscale:mainfrom
douglance:skills-install

Conversation

@douglance

Copy link
Copy Markdown

What

Adds aperture skills install, a subcommand that generates agent skills describing the launcher and installs them into the skill directories of the coding agents on the machine.

Coding agents load skills from a shared directory (~/.agents/skills, linked into each agent's own directory), but nothing there described this launcher. An agent working alongside aperture had no way to know the endpoint model, the bridge flow, or why a launch env var looks the way it does.

Five skills, split by component

Skill Covers
aperture What it is, commands, key map, launch sequence
aperture-agents Agent table, provider types, install/uninstall, YOLO mode
aperture-endpoints Add/activate/delete, Direct vs Bridge
aperture-bridges Bridge setup and auth, ts-unplug
aperture-troubleshooting Failure modes, state files, limits

Splitting keeps each one to roughly 40–60 lines, so an agent loads the part it needs rather than the whole manual. The core skill links the others.

Content is generated, not checked in: the agent table comes from clients.All, and the endpoint and config paths come from the loaded config. A skill therefore cannot describe an agent this build does not support, or an endpoint the user is not on.

Not deleting other tools' skills

~/.agents/skills is shared, so an install can collide with a skill another tool wrote, or one a user wrote by hand. Every destructive step is guarded:

  • Each installed directory carries an ownership marker (.installed-by.json).
  • A directory is replaced only when it carries our marker. Another tool's marker, or no marker at all, is a conflict: reported, not overwritten. -force overrides and reports what it replaced.
  • Conflicts across all five skills are checked before the first write, so a conflict in the last cannot leave the first four applied.
  • Pruning a renamed skill follows the same rule — only our own marked directories are removed.
  • remove lstats and unlinks symlinks rather than following them, so removing a link never reaches into its target.

Notes

  • The subcommand is dispatched before flag.Parse, so the TUI path is untouched. Running aperture with no arguments behaves exactly as before.
  • go build ./..., go vet ./..., and gofmt are clean. go test ./... passes 120 tests across 13 packages — 99 existing, 21 new.

One question for maintainers

The generated skill tells readers that a Claude subscription cannot be used through the launcher, because envForBackend sets ANTHROPIC_AUTH_TOKEN: "-" for the anthropic backend (internal/clients/claudecode/env.go:13) and that placeholder takes precedence over the subscription's OAuth token. That is correct when the gateway holds an API key, but it conflicts with the passthrough setup described in Route a Claude subscription through Aperture, which says to set neither ANTHROPIC_API_KEY nor ANTHROPIC_AUTH_TOKEN.

If passthrough is meant to work through the launcher, the fix is probably to omit the placeholder when the selected provider is in passthrough mode — happy to follow up with that in a separate PR. If it is intentionally out of scope, I will keep the skill's wording as-is.

Coding agents can load skills from a shared directory, but nothing
described this launcher to them. This adds a subcommand that generates
skills from the launcher's own state and installs them for the agents
present on the machine.

Five skills, split by component, so an agent loads only the part it
needs: the launcher itself, agents, endpoints, bridges, and
troubleshooting. Content is generated rather than checked in — the agent
table comes from the client registry, and the endpoint and config paths
come from the loaded config, so a skill cannot describe an agent this
build does not support.

Installing writes to ~/.agents/skills, which other tools also write to,
so every destructive step is guarded. Each directory gets an ownership
marker, and one is only replaced when it carries our own marker.
Directories belonging to another tool, and unmarked ones a user wrote by
hand, are reported as conflicts and left alone; -force overrides.
Conflicts across all five skills are checked before the first write, so
a conflict in the last cannot leave the first four applied. Pruning a
renamed skill follows the same rule: only our own marked directories are
removed.

The subcommand is dispatched before flag.Parse, leaving the TUI path
untouched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant