clawvault 3.1.0 → 3.2.0

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 (289) hide show
  1. package/README.md +422 -141
  2. package/bin/clawvault.js +10 -2
  3. package/bin/command-registration.test.js +3 -1
  4. package/bin/command-runtime.js +9 -1
  5. package/bin/register-core-commands.js +23 -28
  6. package/bin/register-maintenance-commands.js +39 -3
  7. package/bin/register-query-commands.js +58 -29
  8. package/bin/register-tailscale-commands.js +106 -0
  9. package/bin/register-task-commands.js +18 -1
  10. package/bin/register-task-commands.test.js +16 -0
  11. package/bin/register-vault-operations-commands.js +29 -1
  12. package/bin/register-workgraph-commands.js +1368 -0
  13. package/dashboard/lib/graph-diff.js +104 -0
  14. package/dashboard/lib/graph-diff.test.js +75 -0
  15. package/dashboard/lib/vault-parser.js +556 -0
  16. package/dashboard/lib/vault-parser.test.js +254 -0
  17. package/dashboard/public/app.js +796 -0
  18. package/dashboard/public/index.html +52 -0
  19. package/dashboard/public/styles.css +221 -0
  20. package/dashboard/server.js +374 -0
  21. package/dist/{chunk-F2JEUD4J.js → chunk-23YDQ3QU.js} +6 -8
  22. package/dist/{chunk-C7OK5WKP.js → chunk-2JQ3O2YL.js} +4 -4
  23. package/dist/{chunk-VR5NE7PZ.js → chunk-2RAZ4ZFE.js} +1 -1
  24. package/dist/chunk-2ZDO52B4.js +52 -0
  25. package/dist/{chunk-ZZA73MFY.js → chunk-33DOSHTA.js} +176 -36
  26. package/dist/chunk-33VSQP4J.js +37 -0
  27. package/dist/chunk-4BQTQMJP.js +93 -0
  28. package/dist/{chunk-GUKMRGM7.js → chunk-4OXMU5S2.js} +1 -1
  29. package/dist/{chunk-62YTUT6J.js → chunk-4PY655YM.js} +15 -3
  30. package/dist/chunk-6FH3IULF.js +352 -0
  31. package/dist/{chunk-3NSBOUT3.js → chunk-77Q5CSPJ.js} +404 -80
  32. package/dist/{chunk-4VQTUVH7.js → chunk-7YZWHM36.js} +52 -26
  33. package/dist/chunk-BSJ6RIT7.js +447 -0
  34. package/dist/chunk-BUEW6IIK.js +364 -0
  35. package/dist/{chunk-LI4O6NVK.js → chunk-CLJTREDS.js} +74 -14
  36. package/dist/chunk-EK6S23ZB.js +469 -0
  37. package/dist/{chunk-LNJA2UGL.js → chunk-ESFLMDRB.js} +9 -86
  38. package/dist/{chunk-H34S76MB.js → chunk-ESVS6K2B.js} +6 -6
  39. package/dist/{chunk-WAZ3NLWL.js → chunk-F55HGNU4.js} +0 -47
  40. package/dist/{chunk-QK3UCXWL.js → chunk-FHFUXL6G.js} +2 -2
  41. package/dist/{chunk-H62BP7RI.js → chunk-GAOWA7GR.js} +212 -46
  42. package/dist/chunk-GGA32J2R.js +784 -0
  43. package/dist/chunk-GNJL4YGR.js +79 -0
  44. package/dist/chunk-IVRIKYFE.js +520 -0
  45. package/dist/chunk-MDIH26GC.js +183 -0
  46. package/dist/{chunk-LYHGEHXG.js → chunk-MFAWT5O5.js} +0 -1
  47. package/dist/chunk-MM6QGW3P.js +207 -0
  48. package/dist/{chunk-P5EPF6MB.js → chunk-MW5C6ZQA.js} +110 -13
  49. package/dist/chunk-NCKFNBHJ.js +257 -0
  50. package/dist/{chunk-QBLMXKF2.js → chunk-OIWVQYQF.js} +1 -1
  51. package/dist/{chunk-42MXU7A6.js → chunk-P62WHA27.js} +58 -47
  52. package/dist/chunk-PBACDKKP.js +66 -0
  53. package/dist/{chunk-VGLOTGAS.js → chunk-QSHD36LH.js} +2 -2
  54. package/dist/{chunk-OZ7RIXTO.js → chunk-QSRRMEYM.js} +2 -2
  55. package/dist/chunk-QVEERJSP.js +152 -0
  56. package/dist/{chunk-N2AXRYLC.js → chunk-QWQ3TIKS.js} +1 -1
  57. package/dist/{chunk-3DHXQHYG.js → chunk-R2MIW5G7.js} +1 -1
  58. package/dist/{chunk-SJSFRIYS.js → chunk-SLXOR3CC.js} +2 -2
  59. package/dist/chunk-SS4B7P7V.js +99 -0
  60. package/dist/{chunk-JY6FYXIT.js → chunk-STCQGCEQ.js} +6 -11
  61. package/dist/chunk-TIGW564L.js +628 -0
  62. package/dist/chunk-U4O6C46S.js +154 -0
  63. package/dist/{chunk-ITPEXLHA.js → chunk-URXDAUVH.js} +24 -5
  64. package/dist/chunk-VSL7KY3M.js +189 -0
  65. package/dist/{chunk-U55BGUAU.js → chunk-W4SPAEE7.js} +6 -6
  66. package/dist/chunk-WMGIIABP.js +15 -0
  67. package/dist/{chunk-33UGEQRT.js → chunk-X3SPPUFG.js} +151 -64
  68. package/dist/chunk-Y6VJKXGL.js +373 -0
  69. package/dist/{chunk-3WRJEKN4.js → chunk-ZN54U2OZ.js} +123 -10
  70. package/dist/cli/index.js +34 -24
  71. package/dist/commands/archive.js +3 -3
  72. package/dist/commands/backlog.js +3 -3
  73. package/dist/commands/blocked.js +3 -3
  74. package/dist/commands/canvas.d.ts +15 -0
  75. package/dist/commands/canvas.js +200 -0
  76. package/dist/commands/checkpoint.js +2 -2
  77. package/dist/commands/compat.js +2 -2
  78. package/dist/commands/context.js +8 -6
  79. package/dist/commands/doctor.d.ts +11 -7
  80. package/dist/commands/doctor.js +18 -16
  81. package/dist/commands/embed.js +5 -6
  82. package/dist/commands/entities.js +2 -2
  83. package/dist/commands/graph.js +4 -4
  84. package/dist/commands/inject.d.ts +1 -1
  85. package/dist/commands/inject.js +5 -6
  86. package/dist/commands/kanban.js +4 -4
  87. package/dist/commands/link.js +5 -5
  88. package/dist/commands/migrate-observations.js +4 -4
  89. package/dist/commands/observe.d.ts +0 -1
  90. package/dist/commands/observe.js +14 -13
  91. package/dist/commands/project.js +5 -5
  92. package/dist/commands/rebuild-embeddings.d.ts +21 -0
  93. package/dist/commands/rebuild-embeddings.js +91 -0
  94. package/dist/commands/rebuild.js +12 -11
  95. package/dist/commands/recover.js +3 -3
  96. package/dist/commands/reflect.js +6 -7
  97. package/dist/commands/repair-session.js +1 -1
  98. package/dist/commands/replay.js +14 -14
  99. package/dist/commands/session-recap.js +1 -1
  100. package/dist/commands/setup.d.ts +2 -89
  101. package/dist/commands/setup.js +3 -21
  102. package/dist/commands/shell-init.js +1 -1
  103. package/dist/commands/sleep.d.ts +1 -1
  104. package/dist/commands/sleep.js +20 -19
  105. package/dist/commands/status.d.ts +2 -0
  106. package/dist/commands/status.js +57 -35
  107. package/dist/commands/sync-bd.d.ts +10 -0
  108. package/dist/commands/sync-bd.js +10 -0
  109. package/dist/commands/tailscale.d.ts +52 -0
  110. package/dist/commands/tailscale.js +26 -0
  111. package/dist/commands/task.js +4 -4
  112. package/dist/commands/template.js +2 -2
  113. package/dist/commands/wake.d.ts +1 -1
  114. package/dist/commands/wake.js +11 -10
  115. package/dist/commands/workgraph.d.ts +124 -0
  116. package/dist/commands/workgraph.js +38 -0
  117. package/dist/index.d.ts +341 -191
  118. package/dist/index.js +446 -116
  119. package/dist/{inject-Bzi5E-By.d.ts → inject-DYUrDqQO.d.ts} +3 -3
  120. package/dist/ledger-B7g7jhqG.d.ts +44 -0
  121. package/dist/lib/auto-linker.js +2 -2
  122. package/dist/lib/canvas-layout.d.ts +115 -0
  123. package/dist/lib/canvas-layout.js +35 -0
  124. package/dist/lib/config.d.ts +27 -3
  125. package/dist/lib/config.js +4 -2
  126. package/dist/lib/entity-index.js +1 -1
  127. package/dist/lib/project-utils.js +4 -4
  128. package/dist/lib/session-repair.js +1 -1
  129. package/dist/lib/session-utils.js +1 -1
  130. package/dist/lib/tailscale.d.ts +225 -0
  131. package/dist/lib/tailscale.js +50 -0
  132. package/dist/lib/task-utils.js +3 -3
  133. package/dist/lib/template-engine.js +1 -1
  134. package/dist/lib/webdav.d.ts +109 -0
  135. package/dist/lib/webdav.js +35 -0
  136. package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
  137. package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
  138. package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
  139. package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
  140. package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
  141. package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
  142. package/dist/openclaw-plugin.d.ts +8 -0
  143. package/dist/openclaw-plugin.js +14 -0
  144. package/dist/registry-BR4326o0.d.ts +30 -0
  145. package/dist/store-CA-6sKCJ.d.ts +34 -0
  146. package/dist/thread-B9LhXNU0.d.ts +41 -0
  147. package/dist/transformers.node-A2ZRORSQ.js +46775 -0
  148. package/dist/{types-Y2_Um2Ls.d.ts → types-BbWJoC1c.d.ts} +1 -44
  149. package/dist/workgraph/index.d.ts +5 -0
  150. package/dist/workgraph/index.js +23 -0
  151. package/dist/workgraph/ledger.d.ts +2 -0
  152. package/dist/workgraph/ledger.js +25 -0
  153. package/dist/workgraph/registry.d.ts +2 -0
  154. package/dist/workgraph/registry.js +19 -0
  155. package/dist/workgraph/store.d.ts +2 -0
  156. package/dist/workgraph/store.js +25 -0
  157. package/dist/workgraph/thread.d.ts +2 -0
  158. package/dist/workgraph/thread.js +25 -0
  159. package/dist/workgraph/types.d.ts +54 -0
  160. package/dist/workgraph/types.js +7 -0
  161. package/hooks/clawvault/HOOK.md +113 -0
  162. package/hooks/clawvault/handler.js +1561 -0
  163. package/hooks/clawvault/handler.test.js +510 -0
  164. package/hooks/clawvault/openclaw.plugin.json +72 -0
  165. package/openclaw.plugin.json +65 -38
  166. package/package.json +25 -22
  167. package/dist/chunk-3RG5ZIWI.js +0 -10
  168. package/dist/chunk-3ZIH425O.js +0 -871
  169. package/dist/chunk-6U6MK36V.js +0 -205
  170. package/dist/chunk-CMB7UL7C.js +0 -327
  171. package/dist/chunk-D2H45LON.js +0 -1074
  172. package/dist/chunk-E7MFQB6D.js +0 -163
  173. package/dist/chunk-GQSLDZTS.js +0 -560
  174. package/dist/chunk-MFM6K7PU.js +0 -374
  175. package/dist/chunk-MXSSG3QU.js +0 -42
  176. package/dist/chunk-OCGVIN3L.js +0 -88
  177. package/dist/chunk-PAH27GSN.js +0 -108
  178. package/dist/chunk-YCUNCH2I.js +0 -78
  179. package/dist/cli/index.cjs +0 -8584
  180. package/dist/cli/index.d.cts +0 -5
  181. package/dist/commands/archive.cjs +0 -287
  182. package/dist/commands/archive.d.cts +0 -11
  183. package/dist/commands/backlog.cjs +0 -721
  184. package/dist/commands/backlog.d.cts +0 -53
  185. package/dist/commands/blocked.cjs +0 -204
  186. package/dist/commands/blocked.d.cts +0 -26
  187. package/dist/commands/checkpoint.cjs +0 -244
  188. package/dist/commands/checkpoint.d.cts +0 -41
  189. package/dist/commands/compat.cjs +0 -294
  190. package/dist/commands/compat.d.cts +0 -28
  191. package/dist/commands/context.cjs +0 -2990
  192. package/dist/commands/context.d.cts +0 -2
  193. package/dist/commands/doctor.cjs +0 -2986
  194. package/dist/commands/doctor.d.cts +0 -21
  195. package/dist/commands/embed.cjs +0 -232
  196. package/dist/commands/embed.d.cts +0 -17
  197. package/dist/commands/entities.cjs +0 -141
  198. package/dist/commands/entities.d.cts +0 -7
  199. package/dist/commands/graph.cjs +0 -501
  200. package/dist/commands/graph.d.cts +0 -21
  201. package/dist/commands/inject.cjs +0 -1636
  202. package/dist/commands/inject.d.cts +0 -2
  203. package/dist/commands/kanban.cjs +0 -884
  204. package/dist/commands/kanban.d.cts +0 -63
  205. package/dist/commands/link.cjs +0 -965
  206. package/dist/commands/link.d.cts +0 -11
  207. package/dist/commands/migrate-observations.cjs +0 -362
  208. package/dist/commands/migrate-observations.d.cts +0 -19
  209. package/dist/commands/observe.cjs +0 -4099
  210. package/dist/commands/observe.d.cts +0 -23
  211. package/dist/commands/project.cjs +0 -1341
  212. package/dist/commands/project.d.cts +0 -85
  213. package/dist/commands/rebuild.cjs +0 -3136
  214. package/dist/commands/rebuild.d.cts +0 -11
  215. package/dist/commands/recover.cjs +0 -361
  216. package/dist/commands/recover.d.cts +0 -38
  217. package/dist/commands/reflect.cjs +0 -1008
  218. package/dist/commands/reflect.d.cts +0 -11
  219. package/dist/commands/repair-session.cjs +0 -457
  220. package/dist/commands/repair-session.d.cts +0 -38
  221. package/dist/commands/replay.cjs +0 -4103
  222. package/dist/commands/replay.d.cts +0 -16
  223. package/dist/commands/session-recap.cjs +0 -353
  224. package/dist/commands/session-recap.d.cts +0 -27
  225. package/dist/commands/setup.cjs +0 -1278
  226. package/dist/commands/setup.d.cts +0 -99
  227. package/dist/commands/shell-init.cjs +0 -75
  228. package/dist/commands/shell-init.d.cts +0 -7
  229. package/dist/commands/sleep.cjs +0 -6029
  230. package/dist/commands/sleep.d.cts +0 -36
  231. package/dist/commands/status.cjs +0 -2737
  232. package/dist/commands/status.d.cts +0 -52
  233. package/dist/commands/task.cjs +0 -1236
  234. package/dist/commands/task.d.cts +0 -97
  235. package/dist/commands/template.cjs +0 -457
  236. package/dist/commands/template.d.cts +0 -36
  237. package/dist/commands/wake.cjs +0 -2627
  238. package/dist/commands/wake.d.cts +0 -22
  239. package/dist/context-BUGaWpyL.d.cts +0 -46
  240. package/dist/index.cjs +0 -12373
  241. package/dist/index.d.cts +0 -854
  242. package/dist/inject-Bzi5E-By.d.cts +0 -137
  243. package/dist/lib/auto-linker.cjs +0 -176
  244. package/dist/lib/auto-linker.d.cts +0 -26
  245. package/dist/lib/config.cjs +0 -78
  246. package/dist/lib/config.d.cts +0 -11
  247. package/dist/lib/entity-index.cjs +0 -84
  248. package/dist/lib/entity-index.d.cts +0 -26
  249. package/dist/lib/project-utils.cjs +0 -864
  250. package/dist/lib/project-utils.d.cts +0 -97
  251. package/dist/lib/session-repair.cjs +0 -239
  252. package/dist/lib/session-repair.d.cts +0 -110
  253. package/dist/lib/session-utils.cjs +0 -209
  254. package/dist/lib/session-utils.d.cts +0 -63
  255. package/dist/lib/task-utils.cjs +0 -1137
  256. package/dist/lib/task-utils.d.cts +0 -208
  257. package/dist/lib/template-engine.cjs +0 -47
  258. package/dist/lib/template-engine.d.cts +0 -11
  259. package/dist/plugin/index.cjs +0 -1907
  260. package/dist/plugin/index.d.cts +0 -36
  261. package/dist/plugin/index.d.ts +0 -36
  262. package/dist/plugin/index.js +0 -572
  263. package/dist/plugin/inject.cjs +0 -356
  264. package/dist/plugin/inject.d.cts +0 -54
  265. package/dist/plugin/inject.d.ts +0 -54
  266. package/dist/plugin/inject.js +0 -17
  267. package/dist/plugin/observe.cjs +0 -631
  268. package/dist/plugin/observe.d.cts +0 -39
  269. package/dist/plugin/observe.d.ts +0 -39
  270. package/dist/plugin/observe.js +0 -18
  271. package/dist/plugin/templates.cjs +0 -593
  272. package/dist/plugin/templates.d.cts +0 -52
  273. package/dist/plugin/templates.d.ts +0 -52
  274. package/dist/plugin/templates.js +0 -25
  275. package/dist/plugin/types.cjs +0 -18
  276. package/dist/plugin/types.d.cts +0 -209
  277. package/dist/plugin/types.d.ts +0 -209
  278. package/dist/plugin/types.js +0 -0
  279. package/dist/plugin/vault.cjs +0 -927
  280. package/dist/plugin/vault.d.cts +0 -68
  281. package/dist/plugin/vault.d.ts +0 -68
  282. package/dist/plugin/vault.js +0 -22
  283. package/dist/types-Y2_Um2Ls.d.cts +0 -205
  284. package/templates/memory-event.md +0 -67
  285. package/templates/party.md +0 -63
  286. package/templates/primitive-registry.yaml +0 -551
  287. package/templates/run.md +0 -68
  288. package/templates/trigger.md +0 -68
  289. package/templates/workspace.md +0 -50
