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
@@ -0,0 +1,99 @@
1
+ import {
2
+ resolveVaultPath
3
+ } from "./chunk-GNJL4YGR.js";
4
+
5
+ // src/commands/sync-bd.ts
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+ import { spawnSync } from "child_process";
9
+ function hasBdBinary() {
10
+ const probe = spawnSync("bd", ["--version"], { stdio: "ignore" });
11
+ return !probe.error;
12
+ }
13
+ function parseBdTasksFromJson(raw) {
14
+ const parsed = JSON.parse(raw);
15
+ if (!Array.isArray(parsed)) {
16
+ return [];
17
+ }
18
+ return parsed.map((entry) => {
19
+ if (!entry || typeof entry !== "object") return null;
20
+ const record = entry;
21
+ const title = typeof record.title === "string" ? record.title.trim() : typeof record.name === "string" ? record.name.trim() : "";
22
+ const status = typeof record.status === "string" ? record.status.trim().toLowerCase() : void 0;
23
+ if (!title) return null;
24
+ return status ? { title, status } : { title };
25
+ }).filter((entry) => entry !== null);
26
+ }
27
+ function loadActiveBdTasks() {
28
+ const jsonAttempt = spawnSync("bd", ["list", "--json"], { encoding: "utf-8" });
29
+ if (!jsonAttempt.error && typeof jsonAttempt.stdout === "string" && jsonAttempt.stdout.trim()) {
30
+ const tasks = parseBdTasksFromJson(jsonAttempt.stdout);
31
+ if (tasks.length > 0) {
32
+ return tasks.filter((task) => task.status !== "done" && task.status !== "completed" && task.status !== "closed");
33
+ }
34
+ }
35
+ const textAttempt = spawnSync("bd", ["list"], { encoding: "utf-8" });
36
+ if (textAttempt.error || typeof textAttempt.stdout !== "string") {
37
+ return [];
38
+ }
39
+ return textAttempt.stdout.split(/\r?\n/).map((line) => line.replace(/^\s*[-*]\s*/, "").trim()).filter(Boolean).map((title) => ({ title }));
40
+ }
41
+ function upsertSection(markdown, heading, bulletLines) {
42
+ const lines = markdown.split(/\r?\n/);
43
+ const headingIndex = lines.findIndex((line) => line.trim() === heading);
44
+ const sectionContent = [heading, ...bulletLines];
45
+ if (headingIndex === -1) {
46
+ const prefix = markdown.trim() ? `${markdown.trim()}
47
+
48
+ ` : "";
49
+ return `${prefix}${sectionContent.join("\n")}
50
+ `;
51
+ }
52
+ let sectionEnd = lines.length;
53
+ for (let index = headingIndex + 1; index < lines.length; index += 1) {
54
+ if (lines[index].startsWith("## ")) {
55
+ sectionEnd = index;
56
+ break;
57
+ }
58
+ }
59
+ const updated = [
60
+ ...lines.slice(0, headingIndex),
61
+ ...sectionContent,
62
+ ...lines.slice(sectionEnd)
63
+ ];
64
+ return `${updated.join("\n").trim()}
65
+ `;
66
+ }
67
+ async function syncBdCommand(options) {
68
+ if (!hasBdBinary()) {
69
+ console.log("bd binary not found; skipping sync-bd.");
70
+ return;
71
+ }
72
+ const tasks = loadActiveBdTasks();
73
+ const vaultPath = resolveVaultPath({ explicitPath: options.vaultPath });
74
+ const nowViewPath = path.join(vaultPath, "views", "now.md");
75
+ const heading = "## Active Tasks (from bd)";
76
+ const bulletLines = tasks.length > 0 ? tasks.map((task) => `- ${task.title}`) : ["- No active bd tasks."];
77
+ const existing = fs.existsSync(nowViewPath) ? fs.readFileSync(nowViewPath, "utf-8") : "# Now\n";
78
+ const next = upsertSection(existing, heading, bulletLines);
79
+ if (options.dryRun) {
80
+ console.log(`Dry run: would sync ${tasks.length} active bd task(s) to views/now.md.`);
81
+ return;
82
+ }
83
+ fs.mkdirSync(path.dirname(nowViewPath), { recursive: true });
84
+ fs.writeFileSync(nowViewPath, next, "utf-8");
85
+ console.log(`Synced ${tasks.length} active bd task(s) to views/now.md.`);
86
+ }
87
+ function registerSyncBdCommand(program) {
88
+ program.command("sync-bd").description("Sync active bd tasks into views/now.md").option("--dry-run", "Show task sync output without writing").option("-v, --vault <path>", "Vault path").action(async (rawOptions) => {
89
+ await syncBdCommand({
90
+ vaultPath: rawOptions.vault,
91
+ dryRun: rawOptions.dryRun
92
+ });
93
+ });
94
+ }
95
+
96
+ export {
97
+ syncBdCommand,
98
+ registerSyncBdCommand
99
+ };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  runReflection
3
- } from "./chunk-H34S76MB.js";
3
+ } from "./chunk-ESVS6K2B.js";
4
4
  import {
5
5
  Observer
6
- } from "./chunk-3NSBOUT3.js";
6
+ } from "./chunk-77Q5CSPJ.js";
7
7
  import {
8
8
  resolveVaultPath
9
- } from "./chunk-MXSSG3QU.js";
9
+ } from "./chunk-GNJL4YGR.js";
10
10
 
