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
268 lines (213 loc) • 13 kB
Markdown
Migration notes for akm v0.7.0
0.7.0 is the last pre-1.0 ship in the v1 cycle. It introduces the
proposal queue, agent reflection commands, the `lesson` asset type, the
`llm.features.*` per-call-site gates, and the first cut of `akm-bench`.
It also rolls in a batch of pre-prod hardening (security, UX, hygiene)
landed via PR #275.
The CLI surface, configuration schema, provider interfaces, and ref
grammar continue to match the v1 architecture spec
([`docs/technical/v1-architecture-spec.md`](https://github.com/itlackey/akm/blob/v0.7.0/docs/technical/v1-architecture-spec.md)).
0.7.0 commits to maintaining those surfaces through the 0.8.x / 0.9.x
pre-releases — the formal freeze itself happens at 1.0 GA.
If you are coming from 0.6.x, the
[archived pre-1.0 migration plan](https://github.com/itlackey/akm/blob/be3a6a632b0cbe7a63ce71b7d093d8ac266e857c/docs/archive/pre-1.0-migration.md) covers the historical per-surface delta and is the
canonical upgrade reference. This file is the executive summary of
what's new in 0.7.0.
For stash authors on the 0.7.x pre-release line: `.stash.json` remains supported
for compatibility in this release, but it is deprecated and will be removed in
v0.8.0. That timeline is intentional: during this aggressive pre-release
phase-out window, compatibility shims do not stay around until 1.0 unless they
still earn their cost. Prefer frontmatter for markdown assets and structured
code comments for scripts, and migrate any remaining `.stash.json` metadata
before taking the 0.8 upgrade.
## Major new surfaces in 0.7.0
### Proposal queue (`akm proposal *`) — new (#225, #226, #233)
All proposal-producing commands (`akm reflect`, `akm propose`,
`akm distill`, plus any plugin-emitted proposals) write through one
durable queue. The queue lives outside the asset tree so unaccepted
drafts never leak into search or commits. Promotion runs full validation
**before** routing through `writeAssetToSource()` — the same single
write path used by `akm remember` and `akm import`.
```sh
akm proposal list # list pending proposals
akm proposal show <id> # render one proposal
akm proposal diff <id> # diff vs. the live ref
akm proposal accept <id> # validate, then promote
akm proposal reject <id> --reason "…" # archive with reason
```
Multiple proposals for the same `ref` coexist without filesystem
collisions. Auto-accept is gated per-source via the source config
(`autoAcceptProposals: true`); the default is off and requires a
writable source. See the archived pre-1.0 migration spec §11 at
`docs/archive/pre-1.0-migration.md`.
### `akm reflect`, `akm propose`, `akm distill` — new CLI surfaces (#225, #226, #227)
Three new commands produce proposals into the queue:
```sh
akm reflect [ref] [--task ...] # reflection proposals — doclint:ignore (0.7.0-era, folded into `akm improve` later)
akm propose <type> <name> --task "..." # generation proposals — doclint:ignore (0.7.0-era spelling; moved to `akm proposal new` in 0.9.0)
akm distill <ref> # bounded LLM → `lesson` proposal — doclint:ignore (0.7.0-era, folded into `akm improve` later)
```
`reflect` and `propose` shell out via the agent CLI (`agent.*` config,
spec §12) and write **only** to the proposal queue — they never mutate
live stash content. `distill` is the canonical bounded in-tree LLM call
gated behind `llm.features.feedback_distillation`. All three emit usage
events (`reflect_invoked`, `propose_invoked`, `distill_invoked`). See
v1 spec §11.3 and §12.4.
### `lesson` asset type — new (#227)
`lesson` is a first-class well-known type with required frontmatter
`description` and `when_to_use`. Lessons are stored under
`lessons/<name>.md` in the working stash, parallel to `memories/`.
Normally produced by `akm distill <ref>` as a `proposed`-quality
proposal and promoted via `akm proposal accept`. Direct authoring via
`akm import` and `akm remember`-style flows is also supported. See v1
spec §13.
### `llm.features.*` map with default-false gates — new (#227)
Every bounded in-tree LLM call site is gated behind exactly one feature
flag. All defaults are `false` so adding the schema is a non-event
until the user opts in. Seven keys ship in 0.7.0:
| Key | Use site |
| --- | --- |
| `curate_rerank` | LLM rerank in `akm curate` |
| `tag_dedup` | LLM tag dedup during indexer enrichment |
| `memory_consolidation` | `akm remember --enrich` consolidation |
| `feedback_distillation` | `akm distill <ref>` |
| `embedding_fallback_score` | scorer fallback when embeddings unavailable |
| `memory_inference` | indexer split of pending memories into atomic facts |
| `graph_extraction` | indexer entity/relation extraction → SQLite graph tables |
Every gated call site uses `tryLlmFeature(feature, config, fn, fallback)`
from `src/llm/feature-gate.ts`. The wrapper guarantees:
- **Disabled** → `fallback` is returned without ever calling `fn`.
- **Throw** → the error is swallowed; `fallback` is returned.
- **Timeout** → a 30-second hard timeout (override via `timeoutMs`)
raises `LlmFeatureTimeoutError`; `fallback` is returned.
Failure events surface through an optional `onFallback` sink so callers
can emit a structured `warnings` entry. See v1 spec §14.
### `quality: "proposed"` and `--include-proposed` — new
`SearchHit.quality` is an open string set with three well-known values:
`"generated"`, `"curated"`, and `"proposed"`. The first two are
included in default search; `"proposed"` is **excluded from default
search** and surfaces only via `akm search ... --include-proposed` or
via `akm proposal *`. Unknown values parse-warn-include — they remain
searchable so plugin authors can introduce new values without crashing
the indexer. `SearchHit` gains optional `quality?` and `warnings?`
fields. See v1 spec §4.2.
### `akm-bench` v1 — new (#234, PRs #266 / #268 / #269)
Bench grows beyond the 0.6.x smoke run into a paired-utility framework:
- **Track A — paired noakm/akm runs.** For each task, bench runs an
agent CLI twice (without and with akm available), captures
per-tool-call utility, and emits a comparable score pair.
- **Track B — registry attribution.** Utility deltas are mapped back
to specific `[origin//]type:name` refs so operators can see which
assets actually contributed.
- **`akm-bench compare`** aggregates paired runs into a delta report.
- **`akm-bench attribute`** surfaces the per-ref attribution report.
- **`akm-bench evolve`** is a stub for the closed-loop evolution
workflow that lands in 0.8.
The bench technical reference lives in
[`docs/technical/benchmark.md`](https://github.com/itlackey/akm/blob/v0.7.0/docs/technical/benchmark.md).
### Removed legacy fields
- The legacy registry boolean `curated` is removed. Legacy v2 index
JSON parses and silently ignores it. Renderers no longer surface a
`curated` column; the per-asset `quality` field replaces it.
Publishers do not need to migrate existing JSON.
- Earlier 0.7.x pre-release work (#220–#223) finalised the registry
curation surface removal, classification pipeline rewrites, and
error envelope shape that 0.7.0 ships. Operators upgrading from a
0.6.x baseline should read the [archived pre-1.0 plan](https://github.com/itlackey/akm/blob/be3a6a632b0cbe7a63ce71b7d093d8ac266e857c/docs/archive/pre-1.0-migration.md) for
the per-surface migration recipe.
### CLI surface as of 0.7.0
```
add | remove | list | update | search | show | clone | index | setup |
remember | import | feedback | info | curate | workflow * | vault * |
wiki * | enable | disable | completions | upgrade | save | help |
hints | config * | registry * |
agent | reflect | propose | proposal * | distill
```
This is the surface 0.7.0 commits to maintain through 0.8.x / 0.9.x.
Renaming or removing any of these commands at 1.0 GA would be a major
version bump.
## Post-0.7.0 additive surfaces
These landed after the 0.7.0 cut without changing the existing command grammar:
- `akm import <url>` now fetches one HTTP/HTTPS URL, converts it to markdown,
and writes it into `knowledge/` using a URL-path-derived default name.
- `akm wiki stash <name> <url>` now fetches one HTTP/HTTPS URL, converts it to
markdown, and writes it into `wikis/<name>/raw/`.
- Both flows are one-shot ingest only: they do not register a persistent
website source and they do not crawl linked pages.
- Website source sync (`akm add <url> --provider website`) and one-shot URL
ingest now share the same `src/sources/website-ingest.ts` module for URL
validation, fetch/convert, and mirror generation behavior.
## Pre-prod hardening (PR #275)
PR #275 batched five issues plus the bench tmp follow-up that operators
should be aware of:
### Security
- **#270 — git message sanitization.** Commit messages and remote URLs
written by akm are sanitized to prevent shell-substitution and
control-character injection through user-supplied content.
- **#271 — bench env isolation.** `akm-bench` runs each agent invocation
in a scrubbed environment so host secrets do not leak into bench
transcripts or paired-run logs.
- **#272 — LLM body redact + npm tarball host validation.** Outbound
LLM request/response bodies are redacted in error reporting before
surfacing to stderr or warnings, and `akm add npm:…` validates the
tarball download host against the configured npm registry rather
than blindly following arbitrary `dist.tarball` URLs.
### UX
- **#273 — workflow noise gate, sources deprecation warn, setup
`--help`.**
- `akm workflow next/complete/status` no longer print spurious
progress noise on quiet runs.
- Configs still using the legacy `stashes[]` key emit a single
deprecation warning per process (was: per call site).
- `akm setup --help` now renders the same help block as `akm setup`
with no args plus the documented agent-detection summary.
### Hygiene
- **#274 — tsconfig + HF pin + shapes throw.** `tsconfig.json` now
includes `tests/` so `bunx tsc --noEmit` covers test files. The HF
embeddings model is pinned to a specific revision to avoid silent
upstream changes. The output-shape registry now throws on a missing
shape rather than silently `JSON.stringify`-ing.
### Bench
- **#276 — bench tmp redirect.** `akm-bench` no longer writes scratch
state under `/tmp`; everything lands under the AKM cache dir
(`~/.cache/akm/bench/`) so cleanup is bounded and CI sandboxes that
ban `/tmp` writes work out of the box.
## Surfaces 0.7.0 commits to maintain (toward 1.0 GA)
These are the contract surfaces 0.7.0 ships and intends to carry
forward through the 0.8.x / 0.9.x pre-releases into 1.0 GA. They are
not yet frozen — the freeze happens at 1.0 — but operators authoring
against 0.7.0 should expect them to remain stable through the final
pre-release cycle. The full list lives in v1 spec §9.
1. `writable` defaults to `true` on `filesystem`, `false` otherwise.
2. Registry results are off by default in `akm search`; pass
`--include-registry` to merge them. Registry hits never land in
`hits` — they live under `registryHits`.
3. Write target resolves as `--target` → `defaultWriteTarget` →
working stash → `ConfigError`.
4. `writable: true` is rejected on `website` / `npm` at config load.
5. `SearchHit.score` is `[0, 1]`, higher = better. One scoring
pipeline for all indexed content.
6. Asset refs are `[origin//]type:name`. No URI schemes.
7. `quality: "proposed"` is excluded from default search.
8. External agents are CLI shell-out only. The in-tree LLM stays
bounded and stateless, gated per call site by `llm.features.*`.
## Manual actions
None for users on a 0.6.x or earlier 0.7.x pre-release with no `agent`
or `llm.features` blocks set. Everything new is opt-in.
If you want to use the new surfaces:
```sh
akm setup # detects installed agent CLIs;
# persists `agent.default`
akm config set llm.features.feedback_distillation true
akm distill memory:my-debugging-notes # produces a lesson proposal — doclint:ignore (0.7.0-era command + ref grammar, folded into `akm improve` / bundle refs later)
akm proposal list
akm proposal accept <id>
```
## Full migration guides
- [Archived pre-1.0 migration plan](https://github.com/itlackey/akm/blob/be3a6a632b0cbe7a63ce71b7d093d8ac266e857c/docs/archive/pre-1.0-migration.md) — per-surface delta from any 0.6.x
baseline. The canonical reference for upgrading.
- [v0.5 → v0.6](https://github.com/itlackey/akm/blob/main/docs/migration/v0.5-to-v0.6.md) — the older terminology cut and
registry schema v3.
- [v1 architecture spec](https://github.com/itlackey/akm/blob/be3a6a632b0cbe7a63ce71b7d093d8ac266e857c/docs/archive/v1-architecture-spec.md) —
the architecture contract that 0.7.0 commits to maintain through
1.0 GA.