clawvault 2.6.3 → 2.6.4

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.
Files changed (123) hide show
  1. package/README.md +351 -21
  2. package/bin/clawvault.js +8 -2
  3. package/bin/command-runtime.js +9 -1
  4. package/bin/register-maintenance-commands.js +19 -0
  5. package/bin/register-query-commands.js +58 -6
  6. package/bin/register-workgraph-commands.js +451 -0
  7. package/dist/{chunk-VXEOHTSL.js → chunk-2JQ3O2YL.js} +1 -1
  8. package/dist/{chunk-VR5NE7PZ.js → chunk-2RAZ4ZFE.js} +1 -1
  9. package/dist/chunk-2ZDO52B4.js +52 -0
  10. package/dist/chunk-4BQTQMJP.js +93 -0
  11. package/dist/{chunk-MAKNAHAW.js → chunk-5PJ4STIC.js} +98 -8
  12. package/dist/{chunk-IEVLHNLU.js → chunk-627Q3QWK.js} +3 -3
  13. package/dist/{chunk-R6SXNSFD.js → chunk-6NYYDNNG.js} +3 -3
  14. package/dist/chunk-ECRZL5XR.js +50 -0
  15. package/dist/chunk-GNJL4YGR.js +79 -0
  16. package/dist/{chunk-OZ7RIXTO.js → chunk-IIOU45CK.js} +1 -1
  17. package/dist/chunk-L4HSSQ6T.js +152 -0
  18. package/dist/{chunk-DTEHFAL7.js → chunk-LIGHWOH6.js} +1 -1
  19. package/dist/{chunk-PBEE567J.js → chunk-LUBZXECN.js} +2 -2
  20. package/dist/{chunk-PZ2AUU2W.js → chunk-MFL6EEPF.js} +204 -35
  21. package/dist/chunk-MM6QGW3P.js +207 -0
  22. package/dist/{chunk-T76H47ZS.js → chunk-MNPUYCHQ.js} +1 -1
  23. package/dist/{chunk-6546Q4OR.js → chunk-MPOSMDMU.js} +6 -6
  24. package/dist/{chunk-RVYA52PY.js → chunk-NJYJL5AA.js} +1 -1
  25. package/dist/{chunk-Q2J5YTUF.js → chunk-OQGYFZ4A.js} +669 -33
  26. package/dist/{chunk-ME37YNW3.js → chunk-P7SY3D4E.js} +3 -3
  27. package/dist/chunk-RHISK3SZ.js +189 -0
  28. package/dist/{chunk-3BTHWPMB.js → chunk-S5OJEGFG.js} +2 -2
  29. package/dist/{chunk-MGDEINGP.js → chunk-SS4B7P7V.js} +1 -1
  30. package/dist/chunk-U4O6C46S.js +154 -0
  31. package/dist/{chunk-ITPEXLHA.js → chunk-URXDAUVH.js} +24 -5
  32. package/dist/chunk-WIOLLGAD.js +190 -0
  33. package/dist/chunk-WMGIIABP.js +15 -0
  34. package/dist/{chunk-QVMXF7FY.js → chunk-X3SPPUFG.js} +50 -0
  35. package/dist/{chunk-THRJVD4L.js → chunk-Y6VJKXGL.js} +1 -1
  36. package/dist/{chunk-RCBMXTWS.js → chunk-YDWHS4LJ.js} +21 -6
  37. package/dist/{chunk-4VRIMU4O.js → chunk-YNIPYN4F.js} +4 -4
  38. package/dist/{chunk-HIHOUSXS.js → chunk-YXQCA6B7.js} +105 -1
  39. package/dist/cli/index.js +18 -16
  40. package/dist/commands/archive.js +3 -2
  41. package/dist/commands/backlog.js +1 -0
  42. package/dist/commands/blocked.js +1 -0
  43. package/dist/commands/canvas.js +1 -0
  44. package/dist/commands/checkpoint.js +1 -0
  45. package/dist/commands/compat.js +2 -1
  46. package/dist/commands/context.js +5 -3
  47. package/dist/commands/doctor.d.ts +10 -1
  48. package/dist/commands/doctor.js +11 -8
  49. package/dist/commands/embed.js +5 -3
  50. package/dist/commands/entities.js +2 -1
  51. package/dist/commands/graph.js +3 -2
  52. package/dist/commands/inject.d.ts +1 -1
  53. package/dist/commands/inject.js +4 -3
  54. package/dist/commands/kanban.js +1 -0
  55. package/dist/commands/link.js +2 -1
  56. package/dist/commands/migrate-observations.js +3 -2
  57. package/dist/commands/observe.js +8 -6
  58. package/dist/commands/project.js +1 -0
  59. package/dist/commands/rebuild-embeddings.d.ts +21 -0
  60. package/dist/commands/rebuild-embeddings.js +91 -0
  61. package/dist/commands/rebuild.js +6 -4
  62. package/dist/commands/recover.js +1 -0
  63. package/dist/commands/reflect.js +5 -4
  64. package/dist/commands/repair-session.js +1 -0
  65. package/dist/commands/replay.js +7 -6
  66. package/dist/commands/session-recap.js +1 -0
  67. package/dist/commands/setup.js +3 -2
  68. package/dist/commands/shell-init.js +2 -0
  69. package/dist/commands/sleep.d.ts +1 -1
  70. package/dist/commands/sleep.js +8 -6
  71. package/dist/commands/status.js +11 -80
  72. package/dist/commands/sync-bd.js +3 -2
  73. package/dist/commands/tailscale.js +3 -2
  74. package/dist/commands/task.js +1 -0
  75. package/dist/commands/template.js +1 -0
  76. package/dist/commands/wake.d.ts +1 -1
  77. package/dist/commands/wake.js +4 -2
  78. package/dist/index.d.ts +247 -10
  79. package/dist/index.js +285 -152
  80. package/dist/{inject-x65KXWPk.d.ts → inject-DYUrDqQO.d.ts} +2 -2
  81. package/dist/ledger-B7g7jhqG.d.ts +44 -0
  82. package/dist/lib/auto-linker.js +1 -0
  83. package/dist/lib/canvas-layout.js +1 -0
  84. package/dist/lib/config.d.ts +27 -3
  85. package/dist/lib/config.js +4 -1
  86. package/dist/lib/entity-index.js +1 -0
  87. package/dist/lib/project-utils.js +1 -0
  88. package/dist/lib/session-repair.js +1 -0
  89. package/dist/lib/session-utils.js +1 -0
  90. package/dist/lib/tailscale.js +1 -0
  91. package/dist/lib/task-utils.js +1 -0
  92. package/dist/lib/template-engine.js +1 -0
  93. package/dist/lib/webdav.js +1 -0
  94. package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
  95. package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
  96. package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
  97. package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
  98. package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
  99. package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
  100. package/dist/registry-BR4326o0.d.ts +30 -0
  101. package/dist/store-CA-6sKCJ.d.ts +34 -0
  102. package/dist/thread-B9LhXNU0.d.ts +41 -0
  103. package/dist/transformers.node-A2ZRORSQ.js +46775 -0
  104. package/dist/{types-C74wgGL1.d.ts → types-BbWJoC1c.d.ts} +1 -1
  105. package/dist/workgraph/index.d.ts +5 -0
  106. package/dist/workgraph/index.js +23 -0
  107. package/dist/workgraph/ledger.d.ts +2 -0
  108. package/dist/workgraph/ledger.js +25 -0
  109. package/dist/workgraph/registry.d.ts +2 -0
  110. package/dist/workgraph/registry.js +19 -0
  111. package/dist/workgraph/store.d.ts +2 -0
  112. package/dist/workgraph/store.js +25 -0
  113. package/dist/workgraph/thread.d.ts +2 -0
  114. package/dist/workgraph/thread.js +25 -0
  115. package/dist/workgraph/types.d.ts +54 -0
  116. package/dist/workgraph/types.js +7 -0
  117. package/hooks/clawvault/handler.js +714 -2
  118. package/hooks/clawvault/handler.test.js +153 -0
  119. package/hooks/clawvault/openclaw.plugin.json +72 -0
  120. package/openclaw.plugin.json +14 -2
  121. package/package.json +5 -4
  122. package/dist/chunk-4QYGFWRM.js +0 -88
  123. package/dist/chunk-MXSSG3QU.js +0 -42
