clawvault 3.0.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 (291) hide show
  1. package/README.md +352 -20
  2. package/bin/clawvault.js +8 -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 -10
  6. package/bin/register-maintenance-commands.js +39 -3
  7. package/bin/register-query-commands.js +58 -29
  8. package/bin/register-task-commands.js +18 -1
  9. package/bin/register-task-commands.test.js +16 -0
  10. package/bin/register-vault-operations-commands.js +29 -1
  11. package/bin/register-workgraph-commands.js +1368 -0
  12. package/dashboard/lib/graph-diff.js +104 -0
  13. package/dashboard/lib/graph-diff.test.js +75 -0
  14. package/dashboard/lib/vault-parser.js +556 -0
  15. package/dashboard/lib/vault-parser.test.js +254 -0
  16. package/dashboard/public/app.js +796 -0
  17. package/dashboard/public/index.html +52 -0
  18. package/dashboard/public/styles.css +221 -0
  19. package/dashboard/server.js +374 -0
  20. package/dist/{chunk-F2JEUD4J.js → chunk-23YDQ3QU.js} +6 -8
  21. package/dist/{chunk-C7OK5WKP.js → chunk-2JQ3O2YL.js} +4 -4
  22. package/dist/{chunk-VR5NE7PZ.js → chunk-2RAZ4ZFE.js} +1 -1
  23. package/dist/chunk-2ZDO52B4.js +52 -0
  24. package/dist/{chunk-ZZA73MFY.js → chunk-33DOSHTA.js} +176 -36
  25. package/dist/chunk-33VSQP4J.js +37 -0
  26. package/dist/chunk-4BQTQMJP.js +93 -0
  27. package/dist/{chunk-GUKMRGM7.js → chunk-4OXMU5S2.js} +1 -1
  28. package/dist/{chunk-62YTUT6J.js → chunk-4PY655YM.js} +15 -3
  29. package/dist/chunk-6FH3IULF.js +352 -0
  30. package/dist/{chunk-3NSBOUT3.js → chunk-77Q5CSPJ.js} +404 -80
  31. package/dist/{chunk-4VQTUVH7.js → chunk-7YZWHM36.js} +52 -26
  32. package/dist/chunk-BSJ6RIT7.js +447 -0
  33. package/dist/chunk-BUEW6IIK.js +364 -0
  34. package/dist/{chunk-WGRQ6HDV.js → chunk-CLJTREDS.js} +74 -14
  35. package/dist/chunk-EK6S23ZB.js +469 -0
  36. package/dist/{chunk-LNJA2UGL.js → chunk-ESFLMDRB.js} +9 -86
  37. package/dist/{chunk-H34S76MB.js → chunk-ESVS6K2B.js} +6 -6
  38. package/dist/{chunk-WAZ3NLWL.js → chunk-F55HGNU4.js} +0 -47
  39. package/dist/{chunk-QK3UCXWL.js → chunk-FHFUXL6G.js} +2 -2
  40. package/dist/{chunk-YKTA5JOJ.js → chunk-GAOWA7GR.js} +212 -46
  41. package/dist/chunk-GGA32J2R.js +784 -0
  42. package/dist/chunk-GNJL4YGR.js +79 -0
  43. package/dist/chunk-MDIH26GC.js +183 -0
  44. package/dist/{chunk-LYHGEHXG.js → chunk-MFAWT5O5.js} +0 -1
  45. package/dist/chunk-MM6QGW3P.js +207 -0
  46. package/dist/{chunk-P5EPF6MB.js → chunk-MW5C6ZQA.js} +110 -13
  47. package/dist/chunk-NCKFNBHJ.js +257 -0
  48. package/dist/{chunk-QBLMXKF2.js → chunk-OIWVQYQF.js} +1 -1
  49. package/dist/{chunk-42MXU7A6.js → chunk-P62WHA27.js} +58 -47
  50. package/dist/chunk-PBACDKKP.js +66 -0
  51. package/dist/{chunk-VGLOTGAS.js → chunk-QSHD36LH.js} +2 -2
  52. package/dist/{chunk-OZ7RIXTO.js → chunk-QSRRMEYM.js} +2 -2
  53. package/dist/chunk-QVEERJSP.js +152 -0
  54. package/dist/{chunk-N2AXRYLC.js → chunk-QWQ3TIKS.js} +1 -1
  55. package/dist/{chunk-3DHXQHYG.js → chunk-R2MIW5G7.js} +1 -1
  56. package/dist/{chunk-SJSFRIYS.js → chunk-SLXOR3CC.js} +2 -2
  57. package/dist/chunk-SS4B7P7V.js +99 -0
  58. package/dist/{chunk-JY6FYXIT.js → chunk-STCQGCEQ.js} +6 -11
  59. package/dist/chunk-U4O6C46S.js +154 -0
  60. package/dist/{chunk-ITPEXLHA.js → chunk-URXDAUVH.js} +24 -5
  61. package/dist/chunk-VSL7KY3M.js +189 -0
  62. package/dist/{chunk-U55BGUAU.js → chunk-W4SPAEE7.js} +6 -6
  63. package/dist/chunk-WMGIIABP.js +15 -0
  64. package/dist/{chunk-3D6BCTP6.js → chunk-X3SPPUFG.js} +51 -39
  65. package/dist/{chunk-THRJVD4L.js → chunk-Y6VJKXGL.js} +1 -1
  66. package/dist/{chunk-ZVVFWOLW.js → chunk-ZN54U2OZ.js} +123 -10
  67. package/dist/cli/index.js +32 -25
  68. package/dist/commands/archive.js +3 -3
  69. package/dist/commands/backlog.js +3 -3
  70. package/dist/commands/blocked.js +3 -3
  71. package/dist/commands/canvas.d.ts +15 -0
  72. package/dist/commands/canvas.js +200 -0
  73. package/dist/commands/checkpoint.js +2 -2
  74. package/dist/commands/compat.js +2 -2
  75. package/dist/commands/context.js +8 -6
  76. package/dist/commands/doctor.d.ts +11 -7
  77. package/dist/commands/doctor.js +18 -16
  78. package/dist/commands/embed.js +5 -6
  79. package/dist/commands/entities.js +2 -2
  80. package/dist/commands/graph.js +4 -4
  81. package/dist/commands/inject.d.ts +1 -1
  82. package/dist/commands/inject.js +5 -6
  83. package/dist/commands/kanban.js +4 -4
  84. package/dist/commands/link.js +5 -5
  85. package/dist/commands/migrate-observations.js +4 -4
  86. package/dist/commands/observe.d.ts +0 -1
  87. package/dist/commands/observe.js +14 -13
  88. package/dist/commands/project.js +5 -5
  89. package/dist/commands/rebuild-embeddings.d.ts +21 -0
  90. package/dist/commands/rebuild-embeddings.js +91 -0
  91. package/dist/commands/rebuild.js +12 -11
  92. package/dist/commands/recover.js +3 -3
  93. package/dist/commands/reflect.js +6 -7
  94. package/dist/commands/repair-session.js +1 -1
  95. package/dist/commands/replay.js +14 -14
  96. package/dist/commands/session-recap.js +1 -1
  97. package/dist/commands/setup.d.ts +2 -90
  98. package/dist/commands/setup.js +3 -21
  99. package/dist/commands/shell-init.js +1 -1
  100. package/dist/commands/sleep.d.ts +1 -1
  101. package/dist/commands/sleep.js +20 -19
  102. package/dist/commands/status.d.ts +2 -0
  103. package/dist/commands/status.js +57 -35
  104. package/dist/commands/sync-bd.d.ts +10 -0
  105. package/dist/commands/sync-bd.js +10 -0
  106. package/dist/commands/tailscale.js +3 -3
  107. package/dist/commands/task.js +4 -4
  108. package/dist/commands/template.js +2 -2
  109. package/dist/commands/wake.d.ts +1 -1
  110. package/dist/commands/wake.js +11 -10
  111. package/dist/commands/workgraph.d.ts +124 -0
  112. package/dist/commands/workgraph.js +38 -0
  113. package/dist/index.d.ts +337 -191
  114. package/dist/index.js +387 -118
  115. package/dist/{inject-Bzi5E-By.d.cts → inject-DYUrDqQO.d.ts} +3 -3
  116. package/dist/ledger-B7g7jhqG.d.ts +44 -0
  117. package/dist/lib/auto-linker.js +2 -2
  118. package/dist/lib/canvas-layout.d.ts +100 -16
  119. package/dist/lib/canvas-layout.js +21 -78
  120. package/dist/lib/config.d.ts +27 -3
  121. package/dist/lib/config.js +4 -2
  122. package/dist/lib/entity-index.js +1 -1
  123. package/dist/lib/project-utils.js +4 -4
  124. package/dist/lib/session-repair.js +1 -1
  125. package/dist/lib/session-utils.js +1 -1
  126. package/dist/lib/tailscale.js +1 -1
  127. package/dist/lib/task-utils.js +3 -3
  128. package/dist/lib/template-engine.js +1 -1
  129. package/dist/lib/webdav.js +1 -1
  130. package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
  131. package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
  132. package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
  133. package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
  134. package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
  135. package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
  136. package/dist/openclaw-plugin.d.ts +8 -0
  137. package/dist/openclaw-plugin.js +14 -0
  138. package/dist/registry-BR4326o0.d.ts +30 -0
  139. package/dist/store-CA-6sKCJ.d.ts +34 -0
  140. package/dist/thread-B9LhXNU0.d.ts +41 -0
  141. package/dist/transformers.node-A2ZRORSQ.js +46775 -0
  142. package/dist/{types-Y2_Um2Ls.d.cts → types-BbWJoC1c.d.ts} +1 -44
  143. package/dist/workgraph/index.d.ts +5 -0
  144. package/dist/workgraph/index.js +23 -0
  145. package/dist/workgraph/ledger.d.ts +2 -0
  146. package/dist/workgraph/ledger.js +25 -0
  147. package/dist/workgraph/registry.d.ts +2 -0
  148. package/dist/workgraph/registry.js +19 -0
  149. package/dist/workgraph/store.d.ts +2 -0
  150. package/dist/workgraph/store.js +25 -0
  151. package/dist/workgraph/thread.d.ts +2 -0
  152. package/dist/workgraph/thread.js +25 -0
  153. package/dist/workgraph/types.d.ts +54 -0
  154. package/dist/workgraph/types.js +7 -0
  155. package/hooks/clawvault/HOOK.md +34 -4
  156. package/hooks/clawvault/handler.js +760 -78
  157. package/hooks/clawvault/handler.test.js +235 -79
  158. package/hooks/clawvault/openclaw.plugin.json +72 -0
  159. package/openclaw.plugin.json +65 -38
  160. package/package.json +15 -18
  161. package/dist/chunk-3RG5ZIWI.js +0 -10
  162. package/dist/chunk-6U6MK36V.js +0 -205
  163. package/dist/chunk-7R7O6STJ.js +0 -88
  164. package/dist/chunk-CMB7UL7C.js +0 -327
  165. package/dist/chunk-DEFFDRVP.js +0 -938
  166. package/dist/chunk-E7MFQB6D.js +0 -163
  167. package/dist/chunk-GAJV4IGR.js +0 -82
  168. package/dist/chunk-GQSLDZTS.js +0 -560
  169. package/dist/chunk-K234IDRJ.js +0 -1073
  170. package/dist/chunk-MFM6K7PU.js +0 -374
  171. package/dist/chunk-MXSSG3QU.js +0 -42
  172. package/dist/chunk-PAH27GSN.js +0 -108
  173. package/dist/cli/index.cjs +0 -10033
  174. package/dist/cli/index.d.cts +0 -5
  175. package/dist/commands/archive.cjs +0 -287
  176. package/dist/commands/archive.d.cts +0 -11
  177. package/dist/commands/backlog.cjs +0 -721
  178. package/dist/commands/backlog.d.cts +0 -53
  179. package/dist/commands/blocked.cjs +0 -204
  180. package/dist/commands/blocked.d.cts +0 -26
  181. package/dist/commands/checkpoint.cjs +0 -244
  182. package/dist/commands/checkpoint.d.cts +0 -41
  183. package/dist/commands/compat.cjs +0 -369
  184. package/dist/commands/compat.d.cts +0 -28
  185. package/dist/commands/context.cjs +0 -2989
  186. package/dist/commands/context.d.cts +0 -2
  187. package/dist/commands/doctor.cjs +0 -3062
  188. package/dist/commands/doctor.d.cts +0 -21
  189. package/dist/commands/embed.cjs +0 -232
  190. package/dist/commands/embed.d.cts +0 -17
  191. package/dist/commands/entities.cjs +0 -141
  192. package/dist/commands/entities.d.cts +0 -7
  193. package/dist/commands/graph.cjs +0 -501
  194. package/dist/commands/graph.d.cts +0 -21
  195. package/dist/commands/inject.cjs +0 -1636
  196. package/dist/commands/inject.d.cts +0 -2
  197. package/dist/commands/kanban.cjs +0 -884
  198. package/dist/commands/kanban.d.cts +0 -63
  199. package/dist/commands/link.cjs +0 -965
  200. package/dist/commands/link.d.cts +0 -11
  201. package/dist/commands/migrate-observations.cjs +0 -362
  202. package/dist/commands/migrate-observations.d.cts +0 -19
  203. package/dist/commands/observe.cjs +0 -4099
  204. package/dist/commands/observe.d.cts +0 -23
  205. package/dist/commands/project.cjs +0 -1341
  206. package/dist/commands/project.d.cts +0 -85
  207. package/dist/commands/rebuild.cjs +0 -3136
  208. package/dist/commands/rebuild.d.cts +0 -11
  209. package/dist/commands/recover.cjs +0 -361
  210. package/dist/commands/recover.d.cts +0 -38
  211. package/dist/commands/reflect.cjs +0 -1008
  212. package/dist/commands/reflect.d.cts +0 -11
  213. package/dist/commands/repair-session.cjs +0 -457
  214. package/dist/commands/repair-session.d.cts +0 -38
  215. package/dist/commands/replay.cjs +0 -4103
  216. package/dist/commands/replay.d.cts +0 -16
  217. package/dist/commands/session-recap.cjs +0 -353
  218. package/dist/commands/session-recap.d.cts +0 -27
  219. package/dist/commands/setup.cjs +0 -1345
  220. package/dist/commands/setup.d.cts +0 -100
  221. package/dist/commands/shell-init.cjs +0 -75
  222. package/dist/commands/shell-init.d.cts +0 -7
  223. package/dist/commands/sleep.cjs +0 -6028
  224. package/dist/commands/sleep.d.cts +0 -36
  225. package/dist/commands/status.cjs +0 -2736
  226. package/dist/commands/status.d.cts +0 -52
  227. package/dist/commands/tailscale.cjs +0 -1532
  228. package/dist/commands/tailscale.d.cts +0 -52
  229. package/dist/commands/task.cjs +0 -1236
  230. package/dist/commands/task.d.cts +0 -97
  231. package/dist/commands/template.cjs +0 -457
  232. package/dist/commands/template.d.cts +0 -36
  233. package/dist/commands/wake.cjs +0 -2626
  234. package/dist/commands/wake.d.cts +0 -22
  235. package/dist/context-BUGaWpyL.d.cts +0 -46
  236. package/dist/index.cjs +0 -14526
  237. package/dist/index.d.cts +0 -858
  238. package/dist/inject-Bzi5E-By.d.ts +0 -137
  239. package/dist/lib/auto-linker.cjs +0 -176
  240. package/dist/lib/auto-linker.d.cts +0 -26
  241. package/dist/lib/canvas-layout.cjs +0 -136
  242. package/dist/lib/canvas-layout.d.cts +0 -31
  243. package/dist/lib/config.cjs +0 -78
  244. package/dist/lib/config.d.cts +0 -11
  245. package/dist/lib/entity-index.cjs +0 -84
  246. package/dist/lib/entity-index.d.cts +0 -26
  247. package/dist/lib/project-utils.cjs +0 -864
  248. package/dist/lib/project-utils.d.cts +0 -97
  249. package/dist/lib/session-repair.cjs +0 -239
  250. package/dist/lib/session-repair.d.cts +0 -110
  251. package/dist/lib/session-utils.cjs +0 -209
  252. package/dist/lib/session-utils.d.cts +0 -63
  253. package/dist/lib/tailscale.cjs +0 -1183
  254. package/dist/lib/tailscale.d.cts +0 -225
  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/lib/webdav.cjs +0 -568
  260. package/dist/lib/webdav.d.cts +0 -109
  261. package/dist/plugin/index.cjs +0 -1907
  262. package/dist/plugin/index.d.cts +0 -36
  263. package/dist/plugin/index.d.ts +0 -36
  264. package/dist/plugin/index.js +0 -572
  265. package/dist/plugin/inject.cjs +0 -356
  266. package/dist/plugin/inject.d.cts +0 -54
  267. package/dist/plugin/inject.d.ts +0 -54
  268. package/dist/plugin/inject.js +0 -17
  269. package/dist/plugin/observe.cjs +0 -631
  270. package/dist/plugin/observe.d.cts +0 -39
  271. package/dist/plugin/observe.d.ts +0 -39
  272. package/dist/plugin/observe.js +0 -18
  273. package/dist/plugin/templates.cjs +0 -593
  274. package/dist/plugin/templates.d.cts +0 -52
  275. package/dist/plugin/templates.d.ts +0 -52
  276. package/dist/plugin/templates.js +0 -25
  277. package/dist/plugin/types.cjs +0 -18
  278. package/dist/plugin/types.d.cts +0 -209
  279. package/dist/plugin/types.d.ts +0 -209
  280. package/dist/plugin/types.js +0 -0
  281. package/dist/plugin/vault.cjs +0 -927
  282. package/dist/plugin/vault.d.cts +0 -68
  283. package/dist/plugin/vault.d.ts +0 -68
  284. package/dist/plugin/vault.js +0 -22
  285. package/dist/types-Y2_Um2Ls.d.ts +0 -205
  286. package/templates/memory-event.md +0 -67
  287. package/templates/party.md +0 -63
  288. package/templates/primitive-registry.yaml +0 -551
  289. package/templates/run.md +0 -68
  290. package/templates/trigger.md +0 -68
  291. 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
- appendToLedger,
3
- batchWriteObservations,
4
- ensureVaultStructure,
5
- writeObservation,
6
- writeVaultFile
7
- } from "../chunk-MFM6K7PU.js";
8
- import {
9
- buildFullContext,
10
- buildPreferenceContext,
11
- buildSessionRecap,
12
- formatMemoriesForContext,
13
- formatSearchResults,
14
- scanVaultFiles
15
- } from "../chunk-CMB7UL7C.js";
16
- import {
17
- detectCategory,
18
- extractObservations,
19
- extractSearchTerms,
20
- isObservable,
21
- processMessageForObservations
22
- } from "../chunk-6U6MK36V.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: "2.2.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: "2.2.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: "2.2.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
- };