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,257 @@
1
+ // src/lib/llm-provider.ts
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import * as os from "os";
5
+ var DEFAULT_MODELS = {
6
+ anthropic: "claude-3-5-haiku-latest",
7
+ openai: "gpt-4o-mini",
8
+ gemini: "gemini-2.0-flash",
9
+ xai: "grok-2-latest",
10
+ openclaw: "gpt-4o-mini"
11
+ };
12
+ var XAI_BASE_URL = "https://api.x.ai/v1";
13
+ function resolveOpenClawHome() {
14
+ return process.env.OPENCLAW_HOME?.trim() || path.join(os.homedir(), ".openclaw");
15
+ }
16
+ function resolveOpenClawGatewayProvider() {
17
+ try {
18
+ const configPath = path.join(resolveOpenClawHome(), "openclaw.json");
19
+ if (!fs.existsSync(configPath)) {
20
+ return null;
21
+ }
22
+ const raw = JSON.parse(fs.readFileSync(configPath, "utf-8"));
23
+ const enabled = raw.gateway?.http?.endpoints?.chatCompletions?.enabled === true;
24
+ const apiKey = raw.gateway?.auth?.token?.trim();
25
+ const port = raw.gateway?.port;
26
+ if (!enabled || !apiKey || typeof port !== "number" || !Number.isFinite(port) || port <= 0) {
27
+ return null;
28
+ }
29
+ const defaultModel = raw.agents?.defaults?.model?.trim() || DEFAULT_MODELS.openclaw;
30
+ const host = raw.gateway?.bind === "loopback" ? "127.0.0.1" : "127.0.0.1";
31
+ return {
32
+ baseUrl: `http://${host}:${port}/v1`,
33
+ apiKey,
34
+ api: "openai-completions",
35
+ defaultModel
36
+ };
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+ function resolveOpenClawProvider() {
42
+ const gatewayProvider = resolveOpenClawGatewayProvider();
43
+ if (gatewayProvider) {
44
+ return gatewayProvider;
45
+ }
46
+ try {
47
+ const modelsPath = path.join(resolveOpenClawHome(), "agents", "main", "agent", "models.json");
48
+ if (!fs.existsSync(modelsPath)) {
49
+ return null;
50
+ }
51
+ const raw = JSON.parse(fs.readFileSync(modelsPath, "utf-8"));
52
+ if (!raw.providers || typeof raw.providers !== "object") {
53
+ return null;
54
+ }
55
+ for (const [, provider] of Object.entries(raw.providers)) {
56
+ if (provider.baseUrl && provider.apiKey) {
57
+ const defaultModel = provider.models?.[0]?.id ?? "gpt-4o-mini";
58
+ return {
59
+ baseUrl: provider.baseUrl.replace(/\/+$/, ""),
60
+ apiKey: provider.apiKey,
61
+ api: provider.api ?? "openai-completions",
62
+ defaultModel
63
+ };
64
+ }
65
+ }
66
+ } catch {
67
+ }
68
+ return null;
69
+ }
70
+ function resolveLlmProvider() {
71
+ if (process.env.CLAWVAULT_NO_LLM) {
72
+ return null;
73
+ }
74
+ if (resolveOpenClawProvider()) {
75
+ return "openclaw";
76
+ }
77
+ if (process.env.ANTHROPIC_API_KEY) {
78
+ return "anthropic";
79
+ }
80
+ if (process.env.OPENAI_API_KEY) {
81
+ return "openai";
82
+ }
83
+ if (process.env.GEMINI_API_KEY) {
84
+ return "gemini";
85
+ }
86
+ if (process.env.XAI_API_KEY) {
87
+ return "xai";
88
+ }
89
+ return null;
90
+ }
91
+ async function requestLlmCompletion(options) {
92
+ const provider = options.provider ?? resolveLlmProvider();
93
+ if (!provider) {
94
+ return "";
95
+ }
96
+ if (provider === "openclaw") {
97
+ return callOpenClaw(options);
98
+ }
99
+ if (provider === "anthropic") {
100
+ return callAnthropic(options, provider);
101
+ }
102
+ if (provider === "gemini") {
103
+ return callGemini(options, provider);
104
+ }
105
+ if (provider === "xai") {
106
+ return callXAI(options, provider);
107
+ }
108
+ return callOpenAI(options, provider);
109
+ }
110
+ async function callAnthropic(options, provider) {
111
+ const apiKey = process.env.ANTHROPIC_API_KEY;
112
+ if (!apiKey) {
113
+ return "";
114
+ }
115
+ const fetchImpl = options.fetchImpl ?? fetch;
116
+ const response = await fetchImpl("https://api.anthropic.com/v1/messages", {
117
+ method: "POST",
118
+ headers: {
119
+ "content-type": "application/json",
120
+ "x-api-key": apiKey,
121
+ "anthropic-version": "2023-06-01"
122
+ },
123
+ body: JSON.stringify({
124
+ model: options.model ?? DEFAULT_MODELS[provider],
125
+ temperature: options.temperature ?? 0.1,
126
+ max_tokens: options.maxTokens ?? 1200,
127
+ messages: [{ role: "user", content: options.prompt }]
128
+ })
129
+ });
130
+ if (!response.ok) {
131
+ throw new Error(`Anthropic request failed (${response.status})`);
132
+ }
133
+ const payload = await response.json();
134
+ return payload.content?.filter((entry) => entry.type === "text" && entry.text).map((entry) => entry.text).join("\n").trim() ?? "";
135
+ }
136
+ async function callOpenAI(options, provider) {
137
+ const apiKey = process.env.OPENAI_API_KEY;
138
+ if (!apiKey) {
139
+ return "";
140
+ }
141
+ const fetchImpl = options.fetchImpl ?? fetch;
142
+ const messages = [];
143
+ if (options.systemPrompt?.trim()) {
144
+ messages.push({ role: "system", content: options.systemPrompt.trim() });
145
+ }
146
+ messages.push({ role: "user", content: options.prompt });
147
+ const response = await fetchImpl("https://api.openai.com/v1/chat/completions", {
148
+ method: "POST",
149
+ headers: {
150
+ "content-type": "application/json",
151
+ authorization: `Bearer ${apiKey}`
152
+ },
153
+ body: JSON.stringify({
154
+ model: options.model ?? DEFAULT_MODELS[provider],
155
+ temperature: options.temperature ?? 0.1,
156
+ max_tokens: options.maxTokens ?? 1200,
157
+ messages
158
+ })
159
+ });
160
+ if (!response.ok) {
161
+ throw new Error(`OpenAI request failed (${response.status})`);
162
+ }
163
+ const payload = await response.json();
164
+ return payload.choices?.[0]?.message?.content?.trim() ?? "";
165
+ }
166
+ async function callXAI(options, provider) {
167
+ const apiKey = process.env.XAI_API_KEY;
168
+ if (!apiKey) {
169
+ return "";
170
+ }
171
+ const fetchImpl = options.fetchImpl ?? fetch;
172
+ const messages = [];
173
+ if (options.systemPrompt?.trim()) {
174
+ messages.push({ role: "system", content: options.systemPrompt.trim() });
175
+ }
176
+ messages.push({ role: "user", content: options.prompt });
177
+ const response = await fetchImpl(`${XAI_BASE_URL}/chat/completions`, {
178
+ method: "POST",
179
+ headers: {
180
+ "content-type": "application/json",
181
+ authorization: `Bearer ${apiKey}`
182
+ },
183
+ body: JSON.stringify({
184
+ model: options.model ?? DEFAULT_MODELS[provider],
185
+ temperature: options.temperature ?? 0.1,
186
+ max_tokens: options.maxTokens ?? 1200,
187
+ messages
188
+ })
189
+ });
190
+ if (!response.ok) {
191
+ throw new Error(`xAI request failed (${response.status})`);
192
+ }
193
+ const payload = await response.json();
194
+ return payload.choices?.[0]?.message?.content?.trim() ?? "";
195
+ }
196
+ async function callGemini(options, provider) {
197
+ const apiKey = process.env.GEMINI_API_KEY;
198
+ if (!apiKey) {
199
+ return "";
200
+ }
201
+ const fetchImpl = options.fetchImpl ?? fetch;
202
+ const model = options.model ?? DEFAULT_MODELS[provider];
203
+ const response = await fetchImpl(
204
+ `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`,
205
+ {
206
+ method: "POST",
207
+ headers: { "content-type": "application/json", "x-goog-api-key": apiKey },
208
+ body: JSON.stringify({
209
+ contents: [{ parts: [{ text: options.prompt }] }],
210
+ generationConfig: {
211
+ temperature: options.temperature ?? 0.1,
212
+ maxOutputTokens: options.maxTokens ?? 1200
213
+ }
214
+ })
215
+ }
216
+ );
217
+ if (!response.ok) {
218
+ throw new Error(`Gemini request failed (${response.status})`);
219
+ }
220
+ const payload = await response.json();
221
+ return payload.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? "";
222
+ }
223
+ async function callOpenClaw(options) {
224
+ const config = resolveOpenClawProvider();
225
+ if (!config) {
226
+ return "";
227
+ }
228
+ const fetchImpl = options.fetchImpl ?? fetch;
229
+ const messages = [];
230
+ if (options.systemPrompt?.trim()) {
231
+ messages.push({ role: "system", content: options.systemPrompt.trim() });
232
+ }
233
+ messages.push({ role: "user", content: options.prompt });
234
+ const response = await fetchImpl(`${config.baseUrl}/chat/completions`, {
235
+ method: "POST",
236
+ headers: {
237
+ "content-type": "application/json",
238
+ authorization: `Bearer ${config.apiKey}`
239
+ },
240
+ body: JSON.stringify({
241
+ model: options.model ?? config.defaultModel,
242
+ temperature: options.temperature ?? 0.1,
243
+ max_tokens: options.maxTokens ?? 1200,
244
+ messages
245
+ })
246
+ });
247
+ if (!response.ok) {
248
+ throw new Error(`OpenClaw provider request failed (${response.status})`);
249
+ }
250
+ const payload = await response.json();
251
+ return payload.choices?.[0]?.message?.content?.trim() ?? "";
252
+ }
253
+
254
+ export {
255
+ resolveLlmProvider,
256
+ requestLlmCompletion
257
+ };
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  checkDirtyDeath,
6
6
  clearDirtyFlag
7
- } from "./chunk-WAZ3NLWL.js";
7
+ } from "./chunk-F55HGNU4.js";
8
8
 