package/README.md CHANGED
@@ -1,19 +1,301 @@
1
+ <div align="center">
2
+
1
3
  # ClawVault 🐘
2
4
 
3
- Structured memory system for AI agents and operators: typed markdown memory, graph-aware context, task/project primitives, Obsidian views, and OpenClaw hook integration.
5
+ **Persistent Memory for AI Agents**
4
6
 
7
+ [![Tests](https://img.shields.io/badge/tests-466%20passing-brightgreen)](https://github.com/Versatly/clawvault)
5
8
  [![npm](https://img.shields.io/npm/v/clawvault)](https://www.npmjs.com/package/clawvault)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
10
+ [![PRs Merged](https://img.shields.io/badge/PRs%20merged-20%2B-purple)](https://github.com/Versatly/clawvault/pulls?q=is%3Amerged)
11
+ [![Contributors](https://img.shields.io/badge/contributors-6-orange)](https://github.com/Versatly/clawvault/graphs/contributors)
6
12
 
7
- > Local-first. Markdown-first. Built to survive long-running autonomous work.
13
+ *An elephant never forgets. Neither should your AI.*
8
14
 
9
- **$CLAW**: [`5Fjr82MTB8mvxkzi9FYtvrUsPiDGE2M29w3dYcZpump`](https://pump.fun/coin/5Fjr82MTB8mvxkzi9FYtvrUsPiDGE2M29w3dYcZpump)
15
+ [Documentation](https://clawvault.dev) · [npm Package](https://www.npmjs.com/package/clawvault) · [Obsidian Plugin](https://clawvault.dev/obsidian) · [GitHub](https://github.com/Versatly/clawvault)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## What is ClawVault?
22
+
23
+ ClawVault is a **structured memory system** for AI agents that uses **markdown as the storage primitive**. It solves the fundamental problem of AI agents losing context between sessions — what we call "context death."
24
+
25
+ Unlike vector databases or cloud-based memory solutions, ClawVault is:
26
+
27
+ - **Local-first** — Your data stays on your machine. No cloud sync, no vendor lock-in.
28
+ - **Markdown-native** — Human-readable, git-friendly, works with Obsidian out of the box.
29
+ - **Graph-aware** — Wiki-links build a knowledge graph that enriches context retrieval.
30
+ - **Session-resilient** — Checkpoint/recover primitives survive crashes and context resets.
31
+ - **Fact-aware** — Write-time extraction builds structured facts with conflict resolution.
32
+
33
+ ```
34
+ ┌─────────────────────────────────────────────────────────────────────────────┐
35
+ │ ClawVault Architecture │
36
+ ├─────────────────────────────────────────────────────────────────────────────┤
37
+ │ │
38
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
39
+ │ │ Agent │───▶│ Session │───▶│ Observer │───▶│ Router │ │
40
+ │ │ (Claude, │ │ Watcher │ │Compressor│ │ │ │
41
+ │ │ GPT..) │ └──────────┘ └──────────┘ └────┬─────┘ │
42
+ │ └──────────┘ │ │
43
+ │ │ ▼ │
44
+ │ │ ┌─────────────────────────────────────────────────────┐ │
45
+ │ │ │ Markdown Vault │ │
46
+ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
47
+ │ │ │ │decisions/│ │ lessons/ │ │ people/ │ │projects│ │ │
48
+ │ │ │ └──────────┘ └──────────┘ └──────────┘ └────────┘ │ │
49
+ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
50
+ │ │ │ │ tasks/ │ │ backlog/ │ │handoffs/ │ │ inbox/ │ │ │
51
+ │ │ │ └──────────┘ └──────────┘ └──────────┘ └────────┘ │ │
52
+ │ │ └─────────────────────────────────────────────────────┘ │
53
+ │ │ │ │
54
+ │ │ ┌──────────────────────────┴──────────────────────────┐ │
55
+ │ │ │ .clawvault/ (Internal State) │ │
56
+ │ │ │ graph-index.json │ last-checkpoint.json │ config │ │
57
+ │ │ └─────────────────────────────────────────────────────┘ │
58
+ │ │ │ │
59
+ │ ▼ ▼ │
60
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
61
+ │ │ wake │◀──▶│ context │◀──▶│ Graph │◀──▶│ Search │ │
62
+ │ │ sleep │ │ profiles │ │ Traversal│ │(qmd/vec) │ │
63
+ │ │checkpoint│ └──────────┘ └──────────┘ └──────────┘ │
64
+ │ └──────────┘ │
65
+ │ │
66
+ │ Data Flow: Session → Observe → Score → Route → Store → Reflect → Promote │
67
+ │ │
68
+ └─────────────────────────────────────────────────────────────────────────────┘
69
+ ```
70
+
71
+ ---
72
+
73
+ ## The 8 Primitives
74
+
75
+ ClawVault is built around 8 core primitives that model how agents should interact with persistent memory:
76
+
77
+ | Primitive | Description | ClawVault Implementation |
78
+ |-----------|-------------|--------------------------|
79
+ | **Goals** | What the agent is trying to achieve | `tasks/`, `projects/`, `--working-on` flags |
80
+ | **Agents** | Identity and ownership tracking | `--owner` metadata, agent handoffs |
81
+ | **State Space** | Current context and environment | `checkpoint`, `recover`, session state |
82
+ | **Feedback** | Learning from outcomes | `lessons/`, `observations/`, reflection engine |
83
+ | **Capital** | Resources and constraints | Token budgets, context profiles, priority scoring |
84
+ | **Institution** | Rules and patterns | `decisions/`, `preferences/`, injection rules |
85
+ | **Synthesis** | Combining information | Graph traversal, context blending, semantic search |
86
+ | **Recursion** | Self-improvement loops | `reflect`, weekly promotion, archival |
87
+
88
+ These primitives map directly to CLI commands and vault structure, creating a coherent system for agent memory.
89
+
90
+ ---
91
+
92
+ ## Quick Start
93
+
94
+ ### Installation
95
+
96
+ ```bash
97
+ # Install ClawVault CLI
98
+ npm install -g clawvault
99
+
100
+ # Install qmd (required for search/context features)
101
+ npm install -g github:tobi/qmd
102
+ ```
103
+
104
+ ### Initialize Your Vault
105
+
106
+ ```bash
107
+ # Create a new vault
108
+ clawvault init ~/memory --name my-brain
109
+
110
+ # Optional: Set up Obsidian integration
111
+ clawvault setup --theme neural --canvas
112
+ ```
113
+
114
+ ### Basic Workflow
115
+
116
+ ```bash
117
+ # Start your session
118
+ clawvault wake
119
+
120
+ # Store memories as you work
121
+ clawvault remember decision "Use PostgreSQL" --content "Chosen for JSONB support"
122
+ clawvault capture "TODO: Review PR tomorrow"
123
+
124
+ # Checkpoint during heavy work
125
+ clawvault checkpoint --working-on "auth rollout" --focus "token refresh"
126
+
127
+ # End your session
128
+ clawvault sleep "finished auth rollout" --next "implement migration"
129
+ ```
130
+
131
+ ### Search and Context
132
+
133
+ ```bash
134
+ # Keyword search
135
+ clawvault search "postgresql"
136
+
137
+ # Semantic search
138
+ clawvault vsearch "what did we decide about storage"
139
+
140
+ # Get context for a task
141
+ clawvault context "database migration"
142
+ clawvault context --profile planning "Q1 roadmap"
143
+ ```
144
+
145
+ ---
146
+
147
+ ## v3.0 — Structured Memory
148
+
149
+ ClawVault v3 adds **write-time fact extraction** and **entity graphs** to the core memory pipeline:
150
+
151
+ - **Fact Store** — Extracts structured facts (preferences, attributes, relationships) at write time with conflict resolution and deduplication
152
+ - **Entity Graph** — Builds a relational graph enabling multi-hop queries ("Alice works at Google + Google is in CA → Alice is in CA")
153
+ - **Hybrid Search** — BM25 + semantic embeddings + Reciprocal Rank Fusion (RRF)
154
+
155
+ ### Project Stats
156
+
157
+ - **466 tests** passing across **71 test files**
158
+ - **20+ PRs** merged from **6 external contributors**
159
+ - Published on npm as [`clawvault`](https://www.npmjs.com/package/clawvault)
160
+ - Active development since February 2026
161
+
162
+ ---
163
+
164
+ ## Features
165
+
166
+ ### Memory Graph
167
+
168
+ ClawVault builds a typed knowledge graph from wiki-links, tags, and frontmatter:
169
+
170
+ ```bash
171
+ # View graph summary
172
+ clawvault graph
173
+
174
+ # Refresh graph index
175
+ clawvault graph --refresh
176
+ ```
177
+
178
+ ### Context Profiles
179
+
180
+ Different tasks need different context. Use profiles to tune retrieval:
181
+
182
+ | Profile | Purpose |
183
+ |---------|---------|
184
+ | `default` | Balanced retrieval |
185
+ | `planning` | Broader strategic context |
186
+ | `incident` | Recent events, blockers, urgent items |
187
+ | `handoff` | Session transition context |
188
+ | `auto` | Hook-selected based on session intent |
189
+
190
+ ```bash
191
+ clawvault context --profile incident "production outage"
192
+ ```
193
+
194
+ ### Task Management
195
+
196
+ Full task lifecycle with Kanban support:
197
+
198
+ ```bash
199
+ # Create tasks
200
+ clawvault task add "Ship v2 onboarding" --owner agent --project core --priority high
201
+
202
+ # View blocked items
203
+ clawvault blocked
204
+
205
+ # Sync with Obsidian Kanban
206
+ clawvault kanban sync
207
+ ```
208
+
209
+ ### Dynamic Prompt Injection
210
+
211
+ Pull relevant decisions and preferences into agent context automatically:
212
+
213
+ ```bash
214
+ clawvault inject "How should we handle the deployment?"
215
+ clawvault inject --enable-llm "What's our pricing strategy?"
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Obsidian Integration
221
+
222
+ ClawVault is designed to work seamlessly with Obsidian:
223
+
224
+ - **Graph themes** — Neural/minimal themes with colored nodes by category
225
+ - **Bases views** — Auto-generated task views (`all-tasks.base`, `blocked.base`, `by-project.base`)
226
+ - **Canvas dashboards** — `clawvault canvas` generates visual dashboards
227
+ - **Kanban round-trip** — Export/import between ClawVault and Obsidian Kanban
228
+
229
+ ```bash
230
+ # Generate canvas dashboard
231
+ clawvault canvas --template brain
232
+
233
+ # Set up Obsidian integration
234
+ clawvault setup --theme neural --canvas --bases
235
+ ```
236
+
237
+ ---
238
+
239
+ ## OpenClaw Integration
240
+
241
+ For hook-based lifecycle integration with OpenClaw:
242
+
243
+ ```bash
244
+ # Install and enable hook pack
245
+ openclaw hooks install clawvault
246
+ openclaw hooks enable clawvault
247
+
248
+ # Verify
249
+ openclaw hooks list --verbose
250
+ openclaw hooks check
251
+ clawvault compat
252
+ ```
253
+
254
+ The hook automatically:
255
+ - Detects context death and injects recovery alerts
256
+ - Auto-checkpoints before session resets
257
+ - Provides `--profile auto` for context queries
258
+
259
+ ### MEMORY.md vs Vault
260
+
261
+ If you use both a `MEMORY.md` workspace file and a ClawVault vault, understand their roles:
262
+
263
+ - **MEMORY.md** = Boot context (executive summary the agent sees instantly)
264
+ - **Vault** = Full knowledge store (searchable, structured, versioned)
265
+
266
+ MEMORY.md should contain high-level identity, key decisions, and current focus. The vault stores everything else. Update MEMORY.md periodically to reflect vault state, but it doesn't need to mirror it.
267
+
268
+ See [docs/openclaw-plugin-usage.md](docs/openclaw-plugin-usage.md) for detailed guidance on this pattern.
269
+
270
+ ---
10
271
 
11
272
  ## Requirements
12
273
 
13
274
  - Node.js 18+
14
- - `qmd` installed and available on `PATH`
275
+ - `qmd` installed and available on `PATH` (for search/context features)
276
+
277
+ ## LLM Providers
278
+
279
+ ClawVault supports multiple LLM providers for features like context generation, observation compression, and semantic search. Set the appropriate environment variable to enable a provider:
15
280
 
16
- ClawVault currently relies on `qmd` for core vault/query flows. Install it before first use.
281
+ | Provider | Environment Variable | Default Model | Notes |
282
+ |----------|---------------------|---------------|-------|
283
+ | **Anthropic** | `ANTHROPIC_API_KEY` | `claude-3-5-haiku-latest` | Claude models |
284
+ | **OpenAI** | `OPENAI_API_KEY` | `gpt-4o-mini` | GPT models |
285
+ | **Google Gemini** | `GEMINI_API_KEY` | `gemini-2.0-flash` | Gemini models |
286
+ | **xAI (Grok)** | `XAI_API_KEY` | `grok-2-latest` | Grok models via OpenAI-compatible API |
287
+ | **Ollama** | (local) | `llama3.2` | Local models, no API key needed |
288
+ | **OpenAI-compatible** | `OPENAI_API_KEY` | `gpt-4o-mini` | Any OpenAI-compatible endpoint |
289
+
290
+ Provider priority (when multiple keys are set): OpenClaw > Anthropic > OpenAI > Gemini > xAI
291
+
292
+ ```bash
293
+ # Example: Use xAI (Grok) as your LLM provider
294
+ export XAI_API_KEY="your-xai-api-key"
295
+
296
+ # Example: Use Anthropic
297
+ export ANTHROPIC_API_KEY="your-anthropic-api-key"
298
+ ```
17
299
 
18
300
  ## Install
19
301
 
@@ -70,35 +352,39 @@ Append these to your existing memory workflow. Do not replace your full prompt s
70
352
  - Use `clawvault context "<task>"` or `clawvault inject "<message>"` before complex decisions.
71
353
  ```
72
354
 
73
- ## Real CLI Surface (Current)
355
+ ---
74
356
 
75
- Core:
357
+ ## CLI Reference
358
+
359
+ ### Core Commands
76
360
 
77
361
  - `init`, `setup`, `store`, `capture`
78
362
  - `remember`, `list`, `get`, `stats`, `reindex`, `sync`
79
363
 
80
- Context + memory:
364
+ ### Context + Memory
81
365
 
82
366
  - `search`, `vsearch`, `context`, `inject`
83
367
  - `observe`, `reflect`, `session-recap`
84
368
  - `graph`, `entities`, `link`, `embed`
85
369
 
86
- Resilience:
370
+ ### Resilience
87
371
 
88
372
  - `wake`, `sleep`, `handoff`, `recap`
89
373
  - `checkpoint`, `recover`, `status`, `clean-exit`, `repair-session`
90
374
  - `compat`, `doctor`
91
375
 
92
- Execution primitives:
376
+ ### Execution Primitives
93
377
 
94
378
  - `task ...`, `backlog ...`, `blocked`, `project ...`, `kanban ...`
95
379
  - `canvas` (generates default `dashboard.canvas`)
96
380
 
97
- Networking:
381
+ ### Networking
98
382
 
99
383
  - `tailscale-status`, `tailscale-sync`, `tailscale-serve`, `tailscale-discover`
100
384
 
101
- ## Quick Usage
385
+ ---
386
+
387
+ ## Quick Usage Examples
102
388
 
103
389
  ```bash
104
390
  # Store and retrieve memory
@@ -121,15 +407,7 @@ clawvault kanban sync
121
407
  clawvault canvas
122
408
  ```
123
409
 
124
- ## Obsidian Integration
125
-
126
- - Setup can generate:
127
- - graph theme/snippet config (`--theme neural|minimal|none`)
128
- - Bases views (`all-tasks.base`, `blocked.base`, `by-project.base`, `by-owner.base`, `backlog.base`)
129
- - default canvas (`dashboard.canvas`) via `--canvas` or `clawvault canvas`
130
- - Kanban round-trip:
131
- - export: `clawvault kanban sync`
132
- - import lane changes back to task metadata: `clawvault kanban import`
410
+ ---
133
411
 
134
412
  ## Tailscale + WebDAV
135
413
 
@@ -141,6 +419,29 @@ clawvault tailscale-serve --vault ~/memory
141
419
  clawvault tailscale-discover
142
420
  ```
143
421
 
422
+ ---
423
+
424
+ ## Vault Structure
425
+
426
+ ```
427
+ vault/
428
+ ├── .clawvault/ # Internal state
429
+ │ ├── graph-index.json # Knowledge graph
430
+ │ ├── last-checkpoint.json
431
+ │ └── config.json
432
+ ├── decisions/ # Key choices with reasoning
433
+ ├── lessons/ # Insights and patterns
434
+ ├── people/ # One file per person
435
+ ├── projects/ # Active work tracking
436
+ ├── tasks/ # Task files with frontmatter
437
+ ├── backlog/ # Quick captures and ideas
438
+ ├── handoffs/ # Session continuity
439
+ ├── inbox/ # Quick captures
440
+ └── templates/ # Document templates
441
+ ```
442
+
443
+ ---
444
+
144
445
  ## Troubleshooting
145
446
 
146
447
  - Hook not found after enable:
@@ -156,6 +457,35 @@ clawvault tailscale-discover
156
457
  - Session transcript corruption:
157
458
  - run `clawvault repair-session --dry-run` then `clawvault repair-session`
158
459
 
460
+ ---
461
+
462
+ ## Links
463
+
464
+ | Resource | URL |
465
+ |----------|-----|
466
+ | **Documentation** | [clawvault.dev](https://clawvault.dev) |
467
+ | **npm Package** | [npmjs.com/package/clawvault](https://www.npmjs.com/package/clawvault) |
468
+ | **GitHub** | [github.com/Versatly/clawvault](https://github.com/Versatly/clawvault) |
469
+ | **Issues** | [github.com/Versatly/clawvault/issues](https://github.com/Versatly/clawvault/issues) |
470
+ | **Obsidian Plugin** | [clawvault.dev/obsidian](https://clawvault.dev/obsidian) |
471
+
472
+ ---
473
+
474
+ ## Contributing
475
+
476
+ We welcome contributions! ClawVault has had **20+ PRs merged** from **6 external contributors**.
477
+
478
+ 1. Fork the repository
479
+ 2. Create a feature branch
480
+ 3. Run tests: `npm test`
481
+ 4. Submit a PR
482
+
483
+ See our [contribution guidelines](https://github.com/Versatly/clawvault/blob/main/CONTRIBUTING.md) for details.
484
+
485
+ ---
486
+
487
+ **$CLAW**: [`5Fjr82MTB8mvxkzi9FYtvrUsPiDGE2M29w3dYcZpump`](https://pump.fun/coin/5Fjr82MTB8mvxkzi9FYtvrUsPiDGE2M29w3dYcZpump)
488
+
159
489
  ## License
160
490
 
161
491
  MIT
package/bin/clawvault.js CHANGED
@@ -23,13 +23,16 @@ import { registerProjectCommands } from './register-project-commands.js';
23
23
 
24
24
  import { registerTaskCommands } from './register-task-commands.js';
25
25
 
26
+ import { registerWorkgraphCommands } from './register-workgraph-commands.js';
26
27
  import { registerTailscaleCommands } from './register-tailscale-commands.js';
27
28
  import {
28
29
  getVault,
29
30
  resolveVaultPath,
30
31
  runQmd,
31
32
  printQmdMissing,
32
- QmdUnavailableError
33
+ printQmdConfigError,
34
+ QmdUnavailableError,
35
+ QmdConfigurationError
33
36
  } from './command-runtime.js';
34
37
  import {
35
38
  createVault
@@ -66,7 +69,9 @@ registerQueryCommands(program, {
66
69
  getVault,
67
70
  resolveVaultPath,
68
71
  QmdUnavailableError,
69
- printQmdMissing
72
+ QmdConfigurationError,
73
+ printQmdMissing,
74
+ printQmdConfigError
70
75
  });
71
76
 
72
77
  registerSessionLifecycleCommands(program, {
@@ -104,6 +109,7 @@ registerProjectCommands(program, {
104
109
  resolveVaultPath
105
110
  });
106
111
 
112
+ registerWorkgraphCommands(program, { chalk, resolveVaultPath });
107
113
  registerTailscaleCommands(program, { chalk });
108
114
  registerConfigCommands(program, { chalk, resolveVaultPath });
109
115
  registerRouteCommands(program, { chalk, resolveVaultPath });
@@ -4,6 +4,7 @@ import path from 'path';
4
4
  import {
5
5
  ClawVault,
6
6
  QmdUnavailableError,
7
+ QmdConfigurationError,
7
8
  QMD_INSTALL_COMMAND,
8
9
  resolveVaultPath as resolveConfiguredVaultPath
9
10
  } from '../dist/index.js';
@@ -90,4 +91,11 @@ export function printQmdMissing() {
90
91
  console.log(chalk.dim(`Install: ${QMD_INSTALL_COMMAND}`));
91
92
  }
92
93
 
93
- export { QmdUnavailableError };
94
+ export function printQmdConfigError(err) {
95
+ console.error(chalk.red(`Error: ${err.message}`));
96
+ if (err.hint) {
97
+ console.log(chalk.yellow(`Hint: ${err.hint}`));
98
+ }
99
+ }
100
+
101
+ export { QmdUnavailableError, QmdConfigurationError };
@@ -80,6 +80,25 @@ export function registerMaintenanceCommands(program, { chalk }) {
80
80
  }
81
81
  });
82
82
 
83
+ // === REBUILD-EMBEDDINGS ===
84
+ program
85
+ .command('rebuild-embeddings')
86
+ .description('Rebuild local embedding cache for hybrid search (uses all-MiniLM-L6-v2)')
87
+ .option('-v, --vault <path>', 'Vault path')
88
+ .option('--force', 'Force rebuild all embeddings (ignore cache)')
89
+ .action(async (options) => {
90
+ try {
91
+ const { rebuildEmbeddingsCommand } = await import('../dist/commands/rebuild-embeddings.js');
92
+ await rebuildEmbeddingsCommand({
93
+ vaultPath: options.vault,
94
+ force: options.force
95
+ });
96
+ } catch (err) {
97
+ console.error(chalk.red(`Error: ${err.message}`));
98
+ process.exit(1);
99
+ }
100
+ });
101
+
83
102
  // === COMPAT (OpenClaw compatibility) ===
84
103
  program
85
104
  .command('compat')
@@ -9,13 +9,15 @@ export function registerQueryCommands(
9
9
  getVault,
10
10
  resolveVaultPath,
11
11
  QmdUnavailableError,
12
- printQmdMissing
12
+ QmdConfigurationError,
13
+ printQmdMissing,
14
+ printQmdConfigError
13
15
  }
14
16
  ) {
15
17
  // === SEARCH ===
16
18
  program
17
19
  .command('search <query>')
18
- .description('Search the vault via qmd (BM25)')
20
+ .description('Search the vault via qmd (BM25), optionally with semantic hybrid search')
19
21
  .option('-n, --limit <n>', 'Max results (default: 10)', '10')
20
22
  .option('-c, --category <category>', 'Filter by category')
21
23
  .option('--tags <tags>', 'Filter by tags (comma-separated)')
@@ -23,20 +25,57 @@ export function registerQueryCommands(
23
25
  .option('--full', 'Include full content in results')
24
26
  .option('-v, --vault <path>', 'Vault path')
25
27
  .option('--json', 'Output as JSON')
28
+ .option('--semantic', 'Enable hybrid search (BM25 + semantic with RRF)')
29
+ .option('--rebuild-embeddings', 'Rebuild the embedding cache before searching')
26
30
  .action(async (query, options) => {
27
31
  try {
32
+ const vaultPath = resolveVaultPath(options.vault);
28
33
  const vault = await getVault(options.vault);
29
34
 
30
- const results = await vault.find(query, {
31
- limit: parseInt(options.limit, 10),
35
+ // Handle --rebuild-embeddings flag
36
+ if (options.rebuildEmbeddings) {
37
+ const { rebuildEmbeddingsForVault } = await import('../dist/commands/rebuild-embeddings.js');
38
+ console.log(chalk.cyan('Rebuilding embedding cache...'));
39
+ const stats = await rebuildEmbeddingsForVault(vaultPath, {
40
+ onProgress: (current, total) => {
41
+ process.stdout.write(`\r Embedding ${current}/${total} documents...`);
42
+ }
43
+ });
44
+ console.log(chalk.green(`\n Done. ${stats.total} embeddings (${stats.added} new, ${stats.skipped} cached)`));
45
+ console.log();
46
+ }
47
+
48
+ // Get BM25 results
49
+ const bm25Results = await vault.find(query, {
50
+ limit: options.semantic ? 50 : parseInt(options.limit, 10),
32
51
  category: options.category,
33
52
  tags: options.tags?.split(',').map((value) => value.trim()),
34
53
  fullContent: options.full,
35
54
  temporalBoost: options.recent
36
55
  });
37
56
 
57
+ let results = bm25Results;
58
+ let searchMode = 'BM25';
59
+
60
+ // Apply hybrid search if --semantic flag is set
61
+ if (options.semantic) {
62
+ const { EmbeddingCache, hybridSearch } = await import('../dist/lib/hybrid-search.js');
63
+ const cache = new EmbeddingCache(vaultPath);
64
+ cache.load();
65
+
66
+ if (cache.size === 0) {
67
+ console.log(chalk.yellow('Warning: No embeddings found. Run with --rebuild-embeddings to build the cache.'));
68
+ } else {
69
+ results = await hybridSearch(query, bm25Results, cache, {
70
+ topK: parseInt(options.limit, 10),
71
+ rrfK: 60
72
+ });
73
+ searchMode = 'Hybrid (BM25 + Semantic)';
74
+ }
75
+ }
76
+
38
77
  if (options.json) {
39
- console.log(JSON.stringify(results, null, 2));
78
+ console.log(JSON.stringify({ searchMode, results }, null, 2));
40
79
  return;
41
80
  }
42
81
 
@@ -45,7 +84,8 @@ export function registerQueryCommands(
45
84
  return;
46
85
  }
47
86
 
48
- console.log(chalk.cyan(`\n🔍 Found ${results.length} result(s) for "${query}":\n`));
87
+ const icon = options.semantic ? '🔍🧠' : '🔍';
88
+ console.log(chalk.cyan(`\n${icon} Found ${results.length} result(s) for "${query}" [${searchMode}]:\n`));
49
89
 
50
90
  for (const result of results) {
51
91
  const scoreBar = '█'.repeat(Math.round(result.score * 10)).padEnd(10, '░');
@@ -62,6 +102,10 @@ export function registerQueryCommands(
62
102
  printQmdMissing();
63
103
  process.exit(1);
64
104
  }
105
+ if (err instanceof QmdConfigurationError) {
106
+ printQmdConfigError(err);
107
+ process.exit(1);
108
+ }
65
109
  console.error(chalk.red(`Error: ${err.message}`));
66
110
  process.exit(1);
67
111
  }
@@ -117,6 +161,10 @@ export function registerQueryCommands(
117
161
  printQmdMissing();
118
162
  process.exit(1);
119
163
  }
164
+ if (err instanceof QmdConfigurationError) {
165
+ printQmdConfigError(err);
166
+ process.exit(1);
167
+ }
120
168
  console.error(chalk.red(`Error: ${err.message}`));
121
169
  process.exit(1);
122
170
  }
@@ -163,6 +211,10 @@ export function registerQueryCommands(
163
211
  printQmdMissing();
164
212
  process.exit(1);
165
213
  }
214
+ if (err instanceof QmdConfigurationError) {
215
+ printQmdConfigError(err);
216
+ process.exit(1);
217
+ }
166
218
  console.error(chalk.red(`Error: ${err.message}`));
167
219
  process.exit(1);
168
220
  }