clawvault 2.6.1 → 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.
- package/README.md +352 -20
- package/bin/clawvault.js +8 -2
- package/bin/command-runtime.js +9 -1
- package/bin/register-maintenance-commands.js +19 -0
- package/bin/register-query-commands.js +58 -6
- package/bin/register-workgraph-commands.js +451 -0
- package/dist/{chunk-VXEOHTSL.js → chunk-2JQ3O2YL.js} +1 -1
- package/dist/{chunk-VR5NE7PZ.js → chunk-2RAZ4ZFE.js} +1 -1
- package/dist/chunk-2ZDO52B4.js +52 -0
- package/dist/chunk-4BQTQMJP.js +93 -0
- package/dist/{chunk-MAKNAHAW.js → chunk-5PJ4STIC.js} +98 -8
- package/dist/{chunk-IEVLHNLU.js → chunk-627Q3QWK.js} +3 -3
- package/dist/{chunk-R6SXNSFD.js → chunk-6NYYDNNG.js} +3 -3
- package/dist/chunk-ECRZL5XR.js +50 -0
- package/dist/chunk-GNJL4YGR.js +79 -0
- package/dist/{chunk-OZ7RIXTO.js → chunk-IIOU45CK.js} +1 -1
- package/dist/chunk-L4HSSQ6T.js +152 -0
- package/dist/{chunk-XAVB4GB4.js → chunk-LIGHWOH6.js} +1 -1
- package/dist/{chunk-PBEE567J.js → chunk-LUBZXECN.js} +2 -2
- package/dist/{chunk-UEOUADMO.js → chunk-MFL6EEPF.js} +204 -35
- package/dist/chunk-MM6QGW3P.js +207 -0
- package/dist/{chunk-T76H47ZS.js → chunk-MNPUYCHQ.js} +1 -1
- package/dist/{chunk-TLGBDTYT.js → chunk-MPOSMDMU.js} +6 -6
- package/dist/{chunk-RVYA52PY.js → chunk-NJYJL5AA.js} +1 -1
- package/dist/{chunk-Q2J5YTUF.js → chunk-OQGYFZ4A.js} +669 -33
- package/dist/{chunk-ME37YNW3.js → chunk-P7SY3D4E.js} +3 -3
- package/dist/chunk-RHISK3SZ.js +189 -0
- package/dist/{chunk-3BTHWPMB.js → chunk-S5OJEGFG.js} +2 -2
- package/dist/{chunk-MGDEINGP.js → chunk-SS4B7P7V.js} +1 -1
- package/dist/chunk-U4O6C46S.js +154 -0
- package/dist/{chunk-ITPEXLHA.js → chunk-URXDAUVH.js} +24 -5
- package/dist/chunk-WIOLLGAD.js +190 -0
- package/dist/chunk-WMGIIABP.js +15 -0
- package/dist/{chunk-QVMXF7FY.js → chunk-X3SPPUFG.js} +50 -0
- package/dist/{chunk-THRJVD4L.js → chunk-Y6VJKXGL.js} +1 -1
- package/dist/{chunk-KL4NAOMO.js → chunk-YDWHS4LJ.js} +49 -9
- package/dist/{chunk-4VRIMU4O.js → chunk-YNIPYN4F.js} +4 -4
- package/dist/{chunk-HIHOUSXS.js → chunk-YXQCA6B7.js} +105 -1
- package/dist/cli/index.js +18 -16
- package/dist/commands/archive.js +3 -2
- package/dist/commands/backlog.js +1 -0
- package/dist/commands/blocked.js +1 -0
- package/dist/commands/canvas.js +1 -0
- package/dist/commands/checkpoint.js +1 -0
- package/dist/commands/compat.js +2 -1
- package/dist/commands/context.js +5 -3
- package/dist/commands/doctor.d.ts +10 -1
- package/dist/commands/doctor.js +11 -8
- package/dist/commands/embed.js +5 -3
- package/dist/commands/entities.js +2 -1
- package/dist/commands/graph.js +3 -2
- package/dist/commands/inject.d.ts +1 -1
- package/dist/commands/inject.js +4 -3
- package/dist/commands/kanban.js +1 -0
- package/dist/commands/link.js +2 -1
- package/dist/commands/migrate-observations.js +3 -2
- package/dist/commands/observe.js +8 -6
- package/dist/commands/project.js +1 -0
- package/dist/commands/rebuild-embeddings.d.ts +21 -0
- package/dist/commands/rebuild-embeddings.js +91 -0
- package/dist/commands/rebuild.js +6 -4
- package/dist/commands/recover.js +1 -0
- package/dist/commands/reflect.js +5 -4
- package/dist/commands/repair-session.js +1 -0
- package/dist/commands/replay.js +7 -6
- package/dist/commands/session-recap.js +1 -0
- package/dist/commands/setup.js +3 -2
- package/dist/commands/shell-init.js +2 -0
- package/dist/commands/sleep.d.ts +1 -1
- package/dist/commands/sleep.js +8 -6
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +35 -24
- package/dist/commands/sync-bd.js +3 -2
- package/dist/commands/tailscale.js +3 -2
- package/dist/commands/task.js +1 -0
- package/dist/commands/template.js +1 -0
- package/dist/commands/wake.d.ts +1 -1
- package/dist/commands/wake.js +4 -2
- package/dist/index.d.ts +333 -10
- package/dist/index.js +320 -33
- package/dist/{inject-x65KXWPk.d.ts → inject-DYUrDqQO.d.ts} +2 -2
- package/dist/ledger-B7g7jhqG.d.ts +44 -0
- package/dist/lib/auto-linker.js +1 -0
- package/dist/lib/canvas-layout.js +1 -0
- package/dist/lib/config.d.ts +27 -3
- package/dist/lib/config.js +4 -1
- package/dist/lib/entity-index.js +1 -0
- package/dist/lib/project-utils.js +1 -0
- package/dist/lib/session-repair.js +1 -0
- package/dist/lib/session-utils.js +1 -0
- package/dist/lib/tailscale.js +1 -0
- package/dist/lib/task-utils.js +1 -0
- package/dist/lib/template-engine.js +1 -0
- package/dist/lib/webdav.js +1 -0
- package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
- package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
- package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
- package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
- package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
- package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
- package/dist/registry-BR4326o0.d.ts +30 -0
- package/dist/store-CA-6sKCJ.d.ts +34 -0
- package/dist/thread-B9LhXNU0.d.ts +41 -0
- package/dist/transformers.node-A2ZRORSQ.js +46775 -0
- package/dist/{types-C74wgGL1.d.ts → types-BbWJoC1c.d.ts} +1 -1
- package/dist/workgraph/index.d.ts +5 -0
- package/dist/workgraph/index.js +23 -0
- package/dist/workgraph/ledger.d.ts +2 -0
- package/dist/workgraph/ledger.js +25 -0
- package/dist/workgraph/registry.d.ts +2 -0
- package/dist/workgraph/registry.js +19 -0
- package/dist/workgraph/store.d.ts +2 -0
- package/dist/workgraph/store.js +25 -0
- package/dist/workgraph/thread.d.ts +2 -0
- package/dist/workgraph/thread.js +25 -0
- package/dist/workgraph/types.d.ts +54 -0
- package/dist/workgraph/types.js +7 -0
- package/hooks/clawvault/HOOK.md +34 -4
- package/hooks/clawvault/handler.js +751 -8
- package/hooks/clawvault/handler.test.js +247 -0
- package/hooks/clawvault/openclaw.plugin.json +72 -0
- package/openclaw.plugin.json +84 -0
- package/package.json +8 -4
- package/dist/chunk-4QYGFWRM.js +0 -88
- package/dist/chunk-MXSSG3QU.js +0 -42
package/README.md
CHANGED
|
@@ -1,17 +1,301 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# ClawVault 🐘
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
**Persistent Memory for AI Agents**
|
|
4
6
|
|
|
7
|
+
[](https://github.com/Versatly/clawvault)
|
|
5
8
|
[](https://www.npmjs.com/package/clawvault)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
[](https://github.com/Versatly/clawvault/pulls?q=is%3Amerged)
|
|
11
|
+
[](https://github.com/Versatly/clawvault/graphs/contributors)
|
|
12
|
+
|
|
13
|
+
*An elephant never forgets. Neither should your AI.*
|
|
14
|
+
|
|
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
|
|
6
156
|
|
|
7
|
-
|
|
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
|
+
---
|
|
8
271
|
|
|
9
272
|
## Requirements
|
|
10
273
|
|
|
11
274
|
- Node.js 18+
|
|
12
|
-
- `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:
|
|
13
280
|
|
|
14
|
-
|
|
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
|
+
```
|
|
15
299
|
|
|
16
300
|
## Install
|
|
17
301
|
|
|
@@ -68,35 +352,39 @@ Append these to your existing memory workflow. Do not replace your full prompt s
|
|
|
68
352
|
- Use `clawvault context "<task>"` or `clawvault inject "<message>"` before complex decisions.
|
|
69
353
|
```
|
|
70
354
|
|
|
71
|
-
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## CLI Reference
|
|
72
358
|
|
|
73
|
-
Core
|
|
359
|
+
### Core Commands
|
|
74
360
|
|
|
75
361
|
- `init`, `setup`, `store`, `capture`
|
|
76
362
|
- `remember`, `list`, `get`, `stats`, `reindex`, `sync`
|
|
77
363
|
|
|
78
|
-
Context +
|
|
364
|
+
### Context + Memory
|
|
79
365
|
|
|
80
366
|
- `search`, `vsearch`, `context`, `inject`
|
|
81
367
|
- `observe`, `reflect`, `session-recap`
|
|
82
368
|
- `graph`, `entities`, `link`, `embed`
|
|
83
369
|
|
|
84
|
-
Resilience
|
|
370
|
+
### Resilience
|
|
85
371
|
|
|
86
372
|
- `wake`, `sleep`, `handoff`, `recap`
|
|
87
373
|
- `checkpoint`, `recover`, `status`, `clean-exit`, `repair-session`
|
|
88
374
|
- `compat`, `doctor`
|
|
89
375
|
|
|
90
|
-
Execution
|
|
376
|
+
### Execution Primitives
|
|
91
377
|
|
|
92
378
|
- `task ...`, `backlog ...`, `blocked`, `project ...`, `kanban ...`
|
|
93
379
|
- `canvas` (generates default `dashboard.canvas`)
|
|
94
380
|
|
|
95
|
-
Networking
|
|
381
|
+
### Networking
|
|
96
382
|
|
|
97
383
|
- `tailscale-status`, `tailscale-sync`, `tailscale-serve`, `tailscale-discover`
|
|
98
384
|
|
|
99
|
-
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Quick Usage Examples
|
|
100
388
|
|
|
101
389
|
```bash
|
|
102
390
|
# Store and retrieve memory
|
|
@@ -119,15 +407,7 @@ clawvault kanban sync
|
|
|
119
407
|
clawvault canvas
|
|
120
408
|
```
|
|
121
409
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- Setup can generate:
|
|
125
|
-
- graph theme/snippet config (`--theme neural|minimal|none`)
|
|
126
|
-
- Bases views (`all-tasks.base`, `blocked.base`, `by-project.base`, `by-owner.base`, `backlog.base`)
|
|
127
|
-
- default canvas (`dashboard.canvas`) via `--canvas` or `clawvault canvas`
|
|
128
|
-
- Kanban round-trip:
|
|
129
|
-
- export: `clawvault kanban sync`
|
|
130
|
-
- import lane changes back to task metadata: `clawvault kanban import`
|
|
410
|
+
---
|
|
131
411
|
|
|
132
412
|
## Tailscale + WebDAV
|
|
133
413
|
|
|
@@ -139,6 +419,29 @@ clawvault tailscale-serve --vault ~/memory
|
|
|
139
419
|
clawvault tailscale-discover
|
|
140
420
|
```
|
|
141
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
|
+
|
|
142
445
|
## Troubleshooting
|
|
143
446
|
|
|
144
447
|
- Hook not found after enable:
|
|
@@ -154,6 +457,35 @@ clawvault tailscale-discover
|
|
|
154
457
|
- Session transcript corruption:
|
|
155
458
|
- run `clawvault repair-session --dry-run` then `clawvault repair-session`
|
|
156
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
|
+
|
|
157
489
|
## License
|
|
158
490
|
|
|
159
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
|
-
|
|
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
|
-
|
|
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 });
|
package/bin/command-runtime.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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
|
}
|