create-claude-cabinet 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-cabinet",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "Claude Cabinet — opinionated process scaffolding for Claude Code projects",
5
5
  "bin": {
6
6
  "create-claude-cabinet": "bin/create-claude-cabinet.js"
@@ -13,6 +13,8 @@ Commands:
13
13
  capture Store a memory from hook input (PostCompact)
14
14
  store Store a memory directly (called by debrief)
15
15
  query Query memories by text
16
+ delete Delete a memory by full node_id
17
+ list List all memories with full node_ids
16
18
  status Check omega health
17
19
 
18
20
  All commands read JSON from stdin when applicable.
@@ -239,11 +241,85 @@ def cmd_status():
239
241
  _error(f"status failed: {e}")
240
242
 
241
243
 
244
+ def cmd_delete():
245
+ """Delete a memory by its full node_id.
246
+
247
+ Reads JSON from stdin with fields:
248
+ id: the full node_id (e.g. "mem-077e6037742e") (required)
249
+
250
+ Note: omega uses full node_ids, not the truncated display IDs
251
+ shown in timeline output. Query first to get the full ID.
252
+ """
253
+ data = _read_stdin()
254
+ omega = _import_omega()
255
+ if not omega:
256
+ _error("omega not available")
257
+ return
258
+
259
+ memory_id = data.get("id", "")
260
+ if not memory_id:
261
+ _error("no id provided")
262
+ return
263
+
264
+ try:
265
+ result = omega.delete_memory(memory_id)
266
+ if isinstance(result, dict) and result.get("success"):
267
+ _output({"ok": True, "deleted": memory_id})
268
+ else:
269
+ error = result.get("error", "unknown error") if isinstance(result, dict) else str(result)
270
+ _error(f"delete failed: {error}")
271
+ except Exception as e:
272
+ _error(f"delete failed: {e}")
273
+
274
+
275
+ def cmd_list():
276
+ """List all memories with their full node_ids.
277
+
278
+ Returns all memories so delete can target the correct ID.
279
+ Reads JSON from stdin with optional fields:
280
+ type: filter by event_type (optional)
281
+ limit: max results (default: 50)
282
+ """
283
+ data = _read_stdin()
284
+
285
+ try:
286
+ import sqlite3
287
+ db_path = os.path.expanduser("~/.omega/omega.db")
288
+ if not os.path.exists(db_path):
289
+ _error("omega database not found")
290
+ return
291
+
292
+ conn = sqlite3.connect(db_path)
293
+ event_type = data.get("type")
294
+ limit = data.get("limit", 50)
295
+
296
+ if event_type:
297
+ rows = conn.execute(
298
+ "SELECT node_id, content, event_type, created_at FROM memories WHERE event_type = ? ORDER BY created_at DESC LIMIT ?",
299
+ (event_type, limit),
300
+ ).fetchall()
301
+ else:
302
+ rows = conn.execute(
303
+ "SELECT node_id, content, event_type, created_at FROM memories ORDER BY created_at DESC LIMIT ?",
304
+ (limit,),
305
+ ).fetchall()
306
+
307
+ memories = [
308
+ {"id": r[0], "text": r[1], "type": r[2], "created": r[3]}
309
+ for r in rows
310
+ ]
311
+ _output({"ok": True, "memories": memories, "count": len(memories)})
312
+ except Exception as e:
313
+ _error(f"list failed: {e}")
314
+
315
+
242
316
  COMMANDS = {
243
317
  "welcome": cmd_welcome,
244
318
  "capture": cmd_capture,
245
319
  "store": cmd_store,
246
320
  "query": cmd_query,
321
+ "delete": cmd_delete,
322
+ "list": cmd_list,
247
323
  "status": cmd_status,
248
324
  }
249
325
 
@@ -66,14 +66,44 @@ to help you do your job.
66
66
  It stores decisions, lessons, preferences, and constraints with semantic
67
67
  retrieval — meaning you can search by concept, not just keyword.
68
68
 
69
+ **Querying** (search by meaning, not just keyword):
69
70
  ```bash
70
71
  echo '{"text": "your query here", "limit": 10}' | \
71
72
  ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py query
72
73
  ```
73
74
 
75
+ **Storing** (when you discover something worth remembering):
76
+ ```bash
77
+ echo '{"text": "the lesson or decision", "type": "lesson"}' | \
78
+ ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py store
79
+ ```
80
+
81
+ Memory types: `decision` (architectural choices), `lesson` (gotchas,
82
+ discoveries), `preference` (user corrections), `constraint` (limitations
83
+ found), `pattern` (conventions established), `compaction` (auto-captured
84
+ from context compaction).
85
+
86
+ **Listing** (browse all memories with full IDs):
87
+ ```bash
88
+ echo '{"limit": 20}' | \
89
+ ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py list
90
+ ```
91
+
92
+ **Deleting** (remove stale or incorrect memories):
93
+ ```bash
94
+ echo '{"id": "mem-077e6037742e"}' | \
95
+ ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py delete
96
+ ```
97
+ Note: deletion requires the **full node_id** (e.g. `mem-077e6037742e`),
98
+ not the truncated display ID shown in `omega timeline`. Use `list` to
99
+ get full IDs.
100
+
101
+ Omega data lives at `~/.omega/omega.db` (SQLite). The `/memory` skill
102
+ gives users self-serve access to browse, search, and manage memories.
103
+
74
104
  Omega returns memories ranked by relevance. This is the richest source
75
- of institutional memory when available. If omega is not available, skip
76
- to source 1.
105
+ of institutional memory when available. If omega queries return nothing
106
+ or fail, fall through to source 1 (flat memory files).
77
107
 
78
108
  1. **Memory files** — `.claude/memory/*.md` and any project-level memory
79
109
  index (e.g., `MEMORY.md`). These are the distilled, catalogued lessons.
@@ -178,9 +208,10 @@ advocate for improvements.
178
208
 
179
209
  You are responsible for the health of the memory system:
180
210
 
181
- 1. **After significant work:** Ensure lessons are captured in memory files.
182
- If a session produced important context that isn't in any memory file,
183
- create or update one.
211
+ 1. **After significant work:** Ensure lessons are captured. If omega is
212
+ available, store lessons there (they persist across sessions and support
213
+ semantic retrieval). If not, use flat memory files. If a session produced
214
+ important context that isn't captured anywhere, store it now.
184
215
 
185
216
  2. **Cataloguing:** Memory files should be indexed with clear one-line
186
217
  descriptions. A memory file that exists but isn't indexed is invisible
@@ -1,18 +1,20 @@
1
1
  ---
2
2
  name: memory
3
3
  description: |
4
- Browse and search semantic memory. Shows what omega remembers — decisions,
5
- lessons, preferences, constraints. Use when: "what's in memory", "memory",
6
- "/memory", "what do you remember", "show memories", "search memory".
4
+ Browse, search, and manage semantic memory. Shows what omega remembers —
5
+ decisions, lessons, preferences, constraints. Supports browse, search,
6
+ remember, and forget. Use when: "what's in memory", "memory", "/memory",
7
+ "what do you remember", "show memories", "search memory", "forget",
8
+ "delete memory", "remember this".
7
9
  user-invocable: true
8
10
  ---
9
11
 
10
- # /memory — Browse Semantic Memory
12
+ # /memory — Semantic Memory
11
13
 
12
14
  ## Purpose
13
15
 
14
- Give the user visibility into what omega remembers. Browse, search, and
15
- manage the semantic memory store.
16
+ Give the user visibility into what omega remembers. Browse, search, store,
17
+ and delete memories.
16
18
 
17
19
  ## Prerequisites
18
20
 
@@ -23,6 +25,29 @@ Check that omega is available:
23
25
  If not available, tell the user:
24
26
  > Memory module is not set up. Run `npx create-claude-cabinet` to install it.
25
27
 
28
+ ## Adapter Reference
29
+
30
+ The adapter (`scripts/cabinet-memory-adapter.py`) is the single interface
31
+ to omega. All commands read JSON from stdin, output JSON to stdout, and
32
+ exit 0 even on failure. Always call it via the venv Python:
33
+
34
+ ```bash
35
+ echo '<json>' | ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py <command>
36
+ ```
37
+
38
+ | Command | Input | Output |
39
+ |---------|-------|--------|
40
+ | `welcome` | `{}` or hook JSON | `{ok, context}` — relevant memories |
41
+ | `store` | `{text, type, tags?}` | `{ok, id}` — stored memory ID |
42
+ | `query` | `{text, limit?, type?}` | `{ok, results}` — semantic search |
43
+ | `delete` | `{id}` | `{ok, deleted}` — requires full node_id |
44
+ | `list` | `{type?, limit?}` | `{ok, memories, count}` — all memories with full IDs |
45
+ | `capture` | hook JSON with `compact_summary` | `{ok, stored}` — auto-capture count |
46
+ | `status` | `{}` | `{ok, ...health info}` |
47
+
48
+ Memory types: `decision`, `lesson`, `preference`, `constraint`, `pattern`,
49
+ `compaction`.
50
+
26
51
  ## Commands
27
52
 
28
53
  Parse the user's intent from their prompt:
@@ -36,24 +61,21 @@ Show the timeline and stats:
36
61
  ~/.claude-cabinet/omega-venv/bin/omega stats 2>&1
37
62
  ```
38
63
 
39
- Present both outputs. The timeline shows what's stored chronologically,
40
- stats shows the type distribution.
64
+ Present both outputs conversationally. The timeline shows what's stored
65
+ chronologically, stats shows the type distribution.
41
66
 
42
67
  ### Search — user provides a topic
43
68
 
44
- Query omega for memories matching the topic:
45
-
46
69
  ```bash
47
70
  echo '{"text": "the user query", "limit": 10}' | \
48
71
  ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py query
49
72
  ```
50
73
 
51
- Present the results conversationally — don't just dump JSON.
74
+ Present results conversationally — highlight the most relevant matches
75
+ and their types.
52
76
 
53
77
  ### Remember — user wants to store something
54
78
 
55
- Store a new memory:
56
-
57
79
  ```bash
58
80
  echo '{"text": "what to remember", "type": "preference"}' | \
59
81
  ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py store
@@ -70,25 +92,36 @@ Confirm what was stored.
70
92
 
71
93
  ### Forget — user wants to remove something
72
94
 
73
- Look up the memory first with a query, show them what matched, confirm
74
- which one to remove. Use omega's delete:
95
+ **Step 1:** Find the memory. Use `list` to get full node_ids:
75
96
 
76
97
  ```bash
77
- ~/.claude-cabinet/omega-venv/bin/omega query "the topic" 2>&1
98
+ echo '{"type": "preference", "limit": 20}' | \
99
+ ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py list
78
100
  ```
79
101
 
80
- Then delete by ID:
102
+ Or search by content:
81
103
 
82
104
  ```bash
83
- echo '{"text": "delete mem-XXXX", "type": "memory"}' | \
84
- ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py store
105
+ echo '{"text": "the topic to forget"}' | \
106
+ ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py query
107
+ ```
108
+
109
+ **Step 2:** Show the user what matched. Confirm which one(s) to delete.
110
+
111
+ **Step 3:** Delete by full node_id (e.g. `mem-077e6037742e`, NOT the
112
+ truncated `mem-077e6037` shown in timeline):
113
+
114
+ ```bash
115
+ echo '{"id": "mem-077e6037742e"}' | \
116
+ ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py delete
85
117
  ```
86
118
 
87
- Note: omega doesn't have a direct delete API in the adapter yet. For now,
88
- tell the user the memory ID and that direct deletion requires the omega CLI.
119
+ The `list` command returns full node_ids. The `timeline` CLI shows
120
+ truncated IDs always use `list` to get the correct ID for deletion.
89
121
 
90
122
  ## Presentation
91
123
 
92
- Keep it conversational. Don't dump raw CLI output — summarize it.
124
+ Keep it conversational. Don't dump raw CLI output or JSON — summarize it.
93
125
  For timeline, present as a readable list. For search results, highlight
94
- the most relevant matches and their types.
126
+ the most relevant matches and their types. For forget, always confirm
127
+ before deleting.
@@ -49,6 +49,7 @@ early vs mature re-run:
49
49
  | CLAUDE.md | Root `CLAUDE.md` | Project instructions exist |
50
50
  | Rules files | `.claude/rules/*.md` | Scoped instructions exist |
51
51
  | Hook config | `.claude/settings.json` or `.claude/settings.local.json` | Enforcement hooks exist |
52
+ | Omega memory | `~/.claude-cabinet/omega-venv/` and `scripts/cabinet-memory-adapter.py` | Semantic memory is active |
52
53
 
53
54
  **Early re-run:** Fewer than 5 of the above are populated.
54
55
  **Mature re-run:** 5 or more are populated.
@@ -89,6 +89,18 @@ sessions, and project-specific context.
89
89
  - `.claude/memory/patterns/` — enforcement patterns from prior sessions.
90
90
  Scan the directory, read each pattern file. These are project-level
91
91
  feedback that guides behavior (what to avoid, what to keep doing).
92
+ - **Omega semantic memory** — if `~/.claude-cabinet/omega-venv/bin/python3`
93
+ and `scripts/cabinet-memory-adapter.py` both exist, query omega for
94
+ relevant context:
95
+ ```bash
96
+ echo '{"text": "session context project status recent decisions", "limit": 10}' | \
97
+ ~/.claude-cabinet/omega-venv/bin/python3 scripts/cabinet-memory-adapter.py query
98
+ ```
99
+ Surface any relevant memories (decisions, lessons, constraints) that
100
+ inform the current session. If the venv is missing but `.ccrc.json`
101
+ lists the memory module as installed, warn the user:
102
+ > ⚠ Memory module is installed but omega venv is missing.
103
+ > Run `npx create-claude-cabinet` to restore it.
92
104
 
93
105
  The goal: build a mental model of where things stand before doing
94
106
  anything else.