@@ -1,36 +0,0 @@
1
- import { TemplateRegistry } from './templates.cjs';
2
- export { classifyText, getAllSchemas, getSchema, getSchemaNames, initializeTemplateRegistry } from './templates.cjs';
3
- export { detectCategory, extractObservations, extractSearchTerms, isObservable, processMessageForObservations } from './observe.cjs';
4
- export { buildFullContext, buildPreferenceContext, buildSessionRecap, formatMemoriesForContext, formatSearchResults, scanVaultFiles } from './inject.cjs';
5
- export { appendToLedger, batchWriteObservations, ensureVaultStructure, writeObservation, writeVaultFile } from './vault.cjs';
6
-
7
- /**
8
- * ClawVault OpenClaw Plugin v2.2.0
9
- *
10
- * Memory slot provider for OpenClaw. Template-driven observational memory architecture:
11
- * memories are captured automatically from conversations, classified against template
12
- * schemas, and stored with proper frontmatter validation.
13
- *
14
- * Architecture:
15
- * ClawVault (engine) ←→ Plugin (integration) ←→ OpenClaw (agent platform)
16
- * - ClawVault = vault, observations, search index, knowledge graph
17
- * - Plugin = auto-recall, auto-capture, search tools, lifecycle hooks
18
- * - OpenClaw = agent runtime, sessions, tools, channels
19
- * - Templates = schema definitions for primitive types
20
- *
21
- * The plugin does NOT give the agent a "store memory" tool. Memory is
22
- * observational: the system watches conversations and captures automatically.
23
- * The agent searches memory; it doesn't manage it.
24
- */
25
-
26
- declare function getTemplateRegistry(): TemplateRegistry | null;
27
- declare const clawvaultPlugin: {
28
- id: string;
29
- name: string;
30
- description: string;
31
- version: string;
32
- kind: "memory";
33
- register(api: any): void;
34
- };
35
-
36
- export { clawvaultPlugin as default, getTemplateRegistry };
@@ -1,36 +0,0 @@
1
- import { TemplateRegistry } from './templates.js';
2
- export { classifyText, getAllSchemas, getSchema, getSchemaNames, initializeTemplateRegistry } from './templates.js';
3
- export { detectCategory, extractObservations, extractSearchTerms, isObservable, processMessageForObservations } from './observe.js';
4
- export { buildFullContext, buildPreferenceContext, buildSessionRecap, formatMemoriesForContext, formatSearchResults, scanVaultFiles } from './inject.js';
5
- export { appendToLedger, batchWriteObservations, ensureVaultStructure, writeObservation, writeVaultFile } from './vault.js';
6
-
7
- /**
8
- * ClawVault OpenClaw Plugin v2.2.0
9
- *
10
- * Memory slot provider for OpenClaw. Template-driven observational memory architecture:
11
- * memories are captured automatically from conversations, classified against template
12
- * schemas, and stored with proper frontmatter validation.
13
- *
14
- * Architecture:
15
- * ClawVault (engine) ←→ Plugin (integration) ←→ OpenClaw (agent platform)
16
- * - ClawVault = vault, observations, search index, knowledge graph
17
- * - Plugin = auto-recall, auto-capture, search tools, lifecycle hooks
18
- * - OpenClaw = agent runtime, sessions, tools, channels
19
- * - Templates = schema definitions for primitive types
20
- *
21
- * The plugin does NOT give the agent a "store memory" tool. Memory is
22
- * observational: the system watches conversations and captures automatically.
23
- * The agent searches memory; it doesn't manage it.
24
- */
25
-
26
- declare function getTemplateRegistry(): TemplateRegistry | null;
27
- declare const clawvaultPlugin: {
28
- id: string;
29
- name: string;
30
- description: string;
31
- version: string;
32
- kind: "memory";
33
- register(api: any): void;
34
- };
35
-
36
- export { clawvaultPlugin as default, getTemplateRegistry };
@@ -1,572 +0,0 @@
1
- import {
2
- buildFullContext,
3
- buildPreferenceContext,
4
- buildSessionRecap,
5
- formatMemoriesForContext,
6
- formatSearchResults,
7
- scanVaultFiles
8
- } from "../chunk-CMB7UL7C.js";
9
- import {
10
- detectCategory,
11
- extractObservations,
12
- extractSearchTerms,
13
- isObservable,
14
- processMessageForObservations
15
- } from "../chunk-6U6MK36V.js";
16
- import {
17
- appendToLedger,
18
- batchWriteObservations,
19
- ensureVaultStructure,
20
- writeObservation,
21
- writeVaultFile
22
- } from "../chunk-MFM6K7PU.js";
23
- import {
24
- classifyText,
25
- getAllSchemas,
26
- getSchema,
27
- getSchemaNames,
28
- initializeTemplateRegistry
29
- } from "../chunk-GQSLDZTS.js";
30
- import {
31
- __require
32
- } from "../chunk-3RG5ZIWI.js";
33
-
34
- // src/plugin/index.ts
35
- import { execFileSync, execFile } from "child_process";
36
- import { existsSync, readFileSync, mkdirSync } from "fs";
37
- import { join, basename } from "path";
38
- import { Type } from "@sinclair/typebox";
39
- function resolveVaultPath(cfg) {
40
- if (cfg?.vaultPath) return cfg.vaultPath;
41
- if (process.env.CLAWVAULT_PATH) return process.env.CLAWVAULT_PATH;
42
- const home = process.env.HOME ?? process.env.USERPROFILE ?? ".";
43
- for (const candidate of [`${home}/clawvault`, `${home}/.clawvault`]) {
44
- if (existsSync(join(candidate, ".clawvault.json"))) return candidate;
45
- }
46
- return `${home}/.clawvault`;
47
- }
48
- function getVaultConfig(vaultPath) {
49
- const configPath = join(vaultPath, ".clawvault.json");
50
- if (!existsSync(configPath)) return null;
51
- try {
52
- return JSON.parse(readFileSync(configPath, "utf-8"));
53
- } catch {
54
- return null;
55
- }
56
- }
57
- function qmdHybridSearch(query, collection, limit = 10) {
58
- const sanitized = query.replace(/['']/g, " ").replace(/[^\w\s\-.,?!]/g, " ").trim();
59
- if (!sanitized) return [];
60
- try {
61
- const result = execFileSync("qmd", [
62
- "query",
63
- sanitized,
64
- "-n",
65
- String(limit),
66
- "--json",
67
- "-c",
68
- collection
69
- ], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer: 10 * 1024 * 1024, timeout: 3e4 });
70
- const parsed = JSON.parse(result);
71
- if (Array.isArray(parsed) && parsed.length > 0) return parsed;
72
- } catch (err) {
73
- if (err?.stdout) {
74
- try {
75
- const parsed = JSON.parse(err.stdout);
76
- if (Array.isArray(parsed) && parsed.length > 0) return parsed;
77
- } catch {
78
- }
79
- }
80
- }
81
- try {
82
- const result = execFileSync("qmd", [
83
- "search",
84
- sanitized,
85
- "-n",
86
- String(limit),
87
- "--json",
88
- "-c",
89
- collection
90
- ], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer: 10 * 1024 * 1024, timeout: 15e3 });
91
- return JSON.parse(result);
92
- } catch (err) {
93
- if (err?.stdout) {
94
- try {
95
- return JSON.parse(err.stdout);
96
- } catch {
97
- }
98
- }
99
- return [];
100
- }
101
- }
102
- function observe(vaultPath, content, meta = {}) {
103
- try {
104
- const args = ["observe", "--content", content];
105
- if (meta.tags?.length) args.push("--tags", meta.tags.join(","));
106
- execFile("clawvault", args, { cwd: vaultPath, timeout: 15e3 }, () => {
107
- });
108
- } catch {
109
- }
110
- }
111
- function qmdUpdateAsync(collection) {
112
- try {
113
- execFile("qmd", ["update", "-c", collection], { timeout: 3e4 }, () => {
114
- });
115
- execFile("qmd", ["embed", "-c", collection], { timeout: 6e4 }, () => {
116
- });
117
- } catch {
118
- }
119
- }
120
- var templateRegistry = null;
121
- function getTemplateRegistry() {
122
- return templateRegistry;
123
- }
124
- var clawvaultPlugin = {
125
- id: "clawvault",
126
- name: "ClawVault Memory",
127
- description: "Template-driven observational memory with hybrid search. Memories are captured automatically from conversations and classified against template schemas.",
128
- version: "3.1.0",
129
- kind: "memory",
130
- register(api) {
131
- const vaultPath = resolveVaultPath(api.pluginConfig);
132
- const collection = api.pluginConfig?.collection || "clawvault";
133
- const autoRecall = api.pluginConfig?.autoRecall !== false;
134
- const autoCapture = api.pluginConfig?.autoCapture !== false;
135
- const recallLimit = api.pluginConfig?.recallLimit || 5;
136
- const templatesDir = api.pluginConfig?.templatesDir ?? join(vaultPath, "..", "..", "templates");
137
- templateRegistry = initializeTemplateRegistry(templatesDir);
138
- api.logger.info(`[clawvault] Template registry initialized with ${templateRegistry.schemas.size} schemas`);
139
- if (!existsSync(join(vaultPath, ".clawvault.json"))) {
140
- api.logger.warn(`[clawvault] Vault not found at ${vaultPath}`);
141
- return;
142
- }
143
- ensureVaultStructure(vaultPath);
144
- api.logger.info(`[clawvault] v2.2.0 vault=${vaultPath} collection=${collection} recall=${autoRecall} capture=${autoCapture}`);
145
- api.registerTool({
146
- name: "memory_search",
147
- label: "Memory Search",
148
- description: "Search through long-term memories using ClawVault. Supports preferences, temporal queries, and multi-session knowledge retrieval.",
149
- parameters: Type.Object({
150
- query: Type.String({ description: "Search query \u2014 natural language question or keyword search" }),
151
- limit: Type.Optional(Type.Number({ description: "Max results (default: 10)" })),
152
- queryType: Type.Optional(Type.Union([
153
- Type.Literal("preference"),
154
- Type.Literal("temporal"),
155
- Type.Literal("knowledge"),
156
- Type.Literal("general")
157
- ], { description: "Force query type (auto-detected if omitted)" }))
158
- }),
159
- async execute(_id, params) {
160
- try {
161
- let searchQuery = params.query;
162
- if (params.queryType === "preference") searchQuery = `preference: ${searchQuery}`;
163
- else if (params.queryType === "temporal") searchQuery = `when: ${searchQuery}`;
164
- const limit = params.limit || 10;
165
- const results = qmdHybridSearch(searchQuery, collection, limit);
166
- if (results.length === 0) {
167
- return {
168
- content: [{ type: "text", text: "No relevant memories found." }],
169
- details: { count: 0, provider: "clawvault" }
170
- };
171
- }
172
- return {
173
- content: [{ type: "text", text: formatSearchResults(results, collection) }],
174
- details: { count: results.length, provider: "clawvault" }
175
- };
176
- } catch (err) {
177
- return {
178
- content: [{ type: "text", text: `Memory search error: ${String(err)}` }],
179
- isError: true
180
- };
181
- }
182
- }
183
- });
184
- api.registerTool({
185
- name: "memory_get",
186
- label: "Memory Get",
187
- description: "Get vault status or stored preferences.",
188
- parameters: Type.Object({
189
- action: Type.Union([
190
- Type.Literal("status"),
191
- Type.Literal("preferences")
192
- ], { description: "What to retrieve" })
193
- }),
194
- async execute(_id, params) {
195
- try {
196
- if (params.action === "status") {
197
- const config = getVaultConfig(vaultPath);
198
- let docCount = 0;
199
- let vectorCount = 0;
200
- try {
201
- const stats = execFileSync("qmd", ["status", "--json", "-c", collection], {
202
- encoding: "utf-8",
203
- timeout: 5e3,
204
- stdio: ["ignore", "pipe", "pipe"]
205
- });
206
- const parsed = JSON.parse(stats);
207
- docCount = parsed.documents ?? parsed.doc_count ?? 0;
208
- vectorCount = parsed.vectors ?? parsed.vector_count ?? 0;
209
- } catch {
210
- }
211
- return {
212
- content: [{ type: "text", text: JSON.stringify({
213
- vault: vaultPath,
214
- name: config?.name || "clawvault",
215
- collection,
216
- documents: docCount,
217
- vectors: vectorCount,
218
- autoRecall,
219
- autoCapture,
220
- version: "3.1.0",
221
- templateSchemas: templateRegistry?.schemas.size ?? 0
222
- }, null, 2) }]
223
- };
224
- }
225
- const prefContext = buildPreferenceContext(vaultPath, { limit: 20 });
226
- if (prefContext.preferenceCount === 0) {
227
- const results = qmdHybridSearch("user preference likes dislikes prefers wants", collection, 20);
228
- const prefResults = results.filter(
229
- (r) => r.file?.includes("preference") || r.snippet?.toLowerCase().match(/prefer|like|want|hate|love|always|never/)
230
- );
231
- if (prefResults.length === 0) {
232
- return { content: [{ type: "text", text: "No preferences found in vault." }] };
233
- }
234
- const text = prefResults.map((r, i) => {
235
- const file = (r.file || "").replace(`qmd://${collection}/`, "");
236
- const snippet = (r.snippet || "").replace(/@@ .+? @@\s*\(.+?\)\n?/g, "").trim() || r.title;
237
- return `${i + 1}. [${file}] ${snippet}`;
238
- }).join("\n");
239
- return { content: [{ type: "text", text }] };
240
- }
241
- return { content: [{ type: "text", text: prefContext.xml }] };
242
- } catch (err) {
243
- return {
244
- content: [{ type: "text", text: `Memory get error: ${String(err)}` }],
245
- isError: true
246
- };
247
- }
248
- }
249
- });
250
- api.registerTool({
251
- name: "memory_store",
252
- label: "Memory Store",
253
- description: "Save important information in long-term memory. Use for preferences, facts, decisions, or anything worth remembering.",
254
- parameters: Type.Object({
255
- text: Type.String({ description: "Information to remember" }),
256
- category: Type.Optional(Type.Union([
257
- Type.Literal("preference"),
258
- Type.Literal("fact"),
259
- Type.Literal("decision"),
260
- Type.Literal("entity"),
261
- Type.Literal("event"),
262
- Type.Literal("other")
263
- ], { description: "Memory category (auto-detected if omitted)" })),
264
- tags: Type.Optional(Type.Array(Type.String(), { description: "Tags for organization" }))
265
- }),
266
- async execute(_id, params) {
267
- try {
268
- const classification = classifyText(params.text);
269
- const category = params.category || detectCategory(params.text);
270
- const tags = params.tags || [category, ...classification.matchedKeywords.slice(0, 3)];
271
- const result = writeVaultFile(vaultPath, {
272
- primitiveType: classification.primitiveType,
273
- title: params.text.slice(0, 80),
274
- content: params.text,
275
- extraFields: {
276
- type: category,
277
- confidence: classification.confidence,
278
- tags
279
- },
280
- source: "openclaw"
281
- });
282
- appendToLedger(vaultPath, {
283
- timestamp: /* @__PURE__ */ new Date(),
284
- category,
285
- content: params.text,
286
- primitiveType: classification.primitiveType,
287
- tags
288
- });
289
- qmdUpdateAsync(collection);
290
- return {
291
- content: [{ type: "text", text: `Stored: "${params.text.slice(0, 100)}${params.text.length > 100 ? "..." : ""}" [${classification.primitiveType}/${category}]` }],
292
- details: {
293
- action: result.created ? "created" : "updated",
294
- category,
295
- primitiveType: classification.primitiveType,
296
- path: result.path
297
- }
298
- };
299
- } catch (err) {
300
- return {
301
- content: [{ type: "text", text: `Memory store error: ${String(err)}` }],
302
- isError: true
303
- };
304
- }
305
- }
306
- });
307
- api.registerTool({
308
- name: "memory_forget",
309
- label: "Memory Forget",
310
- description: "Delete specific memories from the vault.",
311
- parameters: Type.Object({
312
- query: Type.String({ description: "Search query to find the memory to delete" }),
313
- confirm: Type.Optional(Type.Boolean({ description: "Set true to confirm deletion of first match" }))
314
- }),
315
- async execute(_id, params) {
316
- try {
317
- const results = qmdHybridSearch(params.query, collection, 5);
318
- if (results.length === 0) {
319
- return {
320
- content: [{ type: "text", text: "No matching memories found." }],
321
- details: { found: 0 }
322
- };
323
- }
324
- if (!params.confirm) {
325
- const list = results.map((r, i) => {
326
- const file2 = (r.file || "").replace(`qmd://${collection}/`, "");
327
- const snippet = (r.snippet || "").replace(/@@ .+? @@\s*\(.+?\)\n?/g, "").trim().slice(0, 80);
328
- return `${i + 1}. [${file2}] ${snippet}`;
329
- }).join("\n");
330
- return {
331
- content: [{ type: "text", text: `Found ${results.length} candidates:
332
- ${list}
333
-
334
- Call again with confirm=true to delete the top match.` }],
335
- details: { action: "candidates", count: results.length }
336
- };
337
- }
338
- const target = results[0];
339
- const file = (target.file || "").replace(`qmd://${collection}/`, "");
340
- const fullPath = join(vaultPath, file);
341
- if (existsSync(fullPath)) {
342
- const trashDir = join(vaultPath, ".trash");
343
- if (!existsSync(trashDir)) mkdirSync(trashDir, { recursive: true });
344
- const trashPath = join(trashDir, `${Date.now()}-${basename(file)}`);
345
- const { renameSync } = __require("fs");
346
- renameSync(fullPath, trashPath);
347
- qmdUpdateAsync(collection);
348
- return {
349
- content: [{ type: "text", text: `Forgotten: [${file}] (moved to .trash)` }],
350
- details: { action: "deleted", file, trashPath }
351
- };
352
- }
353
- return {
354
- content: [{ type: "text", text: `File not found on disk: ${file}` }],
355
- details: { action: "not_found", file }
356
- };
357
- } catch (err) {
358
- return {
359
- content: [{ type: "text", text: `Memory forget error: ${String(err)}` }],
360
- isError: true
361
- };
362
- }
363
- }
364
- });
365
- if (autoRecall) {
366
- api.on("before_agent_start", async (event) => {
367
- if (!event.prompt || event.prompt.length < 10) return;
368
- if (event.prompt.includes("HEARTBEAT") || event.prompt.startsWith("[System")) return;
369
- try {
370
- const contextParts = [];
371
- const recap = buildSessionRecap(vaultPath, {
372
- maxAge: 24 * 60 * 60 * 1e3,
373
- // 24 hours
374
- limit: 10,
375
- includeContent: true
376
- });
377
- if (recap.xml) {
378
- contextParts.push(recap.xml);
379
- }
380
- const searchTerms = extractSearchTerms(event.prompt);
381
- const results = qmdHybridSearch(searchTerms, collection, recallLimit);
382
- if (results.length > 0) {
383
- const topScore = results[0]?.score ?? 0;
384
- if (topScore >= 0.25) {
385
- contextParts.push(formatMemoriesForContext(results, collection));
386
- api.logger.info(`[clawvault] auto-recall: ${results.length} memories (top: ${(topScore * 100).toFixed(0)}%, query: "${searchTerms.slice(0, 60)}")`);
387
- }
388
- }
389
- if (contextParts.length === 0) return;
390
- return {
391
- prependContext: contextParts.join("\n\n")
392
- };
393
- } catch (err) {
394
- api.logger.warn(`[clawvault] auto-recall failed: ${String(err)}`);
395
- }
396
- }, { priority: 10 });
397
- }
398
- if (autoCapture) {
399
- api.on("message_received", async (event) => {
400
- if (!event.content || !isObservable(event.content)) return;
401
- try {
402
- const result = processMessageForObservations(event.content, {
403
- from: event.from,
404
- sessionId: event.sessionId
405
- });
406
- if (result.observations.length === 0) return;
407
- const writeResult = batchWriteObservations(vaultPath, result.observations, {
408
- source: "openclaw",
409
- sessionId: event.sessionId,
410
- actor: event.from || "user",
411
- writeLedger: true,
412
- writeFiles: false
413
- // Only write to ledger for speed
414
- });
415
- api.logger.info(`[clawvault] auto-captured ${writeResult.successful} observations from incoming message`);
416
- } catch (err) {
417
- api.logger.warn(`[clawvault] message capture failed: ${String(err)}`);
418
- }
419
- });
420
- api.on("agent_end", async (event) => {
421
- if (!event.success || !event.messages?.length) return;
422
- try {
423
- let captured = 0;
424
- for (const msg of event.messages) {
425
- if (!msg || typeof msg !== "object") continue;
426
- if (msg.role === "user") {
427
- const content = typeof msg.content === "string" ? msg.content : Array.isArray(msg.content) ? msg.content.filter((b) => b?.type === "text").map((b) => b.text).join(" ") : "";
428
- if (isObservable(content)) {
429
- const result = processMessageForObservations(content);
430
- for (const obs of result.observations) {
431
- observe(vaultPath, obs.text, { tags: obs.tags });
432
- captured++;
433
- }
434
- }
435
- }
436
- }
437
- if (captured > 0) {
438
- api.logger.info(`[clawvault] agent_end: captured ${captured} observations`);
439
- qmdUpdateAsync(collection);
440
- }
441
- } catch (err) {
442
- api.logger.warn(`[clawvault] agent_end capture failed: ${String(err)}`);
443
- }
444
- });
445
- }
446
- api.on("before_compaction", async () => {
447
- try {
448
- execFileSync("qmd", ["update", "-c", collection], {
449
- timeout: 15e3,
450
- encoding: "utf-8",
451
- stdio: ["ignore", "pipe", "pipe"]
452
- });
453
- api.logger.info("[clawvault] pre-compaction index update complete");
454
- } catch (err) {
455
- api.logger.warn(`[clawvault] pre-compaction update failed: ${String(err)}`);
456
- }
457
- });
458
- api.registerService({
459
- id: "clawvault",
460
- start: () => {
461
- api.logger.info(`[clawvault] service started \u2014 vault=${vaultPath}`);
462
- qmdUpdateAsync(collection);
463
- },
464
- stop: () => {
465
- api.logger.info("[clawvault] service stopped");
466
- }
467
- });
468
- api.registerCli(
469
- ({ program }) => {
470
- const cmd = program.command("vault").description("ClawVault memory commands");
471
- cmd.command("status").action(() => {
472
- const config = getVaultConfig(vaultPath);
473
- console.log(JSON.stringify({
474
- vault: vaultPath,
475
- version: "3.1.0",
476
- templateSchemas: templateRegistry?.schemas.size ?? 0,
477
- ...config
478
- }, null, 2));
479
- });
480
- cmd.command("search <query>").option("-n, --limit <n>", "Max results", "10").action((query, opts) => {
481
- const results = qmdHybridSearch(query, collection, parseInt(opts.limit));
482
- console.log(formatSearchResults(results, collection));
483
- });
484
- cmd.command("templates").action(() => {
485
- const schemas = getAllSchemas();
486
- console.log("Registered template schemas:");
487
- for (const schema of schemas) {
488
- console.log(` - ${schema.primitive}: ${schema.description || "(no description)"}`);
489
- console.log(` Fields: ${Object.keys(schema.fields).join(", ")}`);
490
- }
491
- });
492
- cmd.command("classify <text>").action((text) => {
493
- const result = classifyText(text);
494
- console.log(JSON.stringify(result, null, 2));
495
- });
496
- },
497
- { commands: ["vault"] }
498
- );
499
- api.registerCommand({
500
- name: "vault",
501
- description: "ClawVault status and quick search",
502
- acceptsArgs: true,
503
- requireAuth: true,
504
- handler: (ctx) => {
505
- const args = (ctx.args || "").trim();
506
- if (!args || args === "status") {
507
- const config = getVaultConfig(vaultPath);
508
- let docCount = 0, vectorCount = 0;
509
- try {
510
- const stats = execFileSync("qmd", ["status", "--json", "-c", collection], {
511
- encoding: "utf-8",
512
- timeout: 5e3,
513
- stdio: ["ignore", "pipe", "pipe"]
514
- });
515
- const p = JSON.parse(stats);
516
- docCount = p.documents ?? p.doc_count ?? 0;
517
- vectorCount = p.vectors ?? p.vector_count ?? 0;
518
- } catch {
519
- }
520
- return {
521
- text: `\u{1F9E0} ClawVault v2.2.0
522
- Vault: ${vaultPath}
523
- Docs: ${docCount} | Vectors: ${vectorCount}
524
- Recall: ${autoRecall ? "\u2705" : "\u274C"} | Capture: ${autoCapture ? "\u2705" : "\u274C"}
525
- Templates: ${templateRegistry?.schemas.size ?? 0} schemas`
526
- };
527
- }
528
- if (args.startsWith("search ")) {
529
- const query = args.slice(7).trim();
530
- const results = qmdHybridSearch(query, collection, 5);
531
- return { text: formatSearchResults(results, collection) };
532
- }
533
- if (args === "templates") {
534
- const names = getSchemaNames();
535
- return { text: `Template schemas: ${names.join(", ")}` };
536
- }
537
- if (args === "recap") {
538
- const recap = buildSessionRecap(vaultPath, { limit: 10, includeContent: true });
539
- return { text: recap.xml || "No recent activity found." };
540
- }
541
- return { text: "Usage: /vault [status|search <query>|templates|recap]" };
542
- }
543
- });
544
- console.log(`[clawvault] v2.2.0 registered \u2014 vault=${vaultPath} templates=${templateRegistry?.schemas.size ?? 0}`);
545
- }
546
- };
547
- var plugin_default = clawvaultPlugin;
548
- export {
549
- appendToLedger,
550
- batchWriteObservations,
551
- buildFullContext,
552
- buildPreferenceContext,
553
- buildSessionRecap,
554
- classifyText,
555
- plugin_default as default,
556
- detectCategory,
557
- ensureVaultStructure,
558
- extractObservations,
559
- extractSearchTerms,
560
- formatMemoriesForContext,
561
- formatSearchResults,
562
- getAllSchemas,
563
- getSchema,
564
- getSchemaNames,
565
- getTemplateRegistry,
566
- initializeTemplateRegistry,
567
- isObservable,
568
- processMessageForObservations,
569
- scanVaultFiles,
570
- writeObservation,
571
- writeVaultFile
572
- };