adeptability learns to publish, automate, and admit what it drops

  • ai
  • developer-experience
  • tooling
  • go
A single fountain pen writes one page, its ink lines fanning out into several threads that each end in a differently shaped robot head.

Since the last post, adeptability kept growing. Echo used it to consume shared skills. A month later we also publish them, automate around them, and trust it when a harness drops a file. Four threads carried that: publishable libraries, agents that compose into loops, honest rendering, and a scope split that keeps two things from sharing one directory.

Publishing a library, not only pulling one

The first post described consuming a library: commit a {name, remote, ref} reference, and adept resolves it into a per-machine store. It never covered who publishes that remote, which until 1.4 meant a hand-rolled repo with no template.

adept init --as-library scaffolds a repo meant to be that remote, with bundled library-management skills for the first contributor. A separate bug had status lumping private skills into library-skill counts, hiding the drift you need to spot; 1.4.1 fixed it. adept library update added a workflow: fetch every library, show what changed, ask before applying.

adept library update                # check every library, prompt before applying
adept library update org-std --yes  # apply without prompting

Publishing a library was possible by hand. Now it is a command, not a README nobody reads.

Scaffolding agents instead of hand-writing them

The library already carried one hand-written PR-reviewer subagent. Scaling past it meant a template, and 1.7 shipped it.

adept agent add pr-reviewer --template evaluator scaffolds a canonical subagent that renders into .claude/agents/, Cursor’s agents, Codex’s .toml format, and the rest: the same author-once model as skills. adept agent check runs a safety scan and a best-practice lint before you trust it with anything.

Loops got the same treatment: a discovery skill decides what to look at, an evaluator agent that can say no, and a schedule triggers the round. adept loop add stale-prs --workflow --edit scaffolds all three at once, plus a GitHub Actions cron skeleton for unattended runs. It also prints a first-loop checklist: state file, isolation, token cap, human review. A loop with no evaluator and no cap is not automation. It is an unsupervised script with better branding.

When a harness drops a file without saying so

Codex’s and Copilot’s renderers computed warnings when a skill’s sidecar files, scripts/ or references/, could not survive that harness’s format. Nobody read them: the warnings got built, then discarded before adept sync printed anything. A skill with a scripts/ directory rendered clean into Claude Code and silently lost the script in Codex.

A 1.6 fix wired those warnings into the sync summary and the JSON output. Losing a sidecar a harness format cannot represent is sometimes unavoidable; losing it silently is a bug.

Getting the binary onto every machine, properly

go install covers Go developers, not everyone else. 1.7 added a Nix flake, so nix profile install github:itaywol/adeptability works without that detour. 1.8 added completions everywhere the binary ships: Nix, the goreleaser archives, the Homebrew formula. Cobra generated them at runtime; packaging installs them.

Then the release pipeline broke itself: cosign v3 defaults to the sigstore bundle format and refused to sign without --bundle, breaking the 1.8 release. The fix pins --use-signing-config=false --new-bundle-format=false, keeping the .sig/.pem outputs install.sh verifies. A dependency bump breaking the release signer made for a fun Saturday.

Proving it works instead of describing it

None of this shows up in a bullet list, so the README got a demo GIF: one canonical skill, adept sync, rendered into Claude Code, Cursor, Codex, and OpenCode in one recording. assets/demo.sh reproduces it exactly, built with asciinema piped through agg: a real session replayed on demand, not hand-edited marketing.

adept sync rendering one skill into four harnesses

Two different things sharing one directory

This one had been there the whole time: skills lived in a per-machine store, but libraries lived there too. One project’s adept library update could yank a ref out from under a project counting on it to stay put.

1.9 splits the two. Libraries clone into .adeptability/libs/ inside the project by default, .adeptability/.gitignore kept in sync automatically, and adept migrate re-clones configured libraries from the machine store into the project. The machine store still exists for skills: --global on sync, status, and the rest of the CLI manages one skill set across every project. Agent subcommands, loop add, and hook install stay project-scope: a global agent or hook never made sense.

Current build is 1.9.0: install via go install, Homebrew, the curl installer, or the Nix flake, listed in the README. Docs cover every command; the project page has the design decisions, if the changelog is not enough.

The adeptability docs site