11
11
  // src/commands/replay.ts
12
12
  import * as fs from "fs";
@@ -135,8 +135,7 @@ function pushMessage(destination, conversationId, record) {
135
135
  if (!text) {
136
136
  return;
137
137
  }
138
- const rawRole = typeof record.role === "string" ? record.role : typeof record.sender === "string" ? record.sender : void 0;
139
- const role = rawRole ? rawRole.trim().toLowerCase() : void 0;
138
+ const role = typeof record.role === "string" ? record.role.trim().toLowerCase() : void 0;
140
139
  destination.push({
141
140
  source: "claude",
142
141
  conversationId,
@@ -152,9 +151,8 @@ function normalizeClaudeExport(input) {
152
151
  if (!item || typeof item !== "object") continue;
153
152
  const record = item;
154
153
  const conversationId = typeof record.id === "string" ? record.id : typeof record.uuid === "string" ? record.uuid : void 0;
155
- const recordMessages = Array.isArray(record.messages) ? record.messages : Array.isArray(record.chat_messages) ? record.chat_messages : void 0;
156
- if (recordMessages) {
157
- for (const message of recordMessages) {
154
+ if (Array.isArray(record.messages)) {
155
+ for (const message of record.messages) {
158
156
  if (!message || typeof message !== "object") continue;
159
157
  pushMessage(messages, conversationId, message);
160
158
  }
@@ -172,9 +170,6 @@ function normalizeClaudeExport(input) {
172
170
  if (Array.isArray(root.messages)) {
173
171
  return normalizeClaudeExport([{ id: root.id, messages: root.messages }]);
174
172
  }
175
- if (Array.isArray(root.chat_messages)) {
176
- return normalizeClaudeExport([{ id: root.id, chat_messages: root.chat_messages }]);
177
- }
178
173
  }
179
174
  return messages;
180
175
  }
@@ -0,0 +1,154 @@
1
+ // src/lib/hybrid-search.ts
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ var embeddingPipeline = null;
5
+ var pipelineLoading = null;
6
+ async function getEmbeddingPipeline() {
7
+ if (embeddingPipeline) return embeddingPipeline;
8
+ if (pipelineLoading) return pipelineLoading;
9
+ pipelineLoading = (async () => {
10
+ const { pipeline } = await import("./transformers.node-A2ZRORSQ.js");
11
+ embeddingPipeline = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2", {
12
+ dtype: "fp32"
13
+ });
14
+ return embeddingPipeline;
15
+ })();
16
+ return pipelineLoading;
17
+ }
18
+ async function embed(text) {
19
+ const pipe = await getEmbeddingPipeline();
20
+ const result = await pipe(text, { pooling: "mean", normalize: true });
21
+ return new Float32Array(result.data);
22
+ }
23
+ async function embedBatch(texts) {
24
+ const pipe = await getEmbeddingPipeline();
25
+ const results = [];
26
+ const batchSize = 32;
27
+ for (let i = 0; i < texts.length; i += batchSize) {
28
+ const batch = texts.slice(i, i + batchSize);
29
+ for (const text of batch) {
30
+ const result = await pipe(text, { pooling: "mean", normalize: true });
31
+ results.push(new Float32Array(result.data));
32
+ }
33
+ }
34
+ return results;
35
+ }
36
+ function cosineSimilarity(a, b) {
37
+ let dot = 0;
38
+ for (let i = 0; i < a.length; i++) {
39
+ dot += a[i] * b[i];
40
+ }
41
+ return dot;
42
+ }
43
+ var EmbeddingCache = class {
44
+ cachePath;
45
+ cache = /* @__PURE__ */ new Map();
46
+ dirty = false;
47
+ constructor(vaultPath) {
48
+ this.cachePath = path.join(vaultPath, ".clawvault", "embeddings.bin");
49
+ }
50
+ /**
51
+ * Load cache from disk
52
+ */
53
+ load() {
54
+ try {
55
+ if (!fs.existsSync(this.cachePath)) return;
56
+ const data = JSON.parse(fs.readFileSync(this.cachePath + ".json", "utf-8"));
57
+ for (const [key, arr] of Object.entries(data)) {
58
+ this.cache.set(key, new Float32Array(arr));
59
+ }
60
+ } catch {
61
+ }
62
+ }
63
+ /**
64
+ * Save cache to disk
65
+ */
66
+ save() {
67
+ if (!this.dirty) return;
68
+ const dir = path.dirname(this.cachePath);
69
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
70
+ const data = {};
71
+ for (const [key, arr] of this.cache.entries()) {
72
+ data[key] = Array.from(arr);
73
+ }
74
+ fs.writeFileSync(this.cachePath + ".json", JSON.stringify(data));
75
+ this.dirty = false;
76
+ }
77
+ get(key) {
78
+ return this.cache.get(key);
79
+ }
80
+ set(key, embedding) {
81
+ this.cache.set(key, embedding);
82
+ this.dirty = true;
83
+ }
84
+ has(key) {
85
+ return this.cache.has(key);
86
+ }
87
+ entries() {
88
+ return this.cache.entries();
89
+ }
90
+ get size() {
91
+ return this.cache.size;
92
+ }
93
+ };
94
+ function reciprocalRankFusion(list1, list2, k = 60) {
95
+ const scores = /* @__PURE__ */ new Map();
96
+ for (let rank = 0; rank < list1.length; rank++) {
97
+ const { id } = list1[rank];
98
+ scores.set(id, (scores.get(id) || 0) + 1 / (k + rank + 1));
99
+ }
100
+ for (let rank = 0; rank < list2.length; rank++) {
101
+ const { id } = list2[rank];
102
+ scores.set(id, (scores.get(id) || 0) + 1 / (k + rank + 1));
103
+ }
104
+ return Array.from(scores.entries()).map(([id, score]) => ({ id, score })).sort((a, b) => b.score - a.score);
105
+ }
106
+ async function semanticSearch(query, cache, topK = 20) {
107
+ const queryEmb = await embed(query);
108
+ const results = [];
109
+ for (const [id, docEmb] of cache.entries()) {
110
+ results.push({ id, score: cosineSimilarity(queryEmb, docEmb) });
111
+ }
112
+ results.sort((a, b) => b.score - a.score);
113
+ return results.slice(0, topK);
114
+ }
115
+ async function hybridSearch(query, bm25Results, cache, options = {}) {
116
+ const { topK = 20, rrfK = 60 } = options;
117
+ const bm25Ranked = bm25Results.map((r) => ({ id: r.document.path || r.document.id, score: r.score }));
118
+ const semanticRanked = await semanticSearch(query, cache, topK);
119
+ const fused = reciprocalRankFusion(bm25Ranked, semanticRanked, rrfK);
120
+ const bm25Map = new Map(bm25Results.map((r) => [r.document.path || r.document.id, r]));
121
+ return fused.slice(0, topK).map(({ id, score }) => {
122
+ const existing = bm25Map.get(id);
123
+ if (existing) {
124
+ return { ...existing, score };
125
+ }
126
+ const minimalDoc = {
127
+ id: id.replace(/\.md$/, ""),
128
+ path: id.endsWith(".md") ? id : id + ".md",
129
+ title: (id.split("/").pop() || id).replace(/\.md$/, ""),
130
+ content: "",
131
+ category: id.split("/")[0] || "root",
132
+ frontmatter: {},
133
+ links: [],
134
+ tags: [],
135
+ modified: /* @__PURE__ */ new Date()
136
+ };
137
+ return {
138
+ document: minimalDoc,
139
+ score,
140
+ snippet: "",
141
+ matchedTerms: []
142
+ };
143
+ });
144
+ }
145
+
146
+ export {
147
+ embed,
148
+ embedBatch,
149
+ cosineSimilarity,
150
+ EmbeddingCache,
151
+ reciprocalRankFusion,
152
+ semanticSearch,
153
+ hybridSearch
154
+ };
@@ -6,16 +6,21 @@ import {
6
6
  import * as fs from "fs";
7
7
  import * as path from "path";
8
8
  var CONFIG_FILE = ".clawvault.json";
9
- var OBSERVE_PROVIDERS = ["anthropic", "openai", "gemini"];
9
+ var OBSERVE_PROVIDERS = ["anthropic", "openai", "gemini", "xai", "openclaw"];
10
10
  var OBSERVER_COMPRESSION_PROVIDERS = [
11
11
  "anthropic",
12
12
  "openai",
13
13
  "gemini",
14
+ "xai",
14
15
  "openai-compatible",
15
- "ollama"
16
+ "ollama",
17
+ "openclaw",
18
+ "minimax",
19
+ "zai"
16
20
  ];
17
21
  var THEMES = ["neural", "minimal", "none"];
18
22
  var CONTEXT_PROFILES = ["default", "planning", "incident", "handoff", "auto"];
23
+ var FACT_EXTRACTION_MODES = ["off", "rule", "llm", "hybrid"];
19
24
  var SUPPORTED_CONFIG_KEYS = [
20
25
  "name",
21
26
  "categories",
@@ -26,6 +31,7 @@ var SUPPORTED_CONFIG_KEYS = [
26
31
  "observer.compression.model",
27
32
  "observer.compression.baseUrl",
28
33
  "observer.compression.apiKey",
34
+ "observer.factExtractionMode",
29
35
  "context.maxResults",
30
36
  "context.defaultProfile",
31
37
  "graph.maxHops",
@@ -36,6 +42,7 @@ var SUPPORTED_CONFIG_KEYS = [
36
42
  var DEFAULT_THEME = "none";
37
43
  var DEFAULT_OBSERVE_MODEL = "gemini-2.0-flash";
38
44
  var DEFAULT_OBSERVE_PROVIDER = "gemini";
45
+ var DEFAULT_FACT_EXTRACTION_MODE = "llm";
39
46
  var DEFAULT_CONTEXT_MAX_RESULTS = 5;
40
47
  var DEFAULT_CONTEXT_PROFILE = "default";
41
48
  var DEFAULT_GRAPH_MAX_HOPS = 2;
@@ -113,6 +120,9 @@ function isTheme(value) {
113
120
  function isContextProfile(value) {
114
121
  return typeof value === "string" && CONTEXT_PROFILES.includes(value);
115
122
  }
123
+ function isFactExtractionMode(value) {
124
+ return typeof value === "string" && FACT_EXTRACTION_MODES.includes(value);
125
+ }
116
126
  function normalizeRouteTarget(target) {
117
127
  const trimmed = target.trim().replace(/^\/+/, "").replace(/\/+$/, "");
118
128
  if (!trimmed) {
@@ -196,7 +206,8 @@ function withDefaults(vaultPath, config) {
196
206
  provider: DEFAULT_OBSERVE_PROVIDER
197
207
  },
198
208
  observer: {
199
- compression: {}
209
+ compression: {},
210
+ factExtractionMode: DEFAULT_FACT_EXTRACTION_MODE
200
211
  },
201
212
  context: {
202
213
  maxResults: DEFAULT_CONTEXT_MAX_RESULTS,
@@ -247,7 +258,8 @@ function withDefaults(vaultPath, config) {
247
258
  },
248
259
  observer: {
249
260
  ...observerRecord,
250
- compression: normalizedCompression
261
+ compression: normalizedCompression,
262
+ factExtractionMode: isFactExtractionMode(observerRecord.factExtractionMode) ? observerRecord.factExtractionMode : defaults.observer.factExtractionMode
251
263
  },
252
264
  context: {
253
265
  ...contextRecord,
@@ -335,6 +347,12 @@ function coerceManagedValue(key, value) {
335
347
  }
336
348
  return value.trim();
337
349
  }
350
+ if (key === "observer.factExtractionMode") {
351
+ if (!isFactExtractionMode(value)) {
352
+ throw new Error(`Config key "observer.factExtractionMode" must be one of: ${FACT_EXTRACTION_MODES.join(", ")}`);
353
+ }
354
+ return value;
355
+ }
338
356
  if (key === "context.maxResults") {
339
357
  const parsed = asPositiveInteger(value);
340
358
  if (parsed === null) {
@@ -424,7 +442,8 @@ function resetConfig(vaultPath) {
424
442
  const observerRecord = document.observer && typeof document.observer === "object" && !Array.isArray(document.observer) ? document.observer : {};
425
443
  document.observer = {
426
444
  ...observerRecord,
427
- compression: {}
445
+ compression: {},
446
+ factExtractionMode: DEFAULT_FACT_EXTRACTION_MODE
428
447
  };
429
448
  document.context = {
430
449
  maxResults: DEFAULT_CONTEXT_MAX_RESULTS,
@@ -0,0 +1,189 @@
1
+ import {
2
+ create,
3
+ read,
4
+ update
5
+ } from "./chunk-QVEERJSP.js";
6
+ import {
7
+ append,
8
+ currentOwner
9
+ } from "./chunk-4BQTQMJP.js";
10
+ import {
11
+ THREAD_STATUS_TRANSITIONS
12
+ } from "./chunk-WMGIIABP.js";
13
+ import {
14
+ __export
15
+ } from "./chunk-2ZDO52B4.js";
16
+
17
+ // src/workgraph/thread.ts
18
+ var thread_exports = {};
19
+ __export(thread_exports, {
20
+ block: () => block,
21
+ cancel: () => cancel,
22
+ claim: () => claim,
23
+ createThread: () => createThread,
24
+ decompose: () => decompose,
25
+ done: () => done,
26
+ release: () => release,
27
+ unblock: () => unblock
28
+ });
29
+ function createThread(vaultPath, title, goal, actor, opts = {}) {
30
+ return create(vaultPath, "thread", {
31
+ title,
32
+ goal,
33
+ status: "open",
34
+ priority: opts.priority ?? "medium",
35
+ deps: opts.deps ?? [],
36
+ parent: opts.parent,
37
+ context_refs: opts.context_refs ?? [],
38
+ tags: opts.tags ?? []
39
+ }, `## Goal
40
+
41
+ ${goal}
42
+ `, actor);
43
+ }
44
+ function claim(vaultPath, threadPath, actor) {
45
+ const thread = read(vaultPath, threadPath);
46
+ if (!thread) throw new Error(`Thread not found: ${threadPath}`);
47
+ const status = thread.fields.status;
48
+ if (status !== "open") {
49
+ throw new Error(`Cannot claim thread in "${status}" state. Only "open" threads can be claimed.`);
50
+ }
51
+ const owner = currentOwner(vaultPath, threadPath);
52
+ if (owner) {
53
+ throw new Error(`Thread already claimed by "${owner}". Wait for release or use a different thread.`);
54
+ }
55
+ append(vaultPath, actor, "claim", threadPath, "thread");
56
+ return update(vaultPath, threadPath, {
57
+ status: "active",
58
+ owner: actor
59
+ }, void 0, actor);
60
+ }
61
+ function release(vaultPath, threadPath, actor, reason) {
62
+ const thread = read(vaultPath, threadPath);
63
+ if (!thread) throw new Error(`Thread not found: ${threadPath}`);
64
+ assertOwner(vaultPath, threadPath, actor);
65
+ append(
66
+ vaultPath,
67
+ actor,
68
+ "release",
69
+ threadPath,
70
+ "thread",
71
+ reason ? { reason } : void 0
72
+ );
73
+ return update(vaultPath, threadPath, {
74
+ status: "open",
75
+ owner: null
76
+ }, void 0, actor);
77
+ }
78
+ function block(vaultPath, threadPath, actor, blockedBy, reason) {
79
+ const thread = read(vaultPath, threadPath);
80
+ if (!thread) throw new Error(`Thread not found: ${threadPath}`);
81
+ assertTransition(thread.fields.status, "blocked");
82
+ append(vaultPath, actor, "block", threadPath, "thread", {
83
+ blocked_by: blockedBy,
84
+ ...reason ? { reason } : {}
85
+ });
86
+ const currentDeps = thread.fields.deps ?? [];
87
+ const updatedDeps = currentDeps.includes(blockedBy) ? currentDeps : [...currentDeps, blockedBy];
88
+ return update(vaultPath, threadPath, {
89
+ status: "blocked",
90
+ deps: updatedDeps
91
+ }, void 0, actor);
92
+ }
93
+ function unblock(vaultPath, threadPath, actor) {
94
+ const thread = read(vaultPath, threadPath);
95
+ if (!thread) throw new Error(`Thread not found: ${threadPath}`);
96
+ assertTransition(thread.fields.status, "active");
97
+ append(vaultPath, actor, "unblock", threadPath, "thread");
98
+ return update(vaultPath, threadPath, {
99
+ status: "active"
100
+ }, void 0, actor);
101
+ }
102
+ function done(vaultPath, threadPath, actor, output) {
103
+ const thread = read(vaultPath, threadPath);
104
+ if (!thread) throw new Error(`Thread not found: ${threadPath}`);
105
+ assertTransition(thread.fields.status, "done");
106
+ assertOwner(vaultPath, threadPath, actor);
107
+ append(
108
+ vaultPath,
109
+ actor,
110
+ "done",
111
+ threadPath,
112
+ "thread",
113
+ output ? { output } : void 0
114
+ );
115
+ const newBody = output ? `${thread.body}
116
+
117
+ ## Output
118
+
119
+ ${output}
120
+ ` : thread.body;
121
+ return update(vaultPath, threadPath, {
122
+ status: "done"
123
+ }, newBody, actor);
124
+ }
125
+ function cancel(vaultPath, threadPath, actor, reason) {
126
+ const thread = read(vaultPath, threadPath);
127
+ if (!thread) throw new Error(`Thread not found: ${threadPath}`);
128
+ assertTransition(thread.fields.status, "cancelled");
129
+ append(
130
+ vaultPath,
131
+ actor,
132
+ "cancel",
133
+ threadPath,
134
+ "thread",
135
+ reason ? { reason } : void 0
136
+ );
137
+ return update(vaultPath, threadPath, {
138
+ status: "cancelled",
139
+ owner: null
140
+ }, void 0, actor);
141
+ }
142
+ function decompose(vaultPath, parentPath, subthreads, actor) {
143
+ const parent = read(vaultPath, parentPath);
144
+ if (!parent) throw new Error(`Thread not found: ${parentPath}`);
145
+ const created = [];
146
+ for (const sub of subthreads) {
147
+ const inst = createThread(vaultPath, sub.title, sub.goal, actor, {
148
+ parent: parentPath,
149
+ deps: sub.deps
150
+ });
151
+ created.push(inst);
152
+ }
153
+ const childRefs = created.map((c) => `[[${c.path}]]`);
154
+ const decomposeNote = `
155
+
156
+ ## Sub-threads
157
+
158
+ ${childRefs.map((r) => `- ${r}`).join("\n")}
159
+ `;
160
+ update(vaultPath, parentPath, {}, parent.body + decomposeNote, actor);
161
+ append(vaultPath, actor, "decompose", parentPath, "thread", {
162
+ children: created.map((c) => c.path)
163
+ });
164
+ return created;
165
+ }
166
+ function assertTransition(from, to) {
167
+ const allowed = THREAD_STATUS_TRANSITIONS[from];
168
+ if (!allowed?.includes(to)) {
169
+ throw new Error(`Invalid transition: "${from}" \u2192 "${to}". Allowed: ${allowed?.join(", ") ?? "none"}`);
170
+ }
171
+ }
172
+ function assertOwner(vaultPath, threadPath, actor) {
173
+ const owner = currentOwner(vaultPath, threadPath);
174
+ if (owner && owner !== actor) {
175
+ throw new Error(`Thread is owned by "${owner}", not "${actor}". Only the owner can perform this action.`);
176
+ }
177
+ }
178
+
179
+ export {
180
+ createThread,
181
+ claim,
182
+ release,
183
+ block,
184
+ unblock,
185
+ done,
186
+ cancel,
187
+ decompose,
188
+ thread_exports
189
+ };
@@ -1,14 +1,14 @@
1
+ import {
2
+ listConfig
3
+ } from "./chunk-URXDAUVH.js";
1
4
  import {
2
5
  requestLlmCompletion,
3
6
  resolveLlmProvider
4
- } from "./chunk-E7MFQB6D.js";
5
- import {
6
- listConfig
7
- } from "./chunk-ITPEXLHA.js";
7
+ } from "./chunk-NCKFNBHJ.js";
8
8
  import {
9
9
  getMemoryGraph,
10
10
  loadMemoryGraphIndex
11
- } from "./chunk-ZZA73MFY.js";
11
+ } from "./chunk-33DOSHTA.js";
12
12
 
13
13
  // src/commands/inject.ts
14
14
  import * as path2 from "path";
@@ -563,7 +563,7 @@ async function runPromptInjection(vaultPathInput, message, options = {}) {
563
563
  const deterministicMs = Date.now() - startDeterministic;
564
564
  let llmProvider = null;
565
565
  if (useLlm) {
566
- llmProvider = await resolveLlmProvider();
566
+ llmProvider = resolveLlmProvider();
567
567
  if (llmProvider) {
568
568
  try {
569
569
  matches = await addLlmIntentMatches({
@@ -0,0 +1,15 @@
1
+ // src/workgraph/types.ts
2
+ var THREAD_STATUS_TRANSITIONS = {
3
+ open: ["active", "cancelled"],
4
+ active: ["blocked", "done", "cancelled", "open"],
5
+ // open = release
6
+ blocked: ["active", "cancelled"],
7
+ done: [],
8
+ // terminal
9
+ cancelled: ["open"]
10
+ // can be reopened
11
+ };
12
+
13
+ export {
14
+ THREAD_STATUS_TRANSITIONS
15
+ };