1. The block, verbatim
Writing more than about three memories in one task? Call memhtml apply once with a JSONL op stream instead of running memhtml write N times. A batch stages every file, makes ONE commit, and reindexes ONCE, where N separate writes make N commits and pay N index passes over N diffs. Pass the stream as memhtml apply --file ops.jsonl, or pipe it: memhtml apply - and a bare memhtml apply both read stdin. One complete JSON object per line, no wrapping array, no pretty-printing. A line looks like this:
{"op":"write","title":"One writer and many readers share the index","type":"semantic","body":"WAL admits a single writer at a time and any number of concurrent readers, so a CLI command and a running `memhtml serve mcp` can work against one store.","tag":"infra"}op is write (the only verb in the vocabulary today), title and type are required, and each op carries the same optional fields memhtml write takes, in snake_case: path, strict_path, workspace, tag, entity, importance, confidence, status, due, session_id, prompt_id, turn_uuid. The whole file is validated for shape before ANY op executes, so a malformed line 7 is exit 2 naming line 7 with nothing written. A failed apply costs you nothing but the call. You get one result per op in INPUT ORDER, each naming its own index, so you can match results back to the lines you sent. A batch is ATOMIC by default: the first refused op aborts the whole batch, no file is written, no commit is made, and the surviving ops report skipped: true. Pass --continue-on-error for best-effort instead, and a refused op comes back as one failed result carrying its own code and error while every op that succeeded lands in the one commit. A duplicate is never an error: an op whose exact content is already stored comes back ok: true with deduped: true and the existing path, so re-applying a file you already applied is safe and writes nothing. commit_sha is null exactly when nothing was committed: a batch that only deduped, or one that aborted.
2. Commands it names
3. Provenance
A loader generates this page from apps/cli/src/commands.ts while the site builds, so no file in the repository holds it: the block is authored beside COMMANDS and is served verbatim by memhtml manifest, so this page and the live answer are the same bytes. Change the registry and this page changes with it.