9
9
  // src/commands/recover.ts
10
10
  import * as fs from "fs";
@@ -14,7 +14,7 @@ function findProtectedRanges(content) {
14
14
  while ((match = codeBlockRegex.exec(content)) !== null) {
15
15
  ranges.push({ start: match.index, end: match.index + match[0].length });
16
16
  }
17
- const inlineCodeRegex = /`[^`]+`/g;
17
+ const inlineCodeRegex = /(?<!`)`[^`\n]+`(?!`)/g;
18
18
  while ((match = inlineCodeRegex.exec(content)) !== null) {
19
19
  ranges.push({ start: match.index, end: match.index + match[0].length });
20
20
  }
@@ -26,10 +26,51 @@ function findProtectedRanges(content) {
26
26
  while ((match = urlRegex.exec(content)) !== null) {
27
27
  ranges.push({ start: match.index, end: match.index + match[0].length });
28
28
  }
29
+ const filePathRegex = /(?:^|[\s([{"'])((?:~|\/)[^\s`<>\])}"']+|[A-Za-z]:\\[^\s`<>\])}"']+)/g;
30
+ while ((match = filePathRegex.exec(content)) !== null) {
31
+ const fullMatch = match[0];
32
+ const pathValue = match[1];
33
+ const start = match.index + fullMatch.indexOf(pathValue);
34
+ ranges.push({ start, end: start + pathValue.length });
35
+ }
29
36
  return ranges;
30
37
  }
31
- function isProtected(pos, ranges) {
32
- return ranges.some((r) => pos >= r.start && pos < r.end);
38
+ function isProtectedRange(start, end, ranges) {
39
+ return ranges.some((range) => start < range.end && end > range.start);
40
+ }
41
+ function createAliasRegex(alias) {
42
+ const escapedAlias = alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
43
+ return new RegExp(`\\b${escapedAlias}\\b`, "gi");
44
+ }
45
+ function formatWikiLink(path, originalText) {
46
+ return originalText.toLowerCase() === path.split("/").pop()?.toLowerCase() ? `[[${path}]]` : `[[${path}|${originalText}]]`;
47
+ }
48
+ function planLinks(content, index, protectedRanges) {
49
+ const sortedAliases = getSortedAliases(index);
50
+ const linkedEntities = /* @__PURE__ */ new Set();
51
+ const claimedRanges = [];
52
+ const plannedLinks = [];
53
+ for (const { alias, path } of sortedAliases) {
54
+ if (linkedEntities.has(path)) continue;
55
+ const regex = createAliasRegex(alias);
56
+ let match;
57
+ while ((match = regex.exec(content)) !== null) {
58
+ const start = match.index;
59
+ const end = start + match[0].length;
60
+ if (isProtectedRange(start, end, protectedRanges)) continue;
61
+ if (isProtectedRange(start, end, claimedRanges)) continue;
62
+ plannedLinks.push({
63
+ start,
64
+ end,
65
+ originalText: match[0],
66
+ path
67
+ });
68
+ claimedRanges.push({ start, end });
69
+ linkedEntities.add(path);
70
+ break;
71
+ }
72
+ }
73
+ return plannedLinks;
33
74
  }
34
75
  function createLineLookup(content) {
35
76
  const lines = content.split("\n");
@@ -48,56 +89,24 @@ function createLineLookup(content) {
48
89
  }
49
90
  function autoLink(content, index) {
50
91
  const protectedRanges = findProtectedRanges(content);
51
- const sortedAliases = getSortedAliases(index);
52
- const linkedEntities = /* @__PURE__ */ new Set();
92
+ const plannedLinks = planLinks(content, index, protectedRanges);
53
93
  let result = content;
54
- let offset = 0;
55
- for (const { alias, path } of sortedAliases) {
56
- if (linkedEntities.has(path)) continue;
57
- const escapedAlias = alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
58
- const regex = new RegExp(`\\b${escapedAlias}\\b`, "gi");
59
- let match;
60
- while ((match = regex.exec(content)) !== null) {
61
- const originalPos = match.index;
62
- const adjustedPos = originalPos + offset;
63
- if (isProtected(originalPos, protectedRanges)) continue;
64
- const beforeMatch = result.substring(0, adjustedPos);
65
- const openBrackets = (beforeMatch.match(/\[\[/g) || []).length;
66
- const closeBrackets = (beforeMatch.match(/\]\]/g) || []).length;
67
- if (openBrackets > closeBrackets) continue;
68
- const originalText = match[0];
69
- const replacement = originalText.toLowerCase() === path.split("/").pop()?.toLowerCase() ? `[[${path}]]` : `[[${path}|${originalText}]]`;
70
- result = result.substring(0, adjustedPos) + replacement + result.substring(adjustedPos + originalText.length);
71
- offset += replacement.length - originalText.length;
72
- linkedEntities.add(path);
73
- break;
74
- }
94
+ const sortedByPosition = plannedLinks.slice().sort((a, b) => b.start - a.start);
95
+ for (const planned of sortedByPosition) {
96
+ const replacement = formatWikiLink(planned.path, planned.originalText);
97
+ result = result.substring(0, planned.start) + replacement + result.substring(planned.end);
75
98
  }
76
99
  return result;
77
100
  }
78
101
  function dryRunLink(content, index) {
79
102
  const protectedRanges = findProtectedRanges(content);
80
- const sortedAliases = getSortedAliases(index);
81
- const linkedEntities = /* @__PURE__ */ new Set();
82
- const matches = [];
103
+ const plannedLinks = planLinks(content, index, protectedRanges);
83
104
  const getLineNumber = createLineLookup(content);
84
- for (const { alias, path } of sortedAliases) {
85
- if (linkedEntities.has(path)) continue;
86
- const escapedAlias = alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
87
- const regex = new RegExp(`\\b${escapedAlias}\\b`, "gi");
88
- let match;
89
- while ((match = regex.exec(content)) !== null) {
90
- if (isProtected(match.index, protectedRanges)) continue;
91
- matches.push({
92
- alias: match[0],
93
- path,
94
- line: getLineNumber(match.index)
95
- });
96
- linkedEntities.add(path);
97
- break;
98
- }
99
- }
100
- return matches;
105
+ return plannedLinks.map((planned) => ({
106
+ alias: planned.originalText,
107
+ path: planned.path,
108
+ line: getLineNumber(planned.start)
109
+ }));
101
110
  }
102
111
  function findUnlinkedMentions(content, index) {
103
112
  const protectedRanges = findProtectedRanges(content);
@@ -111,7 +120,9 @@ function findUnlinkedMentions(content, index) {
111
120
  const regex = new RegExp(`\\b${escapedAlias}\\b`, "gi");
112
121
  let match;
113
122
  while ((match = regex.exec(content)) !== null) {
114
- if (isProtected(match.index, protectedRanges)) continue;
123
+ const start = match.index;
124
+ const end = start + match[0].length;
125
+ if (isProtectedRange(start, end, protectedRanges)) continue;
115
126
  matches.push({
116
127
  alias: match[0],
117
128
  path,
@@ -0,0 +1,66 @@
1
+ import {
2
+ loadVaultQmdConfig,
3
+ recoverQmdEmbeddingIfNeeded,
4
+ runCrashSafeQmdEmbed
5
+ } from "./chunk-6FH3IULF.js";
6
+ import {
7
+ QmdUnavailableError,
8
+ hasQmd
9
+ } from "./chunk-EK6S23ZB.js";
10
+ import {
11
+ resolveVaultPath
12
+ } from "./chunk-GNJL4YGR.js";
13
+
14
+ // src/commands/embed.ts
15
+ async function embedCommand(options = {}) {
16
+ if (!hasQmd()) {
17
+ throw new QmdUnavailableError();
18
+ }
19
+ const vaultPath = resolveVaultPath({ explicitPath: options.vaultPath });
20
+ const qmdConfig = loadVaultQmdConfig(vaultPath);
21
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
22
+ const recovery = recoverQmdEmbeddingIfNeeded({
23
+ vaultPath,
24
+ collection: qmdConfig.qmdCollection,
25
+ rootPath: qmdConfig.qmdRoot,
26
+ mode: "marker-or-empty",
27
+ onLog: options.quiet ? void 0 : (message) => console.log(message)
28
+ });
29
+ if (!options.quiet && recovery.recovered) {
30
+ const reasonLabel = recovery.reason === "interrupted_wal" ? "interrupted run" : "empty vector state";
31
+ console.log(`\u2713 Automatic qmd recovery completed (${reasonLabel}).`);
32
+ }
33
+ if (!options.quiet) {
34
+ console.log(
35
+ `Embedding pending documents for collection "${qmdConfig.qmdCollection}" (root: ${qmdConfig.qmdRoot})...`
36
+ );
37
+ }
38
+ runCrashSafeQmdEmbed({
39
+ vaultPath,
40
+ collection: qmdConfig.qmdCollection,
41
+ rootPath: qmdConfig.qmdRoot
42
+ });
43
+ const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
44
+ if (!options.quiet) {
45
+ console.log(`\u2713 Embedding complete for "${qmdConfig.qmdCollection}"`);
46
+ }
47
+ return {
48
+ vaultPath,
49
+ qmdCollection: qmdConfig.qmdCollection,
50
+ qmdRoot: qmdConfig.qmdRoot,
51
+ startedAt,
52
+ finishedAt
53
+ };
54
+ }
55
+ function registerEmbedCommand(program) {
56
+ program.command("embed").description("Run qmd embedding for pending vault documents").option("-v, --vault <path>", "Vault path").action(async (rawOptions) => {
57
+ await embedCommand({
58
+ vaultPath: rawOptions.vault
59
+ });
60
+ });
61
+ }
62
+
63
+ export {
64
+ embedCommand,
65
+ registerEmbedCommand
66
+ };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  Observer
3
- } from "./chunk-3NSBOUT3.js";
3
+ } from "./chunk-77Q5CSPJ.js";
4
4
  import {
5
5
  resolveVaultPath
6
- } from "./chunk-MXSSG3QU.js";
6
+ } from "./chunk-GNJL4YGR.js";
7
7
  import {
8
8
  getLegacyObservationPath,
9
9
  getObservationPath,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  resolveVaultPath
3
- } from "./chunk-MXSSG3QU.js";
3
+ } from "./chunk-GNJL4YGR.js";
4
4
  import {
5
5
  buildOrUpdateMemoryGraphIndex,
6
6
  loadMemoryGraphIndex
7
- } from "./chunk-ZZA73MFY.js";
7
+ } from "./chunk-33DOSHTA.js";
8
8
 
9
9
  // src/commands/graph.ts
10
10
  function formatGraphSummary(summary) {
@@ -0,0 +1,152 @@
1
+ import {
2
+ append
3
+ } from "./chunk-4BQTQMJP.js";
4
+ import {
5
+ getType,
6
+ loadRegistry
7
+ } from "./chunk-MM6QGW3P.js";
8
+ import {
9
+ __export
10
+ } from "./chunk-2ZDO52B4.js";
11
+
12
+ // src/workgraph/store.ts
13
+ var store_exports = {};
14
+ __export(store_exports, {
15
+ activeThreads: () => activeThreads,
16
+ blockedThreads: () => blockedThreads,
17
+ create: () => create,
18
+ findByField: () => findByField,
19
+ list: () => list,
20
+ openThreads: () => openThreads,
21
+ read: () => read,
22
+ remove: () => remove,
23
+ update: () => update
24
+ });
25
+ import fs from "fs";
26
+ import path from "path";
27
+ import matter from "gray-matter";
28
+ function create(vaultPath, typeName, fields, body, actor) {
29
+ const typeDef = getType(vaultPath, typeName);
30
+ if (!typeDef) {
31
+ throw new Error(`Unknown primitive type "${typeName}". Run \`clawvault primitive list\` to see available types, or \`clawvault primitive define\` to create one.`);
32
+ }
33
+ const now = (/* @__PURE__ */ new Date()).toISOString();
34
+ const merged = applyDefaults(typeDef, {
35
+ ...fields,
36
+ created: fields.created ?? now,
37
+ updated: now
38
+ });
39
+ const slug = slugify(String(merged.title ?? merged.name ?? typeName));
40
+ const relDir = typeDef.directory;
41
+ const relPath = `${relDir}/${slug}.md`;
42
+ const absDir = path.join(vaultPath, relDir);
43
+ const absPath = path.join(vaultPath, relPath);
44
+ if (!fs.existsSync(absDir)) fs.mkdirSync(absDir, { recursive: true });
45
+ if (fs.existsSync(absPath)) {
46
+ throw new Error(`File already exists: ${relPath}. Use update instead.`);
47
+ }
48
+ const content = matter.stringify(body, stripUndefined(merged));
49
+ fs.writeFileSync(absPath, content, "utf-8");
50
+ append(vaultPath, actor, "create", relPath, typeName, {
51
+ title: merged.title ?? slug
52
+ });
53
+ return { path: relPath, type: typeName, fields: merged, body };
54
+ }
55
+ function read(vaultPath, relPath) {
56
+ const absPath = path.join(vaultPath, relPath);
57
+ if (!fs.existsSync(absPath)) return null;
58
+ const raw = fs.readFileSync(absPath, "utf-8");
59
+ const { data, content } = matter(raw);
60
+ const typeName = inferType(vaultPath, relPath);
61
+ return { path: relPath, type: typeName, fields: data, body: content.trim() };
62
+ }
63
+ function list(vaultPath, typeName) {
64
+ const typeDef = getType(vaultPath, typeName);
65
+ if (!typeDef) return [];
66
+ const dir = path.join(vaultPath, typeDef.directory);
67
+ if (!fs.existsSync(dir)) return [];
68
+ const files = fs.readdirSync(dir).filter((f) => f.endsWith(".md"));
69
+ const instances = [];
70
+ for (const file of files) {
71
+ const relPath = `${typeDef.directory}/${file}`;
72
+ const inst = read(vaultPath, relPath);
73
+ if (inst) instances.push(inst);
74
+ }
75
+ return instances;
76
+ }
77
+ function update(vaultPath, relPath, fieldUpdates, bodyUpdate, actor) {
78
+ const existing = read(vaultPath, relPath);
79
+ if (!existing) throw new Error(`Not found: ${relPath}`);
80
+ const now = (/* @__PURE__ */ new Date()).toISOString();
81
+ const newFields = { ...existing.fields, ...fieldUpdates, updated: now };
82
+ const newBody = bodyUpdate ?? existing.body;
83
+ const absPath = path.join(vaultPath, relPath);
84
+ const content = matter.stringify(newBody, stripUndefined(newFields));
85
+ fs.writeFileSync(absPath, content, "utf-8");
86
+ append(vaultPath, actor, "update", relPath, existing.type, {
87
+ changed: Object.keys(fieldUpdates)
88
+ });
89
+ return { path: relPath, type: existing.type, fields: newFields, body: newBody };
90
+ }
91
+ function remove(vaultPath, relPath, actor) {
92
+ const absPath = path.join(vaultPath, relPath);
93
+ if (!fs.existsSync(absPath)) throw new Error(`Not found: ${relPath}`);
94
+ const archiveDir = path.join(vaultPath, ".clawvault", "archive");
95
+ if (!fs.existsSync(archiveDir)) fs.mkdirSync(archiveDir, { recursive: true });
96
+ const archivePath = path.join(archiveDir, path.basename(relPath));
97
+ fs.renameSync(absPath, archivePath);
98
+ const typeName = inferType(vaultPath, relPath);
99
+ append(vaultPath, actor, "delete", relPath, typeName);
100
+ }
101
+ function findByField(vaultPath, typeName, field, value) {
102
+ return list(vaultPath, typeName).filter((inst) => inst.fields[field] === value);
103
+ }
104
+ function openThreads(vaultPath) {
105
+ return findByField(vaultPath, "thread", "status", "open");
106
+ }
107
+ function activeThreads(vaultPath) {
108
+ return findByField(vaultPath, "thread", "status", "active");
109
+ }
110
+ function blockedThreads(vaultPath) {
111
+ return findByField(vaultPath, "thread", "status", "blocked");
112
+ }
113
+ function slugify(text) {
114
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 80);
115
+ }
116
+ function applyDefaults(typeDef, fields) {
117
+ const result = { ...fields };
118
+ for (const [key, def] of Object.entries(typeDef.fields)) {
119
+ if (result[key] === void 0 && def.default !== void 0) {
120
+ result[key] = def.default;
121
+ }
122
+ }
123
+ return result;
124
+ }
125
+ function stripUndefined(obj) {
126
+ const result = {};
127
+ for (const [k, v] of Object.entries(obj)) {
128
+ if (v !== void 0) result[k] = v;
129
+ }
130
+ return result;
131
+ }
132
+ function inferType(vaultPath, relPath) {
133
+ const registry = loadRegistry(vaultPath);
134
+ const dir = relPath.split("/")[0];
135
+ for (const typeDef of Object.values(registry.types)) {
136
+ if (typeDef.directory === dir) return typeDef.name;
137
+ }
138
+ return "unknown";
139
+ }
140
+
141
+ export {
142
+ create,
143
+ read,
144
+ list,
145
+ update,
146
+ remove,
147
+ findByField,
148
+ openThreads,
149
+ activeThreads,
150
+ blockedThreads,
151
+ store_exports
152
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadSchemaTemplateDefinition,
3
3
  renderDocumentFromTemplate
4
- } from "./chunk-LYHGEHXG.js";
4
+ } from "./chunk-MFAWT5O5.js";
5
5
 
6
6
  // src/lib/task-utils.ts
7
7
  import * as fs2 from "fs";
@@ -8,7 +8,7 @@ import {
8
8
  queryTransitions,
9
9
  readTask,
10
10
  updateTask
11
- } from "./chunk-N2AXRYLC.js";
11
+ } from "./chunk-QWQ3TIKS.js";
12
12
 
13
13
  // src/commands/task.ts
14
14
  function taskAdd(vaultPath, title, options = {}) {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  runReflection
3
- } from "./chunk-H34S76MB.js";
3
+ } from "./chunk-ESVS6K2B.js";
4
4
  import {
5
5
  resolveVaultPath
6
- } from "./chunk-MXSSG3QU.js";
6
+ } from "./chunk-GNJL4YGR.js";
7
7
 
8
8
  // src/commands/reflect.ts
9
9
  function parsePositiveInteger(raw, label) {