@mergd/ap
v0.3.9
Published
Agent-portable local secrets — bundles, show, ap run
Readme
ap
Agent-portable local secrets. Declare bundles of credentials in committed manifests, store global secret values inline in TOML, and keep project secrets in .ap/secrets.json. Agents check readiness with ap show <bundle> --check before calling external APIs.
Install
Requires Node 18+.
npm install -g @mergd/apFrom source:
git clone https://github.com/mergd/ap.git
cd ap
npm install
npm run build
npm link # or: ln -sf "$(pwd)/bin/ap" ~/.local/bin/apQuick start
Agents: run ap guide first (YAML contract for show → run → set).
# Optional: seed catalog var stubs into the global manifest
ap init -g # all catalog vars → ~/.config/ap/manifest.toml
# ap init -g cloudflare # or pick a catalog bundle's vars
# Per repo (catalog owns bundle identity — no need to copy [bundle.*] globally)
ap init # ap.toml + .ap/ + project agent skill
# edit ap.toml → bundles = ["namecheap", "cloudflare"]
eval "$(op signin)"
ap setup # SOPS + 1Password — safe to commit .ap/secrets.json
# Set project secrets (default → .ap/secrets.json)
echo "$TOKEN" | ap set DEPLOY_TOKEN
# Set deliberately shared credentials globally (explicit opt-in)
echo "$NC_API_KEY" | ap set NC_API_KEY --global
echo "$KEY" | ap set CF_GLOBAL_API_KEY --global
# Inspect secrets and check readiness
ap show --check
ap show cloudflare --check
# Run commands with secrets injected
ap run cloudflare -- curl ...Install the agent skill (Cursor, Claude Code, Codex):
ap skill install # ~/.agents/skills/ap/ (+ symlinks for claude/cursor)
ap skill install --project # same paths under current reponpm install -g @mergd/ap runs ap skill install via postinstall (global). ap init installs the skill into the repo.
How it works
Bundles group related env vars for a capability (e.g. namecheap → NC_API_USER, NC_API_KEY, NC_CLIENT_IP). Bundle identity (keys, ask/docs/prompt) lives in the built-in catalog; the global manifest only stores var stubs and values.
| File | Purpose |
|------|---------|
| ~/.config/ap/manifest.toml | Global public vars and secret values (value =) |
| ap.toml | Which bundles this repo uses; project var declarations; [encryption] for 1Password age key |
| .ap/secrets.json | Project vault — all project-scoped secrets (SOPS after ap setup) |
| .sops.yaml | SOPS encryption rules (committed after ap setup) |
There is no global secrets.json. Project secrets always live in .ap/secrets.json:
# ap.toml
version = 1
scope = "project"
[var.DEPLOY_TOKEN]
visibility = "secret"
ask = "Deploy token for this repo"echo "$TOKEN" | ap set DEPLOY_TOKENProject secrets use SOPS + age with the private key in 1Password (same pattern as lockbox). Run ap setup once per repo; teammates need op access to decrypt.
Public bundle values surface immediately in ap show. Secrets are never shown — only status and set_with commands.
ap guide # agent contract
ap catalog # built-in templates
ap help # full command referenceCommands
ap -V, --version Print version and update status
ap guide [--human] Agent contract (primary entrypoint for agents)
ap show [BUNDLE] [-g] [--check] [--validate]
ap catalog
ap set KEY [-g|--global|--project] [--from-env]
ap load env [-g|--global]
ap unset KEY [-g|--global|--project]
ap run [BUNDLE] -- <cmd...>
ap init [-g|--global] [BUNDLE...]
ap setup
ap edit <secrets|global|project> [--ui] [--port N] [--no-open]
ap skill install [--project]ap set and ap unset default to the current repo vault (.ap/secrets.json). -g is short for --global and is required to modify the global manifest. --project remains as an explicit, backward-compatible spelling of the default.
ap load env adopts every variable declared in the selected manifest from the process environment without printing values. It defaults to project scope; use --global for the global manifest.
Hooks
ap set and ap unset run a script if you bind one. after_run fires after ap run in the background and never fails the command.
# ap.toml
[hooks]
after_set = ".ap/hooks/sync"
after_unset = ".ap/hooks/sync"
after_run = ".ap/hooks/sync"# .ap/hooks/sync
#!/bin/sh
git pull --rebase && git pushchmod +x .ap/hooks/sync. If [hooks] omits an event, ap still runs .ap/hooks/<event> when that file exists. after_set / after_unset fail closed. before_show is opt-in (warns and continues). after_run is detached: handle errors in the script. Set after_set = "none" or AP_NO_HOOKS=1 to disable.
ap edit --ui opens a local Bootstrap-era page on 127.0.0.1 to edit project ap.toml (or -g / global for manifest.toml, including global secret values).
Output is human-readable in a terminal and YAML when piped. Catalog bundles: cloudflare, namecheap, openrouter.
ap checks npm for updates at most once per day and prints upgrade notices to stderr. Set AP_NO_UPDATE_CHECK=1 to disable the check.
Development
npm install
npm run build
npm test
npm run check
npm run dev -- showLicense
MIT
