Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"source": "git-subdir",
"url": "https://github.com/underpass-ai/kmp.git",
"path": "plugins/kmp",
"ref": "v0.5.0"
"ref": "v0.5.1"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion plugins/kmp/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "kmp",
"displayName": "KMP",
"version": "0.5.0",
"version": "0.5.1",
"description": "Local-first agent memory that preserves what happened, when and why: wires the kmp MCP server, teaches the memory moves, opens memory in ChronoLoom, and diagnoses setup.",
"author": {
"name": "Underpass AI",
Expand Down
2 changes: 1 addition & 1 deletion plugins/kmp/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kmp",
"version": "0.5.0",
"version": "0.5.1",
"description": "Local-first agent memory that preserves what happened, when and why: wires the kmp MCP server, teaches the memory moves, opens memory in ChronoLoom, and diagnoses setup.",
"author": {
"name": "Underpass AI"
Expand Down
14 changes: 7 additions & 7 deletions plugins/kmp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ field-by-field model, safe fallbacks and worked examples.
| `/kmp:save` | Commits this project's memory to the repository, and shows the diff |
| `/kmp:restore` | Loads the memory committed in the repository back into the store |
| `/kmp:revert` | Reverts a decision without deleting it, so both states survive |
| `/kmp:uninstall` | Previews removal, protects memory first, and only applies when explicitly asked |
| `/kmp:uninstall` | Previews whole-install or one-store removal, refuses live owners, protects memory first, and only applies when explicitly asked |

Codex gets all ten as native `kmp-setup`, `kmp-doctor` and so on. Standalone
Codex keeps the equivalent `/kmp-*` prompts. Claude Code keeps `/kmp:*`
Expand Down Expand Up @@ -213,12 +213,12 @@ enabled plugin and a global `mcp_servers.kmp` table both claim the server, the
doctor names both owners and the global store-affecting environment instead of
declaring the setup healthy.

Two failures it names rather than leaving you to guess: a format-1 redb store,
which current KMP detects but deliberately does not open — Doctor points to the
KMP 0.3.2 export bridge and leaves the bytes untouched — and a session that
started before the registration changed and is still carrying the old
inventory. The second one cannot be fixed from inside the session; you have to
restart it.
Two failures it names rather than leaving you to guess: an unsupported store
format, which current KMP detects but deliberately does not open — Doctor
points to the external archive-export contract and leaves the bytes untouched
— and a session that started before the registration changed and is still
carrying the old inventory. The second one cannot be fixed from inside the
session; you have to restart it.

Run it directly, without a host:

Expand Down
10 changes: 7 additions & 3 deletions plugins/kmp/claude/commands/uninstall.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: Show what removing KMP from this machine would take — engines, stores, host wiring — saving the memory into the workspace first
argument-hint: "[--apply] [--purge] [--keep-memory]"
argument-hint: "[--store <absolute-path>] [--apply] [--purge] [--keep-memory]"
allowed-tools: Bash(kmp-mcp:*)
---

Expand All @@ -22,6 +22,9 @@ Then tell them, in a few lines:
merge, so it has to point somewhere new;
- **anything found twice.** Two engines is the shape that makes a live session
answer from an older binary than the one holding the fix;
- **the scope.** To remove one memory, require its absolute path and use
`--store <absolute-path>`. That mode must leave every other memory, engine,
plugin and host registration alone;
- **what this verb will not touch**: a committed bundle belongs to the
repository, a registration lives inside a host's own configuration file, and
a binary outside their home may be a package manager's. Each prints the
Expand All @@ -32,8 +35,9 @@ name. A copy nobody can find is not a copy.

If a store was kept because its export failed, say that plainly — nothing of
that memory was removed — and name the reported cause. If another process is
using the store, close the active agent sessions and run
`kmp-mcp uninstall --apply` from a plain shell.
using the store, name the owning host reported by the command. Never kill it.
Ask the user to stop or restart that host, then retry the same scoped command
from a plain shell.

Never run it with `--apply` or `--purge` on your own initiative — not when the
dry run looks harmless, and not to "finish the job". `--purge` skips the export
Expand Down
8 changes: 6 additions & 2 deletions plugins/kmp/codex/prompts/kmp-uninstall.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ Nothing is removed unless I pass `--apply`. Then tell me, in a few lines:
has to point somewhere new;
- anything found twice, especially two engines: that is how a live session
answers from an older binary than the one holding the fix;
- the scope: to remove one memory, require its absolute path and use `--store
<absolute-path>`. That mode leaves every other memory, engine, plugin and
host registration alone;
- what the verb will not touch — a committed bundle, a registration inside a
host's config, a binary outside my home — each with the command I run myself.

After `--apply`, tell me how many events were saved and into which file, by
name. If a store was kept because its export failed, say so plainly — none of
that memory was removed — and name the reported cause. If another process is
using the store, tell me to close the active agent sessions and run
`kmp-mcp uninstall --apply` from a plain shell.
using the store, name the owning host reported by the command. Never kill it.
Tell me to stop or restart that host, then retry the same scoped command from a
plain shell.

Never add `--apply` or `--purge` on your own initiative. `--purge` skips the
export, which is the one way this command loses memory for good.
Expand Down
6 changes: 3 additions & 3 deletions plugins/kmp/guide/memory.jsonl

Large diffs are not rendered by default.

38 changes: 24 additions & 14 deletions plugins/kmp/scripts/kmp-doctor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -261,26 +261,35 @@ else
fi

# FORMAT_VERSION names the layout, but it is not evidence that memory is
# absent. Discover physical engine files independently first: a missing,
# corrupt or newer stamp must never turn a real store into "empty".
REDB_STORE="$DATA_DIR/store/kernel.redb"
# absent. Discover the SQLite file and any unsupported artifacts first: a
# missing, corrupt or newer stamp must never turn real bytes into "empty".
SQLITE_STORE="$DATA_DIR/store/kernel.sqlite3"
UNSUPPORTED_STORE=""
if [ -d "$DATA_DIR/store" ]; then
while IFS= read -r artifact; do
UNSUPPORTED_STORE="$artifact"
break
done < <(find "$DATA_DIR/store" -maxdepth 1 -type f \
! -name 'kernel.sqlite3' ! -name 'kernel.sqlite3-wal' ! -name 'kernel.sqlite3-shm' \
! -name 'kernel.sqlite3-journal' \
-print 2>/dev/null | LC_ALL=C sort)
fi
STORE_FILE=""
ENGINE=""
PHYSICAL_STORES=0
if [ -f "$REDB_STORE" ]; then
STORE_FILE="$REDB_STORE"; ENGINE="redb"
if [ -n "$UNSUPPORTED_STORE" ]; then
STORE_FILE="$UNSUPPORTED_STORE"; ENGINE="unsupported"
PHYSICAL_STORES=$((PHYSICAL_STORES + 1))
fi
if [ -f "$SQLITE_STORE" ]; then
STORE_FILE="$SQLITE_STORE"; ENGINE="sqlite"
PHYSICAL_STORES=$((PHYSICAL_STORES + 1))
fi
if [ "$PHYSICAL_STORES" -gt 1 ]; then
fail "multiple engine files exist; refusing to guess which memory is live"
fail "SQLite and unsupported storage artifacts coexist; refusing to guess which memory is live"
SESSION_USABLE=0
SESSION_REASON="the data dir contains both redb and sqlite store files"
info "$REDB_STORE"
SESSION_REASON="the data dir contains conflicting storage artifacts"
info "$UNSUPPORTED_STORE"
info "$SQLITE_STORE"
fi

Expand All @@ -290,12 +299,13 @@ else
if FORMAT="$(tr -d '[:space:]' < "$DATA_DIR/FORMAT_VERSION" 2>/dev/null)"; then
case "$FORMAT" in
1)
EXPECTED_ENGINE="redb"; EXPECTED_STORE="$REDB_STORE"
fail "store format 1 uses retired redb; this binary contains no reader"
EXPECTED_ENGINE="unsupported"; EXPECTED_STORE="$UNSUPPORTED_STORE"
fail "store format 1 is unsupported by this binary"
SESSION_USABLE=0
SESSION_REASON="store format 1 requires the KMP 0.3.2 export bridge"
SESSION_REASON="store format 1 requires an archived compatible exporter"
info "the source was left untouched"
info "export it with KMP 0.3.2, then import .kmp/memory.jsonl with current KMP"
info "use an explicitly archived compatible exporter to create .kmp/memory.jsonl"
info "then import that bundle into an empty current KMP store"
;;
2) EXPECTED_ENGINE="sqlite"; EXPECTED_STORE="$SQLITE_STORE" ;;
0)
Expand Down Expand Up @@ -368,8 +378,8 @@ else
STORE_WHEN="$(date -r "$STORE_FILE" '+%Y-%m-%d %H:%M' 2>/dev/null)"
fi
info "store size: ${STORE_SIZE:-?}"
if [ "$ENGINE" = "redb" ]; then
info "legacy redb bytes are inventory only; Doctor did not open or probe them"
if [ "$ENGINE" = "unsupported" ]; then
info "unsupported storage bytes are inventory only; Doctor did not open or probe them"
else
HOLDER=""
if command -v fuser >/dev/null 2>&1; then
Expand Down
8 changes: 4 additions & 4 deletions plugins/kmp/skills/kmp-memory/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ A replaced entry comes back **marked**. `kmp_wake` and `kmp_ask` carry
```json
"superseded": [
{
"ref": "project:kmp:decision:usar-redb",
"ref": "project:kmp:decision:usar-almacen-anterior",
"superseded_by": "project:kmp:decision:usar-sqlite",
"why": "two agent hosts need to share the store"
}
Expand Down Expand Up @@ -446,11 +446,11 @@ For a lifecycle change:

```json
{
"ref": "project:kmp:decision:redb",
"ref": "project:kmp:decision:single-writer-store",
"rel": "supersedes",
"class": "evidential",
"why": "SQLite WAL replaces redb because the architecture now requires multi-process access to one store.",
"evidence": "The shared-store test failed at redb's process lock and passed under SQLite WAL.",
"why": "SQLite WAL replaces the single-writer layout because the architecture now requires multi-process access to one store.",
"evidence": "The shared-store test failed at the previous process lock and passed under SQLite WAL.",
"confidence": "high"
}
```
Expand Down
22 changes: 16 additions & 6 deletions plugins/kmp/skills/kmp-uninstall/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ description: Preview or perform KMP removal while protecting memory and respecti

# KMP uninstall

Run `kmp-mcp uninstall` as a dry run first. Never add `--apply` or `--purge`
unless the user explicitly requested it; `--purge` skips the protective export.
Name the export path and restore command. Remove host wiring only from its
owner: `codex plugin remove` for plugin-managed installs, or the global MCP and
standalone assets for standalone installs. Do not remove both paths when only
one owns the installation.
Run `kmp-mcp uninstall` as a dry run first. To retire one memory, use
`kmp-mcp uninstall --store <absolute-path>` so the preview and apply cannot
reach any other store, engine, plugin or host wiring. The selected path must be
an existing KMP store. Never add `--apply` or `--purge` unless the user
explicitly requested it; `--purge` skips the protective export.

An apply must refuse an active store and leave every process running. Tell the
user which owning host must be stopped or restarted; never kill it on behalf of
uninstall. Retry only after that host releases the store. Name the export path
and restore command.

Use the unscoped command only when the user requested removal of the whole KMP
installation. Remove host wiring only from its owner: `codex plugin remove` for
plugin-managed installs, or the global MCP and standalone assets for
standalone installs. Do not remove both paths when only one owns the
installation.