UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

322 lines (258 loc) • 15 kB
# Bundles akm works toward two outcomes: bring the agent assets you already have into one library, and install (or share) reusable capability bundles with other people. Both go through the same primitive — a **bundle** — which can be a local directory, a git repo, an npm package, or a crawled website. **Registries** are discovery indexes that let you find bundles you haven't heard of yet. Together they give you a unified, searchable library that pulls from anywhere and grows over time. ## Bring what you already have into one library If you already have skills, commands, or agent configs scattered across different tools, point akm at each of them. Nothing moves — akm indexes assets in place — and every asset becomes retrievable through the same search and curate commands regardless of which agent originally created it. ```sh akm bundle add ~/.claude # Claude Code's project/user assets akm bundle add ~/.config/opencode # OpenCode's config directory akm index # Bring the search index up to date akm curate "plan a release" # Pull the best matches from every bundle you added ``` This is the "one library for every agent" idea in practice: assets authored for one tool become discoverable — and usable — from any other. ## akm bundle add `akm bundle add` connects a new bundle. The source kind is inferred from the input: known git hosts and URLs ending in `.git` are git bundles, while other HTTP(S) URLs are website bundles. ```sh akm bundle add ~/.claude/skills # Local directory (filesystem) akm bundle add github:owner/team-bundle # GitHub repo (git) akm bundle add @scope/bundle # npm package akm bundle add npm:@scope/bundle@latest # npm with version pin akm bundle add github:owner/repo#v1.2.3 # GitHub at a specific tag akm bundle add https://docs.example.com --name docs # Crawled website (website) akm bundle add https://docs.example.com --max-pages 200 --max-depth 5 # Add the official onboarding bundle: akm bundle add github:itlackey/akm-stash # Mark a git bundle as writable (enables akm sync to push): akm bundle add git@github.com:org/skills.git --provider git --name my-skills --writable # Authenticate an HTTPS Git bundle without storing a token in its URL: GIT_READ_TOKEN=... akm bundle add https://github.com/org/private.git --provider git \ --name private --credential '$GIT_READ_TOKEN' # Control secondary-bundle resolution priority (the default bundle is always first): akm bundle add github:owner/team-bundle --name team --before community ``` | Bundle kind | Input shape | Behavior | | --- | --- | --- | | `filesystem` | local path | Indexed in place, writable by default | | `git` | `github:`, known git-host URL, or URL ending in `.git` | Cloned into `~/.cache/akm/registry/`, read-only by default | | `npm` | `@scope/pkg` | Installed into cache, read-only | | `website` | Other HTTP/HTTPS URL | Crawled, converted to markdown, refreshed every 12 hours | `akm bundle add` materializes and indexes Git install refs before it reports success. A declarative `--provider git` add does the same, including writable checkouts. Other declarative provider entries are materialized by `akm bundle update`. **Bundle naming.** `--name` sets the bundle's key — akm's config, index, and every persisted ref hang off it. It is a contract, not a hint: it must be a legal bundle slug (no `:` `.` `#` `/` or whitespace), and it must not already be taken by a different bundle, or the add fails before writing anything. Re-adding a source that is already installed under a different `--name` than it already carries also fails, naming the existing key — use [`akm bundle rename`](#akm-bundle-rename) instead of trying to relabel it through `add`. Every `akm bundle add` result carries `bundleId` (its resolved key), so scripting against the JSON output never has to guess it back out of `sourceAdded`/`installed`. Without `--name`, akm derives one (the directory name, the package/repo name, or the hostname), falling back to a `-<hash>` suffix only on a collision — that forgiving fallback applies solely to a derived name, never to an explicit `--name`. Git credentials must be symbolic references: `$VAR`, `${VAR}`, or `secret://name`. AKM resolves the reference only at the Git subprocess boundary and sends it as an HTTPS bearer header; it does not put the token in the remote URL or `config.json`. **Website bundles.** A `website` URL is offered to a set of specialized fetchers (YouTube, Bluesky, X, RSS/Atom feeds) before falling back to a general crawl, and crawl behavior (page/depth limits, timeouts, robots.txt) is configurable. See the [website source recipe](recipes/website-source.md) for a walkthrough and [Website Sources](../reference/website-sources.md) for the full fetcher reference, X credential setup, and crawl-option details. Low-level knobs like `crawlTimeoutMs` and `respectRobots` live in the bundle's `website` descriptor — see [Configuration](../reference/configuration.md). **Example: add a team bundle from GitHub** ```sh akm bundle add github:my-org/team-bundle --name team akm index akm search "deploy" --type script ``` ## akm bundle list `akm bundle list` shows all configured bundles — local directories, managed packages, and remote providers — so you know what is in your library. ```sh akm bundle list # All bundles akm bundle list --kind filesystem # Only local directories akm bundle list --kind git # Only git-cloned bundles akm bundle list --kind npm # Only npm packages akm bundle list --kind filesystem,git # Multiple kinds (comma-separated) ``` Valid `--kind` values are the four bundle providers: `filesystem`, `git`, `npm`, `website`. ## akm bundle update / akm bundle remove `akm bundle update` refreshes git, npm, and website bundles. Each candidate is staged outside its active root, audited for dangerous environment keys, and only then published and indexed. `akm bundle remove` disconnects a bundle and re-indexes without it. Bundle refresh is deliberately explicit: Git bundles do not poll upstream on their own. Consumers that want automatic refresh should schedule `akm bundle update <name>` or `akm bundle update --all`. Scheduled invocations should pass `--skip-if-locked` so concurrent index or improve activity becomes a successful skip instead of exit 75. ```sh # Update akm bundle update @scope/bundle # One managed bundle akm bundle update --all # All managed bundles akm bundle update --all --force # Force fresh download even if version unchanged akm bundle update --all --skip-if-locked # Scheduled refresh: exit 0 on DB contention akm bundle update @scope/bundle --allow-dangerous-env-keys # Approve reviewed dangerous env keys # Remove akm bundle remove @scope/bundle # By npm id akm bundle remove github:owner/repo # By git ref akm bundle remove ~/.claude/skills # By path akm bundle remove my-provider # By name ``` Dangerous keys prompt in a terminal (default: No) and block non-interactive updates unless `--allow-dangerous-env-keys` is explicit. `--yes` only approves deletion of an obsolete moved install directory; it never approves security findings. For `--all`, blocked and failed bundles are reported separately and later bundles continue. A rejected or failed bundle keeps its prior bytes, lock/config state, and search-index generation. Private bundles that intentionally version every file under `env/` and `secrets/` can place this documented marker anywhere in their root `.gitignore`: ```gitignore # akm: intentionally track env and secrets ``` The stash scaffold then leaves the ignore file unchanged. Use this only for a private remote whose exposure policy you have reviewed. During publication AKM holds a SQLite writer transaction across the index and the update-owned state work. Existing readers keep seeing the prior generation, but other writers may wait for a full index pass. This provides process-fault rollback for handled errors, not atomic durability across the filesystem and two WAL database files during `SIGKILL`, power loss, or storage failure. After such a failure, stop writers, run `akm health`, rerun the targeted update if its checkout/lock is not the intended revision, and run `akm index --full`. The `index-state-generation` advisory detects mismatched durable usage links; it cannot detect every theoretical cross-file split. **Example: keep bundles fresh** ```sh akm bundle update --all && akm index ``` ## akm bundle rename `akm bundle rename <old> <new>` is the one command allowed to change a configured bundle's key. A bundle id is a mass identity prefix: every ref this tool minted (`entries.item_ref`, `proposals.ref`, a pending proposal's write target, a workflow's `task_history.target_ref`, `scheduler.enabled[].ref`) carries it, so hand-editing the `bundles` key in `config.json` strands all of it — the rest of akm keeps reading the old prefix out of the index and state databases while config names the new one. ```sh akm bundle rename old-name new-name --dry-run # See the plan first akm bundle rename old-name new-name ``` `<new>` must be a legal, unused bundle slug — the same `--name` contract `akm bundle add` enforces. Rewritten: the config key, `defaultBundle`/`defaultWriteTarget` when they name the old id, every scheduler ref, the lockfile entry, every indexed entry's `bundle_id`, and this tool's own state rows that name the old bundle. Reported, never rewritten: refs inside the bundle's own content (cross-references, a task's `uses:`, `supersededBy`) — the command lists the files that still spell the old `<old>//` prefix so you can fix them by hand. A real run also re-syncs native scheduler bindings under the new name on its own, so scheduled tasks pick it up immediately — but the result's `taskSync.ok` is `false` when a binding fails to re-sync too, not only when the sync call itself fails, so a partial re-sync is never reported as clean; `--dry-run` lists the installed native rows that still name the old bundle, so you can see what that sync will replace. ## akm clone `akm clone` copies a single asset from any bundle into your writable bundle (or a custom destination) for local editing. After cloning, your local copy wins in subsequent searches automatically. ```sh akm clone scripts/deploy.sh akm clone skills/code-review --name my-code-review akm clone scripts/deploy.sh --dest ./project/.claude akm clone "npm:@scope/pkg//scripts/deploy.sh" # From uninstalled package ``` Clone is non-destructive: use `--force` to overwrite an existing local copy. Skills (directories with `SKILL.md`) are copied recursively. All other types copy a single file. **Example: clone and customize a workflow** ```sh akm clone workflows/ship-release --dest ./project/.claude # Edit ./project/.claude/workflows/ship-release.md # The local copy wins in searches from this directory forward ``` ## akm sync `akm sync` stages, commits, and optionally pushes your writable bundle. It is the complement to `akm bundle add`: once you have made changes locally, `sync` persists them to git. (There is no `akm save` command — use `akm sync`.) ```sh akm sync # Primary bundle, auto timestamp message akm sync -m "Add deploy skill" # Custom commit message akm sync my-skills -m "Update" # Named writable git bundle ``` Push behavior depends on configuration: if the bundle is a git repo with a remote and `writable: true`, sync also pushes. Otherwise it commits only. Writes that land on a writable git bundle via an explicit destination flag (e.g. `akm remember --bundle my-skills`, proposal accept/revert, consolidate) are committed automatically in a single batch at the end of the operation — one complete commit (staging `.akm/` + assets together), pushed under the same `writable + remote` gate as `akm sync`. `options.pushOnCommit` is rejected at config load; remove it and rely on `writable: true` + push instead. **Example: publish your own bundle** ```sh # One-time setup (git-descriptor primary bundles only): mark it writable by # setting bundles.<name>.writable: true in ~/.config/akm/config.json. # A filesystem-type primary bundle is already writable by default. akm sync -m "Add deployment skills" # → stages, commits, and pushes to your configured remote ``` For the full workflow of turning a bundle into something others can install — manifest conventions, versioning, and publishing to a registry — see the [Bundle Author's Guide](author-bundles.md). For how a bundle's provider kind maps to the code that indexes and fetches it, see [Architecture](../architecture/architecture.md). ## Install and share reusable capability bundles The other half of the bundle story is discovery: finding bundles other people have published, and publishing your own so others can install it. `akm bundle add` (above) is how you install one once you know where it lives; the registry (below) is how you find it in the first place. ## akm registry The registry is a discovery index — it lets you find and install bundles you don't know about yet. The official registry ships pre-configured. ```sh akm registry list # See configured registries akm search "deploy" --from registry # Search registry bundles by topic akm search "code review" --from registry --assets # Include asset-level hits akm registry add https://example.com/registry/index.json --name my-team akm registry remove my-team ``` Once you find an interesting bundle in the registry, install it with `akm bundle add`: ```sh akm search "kubernetes" --from registry akm bundle add github:some-org/k8s-bundle akm index ``` For the registry index schema, hosting a private registry, and how entries get discovered, see [Registry](../reference/registry.md). ## See also - [Discover & Load](discover-and-load.md) — querying the index after bundles are connected - [Knowledge Management](knowledge-management.md) — writing your own assets - [Use akm With Any Agent](use-with-any-agent.md) — using refs across bundles in prompts - [Website Source Recipe](recipes/website-source.md) — walkthrough for adding a crawled website bundle - [Website Sources](../reference/website-sources.md) — fetcher reference, X credentials, crawl options - [Configuration](../reference/configuration.md) — bundle descriptor fields including `website` crawl knobs - [CLI Reference](../reference/cli.md) — full flag documentation for `add`, `list`, `update`, `remove`, `clone`, `sync`, `registry` - [Registry](../reference/registry.md) — registry index format and private registry setup - [Bundle Author's Guide](author-bundles.md) — build and publish your own bundle - [Architecture](../architecture/architecture.md) — how bundle providers are implemented